]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/TARGET_DISCO_F401VC/system_stm32f4xx.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F4 / TARGET_DISCO_F401VC / system_stm32f4xx.c
1 /**
2   ******************************************************************************
3   * @file    system_stm32f4xx.c
4   * @author  MCD Application Team
5   * @version V2.1.0
6   * @date    19-June-2014
7   * @brief   CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
8   *
9   *   This file provides two functions and one global variable to be called from 
10   *   user application:
11   *      - SystemInit(): This function is called at startup just after reset and 
12   *                      before branch to main program. This call is made inside
13   *                      the "startup_stm32f4xx.s" file.
14   *
15   *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
16   *                                  by the user application to setup the SysTick 
17   *                                  timer or configure other parameters.
18   *                                     
19   *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
20   *                                 be called whenever the core clock is changed
21   *                                 during program execution.
22   *
23   * This file configures the system clock as follows:
24   *-----------------------------------------------------------------------------
25   * System clock source                | 1- PLL_HSE_EXTC        | 3- PLL_HSI
26   *                                    | (external 8 MHz clock) | (internal 16 MHz)
27   *                                    | 2- PLL_HSE_XTAL        |
28   *                                    | (external 8 MHz xtal)  |
29   *-----------------------------------------------------------------------------
30   * SYSCLK(MHz)                        | 84                     | 84
31   *-----------------------------------------------------------------------------
32   * AHBCLK (MHz)                       | 84                     | 84
33   *-----------------------------------------------------------------------------
34   * APB1CLK (MHz)                      | 42                     | 42
35   *-----------------------------------------------------------------------------
36   * APB2CLK (MHz)                      | 84                     | 84
37   *-----------------------------------------------------------------------------
38   * USB capable (48 MHz precise clock) | YES                    | NO
39   *-----------------------------------------------------------------------------  
40   ******************************************************************************
41   * @attention
42   *
43   * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
44   *
45   * Redistribution and use in source and binary forms, with or without modification,
46   * are permitted provided that the following conditions are met:
47   *   1. Redistributions of source code must retain the above copyright notice,
48   *      this list of conditions and the following disclaimer.
49   *   2. Redistributions in binary form must reproduce the above copyright notice,
50   *      this list of conditions and the following disclaimer in the documentation
51   *      and/or other materials provided with the distribution.
52   *   3. Neither the name of STMicroelectronics nor the names of its contributors
53   *      may be used to endorse or promote products derived from this software
54   *      without specific prior written permission.
55   *
56   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
57   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
60   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
62   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
63   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
64   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
65   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
66   *
67   ******************************************************************************
68   */
69
70 /** @addtogroup CMSIS
71   * @{
72   */
73
74 /** @addtogroup stm32f4xx_system
75   * @{
76   */  
77   
78 /** @addtogroup STM32F4xx_System_Private_Includes
79   * @{
80   */
81
82 #include "stm32f4xx.h"
83 #include "hal_tick.h"
84
85 #if !defined  (HSE_VALUE) 
86   #define HSE_VALUE    ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz */
87 #endif /* HSE_VALUE */
88
89 #if !defined  (HSI_VALUE)
90   #define HSI_VALUE    ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
91 #endif /* HSI_VALUE */
92
93 /**
94   * @}
95   */
96
97 /** @addtogroup STM32F4xx_System_Private_TypesDefinitions
98   * @{
99   */
100
101 /**
102   * @}
103   */
104
105 /** @addtogroup STM32F4xx_System_Private_Defines
106   * @{
107   */
108
109 /************************* Miscellaneous Configuration ************************/
110 /*!< Uncomment the following line if you need to use external SRAM or SDRAM mounted
111      on STM324xG_EVAL/STM324x9I_EVAL boards as data memory  */
112 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
113 /* #define DATA_IN_ExtSRAM */
114 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
115  
116 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
117 /* #define DATA_IN_ExtSDRAM */
118 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
119
120 #if defined(DATA_IN_ExtSRAM) && defined(DATA_IN_ExtSDRAM)
121  #error "Please select DATA_IN_ExtSRAM or DATA_IN_ExtSDRAM " 
122 #endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */
123
124 /*!< Uncomment the following line if you need to relocate your vector Table in
125      Internal SRAM. */
126 /* #define VECT_TAB_SRAM */
127 #define VECT_TAB_OFFSET  0x00 /*!< Vector Table base offset field. 
128                                    This value must be a multiple of 0x200. */
129 /******************************************************************************/
130
131 /**
132   * @}
133   */
134
135 /** @addtogroup STM32F4xx_System_Private_Macros
136   * @{
137   */
138
139 /* Select the clock sources (other than HSI) to start with (0=OFF, 1=ON) */
140 #define USE_PLL_HSE_EXTC (1) /* Use external clock */
141 #define USE_PLL_HSE_XTAL (1) /* Use external xtal */
142
143 /**
144   * @}
145   */
146
147 /** @addtogroup STM32F4xx_System_Private_Variables
148   * @{
149   */
150   /* This variable is updated in three ways:
151       1) by calling CMSIS function SystemCoreClockUpdate()
152       2) by calling HAL API function HAL_RCC_GetHCLKFreq()
153       3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency 
154          Note: If you use this function to configure the system clock; then there
155                is no need to call the 2 first functions listed above, since SystemCoreClock
156                variable is updated automatically.
157   */
158 uint32_t SystemCoreClock = 84000000;
159 const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
160
161 /**
162   * @}
163   */
164
165 /** @addtogroup STM32F4xx_System_Private_FunctionPrototypes
166   * @{
167   */
168
169 #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
170   static void SystemInit_ExtMemCtl(void); 
171 #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
172
173 #if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0)
174 uint8_t SetSysClock_PLL_HSE(uint8_t bypass);
175 #endif
176
177 uint8_t SetSysClock_PLL_HSI(void);
178
179 /**
180   * @}
181   */
182
183 /** @addtogroup STM32F4xx_System_Private_Functions
184   * @{
185   */
186
187 /**
188   * @brief  Setup the microcontroller system
189   *         Initialize the FPU setting, vector table location and External memory 
190   *         configuration.
191   * @param  None
192   * @retval None
193   */
194 void SystemInit(void)
195 {
196   /* FPU settings ------------------------------------------------------------*/
197   #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
198     SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
199   #endif
200   /* Reset the RCC clock configuration to the default reset state ------------*/
201   /* Set HSION bit */
202   RCC->CR |= (uint32_t)0x00000001;
203
204   /* Reset CFGR register */
205   RCC->CFGR = 0x00000000;
206
207   /* Reset HSEON, CSSON and PLLON bits */
208   RCC->CR &= (uint32_t)0xFEF6FFFF;
209
210   /* Reset PLLCFGR register */
211   RCC->PLLCFGR = 0x24003010;
212
213   /* Reset HSEBYP bit */
214   RCC->CR &= (uint32_t)0xFFFBFFFF;
215
216   /* Disable all interrupts */
217   RCC->CIR = 0x00000000;
218
219 #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
220   SystemInit_ExtMemCtl(); 
221 #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
222
223   /* Configure the Vector Table location add offset address ------------------*/
224 #ifdef VECT_TAB_SRAM
225   SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
226 #else
227   SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
228 #endif
229
230   /* Configure the Cube driver */
231   SystemCoreClock = 16000000; // At this stage the HSI is used as system clock
232   HAL_Init();
233
234   /* Configure the System clock source, PLL Multiplier and Divider factors,
235      AHB/APBx prescalers and Flash settings */
236   SetSysClock();
237   
238   /* Reset the timer to avoid issues after the RAM initialization */
239   TIM_MST_RESET_ON;
240   TIM_MST_RESET_OFF;  
241 }
242
243 /**
244    * @brief  Update SystemCoreClock variable according to Clock Register Values.
245   *         The SystemCoreClock variable contains the core clock (HCLK), it can
246   *         be used by the user application to setup the SysTick timer or configure
247   *         other parameters.
248   *           
249   * @note   Each time the core clock (HCLK) changes, this function must be called
250   *         to update SystemCoreClock variable value. Otherwise, any configuration
251   *         based on this variable will be incorrect.         
252   *     
253   * @note   - The system frequency computed by this function is not the real 
254   *           frequency in the chip. It is calculated based on the predefined 
255   *           constant and the selected clock source:
256   *             
257   *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
258   *                                              
259   *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
260   *                          
261   *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) 
262   *             or HSI_VALUE(*) multiplied/divided by the PLL factors.
263   *         
264   *         (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
265   *             16 MHz) but the real value may vary depending on the variations
266   *             in voltage and temperature.   
267   *    
268   *         (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value
269   *              depends on the application requirements), user has to ensure that HSE_VALUE
270   *              is same as the real frequency of the crystal used. Otherwise, this function
271   *              may have wrong result.
272   *                
273   *         - The result of this function could be not correct when using fractional
274   *           value for HSE crystal.
275   *     
276   * @param  None
277   * @retval None
278   */
279 void SystemCoreClockUpdate(void)
280 {
281   uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
282   
283   /* Get SYSCLK source -------------------------------------------------------*/
284   tmp = RCC->CFGR & RCC_CFGR_SWS;
285
286   switch (tmp)
287   {
288     case 0x00:  /* HSI used as system clock source */
289       SystemCoreClock = HSI_VALUE;
290       break;
291     case 0x04:  /* HSE used as system clock source */
292       SystemCoreClock = HSE_VALUE;
293       break;
294     case 0x08:  /* PLL used as system clock source */
295
296       /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
297          SYSCLK = PLL_VCO / PLL_P
298          */    
299       pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
300       pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
301       
302       if (pllsource != 0)
303       {
304         /* HSE used as PLL clock source */
305         pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
306       }
307       else
308       {
309         /* HSI used as PLL clock source */
310         pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
311       }
312
313       pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
314       SystemCoreClock = pllvco/pllp;
315       break;
316     default:
317       SystemCoreClock = HSI_VALUE;
318       break;
319   }
320   /* Compute HCLK frequency --------------------------------------------------*/
321   /* Get HCLK prescaler */
322   tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
323   /* HCLK frequency */
324   SystemCoreClock >>= tmp;
325 }
326
327 #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
328 /**
329   * @brief  Setup the external memory controller.
330   *         Called in startup_stm32f4xx.s before jump to main.
331   *         This function configures the external memories (SRAM/SDRAM)
332   *         This SRAM/SDRAM will be used as program data memory (including heap and stack).
333   * @param  None
334   * @retval None
335   */
336 void SystemInit_ExtMemCtl(void)
337 {
338 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
339 #if defined (DATA_IN_ExtSDRAM)
340   register uint32_t tmpreg = 0, timeout = 0xFFFF;
341   register uint32_t index;
342
343   /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface 
344       clock */
345   RCC->AHB1ENR |= 0x000001F8;
346   
347   /* Connect PDx pins to FMC Alternate function */
348   GPIOD->AFR[0]  = 0x000000CC;
349   GPIOD->AFR[1]  = 0xCC000CCC;
350   /* Configure PDx pins in Alternate function mode */  
351   GPIOD->MODER   = 0xA02A000A;
352   /* Configure PDx pins speed to 50 MHz */  
353   GPIOD->OSPEEDR = 0xA02A000A;
354   /* Configure PDx pins Output type to push-pull */  
355   GPIOD->OTYPER  = 0x00000000;
356   /* No pull-up, pull-down for PDx pins */ 
357   GPIOD->PUPDR   = 0x00000000;
358
359   /* Connect PEx pins to FMC Alternate function */
360   GPIOE->AFR[0]  = 0xC00000CC;
361   GPIOE->AFR[1]  = 0xCCCCCCCC;
362   /* Configure PEx pins in Alternate function mode */ 
363   GPIOE->MODER   = 0xAAAA800A;
364   /* Configure PEx pins speed to 50 MHz */ 
365   GPIOE->OSPEEDR = 0xAAAA800A;
366   /* Configure PEx pins Output type to push-pull */  
367   GPIOE->OTYPER  = 0x00000000;
368   /* No pull-up, pull-down for PEx pins */ 
369   GPIOE->PUPDR   = 0x00000000;
370
371   /* Connect PFx pins to FMC Alternate function */
372   GPIOF->AFR[0]  = 0xCCCCCCCC;
373   GPIOF->AFR[1]  = 0xCCCCCCCC;
374   /* Configure PFx pins in Alternate function mode */   
375   GPIOF->MODER   = 0xAA800AAA;
376   /* Configure PFx pins speed to 50 MHz */ 
377   GPIOF->OSPEEDR = 0xAA800AAA;
378   /* Configure PFx pins Output type to push-pull */  
379   GPIOF->OTYPER  = 0x00000000;
380   /* No pull-up, pull-down for PFx pins */ 
381   GPIOF->PUPDR   = 0x00000000;
382
383   /* Connect PGx pins to FMC Alternate function */
384   GPIOG->AFR[0]  = 0xCCCCCCCC;
385   GPIOG->AFR[1]  = 0xCCCCCCCC;
386   /* Configure PGx pins in Alternate function mode */ 
387   GPIOG->MODER   = 0xAAAAAAAA;
388   /* Configure PGx pins speed to 50 MHz */ 
389   GPIOG->OSPEEDR = 0xAAAAAAAA;
390   /* Configure PGx pins Output type to push-pull */  
391   GPIOG->OTYPER  = 0x00000000;
392   /* No pull-up, pull-down for PGx pins */ 
393   GPIOG->PUPDR   = 0x00000000;
394   
395   /* Connect PHx pins to FMC Alternate function */
396   GPIOH->AFR[0]  = 0x00C0CC00;
397   GPIOH->AFR[1]  = 0xCCCCCCCC;
398   /* Configure PHx pins in Alternate function mode */ 
399   GPIOH->MODER   = 0xAAAA08A0;
400   /* Configure PHx pins speed to 50 MHz */ 
401   GPIOH->OSPEEDR = 0xAAAA08A0;
402   /* Configure PHx pins Output type to push-pull */  
403   GPIOH->OTYPER  = 0x00000000;
404   /* No pull-up, pull-down for PHx pins */ 
405   GPIOH->PUPDR   = 0x00000000;
406   
407   /* Connect PIx pins to FMC Alternate function */
408   GPIOI->AFR[0]  = 0xCCCCCCCC;
409   GPIOI->AFR[1]  = 0x00000CC0;
410   /* Configure PIx pins in Alternate function mode */ 
411   GPIOI->MODER   = 0x0028AAAA;
412   /* Configure PIx pins speed to 50 MHz */ 
413   GPIOI->OSPEEDR = 0x0028AAAA;
414   /* Configure PIx pins Output type to push-pull */  
415   GPIOI->OTYPER  = 0x00000000;
416   /* No pull-up, pull-down for PIx pins */ 
417   GPIOI->PUPDR   = 0x00000000;
418   
419 /*-- FMC Configuration ------------------------------------------------------*/
420   /* Enable the FMC interface clock */
421   RCC->AHB3ENR |= 0x00000001;
422   
423   /* Configure and enable SDRAM bank1 */
424   FMC_Bank5_6->SDCR[0] = 0x000019E0;
425   FMC_Bank5_6->SDTR[0] = 0x01115351;      
426   
427   /* SDRAM initialization sequence */
428   /* Clock enable command */
429   FMC_Bank5_6->SDCMR = 0x00000011; 
430   tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
431   while((tmpreg != 0) && (timeout-- > 0))
432   {
433     tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
434   }
435
436   /* Delay */
437   for (index = 0; index<1000; index++);
438   
439   /* PALL command */
440   FMC_Bank5_6->SDCMR = 0x00000012;           
441   timeout = 0xFFFF;
442   while((tmpreg != 0) && (timeout-- > 0))
443   {
444     tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
445   }
446   
447   /* Auto refresh command */
448   FMC_Bank5_6->SDCMR = 0x00000073;
449   timeout = 0xFFFF;
450   while((tmpreg != 0) && (timeout-- > 0))
451   {
452     tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
453   }
454  
455   /* MRD register program */
456   FMC_Bank5_6->SDCMR = 0x00046014;
457   timeout = 0xFFFF;
458   while((tmpreg != 0) && (timeout-- > 0))
459   {
460     tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
461   } 
462   
463   /* Set refresh count */
464   tmpreg = FMC_Bank5_6->SDRTR;
465   FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
466   
467   /* Disable write protection */
468   tmpreg = FMC_Bank5_6->SDCR[0]; 
469   FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
470 #endif /* DATA_IN_ExtSDRAM */
471 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
472
473 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
474 #if defined(DATA_IN_ExtSRAM)
475 /*-- GPIOs Configuration -----------------------------------------------------*/
476    /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
477   RCC->AHB1ENR   |= 0x00000078;
478   
479   /* Connect PDx pins to FMC Alternate function */
480   GPIOD->AFR[0]  = 0x00CCC0CC;
481   GPIOD->AFR[1]  = 0xCCCCCCCC;
482   /* Configure PDx pins in Alternate function mode */  
483   GPIOD->MODER   = 0xAAAA0A8A;
484   /* Configure PDx pins speed to 100 MHz */  
485   GPIOD->OSPEEDR = 0xFFFF0FCF;
486   /* Configure PDx pins Output type to push-pull */  
487   GPIOD->OTYPER  = 0x00000000;
488   /* No pull-up, pull-down for PDx pins */ 
489   GPIOD->PUPDR   = 0x00000000;
490
491   /* Connect PEx pins to FMC Alternate function */
492   GPIOE->AFR[0]  = 0xC00CC0CC;
493   GPIOE->AFR[1]  = 0xCCCCCCCC;
494   /* Configure PEx pins in Alternate function mode */ 
495   GPIOE->MODER   = 0xAAAA828A;
496   /* Configure PEx pins speed to 100 MHz */ 
497   GPIOE->OSPEEDR = 0xFFFFC3CF;
498   /* Configure PEx pins Output type to push-pull */  
499   GPIOE->OTYPER  = 0x00000000;
500   /* No pull-up, pull-down for PEx pins */ 
501   GPIOE->PUPDR   = 0x00000000;
502
503   /* Connect PFx pins to FMC Alternate function */
504   GPIOF->AFR[0]  = 0x00CCCCCC;
505   GPIOF->AFR[1]  = 0xCCCC0000;
506   /* Configure PFx pins in Alternate function mode */   
507   GPIOF->MODER   = 0xAA000AAA;
508   /* Configure PFx pins speed to 100 MHz */ 
509   GPIOF->OSPEEDR = 0xFF000FFF;
510   /* Configure PFx pins Output type to push-pull */  
511   GPIOF->OTYPER  = 0x00000000;
512   /* No pull-up, pull-down for PFx pins */ 
513   GPIOF->PUPDR   = 0x00000000;
514
515   /* Connect PGx pins to FMC Alternate function */
516   GPIOG->AFR[0]  = 0x00CCCCCC;
517   GPIOG->AFR[1]  = 0x000000C0;
518   /* Configure PGx pins in Alternate function mode */ 
519   GPIOG->MODER   = 0x00085AAA;
520   /* Configure PGx pins speed to 100 MHz */ 
521   GPIOG->OSPEEDR = 0x000CAFFF;
522   /* Configure PGx pins Output type to push-pull */  
523   GPIOG->OTYPER  = 0x00000000;
524   /* No pull-up, pull-down for PGx pins */ 
525   GPIOG->PUPDR   = 0x00000000;
526   
527 /*-- FMC/FSMC Configuration --------------------------------------------------*/                                                                               
528   /* Enable the FMC/FSMC interface clock */
529   RCC->AHB3ENR         |= 0x00000001;
530   
531 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) 
532   /* Configure and enable Bank1_SRAM2 */
533   FMC_Bank1->BTCR[2]  = 0x00001011;
534   FMC_Bank1->BTCR[3]  = 0x00000201;
535   FMC_Bank1E->BWTR[2] = 0x0fffffff;
536 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ 
537
538 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)
539   /* Configure and enable Bank1_SRAM2 */
540   FSMC_Bank1->BTCR[2]  = 0x00001011;
541   FSMC_Bank1->BTCR[3]  = 0x00000201;
542   FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF;
543 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */
544
545 #endif /* DATA_IN_ExtSRAM */
546 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ 
547 }
548 #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
549
550 /**
551   * @brief  Configures the System clock source, PLL Multiplier and Divider factors,
552   *               AHB/APBx prescalers and Flash settings
553   * @note   This function should be called only once the RCC clock configuration  
554   *         is reset to the default reset state (done in SystemInit() function).             
555   * @param  None
556   * @retval None
557   */
558 void SetSysClock(void)
559 {
560   /* 1- Try to start with HSE and external clock */
561 #if USE_PLL_HSE_EXTC != 0
562   if (SetSysClock_PLL_HSE(1) == 0)
563 #endif
564   {
565     /* 2- If fail try to start with HSE and external xtal */
566     #if USE_PLL_HSE_XTAL != 0
567     if (SetSysClock_PLL_HSE(0) == 0)
568     #endif
569     {
570       /* 3- If fail start with HSI clock */
571       if (SetSysClock_PLL_HSI() == 0)
572       {
573         while(1)
574         {
575           // [TODO] Put something here to tell the user that a problem occured...
576         }
577       }
578     }
579   }
580   
581   /* Output clock on MCO2 pin(PC9) for debugging purpose */
582   //HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO2SOURCE_SYSCLK, RCC_MCODIV_1); // 84 MHz
583 }
584
585 #if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0)
586 /******************************************************************************/
587 /*            PLL (clocked by HSE) used as System clock source                */
588 /******************************************************************************/
589 uint8_t SetSysClock_PLL_HSE(uint8_t bypass)
590 {
591   RCC_ClkInitTypeDef RCC_ClkInitStruct;
592   RCC_OscInitTypeDef RCC_OscInitStruct;
593
594   /* The voltage scaling allows optimizing the power consumption when the device is 
595      clocked below the maximum system frequency, to update the voltage scaling value 
596      regarding system frequency refer to product datasheet. */
597   __PWR_CLK_ENABLE();
598   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
599   
600   /* Enable HSE oscillator and activate PLL with HSE as source */
601   RCC_OscInitStruct.OscillatorType      = RCC_OSCILLATORTYPE_HSE;
602   if (bypass == 0)
603   {
604     RCC_OscInitStruct.HSEState          = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */
605   }
606   else
607   {
608     RCC_OscInitStruct.HSEState          = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */
609   }
610   RCC_OscInitStruct.PLL.PLLState        = RCC_PLL_ON;
611   RCC_OscInitStruct.PLL.PLLSource       = RCC_PLLSOURCE_HSE;
612   RCC_OscInitStruct.PLL.PLLM            = 8;             // VCO input clock = 1 MHz (8 MHz / 8)
613   RCC_OscInitStruct.PLL.PLLN            = 336;           // VCO output clock = 336 MHz (1 MHz * 336)
614   RCC_OscInitStruct.PLL.PLLP            = RCC_PLLP_DIV4; // PLLCLK = 84 MHz (336 MHz / 4)
615   RCC_OscInitStruct.PLL.PLLQ            = 7;             // USB clock = 48 MHz (336 MHz / 7) --> OK for USB
616   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
617   {
618     return 0; // FAIL
619   }
620  
621   /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
622   RCC_ClkInitStruct.ClockType      = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
623   RCC_ClkInitStruct.SYSCLKSource   = RCC_SYSCLKSOURCE_PLLCLK; // 84 MHz
624   RCC_ClkInitStruct.AHBCLKDivider  = RCC_SYSCLK_DIV1;         // 84 MHz
625   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;           // 42 MHz
626   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;           // 84 MHz
627   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
628   {
629     return 0; // FAIL
630   }
631
632   /* Output clock on MCO1 pin(PA8) for debugging purpose */
633   /*
634   if (bypass == 0)
635     HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_2); // 4 MHz
636   else
637     HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1); // 8 MHz
638   */
639   
640   return 1; // OK
641 }
642 #endif
643
644 /******************************************************************************/
645 /*            PLL (clocked by HSI) used as System clock source                */
646 /******************************************************************************/
647 uint8_t SetSysClock_PLL_HSI(void)
648 {
649   RCC_ClkInitTypeDef RCC_ClkInitStruct;
650   RCC_OscInitTypeDef RCC_OscInitStruct;
651
652   /* The voltage scaling allows optimizing the power consumption when the device is 
653      clocked below the maximum system frequency, to update the voltage scaling value 
654      regarding system frequency refer to product datasheet. */
655   __PWR_CLK_ENABLE();
656   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
657  
658   /* Enable HSI oscillator and activate PLL with HSI as source */
659   RCC_OscInitStruct.OscillatorType      = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE;
660   RCC_OscInitStruct.HSIState            = RCC_HSI_ON;
661   RCC_OscInitStruct.HSEState            = RCC_HSE_OFF;
662   RCC_OscInitStruct.HSICalibrationValue = 16;
663   RCC_OscInitStruct.PLL.PLLState        = RCC_PLL_ON;
664   RCC_OscInitStruct.PLL.PLLSource       = RCC_PLLSOURCE_HSI; 
665   RCC_OscInitStruct.PLL.PLLM            = 16;            // VCO input clock = 1 MHz (16 MHz / 16)
666   RCC_OscInitStruct.PLL.PLLN            = 336;           // VCO output clock = 336 MHz (1 MHz * 336)
667   RCC_OscInitStruct.PLL.PLLP            = RCC_PLLP_DIV4; // PLLCLK = 84 MHz (336 MHz / 4)
668   RCC_OscInitStruct.PLL.PLLQ            = 7;             // USB clock = 48 MHz (336 MHz / 7) --> freq is ok but not precise enough
669   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
670   {
671     return 0; // FAIL
672   }
673  
674   /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
675   RCC_ClkInitStruct.ClockType      = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
676   RCC_ClkInitStruct.SYSCLKSource   = RCC_SYSCLKSOURCE_PLLCLK; // 84 MHz
677   RCC_ClkInitStruct.AHBCLKDivider  = RCC_SYSCLK_DIV1;         // 84 MHz
678   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;           // 42 MHz
679   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;           // 84 MHz
680   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
681   {
682     return 0; // FAIL
683   }
684
685   /* Output clock on MCO1 pin(PA8) for debugging purpose */
686   //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_1); // 16 MHz
687
688   return 1; // OK
689 }
690
691 /**
692   * @}
693   */
694
695 /**
696   * @}
697   */
698   
699 /**
700   * @}
701   */    
702 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/