nrf52: allow repeater to sleep when idle
This commit is contained in:
@@ -127,14 +127,17 @@ void loop() {
|
|||||||
#endif
|
#endif
|
||||||
rtc_clock.tick();
|
rtc_clock.tick();
|
||||||
|
|
||||||
if (the_mesh.getNodePrefs()->powersaving_enabled && // To check if power saving is enabled
|
if (the_mesh.getNodePrefs()->powersaving_enabled && !the_mesh.hasPendingWork()) {
|
||||||
the_mesh.millisHasNowPassed(lastActive + nextSleepinSecs * 1000)) { // To check if it is time to sleep
|
#if defined(NRF52_PLATFORM)
|
||||||
if (!the_mesh.hasPendingWork()) { // No pending work. Safe to sleep
|
board.sleep(1800); // nrf ignores seconds param, sleeps whenever possible
|
||||||
|
#else
|
||||||
|
if (the_mesh.millisHasNowPassed(lastActive + nextSleepinSecs * 1000)) { // To check if it is time to sleep
|
||||||
board.sleep(1800); // To sleep. Wake up after 30 minutes or when receiving a LoRa packet
|
board.sleep(1800); // To sleep. Wake up after 30 minutes or when receiving a LoRa packet
|
||||||
lastActive = millis();
|
lastActive = millis();
|
||||||
nextSleepinSecs = 5; // Default: To work for 5s and sleep again
|
nextSleepinSecs = 5; // Default: To work for 5s and sleep again
|
||||||
} else {
|
} else {
|
||||||
nextSleepinSecs += 5; // When there is pending work, to work another 5s
|
nextSleepinSecs += 5; // When there is pending work, to work another 5s
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,6 +251,32 @@ void NRF52BoardDCDC::begin() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NRF52Board::sleep(uint32_t secs) {
|
||||||
|
// Clear FPU interrupt flags to avoid insomnia
|
||||||
|
// see errata 87 for details https://docs.nordicsemi.com/bundle/errata_nRF52840_Rev3/page/ERR/nRF52840/Rev3/latest/anomaly_840_87.html
|
||||||
|
#if (__FPU_USED == 1)
|
||||||
|
__set_FPSCR(__get_FPSCR() & ~(0x0000009F));
|
||||||
|
(void) __get_FPSCR();
|
||||||
|
NVIC_ClearPendingIRQ(FPU_IRQn);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// On nRF52, we use event-driven sleep instead of timed sleep
|
||||||
|
// The 'secs' parameter is ignored - we wake on any interrupt
|
||||||
|
uint8_t sd_enabled = 0;
|
||||||
|
sd_softdevice_is_enabled(&sd_enabled);
|
||||||
|
|
||||||
|
if (sd_enabled) {
|
||||||
|
// first call processes pending softdevice events, second call sleeps.
|
||||||
|
sd_app_evt_wait();
|
||||||
|
sd_app_evt_wait();
|
||||||
|
} else {
|
||||||
|
// softdevice is disabled, use raw WFE
|
||||||
|
__SEV();
|
||||||
|
__WFE();
|
||||||
|
__WFE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Temperature from NRF52 MCU
|
// Temperature from NRF52 MCU
|
||||||
float NRF52Board::getMCUTemperature() {
|
float NRF52Board::getMCUTemperature() {
|
||||||
NRF_TEMP->TASKS_START = 1; // Start temperature measurement
|
NRF_TEMP->TASKS_START = 1; // Start temperature measurement
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ public:
|
|||||||
virtual float getMCUTemperature() override;
|
virtual float getMCUTemperature() override;
|
||||||
virtual void reboot() override { NVIC_SystemReset(); }
|
virtual void reboot() override { NVIC_SystemReset(); }
|
||||||
virtual bool startOTAUpdate(const char *id, char reply[]) override;
|
virtual bool startOTAUpdate(const char *id, char reply[]) override;
|
||||||
|
virtual void sleep(uint32_t secs) override;
|
||||||
|
|
||||||
#ifdef NRF52_POWER_MANAGEMENT
|
#ifdef NRF52_POWER_MANAGEMENT
|
||||||
bool isExternalPowered() override;
|
bool isExternalPowered() override;
|
||||||
|
|||||||
Reference in New Issue
Block a user