Search by Tags

Touch Screen Calibration (Torizon)

 

Article updated at 30 Jun 2020
Subscribe for this article updates

Introduction

This article will show how you can calibrate a resistive touch screen under Weston on Torizon by using weston-touch-calibrator. Weston is started in a special mode where it exposes the calibration API. Therefore, a separate container is used. See the man page of weston.ini for more information.

This article complies to the Typographic Conventions for Torizon Documentation

Prerequisites

Calibration

As a first step, all running containers need to be stopped. You can achieve that by running the following command:

# docker stop $(docker ps -q)

Then you need to start the weston-touch-calibrator container. Choose instructions for your SoM from the tabs below:

# docker run -ti --rm --privileged -v /dev:/dev -v /run/udev/:/run/udev/ -v /etc/udev/rules.d:/etc/udev/rules.d torizon/arm32v7-debian-weston-touch-calibrator
# docker run -ti --rm --privileged -v /dev:/dev -v /run/udev/:/run/udev/ -v /etc/udev/rules.d:/etc/udev/rules.d -e ACCEPT_FSL_EULA=1 torizon/arm64v8-debian-weston-touch-calibrator

You should see a calibration screen on the display. When you touch all crosses the display should fall back to the Weston desktop. You can try to start a terminal since the calibration matrix should already be applied. After that, you can stop the container by pressing Ctrl+C and reboot the module. Afterward, Weston should automatically apply the new calibration matrix.

Background

Weston reads the calibration matrix of a touchscreen from the udev environment of the input device. You can check the environment by running the following command:

# udevadm info /dev/input/event1
P: /devices/platform/5a800000.i2c/i2c-16/16-002c/input/input1/event1
N: input/event1
L: 0
S: input/by-path/platform-5a800000.i2c-event
S: input/touchscreen0
E: DEVPATH=/devices/platform/5a800000.i2c/i2c-16/16-002c/input/input1/event1
E: DEVNAME=/dev/input/event1
E: MAJOR=13
E: MINOR=65
E: SUBSYSTEM=input
E: USEC_INITIALIZED=8598804
E: ID_INPUT=1
E: ID_INPUT_TOUCHSCREEN=1
E: ID_PATH=platform-5a800000.i2c
E: ID_PATH_TAG=platform-5a800000_i2c
E: LIBINPUT_CALIBRATION_MATRIX=1.039948 0.011494 -0.031650 0.009743 -1.089353 1.047852
E: DEVLINKS=/dev/input/by-path/platform-5a800000.i2c-event /dev/input/touchscreen0

Weston applies LIBINPUT_CALIBRATION_MATRIX to all input values of the touchscreen. The output after the transformation is the pixel position of where the touchscreen was pressed. The weston-touch-calibrator container creates a udev rule and stores it under /etc/udev/rules.d/touchscreen.rules. The rule corresponds to the last line in the following file:

# cat /etc/udev/rules.d/touchscreen.rules
# There are a number of modifiers that are allowed to be used in some
# of the different fields. They provide the following subsitutions:
#
# %n the "kernel number" of the device.
#    For example, 'sda3' has a "kernel number" of '3'
# %e the smallest number for that name which does not matches an existing node
# %k the kernel name for the device
# %M the kernel major number for the device
# %m the kernel minor number for the device
# %b the bus id for the device
# %c the string returned by the PROGRAM
# %s{filename} the content of a sysfs attribute
# %% the '%' char itself
#

# Create a symlink to any touchscreen input device
SUBSYSTEM=="input", KERNEL=="event[0-9]*", ATTRS{modalias}=="input:*-e0*,3,*a0,1,*18,*", SYMLINK+="input/touchscreen0"
SUBSYSTEM=="input", KERNEL=="event[0-9]*", ATTRS{modalias}=="ads7846", SYMLINK+="input/touchscreen0"
SUBSYSTEM=="input", KERNEL=="event[0-9]*", ENV{ID_INPUT_TOUCHSCREEN}=="1", ENV{LIBINPUT_CALIBRATION_MATRIX}="1.039948 0.011494 -0.031650 0.009743 -1.089353 1.047852"

Because /etc/udev/rules.d is mapped to the host system, the change made by the container will automatically apply to the host system as well.