1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Jens Arnold
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
29 static int base_prescale
;
31 void TIMER1(void) __attribute__ ((interrupt_handler
));
34 if (pfn_timer
!= NULL
)
36 TER1
= 0xff; /* clear all events */
39 bool timer_set(long cycles
, bool start
)
41 int phi
= 0; /* bits for the prescaler */
44 while (cycles
> 0x10000)
50 if (prescale
> 4096/CPUFREQ_MAX_MULT
)
53 if (prescale
> 256/CPUFREQ_MAX_MULT
)
55 phi
= 0x05; /* prescale sysclk/16, timer enabled */
59 phi
= 0x03; /* prescale sysclk, timer enabled */
61 base_prescale
= prescale
;
62 prescale
*= (cpu_frequency
/ CPU_FREQ
);
66 if (pfn_unregister
!= NULL
)
69 pfn_unregister
= NULL
;
71 phi
&= ~1; /* timer disabled at start */
73 /* If it is already enabled, writing a 0 to the RST bit will clear
74 the register, so we clear RST explicitly before writing the real
79 /* We are using timer 1 */
80 TMR1
= 0x0018 | (unsigned short)phi
| ((unsigned short)(prescale
- 1) << 8);
81 TRR1
= (unsigned short)(cycles
- 1);
82 if (start
|| (TCN1
>= TRR1
))
83 TCN1
= 0; /* reset the timer */
84 TER1
= 0xff; /* clear all events */
89 bool timer_start(void)
91 ICR2
= 0x90; /* interrupt on level 4.0 */
92 and_l(~(1<<10), &IMR
);
93 TMR1
|= 1; /* start timer */
99 TMR1
= 0; /* disable timer 1 */
100 or_l((1<<10), &IMR
); /* disable interrupt */
103 void timers_adjust_prescale(int multiplier
, bool enable_irq
)
106 TMR0
= (TMR0
& 0x00ef)
107 | ((unsigned short)(multiplier
- 1) << 8)
108 | (enable_irq
? 0x10 : 0);
113 int prescale
= base_prescale
* multiplier
;
114 TMR1
= (TMR1
& 0x00ef)
115 | ((unsigned short)(prescale
- 1) << 8)
116 | (enable_irq
? 0x10 : 0);