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

SPI Overhead

Hi,

-I have a custom board using nrf 52832 and I have interfaced sensor using an SPI interface.
-I am using SDK 15.2.0 and SPI driver.
-I am collecting raw data and send them serially.

===============================================================================
NRF_SERIAL_DRV_UART_CONFIG_DEF ( m_uart0_drv_config,
RX_PIN_NUM,
TX_PIN_NUM, // Rx pin = P0.03 -- Tx pin = P0.04
RTS_PIN_NUMBER , CTS_PIN_NUMBER ,
NRF_UART_HWFC_DISABLED, NRF_UART_PARITY_EXCLUDED,
UART_BAUDRATE_BAUDRATE_Baud1M,
UART_DEFAULT_CONFIG_IRQ_PRIORITY ) ;
NRF_SERIAL_QUEUES_DEF(serial_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE);

NRF_SERIAL_BUFFERS_DEF(serial_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE);

NRF_SERIAL_UART_DEF(serial_uart, 0);
================================================================================
void init_spi(void)

{
nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
spi_config.ss_pin = 17;
spi_config.miso_pin = 16;
spi_config.mosi_pin = 15;
spi_config.sck_pin = 18;
spi_config.irq_priority = APP_IRQ_PRIORITY_LOW ; // original
spi_config.frequency = NRF_SPI_FREQ_4M;
spi_config.mode = NRF_DRV_SPI_MODE_0;
spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
//APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler));
APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));

}
=====================================================================================


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
I have performed some calculations as follows.

SPi Freq 4000000
Time for 1 bit 0.25us
Time for 1 byte 4 us
Time for 12-byte value 48 us

As per my calculation, spi read operation should be completed within 48 us. But actually, it takes more time to complete spi transactions. What is the reason? is it any spi overhead?

  • Hi,

    There is some small overhead in starting and completing the transfer, but the transfer itself does not have any overhead.

    I did a quick test with a logic analyzer to show you the timings in the default SPI master example in the SDK, with frequency increased to 4 MHz:

    As you can see, the transfer of 12 bytes takes ~24 us, which correspond with the calculations (8 bits/byte * 12 bytes * (1/4MHz) = 24 us).

    The toggling of SS signal is handled in SW by transfer start function and interrupt handler triggered by the END event. This is about 40 us, giving a total overhead of ~16 us.

    The timing overhead will depend on the optimization of the code and what state the chip is in when the interrupt is generated. If I remove the sleep function from the example (__WFE()), the overhead is reduced to about 5.5 us:

    Best regards,
    Jørgen

  • Hi,

    Thanks for clarification

    want to read multiple bytes at a time i.e 6 bytes

    I m trying to read as follows but every time I get the first value in all 6 registers.

    void spi_burst_read_reg()
    {
    nrf_drv_spi_xfer_desc_t spd;
    t_tx_data[0]= LIS2DH_OUT_X_L|0x80; //read bit

    memset(t_rx_data, 0, 6);

    spi_xfer_done = false;
    memset(t_rx_data, 0, 6);

    spd.p_tx_buffer = t_tx_data;
    spd.tx_length = 2;
    spd.p_rx_buffer = t_rx_data;
    spd.rx_length = 6;
    APP_ERROR_CHECK(nrf_drv_spi_xfer(&spi, &spd, NRF_DRV_SPI_FLAG_TX_POSTINC));

    while (!spi_xfer_done)
    {
    __WFE();
    }



    }

    Can you tell me how to read it using the nrf spi driver.?

  • What exactly do you mean by "every time I get the first value in all 6 registers." Do you mean that the receive buffer is filled with the same byte?

    Have you checked the SPI lines with a logic analyzer, to see if the sensor outputs the expected data?

    The code you have posted will write two bytes and read 6 bytes, but note that the receive buffer will be filled while the two first bytes are written. This means that you will only receive 4 bytes after the write is done to the sensor. Normally, the sensor will not output valid data for bytes where the register address is written, so you need to increase the read buffer to 8 bytes if you want to receive 6 bytes after the write command is completed.

  • Hi,

    Thanks 

    I have one more question.

    How to clear NRF_SPI_EVENT_READY manually?

  • You can use the HAL function: nrf_spi_event_clear(), where you pass the SPI instance and the event, or you can clear the register manually:

    NRF_SPI(M)x->EVENTS_READY = 0, where x is the SPI instance, and M is included if you are using the SPIM peripheral with EasyDMA support.

Related