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