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