Skip to content

Commit 97fef11

Browse files
STM32L4: Fix sleep implementation
Correctly detect and handle the low power run mode when entering and exiting sleep mode. The generic `hal_sleep` implementation tries to exit LPR mode always, resulting in a spin-loop during a critical section (disabled IRQ). The new approach returns from LPR to Run mode if enabled (LPR bit set), enters sleep, and resets to the original state on wakeup (WFI).
1 parent 2a824a1 commit 97fef11

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

targets/TARGET_STM/sleep.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,34 @@ void hal_sleep(void)
151151
core_util_critical_section_enter();
152152

153153
// Request to enter SLEEP mode
154+
#if TARGET_STM32L4
155+
// State Transitions (see 5.3 Low-power modes, Fig. 13):
156+
// * (opt): Low Power Run (LPR) Mode -> Run Mode
157+
// * Run Mode -> Sleep
158+
// --- Wait for Interrupt --
159+
// * Sleep -> Run Mode
160+
// * (opt): Run Mode -> Low Power Run Mode
161+
162+
// [5.4.1 Power control register 1 (PWR_CR1)]
163+
// LPR: When this bit is set, the regulator is switched from main mode (MR) to low-power mode (LPR).
164+
int lowPowerMode = PWR->CR1 & PWR_CR1_LPR;
165+
166+
// LPR -> Run
167+
if (lowPowerMode) {
168+
HAL_PWREx_DisableLowPowerRunMode();
169+
}
170+
171+
// Entering Sleep mode [5.3.4 Sleep mode]
172+
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); // SLEEPDEEP = 0
173+
__WFI();
174+
175+
// Run -> LPR
176+
if (lowPowerMode) {
177+
HAL_PWREx_EnableLowPowerRunMode();
178+
}
179+
#else
154180
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
181+
#endif
155182

156183
// Enable IRQs
157184
core_util_critical_section_exit();

0 commit comments

Comments
 (0)