]> rtime.felk.cvut.cz Git - arc.git/blobdiff - arch/ppc/mpc55xx/drivers/Mcu.c
Mcu ppc, fix for MCUs not supporting sleep mode.
[arc.git] / arch / ppc / mpc55xx / drivers / Mcu.c
index 86596adaecbf9667df07707db0a0a917d88290e0..eee6347ead943b9975f80e8398e99aab91daf518 100644 (file)
@@ -1,48 +1,49 @@
-/* -------------------------------- Arctic Core ------------------------------
- * Arctic Core - the open source AUTOSAR platform http://arccore.com
- *
- * Copyright (C) 2009  ArcCore AB <contact@arccore.com>
- *
- * This source code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by the
- * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- * -------------------------------- Arctic Core ------------------------------*/
-
-
-
-
-
-
-
-
+/* -------------------------------- Arctic Core ------------------------------\r
+ * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
+ *\r
+ * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
+ *\r
+ * This source code is free software; you can redistribute it and/or modify it\r
+ * under the terms of the GNU General Public License version 2 as published by the\r
+ * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
+ *\r
+ * This program is distributed in the hope that it will be useful, but\r
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
+ * for more details.\r
+ * -------------------------------- Arctic Core ------------------------------*/\r
+\r
+\r
 #include <assert.h>\r
 #include <string.h>\r
 #include "Std_Types.h"\r
 #include "Mcu.h"\r
-#include "Det.h"
-#if defined(USE_DEM)
-#include "Dem.h"
-#endif
+#include "Det.h"\r
+#if defined(USE_DEM)\r
+#include "Dem.h"\r
+#endif\r
 #include "mpc55xx.h"\r
 #include "Cpu.h"\r
 #include "Ramlog.h"\r
 #include "Os.h"\r
-#include "irq.h"\r
+#include "isr.h"\r
+\r
+//#define USE_LDEBUG_PRINTF 1\r
+#include "debug.h"\r
+\r
+#if defined(CFG_MPC5668) || defined(CFG_MPC5516)\r
+#define CFG_MCU_SUPPORT_SLEEP_MODE\r
+#endif\r
 \r
-//#define USE_TRACE 1\r
-//#define USE_DEBUG 1\r
-#include "Trace.h"\r
 \r
 #define SYSCLOCK_SELECT_PLL    0x2\r
 \r
 #if defined(CFG_MPC5567)\r
 #define CALC_SYSTEM_CLOCK(_extal,_emfd,_eprediv,_erfd)  \\r
             ( (_extal) * ((_emfd)+4) / (((_eprediv)+1)*(1<<(_erfd))) )\r
+#elif defined(CFG_MPC560X)\r
+#define CALC_SYSTEM_CLOCK(_extal,_emfd,_eprediv,_erfd)  \\r
+               ( (_extal)*(_emfd) / ((_eprediv+1)*(2<<(_erfd))) )\r
 #else\r
 #define CALC_SYSTEM_CLOCK(_extal,_emfd,_eprediv,_erfd)  \\r
             ( (_extal) * ((_emfd)+16) / (((_eprediv)+1)*((_erfd)+1)) )\r
@@ -53,8 +54,7 @@ typedef void (*vfunc_t)();
 /* Function declarations. */\r
 static void Mcu_ConfigureFlash(void);\r
 \r
