mirror of
https://github.com/meshtastic/firmware.git
synced 2025-07-30 02:15:41 +00:00
remove stateNB, improve regular (non-dynamic) light-sleep handling
This commit is contained in:
parent
94a560b678
commit
8cb9344ed7
117
src/PowerFSM.cpp
117
src/PowerFSM.cpp
@ -93,33 +93,37 @@ static void lsEnter()
|
||||
screen->setOn(false);
|
||||
ledBlink.set(false);
|
||||
|
||||
if (!doPreflightSleep()) {
|
||||
LOG_DEBUG("State change to LS aborted");
|
||||
sleepStart = -1;
|
||||
powerFSM.trigger(EVENT_WAKE_TIMER);
|
||||
return;
|
||||
}
|
||||
|
||||
sleepStart = millis();
|
||||
sleepStart = -1;
|
||||
sleepTime = 0;
|
||||
|
||||
powerMon->setState(meshtastic_PowerMon_State_CPU_LightSleep);
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
doLightSleep(SLEEP_TIME * 1000LL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void lsIdle()
|
||||
{
|
||||
if (!doPreflightSleep()) {
|
||||
#ifdef DYNAMIC_LIGHT_SLEEP
|
||||
powerFSM.trigger(EVENT_WAKE_TIMER);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (sleepStart == -1) {
|
||||
sleepStart = millis();
|
||||
}
|
||||
|
||||
sleepTime = millis() - sleepStart;
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
uint32_t sleepLeft;
|
||||
|
||||
sleepLeft = config.power.ls_secs * 1000LL - sleepTime;
|
||||
if (sleepLeft > SLEEP_TIME * 1000LL) {
|
||||
sleepLeft = SLEEP_TIME * 1000LL;
|
||||
}
|
||||
|
||||
doLightSleep(sleepLeft);
|
||||
|
||||
esp_sleep_source_t cause = esp_sleep_get_wakeup_cause();
|
||||
|
||||
switch (cause) {
|
||||
@ -128,11 +132,6 @@ static void lsIdle()
|
||||
powerFSM.trigger(EVENT_INPUT);
|
||||
return;
|
||||
|
||||
case ESP_SLEEP_WAKEUP_EXT0:
|
||||
LOG_DEBUG("Wake cause ESP_SLEEP_WAKEUP_EXT0");
|
||||
powerFSM.trigger(EVENT_RADIO_INTERRUPT);
|
||||
return;
|
||||
|
||||
case ESP_SLEEP_WAKEUP_EXT1:
|
||||
LOG_DEBUG("Wake cause ESP_SLEEP_WAKEUP_EXT1");
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
@ -143,11 +142,6 @@ static void lsIdle()
|
||||
powerFSM.trigger(EVENT_WAKE_TIMER);
|
||||
return;
|
||||
|
||||
case ESP_SLEEP_WAKEUP_UNDEFINED:
|
||||
LOG_DEBUG("Wake cause ESP_SLEEP_WAKEUP_UNDEFINED");
|
||||
powerFSM.trigger(EVENT_WAKE_TIMER);
|
||||
return;
|
||||
|
||||
default:
|
||||
if (sleepTime > config.power.ls_secs * 1000LL) {
|
||||
powerFSM.trigger(EVENT_WAKE_TIMER);
|
||||
@ -155,15 +149,6 @@ static void lsIdle()
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t sleepLeft;
|
||||
|
||||
sleepLeft = config.power.ls_secs * 1000LL - sleepTime;
|
||||
if (sleepLeft > SLEEP_TIME * 1000LL) {
|
||||
sleepLeft = SLEEP_TIME * 1000LL;
|
||||
}
|
||||
|
||||
doLightSleep(sleepLeft);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -183,21 +168,9 @@ static void lsExit()
|
||||
}
|
||||
}
|
||||
|
||||
static void nbEnter()
|
||||
{
|
||||
LOG_DEBUG("State: NB");
|
||||
if (screen)
|
||||
screen->setOn(false);
|
||||
#ifdef ARCH_ESP32
|
||||
// Only ESP32 should turn off bluetooth
|
||||
setBluetoothEnable(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void darkEnter()
|
||||
{
|
||||
// LOG_DEBUG("State: DARK"); i
|
||||
setBluetoothEnable(true);
|
||||
if (screen)
|
||||
screen->setOn(false);
|
||||
}
|
||||
@ -205,18 +178,11 @@ static void darkEnter()
|
||||
static void serialEnter()
|
||||
{
|
||||
LOG_DEBUG("State: SERIAL");
|
||||
setBluetoothEnable(false);
|
||||
if (screen) {
|
||||
screen->setOn(true);
|
||||
}
|
||||
}
|
||||
|
||||
static void serialExit()
|
||||
{
|
||||
// Turn bluetooth back on when we leave serial stream API
|
||||
setBluetoothEnable(true);
|
||||
}
|
||||
|
||||
static void powerEnter()
|
||||
{
|
||||
LOG_DEBUG("State: POWER");
|
||||
@ -228,7 +194,6 @@ static void powerEnter()
|
||||
} else {
|
||||
if (screen)
|
||||
screen->setOn(true);
|
||||
setBluetoothEnable(true);
|
||||
// within enter() the function getState() returns the state we came from
|
||||
}
|
||||
}
|
||||
@ -246,7 +211,6 @@ static void powerExit()
|
||||
{
|
||||
if (screen)
|
||||
screen->setOn(true);
|
||||
setBluetoothEnable(true);
|
||||
}
|
||||
|
||||
static void onEnter()
|
||||
@ -254,7 +218,6 @@ static void onEnter()
|
||||
LOG_DEBUG("State: ON");
|
||||
if (screen)
|
||||
screen->setOn(true);
|
||||
setBluetoothEnable(true);
|
||||
}
|
||||
|
||||
static void onIdle()
|
||||
@ -274,9 +237,8 @@ State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN");
|
||||
State stateSDS(sdsEnter, NULL, NULL, "SDS");
|
||||
State stateLowBattSDS(lowBattSDSEnter, NULL, NULL, "SDS");
|
||||
State stateLS(lsEnter, lsIdle, lsExit, "LS");
|
||||
State stateNB(nbEnter, NULL, NULL, "NB");
|
||||
State stateDARK(darkEnter, NULL, NULL, "DARK");
|
||||
State stateSERIAL(serialEnter, NULL, serialExit, "SERIAL");
|
||||
State stateSERIAL(serialEnter, NULL, NULL, "SERIAL");
|
||||
State stateBOOT(bootEnter, NULL, NULL, "BOOT");
|
||||
State stateON(onEnter, onIdle, NULL, "ON");
|
||||
State statePOWER(powerEnter, powerIdle, powerExit, "POWER");
|
||||
@ -286,20 +248,14 @@ void PowerFSM_setup()
|
||||
{
|
||||
bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ? 1 : 0);
|
||||
bool hasPower = isPowered();
|
||||
State *stateIDLE;
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
stateIDLE = isRouter ? &stateNB : &stateDARK;
|
||||
#else
|
||||
stateIDLE = &stateDARK;
|
||||
#endif
|
||||
LOG_INFO("PowerFSM init, USB power=%d, is_power_saving=%d", hasPower ? 1 : 0, config.power.is_power_saving ? 1 : 0);
|
||||
LOG_INFO("PowerFSM init, USB power=%d, is_power_saving=%d, wake_time_ms=%d", hasPower ? 1 : 0,
|
||||
config.power.is_power_saving ? 1 : 0, WAKE_TIME_MS);
|
||||
|
||||
powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout");
|
||||
|
||||
// Handle press events - note: we ignore button presses when in API mode
|
||||
powerFSM.add_transition(&stateLS, &stateON, EVENT_PRESS, NULL, "Press");
|
||||
powerFSM.add_transition(&stateNB, &stateON, EVENT_PRESS, NULL, "Press");
|
||||
powerFSM.add_transition(&stateDARK, isPowered() ? &statePOWER : &stateON, EVENT_PRESS, NULL, "Press");
|
||||
powerFSM.add_transition(&statePOWER, &statePOWER, EVENT_PRESS, NULL, "Press");
|
||||
powerFSM.add_transition(&stateON, &stateON, EVENT_PRESS, NULL, "Press"); // reenter On to restart our timers
|
||||
@ -309,7 +265,6 @@ void PowerFSM_setup()
|
||||
// Handle critically low power battery by forcing deep sleep
|
||||
powerFSM.add_transition(&stateBOOT, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
|
||||
powerFSM.add_transition(&stateLS, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
|
||||
powerFSM.add_transition(&stateNB, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
|
||||
powerFSM.add_transition(&stateDARK, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
|
||||
powerFSM.add_transition(&stateON, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
|
||||
powerFSM.add_transition(&stateSERIAL, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
|
||||
@ -317,14 +272,12 @@ void PowerFSM_setup()
|
||||
// Handle being told to power off
|
||||
powerFSM.add_transition(&stateBOOT, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
||||
powerFSM.add_transition(&stateLS, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
||||
powerFSM.add_transition(&stateNB, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
||||
powerFSM.add_transition(&stateDARK, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
||||
powerFSM.add_transition(&stateON, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
||||
powerFSM.add_transition(&stateSERIAL, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
||||
|
||||
// Inputbroker
|
||||
powerFSM.add_transition(&stateLS, &stateON, EVENT_INPUT, NULL, "Input Device");
|
||||
powerFSM.add_transition(&stateNB, &stateON, EVENT_INPUT, NULL, "Input Device");
|
||||
powerFSM.add_transition(&stateDARK, &stateON, EVENT_INPUT, NULL, "Input Device");
|
||||
powerFSM.add_transition(&stateON, &stateON, EVENT_INPUT, NULL, "Input Device"); // restarts the sleep timer
|
||||
powerFSM.add_transition(&statePOWER, &statePOWER, EVENT_INPUT, NULL, "Input Device"); // restarts the sleep timer
|
||||
@ -339,56 +292,48 @@ void PowerFSM_setup()
|
||||
if (!isRouter) {
|
||||
powerFSM.add_transition(&stateLS, &stateDARK, EVENT_CONTACT_FROM_PHONE, NULL, "Contact from phone");
|
||||
powerFSM.add_transition(&stateLS, &stateDARK, EVENT_PACKET_FOR_PHONE, NULL, "Packet for phone");
|
||||
powerFSM.add_transition(&stateLS, &stateDARK, EVENT_WEB_REQUEST, NULL, "Web request");
|
||||
|
||||
// Removed 2.7: we don't show the nodes individually for every node on the screen anymore
|
||||
// powerFSM.add_transition(&stateLS, &stateON, EVENT_NODEDB_UPDATED, NULL, "NodeDB update");
|
||||
// powerFSM.add_transition(&stateNB, &stateON, EVENT_NODEDB_UPDATED, NULL, "NodeDB update");
|
||||
// powerFSM.add_transition(&stateDARK, &stateON, EVENT_NODEDB_UPDATED, NULL, "NodeDB update");
|
||||
// powerFSM.add_transition(&stateON, &stateON, EVENT_NODEDB_UPDATED, NULL, "NodeDB update");
|
||||
|
||||
// Show the received text message
|
||||
powerFSM.add_transition(&stateLS, &stateON, EVENT_RECEIVED_MSG, NULL, "Received text");
|
||||
powerFSM.add_transition(&stateNB, &stateON, EVENT_RECEIVED_MSG, NULL, "Received text");
|
||||
powerFSM.add_transition(&stateDARK, &stateON, EVENT_RECEIVED_MSG, NULL, "Received text");
|
||||
powerFSM.add_transition(&stateON, &stateON, EVENT_RECEIVED_MSG, NULL, "Received text"); // restarts the sleep timer
|
||||
|
||||
} else {
|
||||
// if we are a router we don't turn the screen on for these things
|
||||
powerFSM.add_timed_transition(
|
||||
&stateDARK, &stateNB,
|
||||
Default::getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL,
|
||||
"Bluetooth timeout");
|
||||
}
|
||||
|
||||
// If we are not in statePOWER but get a serial connection, suppress sleep (and keep the screen on) while connected
|
||||
powerFSM.add_transition(&stateLS, &stateSERIAL, EVENT_SERIAL_CONNECTED, NULL, "Serial API");
|
||||
powerFSM.add_transition(&stateNB, &stateSERIAL, EVENT_SERIAL_CONNECTED, NULL, "Serial API");
|
||||
powerFSM.add_transition(&stateDARK, &stateSERIAL, EVENT_SERIAL_CONNECTED, NULL, "Serial API");
|
||||
powerFSM.add_transition(&stateON, &stateSERIAL, EVENT_SERIAL_CONNECTED, NULL, "Serial API");
|
||||
powerFSM.add_transition(&statePOWER, &stateSERIAL, EVENT_SERIAL_CONNECTED, NULL, "Serial API");
|
||||
|
||||
// If we get power connected, go to the power connect state
|
||||
powerFSM.add_transition(&stateLS, &statePOWER, EVENT_POWER_CONNECTED, NULL, "Power connect");
|
||||
powerFSM.add_transition(&stateNB, &statePOWER, EVENT_POWER_CONNECTED, NULL, "Power connect");
|
||||
powerFSM.add_transition(&stateDARK, &statePOWER, EVENT_POWER_CONNECTED, NULL, "Power connect");
|
||||
powerFSM.add_transition(&stateON, &statePOWER, EVENT_POWER_CONNECTED, NULL, "Power connect");
|
||||
|
||||
powerFSM.add_transition(&statePOWER, &stateON, EVENT_POWER_DISCONNECTED, NULL, "Power disconnected");
|
||||
powerFSM.add_transition(&stateLS, &stateON, EVENT_POWER_DISCONNECTED, NULL, "Power disconnected");
|
||||
powerFSM.add_transition(&stateNB, &stateON, EVENT_POWER_DISCONNECTED, NULL, "Power disconnected");
|
||||
powerFSM.add_transition(&stateDARK, &stateON, EVENT_POWER_DISCONNECTED, NULL, "Power disconnected");
|
||||
|
||||
// the only way to leave state serial is for the client to disconnect (or we timeout and force disconnect them)
|
||||
// when we leave, go to ON (which might not be the correct state if we have power connected, we will fix that in onEnter)
|
||||
powerFSM.add_transition(&stateSERIAL, &stateON, EVENT_SERIAL_DISCONNECTED, NULL, "Serial disconnect");
|
||||
|
||||
powerFSM.add_transition(&stateLS, stateIDLE, EVENT_WAKE_TIMER, NULL, "Wake timer");
|
||||
powerFSM.add_transition(&stateLS, stateIDLE, EVENT_RADIO_INTERRUPT, NULL, "Radio interrupt");
|
||||
powerFSM.add_transition(&stateLS, &stateDARK, EVENT_WAKE_TIMER, NULL, "Wake timer");
|
||||
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_WAKE_TIMER, NULL, "Wake timer");
|
||||
|
||||
powerFSM.add_transition(stateIDLE, stateIDLE, EVENT_WAKE_TIMER, NULL, "Wake timer");
|
||||
powerFSM.add_transition(stateIDLE, stateIDLE, EVENT_WEB_REQUEST, NULL, "Web request");
|
||||
powerFSM.add_transition(stateIDLE, stateIDLE, EVENT_RADIO_INTERRUPT, NULL, "Radio interrupt");
|
||||
powerFSM.add_transition(&stateLS, &stateDARK, EVENT_WEB_REQUEST, NULL, "Web request");
|
||||
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_WEB_REQUEST, NULL, "Web request");
|
||||
|
||||
#ifdef DYNAMIC_LIGHT_SLEEP
|
||||
// it's better to exit dynamic light sleep when packet is received to ensure routing is properly handled
|
||||
powerFSM.add_transition(&stateLS, &stateDARK, EVENT_RADIO_INTERRUPT, NULL, "Radio interrupt");
|
||||
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_RADIO_INTERRUPT, NULL, "Radio interrupt");
|
||||
#endif
|
||||
|
||||
#ifdef USE_EINK
|
||||
// Allow E-Ink devices to suppress the screensaver, if screen timeout set to 0
|
||||
@ -403,10 +348,10 @@ void PowerFSM_setup()
|
||||
NULL, "Screen-on timeout");
|
||||
}
|
||||
|
||||
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
||||
// We never enter light-sleep on NRF52 (because the CPU uses so little power normally)
|
||||
#ifdef ARCH_ESP32
|
||||
if (config.power.is_power_saving) {
|
||||
powerFSM.add_timed_transition(stateIDLE, &stateLS, WAKE_TIME_MS, NULL, "Min wake timeout");
|
||||
powerFSM.add_timed_transition(&stateDARK, &stateLS, WAKE_TIME_MS, NULL, "Min wake timeout");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -24,11 +24,12 @@
|
||||
#define EVENT_RADIO_INTERRUPT 18
|
||||
#define EVENT_WEB_REQUEST 19
|
||||
|
||||
#if defined(ARCH_ESP32) && !defined(WAKE_TIME_MS)
|
||||
#ifdef ARCH_ESP32
|
||||
#ifdef CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
#define DYNAMIC_LIGHT_SLEEP
|
||||
#define WAKE_TIME_MS 500
|
||||
#else
|
||||
#define WAKE_TIME_MS Default::getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs)
|
||||
#define WAKE_TIME_MS (Default::getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -1369,12 +1369,16 @@ void setup()
|
||||
#endif
|
||||
|
||||
#ifndef ARCH_PORTDUINO
|
||||
|
||||
// Initialize Wifi
|
||||
#if HAS_WIFI
|
||||
// Initialize Wifi
|
||||
initWifi();
|
||||
#endif
|
||||
|
||||
#if HAS_BLUETOOTH
|
||||
// Enable Bluetooth
|
||||
setBluetoothEnable(true);
|
||||
#endif
|
||||
|
||||
#if HAS_ETHERNET
|
||||
// Initialize Ethernet
|
||||
initEthernet();
|
||||
|
@ -159,7 +159,6 @@ void Router::abortSendAndNak(meshtastic_Routing_Error err, meshtastic_MeshPacket
|
||||
void Router::setReceivedMessage()
|
||||
{
|
||||
// LOG_DEBUG("set interval to ASAP");
|
||||
powerFSM.trigger(EVENT_WAKE_TIMER);
|
||||
setInterval(0); // Run ASAP, so we can figure out our correct sleep time
|
||||
runASAP = true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user