Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
system_stm32f30x.c
00001 /** 00002 ****************************************************************************** 00003 * @file system_stm32f30x.c 00004 * @author MCD Application Team 00005 * @version V1.0.0 00006 * @date 20-June-2014 00007 * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. 00008 * This file contains the system clock configuration for STM32F30x devices 00009 * and is customized for use with stm32f301_nucleo Kit. 00010 * The STM32F30x is configured to run at 72 MHz, following the three 00011 * configuration below: 00012 * - PLL_SOURCE_HSI (default) : HSI (~8MHz) used to clock the PLL, and 00013 * the PLL is used as system clock source, 00014 * 64 MHz is maximum frequency on PLL HSI mode. 00015 * - PLL_SOURCE_HSE : HSE (8MHz) used to clock the PLL, and 00016 * the PLL is used as system clock source. 00017 * - PLL_SOURCE_HSE_BYPASS : HSE bypassed with an external clock 00018 * (8MHz, coming from ST-Link) used to clock 00019 * the PLL, and the PLL is used as system 00020 * clock source. 00021 * 00022 * 1. This file provides two functions and one global variable to be called from 00023 * user application: 00024 * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier 00025 * and Divider factors, AHB/APBx prescalers and Flash settings), 00026 * depending on the configuration made in the clock xls tool. 00027 * This function is called at startup just after reset and 00028 * before branch to main program. This call is made inside 00029 * the "startup_stm32f334x8.s" file. 00030 * 00031 * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used 00032 * by the user application to setup the SysTick 00033 * timer or configure other parameters. 00034 * 00035 * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must 00036 * be called whenever the core clock is changed 00037 * during program execution. 00038 * 00039 * 2. After each device reset the HSI (8 MHz) is used as system clock source. 00040 * Then SystemInit() function is called, in "startup_stm32f334x8.s" file, to 00041 * configure the system clock before to branch to main program. 00042 * 00043 * 3. If the system clock source selected by user fails to startup, the SystemInit() 00044 * function will do nothing and HSI still used as system clock source. User can 00045 * add some code to deal with this issue inside the SetSysClock() function. 00046 * 00047 * 4. The default value of HSE crystal is set to 8MHz, refer to "HSE_VALUE" define 00048 * in "stm32f30x.h" file. When HSE is used as system clock source, directly or 00049 * through PLL, and you are using different crystal you have to adapt the HSE 00050 * value to your own configuration. 00051 * 00052 * 00053 ****************************************************************************** 00054 * @attention 00055 * 00056 * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> 00057 * 00058 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 00059 * You may not use this file except in compliance with the License. 00060 * You may obtain a copy of the License at: 00061 * 00062 * http://www.st.com/software_license_agreement_liberty_v2 00063 * 00064 * Unless required by applicable law or agreed to in writing, software 00065 * distributed under the License is distributed on an "AS IS" BASIS, 00066 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00067 * See the License for the specific language governing permissions and 00068 * limitations under the License. 00069 * 00070 ****************************************************************************** 00071 */ 00072 00073 /** @addtogroup CMSIS 00074 * @{ 00075 */ 00076 00077 /** @addtogroup stm32f30x_system 00078 * @{ 00079 */ 00080 00081 /** @addtogroup STM32F30x_System_Private_Includes 00082 * @{ 00083 */ 00084 00085 #include "stm32f30x.h" 00086 00087 /** 00088 * @} 00089 */ 00090 00091 /** @addtogroup STM32F30x_System_Private_TypesDefinitions 00092 * @{ 00093 */ 00094 00095 /** 00096 * @} 00097 */ 00098 00099 /** @addtogroup STM32F30x_System_Private_Defines 00100 * @{ 00101 */ 00102 /*!< Uncomment the following line if you need to relocate your vector Table in 00103 Internal SRAM. */ 00104 /* #define VECT_TAB_SRAM */ 00105 #define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field. 00106 This value must be a multiple of 0x200. */ 00107 /** 00108 * @} 00109 */ 00110 00111 /** @addtogroup STM32F30x_System_Private_Macros 00112 * @{ 00113 */ 00114 00115 /** 00116 * @} 00117 */ 00118 00119 /** @addtogroup STM32F30x_System_Private_Variables 00120 * @{ 00121 */ 00122 00123 #define PLL_SOURCE_HSI // HSI (~8 MHz) used to clock the PLL, and the PLL is used as system clock source 00124 //#define PLL_SOURCE_HSE // HSE (8MHz) used to clock the PLL, and the PLL is used as system clock source 00125 //#define PLL_SOURCE_HSE_BYPASS // HSE bypassed with an external clock (8MHz, coming from ST-Link) used to clock 00126 00127 00128 uint32_t SystemCoreClock = 72000000; 00129 00130 __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; 00131 00132 /** 00133 * @} 00134 */ 00135 00136 /** @addtogroup STM32F30x_System_Private_FunctionPrototypes 00137 * @{ 00138 */ 00139 00140 static void SetSysClock(void); 00141 00142 /** 00143 * @} 00144 */ 00145 00146 /** @addtogroup STM32F30x_System_Private_Functions 00147 * @{ 00148 */ 00149 00150 /** 00151 * @brief Setup the microcontroller system 00152 * Initialize the Embedded Flash Interface, the PLL and update the 00153 * SystemFrequency variable. 00154 * @param None 00155 * @retval None 00156 */ 00157 void SystemInit(void) 00158 { 00159 /* FPU settings ------------------------------------------------------------*/ 00160 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 00161 SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ 00162 #endif 00163 00164 /* Reset the RCC clock configuration to the default reset state ------------*/ 00165 /* Set HSION bit */ 00166 RCC->CR |= (uint32_t)0x00000001; 00167 00168 /* Reset CFGR register */ 00169 RCC->CFGR &= (uint32_t) 0x08C0C00C; 00170 00171 /* Reset HSEON, CSSON and PLLON bits */ 00172 RCC->CR &= (uint32_t)0xFEF6FFFF; 00173 00174 /* Reset HSEBYP bit */ 00175 RCC->CR &= (uint32_t)0xFFFBFFFF; 00176 00177 /* Reset PREDIV1[3:0] bits */ 00178 RCC->CFGR2 &= (uint32_t)0xFFFFFFF0; 00179 00180 /* Reset USARTSW[1:0], I2CSW and TIMs bits */ 00181 RCC->CFGR3 &= (uint32_t)0xFFF0FECC; 00182 00183 /* Disable all interrupts */ 00184 RCC->CIR = 0x00000000; 00185 00186 /* Configure the System clock source, PLL Multiplier and Divider factors, 00187 AHB/APBx prescalers and Flash settings ----------------------------------*/ 00188 SetSysClock(); 00189 00190 #ifdef VECT_TAB_SRAM 00191 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ 00192 #else 00193 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ 00194 #endif 00195 } 00196 00197 /** 00198 * @brief Update SystemCoreClock variable according to Clock Register Values. 00199 * The SystemCoreClock variable contains the core clock (HCLK), it can 00200 * be used by the user application to setup the SysTick timer or configure 00201 * other parameters. 00202 * 00203 * @note Each time the core clock (HCLK) changes, this function must be called 00204 * to update SystemCoreClock variable value. Otherwise, any configuration 00205 * based on this variable will be incorrect. 00206 * 00207 * @note - The system frequency computed by this function is not the real 00208 * frequency in the chip. It is calculated based on the predefined 00209 * constant and the selected clock source: 00210 * 00211 * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) 00212 * 00213 * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) 00214 * 00215 * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) 00216 * or HSI_VALUE(*) multiplied/divided by the PLL factors. 00217 * 00218 * (*) HSI_VALUE is a constant defined in stm32f30x.h file (default value 00219 * 8 MHz) but the real value may vary depending on the variations 00220 * in voltage and temperature. 00221 * 00222 * (**) HSE_VALUE is a constant defined in stm32f30x.h file (default value 00223 * 8 MHz), user has to ensure that HSE_VALUE is same as the real 00224 * frequency of the crystal used. Otherwise, this function may 00225 * have wrong result. 00226 * 00227 * - The result of this function could be not correct when using fractional 00228 * value for HSE crystal. 00229 * 00230 * @param None 00231 * @retval None 00232 */ 00233 void SystemCoreClockUpdate (void) 00234 { 00235 uint32_t tmp = 0, pllmull = 0, pllsource = 0, prediv1factor = 0; 00236 00237 /* Get SYSCLK source -------------------------------------------------------*/ 00238 tmp = RCC->CFGR & RCC_CFGR_SWS; 00239 00240 switch (tmp) 00241 { 00242 case 0x00: /* HSI used as system clock */ 00243 SystemCoreClock = HSI_VALUE; 00244 break; 00245 case 0x04: /* HSE used as system clock */ 00246 SystemCoreClock = HSE_VALUE; 00247 break; 00248 case 0x08: /* PLL used as system clock */ 00249 /* Get PLL clock source and multiplication factor ----------------------*/ 00250 pllmull = RCC->CFGR & RCC_CFGR_PLLMULL; 00251 pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; 00252 pllmull = ( pllmull >> 18) + 2; 00253 00254 if (pllsource == 0x00) 00255 { 00256 /* HSI oscillator clock divided by 2 selected as PLL clock entry */ 00257 SystemCoreClock = (HSI_VALUE >> 1) * pllmull; 00258 } 00259 else 00260 { 00261 prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1; 00262 /* HSE oscillator clock selected as PREDIV1 clock entry */ 00263 SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; 00264 } 00265 break; 00266 default: /* HSI used as system clock */ 00267 SystemCoreClock = HSI_VALUE; 00268 break; 00269 } 00270 /* Compute HCLK clock frequency ----------------*/ 00271 /* Get HCLK prescaler */ 00272 tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; 00273 /* HCLK clock frequency */ 00274 SystemCoreClock >>= tmp; 00275 } 00276 00277 /** 00278 * @brief Configures the System clock source, PLL Multiplier and Divider factors, 00279 * AHB/APBx prescalers and Flash settings 00280 * @note This function should be called only once the RCC clock configuration 00281 * is reset to the default reset state (done in SystemInit() function). 00282 * @param None 00283 * @retval None 00284 */ 00285 static void SetSysClock(void) 00286 { 00287 __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 00288 00289 #ifdef PLL_SOURCE_HSI 00290 /* At this stage the HSI is already enabled */ 00291 00292 /* PLL configuration: PLLCLK = HSI/2 *16 = 64 MHz Max frequency on PLL HSI mode*/ 00293 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL)); 00294 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLMULL16); 00295 00296 00297 #else /* PLL_SOURCE_HSE_BYPASS or PLL_SOURCE_HSE */ 00298 00299 /* Enable HSE */ 00300 RCC->CR |= ((uint32_t)RCC_CR_HSEON); 00301 #ifdef PLL_SOURCE_HSE_BYPASS 00302 RCC->CR |= ((uint32_t)RCC_CR_HSEBYP); 00303 #endif /* PLL_SOURCE_HSE_BYPASS */ 00304 00305 /* Wait till HSE is ready and if Time out is reached exit */ 00306 do 00307 { 00308 HSEStatus = RCC->CR & RCC_CR_HSERDY; 00309 StartUpCounter++; 00310 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 00311 00312 if ((RCC->CR & RCC_CR_HSERDY) != RESET) 00313 { 00314 HSEStatus = (uint32_t)0x01; 00315 } 00316 else 00317 { 00318 HSEStatus = (uint32_t)0x00; 00319 } 00320 00321 if (HSEStatus == (uint32_t)0x01) 00322 { 00323 /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ 00324 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | 00325 RCC_CFGR_PLLMULL)); 00326 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL9); 00327 } 00328 00329 else 00330 { /* If HSE fails to start-up, the application will have wrong clock 00331 configuration. User can add here some code to deal with this error */ 00332 } 00333 00334 #endif /*PLL_SOURCE_HSI*/ 00335 00336 /* Enable Prefetch Buffer and set Flash Latency */ 00337 FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_1; 00338 /* HCLK = SYSCLK */ 00339 RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 00340 00341 /* PCLK2 = HCLK */ 00342 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 00343 00344 /* PCLK1 = HCLK */ 00345 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 00346 00347 /* Enable PLL */ 00348 RCC->CR |= RCC_CR_PLLON; 00349 00350 /* Wait till PLL is ready */ 00351 while((RCC->CR & RCC_CR_PLLRDY) == 0) 00352 { 00353 } 00354 00355 /* Select PLL as system clock source */ 00356 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 00357 RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 00358 00359 /* Wait till PLL is used as system clock source */ 00360 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL) 00361 { 00362 } 00363 00364 } 00365 00366 /** 00367 * @} 00368 */ 00369 00370 /** 00371 * @} 00372 */ 00373 00374 /** 00375 * @} 00376 */ 00377 00378 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Wed Jul 13 2022 03:44:51 by
1.7.2