Skip to content

Feat/stm32 rtc#10103

Closed
ndoo wants to merge 4 commits intomeshtastic:developfrom
mesh-malaysia:feat/stm32-rtc
Closed

Feat/stm32 rtc#10103
ndoo wants to merge 4 commits intomeshtastic:developfrom
mesh-malaysia:feat/stm32-rtc

Conversation

@ndoo
Copy link
Copy Markdown
Contributor

@ndoo ndoo commented Apr 8, 2026

Implement LSE-backed hardware RTC using STM32RTC library:

Add a proper ARCH_STM32WL branch in readFromRTC() and perhapsSetRTC() backed by the STM32duino STM32RTC library (1.9.0), using the hardware RTC peripheral with LSE_CLOCK as the clock source. The branch is guarded by HAS_RTC, which should be set to 1 only in variant files for boards that have a 32.768kHz LSE crystal populated.

The LSE drive strength is configured per-board via RCC_LSEDRIVE_CONFIG (one of the RCC_LSEDRIVE_* values), set before begin() so it takes effect before the library starts the LSE oscillator. When HAS_RTC=0, the branch returns RTCSetResultNotSet immediately without touching zeroOffsetSecs, bypassing the broken gettimeofday() fallback.

Add STM32duino RTC to stm32.ini lib_deps and HAL_RTC_MODULE_ENABLED to build_flags. LTO strips the unused RTC code on HAS_RTC=0 boards.

Coincidentally this also fixes an issue for STM32 targets, where they previously fell through to a gettimeofday() fallback in readFromRTC() that returns millis()/1000 on STM32duino — not a Unix timestamp — silently corrupting zeroOffsetSecs on first boot.

Also changed incorrect include convention for RTC.h in src/graphics/draw/UIRenderer.cpp and src/mesh/PhoneAPI.cpp which caused clashing includes with STM32's rtc.h on case-insensitive file systems.

