#include "project.h" static uint32_t high_tick; #if HW_CLOCK_LEN == 32 #define QUARTER (1UL << 29) #define HALF (1UL << 30) #define THREE_QUARTERS (HALF+QUARTER) #define ONE (~(uint32_t)0) uint64_t abs_extend (uint32_t now) { static int m; uint64_t ret; if (!m) { ret = high_tick; ret <<= 32; ret |= now; if ((now > THREE_QUARTERS) && (now <= ONE)) { high_tick++; m = 1; } } else { if (now < HALF) { ret = high_tick; ret <<= 32; ret |= now; } else { ret = high_tick - 1; ret <<= 32; ret |= now; } if ((now > QUARTER) && (now < HALF)) m = 0; } return ret; } #elif HW_CLOCK_LEN == 31 #define QUARTER (1UL << 28) #define HALF (1UL << 29) #define THREE_QUARTERS (HALF+QUARTER) #define ONE (0x7fffffff) uint64_t abs_extend (uint32_t now) { static int m; uint64_t ret; if (!m) { ret = high_tick; ret <<= 31; ret |= now; if ((now > THREE_QUARTERS) && (now <= ONE)) { high_tick++; m = 1; } } else { if (now < HALF) { ret = high_tick; ret <<= 31; ret |= now; } else { ret = high_tick - 1; ret <<= 31; ret |= now; } if ((now > QUARTER) && (now < HALF)) m = 0; } return ret; } #else #error unknown hardware clock length #endif void abs_meh (void) { printf ("HT %d\n", (int) high_tick); } uint64_t abs_get (void) { uint32_t now = HW_CLOCK_REG; return abs_extend (now); } void abs_slow_tick() { abs_get(); }