# Compiler/TMS320F28069M: IQmath problem

Part Number: TMS320F28069M

Tool/software: TI C/C++ Compiler

Hi all!

I have a problem with the #include <IQmathLib.h> library. Currently I'm using a Launchpad F28069M, and the idea is that I need to calculate the sine and cosine for some variables in radians. But the IQmath lybrary is not that easy to understand.

My angles values are expressed as a 2*pi*w, and i have to update w several times during  a period of time (w will be between 10 and 10000). (This is in order to apply a FFT in my code)

I hope someone has an example of how  to apply the sine and cosine applying the IQmath lib so I can adapt it to my code.

Thanks in advance for the help!

Maria

### 9 Replies

• Hi Maria,

For examples of the basic IQmath functions I can do no better than point to the code examples in the quickstart guide (attached). The sine and cosine functions expect inputs in radians, and you have to keep within the numeric range of your chosen IQ format.  For example, with w = 10000 you'll be passing in a value of 62832, so your IQ format will need at least 16 bits of range (2^16 = 65536).  This will restrict you to IQ15 or less.

Regards,

Richard

6136.IQmath_Quickstart.pdf

• In reply to Richard Poley:

Dear Richard

Thanks for your repply, there is an easier way to do it? i tried with math.h and it does not matter what value I put i have the same answer, also tried some IQmath examples and they also give me some numbers at the output value that are really big and make no sense to me (even changing them from IQ to float) then I tried also CLAmath without success.

The main idea is only to generate a sine and cosine function in terms of a variable wp with amplitude 1. Then I want to have this value:

sin(2*pi*w) and cos(2*pi*w)

The variables I have are not in IQ format yet, but I would really appreciate if you could tell me an easier way to do it (without getting that into details with IQmath that is a bit complicated)

Best regards

Maria

Hi Maria,

It should be fairly straightforward to do this.  Once you have added the IQmath library to your project, here's what you might try in your program:

// variables
_iq twopi = _IQ(6.283185307f);
_iq sval = _IQ(0.0f);
_iq cval = _IQ(0.0f);
_iq ref = _IQ(0.0f);
_iq inc = _IQ(0.01f);
_iq angle = _IQ(0.0f);
long i;

main()

