• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef HPM_MMC_DRV_H
9 #define HPM_MMC_DRV_H
10 
11 #include "hpm_common.h"
12 #include "hpm_mmc_regs.h"
13 /**
14  * @brief MMC driver APIs
15  * @defgroup mmc_interface MMC driver APIs
16  * @ingroup mmc_interface
17  * @{
18  */
19 
20 /* trigger source to update position parameter */
21 typedef enum {
22     mmc_pos_update_by_timestamp = 0,
23     mmc_pos_update_by_intrgr0_rise_edge = 1,
24     mmc_pos_update_by_intrgr1_rise_edge = 2,
25     mmc_pos_update_by_outtrgr0_rise_edge = 3,
26     mmc_pos_update_by_outtrgr1_rise_edge = 4,
27     mmc_pos_update_by_self_pos_thr = 5,
28     mmc_pos_update_by_self_speed_thr = 6,
29 } mmc_pos_update_trigger_t;
30 
31 
32 /* cmd mask to update position parameter */
33 typedef enum {
34     mmc_pos_update_none = 0,
35     mmc_pos_update_position = 1 << 0,
36     mmc_pos_update_revolution = 1 << 1,
37     mmc_pos_update_speed = 1 << 2,
38     mmc_pos_update_accel = 1 << 3,
39     mmc_pos_update_all = 0b1111,
40 } mmc_pos_update_cmd_mask_t;
41 
42 typedef enum {
43     mmc_coef_not_update = 0,
44     mmc_coef_p_update = 1 << 0,
45     mmc_coef_i_update = 1 << 1,
46     mmc_coef_a_update = 1 << 2,
47     mmc_coef_update_all = 0b111,
48 } mmc_coef_update_cmd_mask_t;
49 
50 typedef struct {
51     bool discrete_pos_mode;
52     uint32_t discrete_line;
53     uint32_t continuous_step_thr;
54     uint32_t continuous_circ_thr;
55     uint32_t oosync_theta_thr;
56 } mmc_track_pos_mode_t;
57 
58 typedef struct {
59     bool force_accel_to_zero;
60     bool en_ms_coef;
61     bool open_loop_mode;
62     bool pos_16bit_type;      /* true for output 16bit position, false for output 32bit position */
63     bool sync_new_pos;        /* predictor base new track position data */
64     mmc_track_pos_mode_t pos_mode;
65 } mmc_track_mode_t;
66 
67 typedef struct {
68     uint32_t pos_time;
69     uint32_t position;
70     int32_t revolution;
71     double speed;
72     double accel;
73     uint32_t cmd_mask; /*!< cmd to to select which parameters to update */
74     uint32_t trigger;  /*!< trigger source for when to update parameters */
75 } mmc_pos_or_delta_pos_input_t;
76 
77 typedef struct {
78     uint32_t coef_time;
79     double coef_p;
80     double coef_i;
81     double coef_a;
82     uint32_t cmd_mask; /* cmd to select change which parameter */
83 } mmc_coef_input_t;
84 
85 typedef struct {
86     uint32_t err_thr;
87     uint32_t hold_time;
88     double coef_p;
89     double coef_i;
90     double coef_a;
91 } mmc_coef_trig_config_t;
92 
93 typedef struct {
94     uint32_t time;
95     uint32_t position;
96     int32_t revolution;
97     double speed;
98     double accel;
99 } mmc_pos_out_t;
100 
101 typedef struct {
102     double coef_p;
103     double coef_i;
104     double coef_a;
105 } mmc_coef_out_t;
106 
107 /* track event, definition align with interrupt mask and status mask */
108 typedef enum {
109     mmc_track_shadow_read_done = 1 << 0,
110     mmc_track_init_coefs_done = 1 << 1,
111     mmc_track_init_pos_done = 1 << 2,
112     mmc_track_oosync = 1 << 4,
113     mmc_track_idle = 1 << 5, /*!< no corresponding interrupt */
114     mmc_pred1_init_pos_done = 1 << 6,
115     mmc_pred0_init_pos_done = 1 << 7,
116     mmc_track_init_delta_pos_done = 1 << 8,
117     mmc_track_pos_trig_valid = 1 << 9,
118     mmc_track_speed_trig_valid = 1 << 10,
119 } mmc_track_event_t;
120 
121 typedef enum {
122     mmc_pred_idle = MMC_BR_BR_ST_IDLE_MASK,
123     mmc_pred_init_delta_pos_done = MMC_BR_BR_ST_INI_DELTA_POS_DONE_MASK,
124     mmc_pred_pos_trig_valid = MMC_BR_BR_ST_POS_TRG_VLD_MASK,
125     mmc_pred_speed_trig_valid = MMC_BR_BR_ST_SPEED_TRG_VLD_MASK,
126     mmc_pred_open_loop = MMC_BR_BR_ST_OPEN_LOOP_ST_MASK,
127 } mmc_pred_event_t;
128 
129 typedef enum {
130     mmc_pred_pos_trig_valid_int = MMC_BR_BR_CTRL_POS_TRG_VALID_IE_MASK,
131     mmc_pred_speed_trig_valid_int = MMC_BR_BR_CTRL_SPEED_TRG_VALID_IE_MASK,
132     mmc_pred_init_delta_pos_done_int = MMC_BR_BR_CTRL_INI_DELTA_POS_DONE_IE_MASK
133 } mmc_pred_int_t;
134 
135 typedef struct {
136     bool speed_trig_int;
137     bool position_trig_int;
138     bool delta_pos_done_trig_int;
139     bool open_loop_mode;
140     uint8_t pred_mode;
141     uint8_t not_first_pred_trig_type;
142     uint8_t first_pred_trig_type;
143 } mmc_pred_mode_t;
144 
145 typedef enum {
146     mmc_pred_not_reload_pos_cmd = 0,
147     mmc_pred_0_reload_pos_cmd = 2,
148     mmc_pred_1_reload_pos_cmd = 1,
149     mmc_pred_both_reload_pos_cmd = 3,
150 } mmc_pred_reload_pos_cmd_t;
151 
152 typedef enum {
153     mmc_pred_by_period = 0,
154     mmc_pred_continuously_repeat = 1,
155     mmc_pred_only_once = 2,
156 } mmc_pred_time_t;
157 
158 /* using for mmc_pred_by_period mode */
159 typedef struct {
160     uint32_t offset_time;
161     uint32_t period_time;
162     uint32_t first_time;
163 } mmc_pred_period_time_t;
164 
165 typedef struct {
166     bool less_than;         /*!< true for less than, false for greater than */
167     bool enable;
168     uint32_t position_thr;  /*!< position in a cycle */
169     int32_t revolution_thr; /*!< cycle */
170 } mmc_pos_trig_t;
171 
172 typedef struct {
173     bool absolute_compare; /*!< true for absolute value compare, false for signed value compare */
174     bool less_than;        /*!< true for less than, false for greater than */
175     bool enable;
176     int32_t speed_thr;
177 } mmc_speed_trig_t;
178 
179 
180 #ifdef __cplusplus
181 extern "C" {
182 #endif
183 
184 /**
185  * @brief MMC set frequency
186  * @param [in] base MMC base address
187  * @param [in] freq the moto system freq
188  */
mmc_set_sysclk_freq(MMC_Type * base,uint32_t freq)189 static inline void mmc_set_sysclk_freq(MMC_Type *base, uint32_t freq)
190 {
191     uint32_t period;
192     base->SYSCLK_FREQ = freq;
193     /* 1/freq *(2^24)*(2^20) */
194     period = (uint32_t)((double)(1 << 20) * (1 << 24) / freq);
195     base->SYSCLK_PERIOD = period;
196 }
197 
198 /**
199  * @brief MMC software reset
200  * @param [in] base MMC base address
201  */
mmc_software_reset(MMC_Type * base)202 static inline void mmc_software_reset(MMC_Type *base)
203 {
204     base->CR |= MMC_CR_SFTRST_MASK;
205     base->CR &= ~MMC_CR_SFTRST_MASK;
206 }
207 
208 /**
209  * @brief MMC module enable
210  * @param [in] base MMC base address
211  */
mmc_enable_module(MMC_Type * base)212 static inline void mmc_enable_module(MMC_Type *base)
213 {
214     base->CR |= MMC_CR_MOD_EN_MASK;
215 }
216 
217 /**
218  * @brief MMC module disable
219  * @param [in] base MMC base address
220  */
mmc_disable_module(MMC_Type * base)221 static inline void mmc_disable_module(MMC_Type *base)
222 {
223     base->CR &= ~MMC_CR_MOD_EN_MASK;
224 }
225 
226 /**
227  * @brief MMC track set loop mode
228  * @param [in] base MMC base address
229  * @param [in] open_loop true for open loop, false for close loop
230  */
mmc_track_set_open_loop_mode(MMC_Type * base,bool open_loop)231 static inline void mmc_track_set_open_loop_mode(MMC_Type *base, bool open_loop)
232 {
233     if (open_loop) {
234         base->CR |= MMC_CR_OPEN_LOOP_MODE_MASK;
235     } else {
236         base->CR &= ~MMC_CR_OPEN_LOOP_MODE_MASK;
237     }
238 }
239 
240 /**
241  * @brief MMC track set adjop mode
242  * @param [in] base MMC base address
243  * @param [in] adjop true for adjop mode, false for normal mode
244  */
mmc_track_set_adjop_mode(MMC_Type * base,bool adjop)245 static inline void mmc_track_set_adjop_mode(MMC_Type *base, bool adjop)
246 {
247     if (adjop) {
248         base->CR |= MMC_CR_ADJOP_MASK;
249     } else {
250         base->CR &= ~MMC_CR_ADJOP_MASK;
251     }
252 }
253 
254 /**
255  * @brief MMC track request shadow read
256  * @param [in] base MMC base address
257  *
258  * @note request shadow before read mmc track resoult register
259  */
mmc_track_enable_shadow_read(MMC_Type * base)260 static inline void mmc_track_enable_shadow_read(MMC_Type *base)
261 {
262     base->CR |= MMC_CR_SHADOW_RD_REQ_MASK;
263     /* SHADOW_RD_REQ clear indicates that the shadow is complete */
264     while ((base->CR & MMC_CR_SHADOW_RD_REQ_MASK) == MMC_CR_SHADOW_RD_REQ_MASK) {
265     }
266 }
267 
268 /**
269  * @brief MMC track enable interrupt
270  * @param [in] base MMC base address
271  * @param [in] int_mask interrupt_mask @ref mmc_track_event_t
272  */
mmc_track_enable_interrupt(MMC_Type * base,uint32_t int_mask)273 static inline void mmc_track_enable_interrupt(MMC_Type *base, uint32_t int_mask)
274 {
275     base->INT_EN = int_mask;
276 }
277 
278 /**
279  * @brief MMC track disable interrupt
280  * @param [in] base MMC base address
281  * @param [in] int_mask interrupt_mask @ref mmc_track_event_t
282  */
mmc_track_disable_interrupt(MMC_Type * base,uint32_t int_mask)283 static inline void mmc_track_disable_interrupt(MMC_Type *base, uint32_t int_mask)
284 {
285     base->INT_EN &= ~int_mask;
286 }
287 
288 /**
289  * @brief MMC track get status register value
290  * @param [in] base MMC base address
291  * @retval status register value
292  */
mmc_track_get_status(MMC_Type * base)293 static inline uint32_t mmc_track_get_status(MMC_Type *base)
294 {
295     return base->STA;
296 }
297 
298 /**
299  * @brief MMC track clear status flag in status register
300  * @param [in] base MMC base address
301  * @param [in] clr_mask  @ref mmc_track_event_t
302  */
mmc_track_clear_status(MMC_Type * base,uint32_t clr_mask)303 static inline void mmc_track_clear_status(MMC_Type *base, uint32_t clr_mask)
304 {
305     base->STA = clr_mask; /* W1C */
306 }
307 
308 /**
309  * @brief MMC track set the threshold of theta for out-of-sync
310  * @param [in] base MMC base address
311  * @param [in] threshold threshold value
312  */
mmc_track_set_oosync_theta_threshold(MMC_Type * base,uint32_t threshold)313 static inline void mmc_track_set_oosync_theta_threshold(MMC_Type *base, uint32_t threshold)
314 {
315     base->OOSYNC_THETA_THR = MMC_OOSYNC_THETA_THR_VAL_SET(threshold);
316 }
317 
318 /**
319  * @brief MMC track config position mode
320  * @param [in] base MMC base address
321  * @param [in] mode mmc_track_pos_mode_t
322  */
323 void mmc_track_config_pos_mode(MMC_Type *base, mmc_track_pos_mode_t *mode);
324 
325 /**
326  * @brief MMC track get default mode config
327  * @param [in] base MMC base address
328  * @param [in] config mmc_track_mode_t
329  */
330 void mmc_track_get_default_mode_config(MMC_Type *base, mmc_track_mode_t *config);
331 
332 /**
333  * @brief MMC track config mode
334  * @param [in] base MMC base address
335  * @param [in] config mmc_track_mode_t
336  */
337 void mmc_track_config_mode(MMC_Type *base, mmc_track_mode_t *config);
338 
339 /**
340  * @brief MMC track config position parameter
341  * @param [in] base MMC base address
342  * @param [in] para mmc_pos_or_delta_pos_input_t
343  */
344 void mmc_track_config_pos_para(MMC_Type *base, mmc_pos_or_delta_pos_input_t *para);
345 
346 /**
347  * @brief MMC track config delta parameter
348  * @param [in] base MMC base address
349  * @param [in] para mmc_pos_or_delta_pos_input_t
350  */
351 void mmc_track_config_delta_para(MMC_Type *base, mmc_pos_or_delta_pos_input_t *para);
352 
353 /**
354  * @brief MMC track config coef parameter
355  * @param [in] base MMC base address
356  * @param [in] para mmc_coef_input_t
357  */
358 void mmc_track_config_coef_para(MMC_Type *base, mmc_coef_input_t *para);
359 
360 /**
361  * @brief MMC track config position trigger
362  * @param [in] base MMC base address
363  * @param [in] para mmc_pos_trig_t
364  */
365 void mmc_track_config_position_trig(MMC_Type *base, mmc_pos_trig_t *trig);
366 
367 /**
368  * @brief MMC track config speed trigger
369  * @param [in] base MMC base address
370  * @param [in] para mmc_speed_trig_t
371  */
372 void mmc_track_config_speed_trig(MMC_Type *base, mmc_speed_trig_t *trig);
373 
374 /**
375  * @brief MMC track disable position trigger
376  * @param [in] base MMC base address
377  */
mmc_track_disable_position_trig(MMC_Type * base)378 static inline void mmc_track_disable_position_trig(MMC_Type *base)
379 {
380     base->POS_TRG_CFG &= ~MMC_POS_TRG_CFG_EN_MASK;
381 }
382 
383 /**
384  * @brief MMC track disable speed trigger
385  * @param [in] base MMC base address
386  */
mmc_track_disable_speed_trig(MMC_Type * base)387 static inline void mmc_track_disable_speed_trig(MMC_Type *base)
388 {
389     base->SPEED_TRG_CFG &= ~MMC_SPEED_TRG_CFG_EN_MASK;
390 }
391 
392 /**
393  * @brief MMC track config multiple coef trigger
394  * @param [in] base MMC base address
395  * @param [in] config mmc_coef_trig_config_t
396  */
397 void mmc_track_config_coef_trig(MMC_Type *base, uint8_t index, mmc_coef_trig_config_t *config);
398 
399 /**
400  * @brief MMC track get result
401  * @param [in] base MMC base address
402  * @param [out] pos_out mmc_pos_out_t
403  * @param [out] coef_out mmc_coef_out_t
404  */
405 void mmc_track_get_result(MMC_Type *base, mmc_pos_out_t *pos_out, mmc_coef_out_t *coef_out);
406 
407 /* predictor */
408 /**
409  * @brief MMC enable predictor
410  * @param [in] base MMC base address
411  * @param [in] index predictor index(0/1)
412  */
mmc_enable_pred(MMC_Type * base,uint8_t index)413 static inline void mmc_enable_pred(MMC_Type *base, uint8_t index)
414 {
415     base->BR[index].BR_CTRL |= MMC_BR_BR_CTRL_BR_EN_MASK;
416 }
417 
418 /**
419  * @brief MMC disable predictor
420  * @param [in] base MMC base address
421  * @param [in] index predictor index(0/1)
422  */
mmc_disable_pred(MMC_Type * base,uint8_t index)423 static inline void mmc_disable_pred(MMC_Type *base, uint8_t index)
424 {
425     base->BR[index].BR_CTRL &= ~MMC_BR_BR_CTRL_BR_EN_MASK;
426 }
427 
428 /**
429  * @brief MMC predictor set loop mode
430  * @param [in] base MMC base address
431  * @param [in] index predictor index(0/1)
432  * @param [in] open_loop true for open loop, false for close loop
433  */
mmc_pred_set_open_loop_mode(MMC_Type * base,uint8_t index,bool open_loop)434 static inline void mmc_pred_set_open_loop_mode(MMC_Type *base, uint8_t index, bool open_loop)
435 {
436     if (open_loop) {
437         base->BR[index].BR_CTRL |= MMC_BR_BR_CTRL_OPEN_LOOP_MODE_MASK;
438     } else {
439         base->BR[index].BR_CTRL &= ~MMC_BR_BR_CTRL_OPEN_LOOP_MODE_MASK;
440     }
441 }
442 
443 /**
444  * @brief MMC predictor set pred time
445  * @param [in] base MMC base address
446  * @param [in] index predictor index(0/1)
447  * @param [in] time mmc_pred_time_t
448  */
mmc_pred_set_pred_time(MMC_Type * base,uint8_t index,mmc_pred_time_t time)449 static inline void mmc_pred_set_pred_time(MMC_Type *base, uint8_t index, mmc_pred_time_t time)
450 {
451     base->BR[index].BR_CTRL &= ~MMC_BR_BR_CTRL_PRED_MODE_MASK;
452     base->BR[index].BR_CTRL |= MMC_BR_BR_CTRL_PRED_MODE_SET(time);
453 }
454 
455 /**
456  * @brief MMC pred enable interrupt
457  * @param [in] base MMC base address
458  * @param [in] index predictor index(0/1)
459  * @param [in] int_mask interrupt_mask @ref mmc_pred_int_t
460  */
mmc_pred_enable_interrupt(MMC_Type * base,uint8_t index,uint32_t int_mask)461 static inline void mmc_pred_enable_interrupt(MMC_Type *base, uint8_t index, uint32_t int_mask)
462 {
463     base->BR[index].BR_CTRL |= int_mask;
464 }
465 
466 /**
467  * @brief MMC pred disable interrupt
468  * @param [in] base MMC base address
469  * @param [in] index predictor index(0/1)
470  * @param [in] int_mask interrupt_mask @ref mmc_pred_int_t
471  */
mmc_pred_disable_interrupt(MMC_Type * base,uint8_t index,uint32_t int_mask)472 static inline void mmc_pred_disable_interrupt(MMC_Type *base, uint8_t index, uint32_t int_mask)
473 {
474     base->BR[index].BR_CTRL &= ~int_mask;
475 }
476 
477 /**
478  * @brief MMC predictor get status register value
479  * @param [in] base MMC base address
480  * @param [in] index predictor index(0/1)
481  * @retval predictor status register value
482  */
mmc_pred_get_status(MMC_Type * base,uint8_t index)483 static inline uint32_t mmc_pred_get_status(MMC_Type *base, uint8_t index)
484 {
485     return base->BR[index].BR_ST;
486 }
487 
488 /**
489  * @brief MMC predictor clear status bit in reigster
490  * @param [in] base MMC base address
491  * @param [in] index predictor index(0/1)
492  * @param [in] clr_mask bit mask @ref mmc_pred_event_t
493  */
mmc_pred_clear_status(MMC_Type * base,uint8_t index,uint32_t clr_mask)494 static inline void mmc_pred_clear_status(MMC_Type *base, uint8_t index, uint32_t clr_mask)
495 {
496     base->BR[index].BR_ST = clr_mask; /*!< W1C */
497 }
498 
499 /**
500  * @brief MMC predictor get default mode config
501  * @param [in] base MMC base address
502  * @param [in] config mmc_pred_mode_t
503  */
504 void mmc_pred_get_default_mode_config(MMC_Type *base, mmc_pred_mode_t *config);
505 
506 /**
507  * @brief MMC predictor config mode
508  * @param [in] base MMC base address
509  * @param [in] index predictor index(0/1)
510  * @param [in] config mmc_pred_mode_t
511  */
512 void mmc_pred_config_mode(MMC_Type *base, uint8_t index, mmc_pred_mode_t *config);
513 
514 /**
515  * @brief MMC predictor config position parameter
516  * @param [in] base MMC base address
517  * @param [in] index predictor index(0/1)
518  * @param [in] para mmc_pos_or_delta_pos_input_t
519  * @param [in] req_reload request to update parameter cmd
520  *
521  * @note 2 predictors can be set simultaneously by call mmc_pred_reload_pos_cmd()
522  */
523 void mmc_pred_config_pos_para(MMC_Type *base, uint8_t index, mmc_pos_or_delta_pos_input_t *para, bool req_reload);
524 
525 /**
526  * @brief MMC predictor reload position parameter cmd
527  * @param [in] base MMC base address
528  * @param [in] cmd mmc_pred_reload_pos_cmd_t
529  */
mmc_pred_reload_pos_cmd(MMC_Type * base,mmc_pred_reload_pos_cmd_t cmd)530 static inline void mmc_pred_reload_pos_cmd(MMC_Type *base, mmc_pred_reload_pos_cmd_t cmd)
531 {
532     base->CR &= ~(MMC_CR_INI_BR0_POS_REQ_MASK | MMC_CR_INI_BR0_POS_REQ_MASK);
533     base->CR |= cmd << MMC_CR_INI_BR1_POS_REQ_SHIFT;
534 }
535 
536 /**
537  * @brief MMC predictor update delta parameter
538  * @param [in] base MMC base address
539  * @param [in] index predictor index(0/1)
540  * @param [in] para mmc_pos_or_delta_pos_input_t
541  */
542 void mmc_pred_config_delta_para(MMC_Type *base, uint8_t index, mmc_pos_or_delta_pos_input_t *para);
543 
544 /**
545  * @brief MMC predictor config period time
546  * @param [in] base MMC base address
547  * @param [in] index predictor index(0/1)
548  * @param [in] time mmc_pred_period_time_t
549  */
550 void mmc_pred_config_period_time(MMC_Type *base, uint8_t index, mmc_pred_period_time_t *time);
551 
552 /**
553  * @brief MMC predictor config position trigger
554  * @param [in] base MMC base address
555  * @param [in] index predictor index(0/1)
556  * @param [in] trig mmc_pos_trig_t
557  */
558 void mmc_pred_config_position_trig(MMC_Type *base, uint8_t index, mmc_pos_trig_t *trig);
559 
560 /**
561  * @brief MMC predictor config speed trigger
562  * @param [in] base MMC base address
563  * @param [in] index predictor index(0/1)
564  * @param [in] trig mmc_speed_trig_t
565  */
566 void mmc_pred_config_speed_trig(MMC_Type *base, uint8_t index, mmc_speed_trig_t *trig);
567 
568 /**
569  * @brief MMC predictor disable position trigger
570  * @param [in] base MMC base address
571  * @param [in] index predictor index(0/1)
572  */
mmc_pred_disable_position_trig(MMC_Type * base,uint8_t index)573 static inline void mmc_pred_disable_position_trig(MMC_Type *base, uint8_t index)
574 {
575     base->BR[index].BR_TRG_POS_CFG &= ~MMC_BR_BR_TRG_POS_CFG_EN_MASK;
576 }
577 
578 /**
579  * @brief MMC predictor disable speed trigger
580  * @param [in] base MMC base address
581  * @param [in] index predictor index(0/1)
582  */
mmc_pred_disable_speed_trig(MMC_Type * base,uint8_t index)583 static inline void mmc_pred_disable_speed_trig(MMC_Type *base, uint8_t index)
584 {
585     base->BR[index].BR_TRG_SPEED_CFG &= ~MMC_BR_BR_TRG_SPEED_CFG_EN_MASK;
586 }
587 
588 /**
589  * @brief MMC predictor get result
590  * @param [in] base MMC base address
591  * @param [in] index predictor index(0/1)
592  * @param [out] pos_out mmc_pos_out_t
593  */
594 void mmc_pred_get_result(MMC_Type *base, uint8_t index, mmc_pos_out_t *pos_out);
595 
596 /**
597  * @brief MMC predictor get result
598  * @param [in] base MMC base address
599  * @param [out] para mmc_pos_or_delta_pos_input_t
600  */
601 void mmc_get_default_pos_or_delta_pos_para(MMC_Type *base, mmc_pos_or_delta_pos_input_t *para);
602 
603 
604 #ifdef __cplusplus
605 }
606 #endif
607 /**
608  * @}
609  */
610 #endif /* HPM_MMC_DRV_H */
611