| /* |
| * 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 |
| ******************************************************************************/ |