1 /**
2   ******************************************************************************
3   * @file    stm32n6xx_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) 2023 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    (#) Several low-power modes are available to save power when the CPU does not need to
33        execute code :
34       (+) Sleep   (CPU clock stopped and still in RUN mode)
35       (+) Stop    (System clock stopped)
36       (+) Standby (System powered down)
37 
38   ==============================================================================
39                         ##### How to use this driver #####
40   ==============================================================================
41   [..]
42 
43    (#) Call HAL_PWR_EnableBkUpAccess() and HAL_PWR_DisableBkUpAccess() functions
44        to enable/disable access to the backup domain (RCC Backup domain control
45        register RCC_BDCR, RTC registers, TAMP registers, backup registers and
46        backup SRAM).
47 
48    (#) Call HAL_PWR_ConfigPVD() after setting parameters to be configured (event
49        mode and voltage threshold) in order to set up the Programmed Voltage
50        Detector, then use HAL_PWR_EnablePVD() and HAL_PWR_DisablePVD()
51        functions to start and stop the PVD detection.
52    (+) PVD level on PVD_IN is compared to the internal VREFINT level.
53        PVDO flag is available in PWR_CR2 to indicate if the voltage level
54        on PVD_IN is higher or lower than the PVD threshold.
55 
56    (#) Call HAL_PWR_EnableWakeUpPin() and HAL_PWR_DisableWakeUpPin() functions
57        with the right parameter to configure the wake up pin polarity (Low or
58        High), the wake up pin selection and to enable and disable it.
59 
60    (#) Call HAL_PWREx_GetWakeupFlag() and HAL_PWREx_ClearWakeupFlag()
61        functions to manage wake-up flag for the selected pin.
62 
63    (#) Call HAL_PWR_EnterSLEEPMode() function to enter the CPU in Sleep mode.
64        Wake-up from Sleep mode could be following to an event or an
65        interrupt according to low power mode intrinsic request called (__WFI()
66        or __WFE()).
67 
68    (#) Call HAL_PWR_EnterSTOPMode() function to enter the whole system to Stop
69        mode. Wake-up from Stop mode could be following to an event or an
70        interrupt according to low power mode intrinsic request called (__WFI()
71        or __WFE()). (Regulator state on STM32N6 devices is managed internally but
72        regulator parameter is kept for product compatibility).
73 
74    (#) Call HAL_PWR_EnterSTANDBYMode() function to enter the whole system in
75        Standby mode. Wake-up from Standby mode can be following only by an
76        interrupt.
77 
78    (#) Call HAL_PWR_EnableSleepOnExit() and HAL_PWR_DisableSleepOnExit() APIs to
79        enable and disable the Cortex-M55 re-entry in Sleep mode after an
80        interruption handling is over.
81 
82    (#) Call HAL_PWR_EnableSEVOnPend() and HAL_PWR_DisableSEVOnPend() functions
83        to configure the Cortex-M55 to wake-up after any pending event / interrupt
84        even if it's disabled or has insufficient priority to cause exception
85        entry.
86 
87    (#) Call HAL_PWR_WAKEUP_PIN_IRQHandler() function to handle all wake-up
88        pins interrupts.
89 
90    (#) Call HAL_PWR_ConfigAttributes() function to configure PWR item secure and
91        privilege attributes and call HAL_PWR_GetConfigAttributes() function to
92        get the attribute configuration for the selected item.
93 
94      *** PWR HAL driver macros list ***
95      =============================================
96      [..]
97        Below the list of most used macros in PWR HAL driver.
98 
99       (+) __HAL_PWR_GET_FLAG()   : Get the PWR pending flags.
100       (+) __HAL_PWR_CLEAR_FLAG() : Clear the PWR pending flags.
101 
102   @endverbatim
103   ******************************************************************************
104   */
105 
106 /* Includes ------------------------------------------------------------------*/
107 #include "stm32n6xx_hal.h"
108 
109 /** @addtogroup STM32N6xx_HAL_Driver
110   * @{
111   */
112 
113 /** @defgroup PWR PWR
114   * @brief PWR HAL module driver
115   * @{
116   */
117 
118 #if defined (HAL_PWR_MODULE_ENABLED)
119 
120 /* Private typedef -----------------------------------------------------------*/
121 /* Private define ------------------------------------------------------------*/
122 
123 /** @defgroup PWR_Private_Defines PWR Private Defines
124   * @{
125   */
126 
127 /** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask
128   * @{
129   */
130 #define PVD_MODE_IT                    (0x00010000U)                           /*!< Mask for interruption yielded by PVD threshold crossing */
131 #define PVD_MODE_EVT                   (0x00020000U)                           /*!< Mask for event yielded by PVD threshold crossing        */
132 #define PVD_RISING_EDGE                (0x00000001U)                           /*!< Mask for rising edge set as PVD trigger                 */
133 #define PVD_FALLING_EDGE               (0x00000002U)                           /*!< Mask for falling edge set as PVD trigger                */
134 #define PVD_RISING_FALLING_EDGE        (0x00000003U)                           /*!< Mask for rising & falling edge set as PVD trigger       */
135 /**
136   * @}
137   */
138 
139 /**
140   * @}
141   */
142 
143 /* Private macro -------------------------------------------------------------*/
144 /* Private variables ---------------------------------------------------------*/
145 /* Private function prototypes -----------------------------------------------*/
146 /* Exported functions --------------------------------------------------------*/
147 
148 /** @defgroup PWR_Exported_Functions PWR Exported Functions
149   * @{
150   */
151 
152 /** @defgroup PWR_Exported_Functions_Group1 Initialization and De-Initialization Functions
153   *  @brief   Initialization and de-Initialization functions
154   *
155 @verbatim
156  ===============================================================================
157               ##### Initialization and De-Initialization Functions #####
158  ===============================================================================
159     [..]
160       This section provides functions allowing to deinitialize power peripheral.
161 
162     [..]
163       After system reset, the backup domain (RCC Backup domain control register
164       RCC_BDCR, RTC registers, TAMP registers, backup registers and backup SRAM)
165       is protected against possible unwanted write accesses.
166       The HAL_PWR_EnableBkUpAccess() function enables the access to the backup
167       domain.
168       The HAL_PWR_DisableBkUpAccess() function disables the access to the backup
169       domain.
170 
171 @endverbatim
172   * @{
173   */
174 
175 /**
176   * @brief  Deinitialize the HAL PWR peripheral registers to their default reset
177   *         values.
178   * @note   This functionality is not available in this product.
179   *         The prototype is kept just to maintain compatibility with other
180   *         products.
181   * @retval None.
182   */
HAL_PWR_DeInit(void)183 void HAL_PWR_DeInit(void)
184 {
185 }
186 
187 /**
188   * @brief  Enable access to the backup domain (RCC Backup domain control
189   *         register RCC_BDCR, RTC registers, TAMP registers, backup registers
190   *         and backup SRAM).
191   * @note   After a system reset, the backup domain is protected against
192   *         possible unwanted write accesses.
193   * @retval None.
194   */
HAL_PWR_EnableBkUpAccess(void)195 void HAL_PWR_EnableBkUpAccess(void)
196 {
197   WRITE_REG(PWR->DBPCR, PWR_DBPCR_DBP);
198 }
199 
200 /**
201   * @brief  Disable access to the backup domain (RCC Backup domain control
202   *         register RCC_BDCR, RTC registers, TAMP registers, backup registers
203   *         and backup SRAM).
204   * @retval None.
205   */
HAL_PWR_DisableBkUpAccess(void)206 void HAL_PWR_DisableBkUpAccess(void)
207 {
208   CLEAR_REG(PWR->DBPCR);
209 }
210 /**
211   * @}
212   */
213 
214 
215 /** @defgroup PWR_Exported_Functions_Group2 Peripheral Control Functions
216   *  @brief   Power Control functions
217   *
218 @verbatim
219  ===============================================================================
220                  ##### Peripheral Control Functions #####
221  ===============================================================================
222     [..]
223       This section provides functions allowing to control power peripheral.
224 
225     *** PVD configuration ***
226     =========================
227     [..]
228       (+) The PVD is used to monitor the VDD power supply by comparing it
229           to the internal VREFINT.
230 
231       (+) A PVDO flag is available to indicate if VDD is higher or lower
232           than the PVD threshold. This event is internally connected to the EXTI
233           line 66 to generate an interrupt if enabled.
234           It is configurable through __HAL_PWR_PVD_EXTI_ENABLE_IT() macro.
235 
236       (+) The PVD is stopped in STANDBY mode.
237 
238     *** Wake-up pin configuration ***
239     =================================
240     [..]
241       (+) Wake-up pin is used to wake up the system from STANDBY mode.
242           The pin pull is configurable through the WKUPEPR register to be in
243           No-pull, Pull-up and Pull-down.
244           The pin polarity is configurable through the WKUPEPR register to be
245           active on rising or falling edges.
246 
247       (+) There are up to four Wake-up pin in the STM32N6 devices family.
248 
249     *** Low Power modes configuration ***
250     =====================================
251     [..]
252      The device present 3 principles low-power modes :
253       (+) SLEEP mode   : Cortex-M55 is stopped and all PWR domains are remaining
254                          active (Powered and Clocked).
255 
256       (+) STOP mode    : Cortex-M55 is stopped, clocks are stopped and the
257                          regulator is running. The Main regulator or the LP
258                          regulator could be selected.
259 
260       (+) STANDBY mode : All PWR domains enter DSTANDBY mode and the VCORE
261                          supply regulator is powered off.
262 
263    *** SLEEP mode ***
264    ==================
265     [..]
266       (+) Entry:
267         The SLEEP mode is entered by using the HAL_PWR_EnterSLEEPMode(Regulator,
268         SLEEPEntry) function.
269 
270           (++) PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction.
271           (++) PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction.
272           (++) PWR_SLEEPENTRY_WFE_NO_EVT_CLEAR: enter SLEEP mode with WFE instruction
273                                                 and no clear of pending event.
274 
275       -@@- The Regulator parameter is not used for the STM32N6 family
276               and is kept as parameter just to maintain compatibility with the
277               lower power families.
278 
279       (+) Exit:
280         Any peripheral interrupt acknowledged by the nested vectored interrupt
281         controller (NVIC) can wake up the device from SLEEP mode.
282 
283    *** STOP mode ***
284    =================
285     [..]
286       In system STOP mode, the CPU clock is stopped. All CPU subsystem peripheral
287       clocks are stopped too.
288       The voltage regulator can be configured either in normal or low-power mode.
289       To minimize the consumption in STOP mode, FLASH can be powered off before
290       entering the STOP mode using the HAL_PWREx_EnableFlashPowerDown() function.
291       It can be switched on again by software after exiting the STOP mode using
292       the HAL_PWREx_DisableFlashPowerDown() function.
293       (+) Entry:
294          The STOP mode is entered using the HAL_PWR_EnterSTOPMode(Regulator,
295          STOPEntry) function with:
296          (++) Regulator:
297           (+++) PWR_MAINREGULATOR_ON: Main regulator ON.
298                 This parameter is not used for the STM32N6 family and is kept as parameter
299                 just to maintain compatibility with the lower power families.
300          (++) STOPEntry:
301           (+++) PWR_STOPENTRY_WFI: enter STOP mode with WFI instruction.
302           (+++) PWR_STOPENTRY_WFE: enter STOP mode with WFE instruction.
303           (+++) PWR_STOPENTRY_WFE_NO_EVT_CLEAR: enter STOP mode with WFE instruction
304                                                 and no clear of pending event.
305 
306       (+) Exit:
307          Any EXTI Line (Internal or External) configured in Interrupt/Event mode.
308 
309    *** STANDBY mode ***
310    ====================
311     [..]
312     (+)
313       The system STANDBY mode allows to achieve the lowest power consumption.
314       It is based on the Cortex-M55 deep SLEEP mode, with the voltage regulator
315       disabled. The system is consequently powered off. The PLL, the HSI
316       oscillator and the HSE oscillator are also switched off. SRAM and register
317       contents are lost except for the RTC registers, RTC backup registers,
318       backup SRAM and standby circuitry.
319 
320     [..]
321       The voltage regulator is OFF.
322 
323       (++) Entry:
324         (+++) The STANDBY mode is entered using the HAL_PWR_EnterSTANDBYMode()
325               function.
326 
327       (++) Exit:
328         (+++) WKUP pin rising or falling edge, RTC alarm (Alarm A and Alarm B),
329               RTC wakeup, tamper event, time stamp event, external reset in NRST
330               pin, IWDG reset.
331 
332    *** Auto-wakeup (AWU) from low-power mode ***
333    =============================================
334     [..]
335      (+) The MCU can be woken up from low-power mode by an RTC Alarm event, an
336          RTC Wakeup event, a tamper event or a time-stamp event, without
337          depending on an external interrupt (Auto-wakeup mode).
338 
339      (+) RTC auto-wakeup (AWU) from the STOP and STANDBY modes
340 
341        (++) To wake up from the STOP mode with an RTC alarm event, it is
342             necessary to configure the RTC to generate the RTC alarm using the
343             HAL_RTC_SetAlarm_IT() function.
344 
345        (++) To wake up from the STOP mode with an RTC Tamper or time stamp event,
346             it is necessary to configure the RTC to detect the tamper or time
347             stamp event using the HAL_RTCEx_SetTimeStamp_IT() or
348             HAL_RTCEx_SetTamper_IT() functions.
349 
350        (++) To wake up from the STOP mode with an RTC WakeUp event, it is
351             necessary to configure the RTC to generate the RTC WakeUp event
352             using the HAL_RTCEx_SetWakeUpTimer_IT() function.
353 
354 @endverbatim
355   * @{
356   */
357 
358 /**
359   * @brief  Configure the voltage threshold detected by the Programmed Voltage
360   *         Detector (PVD).
361   * @param  pConfigPVD : Pointer to a PWR_PVDTypeDef structure that contains the
362   *                      PVD configuration information (EventMode).
363   * @retval None.
364   */
HAL_PWR_ConfigPVD(const PWR_PVDTypeDef * pConfigPVD)365 void HAL_PWR_ConfigPVD(const PWR_PVDTypeDef *pConfigPVD)
366 {
367   /* Check the parameters */
368   assert_param(IS_PWR_PVD_MODE(pConfigPVD->Mode));
369 
370   /* Disable PVD Event/Interrupt */
371   __HAL_PWR_PVD_EXTI_DISABLE_EVENT();
372   __HAL_PWR_PVD_EXTI_DISABLE_IT();
373   __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();
374   __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE();
375 
376   /* Configure the PVD in interrupt mode */
377   if ((pConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT)
378   {
379     __HAL_PWR_PVD_EXTI_ENABLE_IT();
380   }
381 
382   /* Configure the PVD in event mode */
383   if ((pConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT)
384   {
385     __HAL_PWR_PVD_EXTI_ENABLE_EVENT();
386   }
387 
388   /* Rising edge configuration */
389   if ((pConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE)
390   {
391     __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();
392   }
393 
394   /* Falling edge configuration */
395   if ((pConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE)
396   {
397     __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
398   }
399 }
400 
401 /**
402   * @brief  Enable the programmable voltage detector (PVD).
403   * @retval None.
404   */
HAL_PWR_EnablePVD(void)405 void HAL_PWR_EnablePVD(void)
406 {
407   SET_BIT(PWR->CR2, PWR_CR2_PVDEN);
408 }
409 
410 /**
411   * @brief  Disable the programmable voltage detector (PVD).
412   * @retval None.
413   */
HAL_PWR_DisablePVD(void)414 void HAL_PWR_DisablePVD(void)
415 {
416   CLEAR_BIT(PWR->CR2, PWR_CR2_PVDEN);
417 }
418 
419 /**
420   * @brief  Enable the WakeUp PINx functionality.
421   * @param  WakeUpPinPolarity : Specifies which Wake-Up pin to enable.
422   *          This parameter can be one of the following legacy values, which
423   *          sets the default (rising edge):
424   *            @arg PWR_WAKEUP_PIN1,
425   *                 PWR_WAKEUP_PIN2,
426   *                 PWR_WAKEUP_PIN3,
427   *                 PWR_WAKEUP_PIN4.
428   *          or one of the following values where the user can explicitly states
429   *          the enabled pin and the chosen polarity:
430   *            @arg PWR_WAKEUP_PIN1_HIGH, PWR_WAKEUP_PIN1_LOW,
431   *                 PWR_WAKEUP_PIN2_HIGH, PWR_WAKEUP_PIN2_LOW,
432   *                 PWR_WAKEUP_PIN3_HIGH, PWR_WAKEUP_PIN3_LOW,
433   *                 PWR_WAKEUP_PIN4_HIGH, PWR_WAKEUP_PIN4_LOW.
434   * @note   PWR_WAKEUP_PINx and PWR_WAKEUP_PINx_HIGH are equivalent.
435   * @retval None.
436   */
HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity)437 void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity)
438 {
439   /* Check the parameters */
440   assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinPolarity));
441 
442   /*
443      Enable and Specify the Wake-Up pin polarity and the pull configuration
444      for the event detection (rising or falling edge).
445   */
446   SET_BIT(PWR->WKUPEPR, WakeUpPinPolarity);
447 }
448 
449 /**
450   * @brief  Disable the WakeUp PINx functionality.
451   * @param  WakeUpPinx : Specifies the Power Wake-Up pin to disable.
452   *          This parameter can be one of the following values:
453   *            @arg PWR_WAKEUP_PIN1,
454   *                 PWR_WAKEUP_PIN2,
455   *                 PWR_WAKEUP_PIN3,
456   *                 PWR_WAKEUP_PIN4,
457   *                 PWR_WAKEUP_PIN1_HIGH, PWR_WAKEUP_PIN1_LOW,
458   *                 PWR_WAKEUP_PIN2_HIGH, PWR_WAKEUP_PIN2_LOW,
459   *                 PWR_WAKEUP_PIN3_HIGH, PWR_WAKEUP_PIN3_LOW,
460   *                 PWR_WAKEUP_PIN4_HIGH, PWR_WAKEUP_PIN4_LOW.
461   * @retval None.
462   */
HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)463 void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
464 {
465   /* Check the parameters */
466   assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
467 
468   /* Disable the wake up pin selected */
469   CLEAR_BIT(PWR->WKUPEPR, (PWR_WKUPEPR_WKUPEN & WakeUpPinx));
470 }
471 
472 /**
473   * @brief Get the Wake-Up Pin pending flags.
474   * @param  WakeUpFlag : Specifies the Wake-Up PIN flag to be checked.
475   *          This parameter can be one of the following values:
476   *            @arg PWR_WAKEUP_FLAG1    : Get wakeup event received from PA0.
477   *            @arg PWR_WAKEUP_FLAG2    : Get wakeup event received from PA2.
478   *            @arg PWR_WAKEUP_FLAG3    : Get wakeup event received from PC13.
479   *            @arg PWR_WAKEUP_FLAG4    : Get wakeup event received from PD2.
480   *            @arg PWR_WAKEUP_FLAG_ALL : Get Wakeup event received from all
481   *                                       wake up pins.
482   * @retval The Wake-Up pin flag.
483   */
HAL_PWR_GetWakeupFlag(uint32_t WakeUpFlag)484 uint32_t HAL_PWR_GetWakeupFlag(uint32_t WakeUpFlag)
485 {
486   /* Check the parameters */
487   assert_param(IS_PWR_WAKEUP_FLAG(WakeUpFlag));
488 
489   /* Return the wake up pin flag */
490   return (PWR->WKUPSR & WakeUpFlag);
491 }
492 
493 /**
494   * @brief Clear the Wake-Up pin pending flag.
495   * @param  WakeUpFlag: Specifies the Wake-Up PIN flag to clear.
496   *          This parameter can be one of the following values:
497   *            @arg PWR_WAKEUP_FLAG1    : Clear the wakeup event received from PA0.
498   *            @arg PWR_WAKEUP_FLAG2    : Clear the wakeup event received from PA2.
499   *            @arg PWR_WAKEUP_FLAG3    : Clear the wakeup event received from PC13.
500   *            @arg PWR_WAKEUP_FLAG4    : Clear the wakeup event received from PD2.
501   *            @arg PWR_WAKEUP_FLAG_ALL : Clear the wakeup events received from all
502   *                                       wake up pins.
503   * @retval HAL status.
504   */
HAL_PWR_ClearWakeupFlag(uint32_t WakeUpFlag)505 HAL_StatusTypeDef HAL_PWR_ClearWakeupFlag(uint32_t WakeUpFlag)
506 {
507   /* Check the parameter */
508   assert_param(IS_PWR_WAKEUP_FLAG(WakeUpFlag));
509 
510   /* Clear the wake up event received from wake up pin x */
511   WRITE_REG(PWR->WKUPCR, WakeUpFlag);
512 
513   /* Check if the wake up event is well cleared */
514   if ((PWR->WKUPSR & WakeUpFlag) != 0U)
515   {
516     return HAL_ERROR;
517   }
518 
519   return HAL_OK;
520 }
521 
522 /**
523   * @brief  Enter the current core in SLEEP mode (CSLEEP).
524   * @param  Regulator : NA in this family project
525   *         Specifies the regulator state in SLEEP mode.
526   * @note   This parameter is not used for the STM32N6 family and is kept as
527   *         parameter just to maintain compatibility with the lower power
528   *         families.
529   * @param  SLEEPEntry : Specifies if SLEEP mode is entered with WFI or WFE
530   *                      intrinsic instruction.
531   *          This parameter can be one of the following values:
532   *            @arg PWR_SLEEPENTRY_WFI :             Enter SLEEP mode with WFI instruction.
533   *            @arg PWR_SLEEPENTRY_WFE :             Enter SLEEP mode with WFE instruction.
534   *            @arg PWR_SLEEPENTRY_WFE_NO_EVT_CLEAR: Enter SLEEP mode with WFE and no clear of pending event before.
535   *
536   * @note   Ensure to clear pending events before calling this API through
537   *         HAL_PWREx_ClearPendingEvent() when the SLEEP entry is WFE.
538   * @retval None.
539   */
HAL_PWR_EnterSLEEPMode(uint32_t Regulator,uint8_t SLEEPEntry)540 void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
541 {
542   /* Prevent unused argument(s) compilation warning */
543   UNUSED(Regulator);
544 
545   /* Check the parameters */
546   assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry));
547 
548   /* Clear SLEEPDEEP bit of Cortex System Control Register */
549   CLEAR_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk);
550 
551   /* Select Sleep mode entry */
552   if (SLEEPEntry == PWR_SLEEPENTRY_WFI)
553   {
554     /* Request Wait For Interrupt */
555     __WFI();
556   }
557   else
558   {
559     if(SLEEPEntry != PWR_SLEEPENTRY_WFE_NO_EVT_CLEAR)
560     {
561       /* Clear all pending event */
562       __SEV();
563       __WFE();
564     }
565 
566     /* Request Wait For Event */
567     __WFE();
568   }
569 }
570 
571 /**
572   * @brief  Enter the whole system to Stop mode.
573   * @note   This API will enter the system in STOP mode
574   * @param  Regulator : This parameter is not used for this product family.
575             and is kept as parameter just to maintain compatibility with the
576             lower power families.
577   * @param  STOPEntry : Specifies if STOP mode in entered with WFI or WFE
578   *                     intrinsic instruction.
579   *          This parameter can be one of the following values:
580   *            @arg PWR_STOPENTRY_WFI              : Enter STOP mode with WFI instruction.
581   *            @arg PWR_STOPENTRY_WFE              : Enter STOP mode with WFE instruction.
582   *            @arg PWR_STOPENTRY_WFE_NO_EVT_CLEAR : Enter STOP  mode with WFE and no clear of pending event before.
583   * @note   In System STOP mode, all I/O pins keep the same state as in Run mode.
584   * @note   When exiting System STOP mode by issuing an interrupt or a wakeup
585   *         event, the HSI RC oscillator is selected as default system wakeup
586   *         clock.
587   * @note   In System STOP mode, when the voltage regulator operates in low
588   *         power mode, an additional startup delay is incurred when the system
589   *         is waking up. By keeping the internal regulator ON during STOP mode,
590   *         the consumption is higher although the startup time is reduced.
591   * @retval None.
592   */
HAL_PWR_EnterSTOPMode(uint32_t Regulator,uint8_t STOPEntry)593 void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
594 {
595 
596   /* Prevent unused argument(s) compilation warning */
597   UNUSED(Regulator);
598 
599   /* Check the parameters */
600   assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
601 
602   /* Select Stop mode when device enters Deepsleep */
603   CLEAR_BIT(PWR->CPUCR, PWR_CPUCR_PDDS);
604 
605   /* Set SLEEPDEEP bit of Cortex System Control Register */
606   SET_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk);
607 
608   /* Ensure that all instructions are done before entering STOP mode */
609   __DSB();
610   __ISB();
611 
612   /* Select Stop mode entry */
613   if (STOPEntry == PWR_STOPENTRY_WFI)
614   {
615     /* Request Wait For Interrupt */
616     __WFI();
617   }
618   else
619   {
620     if(STOPEntry != PWR_STOPENTRY_WFE_NO_EVT_CLEAR)
621     {
622       /* Clear all pending event */
623       __SEV();
624       __WFE();
625     }
626 
627     /* Request Wait For Event */
628     __WFE();
629   }
630 
631   /* Clear SLEEPDEEP bit of Cortex-M55 in the System Control Register */
632   CLEAR_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk);
633 }
634 
635 /**
636   * @brief  Enter the whole system to Standby mode.
637   * @note   The Standby mode allows achieving the lowest power consumption.
638   * @note   When the system enters in Standby mode, the voltage regulator is disabled.
639   *         The complete VCORE domain is consequently powered off.
640   *         The PLLs, HSI oscillator, CSI oscillator, HSI48 and the HSE oscillator are
641   *         also switched off.
642   *         SRAM and register contents are lost except for backup domain registers
643   *         (RTC registers, RTC backup register and backup RAM), and Standby circuitry.
644   * @note   When the System exit STANDBY mode by issuing an interrupt or a
645   *         wakeup event, the HSI RC oscillator is selected as system clock.
646   * @retval None.
647   */
HAL_PWR_EnterSTANDBYMode(void)648 void HAL_PWR_EnterSTANDBYMode(void)
649 {
650   /* Select Standby when device enters Deepsleep */
651   SET_BIT(PWR->CPUCR, PWR_CPUCR_PDDS);
652 
653   /* Set SLEEPDEEP bit of Cortex System Control Register */
654   SET_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk);
655 
656   /* Ensure that all instructions are done before entering STANDBY mode */
657   __DSB();
658   __ISB();
659 
660   /* Request Wait For Interrupt */
661   __WFI();
662 }
663 
664 /**
665   * @brief  Indicate SLEEP-ON-EXIT feature when returning from handler mode to
666   *         thread mode.
667   * @note   Set SLEEPONEXIT bit of SCR register. When this bit is set, the
668   *         processor re-enters Sleep mode when an interruption handling is over.
669   *         Setting this bit is useful when the processor is expected to run
670   *         only on interruptions handling.
671   * @retval None.
672   */
HAL_PWR_EnableSleepOnExit(void)673 void HAL_PWR_EnableSleepOnExit(void)
674 {
675   /* Set SLEEPONEXIT bit of Cortex-M55 System Control Register */
676   SET_BIT(SCB->SCR, SCB_SCR_SLEEPONEXIT_Msk);
677 }
678 
679 /**
680   * @brief  Disable SLEEP-ON-EXIT feature when returning from handler mode to
681   *         thread mode.
682   * @note   Clears SLEEPONEXIT bit of SCR register. When this bit is set, the
683   *         processor re-enters Sleep mode when an interruption handling is over.
684   * @retval None.
685   */
HAL_PWR_DisableSleepOnExit(void)686 void HAL_PWR_DisableSleepOnExit(void)
687 {
688   /* Clear SLEEPONEXIT bit of Cortex-M55 System Control Register */
689   CLEAR_BIT(SCB->SCR, SCB_SCR_SLEEPONEXIT_Msk);
690 }
691 
692 /**
693   * @brief  Enable CORTEX SEV-ON-PEND feature.
694   * @note   Sets SEVONPEND bit of SCR register. When this bit is set, any
695   *         pending event / interrupt even if it's disabled or has insufficient
696   *         priority to cause exception entry wakes up the Cortex-M55.
697   * @retval None.
698   */
HAL_PWR_EnableSEVOnPend(void)699 void HAL_PWR_EnableSEVOnPend(void)
700 {
701   /* Set SEVONPEND bit of Cortex-M55 System Control Register */
702   SET_BIT(SCB->SCR, SCB_SCR_SEVONPEND_Msk);
703 }
704 
705 /**
706   * @brief  Disable CORTEX SEVONPEND feature.
707   * @note   Resets SEVONPEND bit of SCR register. When this bit is reset, only
708   *         enabled pending causes exception entry wakes up the Cortex-M55.
709   * @retval None.
710   */
HAL_PWR_DisableSEVOnPend(void)711 void HAL_PWR_DisableSEVOnPend(void)
712 {
713   /* Clear SEVONPEND bit of Cortex-M55 System Control Register */
714   CLEAR_BIT(SCB->SCR, SCB_SCR_SEVONPEND_Msk);
715 }
716 
717 /**
718   * @brief  PWR PVD interrupt Rising callback
719   * @retval None
720   */
HAL_PWR_PVD_Rising_Callback(void)721 __weak void HAL_PWR_PVD_Rising_Callback(void)
722 {
723   /* NOTE : This function should not be modified; when the callback is needed,
724             the HAL_PWR_PVD_Rising_Callback can be implemented in the user file
725   */
726 }
727 
728 /**
729   * @brief  PWR PVD interrupt Falling callback
730   * @retval None
731   */
HAL_PWR_PVD_Falling_Callback(void)732 __weak void HAL_PWR_PVD_Falling_Callback(void)
733 {
734   /* NOTE : This function should not be modified; when the callback is needed,
735             the HAL_PWR_PVD_Falling_Callback can be implemented in the user file
736   */
737 }
738 
739 /**
740   * @brief This function handles the PWR WAKEUP PIN interrupt request.
741   * @note   This API should be called under the WAKEUP_PIN_IRQHandler().
742   * @retval None.
743   */
HAL_PWR_WAKEUP_PIN_IRQHandler(void)744 void HAL_PWR_WAKEUP_PIN_IRQHandler(void)
745 {
746   /* Wakeup pin EXTI line interrupt detected */
747   if (READ_BIT(PWR->WKUPSR, PWR_WKUPSR_WKUPF1) != 0U)
748   {
749     /* Clear PWR WKUPF1 flag */
750     __HAL_PWR_CLEAR_WAKEUPFLAG(PWR_FLAG_WKUP1);
751 
752     /* PWR WKUP1 interrupt user callback */
753     HAL_PWR_WKUP1_Callback();
754   }
755 
756   if (READ_BIT(PWR->WKUPSR, PWR_WKUPSR_WKUPF2) != 0U)
757   {
758     /* Clear PWR WKUPF2 flag */
759     __HAL_PWR_CLEAR_WAKEUPFLAG(PWR_FLAG_WKUP2);
760 
761     /* PWR WKUP2 interrupt user callback */
762     HAL_PWR_WKUP2_Callback();
763   }
764 
765   if (READ_BIT(PWR->WKUPSR, PWR_WKUPSR_WKUPF3) != 0U)
766   {
767     /* Clear PWR WKUPF3 flag */
768     __HAL_PWR_CLEAR_WAKEUPFLAG(PWR_FLAG_WKUP3);
769 
770     /* PWR WKUP3 interrupt user callback */
771     HAL_PWR_WKUP3_Callback();
772   }
773 
774   if (READ_BIT(PWR->WKUPSR, PWR_WKUPSR_WKUPF4) != 0U)
775   {
776     /* Clear PWR WKUPF4 flag */
777     __HAL_PWR_CLEAR_WAKEUPFLAG(PWR_FLAG_WKUP4);
778 
779     /* PWR WKUP4 interrupt user callback */
780     HAL_PWR_WKUP4_Callback();
781   }
782 }
783 
784 /**
785   * @brief PWR WKUP1 interrupt callback.
786   * @retval None.
787   */
HAL_PWR_WKUP1_Callback(void)788 __weak void HAL_PWR_WKUP1_Callback(void)
789 {
790   /* NOTE : This function should not be modified, when the callback is needed,
791             the HAL_PWR_WKUP1_Callback can be implemented in the user file
792   */
793 }
794 
795 /**
796   * @brief PWR WKUP2 interrupt callback.
797   * @retval None.
798   */
HAL_PWR_WKUP2_Callback(void)799 __weak void HAL_PWR_WKUP2_Callback(void)
800 {
801   /* NOTE : This function should not be modified, when the callback is needed,
802             the HAL_PWR_WKUP2_Callback can be implemented in the user file
803   */
804 }
805 
806 /**
807   * @brief PWR WKUP3 interrupt callback.
808   * @retval None.
809   */
HAL_PWR_WKUP3_Callback(void)810 __weak void HAL_PWR_WKUP3_Callback(void)
811 {
812   /* NOTE : This function should not be modified, when the callback is needed,
813             the HAL_PWR_WKUP3_Callback can be implemented in the user file
814   */
815 }
816 
817 /**
818   * @brief PWR WKUP4 interrupt callback.
819   * @retval None.
820   */
HAL_PWR_WKUP4_Callback(void)821 __weak void HAL_PWR_WKUP4_Callback(void)
822 {
823   /* NOTE : This function should not be modified, when the callback is needed,
824             the HAL_PWR_WKUP4_Callback can be implemented in the user file
825   */
826 }
827 
828 /**
829   * @}
830   */
831 #if defined(PWR_PRIVCFGR_PRIV0)
832 /** @defgroup PWR_Exported_Functions_Group3 Attributes Management Functions
833   *  @brief    Attributes management functions
834   *
835 @verbatim
836  ===============================================================================
837                        ##### PWR Attributes Functions #####
838  ===============================================================================
839     [..]
840       The PWR is able to protect register bits from being modified by non-secure
841       and unprivileged accesses.
842       The protection can be activated for the following features through PWR_SECCFGR and
843       PWR_PRIVCFGR:
844 
845       (++) System supply configuration.
846       (++) Voltage scaling.
847       (++) Low-power mode.
848       (++) Wake-up (WKUP) pins.
849       (++) Voltage detection and monitoring.
850       (++) VBAT mode.
851 
852       A non-secure access to a secure-protected register bit is denied :
853       (++) The secured bits are not written (WI) with a non-secure write access.
854       (++) The secured bits are read as 0 (RAZ) with a non-secure read access.
855 
856     [..]
857       After any application reset or system reset, the PWR does not filter any access
858       (default configuration: non-secure, any privileged) until the trusted agent has
859       programmed the security and privileged protection.
860 
861     [..] Secure/non-secure access filtering
862       To enable the filtering access based on this attribute, the authorized master
863       agent must set SECx in PWR_SECCFGR related to the PWR feature.
864 
865       When a register is configured as secure, read and write operations are only
866       allowed by a secure access.
867       Non-secure read or write accesses are denied (RAZ/WI).
868       An illegal secure access event is generated to the IAC (illegal access controller).
869       There is no bus error generated.
870       When a register is configured as non-secure, read and write operations are
871       allowed by both secure and non-secure accesses.
872 
873     [..] Privileged/unprivileged access filtering
874       To enable the filtering access based on this attribute, the authorized master
875       agent has to set PRIVx in PWR_PRIVCFGR related to the PWR feature.
876       When a register is configured as privileged, read and write operations are only
877       allowed by a privileged access.
878       Unprivileged read or write accesses are denied (RAZ/WI).
879       An illegal privileged access event is generated to the IAC.
880       There is no bus error generated.
881       When a register is configured as unprivileged, read and write operations are
882       allowed by both privileged and unprivileged accesses.
883 
884 @endverbatim
885   * @{
886   */
887 
888 /**
889   * @brief  Configure the PWR item attributes.
890   * @note   Available attributes are security and privilege protection.
891   * @note   Security attribute can only be set only by secure access.
892   * @note   Privilege attribute for secure items can be managed only by a secure
893   *         privileged access.
894   * @note   Privilege attribute for nsecure items can be managed  by a secure
895   *         privileged access or by a nsecure privileged access.
896   * @param  Item       : Specifies the item(s) to set attributes on.
897   *                      This parameter can be a combination of PWR_ITEMS.
898   * @param  Attributes : Specifies the available attribute(s).
899   *                      This parameter can be one of PWR_ATTRIBUTES.
900   * @retval None.
901   */
HAL_PWR_ConfigAttributes(uint32_t Item,uint32_t Attributes)902 void HAL_PWR_ConfigAttributes(uint32_t Item, uint32_t Attributes)
903 {
904   /* Check the parameters */
905   assert_param(IS_PWR_ITEMS_ATTRIBUTES(Item));
906   assert_param(IS_PWR_ATTRIBUTES(Attributes));
907 
908 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
909   /* Secure item management (TZEN = 1) */
910   if ((Attributes & PWR_ITEM_ATTR_SEC_PRIV_MASK) == PWR_ITEM_ATTR_SEC_PRIV_MASK)
911   {
912     /* Privilege item management */
913     if ((Attributes & PWR_SEC_PRIV) == PWR_SEC_PRIV)
914     {
915       SET_BIT(PWR_S->SECCFGR, Item);
916       SET_BIT(PWR->PRIVCFGR, Item);
917     }
918     else
919     {
920       SET_BIT(PWR_S->SECCFGR, Item);
921       CLEAR_BIT(PWR->PRIVCFGR, Item);
922     }
923   }
924   /* NSecure item management */
925   else
926   {
927     /* Privilege item management */
928     if ((Attributes & PWR_NSEC_PRIV) == PWR_NSEC_PRIV)
929     {
930       CLEAR_BIT(PWR_S->SECCFGR, Item);
931       SET_BIT(PWR->PRIVCFGR, Item);
932     }
933     else
934     {
935       CLEAR_BIT(PWR_S->SECCFGR, Item);
936       CLEAR_BIT(PWR->PRIVCFGR, Item);
937     }
938   }
939 #else
940   /* NSecure item management (TZEN = 0) */
941   if ((Attributes & PWR_ITEM_ATTR_NSEC_PRIV_MASK) == PWR_ITEM_ATTR_NSEC_PRIV_MASK)
942   {
943     /* Privilege item management */
944     if ((Attributes & PWR_NSEC_PRIV) == PWR_NSEC_PRIV)
945     {
946       SET_BIT(PWR->PRIVCFGR, Item);
947     }
948     else
949     {
950       CLEAR_BIT(PWR->PRIVCFGR, Item);
951     }
952   }
953 #endif /* __ARM_FEATURE_CMSE */
954 }
955 
956 
957 /**
958   * @brief  Get attribute(s) of a PWR item.
959   * @param  Item        : Specifies the item(s) to get attributes on.
960   *                       This parameter can be one of PWR_ITEMS.
961   * @param  pAttributes : Pointer to return attribute(s).
962   *                       Returned value could be on of PWR_ATTRIBUTES.
963   * @retval HAL Status.
964   */
HAL_PWR_GetConfigAttributes(uint32_t Item,uint32_t * pAttributes)965 HAL_StatusTypeDef HAL_PWR_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes)
966 {
967   uint32_t attributes;
968 
969   /* Check attribute pointer */
970   if (pAttributes == NULL)
971   {
972     return HAL_ERROR;
973   }
974 
975   /* Check the parameter */
976   assert_param(IS_PWR_ITEMS_ATTRIBUTES(Item));
977 
978 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
979 
980   /* Check item security */
981   if ((PWR->SECCFGR & Item) == Item)
982   {
983     if ((PWR->PRIVCFGR & Item) == Item)
984     {
985       attributes = PWR_SEC_PRIV;
986     }
987     else
988     {
989       attributes = PWR_SEC_NPRIV;
990     }
991   }
992   else
993   {
994     if ((PWR->PRIVCFGR & Item) == Item)
995     {
996       attributes = PWR_NSEC_PRIV;
997     }
998     else
999     {
1000       attributes = PWR_NSEC_NPRIV;
1001     }
1002   }
1003 #else
1004   if ((PWR->PRIVCFGR & Item) == Item)
1005   {
1006     attributes = PWR_NSEC_PRIV;
1007   }
1008   else
1009   {
1010     attributes = PWR_NSEC_NPRIV;
1011   }
1012 #endif /* __ARM_FEATURE_CMSE */
1013 
1014   /* return value */
1015   *pAttributes = attributes;
1016 
1017   return HAL_OK;
1018 }
1019 /**
1020   * @}
1021   */
1022 #endif /* #if defined(PWR_PRIVCFGR_PRIV0) */
1023 
1024 /**
1025   * @}
1026   */
1027 #endif /* defined (HAL_PWR_MODULE_ENABLED) */
1028 /**
1029   * @}
1030   */
1031 
1032 /**
1033   * @}
1034   */
1035 
1036