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 #if (ADC_READ_GROUP_API == STD_ON)
\r
76 static Std_ReturnType Adc_CheckReadGroup (Adc_GroupType group);
\r
78 #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)
\r
79 static Std_ReturnType Adc_CheckStartGroupConversion (Adc_GroupType group);
\r
80 static Std_ReturnType Adc_CheckStopGroupConversion (Adc_GroupType group);
\r
82 static Std_ReturnType Adc_CheckInit (const Adc_ConfigType *ConfigPtr);
\r
83 static Std_ReturnType Adc_CheckSetupResultBuffer (Adc_GroupType group);
\r
84 static Std_ReturnType Adc_CheckDeInit (void);
\r
86 static void Adc_GroupConversionComplete (void);
\r
88 static Adc_StateType adcState = ADC_UNINIT;
\r
90 /* Pointer to configuration structure. */
\r
91 static const Adc_ConfigType *AdcConfigPtr;
\r
93 /* Validate functions used for development error check */
\r
94 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
95 Std_ReturnType ValidateInit(Adc_APIServiceIDType api)
\r
97 Std_ReturnType res = E_OK;
\r
98 if(!(ADC_INIT == adcState)) {
\r
99 Det_ReportError(MODULE_ID_ADC,0,api,ADC_E_UNINIT );
\r
104 Std_ReturnType ValidateGroup(Adc_GroupType group,Adc_APIServiceIDType api)
\r
106 Std_ReturnType res = E_OK;
\r
107 if(!((group >= 0) && (group < AdcConfig->nbrOfGroups))) {
\r
108 Det_ReportError(MODULE_ID_ADC,0,api,ADC_E_PARAM_GROUP );
\r
115 #if (ADC_DEINIT_API == STD_ON)
\r
116 Std_ReturnType Adc_DeInit (const Adc_ConfigType *ConfigPtr)
\r
118 if (E_OK == Adc_CheckDeInit())
\r
120 /* Clean internal status. */
\r
121 AdcConfigPtr = (Adc_ConfigType *)NULL;
\r
122 adcState = ADC_UNINIT;
\r
129 Std_ReturnType Adc_Init (const Adc_ConfigType *ConfigPtr)
\r
131 Std_ReturnType returnValue;
\r
132 Adc_GroupType group;
\r
134 if (E_OK == Adc_CheckInit(ConfigPtr))
\r
136 /* First of all, store the location of the configuration data. */
\r
137 AdcConfigPtr = ConfigPtr;
\r
139 // Connect interrupt to correct isr
\r
140 ISR_INSTALL_ISR2("ADC",Adc_GroupConversionComplete,IRQ_TYPE_ATD0,6,0);
\r
143 ATD0CTL2 = BM_ADPU | BM_AFFC | BM_ASCIE; /* power enable, Fast Flag Clear, irq enable*/
\r
144 ATD0CTL3 = 0x03; /* 8 conversions per sequence default, freeze enable */
\r
146 ATD0CTL4 = (ConfigPtr->hwConfigPtr->resolution << 7) |
\r
147 (ConfigPtr->hwConfigPtr->convTime << 5) |
\r
148 ConfigPtr->hwConfigPtr->adcPrescale;
\r
150 for (group = 0; group < ADC_NBR_OF_GROUPS; group++)
\r
153 ConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\r
156 /* Move on to INIT state. */
\r
157 adcState = ADC_INIT;
\r
158 returnValue = E_OK;
\r
162 returnValue = E_NOT_OK;
\r
165 return (returnValue);
\r
168 Std_ReturnType Adc_SetupResultBuffer (Adc_GroupType group, Adc_ValueGroupType *bufferPtr)
\r
170 Std_ReturnType returnValue;
\r
172 /* Check for development errors. */
\r
173 if (E_OK == Adc_CheckSetupResultBuffer (group))
\r
175 AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr = bufferPtr;
\r
176 returnValue = E_OK;
\r
180 /* An error have been raised from Adc_CheckSetupResultBuffer(). */
\r
181 returnValue = E_NOT_OK;
\r
184 return (returnValue);
\r
187 #if (ADC_READ_GROUP_API == STD_ON)
\r
188 Std_ReturnType Adc_ReadGroup (Adc_GroupType group, Adc_ValueGroupType *dataBufferPtr)
\r
190 Std_ReturnType returnValue;
\r
191 Adc_ChannelType channel;
\r
193 if (E_OK == Adc_CheckReadGroup (group))
\r
195 if ((ADC_CONV_MODE_CONTINUOUS == AdcConfigPtr->groupConfigPtr[group].conversionMode) &&
\r
196 ((ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus) ||
\r
197 (ADC_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus)))
\r
199 /* ADC329, ADC331. */
\r
200 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;
\r
201 returnValue = E_OK;
\r
203 else if ((ADC_CONV_MODE_ONESHOT == AdcConfigPtr->groupConfigPtr[group].conversionMode) &&
\r
204 (ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus))
\r
207 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\r
209 returnValue = E_OK;
\r
214 returnValue = E_OK;
\r
217 if (E_OK == returnValue)
\r
219 /* Copy the result to application buffer. */
\r
220 for (channel = 0; channel < AdcConfigPtr->groupConfigPtr[group].numberOfChannels; channel++)
\r
222 dataBufferPtr[channel] = AdcConfigPtr->groupConfigPtr[group].resultBuffer[channel];
\r
228 /* An error have been raised from Adc_CheckReadGroup(). */
\r
229 returnValue = E_NOT_OK;
\r
232 return (returnValue);
\r
236 Adc_StatusType Adc_GetGroupStatus (Adc_GroupType group)
\r
238 Adc_StatusType returnValue;
\r
240 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
241 if( (ValidateInit(ADC_GETGROUPSTATUS_ID) == E_NOT_OK) ||
\r
242 (ValidateGroup(group, ADC_GETGROUPSTATUS_ID) == E_NOT_OK))
\r
244 returnValue = ADC_IDLE;
\r
248 returnValue = AdcConfigPtr->groupConfigPtr[group].status->groupStatus;
\r
251 returnValue = AdcConfigPtr->groupConfigPtr[group].status->groupStatus;
\r
253 return (returnValue);
\r
256 static void Adc_GroupConversionComplete (void)
\r
259 Adc_GroupDefType *groupPtr = NULL;
\r
260 /* Clear SCF flag. Not needed if AFFC is set but better to always do it */
\r
263 // Check which group is busy, only one is allowed to be busy at a time in a hw unit
\r
264 for (index = 0; index < ADC_NBR_OF_GROUPS; index++)
\r
266 if(AdcConfigPtr->groupConfigPtr[index].status->groupStatus == ADC_BUSY)
\r
268 groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[index];
\r
272 if(groupPtr != NULL)
\r
275 volatile uint16_t *ptr = &ATD0DR0;
\r
276 for(index=0; index<groupPtr->numberOfChannels; index++)
\r
278 groupPtr->resultBuffer[index] = *(ptr + groupPtr->channelList[index]);
\r
281 /* Sample completed. */
\r
282 groupPtr->status->groupStatus = ADC_STREAM_COMPLETED;
\r
284 /* Call notification if enabled. */
\r
285 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
\r
286 if (groupPtr->status->notifictionEnable && groupPtr->groupCallback != NULL)
\r
288 groupPtr->groupCallback();
\r
294 #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)
\r
295 void Adc_StartGroupConversion (Adc_GroupType group)
\r
297 /* Run development error check. */
\r
298 if (E_OK == Adc_CheckStartGroupConversion (group))
\r
300 /* Set single scan enable bit if this group is one shot. */
\r
301 if (AdcConfigPtr->groupConfigPtr[group].conversionMode == ADC_CONV_MODE_ONESHOT)
\r
303 /* Start next AD conversion. */
\r
304 ATD0CTL5 = BM_DJM | BM_MULT; /* 10010000 Right Justified,unsigned */
\r
305 /* No SCAN/MULT/AD0 start select */
\r
306 /* Set group state to BUSY. */
\r
307 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;
\r
312 /* Start AD conversion. */
\r
313 ATD0CTL5 = BM_DJM | BM_MULT | BM_SCAN; /* 10010000 Right Justified,unsigned */
\r
314 /* SCAN/MULT/AD0 start select */
\r
315 /* Set group state to BUSY. */
\r
316 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;
\r
321 void Adc_StopGroupConversion (Adc_GroupType group)
\r
323 /* Run development error check. */
\r
324 if (E_OK == Adc_CheckStopGroupConversion (group))
\r
326 ATD0CTL3 = 0x03; /* Hard write to stop current conversion */
\r
330 /* Error have been set within Adc_CheckStartGroupConversion(). */
\r
335 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
\r
336 void Adc_EnableGroupNotification (Adc_GroupType group)
\r
338 Std_ReturnType res;
\r
340 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
341 if( (ValidateInit(ADC_ENABLEGROUPNOTIFICATION_ID) == E_NOT_OK) ||
\r
342 (ValidateGroup(group, ADC_ENABLEGROUPNOTIFICATION_ID) == E_NOT_OK))
\r
346 else if (AdcConfigPtr->groupConfigPtr[group].groupCallback == NULL)
\r
349 Det_ReportError(MODULE_ID_ADC,0,ADC_ENABLEGROUPNOTIFICATION_ID ,ADC_E_NOTIF_CAPABILITY );
\r
353 /* Nothing strange. Go on... */
\r
360 AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable = 1;
\r
364 void Adc_DisableGroupNotification (Adc_GroupType group)
\r
366 Std_ReturnType res;
\r
368 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
369 if( (ValidateInit(ADC_DISABLEGROUPNOTIFICATION_ID) == E_NOT_OK) ||
\r
370 (ValidateGroup(group, ADC_DISABLEGROUPNOTIFICATION_ID) == E_NOT_OK))
\r
374 else if (AdcConfigPtr->groupConfigPtr[group].groupCallback == NULL)
\r
377 Det_ReportError(MODULE_ID_ADC,0,ADC_DISABLEGROUPNOTIFICATION_ID ,ADC_E_NOTIF_CAPABILITY );
\r
381 /* Nothing strange. Go on... */
\r
388 AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable = 0;
\r
394 /* Development error checking functions. */
\r
395 #if (ADC_READ_GROUP_API == STD_ON)
\r
396 static Std_ReturnType Adc_CheckReadGroup (Adc_GroupType group)
\r
398 Std_ReturnType returnValue;
\r
400 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
402 if (ADC_UNINIT == adcState)
\r
405 returnValue = E_NOT_OK;
\r
406 Det_ReportError(MODULE_ID_ADC,0,ADC_READGROUP_ID ,ADC_E_UNINIT );
\r
408 else if ((group < ADC_GROUP0) || (group >= ADC_NBR_OF_GROUPS))
\r
411 returnValue = E_NOT_OK;
\r
412 Det_ReportError(MODULE_ID_ADC,0,ADC_READGROUP_ID ,ADC_E_PARAM_GROUP );
\r
414 else if (ADC_IDLE == AdcConfigPtr->groupConfigPtr[group].status->groupStatus)
\r
417 returnValue = E_NOT_OK;
\r
418 Det_ReportError(MODULE_ID_ADC,0,ADC_READGROUP_ID ,ADC_E_IDLE );
\r
422 /* Nothing strange. Go on... */
\r
423 returnValue = E_OK;
\r
426 returnValue = E_OK;
\r
428 return (returnValue);
\r
432 #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)
\r
433 static Std_ReturnType Adc_CheckStartGroupConversion (Adc_GroupType group)
\r
435 Std_ReturnType returnValue;
\r
437 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
439 if( (ValidateInit(ADC_STARTGROUPCONVERSION_ID) == E_NOT_OK) ||
\r
440 (ValidateGroup(group, ADC_STARTGROUPCONVERSION_ID) == E_NOT_OK))
\r
442 returnValue = E_NOT_OK;
\r
444 else if ( NULL == AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr )
\r
446 /* ResultBuffer not set, ADC424 */
\r
447 Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_BUFFER_UNINIT );
\r
448 returnValue = E_NOT_OK;
\r
450 else if (!(ADC_TRIGG_SRC_SW == AdcConfigPtr->groupConfigPtr[group].triggerSrc))
\r
452 /* Wrong trig source, ADC133. */
\r
453 Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_WRONG_TRIGG_SRC);
\r
454 returnValue = E_NOT_OK;
\r
456 else if (!((ADC_IDLE == AdcConfigPtr->groupConfigPtr[group].status->groupStatus) ||
\r
457 (ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus)))
\r
459 /* Group status not OK, ADC351, ADC428 */
\r
460 Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_BUSY );
\r
464 * Sometimes the ADC-interrupt gets lost which means that the status is never reset to ADC_IDLE (done in Adc_ReadGroup).
\r
465 * Therefor another group conversion is never started...
\r
467 * The temporary fix is to always return E_OK here. But the reason for the bug needs to be investigated further.
\r
469 //returnValue = E_NOT_OK;
\r
470 returnValue = E_OK;
\r
474 returnValue = E_OK;
\r
477 returnValue = E_OK;
\r
480 return (returnValue);
\r
483 static Std_ReturnType Adc_CheckStopGroupConversion (Adc_GroupType group)
\r
485 Std_ReturnType returnValue;
\r
487 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
488 if( (ValidateInit(ADC_STOPGROUPCONVERSION_ID) == E_NOT_OK) ||
\r
489 (ValidateGroup(group, ADC_STOPGROUPCONVERSION_ID) == E_NOT_OK))
\r
491 returnValue = E_NOT_OK;
\r
493 else if (!(ADC_TRIGG_SRC_SW == AdcConfigPtr->groupConfigPtr[group].triggerSrc))
\r
495 /* Wrong trig source, ADC164. */
\r
496 Det_ReportError(MODULE_ID_ADC,0,ADC_STOPGROUPCONVERSION_ID, ADC_E_WRONG_TRIGG_SRC);
\r
497 returnValue = E_NOT_OK;
\r
499 else if (ADC_IDLE == AdcConfigPtr->groupConfigPtr[group].status->groupStatus)
\r
501 /* Group status not OK, ADC241 */
\r
502 Det_ReportError(MODULE_ID_ADC,0,ADC_STOPGROUPCONVERSION_ID, ADC_E_IDLE );
\r
503 returnValue = E_NOT_OK;
\r
507 returnValue = E_OK;
\r
510 returnValue = E_OK;
\r
513 return (returnValue);
\r
517 static Std_ReturnType Adc_CheckInit (const Adc_ConfigType *ConfigPtr)
\r
519 Std_ReturnType returnValue;
\r
521 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
522 if (!(ADC_UNINIT == adcState))
\r
524 /* Oops, already initialised. */
\r
525 Det_ReportError(MODULE_ID_ADC,0,ADC_INIT_ID, ADC_E_ALREADY_INITIALIZED );
\r
526 returnValue = E_NOT_OK;
\r
528 else if (ConfigPtr == NULL)
\r
530 /* Wrong config! */
\r
531 Det_ReportError(MODULE_ID_ADC,0,ADC_INIT_ID, ADC_E_PARAM_CONFIG );
\r
532 returnValue = E_NOT_OK;
\r
537 returnValue = E_OK;
\r
540 returnValue = E_OK;
\r
542 return (returnValue);
\r
545 static Std_ReturnType Adc_CheckDeInit (void)
\r
547 Std_ReturnType returnValue = E_OK;
\r
549 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
550 if(ValidateInit(ADC_DEINIT_ID) == E_OK)
\r
552 for (Adc_GroupType group = ADC_GROUP0; group < AdcConfigPtr->nbrOfGroups; group++)
\r
554 /* Check ADC is IDLE or COMPLETE*/
\r
555 if((AdcConfigPtr->groupConfigPtr[group].status->groupStatus != ADC_IDLE) && (AdcConfigPtr->groupConfigPtr[group].status->groupStatus != ADC_STREAM_COMPLETED))
\r
557 Det_ReportError(MODULE_ID_ADC,0,ADC_DEINIT_ID, ADC_E_BUSY );
\r
558 returnValue = E_NOT_OK;
\r
564 returnValue = E_NOT_OK;
\r
567 returnValue = E_OK;
\r
569 return (returnValue);
\r
571 static Std_ReturnType Adc_CheckSetupResultBuffer (Adc_GroupType group)
\r
573 Std_ReturnType returnValue = E_OK;
\r
575 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
576 if(ValidateGroup(group, ADC_SETUPRESULTBUFFER_ID) == E_NOT_OK)
\r
578 returnValue = E_NOT_OK;
\r
581 returnValue = E_OK;
\r
583 return (returnValue);
\r