/*
 * Copyright 2019-2022 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef _FSL_VREF_H_
#define _FSL_VREF_H_

#include "fsl_common.h"

/*!
 * @addtogroup vref
 * @{
 */

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

/*! @name Driver version */
/*@{*/
#define FSL_VREF_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*!< Version 2.1.0. */
/*@}*/

/*! @brief VREF buffer modes. */
typedef enum _vref_buffer_mode
{
    kVREF_ModeBandgapOnly     = 0U, /*!< Bandgap enabled/standby. */
    kVREF_ModeLowPowerBuffer  = 1U, /*!< High-power buffer mode enabled */
    kVREF_ModeHighPowerBuffer = 2U  /*!< Low-power buffer mode enabled */
} vref_buffer_mode_t;

/*! @brief Voltage reference selection. */
typedef enum _vref_voltage_reference_sel
{
    kVREF_InternalBandgap    = 0U, /*!< Internal bandgap. */
    kVREF_LowPowerBuffed1v   = 1U, /*!< Low power buffered 1v. */
    kVREF_LowPowerBufferMode = 2U, /*!< Low-power buffer mode enabled. */
} vref_voltage_reference_sel_t;

/*! @brief The description structure for the VREF module. */
typedef struct _vref_config
{
    vref_buffer_mode_t bufferMode;        /*!< Buffer mode selection */
    bool enableInternalVoltageRegulator;  /*!< Provide additional supply noise rejection. */
    bool enableVrefOut;                   /*!< Enable the VREF supply voltage on VREF_OUT. */
    vref_voltage_reference_sel_t vrefSel; /*!< Control voltage reference selection */
} vref_config_t;

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

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

/*!
 * @name Initialization and deinitialization
 * @{
 */

/*!
 * @brief Enables the clock gate and configures the VREF module according to the configuration structure.
 *
 * This function must be called before calling all other VREF driver functions, read/write registers, and
 * configurations with user-defined settings. The example below shows how to set up vref_config_t parameters
 * and how to call the VREF_Init function by passing in these parameters.
 * @code
 *    vref_config_t vrefConfig;
 *    VREF_GetDefaultConfig(VREF, &vrefConfig);
 *    vrefConfig.bufferMode = kVREF_ModeHighPowerBuffer;
 *    VREF_Init(VREF, &vrefConfig);
 * @endcode
 *
 * @param base VREF peripheral address.
 * @param config Pointer to the configuration structure.
 */
void VREF_Init(VREF_Type *base, const vref_config_t *config);

/*!
 * @brief Stops and disables the clock for the VREF module.
 *
 * This function should be called to shut down the module.
 * This is an example.
 * @code
 *    vref_config_t vrefUserConfig;
 *    VREF_GetDefaultConfig(VREF, &vrefUserConfig);
 *    VREF_Init(VREF, &vrefUserConfig);
 *    ...
 *    VREF_Deinit(VREF);
 * @endcode
 *
 * @param base VREF peripheral address.
 */
void VREF_Deinit(VREF_Type *base);

/*!
 * @brief Initializes the VREF configuration structure.
 *
 * This function initializes the VREF configuration structure to default values.
 * This is an example.
 * @code
 *    config->bufferMode = kVREF_ModeHighPowerBuffer;
 *    config->enableInternalVoltageRegulator = true;
 *    config->enableVrefOut = true;
 *    config->vrefSel = kVREF_InternalBandgap;
 * @endcode
 *
 * @param config Pointer to the initialization structure.
 */
void VREF_GetDefaultConfig(vref_config_t *config);

/* @} */

/*!
 * @name Trim functions
 * @{
 */

/*!
 * brief Sets a TRIM value for the accurate 1.0V bandgap output.
 *
 * This function sets a TRIM value for the reference voltage. It will trim the accurate 1.0V bandgap by 0.5mV each step.
 *
 * param base VREF peripheral address.
 * param trimValue Value of the trim register to set the output reference voltage (maximum 0x3F (6-bit)).
 */
void VREF_SetVrefTrimVal(VREF_Type *base, uint8_t trimValue);

/*!
 * brief Sets a TRIM value for the accurate buffered VREF output.
 *
 * This function sets a TRIM value for the reference voltage. If buffer mode be set to other values (Buf21
 * enabled), it will trim the VREF_OUT by 0.1V each step from 1.0V to 2.1V.
 *
 * note When Buf21 is enabled, the value of UTRIM[TRIM2V1] should be ranged from 0b0000 to 0b1011 in order to trim the
 * output voltage from 1.0V to 2.1V, other values will make the VREF_OUT to default value, 1.0V.
 *
 * param base VREF peripheral address.
 * param trimValue Value of the trim register to set the output reference voltage (maximum 0xF (4-bit)).
 */
void VREF_SetTrim21Val(VREF_Type *base, uint8_t trim21Value);

/*!
 * brief Reads the VREF trim value..
 *
 * This function gets the TRIM value from the UTRIM register. It reads UTRIM[VREFTRIM] (13:8)
 *
 * param base VREF peripheral address.
 * return 6-bit value of trim setting.
 */
uint8_t VREF_GetVrefTrimVal(VREF_Type *base);

/*!
 * brief Reads the VREF 2.1V trim value..
 *
 * This function gets the TRIM value from the UTRIM register. It reads UTRIM[TRIM2V1] (3:0),
 *
 * param base VREF peripheral address.
 * return 4-bit value of trim setting.
 */
uint8_t VREF_GetTrim21Val(VREF_Type *base);

/* @} */

#if defined(__cplusplus)
}
#endif /* __cplusplus */

/*! @}*/

#endif /* _FSL_VREF_H_ */
