2020-03-18 20:51:32 +00:00
|
|
|
#include "PowerFSM.h"
|
|
|
|
#include "GPS.h"
|
2020-02-22 20:01:59 +00:00
|
|
|
#include "MeshService.h"
|
|
|
|
#include "NodeDB.h"
|
2022-01-10 06:28:13 +00:00
|
|
|
#include "configuration.h"
|
2020-07-07 08:46:49 +00:00
|
|
|
#include "graphics/Screen.h"
|
2020-09-21 19:41:39 +00:00
|
|
|
#include "main.h"
|
2020-03-18 20:51:32 +00:00
|
|
|
#include "sleep.h"
|
2020-04-10 19:18:48 +00:00
|
|
|
#include "target_specific.h"
|
2020-02-22 20:01:59 +00:00
|
|
|
|
2021-03-25 00:54:43 +00:00
|
|
|
/// Should we behave as if we have AC power now?
|
|
|
|
static bool isPowered()
|
|
|
|
{
|
2022-06-17 18:35:12 +00:00
|
|
|
// Circumvent the battery sensing logic and assumes constant power if no battery pin or power mgmt IC
|
2022-08-08 14:29:34 +00:00
|
|
|
#if !defined(BATTERY_PIN) && !defined(HAS_AXP192)
|
2021-11-06 15:03:10 +00:00
|
|
|
return true;
|
2022-06-17 18:35:12 +00:00
|
|
|
#endif
|
2022-01-10 06:28:13 +00:00
|
|
|
|
2022-05-21 20:38:33 +00:00
|
|
|
bool isRouter = (config.device.role == Config_DeviceConfig_Role_Router ? 1 : 0);
|
2021-03-25 00:54:43 +00:00
|
|
|
|
|
|
|
// If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON
|
|
|
|
// We assume routers might be powered all the time, but from a low current (solar) source
|
2022-06-13 00:56:32 +00:00
|
|
|
bool isPowerSavingMode = config.power.is_power_saving || isRouter;
|
2021-03-25 00:54:43 +00:00
|
|
|
|
|
|
|
/* To determine if we're externally powered, assumptions
|
|
|
|
1) If we're powered up and there's no battery, we must be getting power externally. (because we'd be dead otherwise)
|
|
|
|
|
|
|
|
2) If we detect USB power from the power management chip, we must be getting power externally.
|
|
|
|
*/
|
2022-06-13 00:56:32 +00:00
|
|
|
return !isPowerSavingMode && powerStatus && (!powerStatus->getHasBattery() || powerStatus->getHasUSB());
|
2021-03-25 00:54:43 +00:00
|
|
|
}
|
|
|
|
|
2020-02-22 20:01:59 +00:00
|
|
|
static void sdsEnter()
|
|
|
|
{
|
2021-08-03 04:34:14 +00:00
|
|
|
DEBUG_MSG("Enter state: SDS\n");
|
2020-09-27 01:13:16 +00:00
|
|
|
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
|
2022-05-21 20:38:33 +00:00
|
|
|
doDeepSleep(config.power.sds_secs ? config.power.sds_secs : default_sds_secs * 1000LL);
|
2020-02-22 20:01:59 +00:00
|
|
|
}
|
|
|
|
|
2021-12-06 02:37:35 +00:00
|
|
|
extern Power *power;
|
|
|
|
|
|
|
|
static void shutdownEnter()
|
|
|
|
{
|
|
|
|
DEBUG_MSG("Enter state: SHUTDOWN\n");
|
|
|
|
power->shutdown();
|
|
|
|
}
|
|
|
|
|
2020-03-25 19:25:46 +00:00
|
|
|
#include "error.h"
|
|
|
|
|
2020-06-10 21:11:43 +00:00
|
|
|
static uint32_t secsSlept;
|
|
|
|
|
2020-02-22 20:01:59 +00:00
|
|
|
static void lsEnter()
|
|
|
|
{
|
2022-05-07 10:31:21 +00:00
|
|
|
DEBUG_MSG("lsEnter begin, ls_secs=%u\n",
|
2022-05-21 20:38:33 +00:00
|
|
|
config.power.ls_secs ? config.power.ls_secs : default_ls_secs);
|
2020-10-10 01:57:57 +00:00
|
|
|
screen->setOn(false);
|
2020-06-10 21:11:43 +00:00
|
|
|
secsSlept = 0; // How long have we been sleeping this time
|
2020-03-05 02:59:10 +00:00
|
|
|
|
2021-08-03 04:07:32 +00:00
|
|
|
// DEBUG_MSG("lsEnter end\n");
|
2020-02-22 20:01:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void lsIdle()
|
|
|
|
{
|
2020-10-06 01:43:00 +00:00
|
|
|
// DEBUG_MSG("lsIdle begin ls_secs=%u\n", getPref_ls_secs());
|
2020-03-14 05:38:58 +00:00
|
|
|
|
2022-07-31 12:11:47 +00:00
|
|
|
#ifdef ARCH_ESP32
|
2020-02-23 01:40:31 +00:00
|
|
|
|
2020-06-10 21:11:43 +00:00
|
|
|
// Do we have more sleeping to do?
|
2022-05-21 20:38:33 +00:00
|
|
|
if (secsSlept < config.power.ls_secs ? config.power.ls_secs : default_ls_secs * 1000) {
|
2020-02-23 01:40:31 +00:00
|
|
|
// Briefly come out of sleep long enough to blink the led once every few seconds
|
2020-06-10 21:11:43 +00:00
|
|
|
uint32_t sleepTime = 30;
|
2020-02-23 01:40:31 +00:00
|
|
|
|
2020-06-10 21:11:43 +00:00
|
|
|
// If some other service would stall sleep, don't let sleep happen yet
|
|
|
|
if (doPreflightSleep()) {
|
|
|
|
setLed(false); // Never leave led on while in light sleep
|
2022-01-24 19:58:07 +00:00
|
|
|
esp_sleep_source_t wakeCause2 = doLightSleep(sleepTime * 1000LL);
|
2020-02-23 01:40:31 +00:00
|
|
|
|
2022-01-24 18:39:17 +00:00
|
|
|
switch (wakeCause2) {
|
2020-10-06 03:48:53 +00:00
|
|
|
case ESP_SLEEP_WAKEUP_TIMER:
|
2020-06-10 21:11:43 +00:00
|
|
|
// Normal case: timer expired, we should just go back to sleep ASAP
|
2020-02-23 02:02:44 +00:00
|
|
|
|
2022-05-07 10:31:21 +00:00
|
|
|
setLed(true); // briefly turn on led
|
2022-01-24 18:39:17 +00:00
|
|
|
wakeCause2 = doLightSleep(1); // leave led on for 1ms
|
2020-02-23 01:40:31 +00:00
|
|
|
|
2020-06-10 21:11:43 +00:00
|
|
|
secsSlept += sleepTime;
|
|
|
|
// DEBUG_MSG("sleeping, flash led!\n");
|
2020-10-06 03:48:53 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ESP_SLEEP_WAKEUP_UART:
|
2020-06-10 21:36:11 +00:00
|
|
|
// Not currently used (because uart triggers in hw have problems)
|
|
|
|
powerFSM.trigger(EVENT_SERIAL_CONNECTED);
|
2020-10-06 03:48:53 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
// We woke for some other reason (button press, device interrupt)
|
2020-06-11 01:23:20 +00:00
|
|
|
// uint64_t status = esp_sleep_get_ext1_wakeup_status();
|
2022-01-24 18:39:17 +00:00
|
|
|
DEBUG_MSG("wakeCause2 %d\n", wakeCause2);
|
2020-03-14 05:38:58 +00:00
|
|
|
|
2020-04-01 04:56:35 +00:00
|
|
|
#ifdef BUTTON_PIN
|
2020-06-10 21:11:43 +00:00
|
|
|
bool pressed = !digitalRead(BUTTON_PIN);
|
2020-04-01 04:56:35 +00:00
|
|
|
#else
|
2020-06-10 21:11:43 +00:00
|
|
|
bool pressed = false;
|
2020-04-01 04:56:35 +00:00
|
|
|
#endif
|
2020-06-10 21:11:43 +00:00
|
|
|
if (pressed) // If we woke because of press, instead generate a PRESS event.
|
|
|
|
{
|
|
|
|
powerFSM.trigger(EVENT_PRESS);
|
|
|
|
} else {
|
|
|
|
// Otherwise let the NB state handle the IRQ (and that state will handle stuff like IRQs etc)
|
2020-10-06 03:48:53 +00:00
|
|
|
// we lie and say "wake timer" because the interrupt will be handled by the regular IRQ code
|
2020-06-10 21:11:43 +00:00
|
|
|
powerFSM.trigger(EVENT_WAKE_TIMER);
|
|
|
|
}
|
2020-10-06 03:48:53 +00:00
|
|
|
break;
|
2020-06-10 21:11:43 +00:00
|
|
|
}
|
2020-06-11 01:23:20 +00:00
|
|
|
} else {
|
|
|
|
// Someone says we can't sleep now, so just save some power by sleeping the CPU for 100ms or so
|
|
|
|
delay(100);
|
2020-03-18 20:51:32 +00:00
|
|
|
}
|
2020-06-10 21:11:43 +00:00
|
|
|
} else {
|
|
|
|
// Time to stop sleeping!
|
|
|
|
setLed(false);
|
|
|
|
DEBUG_MSG("reached ls_secs, servicing loop()\n");
|
|
|
|
powerFSM.trigger(EVENT_WAKE_TIMER);
|
2020-03-03 21:31:44 +00:00
|
|
|
}
|
2020-04-15 03:22:27 +00:00
|
|
|
#endif
|
2020-02-22 20:01:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void lsExit()
|
|
|
|
{
|
2021-08-03 04:34:14 +00:00
|
|
|
DEBUG_MSG("Exit state: LS\n");
|
2020-03-14 03:30:48 +00:00
|
|
|
// setGPSPower(true); // restore GPS power
|
2021-03-23 06:44:50 +00:00
|
|
|
if (gps)
|
|
|
|
gps->forceWake(true);
|
2020-02-22 20:01:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void nbEnter()
|
|
|
|
{
|
2021-08-03 04:34:14 +00:00
|
|
|
DEBUG_MSG("Enter state: NB\n");
|
2020-10-10 01:57:57 +00:00
|
|
|
screen->setOn(false);
|
2020-02-22 20:01:59 +00:00
|
|
|
setBluetoothEnable(false);
|
2020-02-22 22:45:58 +00:00
|
|
|
|
|
|
|
// FIXME - check if we already have packets for phone and immediately trigger EVENT_PACKETS_FOR_PHONE
|
2020-02-22 20:01:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void darkEnter()
|
|
|
|
{
|
2020-04-05 20:09:46 +00:00
|
|
|
setBluetoothEnable(true);
|
2020-10-10 01:57:57 +00:00
|
|
|
screen->setOn(false);
|
2020-02-22 20:01:59 +00:00
|
|
|
}
|
|
|
|
|
2020-06-08 23:35:26 +00:00
|
|
|
static void serialEnter()
|
|
|
|
{
|
2021-08-03 04:34:14 +00:00
|
|
|
DEBUG_MSG("Enter state: SERIAL\n");
|
2020-06-08 23:35:26 +00:00
|
|
|
setBluetoothEnable(false);
|
2020-10-10 01:57:57 +00:00
|
|
|
screen->setOn(true);
|
2021-03-25 00:54:43 +00:00
|
|
|
screen->print("Serial connected\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void serialExit()
|
|
|
|
{
|
|
|
|
screen->print("Serial disconnected\n");
|
2020-06-08 23:35:26 +00:00
|
|
|
}
|
|
|
|
|
2020-09-21 19:41:39 +00:00
|
|
|
static void powerEnter()
|
|
|
|
{
|
2021-08-03 04:34:14 +00:00
|
|
|
DEBUG_MSG("Enter state: POWER\n");
|
2021-03-25 00:54:43 +00:00
|
|
|
if (!isPowered()) {
|
|
|
|
// If we got here, we are in the wrong state - we should be in powered, let that state ahndle things
|
|
|
|
DEBUG_MSG("Loss of power in Powered\n");
|
|
|
|
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
|
|
|
|
} else {
|
|
|
|
screen->setOn(true);
|
|
|
|
setBluetoothEnable(true);
|
|
|
|
screen->print("Powered...\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void powerIdle()
|
|
|
|
{
|
|
|
|
if (!isPowered()) {
|
|
|
|
// If we got here, we are in the wrong state
|
|
|
|
DEBUG_MSG("Loss of power in Powered\n");
|
|
|
|
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
|
|
|
|
}
|
2020-10-12 04:19:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void powerExit()
|
|
|
|
{
|
|
|
|
screen->setOn(true);
|
|
|
|
setBluetoothEnable(true);
|
|
|
|
screen->print("Unpowered...\n");
|
2020-10-10 06:07:37 +00:00
|
|
|
}
|
|
|
|
|
2020-02-22 20:01:59 +00:00
|
|
|
static void onEnter()
|
|
|
|
{
|
2021-08-03 04:34:14 +00:00
|
|
|
DEBUG_MSG("Enter state: ON\n");
|
2020-10-10 01:57:57 +00:00
|
|
|
screen->setOn(true);
|
2020-02-22 20:01:59 +00:00
|
|
|
setBluetoothEnable(true);
|
|
|
|
|
2020-03-18 20:51:32 +00:00
|
|
|
static uint32_t lastPingMs;
|
2020-03-05 00:46:57 +00:00
|
|
|
|
2020-09-05 19:34:48 +00:00
|
|
|
uint32_t now = millis();
|
2020-03-18 20:51:32 +00:00
|
|
|
|
2020-12-22 01:42:00 +00:00
|
|
|
if (now - lastPingMs >
|
|
|
|
30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state
|
2020-05-22 00:21:44 +00:00
|
|
|
if (displayedNodeNum)
|
|
|
|
service.sendNetworkPing(displayedNodeNum, true); // Refresh the currently displayed node
|
2020-03-18 20:51:32 +00:00
|
|
|
lastPingMs = now;
|
|
|
|
}
|
2020-02-22 20:01:59 +00:00
|
|
|
}
|
|
|
|
|
2021-03-25 00:54:43 +00:00
|
|
|
static void onIdle()
|
|
|
|
{
|
|
|
|
if (isPowered()) {
|
|
|
|
// If we got here, we are in the wrong state - we should be in powered, let that state ahndle things
|
|
|
|
powerFSM.trigger(EVENT_POWER_CONNECTED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-22 20:01:59 +00:00
|
|
|
static void screenPress()
|
|
|
|
{
|
2020-10-10 01:57:57 +00:00
|
|
|
screen->onPress();
|
2020-02-22 20:01:59 +00:00
|
|
|
}
|
|
|
|
|
2022-01-10 06:28:13 +00:00
|
|
|
static void bootEnter()
|
|
|
|
{
|
2021-08-03 04:34:14 +00:00
|
|
|
DEBUG_MSG("Enter state: BOOT\n");
|
|
|
|
}
|
2020-03-18 22:00:17 +00:00
|
|
|
|
2021-12-06 02:37:35 +00:00
|
|
|
State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN");
|
2020-02-22 21:14:10 +00:00
|
|
|
State stateSDS(sdsEnter, NULL, NULL, "SDS");
|
|
|
|
State stateLS(lsEnter, lsIdle, lsExit, "LS");
|
|
|
|
State stateNB(nbEnter, NULL, NULL, "NB");
|
|
|
|
State stateDARK(darkEnter, NULL, NULL, "DARK");
|
2021-03-25 00:54:43 +00:00
|
|
|
State stateSERIAL(serialEnter, NULL, serialExit, "SERIAL");
|
2020-03-19 02:15:51 +00:00
|
|
|
State stateBOOT(bootEnter, NULL, NULL, "BOOT");
|
2021-03-25 00:54:43 +00:00
|
|
|
State stateON(onEnter, onIdle, NULL, "ON");
|
|
|
|
State statePOWER(powerEnter, powerIdle, powerExit, "POWER");
|
2020-03-18 22:00:17 +00:00
|
|
|
Fsm powerFSM(&stateBOOT);
|
2020-02-22 20:01:59 +00:00
|
|
|
|
|
|
|
void PowerFSM_setup()
|
|
|
|
{
|
2022-05-21 20:38:33 +00:00
|
|
|
bool isRouter = (config.device.role == Config_DeviceConfig_Role_Router ? 1 : 0);
|
2021-03-25 00:54:43 +00:00
|
|
|
bool hasPower = isPowered();
|
2020-12-21 03:38:03 +00:00
|
|
|
|
2020-09-21 19:41:39 +00:00
|
|
|
DEBUG_MSG("PowerFSM init, USB power=%d\n", hasPower);
|
|
|
|
powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout");
|
2020-03-18 22:00:17 +00:00
|
|
|
|
2020-10-06 03:48:53 +00:00
|
|
|
// wake timer expired or a packet arrived
|
|
|
|
// if we are a router node, we go to NB (no need for bluetooth) otherwise we go to DARK (so we can send message to phone)
|
|
|
|
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_WAKE_TIMER, NULL, "Wake timer");
|
2020-02-22 22:45:58 +00:00
|
|
|
|
2022-01-10 06:28:13 +00:00
|
|
|
// We need this transition, because we might not transition if we were waiting to enter light-sleep, because when we wake from
|
|
|
|
// light sleep we _always_ transition to NB or dark and
|
|
|
|
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL,
|
|
|
|
"Received packet, exiting light sleep");
|
2021-08-03 05:07:39 +00:00
|
|
|
powerFSM.add_transition(&stateNB, &stateNB, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, resetting win wake");
|
2020-02-22 21:14:10 +00:00
|
|
|
|
2020-06-08 23:35:26 +00:00
|
|
|
// Handle press events - note: we ignore button presses when in API mode
|
2020-03-18 20:51:32 +00:00
|
|
|
powerFSM.add_transition(&stateLS, &stateON, EVENT_PRESS, NULL, "Press");
|
2020-02-22 21:14:10 +00:00
|
|
|
powerFSM.add_transition(&stateNB, &stateON, EVENT_PRESS, NULL, "Press");
|
|
|
|
powerFSM.add_transition(&stateDARK, &stateON, EVENT_PRESS, NULL, "Press");
|
2020-09-21 19:41:39 +00:00
|
|
|
powerFSM.add_transition(&statePOWER, &statePOWER, EVENT_PRESS, screenPress, "Press");
|
2020-02-22 21:14:10 +00:00
|
|
|
powerFSM.add_transition(&stateON, &stateON, EVENT_PRESS, screenPress, "Press"); // reenter On to restart our timers
|
2020-09-21 19:41:39 +00:00
|
|
|
powerFSM.add_transition(&stateSERIAL, &stateSERIAL, EVENT_PRESS, screenPress,
|
|
|
|
"Press"); // Allow button to work while in serial API
|
2020-02-22 20:01:59 +00:00
|
|
|
|
2020-05-17 11:51:36 +00:00
|
|
|
// Handle critically low power battery by forcing deep sleep
|
|
|
|
powerFSM.add_transition(&stateBOOT, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
|
|
|
|
powerFSM.add_transition(&stateLS, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
|
|
|
|
powerFSM.add_transition(&stateNB, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
|
|
|
|
powerFSM.add_transition(&stateDARK, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
|
|
|
|
powerFSM.add_transition(&stateON, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
|
2020-06-08 23:35:26 +00:00
|
|
|
powerFSM.add_transition(&stateSERIAL, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
|
2020-05-17 11:51:36 +00:00
|
|
|
|
2021-12-06 02:37:35 +00:00
|
|
|
// 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");
|
|
|
|
|
2022-03-25 11:27:14 +00:00
|
|
|
// 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
|
|
|
|
|
2020-02-24 18:23:07 +00:00
|
|
|
powerFSM.add_transition(&stateDARK, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
|
|
|
|
powerFSM.add_transition(&stateON, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
|
2020-02-23 02:02:44 +00:00
|
|
|
|
2020-10-06 03:48:53 +00:00
|
|
|
// if we are a router we don't turn the screen on for these things
|
|
|
|
if (!isRouter) {
|
2021-08-03 05:07:39 +00:00
|
|
|
// if any packet destined for phone arrives, turn on bluetooth at least
|
|
|
|
powerFSM.add_transition(&stateNB, &stateDARK, EVENT_PACKET_FOR_PHONE, NULL, "Packet for phone");
|
|
|
|
|
2020-10-06 03:48:53 +00:00
|
|
|
// show the latest node when we get a new node db 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_TEXT_MSG, NULL, "Received text");
|
|
|
|
powerFSM.add_transition(&stateNB, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text");
|
|
|
|
powerFSM.add_transition(&stateDARK, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text");
|
|
|
|
powerFSM.add_transition(&stateON, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text"); // restarts the sleep timer
|
|
|
|
}
|
2020-02-22 20:01:59 +00:00
|
|
|
|
2021-03-25 00:54:43 +00:00
|
|
|
// If we are not in statePOWER but get a serial connection, suppress sleep (and keep the screen on) while connected
|
2020-06-08 23:35:26 +00:00
|
|
|
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");
|
2021-03-25 00:54:43 +00:00
|
|
|
powerFSM.add_transition(&statePOWER, &stateSERIAL, EVENT_SERIAL_CONNECTED, NULL, "serial API");
|
2020-06-08 23:35:26 +00:00
|
|
|
|
2021-03-25 00:54:43 +00:00
|
|
|
// 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");
|
2020-09-21 19:41:39 +00:00
|
|
|
|
|
|
|
powerFSM.add_transition(&statePOWER, &stateON, EVENT_POWER_DISCONNECTED, NULL, "power disconnected");
|
2021-03-25 00:54:43 +00:00
|
|
|
// powerFSM.add_transition(&stateSERIAL, &stateON, EVENT_POWER_DISCONNECTED, NULL, "power disconnected");
|
2020-09-21 19:41:39 +00:00
|
|
|
|
2021-03-25 00:54:43 +00:00
|
|
|
// 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");
|
2020-06-08 23:35:26 +00:00
|
|
|
|
2020-02-23 16:53:52 +00:00
|
|
|
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_CONTACT_FROM_PHONE, NULL, "Contact from phone");
|
|
|
|
|
2021-03-23 06:44:50 +00:00
|
|
|
// each time we get a new update packet make sure we are staying in the ON state so the screen stays awake (also we don't
|
|
|
|
// shutdown bluetooth if is_router)
|
|
|
|
powerFSM.add_transition(&stateDARK, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update");
|
|
|
|
powerFSM.add_transition(&stateON, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update");
|
|
|
|
|
2022-05-07 10:31:21 +00:00
|
|
|
powerFSM.add_timed_transition(&stateON, &stateDARK,
|
2022-05-21 20:38:33 +00:00
|
|
|
config.display.screen_on_secs ? config.display.screen_on_secs
|
2022-06-04 03:38:13 +00:00
|
|
|
: 60 * 1000 * 10,
|
2022-05-07 10:31:21 +00:00
|
|
|
NULL, "Screen-on timeout");
|
2020-02-22 20:01:59 +00:00
|
|
|
|
2020-10-16 06:00:56 +00:00
|
|
|
// On most boards we use light-sleep to be our main state, but on NRF52 we just stay in DARK
|
|
|
|
State *lowPowerState = &stateLS;
|
2020-02-22 21:50:08 +00:00
|
|
|
|
2021-08-10 08:07:40 +00:00
|
|
|
uint32_t meshSds = 0;
|
2021-08-10 07:23:26 +00:00
|
|
|
|
2022-07-31 12:11:47 +00:00
|
|
|
#ifdef ARCH_ESP32
|
2020-10-16 06:00:56 +00:00
|
|
|
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
|
|
|
|
2022-01-10 06:28:13 +00:00
|
|
|
// See: https://github.com/meshtastic/Meshtastic-device/issues/1071
|
2022-05-21 20:38:33 +00:00
|
|
|
if (isRouter || config.power.is_power_saving) {
|
2022-05-07 10:31:21 +00:00
|
|
|
powerFSM.add_timed_transition(&stateNB, &stateLS,
|
2022-05-21 20:38:33 +00:00
|
|
|
config.power.min_wake_secs ? config.power.min_wake_secs
|
2022-05-07 10:31:21 +00:00
|
|
|
: default_min_wake_secs * 1000,
|
|
|
|
NULL, "Min wake timeout");
|
|
|
|
powerFSM.add_timed_transition(&stateDARK, &stateLS,
|
2022-05-21 20:38:33 +00:00
|
|
|
config.power.wait_bluetooth_secs
|
|
|
|
? config.power.wait_bluetooth_secs
|
2022-05-07 10:31:21 +00:00
|
|
|
: default_wait_bluetooth_secs * 1000,
|
|
|
|
NULL, "Bluetooth timeout");
|
2022-05-21 20:38:33 +00:00
|
|
|
meshSds = config.power.mesh_sds_timeout_secs ? config.power.mesh_sds_timeout_secs
|
2022-05-07 10:31:21 +00:00
|
|
|
: default_mesh_sds_timeout_secs;
|
2022-01-10 06:28:13 +00:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
meshSds = UINT32_MAX;
|
|
|
|
}
|
2022-01-10 03:14:07 +00:00
|
|
|
|
2020-10-30 09:05:32 +00:00
|
|
|
#else
|
|
|
|
lowPowerState = &stateDARK;
|
2022-01-10 06:28:13 +00:00
|
|
|
meshSds = UINT32_MAX; // Workaround for now: Don't go into deep sleep on the RAK4631
|
2020-04-24 18:21:10 +00:00
|
|
|
#endif
|
2020-02-22 20:01:59 +00:00
|
|
|
|
2020-10-06 03:48:53 +00:00
|
|
|
if (meshSds != UINT32_MAX)
|
2020-10-16 06:00:56 +00:00
|
|
|
powerFSM.add_timed_transition(lowPowerState, &stateSDS, meshSds * 1000, NULL, "mesh timeout");
|
2020-03-03 21:31:44 +00:00
|
|
|
|
2020-02-22 21:14:10 +00:00
|
|
|
powerFSM.run_machine(); // run one interation of the state machine, so we run our on enter tasks for the initial DARK state
|
2020-03-15 23:47:38 +00:00
|
|
|
}
|