2015-08-10 10:10 AM
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
2015-08-12 12:28 AM
ST should reply to this. It's fundamental.
Clive, you may have to push this to the moderator yourself!2015-08-12 06:53 PM
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; }2015-08-12 07:49 PM
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.2015-08-18 03:20 AM
Hi clive1,
The issue is reported internally. Best regards -Shahrzad-