@@ -224,13 +224,172 @@ 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+
268+ #elif defined(STM32L4xx ) || defined(STM32L5xx ) || defined(STM32WBxx ) || defined(STM32WLxx )
269+ /**
270+ * @brief For STM32L4, STM32L5, STM32WB and STM32WL
271+ * running in LowPower Sleep requires to slow down frequency to 2MHz max.
272+ * @retval None
273+ */
274+ void SystemClock_Decrease (void )
275+ {
276+ RCC_OscInitTypeDef RCC_OscInitStruct = {};
277+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
278+
279+ /** Configure the main internal regulator output voltage
280+ */
281+ #if defined(STM32L4xx ) || defined(STM32WBxx )
282+ if (HAL_PWREx_ControlVoltageScaling (PWR_REGULATOR_VOLTAGE_SCALE1 ) != HAL_OK )
283+ #elif defined(STM32L5xx ) || defined(STM32WLxx )
284+ if (HAL_PWREx_ControlVoltageScaling (PWR_REGULATOR_VOLTAGE_SCALE2 ) != HAL_OK )
285+ #endif
286+ {
287+ Error_Handler ();
288+ }
289+
290+ /** Initializes the RCC Oscillators according to the specified parameters
291+ * in the RCC_OscInitTypeDef structure.
292+ */
293+ RCC_OscInitStruct .OscillatorType = RCC_OSCILLATORTYPE_MSI ;
294+ RCC_OscInitStruct .MSIState = RCC_MSI_ON ;
295+ RCC_OscInitStruct .MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT ;
296+ RCC_OscInitStruct .MSIClockRange = RCC_MSIRANGE_5 ;
297+ RCC_OscInitStruct .PLL .PLLState = RCC_PLL_NONE ;
298+ if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) != HAL_OK ) {
299+ Error_Handler ();
300+ }
301+
302+ /** Initializes the CPU and buses clocks
303+ */
304+ #if defined(STM32WBxx )
305+ RCC_ClkInitStruct .ClockType = RCC_CLOCKTYPE_HCLK4 | RCC_CLOCKTYPE_HCLK2
306+ | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
307+ | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 ;
308+ RCC_ClkInitStruct .AHBCLK2Divider = RCC_SYSCLK_DIV1 ;
309+ RCC_ClkInitStruct .AHBCLK4Divider = RCC_SYSCLK_DIV1 ;
310+ #elif defined(STM32WLxx )
311+ RCC_ClkInitStruct .ClockType = RCC_CLOCKTYPE_HCLK3 | RCC_CLOCKTYPE_HCLK
312+ | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1
313+ | RCC_CLOCKTYPE_PCLK2 ;
314+ RCC_ClkInitStruct .AHBCLK3Divider = RCC_SYSCLK_DIV1 ;
315+ #elif defined(STM32L4xx )
316+ RCC_ClkInitStruct .ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
317+ | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 ;
318+ #endif
319+ RCC_ClkInitStruct .SYSCLKSource = RCC_SYSCLKSOURCE_MSI ;
320+ RCC_ClkInitStruct .AHBCLKDivider = RCC_SYSCLK_DIV1 ;
321+ RCC_ClkInitStruct .APB1CLKDivider = RCC_HCLK_DIV1 ;
322+ RCC_ClkInitStruct .APB2CLKDivider = RCC_HCLK_DIV1 ;
323+
324+ if (HAL_RCC_ClockConfig (& RCC_ClkInitStruct , FLASH_LATENCY_0 ) != HAL_OK ) {
325+ Error_Handler ();
326+ }
327+ }
328+
329+ #elif defined(STM32G0xx ) || defined(STM32G4xx )
330+ /**
331+ * @brief For STM32G0 and STM32G4
332+ * running in LowPower Sleep requires to slow down frequency to 2MHz max.
333+ * @retval None
334+ */
335+ void SystemClock_Decrease (void )
336+ {
337+ RCC_OscInitTypeDef RCC_OscInitStruct = {};
338+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
339+
340+ /** Configure the main internal regulator output voltage
341+ */
342+ HAL_PWREx_ControlVoltageScaling (PWR_REGULATOR_VOLTAGE_SCALE1 );
343+
344+ /** Initializes the RCC Oscillators according to the specified parameters
345+ * in the RCC_OscInitTypeDef structure.
346+ */
347+ RCC_OscInitStruct .OscillatorType = RCC_OSCILLATORTYPE_HSI ;
348+ RCC_OscInitStruct .HSIState = RCC_HSI_ON ;
349+ #if defined(STM32G0xx )
350+ RCC_OscInitStruct .HSIDiv = RCC_HSI_DIV1 ;
351+ #endif
352+ RCC_OscInitStruct .HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT ;
353+ RCC_OscInitStruct .PLL .PLLState = RCC_PLL_NONE ;
354+ if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) != HAL_OK ) {
355+ Error_Handler ();
356+ }
357+
358+ /** Initializes the CPU, AHB and APB buses clocks
359+ */
360+ #if defined(STM32G4xx )
361+ RCC_ClkInitStruct .ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
362+ | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 ;
363+ RCC_ClkInitStruct .APB2CLKDivider = RCC_HCLK_DIV1 ;
364+ #elif defined(STM32G0xx )
365+ RCC_ClkInitStruct .ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
366+ | RCC_CLOCKTYPE_PCLK1 ;
367+ #endif
368+ RCC_ClkInitStruct .SYSCLKSource = RCC_SYSCLKSOURCE_HSI ;
369+ RCC_ClkInitStruct .AHBCLKDivider = RCC_SYSCLK_DIV8 ;
370+ RCC_ClkInitStruct .APB1CLKDivider = RCC_HCLK_DIV1 ;
371+
372+ if (HAL_RCC_ClockConfig (& RCC_ClkInitStruct , FLASH_LATENCY_0 ) != HAL_OK ) {
373+ Error_Handler ();
374+ }
375+ }
376+ #endif
377+
227378/**
228379 * @brief Enable the sleep mode.
229380 * @param None
230381 * @retval None
231382 */
232383void LowPower_sleep (uint32_t regulator )
233384{
385+
386+ #if defined(PWR_CSR_REGLPF ) || defined(PWR_SR2_REGLPF )
387+ // When LowPower regulator sleep mode is used, it is necessary to decrease CPU Frequency
388+ if (regulator == PWR_LOWPOWERREGULATOR_ON ) {
389+ SystemClock_Decrease ();
390+ }
391+ #endif
392+
234393 /*
235394 * Suspend Tick increment to prevent wakeup by Systick interrupt.
236395 * Otherwise the Systick interrupt will wake up the device within
@@ -246,6 +405,9 @@ void LowPower_sleep(uint32_t regulator)
246405 if (regulator == PWR_LOWPOWERREGULATOR_ON ) {
247406 __HAL_RCC_PWR_CLK_ENABLE ();
248407 HAL_PWREx_DisableLowPowerRunMode ();
408+
409+ // Restore systemClock which has been decreased by SystemClock_Decrease()
410+ SystemClock_Config ();
249411 }
250412#endif
251413
0 commit comments