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

SPI Slave SPIS rx via ENDRX event (no CS toggle) and re-config buffers for tx ACK/NAK without interim CS toggle

Hi

My application requires that SPI CS is NOT TOGGLED within a transaction, only at either side

 My Transaction consists of:

1 - Slave sets up buffer ready for Rx and waits: nrf_drv_spis_buffers_set(&spis, NULL, 0, (uint8_t*)&sProteusMsg, 8); while(!spis_xfer_done) {}

2 - Master Sets CS Low

3 - Master clocks in 8 bytes to Slave, slave knows RX complete via ENDRX, NOT via CS toggle

4 - Slave re-configures buffers for a single byte Tx/Rx: nrf_drv_spis_buffers_set(&spis, &status, 1,&dummy,1);

5 - Master reads the single byte from the slave

6 - Master Sets CS High

The above FAILS - it looks like it fails on the SPI slave at step 4 - the re-configure of the buffer does not 'take'

If I flip CS High/Low on the master between steps 4 and 5, everything works. I am guessing this is down to the acquisition of the SPIS semaphore, I need to 'mimic' whatever it is that is occurring on the slave when CS is toggled - I need to do this when I receive the ENDRX event for the initial 8 bytes transferred master-->slave.

I have tried many many things, all to no avail, and am hoping for some assistance. I need to know what happens on the slave when CS is flipped high/low between the Tx and the Rx so that I can mimic this behaviour somehow?

NB: To make the ENDRX event work for SPIS, I had to modify the code. My mods are in this thread: https://devzone.nordicsemi.com/f/nordic-q-a/41249/spi-slave-comms-using-byte-count-eg-rx-buffer-full-rather-csn-chip-select-to-indicate-end-of-spi-transaction

Kind Regards

Nigel

My SPIS callback function below:

void spis_read_event_handler(nrf_drv_spis_event_t event)
{
		if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
		{
				NRF_LOG_INFO("NRF_DRV_SPIS_BUFFERS_SET_DONE");
		}
		
	
		if (event.evt_type == NRF_DRV_SPIS_ENDRX_DONE)
		{
				if (event.rx_amount > 0 || event.tx_amount > 0)
				{
						NRF_LOG_INFO("ENDRX --> Rx Byte Count: %d",event.rx_amount);
						NRF_LOG_INFO("ENDRX --> Tx Byte Count: %d",event.tx_amount);
						
						spis_xfer_done = true;
				}
		}
	
		if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
    {
				if (event.rx_amount > 0 || event.tx_amount > 0)
				{
						NRF_LOG_INFO("Via CS LO-->HI Rx Byte Count: %d",event.rx_amount);
						NRF_LOG_INFO("Via CS LO-->HI Tx Byte Count: %d",event.tx_amount);
						spis_xfer_done = true;
				}
    }
}

Parents
  • Have you tried to just prepare for one spis transfer, where the buffer is  (8 + 2) bytes, then you may just directly manipulate/update the ram location of the last byte in the rx buffer (10th byte in this case). I added 2 bytes, as I believe the 9th byte is fetched (in hardware to the spis) when the 8th byte is transmitted, thereby it's the 10th you need to update.

Reply
  • Have you tried to just prepare for one spis transfer, where the buffer is  (8 + 2) bytes, then you may just directly manipulate/update the ram location of the last byte in the rx buffer (10th byte in this case). I added 2 bytes, as I believe the 9th byte is fetched (in hardware to the spis) when the 8th byte is transmitted, thereby it's the 10th you need to update.

Children
No Data
Related