This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SPI RX FIFO read delay

Hi all

I am working with an SD-card and communicating using SPI (as many others do).

Everything is working fine, however I notice some delays which are slowing down the read speed.

I am reading from the SD-card by transmitting dummy bytes to toggle the SPI clock and then reading from the rx fifo.

I do something like this:

/* Fill the TX FIFO with 8 bytes to clock out the 8 receive bytes */
for( uint8_t i = 0U; i < 8U; i++ )
{
/* Put some dummy data to toggle the clock */
ROM_SSIDataPut( SDC_SSI_BASE, 0xFF );
}

/* Read back the 8 bytes in the RX FIFO */
for( bytesReceived = 0U; bytesReceived < 8U; bytesReceived++ )
{
/* Read byte (read is blocking) */
ROM_SSIDataGet( SDC_SSI_BASE, &recvData ); /* Reading from the RX fifo seems slow!!! */
pRecvData[ bytesReceived ] = (uint8_t) ( recvData & 0xFF );
}

When I monitor the SPI signals on a scope I get:

Both figures show the clock signal from the SPI line. The top plot shows a single write of 8 bytes using the 8 byte TX fifo. The bottom plot shows back to back reads (using the 8 byte tx fifo to toggle the clock and the 8 byte rx fifo to read the result).

As you see, I have a big delay between each 8 byte block. It turns out that it is the (blocking) ROM_SSIDataGet which causes the delay - when the 8 bytes are read from the rx fifo.

I wonder if there is any good reason it takes so much time to read out the bytes from the rx fifo. The data are received during the transmit (when the clock is active on the plots) - so the data should be ready when the clock toggle using tx is complete?

I know that it is most likely possible to improve this using interrupts and dma... however, for my needs, reading like this is sufficient if I can reduce the delay between the blocks.

I use a custom board, a TIVA TM4C1233D5PMI and TivaWare_C_Series-2.1.2.111

I hope it makes sense.

I appreciate any help that you can provide.

Best regards

Christian

  • Are you sure it's the read that's the delay?

    If you have a spare I/O pin (or can use the select pin temporarily) set it high at the beginning of read and low at the end. Put on the same screen as your clock signal.

    Robert
  • And - unstated w/in your post - is the presence of any other software or hardware which may be, "grabbing" the MCU.

    KISS would ask you to repeat this test w/only the bare minimum SW & HW in play. And - substitution of your SD card w/newer/better may provide further insight.
  • Hi Robert

    Thanks for your suggestions!

    I have done the experiment you suggest with the following result:

    Both figures show the clock signal in blue and the read busy time in red. I have tried with optimization off and with optimization on (-O3 and -mf3 for speed).

    To my surprise, the optimization has quite a lot of impact. With optimization on (and for speed) it actually manages to finish reading just after the final bit is clocked out of the tx fifo. I think the optimized version is as quick as possible using this method.

     

  • Hi,

    The code runs basically in main loop without any other threads, interrupts etc.

    I will try with some other cards and see if I get other results. However, as the spi is duplex, the data should be available as soon as the tx fifo has finished - independent on the card I suppose.
  • I wouldn't expect any card dependencies on that but it's worth checking. I'd do a test after without the read time toggle. It may be having an impact now. I wouldn't bet on it but it's good to know.

    There are a few other things you can try as well, using a larger multiple (ie 16 or 32 bit at a time rather than 8) and hoisting the library code up to remove extra function calls. I'd only do the latter if you really needed the performance though.

    Robert
  • Hi Robert

    I have tested a range of SD-cards as you suggested.

    I will show my speed comparison results below - in case it can be of use for someone else.

    I have tested the timing / speed with four different SD-card - all in spi mode.

    I have tested the timing of the following operations:

    • Command 17 - Initiate single block read 
    • Command 18 - Initiate multi block read
    • Multiblock read interrupt
    • 1 block read (raw, without commands)
    • 4 block read (raw, witout commands and interrupt)

    The results are the following:

    The above timing result can be used to calculate maximum read speed of the 4 cards,

    Apacher max speed 1 block read: 564 [kB/s]
    Apacher max speed 4 block read: 981 [kB/s]
    Kingston max speed 1 block read: 565 [kB/s]
    Kingston max speed 4 block read: 982 [kB/s]
    SanDisk max speed 1 block read: 623 [kB/s]
    SanDisk max speed 4 block read: 983 [kB/s]
    SanDiskUltra max speed 1 block read: 563 [kB/s]
    SanDiskUltra max speed 4 block read: 943 [kB/s]

    The cards I have used for testing are:

    Thanks for the help

    Best regards

    Christian