Merge branch 'master' into NextHopRouter

This commit is contained in:
Ben Meadors 2023-10-03 06:58:04 -05:00 committed by GitHub
commit 3776064b80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 125 additions and 80 deletions

View File

@ -348,10 +348,8 @@ void PowerFSM_setup()
getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL, getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
"Screen-on timeout"); "Screen-on timeout");
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
State *lowPowerState = &stateLS;
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
// See: https://github.com/meshtastic/firmware/issues/1071 // See: https://github.com/meshtastic/firmware/issues/1071
if (isRouter || config.power.is_power_saving) { if (isRouter || config.power.is_power_saving) {
powerFSM.add_timed_transition(&stateNB, &stateLS, powerFSM.add_timed_transition(&stateNB, &stateLS,

View File

@ -20,7 +20,7 @@ HardwareSerial *GPS::_serial_gps = &Serial1;
HardwareSerial *GPS::_serial_gps = NULL; HardwareSerial *GPS::_serial_gps = NULL;
#endif #endif
GPS *gps; GPS *gps = nullptr;
/// Multiple GPS instances might use the same serial port (in sequence), but we can /// Multiple GPS instances might use the same serial port (in sequence), but we can
/// only init that port once. /// only init that port once.

View File

@ -164,11 +164,28 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl
// FIXME - draw serial # somewhere? // FIXME - draw serial # somewhere?
} }
#ifdef ARCH_ESP32
static void drawFrameResume(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
uint16_t x_offset = display->width() / 2;
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
display->drawString(x_offset + x, 26 + y, "Resuming...");
}
#endif
static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{ {
// Draw region in upper left #ifdef ARCH_ESP32
const char *region = myRegion ? myRegion->name : NULL; if (wakeCause == ESP_SLEEP_WAKEUP_TIMER || wakeCause == ESP_SLEEP_WAKEUP_EXT1) {
drawIconScreen(region, display, state, x, y); drawFrameResume(display, state, x, y);
} else
#endif
{
// Draw region in upper left
const char *region = myRegion ? myRegion->name : NULL;
drawIconScreen(region, display, state, x, y);
}
} }
static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)

View File

@ -516,34 +516,34 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
JSONObject msgPayload; JSONObject msgPayload;
JSONObject jsonObj; JSONObject jsonObj;
switch (mp->decoded.portnum) { if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
case meshtastic_PortNum_TEXT_MESSAGE_APP: { switch (mp->decoded.portnum) {
msgType = "text"; case meshtastic_PortNum_TEXT_MESSAGE_APP: {
// convert bytes to string msgType = "text";
LOG_DEBUG("got text message of size %u\n", mp->decoded.payload.size); // convert bytes to string
char payloadStr[(mp->decoded.payload.size) + 1]; LOG_DEBUG("got text message of size %u\n", mp->decoded.payload.size);
memcpy(payloadStr, mp->decoded.payload.bytes, mp->decoded.payload.size); char payloadStr[(mp->decoded.payload.size) + 1];
payloadStr[mp->decoded.payload.size] = 0; // null terminated string memcpy(payloadStr, mp->decoded.payload.bytes, mp->decoded.payload.size);
// check if this is a JSON payload payloadStr[mp->decoded.payload.size] = 0; // null terminated string
JSONValue *json_value = JSON::Parse(payloadStr); // check if this is a JSON payload
if (json_value != NULL) { JSONValue *json_value = JSON::Parse(payloadStr);
LOG_INFO("text message payload is of type json\n"); if (json_value != NULL) {
// if it is, then we can just use the json object LOG_INFO("text message payload is of type json\n");
jsonObj["payload"] = json_value; // if it is, then we can just use the json object
} else { jsonObj["payload"] = json_value;
// if it isn't, then we need to create a json object } else {
// with the string as the value // if it isn't, then we need to create a json object
LOG_INFO("text message payload is of type plaintext\n"); // with the string as the value
msgPayload["text"] = new JSONValue(payloadStr); LOG_INFO("text message payload is of type plaintext\n");
jsonObj["payload"] = new JSONValue(msgPayload); msgPayload["text"] = new JSONValue(payloadStr);
jsonObj["payload"] = new JSONValue(msgPayload);
}
break;
} }
break; case meshtastic_PortNum_TELEMETRY_APP: {
} msgType = "telemetry";
case meshtastic_PortNum_TELEMETRY_APP: { meshtastic_Telemetry scratch;
msgType = "telemetry"; meshtastic_Telemetry *decoded = NULL;
meshtastic_Telemetry scratch;
meshtastic_Telemetry *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
memset(&scratch, 0, sizeof(scratch)); memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Telemetry_msg, &scratch)) { if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Telemetry_msg, &scratch)) {
decoded = &scratch; decoded = &scratch;
@ -564,14 +564,12 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
} else { } else {
LOG_ERROR("Error decoding protobuf for telemetry message!\n"); LOG_ERROR("Error decoding protobuf for telemetry message!\n");
} }
}; break;
break; }
} case meshtastic_PortNum_NODEINFO_APP: {
case meshtastic_PortNum_NODEINFO_APP: { msgType = "nodeinfo";
msgType = "nodeinfo"; meshtastic_User scratch;
meshtastic_User scratch; meshtastic_User *decoded = NULL;
meshtastic_User *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
memset(&scratch, 0, sizeof(scratch)); memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_User_msg, &scratch)) { if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_User_msg, &scratch)) {
decoded = &scratch; decoded = &scratch;
@ -583,14 +581,12 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
} else { } else {
LOG_ERROR("Error decoding protobuf for nodeinfo message!\n"); LOG_ERROR("Error decoding protobuf for nodeinfo message!\n");
} }
}; break;
break; }
} case meshtastic_PortNum_POSITION_APP: {
case meshtastic_PortNum_POSITION_APP: { msgType = "position";
msgType = "position"; meshtastic_Position scratch;
meshtastic_Position scratch; meshtastic_Position *decoded = NULL;
meshtastic_Position *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
memset(&scratch, 0, sizeof(scratch)); memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Position_msg, &scratch)) { if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Position_msg, &scratch)) {
decoded = &scratch; decoded = &scratch;
@ -627,15 +623,12 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
} else { } else {
LOG_ERROR("Error decoding protobuf for position message!\n"); LOG_ERROR("Error decoding protobuf for position message!\n");
} }
}; break;
break; }
} case meshtastic_PortNum_WAYPOINT_APP: {
msgType = "position";
case meshtastic_PortNum_WAYPOINT_APP: { meshtastic_Waypoint scratch;
msgType = "position"; meshtastic_Waypoint *decoded = NULL;
meshtastic_Waypoint scratch;
meshtastic_Waypoint *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
memset(&scratch, 0, sizeof(scratch)); memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Waypoint_msg, &scratch)) { if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Waypoint_msg, &scratch)) {
decoded = &scratch; decoded = &scratch;
@ -650,14 +643,12 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
} else { } else {
LOG_ERROR("Error decoding protobuf for position message!\n"); LOG_ERROR("Error decoding protobuf for position message!\n");
} }
}; break;
break; }
} case meshtastic_PortNum_NEIGHBORINFO_APP: {
case meshtastic_PortNum_NEIGHBORINFO_APP: { msgType = "neighborinfo";
msgType = "neighborinfo"; meshtastic_NeighborInfo scratch;
meshtastic_NeighborInfo scratch; meshtastic_NeighborInfo *decoded = NULL;
meshtastic_NeighborInfo *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
memset(&scratch, 0, sizeof(scratch)); memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_NeighborInfo_msg, if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_NeighborInfo_msg,
&scratch)) { &scratch)) {
@ -678,12 +669,14 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
} else { } else {
LOG_ERROR("Error decoding protobuf for neighborinfo message!\n"); LOG_ERROR("Error decoding protobuf for neighborinfo message!\n");
} }
}; break;
break; }
} // add more packet types here if needed
// add more packet types here if needed default:
default: break;
break; }
} else {
LOG_WARN("Couldn't convert encrypted payload of MeshPacket to JSON\n");
} }
jsonObj["id"] = new JSONValue((uint)mp->id); jsonObj["id"] = new JSONValue((uint)mp->id);

