PDA

View Full Version : Jivelite : Supporting a new touchscreen



Learnincurve
2017-02-02, 01:31
Hi,

I bought a Pine64+ (allwinner A64) board and screen, knowing that this was not yet supported. The reasoning being that it is cheap and ticks a lot of the hardware boxes for a Squeezebox touch replacement with dedicated ethernet and USB ports/busses.

Armbian runs out of the box and supports the touchscreen (at least with legacy 3.10.104 kernel).

There is a are-compiled squeezelite in the Armbian repository and Jivelite compiles and runs without errors using
https://github.com/sindrom91/LuaJIT/tree/ARM64

Athough touch events work perfectly in Xfce, they are "all over the place" in Jivelite, so I'm trying to create a tslib/SDL calibration.


Just now I'm struggling with
"tslib: Selected device is not a touchscreen (must support ABS and KEY event types)"

Googling throws up one or two bits of advice, such as:

From http://http://www.cubieforums.com/index.php/topic,4008.0/prev_next,prev.html#new:

Check if input-raw.c has:
if ((ioctl(ts->fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit)) < 0 ||
!(absbit[BIT_WORD(ABS_X)] & BIT_MASK(ABS_X)) ||
!(absbit[BIT_WORD(ABS_Y)] & BIT_MASK(ABS_Y))) {
/*fprintf(stderr, "tslib: Selected device is not a touchscreen (must support ABS_X and ABS_Y events)\n");
return -1;*/
}

if not, edit the file and comment the lines."


and
from http://stackoverflow.com/questions/11937287/touchscreen-and-driver-installed-but-tslib-cannot-calibrate:


Try to add

input_dev = input_allocate_device();
[..]
set_bit(EV_ABS, input_dev->evbit);
set_bit(EV_KEY, input_dev->evbit);
So that the tslib sees the device as supporting both EV_ABS and EV_KEY events (even if it does not actually send both of those).


