The unified diff between revisions [d8ed90db..] and [253c6510..] is displayed below. It can also be downloaded as a raw diff.
This diff has been restricted to the following files: 'timer.c'
# # old_revision [d8ed90db2d4284a290224447c40a0d9cef3fbc31] # new_revision [253c65100e2208e0b8c93178896f5aab89e4ec0b] # # add_file "timer.c" # content [9ef2a6c50a8a227103c6c98477c1ce62327a0977] # ============================================================ --- /dev/null +++ timer.c 9ef2a6c50a8a227103c6c98477c1ce62327a0977 @@ -0,0 +1,101 @@ +#include "timer.h" +#include "interrupt.h" +#include "uart.h" +#include "event.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 timer_event_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; + event_register(EVENT_TIMER, timer_event_handler); +} + +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* "); + } + + event_set(EVENT_TIMER); + + interrupt_clear(); +} + +void timer_event_handler(void) +{ + putstr(" *t0event* "); +}