IQmath Library for C28x

advertisement
IQmath Library for C28x
Contents
[hide]

1 Introduction to IQmath for C28x MCUs
o 1.1 Downloading IQmath
o 1.2 Frequently Asked Questions
 1.2.1 Q: Digital Motor Control Library
 1.2.2 Q: How do I change an IQmath project to a native floating-point project for the C28x+FPU?
 1.2.2.1 Compiler Version
 1.2.2.2 FastRTS Support Library (RTS)
 1.2.2.3 Modify the MATH_TYPE
 1.2.2.4 Interfacing to Registers
 1.2.2.5 Dividing by a Constant
 1.2.2.6 28x Constant Types in Float
 1.2.2.7 Shifting to Multiply or Divide by Multiples of 2
 1.2.2.8 Compiler Intrinsics
 1.2.3 Q: Where is the function __qmpy32 documented?
 1.2.4 Q: Where is the function __qmpy32by16 documented?
 1.2.5 Q: I get an error that a library is not compatible with the --float_support=fpu32 build option. What
can I do?
 1.2.6 Q: I want to mix IQmath and floating-point math on a C28x+FPU device. Can I do this?
 1.2.7 Q: If I use IQmath_f32.lib, does it do native floating point operations?
Introduction to IQmath for C28x MCUs
Texas Instruments TMS320C28x IQmath Library is collection of highly optimized and high precision mathematical Function Library
for C/C++ programmers to seamlessly port the floating-point algorithm into fixed point code on TMS320C28x devices.
IQmath uses the internal hardware of the C28x in the most efficient way to operate with 32bit fixed-point numbers. Taking into
account that all process data usually do not exceed a resolution of 16 bits, the library gives enough headroom for advanced numerical
calculations.
These routines are typically used in computationally intensive real-time applications where optimal execution speed & high accuracy
is critical. By using these routines you can achieve execution speeds considerable faster than equivalent code written in standard ANSI
C language. In addition, by providing ready-to-use high precision functions, TI IQmath library can shorten significantly your DSP
application development time.
Downloading IQmath
IQmath is included in controlSUITE™ under libs/math/IQmath.
controlSUITE™ for C2000™ microcontrollers is a cohesive set of software infrastructure and software tools
designed to minimize software development time. From device-specific drivers and support software to complete
system examples in sophisticated system applications, controlSUITE™ provides libraries and examples at every
stage of development and evaluation. Go beyond simple code snippits - jump start your real-time system with realworld software.
Visit the ControlSUITE™ webpage (www.ti.com/controlsuite)
Frequently Asked Questions
Q: Digital Motor Control Library
The F28x Digital Motor control library contains the Digital Motor control software modules. These component
modules, implemented in IQmath, are used to construct the systems such as Sensored/ Sensor less Control. The
original DMCLibrary was released for the F281x series SPRC080, and F280x series SPRC215. Starting in 2010
the libraries were re-released with optimized macro usage for system examples using Piccolo and Delfino families
controlSUITE Some examples of the component modules are PID controllers, Clarke, Park transforms, PWM
drivers and much more. For more on the motor control methodology and available resources visit TI Motor Control
Site
Q: How do I change an IQmath project to a native floating-point project for the C28x+FPU?
This is a list of tips and tricks that have been found when converting an IQmath application to floating point:
Compiler Version


Use C28x codegen tools version 5.0.2 or later.
Tell the compiler it can generate native C28x floating-point code. To do this, use the –v28 -float_support=fpu32 compiler switches. In Code Composer Studio V3.3 the float_support switch is on the
advanced tab of the compiler options.
FastRTS Support Library (RTS)
Include two RTS libraries in your project:

Codegen Floating Point RTS Library: Use the correct run-time support library for native 32-bit floating-point.
For C code this is rts2800_fpu32.lib. For C++ code with exception handling, use rts2800_fpu32_eh.lib.

FPU FastRTS Library: This library provides a boost to math operations by using lookup tables available in
the ROM of the device. See the documentation for more information. This library can be downloaded here:
28x FPU FastRTS Library
NOTE: The FastRTS library should be linked before the normal RTS library.
Modify the MATH_TYPE

