diff --git a/.github/workflows/pr-build-check.yml b/.github/workflows/pr-build-check.yml index 37f3701b1a..67468b5691 100644 --- a/.github/workflows/pr-build-check.yml +++ b/.github/workflows/pr-build-check.yml @@ -39,6 +39,10 @@ jobs: - wio-e5-mini_repeater # ESP32-C6 - LilyGo_Tlora_C6_repeater_ + # LR1110 (nRF52) + - wio_wm1110_repeater + # SX1276 (ESP32) + - Tbeam_SX1276_repeater steps: - name: Clone Repo diff --git a/README.md b/README.md index ebad1f6f59..7f02f43c2f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,18 @@ + +## About MeshCore-Evo + +This is a friendly fork of the MeshCore project. +Its aim is to provide repeater firmwares with a few additional pending upstream PRs/improvements (i.e. PRs/improvements that are available to the MeshCore project but have not yet been merged in the upstream repo or PRs that might never be merged upstream for some reason). +These changes are intended to help mitigating challenges in big or dense meshes, e.g.: + +- Dealing with flood advert traffic +- improving `denyf *` handling + +This list might change any time. +Refer to the [release notes](https://github.com/mattzzw/MeshCore-Evo/releases) for an up-to-date list of the applied changes. + + + ## About MeshCore MeshCore is a lightweight, portable C++ library that enables multi-hop packet routing for embedded projects using LoRa and other packet radios. It is designed for developers who want to create resilient, decentralized communication networks that work without the internet. diff --git a/boards/t-echo.json b/boards/t-echo.json index c974ca650f..e0df6eac79 100644 --- a/boards/t-echo.json +++ b/boards/t-echo.json @@ -53,11 +53,14 @@ "protocols": [ "jlink", "nrfjprog", + "nrfutil", "stlink", "cmsis-dap", "blackmagic" - ] + ], + "use_1200bps_touch": true, + "wait_for_upload_port": true }, "url": "https://os.mbed.com/platforms/Nordic-nRF52840-DK/", "vendor": "Nordic" -} \ No newline at end of file +} diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index 666f79fc5c..069fad490d 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -447,6 +447,15 @@ bool MyMesh::allowPacketForward(const mesh::Packet *packet) { return false; } } + // Limit flood advert paket forwarding using a probabilistic reduction defined by P(h) = 0.308^(hops-1) + // https://github.com/meshcore-dev/MeshCore/issues/1223 + if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->isRouteFlood()) { + double roll_dice = (double)rand() / RAND_MAX; + double forw_prob = pow(_prefs.flood_advert_base, packet->path_len - 1); + if (roll_dice > forw_prob) + return false; + } + return true; } @@ -885,6 +894,7 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc _prefs.tx_power_dbm = LORA_TX_POWER; _prefs.advert_interval = 1; // default to 2 minutes for NEW installs _prefs.flood_advert_interval = 12; // 12 hours + _prefs.flood_advert_base = 0.308f; _prefs.flood_max = 64; _prefs.interference_threshold = 0; // disabled diff --git a/examples/simple_room_server/MyMesh.cpp b/examples/simple_room_server/MyMesh.cpp index 145fb0fd9f..1822d00ce7 100644 --- a/examples/simple_room_server/MyMesh.cpp +++ b/examples/simple_room_server/MyMesh.cpp @@ -282,7 +282,17 @@ uint32_t MyMesh::getDirectRetransmitDelay(const mesh::Packet *packet) { bool MyMesh::allowPacketForward(const mesh::Packet *packet) { if (_prefs.disable_fwd) return false; - if (packet->isRouteFlood() && packet->getPathHashCount() >= _prefs.flood_max) return false; + if (packet->isRouteFlood() && packet->path_len >= _prefs.flood_max) return false; + + // Limit flood advert packet forwarding using a probabilistic reduction defined by P(h) = base^(hops-1) + // https://github.com/meshcore-dev/MeshCore/issues/1223 + if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->isRouteFlood()) { + double roll_dice = (double)rand() / RAND_MAX; + double forw_prob = pow(_prefs.flood_advert_base, packet->path_len - 1); + if (roll_dice > forw_prob) + return false; + } + return true; } @@ -642,6 +652,7 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc _prefs.disable_fwd = 1; _prefs.advert_interval = 1; // default to 2 minutes for NEW installs _prefs.flood_advert_interval = 12; // 12 hours + _prefs.flood_advert_base = 0.308f; _prefs.flood_max = 64; _prefs.interference_threshold = 0; // disabled #ifdef ROOM_PASSWORD diff --git a/src/helpers/CommonCLI.cpp b/src/helpers/CommonCLI.cpp index d495aada5f..3bbef5fd2c 100644 --- a/src/helpers/CommonCLI.cpp +++ b/src/helpers/CommonCLI.cpp @@ -2,6 +2,7 @@ #include "CommonCLI.h" #include "TxtDataHelpers.h" #include "AdvertDataHelpers.h" +#include "TxtDataHelpers.h" #include #ifndef BRIDGE_MAX_BAUD @@ -87,8 +88,8 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) { file.read((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162 file.read((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166 file.read((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170 - file.read((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 290 - // next: 291 + file.read((uint8_t *)&_prefs->flood_advert_base, sizeof(_prefs->flood_advert_base)); // 290 + file.read((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 294 // sanitise bad pref values _prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f); @@ -118,6 +119,7 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) { // sanitise settings _prefs->rx_boosted_gain = constrain(_prefs->rx_boosted_gain, 0, 1); // boolean + _prefs->flood_advert_base = constrain(_prefs->flood_advert_base, 0, 1); file.close(); } @@ -178,8 +180,8 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) { file.write((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162 file.write((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166 file.write((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170 - file.write((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 290 - // next: 291 + file.write((uint8_t *)&_prefs->flood_advert_base, sizeof(_prefs->flood_advert_base)); // 290 + file.write((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 294 file.close(); } @@ -285,7 +287,8 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re // change admin password StrHelper::strncpy(_prefs->password, &command[9], sizeof(_prefs->password)); savePrefs(); - sprintf(reply, "password now: %s", _prefs->password); // echo back just to let admin know for sure!! + sprintf(reply, "password now: "); + StrHelper::strncpy(&reply[14], _prefs->password, 160-15); // echo back just to let admin know for sure!! } else if (memcmp(command, "clear stats", 11) == 0) { _callbacks->clearStats(); strcpy(reply, "(OK - stats reset)"); @@ -605,6 +608,15 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep } else { strcpy(reply, "Error, max 64"); } + } else if (memcmp(config, "flood.advert.base ", 18) == 0) { + float f = atof(&config[18]); + if (f >= 0.0f && f <= 1.0f) { + _prefs->flood_advert_base = f; + savePrefs(); + strcpy(reply, "OK"); + } else { + strcpy(reply, "Error: base must be between 0 and 1"); + } } else if (memcmp(config, "direct.txdelay ", 15) == 0) { float f = atof(&config[15]); if (f >= 0) { @@ -726,7 +738,8 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep strcpy(reply, "Error: unsupported by this board"); }; } else { - sprintf(reply, "unknown config: %s", config); + strcpy(reply, "unknown config: "); + StrHelper::strncpy(&reply[16], config, 160-17); } } @@ -781,13 +794,16 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep sprintf(reply, "> %s", StrHelper::ftoa(_prefs->tx_delay_factor)); } else if (memcmp(config, "flood.max", 9) == 0) { sprintf(reply, "> %d", (uint32_t)_prefs->flood_max); + } else if (memcmp(config, "flood.advert.base", 17) == 0) { + sprintf(reply, "> %s", StrHelper::ftoa(_prefs->flood_advert_base)); } else if (memcmp(config, "direct.txdelay", 14) == 0) { sprintf(reply, "> %s", StrHelper::ftoa(_prefs->direct_tx_delay_factor)); } else if (memcmp(config, "owner.info", 10) == 0) { + auto start = reply; *reply++ = '>'; *reply++ = ' '; const char* sp = _prefs->owner_info; - while (*sp) { + while (*sp && reply - start < 159) { *reply++ = (*sp == '\n') ? '|' : *sp; // translate newline back to orig '|' sp++; } diff --git a/src/helpers/CommonCLI.h b/src/helpers/CommonCLI.h index ffdc7c6536..1defcd9255 100644 --- a/src/helpers/CommonCLI.h +++ b/src/helpers/CommonCLI.h @@ -42,6 +42,7 @@ struct NodePrefs { // persisted to file uint8_t flood_max; uint8_t interference_threshold; uint8_t agc_reset_interval; // secs / 4 + float flood_advert_base; // Bridge settings uint8_t bridge_enabled; // boolean uint16_t bridge_delay; // milliseconds (default 500 ms) diff --git a/variants/heltec_t096/LoRaFEMControl.cpp b/variants/heltec_t096/LoRaFEMControl.cpp index 9aeb83852b..fb60a8f781 100644 --- a/variants/heltec_t096/LoRaFEMControl.cpp +++ b/variants/heltec_t096/LoRaFEMControl.cpp @@ -9,7 +9,7 @@ void LoRaFEMControl::init(void) pinMode(P_LORA_KCT8103L_PA_CSD, OUTPUT); digitalWrite(P_LORA_KCT8103L_PA_CSD, HIGH); pinMode(P_LORA_KCT8103L_PA_CTX, OUTPUT); - digitalWrite(P_LORA_KCT8103L_PA_CTX, HIGH); + digitalWrite(P_LORA_KCT8103L_PA_CTX, lna_enabled ? LOW : HIGH); setLnaCanControl(true); } diff --git a/variants/heltec_t096/LoRaFEMControl.h b/variants/heltec_t096/LoRaFEMControl.h index 2c50b74289..fe61b7e441 100644 --- a/variants/heltec_t096/LoRaFEMControl.h +++ b/variants/heltec_t096/LoRaFEMControl.h @@ -16,6 +16,6 @@ class LoRaFEMControl void setLnaCanControl(bool can_control) { lna_can_control = can_control; } private: - bool lna_enabled = false; + bool lna_enabled = true; bool lna_can_control = false; }; diff --git a/variants/heltec_tracker_v2/LoRaFEMControl.cpp b/variants/heltec_tracker_v2/LoRaFEMControl.cpp index 3cf6c3112f..b846465d49 100644 --- a/variants/heltec_tracker_v2/LoRaFEMControl.cpp +++ b/variants/heltec_tracker_v2/LoRaFEMControl.cpp @@ -14,7 +14,7 @@ void LoRaFEMControl::init(void) pinMode(P_LORA_KCT8103L_PA_CSD, OUTPUT); digitalWrite(P_LORA_KCT8103L_PA_CSD, HIGH); pinMode(P_LORA_KCT8103L_PA_CTX, OUTPUT); - digitalWrite(P_LORA_KCT8103L_PA_CTX, HIGH); + digitalWrite(P_LORA_KCT8103L_PA_CTX, lna_enabled ? LOW : HIGH); setLnaCanControl(true); } diff --git a/variants/heltec_tracker_v2/LoRaFEMControl.h b/variants/heltec_tracker_v2/LoRaFEMControl.h index 2c50b74289..fe61b7e441 100644 --- a/variants/heltec_tracker_v2/LoRaFEMControl.h +++ b/variants/heltec_tracker_v2/LoRaFEMControl.h @@ -16,6 +16,6 @@ class LoRaFEMControl void setLnaCanControl(bool can_control) { lna_can_control = can_control; } private: - bool lna_enabled = false; + bool lna_enabled = true; bool lna_can_control = false; }; diff --git a/variants/heltec_v4/HeltecV4Board.cpp b/variants/heltec_v4/HeltecV4Board.cpp index 49580d2ecf..8f01379714 100644 --- a/variants/heltec_v4/HeltecV4Board.cpp +++ b/variants/heltec_v4/HeltecV4Board.cpp @@ -73,7 +73,7 @@ void HeltecV4Board::begin() { digitalWrite(PIN_ADC_CTRL, LOW); - return (5.42 * (3.3 / 1024.0) * raw) * 1000; + return (adc_mult * (3.3 / 1024.0) * raw) * 1000; } const char* HeltecV4Board::getManufacturerName() const { diff --git a/variants/heltec_v4/HeltecV4Board.h b/variants/heltec_v4/HeltecV4Board.h index 4d5ee46155..95def06c95 100644 --- a/variants/heltec_v4/HeltecV4Board.h +++ b/variants/heltec_v4/HeltecV4Board.h @@ -5,8 +5,16 @@ #include #include #include "LoRaFEMControl.h" + +#ifndef ADC_MULTIPLIER + #define ADC_MULTIPLIER 5.42 +#endif + class HeltecV4Board : public ESP32Board { +protected: + float adc_mult = ADC_MULTIPLIER; + public: RefCountedDigitalPin periph_power; LoRaFEMControl loRaFEMControl; @@ -18,6 +26,14 @@ class HeltecV4Board : public ESP32Board { void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1); void powerOff() override; uint16_t getBattMilliVolts() override; - const char* getManufacturerName() const override ; - + bool setAdcMultiplier(float multiplier) override { + if (multiplier == 0.0f) { + adc_mult = ADC_MULTIPLIER; + } else { + adc_mult = multiplier; + } + return true; + } + float getAdcMultiplier() const override { return adc_mult; } + const char* getManufacturerName() const override; }; diff --git a/variants/lilygo_techo_lite/TechoBoard.cpp b/variants/lilygo_techo_lite/TechoBoard.cpp index 81d3d0c9af..a11d31b27c 100644 --- a/variants/lilygo_techo_lite/TechoBoard.cpp +++ b/variants/lilygo_techo_lite/TechoBoard.cpp @@ -8,24 +8,47 @@ void TechoBoard::begin() { NRF52Board::begin(); + // Configure battery measurement control BEFORE Wire.begin() + // to ensure P0.02 is not claimed by another peripheral + pinMode(PIN_VBAT_MEAS_EN, OUTPUT); + digitalWrite(PIN_VBAT_MEAS_EN, LOW); + pinMode(PIN_VBAT_READ, INPUT); + Wire.begin(); pinMode(SX126X_POWER_EN, OUTPUT); digitalWrite(SX126X_POWER_EN, HIGH); - delay(10); // give sx1262 some time to power up + delay(10); } uint16_t TechoBoard::getBattMilliVolts() { - int adcvalue = 0; - + // Use LilyGo's exact ADC configuration analogReference(AR_INTERNAL_3_0); analogReadResolution(12); - delay(10); - // ADC range is 0..3000mV and resolution is 12-bit (0..4095) - adcvalue = analogRead(PIN_VBAT_READ); - // Convert the raw value to compensated mv, taking the resistor- - // divider into account (providing the actual LIPO voltage) - return (uint16_t)((float)adcvalue * REAL_VBAT_MV_PER_LSB); + // Enable battery voltage divider (MOSFET gate on P0.31) + pinMode(PIN_VBAT_MEAS_EN, OUTPUT); + digitalWrite(PIN_VBAT_MEAS_EN, HIGH); + + // Reclaim P0.02 for analog input (in case another peripheral touched it) + pinMode(PIN_VBAT_READ, INPUT); + delay(10); // let divider + ADC settle + + // Read and average (matching LilyGo's approach) + uint32_t sum = 0; + for (int i = 0; i < 8; i++) { + sum += analogRead(PIN_VBAT_READ); + delayMicroseconds(100); + } + uint16_t adc = sum / 8; + + // Disable divider to save power + digitalWrite(PIN_VBAT_MEAS_EN, LOW); + + // LilyGo's exact formula: adc * (3000.0 / 4096.0) * 2.0 + // = adc * 0.73242188 * 2.0 = adc * 1.46484375 + uint16_t millivolts = (uint16_t)((float)adc * (3000.0f / 4096.0f) * 2.0f); + + return millivolts; } -#endif +#endif \ No newline at end of file diff --git a/variants/lilygo_techo_lite/TechoBoard.h b/variants/lilygo_techo_lite/TechoBoard.h index fda393e7f9..7a43fd8383 100644 --- a/variants/lilygo_techo_lite/TechoBoard.h +++ b/variants/lilygo_techo_lite/TechoBoard.h @@ -4,14 +4,12 @@ #include #include -// built-ins -#define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096 - -#define VBAT_DIVIDER (0.5F) // 150K + 150K voltage divider on VBAT -#define VBAT_DIVIDER_COMP (2.0F) // Compensation factor for the VBAT divider - -#define PIN_VBAT_READ (4) -#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) +// ============================================================ +// T-Echo Lite battery pins — hardcoded from LilyGo t_echo_lite_config.h +// NOT using any defines from variant.h for battery measurement +// ============================================================ +#define PIN_VBAT_READ _PINNUM(0, 2) // BATTERY_ADC_DATA +#define PIN_VBAT_MEAS_EN _PINNUM(0, 31) // BATTERY_MEASUREMENT_CONTROL class TechoBoard : public NRF52BoardDCDC { public: @@ -20,10 +18,11 @@ class TechoBoard : public NRF52BoardDCDC { uint16_t getBattMilliVolts() override; const char* getManufacturerName() const override { - return "LilyGo T-Echo"; + return "LilyGo T-Echo Lite"; } void powerOff() override { + digitalWrite(PIN_VBAT_MEAS_EN, LOW); #ifdef LED_RED digitalWrite(LED_RED, LOW); #endif @@ -41,4 +40,4 @@ class TechoBoard : public NRF52BoardDCDC { #endif sd_power_system_off(); } -}; +}; \ No newline at end of file diff --git a/variants/lilygo_techo_lite/platformio.ini b/variants/lilygo_techo_lite/platformio.ini index 0ba6a19703..8861685824 100644 --- a/variants/lilygo_techo_lite/platformio.ini +++ b/variants/lilygo_techo_lite/platformio.ini @@ -96,3 +96,47 @@ build_src_filter = ${LilyGo_T-Echo-Lite.build_src_filter} lib_deps = ${LilyGo_T-Echo-Lite.lib_deps} densaugeo/base64 @ ~1.4.0 + +[env:LilyGo_T-Echo-Lite_non_shell_companion_radio_ble] +extends = LilyGo_T-Echo-Lite +upload_protocol = nrfutil +board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld +board_upload.maximum_size = 712704 +build_flags = + ${nrf52_base.build_flags} + -I variants/lilygo_techo_lite + -I src/helpers/nrf52 + -I lib/nrf52/s140_nrf52_6.1.1_API/include + -I lib/nrf52/s140_nrf52_6.1.1_API/include/nrf52 + -I src/helpers/ui + -I examples/companion_radio/ui-new + -D LILYGO_TECHO + -D RADIO_CLASS=CustomSX1262 + -D WRAPPER_CLASS=CustomSX1262Wrapper + -D LORA_TX_POWER=22 + -D SX126X_POWER_EN=30 + -D SX126X_CURRENT_LIMIT=140 + -D SX126X_RX_BOOSTED_GAIN=1 + -D P_LORA_TX_LED=LED_GREEN + -D DISABLE_DIAGNOSTIC_OUTPUT + -D ENV_INCLUDE_GPS=1 + -D GPS_BAUD_RATE=9600 + -D PIN_GPS_EN=GPS_EN + -D AUTO_OFF_MILLIS=0 + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 + -D BLE_PIN_CODE=123456 + -D OFFLINE_QUEUE_SIZE=256 + -D UI_RECENT_LIST_SIZE=9 + -D AUTO_SHUTDOWN_MILLIVOLTS=3300 +build_src_filter = ${nrf52_base.build_src_filter} + + + + + + + + + +<../variants/lilygo_techo_lite> + + + +<../examples/companion_radio/*.cpp> +lib_deps = + ${LilyGo_T-Echo-Lite.lib_deps} + densaugeo/base64 @ ~1.4.0 diff --git a/variants/lilygo_techo_lite/variant.h b/variants/lilygo_techo_lite/variant.h index 16e0b5cb9d..0720216516 100644 --- a/variants/lilygo_techo_lite/variant.h +++ b/variants/lilygo_techo_lite/variant.h @@ -24,7 +24,7 @@ #define PIN_PWR_EN _PINNUM(0, 30) // RT9080_EN #define BATTERY_PIN _PINNUM(0, 2) -#define ADC_MULTIPLIER (4.90F) +#define ADC_MULTIPLIER (2.0F) #define ADC_RESOLUTION (14) #define BATTERY_SENSE_RES (12) @@ -47,13 +47,13 @@ //////////////////////////////////////////////////////////////////////////////// // I2C pin definition -#define PIN_WIRE_SDA _PINNUM(0, 4) // (SDA) -#define PIN_WIRE_SCL _PINNUM(0, 2) // (SCL) +#define PIN_WIRE_SDA _PINNUM(1, 4) // (SDA) - per LilyGo IIC_1_SDA +#define PIN_WIRE_SCL _PINNUM(1, 2) // (SCL) - per LilyGo IIC_1_SCL //////////////////////////////////////////////////////////////////////////////// // SPI pin definition -#define SPI_INTERFACES_COUNT _PINNUM(0, 2) +#define SPI_INTERFACES_COUNT (2) #define PIN_SPI_MISO _PINNUM(0, 17) // (MISO) #define PIN_SPI_MOSI _PINNUM(0, 15) // (MOSI) @@ -149,10 +149,11 @@ extern const int SCK; #define PIN_DISPLAY_BUSY DISP_BUSY //////////////////////////////////////////////////////////////////////////////// -// GPS - -#define PIN_GPS_RX _PINNUM(1, 13) // RXD -#define PIN_GPS_TX _PINNUM(1, 15) // TXD -#define GPS_EN _PINNUM(1, 11) // POWER_RT9080_EN -#define PIN_GPS_STANDBY _PINNUM(1, 10) -#define PIN_GPS_PPS _PINNUM(0, 29) // 1PPS +// GPS — per LilyGo t_echo_lite_config.h +// PIN_GPS_TX/RX named from GPS module's perspective + +#define PIN_GPS_TX _PINNUM(0, 29) // GPS UART TX → MCU RX +#define PIN_GPS_RX _PINNUM(1, 10) // GPS UART RX ← MCU TX +#define GPS_EN _PINNUM(1, 11) // GPS RT9080 power enable +#define PIN_GPS_STANDBY _PINNUM(1, 13) // GPS wake-up +#define PIN_GPS_PPS _PINNUM(1, 15) // GPS 1PPS \ No newline at end of file diff --git a/variants/muziworks_r1_neo/R1NeoBoard.cpp b/variants/muziworks_r1_neo/R1NeoBoard.cpp index 616d255a8c..89cde02a53 100644 --- a/variants/muziworks_r1_neo/R1NeoBoard.cpp +++ b/variants/muziworks_r1_neo/R1NeoBoard.cpp @@ -14,9 +14,12 @@ const PowerMgtConfig power_config = { void R1NeoBoard::initiateShutdown(uint8_t reason) { // Disable LoRa module power before shutdown - MESH_DEBUG_PRINTLN("R1Neo: shutting down"); digitalWrite(SX126X_POWER_EN, LOW); + // Signal IO controller that MCU is off, then release DCDC latch + digitalWrite(PIN_SOFT_SHUTDOWN, LOW); + digitalWrite(PIN_DCDC_EN_MCU_HOLD, LOW); + if (reason == SHUTDOWN_REASON_LOW_VOLTAGE || reason == SHUTDOWN_REASON_BOOT_PROTECT) { configureVoltageWake(power_config.lpcomp_ain_channel, power_config.lpcomp_refsel); diff --git a/variants/muziworks_r1_neo/R1NeoBoard.h b/variants/muziworks_r1_neo/R1NeoBoard.h index c27ea23212..c56f1f5c2e 100644 --- a/variants/muziworks_r1_neo/R1NeoBoard.h +++ b/variants/muziworks_r1_neo/R1NeoBoard.h @@ -18,6 +18,12 @@ class R1NeoBoard : public NRF52BoardDCDC { R1NeoBoard() : NRF52Board("R1NEO_OTA") {} void begin(); +#ifdef NRF52_POWER_MANAGEMENT + void powerOff() override { + initiateShutdown(SHUTDOWN_REASON_USER); + } +#endif + #if defined(P_LORA_TX_LED) void onBeforeTransmit() override { digitalWrite(P_LORA_TX_LED, HIGH); // turn TX LED on diff --git a/variants/rak4631/variant.h b/variants/rak4631/variant.h index 142d93e91d..38cc88685c 100644 --- a/variants/rak4631/variant.h +++ b/variants/rak4631/variant.h @@ -147,7 +147,7 @@ extern "C" // LoRa radio module pins for RAK4631 #define P_LORA_DIO_1 (47) #define P_LORA_NSS (42) -#define P_LORA_RESET (-1) +#define P_LORA_RESET (38) #define P_LORA_BUSY (46) #define P_LORA_SCLK (43) #define P_LORA_MISO (45)