blob: 4b194658501672195169d2719e0593d8342e7d4d [file] [log] [blame]
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "adc_imx6sx.h"
/*******************************************************************************
* Code
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : ADC_Init
* Description : Initialize ADC to reset state and initialize with initialize
* structure.
*
*END**************************************************************************/
void ADC_Init(ADC_Type* base, const adc_init_config_t* initConfig)
{
assert(initConfig);
/* Reset ADC register to its default value. */
ADC_Deinit(base);
/* Set hardware average function and number. */
if (initConfig->averageNumber != adcAvgNumNone)
{
ADC_GC_REG(base) |= ADC_GC_AVGE_MASK;
ADC_CFG_REG(base) |= ADC_CFG_AVGS(initConfig->averageNumber);
}
/* Set resolution mode. */
ADC_CFG_REG(base) |= ADC_CFG_MODE(initConfig->resolutionMode);
/* Set clock source. */
ADC_SetClockSource(base, initConfig->clockSource, initConfig->divideRatio);
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_Deinit
* Description : This function reset ADC module register content to its
* default value.
*
*END**************************************************************************/
void ADC_Deinit(ADC_Type* base)
{
/* Reset ADC Module Register content to default value */
ADC_HC0_REG(base) = ADC_HC0_ADCH_MASK;
ADC_HC1_REG(base) = ADC_HC1_ADCH_MASK;
ADC_R0_REG(base) = 0x0;
ADC_R1_REG(base) = 0x0;
ADC_CFG_REG(base) = ADC_CFG_ADSTS(2);
ADC_GC_REG(base) = 0x0;
ADC_GS_REG(base) = ADC_GS_CALF_MASK | ADC_GS_AWKST_MASK;
ADC_CV_REG(base) = 0x0;
ADC_OFS_REG(base) = 0x0;
ADC_CAL_REG(base) = 0x0;
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetConvertResultOverwrite
* Description : Enable or disable ADC overwrite conversion result register.
*
*END**************************************************************************/
void ADC_SetConvertResultOverwrite(ADC_Type* base, bool enable)
{
if(enable)
ADC_CFG_REG(base) |= ADC_CFG_OVWREN_MASK;
else
ADC_CFG_REG(base) &= ~ADC_CFG_OVWREN_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetConvertTrigMode
* Description : This function is used to set conversion trigger mode.
*
*END**************************************************************************/
void ADC_SetConvertTrigMode(ADC_Type* base, uint8_t mode)
{
assert(mode <= adcHardwareTrigger);
if(mode == adcHardwareTrigger)
ADC_CFG_REG(base) |= ADC_CFG_ADTRG_MASK;
else
ADC_CFG_REG(base) &= ~ADC_CFG_ADTRG_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetConvertSpeed
* Description : This function is used to set conversion speed mode.
*
*END**************************************************************************/
void ADC_SetConvertSpeed(ADC_Type* base, uint8_t mode)
{
assert(mode <= adcHighSpeed);
if(mode == adcHighSpeed)
ADC_CFG_REG(base) |= ADC_CFG_ADHSC_MASK;
else
ADC_CFG_REG(base) &= ~ADC_CFG_ADHSC_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetSampleTimeDuration
* Description : This function is used to set sample time duration.
*
*END**************************************************************************/
void ADC_SetSampleTimeDuration(ADC_Type* base, uint8_t duration)
{
assert(duration <= adcSamplePeriodClock24);
switch(duration)
{
case adcSamplePeriodClock2:
ADC_CFG_REG(base) &= ~ADC_CFG_ADLSMP_MASK;
ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
ADC_CFG_ADSTS(0U);
break;
case adcSamplePeriodClock4:
ADC_CFG_REG(base) &= ~ADC_CFG_ADLSMP_MASK;
ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
ADC_CFG_ADSTS(1U);
break;
case adcSamplePeriodClock6:
ADC_CFG_REG(base) &= ~ADC_CFG_ADLSMP_MASK;
ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
ADC_CFG_ADSTS(2U);
break;
case adcSamplePeriodClock8:
ADC_CFG_REG(base) &= ~ADC_CFG_ADLSMP_MASK;
ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
ADC_CFG_ADSTS(3U);
break;
case adcSamplePeriodClock12:
ADC_CFG_REG(base) |= ADC_CFG_ADLSMP_MASK;
ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
ADC_CFG_ADSTS(0U);
break;
case adcSamplePeriodClock16:
ADC_CFG_REG(base) |= ADC_CFG_ADLSMP_MASK;
ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
ADC_CFG_ADSTS(1U);
break;
case adcSamplePeriodClock20:
ADC_CFG_REG(base) |= ADC_CFG_ADLSMP_MASK;
ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
ADC_CFG_ADSTS(2U);
break;
case adcSamplePeriodClock24:
ADC_CFG_REG(base) |= ADC_CFG_ADLSMP_MASK;
ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
ADC_CFG_ADSTS(3U);
break;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetPowerMode
* Description : This function is used to set power mode.
*
*END**************************************************************************/
void ADC_SetPowerMode(ADC_Type* base, uint8_t powerMode)
{
assert(powerMode <= adcLowPowerMode);
if(powerMode == adcLowPowerMode)
ADC_CFG_REG(base) |= ADC_CFG_ADLPC_MASK;
else
ADC_CFG_REG(base) &= ~ADC_CFG_ADLPC_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetClockSource
* Description : This function is used to set ADC clock source.
*
*END**************************************************************************/
void ADC_SetClockSource(ADC_Type* base, uint8_t source, uint8_t div)
{
assert(source <= adcAsynClock);
assert(div <= adcInputClockDiv8);
ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADIV_MASK)) |
ADC_CFG_ADIV(div);
ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADICLK_MASK)) |
ADC_CFG_ADICLK(source);
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetAsynClockOutput
* Description : This function is used to enable asynchronous clock source output
* regardless of the state of ADC.
*
*END**************************************************************************/
void ADC_SetAsynClockOutput(ADC_Type* base, bool enable)
{
if(enable)
ADC_GC_REG(base) |= ADC_GC_ADACKEN_MASK;
else
ADC_GC_REG(base) &= ~ADC_GC_ADACKEN_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetCalibration
* Description : Enable or disable calibration function.
*
*END**************************************************************************/
void ADC_SetCalibration(ADC_Type* base, bool enable)
{
if(enable)
ADC_GC_REG(base) |= ADC_GC_CAL_MASK;
else
ADC_GC_REG(base) &= ~ADC_GC_CAL_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetConvertCmd
* Description : Enable continuous conversion and start a conversion on target channel.
* This function is only used for software trigger mode. If configured as
* hardware trigger mode, this function just enable continuous conversion
* and not start the conversion.
*
*END**************************************************************************/
void ADC_SetConvertCmd(ADC_Type* base, uint8_t channel, bool enable)
{
uint8_t triggerMode;
/* Enable continuous conversion. */
if(enable)
{
ADC_GC_REG(base) |= ADC_GC_ADCO_MASK;
/* Start the conversion. */
triggerMode = ADC_GetConvertTrigMode(base);
if(triggerMode == adcSoftwareTrigger)
ADC_HC0_REG(base) = (ADC_HC0_REG(base) & (~ADC_HC0_ADCH_MASK)) |
ADC_HC0_ADCH(channel);
else /* Just set the channel. */
ADC_HC1_REG(base) = (ADC_HC1_REG(base) & (~ADC_HC1_ADCH_MASK)) |
ADC_HC1_ADCH(channel);
}
else
ADC_GC_REG(base) &= ~ADC_GC_ADCO_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_TriggerSingleConvert
* Description : Enable single conversion and trigger single time conversion
* on target imput channel. If configured as hardware trigger
* mode, this function just set input channel and not start a
* conversion.
*
*END**************************************************************************/
void ADC_TriggerSingleConvert(ADC_Type* base, uint8_t channel)
{
uint8_t triggerMode;
/* Enable single conversion. */
ADC_GC_REG(base) &= ~ADC_GC_ADCO_MASK;
/* Start the conversion. */
triggerMode = ADC_GetConvertTrigMode(base);
if(triggerMode == adcSoftwareTrigger)
ADC_HC0_REG(base) = (ADC_HC0_REG(base) & (~ADC_HC0_ADCH_MASK)) |
ADC_HC0_ADCH(channel);
else /* Just set the channel. */
ADC_HC1_REG(base) = (ADC_HC1_REG(base) & (~ADC_HC1_ADCH_MASK)) |
ADC_HC1_ADCH(channel);
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetAverageNum
* Description : This function is used to enable hardware aaverage function
* and set hardware average number. If avgNum is equal to
* adcAvgNumNone, it means disable hardware average function.
*
*END**************************************************************************/
void ADC_SetAverageNum(ADC_Type* base, uint8_t avgNum)
{
assert(avgNum <= adcAvgNumNone);
if(avgNum != adcAvgNumNone)
{
/* Enable hardware average function. */
ADC_GC_REG(base) |= ADC_GC_AVGE_MASK;
/* Set hardware average number. */
ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_AVGS_MASK)) |
ADC_CFG_AVGS(avgNum);
}
else
{
/* Disable hardware average function. */
ADC_GC_REG(base) &= ~ADC_GC_AVGE_MASK;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_StopConvert
* Description : This function is used to stop all conversions.
*
*END**************************************************************************/
void ADC_StopConvert(ADC_Type* base)
{
uint8_t triggerMode;
triggerMode = ADC_GetConvertTrigMode(base);
/* According trigger mode to set specific register. */
if(triggerMode == adcSoftwareTrigger)
ADC_HC0_REG(base) |= ADC_HC0_ADCH_MASK;
else
ADC_HC1_REG(base) |= ADC_HC1_ADCH_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_GetConvertResult
* Description : This function is used to get conversion result.
*
*END**************************************************************************/
uint16_t ADC_GetConvertResult(ADC_Type* base)
{
uint8_t triggerMode;
triggerMode = ADC_GetConvertTrigMode(base);
if(triggerMode == adcSoftwareTrigger)
return (uint16_t)((ADC_R0_REG(base) & ADC_R0_D_MASK) >> ADC_R0_D_SHIFT);
else
return (uint16_t)((ADC_R1_REG(base) & ADC_R1_D_MASK) >> ADC_R1_D_SHIFT);
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetCmpMode
* Description : This function is used to enable compare function
* and set comparer mode.
*
*END**************************************************************************/
void ADC_SetCmpMode(ADC_Type* base, uint8_t cmpMode, uint16_t cmpVal1, uint16_t cmpVal2)
{
assert(cmpMode <= adcCmpModeDisable);
switch(cmpMode)
{
case adcCmpModeLessThanCmpVal1:
ADC_GC_REG(base) |= ADC_GC_ACFE_MASK;
ADC_GC_REG(base) &= ~(ADC_GC_ACFGT_MASK | ADC_GC_ACREN_MASK);
ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV1_MASK)) | ADC_CV_CV1(cmpVal1);
break;
case adcCmpModeGreaterThanCmpVal1:
ADC_GC_REG(base) |= ADC_GC_ACFE_MASK;
ADC_GC_REG(base) = (ADC_GC_REG(base) | ADC_GC_ACFGT_MASK) & (~ADC_GC_ACREN_MASK);
ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV1_MASK)) | ADC_CV_CV1(cmpVal1);
break;
case adcCmpModeOutRangNotInclusive:
ADC_GC_REG(base) |= ADC_GC_ACFE_MASK;
ADC_GC_REG(base) = (ADC_GC_REG(base) | ADC_GC_ACREN_MASK) & (~ADC_GC_ACFGT_MASK);
if(cmpVal1 <= cmpVal2)
{
ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV1_MASK)) | ADC_CV_CV1(cmpVal1);
ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV2_MASK)) | ADC_CV_CV2(cmpVal2);
}
break;
case adcCmpModeInRangNotInclusive:
ADC_GC_REG(base) |= ADC_GC_ACFE_MASK;
ADC_GC_REG(base) = (ADC_GC_REG(base) | ADC_GC_ACREN_MASK) & (~ADC_GC_ACFGT_MASK);
if(cmpVal1 > cmpVal2)
{
ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV1_MASK)) | ADC_CV_CV1(cmpVal1);
ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV2_MASK)) | ADC_CV_CV2(cmpVal2);
}
break;
case adcCmpModeInRangInclusive:
ADC_GC_REG(base) |= ADC_GC_ACFE_MASK;
ADC_GC_REG(base) |= ADC_GC_ACREN_MASK | ADC_GC_ACFGT_MASK;
if(cmpVal1 <= cmpVal2)
{
ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV1_MASK)) | ADC_CV_CV1(cmpVal1);
ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV2_MASK)) | ADC_CV_CV2(cmpVal2);
}
break;
case adcCmpModeOutRangInclusive:
ADC_GC_REG(base) |= ADC_GC_ACFE_MASK;
ADC_GC_REG(base) |= ADC_GC_ACREN_MASK | ADC_GC_ACFGT_MASK;
if(cmpVal1 > cmpVal2)
{
ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV1_MASK)) | ADC_CV_CV1(cmpVal1);
ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV2_MASK)) | ADC_CV_CV2(cmpVal2);
}
break;
case adcCmpModeDisable:
ADC_GC_REG(base) &= ~ADC_GC_ACFE_MASK;
break;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetCorrectionMode
* Description : This function is used to set offset correct mode.
*
*END**************************************************************************/
void ADC_SetCorrectionMode(ADC_Type* base, bool correctMode)
{
if(correctMode)
ADC_OFS_REG(base) |= ADC_OFS_SIGN_MASK;
else
ADC_OFS_REG(base) &= ~ADC_OFS_SIGN_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetIntCmd
* Description : Enables or disables ADC conversion complete interrupt request.
*
*END**************************************************************************/
void ADC_SetIntCmd(ADC_Type* base, bool enable)
{
uint8_t triggerMode;
triggerMode = ADC_GetConvertTrigMode(base);
if(triggerMode == adcSoftwareTrigger)
{
if(enable)
ADC_HC0_REG(base) |= ADC_HC0_AIEN_MASK;
else
ADC_HC0_REG(base) &= ~ADC_HC0_AIEN_MASK;
}
else
{
if(enable)
ADC_HC1_REG(base) |= ADC_HC1_AIEN_MASK;
else
ADC_HC1_REG(base) &= ~ADC_HC1_AIEN_MASK;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_IsConvertComplete
* Description : This function is used to get ADC conversion complete status.
*
*END**************************************************************************/
bool ADC_IsConvertComplete(ADC_Type* base)
{
uint8_t triggerMode;
triggerMode = ADC_GetConvertTrigMode(base);
if(triggerMode == adcSoftwareTrigger)
return (bool)((ADC_HS_REG(base) & ADC_HS_COCO0_MASK) >> ADC_HS_COCO0_SHIFT);
else
return (bool)((ADC_HS_REG(base) & ADC_HS_COCO1_MASK) >> ADC_HS_COCO1_SHIFT);
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetDmaCmd
* Description : Enable or disable DMA request.
*
*END**************************************************************************/
void ADC_SetDmaCmd(ADC_Type* base, bool enable)
{
if (enable)
ADC_GC_REG(base) |= ADC_GC_DMAEN_MASK;
else
ADC_GC_REG(base) &= ~ADC_GC_DMAEN_MASK;
}
/*******************************************************************************
* EOF
******************************************************************************/