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

Setting new SPI Slave TX buffer during potential transaction

I have a SPI Master and a SPI Slave. The Master will randomly pull data over SPI from the Slave. The slave will randomly generate events that result in data to be sent to the Master.

As the Slave, we always want to be able to hear what the Master has to say, so when we don't have any data to send, we set a NULL TX buffer and setup a valid RX buffer.

It is common, that once the NULL buffer is set we now have data to send. To prevent a wasted transaction, we need to be able to replace the NULL buffer with a valid buffer.

There are two cases here:

a. A SPI transaction has not occurred yet, so the semaphore can be acquired by the CPU and the buffer pointer overwritten.

b. A SPI transaction is in progress, so the CPU waits on the semaphore lock and then sets the buffer pointer.

The issue, is that it doesn't seem possible to determine whether the old or the new buffer was sent.  From our application perspective, the series of events looks like:

* Set NULL TX Buffer (nrfx_spis_buffers_set, p_tx_buffer==NULL)

* Receive NRFX_SPIS_BUFFERS_SET_DONE event

* Set valid TX Buffer (nrfx_spis_buffers_set, p_tx_buffer != NULL)

* Receive NRFX_SPIS_BUFFERS_SET_DONE callback

* Receive NRFX_SPIS_XFER_DONE callback

In situation (a), everything happens as expected. In situation (b), there is effectively a lost update because from our application it looks as if the valid buffer was set before the transaction completed. As a result, a lot of data goes missing without us knowing.

Is there any way to know what buffer was sent? Is there a better way of doing this (perhaps by detecting the beginning of a SPI transaction somehow and setting a dirty flag?).

Related