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