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