{

for (i=0; i<9999; i++)
{
angle = _IQmpy(twopi, ref);
sval = _IQsin(angle);
cval = _IQcos(angle);
ref += inc;
}

...etc.

If I set a break-point on the last line ("ref += inc;") it's stepping through the angles nicely.  You would change "inc" to change the frequency of the sine/cosine outputs, which would obviously be in global _IQ format (I was using IQ24).  The attachment is what I see in the watch window.

An alternative approach which does not involve IQmath is to use the FastRTS library which you can find in controlSUITE.  The sine and cosine functions have approximately the same cycle counts as their IQmath counterparts, and you will be able to keep everything in floating-point if that's what you want.

I hope this helps, but do post back if you have further questions.

Regards,

Richard

• In reply to Richard Poley:

Dear Richard

Thanks for the repply, I dont understand what happened but now I have 33 errors related to the #include <IQmathCPP.h> library. The error looks like this

And I cant try the code you sent me. This error appears the moment I call the include function.

Thanks in advance for the help.

best

Maria

Hi Maria,

Regret I can't really see what's going wrong from the errors.  Those warnings are from the C++ version of the library header file.

If I'm right, your project is the ADC SOC example in controlSUITE, which is likely at this location on your hard drive:

I've attached a slightly modified main source file for this example.  The only changes I've made are to add the IQ math header file at the top, and copy in the lines of code from my last post.  It's working correctly on my machine.

Can you change your own source file to look like this and let me know if it builds please?

(Note: you may get a couple of warnings when you build the project but these can be ignored).

Thanks.

Regards,

Richard

• In reply to Richard Poley:

dear Richard

First of all thanks for your time and help. I manage to fix the problem with the library by following your answer. Now i have a problem, I need to use the sine and cosine signal to compare with some float values in real time. I would like to know how to convert the values expressed below (Q format) to float directly(not only for visualization)

I hope you can help me to fix this problem too. Maybe i need to do some conversion?

And still i have some doubts about the results i have, as you can see in the next image, the values are not correctly at all for sine and cosine of the given angle. I would like to know if there is another thing i should add to the code? I'm here just using the code you sent to me. and I even add the #define   GLOBAL_Q       24

Regards

Maria

Dear Richard,

The problem with the 33 errors is generated when I try to include the library #include “IQmathCPP.h” that is used in the examples. I also tried to use the FastRTS but nothing seems to give me values that are useful for me for now. I imported the libraries:

#include "math.h"
#include "C28x_FPU_FastRTS.h"

And not even with 0 or 2*pi or 180 i have some value that is close to reality. Hope you can help me

best regards

Maria

If you are on F28069 you do not need IQmath library at all because you are already on floating point.

Use #include <math.h>

Please note the C28x_FPU_FastRTS.h does not need to be included, it's only a link time replacement..

read the user guide for fastRTS here

C:\ti\controlSUITE\libs\math\FPUfastRTS\V100\doc

Note:

The fastRTS also relies on CMD file for the math look up tables

the uG points to the below but this may not be correct for the device you have selected

MEMORY
{
PAGE 0 :

FPUTABLES : origin = 0x3FEBDC, length = 0x0006A0

}
SECTIONS
{

FPUmathTables : > FPUTABLES, PAGE = 0, TYPE = NOLOAD

}

I think it should be the below...  can you confirm you are using F28069M ??

MEMORY
{
PAGE 0 :

FPUTABLES   : origin = 0x3FD590, length = 0x0006A0 /* FPU Tables in Boot ROM */

}
SECTIONS
{

FPUmathTables : > FPUTABLES, PAGE = 0, TYPE = NOLOAD

}

• In reply to Manish Bhardwaj:

Hi Manish

//###########################################################################
// Description:
//!
//!
//! \b Watch \b Variables \n
//! - Voltage1[10] - Last 10 ADCRESULT0 values
//! - Voltage2[10] - Last 10 ADCRESULT1 values
//! - ConversionCount - Current result number 0-9
//! - LoopCount - Idle loop counter
//
//
//###########################################################################
// \$TI Release: F2806x C/C++ Header Files and Peripheral Examples V151 \$
// \$Release Date: February 2, 2016 \$
//###########################################################################

#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#include "math.h"

// Prototype statements for functions found within this file.

// Global variables used in this example:
Uint16 LoopCount;
Uint16 ConversionCount;
Uint16 Voltage1[10];
Uint16 Voltage2[10];

double sinRT = 0;
double cosRT = 0;
double angle = 0;
double wp = 2.65;
double pi = 3.141592654;

// variables

long i;

main()
{
// IQ math test
angle = 2*pi*wp;
sinRT = sin(angle);
cosRT = cos(angle);

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2806x_SysCtrl.c file.
InitSysCtrl();

// Step 2. Initialize GPIO:
// This example function is found in the F2806x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio(); // Skipped for this example

// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;

// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the F2806x_PieCtrl.c file.
InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in F2806x_DefaultIsr.c.
// This function is found in F2806x_PieVect.c.
InitPieVectTable();

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected register
EDIS; // This is needed to disable write to EALLOW protected registers

// Step 4. Initialize all the Device Peripherals:
// This function is found in F2806x_InitPeripherals.c
// InitPeripherals(); // Not required for this example

// Step 5. User specific code, enable interrupts:

PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable INT 1.1 in the PIE
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

LoopCount = 0;
ConversionCount = 0;

EALLOW;
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 5; // set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 5; // set SOC1 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; // set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC1CTL.bit.ACQPS = 6; // set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
EDIS;

// Assumes ePWM1 clock is already enabled in InitSysCtrl();
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group
EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from CMPA on upcount
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
EPwm1Regs.CMPA.half.CMPA = 0x0080; // Set compare A value
EPwm1Regs.TBPRD = 0xFFFF; // Set period for ePWM1
EPwm1Regs.TBCTL.bit.CTRMODE = 0; // count up and start

for(;;)
{
LoopCount++;
}

}

{

// If 20 conversions have been logged, start over
if(ConversionCount == 9)
{
ConversionCount = 0;
}
else ConversionCount++;

PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE

return;
}

and the replies i have are not the correct values, I don't know if I should change then some other configuration ?
wp = 0;
angle = 0;
sinRT = -0.9569404
cosRT = -0.2902847

or in a second try
wp = 2.65;
angle = 16.65044;
sinRT = 1.054673
cosRT = 0.008753741

Please I hope you can help me to understand where is the mistake