]> rtime.felk.cvut.cz Git - arc.git/blobdiff - arch/ppc/mpc55xx/drivers/Pwm.c
merged second mahi-applications head
[arc.git] / arch / ppc / mpc55xx / drivers / Pwm.c
index 532b4aff5793453eae01b85c954fa4a5bf7de77e..9604ee57f320cfd21481d4966872c3f09afda3fe 100644 (file)
@@ -43,6 +43,8 @@
 #include "mpc5516.h"\r
 #elif defined(CFG_MPC5567)\r
 #include "mpc5567.h"\r
+#elif defined(CFG_MPC5606S)\r
+#include "mpc5606s.h"\r
 #endif\r
 #if defined(USE_KERNEL)\r
 #include "Os.h"\r
 #endif\r
 \r
 \r
-#if PWM_DEV_EROR_DETECT==STD_ON\r
+#if defined(CFG_MPC5606S)\r
+       #define PWM_RUNTIME_CHANNEL_COUNT       48\r
+#else\r
+       #define PWM_RUNTIME_CHANNEL_COUNT       16\r
+#endif\r
+\r
+#if PWM_DEV_ERROR_DETECT==STD_ON\r
        #define PWM_VALIDATE(_exp, _errid) \\r
                if (!(_exp)) { \\r
                        Pwm_ReportError(_errid); \\r
                        return; \\r
                }\r
-       #define Pwm_VALIDATE_CHANNEL(_ch) PWM_VALIDATE(_ch <= 15, PWM_E_PARAM_CHANNEL)\r
+    #if ( defined(CFG_MPC5516) || defined (CFG_MPC5567) )\r
+               \r
+               #define PWM_RUNTIME_CHANNEL_COUNT       16\r
+               #define Pwm_VALIDATE_CHANNEL(_ch) PWM_VALIDATE(_ch < 16, PWM_E_PARAM_CHANNEL)\r
+\r
+       #elif  defined(CFG_MPC5606S)\r
+       \r
+               #define PWM_RUNTIME_CHANNEL_COUNT       48\r
+               #define Pwm_VALIDATE_CHANNEL(_ch) PWM_VALIDATE(((_ch <= PWM_MAX_CHANNEL-1) && (_ch >= 40)) ||((_ch <= 23) && (_ch >= 16)), PWM_E_PARAM_CHANNEL)\r
+       \r
+       #endif\r
+\r
        #define Pwm_VALIDATE_INITIALIZED() PWM_VALIDATE(Pwm_ModuleState == PWM_STATE_INITIALIZED, PWM_E_UNINIT)\r
        #define Pwm_VALIDATE_UNINITIALIZED() PWM_VALIDATE(Pwm_ModuleState != PWM_STATE_INITIALIZED, PWM_E_ALREADY_INITIALIZED)\r
 #else\r
@@ -69,6 +88,7 @@
        #define Pwm_VALIDATE_UNINITIALIZED()\r
 #endif\r
 \r
