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

SPI from BLE event

Hi, I am using SDK14.1 with nrf52832 and want to write to eeprom memory over SPI from BLE characteristic call.

My spi module works and everything was working fine until i tried to write something to eeprom over BLE.

This is my SPI function

_xfer_done = false;
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, extendedTxBuffer, totalLength, NULL, 0));
while (!_xfer_done);

When this function is called from BLE _xfer_done state never changes. So i guess i never get a handler call.

What should i do in this situation?

Parents
  • It could it be caused by interrupt nesting, as @endnode suggests, or some interrupt priority issue.

    You start an SPI transfer from within an interrupt context (the BLE event) and then wait for a transfer complete interrupt with while (!_xfer_done). However, what probably happens is that since the SPI interrupt has lower priority than the BLE event, the SPI interrupt will not be executed before your BLE event code is completed because it is queued behind the BLE event. Hence the flag _xfer_done is never set, and you effectively end up waiting forever in the while (!_xfer_done) loop.

    Solutions are:

    1. Raise the SPI priority to a level above the BLE event level (level 4), as you have already done by setting the level to 3. Then the SPI interrupt will not be queued behind the BLE event, but executed right away. Then the _xfer_done flag will be set letting your code move on from the while loop. This is relatively safe, but it is not good practice to have a while() loop inside an interrupt, so I would rather recommend one of the solutions below.
    2. Set a flag in the BLE event handler and use that flag to trigger an SPI transfer from the main context.
    3. Or use a scheduler and schedule an SPI transfer in the BLE event handler.
Reply
  • It could it be caused by interrupt nesting, as @endnode suggests, or some interrupt priority issue.

    You start an SPI transfer from within an interrupt context (the BLE event) and then wait for a transfer complete interrupt with while (!_xfer_done). However, what probably happens is that since the SPI interrupt has lower priority than the BLE event, the SPI interrupt will not be executed before your BLE event code is completed because it is queued behind the BLE event. Hence the flag _xfer_done is never set, and you effectively end up waiting forever in the while (!_xfer_done) loop.

    Solutions are:

    1. Raise the SPI priority to a level above the BLE event level (level 4), as you have already done by setting the level to 3. Then the SPI interrupt will not be queued behind the BLE event, but executed right away. Then the _xfer_done flag will be set letting your code move on from the while loop. This is relatively safe, but it is not good practice to have a while() loop inside an interrupt, so I would rather recommend one of the solutions below.
    2. Set a flag in the BLE event handler and use that flag to trigger an SPI transfer from the main context.
    3. Or use a scheduler and schedule an SPI transfer in the BLE event handler.
Children
Related