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
  • Log output...

    -- Below is the SPIS log output when not using an interim CS between tx and 
    -- rx on the master
    
    <info> app: Entered WaitForNextSpiMessage
    <info> app: NRF_DRV_SPIS_BUFFERS_SET_DONE
    <info> app: ENDRX --> Rx Byte Count: 8
    <info> app: ENDRX --> Tx Byte Count: 0
    <info> app: Rx Transfer Done - preparing ACK
    <info> app: NRF_DRV_SPIS_BUFFERS_SET_DONE
    <info> app: Via CS LO-->HI Rx Byte Count: 8  //this happens on the DeAssertSpiCS() at the end of the master tx/rx function
    <info> app: Via CS LO-->HI Tx Byte Count: 0
    <info> app: DONE Send ACK/NAK
    <info> app: Message Is Good - Process
    <info> app: Recieved Command: eBleMcuCommand_GetCurrentState
    <info> app: Murata State: eMurataStatus_BleDisabled
    
    -- Log below is where an interim CS toggle (low to high, high to low)
    -- is performed on master between Tx and Rx
    
    <info> app: Entered WaitForNextSpiMessage
    <info> app: NRF_DRV_SPIS_BUFFERS_SET_DONE
    <info> app: ENDRX --> Rx Byte Count: 8
    <info> app: ENDRX --> Tx Byte Count: 0
    <info> app: Rx Transfer Done - preparing ACK
    <info> app: NRF_DRV_SPIS_BUFFERS_SET_DONE      //Interim SPIM CS toggle between Tx and Rx makes this buffer setup actually work.
    <info> app: ENDRX --> Rx Byte Count: 1         //Called via ENDRX once 1 byte recieved
    <info> app: ENDRX --> Tx Byte Count: 0     
    <info> app: DONE Send ACK/NAK
    <info> app: Message Is Good - Process
    <info> app: Recieved Command: eBleMcuCommand_GetCurrentState
    <info> app: Murata State: eMurataStatus_BleDisabled
    
    <info> app: Entered WaitForNextSpiMessage
    <info> app: NRF_DRV_SPIS_BUFFERS_SET_DONE     //<-- fixed buffers for next Message
    
    NB: NRF_DRV_SPIS_BUFFERS_SET_DONE event fires at correct place each time, but in fact
        the buffers were not reconfigured correctly when the interim CS toggle is not used.
    

Reply
  • Log output...

    -- Below is the SPIS log output when not using an interim CS between tx and 
    -- rx on the master
    
    <info> app: Entered WaitForNextSpiMessage
    <info> app: NRF_DRV_SPIS_BUFFERS_SET_DONE
    <info> app: ENDRX --> Rx Byte Count: 8
    <info> app: ENDRX --> Tx Byte Count: 0
    <info> app: Rx Transfer Done - preparing ACK
    <info> app: NRF_DRV_SPIS_BUFFERS_SET_DONE
    <info> app: Via CS LO-->HI Rx Byte Count: 8  //this happens on the DeAssertSpiCS() at the end of the master tx/rx function
    <info> app: Via CS LO-->HI Tx Byte Count: 0
    <info> app: DONE Send ACK/NAK
    <info> app: Message Is Good - Process
    <info> app: Recieved Command: eBleMcuCommand_GetCurrentState
    <info> app: Murata State: eMurataStatus_BleDisabled
    
    -- Log below is where an interim CS toggle (low to high, high to low)
    -- is performed on master between Tx and Rx
    
    <info> app: Entered WaitForNextSpiMessage
    <info> app: NRF_DRV_SPIS_BUFFERS_SET_DONE
    <info> app: ENDRX --> Rx Byte Count: 8
    <info> app: ENDRX --> Tx Byte Count: 0
    <info> app: Rx Transfer Done - preparing ACK
    <info> app: NRF_DRV_SPIS_BUFFERS_SET_DONE      //Interim SPIM CS toggle between Tx and Rx makes this buffer setup actually work.
    <info> app: ENDRX --> Rx Byte Count: 1         //Called via ENDRX once 1 byte recieved
    <info> app: ENDRX --> Tx Byte Count: 0     
    <info> app: DONE Send ACK/NAK
    <info> app: Message Is Good - Process
    <info> app: Recieved Command: eBleMcuCommand_GetCurrentState
    <info> app: Murata State: eMurataStatus_BleDisabled
    
    <info> app: Entered WaitForNextSpiMessage
    <info> app: NRF_DRV_SPIS_BUFFERS_SET_DONE     //<-- fixed buffers for next Message
    
    NB: NRF_DRV_SPIS_BUFFERS_SET_DONE event fires at correct place each time, but in fact
        the buffers were not reconfigured correctly when the interim CS toggle is not used.
    

Children
No Data
Related