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 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
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
60 vuint32_t ADC_REG:16;
\r
61 vuint32_t ADC_REG_ADDR:8;
\r
63 }Adc_RegisterWriteType;
\r
75 vuint32_t MESSAGE_TAG:4;
\r
77 vuint32_t ADC_REG_ADDR:8;
\r
79 }Adc_RegisterReadType;
\r
89 ADC_EQADC_NBR_OF_QUEUES
\r
90 }Adc_eQADCQueueType;
\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
99 typedef int16_t Adc_EQADCRegister;
\r
108 }Adc_EQADCRegisterType;
\r
110 /* Command queue for calibration sequence. See 31.5.6 in reference manual. */
\r
111 const Adc_CommandType AdcCalibrationCommandQueue [] =
\r
113 /* Four samples of 25 % of (VRh - VRl). */
\r
126 /* Four samples of 75 % of (VRh - VRl). */
\r
141 /* DMA configuration for calibration sequence. */
\r
142 const Dma_TcdType AdcCalibrationDMACommandConfig =
\r
144 .SADDR = (uint32_t)AdcCalibrationCommandQueue,
\r
146 .SSIZE = DMA_TRANSFER_SIZE_32BITS,
\r
148 .DSIZE = DMA_TRANSFER_SIZE_32BITS,
\r
149 .SOFF = sizeof(Adc_CommandType),
\r
150 .NBYTESu.R = sizeof(Adc_CommandType),
\r
152 .DADDR = (vuint32_t)&EQADC.CFPR[0].R,
\r
171 const Dma_TcdType AdcCalibrationDMAResultConfig =
\r
173 .SADDR = (vuint32_t)&EQADC.RFPR[0].R + 2,
\r
175 .SSIZE = DMA_TRANSFER_SIZE_16BITS,
\r
177 .DSIZE = DMA_TRANSFER_SIZE_16BITS,
\r
179 .NBYTESu.R = sizeof(Adc_ValueGroupType),
\r
181 .DADDR = 0, /* Dynamic address, written later. */
\r
184 .DOFF = sizeof(Adc_ValueGroupType),
\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
207 void Adc_GroupConversionComplete (Adc_GroupType group);
\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
213 #if (ADC_DEINIT_API == STD_ON)
\r
216 Adc_eQADCQueueType queue;
\r
217 Adc_GroupType group;
\r
218 boolean queueStopped;
\r
220 if (E_OK == Adc_CheckDeInit(adcState, AdcConfigPtr))
\r
222 /* Stop all queues. */
\r
223 for (queue = ADC_EQADC_QUEUE_0; queue < ADC_EQADC_NBR_OF_QUEUES; queue++)
\r
225 /* Disable queue. */
\r
226 EQADC.CFCR[queue].B.MODE = 0;
\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
235 case ADC_EQADC_QUEUE_0:
\r
236 queueStopped = (EQADC.CFSR.B.CFS0 == EQADC_CFIFO_STATUS_IDLE);
\r
238 case ADC_EQADC_QUEUE_1:
\r
239 queueStopped = (EQADC.CFSR.B.CFS1 == EQADC_CFIFO_STATUS_IDLE);
\r
241 case ADC_EQADC_QUEUE_2:
\r
242 queueStopped = (EQADC.CFSR.B.CFS2 == EQADC_CFIFO_STATUS_IDLE);
\r
244 case ADC_EQADC_QUEUE_3:
\r
245 queueStopped = (EQADC.CFSR.B.CFS3 == EQADC_CFIFO_STATUS_IDLE);
\r
247 case ADC_EQADC_QUEUE_4:
\r
248 queueStopped = (EQADC.CFSR.B.CFS4 == EQADC_CFIFO_STATUS_IDLE);
\r
250 case ADC_EQADC_QUEUE_5:
\r
251 queueStopped = (EQADC.CFSR.B.CFS5 == EQADC_CFIFO_STATUS_IDLE);
\r
254 /* We should never get here... Terminate loop. */
\r
255 queueStopped = TRUE;
\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
264 /* Disable FIFO fill requests. */
\r
265 EQADC.IDCR[queue].B.CFFE = 0;
\r
266 EQADC.IDCR[queue].B.RFDE = 0;
\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
275 /* Stop all DMA channels connected to EQADC. */
\r
276 for (group = ADC_GROUP0; group < AdcConfigPtr->nbrOfGroups; group++)
\r
278 Dma_StopChannel (AdcConfigPtr->groupConfigPtr [group].dmaCommandChannel);
\r
279 Dma_StopChannel (AdcConfigPtr->groupConfigPtr [group].dmaResultChannel);
\r
281 /* Set group status to idle. */
\r
282 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\r
285 /* Disable EQADC. */
\r
286 Adc_WriteEQADCRegister (ADC0_CR, 0);
\r
288 /* Clean internal status. */
\r
289 AdcConfigPtr = (Adc_ConfigType *)NULL;
\r
290 adcState = ADC_UNINIT;
\r
295 void Adc_Init (const Adc_ConfigType *ConfigPtr)
\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
303 if (E_OK == Adc_CheckInit(adcState, ConfigPtr))
\r
305 /* First of all, store the location of the configuration data. */
\r
306 AdcConfigPtr = ConfigPtr;
\r
308 /* Start configuring the eQADC queues. */
\r
309 for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)
\r
311 /* Loop through all channels and make the command queue. */
\r
312 for (channel = 0; channel < ConfigPtr->groupConfigPtr[group].numberOfChannels; channel++)
\r
314 /* Get physical channel. */
\r
315 channelId = ConfigPtr->groupConfigPtr[group].channelList[channel];
\r
317 commandQueue = ConfigPtr->groupConfigPtr[group].commandBuffer;
\r
319 /* Begin with empty command. */
\r
322 /* Physical channel number. */
\r
323 command.B.CHANNEL_NUMBER = channelId;
\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
331 /* Write command to command queue. */
\r
332 commandQueue [channel].R = command.R;
\r
334 /* Last channel in group. Write EOQ and configure eQADC FIFO. */
\r
335 if (channel == (ConfigPtr->groupConfigPtr[group].numberOfChannels - 1))
\r
337 commandQueue [channel].B.EOQ = 1;
\r
343 Adc_ConfigureEQADC (ConfigPtr);
\r
345 /* Perform calibration of the ADC. */
\r
346 Adc_EQADCCalibrationSequence ();
\r
348 /* Configure DMA channels. */
\r
349 for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)
\r
352 ConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\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
358 /* Start DMA channels. */
\r
359 for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)
\r
361 /* Invalidate queues. */
\r
362 EQADC.CFCR[group].B.CFINV = 1;
\r
364 Dma_StartChannel (ConfigPtr->groupConfigPtr [group].dmaResultChannel);
\r
365 Dma_StartChannel (ConfigPtr->groupConfigPtr [group].dmaCommandChannel);
\r
368 Adc_ConfigureEQADCInterrupts ();
\r
370 /* Move on to INIT state. */
\r
371 adcState = ADC_INIT;
\r
375 Std_ReturnType Adc_SetupResultBuffer (Adc_GroupType group, Adc_ValueGroupType *bufferPtr)
\r
377 Std_ReturnType returnValue = E_NOT_OK;
\r
379 /* Check for development errors. */
\r
380 if (E_OK == Adc_CheckSetupResultBuffer (adcState, AdcConfigPtr, group))
\r
382 AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr = bufferPtr;
\r
384 returnValue = E_OK;
\r
387 return (returnValue);
\r
390 Adc_StreamNumSampleType Adc_GetStreamLastPointer(Adc_GroupType group, Adc_ValueGroupType** PtrToSamplePtr)
\r
392 Adc_StreamNumSampleType nofSample = 0;
\r
393 Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];
\r
396 /* Check for development errors. */
\r
397 if ( (E_OK == Adc_CheckGetStreamLastPointer (adcState, AdcConfigPtr, group)) &&
\r
398 (groupPtr->status->groupStatus != ADC_BUSY) )
\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
405 if ((ADC_CONV_MODE_ONESHOT == groupPtr->conversionMode) &&
\r
406 (ADC_STREAM_COMPLETED == groupPtr->status->groupStatus))
\r
408 /** @req ADC327. */
\r
409 groupPtr->status->groupStatus = ADC_IDLE;
\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
416 /** @req ADC327. */
\r
417 groupPtr->status->groupStatus = ADC_IDLE;
\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
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
427 /* Start continous conversion again */
\r
428 Adc_StartGroupConversion(group);
\r
433 else{/* Keep status. */}
\r
437 /* Some condition not met */
\r
438 *PtrToSamplePtr = NULL;
\r
445 #if (ADC_READ_GROUP_API == STD_ON)
\r
446 Std_ReturnType Adc_ReadGroup (Adc_GroupType group, Adc_ValueGroupType *dataBufferPtr)
\r
448 Std_ReturnType returnValue = E_OK;
\r
450 Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];
\r
452 if (E_OK == Adc_CheckReadGroup (adcState, AdcConfigPtr, group))
\r
454 /* Copy the result to application buffer. */
\r
455 for (channel = 0; channel < groupPtr->numberOfChannels; channel++)
\r
457 if(groupPtr->status->currSampleCount > 0){
\r
458 dataBufferPtr[channel] = (&(groupPtr->status->resultBufferPtr[groupPtr->status->currSampleCount-1]))[channel];
\r
460 dataBufferPtr[channel] = groupPtr->status->resultBufferPtr[channel];
\r
464 if ((ADC_CONV_MODE_ONESHOT == groupPtr->conversionMode) &&
\r
465 (ADC_STREAM_COMPLETED == groupPtr->status->groupStatus))
\r
467 /** @req ADC330. */
\r
468 groupPtr->status->groupStatus = ADC_IDLE;
\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
475 /** @req ADC330. */
\r
476 groupPtr->status->groupStatus = ADC_IDLE;
\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
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
487 /* Start continous conversion again */
\r
488 Adc_StartGroupConversion(group);
\r
493 else{/* Keep status. */}
\r
497 /* An error have been raised from Adc_CheckReadGroup(). */
\r
498 returnValue = E_NOT_OK;
\r
501 return (returnValue);
\r
505 void Adc_GroupConversionComplete (Adc_GroupType group)
\r
507 Adc_GroupDefType *adcGroup = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];
\r
509 if(ADC_ACCESS_MODE_SINGLE == adcGroup->accessMode )
\r
511 adcGroup->status->groupStatus = ADC_STREAM_COMPLETED;
\r
513 /* Disable trigger. */
\r
514 EQADC.CFCR[group].B.MODE = 0;
\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
520 adcGroup->groupCallback();
\r
526 if(ADC_STREAM_BUFFER_LINEAR == adcGroup->streamBufferMode)
\r
528 adcGroup->status->currSampleCount++;
\r
529 if(adcGroup->status->currSampleCount < adcGroup->streamNumSamples)
\r
531 adcGroup->status->currResultBufPtr += adcGroup->numberOfChannels;
\r
532 adcGroup->status->groupStatus = ADC_COMPLETED;
\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
539 /* Set single scan enable bit */
\r
540 EQADC.CFCR[group].B.SSE = 1;
\r
544 /* All sample completed. */
\r
545 adcGroup->status->groupStatus = ADC_STREAM_COMPLETED;
\r
547 /* Disable trigger. */
\r
548 EQADC.CFCR[group].B.MODE = 0;
\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
558 else if(ADC_STREAM_BUFFER_CIRCULAR == adcGroup->streamBufferMode)
\r
560 adcGroup->status->currSampleCount++;
\r
561 if(adcGroup->status->currSampleCount < adcGroup->streamNumSamples)
\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
568 adcGroup->status->groupStatus = ADC_COMPLETED;
\r
570 /* Set single scan enable bit */
\r
571 EQADC.CFCR[group].B.SSE = 1;
\r
575 /* Sample completed. */
\r
577 /* Disable trigger. */
\r
578 EQADC.CFCR[group].B.MODE = 0;
\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
585 adcGroup->groupCallback();
\r
597 void Adc_Group0ConversionComplete (void)
\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
603 void Adc_Group1ConversionComplete (void)
\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
609 void Adc_Group2ConversionComplete (void)
\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
615 void Adc_Group3ConversionComplete (void)
\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
621 void Adc_Group4ConversionComplete (void)
\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
627 void Adc_Group5ConversionComplete (void)
\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
634 void Adc_EQADCError (void)
\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
639 /* Trigger overrun on queue 0!! */
\r
642 else if (EQADC.FISR[ADC_EQADC_QUEUE_1].B.TORF)
\r
644 /* Trigger overrun on queue 1!! */
\r
647 else if (EQADC.FISR[ADC_EQADC_QUEUE_0].B.CFUF)
\r
649 /* Command underflow on queue 0!! */
\r
652 else if (EQADC.FISR[ADC_EQADC_QUEUE_1].B.CFUF)
\r
654 /* Command underflow on queue 1!! */
\r
657 else if (EQADC.FISR[ADC_EQADC_QUEUE_0].B.RFOF)
\r
659 /* Result overflow on queue 0!! */
\r
662 else if (EQADC.FISR[ADC_EQADC_QUEUE_1].B.RFOF)
\r
664 /* Result overflow on queue 1!! */
\r
669 /* Something else... TODO What have we missed above */
\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
684 while (!EQADC.FISR[q].B.EOQF) \
\r
689 static void Adc_WriteEQADCRegister (Adc_EQADCRegisterType reg, Adc_EQADCRegister value)
\r
691 Adc_RegisterWriteType writeReg;
\r
692 uint32_t temp, oldMode;
\r
696 /* Write command. */
\r
698 writeReg.B.EOQ = 1;
\r
699 writeReg.B.ADC_REG = value;
\r
700 writeReg.B.ADC_REG_ADDR = reg;
\r
702 /* Invalidate queue. */
\r
703 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.CFINV = 1;
\r
706 /* Write command through FIFO. */
\r
707 EQADC.CFPR[ADC_EQADC_QUEUE_0].R = writeReg.R;
\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
714 /* Wait for command to be executed. */
\r
715 WAIT_FOR_QUEUE_TO_FINISH(ADC_EQADC_QUEUE_0);
\r
717 /* Flush result buffer. */
\r
718 temp = EQADC.RFPR[ADC_EQADC_QUEUE_0].R;
\r
720 EQADC.FISR[ADC_EQADC_QUEUE_0].B.EOQF = 1;
\r
722 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE = oldMode;
\r
726 static Adc_EQADCRegister Adc_ReadEQADCRegister (Adc_EQADCRegisterType reg)
\r
728 Adc_RegisterReadType readReg;
\r
729 Adc_EQADCRegister result;
\r
730 uint32_t oldMode, dmaRequestEnable;
\r
734 /* Read command. */
\r
737 readReg.B.ADC_REG_ADDR = reg;
\r
738 readReg.B.MESSAGE_TAG = ADC_EQADC_QUEUE_0;
\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
743 EQADC.IDCR[ADC_EQADC_QUEUE_0].B.CFFE = 0;
\r
744 EQADC.IDCR[ADC_EQADC_QUEUE_0].B.RFDE = 0;
\r
746 /* Remember to enable requests again... */
\r
747 dmaRequestEnable = TRUE;
\r
751 dmaRequestEnable = FALSE;
\r
754 /* Invalidate queue. */
\r
755 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.CFINV = 1;
\r
757 /* Write command through FIFO. */
\r
758 EQADC.CFPR[ADC_EQADC_QUEUE_0].R = readReg.R;
\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
765 /* Wait for command to be executed. */
\r
766 WAIT_FOR_QUEUE_TO_FINISH(ADC_EQADC_QUEUE_0);
\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
772 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.MODE = oldMode;
\r
774 if (dmaRequestEnable)
\r
776 EQADC.IDCR[ADC_EQADC_QUEUE_0].B.CFFE = 1;
\r
777 EQADC.IDCR[ADC_EQADC_QUEUE_0].B.RFDE = 1;
\r
785 static void Adc_ConfigureEQADC (const Adc_ConfigType *ConfigPtr)
\r
787 Adc_GroupType group;
\r
791 ADC_ENABLE = 0x8000,
\r
794 Adc_WriteEQADCRegister (ADC0_CR, (ADC_ENABLE | ConfigPtr->hwConfigPtr->adcPrescale));
\r
796 /* Disable time stamp timer. */
\r
797 Adc_WriteEQADCRegister (ADC0_TSCR, 0);
\r
799 for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)
\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
805 /* Invalidate FIFO. */
\r
806 EQADC.CFCR[group].B.CFINV = 1;
\r
808 /* Enable FIFO fill requests. */
\r
809 EQADC.IDCR[group].B.CFFE = 1;
\r
810 EQADC.IDCR[group].B.RFDE = 1;
\r
814 void Adc_ConfigureEQADCInterrupts (void)
\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
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
824 EQADC.FISR[group].B.CFUF = 1;
\r
825 EQADC.IDCR[group].B.CFUIE = 1;
\r
827 EQADC.FISR[group].B.TORF = 1;
\r
828 EQADC.IDCR[group].B.TORIE = 1;
\r
830 EQADC.FISR[group].B.EOQF = 1;
\r
831 EQADC.IDCR[group].B.EOQIE = 1;
\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
848 #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)
\r
849 void Adc_StartGroupConversion (Adc_GroupType group)
\r
851 Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group];
\r
853 /* Run development error check. */
\r
854 if (E_OK == Adc_CheckStartGroupConversion (adcState, AdcConfigPtr, group))
\r
856 /* Disable trigger. */
\r
857 EQADC.CFCR[group].B.MODE = 0;
\r
859 /* Set group state to BUSY. */
\r
860 groupPtr->status->groupStatus = ADC_BUSY;
\r
862 groupPtr->status->currSampleCount = 0;
\r
863 groupPtr->status->currResultBufPtr = groupPtr->status->resultBufferPtr; /* Set current result buffer */
\r
865 Dma_ConfigureDestinationAddress((uint32_t)groupPtr->status->resultBufferPtr, groupPtr->dmaResultChannel);
\r
867 /* Always use single shot in streaming mode */
\r
868 if( groupPtr->accessMode == ADC_ACCESS_MODE_STREAMING)
\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
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
882 EQADC.CFCR[group].B.SSE = 1;
\r
888 /* Error have been set within Adc_CheckStartGroupConversion(). */
\r
892 void Adc_StopGroupConversion (Adc_GroupType group)
\r
894 if (E_OK == Adc_CheckStopGroupConversion (adcState, AdcConfigPtr, group))
\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
901 /* Invalidate FIFO. */
\r
902 EQADC.CFCR[group].B.CFINV = 1;
\r
904 /* Set group state to IDLE. */
\r
905 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\r
907 /* Disable group notification if enabled. */
\r
908 if(1 == AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable){
\r
909 Adc_DisableGroupNotification (group);
\r
914 /* Error have been set within Adc_CheckStartGroupConversion(). */
\r
919 static void Adc_EQADCCalibrationSequence (void)
\r
921 Adc_ValueGroupType calibrationResult[sizeof(AdcCalibrationCommandQueue)/sizeof(AdcCalibrationCommandQueue[0])];
\r
922 int32_t point25Average, point75Average, i;
\r
923 Adc_EQADCRegister tempGCC, tempOCC;
\r
926 IDEAL_RES25 = 0x1000,
\r
927 IDEAL_RES75 = 0x3000,
\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
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
942 EDMA.TCD[DMA_ADC_GROUP0_COMMAND_CHANNEL].D_REQ = 1;
\r
943 EDMA.TCD[DMA_ADC_GROUP0_RESULT_CHANNEL].D_REQ = 1;
\r
945 /* Invalidate queues. */
\r
946 EQADC.CFCR[ADC_EQADC_QUEUE_0].B.CFINV = 1;
\r
948 Dma_StartChannel (DMA_ADC_GROUP0_COMMAND_CHANNEL);
\r
949 Dma_StartChannel (DMA_ADC_GROUP0_RESULT_CHANNEL);
\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
955 /* Wait for conversion to complete. */
\r
956 while(!Dma_ChannelDone (DMA_ADC_GROUP0_RESULT_CHANNEL))
\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
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
971 point25Average += calibrationResult[i];
\r
972 point75Average += calibrationResult[i + sizeof(calibrationResult)/sizeof(calibrationResult[0]) / 2];
\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
979 tempGCC = ((IDEAL_RES75 - IDEAL_RES25) << 14) / (point75Average - point25Average);
\r
980 tempOCC = IDEAL_RES75 - ((tempGCC * point75Average) >> 14) - 2;
\r
982 /* GCC field is only 15 bits. */
\r
983 tempGCC = tempGCC & ~(1 << 15);
\r
985 /* OCC field is only 14 bits. */
\r
986 tempOCC = tempOCC & ~(3 << 14);
\r
988 /* Write calibration data to ADC engine. */
\r
989 Adc_WriteEQADCRegister (ADC0_GCCR, tempGCC);
\r
990 Adc_WriteEQADCRegister (ADC0_OCCR, tempOCC);
\r
992 /* Read back and check calibration values. */
\r
993 if (Adc_ReadEQADCRegister (ADC0_GCCR) != tempGCC)
\r
997 else if (Adc_ReadEQADCRegister (ADC0_OCCR) != tempOCC)
\r
1003 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
\r
1004 void Adc_EnableGroupNotification (Adc_GroupType group)
\r
1006 Adc_EnableInternalGroupNotification(adcState, AdcConfigPtr, group);
\r
1009 void Adc_DisableGroupNotification (Adc_GroupType group)
\r
1011 Adc_InternalDisableGroupNotification(adcState, AdcConfigPtr, group);
\r
1015 Adc_StatusType Adc_GetGroupStatus (Adc_GroupType group)
\r
1017 return Adc_InternalGetGroupStatus(adcState, AdcConfigPtr, group);
\r