View File

@ -193,8 +193,26 @@ void cpuDeepSleep(uint32_t msecToWake)
rtc_gpio_isolate((gpio_num_t)rtcGpios[i]); rtc_gpio_isolate((gpio_num_t)rtcGpios[i]);
#endif #endif
// FIXME, disable internal rtc pullups/pulldowns on the non isolated pins. for inputs that we aren't using // FIXME, disable internal rtc pullups/pulldowns on the non isolated pins. for inputs that we aren't using
// to detect wake and in normal operation the external part drives them hard. // to detect wake and in normal operation the external part drives them hard.
#ifdef BUTTON_PIN
// Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39.
#if SOC_RTCIO_HOLD_SUPPORTED
uint64_t gpioMask = (1ULL << (config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN));
#endif
#ifdef BUTTON_NEED_PULLUP
gpio_pullup_en((gpio_num_t)BUTTON_PIN);
#endif
// Not needed because both of the current boards have external pullups
// FIXME change polarity in hw so we can wake on ANY_HIGH instead - that would allow us to use all three buttons (instead of
// just the first) gpio_pullup_en((gpio_num_t)BUTTON_PIN);
#if SOC_PM_SUPPORT_EXT_WAKEUP
esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ALL_LOW);
#endif
#endif
// We want RTC peripherals to stay on // We want RTC peripherals to stay on
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);

