diff --git a/docs/software/nrf52-TODO.md b/docs/software/nrf52-TODO.md
index 500180d03..55b781d23 100644
--- a/docs/software/nrf52-TODO.md
+++ b/docs/software/nrf52-TODO.md
@@ -59,8 +59,6 @@ Needed to be fully functional at least at the same level of the ESP32 boards. At
Nice ideas worth considering someday...
-- Use flego to me an iOS/linux app? https://felgo.com/doc/qt/qtbluetooth-index/ or
-- Use flutter to make an iOS/linux app? https://github.com/Polidea/FlutterBleLib
- enable monitor mode debugging (need to use real jlink): https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/monitor-mode-debugging-with-j-link-and-gdbeclipse
- Improve efficiency of PeriodicTimer by only checking the next queued timer event, and carefully sorting based on schedule
- make a Mfg Controller and device under test classes as examples of custom app code for third party devs. Make a post about this. Use a custom payload type code. Have device under test send a broadcast with max hopcount of 0 for the 'mfgcontroller' payload type. mfg controller will read SNR and reply. DOT will declare failure/success and switch to the regular app screen.
diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp
index 1e9adbec9..c495cd27f 100644
--- a/src/PowerFSM.cpp
+++ b/src/PowerFSM.cpp
@@ -26,60 +26,70 @@ static void sdsEnter()
#include "error.h"
+static uint32_t secsSlept;
+
static void lsEnter()
{
DEBUG_MSG("lsEnter begin, ls_secs=%u\n", radioConfig.preferences.ls_secs);
screen.setOn(false);
+ secsSlept = 0; // How long have we been sleeping this time
DEBUG_MSG("lsEnter end\n");
}
static void lsIdle()
{
- DEBUG_MSG("lsIdle begin ls_secs=%u\n", radioConfig.preferences.ls_secs);
+ // DEBUG_MSG("lsIdle begin ls_secs=%u\n", radioConfig.preferences.ls_secs);
#ifndef NO_ESP32
- uint32_t secsSlept = 0;
esp_sleep_source_t wakeCause = ESP_SLEEP_WAKEUP_UNDEFINED;
- bool reached_ls_secs = false;
- while (!reached_ls_secs) {
+ // Do we have more sleeping to do?
+ if (secsSlept < radioConfig.preferences.ls_secs) {
// Briefly come out of sleep long enough to blink the led once every few seconds
- uint32_t sleepTime = 5;
+ uint32_t sleepTime = 30;
- setLed(false); // Never leave led on while in light sleep
- wakeCause = doLightSleep(sleepTime * 1000LL);
- if (wakeCause != ESP_SLEEP_WAKEUP_TIMER)
- break;
+ // 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
+ wakeCause = doLightSleep(sleepTime * 1000LL);
- setLed(true); // briefly turn on led
- doLightSleep(1);
- if (wakeCause != ESP_SLEEP_WAKEUP_TIMER)
- break;
+ if (wakeCause == ESP_SLEEP_WAKEUP_TIMER) {
+ // Normal case: timer expired, we should just go back to sleep ASAP
- secsSlept += sleepTime;
- reached_ls_secs = secsSlept >= radioConfig.preferences.ls_secs;
- }
- setLed(false);
+ setLed(true); // briefly turn on led
+ wakeCause = doLightSleep(1); // leave led on for 1ms
- if (reached_ls_secs) {
- // stay in LS mode but let loop check whatever it wants
- DEBUG_MSG("reached ls_secs, servicing loop()\n");
- } else {
- DEBUG_MSG("wakeCause %d\n", wakeCause);
+ secsSlept += sleepTime;
+ // DEBUG_MSG("sleeping, flash led!\n");
+ }
+ if (wakeCause == 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)
+ //uint64_t status = esp_sleep_get_ext1_wakeup_status();
+ DEBUG_MSG("wakeCause %d\n", wakeCause);
#ifdef BUTTON_PIN
- bool pressed = !digitalRead(BUTTON_PIN);
+ bool pressed = !digitalRead(BUTTON_PIN);
#else
- bool pressed = false;
+ bool pressed = false;
#endif
- 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)
- powerFSM.trigger(EVENT_WAKE_TIMER);
+ 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)
+ powerFSM.trigger(EVENT_WAKE_TIMER);
+ }
+ }
}
+ } else {
+ // Time to stop sleeping!
+ setLed(false);
+ DEBUG_MSG("reached ls_secs, servicing loop()\n");
+ powerFSM.trigger(EVENT_WAKE_TIMER);
}
#endif
}
diff --git a/src/configuration.h b/src/configuration.h
index bc64d3187..4759dfc73 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -258,7 +258,10 @@ along with this program. If not, see .
#ifdef NO_ESP32
#define USE_SEGGER
+#else
+#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32
#endif
+
#ifdef USE_SEGGER
#include "SEGGER_RTT.h"
#define DEBUG_MSG(...) SEGGER_RTT_printf(0, __VA_ARGS__)
diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp
index 86b5bda84..37233a3a0 100644
--- a/src/mesh/NodeDB.cpp
+++ b/src/mesh/NodeDB.cpp
@@ -124,7 +124,7 @@ void NodeDB::init()
// default to no GPS, until one has been found by probing
myNodeInfo.has_gps = false;
myNodeInfo.message_timeout_msec = FLOOD_EXPIRE_TIME;
- myNodeInfo.min_app_version = 167;
+ myNodeInfo.min_app_version = 172;
generatePacketId(); // FIXME - ugly way to init current_packet_id;
// Init our blank owner info to reasonable defaults
diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp
index c7edf74de..43d9a6696 100644
--- a/src/mesh/RadioInterface.cpp
+++ b/src/mesh/RadioInterface.cpp
@@ -24,7 +24,7 @@ separated by 2.16 MHz with respect to the adjacent channels. Channel zero starts
// 1kb was too small
#define RADIO_STACK_SIZE 4096
-RadioInterface::RadioInterface() : txQueue(MAX_TX_QUEUE)
+RadioInterface::RadioInterface()
{
assert(sizeof(PacketHeader) == 4 || sizeof(PacketHeader) == 16); // make sure the compiler did what we expected
diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h
index 64222a76a..0617592ac 100644
--- a/src/mesh/RadioInterface.h
+++ b/src/mesh/RadioInterface.h
@@ -59,7 +59,6 @@ class RadioInterface : protected NotifiedWorkerThread
protected:
MeshPacket *sendingPacket = NULL; // The packet we are currently sending
- PointerQueue txQueue;
uint32_t lastTxStart = 0L;
/**
diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp
index 53f99aae9..5239f8f60 100644
--- a/src/mesh/RadioLibInterface.cpp
+++ b/src/mesh/RadioLibInterface.cpp
@@ -134,7 +134,7 @@ bool RadioLibInterface::canSleep()
{
bool res = txQueue.isEmpty();
if (!res) // only print debug messages if we are vetoing sleep
- DEBUG_MSG("radio wait to sleep, txEmpty=%d\n", txQueue.isEmpty());
+ DEBUG_MSG("radio wait to sleep, txEmpty=%d\n", res);
return res;
}
@@ -173,11 +173,13 @@ void RadioLibInterface::loop()
case ISR_TX:
handleTransmitInterrupt();
startReceive();
+ // DEBUG_MSG("tx complete - starting timer\n");
startTransmitTimer();
break;
case ISR_RX:
handleReceiveInterrupt();
startReceive();
+ // DEBUG_MSG("rx complete - starting timer\n");
startTransmitTimer();
break;
case TRANSMIT_DELAY_COMPLETED:
@@ -192,6 +194,8 @@ void RadioLibInterface::loop()
assert(txp);
startSend(txp);
}
+ } else {
+ // DEBUG_MSG("done with txqueue\n");
}
break;
default:
@@ -216,7 +220,7 @@ void RadioLibInterface::startTransmitTimer(bool withDelay)
uint32_t delay =
!withDelay ? 1 : random(MIN_TX_WAIT_MSEC, MAX_TX_WAIT_MSEC); // See documentation for loop() wrt these values
// DEBUG_MSG("xmit timer %d\n", delay);
-
+ // DEBUG_MSG("delaying %u\n", delay);
setPeriod(delay);
}
}
diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h
index 1a0e5f450..6619337ba 100644
--- a/src/mesh/RadioLibInterface.h
+++ b/src/mesh/RadioLibInterface.h
@@ -29,6 +29,8 @@ class RadioLibInterface : public RadioInterface, private PeriodicTask
*/
uint32_t rxBad = 0, rxGood = 0, txGood = 0;
+ PointerQueue txQueue = PointerQueue(MAX_TX_QUEUE);
+
protected:
float bw = 125;
uint8_t sf = 9;
diff --git a/src/sleep.cpp b/src/sleep.cpp
index 18462de79..8cb0f6798 100644
--- a/src/sleep.cpp
+++ b/src/sleep.cpp
@@ -14,6 +14,7 @@
#include "esp_pm.h"
#include "rom/rtc.h"
#include
+#include
#include "BluetoothUtil.h"
@@ -111,8 +112,7 @@ void initDeepSleep()
#endif
}
-/// return true if sleep is allowed
-static bool doPreflightSleep()
+bool doPreflightSleep()
{
if (preflightSleep.notifyObservers(NULL) != 0)
return false; // vetoed
@@ -257,6 +257,17 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
gpio_pullup_en((gpio_num_t)BUTTON_PIN);
#endif
+#ifdef SERIAL0_RX_GPIO
+ // We treat the serial port as a GPIO for a fast/low power way of waking, if we see a rising edge that means
+ // someone started to send something
+
+ // Alas - doesn't work reliably, instead need to use the uart specific version (which burns a little power)
+ // FIXME: gpio 3 is RXD for serialport 0 on ESP32
+ // Send a few Z characters to wake the port
+ gpio_wakeup_enable((gpio_num_t)SERIAL0_RX_GPIO, GPIO_INTR_LOW_LEVEL);
+ // uart_set_wakeup_threshold(UART_NUM_0, 3);
+ // esp_sleep_enable_uart_wakeup(0);
+#endif
#ifdef BUTTON_PIN
gpio_wakeup_enable((gpio_num_t)BUTTON_PIN, GPIO_INTR_LOW_LEVEL); // when user presses, this button goes low
#endif
diff --git a/src/sleep.h b/src/sleep.h
index b3446882a..66eafa611 100644
--- a/src/sleep.h
+++ b/src/sleep.h
@@ -19,6 +19,9 @@ void initDeepSleep();
void setCPUFast(bool on);
void setLed(bool ledOn);
+/** return true if sleep is allowed right now */
+bool doPreflightSleep();
+
extern int bootCount;
// is bluetooth sw currently running?