More interupt/timer work

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14823 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Karl Kurbjun 2007-09-22 23:17:52 +00:00
parent 7d1eeddf93
commit 67ef4500e3
8 changed files with 183 additions and 104 deletions

View file

@ -117,8 +117,9 @@ void main(void)
tsc2100_read_values(&x, &y, &z1, &z2); tsc2100_read_values(&x, &y, &z1, &z2);
printf("x: %04x y: %04x z1: %04x z2: %04x", x, y, z1, z2); printf("x: %04x y: %04x z1: %04x z2: %04x", x, y, z1, z2);
printf("tsadc: %4x", tsc2100_readreg(TSADC_PAGE, TSADC_ADDRESS)&0xffff); printf("tsadc: %4x", tsc2100_readreg(TSADC_PAGE, TSADC_ADDRESS)&0xffff);
printf("current tick: %04x", current_tick);
tsc2100_keyclick(); /* doesnt work :( */ tsc2100_keyclick(); /* doesnt work :( */
line -= 2; line -= 3;
} }
} }

View file

@ -5,7 +5,7 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id: $ * $Id$
* *
* Copyright (C) 2007 by Karl Kurbjun * Copyright (C) 2007 by Karl Kurbjun
* *
@ -30,33 +30,33 @@
#define DM320_REG(addr) (*(volatile unsigned short *)(PHY_IO_BASE + (addr))) #define DM320_REG(addr) (*(volatile unsigned short *)(PHY_IO_BASE + (addr)))
/* Timer 0-3 */ /* Timer 0-3 */
#define IO_TIMER0_TMMD 0x0000 #define IO_TIMER0_TMMD DM320_REG(0x0000)
#define IO_TIMER0_TMRSV0 0x0002 #define IO_TIMER0_TMRSV0 DM320_REG(0x0002)
#define IO_TIMER0_TMPRSCL 0x0004 #define IO_TIMER0_TMPRSCL DM320_REG(0x0004)
#define IO_TIMER0_TMDIV 0x0006 #define IO_TIMER0_TMDIV DM320_REG(0x0006)
#define IO_TIMER0_TMTRG 0x0008 #define IO_TIMER0_TMTRG DM320_REG(0x0008)
#define IO_TIMER0_TMCNT 0x000A #define IO_TIMER0_TMCNT DM320_REG(0x000A)
#define IO_TIMER1_TMMD 0x0080 #define IO_TIMER1_TMMD DM320_REG(0x0080)
#define IO_TIMER1_TMRSV0 0x0082 #define IO_TIMER1_TMRSV0 DM320_REG(0x0082)
#define IO_TIMER1_TMPRSCL 0x0084 #define IO_TIMER1_TMPRSCL DM320_REG(0x0084)
#define IO_TIMER1_TMDIV 0x0086 #define IO_TIMER1_TMDIV DM320_REG(0x0086)
#define IO_TIMER1_TMTRG 0x0088 #define IO_TIMER1_TMTRG DM320_REG(0x0088)
#define IO_TIMER1_TMCNT 0x008A #define IO_TIMER1_TMCNT DM320_REG(0x008A)
#define IO_TIMER2_TMMD 0x0100 #define IO_TIMER2_TMMD DM320_REG(0x0100)
#define IO_TIMER2_TMVDCLR 0x0102 #define IO_TIMER2_TMVDCLR DM320_REG(0x0102)
#define IO_TIMER2_TMPRSCL 0x0104 #define IO_TIMER2_TMPRSCL DM320_REG(0x0104)
#define IO_TIMER2_TMDIV 0x0106 #define IO_TIMER2_TMDIV DM320_REG(0x0106)
#define IO_TIMER2_TMTRG 0x0108 #define IO_TIMER2_TMTRG DM320_REG(0x0108)
#define IO_TIMER2_TMCNT 0x010A #define IO_TIMER2_TMCNT DM320_REG(0x010A)
#define IO_TIMER3_TMMD 0x0180 #define IO_TIMER3_TMMD DM320_REG(0x0180)
#define IO_TIMER3_TMVDCLR 0x0182 #define IO_TIMER3_TMVDCLR DM320_REG(0x0182)
#define IO_TIMER3_TMPRSCL 0x0184 #define IO_TIMER3_TMPRSCL DM320_REG(0x0184)
#define IO_TIMER3_TMDIV 0x0186 #define IO_TIMER3_TMDIV DM320_REG(0x0186)
#define IO_TIMER3_TMTRG 0x0188 #define IO_TIMER3_TMTRG DM320_REG(0x0188)
#define IO_TIMER3_TMCNT 0x018A #define IO_TIMER3_TMCNT DM320_REG(0x018A)
/* Serial 0/1 */ /* Serial 0/1 */
#define IO_SERIAL0_TX_DATA DM320_REG(0x0200) #define IO_SERIAL0_TX_DATA DM320_REG(0x0200)
@ -144,30 +144,30 @@
#define IO_SDIO_INT_STATUS 0x04D0 #define IO_SDIO_INT_STATUS 0x04D0
/* Interrupt Controller */ /* Interrupt Controller */
#define IO_INTC_FIQ0 0x0500 #define IO_INTC_FIQ0 DM320_REG(0x0500)
#define IO_INTC_FIQ1 0x0502 #define IO_INTC_FIQ1 DM320_REG(0x0502)
#define IO_INTC_FIQ2 0x0504 #define IO_INTC_FIQ2 DM320_REG(0x0504)
#define IO_INTC_IRQ0 0x0508 #define IO_INTC_IRQ0 DM320_REG(0x0508)
#define IO_INTC_IRQ1 0x050A #define IO_INTC_IRQ1 DM320_REG(0x050A)
#define IO_INTC_IRQ2 0x050C #define IO_INTC_IRQ2 DM320_REG(0x050C)
#define IO_INTC_FIQENTRY0 0x0510 #define IO_INTC_FIQENTRY0 DM320_REG(0x0510)
#define IO_INTC_FIQENTRY1 0x0512 #define IO_INTC_FIQENTRY1 DM320_REG(0x0512)
#define IO_INTC_FIQ_LOCK_ADDR0 0x0514 #define IO_INTC_FIQ_LOCK_ADDR0 DM320_REG(0x0514)
#define IO_INTC_FIQ_LOCK_ADDR1 0x0516 #define IO_INTC_FIQ_LOCK_ADDR1 DM320_REG(0x0516)
#define IO_INTC_IRQENTRY0 0x0518 #define IO_INTC_IRQENTRY0 DM320_REG(0x0518)
#define IO_INTC_IRQENTRY1 0x051A #define IO_INTC_IRQENTRY1 DM320_REG(0x051A)
#define IO_INTC_IRQ_LOCK_ADDR0 0x051C #define IO_INTC_IRQ_LOCK_ADDR0 DM320_REG(0x051C)
#define IO_INTC_IRQ_LOCK_ADDR1 0x051E #define IO_INTC_IRQ_LOCK_ADDR1 DM320_REG(0x051E)
#define IO_INTC_FISEL0 0x0520 #define IO_INTC_FISEL0 DM320_REG(0x0520)
#define IO_INTC_FISEL1 0x0522 #define IO_INTC_FISEL1 DM320_REG(0x0522)
#define IO_INTC_FISEL2 0x0524 #define IO_INTC_FISEL2 DM320_REG(0x0524)
#define IO_INTC_EINT0 0x0528 #define IO_INTC_EINT0 DM320_REG(0x0528)
#define IO_INTC_EINT1 0x052A #define IO_INTC_EINT1 DM320_REG(0x052A)
#define IO_INTC_EINT2 0x052C #define IO_INTC_EINT2 DM320_REG(0x052C)
#define IO_INTC_RAW 0x0530 #define IO_INTC_RAW DM320_REG(0x0530)
#define IO_INTC_ENTRY_TBA0 0x0538 #define IO_INTC_ENTRY_TBA0 DM320_REG(0x0538)
#define IO_INTC_ENTRY_TBA1 0x053A #define IO_INTC_ENTRY_TBA1 DM320_REG(0x053A)
#define IO_INTC_PRIORITY0 0x0540 #define IO_INTC_PRIORITY0 DM320_REG(0x0540)
#define IO_INTC_PRIORITY1 0x0542 #define IO_INTC_PRIORITY1 0x0542
#define IO_INTC_PRIORITY2 0x0544 #define IO_INTC_PRIORITY2 0x0544
#define IO_INTC_PRIORITY3 0x0546 #define IO_INTC_PRIORITY3 0x0546
@ -702,4 +702,42 @@
#define NR_IRQS 46 #define NR_IRQS 46
/* Taken from linux/include/asm-arm/arch-integrator/timex.h
*
* Copyright (C) 1999 ARM Limited
*/
#define CONFIG_TIMER1_TMPRSCL 0x000A
#define CLOCK_TICK_RATE (CPUFREQ_MAX / CONFIG_TIMER1_TMPRSCL)
#define CONFIG_TIMER1_TMDIV (unsigned short)(CLOCK_TICK_RATE / HZ)
#define CONFIG_TIMER0_TMMD_STOP 0x0000
#define CONFIG_TIMER0_TMMD_ONE_SHOT 0x0001
#define CONFIG_TIMER0_TMMD_FREE_RUN 0x0002
#define CONFIG_TIMER1_TMMD_STOP 0x0000
#define CONFIG_TIMER1_TMMD_ONE_SHOT 0x0001
#define CONFIG_TIMER1_TMMD_FREE_RUN 0x0002
#define CONFIG_TIMER2_TMMD_STOP 0x0000
#define CONFIG_TIMER2_TMMD_ONE_SHOT 0x0001
#define CONFIG_TIMER2_TMMD_FREE_RUN 0x0002
#define CONFIG_TIMER2_TMMD_CCD_SHUTTER 0x0100
#define CONFIG_TIMER2_TMMD_CCD_STROBE 0x0200
#define CONFIG_TIMER2_TMMD_POLARITY 0x0400
#define CONFIG_TIMER2_TMMD_TRG_SELECT 0x0800
#define CONFIG_TIMER2_TMMD_TRG_READY 0x1000
#define CONFIG_TIMER2_TMMD_SIGNAL 0x2000
#define CONFIG_TIMER3_TMMD_STOP 0x0000
#define CONFIG_TIMER3_TMMD_ONE_SHOT 0x0001
#define CONFIG_TIMER3_TMMD_FREE_RUN 0x0002
#define CONFIG_TIMER3_TMMD_CCD_SHUTTER 0x0100
#define CONFIG_TIMER3_TMMD_CCD_STROBE 0x0200
#define CONFIG_TIMER3_TMMD_POLARITY 0x0400
#define CONFIG_TIMER3_TMMD_TRG_SELECT 0x0800
#define CONFIG_TIMER3_TMMD_TRG_READY 0x1000
#define CONFIG_TIMER3_TMMD_SIGNAL 0x2000
#endif #endif

