Skip to content

Commit

Permalink
Merge branch 'master' into NextHopRouter
Browse files Browse the repository at this point in the history
  • Loading branch information
thebentern authored Oct 3, 2023
2 parents 0d6729b + 37c3d15 commit 3776064
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 80 deletions.
4 changes: 1 addition & 3 deletions src/PowerFSM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,10 +348,8 @@ void PowerFSM_setup()
getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
"Screen-on timeout");

// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
#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
if (isRouter || config.power.is_power_saving) {
powerFSM.add_timed_transition(&stateNB, &stateLS,
Expand Down
2 changes: 1 addition & 1 deletion src/gps/GPS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ HardwareSerial *GPS::_serial_gps = &Serial1;
HardwareSerial *GPS::_serial_gps = NULL;
#endif

GPS *gps;
GPS *gps = nullptr;

/// Multiple GPS instances might use the same serial port (in sequence), but we can
/// only init that port once.
Expand Down
23 changes: 20 additions & 3 deletions src/graphics/Screen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,28 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl
// 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)
{
// Draw region in upper left
const char *region = myRegion ? myRegion->name : NULL;
drawIconScreen(region, display, state, x, y);
#ifdef ARCH_ESP32
if (wakeCause == ESP_SLEEP_WAKEUP_TIMER || wakeCause == ESP_SLEEP_WAKEUP_EXT1) {
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)
Expand Down
125 changes: 59 additions & 66 deletions src/mqtt/MQTT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,34 +516,34 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
JSONObject msgPayload;
JSONObject jsonObj;

switch (mp->decoded.portnum) {
case meshtastic_PortNum_TEXT_MESSAGE_APP: {
msgType = "text";
// convert bytes to string
LOG_DEBUG("got text message of size %u\n", mp->decoded.payload.size);
char payloadStr[(mp->decoded.payload.size) + 1];
memcpy(payloadStr, mp->decoded.payload.bytes, mp->decoded.payload.size);
payloadStr[mp->decoded.payload.size] = 0; // null terminated string
// check if this is a JSON payload
JSONValue *json_value = JSON::Parse(payloadStr);
if (json_value != NULL) {
LOG_INFO("text message payload is of type json\n");
// if it is, then we can just use the json object
jsonObj["payload"] = json_value;
} else {
// if it isn't, then we need to create a json object
// with the string as the value
LOG_INFO("text message payload is of type plaintext\n");
msgPayload["text"] = new JSONValue(payloadStr);
jsonObj["payload"] = new JSONValue(msgPayload);
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
switch (mp->decoded.portnum) {
case meshtastic_PortNum_TEXT_MESSAGE_APP: {
msgType = "text";
// convert bytes to string
LOG_DEBUG("got text message of size %u\n", mp->decoded.payload.size);
char payloadStr[(mp->decoded.payload.size) + 1];
memcpy(payloadStr, mp->decoded.payload.bytes, mp->decoded.payload.size);
payloadStr[mp->decoded.payload.size] = 0; // null terminated string
// check if this is a JSON payload
JSONValue *json_value = JSON::Parse(payloadStr);
if (json_value != NULL) {
LOG_INFO("text message payload is of type json\n");
// if it is, then we can just use the json object
jsonObj["payload"] = json_value;
} else {
// if it isn't, then we need to create a json object
// with the string as the value
LOG_INFO("text message payload is of type plaintext\n");
msgPayload["text"] = new JSONValue(payloadStr);
jsonObj["payload"] = new JSONValue(msgPayload);
}
break;
}
break;
}
case meshtastic_PortNum_TELEMETRY_APP: {
msgType = "telemetry";
meshtastic_Telemetry scratch;
meshtastic_Telemetry *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
case meshtastic_PortNum_TELEMETRY_APP: {
msgType = "telemetry";
meshtastic_Telemetry scratch;
meshtastic_Telemetry *decoded = NULL;
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Telemetry_msg, &scratch)) {
decoded = &scratch;
Expand All @@ -564,14 +564,12 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
} else {
LOG_ERROR("Error decoding protobuf for telemetry message!\n");
}
};
break;
}
case meshtastic_PortNum_NODEINFO_APP: {
msgType = "nodeinfo";
meshtastic_User scratch;
meshtastic_User *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
break;
}
case meshtastic_PortNum_NODEINFO_APP: {
msgType = "nodeinfo";
meshtastic_User scratch;
meshtastic_User *decoded = NULL;
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_User_msg, &scratch)) {
decoded = &scratch;
Expand All @@ -583,14 +581,12 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
} else {
LOG_ERROR("Error decoding protobuf for nodeinfo message!\n");
}
};
break;
}
case meshtastic_PortNum_POSITION_APP: {
msgType = "position";
meshtastic_Position scratch;
meshtastic_Position *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
break;
}
case meshtastic_PortNum_POSITION_APP: {
msgType = "position";
meshtastic_Position scratch;
meshtastic_Position *decoded = NULL;
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Position_msg, &scratch)) {
decoded = &scratch;
Expand Down Expand Up @@ -627,15 +623,12 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
} else {
LOG_ERROR("Error decoding protobuf for position message!\n");
}
};
break;
}

case meshtastic_PortNum_WAYPOINT_APP: {
msgType = "position";
meshtastic_Waypoint scratch;
meshtastic_Waypoint *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
break;
}
case meshtastic_PortNum_WAYPOINT_APP: {
msgType = "position";
meshtastic_Waypoint scratch;
meshtastic_Waypoint *decoded = NULL;
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Waypoint_msg, &scratch)) {
decoded = &scratch;
Expand All @@ -650,14 +643,12 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
} else {
LOG_ERROR("Error decoding protobuf for position message!\n");
}
};
break;
}
case meshtastic_PortNum_NEIGHBORINFO_APP: {
msgType = "neighborinfo";
meshtastic_NeighborInfo scratch;
meshtastic_NeighborInfo *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
break;
}
case meshtastic_PortNum_NEIGHBORINFO_APP: {
msgType = "neighborinfo";
meshtastic_NeighborInfo scratch;
meshtastic_NeighborInfo *decoded = NULL;
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_NeighborInfo_msg,
&scratch)) {
Expand All @@ -678,12 +669,14 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
} else {
LOG_ERROR("Error decoding protobuf for neighborinfo message!\n");
}
};
break;
}
// add more packet types here if needed
default:
break;
break;
}
// add more packet types here if needed
default:
break;
}
} else {
LOG_WARN("Couldn't convert encrypted payload of MeshPacket to JSON\n");
}

jsonObj["id"] = new JSONValue((uint)mp->id);
Expand Down
22 changes: 20 additions & 2 deletions src/platform/esp32/main-esp32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,26 @@ void cpuDeepSleep(uint32_t msecToWake)
rtc_gpio_isolate((gpio_num_t)rtcGpios[i]);
#endif

// 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.
// 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.
#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
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
Expand Down
29 changes: 24 additions & 5 deletions src/sleep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,29 @@ void initDeepSleep()
{
#ifdef ARCH_ESP32
bootCount++;
const char *reason;
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
Expand All @@ -106,7 +128,6 @@ void initDeepSleep()

#ifdef DEBUG_PORT
// 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);

if (hwReason == RTCWDT_BROWN_OUT_RESET)
Expand All @@ -118,9 +139,6 @@ void initDeepSleep()
if (hwReason == TG1WDT_SYS_RESET)
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);
#endif
#endif
Expand Down Expand Up @@ -175,7 +193,8 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false)
nodeDB.saveToDisk();

// 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);

Expand Down

0 comments on commit 3776064

Please sign in to comment.