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