View file

@ -27,7 +27,19 @@ extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
void tick_start(unsigned int interval_in_ms) void tick_start(unsigned int interval_in_ms)
{ {
(void)interval_in_ms; IO_TIMER1_TMMD = CONFIG_TIMER1_TMMD_STOP;
/* Setup the Prescalar */
IO_TIMER1_TMPRSCL = CONFIG_TIMER1_TMPRSCL;
/* Setup the Divisor */
IO_TIMER1_TMDIV = CONFIG_TIMER1_TMDIV;
/* Turn Timer1 to Free Run mode */
IO_TIMER1_TMMD = CONFIG_TIMER1_TMMD_FREE_RUN;
/* Enable the interrupt */
IO_INTC_EINT0 |= 1<<IRQ_TIMER1;
} }
void TIMER4(void) void TIMER4(void)
@ -45,4 +57,5 @@ void TIMER4(void)
current_tick++; current_tick++;
IO_INTC_IRQ0 |= 1<<IRQ_TIMER1;
} }

View file

@ -95,7 +95,7 @@ static const char * const irqname[] =
static void UIRQ(void) static void UIRQ(void)
{ {
unsigned int offset = inw(IO_INTC_IRQENTRY0); unsigned int offset = IO_INTC_IRQENTRY0;
panicf("Unhandled IRQ %02X: %s", offset, irqname[offset]); panicf("Unhandled IRQ %02X: %s", offset, irqname[offset]);
} }
@ -105,7 +105,7 @@ void irq_handler(void)
/* /*
* Based on: linux/arch/arm/kernel/entry-armv.S and system-meg-fx.c * Based on: linux/arch/arm/kernel/entry-armv.S and system-meg-fx.c
*/ */
printf("INTERUPT!");
asm volatile ( asm volatile (
"sub lr, lr, #4 \r\n" "sub lr, lr, #4 \r\n"
"stmfd sp!, {r0-r3, ip, lr} \r\n" "stmfd sp!, {r0-r3, ip, lr} \r\n"
@ -149,23 +149,23 @@ void system_init(void)
/* taken from linux/arch/arm/mach-itdm320-20/irq.c */ /* taken from linux/arch/arm/mach-itdm320-20/irq.c */
/* Clearing all FIQs and IRQs. */ /* Clearing all FIQs and IRQs. */
outw(0xFFFF, IO_INTC_IRQ0); IO_INTC_IRQ0 = 0xFFFF;
outw(0xFFFF, IO_INTC_IRQ1); IO_INTC_IRQ1 = 0xFFFF;
outw(0xFFFF, IO_INTC_IRQ2); IO_INTC_IRQ2 = 0xFFFF;
outw(0xFFFF, IO_INTC_FIQ0); IO_INTC_FIQ0 = 0xFFFF;
outw(0xFFFF, IO_INTC_FIQ1); IO_INTC_FIQ1 = 0xFFFF;
outw(0xFFFF, IO_INTC_FIQ2); IO_INTC_FIQ2 = 0xFFFF;
/* Masking all Interrupts. */ /* Masking all Interrupts. */
outw(0, IO_INTC_EINT0); IO_INTC_EINT0 = 0;
outw(0, IO_INTC_EINT1); IO_INTC_EINT1 = 0;
outw(0, IO_INTC_EINT2); IO_INTC_EINT2 = 0;
/* Setting INTC to all IRQs. */ /* Setting INTC to all IRQs. */
outw(0, IO_INTC_FISEL0); IO_INTC_FISEL0 = 0;
outw(0, IO_INTC_FISEL1); IO_INTC_FISEL1 = 0;
outw(0, IO_INTC_FISEL2); IO_INTC_FISEL2 = 0;
} }
int system_memory_guard(int newmode) int system_memory_guard(int newmode)

