STM32WB5MMG (WB55) enters Stop2 (~7 µA) only after a debugger-mediated reset, never after a cold power-on reset (POR) — ~9 mA instead. All M4-vi
- June 23, 2026
- 0 replies
- 22 views
Summary
On an STM32WB5MMG module (STEVAL-PROTEUS1), with BLE advertising active and the
application configured for Stop2 low-power operation, the device reaches the
expected Stop2 sleep current (p50 ~ 7 uA) ONLY after a debugger-mediated reset
(STM32CubeProgrammer: -c port=SWD mode=UR -rst).
After a cold power-on reset (POR) - removing and reapplying the supply, the real
deployment scenario - it draws a constant ~9 mA and never enters Stop2, even
though it otherwise runs completely normally (RTC cycle runs, BLE advertising
works, application data updates). This is 100% reproducible and deterministic.
Deployment-critical: in the field the customer inserts the battery (= POR) -> 9 mA
-> a 10 Ah cell lasts ~47 days instead of the intended multi-year lifetime.
Hardware / Software
- MCU/Module: STM32WB5MMG (STM32WB55 die) on STEVAL-PROTEUS1.
- Wireless stack: BLE_Stack_full V1.24.0.3 + FUS v2.2.0. First seen on V1.19.0 /
FUS v1.2.0 and UNCHANGED after upgrading to V1.24.0 (the stack update did not fix it).
- RF config: Tx power 0 dBm, PHY 1 Mbit/s, channels 37/38/39, advertising via
aci_gap_additional_beacon_start (rotating MAC), advertising interval 5 s.
- Low power: CubeWB tiny_lpm, CFG_LPM_SUPPORTED=1, Stop2 (LPMS=0b010),
CFG_BLE_LS_SOURCE = LSE. Production build (CFG_DEBUGGER_SUPPORTED=0, DBGMCU
low-power debug bits cleared at boot).
- Tools: STM32CubeIDE, STM32CubeProgrammer v2.22.0, ST-LINK/V3.
- Power/measurement: Nordic PPK2 in source mode @ 3.6 V (independent of ST-LINK;
ST-LINK detached makes no difference - confirmed).
Reproduction (deterministic)
Reset type Result
------------------------------------------ ---------------------------------
mode=UR -rst (debugger-mediated reset) sleeps, p50 = 7 uA (OK)
Power-On Reset (supply off/on) ~9 mA constant, no Stop2 (BUG)
Identical firmware image in both cases. The only difference is how the chip was
last reset.
What is already ruled out (measured on-target via SWD + compiled-in counters)
Application / LPM framework is NOT the cause:
- After POR all LPM gates are open: LPM_disabled = 0, LPM_disabled_forced = 0,
CPU2_started = 1. The idle hook (UTIL_SEQ_Idle) is reached and calls
UTIL_LPM_EnterLowPower() repeatedly. UTIL_LPM_SetStopMode(DISABLE) is never called.
- Wireless "FW running" ready event fires exactly once (no stack re-init loop).
- Disabling the sensor/measurement entirely -> still 9 mA after POR.
- Replacing the whole measurement layer with a pure software stub (no I2C/SPI/BSP/
sensor access) -> still ~9 mA after POR (so the entire application layer is excluded).
- Disabling advertising (aci_gap_additional_beacon_start compiled out) -> still 9 mA.
CPU2 IS in deep-sleep after POR (so it is not "CPU2 refusing deep-sleep").
LL_PWR_IsActiveFlag_C2DS() counted in EnterLowPower:
State Current lpm_calls C2DS (CPU2 deep-sleep)
----------------- -------- ---------- ----------------------
-rst (sleeps) 7 uA 37 35
POR (9 mA) 8.9 mA 84 80
Same ratio -> CPU2 reaches deep-sleep in both cases.
WFI entry rate identical: counters before/after __WFI in the Stop2 path:
-rst 34 / POR 30 over 42 s. So the M4 enters Stop2 the same way and is sitting in
WFI at the snapshot; the ~9 mA is drawn during a genuine Stop2, not in a busy loop.
Register snapshot at the Stop2 __WFI instant, POR vs -rst - all M4-visible Stop2
registers are bit-identical except the reset-cause flag:
Register -rst (7 uA) POR (9 mA)
------------------------ -------------- --------------
SCB_SCR (SLEEPDEEP) 0x00000004 0x00000004
PWR_CR1 (LPMS=Stop2) 0x00000302 0x00000302
PWR_C2CR1 0x00000004 0x00000004
PWR_EXTSCR 0x00008200 0x00008200
RCC_CR 0x03030560 0x03030560
RCC_CFGR 0x00078005 0x00078005
RCC_EXTCFGR 0x00130000 0x00130000
RCC_CSR (reset cause) 0x04000000 0x0C000000
(PINRSTF) (PINRSTF + BORRSTF)
RFWKPSEL = 0b00 in both cases (RF wake-up clock identical -> ES0394 2.3.1 excluded).
Self-heal via firmware reset does not work: NVIC_SystemReset (SYSRESETREQ) and an
IWDG reset both reset only the CPU1 subsystem; the device stays at 9 mA. A heal
counter in RTC->BKP1R proved the reset fired exactly once (no loop). Only the NRST
pin or a POR resets CPU2.
Errata checked (ES0394): 2.2.8 (EXTI line 48 / CDBGPWRUPREQ) - masked the line
before Stop2, no effect. 2.3.1 (RF wake-up clock) - excluded (RFWKPSEL=00). 2.2.17
(debug-in-stop) - debug bits off in the production build. No erratum matches 1:1.
SHCI: SHCI_C2_RADIO_AllowLowPower(BLE_IP, 1) called explicitly after APP_BLE_Init
-> no effect (default already applies).
Conclusion / hypothesis: since every M4-visible digital register is identical
between the 7 uA and the 9 mA case, and both cores are in deep-sleep, the extra
~9 mA must come from the RF / analog power management of the radio coprocessor
(CPU2) at cold start: after a cold POR the RF analog domain does not enter its
low-power state, whereas a debugger-mediated reset leaves CPU2 in a state where it
does. The only digital difference we can see is BORRSTF being set on POR.
Questions
1. Is there a known issue / expected behavior where the STM32WB radio (CPU2)
RF/analog domain does NOT reach the expected Stop2 current after a cold POR,
but does after a debugger-mediated reset (CPU2/debug stays "warm")?
2. Is there a required CPU2 / SHCI cold-start sequence or RF low-power handshake
that differs between a cold POR and a warm/debug reset, that the application
must perform explicitly?
3. Is there a software-only way to bring the CPU2 RF subsystem into the
Stop2-capable state after POR (so we do not need an external GPIO->NRST hardware
mod to pulse a real CPU2 reset)?
4. Can BORRSTF vs PINRSTF (reset cause) influence the CPU2 RF power-management
initialization? Is there a recommended action when BORRSTF is set at boot?
5. Is any specific SHCI command or option (beyond SHCI_C2_RADIO_AllowLowPower)
required at cold start to enable RF analog low-power in Stop2?
Attachments
- Register snapshot after -rst (7 uA, good).
- Register snapshot after POR (~9 mA, bug).
- Minimal reproducer project on request.