Implemented to Wio-E5, RAK3172 and Russell variant (Russell build will fail due to another bug, fix in #10097).

🤝 Attestations

  • I have tested that my proposed changes behave as described.
  • I have tested that my proposed changes do not cause any obvious regressions on the following devices:
    • Heltec (Lora32) V3
    • LilyGo T-Deck
    • LilyGo T-Beam
    • RAK WisBlock 4631
    • Seeed Studio T-1000E tracker card
    • Other (please specify below)
      • RAK3172
      • Wio-E5

@github-actions github-actions Bot added needs-review Needs human review hardware-support Hardware related: new devices or modules, problems specific to hardware labels Apr 8, 2026
@ndoo
Copy link
Copy Markdown
Contributor Author

ndoo commented Apr 8, 2026

Force-pushed with an additional comment in stm32.ini to explain this line,

-iquote src/gps ; Required due to overlap of src/gps/RTC.h and STM32 rtc.h on case-insensitive filesystems

@ndoo ndoo force-pushed the feat/stm32-rtc branch from 794121e to bd62f44 Compare April 8, 2026 05:05
@ndoo ndoo marked this pull request as ready for review April 9, 2026 16:46
@jp-bennett jp-bennett requested a review from Copilot April 10, 2026 19:28
@jp-bennett
Copy link
Copy Markdown
Collaborator

This looks very interesting.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds STM32WL hardware-RTC support backed by the STM32duino STM32RTC library (LSE clock source) and fixes RTC header include collisions on STM32 case-insensitive filesystems.

Changes:

  • Implement STM32WL (ARCH_STM32WL) readFromRTC() / perhapsSetRTC() support using STM32RTC when HAS_RTC=1.
  • Enable RTC usage on specific STM32 variants by defining HAS_RTC and per-board RCC_LSEDRIVE_CONFIG.
  • Update STM32 build config and switch several includes from <RTC.h> to "RTC.h" to avoid clashing with STM32 rtc.h.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
variants/stm32/wio-e5/variant.h Enables RTC via HAS_RTC and sets LSE drive strength for Wio-E5.
variants/stm32/rak3172/variant.h Enables RTC via HAS_RTC and sets LSE drive strength for RAK3172.
variants/stm32/russell/variant.h Enables RTC via HAS_RTC and sets LSE drive strength for Russell.
variants/stm32/stm32.ini Adds STM32RTC dependency and adjusts include search path to prefer project RTC.h.
src/gps/RTC.cpp Adds STM32WL RTC read/set logic using STM32RTC (guarded by HAS_RTC).
src/mqtt/MQTT.cpp Switches to "RTC.h" include form.
src/mesh/PhoneAPI.cpp Switches to "RTC.h" include form.
src/graphics/draw/UIRenderer.cpp Switches to "RTC.h" include form.

Comment thread src/gps/RTC.cpp
Comment thread variants/stm32/stm32.ini
@ndoo
Copy link
Copy Markdown
Contributor Author

ndoo commented Apr 11, 2026

Review feedback addressed + build test ✅

Resolved both Copilot review threads:

  • src/gps/RTC.cpp — added oldQuality capture and triggerNodeInfoCheckOnTimeSource(oldQuality, currentQuality) call in the STM32WL HAS_RTC branch (commit ad84594), matching the pattern used in all other RTC branches. Thread resolved.
  • variants/stm32/stm32.ini — no code change needed; HAL_RTC_MODULE_ENABLED is already unconditionally defined in stm32wlxx_hal_conf_default.h line 56 (part of the Arduino STM32 framework). The -DHAL_DAC_MODULE_ONLY flag only gates DAC usage in analog.h and does not suppress any other HAL module. Thread resolved.

Build-tested the two variants with HAS_RTC=1 added in this PR (Russell excluded — blocked by separate issue being fixed in #10097):

Environment    Status    Duration
-------------  --------  ------------
wio-e5         SUCCESS   00:00:29.404
rak3172        SUCCESS   00:00:28.117
========================= 2 succeeded in 00:00:57.521 =========================

RAM: 33.0% (21640 / 65536 bytes)
Flash: 76.8% (179304 / 233472 bytes) ← rak3172 (smaller of the two targets)

@ndoo
Copy link
Copy Markdown
Contributor Author

ndoo commented Apr 11, 2026

Do tag as ai-generated, sorry.

I use the RTC extensively at my day job for sleep of ~24 hours, the STM32 consumes vanishingly little power in deep sleeps like that (edit: usually over a year of battery life on 2x 19Ah Li-SOCl2 batteries if LoRa is used for just sensor rather than kept on for mesh). Not sure that particular use case is useful to Meshtastic in general but it may come in handy in future if STM32LowPower is implemented so that sensor roles can deep sleep.

For now, it’s just plugging a hole in feature support for STM32 (RTC).

Edit: That being said, the core implementation is CC generated:

  • ddbeffe: feat(stm32): implement LSE-backed hardware RTC using STM32RTC library
  • b76c7b5: fix(stm32): trigger NodeInfo recheck on STM32 RTC time acquisition

However, I did point CC to my existing repos from other projects that use STM32RTC and also provide the LSE drive level init sequencing and cut out some register writes I know from my other projects are not needed.

While these are added by myself for testing the implementation:

  • ea136d3: feat(rak3172,russell): enable LSE hardware RTC
  • 1ccf90a: feat(wio-e5): enable LSE hardware RTC

@ndoo
Copy link
Copy Markdown
Contributor Author

ndoo commented Apr 11, 2026

I need to add another check to prevent the RTC readback from setting the clock to 1970, by checking against build time.

It looks like STM32RTC sometimes thinks it's set when it was set with epoch 0 somehow.

ndoo added 4 commits April 14, 2026 23:28
Add a proper ARCH_STM32WL branch in readFromRTC() and perhapsSetRTC()
backed by the STM32duino STM32RTC library (1.9.0), using the hardware
RTC peripheral with LSE_CLOCK as the clock source. The branch is guarded
by HAS_RTC, which should be set to 1 only in variant files for boards
that have a 32.768kHz LSE crystal populated.

The LSE drive strength is configured per-board via RCC_LSEDRIVE_CONFIG
(one of the RCC_LSEDRIVE_* values), set before begin() so it takes
effect before the library starts the LSE oscillator. When HAS_RTC=0,
the branch returns RTCSetResultNotSet immediately without touching
zeroOffsetSecs, bypassing the broken gettimeofday() fallback.

Add STM32duino RTC to stm32.ini lib_deps and HAL_RTC_MODULE_ENABLED to
build_flags. LTO strips the unused RTC code on HAS_RTC=0 boards.

Coincidentally this also fixes an issue for STM32 targets, where they
previously fell through to a gettimeofday() fallback in readFromRTC()
that returns millis()/1000 on STM32duino — not a Unix timestamp —
silently corrupting zeroOffsetSecs on first boot.

Also changed incorrect include convention for RTC.h in
src/graphics/draw/UIRenderer.cpp and src/mesh/PhoneAPI.cpp which caused
clashing includes with STM32's rtc.h on case-insensitive file systems.

Build-tested on:
* rak3172
* wio-e5

No regressions expected as HAS_RTC gates the inclusion of STM32RTC.

Signed-off-by: Andrew Yong <me@ndoo.sg>
Assisted-by: Claude:claude-sonnet-4-6
RAK3172 has a built-in 32.768 kHz LSE crystal so we can expect built-in
RTC to be functional.

Enable HAS_RTC and configure the LSE drive level for the RAK3172.

LSE drive level from here:
https://github.com/RAKWireless/RAK-STM32-RUI/blob/main/variants/WisDuo_RAK3172_Evaluation_Board/rui_inner_main.c

Also added the same defines for russell which uses the RAK3172 module.

Build-tested on:
* rak3172
* wio-e5 (no changes, just a regression test)

Couldn't build test russell due to build errors fixed in meshtastic#10097.

Signed-off-by: Andrew Yong <me@ndoo.sg>
Wio-E5 has a built-in 32.768 kHz LSE crystal, so we can expect built-in
RTC to be functional.

Enable HAS_RTC and configure the LSE drive level for the Wio-E5.

LSE drive level from here:
https://github.com/Seeed-Studio/LoRaWan-E5-Node/blob/main/Projects/Applications/LoRaWAN/LoRaWAN_End_Node/Core/Src/main.c

Tested on:
* wio-e5 (Wio-E5 Dev Kit mini)

Signed-off-by: Andrew Yong <me@ndoo.sg>
Mirror the triggerNodeInfoCheckOnTimeSource() pattern used in all other
RTC branches so NodeInfo is rechecked when the STM32WL RTC first provides
a valid time source.

Signed-off-by: Andrew Yong <me@ndoo.sg>
@ndoo
Copy link
Copy Markdown
Contributor Author

ndoo commented Apr 14, 2026

I’ll re-open a new one once I have done some cleanup, working with time is always fraught with problems (and ironically, burns lots of time)

@ndoo ndoo closed this Apr 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hardware-support Hardware related: new devices or modules, problems specific to hardware needs-review Needs human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants