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 * @brief Enable the WakeUp PINx functionality.
190 * @param WakeUpPinPolarity Specifies which Wake-Up pin to enable.
191 * This parameter can be one of the following legacy values which set
192 * the default polarity i.e. detection on high level (rising edge):
193 * @arg @ref PWR_WAKEUP_PIN1, PWR_WAKEUP_PIN2, PWR_WAKEUP_PIN3,
194 * PWR_WAKEUP_PIN4, PWR_WAKEUP_PIN5 (Only on STM32C071xx), PWR_WAKEUP_PIN6
195 * or one of the following value where the user can explicitly specify
196 * the enabled pin and the chosen polarity:
197 * @arg @ref PWR_WAKEUP_PIN1_HIGH or PWR_WAKEUP_PIN1_LOW
198 * @arg @ref PWR_WAKEUP_PIN2_HIGH or PWR_WAKEUP_PIN2_LOW
199 * @arg @ref PWR_WAKEUP_PIN3_HIGH or PWR_WAKEUP_PIN3_LOW
200 * @arg @ref PWR_WAKEUP_PIN4_HIGH or PWR_WAKEUP_PIN4_LOW
201 * @arg @ref PWR_WAKEUP_PIN5_HIGH or PWR_WAKEUP_PIN5_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 * @note (*) Availability depends on devices
205 * @retval None
206 */
HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity)207 void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity)
208 {
209 assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinPolarity));
210
211 /* Specifies the Wake-Up pin polarity for the event detection
212 (rising or falling edge) */
213 MODIFY_REG(PWR->CR4, (PWR_CR4_WP & WakeUpPinPolarity), (WakeUpPinPolarity >> PWR_WUP_POLARITY_SHIFT));
214
215 /* Enable wake-up pin */
216 SET_BIT(PWR->CR3, (PWR_CR3_EWUP & WakeUpPinPolarity));
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_PIN3,
224 * PWR_WAKEUP_PIN4, PWR_WAKEUP_PIN5 (*), PWR_WAKEUP_PIN6
225 * @note (*) Availability depends on devices
226 * @retval None
227 */
HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)228 void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
229 {
230 assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
231
232 CLEAR_BIT(PWR->CR3, (PWR_CR3_EWUP & WakeUpPinx));
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 * @brief Enter Stop mode
278 * @note This API is named HAL_PWR_EnterSTOPMode to ensure compatibility with
279 * legacy code running on devices where only "Stop mode" is mentioned
280 * with main regulator ON.
281 * @note In Stop mode, all I/O pins keep the same state as in Run mode.
282 * @note All clocks in the VCORE domain are stopped; the HSI and the
283 * HSE oscillators are disabled. Some peripherals with the wakeup
284 * capability can switch on the HSI to receive a frame, and switch off
285 * the HSI after receiving the frame if it is not a wakeup frame.
286 * SRAM and register contents are preserved.
287 * @note When exiting Stop 0 mode by issuing an interrupt or a
288 * wakeup event, the HSI RC oscillator is selected as system clock
289 * @param Regulator Specifies the regulator state in Stop mode
290 * This parameter can be of the following value:
291 * @arg @ref PWR_MAINREGULATOR_ON Stop 0 mode (main regulator ON)
292 * @param STOPEntry Specifies Stop 0 mode is entered with WFI or
293 * WFE instruction. This parameter can be one of the following values:
294 * @arg @ref PWR_STOPENTRY_WFI Enter Stop 0 mode with WFI
295 * instruction.
296 * @arg @ref PWR_STOPENTRY_WFE Enter Stop 0 mode with WFE
297 * instruction.
298 * @retval None
299 */
HAL_PWR_EnterSTOPMode(uint32_t Regulator,uint8_t STOPEntry)300 void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
301 {
302 /* Check the parameters */
303 assert_param(IS_PWR_REGULATOR(Regulator));
304 assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
305
306 MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_STOP0);
307
308 /* Set SLEEPDEEP bit of Cortex System Control Register */
309 SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
310
311 /* Select Stop mode entry --------------------------------------------------*/
312 if (STOPEntry == PWR_STOPENTRY_WFI)
313 {
314 /* Request Wait For Interrupt */
315 __WFI();
316 }
317 else
318 {
319 /* Request Wait For Event */
320 __SEV();
321 __WFE();
322 __WFE();
323 }
324
325 /* Reset SLEEPDEEP bit of Cortex System Control Register */
326 CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
327 }
328
329 /**
330 * @brief Enter Standby mode.
331 * @note In Standby mode,the HSI and the HSE oscillators are
332 * switched off. SRAM and register contents are lost except
333 * for registers in the Backup domain and Standby circuitry.
334 * @note The I/Os can be configured either with a pull-up or pull-down or can
335 * be kept in analog state.
336 * HAL_PWREx_EnableGPIOPullUp() and HAL_PWREx_EnableGPIOPullDown()
337 * respectively enable Pull Up and PullDown state.
338 * HAL_PWREx_DisableGPIOPullUp() & HAL_PWREx_DisableGPIOPullDown()
339 * disable the same. These states are effective in Standby mode only if
340 * APC bit is set through HAL_PWREx_EnablePullUpPullDownConfig() API.
341 * @retval None
342 */
HAL_PWR_EnterSTANDBYMode(void)343 void HAL_PWR_EnterSTANDBYMode(void)
344 {
345 /* Set Stand-by mode */
346 MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_STANDBY);
347
348 /* Set SLEEPDEEP bit of Cortex System Control Register */
349 SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
350
351 /* Request Wait For Interrupt */
352 __WFI();
353 }
354
355 /**
356 * @brief Enable Sleep-On-Exit Cortex feature
357 * @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the
358 * processor enters SLEEP or DEEPSLEEP mode when an interruption
359 * handling is over returning to thread mode. Setting this bit is
360 * useful when the processor is expected to run only on interruptions
361 * handling.
362 * @retval None
363 */
HAL_PWR_EnableSleepOnExit(void)364 void HAL_PWR_EnableSleepOnExit(void)
365 {
366 /* Set SLEEPONEXIT bit of Cortex System Control Register */
367 SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
368 }
369
370 /**
371 * @brief Disable Sleep-On-Exit Cortex feature
372 * @note Clear SLEEPONEXIT bit of SCR register. When this bit is set, the
373 * processor enters SLEEP or DEEPSLEEP mode when an interruption
374 * handling is over.
375 * @retval None
376 */
HAL_PWR_DisableSleepOnExit(void)377 void HAL_PWR_DisableSleepOnExit(void)
378 {
379 /* Clear SLEEPONEXIT bit of Cortex System Control Register */
380 CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
381 }
382
383 /**
384 * @brief Enable Cortex Sev On Pending feature.
385 * @note Set SEVONPEND bit of SCR register. When this bit is set, enabled
386 * events and all interrupts, including disabled ones can wakeup
387 * processor from WFE.
388 * @retval None
389 */
HAL_PWR_EnableSEVOnPend(void)390 void HAL_PWR_EnableSEVOnPend(void)
391 {
392 /* Set SEVONPEND bit of Cortex System Control Register */
393 SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
394 }
395
396 /**
397 * @brief Disable Cortex Sev On Pending feature.
398 * @note Clear SEVONPEND bit of SCR register. When this bit is clear, only
399 * enable interrupts or events can wakeup processor from WFE
400 * @retval None
401 */
HAL_PWR_DisableSEVOnPend(void)402 void HAL_PWR_DisableSEVOnPend(void)
403 {
404 /* Clear SEVONPEND bit of Cortex System Control Register */
405 CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
406 }
407
408 /**
409 * @}
410 */
411
412 /**
413 * @}
414 */
415
416 #endif /* HAL_PWR_MODULE_ENABLED */
417 /**
418 * @}
419 */
420
421 /**
422 * @}
423 */
424