summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2009-02-19 22:15:02 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2009-02-19 22:15:02 +0000
commit44eba075165f932f6b960e5fc069be22b0c9b929 (patch)
tree674afb2eda2b4ea3f62163232297a9cd898a90d5
parent1cb3ff0ab06cc71eb82b82e36eb22ca1d5eaa61f (diff)
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
-rwxr-xr-xfirmware/drivers/touchscreen.c168
-rwxr-xr-xfirmware/export/touchscreen.h48
-rw-r--r--firmware/target/arm/tcc780x/cowond2/button-cowond2.c37
-rw-r--r--firmware/target/mips/ingenic_jz47xx/onda_vx747/button-target.h4
-rw-r--r--firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c65
5 files changed, 230 insertions, 92 deletions
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;
}
}