From 1c4d0686c8d6a881c8ae2c3574b80e5faea79b79 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 4 Jun 2016 16:05:36 -0600 Subject: [PATCH] LPC43xx: Fill out some missing GPIO interrupt logic --- arch/arm/src/lpc43xx/Kconfig | 13 +++--- arch/arm/src/lpc43xx/lpc43_gpioint.c | 68 ++++++++++++++++++---------- 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/arch/arm/src/lpc43xx/Kconfig b/arch/arm/src/lpc43xx/Kconfig index d29fe32781..9a2bcad916 100644 --- a/arch/arm/src/lpc43xx/Kconfig +++ b/arch/arm/src/lpc43xx/Kconfig @@ -150,13 +150,6 @@ endchoice # LPC43XX Boot Configuration menu "LPC43xx Peripheral Support" - -config LPC43_GPIO_IRQ - bool "GPIO interrupt support" - default n - ---help--- - Enable support for GPIO interrupts - config LPC43_ADC0 bool "ADC0" default n @@ -321,6 +314,12 @@ config LPC43_WWDT endmenu # LPC43xx Peripheral Support +config LPC43_GPIO_IRQ + bool "GPIO interrupt support" + default n + ---help--- + Enable support for GPIO interrupts + if LPC43_ETHERNET menu "Ethernet MAC configuration" diff --git a/arch/arm/src/lpc43xx/lpc43_gpioint.c b/arch/arm/src/lpc43xx/lpc43_gpioint.c index 39d664aabe..328a62c85c 100644 --- a/arch/arm/src/lpc43xx/lpc43_gpioint.c +++ b/arch/arm/src/lpc43xx/lpc43_gpioint.c @@ -181,6 +181,9 @@ int lpc43_gpioint_pinconfig(uint16_t gpiocfg) unsigned int pinint = ((gpiocfg & GPIO_PININT_MASK) >> GPIO_PININT_SHIFT); uint32_t bitmask = (1 << pinint); uint32_t regval; + uint32_t isel; + uint32_t einr; + uint32_t einf; DEBUGASSERT(port < NUM_GPIO_PORTS && pin < NUM_GPIO_PINS && GPIO_IS_PININT(gpiocfg)); @@ -226,37 +229,54 @@ int lpc43_gpioint_pinconfig(uint16_t gpiocfg) putreg32(regval, LPC43_GPIOINT_ISEL); - /* Configure the active high level or rising edge + /* Configure the active level or rising/falling edge * - * TODO: this works for edge sensitive, but not level sensitive, active - * level is only controlled in IENF. + * ISEL + * 0 = Edge sensitive + * 1 = Level sensitive + * EINR 0-7: + * 0 = Disable rising edge or level interrupt. + * 1 = Enable rising edge or level interrupt. + * EINF 0-7: + * 0 = Disable falling edge interrupt or set active interrupt level + * LOW. + * 1 = Enable falling edge interrupt enabled or set active interrupt + * level HIGH */ - regval = getreg32(LPC43_GPIOINT_IENR); - if (GPIO_IS_ACTIVE_HI(gpiocfg)) + isel = getreg32(LPC43_GPIOINT_ISEL) & ~bitmask; + einr = getreg32(LPC43_GPIOINT_IENR) & ~bitmask; + einf = getreg32(LPC43_GPIOINT_IENF) & ~bitmask; + + switch (gpiocfg & GPIO_INT_MASK) { - regval |= bitmask; - } - else - { - regval &= ~bitmask; + case GPIO_INT_LEVEL_HI: + einf |= bitmask; /* Enable active level HI */ + case GPIO_INT_LEVEL_LOW: + isel |= bitmask; /* Level sensitive */ + einr |= bitmask; /* Enable level interrupt */ + break; + + case GPIO_INT_EDGE_RISING: + einr |= bitmask; /* Enable rising edge interrupt */ + break; + + case GPIO_INT_EDGE_BOTH: + einr |= bitmask; /* Enable rising edge interrupt */ + case GPIO_INT_EDGE_FALLING: + einf |= bitmask; /* Enable falling edge interrupt */ + break; + + /* Default is edge sensitive but with both edges disabled. */ + + default: + break; } - putreg32(regval, LPC43_GPIOINT_IENR); + putreg32(isel, LPC43_GPIOINT_ISEL); + putreg32(einr, LPC43_GPIOINT_IENR); + putreg32(einf, LPC43_GPIOINT_IENF); - /* Configure the active high low or falling edge */ - - regval = getreg32(LPC43_GPIOINT_IENF); - if (GPIO_IS_ACTIVE_LOW(gpiocfg)) - { - regval |= bitmask; - } - else - { - regval &= ~bitmask; - } - - putreg32(regval, LPC43_GPIOINT_IENF); return OK; }