-\r
-typedef struct {\r
+typedef struct{\r
        uint32 lossOfLockCnt;\r
        uint32 lossOfClockCnt;\r
 } Mcu_Stats;\r
@@ -64,16 +64,12 @@ typedef struct {
  */\r
 typedef struct\r
 {\r
-  // Set if Mcu_Init() have been called\r
-  boolean initRun;\r
-\r
-  // Our config\r
-  const Mcu_ConfigType *config;\r
-\r
-  Mcu_ClockType clockSetting;\r
-\r
-  Mcu_Stats stats;\r
-\r
+    // Set if Mcu_Init() have been called\r
+    boolean initRun;\r
+    // Our config\r
+    const Mcu_ConfigType *config;\r
+    Mcu_ClockType clockSetting;\r
+    Mcu_Stats stats;\r
 } Mcu_GlobalType;\r
 \r
 /* Development error macros. */\r
@@ -97,96 +93,155 @@ typedef struct
 // Global config\r
 Mcu_GlobalType Mcu_Global =\r
 {\r
-               .initRun = 0,\r
-               .config = &McuConfigData[0],\r
+       .initRun = 0,\r
+       .config = &McuConfigData[0],\r
 };\r
 \r
 //-------------------------------------------------------------------\r
 \r
-static void Mcu_LossOfLock( void  ) {\r
-#if defined(USE_DEM)
-       Dem_ReportErrorStatus(MCU_E_CLOCK_FAILURE, DEM_EVENT_STATUS_FAILED);
+void Mcu_LossOfLock( void  ){\r
+#if defined(USE_DEM)\r
+       Dem_ReportErrorStatus(MCU_E_CLOCK_FAILURE, DEM_EVENT_STATUS_FAILED);\r
 #endif\r
 \r
+  /*\r
+   * NOTE!!!\r
+   * This interrupt may be triggered more than expected.\r
+   * If you are going to use this interrupt, see [Freescale Device Errata MPC5510ACE, Rev. 10 APR 2009, errata ID: 6764].\r
+   *\r
+   */\r
+#if defined(CFG_MPC560X)\r
+       /*not support*/\r
+#else\r
        Mcu_Global.stats.lossOfLockCnt++;\r
        // Clear interrupt\r
        FMPLL.SYNSR.B.LOLF = 1;\r
-\r
+#endif\r
 }\r
 \r
 //-------------------------------------------------------------------\r
-static void Mcu_LossOfCLock( void  ) {\r
 \r
+void Mcu_LossOfClock( void  ){\r
        /* Should report MCU_E_CLOCK_FAILURE with DEM here */\r
-\r
+#if defined(CFG_MPC560X)\r
+       /*not support*/\r
+#else\r
        Mcu_Global.stats.lossOfClockCnt++;\r
        // Clear interrupt\r
        FMPLL.SYNSR.B.LOCF = 1;\r
+#endif\r
 }\r
 \r
-\r
 #define SPR_PIR 286\r
 #define SPR_PVR 287\r
 \r
 #define CORE_PVR_E200Z1        0x81440000UL\r
-#define CORE_PVR_E200Z0        0x81710000UL
+#define CORE_PVR_E200Z0        0x81710000UL\r
 #define CORE_PVR_E200Z3        0x81120000UL\r
 #define CORE_PVR_E200Z6        0x81170000UL\r
+#define CORE_PVR_E200Z65       0x81150000UL    /* Is actually a 5668 */\r
+#define CORE_PVR_E200Z0H       0x817F0000UL\r
 \r
-\r
-typedef struct {\r
-  char *name;\r
-  uint32 pvr;\r
+typedef struct{\r
+       char *name;\r
+       uint32 pvr;\r
 } core_info_t;\r
 \r
-typedef struct {\r
-  char *name;\r
-  uint32 pvr;\r
+typedef struct{\r
+       char *name;\r
+       uint32 pvr;\r
 } cpu_info_t;\r
 \r
-cpu_info_t cpu_info_list[] =\r
-{\r
+const cpu_info_t cpu_info_list[] = {\r
 #if defined(CFG_MPC5516)\r
     {\r
-    .name = "MPC5516",\r
-    .pvr = CORE_PVR_E200Z1,\r
+       .name = "MPC5516",\r
+       .pvr = CORE_PVR_E200Z1,\r
     },\r
     {\r
-    .name = "MPC5516",\r
-    .pvr = CORE_PVR_E200Z0,\r
-    },
+       .name = "MPC5516",\r
+       .pvr = CORE_PVR_E200Z0,\r
+    },\r
 #elif defined(CFG_MPC5567)\r
     {\r
-       .name = "MPC5567",\r
-       .pvr = CORE_PVR_E200Z6,\r
-    }
-#elif defined(CFG_MPC5633)
-    {
-    .name = "MPC563X",
-    .pvr = CORE_PVR_E200Z3,
-    },
+       .name = "MPC5567",\r
+       .pvr = CORE_PVR_E200Z6,\r
+    }\r
+#elif defined(CFG_MPC5633)\r
+    {\r
+       .name = "MPC563X",\r
+       .pvr = CORE_PVR_E200Z3,\r
+    },\r
+#elif defined(CFG_MPC5604B)\r
+    {\r
+       .name = "MPC5604B",\r
+       .pvr = CORE_PVR_E200Z0H,\r
+    },\r
+#elif defined(CFG_MPC5606B)\r
+    {\r
+       .name = "MPC5606B",\r
+       .pvr = CORE_PVR_E200Z0H,\r
+    },\r
+#elif defined(CFG_MPC5606S)\r
+    {\r
+       .name = "MPC5606S",\r
+       .pvr = CORE_PVR_E200Z0H,\r
+    },\r
+#elif defined(CFG_MPC5668)\r
+       {\r
+               .name = "MPC5668",\r
+               .pvr = CORE_PVR_E200Z65,\r
+       },\r
+       {\r
+               .name = "MPC5668",\r
+               .pvr = CORE_PVR_E200Z0,\r
+       },\r
 #endif\r
 };\r
 \r
-core_info_t core_info_list[] = {\r
+const core_info_t core_info_list[] = {\r
 #if defined(CFG_MPC5516)\r
        {\r
-    .name = "CORE_E200Z1",\r
-    .pvr = CORE_PVR_E200Z1,\r
+               .name = "CORE_E200Z1",\r
+               .pvr = CORE_PVR_E200Z1,\r
     },\r
     {\r
-    .name = "CORE_E200Z1",\r
-    .pvr = CORE_PVR_E200Z1,\r
+       .name = "CORE_E200Z1",\r
+       .pvr = CORE_PVR_E200Z1,\r
     },\r
 #elif defined(CFG_MPC5567)\r
     {\r
-       .name = "CORE_E200Z6",\r
-       .pvr = CORE_PVR_E200Z6,\r
-    }
-#elif defined(CFG_MPC5633)
-    {
-    .name = "CORE_E200Z3",
-    .pvr = CORE_PVR_E200Z3,
+       .name = "CORE_E200Z6",\r
+       .pvr = CORE_PVR_E200Z6,\r
+    }\r
+#elif defined(CFG_MPC5633)\r
+    {\r
+               .name = "CORE_E200Z3",\r
+               .pvr = CORE_PVR_E200Z3,\r
+    },\r
+#elif defined(CFG_MPC5604B)\r
+    {\r
+       .name = "MPC5604B",\r
+       .pvr = CORE_PVR_E200Z0H,\r
+    },\r
+#elif defined(CFG_MPC5606B)\r
+    {\r
+       .name = "MPC5606B",\r
+       .pvr = CORE_PVR_E200Z0H,\r
+    },\r
+#elif defined(CFG_MPC5606S)\r
+    {\r
+       .name = "MPC5606S",\r
+       .pvr = CORE_PVR_E200Z0H,\r
+    },\r
+#elif defined(CFG_MPC5668)\r
+    {\r
+       .name = "CORE_E200Z65",\r
+       .pvr = CORE_PVR_E200Z65,\r
+    },\r
+    {\r
+       .name = "CORE_E200Z0",\r
+       .pvr = CORE_PVR_E200Z1,\r
     },\r
 #endif\r
 };\r
@@ -196,208 +251,313 @@ core_info_t core_info_list[] = {
 #define ARRAY_SIZE(_x)  (sizeof(_x)/sizeof((_x)[0]))\r
 #endif\r
 \r
-static cpu_info_t *Mcu_IdentifyCpu(uint32 pvr)\r
+static const cpu_info_t *Mcu_IdentifyCpu(uint32 pvr)\r
 {\r
-  int i;\r
-  for (i = 0; i < ARRAY_SIZE(cpu_info_list); i++) {\r
-    if (cpu_info_list[i].pvr == pvr) {\r
-      return &cpu_info_list[i];\r
+    int i;\r
+\r
+    for (i = 0; i < ARRAY_SIZE(cpu_info_list); i++) {\r
+       if (cpu_info_list[i].pvr == pvr) {\r
+               return &cpu_info_list[i];\r
+        }\r
     }\r
-  }\r
 \r
-  return NULL;\r
+    return NULL;\r
 }\r
 \r
-static core_info_t *Mcu_IdentifyCore(uint32 pvr)\r
+static const core_info_t *Mcu_IdentifyCore(uint32 pvr)\r
 {\r
-  int i;\r
-  for (i = 0; i < ARRAY_SIZE(core_info_list); i++) {\r
-    if (core_info_list[i].pvr == pvr) {\r
-      return &core_info_list[i];\r
+       int i;\r
+\r
+       for (i = 0; i < ARRAY_SIZE(core_info_list); i++) {\r
+               if (core_info_list[i].pvr == pvr) {\r
+                       return &core_info_list[i];\r
+               }\r
     }\r
-  }\r
 \r
   return NULL;\r
 }\r
 \r
-\r
 static uint32 Mcu_CheckCpu( void ) {\r
+       uint32 pvr;\r
+       // uint32 pir;\r
+       const cpu_info_t *cpuType;\r
+       const core_info_t *coreType;\r
 \r
-  uint32 pvr;\r
-  uint32 pir;\r
-  cpu_info_t *cpuType;\r
-  core_info_t *coreType;\r
+    // We have to registers to read here, PIR and PVR\r
+    // pir = get_spr(SPR_PIR);\r
+    pvr = get_spr(SPR_PVR);\r
 \r
-  // We have to registers to read here, PIR and PVR\r
+    cpuType = Mcu_IdentifyCpu(pvr);\r
+    coreType = Mcu_IdentifyCore(pvr);\r
 \r
-  pir = get_spr(SPR_PIR);\r
-  pvr = get_spr(SPR_PVR);\r
-\r
-  cpuType = Mcu_IdentifyCpu(pvr);\r
-  coreType = Mcu_IdentifyCore(pvr);\r
-\r
-  if( (cpuType == NULL) || (coreType == NULL) ) {\r
-    // Just hang\r
-    while(1);\r
-  }\r
+    if( (cpuType == NULL) || (coreType == NULL) ) {\r
+       // Just hang\r
+       while(1) ;\r
+    }\r
 \r
-  //DEBUG(DEBUG_HIGH,"/drivers/mcu: Cpu:  %s( 0x%08x )\n",cpuType->name,pvr);\r
-  //DEBUG(DEBUG_HIGH,"/drivers/mcu: Core: %s( 0x%08x )\n",coreType->name,pvr);\r
+    //DEBUG(DEBUG_HIGH,"/drivers/mcu: Cpu:  %s( 0x%08x )\n",cpuType->name,pvr);\r
+    //DEBUG(DEBUG_HIGH,"/drivers/mcu: Core: %s( 0x%08x )\n",coreType->name,pvr);\r
 \r
-  return 0;\r
+    return 0;\r
 }\r
 \r
-\r
 //-------------------------------------------------------------------\r
 \r
 void Mcu_Init(const Mcu_ConfigType *configPtr)\r
 {\r
-  VALIDATE( ( NULL != configPtr ), MCU_INIT_SERVICE_ID, MCU_E_PARAM_CONFIG );\r
+       VALIDATE( ( NULL != configPtr ), MCU_INIT_SERVICE_ID, MCU_E_PARAM_CONFIG );\r
+\r
+#if defined(CFG_MPC560X)\r
+       /* Disable watchdog. Watchdog is enabled default after reset.*/\r
+       SWT.SR.R = 0x0000c520;     /* Write keys to clear soft lock bit */\r
+       SWT.SR.R = 0x0000d928;\r
+       SWT.CR.R = 0x8000010A;     /* Disable watchdog */\r
+#if defined(USE_WDG)\r
+       SWT.TO.R = 0xfa00;              /* set the timout to 500ms */\r
+       SWT.CR.R = 0x8000011B;      /* enable watchdog */\r
+#endif\r
+#endif\r
 \r
-  if( !SIMULATOR() ) {\r
-         Mcu_CheckCpu();\r
-  }\r
+    if( !SIMULATOR() ) {\r
+       Mcu_CheckCpu();\r
+    }\r
 \r
-  memset(&Mcu_Global.stats,0,sizeof(Mcu_Global.stats));\r
+    memset(&Mcu_Global.stats,0,sizeof(Mcu_Global.stats));\r
 \r
+    // Setup memories\r
+    Mcu_ConfigureFlash();\r
 \r
-  //\r
-  // Setup memories\r
-  //\r
-  Mcu_ConfigureFlash();\r
+    Mcu_Global.config = configPtr;\r
 \r
-  Mcu_Global.config = configPtr;\r
-  Mcu_Global.initRun = 1;\r
+#if defined(CFG_MPC560X)\r
+    /* Enable DRUN, RUN0, SAFE, RESET modes */\r
+    ME.MER.R = 0x0000001D;\r
+#endif\r
 \r
-  if( Mcu_Global.config->McuClockSrcFailureNotification == TRUE  ){\r
-       // Enable loss of lock interrupt\r
+    Mcu_Global.initRun = 1;\r
 \r
-       Irq_AttachIsr1(Mcu_LossOfLock, NULL, PLL_SYNSR_LOLF,10 );\r
-#if defined(CFG_MPC5516)\r
-//     FMPLL.SYNCR.B.LOCIRQ = 1; TODO: Kolla denna bortkommentering med Mårten.\r
-       FMPLL.ESYNCR2.B.LOLIRQ = 1;\r
+    if( Mcu_Global.config->McuClockSrcFailureNotification == TRUE  ) {\r
+#if defined(CFG_MPC560X)\r
+       /*not support*/\r
+#else\r
+       ISR_INSTALL_ISR1("LossOfLock", Mcu_LossOfLock, PLL_SYNSR_LOLF, 10 , 0 );\r
+#if defined(CFG_MPC5516)  || defined(CFG_MPC5668)\r
+       FMPLL.ESYNCR2.B.LOLIRQ = 1;\r
 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
-       FMPLL.SYNCR.B.LOLIRQ = 1;\r
+       FMPLL.SYNCR.B.LOLIRQ = 1;\r
 #endif\r
-       Irq_AttachIsr1(Mcu_LossOfCLock, NULL, PLL_SYNSR_LOCF,10 );\r
-#if defined(CFG_MPC5516)\r
-//     FMPLL.SYNCR.B.LOCIRQ = 1; TODO: Kolla denna bortkommentering med Mårten.\r
-       FMPLL.ESYNCR2.B.LOCIRQ = 1;\r
+       ISR_INSTALL_ISR1("LossOfClock", Mcu_LossOfClock, PLL_SYNSR_LOLF, 10 , 0 );\r
+#if defined(CFG_MPC5516) || defined(CFG_MPC5668)\r
+       FMPLL.ESYNCR2.B.LOCIRQ = 1;\r
 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
-       FMPLL.SYNCR.B.LOCIRQ = 1;\r
+       FMPLL.SYNCR.B.LOCIRQ = 1;\r
+#endif\r
 #endif\r
-  }\r
+    }\r
 }\r
+\r
 //-------------------------------------------------------------------\r
 \r
 void Mcu_DeInit()\r
 {\r
-  Mcu_Global.initRun = FALSE; // Very simple Deinit. Should we do more?\r
+       Mcu_Global.initRun = FALSE; // Very simple Deinit. Should we do more?\r
 }\r
 \r
 //-------------------------------------------------------------------\r
+\r
 Std_ReturnType Mcu_InitRamSection(const Mcu_RamSectionType RamSection)\r
 {\r
-  VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_INITRAMSECTION_SERVICE_ID, MCU_E_UNINIT, E_NOT_OK );\r
-  VALIDATE_W_RV( ( RamSection <= Mcu_Global.config->McuRamSectors ), MCU_INITRAMSECTION_SERVICE_ID, MCU_E_PARAM_RAMSECTION, E_NOT_OK );\r
+       VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_INITRAMSECTION_SERVICE_ID, MCU_E_UNINIT, E_NOT_OK );\r
+       VALIDATE_W_RV( ( RamSection <= Mcu_Global.config->McuRamSectors ), MCU_INITRAMSECTION_SERVICE_ID, MCU_E_PARAM_RAMSECTION, E_NOT_OK );\r
 \r
-  /* NOT SUPPORTED, reason: no support for external RAM */\r
+    /* NOT SUPPORTED, reason: no support for external RAM */\r
 \r
-  return E_OK;\r
+    return E_OK;\r
 }\r
 \r
-\r
-\r
 //-------------------------------------------------------------------\r
 \r
 Std_ReturnType Mcu_InitClock(const Mcu_ClockType ClockSetting)\r
 {\r
-  Mcu_ClockSettingConfigType *clockSettingsPtr;\r
-  VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_INITCLOCK_SERVICE_ID, MCU_E_UNINIT, E_NOT_OK );\r
-  VALIDATE_W_RV( ( ClockSetting < Mcu_Global.config->McuClockSettings ), MCU_INITCLOCK_SERVICE_ID, MCU_E_PARAM_CLOCK, E_NOT_OK );\r
-\r
-  Mcu_Global.clockSetting = ClockSetting;\r
-  clockSettingsPtr = &Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting];\r
-\r
-\r
-  // TODO: find out if the 5554 really works like the 5516 here\r
-  // All three (16, 54, 67) used to run the same code here though, so i'm sticking it with 5516\r
-#if defined(CFG_MPC5516) || defined(CFG_MPC5554)\r
-  /* 5516clock info:\r
-   * Fsys - System frequency ( CPU + all periperals? )\r
-   *\r
-   *  Fsys = EXTAL_FREQ *(  (emfd+16) / ( (eprediv+1) * ( erfd+1 )) ) )\r
-   */\r
-  // Check ranges...\r
-  assert((clockSettingsPtr->PllEmfd>=32) && (clockSettingsPtr->PllEmfd<=132));\r
-  assert( (clockSettingsPtr->PllEprediv!=6) &&\r
-          (clockSettingsPtr->PllEprediv!=8) &&\r
-          (clockSettingsPtr->PllEprediv<10) );\r
-  assert( clockSettingsPtr->PllErfd & 1); // Must be odd\r
+    Mcu_ClockSettingConfigType *clockSettingsPtr;\r
+    VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_INITCLOCK_SERVICE_ID, MCU_E_UNINIT, E_NOT_OK );\r
+    VALIDATE_W_RV( ( ClockSetting < Mcu_Global.config->McuClockSettings ), MCU_INITCLOCK_SERVICE_ID, MCU_E_PARAM_CLOCK, E_NOT_OK );\r
+\r
+    Mcu_Global.clockSetting = ClockSetting;\r
+    clockSettingsPtr = &Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting];\r
+\r
+    // TODO: find out if the 5554 really works like the 5516 here\r
+    // All three (16, 54, 67) used to run the same code here though, so i'm sticking it with 5516\r
+#if defined(CFG_MPC5516) || defined(CFG_MPC5554) || defined(CFG_MPC5668)\r
+    /* 5516clock info:\r
+     * Fsys - System frequency ( CPU + all periperals? )\r
+     *\r
+     *  Fsys = EXTAL_FREQ *(  (emfd+16) / ( (eprediv+1) * ( erfd+1 )) ) )\r
+     */\r
+    // Check ranges...\r
+    assert((clockSettingsPtr->Pll2>=32) && (clockSettingsPtr->Pll2<=132));\r
+    assert( (clockSettingsPtr->Pll1 != 6) &&\r
+            (clockSettingsPtr->Pll1 != 8) &&\r
+            (clockSettingsPtr->Pll1 < 10) );\r
+    assert( clockSettingsPtr->Pll3 & 1); // Must be odd\r
 #elif defined(CFG_MPC5567)\r
-  /* 5567 clock info:\r
-   *  Fsys = EXTAL_FREQ *(  (emfd+4) / ( (eprediv+1) * ( 2^erfd )) ) )\r
-   */\r
-  // Check ranges...\r
-  assert(clockSettingsPtr->PllEmfd < 16);\r
-  assert(clockSettingsPtr->PllEprediv <= 4);\r
-  assert(clockSettingsPtr->PllErfd < 8);\r
+    /* 5567 clock info:\r
+     *  Fsys = EXTAL_FREQ *(  (emfd+4) / ( (eprediv+1) * ( 2^erfd )) ) )\r
+     */\r
+    // Check ranges...\r
+    assert(clockSettingsPtr->Pll2 < 16);\r
+    assert(clockSettingsPtr->Pll1 <= 4);\r
+    assert(clockSettingsPtr->Pll3 < 8);\r
 #endif\r
 \r
+#if defined(USE_LDEBUG_PRINTF)\r
+    {\r
+       uint32  extal = Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting].McuClockReferencePointFrequency;\r
+       uint32  f_sys;\r
 \r
-#if defined(USE_DEBUG)\r
-  {\r
-    uint32    extal = Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting].McuClockReferencePoint;\r
-    uint32    f_sys;\r
-\r
-    f_sys = CALC_SYSTEM_CLOCK( extal,\r
-        clockSettingsPtr->PllEmfd,\r
-        clockSettingsPtr->PllEprediv,\r
-        clockSettingsPtr->PllErfd );\r
+       f_sys = CALC_SYSTEM_CLOCK( extal,\r
+               clockSettingsPtr->Pll2,\r
+               clockSettingsPtr->Pll1,\r
+               clockSettingsPtr->Pll3 );\r
 \r
-    //DEBUG(DEBUG_HIGH,"/drivers/mcu: F_sys will be:%08d Hz\n",f_sys);\r
-  }\r
+        //DEBUG(DEBUG_HIGH,"/drivers/mcu: F_sys will be:%08d Hz\n",f_sys);\r
+    }\r
 #endif\r
 \r
-#if defined(CFG_MPC5516)\r
-  // External crystal PLL mode.\r
-  FMPLL.ESYNCR1.B.CLKCFG = 7; //TODO: Hur ställa detta för 5567?\r
-\r
-  // Write pll parameters.\r
-  FMPLL.ESYNCR1.B.EPREDIV = clockSettingsPtr->PllEprediv;\r
-  FMPLL.ESYNCR1.B.EMFD    = clockSettingsPtr->PllEmfd;\r
-  FMPLL.ESYNCR2.B.ERFD    = clockSettingsPtr->PllErfd;\r
-\r
-  // Connect SYSCLK to FMPLL\r
-  SIU.SYSCLK.B.SYSCLKSEL = SYSCLOCK_SELECT_PLL;\r
-#elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
-  // Partially following the steps in MPC5567 RM..\r
-  FMPLL.SYNCR.B.DEPTH  = 0;\r
-  FMPLL.SYNCR.B.LOLRE  = 0;\r
-  FMPLL.SYNCR.B.LOLIRQ = 0;\r
-\r
-  FMPLL.SYNCR.B.PREDIV         = clockSettingsPtr->PllEprediv;\r
-  FMPLL.SYNCR.B.MFD            = clockSettingsPtr->PllEmfd;\r
-  FMPLL.SYNCR.B.RFD            = clockSettingsPtr->PllErfd;\r
+#if defined(CFG_MPC5516) || defined(CFG_MPC5668)\r
+\r
+    // set post divider to next valid value to ensure that an overshoot during lock phase\r
+    // won't result in a too high freq\r
+    FMPLL.ESYNCR2.B.ERFD = (clockSettingsPtr->Pll3 + 1) | 1;\r
+\r
+    // External crystal PLL mode.\r
+    FMPLL.ESYNCR1.B.CLKCFG = 7; //TODO: Hur ställa detta för 5567?\r
+\r
+    // Write pll parameters.\r
+    FMPLL.ESYNCR1.B.EPREDIV = clockSettingsPtr->Pll1;\r
+    FMPLL.ESYNCR1.B.EMFD    = clockSettingsPtr->Pll2;\r
+\r
+    while(FMPLL.SYNSR.B.LOCK != 1) {};\r
+\r
+    FMPLL.ESYNCR2.B.ERFD    = clockSettingsPtr->Pll3;\r
+    // Connect SYSCLK to FMPLL\r
+    SIU.SYSCLK.B.SYSCLKSEL = SYSCLOCK_SELECT_PLL;\r
+#elif defined(CFG_MPC5604B) || defined(CFG_MPC5606B)\r
+    // Write pll parameters.\r
+    CGM.FMPLL_CR.B.IDF = clockSettingsPtr->Pll1;\r
+    CGM.FMPLL_CR.B.NDIV = clockSettingsPtr->Pll2;\r
+    CGM.FMPLL_CR.B.ODF = clockSettingsPtr->Pll3;\r
+\r
+    /* RUN0 cfg: 16MHzIRCON,OSC0ON,PLL0ON,syclk=PLL0 */\r
+    ME.RUN[0].R = 0x001F0074;\r
+    /* Peri. Cfg. 1 settings: only run in RUN0 mode */\r
+    ME.RUNPC[1].R = 0x00000010;\r
+    /* MPC56xxB/S: select ME.RUNPC[1] */\r
+    ME.PCTL[68].R = 0x01; //SIUL control\r
+    ME.PCTL[91].R = 0x01; //RTC/API control\r
+    ME.PCTL[92].R = 0x01; //PIT_RTI control\r
+    ME.PCTL[72].R = 0x01; //eMIOS0 control\r
+    ME.PCTL[73].R = 0x01; //eMIOS1 control\r
+    ME.PCTL[16].R = 0x01; //FlexCAN0 control\r
+    ME.PCTL[17].R = 0x01; //FlexCAN1 control\r
+    ME.PCTL[4].R = 0x01;  /* MPC56xxB/P/S DSPI0  */\r
+    ME.PCTL[5].R = 0x01;  /* MPC56xxB/P/S DSPI1:  */\r
+    ME.PCTL[32].R = 0x01; //ADC0 control\r
+#if defined(CFG_MPC5606B)\r
+    ME.PCTL[33].R = 0x01; //ADC1 control\r
+#endif\r
+    ME.PCTL[23].R = 0x01; //DMAMUX control\r
+    ME.PCTL[48].R = 0x01; /* MPC56xxB/P/S LINFlex  */\r
+    ME.PCTL[49].R = 0x01; /* MPC56xxB/P/S LINFlex  */\r
+    /* Mode Transition to enter RUN0 mode: */\r
+    /* Enter RUN0 Mode & Key */\r
+    ME.MCTL.R = 0x40005AF0;\r
+    /* Enter RUN0 Mode & Inverted Key */\r
+    ME.MCTL.R = 0x4000A50F;\r
+\r
+    /* Wait for mode transition to complete */\r
+    while (ME.GS.B.S_MTRANS) {}\r
+    /* Verify RUN0 is the current mode */\r
+    while(ME.GS.B.S_CURRENTMODE != 4) {}\r
+\r
+    CGM.SC_DC[0].R = 0x80; /* MPC56xxB/S: Enable peri set 1 sysclk divided by 1 */\r
+    CGM.SC_DC[1].R = 0x80; /* MPC56xxB/S: Enable peri set 2 sysclk divided by 1 */\r
+    CGM.SC_DC[2].R = 0x80; /* MPC56xxB/S: Enable peri set 3 sysclk divided by 1 */\r
+\r
+    SIU.PSMI[0].R = 0x01; /* CAN1RX on PCR43 */\r
+    SIU.PSMI[6].R = 0x01; /* CS0/DSPI_0 on PCR15 */\r
+\r
+#elif defined(CFG_MPC5606S)\r
+    // Write pll parameters.\r
+    CGM.FMPLL[0].CR.B.IDF = clockSettingsPtr->Pll1;\r
+    CGM.FMPLL[0].CR.B.NDIV = clockSettingsPtr->Pll2;\r
+    CGM.FMPLL[0].CR.B.ODF = clockSettingsPtr->Pll3;\r
+\r
+    /* RUN0 cfg: 16MHzIRCON,OSC0ON,PLL0ON,syclk=PLL0 */\r
+    ME.RUN[0].R = 0x001F0074;\r
+    /* Peri. Cfg. 1 settings: only run in RUN0 mode */\r
+    ME.RUNPC[1].R = 0x00000010;\r
+    /* MPC56xxB/S: select ME.RUNPC[1] */\r
+    ME.PCTL[68].R = 0x01; //SIUL control\r
+    ME.PCTL[91].R = 0x01; //RTC/API control\r
+    ME.PCTL[92].R = 0x01; //PIT_RTI control\r
+    ME.PCTL[72].R = 0x01; //eMIOS0 control\r
+    ME.PCTL[73].R = 0x01; //eMIOS1 control\r
+    ME.PCTL[16].R = 0x01; //FlexCAN0 control\r
+    ME.PCTL[17].R = 0x01; //FlexCAN1 control\r
+    ME.PCTL[4].R = 0x01;  /* MPC56xxB/P/S DSPI0  */\r
+    ME.PCTL[5].R = 0x01;  /* MPC56xxB/P/S DSPI1:  */\r
+    ME.PCTL[32].R = 0x01; //ADC0 control\r
+    ME.PCTL[23].R = 0x01; //DMAMUX control\r
+    ME.PCTL[48].R = 0x01; /* MPC56xxB/P/S LINFlex  */\r
+    ME.PCTL[49].R = 0x01; /* MPC56xxB/P/S LINFlex  */\r
+    /* Mode Transition to enter RUN0 mode: */\r
+    /* Enter RUN0 Mode & Key */\r
+    ME.MCTL.R = 0x40005AF0;\r
+    /* Enter RUN0 Mode & Inverted Key */\r
+    ME.MCTL.R = 0x4000A50F;\r
+\r
+    /* Wait for mode transition to complete */\r
+    while (ME.GS.B.S_MTRANS) {}\r
+    /* Verify RUN0 is the current mode */\r
+    while(ME.GS.B.S_CURRENTMODE != 4) {}\r
+\r
+    CGM.SC_DC[0].R = 0x80; /* MPC56xxB/S: Enable peri set 1 sysclk divided by 1 */\r
+    CGM.SC_DC[1].R = 0x80; /* MPC56xxB/S: Enable peri set 2 sysclk divided by 1 */\r
+    CGM.SC_DC[2].R = 0x80; /* MPC56xxB/S: Enable peri set 3 sysclk divided by 1 */\r
+\r
+ #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
+    // Partially following the steps in MPC5567 RM..\r
+    FMPLL.SYNCR.B.DEPTH        = 0;\r
+    FMPLL.SYNCR.B.LOLRE        = 0;\r
+    FMPLL.SYNCR.B.LOLIRQ = 0;\r
+\r
+    FMPLL.SYNCR.B.PREDIV       = clockSettingsPtr->Pll1;\r
+    FMPLL.SYNCR.B.MFD          = clockSettingsPtr->Pll2;\r
+    FMPLL.SYNCR.B.RFD          = clockSettingsPtr->Pll3;\r
 \r
        // Wait for PLL to sync.\r
-  while (Mcu_GetPllStatus() != MCU_PLL_LOCKED)\r
-    ;\r
+    while (Mcu_GetPllStatus() != MCU_PLL_LOCKED) ;\r
 \r
-  FMPLL.SYNCR.B.LOLIRQ = 1;\r
+    FMPLL.SYNCR.B.LOLIRQ       = 1;\r
 #endif\r
 \r
-  return E_OK;\r
+    return E_OK;\r
 }\r
 \r
 //-------------------------------------------------------------------\r
 \r
 void Mcu_DistributePllClock(void)\r
 {\r
-  VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_UNINIT );\r
-  VALIDATE( ( FMPLL.SYNSR.B.LOCK == 1 ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_PLL_NOT_LOCKED );\r
-\r
-  /* NOT IMPLEMENTED due to pointless function on this hardware */\r
+    VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_UNINIT );\r
+#if defined(CFG_MPC560XB)\r
+    VALIDATE( ( CGM.FMPLL_CR.B.S_LOCK == 1 ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_PLL_NOT_LOCKED );\r
+#elif defined(CFG_MPC5606S)\r
+    VALIDATE( ( CGM.FMPLL[0].CR.B.S_LOCK == 1 ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_PLL_NOT_LOCKED );\r
+#else\r
+    VALIDATE( ( FMPLL.SYNSR.B.LOCK == 1 ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_PLL_NOT_LOCKED );\r
+#endif\r
+    /* NOT IMPLEMENTED due to pointless function on this hardware */\r
 \r
 }\r
 \r
@@ -405,24 +565,42 @@ void Mcu_DistributePllClock(void)
 \r
 Mcu_PllStatusType Mcu_GetPllStatus(void)\r
 {\r
-  VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETPLLSTATUS_SERVICE_ID, MCU_E_UNINIT, MCU_PLL_STATUS_UNDEFINED );\r
-  Mcu_PllStatusType rv;\r
+    VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETPLLSTATUS_SERVICE_ID, MCU_E_UNINIT, MCU_PLL_STATUS_UNDEFINED );\r
+    Mcu_PllStatusType rv;\r
 \r
-  if( !SIMULATOR() )\r
-  {\r
-    if ( !FMPLL.SYNSR.B.LOCK )\r
+    if( !SIMULATOR() )\r
     {\r
-      rv = MCU_PLL_UNLOCKED;\r
-    } else\r
+#if defined(CFG_MPC560XB)\r
+       if ( !CGM.FMPLL_CR.B.S_LOCK )\r
+       {\r
+               rv = MCU_PLL_UNLOCKED;\r
+       } else\r
+       {\r
+               rv = MCU_PLL_LOCKED;\r
+       }\r
+#elif defined(CFG_MPC5606S)\r
+       if ( !CGM.FMPLL[0].CR.B.S_LOCK )\r
+       {\r
+               rv = MCU_PLL_UNLOCKED;\r
+       } else\r
+       {\r
+               rv = MCU_PLL_LOCKED;\r
+       }\r
+#else\r
+       if ( !FMPLL.SYNSR.B.LOCK )\r
+       {\r
+               rv = MCU_PLL_UNLOCKED;\r
+       } else\r
+       {\r
+               rv = MCU_PLL_LOCKED;\r
+       }\r
+#endif\r
+    }\r
+    else\r
     {\r
-      rv = MCU_PLL_LOCKED;\r
+       /* We are running on instruction set simulator. PLL is then always in sync... */\r
+       rv = MCU_PLL_LOCKED;\r
     }\r
-  }\r
-  else\r
-  {\r
-    /* We are running on instruction set simulator. PLL is then always in sync... */\r
-    rv = MCU_PLL_LOCKED;\r
-  }\r
 \r
   return rv;\r
 }\r
