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

SPI interrupt and RTC

I'm using the SPI driver and experiencing a hang in the SPI driver because the SPI interrupt is not raised. The reason is in this code from the driver:

p_cb->bytes_transferred = 0;
nrf_spi_int_disable(p_spi, NRF_SPI_INT_READY_MASK);

nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY);

// Start the transfer by writing some byte to the TXD register;
// if TX buffer is not empty, take the first byte from this buffer,
// otherwise - use over-run character.
nrf_spi_txd_set(p_spi,
    (p_xfer_desc->tx_length > 0 ?  p_xfer_desc->p_tx_buffer[0] : p_cb->orc));

// TXD register is double buffered, so next byte to be transmitted can
// be written immediately, if needed, i.e. if TX or RX transfer is to
// be more that 1 byte long. Again - if there is something more in TX
// buffer send it, otherwise use over-run character.
if (p_xfer_desc->tx_length > 1)
{
    nrf_spi_txd_set(p_spi, p_xfer_desc->p_tx_buffer[1]);
}
else if (p_xfer_desc->rx_length > 1)
{
    nrf_spi_txd_set(p_spi, p_cb->orc);
}

// For blocking mode (user handler not provided) wait here for READY
// events (indicating that the byte from TXD register was transmitted
// and a new incoming byte was moved to the RXD register) and continue
// transaction until all requested bytes are transferred.
// In non-blocking mode - IRQ service routine will do this stuff.
if (p_cb->handler)
{
    nrf_spi_int_enable(p_spi, NRF_SPI_INT_READY_MASK);
}

The driver disables the SPI interrupt, sets the TXD and then enables the SPI interrupt. Magically, in between the setting of the TXD and the enabling of the SPI interrupt, an RTC interrupt is getting executed. When the RTC finishes, it's already too late to enable the SPI interrupt as the operation already happened.

Is my analysis correct? Should I modify the driver to be more robust and handle the above case?

Thank you!

Parents Reply Children
  • Hi, yes I did. I moved the interrupt enabling to just before the TXD setting part. Are you using mBed? The problem on my end was the mBed timer that took the execution from the SPI code.

    Another option for me was to switch the mBed driver to use the DMA version of the SPI driver. But that would require more of an effort.

    Do you know what's causing the problem in your code? We used our nRF52 emulator to figure out what's disrupting the SPI code. If you're interested in trying it out, just contact [email protected]. It really helped us solve things quickly.

Related