Skip to main content
Tesla DeLorean
Guru
August 10, 2015
Question

Are there engineers at ST who understand unsigned math?

  • August 10, 2015
  • 4 replies
  • 833 views
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

    This topic has been closed for replies.

    4 replies

    John F.
    Associate III
    August 12, 2015
    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
    August 13, 2015
    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;

    }

    Tesla DeLorean
    Guru
    August 13, 2015
    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 VenmoUp vote any posts that you find helpful, it shows what's working..
    Nickname5522_O
    Visitor II
    August 18, 2015
    Posted on August 18, 2015 at 12:20

    Hi clive1,

    The issue is reported internally.

    Best regards

    -Shahrzad-