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

SPI blocking or nonblocking?

Just to make sure: Will The spi_master_send_recv return when it is done writing and reading, or do you have to have some event wait functionality listening to SPI_MASTER_EVT_TRANSFER_COMPLETED ? I guess it is blocking because you have an output buffer as well...

I am going to do large burst reads having <= 24576 bytes. Is it even possible to read that much in one go memory wise?

Thanks!

Parents
  • The spi_master_send_recv function will only transmit first bytes to start the transaction and then return. This is non blocking.

    After the bytes are received for the transmitted first bytes then the rest of the transaction happens in the interrupt context. When the interrupt context has started for the first time you get a SPI_MASTER_EVT_TRANSFER_STARTED event and when the whole transaction is finished then you get SPI_MASTER_EVT_TRANSFER_COMPLETED event.

  • I just wondered what the best way to block a function while waiting for something. Is it still sleeping every µs and poll the volatile bool?

    I do this:

    static inline void SpiTransfer(uint8_t * const txBuffer, const uint16_t txBufferLength,
    	uint8_t * const rxBuffer, const uint16_t rxBufferLength)
    {	
    	while (_isTransferring)
    		nrf_delay_us(1);
    
    	_count = rxBufferLength;
    
    	_isTransferring = true;
    	uint32_t result = spi_master_send_recv(SPI_MASTER_HW, txBuffer, txBufferLength, rxBuffer,     rxBufferLength);
    	APP_ERROR_CHECK(result);
    
    	while (_isTransferring)
    		nrf_delay_us(1);
    }
    

    static void spi_master_event_handler(spi_master_evt_t spi_master_evt)
    {
    	switch (spi_master_evt.evt_type)
    	{
    	case SPI_MASTER_EVT_TRANSFER_COMPLETED:
    
    		_receivedCount = spi_master_evt.data_count;
    
    		if (_receivedCount >= _count)
    		{
    			_count = 0;
    			_isTransferring = false;
    		}
    
    		break;
    
    	default:
    		// No implementation needed.
    		break;
    	}
    }
    
Reply
  • I just wondered what the best way to block a function while waiting for something. Is it still sleeping every µs and poll the volatile bool?

    I do this:

    static inline void SpiTransfer(uint8_t * const txBuffer, const uint16_t txBufferLength,
    	uint8_t * const rxBuffer, const uint16_t rxBufferLength)
    {	
    	while (_isTransferring)
    		nrf_delay_us(1);
    
    	_count = rxBufferLength;
    
    	_isTransferring = true;
    	uint32_t result = spi_master_send_recv(SPI_MASTER_HW, txBuffer, txBufferLength, rxBuffer,     rxBufferLength);
    	APP_ERROR_CHECK(result);
    
    	while (_isTransferring)
    		nrf_delay_us(1);
    }
    

    static void spi_master_event_handler(spi_master_evt_t spi_master_evt)
    {
    	switch (spi_master_evt.evt_type)
    	{
    	case SPI_MASTER_EVT_TRANSFER_COMPLETED:
    
    		_receivedCount = spi_master_evt.data_count;
    
    		if (_receivedCount >= _count)
    		{
    			_count = 0;
    			_isTransferring = false;
    		}
    
    		break;
    
    	default:
    		// No implementation needed.
    		break;
    	}
    }
    
Children
No Data
Related