123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546 |
- /*
- * Copyright (c) 2023 HPMicro
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
- #ifndef HPM_OPAMP_DRV_H
- #define HPM_OPAMP_DRV_H
- #include "hpm_common.h"
- #include "hpm_opamp_regs.h"
- #include "hpm_soc_feature.h"
- /**
- * @brief OPMAP driver APIs
- * @defgroup opamp_interface OPAMP driver APIs
- * @ingroup io_interfaces
- * @{
- *
- */
- #define OPAMP_MODE_FOLLOW_KEY (0x06)
- #define OPAMP_MODE_INVERT_INDEX0_KEY (0x08)
- #define OPAMP_MODE_INVERT_INDEX1_KEY (0x18)
- #define OPAMP_MODE_NON_INVERT_INDEX0_KEY (0x01)
- #define OPAMP_MODE_NON_INVERT_INDEX1_KEY (0x09)
- #define OPAMP_MODE_NON_INVERT_INDEX2_KEY (0x11)
- #define OPAMP_MODE_NON_INVERT_INDEX3_KEY (0x19)
- #define OPAMP_MODE_NON_INVERT_INDEX4_KEY (0x09)
- #define OPAMP_MODE_USER_DEFINE_KEY (0x04)
- /**
- * @brief Reverse Input Pin Selection
- *
- */
- typedef enum {
- inm_pad_vim0 = 0, /**< Connect pad vim0 */
- inm_pad_vim1 = 1, /**< Connect pad vim1 */
- inm_pad_vim2 = 2, /**< Connect pad vim2 */
- inm_pad_dac = 3, /**< Connect pad vim dac */
- inm_pad_floating = 4 /**< Connect inm floating */
- } opamp_inm_pad_t;
- /**
- * @brief Gain multiplier selection
- *
- */
- typedef enum {
- gain_x_2 = 0, /**< gain x2 */
- gain_x_4 = 1,
- gain_x_8 = 2,
- gain_x_16 = 3,
- gain_x_32 = 4,
- gain_x_64 = 5,
- gain_x_128 = 6, /**< gain x128 */
- } opamp_gain_t;
- /**
- * @brief Miller Capacitor Selection
- *
- */
- typedef enum {
- miller_cap_x_7 = 0, /**< 7 unit cap */
- miller_cap_x_8 = 1,
- miller_cap_x_10 = 2,
- miller_cap_x_13 = 3,
- miller_cap_x_15 = 4, /**< 15 unit cap */
- miller_cap_x_18 = 5,
- miller_cap_x_5 = 6,
- miller_cap_x_6 = 7, /**< 6 unit cap */
- } opamp_miller_cap_t;
- /**
- * @brief Positive Input Pin Selection
- *
- */
- typedef enum {
- inp_pad_vip0 = 0, /**< Connect pad vip0 */
- inp_pad_vip1 = 1, /**< Connect pad vip1 */
- inp_pad_vip2 = 2, /**< Connect pad vip2 */
- inp_pad_dac = 3, /**< Connect pad vip dac */
- inp_pad_vsupply_x_0_25 = 4, /**< Connect reference = 0.25 * vsupply */
- inp_pad_vsupply_x_0_5 = 5, /**< Connect reference = 0.5 * vsupply */
- inp_pad_vsupply_x_0_75 = 6, /**< Connect reference = 0.75 * vsupply */
- inp_pad_floating = 7 /**< Connect inp floating */
- } opamp_inp_pad_t;
- /**
- * @brief opamp preset channel
- *
- */
- typedef enum {
- cfg_preset_0 = OPAMP_CFG_PRESET0,
- cfg_preset_1 = OPAMP_CFG_PRESET1,
- cfg_preset_2 = OPAMP_CFG_PRESET2,
- cfg_preset_3 = OPAMP_CFG_PRESET3,
- cfg_preset_4 = OPAMP_CFG_PRESET4,
- cfg_preset_5 = OPAMP_CFG_PRESET5,
- cfg_preset_6 = OPAMP_CFG_PRESET6,
- cfg_preset_7 = OPAMP_CFG_PRESET7,
- } opamp_cfg_preset_chn_t;
- /**
- * @brief operational amplifier
- *
- */
- typedef enum {
- mode_follow = 0, /**< opamp follow mode */
- mode_invert_intern_vol = 1, /**< inverting opamp */
- mode_invert_extern_vol = 2, /**< inverted amplification mode, external reference voltage */
- mode_invert_dac_vol = 3, /**< inverted amplification mode, DAC output reference voltage */
- mode_non_invert_gnd_vol = 4, /**< forward amplification mode, GND is the reference voltage */
- mode_non_invert_extern_vol = 5, /**< forward amplification mode, external reference voltage */
- mode_non_invert_dac_vol = 6, /**< forward amplification mode, DAC output reference voltage */
- mode_user = 7, /**< custom Mode */
- } opamp_mode_t;
- /**
- * @brief opamp configuration preset0
- *
- */
- typedef union opamp_cfg_preset0 {
- struct {
- uint32_t vip_select: 3;
- uint32_t vim_select: 3;
- uint32_t vswitch_select: 3;
- uint32_t cap_select: 4;
- uint32_t reserve: 19;
- };
- uint32_t val;
- } opamp_ctrl_cfg_preset0_t;
- /**
- * @brief opamp configuration preset1
- *
- */
- typedef union opamp_cfg_preset1 {
- struct {
- uint32_t res_select: 3;
- uint32_t function_mode: 5;
- uint32_t iref_select: 2;
- uint32_t opaout_select: 2;
- uint32_t is_vssa_disconnect: 1;
- uint32_t en_lv: 1;
- uint32_t hw_trig_en: 1;
- uint32_t reserve: 17;
- };
- uint32_t val;
- } opamp_ctrl_cfg_preset1_t;
- typedef struct opamp_cfg {
- opamp_mode_t mode;
- opamp_inm_pad_t negative_input_pin;
- opamp_inp_pad_t positive_input_pin;
- opamp_gain_t gain;
- opamp_miller_cap_t miller_cap;
- bool enable_extern_filter_cap;
- bool enable_phase_margin_cap;
- } opamp_cfg_t;
- #ifdef __cplusplus
- extern "C" {
- #endif
- /**
- * @brief opamp initialisation functions
- * Use this function to initialise the op-amp to different modes
- * @param opamp @ref OPAMP_Type
- * @param cfg @ref opamp_cfg_t
- * @return @ref hpm_stat_t
- */
- hpm_stat_t opamp_init(OPAMP_Type *opamp, opamp_cfg_t *cfg);
- /**
- * @brief enable opamp function
- *
- * @param opamp @ref OPAMP_Type
- */
- static inline void opamp_enable(OPAMP_Type *opamp)
- {
- opamp->CTRL0 |= OPAMP_CTRL0_EN_LV_MASK;
- }
- /**
- * @brief preset enable opamp function
- *
- * @param opamp @ref OPAMP_Type
- * @param preset_chn preset channel
- */
- static inline void opamp_preset_opamp_enable(OPAMP_Type *opamp, uint8_t preset_chn)
- {
- opamp->CFG[preset_chn].CFG1 |= OPAMP_CFG_CFG1_EN_LV_MASK;
- }
- /**
- * @brief disable opamp function
- *
- * @param opamp @ref OPAMP_Type
- */
- static inline void opamp_disable(OPAMP_Type *opamp)
- {
- opamp->CTRL0 &= ~OPAMP_CTRL0_EN_LV_MASK;
- }
- /**
- * @brief preset disable opamp function
- *
- * @param opamp @ref OPAMP_Type
- * @param preset_chn preset channel
- */
- static inline void opamp_preset_opamp_disable(OPAMP_Type *opamp, uint8_t preset_chn)
- {
- opamp->CFG[preset_chn].CFG1 &= ~OPAMP_CFG_CFG1_EN_LV_MASK;
- }
- /**
- * @brief opamp miller cap selection
- *
- * @param opamp @ref OPAMP_Type
- * @param select @ref opamp_miller_cap_t
- */
- static inline void opamp_miller_cap_select(OPAMP_Type *opamp, opamp_miller_cap_t select)
- {
- opamp->CTRL0 = (opamp->CTRL0 & (~OPAMP_CTRL0_MILLER_SEL_MASK)) | OPAMP_CTRL0_MILLER_SEL_SET(select);
- }
- /**
- * @brief opamp miller cap selection preset
- *
- * @param opamp @ref OPAMP_Type
- * @param preset_chn preset channel
- * @param select @ref opamp_miller_cap_t
- */
- static inline void opamp_preset_miller_cap_select(OPAMP_Type *opamp, uint8_t preset_chn, opamp_miller_cap_t select)
- {
- opamp->CFG[preset_chn].CFG0 = (opamp->CFG[preset_chn].CFG0 & (~OPAMP_CFG_CFG0_MILLER_SEL_MASK)) | OPAMP_CFG_CFG0_MILLER_SEL_SET(select);
- }
- /**
- * @brief enable phase margin compensation cap
- *
- * @param opamp @ref OPAMP_Type
- */
- static inline void opamp_phase_margin_cap_enable(OPAMP_Type *opamp)
- {
- opamp->CTRL0 &= ~OPAMP_CTRL0_DISABLE_PM_CAP_MASK;
- }
- /**
- * @brief enable phase margin compensation cap preset
- *
- * @param opamp @ref OPAMP_Type
- * @param preset_chn preset channel
- */
- static inline void opamp_preset_phase_margin_cap_enable(OPAMP_Type *opamp, uint8_t preset_chn)
- {
- opamp->CFG[preset_chn].CFG0 &= ~OPAMP_CFG_CFG0_DISABLE_PM_CAP_MASK;
- }
- /**
- * @brief disable phase margin compensation cap
- *
- * @param opamp @ref OPAMP_Type
- */
- static inline void opamp_phase_margin_cap_disable(OPAMP_Type *opamp)
- {
- opamp->CTRL0 |= OPAMP_CTRL0_DISABLE_PM_CAP_MASK;
- }
- /**
- * @brief disable phase margin compensation cap preset
- *
- * @param opamp @ref OPAMP_Type
- * @param preset_chn preset channel
- */
- static inline void opamp_preset_phase_margin_cap_disable(OPAMP_Type *opamp, uint8_t preset_chn)
- {
- opamp->CFG[preset_chn].CFG0 |= OPAMP_CFG_CFG0_DISABLE_PM_CAP_MASK;
- }
- /**
- * @brief opamp core inm connect pad
- *
- * @param opamp @ref OPAMP_Type
- * @param select @ref opamp_inm_pad_t
- */
- static inline void opamp_inn_pad_select(OPAMP_Type *opamp, opamp_inm_pad_t select)
- {
- opamp->CTRL0 = (opamp->CTRL0 & (~OPAMP_CTRL0_VIM_SEL_MASK)) | OPAMP_CTRL0_VIM_SEL_SET(select);
- }
- /**
- * @brief opamp core inm connect pad preset
- *
- * @param opamp @ref OPAMP_Type
- * @param preset_chn preset channel
- * @param select @ref opamp_inm_pad_t
- */
- static inline void opamp_preset_inn_pad_select(OPAMP_Type *opamp, uint8_t preset_chn, opamp_inm_pad_t select)
- {
- opamp->CFG[preset_chn].CFG0 = (opamp->CFG[preset_chn].CFG0 & (~OPAMP_CFG_CFG0_VIM_SEL_MASK)) | OPAMP_CFG_CFG0_VIM_SEL_SET(select);
- }
- /**
- * @brief main string resistor selection
- *
- * @param opamp @ref OPAMP_Type
- * @param select @ref opamp_gain_t
- *
- */
- static inline void opamp_gain_select(OPAMP_Type *opamp, opamp_gain_t select)
- {
- opamp->CTRL0 = (opamp->CTRL0 & (~OPAMP_CTRL0_GAIN_SEL_MASK)) | OPAMP_CTRL0_GAIN_SEL_SET(select);
- }
- /**
- * @brief main string resistor selection preset
- *
- * @param opamp @ref OPAMP_Type
- * @param preset_chn preset channel
- * @param select @ref opamp_gain_t
- *
- */
- static inline void opamp_preset_gain_select(OPAMP_Type *opamp, uint8_t preset_chn, opamp_gain_t select)
- {
- opamp->CFG[preset_chn].CFG1 = (opamp->CFG[preset_chn].CFG1 & (~OPAMP_CFG_CFG1_GAIN_SEL_MASK)) | OPAMP_CFG_CFG1_GAIN_SEL_SET(select);
- }
- /**
- * @brief disconnect the main series resistor and VSSA
- *
- * @param opamp @ref OPAMP_Type
- */
- static inline void opamp_disconnect_vssa(OPAMP_Type *opamp)
- {
- opamp->CTRL0 |= OPAMP_CTRL0_VBYPASS_MASK;
- }
- /**
- * @brief disconnect the main series resistor and VSSA preset
- *
- * @param opamp @ref OPAMP_Type
- * @param preset_chn preset channel
- */
- static inline void opamp_preset_disconnect_vssa(OPAMP_Type *opamp, uint8_t preset_chn)
- {
- opamp->CFG[preset_chn].CFG1 |= OPAMP_CFG_CFG1_VBYPASS_LV_MASK;
- }
- /**
- * @brief connect the main series resistor and VSSA
- *
- * @param opamp @ref OPAMP_Type
- */
- static inline void opamp_connect_vssa(OPAMP_Type *opamp)
- {
- opamp->CTRL0 &= ~OPAMP_CTRL0_VBYPASS_MASK;
- }
- /**
- * @brief connect the main series resistor and VSSA preset
- *
- * @param opamp @ref OPAMP_Type
- * @param preset_chn preset channel
- */
- static inline void opamp_preset_connect_vssa(OPAMP_Type *opamp, uint8_t preset_chn)
- {
- opamp->CFG[preset_chn].CFG1 &= ~OPAMP_CFG_CFG1_VBYPASS_LV_MASK;
- }
- /**
- * @brief opamp inp select
- *
- * @param opamp @ref OPAMP_Type
- * @param select @ref opamp_inp_pad_t
- */
- static inline void opamp_inp_pad_select(OPAMP_Type *opamp, opamp_inp_pad_t select)
- {
- opamp->CTRL0 = (opamp->CTRL0 & (~OPAMP_CTRL0_VIP_SEL_MASK)) | OPAMP_CTRL0_VIP_SEL_SET(select);
- }
- /**
- * @brief opamp inp select preset
- *
- * @param opamp @ref OPAMP_Type
- * @param preset_chn preset channel
- * @param select @ref opamp_inp_pad_t
- */
- static inline void opamp_preset_inp_pad_select(OPAMP_Type *opamp, uint8_t preset_chn, opamp_inp_pad_t select)
- {
- opamp->CFG[preset_chn].CFG0 = (opamp->CFG[preset_chn].CFG0 & (~OPAMP_CFG_CFG0_VIP_SEL_MASK)) | OPAMP_CFG_CFG0_VIP_SEL_SET(select);
- }
- /**
- * @brief opamp get current preset
- *
- * @param opamp @ref OPAMP_Type
- * @return value
- */
- static inline uint8_t opamp_get_cur_preset(OPAMP_Type *opamp)
- {
- return OPAMP_STATUS_CUR_PRESET_GET(opamp->STATUS);
- }
- /**
- * @brief get the current preset value
- *
- * @param opamp @ref OPAMP_Type
- * @return true one of cur_preset is selected for opamp
- * @return false opamp use cfg0 parameters
- */
- static inline bool opamp_get_is_preset(OPAMP_Type *opamp)
- {
- return OPAMP_STATUS_PRESET_ACT_GET(opamp->STATUS);
- }
- /**
- * @brief Get the trigger conflict status
- *
- * @param opamp @ref OPAMP_Type
- * @return if more than one hardware trigger is set, will put all trigger input there.
- */
- static inline uint8_t opamp_get_trig_conflict_status(OPAMP_Type *opamp)
- {
- return OPAMP_STATUS_TRIG_CONFLICT_GET(opamp->STATUS);
- }
- /**
- * @brief Clear the trigger conflict status
- *
- * @param opamp @ref OPAMP_Type
- */
- static inline void opamp_clear_conflict_status(OPAMP_Type *opamp)
- {
- opamp->STATUS = OPAMP_STATUS_TRIG_CONFLICT_MASK;
- }
- /**
- * @brief Set opamp preset value
- *
- * @param opamp @ref OPAMP_Type
- * @param val @ref opamp_cfg_preset_chn_t
- */
- static inline void opamp_set_sw_preset_val(OPAMP_Type *opamp, opamp_cfg_preset_chn_t val)
- {
- opamp->CTRL1 = (opamp->CTRL1 & (~OPAMP_CTRL1_SW_SEL_MASK)) | OPAMP_CTRL1_SW_SEL_SET(val);
- }
- /**
- * @brief Enable software preset
- *
- * @param opamp @ref OPAMP_Type
- */
- static inline void opamp_enable_sw_preset(OPAMP_Type *opamp)
- {
- opamp->CTRL1 |= OPAMP_CTRL1_SW_PRESET_MASK;
- }
- /**
- * @brief Disable software preset
- *
- * @param opamp @ref OPAMP_Type
- */
- static inline void opamp_disable_sw_preset(OPAMP_Type *opamp)
- {
- opamp->CTRL1 &= ~OPAMP_CTRL1_SW_PRESET_MASK;
- }
- /**
- * @brief Set preset x channel value
- *
- * @param opamp @ref OPAMP_Type
- * @param preset_chn preset channel
- * @param chn channel
- */
- static inline void opamp_set_preset_x_chn(OPAMP_Type *opamp, uint8_t preset_chn, uint8_t chn)
- {
- opamp->CFG[preset_chn].CFG2 = OPAMP_CFG_CFG2_CHANNEL_SET(chn);
- }
- /**
- * @brief Set preset cfg
- *
- * @param opamp @ref OPAMP_Type
- * @param preset_chn preset channel
- * @param cfg @ref opamp_cfg_t
- * @return hpm_stat_t
- */
- hpm_stat_t opamp_set_preset_cfg(OPAMP_Type *opamp, uint8_t preset_chn, opamp_cfg_t *cfg);
- /**
- * @brief opamp enable preset hardware trig
- *
- * @param opamp @ref OPAMP_Type
- * @param preset_chn preset channel
- */
- static inline void opamp_preset_enable_hw_trig(OPAMP_Type *opamp, uint8_t preset_chn)
- {
- opamp->CFG[preset_chn].CFG1 |= OPAMP_CFG_CFG1_HW_TRIG_EN_MASK;
- }
- /**
- * @brief opamp disable preset hardware trig
- *
- * @param opamp @ref OPAMP_Type
- * @param preset_chn preset channel
- */
- static inline void opamp_preset_disable_hw_trig(OPAMP_Type *opamp, uint8_t preset_chn)
- {
- opamp->CFG[preset_chn].CFG1 &= ~OPAMP_CFG_CFG1_HW_TRIG_EN_MASK;
- }
- /**
- * @brief opamp set mode
- *
- * @param opamp @ref OPAMP_Type
- * @param mode OPAMP_MODE_XX
- */
- static inline void opamp_mode_set(OPAMP_Type *opamp, uint8_t mode)
- {
- opamp->CTRL0 = (opamp->CTRL0 & (~OPAMP_CTRL0_MODE_MASK)) | OPAMP_CTRL0_MODE_SET(mode);
- }
- /**
- * @brief opamp preset set mode
- *
- * @param opamp @ref OPAMP_Type
- * @param preset_chn preset channel
- * @param mode OPAMP_MODE_XX
- */
- static inline void opamp_preset_mode_set(OPAMP_Type *opamp, uint8_t preset_chn, uint8_t mode)
- {
- opamp->CFG[preset_chn].CFG1 = (opamp->CFG[preset_chn].CFG1 & (~OPAMP_CFG_CFG1_MODE_MASK)) | OPAMP_CFG_CFG1_MODE_SET(mode);
- }
- /**
- * @}
- *
- */
- #ifdef __cplusplus
- }
- #endif
- #endif /* HPM_ACMP_DRV_H */
|