Skip to content

Commit 56213ca

Browse files
committed
Support sleep for NRF52 boards by suspending the main task
This uses FreeRTOS direct task notifications as recommended in the docs. Using the Arduino core functions suspendLoop() and resumeLoop() can lead to deadlocks which can only be avoided by disabling IRQs and possibly missing incoming packets. Signed-off-by: Frieder Schrempf <frieder@fris.de>
1 parent a6ce03d commit 56213ca

2 files changed

Lines changed: 19 additions & 0 deletions

File tree

src/helpers/NRF52Board.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
static BLEDfu bledfu;
77

8+
BaseType_t wakeup_event;
9+
810
static void connect_callback(uint16_t conn_handle) {
911
(void)conn_handle;
1012
MESH_DEBUG_PRINTLN("BLE client connected");
@@ -19,6 +21,18 @@ static void disconnect_callback(uint16_t conn_handle, uint8_t reason) {
1921

2022
void NRF52Board::begin() {
2123
startup_reason = BD_STARTUP_NORMAL;
24+
loop_task_handle = xTaskGetHandle("loop");
25+
}
26+
27+
void NRF52Board::sleep(uint32_t secs) {
28+
MESH_DEBUG_PRINTLN("Suspending loop for powersaving, set wakeup timer in %u seconds", secs);
29+
ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(secs * 1000));
30+
}
31+
32+
void NRF52Board::onRXInterrupt() {
33+
BaseType_t higher_priority_task_woken = pdFALSE;
34+
vTaskNotifyGiveFromISR(loop_task_handle, &higher_priority_task_woken);
35+
portYIELD_FROM_ISR(higher_priority_task_woken);
2236
}
2337

2438
void NRF52BoardDCDC::begin() {

src/helpers/NRF52Board.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#if defined(NRF52_PLATFORM)
77

88
class NRF52Board : public mesh::MainBoard {
9+
private:
10+
TaskHandle_t loop_task_handle;
11+
912
protected:
1013
uint8_t startup_reason;
1114

@@ -14,6 +17,8 @@ class NRF52Board : public mesh::MainBoard {
1417
virtual uint8_t getStartupReason() const override { return startup_reason; }
1518
virtual float getMCUTemperature() override;
1619
virtual void reboot() override { NVIC_SystemReset(); }
20+
virtual void sleep(uint32_t secs) override;
21+
virtual void onRXInterrupt() override;
1722
};
1823

1924
/*

0 commit comments

Comments
 (0)