input: STMPE811 GPIO interrupt bug fixes

This patch resolves to bugs in the GPIO interrupt logic:

1. Any pins did not have STMPE811_GPIO_RISING in their pincfg
   would clear the rising edge interrupt enable flag for all
   pins due to a masking bug.

2. Pins would never trigger a second interrupt.  There is an
   undocumented requirement that you have to clear both the
   GPIO interrupt status register __and__ also the edge
   detection status register.  Failure to clear either of
   these will result in no further interrupts being triggered.
   This requirement exists both for edge and level modes of
   operation.

Signed-off-by: Brennan Ashton <bashton@brennanashton.com>
This commit is contained in:
Brennan Ashton 2020-09-17 18:31:00 -07:00 committed by Xiang Xiao
parent 2731ab5c19
commit 7554eedf9a
2 changed files with 12 additions and 4 deletions

View File

@ -93,7 +93,6 @@ static void stmpe811_worker(FAR void *arg)
/* Get the global interrupt status */ /* Get the global interrupt status */
regval = stmpe811_getreg8(priv, STMPE811_INT_EN);
regval = stmpe811_getreg8(priv, STMPE811_INT_STA); regval = stmpe811_getreg8(priv, STMPE811_INT_STA);
/* Check for a touchscreen interrupt */ /* Check for a touchscreen interrupt */

View File

@ -194,7 +194,7 @@ int stmpe811_gpioconfig(STMPE811_HANDLE handle, uint8_t pinconfig)
} }
else else
{ {
regval &= pinmask; regval &= ~pinmask;
} }
stmpe811_putreg8(priv, STMPE811_GPIO_FE, regval); stmpe811_putreg8(priv, STMPE811_GPIO_FE, regval);
@ -202,13 +202,13 @@ int stmpe811_gpioconfig(STMPE811_HANDLE handle, uint8_t pinconfig)
/* Set up the rising edge detection */ /* Set up the rising edge detection */
regval = stmpe811_getreg8(priv, STMPE811_GPIO_RE); regval = stmpe811_getreg8(priv, STMPE811_GPIO_RE);
if ((pinconfig & STMPE811_GPIO_FALLING) != 0) if ((pinconfig & STMPE811_GPIO_RISING) != 0)
{ {
regval |= pinmask; regval |= pinmask;
} }
else else
{ {
regval &= pinmask; regval &= ~pinmask;
} }
stmpe811_putreg8(priv, STMPE811_GPIO_RE, regval); stmpe811_putreg8(priv, STMPE811_GPIO_RE, regval);
@ -443,6 +443,15 @@ void stmpe811_gpioworker(FAR struct stmpe811_dev_s *priv)
*/ */
stmpe811_putreg8(priv, STMPE811_GPIO_INTSTA, pinmask); stmpe811_putreg8(priv, STMPE811_GPIO_INTSTA, pinmask);
/* Must also clear the edge detection status bit
* this is _not documented_ as being required but is used in
* the SDK and without it a second interrupt will never trigger.
* Yep you have to "clear" _both_ the edge detection status and
* GPIO interrupt status register even in level mode.
*/
stmpe811_putreg8(priv, STMPE811_GPIO_ED, pinmask);
} }
} }
} }