Files
test/drivers/include/sdrv_acmp.h
2025-11-07 20:19:23 +08:00

295 lines
12 KiB
C

/**
* @file sdrv_acmp.h
* @brief SemiDrive Analog Compare (ACMP) driver header file.
*
* @copyright Copyright (c) 2022 Semidrive Semiconductor.
* All rights reserved.
*/
#ifndef SDRV_ACMP_H_
#define SDRV_ACMP_H_
#include <types.h>
#include <compiler.h>
#include "sdrv_acmp.h"
#include "sdrv_common.h"
/* ACMP Chanel Polar */
#define ACMP_CH_POLAR_POS 1U
#define ACMP_CH_POLAR_NEG 0U
/* Single-End Mode Channel Select */
#define ACMP_SINGLE_CH_SEL(ch, polar, mux) \
(((mux & 0x7u) << 6) | ((polar & 0x1u) << 3) | (ch & 0x7u))
/* Differential Mode Channel Select */
#define ACMP_DIFF_CH_SEL(ch_p, ch_n, mux) \
(((mux & 0x7u) << 6) | ((ch_p & 0x7u) << 3) | (ch_n & 0x7u))
/**
* @brief ACMP status error code.
*/
enum sdrv_acmp_error
{
SDRV_ACMP_STATUS_INVALID_PARAM = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_ACMP, 1), /* Acmp invalid param. */
SDRV_ACMP_STATUS_WRONG_MODE = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_ACMP, 2), /* Acmp wrong mode. */
};
/* sdrv acmp dev */
struct sdrv_acmp_dev;
/* sdrv acmp mode */
typedef enum {
ACMP_HT_MODE = 0x0U, /**< Acmp hardware trigger mode */
ACMP_IT_MODE, /**< Acmp internal trigger mode */
} sdrv_acmp_mode_t;
/* sdrv acmp csel num */
typedef enum {
ACMP_CSEL_0 = 0x0U, /**< Acmp first compare select controller */
ACMP_CSEL_1, /**< Acmp second compare select controller */
ACMP_CSEL_2, /**< Acmp third compare select controller */
ACMP_CSEL_3, /**< Acmp fourth compare select controller */
} sdrv_acmp_csel_t;
/* sdrv acmp index num */
typedef enum {
ACMP_INDEX_0 = 0x0U, /**< Acmp config select index num, max index is 31 */
ACMP_INDEX_1,
ACMP_INDEX_2,
ACMP_INDEX_3,
ACMP_INDEX_4,
ACMP_INDEX_5,
ACMP_INDEX_6,
ACMP_INDEX_7,
ACMP_INDEX_8,
ACMP_INDEX_9,
ACMP_INDEX_10,
ACMP_INDEX_11,
ACMP_INDEX_12,
ACMP_INDEX_13,
ACMP_INDEX_14,
ACMP_INDEX_15,
ACMP_INDEX_16,
ACMP_INDEX_17,
ACMP_INDEX_18,
ACMP_INDEX_19,
ACMP_INDEX_20,
ACMP_INDEX_21,
ACMP_INDEX_22,
ACMP_INDEX_23,
ACMP_INDEX_24,
ACMP_INDEX_25,
ACMP_INDEX_26,
ACMP_INDEX_27,
ACMP_INDEX_28,
ACMP_INDEX_29,
ACMP_INDEX_30,
ACMP_INDEX_31,
} sdrv_acmp_index_t;
/* sdrv acmp pol adjust */
typedef enum {
ACMP_POL_ADJ_DIRECTLY = 0x0U, /**< Acmp analog output directly */
ACMP_POL_ADJ_INVERT, /**< Acmp invert raw analog output */
} sdrv_acmp_pol_adj_t;
/* sdrv acmp select reference voltage source */
typedef enum {
ACMP_SEL_REFP1 = 0x0U, /**< Acmp select internal reference voltage REFP1 */
ACMP_SEL_REFP2, /**< Acmp select internal reference voltage REFP2 or extern reference voltage */
} sdrv_acmp_reg_sel_t;
/* sdrv acmp sd sel */
typedef enum {
ACMP_SEL_SINGLE = 0x0U, /**< Acmp single-ended comparison mode */
ACMP_SEL_DIFF, /**< Acmp differential comparison mode*/
} sdrv_acmp_sd_sel_t;
/* sdrv acmp hysteresis window configure */
typedef enum {
ACMP_HCFG_NO = 0x0U, /**< Acmp without windows */
ACMP_HCFG_50_mV, /**< Acmp with windows, 50 mV */
ACMP_HCFG_100_mV = 0x3U, /**< Acmp With windows, 100 mV */
} sdrv_acmp_hcfg_t;
/* sdrv acmp csel configurations */
typedef struct sdrv_acmp_csel_cfg {
sdrv_acmp_csel_t csel_idx; /**< Index of compare select controller */
/* acmp ctrl cfg */
uint8_t amux_setup; /**< Analog mux setup time, preparation time required for a comparison.
The first period of (prop_delay + amux_setup) time in a comparison,
the comparison result is not reliable. */
uint8_t prop_delay : 5; /**< Propagation delay, in cycles of clock */
uint8_t rbw : 4; /**< Rising edge filter, unit: cycle number of clock, set 0 means bypass filter */
uint8_t fbw : 4; /**< Falling edge filter, unit: cycle number of clock, set 0 means bypass filter */
bool sample_en; /**< The result of analog comparison is sampled by an additional digital clock and then output.
sample_en is usually set to 0, when set to 1, mask and sync will not work. */
bool mask_en; /**< If sample_en is not enabled, mask_en refers to converting the above digital sampling
clock into an enable signal, which will be output only when the sampling clock is high */
bool pol_adj; /**< Analog output polar adjust */
bool sync_en; /**< Whether the output result is synchronized with the internal clock of acmp */
/* acmp analog cfg */
sdrv_acmp_reg_sel_t refsel; /**< select reference voltage source */
sdrv_acmp_sd_sel_t sdsel; /**< Single-ended or differential comparison mode */
sdrv_acmp_hcfg_t hcfg; /**< Set hysteresis window */
uint8_t dain; /**< Reference voltage adjustment. */
} sdrv_acmp_csel_cfg_t;
/* sdrv acmp index configurations */
typedef struct sdrv_acmp_index_cfg {
sdrv_acmp_index_t idx; /**< Acmp index num */
uint16_t amsel : 9; /**< Analog mux select */
uint8_t csel : 2; /**< Acmp config select */
bool ie; /**< Acmp interrupt enable */
bool uie; /**< Acmp uncorrect interrupt enable */
} sdrv_acmp_index_cfg_t;
/* sdrv acmp callback */
typedef int (*sdrv_acmp_callback)(struct sdrv_acmp_dev *dev, uint32_t state);
/* sdrv acmp configurations */
typedef struct sdrv_acmp_config {
paddr_t base; /**< Acmp base address */
int irq; /**< Acmp irq number */
sdrv_acmp_mode_t mode; /**< Acmp mode */
sdrv_acmp_csel_cfg_t *csel_cfg; /**< Acmp compare select controller configuration */
uint8_t csel_num; /**< Acmp config csel number */
sdrv_acmp_index_cfg_t *index_cfg; /**< Acmp index configurations */
uint8_t index_num; /**< Acmp config index number */
uint8_t req_n_dly; /**< Acmp req_n delay number */
bool qch_dac_en; /**< Allow acmp analog dac recieve q channel low power requset */
bool qch_cmp_en; /**< Allow acmp analog competitor recieve q channel low power requset */
/* IT MODE */
uint8_t qstart : 5; /**< The head idx number in a scanning sequence in IT mode */
uint8_t qend : 5; /**< The tail idx number in a scanning sequence in IT mode */
uint8_t cur_entry_pt : 5; /**< The start idx number in a scanning sequence in IT mode */
uint16_t timer_compare_val; /**< The total time for a whole comparison.
Only used in IT (internal trigger) mode.
The time must be more than (prop_delay + amux_setup) */
uint16_t timer_terminal_val; /**< Cycle comparison time, only used in IT (internal trigger) mode.
Acmp output once per cycle, the value must be more than
(timer_compare_val + prop_delay + amux_setup) */
} sdrv_acmp_config_t;
/* define the type of acmp device */
typedef struct sdrv_acmp_dev {
paddr_t base; /**< Acmp base address */
int irq; /**< Acmp irq number */
sdrv_acmp_callback callback; /**< Acmp callback function */
void *priv; /**< reserved */
} sdrv_acmp_t;
/**
* @brief sdrv acmp init
*
* This function initializes acmp device and attach callback function.
*
* @param[in] dev sdrv acmp device
* @param[in] acmp_cfg sdrv acmp configuration parameters
* @param[in] callback sdrv acmp callback function
* @return SDRV_STATUS_OK represents success or other error code
*/
status_t sdrv_acmp_init(sdrv_acmp_t *dev, sdrv_acmp_config_t *acmp_cfg, sdrv_acmp_callback callback);
/**
* @brief sdrv acmp start
*
* This function is used to start or stop acmp comparation.
* All the parameters are remained when acmp stop, and the previous comparation will restart when acmp start.
*
* @param[in] dev sdrv acmp dev
* @param[in] start sdrv acmp start
* @return SDRV_STATUS_OK represents success
*/
status_t sdrv_acmp_start(sdrv_acmp_t *dev, bool start);
/**
* @brief sdrv acmp IT mode trigger start
*
* This function is used to stop or restart trigger with differnet id numbers in IT mode.
* The new comparation will use the same comparation parameters with the former comparation.
* If the parameters need to be modified, acmp should be stopped and reinitialized.
*
* @param[in] dev sdrv acmp device
* @param[in] qstart sdrv acmp trigger start id number for loop
* @param[in] qend sdrv acmp trigger end id number for loop
* @param[in] cur_entry_pt sdrv acmp trigger first access id number
* @param[in] trigger_start acmp IT mode trigger start
* @return SDRV_STATUS_OK represents success
*/
status_t sdrv_acmp_it_trigger_start(sdrv_acmp_t *dev, uint8_t qstart, uint8_t qend, uint8_t cur_entry_pt,
bool trigger_start);
/**
* @brief sdrv acmp IT mode update valid irq state
*
* This function is used to workaround for multiple trigger if interrupt is required in IT mode.
* Occurrence scenario: Only appers in multiple triggers of IT mode, but this is not a problem
* if not changing the configuration(index and analog config) at next trigger.
* At the end of each trigger, if acmp voltage comparision result is pulled up one clock cycle
* before next trigger, the interrupt generated by this trigger will update to the register ID
* of the next trigger. Other functions of ACMP are not affected.
*
* How to use this function:
* Call the function at beginning of acmp callback function.
*
* @param[in] dev sdrv acmp device
* @param[in] state sdrv acmp irq state
* @param[in] wait_time check irq valid wait time, the period should be longer than terminal time.
* @return SDRV_STATUS_OK represents success
*/
status_t sdrv_acmp_it_update_valid_irq(sdrv_acmp_t *dev, uint32_t *state, uint32_t wait_time);
/**
* @brief sdrv acmp power ctrl
*
* This function sets the sdrv acmp power mode.
* The status is default power on after acmp initilization.
* If the acmp comparation is finished, the power mode can be set to power down to reduce power consumption.
*
* @param[in] dev sdrv acmp device
* @param[in] down 0 power on (default), 1 power down
* @return SDRV_STATUS_OK represents success
*/
status_t sdrv_acmp_power_ctrl(sdrv_acmp_t *dev, bool down);
/**
* @brief sdrv acmp allows analog competitor and dac enter lowpower mode
*
* This function allows competitor and dac recv q channel low power request.
* And than if the lowpower request is received, the competitor and dac will enter
* low power mode after req_n_dly clock cycle.
*
* @param[in] dev sdrv acmp device
* @param[in] cmp_en competitor enable or disable
* @param[in] dac_en dac enable or disable
* @param[in] req_n_dly enter lowpower mode delay number
* @return SDRV_STATUS_OK represents success
*/
status_t sdrv_acmp_enable_low_power(sdrv_acmp_t *dev, bool cmp_en, bool dac_en, uint8_t req_n_dly);
/**
* @brief sdrv acmp set callback
*
* This function is used to set the sdrv acmp callback function separately, after acmp initilization.
*
* @param[in] dev sdrv acmp device
* @param[in] callback acmp callback function
* @return SDRV_STATUS_OK represents success
*/
status_t sdrv_acmp_set_callback(sdrv_acmp_t *dev, sdrv_acmp_callback callback);
/**
* @brief sdrv acmp deinit
*
* This function stops acmp and deletes acmp initilization.
* Acmp must be de-initiated before entering lowpower mode.
*
* @param[in] dev sdrv acmp device
* @return SDRV_STATUS_OK represents success
*/
status_t sdrv_acmp_deinit(sdrv_acmp_t *dev);
#endif /* SDRV_ACMP_H_ */