rt-thread-official/bsp/hpmicro/libraries/hpm_sdk/components/adc/hpm_adc.h

618 lines
16 KiB
C

/*
* Copyright (c) 2022 hpmicro
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef HPM_ADC_H
#define HPM_ADC_H
#include "hpm_common.h"
#ifdef CONFIG_HAS_HPMSDK_ADC12
#include "hpm_adc12_drv.h"
#endif
#ifdef CONFIG_HAS_HPMSDK_ADC16
#include "hpm_adc16_drv.h"
#endif
#include "hpm_soc_feature.h"
/**
* @brief ADC HAL driver APIs
* @defgroup hpm_adc_interface HPM ADC driver APIs
* @ingroup hpm_adc_interfaces
* @{
*/
/**
* @brief An ADC peripheral base address.
*
*/
typedef union
{
#ifdef CONFIG_HAS_HPMSDK_ADC12
ADC12_Type *adc12;
#endif
#ifdef CONFIG_HAS_HPMSDK_ADC16
ADC16_Type *adc16;
#endif
} adc_base;
/**
* @brief use adc12 or adc16.
*
*/
#define ADCX_MODULE_ADC12 1
#define ADCX_MODULE_ADC16 2
typedef enum {
adc_module_adc12 = ADCX_MODULE_ADC12,
adc_module_adc16 = ADCX_MODULE_ADC16
} adc_module;
/**
* @brief ADC common configuration struct.
*
*/
typedef struct {
adc_module module;
adc_base adc_base;
struct {
#ifdef CONFIG_HAS_HPMSDK_ADC12
adc12_config_t adc12;
#endif
#ifdef CONFIG_HAS_HPMSDK_ADC16
adc16_config_t adc16;
#endif
} config;
} adc_config_t;
/**
* @brief ADC channel configuration struct.
*
*/
typedef struct {
adc_module module;
adc_base adc_base;
struct {
#ifdef CONFIG_HAS_HPMSDK_ADC12
adc12_channel_config_t adc12_ch;
#endif
#ifdef CONFIG_HAS_HPMSDK_ADC16
adc16_channel_config_t adc16_ch;
#endif
} config;
} adc_channel_config_t;
/**
* @brief ADC DMA configuration struct.
*
* */
typedef struct {
adc_module module;
adc_base adc_base;
struct {
#ifdef CONFIG_HAS_HPMSDK_ADC12
adc12_dma_config_t adc12;
#endif
#ifdef CONFIG_HAS_HPMSDK_ADC16
adc16_dma_config_t adc16;
#endif
} config;
} adc_dma_config_t;
/**
* @brief ADC configuration struct for period mode.
*
* */
typedef struct {
adc_module module;
adc_base adc_base;
struct {
#ifdef CONFIG_HAS_HPMSDK_ADC12
adc12_prd_config_t adc12;
#endif
#ifdef CONFIG_HAS_HPMSDK_ADC16
adc16_prd_config_t adc16;
#endif
} config;
} adc_prd_config_t;
/**
* @brief ADC configuration struct for sequence mode.
*
* */
typedef struct {
adc_module module;
adc_base adc_base;
struct {
#ifdef CONFIG_HAS_HPMSDK_ADC12
adc12_seq_config_t adc12;
#endif
#ifdef CONFIG_HAS_HPMSDK_ADC16
adc16_seq_config_t adc16;
#endif
} config;
} adc_seq_config_t;
/**
* @brief ADC trigger configuration struct for preempt mode.
*
* */
typedef struct
{
adc_module module;
adc_base adc_base;
struct {
#ifdef CONFIG_HAS_HPMSDK_ADC12
adc12_pmt_config_t adc12;
#endif
#ifdef CONFIG_HAS_HPMSDK_ADC16
adc16_pmt_config_t adc16;
#endif
} config;
} adc_pmt_config_t;
typedef struct
{
adc_module module;
adc_base adc_base;
} adc_type;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Get a default configuration for an ADC instance.
*
* @param[out] config A pointer to the configuration struct of "adc_config_t".
*
*/
static inline void hpm_adc_init_default_config(adc_config_t *config)
{
if (config->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
adc12_get_default_config(&config->config.adc12);
#endif
} else if (config->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
adc16_get_default_config(&config->config.adc16);
#endif
}
}
/**
* @brief Get a default configuration for an ADC channel instance.
*
* @param[out] config A pointer to the configuration struct of "adc_channel_config_t".
*
*/
static inline void hpm_adc_init_channel_default_config(adc_channel_config_t *config)
{
if (config->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
adc12_get_channel_default_config(&config->config.adc12_ch);
#endif
} else if (config->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
adc16_get_channel_default_config(&config->config.adc16_ch);
#endif
}
}
/**
* @brief Initialize an ADC instance.
*
* @param[in] config A pointer to the configuration struct of "adc_config_t".
* @retval status_success Initialize an ADC instance successfully.
* @retval status_invalid_argument Initialize an ADC instance unsuccessfully because of passing one or more invalid arguments.
*/
static inline hpm_stat_t hpm_adc_init(adc_config_t *config)
{
if (config->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
return adc12_init(config->adc_base.adc12, &config->config.adc12);
#else
return status_invalid_argument;
#endif
} else if (config->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
return adc16_init(config->adc_base.adc16, &config->config.adc16);
#else
return status_invalid_argument;
#endif
} else {
return false;
}
}
/**
* @brief Initialize an ADC channel.
*
* @param[in] config A pointer to the configuration struct of "adc_config_t".
* @retval status_success Initialize an ADC instance successfully.
* @retval status_invalid_argument Initialize an ADC instance unsuccessfully because of passing one or more invalid arguments.
*/
static inline hpm_stat_t hpm_adc_channel_init(adc_channel_config_t *config)
{
if (config->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
return adc12_init_channel(config->adc_base.adc12, &config->config.adc12_ch);
#else
return status_invalid_argument;
#endif
} else if (config->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
return adc16_init_channel(config->adc_base.adc16, &config->config.adc16_ch);
#else
return status_invalid_argument;
#endif
} else {
return false;
}
}
/**
* @brief Configure the periodic mode for an ADC instance.
*
* @param[in] config A pointer to the configuration struct of "adc_prd_config_t".
* @retval status_success Configure the periodic mode for an ADC instance successfully.
* @retval status_invalid_argument Configure the periodic mode for an ADC instance unsuccessfully because of passing one or more invalid arguments.
*
*/
static inline hpm_stat_t hpm_adc_set_period_config(adc_prd_config_t *config)
{
if (config->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
return adc12_set_prd_config(config->adc_base.adc12, &config->config.adc12);
#else
return status_invalid_argument;
#endif
} else if (config->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
return adc16_set_prd_config(config->adc_base.adc16, &config->config.adc16);
#else
return status_invalid_argument;
#endif
} else {
return false;
}
}
/**
* @brief Configure the sequence mode for an ADC instance.
*
* @param[in] config A pointer to configuration struct of "adc_seq_config_t".
* @retval status_success Configure the sequence mode for an ADC instance successfully.
* @retval status_invalid_argument Configure the sequence mode for an ADC instance unsuccessfully because of passing one or more invalid arguments.
*/
static inline hpm_stat_t hpm_adc_set_sequence_config(adc_seq_config_t *config)
{
if (config->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
return adc12_set_seq_config(config->adc_base.adc12, &config->config.adc12);
#else
return status_invalid_argument;
#endif
} else if (config->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
return adc16_set_seq_config(config->adc_base.adc16, &config->config.adc16);
#else
return status_invalid_argument;
#endif
} else {
return false;
}
}
/**
* @brief Configure the preemption mode for an ADC instance.
*
* @param[in] config a pointer to configuration struct of "adc_pmt_config_t".
* @retval status_success Configure the preemption mode for an ADC instance successfully.
* @retval status_invalid_argument Configure the preemption mode for an ADC instance unsuccessfully because of passing one or more invalid arguments.
*/
static inline hpm_stat_t hpm_adc_set_preempt_config(adc_pmt_config_t *config)
{
if (config->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
return adc12_set_pmt_config(config->adc_base.adc12, &config->config.adc12);
#else
return status_invalid_argument;
#endif
} else if (config->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
return adc16_set_pmt_config(config->adc_base.adc16, &config->config.adc16);
#else
return status_invalid_argument;
#endif
} else {
return false;
}
}
/**
* @brief Configure the stop position offset in the specified memory for DMA write operation for sequence mode.
*
* @param[in] ptr An ADC peripheral base address.
* @param[in] stop_pos The stop position offset.
*/
static inline void hpm_adc_set_seq_stop_pos(adc_type *ptr, uint16_t stop_pos)
{
if (ptr->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
adc12_set_seq_stop_pos(ptr->adc_base.adc12, stop_pos);
#endif
} else if (ptr->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
adc16_set_seq_stop_pos(ptr->adc_base.adc16, stop_pos);
#endif
}
}
/**
* @brief Configure the start address of DMA write operation for preemption mode.
*
* @param[in] ptr An ADC peripheral base address.
* @param[in] addr The start address of DMA write operation.
*/
static inline void hpm_adc_init_pmt_dma(adc_type *ptr, uint32_t addr)
{
if (ptr->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
adc12_init_pmt_dma(ptr->adc_base.adc12, addr);
#endif
} else if (ptr->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
adc16_init_pmt_dma(ptr->adc_base.adc16, addr);
#endif
}
}
/**
* @brief Configure the start address of DMA write operation for preemption mode.
*
* @param[in] config A pointer to configuration struct of "adc_dma_config_t".
*/
static inline void hpm_adc_init_seq_dma(adc_dma_config_t *config)
{
if (config->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
adc12_init_seq_dma(config->adc_base.adc12, &config->config.adc12);
#endif
} else if (config->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
adc16_init_seq_dma(config->adc_base.adc16, &config->config.adc16);
#endif
}
}
/**
* @brief Get ADC status flags.
*
* This function gets all ADC status flags.
* @param[in] ptr An ADC peripheral base address.
* @retval Status The ADC interrupt status flags.
*/
static inline uint32_t hpm_adc_get_status_flags(adc_type *ptr)
{
if (ptr->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
return adc12_get_status_flags(ptr->adc_base.adc12);
#else
return 0;
#endif
} else if (ptr->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
return adc16_get_status_flags(ptr->adc_base.adc16);
#else
return 0;
#endif
} else {
return false;
}
}
/**
* @brief Get the setting value of wait disable.
*
* This status flag is only used when wait_dis is set to disable.
*
* @param[in] ptr An ADC peripheral base address.
* @retval Status It means whether the current setting of wait disable is disable.
*/
static inline bool hpm_adc_get_wait_dis_status(adc_type *ptr)
{
if (ptr->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
return adc12_get_wait_dis_status(ptr->adc_base.adc12);
#else
return 1;
#endif
} else if (ptr->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
return adc16_get_wait_dis_status(ptr->adc_base.adc16);
#else
return 1;
#endif
} else {
return false;
}
}
/**
* @brief Get status flag of a conversion.
*
* This status flag is only used when wait_dis is set to disable.
*
* @param[in] ptr An ADC peripheral base address.
* @param[in] ch An ADC peripheral channel.
* @retval Status It means the current conversion is valid.
*/
static inline bool hpm_adc_get_conv_valid_status(adc_type *ptr, uint8_t ch)
{
if (ptr->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
return adc12_get_conv_valid_status(ptr->adc_base.adc12, ch);
#else
return 0;
#endif
} else if (ptr->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
return adc16_get_conv_valid_status(ptr->adc_base.adc16, ch);
#else
return 0;
#endif
} else {
return false;
}
}
/**
* @brief Clear status flags.
*
* Only the specified flags can be cleared by writing INT_STS register.
*
* @param[in] ptr An ADC peripheral base address.
* @param[in] mask Mask value for flags to be cleared. Refer to "adc12_irq_event_t". Refer to "adc16_irq_event_t".
*/
static inline void hpm_adc_clear_status_flags(adc_type *ptr, uint32_t mask)
{
if (ptr->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
adc12_clear_status_flags(ptr->adc_base.adc12, mask);
#endif
} else if (ptr->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
adc16_clear_status_flags(ptr->adc_base.adc16, mask);
#endif
}
}
/**
* @brief Enable interrupts.
*
* @param[in] ptr An ADC peripheral base address.
* @param[in] mask Mask value for interrupt events. Refer to "adc12_irq_event_t".Refer to "adc16_irq_event_t".
*/
static inline void hpm_adc_enable_interrupts(adc_type *ptr, uint32_t mask)
{
if (ptr->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
adc12_enable_interrupts(ptr->adc_base.adc12, mask);
#endif
} else if (ptr->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
adc16_enable_interrupts(ptr->adc_base.adc16, mask);
#endif
}
}
/**
* @brief Disable interrupts.
*
* @param[in] ptr An ADC peripheral base address.
* @param[in] mask Mask value for interrupt events. Refer to "adc12_irq_event_t".Refer to "adc16_irq_event_t".
*/
static inline void hpm_adc_disable_interrupts(adc_type *ptr, uint32_t mask)
{
if (ptr->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
adc12_disable_interrupts(ptr->adc_base.adc12, mask);
#endif
} else if (ptr->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
adc16_disable_interrupts(ptr->adc_base.adc16, mask);
#endif
}
}
/**
* @brief Get the result in oneshot mode.
*
* @param[in] ptr An ADC peripheral base address.
* @param[in] ch An ADC peripheral channel.
* @param[out] result The result of an ADC12 conversion.
*
* @retval status_success Get the result of an ADC12 conversion in oneshot mode successfully.
* @retval status_invalid_argument Get the result of an ADC12 conversion in oneshot mode unsuccessfully because of passing invalid arguments.
*/
static inline hpm_stat_t hpm_adc_get_oneshot_result(adc_type *ptr, uint8_t ch, uint16_t *result)
{
if (ptr->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
return adc12_get_oneshot_result(ptr->adc_base.adc12, ch, result);
#else
return status_invalid_argument;
#endif
} else if (ptr->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
return adc16_get_oneshot_result(ptr->adc_base.adc16, ch, result);
#else
return status_invalid_argument;
#endif
} else {
return false;
}
}
/**
* @brief Get the result in periodic mode.
*
* @param[in] ptr An ADC12 peripheral base address.
* @param[in] ch An ADC12 peripheral channel.
* @param[out] result The result of an ADC12 conversion.
*
* @retval status_success Get the result of an ADC12 conversion in periodic mode successfully.
* @retval status_invalid_argument Get the result of an ADC12 conversion in periodic mode unsuccessfully because of passing invalid arguments.
*/
hpm_stat_t hpm_adc_get_prd_result(adc_type *ptr, uint8_t ch, uint16_t *result)
{
if (ptr->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
return adc12_get_prd_result(ptr->adc_base.adc12, ch, result);
#else
return status_invalid_argument;
#endif
} else if (ptr->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
return adc16_get_prd_result(ptr->adc_base.adc16, ch, result);
#else
return status_invalid_argument;
#endif
} else {
return false;
}
}
/**
* @brief Do a software trigger for sequence mode.
*
* @param[in] ptr An adc peripheral base address.
*
*/
void hpm_adc_trigger_seq_by_sw(adc_type *ptr)
{
if (ptr->module == adc_module_adc12) {
#ifdef CONFIG_HAS_HPMSDK_ADC12
return adc12_trigger_seq_by_sw(ptr->adc_base.adc12);
#endif
} else if (ptr->module == adc_module_adc16) {
#ifdef CONFIG_HAS_HPMSDK_ADC16
return adc16_trigger_seq_by_sw(ptr->adc_base.adc16);
#endif
}
}
#ifdef __cplusplus
}
#endif
/** @} */
#endif