DCL User's Guide
DCL User's Guide
Version 3.4
User’s Guide
February 2020
Preface
The User’s Guide is divided into six chapters. Chapter 1 presents a general introduction
to the library and provides background information. Chapter 2 describes the library
contents and structure, how to add library functions to a user’s program, and how to
migrate existing source code. Chapter 3 describes the controllers and supporting
functions, and provides information on their use. Chapter 4 describes the utilities supplied
with the library, including data loggers, a transient capture module, and simulation
models. Chapter 5 describes a set of supporting software examples which illustrate the
use of the library. A list of relevant technical references and training can be found in
Chapter 6.
iii
Contents
iv
Contents
DCL_runPID_C2 ............................................................................................................................. 32
DCL_runPID_C3 ............................................................................................................................. 33
DCL_runPID_C4 ............................................................................................................................. 33
DCL_runPID_L1 .............................................................................................................................. 34
DCL_runPID_L2 .............................................................................................................................. 34
DCL_resetPID ................................................................................................................................. 34
DCL_updatePID .............................................................................................................................. 35
DCL_fupdatePID ............................................................................................................................. 35
DCL_setPIDfilterBW........................................................................................................................ 35
DCL_setActivePIDfilterBW .............................................................................................................. 36
DCL_getPIDfilterBW ....................................................................................................................... 36
DCL_loadSeriesPIDasZPK ............................................................................................................. 36
DCL_loadParallelPIDasZPK ........................................................................................................... 37
3.2 Linear PI Controllers................................................................................................................ 37
3.2.1 Description ................................................................................................................................. 37
3.2.2 Implementation ........................................................................................................................... 38
3.2.3 Functions .................................................................................................................................... 40
DCL_runPI_C1 ................................................................................................................................ 40
DCL_runPI_C2 ................................................................................................................................ 40
DCL_runPI_C3 ................................................................................................................................ 40
DCL_runPI_C4 ................................................................................................................................ 41
DCL_runPI_C5 ................................................................................................................................ 41
DCL_runPI_C6 ................................................................................................................................ 42
DCL_runPI_C7 ................................................................................................................................ 42
DCL_runPI_L1 ................................................................................................................................ 42
DCL_runPI_L2 ................................................................................................................................ 43
DCL_runPI_L3 ................................................................................................................................ 43
DCL_runPI_L4 ................................................................................................................................ 43
DCL_runPI_L5 ................................................................................................................................ 44
DCL_resetPI.................................................................................................................................... 44
DCL_updatePI................................................................................................................................. 44
DCL_fupdatePI................................................................................................................................ 45
DCL_loadSeriesPIasZPK ................................................................................................................ 45
DCL_loadParallelPIasZPK .............................................................................................................. 45
3.3 Non-linear PID Controller ........................................................................................................ 46
3.3.1 Description ................................................................................................................................. 46
3.3.2 Implementation ........................................................................................................................... 50
3.3.3 Functions .................................................................................................................................... 51
DCL_runNLPID_C1......................................................................................................................... 51
DCL_runNLPID_C2......................................................................................................................... 51
DCL_runNLPID_C3......................................................................................................................... 52
DCL_setActiveNLPIDGamma ......................................................................................................... 52
DCL_setNLPIDGamma ................................................................................................................... 52
DCL_resetNLPID ............................................................................................................................ 53
DCL_updateNLPID ......................................................................................................................... 53
DCL_setActiveNLPIDfilterBW ......................................................................................................... 53
DCL_setNLPIDfilterBW ................................................................................................................... 54
DCL_getNLPIDfilterBW ................................................................................................................... 54
DCL_getNLPIDgamma ................................................................................................................... 54
DCL_getNLPIDdelta........................................................................................................................ 55
3.4 Non-linear PI Controllers ......................................................................................................... 55
v
Contents
3.4.1 Description..................................................................................................................................55
3.4.2 Implementation ...........................................................................................................................55
3.4.3 Functions ....................................................................................................................................56
DCL_runNLPI_C1 ........................................................................................................................... 56
DCL_resetNLPI ............................................................................................................................... 56
DCL_updateNLPI ............................................................................................................................ 56
3.5 Double Integrator PI Controller ............................................................................................... 57
3.5.1 Description..................................................................................................................................57
3.5.2 Implementation ...........................................................................................................................57
3.5.3 Functions ....................................................................................................................................57
DCL_runPI2_C1 ............................................................................................................................. 57
DCL_resetPI2 ................................................................................................................................. 58
DCL_updatePI2 .............................................................................................................................. 58
DCL_fupdatePI2 ............................................................................................................................. 59
3.6 Direct Form 1 (First Order) Compensators ............................................................................. 59
3.6.1 Description..................................................................................................................................59
3.6.2 Implementation ...........................................................................................................................60
3.6.3 Functions ....................................................................................................................................60
DCL_runDF11_C1 .......................................................................................................................... 60
DCL_runDF11_C2 .......................................................................................................................... 60
DCL_runDF11_L1 ........................................................................................................................... 61
DCL_resetDF11 .............................................................................................................................. 61
DCL_updateDF11 ........................................................................................................................... 61
DCL_fupdateDF11 .......................................................................................................................... 62
DCL_isStableDF11 ......................................................................................................................... 62
DCL_loadDF11asZPK .................................................................................................................... 62
DCL_loadDF11asPI ........................................................................................................................ 63
3.7 Direct Form 1 (Third Order) Compensators ............................................................................ 63
3.7.1 Description..................................................................................................................................63
3.7.2 Implementation ...........................................................................................................................65
3.7.3 Functions ....................................................................................................................................67
DCL_runDF13_C1 .......................................................................................................................... 67
DCL_runDF13_C2 .......................................................................................................................... 67
DCL_runDF13_C3 .......................................................................................................................... 67
DCL_runDF13_C4 .......................................................................................................................... 68
DCL_runDF13_C5 .......................................................................................................................... 68
DCL_runDF13_C6 .......................................................................................................................... 68
DCL_runDF13_L1 ........................................................................................................................... 69
DCL_runDF13_L2 ........................................................................................................................... 69
DCL_runDF13_L3 ........................................................................................................................... 69
DCL_runDF13_L4 ........................................................................................................................... 70
DCL_runDF13_L5 ........................................................................................................................... 70
DCL_runDF13_L6 ........................................................................................................................... 70
DCL_resetDF13 .............................................................................................................................. 71
DCL_updateDF13 ........................................................................................................................... 71
DCL_fupdateDF13 .......................................................................................................................... 72
DCL_isStableDF13 ......................................................................................................................... 72
DCL_loadDF13asZPK .................................................................................................................... 72
3.8 Direct Form 2 (Second Order) Compensators ........................................................................ 73
3.8.1 Description..................................................................................................................................73
3.8.2 Implementation ...........................................................................................................................74
3.8.3 Functions ....................................................................................................................................75
vi
Contents
DCL_runDF22_C1 .......................................................................................................................... 75
DCL_runDF22_C2 .......................................................................................................................... 75
DCL_runDF22_C3 .......................................................................................................................... 75
DCL_runDF22_C4 .......................................................................................................................... 76
DCL_runDF22_C5 .......................................................................................................................... 76
DCL_runDF22_C6 .......................................................................................................................... 76
DCL_runDF22_L1 ........................................................................................................................... 77
DCL_runDF22_L2 ........................................................................................................................... 77
DCL_runDF22_L3 ........................................................................................................................... 77
DCL_runDF22_L4 ........................................................................................................................... 78
DCL_resetDF22 .............................................................................................................................. 78
DCL_updateDF22 ........................................................................................................................... 78
DCL_fupdateDF22 .......................................................................................................................... 79
DCL_isStableDF22 ......................................................................................................................... 79
DCL_loadDF22asZPK..................................................................................................................... 79
DCL_loadDF22asZwn ..................................................................................................................... 80
DCL_loadDF22asParallelPID.......................................................................................................... 80
DCL_loadDF22asSeriesPID ........................................................................................................... 81
3.9 Direct Form 2 (Third Order) Compensators ............................................................................ 81
3.9.1 Description ................................................................................................................................. 81
3.9.2 Implementation ........................................................................................................................... 83
3.9.3 Functions .................................................................................................................................... 83
DCL_runDF23_C1 .......................................................................................................................... 83
DCL_runDF23_C2 .......................................................................................................................... 84
DCL_runDF23_C3 .......................................................................................................................... 84
DCL_runDF23_C4 .......................................................................................................................... 84
DCL_runDF23_C5 .......................................................................................................................... 85
DCL_runDF23_C6 .......................................................................................................................... 85
DCL_runDF23_L1 ........................................................................................................................... 85
DCL_runDF23_L2 ........................................................................................................................... 86
DCL_runDF23_L3 ........................................................................................................................... 86
DCL_resetDF23 .............................................................................................................................. 86
DCL_updateDF23 ........................................................................................................................... 87
DCL_fupdateDF23 .......................................................................................................................... 87
DCL_isStableDF23 ......................................................................................................................... 87
DCL_loadDF23asZPK..................................................................................................................... 88
3.10 Fixed-Point PID Controllers ..................................................................................................... 88
3.10.1 Description ................................................................................................................................. 88
3.10.2 Implementation ........................................................................................................................... 88
3.10.3 Functions .................................................................................................................................... 90
DCL_runPID_A1 ............................................................................................................................. 90
DCL_resetPID32 ............................................................................................................................. 91
DCL_updatePID32 .......................................................................................................................... 91
DCL_fupdatePID32 ......................................................................................................................... 91
3.11 Fixed-Point PI Controllers ....................................................................................................... 92
3.11.1 Description ................................................................................................................................. 92
3.11.2 Implementation ........................................................................................................................... 92
3.11.3 Functions .................................................................................................................................... 93
DCL_runPI_A1 ................................................................................................................................ 93
DCL_resetPI32................................................................................................................................ 93
DCL_updatePI32............................................................................................................................. 94
DCL_fupdatePI32............................................................................................................................ 94
vii
Contents
viii
Contents
ix
Contents
x
Contents
xi
Figures
Figures
xii
Tables
Tables
xiii
Chapter 1
Introduction
This chapter contains a brief introduction to the Texas Instruments C2000 Digital Control
Library (DCL).
Section
1.1 Supported Devices
1.4 Benchmarks
Controller functions contain a suffix which identifies which CPU they are intended to be
used with (see section 1.3.3). The following list provides an overview of the CPU
availability on each class of C2000 device. Users should consult the datasheet for their
chosen device to determine which CPU combination is present.
1
Introduction
TMS320F2806x
TMS320F28M35x
TMS320F28M36x
Some FPU32 devices also contain a Trigonometric Math Unit (TMU) which extends the
instruction set to provide support for trigonometric and other math operations. The DCL
makes use of the TMU wherever possible. Refer to the controller descriptions for more
information.
The library also includes functions optimized for use on the Control Law Accelerator
(CLA). This CPU is only found on certain C2000 devices, including:
TMS320F28004x
TMS320F2838x
TMS320F2837x
TMS320F2807x
TMS320F2806x
TMS320F2805x
TMS320F2803x
The DCL includes limited support for fixed-point C28x platforms in the form of two
controllers and two data logging modules. Among the devices supported in this way are:
TMS320F2805x
TMS320F2804x
TMS320F2803x
TMS320F2802x
TMS320F281x
TMS320F280x
Fixed-point (C28x) DCL library functions will also run un-modified on any device which
contains an FPU32. The DCL does not support the C24x CPU.
The C28x Run Time Support (RTS) library allows FPU32 functions written in C to be run
on the fixed point C28x, however RTS emulation of the floating point data type is not cycle
efficient and the library has not been tested in this way. Users are advised to run only
those controller and CPU combinations recommended in this User’s Guide. A list of
controllers and compatible CPUs can be found in Table 1.
The DCL functions are intended for use in any system in which a C2000 device is used.
The DCL may not be used with any other devices. Refer to the C2000Ware license
agreement for further information.
2
Introduction
The DCL is independent of other application specific C2000 software libraries and
Software Development Kits (SDKs), however providing attention is paid to data type and
numerical range, integration with those packages is straightforward.
The DCL contains PID and “Direct Form” controller types. The former are typically used
to tune properties of a transient response, while the latter are typically used to shape the
open loop frequency response. The DCL contains functions to convert controller
parameters from one type to the other; for example, the user may emulate PID control
using a direct form 2 controller structure. The library also contains a gain scheduler
module.
The library includes a set of example projects which illustrate how DCL functions might be
applied in a user project. The library itself contains no device specific code and users of
other C2000 devices will find it straightforward to apply the examples to their own
projects.
The DCL does not contain tools to measure frequency response or perform compensator
parameter selection; however similar features can be found in the “Compensation
Designer” utility which is part of the TI “powerSUITE” package. A Software Frequency
Response Analyzer (SFRA) utility can be found at: www.ti.com/tool/sfra.
Also added in version 3.4 is support for the DF22 compensator in double precision floating
point. The controller is designated DF22F64 and more information can be found in
chapter 3. A double precision clamp has also been added to support this controller.
The macro DCL_CLEAR_ERROR_CODE has been added to DCL.h to set the stored
error in the CSS sub-structure to ERR_NONE.
Controller update and run functions which are coded as static inline are now placed in the
“dclfuncs” section using a CODE_SECTION pragma. This allows time critical functions to
be copied into RAM at run-time. This change has been made to the files: DCLF32.h,
DCLF64.h, and DCL_NLPID.h. Some functions in the new reference generator module
are also placed in this section.
Library break-points now insert the ESTOP0 assembly instruction instead of NOP. This
instruction inserts a software break-point so the user no longer has to manually set a
break-point in CCS. In stand-alone mode, ESTOP0 is replaced by a NOP instruction. As
before, break-points can be disabled by commenting out the definition of
DCL_BREAK_POINTS_ENABLED in DCL.h.
The C code in DCL_error.c has been simplified. This code is intended for users to modify
to implement their own custom error handlers.
3
Introduction
The naming convention allows several controllers of similar type, but with different
implementations, to be used together in the same program without conflict. An example
of a library function name, together with a description of the constituent fields, is shown
below.
In addition to “run”, all control structures have associated “reset” and “update” functions.
The first resets all internal non-parametric data to its default values without changing any
controller parameters. The second performs a safe parameter update without changing
any non-parametric control data. Note that the “update” function requires both SPS and
CSS structures. The same “verb-noun” function name construction shown in Figure 1
applies to all supporting functions.
The DCL includes an implementation of a 64-bit floating point PID controller. This
controller uses the letter “S” as the CPU identifier to distinguish it from the similar FPU32
controllers. It may be compiled and run on an FPU32, however without hardware support
4
Introduction
for the double precision data type relatively poor cycle performance should be expected.
Refer to Table 6 and Table 7 for further information.
The first such sub-structure contains a Shadow Parameter Set (SPS), which the user
loads prior to executing a parameter update sequence. The update sequence performs a
safe copy of the SPS parameters into the main controller structure by disabling interrupts
before the copy sequence and re-enabling them afterwards. This ensures the controller
never runs with a partially updated parameter set, and allows controller parameters to be
updated without disturbing the control loop.
The second sub-structure is a Common Support Structure (CSS). The CSS contains
supporting data used for error checking and parameter updates.
The use of SPS and CSS is optional. Users who do not need the additional features
provided by SPS and CSS may safely ignore these structures.
Equation 1. 𝐹 𝑧 𝐾
5
Introduction
In Equation 1, q1, q2, and q3, represent the frequencies of the three zeros in Hz; p1, p2,
and p3 represent the frequencies of the three poles in Hz; and K is the real gain.
The ZPK3 structure is also used in the library to represent first and second order transfer
functions. In each case, poles and zeros on the right being ignored. For example, in a 1-
pole, 1-zero description, only K, q1, and p1 are relevant; the user function will ignore q2,
q3, p2, & p3.
The DCL functions which take ZPK3 arguments allow complex poles and zeros providing
they exist in conjugate pairs, thereby resulting in real polynomial coefficients. Error
checking is built into those functions to ensure this is always the case.
DCL_PID No Yes No No
DCL_PI No Yes No No
DCL_PI2 No Yes No No
DCL_NLPID No Yes No No
DCL_NLPI No Yes No No
DCL_DF11 No Yes No No
DCL_DF13 No Yes No No
DCL_DF22 No Yes No No
DCL_DF23 No Yes No No
6
Introduction
DCL_GSM No Yes No No
DCL_PID_CLA No No No Yes
DCL_PI_CLA No No No Yes
DCL_DF11_CLA No No No Yes
DCL_DF13_CLA No No No Yes
DCL_DF22_CLA No No No Yes
DCL_DF23_CLA No No No Yes
DCL_PID32 Yes No No No
DCL_PI32 Yes No No No
FDLOG No Yes No No
MLOG No Yes No No
TCM No Yes No No
FDLOG32 Yes No No No
MLOG32 Yes No No No
1.5 Benchmarks
7
Introduction
DCL_runPID_C1 83 99
DCL_runPID_C2 197 207
DCL_runPID_C3 186 196
DCL_runPID_C4 86 92
DCL_runPID_L1 53 70
DCL_runPID_L2 45 58
DCL_runPI_A1 62 46
DCL_runPI_C1 52 54
DCL_runPI_C2 117 121
DCL_runPI_C3 122 126
DCL_runPI_C4 48 37
DCL_runPI_C5 194 180
DCL_runPI_C6 140 133
DCL_runPI_C7 51 40
DCL_runPI_L1 34 42
DCL_runPI_L2 33 40
DCL_runPI_L3 118 238
DCL_runPI_L4 122 248
DCL_runPI_L5 138 272
(1)(2)
DCL_runNLPID_C1 284
312
DCL_setGamma 2090(2)
DCL_runNLPID_C2 3353(1) 3297(1)
DCL_runNLPID_C3 117 185
(1)
DCL_runNLPI 2230 2197(1)
DCL_runPI2_C1 218 201
DCL_runDF11_C1 37 23
DCL_runDF11_C2 60
DCL_runDF11_L1 30 34
DCL_runDF13_C1 71 66
DCL_runDF13_C2 20
79
DCL_runDF13_C3 74
DCL_runDF13_C4 175 162
DCL_runDF13_C5 40 38
DCL_runDF13_C6 121 126
DCL_runDF13_L1 61 86
DCL_runDF13_L2 20
100
DCL_runDF13_L3 58
DCL_runDF22_C1 44 45
DCL_runDF22_C2 19
48
DCL_runDF22_C3 39
DCL_runDF22_C4 71 75
8
Introduction
DCL_runDF22_C5 29 26
DCL_runDF22_C6 60 67
DCL_runDF22_L1 33 40
DCL_runDF22_L2 20
60
DCL_runDF22_L3 34
DCL_runDF22_L4 83 146
DCL_runDF23_C1 62 64
DCL_runDF23_C2 20
69
DCL_runDF23_C3 54
DCL_runDF23_C4 98 107
DCL_runDF23_C5 29 26
DCL_runDF23_C6 82 97
DCL_runDF23_L1 44 60
DCL_runDF23_L2 20
80
DCL_runDF23_L3 44
DCL_runGSM_C1 50 TBD
(1)
DCL_runNLF_C1 1075 1075(1)
DCL_runPIDF64_S1(4) 2840 310
DCL_writeLog 48 N/A
DCL_readLog 39 N/A
DCL_freadLog 22 11
DCL_fwriteLog 22 14
DCL_runClamp_C1 28
20
DCL_runClamp_C2 71
DCL_runClamp_L1 25 26
(3)
DCL_runITAE_C1
(3) 60
DCL_runIAE_C1
(3)
DCL_runIES_C1
(1)
All paths operating in linearized error region. For all paths in non-linear operation, total
cycle count is approximately 1,433. See section 3.3.1 for more information.
(2)
Measured with run-time library support for the powf() function.
(3)
Cycle count depends on buffer length. Refer to section 3.4.1 for more information.
(4)
Refer to Table 6.
9
Introduction
10
Introduction
11
Introduction
DCL_fupdatePID DCL_futils.asm 77 37 37
DCL_fupdatePI DCL_futils.asm 64 37 24
DCL_fupdatePI2 DCL_futils.asm 57 37 17
DCL_fupdateDF11 DCL_futils.asm 58 37 31
DCL_fupdateDF13 DCL_futils.asm 78 37 38
DCL_fupdateDF22 DCL_futils.asm 66 37 26
DCL_fupdateDF23 DCL_futils.asm 74 37 34
DCL_fupdatePID32 DCL_futils32.asm 73 37 33
DCL_fupdatePI32 DCL_futils32.asm 57 37 17
12
Introduction
13
Using the Digital Control Library
Chapter 2
Section
2.1 What the Library Contains
Inline C code
14
Using the Digital Control Library
15
Using the Digital Control Library
(1)
Requires TMU type 1. Refer to device datasheet for more information.
2.1.3 Examples
A set of code examples is supplied with the Digital Control Library. These were prepared
using CCS version 8.3.0 and run without modification on either the F28069, F280049, or
F28388D device. The examples include linker command files which show how to allocate
device memory when using the DCL. Further details can be found in Chapter 5.
16
Using the Digital Control Library
17
Using the Digital Control Library
Before you can begin using the library you must add the appropriate controller header file
to your project.
To use the 32-bit floating-point DCL functions include the file DCLF32.h.
#include “DCLF32.h”
To use double precision floating point DCL functions include the file DCLF64.h.
#include “DCLF64.h”
#include “DCL_NLPID.h”
It is not necessary to explicitly include the common library file DCL.h since that file is
included in the controller header files above.
CCS must be configured in such a way that the DCL header files are visible to all program
source files which reference controller variables or functions. The include file search
options in CCS allow users to specify header file paths for each project. In CCS, the
18
Using the Digital Control Library
If you wish to use any of the assembly coded controllers, the source file(s) for the
controller(s) you wish to use must be added to your CCS project. You can manually copy
the files into your project directory, or specify the library pathname in the CCS compiler
options. Refer to Table 9 for a list of controller source files. It is only necessary to add
the source files for those functions you wish to use.
DCL functions which run on the FPU32 or C28x core can be allocated to a specific
memory block in the linker command file. It is common to place the controller functions in
zero wait-state internal RAM since this allows them to run at the maximum speed of the
device. Note that all CLA functions must run from internal zero wait-state RAM.
All DCL library functions are placed in the user defined code section .dclfuncs. An
example showing how this section might be mapped into the internal L4 RAM memory
block is shown below.
dclfuncs : > RAML4, PAGE = 0
See also the linker command file F28069_DCL.cmd in the project examples (chapter 5).
19
Using the Digital Control Library
You must declare an instance of the controller you wish to use. For example, to create an
initialized instance of a 32-bit floating-point PID controller with the name “pid1”:
DCL_PID pid1 = PID_DEFAULTS;
This step will create an instance of a PID controller structure the elements of which are
loaded with default parameter and data values specified in the file DCLF32.h.
Note that CLA variables must be initialized at run-time by user code (i.e. they cannot be
initialized at the variable declaration). Typically this is done using a separate CLA task
(see code examples 2 & 4).
If you wish to make use of the error checking or safe parameter update features in the
library, you must declare instances of both the SPS and CSS sub-structures, and initialize
them appropriately. If you do not wish to use these features, this step can be ignored.
To declare an initialized instance of the SPS for the PID controller, you would do the
following:
DCL_PID_SPS spid = PID_SPS_DEFAULTS;
To declare an initialized instance of the CSS for the PID controller, you would do the
following:
DCL_CSS cpid = DCL_CSS_DEFAULTS;
Assign each of the above structures to the PID control structure in step 4.
pid1.sps = &spid;
pid1.css = &cpid;
This creates a variable of type “DCL_PID”, the elements of which are initialized to default
values specified in the DCL.h header file. Like any C variable, the structure must be
visible to any source files which reference it.
Functions which use the update rate of the controller require the “T” element of the CSS
sub-structure to be loaded in advance. This can be done using the
DCL_SET_CONTROLLER_PERIOD macro. For example, an update period of 100 ms
would be loaded as follows:
DCL_SET_CONTROLLER_PERIOD(pid1, 0.1f);
In addition to a pointer to the controller structure, each DCL controller function requires
certain input variables to be passed as arguments to the function, and will return a control
output. You should declare instances of these variables in your code and ensure they can
be referenced by all files which call the controller functions. For example:
float uk; // control
20
Using the Digital Control Library
Note that CLA variables cannot be initialized at the declaration. Refer to the CLA code in
chapter 5 for examples of how to initialize CLA variables.
The elements of the (FPU32 or C28x) controller structure were initialized to default
settings in step 3. The user program must configure any controller elements with specific
values before the function is called. For example:
pid1.Kp = 9.4f; // set proportional gain to 9.4
pid1.Umax = 10.0f; // upper output clamp limit = 10
If a CLA based controller is being used, its parameters must always be initialized using a
separate task. For more information on the CLA C compiler, see Chapter 10 of the
“TMS320C28x Optimizing C/C++ Compiler User’s Guide”.
Direct Form control structures incorporate one or two delay lines which hold previous
controller data. These must be initialized to zero before calling the controller functions,
which can be done with the appropriate “DCL_reset” function. If this is not done, it is
possible that uninitialized delay line data, especially in the recursive path, might cause the
controller to saturate or deliver incorrect results. Initialization of the delay line elements is
the responsibility of the user. Refer to the code in examples 1 and 2 described in chapter
4 for examples of delay line initialization.
Typically the controller functions would be inserted into an Interrupt Service Routine (ISR)
which is triggered by a hardware timer. Each control function returns a single floating-
point variable which represents the controller output. An example of an FPU32 controller
function call is shown below.
uk = DCL_runPID_C1(&pid1, rk, yk lk);
For the C28x, refer to sections 7.2 and 7.3 of the “TMS320C28x Optimizing C/C++
Compiler User’s Guide” for detailed information on register usage and calling conventions.
For the CLA, refer to section 10.2.4 of the same document.
21
Using the Digital Control Library
Load all the elements of the SPS sub-structure with the new controller values. Continuing
the example in section 2.3.1, one might do this:
pid1.sps.Kp = 10.987f;
pid1.sps.Ki = 0.0023f;
Ensure all the SPS elements are loaded before performing the update, even if they do not
need to change.
Set the update flag in the CSS status register to enable the parameter copy on the next
call to the update function. There is a C macro in DCL.h to do this.
DCL_REQUEST_UPDATE(&pid1);
This sets the LSB in the status element sts in the CSS sub-structure to indicate that an
update is pending.
Call the appropriate controller update function. This would typically be done in the
background loop.
DCL_updatePID(&pid1);
This function tests the update flag to determine whether an update is pending. If so, it
blocks the device interrupts, performs the shadow to active parameter set copy, re-
enables device interrupts, and clears the update request flag previously set in step 1.
In blocking interrupts, the library will save the prior state of the global interrupt flag (INTM)
into a local variable. The state is restored when interrupts are re-enabled at the end of
the update. In this way, update functions may be called by the user irrespective of
whether interrupts are already enabled: the function will not change the prior interrupt
state. A similar method of interrupt blocking and protection is implemented in the ‘reset’
functions to ensure controllers do not run with partially reset internal variables. Interrupt
blocking macros and functions can be found in the library header file DCL.h.
Updating controller parameters is a time critical task since interrupts must be disabled
while copying takes place. For this reason the library includes a set of assembly coded
update functions which are used in the same way described above, but which execute
faster than their C counterparts and are deterministic. In all cases, the same update
function names are pre-fixed with the letter ‘f’, so the above example becomes
DCL_fupdatePID(&pid1);
The floating point assembly update routines are contained in the source file
DCL_futils.asm which must be added to the user’s project. At the top of this file is a
list of “.set” directives which allows the user to selectively disable those functions which
are not required in order to reduce code space.
The table below lists the fast parameter update functions together with the cycle counts
when an update is performed and when the update is by-passed. Also shown are the
number of CPU cycles for which global interrupts are masked when the update takes
22
Using the Digital Control Library
place. Note that the assembly functions do not perform any error checking prior to the
update.
DCL_fupdatePID 77 37 37
DCL_fupdatePI 64 37 24
DCL_fupdatePI2 57 37 17
DCL_fupdateDF11 58 37 31
DCL_fupdateDF13 78 37 38
DCL_fupdateDF22 66 7 26
DCL_fupdateDF23 74 37 34
DCL_fupdateGSM 114 37 74
DCL_fupdatePID32 73 37 33
DCL_fupdatePI32 57 37 17
Users should inspect the source code for the relevant functions to determine which
checks are performed.
If an error is detected, the code will set the “err” field of the CSS sub-structure of the
controller with an error code. An enumerated list of error codes can be found in DCL.h.
Name Description
23
Using the Digital Control Library
After each test sequence, if the err field is non-zero, the code will load the source line
number of the error and call an error handler function using the following C macros.
if (p->css->err)
{
DCL_GET_ERROR_LOC(p->css);
DCL_RUN_ERROR_HANDLER(p->css);
}
The default error handler function is located in the source file DCL_error.c. The DCL
does not perform sophisticated error handling, however the user is free to add their own
code to this file, or to re-direct the error handler to their own custom error function if
desired. Note that the enumerated error list is likely to be appended in future versions of
the library.
Among those errors in the standard enumerated list is ERR_CONTROLLER. This error is
used to detect over-run conditions, where a non-atomic controller function fails to
complete before being called again. This is potentially dangerous since the second call
will run with a partially updated data set. To detect this condition, the file DCL.h defines
the macros DCL_CONTROLLER_BEGIN and DCL_CONTROLLER_END which the user
may place at the start and end of a controller function to set and clear respectively the
STS_CONTROLLER_RUNNING bit in the STS field of the CSS sub-structure. This can
be examined inside the function to detect a partially complete control operation as follows.
24
Using the Digital Control Library
In the above code, p represents a pointer to the controller structure. Refer to the
controller code in DCL_NLPID.h for examples of the above method.
Do not modify the DCL functions directly. To modify library code, first copy the
code into a new function with a different name, then modify the new function.
This will ensure that user code remains compatible with future library releases.
Select a name which will not conflict with future library versions. See section
1.3.3 for a description of function naming. Controller numbers of 20 and above
are reserved for customer use. For example, the TI library will never contain a
function DCL_runPI_C20, so users are free to use that function name for their
own code.
Users are not obliged use the DCL controller structures, however they are free to
do so. It is suggested that any new custom structures use a name which is pre-
fixed differently from the library, for example, by replacing DCL_ with DCLU_.
Users need not apply the parameter update or error checking methods described
in sections 2.4 and 2.5, however they are free to do so. It is intended that future
library versions will be compatible with v3.4 in this respect.
25
Controllers
Chapter 3
Controllers
This chapter provides detailed information on the controller functions in the Digital Control
Library.
Section
3.1 Linear PID Controllers
Linear PID
Linear PI
Non-linear PID
Non-linear PI
Double Integrator
26
Controllers
Gain scheduler
In this guide, the four direct form types are referred to as ‘compensators’. This reflects a
situation common in power supply design, in which the design objective is to compensate
some feature of the open loop frequency response, such as phase shift. The
compensator is usually specified using a set of pole & zero frequencies, which leads
naturally to a transfer function description. The term ‘Direct Form” comes from transfer
function descriptions of digital filters which have a similar structure.
Controllers are either coded in C, or in assembly using three different instruction sets
(C28x, FPU32, and CLA). Additionally, most of the Direct Form compensators are
implemented in both full and pre-computed forms. There may therefore be several
different functions for each controller to allow the user to balance execution time with
ease-of-tuning. Different implementations of the same controller are identified using a two
character suffix to the ‘run’ function name (refer to section 1.3.2 for information on function
naming).
The description of each controller in this chapter is broken down into three sub-sections:
A description of functions
The ‘implementation’ sub-section always includes a block diagram showing the internal
structure and the variables used in the code. Local variables, which do not need to be
preserved between functions, are pre-fixed with the letter “v”. Variables which are part of
the controller structure and are therefore preserved between function calls are pre-fixed
with some other letter according to their purpose: for example, “i10” refers to a variable
used in the PID integrator. The prefix letter “l” is reserved for logical signals. The same
variable names are used in the library source code, making it straightforward to compare
the controller diagrams with the source code.
It is sometimes useful to monitor internal controller variables (i.e. which are not elements
in the controller structure) for debugging purposes. The CSS sub-structure contains a
test-point element named “tpt” which is intended to be used for this purpose. Controller
test-points are globally enabled using the following definition in DCL.h. Note that by
default, this definition is commented out to reduce execution cycles.
#define DCL_TESTPOINTS_ENABLED
Users may un-comment the above line, and then assign any internal variable to the tpt
element for monitoring, perhaps in the CCS “Expressions” window or using a data logger.
3.1.1 Description
The basic controller type described here is a linear PID. The PID implementations in the
DCL include several features not commonly found in basic PID designs, and this
complexity is reflected the benchmark figures. Applications which do not require
27
Controllers
derivative action, or are more sensitive to cycle efficiency, may be better served by the
simpler PI controller structure described in the next section.
PID control is widely used in systems which employ output feedback control. In such
systems, the controlled output is measured and fed back to a summing point where it is
subtracted from the reference input. The difference between the reference and feedback
corresponds to the control loop error and forms the input to the PID controller.
Conceptually, the PID controller output is the parallel sum of three paths which act
respectively on the error, error integral, and error derivative. The relative weight of each
path may be adjusted by the user to optimize transient response, or to emulate the
behavior of a specified transfer function expressed in terms of its’ poles and zeros.
t
de (t )
Equation 2. u (t ) K p e(t ) K i e( ) d K d
dt
Conceptually, the controller comprises three separate paths connected in parallel. The
upper path contains an adjustable gain term (Kp). Its effect is to fix the open loop gain of
the control system. Since loop gain is proportional to this term, Kp is known as
proportional gain.
A second path contains an integrator which accumulates error history. A separate gain
term acts on this path. The output of the integral path changes continuously as long as a
non-zero error (e) is present at the controller input. A small but persistent servo error has
the effect of driving the output of the integrator such that the loop error will eventually
disappear. The principal effect of the integral path is therefore to eliminate steady state
error. The effect of the integral gain term is to change the rate at which this happens.
Integral action is especially important in applications such as electronic power supplies,
which must maintain accurate regulation over long periods of time.
The third path contains a differentiator. The output of this path is large whenever the rate
of change of the error is large. The principal effects of the derivative action are to damp
oscillation and reduce transients.
The operation of the PID controller can be visualized in terms of the transient error
following a step change of set-point.
28
Controllers
Tuning the PID controller is a matter of finding the optimum combination of these three
effects. This in turn means finding the best balance of the three gain terms. For more
information on PID control & tuning, see the references in section 6.1.
The PID shown above is known as the “parallel” form because the three controller gains
appear in separate parallel paths. A slightly different PID architecture in which the
proportional gain is moved into the output path (i.e. after the summing point), so that the
proportional path becomes a direct connection between the controller input and the
summing point, is known as the “series” or “ideal” form. In the ideal form, the open loop
gain is directly influenced by the proportional controller gain, and there is less interaction
between the controller gains. However the proportional gain cannot be zero (since the
loop would be opened), and to maintain good control cannot be small. The parallel form
allows the proportional gain to be small, however there is slightly more interaction
between the controller gains, complicating the tuning process. The DCL contains both
ideal and parallel PID functions.
3.1.2 Implementation
The linear PID controllers in the DCL include the following features:
29
Controllers
It is important to note that the controller sample period is not accounted for in the selection
of integral gain (Ki). This is relevant when computing the integral gain as opposed to
manual tuning against a transient response, for example. In such situations, users must
multiply the computed integral gain by the sample period before loading Ki (either directly
or through the SPS). The element T in the CSS sub-structure can be used to store the
sample period for this purpose.
All PID type controllers in the library implement integrator anti-windup reset in a similar
way. A clamp is present at the controller output which allows the user to set upper and
lower limits on the control effort. If either limit is exceeded, an internal floating-point
controller variable changes from 1.0 to 0.0. This variable is multiplied by the integrator
input, such that the integrator accumulates zero data only when the output is saturated,
thus preventing the well-known “wind-up” phenomenon.
The PID controllers in the library make provision for anti-windup reset to be triggered from
an external part of the loop. This is useful in situations where a component outside the
controller may be saturated. The floating-point variable lk is expected to be either 1.0 or
0.0 in the normal and saturated conditions respectively. If this feature is not required, the
functions should be called with the lk argument set to 1.0. Note that all the controllers
here require non-zero proportional gain to recover from loop saturation.
The derivative PID path includes a digital low-pass filter to avoid amplification of un-
wanted high frequency noise. The filter implemented here is a simple first order lag filter
(with differentiator), converted into discrete form using the Tustin transform. Referring to
Figure 6, the difference equation of the filtered differentiator is
Equation 3. v4 (k ) v1 (k ) d 2 (k ) d 3 (k )
The temporary storage elements d2 & d3 must be preserved from the (k - 1)th interval, so
the following must be computed after the differentiator update.
Equation 4. d 2 (k ) v1 (k 1)
Equation 5. d 3 ( k ) c2 v4 ( k 1)
2
Equation 6. c1
T 2
T 2
Equation 7. c2
T 2
30
Controllers
Both the sample period (T) and filter time constant () must be determined by the user.
The time constant is the reciprocal of the desired filter bandwidth in radians per second.
All linear PID controller functions use a common C structure to hold coefficients and data.
Refer to the header file DCLF32.h for details of the DCL_PID controller structure.
31
Controllers
3.1.3 Functions
Declaration: float32_t DCL_runPID_C1(DCL_PID *p, float32_t rk, float32_t yk, float32_t lk)
Description: This function executes an ideal form PID controller on the FPU32. The function is
coded in assembly.
32
Controllers
Declaration: float32_t DCL_runPID_C2(DCL_PID *p, float32_t rk, float32_t yk, float32_t lk)
Description: This function executes an ideal form PID controller on the FPU32, and is identical
in structure and operation to the C1 form. The function is coded in inline C.
Declaration: float32_t DCL_runPID_C3(DCL_PID *p, float32_t rk, float32_t yk, float32_t lk)
Description: This function executes a parallel form PID controller on the FPU32. The function
is coded in inline C.
Declaration: float32_t DCL_runPID_C4(DCL_PID *p, float32_t rk, float32_t yk, float32_t lk)
Description: This function executes a parallel form PID controller on the FPU32, and is
identical in structure and operation to the C3 form. The function is coded in inline
C.
33
Controllers
Description: This function executes an ideal form PID controller on the CLA. The function is
coded in CLA assembly.
Description: This function executes a parallel form PID controller on the CLA. The function is
coded in CLA assembly.
34
Controllers
Description: This function resets the internal variables in the DCL_PID structure to default
values. The integrator accumulator and store derivative path values are set to 0.0,
and the integrator clamp variable set to 1.0. The function also sets the err field
in the CSS sub-structure to NONE. Note that the function is atomic.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the PID structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the PID structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters. The function is implemented as an assembly module.
Return: Void
35
Controllers
Description: Loads the derivative filter coefficients c1 & c2 in the SPS based on the desired
filter bandwidth specified in Hz. Coefficients in the active parameter set are
unaffected until the controller is updated using DCL_updatePID().
Return: Void
Description: Loads the derivative filter coefficients c1 & c2 in the active PID structure based
on the desired filter bandwidth specified in Hz and the controller update date in
seconds. This function does not use or modify the SPS.
Return: Void
Description: Finds the bandwidth of the current derivative filter in Hz by examining the
coefficients in the active parameter set (i.e. not the SPS).
36
Controllers
Description: Loads the SPS coefficients to implement a series form PID controller (e.g. C1, C2
or L1) based on a ZPK3 definition. The ZPK3 is expected to be in the form of a
complex zero pair, plus one real pole, plus an integrator. The real pole
corresponds to the pole in the derivative path filter. Note that the active
coefficients are not affected until the controller is updates using
DCL_updatePID(). Refer to section 1.3.8 for more information on the ZPK3
structure.
Return: Void
Description: Loads the SPS coefficients to implement a parallel form PID controller (e.g. C3,
C4 or L2) based on a ZPK3 definition. The ZPK3 is expected to be in the form of
a complex zero pair, plus one real pole, plus an integrator. The real pole
corresponds to the pole in the derivative path filter. Note that the active
coefficients are not affected until the controller is updated using
DCL_updatePID(). Refer to section 1.3.8 for more information on the ZPK3
structure.
Return: Void
3.2.1 Description
The continuous time parallel PI control equation is
t
Equation 8. u (t ) K p e(t ) K i e( ) d
The linear PI controllers in the DCL differ from the PID in the following respects.
37
Controllers
In all other respects, the PI controllers are similar to the PID controllers described in
section 3.1.
3.2.2 Implementation
All linear PI controller functions use a common C structure to hold coefficients and data,
defined in the header files DCLF32.h and DCLCLA.h.
38
Controllers
39
Controllers
The C6, C7, & L5 controllers combine a series form PI with a Tustin integrator. This configuration
is best suited to applications in which the controller gains are selected on the basis of high
frequency loop gain and zero frequency, because Kp and Ki are effectively un-coupled in the
series form controller. Furthermore the Tustin integrator has fixed 90 degree phase lag at all
frequencies below the Nyquist limit, simplifying design of the compensator.
3.2.3 Functions
Description: This function executes an ideal form PI controller on the FPU32. The function is
coded in assembly.
Description: This function executes an ideal form PI controller on the FPU32, and is identical in
structure and operation to the C1 form. The function is coded in inline C.
40
Controllers
Description: This function executes a parallel form PI controller on the FPU32. The function is
coded in inline C.
Description: This function executes a parallel form PI controller on the FPU32, and is identical
in structure and operation to the C3 form. The function is coded in inline C.
Description: This function executes a parallel form PI controller on the FPU32. The
configuration includes enhanced anti-windup reset logic which produces faster
recovery from integral path saturation. Note that this controller cycle count is a
little higher than C4. The function is coded in inline C.
41
Controllers
Description: This function executes a series form PI controller with Tustin integrator on the
FPU32. The function is coded in inline C.
Description: This function executes a series form PI controller with Tustin integrator on the
FPU32. The function is implemented in an external assembly module.
Description: This function executes an ideal form PI controller on the CLA. The function is
coded in CLA assembly.
42
Controllers
Description: This function executes a parallel form PI controller on the CLA. The function is
coded in CLA assembly.
Description: This function executes an ideal form PI controller on the CLA. The function is
coded in C.
Description: This function executes a parallel form PI controller on the CLA. The function is
coded in C.
43
Controllers
Description: This function executes a series form PI controller with Tustin integrator on the
CLA. The function is coded in inline C.
Description: This function resets the internal variables in the DCL_PI structure to default
values. The integrator accumulator is set to zero, and the err field in the CSS
sub-structure is set NONE. Note that the function is atomic.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the PI structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters.
44
Controllers
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the PI structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters. The function is implemented as an assembly module.
Return: Void
Description: Loads the SPS coefficients to implement a series form PI controller (e.g. C1, C2
or L1) based on a ZPK3 definition (one real zero plus integrator). Note that the
active coefficients are not affected until the controller is updates using
DCL_updatePI(). Refer to section 1.3.8 for more information on the ZPK3
structure.
Return: Void
Description: Loads the SPS coefficients to implement a parallel form PI controller (e.g. C3, C4,
C5, or L2) based on a ZPK3 definition (one real zero plus integrator). Note that
45
Controllers
the active coefficients are not affected until the controller is updates using
DCL_updatePI(). Refer to section 1.3.8 for more information on the ZPK3
structure.
Return: Void
3.3.1 Description
The DCL includes two implementations of a non-linear PID controller, denoted NLPID.
The controllers are broadly similar to the ideal PID_C1 controller, except that there is no
set-point weighting and in one case the derivative path sees the servo error instead of the
feedback. A non-linear gain block appears in series with each of the three paths.
To improve computational efficiency, the non-linear law is separated into two parts: one
part which is common to all paths, and a second part which contains terms specific to
each path. The non-linear part of the high-level controller structure is shown below:
46
Controllers
Equation 9. y x sign x
47
Controllers
The following plot shows the x-y relationship for values of α between 0.2 and 2. Notice
that the curves intersect at x = 0, and x = ±1.
The plots below show the gain vs. control loop error curves for different values of α.
Notice particularly the singularity at x = 0 when α < 1.
48
Controllers
x sign x : x
Equation 10. y
x 1 : x
When the magnitude of servo error falls below δ the linear gain is applied, otherwise the
gain is determined by the non-linear law. For computational efficiency, we pre-compute
the gain in the linear region (γ) as follows.
Equation 11. 1
A typical plot of the linearized control law is shown below. Observe that when x = δ the
linear and non-linear curves intersect, so the controller makes a smooth transition
between the linear and non-linear regions as the servo error passes through x = ±δ.
49
Controllers
The NLPID controller has been seen to provide significantly improved control in many
cases, however it must be remembered that increased gain, even if only applied to part of
the control range, can lead to significantly increased output from the controller. In most
cases, this ‘control effort’ is limited by practical factors such as actuator saturation, PWM
modulation range, and so on. The corollary is that not every application benefits equally
from the use of non-linear control and some may see no benefit at all. In cases where
satisfactory performance cannot be achieved through the use of linear PID control, the
user is advised to start with all α = 1, and experiment by introducing non-linear terms
gradually while monitoring both control performance and the magnitude of the control
effort. In general, P and I paths benefit from increased gain at high servo error (α > 1),
while the D path benefits from reduced gain at high servo error (α < 1), but this is not
universally true. Further information on tuning the nonlinear PID controller can be found
in the Nonlinear PID Controller Tuning Guide in the \docs directory of the DCL.
Further information on this control law can be found in: “From PID to Active Disturbance
Rejection Control”, Jingqing Han, IEEE TRANSACTIONS ON INDUSTRIAL
ELECTRONICS, VOL. 56, NO. 3, MARCH 2009
3.3.2 Implementation
The NLPID controller uses a C structure to hold coefficients and data, defined in the
header file DCL_NLPID.h. Note that the NLPID functions make use of the pow()
function in the standard C library. For this reason the header file math.h must be
included, which is not supported by the CLA compiler. To allow different DCL functions to
be run on both the CPU and CLA in the same program, the NLPID functions are located in
a separate header file. Refer to the file DCL_NLPID.h for details of the NLPID controller
structure.
As with all DCL controllers, it is the responsibility of the user to initialize the DCL_NLPID
structure before use. A set of default values is defined in the library header file and can
50
Controllers
3.3.3 Functions
float32_t lk)
Description: This function executes a parallel form non-linear PID controller on the FPU32.
The function is coded in inline C.
float32_t lk)
Description: This function executes a series form non-linear PID controller on the FPU32. This
controller is broadly similar to C1 except that the derivative path feedback comes
from the loop output rather than the error. The function is coded in inline C.
51
Controllers
float32_t lk)
Description: This function executes a series form non-linear PID controller on the FPU32. This
controller is similar to C2 except that it is coded in assembly for the TMU type 1.
If executed on a device without TMU type 1, the function will return the input
reference, rk.
Description: This function computes the three gain limits for the non-linear PID controller and
loads them directly into the active NLPID structure. The function is coded in C.
Return: Void
Description: This function computes the three gain limits for the non-linear PID controller and
loads them into the SPS sub-structure. Parameters in the active structure are
updated on the next call to DCL_updateNLPID(). The function is coded in C.
52
Controllers
Return: Void
Description: This function resets the internal variables in the DCL_NLPID structure to default
values. The integrator accumulator and store derivative path values are set to 0.0,
and the integrator clamp variable set to 1.0. The function also sets the err field
in the CSS sub-structure to NONE. Note that the function is atomic.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the PID structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters.
Return: Void
Description: Loads the active derivative filter coefficients c1 & c2 in the NLPID structure based
on the desired filter bandwidth specified in Hz and controller update rate in
seconds. Coefficients in the SPS and CSS are unaffected.
53
Controllers
Return: Void
Description: Loads the derivative filter coefficients c1 & c2 in the SPS based on the desired
filter bandwidth specified in Hz. Coefficients in the active parameter set are
unaffected until the controller is updated using DCL_updateNLPID().
Return: Void
Description: Finds the bandwidth of the current derivative filter in Hz by examining the
coefficients in the active parameter set (i.e. not the SPS).
Description: Finds the steady state gain in the linearized region for the specified alpha & delta
choice.
54
Controllers
Description: Finds the semi-width of the linearized region from the specified alpha and gamma
choice.
3.4.1 Description
The DCL contains one non-linear PI controller, similar in form to DCL_PI_C1. Refer to
section 3.3.1 for information on the non-linear control law.
3.4.2 Implementation
The NLPI controller is similar to a linear series form implementation, but with non-linear
law blocks in the P and I paths. The controller uses a common C structure to hold
coefficients and data, defined in the header files DCL_NLPID.h and DCL.h. The
NLPI_C1 controller architecture is shown below.
55
Controllers
3.4.3 Functions
Description: This function executes an ideal form PI controller on the FPU32. The function is
coded in inline C.
Description: This function resets the internal dynamic variables in the DCL_NLPI structure to
their default values. The integrator accumulator is set to zero, and the err field in
the CSS sub-structure is set NONE. Note that this function is atomic.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the control parameters stored in the SPS
sub-structure are copied into the DCL_NLPI structure and sts is cleared.
Dynamic variables are not affected. Note that this function is atomic. Refer to
section 2.4 for more information on updating controller parameters.
Return: Void
56
Controllers
3.5.1 Description
The DCL contains one implementation of a linear PI controller having two series
integrators. This type of controller is similar to the parallel PI controller described above
except that the anti-windup reset logic is more complicated.
In this controller, allowance has been made for the Kp element to be zero. This scenario
presents a problem if the controller enters saturation because without the proportional
path there is no way to recover. The PI2 resolves this by releasing the anti-windup lock
when the integrator input reverses sign. The logic has to be implemented twice, since
there are two cascaded integrators. Similar anti-windup reset logic is present in the
PI_C5 controller (see section 3.2 for more information).
3.5.2 Implementation
The double integrator PI2 controller uses a C structure to hold coefficients and data,
defined in the header file DCLF32.h.
3.5.3 Functions
57
Controllers
Description: This function executes an ideal form PI2 controller on the FPU32. The function is
coded in C.
Description: This function resets the internal variables in the DCL_PI2 structure to default
values. Both integrator accumulators are set to zero, and the err field in the CSS
sub-structure is set NONE. Note that the function is atomic.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the PI2 structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters.
Return: Void
58
Controllers
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the PI2 structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters. The function is implemented as an assembly module.
Return: Void
3.6.1 Description
The DCL includes one first order compensator in Direct Form 1. The DF11 compensator
implements a first order, or “simple lag”, type frequency response. The general form of
discrete time first order transfer function is
b0 b1 z 1
Equation 12. F ( z )
1 a1 z 1
Denominator coefficients must be normalized accordingly. The corresponding difference
equation is
59
Controllers
3.6.2 Implementation
All DF11 functions use a common C structure to hold coefficients and data, defined in the
header files DCLF32.h and DCLCLA.h.
It is the responsibility of the user to initialize coefficients and data prior to use. A set of
default values is defined in the library header file and can be used with the variable
declaration. An example of an initialized DCL_DF11 structure declaration on FPU32 is
shown below:
DCL_DF11 myCtrl = DF11_DEFAULTS;
3.6.3 Functions
Description: This function computes a first order control law using the Direct Form 1 structure.
The function is coded in FPU32 assembly.
Description: This function computes a first order control law using the Direct Form 1 structure.
The function is coded in C.
60
Controllers
Description: This function computes a first order control law using the Direct Form 1 structure.
The function is coded in CLA assembly.
Description: This function resets the internal variables in the DCL_DF11 structure to default
values. The forward and return path coefficients are configured to implement a
unity gain response, and the err field in the CSS sub-structure is set NONE.
Note that the function is atomic.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the DF11 structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters.
Return: Void
61
Controllers
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the DF11 structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters. The function is implemented as an assembly module.
Return: Void
Description: This function determines whether the coefficient set in the SPS sub-structure
represent a stable compensator. If the pole magnitude is less than one, the
function returns ‘1’, indicating stability; otherwise the function returns ‘0’. Refer to
section 1.3.9 for more information on compensator stability tests.
Description: This function loads the DF11 compensator coefficients in the SPS sub-structure
from a 1-pole, 1-zero description held in a ZPK3 structure. Active coefficients are
unaffected until the DCL_updateDF11() function is called. Refer to section
1.3.8 for more information on the ZPK3 structure.
62
Controllers
Return: Void
Description: This function loads the DF11 compensator coefficients in the SPS sub-structure to
emulate a series form PI controller. Active coefficients are unaffected until the
DCL_updateDF11() function is called.
Return: Void
3.7.1 Description
The Direct Form 1 (DF1) structure is a common type of discrete time control structure
used to implement a control law or dynamical system model specified either as a pole-
zero set, or as a rational polynomial in z (i.e. a discrete time transfer function). The DCL
includes one third order DF1 compensator, denoted “DF13”.
In general, the Direct Form 1 structure is less numerically robust than the Direct Form 2
(see below), and for this reason users are encouraged to choose the latter type whenever
possible. However, the DCL_DF13 structure is very common in digital power supplies
and for that reason is included in the library. The same function supports a second order
control law after the superfluous coefficients (a3 & b3) have been set to zero.
b0 b1 z 1 b2 z 2 b3 z 3
Equation 14. F ( z )
1 a1 z 1 a2 z 2 a3 z 3
Notice that the coefficients have been adjusted to normalize the highest power of z in the
denominator. There is no notational standard for numbering of the controller coefficients;
the notation used here has the advantage that the coefficient suffixes are the same as the
delay line elements and this helps with clarity of the assembly code, however other
notations may be found in the literature. The corresponding difference equation is
63
Controllers
The DF13 controller uses two, three-element delay lines to store previous input and
output data required to compute u(k). A diagrammatic representation is shown below.
The DF13 control law can be re-structured to reduce control latency by pre-computing six
of the seven partial products which are already known in the previous sample interval.
The control law is then broken into two parts: the “immediate” part and the “partial” part.
The advantage of doing this is to reduce the “sample-to output” delay, or the time between
e(k) being sampled, and a corresponding u(k) becoming available. By partially pre-
computing the control law, the computation delay can be reduced to one multiplication
and one addition.
Next, the v(k) partial result is pre-computed for use in the (k+1)th interval.
64
Controllers
Figure 23. DCL_DF13 C2, C3, C5, C6, L2, & L3 architecture
The pre-computed structure allows the controller output (u(k)) to be used as soon as it is
computed. The remaining terms in the third order control law do not involve the newest
input e(k) and therefore do not affect u(k). These terms can be computed after u(k) has
been applied to the control loop and the input-output latency of the controller is therefore
reduced.
A further benefit of the pre-computed structure is that it allows the control effort to be
clamped after the immediate part. Computation of the pre-computed part can be made
dependent on the outcome of the clamp such that if u(k) matches or exceeds the clamp
limits there is no point in pre-computing the next partial control variable and the
computation can be avoided. The DCL includes three clamp functions intended for this
purpose (see chapter 6).
3.7.2 Implementation
All DF13 functions use a common C structure to hold coefficients and data, defined in the
header files DCL.h and DCLCLA.h.
The assignment of coefficients and data in the DCL_DF13 structure to those in the
diagram is shown below:
65
Controllers
…where ek and uk are the controller input and output respectively, and df13 is the
controller structure.
...where vk is an intermediate float variable. This arrangement allows the user to make
use of the output immediately by placing instructions between the two lines above to use
the newest value of uk.
For applications where it is necessary to restrict the output of the compensator, a clamp
function can be used as follows.
uk = DCL_runDF13_C2(&df13, ek, vk);
if (0U == s)
The clamp function limits the controller output to lie between “lowerLim” and “upperLim”
and sets the unsigned integer “s” to 1 is that range is exceeded. The pre-computed part
66
Controllers
of the controller will only be executed when the immediate result is in range. Refer to
section 4.1 for information on the clamp functions.
3.7.3 Functions
Description: This function computes a full third order control law using the Direct Form 1
structure. The function is coded in FPU32 assembly.
Description: This function computes the immediate part of the pre-computed DF13 controller.
The function is coded in FPU32 assembly.
Description: This function computes the partial result of the pre-computed DF13 controller.
The function is coded in FPU32 assembly.
67
Controllers
Description: This function computes a full third order control law using the Direct Form 1
structure, and is identical in structure and operation to the C1 form. The function
is coded in inline C.
Description: This function computes the immediate part of the pre-computed DF13 controller.
The function is identical in structure and operation to the C2 form. The function is
coded in inline C.
Description: This function computes the partial result of the pre-computed DF13 controller.
The function is identical in structure and operation to the C3 form. The function is
coded in inline C.
68
Controllers
Description: This function computes a full third order control law using the Direct Form 1
structure, and is identical in structure and operation to the C1 form. The function
is coded in CLA assembly language.
Description: This function computes the immediate part of the pre-computed DF13 controller.
The function is identical in structure and operation to the C2 form. The function is
coded in CLA assembly language.
69
Controllers
Description: This function computes the partial result of the pre-computed DF13 controller.
The function is identical in structure and operation to the C3 form. The function is
coded in CLA assembly language.
Description: This function computes a full third order control law using the Direct Form 1
structure, and is identical in structure and operation to the C4 form. The function
is coded in C.
Description: This function computes the immediate part of the pre-computed DF13 controller.
The function is identical in structure and operation to the C2 form. The function is
coded in C.
70
Controllers
Description: This function computes the partial result of the pre-computed DF13 controller.
The function is identical in structure and operation to the C3 form. The function is
coded in C.
Description: This function resets the internal variables in the DCL_DF13 structure to default
values. The forward and return path coefficients are configured to implement a
unity gain response, and the err field in the CSS sub-structure is set NONE.
Note that the function is atomic.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the DF13 structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters.
Return: Void
71
Controllers
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the DF13 structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters. The function is implemented as an assembly module.
Return: Void
Description: This function determines whether the coefficient set in the SPS sub-structure
represent a stable compensator. If the pole magnitude is less than one, the
function returns ‘1’, indicating stability; otherwise the function returns ‘0’. Refer to
section 1.3.9 for more information on compensator stability tests.
Description: This function loads the DF13 compensator coefficients in the SPS sub-structure
from a 3-pole, 3-zero description held in a ZPK3 structure. Active coefficients are
unaffected until the DCL_updateDF13() function is called. Refer to section
1.3.8 for more information on the ZPK3 structure.
Return: Void
72
Controllers
3.8.1 Description
The C2000 Digital Controller Library contains a second order implementation of the Direct
Form 2 controller structure, denoted “DCL_DF22”. This structure is sometimes referred to
as a “bi-quad” filter and is commonly used in a cascaded chain to build up digital filters of
high order.
b0 b1 z 1 b2 z 2
Equation 18. F ( z )
1 a1 z 1 a2 z 2
The corresponding difference equation is
73
Controllers
Next, the v(k) partial result is pre-computed for use in the (k+1)th interval.
3.8.2 Implementation
All DF22 functions use a common C structure to hold coefficients and data, defined in the
header file DCL.h and DCLCLA.h.
74
Controllers
It is the responsibility of the user to initialize both arrays prior to use. A set of default
values is defined in the library header file and can be used with the variable declaration.
An example of an initialized DCL_DF22 structure declaration is shown below:
DF22 myCtrl = DF22_DEFAULTS;
3.8.3 Functions
Description: This function computes a full second order control law using the Direct Form 2
structure. The function is coded in FPU32 assembly.
Description: This function computes the immediate part of the pre-computed DF22 controller.
The function is coded in FPU32 assembly.
Description: This function computes the partial result of the pre-computed DF22 controller.
The function is coded in FPU32 assembly.
75
Controllers
Description: This function computes a full second order control law using the Direct Form 2
structure, and is identical in structure and operation to the C1 form. The function
is coded in inline C.
Description: This function computes the immediate part of the pre-computed DF22 controller.
The function is identical in structure and operation to the C2 form. The function is
coded in inline C.
Description: This function computes the partial result of the pre-computed DF22 controller.
The function is identical in structure and operation to the C3 form. The function is
coded in inline C.
76
Controllers
Description: This function computes a full third order control law using the Direct Form 2
structure, and is identical in structure and operation to the C1 form. The function
is coded in CLA assembly language.
Description: This function computes the immediate part of the pre-computed DF22 controller.
The function is identical in structure and operation to the C2 form. The function is
coded in CLA assembly language.
Description: This function computes the partial result of the pre-computed DF22 controller.
The function is identical in structure and operation to the C3 form. The function is
coded in CLA assembly language.
77
Controllers
Description: This function computes a full third order control law using the Direct Form 2
structure, and is identical in structure and operation to the C1 form. The function
is coded in C.
Description: This function resets the internal variables in the DCL_DF22 structure to default
values. The forward and return path coefficients are configured to implement a
unity gain response, and the err field in the CSS sub-structure is set NONE.
Note that the function is atomic.
Return: Void
78
Controllers
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the DF22 structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the DF22 structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters. The function is implemented as an assembly module.
Return: Void
Description: This function determines whether the coefficient set in the SPS sub-structure
represent a stable compensator. If the pole magnitude is less than one, the
function returns ‘1’, indicating stability; otherwise the function returns ‘0’. Refer to
section 1.3.9 for more information on compensator stability tests.
79
Controllers
Description: This function loads the DF22 compensator coefficients in the SPS sub-structure
from a 2-pole, 2-zero description held in a ZPK3 structure. Active coefficients are
unaffected until the DCL_updateDF22() function is called. Refer to section
1.3.8 for more information on the ZPK3 structure.
Return: Void
Description: This function loads the DF22 compensator coefficients in the SPS sub-structure
from a classical second order transfer function expressed in terms of damping
ratio (ζ) and un-damped natural frequency (ωn). This function may be useful, for
example, when emulating a plant model for control loop testing. The prototype
transfer function is
Equation 22.
Return: Void
Description: This function loads the DF22 compensator coefficients in the SPS sub-structure to
emulate a parallel form PID controller. Active coefficients are unaffected until the
DCL_updateDF22() function is called.
80
Controllers
Return: Void
Declaration: void DCL_loadDF22asSeriesPID (DCL_22 *p, float32_t Kp, float32_t Ki, float32_t
Kd, float32_t fc )
Description: This function loads the DF22 compensator coefficients in the SPS sub-structure to
emulate a series form PID controller. Active coefficients are unaffected until the
DCL_updateDF22() function is called.
Return: Void
3.9.1 Description
The third order Direct Form 2 compensator (DF23) is similar in all respects to the DF22
compensator. Separate full and pre-computed forms are supplied in C and assembly for
computation on the FPU32, and in assembly for computation on the CLA.
A diagrammatic representation of the full third order Direct Form 2 compensator is shown
below:
81
Controllers
Next, the v(k) partial result is pre-computed for use in the (k+1)th interval.
82
Controllers
3.9.2 Implementation
All DF23 functions use a common C structure to hold coefficients and data, defined in the header
file DCL.h. and DCLCLA.h.
It is the responsibility of the user to initialize both arrays prior to use. A set of default values is
defined in the library header file and can be used with the variable declaration. An example of an
initialized DCL_DF23 structure declaration is shown below:
DCL_DF23 myCtrl = DF23_DEFAULTS;
3.9.3 Functions
Description: This function computes a full third order control law using the Direct Form 2
structure. The function is coded in FPU32 assembly.
83
Controllers
Description: This function computes the immediate part of the pre-computed DF23 controller.
The function is coded in FPU32 assembly.
Description: This function computes the partial result of the pre-computed DF23 controller.
The function is coded in FPU32 assembly.
Description: This function computes a full third order control law using the Direct Form 1
structure, and is identical in structure and operation to the C1 form. The function
is coded in inline C.
84
Controllers
Description: This function computes the immediate part of the pre-computed DF23 controller.
The function is identical in structure and operation to the C2 form. The function is
coded in inline C.
Description: This function computes the partial result of the pre-computed DF23 controller.
The function is identical in structure and operation to the C3 form. The function is
coded in inline C.
Description: This function computes a full third order control law using the Direct Form 2
structure, and is identical in structure and operation to the C1 form. The function
is coded in CLA assembly language.
85
Controllers
Description: This function computes the immediate part of the pre-computed DF23 controller.
The function is identical in structure and operation to the C2 form. The function is
coded in CLA assembly language.
Description: This function computes the partial result of the pre-computed DF23 controller.
The function is identical in structure and operation to the C3 form. The function is
coded in CLA assembly language.
Description: This function resets the internal variables in the DCL_DF23 structure to default
values. The forward and return path coefficients are configured to implement a
unity gain response, and the err field in the CSS sub-structure is set NONE.
Note that the function is atomic.
86
Controllers
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the DF23 structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the DF23 structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters. The function is implemented as an assembly module.
Return: Void
Description: This function determines whether the coefficient set in the SPS sub-structure
represent a stable compensator. If the pole magnitude is less than one, the
function returns ‘1’, indicating stability; otherwise the function returns ‘0’. Refer to
section 1.3.9 for more information on compensator stability tests.
87
Controllers
Description: This function loads the DF23 compensator coefficients in the SPS sub-structure
from a 3-pole, 3-zero description held in a ZPK3 structure. Active coefficients are
unaffected until the DCL_updateDF23() function is called. Refer to section
1.3.8 for more information on the ZPK3 structure.
Return: Void
3.10.1 Description
The DCL contains one implementation of a parallel form fixed-point PID controller. The
structure is similar to the floating-point C1 controller. Refer to section 3.1 for more
information.
3.10.2 Implementation
The linear PID controller in the DCL32 includes the following features.
Parallel form
Both PID and PI type controllers in the DCl32 library implement integrator anti-windup
reset in a similar way. A clamp is present at the controller output which allows the user to
set upper and lower limits on the control effort. If either limit is exceeded, an internal
floating-point controller variable changes from logical 1 to logical 0. This variable is
converted into Q24 format and multiplied by the integrator input, such that the integrator
accumulates successive zero data when the output is saturated, avoiding the “wind-up”
phenomenon.
The following equations describe the implementation of the PID32 controller. Note that
the storage of static variables {i14 i10 d2 d3} is not shown.
88
Controllers
Equation 26. v5 ( k ) r ( k ) y ( k )
Equation 27. v6 ( k ) K p v5 ( k )
Equation 28. v7 ( k ) K i v5 ( k )
Equation 31. v1 (k ) K d v5 (k )
Equation 33. v4 ( k ) v2 ( k ) v2 ( k 1) v3 ( k 1)
Note that the derivative coefficient c1 must be divided by two on initialization. This
element is typically much larger than c2 so we enter half its value in the code and multiply
twice. This allows greater numerical range for a given Q-format.
Equation 35. v9 (k ) v6 ( k ) v8 ( k ) v4 (k )
v9 ( k ) :u min v9 ( k ) u max
Equation 36. u ( k ) u max : v9 ( k ) u max
u min : v9 ( k ) u min
1 : v11 (k ) 0
Equation 38. v12 (k )
0 : v11 (k ) 0
89
Controllers
3.10.3 Functions
Description: This function executes a parallel form PID controller on the C28x. The function is
coded in C28x assembly. All input and output variables are in Q24 format.
90
Controllers
Description: This function resets the internal variables in the DCL_PID32 structure to default
values. The integrator accumulator and store derivative path values are set to
zero, and the integrator clamp variable set to one. The function also sets the err
field in the CSS sub-structure is set NONE. Note that the function is atomic.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the PID structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the PID32 structure and sts is cleared. This function is
implemented as an assembly module and does not perform any error checking.
Note that the function is atomic. Refer to section 2.4 for more information on
updating controller parameters.
Return: Void
91
Controllers
3.11.1 Description
The DCL contains one implementation of a fixed-point series form PI controller. The PI is
similar in operation to the PID controller, with the removal of the derivative path. Refer to
section 3.2 for more information.
3.11.2 Implementation
The following equations describe the implementation of the PI32 controller.
Equation 40. v1 (k ) r (k ) y (k )
Equation 41. v2 ( k ) K p v5 ( k )
Equation 42. v3 ( k ) K i v2 ( k )
Equation 44. v4 (k ) v8 (k ) v4 (k 1)
Equation 45. v5 ( k ) v2 ( k ) v4 ( k )
v5 ( k ) :u min v5 ( k ) u max
Equation 46. u ( k ) u max : v5 ( k ) u max
u min : v5 ( k ) u min
Equation 47. v7 (k ) u (k ) v5 (k )
1 : v7 (k ) 0
Equation 48. v9 ( k )
0 : v7 ( k ) 0
92
Controllers
3.11.3 Functions
Description: This function executes an ideal form PI32 controller on the C28x. The function is
coded in C28x assembly. All input and output variables are in Q24 format.
Description: This function resets the internal variables in the DCL_PI32 structure to default
values. The integrator accumulator and store derivative path values are set to
93
Controllers
zero, and the integrator clamp variable set to one. The function also sets the err
field in the CSS sub-structure is set NONE. Note that the function is atomic.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the PID structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the PI32 structure and sts is cleared. This function is
implemented as an assembly module and does not perform any error checking.
Note that the function is atomic. Refer to section 2.4 for more information on
updating controller parameters.
Return: Void
3.12.1 Description
The DCL contains an implementation of a basic Gain Scheduler Module (GSM) which
runs on the FPU32. The GSM works by dividing the positive normalized input range, from
94
Controllers
0 to +1, into eight equal sectors, each of which is associated with a separate gain. The
negative input range, from 0 to -1, has the same gains but with a sign change.
As the input sweeps through the full range from -1 to +1, the output changes in a way
determined by the entries in two look-up tables loaded by the user. One table fixes the
gain in each sector, while the other fixes the offsets at the sector boundaries. In this way,
the user may realize a piecewise continuous non-linear input-output function without
introducing step discontinuities into the control.
3.12.2 Implementation
The sector gain look-up table consists of eight entries covering the normalized positive
input range. The sector offset table consists of nine entries, with the first entry set to zero,
and the final entry defining the output when the input is equal to 1. Figure 33 shows the
sector numbering used in the GSM for a typical target curve. Sectors, gains, and offsets
are denoted S, m, and c respectively. Note the symmetry for positive and negative inputs,
and the clamp characteristic on the upper right when the input magnitude exceeds 1.
The Matlab script file GSM_example.m can be found in the \models sub-directory and
demonstrates how the gain and offset tables are initialized. Note that due to array
95
Controllers
indexing differences between Matlab and C, sector initialization is slightly different to the
DCL code.
3.12.3 Functions
Description: This function runs the gain scheduler to determine an output from the gain and
offset arrays in the DCL_GSM structure. The function is coded in in-line C.
Description: This function resets the internal variables in the DCL_GSM structure to default
values. All gain segments are set to unity gain and the offset array configured to
generate a linear input/output relationship. The function also sets the err field in
the CSS sub-structure set NONE. Note that the function is atomic.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the active DCL_GSM structure and sts is cleared. Note
96
Controllers
that the function is atomic. Refer to section 2.4 for more information on updating
controller parameters.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the GSM structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters. The function is implemented as an assembly module.
Return: Void
Description: This function configures the offset array in the SPS sub-structure to produce a
piecewise continuous input-output curve from the gains. The active parameters
are not affected until the DCL_updateGSM() function is called.
Return: Void
Description: This function configures the gain array in the SPS sub-structure to produce a
piecewise continuous input-output curve from the offsets. The active parameters
are not affected until the DCL_updateGSM() function is called.
97
Controllers
Return: Void
3.13.1 Description
The DCL contains an implementation of the non-linear control law used in the NLPID &
NLPI controller described earlier in this section. The user could apply this function to
implement a gain scheduling type of control.
3.13.2 Implementation
Refer to section 3.3.1 for information on the non-linear law.
3.13.3 Functions
Description: This function executes a non-linear control law defined by the parameters in the
DCL_NLF structure. No error checks are performed on the parameters. The
function is coded in inline C.
3.14.1 Description
The DCL contains one implementation of a linear PID controller in double precision
floating point form. This controller may be used with the FPU32 CPU, however support
for the double precision data type currently relies on the run time support libraries which
are not cycle efficient. The structure of the controller is identical to the PID_C1 & PID_C2
controllers described earlier in this chapter. Support functions for PIDF64 do not currently
include the ability to load the controller from transfer function coefficient or ZPK3
descriptions.
98
Controllers
3.14.2 Implementation
The controller is supplied in inline C source. Refer to section 3.1.2 for further information.
3.14.3 Functions
Description: This function executes an ideal form PIDF64 controller on the FPU32, and is
identical in structure and operation to the C1 & C2 forms. The function is coded in
inline C.
Description: This function resets the internal variables in the DCL_PIDF64 structure to default
values. The integrator accumulator and store derivative path values are set to 0.0,
and the integrator clamp variable set to 1.0. The function also sets the err field
in the CSS sub-structure to NONE. Note that the function is atomic.
Return: Void
99
Controllers
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
structure are copied into the PIDF64 structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters.
Return: Void
Description: Loads the derivative filter coefficients c1 & c2 in the SPS based on the desired
filter bandwidth specified in Hz. Coefficients in the active parameter set are
unaffected until the controller is updated using DCL_updatePIDF64().
Return: Void
Description: Loads the derivative filter coefficients c1 & c2 in the active PIDF64 structure
based on the desired filter bandwidth specified in Hz and the controller update
date in seconds. This function does not use or modify the SPS.
Return: Void
100
Controllers
Description: Finds the bandwidth of the current derivative filter in Hz by examining the
coefficients in the active parameter set (i.e. not the SPS).
3.15.1 Description
From version 3.4, the DCL contains support for the DF22 compensator in double precision
floating point. The controller architecture is identical to that described in section 3.8 so
the details need not be repeated here. One full controller and a pair of functions to
support a pre-computed controller are implemented. There are also ‘reset’ and ‘update’
functions, and a double precision clamp function (see section 4.1). Other single precision
functions to support coefficient calculation are not implemented at this time.
3.15.2 Implementation
The controller is supplied in inline C source. Refer to section 3.1.2 for further information.
3.15.3 Functions
101
Controllers
Description: This function computes the immediate part of the pre-computed DF22 controller.
Description: This function computes the partial result of the pre-computed DF22F64 controller.
Description: This function resets the internal variables in the DCL_DF22F64 structure to
default values. Note that the function is atomic.
Return: Void
Description: This function tests the sts field in the CSS sub-structure to determine whether a
parameter update is required. If so, the parameters stored in the SPS sub-
102
Controllers
structure are copied into the DF22F64 structure and sts is cleared. Note that the
function is atomic. Refer to section 2.4 for more information on updating
controller parameters.
Return: Void
103
Utilities
Chapter 4
Utilities
This chapter describes the supporting functions included in the Digital Control Library.
Section
4.1 Control Clamps
The Digital Controller Library includes a small number of utilities intended to support use
of the library. These include:
Clamp functions for the CPU and CLA
Floating point data logging functions
A 4-channel floating point data logger
A Transient Capture Module
Functions for measurement of control performance
Fixed point data logging functions
A 4-channel fixed point data logger
A reference generator
The reference generator module is documented in a separate user’s guide which can
be found in the \docs sub-directory of the DCL installation path.
4.1.1 Description
The library contains three functions for clamping a control variable to specified upper and
lower limits. These would typically be used to impose a pre-defined bound the output of a
104
Utilities
The clamp functions bound the input data variable to pre-determined limits and return a
logical value 1 if either bound is matched or exceeded. If the input data lies definitely
within limits (i.e. neither bound is matched or exceeded) the functions return logical 0.
The return value can be used by PI & PID regulators to implement anti-windup reset, and
may be used to clamp the output of the pre-computed forms of all direct form
compensators. An example may be found in the DF22 example project supplied with the
library (see chapter 5).
A difference exists between the C28x clamp function and that of the CLA. On the CPU
the returned value is an unsigned integer of either 0 or 1, while the corresponding CLA
function returns a floating point value of 0.0f or 1.0f. This is because the handling of fixed-
point data on the CLA is less efficiently supported than on the main CPU.
4.1.2 Functions
Description: This function clamps a floating-point data value to defined limits and returns a
non-zero integer if either limit is matched or exceeded. The input data is modified
by the function. The function is coded in assembly.
Return: 0 if the data lies definitely within limits, 1 if the data matches or exceeds the limits.
105
Utilities
Description: This function clamps a floating-point data value to defined limits and returns a
non-zero integer if either limit is matched or exceeded. The input data is modified
by the function. The function is coded in inline C.
Return: 0 if the data lies definitely within the specified limits; 1 if the data matches or
exceeds the specified limits.
Description: This function clamps a floating-point data value to defined limits and returns a
non-zero floating-point result if either limit is matched or exceeded. The function
is coded in CLA assembly.
Return: 0.0f if the data lies definitely within the specified limits; 1.0f if the data matches or
exceeds the specified limits.
Description: This function clamps a double precision floating-point data value to defined limits
and returns a non-zero integer if either limit is matched or exceeded.
Return: 0 if the data lies definitely within the specified limits; 1 if the data matches or
exceeds the specified limits.
106
Utilities
4.2.1 Description
The Digital Control Library includes a general purpose floating-point data logger utility
which is useful when testing and debugging control applications. The intended use of the
data logger utility is to capture a stream of data values in a block of memory for
subsequent analysis. The data logger is supplied in the form of a C header file and one
assembly file, and it may be used on any C2000 device irrespective of whether the DCL is
used. The utility may not be used on the CLA.
The data logger operates with arrays of 32-bit floating-point data. The location, size, and
indexing of each array are defined by three pointers capturing the start address, end
address, and data index address. All three pointers are held in a common C structure
with the data type “FDLOG”, defined as follows:
Conceptually, the relationship between the array pointers and the elements of a data
array of length “N” is shown below:
107
Utilities
To use the data logger, you must include the header file DCL_fdlog.h in your project.
Typically, a user would create an instance of an FDLOG structure as follows:
FDLOG myBuf = FDLOG_DEFAULTS;
The log pointers can then be initialized in the user’s code such that they reference a
memory block in a specific address range. Thereafter, the code can clear or load the
buffer a specific data value, and then begin writing data into it using the
DCL_writeLog() function. The DF22 example project shows how this is done.
The DCL also contains two functions which perform fast read and write to a data log.
These are assembly coded functions in the source file DCL_frwlog.asm. The execution
cycles for these and the corresponding C coded DCL functions are shown below:
DCL_writeLog 48
DCL_readLog 39
DCL_fwriteLog 22
DCL_freadLog 22
4.2.2 Functions
Return: Void
Description: This function resets the data index pointer to start of the data log.
Return: Void
108
Utilities
Description: This function assigns the buffer pointers to a memory block or array and sets the
data index pointer to the first address.
Return: Void
Description: This function writes a data point into the buffer and advances the indexing pointer,
wrapping if necessary. The function returns the data value being over-written,
which allows simple implementation of a fixed-length delay line.
Description: This function fills the data log with a given data value and resets the data index
pointer to the start of the log.
109
Utilities
Return: Void
Description: This function clears the buffer contents by writing 0 to all elements and resets the
data index pointer to the start of the log.
Return: Void
Description: This function reads a data point from the buffer and then advanced the index
pointer, wrapping if necessary.
Description: This function copies the contents of one log into another and resets both buffer
index pointers. The function assumes both logs have the same length.
Return: Void
110
Utilities
Description: This function reads a data point from the log and then advances the indexing
pointer, wrapping if necessary. This function is coded in assembly.
Description: This function writes a data point into the buffer and advances the indexing pointer,
wrapping if necessary. Returns the over-written data value for delay line or FIFO
implementation. This function is coded in assembly.
4.3.1 Description
The Digital Control Library contains a 4 channel floating point data logger module denoted
“MLOG”. This module uses the data logger functions described above to capture up to
four channels of incoming data in separate buffers for later inspection. The MLOG
module is trigged by a sample at its first input exceeding either of a pair of user defined
thresholds, after which incoming samples are successively logged into each buffer until
they are full. A useful feature of the MLOG module is that the sampling rate can be
adjusted by the user to change the time scale of the capture frame.
Conceptually, the MLOG architecture consists of four floating point data capture frames,
each of which is a buffer defined by an FDLOG structure. The input to each buffer passes
through a sample scaler, which divides the sample rate by a user programmable integer.
Sampling is initiated when data at the first input exceeds a pre-defined upper or lower
limit, after which the four data samples are logged into the capture frames at the desired
rate until the buffers are full.
Note that the MLOG modules will be removed in version 4.0 of the DCL.
111
Utilities
MLOG_idle
MLOG_armed
MLOG_capture
MLOG_complete
The operating mode is stored in an element in the MLOG structure. All floating point
MLOG functions are coded in inline C functions in the header file MLOG.h. Note that the
DCL includes a separate fixed point 4-channel data logger which is described later in this
chapter.
4.3.2 Functions
Declaration: void DCL_initMLOG(MLOG *q, float32_t *addr, uint16_t size, float32_t tmax,
float32_t tmin, uint16_t div)
112
Utilities
Description: This function loads all buffer contents with zero, and resets all buffer data pointers
to their respective start addresses. The upper and lower trigger thresholds, and
sample time scale are loaded into the MLOG structure. On completion, the
MLOG module is in MLOG_idle mode. The MLOG module will be removed in
v4.0 of the library.
Return: Void
Description: This function loads all buffer contents with zero, and resets all buffer data pointers
to their respective start addresses. On completion, the MLOG module is in
MLOG_idle mode. The MLOG module will be removed in v4.0 of the library.
Return: Void
Description: This function changes the MLOG operating mode from MLOG_idle to
MLOG_armed. If the operating mode is not already MLOG_idle when the
function is called, it sets the mode to MLOG_idle. The MLOG module will be
removed in v4.0 of the library.
Return: Void
113
Utilities
Description: This function runs the MLOG module. If in the MLOG_armed mode, the MLOG
monitors its first input to determine whether either threshold has been exceeded.
If so, the module enter MLOG_capture mode and sample collection begins.
When the buffers are full, the operating mode is set to MLOG_complete. The
MLOG module will be removed in v4.0 of the library.
Return: Void
A feature of the TCM is that it captures a programmable length lead frame, allowing the
user to inspect conditions immediately prior to the trigger condition. This is accomplished
with three FDLOG structures which are elements in the TCM data structure, together with
the limit pair. Once initialized, the status of the TCM is captured in one of four
enumerated operating modes:
TCM_idle
TCM_armed
TCM_capture
TCM_complete
The current mode is available in the mode element in the TCM structure. To use the
TCM, the user must do the following:
114
Utilities
6. Monitor the mode element in the TCM structure to determine when the capture is
complete.
A code example illustrating the use of the TCM is supplied with the library and is
described in chapter 5.
In the following diagrams, lead, capture, and monitor frames are indexed using the
FDLOG structures x, y, & z respectively (note that these are not the names used in the
TCM structure). FDLOG pointers are color coded blue, green, and red, respectively. To
help visualize the sequence of events, the diagram shows in light gray the data which will
eventually be logged into the TCM, and in blue the current frame contents in each mode.
115
Utilities
Each data point is compared with the upper and lower trigger thresholds to determine
whether to initiate a capture sequence. As long as the incoming data remains within the
specified limits, the TCM remains in TCM_armed mode.
Lead Monitor
y(t)
Frame Frame
Capture Frame
umax
umin
y.fptr x.lptr
y.dptr
116
Utilities
117
Utilities
4.4.5 Functions
Declaration: void DCL_initTCM(TCM *q, float *addr, uint16_t size, uint16_t lead,
Description: This function resets the TCM module. All buffer contents are loaded with zero,
and the operating mode is set to “TCM_idle”.
118
Utilities
Return: Void
Description: This function resets the TCM. The contents of the capture frame are loaded with
zero. All data log pointers are re-initialized, and the operating mode is set to
TCM_idle.
Return: Void
Description: If the current TCM mode is TCM_idle, this function changes it to TCM_armed,
otherwise it is unchanged.
119
Utilities
4.5.1 Description
The Digital Control Library includes functions for the computation of control performance.
All functions are based on discrete integration over a fixed interval of a variable
representing servo error. The result is a non-negative scalar representing the quality of
control: the smaller the result, the better the control. The figure below shows conceptually
the transient servo error during a typical transient response.
The IES performance index is based on the square of the servo error. For an
interval of N samples, with loop reference r and feedback y, the IES index (PIES) is
computed as follows.
N
PIES r (k ) y(k )
2
Equation 49.
k 1
The IAE performance index is based on the absolute value of the servo error. For
an interval of N samples, with loop reference r and feedback y, the IAE index
(PIAE) is computed as follows.
N
Equation 50. PIAE r (k ) y(k )
k 1
The ITAE performance index is based on the time weighted absolute value of the
servo error. For an interval of N samples, with loop reference r and feedback y,
the ITAE index (PITAE) is computed as follows.
N
Equation 51. PITAE k r (k ) y(k )
k 1
120
Utilities
Each index is available in two forms: one coded in assembly, the other in inline C. The
computation time will depend on the length of the error log, but the assembly functions will
always be significantly faster.
The following table shows cycle count benchmarks for each function, for a buffer of N data
points. Cycle counts include function calling overhead from C.
Function Cycles
IES_C1 24 + 6N
IES_C2 73 + 30N
IAE_C1 24 + 6N
IAE_C2 72 + 24N
ITAE_C1 26 + 7N
ITAE_C2 77 + 31N
4.5.2 Functions
Description: This function computes an IES performance index using the servo error data in a
given memory block. The function is coded in assembly.
121
Utilities
Description: This function computes an IES performance index using the servo error data in a
given memory block. The function is coded in assembly.
Description: This function computes an ITAE performance index using the servo error data in a
given memory block. The function is coded in assembly.
122
Utilities
4.6.1 Description
The Digital Control Library contains support for fixed point data logging comprising a set
of data buffer functions and a 4 channel data logger module. Both are similar to their
floating point counterparts described earlier in this chapter. For this reason, neither will be
described in detail here. The reader is referred to sections 4.2 and 4.3 for details.
4.6.2 Functions
Return: Void
Description: This function resets the data index pointer to start of the data log.
Return: Void
123
Utilities
Description: This function assigns the buffer pointers to a memory block or array and sets the
data index pointer to the first address.
Return: Void
Description: This function writes a data point into the buffer and advances the indexing pointer,
wrapping if necessary. The function returns the data value being over-written,
which allows simple implementation of a fixed-length delay line.
Description: This function fills the data log with a given data value and resets the data index
pointer to the start of the log.
Return: Void
124
Utilities
Description: This function clears the buffer contents by writing 0 to all elements and resets the
data index pointer to the start of the log.
Return: Void
Description: This function reads a data point from the buffer and then advanced the index
pointer, wrapping if necessary.
Description: This function copies the contents of one log into another and resets both buffer
index pointers. The function assumes both logs have the same length.
Return: Void
125
Utilities
Declaration: void DCL_initMLOG32(MLOG32 *q, int32_t *addr, uint16_t size, int32_t tmax,
int32_t tmin, uint16_t div)
Description: This function loads all buffer contents with zero, and resets all buffer data pointers
to their respective start addresses. The upper and lower trigger thresholds, and
sample time scale are loaded into the MLOG32 structure. On completion, the
MLOG32 module is in MLOG32_idle mode. This function is similar to
DCL_initMLOG(). The MLOG32 module will be removed in DCL version 4.0.
Return: Void
Description: This function loads all buffer contents with zero, and resets all buffer data pointers
to their respective start addresses. On completion, the MLOG32 module is in
MLOG32_idle mode. This function is similar to DCL_resetMLOG(). The
MLOG32 module will be removed in DCL version 4.0.
Return: Void
Description: This function changes the MLOG32 operating mode from MLOG32_idle to
MLOG32_armed. If the operating mode is not already MLOG32_idle when the
function is called, it sets the mode to MLOG32_idle. This function is similar to
DCL_armMLOG(). The MLOG32 module will be removed in DCL version 4.0.
Return: Void
126
Utilities
Description: This function runs the MLOG32 module. If in the MLOG32_armed mode, the
MLOG32 monitors its first input to determine whether either threshold has been
exceeded. If so, the module enter MLOG32_capture mode and sample collection
begins. When the buffers are full, the operating mode is set to
MLOG32_complete. This function is similar to DCL_runMLOG(). The MLOG32
module will be removed in DCL version 4.0.
Return: Void
It is important to understand that the blocks capture the functional structure of the
controller and are intended to be used for the purposes of control loop simulation only.
None of the models have been configured for automated C code generation from Simulink
or Matlab. Should the user wish to do this, it is their responsibility to re-configure and
build the model accordingly. Code generation currently lies outside the scope of the DCL.
127
Utilities
The script will open a configuration script file PID_config.m, which contains the control
loop settings, including the PID controller gains. These will be manually adjusted by the
user each time the example is run. After the configuration is loaded into the Matlab
workspace, the script then loads the input stimulus from the file PID_inputs.m. The
user can select the type of stimulus by changing the input_config variable near the top
of the example script file.
The example opens the Simulink model PID_sim.slx. The example model consists of a
simple feedback control loop using a PID_C1 controller from the DCL block-set. The plant
is a third order transfer function with one LHP zero (see lines 22-30 in the configuration
script file).
The simulation uses configuration parameters and input data in the Matlab workspace,
and saves simulation data back to the workspace. The user may select which data to plot
by setting plot variables in lines 20-25 of the example script. Plotting is performed in the
script file PID_plots.m.
The example computes a performance index from the loop error and displays it in the
Matlab command window. This is helpful should the user with to experiment with different
controller parameters to improve performance.
Any data the user wishes to save is stored in data files in the \models sub-directory.
Each data file contains a TI header line which facilitates loading the data onto a C2000
target device.
4.8.1 Description
The Digital Control Library contains a double precision floating-point data logger. Apart
from data type, the data logger is similar to that described in section 4.2. The data logger
is supplied in the form of a C header file and may be used on any C2000 device
irrespective of whether the DCL is used. The data logger is not compatible with the CLA.
The data logger operates with arrays of 64-bit floating-point data. The location, size, and
indexing of each array are defined by three pointers capturing the start address, end
address, and data index address. All three pointers are held in a common C structure
with the data type “FDLOG64”, defined as follows:
Conceptually, the relationship between the array pointers and the elements of a data
array of length “N” is shown below:
128
Utilities
To use the data logger, you must include the header file DCL_fdlog64.h in your project.
Typically, a user would create an instance of an FDLOG64 structure as follows:
FDLOG64 myBuf = FDLOG64_DEFAULTS;
The log pointers can then be initialized in the user’s code such that they reference a
memory block in a specific address range. Thereafter, the code can clear or load the
buffer a specific data value, and then begin writing data into it using the
DCL_writeLog64() function.
The execution cycles for the read & write functions are shown below:
DCL_writeLog64 75
DCL_readLog64 58
4.8.2 Functions
129
Utilities
Return: Void
Description: This function resets the data index pointer to start of the data log.
Return: Void
Description: This function assigns the buffer pointers to a memory block or array and sets the
data index pointer to the first address.
Return: Void
130
Utilities
Description: This function writes a data point into the buffer and advances the indexing pointer,
wrapping if necessary. The function returns the data value being over-written,
which allows simple implementation of a fixed-length delay line.
Description: This function fills the data log with a given data value and resets the data index
pointer to the start of the log.
Return: Void
Description: This function clears the buffer contents by writing 0 to all elements, and resets the
data index pointer to the start of the log.
Return: Void
131
Utilities
Description: This function reads one data point from the buffer and then advances the index
pointer, wrapping to the first element if necessary.
Description: This function copies the contents of one log into another and resets both buffer
index pointers. The function assumes both logs have the same length.
Return: Void
132
Examples
Chapter 5
Examples
This chapter describes the example projects supplied with the Digital Control Library.
Section
5.1 Example 1: DF22 compensator running on FPU32
The Digital Control Library package includes a set of code examples intended to illustrate
the use of library functions in a typical software project. Examples are supplied as CCS
projects configured for use with a specified target. Code migration to a different C2000
device is straightforward and does not affect the DCL.
There are ten example projects, located in the C2000Ware installation directory, in the
sub-directory \libraries\control\DCL\c28\examples. Each example has a
“CCS” sub-directory containing a “.projectspec” file which should be imported as a project
into the users CCS workspace.
The following sections describe the example code and outline the steps to run them. The
examples were prepared using CCS version 8.3.0. It is assumed the reader is familiar
with CCS and how to build and run code. For further information on these topics, the
reader is referred to the C2000 training workshop (section 6.2).
133
Examples
The program contains one ISR which is triggered by a CPU timer at 1kHz. The ISR reads
a single input from a data buffer and runs both DF22 compensators. The compensator
outputs are compared, and then both outputs and their difference logged into three
separate data buffers. When the last point of the input buffer has been read and
processed, the ISR passes through the line containing a NOP instruction near the bottom
of the program. The user can place a break-point here to examine the results of the
compensator test.
The program makes use of four data buffers at the following addresses:
Each data buffer contains 1601 single precision floating-point data points.
Lines 17-34: create four data buffers and assign them to memory blocks defined in the
linker file F28069_DCL.cmd
Lines 71-77: initialize the data log structures and data buffers
Lines 94-95: set the clamp limits for the pre-computed compensator
Line 120: tests whether the last element in the input data buffer has been reached
134
Examples
Place a break-point at the line indicated in the control ISR and run the program. When
the program reaches the break-point, inspect the memory buffers by opening a CCS
graph window. The graph setup window below shows how to configure the graph to view
the pre-computed compensator output (u2k).
The plot of the u1k and u2k buffers should look like this.
135
Examples
Similar graphs can be opened for the other buffers by changing the start address. The
buffer at start address 0x12000 captures the difference in output between the full and pre-
computed compensators, and should contain data which is zero or very small.
The CLA task calls two different DF23 compensators and stores their results in two
variables (u1k and u2k) which are located in CLA-to-CPU message RAM. These results
are read by the CPU ISR which computes the difference between them. The ISR then
stores both results and their difference to three data buffers. When the final input value
has been processed in this way the ISR passes through a NOP instruction, allowing the
user to place a break-point and inspect the results.
Lines 19-36: create four buffers which will be used to hold control data
Lines 42-47: create variables which will pass control data between C28x and CLA
Lines 73-79: assign data logs to the buffers and initialize them
Line 146: reads the next data point from the input data file
Line 150: triggers the CLA task which will call the DF23 compensator
Line 154: computes the difference between the two compensator results
Lines 157-159: write the compensator results into the data buffers
136
Examples
Line 36: calls the full DF23 compensator and stores the result in u1k
Line 39: calls the immediate DF23 compensator and stores the result in u2k
Line 40: clamps the immediate result and sets the clamp flag vk
Lines 41-44: pre-compute the next partial DF23 result, providing the immediate part is in
range
Lines 100-101: initialize the clamp limits for the pre-computed DF23 compensator
After the break-point is reached, open a graph window to inspect the contents of the u1k
memory buffer at address 0xE000.
137
Examples
These results were produced by the full DF23 compensator. To view the pre-computed
compensator, change the “Start Address” field in Graph Properties to 0x10000. The
buffer at address 0x12000 contains the difference in compensator results, all of which
should be zero or very small.
The ADC is triggered by a PWM zero match event, and samples two channels. An ISR is
triggered by an ADC end-of-conversion event and reads the ADC results. Channel A0
represents the control loop feedback, and channel B0 represents an external saturation
input which is used for integrator anti-windup. The DCL_runClamp_C2 function is used
to convert the ADC result into an integer with the logical value 1 or 0.
The ISR calls the DCL_NLPID_C1 controller, and stores the control effort in the uk
variable. This is converted into an unsigned 16-bit integer and used to modulate the
PWM duty cycle. In this way, the program implements a non-linear closed loop controller
which regulates the floating-point reference, rk.
Lines 25-27: create an instance of the NLPID controller and its’ sub-structures
Lines 106-107: assign the substructure addresses to the active controller structure
Lines 128-120: copy the SPS parameters into the active controller structure
Line 165: reads the control feedback and converts to signed floating-point format
138
Examples
Lines 171 – 172: set the external clamp variable to 1.0f or 0.0f.
rk – input reference
yk – feedback
uk – controller output
The user can run repeatedly to the break-point, modifying controller parameters and
examining the change of controller variables. If any of the “alpha” or “delta” parameters
are changed, the variable calFlag should be set to 1 to enable the “gamma” gains to be
computed and updated in the background loop.
139
Examples
CLA task 3 calls the function DCL_runPI_L1() which computes the PI controller in an
assembly function. The result is stored in the variable uk, which is located in CLA-to-CPU
message RAM.
The PI controller result is read by the ISR, converted into a scaled un-signed 16-bit
integer, and written to the PWM duty cycle register.
Lines 24-29: create instances of the control variables and assign them to the appropriate
message RAM blocks
Lines 31-32: create an instance of the PI controller structure and place it in CPU-to-CLA
message RAM. This allows controller parameters to be modified from code running on
the C28x CPU.
Line 170: reads the feedback data from the ADC and converts it into floating-point format
Lines 180-181: convert the controller result to 16-bit unsigned integer and write it to the
PWM duty cycle register
Note that in this example, initialization of the PI controller is performed on the C28x CPU,
so there is no need to allocate a separate CLA task for that purpose.
140
Examples
At this point, controller gains can be manually changed and the code run repeatedly to
observe the effect on the control variables.
The ISR calls the DCL_PID_C4 parallel form PID controller to compute control effort held
in the “uk” variable. This is converted into an unsigned 16-bit integer and used to
modulate the PWM duty cycle. In this way, the program implements a simple closed loop
PWM controller which regulates the floating-point reference, “rk”.
Line 145: reads the feedback and converts to the range ±1.0f
Line 155: convert the controller output to unsigned integer in the range 0 to PRD
141
Examples
rk – input reference
yk – feedback
uk – controller output
The user can run repeatedly to the break-point modifying controller parameters and
examining the change of controller variables.
The code contains a single ISR triggered at 1kHz by a CPU timer. The ISR uses the fast
read function DCL_fread() to read values from two buffers representing servo reference
(rBuf), and feedback (yBuf), and then runs the TCM on the feedback sample to detect and
142
Examples
capture the transient response in a third buffer (dBuf). The code subtracts yk from rk to
find the instantaneous servo error, and logs the result into a fourth buffer (eBuf). When
the final point in the input data sequence has been read and acted upon, the dBuf buffer
should contain a portion of the feedback sequence around the transient edge, while the
eBuf buffer contains the servo error. The variables P1, P2, and P3 contain the ITAE, IAE,
and IES performance indices respectively. These are computed over the entire input
sequence.
Lines 20-37: create instances of four data buffers and assign them to specific regions
defined in the linker command file F28069_DCL.cmd.
Line 47: creates an instance of the TCM module and initializes it to default values
Lines 72-76: assign the data buffers to FDLOG structures and clear the servo error buffer
Lines 113-114: compute the servo error and log it to the eBuf data buffer
Line 117: detects if the final point in the input buffer has been processed
When the break-point is reached, open a graph window to view the contents of the 1601-
point yBuf memory at address 0xe000.
143
Examples
Open a second graph to display the 350-point contents of the dBuf buffer at address
0x12000.
The TCM buffer contains part of the feedback data near the transient. Notice that the first
part of the TCM buffer (approximately 25 samples) contains data which has not exceeded
either trigger threshold. This is the lead frame.
144
Examples
Lines 25-28: create an instance of the DF23 controller and sub-structures (note that the
sub-structures are not used in this example).
Lines 34-37: create the delay line which we will use to model time delay in the plant
To verify the working of the delay model, add the variable v6 and the delay line array
“p_array” to the expressions window, then set a break-point at the end of the ISR and
observe the data updates in the array.
The example is configured to construct a y = x2 target profile. Offsets and gains are
loaded into the SPS, and the update performed using the DCL_updateGSM() function.
Lines 23-25: create instances of the GSM module and supporting sub-structures,
initialized with their default values.
Lines 41-42: Initialize the results buffer which will hold the input-output curve.
Lines 49-54: load the GSM shadow offset table from a target function.
Line 57: loads the shadow gain table from the shadow offsets.
Lines 60-61: copy the shadow parameter sets into the active controller tables.
145
Examples
Lines 64-69: run the GSM to construct the input-output table and store it in the results
buffer.
Open a graph window to view the contents of the result buffer. The graph properties
window should be configured as follows.
The graph shows the GSM input-output curve and for the default target function (y = x2)
should look like this:
146
Examples
a 10 1
b 253 2
c 60 3
ISR (a) reflects a situation common in field oriented motor control in which a relatively low
rate PID controller, possibly regulating shaft speed, is cascaded with two parallel PI
147
Examples
current control loops running approximately ten times faster. The interrupt runs at 10 kHz,
and the PID controller is “time sliced” to run ten times slower, at 1 kHz.
ISR (b) represents a higher rate loop, perhaps regulating other power electronics sub-
systems such as PFC control. The ISR contains a gain scheduler and DF11 compensator
in cascade, running at the full 253 kHz rate. Also in this ISR is a DF22 compensator
which is “time sliced” to run at one third of the interrupt rate.
The last loop, ISR (c), contains a DF23 compensator and is configured with a varying
payload, so that the execution time changes as the program runs. Also, the DF23
compensator coefficients are updated periodically in the background loop.
The overall program is fairly demanding from the point of view of computational load and
the programmer might reasonably wish to know the CPU bandwidth to ensure hard real-
time deadlines are being met. This information can be found using the hardware ERAD
module. Refer to the ERAD chapter in the TMS320F28004x Technical Reference Manual
for information on the ERAD module and registers.
This example uses the ERAD module to measure the CPU “bandwidth”: the amount of
cycles available after all the application real-time requirements have been met. To
determine this, we measure the number of CPU cycles between consecutive calls to the
slowest interrupt in the system, and subtract from is the total number of cycles spent
servicing interrupts over the same interval. This is equivalent to the number of cycles
spent in the background loop over the longest interrupt interval and is usually expressed
as a percentage.
In this example, we could have 3 or 4 ISR (b) calls and 5 or 6 ISR (c) calls between two
consecutive ISR (a) calls.
With reference to the above figure, the example code measures the worst case CPU
availability as follows:
148
Examples
The example links all the ISR code to a single named section (“interruptSection”) for ease
of profiling. Refer to the files F280049_ERAD.cmd and F280049_stdmem.cmd to see
how this is done. Note that the method of configuring the ERAD module involves the use
of API functions contained in the source file f28004x_dcl_erad.c.
Lines 8 – 39: create instances of the controllers and control variables used in the
program, and define the constants used for decimation.
Lines 168 – 169: update the DF23 controller parameters used in ISR (c).
Lines 174 – 187: tests the number of passes through the background loop and halts
execution when the number exceeds (arbitrarily) 1000, after which CPU timers are
stopped and the PC is trapped in an infinite “while” loop.
Lines 192 – 244: contain the three interrupt service routines, each of which is associated
with the named section “interruptSection” using a CODE_SECTION pragma.
Lines 247 – 315: configure the ERAD registers using the API set to capture the
information described in the previous section.
Open an Expressions window in CCS and add the variables shown below, then run the
program. The values should be similar to those shown below.
The best case CPU bandwidth measured over 1000 cycles is:
The user may like to experiment with the configuration of the ERAD module to make other
measurements.
149
Examples
To simulate a control loop, the user will load example set-point data (rk) and feedback
data (yk) into two pre-defined buffers in internal RAM. These, together with integrator
clamp data (lk) are processed sequentially by the controller and the results (uk) stored in
a separate buffer. The buffer names and addresses are as follows:
Lines 15-18: use the DATA_SECTION pragma to associate array names with sections in
the linker command file F28388D_DCL.cmd.
Lines 21-24: associate names with the start addresses of these sections.
Lines 27-30: create instances of the four data buffers used in the test.
Lines 33-36: create instances of the data log structures which will manage the buffers.
Line 45: creates an instance of the PIDF64 controller and initializes it with default data.
Open and inspect the header file DCLF64.h to see these definitions.
Lines 69-74: initialize the data buffers. Notice that the “rBuf” buffer, which contains the lk
data, is initialized to hold all 1’s. This is because in this test the loop does not saturate.
The variable “lk” is used by the controller to implement integrator anti-windup from an
external point in the loop, so we need this input to always be 1.
Lines 109-111: read the input data from the three input buffers. Typically this data would
come from an ADC, but in this test we are reading pre-recorded data.
150
Examples
Then, set break-points at the two DCL_BREAK_POINT instructions in lines 86 and 97.
Load the r(k) and y(k) data into the device as follows:
Load the data file “rdata.dat” at this address. Set the data length to 1024.
Load the data file “ydata.dat” to address 0x1A000 with similar length.
In the memory browser, view the controller output buffer at address 0x1C000.
Run the program so that it reaches the second break-point. The controller has now
processed all the points in the input buffers and the results are stored in RAMGS15.
Open a graph window to view the contents of the result buffer at address 0x1C000. The
graph properties should look like this:
151
Examples
Open a memory browser window and configure it to view 32-bit floating point data
beginning at address 0xB800 in data space. Right-click in the memory window and load
the data file NLPID_input.dat at this address. Set the data length to 501.
Load the data file NLPID_feedback.dat to memory address 0xBC00 in a similar way.
152
Examples
View the memory at address 0xC000 in the memory browser. Then, in the source file
Example_F280025_NLPID.c, set a break-point on the DCL_BREAK_POINT instruction in
the while loop at the end of the main program.
Run the program. After a short delay, the PC should stop at the break-point and the
memory browser window be updated with the test data (you may have to scroll down in
the memory browser to see the new data).
Save the test data by right-clicking in the memory browser window and selecting “Save
Memory…”. Enter the filename “NLPID_testdata.dat” in the example directory, and save
501 words of 32-bit floating point data starting at address 0xC000.
The test results data file can be imported into Matlab for comparison with the expected
data. The waveform should look similar to that below.
153
Support
Chapter 6
Support
This chapter contains a list of useful technical resources relevant to the DCL.
Section
6.1 References
6.2 Training
6.3 Support
6.1 References
6.1.2 Literature
The following is a selection of publications on control theory.
154
Support
6.2 Training
Training materials for the C2000 devices from Texas Instruments can be found at
training.ti.com/c2000-workshops
6.3 Support
Technical support on the DCL is available via the C2000 e2e forum, at
e2e.ti.com/support/microcontrollers/c2000
155
IMPORTANT NOTICE AND DISCLAIMER
TI PROVIDES TECHNICAL AND RELIABILITY DATA (INCLUDING DATASHEETS), DESIGN RESOURCES (INCLUDING REFERENCE
DESIGNS), APPLICATION OR OTHER DESIGN ADVICE, WEB TOOLS, SAFETY INFORMATION, AND OTHER RESOURCES “AS IS”
AND WITH ALL FAULTS, AND DISCLAIMS ALL WARRANTIES, EXPRESS AND IMPLIED, INCLUDING WITHOUT LIMITATION ANY
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT OF THIRD
PARTY INTELLECTUAL PROPERTY RIGHTS.
These resources are intended for skilled developers designing with TI products. You are solely responsible for (1) selecting the appropriate
TI products for your application, (2) designing, validating and testing your application, and (3) ensuring your application meets applicable
standards, and any other safety, security, or other requirements. These resources are subject to change without notice. TI grants you
permission to use these resources only for development of an application that uses the TI products described in the resource. Other
reproduction and display of these resources is prohibited. No license is granted to any other TI intellectual property right or to any third
party intellectual property right. TI disclaims responsibility for, and you will fully indemnify TI and its representatives against, any claims,
damages, costs, losses, and liabilities arising out of your use of these resources.
TI’s products are provided subject to TI’s Terms of Sale (www.ti.com/legal/termsofsale.html) or other applicable terms available either on
ti.com or provided in conjunction with such TI products. TI’s provision of these resources does not expand or otherwise alter TI’s applicable
warranties or warranty disclaimers for TI products.
Mailing Address: Texas Instruments, Post Office Box 655303, Dallas, Texas 75265
Copyright © 2019, Texas Instruments Incorporated