STMPE610: Detect TOUCH_DOWN w/o TOUCH_UP, which happens with very short touch durations. If detected, resend the TOUCH_UP event

This commit is contained in:
Pim van Pelt
2017-11-26 22:41:31 +01:00
parent ed9906a0bf
commit 5f10481fb7

View File

@ -15,6 +15,10 @@
#define SPI_BUS VSPI_HOST #define SPI_BUS VSPI_HOST
#define STMPE_SPI_MODE 1 #define STMPE_SPI_MODE 1
struct mgos_stmpe610_event_data s_last_touch;
static spi_lobo_device_handle_t s_stmpe610_spi = NULL; static spi_lobo_device_handle_t s_stmpe610_spi = NULL;
static mgos_stmpe610_event_t s_event_handler = NULL; static mgos_stmpe610_event_t s_event_handler = NULL;
static enum mgos_stmpe610_rotation_t s_rotation = STMPE610_PORTRAIT; static enum mgos_stmpe610_rotation_t s_rotation = STMPE610_PORTRAIT;
@ -145,6 +149,26 @@ static void stmpe610_map_rotation(uint16_t x, uint16_t y, uint16_t *x_out, uint1
} }
} }
/* Each time a TOUCH_DOWN event occurs, s_last_touch is populated
and a timer is started. When the timer fires, we checke to see
if we've sent a TOUCH_UP event already. If not, we may still be
pressing the screen. IF we're not pressing the screen STMP610
bufferLength() will be 0. We've now detected a DOWN without a
corresponding UP, so we send it ourselves.
*/
static void stmpe610_down_cb(void *arg) {
if (s_last_touch.direction == TOUCH_UP)
return;
if (stmpe610_bufferLength() > 0)
return;
s_last_touch.direction=TOUCH_UP;
if (s_event_handler) {
LOG(LL_INFO, ("Touch DOWN not followed by UP -- sending phantom UP"));
s_event_handler(&s_last_touch);
}
}
static void stmpe610_irq(int pin, void *arg) { static void stmpe610_irq(int pin, void *arg) {
struct mgos_stmpe610_event_data ed; struct mgos_stmpe610_event_data ed;
uint16_t x, y; uint16_t x, y;
@ -164,6 +188,9 @@ static void stmpe610_irq(int pin, void *arg) {
ed.direction = TOUCH_DOWN; ed.direction = TOUCH_DOWN;
stmpe610_map_rotation(x, y, &ed.x, &ed.y); stmpe610_map_rotation(x, y, &ed.x, &ed.y);
ed.z = z; ed.z = z;
// To avoid DOWN events without an UP event, set a timer (see stmpe610_down_cb for details)
memcpy((void *)&s_last_touch, (void *)&ed, sizeof(s_last_touch));
mgos_set_timer(100, 0, stmpe610_down_cb, NULL);
if (s_event_handler) if (s_event_handler)
s_event_handler(&ed); s_event_handler(&ed);
break; break;
@ -178,6 +205,7 @@ static void stmpe610_irq(int pin, void *arg) {
ed.direction = TOUCH_UP; ed.direction = TOUCH_UP;
stmpe610_map_rotation(x, y, &ed.x, &ed.y); stmpe610_map_rotation(x, y, &ed.x, &ed.y);
ed.z = z; ed.z = z;
memcpy((void *)&s_last_touch, (void *)&ed, sizeof(s_last_touch));
if (s_event_handler) if (s_event_handler)
s_event_handler(&ed); s_event_handler(&ed);