1 /* -------------------------------- Arctic Core ------------------------------
\r
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
\r
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
\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
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
14 * -------------------------------- Arctic Core ------------------------------*/
\r
19 #include "Std_Types.h"
\r
22 #if defined(USE_DEM)
\r
25 #include "mpc55xx.h"
\r
31 //#define USE_LDEBUG_PRINTF 1
\r
34 #define SYSCLOCK_SELECT_PLL 0x2
\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_MPC560X)
\r
40 #define CALC_SYSTEM_CLOCK(_extal,_emfd,_eprediv,_erfd) \
\r
41 ( (_extal)*(_emfd) / ((_eprediv+1)*(2<<(_erfd))) )
\r
43 #define CALC_SYSTEM_CLOCK(_extal,_emfd,_eprediv,_erfd) \
\r
44 ( (_extal) * ((_emfd)+16) / (((_eprediv)+1)*((_erfd)+1)) )
\r
47 typedef void (*vfunc_t)();
\r
49 /* Function declarations. */
\r
50 static void Mcu_ConfigureFlash(void);
\r
53 uint32 lossOfLockCnt;
\r
54 uint32 lossOfClockCnt;
\r
58 * Type that holds all global data for Mcu
\r
62 // Set if Mcu_Init() have been called
\r
65 const Mcu_ConfigType *config;
\r
66 Mcu_ClockType clockSetting;
\r
70 /* Development error macros. */
\r
71 #if ( MCU_DEV_ERROR_DETECT == STD_ON )
\r
72 #define VALIDATE(_exp,_api,_err ) \
\r
74 Det_ReportError(MODULE_ID_MCU,0,_api,_err); \
\r
78 #define VALIDATE_W_RV(_exp,_api,_err,_rv ) \
\r
80 Det_ReportError(MODULE_ID_MCU,0,_api,_err); \
\r
84 #define VALIDATE(_exp,_api,_err )
\r
85 #define VALIDATE_W_RV(_exp,_api,_err,_rv )
\r
89 Mcu_GlobalType Mcu_Global =
\r
92 .config = &McuConfigData[0],
\r
95 //-------------------------------------------------------------------
\r
97 void Mcu_LossOfLock( void ){
\r
98 #if defined(USE_DEM)
\r
99 Dem_ReportErrorStatus(MCU_E_CLOCK_FAILURE, DEM_EVENT_STATUS_FAILED);
\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
108 #if defined(CFG_MPC560X)
\r
111 Mcu_Global.stats.lossOfLockCnt++;
\r
113 FMPLL.SYNSR.B.LOLF = 1;
\r
117 //-------------------------------------------------------------------
\r
119 void Mcu_LossOfClock( void ){
\r
120 /* Should report MCU_E_CLOCK_FAILURE with DEM here */
\r
121 #if defined(CFG_MPC560X)
\r
124 Mcu_Global.stats.lossOfClockCnt++;
\r
126 FMPLL.SYNSR.B.LOCF = 1;
\r
130 #define SPR_PIR 286
\r
131 #define SPR_PVR 287
\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_E200Z65 0x81150000UL /* Is actually a 5668 */
\r
138 #define CORE_PVR_E200Z0H 0x817F0000UL
\r
150 const cpu_info_t cpu_info_list[] = {
\r
151 #if defined(CFG_MPC5516)
\r
154 .pvr = CORE_PVR_E200Z1,
\r
158 .pvr = CORE_PVR_E200Z0,
\r
160 #elif defined(CFG_MPC5567)
\r
163 .pvr = CORE_PVR_E200Z6,
\r
165 #elif defined(CFG_MPC5633)
\r
168 .pvr = CORE_PVR_E200Z3,
\r
170 #elif defined(CFG_MPC5604B)
\r
172 .name = "MPC5604B",
\r
173 .pvr = CORE_PVR_E200Z0H,
\r
175 #elif defined(CFG_MPC5606B)
\r
177 .name = "MPC5606B",
\r
178 .pvr = CORE_PVR_E200Z0H,
\r
180 #elif defined(CFG_MPC5606S)
\r
182 .name = "MPC5606S",
\r
183 .pvr = CORE_PVR_E200Z0H,
\r
185 #elif defined(CFG_MPC5668)
\r
188 .pvr = CORE_PVR_E200Z65,
\r
192 .pvr = CORE_PVR_E200Z0,
\r
197 const core_info_t core_info_list[] = {
\r
198 #if defined(CFG_MPC5516)
\r
200 .name = "CORE_E200Z1",
\r
201 .pvr = CORE_PVR_E200Z1,
\r
204 .name = "CORE_E200Z1",
\r
205 .pvr = CORE_PVR_E200Z1,
\r
207 #elif defined(CFG_MPC5567)
\r
209 .name = "CORE_E200Z6",
\r
210 .pvr = CORE_PVR_E200Z6,
\r
212 #elif defined(CFG_MPC5633)
\r
214 .name = "CORE_E200Z3",
\r
215 .pvr = CORE_PVR_E200Z3,
\r
217 #elif defined(CFG_MPC5604B)
\r
219 .name = "MPC5604B",
\r
220 .pvr = CORE_PVR_E200Z0H,
\r
222 #elif defined(CFG_MPC5606B)
\r
224 .name = "MPC5606B",
\r
225 .pvr = CORE_PVR_E200Z0H,
\r
227 #elif defined(CFG_MPC5606S)
\r
229 .name = "MPC5606S",
\r
230 .pvr = CORE_PVR_E200Z0H,
\r
232 #elif defined(CFG_MPC5668)
\r
234 .name = "CORE_E200Z65",
\r
235 .pvr = CORE_PVR_E200Z65,
\r
238 .name = "CORE_E200Z0",
\r
239 .pvr = CORE_PVR_E200Z1,
\r
245 #if !defined(ARRAY_SIZE)
\r
246 #define ARRAY_SIZE(_x) (sizeof(_x)/sizeof((_x)[0]))
\r
249 static const cpu_info_t *Mcu_IdentifyCpu(uint32 pvr)
\r
253 for (i = 0; i < ARRAY_SIZE(cpu_info_list); i++) {
\r
254 if (cpu_info_list[i].pvr == pvr) {
\r
255 return &cpu_info_list[i];
\r
262 static const core_info_t *Mcu_IdentifyCore(uint32 pvr)
\r
266 for (i = 0; i < ARRAY_SIZE(core_info_list); i++) {
\r
267 if (core_info_list[i].pvr == pvr) {
\r
268 return &core_info_list[i];
\r
275 static uint32 Mcu_CheckCpu( void ) {
\r
278 const cpu_info_t *cpuType;
\r
279 const core_info_t *coreType;
\r
281 // We have to registers to read here, PIR and PVR
\r
282 // pir = get_spr(SPR_PIR);
\r
283 pvr = get_spr(SPR_PVR);
\r
285 cpuType = Mcu_IdentifyCpu(pvr);
\r
286 coreType = Mcu_IdentifyCore(pvr);
\r
288 if( (cpuType == NULL) || (coreType == NULL) ) {
\r
293 //DEBUG(DEBUG_HIGH,"/drivers/mcu: Cpu: %s( 0x%08x )\n",cpuType->name,pvr);
\r
294 //DEBUG(DEBUG_HIGH,"/drivers/mcu: Core: %s( 0x%08x )\n",coreType->name,pvr);
\r
299 //-------------------------------------------------------------------
\r
301 void Mcu_Init(const Mcu_ConfigType *configPtr)
\r
303 VALIDATE( ( NULL != configPtr ), MCU_INIT_SERVICE_ID, MCU_E_PARAM_CONFIG );
\r
305 #if defined(CFG_MPC560X)
\r
306 /* Disable watchdog. Watchdog is enabled default after reset.*/
\r
307 SWT.SR.R = 0x0000c520; /* Write keys to clear soft lock bit */
\r
308 SWT.SR.R = 0x0000d928;
\r
309 SWT.CR.R = 0x8000010A; /* Disable watchdog */
\r
310 #if defined(USE_WDG)
\r
311 SWT.TO.R = 0xfa00; /* set the timout to 500ms */
\r
312 SWT.CR.R = 0x8000011B; /* enable watchdog */
\r
316 if( !SIMULATOR() ) {
\r
320 memset(&Mcu_Global.stats,0,sizeof(Mcu_Global.stats));
\r
323 Mcu_ConfigureFlash();
\r
325 Mcu_Global.config = configPtr;
\r
327 #if defined(CFG_MPC560X)
\r
328 /* Enable DRUN, RUN0, SAFE, RESET modes */
\r
329 ME.MER.R = 0x0000001D;
\r
332 Mcu_Global.initRun = 1;
\r
334 if( Mcu_Global.config->McuClockSrcFailureNotification == TRUE ) {
\r
335 #if defined(CFG_MPC560X)
\r
338 ISR_INSTALL_ISR1("LossOfLock", Mcu_LossOfLock, PLL_SYNSR_LOLF, 10 , 0 );
\r
339 #if defined(CFG_MPC5516) || defined(CFG_MPC5668)
\r
340 FMPLL.ESYNCR2.B.LOLIRQ = 1;
\r
341 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)
\r
342 FMPLL.SYNCR.B.LOLIRQ = 1;
\r
344 ISR_INSTALL_ISR1("LossOfClock", Mcu_LossOfClock, PLL_SYNSR_LOLF, 10 , 0 );
\r
345 #if defined(CFG_MPC5516) || defined(CFG_MPC5668)
\r
346 FMPLL.ESYNCR2.B.LOCIRQ = 1;
\r
347 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)
\r
348 FMPLL.SYNCR.B.LOCIRQ = 1;
\r
354 //-------------------------------------------------------------------
\r
358 Mcu_Global.initRun = FALSE; // Very simple Deinit. Should we do more?
\r
361 //-------------------------------------------------------------------
\r
363 Std_ReturnType Mcu_InitRamSection(const Mcu_RamSectionType RamSection)
\r
365 VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_INITRAMSECTION_SERVICE_ID, MCU_E_UNINIT, E_NOT_OK );
\r
366 VALIDATE_W_RV( ( RamSection <= Mcu_Global.config->McuRamSectors ), MCU_INITRAMSECTION_SERVICE_ID, MCU_E_PARAM_RAMSECTION, E_NOT_OK );
\r
368 /* NOT SUPPORTED, reason: no support for external RAM */
\r
373 //-------------------------------------------------------------------
\r
375 Std_ReturnType Mcu_InitClock(const Mcu_ClockType ClockSetting)
\r
377 Mcu_ClockSettingConfigType *clockSettingsPtr;
\r
378 VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_INITCLOCK_SERVICE_ID, MCU_E_UNINIT, E_NOT_OK );
\r
379 VALIDATE_W_RV( ( ClockSetting < Mcu_Global.config->McuClockSettings ), MCU_INITCLOCK_SERVICE_ID, MCU_E_PARAM_CLOCK, E_NOT_OK );
\r
381 Mcu_Global.clockSetting = ClockSetting;
\r
382 clockSettingsPtr = &Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting];
\r
384 // TODO: find out if the 5554 really works like the 5516 here
\r
385 // All three (16, 54, 67) used to run the same code here though, so i'm sticking it with 5516
\r
386 #if defined(CFG_MPC5516) || defined(CFG_MPC5554) || defined(CFG_MPC5668)
\r
388 * Fsys - System frequency ( CPU + all periperals? )
\r
390 * Fsys = EXTAL_FREQ *( (emfd+16) / ( (eprediv+1) * ( erfd+1 )) ) )
\r
393 assert((clockSettingsPtr->Pll2>=32) && (clockSettingsPtr->Pll2<=132));
\r
394 assert( (clockSettingsPtr->Pll1 != 6) &&
\r
395 (clockSettingsPtr->Pll1 != 8) &&
\r
396 (clockSettingsPtr->Pll1 < 10) );
\r
397 assert( clockSettingsPtr->Pll3 & 1); // Must be odd
\r
398 #elif defined(CFG_MPC5567)
\r
399 /* 5567 clock info:
\r
400 * Fsys = EXTAL_FREQ *( (emfd+4) / ( (eprediv+1) * ( 2^erfd )) ) )
\r
403 assert(clockSettingsPtr->Pll2 < 16);
\r
404 assert(clockSettingsPtr->Pll1 <= 4);
\r
405 assert(clockSettingsPtr->Pll3 < 8);
\r
408 #if defined(USE_LDEBUG_PRINTF)
\r
410 uint32 extal = Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting].McuClockReferencePointFrequency;
\r
413 f_sys = CALC_SYSTEM_CLOCK( extal,
\r
414 clockSettingsPtr->Pll2,
\r
415 clockSettingsPtr->Pll1,
\r
416 clockSettingsPtr->Pll3 );
\r
418 //DEBUG(DEBUG_HIGH,"/drivers/mcu: F_sys will be:%08d Hz\n",f_sys);
\r
422 #if defined(CFG_MPC5516) || defined(CFG_MPC5668)
\r
424 // set post divider to next valid value to ensure that an overshoot during lock phase
\r
425 // won't result in a too high freq
\r
426 FMPLL.ESYNCR2.B.ERFD = (clockSettingsPtr->Pll3 + 1) | 1;
\r
428 // External crystal PLL mode.
\r
429 FMPLL.ESYNCR1.B.CLKCFG = 7; //TODO: Hur ställa detta för 5567?
\r
431 // Write pll parameters.
\r
432 FMPLL.ESYNCR1.B.EPREDIV = clockSettingsPtr->Pll1;
\r
433 FMPLL.ESYNCR1.B.EMFD = clockSettingsPtr->Pll2;
\r
435 while(FMPLL.SYNSR.B.LOCK != 1) {};
\r
437 FMPLL.ESYNCR2.B.ERFD = clockSettingsPtr->Pll3;
\r
438 // Connect SYSCLK to FMPLL
\r
439 SIU.SYSCLK.B.SYSCLKSEL = SYSCLOCK_SELECT_PLL;
\r
440 #elif defined(CFG_MPC5604B) || defined(CFG_MPC5606B)
\r
441 // Write pll parameters.
\r
442 CGM.FMPLL_CR.B.IDF = clockSettingsPtr->Pll1;
\r
443 CGM.FMPLL_CR.B.NDIV = clockSettingsPtr->Pll2;
\r
444 CGM.FMPLL_CR.B.ODF = clockSettingsPtr->Pll3;
\r
446 /* RUN0 cfg: 16MHzIRCON,OSC0ON,PLL0ON,syclk=PLL0 */
\r
447 ME.RUN[0].R = 0x001F0074;
\r
448 /* Peri. Cfg. 1 settings: only run in RUN0 mode */
\r
449 ME.RUNPC[1].R = 0x00000010;
\r
450 /* MPC56xxB/S: select ME.RUNPC[1] */
\r
451 ME.PCTL[68].R = 0x01; //SIUL control
\r
452 ME.PCTL[91].R = 0x01; //RTC/API control
\r
453 ME.PCTL[92].R = 0x01; //PIT_RTI control
\r
454 ME.PCTL[72].R = 0x01; //eMIOS0 control
\r
455 ME.PCTL[73].R = 0x01; //eMIOS1 control
\r
456 ME.PCTL[16].R = 0x01; //FlexCAN0 control
\r
457 ME.PCTL[17].R = 0x01; //FlexCAN1 control
\r
458 ME.PCTL[4].R = 0x01; /* MPC56xxB/P/S DSPI0 */
\r
459 ME.PCTL[5].R = 0x01; /* MPC56xxB/P/S DSPI1: */
\r
460 ME.PCTL[32].R = 0x01; //ADC0 control
\r
461 #if defined(CFG_MPC5606B)
\r
462 ME.PCTL[33].R = 0x01; //ADC1 control
\r
464 ME.PCTL[23].R = 0x01; //DMAMUX control
\r
465 ME.PCTL[48].R = 0x01; /* MPC56xxB/P/S LINFlex */
\r
466 ME.PCTL[49].R = 0x01; /* MPC56xxB/P/S LINFlex */
\r
467 /* Mode Transition to enter RUN0 mode: */
\r
468 /* Enter RUN0 Mode & Key */
\r
469 ME.MCTL.R = 0x40005AF0;
\r
470 /* Enter RUN0 Mode & Inverted Key */
\r
471 ME.MCTL.R = 0x4000A50F;
\r
473 /* Wait for mode transition to complete */
\r
474 while (ME.GS.B.S_MTRANS) {}
\r
475 /* Verify RUN0 is the current mode */
\r
476 while(ME.GS.B.S_CURRENTMODE != 4) {}
\r
478 CGM.SC_DC[0].R = 0x80; /* MPC56xxB/S: Enable peri set 1 sysclk divided by 1 */
\r
479 CGM.SC_DC[1].R = 0x80; /* MPC56xxB/S: Enable peri set 2 sysclk divided by 1 */
\r
480 CGM.SC_DC[2].R = 0x80; /* MPC56xxB/S: Enable peri set 3 sysclk divided by 1 */
\r
482 SIU.PSMI[0].R = 0x01; /* CAN1RX on PCR43 */
\r
483 SIU.PSMI[6].R = 0x01; /* CS0/DSPI_0 on PCR15 */
\r
485 #elif defined(CFG_MPC5606S)
\r
486 // Write pll parameters.
\r
487 CGM.FMPLL[0].CR.B.IDF = clockSettingsPtr->Pll1;
\r
488 CGM.FMPLL[0].CR.B.NDIV = clockSettingsPtr->Pll2;
\r
489 CGM.FMPLL[0].CR.B.ODF = clockSettingsPtr->Pll3;
\r
491 /* RUN0 cfg: 16MHzIRCON,OSC0ON,PLL0ON,syclk=PLL0 */
\r
492 ME.RUN[0].R = 0x001F0074;
\r
493 /* Peri. Cfg. 1 settings: only run in RUN0 mode */
\r
494 ME.RUNPC[1].R = 0x00000010;
\r
495 /* MPC56xxB/S: select ME.RUNPC[1] */
\r
496 ME.PCTL[68].R = 0x01; //SIUL control
\r
497 ME.PCTL[91].R = 0x01; //RTC/API control
\r
498 ME.PCTL[92].R = 0x01; //PIT_RTI control
\r
499 ME.PCTL[72].R = 0x01; //eMIOS0 control
\r
500 ME.PCTL[73].R = 0x01; //eMIOS1 control
\r
501 ME.PCTL[16].R = 0x01; //FlexCAN0 control
\r
502 ME.PCTL[17].R = 0x01; //FlexCAN1 control
\r
503 ME.PCTL[4].R = 0x01; /* MPC56xxB/P/S DSPI0 */
\r
504 ME.PCTL[5].R = 0x01; /* MPC56xxB/P/S DSPI1: */
\r
505 ME.PCTL[32].R = 0x01; //ADC0 control
\r
506 ME.PCTL[23].R = 0x01; //DMAMUX control
\r
507 ME.PCTL[48].R = 0x01; /* MPC56xxB/P/S LINFlex */
\r
508 ME.PCTL[49].R = 0x01; /* MPC56xxB/P/S LINFlex */
\r
509 /* Mode Transition to enter RUN0 mode: */
\r
510 /* Enter RUN0 Mode & Key */
\r
511 ME.MCTL.R = 0x40005AF0;
\r
512 /* Enter RUN0 Mode & Inverted Key */
\r
513 ME.MCTL.R = 0x4000A50F;
\r
515 /* Wait for mode transition to complete */
\r
516 while (ME.GS.B.S_MTRANS) {}
\r
517 /* Verify RUN0 is the current mode */
\r
518 while(ME.GS.B.S_CURRENTMODE != 4) {}
\r
520 CGM.SC_DC[0].R = 0x80; /* MPC56xxB/S: Enable peri set 1 sysclk divided by 1 */
\r
521 CGM.SC_DC[1].R = 0x80; /* MPC56xxB/S: Enable peri set 2 sysclk divided by 1 */
\r
522 CGM.SC_DC[2].R = 0x80; /* MPC56xxB/S: Enable peri set 3 sysclk divided by 1 */
\r
524 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)
\r
525 // Partially following the steps in MPC5567 RM..
\r
526 FMPLL.SYNCR.B.DEPTH = 0;
\r
527 FMPLL.SYNCR.B.LOLRE = 0;
\r
528 FMPLL.SYNCR.B.LOLIRQ = 0;
\r
530 FMPLL.SYNCR.B.PREDIV = clockSettingsPtr->Pll1;
\r
531 FMPLL.SYNCR.B.MFD = clockSettingsPtr->Pll2;
\r
532 FMPLL.SYNCR.B.RFD = clockSettingsPtr->Pll3;
\r
534 // Wait for PLL to sync.
\r
535 while (Mcu_GetPllStatus() != MCU_PLL_LOCKED) ;
\r
537 FMPLL.SYNCR.B.LOLIRQ = 1;
\r
543 //-------------------------------------------------------------------
\r
545 void Mcu_DistributePllClock(void)
\r
547 VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_UNINIT );
\r
548 #if defined(CFG_MPC560XB)
\r
549 VALIDATE( ( CGM.FMPLL_CR.B.S_LOCK == 1 ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_PLL_NOT_LOCKED );
\r
550 #elif defined(CFG_MPC5606S)
\r
551 VALIDATE( ( CGM.FMPLL[0].CR.B.S_LOCK == 1 ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_PLL_NOT_LOCKED );
\r
553 VALIDATE( ( FMPLL.SYNSR.B.LOCK == 1 ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_PLL_NOT_LOCKED );
\r
555 /* NOT IMPLEMENTED due to pointless function on this hardware */
\r
559 //-------------------------------------------------------------------
\r
561 Mcu_PllStatusType Mcu_GetPllStatus(void)
\r
563 VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETPLLSTATUS_SERVICE_ID, MCU_E_UNINIT, MCU_PLL_STATUS_UNDEFINED );
\r
564 Mcu_PllStatusType rv;
\r
568 #if defined(CFG_MPC560XB)
\r
569 if ( !CGM.FMPLL_CR.B.S_LOCK )
\r
571 rv = MCU_PLL_UNLOCKED;
\r
574 rv = MCU_PLL_LOCKED;
\r
576 #elif defined(CFG_MPC5606S)
\r
577 if ( !CGM.FMPLL[0].CR.B.S_LOCK )
\r
579 rv = MCU_PLL_UNLOCKED;
\r
582 rv = MCU_PLL_LOCKED;
\r
585 if ( !FMPLL.SYNSR.B.LOCK )
\r
587 rv = MCU_PLL_UNLOCKED;
\r
590 rv = MCU_PLL_LOCKED;
\r
596 /* We are running on instruction set simulator. PLL is then always in sync... */
\r
597 rv = MCU_PLL_LOCKED;
\r
603 //-------------------------------------------------------------------
\r
605 Mcu_ResetType Mcu_GetResetReason(void)
\r
609 VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETRESETREASON_SERVICE_ID, MCU_E_UNINIT, MCU_RESET_UNDEFINED );
\r
611 #if defined(CFG_MPC560X)
\r
612 if( RGM.FES.B.F_SOFT ) {
\r
614 } else if( RGM.DES.B.F_SWT ) {
\r
615 rv = MCU_WATCHDOG_RESET;
\r
616 } else if( RGM.DES.B.F_POR ) {
\r
617 rv = MCU_POWER_ON_RESET;
\r
619 rv = MCU_RESET_UNDEFINED;
\r
622 if( SIU.RSR.B.SSRS ) {
\r
624 } else if( SIU.RSR.B.WDRS ) {
\r
625 rv = MCU_WATCHDOG_RESET;
\r
626 } else if( SIU.RSR.B.PORS || SIU.RSR.B.ERS ) {
\r
627 rv = MCU_POWER_ON_RESET;
\r
629 rv = MCU_RESET_UNDEFINED;
\r
636 //-------------------------------------------------------------------
\r
638 Mcu_RawResetType Mcu_GetResetRawValue(void)
\r
640 VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETRESETREASON_SERVICE_ID, MCU_E_UNINIT, MCU_GETRESETRAWVALUE_UNINIT_RV );
\r
642 if( !Mcu_Global.initRun ) {
\r
643 return MCU_GETRESETRAWVALUE_UNINIT_RV;
\r
646 #if defined(CFG_MPC560X)
\r
657 //-------------------------------------------------------------------
\r
659 #if ( MCU_PERFORM_RESET_API == STD_ON )
\r
660 void Mcu_PerformReset(void)
\r
662 VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_PERFORMRESET_SERVICE_ID, MCU_E_UNINIT );
\r
665 #if defined(CFG_MPC560X)
\r
666 ME.MCTL.R = 0x00005AF0;
\r
667 ME.MCTL.R = 0x0000A50F;
\r
669 while (ME.GS.B.S_MTRANS) {}
\r
670 while(ME.GS.B.S_CURRENTMODE != 0) {}
\r
672 SIU.SRCR.B.SSR = 1;
\r
678 //-------------------------------------------------------------------
\r
680 void Mcu_SetMode(const Mcu_ModeType McuMode)
\r
682 VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_SETMODE_SERVICE_ID, MCU_E_UNINIT );
\r
683 // VALIDATE( ( McuMode <= Mcu_Global.config->McuNumberOfMcuModes ), MCU_SETMODE_SERVICE_ID, MCU_E_PARAM_MODE );
\r
686 /* NOT SUPPORTED */
\r
689 //-------------------------------------------------------------------
\r
692 * Get the system clock in Hz. It calculates the clock from the
\r
693 * different register settings in HW.
\r
695 uint32_t McuE_GetSystemClock(void)
\r
698 * System clock calculation
\r
700 * 5516 - f_sys = extal * (emfd+16) / ( (eprediv+1) * ( erfd+1 ));
\r
701 * 5567 - f_sys = extal * (emfd+4) / ( (eprediv+1) * ( 2^erfd ));
\r
702 * 563x - We run in legacy mode = 5567
\r
703 * 5606s - f_sys = extal * emfd / ((eprediv+1)*(2<<(erfd)));
\r
705 #if defined(CFG_MPC5516) || defined(CFG_MPC5668)
\r
706 uint32_t eprediv = FMPLL.ESYNCR1.B.EPREDIV;
\r
707 uint32_t emfd = FMPLL.ESYNCR1.B.EMFD;
\r
708 uint32_t erfd = FMPLL.ESYNCR2.B.ERFD;
\r
709 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567) || defined(CFG_MPC5633)
\r
710 uint32_t eprediv = FMPLL.SYNCR.B.PREDIV;
\r
711 uint32_t emfd = FMPLL.SYNCR.B.MFD;
\r
712 uint32_t erfd = FMPLL.SYNCR.B.RFD;
\r
713 #elif defined(CFG_MPC560XB)
\r
714 uint32_t eprediv = CGM.FMPLL_CR.B.IDF;
\r
715 uint32_t emfd = CGM.FMPLL_CR.B.NDIV;
\r
716 uint32_t erfd = CGM.FMPLL_CR.B.ODF;
\r
717 #elif defined(CFG_MPC5606S)
\r
718 uint32_t eprediv = CGM.FMPLL[0].CR.B.IDF;
\r
719 uint32_t emfd = CGM.FMPLL[0].CR.B.NDIV;
\r
720 uint32_t erfd = CGM.FMPLL[0].CR.B.ODF;
\r
724 uint32 extal = Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting].McuClockReferencePointFrequency;
\r
726 f_sys = CALC_SYSTEM_CLOCK(extal,emfd,eprediv,erfd);
\r
731 #if defined(CFG_MPC5668)
\r
732 uint32_t McuE_GetPeripheralClock(McuE_PeriperalClock_t type) {
\r
733 uint32_t sysClock = McuE_GetSystemClock();
\r
734 vuint32_t prescaler;
\r
738 case PERIPHERAL_CLOCK_FLEXCAN_A:
\r
739 case PERIPHERAL_CLOCK_FLEXCAN_B:
\r
740 case PERIPHERAL_CLOCK_FLEXCAN_C:
\r
741 case PERIPHERAL_CLOCK_FLEXCAN_D:
\r
742 case PERIPHERAL_CLOCK_FLEXCAN_E:
\r
743 case PERIPHERAL_CLOCK_FLEXCAN_F:
\r
744 case PERIPHERAL_CLOCK_DSPI_A:
\r
745 case PERIPHERAL_CLOCK_DSPI_B:
\r
746 case PERIPHERAL_CLOCK_DSPI_C:
\r
747 case PERIPHERAL_CLOCK_DSPI_D:
\r
748 prescaler = SIU.SYSCLK.B.LPCLKDIV1;
\r
750 case PERIPHERAL_CLOCK_ESCI_A:
\r
751 case PERIPHERAL_CLOCK_ESCI_B:
\r
752 case PERIPHERAL_CLOCK_ESCI_C:
\r
753 case PERIPHERAL_CLOCK_ESCI_D:
\r
754 case PERIPHERAL_CLOCK_ESCI_E:
\r
755 case PERIPHERAL_CLOCK_ESCI_F:
\r
756 case PERIPHERAL_CLOCK_IIC_A:
\r
757 case PERIPHERAL_CLOCK_IIC_B:
\r
758 prescaler = SIU.SYSCLK.B.LPCLKDIV0;
\r
760 case PERIPHERAL_CLOCK_ADC_A:
\r
761 prescaler = SIU.SYSCLK.B.LPCLKDIV2;
\r
763 case PERIPHERAL_CLOCK_EMIOS:
\r
764 prescaler = SIU.SYSCLK.B.LPCLKDIV3;
\r
771 return sysClock/(1<<prescaler);
\r
778 * Get the peripheral clock in Hz for a specific device
\r
780 uint32_t McuE_GetPeripheralClock(McuE_PeriperalClock_t type)
\r
782 #if defined(CFG_MPC5567)
\r
783 // No peripheral dividers on 5567.
\r
784 return McuE_GetSystemClock();
\r
786 uint32_t sysClock = McuE_GetSystemClock();
\r
787 vuint32_t prescaler;
\r
789 // See table 3.1, section 3.4.5 Peripheral Clock dividers
\r
792 case PERIPHERAL_CLOCK_FLEXCAN_A:
\r
793 case PERIPHERAL_CLOCK_DSPI_A:
\r
794 #if defined(CFG_MPC5516)
\r
795 prescaler = SIU.SYSCLK.B.LPCLKDIV0;
\r
797 #elif defined(CFG_MPC560X)
\r
798 prescaler = CGM.SC_DC[1].B.DIV;
\r
802 case PERIPHERAL_CLOCK_PIT:
\r
803 case PERIPHERAL_CLOCK_ESCI_A:
\r
804 case PERIPHERAL_CLOCK_IIC_A:
\r
805 #if defined(CFG_MPC5516)
\r
806 prescaler = SIU.SYSCLK.B.LPCLKDIV1;
\r
810 case PERIPHERAL_CLOCK_FLEXCAN_B:
\r
811 case PERIPHERAL_CLOCK_FLEXCAN_C:
\r
812 case PERIPHERAL_CLOCK_FLEXCAN_D:
\r
813 case PERIPHERAL_CLOCK_FLEXCAN_E:
\r
814 case PERIPHERAL_CLOCK_FLEXCAN_F:
\r
815 #if defined(CFG_MPC5516)
\r
816 prescaler = SIU.SYSCLK.B.LPCLKDIV2;
\r
818 #elif defined(CFG_MPC560X)
\r
819 prescaler = CGM.SC_DC[1].B.DIV;
\r
823 case PERIPHERAL_CLOCK_DSPI_B:
\r
824 case PERIPHERAL_CLOCK_DSPI_C:
\r
825 case PERIPHERAL_CLOCK_DSPI_D:
\r
826 case PERIPHERAL_CLOCK_DSPI_E:
\r
827 case PERIPHERAL_CLOCK_DSPI_F:
\r
828 #if defined(CFG_MPC5516)
\r
829 prescaler = SIU.SYSCLK.B.LPCLKDIV3;
\r
833 case PERIPHERAL_CLOCK_ESCI_B:
\r
834 case PERIPHERAL_CLOCK_ESCI_C:
\r
835 case PERIPHERAL_CLOCK_ESCI_D:
\r
836 case PERIPHERAL_CLOCK_ESCI_E:
\r
837 case PERIPHERAL_CLOCK_ESCI_F:
\r
838 case PERIPHERAL_CLOCK_ESCI_G:
\r
839 case PERIPHERAL_CLOCK_ESCI_H:
\r
840 #if defined(CFG_MPC5516)
\r
841 prescaler = SIU.SYSCLK.B.LPCLKDIV4;
\r
845 #if defined(CFG_MPC560X)
\r
846 case PERIPHERAL_CLOCK_LIN_A:
\r
847 case PERIPHERAL_CLOCK_LIN_B:
\r
848 #if defined(CFG_MPC560XB)
\r
849 case PERIPHERAL_CLOCK_LIN_C:
\r
850 case PERIPHERAL_CLOCK_LIN_D:
\r
852 prescaler = CGM.SC_DC[0].B.DIV;
\r
854 case PERIPHERAL_CLOCK_EMIOS_0:
\r
855 prescaler = CGM.SC_DC[2].B.DIV;
\r
857 case PERIPHERAL_CLOCK_EMIOS_1:
\r
858 prescaler = CGM.SC_DC[2].B.DIV;
\r
861 case PERIPHERAL_CLOCK_EMIOS:
\r
862 #if defined(CFG_MPC5516)
\r
863 prescaler = SIU.SYSCLK.B.LPCLKDIV5;
\r
868 case PERIPHERAL_CLOCK_MLB:
\r
869 #if defined(CFG_MPC5516)
\r
870 prescaler = SIU.SYSCLK.B.LPCLKDIV6;
\r
879 return sysClock/(1<<prescaler);
\r
885 * Function to setup the internal flash for optimal performance
\r
888 static void Mcu_ConfigureFlash(void)
\r
890 /* These flash settings increases the CPU performance of 7 times compared
\r
891 to reset default settings!! */
\r
893 #if defined(CFG_MPC5516)
\r
894 /* Disable pipelined reads when flash options are changed. */
\r
895 FLASH.MCR.B.PRD = 1;
\r
897 /* Enable master prefetch for e200z1 and eDMA. */
\r
898 FLASH.PFCRP0.B.M0PFE = 1;
\r
899 FLASH.PFCRP0.B.M2PFE = 1;
\r
901 /* Address pipelining control. Must be set to the same value as RWSC. */
\r
902 FLASH.PFCRP0.B.APC = 2;
\r
903 FLASH.PFCRP0.B.RWSC = 2;
\r
905 /* Write wait states. */
\r
906 FLASH.PFCRP0.B.WWSC = 1;
\r
908 /* Enable data prefetch. */
\r
909 FLASH.PFCRP0.B.DPFEN = 1;
\r
911 /* Enable instruction prefetch. */
\r
912 FLASH.PFCRP0.B.IPFEN = 1;
\r
914 /* Prefetch algorithm. */
\r
915 /* TODO: Ask Freescale about this option. */
\r
916 FLASH.PFCRP0.B.PFLIM = 2;
\r
918 /* Enable line read buffers. */
\r
919 FLASH.PFCRP0.B.BFEN = 1;
\r
921 /* Enable pipelined reads again. */
\r
922 FLASH.MCR.B.PRD = 0;
\r
923 #elif defined(CFG_MPC5668)
\r
924 /* Check values from cookbook and MPC5668x Microcontroller Data Sheet */
\r
926 /* Should probably trim this values */
\r
927 const typeof(FLASH.PFCRP0.B) val = {.M0PFE = 1, .M2PFE=1, .APC=3,
\r
928 .RWSC=3, .WWSC =1, .DPFEN =1, .IPFEN = 1, .PFLIM =2,
\r
930 FLASH.PFCRP0.B = val;
\r
932 /* Enable pipelined reads again. */
\r
933 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)
\r
934 //TODO: Lägg till flash för mpc5554 &67
\r