diff options
Diffstat (limited to 'firmware/target/coldfire/timer-coldfire.c')
-rw-r--r-- | firmware/target/coldfire/timer-coldfire.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/firmware/target/coldfire/timer-coldfire.c b/firmware/target/coldfire/timer-coldfire.c new file mode 100644 index 0000000000..ef9fd9ea7a --- /dev/null +++ b/firmware/target/coldfire/timer-coldfire.c | |||
@@ -0,0 +1,119 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 Jens Arnold | ||
11 | * | ||
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. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include <stdlib.h> | ||
23 | |||
24 | #include "config.h" | ||
25 | #include "system.h" | ||
26 | #include "cpu.h" | ||
27 | #include "timer.h" | ||
28 | #include "timer-target.h" | ||
29 | |||
30 | static int base_prescale; | ||
31 | |||
32 | void TIMER1(void) __attribute__ ((interrupt_handler)); | ||
33 | void TIMER1(void) | ||
34 | { | ||
35 | if (pfn_timer != NULL) | ||
36 | pfn_timer(); | ||
37 | TER1 = 0xff; /* clear all events */ | ||
38 | } | ||
39 | |||
40 | bool __timer_set(long cycles, bool start) | ||
41 | { | ||
42 | int phi = 0; /* bits for the prescaler */ | ||
43 | int prescale = 1; | ||
44 | |||
45 | while (cycles > 0x10000) | ||
46 | { | ||
47 | prescale <<= 1; | ||
48 | cycles >>= 1; | ||
49 | } | ||
50 | |||
51 | if (prescale > 4096/CPUFREQ_MAX_MULT) | ||
52 | return false; | ||
53 | |||
54 | if (prescale > 256/CPUFREQ_MAX_MULT) | ||
55 | { | ||
56 | phi = 0x05; /* prescale sysclk/16, timer enabled */ | ||
57 | prescale >>= 4; | ||
58 | } | ||
59 | else | ||
60 | phi = 0x03; /* prescale sysclk, timer enabled */ | ||
61 | |||
62 | base_prescale = prescale; | ||
63 | prescale *= (cpu_frequency / CPU_FREQ); | ||
64 | |||
65 | if (start) | ||
66 | { | ||
67 | if (pfn_unregister != NULL) | ||
68 | { | ||
69 | pfn_unregister(); | ||
70 | pfn_unregister = NULL; | ||
71 | } | ||
72 | phi &= ~1; /* timer disabled at start */ | ||
73 | |||
74 | /* If it is already enabled, writing a 0 to the RST bit will clear | ||
75 | the register, so we clear RST explicitly before writing the real | ||
76 | data. */ | ||
77 | TMR1 = 0; | ||
78 | } | ||
79 | |||
80 | /* We are using timer 1 */ | ||
81 | TMR1 = 0x0018 | (unsigned short)phi | ((unsigned short)(prescale - 1) << 8); | ||
82 | TRR1 = (unsigned short)(cycles - 1); | ||
83 | if (start || (TCN1 >= TRR1)) | ||
84 | TCN1 = 0; /* reset the timer */ | ||
85 | TER1 = 0xff; /* clear all events */ | ||
86 | |||
87 | return true; | ||
88 | } | ||
89 | |||
90 | bool __timer_start(void) | ||
91 | { | ||
92 | ICR2 = 0x90; /* interrupt on level 4.0 */ | ||
93 | and_l(~(1<<10), &IMR); | ||
94 | TMR1 |= 1; /* start timer */ | ||
95 | return true; | ||
96 | } | ||
97 | |||
98 | void __timer_stop(void) | ||
99 | { | ||
100 | TMR1 = 0; /* disable timer 1 */ | ||
101 | or_l((1<<10), &IMR); /* disable interrupt */ | ||
102 | } | ||
103 | |||
104 | void timers_adjust_prescale(int multiplier, bool enable_irq) | ||
105 | { | ||
106 | /* tick timer */ | ||
107 | TMR0 = (TMR0 & 0x00ef) | ||
108 | | ((unsigned short)(multiplier - 1) << 8) | ||
109 | | (enable_irq ? 0x10 : 0); | ||
110 | |||
111 | if (pfn_timer) | ||
112 | { | ||
113 | /* user timer */ | ||
114 | int prescale = base_prescale * multiplier; | ||
115 | TMR1 = (TMR1 & 0x00ef) | ||
116 | | ((unsigned short)(prescale - 1) << 8) | ||
117 | | (enable_irq ? 0x10 : 0); | ||
118 | } | ||
119 | } | ||