Hi, i'm trying to fix strange issue in my code.
Nrf52832 based custom board with s132 enabled and running, gpiote, spi. Also I have app_timer enabled.sdk15. I have sensor connected over spi with interupt line connected to nordic gpio.
When rtc2 cc interrupt happens in interrupt handler I request SWI interrupt. In swi interrupt handler I setup sensor over spi and wait for gpiote interrupt. When interrupt happens I request swi interrupt and readout sensor over spi. I use swi to get code running with higher priority than in main loop.
The problem is in rtc2 interrupt. Sometimes it stuck for exactly 0xffffff (24bits) clock cycles and than returns to normal operation. With debugging i've got that rtc2 counter keep counting but cc interrupts seemd to be masked. This behaviour catched frequently when more gpiote interrupts received. During rtc2 hang period app timer on rtc1 works as expected (send logs periodically).
In what direction should I digg ti figure out the root cause?any known errata?
I do not know what your problem is, but I want to give you some general advice on periodic readings over SPI:
There's no need to use the CPU unless you need to change the address or content of the SPIMs Tx/Rx buffers.
What you'll want to do is to set up the SPIMs Tx and Rx buffers beforehand and then trigger the SPIM TASKS_START via the RTC CC event via PPI — Programmable peripheral interconnect. You'll also want to fork the RTC CC event to trigger the RTC TASKS_CLEAR to reset the counter value and thereby creating an infinite loop.
If you do need to change the address of the tx/rx buffers you can do so immediately after the previous SPIM transaction has started, on the SPIM EVENTS_STARTED (TXD.PTR, TXD.MAXCNT, RXD.PTR, and RXD.MAXCNT are double buffered ). This means that you'll have plenty of time to update the buffers for the next transmission.
There's also a EasyDMA list feature where the SPIM can increment over a list of buffers automatically. This enables you to sample the sensor say a 100 times into 100 buffers that's place consecutively in RAM without waking up the CPU.
In the end you'll want to end up with a system where you only use the CPU to configure the sensor driver and only use the CPU when you need to access the sensor samples, to analyze, transmit via radio, or store to flash.
Hi haakonsh, thank you for advice. Currently I'm using legacy nrf_drv_spi API and plan to migrate to SPIM and add EasyDMA and PPI.
0) I can make sensor to generate GPIOTE interrupts more frequent and it leads to described problems with RTC.
1) SPI packets are about 2-3Bytes at 8MHz. If I get GPIOTE interrupt I need to read sensor's register and than clear it.
2) I use RTC CC events to sample it once every 50ms.
3) I'd say 0.1 ms
4) I run acquisition periodically to save battery.
I have some progress today, now it works much better. I aligned GPIOTE, RTC, SWI interrupt priorities to the same value. So I suspect that GPIOTE interrupt triggered SWI interrupt -> SWI ISR handler was interrupted by another GPIOTE interrupt while was rescheduling next RTC event. Still not able to catch this neither with debugger nor with RTT logs. Should I use critical section macros in lower priority ISR handler to protect code from interruption by high priority int?Can you recommend some app note or example with best practices of usage 1) SWI and 2) GPIOTE --SPIM short? Thanks
I must confess I'm still a bit confused, I believe there is a much more efficient way to achieve what you want to do without timers and software interrupts. Do you mind sharing the datasheet of your sensor, I'd like to know what you'll need to do in order to read and clear the sensors data register.