1 /**
2 ******************************************************************************
3 * @file stm32wbaxx_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 * @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 (#) Every entity has low power mode as described below :
32 (#) The CPU low power modes are :
33 (+) CPU CRun.
34 (+) CPU CSleep.
35 (+) CPU CStop.
36 (#) The Core low power modes are :
37 (+) Run.
38 (+) Stop 0.
39 (+) Stop 1.
40 (+) Standby with retention
41 (+) Standby.
42
43 ==============================================================================
44 ##### How to use this driver #####
45 ==============================================================================
46 [..]
47 (#) After startup, power management peripheral is not active by default. Use
48 __HAL_RCC_PWR_CLK_ENABLE() macro to enable power interface.
49
50 (#) Call HAL_PWR_EnableBkUpAccess() and HAL_PWR_DisableBkUpAccess() functions
51 to enable/disable access to the backup domain (RCC Backup domain control
52 register RCC_BDCR, RTC registers, TAMP registers, backup registers and
53 backup SRAM).
54
55 (#) Call HAL_PWR_ConfigPVD() after setting parameters to be configured (event
56 mode and voltage threshold) in order to set up the Programmed Voltage
57 Detector, then use HAL_PWR_EnablePVD() and HAL_PWR_DisablePVD()
58 functions to start and stop the PVD detection.
59 (+) PVD level can be one of the following values :
60 (++) 2V0
61 (++) 2V2
62 (++) 2V4
63 (++) 2V5
64 (++) 2V6
65 (++) 2V8
66 (++) 2V9
67 (++) External input analog voltage PVD_IN (compared internally to
68 VREFINT)
69
70 (#) Call HAL_PWR_EnableWakeUpPin() and HAL_PWR_DisableWakeUpPin() functions
71 with the right parameter to configure the wake up pin polarity (Low or
72 High), the wake up pin selection and to enable and disable it.
73
74 (#) Call HAL_PWR_EnterSLEEPMode() function to enter the CPU in Sleep mode.
75 Wake-up from Sleep mode could be following to an event or an
76 interrupt according to low power mode intrinsic request called (__WFI()
77 or __WFE()).
78
79 (#) Call HAL_PWR_EnterSTOPMode() function to enter the whole system to Stop
80 mode. Wake-up from Stop mode could be following to an event or an
81 interrupt according to low power mode intrinsic request called (__WFI()
82 or __WFE()).
83
84 (#) Call HAL_PWR_EnterSTANDBYMode() function to enter the whole system in
85 Standby mode. Wake-up from Standby mode can be following only by an
86 interrupt.
87
88 (#) Call HAL_PWR_EnableSleepOnExit() and HAL_PWR_DisableSleepOnExit() APIs to
89 enable and disable the Cortex-M33 re-entry in Sleep mode after an
90 interruption handling is over.
91
92 (#) Call HAL_PWR_EnableSEVOnPend() and HAL_PWR_DisableSEVOnPend() functions
93 to configure the Cortex-M33 to wake-up after any pending event / interrupt
94 even if it's disabled or has insufficient priority to cause exception
95 entry.
96
97 (#) Call HAL_PWR_PVD_IRQHandler() under PVD_IRQHandler() function to
98 handle the PWR PVD interrupt request.
99
100 (#) Call HAL_PWR_WAKEUP_PIN_IRQHandler() function to handle all wake-up
101 pins interrupts.
102
103 (#) Call HAL_PWR_ConfigAttributes() function to configure PWR item secure and
104 privilege attributes and call HAL_PWR_GetConfigAttributes() function to
105 get the attribute configuration for the selected item.
106
107 *** PWR HAL driver macros list ***
108 =============================================
109 [..]
110 Below the list of most used macros in PWR HAL driver.
111
112 (+) __HAL_PWR_GET_FLAG() : Get the PWR pending flags.
113 (+) __HAL_PWR_CLEAR_FLAG() : Clear the PWR pending flags.
114
115 @endverbatim
116 ******************************************************************************
117 */
118
119 /* Includes ------------------------------------------------------------------*/
120 #include "stm32wbaxx_hal.h"
121
122 /** @addtogroup STM32WBAxx_HAL_Driver
123 * @{
124 */
125
126 /** @defgroup PWR PWR
127 * @brief PWR HAL module driver
128 * @{
129 */
130
131 #if defined(HAL_PWR_MODULE_ENABLED)
132
133 /* Private typedef -----------------------------------------------------------*/
134 /* Private define ------------------------------------------------------------*/
135
136 /** @defgroup PWR_Private_Defines PWR Private Defines
137 * @{
138 */
139
140 /** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask
141 * @{
142 */
143 #define PVD_RISING_EDGE (0x01U) /*!< Mask for rising edge set as PVD trigger */
144 #define PVD_FALLING_EDGE (0x02U) /*!< Mask for falling edge set as PVD trigger */
145 #define PVD_MODE_IT (0x04U) /*!< Mask for interruption yielded by PVD threshold crossing */
146 #define PVD_MODE_EVT (0x08U) /*!< Mask for event yielded by PVD threshold crossing */
147 /**
148 * @}
149 */
150
151 /**
152 * @}
153 */
154
155 /* Private macro -------------------------------------------------------------*/
156 /* Private variables ---------------------------------------------------------*/
157 /* Private function prototypes -----------------------------------------------*/
158 /* Exported functions --------------------------------------------------------*/
159
160 /** @defgroup PWR_Exported_Functions PWR Exported Functions
161 * @{
162 */
163
164 /** @defgroup PWR_Exported_Functions_Group1 Initialization and De-Initialization Functions
165 * @brief Initialization and de-Initialization functions
166 *
167 @verbatim
168 ===============================================================================
169 ##### Initialization and De-Initialization Functions #####
170 ===============================================================================
171 [..]
172 This section provides functions allowing to deinitialize power peripheral.
173
174 [..]
175 After system reset, the backup domain (RCC Backup domain control register
176 RCC_BDCR, RTC registers, TAMP registers, backup registers and backup SRAM)
177 is protected against possible unwanted write accesses.
178 The HAL_PWR_EnableBkUpAccess() function enables the access to the backup
179 domain.
180 The HAL_PWR_DisableBkUpAccess() function disables the access to the backup
181 domain.
182
183 @endverbatim
184 * @{
185 */
186
187 /**
188 * @brief Deinitialize the HAL PWR peripheral registers to their default reset
189 * values.
190 * @note This functionality is not available in this product.
191 * The prototype is kept just to maintain compatibility with other
192 * products.
193 * @retval None.
194 */
HAL_PWR_DeInit(void)195 void HAL_PWR_DeInit(void)
196 {
197 }
198
199 /**
200 * @brief Enable access to the backup domain (RCC Backup domain control
201 * register RCC_BDCR, RTC registers, TAMP registers, backup registers
202 * and backup SRAM).
203 * @note After a system reset, the backup domain is protected against
204 * possible unwanted write accesses.
205 * @retval None.
206 */
HAL_PWR_EnableBkUpAccess(void)207 void HAL_PWR_EnableBkUpAccess(void)
208 {
209 SET_BIT(PWR->DBPR, PWR_DBPR_DBP);
210 }
211
212 /**
213 * @brief Disable access to the backup domain (RCC Backup domain control
214 * register RCC_BDCR, RTC registers, TAMP registers, backup registers
215 * and backup SRAM).
216 * @retval None.
217 */
HAL_PWR_DisableBkUpAccess(void)218 void HAL_PWR_DisableBkUpAccess(void)
219 {
220 CLEAR_BIT(PWR->DBPR, PWR_DBPR_DBP);
221 }
222 /**
223 * @}
224 */
225
226
227 /** @defgroup PWR_Exported_Functions_Group2 Peripheral Control Functions
228 * @brief Low power modes configuration functions
229 *
230 @verbatim
231 ===============================================================================
232 ##### Peripheral Control functions #####
233 ===============================================================================
234 [..]
235 This section provides functions allowing to control power peripheral.
236
237 *** PVD configuration ***
238 =========================
239 [..]
240 (+) The PVD can be used to monitor the VDD power supply by comparing it
241 to a threshold selected by the PVDLS[2:0] bits in the PWR supply
242 voltage monitoring control register (PWR_SVMCR) and can be enabled by
243 setting the PVDE bit.
244
245 (+) A PVDO flag is available in the PWR supply voltage monitoring control
246 register (PWR_SVMCR) to indicate if VDD is higher or lower than the
247 PVD threshold. This event is internally connected to the EXTI line 16
248 and can generate an interrupt if enabled through the EXTI registers.
249 It is configurable through __HAL_PWR_PVD_EXTI_ENABLE_IT() macro.
250
251 (+) The PVD can remain active in Stop 0 and Stop 1 modes. The PVD
252 is not functional in Standby mode.
253
254 (+) During Stop 0 and Stop 1 modes, it is possible to set the PVD
255 in ultra-low-power mode to further reduce the current consumption by
256 setting the ULPMEN bit in PWR_CR1 register.
257
258 *** Wake-up pin configuration ***
259 =================================
260 [..]
261 (+) Wake-up pin is used to wake up the system from Standby mode.
262 The pin selection is configurable through the WUCR3 register to map
263 internal signal to wake up pin line.
264 The pin polarity is configurable through the WUCR2 register to be
265 active on rising or falling edges.
266
267 (+) There are up to 19 wake-up signals that can be mapped to up to 8
268 wake-up lines in the STM32WBA family.
269
270 (+) When a wakeup pin event is received the HAL_PWR_WAKEUP_PIN_IRQHandler
271 is called and the appropriate flag is set in the PWR_WKUPFR register.
272 Then in the HAL_PWR_WAKEUP_PIN_IRQHandler function the wakeup pin flag
273 will be cleared and the appropriate user callback will be called.
274 The user can add his own code by customization of function pointer
275 HAL_PWR_WKUPx_Callback.
276
277 *** Low Power modes configuration ***
278 =====================================
279 [..]
280 This section presents 4 principles low-power modes :
281 (+) Sleep mode : Cortex-M33 is stopped and all PWR domains are remaining
282 active (powered and clocked).
283
284 (+) Stop 0 mode : Cortex-M33 is stopped, clocks are stopped and the
285 main regulator is running.
286
287 (+) Stop 1 mode : Cortex-M33 is stopped, clocks are stopped and the
288 regulator is in low power mode. Several peripheral can
289 operate in this mode.
290
291 (+) Standby mode : Cortex-M33 is in SleepDeep mode and the voltage
292 supply regulator is powered off.
293
294 *** Sleep mode ***
295 ==================
296 [..]
297 (+) Entry :
298 The Sleep mode is entered by using the HAL_PWR_EnterSLEEPMode()
299 function.
300
301 (++) PWR_SLEEPENTRY_WFI: enter Sleep mode with WFI instruction.
302 (++) PWR_SLEEPENTRY_WFE: enter Sleep mode with WFE instruction.
303
304 -@@- The Regulator parameter is not used for the STM32WBA family and is
305 kept as parameter just to maintain compatibility with other families.
306
307 (+) Exit :
308 According to Sleep entry, any event when entry is __WFE() intrinsic
309 and any interrupt when entry is __WFI() intrinsic can wake up the
310 device from Sleep mode.
311
312 *** Stop 0 & Stop 1 modes ***
313 ===================
314 [..]
315 The Stop 0 and Stop 1 mode are based on the Cortex-M33 Deepsleep mode combined with
316 the peripheral clock gating.
317 In Stop 0 mode, the voltage regulator is configured in main.
318 In Stop 1 mode, The voltage regulator is configured in low power mode.
319 all clocks in the VCORE domain are stopped.
320 In Stop mode 0 the PLL, HSI16 and HSE32 oscillators are disabled.
321 Some peripherals with the LPBAM capability can switch on HSI16 or HSE32 for
322 transferring data. All SRAMs and register contents are preserved,
323 but the SRAMs can totally or not be switched off to further reduce
324 consumption.
325 The BOR is always available in Stop mode.
326
327 (+) Entry:
328 The Stop mode is entered using the HAL_PWR_EnterSTOPMode() function
329 with :
330 (++) Regulator:
331 (+++) PWR_MAINREGULATOR_ON : Main regulator ON (Stop 0 mode).
332 (+++) PWR_LOWPOWERREGULATOR_ON : Low power regulator ON (Stop 1 mode).
333
334 (++) STOPEntry:
335 (+++) PWR_STOPENTRY_WFI: enter Stop mode with WFI instruction.
336 (+++) PWR_STOPENTRY_WFE: enter Stop mode with WFE instruction.
337
338 (+) Exit:
339 Any EXTI line configured in interrupt mode (the corresponding EXTI
340 interrupt vector must be enabled in the NVIC). The interrupt source
341 can be external interrupts or peripherals with wakeup capability.
342 Any peripheral interrupt occurring when the AHB/APB clocks are present
343 due to an autonomous peripheral clock request (the peripheral vector
344 must be enabled in the NVIC).
345 Any EXTI line configured in event mode.
346
347 *** Standby mode ***
348 ====================
349 [..]
350 The Standby mode is used to achieve the lowest power consumption with BOR.
351 The internal regulator is switched off so that the VCORE domain is powered
352 off.
353 The PLL, the HSI16 RC and the HSE32 crystal oscillators are also switched off.
354 The RTC can remain active (Standby mode with RTC, Standby mode without
355 RTC).
356 The Brownout reset (BOR) always remains active in Standby mode.
357 The state of each I/O during Standby mode can be selected by software:
358 I/O with internal pull-up, internal pull-down or floating.
359 After entering Standby mode, SRAMs and register contents are lost except
360 for registers and backup SRAM in the Backup domain and Standby circuitry.
361 Optionally, the full SRAM1 and SRAM2 can be retained in Standby mode depending
362 on R1RSB1 and R2RSB1 bit configuration in PWR_CR1. In this case, the low-power
363 regulator is ON and provides the supply to SRAM1 and or SRAM2. Also the 2.4
364 GHz RADIO SRAMs can be retained, and the sleep timer kept operational depending
365 on RADIOSB bit configuration in PWR_CR1.
366 The BORL (Brownout reset detector low) can be configured in ultra low
367 power mode to further reduce power consumption during Standby mode.
368 The device exits Standby mode when an external reset (NRST pin), an IWDG
369 reset, WKUP pin event (configurable rising or falling edge), an RTC event
370 occurs (alarm, periodic wakeup, timestamp), or a tamper detection.
371 The system clock after wakeup is HSI16.
372
373 (++) Entry:
374 The Standby mode is entered using the HAL_PWR_EnterSTANDBYMode()
375 function.
376
377 (++) Exit:
378 WKUPx pin edge, RTC event, external Reset in NRST pin, IWDG Reset,
379 BOR reset.
380
381 @endverbatim
382 * @{
383 */
384
385 /**
386 * @brief Configure the voltage threshold detected by the Programmed Voltage
387 * Detector (PVD).
388 * @param sConfigPVD : Pointer to a PWR_PVDTypeDef structure that contains the
389 * PVD configuration information (PVDLevel and EventMode).
390 * @retval None.
391 */
HAL_PWR_ConfigPVD(const PWR_PVDTypeDef * sConfigPVD)392 HAL_StatusTypeDef HAL_PWR_ConfigPVD(const PWR_PVDTypeDef *sConfigPVD)
393 {
394 /* Check the parameters */
395 assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel));
396 assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode));
397
398 /* Set PLS[2:0] bits according to PVDLevel value */
399 MODIFY_REG(PWR->SVMCR, PWR_SVMCR_PVDLS, sConfigPVD->PVDLevel);
400
401 /* Disable PVD Event/Interrupt */
402 __HAL_PWR_PVD_EXTI_DISABLE_EVENT();
403 __HAL_PWR_PVD_EXTI_DISABLE_IT();
404 __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();
405 __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE();
406
407 /* Configure the PVD in interrupt mode */
408 if ((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT)
409 {
410 __HAL_PWR_PVD_EXTI_ENABLE_IT();
411 }
412
413 /* Configure the PVD in event mode */
414 if ((sConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT)
415 {
416 __HAL_PWR_PVD_EXTI_ENABLE_EVENT();
417 }
418
419 /* Configure the PVD in rising edge */
420 if ((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE)
421 {
422 __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();
423 }
424
425 /* Configure the PVD in falling edge */
426 if ((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE)
427 {
428 __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
429 }
430
431 return HAL_OK;
432 }
433
434 /**
435 * @brief Enable the programmable voltage detector (PVD).
436 * @retval None.
437 */
HAL_PWR_EnablePVD(void)438 void HAL_PWR_EnablePVD(void)
439 {
440 SET_BIT(PWR->SVMCR, PWR_SVMCR_PVDE);
441 }
442
443 /**
444 * @brief Disable the programmable voltage detector (PVD).
445 * @retval None.
446 */
HAL_PWR_DisablePVD(void)447 void HAL_PWR_DisablePVD(void)
448 {
449 CLEAR_BIT(PWR->SVMCR, PWR_SVMCR_PVDE);
450 }
451
452 /**
453 * @brief Enable the wake up line functionality.
454 * @note Wake up lines are used to wake up the system from Sleep, Stop 0-1 and
455 * Standby modes.
456 * @param WakeUpPin : Specifies which wake up line to enable. This parameter
457 * can be one of PWR_WakeUp_Pins_High_Polarity define
458 * group where every param select the wake up line, the
459 * wake up source with high polatiry detection and the wake
460 * up selected I/O or can be one of
461 * PWR_WakeUp_Pins_Low_Polarity define group where every
462 * param select the wake up line, the wake up source with
463 * low polarity and the wake up selected I/O or can be one
464 * of PWR_WakeUp_Pins define group where every param select
465 * the wake up line, the wake up source with
466 * high polarity and the first wake up I/O.
467 * @retval None.
468 */
HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPin)469 void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPin)
470 {
471 /* Check the parameter */
472 assert_param(IS_PWR_WAKEUP_PIN(WakeUpPin));
473
474 /* Specifies the wake up line polarity for the event detection (rising or falling edge) */
475 MODIFY_REG(PWR->WUCR2, (PWR_EWUP_MASK & WakeUpPin), (WakeUpPin >> PWR_WUP_POLARITY_SHIFT));
476
477 /* Specifies the wake up line I/O selection */
478 MODIFY_REG(PWR->WUCR3, (3UL << (POSITION_VAL(PWR_EWUP_MASK & WakeUpPin) * 2U)),
479 (WakeUpPin >> PWR_WUP_SELECT_SIGNAL_SHIFT));
480
481 /* Enable wake-up line */
482 SET_BIT(PWR->WUCR1, (PWR_EWUP_MASK & WakeUpPin));
483 }
484
485 /**
486 * @brief Disable the wake up line functionality.
487 * @param WakeUpPin : Specifies the wake up line to disable.
488 * This parameter can be a combination of all the following
489 * values when available:
490 * @arg @ref PWR_WAKEUP_PIN1
491 * @arg @ref PWR_WAKEUP_PIN2
492 * @arg @ref PWR_WAKEUP_PIN3
493 * @arg @ref PWR_WAKEUP_PIN4
494 * @arg @ref PWR_WAKEUP_PIN5
495 * @arg @ref PWR_WAKEUP_PIN6
496 * @arg @ref PWR_WAKEUP_PIN7
497 * @arg @ref PWR_WAKEUP_PIN8
498 * @retval None
499 */
HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPin)500 void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPin)
501 {
502 /* Check the parameters */
503 assert_param(IS_PWR_WAKEUP_PIN(WakeUpPin));
504
505 /* Disable wake-up pin */
506 CLEAR_BIT(PWR->WUCR1, (PWR_EWUP_MASK & WakeUpPin));
507 }
508
509 /**
510 * @brief Get and Clear Wake-up source.
511 * @retval WakeUpPin : This parameter can be a combination of all the following
512 * values when available:
513 * @arg @ref PWR_WAKEUP_PIN1
514 * @arg @ref PWR_WAKEUP_PIN2
515 * @arg @ref PWR_WAKEUP_PIN3
516 * @arg @ref PWR_WAKEUP_PIN4
517 * @arg @ref PWR_WAKEUP_PIN5
518 * @arg @ref PWR_WAKEUP_PIN6
519 * @arg @ref PWR_WAKEUP_PIN7
520 * @arg @ref PWR_WAKEUP_PIN8
521 */
HAL_PWR_GetClearWakeupSource(void)522 uint32_t HAL_PWR_GetClearWakeupSource(void)
523 {
524 uint32_t wakeuppin;
525
526 /* Get all wake-up pins */
527 wakeuppin = PWR->WUSR;
528
529 /* Clear all the wake-up interrupt flags */
530 PWR->WUSCR = wakeuppin;
531
532 return wakeuppin;
533 }
534
535 /**
536 * @brief Enter the CPU in Sleep mode.
537 * @note In Sleep mode, all I/O pins keep the same state as in Run mode.
538 * @note CPU clock is off and all peripherals including Cortex-M33 core such
539 * as NVIC and SysTick can run and wake up the CPU when an interrupt
540 * or an event occurs.
541 * @param Regulator : Specifies the regulator state in Sleep mode.
542 * This parameter can be one of the following values :
543 * @arg @ref PWR_MAINREGULATOR_ON
544 * @arg @ref PWR_LOWPOWERREGULATOR_ON
545 * @note This parameter is not available in this product.
546 * The parameter is kept just to maintain compatibility with other
547 * products.
548 * @param SLEEPEntry : Specifies if Sleep mode is entered with WFI or WFE
549 * instruction.
550 * This parameter can be one of the following values :
551 * @arg @ref PWR_SLEEPENTRY_WFI enter Sleep mode with Wait
552 * For Interrupt request.
553 * @arg @ref PWR_SLEEPENTRY_WFE enter Sleep mode with Wait
554 * For Event request.
555 * @note When WFI entry is used, ticks interrupt must be disabled to avoid
556 * unexpected CPU wake up.
557 * @retval None.
558 */
HAL_PWR_EnterSLEEPMode(uint32_t Regulator,uint8_t SLEEPEntry)559 void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
560 {
561 UNUSED(Regulator);
562
563 /* Check the parameter */
564 assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry));
565
566 /* Clear SLEEPDEEP bit of Cortex System Control Register */
567 CLEAR_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk);
568
569 /* Select Sleep mode entry */
570 if (SLEEPEntry == PWR_SLEEPENTRY_WFI)
571 {
572 /* Wait For Interrupt Request */
573 __WFI();
574 }
575 else
576 {
577 /* Wait For Event Request */
578 __SEV();
579 __WFE();
580 __WFE();
581 }
582 }
583
584 /**
585 * @brief Enter the whole system to Stop mode.
586 * @note In Stop 0 mode, the regulator remains in main regulator mode,
587 * allowing a very fast wakeup time but with much higher consumption
588 * comparing to other Stop modes.
589 * @note Stop 0 offers the largest number of active peripherals and wakeup
590 * sources, a smaller wakeup time but a higher consumption.
591 * @note Stop 1 mode, The voltage regulator is configured in low power mode.
592 * Stop 1 achieves the lowest power consumption while retaining
593 * the content of SRAM and registers. All clocks in the VCORE domain
594 * are stopped. The PLL, HSI16 and HSE32 oscillators are disabled.
595 * The LSE or LSI is still running.
596 * @note When exiting Stop mode by issuing an interrupt or a
597 * wakeup event, the HSI16 oscillator is selected as system clock
598 * The MCU is in Run mode same range as before entering Stop mode.
599 * @note On STM32WBAXX_SI_CUT1_0 :
600 * Under a critical timing wakeup condition, CPU is executing code
601 * after WFI while the system is still evolving to manage the enter and
602 * exit from STOP mode. Under this condition it results that STOPF flag
603 * is set and SYSCLK source change during CPU wakeup code execution.
604 * Worst case scenario is when the system is running on PLL, fed by
605 * HSE32, and HSI16 is on. In this case STOPF flag bit is set and
606 * SYSCLK clock source is changed 25 sys clock cycles after WFI.
607 * Undoing any PLL1ON, HSEON, HSION and SYSCLK modification.
608 * Workaround at application level is to call this API under critical
609 * section and add a wait loop of at least 25 system clock cycles,
610 * before reading the STOPF flag and making any modification to PLL1ON,
611 * HSEON, HSION and SYSCLK selection.
612 * @param Regulator : Specifies the regulator state in Stop mode
613 * This parameter can be one of the following values:
614 * @arg @ref PWR_LOWPOWERMODE_STOP0 Stop 0 mode (main regulator ON)
615 * @arg @ref PWR_LOWPOWERMODE_STOP1 Stop 1 mode (low power regulator ON)
616 * @param STOPEntry : Specifies if Stop mode is entered with WFI or WFE
617 * instruction.
618 * This parameter can be one of the following values :
619 * @arg @ref PWR_STOPENTRY_WFI enter Stop mode with Wait
620 * For Interrupt request.
621 * @arg @ref PWR_STOPENTRY_WFE enter Stop mode with Wait
622 * For Event request.
623 * @retval None.
624 */
HAL_PWR_EnterSTOPMode(uint32_t Regulator,uint8_t STOPEntry)625 void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
626 {
627 /* Check the parameter */
628 assert_param(IS_PWR_REGULATOR(Regulator));
629 assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
630
631 /* Select Stop mode */
632 MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, Regulator);
633
634 /* Set SLEEPDEEP bit of Cortex System Control Register */
635 SET_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk);
636
637 /* Select Stop mode entry */
638 if (STOPEntry == PWR_STOPENTRY_WFI)
639 {
640 /* Wait For Interrupt Request */
641 __WFI();
642 }
643 else
644 {
645 /* Wait For Event Request */
646 __SEV();
647 __WFE();
648 __WFE();
649 }
650
651 /* Reset SLEEPDEEP bit of Cortex System Control Register */
652 CLEAR_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk);
653 }
654
655 /**
656 * @brief Enter the whole system to Standby mode.
657 * @note The Standby mode is used to achieve the lowest power consumption
658 * with BOR. The internal regulator is switched off so that the VCORE
659 * domain is powered off. The PLL, the HSI16 and the HSE32 crystal
660 * oscillators are also switched off.
661 * @note After entering Standby mode, SRAMs and register contents are lost
662 * except for registers and backup SRAM in the Backup domain and
663 * Standby circuitry. Optionally, the full SRAM1 or SRAM2 can be
664 * retained in Standby mode, supplied by the low-power regulator.
665 * @note The state of each I/O during Standby mode can be selected by
666 * software : Enable GPIO state retention in Standby mode through
667 * HAL_PWREx_EnableStandbyIORetention() and disable through
668 * HAL_PWREx_DisableStandbyIORetention().
669 * @retval None.
670 */
HAL_PWR_EnterSTANDBYMode(void)671 void HAL_PWR_EnterSTANDBYMode(void)
672 {
673 /* Select Standby mode */
674 MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_2);
675
676 /* Set SLEEPDEEP bit of Cortex System Control Register */
677 SET_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk);
678
679 /* Wait For Interrupt Request */
680 __WFI();
681 }
682
683 /**
684 * @brief Indicate SLEEP-ON-EXIT feature when returning from handler mode to
685 * thread mode.
686 * @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the
687 * processor re-enters Sleep mode when an interruption handling is over.
688 * Setting this bit is useful when the processor is expected to run
689 * only on interruptions handling.
690 * @retval None.
691 */
HAL_PWR_EnableSleepOnExit(void)692 void HAL_PWR_EnableSleepOnExit(void)
693 {
694 /* Set SLEEPONEXIT bit of Cortex-M33 System Control Register */
695 SET_BIT(SCB->SCR, SCB_SCR_SLEEPONEXIT_Msk);
696 }
697
698 /**
699 * @brief Disable SLEEP-ON-EXIT feature when returning from handler mode to
700 * thread mode.
701 * @note Clears SLEEPONEXIT bit of SCR register. When this bit is set, the
702 * processor re-enters Sleep mode when an interruption handling is over.
703 * @retval None.
704 */
HAL_PWR_DisableSleepOnExit(void)705 void HAL_PWR_DisableSleepOnExit(void)
706 {
707 /* Clear SLEEPONEXIT bit of Cortex-M33 System Control Register */
708 CLEAR_BIT(SCB->SCR, SCB_SCR_SLEEPONEXIT_Msk);
709 }
710
711 /**
712 * @brief Enable CORTEX SEV-ON-PEND feature.
713 * @note Sets SEVONPEND bit of SCR register. When this bit is set, any
714 * pending event / interrupt even if it's disabled or has insufficient
715 * priority to cause exception entry wakes up the Cortex-M33.
716 * @retval None.
717 */
HAL_PWR_EnableSEVOnPend(void)718 void HAL_PWR_EnableSEVOnPend(void)
719 {
720 /* Set SEVONPEND bit of Cortex-M33 System Control Register */
721 SET_BIT(SCB->SCR, SCB_SCR_SEVONPEND_Msk);
722 }
723
724 /**
725 * @brief Disable CORTEX SEVONPEND feature.
726 * @note Resets SEVONPEND bit of SCR register. When this bit is reset, only
727 * enabled pending causes exception entry wakes up the Cortex-M33.
728 * @retval None.
729 */
HAL_PWR_DisableSEVOnPend(void)730 void HAL_PWR_DisableSEVOnPend(void)
731 {
732 /* Clear SEVONPEND bit of Cortex-M33 System Control Register */
733 CLEAR_BIT(SCB->SCR, SCB_SCR_SEVONPEND_Msk);
734 }
735
736 /**
737 * @brief This function handles the PWR PVD interrupt request.
738 * @note This API should be called under the PVD_IRQHandler().
739 * @retval None.
740 */
HAL_PWR_PVD_IRQHandler(void)741 void HAL_PWR_PVD_IRQHandler(void)
742 {
743 uint32_t rising_flag;
744 uint32_t falling_flag;
745
746 rising_flag = READ_REG(EXTI->RPR1);
747 falling_flag = READ_REG(EXTI->FPR1);
748
749 /* Check PWR exti rising flag */
750 if ((rising_flag & PWR_EXTI_LINE_PVD) != 0U)
751 {
752 /* Clear PVD exti pending bit */
753 __HAL_PWR_PVD_EXTI_CLEAR_RISING_FLAG();
754
755 /* PWR PVD interrupt rising user callback */
756 HAL_PWR_PVD_Rising_Callback();
757 }
758
759 /* Check PWR exti fallling flag */
760 if ((falling_flag & PWR_EXTI_LINE_PVD) != 0U)
761 {
762 /* Clear PVD exti pending bit */
763 __HAL_PWR_PVD_EXTI_CLEAR_FALLING_FLAG();
764
765 /* PWR PVD interrupt falling user callback */
766 HAL_PWR_PVD_Falling_Callback();
767 }
768 }
769
770 /**
771 * @brief PWR PVD interrupt rising callback
772 * @retval None
773 */
HAL_PWR_PVD_Rising_Callback(void)774 __weak void HAL_PWR_PVD_Rising_Callback(void)
775 {
776 /* NOTE : This function should not be modified; when the callback is needed,
777 the HAL_PWR_PVD_Rising_Callback can be implemented in the user file
778 */
779 }
780
781 /**
782 * @brief PWR PVD interrupt Falling callback
783 * @retval None
784 */
HAL_PWR_PVD_Falling_Callback(void)785 __weak void HAL_PWR_PVD_Falling_Callback(void)
786 {
787 /* NOTE : This function should not be modified; when the callback is needed,
788 the HAL_PWR_PVD_Falling_Callback can be implemented in the user file
789 */
790 }
791 /**
792 * @}
793 */
794
795 /**
796 * @brief This function handles the PWR WAKEUP interrupt request.
797 * @note This API should be called under the WKUP_IRQHandler().
798 * @retval None.
799 */
HAL_PWR_WKUP_IRQHandler(void)800 void HAL_PWR_WKUP_IRQHandler(void)
801 {
802 uint32_t wakeuppin;
803
804 wakeuppin = HAL_PWR_GetClearWakeupSource();
805
806 /* Wakeup pin EXTI line interrupt detected */
807 if ((wakeuppin & PWR_WUSR_WUF1) != 0U)
808 {
809 /* PWR WKUP1 interrupt user callback */
810 HAL_PWR_WKUP1_Callback();
811 }
812 #if defined(PWR_WUCR1_WUPEN2)
813 if ((wakeuppin & PWR_WUSR_WUF2) != 0U)
814 {
815 /* PWR WKUP2 interrupt user callback */
816 HAL_PWR_WKUP2_Callback();
817 }
818 #endif /* defined(PWR_WUCR1_WUPEN2) */
819 if ((wakeuppin & PWR_WUSR_WUF3) != 0U)
820 {
821 /* PWR WKUP3 interrupt user callback */
822 HAL_PWR_WKUP3_Callback();
823 }
824
825 if ((wakeuppin & PWR_WUSR_WUF4) != 0U)
826 {
827 /* PWR WKUP4 interrupt user callback */
828 HAL_PWR_WKUP4_Callback();
829 }
830 #if defined(PWR_WUCR1_WUPEN5)
831 if ((wakeuppin & PWR_WUSR_WUF5) != 0U)
832 {
833 /* PWR WKUP5 interrupt user callback */
834 HAL_PWR_WKUP5_Callback();
835 }
836 #endif /* defined(PWR_WUCR1_WUPEN5) */
837 if ((wakeuppin & PWR_WUSR_WUF6) != 0U)
838 {
839 /* PWR WKUP6 interrupt user callback */
840 HAL_PWR_WKUP6_Callback();
841 }
842 if ((wakeuppin & PWR_WUSR_WUF7) != 0U)
843 {
844 /* PWR WKUP7 interrupt user callback */
845 HAL_PWR_WKUP7_Callback();
846 }
847 if ((wakeuppin & PWR_WUSR_WUF8) != 0U)
848 {
849 /* PWR WKUP8 interrupt user callback */
850 HAL_PWR_WKUP8_Callback();
851 }
852 }
853
854 /**
855 * @brief PWR WKUP1 interrupt callback.
856 * @retval None.
857 */
HAL_PWR_WKUP1_Callback(void)858 __weak void HAL_PWR_WKUP1_Callback(void)
859 {
860 /* NOTE : This function should not be modified, when the callback is needed,
861 the HAL_PWR_WKUP1Callback can be implemented in the user file
862 */
863 }
864
865 #if defined(PWR_WUCR1_WUPEN2)
866 /**
867 * @brief PWR WKUP2 interrupt callback.
868 * @retval None.
869 */
HAL_PWR_WKUP2_Callback(void)870 __weak void HAL_PWR_WKUP2_Callback(void)
871 {
872 /* NOTE : This function should not be modified, when the callback is needed,
873 the HAL_PWR_WKUP2Callback can be implemented in the user file
874 */
875 }
876 #endif /* defined(PWR_WUCR1_WUPEN2) */
877
878 /**
879 * @brief PWR WKUP3 interrupt callback.
880 * @retval None.
881 */
HAL_PWR_WKUP3_Callback(void)882 __weak void HAL_PWR_WKUP3_Callback(void)
883 {
884 /* NOTE : This function should not be modified, when the callback is needed,
885 the HAL_PWR_WKUP3Callback can be implemented in the user file
886 */
887 }
888
889 /**
890 * @brief PWR WKUP4 interrupt callback.
891 * @retval None.
892 */
HAL_PWR_WKUP4_Callback(void)893 __weak void HAL_PWR_WKUP4_Callback(void)
894 {
895 /* NOTE : This function should not be modified, when the callback is needed,
896 the HAL_PWR_WKUP4Callback can be implemented in the user file
897 */
898 }
899
900 #if defined(PWR_WUCR1_WUPEN5)
901 /**
902 * @brief PWR WKUP5 interrupt callback.
903 * @retval None.
904 */
HAL_PWR_WKUP5_Callback(void)905 __weak void HAL_PWR_WKUP5_Callback(void)
906 {
907 /* NOTE : This function should not be modified, when the callback is needed,
908 the HAL_PWR_WKUP5Callback can be implemented in the user file
909 */
910 }
911 #endif /* defined(PWR_WUCR1_WUPEN5) */
912
913 /**
914 * @brief PWR WKUP6 interrupt callback.
915 * @retval None.
916 */
HAL_PWR_WKUP6_Callback(void)917 __weak void HAL_PWR_WKUP6_Callback(void)
918 {
919 /* NOTE : This function should not be modified, when the callback is needed,
920 the HAL_PWR_WKUP6Callback can be implemented in the user file
921 */
922 }
923
924 /**
925 * @brief PWR WKUP7 interrupt callback.
926 * @retval None.
927 */
HAL_PWR_WKUP7_Callback(void)928 __weak void HAL_PWR_WKUP7_Callback(void)
929 {
930 /* NOTE : This function should not be modified, when the callback is needed,
931 the HAL_PWR_WKUP7Callback can be implemented in the user file
932 */
933 }
934
935 /**
936 * @brief PWR WKUP8 interrupt callback.
937 * @retval None.
938 */
HAL_PWR_WKUP8_Callback(void)939 __weak void HAL_PWR_WKUP8_Callback(void)
940 {
941 /* NOTE : This function should not be modified, when the callback is needed,
942 the HAL_PWR_WKUP8Callback can be implemented in the user file
943 */
944 }
945 /**
946 * @}
947 */
948
949 #if defined(PWR_PRIVCFGR_NSPRIV)
950 /** @defgroup PWR_Exported_Functions_Group3 Attributes Management Functions
951 * @brief Attributes management functions
952 *
953 @verbatim
954 ===============================================================================
955 ##### PWR Attributes Functions #####
956 ===============================================================================
957 [..]
958 When the TrustZone security is activated by the TZEN option bit in the
959 FLASH_OPTR register, some PWR register fields can be secured against
960 non-secure access.
961 The PWR TrustZone security allows the following features to be secured
962 through the PWR_SECCFGR register :
963
964 (++) Low-power mode.
965 (++) Wake-up (WKUP) pins.
966 (++) Voltage detection and monitoring.
967 (++) VBAT mode.
968 (++) I/Os pull-up/pull-down configuration.
969
970 Other PWR configuration bits are secure when :
971 (++) The system clock selection is secure in RCC: the voltage scaling
972 (VOS) configuration is secure.
973 (++) A GPIO is configured as secure: its corresponding bit for pull-up /
974 pull-down configuration in Standby mode is secure.
975
976 A non-secure access to a secure-protected register bit is denied :
977 (++) The secured bits are not written (WI) with a non-secure write access.
978 (++) The secured bits are read as 0 (RAZ) with a non-secure read access.
979
980 [..]
981 When the TrustZone security is disabled (TZEN = 0), PWR_SECCFGR is RAZ/WI
982 and all other registers are non-secure.
983
984 [..]
985 By default, after a reset, all PWR registers can be read or written with
986 both privileged and unprivileged accesses, except PWR_PRIVCFGR that can be
987 written with privileged access only. PWR_PRIVCFGR can be read by secure
988 and non secure, privileged and unprivileged accesses.
989 The SPRIV bit in PWR_PRIVCFGR can be written with secure privileged access
990 only. This bit configures the privileged access of all PWR secure
991 functions (defined by PWR_SECCFGR, GTZC, RCC or GPIO).
992 When the SPRIV bit is set in PWR_PRIVCFGR:
993 (++) The PWR secure bits can be written only with privileged access,
994 including PWR_SECCFGR.
995 (++) The PWR secure bits can be read only with privileged access except
996 PWR_SECCFGR and PWR_PRIVCFGR that can be read by privileged or
997 unprivileged access.
998 (++) An unprivileged access to a privileged PWR bit or register is
999 discarded : the bits are read as zero and the write to these bits is
1000 ignored (RAZ/WI).
1001 The NSPRIV bit of PWR_PRIVCFGR can be written with privileged access only,
1002 secure or non-secure. This bit configures the privileged access of all PWR
1003 securable functions that are configured as non-secure (defined by
1004 PWR_SECCFGR, GTZC, RCC or GPIO).
1005 When the NSPRIV bit is set in PWR_PRIVCFGR :
1006 (++) The PWR securable bits that are configured as non-secure, can be
1007 written only with privileged access.
1008 (++) The PWR securable bits that are configured as non-secure, can be read
1009 only with privileged access except PWR_PRIVCFGR that can be read by
1010 privileged or unprivileged accesses.
1011 (++) The VOSRDY bit in PWR_VOSR, PWR_SR, PWR_SVMSR and PWR_WUSR, can be read
1012 with privileged or unprivileged accesses.
1013 (++) An unprivileged access to a privileged PWR bit or register is
1014 discarded : the bits are read as zero and the write to these bits is
1015 ignored (RAZ/WI).
1016
1017 @endverbatim
1018 * @{
1019 */
1020
1021 /**
1022 * @brief Configure the PWR item attributes.
1023 * @note Available attributes are security and privilege protection.
1024 * @note Security attribute can only be set only by secure access.
1025 * @note Privilege attribute for secure items can be managed only by a secure
1026 * privileged access.
1027 * @note Privilege attribute for nsecure items can be managed by a secure
1028 * privileged access or by a nsecure privileged access.
1029 * @note As the privileged attributes concern either all secure or all non-secure
1030 * PWR resources accesses and not each PWR individual items access attribute,
1031 * the application must ensure that the privilege access attribute configurations
1032 * are coherent amongst the security level set on PWR individual items so not to
1033 * overwrite a previous more restricted access rule (consider either all secure
1034 * and/or all non-secure PWR resources accesses by privileged-only transactions
1035 * or privileged and unprivileged transactions).
1036 * @param Item : Specifies the item(s) to set attributes on.
1037 * This parameter can be a combination of PWR_ITEMS.
1038 * @param Attributes : Specifies the available attribute(s).
1039 * This parameter can be one of PWR_ATTRIBUTES.
1040 * @retval None.
1041 */
HAL_PWR_ConfigAttributes(uint32_t Item,uint32_t Attributes)1042 void HAL_PWR_ConfigAttributes(uint32_t Item, uint32_t Attributes)
1043 {
1044 /* Check the parameters */
1045 assert_param(IS_PWR_ITEMS_ATTRIBUTES(Item));
1046 assert_param(IS_PWR_ATTRIBUTES(Attributes));
1047
1048 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1049 /* Secure item management (TZEN = 1) */
1050 if ((Attributes & PWR_ITEM_ATTR_SEC_PRIV_MASK) == PWR_ITEM_ATTR_SEC_PRIV_MASK)
1051 {
1052 /* Privilege item management */
1053 if ((Attributes & PWR_SEC_PRIV) == PWR_SEC_PRIV)
1054 {
1055 SET_BIT(PWR_S->SECCFGR, Item);
1056 SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_SPRIV);
1057 }
1058 else
1059 {
1060 SET_BIT(PWR_S->SECCFGR, Item);
1061 CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_SPRIV);
1062 }
1063 }
1064 /* NSecure item management */
1065 else
1066 {
1067 /* Privilege item management */
1068 if ((Attributes & PWR_NSEC_PRIV) == PWR_NSEC_PRIV)
1069 {
1070 CLEAR_BIT(PWR_S->SECCFGR, Item);
1071 SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV);
1072 }
1073 else
1074 {
1075 CLEAR_BIT(PWR_S->SECCFGR, Item);
1076 CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV);
1077 }
1078 }
1079 #else
1080 /* NSecure item management (TZEN = 0) */
1081 if ((Attributes & PWR_ITEM_ATTR_NSEC_PRIV_MASK) == PWR_ITEM_ATTR_NSEC_PRIV_MASK)
1082 {
1083 /* Privilege item management */
1084 if ((Attributes & PWR_NSEC_PRIV) == PWR_NSEC_PRIV)
1085 {
1086 SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV);
1087 }
1088 else
1089 {
1090 CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV);
1091 }
1092 }
1093 #endif /* __ARM_FEATURE_CMSE */
1094 }
1095
1096
1097 /**
1098 * @brief Get attribute(s) of a PWR item.
1099 * @param Item : Specifies the item(s) to set attributes on.
1100 * This parameter can be one of PWR_ITEMS.
1101 * @param pAttributes : Pointer to return attribute(s).
1102 * Returned value could be on of PWR_ATTRIBUTES.
1103 * @retval HAL Status.
1104 */
HAL_PWR_GetConfigAttributes(uint32_t Item,uint32_t * pAttributes)1105 HAL_StatusTypeDef HAL_PWR_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes)
1106 {
1107 uint32_t attributes;
1108
1109 /* Check attribute pointer */
1110 if (pAttributes == NULL)
1111 {
1112 return HAL_ERROR;
1113 }
1114
1115 /* Check the parameter */
1116 assert_param(IS_PWR_ITEMS_ATTRIBUTES(Item));
1117
1118 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1119 /* Check item security */
1120 if ((PWR->SECCFGR & Item) == Item)
1121 {
1122 /* Get Secure privileges attribute */
1123 attributes = ((PWR->PRIVCFGR & PWR_PRIVCFGR_SPRIV) == 0U) ? PWR_SEC_NPRIV : PWR_SEC_PRIV;
1124 }
1125 else
1126 {
1127 /* Get Non-Secure privileges attribute */
1128 attributes = ((PWR->PRIVCFGR & PWR_PRIVCFGR_NSPRIV) == 0U) ? PWR_NSEC_NPRIV : PWR_NSEC_PRIV;
1129 }
1130 #else
1131 /* Get Non-Secure privileges attribute */
1132 attributes = ((PWR->PRIVCFGR & PWR_PRIVCFGR_NSPRIV) == 0U) ? PWR_NSEC_NPRIV : PWR_NSEC_PRIV;
1133 #endif /* __ARM_FEATURE_CMSE */
1134
1135 /* return value */
1136 *pAttributes = attributes;
1137
1138 return HAL_OK;
1139 }
1140 /**
1141 * @}
1142 */
1143 #endif /* #if defined(PWR_PRIVCFGR_SPRIV) */
1144
1145 /**
1146 * @}
1147 */
1148
1149 #endif /* defined(HAL_PWR_MODULE_ENABLED) */
1150 /**
1151 * @}
1152 */
1153
1154 /**
1155 * @}
1156 */
1157
1158