Fix the user timer on iPod Nano 2G

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22959 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Sparmann 2009-10-05 16:01:26 +00:00
parent 79bf2da1ef
commit 271c67e802
3 changed files with 31 additions and 14 deletions

View file

@ -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. */

View file

@ -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"
};

View file

@ -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 */
}