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