Thinknode M6 Repeater Enable LEDs and Function Button#2605
Conversation
See if we can modify the behavior so the LEDs work
…hinknode-m6-power-button
|
Hey MeshCore team, this is my first ever attempt to contribute to a repo. Let me know if there are any questions or if there's something I should do differently next time. I only targeted the Repeater firmware this time, but will explore the other M6 firmware too for feature parity. Note I used Claude to assist and manually reviewed all code. Novice developer, wanted to take a stab at adding these critical features myself and contributing to the project. Tested over the past couple days. |
Remove device-specific code from the universal main.cpp file
The M6 follows a cleaner version of the existing SenseCAP Solar pattern: device-specific button logic lives in the variant (ThinkNodeM6Board::pollButton()), with a minimal dispatch call in main.cpp. The buttonStateChanged() methods on ThinkNodeM3Board, T1000eBoard, and PromicroBoard were defined but never connected to any caller — those boards could adopt the same pollButton() pattern in follow-up PRs if button UX is wanted.
|
I moved as much as a could out of main.cpp. Only a couple small blocks inside main.cpp are minimal dispatch calls (board.bootComplete() and board.pollButton()) to enable boot monitoring and button functionality. |
|
I need to research the affects this has on other firmware builds for the boot LED indicator. I think this causes a regression with companion firmware builds, which would cause an indefinite LED flicker. |
What this fixes
On the original M6 repeater build:
poweroffdidn't actually sleep the chip. The original code called a SoftDevice API (sd_power_system_off()) that requires SoftDevice to be running — but SoftDevice isn't enabled in the repeater build, so the call silently failed and the chip stayed awake. No button mapped to poweroff.variant.hbut never read or armed as a wake source or poweroff.What this adds
poweroffCLI: same shutdown cue.enterDeepSleep()helper with SoftDevice/direct-register fallback. Arms Function Button asSENSE-LOWwake source.RESETREAScaptured in a priority-101 constructor (before Nordic's errata-136 workaround scrubsRESETPIN).GPREGRET2user-intent flag distinguishes deliberate shutdown from transient resets. SurvivesSYSTEMOFF, cleared by full power loss. Result: device stays off when you asked it to, but self-heals from brownouts and auto-boots when a dead battery recovers.Implementation notes
#if defined(THINKNODE_M6)-guarded.SYSTEMOFFfix but not the repeater UX.analogWritePWM-binds pins on the Adafruit nRF52 core — boot path usedigitalWriteto keep blue compatible with the existing LoRa TX LED indicator.Test plan
Verified on hardware:
poweroffover serial → realSYSTEMOFFNot field-verified:
Out of scope
EXT_PWR_DETECT/EXT_CHRG_DETECTand a wake-on-charge mode) — planned follow-up.