mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/adc/fsl_adc_hal.h

Committer:
mbed_official
Date:
2014-04-03
Revision:
149:1fb5f62b92bd
Parent:
targets/hal/TARGET_Freescale/TARGET_KSDK_MCUS/TARGET_KSDK_CODE/hal/adc/fsl_adc_hal.h@ 146:f64d43ff0c18
Child:
324:406fd2029f23

File content as of revision 149:1fb5f62b92bd:

/*
 * Copyright (c) 2013 - 2014, 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.
 */

#ifndef __FSL_ADC_HAL_H__
#define __FSL_ADC_HAL_H__

#include <assert.h>
#include <stdint.h>
#include <stdbool.h>
#include "fsl_adc_features.h"
#include "fsl_device_registers.h"

/*!
 * @addtogroup adc_hal
 * @{
 */

/*! @file*/

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*! @brief Defines the selection of the clock source that ADC module uses.*/
typedef enum _adc_clock_source_mode
{
    kAdcClockSourceBusClk        = 0U,  /*!< Use bus clock.*/
    kAdcClockSourceBusClk2       = 1U,  /*!< Use bus clock / 2.*/
    kAdcClockSourceAlternate     = 2U,  /*!< Use the optional external clock.*/
    kAdcClockSourceAsynchrounous = 3U,  /*!< Use ADC's internal asynchronous clock. */
} adc_clock_source_mode_t;

/*! @brief Defines the selection of the clock divider.*/
typedef enum _adc_clock_divider_mode
{
    kAdcClockDivider1 = 0U,   /*!< Divide 1.*/
    kAdcClockDivider2 = 1U,   /*!< Divide 2.*/
    kAdcClockDivider4 = 2U,   /*!< Divide 4.*/
    kAdcClockDivider8 = 3U,   /*!< Divide 8.*/
} adc_clock_divider_mode_t;

/*! @brief Defines the selection of the voltage source that ADC module uses.*/
typedef enum _adc_reference_voltage_mode
{
    kAdcVoltageVref = 0U,   /*!< Use V_REFH & V_REFL as ref source pin.*/
    kAdcVoltageValt = 1U,   /*!< Use V_ALTH & V_REFL as ref source pin.*/
} adc_reference_voltage_mode_t;

/*! @brief Defines the selection of the long sample extra cycle configuration.*/
typedef enum _adc_long_sample_mode
{
    kAdcLongSampleExtra20 = 0U,  /*!< Extra 20 cycles, total 24 cycles, default.*/
    kAdcLongSampleExtra12 = 1U,  /*!< Extra 12 cycles.*/
    kAdcLongSampleExtra6  = 2U,  /*!< Extra  6 cycles.*/
    kAdcLongSampleExtra2  = 3U,  /*!< Extra  2 cycles.*/
} adc_long_sample_mode_t;

/*! @brief Defines the selection of the sample resolution.*/
typedef enum _adc_resolution_mode
{
    kAdcSingleDiff8or9   = 0U, /*!<  8-bits in single-end or  9-bits in differential.*/
    kAdcSingleDiff12or13 = 1U, /*!< 12-bits in single-end or 13-bits in differential.*/
    kAdcSingleDiff10or11 = 2U, /*!< 10-bits in single-end or 11-bits in differential.*/
    kAdcSingleDiff16     = 3U, /*!< 16-bits both in single-end and differential.*/
} adc_resolution_mode_t;

/*! @brief Defines the selection of the A/B group mux.*/
typedef enum _adc_group_mux_mode
{
    kAdcChannelMuxA = 0U, /*!< Mux A group is active.*/
    kAdcChannelMuxB = 1U, /*!< Mux B group is active.*/
} adc_group_mux_mode_t;

/*! @brief Defines the selection of the time in a hard average mode.*/
typedef enum _adc_hw_average_mode
{
    kAdcHwAverageCount4  = 0U, /*!<  Average the result after accumulating  4 conversion.*/
    kAdcHwAverageCount8  = 1U, /*!<  Average the result after accumulating  8 conversion.*/
    kAdcHwAverageCount16 = 2U, /*!<  Average the result after accumulating 16 conversion.*/
    kAdcHwAverageCount32 = 3U, /*!<  Average the result after accumulating 32 conversion.*/
} adc_hw_average_mode_t;

