]> rtime.felk.cvut.cz Git - arc.git/blob - arch/ppc/mpc55xx/drivers/Mcu.c
ab43113e1c1d87962e9c87e7b8997d556f03e6da
[arc.git] / arch / ppc / mpc55xx / drivers / Mcu.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 \r
17 /* ----------------------------[includes]------------------------------------*/\r
18 #include <assert.h>\r
19 #include <string.h>\r
20 #include "Std_Types.h"\r
21 #include "Mcu.h"\r
22 #include "Det.h"\r
23 #if defined(USE_DEM)\r
24 #include "Dem.h"\r
25 #endif\r
26 #include "mpc55xx.h"\r
27 #include "Cpu.h"\r
28 #include "Ramlog.h"\r
29 #include "Os.h"\r
30 #include "isr.h"\r
31 #include "io.h"\r
32 \r
33 //#define USE_LDEBUG_PRINTF 1\r
34 #include "debug.h"\r
35 \r
36 /* ----------------------------[private define]------------------------------*/\r
37 \r
38 #define SYSCLOCK_SELECT_PLL     0x2\r
39 \r
40 \r
41 #if defined(CFG_MPC5516) || defined(CFG_MPC5668)\r
42 #define CRP_BASE                        (0xFFFEC000ul)\r
43 #else\r
44 #error Please define CRP_BASE\r
45 #endif\r
46 \r
47 #define CRP_CLKSRC                      (CRP_BASE+0x0)\r
48 #define CRP_RTCSC                       (CRP_BASE+0x10)\r
49 #define CRP_RTCCNT                      (CRP_BASE+0x14)\r
50 /* 40--4F differs ALOT */\r
51 #define CRP_Z1VEC                       (CRP_BASE+0x50)\r
52 #define CRP_Z6VEC                       (CRP_BASE+0x50)\r
53 #define CRP_Z0VEC                       (CRP_BASE+0x54)\r
54 #define CRP_RECPTR                      (CRP_BASE+0x58)\r
55 #define CRP_PSCR                        (CRP_BASE+0x60)\r
56 \r
57 #define xVEC_xVEC(_x)\r
58 #define PSCR_SLEEP                      0x00008000ul\r
59 #define PSCR_SLP12EN            0x00000800ul\r
60 #define PCSR_RAMSEL(_x)         ((_x)<<8)\r
61 #define xVEC_VLE                        0x00000001ul\r
62 #define xVEC_xRST                       0x00000002ul\r
63 \r
64 #define RECPTR_FASTREC          0x00000002ul\r
65 \r
66 \r
67 #if defined(CFG_VLE)\r
68 #define VLE_VAL         xVEC_VLE\r
69 #else\r
70 #define VLE_VAL         0\r
71 #endif\r
72 \r
73 #if defined(CFG_MPC5516 )\r
74 #define RAMSEL_VAL              0x7\r
75 #elif defined(CFG_MPC5668)\r
76 #define RAMSEL_VAL              0x3\r
77 #else\r
78 #error  Please define RAMSEL_VAL\r
79 #endif\r
80 \r
81 \r
82 /* ----------------------------[private macro]-------------------------------*/\r
83 \r
84 \r
85 #if defined(CFG_MPC5567)\r
86 #define CALC_SYSTEM_CLOCK(_extal,_emfd,_eprediv,_erfd)  \\r
87             ( (_extal) * ((_emfd)+4) / (((_eprediv)+1)*(1<<(_erfd))) )\r
88 #elif defined(CFG_MPC560X)\r
89 #define CALC_SYSTEM_CLOCK(_extal,_emfd,_eprediv,_erfd)  \\r
90                 ( (_extal)*(_emfd) / ((_eprediv+1)*(2<<(_erfd))) )\r
91 #else\r
92 #define CALC_SYSTEM_CLOCK(_extal,_emfd,_eprediv,_erfd)  \\r
93             ( (_extal) * ((_emfd)+16) / (((_eprediv)+1)*((_erfd)+1)) )\r
94 #endif\r
95 \r
96 /* ----------------------------[private typedef]-----------------------------*/\r
97 \r
98 \r
99 typedef void (*vfunc_t)();\r
100 \r
101 \r
102 /* ----------------------------[private function prototypes]-----------------*/\r
103 /* ----------------------------[private variables]---------------------------*/\r
104 \r
105 #if defined(CFG_MPC5516)\r
106 static uint32 Mcu_SavedHaltFlags;\r
107 #else\r
108 static uint32 Mcu_SavedHaltFlags[2];\r
109 #endif\r
110 \r
111 \r
112 \r
113 /* ----------------------------[private functions]---------------------------*/\r
114 /* ----------------------------[public functions]----------------------------*/\r
115 \r
116 /* Function declarations. */\r
117 static void Mcu_ConfigureFlash(void);\r
118 \r
119 typedef struct{\r
120         uint32 lossOfLockCnt;\r
121         uint32 lossOfClockCnt;\r
122 } Mcu_Stats;\r
123 \r
124 /**\r
125  * Type that holds all global data for Mcu\r
126  */\r
127 typedef struct\r
128 {\r
129     // Set if Mcu_Init() have been called\r
130     boolean initRun;\r
131     // Our config\r
132     const Mcu_ConfigType *config;\r
133     Mcu_ClockType clockSetting;\r
134     Mcu_Stats stats;\r
135 } Mcu_GlobalType;\r
136 \r
137 /* Development error macros. */\r
138 #if ( MCU_DEV_ERROR_DETECT == STD_ON )\r
139 #define VALIDATE(_exp,_api,_err ) \\r
140         if( !(_exp) ) { \\r
141           Det_ReportError(MODULE_ID_MCU,0,_api,_err); \\r
142           return; \\r
143         }\r
144 \r
145 #define VALIDATE_W_RV(_exp,_api,_err,_rv ) \\r
146         if( !(_exp) ) { \\r
147           Det_ReportError(MODULE_ID_MCU,0,_api,_err); \\r
148           return (_rv); \\r
149         }\r
150 #else\r
151 #define VALIDATE(_exp,_api,_err )\r
152 #define VALIDATE_W_RV(_exp,_api,_err,_rv )\r
153 #endif\r
154 \r
155 // Global config\r
156 Mcu_GlobalType Mcu_Global =\r
157 {\r
158         .initRun = 0,\r
159         .config = &McuConfigData[0],\r
160 };\r
161 \r
162 //-------------------------------------------------------------------\r
163 \r
164 void Mcu_LossOfLock( void  ){\r
165 #if defined(USE_DEM)\r
166         Dem_ReportErrorStatus(MCU_E_CLOCK_FAILURE, DEM_EVENT_STATUS_FAILED);\r
167 #endif\r
168 \r
169   /*\r
170    * NOTE!!!\r
171    * This interrupt may be triggered more than expected.\r
172    * If you are going to use this interrupt, see [Freescale Device Errata MPC5510ACE, Rev. 10 APR 2009, errata ID: 6764].\r
173    *\r
174    */\r
175 #if defined(CFG_MPC560X)\r
176         /*not support*/\r
177 #else\r
178         Mcu_Global.stats.lossOfLockCnt++;\r
179         // Clear interrupt\r
180         FMPLL.SYNSR.B.LOLF = 1;\r
181 #endif\r
182 }\r
183 \r
184 //-------------------------------------------------------------------\r
185 \r
186 void Mcu_LossOfClock( void  ){\r
187         /* Should report MCU_E_CLOCK_FAILURE with DEM here */\r
188 #if defined(CFG_MPC560X)\r
189         /*not support*/\r
190 #else\r
191         Mcu_Global.stats.lossOfClockCnt++;\r
192         // Clear interrupt\r
193         FMPLL.SYNSR.B.LOCF = 1;\r
194 #endif\r
195 }\r
196 \r
197 #define SPR_PIR 286\r
198 #define SPR_PVR 287\r
199 \r
200 #define CORE_PVR_E200Z1         0x81440000UL\r
201 #define CORE_PVR_E200Z0         0x81710000UL\r
202 #define CORE_PVR_E200Z3         0x81120000UL\r
203 #define CORE_PVR_E200Z6         0x81170000UL\r
204 #define CORE_PVR_E200Z65        0x81150000UL    /* Is actually a 5668 */\r
205 #define CORE_PVR_E200Z0H        0x817F0000UL\r
206 \r
207 typedef struct{\r
208         char *name;\r
209         uint32 pvr;\r
210 } core_info_t;\r
211 \r
212 typedef struct{\r
213         char *name;\r
214         uint32 pvr;\r
215 } cpu_info_t;\r
216 \r
217 const cpu_info_t cpu_info_list[] = {\r
218 #if defined(CFG_MPC5516)\r
219     {\r
220         .name = "MPC5516",\r
221         .pvr = CORE_PVR_E200Z1,\r
222     },\r
223     {\r
224         .name = "MPC5516",\r
225         .pvr = CORE_PVR_E200Z0,\r
226     },\r
227 #elif defined(CFG_MPC5567)\r
228     {\r
229         .name = "MPC5567",\r
230         .pvr = CORE_PVR_E200Z6,\r
231     }\r
232 #elif defined(CFG_MPC5633)\r
233     {\r
234         .name = "MPC563X",\r
235         .pvr = CORE_PVR_E200Z3,\r
236     },\r
237 #elif defined(CFG_MPC5604B)\r
238     {\r
239         .name = "MPC5604B",\r
240         .pvr = CORE_PVR_E200Z0H,\r
241     },\r
242 #elif defined(CFG_MPC5606B)\r
243     {\r
244         .name = "MPC5606B",\r
245         .pvr = CORE_PVR_E200Z0H,\r
246     },\r
247 #elif defined(CFG_MPC5606S)\r
248     {\r
249         .name = "MPC5606S",\r
250         .pvr = CORE_PVR_E200Z0H,\r
251     },\r
252 #elif defined(CFG_MPC5668)\r
253         {\r
254                 .name = "MPC5668",\r
255                 .pvr = CORE_PVR_E200Z65,\r
256         },\r
257         {\r
258                 .name = "MPC5668",\r
259                 .pvr = CORE_PVR_E200Z0,\r
260         },\r
261 #endif\r
262 };\r
263 \r
264 const core_info_t core_info_list[] = {\r
265 #if defined(CFG_MPC5516)\r
266         {\r
267                 .name = "CORE_E200Z1",\r
268                 .pvr = CORE_PVR_E200Z1,\r
269     },\r
270     {\r
271         .name = "CORE_E200Z1",\r
272         .pvr = CORE_PVR_E200Z1,\r
273     },\r
274 #elif defined(CFG_MPC5567)\r
275     {\r
276         .name = "CORE_E200Z6",\r
277         .pvr = CORE_PVR_E200Z6,\r
278     }\r
279 #elif defined(CFG_MPC5633)\r
280     {\r
281                 .name = "CORE_E200Z3",\r
282                 .pvr = CORE_PVR_E200Z3,\r
283     },\r
284 #elif defined(CFG_MPC5604B)\r
285     {\r
286         .name = "MPC5604B",\r
287         .pvr = CORE_PVR_E200Z0H,\r
288     },\r
289 #elif defined(CFG_MPC5606B)\r
290     {\r
291         .name = "MPC5606B",\r
292         .pvr = CORE_PVR_E200Z0H,\r
293     },\r
294 #elif defined(CFG_MPC5606S)\r
295     {\r
296         .name = "MPC5606S",\r
297         .pvr = CORE_PVR_E200Z0H,\r
298     },\r
299 #elif defined(CFG_MPC5668)\r
300     {\r
301         .name = "CORE_E200Z65",\r
302         .pvr = CORE_PVR_E200Z65,\r
303     },\r
304     {\r
305         .name = "CORE_E200Z0",\r
306         .pvr = CORE_PVR_E200Z1,\r
307     },\r
308 #endif\r
309 };\r
310 \r
311 // TODO: move\r
312 #if !defined(ARRAY_SIZE)\r
313 #define ARRAY_SIZE(_x)  (sizeof(_x)/sizeof((_x)[0]))\r
314 #endif\r
315 \r
316 static const cpu_info_t *Mcu_IdentifyCpu(uint32 pvr)\r
317 {\r
318     int i;\r
319 \r
320     for (i = 0; i < ARRAY_SIZE(cpu_info_list); i++) {\r
321         if (cpu_info_list[i].pvr == pvr) {\r
322                 return &cpu_info_list[i];\r
323         }\r
324     }\r
325 \r
326     return NULL;\r
327 }\r
328 \r
329 static const core_info_t *Mcu_IdentifyCore(uint32 pvr)\r
330 {\r
331         int i;\r
332 \r
333         for (i = 0; i < ARRAY_SIZE(core_info_list); i++) {\r
334                 if (core_info_list[i].pvr == pvr) {\r
335                         return &core_info_list[i];\r
336                 }\r
337     }\r
338 \r
339   return NULL;\r
340 }\r
341 \r
342 static uint32 Mcu_CheckCpu( void ) {\r
343         uint32 pvr;\r
344         // uint32 pir;\r
345         const cpu_info_t *cpuType;\r
346         const core_info_t *coreType;\r
347 \r
348     // We have to registers to read here, PIR and PVR\r
349     // pir = get_spr(SPR_PIR);\r
350     pvr = get_spr(SPR_PVR);\r
351 \r
352     cpuType = Mcu_IdentifyCpu(pvr);\r
353     coreType = Mcu_IdentifyCore(pvr);\r
354 \r
355     if( (cpuType == NULL) || (coreType == NULL) ) {\r
356         // Just hang\r
357         while(1) ;\r
358     }\r
359 \r
360     //DEBUG(DEBUG_HIGH,"/drivers/mcu: Cpu:  %s( 0x%08x )\n",cpuType->name,pvr);\r
361     //DEBUG(DEBUG_HIGH,"/drivers/mcu: Core: %s( 0x%08x )\n",coreType->name,pvr);\r
362 \r
363     return 0;\r
364 }\r
365 \r
366 //-------------------------------------------------------------------\r
367 \r
368 void Mcu_Init(const Mcu_ConfigType *configPtr)\r
369 {\r
370         VALIDATE( ( NULL != configPtr ), MCU_INIT_SERVICE_ID, MCU_E_PARAM_CONFIG );\r
371 \r
372 #if defined(CFG_MPC560X)\r
373         /* Disable watchdog. Watchdog is enabled default after reset.*/\r
374         SWT.SR.R = 0x0000c520;     /* Write keys to clear soft lock bit */\r
375         SWT.SR.R = 0x0000d928;\r
376         SWT.CR.R = 0x8000010A;     /* Disable watchdog */\r
377 #if defined(USE_WDG)\r
378         SWT.TO.R = 0xfa00;              /* set the timout to 500ms */\r
379         SWT.CR.R = 0x8000011B;      /* enable watchdog */\r
380 #endif\r
381 #endif\r
382 \r
383     if( !SIMULATOR() ) {\r
384         Mcu_CheckCpu();\r
385     }\r
386 \r
387     memset(&Mcu_Global.stats,0,sizeof(Mcu_Global.stats));\r
388 \r
389     // Setup memories\r
390     Mcu_ConfigureFlash();\r
391 \r
392     Mcu_Global.config = configPtr;\r
393 \r
394 #if defined(CFG_MPC560X)\r
395     /* Enable DRUN, RUN0, SAFE, RESET modes */\r
396     ME.MER.R = 0x0000001D;\r
397 #endif\r
398 \r
399     Mcu_Global.initRun = 1;\r
400 \r
401     if( Mcu_Global.config->McuClockSrcFailureNotification == TRUE  ) {\r
402 #if defined(CFG_MPC560X)\r
403         /*not support*/\r
404 #else\r
405         ISR_INSTALL_ISR1("LossOfLock", Mcu_LossOfLock, PLL_SYNSR_LOLF, 10 , 0 );\r
406 #if defined(CFG_MPC5516)  || defined(CFG_MPC5668)\r
407         FMPLL.ESYNCR2.B.LOLIRQ = 1;\r
408 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
409         FMPLL.SYNCR.B.LOLIRQ = 1;\r
410 #endif\r
411         ISR_INSTALL_ISR1("LossOfClock", Mcu_LossOfClock, PLL_SYNSR_LOLF, 10 , 0 );\r
412 #if defined(CFG_MPC5516) || defined(CFG_MPC5668)\r
413         FMPLL.ESYNCR2.B.LOCIRQ = 1;\r
414 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
415         FMPLL.SYNCR.B.LOCIRQ = 1;\r
416 #endif\r
417 #endif\r
418     }\r
419 }\r
420 \r
421 //-------------------------------------------------------------------\r
422 \r
423 void Mcu_DeInit()\r
424 {\r
425         Mcu_Global.initRun = FALSE; // Very simple Deinit. Should we do more?\r
426 }\r
427 \r
428 //-------------------------------------------------------------------\r
429 \r
430 Std_ReturnType Mcu_InitRamSection(const Mcu_RamSectionType RamSection)\r
431 {\r
432         VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_INITRAMSECTION_SERVICE_ID, MCU_E_UNINIT, E_NOT_OK );\r
433         VALIDATE_W_RV( ( RamSection <= Mcu_Global.config->McuRamSectors ), MCU_INITRAMSECTION_SERVICE_ID, MCU_E_PARAM_RAMSECTION, E_NOT_OK );\r
434 \r
435     /* NOT SUPPORTED, reason: no support for external RAM */\r
436 \r
437     return E_OK;\r
438 }\r
439 \r
440 //-------------------------------------------------------------------\r
441 \r
442 Std_ReturnType Mcu_InitClock(const Mcu_ClockType ClockSetting)\r
443 {\r
444     Mcu_ClockSettingConfigType *clockSettingsPtr;\r
445     VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_INITCLOCK_SERVICE_ID, MCU_E_UNINIT, E_NOT_OK );\r
446     VALIDATE_W_RV( ( ClockSetting < Mcu_Global.config->McuClockSettings ), MCU_INITCLOCK_SERVICE_ID, MCU_E_PARAM_CLOCK, E_NOT_OK );\r
447 \r
448     Mcu_Global.clockSetting = ClockSetting;\r
449     clockSettingsPtr = &Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting];\r
450 \r
451     // TODO: find out if the 5554 really works like the 5516 here\r
452     // All three (16, 54, 67) used to run the same code here though, so i'm sticking it with 5516\r
453 #if defined(CFG_SIMULATOR)\r
454     return E_OK;\r
455 #elif defined(CFG_MPC5516) || defined(CFG_MPC5554) || defined(CFG_MPC5668)\r
456     /* 5516clock info:\r
457      * Fsys - System frequency ( CPU + all periperals? )\r
458      *\r
459      *  Fsys = EXTAL_FREQ *(  (emfd+16) / ( (eprediv+1) * ( erfd+1 )) ) )\r
460      */\r
461     // Check ranges...\r
462     assert((clockSettingsPtr->Pll2>=32) && (clockSettingsPtr->Pll2<=132));\r
463     assert( (clockSettingsPtr->Pll1 != 6) &&\r
464             (clockSettingsPtr->Pll1 != 8) &&\r
465             (clockSettingsPtr->Pll1 < 10) );\r
466     assert( clockSettingsPtr->Pll3 & 1); // Must be odd\r
467 #elif defined(CFG_MPC5567)\r
468     /* 5567 clock info:\r
469      *  Fsys = EXTAL_FREQ *(  (emfd+4) / ( (eprediv+1) * ( 2^erfd )) ) )\r
470      */\r
471     // Check ranges...\r
472     assert(clockSettingsPtr->Pll2 < 16);\r
473     assert(clockSettingsPtr->Pll1 <= 4);\r
474     assert(clockSettingsPtr->Pll3 < 8);\r
475 #endif\r
476 \r
477 #if defined(USE_LDEBUG_PRINTF)\r
478     {\r
479         uint32  extal = Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting].McuClockReferencePointFrequency;\r
480         uint32  f_sys;\r
481 \r
482         f_sys = CALC_SYSTEM_CLOCK( extal,\r
483                 clockSettingsPtr->Pll2,\r
484                 clockSettingsPtr->Pll1,\r
485                 clockSettingsPtr->Pll3 );\r
486 \r
487         //DEBUG(DEBUG_HIGH,"/drivers/mcu: F_sys will be:%08d Hz\n",f_sys);\r
488     }\r
489 #endif\r
490 \r
491 #if defined(CFG_MPC5516) || defined(CFG_MPC5668)\r
492 \r
493     // set post divider to next valid value to ensure that an overshoot during lock phase\r
494     // won't result in a too high freq\r
495     FMPLL.ESYNCR2.B.ERFD = (clockSettingsPtr->Pll3 + 1) | 1;\r
496 \r
497     // External crystal PLL mode.\r
498     FMPLL.ESYNCR1.B.CLKCFG = 7; //TODO: Hur ställa detta för 5567?\r
499 \r
500     // Write pll parameters.\r
501     FMPLL.ESYNCR1.B.EPREDIV = clockSettingsPtr->Pll1;\r
502     FMPLL.ESYNCR1.B.EMFD    = clockSettingsPtr->Pll2;\r
503 \r
504     while(FMPLL.SYNSR.B.LOCK != 1) {};\r
505 \r
506     FMPLL.ESYNCR2.B.ERFD    = clockSettingsPtr->Pll3;\r
507     // Connect SYSCLK to FMPLL\r
508     SIU.SYSCLK.B.SYSCLKSEL = SYSCLOCK_SELECT_PLL;\r
509 #elif defined(CFG_MPC5604B) || defined(CFG_MPC5606B)\r
510     // Write pll parameters.\r
511     CGM.FMPLL_CR.B.IDF = clockSettingsPtr->Pll1;\r
512     CGM.FMPLL_CR.B.NDIV = clockSettingsPtr->Pll2;\r
513     CGM.FMPLL_CR.B.ODF = clockSettingsPtr->Pll3;\r
514 \r
515     /* RUN0 cfg: 16MHzIRCON,OSC0ON,PLL0ON,syclk=PLL0 */\r
516     ME.RUN[0].R = 0x001F0074;\r
517     /* Peri. Cfg. 1 settings: only run in RUN0 mode */\r
518     ME.RUNPC[1].R = 0x00000010;\r
519     /* MPC56xxB/S: select ME.RUNPC[1] */\r
520     ME.PCTL[68].R = 0x01; //SIUL control\r
521     ME.PCTL[91].R = 0x01; //RTC/API control\r
522     ME.PCTL[92].R = 0x01; //PIT_RTI control\r
523     ME.PCTL[72].R = 0x01; //eMIOS0 control\r
524     ME.PCTL[73].R = 0x01; //eMIOS1 control\r
525     ME.PCTL[16].R = 0x01; //FlexCAN0 control\r
526     ME.PCTL[17].R = 0x01; //FlexCAN1 control\r
527     ME.PCTL[4].R = 0x01;  /* MPC56xxB/P/S DSPI0  */\r
528     ME.PCTL[5].R = 0x01;  /* MPC56xxB/P/S DSPI1:  */\r
529     ME.PCTL[32].R = 0x01; //ADC0 control\r
530 #if defined(CFG_MPC5606B)\r
531     ME.PCTL[33].R = 0x01; //ADC1 control\r
532 #endif\r
533     ME.PCTL[23].R = 0x01; //DMAMUX control\r
534     ME.PCTL[48].R = 0x01; /* MPC56xxB/P/S LINFlex  */\r
535     ME.PCTL[49].R = 0x01; /* MPC56xxB/P/S LINFlex  */\r
536     /* Mode Transition to enter RUN0 mode: */\r
537     /* Enter RUN0 Mode & Key */\r
538     ME.MCTL.R = 0x40005AF0;\r
539     /* Enter RUN0 Mode & Inverted Key */\r
540     ME.MCTL.R = 0x4000A50F;\r
541 \r
542     /* Wait for mode transition to complete */\r
543     while (ME.GS.B.S_MTRANS) {}\r
544     /* Verify RUN0 is the current mode */\r
545     while(ME.GS.B.S_CURRENTMODE != 4) {}\r
546 \r
547     CGM.SC_DC[0].R = 0x80; /* MPC56xxB/S: Enable peri set 1 sysclk divided by 1 */\r
548     CGM.SC_DC[1].R = 0x80; /* MPC56xxB/S: Enable peri set 2 sysclk divided by 1 */\r
549     CGM.SC_DC[2].R = 0x80; /* MPC56xxB/S: Enable peri set 3 sysclk divided by 1 */\r
550 \r
551     SIU.PSMI[0].R = 0x01; /* CAN1RX on PCR43 */\r
552     SIU.PSMI[6].R = 0x01; /* CS0/DSPI_0 on PCR15 */\r
553 \r
554 #elif defined(CFG_MPC5606S)\r
555     // Write pll parameters.\r
556     CGM.FMPLL[0].CR.B.IDF = clockSettingsPtr->Pll1;\r
557     CGM.FMPLL[0].CR.B.NDIV = clockSettingsPtr->Pll2;\r
558     CGM.FMPLL[0].CR.B.ODF = clockSettingsPtr->Pll3;\r
559 \r
560     /* RUN0 cfg: 16MHzIRCON,OSC0ON,PLL0ON,syclk=PLL0 */\r
561     ME.RUN[0].R = 0x001F0074;\r
562     /* Peri. Cfg. 1 settings: only run in RUN0 mode */\r
563     ME.RUNPC[1].R = 0x00000010;\r
564     /* MPC56xxB/S: select ME.RUNPC[1] */\r
565     ME.PCTL[68].R = 0x01; //SIUL control\r
566     ME.PCTL[91].R = 0x01; //RTC/API control\r
567     ME.PCTL[92].R = 0x01; //PIT_RTI control\r
568     ME.PCTL[72].R = 0x01; //eMIOS0 control\r
569     ME.PCTL[73].R = 0x01; //eMIOS1 control\r
570     ME.PCTL[16].R = 0x01; //FlexCAN0 control\r
571     ME.PCTL[17].R = 0x01; //FlexCAN1 control\r
572     ME.PCTL[4].R = 0x01;  /* MPC56xxB/P/S DSPI0  */\r
573     ME.PCTL[5].R = 0x01;  /* MPC56xxB/P/S DSPI1:  */\r
574     ME.PCTL[32].R = 0x01; //ADC0 control\r
575     ME.PCTL[23].R = 0x01; //DMAMUX control\r
576     ME.PCTL[48].R = 0x01; /* MPC56xxB/P/S LINFlex  */\r
577     ME.PCTL[49].R = 0x01; /* MPC56xxB/P/S LINFlex  */\r
578     /* Mode Transition to enter RUN0 mode: */\r
579     /* Enter RUN0 Mode & Key */\r
580     ME.MCTL.R = 0x40005AF0;\r
581     /* Enter RUN0 Mode & Inverted Key */\r
582     ME.MCTL.R = 0x4000A50F;\r
583 \r
584     /* Wait for mode transition to complete */\r
585     while (ME.GS.B.S_MTRANS) {}\r
586     /* Verify RUN0 is the current mode */\r
587     while(ME.GS.B.S_CURRENTMODE != 4) {}\r
588 \r
589     CGM.SC_DC[0].R = 0x80; /* MPC56xxB/S: Enable peri set 1 sysclk divided by 1 */\r
590     CGM.SC_DC[1].R = 0x80; /* MPC56xxB/S: Enable peri set 2 sysclk divided by 1 */\r
591     CGM.SC_DC[2].R = 0x80; /* MPC56xxB/S: Enable peri set 3 sysclk divided by 1 */\r
592 \r
593  #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
594     // Partially following the steps in MPC5567 RM..\r
595     FMPLL.SYNCR.B.DEPTH = 0;\r
596     FMPLL.SYNCR.B.LOLRE = 0;\r
597     FMPLL.SYNCR.B.LOLIRQ = 0;\r
598 \r
599     FMPLL.SYNCR.B.PREDIV        = clockSettingsPtr->Pll1;\r
600     FMPLL.SYNCR.B.MFD           = clockSettingsPtr->Pll2;\r
601     FMPLL.SYNCR.B.RFD           = clockSettingsPtr->Pll3;\r
602 \r
603         // Wait for PLL to sync.\r
604     while (Mcu_GetPllStatus() != MCU_PLL_LOCKED) ;\r
605 \r
606     FMPLL.SYNCR.B.LOLIRQ        = 1;\r
607 #endif\r
608 \r
609     return E_OK;\r
610 }\r
611 \r
612 //-------------------------------------------------------------------\r
613 \r
614 void Mcu_DistributePllClock(void)\r
615 {\r
616     VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_UNINIT );\r
617 #if defined(CFG_MPC560XB)\r
618     VALIDATE( ( CGM.FMPLL_CR.B.S_LOCK == 1 ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_PLL_NOT_LOCKED );\r
619 #elif defined(CFG_MPC5606S)\r
620     VALIDATE( ( CGM.FMPLL[0].CR.B.S_LOCK == 1 ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_PLL_NOT_LOCKED );\r
621 #else\r
622     VALIDATE( ( FMPLL.SYNSR.B.LOCK == 1 ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_PLL_NOT_LOCKED );\r
623 #endif\r
624     /* NOT IMPLEMENTED due to pointless function on this hardware */\r
625 \r
626 }\r
627 \r
628 //-------------------------------------------------------------------\r
629 \r
630 Mcu_PllStatusType Mcu_GetPllStatus(void)\r
631 {\r
632     VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETPLLSTATUS_SERVICE_ID, MCU_E_UNINIT, MCU_PLL_STATUS_UNDEFINED );\r
633     Mcu_PllStatusType rv;\r
634 \r
635     if( !SIMULATOR() )\r
636     {\r
637 #if defined(CFG_MPC560XB)\r
638         if ( !CGM.FMPLL_CR.B.S_LOCK )\r
639         {\r
640                 rv = MCU_PLL_UNLOCKED;\r
641         } else\r
642         {\r
643                 rv = MCU_PLL_LOCKED;\r
644         }\r
645 #elif defined(CFG_MPC5606S)\r
646         if ( !CGM.FMPLL[0].CR.B.S_LOCK )\r
647         {\r
648                 rv = MCU_PLL_UNLOCKED;\r
649         } else\r
650         {\r
651                 rv = MCU_PLL_LOCKED;\r
652         }\r
653 #else\r
654         if ( !FMPLL.SYNSR.B.LOCK )\r
655         {\r
656                 rv = MCU_PLL_UNLOCKED;\r
657         } else\r
658         {\r
659                 rv = MCU_PLL_LOCKED;\r
660         }\r
661 #endif\r
662     }\r
663     else\r
664     {\r
665         /* We are running on instruction set simulator. PLL is then always in sync... */\r
666         rv = MCU_PLL_LOCKED;\r
667     }\r
668 \r
669   return rv;\r
670 }\r
671 \r
672 //-------------------------------------------------------------------\r
673 \r
674 Mcu_ResetType Mcu_GetResetReason(void)\r
675 {\r
676         Mcu_ResetType rv;\r
677 \r
678         VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETRESETREASON_SERVICE_ID, MCU_E_UNINIT, MCU_RESET_UNDEFINED );\r
679 \r
680 #if defined(CFG_MPC560X)\r
681         if( RGM.FES.B.F_SOFT ) {\r
682                 rv = MCU_SW_RESET;\r
683         } else if( RGM.DES.B.F_SWT ) {\r
684                 rv = MCU_WATCHDOG_RESET;\r
685         } else if( RGM.DES.B.F_POR ) {\r
686                 rv = MCU_POWER_ON_RESET;\r
687         } else {\r
688                 rv = MCU_RESET_UNDEFINED;\r
689         }\r
690 #else\r
691         if( SIU.RSR.B.SSRS ) {\r
692                 rv = MCU_SW_RESET;\r
693         } else if( SIU.RSR.B.WDRS ) {\r
694                 rv = MCU_WATCHDOG_RESET;\r
695         } else if( SIU.RSR.B.PORS || SIU.RSR.B.ERS ) {\r
696                 rv = MCU_POWER_ON_RESET;\r
697         } else {\r
698                 rv = MCU_RESET_UNDEFINED;\r
699         }\r
700 #endif\r
701 \r
702         return rv;\r
703 }\r
704 \r
705 //-------------------------------------------------------------------\r
706 \r
707 Mcu_RawResetType Mcu_GetResetRawValue(void)\r
708 {\r
709         VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETRESETREASON_SERVICE_ID, MCU_E_UNINIT, MCU_GETRESETRAWVALUE_UNINIT_RV );\r
710 \r
711         if( !Mcu_Global.initRun ) {\r
712                 return MCU_GETRESETRAWVALUE_UNINIT_RV;\r
713         }\r
714 \r
715 #if defined(CFG_MPC560X)\r
716         if( RGM.DES.R )\r
717                 return RGM.DES.R;\r
718         else\r
719                 return RGM.FES.R;\r
720 #else\r
721         return SIU.RSR.R;\r
722 #endif\r
723 \r
724 }\r
725 \r
726 //-------------------------------------------------------------------\r
727 \r
728 #if ( MCU_PERFORM_RESET_API == STD_ON )\r
729 void Mcu_PerformReset(void)\r
730 {\r
731         VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_PERFORMRESET_SERVICE_ID, MCU_E_UNINIT );\r
732 \r
733         // Reset\r
734 #if defined(CFG_MPC560X)\r
735     ME.MCTL.R = 0x00005AF0;\r
736     ME.MCTL.R = 0x0000A50F;\r
737 \r
738     while (ME.GS.B.S_MTRANS) {}\r
739     while(ME.GS.B.S_CURRENTMODE != 0) {}\r
740 #else\r
741         SIU.SRCR.B.SSR = 1;\r
742 #endif\r
743 \r
744 }\r
745 #endif\r
746 \r
747 //-------------------------------------------------------------------\r
748 \r
749 #if defined(CFG_MPC5516) || defined(CFG_MPC5668)\r
750 \r
751 /**\r
752  *\r
753  * Application Notes!\r
754  * - AN3584, "MPC5510 Family Low Power Features"\r
755  *   Since it's not complete also check MPC5668\r
756  * - AN4150 , "Using Sleep Mode on the MPC5668x" and it's code\r
757  *\r
758  *\r
759  * @param LPM\r
760  */\r
761 static void enterLowPower (Mcu_ModeType mcuMode )\r
762 {\r
763 \r
764 \r
765         uint32 timeout;\r
766         /* - Set the sleep bit; following a WAIT instruction, the device will go to sleep\r
767          * - enable the 1.2V internal regulator when in sleep mode only\r
768          * - MPC5516\r
769          *   - 0x1 8k, 0x2 16k, 0x3 32k, 0x6 64k -- RAMs maintain power\r
770          * - MPC5668\r
771          *   - 0x1 32k, 0x2 64k, 0x3 128k\r
772          */\r
773         WRITE32(CRP_PSCR, PSCR_SLEEP | PSCR_SLP12EN | PCSR_RAMSEL(RAMSEL_VAL));\r
774 \r
775         /* Set Recover Vector */\r
776 #if defined(CFG_MPC5516)\r
777 \r
778         WRITE32(CRP_Z1VEC, ((uint32)&McuE_LowPowerRecoverFlash) | VLE_VAL );\r
779         READWRITE32( CRP_RECPTR, RECPTR_FASTREC, 0 );\r
780 \r
781         Mcu_SavedHaltFlags = SIU.HLT.R;\r
782         /* Halt everything */\r
783         SIU.HLT.R = 0x3FFFFFFF;\r
784         while((SIU.HLTACK.R != 0x3FFFFFFF) && (timeout<3000)) {}\r
785 \r
786         /* put Z0 in reset if not used for wakeup */\r
787         CRP.Z0VEC.B.Z0RST = 1;\r
788 \r
789 #elif defined(CFG_MPC5668)\r
790 \r
791         WRITE32(CRP_Z6VEC, ((uint32)&McuE_LowPowerRecoverFlash) | VLE_VAL );\r
792         READWRITE32(CRP_RECPTR,RECPTR_FASTREC,0 );\r
793 \r
794         Mcu_SavedHaltFlags[0] = SIU.HLT0.R;\r
795         Mcu_SavedHaltFlags[1] = SIU.HLT1.R;\r
796         /* Halt everything */\r
797     SIU.HLT0.R = 0x037FFF3D;\r
798     SIU.HLT1.R = 0x18000F3C;\r
799     while((SIU.HLTACK0.R != 0x037FFF3D) && (SIU.HLTACK1.R != 0x18000F3C) && (timeout<3000)){}\r
800 #else\r
801 #error CPU not defined\r
802 #endif\r
803 \r
804         /* put Z0 in reset if not used for wakeup */\r
805         CRP.Z0VEC.B.Z0RST = 1;\r
806 \r
807     /* Save context and execute wait instruction.\r
808          *\r
809          * Things that matter here are\r
810          * - Z1VEC, determines where TLB0 will point. TLB0 is written with a\r
811          *   value at startup that 4K aligned to this address.\r
812          * - LowPower_Sleep() will save a interrupt context so we will return\r
813          *   intact.\r
814          * - For devices with little RAM we don't want to impose the alignment\r
815          *   requirements there. Almost as we have to occupy a 4K block for this..\r
816          *   although the code does not take that much space.\r
817          * */\r
818         McuE_EnterLowPower(mcuMode);\r
819 \r
820     /* Clear sleep flags to allow pads to operate */\r
821     CRP.PSCR.B.SLEEPF = 0x1;\r
822 }\r
823 \r
824 #endif\r
825 \r
826 void Mcu_SetMode( Mcu_ModeType mcuMode)\r
827 {\r
828         VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_SETMODE_SERVICE_ID, MCU_E_UNINIT );\r
829         // VALIDATE( ( McuMode <= Mcu_Global.config->McuNumberOfMcuModes ), MCU_SETMODE_SERVICE_ID, MCU_E_PARAM_MODE );\r
830 \r
831 \r
832 #if defined(CFG_MPC5516) || defined(CFG_MPC5668)\r
833         if( MCU_MODE_RUN == mcuMode ) {\r
834 \r
835                 /* Get back to "normal" halt flags */\r
836 #if defined(CFG_MPC5516)\r
837                 SIU.HLT.R = Mcu_SavedHaltFlags;\r
838 #elif defined(CFG_MPC5668)\r
839                 SIU.HLT0.R = Mcu_SavedHaltFlags[0];\r
840                 SIU.HLT1.R = Mcu_SavedHaltFlags[1];\r
841 #endif\r
842 \r
843         } else if( MCU_MODE_SLEEP == mcuMode ) {\r
844                 /*\r
845                  * Follows the AN3548 from Freescale\r
846                  *\r
847                  */\r
848 #if defined(USE_DMA)\r
849                 Dma_DeInit();\r
850 #endif\r
851 \r
852 \r
853                 /* Set system clock to 16Mhz IRC */\r
854                 SIU.SYSCLK.B.SYSCLKSEL = 0;\r
855 \r
856                 /* Put flash in low-power mode */\r
857                 // TODO\r
858 \r
859                 /* Put QQADC in low-power mode */\r
860                 // TODO\r
861 \r
862                 /* Set us in SLEEP mode */\r
863                 CRP.PSCR.B.SLEEP = 1;\r
864 \r
865 \r
866                 enterLowPower(mcuMode);\r
867         }\r
868 #else\r
869         /* NOT SUPPORTED */\r
870         (void) mcuMode;\r
871 #endif\r
872 }\r
873 \r
874 //-------------------------------------------------------------------\r
875 \r
876 /**\r
877  * Get the system clock in Hz. It calculates the clock from the\r
878  * different register settings in HW.\r
879  */\r
880 uint32_t McuE_GetSystemClock(void)\r
881 {\r
882         /*\r
883          * System clock calculation\r
884          *\r
885          * 5516 -  f_sys = extal * (emfd+16) / ( (eprediv+1) * ( erfd+1 ));\r
886          * 5567 -  f_sys = extal * (emfd+4) / ( (eprediv+1) * ( 2^erfd ));\r
887          * 563x -  We run in legacy mode = 5567\r
888          * 5606s - f_sys = extal * emfd / ((eprediv+1)*(2<<(erfd)));\r
889          */\r
890 #if defined(CFG_MPC5516) || defined(CFG_MPC5668)\r
891         uint32_t eprediv = FMPLL.ESYNCR1.B.EPREDIV;\r
892         uint32_t emfd = FMPLL.ESYNCR1.B.EMFD;\r
893         uint32_t erfd = FMPLL.ESYNCR2.B.ERFD;\r
894 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567) || defined(CFG_MPC5633)\r
895         uint32_t eprediv = FMPLL.SYNCR.B.PREDIV;\r
896         uint32_t emfd = FMPLL.SYNCR.B.MFD;\r
897         uint32_t erfd = FMPLL.SYNCR.B.RFD;\r
898 #elif defined(CFG_MPC560XB)\r
899     uint32_t eprediv = CGM.FMPLL_CR.B.IDF;\r
900     uint32_t emfd = CGM.FMPLL_CR.B.NDIV;\r
901     uint32_t erfd = CGM.FMPLL_CR.B.ODF;\r
902 #elif defined(CFG_MPC5606S)\r
903     uint32_t eprediv = CGM.FMPLL[0].CR.B.IDF;\r
904     uint32_t emfd = CGM.FMPLL[0].CR.B.NDIV;\r
905     uint32_t erfd = CGM.FMPLL[0].CR.B.ODF;\r
906 #endif\r
907 \r
908     uint32_t f_sys;\r
909     uint32  extal = Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting].McuClockReferencePointFrequency;\r
910 \r
911     f_sys = CALC_SYSTEM_CLOCK(extal,emfd,eprediv,erfd);\r
912 \r
913     return f_sys;\r
914 }\r
915 \r
916 #if defined(CFG_MPC5668)\r
917 uint32_t McuE_GetPeripheralClock(McuE_PeriperalClock_t type) {\r
918         uint32_t sysClock = McuE_GetSystemClock();\r
919         vuint32_t prescaler;\r
920 \r
921         switch (type)\r
922         {\r
923                 case PERIPHERAL_CLOCK_FLEXCAN_A:\r
924                 case PERIPHERAL_CLOCK_FLEXCAN_B:\r
925                 case PERIPHERAL_CLOCK_FLEXCAN_C:\r
926                 case PERIPHERAL_CLOCK_FLEXCAN_D:\r
927                 case PERIPHERAL_CLOCK_FLEXCAN_E:\r
928                 case PERIPHERAL_CLOCK_FLEXCAN_F:\r
929                 case PERIPHERAL_CLOCK_DSPI_A:\r
930                 case PERIPHERAL_CLOCK_DSPI_B:\r
931                 case PERIPHERAL_CLOCK_DSPI_C:\r
932                 case PERIPHERAL_CLOCK_DSPI_D:\r
933                         prescaler = SIU.SYSCLK.B.LPCLKDIV1;\r
934                         break;\r
935                 case PERIPHERAL_CLOCK_ESCI_A:\r
936                 case PERIPHERAL_CLOCK_ESCI_B:\r
937                 case PERIPHERAL_CLOCK_ESCI_C:\r
938                 case PERIPHERAL_CLOCK_ESCI_D:\r
939                 case PERIPHERAL_CLOCK_ESCI_E:\r
940                 case PERIPHERAL_CLOCK_ESCI_F:\r
941                 case PERIPHERAL_CLOCK_IIC_A:\r
942                 case PERIPHERAL_CLOCK_IIC_B:\r
943                         prescaler = SIU.SYSCLK.B.LPCLKDIV0;\r
944                         break;\r
945                 case PERIPHERAL_CLOCK_ADC_A:\r
946                         prescaler = SIU.SYSCLK.B.LPCLKDIV2;\r
947                         break;\r
948                 case PERIPHERAL_CLOCK_EMIOS:\r
949                         prescaler = SIU.SYSCLK.B.LPCLKDIV3;\r
950                         break;\r
951                 default:\r
952                         assert(0);\r
953                         break;\r
954         }\r
955 \r
956         return sysClock/(1<<prescaler);\r
957 \r
958 }\r
959 \r
960 #else\r
961 \r
962 /**\r
963  * Get the peripheral clock in Hz for a specific device\r
964  */\r
965 uint32_t McuE_GetPeripheralClock(McuE_PeriperalClock_t type)\r
966 {\r
967 #if defined(CFG_MPC5567)\r
968         // No peripheral dividers on 5567.\r
969         return McuE_GetSystemClock();\r
970 #else\r
971         uint32_t sysClock = McuE_GetSystemClock();\r
972         vuint32_t prescaler;\r
973 \r
974   // See table 3.1, section 3.4.5 Peripheral Clock dividers\r
975         switch (type)\r
976         {\r
977                 case PERIPHERAL_CLOCK_FLEXCAN_A:\r
978                 case PERIPHERAL_CLOCK_DSPI_A:\r
979 #if defined(CFG_MPC5516)\r
980                         prescaler = SIU.SYSCLK.B.LPCLKDIV0;\r
981                         break;\r
982 #elif defined(CFG_MPC560X)\r
983                         prescaler = CGM.SC_DC[1].B.DIV;\r
984                         break;\r
985 #endif\r
986 \r
987                 case PERIPHERAL_CLOCK_PIT:\r
988                 case PERIPHERAL_CLOCK_ESCI_A:\r
989                 case PERIPHERAL_CLOCK_IIC_A:\r
990 #if defined(CFG_MPC5516)\r
991                         prescaler = SIU.SYSCLK.B.LPCLKDIV1;\r
992                         break;\r
993 #endif\r
994 \r
995                 case PERIPHERAL_CLOCK_FLEXCAN_B:\r
996                 case PERIPHERAL_CLOCK_FLEXCAN_C:\r
997                 case PERIPHERAL_CLOCK_FLEXCAN_D:\r
998                 case PERIPHERAL_CLOCK_FLEXCAN_E:\r
999                 case PERIPHERAL_CLOCK_FLEXCAN_F:\r
1000 #if defined(CFG_MPC5516)\r
1001                         prescaler = SIU.SYSCLK.B.LPCLKDIV2;\r
1002                         break;\r
1003 #elif defined(CFG_MPC560X)\r
1004                         prescaler = CGM.SC_DC[1].B.DIV;\r
1005                         break;\r
1006 #endif\r
1007 \r
1008                 case PERIPHERAL_CLOCK_DSPI_B:\r
1009                 case PERIPHERAL_CLOCK_DSPI_C:\r
1010                 case PERIPHERAL_CLOCK_DSPI_D:\r
1011                 case PERIPHERAL_CLOCK_DSPI_E:\r
1012                 case PERIPHERAL_CLOCK_DSPI_F:\r
1013 #if defined(CFG_MPC5516)\r
1014                 prescaler = SIU.SYSCLK.B.LPCLKDIV3;\r
1015                         break;\r
1016 #endif\r
1017 \r
1018                 case PERIPHERAL_CLOCK_ESCI_B:\r
1019                 case PERIPHERAL_CLOCK_ESCI_C:\r
1020                 case PERIPHERAL_CLOCK_ESCI_D:\r
1021                 case PERIPHERAL_CLOCK_ESCI_E:\r
1022                 case PERIPHERAL_CLOCK_ESCI_F:\r
1023                 case PERIPHERAL_CLOCK_ESCI_G:\r
1024                 case PERIPHERAL_CLOCK_ESCI_H:\r
1025 #if defined(CFG_MPC5516)\r
1026                         prescaler = SIU.SYSCLK.B.LPCLKDIV4;\r
1027                         break;\r
1028 #endif\r
1029 \r
1030 #if defined(CFG_MPC560X)\r
1031                 case PERIPHERAL_CLOCK_LIN_A:\r
1032                 case PERIPHERAL_CLOCK_LIN_B:\r
1033 #if defined(CFG_MPC560XB)\r
1034                 case PERIPHERAL_CLOCK_LIN_C:\r
1035                 case PERIPHERAL_CLOCK_LIN_D:\r
1036 #endif\r
1037                         prescaler = CGM.SC_DC[0].B.DIV;\r
1038                         break;\r
1039                 case PERIPHERAL_CLOCK_EMIOS_0:\r
1040                         prescaler = CGM.SC_DC[2].B.DIV;\r
1041                         break;\r
1042                 case PERIPHERAL_CLOCK_EMIOS_1:\r
1043                         prescaler = CGM.SC_DC[2].B.DIV;\r
1044                         break;\r
1045 #else\r
1046                 case PERIPHERAL_CLOCK_EMIOS:\r
1047 #if defined(CFG_MPC5516)\r
1048                         prescaler = SIU.SYSCLK.B.LPCLKDIV5;\r
1049                         break;\r
1050 #endif\r
1051 #endif\r
1052 \r
1053                 case PERIPHERAL_CLOCK_MLB:\r
1054 #if defined(CFG_MPC5516)\r
1055                         prescaler = SIU.SYSCLK.B.LPCLKDIV6;\r
1056                         break;\r
1057 #endif\r
1058 \r
1059                 default:\r
1060                         assert(0);\r
1061                         break;\r
1062         }\r
1063 \r
1064         return sysClock/(1<<prescaler);\r
1065 #endif\r
1066 }\r
1067 #endif\r
1068 \r
1069 /**\r
1070  * Function to setup the internal flash for optimal performance\r
1071  */\r
1072 \r
1073 static void Mcu_ConfigureFlash(void)\r
1074 {\r
1075         /* These flash settings increases the CPU performance of 7 times compared\r
1076            to reset default settings!! */\r
1077 \r
1078 #if defined(CFG_MPC5516)\r
1079         /* Disable pipelined reads when flash options are changed. */\r
1080         FLASH.MCR.B.PRD = 1;\r
1081 \r
1082         /* Enable master prefetch for e200z1 and eDMA. */\r
1083         FLASH.PFCRP0.B.M0PFE = 1;\r
1084         FLASH.PFCRP0.B.M2PFE = 1;\r
1085 \r
1086         /* Address pipelining control. Must be set to the same value as RWSC. */\r
1087         FLASH.PFCRP0.B.APC = 2;\r
1088         FLASH.PFCRP0.B.RWSC = 2;\r
1089 \r
1090         /* Write wait states. */\r
1091         FLASH.PFCRP0.B.WWSC = 1;\r
1092 \r
1093         /* Enable data prefetch. */\r
1094         FLASH.PFCRP0.B.DPFEN = 1;\r
1095 \r
1096         /* Enable instruction prefetch. */\r
1097         FLASH.PFCRP0.B.IPFEN = 1;\r
1098 \r
1099         /* Prefetch algorithm. */\r
1100         /* TODO: Ask Freescale about this option. */\r
1101         FLASH.PFCRP0.B.PFLIM = 2;\r
1102 \r
1103         /* Enable line read buffers. */\r
1104         FLASH.PFCRP0.B.BFEN = 1;\r
1105 \r
1106         /* Enable pipelined reads again. */\r
1107         FLASH.MCR.B.PRD = 0;\r
1108 #elif defined(CFG_MPC5668)\r
1109         /* Check values from cookbook and MPC5668x Microcontroller Data Sheet */\r
1110 \r
1111         /* Should probably trim this values */\r
1112         const typeof(FLASH.PFCRP0.B) val = {.M0PFE = 1, .M2PFE=1, .APC=3,\r
1113                                                                  .RWSC=3, .WWSC =1, .DPFEN =1, .IPFEN = 1, .PFLIM =2,\r
1114                                                                  .BFEN  = 1 };\r
1115         FLASH.PFCRP0.B = val;\r
1116 \r
1117         /* Enable pipelined reads again. */\r
1118 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
1119         //TODO: Lägg till flash för mpc5554 &67\r
1120 #endif\r
1121 }\r
1122 \r