In the IQmath header file, select FLOAT_MATH. The header file will convert all IQmath function calls to their
floating-point equivalent.
Interfacing to Registers

When writing a floating-point number into a device register, you need to convert the floating-point number to
an integer. Likewise when reading a value from a register it will need to be converted to float. In both cases,
this is done by multiplying the number by a conversion factor. For example to convert a floating-point
number to IQ15, multiply by 32768.0. Likewise, to convert from an IQ15 value to a floating-point value,
multiply by 1/32768.0 or 0.000030518.0. One thing to note: The integer range is restricted to 24-bits for a
32-bit floating-point value.
//
// Example:
// Convert from float to IQ15
//
// If MATH_TYPE == IQ_MATH
// Use the IQmath conversion function
//
#if MATH_TYPE == IQ_MATH
PwmReg = (int16)_IQtoIQ15(Var1);
//
// If MATH_TYPE == FLOAT_MATH
// Scale by 2^15 = 32768.0
//
#else // MATH_TYPE is FLOAT_MATH
PwmReg = (int16)(32768.0*Var1);
#endif
Dividing by a Constant

Instead of dividing by a constant, use a multiply. Using division will call the RTS library, or the fastRTS
library.
//
// This will use the division routine in the RTS library to divide by a constant
// AdcVal is type float32
//
#DEFINE ADC_SCALE 4096.0
...
AdcVal = AdcMirror.ADCRESULT0/ADC_SCALE;
//
// Preferred solution:
// This will perform a multiply instead of the divide
//
#DEFINE ADC_SCALE 1/4096.0
...
AdcVal = AdcMirror.ADCRESULT0* ADC_SCALE;
28x Constant Types in Float

Don't put an L after floating point constants. This will tell the compiler it is a 64-bit floating-point value and
the RTS library will be used.
//
// The L on the end of the constant tells the compiler it is a 64-bit floating-point value
// This multiply will cause a call to the RTS library for 64-bit floating-point support
//
PwmReg = (int16)(32768.0L*Var1);
//
// Preferred solution:
// This multiply will use the native 32-bit floating point capabilities
//
PwmReg = (int16)(32768.0*Var1);
Shifting to Multiply or Divide by Multiples of 2