/*! @brief Defines the selection of the channel inside the ADC module.*/
typedef enum _adc_channel_mode
{
    kAdcChannel0  = 0U,    /*!< ADC channel 0.*/
    kAdcChannell  = 1U,    /*!< ADC channel 1.*/
    kAdcChannel2  = 2U,    /*!< ADC channel 2.*/
    kAdcChannel3  = 3U,    /*!< ADC channel 3.*/
    kAdcChannel4  = 4U,    /*!< ADC channel 4.*/
    kAdcChannel5  = 5U,    /*!< ADC channel 5.*/
    kAdcChannel6  = 6U,    /*!< ADC channel 6.*/
    kAdcChannel7  = 7U,    /*!< ADC channel 7.*/
    kAdcChannel8  = 8U,    /*!< ADC channel 8.*/
    kAdcChannel9  = 9U,    /*!< ADC channel 9.*/
    kAdcChannel10 = 10U,   /*!< ADC channel 10.*/
    kAdcChannel11 = 11U,   /*!< ADC channel 11.*/
    kAdcChannel12 = 12U,   /*!< ADC channel 12.*/
    kAdcChannel13 = 13U,   /*!< ADC channel 13.*/
    kAdcChannel14 = 14U,   /*!< ADC channel 14.*/
    kAdcChannel15 = 15U,   /*!< ADC channel 15.*/
    kAdcChannel16 = 16U,   /*!< ADC channel 16.*/
    kAdcChannel17 = 17U,   /*!< ADC channel 17.*/
    kAdcChannel18 = 18U,   /*!< ADC channel 18.*/
    kAdcChannel19 = 19U,   /*!< ADC channel 19.*/
    kAdcChannel20 = 20U,   /*!< ADC channel 20.*/
    kAdcChannel21 = 21U,   /*!< ADC channel 21.*/
    kAdcChannel22 = 22U,   /*!< ADC channel 22.*/
    kAdcChannel23 = 23U,   /*!< ADC channel 23.*/
    kAdcChannelTemperature          = 26U,  /*!< Internal temperature sensor.*/
    kAdcChannelBandgap              = 27U,  /*!< Internal band gap.*/
    kAdcChannelReferenceVoltageHigh = 29U,  /*!< Internal ref voltage High.*/
    kAdcChannelReferenceVoltageLow  = 30U,  /*!< Internal ref voltage L.*/
    kAdcChannelDisable              = 31U   /*!< Disable the sample process.*/
} adc_channel_mode_t;

/*! @brief Defines the status returned from the ADC API.*/
typedef enum _adc_status
{
    kStatus_ADC_Success = 0U,
    kStatus_ADC_InvalidArgument = 1U,/*!< Parameter is not available for the current configuration.*/
    kStatus_ADC_Failed = 2U /*!< Function operation failed. */
} adc_status_t;

#if FSL_FEATURE_ADC_HAS_PGA
/*! @brief Defines the selection of the Programmable Gain Amplifier mode.*/
typedef enum _adc_pga_mode
{
    kAdcPga1  = 0U, /*!< Gain is 1*/
    kAdcPga2  = 1U, /*!< Gain is 2*/
    kAdcPga4  = 2U, /*!< Gain is 4*/
    kAdcPga8  = 3U, /*!< Gain is 8*/
    kAdcPga16 = 4U, /*!< Gain is 16*/
    kAdcPga32 = 5U, /*!< Gain is 32*/
    kAdcPga64 = 6U  /*!< Gain is 64*/
} adc_pga_mode_t;
#endif /* FSL_FEATURE_ADC_HAS_PGA */

/*******************************************************************************
 * API
 ******************************************************************************/

#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @brief Starts the calibration process.
 *
 * This function clears the calibration flag bit and sets the enable bit 
 * to start the calibration.
 *
 * @param instance ADC instance ID.
 */
adc_status_t adc_hal_start_calibration(uint32_t instance);