@@ -433,32 +611,52 @@ Mcu_ResetType Mcu_GetResetReason(void)
 {\r
        Mcu_ResetType rv;\r
 \r
-  VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETRESETREASON_SERVICE_ID, MCU_E_UNINIT, MCU_RESET_UNDEFINED );\r
-\r
-  if( SIU.RSR.B.SSRS ) {\r
-       rv = MCU_SW_RESET;\r
-  } else if( SIU.RSR.B.WDRS ) {\r
-       rv = MCU_WATCHDOG_RESET;\r
-  } else if( SIU.RSR.B.PORS || SIU.RSR.B.ERS ) {\r
-       rv = MCU_POWER_ON_RESET;\r
-  } else {\r
-       rv = MCU_RESET_UNDEFINED;\r
-  }\r
+       VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETRESETREASON_SERVICE_ID, MCU_E_UNINIT, MCU_RESET_UNDEFINED );\r
+\r
+#if defined(CFG_MPC560X)\r
+       if( RGM.FES.B.F_SOFT ) {\r
+               rv = MCU_SW_RESET;\r
+       } else if( RGM.DES.B.F_SWT ) {\r
+               rv = MCU_WATCHDOG_RESET;\r
+       } else if( RGM.DES.B.F_POR ) {\r
+               rv = MCU_POWER_ON_RESET;\r
+       } else {\r
+               rv = MCU_RESET_UNDEFINED;\r
+       }\r
+#else\r
+       if( SIU.RSR.B.SSRS ) {\r
+               rv = MCU_SW_RESET;\r
+       } else if( SIU.RSR.B.WDRS ) {\r
+               rv = MCU_WATCHDOG_RESET;\r
+       } else if( SIU.RSR.B.PORS || SIU.RSR.B.ERS ) {\r
+               rv = MCU_POWER_ON_RESET;\r
+       } else {\r
+               rv = MCU_RESET_UNDEFINED;\r
+       }\r
+#endif\r
 \r
