For ARM7, A hardware timer is 32-bits, and unsigned int is 32-bits too; For a 16-bits MCU, A hardware timer is 16-bits, and unsigned int is 16-bits too;
So,
t0 = timer_val; while ( ( timer_val - t0 ) < delay_val );
provide a simple and good delay;
Not so sure about, if a cast is needed.
t0 = timer_val; while ( (unsigned int)( timer_val - t0 ) < delay_val );
Just noticed that, due to the integral promotion,
unsigned short t0, t1; ( t1 - t0 ) is a signed int.
It seems that,
unsigned int t0, t1; ( t1 - t0 ) is still an unsigned int.
I noticed this, because I use unsigned short to present a 16-bits timer_val on my X86-PC for testing/simulating purpose, and the result is not what I expected.
int32_t now, end;
int32_t is the wrong type for that. You should use the same unsigned type as the actual timers are. Using signed instead adds nothing useful -- it only adds the issue of what happens on overflow of signed arithmetic. Unsigned arithmetic, OTOH, is guaranteed to wrap around cleanly.
The condition to test for is
(TIMER_VALUE - start) % timer_range >= delay
For timers 16 bits or 32 bits wide, you can avoid the explicit modulo operation if you choose the accorting uint16_t or uint32_t for 'start', since unsigned arithmetic already does the same modulo.
If you analyze the code sample carefully, you'll note how it gracefully handles the overflow issue. The timer is assumed free-running, no reload. It might depend on the arithmetics being '2's complement', but that would be a rather safe assumption.
If you analyze the code sample carefully, you'll note how it gracefully handles the overflow issue.
I don't note, because it doesn't. It causes signed integer overflows every time the TIMER_VALUE is bigger than int32_t variables can hold --- which it is 50% of the time.
What that code does is it assumes signed arithmetic overflows cleanly. It doesn't do anything to handle the possibility it might not.
Exactly. This was meant by design. I think you'll struggle to find an ARM compiler where 'signed arithmetic does not overflow cleanly.' In fact, I don't think one exists. Of course, it should be easy to add some protection against the unlikely event in the form of an assertion. I consulted the C99 standard. Indeed, it does not specify the behavior of a signed integer overflow, while it does for unsigned.
The standard two-complement arithmetic can really be assumed.
I do not thing any new chip vendor would dare to implement a different alternative because they would not save any transistors but would instead get into a shitload of problems.
The two-complement form really is trivial to implement in hardware (and a not too uncommon exercise for students to implement using VHDL or similar), both when having a very strict transistor count, and when having to implement an extremely wide ALU.