/* * Copyright (c) 2019-2023 Beijing Hanwei Innovation Technology Ltd. Co. and * its subsidiaries and affiliates (collectly called MKSEMI). * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form, except as embedded into an MKSEMI * integrated circuit in a product or a software update for such product, * 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. * * 3. Neither the name of MKSEMI nor the names of its contributors may be used * to endorse or promote products derived from this software without * specific prior written permission. * * 4. This software, with or without modification, must only be used with a * MKSEMI integrated circuit. * * 5. Any software provided in binary form under this license must not be * reverse engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY MKSEMI "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL MKSEMI 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 MK_ADC_H_ #define MK_ADC_H_ #include "mk_common.h" #include "mk_dma.h" #ifndef ADC_INT_MODE_EN #define ADC_INT_MODE_EN (1) #endif #ifndef ADC_DMA_MODE_EN #define ADC_DMA_MODE_EN (1) #endif #ifndef ADC_POLL_MODE_EN #define ADC_POLL_MODE_EN (1) #endif /** * @addtogroup MK8000_ADC * @{ */ #define ADC_CLK_HIGH_FREQ 62400000U /*!< ADC works at 62.4M system clock */ #define ADC_CLK_LOW_FREQ 32000U /*!< ADC works at 32K system clock */ #define ADC_CLK_H_MAX_SAMPLE_RATE 2000000U /*!< ADC works at 62.4M system clock, the maximum sampling rate is 2M */ #define ADC_CLK_L_MAX_SAMPLE_RATE ADC_CLK_LOW_FREQ /*!< ADC works at 32K system clock, the maximum sampling rate is 32K */ /* ADC internal voltage reference (1.2V) */ #define ADC_INTERNAL_VREF_MV (1200) /* Temperature characteristic curve slope */ #define ADC_TEMP_K_FACTOR (0.341) /** * @brief ADC P/N channels enumeration */ enum ADC_P_N_SET { ADC_IN_EXTPIN0 = 0, /*!< Select external pin as the positive or negative input (adc input-->GPIO0) */ ADC_IN_EXTPIN1 = 1, /*!< Select external pin as the positive or negative input (adc input-->GPIO1) */ ADC_IN_GUD = 2, /*!< Select GND as the positive or negative input */ ADC_IN_VREF = 3, /*!< Select internal or external reference voltage as input */ }; /** * @brief ADC conversion mode enumeration */ enum ADC_MODE_T { ADC_MODE_SINGLE = 0, /*!< Single conversion mode */ ADC_MODE_CONTINUE, /*!< Continuous conversion mode */ }; /** * @brief ADC system clock enumeration */ enum ADC_CLK_SEL_T { ADC_CLK_HIGH = 0, /*!< ADC works at high frequency system clock (62.5 MHz) */ ADC_CLK_LOW, /*!< ADC works at low frequency system clock (32 KHz) */ }; /** * @brief ADC reference voltage selection enumeration */ enum ADC_VREF_SEL_T { ADC_SEL_VREF_EXT = 0, /*!< To use an external reference voltage, GPIO2 must be enabled as a VREF function, and the external reference voltage used is limited to 3.3V */ ADC_SEL_VREF_INT, /*!< Internal reference voltage is 1.2V, the measuring range is 0~2.4V */ }; /** * @brief ADC state */ enum ADC_STATE_T { ADC_STATE_RESET = 0x00U, /*!< ADC not yet initialized or disabled */ ADC_STATE_READY = 0x01U, /*!< ADC initialized and ready for use */ ADC_STATE_BUSY = 0x10U, /*!< ADC is sampling and converting */ ADC_STATE_TIMEOUT = 0x40U, /*!< ADC conversion timeout */ ADC_STATE_ERROR = 0x80U, /*!< ADC error state */ }; /** * @brief ADC configure Structure * */ struct ADC_CFG_T { enum ADC_MODE_T mode; /*!< ADC conversion mode setting. */ enum ADC_CLK_SEL_T clk_sel; /*!< ADC system clock setting. */ enum ADC_VREF_SEL_T vref_sel; /*!< ADC reference voltage setting. */ uint32_t rate; /*!< ADC works at high-speed clock(62.5M), the maximum sampling rate can be set to 2M. ADC works at low-speed clock(32K), the maximum sampling rate can be set to 32K. */ uint8_t channel_p; /*!< Configure input of the selected ADC positive channel. This parameter will be one of the following values: @arg ADC_IN_EXTPIN0 @arg ADC_IN_EXTPIN1 @arg ADC_IN_GUD @arg ADC_IN_VREF */ uint8_t channel_n; /*!< Configure input of the selected ADC negative channel. This parameter will be one of the following values: @arg ADC_IN_EXTPIN0 @arg ADC_IN_EXTPIN1 @arg ADC_IN_GUD @arg ADC_IN_VREF */ uint8_t acc_num; /*!< The cumulative threshold of sampling times */ uint8_t int_en; /*!< Specifies whether the interrupt is enabled or disabled. This parameter will be one of the following values: @arg true is enable @arg false is disable */ uint8_t dma_en; /*!< Specifies whether the dma is enabled or disabled. This parameter shoule be one of the following values: @arg true is enable @arg false is disable */ uint8_t high_pulse_time : 4; uint8_t settle_time : 4; uint8_t reserved[2]; }; /** * @brief ADC handle Structure */ struct ADC_HANDLE_T { ADC_TypeDef *const base; /*!< ADC registers base address */ const IRQn_Type irq; /*!< ADC interrupt number */ enum DMA_CH_T dma_ch; /*!< ADC dma channel */ enum ADC_MODE_T mode; /*!< ADC conversion mode */ enum ADC_STATE_T state; /*!< ADC status */ uint32_t *data; /*!< Pointer to the output buffer, conversion results will be stored */ uint16_t number; /*!< Number of times to get conversion results */ uint16_t count; /*!< Count of conversion results */ uint8_t int_en; /*!< ADC done interrupt enable */ uint8_t dma_en; /*!< DMA support only in continue mode */ uint8_t reserved[2]; drv_callback_t callback; /*!< Callback function provided by the user */ }; #ifdef __cplusplus extern "C" { #endif /** * @brief Function for initializing the ADC. * * @param[in] config Pointer to a ADC_CFG_T structure that contains the configuration information for ADC. * @return * @arg DRV_BUSY error id * @arg DEV_OK succeed */ int adc_open(struct ADC_CFG_T *config); /** * @brief Function for uninitializing the ADC. * * @return * @arg DRV_BUSY error id * @arg DEV_OK succeed */ int adc_close(void); /** * @brief Function for changing input of ADC P/N. * * @param[in] P The positive input. * This parameter can be a value of @ref ADC_P_N_SET * @param[in] N The negative input. * This parameter can be a value of @ref ADC_P_N_SET * @return * @arg DRV_BUSY error id * @arg DEV_OK succeed */ int adc_switch_channel(enum ADC_P_N_SET P, enum ADC_P_N_SET N); /** * @brief Conversion complete callback in non blocking mode * @param[out] data Pointer to the data buffer, conversion results will be stored * @param[in] number Number of times to get conversion results * @param[in] callback Conversion complete callback * @return * @arg DRV_ERROR error id * @arg DRV_BUSY send failed because of ADC is busy * @arg DEV_OK conversion success */ int adc_get(uint32_t *data, uint16_t number, drv_callback_t callback); /** * @brief Function for Interrupt handler for ADC. */ void ADC_IRQHandler(void); /** * @brief Convert ADC result to mv * @param[in] adc_val ADC result * @param[in] vref_mv Reference voltage, unit: mv * @return voltage in mv */ int16_t adc_code_to_mv(int16_t adc_val, int16_t vref_mv); /* BATTM */ /** * @brief Open battery voltage monitor. */ void battery_monitor_open(void); /** * @brief Close battery voltage monitor. */ void battery_monitor_close(void); /** * @brief Get battery monitor voltage. * @return battery monitor voltage */ int16_t battery_monitor_get(void); /* TEMP */ /** * @brief Open temperature sensor. */ void temp_sensor_open(void); /** * @brief Close temperature sensor. */ void temp_sensor_close(void); /** * @brief Get temperature and adc value of the chip. * @param[out] p_adc_value Pointer to the data buffer, results of adc value will be stored * @return temperature of chip */ int8_t temp_sensor_get(int16_t *p_adc_value); #ifdef __cplusplus } #endif /** * @} */ #endif /* MK_ADC_H_ */