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);
printf("x: %04x y: %04x z1: %04x z2: %04x", x, y, z1, z2);
printf("tsadc: %4x", tsc2100_readreg(TSADC_PAGE, TSADC_ADDRESS)&0xffff);
printf("current tick: %04x", current_tick);
tsc2100_keyclick(); /* doesnt work :( */
line -= 2;
line -= 3;
}
}

View file

@ -5,7 +5,7 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id: $
* $Id$
*
* Copyright (C) 2007 by Karl Kurbjun
*
@ -30,33 +30,33 @@
#define DM320_REG(addr) (*(volatile unsigned short *)(PHY_IO_BASE + (addr)))
/* Timer 0-3 */
#define IO_TIMER0_TMMD 0x0000
#define IO_TIMER0_TMRSV0 0x0002
#define IO_TIMER0_TMPRSCL 0x0004
#define IO_TIMER0_TMDIV 0x0006
#define IO_TIMER0_TMTRG 0x0008
#define IO_TIMER0_TMCNT 0x000A
#define IO_TIMER0_TMMD DM320_REG(0x0000)
#define IO_TIMER0_TMRSV0 DM320_REG(0x0002)
#define IO_TIMER0_TMPRSCL DM320_REG(0x0004)
#define IO_TIMER0_TMDIV DM320_REG(0x0006)
#define IO_TIMER0_TMTRG DM320_REG(0x0008)
#define IO_TIMER0_TMCNT DM320_REG(0x000A)
#define IO_TIMER1_TMMD 0x0080
#define IO_TIMER1_TMRSV0 0x0082
#define IO_TIMER1_TMPRSCL 0x0084
#define IO_TIMER1_TMDIV 0x0086
#define IO_TIMER1_TMTRG 0x0088
#define IO_TIMER1_TMCNT 0x008A
#define IO_TIMER1_TMMD DM320_REG(0x0080)
#define IO_TIMER1_TMRSV0 DM320_REG(0x0082)
#define IO_TIMER1_TMPRSCL DM320_REG(0x0084)
#define IO_TIMER1_TMDIV DM320_REG(0x0086)
#define IO_TIMER1_TMTRG DM320_REG(0x0088)
#define IO_TIMER1_TMCNT DM320_REG(0x008A)
#define IO_TIMER2_TMMD 0x0100
#define IO_TIMER2_TMVDCLR 0x0102
#define IO_TIMER2_TMPRSCL 0x0104
#define IO_TIMER2_TMDIV 0x0106
#define IO_TIMER2_TMTRG 0x0108
#define IO_TIMER2_TMCNT 0x010A
#define IO_TIMER2_TMMD DM320_REG(0x0100)
#define IO_TIMER2_TMVDCLR DM320_REG(0x0102)
#define IO_TIMER2_TMPRSCL DM320_REG(0x0104)
#define IO_TIMER2_TMDIV DM320_REG(0x0106)
#define IO_TIMER2_TMTRG DM320_REG(0x0108)
#define IO_TIMER2_TMCNT DM320_REG(0x010A)
#define IO_TIMER3_TMMD 0x0180
#define IO_TIMER3_TMVDCLR 0x0182
#define IO_TIMER3_TMPRSCL 0x0184
#define IO_TIMER3_TMDIV 0x0186
#define IO_TIMER3_TMTRG 0x0188
#define IO_TIMER3_TMCNT 0x018A
#define IO_TIMER3_TMMD DM320_REG(0x0180)
#define IO_TIMER3_TMVDCLR DM320_REG(0x0182)
#define IO_TIMER3_TMPRSCL DM320_REG(0x0184)
#define IO_TIMER3_TMDIV DM320_REG(0x0186)
#define IO_TIMER3_TMTRG DM320_REG(0x0188)
#define IO_TIMER3_TMCNT DM320_REG(0x018A)
/* Serial 0/1 */
#define IO_SERIAL0_TX_DATA DM320_REG(0x0200)
@ -144,30 +144,30 @@
#define IO_SDIO_INT_STATUS 0x04D0
/* Interrupt Controller */
#define IO_INTC_FIQ0 0x0500
#define IO_INTC_FIQ1 0x0502
#define IO_INTC_FIQ2 0x0504
#define IO_INTC_IRQ0 0x0508
#define IO_INTC_IRQ1 0x050A
#define IO_INTC_IRQ2 0x050C
#define IO_INTC_FIQENTRY0 0x0510
#define IO_INTC_FIQENTRY1 0x0512
#define IO_INTC_FIQ_LOCK_ADDR0 0x0514
#define IO_INTC_FIQ_LOCK_ADDR1 0x0516
#define IO_INTC_IRQENTRY0 0x0518
#define IO_INTC_IRQENTRY1 0x051A
#define IO_INTC_IRQ_LOCK_ADDR0 0x051C
#define IO_INTC_IRQ_LOCK_ADDR1 0x051E
#define IO_INTC_FISEL0 0x0520
#define IO_INTC_FISEL1 0x0522
#define IO_INTC_FISEL2 0x0524
#define IO_INTC_EINT0 0x0528
#define IO_INTC_EINT1 0x052A
#define IO_INTC_EINT2 0x052C
#define IO_INTC_RAW 0x0530
#define IO_INTC_ENTRY_TBA0 0x0538
#define IO_INTC_ENTRY_TBA1 0x053A
#define IO_INTC_PRIORITY0 0x0540
#define IO_INTC_FIQ0 DM320_REG(0x0500)
#define IO_INTC_FIQ1 DM320_REG(0x0502)
#define IO_INTC_FIQ2 DM320_REG(0x0504)
#define IO_INTC_IRQ0 DM320_REG(0x0508)
#define IO_INTC_IRQ1 DM320_REG(0x050A)
#define IO_INTC_IRQ2 DM320_REG(0x050C)
#define IO_INTC_FIQENTRY0 DM320_REG(0x0510)
#define IO_INTC_FIQENTRY1 DM320_REG(0x0512)
#define IO_INTC_FIQ_LOCK_ADDR0 DM320_REG(0x0514)
#define IO_INTC_FIQ_LOCK_ADDR1 DM320_REG(0x0516)
#define IO_INTC_IRQENTRY0 DM320_REG(0x0518)
#define IO_INTC_IRQENTRY1 DM320_REG(0x051A)
#define IO_INTC_IRQ_LOCK_ADDR0 DM320_REG(0x051C)
#define IO_INTC_IRQ_LOCK_ADDR1 DM320_REG(0x051E)
#define IO_INTC_FISEL0 DM320_REG(0x0520)
#define IO_INTC_FISEL1 DM320_REG(0x0522)
#define IO_INTC_FISEL2 DM320_REG(0x0524)
#define IO_INTC_EINT0 DM320_REG(0x0528)
#define IO_INTC_EINT1 DM320_REG(0x052A)
#define IO_INTC_EINT2 DM320_REG(0x052C)
#define IO_INTC_RAW DM320_REG(0x0530)
#define IO_INTC_ENTRY_TBA0 DM320_REG(0x0538)
#define IO_INTC_ENTRY_TBA1 DM320_REG(0x053A)
#define IO_INTC_PRIORITY0 DM320_REG(0x0540)
#define IO_INTC_PRIORITY1 0x0542
#define IO_INTC_PRIORITY2 0x0544
#define IO_INTC_PRIORITY3 0x0546
@ -702,4 +702,42 @@
#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

