]> rtime.felk.cvut.cz Git - arc.git/blobdiff - arch/ppc/mpc55xx/drivers/Adc_560x.c
Adc, fix for mpc5668.
[arc.git] / arch / ppc / mpc55xx / drivers / Adc_560x.c
index 21f034b6c3136b0dfb08457d4835b599304ba086..bb8633ebe880fba31015d4604f027c9dc478221e 100644 (file)
  * for more details.\r
  * -------------------------------- Arctic Core ------------------------------*/\r
 \r
+\r
+/* In order to support multiple hw units we need to match group to a certain hw controller.\r
+ * We handle this in a very simple way i.e. group 0-99 -> hwUnitId 0, group 100-199 -> hwUnitId 1 etc.*\r
+ */\r
+\r
 /* ----------------------------[includes]------------------------------------*/\r
 \r
 #include <assert.h>\r
        #error Adc is configured to use Dma but the module is not enabled.\r
 #endif\r
 \r
+\r
 #if defined(CFG_MPC5668)\r
-#define ADC_0                          ADC\r
+#define ADC0_EOC_INT   ADC_A_EOC\r
+#define ADC0_ER_INT            ADC_A_ERR\r
+#define        ADC0_WD_INT             ADC_A_WD\r
+#define ADC1_EOC_INT   ADC_B_EOC\r
+#define ADC1_ER_INT            ADC_B_ERR\r
+#define        ADC1_WD_INT             ADC_B_WD\r
 #endif\r
 \r
 #if defined(CFG_MPC5668)\r
-#define ADC_EOC_INT    ADC_A_EOC\r
-#define ADC_ER_INT             ADC_A_ERR\r
-#define        ADC_WD_INT              ADC_A_WD\r
+#define ADC_BASE_ADDRESS 0xFFF80000\r
+#else\r
+#define ADC_BASE_ADDRESS 0xFFE00000\r
 #endif\r
 \r
+#define GET_HW_CONTROLLER(_controller)         \\r
+                                               ((struct ADC_tag *)(ADC_BASE_ADDRESS + 0x4000*(_controller)))\r
 \r
+#define GET_HWUNITID_FROM_GROUP(_group) (_group / ADC_NOF_GROUP_PER_CONTROLLER)\r
 \r
 /* ----------------------------[private macro]-------------------------------*/\r
 /* ----------------------------[private typedef]-----------------------------*/\r
 \r
 /* static variable declarations */\r
 static Adc_StateType adcState = ADC_UNINIT;\r
-static const Adc_ConfigType *AdcConfigPtr;      /* Pointer to configuration structure. */\r
+static const Adc_ConfigType *AdcGlobalConfigPtr;      /* Pointer to configuration structure. */\r
 \r
 /* ----------------------------[private functions]---------------------------*/\r
 \r
 /* Function prototypes. */\r
-static void Adc_ConfigureADC (const Adc_ConfigType *ConfigPtr);\r
-static void Adc_ConfigureADCInterrupts (void);\r
-void Adc_GroupConversionComplete (Adc_GroupType group);\r
+static void Adc_ConfigureADC (const Adc_ConfigType *AdcConfigPtr);\r
+static void Adc_ConfigureADCInterrupts (const Adc_ConfigType *AdcConfigPtr);\r
+void Adc_GroupConversionComplete (Adc_GroupType group, const Adc_ConfigType *AdcConfigPtr, volatile struct ADC_tag *hwPtr);\r
 \r
