1 /** 2 ****************************************************************************** 3 * @file system_stm32f1xx.c 4 * @author MCD Application Team 5 * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File. 6 * 7 * 1. This file provides two functions and one global variable to be called from 8 * user application: 9 * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier 10 * factors, AHB/APBx prescalers and Flash settings). 11 * This function is called at startup just after reset and 12 * before branch to main program. This call is made inside 13 * the "startup_stm32f1xx_xx.s" file. 14 * 15 * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used 16 * by the user application to setup the SysTick 17 * timer or configure other parameters. 18 * 19 * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must 20 * be called whenever the core clock is changed 21 * during program execution. 22 * 23 * 2. After each device reset the HSI (8 MHz) is used as system clock source. 24 * Then SystemInit() function is called, in "startup_stm32f1xx_xx.s" file, to 25 * configure the system clock before to branch to main program. 26 * 27 * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on 28 * the product used), refer to "HSE_VALUE". 29 * When HSE is used as system clock source, directly or through PLL, and you 30 * are using different crystal you have to adapt the HSE value to your own 31 * configuration. 32 * 33 ****************************************************************************** 34 * @attention 35 * 36 * Copyright (c) 2017-2021 STMicroelectronics. 37 * All rights reserved. 38 * 39 * This software is licensed under terms that can be found in the LICENSE file 40 * in the root directory of this software component. 41 * If no LICENSE file comes with this software, it is provided AS-IS. 42 * 43 ****************************************************************************** 44 */ 45 46 /** @addtogroup CMSIS 47 * @{ 48 */ 49 50 /** @addtogroup stm32f1xx_system 51 * @{ 52 */ 53 54 /** @addtogroup STM32F1xx_System_Private_Includes 55 * @{ 56 */ 57 58 #include "stm32f1xx.h" 59 60 /** 61 * @} 62 */ 63 64 /** @addtogroup STM32F1xx_System_Private_TypesDefinitions 65 * @{ 66 */ 67 68 /** 69 * @} 70 */ 71 72 /** @addtogroup STM32F1xx_System_Private_Defines 73 * @{ 74 */ 75 76 #if !defined (HSE_VALUE) 77 #define HSE_VALUE 8000000U /*!< Default value of the External oscillator in Hz. 78 This value can be provided and adapted by the user application. */ 79 #endif /* HSE_VALUE */ 80 81 #if !defined (HSI_VALUE) 82 #define HSI_VALUE 8000000U /*!< Default value of the Internal oscillator in Hz. 83 This value can be provided and adapted by the user application. */ 84 #endif /* HSI_VALUE */ 85 86 /*!< Uncomment the following line if you need to use external SRAM */ 87 #if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) 88 /* #define DATA_IN_ExtSRAM */ 89 #endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */ 90 91 /* Note: Following vector table addresses must be defined in line with linker 92 configuration. */ 93 /*!< Uncomment the following line if you need to relocate the vector table 94 anywhere in Flash or Sram, else the vector table is kept at the automatic 95 remap of boot address selected */ 96 /* #define USER_VECT_TAB_ADDRESS */ 97 98 #if defined(USER_VECT_TAB_ADDRESS) 99 /*!< Uncomment the following line if you need to relocate your vector Table 100 in Sram else user remap will be done in Flash. */ 101 /* #define VECT_TAB_SRAM */ 102 #if defined(VECT_TAB_SRAM) 103 #define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field. 104 This value must be a multiple of 0x200. */ 105 #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. 106 This value must be a multiple of 0x200. */ 107 #else 108 #define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field. 109 This value must be a multiple of 0x200. */ 110 #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. 111 This value must be a multiple of 0x200. */ 112 #endif /* VECT_TAB_SRAM */ 113 #endif /* USER_VECT_TAB_ADDRESS */ 114 115 /******************************************************************************/ 116 117 /** 118 * @} 119 */ 120 121 /** @addtogroup STM32F1xx_System_Private_Macros 122 * @{ 123 */ 124 125 /** 126 * @} 127 */ 128 129 /** @addtogroup STM32F1xx_System_Private_Variables 130 * @{ 131 */ 132 133 /* This variable is updated in three ways: 134 1) by calling CMSIS function SystemCoreClockUpdate() 135 2) by calling HAL API function HAL_RCC_GetHCLKFreq() 136 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency 137 Note: If you use this function to configure the system clock; then there 138 is no need to call the 2 first functions listed above, since SystemCoreClock 139 variable is updated automatically. 140 */ 141 uint32_t SystemCoreClock = 8000000; 142 const uint8_t AHBPrescTable[16U] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 143 8, 9 }; 144 const uint8_t APBPrescTable[8U] = { 0, 0, 0, 0, 1, 2, 3, 4 }; 145 146 /** 147 * @} 148 */ 149 150 /** @addtogroup STM32F1xx_System_Private_FunctionPrototypes 151 * @{ 152 */ 153 154 #if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) 155 #ifdef DATA_IN_ExtSRAM 156 static void SystemInit_ExtMemCtl(void); 157 #endif /* DATA_IN_ExtSRAM */ 158 #endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */ 159 160 /** 161 * @} 162 */ 163 164 /** @addtogroup STM32F1xx_System_Private_Functions 165 * @{ 166 */ 167 168 /** 169 * @brief Setup the microcontroller system 170 * Initialize the Embedded Flash Interface, the PLL and update the 171 * SystemCoreClock variable. 172 * @note This function should be used only after reset. 173 * @param None 174 * @retval None 175 */ 176 void SystemInit(void) 177 { 178 #if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) 179 #ifdef DATA_IN_ExtSRAM 180 SystemInit_ExtMemCtl(); 181 #endif /* DATA_IN_ExtSRAM */ 182 #endif 183 184 /* Configure the Vector Table location -------------------------------------*/ 185 #if defined(USER_VECT_TAB_ADDRESS) 186 SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ 187 #endif /* USER_VECT_TAB_ADDRESS */ 188 } 189 190 /** 191 * @brief Update SystemCoreClock variable according to Clock Register Values. 192 * The SystemCoreClock variable contains the core clock (HCLK), it can 193 * be used by the user application to setup the SysTick timer or configure 194 * other parameters. 195 * 196 * @note Each time the core clock (HCLK) changes, this function must be called 197 * to update SystemCoreClock variable value. Otherwise, any configuration 198 * based on this variable will be incorrect. 199 * 200 * @note - The system frequency computed by this function is not the real 201 * frequency in the chip. It is calculated based on the predefined 202 * constant and the selected clock source: 203 * 204 * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) 205 * 206 * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) 207 * 208 * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) 209 * or HSI_VALUE(*) multiplied by the PLL factors. 210 * 211 * (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value 212 * 8 MHz) but the real value may vary depending on the variations 213 * in voltage and temperature. 214 * 215 * (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value 216 * 8 MHz or 25 MHz, depending on the product used), user has to ensure 217 * that HSE_VALUE is same as the real frequency of the crystal used. 218 * Otherwise, this function may have wrong result. 219 * 220 * - The result of this function could be not correct when using fractional 221 * value for HSE crystal. 222 * @param None 223 * @retval None 224 */ 225 void SystemCoreClockUpdate(void) 226 { 227 uint32_t tmp = 0U, pllmull = 0U, pllsource = 0U; 228 229 #if defined(STM32F105xC) || defined(STM32F107xC) 230 uint32_t prediv1source = 0U, prediv1factor = 0U, prediv2factor = 0U, pll2mull = 0U; 231 #endif /* STM32F105xC */ 232 233 #if defined(STM32F100xB) || defined(STM32F100xE) 234 uint32_t prediv1factor = 0U; 235 #endif /* STM32F100xB or STM32F100xE */ 236 237 /* Get SYSCLK source -------------------------------------------------------*/ 238 tmp = RCC->CFGR & RCC_CFGR_SWS; 239 240 switch (tmp) { 241 case 0x00U: /* HSI used as system clock */ 242 SystemCoreClock = HSI_VALUE; 243 break; 244 case 0x04U: /* HSE used as system clock */ 245 SystemCoreClock = HSE_VALUE; 246 break; 247 case 0x08U: /* PLL used as system clock */ 248 249 /* Get PLL clock source and multiplication factor ----------------------*/ 250 pllmull = RCC->CFGR & RCC_CFGR_PLLMULL; 251 pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; 252 253 #if !defined(STM32F105xC) && !defined(STM32F107xC) 254 pllmull = (pllmull >> 18U) + 2U; 255 256 if (pllsource == 0x00U) { 257 /* HSI oscillator clock divided by 2 selected as PLL clock entry */ 258 SystemCoreClock = (HSI_VALUE >> 1U) * pllmull; 259 } else { 260 #if defined(STM32F100xB) || defined(STM32F100xE) 261 prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U; 262 /* HSE oscillator clock selected as PREDIV1 clock entry */ 263 SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; 264 #else 265 /* HSE selected as PLL clock entry */ 266 if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t) RESET) {/* HSE oscillator clock divided by 2 */ 267 SystemCoreClock = (HSE_VALUE >> 1U) * pllmull; 268 } else { 269 SystemCoreClock = HSE_VALUE * pllmull; 270 } 271 #endif 272 } 273 #else 274 pllmull = pllmull >> 18U; 275 276 if (pllmull != 0x0DU) 277 { 278 pllmull += 2U; 279 } 280 else 281 { /* PLL multiplication factor = PLL input clock * 6.5 */ 282 pllmull = 13U / 2U; 283 } 284 285 if (pllsource == 0x00U) 286 { 287 /* HSI oscillator clock divided by 2 selected as PLL clock entry */ 288 SystemCoreClock = (HSI_VALUE >> 1U) * pllmull; 289 } 290 else 291 {/* PREDIV1 selected as PLL clock entry */ 292 293 /* Get PREDIV1 clock source and division factor */ 294 prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC; 295 prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U; 296 297 if (prediv1source == 0U) 298 { 299 /* HSE oscillator clock selected as PREDIV1 clock entry */ 300 SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; 301 } 302 else 303 {/* PLL2 clock selected as PREDIV1 clock entry */ 304 305 /* Get PREDIV2 division factor and PLL2 multiplication factor */ 306 prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4U) + 1U; 307 pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8U) + 2U; 308 SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull; 309 } 310 } 311 #endif /* STM32F105xC */ 312 break; 313 314 default: 315 SystemCoreClock = HSI_VALUE; 316 break; 317 } 318 319 /* Compute HCLK clock frequency ----------------*/ 320 /* Get HCLK prescaler */ 321 tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)]; 322 /* HCLK clock frequency */ 323 SystemCoreClock >>= tmp; 324 } 325 326 #if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) 327 /** 328 * @brief Setup the external memory controller. Called in startup_stm32f1xx.s 329 * before jump to __main 330 * @param None 331 * @retval None 332 */ 333 #ifdef DATA_IN_ExtSRAM 334 /** 335 * @brief Setup the external memory controller. 336 * Called in startup_stm32f1xx_xx.s/.c before jump to main. 337 * This function configures the external SRAM mounted on STM3210E-EVAL 338 * board (STM32 High density devices). This SRAM will be used as program 339 * data memory (including heap and stack). 340 * @param None 341 * @retval None 342 */ 343 void SystemInit_ExtMemCtl(void) 344 { 345 __IO uint32_t tmpreg; 346 /*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is 347 required, then adjust the Register Addresses */ 348 349 /* Enable FSMC clock */ 350 RCC->AHBENR = 0x00000114U; 351 352 /* Delay after an RCC peripheral clock enabling */ 353 tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN); 354 355 /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */ 356 RCC->APB2ENR = 0x000001E0U; 357 358 /* Delay after an RCC peripheral clock enabling */ 359 tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN); 360 361 (void)(tmpreg); 362 363 /* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/ 364 /*---------------- SRAM Address lines configuration -------------------------*/ 365 /*---------------- NOE and NWE configuration --------------------------------*/ 366 /*---------------- NE3 configuration ----------------------------------------*/ 367 /*---------------- NBL0, NBL1 configuration ---------------------------------*/ 368 369 GPIOD->CRL = 0x44BB44BBU; 370 GPIOD->CRH = 0xBBBBBBBBU; 371 372 GPIOE->CRL = 0xB44444BBU; 373 GPIOE->CRH = 0xBBBBBBBBU; 374 375 GPIOF->CRL = 0x44BBBBBBU; 376 GPIOF->CRH = 0xBBBB4444U; 377 378 GPIOG->CRL = 0x44BBBBBBU; 379 GPIOG->CRH = 0x444B4B44U; 380 381 /*---------------- FSMC Configuration ---------------------------------------*/ 382 /*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/ 383 384 FSMC_Bank1->BTCR[4U] = 0x00001091U; 385 FSMC_Bank1->BTCR[5U] = 0x00110212U; 386 } 387 #endif /* DATA_IN_ExtSRAM */ 388 #endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */ 389 390 /** 391 * @} 392 */ 393 394 /** 395 * @} 396 */ 397 398 /** 399 * @} 400 */
