1 /**
2 ******************************************************************************
3 * @file system_stm32f4xx.c
4 * @author MCD Application Team
5 * @brief CMSIS Cortex-M4 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_stm32f4xx.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 *
22 ******************************************************************************
23 * @attention
24 *
25 * <h2><center>© Copyright (c) 2017 STMicroelectronics.
26 * All rights reserved.</center></h2>
27 *
28 * This software component is licensed by ST under BSD 3-Clause license,
29 * the "License"; You may not use this file except in compliance with the
30 * License. You may obtain a copy of the License at:
31 * opensource.org/licenses/BSD-3-Clause
32 *
33 ******************************************************************************
34 */
35
36 /** @addtogroup CMSIS
37 * @{
38 */
39
40 /** @addtogroup stm32f4xx_system
41 * @{
42 */
43
44 /** @addtogroup STM32F4xx_System_Private_Includes
45 * @{
46 */
47
48 #include "stm32f4xx.h"
49
50 #if !defined(HSE_VALUE)
51 #define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */
52 #endif /* HSE_VALUE */
53
54 #if !defined(HSI_VALUE)
55 #define HSI_VALUE ((uint32_t)16000000) /* !< Value of the Internal oscillator in Hz */
56 #endif /* HSI_VALUE */
57
58 /**
59 * @}
60 */
61
62 /** @addtogroup STM32F4xx_System_Private_TypesDefinitions
63 * @{
64 */
65
66 /**
67 * @}
68 */
69
70 /** @addtogroup STM32F4xx_System_Private_Defines
71 * @{
72 */
73
74 /************************* Miscellaneous Configuration ************************/
75 /*!< Uncomment the following line if you need to use external SRAM or SDRAM as data memory */
76 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \
77 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
78 defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
79 /* define DATA_IN_ExtSRAM */
80 #endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F469xx || STM32F479xx || \
81 STM32F412Zx || STM32F412Vx */
82
83 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
84 defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
85 /* define DATA_IN_ExtSDRAM */
86 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || \
87 STM32F479xx */
88
89 /* Note: Following vector table addresses must be defined in line with linker
90 configuration. */
91 /*!< Uncomment the following line if you need to relocate the vector table
92 anywhere in Flash or Sram, else the vector table is kept at the automatic
93 remap of boot address selected */
94 /* define USER_VECT_TAB_ADDRESS */
95
96 #if defined(USER_VECT_TAB_ADDRESS)
97 /*!< Uncomment the following line if you need to relocate your vector Table
98 in Sram else user remap will be done in Flash. */
99 /* define VECT_TAB_SRAM */
100 #if defined(VECT_TAB_SRAM)
101 #define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field. \
102 This value must be a multiple of 0x200. */
103 #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. \
104 This value must be a multiple of 0x200. */
105 #else
106 #define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field. \
107 This value must be a multiple of 0x200. */
108 #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. \
109 This value must be a multiple of 0x200. */
110 #endif /* VECT_TAB_SRAM */
111 #endif /* USER_VECT_TAB_ADDRESS */
112 /******************************************************************************/
113
114 /**
115 * @}
116 */
117
118 /** @addtogroup STM32F4xx_System_Private_Macros
119 * @{
120 */
121
122 /**
123 * @}
124 */
125
126 /** @addtogroup STM32F4xx_System_Private_Variables
127 * @{
128 */
129 /* This variable is updated in three ways:
130 1) by calling CMSIS function SystemCoreClockUpdate()
131 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
132 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
133 Note: If you use this function to configure the system clock; then there
134 is no need to call the 2 first functions listed above, since SystemCoreClock
135 variable is updated automatically.
136 */
137 uint32_t SystemCoreClock = 16000000;
138 const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
139 const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
140 /**
141 * @}
142 */
143
144 /** @addtogroup STM32F4xx_System_Private_FunctionPrototypes
145 * @{
146 */
147
148 #if defined(DATA_IN_ExtSRAM) || defined(DATA_IN_ExtSDRAM)
149 static void SystemInit_ExtMemCtl(void);
150 #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
151
152 /**
153 * @}
154 */
155
156 /** @addtogroup STM32F4xx_System_Private_Functions
157 * @{
158 */
159
160 /**
161 * @brief Setup the microcontroller system
162 * Initialize the FPU setting, vector table location and External memory
163 * configuration.
164 * @param None
165 * @retval None
166 */
SystemInit(void)167 void SystemInit(void)
168 {
169 /* FPU settings ------------------------------------------------------------*/
170 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
171 SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10 and CP11 Full Access */
172 #endif
173
174 #if defined(DATA_IN_ExtSRAM) || defined(DATA_IN_ExtSDRAM)
175 SystemInit_ExtMemCtl();
176 #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
177
178 /* Configure the Vector Table location -------------------------------------*/
179 #if defined(USER_VECT_TAB_ADDRESS)
180 SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
181 #endif /* USER_VECT_TAB_ADDRESS */
182 }
183
184 /**
185 * @brief Update SystemCoreClock variable according to Clock Register Values.
186 * The SystemCoreClock variable contains the core clock (HCLK), it can
187 * be used by the user application to setup the SysTick timer or configure
188 * other parameters.
189 *
190 * @note Each time the core clock (HCLK) changes, this function must be called
191 * to update SystemCoreClock variable value. Otherwise, any configuration
192 * based on this variable will be incorrect.
193 *
194 * @note - The system frequency computed by this function is not the real
195 * frequency in the chip. It is calculated based on the predefined
196 * constant and the selected clock source:
197 *
198 * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
199 *
200 * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
201 *
202 * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
203 * or HSI_VALUE(*) multiplied/divided by the PLL factors.
204 *
205 * (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
206 * 16 MHz) but the real value may vary depending on the variations
207 * in voltage and temperature.
208 *
209 * (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value
210 * depends on the application requirements), user has to ensure that HSE_VALUE
211 * is same as the real frequency of the crystal used. Otherwise, this function
212 * may have wrong result.
213 *
214 * - The result of this function could be not correct when using fractional
215 * value for HSE crystal.
216 *
217 * @param None
218 * @retval None
219 */
SystemCoreClockUpdate(void)220 void SystemCoreClockUpdate(void)
221 {
222 uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
223
224 /* Get SYSCLK source -------------------------------------------------------*/
225 tmp = RCC->CFGR & RCC_CFGR_SWS;
226
227 switch (tmp) {
228 case 0x00: /* HSI used as system clock source */
229 SystemCoreClock = HSI_VALUE;
230 break;
231 case 0x04: /* HSE used as system clock source */
232 SystemCoreClock = HSE_VALUE;
233 break;
234 case 0x08: /* PLL used as system clock source */
235
236 /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
237 SYSCLK = PLL_VCO / PLL_P
238 */
239 pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
240 pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
241
242 if (pllsource != 0) {
243 /* HSE used as PLL clock source */
244 pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
245 } else {
246 /* HSI used as PLL clock source */
247 pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
248 }
249
250 pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> 16) + 1) * 2;
251 SystemCoreClock = pllvco / pllp;
252 break;
253 default:
254 SystemCoreClock = HSI_VALUE;
255 break;
256 }
257 /* Compute HCLK frequency --------------------------------------------------*/
258 /* Get HCLK prescaler */
259 tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
260 /* HCLK frequency */
261 SystemCoreClock >>= tmp;
262 }
263
264 #if defined(DATA_IN_ExtSRAM) && defined(DATA_IN_ExtSDRAM)
265 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
266 defined(STM32F469xx) || defined(STM32F479xx)
267 /**
268 * @brief Setup the external memory controller.
269 * Called in startup_stm32f4xx.s before jump to main.
270 * This function configures the external memories (SRAM/SDRAM)
271 * This SRAM/SDRAM will be used as program data memory (including heap and stack).
272 * @param None
273 * @retval None
274 */
SystemInit_ExtMemCtl(void)275 void SystemInit_ExtMemCtl(void)
276 {
277 __IO uint32_t tmp = 0x00;
278
279 register uint32_t tmpreg = 0, timeout = 0xFFFF;
280 register __IO uint32_t index;
281
282 /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */
283 RCC->AHB1ENR |= 0x000001F8;
284
285 /* Delay after an RCC peripheral clock enabling */
286 tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
287
288 /* Connect PDx pins to FMC Alternate function */
289 GPIOD->AFR[0] = 0x00CCC0CC;
290 GPIOD->AFR[1] = 0xCCCCCCCC;
291 /* Configure PDx pins in Alternate function mode */
292 GPIOD->MODER = 0xAAAA0A8A;
293 /* Configure PDx pins speed to 100 MHz */
294 GPIOD->OSPEEDR = 0xFFFF0FCF;
295 /* Configure PDx pins Output type to push-pull */
296 GPIOD->OTYPER = 0x00000000;
297 /* No pull-up, pull-down for PDx pins */
298 GPIOD->PUPDR = 0x00000000;
299
300 /* Connect PEx pins to FMC Alternate function */
301 GPIOE->AFR[0] = 0xC00CC0CC;
302 GPIOE->AFR[1] = 0xCCCCCCCC;
303 /* Configure PEx pins in Alternate function mode */
304 GPIOE->MODER = 0xAAAA828A;
305 /* Configure PEx pins speed to 100 MHz */
306 GPIOE->OSPEEDR = 0xFFFFC3CF;
307 /* Configure PEx pins Output type to push-pull */
308 GPIOE->OTYPER = 0x00000000;
309 /* No pull-up, pull-down for PEx pins */
310 GPIOE->PUPDR = 0x00000000;
311
312 /* Connect PFx pins to FMC Alternate function */
313 GPIOF->AFR[0] = 0xCCCCCCCC;
314 GPIOF->AFR[1] = 0xCCCCCCCC;
315 /* Configure PFx pins in Alternate function mode */
316 GPIOF->MODER = 0xAA800AAA;
317 /* Configure PFx pins speed to 50 MHz */
318 GPIOF->OSPEEDR = 0xAA800AAA;
319 /* Configure PFx pins Output type to push-pull */
320 GPIOF->OTYPER = 0x00000000;
321 /* No pull-up, pull-down for PFx pins */
322 GPIOF->PUPDR = 0x00000000;
323
324 /* Connect PGx pins to FMC Alternate function */
325 GPIOG->AFR[0] = 0xCCCCCCCC;
326 GPIOG->AFR[1] = 0xCCCCCCCC;
327 /* Configure PGx pins in Alternate function mode */
328 GPIOG->MODER = 0xAAAAAAAA;
329 /* Configure PGx pins speed to 50 MHz */
330 GPIOG->OSPEEDR = 0xAAAAAAAA;
331 /* Configure PGx pins Output type to push-pull */
332 GPIOG->OTYPER = 0x00000000;
333 /* No pull-up, pull-down for PGx pins */
334 GPIOG->PUPDR = 0x00000000;
335
336 /* Connect PHx pins to FMC Alternate function */
337 GPIOH->AFR[0] = 0x00C0CC00;
338 GPIOH->AFR[1] = 0xCCCCCCCC;
339 /* Configure PHx pins in Alternate function mode */
340 GPIOH->MODER = 0xAAAA08A0;
341 /* Configure PHx pins speed to 50 MHz */
342 GPIOH->OSPEEDR = 0xAAAA08A0;
343 /* Configure PHx pins Output type to push-pull */
344 GPIOH->OTYPER = 0x00000000;
345 /* No pull-up, pull-down for PHx pins */
346 GPIOH->PUPDR = 0x00000000;
347
348 /* Connect PIx pins to FMC Alternate function */
349 GPIOI->AFR[0] = 0xCCCCCCCC;
350 GPIOI->AFR[1] = 0x00000CC0;
351 /* Configure PIx pins in Alternate function mode */
352 GPIOI->MODER = 0x0028AAAA;
353 /* Configure PIx pins speed to 50 MHz */
354 GPIOI->OSPEEDR = 0x0028AAAA;
355 /* Configure PIx pins Output type to push-pull */
356 GPIOI->OTYPER = 0x00000000;
357 /* No pull-up, pull-down for PIx pins */
358 GPIOI->PUPDR = 0x00000000;
359
360 /*-- FMC Configuration -------------------------------------------------------*/
361 /* Enable the FMC interface clock */
362 RCC->AHB3ENR |= 0x00000001;
363 /* Delay after an RCC peripheral clock enabling */
364 tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
365
366 FMC_Bank5_6->SDCR[0] = 0x000019E4;
367 FMC_Bank5_6->SDTR[0] = 0x01115351;
368
369 /* SDRAM initialization sequence */
370 /* Clock enable command */
371 FMC_Bank5_6->SDCMR = 0x00000011;
372 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
373 while ((tmpreg != 0) && (timeout-- > 0)) {
374 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
375 }
376
377 /* Delay */
378 for (index = 0; index < 1000; index++)
379 ;
380
381 /* PALL command */
382 FMC_Bank5_6->SDCMR = 0x00000012;
383 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
384 timeout = 0xFFFF;
385 while ((tmpreg != 0) && (timeout-- > 0)) {
386 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
387 }
388
389 /* Auto refresh command */
390 FMC_Bank5_6->SDCMR = 0x00000073;
391 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
392 timeout = 0xFFFF;
393 while ((tmpreg != 0) && (timeout-- > 0)) {
394 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
395 }
396
397 /* MRD register program */
398 FMC_Bank5_6->SDCMR = 0x00046014;
399 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
400 timeout = 0xFFFF;
401 while ((tmpreg != 0) && (timeout-- > 0)) {
402 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
403 }
404
405 /* Set refresh count */
406 tmpreg = FMC_Bank5_6->SDRTR;
407 FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C << 1));
408
409 /* Disable write protection */
410 tmpreg = FMC_Bank5_6->SDCR[0];
411 FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
412
413 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
414 /* Configure and enable Bank1_SRAM2 */
415 FMC_Bank1->BTCR[2] = 0x00001011;
416 FMC_Bank1->BTCR[3] = 0x00000201;
417 FMC_Bank1E->BWTR[2] = 0x0fffffff;
418 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
419 #if defined(STM32F469xx) || defined(STM32F479xx)
420 /* Configure and enable Bank1_SRAM2 */
421 FMC_Bank1->BTCR[2] = 0x00001091;
422 FMC_Bank1->BTCR[3] = 0x00110212;
423 FMC_Bank1E->BWTR[2] = 0x0fffffff;
424 #endif /* STM32F469xx || STM32F479xx */
425
426 (void)(tmp);
427 }
428 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
429 #elif defined(DATA_IN_ExtSRAM) || defined(DATA_IN_ExtSDRAM)
430 /**
431 * @brief Setup the external memory controller.
432 * Called in startup_stm32f4xx.s before jump to main.
433 * This function configures the external memories (SRAM/SDRAM)
434 * This SRAM/SDRAM will be used as program data memory (including heap and stack).
435 * @param None
436 * @retval None
437 */
SystemInit_ExtMemCtl(void)438 void SystemInit_ExtMemCtl(void)
439 {
440 __IO uint32_t tmp = 0x00;
441 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
442 defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
443 #if defined(DATA_IN_ExtSDRAM)
444 register uint32_t tmpreg = 0, timeout = 0xFFFF;
445 register __IO uint32_t index;
446
447 #if defined(STM32F446xx)
448 /* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface
449 clock */
450 RCC->AHB1ENR |= 0x0000007D;
451 #else
452 /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface
453 clock */
454 RCC->AHB1ENR |= 0x000001F8;
455 #endif /* STM32F446xx */
456 /* Delay after an RCC peripheral clock enabling */
457 tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
458
459 #if defined(STM32F446xx)
460 /* Connect PAx pins to FMC Alternate function */
461 GPIOA->AFR[0] |= 0xC0000000;
462 GPIOA->AFR[1] |= 0x00000000;
463 /* Configure PDx pins in Alternate function mode */
464 GPIOA->MODER |= 0x00008000;
465 /* Configure PDx pins speed to 50 MHz */
466 GPIOA->OSPEEDR |= 0x00008000;
467 /* Configure PDx pins Output type to push-pull */
468 GPIOA->OTYPER |= 0x00000000;
469 /* No pull-up, pull-down for PDx pins */
470 GPIOA->PUPDR |= 0x00000000;
471
472 /* Connect PCx pins to FMC Alternate function */
473 GPIOC->AFR[0] |= 0x00CC0000;
474 GPIOC->AFR[1] |= 0x00000000;
475 /* Configure PDx pins in Alternate function mode */
476 GPIOC->MODER |= 0x00000A00;
477 /* Configure PDx pins speed to 50 MHz */
478 GPIOC->OSPEEDR |= 0x00000A00;
479 /* Configure PDx pins Output type to push-pull */
480 GPIOC->OTYPER |= 0x00000000;
481 /* No pull-up, pull-down for PDx pins */
482 GPIOC->PUPDR |= 0x00000000;
483 #endif /* STM32F446xx */
484
485 /* Connect PDx pins to FMC Alternate function */
486 GPIOD->AFR[0] = 0x000000CC;
487 GPIOD->AFR[1] = 0xCC000CCC;
488 /* Configure PDx pins in Alternate function mode */
489 GPIOD->MODER = 0xA02A000A;
490 /* Configure PDx pins speed to 50 MHz */
491 GPIOD->OSPEEDR = 0xA02A000A;
492 /* Configure PDx pins Output type to push-pull */
493 GPIOD->OTYPER = 0x00000000;
494 /* No pull-up, pull-down for PDx pins */
495 GPIOD->PUPDR = 0x00000000;
496
497 /* Connect PEx pins to FMC Alternate function */
498 GPIOE->AFR[0] = 0xC00000CC;
499 GPIOE->AFR[1] = 0xCCCCCCCC;
500 /* Configure PEx pins in Alternate function mode */
501 GPIOE->MODER = 0xAAAA800A;
502 /* Configure PEx pins speed to 50 MHz */
503 GPIOE->OSPEEDR = 0xAAAA800A;
504 /* Configure PEx pins Output type to push-pull */
505 GPIOE->OTYPER = 0x00000000;
506 /* No pull-up, pull-down for PEx pins */
507 GPIOE->PUPDR = 0x00000000;
508
509 /* Connect PFx pins to FMC Alternate function */
510 GPIOF->AFR[0] = 0xCCCCCCCC;
511 GPIOF->AFR[1] = 0xCCCCCCCC;
512 /* Configure PFx pins in Alternate function mode */
513 GPIOF->MODER = 0xAA800AAA;
514 /* Configure PFx pins speed to 50 MHz */
515 GPIOF->OSPEEDR = 0xAA800AAA;
516 /* Configure PFx pins Output type to push-pull */
517 GPIOF->OTYPER = 0x00000000;
518 /* No pull-up, pull-down for PFx pins */
519 GPIOF->PUPDR = 0x00000000;
520
521 /* Connect PGx pins to FMC Alternate function */
522 GPIOG->AFR[0] = 0xCCCCCCCC;
523 GPIOG->AFR[1] = 0xCCCCCCCC;
524 /* Configure PGx pins in Alternate function mode */
525 GPIOG->MODER = 0xAAAAAAAA;
526 /* Configure PGx pins speed to 50 MHz */
527 GPIOG->OSPEEDR = 0xAAAAAAAA;
528 /* Configure PGx pins Output type to push-pull */
529 GPIOG->OTYPER = 0x00000000;
530 /* No pull-up, pull-down for PGx pins */
531 GPIOG->PUPDR = 0x00000000;
532
533 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
534 defined(STM32F469xx) || defined(STM32F479xx)
535 /* Connect PHx pins to FMC Alternate function */
536 GPIOH->AFR[0] = 0x00C0CC00;
537 GPIOH->AFR[1] = 0xCCCCCCCC;
538 /* Configure PHx pins in Alternate function mode */
539 GPIOH->MODER = 0xAAAA08A0;
540 /* Configure PHx pins speed to 50 MHz */
541 GPIOH->OSPEEDR = 0xAAAA08A0;
542 /* Configure PHx pins Output type to push-pull */
543 GPIOH->OTYPER = 0x00000000;
544 /* No pull-up, pull-down for PHx pins */
545 GPIOH->PUPDR = 0x00000000;
546
547 /* Connect PIx pins to FMC Alternate function */
548 GPIOI->AFR[0] = 0xCCCCCCCC;
549 GPIOI->AFR[1] = 0x00000CC0;
550 /* Configure PIx pins in Alternate function mode */
551 GPIOI->MODER = 0x0028AAAA;
552 /* Configure PIx pins speed to 50 MHz */
553 GPIOI->OSPEEDR = 0x0028AAAA;
554 /* Configure PIx pins Output type to push-pull */
555 GPIOI->OTYPER = 0x00000000;
556 /* No pull-up, pull-down for PIx pins */
557 GPIOI->PUPDR = 0x00000000;
558 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
559
560 /*-- FMC Configuration -------------------------------------------------------*/
561 /* Enable the FMC interface clock */
562 RCC->AHB3ENR |= 0x00000001;
563 /* Delay after an RCC peripheral clock enabling */
564 tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
565
566 /* Configure and enable SDRAM bank1 */
567 #if defined(STM32F446xx)
568 FMC_Bank5_6->SDCR[0] = 0x00001954;
569 #else
570 FMC_Bank5_6->SDCR[0] = 0x000019E4;
571 #endif /* STM32F446xx */
572 FMC_Bank5_6->SDTR[0] = 0x01115351;
573
574 /* SDRAM initialization sequence */
575 /* Clock enable command */
576 FMC_Bank5_6->SDCMR = 0x00000011;
577 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
578 while ((tmpreg != 0) && (timeout-- > 0)) {
579 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
580 }
581
582 /* Delay */
583 for (index = 0; index < 1000; index++)
584 ;
585
586 /* PALL command */
587 FMC_Bank5_6->SDCMR = 0x00000012;
588 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
589 timeout = 0xFFFF;
590 while ((tmpreg != 0) && (timeout-- > 0)) {
591 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
592 }
593
594 /* Auto refresh command */
595 #if defined(STM32F446xx)
596 FMC_Bank5_6->SDCMR = 0x000000F3;
597 #else
598 FMC_Bank5_6->SDCMR = 0x00000073;
599 #endif /* STM32F446xx */
600 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
601 timeout = 0xFFFF;
602 while ((tmpreg != 0) && (timeout-- > 0)) {
603 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
604 }
605
606 /* MRD register program */
607 #if defined(STM32F446xx)
608 FMC_Bank5_6->SDCMR = 0x00044014;
609 #else
610 FMC_Bank5_6->SDCMR = 0x00046014;
611 #endif /* STM32F446xx */
612 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
613 timeout = 0xFFFF;
614 while ((tmpreg != 0) && (timeout-- > 0)) {
615 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
616 }
617
618 /* Set refresh count */
619 tmpreg = FMC_Bank5_6->SDRTR;
620 #if defined(STM32F446xx)
621 FMC_Bank5_6->SDRTR = (tmpreg | (0x0000050C << 1));
622 #else
623 FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C << 1));
624 #endif /* STM32F446xx */
625
626 /* Disable write protection */
627 tmpreg = FMC_Bank5_6->SDCR[0];
628 FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
629 #endif /* DATA_IN_ExtSDRAM */
630 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */
631
632 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \
633 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
634 defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
635
636 #if defined(DATA_IN_ExtSRAM)
637 /*-- GPIOs Configuration -----------------------------------------------------*/
638 /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
639 RCC->AHB1ENR |= 0x00000078;
640 /* Delay after an RCC peripheral clock enabling */
641 tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);
642
643 /* Connect PDx pins to FMC Alternate function */
644 GPIOD->AFR[0] = 0x00CCC0CC;
645 GPIOD->AFR[1] = 0xCCCCCCCC;
646 /* Configure PDx pins in Alternate function mode */
647 GPIOD->MODER = 0xAAAA0A8A;
648 /* Configure PDx pins speed to 100 MHz */
649 GPIOD->OSPEEDR = 0xFFFF0FCF;
650 /* Configure PDx pins Output type to push-pull */
651 GPIOD->OTYPER = 0x00000000;
652 /* No pull-up, pull-down for PDx pins */
653 GPIOD->PUPDR = 0x00000000;
654
655 /* Connect PEx pins to FMC Alternate function */
656 GPIOE->AFR[0] = 0xC00CC0CC;
657 GPIOE->AFR[1] = 0xCCCCCCCC;
658 /* Configure PEx pins in Alternate function mode */
659 GPIOE->MODER = 0xAAAA828A;
660 /* Configure PEx pins speed to 100 MHz */
661 GPIOE->OSPEEDR = 0xFFFFC3CF;
662 /* Configure PEx pins Output type to push-pull */
663 GPIOE->OTYPER = 0x00000000;
664 /* No pull-up, pull-down for PEx pins */
665 GPIOE->PUPDR = 0x00000000;
666
667 /* Connect PFx pins to FMC Alternate function */
668 GPIOF->AFR[0] = 0x00CCCCCC;
669 GPIOF->AFR[1] = 0xCCCC0000;
670 /* Configure PFx pins in Alternate function mode */
671 GPIOF->MODER = 0xAA000AAA;
672 /* Configure PFx pins speed to 100 MHz */
673 GPIOF->OSPEEDR = 0xFF000FFF;
674 /* Configure PFx pins Output type to push-pull */
675 GPIOF->OTYPER = 0x00000000;
676 /* No pull-up, pull-down for PFx pins */
677 GPIOF->PUPDR = 0x00000000;
678
679 /* Connect PGx pins to FMC Alternate function */
680 GPIOG->AFR[0] = 0x00CCCCCC;
681 GPIOG->AFR[1] = 0x000000C0;
682 /* Configure PGx pins in Alternate function mode */
683 GPIOG->MODER = 0x00085AAA;
684 /* Configure PGx pins speed to 100 MHz */
685 GPIOG->OSPEEDR = 0x000CAFFF;
686 /* Configure PGx pins Output type to push-pull */
687 GPIOG->OTYPER = 0x00000000;
688 /* No pull-up, pull-down for PGx pins */
689 GPIOG->PUPDR = 0x00000000;
690
691 /*-- FMC/FSMC Configuration --------------------------------------------------*/
692 /* Enable the FMC/FSMC interface clock */
693 RCC->AHB3ENR |= 0x00000001;
694
695 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
696 /* Delay after an RCC peripheral clock enabling */
697 tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
698 /* Configure and enable Bank1_SRAM2 */
699 FMC_Bank1->BTCR[2] = 0x00001011;
700 FMC_Bank1->BTCR[3] = 0x00000201;
701 FMC_Bank1E->BWTR[2] = 0x0fffffff;
702 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
703 #if defined(STM32F469xx) || defined(STM32F479xx)
704 /* Delay after an RCC peripheral clock enabling */
705 tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
706 /* Configure and enable Bank1_SRAM2 */
707 FMC_Bank1->BTCR[2] = 0x00001091;
708 FMC_Bank1->BTCR[3] = 0x00110212;
709 FMC_Bank1E->BWTR[2] = 0x0fffffff;
710 #endif /* STM32F469xx || STM32F479xx */
711 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \
712 defined(STM32F412Zx) || defined(STM32F412Vx)
713 /* Delay after an RCC peripheral clock enabling */
714 tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN);
715 /* Configure and enable Bank1_SRAM2 */
716 FSMC_Bank1->BTCR[2] = 0x00001011;
717 FSMC_Bank1->BTCR[3] = 0x00000201;
718 FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF;
719 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F412Zx || STM32F412Vx */
720
721 #endif /* DATA_IN_ExtSRAM */
722 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || \
723 STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx */
724 (void)(tmp);
725 }
726 #endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */
727 /**
728 * @}
729 */
730
731 /**
732 * @}
733 */
734
735 /**
736 * @}
737 */
738 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
739