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

NRF52840/FreeRTOS unable to sleep after using QSPI peripheral

I have found what I believe to be a bug with the nrfx_qspi driver on NRF52840. After using the QPSI peripheral, I have found that in some cases the NVIC's IRQ#41 (QSPI Interrupt) PENDING bit is left set. Checking the QSPI's registers: INTEN and EVENTS_READY both have a value of 0x00000001. Because the NVIC's pending bit is set for IRQ 41, when FreeRTOS attempts to sleep it immediately wakes back up.

The code using the qpsi driver basically looks like this:

const nrfx_qspi_config_t sQSPIConfig = {
.xip_offset = NRFX_QSPI_CONFIG_XIP_OFFSET,
.pins = {
.sck_pin = BSP_QSPI_SCK_PIN,
.csn_pin = BSP_QSPI_CSN_PIN,
.io0_pin = FLASH_EXTERNAL_IO0_PIN,
.io1_pin = FLASH_EXTERNAL_IO1_PIN,
.io2_pin = FLASH_EXTERNAL_IO2_PIN,
.io3_pin = FLASH_EXTERNAL_IO3_PIN
},
.prot_if = {
.readoc = (nrf_qspi_readoc_t)NRFX_QSPI_CONFIG_READOC,
.writeoc = (nrf_qspi_writeoc_t)NRFX_QSPI_CONFIG_WRITEOC,
.addrmode = (nrf_qspi_addrmode_t)NRFX_QSPI_CONFIG_ADDRMODE,
.dpmconfig = false
},
.phy_if = {
.sck_delay = (uint8_t)NRFX_QSPI_CONFIG_SCK_DELAY,
.dpmen = false,
.spi_mode = (nrf_qspi_spi_mode_t)NRFX_QSPI_CONFIG_MODE,
.sck_freq = (nrf_qspi_frequency_t)NRFX_QSPI_CONFIG_FREQUENCY,
},
// Set QSPI pins to pins related to connected board.
.irq_priority = (uint8_t)NRFX_QSPI_CONFIG_IRQ_PRIORITY
};

read_flash():
{
...

ret = nrfx_qspi_init(&sQSPIConfig, NULL, NULL);

while (nrfx_qspi_mem_busy_check() == NRFX_ERROR_BUSY)
{
vTaskDelay(1);
}
ret = nrfx_qspi_read( p_rx_buffer, rx_buffer_length, src_address);

...

}

I have found that even if I call nrfx_qspi_uninit() the NVIC still has the QSPI interrupt pending, and I am unable to sleep. If I manually call NVIC_ClearPendingIRQ(QSPI_IRQn) after accessing the flash, then I am able to sleep.

Jon

Parents
  • Also note that even after calling uninit the isr is still pending, so I am currently calling uninit and then following the uninit call with the NVIC-clearpendingirq call.

    Also, I found that this stick interrupt send to depend on whether I make a call to nrfx_qspi_mem_busy_check(). I tried different the qspi driver code but was a bit confused at some of the places it was enabling interrupts.

    Jon

Reply
  • Also note that even after calling uninit the isr is still pending, so I am currently calling uninit and then following the uninit call with the NVIC-clearpendingirq call.

    Also, I found that this stick interrupt send to depend on whether I make a call to nrfx_qspi_mem_busy_check(). I tried different the qspi driver code but was a bit confused at some of the places it was enabling interrupts.

    Jon

Children
Related