/*!
 * @brief Ends the calibration process.
 *
 * This function clears the calibration enable bit to end the calibration.
 *
 * @param instance ADC instance ID.
 */
static inline void adc_hal_end_calibration(uint32_t instance)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_SC3_CAL(instance, 0U);
}

/*!
 * @brief Gets and calculates the plus-side calibration parameter.
 * 
 * This function  gets the CLP0 - CLP4 and CLPS, accumulates them, and 
 * returns the value that can be set to the PG directly. 
 *
 * @param instance ADC instance ID.
 * @return the value that can be set to PG directly.
 */
uint32_t adc_hal_get_calibration_PG(uint32_t instance);

/*!
 * @brief Sets the plus-side calibration parameter to the ADC instance.
 * 
 * This function sets the PG register directly.
 *
 * @param instance ADC instance ID.
 * @param val the value that can be set to PG directly.
 */
static inline void adc_hal_set_calibration_PG(uint32_t instance, uint32_t val)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    HW_ADC_PG_WR(instance, val); 
}

/*!
 * @brief Gets and calculates the minus-side calibration parameter.
 * 
 * This function gets the CLM0 - CLM4 and CLMS, accumulates them, and 
 * returns the value that can be set to the MG directly. 
 *
 * @param instance ADC instance ID.
 * @return the value that can be set to MG directly.
 */
uint32_t adc_hal_get_calibration_MG(uint32_t instance);

/*!
 * @brief Sets the minus-side calibration parameter to the ADC instance.
 * 
 * This function sets the MG register directly.
 *
 * @param instance ADC instance ID.
 * @param val the value that can be set to MG directly.
 */
static inline void adc_hal_set_calibration_MG(uint32_t instance, uint32_t val)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    HW_ADC_MG_WR(instance, val);
}

/*!
 * @brief Gets the offset value after the auto-calibration.
 *
 * If the user wants to adjust the offset value according to the application, 
 * the origin offset value will be a reference. 
 *
 * @param instance ADC instance ID.
 * @return The offset value created by auto-calibration.
 */
static inline uint32_t adc_hal_get_calibration_offset(uint32_t instance)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    return BR_ADC_OFS_OFS(instance);
}

/*!
 * @brief Sets the offset value for manual calibration.
 * 
 * This function is to set the user selected or calibration generated offset
 * error correction value. The value set here is subtracted from the conversion
 * and the result is transferred into the result registers (Rn). If the result
 * is above the maximum or below the minimum result value, it is forced to the
 * appropriate limit for the current mode of operation.
 *
 * @param instance ADC instance ID.
 * @param value The manual offset value.
 */
static inline void adc_hal_set_calibration_offset(uint32_t instance, 
        uint32_t value)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_OFS_OFS(instance, value);
}

/*!
 * @brief Sets the selection of the clock source.
 *
 * The selection of ADC clock source can see to the type definition of 
 * adc_clock_source_mode_t. 
 * This function selects the input clock source to generate the internal 
 * clock, ADCK. Note that when the ADACK clock source is selected, it does not
 * have to be activated prior to the start of the conversion. When it is
 * selected and it is not activated prior to start a conversion , the
 * asynchronous clock will be activated at the start of a conversion and shuts
 * off when conversions are terminated. In this case, there is an associated
 * clock startup delay each time the clock source is re-activated.
 *
 * @param instance ADC instance ID.
 * @param mode The indicated clock source mode.
 */
static inline void adc_hal_set_clock_source_mode(uint32_t instance, 
        adc_clock_source_mode_t mode)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_CFG1_ADICLK(instance, (uint32_t)(mode));
}

/*!
 * @brief Switches the asynchronous clock on/off.
 *
 * When enables the ADC's asynchronous clock source and the clock source output 
 * regardless of the conversion and input clock select status of the ADC. Based 
 * on MCU configuration, the asynchronous clock may be used by other modules. 
 * Setting this mode allows the clock to be used even while the ADC is idle or 
 * operating from a different clock source. Also, latency of initiating a single
 * or first-continuous conversion with the asynchronous clock selected is
 * reduced since the ADACK clock is already operational.
 * 
 * @param instance ADC instance ID.
 * @param isEnabled The switcher.
 */
