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

SPIS DMA Setup Slow

Upon testing I am seeing some slowness in setting up the SPIS DMA buffers for the next transaction. I perform a SPIS transaction, and then call nrf_drv_spis_buffers_set(). Setting the SPIS buffers takes somewhere around 20 us to complete. This seems long. Is there way around this delay?

Note: I am also using the ESB radio protocol during these transactions.

I am having to force a delay on my SPI master in order to properly receive my data. Otherwise, I miss SPI transaction because of the SEMAPHORE lock.

Can I not use DMA? Would that be faster?

    static void spi_transaction(uint32_t rx_len, uint32_t tx_len)
    {
         uint32_t rx_size = rx_len - SPI_COMMAND_SIZE;
         uint32_t err_code = 0;if (spi_rx_buf[0] != 0)	// Check received data for transaction type

	     switch (spi_rx_buf[0])
	     {
	     /* Starts the transmit */
	     case SPI_STRT_TX:
		        GPIOWrite(LED_4, LED_ON);
		        StartRadioTransmit((uint8_t*)&spi_rx_buf[SPI_COMMAND_SIZE], payload_length);
		        break;
	     case SPI_LOAD_TX_FIFO:
		        if (rx_size > 0)
		        {
			         app_sched_event_put(&rx_size, sizeof(uint16_t), radio_write_payload_event_handler);
			         GPIOWrite(LED_1, LED_ON); // TIMING OF SPI DMA STARTS HERE
		        }
		        break;
	     case SPI_LOAD_AND_TX:
		        if (rx_size > 0)
		        {
			         GPIOWrite(LED_4, LED_ON);
			         WriteRadioDataDirect((uint8_t*)&spi_rx_buf[SPI_COMMAND_SIZE], rx_size);
		        }
		        break;
	     case SPI_READ_RF:
		        clear_irq();
		        GPIOWrite(LED_2, LED_OFF); // Debugging
		        break;
	     case SPI_NOP:			
		        break;														
	      default:
	                break;										
   }

   spi_rx_buf[0] = 0;

   // set up the next transaction
   SpiDma((uint8_t*)&spi_tx_buf[0], SPI_TX_SIZE, (uint8_t*)&spi_rx_buf[0], SPI_RX_SIZE);

   return;
}


static void spi_slave_event_handler(nrf_drv_spis_event_t event)
{
if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
{	
	spi_state = SPI_BUSY;
	spi_transaction(event.rx_amount, event.tx_amount);
}
if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) // Event occurs after buffers are safely in DMA
{	
	spi_state = SPI_IDLE; // TIMING OF SPI DMA ENDS HERE
	GPIOWrite(LED_1, LED_OFF); // Debugging
}
return;
} 

I re-ran this using the example SPIS software with SDK 13. The delay was less, but I am only running the SPIS and nothing else. I observed this these results: image description

Related