I am using a SPI peripheral on the nRF52832. If the SPI bus is busy when I call
err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
the routine returns success, but advertising does NOT start.
the peripheral is a SPI flash memory, where I log data. I have one process (starting from a timer and dontinuing from driver callbacks) that periodically reads sensors and writes logging data to the flash, another that lets a BLE central read the data back from the flash.
I'm developing on SDK 15.0 with soft device S132 v 6.0.0
I'm using SPI2 and easyDMA via the nrf_drv_spi driver.
During startup I do a page erase on the first page of the flash. This is done with several writes and reads and a state machine.
The first bus write of an operation is done by nrf_drv_spi_transfer(), From then each additional read or write is launched from the completion callback handler, until the operation is complete. For erase and write this involves some one-state polling loops, repeatedly reading a byte in the flash chip until a done bit flips. So the SPI interface runs continuously until the operation is complete. For page erase, which takes a while, this involves a spin of about five thousand reads.
The erase is LAUNCHED by the logging application, but the operation is still continuing after the service's init() returns. When the main() eventually calls advertising start, the start routine silently fails as described above.
I can get the advertising to start by calling the start routine again after the erase has completed. I can also get it to start by starting it before I init the service that does the erase.
But this is not a solution. The SPI bus will be running - reading flash, writing flash, and erasing pages of flash - when the device is logging data and also when it is reading data back for transfer over BLE. After a BLE connection disconnects, advertising has to be restarted. (Also: When a connection is made, non-connectable advertising has to be started, so the tag remains audible to other centrals than the one connected.) If the SPI bus happens to be busy at that time, the tag will stop advertising - and not restart. This effectively bricks it, because without advertising it can no longer be heard or connections made to it.
Can you tell me what is going wrong and/or how to work around it?
It sounds like there is a priority conflict in which SPI driver is working and the context in which ble_advertising_start() is being called. Can you try to tune the priorities of these two contexts to see if it helps.
If not, could you help me reproduce this on my desk, so that i can try to understand the execution path of the driver when this error occurs.