1 /** 2 ****************************************************************************** 3 * @file system_stm32wbxx.c 4 * @author MCD Application Team 5 * @brief CMSIS Cortex 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 * - SystemInit(): This function is called at startup just after reset and 10 * before branch to main program. This call is made inside 11 * the "startup_stm32wbxx.s" file. 12 * 13 * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used 14 * by the user application to setup the SysTick 15 * timer or configure other parameters. 16 * 17 * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must 18 * be called whenever the core clock is changed 19 * during program execution. 20 * 21 * After each device reset the MSI (4 MHz) is used as system clock source. 22 * Then SystemInit() function is called, in "startup_stm32wbxx.s" file, to 23 * configure the system clock before to branch to main program. 24 * 25 * This file configures the system clock as follows: 26 *============================================================================= 27 *----------------------------------------------------------------------------- 28 * System Clock source | MSI 29 *----------------------------------------------------------------------------- 30 * SYSCLK(Hz) | 4000000 31 *----------------------------------------------------------------------------- 32 * HCLK(Hz) | 4000000 33 *----------------------------------------------------------------------------- 34 * AHB Prescaler | 1 35 *----------------------------------------------------------------------------- 36 * APB1 Prescaler | 1 37 *----------------------------------------------------------------------------- 38 * APB2 Prescaler | 1 39 *----------------------------------------------------------------------------- 40 * PLL_M | 1 41 *----------------------------------------------------------------------------- 42 * PLL_N | 8 43 *----------------------------------------------------------------------------- 44 * PLL_P | 7 45 *----------------------------------------------------------------------------- 46 * PLL_Q | 2 47 *----------------------------------------------------------------------------- 48 * PLL_R | 2 49 *----------------------------------------------------------------------------- 50 * PLLSAI1_P | NA 51 *----------------------------------------------------------------------------- 52 * PLLSAI1_Q | NA 53 *----------------------------------------------------------------------------- 54 * PLLSAI1_R | NA 55 *----------------------------------------------------------------------------- 56 * Require 48MHz for USB OTG FS, | Disabled 57 * SDIO and RNG clock | 58 *----------------------------------------------------------------------------- 59 *============================================================================= 60 ****************************************************************************** 61 * @attention 62 * 63 * <h2><center>© Copyright (c) 2019 STMicroelectronics. 64 * All rights reserved.</center></h2> 65 * 66 * This software component is licensed by ST under BSD 3-Clause license, 67 * the "License"; You may not use this file except in compliance with the 68 * License. You may obtain a copy of the License at: 69 * opensource.org/licenses/BSD-3-Clause 70 * 71 ****************************************************************************** 72 */ 73 74 /** @addtogroup CMSIS 75 * @{ 76 */ 77 78 /** @addtogroup stm32WBxx_system 79 * @{ 80 */ 81 82 /** @addtogroup stm32WBxx_System_Private_Includes 83 * @{ 84 */ 85 86 #include "stm32wbxx.h" 87 88 #if !defined (HSE_VALUE) 89 #define HSE_VALUE (32000000UL) /*!< Value of the External oscillator in Hz */ 90 #endif /* HSE_VALUE */ 91 92 #if !defined (MSI_VALUE) 93 #define MSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/ 94 #endif /* MSI_VALUE */ 95 96 #if !defined (HSI_VALUE) 97 #define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/ 98 #endif /* HSI_VALUE */ 99 100 #if !defined (LSI_VALUE) 101 #define LSI_VALUE (32000UL) /*!< Value of LSI in Hz*/ 102 #endif /* LSI_VALUE */ 103 104 #if !defined (LSE_VALUE) 105 #define LSE_VALUE (32768UL) /*!< Value of LSE in Hz*/ 106 #endif /* LSE_VALUE */ 107 108 /** 109 * @} 110 */ 111 112 /** @addtogroup STM32WBxx_System_Private_TypesDefinitions 113 * @{ 114 */ 115 116 /** 117 * @} 118 */ 119 120 /** @addtogroup STM32WBxx_System_Private_Defines 121 * @{ 122 */ 123 124 /*!< Uncomment the following line if you need to relocate your vector Table in 125 Internal SRAM. */ 126 /* #define VECT_TAB_SRAM */ 127 #define VECT_TAB_OFFSET 0x0U /*!< Vector Table base offset field. 128 This value must be a multiple of 0x200. */ 129 130 #define VECT_TAB_BASE_ADDRESS SRAM1_BASE /*!< Vector Table base offset field. 131 This value must be a multiple of 0x200. */ 132 /** 133 * @} 134 */ 135 136 /** @addtogroup STM32WBxx_System_Private_Macros 137 * @{ 138 */ 139 140 /** 141 * @} 142 */ 143 144 /** @addtogroup STM32WBxx_System_Private_Variables 145 * @{ 146 */ 147 /* The SystemCoreClock variable is updated in three ways: 148 1) by calling CMSIS function SystemCoreClockUpdate() 149 2) by calling HAL API function HAL_RCC_GetHCLKFreq() 150 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency 151 Note: If you use this function to configure the system clock; then there 152 is no need to call the 2 first functions listed above, since SystemCoreClock 153 variable is updated automatically. 154 */ 155 uint32_t SystemCoreClock = 4000000UL ; /*CPU1: M4 on MSI clock after startup (4MHz)*/ 156 157 const uint32_t AHBPrescTable[16UL] = {1UL, 3UL, 5UL, 1UL, 1UL, 6UL, 10UL, 32UL, 2UL, 4UL, 8UL, 16UL, 64UL, 128UL, 256UL, 512UL}; 158 159 const uint32_t APBPrescTable[8UL] = {0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL}; 160 161 const uint32_t MSIRangeTable[16UL] = {100000UL, 200000UL, 400000UL, 800000UL, 1000000UL, 2000000UL, \ 162 4000000UL, 8000000UL, 16000000UL, 24000000UL, 32000000UL, 48000000UL, 0UL, 0UL, 0UL, 0UL}; /* 0UL values are incorrect cases */ 163 164 const uint32_t SmpsPrescalerTable[4UL][6UL]={{1UL,3UL,2UL,2UL,1UL,2UL}, \ 165 {2UL,6UL,4UL,3UL,2UL,4UL}, \ 166 {4UL,12UL,8UL,6UL,4UL,8UL}, \ 167 {4UL,12UL,8UL,6UL,4UL,8UL}}; 168 169 /** 170 * @} 171 */ 172 173 /** @addtogroup STM32WBxx_System_Private_FunctionPrototypes 174 * @{ 175 */ 176 177 /** 178 * @} 179 */ 180 181 /** @addtogroup STM32WBxx_System_Private_Functions 182 * @{ 183 */ 184 185 /** 186 * @brief Setup the microcontroller system. 187 * @param None 188 * @retval None 189 */ 190 void SystemInit(void) 191 { 192 /* Configure the Vector Table location add offset address ------------------*/ 193 #if defined(VECT_TAB_SRAM) && defined(VECT_TAB_BASE_ADDRESS) 194 /* program in SRAMx */ 195 SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAMx for CPU1 */ 196 #else /* program in FLASH */ 197 SCB->VTOR = VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ 198 #endif 199 200 /* FPU settings ------------------------------------------------------------*/ 201 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 202 SCB->CPACR |= ((3UL << (10UL*2UL))|(3UL << (11UL*2UL))); /* set CP10 and CP11 Full Access */ 203 #endif 204 205 /* Reset the RCC clock configuration to the default reset state ------------*/ 206 /* Set MSION bit */ 207 RCC->CR |= RCC_CR_MSION; 208 209 /* Reset CFGR register */ 210 RCC->CFGR = 0x00070000U; 211 212 /* Reset PLLSAI1ON, PLLON, HSECSSON, HSEON, HSION, and MSIPLLON bits */ 213 RCC->CR &= (uint32_t)0xFAF6FEFBU; 214 215 /*!< Reset LSI1 and LSI2 bits */ 216 RCC->CSR &= (uint32_t)0xFFFFFFFAU; 217 218 /*!< Reset HSI48ON bit */ 219 RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; 220 221 /* Reset PLLCFGR register */ 222 RCC->PLLCFGR = 0x22041000U; 223 224 /* Reset PLLSAI1CFGR register */ 225 RCC->PLLSAI1CFGR = 0x22041000U; 226 227 /* Reset HSEBYP bit */ 228 RCC->CR &= 0xFFFBFFFFU; 229 230 /* Disable all interrupts */ 231 RCC->CIER = 0x00000000; 232 } 233 234 /** 235 * @brief Update SystemCoreClock variable according to Clock Register Values. 236 * The SystemCoreClock variable contains the core clock (HCLK), it can 237 * be used by the user application to setup the SysTick timer or configure 238 * other parameters. 239 * 240 * @note Each time the core clock (HCLK) changes, this function must be called 241 * to update SystemCoreClock variable value. Otherwise, any configuration 242 * based on this variable will be incorrect. 243 * 244 * @note - The system frequency computed by this function is not the real 245 * frequency in the chip. It is calculated based on the predefined 246 * constant and the selected clock source: 247 * 248 * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*) 249 * 250 * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) 251 * 252 * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) 253 * 254 * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***) 255 * or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors. 256 * 257 * (*) MSI_VALUE is a constant defined in stm32wbxx_hal.h file (default value 258 * 4 MHz) but the real value may vary depending on the variations 259 * in voltage and temperature. 260 * 261 * (**) HSI_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value 262 * 16 MHz) but the real value may vary depending on the variations 263 * in voltage and temperature. 264 * 265 * (***) HSE_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value 266 * 32 MHz), user has to ensure that HSE_VALUE is same as the real 267 * frequency of the crystal used. Otherwise, this function may 268 * have wrong result. 269 * 270 * - The result of this function could be not correct when using fractional 271 * value for HSE crystal. 272 * 273 * @param None 274 * @retval None 275 */ 276 void SystemCoreClockUpdate(void) 277 { 278 uint32_t tmp, msirange, pllvco, pllr, pllsource , pllm; 279 280 /* Get MSI Range frequency--------------------------------------------------*/ 281 282 /*MSI frequency range in Hz*/ 283 msirange = MSIRangeTable[(RCC->CR & RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos]; 284 285 /* Get SYSCLK source -------------------------------------------------------*/ 286 switch (RCC->CFGR & RCC_CFGR_SWS) 287 { 288 case 0x00: /* MSI used as system clock source */ 289 SystemCoreClock = msirange; 290 break; 291 292 case 0x04: /* HSI used as system clock source */ 293 /* HSI used as system clock source */ 294 SystemCoreClock = HSI_VALUE; 295 break; 296 297 case 0x08: /* HSE used as system clock source */ 298 SystemCoreClock = HSE_VALUE; 299 break; 300 301 case 0x0C: /* PLL used as system clock source */ 302 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN 303 SYSCLK = PLL_VCO / PLLR 304 */ 305 pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); 306 pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1UL ; 307 308 if(pllsource == 0x02UL) /* HSI used as PLL clock source */ 309 { 310 pllvco = (HSI_VALUE / pllm); 311 } 312 else if(pllsource == 0x03UL) /* HSE used as PLL clock source */ 313 { 314 pllvco = (HSE_VALUE / pllm); 315 } 316 else /* MSI used as PLL clock source */ 317 { 318 pllvco = (msirange / pllm); 319 } 320 321 pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos); 322 pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1UL); 323 324 SystemCoreClock = pllvco/pllr; 325 break; 326 327 default: 328 SystemCoreClock = msirange; 329 break; 330 } 331 332 /* Compute HCLK clock frequency --------------------------------------------*/ 333 /* Get HCLK1 prescaler */ 334 tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)]; 335 /* HCLK clock frequency */ 336 SystemCoreClock = SystemCoreClock / tmp; 337 338 } 339 340 341 /** 342 * @} 343 */ 344 345 /** 346 * @} 347 */ 348 349 /** 350 * @} 351 */ 352 353 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 354