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
19 //#include "System.h"
\r
20 //#include "Modules.h"
\r
23 #include "stm32f10x_adc.h"
\r
24 #include "stm32f10x_dma.h"
\r
26 #if defined(USE_KERNEL)
\r
38 /* Conversion result register for ADC1. */
\r
39 #define ADC1_DR_Address ((u32)0x4001244C)
\r
41 /* Function prototypes. */
\r
43 /* Development error checking. */
\r
44 static Std_ReturnType Adc_CheckReadGroup (Adc_GroupType group);
\r
45 static Std_ReturnType Adc_CheckStartGroupConversion (Adc_GroupType group);
\r
46 static Std_ReturnType Adc_CheckInit (const Adc_ConfigType *ConfigPtr);
\r
47 static Std_ReturnType Adc_CheckSetupResultBuffer (Adc_GroupType group);
\r
49 static void Adc_Group0ConversionComplete (void);
\r
52 static Adc_StateType adcState = ADC_UNINIT;
\r
54 /* Pointer to configuration structure. */
\r
55 static const Adc_ConfigType *AdcConfigPtr;
\r
58 #if (ADC_DEINIT_API == STD_ON)
\r
59 Std_ReturnType Adc_DeInit (const Adc_ConfigType *ConfigPtr)
\r
61 DMA_DeInit(DMA1_Channel1);
\r
68 Std_ReturnType Adc_Init (const Adc_ConfigType *ConfigPtr)
\r
70 Std_ReturnType returnValue;
\r
71 Adc_ChannelType channel;
\r
72 Adc_ChannelType channelId;
\r
73 Adc_GroupType group;
\r
75 ADC_InitTypeDef ADC_InitStructure;
\r
76 DMA_InitTypeDef DMA_InitStructure;
\r
78 ADC_TempSensorVrefintCmd(ENABLE);
\r
80 if (E_OK == Adc_CheckInit(ConfigPtr))
\r
82 /* First of all, store the location of the configuration data. */
\r
83 AdcConfigPtr = ConfigPtr;
\r
85 /* DMA1 channel1 configuration ---------------------------------------------*/
\r
86 DMA_DeInit(DMA1_Channel1);
\r
87 DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
\r
88 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ConfigPtr->groupConfigPtr->resultBuffer;
\r
89 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
\r
90 DMA_InitStructure.DMA_BufferSize = ConfigPtr->groupConfigPtr->numberOfChannels;
\r
91 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
\r
92 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
\r
93 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
\r
94 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
\r
95 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
\r
96 DMA_InitStructure.DMA_Priority = DMA_Priority_High;
\r
97 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
\r
98 DMA_Init(DMA1_Channel1, &DMA_InitStructure);
\r
100 // Connect interrupt to correct isr
\r
102 tid = Os_Arc_CreateIsr(Adc_Group0ConversionComplete,6/*prio*/,"DMA1");
\r
103 Irq_AttachIsr2(tid,NULL, DMA1_Channel1_IRQn);
\r
105 /* Enable DMA1 channel1 */
\r
106 DMA_Cmd(DMA1_Channel1, ENABLE);
\r
108 /* Enable the DMA1 Channel1 Transfer complete interrupt */
\r
109 DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
\r
111 /* ADC1 configuration ------------------------------------------------------*/
\r
112 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
\r
113 ADC_InitStructure.ADC_ScanConvMode = ENABLE;
\r
114 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
\r
115 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
\r
116 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
\r
117 ADC_InitStructure.ADC_NbrOfChannel = ConfigPtr->groupConfigPtr->numberOfChannels;
\r
118 ADC_Init(ADC1, &ADC_InitStructure);
\r
120 /* Start configuring the channel queues. */
\r
121 for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)
\r
123 /* Loop through all channels and make the command queue. */
\r
124 for (channel = 0; channel < ConfigPtr->groupConfigPtr[group].numberOfChannels; channel++)
\r
126 /* Get physical channel. */
\r
127 channelId = ConfigPtr->groupConfigPtr[group].channelList[channel];
\r
129 /* Configure channel as regular. */
\r
130 ADC_RegularChannelConfig(ADC1, channelId, channel+1,
\r
131 ConfigPtr->channelConfigPtr [channel].adcChannelConvTime);
\r
136 for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)
\r
139 ConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\r
142 /* Enable ADC1 DMA */
\r
143 ADC_DMACmd(ADC1, ENABLE);
\r
146 ADC_Cmd(ADC1, ENABLE);
\r
148 /* Enable ADC1 reset calibaration register */
\r
149 ADC_ResetCalibration(ADC1);
\r
150 /* Check the end of ADC1 reset calibration register */
\r
151 while(ADC_GetResetCalibrationStatus(ADC1));
\r
153 /* Start ADC1 calibaration */
\r
154 ADC_StartCalibration(ADC1);
\r
156 /* Check the end of ADC1 calibration */
\r
157 while(ADC_GetCalibrationStatus(ADC1));
\r
159 /* Move on to INIT state. */
\r
160 adcState = ADC_INIT;
\r
161 returnValue = E_OK;
\r
165 returnValue = E_NOT_OK;
\r
168 return (returnValue);
\r
171 Std_ReturnType Adc_SetupResultBuffer (Adc_GroupType group, Adc_ValueGroupType *bufferPtr)
\r
173 Std_ReturnType returnValue;
\r
175 /* Check for development errors. */
\r
176 if (E_OK == Adc_CheckSetupResultBuffer (group))
\r
178 AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr = bufferPtr;
\r
179 returnValue = E_OK;
\r
183 /* An error have been raised from Adc_CheckSetupResultBuffer(). */
\r
184 returnValue = E_NOT_OK;
\r
187 return (returnValue);
\r
190 #if (ADC_READ_GROUP_API == STD_ON)
\r
191 Std_ReturnType Adc_ReadGroup (Adc_GroupType group, Adc_ValueGroupType *dataBufferPtr)
\r
193 Std_ReturnType returnValue;
\r
194 Adc_ChannelType channel;
\r
196 if (E_OK == Adc_CheckReadGroup (group))
\r
198 if ((ADC_CONV_MODE_CONTINUOUS == AdcConfigPtr->groupConfigPtr[group].conversionMode) &&
\r
199 ((ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus) ||
\r
200 (ADC_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus)))
\r
202 /* ADC329, ADC331. */
\r
203 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;
\r
204 returnValue = E_OK;
\r
206 else if ((ADC_CONV_MODE_ONESHOT == AdcConfigPtr->groupConfigPtr[group].conversionMode) &&
\r
207 (ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus))
\r
210 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE;
\r
212 returnValue = E_OK;
\r
217 returnValue = E_OK;
\r
220 if (E_OK == returnValue)
\r
222 /* Copy the result to application buffer. */
\r
223 for (channel = 0; channel < AdcConfigPtr->groupConfigPtr[group].numberOfChannels; channel++)
\r
225 dataBufferPtr[channel] = AdcConfigPtr->groupConfigPtr[group].resultBuffer[channel];
\r
231 /* An error have been raised from Adc_CheckReadGroup(). */
\r
232 returnValue = E_NOT_OK;
\r
235 return (returnValue);
\r
239 Adc_StatusType Adc_GetGroupStatus (Adc_GroupType group)
\r
241 Adc_StatusType returnValue;
\r
242 if ((ADC_INIT == adcState) && (AdcConfigPtr != NULL))
\r
244 /* Adc initilised, OK to move on... */
\r
245 returnValue = AdcConfigPtr->groupConfigPtr[group].status->groupStatus;
\r
249 returnValue = ADC_IDLE;
\r
250 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
251 Det_ReportError(MODULE_ID_ADC,0,ADC_GETGROUPSTATUS_ID, ADC_E_UNINIT );
\r
255 return (returnValue);
\r
259 static void Adc_Group0ConversionComplete (void)
\r
261 /* ISR for DMA. Clear interrupt flag. */
\r
262 DMA_ClearFlag(DMA1_FLAG_TC1);
\r
264 /* Sample completed. */
\r
265 AdcConfigPtr->groupConfigPtr[ADC_GROUP0].status->groupStatus = ADC_STREAM_COMPLETED;
\r
267 /* Call notification if enabled. */
\r
268 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
\r
269 if (AdcConfigPtr->groupConfigPtr[ADC_GROUP0].status->notifictionEnable && AdcConfigPtr->groupConfigPtr[ADC_GROUP0].groupCallback != NULL)
\r
271 AdcConfigPtr->groupConfigPtr[ADC_GROUP0].groupCallback();
\r
276 #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)
\r
277 void Adc_StartGroupConversion (Adc_GroupType group)
\r
279 /* Run development error check. */
\r
280 if (E_OK == Adc_CheckStartGroupConversion (group))
\r
282 /* Set conversion mode. */
\r
283 /* Only software trigged single scan supported. */
\r
285 /* Set single scan enable bit if this group is one shot. */
\r
286 if (AdcConfigPtr->groupConfigPtr[group].conversionMode == ADC_CONV_MODE_ONESHOT)
\r
288 ADC_SoftwareStartConvCmd(ADC1, ENABLE);
\r
289 /* Set group state to BUSY. */
\r
290 AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;
\r
295 /* Error have been set within Adc_CheckStartGroupConversion(). */
\r
302 #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
\r
303 void Adc_EnableGroupNotification (Adc_GroupType group)
\r
305 AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable = 1;
\r
308 void Adc_DisableGroupNotification (Adc_GroupType group)
\r
310 AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable = 0;
\r
315 /* Development error checking functions. */
\r
316 #if (ADC_READ_GROUP_API == STD_ON)
\r
317 static Std_ReturnType Adc_CheckReadGroup (Adc_GroupType group)
\r
319 Std_ReturnType returnValue;
\r
321 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
323 if (ADC_UNINIT == adcState)
\r
326 returnValue = E_NOT_OK;
\r
327 Det_ReportError(MODULE_ID_ADC,0,ADC_READGROUP_ID ,ADC_E_UNINIT );
\r
329 else if ((group < ADC_GROUP0) || (group >= AdcConfigPtr->nbrOfGroups))
\r
332 returnValue = E_NOT_OK;
\r
333 Det_ReportError(MODULE_ID_ADC,0,ADC_READGROUP_ID ,ADC_E_PARAM_GROUP );
\r
335 else if (ADC_IDLE == AdcConfigPtr->groupConfigPtr[group].status->groupStatus)
\r
338 returnValue = E_NOT_OK;
\r
339 Det_ReportError(MODULE_ID_ADC,0,ADC_READGROUP_ID ,ADC_E_IDLE );
\r
343 /* Nothing strange. Go on... */
\r
344 returnValue = E_OK;
\r
347 returnValue = E_OK;
\r
349 return (returnValue);
\r
353 #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)
\r
354 static Std_ReturnType Adc_CheckStartGroupConversion (Adc_GroupType group)
\r
356 Std_ReturnType returnValue;
\r
357 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
358 if (!(ADC_INIT == adcState))
\r
360 /* ADC not initialised, ADC294. */
\r
361 Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_UNINIT );
\r
362 returnValue = E_NOT_OK;
\r
364 else if (!((group >= 0) && (group < AdcConfig->nbrOfGroups)))
\r
366 /* Wrong group ID, ADC125 */
\r
367 Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_PARAM_GROUP );
\r
368 returnValue = E_NOT_OK;
\r
370 else if (!(ADC_TRIGG_SRC_SW == AdcConfigPtr->groupConfigPtr[group].triggerSrc))
\r
372 /* Wrong trig source, ADC133. */
\r
373 Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_WRONG_TRIGG_SRC);
\r
374 returnValue = E_NOT_OK;
\r
376 else if (!((ADC_IDLE == AdcConfigPtr->groupConfigPtr[group].status->groupStatus) ||
\r
377 (ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus)))
\r
379 /* Group status not OK, ADC351, ADC428 */
\r
380 Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_BUSY );
\r
384 * Sometimes the ADC-interrupt gets lost which means that the status is never reset to ADC_IDLE (done in Adc_ReadGroup).
\r
385 * Therefor another group conversion is never started...
\r
387 * The temporary fix is to always return E_OK here. But the reason for the bug needs to be investigated further.
\r
389 //returnValue = E_NOT_OK;
\r
390 returnValue = E_OK;
\r
394 returnValue = E_OK;
\r
397 returnValue = E_OK;
\r
399 return (returnValue);
\r
403 static Std_ReturnType Adc_CheckInit (const Adc_ConfigType *ConfigPtr)
\r
405 Std_ReturnType returnValue;
\r
407 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
408 if (!(ADC_UNINIT == adcState))
\r
410 /* Oops, already initialised. */
\r
411 Det_ReportError(MODULE_ID_ADC,0,ADC_INIT_ID, ADC_E_ALREADY_INITIALIZED );
\r
412 returnValue = E_NOT_OK;
\r
414 else if (ConfigPtr == NULL)
\r
416 /* Wrong config! */
\r
417 Det_ReportError(MODULE_ID_ADC,0,ADC_INIT_ID, ADC_E_PARAM_CONFIG );
\r
418 returnValue = E_NOT_OK;
\r
423 returnValue = E_OK;
\r
426 returnValue = E_OK;
\r
428 return (returnValue);
\r
431 static Std_ReturnType Adc_CheckSetupResultBuffer (Adc_GroupType group)
\r
433 Std_ReturnType returnValue;
\r
435 #if ( ADC_DEV_ERROR_DETECT == STD_ON )
\r
436 if (ADC_UNINIT == adcState)
\r
438 /* Driver not initialised. */
\r
439 Det_ReportError(MODULE_ID_ADC,0,ADC_SETUPRESULTBUFFER_ID,ADC_E_UNINIT );
\r
440 returnValue = E_NOT_OK;
\r
442 else if (group < AdcConfigPtr->nbrOfGroups)
\r
445 Det_ReportError(MODULE_ID_ADC,0,ADC_SETUPRESULTBUFFER_ID,ADC_E_PARAM_GROUP );
\r
446 returnValue = E_NOT_OK;
\r
451 returnValue = E_OK;
\r
454 returnValue = E_OK;
\r
456 return (returnValue);
\r