diff --git a/arch/arm/src/lpc43xx/Kconfig b/arch/arm/src/lpc43xx/Kconfig index 5b7d730151..c6df85ae35 100644 --- a/arch/arm/src/lpc43xx/Kconfig +++ b/arch/arm/src/lpc43xx/Kconfig @@ -150,6 +150,13 @@ endchoice # LPC43XX Boot Configuration menu "LPC43xx Peripheral Support" + +config GPIO_IRQ + bool "GPIO interrupt support" + default n + ---help--- + Enable support for GPIO interrupts + config LPC43_ADC0 bool "ADC0" default n diff --git a/arch/arm/src/lpc43xx/lpc43_gpio.c b/arch/arm/src/lpc43xx/lpc43_gpio.c index 3d5db11b7e..49b7f9b27f 100644 --- a/arch/arm/src/lpc43xx/lpc43_gpio.c +++ b/arch/arm/src/lpc43xx/lpc43_gpio.c @@ -49,6 +49,10 @@ #include "up_arch.h" #include "lpc43_gpio.h" +#ifdef CONFIG_GPIO_IRQ +#include "lpc43_gpioint.h" +#endif + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ diff --git a/arch/arm/src/lpc43xx/lpc43_gpio.h b/arch/arm/src/lpc43xx/lpc43_gpio.h index 1ee14fac63..4f16c841de 100644 --- a/arch/arm/src/lpc43xx/lpc43_gpio.h +++ b/arch/arm/src/lpc43xx/lpc43_gpio.h @@ -143,7 +143,7 @@ * ..CC C... .... .... */ -#define GPIO_PININT_SHIFT (10) /* Bits 11-13: Pin interrupt number */ +#define GPIO_PININT_SHIFT (11) /* Bits 11-13: Pin interrupt number */ #define GPIO_PININT_MASK (7 << GPIO_PININT_SHIFT) # define GPIO_PININT0 (0 << GPIO_PININT_SHIFT) # define GPIO_PININT1 (1 << GPIO_PININT_SHIFT) @@ -162,9 +162,9 @@ * .... .III .... .... */ -#define _GPIO_INT_LEVEL (1 << 10) /* Bit 10: 1=Level (vs edge) */ -#define _GPIO_INT_HIGH (1 << 9) /* Bit 9: 1=High level or rising edge */ -#define _GPIO_INT_LOW (1 << 8) /* Bit 8: 1=Low level or falling edge */ +#define _GPIO_INT_EDGE (1 << 10) /* Bit 10: 1=Edge (vs level) */ +#define _GPIO_INT_LOW (1 << 9) /* Bit 9: 1=Low level or falling edge */ +#define _GPIO_INT_HIGH (1 << 8) /* Bit 8: 1=High level or rising edge */ #define GPIO_INT_SHIFT (8) /* Bits 8-10: Interrupt mode */ #define GPIO_INT_MASK (7 << GPIO_INT_SHIFT) @@ -176,8 +176,8 @@ #define GPIO_IS_ACTIVE_HI(p) (((p) & _GPIO_INT_HIGH) != 0) #define GPIO_IS_ACTIVE_LOW(p) (((p) & _GPIO_INT_LOW) != 0) -#define GPIO_IS_EDGE(p) (((p) & _GPIO_INT_LEVEL) == 0) -#define GPIO_IS_LEVEL(p) (((p) & _GPIO_INT_LEVEL) != 0) +#define GPIO_IS_LEVEL(p) (((p) & _GPIO_INT_EDGE) == 0) +#define GPIO_IS_EDGE(p) (((p) & _GPIO_INT_EDGE) != 0) /* GPIO Port Number: * diff --git a/arch/arm/src/lpc43xx/lpc43_gpioint.c b/arch/arm/src/lpc43xx/lpc43_gpioint.c index 51e010ba33..029e2aec20 100644 --- a/arch/arm/src/lpc43xx/lpc43_gpioint.c +++ b/arch/arm/src/lpc43xx/lpc43_gpioint.c @@ -57,6 +57,7 @@ #include #include +#include #include @@ -176,7 +177,7 @@ int lpc43_gpioint_grpinitialize(int group, bool anded, bool level) int lpc43_gpioint_pinconfig(uint16_t gpiocfg) { unsigned int port = ((gpiocfg & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); - unsigned int pin = ((gpiocfg & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); + unsigned int pin = ((gpiocfg & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); unsigned int pinint = ((gpiocfg & GPIO_PININT_MASK) >> GPIO_PININT_SHIFT); uint32_t bitmask = (1 << pinint); uint32_t regval; @@ -227,6 +228,8 @@ int lpc43_gpioint_pinconfig(uint16_t gpiocfg) /* Configure the active high level or rising edge */ + /* TODO: this works for edge sensitive, but not level sensitive, active level is only controlled in IENF */ + regval = getreg32(LPC43_GPIOINT_IENR); if (GPIO_IS_ACTIVE_HI(gpiocfg)) { @@ -321,4 +324,28 @@ int lpc43_gpioint_grpconfig(uint16_t gpiocfg) return OK; } +/**************************************************************************** + * Name: lpc43_gpioint_ack + * + * Description: + * Acknowledge the interrupt for a given pint interrupt number. Call this + * inside the interrupt handler. For edge sensitive interrupts, the interrupt + * status is cleared. For level sensitive interrupts, the active-high/-low + * sensitivity is inverted. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int lpc43_gpioint_ack(uint8_t intnumber) +{ + uint32_t regval; + + regval = getreg32(LPC43_GPIOINT_IST); + regval |= (1 << intnumber); + putreg32(regval, LPC43_GPIOINT_IST); + return OK; +} + #endif /* CONFIG_GPIO_IRQ */ diff --git a/arch/arm/src/lpc43xx/lpc43_gpioint.h b/arch/arm/src/lpc43xx/lpc43_gpioint.h index 35b22f7c7f..ec34649455 100644 --- a/arch/arm/src/lpc43xx/lpc43_gpioint.h +++ b/arch/arm/src/lpc43xx/lpc43_gpioint.h @@ -136,5 +136,21 @@ int lpc43_gpioint_pinconfig(uint16_t gpiocfg); int lpc43_gpioint_grpconfig(uint16_t gpiocfg); +/**************************************************************************** + * Name: lpc43_gpioint_ack + * + * Description: + * Acknowledge the interrupt for a given pint interrupt number. Call this + * inside the interrupt handler. For edge sensitive interrupts, the interrupt + * status is cleared. For level sensitive interrupts, the active-high/-low + * sensitivity is inverted. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int lpc43_gpioint_ack(uint8_t intnumber); + #endif /* CONFIG_GPIO_IRQ */ #endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_GPIOINT_H */