• 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_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 }