cancel
Showing results for 
Search instead for 
Did you mean: 

Are there engineers at ST who understand unsigned math?

Posted on August 10, 2015 at 19:10

I've railed on this code construct for several years, it frustratingly continues to get propagated.

...
uint32_t uwIC2Value1 = 0;
uint32_t uwIC2Value2 = 0;
uint32_t uwDiffCapture = 0;
uint32_t uwDiffCapture1 = 0;
uint32_t uwDiffCapture2 = 0;
uint32_t uwDiffCapture3 = 0;
...
/* Get the 2nd Input Capture value */
uwIC2Value2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
/* Capture computation */
if (uwIC2Value2 > uwIC2Value1)
{
uwDiffCapture = (uwIC2Value2 - uwIC2Value1);
}
else /* (uwIC2Value2 <= uwIC2Value1) */
{
uwDiffCapture = ((0xFFFFFFFF - uwIC2Value1) + uwIC2Value2);
}
uwDiffCapture3=uwDiffCapture2;
uwDiffCapture2=uwDiffCapture1;
uwDiffCapture1=uwDiffCapture;
...

Say I have a delta of 4 1 + 4 = 5 So 0x00000001 uwIC2Value1 0x00000005 uwIC2Value2 uwDiffCapture = (uwIC2Value2 - uwIC2Value1); uwDiffCapture = 4 Let's look at the wrapping condition, with a Period of 0xFFFFFFFF (N-1) the counter counts from 0xFFFFFFFF to 0x00000000 as it transitions from the last state to the first. The counter has 2 32 states, not 2 32-1 states. 0xFFFFFFFE + 4 = 0x0000000100000002 in 64-bit space, in 32-bit the 1 is a carry = 0x00000002 Wrapped in 32-bit space So 0xFFFFFFFE uwIC2Value1 0x00000002 uwIC2Value2 uwDiffCapture = ((0xFFFFFFFF - uwIC2Value1) + uwIC2Value2); uwDiffCapture = ((0xFFFFFFFF - 0xFFFFFFFE) + 0x00000002) uwDiffCapture = (0x00000001 + 0x00000002) uwDiffCapture = 0x00000003 !!!!THREE!!! Where as uwDiffCapture = (uwIC2Value2 - uwIC2Value1); uwDiffCapture = 0x00000002 - 0xFFFFFFFE uwDiffCapture = 0xFFFFFFFF00000004 in 64-bit space uwDiffCapture = 0x00000004 in 32-bit space it truncates to the correct answer Can we please fix this in all the 16-bit and 32-bit TIM_InputCapture examples so it stops contaminating the code people copy into their projects

/* Capture computation */
uwDiffCapture = (uwIC2Value2 - uwIC2Value1); // Works for ALL 32-bit unsigned values

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
4 REPLIES 4
John F.
Senior
Posted on August 12, 2015 at 09:28

ST should reply to this. It's fundamental.

Clive, you may have to push this to the moderator yourself!

yhuang
Associate II
Posted on August 13, 2015 at 03:53

It is a long story and depends on compiler implementation.

For unsigned 32bit integer you may try it as below for example of time elapse:

bool TimeAAfterB(u32 a, u32 b)

{

    u32 d  = (b - a);

    return (d & 0x80000000u);

}

u32 GetElapseTime(u32 timeNow, u32 timeBefore)

{

    u32 elapseTime;

    if (TimeAAfterB(timeNow, timeBefore))

        elapseTime = 0xffffffff - timeBefore + timeNow + 1;

    else

        elapseTime = timeNow - timeBefore;

    return elapseTime;

}

Posted on August 13, 2015 at 04:49

It is a long story and depends on compiler implementation.

While intriguing, and perhaps highlighting a broken, or non, 2's complement implementation, I think you missed the point.

a) We don't need to do a comparison, or any other gyrations.

b) We don't want an answer that's off by one.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on August 18, 2015 at 12:20

Hi clive1,

The issue is reported internally.

Best regards

-Shahrzad-