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