AM263x Motor Control SDK  09.02.00
encoder.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Texas Instruments Incorporated
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the
14  * distribution.
15  *
16  * Neither the name of Texas Instruments Incorporated nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifndef ENCODER_H
34 #define ENCODER_H
35 
36 #ifdef __cplusplus
37 extern "C"
38 {
39 #endif
40 
54 // the includes
55 #include <stdint.h>
56 #include <stdlib.h>
57 
58 #include <drivers/eqep.h>
59 #include <drivers/gpio.h>
60 
61 #include "math_types.h"
62 #include "userParams.h"
63 
64 // **************************************************************************
65 // the defines
66 //#define ENC_CALIB 1
67 
68 // State machine typedef for ENC status
69 typedef enum
70 {
71  ENC_IDLE = 0,
76 
77 
80 typedef struct _ENC_Obj_
81 {
82  float32_t Ts_sec; // sampling period (sec)
83  float32_t polePairs; // pole pairs of the motor
84  float32_t encLines; // lines of the encoder
85 
87 
88  float32_t thetaMech_pu; // Mechanical angle
89  float32_t thetaMech_rad; // Mechanical angle
90  float32_t thetaElec_rad; // Electrical angle
91  float32_t thetaHall_rad; // Initial angle of the hall sensor
93  uint32_t *ptrHallPos;
94 
95  float32_t speedElec_Hz; // target speed
96  float32_t speedMech_Hz; // estimated rotor speed
97 
98  uint32_t qepHandle; // the QEP handle
99  uint32_t indexOffset; // the offset of index
100 
101 #if defined(ENC_CALIB)
102  float32_t hallThetaData[12];
103  uint32_t hallPosData[12];
104  uint16_t hallStateIndex[12];
105  uint16_t hallIndex;
106  uint16_t hallStatePrev;
107 #endif // ENC_CALIB
108 
109  uint32_t gpioHallU; // the GPIO for Hall U
110  uint32_t gpioHallV; // the GPIO for Hall V
111  uint32_t gpioHallW; // the GPIO for Hall W
112  uint32_t gpioHallUBase; // the GPIO base address for Hall U
113  uint32_t gpioHallVBase; // the GPIO base address for Hall V
114  uint32_t gpioHallWBase; // the GPIO base address for Hall W
115  uint16_t hallState;
116  uint16_t hallStateZero;
117 
119 } ENC_Obj, *ENC_Handle;
120 
121 // **************************************************************************
122 // the function prototypes
129 //
130 //*****************************************************************************
131 extern ENC_Handle ENC_init(void *pMemory, const size_t numBytes);
132 
133 //*****************************************************************************
134 //
139 //
140 //*****************************************************************************
141 extern void ENC_setParams(ENC_Handle handle, const USER_Params *pUserParams);
142 
143 //*****************************************************************************
144 //
154 //
155 //*****************************************************************************
156 static inline void ENC_setHallGPIO(ENC_Handle handle, const uint32_t gpioHallU,
157  const uint32_t gpioHallV, const uint32_t gpioHallW,
158  const uint32_t gpioHallUBase, const uint32_t gpioHallVBase,
159  const uint32_t gpioHallWBase)
160 {
161  ENC_Obj *obj = (ENC_Obj *)handle;
162 
163  obj->gpioHallU = gpioHallU;
164  obj->gpioHallV = gpioHallV;
165  obj->gpioHallW = gpioHallW;
166  obj->gpioHallUBase = gpioHallUBase;
167  obj->gpioHallVBase = gpioHallVBase;
168  obj->gpioHallWBase = gpioHallWBase;
169 
170  return;
171 }
172 
173 //*****************************************************************************
174 //
180 //
181 //*****************************************************************************
182 static inline float32_t ENC_getSpeedElec_Hz(ENC_Handle handle)
183 {
184  ENC_Obj *obj = (ENC_Obj *)handle;
185 
186  return(obj->speedElec_Hz);
187 }
188 
189 //*****************************************************************************
190 //
196 //
197 //*****************************************************************************
198 static inline float32_t ENC_getElecAngle(ENC_Handle handle)
199 {
200  ENC_Obj *obj = (ENC_Obj *)handle;
201 
202  return(obj->thetaElec_rad);
203 }
204 
205 //*****************************************************************************
206 //
212 //
213 //*****************************************************************************
214 static inline float32_t ENC_getState(ENC_Handle handle)
215 {
216  ENC_Obj *obj = (ENC_Obj *)handle;
217 
218  return(obj->encState);
219 }
220 
221 //*****************************************************************************
222 //
226 //
227 //*****************************************************************************
228 static inline void ENC_resetState(ENC_Handle handle)
229 {
230  ENC_Obj *obj = (ENC_Obj *)handle;
231 
232  obj->encState = ENC_IDLE;
233 
234  return;
235 }
236 
237 //*****************************************************************************
238 //
244 //
245 //*****************************************************************************
246 static inline void ENC_setState(ENC_Handle handle, const ENC_Status_e encState)
247 {
248  ENC_Obj *obj = (ENC_Obj *)handle;
249 
250  obj->encState = encState;
251 
252  return;
253 }
254 
255 //*****************************************************************************
256 //
262 //
263 //*****************************************************************************
264 static inline void ENC_setGPIOHallU(ENC_Handle handle, const uint32_t gpioHallU, const uint32_t gpioHallUBase)
265 {
266  ENC_Obj *obj = (ENC_Obj *)handle;
267 
268  obj->gpioHallU = gpioHallU;
269  obj->gpioHallUBase = gpioHallUBase;
270 
271  return;
272 }
273 
274 //*****************************************************************************
275 //
281 //
282 //*****************************************************************************
283 static inline void ENC_setGPIOHallV(ENC_Handle handle, const uint32_t gpioHallV, const uint32_t gpioHallVBase)
284 {
285  ENC_Obj *obj = (ENC_Obj *)handle;
286 
287  obj->gpioHallV = gpioHallV;
288  obj->gpioHallVBase = gpioHallVBase;
289 
290  return;
291 }
292 
293 //*****************************************************************************
294 //
300 //
301 //*****************************************************************************
302 static inline void ENC_setGPIOHallW(ENC_Handle handle, const uint32_t gpioHallW, const uint32_t gpioHallWBase)
303 {
304  ENC_Obj *obj = (ENC_Obj *)handle;
305 
306  obj->gpioHallW = gpioHallW;
307  obj->gpioHallWBase = gpioHallWBase;
308 
309  return;
310 }
311 
312 //*****************************************************************************
313 //
318 //
319 //*****************************************************************************
320 static inline void ENC_setQEPHandle(ENC_Handle handle, const uint32_t qepBase)
321 {
322  ENC_Obj *obj = (ENC_Obj *)handle;
323 
324  obj->qepHandle = qepBase;
325 
326  return;
327 }
328 
329 //*****************************************************************************
330 //
334 //
335 //*****************************************************************************
336 static inline uint16_t ENC_getHallState(ENC_Handle handle)
337 {
338  ENC_Obj *obj = (ENC_Obj *)handle;
339 
340  uint32_t hallState = 0;
341 
342  hallState = GPIO_pinRead(obj->gpioHallUBase, obj->gpioHallU);
343  hallState += GPIO_pinRead(obj->gpioHallVBase, obj->gpioHallV)<<1;
344  hallState += GPIO_pinRead(obj->gpioHallWBase, obj->gpioHallW)<<2;
345 
346  return(hallState & 0x00000007);
347 }
348 
349 #define ENC_inline_run ENC_run // Backwards compatible
350 
351 //*****************************************************************************
352 //
356 //
357 //*****************************************************************************
358 static __attribute__((always_inline))
359 void ENC_run(ENC_Handle handle)
360 {
361  ENC_Obj *obj = (ENC_Obj *)handle;
362 
363  if(obj->encState == ENC_CALIBRATION_DONE)
364  {
365  obj->thetaMech_pu = obj->mechanicalScaler *
366  (float32_t)EQEP_getPositionLatch(obj->qepHandle);
367 
368  obj->thetaMech_rad = obj->thetaMech_pu * MATH_TWO_PI;
369 
370  float32_t thetaElec_pu = obj->thetaMech_pu * obj->polePairs;
371 
372  obj->thetaElec_rad = (thetaElec_pu - ((int32_t)thetaElec_pu)) * MATH_TWO_PI;
373 
374  if(obj->thetaElec_rad >= MATH_PI)
375  {
376  obj->thetaElec_rad = obj->thetaElec_rad - MATH_TWO_PI;
377  }
378  else if(obj->thetaElec_rad <= -MATH_PI)
379  {
380  obj->thetaElec_rad = obj->thetaElec_rad + MATH_TWO_PI;
381  }
382  }
383  else if(obj->encState == ENC_WAIT_FOR_INDEX)
384  {
385  if(EQEP_getInterruptStatus(obj->qepHandle) & EQEP_INT_INDEX_EVNT_LATCH)
386  {
387  EQEP_setInitialPosition(obj->qepHandle, EQEP_getPositionLatch(obj->qepHandle));
388 
389  EQEP_setPositionInitMode(obj->qepHandle, EQEP_INIT_RISING_INDEX);
390 
391  obj->indexOffset = EQEP_getPositionLatch(obj->qepHandle);
393  }
394  }
395  else // obj->encState == ENC_ALIGNMENT
396  {
397 
398 #if defined(ENC_CALIB)
399  obj->hallStateZero = ENC_getHallState(handle);
400  obj->hallIndex = 0;
401 #endif // ENC_CALIB
402 
403  // during alignment, reset the current shaft position to zero
404  EQEP_setPosition(obj->qepHandle, 0);
405 
406  // Reset pos cnt for QEP
407  EQEP_clearInterruptStatus(obj->qepHandle, EQEP_INT_INDEX_EVNT_LATCH);
408 
409  // reset poscnt init on index
410  EQEP_setPositionInitMode(obj->qepHandle, EQEP_INIT_DO_NOTHING);
411  }
412 
413 #if defined(ENC_CALIB)
414  obj->hallState = ENC_getHallState(handle);
415 
416  if(obj->hallState != obj->hallStatePrev)
417  {
418  obj->hallThetaData[obj->hallIndex] = obj->thetaElec_rad;
419  obj->hallPosData[obj->hallIndex] = EQEP_getPositionLatch(obj->qepHandle);
420  obj->hallStateIndex[obj->hallIndex] = obj->hallState;
421 
422  obj->hallIndex++;
423 
424  if(obj->hallIndex >= 12)
425  {
426  obj->hallIndex = 0;
427  }
428  }
429 
430  obj->hallStatePrev = obj->hallState;
431 #endif // ENC_CALIB
432 
433  return;
434 }
435 
436 #ifndef ENC_full_run
437 #define ENC_full_run ENC_runHall
438 #endif
439 
440 //*****************************************************************************
441 //
445 //
446 //*****************************************************************************
447 static __attribute__((always_inline))
448 void ENC_runHall(ENC_Handle handle)
449 {
450  ENC_Obj *obj = (ENC_Obj *)handle;
451 
452  if(obj->encState == ENC_CALIBRATION_DONE)
453  {
454  obj->thetaMech_pu = obj->mechanicalScaler *
455  (float32_t)EQEP_getPositionLatch(obj->qepHandle);
456 
457  obj->thetaMech_rad = obj->thetaMech_pu * MATH_TWO_PI;
458 
459  float32_t thetaElec_pu = obj->thetaMech_pu * obj->polePairs;
460 
461  obj->thetaElec_rad = (thetaElec_pu - ((int32_t)thetaElec_pu)) * MATH_TWO_PI;
462 
463  if(obj->thetaElec_rad >= MATH_PI)
464  {
465  obj->thetaElec_rad = obj->thetaElec_rad - MATH_TWO_PI;
466  }
467  else if(obj->thetaElec_rad <= -MATH_PI)
468  {
469  obj->thetaElec_rad = obj->thetaElec_rad + MATH_TWO_PI;
470  }
471  }
472  else if(obj->encState == ENC_WAIT_FOR_INDEX)
473  {
474  if(EQEP_getInterruptStatus(obj->qepHandle) & EQEP_INT_INDEX_EVNT_LATCH)
475  {
476  EQEP_setInitialPosition(obj->qepHandle, EQEP_getPositionLatch(obj->qepHandle));
477 
478  EQEP_setPositionInitMode(obj->qepHandle, EQEP_INIT_RISING_INDEX);
479 
481  }
482  }
483  else // obj->encState == ENC_ALIGNMENT
484  {
485  // during alignment, reset the current shaft position to zero
486  EQEP_setPosition(obj->qepHandle, 0);
487 
488  // Reset pos cnt for QEP
489  EQEP_clearInterruptStatus(obj->qepHandle, EQEP_INT_INDEX_EVNT_LATCH);
490 
491  // reset poscnt init on index
492  EQEP_setPositionInitMode(obj->qepHandle, EQEP_INIT_DO_NOTHING);
493  }
494 
495  return;
496 }
497 
500 #ifdef __cplusplus
501 }
502 #endif
503 
504 #endif // ENCODER_H
505 
ENC_Obj::thetaHall_rad
float32_t thetaHall_rad
Definition: encoder.h:91
ENC_Obj::encLines
float32_t encLines
Definition: encoder.h:84
ENC_Obj::hallStateZero
uint16_t hallStateZero
Definition: encoder.h:116
ENC_setGPIOHallV
static void ENC_setGPIOHallV(ENC_Handle handle, const uint32_t gpioHallV, const uint32_t gpioHallVBase)
Set the ENC controller parameter Hall V (only needed for calibration mode)
Definition: encoder.h:283
ENC_getState
static float32_t ENC_getState(ENC_Handle handle)
Gets the state of the ENC controller.
Definition: encoder.h:214
ENC_runHall
static void ENC_runHall(ENC_Handle handle)
Runs the hall of ENC controller.
Definition: encoder.h:448
ENC_getHallState
static uint16_t ENC_getHallState(ENC_Handle handle)
Get the hall state.
Definition: encoder.h:336
ENC_WAIT_FOR_INDEX
@ ENC_WAIT_FOR_INDEX
Definition: encoder.h:73
ENC_getSpeedElec_Hz
static float32_t ENC_getSpeedElec_Hz(ENC_Handle handle)
Runs the ENC controller.
Definition: encoder.h:182
ENC_Obj::encState
ENC_Status_e encState
Definition: encoder.h:118
USER_Params
Defines a structure for the user parameters.
Definition: userParams.h:75
ENC_Obj::ptrHallPos
uint32_t * ptrHallPos
Definition: encoder.h:93
ENC_setHallGPIO
static void ENC_setHallGPIO(ENC_Handle handle, const uint32_t gpioHallU, const uint32_t gpioHallV, const uint32_t gpioHallW, const uint32_t gpioHallUBase, const uint32_t gpioHallVBase, const uint32_t gpioHallWBase)
Set the hall pins and address (only needed for calibration mode)
Definition: encoder.h:156
ENC_setParams
void ENC_setParams(ENC_Handle handle, const USER_Params *pUserParams)
Set the controller parameters.
ENC_Obj::gpioHallVBase
uint32_t gpioHallVBase
Definition: encoder.h:113
ENC_Obj
Defines the ENC controller object.
Definition: encoder.h:81
ENC_setQEPHandle
static void ENC_setQEPHandle(ENC_Handle handle, const uint32_t qepBase)
Set the ENC controller eqep handle.
Definition: encoder.h:320
ENC_run
static void ENC_run(ENC_Handle handle)
Runs the ENC controller.
Definition: encoder.h:359
ENC_Status_e
ENC_Status_e
Definition: encoder.h:70
ENC_Obj::hallState
uint16_t hallState
Definition: encoder.h:115
ENC_Obj::thetaMech_pu
float32_t thetaMech_pu
Definition: encoder.h:88
ENC_Obj::polePairs
float32_t polePairs
Definition: encoder.h:83
ENC_Obj::thetaMech_rad
float32_t thetaMech_rad
Definition: encoder.h:89
ENC_Obj::Ts_sec
float32_t Ts_sec
Definition: encoder.h:82
ENC_resetState
static void ENC_resetState(ENC_Handle handle)
Reset the ENC controller state.
Definition: encoder.h:228
ENC_Obj::qepHandle
uint32_t qepHandle
Definition: encoder.h:98
ENC_Obj::gpioHallU
uint32_t gpioHallU
Definition: encoder.h:109
ENC_Obj::thetaElec_rad
float32_t thetaElec_rad
Definition: encoder.h:90
ENC_CALIBRATION_DONE
@ ENC_CALIBRATION_DONE
Definition: encoder.h:74
ENC_Obj::gpioHallWBase
uint32_t gpioHallWBase
Definition: encoder.h:114
ENC_Obj::gpioHallV
uint32_t gpioHallV
Definition: encoder.h:110
ENC_Obj::gpioHallUBase
uint32_t gpioHallUBase
Definition: encoder.h:112
ENC_init
ENC_Handle ENC_init(void *pMemory, const size_t numBytes)
Initializes the ENC controller.
ENC_IDLE
@ ENC_IDLE
Definition: encoder.h:71
ENC_Obj::gpioHallW
uint32_t gpioHallW
Definition: encoder.h:111
ENC_setState
static void ENC_setState(ENC_Handle handle, const ENC_Status_e encState)
Sets up the ENC controller state.
Definition: encoder.h:246
userParams.h
Contains the public interface for the HAL and EST modules.
ENC_setGPIOHallU
static void ENC_setGPIOHallU(ENC_Handle handle, const uint32_t gpioHallU, const uint32_t gpioHallUBase)
Set the ENC controller parameter Hall U (only needed for calibration mode)
Definition: encoder.h:264
ENC_ALIGNMENT
@ ENC_ALIGNMENT
Definition: encoder.h:72
ENC_getElecAngle
static float32_t ENC_getElecAngle(ENC_Handle handle)
Gets the angle from encoder.
Definition: encoder.h:198
ENC_Obj::indexOffset
uint32_t indexOffset
Definition: encoder.h:99
ENC_Obj::ptrHalltheta
float32_t * ptrHalltheta
Definition: encoder.h:92
ENC_Obj::speedMech_Hz
float32_t speedMech_Hz
Definition: encoder.h:96
float32_t
float float32_t
Definition: dcl_common.h:58
ENC_setGPIOHallW
static void ENC_setGPIOHallW(ENC_Handle handle, const uint32_t gpioHallW, const uint32_t gpioHallWBase)
Set the ENC controller parameter Hall W (only needed for calibration mode)
Definition: encoder.h:302
ENC_Obj::speedElec_Hz
float32_t speedElec_Hz
Definition: encoder.h:95
ENC_Obj::mechanicalScaler
float32_t mechanicalScaler
Definition: encoder.h:86