adafruit / Adafruit_nRF52_Arduino

Adafruit code for the Nordic nRF52 BLE SoC on Arduino
Other
615 stars 496 forks source link

Hardware Interrupt unable break delay() on nRF52840 #749

Closed eyesblue closed 10 months ago

eyesblue commented 1 year ago

Operating System

Others

IDE version

Arduino 2.0

Board

Adafruit Feather nRF52840 Express

BSP version

1.3.0

Sketch

include

define GPS_INT 6 // D6, int1

volatile int repetitions = 1; bool ledSw = true;

void repetitionsIncrease() { // This function will be called once on device wakeup // You can do some little operations here (like changing variables which will be used in the loop) // Remember to avoid calling delay() and long running functions since this functions executes in interrupt context repetitions ++; Serial.print("Interrupt happen - "); Serial.println(repetitions); }

void setup() { // I connect the interrupt pin to GPS module, it provide trigger per second. pinMode(GPS_INT, INPUT); pinMode(LED_BUILTIN, OUTPUT);

Serial.begin(115200); while ( !Serial ) delay(10);

attachInterrupt(digitalPinToInterrupt(GPS_INT), repetitionsIncrease, RISING); }

void loop() {
Serial.println("Start of loop."); ledSw = !ledSw; digitalWrite(LED_BUILTIN, LOW); delay(3000); Serial.println("Wake up from delay."); }

What happened ?

I coded with Arduino nano before, and many projects work with it well. I recently bought [Adafruit Feather nRF52840 Express] and found many behavior differences with Arduino nano, especially the interrupt mechanism.

I saw the delay() function is the same with sleep() from many Q&A, I need to program my uC with an event trigger that sleeps until calendar IC wakes it up, and I write the test code as the posted code, it sleeps 3 seconds in the loop(), but interrupt per second, the result is as bellow:

BSP Library : 1.3.0
Bootloader  : s140 6.1.1
Serial No   : 64A52A84D83C540E

Start of loop.
Interrupt happen - 2
Interrupt happen - 3
Interrupt happen - 4
Wake up from delay.
Start of loop.
Interrupt happen - 5
Interrupt happen - 6
Interrupt happen - 7
Interrupt happen - 8
Wake up from delay.
Start of loop.

In my expectation, it should be wake up every second, which means the interrupt event does not break the delay(3000), the hardware interrupt happened, but the main thread still stuck in delay(3000), it executes the next instruction after the 3 seconds count down finish, it should be a Low-level error, but I have no idea no one reports it.

And I am still confused, there are many libraries or documents titled nRF52-serials or nRF52-base, but they only support nRF52832 but not 52840, and there are many library mixes inside the library, and not know their functions come from, I can't find these function from Arduino Language Reference, I saw many functions from softdevice that develop from Nordic, but it no action when I call it in my sketch, and I also saw many functions from FreeRTOS, and I have no idea how should I code it with my Arduino sketch, I hope you can give me a direction how to start my coding.

Eyes Blue

How to reproduce ?

The result as bellow:

Start of loop.
Interrupt happen - 2
Interrupt happen - 3
Interrupt happen - 4
Wake up from delay.
Start of loop.
Interrupt happen - 5
Interrupt happen - 6
Interrupt happen - 7
Interrupt happen - 8
Wake up from delay.
Start of loop.

My expectation it should be:

Start of loop.
Interrupt happen - 2
Wake up from delay.

Start of loop.
Interrupt happen - 3
Wake up from delay.

...

Debug Log

No response

Screenshots

No response

hathach commented 10 months ago

The behavior is correct, it delay 3 seconds per code instruction. The interrupt handler does waked cpu up and run the attached function. If you want different behavior, you should change your code.

This core is indeed different from Arduino one, and make use of freeRTOS, for your usage, I would suggest to use an semaphore instead of delay(). Try to take semaphore in the loop, while the interrupt function give semaphore when it invoked. Hope that help and sorry for the super late response.