initial commit
[gbajam21] / src / timer.c
1 #include "intr.h"
2 #include "timer.h"
3
4 #define F_CLK   16780000
5 /* clock is 16.78MHz
6  * - no prescale: 59.595ns
7  * - prescale 64: 3.814us
8  * - prescale 256: 15.256us
9  * - prescale 1024: 61.025us
10  */
11
12 static void timer_intr(void);
13
14 void init_timer(int tm, unsigned long rate_hz, void (*intr)(void))
15 {
16         static const unsigned long clk[] = {F_CLK, F_CLK / 64, F_CLK / 256, F_CLK / 1024};
17         unsigned long count;
18         int pscl = 0;
19
20         do {
21                 count = clk[pscl] / rate_hz;
22         } while(count >= 65536 && ++pscl < 4);
23
24         if(pscl >= 4) return;   /* impossible rate */
25
26         REG_TMCNT_H(tm) = 0;
27         REG_TMCNT_L(tm) = 65536 - count;
28         if(intr) {
29                 interrupt(INTR_TIMER0 + tm, intr);
30                 unmask(INTR_TIMER0 + tm);
31                 REG_TMCNT_H(tm) = TMCNT_IE;
32         }
33         REG_TMCNT_H(tm) |= TMCNT_EN | pscl;
34 }
35
36 void reset_msec_timer(void)
37 {
38         REG_TM0CNT_H &= ~TMCNT_EN;
39         interrupt(INTR_TIMER0, timer_intr);
40         timer_msec = 0;
41         REG_TM0CNT_L = 65535 - 16779;
42         REG_TM0CNT_H |= TMCNT_IE | TMCNT_EN;
43         unmask(INTR_TIMER0);
44 }
45
46 void delay(unsigned long ms)
47 {
48         unsigned long end = timer_msec + ms;
49         while(timer_msec < end);
50 }
51
52 static void timer_intr(void)
53 {
54         timer_msec++;
55 }