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