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

NRF52 SPIM - send data as two byte pairs instead of one byte per interrupt

I have an SPI peripheral that has an odd protocol and in trying to sort out why it was acting up I finally caught a logic trace showing about a 13us break in the SPI data I was sending. Normally this wouldn’t be an issue but this peripheral has a clock that times out with a max period of 7200ns (7.2us).

As far I can tell I can’t rely on the soft device not breaking in an inserting these long gaps in my SPI transfer, if Im wrong about this or if there is some documentation on exactly what the max length of these soft device interrupts could be please let me know or point me to the docs.

Now onto the possible hack that could save me. It seems my peripheral only has an issue if the break in the data comes when the data line is high, which means the next bit coming across MOSI is a one. However if the interrupt from the soft device occurs when MOSI is low and the next byte is a zero then I don’t have an issue. Coincidentally the data being sent is in two byte pairs where the first byte is always zero and the second byte is 0-255, so if the interrupt is before the first byte of the pair I am okay, but if it is before the second byte then I have a problem. I can see from my logic trace that the first two bytes are sent together because of the SPI double buffering but after that the bytes are sent as singles. I am making the assumption that the soft device can’t break in during that first two byte transfer so my thinking is if I can get all my data to transfer in these two byte pairs then any soft device interrupt will prepend a zero byte and I won’t get bad data.

So the question is, can someone point me to a good example of how to get all my data to send in pairs by keeping the double buffer primed? Am I going to have to do individual spi transfers of two bytes only, stepping through my data buffer or is there a way to force the built in SPI control to grab two bytes for each interrupt instead of one?

  • Are you really on a NRF52x? Why don't you just use the SPIM with EasyDMA? Allows up to 255 bytes without any interrupt in between.

  • Definitely on an NRF52, but didnt know the EasyDMA blocked interrupts. Hopefully thats the quick fix I need, I'll report back and close this if it works.

  • Okay so here is the update. First thing I did was enable EasyDMA in the config, I'm actually surprised it wasn't already enabled. Previously I was sending my data in blocking mode with no event handler so I just tried again with EasyDMA enabled and still was getting breaks in my SPI data. This is an LED driver so the results of the breaks can be seen as the occasional slight flicker as the first bit of a brightness register gets lost. I've attached a screenshot of the logic probe showing a data transfer with two gaps. The data may be slightly confusing because it shows the original data and clock from the NRF and then the retimed cascading data and clock from two more driver chips. So so far the EASYDMA doesn't seem to block the Soft device from jumping in unless I've implemented it wrong. logic probe screencaps

  • So the next thing I tried was to break all my writes up into non blocking two byte transfers. I used the spi event handler to step to the next two bytes of my data each time around and then when finished I pushed my latch. I know this adds overhead to each transfer but as I said I dont have a problem unless the extra time is before a one bit and this two byte quick send was meant to stop that since I knew every first byte was all zeros. On the scope I was seeing two byte packets, fixing the flicker, but after watching I did every so often see the odd flicker. When I really stepped through some probed data I found that rarely my two byte packets were being split once again into single byte sends with an extra delay between which broke the data.

    So this is a hack but is there a reason that two byte packet got broken up, am I writing too fast for the double buffer to fill?

  • Strange. What SDK are you using? Could you share your complete code so I can test it here?

Related