static inline void adc_hal_configure_asynchronous_clock(uint32_t instance, 
        bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_CFG2_ADACKEN(instance, (isEnabled ? 1U : 0U));
}

/*!
 * @brief Sets the selection of the clock divider.
 *
 * The selection of ADC's clock divider can see to the type definition of the
 * adc_clock_divider_mode_t.
 * This function selects the divide ratio used by the ADC to generate the 
 * internal clock ADCK.
 *
 * @param instance ADC instance ID.
 * @param mode The selection of the divider.
 */
static inline void adc_hal_set_clock_divider_mode(uint32_t instance, 
        adc_clock_divider_mode_t mode)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_CFG1_ADIV(instance, (uint32_t)(mode));
}

/*!
 * @brief Sets the selection of the reference voltage source.
 *
 * The selection of ADC's reference voltage can see to the type definition of 
 * adc_reference_voltage_mode_t.
 * This function  selects the voltage reference source used for conversions.
 * 
 * @param instance ADC instance ID.
 * @param mode The selection of the reference voltage source.
 */
static inline void adc_hal_set_reference_voltage_mode(uint32_t instance, 
        adc_reference_voltage_mode_t mode)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_SC2_REFSEL(instance, (uint32_t)(mode));
}

/*!
 * @brief Switches the high speed mode on/off .
 *
 * This function configures the ADC for  high speed operations. The 
 * conversion sequence is altered (2 ADCK cycles added to the conversion time) 
 * to allow higher speed conversion clocks.
 *
 * @param instance ADC instance ID.
 * @param isEnabled The switcher.
 */
static inline void adc_hal_configure_high_speed(uint32_t instance, 
        bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_CFG2_ADHSC(instance, (isEnabled ? 1U : 0U)); 
}

/*!
 * @brief Switch the long sample mode on/off.
 *
 * This function selects between the different sample times based on the 
 * conversion mode selected. It adjusts the sample period to allow 
 * higher impedance inputs to be accurately sampled or to maximize conversion
 * speed for lower impedance inputs. Longer sample times can also be used to 
 * lower overall power consumption if the continuous conversions are enabled and the
 * high conversion rates are not required. In fact this will be able to charge
 * the SAR in a timely manner way without affecting the SAR configuration.
 *
 * @param instance ADC instance ID.
 * @param isEnabled The switcher.
 */
static inline void adc_hal_configure_long_sample(uint32_t instance, 
        bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_CFG1_ADLSMP(instance, (isEnabled ? 1U : 0U));
}

/*!
 * @brief Sets the selection of the long sample mode.
 *
 * The selection of ADC long sample mode can see to the type definition of the
 * adc_long_sample_mode_t.
 * This function selects the long sample mode that indicating the different
 * count of extra ADCK cycles are needed.
 * 
 * @param instance ADC instance ID.
 * @param mode The selection of long sample mode.
 */
static inline void adc_hal_set_long_sample_mode(uint32_t instance, 
        adc_long_sample_mode_t mode)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_CFG2_ADLSTS(instance, (uint32_t)(mode));
}

/*!
 * @brief Switches  the low power mode on/off.
 *
 * This function controls the power configuration of the successive approximation
 * converter. This optimizes power consumption when higher sample rates are not 
 * required.
 * 
 * @param instance ADC instance ID.
 * @param isEnabled The switcher.
 */
static inline void adc_hal_configure_low_power(uint32_t instance, bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_CFG1_ADLPC(instance, (isEnabled ? 1U : 0U));
}

/*!
 * @brief Sets the selection of the resolution mode.
 *
 * The selection of ADC resolution mode can see to the type definition of the
 * adc_resolution_mode_t.
 * This function selects the ADC resolution mode. Note that the 
 * differential conversion is different to single-end conversion.
 * 
 * @param instance ADC instance ID.
 * @param mode The selection of resolution mode.
 */
static inline void adc_hal_set_resolution_mode(uint32_t instance, 
        adc_resolution_mode_t mode)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_CFG1_MODE(instance, (uint32_t)(mode));
}

