From 398e1059c50a659b08b8a7bf997c24ee0217b8ee Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Wed, 3 Jun 2009 22:52:54 +0000 Subject: Ingenic Jz4740: should fix timer (thanks to Rafaël Carré) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21184 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/mips/ingenic_jz47xx/timer-jz4740.c | 50 +++++++++++----------- firmware/target/mips/ingenic_jz47xx/timer-target.h | 4 +- 2 files changed, 27 insertions(+), 27 deletions(-) (limited to 'firmware/target') diff --git a/firmware/target/mips/ingenic_jz47xx/timer-jz4740.c b/firmware/target/mips/ingenic_jz47xx/timer-jz4740.c index 94ecc3afd4..54ea17a063 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 202f941ce1..40942d4b4c 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); -- cgit v1.2.3