1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_pwr_ex.c
4 * @author MCD Application Team
5 * @brief Extended PWR HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of PWR extension peripheral:
8 * + Peripheral Extended features functions
9 *
10 ******************************************************************************
11 * @attention
12 *
13 * Copyright (c) 2017 STMicroelectronics.
14 * All rights reserved.
15 *
16 * This software is licensed under terms that can be found in the LICENSE file
17 * in the root directory of this software component.
18 * If no LICENSE file comes with this software, it is provided AS-IS.
19 *
20 ******************************************************************************
21 */
22
23 /* Includes ------------------------------------------------------------------*/
24 #include "stm32f7xx_hal.h"
25
26 /** @addtogroup STM32F7xx_HAL_Driver
27 * @{
28 */
29
30 /** @defgroup PWREx PWREx
31 * @brief PWR HAL module driver
32 * @{
33 */
34
35 #ifdef HAL_PWR_MODULE_ENABLED
36
37 /* Private typedef -----------------------------------------------------------*/
38 /* Private define ------------------------------------------------------------*/
39 /** @addtogroup PWREx_Private_Constants
40 * @{
41 */
42 #define PWR_OVERDRIVE_TIMEOUT_VALUE 1000
43 #define PWR_UDERDRIVE_TIMEOUT_VALUE 1000
44 #define PWR_BKPREG_TIMEOUT_VALUE 1000
45 #define PWR_VOSRDY_TIMEOUT_VALUE 1000
46 /**
47 * @}
48 */
49
50 /* Private macro -------------------------------------------------------------*/
51 /* Private variables ---------------------------------------------------------*/
52 /* Private function prototypes -----------------------------------------------*/
53 /* Private functions ---------------------------------------------------------*/
54 /** @defgroup PWREx_Exported_Functions PWREx Exported Functions
55 * @{
56 */
57
58 /** @defgroup PWREx_Exported_Functions_Group1 Peripheral Extended features functions
59 * @brief Peripheral Extended features functions
60 *
61 @verbatim
62
63 ===============================================================================
64 ##### Peripheral extended features functions #####
65 ===============================================================================
66
67 *** Main and Backup Regulators configuration ***
68 ================================================
69 [..]
70 (+) The backup domain includes 4 Kbytes of backup SRAM accessible only from
71 the CPU, and address in 32-bit, 16-bit or 8-bit mode. Its content is
72 retained even in Standby or VBAT mode when the low power backup regulator
73 is enabled. It can be considered as an internal EEPROM when VBAT is
74 always present. You can use the HAL_PWREx_EnableBkUpReg() function to
75 enable the low power backup regulator.
76
77 (+) When the backup domain is supplied by VDD (analog switch connected to VDD)
78 the backup SRAM is powered from VDD which replaces the VBAT power supply to
79 save battery life.
80
81 (+) The backup SRAM is not mass erased by a tamper event. It is read
82 protected to prevent confidential data, such as cryptographic private
83 key, from being accessed. The backup SRAM can be erased only through
84 the Flash interface when a protection level change from level 1 to
85 level 0 is requested.
86 -@- Refer to the description of Read protection (RDP) in the Flash
87 programming manual.
88
89 (+) The main internal regulator can be configured to have a tradeoff between
90 performance and power consumption when the device does not operate at
91 the maximum frequency. This is done through __HAL_PWR_MAINREGULATORMODE_CONFIG()
92 macro which configure VOS bit in PWR_CR register
93
94 Refer to the product datasheets for more details.
95
96 *** FLASH Power Down configuration ****
97 =======================================
98 [..]
99 (+) By setting the FPDS bit in the PWR_CR register by using the
100 HAL_PWREx_EnableFlashPowerDown() function, the Flash memory also enters power
101 down mode when the device enters Stop mode. When the Flash memory
102 is in power down mode, an additional startup delay is incurred when
103 waking up from Stop mode.
104
105 *** Over-Drive and Under-Drive configuration ****
106 =================================================
107 [..]
108 (+) In Run mode: the main regulator has 2 operating modes available:
109 (++) Normal mode: The CPU and core logic operate at maximum frequency at a given
110 voltage scaling (scale 1, scale 2 or scale 3)
111 (++) Over-drive mode: This mode allows the CPU and the core logic to operate at a
112 higher frequency than the normal mode for a given voltage scaling (scale 1,
113 scale 2 or scale 3). This mode is enabled through HAL_PWREx_EnableOverDrive() function and
114 disabled by HAL_PWREx_DisableOverDrive() function, to enter or exit from Over-drive mode please follow
115 the sequence described in Reference manual.
116
117 (+) In Stop mode: the main regulator or low power regulator supplies a low power
118 voltage to the 1.2V domain, thus preserving the content of registers
119 and internal SRAM. 2 operating modes are available:
120 (++) Normal mode: the 1.2V domain is preserved in nominal leakage mode. This mode is only
121 available when the main regulator or the low power regulator is used in Scale 3 or
122 low voltage mode.
123 (++) Under-drive mode: the 1.2V domain is preserved in reduced leakage mode. This mode is only
124 available when the main regulator or the low power regulator is in low voltage mode.
125
126 @endverbatim
127 * @{
128 */
129
130 /**
131 * @brief Enables the Backup Regulator.
132 * @retval HAL status
133 */
HAL_PWREx_EnableBkUpReg(void)134 HAL_StatusTypeDef HAL_PWREx_EnableBkUpReg(void)
135 {
136 uint32_t tickstart = 0;
137
138 /* Enable Backup regulator */
139 PWR->CSR1 |= PWR_CSR1_BRE;
140
141 /* Workaround for the following hardware bug: */
142 /* Id 19: PWR : No STANDBY wake-up when Back-up RAM enabled (ref. Errata Sheet p23) */
143 PWR->CSR1 |= PWR_CSR1_EIWUP;
144
145 /* Get tick */
146 tickstart = HAL_GetTick();
147
148 /* Wait till Backup regulator ready flag is set */
149 while(__HAL_PWR_GET_FLAG(PWR_FLAG_BRR) == RESET)
150 {
151 if((HAL_GetTick() - tickstart ) > PWR_BKPREG_TIMEOUT_VALUE)
152 {
153 return HAL_TIMEOUT;
154 }
155 }
156 return HAL_OK;
157 }
158
159 /**
160 * @brief Disables the Backup Regulator.
161 * @retval HAL status
162 */
HAL_PWREx_DisableBkUpReg(void)163 HAL_StatusTypeDef HAL_PWREx_DisableBkUpReg(void)
164 {
165 uint32_t tickstart = 0;
166
167 /* Disable Backup regulator */
168 PWR->CSR1 &= (uint32_t)~((uint32_t)PWR_CSR1_BRE);
169
170 /* Workaround for the following hardware bug: */
171 /* Id 19: PWR : No STANDBY wake-up when Back-up RAM enabled (ref. Errata Sheet p23) */
172 PWR->CSR1 |= PWR_CSR1_EIWUP;
173
174 /* Get tick */
175 tickstart = HAL_GetTick();
176
177 /* Wait till Backup regulator ready flag is set */
178 while(__HAL_PWR_GET_FLAG(PWR_FLAG_BRR) != RESET)
179 {
180 if((HAL_GetTick() - tickstart ) > PWR_BKPREG_TIMEOUT_VALUE)
181 {
182 return HAL_TIMEOUT;
183 }
184 }
185 return HAL_OK;
186 }
187
188 /**
189 * @brief Enables the Flash Power Down in Stop mode.
190 * @retval None
191 */
HAL_PWREx_EnableFlashPowerDown(void)192 void HAL_PWREx_EnableFlashPowerDown(void)
193 {
194 /* Enable the Flash Power Down */
195 PWR->CR1 |= PWR_CR1_FPDS;
196 }
197
198 /**
199 * @brief Disables the Flash Power Down in Stop mode.
200 * @retval None
201 */
HAL_PWREx_DisableFlashPowerDown(void)202 void HAL_PWREx_DisableFlashPowerDown(void)
203 {
204 /* Disable the Flash Power Down */
205 PWR->CR1 &= (uint32_t)~((uint32_t)PWR_CR1_FPDS);
206 }
207
208 /**
209 * @brief Enables Main Regulator low voltage mode.
210 * @retval None
211 */
HAL_PWREx_EnableMainRegulatorLowVoltage(void)212 void HAL_PWREx_EnableMainRegulatorLowVoltage(void)
213 {
214 /* Enable Main regulator low voltage */
215 PWR->CR1 |= PWR_CR1_MRUDS;
216 }
217
218 /**
219 * @brief Disables Main Regulator low voltage mode.
220 * @retval None
221 */
HAL_PWREx_DisableMainRegulatorLowVoltage(void)222 void HAL_PWREx_DisableMainRegulatorLowVoltage(void)
223 {
224 /* Disable Main regulator low voltage */
225 PWR->CR1 &= (uint32_t)~((uint32_t)PWR_CR1_MRUDS);
226 }
227
228 /**
229 * @brief Enables Low Power Regulator low voltage mode.
230 * @retval None
231 */
HAL_PWREx_EnableLowRegulatorLowVoltage(void)232 void HAL_PWREx_EnableLowRegulatorLowVoltage(void)
233 {
234 /* Enable low power regulator */
235 PWR->CR1 |= PWR_CR1_LPUDS;
236 }
237
238 /**
239 * @brief Disables Low Power Regulator low voltage mode.
240 * @retval None
241 */
HAL_PWREx_DisableLowRegulatorLowVoltage(void)242 void HAL_PWREx_DisableLowRegulatorLowVoltage(void)
243 {
244 /* Disable low power regulator */
245 PWR->CR1 &= (uint32_t)~((uint32_t)PWR_CR1_LPUDS);
246 }
247
248 /**
249 * @brief Activates the Over-Drive mode.
250 * @note This mode allows the CPU and the core logic to operate at a higher frequency
251 * than the normal mode for a given voltage scaling (scale 1, scale 2 or scale 3).
252 * @note It is recommended to enter or exit Over-drive mode when the application is not running
253 * critical tasks and when the system clock source is either HSI or HSE.
254 * During the Over-drive switch activation, no peripheral clocks should be enabled.
255 * The peripheral clocks must be enabled once the Over-drive mode is activated.
256 * @retval HAL status
257 */
HAL_PWREx_EnableOverDrive(void)258 HAL_StatusTypeDef HAL_PWREx_EnableOverDrive(void)
259 {
260 uint32_t tickstart = 0;
261
262 __HAL_RCC_PWR_CLK_ENABLE();
263
264 /* Enable the Over-drive to extend the clock frequency to 216 MHz */
265 __HAL_PWR_OVERDRIVE_ENABLE();
266
267 /* Get tick */
268 tickstart = HAL_GetTick();
269
270 while(!__HAL_PWR_GET_FLAG(PWR_FLAG_ODRDY))
271 {
272 if((HAL_GetTick() - tickstart ) > PWR_OVERDRIVE_TIMEOUT_VALUE)
273 {
274 return HAL_TIMEOUT;
275 }
276 }
277
278 /* Enable the Over-drive switch */
279 __HAL_PWR_OVERDRIVESWITCHING_ENABLE();
280
281 /* Get tick */
282 tickstart = HAL_GetTick();
283
284 while(!__HAL_PWR_GET_FLAG(PWR_FLAG_ODSWRDY))
285 {
286 if((HAL_GetTick() - tickstart ) > PWR_OVERDRIVE_TIMEOUT_VALUE)
287 {
288 return HAL_TIMEOUT;
289 }
290 }
291 return HAL_OK;
292 }
293
294 /**
295 * @brief Deactivates the Over-Drive mode.
296 * @note This mode allows the CPU and the core logic to operate at a higher frequency
297 * than the normal mode for a given voltage scaling (scale 1, scale 2 or scale 3).
298 * @note It is recommended to enter or exit Over-drive mode when the application is not running
299 * critical tasks and when the system clock source is either HSI or HSE.
300 * During the Over-drive switch activation, no peripheral clocks should be enabled.
301 * The peripheral clocks must be enabled once the Over-drive mode is activated.
302 * @retval HAL status
303 */
HAL_PWREx_DisableOverDrive(void)304 HAL_StatusTypeDef HAL_PWREx_DisableOverDrive(void)
305 {
306 uint32_t tickstart = 0;
307
308 __HAL_RCC_PWR_CLK_ENABLE();
309
310 /* Disable the Over-drive switch */
311 __HAL_PWR_OVERDRIVESWITCHING_DISABLE();
312
313 /* Get tick */
314 tickstart = HAL_GetTick();
315
316 while(__HAL_PWR_GET_FLAG(PWR_FLAG_ODSWRDY))
317 {
318 if((HAL_GetTick() - tickstart ) > PWR_OVERDRIVE_TIMEOUT_VALUE)
319 {
320 return HAL_TIMEOUT;
321 }
322 }
323
324 /* Disable the Over-drive */
325 __HAL_PWR_OVERDRIVE_DISABLE();
326
327 /* Get tick */
328 tickstart = HAL_GetTick();
329
330 while(__HAL_PWR_GET_FLAG(PWR_FLAG_ODRDY))
331 {
332 if((HAL_GetTick() - tickstart ) > PWR_OVERDRIVE_TIMEOUT_VALUE)
333 {
334 return HAL_TIMEOUT;
335 }
336 }
337
338 return HAL_OK;
339 }
340
341 /**
342 * @brief Enters in Under-Drive STOP mode.
343 *
344 * @note This mode can be selected only when the Under-Drive is already active
345 *
346 * @note This mode is enabled only with STOP low power mode.
347 * In this mode, the 1.2V domain is preserved in reduced leakage mode. This
348 * mode is only available when the main regulator or the low power regulator
349 * is in low voltage mode
350 *
351 * @note If the Under-drive mode was enabled, it is automatically disabled after
352 * exiting Stop mode.
353 * When the voltage regulator operates in Under-drive mode, an additional
354 * startup delay is induced when waking up from Stop mode.
355 *
356 * @note In Stop mode, all I/O pins keep the same state as in Run mode.
357 *
358 * @note When exiting Stop mode by issuing an interrupt or a wakeup event,
359 * the HSI RC oscillator is selected as system clock.
360 *
361 * @note When the voltage regulator operates in low power mode, an additional
362 * startup delay is incurred when waking up from Stop mode.
363 * By keeping the internal regulator ON during Stop mode, the consumption
364 * is higher although the startup time is reduced.
365 *
366 * @param Regulator specifies the regulator state in STOP mode.
367 * This parameter can be one of the following values:
368 * @arg PWR_MAINREGULATOR_UNDERDRIVE_ON: Main Regulator in under-drive mode
369 * and Flash memory in power-down when the device is in Stop under-drive mode
370 * @arg PWR_LOWPOWERREGULATOR_UNDERDRIVE_ON: Low Power Regulator in under-drive mode
371 * and Flash memory in power-down when the device is in Stop under-drive mode
372 * @param STOPEntry specifies if STOP mode in entered with WFI or WFE instruction.
373 * This parameter can be one of the following values:
374 * @arg PWR_SLEEPENTRY_WFI: enter STOP mode with WFI instruction
375 * @arg PWR_SLEEPENTRY_WFE: enter STOP mode with WFE instruction
376 * @retval None
377 */
HAL_PWREx_EnterUnderDriveSTOPMode(uint32_t Regulator,uint8_t STOPEntry)378 HAL_StatusTypeDef HAL_PWREx_EnterUnderDriveSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
379 {
380 uint32_t tempreg = 0;
381 uint32_t tickstart = 0;
382
383 /* Check the parameters */
384 assert_param(IS_PWR_REGULATOR_UNDERDRIVE(Regulator));
385 assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
386
387 /* Enable Power ctrl clock */
388 __HAL_RCC_PWR_CLK_ENABLE();
389 /* Enable the Under-drive Mode ---------------------------------------------*/
390 /* Clear Under-drive flag */
391 __HAL_PWR_CLEAR_ODRUDR_FLAG();
392
393 /* Enable the Under-drive */
394 __HAL_PWR_UNDERDRIVE_ENABLE();
395
396 /* Get tick */
397 tickstart = HAL_GetTick();
398
399 /* Wait for UnderDrive mode is ready */
400 while(__HAL_PWR_GET_FLAG(PWR_FLAG_UDRDY))
401 {
402 if((HAL_GetTick() - tickstart ) > PWR_UDERDRIVE_TIMEOUT_VALUE)
403 {
404 return HAL_TIMEOUT;
405 }
406 }
407
408 /* Select the regulator state in STOP mode ---------------------------------*/
409 tempreg = PWR->CR1;
410 /* Clear PDDS, LPDS, MRLUDS and LPLUDS bits */
411 tempreg &= (uint32_t)~(PWR_CR1_PDDS | PWR_CR1_LPDS | PWR_CR1_LPUDS | PWR_CR1_MRUDS);
412
413 /* Set LPDS, MRLUDS and LPLUDS bits according to PWR_Regulator value */
414 tempreg |= Regulator;
415
416 /* Store the new value */
417 PWR->CR1 = tempreg;
418
419 /* Set SLEEPDEEP bit of Cortex System Control Register */
420 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
421
422 /* Select STOP mode entry --------------------------------------------------*/
423 if(STOPEntry == PWR_SLEEPENTRY_WFI)
424 {
425 /* Request Wait For Interrupt */
426 __WFI();
427 }
428 else
429 {
430 /* Request Wait For Event */
431 __WFE();
432 }
433 /* Reset SLEEPDEEP bit of Cortex System Control Register */
434 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
435
436 return HAL_OK;
437 }
438
439 /**
440 * @brief Returns Voltage Scaling Range.
441 * @retval VOS bit field (PWR_REGULATOR_VOLTAGE_SCALE1, PWR_REGULATOR_VOLTAGE_SCALE2 or
442 * PWR_REGULATOR_VOLTAGE_SCALE3)PWR_REGULATOR_VOLTAGE_SCALE1
443 */
HAL_PWREx_GetVoltageRange(void)444 uint32_t HAL_PWREx_GetVoltageRange(void)
445 {
446 return (PWR->CR1 & PWR_CR1_VOS);
447 }
448
449 /**
450 * @brief Configures the main internal regulator output voltage.
451 * @param VoltageScaling specifies the regulator output voltage to achieve
452 * a tradeoff between performance and power consumption.
453 * This parameter can be one of the following values:
454 * @arg PWR_REGULATOR_VOLTAGE_SCALE1: Regulator voltage output range 1 mode,
455 * typical output voltage at 1.4 V,
456 * system frequency up to 216 MHz.
457 * @arg PWR_REGULATOR_VOLTAGE_SCALE2: Regulator voltage output range 2 mode,
458 * typical output voltage at 1.2 V,
459 * system frequency up to 180 MHz.
460 * @arg PWR_REGULATOR_VOLTAGE_SCALE3: Regulator voltage output range 2 mode,
461 * typical output voltage at 1.00 V,
462 * system frequency up to 151 MHz.
463 * @note To update the system clock frequency(SYSCLK):
464 * - Set the HSI or HSE as system clock frequency using the HAL_RCC_ClockConfig().
465 * - Call the HAL_RCC_OscConfig() to configure the PLL.
466 * - Call HAL_PWREx_ConfigVoltageScaling() API to adjust the voltage scale.
467 * - Set the new system clock frequency using the HAL_RCC_ClockConfig().
468 * @note The scale can be modified only when the HSI or HSE clock source is selected
469 * as system clock source, otherwise the API returns HAL_ERROR.
470 * @note When the PLL is OFF, the voltage scale 3 is automatically selected and the VOS bits
471 * value in the PWR_CR1 register are not taken in account.
472 * @note This API forces the PLL state ON to allow the possibility to configure the voltage scale 1 or 2.
473 * @note The new voltage scale is active only when the PLL is ON.
474 * @retval HAL Status
475 */
HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling)476 HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling)
477 {
478 uint32_t tickstart = 0;
479
480 assert_param(IS_PWR_REGULATOR_VOLTAGE(VoltageScaling));
481
482 /* Enable Power ctrl clock */
483 __HAL_RCC_PWR_CLK_ENABLE();
484
485 /* Check if the PLL is used as system clock or not */
486 if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
487 {
488 /* Disable the main PLL */
489 __HAL_RCC_PLL_DISABLE();
490
491 /* Get Start Tick */
492 tickstart = HAL_GetTick();
493 /* Wait till PLL is disabled */
494 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
495 {
496 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
497 {
498 return HAL_TIMEOUT;
499 }
500 }
501
502 /* Set Range */
503 __HAL_PWR_VOLTAGESCALING_CONFIG(VoltageScaling);
504
505 /* Enable the main PLL */
506 __HAL_RCC_PLL_ENABLE();
507
508 /* Get Start Tick */
509 tickstart = HAL_GetTick();
510 /* Wait till PLL is ready */
511 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
512 {
513 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
514 {
515 return HAL_TIMEOUT;
516 }
517 }
518
519 /* Get Start Tick */
520 tickstart = HAL_GetTick();
521 while((__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY) == RESET))
522 {
523 if((HAL_GetTick() - tickstart ) > PWR_VOSRDY_TIMEOUT_VALUE)
524 {
525 return HAL_TIMEOUT;
526 }
527 }
528 }
529 else
530 {
531 return HAL_ERROR;
532 }
533 return HAL_OK;
534 }
535
536 /**
537 * @}
538 */
539
540 /**
541 * @}
542 */
543
544 #endif /* HAL_PWR_MODULE_ENABLED */
545 /**
546 * @}
547 */
548
549 /**
550 * @}
551 */
552
553