diff --git a/docs/software/gps-todo.txt b/docs/software/gps-todo.txt index 38781d92..52d52f30 100644 --- a/docs/software/gps-todo.txt +++ b/docs/software/gps-todo.txt @@ -6,6 +6,8 @@ bin/run.sh --set region 8 time only mode ./bin/run.sh --set gps_operation 3 +fix wake behavior when message arrives on lora + do new power measurements fix has_gps based on new logic @@ -18,6 +20,7 @@ increase main cpu sleep time add set router mode in python tool - it will also set GPS to stationary make sure location still gets set once per boot and stays marked as valid on the gui send position updates super rarely +turn off checking for usb power and forcing always on (which will shrink DARK and NB period to zero and make light_sleep very long) diff --git a/proto b/proto index aa018c38..a0b8d888 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit aa018c38de076a7d9e732f2e128c1800b56b1971 +Subproject commit a0b8d888961720d70ab7467c94d8fa0687e58020 diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 92a0d9b1..9a949638 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -45,7 +45,8 @@ static void lsIdle() setLed(false); // Never leave led on while in light sleep wakeCause = doLightSleep(sleepTime * 1000LL); - if (wakeCause == ESP_SLEEP_WAKEUP_TIMER) { + switch (wakeCause) { + case ESP_SLEEP_WAKEUP_TIMER: // Normal case: timer expired, we should just go back to sleep ASAP setLed(true); // briefly turn on led @@ -53,12 +54,15 @@ static void lsIdle() secsSlept += sleepTime; // DEBUG_MSG("sleeping, flash led!\n"); - } - if (wakeCause == ESP_SLEEP_WAKEUP_UART) { + break; + + case ESP_SLEEP_WAKEUP_UART: // Not currently used (because uart triggers in hw have problems) powerFSM.trigger(EVENT_SERIAL_CONNECTED); - } else { - // We woke for some other reason (button press, uart, device interrupt) + break; + + default: + // We woke for some other reason (button press, device interrupt) // uint64_t status = esp_sleep_get_ext1_wakeup_status(); DEBUG_MSG("wakeCause %d\n", wakeCause); @@ -72,8 +76,10 @@ static void lsIdle() powerFSM.trigger(EVENT_PRESS); } else { // Otherwise let the NB state handle the IRQ (and that state will handle stuff like IRQs etc) + // we lie and say "wake timer" because the interrupt will be handled by the regular IRQ code powerFSM.trigger(EVENT_WAKE_TIMER); } + break; } } else { // Someone says we can't sleep now, so just save some power by sleeping the CPU for 100ms or so @@ -136,8 +142,6 @@ static void onEnter() } } -static void wakeForPing() {} - static void screenPress() { screen.onPress(); @@ -157,15 +161,20 @@ Fsm powerFSM(&stateBOOT); void PowerFSM_setup() { - // If we already have AC power go to POWER state after init, otherwise go to ON - bool hasPower = false && powerStatus && powerStatus->getHasUSB(); + // 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 + bool isLowPower = radioConfig.preferences.is_low_power; + bool hasPower = !isLowPower && powerStatus && powerStatus->getHasUSB(); + bool isRouter = radioConfig.preferences.is_router; DEBUG_MSG("PowerFSM init, USB power=%d\n", hasPower); powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout"); - powerFSM.add_transition(&stateLS, &stateDARK, EVENT_WAKE_TIMER, wakeForPing, "Wake timer"); + // 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"); - // Note we don't really use this transition, because when we wake from light sleep we _always_ transition to NB and then - // it handles things powerFSM.add_transition(&stateLS, &stateNB, EVENT_RECEIVED_PACKET, NULL, "Received packet"); + // Note we don't really use this transition, because when we wake from light sleep we _always_ transition to NB or dark and + // then it handles things powerFSM.add_transition(&stateLS, &stateNB, EVENT_RECEIVED_PACKET, NULL, "Received packet"); powerFSM.add_transition(&stateNB, &stateNB, EVENT_RECEIVED_PACKET, NULL, "Received packet, resetting win wake"); @@ -189,24 +198,31 @@ void PowerFSM_setup() powerFSM.add_transition(&stateDARK, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing"); powerFSM.add_transition(&stateON, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing"); - 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"); + // if we are a router we don't turn the screen on for these things + if (!isRouter) { + // 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"); - 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 + // 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 + } 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(&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"); + if (!isLowPower) { + 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(&stateSERIAL, &stateON, EVENT_POWER_DISCONNECTED, NULL, "power disconnected"); @@ -228,7 +244,9 @@ void PowerFSM_setup() powerFSM.add_timed_transition(&stateDARK, &stateLS, getPref_wait_bluetooth_secs() * 1000, NULL, "Bluetooth timeout"); #endif - powerFSM.add_timed_transition(&stateLS, &stateSDS, getPref_mesh_sds_timeout_secs() * 1000, NULL, "mesh timeout"); + auto meshSds = getPref_mesh_sds_timeout_secs(); + if (meshSds != UINT32_MAX) + powerFSM.add_timed_transition(&stateLS, &stateSDS, meshSds * 1000, NULL, "mesh timeout"); // removing for now, because some users don't even have phones // powerFSM.add_timed_transition(&stateLS, &stateSDS, getPref_phone_sds_timeout_sec() * 1000, NULL, "phone // timeout"); diff --git a/src/mesh/mesh.pb.h b/src/mesh/mesh.pb.h index b0624018..01ba5b5d 100644 --- a/src/mesh/mesh.pb.h +++ b/src/mesh/mesh.pb.h @@ -138,6 +138,8 @@ typedef struct _RadioConfig_UserPreferences { GpsOperation gps_operation; uint32_t gps_update_interval; uint32_t gps_attempt_time; + bool is_router; + bool is_low_power; bool factory_reset; pb_size_t ignore_incoming_count; uint32_t ignore_incoming[3]; @@ -291,7 +293,7 @@ typedef struct _ToRadio { #define MeshPacket_init_default {0, 0, 0, {SubPacket_init_default}, 0, 0, 0, 0, 0} #define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0} #define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default, false, ChannelSettings_init_default} -#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, {0, 0, 0}} +#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, {0, 0, 0}} #define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0} #define MyNodeInfo_init_default {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0} #define DeviceState_init_default {false, RadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0} @@ -307,7 +309,7 @@ typedef struct _ToRadio { #define MeshPacket_init_zero {0, 0, 0, {SubPacket_init_zero}, 0, 0, 0, 0, 0} #define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0} #define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero, false, ChannelSettings_init_zero} -#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, {0, 0, 0}} +#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, {0, 0, 0}} #define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0} #define MyNodeInfo_init_zero {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0} #define DeviceState_init_zero {false, RadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0} @@ -366,11 +368,13 @@ typedef struct _ToRadio { #define RadioConfig_UserPreferences_wifi_password_tag 13 #define RadioConfig_UserPreferences_wifi_ap_mode_tag 14 #define RadioConfig_UserPreferences_region_tag 15 +#define RadioConfig_UserPreferences_is_router_tag 37 +#define RadioConfig_UserPreferences_is_low_power_tag 38 +#define RadioConfig_UserPreferences_factory_reset_tag 100 #define RadioConfig_UserPreferences_location_share_tag 32 #define RadioConfig_UserPreferences_gps_operation_tag 33 #define RadioConfig_UserPreferences_gps_update_interval_tag 34 #define RadioConfig_UserPreferences_gps_attempt_time_tag 36 -#define RadioConfig_UserPreferences_factory_reset_tag 100 #define RadioConfig_UserPreferences_ignore_incoming_tag 103 #define RouteDiscovery_route_tag 2 #define User_id_tag 1 @@ -531,6 +535,8 @@ X(a, STATIC, SINGULAR, UENUM, location_share, 32) \ X(a, STATIC, SINGULAR, UENUM, gps_operation, 33) \ X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 34) \ X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 36) \ +X(a, STATIC, SINGULAR, BOOL, is_router, 37) \ +X(a, STATIC, SINGULAR, BOOL, is_low_power, 38) \ X(a, STATIC, SINGULAR, BOOL, factory_reset, 100) \ X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103) #define RadioConfig_UserPreferences_CALLBACK NULL @@ -668,11 +674,11 @@ extern const pb_msgdesc_t ManufacturingData_msg; #define SubPacket_size 274 #define MeshPacket_size 313 #define ChannelSettings_size 84 -#define RadioConfig_size 302 -#define RadioConfig_UserPreferences_size 213 +#define RadioConfig_size 308 +#define RadioConfig_UserPreferences_size 219 #define NodeInfo_size 132 #define MyNodeInfo_size 110 -#define DeviceState_size 5454 +#define DeviceState_size 5460 #define DebugString_size 258 #define FromRadio_size 322 #define ToRadio_size 316