• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 #ifndef HPM_MCL_ENCODER_H
8 #define HPM_MCL_ENCODER_H
9 #include "hpm_mcl_common.h"
10 #include "hpm_mcl_filter.h"
11 
12 enum {
13     mcl_encoder_start_sample_error = MAKE_STATUS(mcl_group_encoder, 0),
14     mcl_encoder_get_tick_error = MAKE_STATUS(mcl_group_encoder, 1),
15     mcl_encoder_update_tick_error = MAKE_STATUS(mcl_group_encoder, 2),
16     mcl_encoder_get_theta_error = MAKE_STATUS(mcl_group_encoder, 3),
17     mcl_encoder_not_ready = MAKE_STATUS(mcl_group_encoder, 4),
18 };
19 
20 typedef enum {
21     encoder_status_null = 0,
22     encoder_status_init = 1,
23     encoder_status_run = 2,
24     encoder_status_fail = 3,
25 } mcl_encoder_status_t;
26 
27 /**
28  * @brief Method of calculating speed
29  *
30  */
31 typedef enum {
32     encoder_method_t,
33     encoder_method_m,
34     encoder_method_m_t,
35     encoder_method_pll,
36     encoder_method_user,
37 } mcl_encoder_cal_speed_function_t;
38 
39 /**
40  * @brief callback function
41  *
42  */
43 typedef struct  mcl_encoder_callback {
44     hpm_mcl_stat_t (*init)(void);
45     _FUNC_OPTIONAL_ hpm_mcl_stat_t (*update_trig_lead_tick)(uint32_t lead_tick);
46     _FUNC_OPTIONAL_ hpm_mcl_stat_t (*get_lead_tick)(uint32_t *lead_tick);
47     hpm_mcl_stat_t (*start_sample)(void);
48     hpm_mcl_stat_t (*get_theta)(float *theta);
49     _FUNC_OPTIONAL_ hpm_mcl_stat_t (*get_absolute_theta)(float *theta);
50     _FUNC_OPTIONAL_ hpm_mcl_stat_t (*process_by_user)(float theta, float *speed, float *theta_forecast);
51 } mcl_encoder_callback_t;
52 
53 /**
54  * @brief Maximum memory required for computational speed, word
55  *
56  */
57 #define MCL_ENCODER_CAL_STRUCT_MAX_MEMMORY  (16)
58 typedef struct {
59     float theta_last;
60     float speed_last;
61     float ts_sigma;
62 } mcl_encoder_cal_speed_t_function_t;
63 
64 typedef struct {
65     float theta_last;
66     float ts_sigma;
67 } mcl_encoder_cal_speed_m_function_t;
68 
69 typedef struct {
70     float theta_last;
71     float ts_sigma;
72     float theta_sigma;
73     float speed_filter_last;
74     float speed_last;
75 } mcl_encoder_cal_speed_m_t_function_t;
76 
77 /**
78  * @brief pll filter configuration
79  *
80  */
81 typedef struct {
82     float kp;   /**< scale factor */
83     float ki;   /**< Integration factor */
84 } mcl_encoder_cal_speed_pll_cfg_t;
85 
86 /**
87  * @brief Running data for the pll method of calculating speed
88  *
89  */
90 typedef struct {
91     mcl_encoder_cal_speed_pll_cfg_t *cfg;
92     float *period_call_time_s;
93     float pi_integrator;
94     float omega_integrator;
95     float theta_last;
96 } mcl_encoder_cal_speed_pll_function_t;
97 
98 /**
99  * @brief Encoder Configuration
100  *
101  */
102 typedef struct {
103     uint8_t disable_start_sample_interrupt;
104     uint64_t communication_interval_us; /**< The communication interval of the communicating encoder ensures that an angle reading can be completed within the interval. Optical encoders can be read at any time, given as zero. */
105     mcl_encoder_cal_speed_function_t speed_cal_method;
106     mcl_encoder_cal_speed_pll_cfg_t cal_speed_pll_cfg;
107     float timeout_s;                  /**< Timeout time, after this time angle is not updated, the speed will be cleared to zero. */
108     float speed_abs_switch_m_t;     /**< Use the m_t method to set the validity, the speed is greater than the set speed, use the m method, the speed is less than the set speed t use the t method to calculate the speed. */
109     uint32_t precision;     /**< Sensor accuracy, various encoders converted to number of lines. The maximum number of angular changes that can occur per revolution of the motor. */
110     float period_call_time_s;   /**< The time of the cycle call, the handler function should be called periodically, in s. */
111     mcl_encoder_callback_t callback;
112 } mcl_encoer_cfg_t;
113 
114 
115 /**
116  * @brief Encoder operation data
117  *
118  */
119 typedef struct {
120     union {
121         mcl_encoder_cal_speed_t_function_t t_method;
122         mcl_encoder_cal_speed_m_function_t m_method;
123         mcl_encoder_cal_speed_m_t_function_t m_t_method;
124         mcl_encoder_cal_speed_pll_function_t pll_method;
125         uint32_t memory[MCL_ENCODER_CAL_STRUCT_MAX_MEMMORY];
126     } cal_speed;
127     mcl_filter_iir_df1_t *iirfilter;
128     mcl_encoder_status_t status;
129     mcl_encoer_cfg_t *cfg;
130     int32_t *mcu_clock_tick;
131     int32_t *pole_num;
132     float theta_initial;
133     float *current_loop_ts;
134     mcl_user_value_t force_set_theta;
135     struct {
136         float speed;
137         float theta;
138         float theta_forecast;
139     } result;
140 } mcl_encoder_t;
141 
142 #ifdef __cplusplus
143 extern "C" {
144 #endif
145 
146 /**
147  * @brief Initialize encoder data
148  *
149  * @param encoder @ref mcl_encoder_t
150  * @param mcl_cfg @ref mcl_cfg_t
151  * @param encoder_cfg @ref mcl_encoer_cfg_t
152  * @param iir @ref mcl_filter_iir_df1_t
153  * @return hpm_mcl_stat_t
154  */
155 hpm_mcl_stat_t hpm_mcl_encoder_init(mcl_encoder_t *encoder, mcl_cfg_t *mcl_cfg, mcl_encoer_cfg_t *encoder_cfg, mcl_filter_iir_df1_t *iir);
156 
157 /**
158  * @brief Encoder starts sampling
159  *
160  * @param encoder @ref mcl_encoder_t
161  * @return hpm_mcl_stat_t
162  */
163 hpm_mcl_stat_t hpm_mcl_encoder_start_sample(mcl_encoder_t *encoder);
164 
165 /**
166  * @brief Setting the initial angle of the encoder
167  *
168  * @param encoder @ref mcl_encoder_t
169  * @param theta Initial angle value
170  * @return hpm_mcl_stat_t
171  */
172 hpm_mcl_stat_t hpm_mcl_encoder_set_initial_theta(mcl_encoder_t *encoder, float theta);
173 
174 /**
175  * @brief Encoder processing, cycle call
176  *
177  * @param encoder @ref mcl_encoder_t
178  * @param tick_deta Difference in the number of cycles between two calls
179  * @return hpm_mcl_stat_t
180  */
181 hpm_mcl_stat_t hpm_mcl_encoder_process(mcl_encoder_t *encoder, uint32_t tick_deta);
182 
183 /**
184  * @brief Force update of encoder status
185  *
186  * @param encoder @ref mcl_encoder_t
187  * @param status @ref mcl_encoder_status_t
188  * @return hpm_mcl_stat_t
189  */
190 hpm_mcl_stat_t hpm_mcl_encoder_set_status(mcl_encoder_t *encoder, mcl_encoder_status_t status);
191 
192 /**
193  * @brief Get the encoder angle value
194  *
195  * @param encoder @ref mcl_encoder_t
196  * @return angle value, rad
197  */
198 float hpm_mcl_encoder_get_theta(mcl_encoder_t *encoder);
199 
200 /**
201  * @brief Get speed
202  *
203  * @param encoder @ref mcl_encoder_t
204  * @return rad/s
205  */
206 float hpm_mcl_encoder_get_speed(mcl_encoder_t *encoder);
207 
208 /**
209  * @brief Get the angle predicted from the speed
210  *
211  * @param encoder @ref mcl_encoder_t
212  * @return theta, rad
213  */
214 float hpm_mcl_encoder_get_forecast_theta(mcl_encoder_t *encoder);
215 
216 /**
217  * @brief Getting the raw angle data of the encoder
218  *
219  * @param encoder @ref mcl_encoder_t
220  * @return theta, rad
221  */
222 float hpm_mcl_encoder_get_raw_theta(mcl_encoder_t *encoder);
223 
224 /**
225  * @brief Force setting of the output angle of the encoder function
226  *
227  * @param encoder @ref mcl_encoder_t
228  * @param theta rad
229  * @param enable Enable or disable the forced output function
230  */
231 void hpm_mcl_encoder_force_theta(mcl_encoder_t *encoder, float theta, bool enable);
232 
233 /**
234  * @brief Get the absolute position of the angle
235  *
236  * @param encoder @ref mcl_encoder_t
237  * @param theta rad
238  * @return hpm_mcl_stat_t
239  */
240 hpm_mcl_stat_t hpm_mcl_encoder_get_absolute_theta(mcl_encoder_t *encoder, float *theta);
241 
242 #ifdef __cplusplus
243 }
244 #endif
245 
246 #endif