/*!
 * @brief Switches the continuous conversion mode on/off.
 *
 * This function configures the continuous conversions or sets of conversions if 
 * the hardware average function is enabled after initiating a conversion.
 * 
 * @param instance ADC instance ID.
 * @param isEnabled The switcher.
 */
static inline void adc_hal_configure_continuous_conversion(uint32_t instance,
        bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_SC3_ADCO(instance, (isEnabled ? 1U : 0U));
}

/*!
 * @brief Switches the hardware trigger mode on/off .
 *
 * This function selects the type of trigger used for initiating a conversion. 
 * Two types of triggers can be selected: software trigger and hardware trigger. 
 * When software trigger is selected, a conversion is initiated following a 
 * write to SC1A. When hardware trigger is selected, a conversion is initiated 
 * following the assertion of the external events. The event will come through
 * the signal on the line of ADHWT input after a pulse of ADHWTSn input inside SOC.
 * 
 * @param instance ADC instance ID.
 * @param isEnabled The switcher.
 */
static inline void adc_hal_configure_hw_trigger(uint32_t instance, bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_SC2_ADTRG(instance, (isEnabled ? 1U : 0U));
}

/*!
 * @brief Switches the hardware average mode on/off.
 *
 * This function  enables the hardware average function of the ADC.
 * 
 * @param instance ADC instance ID.
 * @param isEnabled The switcher.
 */
static inline void adc_hal_configure_hw_average(uint32_t instance, bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_SC3_AVGE(instance, (isEnabled ? 1U : 0U));
}

/*!
 * @brief Sets the selection of the hardware average mode.
 *
 * The selection of ADC hardware average mode can see to the type definition 
 * of the adc_hw_average_mode_t.
 * This function determines how many ADC conversions are averaged to create 
 * the ADC average result.
 *
 * @param instance ADC instance ID.
 * @param mode The selection of hardware average mode.
 */
static inline void adc_hal_set_hw_average_mode(uint32_t instance, 
        adc_hw_average_mode_t mode)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_SC3_AVGS(instance, (uint32_t)(mode));
}

/*!
 * @brief Switches  the hardware compare mode on/off.
 *
 * This function  enables the compare function.
 *
 * @param instance ADC instance ID.
 * @param isEnabled The switcher.
 */
static inline void adc_hal_configure_hw_compare(uint32_t instance, bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_SC2_ACFE(instance, (isEnabled ? 1U : 0U));
}

/*!
 * @brief Switches the hardware compare greater configuration on/off .
 *
 * This function configures the compare function to check the conversion 
 * result relative to the compare value register(s) (CV1 and CV2). To enable
 * will configure greater than or equal to threshold, outside range inclusive
 * and inside range inclusive functionality based on the values placed in the
 * CV1 and CV2 registers. Otherwise, it will configure less than threshold,
 * outside range not inclusive and inside range not inclusive functionality
 * based on the values placed in the CV1 and CV2 registers.
 * 
 *
 * @param instance ADC instance ID.
 * @param isEnabled The switcher.
 */
static inline void adc_hal_configure_hw_compare_greater(uint32_t instance, 
        bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_SC2_ACFGT(instance, (isEnabled ? 1U : 0U));
}

/*!
 * @brief Switches the hardware compare range configuration on/off .
 *
 * This function configures the compare function to check if the conversion
 * result of the input being monitored is either inside or outside the range 
 * formed by the compare value registers (CV1 and CV2). However, the actual
 * compare range should be determined alone with the function of
 * adc_hal_configure_hw_compare_greater() as well.
 * 
 * @param instance ADC instance ID.
 * @param isEnabled The switcher.
 */
static inline void adc_hal_configure_hw_compare_in_range(uint32_t instance, 
        bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_SC2_ACREN(instance, (isEnabled ? 1U : 0U));
}

/*!
 * @brief Sets the value1 in the hardware compare.
 *
 * This function  sets the value of the CV1 register.
 *
 * @param instance ADC instance ID.
 * @param value The setting value.
 */
static inline void adc_hal_set_hw_compare_value1(uint32_t instance, uint32_t value)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_CV1_CV(instance, value);
}

