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