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