/* Function prototypes. */\r
\r
/* Development error checking. */\r
+#if (ADC_READ_GROUP_API == STD_ON)\r
static Std_ReturnType Adc_CheckReadGroup (Adc_GroupType group);\r
+#endif\r
+#if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)\r
static Std_ReturnType Adc_CheckStartGroupConversion (Adc_GroupType group);\r
+static Std_ReturnType Adc_CheckStopGroupConversion (Adc_GroupType group);\r
+#endif\r
static Std_ReturnType Adc_CheckInit (const Adc_ConfigType *ConfigPtr);\r
static Std_ReturnType Adc_CheckSetupResultBuffer (Adc_GroupType group);\r
+static Std_ReturnType Adc_CheckDeInit (void);\r
\r
static void Adc_Group0ConversionComplete (void);\r
\r
\r
/* VALIDATION MACROS */\r
\r
+/* Validate functions used for development error check */\r
+#if ( ADC_DEV_ERROR_DETECT == STD_ON )\r
+Std_ReturnType ValidateInit(Adc_APIServiceIDType api)\r
+{\r
+ Std_ReturnType res = E_OK;\r
+ if(!(ADC_INIT == adcState)) {\r
+ Det_ReportError(MODULE_ID_ADC,0,api,ADC_E_UNINIT );\r
+ res = E_NOT_OK;\r
+ }\r
+ return res;\r
+}\r
+Std_ReturnType ValidateGroup(Adc_GroupType group,Adc_APIServiceIDType api)\r
+{\r
+ Std_ReturnType res = E_OK;\r
+ if(!((group >= 0) && (group < AdcConfig->nbrOfGroups))) {\r
+ Det_ReportError(MODULE_ID_ADC,0,api,ADC_E_PARAM_GROUP );\r
+ res = E_NOT_OK;\r
+ }\r
+ return res;\r
+}\r
+#endif\r
\r
#if (ADC_DEINIT_API == STD_ON)\r
Std_ReturnType Adc_DeInit (const Adc_ConfigType *ConfigPtr)\r
{\r
- ADC_VALIDATE_INITIALIZED( ADC_DEINIT_ID, E_NOT_OK );\r
-\r
- DMA_DeInit(DMA1_Channel1);\r
- ADC_DeInit(ADC1);\r
+ if (E_OK == Adc_CheckDeInit())\r
+ {\r
+ DMA_DeInit(DMA1_Channel1);\r
+ ADC_DeInit(ADC1);\r
\r
- adcState = ADC_UNINIT;\r
+ adcState = ADC_UNINIT;\r
+ }\r
\r
- return (E_OK);\r
+ return (E_OK);\r
}\r
#endif\r
\r
Std_ReturnType Adc_Init (const Adc_ConfigType *ConfigPtr)\r
{\r
- ADC_VALIDATE_NOT_INITIALIZED( ADC_INIT_ID, E_NOT_OK );\r
-\r
Std_ReturnType returnValue;\r
- Adc_ChannelType channel;\r
- Adc_ChannelType channelId;\r
Adc_GroupType group;\r
\r
ADC_InitTypeDef ADC_InitStructure;\r
ADC_InitStructure.ADC_NbrOfChannel = ConfigPtr->groupConfigPtr->numberOfChannels;\r
ADC_Init(ADC1, &ADC_InitStructure);\r
\r
- /* Start configuring the channel queues. */\r
- for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)\r
- {\r
- /* Loop through all channels and make the command queue. */\r
- for (channel = 0; channel < ConfigPtr->groupConfigPtr[group].numberOfChannels; channel++)\r
- {\r
- /* Get physical channel. */\r
- channelId = ConfigPtr->groupConfigPtr[group].channelList[channel];\r
-\r
- /* Configure channel as regular. */\r
- ADC_RegularChannelConfig(ADC1, channelId, channel+1,\r
- ConfigPtr->channelConfigPtr [channel].adcChannelConvTime);\r
-\r
- }\r
- }\r
-\r
for (group = ADC_GROUP0; group < ConfigPtr->nbrOfGroups; group++)\r
{\r
/* ADC307. */\r
if (E_OK == Adc_CheckSetupResultBuffer (group))\r
{\r
AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr = bufferPtr;\r
+ DMA_Cmd(DMA1_Channel1, DISABLE);\r
+ DMA1_Channel1->CMAR = (u32)AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr;\r
+ DMA1_Channel1->CNDTR = AdcConfigPtr->groupConfigPtr[group].numberOfChannels;\r
+ DMA_Cmd(DMA1_Channel1, ENABLE);\r
returnValue = E_OK;\r
}\r
else\r
/* ADC329, ADC331. */\r
AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;\r
returnValue = E_OK;\r
+\r
+ /* Restart continous again after read */\r
+ ADC_SoftwareStartConvCmd(ADC1, ENABLE);\r
}\r
else if ((ADC_CONV_MODE_ONESHOT == AdcConfigPtr->groupConfigPtr[group].conversionMode) &&\r
(ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus))\r
/* Copy the result to application buffer. */\r
for (channel = 0; channel < AdcConfigPtr->groupConfigPtr[group].numberOfChannels; channel++)\r
{\r
- dataBufferPtr[channel] = AdcConfigPtr->groupConfigPtr[group].resultBuffer[channel];\r
+ dataBufferPtr[channel] = AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr[channel];\r
}\r
}\r
}\r
\r
Adc_StatusType Adc_GetGroupStatus (Adc_GroupType group)\r
{\r
- Adc_StatusType returnValue;\r
- if ((ADC_INIT == adcState) && (AdcConfigPtr != NULL))\r
- {\r
- /* Adc initilised, OK to move on... */\r
- returnValue = AdcConfigPtr->groupConfigPtr[group].status->groupStatus;\r
- }\r
- else\r
- {\r
- returnValue = ADC_IDLE;\r
+ Adc_StatusType returnValue;\r
+\r
#if ( ADC_DEV_ERROR_DETECT == STD_ON )\r
- Det_ReportError(MODULE_ID_ADC,0,ADC_GETGROUPSTATUS_ID, ADC_E_UNINIT );\r
+ if( (ValidateInit(ADC_GETGROUPSTATUS_ID) == E_NOT_OK) ||\r
+ (ValidateGroup(group, ADC_GETGROUPSTATUS_ID) == E_NOT_OK))\r
+ {\r
+ returnValue = ADC_IDLE;\r
+ }\r
+ else\r
+ {\r
+ returnValue = AdcConfigPtr->groupConfigPtr[group].status->groupStatus;\r
+ }\r
+#else\r
+ returnValue = AdcConfigPtr->groupConfigPtr[group].status->groupStatus;\r
#endif\r
- }\r
-\r
return (returnValue);\r
}\r
\r
\r
static void Adc_Group0ConversionComplete (void)\r
{\r
+ Adc_GroupDefType *groupPtr = NULL;\r
+\r
/* ISR for DMA. Clear interrupt flag. */\r
DMA_ClearFlag(DMA1_FLAG_TC1);\r
\r
- /* Sample completed. */\r
- AdcConfigPtr->groupConfigPtr[ADC_GROUP0].status->groupStatus = ADC_STREAM_COMPLETED;\r
-\r
- /* Call notification if enabled. */\r
-#if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)\r
- if (AdcConfigPtr->groupConfigPtr[ADC_GROUP0].status->notifictionEnable && AdcConfigPtr->groupConfigPtr[ADC_GROUP0].groupCallback != NULL)\r
+ // Check which group is busy, only one is allowed to be busy at a time in a hw unit\r
+ for (uint8 index = 0; index < ADC_NBR_OF_GROUPS; index++)\r
{\r
- AdcConfigPtr->groupConfigPtr[ADC_GROUP0].groupCallback();\r
+ if(AdcConfigPtr->groupConfigPtr[index].status->groupStatus == ADC_BUSY)\r
+ {\r
+ groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[index];\r
+ break;\r
+ }\r
+ }\r
+ if(groupPtr != NULL)\r
+ {\r
+ if(ADC_CONV_MODE_ONESHOT == groupPtr->conversionMode)\r
+ {\r
+ groupPtr->status->groupStatus = ADC_STREAM_COMPLETED;\r
+\r
+ /* Call notification if enabled. */\r
+ #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)\r
+ if (groupPtr->status->notifictionEnable && groupPtr->groupCallback != NULL)\r
+ {\r
+ groupPtr->groupCallback();\r
+ }\r
+ #endif\r
+ }\r
+ else{\r
+ //Only single access supported so far for continous\r
+ groupPtr->status->groupStatus = ADC_STREAM_COMPLETED;\r
+\r
+ /* Call notification if enabled. */\r
+ #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)\r
+ if (groupPtr->status->notifictionEnable && groupPtr->groupCallback != NULL)\r
+ {\r
+ groupPtr->groupCallback();\r
+ }\r
+ #endif\r
+ }\r
}\r
-#endif\r
}\r
\r
#if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)\r
/* Run development error check. */\r
if (E_OK == Adc_CheckStartGroupConversion (group))\r
{\r
- /* Set conversion mode. */\r
- /* Only software trigged single scan supported. */\r
+ Adc_ChannelType channel;\r
+ Adc_ChannelType channelId;\r
\r
- /* Set single scan enable bit if this group is one shot. */\r
- if (AdcConfigPtr->groupConfigPtr[group].conversionMode == ADC_CONV_MODE_ONESHOT)\r
- {\r
- ADC_SoftwareStartConvCmd(ADC1, ENABLE);\r
- /* Set group state to BUSY. */\r
- AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;\r
- }\r
+ /* Configure the channel queue. */\r
+ ADC1->SQR1 = (AdcConfigPtr->groupConfigPtr[group].numberOfChannels -1) << 20;\r
+ ADC1->SQR2 = 0;\r
+ ADC1->SQR3 = 0;\r
+ /* Loop through all channels and make the command queue. */\r
+ for (channel = 0; channel < AdcConfigPtr->groupConfigPtr[group].numberOfChannels; channel++)\r
+ {\r
+ /* Get physical channel. */\r
+ channelId = AdcConfigPtr->groupConfigPtr[group].channelList[channel];\r
+\r
+ /* Configure channel as regular. */\r
+ ADC_RegularChannelConfig(ADC1, channelId, channel+1,\r
+ AdcConfigPtr->channelConfigPtr [channel].adcChannelConvTime);\r
+\r
+ }\r
+\r
+ /* Set conversion mode. No need we run always in single shot and handle continous ourselves */\r
+/* if (AdcConfigPtr->groupConfigPtr[group].conversionMode == ADC_CONV_MODE_ONESHOT){\r
+ ADC1->CR2 = ADC1->CR2 & ~(1<<1);\r
+ }else{\r
+ ADC1->CR2 = ADC1->CR2 | (1<<1);\r
+ }*/\r
+\r
+ ADC_SoftwareStartConvCmd(ADC1, ENABLE);\r
+ /* Set group state to BUSY. */\r
+ AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_BUSY;\r
}\r
else\r
{\r
}\r
}\r
\r
-\r
+void Adc_StopGroupConversion (Adc_GroupType group)\r
+{\r
+ /* Run development error check. */\r
+ if (E_OK == Adc_CheckStopGroupConversion (group))\r
+ {\r
+ ADC_SoftwareStartConvCmd(ADC1, DISABLE);\r
+ }\r
+ else\r
+ {\r
+ /* Error have been set within Adc_CheckStartGroupConversion(). */\r
+ }\r
+}\r
#endif\r
\r
#if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)\r
void Adc_EnableGroupNotification (Adc_GroupType group)\r
{\r
- AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable = 1;\r
+ Std_ReturnType res;\r
+\r
+#if ( ADC_DEV_ERROR_DETECT == STD_ON )\r
+ if( (ValidateInit(ADC_ENABLEGROUPNOTIFICATION_ID) == E_NOT_OK) ||\r
+ (ValidateGroup(group, ADC_ENABLEGROUPNOTIFICATION_ID) == E_NOT_OK))\r
+ {\r
+ res = E_NOT_OK;\r
+ }\r
+ else if (AdcConfigPtr->groupConfigPtr[group].groupCallback == NULL)\r
+ {\r
+ res = E_NOT_OK;\r
+ Det_ReportError(MODULE_ID_ADC,0,ADC_ENABLEGROUPNOTIFICATION_ID ,ADC_E_NOTIF_CAPABILITY );\r
+ }\r
+ else\r
+ {\r
+ /* Nothing strange. Go on... */\r
+ res = E_OK;\r
+ }\r
+#else\r
+ res = E_OK;\r
+#endif\r
+ if (E_OK == res){\r
+ AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable = 1;\r
+ }\r
}\r
\r
void Adc_DisableGroupNotification (Adc_GroupType group)\r
{\r
- AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable = 0;\r
+ Std_ReturnType res;\r
+\r
+#if ( ADC_DEV_ERROR_DETECT == STD_ON )\r
+ if( (ValidateInit(ADC_DISABLEGROUPNOTIFICATION_ID) == E_NOT_OK) ||\r
+ (ValidateGroup(group, ADC_DISABLEGROUPNOTIFICATION_ID) == E_NOT_OK))\r
+ {\r
+ res = E_NOT_OK;\r
+ }\r
+ else if (AdcConfigPtr->groupConfigPtr[group].groupCallback == NULL)\r
+ {\r
+ res = E_NOT_OK;\r
+ Det_ReportError(MODULE_ID_ADC,0,ADC_DISABLEGROUPNOTIFICATION_ID ,ADC_E_NOTIF_CAPABILITY );\r
+ }\r
+ else\r
+ {\r
+ /* Nothing strange. Go on... */\r
+ res = E_OK;\r
+ }\r
+#else\r
+ res = E_OK;\r
+#endif\r
+ if (E_OK == res){\r
+ AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable = 0;\r
+ }\r
}\r
#endif\r
\r
\r
#if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON)\r
static Std_ReturnType Adc_CheckStartGroupConversion (Adc_GroupType group)\r
+{\r
+ Std_ReturnType returnValue;\r
+\r
+ #if ( ADC_DEV_ERROR_DETECT == STD_ON )\r
+\r
+ if( (ValidateInit(ADC_STARTGROUPCONVERSION_ID) == E_NOT_OK) ||\r
+ (ValidateGroup(group, ADC_STARTGROUPCONVERSION_ID) == E_NOT_OK))\r
+ {\r
+ returnValue = E_NOT_OK;\r
+ }\r
+ else if ( NULL == AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr )\r
+ {\r
+ /* ResultBuffer not set, ADC424 */\r
+ Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_BUFFER_UNINIT );\r
+ returnValue = E_NOT_OK;\r
+ }\r
+ else if (!(ADC_TRIGG_SRC_SW == AdcConfigPtr->groupConfigPtr[group].triggerSrc))\r
+ {\r
+ /* Wrong trig source, ADC133. */\r
+ Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_WRONG_TRIGG_SRC);\r
+ returnValue = E_NOT_OK;\r
+ }\r
+ else if (!((ADC_IDLE == AdcConfigPtr->groupConfigPtr[group].status->groupStatus) ||\r
+ (ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus)))\r
+ {\r
+ /* Group status not OK, ADC351, ADC428 */\r
+ Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_BUSY );\r
+\r
+ //returnValue = E_NOT_OK;\r
+ returnValue = E_OK;\r
+ }\r
+ else\r
+ {\r
+ returnValue = E_OK;\r
+ }\r
+ #else\r
+ returnValue = E_OK;\r
+ #endif\r
+\r
+ return (returnValue);\r
+}\r
+static Std_ReturnType Adc_CheckStopGroupConversion (Adc_GroupType group)\r
{\r
Std_ReturnType returnValue;\r
+\r
#if ( ADC_DEV_ERROR_DETECT == STD_ON )\r
- if (!(ADC_INIT == adcState))\r
- {\r
- /* ADC not initialised, ADC294. */\r
- Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_UNINIT );\r
- returnValue = E_NOT_OK;\r
- }\r
- else if (!((group >= 0) && (group < AdcConfig->nbrOfGroups)))\r
+ if( (ValidateInit(ADC_STOPGROUPCONVERSION_ID) == E_NOT_OK) ||\r
+ (ValidateGroup(group, ADC_STOPGROUPCONVERSION_ID) == E_NOT_OK))\r
{\r
- /* Wrong group ID, ADC125 */\r
- Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_PARAM_GROUP );\r
- returnValue = E_NOT_OK;\r
+ returnValue = E_NOT_OK;\r
}\r
else if (!(ADC_TRIGG_SRC_SW == AdcConfigPtr->groupConfigPtr[group].triggerSrc))\r
{\r
- /* Wrong trig source, ADC133. */\r
- Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_WRONG_TRIGG_SRC);\r
- returnValue = E_NOT_OK;\r
+ /* Wrong trig source, ADC164. */\r
+ Det_ReportError(MODULE_ID_ADC,0,ADC_STOPGROUPCONVERSION_ID, ADC_E_WRONG_TRIGG_SRC);\r
+ returnValue = E_NOT_OK;\r
}\r
- else if (!((ADC_IDLE == AdcConfigPtr->groupConfigPtr[group].status->groupStatus) ||\r
- (ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus)))\r
+ else if (ADC_IDLE == AdcConfigPtr->groupConfigPtr[group].status->groupStatus)\r
{\r
- /* Group status not OK, ADC351, ADC428 */\r
- Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_BUSY );\r
-\r
- /*\r
- * This is a BUG!\r
- * Sometimes the ADC-interrupt gets lost which means that the status is never reset to ADC_IDLE (done in Adc_ReadGroup).\r
- * Therefor another group conversion is never started...\r
- *\r
- * The temporary fix is to always return E_OK here. But the reason for the bug needs to be investigated further.\r
- */\r
- //returnValue = E_NOT_OK;\r
- returnValue = E_OK;\r
+ /* Group status not OK, ADC241 */\r
+ Det_ReportError(MODULE_ID_ADC,0,ADC_STOPGROUPCONVERSION_ID, ADC_E_IDLE );\r
+ returnValue = E_NOT_OK;\r
}\r
else\r
{\r
- returnValue = E_OK;\r
+ returnValue = E_OK;\r
}\r
#else\r
returnValue = E_OK;\r
#endif\r
+\r
return (returnValue);\r
}\r
#endif\r
return (returnValue);\r
}\r
\r
-static Std_ReturnType Adc_CheckSetupResultBuffer (Adc_GroupType group)\r
+static Std_ReturnType Adc_CheckDeInit (void)\r
{\r
- Std_ReturnType returnValue;\r
+ Std_ReturnType returnValue = E_OK;\r
\r
#if ( ADC_DEV_ERROR_DETECT == STD_ON )\r
- if (ADC_UNINIT == adcState)\r
- {\r
- /* Driver not initialised. */\r
- Det_ReportError(MODULE_ID_ADC,0,ADC_SETUPRESULTBUFFER_ID,ADC_E_UNINIT );\r
- returnValue = E_NOT_OK;\r
- }\r
- else if (group >= AdcConfigPtr->nbrOfGroups)\r
- {\r
- /* ADC423 */\r
- Det_ReportError(MODULE_ID_ADC,0,ADC_SETUPRESULTBUFFER_ID,ADC_E_PARAM_GROUP );\r
- returnValue = E_NOT_OK;\r
- }\r
- else\r
- {\r
- /* Looks good!! */\r
- returnValue = E_OK;\r
- }\r
+ if(ValidateInit(ADC_DEINIT_ID) == E_OK)\r
+ {\r
+ for (Adc_GroupType group = ADC_GROUP0; group < AdcConfigPtr->nbrOfGroups; group++)\r
+ {\r
+ /* Check ADC is IDLE or COMPLETE*/\r
+ if((AdcConfigPtr->groupConfigPtr[group].status->groupStatus != ADC_IDLE) && (AdcConfigPtr->groupConfigPtr[group].status->groupStatus != ADC_STREAM_COMPLETED))\r
+ {\r
+ Det_ReportError(MODULE_ID_ADC,0,ADC_DEINIT_ID, ADC_E_BUSY );\r
+ returnValue = E_NOT_OK;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ returnValue = E_NOT_OK;\r
+ }\r
#else\r
- returnValue = E_OK;\r
+ returnValue = E_OK;\r
#endif\r
- return (returnValue);\r
+ return (returnValue);\r
+}\r
+\r
+static Std_ReturnType Adc_CheckSetupResultBuffer (Adc_GroupType group)\r
+{\r
+ Std_ReturnType returnValue = E_OK;\r
+\r
+ #if ( ADC_DEV_ERROR_DETECT == STD_ON )\r
+ if(ValidateGroup(group, ADC_SETUPRESULTBUFFER_ID) == E_NOT_OK)\r
+ {\r
+ returnValue = E_NOT_OK;\r
+ }\r
+ #else\r
+ returnValue = E_OK;\r
+ #endif\r
+ return (returnValue);\r
}\r
\r
\r