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
26 #include "Adc_Internal.h"
\r
30 #define BM_ADPU 0x80
\r
31 #define BM_AFFC 0x40
\r
32 #define BM_AWAI 0x20
\r
33 #define BM_ETRIGLE 0x10
\r
34 #define BM_ETRIGP 0x08
\r
35 #define BM_ETRIG_E 0x04
\r
36 #define BM_ASCIE 0x02
\r
37 #define BM_ASCIF 0x01
\r
44 #define BM_FIFO 0x04
\r
45 #define BM_FRZ1 0x02
\r
46 #define BM_FRZ0 0x01
\r
49 #define BM_SRES8 0x80
\r
50 #define BM_SMP1 0x40
\r
51 #define BM_SMP0 0x20
\r
52 #define BM_PRS4 0x10
\r
53 #define BM_PRS3 0x08
\r
54 #define BM_PRS2 0x04
\r
55 #define BM_PRS1 0x02
\r
56 #define BM_PRS0 0x01
\r
60 #define BM_DSGN 0x40
\r
61 #define BM_SCAN 0x20
\r
62 #define BM_MULT 0x10
\r
69 /* Function prototypes. */
\r
70 static void Adc_GroupConversionComplete (void);
\r
72 static Adc_StateType adcState = ADC_UNINIT;
\r
74 /* Pointer to configuration structure. */
\r
75 static const Adc_ConfigType *AdcConfigPtr;
\r
78 #if (ADC_DEINIT_API == STD_ON)
\r
81 if (E_OK == Adc_CheckDeInit(adcState, AdcConfigPtr))
\r
83 /* Clean internal status. */
\r
84 AdcConfigPtr = (Adc_ConfigType *)NULL;
\r
85 adcState = ADC_UNINIT;
\r
90 void Adc_Init (const Adc_ConfigType *ConfigPtr)
\r
92 Adc_GroupType group;
\r
94 if (E_OK == Adc_CheckInit(adcState, ConfigPtr))
\r
96 /* First of all, store the location of the configuration data. */
\r
97 AdcConfigPtr = ConfigPtr;
\r
99 // Connect interrupt to correct isr
\r
100 ISR_INSTALL_ISR2("ADC",Adc_GroupConversionComplete,IRQ_TYPE_ATD0,6,0);
\r
103 ATD0CTL2 = BM_ADPU | BM_AFFC | BM_ASCIE; /* power enable, Fast Flag Clear, irq enable*/
\r
104 ATD0CTL3 = 0x03; /* 8 conversions per sequence default, freeze enable */
\r
106 ATD0CTL4 = (ConfigPtr->hwConfigPtr->resolution << 7) |
\r
107 (ConfigPtr->hwConfigPtr->convTime << 5) |
\r
108 ConfigPtr->hwConfigPtr->adcPrescale;
\r
110 for (group = 0; group < ADC_NBR_OF_GROUPS; group++)
\r
113 ConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\r
116 /* Move on to INIT state. */
\r
117 adcState = ADC_INIT;
\r
121 Std_ReturnType Adc_SetupResultBuffer (Adc_GroupType group, Adc_ValueGroupType *bufferPtr)
\r
123 Std_ReturnType returnValue;
\r
125 /* Check for development errors. */
\r
126 if (E_OK == Adc_CheckSetupResultBuffer (adcState, AdcConfigPtr, group))
\r
128 AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr = bufferPtr;
\r
129 returnValue = E_OK;
\r
133 /* An error have been raised from Adc_CheckSetupResultBuffer(). */
\r
134 returnValue = E_NOT_OK;
\r
137 return (returnValue);
\r
140 #if (ADC_READ_GROUP_API == STD_ON)
\r
141 Std_ReturnType Adc_ReadGroup (Adc_GroupType group, Adc_ValueGroupType *dataBufferPtr)
\r
143 Std_ReturnType returnValue;
\r
144 Adc_ChannelType channel;
\r
146 if (E_OK == Adc_CheckReadGroup (adcState, AdcConfigPtr, group))
\r
148 if ((ADC_CONV_MODE_CONTINUOUS == AdcConfigPtr->groupConfigPtr[group].conversionMode) &&
\r
149 ((ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus) ||
\r
150 (ADC_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus)))
\r
152 /* ADC329, ADC331. */
\r
153 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;
\r
154 returnValue = E_OK;
\r
156 else if ((ADC_CONV_MODE_ONESHOT == AdcConfigPtr->groupConfigPtr[group].conversionMode) &&
\r
157 (ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus))
\r
160 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\r
162 returnValue = E_OK;
\r
167 returnValue = E_OK;
\r
170 if (E_OK == returnValue)
\r
172 /* Copy the result to application buffer. */
\r
173 for (channel = 0; channel < AdcConfigPtr->groupConfigPtr[group].numberOfChannels; channel++)
\r
175 dataBufferPtr[channel] = AdcConfigPtr->groupConfigPtr[group].resultBuffer[channel];
\r
181 /* An error have been raised from Adc_CheckReadGroup(). */
\r
182 returnValue = E_NOT_OK;
\r
185 return (returnValue);
\r
189 static void Adc_GroupConversionComplete (void)
\r
192 Adc_GroupDefType *groupPtr = NULL;
\r
193 /* Clear SCF flag. Not needed if AFFC is set but better to always do it */
\r
196 // Check which group is busy, only one is allowed to be busy at a time in a hw unit
\r
197 for (index = 0; index < ADC_NBR_OF_GROUPS; index++)
\r
199 if(AdcConfigPtr->groupConfigPtr[index].status->groupStatus == ADC_BUSY)
\r
201 groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[index];
\r
205 if(groupPtr != NULL)
\r
208 volatile uint16_t *ptr = &ATD0DR0;
\r
209 for(index=0; index<groupPtr->numberOfChannels; index++)
\r
211 groupPtr->resultBuffer[index] = *(ptr + groupPtr->channelList[index]);
\r
214 /* Sample completed. */
\r
215 groupPtr->status->groupStatus = ADC_STREAM_COMPLETED;
\r
217 /* Call notification if enabled. */
\r
218 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
\r
219 if (groupPtr->status->notifictionEnable && groupPtr->groupCallback != NULL)
\r
221 groupPtr->groupCallback();
\r
227 #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)
\r
228 void Adc_StartGroupConversion (Adc_GroupType group)
\r
230 /* Run development error check. */
\r
231 if (E_OK == Adc_CheckStartGroupConversion (adcState, AdcConfigPtr, group))
\r
233 /* Set single scan enable bit if this group is one shot. */
\r
234 if (AdcConfigPtr->groupConfigPtr[group].conversionMode == ADC_CONV_MODE_ONESHOT)
\r
236 /* Start next AD conversion. */
\r
237 ATD0CTL5 = BM_DJM | BM_MULT; /* 10010000 Right Justified,unsigned */
\r
238 /* No SCAN/MULT/AD0 start select */
\r
239 /* Set group state to BUSY. */
\r
240 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;
\r
245 /* Start AD conversion. */
\r
246 ATD0CTL5 = BM_DJM | BM_MULT | BM_SCAN; /* 10010000 Right Justified,unsigned */
\r
247 /* SCAN/MULT/AD0 start select */
\r
248 /* Set group state to BUSY. */
\r
249 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;
\r
254 void Adc_StopGroupConversion (Adc_GroupType group)
\r
256 /* Run development error check. */
\r
257 if (E_OK == Adc_CheckStopGroupConversion (adcState, AdcConfigPtr, group))
\r
259 ATD0CTL3 = 0x03; /* Hard write to stop current conversion */
\r
263 /* Error have been set within Adc_CheckStartGroupConversion(). */
\r
268 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
\r
269 void Adc_EnableGroupNotification (Adc_GroupType group)
\r
271 Adc_EnableInternalGroupNotification(adcState, AdcConfigPtr, group);
\r
274 void Adc_DisableGroupNotification (Adc_GroupType group)
\r
276 Adc_InternalDisableGroupNotification(adcState, AdcConfigPtr, group);
\r
280 Adc_StatusType Adc_GetGroupStatus (Adc_GroupType group)
\r
282 return Adc_InternalGetGroupStatus(adcState, AdcConfigPtr, group);
\r