View File

@ -95,7 +95,29 @@ void initDeepSleep()
{ {
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
bootCount++; bootCount++;
const char *reason;
wakeCause = esp_sleep_get_wakeup_cause(); wakeCause = esp_sleep_get_wakeup_cause();
switch (wakeCause) {
case ESP_SLEEP_WAKEUP_EXT0:
reason = "ext0 RTC_IO";
break;
case ESP_SLEEP_WAKEUP_EXT1:
reason = "ext1 RTC_CNTL";
break;
case ESP_SLEEP_WAKEUP_TIMER:
reason = "timer";
break;
case ESP_SLEEP_WAKEUP_TOUCHPAD:
reason = "touchpad";
break;
case ESP_SLEEP_WAKEUP_ULP:
reason = "ULP program";
break;
default:
reason = "reset";
break;
}
/* /*
Not using yet because we are using wake on all buttons being low Not using yet because we are using wake on all buttons being low
@ -106,7 +128,6 @@ void initDeepSleep()
#ifdef DEBUG_PORT #ifdef DEBUG_PORT
// If we booted because our timer ran out or the user pressed reset, send those as fake events // If we booted because our timer ran out or the user pressed reset, send those as fake events
const char *reason = "reset"; // our best guess
RESET_REASON hwReason = rtc_get_reset_reason(0); RESET_REASON hwReason = rtc_get_reset_reason(0);
if (hwReason == RTCWDT_BROWN_OUT_RESET) if (hwReason == RTCWDT_BROWN_OUT_RESET)
@ -118,9 +139,6 @@ void initDeepSleep()
if (hwReason == TG1WDT_SYS_RESET) if (hwReason == TG1WDT_SYS_RESET)
reason = "intWatchdog"; reason = "intWatchdog";
if (wakeCause == ESP_SLEEP_WAKEUP_TIMER)
reason = "timeout";
LOG_INFO("Booted, wake cause %d (boot count %d), reset_reason=%s\n", wakeCause, bootCount, reason); LOG_INFO("Booted, wake cause %d (boot count %d), reset_reason=%s\n", wakeCause, bootCount, reason);
#endif #endif
#endif #endif
@ -175,7 +193,8 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false)
nodeDB.saveToDisk(); nodeDB.saveToDisk();
// Kill GPS power completely (even if previously we just had it in sleep mode) // Kill GPS power completely (even if previously we just had it in sleep mode)
gps->setGPSPower(false, false, 0); if (gps)
gps->setGPSPower(false, false, 0);
setLed(false); setLed(false);