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

Can ble_nus_string_send() be called from a TWI callback?

Calling ble_nus_string_send() from within a TWI callback (case NRF_DRV_TWI_EVT_DONE) is performing a reset on my PCA10028 (nRF51422). It works fine from the main loop.

Am I right in assuming that BLE operations cannot be issued from such callbacks? But on the other hand, the ble_app_uart example issues the same call within the uart handler (APP_UART_DATA_READY).

I'd appreciate any clarification on the above.

Thanks

Parents
  • Hi,

    My guess is that you are trying to execute an interrupt with low priority inside an interrupt routine of high priority. By design, this will lead to a hard fault in the ARM CPU.

    Inside ble_nus_string_send() there is a call to sd_ble_gatts_hvx(). All Softdevice calls are implemented as Supervisor Calls (SVC), which is basically a Software interrupt (SWI) with priority level 2* (see the image). By default, the TWI driver configures the TWI interrupt handler with priority level 1*.

    image description

    When you call ble_nus_string_send() inside your TWI callback you are trying to execute an interrupt with low priority while you are still in the context of an interrupt with a higher priority.

    The simple solution is to make sure that the TWI driver is configured with APP_IRQ_PRIORITY_LOW instead of APP_IRQ_PRIORITY_HIGH*. If you look at how the UART is configured in the example you will see that it uses APP_IRQ_PRIORITY_LOW and hence there is no conflict there.

    *Notes:

    • nRF51 has priority levels ranging from 0-3. nRF52 has levels ranging from 0-7 where SVCs has priority 4.
    • Higher priority level == Lower priority number.
    • nRF52 uses the defines APP_IRQ_PRIORITY_LOWEST to APP_IRQ_PRIORITY_HIGHEST.

    Relevant, Relevant, and Relevant

  • Thank you, Martin! I've been trying to figure this one out for a long time!

Reply Children
No Data
Related