diff options
| author | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2009-06-03 22:52:54 +0000 |
|---|---|---|
| committer | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2009-06-03 22:52:54 +0000 |
| commit | 398e1059c50a659b08b8a7bf997c24ee0217b8ee (patch) | |
| tree | 8ab084975379557ea61fb0315e13f0232693556d | |
| parent | 63bc7c9009045c7280e1b59577fca7e43c09112e (diff) | |
| download | rockbox-398e1059c50a659b08b8a7bf997c24ee0217b8ee.zip rockbox-398e1059c50a659b08b8a7bf997c24ee0217b8ee.tar.gz rockbox-398e1059c50a659b08b8a7bf997c24ee0217b8ee.tar.bz2 rockbox-398e1059c50a659b08b8a7bf997c24ee0217b8ee.tar.xz | |
Ingenic Jz4740: should fix timer (thanks to Rafaël Carré)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21184 a1c6a512-1295-4272-9138-f99709370657
| -rw-r--r-- | firmware/target/mips/ingenic_jz47xx/timer-jz4740.c | 50 | ||||
| -rw-r--r-- | firmware/target/mips/ingenic_jz47xx/timer-target.h | 4 |
2 files changed, 27 insertions, 27 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/timer-jz4740.c b/firmware/target/mips/ingenic_jz47xx/timer-jz4740.c index 94ecc3a..54ea17a 100644 --- a/firmware/target/mips/ingenic_jz47xx/timer-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/timer-jz4740.c @@ -28,69 +28,67 @@ void TCU1(void) { __tcu_clear_full_match_flag(1); - + if (pfn_timer != NULL) pfn_timer(); } -/* TODO: figure out what cycles means */ bool __timer_set(long cycles, bool start) { - unsigned int latch, old_irq; - + unsigned int divider = cycles, prescaler_bit = 0, prescaler = 1, old_irq; + if(cycles < 1) return false; - - if (start && pfn_unregister != NULL) + + if(start && pfn_unregister != NULL) { pfn_unregister(); pfn_unregister = NULL; } - + old_irq = disable_irq_save(); - + __tcu_stop_counter(1); __tcu_disable_pwm_output(1); - + __tcu_mask_half_match_irq(1); __tcu_unmask_full_match_irq(1); - /* EXTAL clock = 12Mhz */ + /* EXTAL clock = CFG_EXTAL (12Mhz in most targets) */ __tcu_select_extalclk(1); - /* 12Mhz / 4 = 3Mhz */ - __tcu_select_clk_div4(1); - - latch = cycles; + /* Increase prescale values starting from 0 to make the cycle count fit */ + while(divider > 65535 && prescaler <= 1024) + { + prescaler >>= 2; /* 1, 4, 16, 64, 256, 1024 */ + prescaler_bit++; + divider = cycles / prescaler; + } + + REG_TCU_TCSR(1) = (REG_TCU_TCSR(1) & ~TCU_TCSR_PRESCALE_MASK) | (prescaler_bit << TCU_TCSR_PRESCALE_BIT); REG_TCU_TCNT(1) = 0; - REG_TCU_TDFR(1) = latch; - REG_TCU_TDHR(1) = latch; + REG_TCU_TDHR(1) = 0; + REG_TCU_TDFR(1) = divider; __tcu_clear_full_match_flag(1); - + system_enable_irq(IRQ_TCU1); - + restore_irq(old_irq); - + return true; } bool __timer_register(void) { - unsigned int old_irq = disable_irq_save(); - __tcu_start_counter(1); - - restore_irq(old_irq); - + return true; } void __timer_unregister(void) { unsigned int old_irq = disable_irq_save(); - __tcu_stop_counter(1); - restore_irq(old_irq); } diff --git a/firmware/target/mips/ingenic_jz47xx/timer-target.h b/firmware/target/mips/ingenic_jz47xx/timer-target.h index 202f941..40942d4 100644 --- a/firmware/target/mips/ingenic_jz47xx/timer-target.h +++ b/firmware/target/mips/ingenic_jz47xx/timer-target.h @@ -22,7 +22,9 @@ #ifndef __TIMER_H_ #define __TIMER_H_ -#define TIMER_FREQ (27000000) +#include "config.h" + +#define TIMER_FREQ (CFG_EXTAL) /* For full precision! */ bool __timer_set(long cycles, bool set); bool __timer_register(void); |