-  return rv;\r
+       return rv;\r
 }\r
 \r
 //-------------------------------------------------------------------\r
 \r
 Mcu_RawResetType Mcu_GetResetRawValue(void)\r
 {\r
-  VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETRESETREASON_SERVICE_ID, MCU_E_UNINIT, MCU_GETRESETRAWVALUE_UNINIT_RV );\r
+       VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETRESETREASON_SERVICE_ID, MCU_E_UNINIT, MCU_GETRESETRAWVALUE_UNINIT_RV );\r
 \r
-  if( !Mcu_Global.initRun ) {\r
-       return MCU_GETRESETRAWVALUE_UNINIT_RV;\r
-  }\r
+       if( !Mcu_Global.initRun ) {\r
+               return MCU_GETRESETRAWVALUE_UNINIT_RV;\r
+       }\r
+\r
+#if defined(CFG_MPC560X)\r
+       if( RGM.DES.R )\r
+               return RGM.DES.R;\r
+       else\r
+               return RGM.FES.R;\r
+#else\r
+       return SIU.RSR.R;\r
+#endif\r
 \r
-  return SIU.RSR.R;\r
 }\r
 \r
 //-------------------------------------------------------------------\r
@@ -466,23 +664,170 @@ Mcu_RawResetType Mcu_GetResetRawValue(void)
 #if ( MCU_PERFORM_RESET_API == STD_ON )\r
 void Mcu_PerformReset(void)\r
 {\r
-  VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_PERFORMRESET_SERVICE_ID, MCU_E_UNINIT );\r
+       VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_PERFORMRESET_SERVICE_ID, MCU_E_UNINIT );\r
+\r
+       // Reset\r
+#if defined(CFG_MPC560X)\r
+    ME.MCTL.R = 0x00005AF0;\r
+    ME.MCTL.R = 0x0000A50F;\r
 \r