+const Pwm_ConfigType* PwmConfigPtr = NULL;\r
 \r
 typedef enum {\r
        PWM_STATE_UNINITIALIZED, PWM_STATE_INITIALIZED\r
@@ -87,7 +107,7 @@ typedef struct {
 } Pwm_ChannelStructType;\r
 \r
 // We use Pwm_ChannelType as index here\r
-Pwm_ChannelStructType ChannelRuntimeStruct[16];\r
+Pwm_ChannelStructType ChannelRuntimeStruct[PWM_RUNTIME_CHANNEL_COUNT];\r
 \r
 /* Local functions */\r
 void inline Pwm_InitChannel(Pwm_ChannelType Channel);\r
@@ -97,11 +117,51 @@ void inline Pwm_DeInitChannel(Pwm_ChannelType Channel);
 static void Pwm_Isr(void);\r
 #endif\r
 \r
+#if ( defined(CFG_MPC5516) || defined (CFG_MPC5567) )\r
+static void calcPeriodTicksAndPrescaler(\r
+    const Pwm_ChannelConfigurationType* channelConfig,\r
+    uint16_t* ticks, Pwm_ChannelPrescalerType* prescaler) {\r
+\r
+  uint32_t f_in = McuE_GetPeripheralClock( PERIPHERAL_CLOCK_EMIOS );\r
+  uint32_t f_target = channelConfig->frequency;\r
+  uint32_t pre_global = EMIOS.MCR.B.GPRE;\r
+\r
+  Pwm_ChannelPrescalerType pre;\r
+  uint32_t ticks_temp;\r
+\r
+  if (channelConfig->prescaler == PWM_CHANNEL_PRESCALER_AUTO) {\r
+    // Go from lowest to highest prescaler\r
+    for (pre = PWM_CHANNEL_PRESCALER_1; pre < PWM_CHANNEL_PRESCALER_4; ++pre) {\r
+      ticks_temp = f_in / (f_target * (pre_global + 1) * (pre + 1)); // Calc ticks\r
+      if (ticks_temp > 0xffff) {\r
+        ticks_temp = 0xffff;  // Prescaler too low\r
+      } else {\r
+        break;                // Prescaler ok\r
+      }\r
+    }\r
+  } else {\r
+    pre = channelConfig->prescaler; // Use config setting\r
+    ticks_temp = f_in / (f_target * pre_global * (pre+1)); // Calc ticks\r
+    if (ticks_temp > 0xffff) {\r
+      ticks_temp = 0xffff;  // Prescaler too low\r
+    }\r
+  }\r
+\r
+  (*ticks) = (uint16_t) ticks_temp;\r
+  (*prescaler) = pre;\r
+}\r
+#endif\r
+\r
 void Pwm_Init(const Pwm_ConfigType* ConfigPtr) {\r
     Pwm_ChannelType channel_iterator;\r
 \r
     Pwm_VALIDATE_UNINITIALIZED();\r
-    #if PWM_DEV_EROR_DETECT==STD_ON\r
+    #if defined(CFG_MPC5606S)\r
+               CGM.AC1_SC.R = 0x03000000; /* MPC56xxS: Select aux. set 1 clock to be FMPLL0 */\r
+               CGM.AC2_SC.R = 0x03000000; /* MPC56xxS: Select aux. set 2 clock to be FMPLL0 */\r
+       #endif\r
+       \r
+    #if PWM_DEV_ERROR_DETECT==STD_ON\r
         /*\r
          * PWM046: If development error detection is enabled for the Pwm module,\r
          * the function Pwm_Init shall raise development error PWM_E_PARAM_CONFIG\r
@@ -119,6 +179,70 @@ void Pwm_Init(const Pwm_ConfigType* ConfigPtr) {
         #endif\r
     #endif\r
 \r
+       #if defined(CFG_MPC5606S)\r
+\r
+       PwmConfigPtr = ConfigPtr;\r
+        /* Clock scaler uses system clock (~64MHz) as source, so prescaler 64 => 1MHz. */\r
+               EMIOS_0.MCR.B.GPRE = PWM_PRESCALER - 1;\r
+               EMIOS_1.MCR.B.GPRE = PWM_PRESCALER - 1;\r
+\r
+               /* Enable eMIOS clock */\r
+               EMIOS_0.MCR.B.GPREN = 1;\r
+               EMIOS_1.MCR.B.GPREN = 1;\r
+\r
+               /* Stop channels when in debug mode */\r
+               EMIOS_0.MCR.B.FRZ = PWM_FREEZE_ENABLE;\r
+               EMIOS_1.MCR.B.FRZ = PWM_FREEZE_ENABLE;\r
+\r
+               /* Use global time base */\r
+               EMIOS_0.MCR.B.GTBE = 1;\r
+               EMIOS_1.MCR.B.GTBE = 1;\r
+\r
+               Pwm_ModuleState = PWM_STATE_INITIALIZED;\r
+\r
+               for (channel_iterator = 0; channel_iterator < PWM_NUMBER_OF_CHANNELS; channel_iterator++)\r
+               {\r
+                       Pwm_ChannelType channel = ConfigPtr->Channels[channel_iterator].channel;\r
+\r
+                       // Set up the registers in hw\r
+\r
+                       if(channel <= PWM_NUMBER_OF_EACH_EMIOS-1)\r
+                       {\r
+                               memcpy((void*) &EMIOS_0.CH[channel],\r
+                                                       (void*) &ConfigPtr->Channels[channel_iterator].r,\r
+                                                       sizeof(Pwm_ChannelRegisterType));\r
+                       }\r
+                       else\r
+                       {\r
+                               memcpy((void*) &EMIOS_1.CH[channel-PWM_NUMBER_OF_EACH_EMIOS],\r
+                                                                               (void*) &ConfigPtr->Channels[channel_iterator].r,\r
+                                                                               sizeof(Pwm_ChannelRegisterType));\r
+                       }\r
+\r
+                       ChannelRuntimeStruct[channel].Class = ConfigPtr->ChannelClass[channel_iterator];\r
+\r
+               #if PWM_NOTIFICATION_SUPPORTED==STD_ON\r
+                /*\r
+                 * PWM052: The function Pwm_Init shall disable all notifications.\r
+                 *\r
+                 * This is now implemented in the configuration macro.\r
+                 */\r
+                // Install ISR\r
+                       if(channel <= PWM_NUMBER_OF_EACH_EMIOS-1)\r
+                       {\r
+                                Irq_AttachIsr2(tid, NULL, EMIOS_0_GFR_F16_F17 + (channel-16)/2);\r
+                       }\r
+                       else\r
+                       {\r
+                                Irq_AttachIsr2(tid, NULL, EMIOS_1_GFR_F16_F17 + (channel-40)/2 );\r
+                       }\r
+\r
+                ChannelRuntimeStruct[channel].NotificationRoutine\r
+                        = ConfigPtr->NotificationHandlers[channel_iterator];\r
+               #endif\r
+               }\r
+       #else\r
+\r
     /* Clock scaler uses system clock (~64MHz) as source, so prescaler 64 => 1MHz. */\r
     EMIOS.MCR.B.GPRE = PWM_PRESCALER - 1;\r
 \r
@@ -134,12 +258,26 @@ void Pwm_Init(const Pwm_ConfigType* ConfigPtr) {
     Pwm_ModuleState = PWM_STATE_INITIALIZED;\r
 \r
     for (channel_iterator = 0; channel_iterator < PWM_NUMBER_OF_CHANNELS; channel_iterator++) {\r
-        Pwm_ChannelType channel = ConfigPtr->Channels[channel_iterator].channel;\r
+      const Pwm_ChannelConfigurationType* channelConfig = &ConfigPtr->Channels[channel_iterator];\r
+      Pwm_ChannelType channel = channelConfig->channel;\r
 \r
-        // Set up the registers in hw\r
-        memcpy((void*) &EMIOS.CH[channel],\r
-                (void*) &ConfigPtr->Channels[channel_iterator].r,\r
-                sizeof(Pwm_ChannelRegisterType));\r
+        EMIOS.CH[channel].CCR.B.MODE = PWM_EMIOS_OPWM;\r
+        EMIOS.CH[channel].CCR.B.DMA = 0;\r
+        EMIOS.CH[channel].CCR.B.BSL = 3;\r
+        EMIOS.CH[channel].CCR.B.ODIS = 0;\r
+\r
+        Pwm_ChannelPrescalerType prescaler;  uint16_t period_ticks;\r
+        calcPeriodTicksAndPrescaler( channelConfig, &period_ticks, &prescaler );\r
+\r
+        EMIOS.CH[channel].CBDR.R = period_ticks;\r
+        EMIOS.CH[channel].CCR.B.UCPRE = prescaler;\r
+        EMIOS.CH[channel].CCR.B.UCPREN = 1;\r
+\r
+        // 0 A match on comparator A clears the output flip-flop, while a match on comparator B sets it\r
+        // 1 A match on comparator A sets the output flip-flop, while a match on comparator B clears it\r
+        // A duty cycle of X % should give a signal with state 'channelConfig->polarity' during\r
+        // X % of the period time.\r
+        EMIOS.CH[channel].CCR.B.EDPOL = (channelConfig->polarity == PWM_LOW) ? 1 : 0;\r
 \r
         #if PWM_NOTIFICATION_SUPPORTED==STD_ON\r
                 /*\r
@@ -174,6 +312,7 @@ void Pwm_Init(const Pwm_ConfigType* ConfigPtr) {
                         = ConfigPtr->NotificationHandlers[channel_iterator];\r
         #endif\r
     }\r
+       #endif\r
 }\r
 \r
 #if PWM_DEINIT_API==STD_ON\r
@@ -188,7 +327,19 @@ void inline Pwm_DeInitChannel(Pwm_ChannelType Channel) {
     #ifdef CFG_MPC5516\r
         // Set the disable bit for this channel\r
         EMIOS.UCDIS.R |= (1 << (31 - Channel));\r
-    #endif\r
+\r
+    #elif defined(CFG_MPC5606S)\r
+        // Set the disable bit for this channel\r
+        if(Channel <= PWM_NUMBER_OF_EACH_EMIOS-1)\r
+        {\r
+               EMIOS_0.UCDIS.R |= (1 << (Channel));\r
+        }\r
+        else\r
+        {\r
+               EMIOS_1.UCDIS.R |= (1 << (Channel-PWM_NUMBER_OF_EACH_EMIOS));\r
+        }\r
+\r
+       #endif\r
 \r
     /*\r
      * PWM052: The function Pwm_DeInit shall disable all notifications.\r
@@ -205,20 +356,28 @@ void Pwm_DeInit() {
        Pwm_VALIDATE_INITIALIZED();\r
 \r
        for (channel_iterator = 0; channel_iterator < PWM_NUMBER_OF_CHANNELS; channel_iterator++) {\r
-               Pwm_DeInitChannel(channel_iterator);\r
+               Pwm_ChannelType channel = PwmConfigPtr->Channels[channel_iterator].channel;\r
+               Pwm_DeInitChannel(channel);\r
 \r
        }\r
 \r
        // Disable module\r
-       EMIOS.MCR.B.MDIS = 1;\r
+\r
+       #ifdef CFG_MPC5516\r
+\r
+               EMIOS.MCR.B.MDIS = 1;\r
+\r
+    #elif defined(CFG_MPC5606S)\r
+\r
+               EMIOS_0.MCR.B.MDIS = 1;\r
+               EMIOS_1.MCR.B.MDIS = 1;\r
+\r
+       #endif\r
 \r
        Pwm_ModuleState = PWM_STATE_UNINITIALIZED;\r
 }\r
 #endif\r
 \r
-void Pwm_GetVersionInfo(Std_VersionInfoType* VersionInfo) {\r
-       /* TODO: Implement Pwm_GetVersionInfo */\r
-}\r
 \r
 /*\r
  * PWM083: The function Pwm_SetPeriodAndDuty shall be pre compile time\r
@@ -235,14 +394,28 @@ void Pwm_GetVersionInfo(Std_VersionInfoType* VersionInfo) {
                uint16 leading_edge_position = (uint16) (((uint32) Period\r
                                * (uint32) DutyCycle) >> 15);\r
 \r
+               #ifdef CFG_MPC5516\r
 \r
+                       /* Timer instant for leading edge */\r
+                       EMIOS.CH[Channel].CADR.R = leading_edge_position;\r
 \r
-               /* Timer instant for leading edge */\r
-               EMIOS.CH[Channel].CADR.R = leading_edge_position;\r
+                       /* Timer instant for the period to restart */\r
+                       EMIOS.CH[Channel].CBDR.R = Period;\r
 \r
-               /* Timer instant for the period to restart */\r
-               EMIOS.CH[Channel].CBDR.R = Period;\r
+               #elif defined(CFG_MPC5606S)\r
+\r
+                       if(Channel <= PWM_NUMBER_OF_EACH_EMIOS-1)\r
+                       {\r
+                               EMIOS_0.CH[Channel].CADR.R = leading_edge_position;\r
+                               EMIOS_0.CH[Channel].CBDR.R = Period;\r
+                       }\r
+                       else\r
+                       {\r
+                        EMIOS_1.CH[Channel - PWM_NUMBER_OF_EACH_EMIOS].CADR.R = leading_edge_position;\r
+                        EMIOS_1.CH[Channel - PWM_NUMBER_OF_EACH_EMIOS].CBDR.R = Period;\r
+                       }\r
 \r
+               #endif\r
        }\r
 #endif\r
 \r
@@ -256,44 +429,92 @@ void Pwm_GetVersionInfo(Std_VersionInfoType* VersionInfo) {
  * @param Channel PWM channel to use. 0 <= Channel < PWM_NUMBER_OF_CHANNELS <= 16\r
  * @param DutyCycle 0 <= DutyCycle <= 0x8000\r
  */\r
-void Pwm_SetDutyCycle(Pwm_ChannelType Channel, Pwm_DutyCycleType DutyCycle) {\r
-\r
-       uint16 leading_edge_position = (uint16) ((EMIOS.CH[Channel].CBDR.R\r
-                               * (uint32) DutyCycle) >> 15);\r
-\r
+#if PWM_SET_DUTYCYCLE==STD_ON\r
 \r
+void Pwm_SetDutyCycle(Pwm_ChannelType Channel, Pwm_DutyCycleType DutyCycle)\r
+{\r
        Pwm_VALIDATE_INITIALIZED();\r
        Pwm_VALIDATE_CHANNEL(Channel);\r
 \r
-       /* Timer instant for leading edge */\r
+       #ifdef CFG_MPC5516\r
 \r
-       /*\r
-        * PWM017: The function Pwm_SetDutyCycle shall update the duty cycle at\r
-        * the end of the period if supported by the implementation and configured\r
-        * with PwmDutycycleUpdatedEndperiod. [ This is achieved in hardware since\r
-        * the A and B registers are double buffered ]\r
-        *\r
-        * PWM014: The function Pwm_SetDutyCycle shall set the output state according\r
-        * to the configured polarity parameter [which is already set from\r
-        * Pwm_InitChannel], when the duty parameter is 0% [=0] or 100% [=0x8000].\r
-        */\r
-       if (DutyCycle == Pwm_100_Procent || DutyCycle == Pwm_0_Procent) {\r
-               EMIOS.CH[Channel].CADR.R = 0;\r
+               uint16 leading_edge_position = (uint16) ((EMIOS.CH[Channel].CBDR.R\r
+                                       * (uint32) DutyCycle) >> 15);\r
+\r
+\r
+               Pwm_VALIDATE_INITIALIZED();\r
+               Pwm_VALIDATE_CHANNEL(Channel);\r
 \r
-       } else {\r
+               /* Timer instant for leading edge */\r
+\r
+               /*\r
+                * PWM017: The function Pwm_SetDutyCycle shall update the duty cycle at\r
+                * the end of the period if supported by the implementation and configured\r
+                * with PwmDutycycleUpdatedEndperiod. [ This is achieved in hardware since\r
+                * the A and B registers are double buffered ]\r
+                *\r
+                * PWM014: The function Pwm_SetDutyCycle shall set the output state according\r
+                * to the configured polarity parameter [which is already set from\r
+                * Pwm_InitChannel], when the duty parameter is 0% [=0] or 100% [=0x8000].\r
+                */\r
                EMIOS.CH[Channel].CADR.R = leading_edge_position;\r
 \r
-       }\r
-}\r
+       #elif defined(CFG_MPC5606S)\r
 \r
-void Pwm_SetOutputToIdle(Pwm_ChannelType Channel) {\r
-       Pwm_VALIDATE_CHANNEL(Channel);\r
-       Pwm_VALIDATE_INITIALIZED();\r
+               if(Channel <= PWM_NUMBER_OF_EACH_EMIOS-1)\r
+               {\r
+                       uint16 leading_edge_position = (uint16) ((EMIOS_0.CH[Channel].CBDR.R* (uint32) DutyCycle) >> 15);\r
+\r
+                       EMIOS_0.CH[Channel].CADR.R = leading_edge_position;\r
 \r
-       /* TODO: Make Pwm_SetOutputToIdle sensitive to PwmIdleState (currently uses PwmPolarity) */\r
-       EMIOS.CH[Channel].CADR.R = 0;\r
+               }\r
+               else\r
+               {\r
+                       uint16 leading_edge_position = (uint16) ((EMIOS_1.CH[Channel-PWM_NUMBER_OF_EACH_EMIOS].CBDR.R* (uint32) DutyCycle) >> 15);\r
+\r
+                       EMIOS_1.CH[Channel-PWM_NUMBER_OF_EACH_EMIOS].CADR.R = leading_edge_position;\r
+\r
+               }\r
+       #endif\r
 }\r
+#endif\r
 \r
+#if  PWM_SET_OUTPUT_TO_IDLE == STD_ON\r
+       void Pwm_SetOutputToIdle(Pwm_ChannelType Channel)\r
+       {\r
+               Pwm_VALIDATE_CHANNEL(Channel);\r
+               Pwm_VALIDATE_INITIALIZED();\r
+\r
+               /* TODO: Make Pwm_SetOutputToIdle sensitive to PwmIdleState (currently uses PwmPolarity) */\r
+\r
+               #ifdef CFG_MPC5516\r
+\r
+                       EMIOS.CH[Channel].CADR.R = 0;\r
+\r
+               #elif defined(CFG_MPC5606S)\r
+\r
+\r
+                       for (Pwm_ChannelType channel_iterator = 0; channel_iterator < PWM_NUMBER_OF_CHANNELS; channel_iterator++)\r
+                       {\r
+                               if(Channel == PwmConfigPtr->Channels[channel_iterator].channel)\r
+                               {\r
+                                       Pwm_OutputStateType ChannelPol = PwmConfigPtr->Channels[channel_iterator].r.edgePolarity;\r
+                                       if(ChannelPol == PwmConfigPtr->IdleState[channel_iterator])\r
+                                       {\r
+                                               Pwm_SetDutyCycle(Channel,0x0000);\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               Pwm_SetDutyCycle(Channel,0x8000);\r
+                                       }\r
+                               }\r
+\r
+                       }\r
+\r
+               #endif\r
+\r
+}\r
+#endif\r
 /*\r
  * PWM085: The function Pwm_GetOutputState shall be pre compile configurable\r
  * ON/OFF by the configuration parameter PwmGetOutputState\r
@@ -303,12 +524,11 @@ void Pwm_SetOutputToIdle(Pwm_ChannelType Channel) {
         * PWM022: The function Pwm_GetOutputState shall read the internal state\r
         * of the PWM output signal and return it.\r
         */\r
-       Pwm_OutputStateType Pwm_GetOutputState(Pwm_ChannelType Channel) {\r
-\r
-\r
-\r
+       Pwm_OutputStateType Pwm_GetOutputState(Pwm_ChannelType Channel)\r
+       {\r
                // We need to return something, even in presence of errors\r
-               if (Channel >= 16) {\r
+               if (Channel >= PWM_MAX_CHANNEL ||Channel < 16 || Channel >23 && Channel <40 )\r
+               {\r
                        Pwm_ReportError(PWM_E_PARAM_CHANNEL);\r
 \r
                        /*\r
@@ -316,51 +536,96 @@ void Pwm_SetOutputToIdle(Pwm_ChannelType Channel) {
                         */\r
                        return PWM_LOW;\r
 \r
-               } else if (Pwm_ModuleState != PWM_STATE_INITIALIZED) {\r
+               }\r
+               else if (Pwm_ModuleState != PWM_STATE_INITIALIZED)\r
+               {\r
                        Pwm_ReportError(PWM_E_UNINIT);\r
-\r
                        /*\r
                         * Accordingly to PWM025, we should return PWM_LOW on failure.\r
                         */\r
                        return PWM_LOW;\r
-\r
                }\r
 \r
-               return EMIOS.CH[Channel].CSR.B.UCOUT;\r
+               #ifdef CFG_MPC5516\r
+\r
+                       return EMIOS.CH[Channel].CSR.B.UCOUT;\r
+\r
+               #elif defined(CFG_MPC5606S)\r
+\r
+                       if(Channel <= PWM_NUMBER_OF_EACH_EMIOS-1)\r
+                       {\r
+                               return EMIOS_0.CH[Channel].CSR.B.UCOUT;\r
+                       }\r
+                       else\r
+                       {\r
+                               return EMIOS_1.CH[Channel-PWM_NUMBER_OF_EACH_EMIOS].CSR.B.UCOUT;\r
+                       }\r
+               #endif\r
 \r
        }\r
 #endif\r
 \r
 #if PWM_NOTIFICATION_SUPPORTED==STD_ON\r
-       void Pwm_DisableNotification(Pwm_ChannelType Channel) {\r
+\r
+       void Pwm_DisableNotification(Pwm_ChannelType Channel)\r
+       {\r
                Pwm_VALIDATE_CHANNEL(Channel);\r
                Pwm_VALIDATE_INITIALIZED();\r
 \r
                // Disable flags on this channel\r
-               EMIOS.CH[Channel].CCR.B.FEN = 0;\r
+               #ifdef CFG_MPC5516\r
+\r
+                       EMIOS.CH[Channel].CCR.B.FEN = 0;\r
+\r
+               #elif defined(CFG_MPC5606S)\r
+\r
+                       if(Channel <= PWM_NUMBER_OF_EACH_EMIOS-1)\r
+                       {\r
+                               EMIOS_0.CH[Channel].CCR.B.FEN = 0;\r
+                       }\r
+                       else\r
+                       {\r
+                               EMIOS_1.CH[Channel-PWM_NUMBER_OF_EACH_EMIOS].CCR.B.FEN = 0;\r
+                       }\r
+               #endif\r
+\r
        }\r
 \r
-       void Pwm_EnableNotification(Pwm_ChannelType Channel,\r
-                       Pwm_EdgeNotificationType Notification) {\r
+       void Pwm_EnableNotification(Pwm_ChannelType Channel,Pwm_EdgeNotificationType Notification)\r
+       {\r
                Pwm_VALIDATE_CHANNEL(Channel);\r
                Pwm_VALIDATE_INITIALIZED();\r
 \r
                ChannelRuntimeStruct[Channel].NotificationState = Notification;\r
 \r
                // Enable flags on this channel\r
-               EMIOS.CH[Channel].CCR.B.FEN = 1;\r
+               #ifdef CFG_MPC5516\r
+\r
+                       EMIOS.CH[Channel].CCR.B.FEN = 1;\r
+\r
+               #elif defined(CFG_MPC5606S)\r
+\r
+                       if(Channel <= PWM_NUMBER_OF_EACH_EMIOS-1)\r
+                       {\r
+                               EMIOS_0.CH[Channel].CCR.B.FEN = 1;\r
+                       }\r
+                       else\r
+                       {\r
+                               EMIOS_1.CH[Channel-PWM_NUMBER_OF_EACH_EMIOS].CCR.B.FEN = 1;\r
+                       }\r
+               #endif\r
        }\r
 \r
-       static void Pwm_Isr(void) {\r
+       static void Pwm_Isr(void)\r
+       {\r
                // Find out which channel that triggered the interrupt\r
-#ifdef CFG_MPC5516\r
-               uint32_t flagmask = EMIOS.GFLAG.R;\r
-#elif defined(CFG_MPC5567)\r
-               uint32_t flagmask = EMIOS.GFR.R;\r
-#endif\r
+               #ifdef CFG_MPC5516\r
+                       uint32_t flagmask = EMIOS.GFLAG.R;\r
+               #elif defined(CFG_MPC5567)\r
+                       uint32_t flagmask = EMIOS.GFR.R;\r
 \r
                // There are 24 channels specified in the global flag register, but\r
-               // we only listen to the first 16 as only these support OPWM\r
+               // we only listen to the first 16 as only these support OPWfM\r
                for (Pwm_ChannelType emios_ch = 0; emios_ch < 16; emios_ch++) {\r
                        if (flagmask & (1 << emios_ch)) {\r
 \r
@@ -369,14 +634,57 @@ void Pwm_SetOutputToIdle(Pwm_ChannelType Channel) {
                                        Pwm_EdgeNotificationType notification = ChannelRuntimeStruct[emios_ch].NotificationState;\r
                                        if (notification == PWM_BOTH_EDGES ||\r
                                                        notification == EMIOS.CH[emios_ch].CSR.B.UCOUT) {\r
+                                       {\r
                                                        ChannelRuntimeStruct[emios_ch].NotificationRoutine();\r
                                        }\r
                                }\r
-\r
                                // Clear interrupt\r
                                EMIOS.CH[emios_ch].CSR.B.FLAG = 1;\r
                        }\r
                }\r
+        #elif defined(CFG_MPC5606S)\r
+                       uint32_t flagmask_0 = EMIOS_0.GFR.R;\r
+                       uint32_t flagmask_1 = EMIOS_1.GFR.R;\r
+\r
+                       for (Pwm_ChannelType channel_iterator = 0; channel_iterator < 16; channel_iterator++)\r
+                       {\r
+\r
+                               Pwm_ChannelType emios_ch = PwmConfigPtr->Channels[channel_iterator].channel;\r
+\r
+                               if (flagmask_0 & (1 << emios_ch))\r
+                               {\r
+                                       if (ChannelRuntimeStruct[channel_iterator].NotificationRoutine != NULL && EMIOS_0.CH[emios_ch].CCR.B.FEN)\r
+                                       {\r
+                                               Pwm_EdgeNotificationType notification = ChannelRuntimeStruct[channel_iterator].NotificationState;\r
+                                               if (notification == PWM_BOTH_EDGES ||\r
+\r
+                                                               notification == EMIOS_0.CH[emios_ch].CSR.B.UCOUT)\r
+                                               {\r
+                                                               ChannelRuntimeStruct[channel_iterator].NotificationRoutine();\r
+                                               }\r
+                                       }\r
+\r
+                                       // Clear interrupt\r
+                                       EMIOS_0.CH[emios_ch].CSR.B.FLAG = 1;\r
+                               }\r
+                               else if (flagmask_1 & (1 << emios_ch - 24 ))\r
+                               {\r
+                                       if (ChannelRuntimeStruct[channel_iterator].NotificationRoutine != NULL && EMIOS_1.CH[emios_ch - 24].CCR.B.FEN)\r
+                                       {\r
+                                               Pwm_EdgeNotificationType notification = ChannelRuntimeStruct[channel_iterator].NotificationState;\r
+                                               if (notification == PWM_BOTH_EDGES ||\r
+                                                               notification == EMIOS_1.CH[emios_ch - 24].CSR.B.UCOUT)\r
+                                                       {\r
+                                                               ChannelRuntimeStruct[channel_iterator].NotificationRoutine();\r
+                                                       }\r
+                                               }\r
+\r
+                                       // Clear interrupt\r
+                                       EMIOS_1.CH[emios_ch - 24].CSR.B.FLAG = 1;\r
+                               }\r
+                       }\r
+\r
+               #endif\r
        }\r
 \r
 #endif /* PWM_NOTIFICATION_SUPPORED == STD_ON */\r