This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
Improved interrupt handling for AT91
- From: daniel dot neri at sigicom dot se (Daniel Néri)
- To: ecos-patches at sources dot redhat dot com
- Date: Wed, 04 Jun 2003 16:16:41 +0000
- Subject: Improved interrupt handling for AT91
- Cancel-lock: sha1:9nI7PFD3h5ABG9TZmPT09De53ss=
- Organization: Sigicom AB, Stockholm, Sweden
Hello,
Here's a patch to offload some boring work in hal_IRQ_handler to the
interrupt controller.
This change has been in my tree for quite some time now and I thought
that maybe other AT91 users might want to try it out.
Note that for the patch to apply cleanly, you will first need the
var_io.h fix that I've posted here previously.
Best wishes,
--Daniel
cvs diff: Diffing hal/arm/at91/var/current
Index: hal/arm/at91/var/current/ChangeLog
===================================================================
RCS file: /home/dne/cvsroot/redhat/ecos/packages/hal/arm/at91/var/current/ChangeLog,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -5 -p -r1.5 -r1.6
--- hal/arm/at91/var/current/ChangeLog 2003/05/27 13:59:59 1.5
+++ hal/arm/at91/var/current/ChangeLog 2003/06/04 15:40:05 1.6
@@ -1,5 +1,16 @@
+2003-06-04 Daniel Néri <daniel.neri@sigicom.se>
+
+ * src/at91_misc.c (hal_hardware_init): Make sure the AIC internal
+ priority level stack is flushed.
+ (hal_IRQ_handler): Calculate active interrupt by dummy read from
+ the IVR, which has the side-effect of updating ISR with the
+ current interrupt source number.
+ (hal_interrupt_acknowledge): Write to ICCR is not needed, as
+ interrupt deassertion is taken care of by read of IVR in
+ hal_IRQ_handler.
+
2003-05-27 Daniel Néri <daniel.neri@sigicom.se>
* include/var_io.h: Add missing USART register defines.
Fix cut'n'paste typos in AT91_PS defines.
cvs diff: Diffing hal/arm/at91/var/current/cdl
cvs diff: Diffing hal/arm/at91/var/current/include
cvs diff: Diffing hal/arm/at91/var/current/src
Index: hal/arm/at91/var/current/src/at91_misc.c
===================================================================
RCS file: /home/dne/cvsroot/redhat/ecos/packages/hal/arm/at91/var/current/src/at91_misc.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -5 -p -r1.3 -r1.4
--- hal/arm/at91/var/current/src/at91_misc.c 2003/05/28 15:37:47 1.3
+++ hal/arm/at91/var/current/src/at91_misc.c 2003/06/04 15:40:05 1.4
@@ -157,37 +157,36 @@ void hal_delay_us(cyg_int32 usecs)
// -------------------------------------------------------------------------
// Hardware init
void hal_hardware_init(void)
{
+ unsigned i;
+
// Set up eCos/ROM interfaces
hal_if_init();
// Reset all interrupts
HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IDCR, 0xFFFFFFFF);
- // Make sure interrupt controller is happy
- HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_EOI, 0xFFFFFFFF);
+ // Flush internal priority level stack
+ for (i = 0; i < 8; ++i)
+ HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_EOI, 0xFFFFFFFF);
}
// -------------------------------------------------------------------------
// This routine is called to respond to a hardware interrupt (IRQ). It
// should interrogate the hardware and return the IRQ vector number.
int hal_IRQ_handler(void)
{
cyg_uint32 irq_num;
- cyg_uint32 ipr, imr;
+ cyg_uint32 ivr;
-// HAL_READ_UINT32(AT91_AIC+AT91_AIC_ISR, irq_num);
-
- HAL_READ_UINT32(AT91_AIC+AT91_AIC_IPR, ipr);
- HAL_READ_UINT32(AT91_AIC+AT91_AIC_IMR, imr);
-
- ipr &= imr;
+ // Calculate active interrupt (updates ISR)
+ HAL_READ_UINT32(AT91_AIC+AT91_AIC_IVR, ivr);
- HAL_LSBIT_INDEX( irq_num, ipr );
+ HAL_READ_UINT32(AT91_AIC+AT91_AIC_ISR, irq_num);
return irq_num;
}
// -------------------------------------------------------------------------
@@ -213,13 +212,10 @@ void hal_interrupt_unmask(int vector)
void hal_interrupt_acknowledge(int vector)
{
CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
- HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_ICCR, (1<<vector));
-
- // FIXME - This isn't 100% correct
HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_EOI, 0xFFFFFFFF);
}
void hal_interrupt_configure(int vector, int level, int up)
{