295 lines
12 KiB
C
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_ */
|