1 /**
2   ******************************************************************************
3   * @file    stm32mp1xx_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 and de-initialization functions
9   *           + Peripheral Control functions
10   *
11   ******************************************************************************
12   * @attention
13   *
14   * Copyright (c) 2019 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   */
23 
24 /* Includes ------------------------------------------------------------------*/
25 #include "stm32mp1xx_hal.h"
26 
27 
28 
29 /** @addtogroup STM32MP1xx_HAL_Driver
30   * @{
31   */
32 
33 /** @defgroup PWR PWR
34   * @brief PWR HAL module driver
35   * @{
36   */
37 
38 #ifdef HAL_PWR_MODULE_ENABLED
39 
40 /* Private typedef -----------------------------------------------------------*/
41 /* Private define ------------------------------------------------------------*/
42 /** @addtogroup PWR_Private_Constants PWR Private Constants
43   * @{
44   */
45 
46 /** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask
47   * @{
48   */
49 #define PVD_MODE_IT              ((uint32_t)0x00010000U)
50 #define PVD_RISING_EDGE          ((uint32_t)0x00000001U)
51 #define PVD_FALLING_EDGE         ((uint32_t)0x00000002U)
52 #define PVD_RISING_FALLING_EDGE  ((uint32_t)0x00000003U)
53 /**
54   * @}
55   */
56 
57 /**
58   * @}
59   */
60 
61 /* Private macro -------------------------------------------------------------*/
62 /* Private variables ---------------------------------------------------------*/
63 /* Private function prototypes -----------------------------------------------*/
64 /* Private functions ---------------------------------------------------------*/
65 
66 /** @defgroup PWR_Private_Functions PWR Private Functions
67   * @{
68   */
69 
70 /** @defgroup PWR_Group1 Initialization and de-initialization functions
71   *  @brief    Initialization and de-initialization functions
72   *
73 @verbatim
74  ===============================================================================
75               ##### Initialization and de-initialization functions #####
76  ===============================================================================
77     [..]
78       After reset, the backup domain (RTC registers, RTC backup data
79       registers and backup SRAM) is protected against possible unwanted
80       write accesses.
81       To enable access to the RTC Domain and RTC registers, proceed as follows:
82         (+) Enable access to RTC domain using the HAL_PWR_EnableBkUpAccess()
83             function.
84 
85 @endverbatim
86   * @{
87   */
88 
89 
90 /**
91   * @brief  Enables access to the backup domain
92   *         In reset state, the RCC_BDCR, PWR_CR2, RTC, and backup registers are
93   *         protected against parasitic write access. DBP bit must be set to
94   *         enable write access to these.
95   * @note   If the HSE divided by 2, 3, ..31 is used as the RTC clock, the
96   *         Backup Domain Access should be kept enabled.
97   * @retval None
98   */
HAL_PWR_EnableBkUpAccess(void)99 void HAL_PWR_EnableBkUpAccess(void)
100 {
101   /* Enable access to RTC and backup registers */
102   SET_BIT(PWR->CR1, PWR_CR1_DBP);
103 }
104 
105 /**
106   * @brief Disables access to the backup domain (RTC registers, RTC
107   *         backup data registers and backup SRAM).
108   * @note If the HSE divided by 2, 3, ..31 is used as the RTC clock, the
109   *         Backup Domain Access should be kept enabled.
110   * @retval None
111   */
HAL_PWR_DisableBkUpAccess(void)112 void HAL_PWR_DisableBkUpAccess(void)
113 {
114   /* Disable access to RTC and backup registers */
115   CLEAR_BIT(PWR->CR1, PWR_CR1_DBP);
116 }
117 
118 /**
119   * @}
120   */
121 
122 /** @defgroup PWR_Group2 Peripheral Control functions
123   *  @brief Low Power modes configuration functions
124   *
125 @verbatim
126 
127  ===============================================================================
128                  ##### Peripheral Control functions #####
129  ===============================================================================
130 
131     *** PVD configuration ***
132     =========================
133     [..]
134       (+) The PVD is used to monitor the VDD power supply by comparing it to a
135           threshold selected by the PVD Level (PLS[2:0] bits in the PWR_CR1).
136       (+) The PVD can also be used to monitor a voltage level on the PVD_IN pin.
137           In this case, the voltage level on PVD_IN is compared to the internal
138           VREFINT level.
139       (+) A PVDO flag is available, in the PWR control status register 1
140           (PWR_CSR1), to indicate whether VDD or voltage level on PVD_IN is
141           higher or lower than the PVD threshold. This event is internally
142           connected to the EXTI line16 and can generate an interrupt if enabled.
143           This is done through __HAL_PWR_PVD_AVD_EXTI_ENABLE_IT() macro.
144       (+) The PVD is stopped in Standby mode.
145 
146     *** WakeUp pins configuration ***
147     ================================
148     [..]
149       (+) WakeUp pins are used to wake up the system from Standby mode. WKUP
150           pins, if enabled, the WKUP pin pulls can be configured by WKUPPUPD
151           register bits in PWR wakeup control register (PWR_WKUPCR).
152 
153     *** Low Power modes configuration ***
154     =====================================
155     [..]
156       Several Low-power modes are available to save power when the MPU and/or
157       MCU do not need to execute code (i.e. when waiting for an external event).
158       Please refer to Reference Manual for more information.
159       MPU and MCU sub-system modes:
160       (+) CSleep mode: MPU/MCU clocks stopped and the MPU/MCU sub-system allocated
161                        peripheral(s) clocks operate according to RCC PERxLPEN
162       (+) CStop mode: MPU/MCU and MPU/MCU sub-system peripheral(s) clock stopped
163       (+) CStandby mode: MPU and MPU sub-system peripheral(s) clock stopped and
164                          wakeup via reset
165       System modes:
166       (+) Stop mode: bus matrix clocks stalled, the oscillators can be stopped.
167                      VDDCORE is supplied.
168                      To enter into this mode:
169                      - Both MPU and MCU sub-systems are in CStop or CStandby.
170                      - At least one PDDS bit (PWR_MPUCR/PWR_MCUCR) selects Stop.
171       (+) LP-Stop mode: bus matrix clocks stalled, the oscillators can be stopped.
172                         VDDCORE is supplied.
173                         To enter into this mode:
174                         - Both MPU and MCU sub-systems are in CStop or CStandby.
175                         - The LPDS bit (PWR_CR1) selects LP-Stop.
176                         - The LVDS bit (PWR_CR1) selects normal voltage.
177                         - At least one PDDS bit (PWR_MPUCR/PWR_MCUCR) selects Stop.
178       (+) LPLV-Stop mode: bus matrix clocks stalled, the oscillators can be stopped.
179                           VDDCORE may be supplied at a lower level.
180                           To enter into this mode:
181                           - Both MPU and MCU sub-systems are in CStop or CStandby.
182                           - The LPDS and LVDS bits (PWR_CR1) select LPLV-Stop.
183                           - At least one PDDS bit (PWR_MPUCR/PWR_MCUCR) selects Stop.
184       (+) Standby mode: System powered down.
185                         To enter into this mode:
186                         - MPU sub-system is in CStandby or CStop with CSTBYDIS = 1
187                           and MCU subsystem is in CStop.
188                         - All PDDS bits (PWR_MPUCR/PWR_MCUCR) select Standby.
189 
190    *** CSleep mode ***
191    ==================
192     [..]
193       (+) Entry:
194         The CSleep mode is entered by using the HAL_PWR_EnterSLEEPMode(Regulator, SLEEPEntry)
195         functions with:
196         (++) STOPEntry:
197           (++) PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
198           (++) PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
199 
200       -@@- The Regulator parameter is not used for the STM32MP1 family
201            and is kept as parameter just to maintain compatibility with the
202            lower power families (STM32L). Use i.e. PWR_MAINREGULATOR_ON
203       (+) Exit:
204           MCU: Any peripheral interrupt acknowledged by the nested vectored interrupt
205           controller (NVIC) if entered by WFI or any event if entered by WFE
206           MPU: Any Interrupt enabled in GIC if entered by WFI or any event if
207           entered by WFE
208 
209 
210    *** CStop mode ***
211    =================
212     [..]
213       (+) Entry:
214          The CStop mode is entered using the HAL_PWR_EnterSTOP(ModeRegulator, STOPEntry)
215          function with:
216          (++) Regulator:
217           (+++) PWR_MAINREGULATOR_ON: Main regulator ON.
218           (+++) PWR_LOWPOWERREGULATOR_ON: Low Power regulator ON.
219          (++) STOPEntry:
220           (+++) PWR_STOPENTRY_WFI: enter STOP mode with WFI instruction
221           (+++) PWR_STOPENTRY_WFE: enter STOP mode with WFE instruction
222       (+) Exit:
223           MCU: Any EXTI Line (Internal or External) configured in Interrupt/Event mode
224           depending of entry mode.
225           MPU: Any EXTI Line (Internal or External) configured in Interrupt mode
226 
227    *** MPU CStandby mode / MCU CStop allowing Standby mode ***
228    ====================
229     [..]
230     (+)
231       The Standby mode allows to achieve the lowest power consumption. On Standby
232       mode the voltage regulator is disabled. The PLLs, the HSI oscillator and
233       the HSE oscillator are also switched off. SRAM and register contents are
234       lost except for the RTC registers, RTC backup registers, backup SRAM and
235       Standby circuitry.
236 
237       (++) Entry:
238         (+++) The MPU CStandby mode / MCU CStop allowing Standby mode is entered
239               using the HAL_PWR_EnterSTANDBYMode() function.
240       (++) Exit:
241            Any EXTI Line (Internal or External) configured in Interrupt mode
242            if system is not in Standby mode
243         (+++) If system is in Standby mode wake up is generated by reset through:
244               WKUP pins, RTC alarm (Alarm A and Alarm B), RTC wakeup, tamper
245               event, time-stamp event, external reset in NRST pin, IWDG reset.
246 
247 @endverbatim
248   * @{
249   */
250 
251 /**
252   * @brief  Configures the voltage threshold detected by the Power Voltage Detector(PVD).
253   * @param  sConfigPVD: pointer to an PWR_PVDTypeDef structure that contains the configuration
254   *         information for the PVD.
255   * @note   Refer to the electrical characteristics of your device datasheet for
256   *         more details about the voltage threshold corresponding to each
257   *         detection level.
258   * @retval None
259   */
HAL_PWR_ConfigPVD(PWR_PVDTypeDef * sConfigPVD)260 void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD)
261 {
262   /* Check the parameters */
263   assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel));
264   assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode));
265 
266   /* Set PLS[7:5] bits according to PVDLevel value */
267   MODIFY_REG(PWR->CR1, PWR_CR1_PLS, sConfigPVD->PVDLevel);
268 
269   /* Clear any previous config. Keep it clear if no IT mode is selected */
270   __HAL_PWR_PVD_AVD_EXTI_DISABLE_IT();
271   __HAL_PWR_PVD_AVD_EXTI_DISABLE_RISING_FALLING_EDGE();
272 
273   /* Configure interrupt mode */
274   if ((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT)
275   {
276     __HAL_PWR_PVD_AVD_EXTI_ENABLE_IT();
277   }
278 
279   /* Configure the edge */
280   if ((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE)
281   {
282     __HAL_PWR_PVD_AVD_EXTI_ENABLE_RISING_EDGE();
283   }
284 
285   if ((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE)
286   {
287     __HAL_PWR_PVD_AVD_EXTI_ENABLE_FALLING_EDGE();
288   }
289 }
290 
291 /**
292   * @brief Enables the Power Voltage Detector(PVD).
293   * @retval None
294   */
HAL_PWR_EnablePVD(void)295 void HAL_PWR_EnablePVD(void)
296 {
297   /* Enable the power voltage detector */
298   SET_BIT(PWR->CR1, PWR_CR1_PVDEN);
299 }
300 
301 /**
302   * @brief Disables the Power Voltage Detector(PVD).
303   * @retval None
304   */
HAL_PWR_DisablePVD(void)305 void HAL_PWR_DisablePVD(void)
306 {
307   /* Disable the power voltage detector */
308   CLEAR_BIT(PWR->CR1, PWR_CR1_PVDEN);
309 }
310 
311 /**
312   * @brief Enable the WakeUp PINx functionality.
313   * @param WakeUpPinPolarity: Specifies which Wake-Up pin to enable.
314   *         This parameter can be one of the following legacy values, which sets the default polarity:
315   *         detection on high level (rising edge):
316   *           @arg PWR_WAKEUP_PIN1, PWR_WAKEUP_PIN2, PWR_WAKEUP_PIN3, PWR_WAKEUP_PIN4, PWR_WAKEUP_PIN5, PWR_WAKEUP_PIN6
317   *                or one of the following value where the user can explicitly states the enabled pin and
318   *                the chosen polarity
319   *           @arg PWR_WAKEUP_PIN1_HIGH or PWR_WAKEUP_PIN1_LOW or
320   *           @arg PWR_WAKEUP_PIN2_HIGH or PWR_WAKEUP_PIN2_LOW
321   *           @arg PWR_WAKEUP_PIN3_HIGH or PWR_WAKEUP_PIN3_LOW
322   *           @arg PWR_WAKEUP_PIN4_HIGH or PWR_WAKEUP_PIN4_LOW
323   *           @arg PWR_WAKEUP_PIN5_HIGH or PWR_WAKEUP_PIN5_LOW
324   *           @arg PWR_WAKEUP_PIN6_HIGH or PWR_WAKEUP_PIN6_LOW
325   * @note  PWR_WAKEUP_PINx and PWR_WAKEUP_PINx_HIGH are equivalent.
326   *
327   * @note  GPIOs are set as next when WKUP pin is enabled (Additional function)
328   *         WKUP1 :  PA0
329   *         WKUP2 :  PA2
330   *         WKUP3 :  PC13
331   *         WKUP4 :  PI8
332   *         WKUP5 :  PI11
333   *         WKUP6 :  PC1
334   * @retval None
335   */
HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity)336 void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity)
337 {
338   uint32_t clear_mask = 0;
339 
340   assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinPolarity));
341 
342   if ((WakeUpPinPolarity & PWR_WAKEUP_PIN1) == PWR_WAKEUP_PIN1)
343   {
344     clear_mask  |= (PWR_WKUPCR_WKUPP_1 | PWR_WKUPCR_WKUPPUPD1);
345   }
346   if ((WakeUpPinPolarity & PWR_WAKEUP_PIN2) == PWR_WAKEUP_PIN2)
347   {
348     clear_mask  |= (PWR_WKUPCR_WKUPP_2 | PWR_WKUPCR_WKUPPUPD2);
349   }
350   if ((WakeUpPinPolarity & PWR_WAKEUP_PIN3) == PWR_WAKEUP_PIN3)
351   {
352     clear_mask  |= (PWR_WKUPCR_WKUPP_3 | PWR_WKUPCR_WKUPPUPD3);
353   }
354   if ((WakeUpPinPolarity & PWR_WAKEUP_PIN4) == PWR_WAKEUP_PIN4)
355   {
356     clear_mask  |= (PWR_WKUPCR_WKUPP_4 | PWR_WKUPCR_WKUPPUPD4);
357   }
358   if ((WakeUpPinPolarity & PWR_WAKEUP_PIN5) == PWR_WAKEUP_PIN5)
359   {
360     clear_mask  |= (PWR_WKUPCR_WKUPP_5 | PWR_WKUPCR_WKUPPUPD5);
361   }
362   if ((WakeUpPinPolarity & PWR_WAKEUP_PIN6) == PWR_WAKEUP_PIN6)
363   {
364     clear_mask  |= (PWR_WKUPCR_WKUPP_6 | PWR_WKUPCR_WKUPPUPD6);
365   }
366 
367   /* Enables and Specifies the Wake-Up pin polarity and the pull configuration
368      for the event detection (rising or falling edge) */
369 #ifdef CORE_CA7
370   CLEAR_BIT(PWR->MPUWKUPENR, (WakeUpPinPolarity & PWR_WAKEUP_PIN_MASK)); /* Disable WKUP pin */
371   MODIFY_REG(PWR->WKUPCR, clear_mask,
372              (WakeUpPinPolarity & (PWR_WKUPCR_WKUPP | PWR_WKUPCR_WKUPPUPD))); /* Modify polarity and pull configuration */
373   SET_BIT(PWR->WKUPCR, (WakeUpPinPolarity & PWR_WKUPCR_WKUPC)); /* Clear wake up flag */
374   SET_BIT(PWR->MPUWKUPENR, (WakeUpPinPolarity & PWR_WAKEUP_PIN_MASK)); /* Enable the Wake up pin for CPU1 */
375 #endif
376 #ifdef CORE_CM4
377   CLEAR_BIT(PWR->MCUWKUPENR, (WakeUpPinPolarity & PWR_WAKEUP_PIN_MASK)); /* Disable WKUP pin */
378   MODIFY_REG(PWR->WKUPCR, clear_mask,
379              (WakeUpPinPolarity & (PWR_WKUPCR_WKUPP | PWR_WKUPCR_WKUPPUPD))); /* Modify polarity and pull configuration */
380   SET_BIT(PWR->WKUPCR, (WakeUpPinPolarity & PWR_WKUPCR_WKUPC)); /* Clear wake up flag */
381   SET_BIT(PWR->MCUWKUPENR, (WakeUpPinPolarity & PWR_WAKEUP_PIN_MASK)); /* Enable the Wake up pin for CPU2 */
382 #endif
383 }
384 
385 
386 /**
387   * @brief Disables the WakeUp PINx functionality.
388   * @param WakeUpPinx: Specifies the Power Wake-Up pin to disable.
389   *         This parameter can be one of the following values:
390   *           @arg PWR_WAKEUP_PIN1
391   *           @arg PWR_WAKEUP_PIN2
392   *           @arg PWR_WAKEUP_PIN3
393   *           @arg PWR_WAKEUP_PIN4
394   *           @arg PWR_WAKEUP_PIN5
395   *           @arg PWR_WAKEUP_PIN6
396   * @retval None
397   */
HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)398 void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
399 {
400   assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
401 #ifdef CORE_CA7
402   CLEAR_BIT(PWR->MPUWKUPENR, (WakeUpPinx & PWR_WAKEUP_PIN_MASK));
403 #endif
404 #ifdef CORE_CM4
405   CLEAR_BIT(PWR->MCUWKUPENR, (WakeUpPinx & PWR_WAKEUP_PIN_MASK));
406 #endif
407 }
408 
409 
410 /**
411   * @brief Enable WakeUp PINx Interrupt on AIEC and NVIC.
412   * @param WakeUpPinx: Specifies the Power Wake-Up pin
413   *         This parameter can be one of the following values:
414   *           @arg PWR_WAKEUP_PIN1
415   *           @arg PWR_WAKEUP_PIN2
416   *           @arg PWR_WAKEUP_PIN3
417   *           @arg PWR_WAKEUP_PIN4
418   *           @arg PWR_WAKEUP_PIN5
419   *           @arg PWR_WAKEUP_PIN6
420   * @retval None
421   */
HAL_PWR_EnableWakeUpPinIT(uint32_t WakeUpPinx)422 void HAL_PWR_EnableWakeUpPinIT(uint32_t WakeUpPinx)
423 {
424   assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
425   switch ((WakeUpPinx & PWR_WAKEUP_PIN_MASK))
426   {
427     case PWR_WAKEUP_PIN1:
428       __HAL_WKUP_EXTI_ENABLE_IT(EXTI_IMR2_IM55);
429       break;
430 
431     case PWR_WAKEUP_PIN2:
432       __HAL_WKUP_EXTI_ENABLE_IT(EXTI_IMR2_IM56);
433       break;
434 
435     case PWR_WAKEUP_PIN3:
436       __HAL_WKUP_EXTI_ENABLE_IT(EXTI_IMR2_IM57);
437       break;
438 
439     case PWR_WAKEUP_PIN4:
440       __HAL_WKUP_EXTI_ENABLE_IT(EXTI_IMR2_IM58);
441       break;
442 
443     case PWR_WAKEUP_PIN5:
444       __HAL_WKUP_EXTI_ENABLE_IT(EXTI_IMR2_IM59);
445       break;
446 
447     case PWR_WAKEUP_PIN6:
448       __HAL_WKUP_EXTI_ENABLE_IT(EXTI_IMR2_IM60);
449       break;
450   }
451 }
452 
453 
454 /**
455   * @brief Disable WakeUp PINx Interrupt on AIEC and NVIC.
456   * @param WakeUpPinx: Specifies the Power Wake-Up pin
457   *         This parameter can be one of the following values:
458   *           @arg PWR_WAKEUP_PIN1
459   *           @arg PWR_WAKEUP_PIN2
460   *           @arg PWR_WAKEUP_PIN3
461   *           @arg PWR_WAKEUP_PIN4
462   *           @arg PWR_WAKEUP_PIN5
463   *           @arg PWR_WAKEUP_PIN6
464   * @retval None
465   */
HAL_PWR_DisableWakeUpPinIT(uint32_t WakeUpPinx)466 void HAL_PWR_DisableWakeUpPinIT(uint32_t WakeUpPinx)
467 {
468   assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
469   switch ((WakeUpPinx & PWR_WAKEUP_PIN_MASK))
470   {
471     case PWR_WAKEUP_PIN1:
472       __HAL_WKUP_EXTI_DISABLE_IT(EXTI_IMR2_IM55);
473       break;
474 
475     case PWR_WAKEUP_PIN2:
476       __HAL_WKUP_EXTI_DISABLE_IT(EXTI_IMR2_IM56);
477       break;
478 
479     case PWR_WAKEUP_PIN3:
480       __HAL_WKUP_EXTI_DISABLE_IT(EXTI_IMR2_IM57);
481       break;
482 
483     case PWR_WAKEUP_PIN4:
484       __HAL_WKUP_EXTI_DISABLE_IT(EXTI_IMR2_IM58);
485       break;
486 
487     case PWR_WAKEUP_PIN5:
488       __HAL_WKUP_EXTI_DISABLE_IT(EXTI_IMR2_IM59);
489       break;
490 
491     case PWR_WAKEUP_PIN6:
492       __HAL_WKUP_EXTI_DISABLE_IT(EXTI_IMR2_IM60);
493       break;
494   }
495 }
496 
497 /**
498   * @brief Enters CSleep mode.
499   *
500   * @note In CSleep mode, all I/O pins keep the same state as in Run mode.
501   *
502   * @note In CSleep mode, the systick is stopped to avoid exit from this mode with
503   *       systick interrupt when used as time base for Timeout
504   *
505   * @param Regulator: Specifies the regulator state in CSLEEP mode.
506   *          This parameter is not used for the STM32MP1 family and is kept as
507   *          parameter just to maintain compatibility with the lower power families
508   *            This parameter can be one of the following values:
509   *            @arg PWR_MAINREGULATOR_ON: CSLEEP mode with regulator ON
510   *            @arg PWR_LOWPOWERREGULATOR_ON: CSLEEP mode with low power regulator ON
511   * @param SLEEPEntry: Specifies if CSLEEP mode in entered with WFI or WFE instruction.
512   *          This parameter can be one of the following values:
513   *            @arg PWR_SLEEPENTRY_WFI: enter CSLEEP mode with WFI instruction
514   *            @arg PWR_SLEEPENTRY_WFE: enter CSLEEP mode with WFE instruction
515   * @retval None
516   */
HAL_PWR_EnterSLEEPMode(uint32_t Regulator,uint8_t SLEEPEntry)517 void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
518 {
519   /* Check the parameters */
520   assert_param(IS_PWR_REGULATOR(Regulator));
521   assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry));
522 
523 #ifdef CORE_CM4
524   /* Ensure CM4 do not enter to CSTOP mode */
525   /* Clear SLEEPDEEP bit of Cortex System Control Register */
526   CLEAR_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk);
527 #endif
528 
529   /* Select SLEEP mode entry -------------------------------------------------*/
530   if (SLEEPEntry == PWR_SLEEPENTRY_WFI)
531   {
532     /* Request Wait For Interrupt */
533     __WFI();
534   }
535   else
536   {
537     /* Request Wait For Event */
538     __SEV();
539     __WFE();
540     __WFE();
541   }
542 }
543 
544 
545 /**
546   * @brief Enters CSTOP
547   *        This function puts core domain into CSTOP allowing system STOP mode
548   *        if both MPU and MCU cores are on CSTOP mode
549   * @note In Stop mode, all I/O pins keep the same state as in Run mode.
550   * @note When exiting Stop mode by issuing an interrupt or a wake up event,
551   *       the HSI oscillator is selected as CM4 system clock.
552   * @note RCC_WAKEUP_IRQn IT must be programmed to have the highest priority and
553   *       to be the only one IT having this value before calling HAL_PWR_EnterSTOPMode.
554   *       Make sure RCC_WAKEUP_IRQn is the only one IT allowed to wake up core
555   *       before calling  HAL_PWR_EnterSTOPMode (BASEPRI)
556   *       Reestablish priority level once system is completely waken up (clock
557   *       restore and IO compensation)
558   * @note When the voltage regulator operates in low power mode, an additional
559   *         startup delay is incurred when waking up from Stop mode.
560   *         By keeping the internal regulator ON during Stop mode, the consumption
561   *         is higher although the startup time is reduced.
562   * @param Regulator: Specifies the regulator state in Stop mode.
563   *          This parameter is unused on MCU but any value must be provided.
564   *          This parameter can be one of the following values:
565   *            @arg PWR_MAINREGULATOR_ON: Stop mode with regulator ON
566   *            @arg PWR_LOWPOWERREGULATOR_ON: Stop mode with low power regulator ON
567   * @param STOPEntry: Specifies if CStop mode is entered with WFI or WFE instruction.
568   *          This parameter can be one of the following values:
569   *            @arg PWR_STOPENTRY_WFI: Enter CStop mode with WFI instruction
570   *            @arg PWR_STOPENTRY_WFE: Enter CStop mode with WFE instruction
571   * @retval None
572   */
HAL_PWR_EnterSTOPMode(uint32_t Regulator,uint8_t STOPEntry)573 void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
574 {
575   /* Check the parameters */
576   assert_param(IS_PWR_REGULATOR(Regulator));
577   assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
578 
579 #ifdef CORE_CM4
580   /*Forbid going to STANDBY mode (select STOP mode) */
581   CLEAR_BIT(PWR->MCUCR, PWR_MCUCR_PDDS);
582 
583   /*Allow CORE_CM4 to enter CSTOP mode
584   Set SLEEPDEEP bit of Cortex System Control Register */
585   SET_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk);
586 #endif/* CORE_CM4 */
587 
588 #ifdef CORE_CA7
589   if (Regulator == PWR_MAINREGULATOR_ON)
590   {
591     /* Select STOP mode */
592     CLEAR_BIT(PWR->CR1, PWR_CR1_LPDS);
593   }
594   else
595   {
596     /* Select LP-STOP mode */
597     SET_BIT(PWR->CR1, PWR_CR1_LPDS);
598   }
599 
600   /* Clear MPU STANDBY, STOP and HOLD flags.(Always read as 0) */
601   SET_BIT(PWR->MPUCR, PWR_MPUCR_CSSF);
602 
603   /* MPU STAY in STOP MODE */
604   CLEAR_BIT(PWR->MPUCR, PWR_MPUCR_PDDS);
605 
606   /* MPU CSTANDBY mode disabled */
607   SET_BIT(PWR->MPUCR, PWR_MPUCR_CSTBYDIS);
608 
609   /* RCC Stop Request Set Register */
610 #if defined(RCC_MP_SREQSETR_STPREQ_P0) & defined(RCC_MP_SREQSETR_STPREQ_P1)
611   /* CA7_CORE0 and CA7_CORE1 available */
612   RCC->MP_SREQSETR = RCC_MP_SREQSETR_STPREQ_P0 | RCC_MP_SREQSETR_STPREQ_P1;
613 #else
614   /* Only CA7_CORE0 available */
615   RCC->MP_SREQSETR = RCC_MP_SREQSETR_STPREQ_P0;
616 #endif /* RCC_MP_SREQSETR_STPREQ_P0 & RCC_MP_SREQSETR_STPREQ_P1 */
617 
618 #else
619   /* Prevent unused argument compilation warning */
620   UNUSED(Regulator);
621 #endif /*CORE_CA7*/
622 
623   /* Select Stop mode entry --------------------------------------------------*/
624   if ((STOPEntry == PWR_STOPENTRY_WFI))
625   {
626     /* Request Wait For Interrupt */
627     __WFI();
628   }
629   else if (STOPEntry == PWR_STOPENTRY_WFE)
630   {
631     /* Request Wait For Event */
632     __SEV();
633     __WFE();
634     __WFE();
635   }
636 
637 #ifdef CORE_CM4
638   /* Reset SLEEPDEEP bit of Cortex System Control Register */
639   SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
640 #endif/* CORE_CM4 */
641 
642 #ifdef CORE_CA7
643   /* RCC Clear Request Set Register */
644 #if defined(RCC_MP_SREQCLRR_STPREQ_P0) & defined(RCC_MP_SREQCLRR_STPREQ_P1)
645   /* CA7_CORE0 and CA7_CORE1 available */
646   RCC->MP_SREQCLRR = RCC_MP_SREQCLRR_STPREQ_P0 | RCC_MP_SREQCLRR_STPREQ_P1;
647 #else
648   /* Only CA7_CORE0 available */
649   RCC->MP_SREQCLRR = RCC_MP_SREQCLRR_STPREQ_P0;
650 #endif /* RCC_MP_SREQCLRR_STPREQ_P0 | RCC_MP_SREQCLRR_STPREQ_P1 */
651 #endif
652 }
653 
654 
655 /**
656   * @brief Enters MPU CStandby / MCU CSTOP allowing system Standby mode.
657   * @note In Standby mode, all I/O pins are high impedance except for:
658   *          - Reset pad (still available)
659   *          - RTC_AF1 pin (PC13) if configured for tamper, time-stamp, RTC
660   *            Alarm out, or RTC clock calibration out.
661   *          - RTC_AF2 pin (PI8) if configured for tamper or time-stamp.
662   *          - WKUP pins if enabled.
663   * @retval None
664   */
HAL_PWR_EnterSTANDBYMode(void)665 void HAL_PWR_EnterSTANDBYMode(void)
666 {
667 
668 #ifdef CORE_CM4
669   /*Allow to go to STANDBY mode */
670   SET_BIT(PWR->MCUCR, PWR_MCUCR_PDDS);
671 
672   /*Allow CORE_CM4 to enter CSTOP mode
673   Set SLEEPDEEP bit of Cortex System Control Register */
674   SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
675 #endif /* CORE_CM4 */
676 
677 #ifdef CORE_CA7
678 
679   /* Clear MPU STANDBY, STOP and HOLD flags.(Always read as 0) */
680   SET_BIT(PWR->MPUCR, PWR_MPUCR_CSSF);
681   /* system Power Down Deepsleep selection */
682   /* MPU go in STANDBY MODE */
683   SET_BIT(PWR->MPUCR, PWR_MPUCR_PDDS);
684 
685   /* MPU CSTANDBY mode enabled */
686   CLEAR_BIT(PWR->MPUCR, PWR_MPUCR_CSTBYDIS);
687 
688   /* RCC Stop Request Set Register */
689 #if defined(RCC_MP_SREQSETR_STPREQ_P0) & defined(RCC_MP_SREQSETR_STPREQ_P1)
690   /* CA7_CORE0 and CA7_CORE1 available */
691   RCC->MP_SREQSETR = RCC_MP_SREQSETR_STPREQ_P0 | RCC_MP_SREQSETR_STPREQ_P1;
692 #else
693   /* Only CA7_CORE0 available */
694   RCC->MP_SREQSETR = RCC_MP_SREQSETR_STPREQ_P0;
695 #endif /* RCC_MP_SREQSETR_STPREQ_P0 & RCC_MP_SREQSETR_STPREQ_P1 */
696 #endif
697 
698   /* Clear Reset Status */
699   __HAL_RCC_CLEAR_RESET_FLAGS();
700 
701 
702   /* This option is used to ensure that store operations are completed */
703 #if defined ( __CC_ARM)
704   __force_stores();
705 #endif
706   /* Request Wait For Interrupt */
707   __WFI();
708 }
709 
710 
711 /**
712   * @brief Indicates Sleep-On-Exit when returning from Handler mode to Thread mode.
713   * @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the processor
714   *       re-enters CSleep mode when an interruption handling is over.
715   *       Setting this bit is useful when the processor is expected to run only on
716   *       interruptions handling.
717   * @retval None
718   */
HAL_PWR_EnableSleepOnExit(void)719 void HAL_PWR_EnableSleepOnExit(void)
720 {
721 #ifdef CORE_CM4
722   /* Set SLEEPONEXIT bit of Cortex System Control Register */
723   SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
724 #endif
725 }
726 
727 
728 /**
729   * @brief Disables Sleep-On-Exit feature when returning from Handler mode to Thread mode.
730   * @note Clears SLEEPONEXIT bit of SCR register. When this bit is set, the processor
731   *       re-enters CSLEEP mode when an interruption handling is over.
732   * @retval None
733   */
HAL_PWR_DisableSleepOnExit(void)734 void HAL_PWR_DisableSleepOnExit(void)
735 {
736 #ifdef CORE_CM4
737   /* Clear SLEEPONEXIT bit of Cortex System Control Register */
738   CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
739 #endif
740 }
741 
742 /**
743   * @brief Enables CORTEX SEVONPEND bit.
744   * @note Sets SEVONPEND bit of SCR register. When this bit is set, this causes
745   *       WFE to wake up when an interrupt moves from inactive to pended.
746   * @retval None
747   */
HAL_PWR_EnableSEVOnPend(void)748 void HAL_PWR_EnableSEVOnPend(void)
749 {
750 #ifdef CORE_CM4
751   /* Set SEVONPEND bit of Cortex System Control Register */
752   SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
753 #endif
754 }
755 
756 /**
757   * @brief Disables CORTEX SEVONPEND bit.
758   * @note Clears SEVONPEND bit of SCR register. When this bit is set, this causes
759   *       WFE to wake up when an interrupt moves from inactive to pended.
760   * @retval None
761   */
HAL_PWR_DisableSEVOnPend(void)762 void HAL_PWR_DisableSEVOnPend(void)
763 {
764 #ifdef CORE_CM4
765   /* Clear SEVONPEND bit of Cortex System Control Register */
766   CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
767 #endif
768 }
769 
770 /**
771   * @brief  PWR PVD interrupt callback
772   * @retval None
773   */
HAL_PWR_PVDCallback(void)774 __weak void HAL_PWR_PVDCallback(void)
775 {
776   /* NOTE : This function Should not be modified, when the callback is needed,
777             the HAL_PWR_PVDCallback could be implemented in the user file
778    */
779 }
780 
781 /**
782   * @}
783   */
784 
785 /**
786   * @}
787   */
788 
789 #endif /* HAL_PWR_MODULE_ENABLED */
790 /**
791   * @}
792   */
793 
794 /**
795   * @}
796   */
797