From e73d2a533cb928cc9954880f819c68840a2a372d Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Tue, 17 Sep 2013 20:17:18 +0100 Subject: [PATCH] dm36x: Fix IRQENTRY register address. Debug out on spurious interrupts. --- ports/arm/platforms/dm36x/atomport-private.c | 61 ++++++++++++++------ ports/arm/platforms/dm36x/dm36x-io.h | 12 +++- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/ports/arm/platforms/dm36x/atomport-private.c b/ports/arm/platforms/dm36x/atomport-private.c index 7986240..86912ba 100644 --- a/ports/arm/platforms/dm36x/atomport-private.c +++ b/ports/arm/platforms/dm36x/atomport-private.c @@ -116,9 +116,19 @@ low_level_init (void) /* Enable timer */ TIMER0_REG(DM36X_TIMER_TCR) |= (2 << 6); /* Enable Timer 1:2 continuous (ENAMODE12) */ - /* Initialise INTC interrupt controller */ + /* Initialise INTC interrupt controller (all at lowest priority 7) */ + INTC_REG(DM36X_INTC_PRI0) = 0x77777777; + INTC_REG(DM36X_INTC_PRI1) = 0x77777777; + INTC_REG(DM36X_INTC_PRI2) = 0x77777777; + INTC_REG(DM36X_INTC_PRI3) = 0x77777777; + INTC_REG(DM36X_INTC_PRI4) = 0x77777777; + INTC_REG(DM36X_INTC_PRI5) = 0x77777777; + INTC_REG(DM36X_INTC_PRI6) = 0x77777777; + INTC_REG(DM36X_INTC_PRI7) = 0x77777777; INTC_REG(DM36X_INTC_INTCTL) = 0; INTC_REG(DM36X_INTC_EABASE) = 0; + INTC_REG(DM36X_INTC_EINT0) = 0; + INTC_REG(DM36X_INTC_EINT1) = 0; /* Ack TINT0 IRQ in INTC interrupt controller */ INTC_REG(DM36X_INTC_IRQ1) = (1 << (DM36X_INTC_VEC_TINT0 - 32)); @@ -147,32 +157,45 @@ void __interrupt_dispatcher (void) { uint32_t vector; + uint32_t irqentry; /* Read IRQENTRY register to determine the source of the interrupt */ - vector = (INTC_REG(DM36X_INTC_IRQENTRY) / 4) - 1; + irqentry = INTC_REG(DM36X_INTC_IRQENTRY); - /* TIMER0:12 tick interrupt (call Atomthreads timer tick ISR) */ - if (vector == DM36X_INTC_VEC_TINT0) + /* Check for spurious interrupt */ + if (irqentry == 0) { - /* Reload timer and enable interupts */ - TIMER0_REG(DM36X_TIMER_PRD12) = (TIMER_CLK / SYSTEM_TICKS_PER_SEC) - 1; /* Set period to 100 ticks per second (PRD12) */ - TIMER0_REG(DM36X_TIMER_INTCTL_STAT) = (1 << 1) | (1 << 0); /* Enable/ack Compare/Match interrupt for Timer 1:2 */ + /* Spurious interrupt */ + uart_write_halt ("Spurious IRQ\n"); + } + else + { + /* Translate from vector address to vector number */ + vector = (INTC_REG(DM36X_INTC_IRQENTRY) / 4) - 1; - /* - * Let the Atomthreads kernel know we're about to enter an OS-aware - * interrupt handler which could cause scheduling of threads. - */ - atomIntEnter(); + /* TIMER0:12 tick interrupt (call Atomthreads timer tick ISR) */ + if (vector == DM36X_INTC_VEC_TINT0) + { + /* Reload timer and enable interupts */ + TIMER0_REG(DM36X_TIMER_PRD12) = (TIMER_CLK / SYSTEM_TICKS_PER_SEC) - 1; /* Set period to 100 ticks per second (PRD12) */ + TIMER0_REG(DM36X_TIMER_INTCTL_STAT) = (1 << 1) | (1 << 0); /* Enable/ack Compare/Match interrupt for Timer 1:2 */ - /* Call the OS system tick handler */ - atomTimerTick(); + /* + * Let the Atomthreads kernel know we're about to enter an OS-aware + * interrupt handler which could cause scheduling of threads. + */ + atomIntEnter(); - /* Call the interrupt exit routine */ - atomIntExit(TRUE); + /* Call the OS system tick handler */ + atomTimerTick(); - /* Ack the interrupt */ - INTC_REG((vector >= 32) ? DM36X_INTC_IRQ1 : DM36X_INTC_IRQ0) = (1 << (vector >= 32) ? (vector - 32) : vector); - } + /* Call the interrupt exit routine */ + atomIntExit(TRUE); + + /* Ack the interrupt */ + INTC_REG((vector >= 32) ? DM36X_INTC_IRQ1 : DM36X_INTC_IRQ0) = (1 << (vector >= 32) ? (vector - 32) : vector); + } + } } diff --git a/ports/arm/platforms/dm36x/dm36x-io.h b/ports/arm/platforms/dm36x/dm36x-io.h index fb0251b..03a9ab9 100644 --- a/ports/arm/platforms/dm36x/dm36x-io.h +++ b/ports/arm/platforms/dm36x/dm36x-io.h @@ -56,10 +56,20 @@ #define DM36X_INTC_BASE 0x01C48000 /* Interrupt controller */ #define DM36X_INTC_IRQ0 0x08 #define DM36X_INTC_IRQ1 0x0C -#define DM36X_INTC_IRQENTRY 0x10 +#define DM36X_INTC_FIQENTRY 0x10 +#define DM36X_INTC_IRQENTRY 0x14 +#define DM36X_INTC_EINT0 0x18 #define DM36X_INTC_EINT1 0x1C #define DM36X_INTC_INTCTL 0x20 #define DM36X_INTC_EABASE 0x24 +#define DM36X_INTC_PRI0 0x30 +#define DM36X_INTC_PRI1 0x34 +#define DM36X_INTC_PRI2 0x38 +#define DM36X_INTC_PRI3 0x3C +#define DM36X_INTC_PRI4 0x40 +#define DM36X_INTC_PRI5 0x44 +#define DM36X_INTC_PRI6 0x48 +#define DM36X_INTC_PRI7 0x4C #define DM36X_INTC_VEC_TINT0 32 #define DM36X_UART0_BASE 0x01C20000 /* UART0 */