]> rtime.felk.cvut.cz Git - arc.git/blob - arch/ppc/mpc55xx/drivers/Adc_560x.c
adc update
[arc.git] / arch / ppc / mpc55xx / drivers / Adc_560x.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 \r
17 /* In order to support multiple hw units we need to match group to a certain hw controller.\r
18  * We handle this in a very simple way i.e. group 0-99 -> hwUnitId 0, group 100-199 -> hwUnitId 1 etc.*\r
19  */\r
20 \r
21 /* ----------------------------[includes]------------------------------------*/\r
22 \r
23 #include <assert.h>\r
24 #include <stdlib.h>\r
25 #include "Std_Types.h"\r
26 #include "mpc55xx.h"\r
27 #include "Modules.h"\r
28 #include "Mcu.h"\r
29 #include "Adc.h"\r
30 #include "Det.h"\r
31 #include "Os.h"\r
32 #include "isr.h"\r
33 #include "irq.h"\r
34 #include "arc.h"\r
35 #include "Adc_Internal.h"\r
36 /* ----------------------------[private define]------------------------------*/\r
37 \r
38 \r
39 /* Uncomment and use DMA for 5606 only if you now what you are doing */\r
40 #define DONT_USE_DMA_IN_ADC_MPC560X\r
41 \r
42 /* Are we gonna use Dma? */\r
43 #if ( defined(CFG_MPC5606S) && !defined(DONT_USE_DMA_IN_ADC_MPC560X) )\r
44         #define ADC_USES_DMA\r
45         #include "Dma.h"\r
46 #endif\r
47 \r
48 #if ( defined(ADC_USES_DMA) && !defined(USE_DMA) )\r
49         #error Adc is configured to use Dma but the module is not enabled.\r
50 #endif\r
51 \r
52 #if defined(CFG_MPC5668)\r
53 #define ADC_0                           ADC\r
54 #endif\r
55 \r
56 #if defined(CFG_MPC5668)\r
57 #define ADC_EOC_INT     ADC_A_EOC\r
58 #define ADC_ER_INT              ADC_A_ERR\r
59 #define ADC_WD_INT              ADC_A_WD\r
60 #endif\r
61 \r
62 #define GET_HW_CONTROLLER(_controller)  \\r
63                                                 ((struct ADC_tag *)(0xFFE00000 + 0x4000*(_controller)))\r
64 \r
65 #define GET_HWUNITID_FROM_GROUP(_group) (_group / NOF_GROUP_PER_CONTROLLER)\r
66 \r
67 /* ----------------------------[private macro]-------------------------------*/\r
68 /* ----------------------------[private typedef]-----------------------------*/\r
69 /* ----------------------------[private function prototypes]-----------------*/\r
70 /* ----------------------------[private variables]---------------------------*/\r
71 \r
72 /* static variable declarations */\r
73 static Adc_StateType adcState = ADC_UNINIT;\r
74 static const Adc_ConfigType *AdcGlobalConfigPtr;      /* Pointer to configuration structure. */\r
75 \r
76 /* ----------------------------[private functions]---------------------------*/\r
77 \r
78 /* Function prototypes. */\r
79 static void Adc_ConfigureADC (const Adc_ConfigType *AdcConfigPtr);\r
80 static void Adc_ConfigureADCInterrupts (const Adc_ConfigType *AdcConfigPtr);\r
81 void Adc_GroupConversionComplete (Adc_GroupType group, const Adc_ConfigType *AdcConfigPtr, volatile struct ADC_tag *hwPtr);\r
82 \r
83 static const Adc_ConfigType * Adc_GetControllerConfigPtrFromHwUnitId(int unit)\r
84 {\r
85         const Adc_ConfigType *AdcConfigPtr = NULL;\r
86 \r
87         for (int configId = 0; configId < ADC_ARC_CTRL_CONFIG_CNT; configId++) {\r
88                 if(unit == AdcGlobalConfigPtr[configId].hwConfigPtr->hwUnitId){\r
89                         AdcConfigPtr = &AdcGlobalConfigPtr[configId];\r
90       break;\r
91                 }\r
92         }\r
93 \r
94         return AdcConfigPtr;\r
95 }\r
96 \r
97 static const Adc_ConfigType * Adc_GetControllerConfigPtrFromGroupId(Adc_GroupType group)\r
98 {\r
99         return Adc_GetControllerConfigPtrFromHwUnitId(GET_HWUNITID_FROM_GROUP(group));\r
100 }\r
101 /* ----------------------------[public functions]----------------------------*/\r
102 \r
103 #if (ADC_DEINIT_API == STD_ON)\r
104 void Adc_DeInit ()\r
105 {\r
106   volatile struct ADC_tag *hwPtr;\r
107   boolean okToClear = TRUE;\r
108 \r
109   for (int configId = 0; configId < ADC_ARC_CTRL_CONFIG_CNT; configId++) {\r
110           hwPtr = GET_HW_CONTROLLER(AdcGlobalConfigPtr[configId].hwConfigPtr->hwUnitId);\r
111           const Adc_ConfigType *AdcConfigPtr = &AdcGlobalConfigPtr[configId];\r
112 \r
113           if (E_OK == Adc_CheckDeInit(adcState, AdcConfigPtr))\r
114           {\r
115                 for(Adc_GroupType group = (Adc_GroupType)0; group < AdcConfigPtr->nbrOfGroups; group++)\r
116                 {\r
117                   /* Set group status to idle. */\r
118                   AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;\r
119                 }\r
120 \r
121                 /* Disable DMA transfer*/\r
122         #ifndef CFG_MPC5604B\r
123                 hwPtr->DMAE.B.DMAEN = 0;\r
124         #endif\r
125                 /* Power down ADC */\r
126                 hwPtr->MCR.R = 0x0001;\r
127 \r
128                 /* Disable all interrupt*/\r
129                 hwPtr->IMR.R = 0;\r
130           }\r
131           else\r
132           {\r
133                 /* Not ok to change adcState if any unit is running */\r
134             okToClear = FALSE;\r
135           }\r
136         }\r
137 \r
138     if(okToClear)\r
139     {\r
140         /* Clean internal status. */\r
141         AdcGlobalConfigPtr = (Adc_ConfigType *)NULL;\r
142         adcState = ADC_UNINIT;\r
143     }\r
144 }\r
145 #endif\r
146 \r
147 void Adc_Init (const Adc_ConfigType *ConfigPtr)\r
148 {\r
149   if (E_OK == Adc_CheckInit(adcState, ConfigPtr))\r
150   {\r
151         /* First of all, store the location of the global configuration data. */\r
152         AdcGlobalConfigPtr = ConfigPtr;\r
153 \r
154         for (int configId = 0; configId < ADC_ARC_CTRL_CONFIG_CNT; configId++)\r
155         {\r
156           const Adc_ConfigType *AdcConfigPtr = &AdcGlobalConfigPtr[configId];\r
157 \r
158           /* Enable ADC. */\r
159       Adc_ConfigureADC(AdcConfigPtr);\r
160 \r
161           Adc_ConfigureADCInterrupts(AdcConfigPtr);\r
162         }\r
163 \r
164         /* Move on to INIT state. */\r
165         adcState = ADC_INIT;\r
166   }\r
167 }\r
168 \r
169 Std_ReturnType Adc_SetupResultBuffer (Adc_GroupType group, Adc_ValueGroupType *bufferPtr)\r
170 {\r
171   Std_ReturnType returnValue = E_NOT_OK;\r
172 \r
173   const Adc_ConfigType *AdcConfigPtr = Adc_GetControllerConfigPtrFromGroupId(group);\r
174 \r
175   /* Check for development errors. */\r
176   if (E_OK == Adc_CheckSetupResultBuffer (adcState, AdcConfigPtr, group))\r
177   {\r
178     AdcConfigPtr->groupConfigPtr[group%NOF_GROUP_PER_CONTROLLER].status->resultBufferPtr = bufferPtr;\r
179     \r
180     returnValue = E_OK;\r
181   }\r
182 \r
183   return (returnValue);\r
184 }\r
185 \r
186 Adc_StreamNumSampleType Adc_GetStreamLastPointer(Adc_GroupType group, Adc_ValueGroupType** PtrToSamplePtr)\r
187 {\r
188         const Adc_ConfigType *AdcConfigPtr = Adc_GetControllerConfigPtrFromGroupId(group);\r
189 \r
190         Adc_StreamNumSampleType nofSample = 0;\r
191         Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group%NOF_GROUP_PER_CONTROLLER];\r
192         \r
193         /** @req ADC216 */\r
194         /* Check for development errors. */\r
195         if ( (E_OK == Adc_CheckGetStreamLastPointer (adcState, AdcConfigPtr, group)) &&\r
196                  (groupPtr->status->groupStatus != ADC_BUSY) )\r
197         {\r
198             /* Set resultPtr to application buffer. */\r
199                 if(groupPtr->status->currSampleCount > 0){\r
200                         *PtrToSamplePtr = &groupPtr->status->resultBufferPtr[groupPtr->status->currSampleCount-1];\r
201                 }\r
202 \r
203             if ((ADC_CONV_MODE_ONESHOT == groupPtr->conversionMode) &&\r
204                 (ADC_STREAM_COMPLETED  == groupPtr->status->groupStatus))\r
205             {\r
206                         /** @req ADC327. */\r
207                         groupPtr->status->groupStatus = ADC_IDLE;\r
208             }\r
209             else if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
210                      (ADC_ACCESS_MODE_STREAMING == groupPtr->accessMode) &&\r
211                      (ADC_STREAM_BUFFER_LINEAR == groupPtr->streamBufferMode) &&\r
212                      (ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus))\r
213             {\r
214                         /** @req ADC327. */\r
215                         groupPtr->status->groupStatus = ADC_IDLE;\r
216             }\r
217             else if ( (ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
218                       ((ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus) ||\r
219                        (ADC_COMPLETED           == groupPtr->status->groupStatus)) )\r
220             {\r
221                 /* Restart continous mode, and reset result buffer */\r
222                 if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
223                     (ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus))\r
224                 {\r
225                           /* Start continous conversion again */\r
226                         Adc_StartGroupConversion(group);\r
227                 }\r
228                         /** @req ADC326 */\r
229                         /** @req ADC328 */\r
230             }\r
231             else{/* Keep status. */}\r
232         }\r
233         else\r
234         {\r
235                 /* Some condition not met */\r
236                 *PtrToSamplePtr = NULL;\r
237         }\r
238 \r
239         return nofSample;\r
240 \r
241 }\r
242 \r
243 #if (ADC_READ_GROUP_API == STD_ON)\r
244 Std_ReturnType Adc_ReadGroup (Adc_GroupType group, Adc_ValueGroupType *dataBufferPtr)\r
245 {\r
246   Std_ReturnType returnValue = E_OK;\r
247   uint8_t channel;\r
248   const Adc_ConfigType *AdcConfigPtr = Adc_GetControllerConfigPtrFromGroupId(group);\r
249   Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group%NOF_GROUP_PER_CONTROLLER];\r
250 \r
251   if (E_OK == Adc_CheckReadGroup (adcState, AdcConfigPtr, group))\r
252   {\r
253     /* Copy the result to application buffer. */\r
254     for (channel = 0; channel < groupPtr->numberOfChannels; channel++)\r
255         {\r
256                 if(groupPtr->status->currSampleCount > 0){\r
257                         dataBufferPtr[channel] = (&(groupPtr->status->resultBufferPtr[groupPtr->status->currSampleCount-1]))[channel];\r
258                 }else{\r
259                         dataBufferPtr[channel] = groupPtr->status->resultBufferPtr[channel];\r
260                 }\r
261         }\r
262 \r
263     if ((ADC_CONV_MODE_ONESHOT == groupPtr->conversionMode) &&\r
264         (ADC_STREAM_COMPLETED  == groupPtr->status->groupStatus))\r
265     {\r
266                 /** @req ADC330. */\r
267                 groupPtr->status->groupStatus = ADC_IDLE;\r
268     }\r
269     else if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
270              (ADC_STREAM_BUFFER_LINEAR == groupPtr->streamBufferMode) &&\r
271              (ADC_ACCESS_MODE_STREAMING == groupPtr->accessMode) &&\r
272              (ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus))\r
273     {\r
274                 /** @req ADC330. */\r
275                 groupPtr->status->groupStatus = ADC_IDLE;\r
276     }\r
277     else if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
278              ((ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus) ||\r
279               (ADC_COMPLETED           == groupPtr->status->groupStatus)))\r
280     {\r
281         /** @req ADC329 */\r
282       /* Restart continous mode, and reset result buffer */\r
283       if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
284           (ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus))\r
285       {\r
286                   /* Start continous conversion again */\r
287         Adc_StartGroupConversion(group);\r
288       }\r
289       /** @req ADC329 */\r
290       /** @req ADC331 */\r
291     }\r
292     else{/* Keep status. */}\r
293   }\r
294   else\r
295   {\r
296     /* An error have been raised from Adc_CheckReadGroup(). */\r
297     returnValue = E_NOT_OK;\r
298   }\r
299 \r
300   return (returnValue);\r
301 }\r
302 #endif\r
303 \r
304 void Adc_GroupConversionComplete (Adc_GroupType group, const Adc_ConfigType *AdcConfigPtr, volatile struct ADC_tag *hwPtr)\r
305 {\r
306   Adc_GroupDefType *adcGroup = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group%NOF_GROUP_PER_CONTROLLER];\r
307 \r
308   if(ADC_ACCESS_MODE_SINGLE == adcGroup->accessMode )\r
309   {\r
310           adcGroup->status->groupStatus = ADC_STREAM_COMPLETED;\r
311 \r
312     /* Disable trigger normal conversions for ADC0 */\r
313     hwPtr->MCR.B.NSTART=0;\r
314 \r
315           /* Call notification if enabled. */\r
316         #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)\r
317           if (adcGroup->status->notifictionEnable && adcGroup->groupCallback != NULL)\r
318           {\r
319                   adcGroup->groupCallback();\r
320           }\r
321         #endif\r
322   }\r
323   else\r
324   {\r
325         if(ADC_STREAM_BUFFER_LINEAR == adcGroup->streamBufferMode)\r
326         {\r
327                 adcGroup->status->currSampleCount++;\r
328                 if(adcGroup->status->currSampleCount < adcGroup->streamNumSamples)\r
329                 {\r
330                   adcGroup->status->currResultBufPtr += adcGroup->numberOfChannels;\r
331                   adcGroup->status->groupStatus = ADC_COMPLETED;\r
332 \r
333 #if defined (ADC_USES_DMA)\r
334                   /* Increase current result buffer ptr */\r
335                 Dma_ConfigureDestinationAddress((uint32_t)adcGroup->status->currResultBufPtr, adcGroup->dmaResultChannel);\r
336 #endif\r
337 \r
338                 hwPtr->IMR.B.MSKECH = 1;\r
339             hwPtr->MCR.B.NSTART=1;\r
340                 }\r
341                 else\r
342                 {\r
343                   /* All sample completed. */\r
344                   adcGroup->status->groupStatus = ADC_STREAM_COMPLETED;\r
345 \r
346       /* Disable trigger normal conversions for ADC0 */\r
347       hwPtr->MCR.B.NSTART=0;\r
348 \r
349                   /* Call notification if enabled. */\r
350                 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)\r
351                   if (adcGroup->status->notifictionEnable && adcGroup->groupCallback != NULL){\r
352                         adcGroup->groupCallback();\r
353                   }\r
354                 #endif\r
355                 }\r
356         }\r
357         else if(ADC_STREAM_BUFFER_CIRCULAR == adcGroup->streamBufferMode)\r
358         {\r
359                 adcGroup->status->currSampleCount++;\r
360                 if(adcGroup->status->currSampleCount < adcGroup->streamNumSamples)\r
361                 {\r
362                         adcGroup->status->currResultBufPtr += adcGroup->numberOfChannels;\r
363 #if defined (ADC_USES_DMA)\r
364                         /* Increase current result buffer ptr */\r
365                         Dma_ConfigureDestinationAddress((uint32_t)adcGroup->status->currResultBufPtr, adcGroup->dmaResultChannel);\r
366 #endif\r
367                         adcGroup->status->groupStatus = ADC_COMPLETED;\r
368 \r
369                         hwPtr->IMR.B.MSKECH = 1;\r
370                     hwPtr->MCR.B.NSTART=1;\r
371                 }\r
372                 else\r
373                 {\r
374                   /* Sample completed. */\r
375 \r
376                   /* Disable trigger normal conversions for ADC*/\r
377                   hwPtr->MCR.B.NSTART=0;\r
378 \r
379                   adcGroup->status->groupStatus = ADC_STREAM_COMPLETED;\r
380                   /* Call notification if enabled. */\r
381                 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)\r
382                   if (adcGroup->status->notifictionEnable && adcGroup->groupCallback != NULL)\r
383                   {\r
384                           adcGroup->groupCallback();\r
385                   }\r
386                 #endif\r
387                 }\r
388         }\r
389         else\r
390         {\r
391                 //nothing to do.\r
392         }\r
393   }\r
394 }\r
395 \r
396 void Adc_Group0ConversionComplete (int unit)\r
397 {\r
398         volatile struct ADC_tag *hwPtr = GET_HW_CONTROLLER(unit);\r
399         const Adc_ConfigType *AdcConfigPtr = Adc_GetControllerConfigPtrFromHwUnitId(unit);\r
400 \r
401         /* Clear ECH Flag and disable interruput */\r
402         hwPtr->ISR.B.ECH = 1;\r
403         hwPtr->IMR.B.MSKECH = 0;\r
404 \r
405         // Check which group is busy, only one is allowed to be busy at a time in a hw unit\r
406         for (int group = 0; group < AdcConfigPtr->nbrOfGroups; group++)\r
407         {\r
408           if((AdcConfigPtr->groupConfigPtr[group].status->groupStatus == ADC_BUSY) ||\r
409        (AdcConfigPtr->groupConfigPtr[group].status->groupStatus == ADC_COMPLETED))\r
410           {\r
411 #if !defined (ADC_USES_DMA)\r
412                 /* Copy to result buffer */\r
413                 for(uint8 index=0; index < AdcConfigPtr->groupConfigPtr[group].numberOfChannels; index++)\r
414                 {\r
415 #if defined(CFG_MPC5606S)\r
416                         AdcConfigPtr->groupConfigPtr[group].status->currResultBufPtr[index] = hwPtr->CDR[32+AdcConfigPtr->groupConfigPtr[group].channelList[index]].B.CDATA;\r
417 #else\r
418                         AdcConfigPtr->groupConfigPtr[group].status->currResultBufPtr[index] = hwPtr->CDR[AdcConfigPtr->groupConfigPtr[group].channelList[index]].B.CDATA;\r
419 #endif\r
420                 }\r
421 #endif\r
422 \r
423             Adc_GroupConversionComplete((Adc_GroupType)group, AdcConfigPtr, hwPtr);\r
424                 break;\r
425           }\r
426         }\r
427 }\r
428 \r
429 static void Adc_Group0ConversionComplete_ADC0(void){\r
430         Adc_Group0ConversionComplete(ADC_CTRL_0);\r
431 }\r
432 \r
433 static void Adc_Group0ConversionComplete_ADC1(void){\r
434         Adc_Group0ConversionComplete(ADC_CTRL_1);\r
435 }\r
436 \r
437 void Adc_WatchdogError (void){\r
438 }\r
439 void Adc_ADCError (void){\r
440 }\r
441 \r
442 static void  Adc_ConfigureADC (const Adc_ConfigType *AdcConfigPtr)\r
443 {\r
444   volatile struct ADC_tag *hwPtr = GET_HW_CONTROLLER(AdcConfigPtr->hwConfigPtr->hwUnitId);\r
445 \r
446   /* Set ADC CLOCK */\r
447   hwPtr->MCR.B.ADCLKSEL = AdcConfigPtr->hwConfigPtr->adcPrescale;\r
448 \r
449   hwPtr->DSDR.B.DSD = 254;\r
450 \r
451   /* Power on ADC */\r
452   hwPtr->MCR.B.PWDN = 0;\r
453 \r
454 #if defined(ADC_USES_DMA)\r
455   /* Enable DMA. */\r
456   hwPtr->DMAE.B.DMAEN = 1;\r
457 #endif\r
458 }\r
459 \r
460 void Adc_ConfigureADCInterrupts (const Adc_ConfigType *AdcConfigPtr)\r
461 {\r
462         if(AdcConfigPtr->hwConfigPtr->hwUnitId == 0)\r
463         {\r
464                 ISR_INSTALL_ISR2(  "Adc_Err", Adc_ADCError, ADC0_ER_INT,     2, 0 );\r
465                 ISR_INSTALL_ISR2(  "Adc_Grp", Adc_Group0ConversionComplete_ADC0, ADC0_EOC_INT,     2, 0 );\r
466                 ISR_INSTALL_ISR2(  "Adc_Wdg", Adc_WatchdogError, ADC0_WD_INT,     2, 0 );\r
467     }\r
468         else if(AdcConfigPtr->hwConfigPtr->hwUnitId == 1)\r
469         {\r
470                 ISR_INSTALL_ISR2(  "Adc_Err", Adc_ADCError, ADC1_ER_INT,     2, 0 );\r
471                 ISR_INSTALL_ISR2(  "Adc_Grp", Adc_Group0ConversionComplete_ADC1, ADC1_EOC_INT,     2, 0 );\r
472                 ISR_INSTALL_ISR2(  "Adc_Wdg", Adc_WatchdogError, ADC1_WD_INT,     2, 0 );\r
473     }\r
474         else\r
475     {\r
476         assert(0);\r
477     }\r
478 }\r
479 \r
480 #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)\r
481 void Adc_StartGroupConversion (Adc_GroupType group)\r
482 {\r
483         const Adc_ConfigType *AdcConfigPtr = Adc_GetControllerConfigPtrFromGroupId(group);\r
484         volatile struct ADC_tag *hwPtr = GET_HW_CONTROLLER(AdcConfigPtr->hwConfigPtr->hwUnitId);\r
485 \r
486         Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group%NOF_GROUP_PER_CONTROLLER];\r
487 \r
488         /* Run development error check. */\r
489         if (E_OK == Adc_CheckStartGroupConversion (adcState, AdcConfigPtr, group))\r
490         {\r
491                 /* Disable trigger normal conversions for ADC0 */\r
492                 hwPtr->MCR.B.NSTART = 0;\r
493 \r
494                 /* Set group state to BUSY. */\r
495                 groupPtr->status->groupStatus = ADC_BUSY;\r
496 \r
497                 groupPtr->status->currSampleCount = 0;\r
498                 groupPtr->status->currResultBufPtr = groupPtr->status->resultBufferPtr; /* Set current result buffer */\r
499 \r
500 #if defined(ADC_USES_DMA)\r
501                 Dma_ConfigureChannel ((Dma_TcdType *)groupPtr->groupDMAResults, groupPtr->dmaResultChannel);\r
502                 Dma_ConfigureDestinationAddress ((uint32_t)groupPtr->status->currResultBufPtr, groupPtr->dmaResultChannel);\r
503 #endif\r
504                 /* Always use single shot in streaming mode */\r
505                 if( groupPtr->accessMode == ADC_ACCESS_MODE_STREAMING)\r
506                 {\r
507                         /* Set conversion mode. */\r
508                         hwPtr->MCR.B.MODE = ADC_CONV_MODE_ONESHOT;\r
509                 }\r
510                 else\r
511                 {\r
512                         /* Set conversion mode. */\r
513                         hwPtr->MCR.B.MODE = groupPtr->conversionMode;\r
514                 }\r
515 \r
516                 /* Enable Overwrite*/\r
517                 hwPtr->MCR.B.OWREN = 1;\r
518 \r
519                 /* Set Conversion Time. */\r
520 #if defined(CFG_MPC5606S)\r
521                 uint32 groupChannelIdMask = 0;\r
522 \r
523                 hwPtr->CTR[1].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH;\r
524                 hwPtr->CTR[1].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP;\r
525                 hwPtr->CTR[1].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP;\r
526 \r
527                 for(uint8 i =0; i < groupPtr->numberOfChannels; i++)\r
528                 {\r
529                         groupChannelIdMask |= (1 << groupPtr->channelList[i]);\r
530                 }\r
531 \r
532 #if defined(ADC_USES_DMA)\r
533                 hwPtr->DMAE.R = 0x01;\r
534                 /* Enable DMA Transfer */\r
535                 hwPtr->DMAR[1].R = groupChannelIdMask;\r
536                 Dma_StartChannel(DMA_ADC_GROUP0_RESULT_CHANNEL);        /* Enable EDMA channel for ADC */\r
537 #endif\r
538 \r
539                 /* Enable Normal conversion */\r
540                 hwPtr->NCMR[1].R = groupChannelIdMask;\r
541 \r
542                 /* Enable Channel Interrupt */\r
543                 hwPtr->CIMR[1].R = groupChannelIdMask;\r
544 \r
545 #else\r
546                 uint32 groupChannelIdMask[3] = {0,0,0};\r
547 \r
548                 hwPtr->CTR[0].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH;\r
549                 hwPtr->CTR[0].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP;\r
550                 hwPtr->CTR[0].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP;\r
551                 hwPtr->CTR[1].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH;\r
552                 hwPtr->CTR[1].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP;\r
553                 hwPtr->CTR[1].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP;\r
554 //              hwPtr->CTR[2].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH;\r
555 //              hwPtr->CTR[2].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP;\r
556 //              hwPtr->CTR[2].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP;\r
557 \r
558                 for(uint8 i =0; i < groupPtr->numberOfChannels; i++)\r
559                 {\r
560 #if defined(CFG_MPC5668)\r
561                         if(groupPtr->channelList[i] <= 31){\r
562 #else\r
563                         if(groupPtr->channelList[i] <= 15){\r
564 #endif\r
565                                 groupChannelIdMask[0] |= (1 << groupPtr->channelList[i]);\r
566                         }else if((groupPtr->channelList[i] >= 32) && (groupPtr->channelList[i] <=47)){\r
567                                 groupChannelIdMask[1] |= (1 << (groupPtr->channelList[i] - 32));\r
568                         }else if((groupPtr->channelList[i] >= 64) && (groupPtr->channelList[i] <=95)){\r
569                                 groupChannelIdMask[2] |= (1 << (groupPtr->channelList[i] - 64));\r
570                         }\r
571                 }\r
572 \r
573                 /* Enable Normal conversion */\r
574                 hwPtr->NCMR[0].R = groupChannelIdMask[0];\r
575                 hwPtr->NCMR[1].R = groupChannelIdMask[1];\r
576 //              hwPtr->NCMR[2].R = groupChannelIdMask[2];\r
577 \r
578                 /* Enable Channel Interrupt */\r
579                 hwPtr->CIMR[0].R = groupChannelIdMask[0];\r
580                 hwPtr->CIMR[1].R = groupChannelIdMask[1];\r
581 //              hwPtr->CIMR[2].R = groupChannelIdMask[2];\r
582 #endif\r
583                 /* Clear interrupts */\r
584                 hwPtr->ISR.B.ECH = 1;\r
585                 /* Enable ECH interrupt */\r
586                 hwPtr->IMR.B.MSKECH = 1;\r
587 \r
588                 /* Trigger normal conversions for ADC0 */\r
589                 hwPtr->MCR.B.NSTART = 1;\r
590         }\r
591         else\r
592         {\r
593         /* Error have been set within Adc_CheckStartGroupConversion(). */\r
594         }\r
595 }\r
596 \r
597 void Adc_StopGroupConversion (Adc_GroupType group)\r
598 {\r
599   const Adc_ConfigType *AdcConfigPtr = Adc_GetControllerConfigPtrFromGroupId(group);\r
600   volatile struct ADC_tag *hwPtr = GET_HW_CONTROLLER(AdcConfigPtr->hwConfigPtr->hwUnitId);\r
601 \r
602   if (E_OK == Adc_CheckStopGroupConversion (adcState, AdcConfigPtr, group))\r
603   {\r
604         /* Disable trigger normal conversions for ADC0 */\r
605         hwPtr->MCR.B.NSTART = 0;\r
606 \r
607         /* Set group state to IDLE. */\r
608         AdcConfigPtr->groupConfigPtr[group%NOF_GROUP_PER_CONTROLLER].status->groupStatus = ADC_IDLE;\r
609 \r
610         /* Disable group notification if enabled. */\r
611     if(1 == AdcConfigPtr->groupConfigPtr[group%NOF_GROUP_PER_CONTROLLER].status->notifictionEnable){\r
612         Adc_DisableGroupNotification (group);\r
613     }\r
614   }\r
615   else\r
616   {\r
617         /* Error have been set within Adc_CheckStartGroupConversion(). */\r
618   }\r
619 }\r
620 #endif  /* endof #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON) */\r
621 \r
622 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)\r
623 void Adc_EnableGroupNotification (Adc_GroupType group)\r
624 {\r
625         Adc_EnableInternalGroupNotification(adcState, Adc_GetControllerConfigPtrFromGroupId(group), group);\r
626 }\r
627 \r
628 void Adc_DisableGroupNotification (Adc_GroupType group)\r
629 {\r
630         Adc_InternalDisableGroupNotification(adcState, Adc_GetControllerConfigPtrFromGroupId(group), group);\r
631 }\r
632 #endif\r
633 \r
634 Adc_StatusType Adc_GetGroupStatus (Adc_GroupType group)\r
635 {\r
636         return Adc_InternalGetGroupStatus(adcState, Adc_GetControllerConfigPtrFromGroupId(group), group);\r
637 }\r
638 \r