From 1f9799b68da9abaef19f7a9489e5bbd7acf58aae Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 3 Aug 2016 13:10:20 -0600 Subject: [PATCH] I/O Expanders: Interrupt detection logic should not ignore the no-change case. Still need to handle level interrupts even with no change. --- arch/sim/src/up_ioexpander.c | 14 +++++--------- drivers/ioexpander/pcf8574.c | 12 ++---------- drivers/ioexpander/tca64xx.c | 15 +++------------ 3 files changed, 10 insertions(+), 31 deletions(-) diff --git a/arch/sim/src/up_ioexpander.c b/arch/sim/src/up_ioexpander.c index 393fdd06e6..8eec0f9040 100644 --- a/arch/sim/src/up_ioexpander.c +++ b/arch/sim/src/up_ioexpander.c @@ -641,17 +641,13 @@ static ioe_pinset_t sim_int_update(FAR struct sim_dev_s *priv) input = priv->inval; diff = priv->last ^ input; - if (diff == 0) + if (diff != 0) { - /* Nothing has changed */ - - return 0; + gpioinfo("toggles=%lx inval=%lx last=%lx diff=%lx\n", + (unsigned long)toggles, (unsigned long)priv->inval, + (unsigned long)priv->last, (unsigned long)diff); } - gpioinfo("toggles=%lx inval=%lx last=%lx diff=%lx\n", - (unsigned long)toggles, (unsigned long)priv->inval, - (unsigned long)priv->last, (unsigned long)diff); - priv->last = input; intstat = 0; @@ -684,7 +680,7 @@ static ioe_pinset_t sim_int_update(FAR struct sim_dev_s *priv) } else /* if (SIM_LEVEL_SENSITIVE(priv, pin)) */ { - /* Level triggered. Set intstat if in match level type. */ + /* Level triggered. Set intstat if imatch in level type. */ if ((pinval && SIM_LEVEL_HIGH(priv, pin)) || (!pinval && SIM_LEVEL_LOW(priv, pin))) diff --git a/drivers/ioexpander/pcf8574.c b/drivers/ioexpander/pcf8574.c index f28c2c9fff..b8eee535b9 100644 --- a/drivers/ioexpander/pcf8574.c +++ b/drivers/ioexpander/pcf8574.c @@ -797,15 +797,7 @@ static void pcf8574_int_update(void *handle, uint8_t input) /* Check the changed bits from last read */ - diff = priv->input ^ input; - if (diff == 0) - { - /* Nothing has changed */ - - leave_critical_section(flags); - return; - } - + diff = priv->input ^ input; priv->input = input; /* PCF8574 doesn't support irq trigger, we have to do this in software. */ @@ -829,7 +821,7 @@ static void pcf8574_int_update(void *handle, uint8_t input) } else /* if (PCF8574_LEVEL_SENSITIVE(priv, pin)) */ { - /* Level triggered. Set intstat if in match level type. */ + /* Level triggered. Set intstat if match in level type. */ if (((input & 1) != 0 && PCF8574_LEVEL_HIGH(priv, pin)) || ((input & 1) == 0 && PCF8574_LEVEL_LOW(priv, pin))) diff --git a/drivers/ioexpander/tca64xx.c b/drivers/ioexpander/tca64xx.c index 49b57ddbb4..2b3b00cf05 100644 --- a/drivers/ioexpander/tca64xx.c +++ b/drivers/ioexpander/tca64xx.c @@ -1038,17 +1038,8 @@ static void tca64_int_update(FAR struct tca64_dev_s *priv, ioe_pinset_t input, /* Check the changed bits from last read */ - input = (priv->input & ~mask) | (input & mask); - diff = priv->input ^ input; - - if (diff == 0) - { - /* Nothing has changed */ - - leave_critical_section(flags); - return; - } - + input = (priv->input & ~mask) | (input & mask); + diff = priv->input ^ input; priv->input = input; /* TCA64XX doesn't support irq trigger, we have to do this in software. */ @@ -1072,7 +1063,7 @@ static void tca64_int_update(FAR struct tca64_dev_s *priv, ioe_pinset_t input, } else /* if (TCA64_LEVEL_SENSITIVE(priv, pin)) */ { - /* Level triggered. Set intstat if in match level type. */ + /* Level triggered. Set intstat bit if match in level type. */ if (((input & 1) != 0 && TCA64_LEVEL_HIGH(priv, pin)) || ((input & 1) == 0 && TCA64_LEVEL_LOW(priv, pin)))