1
0
Fork 0
forked from len0rd/rockbox

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 INTMOD (*(REG32_PTR_T)(0x39C00004)) /* Interrupt mode register. */
#define INTMSK (*(REG32_PTR_T)(0x39C00008)) /* Determines which interrupt source is masked. The */ #define INTMSK (*(REG32_PTR_T)(0x39C00008)) /* Determines which interrupt source is masked. The */
#if CONFIG_CPU==S5L8701 #if CONFIG_CPU==S5L8701
#define INTMSK_TIMERA (1<<5)
#define INTMSK_TIMERB (1<<5) #define INTMSK_TIMERB (1<<5)
#define INTMSK_TIMERC (1<<5)
#define INTMSK_TIMERD (1<<5)
#define INTMSK_ECC (1<<19) #define INTMSK_ECC (1<<19)
#else #else
#define INTMSK_TIMERA (1<<5)
#define INTMSK_TIMERB (1<<7) #define INTMSK_TIMERB (1<<7)
#define INTMSK_TIMERC (1<<8)
#define INTMSK_TIMERD (1<<9)
#endif #endif
#define PRIORITY (*(REG32_PTR_T)(0x39C0000C)) /* IRQ priority control register */ #define PRIORITY (*(REG32_PTR_T)(0x39C0000C)) /* IRQ priority control register */
#define INTPND (*(REG32_PTR_T)(0x39C00010)) /* Indicates the interrupt request status. */ #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_MSTICK);
default_interrupt(INT_ADC_WAKEUP); default_interrupt(INT_ADC_WAKEUP);
default_interrupt(INT_ADC); 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 #if CONFIG_CPU==S5L8701
static void (* const irqvector[])(void) = static void (* const irqvector[])(void) =
{ /* still 90% unverified and probably incorrect */ { /* still 90% unverified and probably incorrect */
EXT0,EXT1,EXT2,EINT_VBUS,EINTG,INT_TIMERB,INT_WDT,INT_TIMERA, EXT0,EXT1,EXT2,EINT_VBUS,EINTG,INT_TIMER,INT_WDT,INT_UNK1,
INT_TIMERC,INT_TIMERD,INT_DMA,INT_ALARM_RTC,INT_PRI_RTC,RESERVED1,INT_UART,INT_USB_HOST, 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_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 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 #if CONFIG_CPU==S5L8701
static const char * const irqname[] = static const char * const irqname[] =
{ /* still 90% unverified and probably incorrect */ { /* still 90% unverified and probably incorrect */
"EXT0","EXT1","EXT2","EINT_VBUS","EINTG","INT_TIMERB","INT_WDT","INT_TIMERA", "EXT0","EXT1","EXT2","EINT_VBUS","EINTG","INT_TIMER","INT_WDT","INT_UNK1",
"INT_TIMERC","INT_TIMERD","INT_DMA","INT_ALARM_RTC","INT_PRI_RTC","Reserved","INT_UART","INT_USB_HOST", "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_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" "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 TODO: investigate why the timer seems to count twice as fast as expected
*/ */
void INT_TIMERD(void) void INT_TIMERC(void)
{ {
/* clear interrupt */ /* clear interrupt */
TDCON = TDCON; TCCON = TCCON;
if (pfn_timer != NULL) { if (pfn_timer != NULL) {
pfn_timer(); pfn_timer();
@ -52,7 +52,7 @@ bool timer_set(long cycles, bool start)
long count; long count;
/* stop and clear timer */ /* stop and clear timer */
TDCMD = (1 << 1); /* TD_CLR */ TCCMD = (1 << 1); /* TD_CLR */
/* optionally unregister any previously registered timer user */ /* optionally unregister any previously registered timer user */
if (start) { if (start) {
@ -78,27 +78,27 @@ bool timer_set(long cycles, bool start)
} }
/* configure timer */ /* configure timer */
TDCON = (1 << 12) | /* TD_INT0_EN */ TCCON = (1 << 12) | /* TD_INT0_EN */
(cs << 8) | /* TS_CS */ (cs << 8) | /* TS_CS */
(0 << 4); /* TD_MODE_SEL, 0 = interval mode */ (0 << 4); /* TD_MODE_SEL, 0 = interval mode */
TDPRE = prescale - 1; TCPRE = prescale - 1;
TDDATA0 = count; TCDATA0 = count;
TDCMD = (1 << 0); /* TD_ENABLE */ TCCMD = (1 << 0); /* TD_ENABLE */
/* enable interrupt */ /* enable interrupt */
INTMSK |= (1 << 9); INTMSK |= INTMSK_TIMERC;
return true; return true;
} }
bool timer_start(void) bool timer_start(void)
{ {
TDCMD = (1 << 0); /* TD_ENABLE */ TCCMD = (1 << 0); /* TD_ENABLE */
return true; return true;
} }
void timer_stop(void) void timer_stop(void)
{ {
TDCMD = (0 << 0); /* TD_ENABLE */ TCCMD = (0 << 0); /* TD_ENABLE */
} }