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.
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
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.
Is your input data (w) already in IQ format?
Regards,
Richard
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
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:
C:\ti\controlSUITE\device_support\f2806x\v151\F2806x_examples_ccsv5\adc_soc
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
//########################################################################### // Description: //! \addtogroup f2806x_example_list //! <h1> ADC Start of Conversion (adc_soc)</h1> //! //! This ADC example uses ePWM1 to generate a periodic ADC SOC - ADCINT1. //! Two channels are converted, ADCINA4 and ADCINA2. //! //! \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 $ // $Copyright: Copyright (C) 2011-2016 Texas Instruments Incorporated - // http://www.ti.com/ ALL RIGHTS RESERVED $ //########################################################################### #include "DSP28x_Project.h" // Device Headerfile and Examples Include File #include "IQmathLib.h" // Prototype statements for functions found within this file. __interrupt void adc_isr(void); void Adc_Config(void); // Global variables used in this example: Uint16 LoopCount; Uint16 ConversionCount; Uint16 Voltage1[10]; Uint16 Voltage2[10]; // 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() { // IQ math test for (i=0; i<9999; i++) { angle = _IQmpy(twopi, ref); sval = _IQsin(angle); cval = _IQcos(angle); ref += inc; } // 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 PieVectTable.ADCINT1 = &adc_isr; 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 InitAdc(); // For this example, init the ADC AdcOffsetSelfCal(); // Step 5. User specific code, enable interrupts: // Enable ADCINT1 in PIE 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; // Configure ADC EALLOW; AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 1; // Enable non-overlap mode AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; // ADCINT1 trips after AdcResults latch AdcRegs.INTSEL1N2.bit.INT1E = 1; // Enabled ADCINT1 AdcRegs.INTSEL1N2.bit.INT1CONT = 0; // Disable ADCINT1 Continuous mode AdcRegs.INTSEL1N2.bit.INT1SEL = 1; // setup EOC1 to trigger ADCINT1 to fire AdcRegs.ADCSOC0CTL.bit.CHSEL = 4; // set SOC0 channel select to ADCINA4 AdcRegs.ADCSOC1CTL.bit.CHSEL = 2; // set SOC1 channel select to ADCINA2 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 // Wait for ADC interrupt for(;;) { LoopCount++; } } __interrupt void adc_isr(void) { Voltage1[ConversionCount] = AdcResult.ADCRESULT0; Voltage2[ConversionCount] = AdcResult.ADCRESULT1; // If 20 conversions have been logged, start over if(ConversionCount == 9) { ConversionCount = 0; } else ConversionCount++; AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //Clear ADCINT1 flag reinitialize for next SOC PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE return; }
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
Thanks in advance for your help
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
…
}