summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sparmann <theseven@rockbox.org>2009-10-05 16:01:26 +0000
committerMichael Sparmann <theseven@rockbox.org>2009-10-05 16:01:26 +0000
commit271c67e802c65b243c7e4c76e276a893345f15fe (patch)
tree10e1389be74cfc62c0651a590c4496fb2e1fea34
parent79bf2da1ef6f8f16c44ba8fa6d71ea6870a19767 (diff)
downloadrockbox-271c67e802c65b243c7e4c76e276a893345f15fe.zip
rockbox-271c67e802c65b243c7e4c76e276a893345f15fe.tar.gz
rockbox-271c67e802c65b243c7e4c76e276a893345f15fe.tar.bz2
rockbox-271c67e802c65b243c7e4c76e276a893345f15fe.tar.xz
Fix the user timer on iPod Nano 2G
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22959 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/export/s5l8700.h6
-rw-r--r--firmware/target/arm/s5l8700/system-s5l8700.c19
-rw-r--r--firmware/target/arm/s5l8700/timer-s5l8700.c20
3 files changed, 31 insertions, 14 deletions
diff --git a/firmware/export/s5l8700.h b/firmware/export/s5l8700.h
index 801e8a0..f652a62 100644
--- a/firmware/export/s5l8700.h
+++ b/firmware/export/s5l8700.h
@@ -126,10 +126,16 @@
#define INTMOD (*(REG32_PTR_T)(0x39C00004)) /* Interrupt mode register. */
#define INTMSK (*(REG32_PTR_T)(0x39C00008)) /* Determines which interrupt source is masked. The */
#if CONFIG_CPU==S5L8701
+#define INTMSK_TIMERA (1<<5)
#define INTMSK_TIMERB (1<<5)
+#define INTMSK_TIMERC (1<<5)
+#define INTMSK_TIMERD (1<<5)
#define INTMSK_ECC (1<<19)
#else
+#define INTMSK_TIMERA (1<<5)
#define INTMSK_TIMERB (1<<7)
+#define INTMSK_TIMERC (1<<8)
+#define INTMSK_TIMERD (1<<9)
#endif
#define PRIORITY (*(REG32_PTR_T)(0x39C0000C)) /* IRQ priority control register */
#define INTPND (*(REG32_PTR_T)(0x39C00010)) /* Indicates the interrupt request status. */
diff --git a/firmware/target/arm/s5l8700/system-s5l8700.c b/firmware/target/arm/s5l8700/system-s5l8700.c
index 3477bb8..a557700 100644
--- a/firmware/target/arm/s5l8700/system-s5l8700.c
+++ b/firmware/target/arm/s5l8700/system-s5l8700.c
@@ -64,14 +64,25 @@ default_interrupt(RESERVED2);
default_interrupt(INT_MSTICK);
default_interrupt(INT_ADC_WAKEUP);
default_interrupt(INT_ADC);
+default_interrupt(INT_UNK1);
+default_interrupt(INT_UNK2);
+default_interrupt(INT_UNK3);
+void INT_TIMER(void)
+{
+ if (TACON & 0x00038000) INT_TIMERA();
+ if (TBCON & 0x00038000) INT_TIMERB();
+ if (TCCON & 0x00038000) INT_TIMERC();
+ if (TDCON & 0x00038000) INT_TIMERD();
+}
+
#if CONFIG_CPU==S5L8701
static void (* const irqvector[])(void) =
{ /* still 90% unverified and probably incorrect */
- EXT0,EXT1,EXT2,EINT_VBUS,EINTG,INT_TIMERB,INT_WDT,INT_TIMERA,
- INT_TIMERC,INT_TIMERD,INT_DMA,INT_ALARM_RTC,INT_PRI_RTC,RESERVED1,INT_UART,INT_USB_HOST,
+ EXT0,EXT1,EXT2,EINT_VBUS,EINTG,INT_TIMER,INT_WDT,INT_UNK1,
+ INT_UNK2,INT_UNK3,INT_DMA,INT_ALARM_RTC,INT_PRI_RTC,RESERVED1,INT_UART,INT_USB_HOST,
INT_USB_FUNC,INT_LCDC_0,INT_LCDC_1,INT_CALM,INT_ATA,INT_UART0,INT_SPDIF_OUT,INT_ECC,
INT_SDCI,INT_LCD,INT_SPI,INT_IIC,RESERVED2,INT_MSTICK,INT_ADC_WAKEUP,INT_ADC
};
@@ -88,8 +99,8 @@ static void (* const irqvector[])(void) =
#if CONFIG_CPU==S5L8701
static const char * const irqname[] =
{ /* still 90% unverified and probably incorrect */
- "EXT0","EXT1","EXT2","EINT_VBUS","EINTG","INT_TIMERB","INT_WDT","INT_TIMERA",
- "INT_TIMERC","INT_TIMERD","INT_DMA","INT_ALARM_RTC","INT_PRI_RTC","Reserved","INT_UART","INT_USB_HOST",
+ "EXT0","EXT1","EXT2","EINT_VBUS","EINTG","INT_TIMER","INT_WDT","INT_UNK1",
+ "INT_UNK2","INT_UNK3","INT_DMA","INT_ALARM_RTC","INT_PRI_RTC","Reserved","INT_UART","INT_USB_HOST",
"INT_USB_FUNC","INT_LCDC_0","INT_LCDC_1","INT_CALM","INT_ATA","INT_UART0","INT_SPDIF_OUT","INT_ECC",
"INT_SDCI","INT_LCD","INT_SPI","INT_IIC","Reserved","INT_MSTICK","INT_ADC_WAKEUP","INT_ADC"
};
diff --git a/firmware/target/arm/s5l8700/timer-s5l8700.c b/firmware/target/arm/s5l8700/timer-s5l8700.c
index 3e8e7d7..9ae7e01 100644
--- a/firmware/target/arm/s5l8700/timer-s5l8700.c
+++ b/firmware/target/arm/s5l8700/timer-s5l8700.c
@@ -35,10 +35,10 @@
TODO: investigate why the timer seems to count twice as fast as expected
*/
-void INT_TIMERD(void)
+void INT_TIMERC(void)
{
/* clear interrupt */
- TDCON = TDCON;
+ TCCON = TCCON;
if (pfn_timer != NULL) {
pfn_timer();
@@ -52,7 +52,7 @@ bool timer_set(long cycles, bool start)
long count;
/* stop and clear timer */
- TDCMD = (1 << 1); /* TD_CLR */
+ TCCMD = (1 << 1); /* TD_CLR */
/* optionally unregister any previously registered timer user */
if (start) {
@@ -78,27 +78,27 @@ bool timer_set(long cycles, bool start)
}
/* configure timer */
- TDCON = (1 << 12) | /* TD_INT0_EN */
+ TCCON = (1 << 12) | /* TD_INT0_EN */
(cs << 8) | /* TS_CS */
(0 << 4); /* TD_MODE_SEL, 0 = interval mode */
- TDPRE = prescale - 1;
- TDDATA0 = count;
- TDCMD = (1 << 0); /* TD_ENABLE */
+ TCPRE = prescale - 1;
+ TCDATA0 = count;
+ TCCMD = (1 << 0); /* TD_ENABLE */
/* enable interrupt */
- INTMSK |= (1 << 9);
+ INTMSK |= INTMSK_TIMERC;
return true;
}
bool timer_start(void)
{
- TDCMD = (1 << 0); /* TD_ENABLE */
+ TCCMD = (1 << 0); /* TD_ENABLE */
return true;
}
void timer_stop(void)
{
- TDCMD = (0 << 0); /* TD_ENABLE */
+ TCCMD = (0 << 0); /* TD_ENABLE */
}