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