1 /*
2 * Copyright (c) 2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "hpm_mmc_drv.h"
9
mmc_track_config_pos_mode(MMC_Type * base,mmc_track_pos_mode_t * mode)10 void mmc_track_config_pos_mode(MMC_Type *base, mmc_track_pos_mode_t *mode)
11 {
12 if (mode->discrete_pos_mode) {
13 base->CR |= MMC_CR_DISCRETETRC_MASK;
14 base->DISCRETECFG0 = MMC_DISCRETECFG0_POSMAX_SET(mode->discrete_line);
15 uint32_t inv_line = (uint32_t)(100000000UL / mode->discrete_line);
16 base->DISCRETECFG1 = MMC_DISCRETECFG1_INV_POSMAX_SET(inv_line);
17 } else {
18 base->CR &= ~MMC_CR_DISCRETETRC_MASK;
19 base->DISCRETECFG1 = MMC_DISCRETECFG1_INV_POSMAX_SET(mode->continuous_step_thr);
20 base->CONTCFG0 = MMC_CONTCFG0_HALF_CIRC_THETA_SET(mode->continuous_circ_thr);
21 }
22
23 base->OOSYNC_THETA_THR = MMC_OOSYNC_THETA_THR_VAL_SET(mode->oosync_theta_thr);
24 }
25
mmc_track_get_default_mode_config(MMC_Type * base,mmc_track_mode_t * config)26 void mmc_track_get_default_mode_config(MMC_Type *base, mmc_track_mode_t *config)
27 {
28 (void) base;
29 config->force_accel_to_zero = false;
30 config->en_ms_coef = false;
31 config->open_loop_mode = false;
32 config->pos_16bit_type = false;
33 config->sync_new_pos = false;
34
35 config->pos_mode.discrete_pos_mode = false;
36 config->pos_mode.discrete_line = 0x10000;
37 config->pos_mode.continuous_step_thr = 0x1000000;
38 config->pos_mode.continuous_circ_thr = 0x1000000;
39 config->pos_mode.oosync_theta_thr = 0x1000000;
40 }
41
mmc_track_config_mode(MMC_Type * base,mmc_track_mode_t * config)42 void mmc_track_config_mode(MMC_Type *base, mmc_track_mode_t *config)
43 {
44 base->CR &= ~(MMC_CR_FRCACCELZERO_MASK
45 | MMC_CR_MS_COEF_EN_MASK
46 | MMC_CR_OPEN_LOOP_MODE_MASK
47 | MMC_CR_POS_TYPE_MASK
48 | MMC_CR_ADJOP_MASK);
49
50 base->CR |= MMC_CR_FRCACCELZERO_SET(config->force_accel_to_zero)
51 | MMC_CR_MS_COEF_EN_SET(config->en_ms_coef)
52 | MMC_CR_OPEN_LOOP_MODE_SET(config->open_loop_mode)
53 | MMC_CR_POS_TYPE_SET(config->pos_16bit_type)
54 | MMC_CR_ADJOP_SET(config->sync_new_pos);
55
56 mmc_track_config_pos_mode(base, &config->pos_mode);
57 }
58
mmc_get_default_pos_or_delta_pos_para(MMC_Type * base,mmc_pos_or_delta_pos_input_t * para)59 void mmc_get_default_pos_or_delta_pos_para(MMC_Type *base, mmc_pos_or_delta_pos_input_t *para)
60 {
61 (void) base;
62 para->pos_time = 0;
63 para->position = 0;
64 para->revolution = 0;
65 para->speed = 0;
66 para->accel = 0;
67 para->cmd_mask = mmc_pos_update_all;
68 para->trigger = mmc_pos_update_by_timestamp;
69 }
70
mmc_track_config_pos_para(MMC_Type * base,mmc_pos_or_delta_pos_input_t * para)71 void mmc_track_config_pos_para(MMC_Type *base, mmc_pos_or_delta_pos_input_t *para)
72 {
73 /* speed and accel has 19bit decimal */
74 int32_t speed = (int32_t)(para->speed * (1 << 19U));
75 int32_t accel = (int32_t)(para->accel * (1 << 19U));
76
77 base->INI_SPEED = speed;
78 base->INI_ACCEL = accel;
79 base->INI_POS = para->position;
80 base->INI_REV = para->revolution;
81 base->INI_POS_TIME = para->pos_time;
82
83 base->CR &= ~(MMC_CR_INI_POS_TRG_TYPE_MASK | MMC_CR_INI_POS_CMD_MSK_MASK | MMC_CR_INI_POS_REQ_MASK);
84 base->CR |= MMC_CR_INI_POS_TRG_TYPE_SET((para->trigger))
85 | MMC_CR_INI_POS_CMD_MSK_SET(para->cmd_mask)
86 | MMC_CR_INI_POS_REQ_MASK;
87 }
88
mmc_track_config_delta_para(MMC_Type * base,mmc_pos_or_delta_pos_input_t * para)89 void mmc_track_config_delta_para(MMC_Type *base, mmc_pos_or_delta_pos_input_t *para)
90 {
91 int32_t speed = (int32_t)(para->speed * (1 << 19U));
92 int32_t accel = (int32_t)(para->accel * (1 << 19U));
93
94 base->INI_DELTA_SPEED = speed;
95 base->INI_DELTA_ACCEL = accel;
96 base->INI_DELTA_POS = para->position;
97 base->INI_DELTA_REV = para->revolution;
98 base->INI_DELTA_POS_TIME = para->pos_time;
99
100 base->CR &= ~(MMC_CR_INI_DELTA_POS_TRG_TYPE_MASK | MMC_CR_INI_DELTA_POS_CMD_MSK_MASK | MMC_CR_INI_DELTA_POS_REQ_MASK);
101 base->CR |= MMC_CR_INI_DELTA_POS_TRG_TYPE_SET((para->trigger))
102 | MMC_CR_INI_DELTA_POS_CMD_MSK_SET(para->cmd_mask)
103 | MMC_CR_INI_DELTA_POS_REQ_MASK;
104 }
105
mmc_track_config_coef_para(MMC_Type * base,mmc_coef_input_t * para)106 void mmc_track_config_coef_para(MMC_Type *base, mmc_coef_input_t *para)
107 {
108 int32_t coef_p = (int32_t)(para->coef_p * (1 << 15U));
109 int32_t coef_i = (int32_t)(para->coef_i * (1 << 21U));
110 int32_t coef_a = (int32_t)(para->coef_a * (1 << 19U));
111
112 base->INI_PCOEF = coef_p;
113 base->INI_ICOEF = coef_i;
114 base->INI_ACOEF = coef_a;
115 base->INI_COEF_TIME = para->coef_time;
116
117 base->CR &= ~(MMC_CR_INI_COEFS_CMD_MSK_MASK | MMC_CR_INI_COEFS_CMD_MASK);
118 base->CR |= MMC_CR_INI_COEFS_CMD_MSK_SET(para->cmd_mask)
119 | MMC_CR_INI_COEFS_CMD_MASK;
120 }
121
mmc_track_config_coef_trig(MMC_Type * base,uint8_t index,mmc_coef_trig_config_t * config)122 void mmc_track_config_coef_trig(MMC_Type *base, uint8_t index, mmc_coef_trig_config_t *config)
123 {
124 int32_t coef_p = (int32_t)(config->coef_p * (1 << 15U));
125 int32_t coef_i = (int32_t)(config->coef_i * (1 << 21U));
126 int32_t coef_a = (int32_t)(config->coef_a * (1 << 19U));
127
128 base->COEF_TRG_CFG[index].P = coef_p;
129 base->COEF_TRG_CFG[index].I = coef_i;
130 base->COEF_TRG_CFG[index].A = coef_a;
131 base->COEF_TRG_CFG[index].TIME = config->hold_time;
132 base->COEF_TRG_CFG[index].ERR_THR = config->err_thr;
133 }
134
mmc_track_get_result(MMC_Type * base,mmc_pos_out_t * pos_out,mmc_coef_out_t * coef_out)135 void mmc_track_get_result(MMC_Type *base, mmc_pos_out_t *pos_out, mmc_coef_out_t *coef_out)
136 {
137 /* mmc_track_enable_shadow_read(base); */
138
139 base->CR |= MMC_CR_SHADOW_RD_REQ_MASK;
140 while ((base->CR & MMC_CR_SHADOW_RD_REQ_MASK) == MMC_CR_SHADOW_RD_REQ_MASK) {
141 }
142
143 if (pos_out != NULL) {
144 pos_out->time = base->ESTM_TIM;
145 pos_out->position = base->ESTM_POS;
146 pos_out->revolution = (int32_t)base->ESTM_REV;
147
148 int32_t speed = base->ESTM_SPEED;
149 int32_t accel = base->ESTM_ACCEL;
150
151 pos_out->speed = (double)speed / (1 << 19U);
152 pos_out->accel = (double)accel / (1 << 19U);
153 }
154
155 if (coef_out != NULL) {
156 int32_t coef_p = base->CUR_PCOEF;
157 int32_t coef_i = base->CUR_ICOEF;
158 int32_t coef_a = base->CUR_ACOEF;
159
160 coef_out->coef_p = (double)coef_p / (1 << 15U);
161 coef_out->coef_i = (double)coef_i / (1 << 21U);
162 coef_out->coef_a = (double)coef_a / (1 << 19U);
163 }
164 }
165
166
mmc_pred_get_default_mode_config(MMC_Type * base,mmc_pred_mode_t * config)167 void mmc_pred_get_default_mode_config(MMC_Type *base, mmc_pred_mode_t *config)
168 {
169 (void) base;
170 config->speed_trig_int = false;
171 config->position_trig_int = false;
172 config->delta_pos_done_trig_int = false;
173
174
175 config->open_loop_mode = false;
176 config->pred_mode = 0;
177 config->not_first_pred_trig_type = 0;
178 config->first_pred_trig_type = 0;
179 }
180
mmc_pred_config_mode(MMC_Type * base,uint8_t index,mmc_pred_mode_t * config)181 void mmc_pred_config_mode(MMC_Type *base, uint8_t index, mmc_pred_mode_t *config)
182 {
183 base->BR[index].BR_CTRL &= ~(MMC_BR_BR_CTRL_SPEED_TRG_VALID_IE_MASK
184 | MMC_BR_BR_CTRL_POS_TRG_VALID_IE_MASK
185 | MMC_BR_BR_CTRL_INI_DELTA_POS_DONE_IE_MASK
186 | MMC_BR_BR_CTRL_OPEN_LOOP_MODE_MASK
187 | MMC_BR_BR_CTRL_PRED_MODE_MASK
188 | MMC_BR_BR_CTRL_NF_TRG_TYPE_MASK
189 | MMC_BR_BR_CTRL_F_TRG_TYPE_MASK);
190
191 base->BR[index].BR_CTRL |= MMC_BR_BR_CTRL_SPEED_TRG_VALID_IE_SET(config->speed_trig_int)
192 | MMC_BR_BR_CTRL_POS_TRG_VALID_IE_SET(config->position_trig_int)
193 | MMC_BR_BR_CTRL_INI_DELTA_POS_DONE_IE_SET(config->delta_pos_done_trig_int)
194 | MMC_BR_BR_CTRL_OPEN_LOOP_MODE_SET(config->open_loop_mode)
195 | MMC_BR_BR_CTRL_PRED_MODE_SET(config->pred_mode)
196 | MMC_BR_BR_CTRL_NF_TRG_TYPE_SET(config->not_first_pred_trig_type)
197 | MMC_BR_BR_CTRL_F_TRG_TYPE_SET(config->first_pred_trig_type);
198 }
199
mmc_pred_config_pos_para(MMC_Type * base,uint8_t index,mmc_pos_or_delta_pos_input_t * para,bool req_reload)200 void mmc_pred_config_pos_para(MMC_Type *base, uint8_t index, mmc_pos_or_delta_pos_input_t *para, bool req_reload)
201 {
202 /* speed and accel has 19bit decimal */
203 int32_t speed = (int32_t)(para->speed * (1 << 19U));
204 int32_t accel = (int32_t)(para->accel * (1 << 19U));
205
206 base->BR[index].BR_INI_SPEED = speed;
207 base->BR[index].BR_INI_ACCEL = accel;
208 base->BR[index].BR_INI_POS = para->position;
209 base->BR[index].BR_INI_REV = para->revolution;
210 base->BR[index].BR_INI_POS_TIME = para->pos_time;
211
212 base->BR[index].BR_CTRL &= ~(MMC_BR_BR_CTRL_INI_POS_TRG_TYPE_MASK | MMC_BR_BR_CTRL_INI_POS_CMD_MSK_MASK);
213 base->BR[index].BR_CTRL |= MMC_BR_BR_CTRL_INI_POS_TRG_TYPE_SET((para->trigger))
214 | MMC_BR_BR_CTRL_INI_POS_CMD_MSK_SET(para->cmd_mask);
215
216 if (req_reload) {
217 base->CR |= (1U << (MMC_CR_INI_BR0_POS_REQ_SHIFT - index));
218 }
219 }
220
mmc_pred_config_delta_para(MMC_Type * base,uint8_t index,mmc_pos_or_delta_pos_input_t * para)221 void mmc_pred_config_delta_para(MMC_Type *base, uint8_t index, mmc_pos_or_delta_pos_input_t *para)
222 {
223 int32_t speed = (int32_t)(para->speed * (1 << 19U));
224 int32_t accel = (int32_t)(para->accel * (1 << 19U));
225
226 base->BR[index].BR_INI_DELTA_SPEED = speed;
227 base->BR[index].BR_INI_DELTA_ACCEL = accel;
228 base->BR[index].BR_INI_DELTA_POS = para->position;
229 base->BR[index].BR_INI_DELTA_REV = para->revolution;
230 base->BR[index].BR_INI_DELTA_POS_TIME = para->pos_time;
231
232 base->BR[index].BR_CTRL &= ~(MMC_BR_BR_CTRL_INI_DELTA_POS_TRG_TYPE_MASK
233 | MMC_BR_BR_CTRL_INI_DELTA_POS_CMD_MSK_MASK
234 | MMC_BR_BR_CTRL_INI_DELTA_POS_REQ_MASK);
235
236 base->BR[index].BR_CTRL |= MMC_BR_BR_CTRL_INI_DELTA_POS_TRG_TYPE_SET(para->trigger)
237 | MMC_BR_BR_CTRL_INI_DELTA_POS_CMD_MSK_SET(para->cmd_mask)
238 | MMC_BR_BR_CTRL_INI_DELTA_POS_REQ_MASK;
239 }
240
241 /* 不需要shadow吗 */
mmc_pred_get_result(MMC_Type * base,uint8_t index,mmc_pos_out_t * pos_out)242 void mmc_pred_get_result(MMC_Type *base, uint8_t index, mmc_pos_out_t *pos_out)
243 {
244 pos_out->time = base->BR[index].BR_CUR_POS_TIME;
245 pos_out->position = base->BR[index].BR_CUR_POS;
246 pos_out->revolution = (int32_t)base->BR[index].BR_CUR_REV;
247
248 int32_t speed = base->BR[index].BR_CUR_SPEED;
249 int32_t accel = base->BR[index].BR_CUR_ACCEL;
250
251 pos_out->speed = (double)speed / (1 << 19U);
252 pos_out->accel = (double)accel / (1 << 19U);
253 }
254
mmc_pred_config_period_time(MMC_Type * base,uint8_t index,mmc_pred_period_time_t * time)255 void mmc_pred_config_period_time(MMC_Type *base, uint8_t index, mmc_pred_period_time_t *time)
256 {
257 base->BR[index].BR_TIMEOFF = time->offset_time;
258 base->BR[index].BR_TRG_PERIOD = time->period_time;
259 base->BR[index].BR_TRG_F_TIME = time->first_time;
260 }
261
mmc_pred_config_position_trig(MMC_Type * base,uint8_t index,mmc_pos_trig_t * trig)262 void mmc_pred_config_position_trig(MMC_Type *base, uint8_t index, mmc_pos_trig_t *trig)
263 {
264 base->BR[index].BR_TRG_POS_THR = trig->position_thr;
265 base->BR[index].BR_TRG_REV_THR = trig->revolution_thr;
266
267 base->BR[index].BR_TRG_POS_CFG = MMC_BR_BR_TRG_POS_CFG_EDGE_SET(trig->less_than)
268 | MMC_BR_BR_TRG_POS_CFG_EN_SET(trig->enable);
269 }
270
mmc_pred_config_speed_trig(MMC_Type * base,uint8_t index,mmc_speed_trig_t * trig)271 void mmc_pred_config_speed_trig(MMC_Type *base, uint8_t index, mmc_speed_trig_t *trig)
272 {
273 /* speed has 19bit decimal */
274 int32_t speed = (int32_t)(trig->speed_thr * (1 << 19U));
275
276 base->BR[index].BR_TRG_SPEED_THR = speed;
277 base->BR[index].BR_TRG_SPEED_CFG = MMC_BR_BR_TRG_SPEED_CFG_COMP_TYPE_SET(trig->absolute_compare)
278 | MMC_BR_BR_TRG_SPEED_CFG_EDGE_SEL_SET(trig->less_than)
279 | MMC_BR_BR_TRG_SPEED_CFG_EN_SET(trig->enable);
280 }
281
mmc_track_config_position_trig(MMC_Type * base,mmc_pos_trig_t * trig)282 void mmc_track_config_position_trig(MMC_Type *base, mmc_pos_trig_t *trig)
283 {
284 base->POS_TRG_POS_THR = trig->position_thr;
285 base->POS_TRG_REV_THR = trig->revolution_thr;
286
287 base->POS_TRG_CFG = MMC_POS_TRG_CFG_EDGE_SET(trig->less_than)
288 | MMC_POS_TRG_CFG_EN_SET(trig->enable);
289 }
290
mmc_track_config_speed_trig(MMC_Type * base,mmc_speed_trig_t * trig)291 void mmc_track_config_speed_trig(MMC_Type *base, mmc_speed_trig_t *trig)
292 {
293 /* speed has 19bit decimal */
294 int32_t speed = (int32_t)(trig->speed_thr * (1 << 19U));
295 base->SPEED_TRG_THR = speed;
296 base->SPEED_TRG_CFG = MMC_SPEED_TRG_CFG_COMP_TYPE_SET(trig->absolute_compare)
297 | MMC_SPEED_TRG_CFG_EDGE_SET(trig->less_than)
298 | MMC_SPEED_TRG_CFG_EN_SET(trig->enable);
299 }