From 6ceb4230337ab8be0ba6b10322571044829ffd4a Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 8 Mar 2021 12:03:04 +0800 Subject: [PATCH 01/17] TODO update --- docs/software/TODO.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/software/TODO.md b/docs/software/TODO.md index 26fb08851..b26ce9b5b 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -29,6 +29,7 @@ You probably don't care about this section - skip to the next one. * DONE release protobufs * DONE release to developers * DONE fix setch-fast in python tool +* turn off fault 8: https://github.com/meshtastic/Meshtastic-device/issues/734 * age out pendingrequests in the python API * DONE stress test channel download from python, sometimes it seems like we don't get all replies, bug was due to simultaneous android connection * DONE combine acks and responses in a single message if possible (do routing plugin LAST and drop ACK if someone else has already replied) From c0e180759d7d05d1c2a09e43c8e6cacb62b7af00 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 8 Mar 2021 15:20:29 +0800 Subject: [PATCH 02/17] improve debugging on cortex m --- bin/nrf52840-gdbserver.sh | 2 +- platformio.ini | 25 ++++++++++++++++++++++--- src/nrf52/hardfault.cpp | 26 ++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/bin/nrf52840-gdbserver.sh b/bin/nrf52840-gdbserver.sh index 15fb8fbff..010c1003f 100755 --- a/bin/nrf52840-gdbserver.sh +++ b/bin/nrf52840-gdbserver.sh @@ -1,3 +1,3 @@ -JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52840_XXAA +JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52840_XXAA -SuppressInfoUpdateFW -DisableAutoUpdateFW -rtos GDBServer/RTOSPlugin_FreeRTOS diff --git a/platformio.ini b/platformio.ini index d8ef51b7f..aeab4f65b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,13 +9,13 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] -default_envs = tbeam +;default_envs = tbeam ;default_envs = tbeam0.7 ;default_envs = heltec ;default_envs = tlora-v1 ;default_envs = tlora-v2 ;default_envs = lora-relay-v1 # nrf board -;default_envs = eink +default_envs = eink ;default_envs = linux # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here [common] @@ -184,7 +184,6 @@ src_filter = ; platform = nordicnrf52 platform = https://github.com/meshtastic/platform-nordicnrf52.git#1a2639a6b0f79b5df66bea3e3089f0d5285fdc63 extends = arduino_base -debug_tool = jlink build_type = debug ; I'm debugging with ICE a lot now ; note: liboberon provides the AES256 implementation for NRF52 (though not using the hardware acceleration of the NRF52840 - FIXME) build_flags = @@ -198,6 +197,26 @@ lib_ignore = BluetoothOTA monitor_port = /dev/ttyACM1 +# we pass in options to jlink so it can understand freertos (note: we don't use "jlink" as the tool) +debug_tool = jlink +debug_port = :2331 +# Note: the ARGUMENTS MUST BE on multiple lines. Otherwise platformio/commands/debug/helpers.py misparses everything into the "executable" +# attribute and leaves "arguments" empty +# /home/kevinh/.platformio/packages/tool-jlink/JLinkGDBServerCLExe +debug_server = + /usr/bin/JLinkGDBServerCLExe + -singlerun + -if + SWD + -select + USB + -device + nRF52840_xxAA + -port + 2331 + -rtos + GDBServer/RTOSPlugin_FreeRTOS + debug_extra_cmds = source gdbinit diff --git a/src/nrf52/hardfault.cpp b/src/nrf52/hardfault.cpp index c1a82d6ae..d63829072 100644 --- a/src/nrf52/hardfault.cpp +++ b/src/nrf52/hardfault.cpp @@ -82,8 +82,34 @@ extern "C" void HardFault_Impl(uint32_t stack[]) // while (1) ; } +#ifndef INC_FREERTOS_H +// This is a generic cortex M entrypoint that doesn't assume freertos + extern "C" void HardFault_Handler(void) { asm volatile(" mrs r0,msp\n" " b HardFault_Impl \n"); } +#else + +/* The prototype shows it is a naked function - in effect this is just an +assembly function. */ +extern "C" void HardFault_Handler( void ) __attribute__( ( naked ) ); + +/* The fault handler implementation calls a function called +prvGetRegistersFromStack(). */ +extern "C" void HardFault_Handler(void) +{ + __asm volatile + ( + " tst lr, #4 \n" + " ite eq \n" + " mrseq r0, msp \n" + " mrsne r0, psp \n" + " ldr r1, [r0, #24] \n" + " ldr r2, handler2_address_const \n" + " bx r2 \n" + " handler2_address_const: .word HardFault_Impl \n" + ); +} +#endif From 707ed75138cb17c5bbd4b299972ede38c83398d8 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 8 Mar 2021 15:20:43 +0800 Subject: [PATCH 03/17] fix warnings found in nrf52 build --- src/RedirectablePrint.cpp | 2 +- src/mesh/Channels.cpp | 2 +- src/plugins/ExternalNotificationPlugin.cpp | 3 ++- src/plugins/SerialPlugin.cpp | 3 ++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index c60b8a502..fd634a99f 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -38,7 +38,7 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg) va_end(arg); return 0; }; - if (len >= printBufLen) { + if (len >= (int) printBufLen) { delete[] printBuf; printBufLen *= 2; printBuf = new char[printBufLen]; diff --git a/src/mesh/Channels.cpp b/src/mesh/Channels.cpp index 414930182..ab0a64b37 100644 --- a/src/mesh/Channels.cpp +++ b/src/mesh/Channels.cpp @@ -13,7 +13,7 @@ Channels channels; uint8_t xorHash(const uint8_t *p, size_t len) { uint8_t code = 0; - for (int i = 0; i < len; i++) + for (size_t i = 0; i < len; i++) code ^= p[i]; return code; } diff --git a/src/plugins/ExternalNotificationPlugin.cpp b/src/plugins/ExternalNotificationPlugin.cpp index 42865f3cc..0320c7b30 100644 --- a/src/plugins/ExternalNotificationPlugin.cpp +++ b/src/plugins/ExternalNotificationPlugin.cpp @@ -114,7 +114,8 @@ int32_t ExternalNotificationPlugin::runOnce() return (INT32_MAX); } - +#else + return INT32_MAX; #endif } diff --git a/src/plugins/SerialPlugin.cpp b/src/plugins/SerialPlugin.cpp index c93bf8521..9aab876f9 100644 --- a/src/plugins/SerialPlugin.cpp +++ b/src/plugins/SerialPlugin.cpp @@ -124,7 +124,8 @@ int32_t SerialPlugin::runOnce() return (INT32_MAX); } - +#else + return INT32_MAX; #endif } From 7bbd2c0e804e361fd99e7e020fb8dd142374458f Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 8 Mar 2021 15:30:08 +0800 Subject: [PATCH 04/17] make textmessageplugin optional --- src/graphics/Screen.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 6e52abdde..c0511a8c6 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -791,7 +791,8 @@ void Screen::setup() powerStatusObserver.observe(&powerStatus->onNewStatus); gpsStatusObserver.observe(&gpsStatus->onNewStatus); nodeStatusObserver.observe(&nodeStatus->onNewStatus); - textMessageObserver.observe(textMessagePlugin); + if(textMessagePlugin) + textMessageObserver.observe(textMessagePlugin); } void Screen::forceDisplay() From 781d2f0ad635e400f6223dbc74811bb334e23da2 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 8 Mar 2021 17:09:35 +0800 Subject: [PATCH 05/17] fix warnings --- docs/software/TODO.md | 20 ++++++++++++++++---- src/graphics/Screen.cpp | 2 ++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/docs/software/TODO.md b/docs/software/TODO.md index b26ce9b5b..a7d85dcfd 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -87,14 +87,26 @@ eink: * new battery level sensing * measure current draw * DONE: fix backlight -* USB is busted because of power enable mode? +* DONE - USB is busted because of power enable mode? +* test that board leaves bootloader always +* test USB - works in bootloader +* test LEDs +* Test BME280 +* test gps +* check GPS fast locking +* tested! dlora +* test eink backlight +* tested! eink +* test buttons +* test battery charging +* test serial flash +* send updated app and bootloader image * OHH BME280! THAT IS GREAT! * make new screen work, ask for datasheet * say I think you could ship this * leds seem busted -* usb doesn't stay connected -* check GPS works -* check GPS fast locking +* fix hw_model: "nrf52unknown" +* use larger icon for meshtastic logo * send email about variants & faster flash programming - https://github.com/geeksville/Meshtastic-esp32/commit/f110225173a77326aac029321cdb6491bfa640f6 * send PR for bootloader * fix nrf52 time/date diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index c0511a8c6..cfc059835 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -143,11 +143,13 @@ static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int1 drawIconScreen(region, display, state, x, y); } +#ifdef HAS_EINK /// Used on eink displays while in deep sleep static void drawSleepScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { drawIconScreen("Sleeping...", display, state, x, y); } +#endif static void drawPluginFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { From f8ec07209331657515f010b22227f9049c40b0fa Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 8 Mar 2021 17:10:48 +0800 Subject: [PATCH 06/17] make debug console stall until host has downloaded --- src/RedirectablePrint.cpp | 4 +++- src/main.cpp | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index fd634a99f..c3743b973 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -20,7 +20,7 @@ size_t RedirectablePrint::write(uint8_t c) { // Always send the characters to our segger JTAG debugger #ifdef SEGGER_STDOUT_CH - SEGGER_RTT_PutCharSkip(SEGGER_STDOUT_CH, c); + SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c); #endif dest->write(c); @@ -85,6 +85,8 @@ size_t RedirectablePrint::logDebug(const char *format, ...) auto thread = concurrency::OSThread::currentThread; if(thread) { print("["); + // printf("%p ", thread); + // assert(thread->ThreadName.length()); print(thread->ThreadName); print("] "); } diff --git a/src/main.cpp b/src/main.cpp index 495dc2f36..28ddb1bc1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -279,7 +279,13 @@ void setup() concurrency::hasBeenSetup = true; #ifdef SEGGER_STDOUT_CH - SEGGER_RTT_ConfigUpBuffer(SEGGER_STDOUT_CH, NULL, NULL, 1024, SEGGER_RTT_MODE_NO_BLOCK_TRIM); + auto mode = true ? SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL : SEGGER_RTT_MODE_NO_BLOCK_TRIM; +#ifdef NRF52840_XXAA + auto buflen = 4096; // this board has a fair amount of ram +#else + auto buflen = 256; // this board has a fair amount of ram +#endif + SEGGER_RTT_ConfigUpBuffer(SEGGER_STDOUT_CH, NULL, NULL, buflen, mode); #endif #ifdef USE_SEGGER From 87ec7b09aa2bff015fc82a69182cdef25a20b3b0 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 8 Mar 2021 18:12:21 +0800 Subject: [PATCH 07/17] add crude check for brownout --- src/mesh/generated/mesh.pb.h | 7 ++--- src/nrf52/main-nrf52.cpp | 52 +++++++++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/mesh/generated/mesh.pb.h b/src/mesh/generated/mesh.pb.h index a8f36a140..b7df1079e 100644 --- a/src/mesh/generated/mesh.pb.h +++ b/src/mesh/generated/mesh.pb.h @@ -25,7 +25,8 @@ typedef enum _CriticalErrorCode { CriticalErrorCode_UBloxInitFailed = 5, CriticalErrorCode_NoAXP192 = 6, CriticalErrorCode_InvalidRadioSetting = 7, - CriticalErrorCode_TransmitFailed = 8 + CriticalErrorCode_TransmitFailed = 8, + CriticalErrorCode_Brownout = 9 } CriticalErrorCode; typedef enum _Routing_Error { @@ -177,8 +178,8 @@ typedef struct _ToRadio { #define _Constants_ARRAYSIZE ((Constants)(Constants_DATA_PAYLOAD_LEN+1)) #define _CriticalErrorCode_MIN CriticalErrorCode_None -#define _CriticalErrorCode_MAX CriticalErrorCode_TransmitFailed -#define _CriticalErrorCode_ARRAYSIZE ((CriticalErrorCode)(CriticalErrorCode_TransmitFailed+1)) +#define _CriticalErrorCode_MAX CriticalErrorCode_Brownout +#define _CriticalErrorCode_ARRAYSIZE ((CriticalErrorCode)(CriticalErrorCode_Brownout+1)) #define _Routing_Error_MIN Routing_Error_NONE #define _Routing_Error_MAX Routing_Error_TOO_LARGE diff --git a/src/nrf52/main-nrf52.cpp b/src/nrf52/main-nrf52.cpp index 8b7bb65b9..1ba0602b9 100644 --- a/src/nrf52/main-nrf52.cpp +++ b/src/nrf52/main-nrf52.cpp @@ -1,5 +1,6 @@ #include "NRF52Bluetooth.h" #include "configuration.h" +#include "error.h" #include "graphics/TFTDisplay.h" #include #include @@ -51,14 +52,14 @@ void getMacAddr(uint8_t *dmac) NRF52Bluetooth *nrf52Bluetooth; static bool bleOn = false; -static const bool enableBle = false; // Set to false for easier debugging +static const bool useSoftDevice = false; // Set to false for easier debugging void setBluetoothEnable(bool on) { if (on != bleOn) { if (on) { if (!nrf52Bluetooth) { - if (!enableBle) + if (!useSoftDevice) DEBUG_MSG("DISABLING NRF52 BLUETOOTH WHILE DEBUGGING\n"); else { nrf52Bluetooth = new NRF52Bluetooth(); @@ -87,6 +88,49 @@ int printf(const char *fmt, ...) #include "BQ25713.h" +void initBrownout() +{ + auto vccthresh = POWER_POFCON_THRESHOLD_V28; + auto vcchthresh = POWER_POFCON_THRESHOLDVDDH_V27; + + if (useSoftDevice) { + auto err_code = sd_power_pof_enable(POWER_POFCON_POF_Enabled); + assert(err_code == NRF_SUCCESS); + + err_code = sd_power_pof_threshold_set(vccthresh); + assert(err_code == NRF_SUCCESS); + } + else { + NRF_POWER->POFCON = POWER_POFCON_POF_Msk | (vccthresh << POWER_POFCON_THRESHOLD_Pos) | (vcchthresh << POWER_POFCON_THRESHOLDVDDH_Pos); + } +} + +void checkSDEvents() +{ + if (useSoftDevice) { + uint32_t evt; + while (NRF_ERROR_NOT_FOUND == sd_evt_get(&evt)) { + switch (evt) { + case NRF_EVT_POWER_FAILURE_WARNING: + recordCriticalError(CriticalErrorCode_Brownout); + break; + + default: + DEBUG_MSG("Unexpected SDevt %d\n", evt); + break; + } + } + } else { + if(NRF_POWER->EVENTS_POFWARN) + recordCriticalError(CriticalErrorCode_Brownout); + } +} + +void nrf52Loop() +{ + checkSDEvents(); +} + void nrf52Setup() { @@ -112,6 +156,8 @@ void nrf52Setup() // randomSeed(r); DEBUG_MSG("FIXME, call randomSeed\n"); // ::printf("TESTING PRINTF\n"); + + initBrownout(); } void cpuDeepSleep(uint64_t msecToWake) @@ -128,7 +174,7 @@ void cpuDeepSleep(uint64_t msecToWake) // https://devzone.nordicsemi.com/f/nordic-q-a/48919/ram-retention-settings-with-softdevice-enabled auto ok = sd_power_system_off(); - if(ok != NRF_SUCCESS) { + if (ok != NRF_SUCCESS) { DEBUG_MSG("FIXME: Ignoring soft device (EasyDMA pending?) and forcing system-off!\n"); NRF_POWER->SYSTEMOFF = 1; } From 2f7c2a2aead2a95e35c30741372cf13c138634eb Mon Sep 17 00:00:00 2001 From: Sacha Weatherstone Date: Tue, 9 Mar 2021 16:16:41 +1100 Subject: [PATCH 08/17] Update main.yml --- .github/workflows/main.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9c9b2fffd..dcbb213b5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,11 +7,12 @@ jobs: setup: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - name: Checkout submodules - uses: textbook/git-checkout-submodule-action@master + - name: Checkout code + uses: actions/checkout@v2 + with: + submodules: true - name: Setup Python - uses: actions/setup-python@master + uses: actions/setup-python@v2 with: python-version: 3.x - name: Install Platform IO @@ -31,4 +32,4 @@ jobs: - name: Build for lora-relay-v1 run: platformio run -e lora-relay-v1 - name: Build for linux - run: platformio run -e linux \ No newline at end of file + run: platformio run -e linux From 5835abbcf625de7c71ce4e70574278cf1480c99a Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 9 Mar 2021 15:06:28 +0800 Subject: [PATCH 09/17] fix eink leds --- variants/eink/variant.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/variants/eink/variant.h b/variants/eink/variant.h index 4cdb33e45..bf8a91680 100644 --- a/variants/eink/variant.h +++ b/variants/eink/variant.h @@ -99,16 +99,16 @@ extern "C" { #define NUM_ANALOG_OUTPUTS (0) // LEDs -#define PIN_LED1 (0 + 13) // red (confirmed on 1.0 board) -#define PIN_LED2 (0 + 14) // blue (seems busted!) -#define PIN_LED3 (0 + 15) // green (seems busted!) +#define PIN_LED1 (0 + 14) // 13 red (confirmed on 1.0 board) +#define PIN_LED2 (0 + 15) // 14 blue +#define PIN_LED3 (0 + 13) // 15 green #define LED_RED PIN_LED3 -#define LED_GREEN PIN_LED1 -#define LED_BLUE PIN_LED2 +#define LED_BLUE PIN_LED1 +#define LED_GREEN PIN_LED2 -#define LED_BUILTIN LED_GREEN -#define LED_CONN PIN_BLUE +#define LED_BUILTIN LED_BLUE +#define LED_CONN PIN_GREEN #define LED_STATE_ON 0 // State when LED is lit #define LED_INVERTED 1 @@ -190,7 +190,7 @@ External serial flash WP25R1635FZUIL0 // Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface // code) -// #define LORA_DISABLE_SENDING // Define this to disable transmission for testing (power testing etc...) +#define LORA_DISABLE_SENDING // Define this to disable transmission for testing (power testing etc...) /* * eink display pins From ecaae87b79f0c38f230673fac60ea65343df3c4f Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 9 Mar 2021 15:07:02 +0800 Subject: [PATCH 10/17] make screen optional --- src/plugins/NodeInfoPlugin.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/NodeInfoPlugin.cpp b/src/plugins/NodeInfoPlugin.cpp index f5f3ae194..5111d7b87 100644 --- a/src/plugins/NodeInfoPlugin.cpp +++ b/src/plugins/NodeInfoPlugin.cpp @@ -19,9 +19,11 @@ bool NodeInfoPlugin::handleReceivedProtobuf(const MeshPacket &mp, const User *pp // Show new nodes on LCD screen if (wasBroadcast) { String lcd = String("Joined: ") + p.long_name + "\n"; - screen->print(lcd.c_str()); + if(screen) + screen->print(lcd.c_str()); } + // DEBUG_MSG("did handleReceived\n"); return false; // Let others look at this message also if they want } From d841d86bbcf13435e2cf459688b205328eec84ad Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 9 Mar 2021 15:07:16 +0800 Subject: [PATCH 11/17] brownout detect --- src/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 28ddb1bc1..3282098ba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -589,6 +589,9 @@ void loop() #ifndef NO_ESP32 esp32Loop(); #endif +#ifdef NRF52_SERIES + nrf52Loop(); +#endif // For debugging // if (rIf) ((RadioLibInterface *)rIf)->isActivelyReceiving(); From 5b0d8381b9b1fe9a3b51470b54b29297bd1f3f17 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 9 Mar 2021 15:07:26 +0800 Subject: [PATCH 12/17] fxi log formatting --- src/graphics/Screen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index cfc059835..e341aea0b 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -852,7 +852,7 @@ int32_t Screen::runOnce() free(cmd.print_text); break; default: - DEBUG_MSG("BUG: invalid cmd"); + DEBUG_MSG("BUG: invalid cmd\n"); } } From 772f2a15fffc0c528f71bc7bebaa4aa035d22b75 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 9 Mar 2021 16:45:40 +0800 Subject: [PATCH 13/17] check more error codes --- proto | 2 +- src/RedirectablePrint.cpp | 77 +++++++++++---------- src/RedirectablePrint.h | 2 + src/concurrency/BinarySemaphoreFreeRTOS.cpp | 2 + src/mesh/MemoryPool.h | 11 ++- 5 files changed, 54 insertions(+), 40 deletions(-) diff --git a/proto b/proto index 7c025b9a4..e56f2770c 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 7c025b9a4d54bb410ec17ee653122861b413f177 +Subproject commit e56f2770c33216ba94f289e2fb7f0b2dfd33aca2 diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index c3743b973..4c460d77f 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -1,9 +1,9 @@ #include "RedirectablePrint.h" +#include "concurrency/OSThread.h" #include "configuration.h" #include #include #include -#include "concurrency/OSThread.h" /** * A printer that doesn't go anywhere @@ -38,7 +38,7 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg) va_end(arg); return 0; }; - if (len >= (int) printBufLen) { + if (len >= (int)printBufLen) { delete[] printBuf; printBufLen *= 2; printBuf = new char[printBufLen]; @@ -55,47 +55,52 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg) size_t RedirectablePrint::logDebug(const char *format, ...) { - va_list arg; - va_start(arg, format); - - // Cope with 0 len format strings, but look for new line terminator - bool hasNewline = *format && format[strlen(format) - 1] == '\n'; - size_t r = 0; - // If we are the first message on a report, include the header - if (!isContinuationMessage) { - struct timeval tv; - if (!gettimeofday(&tv, NULL)) { - long hms = tv.tv_sec % SEC_PER_DAY; - //hms += tz.tz_dsttime * SEC_PER_HOUR; - //hms -= tz.tz_minuteswest * SEC_PER_MIN; - // mod `hms` to ensure in positive range of [0...SEC_PER_DAY) - hms = (hms + SEC_PER_DAY) % SEC_PER_DAY; + if (!inDebugPrint) { + inDebugPrint = true; - // Tear apart hms into h:m:s - int hour = hms / SEC_PER_HOUR; - int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN; - int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN + va_list arg; + va_start(arg, format); - r += printf("%02d:%02d:%02d %u ", hour, min, sec, millis() / 1000); - } else - r += printf("??:??:?? %u ", millis() / 1000); + // Cope with 0 len format strings, but look for new line terminator + bool hasNewline = *format && format[strlen(format) - 1] == '\n'; - auto thread = concurrency::OSThread::currentThread; - if(thread) { - print("["); - // printf("%p ", thread); - // assert(thread->ThreadName.length()); - print(thread->ThreadName); - print("] "); + // If we are the first message on a report, include the header + if (!isContinuationMessage) { + struct timeval tv; + if (!gettimeofday(&tv, NULL)) { + long hms = tv.tv_sec % SEC_PER_DAY; + // hms += tz.tz_dsttime * SEC_PER_HOUR; + // hms -= tz.tz_minuteswest * SEC_PER_MIN; + // mod `hms` to ensure in positive range of [0...SEC_PER_DAY) + hms = (hms + SEC_PER_DAY) % SEC_PER_DAY; + + // Tear apart hms into h:m:s + int hour = hms / SEC_PER_HOUR; + int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN; + int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN + + r += printf("%02d:%02d:%02d %u ", hour, min, sec, millis() / 1000); + } else + r += printf("??:??:?? %u ", millis() / 1000); + + auto thread = concurrency::OSThread::currentThread; + if (thread) { + print("["); + // printf("%p ", thread); + // assert(thread->ThreadName.length()); + print(thread->ThreadName); + print("] "); + } } + + r += vprintf(format, arg); + va_end(arg); + + isContinuationMessage = !hasNewline; + inDebugPrint = false; } - r += vprintf(format, arg); - va_end(arg); - - isContinuationMessage = !hasNewline; - return r; } \ No newline at end of file diff --git a/src/RedirectablePrint.h b/src/RedirectablePrint.h index ca208612c..1eb60199b 100644 --- a/src/RedirectablePrint.h +++ b/src/RedirectablePrint.h @@ -19,6 +19,8 @@ class RedirectablePrint : public Print /// Used to allow multiple logDebug messages to appear on a single log line bool isContinuationMessage = false; + volatile bool inDebugPrint = false; + public: RedirectablePrint(Print *_dest) : dest(_dest) {} diff --git a/src/concurrency/BinarySemaphoreFreeRTOS.cpp b/src/concurrency/BinarySemaphoreFreeRTOS.cpp index 983ee0955..3d8097455 100644 --- a/src/concurrency/BinarySemaphoreFreeRTOS.cpp +++ b/src/concurrency/BinarySemaphoreFreeRTOS.cpp @@ -1,5 +1,6 @@ #include "concurrency/BinarySemaphoreFreeRTOS.h" #include "configuration.h" +#include #ifdef HAS_FREE_RTOS @@ -9,6 +10,7 @@ namespace concurrency BinarySemaphoreFreeRTOS::BinarySemaphoreFreeRTOS() { semaphore = xSemaphoreCreateBinary(); + assert(semaphore); } BinarySemaphoreFreeRTOS::~BinarySemaphoreFreeRTOS() diff --git a/src/mesh/MemoryPool.h b/src/mesh/MemoryPool.h index dc6305d17..8023aa6bc 100644 --- a/src/mesh/MemoryPool.h +++ b/src/mesh/MemoryPool.h @@ -101,25 +101,30 @@ template class MemoryPool : public Allocator /// Return a buffer for use by others virtual void release(T *p) { - assert(dead.enqueue(p, 0)); assert(p >= buf && (size_t)(p - buf) < maxElements); // sanity check to make sure a programmer didn't free something that didn't come from this pool + assert(dead.enqueue(p, 0)); } #ifdef HAS_FREE_RTOS /// Return a buffer from an ISR, if higherPriWoken is set to true you have some work to do ;-) void releaseFromISR(T *p, BaseType_t *higherPriWoken) { - assert(dead.enqueueFromISR(p, higherPriWoken)); assert(p >= buf && (size_t)(p - buf) < maxElements); // sanity check to make sure a programmer didn't free something that didn't come from this pool + assert(dead.enqueueFromISR(p, higherPriWoken)); } #endif protected: /// Return a queable object which has been prefilled with zeros - allow timeout to wait for available buffers (you /// probably don't want this version). - virtual T *alloc(TickType_t maxWait) { return dead.dequeuePtr(maxWait); } + virtual T *alloc(TickType_t maxWait) + { + T *p = dead.dequeuePtr(maxWait); + assert(p); + return p; + } }; From 58715f454c1ccbcfa0771a5ab6c6f5e483ebc9a2 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 10 Mar 2021 15:21:30 +0800 Subject: [PATCH 14/17] add consolePrintf for C style code --- src/SerialConsole.cpp | 12 ++++++++++-- src/SerialConsole.h | 3 +++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/SerialConsole.cpp b/src/SerialConsole.cpp index 9bb539fa5..ad1cf642a 100644 --- a/src/SerialConsole.cpp +++ b/src/SerialConsole.cpp @@ -1,13 +1,21 @@ #include "SerialConsole.h" +#include "NodeDB.h" #include "PowerFSM.h" #include "configuration.h" -#include "NodeDB.h" #include #define Port Serial SerialConsole console; +void consolePrintf(const char *format, ...) +{ + va_list arg; + va_start(arg, format); + console.vprintf(format, arg); + va_end(arg); +} + SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port) { canWrite = false; // We don't send packets to our port until it has talked to us first @@ -29,7 +37,7 @@ void SerialConsole::init() void SerialConsole::handleToRadio(const uint8_t *buf, size_t len) { // Turn off debug serial printing once the API is activated, because other threads could print and corrupt packets - if(!radioConfig.preferences.debug_log_enabled) + if (!radioConfig.preferences.debug_log_enabled) setDestination(&noopPrint); canWrite = true; diff --git a/src/SerialConsole.h b/src/SerialConsole.h index 17cb16943..b4f076286 100644 --- a/src/SerialConsole.h +++ b/src/SerialConsole.h @@ -32,4 +32,7 @@ class SerialConsole : public StreamAPI, public RedirectablePrint virtual void onConnectionChanged(bool connected); }; +// A simple wrapper to allow non class aware code write to the console +void consolePrintf(const char *format, ...); + extern SerialConsole console; From 217bd934d72f1f19ee51e3455561ddf95bcee899 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 10 Mar 2021 15:21:54 +0800 Subject: [PATCH 15/17] fix GPS fixme wrt deletion --- src/gps/GPS.cpp | 22 +++++++++++++++------- src/gps/GPS.h | 2 +- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 04aa2c7af..abf7fc270 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -25,7 +25,7 @@ uint8_t GPS::i2cAddress = 0; GPS *gps; -/// 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. static bool didSerialInit; @@ -33,7 +33,7 @@ bool GPS::setupGPS() { if (_serial_gps && !didSerialInit) { didSerialInit = true; - + #ifdef GPS_RX_PIN _serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); #else @@ -73,6 +73,13 @@ bool GPS::setup() return ok; } +GPS::~GPS() +{ + // we really should unregister our sleep observer + notifySleepObserver.unobserve(); + notifyDeepSleepObserver.unobserve(); +} + // Allow defining the polarity of the WAKE output. default is active high #ifndef GPS_WAKE_ACTIVE #define GPS_WAKE_ACTIVE 1 @@ -86,8 +93,8 @@ void GPS::wake() #endif } - -void GPS::sleep() { +void GPS::sleep() +{ #ifdef PIN_GPS_WAKE digitalWrite(PIN_GPS_WAKE, GPS_WAKE_ACTIVE ? 0 : 1); pinMode(PIN_GPS_WAKE, OUTPUT); @@ -158,7 +165,8 @@ uint32_t GPS::getWakeTime() const return t; // already maxint if (t == 0) - t = radioConfig.preferences.is_router ? 5 * 60 : 15 * 60; // Allow up to 15 mins for each attempt (probably will be much less if we can find sats) or less if a router + t = radioConfig.preferences.is_router ? 5 * 60 : 15 * 60; // Allow up to 15 mins for each attempt (probably will be much + // less if we can find sats) or less if a router t *= 1000; // msecs @@ -179,8 +187,8 @@ uint32_t GPS::getSleepTime() const if (t == UINT32_MAX) return t; // already maxint - if (t == 0) // default - unset in preferences - t = radioConfig.preferences.is_router ? 24 * 60 * 60 : 2 * 60; // 2 mins or once per day for routers + if (t == 0) // default - unset in preferences + t = radioConfig.preferences.is_router ? 24 * 60 * 60 : 2 * 60; // 2 mins or once per day for routers t *= 1000; diff --git a/src/gps/GPS.h b/src/gps/GPS.h index eca2962d2..9d25b2f83 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -47,7 +47,7 @@ class GPS : private concurrency::OSThread GPS() : concurrency::OSThread("GPS") {} - virtual ~GPS() {} // FIXME, we really should unregister our sleep observer + virtual ~GPS(); /** We will notify this observable anytime GPS state has changed meaningfully */ Observable newStatus; From 6e37fe63434813a83de4d18f0f1a2f6d56693a1a Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 10 Mar 2021 15:24:00 +0800 Subject: [PATCH 16/17] turn radio back on --- variants/eink/variant.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/variants/eink/variant.h b/variants/eink/variant.h index bf8a91680..66a42421f 100644 --- a/variants/eink/variant.h +++ b/variants/eink/variant.h @@ -190,7 +190,10 @@ External serial flash WP25R1635FZUIL0 // Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface // code) -#define LORA_DISABLE_SENDING // Define this to disable transmission for testing (power testing etc...) +// #define LORA_DISABLE_SENDING // Define this to disable transmission for testing (power testing etc...) + +// #undef SX1262_CS +// #define USE_SIM_RADIO // define to not use the lora radio hardware at all /* * eink display pins From f55ac8e9c937210a25ff03163ea30078b4613704 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 10 Mar 2021 15:29:25 +0800 Subject: [PATCH 17/17] turn off (buggy) custom_fields in tinygps, and used fixed version of lib --- docs/software/TODO.md | 5 ++++- platformio.ini | 11 +++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/software/TODO.md b/docs/software/TODO.md index a7d85dcfd..1649250de 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -84,10 +84,13 @@ You probably don't care about this section - skip to the next one. eink: +* DONE check email of reported issues +* DONE turn off vbus driving (in bootloader) * new battery level sensing -* measure current draw +* current draw no good * DONE: fix backlight * DONE - USB is busted because of power enable mode? +* test CPU voltage? something is bad with RAM (removing eink module does not help) * test that board leaves bootloader always * test USB - works in bootloader * test LEDs diff --git a/platformio.ini b/platformio.ini index aeab4f65b..742bc6db6 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,13 +9,14 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] -;default_envs = tbeam +default_envs = tbeam ;default_envs = tbeam0.7 ;default_envs = heltec ;default_envs = tlora-v1 ;default_envs = tlora-v2 ;default_envs = lora-relay-v1 # nrf board -default_envs = eink +;default_envs = eink +;default_envs = nrf52840dk-geeksville ;default_envs = linux # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here [common] @@ -33,6 +34,8 @@ default_envs = eink extra_scripts = bin/platformio-custom.py ; note: we add src to our include search path so that lmic_project_config can override +; note: TINYGPS_OPTION_NO_CUSTOM_FIELDS is VERY important. We don't use custom fields and somewhere in that pile +; of code is a heap corruption bug! ; FIXME: fix lib/BluetoothOTA dependency back on src/ so we can remove -Isrc build_flags = -Wno-missing-field-initializers -Wno-format @@ -40,7 +43,7 @@ build_flags = -Wno-missing-field-initializers -DHW_VERSION_${sysenv.COUNTRY} -DHW_VERSION=${sysenv.HW_VERSION} -DUSE_THREAD_NAMES - -DTINYGPSPLUS_OPTION_NO_CUSTOM_FIELDS + -DTINYGPS_OPTION_NO_CUSTOM_FIELDS ; leave this commented out to avoid breaking Windows ;upload_port = /dev/ttyUSB0 @@ -74,7 +77,7 @@ lib_deps = https://github.com/meshtastic/arduino-fsm.git#2f106146071fc7bc620e1e8d4b88dc4e0266ce39 https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad https://github.com/meshtastic/RadioLib.git#07de964e929238949035fb0d5887026a3058df1a - https://github.com/meshtastic/TinyGPSPlus.git#9c1d584d2469523381e077b0b9c1bf868d6c0206 + https://github.com/meshtastic/TinyGPSPlus.git#f0f47067ef2f67c856475933188251c1ef615e79 https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460 Wire ; explicitly needed here because the AXP202 library forgets to add it SPI