AnsweredAssumed Answered

Low current mode and float calculation errors

Question asked by Thomas Johansen on Jul 6, 2018
Latest reply on Jul 12, 2018 by Thomas Johansen

Dear NXP Community

 

I use the low current mode of the LPC824 in my application. But it seems that doing this, makes calculation with double faulty...

I call a function that has a formula with 8-9 coefs (double) with an input value (Double). The function also return double. With some values, the result is alternating each time i call the function. With other values it is ok. Also the calculated values can be a bit of the correct ones.

When I disabling the low current mode there are no problems.

 

// Low power mode

cmdData[0] = 12;
cmdData[1] = PWR_LOW_CURRENT;
cmdData[2] = 12;
__disable_irq();
LPC_ROM_API->pPWRD->set_power(cmdData, &response);
__enable_irq();

 

My question is. How can the low current mode has impact on the calculation of float/double and have this strange behavior?

I'm pretty sure the early prototypes we did not behave like this.

 

I have attached a small project demonstrating this behaviour. It is for KEIL MDK v5 and the source code below

 

Test with low current mode:

LoopFunction Input dResult
127.78121.105545438064
227.78121.105545438064
327.78121.105545438064
427.81251.106883269864
527.81251.106883269864
627.81251.106883270273

 

The result for loop 4, 5 and 6 the resulting value is alternating (loop 4 and 6) and the value itself is a bit off.

Loop 1-3 is correct.

Removing the low power mode, no result is alternating and the value itself is spot on

 

Maybe this behaviour is expected using low current mode?

 

Best regards 

Thomas Johansen

 

Source code

 

double dCalcResult = 0.0;

 

#define cjT0t 2.5000000E+1
#define cjV0t 9.9198279E-01
#define cjP1t 4.0716564E-02
#define cjP2t 7.1170297E-04
#define cjP3t 6.8782631E-07
#define cjP4t 4.3295061E-11
#define cjq1t 1.6458102E-02
#define cjq2t 0.0000000E+00


double T0[4] = {0, 0, 0, cjT0t};
double V0[4] = {0, 0, 0, cjV0t};
double P1[4] = {0, 0, 0, cjP1t};
double P2[4] = {0, 0, 0, cjP2t};
double P3[4] = {0, 0, 0, cjP3t};
double P4[4] = {0, 0, 0, cjP4t};
double q1[4] = {0, 0, 0, cjq1t};
double q2[4] = {0, 0, 0, cjq2t};
double q3[4] = {0, 0, 0, cjq2t};


double dResult = 0.0;

 

/* Systick interrupt rate */
#define TICKRATE_HZ (100) /* 10 ticks per second */

 

double Calculations(double dTemp, int paramIndex)
{

    dResult = V0[paramIndex] + ( (dTemp-T0[paramIndex])*(P1[paramIndex]+(dTemp-T0[paramIndex])*(P2[paramIndex]+(dTemp-T0[paramIndex])*(P3[paramIndex]+P4[paramIndex]*(dTemp-T0[paramIndex]))))/( 1+(dTemp-T0[paramIndex])*(q1[paramIndex]+q2[paramIndex]*(dTemp-T0[paramIndex]))));
   return dResult;
}

 

double fCJTemps[] = {27.7812, 27.7812, 27.7812, 27.8125, 27.8125, 27.8125};
int nCount = 6;
int nIndex = 0;

int main(void)
{
   // uint8_t data[4] = {0xff};
   uint32_t cmdData[3];
   uint32_t response;

   // Generic Initialization
   SystemCoreClockUpdate();

   cmdData[0] = 12;
   cmdData[1] = PWR_LOW_CURRENT;
   cmdData[2] = 12;
   __disable_irq();
   LPC_ROM_API->pPWRD->set_power(cmdData, &response);
   __enable_irq();

 

   while(1)
   {
      if(nIndex >= nCount)
      {
          nIndex = 0;
       }
        dCalcResult = Calculations(fCJTemps[nIndex], 3);
        nIndex++;
    }
}

Attachments

Outcomes