@@ -224,13 +224,172 @@ void LowPower_EnableWakeUpPin(uint32_t pin, uint32_t mode)
224
224
}
225
225
}
226
226
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
+
227
378
/**
228
379
* @brief Enable the sleep mode.
229
380
* @param None
230
381
* @retval None
231
382
*/
232
383
void LowPower_sleep (uint32_t regulator )
233
384
{
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
+
234
393
/*
235
394
* Suspend Tick increment to prevent wakeup by Systick interrupt.
236
395
* Otherwise the Systick interrupt will wake up the device within
@@ -241,6 +400,19 @@ void LowPower_sleep(uint32_t regulator)
241
400
/* Enter Sleep Mode , wake up is done once User push-button is pressed */
242
401
HAL_PWR_EnterSLEEPMode (regulator , PWR_SLEEPENTRY_WFI );
243
402
403
+ #if defined(PWR_CSR_REGLPF ) || defined(PWR_SR2_REGLPF )
404
+ // In case of LowPower Regulator used for sleep, restore Main regulator on exit
405
+ if (regulator == PWR_LOWPOWERREGULATOR_ON ) {
406
+ #if defined(__HAL_RCC_PWR_CLK_ENABLE )
407
+ __HAL_RCC_PWR_CLK_ENABLE ();
408
+ #endif
409
+ HAL_PWREx_DisableLowPowerRunMode ();
410
+
411
+ // Restore systemClock which has been decreased by SystemClock_Decrease()
412
+ SystemClock_Config ();
413
+ }
414
+ #endif
415
+
244
416
/* Resume Tick interrupt if disabled prior to SLEEP mode entry */
245
417
HAL_ResumeTick ();
246
418
0 commit comments