From ecb444b9894f66da4cb87f1305825d18c180d142 Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Wed, 17 Jul 2019 15:18:59 -0500 Subject: [PATCH] MCUXpresso: Fix the LPC GPIO IRQ driver The IRQ disable was always disabling both rising and falling edges of the interrupt thereby causing failures in cases when one of the two should stay enabled. Signed-off-by: Mahesh Mahadevan --- .../TARGET_LPC/gpio_irq_api.c | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/gpio_irq_api.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/gpio_irq_api.c index 46cea7a73b..7a67048baa 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/gpio_irq_api.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/gpio_irq_api.c @@ -67,6 +67,13 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32 return -1; } + obj->pin = pin & 0x1F; + obj->port = pin / 32; + + if (obj->port >= INTERRUPT_PORTS) { + return -1; + } + irq_handler = handler; for (i = 0; i < NUMBER_OF_GPIO_INTS; i++) { @@ -82,13 +89,6 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32 return -1; } - obj->pin = pin & 0x1F; - obj->port = pin / 32; - - if (obj->port >= INTERRUPT_PORTS) { - return -1; - } - /* Connect trigger sources to PINT */ INPUTMUX_Init(INPUTMUX); @@ -139,7 +139,26 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) } } } else { - PINT_PinInterruptConfig(PINT, (pint_pin_int_t)obj->ch, kPINT_PinIntEnableNone, NULL); + if (event == IRQ_RISE) { + /* Checking if falling edge interrupt is already enabled on this pin */ + if (PINT->IENF & (1U << obj->ch)) { + /* Leave falling edge interrupt enabled */ + PINT_PinInterruptConfig(PINT, (pint_pin_int_t)obj->ch, kPINT_PinIntEnableFallEdge, pint_intr_callback); + } else { + /* Both rising and falling edge interrupt are disabled */ + PINT_PinInterruptConfig(PINT, (pint_pin_int_t)obj->ch, kPINT_PinIntEnableNone, pint_intr_callback); + } + } else { + /* Checking if rising edge interrupt is already enabled on this pin */ + if (PINT->IENR & (1U << obj->ch)) { + /* Leave rising edge interrupt enabled */ + PINT_PinInterruptConfig(PINT, (pint_pin_int_t)obj->ch, kPINT_PinIntEnableRiseEdge, pint_intr_callback); + } else { + /* Both rising and falling edge interrupt are disabled */ + PINT_PinInterruptConfig(PINT, (pint_pin_int_t)obj->ch, kPINT_PinIntEnableNone, pint_intr_callback); + } + } + } }