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   * Copyright (c) 2017 STMicroelectronics.
26   * All rights reserved.
27   *
28   * This software is licensed under terms that can be found in the LICENSE file
29   * in the root directory of this software component.
30   * If no LICENSE file comes with this software, it is provided AS-IS.
31   *
32   ******************************************************************************
33   */
34 
35 /** @addtogroup CMSIS
36   * @{
37   */
38 
39 /** @addtogroup stm32f4xx_system
40   * @{
41   */
42 
43 /** @addtogroup STM32F4xx_System_Private_Includes
44   * @{
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   {
229     case 0x00:  /* HSI used as system clock source */
230       SystemCoreClock = HSI_VALUE;
231       break;
232     case 0x04:  /* HSE used as system clock source */
233       SystemCoreClock = HSE_VALUE;
234       break;
235     case 0x08:  /* PLL used as system clock source */
236 
237       /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
238          SYSCLK = PLL_VCO / PLL_P
239          */
240       pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
241       pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
242 
243       if (pllsource != 0)
244       {
245         /* HSE used as PLL clock source */
246         pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
247       }
248       else
249       {
250         /* HSI used as PLL clock source */
251         pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
252       }
253 
254       pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
255       SystemCoreClock = pllvco/pllp;
256       break;
257     default:
258       SystemCoreClock = HSI_VALUE;
259       break;
260   }
261   /* Compute HCLK frequency --------------------------------------------------*/
262   /* Get HCLK prescaler */
263   tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
264   /* HCLK frequency */
265   SystemCoreClock >>= tmp;
266 }
267 
268 #if defined (DATA_IN_ExtSRAM) && defined (DATA_IN_ExtSDRAM)
269 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
270  || defined(STM32F469xx) || defined(STM32F479xx)
271 /**
272   * @brief  Setup the external memory controller.
273   *         Called in startup_stm32f4xx.s before jump to main.
274   *         This function configures the external memories (SRAM/SDRAM)
275   *         This SRAM/SDRAM will be used as program data memory (including heap and stack).
276   * @param  None
277   * @retval None
278   */
SystemInit_ExtMemCtl(void)279 void SystemInit_ExtMemCtl(void)
280 {
281   __IO uint32_t tmp = 0x00;
282 
283   register uint32_t tmpreg = 0, timeout = 0xFFFF;
284   register __IO uint32_t index;
285 
286   /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */
287   RCC->AHB1ENR |= 0x000001F8;
288 
289   /* Delay after an RCC peripheral clock enabling */
290   tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
291 
292   /* Connect PDx pins to FMC Alternate function */
293   GPIOD->AFR[0]  = 0x00CCC0CC;
294   GPIOD->AFR[1]  = 0xCCCCCCCC;
295   /* Configure PDx pins in Alternate function mode */
296   GPIOD->MODER   = 0xAAAA0A8A;
297   /* Configure PDx pins speed to 100 MHz */
298   GPIOD->OSPEEDR = 0xFFFF0FCF;
299   /* Configure PDx pins Output type to push-pull */
300   GPIOD->OTYPER  = 0x00000000;
301   /* No pull-up, pull-down for PDx pins */
302   GPIOD->PUPDR   = 0x00000000;
303 
304   /* Connect PEx pins to FMC Alternate function */
305   GPIOE->AFR[0]  = 0xC00CC0CC;
306   GPIOE->AFR[1]  = 0xCCCCCCCC;
307   /* Configure PEx pins in Alternate function mode */
308   GPIOE->MODER   = 0xAAAA828A;
309   /* Configure PEx pins speed to 100 MHz */
310   GPIOE->OSPEEDR = 0xFFFFC3CF;
311   /* Configure PEx pins Output type to push-pull */
312   GPIOE->OTYPER  = 0x00000000;
313   /* No pull-up, pull-down for PEx pins */
314   GPIOE->PUPDR   = 0x00000000;
315 
316   /* Connect PFx pins to FMC Alternate function */
317   GPIOF->AFR[0]  = 0xCCCCCCCC;
318   GPIOF->AFR[1]  = 0xCCCCCCCC;
319   /* Configure PFx pins in Alternate function mode */
320   GPIOF->MODER   = 0xAA800AAA;
321   /* Configure PFx pins speed to 50 MHz */
322   GPIOF->OSPEEDR = 0xAA800AAA;
323   /* Configure PFx pins Output type to push-pull */
324   GPIOF->OTYPER  = 0x00000000;
325   /* No pull-up, pull-down for PFx pins */
326   GPIOF->PUPDR   = 0x00000000;
327 
328   /* Connect PGx pins to FMC Alternate function */
329   GPIOG->AFR[0]  = 0xCCCCCCCC;
330   GPIOG->AFR[1]  = 0xCCCCCCCC;
331   /* Configure PGx pins in Alternate function mode */
332   GPIOG->MODER   = 0xAAAAAAAA;
333   /* Configure PGx pins speed to 50 MHz */
334   GPIOG->OSPEEDR = 0xAAAAAAAA;
335   /* Configure PGx pins Output type to push-pull */
336   GPIOG->OTYPER  = 0x00000000;
337   /* No pull-up, pull-down for PGx pins */
338   GPIOG->PUPDR   = 0x00000000;
339 
340   /* Connect PHx pins to FMC Alternate function */
341   GPIOH->AFR[0]  = 0x00C0CC00;
342   GPIOH->AFR[1]  = 0xCCCCCCCC;
343   /* Configure PHx pins in Alternate function mode */
344   GPIOH->MODER   = 0xAAAA08A0;
345   /* Configure PHx pins speed to 50 MHz */
346   GPIOH->OSPEEDR = 0xAAAA08A0;
347   /* Configure PHx pins Output type to push-pull */
348   GPIOH->OTYPER  = 0x00000000;
349   /* No pull-up, pull-down for PHx pins */
350   GPIOH->PUPDR   = 0x00000000;
351 
352   /* Connect PIx pins to FMC Alternate function */
353   GPIOI->AFR[0]  = 0xCCCCCCCC;
354   GPIOI->AFR[1]  = 0x00000CC0;
355   /* Configure PIx pins in Alternate function mode */
356   GPIOI->MODER   = 0x0028AAAA;
357   /* Configure PIx pins speed to 50 MHz */
358   GPIOI->OSPEEDR = 0x0028AAAA;
359   /* Configure PIx pins Output type to push-pull */
360   GPIOI->OTYPER  = 0x00000000;
361   /* No pull-up, pull-down for PIx pins */
362   GPIOI->PUPDR   = 0x00000000;
363 
364 /*-- FMC Configuration -------------------------------------------------------*/
365   /* Enable the FMC interface clock */
366   RCC->AHB3ENR |= 0x00000001;
367   /* Delay after an RCC peripheral clock enabling */
368   tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
369 
370   FMC_Bank5_6->SDCR[0] = 0x000019E4;
371   FMC_Bank5_6->SDTR[0] = 0x01115351;
372 
373   /* SDRAM initialization sequence */
374   /* Clock enable command */
375   FMC_Bank5_6->SDCMR = 0x00000011;
376   tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
377   while((tmpreg != 0) && (timeout-- > 0))
378   {
379     tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
380   }
381 
382   /* Delay */
383   for (index = 0; index<1000; index++);
384 
385   /* PALL command */
386   FMC_Bank5_6->SDCMR = 0x00000012;
387   tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
388   timeout = 0xFFFF;
389   while((tmpreg != 0) && (timeout-- > 0))
390   {
391     tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
392   }
393 
394   /* Auto refresh command */
395   FMC_Bank5_6->SDCMR = 0x00000073;
396   tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
397   timeout = 0xFFFF;
398   while((tmpreg != 0) && (timeout-- > 0))
399   {
400     tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
401   }
402 
403   /* MRD register program */
404   FMC_Bank5_6->SDCMR = 0x00046014;
405   tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
406   timeout = 0xFFFF;
407   while((tmpreg != 0) && (timeout-- > 0))
408   {
409     tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
410   }
411 
412   /* Set refresh count */
413   tmpreg = FMC_Bank5_6->SDRTR;
414   FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
415 
416   /* Disable write protection */
417   tmpreg = FMC_Bank5_6->SDCR[0];
418   FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
419 
420 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
421   /* Configure and enable Bank1_SRAM2 */
422   FMC_Bank1->BTCR[2]  = 0x00001011;
423   FMC_Bank1->BTCR[3]  = 0x00000201;
424   FMC_Bank1E->BWTR[2] = 0x0fffffff;
425 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
426 #if defined(STM32F469xx) || defined(STM32F479xx)
427   /* Configure and enable Bank1_SRAM2 */
428   FMC_Bank1->BTCR[2]  = 0x00001091;
429   FMC_Bank1->BTCR[3]  = 0x00110212;
430   FMC_Bank1E->BWTR[2] = 0x0fffffff;
431 #endif /* STM32F469xx || STM32F479xx */
432 
433   (void)(tmp);
434 }
435 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
436 #elif defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
437 /**
438   * @brief  Setup the external memory controller.
439   *         Called in startup_stm32f4xx.s before jump to main.
440   *         This function configures the external memories (SRAM/SDRAM)
441   *         This SRAM/SDRAM will be used as program data memory (including heap and stack).
442   * @param  None
443   * @retval None
444   */
SystemInit_ExtMemCtl(void)445 void SystemInit_ExtMemCtl(void)
446 {
447   __IO uint32_t tmp = 0x00;
448 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
449  || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
450 #if defined (DATA_IN_ExtSDRAM)
451   register uint32_t tmpreg = 0, timeout = 0xFFFF;
452   register __IO uint32_t index;
453 
454 #if defined(STM32F446xx)
455   /* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface
456       clock */
457   RCC->AHB1ENR |= 0x0000007D;
458 #else
459   /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface
460       clock */
461   RCC->AHB1ENR |= 0x000001F8;
462 #endif /* STM32F446xx */
463   /* Delay after an RCC peripheral clock enabling */
464   tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
465 
466 #if defined(STM32F446xx)
467   /* Connect PAx pins to FMC Alternate function */
468   GPIOA->AFR[0]  |= 0xC0000000;
469   GPIOA->AFR[1]  |= 0x00000000;
470   /* Configure PDx pins in Alternate function mode */
471   GPIOA->MODER   |= 0x00008000;
472   /* Configure PDx pins speed to 50 MHz */
473   GPIOA->OSPEEDR |= 0x00008000;
474   /* Configure PDx pins Output type to push-pull */
475   GPIOA->OTYPER  |= 0x00000000;
476   /* No pull-up, pull-down for PDx pins */
477   GPIOA->PUPDR   |= 0x00000000;
478 
479   /* Connect PCx pins to FMC Alternate function */
480   GPIOC->AFR[0]  |= 0x00CC0000;
481   GPIOC->AFR[1]  |= 0x00000000;
482   /* Configure PDx pins in Alternate function mode */
483   GPIOC->MODER   |= 0x00000A00;
484   /* Configure PDx pins speed to 50 MHz */
485   GPIOC->OSPEEDR |= 0x00000A00;
486   /* Configure PDx pins Output type to push-pull */
487   GPIOC->OTYPER  |= 0x00000000;
488   /* No pull-up, pull-down for PDx pins */
489   GPIOC->PUPDR   |= 0x00000000;
490 #endif /* STM32F446xx */
491 
492   /* Connect PDx pins to FMC Alternate function */
493   GPIOD->AFR[0]  = 0x000000CC;
494   GPIOD->AFR[1]  = 0xCC000CCC;
495   /* Configure PDx pins in Alternate function mode */
496   GPIOD->MODER   = 0xA02A000A;
497   /* Configure PDx pins speed to 50 MHz */
498   GPIOD->OSPEEDR = 0xA02A000A;
499   /* Configure PDx pins Output type to push-pull */
500   GPIOD->OTYPER  = 0x00000000;
501   /* No pull-up, pull-down for PDx pins */
502   GPIOD->PUPDR   = 0x00000000;
503 
504   /* Connect PEx pins to FMC Alternate function */
505   GPIOE->AFR[0]  = 0xC00000CC;
506   GPIOE->AFR[1]  = 0xCCCCCCCC;
507   /* Configure PEx pins in Alternate function mode */
508   GPIOE->MODER   = 0xAAAA800A;
509   /* Configure PEx pins speed to 50 MHz */
510   GPIOE->OSPEEDR = 0xAAAA800A;
511   /* Configure PEx pins Output type to push-pull */
512   GPIOE->OTYPER  = 0x00000000;
513   /* No pull-up, pull-down for PEx pins */
514   GPIOE->PUPDR   = 0x00000000;
515 
516   /* Connect PFx pins to FMC Alternate function */
517   GPIOF->AFR[0]  = 0xCCCCCCCC;
518   GPIOF->AFR[1]  = 0xCCCCCCCC;
519   /* Configure PFx pins in Alternate function mode */
520   GPIOF->MODER   = 0xAA800AAA;
521   /* Configure PFx pins speed to 50 MHz */
522   GPIOF->OSPEEDR = 0xAA800AAA;
523   /* Configure PFx pins Output type to push-pull */
524   GPIOF->OTYPER  = 0x00000000;
525   /* No pull-up, pull-down for PFx pins */
526   GPIOF->PUPDR   = 0x00000000;
527 
528   /* Connect PGx pins to FMC Alternate function */
529   GPIOG->AFR[0]  = 0xCCCCCCCC;
530   GPIOG->AFR[1]  = 0xCCCCCCCC;
531   /* Configure PGx pins in Alternate function mode */
532   GPIOG->MODER   = 0xAAAAAAAA;
533   /* Configure PGx pins speed to 50 MHz */
534   GPIOG->OSPEEDR = 0xAAAAAAAA;
535   /* Configure PGx pins Output type to push-pull */
536   GPIOG->OTYPER  = 0x00000000;
537   /* No pull-up, pull-down for PGx pins */
538   GPIOG->PUPDR   = 0x00000000;
539 
540 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
541  || defined(STM32F469xx) || defined(STM32F479xx)
542   /* Connect PHx pins to FMC Alternate function */
543   GPIOH->AFR[0]  = 0x00C0CC00;
544   GPIOH->AFR[1]  = 0xCCCCCCCC;
545   /* Configure PHx pins in Alternate function mode */
546   GPIOH->MODER   = 0xAAAA08A0;
547   /* Configure PHx pins speed to 50 MHz */
548   GPIOH->OSPEEDR = 0xAAAA08A0;
549   /* Configure PHx pins Output type to push-pull */
550   GPIOH->OTYPER  = 0x00000000;
551   /* No pull-up, pull-down for PHx pins */
552   GPIOH->PUPDR   = 0x00000000;
553 
554   /* Connect PIx pins to FMC Alternate function */
555   GPIOI->AFR[0]  = 0xCCCCCCCC;
556   GPIOI->AFR[1]  = 0x00000CC0;
557   /* Configure PIx pins in Alternate function mode */
558   GPIOI->MODER   = 0x0028AAAA;
559   /* Configure PIx pins speed to 50 MHz */
560   GPIOI->OSPEEDR = 0x0028AAAA;
561   /* Configure PIx pins Output type to push-pull */
562   GPIOI->OTYPER  = 0x00000000;
563   /* No pull-up, pull-down for PIx pins */
564   GPIOI->PUPDR   = 0x00000000;
565 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
566 
567 /*-- FMC Configuration -------------------------------------------------------*/
568   /* Enable the FMC interface clock */
569   RCC->AHB3ENR |= 0x00000001;
570   /* Delay after an RCC peripheral clock enabling */
571   tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
572 
573   /* Configure and enable SDRAM bank1 */
574 #if defined(STM32F446xx)
575   FMC_Bank5_6->SDCR[0] = 0x00001954;
576 #else
577   FMC_Bank5_6->SDCR[0] = 0x000019E4;
578 #endif /* STM32F446xx */
579   FMC_Bank5_6->SDTR[0] = 0x01115351;
580 
581   /* SDRAM initialization sequence */
582   /* Clock enable command */
583   FMC_Bank5_6->SDCMR = 0x00000011;
584   tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
585   while((tmpreg != 0) && (timeout-- > 0))
586   {
587     tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
588   }
589 
590   /* Delay */
591   for (index = 0; index<1000; index++);
592 
593   /* PALL command */
594   FMC_Bank5_6->SDCMR = 0x00000012;
595   tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
596   timeout = 0xFFFF;
597   while((tmpreg != 0) && (timeout-- > 0))
598   {
599     tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
600   }
601 
602   /* Auto refresh command */
603 #if defined(STM32F446xx)
604   FMC_Bank5_6->SDCMR = 0x000000F3;
605 #else
606   FMC_Bank5_6->SDCMR = 0x00000073;
607 #endif /* STM32F446xx */
608   tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
609   timeout = 0xFFFF;
610   while((tmpreg != 0) && (timeout-- > 0))
611   {
612     tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
613   }
614 
615   /* MRD register program */
616 #if defined(STM32F446xx)
617   FMC_Bank5_6->SDCMR = 0x00044014;
618 #else
619   FMC_Bank5_6->SDCMR = 0x00046014;
620 #endif /* STM32F446xx */
621   tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
622   timeout = 0xFFFF;
623   while((tmpreg != 0) && (timeout-- > 0))
624   {
625     tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
626   }
627 
628   /* Set refresh count */
629   tmpreg = FMC_Bank5_6->SDRTR;
630 #if defined(STM32F446xx)
631   FMC_Bank5_6->SDRTR = (tmpreg | (0x0000050C<<1));
632 #else
633   FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
634 #endif /* STM32F446xx */
635 
636   /* Disable write protection */
637   tmpreg = FMC_Bank5_6->SDCR[0];
638   FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
639 #endif /* DATA_IN_ExtSDRAM */
640 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */
641 
642 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
643  || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
644  || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
645 
646 #if defined(DATA_IN_ExtSRAM)
647 /*-- GPIOs Configuration -----------------------------------------------------*/
648    /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
649   RCC->AHB1ENR   |= 0x00000078;
650   /* Delay after an RCC peripheral clock enabling */
651   tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);
652 
653   /* Connect PDx pins to FMC Alternate function */
654   GPIOD->AFR[0]  = 0x00CCC0CC;
655   GPIOD->AFR[1]  = 0xCCCCCCCC;
656   /* Configure PDx pins in Alternate function mode */
657   GPIOD->MODER   = 0xAAAA0A8A;
658   /* Configure PDx pins speed to 100 MHz */
659   GPIOD->OSPEEDR = 0xFFFF0FCF;
660   /* Configure PDx pins Output type to push-pull */
661   GPIOD->OTYPER  = 0x00000000;
662   /* No pull-up, pull-down for PDx pins */
663   GPIOD->PUPDR   = 0x00000000;
664 
665   /* Connect PEx pins to FMC Alternate function */
666   GPIOE->AFR[0]  = 0xC00CC0CC;
667   GPIOE->AFR[1]  = 0xCCCCCCCC;
668   /* Configure PEx pins in Alternate function mode */
669   GPIOE->MODER   = 0xAAAA828A;
670   /* Configure PEx pins speed to 100 MHz */
671   GPIOE->OSPEEDR = 0xFFFFC3CF;
672   /* Configure PEx pins Output type to push-pull */
673   GPIOE->OTYPER  = 0x00000000;
674   /* No pull-up, pull-down for PEx pins */
675   GPIOE->PUPDR   = 0x00000000;
676 
677   /* Connect PFx pins to FMC Alternate function */
678   GPIOF->AFR[0]  = 0x00CCCCCC;
679   GPIOF->AFR[1]  = 0xCCCC0000;
680   /* Configure PFx pins in Alternate function mode */
681   GPIOF->MODER   = 0xAA000AAA;
682   /* Configure PFx pins speed to 100 MHz */
683   GPIOF->OSPEEDR = 0xFF000FFF;
684   /* Configure PFx pins Output type to push-pull */
685   GPIOF->OTYPER  = 0x00000000;
686   /* No pull-up, pull-down for PFx pins */
687   GPIOF->PUPDR   = 0x00000000;
688 
689   /* Connect PGx pins to FMC Alternate function */
690   GPIOG->AFR[0]  = 0x00CCCCCC;
691   GPIOG->AFR[1]  = 0x000000C0;
692   /* Configure PGx pins in Alternate function mode */
693   GPIOG->MODER   = 0x00085AAA;
694   /* Configure PGx pins speed to 100 MHz */
695   GPIOG->OSPEEDR = 0x000CAFFF;
696   /* Configure PGx pins Output type to push-pull */
697   GPIOG->OTYPER  = 0x00000000;
698   /* No pull-up, pull-down for PGx pins */
699   GPIOG->PUPDR   = 0x00000000;
700 
701 /*-- FMC/FSMC Configuration --------------------------------------------------*/
702   /* Enable the FMC/FSMC interface clock */
703   RCC->AHB3ENR         |= 0x00000001;
704 
705 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
706   /* Delay after an RCC peripheral clock enabling */
707   tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
708   /* Configure and enable Bank1_SRAM2 */
709   FMC_Bank1->BTCR[2]  = 0x00001011;
710   FMC_Bank1->BTCR[3]  = 0x00000201;
711   FMC_Bank1E->BWTR[2] = 0x0fffffff;
712 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
713 #if defined(STM32F469xx) || defined(STM32F479xx)
714   /* Delay after an RCC peripheral clock enabling */
715   tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
716   /* Configure and enable Bank1_SRAM2 */
717   FMC_Bank1->BTCR[2]  = 0x00001091;
718   FMC_Bank1->BTCR[3]  = 0x00110212;
719   FMC_Bank1E->BWTR[2] = 0x0fffffff;
720 #endif /* STM32F469xx || STM32F479xx */
721 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)\
722    || defined(STM32F412Zx) || defined(STM32F412Vx)
723   /* Delay after an RCC peripheral clock enabling */
724   tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN);
725   /* Configure and enable Bank1_SRAM2 */
726   FSMC_Bank1->BTCR[2]  = 0x00001011;
727   FSMC_Bank1->BTCR[3]  = 0x00000201;
728   FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF;
729 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F412Zx || STM32F412Vx */
730 
731 #endif /* DATA_IN_ExtSRAM */
732 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\
733           STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx  */
734   (void)(tmp);
735 }
736 #endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */
737 /**
738   * @}
739   */
740 
741 /**
742   * @}
743   */
744 
745 /**
746   * @}
747   */
748