You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
1.7 KiB
91 lines
1.7 KiB
#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(); |
|
} |
|
|
|
|