1 /*
2  * Copyright (c) 2024 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef HPM_VSC_DRV_H
9 #define HPM_VSC_DRV_H
10 
11 #include "hpm_common.h"
12 #include "hpm_vsc_regs.h"
13 
14 /**
15  * @brief VSC driver APIs
16  * @defgroup vsc_interface VSC driver APIs
17  * @ingroup motor_interfaces
18  * @{
19  */
20 
21 /**
22  * @brief vsc phase mode
23  *
24  */
25 typedef enum vsc_phase_mode {
26     vsc_abc_phase = 0,
27     vsc_ab_phase = 1,
28 } vsc_phase_mode_t; /**< vsc_phase_mode_t */
29 
30 /**
31  * @brief vsc data operation mode
32  *
33  */
34 typedef enum vsc_data_opr_mode {
35     vsc_data_opr_plus_mul_1 = 0,
36     vsc_data_opr_plus_mul_2 = 1,
37     vsc_data_opr_plus_div_2 = 5,
38     vsc_data_opr_plus_div_3 = 6,
39     vsc_data_opr_plus_div_4 = 7,
40     vsc_data_opr_minus_mul_1 = 8,
41     vsc_data_opr_minus_mul_2 = 9,
42     vsc_data_opr_minus_div_2 = 13,
43     vsc_data_opr_minus_div_3 = 14,
44     vsc_data_opr_minus_div_4 = 15
45 } vsc_data_opr_mode_t; /**< vsc_data_opr_mode_t */
46 
47 /**
48  * @brief vsc select adc instance
49  *
50  */
51 typedef enum vsc_adc_sel {
52     vsc_sel_adc0 = 1,
53     vsc_sel_adc1 = 2,
54     vsc_sel_adc2 = 3
55 } vsc_adc_sel_t; /**< vsc_adc_sel_t */
56 
57 /**
58  * @brief vsc position capture mode
59  *
60  */
61 typedef enum vsc_pos_cap_mode {
62     vsc_pos_use_last_data_when_adc_sample_finish = 0,
63     vsc_pos_use_first_data_after_adc_sample_start = 1,
64     vsc_pos_use_last_data_before_adc_sample_start = 2
65 } vsc_pos_cap_mode_t; /**< vsc_pos_cap_mode_t */
66 
67 /**
68  * @brief vsc select adc timestamp
69  *
70  */
71 typedef enum vsc_timestamp_sel {
72     vsc_timestamp_sel_value_a = 1,
73     vsc_timestamp_sel_value_b = 2,
74     vsc_timestamp_sel_value_c = 3
75 } vsc_timestamp_sel_t; /**< vsc_timestamp_sel_t */
76 
77 /**
78  * @brief vsc irq mask bit
79  *
80  */
81 typedef enum vsc_irq_mask {
82     vsc_irq_convert_done = BIT0_MASK,
83     vsc_irq_abc_over_tolerate = BIT1_MASK,
84     vsc_irq_c_overflow = BIT2_MASK,
85     vsc_irq_b_overflow = BIT3_MASK,
86     vsc_irq_a_overflow = BIT4_MASK,
87     vsc_irq_adc2_cap_not_enough = BIT5_MASK,
88     vsc_irq_adc1_cap_not_enough = BIT6_MASK,
89     vsc_irq_adc0_cap_not_enough = BIT7_MASK,
90     vsc_irq_pos_timeout = BIT8_MASK,
91     vsc_irq_adc2_timeout = BIT9_MASK,
92     vsc_irq_adc1_timeout = BIT10_MASK,
93     vsc_irq_adc0_timeout = BIT11_MASK,
94     vsc_irq_convert_conflict = BIT12_MASK
95 } vsc_irq_mask_t;
96 
97 /**
98  * @brief adc config structure
99  */
100 typedef struct {
101     vsc_adc_sel_t adc_sel;
102     uint8_t adc_chn;
103     uint32_t adc_offset;
104 } vsc_adc_config_t;
105 
106 /**
107  * @brief vsc config structure
108  */
109 typedef struct {
110     vsc_data_opr_mode_t opr_0;
111     vsc_data_opr_mode_t opr_1;
112     vsc_data_opr_mode_t opr_2;
113     vsc_data_opr_mode_t opr_3;
114 } vsc_data_opr_config_t;
115 
116 /**
117  * @brief vsc config structure
118  */
119 typedef struct {
120     vsc_phase_mode_t phase_mode;
121     uint8_t a_data_cnt;
122     uint8_t b_data_cnt;
123     uint8_t c_data_cnt;
124     vsc_data_opr_config_t a_data_opr_config;
125     vsc_data_opr_config_t b_data_opr_config;
126     vsc_data_opr_config_t c_data_opr_config;
127     vsc_adc_config_t a_adc_config;
128     vsc_adc_config_t b_adc_config;
129     vsc_adc_config_t c_adc_config;
130     vsc_pos_cap_mode_t pos_cap_mode;
131     uint16_t pole_pairs;
132 } vsc_config_t;
133 
134 
135 #ifdef __cplusplus
136 extern "C" {
137 #endif
138 
139 /**
140  * @brief vsc enable or disable
141  *
142  * @param[in] vsc VSC base address
143  * @param[in] enable true-enable, false-disable
144  */
vsc_set_enable(VSC_Type * vsc,bool enable)145 static inline void vsc_set_enable(VSC_Type *vsc, bool enable)
146 {
147     if (enable) {
148         vsc->ABC_MODE |= VSC_ABC_MODE_ENABLE_VSC_MASK;
149     } else {
150         vsc->ABC_MODE &= ~VSC_ABC_MODE_ENABLE_VSC_MASK;
151     }
152 }
153 
154 /**
155  * @brief vsc config position capture mode
156  *
157  * @param[in] vsc VSC base address
158  * @param[in] mode @ref vsc_pos_cap_mode_t
159  */
vsc_config_pos_capture_mode(VSC_Type * vsc,vsc_pos_cap_mode_t mode)160 static inline void vsc_config_pos_capture_mode(VSC_Type *vsc, vsc_pos_cap_mode_t mode)
161 {
162     vsc->TIMELOCK = (vsc->TIMELOCK & ~(VSC_TIMELOCK_POSITION_CAPTURE_MODE_MASK))
163                     | VSC_TIMELOCK_POSITION_CAPTURE_MODE_SET(mode);
164 }
165 
166 /**
167  * @brief vsc config adc timestamp
168  *
169  * @param[in] vsc VSC base address
170  * @param[in] select timestamp select from value a/b/c. @ref vsc_timestamp_sel_t
171  * @param[in] num timestamp use which number index of @ref vsc_timestamp_sel_t used.
172  */
vsc_config_adc_timestamp(VSC_Type * vsc,vsc_timestamp_sel_t select,uint8_t num)173 static inline void vsc_config_adc_timestamp(VSC_Type *vsc, vsc_timestamp_sel_t select, uint8_t num)
174 {
175     vsc->TIMELOCK = (vsc->TIMELOCK & ~(VSC_TIMELOCK_ADC_TIMESTAMP_SEL_MASK | VSC_TIMELOCK_VALUE_COUNTER_SEL_MASK))
176                     | VSC_TIMELOCK_ADC_TIMESTAMP_SEL_SET(select) | VSC_TIMELOCK_VALUE_COUNTER_SEL_SET(num);
177 }
178 
179 /**
180  * @brief vsc set irq enable or disable
181  * @param [in] vsc CLC base address
182  * @param [in] irq_mask irq mask, @ref vsc_irq_mask_t
183  * @param [in] enable enable or disable
184  *  @arg true enable
185  *  @arg false disable
186  */
vsc_set_irq_enable(VSC_Type * vsc,uint32_t irq_mask,bool enable)187 static inline void vsc_set_irq_enable(VSC_Type *vsc, uint32_t irq_mask, bool enable)
188 {
189     if (enable) {
190         vsc->IRQ_ENABLE |= irq_mask;
191     } else {
192         vsc->IRQ_ENABLE &= ~irq_mask;
193     }
194 }
195 
196 /**
197  * @brief vsc get irq status
198  * @param [in] vsc CLC base address
199 
200  * @retval irq status.
201  */
vsc_get_irq_status(VSC_Type * vsc)202 static inline uint32_t vsc_get_irq_status(VSC_Type *vsc)
203 {
204     return vsc->IRQ_STATUS;
205 }
206 
207 /**
208  * @brief vsc clear irq status
209  * @param [in] vsc CLC base address
210  * @param [in] irq_mask irq mask, @ref vsc_irq_mask_t
211  */
vsc_clear_irq_status(VSC_Type * vsc,uint32_t irq_mask)212 static inline void vsc_clear_irq_status(VSC_Type *vsc, uint32_t irq_mask)
213 {
214     vsc->IRQ_STATUS = irq_mask;
215 }
216 
217 /**
218  * @brief vsc check irq request flag
219  * @param [in] vsc CLC base address
220  * @param [in] irq_mask irq mask, @ref vsc_irq_mask_t
221 
222  * @retval true-has irq req, false-no irq req.
223  */
vsc_get_irq_flag(VSC_Type * vsc,uint32_t irq_mask)224 static inline bool vsc_get_irq_flag(VSC_Type *vsc, uint32_t irq_mask)
225 {
226     return ((vsc->IRQ_STATUS & irq_mask) == irq_mask) ? true : false;
227 }
228 
229 /**
230  * @brief vsc set adc wait cycles
231  * @param [in] vsc CLC base address
232  * @param [in] wait_cycle adc wait cycle for exception
233  */
vsc_set_adc_wait_cycle(VSC_Type * vsc,uint32_t wait_cycle)234 static inline void vsc_set_adc_wait_cycle(VSC_Type *vsc, uint32_t wait_cycle)
235 {
236     vsc->ADC_WAIT_CYCLE = VSC_ADC_WAIT_CYCLE_ADC_WAIT_CYCLE_SET(wait_cycle);
237 }
238 
239 /**
240  * @brief vsc set position wait cycles
241  * @param [in] vsc CLC base address
242  * @param [in] wait_cycle position wait cycle for exception
243  */
vsc_set_pos_wait_cycle(VSC_Type * vsc,uint32_t wait_cycle)244 static inline void vsc_set_pos_wait_cycle(VSC_Type *vsc, uint32_t wait_cycle)
245 {
246     vsc->POS_WAIT_CYCLE = VSC_POS_WAIT_CYCLE_POS_WAIT_CYCLE_SET(wait_cycle);
247 }
248 
249 /**
250  * @brief vsc set abc phase value tolerate
251  * @param [in] vsc CLC base address
252  * @param [in] tolerate value a/b/c total value tolerate
253  */
vsc_set_adc_tolerate(VSC_Type * vsc,uint32_t tolerate)254 static inline void vsc_set_adc_tolerate(VSC_Type *vsc, uint32_t tolerate)
255 {
256     vsc->ADC_PHASE_TOLERATE = VSC_ADC_PHASE_TOLERATE_ADC_PHASE_TOLERATE_SET(tolerate);
257 }
258 
259 /**
260  * @brief vsc set position pole pairs
261  * @param [in] vsc CLC base address
262  * @param [in] pole_pairs pole pairs number
263  */
vsc_set_pos_pole_pairs(VSC_Type * vsc,uint32_t pole_pairs)264 static inline void vsc_set_pos_pole_pairs(VSC_Type *vsc, uint32_t pole_pairs)
265 {
266     vsc->POS_POLE = (vsc->POS_POLE & ~VSC_POS_POLE_POS_POLE_MASK) | VSC_POS_POLE_POS_POLE_SET(pole_pairs);
267 }
268 
269 /**
270  * @brief vsc set software trigger in
271  * @param [in] vsc CLC base address
272  */
vsc_set_sw_trig_in(VSC_Type * vsc)273 static inline void vsc_set_sw_trig_in(VSC_Type *vsc)
274 {
275     vsc->TRIGGER_SW = VSC_TRIGGER_SW_TRIGGER_SW_MASK;
276 }
277 
278 /**
279  * @brief vsc get d-axis value
280  * @param [in] vsc CLC base address
281  * @param [in] positive_seq true - positive order; false - reverse order
282  * @retval d-axis value
283  */
vsc_get_d_axis_value(VSC_Type * vsc,bool positive_seq)284 static inline int32_t vsc_get_d_axis_value(VSC_Type *vsc, bool positive_seq)
285 {
286     if (positive_seq) {
287         return (int32_t)vsc->ID_POSEDGE;
288     } else {
289         return (int32_t)vsc->ID_NEGEDGE;
290     }
291 }
292 
293 /**
294  * @brief vsc get q-axis value
295  * @param [in] vsc CLC base address
296  * @param [in] positive_seq true - positive order; false - reverse order
297  * @retval q-axis value
298  */
vsc_get_q_axis_value(VSC_Type * vsc,bool positive_seq)299 static inline int32_t vsc_get_q_axis_value(VSC_Type *vsc, bool positive_seq)
300 {
301     if (positive_seq) {
302         return (int32_t)vsc->IQ_POSEDGE;
303     } else {
304         return (int32_t)vsc->IQ_NEGEDGE;
305     }
306 }
307 
308 /**
309  * @brief vsc get alpha-axis value
310  * @param [in] vsc CLC base address
311  * @param [in] positive_seq true - positive order; false - reverse order
312  * @retval alpha-axis value
313  */
vsc_get_alpha_axis_value(VSC_Type * vsc,bool positive_seq)314 static inline int32_t vsc_get_alpha_axis_value(VSC_Type *vsc, bool positive_seq)
315 {
316     if (positive_seq) {
317         return (int32_t)vsc->ALPHA_POSEDGE;
318     } else {
319         return (int32_t)vsc->ALPHA_NEGEDGE;
320     }
321 }
322 
323 /**
324  * @brief vsc get beta-axis value
325  * @param [in] vsc CLC base address
326  * @param [in] positive_seq true - positive order; false - reverse order
327  * @retval beta-axis value
328  */
vsc_get_beta_axis_value(VSC_Type * vsc,bool positive_seq)329 static inline int32_t vsc_get_beta_axis_value(VSC_Type *vsc, bool positive_seq)
330 {
331     if (positive_seq) {
332         return (int32_t)vsc->BETA_POSEDGE;
333     } else {
334         if (vsc->BETA_NEGEDGE == 0x80000000) {
335             return 0x7FFFFFFF;
336         } else {
337             return (int32_t)vsc->BETA_NEGEDGE;
338         }
339     }
340 }
341 
342 /**
343  * @brief vsc get adc timestamp value
344  * @param [in] vsc CLC base address
345  * @retval adc timestamp value
346  */
vsc_get_adc_timestamp(VSC_Type * vsc)347 static inline uint32_t vsc_get_adc_timestamp(VSC_Type *vsc)
348 {
349     return vsc->TIMESTAMP_LOCKED;
350 }
351 
352 /**
353  * @brief vsc get default config
354  *
355  * @param[in] vsc VSC base address
356  * @param[out] config vsc default config
357  */
358 void vsc_get_default_config(VSC_Type *vsc, vsc_config_t *config);
359 
360 /**
361  * @brief vsc config initialization
362  *
363  * @param[in] vsc VSC base address
364  * @param[in] config vsc config struct
365  */
366 void vsc_config_init(VSC_Type *vsc, vsc_config_t *config);
367 
368 /**
369  * @brief vsc software inject phase a/b/c value
370  *
371  * @param[in] vsc VSC base address
372  * @param[in] value_a phase a value
373  * @param[in] value_b phase b value
374  * @param[in] value_c phase c value
375  */
376 void vsc_sw_inject_abc_value(VSC_Type *vsc, int32_t value_a, int32_t value_b, int32_t value_c);
377 
378 /**
379  * @brief vsc software inject position value
380  *
381  * @param[in] vsc VSC base address
382  * @param[in] pos position value
383  */
384 void vsc_sw_inject_pos_value(VSC_Type *vsc, uint32_t pos);
385 
386 
387 #ifdef __cplusplus
388 }
389 #endif
390 /**
391  * @}
392  */
393 #endif /* HPM_VSC_DRV_H */
394