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
  • That sounds like a bug in QSPI driver. 

    Normally you do not need to call nrfx_qspi_uninit to have the pending bit cleared, the driver should have first handled the interrupt before disabling it. 

    Your workaround to clear the pending bit of NVIC for QSPI  just before going sleep sounds promising, but I am still a bit worried as to why the QSPI driver became idle by disabling the NVIC->QSPI related interrupt and not disabled the event generation of this interrupt.

Reply
  • That sounds like a bug in QSPI driver. 

    Normally you do not need to call nrfx_qspi_uninit to have the pending bit cleared, the driver should have first handled the interrupt before disabling it. 

    Your workaround to clear the pending bit of NVIC for QSPI  just before going sleep sounds promising, but I am still a bit worried as to why the QSPI driver became idle by disabling the NVIC->QSPI related interrupt and not disabled the event generation of this interrupt.

Children
No Data
Related