/*!
 * @brief Sets the value2 in the hardware compare.
 *
 * This function  sets the value of the CV2 register.
 *
 * @param instance ADC instance ID.
 * @param value The setting value.
 */
static inline void adc_hal_set_hw_compare_value2(uint32_t instance, uint32_t value)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_CV2_CV(instance, value);
}

/*!
 * @brief Switches  the ADC DMA trigger on/off.
 *
 * When DMA is enabled, it asserts the ADC DMA request during the ADC 
 * conversion complete event noted by the assertion of any of the ADC COCO flags.
 * 
 * @param instance ADC instance ID.
 * @param isEnabled The switcher.
 */
static inline void adc_hal_configure_dma(uint32_t instance, bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_SC2_DMAEN(instance, (isEnabled ? 1U : 0U));
}

/*!
 * @brief Switches off the ADC channel conversion.
 *
 * Here the "NUll" channel is set to the conversion channel.
 *
 * @param instance ADC instance ID.
 * @param group The group mux index.
 */
static inline void adc_hal_disable(uint32_t instance, uint32_t group)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    assert(group < HW_ADC_SC1n_COUNT);
    BW_ADC_SC1n_ADCH(instance, group, (uint32_t)(kAdcChannelDisable));
}

/*!
 * @brief Sets the channel number and switches on the conversion.
 *
 * When the available channel is set, the conversion begins to execute.
 * 
 * @param instance ADC instance ID.
 * @param group The group mux index.
 * @param mode The selection of channel number.
 * @param isDifferential the selection of differential input.
 */
static inline void adc_hal_enable(uint32_t instance, uint32_t group, 
        adc_channel_mode_t mode, bool isDifferential)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    assert(group < HW_ADC_SC1n_COUNT);
    BW_ADC_SC1n_DIFF(instance, group, (isDifferential ? 1U : 0U));
    /* Set new channel will restart the conversion. */
    BW_ADC_SC1n_ADCH(instance, group, (uint32_t)(mode));    
}

/*!
 * @brief Switches the ADC interrupt trigger on/off .
 *
 * This function  enables conversion complete interrupts. When COCO is 
 * set while the respective AIEN is high, an interrupt is asserted.
 *
 * @param instance ADC instance ID.
 * @param group The group mux index.
 * @param inEnable The switcher.
 */
static inline void adc_hal_configure_interrupt(uint32_t instance, uint32_t group, 
        bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    assert(group < HW_ADC_SC1n_COUNT);
    BW_ADC_SC1n_AIEN(instance, group, (isEnabled ? 1U : 0U));
}

/*!
 * @brief Checks whether the ADC is in process.
 *
 * This function  indicates that a conversion or hardware averaging is in 
 * progress. ADACT is set when a conversion is initiated and cleared when a 
 * conversion is completed or aborted. Note that if the continuous conversion
 * is been use, this function will always return true.
 * 
 * @param instance ADC instance ID.
 * @return true if it is.
 */
static inline bool adc_hal_is_in_process(uint32_t instance)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    return BR_ADC_SC2_ADACT(instance);
}

/*!
 * @brief Checks whether the channel conversion is complete.
 *
 * This function  indicates whether each conversion is completed.
 * 
 * @param instance ADC instance ID.
 * @param group The grout mux index.
 * @return true if it is.
 */
static inline bool adc_hal_is_conversion_completed(uint32_t instance, uint32_t group)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    assert(group < HW_ADC_SC1n_COUNT);
    return BR_ADC_SC1n_COCO(instance, group);
}

/*!
 * @brief Checks whether the calibration  failed.
 *
 * This function displays the result of the calibration sequence.
 * 
 * @param instance ADC instance ID.
 * @return true if it is.
 */
static inline bool adc_hal_is_calibration_fail(uint32_t instance)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    return BR_ADC_SC3_CALF(instance);
}

/*!
 * @brief Gets the conversion value.
 *
 * This function returns the conversion value kept in the Rn Register. Unused bits 
 * in the Rn register are cleared in unsigned right justified modes and carry 
 * the sign bit (MSB) in sign extended 2's complement modes.
 * 
 * @param instance ADC instance ID.
 * @param group The group mux index.
 */
