summaryrefslogtreecommitdiffstats
path: root/bsps/arm/imxrt/mcux-sdk/drivers/lpadc/fsl_lpadc.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--bsps/arm/imxrt/mcux-sdk/drivers/lpadc/fsl_lpadc.c708
1 files changed, 708 insertions, 0 deletions
diff --git a/bsps/arm/imxrt/mcux-sdk/drivers/lpadc/fsl_lpadc.c b/bsps/arm/imxrt/mcux-sdk/drivers/lpadc/fsl_lpadc.c
new file mode 100644
index 0000000000..b930fd9f93
--- /dev/null
+++ b/bsps/arm/imxrt/mcux-sdk/drivers/lpadc/fsl_lpadc.c
@@ -0,0 +1,708 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2022 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);
+
+#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE
+/*!
+ * @brief Get gain conversion result .
+ *
+ * @param gainAdjustment gain adjustment value.
+ */
+static uint32_t LPADC_GetGainConvResult(float gainAdjustment);
+#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE */
+
+/*******************************************************************************
+ * 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;
+}
+
+#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE
+/*!
+ * brief Get gain conversion Result .
+ *
+ * param gainAdjustment gain adjustment value.
+ */
+static uint32_t LPADC_GetGainConvResult(float gainAdjustment)
+{
+ int8_t i = 0;
+ uint32_t tmp32 = 0U;
+ uint32_t GCRa[17] = {0};
+ uint32_t GCALR = 0U;
+
+ for (i = 0x10; i >= 0; i--)
+ {
+ tmp32 = (uint32_t)((gainAdjustment) / ((float)(1.0 / (0x01 << (0x10 - i)))));
+ GCRa[i] = tmp32;
+ gainAdjustment = gainAdjustment - ((float)tmp32) * ((float)(1.0 / (0x01 << (0x10 - i))));
+ }
+ /* Get GCALR value calculated */
+ for (i = 0x10; i >= 0; i--)
+ {
+ GCALR += GCRa[i] * (0x01 << i);
+ }
+
+ /* to return GCALR value calculated */
+ return GCALR;
+}
+#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE */
+
+/*!
+ * 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. */
+
+#if !(defined(FSL_FEATURE_LPADC_HAS_CFG_PWRSEL) && (FSL_FEATURE_LPADC_HAS_CFG_PWRSEL == 0))
+ | ADC_CFG_PWRSEL(config->powerLevelMode) /* Power configuration. */
+#endif /* FSL_FEATURE_LPADC_HAS_CFG_PWRSEL */
+ | 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;
+#if !(defined(FSL_FEATURE_LPADC_HAS_CFG_PWRSEL) && (FSL_FEATURE_LPADC_HAS_CFG_PWRSEL == 0))
+ config->powerLevelMode = kLPADC_PowerLevelAlt1;
+#endif /* FSL_FEATURE_LPADC_HAS_CFG_PWRSEL */
+ 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_ALTB_ADCH) && FSL_FEATURE_LPADC_HAS_CMDL_ALTB_ADCH
+ tmp32 |= ADC_CMDL_ALTB_ADCH(config->channelBNumber); /* Alternate channel B number. */
+#endif
+#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_ALTB_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE
+ tmp32 |= ADC_CMDL_ALTB_CSCALE(config->channelBScaleMode); /* Alternate channel B full/Part scale input voltage. */
+#endif /* FSL_FEATURE_LPADC_HAS_CMDL_ALTB_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 */
+
+#if defined(FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN) && FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN
+ /* Enable alternate channel B.*/
+ if (config->enableChannelB)
+ {
+ tmp32 |= ADC_CMDL_ALTBEN_MASK;
+ }
+#endif /* FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN */
+
+ 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->channelBScaleMode = kLPADC_SampleFullScale;
+ * config->channelSampleMode = kLPADC_SampleChannelSingleEndSideA;
+ * config->channelNumber = 0U;
+ * config ->alternateChannelNumber = 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;
+ * config->enableChannelB = 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 */
+#if defined(FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE
+ config->channelBScaleMode = kLPADC_SampleFullScale;
+#endif /* FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE */
+ config->sampleChannelMode = kLPADC_SampleChannelSingleEndSideA;
+ config->channelNumber = 0U;
+#if defined(FSL_FEATURE_LPADC_HAS_CMDL_ALTB_ADCH) && FSL_FEATURE_LPADC_HAS_CMDL_ALTB_ADCH
+ config->channelBNumber = 0U;
+#endif /* FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE */
+ 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_CMDL_ALTBEN) && FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN
+ config->enableChannelB = false; /* Enable alternate channel B.*/
+#endif /* FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN */
+}
+
+#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)));
+
+#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE
+ int32_t GCCa;
+ int32_t GCCb;
+ float GCRa;
+ float GCRb;
+#else
+ uint32_t GCCa;
+ uint32_t GCCb;
+ uint32_t GCRa;
+ uint32_t GCRb;
+#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE */
+
+ /* 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);
+
+#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE
+ if (((base->GCC[0]) & 0x8000U))
+ {
+ GCCa = GCCa - 0x10000;
+ GCRa =
+ (float)((131072.0) / (0x20000 - GCCa)); /* Gain_CalA = (131072.0 / (131072-(ADC_GCC_GAIN_CAL(ADC->GCC[0]))*/
+ base->GCR[0] = LPADC_GetGainConvResult(GCRa); /* write A side GCALR. */
+ }
+
+ if (((base->GCC[1]) & 0x8000U))
+ {
+ GCCb = GCCb - 0x10000;
+ GCRb =
+ (float)((131072.0) / (0x20000 - GCCb)); /* Gain_CalB = (131072.0 / (131072-(ADC_GCC_GAIN_CAL(ADC->GCC[1]))*/
+ base->GCR[1] = LPADC_GetGainConvResult(GCRb); /* write B side GCALR. */
+ }
+#else
+ 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);
+#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE */
+ /* 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 */