diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 89f0e6cb9f..509f7a1ad1 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -1,6 +1,7 @@ #include // needed for PlatformIO #include #include "MyMesh.h" +#include // Believe it or not, this std C function is busted on some platforms! static uint32_t _atoi(const char* sp) { @@ -104,7 +105,7 @@ MyMesh the_mesh(radio_driver, fast_rng, rtc_clock, tables, store /* END GLOBAL OBJECTS */ void halt() { - while (1) ; + haltWithRadioFailure(); } /* WIFI RECONNECT TRACKERS */ @@ -134,7 +135,12 @@ void setup() { } #endif - if (!radio_init()) { halt(); } + if (!radio_init()) { + #ifdef DISPLAY_CLASS + showRadioErrorOnDisplay(disp); + #endif + halt(); + } fast_rng.begin(radio_driver.getRngSeed()); diff --git a/examples/kiss_modem/main.cpp b/examples/kiss_modem/main.cpp index 5836a69416..11f8affb06 100644 --- a/examples/kiss_modem/main.cpp +++ b/examples/kiss_modem/main.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "KissModem.h" #if defined(NRF52_PLATFORM) @@ -30,7 +31,7 @@ static uint32_t next_noise_floor_calib_ms = 0; static uint32_t next_agc_reset_ms = 0; void halt() { - while (1) ; + haltWithRadioFailure(); } void loadOrCreateIdentity() { diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index a714db68ec..4031522dfb 100644 --- a/examples/simple_repeater/main.cpp +++ b/examples/simple_repeater/main.cpp @@ -2,6 +2,7 @@ #include #include "MyMesh.h" +#include #ifdef DISPLAY_CLASS #include "UITask.h" @@ -19,7 +20,7 @@ SimpleMeshTables tables; MyMesh the_mesh(board, radio_driver, *new ArduinoMillis(), fast_rng, rtc_clock, tables); void halt() { - while (1) ; + haltWithRadioFailure(); } static char command[160]; @@ -52,16 +53,20 @@ void setup() { #endif #ifdef DISPLAY_CLASS - if (display.begin()) { - display.startFrame(); - display.setCursor(0, 0); - display.print("Please wait..."); - display.endFrame(); + DisplayDriver* disp = display.begin() ? &display : NULL; + if (disp != NULL) { + disp->startFrame(); + disp->setCursor(0, 0); + disp->print("Please wait..."); + disp->endFrame(); } #endif if (!radio_init()) { MESH_DEBUG_PRINTLN("Radio init failed!"); + #ifdef DISPLAY_CLASS + showRadioErrorOnDisplay(disp); + #endif halt(); } diff --git a/examples/simple_room_server/main.cpp b/examples/simple_room_server/main.cpp index d833fff39e..e2d2d81504 100644 --- a/examples/simple_room_server/main.cpp +++ b/examples/simple_room_server/main.cpp @@ -2,6 +2,7 @@ #include #include "MyMesh.h" +#include #ifdef ETHERNET_ENABLED #define ETHERNET_CLI_BANNER "MeshCore Room Server CLI" @@ -18,7 +19,7 @@ SimpleMeshTables tables; MyMesh the_mesh(board, radio_driver, *new ArduinoMillis(), fast_rng, rtc_clock, tables); void halt() { - while (1) ; + haltWithRadioFailure(); } static char command[MAX_POST_TEXT_LEN+1]; @@ -37,15 +38,21 @@ void setup() { #endif #ifdef DISPLAY_CLASS - if (display.begin()) { - display.startFrame(); - display.setCursor(0, 0); - display.print("Please wait..."); - display.endFrame(); + DisplayDriver* disp = display.begin() ? &display : NULL; + if (disp != NULL) { + disp->startFrame(); + disp->setCursor(0, 0); + disp->print("Please wait..."); + disp->endFrame(); } #endif - if (!radio_init()) { halt(); } + if (!radio_init()) { + #ifdef DISPLAY_CLASS + showRadioErrorOnDisplay(disp); + #endif + halt(); + } fast_rng.begin(radio_driver.getRngSeed()); diff --git a/examples/simple_secure_chat/main.cpp b/examples/simple_secure_chat/main.cpp index da42ddcbbd..cc66e8b522 100644 --- a/examples/simple_secure_chat/main.cpp +++ b/examples/simple_secure_chat/main.cpp @@ -15,6 +15,7 @@ #include #include #include +#include /* ---------------------------------- CONFIGURATION ------------------------------------- */ @@ -552,7 +553,7 @@ SimpleMeshTables tables; MyMesh the_mesh(radio_driver, fast_rng, rtc_clock, tables); void halt() { - while (1) ; + haltWithRadioFailure(); } void setup() { diff --git a/examples/simple_sensor/main.cpp b/examples/simple_sensor/main.cpp index 69182f3a7a..3abb2954ab 100644 --- a/examples/simple_sensor/main.cpp +++ b/examples/simple_sensor/main.cpp @@ -1,4 +1,5 @@ #include "SensorMesh.h" +#include #ifdef DISPLAY_CLASS #include "UITask.h" @@ -47,7 +48,7 @@ SimpleMeshTables tables; MyMesh the_mesh(board, radio_driver, *new ArduinoMillis(), fast_rng, rtc_clock, tables); void halt() { - while (1) ; + haltWithRadioFailure(); } static char command[160]; @@ -63,14 +64,20 @@ void setup() { #endif #ifdef DISPLAY_CLASS - if (display.begin()) { - display.startFrame(); - display.print("Please wait..."); - display.endFrame(); + DisplayDriver* disp = display.begin() ? &display : NULL; + if (disp != NULL) { + disp->startFrame(); + disp->print("Please wait..."); + disp->endFrame(); } #endif - if (!radio_init()) { halt(); } + if (!radio_init()) { + #ifdef DISPLAY_CLASS + showRadioErrorOnDisplay(disp); + #endif + halt(); + } fast_rng.begin(radio_driver.getRngSeed()); diff --git a/src/helpers/RadioFailIndicator.h b/src/helpers/RadioFailIndicator.h new file mode 100644 index 0000000000..e17bb079bf --- /dev/null +++ b/src/helpers/RadioFailIndicator.h @@ -0,0 +1,53 @@ +#pragma once + +#include + +#ifdef DISPLAY_CLASS +#include + +static inline void showRadioErrorOnDisplay(DisplayDriver* disp) { + if (disp == NULL) return; + disp->startFrame(); +#ifdef ST7789 + disp->setTextSize(2); +#endif + disp->drawTextCentered(disp->width() / 2, 28, "Radio Error"); + disp->endFrame(); +} +#endif + +#if defined(LED_PIN) && (LED_PIN >= 0) && (LED_PIN != 0xFF) + #define _RADIO_FAIL_LED_PIN LED_PIN +#elif defined(LED_BUILTIN) && (LED_BUILTIN >= 0) && (LED_BUILTIN != 0xFF) + #define _RADIO_FAIL_LED_PIN LED_BUILTIN +#endif + +static inline void haltWithRadioFailure() { +#if defined(_RADIO_FAIL_LED_PIN) && defined(LED_STATE_ON) + pinMode(_RADIO_FAIL_LED_PIN, OUTPUT); + const uint16_t UNIT_MS = 300; + const uint16_t DASH_MS = UNIT_MS * 3; + const uint16_t LETTER_PAUSE_MS = UNIT_MS * 2; + const uint16_t WORD_PAUSE_MS = UNIT_MS * 4; + + while (true) { + for (uint8_t letter = 0; letter < 3; letter++) { + uint16_t onMs = (letter == 1) ? DASH_MS : UNIT_MS; + for (uint8_t symbol = 0; symbol < 3; symbol++) { + digitalWrite(_RADIO_FAIL_LED_PIN, LED_STATE_ON); + delay(onMs); + digitalWrite(_RADIO_FAIL_LED_PIN, !LED_STATE_ON); + delay(UNIT_MS); + } + delay(LETTER_PAUSE_MS); + } + delay(WORD_PAUSE_MS); + } +#else + while (1) ; +#endif +} + +#ifdef _RADIO_FAIL_LED_PIN +#undef _RADIO_FAIL_LED_PIN +#endif