]> rtime.felk.cvut.cz Git - arc.git/blob - arch/ppc/mpc55xx/drivers/Mcu.c
Merged with dem-dev
[arc.git] / arch / ppc / mpc55xx / drivers / Mcu.c
1 /* -------------------------------- Arctic Core ------------------------------
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com
3  *
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>
5  *
6  * This source code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 as published by the
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * for more details.
14  * -------------------------------- Arctic Core ------------------------------*/
15
16
17
18
19
20
21
22
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"
28 #if defined(USE_DEM)
29 #include "Dem.h"
30 #endif
31 #include "mpc55xx.h"\r
32 #include "Cpu.h"\r
33 #include "Ramlog.h"\r
34 #include "Os.h"\r
35 #include "int_ctrl.h"\r
36 \r
37 //#define USE_TRACE 1\r
38 //#define USE_DEBUG 1\r
39 #include "Trace.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)
108         Dem_ReportErrorStatus(MCU_E_CLOCK_FAILURE, DEM_EVENT_STATUS_FAILED);
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
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     },
158 #elif defined(CFG_MPC5567)\r
159     {\r
160         .name = "MPC5567",\r
161         .pvr = CORE_PVR_E200Z6,\r
162     }
163 #elif defined(CFG_MPC5633)
164     {
165     .name = "MPC563X",
166     .pvr = CORE_PVR_E200Z3,
167     },
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     }
186 #elif defined(CFG_MPC5633)
187     {
188     .name = "CORE_E200Z3",
189     .pvr = CORE_PVR_E200Z3,
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   Irq_Enable();\r
270 \r
271   Mcu_Global.config = configPtr;\r
272   Mcu_Global.initRun = 1;\r
273 \r
274   if( Mcu_Global.config->McuClockSrcFailureNotification == TRUE  ){\r
275         // Enable loss of lock interrupt\r
276 \r
277         IntCtrl_AttachIsr1(Mcu_LossOfLock, NULL, PLL_SYNSR_LOLF,10 );\r
278 #if defined(CFG_MPC5516)\r
279 //      FMPLL.SYNCR.B.LOCIRQ = 1; TODO: Kolla denna bortkommentering med Mårten.\r
280         FMPLL.ESYNCR2.B.LOLIRQ = 1;\r
281 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
282         FMPLL.SYNCR.B.LOLIRQ = 1;\r
283 #endif\r
284         IntCtrl_AttachIsr1(Mcu_LossOfCLock, NULL, PLL_SYNSR_LOCF,10 );\r
285 #if defined(CFG_MPC5516)\r
286 //      FMPLL.SYNCR.B.LOCIRQ = 1; TODO: Kolla denna bortkommentering med Mårten.\r
287         FMPLL.ESYNCR2.B.LOCIRQ = 1;\r
288 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
289         FMPLL.SYNCR.B.LOCIRQ = 1;\r
290 #endif\r
291   }\r
292 }\r
293 //-------------------------------------------------------------------\r
294 \r
295 void Mcu_DeInit()\r
296 {\r
297   Mcu_Global.initRun = FALSE; // Very simple Deinit. Should we do more?\r
298 }\r
299 \r
300 //-------------------------------------------------------------------\r
301 Std_ReturnType Mcu_InitRamSection(const Mcu_RamSectionType RamSection)\r
302 {\r
303   VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_INITRAMSECTION_SERVICE_ID, MCU_E_UNINIT, E_NOT_OK );\r
304   VALIDATE_W_RV( ( RamSection <= Mcu_Global.config->McuRamSectors ), MCU_INITRAMSECTION_SERVICE_ID, MCU_E_PARAM_RAMSECTION, E_NOT_OK );\r
305 \r
306   /* NOT SUPPORTED, reason: no support for external RAM */\r
307 \r
308   return E_OK;\r
309 }\r
310 \r
311 \r
312 \r
313 //-------------------------------------------------------------------\r
314 \r
315 Std_ReturnType Mcu_InitClock(const Mcu_ClockType ClockSetting)\r
316 {\r
317   Mcu_ClockSettingConfigType *clockSettingsPtr;\r
318   VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_INITCLOCK_SERVICE_ID, MCU_E_UNINIT, E_NOT_OK );\r
319   VALIDATE_W_RV( ( ClockSetting < Mcu_Global.config->McuClockSettings ), MCU_INITCLOCK_SERVICE_ID, MCU_E_PARAM_CLOCK, E_NOT_OK );\r
320 \r
321   Mcu_Global.clockSetting = ClockSetting;\r
322   clockSettingsPtr = &Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting];\r
323 \r
324 \r
325   // TODO: find out if the 5554 really works like the 5516 here\r
326   // All three (16, 54, 67) used to run the same code here though, so i'm sticking it with 5516\r
327 #if defined(CFG_MPC5516) || defined(CFG_MPC5554)\r
328   /* 5516clock info:\r
329    * Fsys - System frequency ( CPU + all periperals? )\r
330    *\r
331    *  Fsys = EXTAL_FREQ *(  (emfd+16) / ( (eprediv+1) * ( erfd+1 )) ) )\r
332    */\r
333   // Check ranges...\r
334   assert((clockSettingsPtr->PllEmfd>=32) && (clockSettingsPtr->PllEmfd<=132));\r
335   assert( (clockSettingsPtr->PllEprediv!=6) &&\r
336           (clockSettingsPtr->PllEprediv!=8) &&\r
337           (clockSettingsPtr->PllEprediv<10) );\r
338   assert( clockSettingsPtr->PllErfd & 1); // Must be odd\r
339 #elif defined(CFG_MPC5567)\r
340   /* 5567 clock info:\r
341    *  Fsys = EXTAL_FREQ *(  (emfd+4) / ( (eprediv+1) * ( 2^erfd )) ) )\r
342    */\r
343   // Check ranges...\r
344   assert(clockSettingsPtr->PllEmfd < 16);\r
345   assert(clockSettingsPtr->PllEprediv <= 4);\r
346   assert(clockSettingsPtr->PllErfd < 8);\r
347 #endif\r
348 \r
349 \r
350 #if defined(USE_DEBUG)\r
351   {\r
352     uint32    extal = Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting].McuClockReferencePoint;\r
353     uint32    f_sys;\r
354 \r
355     f_sys = CALC_SYSTEM_CLOCK( extal,\r
356         clockSettingsPtr->PllEmfd,\r
357         clockSettingsPtr->PllEprediv,\r
358         clockSettingsPtr->PllErfd );\r
359 \r
360     //DEBUG(DEBUG_HIGH,"/drivers/mcu: F_sys will be:%08d Hz\n",f_sys);\r
361   }\r
362 #endif\r
363 \r
364 #if defined(CFG_MPC5516)\r
365   // External crystal PLL mode.\r
366   FMPLL.ESYNCR1.B.CLKCFG = 7; //TODO: Hur ställa detta för 5567?\r
367 \r
368   // Write pll parameters.\r
369   FMPLL.ESYNCR1.B.EPREDIV = clockSettingsPtr->PllEprediv;\r
370   FMPLL.ESYNCR1.B.EMFD    = clockSettingsPtr->PllEmfd;\r
371   FMPLL.ESYNCR2.B.ERFD    = clockSettingsPtr->PllErfd;\r
372 \r
373   // Connect SYSCLK to FMPLL\r
374   SIU.SYSCLK.B.SYSCLKSEL = SYSCLOCK_SELECT_PLL;\r
375 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
376   // Partially following the steps in MPC5567 RM..\r
377   FMPLL.SYNCR.B.DEPTH   = 0;\r
378   FMPLL.SYNCR.B.LOLRE   = 0;\r
379   FMPLL.SYNCR.B.LOLIRQ  = 0;\r
380 \r
381   FMPLL.SYNCR.B.PREDIV  = clockSettingsPtr->PllEprediv;\r
382   FMPLL.SYNCR.B.MFD             = clockSettingsPtr->PllEmfd;\r
383   FMPLL.SYNCR.B.RFD     = clockSettingsPtr->PllErfd;\r
384 \r
385         // Wait for PLL to sync.\r
386   while (Mcu_GetPllStatus() != MCU_PLL_LOCKED)\r
387     ;\r
388 \r
389   FMPLL.SYNCR.B.LOLIRQ  = 1;\r
390 #endif\r
391 \r
392   return E_OK;\r
393 }\r
394 \r
395 //-------------------------------------------------------------------\r
396 \r
397 void Mcu_DistributePllClock(void)\r
398 {\r
399   VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_UNINIT );\r
400   VALIDATE( ( FMPLL.SYNSR.B.LOCK == 1 ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_PLL_NOT_LOCKED );\r
401 \r
402   /* NOT IMPLEMENTED due to pointless function on this hardware */\r
403 \r
404 }\r
405 \r
406 //-------------------------------------------------------------------\r
407 \r
408 Mcu_PllStatusType Mcu_GetPllStatus(void)\r
409 {\r
410   VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETPLLSTATUS_SERVICE_ID, MCU_E_UNINIT, MCU_PLL_STATUS_UNDEFINED );\r
411   Mcu_PllStatusType rv;\r
412 \r
413   if( !SIMULATOR() )\r
414   {\r
415     if ( !FMPLL.SYNSR.B.LOCK )\r
416     {\r
417       rv = MCU_PLL_UNLOCKED;\r
418     } else\r
419     {\r
420       rv = MCU_PLL_LOCKED;\r
421     }\r
422   }\r
423   else\r
424   {\r
425     /* We are running on instruction set simulator. PLL is then always in sync... */\r
426     rv = MCU_PLL_LOCKED;\r
427   }\r
428 \r
429   return rv;\r
430 }\r
431 \r
432 //-------------------------------------------------------------------\r
433 \r
434 Mcu_ResetType Mcu_GetResetReason(void)\r
435 {\r
436         Mcu_ResetType rv;\r
437 \r
438   VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETRESETREASON_SERVICE_ID, MCU_E_UNINIT, MCU_RESET_UNDEFINED );\r
439 \r
440   if( SIU.RSR.B.SSRS ) {\r
441         rv = MCU_SW_RESET;\r
442   } else if( SIU.RSR.B.WDRS ) {\r
443         rv = MCU_WATCHDOG_RESET;\r
444   } else if( SIU.RSR.B.PORS || SIU.RSR.B.ERS ) {\r
445         rv = MCU_POWER_ON_RESET;\r
446   } else {\r
447         rv = MCU_RESET_UNDEFINED;\r
448   }\r
449 \r
450   return rv;\r
451 }\r
452 \r
453 //-------------------------------------------------------------------\r
454 \r
455 Mcu_RawResetType Mcu_GetResetRawValue(void)\r
456 {\r
457   VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETRESETREASON_SERVICE_ID, MCU_E_UNINIT, MCU_GETRESETRAWVALUE_UNINIT_RV );\r
458 \r
459   if( !Mcu_Global.initRun ) {\r
460         return MCU_GETRESETRAWVALUE_UNINIT_RV;\r
461   }\r
462 \r
463   return SIU.RSR.R;\r
464 }\r
465 \r
466 //-------------------------------------------------------------------\r
467 \r
468 #if ( MCU_PERFORM_RESET_API == STD_ON )\r
469 void Mcu_PerformReset(void)\r
470 {\r
471   VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_PERFORMRESET_SERVICE_ID, MCU_E_UNINIT );\r
472 \r
473   // Reset\r
474         SIU.SRCR.B.SSR = 1;\r
475 \r
476 }\r
477 #endif\r
478 \r
479 //-------------------------------------------------------------------\r
480 \r
481 void Mcu_SetMode(const Mcu_ModeType McuMode)\r
482 {\r
483   VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_SETMODE_SERVICE_ID, MCU_E_UNINIT );\r
484   VALIDATE( ( McuMode <= Mcu_Global.config->McuNumberOfMcuModes ), MCU_SETMODE_SERVICE_ID, MCU_E_PARAM_MODE );\r
485   (void) McuMode;\r
486 \r
487   /* NOT SUPPORTED */\r
488 }\r
489 \r
490 //-------------------------------------------------------------------\r
491 \r
492 /**\r
493  * Get the system clock in Hz. It calculates the clock from the\r
494  * different register settings in HW.\r
495  */\r
496 uint32_t McuE_GetSystemClock(void)\r
497 {\r
498   /*\r
499    * System clock calculation\r
500    *\r
501    * 5516 -  f_sys = extal * (emfd+16) / ( (eprediv+1) * ( erfd+1 ));\r
502    * 5567 -  f_sys = extal * (emfd+4) / ( (eprediv+1) * ( 2^erfd ));
503    * 563x -  We run in legacy mode = 5567
504    */\r
505 #if defined(CFG_MPC5516)\r
506   uint32_t eprediv = FMPLL.ESYNCR1.B.EPREDIV;\r
507   uint32_t emfd = FMPLL.ESYNCR1.B.EMFD;\r
508   uint32_t erfd = FMPLL.ESYNCR2.B.ERFD;\r
509 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567) || defined(CFG_MPC5633)\r
510   uint32_t eprediv = FMPLL.SYNCR.B.PREDIV;\r
511   uint32_t emfd = FMPLL.SYNCR.B.MFD;\r
512   uint32_t erfd = FMPLL.SYNCR.B.RFD;\r
513 #endif\r
514   uint32_t f_sys;\r
515   uint32  extal = Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting].McuClockReferencePoint;\r
516 \r
517   f_sys =  CALC_SYSTEM_CLOCK(extal,emfd,eprediv,erfd);
518 \r
519   return f_sys;\r
520 }\r
521 \r
522 imask_t McuE_EnterCriticalSection()\r
523 {\r
524   uint32_t msr = get_msr();\r
525   Irq_Disable();\r
526   return msr;\r
527 }\r
528 \r
529 void McuE_ExitCriticalSection(uint32_t old_state)\r
530 {\r
531   set_msr(old_state);\r
532 }\r
533 \r
534 /**\r
535  * Get the peripheral clock in Hz for a specific device\r
536  */\r
537 \r
538 uint32_t McuE_GetPeripheralClock(McuE_PeriperalClock_t type)\r
539 {\r
540 #if defined(CFG_MPC5567)\r
541         // No peripheral dividers on 5567.\r
542         return McuE_GetSystemClock();\r
543 #else\r
544         uint32_t sysClock = McuE_GetSystemClock();\r
545         vuint32_t prescaler;\r
546 \r
547 \r
548   // See table 3.1, section 3.4.5 Peripheral Clock dividers\r
549         switch (type)\r
550         {\r
551         case PERIPHERAL_CLOCK_FLEXCAN_A:\r
552         case PERIPHERAL_CLOCK_DSPI_A:\r
553 #if defined(CFG_MPC5516)\r
554                 prescaler = SIU.SYSCLK.B.LPCLKDIV0;\r
555                 break;\r
556 #endif\r
557 \r
558         case PERIPHERAL_CLOCK_PIT:\r
559         case PERIPHERAL_CLOCK_ESCI_A:\r
560         case PERIPHERAL_CLOCK_IIC_A:\r
561 #if defined(CFG_MPC5516)\r
562         prescaler = SIU.SYSCLK.B.LPCLKDIV1;\r
563                 break;\r
564 #endif\r
565 \r
566         case PERIPHERAL_CLOCK_FLEXCAN_B:\r
567         case PERIPHERAL_CLOCK_FLEXCAN_C:\r
568         case PERIPHERAL_CLOCK_FLEXCAN_D:\r
569         case PERIPHERAL_CLOCK_FLEXCAN_E:\r
570         case PERIPHERAL_CLOCK_FLEXCAN_F:\r
571 #if defined(CFG_MPC5516)\r
572                 prescaler = SIU.SYSCLK.B.LPCLKDIV2;\r
573                 break;\r
574 #endif\r
575 \r
576         case PERIPHERAL_CLOCK_DSPI_B:\r
577         case PERIPHERAL_CLOCK_DSPI_C:\r
578         case PERIPHERAL_CLOCK_DSPI_D:\r
579 #if defined(CFG_MPC5516)\r
580                 prescaler = SIU.SYSCLK.B.LPCLKDIV3;\r
581                 break;\r
582 #endif\r
583 \r
584         case PERIPHERAL_CLOCK_ESCI_B:\r
585         case PERIPHERAL_CLOCK_ESCI_C:\r
586         case PERIPHERAL_CLOCK_ESCI_D:\r
587         case PERIPHERAL_CLOCK_ESCI_E:\r
588         case PERIPHERAL_CLOCK_ESCI_F:\r
589         case PERIPHERAL_CLOCK_ESCI_G:\r
590         case PERIPHERAL_CLOCK_ESCI_H:\r
591 #if defined(CFG_MPC5516)\r
592           prescaler = SIU.SYSCLK.B.LPCLKDIV4;\r
593           break;\r
594 #endif\r
595 \r
596         case PERIPHERAL_CLOCK_EMIOS:\r
597 #if defined(CFG_MPC5516)\r
598           prescaler = SIU.SYSCLK.B.LPCLKDIV5;\r
599           break;\r
600 #endif\r
601 \r
602         case PERIPHERAL_CLOCK_MLB:\r
603 #if defined(CFG_MPC5516)\r
604           prescaler = SIU.SYSCLK.B.LPCLKDIV6;\r
605           break;\r
606 #endif\r
607 \r
608         default:\r
609                 assert(0);\r
610                 break;\r
611         }\r
612 \r
613         return sysClock/(1<<prescaler);\r
614 #endif\r
615 }\r
616 \r
617 \r
618 /**\r
619  * Function to setup the internal flash for optimal performance\r
620  */\r
621 \r
622 static void Mcu_ConfigureFlash(void)\r
623 {\r
624   /* These flash settings increases the CPU performance of 7 times compared\r
625    to reset default settings!! */\r
626 \r
627 #if defined(CFG_MPC5516)\r
628   /* Disable pipelined reads when flash options are changed. */\r
629   FLASH.MCR.B.PRD = 1;\r
630 \r
631   /* Enable master prefetch for e200z1 and eDMA. */\r
632   FLASH.PFCRP0.B.M0PFE = 1;\r
633   FLASH.PFCRP0.B.M2PFE = 1;\r
634 \r
635   /* Address pipelining control. Must be set to the same value as RWSC. */\r
636   FLASH.PFCRP0.B.APC = 2;\r
637   FLASH.PFCRP0.B.RWSC = 2;\r
638 \r
639   /* Write wait states. */\r
640   FLASH.PFCRP0.B.WWSC = 1;\r
641 \r
642   /* Enable data prefetch. */\r
643   FLASH.PFCRP0.B.DPFEN = 1;\r
644 \r
645   /* Enable instruction prefetch. */\r
646   FLASH.PFCRP0.B.IPFEN = 1;\r
647 \r
648   /* Prefetch algorithm. */\r
649   /* TODO: Ask Freescale about this option. */\r
650   FLASH.PFCRP0.B.PFLIM = 2;\r
651 \r
652   /* Enable line read buffers. */\r
653   FLASH.PFCRP0.B.BFEN = 1;\r
654 \r
655   /* Enable pipelined reads again. */\r
656   FLASH.MCR.B.PRD = 0;\r
657 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
658   //TODO: Lägg till flash för mpc5554 &67\r
659 #endif\r
660 }\r
661 \r
662 void McuE_EnableInterrupts(void)\r
663 {\r
664   Irq_Enable();\r
665 }\r
666 \r
667 void McuE_DisableInterrupts(void)\r
668 {\r
669   Irq_Disable();\r
670 }\r