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.

Type casting IQ format values

Other Parts Discussed in Thread: EK-TM4C123GXL

I am attempting to generate, at compile time, an array of sine values. Here is my code;

#include <stdint.h>
#include <stdbool.h>
#include "driverlib/sysctl.h"
#include "IQmath/IQmathLib.h"

#define PI 3.14156

int32_t out_array[64];

uint8_t i;


void main(void)
{
    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); //40 MHz

     for (i = 0; i<64; i++)
     {
    	 (_iq28) out_array[i] = _IQ28sin(i/64 * 2 * PI);
     }


     while(1)
     {

     }
}

If I declare out_array[64] as type _IQ28, this will compile. but i do not observe any resulting values in memory. Is this fixable?

To fix the invisible memory problem I am attempting to type cast out_array[64], which is now declared as type int32_t, as type _IQ28. I get a compile error "#138 expression must be a modifiable Ivalue". So now I have a second question: how can I cast an _IQ28 value as type int32_t?

I am running CCS 6.01, compiling for the EK-TM4C123GXL launchpad.

  • First, you're going to want to rearrange the argument to _IQ28sin; the expression i/64 will always be 0.  You should write it as i * 2 * PI / 64.

    It is not legal to cast the left hand side of an assignment.  Casting has higher precedence than assignment.  You could write it like this:

    (_iq28) ( out_array[i] = _IQ28sin(i/64 * 2 * PI) ) ;

    but the compiler will throw away the cast because it is unused.  You'll need to assign the value to a variable:

    _iq28 local = (_iq28) ( out_array[i] = _IQ28sin(i/64 * 2 * PI) ) ;

    However, I'm not sure I really understand the problem you're having.  You said that you "do not observe any resulting values;" do you mean that they are all zero?  That's likely because of the first thing, above.  Otherwise, please clarify what you are observing, and what you expected instead.

  • Thanks, Archaeologist, for pointing out my mistake that made sine values all zero. Now I see values in memory where they should be.

    I still have a question, though: how can I transfer IQ28 values to type int, if not by type casting? I am still pursuing this because I still do not have a useful listing of sine values in memory. Pasted below is my latest attempt:

    #include <stdint.h>
    #include <stdbool.h>
    #include "driverlib/sysctl.h"
    #include "IQmath/IQmathLib.h"
    
    #define PI 3.14156
    
    float out_array[64];
    uint8_t i;
    
    void main(void)
    {
        SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); //40 MHz
    
         for (i = 0; i<64; i++)
         {
        	 out_array[i] = _IQ28toF(_IQ28sin(i * 2 * PI/64));
         }
    
    
         while(1)
         {
         }
    }

    I set the memory browser to view 64-bit floating point only to see a long column of zeros. I am trying to get to see a column of values that might appear in a high school trig text book.

  • Hey, wow - I got it working! The code below produces an array of 8-bit values that embody a full sine wave:

    #include <stdint.h>
    #include <stdbool.h>
    #include "driverlib/sysctl.h"
    #include "IQmath/IQmathLib.h"
    
    #define PI 3.14156
    
    uint8_t sine_array[128], i;
    
    void main(void)
    {
        SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); //40 MHz
    
         for (i = 0; i<128; i++)
         {
           		 sine_array[i] = _IQ29sin(_IQ29(2 * PI * i/128 - PI))>>22 & 0xFF;
         }
    
         while(1)
         {
         }
    }

    What I finally realized was that the _IQ29sin function only operates on values of type _iq29. Also I found that simply doing 2*PI to go full circle produced unsatisfactory results near the end of the negative portion of the output. Following the example on page 56 here, I subtracted PI so the function input magnitude never exceeds PI.

    I also found the introduction to the IQ format here useful.