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.