• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "hpm_qeo_drv.h"
9 
qeo_wave_get_default_mode_config(QEO_Type * base,qeo_wave_mode_t * config)10 void qeo_wave_get_default_mode_config(QEO_Type *base, qeo_wave_mode_t *config)
11 {
12     (void) base;
13     config->wave0.above_max_limit = qeo_wave_above_max_limit_max_val;
14     config->wave0.high_area0_limit = qeo_wave_high_area_limit_max_val;
15     config->wave0.high_area1_limit = qeo_wave_high_area_limit_max_val;
16     config->wave0.low_area0_limit = qeo_wave_low_area_limit_zero;
17     config->wave0.low_area1_limit = qeo_wave_low_area_limit_zero;
18     config->wave0.below_min_limit = qeo_wave_below_min_limit_zero;
19 
20     config->wave1.above_max_limit = qeo_wave_above_max_limit_max_val;
21     config->wave1.high_area0_limit = qeo_wave_high_area_limit_max_val;
22     config->wave1.high_area1_limit = qeo_wave_high_area_limit_max_val;
23     config->wave1.low_area0_limit = qeo_wave_low_area_limit_zero;
24     config->wave1.low_area1_limit = qeo_wave_low_area_limit_zero;
25     config->wave1.below_min_limit = qeo_wave_below_min_limit_zero;
26 
27     config->wave2.above_max_limit = qeo_wave_above_max_limit_max_val;
28     config->wave2.high_area0_limit = qeo_wave_high_area_limit_max_val;
29     config->wave2.high_area1_limit = qeo_wave_high_area_limit_max_val;
30     config->wave2.low_area0_limit = qeo_wave_low_area_limit_zero;
31     config->wave2.low_area1_limit = qeo_wave_low_area_limit_zero;
32     config->wave2.below_min_limit = qeo_wave_below_min_limit_zero;
33 
34     config->saddle_type = 0;
35     config->wave_type = qeo_wave_cosine;
36 }
37 
qeo_wave_config_mode(QEO_Type * base,qeo_wave_mode_t * config)38 void qeo_wave_config_mode(QEO_Type *base, qeo_wave_mode_t *config)
39 {
40     /* clear other bit except EN_WAVEx_VD_VQ_INJECT in MODE register */
41     base->WAVE.MODE &= QEO_WAVE_MODE_EN_WAVE2_VD_VQ_INJECT_MASK
42                     | QEO_WAVE_MODE_EN_WAVE1_VD_VQ_INJECT_MASK
43                     | QEO_WAVE_MODE_EN_WAVE0_VD_VQ_INJECT_MASK;
44 
45     base->WAVE.MODE |= QEO_WAVE_MODE_WAVE2_ABOVE_MAX_LIMIT_SET(config->wave2.above_max_limit)
46                     | QEO_WAVE_MODE_WAVE2_HIGH_AREA1_LIMIT_SET(config->wave2.high_area1_limit)
47                     | QEO_WAVE_MODE_WAVE2_HIGH_AREA0_LIMIT_SET(config->wave2.high_area0_limit)
48                     | QEO_WAVE_MODE_WAVE2_LOW_AREA1_LIMIT_SET(config->wave2.low_area1_limit)
49                     | QEO_WAVE_MODE_WAVE2_LOW_AREA0_LIMIT_SET(config->wave2.low_area0_limit)
50                     | QEO_WAVE_MODE_WAVE2_BELOW_MIN_LIMIT_SET(config->wave2.below_min_limit)
51 
52                     | QEO_WAVE_MODE_WAVE1_ABOVE_MAX_LIMIT_SET(config->wave1.above_max_limit)
53                     | QEO_WAVE_MODE_WAVE1_HIGH_AREA1_LIMIT_SET(config->wave1.high_area1_limit)
54                     | QEO_WAVE_MODE_WAVE1_HIGH_AREA0_LIMIT_SET(config->wave1.high_area0_limit)
55                     | QEO_WAVE_MODE_WAVE1_LOW_AREA1_LIMIT_SET(config->wave1.low_area1_limit)
56                     | QEO_WAVE_MODE_WAVE1_LOW_AREA0_LIMIT_SET(config->wave1.low_area0_limit)
57                     | QEO_WAVE_MODE_WAVE1_BELOW_MIN_LIMIT_SET(config->wave1.below_min_limit)
58 
59                     | QEO_WAVE_MODE_WAVE0_ABOVE_MAX_LIMIT_SET(config->wave0.above_max_limit)
60                     | QEO_WAVE_MODE_WAVE0_HIGH_AREA1_LIMIT_SET(config->wave0.high_area1_limit)
61                     | QEO_WAVE_MODE_WAVE0_HIGH_AREA0_LIMIT_SET(config->wave0.high_area0_limit)
62                     | QEO_WAVE_MODE_WAVE0_LOW_AREA1_LIMIT_SET(config->wave0.low_area1_limit)
63                     | QEO_WAVE_MODE_WAVE0_LOW_AREA0_LIMIT_SET(config->wave0.low_area0_limit)
64                     | QEO_WAVE_MODE_WAVE0_BELOW_MIN_LIMIT_SET(config->wave0.below_min_limit)
65                     | QEO_WAVE_MODE_SADDLE_TYPE_SET(config->saddle_type)
66                     | QEO_WAVE_MODE_WAVES_OUTPUT_TYPE_SET(config->wave_type);
67 }
68 
qeo_abz_get_default_mode_config(QEO_Type * base,qeo_abz_mode_t * config)69 void qeo_abz_get_default_mode_config(QEO_Type *base, qeo_abz_mode_t *config)
70 {
71     (void) base;
72     config->a_inv_pol = false;
73     config->b_inv_pol = false;
74     config->z_inv_pol = false;
75     config->output_type = qeo_abz_output_abz;
76     config->z_pulse_period = qeo_z_pulse_100_percent;
77 }
78 
qeo_abz_config_mode(QEO_Type * base,qeo_abz_mode_t * config)79 void qeo_abz_config_mode(QEO_Type *base, qeo_abz_mode_t *config)
80 {
81     base->ABZ.MODE &= ~(QEO_ABZ_MODE_Z_POLARITY_MASK
82                         | QEO_ABZ_MODE_B_POLARITY_MASK
83                         | QEO_ABZ_MODE_A_POLARITY_MASK
84                         | QEO_ABZ_MODE_Z_TYPE_MASK
85                         | QEO_ABZ_MODE_B_TYPE_MASK
86                         | QEO_ABZ_MODE_A_TYPE_MASK);
87 
88     base->ABZ.MODE = QEO_ABZ_MODE_Z_POLARITY_SET(config->z_inv_pol)
89                     | QEO_ABZ_MODE_B_POLARITY_SET(config->b_inv_pol)
90                     | QEO_ABZ_MODE_A_POLARITY_SET(config->a_inv_pol);
91 
92     if ((config->output_type == qeo_abz_output_pulse_revise) || (config->output_type == qeo_abz_output_up_down)) {
93         base->ABZ.MODE |= QEO_ABZ_MODE_B_TYPE_SET(config->output_type)
94                         | QEO_ABZ_MODE_A_TYPE_SET(config->output_type);
95     } else if (config->output_type == qeo_abz_output_three_phase) {
96         base->ABZ.MODE |= QEO_ABZ_MODE_Z_TYPE_SET(config->output_type)
97                         | QEO_ABZ_MODE_B_TYPE_SET(config->output_type)
98                         | QEO_ABZ_MODE_A_TYPE_SET(config->output_type);
99     } else {
100         base->ABZ.MODE |= QEO_ABZ_MODE_Z_TYPE_SET(config->z_pulse_period)
101                         | QEO_ABZ_MODE_B_TYPE_SET(config->output_type)
102                         | QEO_ABZ_MODE_A_TYPE_SET(config->output_type);
103     }
104 }
105 
qeo_abz_set_max_frequency(QEO_Type * base,uint32_t src_freq,uint32_t freq)106 hpm_stat_t qeo_abz_set_max_frequency(QEO_Type *base, uint32_t src_freq, uint32_t freq)
107 {
108     uint32_t count;
109 
110     if ((freq > 0xffffffffU / 4U) || ((src_freq % (freq * 4U)) != 0)) {
111         return status_invalid_argument;
112     }
113     count = src_freq / (freq * 4U);
114     base->ABZ.LINE_WIDTH = QEO_ABZ_LINE_WIDTH_LINE_SET(count);
115 
116     return status_success;
117 }
118 
qeo_abz_set_wdog_frequency(QEO_Type * base,uint32_t src_freq,uint32_t freq)119 hpm_stat_t qeo_abz_set_wdog_frequency(QEO_Type *base, uint32_t src_freq, uint32_t freq)
120 {
121     uint32_t count;
122 
123     if ((src_freq % freq) != 0) {
124         return status_invalid_argument;
125     }
126     count = src_freq / freq;
127     base->ABZ.WDOG_WIDTH = QEO_ABZ_WDOG_WIDTH_WIDTH_SET(count);
128     base->ABZ.MODE |= QEO_ABZ_MODE_EN_WDOG_MASK;
129 
130     return status_success;
131 }
132 
qeo_pwm_get_default_safety_table_config(QEO_Type * base,qeo_pwm_safety_output_table_t * table)133 void qeo_pwm_get_default_safety_table_config(QEO_Type *base, qeo_pwm_safety_output_table_t *table)
134 {
135     (void) base;
136     table->pwm7_output = qeo_pwm_safety_output_highz;
137     table->pwm6_output = qeo_pwm_safety_output_highz;
138     table->pwm5_output = qeo_pwm_safety_output_highz;
139     table->pwm4_output = qeo_pwm_safety_output_highz;
140     table->pwm3_output = qeo_pwm_safety_output_highz;
141     table->pwm2_output = qeo_pwm_safety_output_highz;
142     table->pwm1_output = qeo_pwm_safety_output_highz;
143     table->pwm0_output = qeo_pwm_safety_output_highz;
144 }
145 
qeo_pwm_get_default_phase_table_config(QEO_Type * base,qeo_pwm_phase_output_table_t * table)146 void qeo_pwm_get_default_phase_table_config(QEO_Type *base, qeo_pwm_phase_output_table_t *table)
147 {
148     (void) base;
149     table->pwm7_output = qeo_pwm_output_force_0;
150     table->pwm6_output = qeo_pwm_output_force_0;
151     table->pwm5_output = qeo_pwm_output_force_0;
152     table->pwm4_output = qeo_pwm_output_force_0;
153     table->pwm3_output = qeo_pwm_output_force_0;
154     table->pwm2_output = qeo_pwm_output_force_0;
155     table->pwm1_output = qeo_pwm_output_force_0;
156     table->pwm0_output = qeo_pwm_output_force_0;
157 }
158 
qeo_pwm_get_default_mode_config(QEO_Type * base,qeo_pwm_mode_t * config)159 void qeo_pwm_get_default_mode_config(QEO_Type *base, qeo_pwm_mode_t *config)
160 {
161     (void) base;
162     config->phase_num = 4;
163     config->shield_hardware_trig_safety = false;
164     config->revise_pairs_output = false;
165 }
166 
qeo_pwm_config_mode(QEO_Type * base,qeo_pwm_mode_t * config)167 void qeo_pwm_config_mode(QEO_Type *base, qeo_pwm_mode_t *config)
168 {
169     base->PWM.MODE &= ~(QEO_PWM_MODE_PWM_SAFETY_BYPASS_MASK
170                         | QEO_PWM_MODE_REVISE_UP_DN_MASK
171                         | QEO_PWM_MODE_PHASE_NUM_MASK);
172     base->PWM.MODE |= QEO_PWM_MODE_PWM_SAFETY_BYPASS_SET(config->shield_hardware_trig_safety)
173                     | QEO_PWM_MODE_REVISE_UP_DN_SET(config->revise_pairs_output)
174                     | QEO_PWM_MODE_PHASE_NUM_SET(config->phase_num);
175 }
176 
qeo_pwm_config_phase_table(QEO_Type * base,uint8_t index,qeo_pwm_phase_output_table_t * table)177 void qeo_pwm_config_phase_table(QEO_Type *base, uint8_t index, qeo_pwm_phase_output_table_t *table)
178 {
179     base->PWM.PHASE_TABLE[index] = QEO_PWM_PHASE_TABLE_PWM7_SET(table->pwm7_output)
180                                 | QEO_PWM_PHASE_TABLE_PWM6_SET(table->pwm6_output)
181                                 | QEO_PWM_PHASE_TABLE_PWM5_SET(table->pwm5_output)
182                                 | QEO_PWM_PHASE_TABLE_PWM4_SET(table->pwm4_output)
183                                 | QEO_PWM_PHASE_TABLE_PWM3_SET(table->pwm3_output)
184                                 | QEO_PWM_PHASE_TABLE_PWM2_SET(table->pwm2_output)
185                                 | QEO_PWM_PHASE_TABLE_PWM1_SET(table->pwm1_output)
186                                 | QEO_PWM_PHASE_TABLE_PWM0_SET(table->pwm0_output);
187 }
188 
qeo_pwm_config_safety_table(QEO_Type * base,qeo_pwm_safety_output_table_t * table)189 void qeo_pwm_config_safety_table(QEO_Type *base, qeo_pwm_safety_output_table_t *table)
190 {
191     /*< clear safety table */
192     base->PWM.MODE &= ~(QEO_PWM_MODE_PWM7_SAFETY_MASK
193                     | QEO_PWM_MODE_PWM6_SAFETY_MASK
194                     | QEO_PWM_MODE_PWM5_SAFETY_MASK
195                     | QEO_PWM_MODE_PWM4_SAFETY_MASK
196                     | QEO_PWM_MODE_PWM3_SAFETY_MASK
197                     | QEO_PWM_MODE_PWM2_SAFETY_MASK
198                     | QEO_PWM_MODE_PWM1_SAFETY_MASK
199                     | QEO_PWM_MODE_PWM0_SAFETY_MASK);
200     /*< set safety table */
201     base->PWM.MODE |= QEO_PWM_MODE_PWM7_SAFETY_SET(table->pwm7_output)
202                     | QEO_PWM_MODE_PWM6_SAFETY_SET(table->pwm6_output)
203                     | QEO_PWM_MODE_PWM5_SAFETY_SET(table->pwm5_output)
204                     | QEO_PWM_MODE_PWM4_SAFETY_SET(table->pwm4_output)
205                     | QEO_PWM_MODE_PWM3_SAFETY_SET(table->pwm3_output)
206                     | QEO_PWM_MODE_PWM2_SAFETY_SET(table->pwm2_output)
207                     | QEO_PWM_MODE_PWM1_SAFETY_SET(table->pwm1_output)
208                     | QEO_PWM_MODE_PWM0_SAFETY_SET(table->pwm0_output);
209 }
210 
211 /**
212  * If the line step of the position to be synchronized after position value
213  * to ABZ value conversion is the same as the current position, will hang the ABZ.
214  * ABZ value = m lines + n line_steps(0 <= m <= 3)
215  * This API will check the sync_pos and shift it if needed
216  */
qeo_abz_position_sync(QEO_Type * base,uint32_t lines,uint32_t sync_pos)217 void qeo_abz_position_sync(QEO_Type *base, uint32_t lines, uint32_t sync_pos)
218 {
219     uint32_t line_width;
220     uint32_t line_step_width;
221     uint32_t shift_pos;
222     uint32_t current_line_step;
223     uint32_t temp;
224 
225     line_width = (uint32_t)(0x100000000UL / lines);
226     line_step_width = line_width / 4U;
227     current_line_step = base->DEBUG2 & 0x3; /* get the lowest two bits */
228     temp = (sync_pos % line_width) / line_step_width;
229     if (temp == current_line_step) {
230         shift_pos = sync_pos - line_step_width;
231     } else {
232         shift_pos = sync_pos;
233     }
234 
235     base->ABZ.POSTION_SYNC = QEO_ABZ_POSTION_SYNC_POSTION_MASK;
236     qeo_enable_software_position_inject(base);
237     qeo_software_position_inject(base, shift_pos);
238     qeo_disable_software_position_inject(base);
239 }