-  // Reset\r
+    while (ME.GS.B.S_MTRANS) {}\r
+    while(ME.GS.B.S_CURRENTMODE != 0) {}\r
+#else\r
        SIU.SRCR.B.SSR = 1;\r
+#endif\r
 \r
 }\r
 #endif\r
 \r
 //-------------------------------------------------------------------\r
 \r
-void Mcu_SetMode(const Mcu_ModeType McuMode)\r
+/**\r
+ *\r
+ * Application Notes!\r
+ * - AN3584, "MPC5510 Family Low Power Features"\r
+ *   Since it's not complete also check MPC5668\r
+ * - AN4150 , "Using Sleep Mode on the MPC5668x" and it's code\r
+ *\r
+ *\r
+ * @param LPM\r
+ */\r
+static void enterLowPower (Mcu_ModeType mcuMode )\r
 {\r
-  VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_SETMODE_SERVICE_ID, MCU_E_UNINIT );\r
-  VALIDATE( ( McuMode <= Mcu_Global.config->McuNumberOfMcuModes ), MCU_SETMODE_SERVICE_ID, MCU_E_PARAM_MODE );\r
-  (void) McuMode;\r
+#if defined(CFG_MCU_SUPPORT_SLEEP_MODE)\r
+\r
+#if defined(CFG_MPC5668)\r
+       uint32 timeout;\r
+       /* Set the sleep bit; following a WAIT instruction, the device will go to sleep */\r
+       CRP.PSCR.B.SLEEP = 1;\r
+\r
+       /* 0x1 32k, 0x2 64k, 0x3 128k -- RAMs maintain power */\r
+       CRP.PSCR.B.RAMSEL = 0x3;                // Keep all 128K\r
 \r
