1 /**
2 ******************************************************************************
3 * @file stm32c0xx_hal_pwr.c
4 * @author MCD Application Team
5 * @brief PWR HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Power Controller (PWR) peripheral:
8 * + Initialization/de-initialization functions
9 * + Peripheral Control functions
10 *
11 ******************************************************************************
12 * @attention
13 *
14 * Copyright (c) 2022 STMicroelectronics.
15 * All rights reserved.
16 *
17 * This software is licensed under terms that can be found in the LICENSE file
18 * in the root directory of this software component.
19 * If no LICENSE file comes with this software, it is provided AS-IS.
20 *
21 ******************************************************************************
22 */
23
24 /* Includes ------------------------------------------------------------------*/
25 #include "stm32c0xx_hal.h"
26
27 /** @addtogroup STM32C0xx_HAL_Driver
28 * @{
29 */
30
31 /** @addtogroup PWR
32 * @{
33 */
34
35 #ifdef HAL_PWR_MODULE_ENABLED
36
37 /* Private typedef -----------------------------------------------------------*/
38 /* Private define ------------------------------------------------------------*/
39 /** @defgroup PWR_Private_Defines PWR Private Defines
40 * @{
41 */
42
43 /**
44 * @}
45 */
46
47 /* Private macro -------------------------------------------------------------*/
48 /* Private variables ---------------------------------------------------------*/
49 /* Private function prototypes -----------------------------------------------*/
50 /* Exported functions --------------------------------------------------------*/
51 /** @addtogroup PWR_Exported_Functions PWR Exported Functions
52 * @{
53 */
54
55 /** @addtogroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions
56 * @brief Initialization and de-initialization functions
57 *
58 @verbatim
59 ===============================================================================
60 ##### Initialization and de-initialization functions #####
61 ===============================================================================
62 [..]
63
64 @endverbatim
65 * @{
66 */
67
68 /**
69 * @brief Deinitialize the HAL PWR peripheral registers to their default reset
70 values.
71 * @retval None
72 */
HAL_PWR_DeInit(void)73 void HAL_PWR_DeInit(void)
74 {
75 __HAL_RCC_PWR_FORCE_RESET();
76 __HAL_RCC_PWR_RELEASE_RESET();
77 }
78
79 /**
80 * @}
81 */
82
83 /** @addtogroup PWR_Exported_Functions_Group2 Peripheral Control functions
84 * @brief Low Power modes configuration functions
85 *
86 @verbatim
87
88 ===============================================================================
89 ##### Peripheral Control functions #####
90 ===============================================================================
91
92 [..]
93
94 *** WakeUp pin configuration ***
95 ================================
96 [..]
97 (+) WakeUp pins are used to wakeup the system from Standby mode or
98 Shutdown mode. WakeUp pins polarity can be set to configure event
99 detection on high level (rising edge) or low level (falling edge).
100
101 *** Low Power mode configuration ***
102 =====================================
103 [..]
104 The devices feature 4 low-power modes:
105 (+) Sleep mode: Cortex-M0+ core stopped, peripherals kept running,
106 regulator is main mode.
107 (+) Stop 0 mode: all clocks are stopped except LSI and LSE, regulator is
108 main mode.
109 (+) Standby mode: all clocks are stopped except LSI and LSE, regulator is
110 disable.
111 (+) Shutdown mode: all clocks are stopped except LSE, regulator is
112 disable.
113
114
115 *** Sleep mode ***
116 =========================================
117 [..]
118 (+) Entry:
119 The Sleep is entered through HAL_PWR_EnterSLEEPMode() API specifying
120 the main regulator per default and if exit is interrupt or event
121 triggered.
122 (++) PWR_MAINREGULATOR_ON: Sleep mode (regulator in main mode).
123 (++) PWR_SLEEPENTRY_WFI: Core enters sleep mode with WFI instruction
124 (++) PWR_SLEEPENTRY_WFE: Core enters sleep mode with WFE instruction
125 (+) WFI Exit:
126 (++) Any interrupt enabled in nested vectored interrupt controller (NVIC)
127 (+) WFE Exit:
128 (++) Any wakeup event if cortex is configured with SEVONPEND = 0
129 (++) Interrupt even when disabled in NVIC if cortex is configured with
130 SEVONPEND = 1
131
132 *** Stop 0 mode ***
133 =============================
134 [..]
135 (+) Entry:
136 The Stop modes are entered through the following APIs:
137 (++) HAL_PWR_EnterSTOPMode() with following settings:
138 (+++) PWR_MAINREGULATOR_ON to enter STOP0 mode.
139 (+) Exit (interrupt or event-triggered, specified when entering STOP mode):
140 (++) PWR_STOPENTRY_WFI: enter Stop mode with WFI instruction
141 (++) PWR_STOPENTRY_WFE: enter Stop mode with WFE instruction
142 (+) WFI Exit:
143 (++) Any EXTI line (internal or external) configured in interrupt mode
144 with corresponding interrupt enable in NVIC
145 (+) WFE Exit:
146 (++) Any EXTI line (internal or external) configured in event mode if
147 cortex is configured with SEVONPEND = 0
148 (++) Any EXTI line configured in interrupt mode (even if the
149 corresponding EXTI Interrupt vector is disabled in the NVIC) if
150 cortex is configured with SEVONPEND = 0. The interrupt source can
151 be external interrupts or peripherals with wakeup capability.
152
153 *** Standby mode ***
154 ====================
155 [..]
156 (+) Entry:
157 (++) The Standby mode is entered through HAL_PWR_EnterSTANDBYMode() API, by
158 setting SLEEPDEEP in Cortex control register.
159 (+) Exit:
160 (++) WKUP pin edge detection, RTC event (alarm, timestamp),
161 LSE CSS detection, reset on NRST pin, IWDG reset & BOR reset.
162 [..] Exiting Standby generates a power reset: Cortex is reset and execute
163 Reset handler vector, all registers in the Vcore domain are set to
164 their reset value. Registers outside the VCORE domain (RTC, WKUP, IWDG,
165 and Standby/Shutdown modes control) are not impacted.
166
167 *** Shutdown mode ***
168 ======================
169 [..]
170 In Shutdown mode,
171 voltage regulator is disabled, all clocks are off except LSE, RRS bit is
172 cleared. SRAM and registers contents are lost except for backup domain
173 registers.
174 (+) Entry:
175 (++) The Shutdown mode is entered through HAL_PWREx_EnterSHUTDOWNMode() API,
176 by setting SLEEPDEEP in Cortex control register.
177 (+) Exit:
178 (++) WKUP pin edge detection, RTC event (alarm, timestamp),
179 LSE CSS detection, reset on NRST pin.
180 [..] Exiting Shutdown generates a brown out reset: Cortex is reset and execute
181 Reset handler vector, all registers are set to their reset value but ones
182 in backup domain.
183
184 @endverbatim
185 * @{
186 */
187
188
189 /**
190 * @brief Enable the WakeUp PINx functionality.
191 * @param WakeUpPinPolarity Specifies which Wake-Up pin to enable.
192 * This parameter can be one of the following legacy values which set
193 * the default polarity i.e. detection on high level (rising edge):
194 * @arg @ref PWR_WAKEUP_PIN1, PWR_WAKEUP_PIN2, PWR_WAKEUP_PIN3,
195 * PWR_WAKEUP_PIN4, PWR_WAKEUP_PIN6
196 * or one of the following value where the user can explicitly specify
197 * the enabled pin and the chosen polarity:
198 * @arg @ref PWR_WAKEUP_PIN1_HIGH or PWR_WAKEUP_PIN1_LOW
199 * @arg @ref PWR_WAKEUP_PIN2_HIGH or PWR_WAKEUP_PIN2_LOW
200 * @arg @ref PWR_WAKEUP_PIN3_HIGH or PWR_WAKEUP_PIN3_LOW
201 * @arg @ref PWR_WAKEUP_PIN4_HIGH or PWR_WAKEUP_PIN4_LOW
202 * @arg @ref PWR_WAKEUP_PIN6_HIGH or PWR_WAKEUP_PIN6_LOW
203 * @note PWR_WAKEUP_PINx and PWR_WAKEUP_PINx_HIGH are equivalent.
204 * @retval None
205 */
HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity)206 void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity)
207 {
208 assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinPolarity));
209
210 /* Specifies the Wake-Up pin polarity for the event detection
211 (rising or falling edge) */
212 MODIFY_REG(PWR->CR4, (PWR_CR4_WP & WakeUpPinPolarity), (WakeUpPinPolarity >> PWR_WUP_POLARITY_SHIFT));
213
214 /* Enable wake-up pin */
215 SET_BIT(PWR->CR3, (PWR_CR3_EWUP & WakeUpPinPolarity));
216 }
217
218
219 /**
220 * @brief Disable the WakeUp PINx functionality.
221 * @param WakeUpPinx Specifies the Power Wake-Up pin to disable.
222 * This parameter can be one of the following values:
223 * @arg @ref PWR_WAKEUP_PIN1, PWR_WAKEUP_PIN2, PWR_WAKEUP_PIN4,
224 * PWR_WAKEUP_PIN6
225 * @retval None
226 */
HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)227 void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
228 {
229 assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
230
231 CLEAR_BIT(PWR->CR3, (PWR_CR3_EWUP & WakeUpPinx));
232 }
233
234
235 /**
236 * @brief Enter Sleep mode.
237 * @note In Sleep mode, all I/O pins keep the same state as
238 * in Run mode.
239 * @param Regulator Specifies the regulator state in Sleep mode.
240 * This parameter can be the following value:
241 * @arg @ref PWR_MAINREGULATOR_ON Sleep mode (regulator in main mode)
242 * @param SLEEPEntry Specifies if Sleep mode is entered with WFI or WFE
243 * instruction. This parameter can be one of the following values:
244 * @arg @ref PWR_SLEEPENTRY_WFI enter Sleep or Low-power Sleep
245 * mode with WFI instruction
246 * @arg @ref PWR_SLEEPENTRY_WFE enter Sleep or Low-power Sleep
247 * mode with WFE instruction
248 * @note When WFI entry is used, tick interrupt have to be disabled if not
249 * desired as the interrupt wake up source.
250 * @retval None
251 */
HAL_PWR_EnterSLEEPMode(uint32_t Regulator,uint8_t SLEEPEntry)252 void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
253 {
254 /* Check the parameters */
255 assert_param(IS_PWR_REGULATOR(Regulator));
256 assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry));
257
258 /* Clear SLEEPDEEP bit of Cortex System Control Register */
259 CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
260
261 /* Select SLEEP mode entry -------------------------------------------------*/
262 if (SLEEPEntry == PWR_SLEEPENTRY_WFI)
263 {
264 /* Request Wait For Interrupt */
265 __WFI();
266 }
267 else
268 {
269 /* Request Wait For Event */
270 __SEV();
271 __WFE();
272 __WFE();
273 }
274 }
275
276
277 /**
278 * @brief Enter Stop mode
279 * @note This API is named HAL_PWR_EnterSTOPMode to ensure compatibility with
280 * legacy code running on devices where only "Stop mode" is mentioned
281 * with main regulator ON.
282 * @note In Stop mode, all I/O pins keep the same state as in Run mode.
283 * @note All clocks in the VCORE domain are stopped; the HSI and the
284 * HSE oscillators are disabled. Some peripherals with the wakeup
285 * capability can switch on the HSI to receive a frame, and switch off
286 * the HSI after receiving the frame if it is not a wakeup frame.
287 * SRAM and register contents are preserved.
288 * @note When exiting Stop 0 mode by issuing an interrupt or a
289 * wakeup event, the HSI RC oscillator is selected as system clock
290 * @param Regulator Specifies the regulator state in Stop mode
291 * This parameter can be of the following value:
292 * @arg @ref PWR_MAINREGULATOR_ON Stop 0 mode (main regulator ON)
293 * @param STOPEntry Specifies Stop 0 mode is entered with WFI or
294 * WFE instruction. This parameter can be one of the following values:
295 * @arg @ref PWR_STOPENTRY_WFI Enter Stop 0 mode with WFI
296 * instruction.
297 * @arg @ref PWR_STOPENTRY_WFE Enter Stop 0 mode with WFE
298 * instruction.
299 * @retval None
300 */
HAL_PWR_EnterSTOPMode(uint32_t Regulator,uint8_t STOPEntry)301 void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
302 {
303 /* Check the parameters */
304 assert_param(IS_PWR_REGULATOR(Regulator));
305 assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
306
307 MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_STOP0);
308
309 /* Set SLEEPDEEP bit of Cortex System Control Register */
310 SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
311
312 /* Select Stop mode entry --------------------------------------------------*/
313 if (STOPEntry == PWR_STOPENTRY_WFI)
314 {
315 /* Request Wait For Interrupt */
316 __WFI();
317 }
318 else
319 {
320 /* Request Wait For Event */
321 __SEV();
322 __WFE();
323 __WFE();
324 }
325
326 /* Reset SLEEPDEEP bit of Cortex System Control Register */
327 CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
328 }
329
330
331 /**
332 * @brief Enter Standby mode.
333 * @note In Standby mode,the HSI and the HSE oscillators are
334 * switched off. SRAM and register contents are lost except
335 * for registers in the Backup domain and Standby circuitry.
336 * @note The I/Os can be configured either with a pull-up or pull-down or can
337 * be kept in analog state.
338 * HAL_PWREx_EnableGPIOPullUp() and HAL_PWREx_EnableGPIOPullDown()
339 * respectively enable Pull Up and PullDown state.
340 * HAL_PWREx_DisableGPIOPullUp() & HAL_PWREx_DisableGPIOPullDown()
341 * disable the same. These states are effective in Standby mode only if
342 * APC bit is set through HAL_PWREx_EnablePullUpPullDownConfig() API.
343 * @retval None
344 */
HAL_PWR_EnterSTANDBYMode(void)345 void HAL_PWR_EnterSTANDBYMode(void)
346 {
347 /* Set Stand-by mode */
348 MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_STANDBY);
349
350 /* Set SLEEPDEEP bit of Cortex System Control Register */
351 SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
352
353 /* Request Wait For Interrupt */
354 __WFI();
355 }
356
357
358 /**
359 * @brief Enable Sleep-On-Exit Cortex feature
360 * @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the
361 * processor enters SLEEP or DEEPSLEEP mode when an interruption
362 * handling is over returning to thread mode. Setting this bit is
363 * useful when the processor is expected to run only on interruptions
364 * handling.
365 * @retval None
366 */
HAL_PWR_EnableSleepOnExit(void)367 void HAL_PWR_EnableSleepOnExit(void)
368 {
369 /* Set SLEEPONEXIT bit of Cortex System Control Register */
370 SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
371 }
372
373
374 /**
375 * @brief Disable Sleep-On-Exit Cortex feature
376 * @note Clear SLEEPONEXIT bit of SCR register. When this bit is set, the
377 * processor enters SLEEP or DEEPSLEEP mode when an interruption
378 * handling is over.
379 * @retval None
380 */
HAL_PWR_DisableSleepOnExit(void)381 void HAL_PWR_DisableSleepOnExit(void)
382 {
383 /* Clear SLEEPONEXIT bit of Cortex System Control Register */
384 CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
385 }
386
387
388 /**
389 * @brief Enable Cortex Sev On Pending feature.
390 * @note Set SEVONPEND bit of SCR register. When this bit is set, enabled
391 * events and all interrupts, including disabled ones can wakeup
392 * processor from WFE.
393 * @retval None
394 */
HAL_PWR_EnableSEVOnPend(void)395 void HAL_PWR_EnableSEVOnPend(void)
396 {
397 /* Set SEVONPEND bit of Cortex System Control Register */
398 SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
399 }
400
401
402 /**
403 * @brief Disable Cortex Sev On Pending feature.
404 * @note Clear SEVONPEND bit of SCR register. When this bit is clear, only
405 * enable interrupts or events can wakeup processor from WFE
406 * @retval None
407 */
HAL_PWR_DisableSEVOnPend(void)408 void HAL_PWR_DisableSEVOnPend(void)
409 {
410 /* Clear SEVONPEND bit of Cortex System Control Register */
411 CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
412 }
413
414 /**
415 * @}
416 */
417
418 /**
419 * @}
420 */
421
422 #endif /* HAL_PWR_MODULE_ENABLED */
423 /**
424 * @}
425 */
426
427 /**
428 * @}
429 */
430