This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SPI delays between writes

I am currently using the 17.0.2 SDK to develop some code on the nrf52832 which involves streaming data via SPI to an external flash.  I need to stream this data at a ~50KHz rate.  The data to the flash consists of the write command (8bits) followed by the data (16bits), after which the write happens and the cycle is repeated.  I wrote some code to do this using the library functions.  The first code asserted CE once again after the data transfer and looked at the MISO pin (memory write status from the chip) to see when the write cycle was done (first picture).  I then modified the code to simply delay while the write cycle was happening (second picture).  As you can see in the pictures below, there is a very large amount of time that is "wasted" in both scenarios.  In particular, in the second scenario, there is a large amount of time where CE is low before the data is transferred and the again when CE is low after the data has been transferred.  These delays are such that I cannot meet the target rate.  In order to meet my target data rate I need to reduce these delays.  Are there things I can do in the library to reduce those delays or do I need to write my own SPI code?  This streaming code will likely run in the foreground and therefore can be blocking while it is running if it has to be.  Please let me know the best way to increase my data throughput.  Thanks!

SPI write with handshake

SPI write no handshake (timing only)

Parents Reply
  • Hi Tim,

    There is no direct hardware control of the CE pin when using SPI, so the application will need to handle the CE pin manually, typically there will be some delays due to the way it's implemented. E.g. there will interrupt latencies here du to possible wakeup before and after the SPI transfer, and possible delay due to the SoC framework if the softdevice is enabled and need to forward the interrupt to the application, not to mention some delay due to code execution handling the interrupt. Adding these up you may experience several us of delay before and after SPI transcation and CE pin. 

    The only real way to reduce this is to use PPI to handle the CE pin and SPI transcation. There is a discussion in this case how this can be done:
    https://devzone.nordicsemi.com/f/nordic-q-a/13523/ppi-to-spim-task-how-to

    Alternatively use the nRF52840 which have an SPIM3 interface with CE handling in hardware.

    Kenneth

Children
  • Hi Kenneth,

    Thank you for the answer.  I understand your explanation.  Fortunately, running the SPI in blocking mode gets me just under my bandwidth limit, so I should be good to go.  However, I do have one additional question.  In my trying to optimize the CE assertion timing I put a bunch of set/clear commands together to see what the maximum GPIO toggle rate was.  If I remember right it was about 2uS per transition.  This seemed slower than I expected.  I am very new to the ARM architecture so my question might be ignorant, but I was wondering if there was a way to get faster IO response by changing the peripheral clock speed to the IO or by some other means.

    Thanks for your help,

    Tim

  • Hi Tim,

    The GPIO peripheral run of 16MHz (this is fixed), however depending on how the code is written and compiled, and there is an OS running here also, then you likely will not be able to get this high speed. Though, 2us, was a bit slower than I would expect yes.

    Kenneth

Related