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