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   * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
15   * All rights reserved.</center></h2>
16   *
17   * This software component is licensed by ST under BSD 3-Clause license,
18   * the "License"; You may not use this file except in compliance with the
19   * License. You may obtain a copy of the License at:
20   *                        opensource.org/licenses/BSD-3-Clause
21   *
22   ******************************************************************************
23   */
24 
25 /* Includes ------------------------------------------------------------------*/
26 #include "stm32wbxx_hal.h"
27 
28 /** @addtogroup STM32WBxx_HAL_Driver
29   * @{
30   */
31 
32 /** @addtogroup PWREx
33   * @{
34   */
35 
36 #ifdef HAL_PWR_MODULE_ENABLED
37 
38 /* Private typedef -----------------------------------------------------------*/
39 /* Private define ------------------------------------------------------------*/
40 /** @defgroup PWR_Extended_Private_Defines PWR Extended Private Defines
41   * @{
42   */
43 #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)
44 #define PWR_PORTH_AVAILABLE_PINS   (PWR_GPIO_BIT_3 | PWR_GPIO_BIT_1 | PWR_GPIO_BIT_0)
45 
46 /** @defgroup PWREx_TimeOut_Value PWR Extended Flag Setting Time Out Value
47   * @{
48   */
49 #define PWR_FLAG_SETTING_DELAY_US                      50U   /*!< Time out value for REGLPF and VOSF flags setting */
50 /**
51   * @}
52   */
53 
54 /**
55   * @}
56   */
57 
58 
59 
60 /* Private macro -------------------------------------------------------------*/
61 /* Private variables ---------------------------------------------------------*/
62 /* Private function prototypes -----------------------------------------------*/
63 /* Exported functions --------------------------------------------------------*/
64 /** @addtogroup PWREx_Exported_Functions PWR Extended Exported Functions
65   * @{
66   */
67 
68 /** @addtogroup PWREx_Exported_Functions_Group1 Extended Peripheral Control functions
69   *  @brief   Extended Peripheral Control functions
70   *
71 @verbatim
72  ===============================================================================
73               ##### Extended Peripheral Initialization and de-initialization functions #####
74  ===============================================================================
75     [..]
76 
77 @endverbatim
78   * @{
79   */
80 
81 
82 #if defined(PWR_CR1_VOS)
83 /**
84   * @brief Return Voltage Scaling Range.
85   * @retval VOS bit field (PWR_REGULATOR_VOLTAGE_RANGE1 or PWR_REGULATOR_VOLTAGE_RANGE2)
86   */
HAL_PWREx_GetVoltageRange(void)87 uint32_t HAL_PWREx_GetVoltageRange(void)
88 {
89   return  (PWR->CR1 & PWR_CR1_VOS);
90 }
91 
92 /**
93   * @brief Configure the main internal regulator output voltage.
94   * @param VoltageScaling specifies the regulator output voltage to achieve
95   *         a tradeoff between performance and power consumption.
96   *          This parameter can be one of the following values:
97   *            @arg @ref PWR_REGULATOR_VOLTAGE_SCALE1 Regulator voltage output range 1 mode,
98   *                                                typical output voltage at 1.2 V,
99   *                                                system frequency up to 64 MHz.
100   *            @arg @ref PWR_REGULATOR_VOLTAGE_SCALE2 Regulator voltage output range 2 mode,
101   *                                                typical output voltage at 1.0 V,
102   *                                                system frequency up to 16 MHz.
103   * @note  When moving from Range 1 to Range 2, the system frequency must be decreased to
104   *        a value below 16 MHz before calling HAL_PWREx_ControlVoltageScaling() API.
105   *        When moving from Range 2 to Range 1, the system frequency can be increased to
106   *        a value up to 64 MHz after calling HAL_PWREx_ControlVoltageScaling() API.
107   * @note  When moving from Range 2 to Range 1, the API waits for VOSF flag to be
108   *        cleared before returning the status. If the flag is not cleared within
109   *        50 microseconds, HAL_TIMEOUT status is reported.
110   * @retval HAL Status
111   */
HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling)112 HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling)
113 {
114   uint32_t wait_loop_index;
115 
116   assert_param(IS_PWR_VOLTAGE_SCALING_RANGE(VoltageScaling));
117 
118   /* If Set Range 1 */
119   if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1)
120   {
121     if (READ_BIT(PWR->CR1, PWR_CR1_VOS) != PWR_REGULATOR_VOLTAGE_SCALE1)
122     {
123       /* Set Range 1 */
124       MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1);
125 
126       /* Wait until VOSF is cleared */
127       wait_loop_index = (PWR_FLAG_SETTING_DELAY_US * (SystemCoreClock / 1000000U));
128       while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) && (wait_loop_index != 0U))
129       {
130         wait_loop_index--;
131       }
132       if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF))
133       {
134         return HAL_TIMEOUT;
135       }
136     }
137   }
138   else
139   {
140     if (READ_BIT(PWR->CR1, PWR_CR1_VOS) != PWR_REGULATOR_VOLTAGE_SCALE2)
141     {
142       /* Set Range 2 */
143       MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE2);
144       /* No need to wait for VOSF to be cleared for this transition */
145     }
146   }
147 
148   return HAL_OK;
149 }
150 #endif
151 
152 /****************************************************************************/
153 
154 /**
155   * @brief Enable battery charging.
156   *        When VDD is present, charge the external battery on VBAT thru an internal resistor.
157   * @param ResistorSelection specifies the resistor impedance.
158   *          This parameter can be one of the following values:
159   *            @arg @ref PWR_BATTERY_CHARGING_RESISTOR_5     5 kOhms resistor
160   *            @arg @ref PWR_BATTERY_CHARGING_RESISTOR_1_5 1.5 kOhms resistor
161   * @retval None
162   */
HAL_PWREx_EnableBatteryCharging(uint32_t ResistorSelection)163 void HAL_PWREx_EnableBatteryCharging(uint32_t ResistorSelection)
164 {
165   assert_param(IS_PWR_BATTERY_RESISTOR_SELECT(ResistorSelection));
166 
167   /* Specify resistor selection */
168   MODIFY_REG(PWR->CR4, PWR_CR4_VBRS, ResistorSelection);
169 
170   /* Enable battery charging */
171   SET_BIT(PWR->CR4, PWR_CR4_VBE);
172 }
173 
174 /**
175   * @brief Disable battery charging.
176   * @retval None
177   */
HAL_PWREx_DisableBatteryCharging(void)178 void HAL_PWREx_DisableBatteryCharging(void)
179 {
180   CLEAR_BIT(PWR->CR4, PWR_CR4_VBE);
181 }
182 
183 /****************************************************************************/
184 #if defined(PWR_CR2_PVME1)
185 /**
186   * @brief Enable VDDUSB supply.
187   * @note  Remove VDDUSB electrical and logical isolation, once VDDUSB supply is present.
188   * @retval None
189   */
HAL_PWREx_EnableVddUSB(void)190 void HAL_PWREx_EnableVddUSB(void)
191 {
192   SET_BIT(PWR->CR2, PWR_CR2_USV);
193 }
194 
195 /**
196   * @brief Disable VDDUSB supply.
197   * @retval None
198   */
HAL_PWREx_DisableVddUSB(void)199 void HAL_PWREx_DisableVddUSB(void)
200 {
201   CLEAR_BIT(PWR->CR2, PWR_CR2_USV);
202 }
203 #endif
204 
205 /****************************************************************************/
206 
207 /**
208   * @brief Enable Internal Wake-up Line.
209   * @retval None
210   */
HAL_PWREx_EnableInternalWakeUpLine(void)211 void HAL_PWREx_EnableInternalWakeUpLine(void)
212 {
213   SET_BIT(PWR->CR3, PWR_CR3_EIWUL);
214 }
215 
216 /**
217   * @brief Disable Internal Wake-up Line.
218   * @retval None
219   */
HAL_PWREx_DisableInternalWakeUpLine(void)220 void HAL_PWREx_DisableInternalWakeUpLine(void)
221 {
222   CLEAR_BIT(PWR->CR3, PWR_CR3_EIWUL);
223 }
224 
225 #if defined(PWR_CR5_SMPSEN)
226 /**
227   * @brief Enable BORH and SMPS step down converter forced in bypass mode
228   *        interrupt for CPU1
229   * @retval None
230   */
HAL_PWREx_EnableBORH_SMPSBypassIT(void)231 void HAL_PWREx_EnableBORH_SMPSBypassIT(void)
232 {
233   SET_BIT(PWR->CR3, PWR_CR3_EBORHSMPSFB);
234 }
235 
236 /**
237   * @brief Disable BORH and SMPS step down converter forced in bypass mode
238   *        interrupt for CPU1
239   * @retval None
240   */
HAL_PWREx_DisableBORH_SMPSBypassIT(void)241 void HAL_PWREx_DisableBORH_SMPSBypassIT(void)
242 {
243   CLEAR_BIT(PWR->CR3, PWR_CR3_EBORHSMPSFB);
244 }
245 #endif
246 
247 /**
248   * @brief Enable RF Phase interrupt.
249   * @retval None
250   */
HAL_PWREx_EnableRFPhaseIT(void)251 void HAL_PWREx_EnableRFPhaseIT(void)
252 {
253   SET_BIT(PWR->CR3, PWR_CR3_ECRPE_Msk);
254 }
255 
256 /**
257   * @brief Disable RF Phase interrupt.
258   * @retval None
259   */
HAL_PWREx_DisableRFPhaseIT(void)260 void HAL_PWREx_DisableRFPhaseIT(void)
261 {
262   CLEAR_BIT(PWR->CR3, PWR_CR3_ECRPE_Msk);
263 }
264 
265 
266 /**
267   * @brief Enable BLE Activity interrupt.
268   * @retval None
269   */
HAL_PWREx_EnableBLEActivityIT(void)270 void HAL_PWREx_EnableBLEActivityIT(void)
271 {
272   SET_BIT(PWR->CR3, PWR_CR3_EBLEA);
273 }
274 
275 /**
276   * @brief Disable BLE Activity interrupt.
277   * @retval None
278   */
HAL_PWREx_DisableBLEActivityIT(void)279 void HAL_PWREx_DisableBLEActivityIT(void)
280 {
281   CLEAR_BIT(PWR->CR3, PWR_CR3_EBLEA);
282 }
283 
284 
285 /**
286   * @brief Enable 802.15.4 Activity interrupt.
287   * @retval None
288   */
HAL_PWREx_Enable802ActivityIT(void)289 void HAL_PWREx_Enable802ActivityIT(void)
290 {
291   SET_BIT(PWR->CR3, PWR_CR3_E802A);
292 }
293 
294 /**
295   * @brief Disable 802.15.4 Activity interrupt.
296   * @retval None
297   */
HAL_PWREx_Disable802ActivityIT(void)298 void HAL_PWREx_Disable802ActivityIT(void)
299 {
300   CLEAR_BIT(PWR->CR3, PWR_CR3_E802A);
301 }
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
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
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
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
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
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 BKRAM content retention in Standby mode.
644   * @note  When RRS bit is set, SRAM is powered by the low-power regulator in
645   *         Standby mode and its content is kept.
646   * @retval None
647   */
HAL_PWREx_EnableSRAMRetention(void)648 void HAL_PWREx_EnableSRAMRetention(void)
649 {
650   LL_PWR_EnableSRAM2Retention();
651 }
652 
653 /**
654   * @brief Disable BKRAM content retention in Standby mode.
655   * @note  When RRS bit is reset, SRAM is powered off in Standby mode
656   *        and its content is lost.
657   * @retval None
658   */
HAL_PWREx_DisableSRAMRetention(void)659 void HAL_PWREx_DisableSRAMRetention(void)
660 {
661   LL_PWR_DisableSRAM2Retention();
662 }
663 
664 /****************************************************************************/
665 /**
666   * @brief  Enable Flash Power Down.
667   * @note   This API allows to enable flash power down capabilities in low power
668   *         run and low power sleep modes.
669   * @param  PowerMode this can be a combination of following values:
670   *           @arg @ref PWR_FLASHPD_LPRUN
671   *           @arg @ref PWR_FLASHPD_LPSLEEP
672   * @retval None
673   */
HAL_PWREx_EnableFlashPowerDown(uint32_t PowerMode)674 void HAL_PWREx_EnableFlashPowerDown(uint32_t PowerMode)
675 {
676   assert_param(IS_PWR_FLASH_POWERDOWN(PowerMode));
677 
678   if((PowerMode & PWR_FLASHPD_LPRUN) != 0U)
679   {
680     /* Unlock bit FPDR */
681     WRITE_REG(PWR->CR1, 0x0000C1B0U);
682   }
683 
684   /* Set flash power down mode */
685   SET_BIT(PWR->CR1, PowerMode);
686 }
687 
688 /**
689   * @brief  Disable Flash Power Down.
690   * @note   This API allows to disable flash power down capabilities in low power
691   *         run and low power sleep modes.
692   * @param  PowerMode this can be a combination of following values:
693   *           @arg @ref PWR_FLASHPD_LPRUN
694   *           @arg @ref PWR_FLASHPD_LPSLEEP
695   * @retval None
696   */
HAL_PWREx_DisableFlashPowerDown(uint32_t PowerMode)697 void HAL_PWREx_DisableFlashPowerDown(uint32_t PowerMode)
698 {
699   assert_param(IS_PWR_FLASH_POWERDOWN(PowerMode));
700 
701   /* Set flash power down mode */
702   CLEAR_BIT(PWR->CR1, PowerMode);
703 }
704 
705 /****************************************************************************/
706 #if defined(PWR_CR2_PVME1)
707 /**
708   * @brief Enable the Power Voltage Monitoring 1: VDDUSB versus 1.2V.
709   * @retval None
710   */
HAL_PWREx_EnablePVM1(void)711 void HAL_PWREx_EnablePVM1(void)
712 {
713   SET_BIT(PWR->CR2, PWR_PVM_1);
714 }
715 
716 /**
717   * @brief Disable the Power Voltage Monitoring 1: VDDUSB versus 1.2V.
718   * @retval None
719   */
HAL_PWREx_DisablePVM1(void)720 void HAL_PWREx_DisablePVM1(void)
721 {
722   CLEAR_BIT(PWR->CR2, PWR_PVM_1);
723 }
724 #endif
725 
726 /**
727   * @brief Enable the Power Voltage Monitoring 3: VDDA versus 1.62V.
728   * @retval None
729   */
HAL_PWREx_EnablePVM3(void)730 void HAL_PWREx_EnablePVM3(void)
731 {
732   SET_BIT(PWR->CR2, PWR_PVM_3);
733 }
734 
735 /**
736   * @brief Disable the Power Voltage Monitoring 3: VDDA versus 1.62V.
737   * @retval None
738   */
HAL_PWREx_DisablePVM3(void)739 void HAL_PWREx_DisablePVM3(void)
740 {
741   CLEAR_BIT(PWR->CR2, PWR_PVM_3);
742 }
743 
744 
745 
746 
747 /**
748   * @brief Configure the Peripheral Voltage Monitoring (PVM).
749   * @param sConfigPVM pointer to a PWR_PVMTypeDef structure that contains the
750   *        PVM configuration information.
751   * @note The API configures a single PVM according to the information contained
752   *       in the input structure. To configure several PVMs, the API must be singly
753   *       called for each PVM used.
754   * @note Refer to the electrical characteristics of your device datasheet for
755   *         more details about the voltage thresholds corresponding to each
756   *         detection level and to each monitored supply.
757   * @retval HAL status
758   */
HAL_PWREx_ConfigPVM(PWR_PVMTypeDef * sConfigPVM)759 HAL_StatusTypeDef HAL_PWREx_ConfigPVM(PWR_PVMTypeDef *sConfigPVM)
760 {
761   HAL_StatusTypeDef status = HAL_OK;
762 
763   /* Check the parameters */
764   assert_param(IS_PWR_PVM_TYPE(sConfigPVM->PVMType));
765   assert_param(IS_PWR_PVM_MODE(sConfigPVM->Mode));
766 
767   /* Configure EXTI 31 and 33 interrupts if so required:
768      scan thru PVMType to detect which PVMx is set and
769      configure the corresponding EXTI line accordingly. */
770   switch (sConfigPVM->PVMType)
771   {
772 #if defined(PWR_CR2_PVME1)
773    case PWR_PVM_1:
774       /* Clear any previous config. Keep it clear if no event or IT mode is selected */
775       __HAL_PWR_PVM1_EXTI_DISABLE_EVENT();
776       __HAL_PWR_PVM1_EXTI_DISABLE_IT();
777       __HAL_PWR_PVM1_EXTI_DISABLE_FALLING_EDGE();
778       __HAL_PWR_PVM1_EXTI_DISABLE_RISING_EDGE();
779 
780       /* Configure interrupt mode */
781       if((sConfigPVM->Mode & PVM_MODE_IT) == PVM_MODE_IT)
782       {
783         __HAL_PWR_PVM1_EXTI_ENABLE_IT();
784       }
785 
786       /* Configure event mode */
787       if((sConfigPVM->Mode & PVM_MODE_EVT) == PVM_MODE_EVT)
788       {
789         __HAL_PWR_PVM1_EXTI_ENABLE_EVENT();
790       }
791 
792       /* Configure the edge */
793       if((sConfigPVM->Mode & PVM_RISING_EDGE) == PVM_RISING_EDGE)
794       {
795         __HAL_PWR_PVM1_EXTI_ENABLE_RISING_EDGE();
796       }
797 
798       if((sConfigPVM->Mode & PVM_FALLING_EDGE) == PVM_FALLING_EDGE)
799       {
800         __HAL_PWR_PVM1_EXTI_ENABLE_FALLING_EDGE();
801       }
802       break;
803 #endif
804 
805     case PWR_PVM_3:
806       /* Clear any previous config. Keep it clear if no event or IT mode is selected */
807       __HAL_PWR_PVM3_EXTI_DISABLE_EVENT();
808       __HAL_PWR_PVM3_EXTI_DISABLE_IT();
809       __HAL_PWR_PVM3_EXTI_DISABLE_FALLING_EDGE();
810       __HAL_PWR_PVM3_EXTI_DISABLE_RISING_EDGE();
811 
812       /* Configure interrupt mode */
813       if((sConfigPVM->Mode & PVM_MODE_IT) == PVM_MODE_IT)
814       {
815         __HAL_PWR_PVM3_EXTI_ENABLE_IT();
816       }
817 
818       /* Configure event mode */
819       if((sConfigPVM->Mode & PVM_MODE_EVT) == PVM_MODE_EVT)
820       {
821         __HAL_PWR_PVM3_EXTI_ENABLE_EVENT();
822       }
823 
824       /* Configure the edge */
825       if((sConfigPVM->Mode & PVM_RISING_EDGE) == PVM_RISING_EDGE)
826       {
827         __HAL_PWR_PVM3_EXTI_ENABLE_RISING_EDGE();
828       }
829 
830       if((sConfigPVM->Mode & PVM_FALLING_EDGE) == PVM_FALLING_EDGE)
831       {
832         __HAL_PWR_PVM3_EXTI_ENABLE_FALLING_EDGE();
833       }
834       break;
835 
836     default:
837       status = HAL_ERROR;
838       break;
839 
840   }
841 
842   return status;
843 }
844 
845 #if defined(PWR_CR5_SMPSEN)
846 /**
847   * @brief Configure the SMPS step down converter.
848   * @note   SMPS output voltage is calibrated in production,
849   *         calibration parameters are applied to the voltage level parameter
850   *         to reach the requested voltage value.
851   * @param sConfigSMPS pointer to a PWR_SMPSTypeDef structure that contains the
852   *        SMPS configuration information.
853   * @note  To set and enable SMPS operating mode, refer to function
854   *        "HAL_PWREx_SMPS_SetMode()".
855   * @retval HAL status
856   */
HAL_PWREx_ConfigSMPS(PWR_SMPSTypeDef * sConfigSMPS)857 HAL_StatusTypeDef HAL_PWREx_ConfigSMPS(PWR_SMPSTypeDef *sConfigSMPS)
858 {
859   HAL_StatusTypeDef status = HAL_OK;
860 
861   /* Check the parameters */
862   assert_param(IS_PWR_SMPS_STARTUP_CURRENT(sConfigSMPS->StartupCurrent));
863   assert_param(IS_PWR_SMPS_OUTPUT_VOLTAGE(sConfigSMPS->OutputVoltage));
864 
865   __IO const uint32_t OutputVoltageLevel_calibration = (((*SMPS_VOLTAGE_CAL_ADDR) & SMPS_VOLTAGE_CAL) >> SMPS_VOLTAGE_CAL_POS);  /* SMPS output voltage level calibrated in production */
866   int32_t TrimmingSteps;                         /* Trimming steps between theorical output voltage and calibrated output voltage */
867   int32_t OutputVoltageLevelTrimmed;             /* SMPS output voltage level after calibration: trimming value added to required level */
868 
869   if(OutputVoltageLevel_calibration == 0UL)
870   {
871     /* Device with SMPS output voltage not calibrated in production: Apply output voltage value directly */
872 
873     /* Update register */
874     MODIFY_REG(PWR->CR5, PWR_CR5_SMPSVOS, (sConfigSMPS->StartupCurrent | sConfigSMPS->OutputVoltage));
875   }
876   else
877   {
878     /* Device with SMPS output voltage calibrated in production: Apply output voltage value after correction by calibration value */
879 
880     TrimmingSteps = ((int32_t)OutputVoltageLevel_calibration - (int32_t)(LL_PWR_SMPS_OUTPUT_VOLTAGE_1V50 >> PWR_CR5_SMPSVOS_Pos));
881     OutputVoltageLevelTrimmed = ((int32_t)((uint32_t)(sConfigSMPS->OutputVoltage >> PWR_CR5_SMPSVOS_Pos)) + (int32_t)TrimmingSteps);
882 
883     /* Clamp value to voltage trimming bitfield range */
884     if(OutputVoltageLevelTrimmed < 0)
885     {
886       OutputVoltageLevelTrimmed = 0;
887       status = HAL_ERROR;
888     }
889     else
890     {
891       if(OutputVoltageLevelTrimmed > (int32_t)PWR_CR5_SMPSVOS)
892       {
893         OutputVoltageLevelTrimmed = (int32_t)PWR_CR5_SMPSVOS;
894         status = HAL_ERROR;
895       }
896     }
897 
898     /* Update register */
899     MODIFY_REG(PWR->CR5, (PWR_CR5_SMPSSC | PWR_CR5_SMPSVOS), (sConfigSMPS->StartupCurrent | ((uint32_t) OutputVoltageLevelTrimmed)));
900   }
901 
902   return status;
903 }
904 
905 /**
906   * @brief Set SMPS operating mode.
907   * @param  OperatingMode This parameter can be one of the following values:
908   *         @arg @ref PWR_SMPS_BYPASS
909   *         @arg @ref PWR_SMPS_STEP_DOWN (1)
910   *
911   *         (1) SMPS operating mode step down or open depends on system low-power mode:
912   *              - step down mode if system low power mode is run, LP run or stop,
913   *              - open mode if system low power mode is stop1, stop2, standby or shutdown
914   * @retval None
915   */
HAL_PWREx_SMPS_SetMode(uint32_t OperatingMode)916 void HAL_PWREx_SMPS_SetMode(uint32_t OperatingMode)
917 {
918   MODIFY_REG(PWR->CR5, PWR_CR5_SMPSEN, (OperatingMode & PWR_SR2_SMPSF) << (PWR_CR5_SMPSEN_Pos - PWR_SR2_SMPSF_Pos));
919 }
920 
921 /**
922   * @brief  Get SMPS effective operating mode
923   * @note   SMPS operating mode can be changed by hardware, therefore
924   *         requested operating mode can differ from effective low power mode.
925   *         - dependency on system low-power mode:
926   *           - step down mode if system low power mode is run, LP run or stop,
927   *           - open mode if system low power mode is stop1, stop2, standby or shutdown
928   *         - dependency on BOR level:
929   *           - bypass mode if supply voltage drops below BOR level
930   * @note   This functions check flags of SMPS operating modes step down
931   *         and bypass. If the SMPS is not among these 2 operating modes,
932   *         then it can be in mode off or open.
933   * @retval Returned value can be one of the following values:
934   *         @arg @ref PWR_SMPS_BYPASS
935   *         @arg @ref PWR_SMPS_STEP_DOWN (1)
936   *
937   *         (1) SMPS operating mode step down or open depends on system low-power mode:
938   *              - step down mode if system low power mode is run, LP run or stop,
939   *              - open mode if system low power mode is stop1, stop2, standby or shutdown
940   */
HAL_PWREx_SMPS_GetEffectiveMode(void)941 uint32_t HAL_PWREx_SMPS_GetEffectiveMode(void)
942 {
943   return (uint32_t)(READ_BIT(PWR->SR2, (PWR_SR2_SMPSF | PWR_SR2_SMPSBF)));
944 }
945 #endif
946 
947 /****************************************************************************/
948 
949 /**
950   * @brief Enable the WakeUp PINx functionality.
951   * @param WakeUpPinPolarity Specifies which Wake-Up pin to enable.
952   *         This parameter can be one of the following legacy values which set the default polarity
953   *         i.e. detection on high level (rising edge):
954   *           @arg @ref PWR_WAKEUP_PIN1, PWR_WAKEUP_PIN2, PWR_WAKEUP_PIN3, PWR_WAKEUP_PIN4, PWR_WAKEUP_PIN5
955   *
956   *         or one of the following value where the user can explicitly specify the enabled pin and
957   *         the chosen polarity:
958   *           @arg @ref PWR_WAKEUP_PIN1_HIGH or PWR_WAKEUP_PIN1_LOW
959   *           @arg @ref PWR_WAKEUP_PIN2_HIGH or PWR_WAKEUP_PIN2_LOW
960   *           @arg @ref PWR_WAKEUP_PIN3_HIGH or PWR_WAKEUP_PIN3_LOW
961   *           @arg @ref PWR_WAKEUP_PIN4_HIGH or PWR_WAKEUP_PIN4_LOW
962   *           @arg @ref PWR_WAKEUP_PIN5_HIGH or PWR_WAKEUP_PIN5_LOW
963   * @param wakeupTarget Specifies the wake-up target
964   *         @arg @ref PWR_CORE_CPU1
965   *         @arg @ref PWR_CORE_CPU2
966   * @note  PWR_WAKEUP_PINx and PWR_WAKEUP_PINx_HIGH are equivalent.
967   * @retval None
968   */
HAL_PWREx_EnableWakeUpPin(uint32_t WakeUpPinPolarity,uint32_t wakeupTarget)969 void HAL_PWREx_EnableWakeUpPin(uint32_t WakeUpPinPolarity, uint32_t wakeupTarget)
970 {
971   assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinPolarity));
972 
973   /* Specifies the Wake-Up pin polarity for the event detection
974     (rising or falling edge) */
975   MODIFY_REG(PWR->CR4, (PWR_C2CR3_EWUP & WakeUpPinPolarity), (WakeUpPinPolarity >> PWR_WUP_POLARITY_SHIFT));
976 
977   /* Enable wake-up pin */
978   if(PWR_CORE_CPU2 == wakeupTarget)
979   {
980     SET_BIT(PWR->C2CR3, (PWR_C2CR3_EWUP & WakeUpPinPolarity));
981   }
982   else
983   {
984     SET_BIT(PWR->CR3, (PWR_CR3_EWUP & WakeUpPinPolarity));
985   }
986 }
987 
988 /**
989   * @brief  Get the Wake-Up pin flag.
990   * @param WakeUpFlag specifies the Wake-Up PIN flag to check.
991   *          This parameter can be one of the following values:
992   *            @arg PWR_FLAG_WUF1: A wakeup event was received from PA0.
993   *            @arg PWR_FLAG_WUF2: A wakeup event was received from PC13.
994   *            @arg PWR_FLAG_WUF3: A wakeup event was received from PC12.
995   *            @arg PWR_FLAG_WUF4: A wakeup event was received from PA2.
996   *            @arg PWR_FLAG_WUF5: A wakeup event was received from PC5.
997   * @retval The Wake-Up pin flag.
998   */
HAL_PWREx_GetWakeupFlag(uint32_t WakeUpFlag)999 uint32_t  HAL_PWREx_GetWakeupFlag(uint32_t WakeUpFlag)
1000 {
1001   return (PWR->SR1 & (1UL << ((WakeUpFlag) & 31U)));
1002 }
1003 
1004 /**
1005   * @brief  Clear the Wake-Up pin flag.
1006   * @param WakeUpFlag specifies the Wake-Up PIN flag to clear.
1007   *          This parameter can be one of the following values:
1008   *            @arg PWR_FLAG_WUF1: A wakeup event was received from PA0.
1009   *            @arg PWR_FLAG_WUF2: A wakeup event was received from PC13.
1010   *            @arg PWR_FLAG_WUF3: A wakeup event was received from PC12.
1011   *            @arg PWR_FLAG_WUF4: A wakeup event was received from PA2.
1012   *            @arg PWR_FLAG_WUF5: A wakeup event was received from PC5.
1013   * @retval HAL status.
1014   */
HAL_PWREx_ClearWakeupFlag(uint32_t WakeUpFlag)1015 HAL_StatusTypeDef HAL_PWREx_ClearWakeupFlag(uint32_t WakeUpFlag)
1016 {
1017   PWR->SCR = (1UL << ((WakeUpFlag) & 31U));
1018 
1019   if((PWR->SR1 & (1UL << ((WakeUpFlag) & 31U))) != 0U)
1020   {
1021     return HAL_ERROR;
1022   }
1023   return HAL_OK;
1024 }
1025 
1026 /****************************************************************************/
1027 
1028 /**
1029   * @brief Enter Low-power Run mode
1030   * @note  In Low-power Run mode, all I/O pins keep the same state as in Run mode.
1031   * @note  When Regulator is set to PWR_LOWPOWERREGULATOR_ON, the user can optionally configure the
1032   *        Flash in power-down mode in setting the RUN_PD bit in FLASH_ACR register.
1033   *        Additionally, the clock frequency must be reduced below 2 MHz.
1034   *        Setting RUN_PD in FLASH_ACR then appropriately reducing the clock frequency must
1035   *        be done before calling HAL_PWREx_EnableLowPowerRunMode() API.
1036   * @retval None
1037   */
HAL_PWREx_EnableLowPowerRunMode(void)1038 void HAL_PWREx_EnableLowPowerRunMode(void)
1039 {
1040   /* Set Regulator parameter */
1041   SET_BIT(PWR->CR1, PWR_CR1_LPR);
1042 }
1043 
1044 
1045 /**
1046   * @brief Exit Low-power Run mode.
1047   * @note  Before HAL_PWREx_DisableLowPowerRunMode() completion, the function checks that
1048   *        REGLPF has been properly reset (otherwise, HAL_PWREx_DisableLowPowerRunMode
1049   *        returns HAL_TIMEOUT status). The system clock frequency can then be
1050   *        increased above 2 MHz.
1051   * @retval HAL Status
1052   */
HAL_PWREx_DisableLowPowerRunMode(void)1053 HAL_StatusTypeDef HAL_PWREx_DisableLowPowerRunMode(void)
1054 {
1055   uint32_t wait_loop_index;
1056 
1057   /* Clear LPR bit */
1058   CLEAR_BIT(PWR->CR1, PWR_CR1_LPR);
1059 
1060   /* Wait until REGLPF is reset */
1061   wait_loop_index = (PWR_FLAG_SETTING_DELAY_US * (SystemCoreClock / 1000000U));
1062   while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_REGLPF)) && (wait_loop_index != 0U))
1063   {
1064     wait_loop_index--;
1065   }
1066   if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_REGLPF))
1067   {
1068     return HAL_TIMEOUT;
1069   }
1070 
1071   return HAL_OK;
1072 }
1073 
1074 /****************************************************************************/
1075 
1076 /**
1077   * @brief Enter Stop 0 mode.
1078   * @note  In Stop 0 mode, main and low voltage regulators are ON.
1079   * @note  In Stop 0 mode, all I/O pins keep the same state as in Run mode.
1080   * @note  All clocks in the VCORE domain are stopped; the PLL, the MSI,
1081   *        the HSI and the HSE oscillators are disabled. Some peripherals with the wakeup capability
1082   *        (I2Cx, USARTx and LPUART) can switch on the HSI to receive a frame, and switch off the HSI
1083   *        after receiving the frame if it is not a wakeup frame. In this case, the HSI clock is propagated
1084   *        only to the peripheral requesting it.
1085   *        SRAM1, SRAM2 and register contents are preserved.
1086   *        The BOR is available.
1087   * @note  When exiting Stop 0 mode by issuing an interrupt or a wakeup event,
1088   *         the HSI RC oscillator is selected as system clock if STOPWUCK bit in RCC_CFGR register
1089   *         is set; the MSI oscillator is selected if STOPWUCK is cleared.
1090   * @note  By keeping the internal regulator ON during Stop 0 mode, the consumption
1091   *         is higher although the startup time is reduced.
1092   * @note  Case of Stop0 mode with SMPS: Before entering Stop 0 mode with SMPS Step Down converter enabled,
1093   *        the HSI16 must be kept on by enabling HSI kernel clock (set HSIKERON register bit).
1094   * @note  According to system power policy, system entering in Stop mode
1095   *        is depending on other CPU power mode.
1096   * @param STOPEntry  specifies if Stop mode in entered with WFI or WFE instruction.
1097   *          This parameter can be one of the following values:
1098   *            @arg @ref PWR_STOPENTRY_WFI  Enter Stop mode with WFI instruction
1099   *            @arg @ref PWR_STOPENTRY_WFE  Enter Stop mode with WFE instruction
1100   * @retval None
1101   */
HAL_PWREx_EnterSTOP0Mode(uint8_t STOPEntry)1102 void HAL_PWREx_EnterSTOP0Mode(uint8_t STOPEntry)
1103 {
1104   /* Check the parameters */
1105   assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
1106 
1107   /* Stop 0 mode with Main Regulator */
1108   MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_STOP0);
1109 
1110 
1111   /* Set SLEEPDEEP bit of Cortex System Control Register */
1112   SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1113 
1114   /* Select Stop mode entry --------------------------------------------------*/
1115   if(STOPEntry == PWR_STOPENTRY_WFI)
1116   {
1117     /* Request Wait For Interrupt */
1118     __WFI();
1119   }
1120   else
1121   {
1122     /* Request Wait For Event */
1123     __SEV();
1124     __WFE();
1125     __WFE();
1126   }
1127 
1128   /* Reset SLEEPDEEP bit of Cortex System Control Register */
1129   CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1130 }
1131 
1132 
1133 /**
1134   * @brief Enter Stop 1 mode.
1135   * @note  In Stop 1 mode, only low power voltage regulator is ON.
1136   * @note  In Stop 1 mode, all I/O pins keep the same state as in Run mode.
1137   * @note  All clocks in the VCORE domain are stopped; the PLL, the MSI,
1138   *        the HSI and the HSE oscillators are disabled. Some peripherals with the wakeup capability
1139   *        (I2Cx, USARTx and LPUART) can switch on the HSI to receive a frame, and switch off the HSI
1140   *        after receiving the frame if it is not a wakeup frame. In this case, the HSI clock is propagated
1141   *        only to the peripheral requesting it.
1142   *        SRAM1, SRAM2 and register contents are preserved.
1143   *        The BOR is available.
1144   * @note  When exiting Stop 1 mode by issuing an interrupt or a wakeup event,
1145   *         the HSI RC oscillator is selected as system clock if STOPWUCK bit in RCC_CFGR register
1146   *         is set; the MSI oscillator is selected if STOPWUCK is cleared.
1147   * @note  Due to low power mode, an additional startup delay is incurred when waking up from Stop 1 mode.
1148   * @note  According to system power policy, system entering in Stop mode
1149   *        is depending on other CPU power mode.
1150   * @param STOPEntry  specifies if Stop mode in entered with WFI or WFE instruction.
1151   *          This parameter can be one of the following values:
1152   *            @arg @ref PWR_STOPENTRY_WFI  Enter Stop mode with WFI instruction
1153   *            @arg @ref PWR_STOPENTRY_WFE  Enter Stop mode with WFE instruction
1154   * @retval None
1155   */
HAL_PWREx_EnterSTOP1Mode(uint8_t STOPEntry)1156 void HAL_PWREx_EnterSTOP1Mode(uint8_t STOPEntry)
1157 {
1158   /* Check the parameters */
1159   assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
1160 
1161   /* Stop 1 mode with Low-Power Regulator */
1162   MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_STOP1);
1163 
1164   /* Set SLEEPDEEP bit of Cortex System Control Register */
1165   SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1166 
1167   /* Select Stop mode entry --------------------------------------------------*/
1168   if(STOPEntry == PWR_STOPENTRY_WFI)
1169   {
1170     /* Request Wait For Interrupt */
1171     __WFI();
1172   }
1173   else
1174   {
1175     /* Request Wait For Event */
1176     __SEV();
1177     __WFE();
1178     __WFE();
1179   }
1180 
1181   /* Reset SLEEPDEEP bit of Cortex System Control Register */
1182   CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1183 }
1184 
1185 
1186 /**
1187   * @brief Enter Stop 2 mode.
1188   * @note  In Stop 2 mode, only low power voltage regulator is ON.
1189   * @note  In Stop 2 mode, all I/O pins keep the same state as in Run mode.
1190   * @note  All clocks in the VCORE domain are stopped, the PLL, the MSI,
1191   *        the HSI and the HSE oscillators are disabled. Some peripherals with wakeup capability
1192   *        (LCD, LPTIM1, I2C3 and LPUART) can switch on the HSI to receive a frame, and switch off the HSI after
1193   *        receiving the frame if it is not a wakeup frame. In this case the HSI clock is propagated only
1194   *        to the peripheral requesting it.
1195   *        SRAM1, SRAM2 and register contents are preserved.
1196   *        The BOR is available.
1197   *        The voltage regulator is set in low-power mode but LPR bit must be cleared to enter stop 2 mode.
1198   *        Otherwise, Stop 1 mode is entered.
1199   * @note  When exiting Stop 2 mode by issuing an interrupt or a wakeup event,
1200   *         the HSI RC oscillator is selected as system clock if STOPWUCK bit in RCC_CFGR register
1201   *         is set; the MSI oscillator is selected if STOPWUCK is cleared.
1202   * @note  Case of Stop2 mode and debugger probe attached: a workaround should be applied.
1203   *        Issue specified in "ES0394 - STM32WB55Cx/Rx/Vx device errata":
1204   *        2.2.9 Incomplete Stop 2 mode entry after a wakeup from debug upon EXTI line 48 event
1205   *        "With the JTAG debugger enabled on GPIO pins and after a wakeup from debug triggered by an event on EXTI
1206   *        line 48 (CDBGPWRUPREQ), the device may enter in a state in which attempts to enter Stop 2 mode are not fully
1207   *        effective ..."
1208   *        Workaround implementation example using LL driver:
1209   *        LL_EXTI_DisableIT_32_63(LL_EXTI_LINE_48);
1210   *        LL_C2_EXTI_DisableIT_32_63(LL_EXTI_LINE_48);
1211   * @note  According to system power policy, system entering in Stop mode
1212   *        is depending on other CPU power mode.
1213   * @param STOPEntry  specifies if Stop mode in entered with WFI or WFE instruction.
1214   *          This parameter can be one of the following values:
1215   *            @arg @ref PWR_STOPENTRY_WFI  Enter Stop mode with WFI instruction
1216   *            @arg @ref PWR_STOPENTRY_WFE  Enter Stop mode with WFE instruction
1217   * @retval None
1218   */
HAL_PWREx_EnterSTOP2Mode(uint8_t STOPEntry)1219 void HAL_PWREx_EnterSTOP2Mode(uint8_t STOPEntry)
1220 {
1221   /* Check the parameter */
1222   assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
1223 
1224   /* Set Stop mode 2 */
1225   MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_STOP2);
1226 
1227   /* Set SLEEPDEEP bit of Cortex System Control Register */
1228   SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1229 
1230   /* Select Stop mode entry --------------------------------------------------*/
1231   if(STOPEntry == PWR_STOPENTRY_WFI)
1232   {
1233     /* Request Wait For Interrupt */
1234     __WFI();
1235   }
1236   else
1237   {
1238     /* Request Wait For Event */
1239     __SEV();
1240     __WFE();
1241     __WFE();
1242   }
1243 
1244   /* Reset SLEEPDEEP bit of Cortex System Control Register */
1245   CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1246 }
1247 
1248 
1249 
1250 
1251 
1252 /**
1253   * @brief Enter Shutdown mode.
1254   * @note  In Shutdown mode, the PLL, the HSI, the MSI, the LSI and the HSE oscillators are switched
1255   *        off. The voltage regulator is disabled and Vcore domain is powered off.
1256   *        SRAM1, SRAM2, BKRAM and registers contents are lost except for registers in the Backup domain.
1257   *        The BOR is not available.
1258   * @note  The I/Os can be configured either with a pull-up or pull-down or can be kept in analog state.
1259   * @note  According to system power policy, system entering in Shutdown mode
1260   *        is depending on other CPU power mode.
1261   * @retval None
1262   */
HAL_PWREx_EnterSHUTDOWNMode(void)1263 void HAL_PWREx_EnterSHUTDOWNMode(void)
1264 {
1265   /* Set Shutdown mode */
1266   MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_SHUTDOWN);
1267 
1268   /* Set SLEEPDEEP bit of Cortex System Control Register */
1269   SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1270 
1271 /* This option is used to ensure that store operations are completed */
1272 #if defined ( __CC_ARM)
1273   __force_stores();
1274 #endif
1275 
1276   /* Request Wait For Interrupt */
1277   __WFI();
1278 
1279   /* Following code is executed after wake up if system didn't go to SHUTDOWN
1280    * or STANDBY mode according to power policy */
1281 
1282   /* Reset SLEEPDEEP bit of Cortex System Control Register */
1283   CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
1284 }
1285 
1286 
1287 /**
1288   * @brief This function handles the PWR PVD/PVMx interrupt request.
1289   * @note This API should be called under the PVD_PVM_IRQHandler().
1290   * @retval None
1291   */
HAL_PWREx_PVD_PVM_IRQHandler(void)1292 void HAL_PWREx_PVD_PVM_IRQHandler(void)
1293 {
1294   /* Check PWR exti flag */
1295   if(__HAL_PWR_PVD_EXTI_GET_FLAG() != 0U)
1296   {
1297     /* PWR PVD interrupt user callback */
1298     HAL_PWR_PVDCallback();
1299 
1300     /* Clear PVD exti pending bit */
1301     __HAL_PWR_PVD_EXTI_CLEAR_FLAG();
1302   }
1303 
1304 #if defined(PWR_CR2_PVME1)
1305   /* Next, successively check PVMx exti flags */
1306   if(__HAL_PWR_PVM1_EXTI_GET_FLAG() != 0U)
1307   {
1308     /* PWR PVM1 interrupt user callback */
1309     HAL_PWREx_PVM1Callback();
1310 
1311     /* Clear PVM1 exti pending bit */
1312     __HAL_PWR_PVM1_EXTI_CLEAR_FLAG();
1313   }
1314 #endif
1315 
1316   if(__HAL_PWR_PVM3_EXTI_GET_FLAG() != 0U)
1317   {
1318     /* PWR PVM3 interrupt user callback */
1319     HAL_PWREx_PVM3Callback();
1320 
1321     /* Clear PVM3 exti pending bit */
1322     __HAL_PWR_PVM3_EXTI_CLEAR_FLAG();
1323   }
1324 }
1325 
1326 #if defined(PWR_CR2_PVME1)
1327 /**
1328   * @brief PWR PVM1 interrupt callback
1329   * @retval None
1330   */
HAL_PWREx_PVM1Callback(void)1331 __weak void HAL_PWREx_PVM1Callback(void)
1332 {
1333   /* NOTE : This function should not be modified; when the callback is needed,
1334             HAL_PWREx_PVM1Callback() API can be implemented in the user file
1335    */
1336 }
1337 #endif
1338 
1339 /**
1340   * @brief PWR PVM3 interrupt callback
1341   * @retval None
1342   */
HAL_PWREx_PVM3Callback(void)1343 __weak void HAL_PWREx_PVM3Callback(void)
1344 {
1345   /* NOTE : This function should not be modified; when the callback is needed,
1346             HAL_PWREx_PVM3Callback() API can be implemented in the user file
1347    */
1348 }
1349 
1350 
1351 /**
1352   * @}
1353   */
1354 
1355 /**
1356   * @}
1357   */
1358 
1359 #endif /* HAL_PWR_MODULE_ENABLED */
1360 /**
1361   * @}
1362   */
1363 
1364 /**
1365   * @}
1366   */
1367 
1368 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1369