#include "timer.h" #include "interrupt.h" #include "uart.h" #define TIMER0BASE 0xE0004000 #define TIMER1BASE 0xE0008000 #define IR 0x00 #define TCR 0x04 #define TC 0x08 #define PR 0x0c #define PC 0x10 #define MCR 0x14 #define MR0 0x18 #define MR1 0x1C #define MR2 0x20 #define MR3 0x24 #define CCR 0x28 #define CR0 0x2C #define CR1 0x30 #define CR2 0x34 #define CR3 0x38 #define EMR 0x3C #define CTCR 0x70 #define PWM 0x74 #define TREG(x) (((volatile unsigned char *)TIMER0BASE)[x]) #define TWREG(x) (((volatile unsigned int *)TIMER0BASE)[(x)/sizeof(unsigned int)]) #define TCR_ENABLE (1<<0) #define TCR_RESET (1<<1) #define MR0I (1<<0) #define MR0R (1<<1) #define MR0S (1<<2) #define MR1I (1<<3) #define MR1R (1<<4) #define MR1S (1<<5) #define MR2I (1<<6) #define MR2R (1<<7) #define MR2S (1<<8) #define MR3I (1<<9) #define MR3R (1<<10) #define MR3S (1<<11) void __attribute__((interrupt("IRQ"))) timer_interrupt_handler(void); void init_timer(void) { TREG(TCR) = TCR_ENABLE | TCR_RESET; TREG(CTCR) = 0; /* Use PCLK */ TWREG(TC) = 0; TWREG(PR) = TIMER_PRESCALE ; TWREG(PC) = 0; TREG(TCR) = TCR_ENABLE; } unsigned int timer_read(void) { return TWREG(TC); } void timer_delay_clocks(unsigned int clocks) { signed int time = TWREG(TC) + clocks; while (((signed int) (time-TWREG(TC))) > 0); } void timer_set_period(unsigned int period) { TWREG(MR0) = period; TWREG(MCR) = MR0I | MR0R; interrupt_register(TIMER0, timer_interrupt_handler); } void __attribute__((interrupt("IRQ"))) timer_interrupt_handler(void) { unsigned int ir; ir = TREG(IR); TREG(IR) = ir; if (ir & (1<<0)) { /* Match channel 0 */ putstr(" *timer0* "); } interrupt_clear(); }