• 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 
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 /* Note: Following vector table addresses must be defined in line with linker
91          configuration. */
92 /*!< Uncomment the following line if you need to relocate the vector table
93     anywhere in Flash or Sram, else the vector table is kept at the automatic
94     remap of boot address selected */
95 #define USER_VECT_TAB_ADDRESS
96 
97 #if defined(USER_VECT_TAB_ADDRESS)
98 /* !< Uncomment the following line if you need to relocate your vector Table
99     in Sram else user remap will be done in Flash. */
100 /* define VECT_TAB_SRAM */
101 #if defined(VECT_TAB_SRAM)
102 #define VECT_TAB_BASE_ADDRESS   SRAM_BASE       /*!< Vector Table base address field.
103                                                      This value must be a multiple of 0x200. */
104 #define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table base offset field.
105                                                      This value must be a multiple of 0x200. */
106 #else
107 #define VECT_TAB_BASE_ADDRESS   FLASH_BASE      /*!< Vector Table base address field.
108                                                      This value must be a multiple of 0x200. */
109 #define VECT_TAB_OFFSET         0x00010000U     /*!< Vector Table base offset field.
110                                                      This value must be a multiple of 0x200. */
111 #endif /* VECT_TAB_SRAM */
112 #endif /* USER_VECT_TAB_ADDRESS */
113 /******************************************************************************/
114 
115 /**
116   * @}
117   */
118 
119 /** @addtogroup STM32F4xx_System_Private_Macros
120   * @{
121   */
122 
123 /**
124   * @}
125   */
126 
127 /** @addtogroup STM32F4xx_System_Private_Variables
128   * @{
129   */
130   /* This variable is updated in three ways:
131       1) by calling CMSIS function SystemCoreClockUpdate()
132       2) by calling HAL API function HAL_RCC_GetHCLKFreq()
133       3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
134          Note: If you use this function to configure the system clock; then there
135                is no need to call the 2 first functions listed above, since SystemCoreClock
136                variable is updated automatically.
137   */
138 uint32_t SystemCoreClock = 16000000;
139 const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
140 const uint8_t APBPrescTable[8]  = {0, 0, 0, 0, 1, 2, 3, 4};
141 /**
142   * @}
143   */
144 
145 /** @addtogroup STM32F4xx_System_Private_FunctionPrototypes
146   * @{
147   */
148 
149 #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
150     static void SystemInit_ExtMemCtl(void);
151 #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
152 
153 /**
154   * @}
155   */
156 
157 /** @addtogroup STM32F4xx_System_Private_Functions
158   * @{
159   */
160 
161 /**
162   * @brief  Setup the microcontroller system
163   *         Initialize the FPU setting, vector table location and External memory
164   *         configuration.
165   * @param  None
166   * @retval None
167   */
SystemInit(void)168 void SystemInit(void)
169 {
170   /* FPU settings ------------------------------------------------------------ */
171 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
172     SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
173 #endif
174 
175 #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
176     SystemInit_ExtMemCtl();
177 #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
178 
179     /* Configure the Vector Table location -------------------------------------*/
180 #if defined(USER_VECT_TAB_ADDRESS)
181 
182     SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
183 #endif /* USER_VECT_TAB_ADDRESS */
184 }
185 
186 /**
187    * @brief  Update SystemCoreClock variable according to Clock Register Values.
188   *         The SystemCoreClock variable contains the core clock (HCLK), it can
189   *         be used by the user application to setup the SysTick timer or configure
190   *         other parameters.
191   *
192   * @note   Each time the core clock (HCLK) changes, this function must be called
193   *         to update SystemCoreClock variable value. Otherwise, any configuration
194   *         based on this variable will be incorrect.
195   *
196   * @note   - The system frequency computed by this function is not the real
197   *           frequency in the chip. It is calculated based on the predefined
198   *           constant and the selected clock source:
199   *
200   *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
201   *
202   *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
203   *
204   *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
205   *             or HSI_VALUE(*) multiplied/divided by the PLL factors.
206   *
207   *         (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
208   *             16 MHz) but the real value may vary depending on the variations
209   *             in voltage and temperature.
210   *
211   *         (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value
212   *              depends on the application requirements), user has to ensure that HSE_VALUE
213   *              is same as the real frequency of the crystal used. Otherwise, this function
214   *              may have wrong result.
215   *
216   *         - The result of this function could be not correct when using fractional
217   *           value for HSE crystal.
218   *
219   * @param  None
220   * @retval None
221   */
SystemCoreClockUpdate(void)222 void SystemCoreClockUpdate(void)
223 {
224     uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
225 
226     /* Get SYSCLK source -------------------------------------------------------*/
227     tmp = RCC->CFGR & RCC_CFGR_SWS;
228 
229     switch (tmp) {
230         case 0x00:  /* HSI used as system clock source */
231             SystemCoreClock = HSI_VALUE;
232             break;
233         case 0x04:  /* HSE used as system clock source */
234             SystemCoreClock = HSE_VALUE;
235             break;
236         case 0x08:  /* PLL used as system clock source */
237 
238         /* PLL_VCO = (HSE_VALUE or HSI_VALUE /PLL_M) * PLL_N
239           SYSCLK = PLL_VCO /PLL_P
240           */
241             pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
242             pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
243 
244             if (pllsource != 0) {
245                 /* HSE used as PLL clock source */
246                 pllvco = (HSE_VALUE /pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
247             } else {
248                 /* HSI used as PLL clock source */
249                 pllvco = (HSI_VALUE /pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
250             }
251 
252             pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1) *2;
253             SystemCoreClock = pllvco/pllp;
254             break;
255         default:
256             SystemCoreClock = HSI_VALUE;
257             break;
258     }
259     /* Compute HCLK frequency --------------------------------------------------*/
260     /* Get HCLK prescaler */
261     tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
262     /* HCLK frequency */
263     SystemCoreClock >>= tmp;
264 }
265 
266 #if defined (DATA_IN_ExtSRAM) && defined (DATA_IN_ExtSDRAM)
267 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
268     defined(STM32F469xx) || defined(STM32F479xx)
269 /**
270   * @brief  Setup the external memory controller.
271   *         Called in startup_stm32f4xx.s before jump to main.
272   *         This function configures the external memories (SRAM/SDRAM)
273   *         This SRAM/SDRAM will be used as program data memory (including heap and stack).
274   * @param  None
275   * @retval None
276   */
SystemInit_ExtMemCtl(void)277 void SystemInit_ExtMemCtl(void)
278 {
279     __IO uint32_t tmp = 0x00;
280 
281     register uint32_t tmpreg = 0, timeout = 0xFFFF;
282     register __IO uint32_t index;
283 
284   /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */
285     RCC->AHB1ENR |= 0x000001F8;
286 
287     /* Delay after an RCC peripheral clock enabling */
288     tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
289 
290     /* Connect PDx pins to FMC Alternate function */
291     GPIOD->AFR[0]  = 0x00CCC0CC;
292     GPIOD->AFR[1]  = 0xCCCCCCCC;
293     /* Configure PDx pins in Alternate function mode */
294     GPIOD->MODER   = 0xAAAA0A8A;
295     /* Configure PDx pins speed to 100 MHz */
296     GPIOD->OSPEEDR = 0xFFFF0FCF;
297     /* Configure PDx pins Output type to push-pull */
298     GPIOD->OTYPER  = 0x00000000;
299     /* No pull-up, pull-down for PDx pins */
300     GPIOD->PUPDR   = 0x00000000;
301 
302     /* Connect PEx pins to FMC Alternate function */
303     GPIOE->AFR[0]  = 0xC00CC0CC;
304     GPIOE->AFR[1]  = 0xCCCCCCCC;
305     /* Configure PEx pins in Alternate function mode */
306     GPIOE->MODER   = 0xAAAA828A;
307     /* Configure PEx pins speed to 100 MHz */
308     GPIOE->OSPEEDR = 0xFFFFC3CF;
309     /* Configure PEx pins Output type to push-pull */
310     GPIOE->OTYPER  = 0x00000000;
311     /* No pull-up, pull-down for PEx pins */
312     GPIOE->PUPDR   = 0x00000000;
313 
314     /* Connect PFx pins to FMC Alternate function */
315     GPIOF->AFR[0]  = 0xCCCCCCCC;
316     GPIOF->AFR[1]  = 0xCCCCCCCC;
317     /* Configure PFx pins in Alternate function mode */
318     GPIOF->MODER   = 0xAA800AAA;
319     /* Configure PFx pins speed to 50 MHz */
320     GPIOF->OSPEEDR = 0xAA800AAA;
321     /* Configure PFx pins Output type to push-pull */
322     GPIOF->OTYPER  = 0x00000000;
323     /* No pull-up, pull-down for PFx pins */
324     GPIOF->PUPDR   = 0x00000000;
325 
326     /* Connect PGx pins to FMC Alternate function */
327     GPIOG->AFR[0]  = 0xCCCCCCCC;
328     GPIOG->AFR[1]  = 0xCCCCCCCC;
329     /* Configure PGx pins in Alternate function mode */
330     GPIOG->MODER   = 0xAAAAAAAA;
331     /* Configure PGx pins speed to 50 MHz */
332     GPIOG->OSPEEDR = 0xAAAAAAAA;
333     /* Configure PGx pins Output type to push-pull */
334     GPIOG->OTYPER  = 0x00000000;
335     /* No pull-up, pull-down for PGx pins */
336     GPIOG->PUPDR   = 0x00000000;
337 
338     /* Connect PHx pins to FMC Alternate function */
339     GPIOH->AFR[0]  = 0x00C0CC00;
340     GPIOH->AFR[1]  = 0xCCCCCCCC;
341     /* Configure PHx pins in Alternate function mode */
342     GPIOH->MODER   = 0xAAAA08A0;
343     /* Configure PHx pins speed to 50 MHz */
344     GPIOH->OSPEEDR = 0xAAAA08A0;
345     /* Configure PHx pins Output type to push-pull */
346     GPIOH->OTYPER  = 0x00000000;
347     /* No pull-up, pull-down for PHx pins */
348     GPIOH->PUPDR   = 0x00000000;
349 
350     /* Connect PIx pins to FMC Alternate function */
351     GPIOI->AFR[0]  = 0xCCCCCCCC;
352     GPIOI->AFR[1]  = 0x00000CC0;
353     /* Configure PIx pins in Alternate function mode */
354     GPIOI->MODER   = 0x0028AAAA;
355     /* Configure PIx pins speed to 50 MHz */
356     GPIOI->OSPEEDR = 0x0028AAAA;
357     /* Configure PIx pins Output type to push-pull */
358     GPIOI->OTYPER  = 0x00000000;
359     /* No pull-up, pull-down for PIx pins */
360     GPIOI->PUPDR   = 0x00000000;
361 
362 /* -- FMC Configuration ------------------------------------------------------- */
363     /* Enable the FMC interface clock */
364     RCC->AHB3ENR |= 0x00000001;
365     /* Delay after an RCC peripheral clock enabling */
366     tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
367 
368     FMC_Bank5_6->SDCR[0] = 0x000019E4;
369     FMC_Bank5_6->SDTR[0] = 0x01115351;
370 
371     /* SDRAM initialization sequence */
372     /* Clock enable command */
373     FMC_Bank5_6->SDCMR = 0x00000011;
374     tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
375     while ((tmpreg != 0) && (timeout-- > 0)) {
376         tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
377     }
378 
379     /* Delay */
380     for (index = 0; index<1000; index++);
381 
382     /* PALL command */
383     FMC_Bank5_6->SDCMR = 0x00000012;
384     tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
385     timeout = 0xFFFF;
386     while ((tmpreg != 0) && (timeout-- > 0)) {
387         tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
388     }
389 
390     /* Auto refresh command */
391     FMC_Bank5_6->SDCMR = 0x00000073;
392     tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
393     timeout = 0xFFFF;
394     while ((tmpreg != 0) && (timeout-- > 0)) {
395         tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
396     }
397 
398     /* MRD register program */
399     FMC_Bank5_6->SDCMR = 0x00046014;
400     tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
401     timeout = 0xFFFF;
402     while ((tmpreg != 0) && (timeout-- > 0)) {
403         tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
404     }
405 
406     /* Set refresh count */
407     tmpreg = FMC_Bank5_6->SDRTR;
408     FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
409 
410     /* Disable write protection */
411     tmpreg = FMC_Bank5_6->SDCR[0];
412     FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
413 
414 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
415     /* Configure and enable Bank1_SRAM2 */
416     FMC_Bank1->BTCR[2]  = 0x00001011;
417     FMC_Bank1->BTCR[3]  = 0x00000201;
418     FMC_Bank1E->BWTR[2] = 0x0fffffff;
419 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
420 #if defined(STM32F469xx) || defined(STM32F479xx)
421     /* Configure and enable Bank1_SRAM2 */
422     FMC_Bank1->BTCR[2]  = 0x00001091;
423     FMC_Bank1->BTCR[3]  = 0x00110212;
424     FMC_Bank1E->BWTR[2] = 0x0fffffff;
425 #endif /* STM32F469xx || STM32F479xx */
426 
427     (void)(tmp);
428 }
429 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
430 #elif defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
431 /**
432   * @brief  Setup the external memory controller.
433   *         Called in startup_stm32f4xx.s before jump to main.
434   *         This function configures the external memories (SRAM/SDRAM)
435   *         This SRAM/SDRAM will be used as program data memory (including heap and stack).
436   * @param  None
437   * @retval None
438   */
SystemInit_ExtMemCtl(void)439 void SystemInit_ExtMemCtl(void)
440 {
441     __IO uint32_t tmp = 0x00;
442 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
443     defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
444 #if defined (DATA_IN_ExtSDRAM)
445     register uint32_t tmpreg = 0, timeout = 0xFFFF;
446     register __IO uint32_t index;
447 
448 #if defined(STM32F446xx)
449     /* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface
450       clock */
451     RCC->AHB1ENR |= 0x0000007D;
452 #else
453     /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface
454       clock */
455     RCC->AHB1ENR |= 0x000001F8;
456 #endif /* STM32F446xx */
457     /* Delay after an RCC peripheral clock enabling */
458     tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
459 
460 #if defined(STM32F446xx)
461     /* Connect PAx pins to FMC Alternate function */
462     GPIOA->AFR[0]  |= 0xC0000000;
463     GPIOA->AFR[1]  |= 0x00000000;
464     /* Configure PDx pins in Alternate function mode */
465     GPIOA->MODER   |= 0x00008000;
466     /* Configure PDx pins speed to 50 MHz */
467     GPIOA->OSPEEDR |= 0x00008000;
468     /* Configure PDx pins Output type to push-pull */
469     GPIOA->OTYPER  |= 0x00000000;
470     /* No pull-up, pull-down for PDx pins */
471     GPIOA->PUPDR   |= 0x00000000;
472 
473     /* Connect PCx pins to FMC Alternate function */
474     GPIOC->AFR[0]  |= 0x00CC0000;
475     GPIOC->AFR[1]  |= 0x00000000;
476     /* Configure PDx pins in Alternate function mode */
477     GPIOC->MODER   |= 0x00000A00;
478     /* Configure PDx pins speed to 50 MHz */
479     GPIOC->OSPEEDR |= 0x00000A00;
480     /* Configure PDx pins Output type to push-pull */
481     GPIOC->OTYPER  |= 0x00000000;
482     /* No pull-up, pull-down for PDx pins */
483     GPIOC->PUPDR   |= 0x00000000;
484 #endif /* STM32F446xx */
485 
486     /* Connect PDx pins to FMC Alternate function */
487     GPIOD->AFR[0]  = 0x000000CC;
488     GPIOD->AFR[1]  = 0xCC000CCC;
489     /* Configure PDx pins in Alternate function mode */
490     GPIOD->MODER   = 0xA02A000A;
491     /* Configure PDx pins speed to 50 MHz */
492     GPIOD->OSPEEDR = 0xA02A000A;
493     /* Configure PDx pins Output type to push-pull */
494     GPIOD->OTYPER  = 0x00000000;
495     /* No pull-up, pull-down for PDx pins */
496     GPIOD->PUPDR   = 0x00000000;
497 
498     /* Connect PEx pins to FMC Alternate function */
499     GPIOE->AFR[0]  = 0xC00000CC;
500     GPIOE->AFR[1]  = 0xCCCCCCCC;
501     /* Configure PEx pins in Alternate function mode */
502     GPIOE->MODER   = 0xAAAA800A;
503     /* Configure PEx pins speed to 50 MHz */
504     GPIOE->OSPEEDR = 0xAAAA800A;
505     /* Configure PEx pins Output type to push-pull */
506     GPIOE->OTYPER  = 0x00000000;
507     /* No pull-up, pull-down for PEx pins */
508     GPIOE->PUPDR   = 0x00000000;
509 
510     /* Connect PFx pins to FMC Alternate function */
511     GPIOF->AFR[0]  = 0xCCCCCCCC;
512     GPIOF->AFR[1]  = 0xCCCCCCCC;
513     /* Configure PFx pins in Alternate function mode */
514     GPIOF->MODER   = 0xAA800AAA;
515     /* Configure PFx pins speed to 50 MHz */
516     GPIOF->OSPEEDR = 0xAA800AAA;
517     /* Configure PFx pins Output type to push-pull */
518     GPIOF->OTYPER  = 0x00000000;
519     /* No pull-up, pull-down for PFx pins */
520     GPIOF->PUPDR   = 0x00000000;
521 
522     /* Connect PGx pins to FMC Alternate function */
523     GPIOG->AFR[0]  = 0xCCCCCCCC;
524     GPIOG->AFR[1]  = 0xCCCCCCCC;
525     /* Configure PGx pins in Alternate function mode */
526     GPIOG->MODER   = 0xAAAAAAAA;
527     /* Configure PGx pins speed to 50 MHz */
528     GPIOG->OSPEEDR = 0xAAAAAAAA;
529     /* Configure PGx pins Output type to push-pull */
530     GPIOG->OTYPER  = 0x00000000;
531     /* No pull-up, pull-down for PGx pins */
532     GPIOG->PUPDR   = 0x00000000;
533 
534 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
535     defined(STM32F469xx) || defined(STM32F479xx)
536     /* Connect PHx pins to FMC Alternate function */
537     GPIOH->AFR[0]  = 0x00C0CC00;
538     GPIOH->AFR[1]  = 0xCCCCCCCC;
539     /* Configure PHx pins in Alternate function mode */
540     GPIOH->MODER   = 0xAAAA08A0;
541     /* Configure PHx pins speed to 50 MHz */
542     GPIOH->OSPEEDR = 0xAAAA08A0;
543     /* Configure PHx pins Output type to push-pull */
544     GPIOH->OTYPER  = 0x00000000;
545     /* No pull-up, pull-down for PHx pins */
546     GPIOH->PUPDR   = 0x00000000;
547 
548     /* Connect PIx pins to FMC Alternate function */
549     GPIOI->AFR[0]  = 0xCCCCCCCC;
550     GPIOI->AFR[1]  = 0x00000CC0;
551     /* Configure PIx pins in Alternate function mode */
552     GPIOI->MODER   = 0x0028AAAA;
553     /* Configure PIx pins speed to 50 MHz */
554     GPIOI->OSPEEDR = 0x0028AAAA;
555     /* Configure PIx pins Output type to push-pull */
556     GPIOI->OTYPER  = 0x00000000;
557     /* No pull-up, pull-down for PIx pins */
558     GPIOI->PUPDR   = 0x00000000;
559 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
560 
561 /* -- FMC Configuration ------------------------------------------------------- */
562     /* Enable the FMC interface clock */
563     RCC->AHB3ENR |= 0x00000001;
564     /* Delay after an RCC peripheral clock enabling */
565     tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
566 
567     /* Configure and enable SDRAM bank1 */
568 #if defined(STM32F446xx)
569     FMC_Bank5_6->SDCR[0] = 0x00001954;
570 #else
571     FMC_Bank5_6->SDCR[0] = 0x000019E4;
572 #endif /* STM32F446xx */
573     FMC_Bank5_6->SDTR[0] = 0x01115351;
574 
575     /* SDRAM initialization sequence */
576     /* Clock enable command */
577     FMC_Bank5_6->SDCMR = 0x00000011;
578     tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
579     while ((tmpreg != 0) && (timeout-- > 0)) {
580         tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
581     }
582 
583     /* Delay */
584     for (index = 0; index<1000; index++);
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