+static const Adc_ConfigType * Adc_GetControllerConfigPtrFromHwUnitId(int unit)\r
+{\r
+       const Adc_ConfigType *AdcConfigPtr = NULL;\r
+\r
+       if(adcState == ADC_INIT){\r
+               for (int configId = 0; configId < ADC_ARC_CTRL_CONFIG_CNT; configId++) {\r
+                       if(unit == AdcGlobalConfigPtr[configId].hwConfigPtr->hwUnitId){\r
+                               AdcConfigPtr = &AdcGlobalConfigPtr[configId];\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
 \r
+       return AdcConfigPtr;\r
+}\r
+\r
+static const Adc_ConfigType * Adc_GetControllerConfigPtrFromGroupId(Adc_GroupType group)\r
+{\r
+       return Adc_GetControllerConfigPtrFromHwUnitId(GET_HWUNITID_FROM_GROUP(group));\r
+}\r
 /* ----------------------------[public functions]----------------------------*/\r
 \r
 #if (ADC_DEINIT_API == STD_ON)\r
 void Adc_DeInit ()\r
 {\r
-  if (E_OK == Adc_CheckDeInit(adcState, AdcConfigPtr))\r
-  {\r
-    for(Adc_GroupType group = (Adc_GroupType)ADC_GROUP0; group < AdcConfigPtr->nbrOfGroups; group++)\r
-    {\r
-      /* Set group status to idle. */\r
-      AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;\r
-    }\r
+  volatile struct ADC_tag *hwPtr;\r
+  boolean okToClear = TRUE;\r
 \r
-    /* Disable DMA transfer*/\r
-#ifndef CFG_MPC5604B\r
-    ADC_0.DMAE.B.DMAEN = 0;\r
-#endif\r
-    /* Power down ADC */\r
-    ADC_0.MCR.R = 0x0001;\r
+  for (int configId = 0; configId < ADC_ARC_CTRL_CONFIG_CNT; configId++) {\r
+         const Adc_ConfigType *AdcConfigPtr = &AdcGlobalConfigPtr[configId];\r
 \r
-    /* Disable all interrupt*/\r
-    ADC_0.IMR.R = 0;\r
+         if (E_OK == Adc_CheckDeInit(adcState, AdcConfigPtr))\r
+         {\r
+               hwPtr = GET_HW_CONTROLLER(AdcGlobalConfigPtr[configId].hwConfigPtr->hwUnitId);\r
+               for(Adc_GroupType group = (Adc_GroupType)0; group < AdcConfigPtr->nbrOfGroups; group++)\r
+               {\r
+                 /* Set group status to idle. */\r
+                 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;\r
+               }\r
 \r
-    /* Clean internal status. */\r
-    AdcConfigPtr = (Adc_ConfigType *)NULL;\r
-    adcState = ADC_UNINIT;\r
-  }\r
+               /* Disable DMA transfer*/\r
+       #ifndef CFG_MPC5604B\r
+               hwPtr->DMAE.B.DMAEN = 0;\r
+       #endif\r
+               /* Power down ADC */\r
+               hwPtr->MCR.R = 0x0001;\r
+\r
+               /* Disable all interrupt*/\r
+               hwPtr->IMR.R = 0;\r
+         }\r
+         else\r
+         {\r
+               /* Not ok to change adcState if any unit is running */\r
+           okToClear = FALSE;\r
+         }\r
+       }\r
+\r
+    if(okToClear)\r
+    {\r
+       /* Clean internal status. */\r
+       AdcGlobalConfigPtr = (Adc_ConfigType *)NULL;\r
+       adcState = ADC_UNINIT;\r
+    }\r
 }\r
 #endif\r
 \r
@@ -107,16 +156,21 @@ void Adc_Init (const Adc_ConfigType *ConfigPtr)
 {\r
   if (E_OK == Adc_CheckInit(adcState, ConfigPtr))\r
   {\r
-            /* First of all, store the location of the configuration data. */\r
-            AdcConfigPtr = ConfigPtr;\r
+       /* First of all, store the location of the global configuration data. */\r
+       AdcGlobalConfigPtr = ConfigPtr;\r
 \r
-            /* Enable ADC. */\r
-             Adc_ConfigureADC(ConfigPtr);\r
+       for (int configId = 0; configId < ADC_ARC_CTRL_CONFIG_CNT; configId++)\r
+       {\r
+         const Adc_ConfigType *AdcConfigPtr = &AdcGlobalConfigPtr[configId];\r
+\r
+         /* Enable ADC. */\r
+      Adc_ConfigureADC(AdcConfigPtr);\r
 \r
-             Adc_ConfigureADCInterrupts();\r
+         Adc_ConfigureADCInterrupts(AdcConfigPtr);\r
+       }\r
 \r
-            /* Move on to INIT state. */\r
-            adcState = ADC_INIT;\r
+       /* Move on to INIT state. */\r
+       adcState = ADC_INIT;\r
   }\r
 }\r
 \r
@@ -124,10 +178,12 @@ Std_ReturnType Adc_SetupResultBuffer (Adc_GroupType group, Adc_ValueGroupType *b
 {\r
   Std_ReturnType returnValue = E_NOT_OK;\r
 \r
+  const Adc_ConfigType *AdcConfigPtr = Adc_GetControllerConfigPtrFromGroupId(group);\r
+\r
   /* Check for development errors. */\r
   if (E_OK == Adc_CheckSetupResultBuffer (adcState, AdcConfigPtr, group))\r
   {\r
-    AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr = bufferPtr;\r
+    AdcConfigPtr->groupConfigPtr[group%ADC_NOF_GROUP_PER_CONTROLLER].status->resultBufferPtr = bufferPtr;\r
     \r
     returnValue = E_OK;\r
   }\r
@@ -137,48 +193,57 @@ Std_ReturnType Adc_SetupResultBuffer (Adc_GroupType group, Adc_ValueGroupType *b
 \r
 Adc_StreamNumSampleType Adc_GetStreamLastPointer(Adc_GroupType group, Adc_ValueGroupType** PtrToSamplePtr)\r
 {\r
+       const Adc_ConfigType *AdcConfigPtr = Adc_GetControllerConfigPtrFromGroupId(group);\r
        Adc_StreamNumSampleType nofSample = 0;\r
-       Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];\r
        \r
        /** @req ADC216 */\r
        /* Check for development errors. */\r
-       if ( (E_OK == Adc_CheckGetStreamLastPointer (adcState, AdcConfigPtr, group)) &&\r
-                (groupPtr->status->groupStatus != ADC_BUSY) )\r
+       if (E_OK == Adc_CheckGetStreamLastPointer (adcState, AdcConfigPtr, group))\r
        {\r
-           /* Set resultPtr to application buffer. */\r
-               if(groupPtr->status->currSampleCount > 0){\r
-                       *PtrToSamplePtr = &groupPtr->status->resultBufferPtr[groupPtr->status->currSampleCount-1];\r
-               }\r
+               Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group%ADC_NOF_GROUP_PER_CONTROLLER];\r
 \r
-           if ((ADC_CONV_MODE_ONESHOT == groupPtr->conversionMode) &&\r
-               (ADC_STREAM_COMPLETED  == groupPtr->status->groupStatus))\r
+               if (groupPtr->status->groupStatus != ADC_BUSY)\r
            {\r
-                       /** @req ADC327. */\r
-                       groupPtr->status->groupStatus = ADC_IDLE;\r
-           }\r
-           else if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
-                    (ADC_ACCESS_MODE_STREAMING == groupPtr->accessMode) &&\r
-                    (ADC_STREAM_BUFFER_LINEAR == groupPtr->streamBufferMode) &&\r
-                    (ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus))\r
-           {\r
-                       /** @req ADC327. */\r
-                       groupPtr->status->groupStatus = ADC_IDLE;\r
-           }\r
-           else if ( (ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
-                     ((ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus) ||\r
-                      (ADC_COMPLETED           == groupPtr->status->groupStatus)) )\r
-           {\r
-               /* Restart continous mode, and reset result buffer */\r
-               if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
-                   (ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus))\r
-               {\r
-                         /* Start continous conversion again */\r
-                       Adc_StartGroupConversion(group);\r
-               }\r
-                       /** @req ADC326 */\r
-                       /** @req ADC328 */\r
+                       /* Set resultPtr to application buffer. */\r
+                       if(groupPtr->status->currSampleCount > 0){\r
+                               *PtrToSamplePtr = &groupPtr->status->resultBufferPtr[groupPtr->status->currSampleCount-1];\r
+                       }\r
+\r
+                       if ((ADC_CONV_MODE_ONESHOT == groupPtr->conversionMode) &&\r
+                               (ADC_STREAM_COMPLETED  == groupPtr->status->groupStatus))\r
+                       {\r
+                               /** @req ADC327. */\r
+                               groupPtr->status->groupStatus = ADC_IDLE;\r
+                       }\r
+                       else if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
+                                        (ADC_ACCESS_MODE_STREAMING == groupPtr->accessMode) &&\r
+                                        (ADC_STREAM_BUFFER_LINEAR == groupPtr->streamBufferMode) &&\r
+                                        (ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus))\r
+                       {\r
+                               /** @req ADC327. */\r
+                               groupPtr->status->groupStatus = ADC_IDLE;\r
+                       }\r
+                       else if ( (ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
+                                         ((ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus) ||\r
+                                          (ADC_COMPLETED           == groupPtr->status->groupStatus)) )\r
+                       {\r
+                               /* Restart continous mode, and reset result buffer */\r
+                               if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
+                                       (ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus))\r
+                               {\r
+                                 /* Start continous conversion again */\r
+                                       Adc_StartGroupConversion(group);\r
+                               }\r
+                               /** @req ADC326 */\r
+                               /** @req ADC328 */\r
+                       }\r
+                       else{/* Keep status. */}\r
            }\r
-           else{/* Keep status. */}\r
+               else\r
+               {\r
+                       /* Some condition not met */\r
+                       *PtrToSamplePtr = NULL;\r
+               }\r
        }\r
        else\r
        {\r
@@ -195,10 +260,12 @@ Std_ReturnType Adc_ReadGroup (Adc_GroupType group, Adc_ValueGroupType *dataBuffe
 {\r
   Std_ReturnType returnValue = E_OK;\r
   uint8_t channel;\r
-  Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];\r
+  const Adc_ConfigType *AdcConfigPtr = Adc_GetControllerConfigPtrFromGroupId(group);\r
 \r
   if (E_OK == Adc_CheckReadGroup (adcState, AdcConfigPtr, group))\r
   {\r
+       Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group%ADC_NOF_GROUP_PER_CONTROLLER];\r
+\r
     /* Copy the result to application buffer. */\r
     for (channel = 0; channel < groupPtr->numberOfChannels; channel++)\r
        {\r
@@ -250,16 +317,16 @@ Std_ReturnType Adc_ReadGroup (Adc_GroupType group, Adc_ValueGroupType *dataBuffe
 }\r
 #endif\r
 \r
-void Adc_GroupConversionComplete (Adc_GroupType group)\r
+void Adc_GroupConversionComplete (Adc_GroupType group, const Adc_ConfigType *AdcConfigPtr, volatile struct ADC_tag *hwPtr)\r
 {\r
-       Adc_GroupDefType *adcGroup = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];\r
+  Adc_GroupDefType *adcGroup = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group%ADC_NOF_GROUP_PER_CONTROLLER];\r
 \r
   if(ADC_ACCESS_MODE_SINGLE == adcGroup->accessMode )\r
   {\r
          adcGroup->status->groupStatus = ADC_STREAM_COMPLETED;\r
 \r
     /* Disable trigger normal conversions for ADC0 */\r
-    ADC_0.MCR.B.NSTART=0;\r
+    hwPtr->MCR.B.NSTART=0;\r
 \r
          /* Call notification if enabled. */\r
        #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)\r
@@ -284,8 +351,8 @@ void Adc_GroupConversionComplete (Adc_GroupType group)
                Dma_ConfigureDestinationAddress((uint32_t)adcGroup->status->currResultBufPtr, adcGroup->dmaResultChannel);\r
 #endif\r
 \r
-               ADC_0.IMR.B.MSKECH = 1;\r
-           ADC_0.MCR.B.NSTART=1;\r
+               hwPtr->IMR.B.MSKECH = 1;\r
+           hwPtr->MCR.B.NSTART=1;\r
                }\r
                else\r
                {\r
@@ -293,7 +360,7 @@ void Adc_GroupConversionComplete (Adc_GroupType group)
                  adcGroup->status->groupStatus = ADC_STREAM_COMPLETED;\r
 \r
       /* Disable trigger normal conversions for ADC0 */\r
-      ADC_0.MCR.B.NSTART=0;\r
+      hwPtr->MCR.B.NSTART=0;\r
 \r
                  /* Call notification if enabled. */\r
                #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)\r
@@ -315,15 +382,15 @@ void Adc_GroupConversionComplete (Adc_GroupType group)
 #endif\r
                        adcGroup->status->groupStatus = ADC_COMPLETED;\r
 \r
-                       ADC_0.IMR.B.MSKECH = 1;\r
-                   ADC_0.MCR.B.NSTART=1;\r
+                       hwPtr->IMR.B.MSKECH = 1;\r
+                   hwPtr->MCR.B.NSTART=1;\r
                }\r
                else\r
                {\r
                  /* Sample completed. */\r
 \r
                  /* Disable trigger normal conversions for ADC*/\r
-                 ADC_0.MCR.B.NSTART=0;\r
+                 hwPtr->MCR.B.NSTART=0;\r
 \r
                  adcGroup->status->groupStatus = ADC_STREAM_COMPLETED;\r
                  /* Call notification if enabled. */\r
@@ -341,14 +408,18 @@ void Adc_GroupConversionComplete (Adc_GroupType group)
        }\r
   }\r
 }\r
-void Adc_Group0ConversionComplete (void)\r
+\r
+void Adc_Group0ConversionComplete (int unit)\r
 {\r
+       volatile struct ADC_tag *hwPtr = GET_HW_CONTROLLER(unit);\r
+       const Adc_ConfigType *AdcConfigPtr = Adc_GetControllerConfigPtrFromHwUnitId(unit);\r
+\r
        /* Clear ECH Flag and disable interruput */\r
-       ADC_0.ISR.B.ECH = 1;\r
-       ADC_0.IMR.B.MSKECH = 0;\r
+       hwPtr->ISR.B.ECH = 1;\r
+       hwPtr->IMR.B.MSKECH = 0;\r
 \r
        // Check which group is busy, only one is allowed to be busy at a time in a hw unit\r
-       for (int group = 0; group < ADC_NBR_OF_GROUPS; group++)\r
+       for (int group = 0; group < AdcConfigPtr->nbrOfGroups; group++)\r
        {\r
          if((AdcConfigPtr->groupConfigPtr[group].status->groupStatus == ADC_BUSY) ||\r
        (AdcConfigPtr->groupConfigPtr[group].status->groupStatus == ADC_COMPLETED))\r
@@ -358,57 +429,84 @@ void Adc_Group0ConversionComplete (void)
                for(uint8 index=0; index < AdcConfigPtr->groupConfigPtr[group].numberOfChannels; index++)\r
                {\r
 #if defined(CFG_MPC5606S)\r
-                       AdcConfigPtr->groupConfigPtr[group].status->currResultBufPtr[index] = ADC_0.CDR[32+AdcConfigPtr->groupConfigPtr[group].channelList[index]].B.CDATA;\r
+                       AdcConfigPtr->groupConfigPtr[group].status->currResultBufPtr[index] = hwPtr->CDR[32+AdcConfigPtr->groupConfigPtr[group].channelList[index]].B.CDATA;\r
 #else\r
-                       AdcConfigPtr->groupConfigPtr[group].status->currResultBufPtr[index] = ADC_0.CDR[AdcConfigPtr->groupConfigPtr[group].channelList[index]].B.CDATA;\r
+                       AdcConfigPtr->groupConfigPtr[group].status->currResultBufPtr[index] = hwPtr->CDR[AdcConfigPtr->groupConfigPtr[group].channelList[index]].B.CDATA;\r
 #endif\r
                }\r
 #endif\r
 \r
-           Adc_GroupConversionComplete((Adc_GroupType)group);\r
+           Adc_GroupConversionComplete((Adc_GroupType)group, AdcConfigPtr, hwPtr);\r
                break;\r
          }\r
        }\r
 }\r
 \r
+static void Adc_Group0ConversionComplete_ADC0(void){\r
+       Adc_Group0ConversionComplete(ADC_CTRL_0);\r
+}\r
+\r
+static void Adc_Group0ConversionComplete_ADC1(void){\r
+       Adc_Group0ConversionComplete(ADC_CTRL_1);\r
+}\r
+\r
 void Adc_WatchdogError (void){\r
 }\r
 void Adc_ADCError (void){\r
 }\r
 \r
-static void  Adc_ConfigureADC (const Adc_ConfigType *ConfigPtr)\r
+static void  Adc_ConfigureADC (const Adc_ConfigType *AdcConfigPtr)\r
 {\r
+  volatile struct ADC_tag *hwPtr = GET_HW_CONTROLLER(AdcConfigPtr->hwConfigPtr->hwUnitId);\r
+\r
   /* Set ADC CLOCK */\r
-  ADC_0.MCR.B.ADCLKSEL = ConfigPtr->hwConfigPtr->adcPrescale;\r
+  hwPtr->MCR.B.ADCLKSEL = AdcConfigPtr->hwConfigPtr->adcPrescale;\r
 \r
-  ADC_0.DSDR.B.DSD = 254;\r
+  hwPtr->DSDR.B.DSD = 254;\r
 \r
   /* Power on ADC */\r
-  ADC_0.MCR.B.PWDN = 0;\r
+  hwPtr->MCR.B.PWDN = 0;\r
 \r
 #if defined(ADC_USES_DMA)\r
   /* Enable DMA. */\r
-  ADC_0.DMAE.B.DMAEN = 1;\r
+  hwPtr->DMAE.B.DMAEN = 1;\r
 #endif\r
 }\r
 \r
-void Adc_ConfigureADCInterrupts (void)\r
+void Adc_ConfigureADCInterrupts (const Adc_ConfigType *AdcConfigPtr)\r
 {\r
-       ISR_INSTALL_ISR2(  "Adc_Err", Adc_ADCError, ADC_ER_INT,     2, 0 );\r
-       ISR_INSTALL_ISR2(  "Adc_Grp", Adc_Group0ConversionComplete, ADC_EOC_INT,     2, 0 );\r
-       ISR_INSTALL_ISR2(  "Adc_Wdg", Adc_WatchdogError, ADC_WD_INT,     2, 0 );\r
+       if(AdcConfigPtr->hwConfigPtr->hwUnitId == 0)\r
+       {\r
+               ISR_INSTALL_ISR2(  "Adc_Err", Adc_ADCError, ADC0_ER_INT,     2, 0 );\r
+               ISR_INSTALL_ISR2(  "Adc_Grp", Adc_Group0ConversionComplete_ADC0, ADC0_EOC_INT,     2, 0 );\r
+               ISR_INSTALL_ISR2(  "Adc_Wdg", Adc_WatchdogError, ADC0_WD_INT,     2, 0 );\r
+    }\r
+       else if(AdcConfigPtr->hwConfigPtr->hwUnitId == 1)\r
+       {\r
+               ISR_INSTALL_ISR2(  "Adc_Err", Adc_ADCError, ADC1_ER_INT,     2, 0 );\r
+               ISR_INSTALL_ISR2(  "Adc_Grp", Adc_Group0ConversionComplete_ADC1, ADC1_EOC_INT,     2, 0 );\r
+               ISR_INSTALL_ISR2(  "Adc_Wdg", Adc_WatchdogError, ADC1_WD_INT,     2, 0 );\r
+    }\r
+       else\r
+    {\r
+       assert(0);\r
+    }\r
 }\r
 \r
 #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)\r
 void Adc_StartGroupConversion (Adc_GroupType group)\r
 {\r
-       Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];\r
+       const Adc_ConfigType *AdcConfigPtr = Adc_GetControllerConfigPtrFromGroupId(group);\r
 \r
        /* Run development error check. */\r
        if (E_OK == Adc_CheckStartGroupConversion (adcState, AdcConfigPtr, group))\r
        {\r
+               volatile struct ADC_tag *hwPtr = GET_HW_CONTROLLER(AdcConfigPtr->hwConfigPtr->hwUnitId);\r
+\r
+               Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group%ADC_NOF_GROUP_PER_CONTROLLER];\r
+\r
                /* Disable trigger normal conversions for ADC0 */\r
-               ADC_0.MCR.B.NSTART = 0;\r
+               hwPtr->MCR.B.NSTART = 0;\r
 \r
                /* Set group state to BUSY. */\r
                groupPtr->status->groupStatus = ADC_BUSY;\r
@@ -424,24 +522,24 @@ void Adc_StartGroupConversion (Adc_GroupType group)
                if( groupPtr->accessMode == ADC_ACCESS_MODE_STREAMING)\r
                {\r
                        /* Set conversion mode. */\r
-                       ADC_0.MCR.B.MODE = ADC_CONV_MODE_ONESHOT;\r
+                       hwPtr->MCR.B.MODE = ADC_CONV_MODE_ONESHOT;\r
                }\r
                else\r
                {\r
                        /* Set conversion mode. */\r
-                       ADC_0.MCR.B.MODE = groupPtr->conversionMode;\r
+                       hwPtr->MCR.B.MODE = groupPtr->conversionMode;\r
                }\r
 \r
                /* Enable Overwrite*/\r
-               ADC_0.MCR.B.OWREN = 1;\r
+               hwPtr->MCR.B.OWREN = 1;\r
 \r
                /* Set Conversion Time. */\r
 #if defined(CFG_MPC5606S)\r
                uint32 groupChannelIdMask = 0;\r
 \r
-               ADC_0.CTR[1].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH;\r
-               ADC_0.CTR[1].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP;\r
-               ADC_0.CTR[1].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP;\r
+               hwPtr->CTR[1].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH;\r
+               hwPtr->CTR[1].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP;\r
+               hwPtr->CTR[1].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP;\r
 \r
                for(uint8 i =0; i < groupPtr->numberOfChannels; i++)\r
                {\r
@@ -449,30 +547,30 @@ void Adc_StartGroupConversion (Adc_GroupType group)
                }\r
 \r
 #if defined(ADC_USES_DMA)\r
-               ADC_0.DMAE.R = 0x01;\r
+               hwPtr->DMAE.R = 0x01;\r
                /* Enable DMA Transfer */\r
-               ADC_0.DMAR[1].R = groupChannelIdMask;\r
+               hwPtr->DMAR[1].R = groupChannelIdMask;\r
                Dma_StartChannel(DMA_ADC_GROUP0_RESULT_CHANNEL);        /* Enable EDMA channel for ADC */\r
 #endif\r
 \r
                /* Enable Normal conversion */\r
-               ADC_0.NCMR[1].R = groupChannelIdMask;\r
+               hwPtr->NCMR[1].R = groupChannelIdMask;\r
 \r
                /* Enable Channel Interrupt */\r
-               ADC_0.CIMR[1].R = groupChannelIdMask;\r
+               hwPtr->CIMR[1].R = groupChannelIdMask;\r
 \r
 #else\r
                uint32 groupChannelIdMask[3] = {0,0,0};\r
 \r
-               ADC_0.CTR[0].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH;\r
-               ADC_0.CTR[0].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP;\r
-               ADC_0.CTR[0].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP;\r
-               ADC_0.CTR[1].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH;\r
-               ADC_0.CTR[1].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP;\r
-               ADC_0.CTR[1].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP;\r
-               ADC_0.CTR[2].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH;\r
-               ADC_0.CTR[2].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP;\r
-               ADC_0.CTR[2].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP;\r
+               hwPtr->CTR[0].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH;\r
+               hwPtr->CTR[0].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP;\r
+               hwPtr->CTR[0].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP;\r
+               hwPtr->CTR[1].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH;\r
+               hwPtr->CTR[1].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP;\r
+               hwPtr->CTR[1].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP;\r
+//             hwPtr->CTR[2].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH;\r
+//             hwPtr->CTR[2].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP;\r
+//             hwPtr->CTR[2].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP;\r
 \r
                for(uint8 i =0; i < groupPtr->numberOfChannels; i++)\r
                {\r
@@ -490,22 +588,22 @@ void Adc_StartGroupConversion (Adc_GroupType group)
                }\r
 \r
                /* Enable Normal conversion */\r
-               ADC_0.NCMR[0].R = groupChannelIdMask[0];\r
-               ADC_0.NCMR[1].R = groupChannelIdMask[1];\r
-               ADC_0.NCMR[2].R = groupChannelIdMask[2];\r
+               hwPtr->NCMR[0].R = groupChannelIdMask[0];\r
+               hwPtr->NCMR[1].R = groupChannelIdMask[1];\r
+//             hwPtr->NCMR[2].R = groupChannelIdMask[2];\r
 \r
                /* Enable Channel Interrupt */\r
-               ADC_0.CIMR[0].R = groupChannelIdMask[0];\r
-               ADC_0.CIMR[1].R = groupChannelIdMask[1];\r
-               ADC_0.CIMR[2].R = groupChannelIdMask[2];\r
+               hwPtr->CIMR[0].R = groupChannelIdMask[0];\r
+               hwPtr->CIMR[1].R = groupChannelIdMask[1];\r
+//             hwPtr->CIMR[2].R = groupChannelIdMask[2];\r
 #endif\r
                /* Clear interrupts */\r
-               ADC_0.ISR.B.ECH = 1;\r
+               hwPtr->ISR.B.ECH = 1;\r
                /* Enable ECH interrupt */\r
-               ADC_0.IMR.B.MSKECH = 1;\r
+               hwPtr->IMR.B.MSKECH = 1;\r
 \r
                /* Trigger normal conversions for ADC0 */\r
-               ADC_0.MCR.B.NSTART = 1;\r
+               hwPtr->MCR.B.NSTART = 1;\r
        }\r
        else\r
        {\r
@@ -515,16 +613,20 @@ void Adc_StartGroupConversion (Adc_GroupType group)
 \r
 void Adc_StopGroupConversion (Adc_GroupType group)\r
 {\r
+  const Adc_ConfigType *AdcConfigPtr = Adc_GetControllerConfigPtrFromGroupId(group);\r
+\r
   if (E_OK == Adc_CheckStopGroupConversion (adcState, AdcConfigPtr, group))\r
   {\r
+       volatile struct ADC_tag *hwPtr = GET_HW_CONTROLLER(AdcConfigPtr->hwConfigPtr->hwUnitId);\r
+\r
        /* Disable trigger normal conversions for ADC0 */\r
-       ADC_0.MCR.B.NSTART = 0;\r
+       hwPtr->MCR.B.NSTART = 0;\r
 \r
        /* Set group state to IDLE. */\r
-       AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;\r
+       AdcConfigPtr->groupConfigPtr[group%ADC_NOF_GROUP_PER_CONTROLLER].status->groupStatus = ADC_IDLE;\r
 \r
        /* Disable group notification if enabled. */\r
-    if(1 == AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable){\r
+    if(1 == AdcConfigPtr->groupConfigPtr[group%ADC_NOF_GROUP_PER_CONTROLLER].status->notifictionEnable){\r
        Adc_DisableGroupNotification (group);\r
     }\r
   }\r
@@ -538,17 +640,17 @@ void Adc_StopGroupConversion (Adc_GroupType group)
 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)\r
 void Adc_EnableGroupNotification (Adc_GroupType group)\r
 {\r
-       Adc_EnableInternalGroupNotification(adcState, AdcConfigPtr, group);\r
+       Adc_EnableInternalGroupNotification(adcState, Adc_GetControllerConfigPtrFromGroupId(group), group);\r
 }\r
 \r
 void Adc_DisableGroupNotification (Adc_GroupType group)\r
 {\r
-       Adc_InternalDisableGroupNotification(adcState, AdcConfigPtr, group);\r
+       Adc_InternalDisableGroupNotification(adcState, Adc_GetControllerConfigPtrFromGroupId(group), group);\r
 }\r
 #endif\r
 \r
 Adc_StatusType Adc_GetGroupStatus (Adc_GroupType group)\r
 {\r
-       return Adc_InternalGetGroupStatus(adcState, AdcConfigPtr, group);\r
+       return Adc_InternalGetGroupStatus(adcState, Adc_GetControllerConfigPtrFromGroupId(group), group);\r
 }\r
 \r