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

QSPI STATUS READY flag race condition following ACTIVATE event

Because the nRF52840 consumes an additional 1mA when QSPI is activated, Nordic has previously recommended deactivating QSPI when not in use, which in practice means deactivating it following completion of a QSPI operation and then reactivating it just before the next QSPI operation. In the case of long asynchronous Flash operations -- like erases -- the Flash part does not need QSPI to be active during the Flash operation (as long as GPIOs are correctly configured), so it's possible to save power by deactivating QSPI following delivery of the command to the Flash part, even though the Flash part is still busy with the command. We've implemented this and it works well.

In the scenario where QSPI is deactivated while the Flash part is still busy with an operation, a subsequent Flash operation will need to reactivate QSPI and then check to see if the Flash part is still busy, using nrfx_qspi_mem_busy_check(), before reading, writing, or sending a command to the Flash part. Based on code in nrfx_qspi_init(), our QSPI reactivation code works like this (FYI, we use the QSPI driver in blocking mode):

nrf_qspi_enable(NRF_QSPI);

nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY);

nrf_qspi_task_trigger(NRF_QSPI, NRF_QSPI_TASK_ACTIVATE);

while ((NRF_QSPI->STATUS & QSPI_STATUS_READY) == 0)
{
}

Here's the problem. In order to set the READY bit of the STATUS register, I assume the nRF5240 QSPI controller needs to query the Flash part, which is apparently one of the things it does when NRF_QSPI_TASK_ACTIVATE is issued. In our testing, however, it appears that the READY flag of the STATUS register defaults to 1 (READY) following NRF_QSPI_TASK_ACTIVATE and until the status of the Flash part has been read.

What this means, in the case where the Flash part is currently busy when nrf_qspi_task_trigger() is called, is that the READY bit will briefly be set to 1 but then it will quickly change to 0, reflecting the fact that the Flash part is still busy. By the time it changes to 0, however, the following loop that intends to ensure READY status will have already been passed by, and subsequent QSPI API calls to read, write, or send commands to the Flash part will fail with a  NRFX_ERROR_TIMEOUT error (which itself is not documented in those calls).

We've worked around this problem by issuing a 5us delay after nrf_qspi_task_trigger() but before the loop that checks for READY, but that's a SWAG. So our question for Nordic is, How long do we need to delay following nrf_qspi_task_trigger(NRF_QSPI_TASK_ACTIVATE) to ensure that the READY flag of the STATUS register is accurately reflecting the state of the Flash part?

Note that while we haven't tested nrfx_qspi_init() to see if this exhibits the problem, it looks like it should based on the similarity to the code above. Note that one difference is that nrfx_qspi_init() polls on the EVENTS_READY register instead of polling on the READY flag of the STATUS register, but we also encounter a race condition in the scenario above if we poll on EVENTS_READY, and that race condition was also resolved by adding a 5us delay after nrf_qspi_task_trigger().

Related