123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612 |
- /*
- * Copyright (c) 2016, Freescale Semiconductor, Inc.
- * Copyright 2016-2020 NXP
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include "fsl_lpadc.h"
- /* Component ID definition, used by tools. */
- #ifndef FSL_COMPONENT_ID
- #define FSL_COMPONENT_ID "platform.drivers.lpadc"
- #endif
- /*******************************************************************************
- * Prototypes
- ******************************************************************************/
- /*!
- * @brief Get instance number for LPADC module.
- *
- * @param base LPADC peripheral base address
- */
- static uint32_t LPADC_GetInstance(ADC_Type *base);
- /*******************************************************************************
- * Variables
- ******************************************************************************/
- /*! @brief Pointers to LPADC bases for each instance. */
- static ADC_Type *const s_lpadcBases[] = ADC_BASE_PTRS;
- #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
- /*! @brief Pointers to LPADC clocks for each instance. */
- static const clock_ip_name_t s_lpadcClocks[] = LPADC_CLOCKS;
- #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
- /*******************************************************************************
- * Code
- ******************************************************************************/
- static uint32_t LPADC_GetInstance(ADC_Type *base)
- {
- uint32_t instance;
- /* Find the instance index from base address mappings. */
- for (instance = 0; instance < ARRAY_SIZE(s_lpadcBases); instance++)
- {
- if (s_lpadcBases[instance] == base)
- {
- break;
- }
- }
- assert(instance < ARRAY_SIZE(s_lpadcBases));
- return instance;
- }
- /*!
- * brief Initializes the LPADC module.
- *
- * param base LPADC peripheral base address.
- * param config Pointer to configuration structure. See "lpadc_config_t".
- */
- void LPADC_Init(ADC_Type *base, const lpadc_config_t *config)
- {
- /* Check if the pointer is available. */
- assert(config != NULL);
- uint32_t tmp32 = 0U;
- #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
- /* Enable the clock for LPADC instance. */
- (void)CLOCK_EnableClock(s_lpadcClocks[LPADC_GetInstance(base)]);
- #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
- /* Reset the module. */
- LPADC_DoResetConfig(base);
- #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
- LPADC_DoResetFIFO0(base);
- LPADC_DoResetFIFO1(base);
- #else
- LPADC_DoResetFIFO(base);
- #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
- /* Disable the module before setting configuration. */
- LPADC_Enable(base, false);
- /* Configure the module generally. */
- if (config->enableInDozeMode)
- {
- base->CTRL &= ~ADC_CTRL_DOZEN_MASK;
- }
- else
- {
- base->CTRL |= ADC_CTRL_DOZEN_MASK;
- }
- #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS
- /* Set calibration average mode. */
- base->CTRL |= ADC_CTRL_CAL_AVGS(config->conversionAverageMode);
- #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS */
- /* ADCx_CFG. */
- #if defined(FSL_FEATURE_LPADC_HAS_CFG_ADCKEN) && FSL_FEATURE_LPADC_HAS_CFG_ADCKEN
- if (config->enableInternalClock)
- {
- tmp32 |= ADC_CFG_ADCKEN_MASK;
- }
- #endif /* FSL_FEATURE_LPADC_HAS_CFG_ADCKEN */
- #if defined(FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG) && FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG
- if (config->enableVref1LowVoltage)
- {
- tmp32 |= ADC_CFG_VREF1RNG_MASK;
- }
- #endif /* FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG */
- if (config->enableAnalogPreliminary)
- {
- tmp32 |= ADC_CFG_PWREN_MASK;
- }
- tmp32 |= ADC_CFG_PUDLY(config->powerUpDelay) /* Power up delay. */
- | ADC_CFG_REFSEL(config->referenceVoltageSource) /* Reference voltage. */
- | ADC_CFG_PWRSEL(config->powerLevelMode) /* Power configuration. */
- | ADC_CFG_TPRICTRL(config->triggerPriorityPolicy); /* Trigger priority policy. */
- base->CFG = tmp32;
- /* ADCx_PAUSE. */
- if (config->enableConvPause)
- {
- base->PAUSE = ADC_PAUSE_PAUSEEN_MASK | ADC_PAUSE_PAUSEDLY(config->convPauseDelay);
- }
- else
- {
- base->PAUSE = 0U;
- }
- #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
- /* ADCx_FCTRL0. */
- base->FCTRL[0] = ADC_FCTRL_FWMARK(config->FIFO0Watermark);
- /* ADCx_FCTRL1. */
- base->FCTRL[1] = ADC_FCTRL_FWMARK(config->FIFO1Watermark);
- #else
- /* ADCx_FCTRL. */
- base->FCTRL = ADC_FCTRL_FWMARK(config->FIFOWatermark);
- #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
- /* Enable the module after setting configuration. */
- LPADC_Enable(base, true);
- }
- /*!
- * brief Gets an available pre-defined settings for initial configuration.
- *
- * This function initializes the converter configuration structure with an available settings. The default values are:
- * code
- * config->enableInDozeMode = true;
- * config->conversionAverageMode = kLPADC_ConversionAverage1;
- * config->enableAnalogPreliminary = false;
- * config->powerUpDelay = 0x80;
- * config->referenceVoltageSource = kLPADC_ReferenceVoltageAlt1;
- * config->powerLevelMode = kLPADC_PowerLevelAlt1;
- * config->triggerPriorityPolicy = kLPADC_TriggerPriorityPreemptImmediately;
- * config->enableConvPause = false;
- * config->convPauseDelay = 0U;
- * config->FIFO0Watermark = 0U;
- * config->FIFO1Watermark = 0U;
- * config->FIFOWatermark = 0U;
- * endcode
- * param config Pointer to configuration structure.
- */
- void LPADC_GetDefaultConfig(lpadc_config_t *config)
- {
- /* Initializes the configure structure to zero. */
- (void)memset(config, 0, sizeof(*config));
- #if defined(FSL_FEATURE_LPADC_HAS_CFG_ADCKEN) && FSL_FEATURE_LPADC_HAS_CFG_ADCKEN
- config->enableInternalClock = false;
- #endif /* FSL_FEATURE_LPADC_HAS_CFG_ADCKEN */
- #if defined(FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG) && FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG
- config->enableVref1LowVoltage = false;
- #endif /* FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG */
- config->enableInDozeMode = true;
- #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS
- /* Set calibration average mode. */
- config->conversionAverageMode = kLPADC_ConversionAverage1;
- #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS */
- config->enableAnalogPreliminary = false;
- config->powerUpDelay = 0x80;
- config->referenceVoltageSource = kLPADC_ReferenceVoltageAlt1;
- config->powerLevelMode = kLPADC_PowerLevelAlt1;
- config->triggerPriorityPolicy = kLPADC_TriggerPriorityPreemptImmediately;
- config->enableConvPause = false;
- config->convPauseDelay = 0U;
- #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
- config->FIFO0Watermark = 0U;
- config->FIFO1Watermark = 0U;
- #else
- config->FIFOWatermark = 0U;
- #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
- }
- /*!
- * brief De-initializes the LPADC module.
- *
- * param base LPADC peripheral base address.
- */
- void LPADC_Deinit(ADC_Type *base)
- {
- /* Disable the module. */
- LPADC_Enable(base, false);
- #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
- /* Gate the clock. */
- (void)CLOCK_DisableClock(s_lpadcClocks[LPADC_GetInstance(base)]);
- #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
- }
- #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
- /*!
- * brief Get the result in conversion FIFOn.
- *
- * param base LPADC peripheral base address.
- * param result Pointer to structure variable that keeps the conversion result in conversion FIFOn.
- * param index Result FIFO index.
- *
- * return Status whether FIFOn entry is valid.
- */
- bool LPADC_GetConvResult(ADC_Type *base, lpadc_conv_result_t *result, uint8_t index)
- {
- assert(result != NULL); /* Check if the input pointer is available. */
- uint32_t tmp32;
- tmp32 = base->RESFIFO[index];
- if (0U == (ADC_RESFIFO_VALID_MASK & tmp32))
- {
- return false; /* FIFO is empty. Discard any read from RESFIFO. */
- }
- result->commandIdSource = (tmp32 & ADC_RESFIFO_CMDSRC_MASK) >> ADC_RESFIFO_CMDSRC_SHIFT;
- result->loopCountIndex = (tmp32 & ADC_RESFIFO_LOOPCNT_MASK) >> ADC_RESFIFO_LOOPCNT_SHIFT;
- result->triggerIdSource = (tmp32 & ADC_RESFIFO_TSRC_MASK) >> ADC_RESFIFO_TSRC_SHIFT;
- result->convValue = (uint16_t)(tmp32 & ADC_RESFIFO_D_MASK);
- return true;
- }
- #else
- /*!
- * brief Get the result in conversion FIFO.
- *
- * param base LPADC peripheral base address.
- * param result Pointer to structure variable that keeps the conversion result in conversion FIFO.
- *
- * return Status whether FIFO entry is valid.
- */
- bool LPADC_GetConvResult(ADC_Type *base, lpadc_conv_result_t *result)
- {
- assert(result != NULL); /* Check if the input pointer is available. */
- uint32_t tmp32;
- tmp32 = base->RESFIFO;
- if (0U == (ADC_RESFIFO_VALID_MASK & tmp32))
- {
- return false; /* FIFO is empty. Discard any read from RESFIFO. */
- }
- result->commandIdSource = (tmp32 & ADC_RESFIFO_CMDSRC_MASK) >> ADC_RESFIFO_CMDSRC_SHIFT;
- result->loopCountIndex = (tmp32 & ADC_RESFIFO_LOOPCNT_MASK) >> ADC_RESFIFO_LOOPCNT_SHIFT;
- result->triggerIdSource = (tmp32 & ADC_RESFIFO_TSRC_MASK) >> ADC_RESFIFO_TSRC_SHIFT;
- result->convValue = (uint16_t)(tmp32 & ADC_RESFIFO_D_MASK);
- return true;
- }
- #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
- /*!
- * brief Configure the conversion trigger source.
- *
- * Each programmable trigger can launch the conversion command in command buffer.
- *
- * param base LPADC peripheral base address.
- * param triggerId ID for each trigger. Typically, the available value range is from 0.
- * param config Pointer to configuration structure. See to #lpadc_conv_trigger_config_t.
- */
- void LPADC_SetConvTriggerConfig(ADC_Type *base, uint32_t triggerId, const lpadc_conv_trigger_config_t *config)
- {
- assert(triggerId < ADC_TCTRL_COUNT); /* Check if the triggerId is available in this device. */
- assert(config != NULL); /* Check if the input pointer is available. */
- uint32_t tmp32;
- tmp32 = ADC_TCTRL_TCMD(config->targetCommandId) /* Trigger command select. */
- | ADC_TCTRL_TDLY(config->delayPower) /* Trigger delay select. */
- | ADC_TCTRL_TPRI(config->priority) /* Trigger priority setting. */
- #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
- | ADC_TCTRL_FIFO_SEL_A(config->channelAFIFOSelect)
- #if !(defined(FSL_FEATURE_LPADC_HAS_NO_TCTRL_FIFO_SEL_B) && FSL_FEATURE_LPADC_HAS_NO_TCTRL_FIFO_SEL_B)
- | ADC_TCTRL_FIFO_SEL_B(config->channelBFIFOSelect)
- #endif /* FSL_FEATURE_LPADC_HAS_NO_TCTRL_FIFO_SEL_B */
- #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
- ;
- if (config->enableHardwareTrigger)
- {
- tmp32 |= ADC_TCTRL_HTEN_MASK;
- }
- base->TCTRL[triggerId] = tmp32;
- }
- /*!
- * brief Gets an available pre-defined settings for trigger's configuration.
- *
- * This function initializes the trigger's configuration structure with an available settings. The default values are:
- * code
- * config->commandIdSource = 0U;
- * config->loopCountIndex = 0U;
- * config->triggerIdSource = 0U;
- * config->enableHardwareTrigger = false;
- * config->channelAFIFOSelect = 0U;
- * config->channelBFIFOSelect = 0U;
- * endcode
- * param config Pointer to configuration structure.
- */
- void LPADC_GetDefaultConvTriggerConfig(lpadc_conv_trigger_config_t *config)
- {
- assert(config != NULL); /* Check if the input pointer is available. */
- /* Initializes the configure structure to zero. */
- (void)memset(config, 0, sizeof(*config));
- config->targetCommandId = 0U;
- config->delayPower = 0U;
- config->priority = 0U;
- #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
- config->channelAFIFOSelect = 0U;
- config->channelBFIFOSelect = 0U;
- #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
- config->enableHardwareTrigger = false;
- }
- /*!
- * brief Configure conversion command.
- *
- * param base LPADC peripheral base address.
- * param commandId ID for command in command buffer. Typically, the available value range is 1 - 15.
- * param config Pointer to configuration structure. See to #lpadc_conv_command_config_t.
- */
- void LPADC_SetConvCommandConfig(ADC_Type *base, uint32_t commandId, const lpadc_conv_command_config_t *config)
- {
- assert(commandId < (ADC_CMDL_COUNT + 1U)); /* Check if the commandId is available on this device. */
- assert(config != NULL); /* Check if the input pointer is available. */
- uint32_t tmp32 = 0;
- commandId--; /* The available command number are 1-15, while the index of register group are 0-14. */
- /* ADCx_CMDL. */
- tmp32 = ADC_CMDL_ADCH(config->channelNumber); /* Channel number. */
- #if defined(FSL_FEATURE_LPADC_HAS_CMDL_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_CSCALE
- tmp32 |= ADC_CMDL_CSCALE(config->sampleScaleMode); /* Full/Part scale input voltage. */
- #endif /* FSL_FEATURE_LPADC_HAS_CMDL_CSCALE */
- #if defined(FSL_FEATURE_LPADC_HAS_CMDL_CTYPE) && FSL_FEATURE_LPADC_HAS_CMDL_CTYPE
- tmp32 |= ADC_CMDL_CTYPE(config->sampleChannelMode);
- #else
- switch (config->sampleChannelMode) /* Sample input. */
- {
- case kLPADC_SampleChannelSingleEndSideB:
- tmp32 |= ADC_CMDL_ABSEL_MASK;
- break;
- #if defined(FSL_FEATURE_LPADC_HAS_CMDL_DIFF) && FSL_FEATURE_LPADC_HAS_CMDL_DIFF
- case kLPADC_SampleChannelDiffBothSideAB:
- tmp32 |= ADC_CMDL_DIFF_MASK;
- break;
- case kLPADC_SampleChannelDiffBothSideBA:
- tmp32 |= ADC_CMDL_ABSEL_MASK | ADC_CMDL_DIFF_MASK;
- break;
- #endif /* FSL_FEATURE_LPADC_HAS_CMDL_DIFF */
- default: /* kLPADC_SampleChannelSingleEndSideA. */
- break;
- }
- #endif /* FSL_FEATURE_LPADC_HAS_CMDL_CTYPE */
- #if defined(FSL_FEATURE_LPADC_HAS_CMDL_MODE) && FSL_FEATURE_LPADC_HAS_CMDL_MODE
- tmp32 |= ADC_CMDL_MODE(config->conversionResolutionMode);
- #endif /* FSL_FEATURE_LPADC_HAS_CMDL_MODE */
- base->CMD[commandId].CMDL = tmp32;
- /* ADCx_CMDH. */
- tmp32 = ADC_CMDH_NEXT(config->chainedNextCommandNumber) /* Next Command Select. */
- | ADC_CMDH_LOOP(config->loopCount) /* Loop Count Select. */
- | ADC_CMDH_AVGS(config->hardwareAverageMode) /* Hardware Average Select. */
- | ADC_CMDH_STS(config->sampleTimeMode) /* Sample Time Select. */
- | ADC_CMDH_CMPEN(config->hardwareCompareMode); /* Hardware compare enable. */
- #if (defined(FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG) && FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG)
- if (config->enableWaitTrigger)
- {
- tmp32 |= ADC_CMDH_WAIT_TRIG_MASK; /* Wait trigger enable. */
- }
- #endif /* FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG */
- if (config->enableAutoChannelIncrement)
- {
- tmp32 |= ADC_CMDH_LWI_MASK;
- }
- base->CMD[commandId].CMDH = tmp32;
- /* Hardware compare settings.
- * Not all Command Buffers have an associated Compare Value register. The compare function is only available on
- * Command Buffers that have a corresponding Compare Value register.
- */
- if (kLPADC_HardwareCompareDisabled != config->hardwareCompareMode)
- {
- /* Check if the hardware compare feature is available for indicated command buffer. */
- assert(commandId < ADC_CV_COUNT);
- /* Set CV register. */
- base->CV[commandId] = ADC_CV_CVH(config->hardwareCompareValueHigh) /* Compare value high. */
- | ADC_CV_CVL(config->hardwareCompareValueLow); /* Compare value low. */
- }
- }
- /*!
- * brief Gets an available pre-defined settings for conversion command's configuration.
- *
- * This function initializes the conversion command's configuration structure with an available settings. The default
- * values are:
- * code
- * config->sampleScaleMode = kLPADC_SampleFullScale;
- * config->channelSampleMode = kLPADC_SampleChannelSingleEndSideA;
- * config->channelNumber = 0U;
- * config->chainedNextCmdNumber = 0U;
- * config->enableAutoChannelIncrement = false;
- * config->loopCount = 0U;
- * config->hardwareAverageMode = kLPADC_HardwareAverageCount1;
- * config->sampleTimeMode = kLPADC_SampleTimeADCK3;
- * config->hardwareCompareMode = kLPADC_HardwareCompareDisabled;
- * config->hardwareCompareValueHigh = 0U;
- * config->hardwareCompareValueLow = 0U;
- * config->conversionResolutionMode = kLPADC_ConversionResolutionStandard;
- * config->enableWaitTrigger = false;
- * endcode
- * param config Pointer to configuration structure.
- */
- void LPADC_GetDefaultConvCommandConfig(lpadc_conv_command_config_t *config)
- {
- assert(config != NULL); /* Check if the input pointer is available. */
- /* Initializes the configure structure to zero. */
- (void)memset(config, 0, sizeof(*config));
- #if defined(FSL_FEATURE_LPADC_HAS_CMDL_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_CSCALE
- config->sampleScaleMode = kLPADC_SampleFullScale;
- #endif /* FSL_FEATURE_LPADC_HAS_CMDL_CSCALE */
- config->sampleChannelMode = kLPADC_SampleChannelSingleEndSideA;
- config->channelNumber = 0U;
- config->chainedNextCommandNumber = 0U; /* No next command defined. */
- config->enableAutoChannelIncrement = false;
- config->loopCount = 0U;
- config->hardwareAverageMode = kLPADC_HardwareAverageCount1;
- config->sampleTimeMode = kLPADC_SampleTimeADCK3;
- config->hardwareCompareMode = kLPADC_HardwareCompareDisabled;
- config->hardwareCompareValueHigh = 0U; /* No used. */
- config->hardwareCompareValueLow = 0U; /* No used. */
- #if defined(FSL_FEATURE_LPADC_HAS_CMDL_MODE) && FSL_FEATURE_LPADC_HAS_CMDL_MODE
- config->conversionResolutionMode = kLPADC_ConversionResolutionStandard;
- #endif /* FSL_FEATURE_LPADC_HAS_CMDL_MODE */
- #if defined(FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG) && FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG
- config->enableWaitTrigger = false;
- #endif /* FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG */
- }
- #if defined(FSL_FEATURE_LPADC_HAS_CFG_CALOFS) && FSL_FEATURE_LPADC_HAS_CFG_CALOFS
- /*!
- * brief Enable the calibration function.
- *
- * When CALOFS is set, the ADC is configured to perform a calibration function anytime the ADC executes
- * a conversion. Any channel selected is ignored and the value returned in the RESFIFO is a signed value
- * between -31 and 31. -32 is not a valid and is never a returned value. Software should copy the lower 6-
- * bits of the conversion result stored in the RESFIFO after a completed calibration conversion to the
- * OFSTRIM field. The OFSTRIM field is used in normal operation for offset correction.
- *
- * param base LPADC peripheral base address.
- * param enable switcher to the calibration function.
- */
- void LPADC_EnableCalibration(ADC_Type *base, bool enable)
- {
- LPADC_Enable(base, false);
- if (enable)
- {
- base->CFG |= ADC_CFG_CALOFS_MASK;
- }
- else
- {
- base->CFG &= ~ADC_CFG_CALOFS_MASK;
- }
- LPADC_Enable(base, true);
- }
- #if defined(FSL_FEATURE_LPADC_HAS_OFSTRIM) && FSL_FEATURE_LPADC_HAS_OFSTRIM
- /*!
- * brief Do auto calibration.
- *
- * Calibration function should be executed before using converter in application. It used the software trigger and a
- * dummy conversion, get the offset and write them into the OFSTRIM register. It called some of functional API
- * including: -LPADC_EnableCalibration(...) -LPADC_LPADC_SetOffsetValue(...) -LPADC_SetConvCommandConfig(...)
- * -LPADC_SetConvTriggerConfig(...)
- *
- * param base LPADC peripheral base address.
- */
- void LPADC_DoAutoCalibration(ADC_Type *base)
- {
- assert(0u == LPADC_GetConvResultCount(base));
- uint32_t mLpadcCMDL;
- uint32_t mLpadcCMDH;
- uint32_t mLpadcTrigger;
- lpadc_conv_trigger_config_t mLpadcTriggerConfigStruct;
- lpadc_conv_command_config_t mLpadcCommandConfigStruct;
- lpadc_conv_result_t mLpadcResultConfigStruct;
- /* Enable the calibration function. */
- LPADC_EnableCalibration(base, true);
- /* Keep the CMD and TRG state here and restore it later if the calibration completes.*/
- mLpadcCMDL = base->CMD[0].CMDL; /* CMD1L. */
- mLpadcCMDH = base->CMD[0].CMDH; /* CMD1H. */
- mLpadcTrigger = base->TCTRL[0]; /* Trigger0. */
- /* Set trigger0 configuration - for software trigger. */
- LPADC_GetDefaultConvTriggerConfig(&mLpadcTriggerConfigStruct);
- mLpadcTriggerConfigStruct.targetCommandId = 1U; /* CMD1 is executed. */
- LPADC_SetConvTriggerConfig(base, 0U, &mLpadcTriggerConfigStruct); /* Configurate the trigger0. */
- /* Set conversion CMD configuration. */
- LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct);
- mLpadcCommandConfigStruct.hardwareAverageMode = kLPADC_HardwareAverageCount128;
- LPADC_SetConvCommandConfig(base, 1U, &mLpadcCommandConfigStruct); /* Set CMD1 configuration. */
- /* Do calibration. */
- LPADC_DoSoftwareTrigger(base, 1U); /* 1U is trigger0 mask. */
- while (!LPADC_GetConvResult(base, &mLpadcResultConfigStruct))
- {
- }
- /* The valid bits of data are bits 14:3 in the RESFIFO register. */
- LPADC_SetOffsetValue(base, (uint32_t)(mLpadcResultConfigStruct.convValue) >> 3UL);
- /* Disable the calibration function. */
- LPADC_EnableCalibration(base, false);
- /* restore CMD and TRG registers. */
- base->CMD[0].CMDL = mLpadcCMDL; /* CMD1L. */
- base->CMD[0].CMDH = mLpadcCMDH; /* CMD1H. */
- base->TCTRL[0] = mLpadcTrigger; /* Trigger0. */
- }
- #endif /* FSL_FEATURE_LPADC_HAS_OFSTRIM */
- #endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */
- #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFS
- /*!
- * brief Do offset calibration.
- *
- * param base LPADC peripheral base address.
- */
- void LPADC_DoOffsetCalibration(ADC_Type *base)
- {
- LPADC_EnableOffsetCalibration(base, true);
- while (ADC_STAT_CAL_RDY_MASK != (base->STAT & ADC_STAT_CAL_RDY_MASK))
- {
- }
- }
- #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ
- /*!
- * brief Do auto calibration.
- *
- * param base LPADC peripheral base address.
- */
- void LPADC_DoAutoCalibration(ADC_Type *base)
- {
- assert((0u == LPADC_GetConvResultCount(base, 0)) && (0u == LPADC_GetConvResultCount(base, 1)));
- uint32_t GCCa;
- uint32_t GCCb;
- uint32_t GCRa;
- uint32_t GCRb;
- /* Request gain calibration. */
- base->CTRL |= ADC_CTRL_CAL_REQ_MASK;
- while ((ADC_GCC_RDY_MASK != (base->GCC[0] & ADC_GCC_RDY_MASK)) ||
- (ADC_GCC_RDY_MASK != (base->GCC[1] & ADC_GCC_RDY_MASK)))
- {
- }
- /* Calculate gain offset. */
- GCCa = (base->GCC[0] & ADC_GCC_GAIN_CAL_MASK);
- GCCb = (base->GCC[1] & ADC_GCC_GAIN_CAL_MASK);
- GCRa = (uint16_t)((GCCa << 16U) /
- (0x1FFFFU - GCCa)); /* Gain_CalA = (131072 / (131072-(ADC_GCC_GAIN_CAL(ADC0->GCC[0])) - 1. */
- GCRb = (uint16_t)((GCCb << 16U) /
- (0x1FFFFU - GCCb)); /* Gain_CalB = (131072 / (131072-(ADC_GCC_GAIN_CAL(ADC0->GCC[1])) - 1. */
- base->GCR[0] = ADC_GCR_GCALR(GCRa);
- base->GCR[1] = ADC_GCR_GCALR(GCRb);
- /* Indicate the values are valid. */
- base->GCR[0] |= ADC_GCR_RDY_MASK;
- base->GCR[1] |= ADC_GCR_RDY_MASK;
- while (ADC_STAT_CAL_RDY_MASK != (base->STAT & ADC_STAT_CAL_RDY_MASK))
- {
- }
- }
- #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ */
- #endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */
|