From 44eba075165f932f6b960e5fc069be22b0c9b929 Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Thu, 19 Feb 2009 22:15:02 +0000 Subject: Add generic touchscreen driver which allows calibration (apps/ layer will follow later). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20055 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/touchscreen.c | 168 +++++++++++++++++++++ firmware/export/touchscreen.h | 48 ++++++ .../target/arm/tcc780x/cowond2/button-cowond2.c | 37 +---- .../mips/ingenic_jz47xx/onda_vx747/button-target.h | 4 + .../ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c | 65 +------- 5 files changed, 230 insertions(+), 92 deletions(-) create mode 100755 firmware/drivers/touchscreen.c create mode 100755 firmware/export/touchscreen.h diff --git a/firmware/drivers/touchscreen.c b/firmware/drivers/touchscreen.c new file mode 100755 index 0000000000..f7b1b09b92 --- /dev/null +++ b/firmware/drivers/touchscreen.c @@ -0,0 +1,168 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 by Maurus Cuelenaere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include "button.h" +#include "button-target.h" +#include "touchscreen.h" +#include "string.h" +#include "logf.h" + +static enum touchscreen_mode current_mode = TOUCHSCREEN_POINT; +static const int touchscreen_buttons[3][3] = +{ + {BUTTON_TOPLEFT, BUTTON_TOPMIDDLE, BUTTON_TOPRIGHT}, + {BUTTON_MIDLEFT, BUTTON_CENTER, BUTTON_MIDRIGHT}, + {BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT} +}; + +/* Based on ftp://ftp.embedded.com/pub/2002/06vidales/calibrate.c + * + * Copyright (c) 2001, Carlos E. Vidales. All rights reserved. + * + * This sample program was written and put in the public domain + * by Carlos E. Vidales. The program is provided "as is" + * without warranty of any kind, either expressed or implied. + * If you choose to use the program within your own products + * you do so at your own risk, and assume the responsibility + * for servicing, repairing or correcting the program should + * it prove defective in any manner. + * You may copy and distribute the program's source code in any + * medium, provided that you also include in each copy an + * appropriate copyright notice and disclaimer of warranty. + * You may also modify this program and distribute copies of + * it provided that you include prominent notices stating + * that you changed the file(s) and the date of any change, + * and that you do not charge any royalties or licenses for + * its use. + */ +struct touchscreen_parameter +{ + long A; + long B; + long C; + long D; + long E; + long F; + long divider; +}; + +#ifndef DEFAULT_TOUCHSCREEN_CALIBRATION +#define DEFAULT_TOUCHSCREEN_CALIBRATION {.A=1, .B=0, .C=0, \ + .D=0, .E=1, .F=0, \ + .divider=1} +#endif + +static struct touchscreen_parameter calibration_parameters + = DEFAULT_TOUCHSCREEN_CALIBRATION; +static const struct touchscreen_parameter default_parameters + = DEFAULT_TOUCHSCREEN_CALIBRATION; + +void touchscreen_disable_mapping(void) +{ + calibration_parameters.A = 1; + calibration_parameters.B = 0; + calibration_parameters.C = 0; + calibration_parameters.D = 0; + calibration_parameters.E = 1; + calibration_parameters.F = 0; + calibration_parameters.divider = 1; +} + +void touchscreen_reset_mapping(void) +{ + memcpy(&calibration_parameters, &default_parameters, + sizeof(struct touchscreen_parameter)); +} + +int touchscreen_calibrate(struct touchscreen_calibration *cal) +{ + calibration_parameters.divider = ((cal->x[0] - cal->x[2]) * (cal->y[1] - cal->y[2])) - + ((cal->x[1] - cal->x[2]) * (cal->y[0] - cal->y[2])) ; + + if(calibration_parameters.divider == 0) + return -1; + + calibration_parameters.A = ((cal->xfb[0] - cal->xfb[2]) * (cal->y[1] - cal->y[2])) - + ((cal->xfb[1] - cal->xfb[2]) * (cal->y[0] - cal->y[2])) ; + + calibration_parameters.B = ((cal->x[0] - cal->x[2]) * (cal->xfb[1] - cal->xfb[2])) - + ((cal->xfb[0] - cal->xfb[2]) * (cal->x[1] - cal->x[2])) ; + + calibration_parameters.C = (cal->x[2] * cal->xfb[1] - cal->x[1] * cal->xfb[2]) * cal->y[0] + + (cal->x[0] * cal->xfb[2] - cal->x[2] * cal->xfb[0]) * cal->y[1] + + (cal->x[1] * cal->xfb[0] - cal->x[0] * cal->xfb[1]) * cal->y[2] ; + + calibration_parameters.D = ((cal->yfb[0] - cal->yfb[2]) * (cal->y[1] - cal->y[2])) - + ((cal->yfb[1] - cal->yfb[2]) * (cal->y[0] - cal->y[2])) ; + + calibration_parameters.E = ((cal->x[0] - cal->x[2]) * (cal->yfb[1] - cal->yfb[2])) - + ((cal->yfb[0] - cal->yfb[2]) * (cal->x[1] - cal->x[2])) ; + + calibration_parameters.F = (cal->x[2] * cal->yfb[1] - cal->x[1] * cal->yfb[2]) * cal->y[0] + + (cal->x[0] * cal->yfb[2] - cal->x[2] * cal->yfb[0]) * cal->y[1] + + (cal->x[1] * cal->yfb[0] - cal->x[0] * cal->yfb[1]) * cal->y[2] ; + + logf("A: %lX B: %lX C: %lX", calibration_parameters.A, + calibration_parameters.B, calibration_parameters.C); + logf("D: %lX E: %lX F: %lX", calibration_parameters.D, + calibration_parameters.E, calibration_parameters.F); + logf("divider: %lX", calibration_parameters.divider); + + return 0; +} + +static void map_pixels(int *x, int *y) +{ + int _x = *x, _y = *y; + + *x = (calibration_parameters.A*_x + calibration_parameters.B*_y + + calibration_parameters.C) / calibration_parameters.divider; + *y = (calibration_parameters.D*_x + calibration_parameters.E*_y + + calibration_parameters.F) / calibration_parameters.divider; +} + +int touchscreen_to_pixels(int x, int y, int *data) +{ + x &= 0xFFFF; + y &= 0xFFFF; + + map_pixels(&x, &y); + + if(current_mode == TOUCHSCREEN_BUTTON) + return touchscreen_buttons[y / (LCD_HEIGHT/3)] + [x / (LCD_WIDTH/3) ]; + else + { + *data = (x << 16 | y); + return BUTTON_TOUCHSCREEN; + } +} + +void touchscreen_set_mode(enum touchscreen_mode mode) +{ + current_mode = mode; +} + +enum touchscreen_mode touchscreen_get_mode(void) +{ + return current_mode; +} diff --git a/firmware/export/touchscreen.h b/firmware/export/touchscreen.h new file mode 100755 index 0000000000..0d8233a522 --- /dev/null +++ b/firmware/export/touchscreen.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 by Maurus Cuelenaere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __TOUCHSCREEN_INCLUDE_H_ +#define __TOUCHSCREEN_INCLUDE_H_ + +struct touchscreen_calibration +{ + int x[3]; + int xfb[3]; + int y[3]; + int yfb[3]; +}; + +enum touchscreen_mode +{ + TOUCHSCREEN_POINT = 0, /* touchscreen returns pixel co-ords */ + TOUCHSCREEN_BUTTON, /* touchscreen returns BUTTON_* area codes + actual pixel value will still be accessible + from button_get_data */ +}; + +int touchscreen_calibrate(struct touchscreen_calibration *cal); +int touchscreen_to_pixels(int x, int y, int *data); +void touchscreen_set_mode(enum touchscreen_mode mode); +enum touchscreen_mode touchscreen_get_mode(void); +void touchscreen_disable_mapping(void); +void touchscreen_reset_mapping(void); + +#endif /* __TOUCHSCREEN_INCLUDE_H_ */ diff --git a/firmware/target/arm/tcc780x/cowond2/button-cowond2.c b/firmware/target/arm/tcc780x/cowond2/button-cowond2.c index 9449bcdf30..12eb88907a 100644 --- a/firmware/target/arm/tcc780x/cowond2/button-cowond2.c +++ b/firmware/target/arm/tcc780x/cowond2/button-cowond2.c @@ -25,31 +25,13 @@ #include "adc.h" #include "pcf50606.h" #include "backlight.h" +#include "touchscreen.h" #define TOUCH_MARGIN 8 -static enum touchscreen_mode current_mode = TOUCHSCREEN_POINT; - static short last_x, last_y; static bool touch_available = false; -static int touchscreen_buttons[3][3] = -{ - {BUTTON_TOPLEFT, BUTTON_TOPMIDDLE, BUTTON_TOPRIGHT}, - {BUTTON_MIDLEFT, BUTTON_CENTER, BUTTON_MIDRIGHT}, - {BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT}, -}; - -void touchscreen_set_mode(enum touchscreen_mode mode) -{ - current_mode = mode; -} - -enum touchscreen_mode touchscreen_get_mode(void) -{ - return current_mode; -} - void button_set_touch_available(void) { touch_available = true; @@ -186,20 +168,9 @@ int button_read_device(int *data) last_x = x; last_y = y; *data = touch_to_pixels(x, y); - switch (current_mode) - { - case TOUCHSCREEN_POINT: - btn |= BUTTON_TOUCHSCREEN; - break; - case TOUCHSCREEN_BUTTON: - { - int px_x = (*data&0xffff0000)>>16; - int px_y = (*data&0x0000ffff); - btn |= touchscreen_buttons[px_y/(LCD_HEIGHT/3)] - [px_x/(LCD_WIDTH/3)]; - break; - } - } + btn |= touchscreen_to_pixels((*data&0xffff0000)>>16, + (*data&0x0000ffff), + data); } last_touch = current_tick; touch_available = false; diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/button-target.h b/firmware/target/mips/ingenic_jz47xx/onda_vx747/button-target.h index 677e4d1c67..67d710a38a 100644 --- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/button-target.h +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/button-target.h @@ -57,6 +57,10 @@ void button_set_touch_available(void); #define BUTTON_TOUCH 0x00002000 +#define DEFAULT_TOUCHSCREEN_CALIBRATION {.A=0xFFF9FDA2, .B=0xFFFFE82A, \ + .C=0xA22AA2C, .D=0x23DC, .E=0x8E3E6, \ + .F=0x76CF88AA, .divider=0xFFAD4013} + #define BUTTON_MAIN 0x3FFF /* No remote */ diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c b/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c index c6fffdec42..3dce73b05e 100644 --- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c @@ -68,14 +68,6 @@ static volatile bool pen_down = false; static volatile unsigned short bat_val; static struct mutex battery_mtx; -static enum touchscreen_mode current_mode = TOUCHSCREEN_POINT; -static const int touchscreen_buttons[3][3] = -{ - {BUTTON_TOPLEFT, BUTTON_TOPMIDDLE, BUTTON_TOPRIGHT}, - {BUTTON_MIDLEFT, BUTTON_CENTER, BUTTON_MIDRIGHT}, - {BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT} -}; - const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = { /* TODO */ @@ -163,30 +155,6 @@ void button_init_device(void) mutex_init(&battery_mtx); } -static int touch_to_pixels(short x, short y) -{ - /* X:300 -> 3800 Y:300->3900 */ - x -= 300; - y -= 300; - -#if CONFIG_ORIENTATION == SCREEN_PORTRAIT - x /= 3200 / LCD_WIDTH; - y /= 3600 / LCD_HEIGHT; - - y = LCD_HEIGHT - y; - - return (x << 16) | y; -#else - x /= 3200 / LCD_HEIGHT; - y /= 3600 / LCD_WIDTH; - - y = LCD_WIDTH - y; - x = LCD_HEIGHT - x; - - return (y << 16) | x; -#endif -} - bool button_hold(void) { return ( @@ -218,38 +186,16 @@ int button_read_device(int *data) if(tmp & BTN_OFF) ret |= BUTTON_POWER; - if(cur_touch != 0) + if(cur_touch != 0 && pen_down) { - if(current_mode == TOUCHSCREEN_BUTTON) - { - int px_x = cur_touch >> 16; - int px_y = cur_touch & 0xFFFF; - ret |= touchscreen_buttons[px_y/(LCD_HEIGHT/3)] - [px_x/(LCD_WIDTH/3)]; - } - else if(pen_down) - { - ret |= BUTTON_TOUCHSCREEN; - *data = cur_touch; - } + ret |= touchscreen_to_pixels(cur_touch >> 16, cur_touch & 0xFFFF, data); + if( UNLIKELY(!is_backlight_on(true)) ) + *data = 0; } - - if(ret & BUTTON_TOUCHSCREEN && !is_backlight_on(true)) - *data = 0; return ret; } -void touchscreen_set_mode(enum touchscreen_mode mode) -{ - current_mode = mode; -} - -enum touchscreen_mode touchscreen_get_mode(void) -{ - return current_mode; -} - /* Interrupt handler */ void SADC(void) { @@ -314,7 +260,8 @@ void SADC(void) if(datacount >= TS_AD_COUNT) { - cur_touch = touch_to_pixels(x_pos/datacount, y_pos/datacount); + cur_touch = ((x_pos / datacount) << 16) | + ((y_pos / datacount) & 0xFFFF); datacount = 0; } } -- cgit v1.2.3