1 /* -------------------------------- Arctic Core ------------------------------
\r
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
\r
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
\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
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
14 * -------------------------------- Arctic Core ------------------------------*/
\r
18 //#include "System.h"
\r
19 #include "mpc55xx.h"
\r
20 #include "Modules.h"
\r
28 #include "Adc_Internal.h"
\r
30 #define ADC_USES_DMA
\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
37 #define ADC_GROUP0 0
\r
49 vuint32_t ADC_REG:16;
\r
50 vuint32_t ADC_REG_ADDR:8;
\r
52 }Adc_RegisterWriteType;
\r
64 vuint32_t MESSAGE_TAG:4;
\r
66 vuint32_t ADC_REG_ADDR:8;
\r
68 }Adc_RegisterReadType;
\r
78 ADC_EQADC_NBR_OF_QUEUES
\r
79 }Adc_eQADCQueueType;
\r
83 EQADC_CFIFO_STATUS_IDLE = 0,
\r
84 EQADC_CFIFO_STATUS_WAITINGFOR_TRIGGER = 0x2,
\r
85 EQADC_CFIFO_STATUS_TRIGGERED = 0x3
\r
86 }Adc_EQADCQueueStatusType;
\r
88 typedef int16_t Adc_EQADCRegister;
\r
97 }Adc_EQADCRegisterType;
\r
99 /* Command queue for calibration sequence. See 31.5.6 in reference manual. */
\r
100 const Adc_CommandType AdcCalibrationCommandQueue [] =
\r
102 /* Four samples of 25 % of (VRh - VRl). */
\r
104 .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
105 .B.CHANNEL_NUMBER = 44
\r
108 .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
109 .B.CHANNEL_NUMBER = 44
\r
112 .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
113 .B.CHANNEL_NUMBER = 44
\r
116 .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
117 .B.CHANNEL_NUMBER = 44
\r
119 /* Four samples of 75 % of (VRh - VRl). */
\r
121 .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
122 .B.CHANNEL_NUMBER = 43
\r
125 .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
126 .B.CHANNEL_NUMBER = 43
\r
129 .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
130 .B.CHANNEL_NUMBER = 43
\r
133 .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
134 .B.CHANNEL_NUMBER = 43
\r
138 /* DMA configuration for calibration sequence. */
\r
139 const Dma_TcdType AdcCalibrationDMACommandConfig =
\r
141 .SADDR = (uint32_t)AdcCalibrationCommandQueue,
\r
143 .SSIZE = DMA_TRANSFER_SIZE_32BITS,
\r
145 .DSIZE = DMA_TRANSFER_SIZE_32BITS,
\r
146 .SOFF = sizeof(Adc_CommandType),
\r
147 .NBYTESu.B.NBYTES = sizeof(Adc_CommandType),
\r
149 .DADDR = (vint32_t)&EQADC.CFPR[0].R,
\r
168 const Dma_TcdType AdcCalibrationDMAResultConfig =
\r
170 .SADDR = (vint32_t)&EQADC.RFPR[0].R + 2,
\r
172 .SSIZE = DMA_TRANSFER_SIZE_16BITS,
\r
174 .DSIZE = DMA_TRANSFER_SIZE_16BITS,
\r
176 .NBYTESu.B.NBYTES = sizeof(Adc_ValueGroupType),
\r
178 .DADDR = 0, /* Dynamic address, written later. */
\r
181 .DOFF = sizeof(Adc_ValueGroupType),
\r
197 /* Function prototypes. */
\r
198 static void Adc_ConfigureEQADC (const Adc_ConfigType *ConfigPtr);
\r
199 static void Adc_ConfigureEQADCInterrupts (void);
\r
200 static void Adc_EQADCCalibrationSequence (void);
\r
201 static void Adc_WriteEQADCRegister (Adc_EQADCRegisterType reg, Adc_EQADCRegister value);
\r
202 static Adc_EQADCRegister Adc_ReadEQADCRegister (Adc_EQADCRegisterType reg);
\r
204 void Adc_GroupConversionComplete (Adc_GroupType group);
\r
206 /* static variable declarations */
\r
207 static Adc_StateType adcState = ADC_UNINIT;
\r
208 static const Adc_ConfigType *AdcConfigPtr; /* Pointer to configuration structure. */
\r
210 #if (ADC_DEINIT_API == STD_ON)
\r
211 Std_ReturnType Adc_DeInit (const Adc_ConfigType *ConfigPtr)
\r
215 Adc_eQADCQueueType queue;
\r
216 Adc_GroupType group;
\r
217 boolean queueStopped;
\r
219 if (E_OK == Adc_CheckDeInit(adcState, ConfigPtr))
\r
221 /* Stop all queues. */
\r
222 for (queue = ADC_EQADC_QUEUE_0; queue < ADC_EQADC_NBR_OF_QUEUES; queue++)
\r
224 /* Disable queue. */
\r
225 EQADC.CFCR[queue].B.MODE = 0;
\r
227 /* Wait for queue to enter idle state. */
\r
228 queueStopped = FALSE;
\r
229 /* TODO replace switch with bit pattern. */
\r
230 while (!queueStopped)
\r
234 case ADC_EQADC_QUEUE_0:
\r
235 queueStopped = (EQADC.CFSR.B.CFS0 == EQADC_CFIFO_STATUS_IDLE);
\r
237 case ADC_EQADC_QUEUE_1:
\r
238 queueStopped = (EQADC.CFSR.B.CFS1 == EQADC_CFIFO_STATUS_IDLE);
\r
240 case ADC_EQADC_QUEUE_2:
\r
241 queueStopped = (EQADC.CFSR.B.CFS2 == EQADC_CFIFO_STATUS_IDLE);
\r
243 case ADC_EQADC_QUEUE_3:
\r
244 queueStopped = (EQADC.CFSR.B.CFS3 == EQADC_CFIFO_STATUS_IDLE);
\r
246 case ADC_EQADC_QUEUE_4:
\r
247 queueStopped = (EQADC.CFSR.B.CFS4 == EQADC_CFIFO_STATUS_IDLE);
\r
249 case ADC_EQADC_QUEUE_5:
\r
250 queueStopped = (EQADC.CFSR.B.CFS5 == EQADC_CFIFO_STATUS_IDLE);
\r
253 /* We should never get here... Terminate loop. */
\r
254 queueStopped = TRUE;
\r
259 /* Disable eDMA requests for commands and results. */
\r
260 EQADC.IDCR[queue].B.CFFS = 0;
\r
261 EQADC.IDCR[queue].B.RFDS = 0;
\r
263 /* Disable FIFO fill requests. */
\r
264 EQADC.IDCR[queue].B.CFFE = 0;
\r
265 EQADC.IDCR[queue].B.RFDE = 0;
\r
267 /* Disable interrupts. */
\r
268 EQADC.IDCR[queue].B.RFOIE = 0;
\r
269 EQADC.IDCR[queue].B.CFUIE = 0;
\r
270 EQADC.IDCR[queue].B.TORIE = 0;
\r
271 EQADC.IDCR[queue].B.EOQIE = 0;
\r
274 /* Stop all DMA channels connected to EQADC. */
\r
275 for (group = ADC_GROUP0; group < AdcConfigPtr->nbrOfGroups; group++)
\r
277 Dma_StopChannel (AdcConfigPtr->groupConfigPtr [group].dmaCommandChannel);
\r
278 Dma_StopChannel (AdcConfigPtr->groupConfigPtr [group].dmaResultChannel);
\r
280 /* Set group status to idle. */
\r
281 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\r
284 /* Disable EQADC. */
\r
285 Adc_WriteEQADCRegister (ADC0_CR, 0);
\r
287 /* Clean internal status. */
\r
288 AdcConfigPtr = (Adc_ConfigType *)NULL;
\r
289 adcState = ADC_UNINIT;
\r
295 Std_ReturnType Adc_Init (const Adc_ConfigType *ConfigPtr)
\r
297 Std_ReturnType returnValue;
\r
298 Adc_InternalChannelIdType channel;
\r
299 Adc_InternalChannelIdType channelId;
\r
300 Adc_GroupType group;
\r
301 Adc_CommandType *commandQueue;
\r
302 Adc_CommandType command;
\r
304 if (E_OK == Adc_CheckInit(adcState, ConfigPtr))
\r
306 /* First of all, store the location of the configuration data. */
\r
307 AdcConfigPtr = ConfigPtr;
\r
309 /* Start configuring the eQADC queues. */
\r
310 for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)
\r
312 /* Loop through all channels and make the command queue. */
\r
313 for (channel = 0; channel < ConfigPtr->groupConfigPtr[group].numberOfChannels; channel++)
\r
315 /* Get physical channel. */
\r
316 channelId = ConfigPtr->groupConfigPtr[group].channelList[channel];
\r
318 commandQueue = ConfigPtr->groupConfigPtr[group].commandBuffer;
\r
320 /* Begin with empty command. */
\r
323 /* Physical channel number. */
\r
324 command.B.CHANNEL_NUMBER = channelId;
\r
326 command.B.LST = ConfigPtr->channelConfigPtr [channel].adcChannelConvTime;
\r
327 /* Calibration feature. */
\r
328 command.B.CAL = ConfigPtr->channelConfigPtr [channel].adcChannelCalibrationEnable;
\r
329 /* Result buffer FIFO. The number of groups must not be greater than the number of queues. */
\r
330 command.B.MESSAGE_TAG = group;
\r
332 /* Write command to command queue. */
\r
333 commandQueue [channel].R = command.R;
\r
335 /* Last channel in group. Write EOQ and configure eQADC FIFO. */
\r
336 if (channel == (ConfigPtr->groupConfigPtr[group].numberOfChannels - 1))
\r
338 commandQueue [channel].B.EOQ = 1;
\r
344 Adc_ConfigureEQADC (ConfigPtr);
\r
346 /* Perform calibration of the ADC. */
\r
347 Adc_EQADCCalibrationSequence ();
\r
349 /* Configure DMA channels. */
\r
350 for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)
\r
353 ConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\r
355 Dma_ConfigureChannel ((Dma_TcdType *)ConfigPtr->groupConfigPtr [group].groupDMAResults, ConfigPtr->groupConfigPtr [group].dmaResultChannel);
\r
356 Dma_ConfigureChannel ((Dma_TcdType *)ConfigPtr->groupConfigPtr [group].groupDMACommands, ConfigPtr->groupConfigPtr [group].dmaCommandChannel);
\r
359 /* Start DMA channels. */
\r
360 for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)
\r
362 /* Invalidate queues. */
\r
363 EQADC.CFCR[group].B.CFINV = 1;
\r
365 Dma_StartChannel (ConfigPtr->groupConfigPtr [group].dmaResultChannel);
\r
366 Dma_StartChannel (ConfigPtr->groupConfigPtr [group].dmaCommandChannel);
\r
369 Adc_ConfigureEQADCInterrupts ();
\r
371 /* Move on to INIT state. */
\r
372 adcState = ADC_INIT;
\r
373 returnValue = E_OK;
\r
377 returnValue = E_NOT_OK;
\r
380 return (returnValue);
\r
383 Std_ReturnType Adc_SetupResultBuffer (Adc_GroupType group, Adc_ValueGroupType *bufferPtr)
\r
385 Std_ReturnType returnValue = E_NOT_OK;
\r
387 /* Check for development errors. */
\r
388 if (E_OK == Adc_CheckSetupResultBuffer (AdcConfigPtr, group))
\r
390 AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr = bufferPtr;
\r
392 returnValue = E_OK;
\r
395 return (returnValue);
\r
398 Adc_StreamNumSampleType Adc_GetStreamLastPointer(Adc_GroupType group, Adc_ValueGroupType** PtrToSamplePtr)
\r
400 Adc_StreamNumSampleType nofSample = 0;
\r
401 Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];
\r
404 /* Check for development errors. */
\r
405 if ( (E_OK == Adc_CheckGetStreamLastPointer (adcState, AdcConfigPtr, group)) &&
\r
406 (groupPtr->status->groupStatus != ADC_BUSY) )
\r
408 /* Set resultPtr to application buffer. */
\r
409 if(groupPtr->status->currSampleCount > 0){
\r
410 *PtrToSamplePtr = &groupPtr->status->resultBufferPtr[groupPtr->status->currSampleCount-1];
\r
413 if ((ADC_CONV_MODE_ONESHOT == groupPtr->conversionMode) &&
\r
414 (ADC_STREAM_COMPLETED == groupPtr->status->groupStatus))
\r
416 /** @req ADC327. */
\r
417 groupPtr->status->groupStatus = ADC_IDLE;
\r
419 else if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&
\r
420 (ADC_ACCESS_MODE_STREAMING == groupPtr->accessMode) &&
\r
421 (ADC_STREAM_BUFFER_LINEAR == groupPtr->streamBufferMode) &&
\r
422 (ADC_STREAM_COMPLETED == groupPtr->status->groupStatus))
\r
424 /** @req ADC327. */
\r
425 groupPtr->status->groupStatus = ADC_IDLE;
\r
427 else if ( (ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&
\r
428 ((ADC_STREAM_COMPLETED == groupPtr->status->groupStatus) ||
\r
429 (ADC_COMPLETED == groupPtr->status->groupStatus)) )
\r
431 /* Restart continous mode, and reset result buffer */
\r
432 if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&
\r
433 (ADC_STREAM_COMPLETED == groupPtr->status->groupStatus))
\r
435 /* Start continous conversion again */
\r
436 Adc_StartGroupConversion(group);
\r
441 else{/* Keep status. */}
\r
445 /* Some condition not met */
\r
446 *PtrToSamplePtr = NULL;
\r
453 #if (ADC_READ_GROUP_API == STD_ON)
\r
454 Std_ReturnType Adc_ReadGroup (Adc_GroupType group, Adc_ValueGroupType *dataBufferPtr)
\r
456 Std_ReturnType returnValue = E_OK;
\r
458 Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];
\r
460 if (E_OK == Adc_CheckReadGroup (adcState, AdcConfigPtr, group))
\r
462 /* Copy the result to application buffer. */
\r
463 for (channel = 0; channel < groupPtr->numberOfChannels; channel++)
\r
465 if(groupPtr->status->currSampleCount > 0){
\r
466 dataBufferPtr[channel] = (&(groupPtr->status->resultBufferPtr[groupPtr->status->currSampleCount-1]))[channel];
\r
468 dataBufferPtr[channel] = groupPtr->status->resultBufferPtr[channel];
\r
472 if ((ADC_CONV_MODE_ONESHOT == groupPtr->conversionMode) &&
\r
473 (ADC_STREAM_COMPLETED == groupPtr->status->groupStatus))
\r
475 /** @req ADC330. */
\r
476 groupPtr->status->groupStatus = ADC_IDLE;
\r
478 else if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&
\r
479 (ADC_STREAM_BUFFER_LINEAR == groupPtr->streamBufferMode) &&
\r
480 (ADC_ACCESS_MODE_STREAMING == groupPtr->accessMode) &&
\r
481 (ADC_STREAM_COMPLETED == groupPtr->status->groupStatus))
\r
483 /** @req ADC330. */
\r
484 groupPtr->status->groupStatus = ADC_IDLE;
\r
486 else if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&
\r
487 ((ADC_STREAM_COMPLETED == groupPtr->status->groupStatus) ||
\r
488 (ADC_COMPLETED == groupPtr->status->groupStatus)))
\r
491 /* Restart continous mode, and reset result buffer */
\r
492 if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) &&
\r
493 (ADC_STREAM_COMPLETED == groupPtr->status->groupStatus))
\r
495 /* Start continous conversion again */
\r
496 Adc_StartGroupConversion(group);
\r
501 else{/* Keep status. */}
\r
505 /* An error have been raised from Adc_CheckReadGroup(). */
\r
506 returnValue = E_NOT_OK;
\r
509 return (returnValue);
\r
513 void Adc_GroupConversionComplete (Adc_GroupType group)
\r
515 Adc_GroupDefType *adcGroup = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];
\r
517 if(ADC_ACCESS_MODE_SINGLE == adcGroup->accessMode )
\r
519 adcGroup->status->groupStatus = ADC_STREAM_COMPLETED;
\r
520 /* Call notification if enabled. */
\r
521 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
\r
522 if (adcGroup->status->notifictionEnable && adcGroup->groupCallback != NULL)
\r
524 adcGroup->groupCallback();
\r
527 /* Disable trigger. */
\r
528 EQADC.CFCR[group].B.MODE = 0;
\r
532 if(ADC_STREAM_BUFFER_LINEAR == adcGroup->streamBufferMode)
\r
534 adcGroup->status->currSampleCount++;
\r
535 if(adcGroup->status->currSampleCount < adcGroup->streamNumSamples)
\r
537 adcGroup->status->currResultBufPtr += adcGroup->numberOfChannels;
\r
538 adcGroup->status->groupStatus = ADC_COMPLETED;
\r
540 #if defined (ADC_USES_DMA)
\r
541 /* Increase current result buffer ptr */
\r
542 Dma_ConfigureDestinationAddress((uint32_t)adcGroup->status->currResultBufPtr, adcGroup->dmaResultChannel);
\r
545 /* Set single scan enable bit */
\r
546 EQADC.CFCR[group].B.SSE = 1;
\r
550 /* All sample completed. */
\r
551 adcGroup->status->groupStatus = ADC_STREAM_COMPLETED;
\r
553 /* Call notification if enabled. */
\r
554 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
\r
555 if (adcGroup->status->notifictionEnable && adcGroup->groupCallback != NULL){
\r
556 adcGroup->groupCallback();
\r
559 /* Disable trigger. */
\r
560 EQADC.CFCR[group].B.MODE = 0;
\r
563 else if(ADC_STREAM_BUFFER_CIRCULAR == adcGroup->streamBufferMode)
\r
565 adcGroup->status->currSampleCount++;
\r
566 if(adcGroup->status->currSampleCount < adcGroup->streamNumSamples)
\r
568 adcGroup->status->currResultBufPtr += adcGroup->numberOfChannels;
\r
569 #if defined (ADC_USES_DMA)
\r
570 /* Increase current result buffer ptr */
\r
571 Dma_ConfigureDestinationAddress((uint32_t)adcGroup->status->currResultBufPtr, adcGroup->dmaResultChannel);
\r
573 adcGroup->status->groupStatus = ADC_COMPLETED;
\r
575 /* Set single scan enable bit */
\r
576 EQADC.CFCR[group].B.SSE = 1;
\r
580 /* Sample completed. */
\r
581 /* Disable trigger. */
\r
582 EQADC.CFCR[group].B.MODE = 0;
\r
583 adcGroup->status->groupStatus = ADC_STREAM_COMPLETED;
\r
584 /* Call notification if enabled. */
\r
585 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
\r
586 if (adcGroup->status->notifictionEnable && adcGroup->groupCallback != NULL)
\r
588 adcGroup->groupCallback();
\r
600 void Adc_Group0ConversionComplete (void)
\r
602 /* ISR for FIFO 0 end of queue. Clear interrupt flag. */
\r
603 EQADC.FISR[ADC_EQADC_QUEUE_0].B.EOQF = 1;
\r
604 Adc_GroupConversionComplete(0);
\r
606 void Adc_Group1ConversionComplete (void)
\r
608 /* ISR for FIFO 0 end of queue. Clear interrupt flag. */
\r
609 EQADC.FISR[ADC_EQADC_QUEUE_1].B.EOQF = 1;
\r
610 Adc_GroupConversionComplete(1);
\r
612 void Adc_Group2ConversionComplete (void)
\r
614 /* ISR for FIFO 0 end of queue. Clear interrupt flag. */
\r
615 EQADC.FISR[ADC_EQADC_QUEUE_2].B.EOQF = 1;
\r
616 Adc_GroupConversionComplete(2);
\r
618 void Adc_Group3ConversionComplete (void)
\r
620 /* ISR for FIFO 0 end of queue. Clear interrupt flag. */
\r
621 EQADC.FISR[ADC_EQADC_QUEUE_3].B.EOQF = 1;
\r
622 Adc_GroupConversionComplete(3);
\r
624 void Adc_Group4ConversionComplete (void)
\r
626 /* ISR for FIFO 0 end of queue. Clear interrupt flag. */
\r
627 EQADC.FISR[ADC_EQADC_QUEUE_4].B.EOQF = 1;
\r
628 Adc_GroupConversionComplete(4);
\r
630 void Adc_Group5ConversionComplete (void)
\r
632 /* ISR for FIFO 0 end of queue. Clear interrupt flag. */
\r
633 EQADC.FISR[ADC_EQADC_QUEUE_5].B.EOQF = 1;
\r
634 Adc_GroupConversionComplete(5);
\r
637 void Adc_EQADCError (void)
\r
639 /* Something is wrong!! Check the cause of the error and try to correct it. */
\r
640 if (EQADC.FISR[ADC_EQADC_QUEUE_0].B.TORF)
\r
642 /* Trigger overrun on queue 0!! */
\r
645 else if (EQADC.FISR[ADC_EQADC_QUEUE_1].B.TORF)
\r
647 /* Trigger overrun on queue 1!! */
\r
650 else if (EQADC.FISR[ADC_EQADC_QUEUE_0].B.CFUF)
\r
652 /* Command underflow on queue 0!! */
\r
655 else if (EQADC.FISR[ADC_EQADC_QUEUE_1].B.CFUF)
\r
657 /* Command underflow on queue 1!! */
\r
660 else if (EQADC.FISR[ADC_EQADC_QUEUE_0].B.RFOF)
\r
662 /* Result overflow on queue 0!! */
\r
665 else if (EQADC.FISR[ADC_EQADC_QUEUE_1].B.RFOF)
\r
667 /* Result overflow on queue 1!! */
\r
672 /* Something else... TODO What have we missed above */
\r
677 /* Helper macro to make sure that the qommand queue have
\r
678 * executed the commands in the fifo.
\r
679 * First check that the H/W negate the
\r
680 * single scan bit and then wait for EOQ. */
\r
681 #define WAIT_FOR_QUEUE_TO_FINISH(q) \
\r
682 while (EQADC.FISR[q].B.SSS) \
\r
687 while (!EQADC.FISR[q].B.EOQF) \
\r
692 static void Adc_WriteEQADCRegister (Adc_EQADCRegisterType reg, Adc_EQADCRegister value)
\r
694 Adc_RegisterWriteType writeReg;
\r
695 uint32_t temp, oldMode;
\r
699 /* Write command. */
\r
701 writeReg.B.EOQ = 1;
\r
702 writeReg.B.ADC_REG = value;
\r
703 writeReg.B.ADC_REG_ADDR = reg;
\r
705 /* Invalidate queue. */
\r
706 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.CFINV = 1;
\r
709 /* Write command through FIFO. */
\r
710 EQADC.CFPR[ADC_EQADC_QUEUE_0].R = writeReg.R;
\r
713 oldMode = EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE;
\r
714 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE = ADC_CONV_MODE_ONESHOT;
\r
715 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.SSE = 1;
\r
717 /* Wait for command to be executed. */
\r
718 WAIT_FOR_QUEUE_TO_FINISH(ADC_EQADC_QUEUE_0);
\r
720 /* Flush result buffer. */
\r
721 temp = EQADC.RFPR[ADC_EQADC_QUEUE_0].R;
\r
722 EQADC.FISR[ADC_EQADC_QUEUE_0].B.EOQF = 1;
\r
724 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE = oldMode;
\r
728 static Adc_EQADCRegister Adc_ReadEQADCRegister (Adc_EQADCRegisterType reg)
\r
730 Adc_RegisterReadType readReg;
\r
731 Adc_EQADCRegister result;
\r
732 uint32_t oldMode, dmaRequestEnable;
\r
736 /* Read command. */
\r
739 readReg.B.ADC_REG_ADDR = reg;
\r
740 readReg.B.MESSAGE_TAG = ADC_EQADC_QUEUE_0;
\r
742 /* Make sure that DMA requests for command fill and result drain is disabled. */
\r
743 if (EQADC.IDCR[ADC_EQADC_QUEUE_0].B.RFDE || EQADC.IDCR[ADC_EQADC_QUEUE_0].B.CFFE)
\r
745 EQADC.IDCR[ADC_EQADC_QUEUE_0].B.CFFE = 0;
\r
746 EQADC.IDCR[ADC_EQADC_QUEUE_0].B.RFDE = 0;
\r
748 /* Remember to enable requests again... */
\r
749 dmaRequestEnable = TRUE;
\r
753 dmaRequestEnable = FALSE;
\r
756 /* Invalidate queue. */
\r
757 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.CFINV = 1;
\r
759 /* Write command through FIFO. */
\r
760 EQADC.CFPR[ADC_EQADC_QUEUE_0].R = readReg.R;
\r
763 oldMode = EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE;
\r
764 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE = ADC_CONV_MODE_ONESHOT;
\r
765 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.SSE = 1;
\r
767 /* Wait for command to be executed. */
\r
768 WAIT_FOR_QUEUE_TO_FINISH(ADC_EQADC_QUEUE_0);
\r
770 /* Read result buffer. */
\r
771 result = EQADC.RFPR[ADC_EQADC_QUEUE_0].R;
\r
772 EQADC.FISR[ADC_EQADC_QUEUE_0].B.EOQF = 1;
\r
774 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE = oldMode;
\r
776 if (dmaRequestEnable)
\r
778 EQADC.IDCR[ADC_EQADC_QUEUE_0].B.CFFE = 1;
\r
779 EQADC.IDCR[ADC_EQADC_QUEUE_0].B.RFDE = 1;
\r
787 static void Adc_ConfigureEQADC (const Adc_ConfigType *ConfigPtr)
\r
789 Adc_GroupType group;
\r
793 ADC_ENABLE = 0x8000,
\r
796 Adc_WriteEQADCRegister (ADC0_CR, (ADC_ENABLE | ConfigPtr->hwConfigPtr->adcPrescale));
\r
798 /* Disable time stamp timer. */
\r
799 Adc_WriteEQADCRegister (ADC0_TSCR, 0);
\r
801 for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)
\r
803 /* Enable eDMA requests for commands and results. */
\r
804 EQADC.IDCR[group].B.CFFS = 1;
\r
805 EQADC.IDCR[group].B.RFDS = 1;
\r
807 /* Invalidate FIFO. */
\r
808 EQADC.CFCR[group].B.CFINV = 1;
\r
810 /* Enable FIFO fill requests. */
\r
811 EQADC.IDCR[group].B.CFFE = 1;
\r
812 EQADC.IDCR[group].B.RFDE = 1;
\r
816 void Adc_ConfigureEQADCInterrupts (void)
\r
818 Adc_GroupType group;
\r
819 ISR_INSTALL_ISR2( "Adc_Err", Adc_EQADCError, EQADC_FISR_OVER, 2, 0);
\r
820 for (group = ADC_GROUP0; group < AdcConfigPtr->nbrOfGroups; group++)
\r
822 /* Enable end of queue, queue overflow/underflow interrupts. Clear corresponding flags. */
\r
823 EQADC.FISR[group].B.RFOF = 1;
\r
824 EQADC.IDCR[group].B.RFOIE = 1;
\r
826 EQADC.FISR[group].B.CFUF = 1;
\r
827 EQADC.IDCR[group].B.CFUIE = 1;
\r
829 EQADC.FISR[group].B.TORF = 1;
\r
830 EQADC.IDCR[group].B.TORIE = 1;
\r
832 EQADC.FISR[group].B.EOQF = 1;
\r
833 EQADC.IDCR[group].B.EOQIE = 1;
\r
835 ISR_INSTALL_ISR2( "Adc_Grp0", Adc_Group0ConversionComplete, EQADC_FISR0_EOQF0, 2, 0);
\r
836 }else if(group == 1){
\r
837 ISR_INSTALL_ISR2( "Adc_Grp1", Adc_Group1ConversionComplete, EQADC_FISR1_EOQF1, 2, 0);
\r
838 }else if(group == 2){
\r
839 ISR_INSTALL_ISR2( "Adc_Grp2", Adc_Group2ConversionComplete, EQADC_FISR2_EOQF2, 2, 0);
\r
840 }else if(group == 3){
\r
841 ISR_INSTALL_ISR2( "Adc_Grp3", Adc_Group3ConversionComplete, EQADC_FISR3_EOQF3, 2, 0);
\r
842 }else if(group == 4){
\r
843 ISR_INSTALL_ISR2( "Adc_Grp4", Adc_Group4ConversionComplete, EQADC_FISR4_EOQF4, 2, 0);
\r
844 }else if(group == 5){
\r
845 ISR_INSTALL_ISR2( "Adc_Grp5", Adc_Group5ConversionComplete, EQADC_FISR5_EOQF5, 2, 0);
\r
850 #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)
\r
851 void Adc_StartGroupConversion (Adc_GroupType group)
\r
853 Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];
\r
855 /* Run development error check. */
\r
856 if (E_OK == Adc_CheckStartGroupConversion (adcState, AdcConfigPtr, group))
\r
858 /* Disable trigger. */
\r
859 EQADC.CFCR[group].B.MODE = 0;
\r
861 /* Set group state to BUSY. */
\r
862 groupPtr->status->groupStatus = ADC_BUSY;
\r
864 groupPtr->status->currSampleCount = 0;
\r
865 groupPtr->status->currResultBufPtr = groupPtr->status->resultBufferPtr; /* Set current result buffer */
\r
867 Dma_ConfigureDestinationAddress((uint32_t)groupPtr->status->resultBufferPtr, groupPtr->dmaResultChannel);
\r
869 /* Always use single shot in streaming mode */
\r
870 if( groupPtr->accessMode == ADC_ACCESS_MODE_STREAMING)
\r
872 /* Set conversion mode. */
\r
873 EQADC.CFCR[group].B.MODE = ADC_CONV_MODE_ONESHOT;
\r
874 /* Set single scan enable bit if this group is one shot. */
\r
875 EQADC.CFCR[group].B.SSE = 1;
\r
879 /* Set conversion mode. */
\r
880 EQADC.CFCR[group].B.MODE = groupPtr->conversionMode;
\r
881 /* Set single scan enable bit if this group is one shot. */
\r
882 if (AdcConfigPtr->groupConfigPtr[group].conversionMode == ADC_CONV_MODE_ONESHOT)
\r
884 EQADC.CFCR[group].B.SSE = 1;
\r
890 /* Error have been set within Adc_CheckStartGroupConversion(). */
\r
894 void Adc_StopGroupConversion (Adc_GroupType group)
\r
896 if (E_OK == Adc_CheckStopGroupConversion (adcState, AdcConfigPtr, group))
\r
898 uint32 groupMask = 0x3 << (group * 2);
\r
899 /* Disable trigger normal conversions for ADC */
\r
900 EQADC.CFCR[group].B.MODE = 0;
\r
901 while((EQADC.CFSR.R & groupMask) != EQADC_CFIFO_STATUS_IDLE);
\r
903 /* Invalidate FIFO. */
\r
904 EQADC.CFCR[group].B.CFINV = 1;
\r
906 /* Set group state to IDLE. */
\r
907 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\r
909 /* Disable group notification if enabled. */
\r
910 if(1 == AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable){
\r
911 Adc_DisableGroupNotification (group);
\r
916 /* Error have been set within Adc_CheckStartGroupConversion(). */
\r
921 static void Adc_EQADCCalibrationSequence (void)
\r
923 Adc_ValueGroupType calibrationResult[sizeof(AdcCalibrationCommandQueue)/sizeof(AdcCalibrationCommandQueue[0])];
\r
924 int32_t point25Average, point75Average, i;
\r
925 Adc_EQADCRegister tempGCC, tempOCC;
\r
928 IDEAL_RES25 = 0x1000,
\r
929 IDEAL_RES75 = 0x3000,
\r
932 /* Use group 0 DMA channel for calibration. */
\r
933 Dma_ConfigureChannel ((Dma_TcdType *)&AdcCalibrationDMACommandConfig,DMA_ADC_GROUP0_COMMAND_CHANNEL);
\r
934 Dma_ConfigureChannelTranferSize (sizeof(AdcCalibrationCommandQueue)/sizeof(AdcCalibrationCommandQueue[0]),
\r
935 DMA_ADC_GROUP0_COMMAND_CHANNEL);
\r
936 Dma_ConfigureChannelSourceCorr (-sizeof(AdcCalibrationCommandQueue), DMA_ADC_GROUP0_COMMAND_CHANNEL);
\r
938 Dma_ConfigureChannel ((Dma_TcdType *)&AdcCalibrationDMAResultConfig, DMA_ADC_GROUP0_RESULT_CHANNEL);
\r
939 Dma_ConfigureChannelTranferSize (sizeof(calibrationResult)/sizeof(calibrationResult[0]),
\r
940 DMA_ADC_GROUP0_RESULT_CHANNEL);
\r
941 Dma_ConfigureChannelDestinationCorr (-sizeof(calibrationResult), DMA_ADC_GROUP0_RESULT_CHANNEL);
\r
942 Dma_ConfigureDestinationAddress ((uint32_t)calibrationResult, DMA_ADC_GROUP0_RESULT_CHANNEL);
\r
944 /* Invalidate queues. */
\r
945 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.CFINV = 1;
\r
947 Dma_StartChannel (DMA_ADC_GROUP0_COMMAND_CHANNEL);
\r
948 Dma_StartChannel (DMA_ADC_GROUP0_RESULT_CHANNEL);
\r
950 /* Start conversion. */
\r
951 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE = ADC_CONV_MODE_ONESHOT;
\r
952 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.SSE = 1;
\r
954 /* Wait for conversion to complete. */
\r
955 while(!Dma_ChannelDone (DMA_ADC_GROUP0_RESULT_CHANNEL))
\r
960 /* Stop DMA channels and write calibration data to ADC engine. */
\r
961 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE = ADC_CONV_MODE_DISABLED;
\r
962 Dma_StopChannel (DMA_ADC_GROUP0_COMMAND_CHANNEL);
\r
963 Dma_StopChannel (DMA_ADC_GROUP0_RESULT_CHANNEL);
\r
965 /* Calculate conversion factors and write to ADC. */
\r
966 point25Average = 0;
\r
967 point75Average = 0;
\r
968 for (i = 0; i < sizeof(calibrationResult)/sizeof(calibrationResult[0] / 2); i++)
\r
970 point25Average += calibrationResult[i];
\r
971 point75Average += calibrationResult[i + sizeof(calibrationResult)/sizeof(calibrationResult[0]) / 2];
\r
974 /* Calculate average and correction slope and offset. */
\r
975 point25Average /= (sizeof(calibrationResult)/sizeof(calibrationResult[0]) / 2);
\r
976 point75Average /= (sizeof(calibrationResult)/sizeof(calibrationResult[0]) / 2);
\r
978 tempGCC = ((IDEAL_RES75 - IDEAL_RES25) << 14) / (point75Average - point25Average);
\r
979 tempOCC = IDEAL_RES75 - ((tempGCC * point75Average) >> 14) - 2;
\r
981 /* GCC field is only 15 bits. */
\r
982 tempGCC = tempGCC & ~(1 << 15);
\r
984 /* OCC field is only 14 bits. */
\r
985 tempOCC = tempOCC & ~(3 << 14);
\r
987 /* Write calibration data to ADC engine. */
\r
988 Adc_WriteEQADCRegister (ADC0_GCCR, tempGCC);
\r
989 Adc_WriteEQADCRegister (ADC0_OCCR, tempOCC);
\r
991 /* Read back and check calibration values. */
\r
992 if (Adc_ReadEQADCRegister (ADC0_GCCR) != tempGCC)
\r
996 else if (Adc_ReadEQADCRegister (ADC0_OCCR) != tempOCC)
\r
1002 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
\r
1003 void Adc_EnableGroupNotification (Adc_GroupType group)
\r
1005 Adc_EnableInternalGroupNotification(adcState, AdcConfigPtr, group);
\r
1008 void Adc_DisableGroupNotification (Adc_GroupType group)
\r
1010 Adc_InternalDisableGroupNotification(adcState, AdcConfigPtr, group);
\r
1014 Adc_StatusType Adc_GetGroupStatus (Adc_GroupType group)
\r
1016 return Adc_InternalGetGroupStatus(adcState, AdcConfigPtr, group);
\r