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