(I'm assuming this should also be in input-raw.c)

If I look at my own input-raw.c, I see:


static int check_fd(struct tslib_input *i)
{
struct tsdev *ts = i->module.dev;
int version;
long evbit[BITS_TO_LONGS(EV_CNT)];
long absbit[BITS_TO_LONGS(ABS_CNT)];
long keybit[BITS_TO_LONGS(KEY_CNT)];
long synbit[BITS_TO_LONGS(SYN_CNT)];

if (ioctl(ts->fd, EVIOCGVERSION, &version) < 0) {
fprintf(stderr, "tslib: Selected device is not a Linux input event device\n");
return -1;
}

/* support version EV_VERSION 0x010000 and 0x010001
* this check causes more troubles than it solves here */
if (version < EV_VERSION)
fprintf(stderr, "tslib: Warning: Selected device uses a different version of the event protocol than tslib was compiled for\n");

if ( (ioctl(ts->fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
!(evbit[BIT_WORD(EV_ABS)] & BIT_MASK(EV_ABS)) ||
!(evbit[BIT_WORD(EV_KEY)] & BIT_MASK(EV_KEY)) ) {
fprintf(stderr, "tslib: Selected device is not a touchscreen (must support ABS and KEY event types)\n");
return -1;
}

if ((ioctl(ts->fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit)) < 0 ||
!(absbit[BIT_WORD(ABS_X)] & BIT_MASK(ABS_X)) ||
!(absbit[BIT_WORD(ABS_Y)] & BIT_MASK(ABS_Y))) {
if (!(absbit[BIT_WORD(ABS_MT_POSITION_X)] & BIT_MASK(ABS_MT_POSITION_X)) ||
!(absbit[BIT_WORD(ABS_MT_POSITION_Y)] & BIT_MASK(ABS_MT_POSITION_Y))) {
fprintf(stderr, "tslib: Selected device is not a touchscreen (must support ABS_X/Y or ABS_MT_POSITION_X/Y events)\n");
return -1;
}
}

/* Since some touchscreens (eg. infrared) physically can't measure pressure,
* the input system doesn't report it on those. Tslib relies on pressure, thus
* we set it to constant 255. It's still controlled by BTN_TOUCH/BTN_LEFT -
* when not touched, the pressure is forced to 0. */
if (!(absbit[BIT_WORD(ABS_PRESSURE)] & BIT_MASK(ABS_PRESSURE)))
i->no_pressure = 1;

if ((ioctl(ts->fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
!(keybit[BIT_WORD(BTN_TOUCH)] & BIT_MASK(BTN_TOUCH) ||
keybit[BIT_WORD(BTN_LEFT)] & BIT_MASK(BTN_LEFT))) {
fprintf(stderr, "tslib: Selected device is not a touchscreen (must support BTN_TOUCH or BTN_LEFT events)\n");
return -1;
}

/* Remember whether we have a multitouch device. We need to know for ABS_X,
* ABS_Y and ABS_PRESSURE data. */
if ((absbit[BIT_WORD(ABS_MT_POSITION_X)] & BIT_MASK(ABS_MT_POSITION_X)) &&
(absbit[BIT_WORD(ABS_MT_POSITION_Y)] & BIT_MASK(ABS_MT_POSITION_Y)))
i->mt = 1;

/* remember if we have a device that doesn't support pressure. We have to
* set pressure ourselves in this case. */
if (i->mt && !(absbit[BIT_WORD(ABS_MT_PRESSURE)] & BIT_MASK(ABS_MT_PRESSURE)))
i->no_pressure = 1;

if (evbit[BIT_WORD(EV_SYN)] & BIT_MASK(EV_SYN))
i->using_syn = 1;

if ((ioctl(ts->fd, EVIOCGBIT(EV_SYN, sizeof(synbit)), synbit)) == -1)
fprintf(stderr, "tslib: ioctl error\n");

/* remember whether we have a multitouch type A device */
if (i->mt && synbit[BIT_WORD(SYN_MT_REPORT)] & BIT_MASK(SYN_MT_REPORT) &&
!(absbit[BIT_WORD(ABS_MT_SLOT)] & BIT_MASK(ABS_MT_SLOT)))
i->type_a = 1;

if (i->grab_events == GRAB_EVENTS_WANTED) {
if (ioctl(ts->fd, EVIOCGRAB, (void *)1)) {
fprintf(stderr, "tslib: Unable to grab selected input device\n");
return -1;
}
i->grab_events = GRAB_EVENTS_ACTIVE;
}

return ts->fd;
}




and I can't see why the test is failing as


TS_INFO_FILE=/sys/devices/virtual/input/input6/uevent:
I: Bus=0018 Vendor=dead Product=beef Version=28bb
N: Name="gt9xxf_ts"
P: Phys=input/goodix-ts
S: Sysfs=/devices/virtual/input/input6
U: Uniq=
H: Handlers=event5 autohotplug cpufreq_interactive
B: PROP=2
B: EV=b
B: KEY=400 0 0 0 0 0
B: ABS=265000000000000
# evtest /dev/input/event5
Input driver version is 1.0.1
Input device ID: bus 0x18 vendor 0xdead product 0xbeef version 0x28bb
Input device name: "gt9xxf_ts"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 330 (BTN_TOUCH)
Event type 3 (EV_ABS)
Event code 48 (ABS_MT_TOUCH_MAJOR)
Value 0
Min 0
Max 255
Event code 50 (ABS_MT_WIDTH_MAJOR)
Value 0
Min 0
Max 255
Event code 53 (ABS_MT_POSITION_X)
Value 0
Min 0
Max 1024
Event code 54 (ABS_MT_POSITION_Y)
Value 0
Min 0
Max 600
Event code 57 (ABS_MT_TRACKING_ID)
Value 0
Min 0
Max 255
Properties:
Property type 1 (INPUT_PROP_DIRECT)



Can anyone point me in the right direction to getting the device calibrated?

I figure that if I (with help) can get this working, it might be an excellent and cheap squeezebox touch alternative.

BR.

--Marius-

Learnincurve
2017-02-14, 05:17
Hi,

I now have a working Xorg, using the tslib touchscreen driver and a patched JogglerSkinApplet.lua, suporting my 1024x600 screen resolution.

I have modified my ~/.xsessionrc file to start jivelite directly in the context of the autologin user.

The alternative would be to start it as a service from /etc/rc.local

Testing for this, I can manually start jivelite in a root ssh session, which causes the UI to start on the LCD screen (which is running an autologin user session), but if I do that, I can't get touch events to be recognised correctly, even if I pass the SDL environment variables when invoking jivelite:

# export SDL_TOUCHSCREEN=1
# export TSLIB_TSDEVICE=/dev/input/event5
# export SDL_MOUSEDRV=TSLIB
# export SDL_MOUSEDEV=$TSLIB_TSDEVICE

# /opt/jivelite/bin/jivelite

Interestingly, the "Jivelite" splash is centered correctly when starting as root, but is offset to the left, as if the 1024x600 resolution is not being picked up, if I start as my normal user. I'd also like to be able to pass screen-dimming strings to some /sys/class/gpio... files as part of some screensaver mods if I can find out how, but this might not be possible as a normal user.

What is the correct way of starting it?

BR.

--Marius--

Learnincurve
2017-02-14, 05:34
Hi again,

the Pine64 LCD touchscreen has a refresh rate of 56Hz.

I notice that when I start jivelite with the default settings of 30fps, the text jumps and flickers, so I truied setting different JIVE_FRAME_RATEs in src/jive.h

The smoothest scrolling is not surprisingly with multiples of 56:

#define JIVE_FRAME_RATE_DEFAULT 56
#define JIVE_FRAME_RATE_DEFAULT 112

but these reult in very fast scrolling, which is unreadable.

Is there any way to compile with a 56fps frame rate, but halve the actual scrolling speed to get smooth, slow scrolling?

BR.

--Marius--