-  /* NOT SUPPORTED */\r
+       CRP.Z6VEC.R = (uint32)&McuE_LowPowerRecoverFlash;\r
+#if defined(CFG_VLE)\r
+       CRP.Z6VEC.VLE = 1;\r
+#endif\r
+\r
+       /* If we "Mcu_Wakeup()" is located in RAM, set FASTREC */\r
+       CRP.RECPTR.B.FASTREC = 0;\r
+\r
+       /* Halt everything */\r
+    SIU.HLT0.R = 0x037FFF3D;\r
+    SIU.HLT1.R = 0x18000F3C;\r
+    while((SIU.HLTACK0.R != 0x037FFF3D) && (SIU.HLTACK1.R != 0x18000F3C) && (timeout<3000)){}\r
+\r
+       /* put Z0 in reset if not used for wakeup */\r
+       CRP.Z0VEC.B.Z0RST = 1;\r
+\r
+       // TODO: Enable_all_internal_pull_devices (PULL_DOWN);\r
+\r
+       /* Save context and execute wait instruction.\r
+        *\r
+        * Things that matter here are\r
+        * - Z1VEC, determines where TLB0 will point. TLB0 is written with a\r
+        *   value at startup that 4K aligned to this address.\r
+        * - LowPower_Sleep() will save a interrupt context so we will return\r
+        *   intact.\r
+        * - For devices with little RAM we don't want to impose the alignment\r
+        *   requirements there. Almost as we have to occupy a 4K block for this..\r
+        *   although the code does not take that much space.\r
+        * */\r
+       McuE_EnterLowPower(mcuMode);\r
+\r
+    /* Clear sleep flags to allow pads to operate */\r
+       CRP.PSCR.B.SLEEPF = 0x1;\r
+\r
+#elif defined(CFG_MPC5516)\r
+       uint32 timeout;\r
+       /* Set the sleep bit; following a WAIT instruction, the device will go to sleep */\r
+       CRP.PSCR.B.SLEEP = 1;\r
+       /* enable the 1.2V internal regulator when in sleep mode only */\r
+       CRP.PSCR.B.STOP12EN = 1;\r
+       /* 0x1 8k, 0x2 16k, 0x3 32k, 0x6 64k -- RAMs maintain power */\r
+       CRP.PSCR.B.RAMSEL = 0x7;                // Keep all 80K\r
+\r
+       CRP.Z1VEC.R = (uint32)&McuE_LowPowerRecoverFlash;\r
+#if defined(CFG_VLE)\r
+       CRP.VLE = 1;\r
+#endif\r
+\r
+       /* If we "Mcu_Wakeup()" is located in RAM, set FASTREC */\r
+       CRP.RECPRTR.B.FASTREC = 0;\r
+\r
+       /* Halt everything */\r
+       SIU.HLT.R = 0x3FFFFFFF;\r
+       while((SIU.HLTACK.R != 0x3FFFFFFF) && (timeout<3000)) {}\r
+\r
+       /* put Z0 in reset if not used for wakeup */\r
+       CRP.Z0VEC.B.Z0RST = 1;\r
+\r
+       // TODO: Enable_all_internal_pull_devices (PULL_DOWN);\r
+\r
+       /* Save context and execute wait instruction.\r
+        *\r
+        * Things that matter here are\r
+        * - Z1VEC, determines where TLB0 will point. TLB0 is written with a\r
+        *   value at startup that 4K aligned to this address.\r
+        * - LowPower_Sleep() will save a interrupt context so we will return\r
+        *   intact.\r
+        * - For devices with little RAM we don't want to impose the alignment\r
+        *   requirements there. Almost as we have to occupy a 4K block for this..\r
+        *   although the code does not take that much space.\r
+        * */\r
+       McuE_EnterLowPower(mcuMode);\r
+\r
+    /* Clear sleep flags to allow pads to operate */\r
+    CRP.PSCR.B.SLEEPF = 0x1;\r
+#else\r
+       /* NOT SUPPORTED */\r
+       (void) McuMode;\r
+#endif\r
+#endif\r
+}\r
+\r
+\r
+\r
+void Mcu_SetMode( Mcu_ModeType mcuMode)\r
+{\r
+\r
+       VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_SETMODE_SERVICE_ID, MCU_E_UNINIT );\r
+       // VALIDATE( ( McuMode <= Mcu_Global.config->McuNumberOfMcuModes ), MCU_SETMODE_SERVICE_ID, MCU_E_PARAM_MODE );\r
+#if defined(CFG_MCU_SUPPORT_SLEEP_MODE)\r
+\r
+#if defined(CFG_MPC5516) || defined(CFG_MPC5668)\r
+       if( MCU_MODE_RUN == mcuMode ) {\r
+\r
+       } else if( MCU_MODE_SLEEP == mcuMode ) {\r
+               /*\r
+                * Follows the AN3548 from Freescale\r
+                *\r
+                */\r
+#if defined(USE_DMA)\r
+               Dma_StopAll();\r
+#endif\r
+\r
+\r
+               /* Set system clock to 16Mhz IRC */\r
+               SIU.SYSCLK.B.SYSCLKSEL = 0;\r
+\r
+               /* Put flash in low-power mode */\r
+               // TODO\r
+\r
+               /* Put QQADC in low-power mode */\r
+               // TODO\r
+\r
+               /* Set us in SLEEP mode */\r
+               CRP.PSCR.B.SLEEP = 1;\r
+\r
+\r
+               enterLowPower(mcuMode);\r
+       }\r
+#else\r
+       /* NOT SUPPORTED */\r
+       (void) McuMode;\r
+#endif\r
+#endif\r
 }\r
 \r
 //-------------------------------------------------------------------\r
