Skip to content

Commit

Permalink
drivers/stmpe811: introduce coordinate conversion
Browse files Browse the repository at this point in the history
To obtain coordinates from the touch panel that correspond to the display coordinates, it is often necessary to convert the coordinates from the touch display by swapping and mirroring. For the sake of simplicity, possible rotations are additionally defined.
  • Loading branch information
gschorcht committed Aug 14, 2023
1 parent 91441db commit 353b815
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 10 deletions.
1 change: 1 addition & 0 deletions dist/tools/doccheck/exclude_simple
Original file line number Diff line number Diff line change
Expand Up @@ -6668,6 +6668,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.
Expand Down
10 changes: 10 additions & 0 deletions drivers/include/stmpe811.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ typedef void (*stmpe811_event_cb_t)(void *arg);

/**
* @brief Device initialization parameters
*
* note If @ref STMPE811_SWAP_XY is used for the conversion in
* stmpe811_params_t::xyconv, the resulting maximum X and Y coordinates
* do not correspond to the parameters stmpe811_params_t::xmax and
* stmpe811_params_t::ymax defined for the touch panel, respectively.
* Instead, the X coordinate then is in the range from 0 to
* stmpe811_params_t::ymax and the Y coordinate then is in the range
* from 0 to stmpe811_params_t::xmax.
*/
typedef struct {
#if IS_USED(MODULE_STMPE811_SPI)
Expand All @@ -78,6 +86,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 */
uint8_t xyconv; /**< Touch screen coordinates conversion,
mirroring is applied before swapping */
} stmpe811_params_t;

/**
Expand Down
32 changes: 32 additions & 0 deletions drivers/stmpe811/include/stmpe811_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,38 @@ extern "C" {

#define STMPE811_CHIP_ID_VALUE (0x0811) /**< Chip ID */

/**
* @name Touch screen orientation flags
*
* The swap flag is applied before the mirror flags.
*
* @warning If @ref STMPE811_SWAP_XY is used for the conversion, the resulting
* maximum X and Y coordinates do not correspond to the parameters
* stmpe811_params_t::xmax and stmpe811_params_t::ymax defined for
* the touch panel, respectively. Instead, the X coordinate then is
* in the range from 0 to stmpe811_params_t::ymax and the Y coordinate
* then is in the range from 0 to stmpe811_params_t::xmax.
*
* @{
*/
#define STMPE811_NO_CONV (0x00) /**< No conversion */
#define STMPE811_MIRROR_X (0x01) /**< Mirror X */
#define STMPE811_MIRROR_Y (0x02) /**< Mirror Y */
#define STMPE811_SWAP_XY (0x04) /**< Swap XY, the relation to the maximum
coordinates changes */

/** No rotation */
#define STMPE811_ROTATE_0 (STMPE811_MIRROR_X)
/** Rotate the coordinates 90 degrees counterclockwise, the relation to
* the maximum coordinates changes */
#define STMPE811_ROTATE_90 (STMPE811_MIRROR_X | STMPE811_MIRROR_Y | STMPE811_SWAP_XY)
/** Rotate the coordinates 180 degrees */
#define STMPE811_ROTATE_180 (STMPE811_MIRROR_Y)
/** Rotate the coordinates 270 degrees counterclockwise, the relation to
* the maximum coordinates changes. */
#define STMPE811_ROTATE_270 (STMPE811_SWAP_XY)
/** @} */

/**
* @name Registers
* @{
Expand Down
9 changes: 7 additions & 2 deletions drivers/stmpe811/include/stmpe811_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ extern "C" {
#ifndef STMPE811_PARAM_YMAX
#define STMPE811_PARAM_YMAX (320U)
#endif
#ifndef STMPE811_PARAM_XYCONV
#define STMPE811_PARAM_XYCONV (STMPE811_ROTATE_90)
#endif

#ifndef STMPE811_PARAMS
#if IS_USED(MODULE_STMPE811_SPI)
Expand All @@ -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
/**@}*/
Expand Down
18 changes: 15 additions & 3 deletions drivers/stmpe811/stmpe811.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
#define ADDR (dev->params.addr)
#endif


#if IS_USED(MODULE_STMPE811_SPI) /* using SPI mode */
static inline void _acquire(const stmpe811_t *dev)
{
Expand Down Expand Up @@ -377,8 +376,21 @@ int stmpe811_read_touch_position(stmpe811_t *dev, stmpe811_touch_position_t *pos

dev->prev_x = tmp_x;
dev->prev_y = tmp_y;
position->x = tmp_x;
position->y = tmp_y;

if (dev->params.xyconv & STMPE811_MIRROR_X) {
tmp_x = dev->params.xmax - tmp_x;
}
if (dev->params.xyconv & STMPE811_MIRROR_Y) {
tmp_y = dev->params.ymax - tmp_y;
}
if (dev->params.xyconv & STMPE811_SWAP_XY) {
position->x = tmp_y;
position->y = tmp_x;
}
else {
position->x = tmp_x;
position->y = tmp_y;
}

return 0;
}
Expand Down
7 changes: 2 additions & 5 deletions drivers/stmpe811/stmpe811_touch_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit 353b815

Please sign in to comment.