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