@@ -493,46 +838,89 @@ void Mcu_SetMode(const Mcu_ModeType McuMode)
  */\r
 uint32_t McuE_GetSystemClock(void)\r
 {\r
-  /*\r
-   * System clock calculation\r
-   *\r
-   * 5516 -  f_sys = extal * (emfd+16) / ( (eprediv+1) * ( erfd+1 ));\r
-   * 5567 -  f_sys = extal * (emfd+4) / ( (eprediv+1) * ( 2^erfd ));
-   * 563x -  We run in legacy mode = 5567
-   */\r
-#if defined(CFG_MPC5516)\r
-  uint32_t eprediv = FMPLL.ESYNCR1.B.EPREDIV;\r
-  uint32_t emfd = FMPLL.ESYNCR1.B.EMFD;\r
-  uint32_t erfd = FMPLL.ESYNCR2.B.ERFD;\r
+       /*\r
+        * System clock calculation\r
+        *\r
+        * 5516 -  f_sys = extal * (emfd+16) / ( (eprediv+1) * ( erfd+1 ));\r
+        * 5567 -  f_sys = extal * (emfd+4) / ( (eprediv+1) * ( 2^erfd ));\r
+        * 563x -  We run in legacy mode = 5567\r
+        * 5606s - f_sys = extal * emfd / ((eprediv+1)*(2<<(erfd)));\r
+        */\r
+#if defined(CFG_MPC5516) || defined(CFG_MPC5668)\r
+       uint32_t eprediv = FMPLL.ESYNCR1.B.EPREDIV;\r
+       uint32_t emfd = FMPLL.ESYNCR1.B.EMFD;\r
+       uint32_t erfd = FMPLL.ESYNCR2.B.ERFD;\r
 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567) || defined(CFG_MPC5633)\r
-  uint32_t eprediv = FMPLL.SYNCR.B.PREDIV;\r
-  uint32_t emfd = FMPLL.SYNCR.B.MFD;\r
-  uint32_t erfd = FMPLL.SYNCR.B.RFD;\r
+       uint32_t eprediv = FMPLL.SYNCR.B.PREDIV;\r
+       uint32_t emfd = FMPLL.SYNCR.B.MFD;\r
+       uint32_t erfd = FMPLL.SYNCR.B.RFD;\r
+#elif defined(CFG_MPC560XB)\r
+    uint32_t eprediv = CGM.FMPLL_CR.B.IDF;\r
+    uint32_t emfd = CGM.FMPLL_CR.B.NDIV;\r
+    uint32_t erfd = CGM.FMPLL_CR.B.ODF;\r
+#elif defined(CFG_MPC5606S)\r
+    uint32_t eprediv = CGM.FMPLL[0].CR.B.IDF;\r
+    uint32_t emfd = CGM.FMPLL[0].CR.B.NDIV;\r
+    uint32_t erfd = CGM.FMPLL[0].CR.B.ODF;\r
 #endif\r
-  uint32_t f_sys;\r
-  uint32  extal = Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting].McuClockReferencePoint;\r
 \r
-  f_sys =  CALC_SYSTEM_CLOCK(extal,emfd,eprediv,erfd);
+    uint32_t f_sys;\r
+    uint32  extal = Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting].McuClockReferencePointFrequency;\r
 \r
-  return f_sys;\r
-}\r
+    f_sys = CALC_SYSTEM_CLOCK(extal,emfd,eprediv,erfd);\r
 \r
-imask_t McuE_EnterCriticalSection()\r
-{\r
-  uint32_t msr = get_msr();\r
-  Irq_Disable();\r
-  return msr;\r
+    return f_sys;\r
 }\r
 \r