static inline uint32_t adc_hal_get_conversion_value(uint32_t instance, 
        uint32_t group)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    assert(group < HW_ADC_SC1n_COUNT);
    return BR_ADC_Rn_D(instance, group);
}

/*!
 * @brief Sets the current group mux that executes the conversion.
 *
 * ADC Mux select bit changes the ADC group setting to select between 
 * alternate sets of ADC channels. It will activate group A or group B.
 * 
 * @param instance ADC instance ID.
 * @param group The group mux index.
 */
static inline void adc_hal_set_group_mux(uint32_t instance, adc_group_mux_mode_t group)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    assert(group < HW_ADC_SC1n_COUNT);
    BW_ADC_CFG2_MUXSEL(instance, (uint32_t)group);
}

#if FSL_FEATURE_ADC_HAS_PGA
/*!
 * @brief Switches on/off to enable the ADC Programmable Gain Amplifier.
 *
 * The Programmable Gain Amplifier (PGA) is designed to increase the dynamic 
 * range by amplifying low-amplitude signals before they are fed to the 16-bit 
 * SAR ADC. The gain of this amplifier ranges between 1 to 64 in (2^N) steps.
 *
 * @param instance ADC instance ID.
 * @param isEnabled The switcher.
 */
static inline void adc_hal_configure_pga(uint32_t instance, bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_PGA_PGAEN(instance, (isEnabled ? 1U : 0U));
}

/*!
 * @brief Switches on/off to enable the PGA chopping mode.
 *
 * The PGA employs chopping to remove/reduce offset and 1/f noise and offers an 
 * offset measurement configuration that aids the offset calibration. 
 *
 * @param instance ADC instance ID.
 * @param isEnabled The switcher.
 */
static inline void adc_hal_configure_pga_chopping(uint32_t instance, 
        bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_PGA_PGACHPb(instance, (isEnabled ? 0U : 1U));
}

/*!
 * @brief Switches on/off to enable the PGA in a low power mode.
 *
 * This function  configures the PGA running in low power mode.
 * 
 * @param instance ADC instance ID.
 * @param isEnabled The switcher.
 */
static inline void adc_hal_configure_pga_in_low_power(uint32_t instance, 
        bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_PGA_PGALPb(instance, (isEnabled ? 0U : 1U));
}

/*!
 * @brief Switches on/off to enable the offset measurement mode.
 *
 * When this function is asserted, the PGA disconnects  from the external 
 * inputs and auto-configures into offset measurement mode. With this function is
 * asserted,  run the ADC in recommended settings and enable maximum
 * hardware averaging to get the PGA offset number. The output  is 
 * (PGA offset * (64+1)) for a given PGA setting.
 * 
 * @param instance ADC instance ID.
 * @param isEnabled The switcher.
 */
static inline void adc_hal_configure_pga_offset_measurement(uint32_t instance, 
        bool isEnabled)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_PGA_PGAOFSM(instance, (isEnabled ? 0U : 1U));
}

/*!
 * @brief Sets the selection of the PGA gain mode.
 *
 * The selection of the PGA gain mode can see to the type definition of the adc_pga_mode_t.
 * 
 * @param instance ADC instance ID.
 * @param mode The selection of gain.
 */
static inline void adc_hal_set_pga_gain_mode(uint32_t instance, 
        adc_pga_mode_t mode)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    BW_ADC_PGA_PGAG(instance, (uint32_t)(mode));
}

/*!
 * @brief Gets the selection of the current PGA gain mode.
 *
 * This function  returns the selection of the current PGA gain mode status.
 * 
 * @param instance ADC instance ID.
 * @return Current selection of gain mode.
 */
static inline adc_pga_mode_t adc_hal_get_pga_gain_mode(uint32_t instance)
{
    assert(instance < HW_ADC_INSTANCE_COUNT);
    
    return (adc_pga_mode_t)(BR_ADC_PGA_PGAG(instance));
}

#endif /* FSL_FEATURE_ADC_HAS_PGA */

#if defined(__cplusplus)
}
#endif

/*! @}*/

#endif /* __FSL_ADC_HAL_H__ */
/*******************************************************************************
* EOF
*******************************************************************************/