Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 3 1 2 3 LastLast
Results 1 to 25 of 63

Thread: microSD slot on teensy 3.6

  1. #1
    Junior Member
    Join Date
    Oct 2016
    Posts
    11

    microSD slot on teensy 3.6

    Hi --

    I was attempting to use the microSD slot on the teensy 3.6 with the built in sample project in teensyduino (SD/cardinfo). When I run it with a SDHC card in the slot, I get the following output:

    Initializing SD card...initialization failed. Things to check:
    * is a card inserted?
    * is your wiring correct?
    * did you change the chipSelect pin to match your shield or module?
    I've tried this with a handful of cards I have on hand -- a 8GB generic microSD card, and a set of 16GB and 32GB SanDisk microSD cards. All fail with the same message.

    So I guess my first assumption is that I assumed the SD library in teensyduino supports SDHC -- is that an incorrect assumption? If not, is there some other setup I need to do on the board to enable the microSD slot or should it just be enabled by default?

    Thanks!
    dennis

    UPDATE: just found a 2GB SanDisk microSD card I had around as well and I get the same failure message. I realize that this could still be a SDHC card, but it doesn't appear to be marked as one.
    Last edited by SmileyDude; 10-02-2016 at 11:54 PM.

  2. #2
    Senior Member johnnyfp's Avatar
    Join Date
    Jan 2014
    Location
    New Zealand
    Posts
    260
    Try the SDIO library and example available from https://github.com/greiman/SdFat-beta

  3. #3
    Junior Member
    Join Date
    Oct 2016
    Posts
    11
    Quote Originally Posted by johnnyfp View Post
    Try the SDIO library and example available from https://github.com/greiman/SdFat-beta
    Just installed that library and gave the SdInfo sketch a try. I get the following error:

    SdFat version: 20160913

    Assuming the SD is the only SPI device.
    Edit DISABLE_CHIP_SELECT to disable another device.

    Assuming the SD chip select pin is: 10
    Edit SD_CHIP_SELECT to change the SD chip select pin.
    error: cardBegin failed
    SD errorCode: 0X20,0XFF
    I did verify that the card is recognized in my computer (2014 MacBook Pro running macOS Sierra), so it doesn't appear to be an issue with the card.

    Doing some more digging on my end.

  4. #4
    Junior Member
    Join Date
    Oct 2016
    Posts
    11
    I just used the SdFat library on an Arduino UNO using the same card, but wired up through an SD card breakout board that I have. It looks like that same library and board work fine on the Uno.

    SdFat version: 20160913

    Assuming the SD is the only SPI device.
    Edit DISABLE_CHIP_SELECT to disable another device.

    Assuming the SD chip select pin is: 10
    Edit SD_CHIP_SELECT to change the SD chip select pin.

    init time: 755 ms

    Card type: SDHC

    Manufacturer ID: 0X1B
    OEM ID: SM
    Product: 00000
    Version: 1.0
    Serial number: 0X595547CC
    Manufacturing date: 9/2013

    cardSize: 7861.17 MB (MB = 1,000,000 bytes)
    flashEraseSize: 128 blocks
    eraseSingleBlock: true
    OCR: 0XC0FF8000

    SD Partition Table
    part,boot,type,start,length
    1,0X0,0XE,8192,2358996
    2,0X0,0X85,2367188,12986668
    3,0X0,0X0,0,0
    4,0X0,0X0,0,0

    Volume is FAT32
    blocksPerCluster: 32
    clusterCount: 73679
    freeClusters: 5948
    freeSpace: 97.45 MB (MB = 1,000,000 bytes)
    fatStartBlock: 8288
    fatCount: 2
    blocksPerFat: 576
    rootDirStart: 2
    dataStartBlock: 9440
    Data area is not aligned on flash erase boundaries!
    Download and use formatter from www.sdcard.org!

  5. #5
    Junior Member
    Join Date
    Oct 2016
    Posts
    11
    So I'm not very familiar with any of the teensy models, since the 3.6 is my first one. So please forgive me if I'm missing something obvious here. Looking at the datasheet for the microcontroller, there appears to be three SPI buses on the chip. Looking at the pinout card for the teensy 3.6, my guess would be that the SD card is using SPI2, since the breakout pads for that bus is located directly underneath the microSD slot.

    My question is (assuming SPI2 is being used), if I use the continuity tester on my multimeter, should I see continuity between the SCK2 pin on the bottom and the CLK pin on the microSD slot?

  6. #6
    Junior Member
    Join Date
    Oct 2016
    Posts
    11
    Sorry for yet another reply, but I was able to get the teensy working with the SD card, but only by using the breakout board. I just wired it up to SPI0 (figured out that it wasn't on SPI2, as you can tell) and it worked.

    SdFat version: 20160913

    Assuming the SD is the only SPI device.
    Edit DISABLE_CHIP_SELECT to disable another device.

    Assuming the SD chip select pin is: 10
    Edit SD_CHIP_SELECT to change the SD chip select pin.

    type any character to start

    init time: 147 ms

    Card type: SDHC

    Manufacturer ID: 0X1B
    OEM ID: SM
    Product: 00000
    Version: 1.0
    Serial number: 0X595547CC
    Manufacturing date: 9/2013

    cardSize: 7861.17 MB (MB = 1,000,000 bytes)
    flashEraseSize: 128 blocks
    eraseSingleBlock: true
    OCR: 0XC0FF8000

    SD Partition Table
    part,boot,type,start,length
    1,0X0,0XE,8192,2358996
    2,0X0,0X85,2367188,12986668
    3,0X0,0X0,0,0
    4,0X0,0X0,0,0

    Volume is FAT32
    blocksPerCluster: 32
    clusterCount: 73679
    freeClusters: 5948
    freeSpace: 97.45 MB (MB = 1,000,000 bytes)
    fatStartBlock: 8288
    fatCount: 2
    blocksPerFat: 576
    rootDirStart: 2
    dataStartBlock: 9440
    Data area is not aligned on flash erase boundaries!
    Download and use formatter from www.sdcard.org!
    Moving the card to the internal SD card slot fails with the 0x20,0xFF error as before.

    Is it possible I got a bad SD card slot?

  7. #7
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    6,090
    Quote Originally Posted by SmileyDude View Post
    So I'm not very familiar with any of the teensy models, since the 3.6 is my first one. So please forgive me if I'm missing something obvious here. Looking at the datasheet for the microcontroller, there appears to be three SPI buses on the chip. Looking at the pinout card for the teensy 3.6, my guess would be that the SD card is using SPI2, since the breakout pads for that bus is located directly underneath the microSD slot.

    My question is (assuming SPI2 is being used), if I use the continuity tester on my multimeter, should I see continuity between the SCK2 pin on the bottom and the CLK pin on the microSD slot?
    The T_3.5 & T_3.6 share common heritage - but these new models have extended hardware capabilities that are new to all and evolving - the SD adapter is one of those things.

    The onboard SD adapter does not use any of the exposed SPI interfaces. There are dedicated SDIO lines providing a 4 bit parallel SPI interface - the is what the post #2 link interfaces to. Pull down that code and put the SDFAT folder in 'your_sketchbook/libraries' and run the "Examples / TeensySdioDemo" - IIRC that is how that one worked for me.

  8. #8
    As dfragster stated above the new Teensy 3.5 and Teensy 3.6 onboard SD card utilizes a special SD card controller in the microprocessor that has dedicated SDIO lines to the SD card. You need to modify the example code to switch from the old 1bit SPI interface to the new 4bit SDIO interface when trying to use the new onboard SD Card.

    The key change is to edit this line -> #define USE_SDIO 1

    Code:
    /*
     * This program attempts to initialize an SD card and analyze its structure.
     */
    #include <SPI.h>
    #include <SdFat.h>
    
    // Set USE_SDIO to zero for SPI card access. 
    #define USE_SDIO 1
    /*
     * SD chip select pin.  Common values are:
     *
     * Arduino Ethernet shield, pin 4.
     * SparkFun SD shield, pin 8.
     * Adafruit SD shields and modules, pin 10.
     * Default SD chip select is the SPI SS pin.
     */
    const uint8_t SD_CHIP_SELECT = SS;
    /*
     * Set DISABLE_CHIP_SELECT to disable a second SPI device.
     * For example, with the Ethernet shield, set DISABLE_CHIP_SELECT
     * to 10 to disable the Ethernet controller.
     */
    const int8_t DISABLE_CHIP_SELECT = -1;
    
    #if USE_SDIO
    // Use faster SdioCardEX
    SdFatSdioEX sd;
    // SdFatSdio sd;
    #else // USE_SDIO
    SdFat sd;
    #endif  // USE_SDIO
    
    // serial output steam
    ArduinoOutStream cout(Serial);
    
    // global for card size
    uint32_t cardSize;
    
    // global for card erase size
    uint32_t eraseSize;
    //------------------------------------------------------------------------------
    // store error strings in flash
    #define sdErrorMsg(msg) sd.errorPrint(F(msg));
    //------------------------------------------------------------------------------
    uint8_t cidDmp() {
      cid_t cid;
      if (!sd.card()->readCID(&cid)) {
        sdErrorMsg("readCID failed");
        return false;
      }
      cout << F("\nManufacturer ID: ");
      cout << hex << int(cid.mid) << dec << endl;
      cout << F("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl;
      cout << F("Product: ");
      for (uint8_t i = 0; i < 5; i++) {
        cout << cid.pnm[i];
      }
      cout << F("\nVersion: ");
      cout << int(cid.prv_n) << '.' << int(cid.prv_m) << endl;
      cout << F("Serial number: ") << hex << cid.psn << dec << endl;
      cout << F("Manufacturing date: ");
      cout << int(cid.mdt_month) << '/';
      cout << (2000 + cid.mdt_year_low + 10 * cid.mdt_year_high) << endl;
      cout << endl;
      return true;
    }
    //------------------------------------------------------------------------------
    uint8_t csdDmp() {
      csd_t csd;
      uint8_t eraseSingleBlock;
      if (!sd.card()->readCSD(&csd)) {
        sdErrorMsg("readCSD failed");
        return false;
      }
      if (csd.v1.csd_ver == 0) {
        eraseSingleBlock = csd.v1.erase_blk_en;
        eraseSize = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low;
      } else if (csd.v2.csd_ver == 1) {
        eraseSingleBlock = csd.v2.erase_blk_en;
        eraseSize = (csd.v2.sector_size_high << 1) | csd.v2.sector_size_low;
      } else {
        cout << F("csd version error\n");
        return false;
      }
      eraseSize++;
      cout << F("cardSize: ") << 0.000512*cardSize;
      cout << F(" MB (MB = 1,000,000 bytes)\n");
    
      cout << F("flashEraseSize: ") << int(eraseSize) << F(" blocks\n");
      cout << F("eraseSingleBlock: ");
      if (eraseSingleBlock) {
        cout << F("true\n");
      } else {
        cout << F("false\n");
      }
      return true;
    }
    //------------------------------------------------------------------------------
    // print partition table
    uint8_t partDmp() {
      mbr_t mbr;
      if (!sd.card()->readBlock(0, (uint8_t*)&mbr)) {
        sdErrorMsg("read MBR failed");
        return false;
      }
      for (uint8_t ip = 1; ip < 5; ip++) {
        part_t *pt = &mbr.part[ip - 1];
        if ((pt->boot & 0X7F) != 0 || pt->firstSector > cardSize) {
          cout << F("\nNo MBR. Assuming Super Floppy format.\n");
          return true;
        }
      }
      cout << F("\nSD Partition Table\n");
      cout << F("part,boot,type,start,length\n");
      for (uint8_t ip = 1; ip < 5; ip++) {
        part_t *pt = &mbr.part[ip - 1];
        cout << int(ip) << ',' << hex << int(pt->boot) << ',' << int(pt->type);
        cout << dec << ',' << pt->firstSector <<',' << pt->totalSectors << endl;
      }
      return true;
    }
    //------------------------------------------------------------------------------
    void volDmp() {
      cout << F("\nVolume is FAT") << int(sd.vol()->fatType()) << endl;
      cout << F("blocksPerCluster: ") << int(sd.vol()->blocksPerCluster()) << endl;
      cout << F("clusterCount: ") << sd.vol()->clusterCount() << endl;
      cout << F("freeClusters: ");
      uint32_t volFree = sd.vol()->freeClusterCount();
      cout <<  volFree << endl;
      float fs = 0.000512*volFree*sd.vol()->blocksPerCluster();
      cout << F("freeSpace: ") << fs << F(" MB (MB = 1,000,000 bytes)\n");
      cout << F("fatStartBlock: ") << sd.vol()->fatStartBlock() << endl;
      cout << F("fatCount: ") << int(sd.vol()->fatCount()) << endl;
      cout << F("blocksPerFat: ") << sd.vol()->blocksPerFat() << endl;
      cout << F("rootDirStart: ") << sd.vol()->rootDirStart() << endl;
      cout << F("dataStartBlock: ") << sd.vol()->dataStartBlock() << endl;
      if (sd.vol()->dataStartBlock() % eraseSize) {
        cout << F("Data area is not aligned on flash erase boundaries!\n");
        cout << F("Download and use formatter from www.sdcard.org!\n");
      }
    }
    //------------------------------------------------------------------------------
    void setup() {
      delay(2000);
      Serial.begin(9600);
      
      // Wait for USB Serial 
      while (!Serial) {
        SysCall::yield();
      }
    
      // use uppercase in hex and use 0X base prefix
      cout << uppercase << showbase << endl;
    
      // F stores strings in flash to save RAM
      cout << F("SdFat version: ") << SD_FAT_VERSION << endl;
    #if !USE_SDIO  
      if (DISABLE_CHIP_SELECT < 0) {
        cout << F(
               "\nAssuming the SD is the only SPI device.\n"
               "Edit DISABLE_CHIP_SELECT to disable another device.\n");
      } else {
        cout << F("\nDisabling SPI device on pin ");
        cout << int(DISABLE_CHIP_SELECT) << endl;
        pinMode(DISABLE_CHIP_SELECT, OUTPUT);
        digitalWrite(DISABLE_CHIP_SELECT, HIGH);
      }
      cout << F("\nAssuming the SD chip select pin is: ") <<int(SD_CHIP_SELECT);
      cout << F("\nEdit SD_CHIP_SELECT to change the SD chip select pin.\n");
    #endif  // !USE_SDIO  
    }
    //------------------------------------------------------------------------------
    void loop() {
      // Read any existing Serial data.
      do {
        delay(10);
      } while (Serial.available() && Serial.read() >= 0);
    
      // F stores strings in flash to save RAM
      cout << F("\ntype any character to start\n");
      while (!Serial.available()) {
        SysCall::yield();
      }
    
      uint32_t t = millis();
    #if USE_SDIO
      if (!sd.cardBegin()) {
        sdErrorMsg("\ncardBegin failed");
        return;
      }
    #else  // USE_SDIO
      // Initialize at the highest speed supported by the board that is
      // not over 50 MHz. Try a lower speed if SPI errors occur.
      if (!sd.cardBegin(SD_CHIP_SELECT, SD_SCK_MHZ(50))) {
        sdErrorMsg("cardBegin failed");
        return;
      }
     #endif  // USE_SDIO 
      t = millis() - t;
    
      cardSize = sd.card()->cardSize();
      if (cardSize == 0) {
        sdErrorMsg("cardSize failed");
        return;
      }
      cout << F("\ninit time: ") << t << " ms" << endl;
      cout << F("\nCard type: ");
      switch (sd.card()->type()) {
      case SD_CARD_TYPE_SD1:
        cout << F("SD1\n");
        break;
    
      case SD_CARD_TYPE_SD2:
        cout << F("SD2\n");
        break;
    
      case SD_CARD_TYPE_SDHC:
        if (cardSize < 70000000) {
          cout << F("SDHC\n");
        } else {
          cout << F("SDXC\n");
        }
        break;
    
      default:
        cout << F("Unknown\n");
      }
      if (!cidDmp()) {
        return;
      }
      if (!csdDmp()) {
        return;
      }
      uint32_t ocr;
      if (!sd.card()->readOCR(&ocr)) {
        sdErrorMsg("\nreadOCR failed");
        return;
      }
      cout << F("OCR: ") << hex << ocr << dec << endl;
      if (!partDmp()) {
        return;
      }
      if (!sd.fsBegin()) {
        sdErrorMsg("\nFile System initialization failed.\n");
        return;
      }
      volDmp();
    }
    You will then see output similar to this from a SD card inserted into the onboard SD card holder.

    Code:
    SdFat version: 20160913
    
    type any character to start
    
    init time: 229 ms
    
    Card type: SD2
    
    Manufacturer ID: 0X1B
    OEM ID: SM
    Product: 00000
    Version: 1.0
    Serial number: 0XE162AF16
    Manufacturing date: 1/2012
    
    cardSize: 2002.78 MB (MB = 1,000,000 bytes)
    flashEraseSize: 64 blocks
    eraseSingleBlock: true
    OCR: 0X80FF8000
    
    SD Partition Table
    part,boot,type,start,length
    1,0X0,0XE,129,3911551
    2,0X0,0X0,0,0
    3,0X0,0X0,0,0
    4,0X0,0X0,0,0
    
    Volume is FAT16
    blocksPerCluster: 64
    clusterCount: 61109
    freeClusters: 56909
    freeSpace: 1864.79 MB (MB = 1,000,000 bytes)
    fatStartBlock: 131
    fatCount: 2
    blocksPerFat: 239
    rootDirStart: 609
    dataStartBlock: 641
    Data area is not aligned on flash erase boundaries!
    Download and use formatter from www.sdcard.org!
    Last edited by drmartin; 10-03-2016 at 05:12 AM.

  9. #9
    Since it has the SDIO 4-bit interface, T3.6 is capable of doing about 20 Mbyte/sec I/O to a SD card. That's pretty impressive, and I don't think that kind of performance happens with any traditional Arduino using only 1-bit SPI.

  10. #10
    Senior Member
    Join Date
    Jul 2014
    Posts
    1,633
    Quote Originally Posted by johnnyfp View Post
    Try the SDIO library and example available from https://github.com/greiman/SdFat-beta
    you can also use https://github.com/WMXZ-EU/uSDFS which only works for T3.5/T3.6 as it only uses sdio. It works onFAT32 ans exFAT formatted disks.

  11. #11
    Junior Member
    Join Date
    Oct 2016
    Posts
    11
    Quote Originally Posted by drmartin View Post
    As dfragster stated above the new Teensy 3.5 and Teensy 3.6 onboard SD card utilizes a special SD card controller in the microprocessor that has dedicated SDIO lines to the SD card. You need to modify the example code to switch from the old 1bit SPI interface to the new 4bit SDIO interface when trying to use the new onboard SD Card.

    The key change is to edit this line -> #define USE_SDIO 1
    This is what I was missing. I somehow had missed that that built in microSD slot had a native SD interface instead of using SPI like pretty much everything else in the Arduino world. Once I made that change, the SdInfo example worked with the built in microSD slot.

    Thanks for your help everyone!

  12. #12
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    17,022
    Please allow me to apologize, as I had meant to get basic (not necessarily optimized) 4 bit SDIO support into the default Arduino SD library by this point.... but Kickstarter....

    I'm still in New York, writing this from a hotel room, but traveling back to Oregon later today. I will work on the SD lib this week and hopefully get a 1.31-beta2 version by the weekend. Support for the on-board SD card and fixing the serial number in HSRUN mode are my top priorities.

    Later I'm planning to complete the SD lib optimization work I started in January, to use more memory for caching and multi-sector reads, and leverage DMA, to (hopefully) allow the much faster performance to be seen with most sketches, not just specific benchmarks.

  13. #13
    Senior Member
    Join Date
    Jan 2013
    Posts
    843
    Quote Originally Posted by PaulStoffregen View Post
    Later I'm planning to complete the SD lib optimization work I started in January, to use more memory for caching and multi-sector reads, and leverage DMA, to (hopefully) allow the much faster performance to be seen with most sketches, not just specific benchmarks.
    What would be rather useful is an asynchronous API - e.g. files with "readAsync()", "writeAsync()", "asyncProgress()" (returns how much has been read / written so that partial data can be used).

    Another useful feature would be support for pre-allocating, pre-erasing a file that will then support much faster / lower latency writes.

  14. #14
    Senior Member
    Join Date
    Jul 2014
    Posts
    1,633
    Quote Originally Posted by tni View Post
    What would be rather useful is an asynchronous API - e.g. files with "readAsync()", "writeAsync()", "asyncProgress()" (returns how much has been read / written so that partial data can be used).

    Another useful feature would be support for pre-allocating, pre-erasing a file that will then support much faster / lower latency writes.
    Here it becomes tricky. It is not difficult to have, for example, async operations with SDIO (after all the K66 has its own internal DMA for sdio operations) and my approach is using this, but this does not mean that the existing FS (being it Bill Greiman's or CHaN's implementation) would support async operations. For example you cannot simply make all read/write async, as the FS needs do also synchronous operations. So if the FS for which you provide the SDIO interface is not supporting a mix of async operations, then you have to wait after each read/write operation for completion.
    At least that is how I do it. All read/write use internal DMA and are async but the FS interface (diskio.c) waits for completion. I did this, because for simple data logging, I wrote my own loggingFS, that can indeed write asynchronously to disk. But this is I not a general FS and functionality is limited to write-only.

    Next: pre-allococation, pre-erasing are FS functionality and not SDIO. Interestingly, the write/read start/stop operation available for SPI seems to be missing in the SDIO world, at least I have not found it.

  15. #15
    Junior Member
    Join Date
    Oct 2016
    Posts
    11
    Quote Originally Posted by PaulStoffregen View Post
    Please allow me to apologize, as I had meant to get basic (not necessarily optimized) 4 bit SDIO support into the default Arduino SD library by this point.... but Kickstarter....
    Not a problem at all. If I had made the connection that the SD slot was using SDIO, I probably would've figured things out a bit sooner Given that this board just came out, I'm impressed with how much is already supported. Thanks again!

  16. #16
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    17,022
    I've committed on github the first attempt at 4 bit SDIO support in the Arduino SD library.

    https://github.com/PaulStoffregen/SD

    If anyone wants to try this, just replace your copy of the SD lib in hardware/teensy/avr/libraries/SD with this copy from github. Do *not* edit SD_t3.h for the optimized stuff.

    In your program, use BUILTIN_SDCARD for the chip select pin. Like this:

    Code:
      if (!(SD.begin(BUILTIN_SDCARD))) {
        while (1) {
          Serial.println("Unable to access the SD card");
          delay(500);
        }
      }
    If you use it, please reply here to let me know how it works for you? My hope is to release 1.31-beta2 by this weekend, with this and several other fixes.

  17. #17
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,394
    Great !
    Tested with my audiocodecs ( mp3 & aac ) : Works.
    A first quick'n dirty benchmark shows ~1.6 MB/sec reading. Way too slow for video, but might be enough for most use-cases..
    Last edited by Frank B; 10-20-2016 at 12:13 PM.

  18. #18
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,382
    OK, after tidying up my sketchbook/libraries (?new SdFat conflict), i installled the new SD library on 1.6.11/1.30. listed and read files OK. Paul's version is not optimized yet (only single sector reads), but here are comparisons for file read of 512 bytes and 2048 bytes using K64 (T3.5)

    Code:
                  Times microseconds (megabits/sec)
                  pjrc SD      SdFat       uSDFS          SPI0 external SD
                 4-bit SDIO  4-bit SDIO  4-bit SDIO      SD.h      SdFat.h
    read 512     453  (9.0)   313 (13.1)    295 (15)    456 (9.0)  492 (8.3)
    read 2048   1563 (10.5)   394 (41.6)    396 (41)   1882 (8.7)  967 (16.9)
    More SdFat info
    https://forum.pjrc.com/threads/36737...Teensy-3-5-3-6
    https://forum.pjrc.com/threads/36331...6-microSD-pins
    Last edited by manitou; 10-20-2016 at 04:27 PM.

  19. #19
    Senior Member
    Join Date
    Nov 2012
    Posts
    240
    Quote Originally Posted by manitou View Post
    OK, after tidying up my sketchbook/libraries (?new SdFat conflict), i installled the new SD library on 1.6.11/1.30. listed and read files OK. Paul's version is not optimized yet (only single sector reads), but here are comparisons for file read of 512 bytes and 2048 bytes using K64 (T3.5)

    Code:
                  Times microseconds (megabits/sec)
                  pjrc SD      SdFat       uSDFS          SPI0 external SD
                 4-bit SDIO  4-bit SDIO  4-bit SDIO      SD.h      SdFat.h
    read 512     453  (9.0)   313 (13.1)    295 (15)    456 (9.0)  492 (8.3)
    read 2048   1563 (10.5)   394 (41.6)    396 (41)   1882 (8.7)  967 (16.9)
    More SdFat info
    https://forum.pjrc.com/threads/36737...Teensy-3-5-3-6
    https://forum.pjrc.com/threads/36331...6-microSD-pins
    Are you using the latest SdFat-beta? Are you using the SdFatSdioEX class?

    Here are Teensy 3.5 results using a 32GB Samsung Pro+ with the TeensySdioDemo example.

    SDIO SdFatSdioEX class:

    size,write,read
    bytes,KB/sec,KB/sec
    size,write,read
    bytes,KB/sec,KB/sec
    512,14901.45,15329.58
    1024,15151.93,15570.79
    2048,15424.21,15896.00
    4096,15654.45,16053.19
    8192,15729.68,16129.95
    16384,15774.26,16128.96
    32768,15852.30,16104.16
    Read for 512 bytes is 15329 KB/sec or 122 megabits/sec. Read for 2048 KB/sec is 15896 KB/sec or 127 megabits/sec.

    If you can dedicate an SPI port, you can use the SdFatEX class with an SPI SD module.

    With a Teensy 3.6 using SdFatEX at 180 MHz and the bench example:

    Read speed for 512 byte buffers with SPI is 3293 KB/sec or 26 megabits/sec.

    Read speed for 2048 byte buffers with SPI is 3299 KB/sec also 26 megabits/sec.

    Speed is limited by my SPI driver. It is program I/O using the SPI FIFO.

  20. #20
    Quote Originally Posted by Bill Greiman View Post

    With a Teensy 3.6 using SdFatEX at 180 MHz and the bench example:

    Read speed for 512 byte buffers with SPI is 3293 KB/sec or 26 megabits/sec.

    Read speed for 2048 byte buffers with SPI is 3299 KB/sec also 26 megabits/sec.

    Speed is limited by my SPI driver. It is program I/O using the SPI FIFO.
    Why is the 3.6 lagging behind the 3.5 in this test, or am I missing something?

  21. #21
    Senior Member
    Join Date
    Nov 2012
    Posts
    240
    Quote Originally Posted by SharpEars View Post
    Why is the 3.6 lagging behind the 3.5 in this test, or am I missing something?
    The 3.5 uses SDIO with the builtin socket. A 3.6 will be even faster using SDIO with the SdFatSdioEX class.

    Here is a 3.6 at 180 MHz with SdFatSdioEX.

    size,write,read
    bytes,KB/sec,KB/sec
    512,18054.97,18628.56
    1024,18160.34,18759.33
    2048,17940.78,18871.71
    4096,17907.46,19007.74
    8192,17898.33,19035.99
    16384,17800.50,19051.21
    32768,17878.27,19021.57
    Here is a 3.6 at 240 MHz with SdFatSdioEX.

    size,write,read
    bytes,KB/sec,KB/sec
    512,19433.28,20050.26
    1024,19553.27,20139.75
    2048,19159.38,20237.90
    4096,19212.21,20224.19
    8192,19168.66,20314.15
    16384,19278.66,20384.25
    32768,19360.17,20308.25
    The 240 MHz test is limited by a max SDIO clock of 48 MHz which is 240/5. The 180 MHz test runs with an SDIO clock of 45 MHz which is 180/4. Too bad the max SD clock speed of 50 MHz is not possible. I have not tried overclocking the Samsung Pro+ microSD, it might run at a rate higher than 50 MHz. The Pro+ microSD supports 208 MHz clock in UH I bus mode but the Teensy does not

    I used the 3.6 for an SPI example since I don't have a 3.5 with an attached SPI SD module. A 3.5 will be slightly slower in the SPI test.
    Last edited by Bill Greiman; 10-27-2016 at 07:41 PM.

  22. #22
    Senior Member
    Join Date
    Nov 2012
    Posts
    240
    Tried overclocking a Samsung PRO Select 32 GB microSD.

    At 60 MHz SDIO clock = 240 MHz / 4.

    size,write,read
    bytes,KB/sec,KB/sec
    512,23488.95,24153.22
    1024,23554.44,24420.63
    2048,23867.68,24657.51
    4096,23614.32,24885.07
    8192,24011.01,24889.28
    16384,24028.41,24983.72
    32768,23721.16,24862.80
    At 80 MHz SDIO clock = 240 MHz / 3.

    size,write,read
    bytes,KB/sec,KB/sec
    512,29232.88,30546.46
    1024,29664.37,31105.21
    2048,29523.73,31342.76
    4096,29550.25,31830.49
    8192,30222.68,31637.34
    16384,30247.86,31734.04
    32768,29727.13,31926.68
    Don't expect me to support it but at line 518 of SdioTeensy.cpp

    Code:
    //    kHzSdClk = 50000;
        kHzSdClk = 80000;

  23. #23
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    17,022
    Quote Originally Posted by Bill Greiman View Post
    Tried overclocking a Samsung PRO Select 32 GB microSD.
    Did you use CMD6 to put the card into high speed mode?

  24. #24
    Senior Member
    Join Date
    Nov 2012
    Posts
    240
    Quote Originally Posted by PaulStoffregen View Post
    Did you use CMD6 to put the card into high speed mode?
    Yes but the spec for high speed mode is 50 MHz max.

    See Section 4.3.11 of the SD physical layer spec.

    Although the Rev 1.01 SD memory card supports up to 12.5 MB/sec interface speed, the speed of 25
    MB/sec is necessary to support increasing performance needs of the host and because memory size
    continues to grow.
    To achieve the 25 MB/sec interface speed, the clock rate is increased to 50 MHz and CLK/CMD/DAT
    signal timing and circuit conditions are reconsidered and changed from the Physical Layer Specification
    Version 1.01.
    After power up, the SD memory card is in the default speed mode, and by using Switch Function
    command (CMD6), the Version 1.10 and higher SD memory card can be placed in High-Speed mode.
    The High-Speed function is a function in the access mode group (see Table 4-11). Supporting High-
    Speed mode is optional.
    The SDIO interface on most micro-controllers is limited to the 3.3V 1.10 standard. I was surprised that the card and Teensy controller worked at 80 MHz.

    the card supports 208 MHz UH I with 1.8V signaling.

    You might also want to read section 4.13 of the standard before you continue with your cache optimization. Modern SD cards are nasty. I really had to fight to get this 30 MB/sec performance. This is 30 MB/sec reading into a 512 byte buffer with no additional cache in the Teensy.

    I use tricks in the driver to use the internals of the card instead of more cache in the Teensy.
    Last edited by Bill Greiman; 10-27-2016 at 09:10 PM.

  25. #25
    Senior Member ninja2's Avatar
    Join Date
    Aug 2016
    Location
    Adelaide, Australia
    Posts
    151
    Read all this good info but I have a simple question - should I use SD library in teensyduino 1.34 (which I have already), or install SdFat library separately?

    I have existing (non-teensy) code I would like to reuse ...
    I do use long filenames ...
    higher/performance speed is always good, but not critical in my applications (so far) ...

    Edit: I just spotted the 'Data Manipulation Libraries' section at bottom of teensyduino 'Main List' and it lists both SD and SdFat (although no hyperlinks yet). So perhaps they are both built into teensyduino anyway??
    What is the overlap between teensyduino and arduino stuff? For example if teensyduino lists SD does that mean it is separate from arduino SD lib, or the arduino SD lib has teensy mods built in?
    Last edited by ninja2; 01-14-2017 at 09:37 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •