4008-04-07 Release
[avr_bc100.git] / BaseMegaFirmware / GCC / timebase.c
diff --git a/BaseMegaFirmware/GCC/timebase.c b/BaseMegaFirmware/GCC/timebase.c
new file mode 100644 (file)
index 0000000..92bf015
--- /dev/null
@@ -0,0 +1,87 @@
+// 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