-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Meshlink v1.3 board updates and heartbeat LED fixes #11654
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
269db96
c7237e9
8483a9b
10ee315
4436ab8
33a1278
1bbd1de
50e4b0a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,17 +25,15 @@ extern "C" { | |
| #define NUM_ANALOG_INPUTS (2) | ||
| #define NUM_ANALOG_OUTPUTS (0) | ||
|
|
||
| #define BUTTON_PIN (-1) // If defined, this will be used for user button presses, | ||
| #define BUTTON_PIN (10) // If defined, this will be used for user button presses, | ||
| #define BUTTON_NEED_PULLUP | ||
|
|
||
| // LEDs | ||
| #define PIN_LED1 (24) // Built in white led for status | ||
| #define LED_BLUE PIN_LED1 | ||
|
|
||
| #define LED_STATE_ON 0 // State when LED is lit | ||
| #define LED_HEARTBEAT (24) // Force strictly heartbeat on Pin 24 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift 🔎 Supported by static analysis🏁 Script executed: printf '%s\n' '--- applicable instructions ---'
cat .github/copilot-instructions.md
printf '%s\n' '--- repository knowledge scopes ---'
find /tmp/coderabbit-repo-knowledge/meshtastic-firmware-d6b70ec8 -maxdepth 2 -type f -name '*.md' -print
printf '%s\n' '--- target file ---'
cat -n variants/nrf52840/meshlink/variant.h | sed -n '1,70p'
printf '%s\n' '--- directly bound LED/watchdog definitions and call sites ---'
rg -n -S 'LED_HEARTBEAT|StatusLEDModule|watchdog|Watchdog|MeshLink|meshlink' \
variants/nrf52840/meshlink src modules .github 2>/dev/null | head -250Repository: meshtastic/firmware Length of output: 50378 🏁 Script executed: printf '%s\n' '--- relevant repository guidance and learnings ---'
for f in /tmp/coderabbit-repo-knowledge/meshtastic-firmware-d6b70ec8/*/*.md; do
case "$f" in
*/learnings/*|*/architecture/*|*/conventions/*)
if grep -Eqi 'LED|watchdog|MeshLink|charging|StatusLED' "$f"; then
echo "### $f"
cat "$f"
fi
;;
esac
done
printf '%s\n' '--- target variant ---'
cat -n variants/nrf52840/meshlink/variant.h | sed -n '1,55p'
printf '%s\n' '--- relevant source files ---'
git ls-files | grep -E '(^|/)(StatusLEDModule|Watchdog|watchdog|PowerFSM|Charging|MeshLink|meshlink)' | head -100
printf '%s\n' '--- relevant symbols ---'
rg -n -S --glob '*.{cpp,h,hpp,cc,hh}' \
'LED_HEARTBEAT|StatusLEDModule|watchdog|Watchdog|charging|Charging|MESH[Ll]ink' \
variants/nrf52840/meshlink src | head -300Repository: meshtastic/firmware Length of output: 23607 🏁 Script executed: printf '%s\n' '--- relevant repository guidance and learnings ---'
for f in /tmp/coderabbit-repo-knowledge/meshtastic-firmware-d6b70ec8/*/*.md; do
if grep -Eqi 'LED|watchdog|MeshLink|charging|StatusLED' "$f"; then
echo "### $f"
cat "$f"
fi
done
printf '%s\n' '--- target variant ---'
cat -n variants/nrf52840/meshlink/variant.h | sed -n '1,55p'
printf '%s\n' '--- relevant source files ---'
git ls-files | grep -E '(^|/)(StatusLEDModule|Watchdog|watchdog|PowerFSM|Charging|MeshLink|meshlink)' | head -100
printf '%s\n' '--- relevant symbols ---'
rg -n -S --glob '*.{cpp,h,hpp,cc,hh}' \
'LED_HEARTBEAT|StatusLEDModule|watchdog|Watchdog|charging|Charging|MESH[Ll]ink' \
variants/nrf52840/meshlink src | head -300Repository: meshtastic/firmware Length of output: 23607 🏁 Script executed: printf '%s\n' '--- StatusLEDModule implementation ---'
cat -n src/modules/StatusLEDModule.cpp | sed -n '1,180p'
printf '%s\n' '--- StatusLEDModule declaration ---'
cat -n src/modules/StatusLEDModule.h | sed -n '1,125p'
printf '%s\n' '--- MeshLink variant watchdog setup ---'
cat -n variants/nrf52840/meshlink/variant.cpp | sed -n '1,45p'
cat -n variants/nrf52840/meshlink/variant.h | sed -n '105,145p'
printf '%s\n' '--- watchdog thread implementation and registration ---'
cat -n src/watchdog/watchdogThread.cpp | sed -n '1,70p'
cat -n src/modules/Modules.cpp | sed -n '115,145p;275,295p'
printf '%s\n' '--- nRF52 main watchdog path ---'
cat -n src/platform/nrf52/main-nrf52.cpp | sed -n '350,385p;440,470p'Repository: meshtastic/firmware Length of output: 20180 🏁 Script executed: printf '%s\n' '--- MeshLink build contract ---'
cat -n variants/nrf52840/meshlink/platformio.ini
rg -n -S --glob '*.{h,hpp,cpp,ini,json}' \
'HAS_HARDWARE_WATCHDOG|HARDWARE_WATCHDOG_(DONE|WAKE|TIMEOUT)|APP_WATCHDOG_SECS|MeshLink' \
variants src boards | head -200
printf '%s\n' '--- remaining LED implementation ---'
cat -n src/modules/StatusLEDModule.cpp | sed -n '180,330p'
printf '%s\n' '--- nRF52 watchdog channel allocation ---'
rg -n -S --glob '*.{cpp,h,hpp}' \
'nrfx_wdt_channel_alloc|nrfx_wdt_channel_feed|HARDWARE_WATCHDOG_DONE|HARDWARE_WATCHDOG_WAKE' \
src variantsRepository: meshtastic/firmware Length of output: 13420 🏁 Script executed: printf '%s\n' '--- reviewed change ---'
git diff --unified=20 -- variants/nrf52840/meshlink/variant.h src/modules/StatusLEDModule.cpp variants/nrf52840/meshlink/variant.cpp
printf '%s\n' '--- pre-change target and directly related source ---'
git show HEAD^:variants/nrf52840/meshlink/variant.h | sed -n '24,38p'
git show HEAD^:src/modules/StatusLEDModule.cpp | sed -n '105,165p'
printf '%s\n' '--- all MeshLink-specific watchdog symbols in current and parent revisions ---'
for rev in HEAD HEAD^; do
echo "### $rev"
git grep -n -E 'PIN_WD_EN|HAS_HARDWARE_WATCHDOG|HARDWARE_WATCHDOG_|LED_HEARTBEAT' "$rev" -- variants/nrf52840/meshlink src/modules/StatusLEDModule.cpp src/watchdog 2>/dev/null
doneRepository: meshtastic/firmware Length of output: 6558 🌐 Web query:
💡 Result: Based on the current state of the Meshtastic firmware repository as of August 29, 2026, there is no direct pull request identified as Citations:
🌐 Web query:
💡 Result: PR
It has 4 commits and was tested on V1.2 and V1.3 boards. [1] 🌐 Web query:
💡 Result: The MeshLink V1.3 board, developed by LoraItalia, uses an NRF52840 processor and includes features such as an integrated hardware watchdog, MPPT solar charging support, and various peripheral options [1]. Board Updates and Configuration Recent firmware developments for the MeshLink board have focused on refining its hardware support, including updates to platformio.ini and variant.h files [2][3]. These updates have addressed issues with GPS serial pin mapping, enabled the correct GPS enable pin, and standardized the platformio.ini configuration to align with other boards in the Meshtastic firmware ecosystem [2][3]. Additionally, optimizations have been implemented for E-INK screen responsiveness, and a default GPIO (10) has been assigned for the user button [2][3]. Watchdog and Power Management The MeshLink board is explicitly designed with a hardware watchdog [1]. In the board's variant.h file, PIN 25 is defined as PIN_WD_EN to manage this watchdog [4]. It is a critical requirement that this pin be disabled when the CPU enters sleep mode; otherwise, the timer will expire and cause the CPU to reboot [4]. StatusLEDModule and Charging The StatusLEDModule in the Meshtastic firmware manages device status indicators, including those for charging status and Bluetooth state [5][6]. Support for detecting charging states was specifically added to this module to ensure correct LED feedback during charge cycles [7]. The module processes power status updates (e.g., USB connection, charging, charged, discharging, critical battery levels) and updates the assigned LEDs accordingly [5]. For boards utilizing PMUs (Power Management Units), the module interfaces with the PMU to control charging LEDs [5]. Heartbeat LED Behavior Issues involving the heartbeat LED remaining solid rather than blinking are often related to specific board variant configurations or power-saving states [8][9]. On NRF52-based boards, if the system perceives the battery voltage as being below a certain threshold or detects power-loss conditions, it may alter LED behavior as part of its power-saving logic [9]. Users encountering solid LED behavior are advised to verify their board's variant definitions (e.g., LED_STATE_ON settings) and ensure that battery voltage reporting is correctly calibrated [9]. Citations:
🌐 Web query:
💡 Result: There is no evidence of a specific Meshtastic firmware issue tied to the number "11654" in the context of watchdog or charging problems [1][2][3][4]. The number 11654 appears in unrelated technical contexts, such as historical Linux kernel build logs [5][6] and Patton SmartWare release notes [7]. Regarding Meshtastic firmware, charging and watchdog-related issues are well-documented but are typically associated with specific hardware behaviors rather than a single numerical identifier: 1. Charging and Deep Sleep Loops: On some ESP32-based devices, intelligent charging controllers may cause the device to enter a deep sleep loop because the battery voltage rises slowly, preventing the device from detecting a full or sufficient charge [1]. 2. NRF52 Brownouts: NRF52 boards can experience lockups when battery voltage sags, sometimes triggering power-fail warnings or requiring physical resets because the hardware brownout reset (BOR) is factory-fixed and cannot always recover without a complete power cycle [2][3]. 3. Heltec T114 Lockups: These are often linked to unregulated solar panels providing over-voltage, which causes the charging chip to trigger protection and effectively lock the device [3]. If you are encountering a specific watchdog or charging error, it is recommended to search the official Meshtastic GitHub repository issues using descriptive keywords like "solar charging," "deep sleep," "brownout," or the specific model of your hardware (e.g., "T114," "ESP32," "RAK") [1][2][3]. Citations:
🌐 Web query:
💡 Result: In the MeshLink hardware configuration (nRF52840-based board developed by LoraItalia), specific GPIO pins are designated for status indication and hardware watchdog management [1][2][3]. According to the official board variant files (e.g., variant.h), the hardware functions are defined as follows: - GPIO 24: This pin is assigned to the status LED (PIN_LED1) [1][4]. It functions as a heartbeat or status indicator, with the LED state being active-low (LED_STATE_ON = 0) [1][4]. - GPIO 25: This pin serves as the hardware watchdog enable pin (PIN_WD_EN) [1]. It is used to enable or disable the external hardware watchdog [1]. Crucially, this pin must be disabled when the CPU enters sleep mode; otherwise, the timer will expire and the watchdog will trigger a CPU reboot [1]. These definitions are consistent across recent firmware configurations for the MeshLink board [1][5][6]. The MeshLink board integrates these features to support autonomous operations, particularly for remote nodes or repeaters where hardware-level monitoring is required [2][7][3]. Citations:
Land the MeshLink watchdog fix before enabling
🤖 Prompt for AI Agents |
||
| #define LED_STATE_ON 0 // Active LOW | ||
|
|
||
| // Testing USB detection | ||
| // #define NRF_APM | ||
| //#define NRF_APM | ||
|
|
||
| /* | ||
| * Analog pins | ||
|
|
@@ -50,8 +48,8 @@ extern "C" { | |
| /* | ||
| * Serial interfaces | ||
| */ | ||
| #define PIN_SERIAL1_RX (32 + 8) | ||
| #define PIN_SERIAL1_TX (7) | ||
| #define PIN_SERIAL1_TX (32 + 8) | ||
| #define PIN_SERIAL1_RX (7) | ||
| #define SERIAL_PRINT_PORT 0 | ||
|
|
||
| /* | ||
|
|
@@ -126,12 +124,15 @@ static const uint8_t SCK = PIN_SPI_SCK; | |
| // #define GPS_THREAD_INTERVAL 50 | ||
|
|
||
| // Define pin to enable GPS toggle (set GPIO to LOW) via user button triple press | ||
| #define PIN_GPS_EN (0) | ||
| #define PIN_GPS_EN (4) | ||
| #define GPS_EN_ACTIVE LOW | ||
|
|
||
| #define PIN_BUZZER (31) // P0.31/AIN7 | ||
|
|
||
|
|
||
| // Battery | ||
| //our INA219 is reversed (+ sign when discharging and - when charging) | ||
| #define INA219_MULTIPLIER -1.0f //with this we fix the sign shown | ||
| // The battery sense is hooked to pin A0 (2) | ||
| #define BATTERY_PIN (2) | ||
| // and has 12 bit resolution | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: meshtastic/firmware
Length of output: 50378
🏁 Script executed:
Repository: meshtastic/firmware
Length of output: 50376
🏁 Script executed:
Repository: meshtastic/firmware
Length of output: 50376
🌐 Web query:
Good Display GDEY/B74 2.13 inch e-paper GxEPD2_213_B74 partial refresh full refresh every five partial updates ghosting💡 Result:
The Good Display GDEY0213B74 2.13-inch e-paper display supports both full and partial refreshes [1][2]. When using the GxEPD2 library, the GxEPD2_213_B74 driver is designed to handle these operations, including specific handling for partial updates [3][4][5]. Regarding the specific concern of ghosting and partial refresh frequency: 1. Ghosting and Partial Refresh: E-paper displays naturally accumulate artifacts ("ghosting") when using partial updates because they do not fully reset the pixels to a neutral state with every refresh [6]. To manage this, it is standard practice to perform a full refresh periodically [6][7]. A common recommendation is to perform a full refresh every 5 to 10 partial updates, depending on the application and how much content changes on the screen [6][7]. 2. Partial vs. Full Screen Refresh: On many panels with SSD controllers (like the SSD1680 used in the GDEY0213B74), "partial update" technically refers to updating a specific window, but many drivers perform a differential refresh on the full screen anyway [6][8]. If your application involves multiple elements changing at different times, it is often more efficient and cleaner to trigger a full-screen refresh to avoid the "ghost frame" or artifacts that can appear around defined partial windows [6][8]. 3. Library Configuration: The GxEPD2 library includes mechanisms to control this behavior [5]. You can monitor the number of partial updates in your code and trigger a full update (
display.refresh(false)) once the threshold (e.g., every 5 updates) is reached [6][7]. If ghosting is excessive even with frequent full updates, ensuring that you are using the correctGxEPD2_213_B74driver class and that your initialization sequence matches the manufacturer's recommendations is crucial [5]. Some developers also successfully mitigate ghosting by re-initializing the display or forcing a full refresh sequence after a certain period of continuous partial updates [9][7]. In summary, ghosting is an inherent characteristic of partial refresh in electrophoretic displays [6]. Performing a full refresh every 5 partial updates is a widely accepted heuristic to maintain image quality [6][7]. If you notice persistent issues, try increasing the frequency of full refreshes or switching to full-screen updates if the performance impact allows [6][8].Citations:
🏁 Script executed:
Repository: meshtastic/firmware
Length of output: 32400
Use a conservative fast-refresh limit for
GxEPD2_213_B74.EInkDynamicDisplay::checkConsecutiveFastRefreshes()forces the next frame to full refresh only after 100 consecutive fast refreshes. Partial refreshes may accumulate visible ghosting, and commenting outEINK_LIMIT_GHOSTING_PXdisables the pixel-based guard. SetEINK_LIMIT_FASTREFRESH=5and enableEINK_LIMIT_GHOSTING_PX=2000, or provide hardware soak-test evidence for 100 refreshes.🤖 Prompt for AI Agents