Replies: 14 comments 19 replies
-
No problem adding a FatFS filesystem if someone really needs the speed of SDIO. FWIW the SDFat library from grieman can do most of what you mention, I believe, but right now it's not implemented. ExFat, for example, is just a |
Beta Was this translation helpful? Give feedback.
-
I am interested in RP2040 SDIO for SdFat. SdFat has support for SDIO. I implemented a Teensy driver. There apparently is a SdFat SDIO driver for some STM32 chip. Here is the performance for Teensy 4.1:
Here is the performance for SDIO with FatFS on RP2040 from the above site:
This is great performance but it requires huge writes and reads with FatFS. I modified SdFat so the SDIO driver is put in infinite multi-block read or write mode and kept in that mode as long as possible. This means all file I/O is fast with only the standard 512 byte internal sector buffer. Here is the result on Teensy 4.1 for 20 byte reads and writes.
I don't know if the implementation for RP2040 allows the infinite multi block mode. I will start looking at the versions of the RP2040 driver. I may need help if the driver's PIO needs to be modified. I have only played with the simplest PIO examples. Here is the current state of SdFat SPI on RP2040:
This result takes advantage of the SPI |
Beta Was this translation helpful? Give feedback.
-
SdFat supports exFAT, FAT32/FAT16/FAT12 and file rename with move. UTF-8 is supported for filenames. I have not implemented disk labels since there have been no requests. The base classes for the file system support the four MBR partition. I don't use it for SD cards since modern SD cards only guarantee high performance if you use the SD standard single partition layout. The hardware SD caching and RAM buffering is optimized for this layout. New cards will even optimize flash for this layout. Modern flash devices use pseudo SCL for some areas. SdFat has features for very fast data-logging, I have logged ADC data on Teensy at over a million samples per second with no missed points due to write latency. I pre-allocate a file and write 512 byte sectors using a circular buffer as a queue. SD cards have a not busy functions that guarantees you can send 512 bytes at full SDIO speed. |
Beta Was this translation helpful? Give feedback.
-
I looked at all the Rp2040 SDIO versions. I almost missed the best version for SdFat. I looked at the ZuluSCSI version and saw they were porting to a version for their boards. Then I decided to look at the wrapper for their boards. It was for SdFat. They use a port of SdFat on their boards. That's the good news, almost certainly I can have 4-bit SDIO working. The less good news is that I have two modes for SDIO. A mode that works with almost all MCU SDIO controllers but doesn't allow the infinite transfer mode and one for more flexible controllers with infinite transfers. They have only implemented the former. On other boards the simple SDIO runs slower than my SPI implementation until you do about 8 KB writes and 4KB reads aligned on 32-bit boundaries and only read or write multiples of 4-bytes. I didn't include SDIO for ESP32 since I couldn't get performance. The problem is SD cards now have huge flash pages, multiples of 16 KB. the 512 byte sectors are emulated. When you end a write, an entire flash page is programmed. The next 512 byte write causes the just programmed page to be copied to a RAM buffer, 512 bytes added and a new page programmed. I estimate data rates in a high end card reach 200 MB/sec with lots of flash wear. I have some hope since RP2040 is flexible. I have never done anything beyond looking at examples of PIO programs for RP2040 so this may be a learning opportunity. This is how ZuluSCSI handled the infinite transfer API which is now my todo list:
|
Beta Was this translation helpful? Give feedback.
-
I see that there is continued development of SDIO for RP2040 so I have done this post to see if people with experience are interested in an implementation that provides fast performance for all read/write sizes. Seems like a common effort is the best answer. |
Beta Was this translation helpful? Give feedback.
-
I am making progress. I have a version of SDIO working with this board support package. I will be able to get good performance for large transfers but there will be restrictions. One of the biggest problems is 32-bit alignment for DMA and PIO. This means the best performance is only obtained if a file is read/written with transfers that are multiples of four bytes. The optimal size is multiples of 512 bytes. This eliminates memcpy to/from tmp buffers. The other problem is being able to put the SD in infinite read or write mode like I do for optimized SPI mode or SDIO on Teensy. It requires SD clock control that not in the current PIO code. Also the small PIO FIFOs may be a problem. Teensy has full sector FIFOs. PIO requires four contiguous GPIOs. The PIO programs need to be modified and re-assembled to change this. I need to select several choices for pre-assembled configurations and provide instructions for custom configurations. |
Beta Was this translation helpful? Give feedback.
-
From following that other issue in ZuluSCSI I have two questions I'm curious about:
Why does sharing SPI limit it to 24MHz? |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
I agree but I have too many things to maintain. I am only doing functionality needed for SdFat, MSBFIRST, SPI_MODE0 Maybe someone will make a real library. Here are the first SdFat results with a very rough version of PIO SPI. Of course I don't get the raw SPI speed due to overhead of file system and SD protocol. Here is what I did to get it to work with SdFat: Edit: No changes to the SdFat library, only the these changes to the app. Added PioSpi and modified config:
This is for 512 byte transfers. You can get a tiny bit more for large transfers. I get 7,112 KB/sec with 8,192 byte writes at 250 MHz CPU speed. Results:
CPU Speed: 200 MHz
CPU Speed: 250 MHz
|
Beta Was this translation helpful? Give feedback.
-
Here is a snapshot of my PIO SPI library. I included a version that works with the current release of SdFat. The zip file contains readme.txt and the PioSpi folder needed to try it with SdFat. I started to add all SPI modes for MSBFIRST but first I want to experiment with ideas for a full rewrite SDIO PIO while my memory of PIO is fresh. If you try it, let me know if it works for you. Here are the results I get with an old SD card that has SLC flash and is very good for SPI. At 250 MHz system clock:
|
Beta Was this translation helpful? Give feedback.
-
I have had good luck with most cards I have tried with the above PioSpi library. I have not tuned the library yet for these GPIO options.
The above card is: New versions don't perform well on MCUs. They are best on phones with huge read ahead/ write behind buffers. Here are a few bench results for newer cards. Notice max write latency is often high for new cards. They are optimized for phones with huge buffers. If you buy one of these cards today they many perform well on MCUs. Phone are the market. All Tests:
I like this card for consistent write latency. Fairly low cost for 128GB.
A high end Samsung card - disappointing.
A few SanDisk cards:
|
Beta Was this translation helpful? Give feedback.
-
I am interested in porting SDIO support to a custom board. Was there some progress on RP2350 yet? |
Beta Was this translation helpful? Give feedback.
-
You might try this version of SdFat with a development version of SDIO for RP2040. I have also tested on Pico 2 here. Edit: Looks like your pin-out would work. CMD and CLK can be on any pins and DAT on any four consecutive pins. |
Beta Was this translation helpful? Give feedback.
-
SanDisk Ultra probably explains the uneven write performance. Ultra will have occasional long latency for write. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
https://github.com/carlk3/no-OS-FatFS-SD-SPI-RPi-Pico/tree/sdio
I think it should be possible to integrate this into this core and add wrappers to allow usage of Arduino Streams, Files, etc.
Benefits would be (if I understand correctly):
I don't have the time to do that now. And I'm not sure if you would be open to completely replacing the FS or adding a second FS. So I'm just putting the idea out there for now.
Beta Was this translation helpful? Give feedback.
All reactions