I’m working with the Seeed Studio XIAO nRF52840 (Sense) board, using Arduino. The board enters and exits deep sleep (NRF_POWER->SYSTEMOFF = 1;), but this doesn’t work for me. I need System ON (Idle mode).
“The system enters the lowest power consumption mode, where most peripherals, including the CPU and radio, are shut down. The only way to wake the system is via external events like GPIO pin interrupts or timer events.”
But the microcontroller doesn’t want to enter sleep mode.
__WFE();
/* Clear SEV flag if CPU was woken up by event */
__SEV();
__WFE();
#define int1Pin 2
const int ledPin = 13; // set ledPin to on-board LED
uint8_t interruptCount = 0; // Amount of received interrupts
uint8_t prevInterruptCount = 0; // Interrupt Counter from last loop
uint8_t prevInterruptCountTest = 0; // Interrupt Counter from last loop
void setup() {
Serial.begin(115200);
// while ( !Serial ) delay(10); // for nrf52840 with native usb
delay(10);
pinMode(ledPin, OUTPUT); // use the LED as an output
Serial.println("Hello, I am awake!");
setupDoubleTapInterrupt();
pinMode(int1Pin, INPUT_PULLDOWN);
attachInterrupt(digitalPinToInterrupt(int1Pin), int1ISR, RISING);
}
void loop() {
setLED(false);
Serial.print("Interrupt Counter: ");
Serial.println(interruptCount);
Serial.print("Interrupt Counter TEST: ");
Serial.println(interruptCount);
if (interruptCount > prevInterruptCount) {
Serial.println("Interrupt received!");
}
prevInterruptCount = interruptCount;
if (interruptCount >= 1) {
// Trigger System OFF after 5 interrupts
goToPowerOff();
}
delay(500);
}
void goToPowerOff() {
interruptCount = 0;
Serial.println("Going to System OFF");
setLED(true);
setupDoubleTapInterrupt();
delay(1000); // delay seems important to apply settings, before going to System OFF
//Ensure interrupt pin from IMU is set to wake up device
nrf_gpio_cfg_sense_input(digitalPinToInterrupt(int1Pin), NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH);
delay(2000);// Trigger System OFF
//NRF_POWER->SYSTEMOFF = 1;
//__WFE();
//sd_power_system_off(); // Використовувати цей метод, якщо використовується SoftDevice
__WFE();
/* Clear SEV flag if CPU was woken up by event */
__SEV();
__WFE();
}
void setupDoubleTapInterrupt() {
}
void int1ISR() {
interruptCount++;
prevInterruptCountTest++;
}
void setLED(bool on)
{
// data = 1 -> LED = On
// data = 0 -> LED = Off
digitalWrite(LED_BUILTIN, on ? HIGH : LOW);
}
![2024_09_15_15_59_12_StartApp_Arduino_IDE_2.3.2|690x255](upload://jbHUjuiplnTN8BsBTP4dXNXoJa4.png)
Hi there,
Ok, so I can compile it as an Mbed 2.9.0 & 2.9.2 No errors.
Serial output and taping GND pin with jumper from pin2. It stops but doesn’t sleep, same with removing the PIN2 > GND connection. So it is registering the interrupt.
I simplified the code to the maximum, and it still won’t go to sleep.
#include <Arduino.h>
#include <Wire.h>
const int ledPin = 13; // set ledPin to on-board LED
void setup() {
Serial.begin(115200);
while ( !Serial ) delay(10); // for nrf52840 with native usb
delay(10);
Serial.println("Hello, I am awake!");
goToPowerOff();
}
void loop() {
setLED(false);
Serial.println("loop");
delay(1000);
}
void goToPowerOff() {
Serial.println("Going to System OFF");
setLED(true);
Serial.end();
delay(1000); // delay seems important to apply settings, before going to System OFF
__WFE();
__WFE();
}
void int1ISR() {
}
void setLED(bool on)
{
// data = 1 -> LED = On
// data = 0 -> LED = Off
digitalWrite(LED_BUILTIN, on ? HIGH : LOW);
}
Hi there,
I understand this part maybe it’s not setup correctly or the Event register isn’t clear?
"
We have 2 instructions for entering low-power standby state where most clocks are gated: WFI and WFE.
They differ slightly in their entry and wake-up conditions, with the main difference being that WFE makes use of the event register, the SEV instruction and EVENTI, EVENTO signals.
WFI is targeted at entering either standby, dormant or shutdown mode, where an interrupt is required to wake-up the processor.
A usage for WFE is to put it into a spinlock loop. Where a CPU wants to access a shared resource such as shared memory, we can use a semaphore flag location managed by exclusive load and store access. If multiple CPUs are trying to access the resource, one will get access and will start to use the resource while the other CPUs will be stuck in the spinlock loop. To save power, you can insert the WFE instruction into the loop so the CPUs instead of looping continuously will enter STANDBYWFE. Then the CPU who has been using the resource should execute SEV instruction after it has finished using the resource. This will wake up all other CPUs from STANDBYWFE and another CPU can then access the shared resource."