IQmath Library for C28x

From Texas Instruments Wiki
Jump to: navigation, search

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 real-world 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.