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
29 #define BM_ADPU 0x80
\r
30 #define BM_AFFC 0x40
\r
31 #define BM_AWAI 0x20
\r
32 #define BM_ETRIGLE 0x10
\r
33 #define BM_ETRIGP 0x08
\r
34 #define BM_ETRIG_E 0x04
\r
35 #define BM_ASCIE 0x02
\r
36 #define BM_ASCIF 0x01
\r
43 #define BM_FIFO 0x04
\r
44 #define BM_FRZ1 0x02
\r
45 #define BM_FRZ0 0x01
\r
48 #define BM_SRES8 0x80
\r
49 #define BM_SMP1 0x40
\r
50 #define BM_SMP0 0x20
\r
51 #define BM_PRS4 0x10
\r
52 #define BM_PRS3 0x08
\r
53 #define BM_PRS2 0x04
\r
54 #define BM_PRS1 0x02
\r
55 #define BM_PRS0 0x01
\r
59 #define BM_DSGN 0x40
\r
60 #define BM_SCAN 0x20
\r
61 #define BM_MULT 0x10
\r
72 /* Function prototypes. */
\r
74 /* Development error checking. */
\r
75 static Std_ReturnType Adc_CheckReadGroup (Adc_GroupType group);
\r
76 static Std_ReturnType Adc_CheckStartGroupConversion (Adc_GroupType group);
\r
77 static Std_ReturnType Adc_CheckInit (const Adc_ConfigType *ConfigPtr);
\r
78 static Std_ReturnType Adc_CheckSetupResultBuffer (Adc_GroupType group);
\r
80 static void Adc_GroupConversionComplete (void);
\r
82 static Adc_StateType adcState = ADC_UNINIT;
\r
84 /* Pointer to configuration structure. */
\r
85 static const Adc_ConfigType *AdcConfigPtr;
\r
87 #if (ADC_DEINIT_API == STD_ON)
\r
88 Std_ReturnType Adc_DeInit (const Adc_ConfigType *ConfigPtr)
\r
95 Std_ReturnType Adc_Init (const Adc_ConfigType *ConfigPtr)
\r
97 Std_ReturnType returnValue;
\r
98 Adc_GroupType group;
\r
100 if (E_OK == Adc_CheckInit(ConfigPtr))
\r
102 /* First of all, store the location of the configuration data. */
\r
103 AdcConfigPtr = ConfigPtr;
\r
105 // Connect interrupt to correct isr
\r
107 tid = Os_Arc_CreateIsr(Adc_GroupConversionComplete,6/*prio*/,"ADC");
\r
108 Irq_AttachIsr2(tid,NULL, IRQ_TYPE_ATD0);
\r
110 ATD0CTL2 = BM_ADPU | BM_AFFC | BM_ASCIE; /* power enable, Fast Flag Clear, irq enable*/
\r
111 ATD0CTL3 = 0x00; /* 8 conversions per sequence default */
\r
113 ATD0CTL4 = (ConfigPtr->hwConfigPtr->resolution << 7) |
\r
114 (ConfigPtr->hwConfigPtr->convTime << 5) |
\r
115 ConfigPtr->hwConfigPtr->adcPrescale;
\r
117 for (group = ADC_GROUP0; group < ADC_NBR_OF_GROUPS; group++)
\r
120 ConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\r
123 /* Move on to INIT state. */
\r
124 adcState = ADC_INIT;
\r
125 returnValue = E_OK;
\r
129 returnValue = E_NOT_OK;
\r
132 return (returnValue);
\r
135 Std_ReturnType Adc_SetupResultBuffer (Adc_GroupType group, Adc_ValueGroupType *bufferPtr)
\r
137 Std_ReturnType returnValue;
\r
139 /* Check for development errors. */
\r
140 if (E_OK == Adc_CheckSetupResultBuffer (group))
\r
142 AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr = bufferPtr;
\r
143 returnValue = E_OK;
\r
147 /* An error have been raised from Adc_CheckSetupResultBuffer(). */
\r
148 returnValue = E_NOT_OK;
\r
151 return (returnValue);
\r
154 #if (ADC_READ_GROUP_API == STD_ON)
\r
155 Std_ReturnType Adc_ReadGroup (Adc_GroupType group, Adc_ValueGroupType *dataBufferPtr)
\r
157 Std_ReturnType returnValue;
\r
158 Adc_ChannelType channel;
\r
160 if (E_OK == Adc_CheckReadGroup (group))
\r
162 if ((ADC_CONV_MODE_CONTINOUS == AdcConfigPtr->groupConfigPtr[group].conversionMode) &&
\r
163 ((ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus) ||
\r
164 (ADC_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus)))
\r
166 /* ADC329, ADC331. */
\r
167 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;
\r
168 returnValue = E_OK;
\r
170 else if ((ADC_CONV_MODE_ONESHOT == AdcConfigPtr->groupConfigPtr[group].conversionMode) &&
\r
171 (ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus))
\r
174 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\r
176 returnValue = E_OK;
\r
181 returnValue = E_OK;
\r
184 if (E_OK == returnValue)
\r
186 /* Copy the result to application buffer. */
\r
187 for (channel = 0; channel < AdcConfigPtr->groupConfigPtr[group].numberOfChannels; channel++)
\r
189 dataBufferPtr[channel] = AdcConfigPtr->groupConfigPtr[group].resultBuffer[channel];
\r
195 /* An error have been raised from Adc_CheckReadGroup(). */
\r
196 returnValue = E_NOT_OK;
\r
199 return (returnValue);
\r
203 Adc_StatusType Adc_GetGroupStatus (Adc_GroupType group)
\r
205 Adc_StatusType returnValue;
\r
206 if ((ADC_INIT == adcState) && (AdcConfigPtr != NULL))
\r
208 /* Adc initilised, OK to move on... */
\r
209 returnValue = AdcConfigPtr->groupConfigPtr[group].status->groupStatus;
\r
213 returnValue = ADC_IDLE;
\r
214 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
215 Det_ReportError(MODULE_ID_ADC,0,ADC_GETGROUPSTATUS_ID, ADC_E_UNINIT );
\r
219 return (returnValue);
\r
222 static void Adc_GroupConversionComplete (void)
\r
225 Adc_GroupDefType *groupPtr = NULL;
\r
226 /* Clear SCF flag. Not needed if AFFC is set but better to always do it */
\r
229 // Check which group is busy, only one is allowed to be busy at a time in a hw unit
\r
230 for (index = ADC_GROUP0; index < ADC_NBR_OF_GROUPS; index++)
\r
232 if(AdcConfigPtr->groupConfigPtr[index].status->groupStatus == ADC_BUSY)
\r
234 groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[index];
\r
238 if(groupPtr != NULL)
\r
241 volatile uint16_t *ptr = &ATD0DR0;
\r
242 for(index=0; index<groupPtr->numberOfChannels; index++)
\r
244 groupPtr->resultBuffer[index] = *(ptr + groupPtr->channelList[index]);
\r
247 /* Sample completed. */
\r
248 groupPtr->status->groupStatus = ADC_STREAM_COMPLETED;
\r
250 /* Call notification if enabled. */
\r
251 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
\r
252 if (groupPtr->status->notifictionEnable && groupPtr->groupCallback != NULL)
\r
254 groupPtr->groupCallback();
\r
260 #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)
\r
261 void Adc_StartGroupConversion (Adc_GroupType group)
\r
263 /* Run development error check. */
\r
264 if (E_OK == Adc_CheckStartGroupConversion (group))
\r
266 /* Set single scan enable bit if this group is one shot. */
\r
267 if (AdcConfigPtr->groupConfigPtr[group].conversionMode == ADC_CONV_MODE_ONESHOT)
\r
269 /* Start next AD conversion. */
\r
270 ATD0CTL5 = BM_DJM | BM_MULT; /* 10010000 Right Justified,unsigned */
\r
271 /* No SCAN/MULT/AD0 start select */
\r
272 /* Set group state to BUSY. */
\r
273 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;
\r
278 /* Start AD conversion. */
\r
279 ATD0CTL5 = BM_DJM | BM_MULT | BM_SCAN; /* 10010000 Right Justified,unsigned */
\r
280 /* SCAN/MULT/AD0 start select */
\r
281 /* Set group state to BUSY. */
\r
282 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;
\r
288 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
\r
289 void Adc_EnableGroupNotification (Adc_GroupType group)
\r
291 AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable = 1;
\r
294 void Adc_DisableGroupNotification (Adc_GroupType group)
\r
296 AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable = 0;
\r
301 /* Development error checking functions. */
\r
302 #if (ADC_READ_GROUP_API == STD_ON)
\r
303 static Std_ReturnType Adc_CheckReadGroup (Adc_GroupType group)
\r
305 Std_ReturnType returnValue;
\r
307 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
309 if (ADC_UNINIT == adcState)
\r
312 returnValue = E_NOT_OK;
\r
313 Det_ReportError(MODULE_ID_ADC,0,ADC_READGROUP_ID ,ADC_E_UNINIT );
\r
315 else if ((group < ADC_GROUP0) || (group >= ADC_NBR_OF_GROUPS))
\r
318 returnValue = E_NOT_OK;
\r
319 Det_ReportError(MODULE_ID_ADC,0,ADC_READGROUP_ID ,ADC_E_PARAM_GROUP );
\r
321 else if (ADC_IDLE == AdcConfigPtr->groupConfigPtr[group].status->groupStatus)
\r
324 returnValue = E_NOT_OK;
\r
325 Det_ReportError(MODULE_ID_ADC,0,ADC_READGROUP_ID ,ADC_E_IDLE );
\r
329 /* Nothing strange. Go on... */
\r
330 returnValue = E_OK;
\r
333 returnValue = E_OK;
\r
335 return (returnValue);
\r
339 #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)
\r
340 static Std_ReturnType Adc_CheckStartGroupConversion (Adc_GroupType group)
\r
342 Std_ReturnType returnValue;
\r
343 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
344 if (!(ADC_INIT == adcState))
\r
346 /* ADC not initialised, ADC294. */
\r
347 Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_UNINIT );
\r
348 returnValue = E_NOT_OK;
\r
350 else if (!((group >= 0) && (group < ADC_NBR_OF_GROUPS)))
\r
352 /* Wrong group ID, ADC125 */
\r
353 Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_PARAM_GROUP );
\r
354 returnValue = E_NOT_OK;
\r
356 else if (!(ADC_TRIGG_SRC_SW == AdcConfigPtr->groupConfigPtr[group].triggerSrc))
\r
358 /* Wrong trig source, ADC133. */
\r
359 Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_WRONG_TRIGG_SRC);
\r
360 returnValue = E_NOT_OK;
\r
362 else if (!((ADC_IDLE == AdcConfigPtr->groupConfigPtr[group].status->groupStatus) ||
\r
363 (ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus)))
\r
365 /* Group status not OK, ADC351, ADC428 */
\r
366 Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_BUSY );
\r
368 returnValue = E_NOT_OK;
\r
372 returnValue = E_OK;
\r
375 returnValue = E_OK;
\r
377 return (returnValue);
\r
381 static Std_ReturnType Adc_CheckInit (const Adc_ConfigType *ConfigPtr)
\r
383 Std_ReturnType returnValue;
\r
385 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
386 if (!(ADC_UNINIT == adcState))
\r
388 /* Oops, already initialised. */
\r
389 Det_ReportError(MODULE_ID_ADC,0,ADC_INIT_ID, ADC_E_ALREADY_INITIALIZED );
\r
390 returnValue = E_NOT_OK;
\r
392 else if (ConfigPtr == NULL)
\r
394 /* Wrong config! */
\r
395 Det_ReportError(MODULE_ID_ADC,0,ADC_INIT_ID, ADC_E_PARAM_CONFIG );
\r
396 returnValue = E_NOT_OK;
\r
401 returnValue = E_OK;
\r
404 returnValue = E_OK;
\r
406 return (returnValue);
\r
409 static Std_ReturnType Adc_CheckSetupResultBuffer (Adc_GroupType group)
\r
411 Std_ReturnType returnValue;
\r
413 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
414 if (ADC_UNINIT == adcState)
\r
416 /* Driver not initialised. */
\r
417 Det_ReportError(MODULE_ID_ADC,0,ADC_SETUPRESULTBUFFER_ID,ADC_E_UNINIT );
\r
418 returnValue = E_NOT_OK;
\r
420 else if (group < ADC_NBR_OF_GROUPS)
\r
423 Det_ReportError(MODULE_ID_ADC,0,ADC_SETUPRESULTBUFFER_ID,ADC_E_PARAM_GROUP );
\r
424 returnValue = E_NOT_OK;
\r
429 returnValue = E_OK;
\r
432 returnValue = E_OK;
\r
434 return (returnValue);
\r