1 /**
2   ******************************************************************************
3   * @file    stm32wbxx_hal_pwr_ex.c
4   * @author  MCD Application Team
5   * @brief   Extended PWR HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Power Controller (PWR) peripheral:
8   *           + Extended Initialization and de-initialization functions
9   *           + Extended Peripheral Control functions
10   *
11   ******************************************************************************
12   * @attention
13   *
14   * Copyright (c) 2019 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   */
23 
24 /* Includes ------------------------------------------------------------------*/
25 #include "stm32wbxx_hal.h"
26 
27 /** @addtogroup STM32WBxx_HAL_Driver
28   * @{
29   */
30 
31 /** @addtogroup PWREx
32   * @{
33   */
34 
35 #ifdef HAL_PWR_MODULE_ENABLED
36 
37 /* Private typedef -----------------------------------------------------------*/
38 /* Private define ------------------------------------------------------------*/
39 /** @defgroup PWR_Extended_Private_Defines PWR Extended Private Defines
40   * @{
41   */
42 #define PWR_PORTE_AVAILABLE_PINS   (PWR_GPIO_BIT_4 | PWR_GPIO_BIT_3 | PWR_GPIO_BIT_2 | PWR_GPIO_BIT_1 | PWR_GPIO_BIT_0)
43 #define PWR_PORTH_AVAILABLE_PINS   (PWR_GPIO_BIT_3 | PWR_GPIO_BIT_1 | PWR_GPIO_BIT_0)
44 
45 /** @defgroup PWREx_TimeOut_Value PWR Extended Flag Setting Time Out Value
46   * @{
47   */
48 #define PWR_FLAG_SETTING_DELAY_US                      50U   /*!< Time out value for REGLPF and VOSF flags setting */
49 /**
50   * @}
51   */
52 
53 /**
54   * @}
55   */
56 
57 
58 
59 /* Private macro -------------------------------------------------------------*/
60 /* Private variables ---------------------------------------------------------*/
61 /* Private function prototypes -----------------------------------------------*/
62 /* Exported functions --------------------------------------------------------*/
63 /** @addtogroup PWREx_Exported_Functions PWR Extended Exported Functions
64   * @{
65   */
66 
67 /** @addtogroup PWREx_Exported_Functions_Group1 Extended Peripheral Control functions
68   *  @brief   Extended Peripheral Control functions
69   *
70 @verbatim
71  ===============================================================================
72               ##### Extended Peripheral Initialization and de-initialization functions #####
73  ===============================================================================
74     [..]
75 
76 @endverbatim
77   * @{
78   */
79 
80 
81 #if defined(PWR_CR1_VOS)
82 /**
83   * @brief Return Voltage Scaling Range.
84   * @retval VOS bit field (PWR_REGULATOR_VOLTAGE_RANGE1 or PWR_REGULATOR_VOLTAGE_RANGE2)
85   */
HAL_PWREx_GetVoltageRange(void)86 uint32_t HAL_PWREx_GetVoltageRange(void)
87 {
88   return (PWR->CR1 & PWR_CR1_VOS);
89 }
90 
91 /**
92   * @brief Configure the main internal regulator output voltage.
93   * @param VoltageScaling specifies the regulator output voltage to achieve
94   *         a tradeoff between performance and power consumption.
95   *          This parameter can be one of the following values:
96   *            @arg @ref PWR_REGULATOR_VOLTAGE_SCALE1 Regulator voltage output range 1 mode,
97   *                                                typical output voltage at 1.2 V,
98   *                                                system frequency up to 64 MHz.
99   *            @arg @ref PWR_REGULATOR_VOLTAGE_SCALE2 Regulator voltage output range 2 mode,
100   *                                                typical output voltage at 1.0 V,
101   *                                                system frequency up to 16 MHz.
102   * @note  When moving from Range 1 to Range 2, the system frequency must be decreased to
103   *        a value below 16 MHz before calling HAL_PWREx_ControlVoltageScaling() API.
104   *        When moving from Range 2 to Range 1, the system frequency can be increased to
105   *        a value up to 64 MHz after calling HAL_PWREx_ControlVoltageScaling() API.
106   * @note  When moving from Range 2 to Range 1, the API waits for VOSF flag to be
107   *        cleared before returning the status. If the flag is not cleared within
108   *        50 microseconds, HAL_TIMEOUT status is reported.
109   * @retval HAL Status
110   */
HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling)111 HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling)
112 {
113   uint32_t wait_loop_index;
114 
115   assert_param(IS_PWR_VOLTAGE_SCALING_RANGE(VoltageScaling));
116 
117   /* If Set Range 1 */
118   if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1)
119   {
120     if (READ_BIT(PWR->CR1, PWR_CR1_VOS) != PWR_REGULATOR_VOLTAGE_SCALE1)
121     {
122       /* Set Range 1 */
123       MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1);
124 
125       /* Wait until VOSF is cleared */
126       wait_loop_index = (PWR_FLAG_SETTING_DELAY_US * (SystemCoreClock / 1000000U));
127       while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) && (wait_loop_index != 0U))
128       {
129         wait_loop_index--;
130       }
131       if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF))
132       {
133         return HAL_TIMEOUT;
134       }
135     }
136   }
137   else
138   {
139     if (READ_BIT(PWR->CR1, PWR_CR1_VOS) != PWR_REGULATOR_VOLTAGE_SCALE2)
140     {
141       /* Set Range 2 */
142       MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE2);
143       /* No need to wait for VOSF to be cleared for this transition */
144     }
145   }
146 
147   return HAL_OK;
148 }
149 #endif /* PWR_CR1_VOS */
150 
151 /****************************************************************************/
152 
153 /**
154   * @brief Enable battery charging.
155   *        When VDD is present, charge the external battery on VBAT thru an internal resistor.
156   * @param ResistorSelection specifies the resistor impedance.
157   *          This parameter can be one of the following values:
158   *            @arg @ref PWR_BATTERY_CHARGING_RESISTOR_5     5 kOhms resistor
159   *            @arg @ref PWR_BATTERY_CHARGING_RESISTOR_1_5 1.5 kOhms resistor
160   * @retval None
161   */
HAL_PWREx_EnableBatteryCharging(uint32_t ResistorSelection)162 void HAL_PWREx_EnableBatteryCharging(uint32_t ResistorSelection)
163 {
164   assert_param(IS_PWR_BATTERY_RESISTOR_SELECT(ResistorSelection));
165 
166   /* Specify resistor selection */
167   MODIFY_REG(PWR->CR4, PWR_CR4_VBRS, ResistorSelection);
168 
169   /* Enable battery charging */
170   SET_BIT(PWR->CR4, PWR_CR4_VBE);
171 }
172 
173 /**
174   * @brief Disable battery charging.
175   * @retval None
176   */
HAL_PWREx_DisableBatteryCharging(void)177 void HAL_PWREx_DisableBatteryCharging(void)
178 {
179   CLEAR_BIT(PWR->CR4, PWR_CR4_VBE);
180 }
181 
182 /****************************************************************************/
183 #if defined(PWR_CR2_PVME1)
184 /**
185   * @brief Enable VDDUSB supply.
186   * @note  Remove VDDUSB electrical and logical isolation, once VDDUSB supply is present.
187   * @retval None
188   */
HAL_PWREx_EnableVddUSB(void)189 void HAL_PWREx_EnableVddUSB(void)
190 {
191   SET_BIT(PWR->CR2, PWR_CR2_USV);
192 }
193 
194 /**
195   * @brief Disable VDDUSB supply.
196   * @retval None
197   */
HAL_PWREx_DisableVddUSB(void)198 void HAL_PWREx_DisableVddUSB(void)
199 {
200   CLEAR_BIT(PWR->CR2, PWR_CR2_USV);
201 }
202 #endif /* PWR_CR2_PVME1 */
203 
204 /****************************************************************************/
205 
206 /**
207   * @brief Enable Internal Wake-up Line.
208   * @retval None
209   */
HAL_PWREx_EnableInternalWakeUpLine(void)210 void HAL_PWREx_EnableInternalWakeUpLine(void)
211 {
212   SET_BIT(PWR->CR3, PWR_CR3_EIWUL);
213 }
214 
215 /**
216   * @brief Disable Internal Wake-up Line.
217   * @retval None
218   */
HAL_PWREx_DisableInternalWakeUpLine(void)219 void HAL_PWREx_DisableInternalWakeUpLine(void)
220 {
221   CLEAR_BIT(PWR->CR3, PWR_CR3_EIWUL);
222 }
223 
224 #if defined(PWR_CR5_SMPSEN)
225 /**
226   * @brief Enable BORH and SMPS step down converter forced in bypass mode
227   *        interrupt for CPU1
228   * @retval None
229   */
HAL_PWREx_EnableBORH_SMPSBypassIT(void)230 void HAL_PWREx_EnableBORH_SMPSBypassIT(void)
231 {
232   SET_BIT(PWR->CR3, PWR_CR3_EBORHSMPSFB);
233 }
234 
235 /**
236   * @brief Disable BORH and SMPS step down converter forced in bypass mode
237   *        interrupt for CPU1
238   * @retval None
239   */
HAL_PWREx_DisableBORH_SMPSBypassIT(void)240 void HAL_PWREx_DisableBORH_SMPSBypassIT(void)
241 {
242   CLEAR_BIT(PWR->CR3, PWR_CR3_EBORHSMPSFB);
243 }
244 #endif /* PWR_CR5_SMPSEN */
245 
246 /**
247   * @brief Enable RF Phase interrupt.
248   * @retval None
249   */
HAL_PWREx_EnableRFPhaseIT(void)250 void HAL_PWREx_EnableRFPhaseIT(void)
251 {
252   SET_BIT(PWR->CR3, PWR_CR3_ECRPE_Msk);
253 }
254 
255 /**
256   * @brief Disable RF Phase interrupt.
257   * @retval None
258   */
HAL_PWREx_DisableRFPhaseIT(void)259 void HAL_PWREx_DisableRFPhaseIT(void)
260 {
261   CLEAR_BIT(PWR->CR3, PWR_CR3_ECRPE_Msk);
262 }
263 
264 
265 /**
266   * @brief Enable BLE Activity interrupt.
267   * @retval None
268   */
HAL_PWREx_EnableBLEActivityIT(void)269 void HAL_PWREx_EnableBLEActivityIT(void)
270 {
271   SET_BIT(PWR->CR3, PWR_CR3_EBLEA);
272 }
273 
274 /**
275   * @brief Disable BLE Activity interrupt.
276   * @retval None
277   */
HAL_PWREx_DisableBLEActivityIT(void)278 void HAL_PWREx_DisableBLEActivityIT(void)
279 {
280   CLEAR_BIT(PWR->CR3, PWR_CR3_EBLEA);
281 }
282 
283 #if defined(PWR_CR3_E802A)
284 /**
285   * @brief Enable 802.15.4 Activity interrupt.
286   * @retval None
287   */
HAL_PWREx_Enable802ActivityIT(void)288 void HAL_PWREx_Enable802ActivityIT(void)
289 {
290   SET_BIT(PWR->CR3, PWR_CR3_E802A);
291 }
292 
293 /**
294   * @brief Disable 802.15.4 Activity interrupt.
295   * @retval None
296   */
HAL_PWREx_Disable802ActivityIT(void)297 void HAL_PWREx_Disable802ActivityIT(void)
298 {
299   CLEAR_BIT(PWR->CR3, PWR_CR3_E802A);
300 }
301 #endif /* PWR_CR3_E802A */
302 
303 /**
304   * @brief Enable CPU2 on-Hold interrupt.
305   * @retval None
306   */
HAL_PWREx_EnableHOLDC2IT(void)307 void HAL_PWREx_EnableHOLDC2IT(void)
308 {
309   SET_BIT(PWR->CR3, PWR_CR3_EC2H);
310 }
311 
312 /**
313   * @brief Disable CPU2 on-Hold interrupt.
314   * @retval None
315   */
HAL_PWREx_DisableHOLDC2IT(void)316 void HAL_PWREx_DisableHOLDC2IT(void)
317 {
318   CLEAR_BIT(PWR->CR3, PWR_CR3_EC2H);
319 }
320 
321 /****************************************************************************/
322 
323 /**
324   * @brief Enable GPIO pull-up state in Standby and Shutdown modes.
325   * @note  Set the relevant PUy bits of PWR_PUCRx register to configure the I/O in
326   *        pull-up state in Standby and Shutdown modes.
327   * @note  This state is effective in Standby and Shutdown modes only if APC bit
328   *        is set through HAL_PWREx_EnablePullUpPullDownConfig() API.
329   * @note  The configuration is lost when exiting the Shutdown mode due to the
330   *        power-on reset, maintained when exiting the Standby mode.
331   * @note  To avoid any conflict at Standby and Shutdown modes exits, the corresponding
332   *        PDy bit of PWR_PDCRx register is cleared unless it is reserved.
333   * @note  Even if a PUy bit to set is reserved, the other PUy bits entered as input
334   *        parameter at the same time are set.
335   * @param GPIO Specify the IO port. This parameter can be PWR_GPIO_A, ..., PWR_GPIO_H
336   *         to select the GPIO peripheral.
337   * @param GPIONumber Specify the I/O pins numbers.
338   *         This parameter can be one of the following values:
339   *         PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15 (except for PORTH where less
340   *         I/O pins are available) or the logical OR of several of them to set
341   *         several bits for a given port in a single API call.
342   * @retval HAL Status
343   */
HAL_PWREx_EnableGPIOPullUp(uint32_t GPIO,uint32_t GPIONumber)344 HAL_StatusTypeDef HAL_PWREx_EnableGPIOPullUp(uint32_t GPIO, uint32_t GPIONumber)
345 {
346   HAL_StatusTypeDef status = HAL_OK;
347 
348   assert_param(IS_PWR_GPIO(GPIO));
349   assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
350 
351   switch (GPIO)
352   {
353     case PWR_GPIO_A:
354       SET_BIT(PWR->PUCRA, GPIONumber);
355       CLEAR_BIT(PWR->PDCRA, GPIONumber);
356       break;
357     case PWR_GPIO_B:
358       SET_BIT(PWR->PUCRB, GPIONumber);
359       CLEAR_BIT(PWR->PDCRB, GPIONumber);
360       break;
361     case PWR_GPIO_C:
362       SET_BIT(PWR->PUCRC, GPIONumber);
363       CLEAR_BIT(PWR->PDCRC, GPIONumber);
364       break;
365 #if defined(GPIOD)
366     case PWR_GPIO_D:
367       SET_BIT(PWR->PUCRD, GPIONumber);
368       CLEAR_BIT(PWR->PDCRD, GPIONumber);
369       break;
370 #endif /* GPIOD */
371     case PWR_GPIO_E:
372       SET_BIT(PWR->PUCRE, (GPIONumber & PWR_PORTE_AVAILABLE_PINS));
373       CLEAR_BIT(PWR->PDCRE, (GPIONumber & PWR_PORTE_AVAILABLE_PINS));
374       break;
375     case PWR_GPIO_H:
376       SET_BIT(PWR->PUCRH, (GPIONumber & PWR_PORTH_AVAILABLE_PINS));
377       CLEAR_BIT(PWR->PDCRH, (GPIONumber & PWR_PORTH_AVAILABLE_PINS));
378       break;
379     default:
380       status = HAL_ERROR;
381       break;
382   }
383 
384   return status;
385 }
386 
387 /**
388   * @brief Disable GPIO pull-up state in Standby mode and Shutdown modes.
389   * @note  Reset the relevant PUy bits of PWR_PUCRx register used to configure the I/O
390   *        in pull-up state in Standby and Shutdown modes.
391   * @note  Even if a PUy bit to reset is reserved, the other PUy bits entered as input
392   *        parameter at the same time are reset.
393   * @param GPIO Specifies the IO port. This parameter can be PWR_GPIO_A, ..., PWR_GPIO_H
394   *         to select the GPIO peripheral.
395   * @param GPIONumber Specify the I/O pins numbers.
396   *         This parameter can be one of the following values:
397   *         PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15 (except for PORTH where less
398   *         I/O pins are available) or the logical OR of several of them to reset
399   *         several bits for a given port in a single API call.
400   * @retval HAL Status
401   */
HAL_PWREx_DisableGPIOPullUp(uint32_t GPIO,uint32_t GPIONumber)402 HAL_StatusTypeDef HAL_PWREx_DisableGPIOPullUp(uint32_t GPIO, uint32_t GPIONumber)
403 {
404   HAL_StatusTypeDef status = HAL_OK;
405 
406   assert_param(IS_PWR_GPIO(GPIO));
407   assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
408 
409   switch (GPIO)
410   {
411     case PWR_GPIO_A:
412       CLEAR_BIT(PWR->PUCRA, GPIONumber);
413       break;
414     case PWR_GPIO_B:
415       CLEAR_BIT(PWR->PUCRB, GPIONumber);
416       break;
417     case PWR_GPIO_C:
418       CLEAR_BIT(PWR->PUCRC, GPIONumber);
419       break;
420 #if defined(GPIOD)
421     case PWR_GPIO_D:
422       CLEAR_BIT(PWR->PUCRD, GPIONumber);
423       break;
424 #endif /* GPIOD */
425     case PWR_GPIO_E:
426       CLEAR_BIT(PWR->PUCRE, (GPIONumber & PWR_PORTE_AVAILABLE_PINS));
427       break;
428     case PWR_GPIO_H:
429       CLEAR_BIT(PWR->PUCRH, (GPIONumber & PWR_PORTH_AVAILABLE_PINS));
430       break;
431     default:
432       status = HAL_ERROR;
433       break;
434   }
435 
436   return status;
437 }
438 
439 
440 
441 /**
442   * @brief Enable GPIO pull-down state in Standby and Shutdown modes.
443   * @note  Set the relevant PDy bits of PWR_PDCRx register to configure the I/O in
444   *        pull-down state in Standby and Shutdown modes.
445   * @note  This state is effective in Standby and Shutdown modes only if APC bit
446   *        is set through HAL_PWREx_EnablePullUpPullDownConfig() API.
447   * @note  The configuration is lost when exiting the Shutdown mode due to the
448   *        power-on reset, maintained when exiting the Standby mode.
449   * @note  To avoid any conflict at Standby and Shutdown modes exits, the corresponding
450   *        PUy bit of PWR_PUCRx register is cleared unless it is reserved.
451   * @note  Even if a PDy bit to set is reserved, the other PDy bits entered as input
452   *        parameter at the same time are set.
453   * @param GPIO Specify the IO port. This parameter can be PWR_GPIO_A..PWR_GPIO_H
454   *         to select the GPIO peripheral.
455   * @param GPIONumber Specify the I/O pins numbers.
456   *         This parameter can be one of the following values:
457   *         PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15 (except for PORTH where less
458   *         I/O pins are available) or the logical OR of several of them to set
459   *         several bits for a given port in a single API call.
460   * @retval HAL Status
461   */
HAL_PWREx_EnableGPIOPullDown(uint32_t GPIO,uint32_t GPIONumber)462 HAL_StatusTypeDef HAL_PWREx_EnableGPIOPullDown(uint32_t GPIO, uint32_t GPIONumber)
463 {
464   HAL_StatusTypeDef status = HAL_OK;
465 
466   assert_param(IS_PWR_GPIO(GPIO));
467   assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
468 
469   switch (GPIO)
470   {
471     case PWR_GPIO_A:
472       SET_BIT(PWR->PDCRA, GPIONumber);
473       CLEAR_BIT(PWR->PUCRA, GPIONumber);
474       break;
475     case PWR_GPIO_B:
476       SET_BIT(PWR->PDCRB, GPIONumber);
477       CLEAR_BIT(PWR->PUCRB, GPIONumber);
478       break;
479     case PWR_GPIO_C:
480       SET_BIT(PWR->PDCRC, GPIONumber);
481       CLEAR_BIT(PWR->PUCRC, GPIONumber);
482       break;
483 #if defined(GPIOD)
484     case PWR_GPIO_D:
485       SET_BIT(PWR->PDCRD, GPIONumber);
486       CLEAR_BIT(PWR->PUCRD, GPIONumber);
487       break;
488 #endif /* GPIOD */
489     case PWR_GPIO_E:
490       SET_BIT(PWR->PDCRE, (GPIONumber & PWR_PORTE_AVAILABLE_PINS));
491       CLEAR_BIT(PWR->PUCRE, (GPIONumber & PWR_PORTE_AVAILABLE_PINS));
492       break;
493     case PWR_GPIO_H:
494       SET_BIT(PWR->PDCRH, (GPIONumber & PWR_PORTH_AVAILABLE_PINS));
495       CLEAR_BIT(PWR->PUCRH, (GPIONumber & PWR_PORTH_AVAILABLE_PINS));
496       break;
497     default:
498       status = HAL_ERROR;
499       break;
500   }
501 
502   return status;
503 }
504 
505 /**
506   * @brief Disable GPIO pull-down state in Standby and Shutdown modes.
507   * @note  Reset the relevant PDy bits of PWR_PDCRx register used to configure the I/O
508   *        in pull-down state in Standby and Shutdown modes.
509   * @note  Even if a PDy bit to reset is reserved, the other PDy bits entered as input
510   *        parameter at the same time are reset.
511   * @param GPIO Specifies the IO port. This parameter can be PWR_GPIO_A..PWR_GPIO_H
512   *         to select the GPIO peripheral.
513   * @param GPIONumber Specify the I/O pins numbers.
514   *         This parameter can be one of the following values:
515   *         PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15 (except for PORTH where less
516   *         I/O pins are available) or the logical OR of several of them to reset
517   *         several bits for a given port in a single API call.
518   * @retval HAL Status
519   */
HAL_PWREx_DisableGPIOPullDown(uint32_t GPIO,uint32_t GPIONumber)520 HAL_StatusTypeDef HAL_PWREx_DisableGPIOPullDown(uint32_t GPIO, uint32_t GPIONumber)
521 {
522   HAL_StatusTypeDef status = HAL_OK;
523 
524   assert_param(IS_PWR_GPIO(GPIO));
525   assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
526 
527   switch (GPIO)
528   {
529     case PWR_GPIO_A:
530       CLEAR_BIT(PWR->PDCRA, GPIONumber);
531       break;
532     case PWR_GPIO_B:
533       CLEAR_BIT(PWR->PDCRB, GPIONumber);
534       break;
535     case PWR_GPIO_C:
536       CLEAR_BIT(PWR->PDCRC, GPIONumber);
537       break;
538 #if defined(GPIOD)
539     case PWR_GPIO_D:
540       CLEAR_BIT(PWR->PDCRD, GPIONumber);
541       break;
542 #endif /* GPIOD */
543     case PWR_GPIO_E:
544       CLEAR_BIT(PWR->PDCRE, (GPIONumber & PWR_PORTE_AVAILABLE_PINS));
545       break;
546     case PWR_GPIO_H:
547       CLEAR_BIT(PWR->PDCRH, (GPIONumber & PWR_PORTH_AVAILABLE_PINS));
548       break;
549     default:
550       status = HAL_ERROR;
551       break;
552   }
553 
554   return status;
555 }
556 
557 /**
558   * @brief Enable pull-up and pull-down configuration.
559   * @note  When APC bit is set, the I/O pull-up and pull-down configurations defined in
560   *        PWR_PUCRx and PWR_PDCRx registers are applied in Standby and Shutdown modes.
561   * @note  Pull-up set by PUy bit of PWR_PUCRx register is not activated if the corresponding
562   *        PDy bit of PWR_PDCRx register is also set (pull-down configuration priority is higher).
563   *        HAL_PWREx_EnableGPIOPullUp() and HAL_PWREx_EnableGPIOPullDown() API's ensure there
564   *        is no conflict when setting PUy or PDy bit.
565   * @retval None
566   */
HAL_PWREx_EnablePullUpPullDownConfig(void)567 void HAL_PWREx_EnablePullUpPullDownConfig(void)
568 {
569   SET_BIT(PWR->CR3, PWR_CR3_APC);
570 }
571 
572 /**
573   * @brief Disable pull-up and pull-down configuration.
574   * @note  When APC bit is cleared, the I/O pull-up and pull-down configurations defined in
575   *        PWR_PUCRx and PWR_PDCRx registers are not applied in Standby and Shutdown modes.
576   * @retval None
577   */
HAL_PWREx_DisablePullUpPullDownConfig(void)578 void HAL_PWREx_DisablePullUpPullDownConfig(void)
579 {
580   CLEAR_BIT(PWR->CR3, PWR_CR3_APC);
581 }
582 
583 /****************************************************************************/
584 
585 #if defined(PWR_CR5_SMPSEN)
586 /**
587   * @brief  Set BOR configuration
588   * @param  BORConfiguration This parameter can be one of the following values:
589   *         @arg @ref PWR_BOR_SYSTEM_RESET
590   *         @arg @ref PWR_BOR_SMPS_FORCE_BYPASS
591   */
HAL_PWREx_SetBORConfig(uint32_t BORConfiguration)592 void HAL_PWREx_SetBORConfig(uint32_t BORConfiguration)
593 {
594   LL_PWR_SetBORConfig(BORConfiguration);
595 }
596 
597 /**
598   * @brief  Get BOR configuration
599   * @retval Returned value can be one of the following values:
600   *         @arg @ref PWR_BOR_SYSTEM_RESET
601   *         @arg @ref PWR_BOR_SMPS_FORCE_BYPASS
602   */
HAL_PWREx_GetBORConfig(void)603 uint32_t HAL_PWREx_GetBORConfig(void)
604 {
605   return LL_PWR_GetBORConfig();
606 }
607 #endif /* PWR_CR5_SMPSEN */
608 
609 /****************************************************************************/
610 /**
611   * @brief  Hold the CPU and their allocated peripherals after reset or wakeup from stop or standby.
612   * @param  CPU: Specifies the core to be held.
613   *              This parameter can be one of the following values:
614   *             @arg PWR_CORE_CPU2: Hold CPU2 and set CPU1 as master.
615   * @note   Hold CPU2 with CPU1 as master by default.
616   * @retval None
617   */
HAL_PWREx_HoldCore(uint32_t CPU)618 void HAL_PWREx_HoldCore(uint32_t CPU)
619 {
620   /* Check the parameters */
621   assert_param(IS_PWR_CORE_HOLD_RELEASE(CPU));
622 
623   LL_PWR_DisableBootC2();
624 }
625 
626 /**
627   * @brief  Release Cortex CPU2 and allocated peripherals after reset or wakeup from stop or standby.
628   * @param  CPU: Specifies the core to be released.
629   *              This parameter can be one of the following values:
630   *             @arg PWR_CORE_CPU2: Release the CPU2 from holding.
631   * @retval None
632   */
HAL_PWREx_ReleaseCore(uint32_t CPU)633 void HAL_PWREx_ReleaseCore(uint32_t CPU)
634 {
635   /* Check the parameters */
636   assert_param(IS_PWR_CORE_HOLD_RELEASE(CPU));
637 
638   LL_PWR_EnableBootC2();
639 }
640 
641 /****************************************************************************/
642 /**
643   * @brief Enable SRAM2a content retention in Standby mode.
644   * @note  When RRS bit is set, SRAM2a is powered by the low-power regulator in
645   *         Standby mode and its content is kept.
646   * @note   On devices STM32WB15xx, STM32WB10xx, STM32WB1Mxx retention is extended
647   *         to SRAM1, SRAM2a and SRAM2b.
648   * @retval None
649   */
HAL_PWREx_EnableSRAMRetention(void)650 void HAL_PWREx_EnableSRAMRetention(void)
651 {
652   LL_PWR_EnableSRAM2Retention();
653 }
654 
655 /**
656   * @brief Disable SRAM2a content retention in Standby mode.
657   * @note  When RRS bit is reset, SRAM2a is powered off in Standby mode
658   *        and its content is lost.
659   * @note   On devices STM32WB15xx, STM32WB10xx, STM32WB1Mxx retention is extended
660   *         to SRAM1, SRAM2a and SRAM2b.
661   * @retval None
662   */
HAL_PWREx_DisableSRAMRetention(void)663 void HAL_PWREx_DisableSRAMRetention(void)
664 {
665   LL_PWR_DisableSRAM2Retention();
666 }
667 
668 /****************************************************************************/
669 /**
670   * @brief  Enable Flash Power Down.
671   * @note   This API allows to enable flash power down capabilities in low power
672   *         run and low power sleep modes.
673   * @param  PowerMode this can be a combination of following values:
674   *           @arg @ref PWR_FLASHPD_LPRUN
675   *           @arg @ref PWR_FLASHPD_LPSLEEP
676   * @retval None
677   */
HAL_PWREx_EnableFlashPowerDown(uint32_t PowerMode)678 void HAL_PWREx_EnableFlashPowerDown(uint32_t PowerMode)
679 {
680   assert_param(IS_PWR_FLASH_POWERDOWN(PowerMode));
681 
682   if ((PowerMode & PWR_FLASHPD_LPRUN) != 0U)
683   {
684     /* Unlock bit FPDR */
685     WRITE_REG(PWR->CR1, 0x0000C1B0UL);
686   }
687 
688   /* Set flash power down mode */
689   SET_BIT(PWR->CR1, PowerMode);
690 }
691 
692 /**
693   * @brief  Disable Flash Power Down.
694   * @note   This API allows to disable flash power down capabilities in low power
695   *         run and low power sleep modes.
696   * @param  PowerMode this can be a combination of following values:
697   *           @arg @ref PWR_FLASHPD_LPRUN
698   *           @arg @ref PWR_FLASHPD_LPSLEEP
699   * @retval None
700   */
HAL_PWREx_DisableFlashPowerDown(uint32_t PowerMode)701 void HAL_PWREx_DisableFlashPowerDown(uint32_t PowerMode)
702 {
703   assert_param(IS_PWR_FLASH_POWERDOWN(PowerMode));
704 
705   /* Set flash power down mode */
706   CLEAR_BIT(PWR->CR1, PowerMode);
707 }
708 
709 /****************************************************************************/
710 #if defined(PWR_CR2_PVME1)
711 /**
712   * @brief Enable the Power Voltage Monitoring 1: VDDUSB versus 1.2V.
713   * @retval None
714   */
HAL_PWREx_EnablePVM1(void)715 void HAL_PWREx_EnablePVM1(void)
716 {
717   SET_BIT(PWR->CR2, PWR_PVM_1);
718 }
719 
720 /**
721   * @brief Disable the Power Voltage Monitoring 1: VDDUSB versus 1.2V.
722   * @retval None
723   */
HAL_PWREx_DisablePVM1(void)724 void HAL_PWREx_DisablePVM1(void)
725 {
726   CLEAR_BIT(PWR->CR2, PWR_PVM_1);
727 }
728 #endif /* PWR_CR2_PVME1 */
729 
730 /**
731   * @brief Enable the Power Voltage Monitoring 3: VDDA versus 1.62V.
732   * @retval None
733   */
HAL_PWREx_EnablePVM3(void)734 void HAL_PWREx_EnablePVM3(void)
735 {
736   SET_BIT(PWR->CR2, PWR_PVM_3);
737 }
738 
739 /**
740   * @brief Disable the Power Voltage Monitoring 3: VDDA versus 1.62V.
741   * @retval None
742   */
HAL_PWREx_DisablePVM3(void)743 void HAL_PWREx_DisablePVM3(void)
744 {
745   CLEAR_BIT(PWR->CR2, PWR_PVM_3);
746 }
747 
748 
749 
750 
751 /**
752   * @brief Configure the Peripheral Voltage Monitoring (PVM).
753   * @param sConfigPVM pointer to a PWR_PVMTypeDef structure that contains the
754   *        PVM configuration information.
755   * @note The API configures a single PVM according to the information contained
756   *       in the input structure. To configure several PVMs, the API must be singly
757   *       called for each PVM used.
758   * @note Refer to the electrical characteristics of your device datasheet for
759   *         more details about the voltage thresholds corresponding to each
760   *         detection level and to each monitored supply.
761   * @retval HAL status
762   */
HAL_PWREx_ConfigPVM(PWR_PVMTypeDef * sConfigPVM)763 HAL_StatusTypeDef HAL_PWREx_ConfigPVM(PWR_PVMTypeDef *sConfigPVM)
764 {
765   HAL_StatusTypeDef status = HAL_OK;
766 
767   /* Check the parameters */
768   assert_param(IS_PWR_PVM_TYPE(sConfigPVM->PVMType));
769   assert_param(IS_PWR_PVM_MODE(sConfigPVM->Mode));
770 
771   /* Configure EXTI 31 and 33 interrupts if so required:
772      scan thru PVMType to detect which PVMx is set and
773      configure the corresponding EXTI line accordingly. */
774   switch (sConfigPVM->PVMType)
775   {
776 #if defined(PWR_CR2_PVME1)
777     case PWR_PVM_1:
778       /* Clear any previous config. Keep it clear if no event or IT mode is selected */
779       __HAL_PWR_PVM1_EXTI_DISABLE_EVENT();
780       __HAL_PWR_PVM1_EXTI_DISABLE_IT();
781       __HAL_PWR_PVM1_EXTI_DISABLE_FALLING_EDGE();
782       __HAL_PWR_PVM1_EXTI_DISABLE_RISING_EDGE();
783 
784       /* Configure interrupt mode */
785       if ((sConfigPVM->Mode & PVM_MODE_IT) == PVM_MODE_IT)
786       {
787         __HAL_PWR_PVM1_EXTI_ENABLE_IT();
788       }
789 
790       /* Configure event mode */
791       if ((sConfigPVM->Mode & PVM_MODE_EVT) == PVM_MODE_EVT)
792       {
793         __HAL_PWR_PVM1_EXTI_ENABLE_EVENT();
794       }
795 
796       /* Configure the edge */
797       if ((sConfigPVM->Mode & PVM_RISING_EDGE) == PVM_RISING_EDGE)
798       {
799         __HAL_PWR_PVM1_EXTI_ENABLE_RISING_EDGE();
800       }
801 
802       if ((sConfigPVM->Mode & PVM_FALLING_EDGE) == PVM_FALLING_EDGE)
803       {
804         __HAL_PWR_PVM1_EXTI_ENABLE_FALLING_EDGE();
805       }
806       break;
807 #endif /* PWR_CR2_PVME1 */
808 
809     case PWR_PVM_3:
810       /* Clear any previous config. Keep it clear if no event or IT mode is selected */
811       __HAL_PWR_PVM3_EXTI_DISABLE_EVENT();
812       __HAL_PWR_PVM3_EXTI_DISABLE_IT();
813       __HAL_PWR_PVM3_EXTI_DISABLE_FALLING_EDGE();
814       __HAL_PWR_PVM3_EXTI_DISABLE_RISING_EDGE();
815 
816       /* Configure interrupt mode */
817       if ((sConfigPVM->Mode & PVM_MODE_IT) == PVM_MODE_IT)
818       {
819         __HAL_PWR_PVM3_EXTI_ENABLE_IT();
820       }
821 
822       /* Configure event mode */
823       if ((sConfigPVM->Mode & PVM_MODE_EVT) == PVM_MODE_EVT)
824       {
825         __HAL_PWR_PVM3_EXTI_ENABLE_EVENT();
826       }
827 
828       /* Configure the edge */
829       if ((sConfigPVM->Mode & PVM_RISING_EDGE) == PVM_RISING_EDGE)
830       {
831         __HAL_PWR_PVM3_EXTI_ENABLE_RISING_EDGE();
832       }
833 
834       if ((sConfigPVM->Mode & PVM_FALLING_EDGE) == PVM_FALLING_EDGE)
835       {
836         __HAL_PWR_PVM3_EXTI_ENABLE_FALLING_EDGE();
837       }
838       break;
839 
840     default:
841       status = HAL_ERROR;
842       break;
843 
844   }
845 
846   return status;
847 }
848 
849 #if defined(PWR_CR5_SMPSEN)
850 /**
851   * @brief Configure the SMPS step down converter.
852   * @note   SMPS output voltage is calibrated in production,
853   *         calibration parameters are applied to the voltage level parameter
854   *         to reach the requested voltage value.
855   * @param sConfigSMPS pointer to a PWR_SMPSTypeDef structure that contains the
856   *        SMPS configuration information.
857   * @note  To set and enable SMPS operating mode, refer to function
858   *        "HAL_PWREx_SMPS_SetMode()".
859   * @retval HAL status
860   */
HAL_PWREx_ConfigSMPS(PWR_SMPSTypeDef * sConfigSMPS)861 HAL_StatusTypeDef HAL_PWREx_ConfigSMPS(PWR_SMPSTypeDef *sConfigSMPS)
862 {
863   HAL_StatusTypeDef status = HAL_OK;
864 
865   /* Check the parameters */
866   assert_param(IS_PWR_SMPS_STARTUP_CURRENT(sConfigSMPS->StartupCurrent));
867   assert_param(IS_PWR_SMPS_OUTPUT_VOLTAGE(sConfigSMPS->OutputVoltage));
868 
869   __IO const uint32_t OutputVoltageLevel_calibration = (((*SMPS_VOLTAGE_CAL_ADDR) & SMPS_VOLTAGE_CAL) >> SMPS_VOLTAGE_CAL_POS);  /* SMPS output voltage level calibrated in production */
870   int32_t TrimmingSteps;                         /* Trimming steps between theoretical output voltage and calibrated output voltage */
871   int32_t OutputVoltageLevelTrimmed;             /* SMPS output voltage level after calibration: trimming value added to required level */
872 
873   if (OutputVoltageLevel_calibration == 0UL)
874   {
875     /* Device with SMPS output voltage not calibrated in production: Apply output voltage value directly */
876 
877     /* Update register */
878     MODIFY_REG(PWR->CR5, PWR_CR5_SMPSVOS, (sConfigSMPS->StartupCurrent | sConfigSMPS->OutputVoltage));
879   }
880   else
881   {
882     /* Device with SMPS output voltage calibrated in production: Apply output voltage value after correction by calibration value */
883 
884     TrimmingSteps = ((int32_t)OutputVoltageLevel_calibration - (int32_t)(LL_PWR_SMPS_OUTPUT_VOLTAGE_1V50 >> PWR_CR5_SMPSVOS_Pos));
885     OutputVoltageLevelTrimmed = ((int32_t)((uint32_t)(sConfigSMPS->OutputVoltage >> PWR_CR5_SMPSVOS_Pos)) + (int32_t)TrimmingSteps);
886 
887     /* Clamp value to voltage trimming bitfield range */
888     if (OutputVoltageLevelTrimmed < 0)
889     {
890       OutputVoltageLevelTrimmed = 0;
891       status = HAL_ERROR;
892     }
893     else
894     {
895       if (OutputVoltageLevelTrimmed > (int32_t)PWR_CR5_SMPSVOS)
896       {
897         OutputVoltageLevelTrimmed = (int32_t)PWR_CR5_SMPSVOS;
898         status = HAL_ERROR;
899       }
900     }
901 
902     /* Update register */
903     MODIFY_REG(PWR->CR5, (PWR_CR5_SMPSSC | PWR_CR5_SMPSVOS),
904                (sConfigSMPS->StartupCurrent | ((uint32_t) OutputVoltageLevelTrimmed)));
905   }
906 
907   return status;
908 }
909 
910 /**
911   * @brief Set SMPS operating mode.
912   * @param  OperatingMode This parameter can be one of the following values:
913   *         @arg @ref PWR_SMPS_BYPASS
914   *         @arg @ref PWR_SMPS_STEP_DOWN (1)
915   *
916   *         (1) SMPS operating mode step down or open depends on system low-power mode:
917   *              - step down mode if system low power mode is run, LP run or stop,
918   *              - open mode if system low power mode is Stop1, Stop2, Standby or Shutdown
919   * @retval None
920   */
HAL_PWREx_SMPS_SetMode(uint32_t OperatingMode)921 void HAL_PWREx_SMPS_SetMode(uint32_t OperatingMode)
922 {
923   MODIFY_REG(PWR->CR5, PWR_CR5_SMPSEN, (OperatingMode & PWR_SR2_SMPSF) << (PWR_CR5_SMPSEN_Pos - PWR_SR2_SMPSF_Pos));
924 }
925 
926 /**
927   * @brief  Get SMPS effective operating mode
928   * @note   SMPS operating mode can be changed by hardware, therefore
929   *         requested operating mode can differ from effective low power mode.
930   *         - dependency on system low-power mode:
931   *           - step down mode if system low power mode is run, LP run or stop,
932   *           - open mode if system low power mode is Stop1, Stop2, Standby or Shutdown
933   *         - dependency on BOR level:
934   *           - bypass mode if supply voltage drops below BOR level
935   * @note   This functions check flags of SMPS operating modes step down
936   *         and bypass. If the SMPS is not among these 2 operating modes,
937   *         then it can be in mode off or open.
938   * @retval Returned value can be one of the following values:
939   *         @arg @ref PWR_SMPS_BYPASS
940   *         @arg @ref PWR_SMPS_STEP_DOWN (1)
941   *
942   *         (1) SMPS operating mode step down or open depends on system low-power mode:
943   *              - step down mode if system low power mode is run, LP run or stop,
944   *              - open mode if system low power mode is Stop1, Stop2, Standby or Shutdown
945   */
HAL_PWREx_SMPS_GetEffectiveMode(void)946 uint32_t HAL_PWREx_SMPS_GetEffectiveMode(void)
947 {
948   return (uint32_t)(READ_BIT(PWR->SR2, (PWR_SR2_SMPSF | PWR_SR2_SMPSBF)));
949 }
950 #endif /* PWR_CR5_SMPSEN */
951 
952 /****************************************************************************/
953 
954 /**
955   * @brief Enable the WakeUp PINx functionality.
956   * @param WakeUpPinPolarity Specifies which Wake-Up pin to enable.
957   *         This parameter can be one of the following legacy values which set the default polarity
958   *         i.e. detection on high level (rising edge):
959   *           @arg @ref PWR_WAKEUP_PIN1, PWR_WAKEUP_PIN2, PWR_WAKEUP_PIN3, PWR_WAKEUP_PIN4, PWR_WAKEUP_PIN5
960   *
961   *         or one of the following value where the user can explicitly specify the enabled pin and
962   *         the chosen polarity:
963   *           @arg @ref PWR_WAKEUP_PIN1_HIGH or PWR_WAKEUP_PIN1_LOW
964   *           @arg @ref PWR_WAKEUP_PIN2_HIGH or PWR_WAKEUP_PIN2_LOW
965   *           @arg @ref PWR_WAKEUP_PIN3_HIGH or PWR_WAKEUP_PIN3_LOW
966   *           @arg @ref PWR_WAKEUP_PIN4_HIGH or PWR_WAKEUP_PIN4_LOW
967   *           @arg @ref PWR_WAKEUP_PIN5_HIGH or PWR_WAKEUP_PIN5_LOW
968   * @param wakeupTarget Specifies the wake-up target
969   *         @arg @ref PWR_CORE_CPU1
970   *         @arg @ref PWR_CORE_CPU2
971   * @note  PWR_WAKEUP_PINx and PWR_WAKEUP_PINx_HIGH are equivalent.
972   * @retval None
973   */
HAL_PWREx_EnableWakeUpPin(uint32_t WakeUpPinPolarity,uint32_t wakeupTarget)974 void HAL_PWREx_EnableWakeUpPin(uint32_t WakeUpPinPolarity, uint32_t wakeupTarget)
975 {
976   assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinPolarity));
977 
978   /* Specifies the Wake-Up pin polarity for the event detection
979     (rising or falling edge) */
980   MODIFY_REG(PWR->CR4, (PWR_C2CR3_EWUP & WakeUpPinPolarity), (WakeUpPinPolarity >> PWR_WUP_POLARITY_SHIFT));
981 
982   /* Enable wake-up pin */
983   if (PWR_CORE_CPU2 == wakeupTarget)
984   {
985     SET_BIT(PWR->C2CR3, (PWR_C2CR3_EWUP & WakeUpPinPolarity));
986   }
987   else
988   {
989     SET_BIT(PWR->CR3, (PWR_CR3_EWUP & WakeUpPinPolarity));
990   }
991 }
992 
993 /**
994   * @brief  Get the Wake-Up pin flag.
995   * @param WakeUpFlag specifies the Wake-Up PIN flag to check.
996   *          This parameter can be one of the following values:
997   *            @arg PWR_FLAG_WUF1: A wakeup event was received from PA0.
998   *            @arg PWR_FLAG_WUF2: A wakeup event was received from PC13.
999   *            @arg PWR_FLAG_WUF3: A wakeup event was received from PC12.
1000   *            @arg PWR_FLAG_WUF4: A wakeup event was received from PA2.
1001   *            @arg PWR_FLAG_WUF5: A wakeup event was received from PC5.
1002   * @retval The Wake-Up pin flag.
1003   */
HAL_PWREx_GetWakeupFlag(uint32_t WakeUpFlag)1004 uint32_t  HAL_PWREx_GetWakeupFlag(uint32_t WakeUpFlag)
1005 {
1006   return (PWR->SR1 & (1UL << ((WakeUpFlag) & 31U)));
1007 }
1008 
1009 /**
1010   * @brief  Clear the Wake-Up pin flag.
1011   * @param WakeUpFlag specifies the Wake-Up PIN flag to clear.
1012   *          This parameter can be one of the following values:
1013   *            @arg PWR_FLAG_WUF1: A wakeup event was received from PA0.
1014   *            @arg PWR_FLAG_WUF2: A wakeup event was received from PC13.
1015   *            @arg PWR_FLAG_WUF3: A wakeup event was received from PC12.
1016   *            @arg PWR_FLAG_WUF4: A wakeup event was received from PA2.
1017   *            @arg PWR_FLAG_WUF5: A wakeup event was received from PC5.
1018   * @retval HAL status.
1019   */
HAL_PWREx_ClearWakeupFlag(uint32_t WakeUpFlag)1020 HAL_StatusTypeDef HAL_PWREx_ClearWakeupFlag(uint32_t WakeUpFlag)
1021 {
1022   PWR->SCR = (1UL << ((WakeUpFlag) & 31U));
1023 
1024   if ((PWR->SR1 & (1UL << ((WakeUpFlag) & 31U))) != 0U)
1025   {
1026     return HAL_ERROR;
1027   }
1028   return HAL_OK;
1029 }
1030 
1031 /****************************************************************************/
1032 
1033 /**
1034   * @brief Enter Low-power Run mode
1035   * @note  In Low-power Run mode, all I/O pins keep the same state as in Run mode.
1036   * @note  When Regulator is set to PWR_LOWPOWERREGULATOR_ON, the user can optionally configure the
1037   *        Flash in power-down mode in setting the RUN_PD bit in FLASH_ACR register.
1038   *        Additionally, the clock frequency must be reduced below 2 MHz.
1039   *        Setting RUN_PD in FLASH_ACR then appropriately reducing the clock frequency must
1040   *        be done before calling HAL_PWREx_EnableLowPowerRunMode() API.
1041   * @retval None
1042   */
HAL_PWREx_EnableLowPowerRunMode(void)1043 void HAL_PWREx_EnableLowPowerRunMode(void)
1044 {
1045   /* Set Regulator parameter */
1046   SET_BIT(PWR->CR1, PWR_CR1_LPR);
1047 }
1048 
1049 
1050 /**
1051   * @brief Exit Low-power Run mode.
1052   * @note  Before HAL_PWREx_DisableLowPowerRunMode() completion, the function checks that
1053   *        REGLPF has been properly reset (otherwise, HAL_PWREx_DisableLowPowerRunMode
1054   *        returns HAL_TIMEOUT status). The system clock frequency can then be
1055   *        increased above 2 MHz.
1056   * @retval HAL Status
1057   */
HAL_PWREx_DisableLowPowerRunMode(void)1058 HAL_StatusTypeDef HAL_PWREx_DisableLowPowerRunMode(void)
1059 {
1060   uint32_t wait_loop_index;
1061 
1062   /* Clear LPR bit */
1063   CLEAR_BIT(PWR->CR1, PWR_CR1_LPR);
1064 
1065   /* Wait until REGLPF is reset */
1066   wait_loop_index = (PWR_FLAG_SETTING_DELAY_US * (SystemCoreClock / 1000000U));
1067   while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_REGLPF)) && (wait_loop_index != 0U))
1068   {
1069     wait_loop_index--;
1070   }
1071   if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_REGLPF))
1072   {
1073     return HAL_TIMEOUT;
1074   }
1075 
1076   return HAL_OK;
1077 }
1078 
1079 /****************************************************************************/
1080 
1081 /**
1082   * @brief Enter Stop 0 mode.
1083   * @note  In Stop 0 mode, main and low voltage regulators are ON.
1084   * @note  In Stop 0 mode, all I/O pins keep the same state as in Run mode.
1085   * @note  All clocks in the VCORE domain are stopped; the PLL, the MSI,
1086   *        the HSI and the HSE oscillators are disabled. Some peripherals with the wakeup capability
1087   *        (I2Cx, USARTx and LPUART) can switch on the HSI to receive a frame, and switch off the HSI
1088   *        after receiving the frame if it is not a wakeup frame. In this case, the HSI clock is propagated
1089   *        only to the peripheral requesting it.
1090   *        SRAM1, SRAM2 and register contents are preserved.
1091   *        The BOR is available.
1092   * @note  When exiting Stop 0 mode by issuing an interrupt or a wakeup event,
1093   *         the HSI RC oscillator is selected as system clock if STOPWUCK bit in RCC_CFGR register
1094   *         is set; the MSI oscillator is selected if STOPWUCK is cleared.
1095   * @note  By keeping the internal regulator ON during Stop 0 mode, the consumption
1096   *         is higher although the startup time is reduced.
1097   * @note  Case of Stop0 mode with SMPS: Before entering Stop 0 mode with SMPS Step Down converter enabled,
1098   *        the HSI16 must be kept on by enabling HSI kernel clock (set HSIKERON register bit).
1099   * @note  According to system power policy, system entering in Stop mode
1100   *        is depending on other CPU power mode.
1101   * @param STOPEntry  specifies if Stop mode in entered with WFI or WFE instruction.
1102   *          This parameter can be one of the following values:
1103   *            @arg @ref PWR_STOPENTRY_WFI  Enter Stop mode with WFI instruction
1104   *            @arg @ref PWR_STOPENTRY_WFE  Enter Stop mode with WFE instruction
1105   * @retval None
1106   */
HAL_PWREx_EnterSTOP0Mode(uint8_t STOPEntry)1107 void HAL_PWREx_EnterSTOP0Mode(uint8_t STOPEntry)
1108 {
1109   /* Check the parameters */
1110   assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
1111 
1112   /* Stop 0 mode with Main Regulator */
1113   MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_STOP0);
1114 
1115 
1116   /* Set SLEEPDEEP bit of Cortex System Control Register */
1117   SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1118 
1119   /* Select Stop mode entry --------------------------------------------------*/
1120   if (STOPEntry == PWR_STOPENTRY_WFI)
1121   {
1122     /* Request Wait For Interrupt */
1123     __WFI();
1124   }
1125   else
1126   {
1127     /* Request Wait For Event */
1128     __SEV();
1129     __WFE();
1130     __WFE();
1131   }
1132 
1133   /* Reset SLEEPDEEP bit of Cortex System Control Register */
1134   CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1135 }
1136 
1137 /**
1138   * @brief Enter Stop 1 mode.
1139   * @note  In Stop 1 mode, only low power voltage regulator is ON.
1140   * @note  In Stop 1 mode, all I/O pins keep the same state as in Run mode.
1141   * @note  All clocks in the VCORE domain are stopped; the PLL, the MSI,
1142   *        the HSI and the HSE oscillators are disabled. Some peripherals with the wakeup capability
1143   *        (I2Cx, USARTx and LPUART) can switch on the HSI to receive a frame, and switch off the HSI
1144   *        after receiving the frame if it is not a wakeup frame. In this case, the HSI clock is propagated
1145   *        only to the peripheral requesting it.
1146   *        SRAM1, SRAM2 and register contents are preserved.
1147   *        The BOR is available.
1148   * @note  When exiting Stop 1 mode by issuing an interrupt or a wakeup event,
1149   *         the HSI RC oscillator is selected as system clock if STOPWUCK bit in RCC_CFGR register
1150   *         is set; the MSI oscillator is selected if STOPWUCK is cleared.
1151   * @note  Due to low power mode, an additional startup delay is incurred when waking up from Stop 1 mode.
1152   * @note  According to system power policy, system entering in Stop mode
1153   *        is depending on other CPU power mode.
1154   * @param STOPEntry  specifies if Stop mode in entered with WFI or WFE instruction.
1155   *          This parameter can be one of the following values:
1156   *            @arg @ref PWR_STOPENTRY_WFI  Enter Stop mode with WFI instruction
1157   *            @arg @ref PWR_STOPENTRY_WFE  Enter Stop mode with WFE instruction
1158   * @retval None
1159   */
HAL_PWREx_EnterSTOP1Mode(uint8_t STOPEntry)1160 void HAL_PWREx_EnterSTOP1Mode(uint8_t STOPEntry)
1161 {
1162   /* Check the parameters */
1163   assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
1164 
1165   /* Stop 1 mode with Low-Power Regulator */
1166   MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_STOP1);
1167 
1168   /* Set SLEEPDEEP bit of Cortex System Control Register */
1169   SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1170 
1171   /* Select Stop mode entry --------------------------------------------------*/
1172   if (STOPEntry == PWR_STOPENTRY_WFI)
1173   {
1174     /* Request Wait For Interrupt */
1175     __WFI();
1176   }
1177   else
1178   {
1179     /* Request Wait For Event */
1180     __SEV();
1181     __WFE();
1182     __WFE();
1183   }
1184 
1185   /* Reset SLEEPDEEP bit of Cortex System Control Register */
1186   CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1187 }
1188 
1189 #if defined(PWR_SUPPORT_STOP2)
1190 /**
1191   * @brief Enter Stop 2 mode.
1192   * @note  In Stop 2 mode, only low power voltage regulator is ON.
1193   * @note  In Stop 2 mode, all I/O pins keep the same state as in Run mode.
1194   * @note  All clocks in the VCORE domain are stopped, the PLL, the MSI,
1195   *        the HSI and the HSE oscillators are disabled. Some peripherals with wakeup capability
1196   *        (LCD, LPTIM1, I2C3 and LPUART) can switch on the HSI to receive a frame, and switch off the HSI after
1197   *        receiving the frame if it is not a wakeup frame. In this case the HSI clock is propagated only
1198   *        to the peripheral requesting it.
1199   *        SRAM1, SRAM2 and register contents are preserved.
1200   *        The BOR is available.
1201   *        The voltage regulator is set in low-power mode but LPR bit must be cleared to enter stop 2 mode.
1202   *        Otherwise, Stop 1 mode is entered.
1203   * @note  When exiting Stop 2 mode by issuing an interrupt or a wakeup event,
1204   *         the HSI RC oscillator is selected as system clock if STOPWUCK bit in RCC_CFGR register
1205   *         is set; the MSI oscillator is selected if STOPWUCK is cleared.
1206   * @note  Case of Stop2 mode and debugger probe attached: a workaround should be applied.
1207   *        Issue specified in "ES0394 - STM32WB55Cx/Rx/Vx device errata":
1208   *        2.2.9 Incomplete Stop 2 mode entry after a wakeup from debug upon EXTI line 48 event
1209   *        "With the JTAG debugger enabled on GPIO pins and after a wakeup from debug triggered by an event on EXTI
1210   *        line 48 (CDBGPWRUPREQ), the device may enter in a state in which attempts to enter Stop 2 mode are not fully
1211   *        effective ..."
1212   *        Workaround implementation example using LL driver:
1213   *        LL_EXTI_DisableIT_32_63(LL_EXTI_LINE_48);
1214   *        LL_C2_EXTI_DisableIT_32_63(LL_EXTI_LINE_48);
1215   * @note  According to system power policy, system entering in Stop mode
1216   *        is depending on other CPU power mode.
1217   * @param STOPEntry  specifies if Stop mode in entered with WFI or WFE instruction.
1218   *          This parameter can be one of the following values:
1219   *            @arg @ref PWR_STOPENTRY_WFI  Enter Stop mode with WFI instruction
1220   *            @arg @ref PWR_STOPENTRY_WFE  Enter Stop mode with WFE instruction
1221   * @retval None
1222   */
HAL_PWREx_EnterSTOP2Mode(uint8_t STOPEntry)1223 void HAL_PWREx_EnterSTOP2Mode(uint8_t STOPEntry)
1224 {
1225   /* Check the parameter */
1226   assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
1227 
1228   /* Set Stop mode 2 */
1229   MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_STOP2);
1230 
1231   /* Set SLEEPDEEP bit of Cortex System Control Register */
1232   SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1233 
1234   /* Select Stop mode entry --------------------------------------------------*/
1235   if (STOPEntry == PWR_STOPENTRY_WFI)
1236   {
1237     /* Request Wait For Interrupt */
1238     __WFI();
1239   }
1240   else
1241   {
1242     /* Request Wait For Event */
1243     __SEV();
1244     __WFE();
1245     __WFE();
1246   }
1247 
1248   /* Reset SLEEPDEEP bit of Cortex System Control Register */
1249   CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1250 }
1251 #endif /* PWR_SUPPORT_STOP2 */
1252 
1253 /**
1254   * @brief Enter Shutdown mode.
1255   * @note  In Shutdown mode, the PLL, the HSI, the MSI, the LSI and the HSE oscillators are switched
1256   *        off. The voltage regulator is disabled and Vcore domain is powered off.
1257   *        SRAM1, SRAM2, BKRAM and registers contents are lost except for registers in the Backup domain.
1258   *        The BOR is not available.
1259   * @note  The I/Os can be configured either with a pull-up or pull-down or can be kept in analog state.
1260   * @note  According to system power policy, system entering in Shutdown mode
1261   *        is depending on other CPU power mode.
1262   * @retval None
1263   */
HAL_PWREx_EnterSHUTDOWNMode(void)1264 void HAL_PWREx_EnterSHUTDOWNMode(void)
1265 {
1266   /* Set Shutdown mode */
1267   MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_SHUTDOWN);
1268 
1269   /* Set SLEEPDEEP bit of Cortex System Control Register */
1270   SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1271 
1272   /* This option is used to ensure that store operations are completed */
1273 #if defined (__CC_ARM)
1274   __force_stores();
1275 #endif /* __CC_ARM */
1276 
1277   /* Request Wait For Interrupt */
1278   __WFI();
1279 
1280   /* Following code is executed after wake up if system didn't go to SHUTDOWN
1281    * or STANDBY mode according to power policy */
1282 
1283   /* Reset SLEEPDEEP bit of Cortex System Control Register */
1284   CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1285 }
1286 
1287 
1288 /**
1289   * @brief This function handles the PWR PVD/PVMx interrupt request.
1290   * @note This API should be called under the PVD_PVM_IRQHandler().
1291   * @retval None
1292   */
HAL_PWREx_PVD_PVM_IRQHandler(void)1293 void HAL_PWREx_PVD_PVM_IRQHandler(void)
1294 {
1295   /* Check PWR exti flag */
1296   if (__HAL_PWR_PVD_EXTI_GET_FLAG() != 0U)
1297   {
1298     /* PWR PVD interrupt user callback */
1299     HAL_PWR_PVDCallback();
1300 
1301     /* Clear PVD exti pending bit */
1302     __HAL_PWR_PVD_EXTI_CLEAR_FLAG();
1303   }
1304 
1305 #if defined(PWR_CR2_PVME1)
1306   /* Next, successively check PVMx exti flags */
1307   if (__HAL_PWR_PVM1_EXTI_GET_FLAG() != 0U)
1308   {
1309     /* PWR PVM1 interrupt user callback */
1310     HAL_PWREx_PVM1Callback();
1311 
1312     /* Clear PVM1 exti pending bit */
1313     __HAL_PWR_PVM1_EXTI_CLEAR_FLAG();
1314   }
1315 #endif /* PWR_CR2_PVME1 */
1316 
1317   if (__HAL_PWR_PVM3_EXTI_GET_FLAG() != 0U)
1318   {
1319     /* PWR PVM3 interrupt user callback */
1320     HAL_PWREx_PVM3Callback();
1321 
1322     /* Clear PVM3 exti pending bit */
1323     __HAL_PWR_PVM3_EXTI_CLEAR_FLAG();
1324   }
1325 }
1326 
1327 #if defined(PWR_CR2_PVME1)
1328 /**
1329   * @brief PWR PVM1 interrupt callback
1330   * @retval None
1331   */
HAL_PWREx_PVM1Callback(void)1332 __weak void HAL_PWREx_PVM1Callback(void)
1333 {
1334   /* NOTE : This function should not be modified; when the callback is needed,
1335             HAL_PWREx_PVM1Callback() API can be implemented in the user file
1336    */
1337 }
1338 #endif /* PWR_CR2_PVME1 */
1339 
1340 /**
1341   * @brief PWR PVM3 interrupt callback
1342   * @retval None
1343   */
HAL_PWREx_PVM3Callback(void)1344 __weak void HAL_PWREx_PVM3Callback(void)
1345 {
1346   /* NOTE : This function should not be modified; when the callback is needed,
1347             HAL_PWREx_PVM3Callback() API can be implemented in the user file
1348    */
1349 }
1350 
1351 
1352 /**
1353   * @}
1354   */
1355 
1356 /**
1357   * @}
1358   */
1359 
1360 #endif /* HAL_PWR_MODULE_ENABLED */
1361 /**
1362   * @}
1363   */
1364 
1365 /**
1366   * @}
1367   */
1368 
1369