I am trying to integrate DWS3000 (UWB) APIs, given here to nRF52840 with BLE stack enabled such that my firmware can have the softdevice on at the same time when UWB ranging is performed.
Is there already any working done on this? I’m facing issues with the interrupt priority as I try to integrate the two, the code gets stuck.
Any leads/help would be much appreciated.
Very interested if anyone was successful with this.
The example code uses lots of “delay” statements that are verboten when working with a SoftDevice (BLE Stack). Is there a code example that does something more intelligent, like use a task manager?
Reworking the example SPI driver to use task manager is a pretty major stir of the code.
Seems there are more than IRQ priority issues. Hard fault’s abound.
Integrating the DWS3000 with the nRF52840 with a BLE stack enabled has more than interrupt priority issues. However, setting the SPI IRQ priorities to the lowest priority (APP_IRQ_PRIORITY_LOWEST) everywhere resolves compiler errors and it seems to operate okay.
More serious are hard faults caused by use of the SPI port in combination with the SoftDevice.
The DecaWave example code uses the high speed SPIM3 port of the nRF52840, leveraging the 32mb transfer rate. SPIM3 has numerous errata posted, even in current silicon. One of the errata (anomaly_198) involves conflicts between simultaneous access to the RX/TX buffers by internal DMA (EasyDMA) and CPU operations resulting in ambiguous data.
Nordic provides a software workaround in their SDK (nrf_spim.c) for this anomaly which involves writing to a specific memory location. With non-SoftDevice applications, this memory location is freely addressable.
When an application includes a SoftDevice, various memory regions are protected from application writes using the Nordic Memory Watch Unit (MWU) and hard faults are generated whenever application code outside the SoftDevice writes locations in these regions.
The special memory address written by the Nordic anomaly_198_workaround() code violates one of these regions and as a result a hard fault occurs whenever the workaround code is executed with a SoftDriver present. The DecaWave SPI driver calls Nordic nrf_spim functions and thus the workaround code whenever SPI operations are performed resulting in immediate hard faults.
After some digging it appears that there are two mitigation suggestions to resolve this issue that have some promise, either solo or in combination:
- Disable the memory protection specifically around the write operation in the workaround code and enable it once the write is complete. An example is posted here: Segmentation fault after enabling BLE stack - Nordic Q&A - Nordic DevZone - Nordic DevZone
- Use the Nordic Time_Slice library to allocate discrete time slots for the soft radio and the application code. This ensures that neither will simultaneously access the protected region. So if you have disabled the protection, you know the SoftRadio won’t sneak in and try to also access the register during that brief window.
Using 1) will probably get you going but 2) may be required to avoid race conditions. Testing that now.
And yes, I’m getting rid of the nrf_delay()/Sleep() calls. Ugh.
Manipulating memory watch unit configuration (MWU) settings does get you going … but eventually you still get a hard fault at the transition. Also note that the Nordic workaround code executes from both application level (enable/disable workaround setting) and IRQ level (disable workaround setting).
Implemented Time slot API (sd_radio_session_open() and related functions). but it is still not working as expected, with hard faults occurring at protected memory write operations in the workaround code.
Considering abandoning SPIM3 configuration for nRF52840 and BLE, using SPIM2 or other channel with lower bandwidth.
I’m hoping you might have more of an update on how you were able to implement the softdevice with the existing API. I’d be interested to know if switching the SPIM instances worked?