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.

TMS320F28035: query regarding dividing _iq variable by integer

Part Number: TMS320F28035


Hi

I am using the IQmath library within our DSP code and am finding it tricky to get the correct method for integer division of an _iq variable

I have:

  •  the numerator: a measured _iq value of around 60.0
  •  the denominator: a Uint16 counter running in interrupt with value between 100 and 10000

Global_Q is 24 for our application

I would like to divide the _iq value by the Uint16 but I am unsure of the correct way to do this.

It might be that I am inspecting the variables incorrectly in CCS but for two options in the test code below both give negative numbers once den equals 1000
- this makes me suspect that I am hitting the limits of the global iq24?

#define kNoTests 4
Uint16 den = 10;
_iq num;
_iq testIQOut;
_iq testIQOutTwo;
static inline void _testRoutine(void){
  num = _IQ(61.2);

  Uint16 i;
  // testing 10, 100, 1000, 10000
  for (i = 0; i < kNoTests; i++ ) {
	  testIQOut =  _IQdiv(num, _IQ16toIQ((_iq)((Uint32)den << 16)));
	  testIQOutTwo = _IQdiv(num, _IQmpyI32(_IQ(1.0), (Uint32)den));

	  den *= 10;
  }
}

Any suggestions for how to cleanly do this would be gratefully received


Best regards,
- Richard

  • Suggesting my own answer it looks like it works if I promote to IQ16 for the complete calculation:

    static inline void _testRoutine(void){
      num = _IQ(61.2);
    
      Uint16 i;
    
      for (i = 0; i < kNoTests; i++ ) {
    
    	  _iq16 numTemp = _IQtoIQ16(num);
    	  _iq16 outTemp = _IQ16div(numT,(_iq16)((Uint32)den << 16));
    
    	  testIQOut =  _IQ16toIQ(outTemp);
    
    	  den *= 10;
      }
    }

    I would still be grateful for any suggestions or recommendations for how this is best done

    Best regards,

    - Richard

  • Richard,

    It looks to me like you are handling the variables consistently in your second "suggested" case. The only thing that looks suspicious to me in your original code snippet is _IQ16toIQ((_iq)((Uint32)den << 16)) for the denominator, where in your second case, you have (_iq16)((Uint32)den << 16)). In other words, I believe the first case might be performing the same operation (IQ conversion) twice, thus corrupting the den?

    Thanks,

    Sira

  • Thanks Sira

    I think the issue is more that the interim value I need does not fit in the IQ24 (but my ultimate result does)

    So if I shift back using _IQ16toIQ while the value is greater than (or equal to) 128 I get a saturated IQ24 value

    In essence I need to preserve the dynamic range during the whole of the operation

    Best regards,

    - Richard

  • Richard,

    Your explanation is correct.

    Thanks,

    Sira