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.

IQmath Lib - Performance



Hi everyone! I have some weird situation with IQmath library:

I've got several math operations with float variables in my adc_isr() function. This function is time critical so I decided to use IQmath library. I needed only functions like _IQmpy(), _IQdiv and _IQfrac. But after I've used them the execution time of my ISR increased almost twice. I thought this functions are supposed to be highly efficient... Can anyone explain this? Or maybe I'm doing something wrong?

Thank you in advance!

  • It is possible all is working as they should ... please check IQMath library documentation for benchmark information on each function. You will have a much better idea about the cycle efficiency once you know the reuired number of cycles for each IQ function used in your ISR.

  • Glib Dovgych said:
    I've got several math operations with float variables in my adc_isr() function. This function is time critical so I decided to use IQmath library. I needed only functions like _IQmpy(), _IQdiv and _IQfrac. But after I've used them the execution time of my ISR increased almost twice. I thought this functions are supposed to be highly efficient... Can anyone explain this? Or maybe I'm doing something wrong?

    Glib,

    It would help to know what the ISR code looked like before and after.  Also which device (in particular float or fixed-point).

    On a fixed point C28x float operations will be handled by the RTS library.  It will emulate IEEE float which is indeed very cycle intensive.

    If you wern't using float types then we need to look elsewhere for a answer. One thought - IQmath library is optimized for 32-bit - were you using less than this resoulution prior?

    -Lori

     

  • Thank you for your interest, Lori!

    I'm using F28035 controller without using CLA.

    First my ISR looked like this:

    interrupt void adc_isr(void)
    {  
     Uint16 Qpwm;
     float Ti, HRpart;
     array[i++] = (Uint16)(AdcResult.ADCRESULT0);          // Write current sample into array
     DCVoltage = (Uint16)(AdcResult.ADCRESULT1);       // Write DC voltage value

     AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;                //Clear ADCINT1 flag reinitialize for next SOC
     PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;             // Acknowledge interrupt to PIE

     if(i >= Npwm)  i = 0;  
     
      Ti = ((unsigned long)array[j++]*Tpwm/4095);
      Qpwm = (Uint16) Ti;
      HRpart = Ti-Qpwm;
      HRpart = (HRpart*256)+0x80;
      EPwm2Regs.CMPA.half.CMPA = Qpwm;
      EPwm2Regs.CMPA.half.CMPAHR = (Uint16)HRpart;
    }

    And after using IQmath library:

    interrupt void adc_isr(void)
    {  
     Uint16 Qpwm;
     _iq5 Ti;
     _iq HRpart;  // Q = 15
     array[i++] = _IQ(AdcResult.ADCRESULT0);              // Write current sample into array
     DCVoltage = _IQ(AdcResult.ADCRESULT1);           // Write DC voltage value

     AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;           //Clear ADCINT1 flag reinitialize for next SOC
     PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;        // Acknowledge interrupt to PIE

     if(i >= Npwm)   i = 0;

     Ti = _IQ5mpy(_IQtoIQ5(array[j++]),_IQtoIQ5(PwmLimit));
     Ti = _IQ5div(Ti,_IQtoIQ5(4095.0));
     Qpwm = (Uint16) _IQ5int(Ti);
     HRpart = _IQ5toIQ(_IQ5frac(Ti));
     HRpart = _IQmpy(HRpart, _IQ(256.0))+_IQ(0x80);
     EPwm2Regs.CMPA.half.CMPA = Qpwm;
     EPwm2Regs.CMPA.half.CMPAHR = (Uint16)_IQint(HRpart);
    }
     

    Am I somewhere wrong?