From 34619e55a672b1dcc0f536d8d4bc1ad2ffe77e98 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); + } + } + } }