--- /dev/null
+// Copyright (c) 2007, 2008 Martin Thomas - BSD-license\r
+// 10 ms timebase with \r
+// 8bit timer-counter #0 in CTC-mode on ATmega644\r
+\r
+#include <stdint.h>\r
+#include <avr/io.h>\r
+#include <avr/interrupt.h>\r
+#include "timebase.h"\r
+\r
+#include "key_io.h" /* keys callback/debouce */\r
+\r
+#define COUNTER_IS_16BIT 0\r
+#define PRESCALER 1024UL\r
+\r
+#if TIMEBASE_DELTAT_MS != 10\r
+#warning "code prepared for 10ms tick"\r
+#endif\r
+\r
+#define TIMERFREQ (1000/TIMEBASE_DELTAT_MS) /* Hz */\r
+#define OCRMATCHVAL ( (F_CPU*10/PRESCALER/TIMERFREQ+5)/10 - 1 )\r
+\r
+#if COUNTER_IS_16BIT\r
+ /* 16 bit counter */\r
+#define OCR_MATCH_MAX 0xfffe\r
+#else\r
+/* 8 bit counter */\r
+#define OCR_MATCH_MAX 0xfe\r
+#endif /* COUNTER_IS_16BIT */\r
+#define OCR_MATCH_MIN 0x02\r
+\r
+#if ( OCRMATCHVAL > OCR_MATCH_MAX )\r
+#error "PRESCALER too small or F_CPU too high"\r
+#endif\r
+#if ( OCRMATCHVAL < 2 )\r
+#error "PRESCALER too large or F_CPU too low"\r
+#endif\r
+\r
+volatile uint16_t timebase_tick;\r
+\r
+ISR(TIMER0_COMPA_vect)\r
+{\r
+ timebase_tick++;\r
+\r
+ key_io_callback();\r
+}\r
+\r
+void timebase_init(void)\r
+{\r
+ uint8_t sreg;\r
+\r
+ sreg=SREG;\r
+ cli();\r
+\r
+ // init Timer 0 Mode 4 - CTC with interrupt on compare-match \r
+ \r
+ TCCR0A = (1<<WGM01);\r
+#if (PRESCALER == 1024)\r
+ TCCR0B = (1<<CS02) | (1<<CS00);\r
+#else\r
+#error "PRESCALER settings not available"\r
+#endif\r
+ \r
+ OCR0A = OCRMATCHVAL; // match-value\r
+ \r
+ TCNT0 = 0; // reset timer-counter\r
+ TIFR0 = (1<<OCF0A); // clear interrupt\r
+ TIMSK0 = (1<<OCIE0A); // enabled matchA interrupt\r
+\r
+ timebase_tick = 0;\r
+\r
+ SREG=sreg;\r
+}\r
+\r
+uint16_t timebase_get_tick(void)\r
+{\r
+ uint8_t sreg;\r
+ uint16_t res;\r
+\r
+ sreg = SREG;\r
+ cli();\r
+\r
+ res = timebase_tick;\r
+\r
+ SREG=sreg;\r
+\r
+ return res;\r
+}\r