AM261x Motor Control SDK  10.02.00
dcl_refgen.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023-2025 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 #ifndef _DCL_REFGEN_H_
33 #define _DCL_REFGEN_H_
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
47 #include "dcl_fdlog.h"
48 #include "../dcl_common.h"
49 
52 #define DCL_REFGEN_MIN_INC 1.0e-06f
53 
56 typedef enum dcl_rgen_modes
57 {
66  REFGEN_SINE3 = 8
68 
71 typedef _DCL_VOLATILE struct dcl_refgen
72 {
92  uint32_t mode;
95 
98 #define DCL_REFGEN_DEFAULTS { 0.0f, 0.0f, \
99  0.0f, 0.0f, \
100  0.0f, 0.0f, 0.0f, \
101  0.0f, 1.0f, 1.0f, 1.0f, -1.0f, \
102  0.0f, 0.0f, 0.0f, 0.0f, \
103  0.0f, 0.0f, 0.0f, \
104  REFGEN_OFF, &(DCL_CSS)DCL_CSS_DEFAULTS }
105 
112 {
113  p->ampl = 0.0f;
114  p->freq = 0.0f;
115  p->rinc = 0.0f;
116  p->theta = 0.0f;
117  p->thetb = 0.0f;
118  p->thetc = 0.0f;
119  p->thinc = 0.0f;
120  p->yr = 0.0f;
121  p->ya = 0.0f;
122  p->yb = 0.0f;
123  p->yc = 0.0f;
124 }
125 
134 {
135 #ifdef DCL_ERROR_HANDLING_ENABLED
136  uint32_t err_code = dcl_none;
137  err_code |= (tr < 0.0f) ? dcl_param_range_err : dcl_none;
138  if (err_code)
139  {
140  DCL_setError(p,err_code);
141  DCL_getErrorInfo(p);
143  }
144 #endif
145 
146  // compute ramp increment
147  tr = (tr < p->css->T) ? p->css->T : tr;
148  p->rtgt = tgt;
149  p->rinc = p->css->T * (tgt - p->yr) / tr;
150 
151  // clamp minimum ramp increment
152  if (!(0.0f == p->rinc) && (fabsf(p->rinc) < DCL_REFGEN_MIN_INC))
153  {
154 #ifdef DCL_ERROR_HANDLING_ENABLED
156  DCL_getErrorInfo(p);
158 #endif
159  if (signbit(p->rinc))
160  {
161  p->rinc = -DCL_REFGEN_MIN_INC;
162  }
163  else
164  {
165  p->rinc = DCL_REFGEN_MIN_INC;
166  }
167  }
168 }
169 
178 {
179 #ifdef DCL_ERROR_HANDLING_ENABLED
180  uint32_t err_code = dcl_none;
181  err_code |= (tr < 0.0f) ? dcl_param_range_err : dcl_none;
182  if (err_code)
183  {
184  DCL_setError(p,err_code);
185  DCL_getErrorInfo(p);
187  }
188 #endif
189 
190  // compute amplitude increment
191  tr = (tr < p->css->T) ? p->css->T : tr;
192  p->amtgt = ampl;
193  p->aminc = p->css->T * (ampl - p->ampl) / tr;
194 
195  // clamp minimum amplitude increment
196  if ((p->aminc > 0.0f) && (fabsf(p->aminc) < DCL_REFGEN_MIN_INC))
197  {
198 #ifdef DCL_ERROR_HANDLING_ENABLED
200  DCL_getErrorInfo(p);
202 #endif
203  if (signbit(p->aminc))
204  {
205  p->aminc = -DCL_REFGEN_MIN_INC;
206  }
207  else
208  {
209  p->aminc = DCL_REFGEN_MIN_INC;
210  }
211  }
212 }
213 
222 {
223 #ifdef DCL_ERROR_HANDLING_ENABLED
224  uint32_t err_code = dcl_none;
225  err_code |= (tr < 0.0f) ? dcl_param_range_err : dcl_none;
226  if (err_code)
227  {
228  DCL_setError(p,err_code);
229  DCL_getErrorInfo(p);
231  }
232 #endif
233 
234  // compute frequency increment
235  tr = (tr < p->css->T) ? p->css->T : tr;
236  p->fmtgt = freq;
237  p->fminc = p->css->T * (freq - p->freq) / tr;
238 
239  // clamp minimum frequency increment
240  if ((p->fminc > 0.0f) && (fabsf(p->fminc) < DCL_REFGEN_MIN_INC))
241  {
242 #ifdef DCL_ERROR_HANDLING_ENABLED
244  DCL_getErrorInfo(p);
246 #endif
247  if (signbit(p->fminc))
248  {
249  p->fminc = -DCL_REFGEN_MIN_INC;
250  }
251  else
252  {
253  p->fminc = DCL_REFGEN_MIN_INC;
254  }
255  }
256 }
257 
265 {
266 #ifdef DCL_ERROR_HANDLING_ENABLED
267  uint32_t err_code = dcl_none;
268  err_code |= ((duty < 0.0f) || (duty > 1.0f)) ? dcl_param_range_err : dcl_none;
269  if (err_code)
270  {
271  DCL_setError(p,err_code);
272  DCL_getErrorInfo(p);
274  }
275 #endif
276 
277  p->duty = duty;
278 }
279 
288 {
289 #ifdef DCL_ERROR_HANDLING_ENABLED
290  uint32_t err_code = dcl_none;
291  err_code |= (max < min) ? dcl_param_range_err : dcl_none;
292  if (err_code)
293  {
294  DCL_setError(p,err_code);
295  DCL_getErrorInfo(p);
297  }
298 #endif
299 
300  p->umax = max;
301  p->umin = min;
302 }
303 
304 
311 void DCL_setRefgenMode(DCL_REFGEN *p, int16_t mode)
312 {
313  p->mode = mode;
314 }
315 
322 {
323 #ifdef DCL_ERROR_HANDLING_ENABLED
324  float32_t v;
325 #endif
326 
327  // static offset generator
328  if (!DCL_isZero(p->rinc))
329  {
330  if (fabsf(p->rinc) > fabsf(p->rtgt - p->yr))
331  {
332  p->yr = p->rtgt;
333  p->rinc = 0.0f;
334  // Adjustment complete
336  }
337  else
338  {
339 #ifdef DCL_ERROR_HANDLING_ENABLED
340  v = p->yr;
341 #endif
342  p->yr += p->rinc;
343 #ifdef DCL_ERROR_HANDLING_ENABLED
344  if (DCL_isZero(v - p->yr))
345  {
346  p->css->err = dcl_comp_err;
347  DCL_getErrorInfo(p);
349  }
350 #endif
351  // Adjustment running
353  }
354  }
355 
356  // amplitude modulator
357  if (!DCL_isZero(p->aminc))
358  {
359  if (fabsf(p->aminc) > fabsf(p->amtgt - p->ampl))
360  {
361  p->ampl = p->amtgt;
362  p->aminc = 0.0f;
363  }
364  else
365  {
366 #ifdef DCL_ERROR_HANDLING_ENABLED
367  v = p->ampl;
368 #endif
369  p->ampl += p->aminc;
370 #ifdef DCL_ERROR_HANDLING_ENABLED
371  if (DCL_isZero(v - p->ampl))
372  {
373  p->css->err = dcl_comp_err;
374  DCL_getErrorInfo(p);
376  }
377 #endif
378  }
379  }
380 
381  // frequency modulator
382  if (!DCL_isZero(p->fminc))
383  {
384  if (fabsf(p->fminc) > fabsf(p->fmtgt - p->freq))
385  {
386  p->freq = p->fmtgt;
387  p->fminc = 0.0f;
388  }
389  else
390  {
391 #ifdef DCL_ERROR_HANDLING_ENABLED
392  v = p->freq;
393 #endif
394  p->freq += p->fminc;
395 #ifdef DCL_ERROR_HANDLING_ENABLED
396  if (DCL_isZero(v - p->freq))
397  {
398  p->css->err = dcl_comp_err;
399  DCL_getErrorInfo(p);
401  }
402 #endif
403  }
404  }
405 
406  // angle increment
407  if (p->freq > 0.0f)
408  {
409  p->thinc = p->css->T * p->freq;
410  if (p->thinc < DCL_REFGEN_MIN_INC)
411  {
412 #ifdef DCL_ERROR_HANDLING_ENABLED
413  p->css->err = dcl_comp_err;
414  DCL_getErrorInfo(p);
416 #endif
417  p->thinc = DCL_REFGEN_MIN_INC;
418  }
419  }
420  else
421  {
422  p->thinc = 0.0f;
423  }
424 
425  p->theta += p->thinc;
426  p->theta -= (p->theta >= 1.0f) ? 1.0f : 0.0f;
427 
428  // dynamic signal generator
429  switch (p->mode)
430  {
431  case REFGEN_STATIC:
432  p->ya = 0.0f;
433  p->yb = 0.0f;
434  p->yc = 0.0f;
435  break;
436 
437  case REFGEN_SINE:
438  p->ya = sinf(CONST_PI * p->theta);
439  p->yb = 0.0f;
440  p->yc = 0.0f;
441  break;
442 
443  case REFGEN_SQUARE:
444  p->ya = (p->theta > 0.5f) ? 1.0f : 0.0f;
445  p->yb = 0.0f;
446  p->yc = 0.0f;
447  break;
448 
449  case REFGEN_SAW:
450  p->ya = p->theta;
451  p->yb = 0.0f;
452  p->yc = 0.0f;
453  break;
454 
455  case REFGEN_TRIANGLE:
456  if (p->theta < 0.5f)
457  {
458  p->ya = 2.0f * p->theta;
459  }
460  else
461  {
462  p->ya = 1.0f - 2.0f * (p->theta - 0.5f);
463  }
464  p->yb = 0.0f;
465  p->yc = 0.0f;
466  break;
467 
468  case REFGEN_PULSE:
469  p->ya = (p->theta > p->duty) ? 0.0f : 1.0f;
470  p->yb = 0.0f;
471  p->yc = 0.0f;
472  break;
473 
474  case REFGEN_SINE2:
475  p->ya = sinf(CONST_2PI * p->theta);
476  p->yb = cosf(CONST_2PI * p->theta);
477  p->yc = 0.0f;
478  break;
479 
480  case REFGEN_SINE3:
481  p->thetb = p->theta + 0.3333333333333f;
482  p->thetc = p->theta + 0.6666666666667f;
483  p->thetb -= (p->thetb >= 1.0f) ? 1.0f : 0.0f;
484  p->thetc -= (p->thetc >= 1.0f) ? 1.0f : 0.0f;
485  p->ya = sinf(CONST_2PI * p->theta);
486  p->yb = sinf(CONST_2PI * p->thetb);
487  p->yc = sinf(CONST_2PI * p->thetc);
488  break;
489 
490  case REFGEN_OFF:
491  default:
492  p->yr = 0.0f;
493  p->ya = 0.0f;
494  p->yb = 0.0f;
495  p->yc = 0.0f;
496  }
497 
498  // output sum & saturation
499  p->ya = DCL_runSat(p->ampl * p->ya + p->yr, p->umax, p->umin);
500  p->yb = DCL_runSat(p->ampl * p->yb + p->yr, p->umax, p->umin);
501  p->yc = DCL_runSat(p->ampl * p->yc + p->yr, p->umax, p->umin);
502 }
503 
511 {
512  return(p->ya);
513 }
514 
522 {
523  return(p->yb);
524 }
525 
533 {
534  return(p->yc);
535 }
536 
539 #ifdef __cplusplus
540 }
541 #endif // extern "C"
542 
543 #endif // _DCL_REFGEN_H_
dcl_refgen::mode
uint32_t mode
Operating mode.
Definition: dcl_refgen.h:92
DCL_resetRefgen
_DCL_CODE_ACCESS void DCL_resetRefgen(DCL_REFGEN *p)
Resets DCL_REFGEN dynamic data.
Definition: dcl_refgen.h:111
CONST_2PI
#define CONST_2PI
Definition: dcl_macro.h:54
REFGEN_TRIANGLE
@ REFGEN_TRIANGLE
Definition: dcl_refgen.h:63
DCL_setRefgenClamp
_DCL_CODE_ACCESS void DCL_setRefgenClamp(DCL_REFGEN *p, float32_t max, float32_t min)
Loads the REFGEN output clam limits.
Definition: dcl_refgen.h:287
dcl_refgen::theta
float32_t theta
Normalized angle - phase A.
Definition: dcl_refgen.h:86
CONST_PI
#define CONST_PI
Local definitions of the mathematical constant pi.
Definition: dcl_macro.h:53
dcl_refgen::thetb
float32_t thetb
Normalized angle - phase B.
Definition: dcl_refgen.h:87
DCL_setRefgenMode
_DCL_CODE_ACCESS void DCL_setRefgenMode(DCL_REFGEN *p, int16_t mode)
Sets the REFGEN operating mode.
Definition: dcl_refgen.h:311
REFGEN_PULSE
@ REFGEN_PULSE
Definition: dcl_refgen.h:64
dcl_refgen::freq
float32_t freq
Dynamic frequency.
Definition: dcl_refgen.h:85
REFGEN_STATIC
@ REFGEN_STATIC
Definition: dcl_refgen.h:59
DCL_getRefgenPhaseB
_DCL_CODE_ACCESS float32_t DCL_getRefgenPhaseB(DCL_REFGEN *p)
Returns the phase reference output.
Definition: dcl_refgen.h:521
DCL_REFGEN_MIN_INC
#define DCL_REFGEN_MIN_INC
Defines the minimum normalized increment.
Definition: dcl_refgen.h:52
DCL_setRefgenFreq
_DCL_CODE_ACCESS void DCL_setRefgenFreq(DCL_REFGEN *p, float32_t freq, float32_t tr)
Loads the REFGEN frequency.
Definition: dcl_refgen.h:221
DCL_setRefgenRamp
_DCL_CODE_ACCESS void DCL_setRefgenRamp(DCL_REFGEN *p, float32_t tgt, float32_t tr)
Loads the REFGEN ramp parameters.
Definition: dcl_refgen.h:133
DCL_setUpdateStatus
#define DCL_setUpdateStatus(p)
Macros to set and clear the update-in-progress flag.
Definition: dcl_css.h:114
dcl_none
@ dcl_none
No error.
Definition: dcl_error.h:57
dcl_refgen::yc
float32_t yc
Phase C output.
Definition: dcl_refgen.h:91
DCL_runErrorHandler
#define DCL_runErrorHandler(ptr)
Prototype for basic error handler.
Definition: dcl_error.h:108
dcl_refgen::css
DCL_CSS * css
Pointer to the common support structure.
Definition: dcl_refgen.h:93
dcl_refgen::yr
float32_t yr
Ramp generator output.
Definition: dcl_refgen.h:83
REFGEN_OFF
@ REFGEN_OFF
Definition: dcl_refgen.h:58
DCL_clearUpdateStatus
#define DCL_clearUpdateStatus(p)
Definition: dcl_css.h:115
dcl_refgen::fminc
float32_t fminc
Frequency increment.
Definition: dcl_refgen.h:78
REFGEN_SQUARE
@ REFGEN_SQUARE
Definition: dcl_refgen.h:61
_DCL_CODE_ACCESS
#define _DCL_CODE_ACCESS
Defines the scope of dcl functions.
Definition: dcl_common.h:63
dcl_refgen::ampl
float32_t ampl
Dynamic amplitude.
Definition: dcl_refgen.h:84
dcl_refgen::aminc
float32_t aminc
Amplitude increment.
Definition: dcl_refgen.h:76
DCL_setRefgenDuty
_DCL_CODE_ACCESS void DCL_setRefgenDuty(DCL_REFGEN *p, float32_t duty)
Loads the REFGEN pulse duty cycle.
Definition: dcl_refgen.h:264
DCL_refgen_modes
DCL_refgen_modes
Defines the REFGEN operating modes.
Definition: dcl_refgen.h:57
dcl_refgen
Defines the DCL_REFGEN structure.
Definition: dcl_refgen.h:72
dcl_refgen::thinc
float32_t thinc
Angular increment.
Definition: dcl_refgen.h:79
dcl_refgen::fmtgt
float32_t fmtgt
Frequency ramp value.
Definition: dcl_refgen.h:77
dcl_refgen::umin
float32_t umin
Minimum allowable output.
Definition: dcl_refgen.h:82
dcl_refgen::thetc
float32_t thetc
Normalized angle - phase C.
Definition: dcl_refgen.h:88
REFGEN_SINE3
@ REFGEN_SINE3
Definition: dcl_refgen.h:66
DCL_REFGEN
_DCL_VOLATILE struct dcl_refgen DCL_REFGEN
dcl_refgen::umax
float32_t umax
Maximum allowable output.
Definition: dcl_refgen.h:81
dcl_refgen::yb
float32_t yb
Phase B output.
Definition: dcl_refgen.h:90
DCL_isZero
#define DCL_isZero(x)
Determines floating point numerical proximity to zero.
Definition: dcl_macro.h:75
DCL_getRefgenPhaseA
_DCL_CODE_ACCESS float32_t DCL_getRefgenPhaseA(DCL_REFGEN *p)
Returns the phase reference output.
Definition: dcl_refgen.h:510
dcl_param_range_err
@ dcl_param_range_err
Parameter range exceeded.
Definition: dcl_error.h:58
dcl_refgen::duty
float32_t duty
Pulse duty cycle.
Definition: dcl_refgen.h:80
DCL_runSat
#define DCL_runSat(data, Umax, Umin)
Macro to saturate a control variable but does not change the data itself unlike runClamp()
Definition: dcl_clamp.h:90
REFGEN_SINE
@ REFGEN_SINE
Definition: dcl_refgen.h:60
DCL_CSS
Defines the controller common support structure.
Definition: dcl_css.h:56
DCL_setRefgenAmpl
_DCL_CODE_ACCESS void DCL_setRefgenAmpl(DCL_REFGEN *p, float32_t ampl, float32_t tr)
Loads the REFGEN dynamic amplitude.
Definition: dcl_refgen.h:177
_DCL_VOLATILE
#define _DCL_VOLATILE
Defines volatile for DCL strctures Flags can be defined in dcl.h or user files before including DCL l...
Definition: dcl_common.h:75
DCL_getRefgenPhaseC
_DCL_CODE_ACCESS float32_t DCL_getRefgenPhaseC(DCL_REFGEN *p)
Returns the phase reference output.
Definition: dcl_refgen.h:532
dcl_fdlog.h
Defines a 32-bit floating-point data logger strcture and related functions.
dcl_refgen::rtgt
float32_t rtgt
Target ramp value.
Definition: dcl_refgen.h:73
DCL_getErrorInfo
#define DCL_getErrorInfo(ptr)
Macro to store error info in CSS.
Definition: dcl_error.h:98
dcl_refgen::amtgt
float32_t amtgt
Target amplitude value.
Definition: dcl_refgen.h:75
DCL_setError
#define DCL_setError(ptr, code)
Macro to set error code in CSS.
Definition: dcl_error.h:80
REFGEN_SINE2
@ REFGEN_SINE2
Definition: dcl_refgen.h:65
REFGEN_SAW
@ REFGEN_SAW
Definition: dcl_refgen.h:62
dcl_comp_err
@ dcl_comp_err
Computation error.
Definition: dcl_error.h:66
dcl_refgen::ya
float32_t ya
Phase A output.
Definition: dcl_refgen.h:89
float32_t
float float32_t
Definition: dcl_common.h:58
dcl_refgen::rinc
float32_t rinc
Ramp increment.
Definition: dcl_refgen.h:74
DCL_runRefgen
_DCL_CODE_ACCESS void DCL_runRefgen(DCL_REFGEN *p)
Runs the REFGEN module.
Definition: dcl_refgen.h:321