diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2007-07-06 21:36:32 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2007-07-06 21:36:32 +0000 |
commit | 4ae87c8b8ab7ddbd286f5288adaddcaf0a187e31 (patch) | |
tree | d3880b9f53a5c38d2211a1b8812724bf96913c4c /firmware/timer.c | |
parent | cbed7a2cd21bb2715b39ebcd3015147a9d7ff3c2 (diff) | |
download | rockbox-4ae87c8b8ab7ddbd286f5288adaddcaf0a187e31.tar.gz rockbox-4ae87c8b8ab7ddbd286f5288adaddcaf0a187e31.zip |
Gigabeat: Add timer functionality. Rework tick timer setup to be exactly 100Hz. Metronome should work now but some pcm changes are needed to have faster tocks work correctly (in the works).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13806 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/timer.c')
-rw-r--r-- | firmware/timer.c | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/firmware/timer.c b/firmware/timer.c index ca23cb890c..1ac16b697a 100644 --- a/firmware/timer.c +++ b/firmware/timer.c | |||
@@ -22,10 +22,11 @@ | |||
22 | #include "cpu.h" | 22 | #include "cpu.h" |
23 | #include "system.h" | 23 | #include "system.h" |
24 | #include "timer.h" | 24 | #include "timer.h" |
25 | #include "logf.h" | ||
25 | 26 | ||
26 | static int timer_prio = -1; | 27 | static int timer_prio = -1; |
27 | static void (*pfn_timer)(void) = NULL; /* timer callback */ | 28 | void (*pfn_timer)(void) = NULL; /* timer callback */ |
28 | static void (*pfn_unregister)(void) = NULL; /* unregister callback */ | 29 | void (*pfn_unregister)(void) = NULL; /* unregister callback */ |
29 | #ifdef CPU_COLDFIRE | 30 | #ifdef CPU_COLDFIRE |
30 | static int base_prescale; | 31 | static int base_prescale; |
31 | #elif defined CPU_PP || CONFIG_CPU == PNX0101 | 32 | #elif defined CPU_PP || CONFIG_CPU == PNX0101 |
@@ -123,9 +124,9 @@ static bool timer_set(long cycles, bool start) | |||
123 | } | 124 | } |
124 | else | 125 | else |
125 | cycles_new = cycles; | 126 | cycles_new = cycles; |
126 | #endif | ||
127 | 127 | ||
128 | #if CONFIG_CPU == SH7034 | 128 | return true; |
129 | #elif CONFIG_CPU == SH7034 | ||
129 | if (prescale > 8) | 130 | if (prescale > 8) |
130 | return false; | 131 | return false; |
131 | 132 | ||
@@ -150,6 +151,7 @@ static bool timer_set(long cycles, bool start) | |||
150 | TCNT4 = 0; | 151 | TCNT4 = 0; |
151 | and_b(~0x01, &TSR4); /* clear an eventual interrupt */ | 152 | and_b(~0x01, &TSR4); /* clear an eventual interrupt */ |
152 | 153 | ||
154 | return true; | ||
153 | #elif defined CPU_COLDFIRE | 155 | #elif defined CPU_COLDFIRE |
154 | if (prescale > 4096/CPUFREQ_MAX_MULT) | 156 | if (prescale > 4096/CPUFREQ_MAX_MULT) |
155 | return false; | 157 | return false; |
@@ -186,6 +188,8 @@ static bool timer_set(long cycles, bool start) | |||
186 | if (start || (TCN1 >= TRR1)) | 188 | if (start || (TCN1 >= TRR1)) |
187 | TCN1 = 0; /* reset the timer */ | 189 | TCN1 = 0; /* reset the timer */ |
188 | TER1 = 0xff; /* clear all events */ | 190 | TER1 = 0xff; /* clear all events */ |
191 | |||
192 | return true; | ||
189 | #elif defined(CPU_PP) | 193 | #elif defined(CPU_PP) |
190 | if (cycles > 0x20000000 || cycles < 2) | 194 | if (cycles > 0x20000000 || cycles < 2) |
191 | return false; | 195 | return false; |
@@ -203,11 +207,10 @@ static bool timer_set(long cycles, bool start) | |||
203 | else | 207 | else |
204 | cycles_new = cycles; | 208 | cycles_new = cycles; |
205 | 209 | ||
206 | #elif CONFIG_CPU == S3C2440 /* TODO: Implement for the Gigabeat */ | ||
207 | (void)start; | ||
208 | (void)cycles; | ||
209 | #endif /* CONFIG_CPU */ | ||
210 | return true; | 210 | return true; |
211 | #elif CONFIG_CPU == S3C2440 | ||
212 | return __TIMER_SET(cycles, start); | ||
213 | #endif /* CONFIG_CPU */ | ||
211 | } | 214 | } |
212 | 215 | ||
213 | #ifdef CPU_COLDFIRE | 216 | #ifdef CPU_COLDFIRE |
@@ -236,16 +239,9 @@ bool timer_register(int reg_prio, void (*unregister_callback)(void), | |||
236 | if (reg_prio <= timer_prio || cycles == 0) | 239 | if (reg_prio <= timer_prio || cycles == 0) |
237 | return false; | 240 | return false; |
238 | 241 | ||
239 | #if defined(CPU_PP) || (CONFIG_CPU==PNX0101) || (CONFIG_CPU==S3C2440) | ||
240 | /* TODO: Implement for PortalPlayer and iFP (if possible) */ | ||
241 | (void)int_prio; | ||
242 | #endif | ||
243 | |||
244 | #if CONFIG_CPU == SH7034 | 242 | #if CONFIG_CPU == SH7034 |
245 | if (int_prio < 1 || int_prio > 15) | 243 | if (int_prio < 1 || int_prio > 15) |
246 | return false; | 244 | return false; |
247 | #elif defined CPU_COLDFIRE | ||
248 | (void)int_prio; | ||
249 | #endif | 245 | #endif |
250 | 246 | ||
251 | if (!timer_set(cycles, true)) | 247 | if (!timer_set(cycles, true)) |
@@ -258,18 +254,31 @@ bool timer_register(int reg_prio, void (*unregister_callback)(void), | |||
258 | #if CONFIG_CPU == SH7034 | 254 | #if CONFIG_CPU == SH7034 |
259 | IPRD = (IPRD & 0xFF0F) | int_prio << 4; /* interrupt priority */ | 255 | IPRD = (IPRD & 0xFF0F) | int_prio << 4; /* interrupt priority */ |
260 | or_b(0x10, &TSTR); /* start timer 4 */ | 256 | or_b(0x10, &TSTR); /* start timer 4 */ |
257 | return true; | ||
261 | #elif defined CPU_COLDFIRE | 258 | #elif defined CPU_COLDFIRE |
262 | ICR2 = 0x90; /* interrupt on level 4.0 */ | 259 | ICR2 = 0x90; /* interrupt on level 4.0 */ |
263 | and_l(~(1<<10), &IMR); | 260 | and_l(~(1<<10), &IMR); |
264 | TMR1 |= 1; /* start timer */ | 261 | TMR1 |= 1; /* start timer */ |
262 | return true; | ||
265 | #elif defined(CPU_PP) | 263 | #elif defined(CPU_PP) |
266 | /* unmask interrupt source */ | 264 | /* unmask interrupt source */ |
267 | CPU_INT_EN = TIMER2_MASK; | 265 | CPU_INT_EN = TIMER2_MASK; |
266 | return true; | ||
268 | #elif CONFIG_CPU == PNX0101 | 267 | #elif CONFIG_CPU == PNX0101 |
269 | irq_set_int_handler(IRQ_TIMER1, TIMER1_ISR); | 268 | irq_set_int_handler(IRQ_TIMER1, TIMER1_ISR); |
270 | irq_enable_int(IRQ_TIMER1); | 269 | irq_enable_int(IRQ_TIMER1); |
271 | #endif | ||
272 | return true; | 270 | return true; |
271 | #elif CONFIG_CPU == S3C2440 | ||
272 | return __TIMER_REGISTER(reg_prio, unregister_callback, cycles, | ||
273 | int_prio, timer_callback); | ||
274 | #endif | ||
275 | /* Cover for targets that don't use all these */ | ||
276 | (void)reg_prio; | ||
277 | (void)unregister_callback; | ||
278 | (void)cycles; | ||
279 | /* TODO: Implement for PortalPlayer and iFP (if possible) */ | ||
280 | (void)int_prio; | ||
281 | (void)timer_callback; | ||
273 | } | 282 | } |
274 | 283 | ||
275 | bool timer_set_period(long cycles) | 284 | bool timer_set_period(long cycles) |
@@ -291,6 +300,8 @@ void timer_unregister(void) | |||
291 | #elif CONFIG_CPU == PNX0101 | 300 | #elif CONFIG_CPU == PNX0101 |
292 | TIMER1.ctrl &= ~0x80; /* disable timer 1 */ | 301 | TIMER1.ctrl &= ~0x80; /* disable timer 1 */ |
293 | irq_disable_int(5); | 302 | irq_disable_int(5); |
303 | #elif CONFIG_CPU == S3C2440 | ||
304 | __TIMER_UNREGISTER(); | ||
294 | #endif | 305 | #endif |
295 | pfn_timer = NULL; | 306 | pfn_timer = NULL; |
296 | pfn_unregister = NULL; | 307 | pfn_unregister = NULL; |