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.