AnsweredAssumed Answered

Are there engineers at ST who understand unsigned math?

Question asked by Clive One on Aug 10, 2015
Latest reply on Aug 18, 2015 by 68516
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 232 states, not 232-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

Outcomes