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