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
79 Std_ReturnType Adc_DeInit (const Adc_ConfigType *ConfigPtr)
\r
81 if (E_OK == Adc_CheckDeInit(adcState, ConfigPtr))
\r
83 /* Clean internal status. */
\r
84 AdcConfigPtr = (Adc_ConfigType *)NULL;
\r
85 adcState = ADC_UNINIT;
\r
92 Std_ReturnType Adc_Init (const Adc_ConfigType *ConfigPtr)
\r
94 Std_ReturnType returnValue;
\r
95 Adc_GroupType group;
\r
97 if (E_OK == Adc_CheckInit(adcState, ConfigPtr))
\r
99 /* First of all, store the location of the configuration data. */
\r
100 AdcConfigPtr = ConfigPtr;
\r
102 // Connect interrupt to correct isr
\r
103 ISR_INSTALL_ISR2("ADC",Adc_GroupConversionComplete,IRQ_TYPE_ATD0,6,0);
\r
106 ATD0CTL2 = BM_ADPU | BM_AFFC | BM_ASCIE; /* power enable, Fast Flag Clear, irq enable*/
\r
107 ATD0CTL3 = 0x03; /* 8 conversions per sequence default, freeze enable */
\r
109 ATD0CTL4 = (ConfigPtr->hwConfigPtr->resolution << 7) |
\r
110 (ConfigPtr->hwConfigPtr->convTime << 5) |
\r
111 ConfigPtr->hwConfigPtr->adcPrescale;
\r
113 for (group = 0; group < ADC_NBR_OF_GROUPS; group++)
\r
116 ConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\r
119 /* Move on to INIT state. */
\r
120 adcState = ADC_INIT;
\r
121 returnValue = E_OK;
\r
125 returnValue = E_NOT_OK;
\r
128 return (returnValue);
\r
131 Std_ReturnType Adc_SetupResultBuffer (Adc_GroupType group, Adc_ValueGroupType *bufferPtr)
\r
133 Std_ReturnType returnValue;
\r
135 /* Check for development errors. */
\r
136 if (E_OK == Adc_CheckSetupResultBuffer (AdcConfigPtr, group))
\r
138 AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr = bufferPtr;
\r
139 returnValue = E_OK;
\r
143 /* An error have been raised from Adc_CheckSetupResultBuffer(). */
\r
144 returnValue = E_NOT_OK;
\r
147 return (returnValue);
\r
150 #if (ADC_READ_GROUP_API == STD_ON)
\r
151 Std_ReturnType Adc_ReadGroup (Adc_GroupType group, Adc_ValueGroupType *dataBufferPtr)
\r
153 Std_ReturnType returnValue;
\r
154 Adc_ChannelType channel;
\r
156 if (E_OK == Adc_CheckReadGroup (adcState, AdcConfigPtr, group))
\r
158 if ((ADC_CONV_MODE_CONTINUOUS == AdcConfigPtr->groupConfigPtr[group].conversionMode) &&
\r
159 ((ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus) ||
\r
160 (ADC_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus)))
\r
162 /* ADC329, ADC331. */
\r
163 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;
\r
164 returnValue = E_OK;
\r
166 else if ((ADC_CONV_MODE_ONESHOT == AdcConfigPtr->groupConfigPtr[group].conversionMode) &&
\r
167 (ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus))
\r
170 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\r
172 returnValue = E_OK;
\r
177 returnValue = E_OK;
\r
180 if (E_OK == returnValue)
\r
182 /* Copy the result to application buffer. */
\r
183 for (channel = 0; channel < AdcConfigPtr->groupConfigPtr[group].numberOfChannels; channel++)
\r
185 dataBufferPtr[channel] = AdcConfigPtr->groupConfigPtr[group].resultBuffer[channel];
\r
191 /* An error have been raised from Adc_CheckReadGroup(). */
\r
192 returnValue = E_NOT_OK;
\r
195 return (returnValue);
\r
199 static void Adc_GroupConversionComplete (void)
\r
202 Adc_GroupDefType *groupPtr = NULL;
\r
203 /* Clear SCF flag. Not needed if AFFC is set but better to always do it */
\r
206 // Check which group is busy, only one is allowed to be busy at a time in a hw unit
\r
207 for (index = 0; index < ADC_NBR_OF_GROUPS; index++)
\r
209 if(AdcConfigPtr->groupConfigPtr[index].status->groupStatus == ADC_BUSY)
\r
211 groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[index];
\r
215 if(groupPtr != NULL)
\r
218 volatile uint16_t *ptr = &ATD0DR0;
\r
219 for(index=0; index<groupPtr->numberOfChannels; index++)
\r
221 groupPtr->resultBuffer[index] = *(ptr + groupPtr->channelList[index]);
\r
224 /* Sample completed. */
\r
225 groupPtr->status->groupStatus = ADC_STREAM_COMPLETED;
\r
227 /* Call notification if enabled. */
\r
228 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
\r
229 if (groupPtr->status->notifictionEnable && groupPtr->groupCallback != NULL)
\r
231 groupPtr->groupCallback();
\r
237 #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)
\r
238 void Adc_StartGroupConversion (Adc_GroupType group)
\r
240 /* Run development error check. */
\r
241 if (E_OK == Adc_CheckStartGroupConversion (adcState, AdcConfigPtr, group))
\r
243 /* Set single scan enable bit if this group is one shot. */
\r
244 if (AdcConfigPtr->groupConfigPtr[group].conversionMode == ADC_CONV_MODE_ONESHOT)
\r
246 /* Start next AD conversion. */
\r
247 ATD0CTL5 = BM_DJM | BM_MULT; /* 10010000 Right Justified,unsigned */
\r
248 /* No SCAN/MULT/AD0 start select */
\r
249 /* Set group state to BUSY. */
\r
250 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;
\r
255 /* Start AD conversion. */
\r
256 ATD0CTL5 = BM_DJM | BM_MULT | BM_SCAN; /* 10010000 Right Justified,unsigned */
\r
257 /* SCAN/MULT/AD0 start select */
\r
258 /* Set group state to BUSY. */
\r
259 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;
\r
264 void Adc_StopGroupConversion (Adc_GroupType group)
\r
266 /* Run development error check. */
\r
267 if (E_OK == Adc_CheckStopGroupConversion (adcState, AdcConfigPtr, group))
\r
269 ATD0CTL3 = 0x03; /* Hard write to stop current conversion */
\r
273 /* Error have been set within Adc_CheckStartGroupConversion(). */
\r
278 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
\r
279 void Adc_EnableGroupNotification (Adc_GroupType group)
\r
281 Adc_EnableInternalGroupNotification(adcState, AdcConfigPtr, group);
\r
284 void Adc_DisableGroupNotification (Adc_GroupType group)
\r
286 Adc_InternalDisableGroupNotification(adcState, AdcConfigPtr, group);
\r
290 Adc_StatusType Adc_GetGroupStatus (Adc_GroupType group)
\r
292 return Adc_InternalGetGroupStatus(adcState, AdcConfigPtr, group);
\r