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:
| Loop | Function Input | dResult |
|---|
| 1 | 27.7812 | 1.105545438064 |
| 2 | 27.7812 | 1.105545438064 |
| 3 | 27.7812 | 1.105545438064 |
| 4 | 27.8125 | 1.106883269864 |
| 5 | 27.8125 | 1.106883269864 |
| 6 | 27.8125 | 1.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++;
}
}