summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s3c2440/mini2440/touchscreen-mini2440.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/s3c2440/mini2440/touchscreen-mini2440.c')
-rw-r--r--firmware/target/arm/s3c2440/mini2440/touchscreen-mini2440.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/firmware/target/arm/s3c2440/mini2440/touchscreen-mini2440.c b/firmware/target/arm/s3c2440/mini2440/touchscreen-mini2440.c
new file mode 100644
index 0000000000..ce7c8d5dd7
--- /dev/null
+++ b/firmware/target/arm/s3c2440/mini2440/touchscreen-mini2440.c
@@ -0,0 +1,190 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___void
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Rob Purchase
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 "touchscreen-target.h"
24#include "adc-target.h"
25#include "system.h"
26#include "stdlib.h"
27#include "button.h"
28#include "touchscreen.h"
29
30#define NO_OF_TOUCH_DATA 5
31
32struct touch_calibration_point {
33 short px_x; /* known pixel value */
34 short px_y;
35 short val_x; /* touchscreen value at the known pixel */
36 short val_y;
37};
38
39static struct touch_calibration_point topleft, bottomright;
40
41static bool touch_available = false;
42
43static short x[NO_OF_TOUCH_DATA], y[NO_OF_TOUCH_DATA];
44
45/* comparator for qsort */
46static int short_cmp(const void *a, const void *b)
47{
48 return *(short*)a - *(short*)b;
49}
50
51static int touch_to_pixels(short val_x, short val_y)
52{
53 short x,y;
54
55 x=val_x;
56 y=val_y;
57
58 x = (x-topleft.val_x)*(bottomright.px_x - topleft.px_x)
59 / (bottomright.val_x - topleft.val_x) + topleft.px_x;
60
61 y = (y-topleft.val_y)*(bottomright.px_y - topleft.px_y)
62 / (bottomright.val_y - topleft.val_y) + topleft.px_y;
63
64 if (x < 0)
65 x = 0;
66 else if (x>=LCD_WIDTH)
67 x=LCD_WIDTH-1;
68
69 if (y < 0)
70 y = 0;
71 else if (y>=LCD_HEIGHT)
72 y=LCD_HEIGHT-1;
73
74 return (x<<16)|y;
75}
76
77void touchscreen_init_device()
78{
79 /* set touchscreen adc controller into wait for interrupt mode */
80 ADCTSC = 0xd3; /* Wfait,XP-PU,XP_DIS,XM_DIS,YP_dis,YM_end */
81
82 /* Arbitrary touchscreen calibration */
83 topleft.px_x = 0;
84 topleft.px_y = 0;
85 topleft.val_x = 105;
86 topleft.val_y = 925;
87
88 bottomright.px_x = LCD_WIDTH;
89 bottomright.px_y = LCD_HEIGHT;
90 bottomright.val_x = 890;
91 bottomright.val_y = 105;
92
93 touch_available = false;
94}
95
96void touchscreen_scan_device()
97{
98 static long last_touch_read = 0;
99 static int touch_data_index = 0;
100
101 int saveADCDLY;
102
103 /* check touch state */
104 if(ADCDAT1 & (1<<15))
105 {
106 return;
107 }
108
109 if (TIME_AFTER(current_tick, last_touch_read + 1))
110 {
111 /* resets the index if the last touch could not be read 5 times */
112 touch_data_index = 0;
113 }
114
115 /* read touch data */
116 saveADCDLY = ADCDLY;
117 ADCDLY = 40000; /*delay ~0.8ms (1/50M)*4000 */
118 ADCTSC = (1<<3)|(1<<2); /* pullup disable, seq x,y pos measure */
119 /* start adc */
120 ADCCON|= 0x1;
121 /* wait for start and end */
122 while(ADCCON & 0x1);
123 while(!(ADCCON & 0x8000));
124
125 x[touch_data_index] = ADCDAT0&0x3ff;
126 y[touch_data_index] = ADCDAT1&0x3ff;
127
128 ADCTSC = 0xd3; /* back to interrupt mode */
129 ADCDLY = saveADCDLY;
130
131 touch_data_index++;
132
133 if (touch_data_index > NO_OF_TOUCH_DATA - 1)
134 {
135 /* coordinates 5 times read */
136 touch_available = true;
137 touch_data_index = 0;
138 }
139 last_touch_read = current_tick;
140}
141
142int touchscreen_read_device(int *data, int *old_data)
143{
144 int btn = BUTTON_NONE;
145 static bool touch_hold = false;
146 static long last_touch = 0;
147
148 if (touch_available || touch_hold)
149 {
150 short x_touch, y_touch;
151 static short last_x = 0, last_y = 0;
152
153 if (touch_hold)
154 {
155 /* get rid of very fast unintended double touches */
156 x_touch = last_x;
157 y_touch = last_y;
158 }
159 else
160 {
161 /* sort the 5 data taken and use the median value */
162 qsort(x, NO_OF_TOUCH_DATA, sizeof(short), short_cmp);
163 qsort(y, NO_OF_TOUCH_DATA, sizeof(short), short_cmp);
164
165 x_touch = last_x = x[(NO_OF_TOUCH_DATA - 1)/2];
166 y_touch = last_y = y[(NO_OF_TOUCH_DATA - 1)/2];
167
168 last_touch = current_tick;
169
170 touch_hold = true;
171 touch_available = false;
172 }
173
174 *old_data = *data = touch_to_pixels(x_touch, y_touch);
175
176 btn |= touchscreen_to_pixels((*data&0xffff0000) >> 16,
177 (*data&0x0000ffff),
178 data);
179 }
180
181 if (TIME_AFTER(current_tick, last_touch + 10))
182 {
183 /* put the touchscreen back into interrupt mode */
184 touch_hold = false;
185 }
186
187 return btn;
188}
189
190