@@ -224,13 +224,170 @@ void LowPower_EnableWakeUpPin(uint32_t pin, uint32_t mode)
224224 }
225225}
226226
227+ #if defined(PWR_CSR_REGLPF )
228+ /**
229+ * @brief For STM32L0 and STM32L1, running in LowPower Sleep requires
230+ * to slow down frequency to MSI range1.
231+ * @retval None
232+ */
233+ void SystemClock_Decrease (void )
234+ {
235+ RCC_OscInitTypeDef RCC_OscInitStruct = {};
236+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
237+
238+ /** Configure the main internal regulator output voltage
239+ */
240+ __HAL_PWR_VOLTAGESCALING_CONFIG (PWR_REGULATOR_VOLTAGE_SCALE1 );
241+
242+ /** Initializes the RCC Oscillators according to the specified parameters
243+ * in the RCC_OscInitTypeDef structure.
244+ */
245+ RCC_OscInitStruct .OscillatorType = RCC_OSCILLATORTYPE_MSI ;
246+ RCC_OscInitStruct .MSIState = RCC_MSI_ON ;
247+ RCC_OscInitStruct .MSICalibrationValue = 0 ;
248+ RCC_OscInitStruct .MSIClockRange = RCC_MSIRANGE_1 ;
249+ RCC_OscInitStruct .PLL .PLLState = RCC_PLL_NONE ;
250+ if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) != HAL_OK ) {
251+ Error_Handler ();
252+ }
253+
254+ /** Initializes the CPU, AHB and APB buses clocks
255+ */
256+ RCC_ClkInitStruct .ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
257+ | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 ;
258+ RCC_ClkInitStruct .SYSCLKSource = RCC_SYSCLKSOURCE_MSI ;
259+ RCC_ClkInitStruct .AHBCLKDivider = RCC_SYSCLK_DIV1 ;
260+ RCC_ClkInitStruct .APB1CLKDivider = RCC_HCLK_DIV1 ;
261+ RCC_ClkInitStruct .APB2CLKDivider = RCC_HCLK_DIV1 ;
262+
263+ if (HAL_RCC_ClockConfig (& RCC_ClkInitStruct , FLASH_LATENCY_0 ) != HAL_OK ) {
264+ Error_Handler ();
265+ }
266+ }
267+ #elif defined(STM32L4xx ) || defined(STM32L5xx ) || defined(STM32WBxx ) || defined(STM32WLxx )
268+ /**
269+ * @brief For STM32L4, STM32L5, STM32WB and STM32WL
270+ * running in LowPower Sleep requires to slow down frequency to 2MHz max.
271+ * @retval None
272+ */
273+ void SystemClock_Decrease (void )
274+ {
275+ RCC_OscInitTypeDef RCC_OscInitStruct = {};
276+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
277+
278+ /** Configure the main internal regulator output voltage
279+ */
280+ #if defined(STM32L4xx ) || defined(STM32WBxx )
281+ if (HAL_PWREx_ControlVoltageScaling (PWR_REGULATOR_VOLTAGE_SCALE1 ) != HAL_OK )
282+ #elif defined(STM32L5xx ) || defined(STM32WLxx )
283+ if (HAL_PWREx_ControlVoltageScaling (PWR_REGULATOR_VOLTAGE_SCALE2 ) != HAL_OK )
284+ #endif
285+ {
286+ Error_Handler ();
287+ }
288+
289+ /** Initializes the RCC Oscillators according to the specified parameters
290+ * in the RCC_OscInitTypeDef structure.
291+ */
292+ RCC_OscInitStruct .OscillatorType = RCC_OSCILLATORTYPE_MSI ;
293+ RCC_OscInitStruct .MSIState = RCC_MSI_ON ;
294+ RCC_OscInitStruct .MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT ;
295+ RCC_OscInitStruct .MSIClockRange = RCC_MSIRANGE_5 ;
296+ RCC_OscInitStruct .PLL .PLLState = RCC_PLL_NONE ;
297+ if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) != HAL_OK ) {
298+ Error_Handler ();
299+ }
300+
301+ /** Initializes the CPU and buses clocks
302+ */
303+ #if defined(STM32WBxx )
304+ RCC_ClkInitStruct .ClockType = RCC_CLOCKTYPE_HCLK4 | RCC_CLOCKTYPE_HCLK2
305+ | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
306+ | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 ;
307+ RCC_ClkInitStruct .AHBCLK2Divider = RCC_SYSCLK_DIV1 ;
308+ RCC_ClkInitStruct .AHBCLK4Divider = RCC_SYSCLK_DIV1 ;
309+ #elif defined(STM32WLxx )
310+ RCC_ClkInitStruct .ClockType = RCC_CLOCKTYPE_HCLK3 | RCC_CLOCKTYPE_HCLK
311+ | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1
312+ | RCC_CLOCKTYPE_PCLK2 ;
313+ RCC_ClkInitStruct .AHBCLK3Divider = RCC_SYSCLK_DIV1 ;
314+ #elif defined(STM32L4xx )
315+ RCC_ClkInitStruct .ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
316+ | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 ;
317+ #endif
318+ RCC_ClkInitStruct .SYSCLKSource = RCC_SYSCLKSOURCE_MSI ;
319+ RCC_ClkInitStruct .AHBCLKDivider = RCC_SYSCLK_DIV1 ;
320+ RCC_ClkInitStruct .APB1CLKDivider = RCC_HCLK_DIV1 ;
321+ RCC_ClkInitStruct .APB2CLKDivider = RCC_HCLK_DIV1 ;
322+
323+ if (HAL_RCC_ClockConfig (& RCC_ClkInitStruct , FLASH_LATENCY_0 ) != HAL_OK ) {
324+ Error_Handler ();
325+ }
326+ }
327+ #elif defined(STM32G0xx ) || defined(STM32G4xx )
328+ /**
329+ * @brief For STM32G0 and STM32G4
330+ * running in LowPower Sleep requires to slow down frequency to 2MHz max.
331+ * @retval None
332+ */
333+ void SystemClock_Config (void )
334+ {
335+ RCC_OscInitTypeDef RCC_OscInitStruct = {};
336+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
337+
338+ /** Configure the main internal regulator output voltage
339+ */
340+ HAL_PWREx_ControlVoltageScaling (PWR_REGULATOR_VOLTAGE_SCALE1 );
341+
342+ /** Initializes the RCC Oscillators according to the specified parameters
343+ * in the RCC_OscInitTypeDef structure.
344+ */
345+ RCC_OscInitStruct .OscillatorType = RCC_OSCILLATORTYPE_HSI ;
346+ RCC_OscInitStruct .HSIState = RCC_HSI_ON ;
347+ #if defined(STM32G0xx )
348+ RCC_OscInitStruct .HSIDiv = RCC_HSI_DIV1 ;
349+ #endif
350+ RCC_OscInitStruct .HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT ;
351+ RCC_OscInitStruct .PLL .PLLState = RCC_PLL_NONE ;
352+ if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) != HAL_OK ) {
353+ Error_Handler ();
354+ }
355+
356+ /** Initializes the CPU, AHB and APB buses clocks
357+ */
358+ #if defined(STM32G4xx )
359+ RCC_ClkInitStruct .ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
360+ | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 ;
361+ RCC_ClkInitStruct .APB2CLKDivider = RCC_HCLK_DIV1 ;
362+ #elif defined(STM32G0xx )
363+ RCC_ClkInitStruct .ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
364+ | RCC_CLOCKTYPE_PCLK1 ;
365+ #endif
366+ RCC_ClkInitStruct .SYSCLKSource = RCC_SYSCLKSOURCE_HSI ;
367+ RCC_ClkInitStruct .AHBCLKDivider = RCC_SYSCLK_DIV8 ;
368+ RCC_ClkInitStruct .APB1CLKDivider = RCC_HCLK_DIV1 ;
369+
370+ if (HAL_RCC_ClockConfig (& RCC_ClkInitStruct , FLASH_LATENCY_0 ) != HAL_OK ) {
371+ Error_Handler ();
372+ }
373+ }
374+
375+ #endif
376+
227377/**
228378 * @brief Enable the sleep mode.
229379 * @param None
230380 * @retval None
231381 */
232382void LowPower_sleep (uint32_t regulator )
233383{
384+
385+ #if defined(PWR_CSR_REGLPF ) || defined(PWR_SR2_REGLPF )
386+ // When LowPower regulator sleep mode is used, it is necessary to decrease CPU Frequency
387+ if (regulator == PWR_LOWPOWERREGULATOR_ON ) {
388+ SystemClock_Decrease ();
389+ }
390+ #endif
234391 /*
235392 * Suspend Tick increment to prevent wakeup by Systick interrupt.
236393 * Otherwise the Systick interrupt will wake up the device within
@@ -246,7 +403,12 @@ void LowPower_sleep(uint32_t regulator)
246403 if (regulator == PWR_LOWPOWERREGULATOR_ON ) {
247404 __HAL_RCC_PWR_CLK_ENABLE ();
248405 HAL_PWREx_DisableLowPowerRunMode ();
406+
407+ // Restore systemClock which has been decreased by SystemClock_Decrease()
408+ SystemClock_Config ();
249409 }
410+
411+
250412#endif
251413
252414 /* Resume Tick interrupt if disabled prior to SLEEP mode entry */
0 commit comments