]> git.sur5r.net Git - freertos/blob
c4f5fe876170632134eef23e97c4cbfd9cc07460
[freertos] /
1 /******************************************************************************\r
2  * @file     system_XMC4500.c\r
3  * @brief    Device specific initialization for the XMC4500-Series according to CMSIS\r
4  * @version  V2.2\r
5  * @date     20. January 2012\r
6  *\r
7  * @note\r
8  * Copyright (C) 2011 Infineon Technologies AG. All rights reserved.\r
9 \r
10  *\r
11  * @par\r
12  * Infineon Technologies AG (Infineon) is supplying this software for use with Infineon\92s microcontrollers.  \r
13  * This file can be freely distributed within development tools that are supporting such microcontrollers. \r
14 \r
15  *\r
16  * @par\r
17  * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
18  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
20  * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR\r
21  * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\r
22  *\r
23  *\r
24  ******************************************************************************/\r
25 \r
26 #include "System_XMC4500.h"\r
27 #include <XMC4500.h>\r
28 \r
29 /*----------------------------------------------------------------------------\r
30   Define clocks is located in System_XMC4500.h\r
31  *----------------------------------------------------------------------------*/\r
32 \r
33 /*----------------------------------------------------------------------------\r
34   Clock Variable definitions\r
35  *----------------------------------------------------------------------------*/\r
36 /*!< System Clock Frequency (Core Clock)*/\r
37 uint32_t SystemCoreClock = CLOCK_OSC_HP;\r
38 \r
39 /*\r
40 //-------- <<< Use Configuration Wizard in Context Menu >>> ------------------\r
41 */\r
42 \r
43 \r
44 \r
45 /*--------------------- Watchdog Configuration -------------------------------\r
46 //\r
47 // <e> Watchdog Configuration\r
48 //     <o1.0> Disable Watchdog\r
49 //\r
50 // </e>\r
51 */\r
52 #define WDT_SETUP               1\r
53 #define WDTENB_nVal             0x00000001\r
54 \r
55 /*--------------------- CLOCK Configuration -------------------------------\r
56 //\r
57 // <e> Main Clock Configuration\r
58 //     <o1.0..1> CPU clock divider\r
59 //                     <0=> fCPU = fSYS \r
60 //                     <1=> fCPU = fSYS / 2\r
61 //     <o2.0..1>  Peripheral Bus clock divider\r
62 //                     <0=> fPB = fCPU\r
63 //                     <1=> fPB = fCPU / 2\r
64 //     <o3.0..1>  CCU Bus clock divider\r
65 //                     <0=> fCCU = fCPU\r
66 //                     <1=> fCCU = fCPU / 2\r
67 //\r
68 // </e>\r
69 // \r
70 */\r
71 \r
72 #define SCU_CLOCK_SETUP               1\r
73 #define SCU_CPUCLKCR_DIV                0x00000000\r
74 #define SCU_PBCLKCR_DIV             0x00000000\r
75 #define SCU_CCUCLKCR_DIV                0x00000000\r
76 \r
77 \r
78 \r
79 /*--------------------- USB CLOCK Configuration ---------------------------\r
80 //\r
81 // <e> USB Clock Configuration\r
82 //\r
83 // </e>\r
84 // \r
85 */\r
86 \r
87 #define SCU_USB_CLOCK_SETUP              0\r
88 \r
89 \r
90 /*--------------------- CLOCKOUT Configuration -------------------------------\r
91 //\r
92 // <e> Clock OUT Configuration\r
93 //     <o1.0..1>   Clockout Source Selection\r
94 //                     <0=> System Clock\r
95 //                     <2=> USB Clock\r
96 //                     <3=> Divided value of PLL Clock\r
97 //     <o2.0..1>   Clockout Pin Selection\r
98 //                     <0=> P1.15\r
99 //                     <1=> P0.8\r
100 //                     \r
101 //\r
102 // </e>\r
103 // \r
104 */\r
105 \r
106 #define SCU_CLOCKOUT_SETUP              0  // recommended to keep disabled\r
107 #define SCU_CLOCKOUT_SOURCE             0x00000000\r
108 #define SCU_CLOCKOUT_PIN                0x00000000\r
109 \r
110 /*----------------------------------------------------------------------------\r
111   static functions declarations\r
112  *----------------------------------------------------------------------------*/\r
113 #if (SCU_CLOCK_SETUP == 1)\r
114 static int SystemClockSetup(void);\r
115 #endif\r
116 \r
117 #if (SCU_USB_CLOCK_SETUP == 1)\r
118 static void USBClockSetup(void);\r
119 #endif\r
120 \r
121 /**\r
122   * @brief  Setup the microcontroller system.\r
123   *         Initialize the PLL and update the \r
124   *         SystemCoreClock variable.\r
125   * @param  None\r
126   * @retval None\r
127   */\r
128 void SystemInit(void)\r
129 {\r
130 /* Setup the WDT */\r
131 #if (WDT_SETUP == 1)\r
132 WDT->CTR &= ~WDTENB_nVal; \r
133 #endif\r
134 \r
135 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)\r
136 SCB->CPACR |= ((3UL << 10*2) |                 /* set CP10 Full Access */\r
137                (3UL << 11*2)  );               /* set CP11 Full Access */\r
138 #endif\r
139 \r
140 /* Disable branch prediction - PCON.PBS = 1 */\r
141 PREF->PCON |= (PREF_PCON_PBS_Msk);\r
142 \r
143 /* Enable unaligned memory access - SCB_CCR.UNALIGN_TRP = 0 */\r
144 SCB->CCR &= ~(SCB_CCR_UNALIGN_TRP_Msk);\r
145 \r
146 /* Setup the clockout */\r
147 /* README README README README README README README README README README */\r
148 /*\r
149  * Please use the CLOCKOUT feature with diligence. Use this only if you know\r
150  * what you are doing.\r
151  *\r
152  * You must be aware that the settings below can potentially be in conflict\r
153  * with DAVE code generation engine preferences.\r
154  *\r
155  * Even worse, the setting below configures the ports as output ports while in\r
156  * reality, the board on which this chip is mounted may have a source driving\r
157  * the ports.\r
158  *\r
159  * So use this feature only when you are absolutely sure that the port must \r
160  * indeed be configured as an output AND you are NOT linking this startup code\r
161  * with code that was generated by DAVE code engine.\r
162  */\r
163 #if (SCU_CLOCKOUT_SETUP == 1)\r
164 SCU_CLK->EXTCLKCR       |= SCU_CLOCKOUT_SOURCE;\r
165 \r
166 if (SCU_CLOCKOUT_PIN) {\r
167               PORT0->IOCR8 = 0x00000088;  /*P0.8 --> ALT1 select +  HWSEL */\r
168               PORT0->HWSEL &= (~PORT0_HWSEL_HW8_Msk);\r
169               }\r
170 else PORT1->IOCR12 = 0x88000000; /*P1.15--> ALT1 select */\r
171 #endif\r
172 \r
173 /* Setup the System clock */ \r
174 #if (SCU_CLOCK_SETUP == 1)\r
175 SystemClockSetup();\r
176 #endif\r
177 \r
178 /* Setup the USB PL */ \r
179 #if (SCU_USB_CLOCK_SETUP == 1)\r
180 USBClockSetup();\r
181 #endif\r
182 \r
183 }\r
184 \r
185 \r
186 /**\r
187   * @brief  Update SystemCoreClock according to Clock Register Values\r
188   * @note   -  \r
189   * @param  None\r
190   * @retval None\r
191   */\r
192 void SystemCoreClockUpdate(void)\r
193 {\r
194 \r
195 /*----------------------------------------------------------------------------\r
196   Clock Variable definitions\r
197  *----------------------------------------------------------------------------*/\r
198 SystemCoreClock = SYSTEM_FREQUENCY;/*!< System Clock Frequency (Core Clock)*/\r
199 \r
200 }\r
201 \r
202 \r
203 /**\r
204   * @brief  -\r
205   * @note   -  \r
206   * @param  None\r
207   * @retval None\r
208   */\r
209 #if (SCU_CLOCK_SETUP == 1)\r
210 static int SystemClockSetup(void)\r
211 {\r
212 /* enable PLL first */\r
213   SCU_PLL->PLLCON0 &= ~(SCU_PLL_PLLCON0_VCOPWD_Msk | \r
214                                                                                                         SCU_PLL_PLLCON0_PLLPWD_Msk);\r
215 \r
216 /* Enable OSC_HP */\r
217   if (SCU_PLL_CLOCK_INPUT == SCU_CLOCK_CRYSTAL)\r
218   {\r
219    /* Enable the OSC_HP*/\r
220    SCU_OSC->OSCHPCTRL = (OSC_HP_MODE<<4);        \r
221    /* Setup OSC WDG devider */\r
222    SCU_OSC->OSCHPCTRL |= (OSCHPWDGDIV<<16);         \r
223    /* Select external OSC as PLL input */\r
224    SCU_PLL->PLLCON2 &= ~SCU_PLL_PLLCON2_PINSEL_Msk;\r
225    /* Restart OSC Watchdog */\r
226    SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCRES_Msk;  \r
227 \r
228    do \r
229    {\r
230         ;  /* here a timeout need to be added */\r
231    }while(!( (SCU_PLL->PLLSTAT) & \r
232                                            (SCU_PLL_PLLSTAT_PLLHV_Msk | SCU_PLL_PLLSTAT_PLLLV_Msk |\r
233                                             SCU_PLL_PLLSTAT_PLLSP_Msk)\r
234                                          )\r
235          ); \r
236 \r
237   }\r
238 \r
239 /* Setup Main PLL */\r
240    /* Select FOFI as system clock */\r
241    if(SCU_CLK->SYSCLKCR != 0X000000)\r
242           SCU_CLK->SYSCLKCR = 0x00000000; /*Select FOFI*/\r
243 \r
244          /* Go to bypass the Main PLL */\r
245    SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_VCOBYP_Msk;\r
246 \r
247          /* disconnect OSC_HP to PLL */\r
248    SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_FINDIS_Msk;\r
249 \r
250          /* Setup devider settings for main PLL */\r
251    SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) | \r
252                                      (PLL_K2DIV_STEP_1<<16) | (PLL_PDIV<<24));\r
253 \r
254          /* we may have to set OSCDISCDIS */\r
255    SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_OSCDISCDIS_Msk;\r
256 \r
257          /* connect OSC_HP to PLL */\r
258    SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_FINDIS_Msk;\r
259 \r
260          /* restart PLL Lock detection */\r
261    SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_RESLD_Msk;\r
262 \r
263          /* wait for PLL Lock */\r
264    while (!(SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOLOCK_Msk));\r
265 \r
266         /* Go back to the Main PLL */\r
267    SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_VCOBYP_Msk;\r
268 \r
269    /*********************************************************\r
270    here we need to setup the system clock divider\r
271    *********************************************************/\r
272 \r
273         SCU_CLK->CPUCLKCR = SCU_CPUCLKCR_DIV;\r
274         SCU_CLK->PBCLKCR = SCU_PBCLKCR_DIV;     \r
275         SCU_CLK->CCUCLKCR = SCU_CCUCLKCR_DIV;\r
276 \r
277    /* Switch system clock to PLL */\r
278    SCU_CLK->SYSCLKCR |=  0x00010000; \r
279                                                                                                                           \r
280    /*********************************************************\r
281    here the ramp up of the system clock starts\r
282    *********************************************************/\r
283     /* Delay for next K2 step ~50µs */\r
284    /********************************/\r
285    /* Set reload register */\r
286    SysTick->LOAD  = ((1250+100) & SysTick_LOAD_RELOAD_Msk) - 1;\r
287 \r
288    /* Load the SysTick Counter Value */\r
289    SysTick->VAL   = 0;                                         \r
290 \r
291    /* Enable SysTick IRQ and SysTick Timer */\r
292    SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |\r
293                    SysTick_CTRL_ENABLE_Msk;                    \r
294    \r
295          /* wait for ~50µs  */\r
296    while (SysTick->VAL >= 100);                                                            \r
297 \r
298    /* Stop SysTick Timer */\r
299    SysTick->CTRL  &= ~SysTick_CTRL_ENABLE_Msk;                 \r
300    /********************************/\r
301 \r
302    /* Setup devider settings for main PLL */\r
303    SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) | \r
304                                      (PLL_K2DIV_STEP_2<<16) | (PLL_PDIV<<24));\r
305 \r
306    /* Delay for next K2 step ~50µs */\r
307    /********************************/\r
308    SysTick->LOAD  = ((3000+100) & SysTick_LOAD_RELOAD_Msk) - 1;\r
309 \r
310    /* Load the SysTick Counter Value */\r
311    SysTick->VAL   = 0;\r
312 \r
313    /* Enable SysTick IRQ and SysTick Timer */\r
314    SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;\r
315                                                                    \r
316    /* Wait for ~50µs  */\r
317    while (SysTick->VAL >= 100);                                                            \r
318 \r
319    /* Stop SysTick Timer */\r
320    SysTick->CTRL  &= ~SysTick_CTRL_ENABLE_Msk;                 \r
321    /********************************/\r
322 \r
323    /* Setup devider settings for main PLL */\r
324    SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) | \r
325                                                                                             (PLL_K2DIV_STEP_3<<16) | (PLL_PDIV<<24));\r
326 \r
327    /* Delay for next K2 step ~50µs */\r
328    /********************************/\r
329    SysTick->LOAD  = ((4800+100) & SysTick_LOAD_RELOAD_Msk) - 1;\r
330 \r
331    /* Load the SysTick Counter Value */\r
332    SysTick->VAL   = 0;                                         \r
333 \r
334    /* Enable SysTick IRQ and SysTick Timer */\r
335    SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;\r
336                                        \r
337    /* Wait for ~50µs  */\r
338    while (SysTick->VAL >= 100);                                                            \r
339 \r
340    /* Stop SysTick Timer */\r
341    SysTick->CTRL  &= ~SysTick_CTRL_ENABLE_Msk;                 \r
342    /********************************/\r
343 \r
344    /* Setup devider settings for main PLL */\r
345    SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) | (PLL_K2DIV<<16) | \r
346                                                                (PLL_PDIV<<24));\r
347 \r
348          /* clear request for System OCS Watchdog Trap and System VCO Lock Trap  */\r
349    SCU_TRAP->TRAPCLR = SCU_TRAP_TRAPCLR_SOSCWDGT_Msk | \r
350                                                                             SCU_TRAP_TRAPCLR_SVCOLCKT_Msk;  \r
351 \r
352    return(1);\r
353 \r
354 }\r
355 #endif\r
356 \r
357 /**\r
358   * @brief  -\r
359   * @note   -  \r
360   * @param  None\r
361   * @retval None\r
362   */\r
363 #if(SCU_USB_CLOCK_SETUP == 1)\r
364 static void USBClockSetup(void)\r
365 {\r
366 /* enable PLL first */\r
367   SCU_PLL->USBPLLCON &= ~(SCU_PLL_USBPLLCON_VCOPWD_Msk | \r
368                                                                                                        SCU_PLL_USBPLLCON_PLLPWD_Msk);\r
369 \r
370 /* check and if not already running enable OSC_HP */\r
371   if(!((SCU_PLL->PLLSTAT) & \r
372                          (SCU_PLL_PLLSTAT_PLLHV_Msk | \r
373         SCU_PLL_PLLSTAT_PLLLV_Msk |SCU_PLL_PLLSTAT_PLLSP_Msk)))\r
374   {\r
375           if (SCU_PLL_CLOCK_INPUT == SCU_CLOCK_CRYSTAL)\r
376           {\r
377         \r
378            SCU_OSC->OSCHPCTRL = (OSC_HP_MODE<<4);        /*enable the OSC_HP*/\r
379            /* setup OSC WDG devider */\r
380            SCU_OSC->OSCHPCTRL |= (OSCHPWDGDIV<<16);         \r
381            /* select external OSC as PLL input */\r
382            SCU_PLL->PLLCON2 &= ~SCU_PLL_PLLCON2_PINSEL_Msk;\r
383            /* restart OSC Watchdog */\r
384            SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCRES_Msk;  \r
385         \r
386            do \r
387            {\r
388                 ;  /* here a timeout need to be added */\r
389            }while(!((SCU_PLL->PLLSTAT) & (SCU_PLL_PLLSTAT_PLLHV_Msk | \r
390                SCU_PLL_PLLSTAT_PLLLV_Msk |SCU_PLL_PLLSTAT_PLLSP_Msk))); \r
391         \r
392           }\r
393   }\r
394 \r
395 \r
396 /* Setup USB PLL */\r
397    /* Go to bypass the Main PLL */\r
398    SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_VCOBYP_Msk;\r
399    /* disconnect OSC_FI to PLL */\r
400    SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_FINDIS_Msk;\r
401    /* Setup devider settings for main PLL */\r
402    SCU_PLL->USBPLLCON = ((USBPLL_NDIV<<8) | (USBPLL_PDIV<<24));\r
403    /* we may have to set OSCDISCDIS */\r
404    SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_OSCDISCDIS_Msk;\r
405    /* connect OSC_FI to PLL */\r
406    SCU_PLL->USBPLLCON &= ~SCU_PLL_USBPLLCON_FINDIS_Msk;\r
407    /* restart PLL Lock detection */\r
408    SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_RESLD_Msk;\r
409    /* wait for PLL Lock */\r
410    while (!(SCU_PLL->USBPLLSTAT & SCU_PLL_USBPLLSTAT_VCOLOCK_Msk));\r
411  }\r
412 #endif