#define HAVE_TICK static union { uint32_t u32; uint8_t u8[4]; } systick = { .u32 = 0 }; #ifndef SYSTICK_USER_1HZ #define systick_user_1hz() #endif static uint8_t tick_sub; ISR(TIMER1_COMPA_vect) { #ifdef SYSTICK_USER_100HZ systick_user_100hz(); if (++tick_sub < 100) return; tick_sub = 0; #endif systick.u32++; systick_user_1hz(); } static void uart_puttick(void) { uint16_t frac = TCNT1; _uart_putch('@'); uart_puthex(systick.u8[3]); uart_puthex(systick.u8[2]); uart_puthex(systick.u8[1]); uart_puthex(systick.u8[0]); _uart_putch('.'); #ifdef SYSTICK_USER_100HZ uart_puthex(tick_sub); #else uart_puthex16(frac); #endif #if DEBUG_SP _uart_putch('~'); uint8_t spl, sph; asm ("\n\ in %[spl], 0x3d\n\ in %[sph], 0x3e\n\ " : [spl] "=r" (spl), [sph] "=r" (sph)); uart_puthex(sph); uart_puthex(spl); #endif _uart_putch(' '); } static void tick_init(void) { TCCR1A = 0; #ifdef SYSTICK_USER_100HZ TCCR1B = (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10); // 8 MHz / 8 = 1 MHz asm volatile ("" ::: "memory"); TCNT1 = 0; OCR1A = 9999; // 100 Hz #else TCCR1B = (1 << WGM12) | (1 << CS12) | (0 << CS11) | (0 << CS10); // 8 MHz / 256 = 31250 Hz asm volatile ("" ::: "memory"); TCNT1 = 0; OCR1A = 31249; // 1 Hz #endif asm volatile ("" ::: "memory"); TIFR1 = (1 << OCF1A); TIMSK1 = (1 << OCIE1A); }