1 /**
2   ******************************************************************************
3   * @file    stm32h7rsxx_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   *
11   ******************************************************************************
12   * @attention
13   *
14   * Copyright (c) 2022 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   @verbatim
23   ==============================================================================
24                         ##### PWR peripheral overview #####
25   ==============================================================================
26   [..]
27    (#) The Power control (PWR) provides an overview of the supply architecture
28        for the different power domains and of the supply configuration
29        controller.
30 
31    (#) Several low-power modes are available to save power when the CPU does not need to
32        execute code :
33       (+) Sleep   (CPU clock stopped and still in RUN mode)
34       (+) Stop    (System clock stopped)
35       (+) Standby (System powered down)
36 
37   ==============================================================================
38                         ##### How to use this driver #####
39   ==============================================================================
40   [..]
41 
42    (#) Call HAL_PWR_EnableBkUpAccess() and HAL_PWR_DisableBkUpAccess() functions
43        to enable/disable access to the backup domain (RCC Backup domain control
44        register RCC_BDCR, RTC registers, TAMP registers, backup registers and
45        backup SRAM).
46 
47    (#) Call HAL_PWR_ConfigPVD() after setting parameters to be configured (event
48        mode and voltage threshold) in order to set up the Programmed Voltage
49        Detector, then use HAL_PWR_EnablePVD() and  HAL_PWR_DisablePVD()
50        functions to start and stop the PVD detection.
51        (+) PVD level can be one of the following values :
52              (++) 2V0
53              (++) 2V2
54              (++) 2V4
55              (++) 2V5
56              (++) 2V6
57              (++) 2V8
58              (++) 2V9
59              (++) External input analog voltage PVD_IN (compared internally to
60                   VREFINT)
61 
62    (#) Call HAL_PWR_EnableWakeUpPin() and HAL_PWR_DisableWakeUpPin() functions
63        with the right parameter to configure the wake up pin polarity (Low or
64        High), the wake up pin selection and to enable and disable it.
65 
66    (#) Call HAL_PWR_EnterSLEEPMode() function to enter the CPU in Sleep mode.
67        Wake-up from Sleep mode could be following to an event or an
68        interrupt according to low power mode intrinsic request called (__WFI()
69        or __WFE()).
70 
71    (#) Call HAL_PWR_EnterSTOPMode() function to enter the whole system to Stop
72        mode. Wake-up from Stop mode could be following to an event or an
73        interrupt according to low power mode intrinsic request called (__WFI()
74        or __WFE()).
75 
76    (#) Call HAL_PWR_EnterSTANDBYMode() function to enter the whole system in
77        Standby mode. Wake-up from Standby mode can be following only by an
78        interrupt.
79 
80    (#) Call HAL_PWR_EnableSleepOnExit() and HAL_PWR_DisableSleepOnExit() APIs to
81        enable and disable the Cortex-M7 re-entry in Sleep mode after an
82        interruption handling is over.
83 
84    (#) Call HAL_PWR_EnableSEVOnPend() and HAL_PWR_DisableSEVOnPend() functions
85        to configure the Cortex-M7 to wake-up after any pending event / interrupt
86        even if it's disabled or has insufficient priority to cause exception
87        entry.
88 
89      *** PWR HAL driver macros list ***
90      =============================================
91      [..]
92        Below the list of most used macros in PWR HAL driver.
93 
94       (+) __HAL_PWR_GET_FLAG()   : Get the PWR pending flags.
95       (+) __HAL_PWR_CLEAR_FLAG() : Clear the PWR pending flags.
96   @endverbatim
97   ******************************************************************************
98   */
99 
100 /* Includes ------------------------------------------------------------------*/
101 #include "stm32h7rsxx_hal.h"
102 
103 /** @addtogroup STM32H7RSxx_HAL_Driver
104   * @{
105   */
106 
107 /** @defgroup PWR PWR
108   * @brief PWR HAL module driver
109   * @{
110   */
111 
112 #ifdef HAL_PWR_MODULE_ENABLED
113 
114 /* Private typedef -----------------------------------------------------------*/
115 /* Private define ------------------------------------------------------------*/
116 
117 /** @defgroup PWR_Private_Defines PWR Private Defines
118   * @{
119   */
120 
121 /** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask
122   * @{
123   */
124 #define PVD_MODE_IT                     (0x00010000U)
125 #define PVD_MODE_EVT                    (0x00020000U)
126 #define PVD_RISING_EDGE                 (0x00000001U)
127 #define PVD_FALLING_EDGE                (0x00000002U)
128 #define PVD_RISING_FALLING_EDGE         (0x00000003U)
129 /**
130   * @}
131   */
132 
133 /**
134   * @}
135   */
136 
137 /* Private macro -------------------------------------------------------------*/
138 /* Private variables ---------------------------------------------------------*/
139 /* Private function prototypes -----------------------------------------------*/
140 /* Exported functions --------------------------------------------------------*/
141 
142 /** @defgroup PWR_Exported_Functions PWR Exported Functions
143   * @{
144   */
145 
146 /** @defgroup PWR_Exported_Functions_Group1 Initialization and De-Initialization Functions
147   *  @brief   Initialization and de-Initialization functions
148   *
149 @verbatim
150  ===============================================================================
151               ##### Initialization and De-Initialization Functions #####
152  ===============================================================================
153     [..]
154       This section provides functions allowing to deinitialize power peripheral.
155 
156     [..]
157       After system reset, the backup domain (RCC Backup domain control register
158       RCC_BDCR, RTC registers, TAMP registers, backup registers and backup SRAM)
159       is protected against possible unwanted write accesses.
160       The HAL_PWR_EnableBkUpAccess() function enables the access to the backup
161       domain.
162       The HAL_PWR_DisableBkUpAccess() function disables the access to the backup
163       domain.
164 
165 @endverbatim
166   * @{
167   */
168 
169 /**
170   * @brief  Deinitialize the HAL PWR peripheral registers to their default reset
171   *         values.
172   * @note   This functionality is not available in this product.
173   *         The prototype is kept just to maintain compatibility with other
174   *         products.
175   * @retval None.
176   */
HAL_PWR_DeInit(void)177 void HAL_PWR_DeInit(void)
178 {
179 }
180 
181 /**
182   * @brief  Enable access to the backup domain (RCC Backup domain control
183   *         register RCC_BDCR, RTC registers, TAMP registers, backup registers
184   *         and backup SRAM).
185   * @note   After a system reset, the backup domain is protected against
186   *         possible unwanted write accesses.
187   * @retval None.
188   */
HAL_PWR_EnableBkUpAccess(void)189 void HAL_PWR_EnableBkUpAccess(void)
190 {
191   SET_BIT(PWR->CR1, PWR_CR1_DBP);
192 }
193 
194 /**
195   * @brief  Disable access to the backup domain (RCC Backup domain control
196   *         register RCC_BDCR, RTC registers, TAMP registers, backup registers
197   *         and backup SRAM).
198   * @retval None.
199   */
HAL_PWR_DisableBkUpAccess(void)200 void HAL_PWR_DisableBkUpAccess(void)
201 {
202   CLEAR_BIT(PWR->CR1, PWR_CR1_DBP);
203 }
204 /**
205   * @}
206   */
207 
208 
209 /** @defgroup PWR_Exported_Functions_Group2 Peripheral Control Functions
210   *  @brief   Power Control functions
211   *
212 @verbatim
213  ===============================================================================
214                  ##### Peripheral Control Functions #####
215  ===============================================================================
216     [..]
217       This section provides functions allowing to control power peripheral.
218 
219     *** PVD configuration ***
220     =========================
221     [..]
222       (+) The PVD is used to monitor the VDD power supply by comparing it to a
223           threshold selected by the PVD Level (PLS[2:0] bits in the PWR_CR1
224           register).
225 
226       (+) A PVDO flag is available to indicate if VDD is higher or lower
227           than the PVD threshold. This event is internally connected to the EXTI
228           line 16 to generate an interrupt if enabled.
229           It is configurable through __HAL_PWR_PVD_EXTI_ENABLE_IT() macro.
230 
231       (+) The PVD is stopped in STANDBY mode.
232 
233     *** Wake-up pin configuration ***
234     =================================
235     [..]
236       (+) Wake-up pin is used to wake up the system from STANDBY mode.
237           The pin pull is configurable through the WKUPEPR register to be in
238           No-pull, Pull-up and Pull-down.
239           The pin polarity is configurable through the WKUPEPR register to be
240           active on rising or falling edges.
241 
242       (+) There are up to four Wake-up pin in the STM32H7RS devices family.
243 
244     *** Low Power modes configuration ***
245     =====================================
246     [..]
247      The device present 3 principles low-power modes :
248       (+) SLEEP mode   : Cortex-M7 is stopped and all PWR domains are remaining
249                          active (Powered and Clocked).
250 
251       (+) STOP mode    : Cortex-M7 is stopped, clocks are stopped and the
252                          regulator is running. The Main regulator or the LP
253                          regulator could be selected.
254 
255       (+) STANDBY mode : All PWR domains enter DSTANDBY mode and the VCORE
256                          supply regulator is powered off.
257 
258    *** SLEEP mode ***
259    ==================
260     [..]
261       (+) Entry:
262         The SLEEP mode is entered by using the HAL_PWR_EnterSLEEPMode(Regulator,
263         SLEEPEntry) function.
264 
265           (++) PWR_SLEEPENTRY_WFI             : Enter SLEEP mode with WFI instruction.
266           (++) PWR_SLEEPENTRY_WFE             : Enter SLEEP mode with WFE instruction and
267                                                 clear of pending events before.
268           (++) PWR_SLEEPENTRY_WFE_NO_EVT_CLEAR: Enter SLEEP mode with WFE instruction and
269                                                 no clear of pending event before.
270       -@@- The Regulator parameter is not used for the STM32H7RS family
271               and is kept as parameter just to maintain compatibility with the
272               lower power families. (STM32L).
273 
274       (+) Exit:
275         Any peripheral interrupt acknowledged by the nested vectored interrupt
276         controller (NVIC) can wake up the device from SLEEP mode.
277 
278    *** STOP mode ***
279    =================
280     [..]
281       In system STOP mode, the CPU clock is stopped. All CPU subsystem peripheral
282       clocks are stopped too.
283       The voltage regulator can be configured either in normal or low-power mode.
284       To minimize the consumption in STOP mode, FLASH can be powered off before
285       entering the STOP mode using the HAL_PWREx_EnableFlashPowerDown() function.
286       It can be switched on again by software after exiting the STOP mode using
287       the HAL_PWREx_DisableFlashPowerDown() function.
288       (+) Entry:
289          The STOP mode is entered using the HAL_PWR_EnterSTOPMode(Regulator,
290          STOPEntry) function with:
291          (++) Regulator:
292           (+++) PWR_MAINREGULATOR_ON: Main regulator ON.
293                 This parameter is not used for the STM32H7RS family and is kept as parameter
294                 just to maintain compatibility with the lower power families.
295          (++) STOPEntry:
296           (+++) PWR_STOPENTRY_WFI             : Enter STOP mode with WFI instruction.
297           (+++) PWR_STOPENTRY_WFE             : Enter STOP mode with WFE instruction and
298                                                 clear of pending events before.
299           (+++) PWR_STOPENTRY_WFE_NO_EVT_CLEAR: Enter STOP mode with WFE instruction and
300                                                 no clear of pending event before.
301       (+) Exit:
302          Any EXTI Line (Internal or External) configured in Interrupt/Event mode.
303 
304    *** STANDBY mode ***
305    ====================
306     [..]
307     (+)
308       The system STANDBY mode allows to achieve the lowest power consumption.
309       It is based on the Cortex-M7 deep SLEEP mode, with the voltage regulator
310       disabled. The system is consequently powered off. The PLL, the HSI
311       oscillator and the HSE oscillator are also switched off. SRAM and register
312       contents are lost except for the RTC registers, RTC backup registers,
313       backup SRAM and standby circuitry.
314 
315     [..]
316       The voltage regulator is OFF.
317 
318       (++) Entry:
319         (+++) The STANDBY mode is entered using the HAL_PWR_EnterSTANDBYMode()
320               function.
321 
322       (++) Exit:
323         (+++) WKUP pin rising or falling edge, RTC alarm (Alarm A and Alarm B),
324               RTC wakeup, tamper event, time stamp event, external reset in NRST
325               pin, IWDG reset.
326 
327    *** Auto-wakeup (AWU) from low-power mode ***
328    =============================================
329     [..]
330      (+) The MCU can be woken up from low-power mode by an RTC Alarm event, an
331          RTC Wakeup event, a tamper event or a time-stamp event, without
332          depending on an external interrupt (Auto-wakeup mode).
333 
334      (+) RTC auto-wakeup (AWU) from the STOP and STANDBY modes
335 
336        (++) To wake up from the STOP mode with an RTC alarm event, it is
337             necessary to configure the RTC to generate the RTC alarm using the
338             HAL_RTC_SetAlarm_IT() function.
339 
340        (++) To wake up from the STOP mode with an RTC Tamper or time stamp event,
341             it is necessary to configure the RTC to detect the tamper or time
342             stamp event using the HAL_RTCEx_SetTimeStamp_IT() or
343             HAL_RTCEx_SetTamper_IT() functions.
344 
345        (++) To wake up from the STOP mode with an RTC WakeUp event, it is
346             necessary to configure the RTC to generate the RTC WakeUp event
347             using the HAL_RTCEx_SetWakeUpTimer_IT() function.
348 
349 @endverbatim
350   * @{
351   */
352 
353 /**
354   * @brief  Configure the voltage threshold detected by the Programmed Voltage
355   *         Detector (PVD).
356   * @param  sConfigPVD : Pointer to a PWR_PVDTypeDef structure that contains the
357   *                      PVD configuration information (PVDLevel and EventMode).
358   * @note   Refer to the electrical characteristics of your device datasheet for
359   *         more details about the voltage threshold corresponding to each
360   *         detection level.
361   * @note   As PVD and AVD share the same EXTI line, the EXTI operating mode to
362   *         configure will replace a possible previous configuration done through
363   *         HAL_PWREx_ConfigAVD.
364   * @retval None.
365   */
HAL_PWR_ConfigPVD(const PWR_PVDTypeDef * sConfigPVD)366 void HAL_PWR_ConfigPVD(const PWR_PVDTypeDef *sConfigPVD)
367 {
368   /* Check the PVD configuration parameter */
369   if (sConfigPVD == NULL)
370   {
371     return;
372   }
373 
374   /* Check the parameters */
375   assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel));
376   assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode));
377 
378   /* Set PLS[7:5] bits according to PVDLevel value */
379   MODIFY_REG(PWR->CR1, PWR_CR1_PLS, sConfigPVD->PVDLevel);
380 
381   /* Clear any previous config. Keep it clear if no event or IT mode is selected */
382   __HAL_PWR_PVD_EXTI_DISABLE_EVENT();
383   __HAL_PWR_PVD_EXTI_DISABLE_IT();
384   __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();
385   __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE();
386 
387   /* Configure the PVD in interrupt mode */
388   if ((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT)
389   {
390     __HAL_PWR_PVD_EXTI_ENABLE_IT();
391   }
392 
393   /* Configure the PVD in event mode */
394   if ((sConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT)
395   {
396     __HAL_PWR_PVD_EXTI_ENABLE_EVENT();
397   }
398 
399   /* Rising edge configuration */
400   if ((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE)
401   {
402     __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();
403   }
404 
405   /* Falling edge configuration */
406   if ((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE)
407   {
408     __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
409   }
410 }
411 
412 /**
413   * @brief  Enable the programmable voltage detector (PVD).
414   * @retval None.
415   */
HAL_PWR_EnablePVD(void)416 void HAL_PWR_EnablePVD(void)
417 {
418   SET_BIT(PWR->CR1, PWR_CR1_PVDE);
419 }
420 
421 /**
422   * @brief  Disable the programmable voltage detector (PVD).
423   * @retval None.
424   */
HAL_PWR_DisablePVD(void)425 void HAL_PWR_DisablePVD(void)
426 {
427   CLEAR_BIT(PWR->CR1, PWR_CR1_PVDE);
428 }
429 
430 /**
431   * @brief  Enable the WakeUp PINx functionality.
432   * @param  WakeUpPinPolarity : Specifies which Wake-Up pin to enable.
433   *          This parameter can be one of the following legacy values, which
434   *          sets the default (rising edge):
435   *            @arg PWR_WAKEUP_PIN1,
436   *                 PWR_WAKEUP_PIN2,
437   *                 PWR_WAKEUP_PIN3,
438   *                 PWR_WAKEUP_PIN4.
439   *          or one of the following values where the user can explicitly states
440   *          the enabled pin and the chosen polarity:
441   *            @arg PWR_WAKEUP_PIN1_HIGH, PWR_WAKEUP_PIN1_LOW,
442   *                 PWR_WAKEUP_PIN2_HIGH, PWR_WAKEUP_PIN2_LOW,
443   *                 PWR_WAKEUP_PIN3_HIGH, PWR_WAKEUP_PIN3_LOW,
444   *                 PWR_WAKEUP_PIN4_HIGH, PWR_WAKEUP_PIN4_LOW.
445   * @note   PWR_WAKEUP_PINx and PWR_WAKEUP_PINx_HIGH are equivalent.
446   * @retval None.
447   */
HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity)448 void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity)
449 {
450   /* Check the parameters */
451   assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinPolarity));
452 
453   /*
454      Enable and Specify the Wake-Up pin polarity and the pull configuration
455      for the event detection (rising or falling edge).
456   */
457   MODIFY_REG(PWR->WKUPEPR, PWR_WKUPEPR_WKUPEN | PWR_WKUPEPR_WKUPP, WakeUpPinPolarity);
458 }
459 
460 /**
461   * @brief  Disable the WakeUp PINx functionality.
462   * @param  WakeUpPinx : Specifies the Power Wake-Up pin to disable.
463   *          This parameter can be one of the following values:
464   *            @arg PWR_WAKEUP_PIN1,
465   *                 PWR_WAKEUP_PIN2,
466   *                 PWR_WAKEUP_PIN3,
467   *                 PWR_WAKEUP_PIN4,
468   *                 PWR_WAKEUP_PIN1_HIGH, PWR_WAKEUP_PIN1_LOW,
469   *                 PWR_WAKEUP_PIN2_HIGH, PWR_WAKEUP_PIN2_LOW,
470   *                 PWR_WAKEUP_PIN3_HIGH, PWR_WAKEUP_PIN3_LOW,
471   *                 PWR_WAKEUP_PIN4_HIGH, PWR_WAKEUP_PIN4_LOW.
472   * @retval None.
473   */
HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)474 void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
475 {
476   /* Check the parameters */
477   assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
478 
479   /* Disable the wake up pin selected */
480   CLEAR_BIT(PWR->WKUPEPR, (PWR_WKUPEPR_WKUPEN & WakeUpPinx));
481 }
482 
483 /**
484   * @brief  Enter the current core in SLEEP mode (CSLEEP).
485   * @param  Regulator : NA in this family project
486   *         Specifies the regulator state in SLEEP mode.
487   * @note   This parameter is not used for the STM32H7RS family and is kept as
488   *         parameter just to maintain compatibility with the lower power
489   *         families.
490   * @param  SLEEPEntry : Specifies if SLEEP mode is entered with WFI or WFE
491   *                      intrinsic instruction.
492   *          This parameter can be one of the following values:
493   *            @arg PWR_SLEEPENTRY_WFI              : Enter SLEEP mode with WFI instruction.
494   *            @arg PWR_SLEEPENTRY_WFE              : Enter SLEEP mode with WFE instruction and
495   *                                                   clear of pending events before.
496   *            @arg PWR_SLEEPENTRY_WFE_NO_EVT_CLEAR : Enter SLEEP mode with WFE instruction and
497   *                                                   no clear of pending event before.
498   * @retval None.
499   */
HAL_PWR_EnterSLEEPMode(uint32_t Regulator,uint8_t SLEEPEntry)500 void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
501 {
502   /* Prevent unused argument(s) compilation warning */
503   UNUSED(Regulator);
504 
505   /* Check the parameters */
506   assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry));
507 
508   /* Clear SLEEPDEEP bit of Cortex System Control Register */
509   CLEAR_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk);
510 
511   /* Select Sleep mode entry */
512   if (SLEEPEntry == PWR_SLEEPENTRY_WFI)
513   {
514     /* Request Wait For Interrupt */
515     __WFI();
516   }
517   else
518   {
519     if (SLEEPEntry != PWR_SLEEPENTRY_WFE_NO_EVT_CLEAR)
520     {
521       /* Clear all pending event */
522       __SEV();
523       __WFE();
524     }
525 
526     /* Request Wait For Event */
527     __WFE();
528   }
529 }
530 
531 /**
532   * @brief  Enter the whole system to Stop mode.
533   * @note   This API will enter the system in STOP mode
534   * @param  Regulator : This parameter is not used for this product family.
535             and is kept as parameter just to maintain compatibility with the
536             lower power families.
537   * @param  STOPEntry : Specifies if STOP mode in entered with WFI or WFE
538   *                     intrinsic instruction.
539   *          This parameter can be one of the following values:
540   *            @arg PWR_STOPENTRY_WFI              : Enter STOP mode with WFI instruction.
541   *            @arg PWR_STOPENTRY_WFE              : Enter STOP mode with WFE instruction and
542   *                                                  clear of pending events before.
543   *            @arg PWR_STOPENTRY_WFE_NO_EVT_CLEAR : Enter STOP mode with WFE instruction and
544   *                                                  no clear of pending event before.
545   * @note   In System STOP mode, all I/O pins keep the same state as in Run mode.
546   * @note   When exiting System STOP mode by issuing an interrupt or a wakeup
547   *         event, the HSI RC oscillator is selected as default system wakeup
548   *         clock.
549   * @note   In System STOP mode, when the voltage regulator operates in low
550   *         power mode, an additional startup delay is incurred when the system
551   *         is waking up. By keeping the internal regulator ON during STOP mode,
552   *         the consumption is higher although the startup time is reduced.
553   * @retval None.
554   */
HAL_PWR_EnterSTOPMode(uint32_t Regulator,uint8_t STOPEntry)555 void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
556 {
557 
558   /* Prevent unused argument(s) compilation warning */
559   UNUSED(Regulator);
560 
561   /* Check the parameters */
562   assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
563 
564   /* Select Stop mode when device enters Deepsleep */
565   CLEAR_BIT(PWR->CSR3, PWR_CSR3_PDDS);
566 
567   /* Set SLEEPDEEP bit of Cortex System Control Register */
568   SET_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk);
569 
570   /* Ensure that all instructions are done before entering STOP mode */
571   __DSB();
572   __ISB();
573 
574   /* Select Stop mode entry */
575   if (STOPEntry == PWR_STOPENTRY_WFI)
576   {
577     /* Request Wait For Interrupt */
578     __WFI();
579   }
580   else
581   {
582     if (STOPEntry != PWR_STOPENTRY_WFE_NO_EVT_CLEAR)
583     {
584       /* Clear all pending event */
585       __SEV();
586       __WFE();
587     }
588     /* Request Wait For Event */
589     __WFE();
590   }
591 
592   /* Clear SLEEPDEEP bit of Cortex-M7 in the System Control Register */
593   CLEAR_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk);
594 }
595 
596 /**
597   * @brief  Enter the whole system to Standby mode.
598   * @note   The Standby mode allows achieving the lowest power consumption.
599   * @note   When the system enters in Standby mode, the voltage regulator is disabled.
600   *         The complete VCORE domain is consequently powered off.
601   *         The PLLs, HSI oscillator, CSI oscillator, HSI48 and the HSE oscillator are
602   *         also switched off.
603   *         SRAM and register contents are lost except for backup domain registers
604   *         (RTC registers, RTC backup register and backup RAM), and Standby circuitry.
605   * @note   When the System exit STANDBY mode by issuing an interrupt or a
606   *         wakeup event, the HSI RC oscillator is selected as system clock.
607   * @retval None.
608   */
HAL_PWR_EnterSTANDBYMode(void)609 void HAL_PWR_EnterSTANDBYMode(void)
610 {
611   /* Select Standby when device enters Deepsleep */
612   SET_BIT(PWR->CSR3, PWR_CSR3_PDDS);
613 
614   /* Set SLEEPDEEP bit of Cortex System Control Register */
615   SET_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk);
616 
617   /* Ensure that all instructions are done before entering STANDBY mode */
618   __DSB();
619   __ISB();
620 
621   /* Request Wait For Interrupt */
622   __WFI();
623 }
624 
625 /**
626   * @brief  Indicate SLEEP-ON-EXIT feature when returning from handler mode to
627   *         thread mode.
628   * @note   Set SLEEPONEXIT bit of SCR register. When this bit is set, the
629   *         processor re-enters Sleep mode when an interruption handling is over.
630   *         Setting this bit is useful when the processor is expected to run
631   *         only on interruptions handling.
632   * @retval None.
633   */
HAL_PWR_EnableSleepOnExit(void)634 void HAL_PWR_EnableSleepOnExit(void)
635 {
636   /* Set SLEEPONEXIT bit of Cortex-M7 System Control Register */
637   SET_BIT(SCB->SCR, SCB_SCR_SLEEPONEXIT_Msk);
638 }
639 
640 /**
641   * @brief  Disable SLEEP-ON-EXIT feature when returning from handler mode to
642   *         thread mode.
643   * @note   Clears SLEEPONEXIT bit of SCR register. When this bit is set, the
644   *         processor re-enters Sleep mode when an interruption handling is over.
645   * @retval None.
646   */
HAL_PWR_DisableSleepOnExit(void)647 void HAL_PWR_DisableSleepOnExit(void)
648 {
649   /* Clear SLEEPONEXIT bit of Cortex-M7 System Control Register */
650   CLEAR_BIT(SCB->SCR, SCB_SCR_SLEEPONEXIT_Msk);
651 }
652 
653 /**
654   * @brief  Enable CORTEX SEV-ON-PEND feature.
655   * @note   Sets SEVONPEND bit of SCR register. When this bit is set, any
656   *         pending event / interrupt even if it's disabled or has insufficient
657   *         priority to cause exception entry wakes up the Cortex-M7.
658   * @retval None.
659   */
HAL_PWR_EnableSEVOnPend(void)660 void HAL_PWR_EnableSEVOnPend(void)
661 {
662   /* Set SEVONPEND bit of Cortex-M7 System Control Register */
663   SET_BIT(SCB->SCR, SCB_SCR_SEVONPEND_Msk);
664 }
665 
666 /**
667   * @brief  Disable CORTEX SEVONPEND feature.
668   * @note   Resets SEVONPEND bit of SCR register. When this bit is reset, only
669   *         enabled pending causes exception entry wakes up the Cortex-M7.
670   * @retval None.
671   */
HAL_PWR_DisableSEVOnPend(void)672 void HAL_PWR_DisableSEVOnPend(void)
673 {
674   /* Clear SEVONPEND bit of Cortex-M7 System Control Register */
675   CLEAR_BIT(SCB->SCR, SCB_SCR_SEVONPEND_Msk);
676 }
677 /**
678   * @}
679   */
680 
681 /**
682   * @}
683   */
684 #endif /* HAL_PWR_MODULE_ENABLED */
685 /**
686   * @}
687   */
688 
689 /**
690   * @}
691   */
692