This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ] IQMath

Other Parts Discussed in Thread: C2000WARE

This post addresses some common questions about the C2000 IQMath Library.  The library is fully documented in the C2000Ware software package.

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.
  • Refer to the C2000 Compiler User guide (http://www.ti.com/lit/spru514) for other compiler switches related to generating native floating-point code.
  • If your device has a TMU, then also enable this compiler switch.

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. The RTS index library (libc.a) will direct the linker to use the RTS library appropriate for your build.  Refer to the C2000 Compiler User guide (http://www.ti.com/lit/spru514)
  • 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 is included in C2000Ware. 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;

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 intrinsic to floating point operations. These must be modified manually or a macro created to do the translation.  These are documented in the MS320C28x Optimizing C/C++ Compiler User's Guide (www.ti.com/lit/spru514).
long __qmpy32(long src32a, long src32b, int q);

long __qmpy32by16(long src32, int src16, int q);

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.