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

Interrupt priorities and FATFS

I am using the nRF52840 (with SDKv17.0.0 + s140_7.0.1) and made a custom FW based on the ble_app_hrs example. My custom HW has a 64MB MX25U51245G flash memory chip and some I2C/SPI ADCs (which use GPIOTE interrupts to tell the nRF52 to read/process the data). My goal is to store the ADC data to as a file via FATFS to the MX25U51245G and download it via (Windows 10) USB. Also, the data will be streamed via BLE while connected to the central. The central device sends a command to start/stop this process.

When I first designed the application FW, I simply set flag in the GPIOTE interrupt (handler mode) and cleared the flag in the main superloop and did the SPI read (thread mode). This worked fine for BLE streaming, but I noticed that when I call f_write(), it is blocking and quite slow (due to erase and write) and thus the nRF52 cannot service the ADC interrupts during this time. The ADC provides 20B every 2ms and the FATFS write (4KB) takes ~30ms. I need to read the ADC whenever the interrupts occur rather than batch read them when the f_write has completed since I need to process the data on a sample-by-sample basis in order to make real-time adjustments (via SPI writes) to the ADC.

To remedy this, I now do the SPI read in the GPIOTE interrupt (handler mode) so that it has higher priority (6) over the FATFS write. When 4KB are ready (in a double buffer), I set a flag for thread mode to call f_write on that half of the buffer and the ADC can continue writing to the other half of the buffer. I also set the QSPI priority to 7 so that the GPIOTE handler gets priority over QSPI in case it does some work while the ADC sets its interrupt (however, leaving this at 6 seems to not make a difference.).

Some questions:

1. I read that doing a lot of work in handler mode is not ideal. However, without using RTOS, I'm not sure how to do the SPI read/algo processing/SPI write during the f_write thread mode activity. Is there a better solution?

2. I understand what GPIOTE_CONFIG_IRQ_PRIORITY and QSPI_CONFIG_IRQ_PRIORITY do since I have callbacks for them implemented. However, does SPI_DEFAULT_CONFIG_IRQ_PRIORITY and TWI_DEFAULT_CONFIG_IRQ_PRIORITY have any meaning if I don't have callbacks implemented (I am using blocking mode for SPI/I2C).

3. What is the priority of the ble_data_handler callback? I need to make this higher than the GPIOTE_CONFIG_IRQ_PRIORITY so that any requests from the central are serviced properly. Where do I set this?

4. The MX25U51245G uses 4KB erase sectors and I see that f_write only triggers a write when 4KB are ready. I now send 4KB to f_write but when I first started developing the system, I tried smaller values and data corruption would occur. Does this seem right? I kept the sector size at default of 512B in ffconf.h. 

Thanks!

  • Hi

    I see that you're using SDK v17.0.0. Please note that it's strongly recommended to move to SDK v17.0.2, as this is a bug fix release to v17.0.0, fixing quite a few issues.

    1. If I understand you correctly, what's most important is that you don't do too many time consuming operations within interrupts, and you should make sure to handle data separately from interrupts (wait until the interrupt is done before you handle the transmitted data for instance).

    2. From the following snippet (nrfx_twi.c and similar in nrfx_spi.c) you can see that if you don't have a handler of any kind, the interrupt won't be enabled at all.

    if (p_cb->handler)
        {
            NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_instance->p_twi),
                p_config->interrupt_priority);
            NRFX_IRQ_ENABLE(nrfx_get_irq_number(p_instance->p_twi));
        }

    3. In the SoftDevice specification, you can see that the SoftDevice uses priority levels 0, 1 and 4 by default, where 4 is "SoftDevice API calls and non-time-critical processing, which I believe the BLE data handler operates as. Setting the GPIOTE interrupt priority to 5 for instance should be sufficient. You can not change the SoftDevice priorities.

    4. Please note that all memory access by the QSPI peripheral memories have to be word-aligned to the external memory address space, so you can only write/read in full 32-bit words.

    Best regards,

    Simon

  • In regards to #3, the nRF52 seems to intermittently not service the host's requests in a timely manner if I set GPIOTE_CONFIG_IRQ_PRIORITY to 6. Setting it to 7 seems to work fine. Not sure if that is due to an SDK17.0.0 issue or if the BLE data handler priority is also 6. In any case I will upgrade to SDK17.0.2 and eventually add in FreeRTOS, but the system seems stable for now. Thanks.

Related