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