Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:00

0001 /*
0002  * Copyright (c) 2016, Freescale Semiconductor, Inc.
0003  * Copyright 2016-2022 NXP
0004  * All rights reserved.
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #include "fsl_lpadc.h"
0010 
0011 /* Component ID definition, used by tools. */
0012 #ifndef FSL_COMPONENT_ID
0013 #define FSL_COMPONENT_ID "platform.drivers.lpadc"
0014 #endif
0015 
0016 /*******************************************************************************
0017  * Prototypes
0018  ******************************************************************************/
0019 /*!
0020  * @brief Get instance number for LPADC module.
0021  *
0022  * @param base LPADC peripheral base address
0023  */
0024 static uint32_t LPADC_GetInstance(ADC_Type *base);
0025 
0026 #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE
0027 /*!
0028  * @brief Get gain conversion result .
0029  *
0030  * @param gainAdjustment gain adjustment value.
0031  */
0032 static uint32_t LPADC_GetGainConvResult(float gainAdjustment);
0033 #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE */
0034 
0035 /*******************************************************************************
0036  * Variables
0037  ******************************************************************************/
0038 /*! @brief Pointers to LPADC bases for each instance. */
0039 static ADC_Type *const s_lpadcBases[] = ADC_BASE_PTRS;
0040 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0041 /*! @brief Pointers to LPADC clocks for each instance. */
0042 static const clock_ip_name_t s_lpadcClocks[] = LPADC_CLOCKS;
0043 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0044 
0045 /*******************************************************************************
0046  * Code
0047  ******************************************************************************/
0048 static uint32_t LPADC_GetInstance(ADC_Type *base)
0049 {
0050     uint32_t instance;
0051 
0052     /* Find the instance index from base address mappings. */
0053     for (instance = 0; instance < ARRAY_SIZE(s_lpadcBases); instance++)
0054     {
0055         if (s_lpadcBases[instance] == base)
0056         {
0057             break;
0058         }
0059     }
0060 
0061     assert(instance < ARRAY_SIZE(s_lpadcBases));
0062 
0063     return instance;
0064 }
0065 
0066 #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE
0067 /*!
0068  * brief  Get gain conversion Result .
0069  *
0070  * param gainAdjustment gain adjustment value.
0071  */
0072 static uint32_t LPADC_GetGainConvResult(float gainAdjustment)
0073 {
0074     int8_t i          = 0;
0075     uint32_t tmp32    = 0U;
0076     uint32_t GCRa[17] = {0};
0077     uint32_t GCALR    = 0U;
0078 
0079     for (i = 0x10; i >= 0; i--)
0080     {
0081         tmp32          = (uint32_t)((gainAdjustment) / ((float)(1.0 / (0x01 << (0x10 - i)))));
0082         GCRa[i]        = tmp32;
0083         gainAdjustment = gainAdjustment - ((float)tmp32) * ((float)(1.0 / (0x01 << (0x10 - i))));
0084     }
0085     /* Get GCALR value calculated */
0086     for (i = 0x10; i >= 0; i--)
0087     {
0088         GCALR += GCRa[i] * (0x01 << i);
0089     }
0090 
0091     /* to return GCALR value calculated */
0092     return GCALR;
0093 }
0094 #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE */
0095 
0096 /*!
0097  * brief Initializes the LPADC module.
0098  *
0099  * param base   LPADC peripheral base address.
0100  * param config Pointer to configuration structure. See "lpadc_config_t".
0101  */
0102 void LPADC_Init(ADC_Type *base, const lpadc_config_t *config)
0103 {
0104     /* Check if the pointer is available. */
0105     assert(config != NULL);
0106 
0107     uint32_t tmp32 = 0U;
0108 
0109 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0110     /* Enable the clock for LPADC instance. */
0111     (void)CLOCK_EnableClock(s_lpadcClocks[LPADC_GetInstance(base)]);
0112 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0113 
0114     /* Reset the module. */
0115     LPADC_DoResetConfig(base);
0116 #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
0117     LPADC_DoResetFIFO0(base);
0118     LPADC_DoResetFIFO1(base);
0119 #else
0120     LPADC_DoResetFIFO(base);
0121 #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
0122 
0123     /* Disable the module before setting configuration. */
0124     LPADC_Enable(base, false);
0125 
0126     /* Configure the module generally. */
0127     if (config->enableInDozeMode)
0128     {
0129         base->CTRL &= ~ADC_CTRL_DOZEN_MASK;
0130     }
0131     else
0132     {
0133         base->CTRL |= ADC_CTRL_DOZEN_MASK;
0134     }
0135 
0136 #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS
0137     /* Set calibration average mode. */
0138     base->CTRL |= ADC_CTRL_CAL_AVGS(config->conversionAverageMode);
0139 #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS */
0140 
0141 /* ADCx_CFG. */
0142 #if defined(FSL_FEATURE_LPADC_HAS_CFG_ADCKEN) && FSL_FEATURE_LPADC_HAS_CFG_ADCKEN
0143     if (config->enableInternalClock)
0144     {
0145         tmp32 |= ADC_CFG_ADCKEN_MASK;
0146     }
0147 #endif /* FSL_FEATURE_LPADC_HAS_CFG_ADCKEN */
0148 #if defined(FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG) && FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG
0149     if (config->enableVref1LowVoltage)
0150     {
0151         tmp32 |= ADC_CFG_VREF1RNG_MASK;
0152     }
0153 #endif /* FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG */
0154     if (config->enableAnalogPreliminary)
0155     {
0156         tmp32 |= ADC_CFG_PWREN_MASK;
0157     }
0158     tmp32 |= ADC_CFG_PUDLY(config->powerUpDelay)              /* Power up delay. */
0159              | ADC_CFG_REFSEL(config->referenceVoltageSource) /* Reference voltage. */
0160 
0161 #if !(defined(FSL_FEATURE_LPADC_HAS_CFG_PWRSEL) && (FSL_FEATURE_LPADC_HAS_CFG_PWRSEL == 0))
0162              | ADC_CFG_PWRSEL(config->powerLevelMode)           /* Power configuration. */
0163 #endif                                                          /* FSL_FEATURE_LPADC_HAS_CFG_PWRSEL */
0164              | ADC_CFG_TPRICTRL(config->triggerPriorityPolicy); /* Trigger priority policy. */
0165     base->CFG = tmp32;
0166 
0167     /* ADCx_PAUSE. */
0168     if (config->enableConvPause)
0169     {
0170         base->PAUSE = ADC_PAUSE_PAUSEEN_MASK | ADC_PAUSE_PAUSEDLY(config->convPauseDelay);
0171     }
0172     else
0173     {
0174         base->PAUSE = 0U;
0175     }
0176 
0177 #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
0178     /* ADCx_FCTRL0. */
0179     base->FCTRL[0] = ADC_FCTRL_FWMARK(config->FIFO0Watermark);
0180     /* ADCx_FCTRL1. */
0181     base->FCTRL[1] = ADC_FCTRL_FWMARK(config->FIFO1Watermark);
0182 #else
0183     /* ADCx_FCTRL. */
0184     base->FCTRL           = ADC_FCTRL_FWMARK(config->FIFOWatermark);
0185 #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
0186 
0187     /* Enable the module after setting configuration. */
0188     LPADC_Enable(base, true);
0189 }
0190 
0191 /*!
0192  * brief Gets an available pre-defined settings for initial configuration.
0193  *
0194  * This function initializes the converter configuration structure with an available settings. The default values are:
0195  * code
0196  *   config->enableInDozeMode        = true;
0197  *   config->conversionAverageMode   = kLPADC_ConversionAverage1;
0198  *   config->enableAnalogPreliminary = false;
0199  *   config->powerUpDelay            = 0x80;
0200  *   config->referenceVoltageSource  = kLPADC_ReferenceVoltageAlt1;
0201  *   config->powerLevelMode          = kLPADC_PowerLevelAlt1;
0202  *   config->triggerPriorityPolicy   = kLPADC_TriggerPriorityPreemptImmediately;
0203  *   config->enableConvPause         = false;
0204  *   config->convPauseDelay          = 0U;
0205  *   config->FIFO0Watermark          = 0U;
0206  *   config->FIFO1Watermark          = 0U;
0207  *   config->FIFOWatermark           = 0U;
0208  * endcode
0209  * param config Pointer to configuration structure.
0210  */
0211 void LPADC_GetDefaultConfig(lpadc_config_t *config)
0212 {
0213     /* Initializes the configure structure to zero. */
0214     (void)memset(config, 0, sizeof(*config));
0215 
0216 #if defined(FSL_FEATURE_LPADC_HAS_CFG_ADCKEN) && FSL_FEATURE_LPADC_HAS_CFG_ADCKEN
0217     config->enableInternalClock = false;
0218 #endif /* FSL_FEATURE_LPADC_HAS_CFG_ADCKEN */
0219 #if defined(FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG) && FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG
0220     config->enableVref1LowVoltage = false;
0221 #endif /* FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG */
0222     config->enableInDozeMode = true;
0223 #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS
0224     /* Set calibration average mode. */
0225     config->conversionAverageMode = kLPADC_ConversionAverage1;
0226 #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS */
0227     config->enableAnalogPreliminary = false;
0228     config->powerUpDelay            = 0x80;
0229     config->referenceVoltageSource  = kLPADC_ReferenceVoltageAlt1;
0230 #if !(defined(FSL_FEATURE_LPADC_HAS_CFG_PWRSEL) && (FSL_FEATURE_LPADC_HAS_CFG_PWRSEL == 0))
0231     config->powerLevelMode = kLPADC_PowerLevelAlt1;
0232 #endif /* FSL_FEATURE_LPADC_HAS_CFG_PWRSEL */
0233     config->triggerPriorityPolicy = kLPADC_TriggerPriorityPreemptImmediately;
0234     config->enableConvPause       = false;
0235     config->convPauseDelay        = 0U;
0236 #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
0237     config->FIFO0Watermark = 0U;
0238     config->FIFO1Watermark = 0U;
0239 #else
0240     config->FIFOWatermark = 0U;
0241 #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
0242 }
0243 
0244 /*!
0245  * brief De-initializes the LPADC module.
0246  *
0247  * param base LPADC peripheral base address.
0248  */
0249 void LPADC_Deinit(ADC_Type *base)
0250 {
0251     /* Disable the module. */
0252     LPADC_Enable(base, false);
0253 
0254 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0255     /* Gate the clock. */
0256     (void)CLOCK_DisableClock(s_lpadcClocks[LPADC_GetInstance(base)]);
0257 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0258 }
0259 
0260 #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
0261 /*!
0262  * brief Get the result in conversion FIFOn.
0263  *
0264  * param base LPADC peripheral base address.
0265  * param result Pointer to structure variable that keeps the conversion result in conversion FIFOn.
0266  * param index Result FIFO index.
0267  *
0268  * return Status whether FIFOn entry is valid.
0269  */
0270 bool LPADC_GetConvResult(ADC_Type *base, lpadc_conv_result_t *result, uint8_t index)
0271 {
0272     assert(result != NULL); /* Check if the input pointer is available. */
0273 
0274     uint32_t tmp32;
0275 
0276     tmp32 = base->RESFIFO[index];
0277 
0278     if (0U == (ADC_RESFIFO_VALID_MASK & tmp32))
0279     {
0280         return false; /* FIFO is empty. Discard any read from RESFIFO. */
0281     }
0282 
0283     result->commandIdSource = (tmp32 & ADC_RESFIFO_CMDSRC_MASK) >> ADC_RESFIFO_CMDSRC_SHIFT;
0284     result->loopCountIndex  = (tmp32 & ADC_RESFIFO_LOOPCNT_MASK) >> ADC_RESFIFO_LOOPCNT_SHIFT;
0285     result->triggerIdSource = (tmp32 & ADC_RESFIFO_TSRC_MASK) >> ADC_RESFIFO_TSRC_SHIFT;
0286     result->convValue       = (uint16_t)(tmp32 & ADC_RESFIFO_D_MASK);
0287 
0288     return true;
0289 }
0290 #else
0291 /*!
0292  * brief Get the result in conversion FIFO.
0293  *
0294  * param base LPADC peripheral base address.
0295  * param result Pointer to structure variable that keeps the conversion result in conversion FIFO.
0296  *
0297  * return Status whether FIFO entry is valid.
0298  */
0299 bool LPADC_GetConvResult(ADC_Type *base, lpadc_conv_result_t *result)
0300 {
0301     assert(result != NULL); /* Check if the input pointer is available. */
0302 
0303     uint32_t tmp32;
0304 
0305     tmp32 = base->RESFIFO;
0306 
0307     if (0U == (ADC_RESFIFO_VALID_MASK & tmp32))
0308     {
0309         return false; /* FIFO is empty. Discard any read from RESFIFO. */
0310     }
0311 
0312     result->commandIdSource = (tmp32 & ADC_RESFIFO_CMDSRC_MASK) >> ADC_RESFIFO_CMDSRC_SHIFT;
0313     result->loopCountIndex = (tmp32 & ADC_RESFIFO_LOOPCNT_MASK) >> ADC_RESFIFO_LOOPCNT_SHIFT;
0314     result->triggerIdSource = (tmp32 & ADC_RESFIFO_TSRC_MASK) >> ADC_RESFIFO_TSRC_SHIFT;
0315     result->convValue = (uint16_t)(tmp32 & ADC_RESFIFO_D_MASK);
0316 
0317     return true;
0318 }
0319 #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
0320 
0321 /*!
0322  * brief Configure the conversion trigger source.
0323  *
0324  * Each programmable trigger can launch the conversion command in command buffer.
0325  *
0326  * param base LPADC peripheral base address.
0327  * param triggerId ID for each trigger. Typically, the available value range is from 0.
0328  * param config Pointer to configuration structure. See to #lpadc_conv_trigger_config_t.
0329  */
0330 void LPADC_SetConvTriggerConfig(ADC_Type *base, uint32_t triggerId, const lpadc_conv_trigger_config_t *config)
0331 {
0332     assert(triggerId < ADC_TCTRL_COUNT); /* Check if the triggerId is available in this device. */
0333     assert(config != NULL);              /* Check if the input pointer is available. */
0334 
0335     uint32_t tmp32;
0336 
0337     tmp32 = ADC_TCTRL_TCMD(config->targetCommandId) /* Trigger command select. */
0338             | ADC_TCTRL_TDLY(config->delayPower)    /* Trigger delay select. */
0339             | ADC_TCTRL_TPRI(config->priority)      /* Trigger priority setting. */
0340 #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
0341             | ADC_TCTRL_FIFO_SEL_A(config->channelAFIFOSelect)
0342 #if !(defined(FSL_FEATURE_LPADC_HAS_NO_TCTRL_FIFO_SEL_B) && FSL_FEATURE_LPADC_HAS_NO_TCTRL_FIFO_SEL_B)
0343             | ADC_TCTRL_FIFO_SEL_B(config->channelBFIFOSelect)
0344 #endif /* FSL_FEATURE_LPADC_HAS_NO_TCTRL_FIFO_SEL_B  */
0345 #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
0346         ;
0347     if (config->enableHardwareTrigger)
0348     {
0349         tmp32 |= ADC_TCTRL_HTEN_MASK;
0350     }
0351 
0352     base->TCTRL[triggerId] = tmp32;
0353 }
0354 
0355 /*!
0356  * brief Gets an available pre-defined settings for trigger's configuration.
0357  *
0358  * This function initializes the trigger's configuration structure with an available settings. The default values are:
0359  * code
0360  *   config->commandIdSource       = 0U;
0361  *   config->loopCountIndex        = 0U;
0362  *   config->triggerIdSource       = 0U;
0363  *   config->enableHardwareTrigger = false;
0364  *   config->channelAFIFOSelect    = 0U;
0365  *   config->channelBFIFOSelect    = 0U;
0366  * endcode
0367  * param config Pointer to configuration structure.
0368  */
0369 void LPADC_GetDefaultConvTriggerConfig(lpadc_conv_trigger_config_t *config)
0370 {
0371     assert(config != NULL); /* Check if the input pointer is available. */
0372 
0373     /* Initializes the configure structure to zero. */
0374     (void)memset(config, 0, sizeof(*config));
0375 
0376     config->targetCommandId = 0U;
0377     config->delayPower      = 0U;
0378     config->priority        = 0U;
0379 #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
0380     config->channelAFIFOSelect = 0U;
0381     config->channelBFIFOSelect = 0U;
0382 #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
0383     config->enableHardwareTrigger = false;
0384 }
0385 
0386 /*!
0387  * brief Configure conversion command.
0388  *
0389  * param base LPADC peripheral base address.
0390  * param commandId ID for command in command buffer. Typically, the available value range is 1 - 15.
0391  * param config Pointer to configuration structure. See to #lpadc_conv_command_config_t.
0392  */
0393 void LPADC_SetConvCommandConfig(ADC_Type *base, uint32_t commandId, const lpadc_conv_command_config_t *config)
0394 {
0395     assert(commandId < (ADC_CMDL_COUNT + 1U)); /* Check if the commandId is available on this device. */
0396     assert(config != NULL);                    /* Check if the input pointer is available. */
0397 
0398     uint32_t tmp32 = 0;
0399 
0400     commandId--; /* The available command number are 1-15, while the index of register group are 0-14. */
0401 
0402     /* ADCx_CMDL. */
0403     tmp32 = ADC_CMDL_ADCH(config->channelNumber); /* Channel number. */
0404 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_ALTB_ADCH) && FSL_FEATURE_LPADC_HAS_CMDL_ALTB_ADCH
0405     tmp32 |= ADC_CMDL_ALTB_ADCH(config->channelBNumber); /* Alternate channel B number. */
0406 #endif
0407 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_CSCALE
0408     tmp32 |= ADC_CMDL_CSCALE(config->sampleScaleMode); /* Full/Part scale input voltage. */
0409 #endif                                                 /* FSL_FEATURE_LPADC_HAS_CMDL_CSCALE */
0410 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE
0411     tmp32 |= ADC_CMDL_ALTB_CSCALE(config->channelBScaleMode); /* Alternate channel B full/Part scale input voltage. */
0412 #endif                                                        /* FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE */
0413 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_CTYPE) && FSL_FEATURE_LPADC_HAS_CMDL_CTYPE
0414     tmp32 |= ADC_CMDL_CTYPE(config->sampleChannelMode);
0415 #else
0416     switch (config->sampleChannelMode) /* Sample input. */
0417     {
0418         case kLPADC_SampleChannelSingleEndSideB:
0419             tmp32 |= ADC_CMDL_ABSEL_MASK;
0420             break;
0421 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_DIFF) && FSL_FEATURE_LPADC_HAS_CMDL_DIFF
0422         case kLPADC_SampleChannelDiffBothSideAB:
0423             tmp32 |= ADC_CMDL_DIFF_MASK;
0424             break;
0425         case kLPADC_SampleChannelDiffBothSideBA:
0426             tmp32 |= ADC_CMDL_ABSEL_MASK | ADC_CMDL_DIFF_MASK;
0427             break;
0428 #endif /* FSL_FEATURE_LPADC_HAS_CMDL_DIFF */
0429         default: /* kLPADC_SampleChannelSingleEndSideA. */
0430             break;
0431     }
0432 #endif /* FSL_FEATURE_LPADC_HAS_CMDL_CTYPE */
0433 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_MODE) && FSL_FEATURE_LPADC_HAS_CMDL_MODE
0434     tmp32 |= ADC_CMDL_MODE(config->conversionResolutionMode);
0435 #endif /* FSL_FEATURE_LPADC_HAS_CMDL_MODE */
0436 
0437 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN) && FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN
0438     /* Enable alternate channel B.*/
0439     if (config->enableChannelB)
0440     {
0441         tmp32 |= ADC_CMDL_ALTBEN_MASK;
0442     }
0443 #endif /* FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN */
0444 
0445     base->CMD[commandId].CMDL = tmp32;
0446 
0447     /* ADCx_CMDH. */
0448     tmp32 = ADC_CMDH_NEXT(config->chainedNextCommandNumber) /* Next Command Select. */
0449             | ADC_CMDH_LOOP(config->loopCount)              /* Loop Count Select. */
0450             | ADC_CMDH_AVGS(config->hardwareAverageMode)    /* Hardware Average Select. */
0451             | ADC_CMDH_STS(config->sampleTimeMode)          /* Sample Time Select. */
0452             | ADC_CMDH_CMPEN(config->hardwareCompareMode);  /* Hardware compare enable. */
0453 #if (defined(FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG) && FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG)
0454     if (config->enableWaitTrigger)
0455     {
0456         tmp32 |= ADC_CMDH_WAIT_TRIG_MASK; /* Wait trigger enable. */
0457     }
0458 #endif /* FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG */
0459 
0460     if (config->enableAutoChannelIncrement)
0461     {
0462         tmp32 |= ADC_CMDH_LWI_MASK;
0463     }
0464     base->CMD[commandId].CMDH = tmp32;
0465 
0466     /* Hardware compare settings.
0467      * Not all Command Buffers have an associated Compare Value register. The compare function is only available on
0468      * Command Buffers that have a corresponding Compare Value register.
0469      */
0470     if (kLPADC_HardwareCompareDisabled != config->hardwareCompareMode)
0471     {
0472         /* Check if the hardware compare feature is available for indicated command buffer. */
0473         assert(commandId < ADC_CV_COUNT);
0474 
0475         /* Set CV register. */
0476         base->CV[commandId] = ADC_CV_CVH(config->hardwareCompareValueHigh)   /* Compare value high. */
0477                               | ADC_CV_CVL(config->hardwareCompareValueLow); /* Compare value low. */
0478     }
0479 }
0480 
0481 /*!
0482  * brief Gets an available pre-defined settings for conversion command's configuration.
0483  *
0484  * This function initializes the conversion command's configuration structure with an available settings. The default
0485  * values are:
0486  * code
0487  *   config->sampleScaleMode            = kLPADC_SampleFullScale;
0488  *   config->channelBScaleMode          = kLPADC_SampleFullScale;
0489  *   config->channelSampleMode          = kLPADC_SampleChannelSingleEndSideA;
0490  *   config->channelNumber              = 0U;
0491  *   config ->alternateChannelNumber    = 0U;
0492  *   config->chainedNextCmdNumber       = 0U;
0493  *   config->enableAutoChannelIncrement = false;
0494  *   config->loopCount                  = 0U;
0495  *   config->hardwareAverageMode        = kLPADC_HardwareAverageCount1;
0496  *   config->sampleTimeMode             = kLPADC_SampleTimeADCK3;
0497  *   config->hardwareCompareMode        = kLPADC_HardwareCompareDisabled;
0498  *   config->hardwareCompareValueHigh   = 0U;
0499  *   config->hardwareCompareValueLow    = 0U;
0500  *   config->conversionResolutionMode   = kLPADC_ConversionResolutionStandard;
0501  *   config->enableWaitTrigger          = false;
0502  *   config->enableChannelB             = false;
0503  * endcode
0504  * param config Pointer to configuration structure.
0505  */
0506 void LPADC_GetDefaultConvCommandConfig(lpadc_conv_command_config_t *config)
0507 {
0508     assert(config != NULL); /* Check if the input pointer is available. */
0509 
0510     /* Initializes the configure structure to zero. */
0511     (void)memset(config, 0, sizeof(*config));
0512 
0513 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_CSCALE
0514     config->sampleScaleMode = kLPADC_SampleFullScale;
0515 #endif /* FSL_FEATURE_LPADC_HAS_CMDL_CSCALE */
0516 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE
0517     config->channelBScaleMode = kLPADC_SampleFullScale;
0518 #endif /* FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE */
0519     config->sampleChannelMode = kLPADC_SampleChannelSingleEndSideA;
0520     config->channelNumber     = 0U;
0521 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_ALTB_ADCH) && FSL_FEATURE_LPADC_HAS_CMDL_ALTB_ADCH
0522     config->channelBNumber = 0U;
0523 #endif                                       /* FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE */
0524     config->chainedNextCommandNumber   = 0U; /* No next command defined. */
0525     config->enableAutoChannelIncrement = false;
0526     config->loopCount                  = 0U;
0527     config->hardwareAverageMode        = kLPADC_HardwareAverageCount1;
0528     config->sampleTimeMode             = kLPADC_SampleTimeADCK3;
0529     config->hardwareCompareMode        = kLPADC_HardwareCompareDisabled;
0530     config->hardwareCompareValueHigh   = 0U; /* No used. */
0531     config->hardwareCompareValueLow    = 0U; /* No used. */
0532 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_MODE) && FSL_FEATURE_LPADC_HAS_CMDL_MODE
0533     config->conversionResolutionMode = kLPADC_ConversionResolutionStandard;
0534 #endif /* FSL_FEATURE_LPADC_HAS_CMDL_MODE */
0535 #if defined(FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG) && FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG
0536     config->enableWaitTrigger = false;
0537 #endif /* FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG */
0538 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN) && FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN
0539     config->enableChannelB = false; /* Enable alternate channel B.*/
0540 #endif                              /* FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN */
0541 }
0542 
0543 #if defined(FSL_FEATURE_LPADC_HAS_CFG_CALOFS) && FSL_FEATURE_LPADC_HAS_CFG_CALOFS
0544 /*!
0545  * brief Enable the calibration function.
0546  *
0547  * When CALOFS is set, the ADC is configured to perform a calibration function anytime the ADC executes
0548  * a conversion. Any channel selected is ignored and the value returned in the RESFIFO is a signed value
0549  * between -31 and 31. -32 is not a valid and is never a returned value. Software should copy the lower 6-
0550  * bits of the conversion result stored in the RESFIFO after a completed calibration conversion to the
0551  * OFSTRIM field. The OFSTRIM field is used in normal operation for offset correction.
0552  *
0553  * param base LPADC peripheral base address.
0554  * param enable switcher to the calibration function.
0555  */
0556 void LPADC_EnableCalibration(ADC_Type *base, bool enable)
0557 {
0558     LPADC_Enable(base, false);
0559     if (enable)
0560     {
0561         base->CFG |= ADC_CFG_CALOFS_MASK;
0562     }
0563     else
0564     {
0565         base->CFG &= ~ADC_CFG_CALOFS_MASK;
0566     }
0567     LPADC_Enable(base, true);
0568 }
0569 
0570 #if defined(FSL_FEATURE_LPADC_HAS_OFSTRIM) && FSL_FEATURE_LPADC_HAS_OFSTRIM
0571 /*!
0572  * brief Do auto calibration.
0573  *
0574  * Calibration function should be executed before using converter in application. It used the software trigger and a
0575  * dummy conversion, get the offset and write them into the OFSTRIM register. It called some of functional API
0576  * including: -LPADC_EnableCalibration(...) -LPADC_LPADC_SetOffsetValue(...) -LPADC_SetConvCommandConfig(...)
0577  *   -LPADC_SetConvTriggerConfig(...)
0578  *
0579  * param base  LPADC peripheral base address.
0580  */
0581 void LPADC_DoAutoCalibration(ADC_Type *base)
0582 {
0583     assert(0u == LPADC_GetConvResultCount(base));
0584 
0585     uint32_t mLpadcCMDL;
0586     uint32_t mLpadcCMDH;
0587     uint32_t mLpadcTrigger;
0588     lpadc_conv_trigger_config_t mLpadcTriggerConfigStruct;
0589     lpadc_conv_command_config_t mLpadcCommandConfigStruct;
0590     lpadc_conv_result_t mLpadcResultConfigStruct;
0591 
0592     /* Enable the calibration function. */
0593     LPADC_EnableCalibration(base, true);
0594 
0595     /* Keep the CMD and TRG state here and restore it later if the calibration completes.*/
0596     mLpadcCMDL    = base->CMD[0].CMDL; /* CMD1L. */
0597     mLpadcCMDH    = base->CMD[0].CMDH; /* CMD1H. */
0598     mLpadcTrigger = base->TCTRL[0];    /* Trigger0. */
0599 
0600     /* Set trigger0 configuration - for software trigger. */
0601     LPADC_GetDefaultConvTriggerConfig(&mLpadcTriggerConfigStruct);
0602     mLpadcTriggerConfigStruct.targetCommandId = 1U;                   /* CMD1 is executed. */
0603     LPADC_SetConvTriggerConfig(base, 0U, &mLpadcTriggerConfigStruct); /* Configurate the trigger0. */
0604 
0605     /* Set conversion CMD configuration. */
0606     LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct);
0607     mLpadcCommandConfigStruct.hardwareAverageMode = kLPADC_HardwareAverageCount128;
0608     LPADC_SetConvCommandConfig(base, 1U, &mLpadcCommandConfigStruct); /* Set CMD1 configuration. */
0609 
0610     /* Do calibration. */
0611     LPADC_DoSoftwareTrigger(base, 1U); /* 1U is trigger0 mask. */
0612     while (!LPADC_GetConvResult(base, &mLpadcResultConfigStruct))
0613     {
0614     }
0615     /* The valid bits of data are bits 14:3 in the RESFIFO register. */
0616     LPADC_SetOffsetValue(base, (uint32_t)(mLpadcResultConfigStruct.convValue) >> 3UL);
0617     /* Disable the calibration function. */
0618     LPADC_EnableCalibration(base, false);
0619 
0620     /* restore CMD and TRG registers. */
0621     base->CMD[0].CMDL = mLpadcCMDL;    /* CMD1L. */
0622     base->CMD[0].CMDH = mLpadcCMDH;    /* CMD1H. */
0623     base->TCTRL[0]    = mLpadcTrigger; /* Trigger0. */
0624 }
0625 #endif /* FSL_FEATURE_LPADC_HAS_OFSTRIM */
0626 #endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */
0627 
0628 #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFS
0629 /*!
0630  * brief Do offset calibration.
0631  *
0632  * param base LPADC peripheral base address.
0633  */
0634 void LPADC_DoOffsetCalibration(ADC_Type *base)
0635 {
0636     LPADC_EnableOffsetCalibration(base, true);
0637     while (ADC_STAT_CAL_RDY_MASK != (base->STAT & ADC_STAT_CAL_RDY_MASK))
0638     {
0639     }
0640 }
0641 
0642 #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ
0643 /*!
0644  * brief Do auto calibration.
0645  *
0646  * param base  LPADC peripheral base address.
0647  */
0648 void LPADC_DoAutoCalibration(ADC_Type *base)
0649 {
0650     assert((0u == LPADC_GetConvResultCount(base, 0)) && (0u == LPADC_GetConvResultCount(base, 1)));
0651 
0652 #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE
0653     int32_t GCCa;
0654     int32_t GCCb;
0655     float GCRa;
0656     float GCRb;
0657 #else
0658     uint32_t GCCa;
0659     uint32_t GCCb;
0660     uint32_t GCRa;
0661     uint32_t GCRb;
0662 #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE */
0663 
0664     /* Request gain calibration. */
0665     base->CTRL |= ADC_CTRL_CAL_REQ_MASK;
0666     while ((ADC_GCC_RDY_MASK != (base->GCC[0] & ADC_GCC_RDY_MASK)) ||
0667            (ADC_GCC_RDY_MASK != (base->GCC[1] & ADC_GCC_RDY_MASK)))
0668     {
0669     }
0670 
0671     /* Calculate gain offset. */
0672     GCCa = (base->GCC[0] & ADC_GCC_GAIN_CAL_MASK);
0673     GCCb = (base->GCC[1] & ADC_GCC_GAIN_CAL_MASK);
0674 
0675 #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE
0676     if (((base->GCC[0]) & 0x8000U))
0677     {
0678         GCCa = GCCa - 0x10000;
0679         GCRa =
0680             (float)((131072.0) / (0x20000 - GCCa)); /* Gain_CalA = (131072.0 / (131072-(ADC_GCC_GAIN_CAL(ADC->GCC[0]))*/
0681         base->GCR[0] = LPADC_GetGainConvResult(GCRa); /* write A side GCALR. */
0682     }
0683 
0684     if (((base->GCC[1]) & 0x8000U))
0685     {
0686         GCCb = GCCb - 0x10000;
0687         GCRb =
0688             (float)((131072.0) / (0x20000 - GCCb)); /* Gain_CalB = (131072.0 / (131072-(ADC_GCC_GAIN_CAL(ADC->GCC[1]))*/
0689         base->GCR[1] = LPADC_GetGainConvResult(GCRb); /* write B side GCALR. */
0690     }
0691 #else
0692     GCRa         = (uint16_t)((GCCa << 16U) /
0693                       (0x1FFFFU - GCCa)); /* Gain_CalA = (131072 / (131072-(ADC_GCC_GAIN_CAL(ADC0->GCC[0])) - 1. */
0694     GCRb         = (uint16_t)((GCCb << 16U) /
0695                       (0x1FFFFU - GCCb)); /* Gain_CalB = (131072 / (131072-(ADC_GCC_GAIN_CAL(ADC0->GCC[1])) - 1. */
0696     base->GCR[0] = ADC_GCR_GCALR(GCRa);
0697     base->GCR[1] = ADC_GCR_GCALR(GCRb);
0698 #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE */
0699     /* Indicate the values are valid. */
0700     base->GCR[0] |= ADC_GCR_RDY_MASK;
0701     base->GCR[1] |= ADC_GCR_RDY_MASK;
0702 
0703     while (ADC_STAT_CAL_RDY_MASK != (base->STAT & ADC_STAT_CAL_RDY_MASK))
0704     {
0705     }
0706 }
0707 #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ */
0708 #endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */