diff --git a/drivers/stmpe811/stmpe811.c b/drivers/stmpe811/stmpe811.c index fb5aa73f50..ed0b0939a1 100644 --- a/drivers/stmpe811/stmpe811.c +++ b/drivers/stmpe811/stmpe811.c @@ -46,6 +46,23 @@ #define ADDR (dev->params.addr) #endif +#ifndef STMPE811_FIFO_THRESHOLD_ENABLED +#define STMPE811_FIFO_THRESHOLD_ENABLED (0) +#endif + +/* The driver only works reliably with FIFO threshold interrupts if the FIFO + * threshold is at least 2. The reason is that all interrupts are cleared when + * the status is checked in `stmpe811_read_touch_state` but the FIFO Threshold + * interrupt is asserted again immediately since the FIFO is not read so that + * a new interrupt is pending. On the other hand, the Touch Detected interrupt + * does not work reliably for the release event if only the Touch Detected + * interrupt in `stmpe811_read_touch_state` is cleared. The workaround is + * to set the FIFO threshold to at least 2 to introduce a small delay between + * the Touch Detect interrupt on a touch and the first FIFO threshold + * interrupt. */ +#ifndef STMPE811_FIFO_THRESHOLD +#define STMPE811_FIFO_THRESHOLD (STMPE811_FIFO_THRESHOLD_ENABLED ? 2 : 1) +#endif #if IS_USED(MODULE_STMPE811_SPI) /* using SPI mode */ static inline void _acquire(const stmpe811_t *dev) @@ -194,7 +211,7 @@ int stmpe811_init(stmpe811_t *dev, const stmpe811_params_t *params, stmpe811_eve } /* check mode configuration */ - if(_stmpe811_check_mode(dev) != 0) { + if (_stmpe811_check_mode(dev) != 0) { DEBUG("[stmpe811] error: couldn't setup SPI\n"); return -EIO; } @@ -257,7 +274,7 @@ int stmpe811_init(stmpe811_t *dev, const stmpe811_params_t *params, stmpe811_eve ret += _write_reg(dev, STMPE811_TSC_CFG, reg); /* set fifo threshold */ - ret += _write_reg(dev, STMPE811_FIFO_TH, 0x01); + ret += _write_reg(dev, STMPE811_FIFO_TH, STMPE811_FIFO_THRESHOLD); /* reset fifo */ _reset_fifo(dev); @@ -285,7 +302,9 @@ int stmpe811_init(stmpe811_t *dev, const stmpe811_params_t *params, stmpe811_eve gpio_init_int(dev->params.int_pin, GPIO_IN, GPIO_FALLING, cb, arg); /* Enable touchscreen interrupt */ - ret += _write_reg(dev, STMPE811_INT_EN, STMPE811_INT_EN_TOUCH_DET); + ret += _write_reg(dev, STMPE811_INT_EN, + STMPE811_INT_EN_TOUCH_DET | + (STMPE811_FIFO_THRESHOLD_ENABLED ? STMPE811_INT_EN_FIFO_TH : 0)); /* Enable global interrupt */ ret += _write_reg(dev, STMPE811_INT_CTRL,