]> rtime.felk.cvut.cz Git - arc.git/blob - arch/ppc/mpc55xx/drivers/Adc_eQADC.c
Re-added generic callout stubs file for Dcm (with make rule).
[arc.git] / arch / ppc / mpc55xx / drivers / Adc_eQADC.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 #include <assert.h>\r
17 #include <stdlib.h>\r
18 //#include "System.h"\r
19 #include "mpc55xx.h"\r
20 #include "Modules.h"\r
21 #include "Mcu.h"\r
22 #include "Adc.h"\r
23 #include "Det.h"\r
24 #include "Os.h"\r
25 #include "isr.h"\r
26 #include "irq.h"\r
27 #include "arc.h"\r
28 #include "Adc_Internal.h"\r
29 \r
30 #define ADC_USES_DMA\r
31 #include "Dma.h"\r
32 \r
33 #if ( defined(ADC_USES_DMA) && !defined(USE_DMA) )\r
34         #error Adc is configured to use Dma but the module is not enabled.\r
35 #endif\r
36 \r
37 #define CCM_EOQ(x)        ((x)<<31)\r
38 #define CCM_PAUSE(x)      ((x)<<30)\r
39 #define CCM_BN(x)       ((x)<<25)\r
40 #define CCM_CAL(x)        ((x)<<24)\r
41 #define CCM_MESSAGE_TAG(x)    ((x)<<20)\r
42 #define CCM_LST(x)        ((x)<<18)\r
43 #define CCM_TSR(x)        ((x)<<17)\r
44 #define CCM_FMT(x)        ((x)<<16)\r
45 #define CCM_CHANNEL_NUMBER(x) ((x)<<8)\r
46 \r
47 #define CAL_CH(ch)  CCM_EOQ(0) | CCM_PAUSE(0) | CCM_BN(0) | CCM_CAL(0) | CCM_MESSAGE_TAG(0) | CCM_LST(ADC_CONVERSION_TIME_128_CLOCKS) | \\r
48           CCM_TSR(0) | CCM_FMT(0) | CCM_CHANNEL_NUMBER(ch)\r
49 \r
50 typedef union\r
51 {\r
52   vuint32_t R;\r
53   struct\r
54   {\r
55     vuint32_t EOQ:1;\r
56     vuint32_t PAUSE:1;\r
57     vuint32_t :4;\r
58     vuint32_t BN:1;\r
59     vuint32_t RW:1;\r
60     vuint32_t ADC_REG:16;\r
61     vuint32_t ADC_REG_ADDR:8;\r
62    } B;\r
63 }Adc_RegisterWriteType;\r
64 \r
65 typedef union\r
66 {\r
67   vuint32_t R;\r
68   struct\r
69   {\r
70     vuint32_t EOQ:1;\r
71     vuint32_t PAUSE:1;\r
72     vuint32_t :4;\r
73     vuint32_t BN:1;\r
74     vuint32_t RW:1;\r
75     vuint32_t MESSAGE_TAG:4;\r
76     vuint32_t :12;\r
77     vuint32_t ADC_REG_ADDR:8;\r
78    } B;\r
79 }Adc_RegisterReadType;\r
80 \r
81 typedef enum\r
82 {\r
83   ADC_EQADC_QUEUE_0,\r
84   ADC_EQADC_QUEUE_1,\r
85   ADC_EQADC_QUEUE_2,\r
86   ADC_EQADC_QUEUE_3,\r
87   ADC_EQADC_QUEUE_4,\r
88   ADC_EQADC_QUEUE_5,\r
89   ADC_EQADC_NBR_OF_QUEUES\r
90 }Adc_eQADCQueueType;\r
91 \r
92 typedef enum\r
93 {\r
94   EQADC_CFIFO_STATUS_IDLE = 0,\r
95   EQADC_CFIFO_STATUS_WAITINGFOR_TRIGGER = 0x2,\r
96   EQADC_CFIFO_STATUS_TRIGGERED = 0x3\r
97 }Adc_EQADCQueueStatusType;\r
98 \r
99 typedef int16_t Adc_EQADCRegister;\r
100 \r
101 typedef enum\r
102 {\r
103   ADC0_CR = 1,\r
104   ADC0_TSCR,\r
105   ADC0_TBCR,\r
106   ADC0_GCCR,\r
107   ADC0_OCCR\r
108 }Adc_EQADCRegisterType;\r
109 \r
110 /* Command queue for calibration sequence. See 31.5.6 in reference manual. */\r
111 const Adc_CommandType AdcCalibrationCommandQueue [] =\r
112 {\r
113   /* Four samples of 25 % of (VRh - VRl). */\r
114   {\r
115   .R = CAL_CH(44),\r
116   },\r
117   {\r
118   .R = CAL_CH(44),\r
119   },\r
120   {\r
121   .R = CAL_CH(44),\r
122   },\r
123   {\r
124   .R = CAL_CH(44),\r
125   },\r
126   /* Four samples of 75 % of (VRh - VRl). */\r
127   {\r
128     .R = CAL_CH(43),\r
129   },\r
130   {\r
131   .R = CAL_CH(43),\r
132   },\r
133   {\r
134   .R = CAL_CH(43),\r
135   },\r
136   {\r
137   .R = CAL_CH(43),\r
138   }\r
139 };\r
140 \r
141 /* DMA configuration for calibration sequence. */\r
142 const Dma_TcdType AdcCalibrationDMACommandConfig =\r
143 {\r
144   .SADDR = (uint32_t)AdcCalibrationCommandQueue,\r
145   .SMOD = 0,\r
146   .SSIZE = DMA_TRANSFER_SIZE_32BITS,\r
147   .DMOD = 0,\r
148   .DSIZE = DMA_TRANSFER_SIZE_32BITS,\r
149   .SOFF = sizeof(Adc_CommandType),\r
150   .NBYTESu.R = sizeof(Adc_CommandType),\r
151   .SLAST = 0,\r
152   .DADDR = (vuint32_t)&EQADC.CFPR[0].R,\r
153   .CITERE_LINK = 0,\r
154   .CITER = 0,\r
155   .DOFF = 0,\r
156   .DLAST_SGA = 0,\r
157   .BITERE_LINK = 0,\r
158   .BITER = 0,\r
159   .BWC = 0,\r
160   .MAJORLINKCH = 0,\r
161   .DONE = 0,\r
162   .ACTIVE = 0,\r
163   .MAJORE_LINK = 0,\r
164   .E_SG = 0,\r
165   .D_REQ = 1,\r
166   .INT_HALF = 0,\r
167   .INT_MAJ = 0,\r
168   .START = 0,\r
169 };\r
170 \r
171 const Dma_TcdType AdcCalibrationDMAResultConfig =\r
172 {\r
173   .SADDR = (vuint32_t)&EQADC.RFPR[0].R + 2,\r
174   .SMOD = 0,\r
175   .SSIZE = DMA_TRANSFER_SIZE_16BITS,\r
176   .DMOD = 0,\r
177   .DSIZE = DMA_TRANSFER_SIZE_16BITS,\r
178   .SOFF = 0,\r
179   .NBYTESu.R = sizeof(Adc_ValueGroupType),\r
180   .SLAST = 0,\r
181   .DADDR = 0, /* Dynamic address, written later. */\r
182   .CITERE_LINK = 0,\r
183   .CITER = 0,\r
184   .DOFF = sizeof(Adc_ValueGroupType),\r
185   .DLAST_SGA = 0,\r
186   .BITERE_LINK = 0,\r
187   .BITER = 0,\r
188   .BWC = 0,\r
189   .MAJORLINKCH = 0,\r
190   .DONE = 0,\r
191   .ACTIVE = 0,\r
192   .MAJORE_LINK = 0,\r
193   .E_SG = 0,\r
194   .D_REQ = 1,\r
195   .INT_HALF = 0,\r
196   .INT_MAJ = 0,\r
197   .START = 0\r
198 };\r
199 \r
200 /* Function prototypes. */\r
201 static void Adc_ConfigureEQADC (const Adc_ConfigType *ConfigPtr);\r
202 static void Adc_ConfigureEQADCInterrupts (void);\r
203 static void Adc_EQADCCalibrationSequence (void);\r
204 static void Adc_WriteEQADCRegister (Adc_EQADCRegisterType reg, Adc_EQADCRegister value);\r
205 static Adc_EQADCRegister Adc_ReadEQADCRegister (Adc_EQADCRegisterType reg);\r
206 \r
207 void Adc_GroupConversionComplete (Adc_GroupType group);\r
208 \r
209 /* static variable declarations */\r
210 static Adc_StateType adcState = ADC_UNINIT;\r
211 static const Adc_ConfigType *AdcConfigPtr;      /* Pointer to configuration structure. */\r
212 \r
213 #if (ADC_DEINIT_API == STD_ON)\r
214 void Adc_DeInit ()\r
215 {\r
216   Adc_eQADCQueueType queue;\r
217   Adc_GroupType group;\r
218   boolean queueStopped;\r
219 \r
220   if (E_OK == Adc_CheckDeInit(adcState, AdcConfigPtr))\r
221   {\r
222     /* Stop all queues. */\r
223     for (queue = ADC_EQADC_QUEUE_0; queue < ADC_EQADC_NBR_OF_QUEUES; queue++)\r
224     {\r
225       /* Disable queue. */\r
226       EQADC.CFCR[queue].B.MODE = 0;\r
227 \r
228       /* Wait for queue to enter idle state. */\r
229       queueStopped = FALSE;\r
230       /* TODO replace switch with bit pattern. */\r
231       while (!queueStopped)\r
232       {\r
233         switch (queue)\r
234         {\r
235         case ADC_EQADC_QUEUE_0:\r
236           queueStopped = (EQADC.CFSR.B.CFS0 == EQADC_CFIFO_STATUS_IDLE);\r
237           break;\r
238         case ADC_EQADC_QUEUE_1:\r
239           queueStopped = (EQADC.CFSR.B.CFS1 == EQADC_CFIFO_STATUS_IDLE);\r
240           break;\r
241         case ADC_EQADC_QUEUE_2:\r
242           queueStopped = (EQADC.CFSR.B.CFS2 == EQADC_CFIFO_STATUS_IDLE);\r
243           break;\r
244         case ADC_EQADC_QUEUE_3:\r
245           queueStopped = (EQADC.CFSR.B.CFS3 == EQADC_CFIFO_STATUS_IDLE);\r
246           break;\r
247         case ADC_EQADC_QUEUE_4:\r
248           queueStopped = (EQADC.CFSR.B.CFS4 == EQADC_CFIFO_STATUS_IDLE);\r
249           break;\r
250         case ADC_EQADC_QUEUE_5:\r
251           queueStopped = (EQADC.CFSR.B.CFS5 == EQADC_CFIFO_STATUS_IDLE);\r
252           break;\r
253         default :\r
254           /* We should never get here... Terminate loop. */\r
255           queueStopped = TRUE;\r
256           break;\r
257         }\r
258       }\r
259 \r
260       /* Disable eDMA requests for commands and results. */\r
261       EQADC.IDCR[queue].B.CFFS = 0;\r
262       EQADC.IDCR[queue].B.RFDS = 0;\r
263 \r
264       /* Disable FIFO fill requests. */\r
265       EQADC.IDCR[queue].B.CFFE = 0;\r
266       EQADC.IDCR[queue].B.RFDE = 0;\r
267 \r
268       /* Disable interrupts. */\r
269       EQADC.IDCR[queue].B.RFOIE = 0;\r
270       EQADC.IDCR[queue].B.CFUIE = 0;\r
271       EQADC.IDCR[queue].B.TORIE = 0;\r
272       EQADC.IDCR[queue].B.EOQIE = 0;\r
273     }\r
274 \r
275     /* Stop all DMA channels connected to EQADC. */\r
276     for (group = ADC_GROUP0; group < AdcConfigPtr->nbrOfGroups; group++)\r
277     {\r
278       Dma_StopChannel (AdcConfigPtr->groupConfigPtr [group].dmaCommandChannel);\r
279       Dma_StopChannel (AdcConfigPtr->groupConfigPtr [group].dmaResultChannel);\r
280 \r
281       /* Set group status to idle. */\r
282       AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;\r
283     }\r
284 \r
285     /* Disable EQADC. */\r
286     Adc_WriteEQADCRegister (ADC0_CR, 0);\r
287 \r
288     /* Clean internal status. */\r
289     AdcConfigPtr = (Adc_ConfigType *)NULL;\r
290     adcState = ADC_UNINIT;\r
291   }\r
292 }\r
293 #endif\r
294 \r
295 void Adc_Init (const Adc_ConfigType *ConfigPtr)\r
296 {\r
297   Adc_InternalChannelIdType channel;\r
298   Adc_InternalChannelIdType channelId;\r
299   Adc_GroupType group;\r
300   Adc_CommandType *commandQueue;\r
301   Adc_CommandType command;\r
302 \r
303   if (E_OK == Adc_CheckInit(adcState, ConfigPtr))\r
304   {\r
305     /* First of all, store the location of the configuration data. */\r
306     AdcConfigPtr = ConfigPtr;\r
307 \r
308     /* Start configuring the eQADC queues. */\r
309     for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)\r
310     {\r
311       /* Loop through all channels and make the command queue. */\r
312       for (channel = 0; channel < ConfigPtr->groupConfigPtr[group].numberOfChannels; channel++)\r
313       {\r
314         /* Get physical channel. */\r
315         channelId = ConfigPtr->groupConfigPtr[group].channelList[channel];\r
316 \r
317         commandQueue = ConfigPtr->groupConfigPtr[group].commandBuffer;\r
318 \r
319         /* Begin with empty command. */\r
320         command.R = 0;\r
321 \r
322         /* Physical channel number. */\r
323         command.B.CHANNEL_NUMBER = channelId;\r
324         /* Sample time. */\r
325         command.B.LST = ConfigPtr->channelConfigPtr [channel].adcChannelConvTime;\r
326         /* Calibration feature. */\r
327         command.B.CAL = ConfigPtr->channelConfigPtr [channel].adcChannelCalibrationEnable;\r
328         /* Result buffer FIFO. The number of groups must not be greater than the number of queues. */\r
329         command.B.MESSAGE_TAG = group;\r
330 \r
331         /* Write command to command queue. */\r
332         commandQueue [channel].R = command.R;\r
333 \r
334         /* Last channel in group. Write EOQ and configure eQADC FIFO. */\r
335         if (channel == (ConfigPtr->groupConfigPtr[group].numberOfChannels - 1))\r
336         {\r
337           commandQueue [channel].B.EOQ = 1;\r
338         }\r
339       }\r
340     }\r
341 \r
342     /* Enable ADC. */\r
343     Adc_ConfigureEQADC (ConfigPtr);\r
344 \r
345     /* Perform calibration of the ADC. */\r
346     Adc_EQADCCalibrationSequence ();\r
347 \r
348     /* Configure DMA channels. */\r
349     for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)\r
350     {\r
351       /* ADC307. */\r
352       ConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;\r
353 \r
354       Dma_ConfigureChannel ((Dma_TcdType *)ConfigPtr->groupConfigPtr [group].groupDMAResults, ConfigPtr->groupConfigPtr [group].dmaResultChannel);\r
355       Dma_ConfigureChannel ((Dma_TcdType *)ConfigPtr->groupConfigPtr [group].groupDMACommands, ConfigPtr->groupConfigPtr [group].dmaCommandChannel);\r
356     }\r
357 \r
358     /* Start DMA channels. */\r
359     for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)\r
360     {\r
361       /* Invalidate queues. */\r
362       EQADC.CFCR[group].B.CFINV = 1;\r
363 \r
364       Dma_StartChannel (ConfigPtr->groupConfigPtr [group].dmaResultChannel);\r
365       Dma_StartChannel (ConfigPtr->groupConfigPtr [group].dmaCommandChannel);\r
366     }\r
367 \r
368     Adc_ConfigureEQADCInterrupts ();\r
369 \r
370     /* Move on to INIT state. */\r
371     adcState = ADC_INIT;\r
372   }\r
373 }\r
374 \r
375 Std_ReturnType Adc_SetupResultBuffer (Adc_GroupType group, Adc_ValueGroupType *bufferPtr)\r
376 {\r
377   Std_ReturnType returnValue = E_NOT_OK;\r
378 \r
379   /* Check for development errors. */\r
380   if (E_OK == Adc_CheckSetupResultBuffer (adcState, AdcConfigPtr, group))\r
381   {\r
382     AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr = bufferPtr;\r
383     \r
384     returnValue = E_OK;\r
385   }\r
386 \r
387   return (returnValue);\r
388 }\r
389 \r
390 Adc_StreamNumSampleType Adc_GetStreamLastPointer(Adc_GroupType group, Adc_ValueGroupType** PtrToSamplePtr)\r
391 {\r
392         Adc_StreamNumSampleType nofSample = 0;\r
393         Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];\r
394         \r
395         /** @req ADC216 */\r
396         /* Check for development errors. */\r
397         if ( (E_OK == Adc_CheckGetStreamLastPointer (adcState, AdcConfigPtr, group)) &&\r
398                  (groupPtr->status->groupStatus != ADC_BUSY) )\r
399         {\r
400             /* Set resultPtr to application buffer. */\r
401                 if(groupPtr->status->currSampleCount > 0){\r
402                         *PtrToSamplePtr = &groupPtr->status->resultBufferPtr[groupPtr->status->currSampleCount-1];\r
403                 }\r
404 \r
405             if ((ADC_CONV_MODE_ONESHOT == groupPtr->conversionMode) &&\r
406                 (ADC_STREAM_COMPLETED  == groupPtr->status->groupStatus))\r
407             {\r
408                         /** @req ADC327. */\r
409                         groupPtr->status->groupStatus = ADC_IDLE;\r
410             }\r
411             else if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
412                      (ADC_ACCESS_MODE_STREAMING == groupPtr->accessMode) &&\r
413                      (ADC_STREAM_BUFFER_LINEAR == groupPtr->streamBufferMode) &&\r
414                      (ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus))\r
415             {\r
416                         /** @req ADC327. */\r
417                         groupPtr->status->groupStatus = ADC_IDLE;\r
418             }\r
419             else if ( (ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
420                       ((ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus) ||\r
421                        (ADC_COMPLETED           == groupPtr->status->groupStatus)) )\r
422             {\r
423                 /* Restart continous mode, and reset result buffer */\r
424                 if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
425                     (ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus))\r
426                 {\r
427                           /* Start continous conversion again */\r
428                         Adc_StartGroupConversion(group);\r
429                 }\r
430                         /** @req ADC326 */\r
431                         /** @req ADC328 */\r
432             }\r
433             else{/* Keep status. */}\r
434         }\r
435         else\r
436         {\r
437                 /* Some condition not met */\r
438                 *PtrToSamplePtr = NULL;\r
439         }\r
440 \r
441         return nofSample;\r
442 \r
443 }\r
444 \r
445 #if (ADC_READ_GROUP_API == STD_ON)\r
446 Std_ReturnType Adc_ReadGroup (Adc_GroupType group, Adc_ValueGroupType *dataBufferPtr)\r
447 {\r
448   Std_ReturnType returnValue = E_OK;\r
449   uint8_t channel;\r
450   Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];\r
451 \r
452   if (E_OK == Adc_CheckReadGroup (adcState, AdcConfigPtr, group))\r
453   {\r
454     /* Copy the result to application buffer. */\r
455     for (channel = 0; channel < groupPtr->numberOfChannels; channel++)\r
456         {\r
457                 if(groupPtr->status->currSampleCount > 0){\r
458                         dataBufferPtr[channel] = (&(groupPtr->status->resultBufferPtr[groupPtr->status->currSampleCount-1]))[channel];\r
459                 }else{\r
460                         dataBufferPtr[channel] = groupPtr->status->resultBufferPtr[channel];\r
461                 }\r
462         }\r
463 \r
464     if ((ADC_CONV_MODE_ONESHOT == groupPtr->conversionMode) &&\r
465         (ADC_STREAM_COMPLETED  == groupPtr->status->groupStatus))\r
466     {\r
467                 /** @req ADC330. */\r
468                 groupPtr->status->groupStatus = ADC_IDLE;\r
469     }\r
470     else if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
471              (ADC_STREAM_BUFFER_LINEAR == groupPtr->streamBufferMode) &&\r
472              (ADC_ACCESS_MODE_STREAMING == groupPtr->accessMode) &&\r
473              (ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus))\r
474     {\r
475                 /** @req ADC330. */\r
476                 groupPtr->status->groupStatus = ADC_IDLE;\r
477     }\r
478     else if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
479              ((ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus) ||\r
480               (ADC_COMPLETED           == groupPtr->status->groupStatus)))\r
481     {\r
482         /** @req ADC329 */\r
483       /* Restart continous mode, and reset result buffer */\r
484       if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&\r
485           (ADC_STREAM_COMPLETED    == groupPtr->status->groupStatus))\r
486       {\r
487                   /* Start continous conversion again */\r
488         Adc_StartGroupConversion(group);\r
489       }\r
490       /** @req ADC329 */\r
491       /** @req ADC331 */\r
492     }\r
493     else{/* Keep status. */}\r
494   }\r
495   else\r
496   {\r
497     /* An error have been raised from Adc_CheckReadGroup(). */\r
498     returnValue = E_NOT_OK;\r
499   }\r
500 \r
501   return (returnValue);\r
502 }\r
503 #endif\r
504 \r
505 void Adc_GroupConversionComplete (Adc_GroupType group)\r
506 {\r
507         Adc_GroupDefType *adcGroup = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];\r
508 \r
509   if(ADC_ACCESS_MODE_SINGLE == adcGroup->accessMode )\r
510   {\r
511           adcGroup->status->groupStatus = ADC_STREAM_COMPLETED;\r
512 \r
513     /* Disable trigger. */\r
514     EQADC.CFCR[group].B.MODE = 0;\r
515 \r
516           /* Call notification if enabled. */\r
517         #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)\r
518           if (adcGroup->status->notifictionEnable && adcGroup->groupCallback != NULL)\r
519           {\r
520                   adcGroup->groupCallback();\r
521           }\r
522         #endif\r
523   }\r
524   else\r
525   {\r
526         if(ADC_STREAM_BUFFER_LINEAR == adcGroup->streamBufferMode)\r
527         {\r
528                 adcGroup->status->currSampleCount++;\r
529                 if(adcGroup->status->currSampleCount < adcGroup->streamNumSamples)\r
530                 {\r
531                   adcGroup->status->currResultBufPtr += adcGroup->numberOfChannels;\r
532                   adcGroup->status->groupStatus = ADC_COMPLETED;\r
533 \r
534 #if defined (ADC_USES_DMA)\r
535                   /* Increase current result buffer ptr */\r
536                 Dma_ConfigureDestinationAddress((uint32_t)adcGroup->status->currResultBufPtr, adcGroup->dmaResultChannel);\r
537 #endif\r
538 \r
539                 /* Set single scan enable bit */\r
540                 EQADC.CFCR[group].B.SSE = 1;\r
541                 }\r
542                 else\r
543                 {\r
544                   /* All sample completed. */\r
545                   adcGroup->status->groupStatus = ADC_STREAM_COMPLETED;\r
546 \r
547       /* Disable trigger. */\r
548       EQADC.CFCR[group].B.MODE = 0;\r
549 \r
550                   /* Call notification if enabled. */\r
551                 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)\r
552                   if (adcGroup->status->notifictionEnable && adcGroup->groupCallback != NULL){\r
553                         adcGroup->groupCallback();\r
554                   }\r
555                 #endif\r
556                 }\r
557         }\r
558         else if(ADC_STREAM_BUFFER_CIRCULAR == adcGroup->streamBufferMode)\r
559         {\r
560                 adcGroup->status->currSampleCount++;\r
561                 if(adcGroup->status->currSampleCount < adcGroup->streamNumSamples)\r
562                 {\r
563                         adcGroup->status->currResultBufPtr += adcGroup->numberOfChannels;\r
564 #if defined (ADC_USES_DMA)\r
565                         /* Increase current result buffer ptr */\r
566                         Dma_ConfigureDestinationAddress((uint32_t)adcGroup->status->currResultBufPtr, adcGroup->dmaResultChannel);\r
567 #endif\r
568                         adcGroup->status->groupStatus = ADC_COMPLETED;\r
569 \r
570                         /* Set single scan enable bit */\r
571                         EQADC.CFCR[group].B.SSE = 1;\r
572                 }\r
573                 else\r
574                 {\r
575                   /* Sample completed. */\r
576 \r
577                   /* Disable trigger. */\r
578                   EQADC.CFCR[group].B.MODE = 0;\r
579 \r
580                   adcGroup->status->groupStatus = ADC_STREAM_COMPLETED;\r
581                   /* Call notification if enabled. */\r
582                 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)\r
583                   if (adcGroup->status->notifictionEnable && adcGroup->groupCallback != NULL)\r
584                   {\r
585                           adcGroup->groupCallback();\r
586                   }\r
587                 #endif\r
588                 }\r
589         }\r
590         else\r
591         {\r
592                 //nothing to do.\r
593         }\r
594   }\r
595 }\r
596 \r
597 void Adc_Group0ConversionComplete (void)\r
598 {\r
599   /* ISR for FIFO 0 end of queue. Clear interrupt flag.  */\r
600   EQADC.FISR[ADC_EQADC_QUEUE_0].B.EOQF = 1;\r
601   Adc_GroupConversionComplete(0);\r
602 }\r
603 void Adc_Group1ConversionComplete (void)\r
604 {\r
605   /* ISR for FIFO 0 end of queue. Clear interrupt flag.  */\r
606   EQADC.FISR[ADC_EQADC_QUEUE_1].B.EOQF = 1;\r
607   Adc_GroupConversionComplete(1);\r
608 }\r
609 void Adc_Group2ConversionComplete (void)\r
610 {\r
611   /* ISR for FIFO 0 end of queue. Clear interrupt flag.  */\r
612   EQADC.FISR[ADC_EQADC_QUEUE_2].B.EOQF = 1;\r
613   Adc_GroupConversionComplete(2);\r
614 }\r
615 void Adc_Group3ConversionComplete (void)\r
616 {\r
617   /* ISR for FIFO 0 end of queue. Clear interrupt flag.  */\r
618   EQADC.FISR[ADC_EQADC_QUEUE_3].B.EOQF = 1;\r
619   Adc_GroupConversionComplete(3);\r
620 }\r
621 void Adc_Group4ConversionComplete (void)\r
622 {\r
623   /* ISR for FIFO 0 end of queue. Clear interrupt flag.  */\r
624   EQADC.FISR[ADC_EQADC_QUEUE_4].B.EOQF = 1;\r
625   Adc_GroupConversionComplete(4);\r
626 }\r
627 void Adc_Group5ConversionComplete (void)\r
628 {\r
629   /* ISR for FIFO 0 end of queue. Clear interrupt flag.  */\r
630   EQADC.FISR[ADC_EQADC_QUEUE_5].B.EOQF = 1;\r
631   Adc_GroupConversionComplete(5);\r
632 }\r
633 \r
634 void Adc_EQADCError (void)\r
635 {\r
636   /* Something is wrong!! Check the cause of the error and try to correct it. */\r
637   if (EQADC.FISR[ADC_EQADC_QUEUE_0].B.TORF)\r
638   {\r
639     /* Trigger overrun on queue 0!! */\r
640     assert (0);\r
641   }\r
642   else if (EQADC.FISR[ADC_EQADC_QUEUE_1].B.TORF)\r
643   {\r
644     /* Trigger overrun on queue 1!! */\r
645     assert (0);\r
646   }\r
647   else if (EQADC.FISR[ADC_EQADC_QUEUE_0].B.CFUF)\r
648   {\r
649     /* Command underflow on queue 0!! */\r
650     assert (0);\r
651   }\r
652   else if (EQADC.FISR[ADC_EQADC_QUEUE_1].B.CFUF)\r
653   {\r
654     /* Command underflow on queue 1!! */\r
655     assert (0);\r
656   }\r
657   else if (EQADC.FISR[ADC_EQADC_QUEUE_0].B.RFOF)\r
658   {\r
659     /* Result overflow on queue 0!! */\r
660     assert (0);\r
661   }\r
662   else if (EQADC.FISR[ADC_EQADC_QUEUE_1].B.RFOF)\r
663   {\r
664     /* Result overflow on queue 1!! */\r
665     assert (0);\r
666   }\r
667   else\r
668   {\r
669     /* Something else... TODO What have we missed above */\r
670     assert(0);\r
671   }\r
672 }\r
673 \r
674 /* Helper macro to make sure that the qommand queue have\r
675  * executed the commands in the fifo.\r
676  * First check that the H/W negate the\r
677  * single scan bit and then wait for EOQ. */\r
678 #define WAIT_FOR_QUEUE_TO_FINISH(q) \\r
679   while (EQADC.FISR[q].B.SSS)             \\r
680   {                                       \\r
681     ;                                     \\r
682   }                                       \\r
683                                           \\r
684   while (!EQADC.FISR[q].B.EOQF)           \\r
685   {                                       \\r
686     ;                                     \\r
687   }\r
688 \r
689 static void Adc_WriteEQADCRegister (Adc_EQADCRegisterType reg, Adc_EQADCRegister value)\r
690 {\r
691   Adc_RegisterWriteType writeReg;\r
692   uint32_t temp, oldMode;\r
693 \r
694   writeReg.R = 0;\r
695 \r
696   /* Write command. */\r
697   writeReg.B.RW = 0;\r
698   writeReg.B.EOQ = 1;\r
699   writeReg.B.ADC_REG = value;\r
700   writeReg.B.ADC_REG_ADDR = reg;\r
701 \r
702   /* Invalidate queue. */\r
703   EQADC.CFCR[ADC_EQADC_QUEUE_0].B.CFINV = 1;\r
704 \r
705 \r
706   /* Write command through FIFO. */\r
707   EQADC.CFPR[ADC_EQADC_QUEUE_0].R = writeReg.R;\r
708 \r
709   /* Enable FIFO. */\r
710   oldMode = EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE;\r
711   EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE = ADC_CONV_MODE_ONESHOT;\r
712   EQADC.CFCR[ADC_EQADC_QUEUE_0].B.SSE = 1;\r
713 \r
714   /* Wait for command to be executed. */\r
715   WAIT_FOR_QUEUE_TO_FINISH(ADC_EQADC_QUEUE_0);\r
716 \r
717   /* Flush result buffer. */\r
718   temp = EQADC.RFPR[ADC_EQADC_QUEUE_0].R;\r
719   (void)temp;\r
720   EQADC.FISR[ADC_EQADC_QUEUE_0].B.EOQF = 1;\r
721 \r
722   EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE = oldMode;\r
723 \r
724 }\r
725 \r
726 static Adc_EQADCRegister Adc_ReadEQADCRegister (Adc_EQADCRegisterType reg)\r
727 {\r
728   Adc_RegisterReadType readReg;\r
729   Adc_EQADCRegister result;\r
730   uint32_t oldMode, dmaRequestEnable;\r
731 \r
732   readReg.R = 0;\r
733 \r
734   /* Read command. */\r
735   readReg.B.RW = 1;\r
736   readReg.B.EOQ = 1;\r
737   readReg.B.ADC_REG_ADDR = reg;\r
738   readReg.B.MESSAGE_TAG = ADC_EQADC_QUEUE_0;\r
739 \r
740   /* Make sure that DMA requests for command fill and result drain is disabled. */\r
741   if (EQADC.IDCR[ADC_EQADC_QUEUE_0].B.RFDE || EQADC.IDCR[ADC_EQADC_QUEUE_0].B.CFFE)\r
742   {\r
743     EQADC.IDCR[ADC_EQADC_QUEUE_0].B.CFFE = 0;\r
744     EQADC.IDCR[ADC_EQADC_QUEUE_0].B.RFDE = 0;\r
745 \r
746     /* Remember to enable requests again... */\r
747     dmaRequestEnable = TRUE;\r
748   }\r
749   else\r
750   {\r
751     dmaRequestEnable = FALSE;\r
752   }\r
753 \r
754   /* Invalidate queue. */\r
755   EQADC.CFCR[ADC_EQADC_QUEUE_0].B.CFINV = 1;\r
756 \r
757   /* Write command through FIFO. */\r
758   EQADC.CFPR[ADC_EQADC_QUEUE_0].R = readReg.R;\r
759 \r
760   /* Enable FIFO. */\r
761   oldMode = EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE;\r
762   EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE = ADC_CONV_MODE_ONESHOT;\r
763   EQADC.CFCR[ADC_EQADC_QUEUE_0].B.SSE = 1;\r
764 \r
765   /* Wait for command to be executed. */\r
766   WAIT_FOR_QUEUE_TO_FINISH(ADC_EQADC_QUEUE_0);\r
767 \r
768   /* Read result buffer. */\r
769   result = EQADC.RFPR[ADC_EQADC_QUEUE_0].R;\r
770   EQADC.FISR[ADC_EQADC_QUEUE_0].B.EOQF = 1;\r
771 \r
772   EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE = oldMode;\r
773 \r
774   if (dmaRequestEnable)\r
775   {\r
776     EQADC.IDCR[ADC_EQADC_QUEUE_0].B.CFFE = 1;\r
777     EQADC.IDCR[ADC_EQADC_QUEUE_0].B.RFDE = 1;\r
778   }\r
779   else\r
780   {\r
781     /* Do nothing. */\r
782   }\r
783   return (result);\r
784 }\r
785 static void  Adc_ConfigureEQADC (const Adc_ConfigType *ConfigPtr)\r
786 {\r
787   Adc_GroupType group;\r
788 \r
789   enum\r
790   {\r
791     ADC_ENABLE = 0x8000,\r
792   };\r
793   /* Enable ADC0. */\r
794   Adc_WriteEQADCRegister (ADC0_CR, (ADC_ENABLE | ConfigPtr->hwConfigPtr->adcPrescale));\r
795 \r
796   /* Disable time stamp timer. */\r
797   Adc_WriteEQADCRegister (ADC0_TSCR, 0);\r
798 \r
799   for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)\r
800   {\r
801     /* Enable eDMA requests for commands and results. */\r
802     EQADC.IDCR[group].B.CFFS = 1;\r
803     EQADC.IDCR[group].B.RFDS = 1;\r
804 \r
805     /* Invalidate FIFO. */\r
806     EQADC.CFCR[group].B.CFINV = 1;\r
807 \r
808     /* Enable FIFO fill requests. */\r
809     EQADC.IDCR[group].B.CFFE = 1;\r
810     EQADC.IDCR[group].B.RFDE = 1;\r
811   }\r
812 }\r
813 \r
814 void Adc_ConfigureEQADCInterrupts (void)\r
815 {\r
816   Adc_GroupType group;\r
817   ISR_INSTALL_ISR2( "Adc_Err", Adc_EQADCError, EQADC_FISR_OVER,     2, 0);\r
818   for (group = ADC_GROUP0; group < AdcConfigPtr->nbrOfGroups; group++)\r
819   {\r
820     /* Enable end of queue, queue overflow/underflow interrupts. Clear corresponding flags. */\r
821     EQADC.FISR[group].B.RFOF = 1;\r
822     EQADC.IDCR[group].B.RFOIE = 1;\r
823 \r
824     EQADC.FISR[group].B.CFUF = 1;\r
825     EQADC.IDCR[group].B.CFUIE = 1;\r
826 \r
827     EQADC.FISR[group].B.TORF = 1;\r
828     EQADC.IDCR[group].B.TORIE = 1;\r
829 \r
830     EQADC.FISR[group].B.EOQF = 1;\r
831     EQADC.IDCR[group].B.EOQIE = 1;\r
832     if(group == 0){\r
833         ISR_INSTALL_ISR2( "Adc_Grp0", Adc_Group0ConversionComplete, EQADC_FISR0_EOQF0,     2, 0);\r
834     }else if(group == 1){\r
835         ISR_INSTALL_ISR2( "Adc_Grp1", Adc_Group1ConversionComplete, EQADC_FISR1_EOQF1,     2, 0);\r
836         }else if(group == 2){\r
837                 ISR_INSTALL_ISR2( "Adc_Grp2", Adc_Group2ConversionComplete, EQADC_FISR2_EOQF2,     2, 0);\r
838         }else if(group == 3){\r
839                 ISR_INSTALL_ISR2( "Adc_Grp3", Adc_Group3ConversionComplete, EQADC_FISR3_EOQF3,     2, 0);\r
840         }else if(group == 4){\r
841                 ISR_INSTALL_ISR2( "Adc_Grp4", Adc_Group4ConversionComplete, EQADC_FISR4_EOQF4,     2, 0);\r
842         }else if(group == 5){\r
843                 ISR_INSTALL_ISR2( "Adc_Grp5", Adc_Group5ConversionComplete, EQADC_FISR5_EOQF5,     2, 0);\r
844         }\r
845   }\r
846 }\r
847 \r
848 #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)\r
849 void Adc_StartGroupConversion (Adc_GroupType group)\r
850 {\r
851         Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];\r
852 \r
853         /* Run development error check. */\r
854         if (E_OK == Adc_CheckStartGroupConversion (adcState, AdcConfigPtr, group))\r
855         {\r
856         /* Disable trigger. */\r
857         EQADC.CFCR[group].B.MODE = 0;\r
858 \r
859         /* Set group state to BUSY. */\r
860                 groupPtr->status->groupStatus = ADC_BUSY;\r
861 \r
862                 groupPtr->status->currSampleCount = 0;\r
863                 groupPtr->status->currResultBufPtr = groupPtr->status->resultBufferPtr; /* Set current result buffer */\r
864 \r
865                 Dma_ConfigureDestinationAddress((uint32_t)groupPtr->status->resultBufferPtr, groupPtr->dmaResultChannel);\r
866 \r
867                 /* Always use single shot in streaming mode */\r
868                 if( groupPtr->accessMode == ADC_ACCESS_MODE_STREAMING)\r
869                 {\r
870                         /* Set conversion mode. */\r
871                         EQADC.CFCR[group].B.MODE = ADC_CONV_MODE_ONESHOT;\r
872                         /* Set single scan enable bit if this group is one shot. */\r
873                         EQADC.CFCR[group].B.SSE = 1;\r
874                 }\r
875                 else\r
876                 {\r
877                         /* Set conversion mode. */\r
878                         EQADC.CFCR[group].B.MODE = groupPtr->conversionMode;\r
879                         /* Set single scan enable bit if this group is one shot. */\r
880                         if (AdcConfigPtr->groupConfigPtr[group].conversionMode == ADC_CONV_MODE_ONESHOT)\r
881                         {\r
882                           EQADC.CFCR[group].B.SSE = 1;\r
883                         }\r
884                 }\r
885         }\r
886         else\r
887         {\r
888         /* Error have been set within Adc_CheckStartGroupConversion(). */\r
889         }\r
890 }\r
891 \r
892 void Adc_StopGroupConversion (Adc_GroupType group)\r
893 {\r
894         if (E_OK == Adc_CheckStopGroupConversion (adcState, AdcConfigPtr, group))\r
895         {\r
896                 uint32 groupMask = 0x3 << (group * 2);\r
897                 /* Disable trigger normal conversions for ADC */\r
898                 EQADC.CFCR[group].B.MODE = 0;\r
899                 while((EQADC.CFSR.R & groupMask) != EQADC_CFIFO_STATUS_IDLE);\r
900 \r
901                 /* Invalidate FIFO. */\r
902                 EQADC.CFCR[group].B.CFINV = 1;\r
903 \r
904                 /* Set group state to IDLE. */\r
905                 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;\r
906 \r
907                 /* Disable group notification if enabled. */\r
908                 if(1 == AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable){\r
909                         Adc_DisableGroupNotification (group);\r
910                 }\r
911         }\r
912         else\r
913         {\r
914         /* Error have been set within Adc_CheckStartGroupConversion(). */\r
915         }\r
916 }\r
917 #endif\r
918 \r
919 static void Adc_EQADCCalibrationSequence (void)\r
920 {\r
921   Adc_ValueGroupType calibrationResult[sizeof(AdcCalibrationCommandQueue)/sizeof(AdcCalibrationCommandQueue[0])];\r
922   int32_t point25Average, point75Average, i;\r
923   Adc_EQADCRegister tempGCC, tempOCC;\r
924   enum\r
925   {\r
926     IDEAL_RES25 = 0x1000,\r
927     IDEAL_RES75 = 0x3000,\r
928   };\r
929 \r
930   /* Use group 0 DMA channel for calibration. */\r
931   Dma_ConfigureChannel ((Dma_TcdType *)&AdcCalibrationDMACommandConfig,DMA_ADC_GROUP0_COMMAND_CHANNEL);\r
932   Dma_ConfigureChannelTranferSize (sizeof(AdcCalibrationCommandQueue)/sizeof(AdcCalibrationCommandQueue[0]),\r
933                                            DMA_ADC_GROUP0_COMMAND_CHANNEL);\r
934   Dma_ConfigureChannelSourceCorr (-sizeof(AdcCalibrationCommandQueue), DMA_ADC_GROUP0_COMMAND_CHANNEL);\r
935 \r
936   Dma_ConfigureChannel ((Dma_TcdType *)&AdcCalibrationDMAResultConfig, DMA_ADC_GROUP0_RESULT_CHANNEL);\r
937   Dma_ConfigureChannelTranferSize (sizeof(calibrationResult)/sizeof(calibrationResult[0]),\r
938                                            DMA_ADC_GROUP0_RESULT_CHANNEL);\r
939   Dma_ConfigureChannelDestinationCorr (-sizeof(calibrationResult), DMA_ADC_GROUP0_RESULT_CHANNEL);\r
940   Dma_ConfigureDestinationAddress ((uint32_t)calibrationResult, DMA_ADC_GROUP0_RESULT_CHANNEL);\r
941 \r
942   EDMA.TCD[DMA_ADC_GROUP0_COMMAND_CHANNEL].D_REQ = 1;\r
943   EDMA.TCD[DMA_ADC_GROUP0_RESULT_CHANNEL].D_REQ = 1;\r
944 \r
945   /* Invalidate queues. */\r
946   EQADC.CFCR[ADC_EQADC_QUEUE_0].B.CFINV = 1;\r
947 \r
948   Dma_StartChannel (DMA_ADC_GROUP0_COMMAND_CHANNEL);\r
949   Dma_StartChannel (DMA_ADC_GROUP0_RESULT_CHANNEL);\r
950 \r
951   /* Start conversion. */\r
952   EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE = ADC_CONV_MODE_ONESHOT;\r
953   EQADC.CFCR[ADC_EQADC_QUEUE_0].B.SSE = 1;\r
954 \r
955   /* Wait for conversion to complete. */\r
956   while(!Dma_ChannelDone (DMA_ADC_GROUP0_RESULT_CHANNEL))\r
957   {\r
958     ;\r
959   }\r
960 \r
961   /* Stop DMA channels and write calibration data to ADC engine. */\r
962   EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE = ADC_CONV_MODE_DISABLED;\r
963   Dma_StopChannel (DMA_ADC_GROUP0_COMMAND_CHANNEL);\r
964   Dma_StopChannel (DMA_ADC_GROUP0_RESULT_CHANNEL);\r
965 \r
966   /* Calculate conversion factors and write to ADC. */\r
967   point25Average = 0;\r
968   point75Average = 0;\r
969   for (i = 0; i < sizeof(calibrationResult)/sizeof(calibrationResult[0] / 2); i++)\r
970   {\r
971     point25Average += calibrationResult[i];\r
972     point75Average += calibrationResult[i + sizeof(calibrationResult)/sizeof(calibrationResult[0]) / 2];\r
973   }\r
974 \r
975   /* Calculate average and correction slope and offset.  */\r
976   point25Average /= (sizeof(calibrationResult)/sizeof(calibrationResult[0]) / 2);\r
977   point75Average /= (sizeof(calibrationResult)/sizeof(calibrationResult[0]) / 2);\r
978 \r
979   tempGCC = ((IDEAL_RES75 - IDEAL_RES25) << 14) / (point75Average - point25Average);\r
980   tempOCC = IDEAL_RES75 - ((tempGCC * point75Average) >> 14) - 2;\r
981 \r
982   /* GCC field is only 15 bits. */\r
983   tempGCC = tempGCC & ~(1 << 15);\r
984 \r
985   /* OCC field is only 14 bits. */\r
986   tempOCC = tempOCC & ~(3 << 14);\r
987 \r
988   /* Write calibration data to ADC engine. */\r
989   Adc_WriteEQADCRegister (ADC0_GCCR, tempGCC);\r
990   Adc_WriteEQADCRegister (ADC0_OCCR, tempOCC);\r
991 \r
992   /* Read back and check calibration values. */\r
993   if (Adc_ReadEQADCRegister (ADC0_GCCR) != tempGCC)\r
994   {\r
995     assert (0);\r
996   }\r
997   else if (Adc_ReadEQADCRegister (ADC0_OCCR) != tempOCC)\r
998   {\r
999     assert (0);\r
1000   }\r
1001 }\r
1002 \r
1003 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)\r
1004 void Adc_EnableGroupNotification (Adc_GroupType group)\r
1005 {\r
1006         Adc_EnableInternalGroupNotification(adcState, AdcConfigPtr, group);\r
1007 }\r
1008 \r
1009 void Adc_DisableGroupNotification (Adc_GroupType group)\r
1010 {\r
1011         Adc_InternalDisableGroupNotification(adcState, AdcConfigPtr, group);\r
1012 }\r
1013 #endif\r
1014 \r
1015 Adc_StatusType Adc_GetGroupStatus (Adc_GroupType group)\r
1016 {\r
1017         return Adc_InternalGetGroupStatus(adcState, AdcConfigPtr, group);\r
1018 }\r
1019 \r
1020 \r