diff --git a/dist/tools/doccheck/exclude_simple b/dist/tools/doccheck/exclude_simple index ecdc91e14b..2a7a1eff3f 100644 --- a/dist/tools/doccheck/exclude_simple +++ b/dist/tools/doccheck/exclude_simple @@ -6669,6 +6669,7 @@ warning: Member STMPE811_PARAM_INT_PIN (macro definition) of file stmpe811_param warning: Member STMPE811_PARAMS (macro definition) of file stmpe811_params.h is not documented. warning: Member STMPE811_PARAM_XMAX (macro definition) of file stmpe811_params.h is not documented. warning: Member STMPE811_PARAM_YMAX (macro definition) of file stmpe811_params.h is not documented. +warning: Member STMPE811_PARAM_XYCONV (macro definition) of file stmpe811_params.h is not documented. warning: Member suit_parameter_t (enumeration) of group sys_suit is not documented. warning: Member _SV(elt, list) (macro definition) of group sys_ut is not documented. warning: Member SX126X_PARAM_BUSY (macro definition) of file sx126x_params.h is not documented. diff --git a/drivers/include/stmpe811.h b/drivers/include/stmpe811.h index 9d08a7ad59..c60f03a4eb 100644 --- a/drivers/include/stmpe811.h +++ b/drivers/include/stmpe811.h @@ -45,6 +45,26 @@ typedef enum { STMPE811_TOUCH_STATE_RELEASED, /**< Touchscreen is released */ } stmpe811_touch_state_t; +/** + * @brief Touch screen coordinate conversions + * + * Normally the coordinates of the touch device must be converted to the + * screen coordinates by swapping and/or mirroring. The flags defined by + * this enumeration can be ORed for a combined conversion. In this case, + * the swapping is performed before the mirroring. + * + * @note The maximum X and Y screen coordinates defined by + * @ref stmpe811_params_t::xmax and @ref stmpe811_params_t::ymax + * define the dimension of the touch device in screen coordinates, + * i.e. after conversion. + */ +typedef enum { + STMPE811_NO_CONV = 0x00, /**< No conversion */ + STMPE811_MIRROR_X = 0x01, /**< Mirror X, applied after optional swapping */ + STMPE811_MIRROR_Y = 0x02, /**< Mirror Y, applied after optional swapping */ + STMPE811_SWAP_XY = 0x04, /**< Swap XY, applied before optional mirroring */ +} stmpe811_touch_conv_t; + /** * @brief Touch position structure */ @@ -62,6 +82,10 @@ typedef void (*stmpe811_event_cb_t)(void *arg); /** * @brief Device initialization parameters + * + * @note stmpe811_params_t::xmax and stmpe811_params_t::ymax define the + * maximum X and Y values in screen coordinates after the optional + * conversion defined by stmpe811_params_t::xmax. */ typedef struct { #if IS_USED(MODULE_STMPE811_SPI) @@ -78,6 +102,8 @@ typedef struct { gpio_t int_pin; /**< Touch screen interrupt pin */ uint16_t xmax; /**< Touch screen max X position */ uint16_t ymax; /**< Touch screen max Y position */ + stmpe811_touch_conv_t xyconv; /**< Touch screen coordinates conversion, + swapping is applied before mirroring */ } stmpe811_params_t; /** diff --git a/drivers/stmpe811/include/stmpe811_params.h b/drivers/stmpe811/include/stmpe811_params.h index 975f2f9a50..9a075a3563 100644 --- a/drivers/stmpe811/include/stmpe811_params.h +++ b/drivers/stmpe811/include/stmpe811_params.h @@ -59,10 +59,13 @@ extern "C" { #define STMPE811_PARAM_INT_PIN GPIO_PIN(0, 15) #endif #ifndef STMPE811_PARAM_XMAX -#define STMPE811_PARAM_XMAX (240U) +#define STMPE811_PARAM_XMAX (320U) #endif #ifndef STMPE811_PARAM_YMAX -#define STMPE811_PARAM_YMAX (320U) +#define STMPE811_PARAM_YMAX (240U) +#endif +#ifndef STMPE811_PARAM_XYCONV +#define STMPE811_PARAM_XYCONV (STMPE811_MIRROR_X | STMPE811_MIRROR_Y | STMPE811_SWAP_XY) #endif #ifndef STMPE811_PARAMS @@ -73,14 +76,16 @@ extern "C" { .int_pin = STMPE811_PARAM_INT_PIN, \ .xmax = STMPE811_PARAM_XMAX, \ .ymax = STMPE811_PARAM_YMAX, \ - } + .xyconv = STMPE811_PARAM_XYCONV, \ + } #else #define STMPE811_PARAMS { .i2c = STMPE811_PARAM_I2C_DEV, \ .addr = STMPE811_PARAM_ADDR, \ .int_pin = STMPE811_PARAM_INT_PIN, \ .xmax = STMPE811_PARAM_XMAX, \ .ymax = STMPE811_PARAM_YMAX, \ - } + .xyconv = STMPE811_PARAM_XYCONV, \ + } #endif #endif /**@}*/ diff --git a/drivers/stmpe811/stmpe811.c b/drivers/stmpe811/stmpe811.c index 549e12dc92..f67fc6e657 100644 --- a/drivers/stmpe811/stmpe811.c +++ b/drivers/stmpe811/stmpe811.c @@ -383,8 +383,21 @@ int stmpe811_read_touch_position(stmpe811_t *dev, stmpe811_touch_position_t *pos /* Y value second correction */ tmp_y /= 11; + /* maximum values in device coordinates */ + uint16_t tmp_xmax; + uint16_t tmp_ymax; + + if (dev->params.xyconv & STMPE811_SWAP_XY) { + tmp_xmax = dev->params.ymax; + tmp_ymax = dev->params.xmax; + } + else { + tmp_xmax = dev->params.xmax; + tmp_ymax = dev->params.ymax; + } + /* clamp y position */ - if (tmp_y > dev->params.ymax) { + if (tmp_y > tmp_ymax) { tmp_y = dev->prev_y; } @@ -400,14 +413,30 @@ int stmpe811_read_touch_position(stmpe811_t *dev, stmpe811_touch_position_t *pos tmp_x /= 15; /* clamp x position */ - if (tmp_x > dev->params.xmax) { + if (tmp_x > tmp_xmax) { tmp_x = dev->prev_x; } dev->prev_x = tmp_x; dev->prev_y = tmp_y; - position->x = tmp_x; - position->y = tmp_y; + + /* conversion to screen coordinates */ + if (dev->params.xyconv & STMPE811_SWAP_XY) { + position->x = tmp_y; + position->y = tmp_x; + } + else { + position->x = tmp_x; + position->y = tmp_y; + } + if (dev->params.xyconv & STMPE811_MIRROR_X) { + assert(position->x <= dev->params.xmax); + position->x = dev->params.xmax - position->x; + } + if (dev->params.xyconv & STMPE811_MIRROR_Y) { + assert(position->y <= dev->params.ymax); + position->y = dev->params.ymax - position->y; + } return 0; } diff --git a/drivers/stmpe811/stmpe811_touch_dev.c b/drivers/stmpe811/stmpe811_touch_dev.c index 68bdec68e8..f5c4bb5f5b 100644 --- a/drivers/stmpe811/stmpe811_touch_dev.c +++ b/drivers/stmpe811/stmpe811_touch_dev.c @@ -61,11 +61,8 @@ uint8_t _stmpe811_touches(const touch_dev_t *touch_dev, touch_t *touches, size_t if (ret && touches != NULL) { stmpe811_touch_position_t pos; stmpe811_read_touch_position(dev, &pos); - /* STMPE811 driver returns the position with origin at the bottom left - corner and portrait orientation, so convert them to use top left corner - as origin and landscape orientation. */ - touches[0].x = pos.y; - touches[0].y = dev->params.xmax - pos.x; + touches[0].x = pos.x; + touches[0].y = pos.y; DEBUG("X: %i, Y: %i\n", touches[0].x, touches[0].y); }