Bill Greiman
Well-known member
Sharing the SPI bus with SdFat can be a problem for applications that use SPI in interrupts. Paul has developed SPI transactions which will help in many cases.
I will add SPI transaction to SdFat but this will be a limited solution since SdFat will still transfer an entire 512 byte block. The SPI bus can be released in a transaction while the SD is busy but you can not reliably breakup the actual data transfer.
This is from Elm Chan http://elm-chan.org/docs/mmc/mmc_e.html, the author of FatFS, the most used open source FAT file system for embedded systems.
Another solution is to use software SPI for SdFat or in the interrupt routine.
I am developing a general software SPI library. Here are some results.
A scope trace for the transfer of the byte 0XAA is attached. Yellow is clock and green is data. The timing is not as good as hardware SPI but works in devices I have tested. A single macro is used for each clock period but compiler optimization make the timing for each bit different. I may try to improve it. The clock rate is something like 4-5 MHz.
Here is a test with the SdFat bench example comparing hardware SPI with software SPI on Teensy 3.1.
Software SPI:
Hardware SPI:
Here is the SdFat PrintBenchmark.
Software SPI:
Hardware SPI:
I will post the software SPI library. The library supports all three SPI modes. There is no SPI speed parameter, the speed is fixed at about 4-5 MHz.
The library is a template class.
I will add SPI transaction to SdFat but this will be a limited solution since SdFat will still transfer an entire 512 byte block. The SPI bus can be released in a transaction while the SD is busy but you can not reliably breakup the actual data transfer.
This is from Elm Chan http://elm-chan.org/docs/mmc/mmc_e.html, the author of FatFS, the most used open source FAT file system for embedded systems.
In principle in SPI mode, the CS signal must be kept asserted during a transaction. However there is an exception to this rule. When the card is busy, the host controller can deassert CS to release SPI bus for any other SPI devices.
Another solution is to use software SPI for SdFat or in the interrupt routine.
I am developing a general software SPI library. Here are some results.
A scope trace for the transfer of the byte 0XAA is attached. Yellow is clock and green is data. The timing is not as good as hardware SPI but works in devices I have tested. A single macro is used for each clock period but compiler optimization make the timing for each bit different. I may try to improve it. The clock rate is something like 4-5 MHz.
Here is a test with the SdFat bench example comparing hardware SPI with software SPI on Teensy 3.1.
Software SPI:
File size 5 MB
Buffer size 512 bytes
write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
237.35,62658,1851,2155
read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
539.92,1992,933,947
Hardware SPI:
File size 5 MB
Buffer size 512 bytes
write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
398.41,60649,941,1284
read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
1351.26,1418,363,378
Here is the SdFat PrintBenchmark.
Software SPI:
Test of println(uint16_t)
Time 0.55 sec
File size 128.89 KB
Write 234.77 KB/sec
Maximum latency: 8882 usec, Minimum Latency: 9 usec, Avg Latency: 26 usec
Test of println(double)
Time 1.04 sec
File size 149.00 KB
Write 142.58 KB/sec
Maximum latency: 1178 usec, Minimum Latency: 29 usec, Avg Latency: 51 usec
Hardware SPI:
Software SPI will be fast enough for many applications. You could use hardware SPI for non-interrupt code and use software SPI for interrupts to get quick access to an SPI device at about 4 MHz.Test of println(uint16_t)
Time 0.34 sec
File size 128.89 KB
Write 382.46 KB/sec
Maximum latency: 3969 usec, Minimum Latency: 10 usec, Avg Latency: 15 usec
Test of println(double)
Time 0.94 sec
File size 149.00 KB
Write 158.85 KB/sec
Maximum latency: 55905 usec, Minimum Latency: 29 usec, Avg Latency: 46 usec
I will post the software SPI library. The library supports all three SPI modes. There is no SPI speed parameter, the speed is fixed at about 4-5 MHz.
The library is a template class.
Code:
/**
* @class SoftSPI
* @brief Fast software SPI.
*/
template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin, uint8_t Mode = 0>
class SoftSPI {
Attachments
Last edited: