1 /*
2  * Copyright (c) 2023 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "hpm_qeov2_drv.h"
9 
qeo_wave_get_default_mode_config(QEOV2_Type * base,qeo_wave_mode_t * config)10 void qeo_wave_get_default_mode_config(QEOV2_Type *base, qeo_wave_mode_t *config)
11 {
12     (void)base;
13 
14     config->wave0.above_max_limit = qeo_wave_above_max_limit_max_val;
15     config->wave0.high_area0_limit = qeo_wave_high_area_limit_max_val;
16     config->wave0.high_area1_limit = qeo_wave_high_area_limit_max_val;
17     config->wave0.low_area0_limit = qeo_wave_low_area_limit_zero;
18     config->wave0.low_area1_limit = qeo_wave_low_area_limit_zero;
19     config->wave0.below_min_limit = qeo_wave_below_min_limit_zero;
20 
21     config->wave1.above_max_limit = qeo_wave_above_max_limit_max_val;
22     config->wave1.high_area0_limit = qeo_wave_high_area_limit_max_val;
23     config->wave1.high_area1_limit = qeo_wave_high_area_limit_max_val;
24     config->wave1.low_area0_limit = qeo_wave_low_area_limit_zero;
25     config->wave1.low_area1_limit = qeo_wave_low_area_limit_zero;
26     config->wave1.below_min_limit = qeo_wave_below_min_limit_zero;
27 
28     config->wave2.above_max_limit = qeo_wave_above_max_limit_max_val;
29     config->wave2.high_area0_limit = qeo_wave_high_area_limit_max_val;
30     config->wave2.high_area1_limit = qeo_wave_high_area_limit_max_val;
31     config->wave2.low_area0_limit = qeo_wave_low_area_limit_zero;
32     config->wave2.low_area1_limit = qeo_wave_low_area_limit_zero;
33     config->wave2.below_min_limit = qeo_wave_below_min_limit_zero;
34 
35     config->dq_valid_trig_enable = false;
36     config->pos_valid_trig_enable = true;
37     config->vd_vq_inject_enable = false;
38     config->vd_vq_from_sw = false;
39 
40     config->saddle_type = 0;
41     config->wave_type = qeo_wave_cosine;
42 }
43 
qeo_wave_config_mode(QEOV2_Type * base,qeo_wave_mode_t * config)44 void qeo_wave_config_mode(QEOV2_Type *base, qeo_wave_mode_t *config)
45 {
46     base->WAVE.MODE = QEOV2_WAVE_MODE_WAVE2_ABOVE_MAX_LIMIT_SET(config->wave2.above_max_limit)
47                     | QEOV2_WAVE_MODE_WAVE2_HIGH_AREA1_LIMIT_SET(config->wave2.high_area1_limit)
48                     | QEOV2_WAVE_MODE_WAVE2_HIGH_AREA0_LIMIT_SET(config->wave2.high_area0_limit)
49                     | QEOV2_WAVE_MODE_WAVE2_LOW_AREA1_LIMIT_SET(config->wave2.low_area1_limit)
50                     | QEOV2_WAVE_MODE_WAVE2_LOW_AREA0_LIMIT_SET(config->wave2.low_area0_limit)
51                     | QEOV2_WAVE_MODE_WAVE2_BELOW_MIN_LIMIT_SET(config->wave2.below_min_limit)
52 
53                     | QEOV2_WAVE_MODE_WAVE1_ABOVE_MAX_LIMIT_SET(config->wave1.above_max_limit)
54                     | QEOV2_WAVE_MODE_WAVE1_HIGH_AREA1_LIMIT_SET(config->wave1.high_area1_limit)
55                     | QEOV2_WAVE_MODE_WAVE1_HIGH_AREA0_LIMIT_SET(config->wave1.high_area0_limit)
56                     | QEOV2_WAVE_MODE_WAVE1_LOW_AREA1_LIMIT_SET(config->wave1.low_area1_limit)
57                     | QEOV2_WAVE_MODE_WAVE1_LOW_AREA0_LIMIT_SET(config->wave1.low_area0_limit)
58                     | QEOV2_WAVE_MODE_WAVE1_BELOW_MIN_LIMIT_SET(config->wave1.below_min_limit)
59 
60                     | QEOV2_WAVE_MODE_WAVE0_ABOVE_MAX_LIMIT_SET(config->wave0.above_max_limit)
61                     | QEOV2_WAVE_MODE_WAVE0_HIGH_AREA1_LIMIT_SET(config->wave0.high_area1_limit)
62                     | QEOV2_WAVE_MODE_WAVE0_HIGH_AREA0_LIMIT_SET(config->wave0.high_area0_limit)
63                     | QEOV2_WAVE_MODE_WAVE0_LOW_AREA1_LIMIT_SET(config->wave0.low_area1_limit)
64                     | QEOV2_WAVE_MODE_WAVE0_LOW_AREA0_LIMIT_SET(config->wave0.low_area0_limit)
65                     | QEOV2_WAVE_MODE_WAVE0_BELOW_MIN_LIMIT_SET(config->wave0.below_min_limit)
66                     | QEOV2_WAVE_MODE_SADDLE_TYPE_SET(config->saddle_type)
67                     | QEOV2_WAVE_MODE_WAVES_OUTPUT_TYPE_SET(config->wave_type)
68                     | QEOV2_WAVE_MODE_ENABLE_DQ_VALID_SET(config->dq_valid_trig_enable)
69                     | QEOV2_WAVE_MODE_ENABLE_POS_VALID_SET(config->pos_valid_trig_enable)
70                     | QEOV2_WAVE_MODE_EN_WAVE_VD_VQ_INJECT_SET(config->vd_vq_inject_enable)
71                     | QEOV2_WAVE_MODE_VD_VQ_SEL_SET(config->vd_vq_from_sw);
72 }
73 
qeo_abz_get_default_mode_config(QEOV2_Type * base,qeo_abz_mode_t * config)74 void qeo_abz_get_default_mode_config(QEOV2_Type *base, qeo_abz_mode_t *config)
75 {
76     (void)base;
77 
78     config->a_inv_pol = false;
79     config->b_inv_pol = false;
80     config->z_inv_pol = false;
81     config->enable_wdog = false;
82     config->sync_step_position = true;
83     config->reverse_align_clk_falling_edge = false;
84     config->output_type = qeo_abz_output_abz;
85 }
86 
qeo_abz_config_mode(QEOV2_Type * base,qeo_abz_mode_t * config)87 void qeo_abz_config_mode(QEOV2_Type *base, qeo_abz_mode_t *config)
88 {
89     base->ABZ.MODE &= ~(QEOV2_ABZ_MODE_Z_POLARITY_MASK
90                         | QEOV2_ABZ_MODE_B_POLARITY_MASK
91                         | QEOV2_ABZ_MODE_A_POLARITY_MASK
92                         | QEOV2_ABZ_MODE_Z_TYPE_MASK
93                         | QEOV2_ABZ_MODE_B_TYPE_MASK
94                         | QEOV2_ABZ_MODE_A_TYPE_MASK
95                         | QEOV2_ABZ_MODE_REVERSE_EDGE_TYPE_MASK
96                         | QEOV2_ABZ_MODE_POSITION_SYNC_MODE_MASK
97                         | QEOV2_ABZ_MODE_EN_WDOG_MASK);
98 
99     base->ABZ.MODE = QEOV2_ABZ_MODE_Z_POLARITY_SET(config->z_inv_pol)
100                     | QEOV2_ABZ_MODE_B_POLARITY_SET(config->b_inv_pol)
101                     | QEOV2_ABZ_MODE_A_POLARITY_SET(config->a_inv_pol)
102                     | QEOV2_ABZ_MODE_REVERSE_EDGE_TYPE_SET(config->reverse_align_clk_falling_edge)
103                     | QEOV2_ABZ_MODE_POSITION_SYNC_MODE_SET(config->sync_step_position)
104                     | QEOV2_ABZ_MODE_EN_WDOG_SET(config->enable_wdog)
105                     | QEOV2_ABZ_MODE_B_TYPE_SET(config->output_type)
106                     | QEOV2_ABZ_MODE_A_TYPE_SET(config->output_type);
107 
108     if ((config->output_type == qeo_abz_output_pulse_revise) || (config->output_type == qeo_abz_output_up_down)) {
109         base->ABZ.MODE |= QEOV2_ABZ_MODE_Z_TYPE_SET(qeo_z_as_no_output_signal);
110     } else if (config->output_type == qeo_abz_output_three_phase) {
111         base->ABZ.MODE |= QEOV2_ABZ_MODE_Z_TYPE_SET(qeo_z_as_third_phase_signal);
112     } else {
113         base->ABZ.MODE |= QEOV2_ABZ_MODE_Z_TYPE_SET(qeo_z_as_zero_signal_mode0);
114     }
115 }
116 
qeo_abz_get_default_z_output_mode(QEOV2_Type * base,qeo_z_output_mode_t * mode)117 void qeo_abz_get_default_z_output_mode(QEOV2_Type *base, qeo_z_output_mode_t *mode)
118 {
119     (void)base;
120 
121     /* z output width 1/4 ab period */
122     mode->type = qeo_z_as_zero_signal_mode0;
123     mode->start_line = 0;
124     mode->end_line = 0;
125     mode->start_step = 0;
126     mode->end_step = 0;
127     mode->width = 0; /* used for qeo_z_as_zero_signal_mode1 */
128 }
129 
qeo_abz_config_z_output_mode(QEOV2_Type * base,qeo_z_output_mode_t * mode)130 void qeo_abz_config_z_output_mode(QEOV2_Type *base, qeo_z_output_mode_t *mode)
131 {
132     if (mode->type == qeo_z_as_zero_signal_mode0) {
133         base->ABZ.Z_START = mode->start_line;
134         base->ABZ.Z_END = mode->end_line;
135         base->ABZ.Z_OFFSET = QEOV2_ABZ_Z_OFFSET_Z_START_OFFSET_SET(mode->start_step) | QEOV2_ABZ_Z_OFFSET_Z_END_OFFSET_SET(mode->end_step);
136     } else if (mode->type == qeo_z_as_zero_signal_mode1) {
137         base->ABZ.Z_START = mode->start_line;
138         base->ABZ.Z_PULSE_WIDTH = mode->width;
139     }
140 
141     base->ABZ.MODE = (base->ABZ.MODE & ~QEOV2_ABZ_MODE_Z_TYPE_MASK) | QEOV2_ABZ_MODE_Z_TYPE_SET(mode->type);
142 }
143 
qeo_abz_set_max_frequency(QEOV2_Type * base,uint32_t src_freq,uint32_t freq)144 hpm_stat_t qeo_abz_set_max_frequency(QEOV2_Type *base, uint32_t src_freq, uint32_t freq)
145 {
146     uint32_t count;
147 
148     if ((freq > 0xffffffffU / 4U) || ((src_freq % (freq * 4U)) != 0)) {
149         return status_invalid_argument;
150     }
151     count = src_freq / (freq * 4U);
152     base->ABZ.LINE_WIDTH = QEOV2_ABZ_LINE_WIDTH_LINE_SET(count);
153 
154     return status_success;
155 }
156 
qeo_abz_set_wdog_frequency(QEOV2_Type * base,uint32_t src_freq,uint32_t freq)157 hpm_stat_t qeo_abz_set_wdog_frequency(QEOV2_Type *base, uint32_t src_freq, uint32_t freq)
158 {
159     uint32_t count;
160 
161     if ((src_freq % freq) != 0) {
162         return status_invalid_argument;
163     }
164     count = src_freq / freq;
165     base->ABZ.WDOG_WIDTH = QEOV2_ABZ_WDOG_WIDTH_WIDTH_SET(count);
166     base->ABZ.MODE |= QEOV2_ABZ_MODE_EN_WDOG_MASK;
167 
168     return status_success;
169 }
170 
qeo_pwm_get_default_safety_table_config(QEOV2_Type * base,qeo_pwm_safety_output_table_t * table)171 void qeo_pwm_get_default_safety_table_config(QEOV2_Type *base, qeo_pwm_safety_output_table_t *table)
172 {
173     (void)base;
174 
175     table->pwm7_output = qeo_pwm_safety_output_highz;
176     table->pwm6_output = qeo_pwm_safety_output_highz;
177     table->pwm5_output = qeo_pwm_safety_output_highz;
178     table->pwm4_output = qeo_pwm_safety_output_highz;
179     table->pwm3_output = qeo_pwm_safety_output_highz;
180     table->pwm2_output = qeo_pwm_safety_output_highz;
181     table->pwm1_output = qeo_pwm_safety_output_highz;
182     table->pwm0_output = qeo_pwm_safety_output_highz;
183 }
184 
qeo_pwm_get_default_phase_table_config(QEOV2_Type * base,qeo_pwm_phase_output_table_t * table)185 void qeo_pwm_get_default_phase_table_config(QEOV2_Type *base, qeo_pwm_phase_output_table_t *table)
186 {
187     (void)base;
188 
189     table->pwm7_output = qeo_pwm_output_force_0;
190     table->pwm6_output = qeo_pwm_output_force_0;
191     table->pwm5_output = qeo_pwm_output_force_0;
192     table->pwm4_output = qeo_pwm_output_force_0;
193     table->pwm3_output = qeo_pwm_output_force_0;
194     table->pwm2_output = qeo_pwm_output_force_0;
195     table->pwm1_output = qeo_pwm_output_force_0;
196     table->pwm0_output = qeo_pwm_output_force_0;
197 }
198 
qeo_pwm_get_default_mode_config(QEOV2_Type * base,qeo_pwm_mode_t * config)199 void qeo_pwm_get_default_mode_config(QEOV2_Type *base, qeo_pwm_mode_t *config)
200 {
201     (void)base;
202 
203     config->phase_num = 4;
204     config->shield_hardware_trig_safety = false;
205     config->revise_pairs_output = false;
206 }
207 
qeo_pwm_config_mode(QEOV2_Type * base,qeo_pwm_mode_t * config)208 void qeo_pwm_config_mode(QEOV2_Type *base, qeo_pwm_mode_t *config)
209 {
210     base->PWM.MODE &= ~(QEOV2_PWM_MODE_PWM_SAFETY_BYPASS_MASK
211                         | QEOV2_PWM_MODE_REVISE_UP_DN_MASK
212                         | QEOV2_PWM_MODE_PHASE_NUM_MASK);
213     base->PWM.MODE |= QEOV2_PWM_MODE_PWM_SAFETY_BYPASS_SET(config->shield_hardware_trig_safety)
214                     | QEOV2_PWM_MODE_REVISE_UP_DN_SET(config->revise_pairs_output)
215                     | QEOV2_PWM_MODE_PHASE_NUM_SET(config->phase_num);
216 }
217 
qeo_pwm_config_phase_table(QEOV2_Type * base,uint8_t index,qeo_pwm_phase_output_table_t * table)218 void qeo_pwm_config_phase_table(QEOV2_Type *base, uint8_t index, qeo_pwm_phase_output_table_t *table)
219 {
220     base->PWM.PHASE_TABLE[index] = QEOV2_PWM_PHASE_TABLE_PWM7_SET(table->pwm7_output)
221                                 | QEOV2_PWM_PHASE_TABLE_PWM6_SET(table->pwm6_output)
222                                 | QEOV2_PWM_PHASE_TABLE_PWM5_SET(table->pwm5_output)
223                                 | QEOV2_PWM_PHASE_TABLE_PWM4_SET(table->pwm4_output)
224                                 | QEOV2_PWM_PHASE_TABLE_PWM3_SET(table->pwm3_output)
225                                 | QEOV2_PWM_PHASE_TABLE_PWM2_SET(table->pwm2_output)
226                                 | QEOV2_PWM_PHASE_TABLE_PWM1_SET(table->pwm1_output)
227                                 | QEOV2_PWM_PHASE_TABLE_PWM0_SET(table->pwm0_output);
228 }
229 
qeo_pwm_config_safety_table(QEOV2_Type * base,qeo_pwm_safety_output_table_t * table)230 void qeo_pwm_config_safety_table(QEOV2_Type *base, qeo_pwm_safety_output_table_t *table)
231 {
232     /*< clear safety table */
233     base->PWM.MODE &= ~(QEOV2_PWM_MODE_PWM7_SAFETY_MASK
234                     | QEOV2_PWM_MODE_PWM6_SAFETY_MASK
235                     | QEOV2_PWM_MODE_PWM5_SAFETY_MASK
236                     | QEOV2_PWM_MODE_PWM4_SAFETY_MASK
237                     | QEOV2_PWM_MODE_PWM3_SAFETY_MASK
238                     | QEOV2_PWM_MODE_PWM2_SAFETY_MASK
239                     | QEOV2_PWM_MODE_PWM1_SAFETY_MASK
240                     | QEOV2_PWM_MODE_PWM0_SAFETY_MASK);
241     /*< set safety table */
242     base->PWM.MODE |= QEOV2_PWM_MODE_PWM7_SAFETY_SET(table->pwm7_output)
243                     | QEOV2_PWM_MODE_PWM6_SAFETY_SET(table->pwm6_output)
244                     | QEOV2_PWM_MODE_PWM5_SAFETY_SET(table->pwm5_output)
245                     | QEOV2_PWM_MODE_PWM4_SAFETY_SET(table->pwm4_output)
246                     | QEOV2_PWM_MODE_PWM3_SAFETY_SET(table->pwm3_output)
247                     | QEOV2_PWM_MODE_PWM2_SAFETY_SET(table->pwm2_output)
248                     | QEOV2_PWM_MODE_PWM1_SAFETY_SET(table->pwm1_output)
249                     | QEOV2_PWM_MODE_PWM0_SAFETY_SET(table->pwm0_output);
250 }
251