summaryrefslogtreecommitdiff
path: root/nuttx/arch
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-03 00:29:56 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-03 00:29:56 +0000
commit5f2f233d6704d1844dfdc7334e9f2b84c8c00908 (patch)
treec1d989acaa7163213655b8dd1790bc015a92684a /nuttx/arch
parent6e21730d1f9137a9798b934552afd0f5b6c07299 (diff)
downloadpx4-nuttx-5f2f233d6704d1844dfdc7334e9f2b84c8c00908.tar.gz
px4-nuttx-5f2f233d6704d1844dfdc7334e9f2b84c8c00908.tar.bz2
px4-nuttx-5f2f233d6704d1844dfdc7334e9f2b84c8c00908.zip
Completes coding of basic interrupt handling logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@199 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch')
-rw-r--r--nuttx/arch/arm/include/lpc214x/irq.h2
-rw-r--r--nuttx/arch/arm/src/lpc214x/chip.h2
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_decodeirq.c39
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_irq.c82
-rwxr-xr-xnuttx/arch/arm/src/lpc214x/lpc214x_vic.h6
5 files changed, 95 insertions, 36 deletions
diff --git a/nuttx/arch/arm/include/lpc214x/irq.h b/nuttx/arch/arm/include/lpc214x/irq.h
index 457a903d8..1542ee290 100644
--- a/nuttx/arch/arm/include/lpc214x/irq.h
+++ b/nuttx/arch/arm/include/lpc214x/irq.h
@@ -80,7 +80,9 @@
* Public Types
************************************************************/
+#ifndef __ASSEMBLY__
typedef void (*vic_vector_t)(uint32 *regs);
+#endif
/************************************************************
* Inline functions
diff --git a/nuttx/arch/arm/src/lpc214x/chip.h b/nuttx/arch/arm/src/lpc214x/chip.h
index 807777fd8..84cdf4c13 100644
--- a/nuttx/arch/arm/src/lpc214x/chip.h
+++ b/nuttx/arch/arm/src/lpc214x/chip.h
@@ -68,7 +68,7 @@
#define LPC214X_PLL_BASE 0xe01fc080 /* Phase Locked Loop (PLL) Base Address */
#define LPC214X_VPBDIV 0xe01fc100 /* VPBDIV Address */
#define LPC214X_EMC_BASE 0xffe00000 /* External Memory Controller (EMC) Base Address */
-#define LPC214X_VIC_BASE 0xffff0000 /* Vectored Interrupt Controller (VIC) Base */
+#define LPC214X_VIC_BASE 0xfffff000 /* Vectored Interrupt Controller (VIC) Base */
/* UART0/1 Register Offsets */
diff --git a/nuttx/arch/arm/src/lpc214x/lpc214x_decodeirq.c b/nuttx/arch/arm/src/lpc214x/lpc214x_decodeirq.c
index f28be2606..f90feb9c7 100644
--- a/nuttx/arch/arm/src/lpc214x/lpc214x_decodeirq.c
+++ b/nuttx/arch/arm/src/lpc214x/lpc214x_decodeirq.c
@@ -65,6 +65,10 @@
* Private Data
********************************************************************************/
+/* This type arry maps 4 bits into the bit number of the lowest bit that it set */
+
+static uint8 g_nibblemap[16] = { 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 };
+
/********************************************************************************
* Private Functions
********************************************************************************/
@@ -108,19 +112,34 @@ static void lpc214x_decodeirq( uint32 *regs)
PANIC(OSERR_ERREXCEPTION);
#else
- /* Decode the interrupt. First, fetch the interrupt id register. */
+ /* Decode the interrupt. We have to do this by search for the lowest numbered
+ * non-zero bit in the interrupt status register.
+ */
- int irq = 0;
-#warning "Need to decode the interrupt here"
+ uint32 pending = vic_getreg(LPC214X_VIC_IRQSTATUS_OFFSET) & 0x007fffff;
+ unsigned int nibble;
+ unsigned int irq_base;
+ unsigned int irq = NR_IRQS;
- /* Verify that the resulting IRQ number is valie */
+ /* Search in groups of four bits. For 22 sources, this is at most five
+ * times through the loop.
+ */
- if ((unsigned)irq < NR_IRQS)
+ for (nibble = pending & 0xff, irq_base = 0;
+ pending && irq < NR_IRQS;
+ pending >>= 4, nibble = pending & 0xff, irq_base += 4)
{
- /* Mask and acknowledge the interrupt */
+ if (nibble)
+ {
+ irq = irq_base + g_nibblemap[nibble];
+ break;
+ }
+ }
- up_maskack_irq(irq);
+ /* Verify that the resulting IRQ number is valid */
+ if (irq < NR_IRQS)
+ {
/* Current regs non-zero indicates that we are processing an interrupt;
* current_regs is also used to manage interrupt level context switches.
*/
@@ -134,12 +153,6 @@ static void lpc214x_decodeirq( uint32 *regs)
/* Indicate that we are no long in an interrupt handler */
current_regs = NULL;
-
- /* Unmask the last interrupt (global interrupts are still
- * disabled.
- */
-
- up_enable_irq(irq);
}
#endif
}
diff --git a/nuttx/arch/arm/src/lpc214x/lpc214x_irq.c b/nuttx/arch/arm/src/lpc214x/lpc214x_irq.c
index 8105fd897..37609a6dd 100644
--- a/nuttx/arch/arm/src/lpc214x/lpc214x_irq.c
+++ b/nuttx/arch/arm/src/lpc214x/lpc214x_irq.c
@@ -76,12 +76,14 @@ void up_irqinitialize(void)
{
int reg;
- /* Acknowledge and disable all interrupts */
+ /* Disable all interrupts. We do this by writing zero to the IntEnable
+ * register. This is equivalent to writing all ones to the IntClearEnable
+ * register.
+ */
- vic_putreg(0, LPC214X_VIC_INTENCLEAR_OFFSET);
vic_putreg(0, LPC214X_VIC_INTENABLE_OFFSET);
- /* All IRQs, no FIQs */
+ /* Select all IRQs, no FIQs */
vic_putreg(0, LPC214X_VIC_INTSELECT_OFFSET);
@@ -98,8 +100,6 @@ void up_irqinitialize(void)
vic_putreg(0, reg);
}
-#warning "Not implemented"
-
/* currents_regs is non-NULL only while processing an interrupt */
current_regs = NULL;
@@ -121,7 +121,16 @@ void up_irqinitialize(void)
void up_disable_irq(int irq)
{
-#warning "Not implemented"
+ /* Verify that the IRQ number is within range */
+
+ if (irq < NR_IRQS)
+ {
+ /* Disable the irq by setting the corresponding bit in the VIC
+ * Interrupt Enable Clear register.
+ */
+
+ vic_putreg((1 << irq), LPC214X_VIC_INTENCLEAR_OFFSET);
+ }
}
/****************************************************************************
@@ -134,34 +143,55 @@ void up_disable_irq(int irq)
void up_enable_irq(int irq)
{
-#warning "Not implemented"
-}
+ /* Verify that the IRQ number is within range */
-/****************************************************************************
- * Name: up_maskack_irq
- *
- * Description:
- * Mask the IRQ and acknowledge it
- *
- ****************************************************************************/
+ if (irq < NR_IRQS)
+ {
+ /* Disable all interrupts */
-void up_maskack_irq(int irq)
-{
-#warning "Not implemented"
+ irqstate_t flags = irqsave();
+
+ /* Enable the irq by setting the corresponding bit in the VIC
+ * Interrupt Enable register.
+ */
+
+ uint32 val = vic_getreg(LPC214X_VIC_INTENABLE_OFFSET);
+ vic_putreg(val | (1 << irq), LPC214X_VIC_INTENCLEAR_OFFSET);
+ irqrestore(flags);
+ }
}
/****************************************************************************
* Name: up_attach_vector
*
* Description:
- * Assign
+ * Attach a user-supplied handler to a vectored interrupt
*
****************************************************************************/
#ifndef CONFIG_VECTORED_INTERRUPTS
void up_attach_vector(int irq, int vector, vic_vector_t handler)
{
-#warning "Not implemented"
+ /* Verify that the IRQ number and vector number are within range */
+
+ if (irq < NR_IRQS && vector < 16 && handler)
+ {
+ int offset = vector << 2;
+
+ /* Disable all interrupts */
+
+ irqstate_t flags = irqsave();
+
+ /* Save the vector address */
+
+ vic_putreg((uint32)handler, LPC214X_VIC_VECTADDR0_OFFSET + offset);
+
+ /* Enable the vectored interrupt */
+
+ vic_putreg(((irq << LPC214X_VECTCNTL_IRQSHIFT) | LPC214X_VECTCNTL_ENABLE),
+ LPC214X_VIC_VECTCNTL0_OFFSET + offset);
+ irqrestore(flags);
+ }
}
#endif
@@ -169,13 +199,21 @@ void up_attach_vector(int irq, int vector, vic_vector_t handler)
* Name: up_detach_vector
*
* Description:
- * Mask the IRQ and acknowledge it
+ * Detach a user-supplied handler from a vectored interrupt
*
****************************************************************************/
#ifndef CONFIG_VECTORED_INTERRUPTS
void up_detach_vector(int vector)
{
-#warning "Not implemented"
+ /* Verify that the vector number is within range */
+
+ if (vector < 16)
+ {
+ /* Disable the vectored interrupt */
+
+ int offset = vector << 2;
+ vic_putreg(0, LPC214X_VIC_VECTCNTL0_OFFSET + offset);
+ }
}
#endif
diff --git a/nuttx/arch/arm/src/lpc214x/lpc214x_vic.h b/nuttx/arch/arm/src/lpc214x/lpc214x_vic.h
index d9b60501f..dcc297030 100755
--- a/nuttx/arch/arm/src/lpc214x/lpc214x_vic.h
+++ b/nuttx/arch/arm/src/lpc214x/lpc214x_vic.h
@@ -49,6 +49,12 @@
#define vic_getreg(o) getreg32(LPC214X_VIC_BASE+(o))
#define vic_putreg(v,o) putreg32((v),LPC214X_VIC_BASE+(o))
+// Vector Control Register bit definitions
+
+#define LPC214X_VECTCNTL_IRQMASK (0x0000001f)
+#define LPC214X_VECTCNTL_IRQSHIFT (0)
+#define LPC214X_VECTCNTL_ENABLE (1 << 5)
+
/************************************************************************************
* Public Types
************************************************************************************/