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.

CCS/MSP430FR5994: MSP430 IQFrac function on negative IQ values less than 1 error

Part Number: MSP430FR5994

Tool/software: Code Composer Studio

Hello All,

I have having an issue with the IQFrac function for the MSP430.  In a nutshell, it seems that trying to get the fractional portion of a negative IQ number removes all the sign extension, and gives a positive number.

(Note:  all my values are IQ16)

In my case, I am calling the IQ16Frac function on a variable whose value is -0.0625 (in hex, this is 0xFFFFE000).  When I call the IQfrac function, it returns only 0x0000F000 which is 0.9375, where my value should be -0.0625 (in hex 0xFFFFF000).  In this case, it seems the IQFrac function is just masking off the top 16 bits regardless of sign of the IQ number...

When I step through the assembly, I can see combined registers R12 (value 0xF000) and R13(value 0xFFFF), after the call to _IQ16Frac, the registers are R12 (0xF000) and R13 (0x0000).  Thus, the combination of this IQ16 number is now 0x0000F0000 (0.9375) which is not correct.

Dissassembly:

010118:   521C 1F04           ADD.W   &0x1f04,R12
01011c:   621D 1F06           ADDC.W  &0x1f06,R13
010120:   13B1 1950           CALLA   #_IQ16frac
010124:   4C82 1F04           MOV.W   R12,&0x1f04
010128:   4D82 1F06           MOV.W   R13,&0x1f06

Registers before CALLA instruction:

R12    0x00F000    Core    
R13    0x00FFFF    Core    

Registers after CALLA instruction:

R12    0x00F000    Core    
R13    0x000000    Core    

So I guess the question is, am I doing something wrong??   If not, any easy workarounds??

Thanks,

-mike

  • Hi

    The IQmath functions are based 32-bit data types. Have you define all the values to _iqxx like _iq16?
    Can you upload your whole test code?

    Best regards
    Gary
  • Hello Gary,

    Yep, all my variables are defined as _iq16...  See snippets below...

    this->stateData.IdftAngle = _IQ16frac(this->stateData.IdftAngle + Constants.Pro.minimumAngleIncrementPerTick);
    
    typedef struct tagStateData{
    	_iq16 IdftAngle;
    }STATEDATA
    
    typedef struct tagCONSTANTS{
        _iq16 minimumAngleIncrementPerTick;
    }CONSTANTS;
    
    

    This issue only occurs when the data is a negative value (in my case, I have only tested with negative values between 0 and -1.  I have not seen an issue (not sure if tested) with negative values less than -1 (such as -1.5, etc)

    I will see how the function reacts to that...

    thanks,

    -mike

  • Hello Gary,

    Attached is an example project that demonstrates this issue.

    I am using the LaunchPad for the MSP430FR5994 blink Led example project.  All I did was add IQ library support, and then a few global variables.

    I am using CCS 8.3, with the latest compiler (18.12.1) and latest mspware for the IQ libraries (3.8)

    To the main file, I added:

    #include "IQmathLib.h"
    
    const _iq16 negativeVar = _IQ16(-0.0625);
    volatile _iq16 fracOfVar = 0;

    and then in the main loop:

    fracOfVar = _IQ16frac(negativeVar);

    If you place a watch on the variable "negativeVar", you can see that its value is 0x0000F000, and if you setup the watch with Qvalue 16, you will see that it shows the value of 0.9375.  Where it should still show the value of -0.0625.

    thanks,

    -mike

    Snippets from screen shots when stepping through code (if they paste correctly):

    6622.BlinkLED_MSP430FR5994.zip

  • Hi Mike

    Thank you for your test. That really a bug in the function of _IQ16frac.
    Just add code
    if(negativeVar< 0)
    {
    fracOfVar= fracOfVar| 0xFFFF0000;
    }

    Best regards
    Gary
  • Thanks for the workaround. Will use that for now until a new build of the IQ MSP430 library is released.

**Attention** This is a public forum