View file

@ -27,7 +27,19 @@ extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
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)
@ -45,4 +57,5 @@ void TIMER4(void)
current_tick++;
IO_INTC_IRQ0 |= 1<<IRQ_TIMER1;
}

View file

@ -95,7 +95,7 @@ static const char * const irqname[] =
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]);
}
@ -105,7 +105,7 @@ void irq_handler(void)
/*
* Based on: linux/arch/arm/kernel/entry-armv.S and system-meg-fx.c
*/
printf("INTERUPT!");
asm volatile (
"sub lr, lr, #4 \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 */
/* Clearing all FIQs and IRQs. */
outw(0xFFFF, IO_INTC_IRQ0);
outw(0xFFFF, IO_INTC_IRQ1);
outw(0xFFFF, IO_INTC_IRQ2);
IO_INTC_IRQ0 = 0xFFFF;
IO_INTC_IRQ1 = 0xFFFF;
IO_INTC_IRQ2 = 0xFFFF;
outw(0xFFFF, IO_INTC_FIQ0);
outw(0xFFFF, IO_INTC_FIQ1);
outw(0xFFFF, IO_INTC_FIQ2);
IO_INTC_FIQ0 = 0xFFFF;
IO_INTC_FIQ1 = 0xFFFF;
IO_INTC_FIQ2 = 0xFFFF;
/* Masking all Interrupts. */
outw(0, IO_INTC_EINT0);
outw(0, IO_INTC_EINT1);
outw(0, IO_INTC_EINT2);
IO_INTC_EINT0 = 0;
IO_INTC_EINT1 = 0;
IO_INTC_EINT2 = 0;
/* Setting INTC to all IRQs. */
outw(0, IO_INTC_FISEL0);
outw(0, IO_INTC_FISEL1);
outw(0, IO_INTC_FISEL2);
IO_INTC_FISEL0 = 0;
IO_INTC_FISEL1 = 0;
IO_INTC_FISEL2 = 0;
}
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)
pfn_timer();
IO_INTC_IRQ0 |= 1<<IRQ_TIMER0;
}
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)
{
int oldlevel;
unsigned int divider;
/* taken from linux/arch/arm/mach-itdm320-20/time.c and timer-meg-fx.c */
/* Turn off all timers */
/* outw(CONFIG_TIMER0_TMMD_STOP, IO_TIMER0_TMMD);
outw(CONFIG_TIMER1_TMMD_STOP, IO_TIMER1_TMMD);
outw(CONFIG_TIMER2_TMMD_STOP, IO_TIMER2_TMMD);
outw(CONFIG_TIMER3_TMMD_STOP, IO_TIMER3_TMMD);
*/
/* Turn Timer0 to Free Run mode */
// outw(CONFIG_TIMER0_TMMD_FREE_RUN, IO_TIMER0_TMMD);
bool retval = false;
IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_STOP;
IO_TIMER1_TMMD = CONFIG_TIMER1_TMMD_STOP;
IO_TIMER2_TMMD = CONFIG_TIMER2_TMMD_STOP;
IO_TIMER3_TMMD = CONFIG_TIMER3_TMMD_STOP;
/* Find the minimum factor that puts the counter in range 1-65535 */
unsigned int prescaler = (cycles + 65534) / 65535;
/* Test this by writing 1's to registers to see how many bits we have */
/* Maximum divider setting is x / 1024 / 65536 = x / 67108864 */
if (start && pfn_unregister != NULL)
{
int oldlevel;
unsigned int divider;
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;
pfn_unregister();
pfn_unregister = NULL;
}
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)
@ -93,7 +89,9 @@ bool __timer_register(void)
stop_timer();
/* 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);

View file

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

View file

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