AM243x Motor Control SDK  09.02.00
svgen_current.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2024 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 SVGEN_CURRENT_H
34 #define SVGEN_CURRENT_H
35 
36 #ifdef __cplusplus
37 extern "C"
38 {
39 #endif
40 
51 #include <stdlib.h>
52 #include <math.h>
53 
54 #include "math_types.h"
55 
56 // **************************************************************************
57 // the typedefs
58 
59 typedef enum
60 {
70 
71 typedef enum
72 {
78 
79 typedef enum
80 {
85 
88 typedef struct _SVGENCURRENT_Obj_
89 {
90  int16_t minWidth;
95  int16_t Voffset;
97 
100 typedef struct _SVGENCURRENT_Obj_ *SVGENCURRENT_Handle;
101 
102 
103 // **************************************************************************
104 // the function prototypes
105 
106 //*****************************************************************************
107 //
111 //
112 //*****************************************************************************
113 extern SVGENCURRENT_Handle
114 SVGENCURRENT_init(void *pMemory,const size_t numBytes);
115 
116 //*****************************************************************************
117 //
123 //
124 //*****************************************************************************
125 void SVGENCURRENT_setup(SVGENCURRENT_Handle handle, const float32_t minWidth_usec,
126  const float32_t pwmFreq_kHz, const float32_t systemFreq_MHz);
127 
128 //*****************************************************************************
129 //
134 //
135 //*****************************************************************************
136 static inline void
138  const int16_t minwidth)
139 {
140  SVGENCURRENT_Obj *obj = (SVGENCURRENT_Obj *)handle;
141 
142  obj->minWidth = minwidth;
143 
144  return;
145 } // end of SVGENCURRENT_setMinWidth() function
146 
147 //*****************************************************************************
148 //
152 //
153 //*****************************************************************************
154 static inline void
156  const SVGENCURRENT_IgnoreShunt_e ignoreShunt)
157 {
158  SVGENCURRENT_Obj *obj = (SVGENCURRENT_Obj *)handle;
159 
160  obj->ignoreShunt = ignoreShunt;
161 
162  return;
163 } // end of SVGENCURRENT_setIgnoreShunt() function
164 
165 //*****************************************************************************
166 //
170 //
171 //*****************************************************************************
172 static inline void
174  const SVGENCURRENT_MeasureShunt_e compMode)
175 {
176  SVGENCURRENT_Obj *obj = (SVGENCURRENT_Obj *)handle;
177 
178  obj->compMode = compMode;
179 
180  return;
181 } // end of SVGENCURRENT_setMode() function
182 
183 //*****************************************************************************
184 //
188 //
189 //*****************************************************************************
190 static inline void
192  const float32_t Vlimit)
193 {
194  SVGENCURRENT_Obj *obj = (SVGENCURRENT_Obj *)handle;
195 
196  obj->Vlimit = Vlimit;
197 
198  return;
199 } // end of SVGENCURRENT_setVlimit() function
200 
201 //*****************************************************************************
202 //
206 //
207 //*****************************************************************************
208 static inline SVGENCURRENT_IgnoreShunt_e
210 {
211  SVGENCURRENT_Obj *obj = (SVGENCURRENT_Obj *)handle;
212 
213  return(obj->ignoreShunt);
214 } // end of SVGENCURRENT_getIgnoreShunt() function
215 
216 //*****************************************************************************
217 //
222 //
223 //*****************************************************************************
224 static inline int16_t
226 {
227  SVGENCURRENT_Obj *obj = (SVGENCURRENT_Obj *)handle;
228 
229  return(obj->minWidth);
230 } // end of SVGENCURRENT_getMinWidth() function
231 
232 //*****************************************************************************
233 //
237 //
238 //*****************************************************************************
239 static inline float32_t
241 {
242  SVGENCURRENT_Obj *obj = (SVGENCURRENT_Obj *)handle;
243 
244  return(obj->Vlimit);
245 
246 } // end of SVGENCURRENT_getVlimit() function
247 
248 //*****************************************************************************
249 //
253 //
254 //*****************************************************************************
255 static inline SVGENCURRENT_MeasureShunt_e
257 {
258  SVGENCURRENT_Obj *obj = (SVGENCURRENT_Obj *)handle;
259 
260  return(obj->compMode);
261 
262 } // end of SVGENCURRENT_getMode() function
263 
264 //*****************************************************************************
265 //
269 //
270 //*****************************************************************************
271 static inline SVGENCURRENT_VmidShunt_e
273 {
274  SVGENCURRENT_Obj *obj = (SVGENCURRENT_Obj *)handle;
275 
276  return(obj->Vmid);
277 
278 } // end of SVGENCURRENT_getVmiddle() function
279 
280 //*****************************************************************************
281 //
292 //
293 //*****************************************************************************
294 static __attribute__((always_inline))
296  uint16_t cmp1, uint16_t cmp2, uint16_t cmp3,
297  uint16_t cmpM1, uint16_t cmpM2, uint16_t cmpM3)
298 {
299  SVGENCURRENT_Obj *obj = (SVGENCURRENT_Obj *)handle;
300  uint16_t minWidth;
301 
302  minWidth = obj->minWidth;
303 
304  uint16_t nextPulse1 = (cmp1 + cmpM1)>>1;
305  uint16_t nextPulse2 = (cmp2 + cmpM2)>>1;
306  uint16_t nextPulse3 = (cmp3 + cmpM3)>>1;
307 
308  if(nextPulse1 < minWidth)
309  {
310  if((nextPulse2 < minWidth) || ((cmp2 - cmp1) < minWidth))
311  {
313  }
314  else if((nextPulse3 < minWidth) || ((cmp3 - cmp1) < minWidth))
315  {
317  }
318  else
319  {
321  }
322  }
323  else if(nextPulse2 < minWidth)
324  {
325  if((nextPulse1 < minWidth) || ((cmp1 - cmp2) < minWidth))
326  {
328  }
329  else if((nextPulse3 < minWidth) || ((cmp3 - cmp2) < minWidth))
330  {
332  }
333  else
334  {
336  }
337  }
338  else if(nextPulse3 < minWidth)
339  {
340  if((nextPulse1 < minWidth) || ((cmp1 - cmp3) < minWidth))
341  {
343  }
344  else if((nextPulse2 < minWidth) || ((cmp2 - cmp3) < minWidth))
345  {
347  }
348  else
349  {
351  }
352  }
353  else
354  {
356  }
357 
358  return;
359 
360 } // end of SVGENCURRENT_RunIgnoreShunt() function
361 
362 //*****************************************************************************
363 //
368 //
369 //*****************************************************************************
370 static __attribute__((always_inline))
372  MATH_Vec3 *pADCData, MATH_Vec3 *pADCDataPrev)
373 {
374  SVGENCURRENT_Obj *obj = (SVGENCURRENT_Obj *)handle;
375 
376  float32_t Ia = pADCData->value[0];
377  float32_t Ib = pADCData->value[1];
378  float32_t Ic = pADCData->value[2];
379 
380  // select valid shunts and ignore one when needed
382  {
383  // repair a based on b and c
384  Ia = -Ib - Ic; //Ia = -Ib - Ic;
385  }
386  else if(obj->ignoreShunt == SVGENCURRENT_IGNORE_B)
387  {
388  // repair b based on a and c
389  Ib = -Ia - Ic; //Ib = -Ia - Ic;
390  }
391  else if(obj->ignoreShunt == SVGENCURRENT_IGNORE_C)
392  {
393  // repair c based on a and b
394  Ic = -Ia - Ib; //Ic = -Ia - Ib;
395  }
396  else if(obj->ignoreShunt == SVGENCURRENT_IGNORE_AB)
397  {
398  Ia = -Ic * 0.5f;
399  Ib = Ia;
400  }
401  else if(obj->ignoreShunt == SVGENCURRENT_IGNORE_AC)
402  {
403  Ia = -Ib * 0.5f;
404  Ic = Ia;
405  }
406  else if(obj->ignoreShunt == SVGENCURRENT_IGNORE_BC)
407  {
408  Ib = -Ia * 0.5f;
409  Ic = Ib;
410  }
411 
412  pADCData->value[0] = Ia;
413  pADCData->value[1] = Ib;
414  pADCData->value[2] = Ic;
415 
416  pADCDataPrev->value[0] += (pADCData->value[0] - pADCDataPrev->value[0]) * 0.5f;
417  pADCDataPrev->value[1] += (pADCData->value[1] - pADCDataPrev->value[1]) * 0.5f;
418  pADCDataPrev->value[2] += (pADCData->value[2] - pADCDataPrev->value[2]) * 0.5f;
419 
421  {
422  pADCData->value[0] = pADCDataPrev->value[0];
423  pADCData->value[1] = pADCDataPrev->value[1];
424  pADCData->value[2] = pADCDataPrev->value[2];
425  }
426 
427  return;
428 } // end of SVGENCURRENT_RunRegenCurrent() function
429 
430 //*****************************************************************************
431 //
436 //
437 //*****************************************************************************
438 static __attribute__((always_inline))
440  MATH_Vec3 *pPWMData, MATH_Vec3 *pPWMData_prev)
441 {
442  SVGENCURRENT_Obj *obj = (SVGENCURRENT_Obj *)handle;
443 
444  float32_t Va_avg = (pPWMData->value[0] + pPWMData_prev->value[0]) * 0.5f;
445  float32_t Vb_avg = (pPWMData->value[1] + pPWMData_prev->value[1]) * 0.5f;
446  float32_t Vc_avg = (pPWMData->value[2] + pPWMData_prev->value[2]) * 0.5f;
447 
448  float32_t Vlimit = obj->Vlimit;
449  float32_t Vmid, Vmid_prev, Voffset;
450 
451  //define compensation mode
452  if(Va_avg > Vlimit)
453  {
454  if(Vb_avg > Vlimit)
455  {
457 
458  if(Va_avg > Vb_avg)
459  {
460  obj->Vmid = SVGENCURRENT_VMID_B;
461  Vmid = pPWMData->value[1];
462  Vmid_prev = pPWMData_prev->value[1];
463  }
464  else
465  {
466  obj->Vmid = SVGENCURRENT_VMID_A;
467  Vmid = pPWMData->value[0];
468  Vmid_prev = pPWMData_prev->value[0];
469  }
470  }
471  else if(Vc_avg > Vlimit)
472  {
474 
475  if(Va_avg > Vc_avg)
476  {
477  obj->Vmid = SVGENCURRENT_VMID_C;
478  Vmid = pPWMData->value[2];
479  Vmid_prev = pPWMData_prev->value[2];
480  }
481  else
482  {
483  obj->Vmid = SVGENCURRENT_VMID_A;
484  Vmid = pPWMData->value[0];
485  Vmid_prev = pPWMData_prev->value[0];
486  }
487  }
488  else
489  {
491 
492  if(Vb_avg > Vc_avg)
493  {
494  obj->Vmid = SVGENCURRENT_VMID_B;
495  }
496  else
497  {
498  obj->Vmid = SVGENCURRENT_VMID_C;
499  }
500  }
501  }
502  else
503  {
504  if(Vb_avg > Vlimit)
505  {
506  if(Vc_avg > Vlimit)
507  {
509 
510  if(Vb_avg > Vc_avg)
511  {
512  obj->Vmid = SVGENCURRENT_VMID_C;
513  Vmid = pPWMData->value[2];
514  Vmid_prev = pPWMData_prev->value[2];
515  }
516  else
517  {
518  obj->Vmid = SVGENCURRENT_VMID_B;
519  Vmid = pPWMData->value[1];
520  Vmid_prev = pPWMData_prev->value[1];
521  }
522  }
523  else
524  {
526 
527  if(Va_avg > Vc_avg)
528  {
529  obj->Vmid = SVGENCURRENT_VMID_A;
530  }
531  else
532  {
533  obj->Vmid = SVGENCURRENT_VMID_C;
534  }
535  }
536  }
537  else if(Vc_avg > Vlimit)
538  {
540 
541  if(Va_avg > Vb_avg)
542  {
543  obj->Vmid = SVGENCURRENT_VMID_A;
544  }
545  else
546  {
547  obj->Vmid = SVGENCURRENT_VMID_B;
548  }
549  }
550  else
551  {
554  }
555  }
556 
557  //phase voltage compensator
559  {
560  Voffset = (Vmid + Vmid_prev) * 0.5f - Vlimit;
561 
562  if(pPWMData->value[0] > -0.50f)
563  {
564  pPWMData->value[0] -= Voffset;
565  }
566 
567  if(pPWMData->value[1] > -0.50f)
568  {
569  pPWMData->value[1] -= Voffset;
570  }
571 
572  if(pPWMData->value[2] > -0.50f)
573  {
574  pPWMData->value[2] -= Voffset;
575  }
576 
577  obj->Voffset = Voffset;
578  }
579 
580  // get ignore current
581  if(((pPWMData->value[0] + pPWMData_prev->value[0]) * 0.5f) > Vlimit)
582  {
584  }
585  else if(((pPWMData->value[1] + pPWMData_prev->value[1]) * 0.5f) > Vlimit)
586  {
588  }
589  else if(((pPWMData->value[2] + pPWMData_prev->value[2]) * 0.5f) > Vlimit)
590  {
592  }
593  else
594  {
596  }
597 
598 
599  pPWMData_prev->value[0] = pPWMData->value[0];
600  pPWMData_prev->value[1] = pPWMData->value[1];
601  pPWMData_prev->value[2] = pPWMData->value[2];
602 
603  return;
604 } // end of SVGENCURRENT_compPWMData() function
605 
606 
607 //*****************************************************************************
608 //
609 // Close the Doxygen group.
611 //
612 //*****************************************************************************
613 
614 //*****************************************************************************
615 //
616 // Mark the end of the C bindings section for C++ compilers.
617 //
618 //*****************************************************************************
619 #ifdef __cplusplus
620 }
621 #endif
622 
623 #endif // end of SVGEN_CURRENT_H definition
SVGENCURRENT_Obj::minWidth
int16_t minWidth
The maximum width where a valid measurement cannot be taken.
Definition: svgen_current.h:90
SVGENCURRENT_setup
void SVGENCURRENT_setup(SVGENCURRENT_Handle handle, const float32_t minWidth_usec, const float32_t pwmFreq_kHz, const float32_t systemFreq_MHz)
Sets up the PWM minimum width.
SVGENCURRENT_getIgnoreShunt
static SVGENCURRENT_IgnoreShunt_e SVGENCURRENT_getIgnoreShunt(SVGENCURRENT_Handle handle)
Gets the ignore shunt value.
Definition: svgen_current.h:209
SVGENCURRENT_setMode
static void SVGENCURRENT_setMode(SVGENCURRENT_Handle handle, const SVGENCURRENT_MeasureShunt_e compMode)
Sets the compensation mode.
Definition: svgen_current.h:173
SVGENCURRENT_setVlimit
static void SVGENCURRENT_setVlimit(SVGENCURRENT_Handle handle, const float32_t Vlimit)
Sets the output voltage limit value for gurrantee a current sampling.
Definition: svgen_current.h:191
SVGENCURRENT_Handle
struct _SVGENCURRENT_Obj_ * SVGENCURRENT_Handle
Defines the Svgen Current handle.
Definition: svgen_current.h:100
SVGENCURRENT_VMID_B
@ SVGENCURRENT_VMID_B
Middle voltage is B phase.
Definition: svgen_current.h:82
SVGENCURRENT_VMID_C
@ SVGENCURRENT_VMID_C
Middle voltage is C phase.
Definition: svgen_current.h:83
SVGENCURRENT_IMMEASUREABLE
@ SVGENCURRENT_IMMEASUREABLE
Definition: svgen_current.h:76
SVGENCURRENT_IGNORE_A
@ SVGENCURRENT_IGNORE_A
Ignore the A phase shunt measurement.
Definition: svgen_current.h:62
SVGENCURRENT_IGNORE_B
@ SVGENCURRENT_IGNORE_B
Ignore the B phase shunt measurement.
Definition: svgen_current.h:63
SVGENCURRENT_IGNORE_C
@ SVGENCURRENT_IGNORE_C
Ignore the C phase shunt measurement.
Definition: svgen_current.h:64
SVGENCURRENT_Obj::Vmid
SVGENCURRENT_VmidShunt_e Vmid
The middle amplitude voltage among the three phase voltages.
Definition: svgen_current.h:93
SVGENCURRENT_IGNORE_BC
@ SVGENCURRENT_IGNORE_BC
Ignore the BC phase shunt measurement.
Definition: svgen_current.h:67
SVGENCURRENT_IGNORE_AB
@ SVGENCURRENT_IGNORE_AB
Ignore the AB phase shunt measurement.
Definition: svgen_current.h:65
SVGENCURRENT_getVlimit
static float32_t SVGENCURRENT_getVlimit(SVGENCURRENT_Handle handle)
Gets the Voltage(Duty) Limit value.
Definition: svgen_current.h:240
SVGENCURRENT_compPWMData
static void SVGENCURRENT_compPWMData(SVGENCURRENT_Handle handle, MATH_Vec3 *pPWMData, MATH_Vec3 *pPWMData_prev)
output voltage reconsturction to guarantee min duty in two phase at least
Definition: svgen_current.h:439
SVGENCURRENT_RunIgnoreShunt
static void SVGENCURRENT_RunIgnoreShunt(SVGENCURRENT_Handle handle, uint16_t cmp1, uint16_t cmp2, uint16_t cmp3, uint16_t cmpM1, uint16_t cmpM2, uint16_t cmpM3)
Gets the svgen current module ignore shunt.
Definition: svgen_current.h:295
SVGENCURRENT_Obj
Defines the Svgen Current object.
Definition: svgen_current.h:89
SVGENCURRENT_RunRegenCurrent
static void SVGENCURRENT_RunRegenCurrent(SVGENCURRENT_Handle handle, MATH_Vec3 *pADCData, MATH_Vec3 *pADCDataPrev)
Reconstructs the missed measured currents due to a small sampling window.
Definition: svgen_current.h:371
SVGENCURRENT_USE_ALL
@ SVGENCURRENT_USE_ALL
Use all shunt measurements.
Definition: svgen_current.h:61
SVGENCURRENT_Obj::Vlimit
float32_t Vlimit
The maximum output voltage duty that current can be sampled.
Definition: svgen_current.h:94
SVGENCURRENT_init
SVGENCURRENT_Handle SVGENCURRENT_init(void *pMemory, const size_t numBytes)
Initializes the svgen current object.
SVGENCURRENT_TWO_PHASE_MEASURABLE
@ SVGENCURRENT_TWO_PHASE_MEASURABLE
just two shunt measurable
Definition: svgen_current.h:74
SVGENCURRENT_Obj::ignoreShunt
SVGENCURRENT_IgnoreShunt_e ignoreShunt
Output of what shunt or shunts to ignore.
Definition: svgen_current.h:91
SVGENCURRENT_IgnoreShunt_e
SVGENCURRENT_IgnoreShunt_e
Definition: svgen_current.h:60
SVGENCURRENT_setIgnoreShunt
static void SVGENCURRENT_setIgnoreShunt(SVGENCURRENT_Handle handle, const SVGENCURRENT_IgnoreShunt_e ignoreShunt)
Sets the ignore shunt value.
Definition: svgen_current.h:155
SVGENCURRENT_IGNORE_AC
@ SVGENCURRENT_IGNORE_AC
Ignore the AC phase shunt measurement.
Definition: svgen_current.h:66
SVGENCURRENT_getVmid
static SVGENCURRENT_VmidShunt_e SVGENCURRENT_getVmid(SVGENCURRENT_Handle handle)
Gets the middle amplitude voltage.
Definition: svgen_current.h:272
SVGENCURRENT_MeasureShunt_e
SVGENCURRENT_MeasureShunt_e
Definition: svgen_current.h:72
SVGENCURRENT_ALL_PHASE_MEASURABLE
@ SVGENCURRENT_ALL_PHASE_MEASURABLE
all shunt measurable
Definition: svgen_current.h:73
SVGENCURRENT_getMode
static SVGENCURRENT_MeasureShunt_e SVGENCURRENT_getMode(SVGENCURRENT_Handle handle)
Gets the current reconstruction mode.
Definition: svgen_current.h:256
SVGENCURRENT_getMinWidth
static int16_t SVGENCURRENT_getMinWidth(SVGENCURRENT_Handle handle)
Gets the minimum Duty Cycle width that the lower switch can be on before.
Definition: svgen_current.h:225
SVGENCURRENT_setMinWidth
static void SVGENCURRENT_setMinWidth(SVGENCURRENT_Handle handle, const int16_t minwidth)
Sets the minimum Duty Cycle width that the lower switch can be on before.
Definition: svgen_current.h:137
SVGENCURRENT_Obj::compMode
SVGENCURRENT_MeasureShunt_e compMode
Output phase compensation mode.
Definition: svgen_current.h:92
SVGENCURRENT_IGNORE_ALL
@ SVGENCURRENT_IGNORE_ALL
Ignore the ABC phase shunt measurement.
Definition: svgen_current.h:68
SVGENCURRENT_ONE_PHASE_MEASURABLE
@ SVGENCURRENT_ONE_PHASE_MEASURABLE
just one shunt measurable
Definition: svgen_current.h:75
float32_t
float float32_t
Definition: dcl_common.h:58
SVGENCURRENT_Obj::Voffset
int16_t Voffset
The offset.
Definition: svgen_current.h:95
SVGENCURRENT_VmidShunt_e
SVGENCURRENT_VmidShunt_e
Definition: svgen_current.h:80
SVGENCURRENT_VMID_A
@ SVGENCURRENT_VMID_A
Middle voltage is A phase.
Definition: svgen_current.h:81