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.
#define LWIP_U32_DIFF(a, b) (((a) >= (b)) ? ((a) - (b)) : (((a) + ((b) ^ 0xFFFFFFFF) + 1)))
When ( a < b ), max_a is (b-1), min_a is 0, the result == a + (UINT_MAX - b) + 1, max_result == (b-1) + (UINT_MAX - b) + 1, min_result == 0 + (UINT_MAX - b) + 1, no wrapping.
#include <stdio.h> #include <stdint.h> void main(void) { uint16_t a16 = 0xFFFF, b16 = 1234, r16; uint32_t a32 = 0xFFFF, b32 = 1234, r32; r16 = a16 * b16; r32 = a32 * b32; printf("r16 = %u\n", r16); printf("r32 = %u\n", r32); printf( "r32 mod 0x10000 = %u\n", ( r32 % 0x10000 ) ); system("PAUSE"); }
r16 = 64302 r32 = 80870190 r32 mod 0x10000 = 64302
#include <stdio.h> #include <stdint.h> void main(void) { int16_t a16 = 32760, b16 = 1234, r16, r16_chk = -9872; int32_t a32 = 32760, b32 = 1234, r32; r16 = a16 * b16; r32 = a32 * b32; printf("r16 = %d\n", r16); printf("r32 = %d\n", r32); printf( "r32 mod 0x10000 = %d\n", ( r32 % 0x10000 ) ); printf( "r16_chk = %u\n", (uint16_t)r16_chk ); system("PAUSE"); }
r16 = -9872 r32 = 40425840 r32 mod 0x10000 = 55664 r16_chk = 55664
Modular arithmetic
en.wikipedia.org/.../Modular_arithmetic
(It is too difficult for me, so I simply skip it.)