From c1023c33f2e5e3bb307b254df66402e2f082287f Mon Sep 17 00:00:00 2001 From: Frederik 'playya' Sdun Date: Wed, 29 Sep 2010 00:15:58 +0200 Subject: [PATCH] cy8mrln-palmpre: Add configuration to the info struct and add noise and ts_pressure option --- plugins/cy8mrln-palmpre.c | 275 ++++++++++++++++++++++++++++------------------ 1 file changed, 168 insertions(+), 107 deletions(-) diff --git a/plugins/cy8mrln-palmpre.c b/plugins/cy8mrln-palmpre.c index c571405..0404e3c 100644 --- a/plugins/cy8mrln-palmpre.c +++ b/plugins/cy8mrln-palmpre.c @@ -2,15 +2,16 @@ * tslib/plugins/cy8mrln-palmpre.c * * Copyright (C) 2010 Frederik Sdun - * Thomas Zimmermann - * + * Thomas Zimmermann + * Simon Busch * * This file is placed under the LGPL. Please see the file * COPYING for more details. * + * Plugin for the cy8mrln touchscreen with the firmware used on the Palm Pre (Plus). * - * Pluging for the cy8mrln touchscreen with the Firmware used on the Palm Pre */ + #include #include #include @@ -23,19 +24,28 @@ #include #include #include - +#include +#include +#include +#include +#include +#include #include "config.h" #include "tslib-private.h" #include "tslib-filter.h" -#include "cy8mrln.h" - -#define NOISE 25 #define SCREEN_WIDTH 319 #define SCREEN_HEIGHT 527 #define H_FIELDS 7 #define V_FIELDS 11 -#define TS_PRESSURE 255 +#define DEFAULT_SCANRATE 60 +#define DEFAULT_VERBOSE 0 +#define DEFAULT_WOT_THRESHOLD 22 +#define DEFAULT_SLEEPMODE CY8MRLN_ON_STATE +#define DEFAULT_WOT_SCANRATE WOT_SCANRATE_512HZ +#define DEFAULT_TIMESTAMP_MODE 1 +#define DEFAULT_TS_PRESSURE 255 +#define DEFAULT_NOISE 25 #define container_of(ptr, type, member) ({ \ const typeof( ((type*)0)->member ) *__mptr = (ptr); \ @@ -43,36 +53,38 @@ struct cy8mrln_palmpre_input { - uint16_t n_r; - uint16_t field[H_FIELDS * V_FIELDS]; - uint16_t ffff; //seperator? always ff - uint8_t seq_nr1; //incremented if seq_nr0 = scanrate - uint16_t seq_nr2; //incremeted if seq_nr1 = 255 - uint8_t unknown[4]; - uint8_t seq_nr0; //incremented. 0- scanrate - uint8_t null; //\0 + uint16_t n_r; + uint16_t field[H_FIELDS * V_FIELDS]; + uint16_t ffff; /* always 0xffff */ + uint8_t seq_nr1; /* incremented if seq_nr0 == scanrate */ + uint16_t seq_nr2; /* incremeted if seq_nr1 == 255 */ + uint8_t unknown[4]; + uint8_t seq_nr0; /* incremented [0:scanrate] */ + uint8_t null; /* NULL byte */ }__attribute__((packed)); struct tslib_cy8mrln_palmpre { struct tslib_module_info module; uint16_t nulls[H_FIELDS * V_FIELDS]; + int scanrate; + int verbose; + int wot_threshold; + int sleepmode; + int wot_scanrate; + int timestamp_mode; + int ts_pressure; + int noise; }; -static int scanrate = 60; -static int verbose = 0; -static int wot_threshold = 22; -static int sleepmode = CY8MRLN_ON_STATE; -static int wot_scanrate = WOT_SCANRATE_512HZ; -static int timestamp_mode = 1; static int -cy8mrln_palmpre_set_scanrate(struct tsdev* dev, int rate) +cy8mrln_palmpre_set_scanrate(struct tslib_cy8mrln_palmpre* info, int rate) { - if (dev == NULL || ioctl(dev->fd,CY8MRLN_IOCTL_SET_SCANRATE,&rate) < 0) + if (info == NULL || info->module.dev == NULL || ioctl(info->module.dev->fd,CY8MRLN_IOCTL_SET_SCANRATE,&rate) < 0) goto error; - scanrate = rate; + info->scanrate = rate; return 0; error: @@ -81,12 +93,12 @@ error: } static int -cy8mrln_palmpre_set_verbose(struct tsdev* dev, int v) +cy8mrln_palmpre_set_verbose(struct tslib_cy8mrln_palmpre* info, int v) { - if (dev == NULL || ioctl(dev->fd,CY8MRLN_IOCTL_SET_VERBOSE_MODE,&v) < 0) + if (info == NULL || info->module.dev == NULL || ioctl(info->module.dev->fd,CY8MRLN_IOCTL_SET_VERBOSE_MODE,&v) < 0) goto error; - verbose = v; + info->verbose = v; return 0; error: @@ -95,12 +107,12 @@ error: } static int -cy8mrln_palmpre_set_sleepmode(struct tsdev* dev, int mode) +cy8mrln_palmpre_set_sleepmode(struct tslib_cy8mrln_palmpre* info, int mode) { - if (dev == NULL || ioctl(dev->fd,CY8MRLN_IOCTL_SET_SLEEPMODE,&mode) < 0) + if (info == NULL || info->module.dev == NULL || ioctl(info->module.dev->fd,CY8MRLN_IOCTL_SET_SLEEPMODE,&mode) < 0) goto error; - sleepmode = mode; + info->sleepmode = mode; return 0; error: @@ -109,12 +121,12 @@ error: } static int -cy8mrln_palmpre_set_wot_scanrate(struct tsdev* dev, int rate) +cy8mrln_palmpre_set_wot_scanrate(struct tslib_cy8mrln_palmpre* info, int rate) { - if (dev == NULL || ioctl(dev->fd,CY8MRLN_IOCTL_SET_WOT_SCANRATE,&rate) < 0) + if (info == NULL || info->module.dev == NULL || ioctl(info->module.dev->fd,CY8MRLN_IOCTL_SET_WOT_SCANRATE,&rate) < 0) goto error; - wot_scanrate = rate; + info->wot_scanrate = rate; return 0; error: @@ -123,16 +135,16 @@ error: } static int -cy8mrln_palmpre_set_wot_threshold(struct tsdev* dev, int v) +cy8mrln_palmpre_set_wot_threshold(struct tslib_cy8mrln_palmpre* info, int v) { - if (dev == NULL) + if (info == NULL || info->module.dev == NULL) goto error; if(v < WOT_THRESHOLD_MIN || v > WOT_THRESHOLD_MAX) goto error; - if(ioctl(dev->fd,CY8MRLN_IOCTL_SET_WOT_THRESHOLD,&v) < 0) + if(ioctl(info->module.dev->fd,CY8MRLN_IOCTL_SET_WOT_THRESHOLD,&v) < 0) goto error; - wot_threshold = v; + info->wot_threshold = v; return 0; error: @@ -141,12 +153,12 @@ error: } static int -cy8mrln_palmpre_set_timestamp_mode(struct tsdev* dev, int v) +cy8mrln_palmpre_set_timestamp_mode(struct tslib_cy8mrln_palmpre* info, int v) { v = v ? 1 : 0; - if(dev == NULL || ioctl(dev->fd,CY8MRLN_IOCTL_SET_TIMESTAMP_MODE,&v) < 0) + if(info == NULL || info->module.dev == NULL || ioctl(info->module.dev->fd,CY8MRLN_IOCTL_SET_TIMESTAMP_MODE,&v) < 0) goto error; - timestamp_mode = v; + info->timestamp_mode = v; return 0; error: @@ -154,64 +166,122 @@ error: return -1; } +static int +cy8mrln_palmpre_set_noise (struct tslib_cy8mrln_palmpre* info, int n) +{ + if (info == NULL) { + printf("TSLIB: cy8mrln_palmpre: ERROR: could not set noise value\n"); + return -1; + } + info->noise = n; + return 0; +} + +static int +cy8mrln_palmpre_set_ts_pressure(struct tslib_cy8mrln_palmpre* info, int p) +{ + if (info == NULL) { + printf("TSLIB: cy8mrln_palmpre: ERROR: could not set ts_pressure value\n"); + return -1; + } + info->ts_pressure = p; + return 0; +} + static int parse_scanrate(struct tslib_module_info *info, char *str, void *data) { - struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info; + (void)data; + struct tslib_cy8mrln_palmpre *i = container_of(info, struct tslib_cy8mrln_palmpre, module); unsigned long rate = strtoul(str, NULL, 0); if(rate == ULONG_MAX && errno == ERANGE) return -1; - return cy8mrln_palmpre_set_scanrate(i->module.dev, scanrate); + return cy8mrln_palmpre_set_scanrate(i, rate); } static int parse_verbose(struct tslib_module_info *info, char *str, void *data) { - struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info; + (void)data; + struct tslib_cy8mrln_palmpre *i = container_of(info, struct tslib_cy8mrln_palmpre, module); unsigned long v = strtoul(str, NULL, 0); if(v == ULONG_MAX && errno == ERANGE) return -1; - return cy8mrln_palmpre_set_verbose(i->module.dev, scanrate); + return cy8mrln_palmpre_set_verbose(i, v); } static int parse_wot_scanrate(struct tslib_module_info *info, char *str, void *data) { - struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info; + (void)data; + struct tslib_cy8mrln_palmpre *i = container_of(info, struct tslib_cy8mrln_palmpre, module); unsigned long rate = strtoul(str, NULL, 0); - return cy8mrln_palmpre_set_wot_scanrate(i->module.dev, rate); + return cy8mrln_palmpre_set_wot_scanrate(i, rate); } static int parse_wot_threshold(struct tslib_module_info *info, char *str, void *data) { - struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info; + (void)data; + struct tslib_cy8mrln_palmpre *i = container_of(info, struct tslib_cy8mrln_palmpre, module); unsigned long threshold = strtoul(str, NULL, 0); - return cy8mrln_palmpre_set_wot_threshold(i->module.dev, threshold); + return cy8mrln_palmpre_set_wot_threshold(i, threshold); } static int parse_sleepmode(struct tslib_module_info *info, char *str, void *data) { - struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info; + (void)data; + struct tslib_cy8mrln_palmpre *i = container_of(info, struct tslib_cy8mrln_palmpre, module); unsigned long sleep = strtoul(str, NULL, 0); - return cy8mrln_palmpre_set_sleepmode(i->module.dev, sleep); + return cy8mrln_palmpre_set_sleepmode(i, sleep); } static int parse_timestamp_mode(struct tslib_module_info *info, char *str, void *data) { + (void)data; struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info; unsigned long sleep = strtoul(str, NULL, 0); - return cy8mrln_palmpre_set_sleepmode(i->module.dev, sleep); + if(sleep == ULONG_MAX && errno == ERANGE) + return -1; + + + return cy8mrln_palmpre_set_sleepmode(i, sleep); +} +static int +parse_noise(struct tslib_module_info *info, char *str, void *data) +{ + (void)data; + struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info; + unsigned long noise = strtoul (str, NULL, 0); + + if(noise == ULONG_MAX && errno == ERANGE) + return -1; + + + return cy8mrln_palmpre_set_noise (i, noise); +} + +static int +parse_ts_pressure(struct tslib_module_info *info, char *str, void *data) +{ + (void)data; + struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info; + unsigned long tp = strtoul (str, NULL, 0); + + if(tp == ULONG_MAX && errno == ERANGE) + return -1; + + return cy8mrln_palmpre_set_ts_pressure (i, tp); } static const struct tslib_vars raw_vars[] = @@ -221,14 +291,16 @@ static const struct tslib_vars raw_vars[] = { "wot_scanrate", NULL, parse_wot_scanrate}, { "wot_threshold", NULL, parse_wot_threshold}, { "sleepmode", NULL, parse_sleepmode}, - { "timestamp_mode", NULL, parse_timestamp_mode} + { "timestamp_mode", NULL, parse_timestamp_mode}, + { "noise", NULL, parse_noise}, + { "ts_pressure", NULL, parse_ts_pressure} }; #define NR_VARS (sizeof(raw_vars) / sizeof(raw_vars[0])) void interpolate(uint16_t field[H_FIELDS * V_FIELDS], int i, struct ts_sample *out) { - float f11, f12, f13, f21, f22, f23, f31, f32, f33; + float f12, f21, f22, f23, f32; //f33, f31, f13, f11 int x = SCREEN_WIDTH / H_FIELDS * (H_FIELDS - (i % H_FIELDS)); int y = SCREEN_HEIGHT / (V_FIELDS - 1) * (i / H_FIELDS); static int dx = SCREEN_WIDTH / H_FIELDS; @@ -242,10 +314,8 @@ interpolate(uint16_t field[H_FIELDS * V_FIELDS], int i, struct ts_sample *out) { ? 0.0 : 0.5 * field[i + 1] / field[i]; f23 = (i % H_FIELDS == 0) ? 0.0 : 0.5 * field[i - 1] / field[i]; - /* - correct values for the edges, shift the mesuarment point by half a - field diminsion to the outside - */ + /* correct values for the edges, shift the mesuarment point by half a + * field diminsion to the outside */ if (i == 0) { x = x + dx / 2; f21 = f21 * 2.0; @@ -301,7 +371,6 @@ interpolate(uint16_t field[H_FIELDS * V_FIELDS], int i, struct ts_sample *out) { out->y = y // + (f31 + f33 - f11 - f13) * dy /* use corners too?*/ + (f32 - f12) * dy + (dy / 2); - out->pressure = TS_PRESSURE; #ifdef DEBUG printf("RAW---------------------------> f22: %f (%d) f21: %f (%d), f23: %f (%d), f12: %f (%d), f32: %f (%d), \n", f22, field[i], @@ -314,7 +383,8 @@ static int cy8mrln_palmpre_read(struct tslib_module_info *info, struct ts_sample *samp, int nr) { struct tsdev *ts = info->dev; - struct cy8mrln_palmpre_input *cy8mrln_evt; + //We can only read one input struct at once + struct cy8mrln_palmpre_input cy8mrln_evt; struct tslib_cy8mrln_palmpre *cy8mrln_info; int max_index = 0, max_value = 0, i = 0; uint16_t tmp_value; @@ -322,61 +392,50 @@ cy8mrln_palmpre_read(struct tslib_module_info *info, struct ts_sample *samp, int struct ts_sample *p = samp; /* initalize all samples with proper values */ - for (i = 0; i < nr; i++, p++) - { - p->x = 0; - p->y = 0; - p->pressure = 0; - } + memset(p, '\0', nr * sizeof (*p)); cy8mrln_info = container_of(info, struct tslib_cy8mrln_palmpre, module); - cy8mrln_evt = alloca(sizeof(*cy8mrln_evt) * nr); - ret = read(ts->fd, cy8mrln_evt, sizeof(*cy8mrln_evt) * nr); + ret = read(ts->fd, &cy8mrln_evt, sizeof(cy8mrln_evt)); if (ret > 0) { max_index = 0; max_value = 0; - while(ret >= (int)sizeof(*cy8mrln_evt)) { - for (i = 0; i < (H_FIELDS * V_FIELDS); i++) { - /* auto calibrate zero values */ - if (cy8mrln_evt->field[i] > cy8mrln_info->nulls[i]) - cy8mrln_info->nulls[i] = cy8mrln_evt->field[i]; - - tmp_value = abs(cy8mrln_info->nulls[i] - cy8mrln_evt->field[i]); - - /* check for the maximum value */ - if (tmp_value > max_value) { - max_value = tmp_value; - max_index = i; - } - - cy8mrln_evt->field[i] = tmp_value; - } - /* only caluclate events that are not noise */ - if (max_value > NOISE) { - interpolate(cy8mrln_evt->field, max_index, samp); + for (i = 0; i < (H_FIELDS * V_FIELDS); i++) { + /* auto calibrate zero values */ + if (cy8mrln_evt.field[i] > cy8mrln_info->nulls[i]) + cy8mrln_info->nulls[i] = cy8mrln_evt.field[i]; + + tmp_value = abs(cy8mrln_info->nulls[i] - cy8mrln_evt.field[i]); + + /* check for the maximum value */ + if (tmp_value > max_value) { + max_value = tmp_value; + max_index = i; + } + + cy8mrln_evt.field[i] = tmp_value; + } + /* only caluclate events that are not noise */ + if (max_value > cy8mrln_info->noise) { + interpolate(cy8mrln_evt.field, max_index, samp); + samp->pressure = cy8mrln_info -> ts_pressure; #ifdef DEBUG - fprintf(stderr,"RAW---------------------------> %d %d %d\n", - samp->x, samp->y, samp->pressure); + fprintf(stderr,"RAW---------------------------> %d %d %d\n", + samp->x, samp->y, samp->pressure); #endif /*DEBUG*/ - gettimeofday(&samp->tv,NULL); - samp++; - valid_samples++; - } - - cy8mrln_evt++; - ret -= sizeof(*cy8mrln_evt); - } - } else { - return -1; + gettimeofday(&samp->tv,NULL); + samp++; + valid_samples++; + } } return valid_samples; } static int -cy8mrln_palmpre_fini(struct tslib_module_info *inf) +cy8mrln_palmpre_fini(struct tslib_module_info *info) { + (void)info; return 0; } @@ -398,19 +457,21 @@ TSAPI struct tslib_module_info *cy8mrln_palmpre_mod_init(struct tsdev *dev, cons return NULL; info->module.ops = &cy8mrln_palmpre_ops; - cy8mrln_palmpre_set_verbose(dev,verbose); - cy8mrln_palmpre_set_scanrate(dev,scanrate); - cy8mrln_palmpre_set_timestamp_mode(dev,timestamp_mode); - cy8mrln_palmpre_set_sleepmode(dev,sleepmode); - cy8mrln_palmpre_set_wot_scanrate(dev,wot_scanrate); - cy8mrln_palmpre_set_wot_threshold(dev,wot_threshold); + cy8mrln_palmpre_set_verbose(info, DEFAULT_VERBOSE); + cy8mrln_palmpre_set_scanrate(info, DEFAULT_SCANRATE); + cy8mrln_palmpre_set_timestamp_mode(info, DEFAULT_TIMESTAMP_MODE); + cy8mrln_palmpre_set_sleepmode(info, DEFAULT_SLEEPMODE); + cy8mrln_palmpre_set_wot_scanrate(info, DEFAULT_WOT_SCANRATE); + cy8mrln_palmpre_set_wot_threshold(info, DEFAULT_WOT_THRESHOLD); + cy8mrln_palmpre_set_noise(info, DEFAULT_NOISE); + cy8mrln_palmpre_set_ts_pressure(info, DEFAULT_TS_PRESSURE); if (tslib_parse_vars(&info->module, raw_vars, NR_VARS, params)) { free(info); return NULL; } - /* We need the intial values the touchscreen repots with no touch input force + /* We need the intial values the touchscreen repots with no touch input for * later use */ do { ret = read(dev->fd, &input, sizeof(input)); -- 2.11.0