From ee2303e97085dccae0a05114ef5d22fa904a5011 Mon Sep 17 00:00:00 2001 From: patacongo Date: Mon, 3 May 2010 00:29:13 +0000 Subject: [PATCH] XTI interrupt enable/disable logic git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2647 42af7a65-404d-4744-a932-0658087f49c3 --- arch/arm/src/str71x/str71x_internal.h | 39 +++++++-- arch/arm/src/str71x/str71x_irq.c | 31 +++++-- arch/arm/src/str71x/str71x_xti.c | 115 ++++++++++++++++++++++---- 3 files changed, 159 insertions(+), 26 deletions(-) diff --git a/arch/arm/src/str71x/str71x_internal.h b/arch/arm/src/str71x/str71x_internal.h index 6c8913376d..99012ca9c9 100644 --- a/arch/arm/src/str71x/str71x_internal.h +++ b/arch/arm/src/str71x/str71x_internal.h @@ -105,23 +105,52 @@ ********************************************************************************/ #ifdef CONFIG_STR71X_XTI -extern int str7x_xtiinitialize(void); +extern int str71x_xtiinitialize(void); #else -# define str7x_xtiinitialize() +# define str71x_xtiinitialize() #endif /* CONFIG_STR71X_XTI */ /******************************************************************************** * Name: str7x_xticonfig * * Description: - * Configure an external line to provide interrupts. + * Configure an external line to provide interrupts. Interrupt is configured, + * but disabled on return. * ********************************************************************************/ #ifdef CONFIG_STR71X_XTI -extern int str7x_xticonfig(int irq, bool rising); +extern int str71x_xticonfig(int irq, bool rising); #else -# define str7x_xticonfig(irq,rising) +# define str71x_xticonfig(irq,rising) +#endif /* CONFIG_STR71X_XTI */ + +/**************************************************************************** + * Name: str71x_enable_xtiirq + * + * Description: + * Enable an external interrupt. + * + ****************************************************************************/ + +#ifdef CONFIG_STR71X_XTI +extern void str71x_enable_xtiirq(int irq); +#else +# define str71x_enable_xtiirq(irq) +#endif /* CONFIG_STR71X_XTI */ + +/**************************************************************************** + * Name: str71x_disable_xtiirq + * + * Description: + * Disable an external interrupt. + * + ****************************************************************************/ + +#ifdef CONFIG_STR71X_XTI +extern void str71x_disable_xtiirq(int irq); +#else +# define str71x_disable_xtiirq(irq) #endif /* CONFIG_STR71X_XTI */ #endif /* __ARCH_ARM_SRC_STR71X_STR71X_INTERNAL_H */ diff --git a/arch/arm/src/str71x/str71x_irq.c b/arch/arm/src/str71x/str71x_irq.c index ed39a560be..d27412e172 100644 --- a/arch/arm/src/str71x/str71x_irq.c +++ b/arch/arm/src/str71x/str71x_irq.c @@ -48,6 +48,7 @@ #include "chip.h" #include "up_arch.h" #include "up_internal.h" +#include "str71x_internal.h" /**************************************************************************** * Pre-procesor Definitions @@ -100,6 +101,10 @@ void up_irqinitialize(void) putreg32(0xffffffff, STR71X_EIC_IPR); /* And that no interrupts are pending */ #endif + /* Initialize external interrupts */ + + str71x_xtiinitialize(); + /* Enable global ARM interrupts */ #ifndef CONFIG_SUPPRESS_INTERRUPTS @@ -119,7 +124,7 @@ void up_disable_irq(int irq) { uint32_t reg32; - if ((unsigned)irq < NR_IRQS) + if ((unsigned)irq < STR71X_NBASEIRQS) { /* Mask the IRQ by clearing the associated bit in the IER register */ @@ -127,6 +132,12 @@ void up_disable_irq(int irq) reg32 &= ~(1 << irq); putreg32(reg32, STR71X_EIC_IER); } +#ifdef CONFIG_STR71X_XTI + else if ((unsigned)irq < NR_IRQS) + { + str71x_disable_xtiirq(irq); + } +#endif /* CONFIG_STR71X_XTI */ } /**************************************************************************** @@ -141,7 +152,7 @@ void up_enable_irq(int irq) { uint32_t reg32; - if ((unsigned)irq < NR_IRQS) + if ((unsigned)irq < STR71X_NBASEIRQS) { /* Enable the IRQ by setting the associated bit in the IER register */ @@ -149,13 +160,20 @@ void up_enable_irq(int irq) reg32 |= (1 << irq); putreg32(reg32, STR71X_EIC_IER); } +#ifdef CONFIG_STR71X_XTI + else if ((unsigned)irq < NR_IRQS) + { + str71x_enable_xtiirq(irq); + } +#endif /* CONFIG_STR71X_XTI */ } /**************************************************************************** * Name: up_maskack_irq * * Description: - * Mask the IRQ and acknowledge it + * Mask the IRQ and acknowledge it. No XTI support.. only used in + * interrupt handling logic. * ****************************************************************************/ @@ -163,7 +181,7 @@ void up_maskack_irq(int irq) { uint32_t reg32; - if ((unsigned)irq < NR_IRQS) + if ((unsigned)irq < STR71X_NBASEIRQS) { /* Mask the IRQ by clearing the associated bit in the IER register */ @@ -185,7 +203,8 @@ void up_maskack_irq(int irq) * Name: up_prioritize_irq * * Description: - * set interrupt priority + * Set interrupt priority. Note, there is no way to prioritize + * individual XTI interrrupts. * ****************************************************************************/ @@ -198,7 +217,7 @@ int up_prioritize_irq(int irq, int priority) * of one is enforced to prevent disabling the interrupt. */ - if ((unsigned)irq < NR_IRQS && priority > 0 && priority < 16) + if ((unsigned)irq < STR71X_NBASEIRQS && priority > 0 && priority < 16) { addr = STR71X_EIC_SIR(irq); reg32 = getreg32(addr); diff --git a/arch/arm/src/str71x/str71x_xti.c b/arch/arm/src/str71x/str71x_xti.c index 63e084577a..f89f0715f5 100755 --- a/arch/arm/src/str71x/str71x_xti.c +++ b/arch/arm/src/str71x/str71x_xti.c @@ -52,6 +52,7 @@ #include "up_arch.h" #include "os_internal.h" #include "up_internal.h" +#include "str71x_internal.h" #ifdef CONFIG_STR71X_XTI @@ -87,7 +88,15 @@ static const struct xtiregs_s g_xtiregs[2] = * Private Functions ********************************************************************************/ -static int str7x_xtiinterrupt(int irq, FAR void *context) +/******************************************************************************** + * Name: str71x_xtiinterrupt + * + * Description: + * Dispatch an XTI interrupt. + * + ********************************************************************************/ + +static int str71x_xtiinterrupt(int irq, FAR void *context) { uint16_t enabled = (uint16_t)getreg8(STR71X_XTI_MRH) << 8 | (uint16_t)getreg8(STR71X_XTI_MRL); @@ -135,7 +144,7 @@ static int str7x_xtiinterrupt(int irq, FAR void *context) ********************************************************************************/ /******************************************************************************** - * Name: str7x_xtiinitialize + * Name: str71x_xtiinitialize * * Description: * Configure XTI for operation. Note that the lines are not used as wake-up @@ -144,7 +153,7 @@ static int str7x_xtiinterrupt(int irq, FAR void *context) * ********************************************************************************/ -int str7x_xtiinitialize(void) +int str71x_xtiinitialize(void) { int ret; @@ -160,7 +169,7 @@ int str7x_xtiinitialize(void) /* Attach the XTI interrupt */ - ret = irq_attach(STR71X_IRQ_XTI, str7x_xtiinterrupt); + ret = irq_attach(STR71X_IRQ_XTI, str71x_xtiinterrupt); if (ret == OK) { /* Enable the XTI interrupt at the XTI */ @@ -175,16 +184,16 @@ int str7x_xtiinitialize(void) } /******************************************************************************** - * Name: str7x_xticonfig + * Name: str71x_xticonfig * * Description: * Configure an external line to provide interrupts. * ********************************************************************************/ -int str7x_xticonfig(int irq, bool rising) +int str71x_xticonfig(int irq, bool rising) { - uint8_t regval; + uint8_t regval; int bit; int ndx; int ret = -EINVAL; @@ -193,6 +202,10 @@ int str7x_xticonfig(int irq, bool rising) if (irq > STR71X_IRQ_FIRSTXTI && irq <= NR_IRQS) { + /* Make sure that the interrupt is disabled */ + + str71x_disable_xtiirq(irq); + /* Decide if we use the lower or upper regiser */ bit = irq - STR71X_IRQ_FIRSTXTI; @@ -218,14 +231,6 @@ int str7x_xticonfig(int irq, bool rising) } putreg8(regval, g_xtiregs[ndx].tr); - /* Enable the interrupt be setting the corresponding mask bit - * the XTI_MRL/H register. - */ - - regval = getreg8(g_xtiregs[ndx].mr); - regval |= (1 << bit); - putreg8(regval, g_xtiregs[ndx].mr); - /* Return success */ ret = OK; @@ -233,4 +238,84 @@ int str7x_xticonfig(int irq, bool rising) return ret; } +/**************************************************************************** + * Name: str71x_enable_xtiirq + * + * Description: + * Enable an external interrupt. + * + ****************************************************************************/ + +void str71x_enable_xtiirq(int irq) +{ + uint8_t regval; + int bit; + int ndx; + + /* Enable the external interrupt */ + + if (irq > STR71X_IRQ_FIRSTXTI && irq <= NR_IRQS) + { + /* Decide if we use the lower or upper regiser */ + + bit = irq - STR71X_IRQ_FIRSTXTI; + ndx = 0; + if (bit > 7) + { + /* Select the high register */ + + bit -= 8; + ndx = 1; + } + + /* Enable the interrupt be setting the corresponding mask bit + * the XTI_MRL/H register. + */ + + regval = getreg8(g_xtiregs[ndx].mr); + regval |= (1 << bit); + putreg8(regval, g_xtiregs[ndx].mr); + } +} + +/**************************************************************************** + * Name: str71x_disable_xtiirq + * + * Description: + * Disable an external interrupt. + * + ****************************************************************************/ + +void str71x_disable_xtiirq(int irq) +{ + uint8_t regval; + int bit; + int ndx; + + /* Disable the external interrupt */ + + if (irq > STR71X_IRQ_FIRSTXTI && irq <= NR_IRQS) + { + /* Decide if we use the lower or upper regiser */ + + bit = irq - STR71X_IRQ_FIRSTXTI; + ndx = 0; + if (bit > 7) + { + /* Select the high register */ + + bit -= 8; + ndx = 1; + } + + /* Disable the interrupt be clearing the corresponding mask bit + * the XTI_MRL/H register. + */ + + regval = getreg8(g_xtiregs[ndx].mr); + regval &= ~(1 << bit); + putreg8(regval, g_xtiregs[ndx].mr); + } +} + #endif /* CONFIG_STR71X_XTI */