If your IQmath used shifts to divide or multiply by multiples of 2 this will need to be changed to a multiply in
float. Remember to use multiply instead of divide when possible. For example, instead of a divide by 2, use
a multiply by .5 so the divide routine is not used.
Compiler Intrinsics
The current IQmath header file will not translate the following compiler intrinsics to floating point operations. These must be modified
manually or a macro created to do the translation.
long __qmpy32(long src32a, long src32b, int q);
long __qmpy32by16(long src32, int src16, int q);
Q: Where is the function __qmpy32 documented?
This function is a compiler intrinsic and is documented in the TMS320C28x Optimizing C/C++ Compiler User's
Guide (spru514).
Q: Where is the function __qmpy32by16 documented?
This function is a compiler intrinsic and is documented in the TMS320C28x Optimizing C/C++ Compiler User's
Guide (spru514).
Q: I get an error that a library is not compatible with the --float_support=fpu32 build option. What can I do?
The linker will not allow you to mix libraries built with float support with libraries that were not built with float support.
If it is a library you have the source to, then you can rebuild it with the --float_support=f32 switch. If it is a TI
supplied library without source then check to see if one is provided already. For example if you want to mix IQmath
and float32 math use IQmath_f32.lib instead of IQmath.lib.
Q: I want to mix IQmath and floating-point math on a C28x+FPU device. Can I do this?
Instead of using the IQmath.lib library use IQmath_f32.lib. This build of the library can be linked with code built with
the --float_support=fpu32 switch. This can be useful for mixing IQmath with native floating-point code on devices
with the C28x+FPU.
IQmath_f32.lib is available in the IQmath library V1.5 and later.
Q: If I use IQmath_f32.lib, does it do native floating point operations?
No - functions in this library still operate on _iq math types. Remember all fixed-point operations are 100%
compatible on the C28x+FPU.
For technical support please post your questions at http://e2e.ti.com. Please post only comments about the article IQmath
Library for C28x here
Supporting Functions
Introduction
Fixed point math library contains High Accuracy Mathematical Functions that are developed as an easy-to-use library, which has to be
linked to the user's application. These routines are typically used in computationally intensive real-time applications where optimal
execution speed and high accuracy is critical. By using these routines you can achieve execution speeds considerable faster than
equivalent code written in standard ANSI C language.
Trigonometric Functions
Functions
Description
_iq _IQasin( _iq A)
High precision ASIN (output in radians)
_iq _IQsin( _iq A)
High precision SIN (input in radians)
_iq _IQsinPU( _iq A)
High precision SIN (input in per-unit)
_iq _IQacos( _iq A)
High precision Acos (output in radians)
_iq _IQcos( _iq A)
High precision cos(input in radians)
_iq _IQcosPU( _iq A)
High precision sin(input in per-unit)
_iq _IQatan2( _iq A, _iq B)
4-quadrant ATAN (output in radians)
_iq _IQatan2PU( _iq A, _iq B)
4-quadrant ATAN (output in per-unit)
_iq _IQatan( _iq A, _iq B)
Arctangent
Mathematical Functions
Functions
Description
_iq _IQexp( _iq A)
High precision e raised to the A power
_iq _IQsqrt( _iq A)
High precision square root
_iq _IQisqrt( _iq A)
High precision inverse square root
_iq _IQmag( _iq A, _iq B)
Magnitude Square: sqrt(A2 + B2)
Arithmetic Operations
Functions
Description
_iq _IQmpy( _iq A, _iq B)
IQ Multiplication
_iq _IQrmpy( _iq A, _iq B)
IQ Multiplication with rounding
_iq _IQrsmpy( _iq A, _iq B)
IQ multiplication with rounding & saturation
_iq _IQmpyIQX( _iqN1 A, N1, _iqN2 B, N2 )
Multiply two 2-different IQ number
_iq _IQdiv( _iq A, _iq B)
Fixed point division
Benchmarks
Cortex-M3 Processor --Keil Optimization default . Optimize for Time Runs Under Simulator.Equals to Run in Ram
1. _IQ24sin(_IQ24(3.1415926/3.0))=0x00DDB3D6=_IQ24(0.866025),Time=86 Cycles
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
_IQ24cos(_IQ24(3.1415926/3.0))=0x00800000=_IQ24(0.500000),Time=80 Cycles
_IQ24cosPU(_IQ24(1.0/6.0))=0x00800003=_IQ24(0.500000),Time=69 Cycles
_IQ24sinPU(_IQ24(1.0/6.0))=0x00DDB3D5=_IQ24(0.866025),Time=75 Cycles
_IQ24exp(_IQ24(1.0))=0x02B7E14E=_IQ24(2.718282),Time=282 Cycles
_IQ24sqrt(_IQ24(2.0))=0x016A09E5=_IQ24(1.414213),Time=128 Cycles
_IQ24isqrt(_IQ24(2.0))=0x00B504F3=_IQ24(0.707107),Time=125 Cycles
_IQ24asin(_IQ24(0.5))=0x00860A91=_IQ24(0.523599),Time=322 Cycles
_IQ24acos(_IQ24(0.5))=0x010C1524=_IQ24(1.047198),Time=327 Cycles
_IQ24atan(_IQ24(0.5))=0x0076B19C=_IQ24(0.463648),Time=178 Cycles
_IQ24int(_IQ24(0.5))=0x00000000=_IQ24(0.000000),Time=16 Cycles
_IQ24frac(_IQ24(0.5))=0x00800000=_IQ24(0.500000),Time=17 Cycles
_IQ24mag(_IQ24(0.5),_IQ24(0.5))=0x00B504F2=_IQ24(0.707107),Time=147 Cycles
_IQ24div(_IQ24(0.5),_IQ24(0.5))=0x01000000=_IQ24(1.000000),Time=131 Cycles
15.
16.
17.
18.
_IQ24rmpy(_IQ24(0.5),_IQ24(0.5))=0x00400000=_IQ24(0.250000),Time=22 Cycles
_IQ24rsmpy(_IQ24(0.5),_IQ24(0.5))=0x00400000=_IQ24(0.250000),Time=49 Cycles
_IQ24atan2(_IQ24(0.5),_IQ24(0.5))=0x00C90FDA=_IQ24(0.785398),Time=181 Cycles
_IQ24atan2PU(_IQ24(0.5),_IQ24(0.5))=0x001FFFFF=_IQ24(0.125000),Time=189 Cycles
Cortex-M3 Processor --Keil Optimization default . Optimize for Time Device:Stm32f103VC Run in Flash :FLASH_ACR_LATENCY_2;
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
_IQ24sin(_IQ24(3.1415926/3.0))=0x00DDB3D6=_IQ24(0.866025),Time=113 Cycles
_IQ24cos(_IQ24(3.1415926/3.0))=0x00800000=_IQ24(0.500000),Time=112 Cycles
_IQ24cosPU(_IQ24(1.0/6.0))=0x00800003=_IQ24(0.500000),Time=94 Cycles
_IQ24sinPU(_IQ24(1.0/6.0))=0x00DDB3D5=_IQ24(0.866025),Time=99 Cycles
_IQ24exp(_IQ24(1.0))=0x02B7E14E=_IQ24(2.718282),Time=316 Cycles
_IQ24sqrt(_IQ24(2.0))=0x016A09E5=_IQ24(1.414213),Time=143 Cycles
_IQ24isqrt(_IQ24(2.0))=0x00B504F3=_IQ24(0.707107),Time=141 Cycles
_IQ24asin(_IQ24(0.5))=0x00860A91=_IQ24(0.523599),Time=377 Cycles
_IQ24acos(_IQ24(0.5))=0x010C1524=_IQ24(1.047198),Time=392 Cycles
_IQ24atan(_IQ24(0.5))=0x0076B19C=_IQ24(0.463648),Time=217 Cycles
_IQ24int(_IQ24(0.5))=0x00000000=_IQ24(0.000000),Time=22 Cycles
_IQ24frac(_IQ24(0.5))=0x00800000=_IQ24(0.500000),Time=22 Cycles
_IQ24mag(_IQ24(0.5),_IQ24(0.5))=0x00B504F2=_IQ24(0.707107),Time=159 Cycles
_IQ24div(_IQ24(0.5),_IQ24(0.5))=0x01000000=_IQ24(1.000000),Time=166 Cycles
_IQ24rmpy(_IQ24(0.5),_IQ24(0.5))=0x00400000=_IQ24(0.250000),Time=26 Cycles
_IQ24rsmpy(_IQ24(0.5),_IQ24(0.5))=0x00400000=_IQ24(0.250000),Time=57 Cycles
_IQ24atan2(_IQ24(0.5),_IQ24(0.5))=0x00C90FDA=_IQ24(0.785398),Time=223 Cycles
_IQ24atan2PU(_IQ24(0.5),_IQ24(0.5))=0x001FFFFF=_IQ24(0.125000),Time=238 Cycles
Cortex-M3 Processor --Gcc Sourcery G++ Lite. Optimize for Speed(level 2)Device:Stm32f103VC Run in Ram Simulator;
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
_IQ24sin(_IQ24(3.1415926/3.0))=0x00DDB3D6=_IQ24(0.866025),Time=127 Cycles
_IQ24cos(_IQ24(3.1415926/3.0))=0x00800000=_IQ24(0.500000),Time=109 Cycles
_IQ24cosPU(_IQ24(1.0/6.0))=0x00800003=_IQ24(0.500000),Time=104 Cycles
_IQ24sinPU(_IQ24(1.0/6.0))=0x00DDB3D5=_IQ24(0.866025),Time=123 Cycles
_IQ24exp(_IQ24(1.0))=0x02B7E14E=_IQ24(2.718282),Time=367 Cycles
_IQ24sqrt(_IQ24(2.0))=0x016A09E5=_IQ24(1.414213),Time=108 Cycles
_IQ24isqrt(_IQ24(2.0))=0x00B504F3=_IQ24(0.707107),Time=105 Cycles
_IQ24asin(_IQ24(0.5))=0x00860A91=_IQ24(0.523599),Time=362 Cycles
_IQ24acos(_IQ24(0.5))=0x010C1524=_IQ24(1.047198),Time=367 Cycles
_IQ24atan(_IQ24(0.5))=0x0076B19C=_IQ24(0.463648),Time=223 Cycles
_IQ24int(_IQ24(0.5))=0x00000000=_IQ24(0.000000),Time=13 Cycles
12.
13.
14.
15.
16.
17.
18.
_IQ24frac(_IQ24(0.5))=0x00800000=_IQ24(0.500000),Time=19 Cycles
_IQ24mag(_IQ24(0.5),_IQ24(0.5))=0x00B504F2=_IQ24(0.707107),Time=145 Cycles
_IQ24div(_IQ24(0.5),_IQ24(0.5))=0x01000000=_IQ24(1.000000),Time=141 Cycles
_IQ24rmpy(_IQ24(0.5),_IQ24(0.5))=0x00400000=_IQ24(0.250000),Time=22 Cycles
_IQ24rsmpy(_IQ24(0.5),_IQ24(0.5))=0x00400000=_IQ24(0.250000),Time=39 Cycles
_IQ24atan2(_IQ24(0.5),_IQ24(0.5))=0x00C90FDA=_IQ24(0.785398),Time=223 Cycles
_IQ24atan2PU(_IQ24(0.5),_IQ24(0.5))=0x001FFFFF=_IQ24(0.125000),Time=229 Cycles
Cortex-M3 Processor --Gcc Sourcery G++ Lite. Optimize for Speed(level 2)Device:Stm32f103VC Run in Flash :FLASH_ACR_LATENCY_2;
1. _IQ24sin(_IQ24(3.1415926/3.0))=0x00DDB3D6=_IQ24(),Time=148 Cycles
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
_IQ24cos(_IQ24(3.1415926/3.0))=0x00800000=_IQ24(),Time=127 Cycles
_IQ24cosPU(_IQ24(1.0/6.0))=0x00800003=_IQ24(),Time=131 Cycles
_IQ24sinPU(_IQ24(1.0/6.0))=0x00DDB3D5=_IQ24(),Time=144 Cycles
_IQ24exp(_IQ24(1.0))=0x02B7E14E=_IQ24(),Time=421 Cycles
_IQ24sqrt(_IQ24(2.0))=0x016A09E5=_IQ24(),Time=118 Cycles
_IQ24isqrt(_IQ24(2.0))=0x00B504F3=_IQ24(),Time=124 Cycles
_IQ24asin(_IQ24(0.5))=0x00860A91=_IQ24(),Time=416 Cycles
_IQ24acos(_IQ24(0.5))=0x010C1524=_IQ24(),Time=429 Cycles
_IQ24atan(_IQ24(0.5))=0x0076B19C=_IQ24(),Time=267 Cycles
_IQ24int(_IQ24(0.5))=0x00000000=_IQ24(),Time=21 Cycles
_IQ24frac(_IQ24(0.5))=0x00800000=_IQ24(),Time=27 Cycles
_IQ24mag(_IQ24(0.5),_IQ24(0.5))=0x00B504F2=_IQ24(),Time=150 Cycles
_IQ24div(_IQ24(0.5),_IQ24(0.5))=0x01000000=_IQ24(),Time=160 Cycles
_IQ24rmpy(_IQ24(0.5),_IQ24(0.5))=0x00400000=_IQ24(),Time=25 Cycles
_IQ24rsmpy(_IQ24(0.5),_IQ24(0.5))=0x00400000=_IQ24(),Time=49 Cycles
_IQ24atan2(_IQ24(0.5),_IQ24(0.5))=0x00C90FDA=_IQ24(),Time=267 Cycles
_IQ24atan2PU(_IQ24(0.5),_IQ24(0.5))=0x001FFFFF=_IQ24(),Time=276 Cycles
Cortex-M3 Processor --IAR Optimization High. Optimize for Speed Device:Stm32f103VC Run in Flash :FLASH_ACR_LATENCY_2;
1.
2.
3.
4.
5.
6.
7.
8.
_IQ24sin(_IQ24(3.1415926/3.0))=0x00DDB3D6=_IQ24(0.866025),Time=177 Cycles
_IQ24cos(_IQ24(3.1415926/3.0))=0x00800000=_IQ24(0.500000),Time=160 Cycles
_IQ24cosPU(_IQ24(1.0/6.0))=0x00800003=_IQ24(0.500000),Time=150 Cycles
_IQ24sinPU(_IQ24(1.0/6.0))=0x00DDB3D5=_IQ24(0.866025),Time=157 Cycles
_IQ24exp(_IQ24(1.0))=0x02B7E14E=_IQ24(2.718282),Time=474 Cycles
_IQ24sqrt(_IQ24(2.0))=0x016A09E5=_IQ24(1.414213),Time=151 Cycles
_IQ24isqrt(_IQ24(2.0))=0x00B504F3=_IQ24(0.707107),Time=150 Cycles
_IQ24asin(_IQ24(0.5))=0x00860A91=_IQ24(0.523599),Time=513 Cycles
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
_IQ24acos(_IQ24(0.5))=0x010C1524=_IQ24(1.047198),Time=533 Cycles
_IQ24atan(_IQ24(0.5))=0x0076B19C=_IQ24(0.463648),Time=332 Cycles
_IQ24int(_IQ24(0.5))=0x00000000=_IQ24(0.000000),Time=19 Cycles
_IQ24frac(_IQ24(0.5))=0x00800000=_IQ24(0.500000),Time=26 Cycles
_IQ24mag(_IQ24(0.5),_IQ24(0.5))=0x00B504F2=_IQ24(0.707107),Time=182 Cycles
_IQ24div(_IQ24(0.5),_IQ24(0.5))=0x01000000=_IQ24(1.000000),Time=173 Cycles
_IQ24rmpy(_IQ24(0.5),_IQ24(0.5))=0x00400000=_IQ24(0.250000),Time=28 Cycles
_IQ24rsmpy(_IQ24(0.5),_IQ24(0.5))=0x00400000=_IQ24(0.250000),Time=39 Cycles
_IQ24atan2(_IQ24(0.5),_IQ24(0.5))=0x00C90FDA=_IQ24(0.785398),Time=346 Cycles
_IQ24atan2PU(_IQ24(0.5),_IQ24(0.5))=0x001FFFFF=_IQ24(0.125000),Time=371 Cycles
Available Libraries



Win32
1. compiled and linked by Visual Stdio 2008
Cortex-M3 Processor
1. Compiled and Linked by Keil
2. Compiled and Linked by IAR
3. Compiled and Linked by GCC
Matlab
Background
Texas Instruments TMS320C28x IQmath Library is collection of highly optimized and high precision mathematical functions for C/C++
programmers to seamlessly port a floating-point algorithm into fixed point code on TMS320C28x devices. These routines are typically used in
computationally intensive real-time applications where optimal execution speed and high accuracy is critical. By using these routines you can
achieve execution speeds considerable faster than equivalent code written in standard ANSI C language. In addition, by providing readyto-use
high precision functions, TI IQmath library can shorten significantly your DSP application development time.
However the TI IQmath library can only be used in TMS320C28x devices, So i developed a library that all the functions are same as TI IQmath
libray and it can be in other devices,such as STM32 and so on.also it can be used in a device that has a CortexM3 core
Application
Can be used in a processor without a float process unit. MotorControl,FuzzyControl
About the Author
AlexKingBaby has been programming computers since 2002, he's now employed as an embedded software engineer.His current main focus is
developing high quality Motor Control algorithms. he spends his time to design Motor Control algorithms just for fun.
Download