This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Improved interrupt handling for AT91


     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)
 {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]