From 019a82912169e27cd6e1dcd1775bd6a79c1171f7 Mon Sep 17 00:00:00 2001 From: Florent Date: Sat, 5 Apr 2025 17:28:25 +0200 Subject: [PATCH 01/27] add companion radio usb to t114 --- variants/t114/platformio.ini | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/variants/t114/platformio.ini b/variants/t114/platformio.ini index 297517d4..61a722d0 100644 --- a/variants/t114/platformio.ini +++ b/variants/t114/platformio.ini @@ -74,3 +74,22 @@ build_src_filter = ${Heltec_t114.build_src_filter} lib_deps = ${Heltec_t114.lib_deps} densaugeo/base64 @ ~1.4.0 + +[env:Heltec_t114_companion_radio_usb] +extends = Heltec_t114 +build_flags = + ${Heltec_t114.build_flags} + -D MAX_CONTACTS=100 + -D MAX_GROUP_CHANNELS=8 +; -D BLE_PIN_CODE=123456 +; -D BLE_DEBUG_LOGGING=1 +; -D ENABLE_PRIVATE_KEY_IMPORT=1 +; -D ENABLE_PRIVATE_KEY_EXPORT=1 +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = ${Heltec_t114.build_src_filter} + + + +<../examples/companion_radio/main.cpp> +lib_deps = + ${Heltec_t114.lib_deps} + densaugeo/base64 @ ~1.4.0 \ No newline at end of file From 396a7a24b1335bfd41dddbb3b203580eaf8134f4 Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Mon, 7 Apr 2025 21:55:24 +1000 Subject: [PATCH 02/27] * default SF now 11 --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 53ef30c4..1652f1e3 100644 --- a/platformio.ini +++ b/platformio.ini @@ -25,7 +25,7 @@ lib_deps = build_flags = -w -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1 -D LORA_FREQ=869.525 -D LORA_BW=250 - -D LORA_SF=10 + -D LORA_SF=11 build_src_filter = +<*.cpp> + From d7e6a361b580818d8adb0e7eaf3f8445d42dddcc Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Mon, 7 Apr 2025 21:59:53 +1000 Subject: [PATCH 03/27] * ver bump to v1.4.3 --- examples/companion_radio/main.cpp | 4 ++-- examples/simple_repeater/main.cpp | 4 ++-- examples/simple_room_server/main.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 2a6af5b7..e2640543 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -86,11 +86,11 @@ static uint32_t _atoi(const char* sp) { #define FIRMWARE_VER_CODE 3 #ifndef FIRMWARE_BUILD_DATE - #define FIRMWARE_BUILD_DATE "30 Mar 2025" + #define FIRMWARE_BUILD_DATE "7 Apr 2025" #endif #ifndef FIRMWARE_VERSION - #define FIRMWARE_VERSION "v1.4.2" + #define FIRMWARE_VERSION "v1.4.3" #endif #define CMD_APP_START 1 diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index 1c76264e..79194e96 100644 --- a/examples/simple_repeater/main.cpp +++ b/examples/simple_repeater/main.cpp @@ -20,11 +20,11 @@ /* ------------------------------ Config -------------------------------- */ #ifndef FIRMWARE_BUILD_DATE - #define FIRMWARE_BUILD_DATE "30 Mar 2025" + #define FIRMWARE_BUILD_DATE "7 Apr 2025" #endif #ifndef FIRMWARE_VERSION - #define FIRMWARE_VERSION "v1.4.2" + #define FIRMWARE_VERSION "v1.4.3" #endif #ifndef LORA_FREQ diff --git a/examples/simple_room_server/main.cpp b/examples/simple_room_server/main.cpp index daf8b497..405c8f7f 100644 --- a/examples/simple_room_server/main.cpp +++ b/examples/simple_room_server/main.cpp @@ -20,11 +20,11 @@ /* ------------------------------ Config -------------------------------- */ #ifndef FIRMWARE_BUILD_DATE - #define FIRMWARE_BUILD_DATE "30 Mar 2025" + #define FIRMWARE_BUILD_DATE "7 Apr 2025" #endif #ifndef FIRMWARE_VERSION - #define FIRMWARE_VERSION "v1.4.2" + #define FIRMWARE_VERSION "v1.4.3" #endif #ifndef LORA_FREQ From a0d9449e21fda7c78f0a822feee5aa769de6bb9b Mon Sep 17 00:00:00 2001 From: taco Date: Tue, 8 Apr 2025 11:04:20 +1000 Subject: [PATCH 04/27] set TBeam MAX_GROUP_CHANNELS=8 --- variants/lilygo_tbeam/platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variants/lilygo_tbeam/platformio.ini b/variants/lilygo_tbeam/platformio.ini index 007d06d2..01ab38e7 100644 --- a/variants/lilygo_tbeam/platformio.ini +++ b/variants/lilygo_tbeam/platformio.ini @@ -27,7 +27,7 @@ build_flags = ${LilyGo_TBeam.build_flags} -D DISPLAY_CLASS=SSD1306Display -D MAX_CONTACTS=100 - -D MAX_GROUP_CHANNELS=1 + -D MAX_GROUP_CHANNELS=8 -D BLE_PIN_CODE=123456 -D BLE_DEBUG_LOGGING=1 -D MESH_PACKET_LOGGING=1 From 28aa94b899ba88de8fccaaf2348d58f04dcd7064 Mon Sep 17 00:00:00 2001 From: liamcottle Date: Tue, 8 Apr 2025 22:58:17 +1200 Subject: [PATCH 05/27] show firmware version and build date on companion screen --- examples/companion_radio/UITask.cpp | 19 +++++++++++++++---- examples/companion_radio/UITask.h | 4 +++- examples/companion_radio/main.cpp | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/examples/companion_radio/UITask.cpp b/examples/companion_radio/UITask.cpp index c42bb094..cfe08cf7 100644 --- a/examples/companion_radio/UITask.cpp +++ b/examples/companion_radio/UITask.cpp @@ -25,16 +25,28 @@ static const uint8_t meshcore_logo [] PROGMEM = { 0xe3, 0xe3, 0x8f, 0xff, 0x1f, 0xfc, 0x3c, 0x0e, 0x1f, 0xf8, 0xff, 0xf8, 0x70, 0x3c, 0x7f, 0xf8, }; -void UITask::begin(DisplayDriver* display, const char* node_name, const char* build_date, uint32_t pin_code) { +void UITask::begin(DisplayDriver* display, const char* node_name, const char* build_date, const char* firmware_version, uint32_t pin_code) { _display = display; _auto_off = millis() + AUTO_OFF_MILLIS; clearMsgPreview(); _node_name = node_name; _build_date = build_date; + _firmware_version = firmware_version; _pin_code = pin_code; if (_display != NULL) { _display->turnOn(); } + + // strip off dash and commit hash by changing dash to null terminator + // e.g: v1.2.3-abcdef -> v1.2.3 + char *version = strdup(_firmware_version); + char *dash = strchr(version, '-'); + if(dash){ + *dash = 0; + } + + // v1.2.3 (1 Jan 2025) + sprintf(_version_info, "%s (%s)", version, _build_date); } void UITask::msgRead(int msgcount) { @@ -90,10 +102,9 @@ void UITask::renderCurrScreen() { _display->setCursor(0, 20); _display->setTextSize(1); _display->print(_node_name); - - sprintf(tmp, "Build: %s", _build_date); + _display->setCursor(0, 32); - _display->print(tmp); + _display->print(_version_info); if (_connected) { //_display->printf("freq : %03.2f sf %d\n", _prefs.freq, _prefs.sf); diff --git a/examples/companion_radio/UITask.h b/examples/companion_radio/UITask.h index a0c60186..8fe0145e 100644 --- a/examples/companion_radio/UITask.h +++ b/examples/companion_radio/UITask.h @@ -12,6 +12,8 @@ class UITask { uint32_t _pin_code; const char* _node_name; const char* _build_date; + const char* _firmware_version; + char _version_info[32]; char _origin[62]; char _msg[80]; int _msgcount; @@ -26,7 +28,7 @@ public: _next_refresh = 0; _connected = false; } - void begin(DisplayDriver* display, const char* node_name, const char* build_date, uint32_t pin_code); + void begin(DisplayDriver* display, const char* node_name, const char* build_date, const char* firmware_version, uint32_t pin_code); void setHasConnection(bool connected) { _connected = connected; } bool hasDisplay() const { return _display != NULL; } diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index e2640543..30e492ce 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -1505,7 +1505,7 @@ void setup() { #endif #ifdef HAS_UI - ui_task.begin(disp, the_mesh.getNodeName(), FIRMWARE_BUILD_DATE, the_mesh.getBLEPin()); + ui_task.begin(disp, the_mesh.getNodeName(), FIRMWARE_BUILD_DATE, FIRMWARE_VERSION, the_mesh.getBLEPin()); #endif } From 4a51cb98c6c1b0405c8f6f929736f5f9466da903 Mon Sep 17 00:00:00 2001 From: liamcottle Date: Tue, 8 Apr 2025 23:05:27 +1200 Subject: [PATCH 06/27] show firmware version and build date on repeater screen --- examples/simple_repeater/UITask.cpp | 17 +++++++++++++---- examples/simple_repeater/UITask.h | 3 ++- examples/simple_repeater/main.cpp | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/examples/simple_repeater/UITask.cpp b/examples/simple_repeater/UITask.cpp index e8a204e3..4597a344 100644 --- a/examples/simple_repeater/UITask.cpp +++ b/examples/simple_repeater/UITask.cpp @@ -20,25 +20,34 @@ static const uint8_t meshcore_logo [] PROGMEM = { 0xe3, 0xe3, 0x8f, 0xff, 0x1f, 0xfc, 0x3c, 0x0e, 0x1f, 0xf8, 0xff, 0xf8, 0x70, 0x3c, 0x7f, 0xf8, }; -void UITask::begin(const char* node_name, const char* build_date) { +void UITask::begin(const char* node_name, const char* build_date, const char* firmware_version) { _prevBtnState = HIGH; _auto_off = millis() + AUTO_OFF_MILLIS; _node_name = node_name; _build_date = build_date; _display->turnOn(); + + // strip off dash and commit hash by changing dash to null terminator + // e.g: v1.2.3-abcdef -> v1.2.3 + char *version = strdup(firmware_version); + char *dash = strchr(version, '-'); + if(dash){ + *dash = 0; + } + + // v1.2.3 (1 Jan 2025) + sprintf(_version_info, "%s (%s)", version, _build_date); } void UITask::renderCurrScreen() { - char tmp[80]; // render 'home' screen _display->drawXbm(0, 0, meshcore_logo, 128, 13); _display->setCursor(0, 20); _display->setTextSize(1); _display->print(_node_name); - sprintf(tmp, "Build: %s", _build_date); _display->setCursor(0, 32); - _display->print(tmp); + _display->print(_version_info); _display->setCursor(0, 43); _display->print("< Repeater >"); //_display->printf("freq : %03.2f sf %d\n", _prefs.freq, _prefs.sf); diff --git a/examples/simple_repeater/UITask.h b/examples/simple_repeater/UITask.h index e58d6111..e087b86c 100644 --- a/examples/simple_repeater/UITask.h +++ b/examples/simple_repeater/UITask.h @@ -8,11 +8,12 @@ class UITask { int _prevBtnState; const char* _node_name; const char* _build_date; + char _version_info[32]; void renderCurrScreen(); public: UITask(DisplayDriver& display) : _display(&display) { _next_read = _next_refresh = 0; } - void begin(const char* node_name, const char* build_date); + void begin(const char* node_name, const char* build_date, const char* firmware_version); void loop(); }; \ No newline at end of file diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index 79194e96..1d8cac6e 100644 --- a/examples/simple_repeater/main.cpp +++ b/examples/simple_repeater/main.cpp @@ -658,7 +658,7 @@ void setup() { the_mesh.begin(fs); #ifdef DISPLAY_CLASS - ui_task.begin(the_mesh.getNodeName(), FIRMWARE_BUILD_DATE); + ui_task.begin(the_mesh.getNodeName(), FIRMWARE_BUILD_DATE, FIRMWARE_VERSION); #endif // send out initial Advertisement to the mesh From bc820ae93e375f9cf57da65463e0d0425b2f20a2 Mon Sep 17 00:00:00 2001 From: liamcottle Date: Tue, 8 Apr 2025 23:09:55 +1200 Subject: [PATCH 07/27] show firmware version and build date on room server screen --- examples/simple_room_server/UITask.cpp | 17 +++++++++++++---- examples/simple_room_server/UITask.h | 3 ++- examples/simple_room_server/main.cpp | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/examples/simple_room_server/UITask.cpp b/examples/simple_room_server/UITask.cpp index 2f1d8ae5..eb2e4a00 100644 --- a/examples/simple_room_server/UITask.cpp +++ b/examples/simple_room_server/UITask.cpp @@ -20,25 +20,34 @@ static const uint8_t meshcore_logo [] PROGMEM = { 0xe3, 0xe3, 0x8f, 0xff, 0x1f, 0xfc, 0x3c, 0x0e, 0x1f, 0xf8, 0xff, 0xf8, 0x70, 0x3c, 0x7f, 0xf8, }; -void UITask::begin(const char* node_name, const char* build_date) { +void UITask::begin(const char* node_name, const char* build_date, const char* firmware_version) { _prevBtnState = HIGH; _auto_off = millis() + AUTO_OFF_MILLIS; _node_name = node_name; _build_date = build_date; _display->turnOn(); + + // strip off dash and commit hash by changing dash to null terminator + // e.g: v1.2.3-abcdef -> v1.2.3 + char *version = strdup(firmware_version); + char *dash = strchr(version, '-'); + if(dash){ + *dash = 0; + } + + // v1.2.3 (1 Jan 2025) + sprintf(_version_info, "%s (%s)", version, _build_date); } void UITask::renderCurrScreen() { - char tmp[80]; // render 'home' screen _display->drawXbm(0, 0, meshcore_logo, 128, 13); _display->setCursor(0, 20); _display->setTextSize(1); _display->print(_node_name); - sprintf(tmp, "Build: %s", _build_date); _display->setCursor(0, 32); - _display->print(tmp); + _display->print(_version_info); _display->setCursor(0, 43); _display->print("< Room Server >"); //_display->printf("freq : %03.2f sf %d\n", _prefs.freq, _prefs.sf); diff --git a/examples/simple_room_server/UITask.h b/examples/simple_room_server/UITask.h index e58d6111..e087b86c 100644 --- a/examples/simple_room_server/UITask.h +++ b/examples/simple_room_server/UITask.h @@ -8,11 +8,12 @@ class UITask { int _prevBtnState; const char* _node_name; const char* _build_date; + char _version_info[32]; void renderCurrScreen(); public: UITask(DisplayDriver& display) : _display(&display) { _next_read = _next_refresh = 0; } - void begin(const char* node_name, const char* build_date); + void begin(const char* node_name, const char* build_date, const char* firmware_version); void loop(); }; \ No newline at end of file diff --git a/examples/simple_room_server/main.cpp b/examples/simple_room_server/main.cpp index 405c8f7f..235638f8 100644 --- a/examples/simple_room_server/main.cpp +++ b/examples/simple_room_server/main.cpp @@ -887,7 +887,7 @@ void setup() { the_mesh.begin(fs); #ifdef DISPLAY_CLASS - ui_task.begin(the_mesh.getNodeName(), FIRMWARE_BUILD_DATE); + ui_task.begin(the_mesh.getNodeName(), FIRMWARE_BUILD_DATE, FIRMWARE_VERSION); #endif // send out initial Advertisement to the mesh From c4d32eba7416954d6db8b372a3f59434e5fa27d8 Mon Sep 17 00:00:00 2001 From: liamcottle Date: Tue, 8 Apr 2025 23:17:22 +1200 Subject: [PATCH 08/27] remove unused variables --- examples/companion_radio/UITask.cpp | 6 ++---- examples/companion_radio/UITask.h | 2 -- examples/simple_repeater/UITask.cpp | 3 +-- examples/simple_repeater/UITask.h | 1 - examples/simple_room_server/UITask.cpp | 3 +-- examples/simple_room_server/UITask.h | 1 - 6 files changed, 4 insertions(+), 12 deletions(-) diff --git a/examples/companion_radio/UITask.cpp b/examples/companion_radio/UITask.cpp index cfe08cf7..2d2e95a6 100644 --- a/examples/companion_radio/UITask.cpp +++ b/examples/companion_radio/UITask.cpp @@ -30,8 +30,6 @@ void UITask::begin(DisplayDriver* display, const char* node_name, const char* bu _auto_off = millis() + AUTO_OFF_MILLIS; clearMsgPreview(); _node_name = node_name; - _build_date = build_date; - _firmware_version = firmware_version; _pin_code = pin_code; if (_display != NULL) { _display->turnOn(); @@ -39,14 +37,14 @@ void UITask::begin(DisplayDriver* display, const char* node_name, const char* bu // strip off dash and commit hash by changing dash to null terminator // e.g: v1.2.3-abcdef -> v1.2.3 - char *version = strdup(_firmware_version); + char *version = strdup(firmware_version); char *dash = strchr(version, '-'); if(dash){ *dash = 0; } // v1.2.3 (1 Jan 2025) - sprintf(_version_info, "%s (%s)", version, _build_date); + sprintf(_version_info, "%s (%s)", version, build_date); } void UITask::msgRead(int msgcount) { diff --git a/examples/companion_radio/UITask.h b/examples/companion_radio/UITask.h index 8fe0145e..4cba1fca 100644 --- a/examples/companion_radio/UITask.h +++ b/examples/companion_radio/UITask.h @@ -11,8 +11,6 @@ class UITask { bool _connected; uint32_t _pin_code; const char* _node_name; - const char* _build_date; - const char* _firmware_version; char _version_info[32]; char _origin[62]; char _msg[80]; diff --git a/examples/simple_repeater/UITask.cpp b/examples/simple_repeater/UITask.cpp index 4597a344..6fff675e 100644 --- a/examples/simple_repeater/UITask.cpp +++ b/examples/simple_repeater/UITask.cpp @@ -24,7 +24,6 @@ void UITask::begin(const char* node_name, const char* build_date, const char* fi _prevBtnState = HIGH; _auto_off = millis() + AUTO_OFF_MILLIS; _node_name = node_name; - _build_date = build_date; _display->turnOn(); // strip off dash and commit hash by changing dash to null terminator @@ -36,7 +35,7 @@ void UITask::begin(const char* node_name, const char* build_date, const char* fi } // v1.2.3 (1 Jan 2025) - sprintf(_version_info, "%s (%s)", version, _build_date); + sprintf(_version_info, "%s (%s)", version, build_date); } void UITask::renderCurrScreen() { diff --git a/examples/simple_repeater/UITask.h b/examples/simple_repeater/UITask.h index e087b86c..13005957 100644 --- a/examples/simple_repeater/UITask.h +++ b/examples/simple_repeater/UITask.h @@ -7,7 +7,6 @@ class UITask { unsigned long _next_read, _next_refresh, _auto_off; int _prevBtnState; const char* _node_name; - const char* _build_date; char _version_info[32]; void renderCurrScreen(); diff --git a/examples/simple_room_server/UITask.cpp b/examples/simple_room_server/UITask.cpp index eb2e4a00..eb7be78e 100644 --- a/examples/simple_room_server/UITask.cpp +++ b/examples/simple_room_server/UITask.cpp @@ -24,7 +24,6 @@ void UITask::begin(const char* node_name, const char* build_date, const char* fi _prevBtnState = HIGH; _auto_off = millis() + AUTO_OFF_MILLIS; _node_name = node_name; - _build_date = build_date; _display->turnOn(); // strip off dash and commit hash by changing dash to null terminator @@ -36,7 +35,7 @@ void UITask::begin(const char* node_name, const char* build_date, const char* fi } // v1.2.3 (1 Jan 2025) - sprintf(_version_info, "%s (%s)", version, _build_date); + sprintf(_version_info, "%s (%s)", version, build_date); } void UITask::renderCurrScreen() { diff --git a/examples/simple_room_server/UITask.h b/examples/simple_room_server/UITask.h index e087b86c..13005957 100644 --- a/examples/simple_room_server/UITask.h +++ b/examples/simple_room_server/UITask.h @@ -7,7 +7,6 @@ class UITask { unsigned long _next_read, _next_refresh, _auto_off; int _prevBtnState; const char* _node_name; - const char* _build_date; char _version_info[32]; void renderCurrScreen(); From 329c76629db02d3267f07ea8667334cc7ea05bef Mon Sep 17 00:00:00 2001 From: Adrian <76220205+adrian-immel@users.noreply.github.com> Date: Tue, 8 Apr 2025 16:08:04 +0200 Subject: [PATCH 09/27] Fix Floating Pin on Promicro change INPUT to INPUT_PULLUP --- src/helpers/nrf52/PromicroBoard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/nrf52/PromicroBoard.cpp b/src/helpers/nrf52/PromicroBoard.cpp index 58710509..b923e16e 100644 --- a/src/helpers/nrf52/PromicroBoard.cpp +++ b/src/helpers/nrf52/PromicroBoard.cpp @@ -14,7 +14,7 @@ void PromicroBoard::begin() { pinMode(PIN_VBAT_READ, INPUT); #ifdef BUTTON_PIN - pinMode(BUTTON_PIN, INPUT); + pinMode(BUTTON_PIN, INPUT_PULLUP); #endif #if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL) From 9b3e7e5a21b510e0792c3065fb6b0b8cc7e383db Mon Sep 17 00:00:00 2001 From: taco Date: Wed, 9 Apr 2025 18:07:01 +1000 Subject: [PATCH 10/27] FIX: define OLED pins for RAK --- variants/rak4631/platformio.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/variants/rak4631/platformio.ini b/variants/rak4631/platformio.ini index 63d6b6b8..49955722 100644 --- a/variants/rak4631/platformio.ini +++ b/variants/rak4631/platformio.ini @@ -7,6 +7,9 @@ build_flags = ${nrf52840_base.build_flags} -I variants/rak4631 -D RAK_4631 -D PIN_USER_BTN=9 + -D PIN_BOARD_SCL=14 + -D PIN_BOARD_SDA=13 + -D PIN_OLED_RESET=-1 -D RADIO_CLASS=CustomSX1262 -D WRAPPER_CLASS=CustomSX1262Wrapper -D LORA_TX_POWER=22 From 5c2c248f70c8043526cffb918c79035a1be62af5 Mon Sep 17 00:00:00 2001 From: taco Date: Wed, 9 Apr 2025 18:19:13 +1000 Subject: [PATCH 11/27] build: fix RAK, T114, T1000e builds --- src/helpers/nrf52/RAK4631Board.cpp | 2 +- src/helpers/nrf52/T1000eBoard.cpp | 2 +- src/helpers/nrf52/T114Board.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/helpers/nrf52/RAK4631Board.cpp b/src/helpers/nrf52/RAK4631Board.cpp index 4d2f0edf..8b368734 100644 --- a/src/helpers/nrf52/RAK4631Board.cpp +++ b/src/helpers/nrf52/RAK4631Board.cpp @@ -27,7 +27,7 @@ void RAK4631Board::begin() { #endif #if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL) - Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL) + Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL); #endif Wire.begin(); diff --git a/src/helpers/nrf52/T1000eBoard.cpp b/src/helpers/nrf52/T1000eBoard.cpp index c6fc27a9..a17711db 100644 --- a/src/helpers/nrf52/T1000eBoard.cpp +++ b/src/helpers/nrf52/T1000eBoard.cpp @@ -18,7 +18,7 @@ void T1000eBoard::begin() { #endif #if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL) - Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL) + Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL); #endif Wire.begin(); diff --git a/src/helpers/nrf52/T114Board.cpp b/src/helpers/nrf52/T114Board.cpp index d39b3e71..1f8c5854 100644 --- a/src/helpers/nrf52/T114Board.cpp +++ b/src/helpers/nrf52/T114Board.cpp @@ -27,7 +27,7 @@ void T114Board::begin() { pinMode(PIN_VBAT_READ, INPUT); #if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL) - Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL) + Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL); #endif Wire.begin(); From be64fa7ca022cc23ad1b8af30d787ebab3e10fd8 Mon Sep 17 00:00:00 2001 From: taco Date: Wed, 9 Apr 2025 18:22:01 +1000 Subject: [PATCH 12/27] build: fix RAK, T114, T1000 builds --- src/helpers/nrf52/RAK4631Board.cpp | 2 +- src/helpers/nrf52/T1000eBoard.cpp | 2 +- src/helpers/nrf52/T114Board.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/helpers/nrf52/RAK4631Board.cpp b/src/helpers/nrf52/RAK4631Board.cpp index 4d2f0edf..8b368734 100644 --- a/src/helpers/nrf52/RAK4631Board.cpp +++ b/src/helpers/nrf52/RAK4631Board.cpp @@ -27,7 +27,7 @@ void RAK4631Board::begin() { #endif #if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL) - Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL) + Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL); #endif Wire.begin(); diff --git a/src/helpers/nrf52/T1000eBoard.cpp b/src/helpers/nrf52/T1000eBoard.cpp index c6fc27a9..a17711db 100644 --- a/src/helpers/nrf52/T1000eBoard.cpp +++ b/src/helpers/nrf52/T1000eBoard.cpp @@ -18,7 +18,7 @@ void T1000eBoard::begin() { #endif #if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL) - Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL) + Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL); #endif Wire.begin(); diff --git a/src/helpers/nrf52/T114Board.cpp b/src/helpers/nrf52/T114Board.cpp index d39b3e71..1f8c5854 100644 --- a/src/helpers/nrf52/T114Board.cpp +++ b/src/helpers/nrf52/T114Board.cpp @@ -27,7 +27,7 @@ void T114Board::begin() { pinMode(PIN_VBAT_READ, INPUT); #if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL) - Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL) + Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL); #endif Wire.begin(); From 1718657829c332198cbff56428f8195dcbec8581 Mon Sep 17 00:00:00 2001 From: recrof Date: Wed, 9 Apr 2025 13:07:58 +0200 Subject: [PATCH 13/27] lilygo t-echo: move init stuff to variant.cpp, disable gps to conserve battery --- src/helpers/nrf52/TechoBoard.cpp | 13 ------------- variants/techo/variant.cpp | 22 +++++++++++++++------- variants/techo/variant.h | 23 ++++++++++++++++++++++- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/src/helpers/nrf52/TechoBoard.cpp b/src/helpers/nrf52/TechoBoard.cpp index 13a250e6..dee14688 100644 --- a/src/helpers/nrf52/TechoBoard.cpp +++ b/src/helpers/nrf52/TechoBoard.cpp @@ -24,19 +24,6 @@ void TechoBoard::begin() { // for future use, sub-classes SHOULD call this from their begin() startup_reason = BD_STARTUP_NORMAL; - delay(200); - pinMode(PIN_PWR_EN, OUTPUT); - digitalWrite(PIN_PWR_EN, HIGH); - pinMode(PIN_BUTTON1, INPUT_PULLUP); - pinMode(PIN_BUTTON2, INPUT_PULLUP); - pinMode(LED_RED, OUTPUT); - pinMode(LED_GREEN, OUTPUT); - pinMode(LED_BLUE, OUTPUT); - delay(200); - - pinMode(PIN_TXCO, OUTPUT); - digitalWrite(PIN_TXCO, HIGH); - Wire.begin(); pinMode(SX126X_POWER_EN, OUTPUT); diff --git a/variants/techo/variant.cpp b/variants/techo/variant.cpp index 3d3dc9c1..7b7bee95 100644 --- a/variants/techo/variant.cpp +++ b/variants/techo/variant.cpp @@ -9,14 +9,22 @@ const uint32_t g_ADigitalPinMap[] = { 40, 41, 42, 43, 44, 45, 46, 47 }; -void initVariant() -{ +void initVariant() { + pinMode(PIN_PWR_EN, OUTPUT); + digitalWrite(PIN_PWR_EN, HIGH); + + pinMode(PIN_BUTTON1, INPUT_PULLUP); + pinMode(PIN_BUTTON2, INPUT_PULLUP); + pinMode(LED_RED, OUTPUT); - ledOff(LED_RED); - pinMode(LED_GREEN, OUTPUT); - ledOff(LED_GREEN); - pinMode(LED_BLUE, OUTPUT); - ledOff(LED_BLUE); + digitalWrite(LED_BLUE, HIGH); + + pinMode(PIN_TXCO, OUTPUT); + digitalWrite(PIN_TXCO, HIGH); + + // shutdown gps + pinMode(PIN_GPS_STANDBY, OUTPUT); + digitalWrite(PIN_GPS_STANDBY, LOW); } diff --git a/variants/techo/variant.h b/variants/techo/variant.h index 8fcb765e..e3022adc 100644 --- a/variants/techo/variant.h +++ b/variants/techo/variant.h @@ -42,7 +42,7 @@ #define PIN_SERIAL1_RX (41) // GPS TX #define PIN_SERIAL1_TX (40) // GPS RX - +#define PIN_GPS_STANDBY (34) //////////////////////////////////////////////////////////////////////////////// // I2C pin definition @@ -100,3 +100,24 @@ #define PIN_SPI1_MISO (39) #define PIN_SPI1_MOSI (29) #define PIN_SPI1_SCK (31) + +//////////////////////////////////////////////////////////////////////////////// +// Display + +#define DISP_MISO (38) +#define DISP_MOSI (29) +#define DISP_SCLK (31) +#define DISP_CS (30) +#define DISP_DC (28) +#define DISP_RST (2) +#define DISP_BUSY (3) +#define DISP_BACKLIGHT (43) + +//////////////////////////////////////////////////////////////////////////////// +// GPS + +#define PIN_GPS_RX (41) +#define PIN_GPS_TX (40) +#define PIN_GPS_WAKEUP (34) +#define PIN_GPS_RESET (37) +#define PIN_GPS_PPS (36) From 511a935bbf9f03dc7374cf3f48d3666a1c40a211 Mon Sep 17 00:00:00 2001 From: recrof Date: Wed, 9 Apr 2025 13:21:34 +0200 Subject: [PATCH 14/27] move gps standby pin to gps section --- variants/techo/variant.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variants/techo/variant.h b/variants/techo/variant.h index e3022adc..9f4da8e7 100644 --- a/variants/techo/variant.h +++ b/variants/techo/variant.h @@ -42,7 +42,6 @@ #define PIN_SERIAL1_RX (41) // GPS TX #define PIN_SERIAL1_TX (40) // GPS RX -#define PIN_GPS_STANDBY (34) //////////////////////////////////////////////////////////////////////////////// // I2C pin definition @@ -121,3 +120,4 @@ #define PIN_GPS_WAKEUP (34) #define PIN_GPS_RESET (37) #define PIN_GPS_PPS (36) +#define PIN_GPS_STANDBY (34) From a3c859774726296447c03374a113d312166d6ba7 Mon Sep 17 00:00:00 2001 From: recrof Date: Wed, 9 Apr 2025 14:08:13 +0200 Subject: [PATCH 15/27] LilyGo T-Beam: added battery voltage reporting --- src/helpers/TBeamBoard.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/helpers/TBeamBoard.h b/src/helpers/TBeamBoard.h index 6c6367fa..fc52e712 100644 --- a/src/helpers/TBeamBoard.h +++ b/src/helpers/TBeamBoard.h @@ -33,11 +33,11 @@ class TBeamBoard : public ESP32Board { public: void begin() { ESP32Board::begin(); - + power.setALDO2Voltage(3300); power.enableALDO2(); - pinMode(38,INPUT_PULLUP); + pinMode(38, INPUT_PULLUP); esp_reset_reason_t reason = esp_reset_reason(); if (reason == ESP_RST_DEEPSLEEP) { @@ -75,7 +75,7 @@ public: } uint16_t getBattMilliVolts() override { - return 0; + return power.getBattVoltage(); } const char* getManufacturerName() const override { From 3c7ff8da2984c60485f32a446012c3ea6643866f Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Fri, 11 Apr 2025 04:56:13 +1000 Subject: [PATCH 16/27] * Packet::header, new: ROUTE_TYPE_TRANS_FLOOD, ROUTE_TYPE_TRANS_DIRECT * Packet wire format change: (optional) extra 4 bytes for two trans_codes --- src/Dispatcher.cpp | 10 ++++++++++ src/Packet.cpp | 10 ++++++++++ src/Packet.h | 11 +++++++---- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/Dispatcher.cpp b/src/Dispatcher.cpp index ae225d36..953ede67 100644 --- a/src/Dispatcher.cpp +++ b/src/Dispatcher.cpp @@ -101,6 +101,12 @@ void Dispatcher::checkRecv() { #endif pkt->header = raw[i++]; + if (pkt->hasTransCodes()) { + memcpy(&pkt->trans_codes[0], &raw[i], 2); i += 2; + memcpy(&pkt->trans_codes[1], &raw[i], 2); i += 2; + } else { + pkt->trans_codes[0] = pkt->trans_codes[1] = 0; + } pkt->path_len = raw[i++]; if (pkt->path_len > MAX_PATH_SIZE || i + pkt->path_len > len) { @@ -212,6 +218,10 @@ void Dispatcher::checkSend() { raw[len++] = NODE_ID; #endif raw[len++] = outbound->header; + if (outbound->hasTransCodes()) { + memcpy(&raw[len], &outbound->trans_codes[0], 2); len += 2; + memcpy(&raw[len], &outbound->trans_codes[1], 2); len += 2; + } raw[len++] = outbound->path_len; memcpy(&raw[len], outbound->path, outbound->path_len); len += outbound->path_len; diff --git a/src/Packet.cpp b/src/Packet.cpp index e338b60d..48f7699e 100644 --- a/src/Packet.cpp +++ b/src/Packet.cpp @@ -24,6 +24,10 @@ void Packet::calculatePacketHash(uint8_t* hash) const { uint8_t Packet::writeTo(uint8_t dest[]) const { uint8_t i = 0; dest[i++] = header; + if (hasTransCodes()) { + memcpy(&dest[i], &trans_codes[0], 2); i += 2; + memcpy(&dest[i], &trans_codes[1], 2); i += 2; + } dest[i++] = path_len; memcpy(&dest[i], path, path_len); i += path_len; memcpy(&dest[i], payload, payload_len); i += payload_len; @@ -33,6 +37,12 @@ uint8_t Packet::writeTo(uint8_t dest[]) const { bool Packet::readFrom(const uint8_t src[], uint8_t len) { uint8_t i = 0; header = src[i++]; + if (hasTransCodes()) { + memcpy(&trans_codes[0], &src[i], 2); i += 2; + memcpy(&trans_codes[1], &src[i], 2); i += 2; + } else { + trans_codes[0] = trans_codes[1] = 0; + } path_len = src[i++]; if (path_len > sizeof(path)) return false; // bad encoding memcpy(path, &src[i], path_len); i += path_len; diff --git a/src/Packet.h b/src/Packet.h index e20b3a49..08e78899 100644 --- a/src/Packet.h +++ b/src/Packet.h @@ -11,10 +11,10 @@ namespace mesh { #define PH_VER_SHIFT 6 #define PH_VER_MASK 0x03 // 2-bits -#define ROUTE_TYPE_RESERVED1 0x00 // FUTURE +#define ROUTE_TYPE_TRANS_FLOOD 0x00 // flood mode + transport codes #define ROUTE_TYPE_FLOOD 0x01 // flood mode, needs 'path' to be built up (max 64 bytes) #define ROUTE_TYPE_DIRECT 0x02 // direct route, 'path' is supplied -#define ROUTE_TYPE_RESERVED2 0x03 // FUTURE +#define ROUTE_TYPE_TRANS_DIRECT 0x03 // direct route + transport codes #define PAYLOAD_TYPE_REQ 0x00 // request (prefixed with dest/src hashes, MAC) (enc data: timestamp, blob) #define PAYLOAD_TYPE_RESPONSE 0x01 // response to REQ or ANON_REQ (prefixed with dest/src hashes, MAC) (enc data: timestamp, blob) @@ -43,6 +43,7 @@ public: uint8_t header; uint16_t payload_len, path_len; + uint16_t trans_codes[2]; uint8_t path[MAX_PATH_SIZE]; uint8_t payload[MAX_PACKET_PAYLOAD]; int8_t _snr; @@ -58,8 +59,10 @@ public: */ uint8_t getRouteType() const { return header & PH_ROUTE_MASK; } - bool isRouteFlood() const { return getRouteType() == ROUTE_TYPE_FLOOD; } - bool isRouteDirect() const { return getRouteType() == ROUTE_TYPE_DIRECT; } + bool isRouteFlood() const { return getRouteType() == ROUTE_TYPE_FLOOD || getRouteType() == ROUTE_TYPE_TRANS_FLOOD; } + bool isRouteDirect() const { return getRouteType() == ROUTE_TYPE_DIRECT || getRouteType() == ROUTE_TYPE_TRANS_DIRECT; } + + bool hasTransCodes() const { return getRouteType() == ROUTE_TYPE_TRANS_FLOOD || getRouteType() == ROUTE_TYPE_TRANS_DIRECT; } /** * \returns one of PAYLOAD_TYPE_ values From 96d6ffefad9d9905bb3bc6b513dbdf56d775adc8 Mon Sep 17 00:00:00 2001 From: Florent Date: Thu, 10 Apr 2025 22:00:25 +0200 Subject: [PATCH 17/27] t1000 : power bat sensor only when necessary --- src/helpers/nrf52/T1000eBoard.h | 3 +++ variants/t1000-e/variant.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/helpers/nrf52/T1000eBoard.h b/src/helpers/nrf52/T1000eBoard.h index d71c829b..9511706b 100644 --- a/src/helpers/nrf52/T1000eBoard.h +++ b/src/helpers/nrf52/T1000eBoard.h @@ -29,9 +29,12 @@ public: uint16_t getBattMilliVolts() override { #ifdef BATTERY_PIN + digitalWrite(PIN_3V3_EN, HIGH); analogReference(AR_INTERNAL_3_0); analogReadResolution(12); + delay(10); float volts = (analogRead(BATTERY_PIN) * ADC_MULTIPLIER * AREF_VOLTAGE) / 4096; + digitalWrite(PIN_3V3_EN, LOW); analogReference(AR_DEFAULT); // put back to default analogReadResolution(10); diff --git a/variants/t1000-e/variant.cpp b/variants/t1000-e/variant.cpp index a71a831b..f17b3a8d 100644 --- a/variants/t1000-e/variant.cpp +++ b/variants/t1000-e/variant.cpp @@ -83,13 +83,13 @@ void initVariant() pinMode(GPS_RTC_INT, OUTPUT); pinMode(LED_PIN, OUTPUT); - digitalWrite(PIN_3V3_EN, HIGH); + digitalWrite(PIN_3V3_EN, LOW); digitalWrite(PIN_3V3_ACC_EN, LOW); digitalWrite(BUZZER_EN, LOW); digitalWrite(SENSOR_EN, LOW); digitalWrite(GPS_EN, LOW); digitalWrite(GPS_RESET, LOW); - digitalWrite(GPS_VRTC_EN, HIGH); + digitalWrite(GPS_VRTC_EN, LOW); digitalWrite(GPS_SLEEP_INT, HIGH); digitalWrite(GPS_RTC_INT, LOW); digitalWrite(LED_PIN, LOW); From 366461a3a11d771495625a973cb4297032441219 Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Fri, 11 Apr 2025 14:12:09 +1000 Subject: [PATCH 18/27] * companion: onRawDataRecv() guard for payload_len too long --- examples/companion_radio/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 30e492ce..48eafbf2 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -663,6 +663,10 @@ protected: } void onRawDataRecv(mesh::Packet* packet) override { + if (packet->payload_len + 4 > sizeof(out_frame)) { + MESH_DEBUG_PRINTLN("onRawDataRecv(), payload_len too long: %d", packet->payload_len); + return; + } int i = 0; out_frame[i++] = PUSH_CODE_RAW_DATA; out_frame[i++] = (int8_t)(_radio->getLastSNR() * 4); From ab8cd85d8ea4146e663d7591bfc55d439025c1ec Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Fri, 11 Apr 2025 15:12:04 +1000 Subject: [PATCH 19/27] * added Packet::getRawLength() helper --- src/Dispatcher.cpp | 4 ++-- src/Mesh.cpp | 2 +- src/Packet.cpp | 4 ++++ src/Packet.h | 5 +++++ src/helpers/BaseChatMesh.cpp | 8 ++++---- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Dispatcher.cpp b/src/Dispatcher.cpp index 953ede67..cd7090d1 100644 --- a/src/Dispatcher.cpp +++ b/src/Dispatcher.cpp @@ -138,7 +138,7 @@ void Dispatcher::checkRecv() { #if MESH_PACKET_LOGGING Serial.print(getLogDateTime()); Serial.printf(": RX, len=%d (type=%d, route=%s, payload_len=%d) SNR=%d RSSI=%d score=%d", - 2 + pkt->path_len + pkt->payload_len, pkt->getPayloadType(), pkt->isRouteDirect() ? "D" : "F", pkt->payload_len, + pkt->getRawLength(), pkt->getPayloadType(), pkt->isRouteDirect() ? "D" : "F", pkt->payload_len, (int)pkt->getSNR(), (int)_radio->getLastRSSI(), (int)(score*1000)); static uint8_t packet_hash[MAX_HASH_SIZE]; @@ -153,7 +153,7 @@ void Dispatcher::checkRecv() { Serial.printf("\n"); } #endif - logRx(pkt, 2 + pkt->path_len + pkt->payload_len, score); // hook for custom logging + logRx(pkt, pkt->getRawLength(), score); // hook for custom logging if (pkt->isRouteFlood()) { n_recv_flood++; diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 0a0fd769..fe3b2473 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -15,7 +15,7 @@ bool Mesh::allowPacketForward(const mesh::Packet* packet) { return false; // by default, Transport NOT enabled } uint32_t Mesh::getRetransmitDelay(const mesh::Packet* packet) { - uint32_t t = (_radio->getEstAirtimeFor(packet->path_len + packet->payload_len + 2) * 52 / 50) / 2; + uint32_t t = (_radio->getEstAirtimeFor(packet->getRawLength()) * 52 / 50) / 2; return _rng->nextInt(0, 5)*t; } diff --git a/src/Packet.cpp b/src/Packet.cpp index 48f7699e..386585fc 100644 --- a/src/Packet.cpp +++ b/src/Packet.cpp @@ -10,6 +10,10 @@ Packet::Packet() { payload_len = 0; } +int Packet::getRawLength() const { + return 2 + path_len + payload_len + (hasTransCodes() ? 4 : 0); +} + void Packet::calculatePacketHash(uint8_t* hash) const { SHA256 sha; uint8_t t = getPayloadType(); diff --git a/src/Packet.h b/src/Packet.h index 08e78899..dfd61da8 100644 --- a/src/Packet.h +++ b/src/Packet.h @@ -79,6 +79,11 @@ public: float getSNR() const { return ((float)_snr) / 4.0f; } + /** + * \returns the encoded/wire format length of this packet + */ + int getRawLength() const; + /** * \brief save entire packet as a blob * \param dest (OUT) destination buffer (assumed to be MAX_MTU_SIZE) diff --git a/src/helpers/BaseChatMesh.cpp b/src/helpers/BaseChatMesh.cpp index 083a0629..989fcb2c 100644 --- a/src/helpers/BaseChatMesh.cpp +++ b/src/helpers/BaseChatMesh.cpp @@ -252,7 +252,7 @@ int BaseChatMesh::sendMessage(const ContactInfo& recipient, uint32_t timestamp, mesh::Packet* pkt = composeMsgPacket(recipient, timestamp, attempt, text, expected_ack); if (pkt == NULL) return MSG_SEND_FAILED; - uint32_t t = _radio->getEstAirtimeFor(pkt->payload_len + pkt->path_len + 2); + uint32_t t = _radio->getEstAirtimeFor(pkt->getRawLength()); int rc; if (recipient.out_path_len < 0) { @@ -279,7 +279,7 @@ int BaseChatMesh::sendCommandData(const ContactInfo& recipient, uint32_t timest auto pkt = createDatagram(PAYLOAD_TYPE_TXT_MSG, recipient.id, recipient.shared_secret, temp, 5 + text_len); if (pkt == NULL) return MSG_SEND_FAILED; - uint32_t t = _radio->getEstAirtimeFor(pkt->payload_len + pkt->path_len + 2); + uint32_t t = _radio->getEstAirtimeFor(pkt->getRawLength()); int rc; if (recipient.out_path_len < 0) { sendFlood(pkt); @@ -362,7 +362,7 @@ int BaseChatMesh::sendLogin(const ContactInfo& recipient, const char* password, auto pkt = createAnonDatagram(PAYLOAD_TYPE_ANON_REQ, self_id, recipient.id, recipient.shared_secret, temp, tlen); if (pkt) { - uint32_t t = _radio->getEstAirtimeFor(pkt->payload_len + pkt->path_len + 2); + uint32_t t = _radio->getEstAirtimeFor(pkt->getRawLength()); if (recipient.out_path_len < 0) { sendFlood(pkt); est_timeout = calcFloodTimeoutMillisFor(t); @@ -386,7 +386,7 @@ int BaseChatMesh::sendStatusRequest(const ContactInfo& recipient, uint32_t& est auto pkt = createDatagram(PAYLOAD_TYPE_REQ, recipient.id, recipient.shared_secret, temp, sizeof(temp)); if (pkt) { - uint32_t t = _radio->getEstAirtimeFor(pkt->payload_len + pkt->path_len + 2); + uint32_t t = _radio->getEstAirtimeFor(pkt->getRawLength()); if (recipient.out_path_len < 0) { sendFlood(pkt); est_timeout = calcFloodTimeoutMillisFor(t); From 82bcd74932b1aec6c1f003752daea7d26b7055ae Mon Sep 17 00:00:00 2001 From: Florent de Lamotte Date: Mon, 7 Apr 2025 18:14:39 +0200 Subject: [PATCH 20/27] xiao-nrf52 : initial support for meshcore initial config for xiao_nrf52 repeater role for xiao-nrf52 xiao-nrf52 correction on bat voltage xiao-nrf52 this file should not be here ... --- boards/seeed-xiao-afruitnrf52-nrf52840.json | 61 ++++++++ src/helpers/nrf52/XiaoNrf52Board.cpp | 91 ++++++++++++ src/helpers/nrf52/XiaoNrf52Board.h | 75 ++++++++++ variants/xiao_nrf52/platformio.ini | 81 +++++++++++ variants/xiao_nrf52/target.cpp | 68 +++++++++ variants/xiao_nrf52/target.h | 18 +++ variants/xiao_nrf52/variant.cpp | 78 ++++++++++ variants/xiao_nrf52/variant.h | 149 ++++++++++++++++++++ 8 files changed, 621 insertions(+) create mode 100644 boards/seeed-xiao-afruitnrf52-nrf52840.json create mode 100644 src/helpers/nrf52/XiaoNrf52Board.cpp create mode 100644 src/helpers/nrf52/XiaoNrf52Board.h create mode 100644 variants/xiao_nrf52/platformio.ini create mode 100644 variants/xiao_nrf52/target.cpp create mode 100644 variants/xiao_nrf52/target.h create mode 100644 variants/xiao_nrf52/variant.cpp create mode 100644 variants/xiao_nrf52/variant.h diff --git a/boards/seeed-xiao-afruitnrf52-nrf52840.json b/boards/seeed-xiao-afruitnrf52-nrf52840.json new file mode 100644 index 00000000..78855cd7 --- /dev/null +++ b/boards/seeed-xiao-afruitnrf52-nrf52840.json @@ -0,0 +1,61 @@ +{ + "build": { + "arduino": { + "ldscript": "nrf52840_s140_v7.ld" + }, + "core": "nRF5", + "cpu": "cortex-m4", + "extra_flags": "-DARDUINO_Seeed_XIAO_nRF52840 -DNRF52840_XXAA -DSEEED_XIAO_NRF52840 ", + "f_cpu": "64000000L", + "hwids": [ + [ "0x2886", "0x8044" ], + [ "0x2886", "0x0044" ] + ], + "mcu": "nrf52840", + "variant": "Seeed_XIAO_nRF52840", + "softdevice": { + "sd_flags": "-DS140", + "sd_name": "s140", + "sd_version": "7.3.0", + "sd_fwid": "0x0123" + }, + "bsp": { + "name": "adafruit" + }, + "bootloader": { + "settings_addr": "0xFF000" + }, + "usb_product": "XIAO nRF52840" + }, + "connectivity": [ + "bluetooth" + ], + "debug": { + "jlink_device": "nRF52840_xxAA", + "openocd_target": "nrf52.cfg", + "svd_path": "nrf52840.svd" + }, + "frameworks": [ + "arduino" + ], + "name": "Seeed Studio XIAO nRF52840", + "upload": { + "maximum_ram_size": 237568, + "maximum_size": 811008, + "protocol": "nrfutil", + "speed": 115200, + "protocols": [ + "jlink", + "nrfjprog", + "nrfutil", + "cmsis-dap", + "sam-ba", + "blackmagic" + ], + "use_1200bps_touch": true, + "require_upload_port": true, + "wait_for_upload_port": true + }, + "url": "https://wiki.seeedstudio.com/XIAO_BLE", + "vendor": "Seeed Studio" +} diff --git a/src/helpers/nrf52/XiaoNrf52Board.cpp b/src/helpers/nrf52/XiaoNrf52Board.cpp new file mode 100644 index 00000000..cf9d150f --- /dev/null +++ b/src/helpers/nrf52/XiaoNrf52Board.cpp @@ -0,0 +1,91 @@ +#include +#include "XiaoNrf52Board.h" + +#include +#include + +static BLEDfu bledfu; + +static void connect_callback(uint16_t conn_handle) +{ + (void)conn_handle; + MESH_DEBUG_PRINTLN("BLE client connected"); +} + +static void disconnect_callback(uint16_t conn_handle, uint8_t reason) +{ + (void)conn_handle; + (void)reason; + + MESH_DEBUG_PRINTLN("BLE client disconnected"); +} + +void XiaoNrf52Board::begin() { + // for future use, sub-classes SHOULD call this from their begin() + startup_reason = BD_STARTUP_NORMAL; + + pinMode(PIN_VBAT, INPUT); + pinMode(VBAT_ENABLE, OUTPUT); + digitalWrite(VBAT_ENABLE, HIGH); + +#if defined(PIN_WIRE_SDA) && defined(PIN_WIRE_SCL) + Wire.setPins(PIN_WIRE_SDA, PIN_WIRE_SCL); +#endif + + Wire.begin(); + +#ifdef P_LORA_TX_LED + pinMode(P_LORA_TX_LED, OUTPUT); + digitalWrite(P_LORA_TX_LED, HIGH); +#endif + +// pinMode(SX126X_POWER_EN, OUTPUT); +// digitalWrite(SX126X_POWER_EN, HIGH); + delay(10); // give sx1262 some time to power up +} + +bool XiaoNrf52Board::startOTAUpdate(const char* id, char reply[]) { + // Config the peripheral connection with maximum bandwidth + // more SRAM required by SoftDevice + // Note: All config***() function must be called before begin() + Bluefruit.configPrphBandwidth(BANDWIDTH_MAX); + Bluefruit.configPrphConn(92, BLE_GAP_EVENT_LENGTH_MIN, 16, 16); + + Bluefruit.begin(1, 0); + // Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4 + Bluefruit.setTxPower(4); + // Set the BLE device name + Bluefruit.setName("XIAO_NRF52_OTA"); + + Bluefruit.Periph.setConnectCallback(connect_callback); + Bluefruit.Periph.setDisconnectCallback(disconnect_callback); + + // To be consistent OTA DFU should be added first if it exists + bledfu.begin(); + + // Set up and start advertising + // Advertising packet + Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); + Bluefruit.Advertising.addTxPower(); + Bluefruit.Advertising.addName(); + + /* Start Advertising + - Enable auto advertising if disconnected + - Interval: fast mode = 20 ms, slow mode = 152.5 ms + - Timeout for fast mode is 30 seconds + - Start(timeout) with timeout = 0 will advertise forever (until connected) + + For recommended advertising interval + https://developer.apple.com/library/content/qa/qa1931/_index.html + */ + Bluefruit.Advertising.restartOnDisconnect(true); + Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms + Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode + Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds + + strcpy(reply, "OK - started"); + return true; + + + return false; +} diff --git a/src/helpers/nrf52/XiaoNrf52Board.h b/src/helpers/nrf52/XiaoNrf52Board.h new file mode 100644 index 00000000..5c2977c1 --- /dev/null +++ b/src/helpers/nrf52/XiaoNrf52Board.h @@ -0,0 +1,75 @@ +#pragma once + +#include +#include + +// LoRa radio module pins for Seeed Xiao-nrf52 +#ifdef SX1262_XIAO_S3_VARIANT + #define P_LORA_DIO_1 D0 + #define P_LORA_BUSY D1 + #define P_LORA_RESET D2 + #define P_LORA_NSS D3 + #define LORA_TX_BOOST_PIN D4 +#else + #define P_LORA_DIO_1 D1 + #define P_LORA_BUSY D3 + #define P_LORA_RESET D2 + #define P_LORA_NSS D4 + #define LORA_TX_BOOST_PIN D5 +#endif +#define P_LORA_SCLK PIN_SPI_SCK +#define P_LORA_MISO PIN_SPI_MISO +#define P_LORA_MOSI PIN_SPI_MOSI +//#define SX126X_POWER_EN 37 + +#define SX126X_DIO2_AS_RF_SWITCH true +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 + + +class XiaoNrf52Board : public mesh::MainBoard { +protected: + uint8_t startup_reason; + +public: + void begin(); + uint8_t getStartupReason() const override { return startup_reason; } + +#if defined(P_LORA_TX_LED) + void onBeforeTransmit() override { + digitalWrite(P_LORA_TX_LED, LOW); // turn TX LED on + } + void onAfterTransmit() override { + digitalWrite(P_LORA_TX_LED, HIGH); // turn TX LED off + } +#endif + + uint16_t getBattMilliVolts() override { + // Please read befor going further ;) + // https://wiki.seeedstudio.com/XIAO_BLE#q3-what-are-the-considerations-when-using-xiao-nrf52840-sense-for-battery-charging + + pinMode(BAT_NOT_CHARGING, INPUT); + if (digitalRead(BAT_NOT_CHARGING) == HIGH) { + int adcvalue = 0; + analogReadResolution(12); + analogReference(AR_INTERNAL_3_0); + digitalWrite(VBAT_ENABLE, LOW); + delay(10); + adcvalue = analogRead(PIN_VBAT); + digitalWrite(VBAT_ENABLE, HIGH); + return (adcvalue * ADC_MULTIPLIER * AREF_VOLTAGE) / 4.096; + } else { + digitalWrite(VBAT_ENABLE, HIGH); // ensures high ! + return 4200; // charging value + } + } + + const char* getManufacturerName() const override { + return "Seeed Xiao-nrf52"; + } + + void reboot() override { + NVIC_SystemReset(); + } + + bool startOTAUpdate(const char* id, char reply[]) override; +}; diff --git a/variants/xiao_nrf52/platformio.ini b/variants/xiao_nrf52/platformio.ini new file mode 100644 index 00000000..0947d86e --- /dev/null +++ b/variants/xiao_nrf52/platformio.ini @@ -0,0 +1,81 @@ +[nrf52840_xiao] +extends = nrf52_base +platform_packages = + toolchain-gccarmnoneeabi@~1.100301.0 + framework-arduinoadafruitnrf52 +board = seeed-xiao-afruitnrf52-nrf52840 +board_build.ldscript = boards/nrf52840_s140_v7.ld +build_flags = ${nrf52_base.build_flags} + -D NRF52_PLATFORM -D XIAO_NRF52 + -I lib/nrf52/s140_nrf52_7.3.0_API/include + -I lib/nrf52/s140_nrf52_7.3.0_API/include/nrf52 +lib_ignore = + BluetoothOTA + lvgl + lib5b4 +lib_deps = + ${nrf52_base.lib_deps} + rweather/Crypto @ ^0.4.0 + +[Xiao_nrf52] +extends = nrf52840_xiao +;board_build.ldscript = boards/nrf52840_s140_v7.ld +build_flags = ${nrf52840_xiao.build_flags} + -D P_LORA_TX_LED=11 + -I variants/xiao_nrf52 + -I src/helpers/nrf52 + -D RADIO_CLASS=CustomSX1262 + -D WRAPPER_CLASS=CustomSX1262Wrapper + -D LORA_TX_POWER=22 + -D SX126X_CURRENT_LIMIT=130 + -D SX126X_RX_BOOSTED_GAIN=1 +build_src_filter = ${nrf52840_xiao.build_src_filter} + + + + + +<../variants/xiao_nrf52> +debug_tool = jlink +upload_protocol = nrfutil + +[env:Xiao_nrf52_companion_radio_ble] +extends = Xiao_nrf52 +build_flags = + ${Xiao_nrf52.build_flags} + -D MAX_CONTACTS=100 + -D MAX_GROUP_CHANNELS=8 + -D BLE_PIN_CODE=123456 +; -D BLE_DEBUG_LOGGING=1 +; -D ENABLE_PRIVATE_KEY_IMPORT=1 +; -D ENABLE_PRIVATE_KEY_EXPORT=1 + -D MESH_PACKET_LOGGING=1 + -D MESH_DEBUG=1 +build_src_filter = ${Xiao_nrf52.build_src_filter} + + + +<../examples/companion_radio/main.cpp> +lib_deps = + ${Xiao_nrf52.lib_deps} + densaugeo/base64 @ ~1.4.0 + +[env:Xiao_nrf52_alt_pinout_companion_radio_ble] +extends = env:Xiao_nrf52_companion_radio_ble +build_flags = + ${env:Xiao_nrf52_companion_radio_ble.build_flags} + -D SX1262_XIAO_S3_VARIANT + +[env:Xiao_nrf52_repeater] +extends = Xiao_nrf52 +build_flags = + ${Xiao_nrf52.build_flags} + -D ADVERT_NAME='"Xiao_nrf52 Repeater"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = ${Xiao_nrf52.build_src_filter} + +<../examples/simple_repeater/main.cpp> + +[env:Xiao_nrf52_alt_pinout_repeater] +extends = env:Xiao_nrf52_repeater +build_flags = + ${env:Xiao_nrf52_repeater.build_flags} + -D SX1262_XIAO_S3_VARIANT \ No newline at end of file diff --git a/variants/xiao_nrf52/target.cpp b/variants/xiao_nrf52/target.cpp new file mode 100644 index 00000000..0707aa39 --- /dev/null +++ b/variants/xiao_nrf52/target.cpp @@ -0,0 +1,68 @@ +#include +#include "target.h" +#include + +XiaoNrf52Board board; + +RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI); + +WRAPPER_CLASS radio_driver(radio, board); + +VolatileRTCClock rtc_clock; + +#ifndef LORA_CR + #define LORA_CR 5 +#endif + +bool radio_init() { +// rtc_clock.begin(Wire); + +#ifdef SX126X_DIO3_TCXO_VOLTAGE + float tcxo = SX126X_DIO3_TCXO_VOLTAGE; +#else + float tcxo = 1.6f; +#endif + + SPI.setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI); + SPI.begin(); + int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo); + if (status != RADIOLIB_ERR_NONE) { + Serial.print("ERROR: radio init failed: "); + Serial.println(status); + return false; // fail + } + + radio.setCRC(1); + +#ifdef SX126X_CURRENT_LIMIT + radio.setCurrentLimit(SX126X_CURRENT_LIMIT); +#endif +#ifdef SX126X_DIO2_AS_RF_SWITCH + radio.setDio2AsRfSwitch(SX126X_DIO2_AS_RF_SWITCH); +#endif +#ifdef SX126X_RX_BOOSTED_GAIN + radio.setRxBoostedGainMode(SX126X_RX_BOOSTED_GAIN); +#endif + + return true; // success +} + +uint32_t radio_get_rng_seed() { + return radio.random(0x7FFFFFFF); +} + +void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { + radio.setFrequency(freq); + radio.setSpreadingFactor(sf); + radio.setBandwidth(bw); + radio.setCodingRate(cr); +} + +void radio_set_tx_power(uint8_t dbm) { + radio.setOutputPower(dbm); +} + +mesh::LocalIdentity radio_new_identity() { + RadioNoiseListener rng(radio); + return mesh::LocalIdentity(&rng); // create new random identity +} diff --git a/variants/xiao_nrf52/target.h b/variants/xiao_nrf52/target.h new file mode 100644 index 00000000..85f1ce1c --- /dev/null +++ b/variants/xiao_nrf52/target.h @@ -0,0 +1,18 @@ +#pragma once + +#define RADIOLIB_STATIC_ONLY 1 +#include +#include +#include +#include +#include + +extern XiaoNrf52Board board; +extern WRAPPER_CLASS radio_driver; +extern VolatileRTCClock rtc_clock; + +bool radio_init(); +uint32_t radio_get_rng_seed(); +void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); +void radio_set_tx_power(uint8_t dbm); +mesh::LocalIdentity radio_new_identity(); diff --git a/variants/xiao_nrf52/variant.cpp b/variants/xiao_nrf52/variant.cpp new file mode 100644 index 00000000..3c99b98d --- /dev/null +++ b/variants/xiao_nrf52/variant.cpp @@ -0,0 +1,78 @@ +#include "variant.h" +#include "wiring_constants.h" +#include "wiring_digital.h" +#include "nrf.h" + +const uint32_t g_ADigitalPinMap[] = +{ + // D0 .. D10 + 2, // D0 is P0.02 (A0) + 3, // D1 is P0.03 (A1) + 28, // D2 is P0.28 (A2) + 29, // D3 is P0.29 (A3) + 4, // D4 is P0.04 (A4,SDA) + 5, // D5 is P0.05 (A5,SCL) + 43, // D6 is P1.11 (TX) + 44, // D7 is P1.12 (RX) + 45, // D8 is P1.13 (SCK) + 46, // D9 is P1.14 (MISO) + 47, // D10 is P1.15 (MOSI) + + // LEDs + 26, // D11 is P0.26 (LED RED) + 6, // D12 is P0.06 (LED BLUE) + 30, // D13 is P0.30 (LED GREEN) + 14, // D14 is P0.14 (READ_BAT) + + // LSM6DS3TR + 40, // D15 is P1.08 (6D_PWR) + 27, // D16 is P0.27 (6D_I2C_SCL) + 7, // D17 is P0.07 (6D_I2C_SDA) + 11, // D18 is P0.11 (6D_INT1) + + // MIC + 42, // D19 is P1.10 (MIC_PWR) + 32, // D20 is P1.00 (PDM_CLK) + 16, // D21 is P0.16 (PDM_DATA) + + // BQ25100 + 13, // D22 is P0.13 (HICHG) + 17, // D23 is P0.17 (~CHG) + + // + 21, // D24 is P0.21 (QSPI_SCK) + 25, // D25 is P0.25 (QSPI_CSN) + 20, // D26 is P0.20 (QSPI_SIO_0 DI) + 24, // D27 is P0.24 (QSPI_SIO_1 DO) + 22, // D28 is P0.22 (QSPI_SIO_2 WP) + 23, // D29 is P0.23 (QSPI_SIO_3 HOLD) + + // NFC + 9, // D30 is P0.09 (NFC1) + 10, // D31 is P0.10 (NFC2) + + // VBAT + 31, // D32 is P0.31 (VBAT) +}; + +void initVariant() +{ + // Disable reading of the BAT voltage. + // https://wiki.seeedstudio.com/XIAO_BLE#q3-what-are-the-considerations-when-using-xiao-nrf52840-sense-for-battery-charging + pinMode(VBAT_ENABLE, OUTPUT); + digitalWrite(VBAT_ENABLE, HIGH); + + // Low charging current. + // https://wiki.seeedstudio.com/XIAO_BLE#battery-charging-current + pinMode(PIN_CHARGING_CURRENT, INPUT); + + pinMode(PIN_QSPI_CS, OUTPUT); + digitalWrite(PIN_QSPI_CS, HIGH); + + pinMode(LED_RED, OUTPUT); + digitalWrite(LED_RED, HIGH); + pinMode(LED_GREEN, OUTPUT); + digitalWrite(LED_GREEN, HIGH); + pinMode(LED_BLUE, OUTPUT); + digitalWrite(LED_BLUE, HIGH); +} diff --git a/variants/xiao_nrf52/variant.h b/variants/xiao_nrf52/variant.h new file mode 100644 index 00000000..5d68d270 --- /dev/null +++ b/variants/xiao_nrf52/variant.h @@ -0,0 +1,149 @@ +#ifndef _SEEED_XIAO_NRF52840_H_ +#define _SEEED_XIAO_NRF52840_H_ + +/** Master clock frequency */ +#define VARIANT_MCK (64000000ul) + +#define USE_LFXO // Board uses 32khz crystal for LF +//#define USE_LFRC // Board uses RC for LF + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +#define PINS_COUNT (33) +#define NUM_DIGITAL_PINS (33) +#define NUM_ANALOG_INPUTS (8) +#define NUM_ANALOG_OUTPUTS (0) + +// LEDs +#define PIN_LED (LED_RED) +#define LED_PWR (PINS_COUNT) +#define PIN_NEOPIXEL (PINS_COUNT) +#define NEOPIXEL_NUM (0) + +#define LED_BUILTIN (PIN_LED) + +#define LED_RED (11) +#define LED_GREEN (13) +#define LED_BLUE (12) + +#define LED_STATE_ON (1) // State when LED is litted + +// Buttons +#define PIN_BUTTON1 (PINS_COUNT) + +// Digital PINs +static const uint8_t D0 = 0 ; +static const uint8_t D1 = 1 ; +static const uint8_t D2 = 2 ; +static const uint8_t D3 = 3 ; +static const uint8_t D4 = 4 ; +static const uint8_t D5 = 5 ; +static const uint8_t D6 = 6 ; +static const uint8_t D7 = 7 ; +static const uint8_t D8 = 8 ; +static const uint8_t D9 = 9 ; +static const uint8_t D10 = 10; + +#define VBAT_ENABLE (14) // Output LOW to enable reading of the BAT voltage. + // https://wiki.seeedstudio.com/XIAO_BLE#q3-what-are-the-considerations-when-using-xiao-nrf52840-sense-for-battery-charging + +#define PIN_CHARGING_CURRENT (22) // Battery Charging current + // https://wiki.seeedstudio.com/XIAO_BLE#battery-charging-current + +// Analog pins +#define PIN_A0 (0) +#define PIN_A1 (1) +#define PIN_A2 (2) +#define PIN_A3 (3) +#define PIN_A4 (4) +#define PIN_A5 (5) +#define PIN_VBAT (32) // Read the BAT voltage. + // https://wiki.seeedstudio.com/XIAO_BLE#q3-what-are-the-considerations-when-using-xiao-nrf52840-sense-for-battery-charging + +#define BAT_NOT_CHARGING (23) // LOW when charging + +#define AREF_VOLTAGE (3.0) +#define ADC_MULTIPLIER (3.0F) // 1M, 512k divider bridge + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; + +#define ADC_RESOLUTION (12) + +// Other pins +#define PIN_NFC1 (30) +#define PIN_NFC2 (31) + +// Serial interfaces +#define PIN_SERIAL1_RX (7) +#define PIN_SERIAL1_TX (6) + +// SPI Interfaces +#define SPI_INTERFACES_COUNT (2) + +#define PIN_SPI_MISO (9) +#define PIN_SPI_MOSI (10) +#define PIN_SPI_SCK (8) + +static const uint8_t SS = D3; // NSS for sx ? +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK ; + +#define PIN_SPI1_MISO (25) +#define PIN_SPI1_MOSI (26) +#define PIN_SPI1_SCK (29) + +// Wire Interfaces +#define WIRE_INTERFACES_COUNT (1) + +#define PIN_WIRE_SDA (17) // 4 and 5 are used for the sx1262 ! +#define PIN_WIRE_SCL (16) // use WIRE1_SDA + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +//#define PIN_WIRE1_SDA (17) +//#define PIN_WIRE1_SCL (16) +#define PIN_LSM6DS3TR_C_POWER (15) +#define PIN_LSM6DS3TR_C_INT1 (18) + +// PDM Interfaces +#define PIN_PDM_PWR (19) +#define PIN_PDM_CLK (20) +#define PIN_PDM_DIN (21) + +// QSPI Pins +#define PIN_QSPI_SCK (24) +#define PIN_QSPI_CS (25) +#define PIN_QSPI_IO0 (26) +#define PIN_QSPI_IO1 (27) +#define PIN_QSPI_IO2 (28) +#define PIN_QSPI_IO3 (29) + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES (P25Q16H) +#define EXTERNAL_FLASH_USE_QSPI + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#endif From 1d4ae9f3c4ac744f1d1e013bd33e1cd3b75fcf71 Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Fri, 11 Apr 2025 19:11:06 +1000 Subject: [PATCH 21/27] minor refactor --- src/Dispatcher.cpp | 14 +++++++------- src/Packet.cpp | 16 ++++++++-------- src/Packet.h | 16 ++++++++-------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Dispatcher.cpp b/src/Dispatcher.cpp index cd7090d1..7a415f07 100644 --- a/src/Dispatcher.cpp +++ b/src/Dispatcher.cpp @@ -101,11 +101,11 @@ void Dispatcher::checkRecv() { #endif pkt->header = raw[i++]; - if (pkt->hasTransCodes()) { - memcpy(&pkt->trans_codes[0], &raw[i], 2); i += 2; - memcpy(&pkt->trans_codes[1], &raw[i], 2); i += 2; + if (pkt->hasTransportCodes()) { + memcpy(&pkt->transport_codes[0], &raw[i], 2); i += 2; + memcpy(&pkt->transport_codes[1], &raw[i], 2); i += 2; } else { - pkt->trans_codes[0] = pkt->trans_codes[1] = 0; + pkt->transport_codes[0] = pkt->transport_codes[1] = 0; } pkt->path_len = raw[i++]; @@ -218,9 +218,9 @@ void Dispatcher::checkSend() { raw[len++] = NODE_ID; #endif raw[len++] = outbound->header; - if (outbound->hasTransCodes()) { - memcpy(&raw[len], &outbound->trans_codes[0], 2); len += 2; - memcpy(&raw[len], &outbound->trans_codes[1], 2); len += 2; + if (outbound->hasTransportCodes()) { + memcpy(&raw[len], &outbound->transport_codes[0], 2); len += 2; + memcpy(&raw[len], &outbound->transport_codes[1], 2); len += 2; } raw[len++] = outbound->path_len; memcpy(&raw[len], outbound->path, outbound->path_len); len += outbound->path_len; diff --git a/src/Packet.cpp b/src/Packet.cpp index 386585fc..cb31638c 100644 --- a/src/Packet.cpp +++ b/src/Packet.cpp @@ -11,7 +11,7 @@ Packet::Packet() { } int Packet::getRawLength() const { - return 2 + path_len + payload_len + (hasTransCodes() ? 4 : 0); + return 2 + path_len + payload_len + (hasTransportCodes() ? 4 : 0); } void Packet::calculatePacketHash(uint8_t* hash) const { @@ -28,9 +28,9 @@ void Packet::calculatePacketHash(uint8_t* hash) const { uint8_t Packet::writeTo(uint8_t dest[]) const { uint8_t i = 0; dest[i++] = header; - if (hasTransCodes()) { - memcpy(&dest[i], &trans_codes[0], 2); i += 2; - memcpy(&dest[i], &trans_codes[1], 2); i += 2; + if (hasTransportCodes()) { + memcpy(&dest[i], &transport_codes[0], 2); i += 2; + memcpy(&dest[i], &transport_codes[1], 2); i += 2; } dest[i++] = path_len; memcpy(&dest[i], path, path_len); i += path_len; @@ -41,11 +41,11 @@ uint8_t Packet::writeTo(uint8_t dest[]) const { bool Packet::readFrom(const uint8_t src[], uint8_t len) { uint8_t i = 0; header = src[i++]; - if (hasTransCodes()) { - memcpy(&trans_codes[0], &src[i], 2); i += 2; - memcpy(&trans_codes[1], &src[i], 2); i += 2; + if (hasTransportCodes()) { + memcpy(&transport_codes[0], &src[i], 2); i += 2; + memcpy(&transport_codes[1], &src[i], 2); i += 2; } else { - trans_codes[0] = trans_codes[1] = 0; + transport_codes[0] = transport_codes[1] = 0; } path_len = src[i++]; if (path_len > sizeof(path)) return false; // bad encoding diff --git a/src/Packet.h b/src/Packet.h index dfd61da8..7c7df8e3 100644 --- a/src/Packet.h +++ b/src/Packet.h @@ -11,10 +11,10 @@ namespace mesh { #define PH_VER_SHIFT 6 #define PH_VER_MASK 0x03 // 2-bits -#define ROUTE_TYPE_TRANS_FLOOD 0x00 // flood mode + transport codes -#define ROUTE_TYPE_FLOOD 0x01 // flood mode, needs 'path' to be built up (max 64 bytes) -#define ROUTE_TYPE_DIRECT 0x02 // direct route, 'path' is supplied -#define ROUTE_TYPE_TRANS_DIRECT 0x03 // direct route + transport codes +#define ROUTE_TYPE_TRANSPORT_FLOOD 0x00 // flood mode + transport codes +#define ROUTE_TYPE_FLOOD 0x01 // flood mode, needs 'path' to be built up (max 64 bytes) +#define ROUTE_TYPE_DIRECT 0x02 // direct route, 'path' is supplied +#define ROUTE_TYPE_TRANSPORT_DIRECT 0x03 // direct route + transport codes #define PAYLOAD_TYPE_REQ 0x00 // request (prefixed with dest/src hashes, MAC) (enc data: timestamp, blob) #define PAYLOAD_TYPE_RESPONSE 0x01 // response to REQ or ANON_REQ (prefixed with dest/src hashes, MAC) (enc data: timestamp, blob) @@ -43,7 +43,7 @@ public: uint8_t header; uint16_t payload_len, path_len; - uint16_t trans_codes[2]; + uint16_t transport_codes[2]; uint8_t path[MAX_PATH_SIZE]; uint8_t payload[MAX_PACKET_PAYLOAD]; int8_t _snr; @@ -59,10 +59,10 @@ public: */ uint8_t getRouteType() const { return header & PH_ROUTE_MASK; } - bool isRouteFlood() const { return getRouteType() == ROUTE_TYPE_FLOOD || getRouteType() == ROUTE_TYPE_TRANS_FLOOD; } - bool isRouteDirect() const { return getRouteType() == ROUTE_TYPE_DIRECT || getRouteType() == ROUTE_TYPE_TRANS_DIRECT; } + bool isRouteFlood() const { return getRouteType() == ROUTE_TYPE_FLOOD || getRouteType() == ROUTE_TYPE_TRANSPORT_FLOOD; } + bool isRouteDirect() const { return getRouteType() == ROUTE_TYPE_DIRECT || getRouteType() == ROUTE_TYPE_TRANSPORT_DIRECT; } - bool hasTransCodes() const { return getRouteType() == ROUTE_TYPE_TRANS_FLOOD || getRouteType() == ROUTE_TYPE_TRANS_DIRECT; } + bool hasTransportCodes() const { return getRouteType() == ROUTE_TYPE_TRANSPORT_FLOOD || getRouteType() == ROUTE_TYPE_TRANSPORT_DIRECT; } /** * \returns one of PAYLOAD_TYPE_ values From b4330e376c35011ac0ec34a60c87bc054adc7701 Mon Sep 17 00:00:00 2001 From: Florent Date: Fri, 11 Apr 2025 14:51:10 +0200 Subject: [PATCH 22/27] compiles xiao_nrf52 board files only if we compile for xiao_nrf52 --- src/helpers/nrf52/XiaoNrf52Board.cpp | 4 ++++ src/helpers/nrf52/XiaoNrf52Board.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/helpers/nrf52/XiaoNrf52Board.cpp b/src/helpers/nrf52/XiaoNrf52Board.cpp index cf9d150f..c603b2af 100644 --- a/src/helpers/nrf52/XiaoNrf52Board.cpp +++ b/src/helpers/nrf52/XiaoNrf52Board.cpp @@ -1,3 +1,5 @@ +#ifdef XIAO_NRF52 + #include #include "XiaoNrf52Board.h" @@ -89,3 +91,5 @@ bool XiaoNrf52Board::startOTAUpdate(const char* id, char reply[]) { return false; } + +#endif \ No newline at end of file diff --git a/src/helpers/nrf52/XiaoNrf52Board.h b/src/helpers/nrf52/XiaoNrf52Board.h index 5c2977c1..1474892e 100644 --- a/src/helpers/nrf52/XiaoNrf52Board.h +++ b/src/helpers/nrf52/XiaoNrf52Board.h @@ -3,6 +3,8 @@ #include #include +#ifdef XIAO_NRF52 + // LoRa radio module pins for Seeed Xiao-nrf52 #ifdef SX1262_XIAO_S3_VARIANT #define P_LORA_DIO_1 D0 @@ -73,3 +75,5 @@ public: bool startOTAUpdate(const char* id, char reply[]) override; }; + +#endif \ No newline at end of file From 561d289ea5403880ea9e549d06c43527e163128c Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Sat, 12 Apr 2025 21:43:30 +1000 Subject: [PATCH 23/27] Companion: new 'manual_add_contacts' pref. New PUSH_CODE_NEW_ADVERT frames --- examples/companion_radio/main.cpp | 35 ++++++++++++++++++++++--------- src/helpers/BaseChatMesh.cpp | 25 ++++++++++++++++++---- src/helpers/BaseChatMesh.h | 1 + 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 48eafbf2..3932ba82 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -113,7 +113,7 @@ static uint32_t _atoi(const char* sp) { #define CMD_IMPORT_CONTACT 18 #define CMD_REBOOT 19 #define CMD_GET_BATTERY_VOLTAGE 20 -#define CMD_SET_TUNING_PARAMS 21 +#define CMD_SET_OTHER_PARAMS 21 #define CMD_DEVICE_QEURY 22 #define CMD_EXPORT_PRIVATE_KEY 23 #define CMD_IMPORT_PRIVATE_KEY 24 @@ -164,6 +164,7 @@ static uint32_t _atoi(const char* sp) { #define PUSH_CODE_STATUS_RESPONSE 0x87 #define PUSH_CODE_LOG_RX_DATA 0x88 #define PUSH_CODE_TRACE_DATA 0x89 +#define PUSH_CODE_NEW_ADVERT 0x8A #define ERR_CODE_UNSUPPORTED_CMD 1 #define ERR_CODE_NOT_FOUND 2 @@ -184,7 +185,7 @@ struct NodePrefs { // persisted to file uint8_t sf; uint8_t cr; uint8_t reserved1; - uint8_t reserved2; + uint8_t manual_add_contacts; float bw; uint8_t tx_power_dbm; uint8_t unused[3]; @@ -499,11 +500,19 @@ protected: } } + bool isAutoAddEnabled() const override { + return (_prefs.manual_add_contacts & 1) == 0; + } + void onDiscoveredContact(ContactInfo& contact, bool is_new) override { if (_serial->isConnected()) { - out_frame[0] = PUSH_CODE_ADVERT; - memcpy(&out_frame[1], contact.id.pub_key, PUB_KEY_SIZE); - _serial->writeFrame(out_frame, 1 + PUB_KEY_SIZE); + if (!isAutoAddEnabled() && is_new) { + writeContactRespFrame(PUSH_CODE_NEW_ADVERT, contact); + } else { + out_frame[0] = PUSH_CODE_ADVERT; + memcpy(&out_frame[1], contact.id.pub_key, PUB_KEY_SIZE); + _serial->writeFrame(out_frame, 1 + PUB_KEY_SIZE); + } } else { soundBuzzer(); } @@ -750,7 +759,7 @@ public: file.read((uint8_t *) &_prefs.sf, sizeof(_prefs.sf)); // 60 file.read((uint8_t *) &_prefs.cr, sizeof(_prefs.cr)); // 61 file.read((uint8_t *) &_prefs.reserved1, sizeof(_prefs.reserved1)); // 62 - file.read((uint8_t *) &_prefs.reserved2, sizeof(_prefs.reserved2)); // 63 + file.read((uint8_t *) &_prefs.manual_add_contacts, sizeof(_prefs.manual_add_contacts)); // 63 file.read((uint8_t *) &_prefs.bw, sizeof(_prefs.bw)); // 64 file.read((uint8_t *) &_prefs.tx_power_dbm, sizeof(_prefs.tx_power_dbm)); // 68 file.read((uint8_t *) _prefs.unused, sizeof(_prefs.unused)); // 69 @@ -851,7 +860,7 @@ public: file.write((uint8_t *) &_prefs.sf, sizeof(_prefs.sf)); // 60 file.write((uint8_t *) &_prefs.cr, sizeof(_prefs.cr)); // 61 file.write((uint8_t *) &_prefs.reserved1, sizeof(_prefs.reserved1)); // 62 - file.write((uint8_t *) &_prefs.reserved2, sizeof(_prefs.reserved2)); // 63 + file.write((uint8_t *) &_prefs.manual_add_contacts, sizeof(_prefs.manual_add_contacts)); // 63 file.write((uint8_t *) &_prefs.bw, sizeof(_prefs.bw)); // 64 file.write((uint8_t *) &_prefs.tx_power_dbm, sizeof(_prefs.tx_power_dbm)); // 68 file.write((uint8_t *) _prefs.unused, sizeof(_prefs.unused)); // 69 @@ -892,12 +901,15 @@ public: out_frame[i++] = MAX_LORA_TX_POWER; memcpy(&out_frame[i], self_id.pub_key, PUB_KEY_SIZE); i += PUB_KEY_SIZE; - int32_t lat, lon, alt = 0; + int32_t lat, lon; lat = (_prefs.node_lat * 1000000.0); lon = (_prefs.node_lon * 1000000.0); memcpy(&out_frame[i], &lat, 4); i += 4; memcpy(&out_frame[i], &lon, 4); i += 4; - memcpy(&out_frame[i], &alt, 4); i += 4; + out_frame[i++] = 0; // reserved + out_frame[i++] = 0; // reserved + out_frame[i++] = 0; // reserved + out_frame[i++] = _prefs.manual_add_contacts; uint32_t freq = _prefs.freq * 1000; memcpy(&out_frame[i], &freq, 4); i += 4; @@ -1172,13 +1184,16 @@ public: radio_set_tx_power(_prefs.tx_power_dbm); writeOKFrame(); } - } else if (cmd_frame[0] == CMD_SET_TUNING_PARAMS) { + } else if (cmd_frame[0] == CMD_SET_OTHER_PARAMS) { int i = 1; uint32_t rx, af; memcpy(&rx, &cmd_frame[i], 4); i += 4; memcpy(&af, &cmd_frame[i], 4); i += 4; _prefs.rx_delay_base = ((float)rx) / 1000.0f; _prefs.airtime_factor = ((float)af) / 1000.0f; + if (i < len) { + _prefs.manual_add_contacts = cmd_frame[i++]; + } savePrefs(); writeOKFrame(); } else if (cmd_frame[0] == CMD_REBOOT && memcmp(&cmd_frame[1], "reboot", 6) == 0) { diff --git a/src/helpers/BaseChatMesh.cpp b/src/helpers/BaseChatMesh.cpp index 989fcb2c..97aefff4 100644 --- a/src/helpers/BaseChatMesh.cpp +++ b/src/helpers/BaseChatMesh.cpp @@ -31,8 +31,29 @@ void BaseChatMesh::onAdvertRecv(mesh::Packet* packet, const mesh::Identity& id, } } + // save a copy of raw advert packet (to support "Share..." function) + int plen = packet->writeTo(temp_buf); + putBlobByKey(id.pub_key, PUB_KEY_SIZE, temp_buf, plen); + bool is_new = false; if (from == NULL) { + if (!isAutoAddEnabled()) { + ContactInfo ci; + memset(&ci, 0, sizeof(ci)); + ci.id = id; + ci.out_path_len = -1; // initially out_path is unknown + StrHelper::strncpy(ci.name, parser.getName(), sizeof(ci.name)); + ci.type = parser.getType(); + if (parser.hasLatLon()) { + ci.gps_lat = parser.getIntLat(); + ci.gps_lon = parser.getIntLon(); + } + ci.last_advert_timestamp = timestamp; + ci.lastmod = getRTCClock()->getCurrentTime(); + onDiscoveredContact(ci, true); // let UI know + return; + } + is_new = true; if (num_contacts < MAX_CONTACTS) { from = &contacts[num_contacts++]; @@ -50,10 +71,6 @@ void BaseChatMesh::onAdvertRecv(mesh::Packet* packet, const mesh::Identity& id, } } - // save a copy of raw advert packet (to support "Share..." function) - int plen = packet->writeTo(temp_buf); - putBlobByKey(id.pub_key, PUB_KEY_SIZE, temp_buf, plen); - // update StrHelper::strncpy(from->name, parser.getName(), sizeof(from->name)); from->type = parser.getType(); diff --git a/src/helpers/BaseChatMesh.h b/src/helpers/BaseChatMesh.h index 30598f6c..ed6e1c3a 100644 --- a/src/helpers/BaseChatMesh.h +++ b/src/helpers/BaseChatMesh.h @@ -103,6 +103,7 @@ protected: } // 'UI' concepts, for sub-classes to implement + virtual bool isAutoAddEnabled() const { return true; } virtual void onDiscoveredContact(ContactInfo& contact, bool is_new) = 0; virtual bool processAck(const uint8_t *data) = 0; virtual void onContactPathUpdated(const ContactInfo& contact) = 0; From 34faa49685fd8879206653a2558028d80136373d Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Sat, 12 Apr 2025 22:00:05 +1000 Subject: [PATCH 24/27] * new CMD_SET_OTHER_PARAMS (38) --- examples/companion_radio/main.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 3932ba82..e6c4432d 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -113,7 +113,7 @@ static uint32_t _atoi(const char* sp) { #define CMD_IMPORT_CONTACT 18 #define CMD_REBOOT 19 #define CMD_GET_BATTERY_VOLTAGE 20 -#define CMD_SET_OTHER_PARAMS 21 +#define CMD_SET_TUNING_PARAMS 21 #define CMD_DEVICE_QEURY 22 #define CMD_EXPORT_PRIVATE_KEY 23 #define CMD_IMPORT_PRIVATE_KEY 24 @@ -130,6 +130,7 @@ static uint32_t _atoi(const char* sp) { #define CMD_SIGN_FINISH 35 #define CMD_SEND_TRACE_PATH 36 #define CMD_SET_DEVICE_PIN 37 +#define CMD_SET_OTHER_PARAMS 38 #define RESP_CODE_OK 0 #define RESP_CODE_ERR 1 @@ -1184,16 +1185,17 @@ public: radio_set_tx_power(_prefs.tx_power_dbm); writeOKFrame(); } - } else if (cmd_frame[0] == CMD_SET_OTHER_PARAMS) { + } else if (cmd_frame[0] == CMD_SET_TUNING_PARAMS) { int i = 1; uint32_t rx, af; memcpy(&rx, &cmd_frame[i], 4); i += 4; memcpy(&af, &cmd_frame[i], 4); i += 4; _prefs.rx_delay_base = ((float)rx) / 1000.0f; _prefs.airtime_factor = ((float)af) / 1000.0f; - if (i < len) { - _prefs.manual_add_contacts = cmd_frame[i++]; - } + savePrefs(); + writeOKFrame(); + } else if (cmd_frame[0] == CMD_SET_OTHER_PARAMS) { + _prefs.manual_add_contacts = cmd_frame[1]; savePrefs(); writeOKFrame(); } else if (cmd_frame[0] == CMD_REBOOT && memcmp(&cmd_frame[1], "reboot", 6) == 0) { From 04118f01fcfc968f579043e52c038c2b681e36ed Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Sat, 12 Apr 2025 22:06:47 +1000 Subject: [PATCH 25/27] * companion: protocol ver (FIRMWARE_VER_CODE) now 4 --- examples/companion_radio/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index e6c4432d..e0b5e2a5 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -83,7 +83,7 @@ static uint32_t _atoi(const char* sp) { /*------------ Frame Protocol --------------*/ -#define FIRMWARE_VER_CODE 3 +#define FIRMWARE_VER_CODE 4 #ifndef FIRMWARE_BUILD_DATE #define FIRMWARE_BUILD_DATE "7 Apr 2025" From e825e4474fdd0ead26c2ca7aa8d5af527d3d2e4b Mon Sep 17 00:00:00 2001 From: liamcottle Date: Sun, 13 Apr 2025 13:36:39 +1200 Subject: [PATCH 26/27] fix rak4631 builds after addition of xio nrf52 board --- variants/rak4631/platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/variants/rak4631/platformio.ini b/variants/rak4631/platformio.ini index 49955722..f8708acd 100644 --- a/variants/rak4631/platformio.ini +++ b/variants/rak4631/platformio.ini @@ -16,7 +16,7 @@ build_flags = ${nrf52840_base.build_flags} -D SX126X_CURRENT_LIMIT=130 -D SX126X_RX_BOOSTED_GAIN=1 build_src_filter = ${nrf52840_base.build_src_filter} - + + + +<../variants/rak4631> lib_deps = ${nrf52840_base.lib_deps} @@ -86,7 +86,7 @@ build_flags = ; -D MESH_DEBUG=1 build_src_filter = ${rak4631.build_src_filter} + - + + + +<../examples/companion_radio> lib_deps = ${rak4631.lib_deps} From 7f7b03e442823b005fb5dd9968aa9055d9542e05 Mon Sep 17 00:00:00 2001 From: Florent Date: Mon, 14 Apr 2025 12:23:28 +0200 Subject: [PATCH 27/27] permit access to rx_boosted_mode at runtime for LR1110 (for dpm tests on that setting) --- src/helpers/CustomLR1110Wrapper.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/helpers/CustomLR1110Wrapper.h b/src/helpers/CustomLR1110Wrapper.h index fb3a4b91..3a96d3c2 100644 --- a/src/helpers/CustomLR1110Wrapper.h +++ b/src/helpers/CustomLR1110Wrapper.h @@ -27,4 +27,5 @@ public: float getLastRSSI() const override { return ((CustomLR1110 *)_radio)->getRSSI(); } float getLastSNR() const override { return ((CustomLR1110 *)_radio)->getSNR(); } + int16_t setRxBoostedGainMode(bool en) { return ((CustomLR1110 *)_radio)->setRxBoostedGainMode(en); }; };