1 /**
2   ******************************************************************************
3   * @file    system_stm32h7xx.c
4   * @author  MCD Application Team
5   * @brief   CMSIS Cortex-Mx Device Peripheral Access Layer System Source File.
6   *
7   *   This file provides two functions and one global variable to be called from
8   *   user application:
9   *      - ExitRun0Mode(): Specifies the Power Supply source. This function is
10   *                        called at startup just after reset and before the call
11   *                        of SystemInit(). This call is made inside
12   *                        the "startup_stm32h7xx.s" file.
13   *
14   *      - SystemInit(): This function is called at startup just after reset and
15   *                      before branch to main program. This call is made inside
16   *                      the "startup_stm32h7xx.s" file.
17   *
18   *      - SystemCoreClock variable: Contains the core clock, it can be used
19   *                                  by the user application to setup the SysTick
20   *                                  timer or configure other parameters.
21   *
22   *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
23   *                                 be called whenever the core clock is changed
24   *                                 during program execution.
25   *
26   *
27   ******************************************************************************
28   * @attention
29   *
30   * Copyright (c) 2017 STMicroelectronics.
31   * All rights reserved.
32   *
33   * This software is licensed under terms that can be found in the LICENSE file
34   * in the root directory of this software component.
35   * If no LICENSE file comes with this software, it is provided AS-IS.
36   *
37   ******************************************************************************
38   */
39 
40 /** @addtogroup CMSIS
41   * @{
42   */
43 
44 /** @addtogroup stm32h7xx_system
45   * @{
46   */
47 
48 /** @addtogroup STM32H7xx_System_Private_Includes
49   * @{
50   */
51 
52 #include "stm32h7xx.h"
53 #include <math.h>
54 
55 #if !defined  (HSE_VALUE)
56 #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
57 #endif /* HSE_VALUE */
58 
59 #if !defined  (CSI_VALUE)
60   #define CSI_VALUE    ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/
61 #endif /* CSI_VALUE */
62 
63 #if !defined  (HSI_VALUE)
64   #define HSI_VALUE    ((uint32_t)64000000) /*!< Value of the Internal oscillator in Hz*/
65 #endif /* HSI_VALUE */
66 
67 
68 /**
69   * @}
70   */
71 
72 /** @addtogroup STM32H7xx_System_Private_TypesDefinitions
73   * @{
74   */
75 
76 /**
77   * @}
78   */
79 
80 /** @addtogroup STM32H7xx_System_Private_Defines
81   * @{
82   */
83 
84 /************************* Miscellaneous Configuration ************************/
85 /*!< Uncomment the following line if you need to use initialized data in D2 domain SRAM (AHB SRAM) */
86 /* #define DATA_IN_D2_SRAM */
87 
88 /* Note: Following vector table addresses must be defined in line with linker
89          configuration. */
90 /*!< Uncomment the following line if you need to relocate the vector table
91      anywhere in FLASH BANK1 or AXI SRAM, else the vector table is kept at the automatic
92      remap of boot address selected */
93 /* #define USER_VECT_TAB_ADDRESS */
94 
95 #if defined(USER_VECT_TAB_ADDRESS)
96 #if defined(DUAL_CORE) && defined(CORE_CM4)
97 /*!< Uncomment the following line if you need to relocate your vector Table
98      in D2 AXI SRAM else user remap will be done in FLASH BANK2. */
99 /* #define VECT_TAB_SRAM */
100 #if defined(VECT_TAB_SRAM)
101 #define VECT_TAB_BASE_ADDRESS   D2_AXISRAM_BASE   /*!< Vector Table base address field.
102                                                        This value must be a multiple of 0x400. */
103 #define VECT_TAB_OFFSET         0x00000000U       /*!< Vector Table base offset field.
104                                                        This value must be a multiple of 0x400. */
105 #else
106 #define VECT_TAB_BASE_ADDRESS   FLASH_BANK2_BASE  /*!< Vector Table base address field.
107                                                        This value must be a multiple of 0x400. */
108 #define VECT_TAB_OFFSET         0x00000000U       /*!< Vector Table base offset field.
109                                                        This value must be a multiple of 0x400. */
110 #endif /* VECT_TAB_SRAM */
111 #else
112 /*!< Uncomment the following line if you need to relocate your vector Table
113      in D1 AXI SRAM else user remap will be done in FLASH BANK1. */
114 /* #define VECT_TAB_SRAM */
115 #if defined(VECT_TAB_SRAM)
116 #define VECT_TAB_BASE_ADDRESS   D1_AXISRAM_BASE   /*!< Vector Table base address field.
117                                                        This value must be a multiple of 0x400. */
118 #define VECT_TAB_OFFSET         0x00000000U       /*!< Vector Table base offset field.
119                                                        This value must be a multiple of 0x400. */
120 #else
121 #define VECT_TAB_BASE_ADDRESS   FLASH_BANK1_BASE  /*!< Vector Table base address field.
122                                                        This value must be a multiple of 0x400. */
123 #define VECT_TAB_OFFSET         0x00000000U       /*!< Vector Table base offset field.
124                                                        This value must be a multiple of 0x400. */
125 #endif /* VECT_TAB_SRAM */
126 #endif /* DUAL_CORE && CORE_CM4 */
127 #endif /* USER_VECT_TAB_ADDRESS */
128 /******************************************************************************/
129 
130 /**
131   * @}
132   */
133 
134 /** @addtogroup STM32H7xx_System_Private_Macros
135   * @{
136   */
137 
138 /**
139   * @}
140   */
141 
142 /** @addtogroup STM32H7xx_System_Private_Variables
143   * @{
144   */
145   /* This variable is updated in three ways:
146       1) by calling CMSIS function SystemCoreClockUpdate()
147       2) by calling HAL API function HAL_RCC_GetHCLKFreq()
148       3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
149          Note: If you use this function to configure the system clock; then there
150                is no need to call the 2 first functions listed above, since SystemCoreClock
151                variable is updated automatically.
152   */
153   uint32_t SystemCoreClock = 64000000;
154   uint32_t SystemD2Clock = 64000000;
155   const  uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
156 
157 /**
158   * @}
159   */
160 
161 /** @addtogroup STM32H7xx_System_Private_FunctionPrototypes
162   * @{
163   */
164 
165 /**
166   * @}
167   */
168 
169 /** @addtogroup STM32H7xx_System_Private_Functions
170   * @{
171   */
172 
173 /**
174   * @brief  Setup the microcontroller system
175   *         Initialize the FPU setting and  vector table location
176   *         configuration.
177   * @param  None
178   * @retval None
179   */
SystemInit(void)180 void SystemInit (void)
181 {
182 #if defined (DATA_IN_D2_SRAM)
183  __IO uint32_t tmpreg;
184 #endif /* DATA_IN_D2_SRAM */
185 
186   /* FPU settings ------------------------------------------------------------*/
187   #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
188     SCB->CPACR |= ((3UL << (10*2))|(3UL << (11*2)));  /* set CP10 and CP11 Full Access */
189   #endif
190   /* Reset the RCC clock configuration to the default reset state ------------*/
191 
192    /* Increasing the CPU frequency */
193   if(FLASH_LATENCY_DEFAULT  > (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY)))
194   {
195     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
196     MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, (uint32_t)(FLASH_LATENCY_DEFAULT));
197   }
198 
199   /* Set HSION bit */
200   RCC->CR |= RCC_CR_HSION;
201 
202   /* Reset CFGR register */
203   RCC->CFGR = 0x00000000;
204 
205   /* Reset HSEON, HSECSSON, CSION, HSI48ON, CSIKERON, PLL1ON, PLL2ON and PLL3ON bits */
206   RCC->CR &= 0xEAF6ED7FU;
207 
208    /* Decreasing the number of wait states because of lower CPU frequency */
209   if(FLASH_LATENCY_DEFAULT  < (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY)))
210   {
211     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
212     MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, (uint32_t)(FLASH_LATENCY_DEFAULT));
213   }
214 
215 #if defined(D3_SRAM_BASE)
216   /* Reset D1CFGR register */
217   RCC->D1CFGR = 0x00000000;
218 
219   /* Reset D2CFGR register */
220   RCC->D2CFGR = 0x00000000;
221 
222   /* Reset D3CFGR register */
223   RCC->D3CFGR = 0x00000000;
224 #else
225   /* Reset CDCFGR1 register */
226   RCC->CDCFGR1 = 0x00000000;
227 
228   /* Reset CDCFGR2 register */
229   RCC->CDCFGR2 = 0x00000000;
230 
231   /* Reset SRDCFGR register */
232   RCC->SRDCFGR = 0x00000000;
233 #endif
234   /* Reset PLLCKSELR register */
235   RCC->PLLCKSELR = 0x02020200;
236 
237   /* Reset PLLCFGR register */
238   RCC->PLLCFGR = 0x01FF0000;
239   /* Reset PLL1DIVR register */
240   RCC->PLL1DIVR = 0x01010280;
241   /* Reset PLL1FRACR register */
242   RCC->PLL1FRACR = 0x00000000;
243 
244   /* Reset PLL2DIVR register */
245   RCC->PLL2DIVR = 0x01010280;
246 
247   /* Reset PLL2FRACR register */
248 
249   RCC->PLL2FRACR = 0x00000000;
250   /* Reset PLL3DIVR register */
251   RCC->PLL3DIVR = 0x01010280;
252 
253   /* Reset PLL3FRACR register */
254   RCC->PLL3FRACR = 0x00000000;
255 
256   /* Reset HSEBYP bit */
257   RCC->CR &= 0xFFFBFFFFU;
258 
259   /* Disable all interrupts */
260   RCC->CIER = 0x00000000;
261 
262 #if (STM32H7_DEV_ID == 0x450UL)
263   /* dual core CM7 or single core line */
264   if((DBGMCU->IDCODE & 0xFFFF0000U) < 0x20000000U)
265   {
266     /* if stm32h7 revY*/
267     /* Change  the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */
268     *((__IO uint32_t*)0x51008108) = 0x000000001U;
269   }
270 #endif /* STM32H7_DEV_ID */
271 
272 #if defined(DATA_IN_D2_SRAM)
273   /* in case of initialized data in D2 SRAM (AHB SRAM), enable the D2 SRAM clock (AHB SRAM clock) */
274 #if defined(RCC_AHB2ENR_D2SRAM3EN)
275   RCC->AHB2ENR |= (RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN | RCC_AHB2ENR_D2SRAM3EN);
276 #elif defined(RCC_AHB2ENR_D2SRAM2EN)
277   RCC->AHB2ENR |= (RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN);
278 #else
279   RCC->AHB2ENR |= (RCC_AHB2ENR_AHBSRAM1EN | RCC_AHB2ENR_AHBSRAM2EN);
280 #endif /* RCC_AHB2ENR_D2SRAM3EN */
281 
282   tmpreg = RCC->AHB2ENR;
283   (void) tmpreg;
284 #endif /* DATA_IN_D2_SRAM */
285 
286 #if defined(DUAL_CORE) && defined(CORE_CM4)
287   /* Configure the Vector Table location add offset address for cortex-M4 ------------------*/
288 #if defined(USER_VECT_TAB_ADDRESS)
289   SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal D2 AXI-RAM or in Internal FLASH */
290 #endif /* USER_VECT_TAB_ADDRESS */
291 
292 #else
293   /*
294    * Disable the FMC bank1 (enabled after reset).
295    * This, prevents CPU speculation access on this bank which blocks the use of FMC during
296    * 24us. During this time the others FMC master (such as LTDC) cannot use it!
297    */
298   FMC_Bank1_R->BTCR[0] = 0x000030D2;
299 
300   /* Configure the Vector Table location -------------------------------------*/
301 #if defined(USER_VECT_TAB_ADDRESS)
302   SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal D1 AXI-RAM or in Internal FLASH */
303 #endif /* USER_VECT_TAB_ADDRESS */
304 
305 #endif /*DUAL_CORE && CORE_CM4*/
306 }
307 
308 /**
309   * @brief  Update SystemCoreClock variable according to Clock Register Values.
310   *         The SystemCoreClock variable contains the core clock , it can
311   *         be used by the user application to setup the SysTick timer or configure
312   *         other parameters.
313   *
314   * @note   Each time the core clock changes, this function must be called
315   *         to update SystemCoreClock variable value. Otherwise, any configuration
316   *         based on this variable will be incorrect.
317   *
318   * @note   - The system frequency computed by this function is not the real
319   *           frequency in the chip. It is calculated based on the predefined
320   *           constant and the selected clock source:
321   *
322   *           - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*)
323   *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
324   *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
325   *           - If SYSCLK source is PLL, SystemCoreClock will contain the CSI_VALUE(*),
326   *             HSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
327   *
328   *         (*) CSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value
329   *             4 MHz) but the real value may vary depending on the variations
330   *             in voltage and temperature.
331   *         (**) HSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value
332   *             64 MHz) but the real value may vary depending on the variations
333   *             in voltage and temperature.
334   *
335   *         (***)HSE_VALUE is a constant defined in stm32h7xx_hal.h file (default value
336   *              25 MHz), user has to ensure that HSE_VALUE is same as the real
337   *              frequency of the crystal used. Otherwise, this function may
338   *              have wrong result.
339   *
340   *         - The result of this function could be not correct when using fractional
341   *           value for HSE crystal.
342   * @param  None
343   * @retval None
344   */
SystemCoreClockUpdate(void)345 void SystemCoreClockUpdate (void)
346 {
347   uint32_t pllp, pllsource, pllm, pllfracen, hsivalue, tmp;
348   uint32_t common_system_clock;
349   float_t fracn1, pllvco;
350 
351 
352   /* Get SYSCLK source -------------------------------------------------------*/
353 
354   switch (RCC->CFGR & RCC_CFGR_SWS)
355   {
356   case RCC_CFGR_SWS_HSI:  /* HSI used as system clock source */
357     common_system_clock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3));
358     break;
359 
360   case RCC_CFGR_SWS_CSI:  /* CSI used as system clock  source */
361     common_system_clock = CSI_VALUE;
362     break;
363 
364   case RCC_CFGR_SWS_HSE:  /* HSE used as system clock  source */
365     common_system_clock = HSE_VALUE;
366     break;
367 
368   case RCC_CFGR_SWS_PLL1:  /* PLL1 used as system clock  source */
369 
370     /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
371     SYSCLK = PLL_VCO / PLLR
372     */
373     pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
374     pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1)>> 4)  ;
375     pllfracen = ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN)>>RCC_PLLCFGR_PLL1FRACEN_Pos);
376     fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN1)>> 3));
377 
378     if (pllm != 0U)
379     {
380       switch (pllsource)
381       {
382         case RCC_PLLCKSELR_PLLSRC_HSI:  /* HSI used as PLL clock source */
383 
384         hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ;
385         pllvco = ( (float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
386 
387         break;
388 
389         case RCC_PLLCKSELR_PLLSRC_CSI:  /* CSI used as PLL clock source */
390           pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
391         break;
392 
393         case RCC_PLLCKSELR_PLLSRC_HSE:  /* HSE used as PLL clock source */
394           pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
395         break;
396 
397       default:
398           hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ;
399           pllvco = ((float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
400         break;
401       }
402       pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_P1) >>9) + 1U ) ;
403       common_system_clock =  (uint32_t)(float_t)(pllvco/(float_t)pllp);
404     }
405     else
406     {
407       common_system_clock = 0U;
408     }
409     break;
410 
411   default:
412     common_system_clock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3));
413     break;
414   }
415 
416   /* Compute SystemClock frequency --------------------------------------------------*/
417 #if defined (RCC_D1CFGR_D1CPRE)
418   tmp = D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_D1CPRE)>> RCC_D1CFGR_D1CPRE_Pos];
419 
420   /* common_system_clock frequency : CM7 CPU frequency  */
421   common_system_clock >>= tmp;
422 
423   /* SystemD2Clock frequency : CM4 CPU, AXI and AHBs Clock frequency  */
424   SystemD2Clock = (common_system_clock >> ((D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_HPRE)>> RCC_D1CFGR_HPRE_Pos]) & 0x1FU));
425 
426 #else
427   tmp = D1CorePrescTable[(RCC->CDCFGR1 & RCC_CDCFGR1_CDCPRE)>> RCC_CDCFGR1_CDCPRE_Pos];
428 
429   /* common_system_clock frequency : CM7 CPU frequency  */
430   common_system_clock >>= tmp;
431 
432   /* SystemD2Clock frequency : AXI and AHBs Clock frequency  */
433   SystemD2Clock = (common_system_clock >> ((D1CorePrescTable[(RCC->CDCFGR1 & RCC_CDCFGR1_HPRE)>> RCC_CDCFGR1_HPRE_Pos]) & 0x1FU));
434 
435 #endif
436 
437 #if defined(DUAL_CORE) && defined(CORE_CM4)
438   SystemCoreClock = SystemD2Clock;
439 #else
440   SystemCoreClock = common_system_clock;
441 #endif /* DUAL_CORE && CORE_CM4 */
442 }
443 
444 /**
445   * @brief  Exit Run* mode and Configure the system Power Supply
446   *
447   * @note   This function exits the Run* mode and configures the system power supply
448   *         according to the definition to be used at compilation preprocessing level.
449   *         The application shall set one of the following configuration option:
450   *           - PWR_LDO_SUPPLY
451   *           - PWR_DIRECT_SMPS_SUPPLY
452   *           - PWR_EXTERNAL_SOURCE_SUPPLY
453   *           - PWR_SMPS_1V8_SUPPLIES_LDO
454   *           - PWR_SMPS_2V5_SUPPLIES_LDO
455   *           - PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO
456   *           - PWR_SMPS_2V5_SUPPLIES_EXT_AND_LDO
457   *           - PWR_SMPS_1V8_SUPPLIES_EXT
458   *           - PWR_SMPS_2V5_SUPPLIES_EXT
459   *
460   * @note   The function modifies the PWR->CR3 register to enable or disable specific
461   *         power supply modes and waits until the voltage level flag is set, indicating
462   *         that the power supply configuration is stable.
463   *
464   * @param  None
465   * @retval None
466   */
ExitRun0Mode(void)467 void ExitRun0Mode(void)
468 {
469 #if defined(USE_PWR_LDO_SUPPLY)
470   #if defined(SMPS)
471     /* Exit Run* mode by disabling SMPS and enabling LDO */
472     PWR->CR3 = (PWR->CR3 & ~PWR_CR3_SMPSEN) | PWR_CR3_LDOEN;
473   #else
474     /* Enable LDO mode */
475     PWR->CR3 |= PWR_CR3_LDOEN;
476   #endif /* SMPS */
477   /* Wait till voltage level flag is set */
478   while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0U)
479   {}
480 #elif defined(USE_PWR_EXTERNAL_SOURCE_SUPPLY)
481   #if defined(SMPS)
482     /* Exit Run* mode */
483     PWR->CR3 = (PWR->CR3 & ~(PWR_CR3_SMPSEN | PWR_CR3_LDOEN)) | PWR_CR3_BYPASS;
484   #else
485     PWR->CR3 = (PWR->CR3 & ~(PWR_CR3_LDOEN)) | PWR_CR3_BYPASS;
486   #endif /* SMPS */
487   /* Wait till voltage level flag is set */
488   while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0U)
489   {}
490 #elif defined(USE_PWR_DIRECT_SMPS_SUPPLY) && defined(SMPS)
491   /* Exit Run* mode */
492   PWR->CR3 &= ~(PWR_CR3_LDOEN);
493   /* Wait till voltage level flag is set */
494   while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0U)
495   {}
496 #elif defined(USE_PWR_SMPS_1V8_SUPPLIES_LDO) && defined(SMPS)
497   /* Exit Run* mode */
498   PWR->CR3 |= PWR_CR3_SMPSLEVEL_0 | PWR_CR3_SMPSEN | PWR_CR3_LDOEN;
499   /* Wait till voltage level flag is set */
500   while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0U)
501   {}
502 #elif defined(USE_PWR_SMPS_2V5_SUPPLIES_LDO) && defined(SMPS)
503   /* Exit Run* mode */
504   PWR->CR3 |= PWR_CR3_SMPSLEVEL_1 | PWR_CR3_SMPSEN | PWR_CR3_LDOEN;
505   /* Wait till voltage level flag is set */
506   while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0U)
507   {}
508 #elif defined(USE_PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO) && defined(SMPS)
509   /* Exit Run* mode */
510   PWR->CR3 |= PWR_CR3_SMPSLEVEL_0 | PWR_CR3_SMPSEXTHP | PWR_CR3_SMPSEN | PWR_CR3_LDOEN;
511   /* Wait till voltage level flag is set */
512   while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0U)
513   {}
514 #elif defined(USE_PWR_SMPS_2V5_SUPPLIES_EXT_AND_LDO) && defined(SMPS)
515   /* Exit Run* mode */
516   PWR->CR3 |= PWR_CR3_SMPSLEVEL_1 | PWR_CR3_SMPSEXTHP | PWR_CR3_SMPSEN | PWR_CR3_LDOEN;
517   /* Wait till voltage level flag is set */
518   while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0U)
519   {}
520 #elif defined(USE_PWR_SMPS_1V8_SUPPLIES_EXT) && defined(SMPS)
521   /* Exit Run* mode */
522   PWR->CR3 = (PWR->CR3 & ~(PWR_CR3_LDOEN)) | PWR_CR3_SMPSLEVEL_0 | PWR_CR3_SMPSEXTHP | PWR_CR3_SMPSEN | PWR_CR3_BYPASS;
523   /* Wait till voltage level flag is set */
524   while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0U)
525   {}
526 #elif defined(USE_PWR_SMPS_2V5_SUPPLIES_EXT) && defined(SMPS)
527   /* Exit Run* mode */
528   PWR->CR3 = (PWR->CR3 & ~(PWR_CR3_LDOEN)) | PWR_CR3_SMPSLEVEL_1 | PWR_CR3_SMPSEXTHP | PWR_CR3_SMPSEN | PWR_CR3_BYPASS;
529   /* Wait till voltage level flag is set */
530   while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0U)
531   {}
532 #else
533   /* No system power supply configuration is selected at exit Run* mode */
534 #endif /* USE_PWR_LDO_SUPPLY */
535 }
536 
537 /**
538   * @}
539   */
540 
541 /**
542   * @}
543   */
544 
545 /**
546   * @}
547   */
548