From 318433e6846db8a66a34e6efe07e4cdfd5ebc019 Mon Sep 17 00:00:00 2001 From: jcar Date: Fri, 17 Feb 2012 09:30:24 +0100 Subject: [PATCH] Splitting of Adc to eQADC and Adc_560x --- arch/ppc/mpc55xx/drivers/Adc_560x.c | 824 ++++++++++++++++++++ arch/ppc/mpc55xx/drivers/{Adc.c => eQADC.c} | 289 +------ boards/board_common.mk | 4 +- 3 files changed, 829 insertions(+), 288 deletions(-) create mode 100644 arch/ppc/mpc55xx/drivers/Adc_560x.c rename arch/ppc/mpc55xx/drivers/{Adc.c => eQADC.c} (79%) diff --git a/arch/ppc/mpc55xx/drivers/Adc_560x.c b/arch/ppc/mpc55xx/drivers/Adc_560x.c new file mode 100644 index 00000000..72d10766 --- /dev/null +++ b/arch/ppc/mpc55xx/drivers/Adc_560x.c @@ -0,0 +1,824 @@ +/* -------------------------------- Arctic Core ------------------------------ + * Arctic Core - the open source AUTOSAR platform http://arccore.com + * + * Copyright (C) 2009 ArcCore AB + * + * This source code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation; See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * -------------------------------- Arctic Core ------------------------------*/ + +#include +#include +//#include "System.h" +#include "mpc55xx.h" +#include "Modules.h" +#include "Mcu.h" +#include "Adc.h" +#include "Det.h" +#include "Os.h" +#include "isr.h" +#include "irq.h" +#include "arc.h" + +/* Uncomment and use DMA for 5606 only if you now what you are doing */ +#define DONT_USE_DMA_IN_ADC_MPC560X + +/* Are we gonna use Dma? */ +#if ( defined(CFG_MPC5606S) && !defined(DONT_USE_DMA_IN_ADC_MPC560X) ) + #define ADC_USES_DMA + #include "Dma.h" +#endif + +#if ( defined(ADC_USES_DMA) && !defined(USE_DMA) ) + #error Adc is configured to use Dma but the module is not enabled. +#endif + +#define ADC_GROUP0 0 + +typedef enum +{ + ADC_UNINIT, + ADC_INIT, +}Adc_StateType; + +/* Function prototypes. */ +static void Adc_ConfigureADC (const Adc_ConfigType *ConfigPtr); +static void Adc_ConfigureADCInterrupts (void); + +void Adc_GroupConversionComplete (Adc_GroupType group); + +/* Development error checking. */ +static Std_ReturnType Adc_CheckReadGroup (Adc_GroupType group); +static Std_ReturnType Adc_CheckStartGroupConversion (Adc_GroupType group); +static Std_ReturnType Adc_CheckStopGroupConversion (Adc_GroupType group); +static Std_ReturnType Adc_CheckInit (const Adc_ConfigType *ConfigPtr); +#if (ADC_DEINIT_API == STD_ON) +static Std_ReturnType Adc_CheckDeInit (void); +#endif +static Std_ReturnType Adc_CheckSetupResultBuffer (Adc_GroupType group); +static Std_ReturnType Adc_CheckGetStreamLastPointer (Adc_GroupType group); + +/* static variable declarations */ +static Adc_StateType adcState = ADC_UNINIT; +static const Adc_ConfigType *AdcConfigPtr; /* Pointer to configuration structure. */ + +/* Validate functions used for development error check */ +#if ( ADC_DEV_ERROR_DETECT == STD_ON ) +Std_ReturnType ValidateInit(Adc_APIServiceIDType api) +{ + Std_ReturnType res = E_OK; + if(!(ADC_INIT == adcState)) { + Det_ReportError(MODULE_ID_ADC,0,api,ADC_E_UNINIT ); + res = E_NOT_OK; + } + return res; +} +Std_ReturnType ValidateGroup(Adc_GroupType group,Adc_APIServiceIDType api) +{ + Std_ReturnType res = E_OK; + if(!((group >= 0) && (group < AdcConfig->nbrOfGroups))) { + Det_ReportError(MODULE_ID_ADC,0,api,ADC_E_PARAM_GROUP ); + res = E_NOT_OK; + } + return res; +} +#endif + +#if (ADC_DEINIT_API == STD_ON) +Std_ReturnType Adc_DeInit (const Adc_ConfigType *ConfigPtr) +{ + (void)ConfigPtr; + + if (E_OK == Adc_CheckDeInit()) + { + for(Adc_GroupType group = ADC_GROUP0; group < AdcConfigPtr->nbrOfGroups; group++) + { + /* Set group status to idle. */ + AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE; + } + + /* Disable DMA transfer*/ +#ifndef CFG_MPC5604B + ADC_0.DMAE.B.DMAEN = 0; +#endif + /* Power down ADC */ + ADC_0.MCR.R = 0x0001; + + /* Disable all interrupt*/ + ADC_0.IMR.R = 0; + + /* Clean internal status. */ + AdcConfigPtr = (Adc_ConfigType *)NULL; + adcState = ADC_UNINIT; + } + + return (E_OK); +} +#endif + +Std_ReturnType Adc_Init (const Adc_ConfigType *ConfigPtr) +{ + if (E_OK == Adc_CheckInit(ConfigPtr)) + { + /* First of all, store the location of the configuration data. */ + AdcConfigPtr = ConfigPtr; + + /* Enable ADC. */ + Adc_ConfigureADC(ConfigPtr); + + Adc_ConfigureADCInterrupts(); + + /* Move on to INIT state. */ + adcState = ADC_INIT; + return E_OK; + } + else + { + return E_NOT_OK; + } +} + +Std_ReturnType Adc_SetupResultBuffer (Adc_GroupType group, Adc_ValueGroupType *bufferPtr) +{ + Std_ReturnType returnValue = E_NOT_OK; + + /* Check for development errors. */ + if (E_OK == Adc_CheckSetupResultBuffer (group)) + { + AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr = bufferPtr; + + returnValue = E_OK; + } + + return (returnValue); +} + +Adc_StreamNumSampleType Adc_GetStreamLastPointer(Adc_GroupType group, Adc_ValueGroupType** PtrToSamplePtr) +{ + Adc_StreamNumSampleType nofSample = 0; + Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group]; + + /** @req ADC216 */ + /* Check for development errors. */ + if ( (E_OK == Adc_CheckGetStreamLastPointer (group)) && + (groupPtr->status->groupStatus != ADC_BUSY) ) + { + /* Set resultPtr to application buffer. */ + if(groupPtr->status->currSampleCount > 0){ + *PtrToSamplePtr = &groupPtr->status->resultBufferPtr[groupPtr->status->currSampleCount-1]; + } + + if ((ADC_CONV_MODE_ONESHOT == groupPtr->conversionMode) && + (ADC_STREAM_COMPLETED == groupPtr->status->groupStatus)) + { + /** @req ADC327. */ + groupPtr->status->groupStatus = ADC_IDLE; + } + else if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) && + (ADC_ACCESS_MODE_STREAMING == groupPtr->accessMode) && + (ADC_STREAM_BUFFER_LINEAR == groupPtr->streamBufferMode) && + (ADC_STREAM_COMPLETED == groupPtr->status->groupStatus)) + { + /** @req ADC327. */ + groupPtr->status->groupStatus = ADC_IDLE; + } + else if ( (ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) && + ((ADC_STREAM_COMPLETED == groupPtr->status->groupStatus) || + (ADC_COMPLETED == groupPtr->status->groupStatus)) ) + { + /* Restart continous mode, and reset result buffer */ + if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) && + (ADC_STREAM_COMPLETED == groupPtr->status->groupStatus)) + { + /* Start continous conversion again */ + Adc_StartGroupConversion(group); + } + /** @req ADC326 */ + /** @req ADC328 */ + } + else{/* Keep status. */} + } + else + { + /* Some condition not met */ + *PtrToSamplePtr = NULL; + } + + return nofSample; + +} + +#if (ADC_READ_GROUP_API == STD_ON) +Std_ReturnType Adc_ReadGroup (Adc_GroupType group, Adc_ValueGroupType *dataBufferPtr) +{ + Std_ReturnType returnValue = E_OK; + uint8_t channel; + Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group]; + + if (E_OK == Adc_CheckReadGroup (group)) + { + /* Copy the result to application buffer. */ + for (channel = 0; channel < groupPtr->numberOfChannels; channel++) + { + if(groupPtr->status->currSampleCount > 0){ + dataBufferPtr[channel] = (&(groupPtr->status->resultBufferPtr[groupPtr->status->currSampleCount-1]))[channel]; + }else{ + dataBufferPtr[channel] = groupPtr->status->resultBufferPtr[channel]; + } + } + + if ((ADC_CONV_MODE_ONESHOT == groupPtr->conversionMode) && + (ADC_STREAM_COMPLETED == groupPtr->status->groupStatus)) + { + /** @req ADC330. */ + groupPtr->status->groupStatus = ADC_IDLE; + } + else if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) && + (ADC_STREAM_BUFFER_LINEAR == groupPtr->streamBufferMode) && + (ADC_ACCESS_MODE_STREAMING == groupPtr->accessMode) && + (ADC_STREAM_COMPLETED == groupPtr->status->groupStatus)) + { + /** @req ADC330. */ + groupPtr->status->groupStatus = ADC_IDLE; + } + else if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) && + ((ADC_STREAM_COMPLETED == groupPtr->status->groupStatus) || + (ADC_COMPLETED == groupPtr->status->groupStatus))) + { + /** @req ADC329 */ + /* Restart continous mode, and reset result buffer */ + if ((ADC_CONV_MODE_CONTINOUS == groupPtr->conversionMode) && + (ADC_STREAM_COMPLETED == groupPtr->status->groupStatus)) + { + /* Start continous conversion again */ + Adc_StartGroupConversion(group); + } + /** @req ADC329 */ + /** @req ADC331 */ + } + else{/* Keep status. */} + } + else + { + /* An error have been raised from Adc_CheckReadGroup(). */ + returnValue = E_NOT_OK; + } + + return (returnValue); +} +#endif + +Adc_StatusType Adc_GetGroupStatus (Adc_GroupType group) +{ + Adc_StatusType returnValue; + +#if ( ADC_DEV_ERROR_DETECT == STD_ON ) + if( (ValidateInit(ADC_GETGROUPSTATUS_ID) == E_NOT_OK) || + (ValidateGroup(group, ADC_GETGROUPSTATUS_ID) == E_NOT_OK)) + { + returnValue = ADC_IDLE; + } + else + { + returnValue = AdcConfigPtr->groupConfigPtr[group].status->groupStatus; + } +#else + returnValue = AdcConfigPtr->groupConfigPtr[group].status->groupStatus; +#endif + return (returnValue); +} + +void Adc_GroupConversionComplete (Adc_GroupType group) +{ + Adc_GroupDefType *adcGroup = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group]; + + if(ADC_ACCESS_MODE_SINGLE == adcGroup->accessMode ) + { + adcGroup->status->groupStatus = ADC_STREAM_COMPLETED; + /* Call notification if enabled. */ + #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON) + if (adcGroup->status->notifictionEnable && adcGroup->groupCallback != NULL) + { + adcGroup->groupCallback(); + } + #endif + /* Disable trigger normal conversions for ADC0 */ + ADC_0.MCR.B.NSTART=0; + } + else + { + if(ADC_STREAM_BUFFER_LINEAR == adcGroup->streamBufferMode) + { + adcGroup->status->currSampleCount++; + if(adcGroup->status->currSampleCount < adcGroup->streamNumSamples) + { + adcGroup->status->currResultBufPtr += adcGroup->numberOfChannels; + adcGroup->status->groupStatus = ADC_COMPLETED; + +#if defined (ADC_USES_DMA) + /* Increase current result buffer ptr */ + Dma_ConfigureDestinationAddress((uint32_t)adcGroup->status->currResultBufPtr, adcGroup->dmaResultChannel); +#endif + + ADC_0.IMR.B.MSKECH = 1; + ADC_0.MCR.B.NSTART=1; + } + else + { + /* All sample completed. */ + adcGroup->status->groupStatus = ADC_STREAM_COMPLETED; + + /* Call notification if enabled. */ + #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON) + if (adcGroup->status->notifictionEnable && adcGroup->groupCallback != NULL){ + adcGroup->groupCallback(); + } + #endif + /* Disable trigger normal conversions for ADC0 */ + ADC_0.MCR.B.NSTART=0; + } + } + else if(ADC_STREAM_BUFFER_CIRCULAR == adcGroup->streamBufferMode) + { + adcGroup->status->currSampleCount++; + if(adcGroup->status->currSampleCount < adcGroup->streamNumSamples) + { + adcGroup->status->currResultBufPtr += adcGroup->numberOfChannels; +#if defined (ADC_USES_DMA) + /* Increase current result buffer ptr */ + Dma_ConfigureDestinationAddress((uint32_t)adcGroup->status->currResultBufPtr, adcGroup->dmaResultChannel); +#endif + adcGroup->status->groupStatus = ADC_COMPLETED; + + ADC_0.IMR.B.MSKECH = 1; + ADC_0.MCR.B.NSTART=1; + } + else + { + /* Sample completed. */ + /* Disable trigger normal conversions for ADC*/ + ADC_0.MCR.B.NSTART=0; + adcGroup->status->groupStatus = ADC_STREAM_COMPLETED; + /* Call notification if enabled. */ + #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON) + if (adcGroup->status->notifictionEnable && adcGroup->groupCallback != NULL) + { + adcGroup->groupCallback(); + } + #endif + } + } + else + { + //nothing to do. + } + } +} +void Adc_Group0ConversionComplete (void) +{ + /* Clear ECH Flag and disable interruput */ + ADC_0.ISR.B.ECH = 1; + ADC_0.IMR.B.MSKECH = 0; + + // Check which group is busy, only one is allowed to be busy at a time in a hw unit + for (int group = 0; group < ADC_NBR_OF_GROUPS; group++) + { + if((AdcConfigPtr->groupConfigPtr[group].status->groupStatus == ADC_BUSY) || + (AdcConfigPtr->groupConfigPtr[group].status->groupStatus == ADC_COMPLETED)) + { +#if !defined (ADC_USES_DMA) + /* Copy to result buffer */ + for(uint8 index=0; index < AdcConfigPtr->groupConfigPtr[group].numberOfChannels; index++) + { +#if defined(CFG_MPC5606S) + AdcConfigPtr->groupConfigPtr[group].status->currResultBufPtr[index] = ADC_0.CDR[32+AdcConfigPtr->groupConfigPtr[group].channelList[index]].B.CDATA; +#else + AdcConfigPtr->groupConfigPtr[group].status->currResultBufPtr[index] = ADC_0.CDR[AdcConfigPtr->groupConfigPtr[group].channelList[index]].B.CDATA; +#endif + } +#endif + + Adc_GroupConversionComplete((Adc_GroupType)group); + break; + } + } +} + +void Adc_WatchdogError (void){ +} +void Adc_ADCError (void){ +} + +static void Adc_ConfigureADC (const Adc_ConfigType *ConfigPtr) +{ + /* Set ADC CLOCK */ + ADC_0.MCR.B.ADCLKSEL = ConfigPtr->hwConfigPtr->adcPrescale; + + ADC_0.DSDR.B.DSD = 254; + + /* Power on ADC */ + ADC_0.MCR.B.PWDN = 0; + +#if defined(ADC_USES_DMA) + /* Enable DMA. */ + ADC_0.DMAE.B.DMAEN = 1; +#endif +} + +void Adc_ConfigureADCInterrupts (void) +{ + ISR_INSTALL_ISR2( "Adc_Err", Adc_ADCError, ADC_ER_INT, 2, 0 ); + ISR_INSTALL_ISR2( "Adc_Grp", Adc_Group0ConversionComplete, ADC_EOC_INT, 2, 0 ); + ISR_INSTALL_ISR2( "Adc_Wdg", Adc_WatchdogError, ADC_WD_INT, 2, 0 ); +} + +#if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON) +void Adc_StartGroupConversion (Adc_GroupType group) +{ + Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group]; + + /* Run development error check. */ + if (E_OK == Adc_CheckStartGroupConversion (group)) + { + /* Disable trigger normal conversions for ADC0 */ + ADC_0.MCR.B.NSTART = 0; + + /* Set group state to BUSY. */ + groupPtr->status->groupStatus = ADC_BUSY; + + groupPtr->status->currSampleCount = 0; + groupPtr->status->currResultBufPtr = groupPtr->status->resultBufferPtr; /* Set current result buffer */ + +#if defined(ADC_USES_DMA) + Dma_ConfigureChannel ((Dma_TcdType *)groupPtr->groupDMAResults, groupPtr->dmaResultChannel); + Dma_ConfigureDestinationAddress ((uint32_t)groupPtr->status->currResultBufPtr, groupPtr->dmaResultChannel); +#endif + /* Always use single shot in streaming mode */ + if( groupPtr->accessMode == ADC_ACCESS_MODE_STREAMING) + { + /* Set conversion mode. */ + ADC_0.MCR.B.MODE = ADC_CONV_MODE_ONESHOT; + } + else + { + /* Set conversion mode. */ + ADC_0.MCR.B.MODE = groupPtr->conversionMode; + } + + /* Enable Overwrite*/ + ADC_0.MCR.B.OWREN = 1; + + /* Set Conversion Time. */ +#if defined(CFG_MPC5606S) + uint32 groupChannelIdMask = 0; + + ADC_0.CTR[1].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH; + ADC_0.CTR[1].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP; + ADC_0.CTR[1].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP; + + for(uint8 i =0; i < groupPtr->numberOfChannels; i++) + { + groupChannelIdMask |= (1 << groupPtr->channelList[i]); + } + +#if defined(ADC_USES_DMA) + ADC_0.DMAE.R = 0x01; + /* Enable DMA Transfer */ + ADC_0.DMAR[1].R = groupChannelIdMask; + Dma_StartChannel(DMA_ADC_GROUP0_RESULT_CHANNEL); /* Enable EDMA channel for ADC */ +#endif + + /* Enable Normal conversion */ + ADC_0.NCMR[1].R = groupChannelIdMask; + + /* Enable Channel Interrupt */ + ADC_0.CIMR[1].R = groupChannelIdMask; + +#else + uint32 groupChannelIdMask[3] = {0,0,0}; + + ADC_0.CTR[0].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH; + ADC_0.CTR[0].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP; + ADC_0.CTR[0].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP; + ADC_0.CTR[1].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH; + ADC_0.CTR[1].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP; + ADC_0.CTR[1].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP; + ADC_0.CTR[2].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH; + ADC_0.CTR[2].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP; + ADC_0.CTR[2].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP; + + for(uint8 i =0; i < groupPtr->numberOfChannels; i++) + { + if(groupPtr->channelList[i] <= 15){ + groupChannelIdMask[0] |= (1 << groupPtr->channelList[i]); + }else if((groupPtr->channelList[i] >= 32) && (groupPtr->channelList[i] <=47)){ + groupChannelIdMask[1] |= (1 << (groupPtr->channelList[i] - 32)); + }else if((groupPtr->channelList[i] >= 64) && (groupPtr->channelList[i] <=95)){ + groupChannelIdMask[2] |= (1 << (groupPtr->channelList[i] - 64)); + } + } + + /* Enable Normal conversion */ + ADC_0.NCMR[0].R = groupChannelIdMask[0]; + ADC_0.NCMR[1].R = groupChannelIdMask[1]; + ADC_0.NCMR[2].R = groupChannelIdMask[2]; + + /* Enable Channel Interrupt */ + ADC_0.CIMR[0].R = groupChannelIdMask[0]; + ADC_0.CIMR[1].R = groupChannelIdMask[1]; + ADC_0.CIMR[2].R = groupChannelIdMask[2]; +#endif + /* Clear interrupts */ + ADC_0.ISR.B.ECH = 1; + /* Enable ECH interrupt */ + ADC_0.IMR.B.MSKECH = 1; + + /* Trigger normal conversions for ADC0 */ + ADC_0.MCR.B.NSTART = 1; + } + else + { + /* Error have been set within Adc_CheckStartGroupConversion(). */ + } +} + +void Adc_StopGroupConversion (Adc_GroupType group) +{ + if (E_OK == Adc_CheckStopGroupConversion (group)) + { + /* Disable trigger normal conversions for ADC0 */ + ADC_0.MCR.B.NSTART = 0; + + /* Set group state to IDLE. */ + AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE; + + /* Disable group notification if enabled. */ + if(1 == AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable){ + Adc_DisableGroupNotification (group); + } + } + else + { + /* Error have been set within Adc_CheckStartGroupConversion(). */ + } +} +#endif /* endof #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON) */ + +#define SYSTEM_CLOCK_DIVIDE(f) ((f / 2) - 1) + +#if (ADC_GRP_NOTIF_CAPABILITY == STD_ON) +void Adc_EnableGroupNotification (Adc_GroupType group) +{ + Std_ReturnType res; + +#if ( ADC_DEV_ERROR_DETECT == STD_ON ) + if( (ValidateInit(ADC_ENABLEGROUPNOTIFICATION_ID) == E_NOT_OK) || + (ValidateGroup(group, ADC_ENABLEGROUPNOTIFICATION_ID) == E_NOT_OK)) + { + res = E_NOT_OK; + } + else if (AdcConfigPtr->groupConfigPtr[group].groupCallback == NULL) + { + res = E_NOT_OK; + Det_ReportError(MODULE_ID_ADC,0,ADC_ENABLEGROUPNOTIFICATION_ID ,ADC_E_NOTIF_CAPABILITY ); + } + else + { + /* Nothing strange. Go on... */ + res = E_OK; + } +#else + res = E_OK; +#endif + if (E_OK == res){ + AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable = 1; + } +} + +void Adc_DisableGroupNotification (Adc_GroupType group) +{ + Std_ReturnType res; + +#if ( ADC_DEV_ERROR_DETECT == STD_ON ) + if( (ValidateInit(ADC_DISABLEGROUPNOTIFICATION_ID) == E_NOT_OK) || + (ValidateGroup(group, ADC_DISABLEGROUPNOTIFICATION_ID) == E_NOT_OK)) + { + res = E_NOT_OK; + } + else if (AdcConfigPtr->groupConfigPtr[group].groupCallback == NULL) + { + res = E_NOT_OK; + Det_ReportError(MODULE_ID_ADC,0,ADC_DISABLEGROUPNOTIFICATION_ID ,ADC_E_NOTIF_CAPABILITY ); + } + else + { + /* Nothing strange. Go on... */ + res = E_OK; + } +#else + res = E_OK; +#endif + if (E_OK == res){ + AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable = 0; + } +} +#endif + + + +/* Development error checking functions. */ +#if (ADC_READ_GROUP_API == STD_ON) +static Std_ReturnType Adc_CheckReadGroup (Adc_GroupType group) +{ + Std_ReturnType returnValue = E_OK; + +#if ( ADC_DEV_ERROR_DETECT == STD_ON ) + + if( (ValidateInit(ADC_READGROUP_ID) == E_NOT_OK) || + (ValidateGroup(group, ADC_READGROUP_ID) == E_NOT_OK)) + { + returnValue = E_NOT_OK; + } + else if (ADC_IDLE == AdcConfigPtr->groupConfigPtr[group].status->groupStatus) + { + /* ADC388. */ + returnValue = E_NOT_OK; + Det_ReportError(MODULE_ID_ADC,0,ADC_READGROUP_ID ,ADC_E_IDLE ); + } + else + { + /* Nothing strange. Go on... */ + returnValue = E_OK; + } +#endif + return (returnValue); +} +#endif + +#if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON) +static Std_ReturnType Adc_CheckStartGroupConversion (Adc_GroupType group) +{ + Std_ReturnType returnValue = E_OK; + +#if ( ADC_DEV_ERROR_DETECT == STD_ON ) + + if( (ValidateInit(ADC_STARTGROUPCONVERSION_ID) == E_NOT_OK) || + (ValidateGroup(group, ADC_STARTGROUPCONVERSION_ID) == E_NOT_OK)) + { + returnValue = E_NOT_OK; + } + else if ( NULL == AdcConfigPtr->groupConfigPtr[group].status->resultBufferPtr ) + { + /* ResultBuffer not set, ADC424 */ + Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_BUFFER_UNINIT ); + returnValue = E_NOT_OK; + } + else if (!(ADC_TRIGG_SRC_SW == AdcConfigPtr->groupConfigPtr[group].triggerSrc)) + { + /* Wrong trig source, ADC133. */ + Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_WRONG_TRIGG_SRC); + returnValue = E_NOT_OK; + } + else if (!((ADC_IDLE == AdcConfigPtr->groupConfigPtr[group].status->groupStatus) || + (ADC_STREAM_COMPLETED == AdcConfigPtr->groupConfigPtr[group].status->groupStatus))) + { + /* Group status not OK, ADC351, ADC428 */ + Det_ReportError(MODULE_ID_ADC,0,ADC_STARTGROUPCONVERSION_ID, ADC_E_BUSY ); + + //returnValue = E_NOT_OK; + returnValue = E_OK; + } + else + { + returnValue = E_OK; + } +#endif + + return (returnValue); +} + +static Std_ReturnType Adc_CheckStopGroupConversion (Adc_GroupType group) +{ + Std_ReturnType returnValue = E_OK; + +#if ( ADC_DEV_ERROR_DETECT == STD_ON ) + if( (ValidateInit(ADC_STOPGROUPCONVERSION_ID) == E_NOT_OK) || + (ValidateGroup(group, ADC_STOPGROUPCONVERSION_ID) == E_NOT_OK)) + { + returnValue = E_NOT_OK; + } + else if (!(ADC_TRIGG_SRC_SW == AdcConfigPtr->groupConfigPtr[group].triggerSrc)) + { + /* Wrong trig source, ADC164. */ + Det_ReportError(MODULE_ID_ADC,0,ADC_STOPGROUPCONVERSION_ID, ADC_E_WRONG_TRIGG_SRC); + returnValue = E_NOT_OK; + } + else if (ADC_IDLE == AdcConfigPtr->groupConfigPtr[group].status->groupStatus) + { + /* Group status not OK, ADC241 */ + Det_ReportError(MODULE_ID_ADC,0,ADC_STOPGROUPCONVERSION_ID, ADC_E_IDLE ); + returnValue = E_NOT_OK; + } + else + { + returnValue = E_OK; + } +#endif + + return (returnValue); +} +#endif + +static Std_ReturnType Adc_CheckInit (const Adc_ConfigType *ConfigPtr) +{ + Std_ReturnType returnValue = E_OK; + +#if ( ADC_DEV_ERROR_DETECT == STD_ON ) + if (!(ADC_UNINIT == adcState)) + { + /* Oops, already initialised. */ + Det_ReportError(MODULE_ID_ADC,0,ADC_INIT_ID, ADC_E_ALREADY_INITIALIZED ); + returnValue = E_NOT_OK; + } + else if (ConfigPtr == NULL) + { + /* Wrong config! */ + Det_ReportError(MODULE_ID_ADC,0,ADC_INIT_ID, ADC_E_PARAM_CONFIG ); + returnValue = E_NOT_OK; + } + else + { + /* Looks good!! */ + returnValue = E_OK; + } +#endif + return (returnValue); +} + +#if (ADC_DEINIT_API == STD_ON) +static Std_ReturnType Adc_CheckDeInit (void) +{ + Std_ReturnType returnValue = E_OK; + +#if ( ADC_DEV_ERROR_DETECT == STD_ON ) + if(ValidateInit(ADC_DEINIT_ID) == E_OK) + { + for (Adc_GroupType group = ADC_GROUP0; group < AdcConfigPtr->nbrOfGroups; group++) + { + /* Check ADC is IDLE or COMPLETE*/ + if((AdcConfigPtr->groupConfigPtr[group].status->groupStatus != ADC_IDLE) && (AdcConfigPtr->groupConfigPtr[group].status->groupStatus != ADC_STREAM_COMPLETED)) + { + Det_ReportError(MODULE_ID_ADC,0,ADC_DEINIT_ID, ADC_E_BUSY ); + returnValue = E_NOT_OK; + } + } + } + else + { + returnValue = E_NOT_OK; + } +#endif + return (returnValue); +} +#endif + +static Std_ReturnType Adc_CheckSetupResultBuffer (Adc_GroupType group) +{ + Std_ReturnType returnValue = E_OK; + +#if ( ADC_DEV_ERROR_DETECT == STD_ON ) + if(ValidateGroup(group, ADC_SETUPRESULTBUFFER_ID) == E_NOT_OK) + { + returnValue = E_NOT_OK; + } +#endif + return (returnValue); +} + +static Std_ReturnType Adc_CheckGetStreamLastPointer (Adc_GroupType group) +{ + Std_ReturnType returnValue = E_OK; + +#if ( ADC_DEV_ERROR_DETECT == STD_ON ) + if( (ValidateInit(ADC_GETSTREAMLASTPOINTER_ID) == E_NOT_OK) || + (ValidateGroup(group, ADC_GETSTREAMLASTPOINTER_ID) == E_NOT_OK)) + { + returnValue = E_NOT_OK; + } + else if(AdcConfigPtr->groupConfigPtr[group].status->groupStatus == ADC_IDLE) + { /** @req ADC215 Check ADC is not in IDLE */ + Det_ReportError(MODULE_ID_ADC,0,ADC_GETSTREAMLASTPOINTER_ID, ADC_E_IDLE ); + returnValue = E_NOT_OK; + } +#endif + return (returnValue); +} + + + diff --git a/arch/ppc/mpc55xx/drivers/Adc.c b/arch/ppc/mpc55xx/drivers/eQADC.c similarity index 79% rename from arch/ppc/mpc55xx/drivers/Adc.c rename to arch/ppc/mpc55xx/drivers/eQADC.c index c49d97dc..b69baf0b 100644 --- a/arch/ppc/mpc55xx/drivers/Adc.c +++ b/arch/ppc/mpc55xx/drivers/eQADC.c @@ -26,15 +26,8 @@ #include "irq.h" #include "arc.h" -/* Uncomment and use DMA for 5606 only if you now what you are doing */ -#define DONT_USE_DMA_IN_ADC_MPC560X - -/* Are we gonna use Dma? */ -#if ( !defined(CFG_MPC560X) || \ - ( defined(CFG_MPC5606S) && !defined(DONT_USE_DMA_IN_ADC_MPC560X) ) ) - #define ADC_USES_DMA - #include "Dma.h" -#endif +#define ADC_USES_DMA +#include "Dma.h" #if ( defined(ADC_USES_DMA) && !defined(USE_DMA) ) #error Adc is configured to use Dma but the module is not enabled. @@ -42,7 +35,6 @@ #define ADC_GROUP0 0 -#if !defined(CFG_MPC560X) typedef union { vuint32_t R; @@ -200,7 +192,6 @@ const Dma_TcdType AdcCalibrationDMAResultConfig = .INT_MAJ = 0, .START = 0 }; -#endif typedef enum { @@ -209,16 +200,11 @@ typedef enum }Adc_StateType; /* Function prototypes. */ -#if defined(CFG_MPC560X) -static void Adc_ConfigureADC (const Adc_ConfigType *ConfigPtr); -static void Adc_ConfigureADCInterrupts (void); -#else static void Adc_ConfigureEQADC (const Adc_ConfigType *ConfigPtr); static void Adc_ConfigureEQADCInterrupts (void); static void Adc_EQADCCalibrationSequence (void); static void Adc_WriteEQADCRegister (Adc_EQADCRegisterType reg, Adc_EQADCRegister value); static Adc_EQADCRegister Adc_ReadEQADCRegister (Adc_EQADCRegisterType reg); -#endif void Adc_GroupConversionComplete (Adc_GroupType group); @@ -263,34 +249,6 @@ Std_ReturnType ValidateGroup(Adc_GroupType group,Adc_APIServiceIDType api) Std_ReturnType Adc_DeInit (const Adc_ConfigType *ConfigPtr) { (void)ConfigPtr; -#if defined(CFG_MPC560X) - - if (E_OK == Adc_CheckDeInit()) - { - for(Adc_GroupType group = ADC_GROUP0; group < AdcConfigPtr->nbrOfGroups; group++) - { - /* Set group status to idle. */ - AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE; - } - - /* Disable DMA transfer*/ -#ifndef CFG_MPC5604B - ADC_0.DMAE.B.DMAEN = 0; -#endif - /* Power down ADC */ - ADC_0.MCR.R = 0x0001; - - /* Disable all interrupt*/ - ADC_0.IMR.R = 0; - - /* Clean internal status. */ - AdcConfigPtr = (Adc_ConfigType *)NULL; - adcState = ADC_UNINIT; - } - - return (E_OK); - -#else Adc_eQADCQueueType queue; Adc_GroupType group; @@ -369,35 +327,11 @@ Std_ReturnType Adc_DeInit (const Adc_ConfigType *ConfigPtr) adcState = ADC_UNINIT; } return (E_OK); -#endif /* ENDOF defined(CFG_MPC560X) */ } #endif Std_ReturnType Adc_Init (const Adc_ConfigType *ConfigPtr) { -#if defined(CFG_MPC560X) - - if (E_OK == Adc_CheckInit(ConfigPtr)) - { - /* First of all, store the location of the configuration data. */ - AdcConfigPtr = ConfigPtr; - - /* Enable ADC. */ - Adc_ConfigureADC(ConfigPtr); - - Adc_ConfigureADCInterrupts(); - - /* Move on to INIT state. */ - adcState = ADC_INIT; - return E_OK; - } - else - { - return E_NOT_OK; - } - -#else - Std_ReturnType returnValue; Adc_InternalChannelIdType channel; Adc_InternalChannelIdType channelId; @@ -482,7 +416,6 @@ Std_ReturnType Adc_Init (const Adc_ConfigType *ConfigPtr) } return (returnValue); -#endif } Std_ReturnType Adc_SetupResultBuffer (Adc_GroupType group, Adc_ValueGroupType *bufferPtr) @@ -649,13 +582,8 @@ void Adc_GroupConversionComplete (Adc_GroupType group) adcGroup->groupCallback(); } #endif -#if defined(CFG_MPC560X) - /* Disable trigger normal conversions for ADC0 */ - ADC_0.MCR.B.NSTART=0; -#else /* Disable trigger. */ EQADC.CFCR[group].B.MODE = 0; -#endif } else { @@ -672,13 +600,8 @@ void Adc_GroupConversionComplete (Adc_GroupType group) Dma_ConfigureDestinationAddress((uint32_t)adcGroup->status->currResultBufPtr, adcGroup->dmaResultChannel); #endif -#if defined(CFG_MPC560X) - ADC_0.IMR.B.MSKECH = 1; - ADC_0.MCR.B.NSTART=1; -#else /* Set single scan enable bit */ EQADC.CFCR[group].B.SSE = 1; -#endif } else { @@ -691,13 +614,8 @@ void Adc_GroupConversionComplete (Adc_GroupType group) adcGroup->groupCallback(); } #endif -#if defined(CFG_MPC560X) - /* Disable trigger normal conversions for ADC0 */ - ADC_0.MCR.B.NSTART=0; -#else /* Disable trigger. */ EQADC.CFCR[group].B.MODE = 0; -#endif } } else if(ADC_STREAM_BUFFER_CIRCULAR == adcGroup->streamBufferMode) @@ -712,24 +630,14 @@ void Adc_GroupConversionComplete (Adc_GroupType group) #endif adcGroup->status->groupStatus = ADC_COMPLETED; -#if defined(CFG_MPC560X) - ADC_0.IMR.B.MSKECH = 1; - ADC_0.MCR.B.NSTART=1; -#else /* Set single scan enable bit */ EQADC.CFCR[group].B.SSE = 1; -#endif } else { /* Sample completed. */ -#if defined(CFG_MPC560X) - /* Disable trigger normal conversions for ADC*/ - ADC_0.MCR.B.NSTART=0; -#else /* Disable trigger. */ EQADC.CFCR[group].B.MODE = 0; -#endif adcGroup->status->groupStatus = ADC_STREAM_COMPLETED; /* Call notification if enabled. */ #if (ADC_GRP_NOTIF_CAPABILITY == STD_ON) @@ -746,198 +654,6 @@ void Adc_GroupConversionComplete (Adc_GroupType group) } } } -#if defined(CFG_MPC560X) -void Adc_Group0ConversionComplete (void) -{ - /* Clear ECH Flag and disable interruput */ - ADC_0.ISR.B.ECH = 1; - ADC_0.IMR.B.MSKECH = 0; - - // Check which group is busy, only one is allowed to be busy at a time in a hw unit - for (int group = 0; group < ADC_NBR_OF_GROUPS; group++) - { - if((AdcConfigPtr->groupConfigPtr[group].status->groupStatus == ADC_BUSY) || - (AdcConfigPtr->groupConfigPtr[group].status->groupStatus == ADC_COMPLETED)) - { -#if !defined (ADC_USES_DMA) - /* Copy to result buffer */ - for(uint8 index=0; index < AdcConfigPtr->groupConfigPtr[group].numberOfChannels; index++) - { -#if defined(CFG_MPC5606S) - AdcConfigPtr->groupConfigPtr[group].status->currResultBufPtr[index] = ADC_0.CDR[32+AdcConfigPtr->groupConfigPtr[group].channelList[index]].B.CDATA; -#else - AdcConfigPtr->groupConfigPtr[group].status->currResultBufPtr[index] = ADC_0.CDR[AdcConfigPtr->groupConfigPtr[group].channelList[index]].B.CDATA; -#endif - } -#endif - - Adc_GroupConversionComplete((Adc_GroupType)group); - break; - } - } -} - -void Adc_WatchdogError (void){ -} -void Adc_ADCError (void){ -} - -static void Adc_ConfigureADC (const Adc_ConfigType *ConfigPtr) -{ - /* Set ADC CLOCK */ - ADC_0.MCR.B.ADCLKSEL = ConfigPtr->hwConfigPtr->adcPrescale; - - ADC_0.DSDR.B.DSD = 254; - - /* Power on ADC */ - ADC_0.MCR.B.PWDN = 0; - -#if defined(ADC_USES_DMA) - /* Enable DMA. */ - ADC_0.DMAE.B.DMAEN = 1; -#endif -} - -void Adc_ConfigureADCInterrupts (void) -{ - ISR_INSTALL_ISR2( "Adc_Err", Adc_ADCError, ADC_ER_INT, 2, 0 ); - ISR_INSTALL_ISR2( "Adc_Grp", Adc_Group0ConversionComplete, ADC_EOC_INT, 2, 0 ); - ISR_INSTALL_ISR2( "Adc_Wdg", Adc_WatchdogError, ADC_WD_INT, 2, 0 ); -} - -#if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON) -void Adc_StartGroupConversion (Adc_GroupType group) -{ - Adc_GroupDefType *groupPtr = (Adc_GroupDefType *)&AdcConfigPtr->groupConfigPtr[group]; - - /* Run development error check. */ - if (E_OK == Adc_CheckStartGroupConversion (group)) - { - /* Disable trigger normal conversions for ADC0 */ - ADC_0.MCR.B.NSTART = 0; - - /* Set group state to BUSY. */ - groupPtr->status->groupStatus = ADC_BUSY; - - groupPtr->status->currSampleCount = 0; - groupPtr->status->currResultBufPtr = groupPtr->status->resultBufferPtr; /* Set current result buffer */ - -#if defined(ADC_USES_DMA) - Dma_ConfigureChannel ((Dma_TcdType *)groupPtr->groupDMAResults, groupPtr->dmaResultChannel); - Dma_ConfigureDestinationAddress ((uint32_t)groupPtr->status->currResultBufPtr, groupPtr->dmaResultChannel); -#endif - /* Always use single shot in streaming mode */ - if( groupPtr->accessMode == ADC_ACCESS_MODE_STREAMING) - { - /* Set conversion mode. */ - ADC_0.MCR.B.MODE = ADC_CONV_MODE_ONESHOT; - } - else - { - /* Set conversion mode. */ - ADC_0.MCR.B.MODE = groupPtr->conversionMode; - } - - /* Enable Overwrite*/ - ADC_0.MCR.B.OWREN = 1; - - /* Set Conversion Time. */ -#if defined(CFG_MPC5606S) - uint32 groupChannelIdMask = 0; - - ADC_0.CTR[1].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH; - ADC_0.CTR[1].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP; - ADC_0.CTR[1].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP; - - for(uint8 i =0; i < groupPtr->numberOfChannels; i++) - { - groupChannelIdMask |= (1 << groupPtr->channelList[i]); - } - -#if defined(ADC_USES_DMA) - ADC_0.DMAE.R = 0x01; - /* Enable DMA Transfer */ - ADC_0.DMAR[1].R = groupChannelIdMask; - Dma_StartChannel(DMA_ADC_GROUP0_RESULT_CHANNEL); /* Enable EDMA channel for ADC */ -#endif - - /* Enable Normal conversion */ - ADC_0.NCMR[1].R = groupChannelIdMask; - - /* Enable Channel Interrupt */ - ADC_0.CIMR[1].R = groupChannelIdMask; - -#else - uint32 groupChannelIdMask[3] = {0,0,0}; - - ADC_0.CTR[0].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH; - ADC_0.CTR[0].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP; - ADC_0.CTR[0].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP; - ADC_0.CTR[1].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH; - ADC_0.CTR[1].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP; - ADC_0.CTR[1].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP; - ADC_0.CTR[2].B.INPLATCH = groupPtr->adcChannelConvTime.INPLATCH; - ADC_0.CTR[2].B.INPCMP = groupPtr->adcChannelConvTime.INPCMP; - ADC_0.CTR[2].B.INPSAMP = groupPtr->adcChannelConvTime.INPSAMP; - - for(uint8 i =0; i < groupPtr->numberOfChannels; i++) - { - if(groupPtr->channelList[i] <= 15){ - groupChannelIdMask[0] |= (1 << groupPtr->channelList[i]); - }else if((groupPtr->channelList[i] >= 32) && (groupPtr->channelList[i] <=47)){ - groupChannelIdMask[1] |= (1 << (groupPtr->channelList[i] - 32)); - }else if((groupPtr->channelList[i] >= 64) && (groupPtr->channelList[i] <=95)){ - groupChannelIdMask[2] |= (1 << (groupPtr->channelList[i] - 64)); - } - } - - /* Enable Normal conversion */ - ADC_0.NCMR[0].R = groupChannelIdMask[0]; - ADC_0.NCMR[1].R = groupChannelIdMask[1]; - ADC_0.NCMR[2].R = groupChannelIdMask[2]; - - /* Enable Channel Interrupt */ - ADC_0.CIMR[0].R = groupChannelIdMask[0]; - ADC_0.CIMR[1].R = groupChannelIdMask[1]; - ADC_0.CIMR[2].R = groupChannelIdMask[2]; -#endif - /* Clear interrupts */ - ADC_0.ISR.B.ECH = 1; - /* Enable ECH interrupt */ - ADC_0.IMR.B.MSKECH = 1; - - /* Trigger normal conversions for ADC0 */ - ADC_0.MCR.B.NSTART = 1; - } - else - { - /* Error have been set within Adc_CheckStartGroupConversion(). */ - } -} - -void Adc_StopGroupConversion (Adc_GroupType group) -{ - if (E_OK == Adc_CheckStopGroupConversion (group)) - { - /* Disable trigger normal conversions for ADC0 */ - ADC_0.MCR.B.NSTART = 0; - - /* Set group state to IDLE. */ - AdcConfigPtr->groupConfigPtr[group].status->groupStatus = ADC_IDLE; - - /* Disable group notification if enabled. */ - if(1 == AdcConfigPtr->groupConfigPtr[group].status->notifictionEnable){ - Adc_DisableGroupNotification (group); - } - } - else - { - /* Error have been set within Adc_CheckStartGroupConversion(). */ - } -} -#endif /* endof #if (ADC_ENABLE_START_STOP_GROUP_API == STD_ON) */ - -#else /* End of mpc5606s unique */ void Adc_Group0ConversionComplete (void) { @@ -1340,7 +1056,6 @@ static void Adc_EQADCCalibrationSequence (void) assert (0); } } -#endif #define SYSTEM_CLOCK_DIVIDE(f) ((f / 2) - 1) diff --git a/boards/board_common.mk b/boards/board_common.mk index fa306a4e..56d7f362 100644 --- a/boards/board_common.mk +++ b/boards/board_common.mk @@ -92,7 +92,9 @@ obj-$(USE_DIO) += Dio_Lcfg.o obj-$(USE_PORT) += Port.o obj-$(USE_PORT) += Port_Cfg.o -obj-$(USE_ADC) += Adc.o +obj-$(USE_ADC)-$(CFG_MPC560X) += Adc_560x.o +obj-$(USE_ADC)-$(CFG_MPC5516) += eQADC.o +obj-$(USE_ADC)-$(CFG_MPC5567) += eQADC.o obj-$(USE_ADC) += Adc_Cfg.o # J1939Tp -- 2.39.2