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