]> rtime.felk.cvut.cz Git - arc.git/blob - arch/ppc/mpc55xx/drivers/Mcu.c
Merge with hcs12_mcal
[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 \r
18 \r
19 \r
20 \r
21 \r
22 \r
23 #include <assert.h>\r
24 #include <string.h>\r
25 #include "Std_Types.h"\r
26 #include "Mcu.h"\r
27 #include "Det.h"\r
28 #if defined(USE_DEM)\r
29 #include "Dem.h"\r
30 #endif\r
31 #include "mpc55xx.h"\r
32 #include "Cpu.h"\r
33 #include "Ramlog.h"\r
34 #include "Os.h"\r
35 #include "irq.h"\r
36 \r
37 //#define USE_TRACE 1\r
38 //#define USE_LDEBUG_PRINTF 1\r
39 #include "debug.h"\r
40 \r
41 #define SYSCLOCK_SELECT_PLL     0x2\r
42 \r
43 #if defined(CFG_MPC5567)\r
44 #define CALC_SYSTEM_CLOCK(_extal,_emfd,_eprediv,_erfd)  \\r
45             ( (_extal) * ((_emfd)+4) / (((_eprediv)+1)*(1<<(_erfd))) )\r
46 #else\r
47 #define CALC_SYSTEM_CLOCK(_extal,_emfd,_eprediv,_erfd)  \\r
48             ( (_extal) * ((_emfd)+16) / (((_eprediv)+1)*((_erfd)+1)) )\r
49 #endif\r
50 \r
51 typedef void (*vfunc_t)();\r
52 \r
53 /* Function declarations. */\r
54 static void Mcu_ConfigureFlash(void);\r
55 \r
56 \r
57 typedef struct {\r
58         uint32 lossOfLockCnt;\r
59         uint32 lossOfClockCnt;\r
60 } Mcu_Stats;\r
61 \r
62 /**\r
63  * Type that holds all global data for Mcu\r
64  */\r
65 typedef struct\r
66 {\r
67   // Set if Mcu_Init() have been called\r
68   boolean initRun;\r
69 \r
70   // Our config\r
71   const Mcu_ConfigType *config;\r
72 \r
73   Mcu_ClockType clockSetting;\r
74 \r
75   Mcu_Stats stats;\r
76 \r
77 } Mcu_GlobalType;\r
78 \r
79 /* Development error macros. */\r
80 #if ( MCU_DEV_ERROR_DETECT == STD_ON )\r
81 #define VALIDATE(_exp,_api,_err ) \\r
82         if( !(_exp) ) { \\r
83           Det_ReportError(MODULE_ID_MCU,0,_api,_err); \\r
84           return; \\r
85         }\r
86 \r
87 #define VALIDATE_W_RV(_exp,_api,_err,_rv ) \\r
88         if( !(_exp) ) { \\r
89           Det_ReportError(MODULE_ID_MCU,0,_api,_err); \\r
90           return (_rv); \\r
91         }\r
92 #else\r
93 #define VALIDATE(_exp,_api,_err )\r
94 #define VALIDATE_W_RV(_exp,_api,_err,_rv )\r
95 #endif\r
96 \r
97 // Global config\r
98 Mcu_GlobalType Mcu_Global =\r
99 {\r
100                 .initRun = 0,\r
101                 .config = &McuConfigData[0],\r
102 };\r
103 \r
104 //-------------------------------------------------------------------\r
105 \r
106 static void Mcu_LossOfLock( void  ) {\r
107 #if defined(USE_DEM)\r
108         Dem_ReportErrorStatus(MCU_E_CLOCK_FAILURE, DEM_EVENT_STATUS_FAILED);\r
109 #endif\r
110 \r
111         Mcu_Global.stats.lossOfLockCnt++;\r
112         // Clear interrupt\r
113         FMPLL.SYNSR.B.LOLF = 1;\r
114 \r
115 }\r
116 \r
117 //-------------------------------------------------------------------\r
118 static void Mcu_LossOfCLock( void  ) {\r
119 \r
120         /* Should report MCU_E_CLOCK_FAILURE with DEM here */\r
121 \r
122         Mcu_Global.stats.lossOfClockCnt++;\r
123         // Clear interrupt\r
124         FMPLL.SYNSR.B.LOCF = 1;\r
125 }\r
126 \r
127 \r
128 #define SPR_PIR 286\r
129 #define SPR_PVR 287\r
130 \r
131 #define CORE_PVR_E200Z1         0x81440000UL\r
132 #define CORE_PVR_E200Z0         0x81710000UL\r
133 #define CORE_PVR_E200Z3         0x81120000UL\r
134 #define CORE_PVR_E200Z6         0x81170000UL\r
135 \r
136 \r
137 typedef struct {\r
138   char *name;\r
139   uint32 pvr;\r
140 } core_info_t;\r
141 \r
142 typedef struct {\r
143   char *name;\r
144   uint32 pvr;\r
145 } cpu_info_t;\r
146 \r
147 cpu_info_t cpu_info_list[] =\r
148 {\r
149 #if defined(CFG_MPC5516)\r
150     {\r
151     .name = "MPC5516",\r
152     .pvr = CORE_PVR_E200Z1,\r
153     },\r
154     {\r
155     .name = "MPC5516",\r
156     .pvr = CORE_PVR_E200Z0,\r
157     },\r
158 #elif defined(CFG_MPC5567)\r
159     {\r
160         .name = "MPC5567",\r
161         .pvr = CORE_PVR_E200Z6,\r
162     }\r
163 #elif defined(CFG_MPC5633)\r
164     {\r
165     .name = "MPC563X",\r
166     .pvr = CORE_PVR_E200Z3,\r
167     },\r
168 #endif\r
169 };\r
170 \r
171 core_info_t core_info_list[] = {\r
172 #if defined(CFG_MPC5516)\r
173         {\r
174     .name = "CORE_E200Z1",\r
175     .pvr = CORE_PVR_E200Z1,\r
176     },\r
177     {\r
178     .name = "CORE_E200Z1",\r
179     .pvr = CORE_PVR_E200Z1,\r
180     },\r
181 #elif defined(CFG_MPC5567)\r
182     {\r
183         .name = "CORE_E200Z6",\r
184         .pvr = CORE_PVR_E200Z6,\r
185     }\r
186 #elif defined(CFG_MPC5633)\r
187     {\r
188     .name = "CORE_E200Z3",\r
189     .pvr = CORE_PVR_E200Z3,\r
190     },\r
191 #endif\r
192 };\r
193 \r
194 // TODO: move\r
195 #if !defined(ARRAY_SIZE)\r
196 #define ARRAY_SIZE(_x)  (sizeof(_x)/sizeof((_x)[0]))\r
197 #endif\r
198 \r
199 static cpu_info_t *Mcu_IdentifyCpu(uint32 pvr)\r
200 {\r
201   int i;\r
202   for (i = 0; i < ARRAY_SIZE(cpu_info_list); i++) {\r
203     if (cpu_info_list[i].pvr == pvr) {\r
204       return &cpu_info_list[i];\r
205     }\r
206   }\r
207 \r
208   return NULL;\r
209 }\r
210 \r
211 static core_info_t *Mcu_IdentifyCore(uint32 pvr)\r
212 {\r
213   int i;\r
214   for (i = 0; i < ARRAY_SIZE(core_info_list); i++) {\r
215     if (core_info_list[i].pvr == pvr) {\r
216       return &core_info_list[i];\r
217     }\r
218   }\r
219 \r
220   return NULL;\r
221 }\r
222 \r
223 \r
224 static uint32 Mcu_CheckCpu( void ) {\r
225 \r
226   uint32 pvr;\r
227   uint32 pir;\r
228   cpu_info_t *cpuType;\r
229   core_info_t *coreType;\r
230 \r
231   // We have to registers to read here, PIR and PVR\r
232 \r
233   pir = get_spr(SPR_PIR);\r
234   pvr = get_spr(SPR_PVR);\r
235 \r
236   cpuType = Mcu_IdentifyCpu(pvr);\r
237   coreType = Mcu_IdentifyCore(pvr);\r
238 \r
239   if( (cpuType == NULL) || (coreType == NULL) ) {\r
240     // Just hang\r
241     while(1);\r
242   }\r
243 \r
244   //DEBUG(DEBUG_HIGH,"/drivers/mcu: Cpu:  %s( 0x%08x )\n",cpuType->name,pvr);\r
245   //DEBUG(DEBUG_HIGH,"/drivers/mcu: Core: %s( 0x%08x )\n",coreType->name,pvr);\r
246 \r
247   return 0;\r
248 }\r
249 \r
250 \r
251 //-------------------------------------------------------------------\r
252 \r
253 void Mcu_Init(const Mcu_ConfigType *configPtr)\r
254 {\r
255   VALIDATE( ( NULL != configPtr ), MCU_INIT_SERVICE_ID, MCU_E_PARAM_CONFIG );\r
256 \r
257   if( !SIMULATOR() ) {\r
258           Mcu_CheckCpu();\r
259   }\r
260 \r
261   memset(&Mcu_Global.stats,0,sizeof(Mcu_Global.stats));\r
262 \r
263 \r
264   //\r
265   // Setup memories\r
266   //\r
267   Mcu_ConfigureFlash();\r
268 \r
269   Mcu_Global.config = configPtr;\r
270   Mcu_Global.initRun = 1;\r
271 \r
272   if( Mcu_Global.config->McuClockSrcFailureNotification == TRUE  ){\r
273         // Enable loss of lock interrupt\r
274 \r
275         Irq_AttachIsr1(Mcu_LossOfLock, NULL, PLL_SYNSR_LOLF,10 );\r
276 #if defined(CFG_MPC5516)\r
277 //      FMPLL.SYNCR.B.LOCIRQ = 1; TODO: Kolla denna bortkommentering med Mårten.\r
278         FMPLL.ESYNCR2.B.LOLIRQ = 1;\r
279 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
280         FMPLL.SYNCR.B.LOLIRQ = 1;\r
281 #endif\r
282         Irq_AttachIsr1(Mcu_LossOfCLock, NULL, PLL_SYNSR_LOCF,10 );\r
283 #if defined(CFG_MPC5516)\r
284 //      FMPLL.SYNCR.B.LOCIRQ = 1; TODO: Kolla denna bortkommentering med Mårten.\r
285         FMPLL.ESYNCR2.B.LOCIRQ = 1;\r
286 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
287         FMPLL.SYNCR.B.LOCIRQ = 1;\r
288 #endif\r
289   }\r
290 }\r
291 //-------------------------------------------------------------------\r
292 \r
293 void Mcu_DeInit()\r
294 {\r
295   Mcu_Global.initRun = FALSE; // Very simple Deinit. Should we do more?\r
296 }\r
297 \r
298 //-------------------------------------------------------------------\r
299 Std_ReturnType Mcu_InitRamSection(const Mcu_RamSectionType RamSection)\r
300 {\r
301   VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_INITRAMSECTION_SERVICE_ID, MCU_E_UNINIT, E_NOT_OK );\r
302   VALIDATE_W_RV( ( RamSection <= Mcu_Global.config->McuRamSectors ), MCU_INITRAMSECTION_SERVICE_ID, MCU_E_PARAM_RAMSECTION, E_NOT_OK );\r
303 \r
304   /* NOT SUPPORTED, reason: no support for external RAM */\r
305 \r
306   return E_OK;\r
307 }\r
308 \r
309 \r
310 \r
311 //-------------------------------------------------------------------\r
312 \r
313 Std_ReturnType Mcu_InitClock(const Mcu_ClockType ClockSetting)\r
314 {\r
315   Mcu_ClockSettingConfigType *clockSettingsPtr;\r
316   VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_INITCLOCK_SERVICE_ID, MCU_E_UNINIT, E_NOT_OK );\r
317   VALIDATE_W_RV( ( ClockSetting < Mcu_Global.config->McuClockSettings ), MCU_INITCLOCK_SERVICE_ID, MCU_E_PARAM_CLOCK, E_NOT_OK );\r
318 \r
319   Mcu_Global.clockSetting = ClockSetting;\r
320   clockSettingsPtr = &Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting];\r
321 \r
322 \r
323   // TODO: find out if the 5554 really works like the 5516 here\r
324   // All three (16, 54, 67) used to run the same code here though, so i'm sticking it with 5516\r
325 #if defined(CFG_MPC5516) || defined(CFG_MPC5554)\r
326   /* 5516clock info:\r
327    * Fsys - System frequency ( CPU + all periperals? )\r
328    *\r
329    *  Fsys = EXTAL_FREQ *(  (emfd+16) / ( (eprediv+1) * ( erfd+1 )) ) )\r
330    */\r
331   // Check ranges...\r
332   assert((clockSettingsPtr->Pll2>=32) && (clockSettingsPtr->Pll2<=132));\r
333   assert( (clockSettingsPtr->Pll1 != 6) &&\r
334           (clockSettingsPtr->Pll1 != 8) &&\r
335           (clockSettingsPtr->Pll1 < 10) );\r
336   assert( clockSettingsPtr->Pll3 & 1); // Must be odd\r
337 #elif defined(CFG_MPC5567)\r
338   /* 5567 clock info:\r
339    *  Fsys = EXTAL_FREQ *(  (emfd+4) / ( (eprediv+1) * ( 2^erfd )) ) )\r
340    */\r
341   // Check ranges...\r
342   assert(clockSettingsPtr->Pll2 < 16);\r
343   assert(clockSettingsPtr->Pll1 <= 4);\r
344   assert(clockSettingsPtr->Pll3 < 8);\r
345 #endif\r
346 \r
347 \r
348 #if defined(USE_LDEBUG_PRINTF)\r
349   {\r
350     uint32    extal = Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting].McuClockReferencePointFrequency;\r
351     uint32    f_sys;\r
352 \r
353     f_sys = CALC_SYSTEM_CLOCK( extal,\r
354         clockSettingsPtr->Pll2,\r
355         clockSettingsPtr->Pll1,\r
356         clockSettingsPtr->Pll3 );\r
357 \r
358     //DEBUG(DEBUG_HIGH,"/drivers/mcu: F_sys will be:%08d Hz\n",f_sys);\r
359   }\r
360 #endif\r
361 \r
362 #if defined(CFG_MPC5516)\r
363   // External crystal PLL mode.\r
364   FMPLL.ESYNCR1.B.CLKCFG = 7; //TODO: Hur ställa detta för 5567?\r
365 \r
366   // Write pll parameters.\r
367   FMPLL.ESYNCR1.B.EPREDIV = clockSettingsPtr->Pll1;\r
368   FMPLL.ESYNCR1.B.EMFD    = clockSettingsPtr->Pll2;\r
369   FMPLL.ESYNCR2.B.ERFD    = clockSettingsPtr->Pll3;\r
370 \r
371   // Connect SYSCLK to FMPLL\r
372   SIU.SYSCLK.B.SYSCLKSEL = SYSCLOCK_SELECT_PLL;\r
373 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
374   // Partially following the steps in MPC5567 RM..\r
375   FMPLL.SYNCR.B.DEPTH   = 0;\r
376   FMPLL.SYNCR.B.LOLRE   = 0;\r
377   FMPLL.SYNCR.B.LOLIRQ  = 0;\r
378 \r
379   FMPLL.SYNCR.B.PREDIV  = clockSettingsPtr->Pll1;\r
380   FMPLL.SYNCR.B.MFD             = clockSettingsPtr->Pll2;\r
381   FMPLL.SYNCR.B.RFD     = clockSettingsPtr->Pll3;\r
382 \r
383         // Wait for PLL to sync.\r
384   while (Mcu_GetPllStatus() != MCU_PLL_LOCKED)\r
385     ;\r
386 \r
387   FMPLL.SYNCR.B.LOLIRQ  = 1;\r
388 #endif\r
389 \r
390   return E_OK;\r
391 }\r
392 \r
393 //-------------------------------------------------------------------\r
394 \r
395 void Mcu_DistributePllClock(void)\r
396 {\r
397   VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_UNINIT );\r
398   VALIDATE( ( FMPLL.SYNSR.B.LOCK == 1 ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_PLL_NOT_LOCKED );\r
399 \r
400   /* NOT IMPLEMENTED due to pointless function on this hardware */\r
401 \r
402 }\r
403 \r
404 //-------------------------------------------------------------------\r
405 \r
406 Mcu_PllStatusType Mcu_GetPllStatus(void)\r
407 {\r
408   VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETPLLSTATUS_SERVICE_ID, MCU_E_UNINIT, MCU_PLL_STATUS_UNDEFINED );\r
409   Mcu_PllStatusType rv;\r
410 \r
411   if( !SIMULATOR() )\r
412   {\r
413     if ( !FMPLL.SYNSR.B.LOCK )\r
414     {\r
415       rv = MCU_PLL_UNLOCKED;\r
416     } else\r
417     {\r
418       rv = MCU_PLL_LOCKED;\r
419     }\r
420   }\r
421   else\r
422   {\r
423     /* We are running on instruction set simulator. PLL is then always in sync... */\r
424     rv = MCU_PLL_LOCKED;\r
425   }\r
426 \r
427   return rv;\r
428 }\r
429 \r
430 //-------------------------------------------------------------------\r
431 \r
432 Mcu_ResetType Mcu_GetResetReason(void)\r
433 {\r
434         Mcu_ResetType rv;\r
435 \r
436   VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETRESETREASON_SERVICE_ID, MCU_E_UNINIT, MCU_RESET_UNDEFINED );\r
437 \r
438   if( SIU.RSR.B.SSRS ) {\r
439         rv = MCU_SW_RESET;\r
440   } else if( SIU.RSR.B.WDRS ) {\r
441         rv = MCU_WATCHDOG_RESET;\r
442   } else if( SIU.RSR.B.PORS || SIU.RSR.B.ERS ) {\r
443         rv = MCU_POWER_ON_RESET;\r
444   } else {\r
445         rv = MCU_RESET_UNDEFINED;\r
446   }\r
447 \r
448   return rv;\r
449 }\r
450 \r
451 //-------------------------------------------------------------------\r
452 \r
453 Mcu_RawResetType Mcu_GetResetRawValue(void)\r
454 {\r
455   VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETRESETREASON_SERVICE_ID, MCU_E_UNINIT, MCU_GETRESETRAWVALUE_UNINIT_RV );\r
456 \r
457   if( !Mcu_Global.initRun ) {\r
458         return MCU_GETRESETRAWVALUE_UNINIT_RV;\r
459   }\r
460 \r
461   return SIU.RSR.R;\r
462 }\r
463 \r
464 //-------------------------------------------------------------------\r
465 \r
466 #if ( MCU_PERFORM_RESET_API == STD_ON )\r
467 void Mcu_PerformReset(void)\r
468 {\r
469   VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_PERFORMRESET_SERVICE_ID, MCU_E_UNINIT );\r
470 \r
471   // Reset\r
472         SIU.SRCR.B.SSR = 1;\r
473 \r
474 }\r
475 #endif\r
476 \r
477 //-------------------------------------------------------------------\r
478 \r
479 void Mcu_SetMode(const Mcu_ModeType McuMode)\r
480 {\r
481   VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_SETMODE_SERVICE_ID, MCU_E_UNINIT );\r
482  // VALIDATE( ( McuMode <= Mcu_Global.config->McuNumberOfMcuModes ), MCU_SETMODE_SERVICE_ID, MCU_E_PARAM_MODE );\r
483   (void) McuMode;\r
484 \r
485   /* NOT SUPPORTED */\r
486 }\r
487 \r
488 //-------------------------------------------------------------------\r
489 \r
490 /**\r
491  * Get the system clock in Hz. It calculates the clock from the\r
492  * different register settings in HW.\r
493  */\r
494 uint32_t McuE_GetSystemClock(void)\r
495 {\r
496   /*\r
497    * System clock calculation\r
498    *\r
499    * 5516 -  f_sys = extal * (emfd+16) / ( (eprediv+1) * ( erfd+1 ));\r
500    * 5567 -  f_sys = extal * (emfd+4) / ( (eprediv+1) * ( 2^erfd ));\r
501    * 563x -  We run in legacy mode = 5567\r
502    */\r
503 #if defined(CFG_MPC5516)\r
504   uint32_t eprediv = FMPLL.ESYNCR1.B.EPREDIV;\r
505   uint32_t emfd = FMPLL.ESYNCR1.B.EMFD;\r
506   uint32_t erfd = FMPLL.ESYNCR2.B.ERFD;\r
507 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567) || defined(CFG_MPC5633)\r
508   uint32_t eprediv = FMPLL.SYNCR.B.PREDIV;\r
509   uint32_t emfd = FMPLL.SYNCR.B.MFD;\r
510   uint32_t erfd = FMPLL.SYNCR.B.RFD;\r
511 #endif\r
512   uint32_t f_sys;\r
513   uint32  extal = Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting].McuClockReferencePointFrequency;\r
514 \r
515   f_sys =  CALC_SYSTEM_CLOCK(extal,emfd,eprediv,erfd);\r
516 \r
517   return f_sys;\r
518 }\r
519 \r
520 imask_t McuE_EnterCriticalSection()\r
521 {\r
522   uint32_t msr = get_msr();\r
523   Irq_Disable();\r
524   return msr;\r
525 }\r
526 \r
527 void McuE_ExitCriticalSection(uint32_t old_state)\r
528 {\r
529   set_msr(old_state);\r
530 }\r
531 \r
532 /**\r
533  * Get the peripheral clock in Hz for a specific device\r
534  */\r
535 \r
536 uint32_t McuE_GetPeripheralClock(McuE_PeriperalClock_t type)\r
537 {\r
538 #if defined(CFG_MPC5567)\r
539         // No peripheral dividers on 5567.\r
540         return McuE_GetSystemClock();\r
541 #else\r
542         uint32_t sysClock = McuE_GetSystemClock();\r
543         vuint32_t prescaler;\r
544 \r
545 \r
546   // See table 3.1, section 3.4.5 Peripheral Clock dividers\r
547         switch (type)\r
548         {\r
549         case PERIPHERAL_CLOCK_FLEXCAN_A:\r
550         case PERIPHERAL_CLOCK_DSPI_A:\r
551 #if defined(CFG_MPC5516)\r
552                 prescaler = SIU.SYSCLK.B.LPCLKDIV0;\r
553                 break;\r
554 #endif\r
555 \r
556         case PERIPHERAL_CLOCK_PIT:\r
557         case PERIPHERAL_CLOCK_ESCI_A:\r
558         case PERIPHERAL_CLOCK_IIC_A:\r
559 #if defined(CFG_MPC5516)\r
560         prescaler = SIU.SYSCLK.B.LPCLKDIV1;\r
561                 break;\r
562 #endif\r
563 \r
564         case PERIPHERAL_CLOCK_FLEXCAN_B:\r
565         case PERIPHERAL_CLOCK_FLEXCAN_C:\r
566         case PERIPHERAL_CLOCK_FLEXCAN_D:\r
567         case PERIPHERAL_CLOCK_FLEXCAN_E:\r
568         case PERIPHERAL_CLOCK_FLEXCAN_F:\r
569 #if defined(CFG_MPC5516)\r
570                 prescaler = SIU.SYSCLK.B.LPCLKDIV2;\r
571                 break;\r
572 #endif\r
573 \r
574         case PERIPHERAL_CLOCK_DSPI_B:\r
575         case PERIPHERAL_CLOCK_DSPI_C:\r
576         case PERIPHERAL_CLOCK_DSPI_D:\r
577 #if defined(CFG_MPC5516)\r
578                 prescaler = SIU.SYSCLK.B.LPCLKDIV3;\r
579                 break;\r
580 #endif\r
581 \r
582         case PERIPHERAL_CLOCK_ESCI_B:\r
583         case PERIPHERAL_CLOCK_ESCI_C:\r
584         case PERIPHERAL_CLOCK_ESCI_D:\r
585         case PERIPHERAL_CLOCK_ESCI_E:\r
586         case PERIPHERAL_CLOCK_ESCI_F:\r
587         case PERIPHERAL_CLOCK_ESCI_G:\r
588         case PERIPHERAL_CLOCK_ESCI_H:\r
589 #if defined(CFG_MPC5516)\r
590           prescaler = SIU.SYSCLK.B.LPCLKDIV4;\r
591           break;\r
592 #endif\r
593 \r
594         case PERIPHERAL_CLOCK_EMIOS:\r
595 #if defined(CFG_MPC5516)\r
596           prescaler = SIU.SYSCLK.B.LPCLKDIV5;\r
597           break;\r
598 #endif\r
599 \r
600         case PERIPHERAL_CLOCK_MLB:\r
601 #if defined(CFG_MPC5516)\r
602           prescaler = SIU.SYSCLK.B.LPCLKDIV6;\r
603           break;\r
604 #endif\r
605 \r
606         default:\r
607                 assert(0);\r
608                 break;\r
609         }\r
610 \r
611         return sysClock/(1<<prescaler);\r
612 #endif\r
613 }\r
614 \r
615 \r
616 /**\r
617  * Function to setup the internal flash for optimal performance\r
618  */\r
619 \r
620 static void Mcu_ConfigureFlash(void)\r
621 {\r
622   /* These flash settings increases the CPU performance of 7 times compared\r
623    to reset default settings!! */\r
624 \r
625 #if defined(CFG_MPC5516)\r
626   /* Disable pipelined reads when flash options are changed. */\r
627   FLASH.MCR.B.PRD = 1;\r
628 \r
629   /* Enable master prefetch for e200z1 and eDMA. */\r
630   FLASH.PFCRP0.B.M0PFE = 1;\r
631   FLASH.PFCRP0.B.M2PFE = 1;\r
632 \r
633   /* Address pipelining control. Must be set to the same value as RWSC. */\r
634   FLASH.PFCRP0.B.APC = 2;\r
635   FLASH.PFCRP0.B.RWSC = 2;\r
636 \r
637   /* Write wait states. */\r
638   FLASH.PFCRP0.B.WWSC = 1;\r
639 \r
640   /* Enable data prefetch. */\r
641   FLASH.PFCRP0.B.DPFEN = 1;\r
642 \r
643   /* Enable instruction prefetch. */\r
644   FLASH.PFCRP0.B.IPFEN = 1;\r
645 \r
646   /* Prefetch algorithm. */\r
647   /* TODO: Ask Freescale about this option. */\r
648   FLASH.PFCRP0.B.PFLIM = 2;\r
649 \r
650   /* Enable line read buffers. */\r
651   FLASH.PFCRP0.B.BFEN = 1;\r
652 \r
653   /* Enable pipelined reads again. */\r
654   FLASH.MCR.B.PRD = 0;\r
655 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
656   //TODO: Lägg till flash för mpc5554 &67\r
657 #endif\r
658 }\r
659 \r
660 void McuE_EnableInterrupts(void)\r
661 {\r
662   Irq_Enable();\r
663 }\r
664 \r
665 void McuE_DisableInterrupts(void)\r
666 {\r
667   Irq_Disable();\r
668 }\r