summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Purchase <shotofadds@rockbox.org>2009-09-26 17:31:30 +0000
committerRob Purchase <shotofadds@rockbox.org>2009-09-26 17:31:30 +0000
commit65f1a94a08793ea99386a0cb69cf3151e20cacbe (patch)
treec8bc2824a45faecf44dff0e75cf8e4c5ae3ac118
parent8e365ba12b75f1ebb360342bcd2804d7a245e5bf (diff)
downloadrockbox-65f1a94a08793ea99386a0cb69cf3151e20cacbe.tar.gz
rockbox-65f1a94a08793ea99386a0cb69cf3151e20cacbe.zip
Improved Cowon D2 touchscreen driver.
Flyspray: FS#10615 Author: Carsten Schreiter and myself git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22842 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--docs/CREDITS1
-rw-r--r--firmware/target/arm/tcc780x/cowond2/button-cowond2.c137
-rw-r--r--firmware/target/arm/tcc780x/cowond2/button-target.h2
-rw-r--r--firmware/target/arm/tcc780x/cowond2/power-cowond2.c2
4 files changed, 87 insertions, 55 deletions
diff --git a/docs/CREDITS b/docs/CREDITS
index 148e010731..0ef1ce4f0b 100644
--- a/docs/CREDITS
+++ b/docs/CREDITS
@@ -494,6 +494,7 @@ Michael Lechner
494Peter Schlenker 494Peter Schlenker
495Dan Davison 495Dan Davison
496David Kauffmann 496David Kauffmann
497Carsten Schreiter
497 498
498The libmad team 499The libmad team
499The wavpack team 500The wavpack team
diff --git a/firmware/target/arm/tcc780x/cowond2/button-cowond2.c b/firmware/target/arm/tcc780x/cowond2/button-cowond2.c
index a9b7265d4a..e66ba2332a 100644
--- a/firmware/target/arm/tcc780x/cowond2/button-cowond2.c
+++ b/firmware/target/arm/tcc780x/cowond2/button-cowond2.c
@@ -26,15 +26,65 @@
26#include "pcf50606.h" 26#include "pcf50606.h"
27#include "backlight.h" 27#include "backlight.h"
28#include "touchscreen.h" 28#include "touchscreen.h"
29#include "stdlib.h"
29 30
30#define TOUCH_MARGIN 8 31#define NO_OF_TOUCH_DATA 5
31 32
32static short last_x, last_y;
33static bool touch_available = false; 33static bool touch_available = false;
34static short x[NO_OF_TOUCH_DATA], y[NO_OF_TOUCH_DATA];
34 35
35void button_set_touch_available(void) 36/* comparator for qsort */
37static int short_cmp(const void *a, const void *b)
36{ 38{
37 touch_available = true; 39 return *(short*)a - *(short*)b;
40}
41
42void button_read_touch()
43{
44 unsigned char buf[3];
45
46 static long last_touch_interrupt = 0;
47 static int touch_data_index = 0;
48
49 /* put the touchscreen into idle mode */
50 pcf50606_write(PCF5060X_ADCC1, 0);
51
52 /* here the touch coordinates are read 5 times */
53 /* they will be sorted and the middle one will be used */
54 pcf50606_write(PCF5060X_ADCC2, (0xE<<1) | 1); /* ADC start X+Y */
55
56 do {
57 buf[1] = pcf50606_read(PCF5060X_ADCS2);
58 } while (!(buf[1] & 0x80)); /* Busy wait on ADCRDY flag */
59
60 buf[0] = pcf50606_read(PCF5060X_ADCS1);
61 buf[2] = pcf50606_read(PCF5060X_ADCS3);
62
63 pcf50606_write(PCF5060X_ADCC2, 0); /* ADC stop */
64
65 if (TIME_AFTER(current_tick, last_touch_interrupt + 1))
66 {
67 /* resets the index if the last touch could not be read 5 times */
68 touch_data_index = 0;
69 }
70
71 x[touch_data_index] = (buf[0] << 2) | (buf[1] & 3);
72 y[touch_data_index] = (buf[2] << 2) | ((buf[1] & 0xC) >> 2);
73
74 touch_data_index++;
75
76 if (touch_data_index > NO_OF_TOUCH_DATA - 1)
77 {
78 /* coordinates 5 times read */
79 touch_available = true;
80 touch_data_index = 0;
81 }
82 else
83 {
84 /* put the touchscreen back into the interrupt mode */
85 pcf50606_write(PCF5060X_ADCC1, 1);
86 }
87 last_touch_interrupt = current_tick;
38} 88}
39 89
40struct touch_calibration_point { 90struct touch_calibration_point {
@@ -107,7 +157,9 @@ int button_read_device(int *data)
107 157
108 static bool hold_button = false; 158 static bool hold_button = false;
109 bool hold_button_old; 159 bool hold_button_old;
110 160 static bool touch_hold = false;
161 static long last_touch = 0;
162
111 *data = old_data; 163 *data = old_data;
112 164
113 hold_button_old = hold_button; 165 hold_button_old = hold_button;
@@ -143,66 +195,45 @@ int button_read_device(int *data)
143 } 195 }
144 } 196 }
145 197
146 if (touch_available) 198 if (touch_available || touch_hold)
147 { 199 {
148 short x = 0, y = 0; 200 short x_touch, y_touch;
149 static long last_touch = 0; 201 static short last_x = 0, last_y = 0;
150 bool send_touch = false;
151 202
152 int irq_level = disable_irq_save(); 203 if (touch_hold)
153 if (pcf50606_read(PCF5060X_ADCC1) & 0x80) /* Pen down */
154 { 204 {
155 unsigned char buf[3]; 205 /* get rid of very fast unintended double touches */
156 206 x_touch = last_x;
157 pcf50606_write(PCF5060X_ADCC2, (0xE<<1) | 1); /* ADC start X+Y */ 207 y_touch = last_y;
158
159 do {
160 buf[1] = pcf50606_read(PCF5060X_ADCS2);
161 } while (!(buf[1] & 0x80)); /* Busy wait on ADCRDY flag */
162
163 buf[0] = pcf50606_read(PCF5060X_ADCS1);
164 buf[2] = pcf50606_read(PCF5060X_ADCS3);
165
166 pcf50606_write(PCF5060X_ADCC2, 0); /* ADC stop */
167
168 x = (buf[0] << 2) | (buf[1] & 3);
169 y = (buf[2] << 2) | ((buf[1] & 0xC) >> 2);
170
171 if (TIME_BEFORE(last_touch + HZ/5, current_tick))
172 {
173 if ((x > last_x + TOUCH_MARGIN) ||
174 (x < last_x - TOUCH_MARGIN) ||
175 (y > last_y + TOUCH_MARGIN) ||
176 (y < last_y - TOUCH_MARGIN))
177 {
178 send_touch = true;
179 }
180 }
181 else
182 {
183 send_touch = true;
184 }
185 } 208 }
186 restore_irq(irq_level); 209 else
187
188 if (send_touch)
189 { 210 {
190 last_x = x; 211 /* sort the 5 data taken and use the median value */
191 last_y = y; 212 qsort(x, NO_OF_TOUCH_DATA, sizeof(short), short_cmp);
192 old_data = *data = touch_to_pixels(x, y); 213 qsort(y, NO_OF_TOUCH_DATA, sizeof(short), short_cmp);
193 btn |= touchscreen_to_pixels((*data&0xffff0000)>>16, 214 x_touch = last_x = x[(NO_OF_TOUCH_DATA - 1)/2];
194 (*data&0x0000ffff), 215 y_touch = last_y = y[(NO_OF_TOUCH_DATA - 1)/2];
195 data); 216 last_touch = current_tick;
217 touch_hold = true;
218 touch_available = false;
196 } 219 }
220 old_data = *data = touch_to_pixels(x_touch, y_touch);
221 btn |= touchscreen_to_pixels((*data&0xffff0000)>>16,
222 (*data&0x0000ffff),
223 data);
224 }
197 225
198 last_touch = current_tick; 226 if (TIME_AFTER(current_tick, last_touch + 10))
199 touch_available = false; 227 {
228 /* put the touchscreen back into interrupt mode */
229 touch_hold = false;
230 pcf50606_write(PCF5060X_ADCC1, 1);
200 } 231 }
201 232
202 if (!(GPIOA & 0x4)) 233 if (!(GPIOA & 0x4))
203 btn |= BUTTON_POWER; 234 btn |= BUTTON_POWER;
204 235
205 if(btn & BUTTON_TOUCHSCREEN && !is_backlight_on(true)) 236 if (btn & BUTTON_TOUCHSCREEN && !is_backlight_on(true))
206 old_data = *data = 0; 237 old_data = *data = 0;
207 238
208 return btn; 239 return btn;
diff --git a/firmware/target/arm/tcc780x/cowond2/button-target.h b/firmware/target/arm/tcc780x/cowond2/button-target.h
index faf660fc71..1c224c57b2 100644
--- a/firmware/target/arm/tcc780x/cowond2/button-target.h
+++ b/firmware/target/arm/tcc780x/cowond2/button-target.h
@@ -30,7 +30,7 @@
30bool button_hold(void); 30bool button_hold(void);
31void button_init_device(void); 31void button_init_device(void);
32int button_read_device(int *data); 32int button_read_device(int *data);
33void button_set_touch_available(void); 33void button_read_touch(void);
34 34
35/* Main unit's buttons */ 35/* Main unit's buttons */
36#define BUTTON_POWER 0x00000001 36#define BUTTON_POWER 0x00000001
diff --git a/firmware/target/arm/tcc780x/cowond2/power-cowond2.c b/firmware/target/arm/tcc780x/cowond2/power-cowond2.c
index 5897370735..8190108dd4 100644
--- a/firmware/target/arm/tcc780x/cowond2/power-cowond2.c
+++ b/firmware/target/arm/tcc780x/cowond2/power-cowond2.c
@@ -81,7 +81,7 @@ void EXT3(void)
81 if (data[2] & 0x08) 81 if (data[2] & 0x08)
82 { 82 {
83 /* Touchscreen event, do something about it */ 83 /* Touchscreen event, do something about it */
84 button_set_touch_available(); 84 button_read_touch();
85 } 85 }
86} 86}
87#endif 87#endif