• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>&copy; 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