diff options
author | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2009-02-19 22:15:02 +0000 |
---|---|---|
committer | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2009-02-19 22:15:02 +0000 |
commit | 44eba075165f932f6b960e5fc069be22b0c9b929 (patch) | |
tree | 674afb2eda2b4ea3f62163232297a9cd898a90d5 /firmware | |
parent | 1cb3ff0ab06cc71eb82b82e36eb22ca1d5eaa61f (diff) | |
download | rockbox-44eba075165f932f6b960e5fc069be22b0c9b929.tar.gz rockbox-44eba075165f932f6b960e5fc069be22b0c9b929.zip |
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
Diffstat (limited to 'firmware')
-rwxr-xr-x | firmware/drivers/touchscreen.c | 168 | ||||
-rwxr-xr-x | firmware/export/touchscreen.h | 48 | ||||
-rw-r--r-- | firmware/target/arm/tcc780x/cowond2/button-cowond2.c | 37 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/onda_vx747/button-target.h | 4 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c | 65 |
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 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Maurus Cuelenaere | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "config.h" | ||
23 | #include "button.h" | ||
24 | #include "button-target.h" | ||
25 | #include "touchscreen.h" | ||
26 | #include "string.h" | ||
27 | #include "logf.h" | ||
28 | |||
29 | static enum touchscreen_mode current_mode = TOUCHSCREEN_POINT; | ||
30 | static const int touchscreen_buttons[3][3] = | ||
31 | { | ||
32 | {BUTTON_TOPLEFT, BUTTON_TOPMIDDLE, BUTTON_TOPRIGHT}, | ||
33 | {BUTTON_MIDLEFT, BUTTON_CENTER, BUTTON_MIDRIGHT}, | ||
34 | {BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT} | ||
35 | }; | ||
36 | |||
37 | /* Based on ftp://ftp.embedded.com/pub/2002/06vidales/calibrate.c | ||
38 | * | ||
39 | * Copyright (c) 2001, Carlos E. Vidales. All rights reserved. | ||
40 | * | ||
41 | * This sample program was written and put in the public domain | ||
42 | * by Carlos E. Vidales. The program is provided "as is" | ||
43 | * without warranty of any kind, either expressed or implied. | ||
44 | * If you choose to use the program within your own products | ||
45 | * you do so at your own risk, and assume the responsibility | ||
46 | * for servicing, repairing or correcting the program should | ||
47 | * it prove defective in any manner. | ||
48 | * You may copy and distribute the program's source code in any | ||
49 | * medium, provided that you also include in each copy an | ||
50 | * appropriate copyright notice and disclaimer of warranty. | ||
51 | * You may also modify this program and distribute copies of | ||
52 | * it provided that you include prominent notices stating | ||
53 | * that you changed the file(s) and the date of any change, | ||
54 | * and that you do not charge any royalties or licenses for | ||
55 | * its use. | ||
56 | */ | ||
57 | struct touchscreen_parameter | ||
58 | { | ||
59 | long A; | ||
60 | long B; | ||
61 | long C; | ||
62 | long D; | ||
63 | long E; | ||
64 | long F; | ||
65 | long divider; | ||
66 | }; | ||
67 | |||
68 | #ifndef DEFAULT_TOUCHSCREEN_CALIBRATION | ||
69 | #define DEFAULT_TOUCHSCREEN_CALIBRATION {.A=1, .B=0, .C=0, \ | ||
70 | .D=0, .E=1, .F=0, \ | ||
71 | .divider=1} | ||
72 | #endif | ||
73 | |||
74 | static struct touchscreen_parameter calibration_parameters | ||
75 | = DEFAULT_TOUCHSCREEN_CALIBRATION; | ||
76 | static const struct touchscreen_parameter default_parameters | ||
77 | = DEFAULT_TOUCHSCREEN_CALIBRATION; | ||
78 | |||
79 | void touchscreen_disable_mapping(void) | ||
80 | { | ||
81 | calibration_parameters.A = 1; | ||
82 | calibration_parameters.B = 0; | ||
83 | calibration_parameters.C = 0; | ||
84 | calibration_parameters.D = 0; | ||
85 | calibration_parameters.E = 1; | ||
86 | calibration_parameters.F = 0; | ||
87 | calibration_parameters.divider = 1; | ||
88 | } | ||
89 | |||
90 | void touchscreen_reset_mapping(void) | ||
91 | { | ||
92 | memcpy(&calibration_parameters, &default_parameters, | ||
93 | sizeof(struct touchscreen_parameter)); | ||
94 | } | ||
95 | |||
96 | int touchscreen_calibrate(struct touchscreen_calibration *cal) | ||
97 | { | ||
98 | calibration_parameters.divider = ((cal->x[0] - cal->x[2]) * (cal->y[1] - cal->y[2])) - | ||
99 | ((cal->x[1] - cal->x[2]) * (cal->y[0] - cal->y[2])) ; | ||
100 | |||
101 | if(calibration_parameters.divider == 0) | ||
102 | return -1; | ||
103 | |||
104 | calibration_parameters.A = ((cal->xfb[0] - cal->xfb[2]) * (cal->y[1] - cal->y[2])) - | ||
105 | ((cal->xfb[1] - cal->xfb[2]) * (cal->y[0] - cal->y[2])) ; | ||
106 | |||
107 | calibration_parameters.B = ((cal->x[0] - cal->x[2]) * (cal->xfb[1] - cal->xfb[2])) - | ||
108 | ((cal->xfb[0] - cal->xfb[2]) * (cal->x[1] - cal->x[2])) ; | ||
109 | |||
110 | calibration_parameters.C = (cal->x[2] * cal->xfb[1] - cal->x[1] * cal->xfb[2]) * cal->y[0] + | ||
111 | (cal->x[0] * cal->xfb[2] - cal->x[2] * cal->xfb[0]) * cal->y[1] + | ||
112 | (cal->x[1] * cal->xfb[0] - cal->x[0] * cal->xfb[1]) * cal->y[2] ; | ||
113 | |||
114 | calibration_parameters.D = ((cal->yfb[0] - cal->yfb[2]) * (cal->y[1] - cal->y[2])) - | ||
115 | ((cal->yfb[1] - cal->yfb[2]) * (cal->y[0] - cal->y[2])) ; | ||
116 | |||
117 | calibration_parameters.E = ((cal->x[0] - cal->x[2]) * (cal->yfb[1] - cal->yfb[2])) - | ||
118 | ((cal->yfb[0] - cal->yfb[2]) * (cal->x[1] - cal->x[2])) ; | ||
119 | |||
120 | calibration_parameters.F = (cal->x[2] * cal->yfb[1] - cal->x[1] * cal->yfb[2]) * cal->y[0] + | ||
121 | (cal->x[0] * cal->yfb[2] - cal->x[2] * cal->yfb[0]) * cal->y[1] + | ||
122 | (cal->x[1] * cal->yfb[0] - cal->x[0] * cal->yfb[1]) * cal->y[2] ; | ||
123 | |||
124 | logf("A: %lX B: %lX C: %lX", calibration_parameters.A, | ||
125 | calibration_parameters.B, calibration_parameters.C); | ||
126 | logf("D: %lX E: %lX F: %lX", calibration_parameters.D, | ||
127 | calibration_parameters.E, calibration_parameters.F); | ||
128 | logf("divider: %lX", calibration_parameters.divider); | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static void map_pixels(int *x, int *y) | ||
134 | { | ||
135 | int _x = *x, _y = *y; | ||
136 | |||
137 | *x = (calibration_parameters.A*_x + calibration_parameters.B*_y + | ||
138 | calibration_parameters.C) / calibration_parameters.divider; | ||
139 | *y = (calibration_parameters.D*_x + calibration_parameters.E*_y + | ||
140 | calibration_parameters.F) / calibration_parameters.divider; | ||
141 | } | ||
142 | |||
143 | int touchscreen_to_pixels(int x, int y, int *data) | ||
144 | { | ||
145 | x &= 0xFFFF; | ||
146 | y &= 0xFFFF; | ||
147 | |||
148 | map_pixels(&x, &y); | ||
149 | |||
150 | if(current_mode == TOUCHSCREEN_BUTTON) | ||
151 | return touchscreen_buttons[y / (LCD_HEIGHT/3)] | ||
152 | [x / (LCD_WIDTH/3) ]; | ||
153 | else | ||
154 | { | ||
155 | *data = (x << 16 | y); | ||
156 | return BUTTON_TOUCHSCREEN; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | void touchscreen_set_mode(enum touchscreen_mode mode) | ||
161 | { | ||
162 | current_mode = mode; | ||
163 | } | ||
164 | |||
165 | enum touchscreen_mode touchscreen_get_mode(void) | ||
166 | { | ||
167 | return current_mode; | ||
168 | } | ||
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 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Maurus Cuelenaere | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef __TOUCHSCREEN_INCLUDE_H_ | ||
23 | #define __TOUCHSCREEN_INCLUDE_H_ | ||
24 | |||
25 | struct touchscreen_calibration | ||
26 | { | ||
27 | int x[3]; | ||
28 | int xfb[3]; | ||
29 | int y[3]; | ||
30 | int yfb[3]; | ||
31 | }; | ||
32 | |||
33 | enum touchscreen_mode | ||
34 | { | ||
35 | TOUCHSCREEN_POINT = 0, /* touchscreen returns pixel co-ords */ | ||
36 | TOUCHSCREEN_BUTTON, /* touchscreen returns BUTTON_* area codes | ||
37 | actual pixel value will still be accessible | ||
38 | from button_get_data */ | ||
39 | }; | ||
40 | |||
41 | int touchscreen_calibrate(struct touchscreen_calibration *cal); | ||
42 | int touchscreen_to_pixels(int x, int y, int *data); | ||
43 | void touchscreen_set_mode(enum touchscreen_mode mode); | ||
44 | enum touchscreen_mode touchscreen_get_mode(void); | ||
45 | void touchscreen_disable_mapping(void); | ||
46 | void touchscreen_reset_mapping(void); | ||
47 | |||
48 | #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 @@ | |||
25 | #include "adc.h" | 25 | #include "adc.h" |
26 | #include "pcf50606.h" | 26 | #include "pcf50606.h" |
27 | #include "backlight.h" | 27 | #include "backlight.h" |
28 | #include "touchscreen.h" | ||
28 | 29 | ||
29 | #define TOUCH_MARGIN 8 | 30 | #define TOUCH_MARGIN 8 |
30 | 31 | ||
31 | static enum touchscreen_mode current_mode = TOUCHSCREEN_POINT; | ||
32 | |||
33 | static short last_x, last_y; | 32 | static short last_x, last_y; |
34 | static bool touch_available = false; | 33 | static bool touch_available = false; |
35 | 34 | ||
36 | static int touchscreen_buttons[3][3] = | ||
37 | { | ||
38 | {BUTTON_TOPLEFT, BUTTON_TOPMIDDLE, BUTTON_TOPRIGHT}, | ||
39 | {BUTTON_MIDLEFT, BUTTON_CENTER, BUTTON_MIDRIGHT}, | ||
40 | {BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT}, | ||
41 | }; | ||
42 | |||
43 | void touchscreen_set_mode(enum touchscreen_mode mode) | ||
44 | { | ||
45 | current_mode = mode; | ||
46 | } | ||
47 | |||
48 | enum touchscreen_mode touchscreen_get_mode(void) | ||
49 | { | ||
50 | return current_mode; | ||
51 | } | ||
52 | |||
53 | void button_set_touch_available(void) | 35 | void button_set_touch_available(void) |
54 | { | 36 | { |
55 | touch_available = true; | 37 | touch_available = true; |
@@ -186,20 +168,9 @@ int button_read_device(int *data) | |||
186 | last_x = x; | 168 | last_x = x; |
187 | last_y = y; | 169 | last_y = y; |
188 | *data = touch_to_pixels(x, y); | 170 | *data = touch_to_pixels(x, y); |
189 | switch (current_mode) | 171 | btn |= touchscreen_to_pixels((*data&0xffff0000)>>16, |
190 | { | 172 | (*data&0x0000ffff), |
191 | case TOUCHSCREEN_POINT: | 173 | data); |
192 | btn |= BUTTON_TOUCHSCREEN; | ||
193 | break; | ||
194 | case TOUCHSCREEN_BUTTON: | ||
195 | { | ||
196 | int px_x = (*data&0xffff0000)>>16; | ||
197 | int px_y = (*data&0x0000ffff); | ||
198 | btn |= touchscreen_buttons[px_y/(LCD_HEIGHT/3)] | ||
199 | [px_x/(LCD_WIDTH/3)]; | ||
200 | break; | ||
201 | } | ||
202 | } | ||
203 | } | 174 | } |
204 | last_touch = current_tick; | 175 | last_touch = current_tick; |
205 | touch_available = false; | 176 | 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); | |||
57 | 57 | ||
58 | #define BUTTON_TOUCH 0x00002000 | 58 | #define BUTTON_TOUCH 0x00002000 |
59 | 59 | ||
60 | #define DEFAULT_TOUCHSCREEN_CALIBRATION {.A=0xFFF9FDA2, .B=0xFFFFE82A, \ | ||
61 | .C=0xA22AA2C, .D=0x23DC, .E=0x8E3E6, \ | ||
62 | .F=0x76CF88AA, .divider=0xFFAD4013} | ||
63 | |||
60 | #define BUTTON_MAIN 0x3FFF | 64 | #define BUTTON_MAIN 0x3FFF |
61 | 65 | ||
62 | /* No remote */ | 66 | /* 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; | |||
68 | static volatile unsigned short bat_val; | 68 | static volatile unsigned short bat_val; |
69 | static struct mutex battery_mtx; | 69 | static struct mutex battery_mtx; |
70 | 70 | ||
71 | static enum touchscreen_mode current_mode = TOUCHSCREEN_POINT; | ||
72 | static const int touchscreen_buttons[3][3] = | ||
73 | { | ||
74 | {BUTTON_TOPLEFT, BUTTON_TOPMIDDLE, BUTTON_TOPRIGHT}, | ||
75 | {BUTTON_MIDLEFT, BUTTON_CENTER, BUTTON_MIDRIGHT}, | ||
76 | {BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT} | ||
77 | }; | ||
78 | |||
79 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = | 71 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = |
80 | { | 72 | { |
81 | /* TODO */ | 73 | /* TODO */ |
@@ -163,30 +155,6 @@ void button_init_device(void) | |||
163 | mutex_init(&battery_mtx); | 155 | mutex_init(&battery_mtx); |
164 | } | 156 | } |
165 | 157 | ||
166 | static int touch_to_pixels(short x, short y) | ||
167 | { | ||
168 | /* X:300 -> 3800 Y:300->3900 */ | ||
169 | x -= 300; | ||
170 | y -= 300; | ||
171 | |||
172 | #if CONFIG_ORIENTATION == SCREEN_PORTRAIT | ||
173 | x /= 3200 / LCD_WIDTH; | ||
174 | y /= 3600 / LCD_HEIGHT; | ||
175 | |||
176 | y = LCD_HEIGHT - y; | ||
177 | |||
178 | return (x << 16) | y; | ||
179 | #else | ||
180 | x /= 3200 / LCD_HEIGHT; | ||
181 | y /= 3600 / LCD_WIDTH; | ||
182 | |||
183 | y = LCD_WIDTH - y; | ||
184 | x = LCD_HEIGHT - x; | ||
185 | |||
186 | return (y << 16) | x; | ||
187 | #endif | ||
188 | } | ||
189 | |||
190 | bool button_hold(void) | 158 | bool button_hold(void) |
191 | { | 159 | { |
192 | return ( | 160 | return ( |
@@ -218,38 +186,16 @@ int button_read_device(int *data) | |||
218 | if(tmp & BTN_OFF) | 186 | if(tmp & BTN_OFF) |
219 | ret |= BUTTON_POWER; | 187 | ret |= BUTTON_POWER; |
220 | 188 | ||
221 | if(cur_touch != 0) | 189 | if(cur_touch != 0 && pen_down) |
222 | { | 190 | { |
223 | if(current_mode == TOUCHSCREEN_BUTTON) | 191 | ret |= touchscreen_to_pixels(cur_touch >> 16, cur_touch & 0xFFFF, data); |
224 | { | 192 | if( UNLIKELY(!is_backlight_on(true)) ) |
225 | int px_x = cur_touch >> 16; | 193 | *data = 0; |
226 | int px_y = cur_touch & 0xFFFF; | ||
227 | ret |= touchscreen_buttons[px_y/(LCD_HEIGHT/3)] | ||
228 | [px_x/(LCD_WIDTH/3)]; | ||
229 | } | ||
230 | else if(pen_down) | ||
231 | { | ||
232 | ret |= BUTTON_TOUCHSCREEN; | ||
233 | *data = cur_touch; | ||
234 | } | ||
235 | } | 194 | } |
236 | |||
237 | if(ret & BUTTON_TOUCHSCREEN && !is_backlight_on(true)) | ||
238 | *data = 0; | ||
239 | 195 | ||
240 | return ret; | 196 | return ret; |
241 | } | 197 | } |
242 | 198 | ||
243 | void touchscreen_set_mode(enum touchscreen_mode mode) | ||
244 | { | ||
245 | current_mode = mode; | ||
246 | } | ||
247 | |||
248 | enum touchscreen_mode touchscreen_get_mode(void) | ||
249 | { | ||
250 | return current_mode; | ||
251 | } | ||
252 | |||
253 | /* Interrupt handler */ | 199 | /* Interrupt handler */ |
254 | void SADC(void) | 200 | void SADC(void) |
255 | { | 201 | { |
@@ -314,7 +260,8 @@ void SADC(void) | |||
314 | 260 | ||
315 | if(datacount >= TS_AD_COUNT) | 261 | if(datacount >= TS_AD_COUNT) |
316 | { | 262 | { |
317 | cur_touch = touch_to_pixels(x_pos/datacount, y_pos/datacount); | 263 | cur_touch = ((x_pos / datacount) << 16) | |
264 | ((y_pos / datacount) & 0xFFFF); | ||
318 | datacount = 0; | 265 | datacount = 0; |
319 | } | 266 | } |
320 | } | 267 | } |