-void McuE_ExitCriticalSection(uint32_t old_state)\r
-{\r
-  set_msr(old_state);\r
+#if defined(CFG_MPC5668)\r
+uint32_t McuE_GetPeripheralClock(McuE_PeriperalClock_t type) {\r
+       uint32_t sysClock = McuE_GetSystemClock();\r
+       vuint32_t prescaler;\r
+\r
+       switch (type)\r
+       {\r
+               case PERIPHERAL_CLOCK_FLEXCAN_A:\r
+               case PERIPHERAL_CLOCK_FLEXCAN_B:\r
+               case PERIPHERAL_CLOCK_FLEXCAN_C:\r
+               case PERIPHERAL_CLOCK_FLEXCAN_D:\r
+               case PERIPHERAL_CLOCK_FLEXCAN_E:\r
+               case PERIPHERAL_CLOCK_FLEXCAN_F:\r
+               case PERIPHERAL_CLOCK_DSPI_A:\r
+               case PERIPHERAL_CLOCK_DSPI_B:\r
+               case PERIPHERAL_CLOCK_DSPI_C:\r
+               case PERIPHERAL_CLOCK_DSPI_D:\r
+                       prescaler = SIU.SYSCLK.B.LPCLKDIV1;\r
+                       break;\r
+               case PERIPHERAL_CLOCK_ESCI_A:\r
+               case PERIPHERAL_CLOCK_ESCI_B:\r
+               case PERIPHERAL_CLOCK_ESCI_C:\r
+               case PERIPHERAL_CLOCK_ESCI_D:\r
+               case PERIPHERAL_CLOCK_ESCI_E:\r
+               case PERIPHERAL_CLOCK_ESCI_F:\r
+               case PERIPHERAL_CLOCK_IIC_A:\r
+               case PERIPHERAL_CLOCK_IIC_B:\r
+                       prescaler = SIU.SYSCLK.B.LPCLKDIV0;\r
+                       break;\r
+               case PERIPHERAL_CLOCK_ADC_A:\r
+                       prescaler = SIU.SYSCLK.B.LPCLKDIV2;\r
+                       break;\r
+               case PERIPHERAL_CLOCK_EMIOS:\r
+                       prescaler = SIU.SYSCLK.B.LPCLKDIV3;\r
+                       break;\r
+               default:\r
+                       assert(0);\r
+                       break;\r
+       }\r
+\r
+       return sysClock/(1<<prescaler);\r
+\r
 }\r
 \r
+#else\r
+\r
 /**\r
  * Get the peripheral clock in Hz for a specific device\r
  */\r
-\r
 uint32_t McuE_GetPeripheralClock(McuE_PeriperalClock_t type)\r
 {\r
 #if defined(CFG_MPC5567)\r
@@ -542,76 +930,100 @@ uint32_t McuE_GetPeripheralClock(McuE_PeriperalClock_t type)
        uint32_t sysClock = McuE_GetSystemClock();\r
        vuint32_t prescaler;\r
 \r
-\r
   // See table 3.1, section 3.4.5 Peripheral Clock dividers\r
        switch (type)\r
        {\r
-       case PERIPHERAL_CLOCK_FLEXCAN_A:\r
-       case PERIPHERAL_CLOCK_DSPI_A:\r
+               case PERIPHERAL_CLOCK_FLEXCAN_A:\r
+               case PERIPHERAL_CLOCK_DSPI_A:\r
 #if defined(CFG_MPC5516)\r
-               prescaler = SIU.SYSCLK.B.LPCLKDIV0;\r
-               break;\r
+                       prescaler = SIU.SYSCLK.B.LPCLKDIV0;\r
+                       break;\r
+#elif defined(CFG_MPC560X)\r
+                       prescaler = CGM.SC_DC[1].B.DIV;\r
+                       break;\r
 #endif\r
 \r
-       case PERIPHERAL_CLOCK_PIT:\r
-       case PERIPHERAL_CLOCK_ESCI_A:\r
-       case PERIPHERAL_CLOCK_IIC_A:\r
+               case PERIPHERAL_CLOCK_PIT:\r
+               case PERIPHERAL_CLOCK_ESCI_A:\r
+               case PERIPHERAL_CLOCK_IIC_A:\r
 #if defined(CFG_MPC5516)\r
-       prescaler = SIU.SYSCLK.B.LPCLKDIV1;\r
-               break;\r
+                       prescaler = SIU.SYSCLK.B.LPCLKDIV1;\r
+                       break;\r
 #endif\r
 \r
-       case PERIPHERAL_CLOCK_FLEXCAN_B:\r
-       case PERIPHERAL_CLOCK_FLEXCAN_C:\r
-       case PERIPHERAL_CLOCK_FLEXCAN_D:\r
-       case PERIPHERAL_CLOCK_FLEXCAN_E:\r
-       case PERIPHERAL_CLOCK_FLEXCAN_F:\r
+               case PERIPHERAL_CLOCK_FLEXCAN_B:\r
+               case PERIPHERAL_CLOCK_FLEXCAN_C:\r
+               case PERIPHERAL_CLOCK_FLEXCAN_D:\r
+               case PERIPHERAL_CLOCK_FLEXCAN_E:\r
+               case PERIPHERAL_CLOCK_FLEXCAN_F:\r
 #if defined(CFG_MPC5516)\r
-               prescaler = SIU.SYSCLK.B.LPCLKDIV2;\r
-               break;\r
+                       prescaler = SIU.SYSCLK.B.LPCLKDIV2;\r
+                       break;\r
+#elif defined(CFG_MPC560X)\r
+                       prescaler = CGM.SC_DC[1].B.DIV;\r
+                       break;\r
 #endif\r
 \r
-       case PERIPHERAL_CLOCK_DSPI_B:\r
-       case PERIPHERAL_CLOCK_DSPI_C:\r
-       case PERIPHERAL_CLOCK_DSPI_D:\r
+               case PERIPHERAL_CLOCK_DSPI_B:\r
+               case PERIPHERAL_CLOCK_DSPI_C:\r
+               case PERIPHERAL_CLOCK_DSPI_D:\r
+               case PERIPHERAL_CLOCK_DSPI_E:\r
+               case PERIPHERAL_CLOCK_DSPI_F:\r
 #if defined(CFG_MPC5516)\r
                prescaler = SIU.SYSCLK.B.LPCLKDIV3;\r
-               break;\r
+                       break;\r
 #endif\r
 \r
-       case PERIPHERAL_CLOCK_ESCI_B:\r
-       case PERIPHERAL_CLOCK_ESCI_C:\r
-       case PERIPHERAL_CLOCK_ESCI_D:\r
-       case PERIPHERAL_CLOCK_ESCI_E:\r
-       case PERIPHERAL_CLOCK_ESCI_F:\r
-       case PERIPHERAL_CLOCK_ESCI_G:\r
-       case PERIPHERAL_CLOCK_ESCI_H:\r
+               case PERIPHERAL_CLOCK_ESCI_B:\r
+               case PERIPHERAL_CLOCK_ESCI_C:\r
+               case PERIPHERAL_CLOCK_ESCI_D:\r
+               case PERIPHERAL_CLOCK_ESCI_E:\r
+               case PERIPHERAL_CLOCK_ESCI_F:\r
+               case PERIPHERAL_CLOCK_ESCI_G:\r
+               case PERIPHERAL_CLOCK_ESCI_H:\r
 #if defined(CFG_MPC5516)\r
-         prescaler = SIU.SYSCLK.B.LPCLKDIV4;\r
-         break;\r
+                       prescaler = SIU.SYSCLK.B.LPCLKDIV4;\r
+                       break;\r
 #endif\r
 \r
-       case PERIPHERAL_CLOCK_EMIOS:\r
+#if defined(CFG_MPC560X)\r
+               case PERIPHERAL_CLOCK_LIN_A:\r
+               case PERIPHERAL_CLOCK_LIN_B:\r
+#if defined(CFG_MPC560XB)\r
+               case PERIPHERAL_CLOCK_LIN_C:\r
+               case PERIPHERAL_CLOCK_LIN_D:\r
+#endif\r
+                       prescaler = CGM.SC_DC[0].B.DIV;\r
+                       break;\r
+               case PERIPHERAL_CLOCK_EMIOS_0:\r
+                       prescaler = CGM.SC_DC[2].B.DIV;\r
+                       break;\r
+               case PERIPHERAL_CLOCK_EMIOS_1:\r
+                       prescaler = CGM.SC_DC[2].B.DIV;\r
+                       break;\r
+#else\r
+               case PERIPHERAL_CLOCK_EMIOS:\r
 #if defined(CFG_MPC5516)\r
-         prescaler = SIU.SYSCLK.B.LPCLKDIV5;\r
-         break;\r
+                       prescaler = SIU.SYSCLK.B.LPCLKDIV5;\r
+                       break;\r
+#endif\r
 #endif\r
 \r
-       case PERIPHERAL_CLOCK_MLB:\r
+               case PERIPHERAL_CLOCK_MLB:\r
 #if defined(CFG_MPC5516)\r
-         prescaler = SIU.SYSCLK.B.LPCLKDIV6;\r
-         break;\r
+                       prescaler = SIU.SYSCLK.B.LPCLKDIV6;\r
+                       break;\r
 #endif\r
 \r
-       default:\r
-               assert(0);\r
-               break;\r
+               default:\r
+                       assert(0);\r
+                       break;\r
        }\r
 \r
        return sysClock/(1<<prescaler);\r
 #endif\r
 }\r
-\r
+#endif\r
 \r
 /**\r
  * Function to setup the internal flash for optimal performance\r
@@ -619,50 +1031,51 @@ uint32_t McuE_GetPeripheralClock(McuE_PeriperalClock_t type)
 \r
 static void Mcu_ConfigureFlash(void)\r
 {\r
-  /* These flash settings increases the CPU performance of 7 times compared\r
-   to reset default settings!! */\r
+       /* These flash settings increases the CPU performance of 7 times compared\r
+          to reset default settings!! */\r
 \r
 #if defined(CFG_MPC5516)\r
-  /* Disable pipelined reads when flash options are changed. */\r
-  FLASH.MCR.B.PRD = 1;\r
+       /* Disable pipelined reads when flash options are changed. */\r
+       FLASH.MCR.B.PRD = 1;\r
+\r
+       /* Enable master prefetch for e200z1 and eDMA. */\r
+       FLASH.PFCRP0.B.M0PFE = 1;\r
+       FLASH.PFCRP0.B.M2PFE = 1;\r
+\r
+       /* Address pipelining control. Must be set to the same value as RWSC. */\r
+       FLASH.PFCRP0.B.APC = 2;\r
+       FLASH.PFCRP0.B.RWSC = 2;\r
 \r
-  /* Enable master prefetch for e200z1 and eDMA. */\r
-  FLASH.PFCRP0.B.M0PFE = 1;\r
-  FLASH.PFCRP0.B.M2PFE = 1;\r
+       /* Write wait states. */\r
+       FLASH.PFCRP0.B.WWSC = 1;\r
 \r
-  /* Address pipelining control. Must be set to the same value as RWSC. */\r
-  FLASH.PFCRP0.B.APC = 2;\r
-  FLASH.PFCRP0.B.RWSC = 2;\r
+       /* Enable data prefetch. */\r
+       FLASH.PFCRP0.B.DPFEN = 1;\r
 \r
-  /* Write wait states. */\r
-  FLASH.PFCRP0.B.WWSC = 1;\r
+       /* Enable instruction prefetch. */\r
+       FLASH.PFCRP0.B.IPFEN = 1;\r
 \r
-  /* Enable data prefetch. */\r
-  FLASH.PFCRP0.B.DPFEN = 1;\r
+       /* Prefetch algorithm. */\r
+       /* TODO: Ask Freescale about this option. */\r
+       FLASH.PFCRP0.B.PFLIM = 2;\r
 \r
-  /* Enable instruction prefetch. */\r
-  FLASH.PFCRP0.B.IPFEN = 1;\r
+       /* Enable line read buffers. */\r
+       FLASH.PFCRP0.B.BFEN = 1;\r
 \r
-  /* Prefetch algorithm. */\r
-  /* TODO: Ask Freescale about this option. */\r
-  FLASH.PFCRP0.B.PFLIM = 2;\r
+       /* Enable pipelined reads again. */\r
+       FLASH.MCR.B.PRD = 0;\r
+#elif defined(CFG_MPC5668)\r
+       /* Check values from cookbook and MPC5668x Microcontroller Data Sheet */\r
 \r
-  /* Enable line read buffers. */\r
-  FLASH.PFCRP0.B.BFEN = 1;\r
+       /* Should probably trim this values */\r
+       const typeof(FLASH.PFCRP0.B) val = {.M0PFE = 1, .M2PFE=1, .APC=3,\r
+                                                                .RWSC=3, .WWSC =1, .DPFEN =1, .IPFEN = 1, .PFLIM =2,\r
+                                                                .BFEN  = 1 };\r
+       FLASH.PFCRP0.B = val;\r
 \r
-  /* Enable pipelined reads again. */\r
-  FLASH.MCR.B.PRD = 0;\r
+       /* Enable pipelined reads again. */\r
 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
-  //TODO: Lägg till flash för mpc5554 &67\r
+       //TODO: Lägg till flash för mpc5554 &67\r
 #endif\r
 }\r
 \r
-void McuE_EnableInterrupts(void)\r
-{\r
-  Irq_Enable();\r
-}\r
-\r
-void McuE_DisableInterrupts(void)\r
-{\r
-  Irq_Disable();\r
-}\r