View file

@ -0,0 +1,32 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 by Karl Kurbjun
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef SYSTEM_TARGET_H
#define SYSTEM_TARGET_H
#include "system-arm.h"
#define CPUFREQ_SLEEP 32768
#define CPUFREQ_DEFAULT 24000000
#define CPUFREQ_NORMAL 30000000
#define CPUFREQ_MAX 80000000
#define inw(p) (*((volatile unsigned short*)((p) + PHY_IO_BASE)))
#define outw(v,p) (*((volatile unsigned short*)((p) + PHY_IO_BASE)) = (v))
#endif /* SYSTEM_TARGET_H */

View file

@ -29,59 +29,55 @@ void TIMER0(void)
{ {
if (pfn_timer != NULL) if (pfn_timer != NULL)
pfn_timer(); pfn_timer();
IO_INTC_IRQ0 |= 1<<IRQ_TIMER0;
} }
static void stop_timer(void) static void stop_timer(void)
{ {
IO_INTC_EINT0 &= ~(1<<IRQ_TIMER0);
IO_INTC_IRQ0 |= 1<<IRQ_TIMER0;
IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_STOP;
} }
bool __timer_set(long cycles, bool start) bool __timer_set(long cycles, bool start)
{ {
int oldlevel;
unsigned int divider;
/* taken from linux/arch/arm/mach-itdm320-20/time.c and timer-meg-fx.c */ /* taken from linux/arch/arm/mach-itdm320-20/time.c and timer-meg-fx.c */
/* Turn off all timers */ /* Turn off all timers */
/* outw(CONFIG_TIMER0_TMMD_STOP, IO_TIMER0_TMMD); IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_STOP;
outw(CONFIG_TIMER1_TMMD_STOP, IO_TIMER1_TMMD); IO_TIMER1_TMMD = CONFIG_TIMER1_TMMD_STOP;
outw(CONFIG_TIMER2_TMMD_STOP, IO_TIMER2_TMMD); IO_TIMER2_TMMD = CONFIG_TIMER2_TMMD_STOP;
outw(CONFIG_TIMER3_TMMD_STOP, IO_TIMER3_TMMD); IO_TIMER3_TMMD = CONFIG_TIMER3_TMMD_STOP;
*/
/* Turn Timer0 to Free Run mode */
// outw(CONFIG_TIMER0_TMMD_FREE_RUN, IO_TIMER0_TMMD);
bool retval = false;
/* Find the minimum factor that puts the counter in range 1-65535 */ /* Find the minimum factor that puts the counter in range 1-65535 */
unsigned int prescaler = (cycles + 65534) / 65535; unsigned int prescaler = (cycles + 65534) / 65535;
/* Test this by writing 1's to registers to see how many bits we have */ /* Test this by writing 1's to registers to see how many bits we have */
/* Maximum divider setting is x / 1024 / 65536 = x / 67108864 */ /* Maximum divider setting is x / 1024 / 65536 = x / 67108864 */
if (start && pfn_unregister != NULL)
{ {
int oldlevel; pfn_unregister();
unsigned int divider; pfn_unregister = NULL;
if (start && pfn_unregister != NULL)
{
pfn_unregister();
pfn_unregister = NULL;
}
oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
/* Max prescale is 1023+1 */
for (divider = 0; prescaler > 1024; prescaler >>= 1, divider++);
/* Setup the Prescalar */
outw(prescaler, IO_TIMER0_TMPRSCL);
/* Setup the Divisor */
outw(divider, IO_TIMER0_TMDIV);
set_irq_level(oldlevel);
retval = true;
} }
return retval; oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
/* Max prescale is 1023+1 */
for (divider = 0; prescaler > 1024; prescaler >>= 1, divider++);
/* Setup the Prescalar */
IO_TIMER0_TMPRSCL = prescaler;
/* Setup the Divisor */
IO_TIMER0_TMDIV = divider;
set_irq_level(oldlevel);
return true;
} }
bool __timer_register(void) bool __timer_register(void)
@ -93,7 +89,9 @@ bool __timer_register(void)
stop_timer(); stop_timer();
/* Turn Timer0 to Free Run mode */ /* Turn Timer0 to Free Run mode */
outw(0x0002, IO_TIMER0_TMMD); IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_FREE_RUN;
IO_INTC_EINT0 |= 1<<IRQ_TIMER0;
set_interrupt_status(oldstatus, IRQ_FIQ_STATUS); set_interrupt_status(oldstatus, IRQ_FIQ_STATUS);

View file

@ -40,7 +40,7 @@ void tick_start(unsigned int interval_in_ms)
INTMSK &= ~TIMER4_MASK; INTMSK &= ~TIMER4_MASK;
} }
void TIMER4(void) void TIMER1(void)
{ {
int i; int i;

View file

@ -91,10 +91,7 @@ static inline void flush_icache(void)
} }
#endif /* CONFIG_CPU */ #endif /* CONFIG_CPU */
#else /* CPU_CONFIG == DM320 */ #else
#define inw(p) (*((volatile unsigned short*)((p) + PHY_IO_BASE)))
#define outw(v,p) (*((volatile unsigned short*)((p) + PHY_IO_BASE)) = (v))
#endif #endif