1 /**
2   ******************************************************************************
3   * @file    stm32u5xx_hal_pwr.c
4   * @author  MCD Application Team
5   * @brief   PWR HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Power Controller (PWR) peripheral:
8   *           + Initialization/De-Initialization Functions.
9   *           + Peripheral Control Functions.
10   *           + PWR Attributes Functions.
11   *
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2021 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23   @verbatim
24   ==============================================================================
25                         ##### PWR peripheral overview #####
26   ==============================================================================
27   [..]
28    (#) The Power control (PWR) provides an overview of the supply architecture
29        for the different power domains and of the supply configuration
30        controller.
31 
32    (#) Domain architecture overview for the U5 devices:
33       (+) U5 devices have 2 power domains (CD and SRD).
34           The core domain (CD) contains a CPU (Cortex-M33), a Flash memory and
35           some peripherals dedicated for general purpose. The SRD domain
36           contains the system control and low-power peripherals.
37 
38    (#) Every entity has low power mode as described below :
39    (#) The CPU low power modes are :
40       (+) CPU CRun.
41       (+) CPU CSleep.
42       (+) CPU CStop.
43    (#) The system low power modes are :
44       (+) Run.
45       (+) Stop 0.
46       (+) Stop 1.
47       (+) Stop 2.
48       (+) Stop 3.
49       (+) Standby.
50       (+) Shutdown.
51 
52   ==============================================================================
53                         ##### How to use this driver #####
54   ==============================================================================
55   [..]
56    (#) After startup, power management peripheral is not active by default. Use
57        __HAL_RCC_PWR_CLK_ENABLE() macro to enable power interface.
58 
59    (#) Call HAL_PWR_EnableBkUpAccess() and HAL_PWR_DisableBkUpAccess() functions
60        to enable/disable access to the backup domain (RCC Backup domain control
61        register RCC_BDCR, RTC registers, TAMP registers, backup registers and
62        backup SRAM).
63 
64    (#) Call HAL_PWR_ConfigPVD() after setting parameters to be configured (event
65        mode and voltage threshold) in order to set up the Programmed Voltage
66        Detector, then use HAL_PWR_EnablePVD() and  HAL_PWR_DisablePVD()
67        functions to start and stop the PVD detection.
68        (+) PVD level can be one of the following values :
69              (++) 2V0
70              (++) 2V2
71              (++) 2V4
72              (++) 2V5
73              (++) 2V6
74              (++) 2V8
75              (++) 2V9
76              (++) External input analog voltage PVD_IN (compared internally to
77                   VREFINT)
78 
79    (#) Call HAL_PWR_EnableWakeUpPin() and HAL_PWR_DisableWakeUpPin() functions
80        with the right parameter to configure the wake up pin polarity (Low or
81        High), the wake up pin selection and to enable and disable it.
82 
83    (#) Call HAL_PWR_EnterSLEEPMode() function to enter the CPU in Sleep mode.
84        Wake-up from Sleep mode could be following to an event or an
85        interrupt according to low power mode intrinsic request called (__WFI()
86        or __WFE()).
87 
88    (#) Call HAL_PWR_EnterSTOPMode() function to enter the whole system to Stop 0
89        mode. Wake-up from Stop 0 mode could be following to an event or an
90        interrupt according to low power mode intrinsic request called (__WFI()
91        or __WFE()). (Regulator state on U5 devices is managed internally but
92        regulator parameter is kept for product compatibility).
93 
94    (#) Call HAL_PWR_EnterSTANDBYMode() function to enter the whole system in
95        Standby mode. Wake-up from Standby mode can be following only by an
96        interrupt.
97 
98    (#) Call HAL_PWR_EnableSleepOnExit() and HAL_PWR_DisableSleepOnExit() APIs to
99        enable and disable the Cortex-M33 re-entry in Sleep mode after an
100        interruption handling is over.
101 
102    (#) Call HAL_PWR_EnableSEVOnPend() and HAL_PWR_DisableSEVOnPend() functions
103        to configure the Cortex-M33 to wake-up after any pending event / interrupt
104        even if it's disabled or has insufficient priority to cause exception
105        entry.
106 
107    (#) Call HAL_PWR_PVD_IRQHandler() under PVD_AVD_IRQHandler() function to
108        handle the PWR PVD interrupt request.
109 
110    (#) Call HAL_PWR_ConfigAttributes() function to configure PWR item secure and
111        privilege attributes and call HAL_PWR_GetConfigAttributes() function to
112        get the attribute configuration for the selected item.
113 
114      *** PWR HAL driver macros list ***
115      =============================================
116      [..]
117        Below the list of most used macros in PWR HAL driver.
118 
119       (+) __HAL_PWR_GET_FLAG()   : Get the PWR pending flags.
120       (+) __HAL_PWR_CLEAR_FLAG() : Clear the PWR pending flags.
121 
122   @endverbatim
123   ******************************************************************************
124   */
125 
126 /* Includes ------------------------------------------------------------------*/
127 #include "stm32u5xx_hal.h"
128 
129 /** @addtogroup STM32U5xx_HAL_Driver
130   * @{
131   */
132 
133 /** @defgroup PWR PWR
134   * @brief PWR HAL module driver
135   * @{
136   */
137 
138 #if defined (HAL_PWR_MODULE_ENABLED)
139 
140 /* Private typedef -----------------------------------------------------------*/
141 /* Private define ------------------------------------------------------------*/
142 
143 /** @defgroup PWR_Private_Defines PWR Private Defines
144   * @{
145   */
146 
147 /** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask
148   * @{
149   */
150 #define PVD_RISING_EDGE  (0x01U)  /*!< Mask for rising edge set as PVD trigger                 */
151 #define PVD_FALLING_EDGE (0x02U)  /*!< Mask for falling edge set as PVD trigger                */
152 #define PVD_MODE_IT      (0x04U)  /*!< Mask for interruption yielded by PVD threshold crossing */
153 #define PVD_MODE_EVT     (0x08U)  /*!< Mask for event yielded by PVD threshold crossing        */
154 /**
155   * @}
156   */
157 
158 /**
159   * @}
160   */
161 
162 /* Private macro -------------------------------------------------------------*/
163 /* Private variables ---------------------------------------------------------*/
164 /* Private function prototypes -----------------------------------------------*/
165 /* Exported functions --------------------------------------------------------*/
166 
167 /** @defgroup PWR_Exported_Functions PWR Exported Functions
168   * @{
169   */
170 
171 /** @defgroup PWR_Exported_Functions_Group1 Initialization and De-Initialization Functions
172   *  @brief   Initialization and de-Initialization functions
173   *
174 @verbatim
175  ===============================================================================
176               ##### Initialization and De-Initialization Functions #####
177  ===============================================================================
178     [..]
179       This section provides functions allowing to deinitialize power peripheral
180       and to manage backup domain access.
181 
182     [..]
183       After system reset, the backup domain (RCC Backup domain control register
184       RCC_BDCR, RTC registers, TAMP registers, backup registers and backup SRAM)
185       is protected against possible unwanted write accesses.
186       The HAL_PWR_EnableBkUpAccess() function enables the access to the backup
187       domain.
188       The HAL_PWR_DisableBkUpAccess() function disables the access to the backup
189       domain.
190 
191 @endverbatim
192   * @{
193   */
194 
195 /**
196   * @brief  Deinitialize the HAL PWR peripheral registers to their default reset
197   *         values.
198   * @note   This functionality is not available in this product.
199   *         The prototype is kept just to maintain compatibility with other
200   *         products.
201   * @retval None.
202   */
HAL_PWR_DeInit(void)203 void HAL_PWR_DeInit(void)
204 {
205 }
206 
207 /**
208   * @brief  Enable access to the backup domain (RCC Backup domain control
209   *         register RCC_BDCR, RTC registers, TAMP registers, backup registers
210   *         and backup SRAM).
211   * @note   After a system reset, the backup domain is protected against
212   *         possible unwanted write accesses.
213   * @retval None.
214   */
HAL_PWR_EnableBkUpAccess(void)215 void HAL_PWR_EnableBkUpAccess(void)
216 {
217   SET_BIT(PWR->DBPR, PWR_DBPR_DBP);
218 }
219 
220 /**
221   * @brief  Disable access to the backup domain (RCC Backup domain control
222   *         register RCC_BDCR, RTC registers, TAMP registers, backup registers
223   *         and backup SRAM).
224   * @retval None.
225   */
HAL_PWR_DisableBkUpAccess(void)226 void HAL_PWR_DisableBkUpAccess(void)
227 {
228   CLEAR_BIT(PWR->DBPR, PWR_DBPR_DBP);
229 }
230 /**
231   * @}
232   */
233 
234 
235 /** @defgroup PWR_Exported_Functions_Group2 Peripheral Control Functions
236   *  @brief   Low power modes configuration functions
237   *
238 @verbatim
239  ===============================================================================
240                  ##### Peripheral Control functions #####
241  ===============================================================================
242     [..]
243       This section provides functions allowing to control power peripheral.
244 
245     *** PVD configuration ***
246     =========================
247     [..]
248       (+) The PVD can be used to monitor the VDD power supply by comparing it
249           to a threshold selected by the PVDLS[2:0] bits in the PWR supply
250           voltage monitoring control register (PWR_SVMCR) and can be enabled by
251           setting the PVDE bit.
252 
253       (+) A PVDO flag is available in the PWR supply voltage monitoring control
254           register (PWR_SVMCR) to indicate if VDD is higher or lower than the
255           PVD threshold. This event is internally connected to the EXTI line 16
256           and can generate an interrupt if enabled through the EXTI registers.
257           It is configurable through __HAL_PWR_PVD_EXTI_ENABLE_IT() macro.
258 
259       (+) The PVD can remain active in Stop 0, Stop 1, Stop 2 modes, and the PVM
260           interrupt can wake up from the Stop mode. The PVD is not functional in
261           Stop 3 mode.
262 
263       (+) During Stop 1, Stop 2 and Stop 3 modes, it is possible to set the PVD
264           in ultra-low-power mode to further reduce the current consumption by
265           setting the ULPMEN bit in PWR_CR1 register.
266 
267     *** Wake-up pin configuration ***
268     =================================
269     [..]
270       (+) Wake-up pin is used to wake up the system from Stop 3, Standby and
271           Shutdown mode.
272           The pin selection is configurable through the WUCR3 register to map
273           internal signal to wake up pin line.
274           The pin polarity is configurable through the WUCR2 register to be
275           active on rising or falling edges.
276 
277       (+) There are up to 24 wake-up signals that can be mapped to up to 8
278           wake-up lines in the STM32U5 family.
279 
280     *** Low Power modes configuration ***
281     =====================================
282     [..]
283       This section presents 3 principles low-power modes :
284       (+) Sleep mode   : Cortex-M33 is stopped and all PWR domains are remaining
285                          active (powered and clocked).
286 
287       (+) Stop 0 mode  : Cortex-M33 is stopped, clocks are stopped and the
288                          regulator is running.
289 
290       (+) Standby mode : All PWR domains enter DSTANDBY mode and the VCORE
291                          supply regulator is powered off.
292 
293    *** Sleep mode ***
294    ==================
295     [..]
296       (+) Entry :
297           The Sleep mode is entered by using the HAL_PWR_EnterSLEEPMode()
298           function.
299 
300           (++) PWR_SLEEPENTRY_WFI             : Enter SLEEP mode with WFI instruction.
301           (++) PWR_SLEEPENTRY_WFE             : Enter SLEEP mode with WFE instruction and
302                                                 clear of pending events before.
303           (++) PWR_SLEEPENTRY_WFE_NO_EVT_CLEAR: Enter SLEEP mode with WFE instruction and
304                                                 no clear of pending event before.
305 
306       -@@- The Regulator parameter is not used for the STM32U5 family and is
307            kept as parameter just to maintain compatibility with other families.
308 
309       (+) Exit :
310           According to Sleep entry, any event when entry is __WFE() intrinsic
311           and any interrupt when entry is __WFI() intrinsic can wake up the
312           device from Sleep mode.
313 
314    *** Stop 0 mode ***
315    ===================
316     [..]
317       The Stop 0 mode is based on the Cortex-M33 Deepsleep mode combined with
318       the peripheral clock gating. The voltage regulator is configured in main
319       regulator mode. In Stop 0 mode, all clocks in the VCORE domain are stopped.
320       The PLL, MSIS, MSIK, HSI16 and HSE oscillators are disabled.
321       Some peripherals with the LPBAM capability can switch on HSI16 or MSIS or
322       MSIK for transferring data. All SRAMs and register contents are preserved,
323       but the SRAMs can be totally or partially switched off to further reduced
324       consumption.
325       The BOR is always available in Stop 0 mode.
326 
327       (+) Entry:
328           The Stop mode is entered using the HAL_PWR_EnterSTOPMode() function
329           with :
330 
331          (++) StopEntry:
332           (+++) PWR_STOPENTRY_WFI             : Enter STOP mode with WFI instruction.
333           (+++) PWR_STOPENTRY_WFE             : Enter STOP mode with WFE instruction and
334                                                 clear of pending events before.
335           (+++) PWR_STOPENTRY_WFE_NO_EVT_CLEAR: Enter STOP mode with WFE instruction and
336                                                 no clear of pending event before.
337 
338       -@@- The Regulator parameter is not used for the STM32U5 family and is
339            kept as parameter just to maintain compatibility with other families.
340 
341       (+) Exit:
342           Any EXTI line configured in interrupt mode (the corresponding EXTI
343           interrupt vector must be enabled in the NVIC). The interrupt source
344           can be external interrupts or peripherals with wakeup capability.
345           Any peripheral interrupt occurring when the AHB/APB clocks are present
346           due to an autonomous peripheral clock request (the peripheral vector
347           must be enabled in the NVIC).
348 
349    *** Standby mode ***
350    ====================
351     [..]
352       The Standby mode is used to achieve the lowest power consumption with BOR.
353       The internal regulator is switched off so that the VCORE domain is powered
354       off.
355       The PLL, the MSI (MSIS and MSIK) RC, the HSI16 RC and the HSE crystal
356       oscillators are also switched off.
357       The RTC can remain active (Standby mode with RTC, Standby mode without
358       RTC).
359       The Brownout reset (BOR) always remains active in Standby mode.
360       The state of each I/O during Standby mode can be selected by software:
361       I/O with internal pull-up, internal pull-down or floating.
362       After entering Standby mode, SRAMs and register contents are lost except
363       for registers and backup SRAM in the Backup domain and Standby circuitry.
364       Optionally, the full SRAM2 or 8 Kbytes or 56 Kbytes can be retained in
365       Standby mode, supplied by the low-power regulator (Standby with RAM2
366       retention mode).
367       The BORL (Brownout reset detector low) can be configured in ultra low
368       power mode to further reduce power consumption during Standby mode.
369       The device exits Standby mode upon an external reset (NRST pin), an IWDG
370       reset, WKUP pin event (configurable rising or falling edge), an RTC event
371       occurs (alarm, periodic wakeup, timestamp), or a tamper detection.
372       The system clock after wakeup is MSIS up to 4 MHz.
373 
374       (++) Entry:
375            The Standby mode is entered using the HAL_PWR_EnterSTANDBYMode()
376            function.
377 
378       (++) Exit:
379            WKUPx pin edge, RTC event, external Reset in NRST pin, IWDG Reset,
380            BOR reset.
381 
382 @endverbatim
383   * @{
384   */
385 
386 /**
387   * @brief  Configure the voltage threshold detected by the Programmed Voltage
388   *         Detector (PVD).
389   * @param  pConfigPVD : Pointer to a PWR_PVDTypeDef structure that contains the
390   *                      PVD configuration information (PVDLevel and EventMode).
391   * @retval HAL Status.
392   */
HAL_PWR_ConfigPVD(PWR_PVDTypeDef * pConfigPVD)393 HAL_StatusTypeDef HAL_PWR_ConfigPVD(PWR_PVDTypeDef *pConfigPVD)
394 {
395   /* Check the PVD parameter */
396   if (pConfigPVD == NULL)
397   {
398     return HAL_ERROR;
399   }
400 
401   /* Check the parameters */
402   assert_param(IS_PWR_PVD_LEVEL(pConfigPVD->PVDLevel));
403   assert_param(IS_PWR_PVD_MODE(pConfigPVD->Mode));
404 
405   /* Set PVDLS[2:0] bits according to PVDLevel value */
406   MODIFY_REG(PWR->SVMCR, PWR_SVMCR_PVDLS, pConfigPVD->PVDLevel);
407 
408   /* Disable PVD Event/Interrupt */
409   __HAL_PWR_PVD_EXTI_DISABLE_EVENT();
410   __HAL_PWR_PVD_EXTI_DISABLE_IT();
411   __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();
412   __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE();
413 
414   /* Configure the PVD in interrupt mode */
415   if ((pConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT)
416   {
417     __HAL_PWR_PVD_EXTI_ENABLE_IT();
418   }
419 
420   /* Configure the PVD in event mode */
421   if ((pConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT)
422   {
423     __HAL_PWR_PVD_EXTI_ENABLE_EVENT();
424   }
425 
426   /* Configure the PVD in rising edge */
427   if ((pConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE)
428   {
429     __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();
430   }
431 
432   /* Configure the PVD in falling edge */
433   if ((pConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE)
434   {
435     __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
436   }
437 
438   return HAL_OK;
439 }
440 
441 /**
442   * @brief  Enable the programmable voltage detector (PVD).
443   * @retval None.
444   */
HAL_PWR_EnablePVD(void)445 void HAL_PWR_EnablePVD(void)
446 {
447   SET_BIT(PWR->SVMCR, PWR_SVMCR_PVDE);
448 }
449 
450 /**
451   * @brief  Disable the programmable voltage detector (PVD).
452   * @retval None.
453   */
HAL_PWR_DisablePVD(void)454 void HAL_PWR_DisablePVD(void)
455 {
456   CLEAR_BIT(PWR->SVMCR, PWR_SVMCR_PVDE);
457 }
458 
459 /**
460   * @brief  Enable the wake up line functionality.
461   * @note   Wake up lines are used to wake up the system from Stop 3, Standby and
462   *         Shutdown modes.
463   * @param  WakeUpPin : Specifies which wake up line to enable. This parameter
464   *                     can be one of PWR_WakeUp_Pins_High_Polarity define
465   *                     group where every param select the wake up line, the
466   *                     wake up source with high polarity detection and the wake
467   *                     up selected I/O or can be one of
468   *                     PWR_WakeUp_Pins_Low_Polarity define group where every
469   *                     param select the wake up line, the wake up source with
470   *                     low polarity and the wake up selected I/O or can be one
471   *                     of PWR_WakeUp_Pins define group where every param select
472   *                     the wake up line, the wake up source with
473   *                     high polarity and the first wake up I/O.
474   * @retval None.
475   */
HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPin)476 void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPin)
477 {
478   /* Check the parameter */
479   assert_param(IS_PWR_WAKEUP_PIN(WakeUpPin));
480 
481   /* Specifies the wake up line polarity for the event detection (rising or falling edge) */
482   MODIFY_REG(PWR->WUCR2, (PWR_EWUP_MASK & WakeUpPin), (WakeUpPin >> PWR_WUP_POLARITY_SHIFT));
483 
484   /* Specifies the wake up line I/O selection */
485   MODIFY_REG(PWR->WUCR3, (3UL << (POSITION_VAL(PWR_EWUP_MASK & WakeUpPin) * 2U)),
486              (WakeUpPin >> PWR_WUP_SELECT_SIGNAL_SHIFT));
487 
488   /* Enable wake-up line */
489   SET_BIT(PWR->WUCR1, (PWR_EWUP_MASK & WakeUpPin));
490 }
491 
492 /**
493   * @brief  Disable the wake up line functionality.
494   * @param  WakeUpPin : Specifies the wake up line to disable.
495   *                     This parameter can be a combination of all the following
496   *                     values :
497   *                     @arg @ref PWR_WAKEUP_PIN1
498   *                     @arg @ref PWR_WAKEUP_PIN2
499   *                     @arg @ref PWR_WAKEUP_PIN3
500   *                     @arg @ref PWR_WAKEUP_PIN4
501   *                     @arg @ref PWR_WAKEUP_PIN6
502   *                     @arg @ref PWR_WAKEUP_PIN5
503   *                     @arg @ref PWR_WAKEUP_PIN7
504   *                     @arg @ref PWR_WAKEUP_PIN8
505   * @retval None
506   */
HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPin)507 void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPin)
508 {
509   /* Check the parameters */
510   assert_param(IS_PWR_WAKEUP_PIN(WakeUpPin));
511 
512   /* Disable wake-up pin */
513   CLEAR_BIT(PWR->WUCR1, (PWR_EWUP_MASK & WakeUpPin));
514 }
515 
516 /**
517   * @brief  Enter the CPU in Sleep mode.
518   * @note   In Sleep mode, all I/O pins keep the same state as in Run mode.
519   * @note   CPU clock is off and all peripherals including Cortex-M33 core such
520   *         as NVIC and SysTick can run and wake up the CPU when an interrupt
521   *         or an event occurs.
522   * @param  Regulator : Specifies the regulator state in Sleep mode.
523   *                     This parameter can be one of the following values :
524   *                     @arg @ref PWR_MAINREGULATOR_ON
525   *                     @arg @ref PWR_LOWPOWERREGULATOR_ON
526   * @note   This parameter is not available in this product.
527   *         The parameter is kept just to maintain compatibility with other
528   *         products.
529   * @param  SleepEntry : Specifies if Sleep mode is entered with WFI or WFE
530   *                      instruction.
531   *            @arg PWR_SLEEPENTRY_WFI              : Enter SLEEP mode with WFI instruction.
532   *            @arg PWR_SLEEPENTRY_WFE              : Enter SLEEP mode with WFE instruction and
533   *                                                   clear of pending events before.
534   *            @arg PWR_SLEEPENTRY_WFE_NO_EVT_CLEAR : Enter SLEEP mode with WFE instruction and
535   *                                                   no clear of pending event before.
536   * @retval None.
537   */
HAL_PWR_EnterSLEEPMode(uint32_t Regulator,uint8_t SleepEntry)538 void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SleepEntry)
539 {
540   UNUSED(Regulator);
541 
542   /* Check the parameter */
543   assert_param(IS_PWR_SLEEP_ENTRY(SleepEntry));
544 
545   /* Clear SLEEPDEEP bit of Cortex System Control Register */
546   CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
547 
548   /* Select Sleep mode entry */
549   if (SleepEntry == PWR_SLEEPENTRY_WFI)
550   {
551     /* Wait For Interrupt Request */
552     __WFI();
553   }
554   else
555   {
556     if (SleepEntry != PWR_SLEEPENTRY_WFE_NO_EVT_CLEAR)
557     {
558       /* Clear all pending event */
559       __SEV();
560       __WFE();
561     }
562 
563     /* Request Wait For Event */
564     __WFE();
565   }
566 }
567 
568 /**
569   * @brief  Enter the whole system to Stop 0 mode.
570   * @note   In Stop 0 mode, the regulator remains in main regulator mode,
571   *         allowing a very fast wakeup time but with much higher consumption
572   *         comparing to other Stop modes.
573   * @note   Stop 0 offers the largest number of active peripherals and wakeup
574   *         sources, a smaller wakeup time but a higher consumption.
575   *         Stop mode achieves the lowest power consumption while retaining
576   *         the content of SRAM and registers. All clocks in the VCORE domain
577   *         are stopped. The PLL, the MSI (MSIS and MSIK) RC, the HSI16 RC and
578   *         the HSE crystal oscillators are disabled. The LSE or LSI is still
579   *         running.
580   * @note   The system clock when exiting from Stop mode can be either MSIS up
581   *         to 24 MHz or HSI16, depending on software configuration.
582   * @param  Regulator : Specifies the regulator state in Stop mode.
583   *                     This parameter can be one of the following values :
584   *                     @arg @ref PWR_MAINREGULATOR_ON
585   *                     @arg @ref PWR_LOWPOWERREGULATOR_ON
586   * @note   This parameter is not available in this product.
587   *         The parameter is kept just to maintain compatibility with other
588   *         products.
589   * @param  StopEntry : Specifies if Stop mode is entered with WFI or WFE
590   *                     instruction.
591   *                     This parameter can be one of the following values :
592   *            @arg PWR_STOPENTRY_WFI              : Enter STOP mode with WFI instruction.
593   *            @arg PWR_STOPENTRY_WFE              : Enter STOP mode with WFE instruction and
594   *                                                  clear of pending events before.
595   *            @arg PWR_STOPENTRY_WFE_NO_EVT_CLEAR : Enter STOP mode with WFE instruction and
596   *                                                  no clear of pending event before.
597   * @note   In System STOP mode, all I/O pins keep the same state as in Run mode.
598   * @retval None.
599   */
HAL_PWR_EnterSTOPMode(uint32_t Regulator,uint8_t StopEntry)600 void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t StopEntry)
601 {
602   UNUSED(Regulator);
603 
604   /* Check the parameter */
605   assert_param(IS_PWR_STOP_ENTRY(StopEntry));
606 
607   /* Select Stop 0 mode */
608   MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, 0U);
609 
610   /* Set SLEEPDEEP bit of Cortex System Control Register */
611   SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
612 
613   /* Select Stop mode entry */
614   if (StopEntry == PWR_STOPENTRY_WFI)
615   {
616     /* Wait For Interrupt Request */
617     __WFI();
618   }
619   else
620   {
621     if (StopEntry != PWR_STOPENTRY_WFE_NO_EVT_CLEAR)
622     {
623       /* Clear all pending event */
624       __SEV();
625       __WFE();
626     }
627 
628     /* Request Wait For Event */
629     __WFE();
630   }
631 
632   /* Reset SLEEPDEEP bit of Cortex System Control Register */
633   CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
634 }
635 
636 /**
637   * @brief  Enter the whole system to Standby mode.
638   * @note   The Standby mode is used to achieve the lowest power consumption
639   *         with BOR. The internal regulator is switched off so that the VCORE
640   *         domain is powered off. The PLL, the MSI (MSIS and MSIK) RC, the
641   *         HSI16 RC and the HSE crystal oscillators are also switched off.
642   * @note   After entering Standby mode, SRAMs and register contents are lost
643   *         except for registers and backup SRAM in the Backup domain and
644   *         Standby circuitry. Optionally, the full SRAM2 or 8 Kbytes or 56
645   *         Kbytes can be retained in Standby mode, supplied by the low-power
646   *         regulator (Standby with RAM2 retention mode) through
647   *         HAL_PWREx_EnableSRAM2ContentStandbyRetention().
648   * @note   The state of each I/O during Standby mode can be selected by
649   *         software : I/O with internal pull-up through
650   *         HAL_PWREx_EnableGPIOPullUp() and internal pull-down through
651   *         HAL_PWREx_EnableGPIOPullDown().
652   * @retval None.
653   */
HAL_PWR_EnterSTANDBYMode(void)654 void HAL_PWR_EnterSTANDBYMode(void)
655 {
656   /* Select Standby mode */
657   MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_2);
658 
659   /* Set SLEEPDEEP bit of Cortex System Control Register */
660   SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
661 
662   /* Wait For Interrupt Request */
663   __WFI();
664 }
665 
666 /**
667   * @brief  Indicate SLEEP-ON-EXIT feature when returning from handler mode to
668   *         thread mode.
669   * @note   Set SLEEPONEXIT bit of SCR register. When this bit is set, the
670   *         processor re-enters Sleep mode when an interruption handling is over.
671   *         Setting this bit is useful when the processor is expected to run
672   *         only on interruptions handling.
673   * @retval None.
674   */
HAL_PWR_EnableSleepOnExit(void)675 void HAL_PWR_EnableSleepOnExit(void)
676 {
677   /* Set SLEEPONEXIT bit of Cortex-M33 System Control Register */
678   SET_BIT(SCB->SCR, SCB_SCR_SLEEPONEXIT_Msk);
679 }
680 
681 /**
682   * @brief  Disable SLEEP-ON-EXIT feature when returning from handler mode to
683   *         thread mode.
684   * @note   Clears SLEEPONEXIT bit of SCR register. When this bit is set, the
685   *         processor re-enters Sleep mode when an interruption handling is over.
686   * @retval None.
687   */
HAL_PWR_DisableSleepOnExit(void)688 void HAL_PWR_DisableSleepOnExit(void)
689 {
690   /* Clear SLEEPONEXIT bit of Cortex-M33 System Control Register */
691   CLEAR_BIT(SCB->SCR, SCB_SCR_SLEEPONEXIT_Msk);
692 }
693 
694 /**
695   * @brief  Enable CORTEX SEV-ON-PEND feature.
696   * @note   Sets SEVONPEND bit of SCR register. When this bit is set, any
697   *         pending event / interrupt even if it's disabled or has insufficient
698   *         priority to cause exception entry wakes up the Cortex-M33.
699   * @retval None.
700   */
HAL_PWR_EnableSEVOnPend(void)701 void HAL_PWR_EnableSEVOnPend(void)
702 {
703   /* Set SEVONPEND bit of Cortex-M33 System Control Register */
704   SET_BIT(SCB->SCR, SCB_SCR_SEVONPEND_Msk);
705 }
706 
707 /**
708   * @brief  Disable CORTEX SEVONPEND feature.
709   * @note   Resets SEVONPEND bit of SCR register. When this bit is reset, only enabled
710   *         pending event / interrupt to cause exception entry wakes up the Cortex-M33.
711   * @retval None.
712   */
HAL_PWR_DisableSEVOnPend(void)713 void HAL_PWR_DisableSEVOnPend(void)
714 {
715   /* Clear SEVONPEND bit of Cortex-M33 System Control Register */
716   CLEAR_BIT(SCB->SCR, SCB_SCR_SEVONPEND_Msk);
717 }
718 
719 /**
720   * @brief  This function handles the PWR PVD interrupt request.
721   * @note   This API should be called under the PVD_AVD_IRQHandler().
722   * @retval None.
723   */
HAL_PWR_PVD_IRQHandler(void)724 void HAL_PWR_PVD_IRQHandler(void)
725 {
726   uint32_t  rising_flag;
727   uint32_t  falling_flag;
728 
729   /* Get pending flags */
730   rising_flag  = READ_REG(EXTI->RPR1);
731   falling_flag = READ_REG(EXTI->FPR1);
732 
733   /* Check PWR EXTI flags for PVD */
734   if (((rising_flag | falling_flag) & PWR_EXTI_LINE_PVD) != 0U)
735   {
736     /* PWR PVD interrupt user callback */
737     HAL_PWR_PVDCallback();
738 
739     /* Clear PVD EXTI pending bit */
740     WRITE_REG(EXTI->RPR1, PWR_EXTI_LINE_PVD);
741     WRITE_REG(EXTI->FPR1, PWR_EXTI_LINE_PVD);
742   }
743 }
744 
745 /**
746   * @brief  PWR PVD interrupt callback.
747   * @retval None.
748   */
HAL_PWR_PVDCallback(void)749 __weak void HAL_PWR_PVDCallback(void)
750 {
751   /* NOTE : This function should not be modified, when the callback is needed,
752             the HAL_PWR_PVDCallback can be implemented in the user file
753   */
754 }
755 /**
756   * @}
757   */
758 
759 /** @defgroup PWR_Exported_Functions_Group3 Attributes Management Functions
760   *  @brief    Attributes management functions
761   *
762 @verbatim
763  ===============================================================================
764                        ##### PWR Attributes Functions #####
765  ===============================================================================
766     [..]
767       When the TrustZone security is activated by the TZEN option bit in the
768       FLASH_OPTR register, some PWR register fields can be secured against
769       non-secure access.
770       The PWR TrustZone security allows the following features to be secured
771       through the PWR_SECCFGR register :
772 
773       (++) Low-power mode.
774       (++) Wake-up (WKUP) pins.
775       (++) Voltage detection and monitoring.
776       (++) VBAT mode.
777       (++) I/Os pull-up/pull-down configuration.
778 
779       Other PWR configuration bits are secure when :
780       (++) The system clock selection is secure in RCC: the voltage scaling
781            (VOS) configuration and the regulator booster (BOOSTEN) are secure.
782       (++) A GPIO is configured as secure: its corresponding bit for pull-up /
783            pull-down configuration in Standby mode is secure.
784       (++) The UCPD1 is secure in the GTZC: the PWR_UCPDR register is secure.
785 
786       A non-secure access to a secure-protected register bit is denied :
787       (++) The secured bits are not written (WI) with a non-secure write access.
788       (++) The secured bits are read as 0 (RAZ) with a non-secure read access.
789 
790     [..]
791       When the TrustZone security is disabled (TZEN = 0), PWR_SECCFGR is RAZ/WI
792       and all other registers are non-secure.
793 
794     [..]
795       By default, after a reset, all PWR registers can be read or written with
796       both privileged and unprivileged accesses, except PWR_PRIVCFGR that can be
797       written with privileged access only. PWR_PRIVCFGR can be read by secure
798       and non secure, privileged and unprivileged accesses.
799       The SPRIV bit in PWR_PRIVCFGR can be written with secure privileged access
800       only. This bit configures the privileged access of all PWR secure
801       functions (defined by PWR_SECCFGR, GTZC, RCC or GPIO).
802       When the SPRIV bit is set in PWR_PRIVCFGR:
803       (++) The PWR secure bits can be written only with privileged access,
804       including PWR_SECCFGR.
805       (++) The PWR secure bits can be read only with privileged access except
806            PWR_SECCFGR and PWR_PRIVCFGR that can be read by privileged or
807            unprivileged access.
808       (++) An unprivileged access to a privileged PWR bit or register is
809            discarded : the bits are read as zero and the write to these bits is
810            ignored (RAZ/WI).
811       The NSPRIV bit of PWR_PRIVCFGR can be written with privileged access only,
812       secure or non-secure. This bit configures the privileged access of all PWR
813       securable functions that are configured as non-secure (defined by
814       PWR_SECCFGR, GTZC, RCC or GPIO).
815       When the NSPRIV bit is set in PWR_PRIVCFGR :
816       (++) The PWR securable bits that are configured as non-secure, can be
817            written only with privileged access.
818       (++) The PWR securable bits that are configured as non-secure, can be read
819            only with privileged access except PWR_PRIVCFGR that can be read by
820            privileged or unprivileged accesses.
821       (++) The VOSRDY and BOOSTRDY bits in PWR_VOSR, PWR_SR, PWR_SVMSR, PWR_BDSR
822            and PWR_WUSR, can be read with privileged or unprivileged accesses.
823       (++) An unprivileged access to a privileged PWR bit or register is
824            discarded : the bits are read as zero and the write to these bits is
825            ignored (RAZ/WI).
826 
827 @endverbatim
828   * @{
829   */
830 
831 /**
832   * @brief  Configure the PWR item attributes.
833   * @note   Available attributes are security and privilege protection.
834   * @note   Security attribute can only be set only by secure access.
835   * @note   Privilege attribute for secure items can be managed only by a secure
836   *         privileged access.
837   * @note   Privilege attribute for nsecure items can be managed  by a secure
838   *         privileged access or by a nsecure privileged access.
839   * @param  Item       : Specifies the item(s) to set attributes on.
840   *                      This parameter can be a combination of @ref PWR_Items.
841   * @param  Attributes : Specifies the available attribute(s).
842   *                      This parameter can be one of @ref PWR_Attributes.
843   * @retval None.
844   */
HAL_PWR_ConfigAttributes(uint32_t Item,uint32_t Attributes)845 void HAL_PWR_ConfigAttributes(uint32_t Item, uint32_t Attributes)
846 {
847   /* Check the parameters */
848   assert_param(IS_PWR_ITEMS_ATTRIBUTES(Item));
849   assert_param(IS_PWR_ATTRIBUTES(Attributes));
850 
851 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
852   /* Secure item management (TZEN = 1) */
853   if ((Attributes & PWR_ITEM_ATTR_SEC_PRIV_MASK) == PWR_ITEM_ATTR_SEC_PRIV_MASK)
854   {
855     /* Privilege item management */
856     if ((Attributes & PWR_SEC_PRIV) == PWR_SEC_PRIV)
857     {
858       SET_BIT(PWR->SECCFGR, Item);
859       SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_SPRIV);
860     }
861     else
862     {
863       SET_BIT(PWR->SECCFGR, Item);
864       CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_SPRIV);
865     }
866   }
867   /* NSecure item management */
868   else
869   {
870     /* Privilege item management */
871     if ((Attributes & PWR_NSEC_PRIV) == PWR_NSEC_PRIV)
872     {
873       CLEAR_BIT(PWR->SECCFGR, Item);
874       SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV);
875     }
876     else
877     {
878       CLEAR_BIT(PWR->SECCFGR, Item);
879       CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV);
880     }
881   }
882 #else
883   /* Prevent unused argument(s) compilation warning */
884   UNUSED(Item);
885 
886   /* NSecure item management (TZEN = 0) */
887   if ((Attributes & PWR_ITEM_ATTR_NSEC_PRIV_MASK) == PWR_ITEM_ATTR_NSEC_PRIV_MASK)
888   {
889     /* Privilege item management */
890     if ((Attributes & PWR_NSEC_PRIV) == PWR_NSEC_PRIV)
891     {
892       SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV);
893     }
894     else
895     {
896       CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV);
897     }
898   }
899 #endif /* __ARM_FEATURE_CMSE */
900 }
901 
902 /**
903   * @brief  Get attribute(s) of a PWR item.
904   * @param  Item        : Specifies the item(s) to get attributes of.
905   *                       This parameter can be one of @ref PWR_Items.
906   * @param  pAttributes : Pointer to return attribute(s).
907   *                       Returned value could be one of @ref PWR_Attributes.
908   * @retval HAL Status.
909   */
HAL_PWR_GetConfigAttributes(uint32_t Item,uint32_t * pAttributes)910 HAL_StatusTypeDef HAL_PWR_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes)
911 {
912   uint32_t attributes;
913 
914   /* Check attribute pointer */
915   if (pAttributes == NULL)
916   {
917     return HAL_ERROR;
918   }
919 
920   /* Check the parameter */
921   assert_param(IS_PWR_ITEMS_ATTRIBUTES(Item));
922 
923 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
924   /* Check item security */
925   if ((PWR->SECCFGR & Item) == Item)
926   {
927     /* Get Secure privileges attribute */
928     attributes = ((PWR->PRIVCFGR & PWR_PRIVCFGR_SPRIV) == 0U) ? PWR_SEC_NPRIV : PWR_SEC_PRIV;
929   }
930   else
931   {
932     /* Get Non-Secure privileges attribute */
933     attributes = ((PWR->PRIVCFGR & PWR_PRIVCFGR_NSPRIV) == 0U) ? PWR_NSEC_NPRIV : PWR_NSEC_PRIV;
934   }
935 #else
936   /* Get Non-Secure privileges attribute */
937   attributes = ((PWR->PRIVCFGR & PWR_PRIVCFGR_NSPRIV) == 0U) ? PWR_NSEC_NPRIV : PWR_NSEC_PRIV;
938 #endif /* __ARM_FEATURE_CMSE */
939 
940   /* return value */
941   *pAttributes = attributes;
942 
943   return HAL_OK;
944 }
945 /**
946   * @}
947   */
948 
949 /**
950   * @}
951   */
952 
953 #endif /* defined (HAL_PWR_MODULE_ENABLED) */
954 /**
955   * @}
956   */
957 
958 /**
959   * @}
960   */
961