123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- /*
- * Copyright (c) 2024 HPMicro
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
- #ifndef HPM_CLC_DRV_H
- #define HPM_CLC_DRV_H
- #include "hpm_common.h"
- #include "hpm_clc_regs.h"
- /**
- * @brief CLC driver APIs
- * @defgroup clc_interface CLC driver APIs
- * @ingroup motor_interfaces
- * @{
- */
- /**
- * @brief clc channel
- */
- typedef enum {
- clc_vd_chn = CLC_VDVQ_CHAN_VD,
- clc_vq_chn = CLC_VDVQ_CHAN_VQ,
- } clc_chn_t; /**< clc_chn_t */
- /**
- * @brief clc coefficient zone
- */
- typedef enum {
- clc_coeff_zone_0 = CLC_COEFF_0,
- clc_coeff_zone_1 = CLC_COEFF_1,
- clc_coeff_zone_2 = CLC_COEFF_2,
- } clc_coeff_zone_t; /**< clc_coeff_zone_t */
- /**
- * @brief clc irq mask bit
- */
- typedef enum {
- clc_irq_calc_done = BIT0_MASK,
- clc_irq_eadc_setting_err = BIT1_MASK,
- clc_irq_2p2z_clamp_setting_err = BIT2_MASK,
- clc_irq_2p2z_over_hi = BIT3_MASK,
- clc_irq_2p2z_over_lo = BIT4_MASK,
- clc_irq_2p2z_over_sf = BIT5_MASK,
- clc_irq_3p3z_clamp_setting_err = BIT6_MASK,
- clc_irq_3p3z_over_hi = BIT7_MASK,
- clc_irq_3p3z_over_lo = BIT8_MASK,
- clc_irq_forb_setting_err = BIT9_MASK,
- clc_irq_data_in_forbid = BIT10_MASK
- } clc_irq_mask_t;
- /**
- * @brief clc parameter configuration
- */
- typedef struct {
- int32_t eadc_lowth;
- int32_t eadc_mid_lowth;
- int32_t eadc_mid_highth;
- int32_t eadc_highth;
- int32_t _2p2z_clamp_lowth;
- int32_t _2p2z_clamp_highth;
- int32_t _3p3z_clamp_lowth;
- int32_t _3p3z_clamp_highth;
- int32_t output_forbid_lowth;
- int32_t output_forbid_mid;
- int32_t output_forbid_highth;
- } clc_param_config_t; /**< clc_param_config_t */
- /**
- * @brief clc coefficient configuration
- */
- typedef struct {
- float b0;
- float b1;
- float b2;
- float b3;
- float a0;
- float a1;
- float a2;
- } clc_coeff_config_t; /**< clc_coeff_config_t */
- #ifdef __cplusplus
- extern "C" {
- #endif
- /**
- * @brief CLC enable or disable
- *
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] enable true-enable, false-disable
- */
- static inline void clc_set_enable(CLC_Type *clc, clc_chn_t chn, bool enable)
- {
- if (enable) {
- clc->VDVQ_CHAN[chn].MODE |= CLC_VDVQ_CHAN_MODE_ENABLE_CLC_MASK;
- } else {
- clc->VDVQ_CHAN[chn].MODE &= ~CLC_VDVQ_CHAN_MODE_ENABLE_CLC_MASK;
- }
- }
- /**
- * @brief CLC keep working even if bad irq status ocurred
- *
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] enable true-enable, false-disable
- */
- static inline void clc_set_mask_mode_enable(CLC_Type *clc, clc_chn_t chn, bool enable)
- {
- if (enable) {
- clc->VDVQ_CHAN[chn].MODE |= CLC_VDVQ_CHAN_MODE_MASK_MODE_MASK;
- } else {
- clc->VDVQ_CHAN[chn].MODE &= ~CLC_VDVQ_CHAN_MODE_MASK_MODE_MASK;
- }
- }
- /**
- * @brief CLC set software inject dq work mode
- *
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] enable true-if the ADC value comes from software injection and the VD/VQ channel is required for joint use.
- */
- static inline void clc_set_sw_inject_dq_mode_enable(CLC_Type *clc, clc_chn_t chn, bool enable)
- {
- if (enable) {
- clc->VDVQ_CHAN[chn].MODE |= CLC_VDVQ_CHAN_MODE_DQ_MODE_MASK;
- } else {
- clc->VDVQ_CHAN[chn].MODE &= ~CLC_VDVQ_CHAN_MODE_DQ_MODE_MASK;
- }
- }
- /**
- * @brief CLC set irq enable or disable
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] irq_mask irq mask, @ref clc_irq_mask_t
- * @param[in] enable enable or disable
- * @arg true enable
- * @arg false disable
- */
- static inline void clc_set_irq_enable(CLC_Type *clc, clc_chn_t chn, uint32_t irq_mask, bool enable)
- {
- if (enable) {
- clc->VDVQ_CHAN[chn].MODE |= CLC_VDVQ_CHAN_MODE_ENABLE_IRQ_SET(irq_mask);
- } else {
- clc->VDVQ_CHAN[chn].MODE &= ~CLC_VDVQ_CHAN_MODE_ENABLE_IRQ_SET(irq_mask);
- }
- }
- /**
- * @brief CLC get irq status
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @retval irq status.
- */
- static inline uint32_t clc_get_irq_status(CLC_Type *clc, clc_chn_t chn)
- {
- return CLC_VDVQ_CHAN_STATUS_STATUS_GET(clc->VDVQ_CHAN[chn].STATUS);
- }
- /**
- * @brief CLC clear irq status
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] irq_mask irq mask, @ref clc_irq_mask_t
- */
- static inline void clc_clear_irq_status(CLC_Type *clc, clc_chn_t chn, uint32_t irq_mask)
- {
- clc->VDVQ_CHAN[chn].STATUS = CLC_VDVQ_CHAN_STATUS_STATUS_SET(irq_mask);
- }
- /**
- * @brief CLC check irq request flag
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] irq_mask irq mask, @ref clc_irq_mask_t
- * @retval true-has irq req, false-no irq req.
- */
- static inline bool clc_get_irq_flag(CLC_Type *clc, clc_chn_t chn, uint32_t irq_mask)
- {
- return ((clc->VDVQ_CHAN[chn].STATUS & irq_mask) == irq_mask) ? true : false;
- }
- /**
- * @brief CLC set adc channel
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] adc_chn adc channel for ADC0~3 or SDM_ADC0~7, adc from VSC must be set to 0.
- * @param[in] adc_offset adc offset for ADC0~3 or SDM_ADC0~7, adc from VSC must be set to 0.
- */
- static inline void clc_set_adc_chn_offset(CLC_Type *clc, clc_chn_t chn, uint32_t adc_chn, uint32_t adc_offset)
- {
- clc->VDVQ_CHAN[chn].ADC_CHAN = adc_chn;
- clc->VDVQ_CHAN[chn].ADC_OFFSET = adc_offset;
- }
- /**
- * @brief CLC set pwm period
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] pwm_period 0-clc dac output pwm duty ratio, else-clc dac output pwm period, number of clock cycles.
- */
- static inline void clc_set_pwm_period(CLC_Type *clc, clc_chn_t chn, uint32_t pwm_period)
- {
- clc->VDVQ_CHAN[chn].PWM_PERIOD = pwm_period;
- }
- /**
- * @brief CLC set pwm period
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @retval pwm period
- */
- static inline uint32_t clc_get_pwm_period(CLC_Type *clc, clc_chn_t chn)
- {
- return clc->VDVQ_CHAN[chn].PWM_PERIOD;
- }
- /**
- * @brief CLC get output caculated value
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @retval CLC output caculated value
- */
- static inline uint32_t clc_get_output_value(CLC_Type *clc, clc_chn_t chn)
- {
- return clc->VDVQ_CHAN[chn].OUTPUT_VALUE;
- }
- /**
- * @brief CLC get timestamp
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @retval CLC adc timestamp
- */
- static inline uint32_t clc_get_timestamp(CLC_Type *clc, clc_chn_t chn)
- {
- return clc->VDVQ_CHAN[chn].TIMESTAMP;
- }
- /**
- * @brief CLC get error adc latest value
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @retval CLC error adc latest value
- */
- static inline int32_t clc_get_eadc_current_value(CLC_Type *clc, clc_chn_t chn)
- {
- return (int32_t)clc->VDVQ_CHAN[chn].EADC_CURR;
- }
- /**
- * @brief CLC get error adc previous0 value
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @retval CLC error adc previous0 value
- */
- static inline int32_t clc_get_eadc_previous0_value(CLC_Type *clc, clc_chn_t chn)
- {
- return (int32_t)clc->VDVQ_CHAN[chn].EADC_PRE0;
- }
- /**
- * @brief CLC software inject error adc previous0 value
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] value CLC error adc previous0 value
- */
- static inline void clc_sw_inject_eadc_previous0_value(CLC_Type *clc, clc_chn_t chn, int32_t value)
- {
- clc->VDVQ_CHAN[chn].EADC_PRE0 = (uint32_t)value;
- }
- /**
- * @brief CLC get error adc previous1 value
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @retval CLC error adc previous1 value
- */
- static inline int32_t clc_get_eadc_previous1_value(CLC_Type *clc, clc_chn_t chn)
- {
- return (int32_t)clc->VDVQ_CHAN[chn].EADC_PRE1;
- }
- /**
- * @brief CLC software inject error adc previous1 value
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] value CLC error adc previous1 value
- */
- static inline void clc_sw_inject_eadc_previous1_value(CLC_Type *clc, clc_chn_t chn, int32_t value)
- {
- clc->VDVQ_CHAN[chn].EADC_PRE1 = (uint32_t)value;
- }
- /**
- * @brief CLC get 2p2z last value
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @retval CLC 2p2z last value
- */
- static inline int32_t clc_get_2p2z_current_value(CLC_Type *clc, clc_chn_t chn)
- {
- return (int32_t)clc->VDVQ_CHAN[chn].P2Z2_CURR;
- }
- /**
- * @brief CLC software inject 2p2z last value
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] value CLC 2p2z last value
- */
- static inline void clc_sw_inject_2p2z_current_value(CLC_Type *clc, clc_chn_t chn, int32_t value)
- {
- clc->VDVQ_CHAN[chn].P2Z2_CURR = (uint32_t)value;
- }
- /**
- * @brief CLC get 2p2z previous0 value
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @retval CLC 2p2z previous0 value
- */
- static inline int32_t clc_get_2p2z_previous0_value(CLC_Type *clc, clc_chn_t chn)
- {
- return (int32_t)clc->VDVQ_CHAN[chn].P2Z2_PRE0;
- }
- /**
- * @brief CLC software inject 2p2z previous0 value
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] value CLC 2p2z previous0 value
- */
- static inline void clc_sw_inject_2p2z_previous0_value(CLC_Type *clc, clc_chn_t chn, int32_t value)
- {
- clc->VDVQ_CHAN[chn].P2Z2_PRE0 = (uint32_t)value;
- }
- /**
- * @brief CLC get 3p3z last value
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @retval CLC 3p3z last value
- */
- static inline int32_t clc_get_3p3z_current_value(CLC_Type *clc, clc_chn_t chn)
- {
- return (int32_t)clc->VDVQ_CHAN[chn].P3Z3_CURR;
- }
- /**
- * @brief CLC software inject 3p3z last value
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] value CLC 3p3z last value
- */
- static inline void clc_sw_inject_3p3z_current_value(CLC_Type *clc, clc_chn_t chn, int32_t value)
- {
- clc->VDVQ_CHAN[chn].P3Z3_CURR = (uint32_t)value;
- }
- /**
- * @brief CLC set expected adc value
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] expect expected adc value
- */
- static inline void clc_set_expect_adc_value(CLC_Type *clc, clc_chn_t chn, int32_t expect)
- {
- clc->VDVQ_CHAN[chn].ADC_EXPECT = (uint32_t)expect;
- }
- /**
- * @brief CLC software inject adc value. If it's not dq mode, this will trig clc calculation.
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] value CLC adc value
- */
- static inline void clc_sw_inject_adc_value(CLC_Type *clc, clc_chn_t chn, uint32_t value)
- {
- clc->VDVQ_CHAN[chn].ADC_SW = value;
- }
- /**
- * @brief CLC set software inject dq adc value ready, this will trig clc calculation.
- * @param[in] clc CLC base address
- */
- static inline void clc_set_sw_inject_dq_adc_value_ready(CLC_Type *clc)
- {
- clc->DQ_ADC_SW_READY = CLC_DQ_ADC_SW_READY_DQ_ADC_SW_READY_MASK;
- }
- /**
- * @brief CLC parameter configuration
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] param @ref clc_param_config_t.
- */
- void clc_config_param(CLC_Type *clc, clc_chn_t chn, clc_param_config_t *param);
- /**
- * @brief CLC coefficient configuration
- * @param[in] clc CLC base address
- * @param[in] chn CLC channel, @ref clc_chn_t
- * @param[in] zone CLC coefficient zone, @ref clc_coeff_zone_t
- * @param[in] coeff @ref clc_param_config_t.
- *
- * @retval status_invalid_argument some parameters are invalid
- * @retval status_success operation is successful
- */
- hpm_stat_t clc_config_coeff(CLC_Type *clc, clc_chn_t chn, clc_coeff_zone_t zone, clc_coeff_config_t *coeff);
- /**
- * @brief CLC software inject dq adc value
- * @param[in] clc CLC base address
- * @param[in] d_value CLC d adc value
- * @param[in] q_value CLC q adc value
- */
- void clc_sw_inject_dq_adc_value(CLC_Type *clc, uint32_t d_value, uint32_t q_value);
- #ifdef __cplusplus
- }
- #endif
- /**
- * @}
- */
- #endif /* HPM_CLC_DRV_H */
|