source: rtems/c/src/lib/libbsp/arm/nds/libnds/source/arm7/touch.c @ ca11e781

4.104.115
Last change on this file since ca11e781 was ca11e781, checked in by Ralf Corsepius <ralf.corsepius@…>, on 12/07/09 at 07:12:20

Eliminate various warnings.

  • Property mode set to 100644
File size: 8.7 KB
Line 
1/*---------------------------------------------------------------------------------
2        $Id$
3
4        Touch screen control for the ARM7
5
6        Copyright (C) 2005
7                Michael Noland (joat)
8                Jason Rogers (dovoto)
9                Dave Murphy (WinterMute)
10
11        This software is provided 'as-is', without any express or implied
12        warranty.  In no event will the authors be held liable for any
13        damages arising from the use of this software.
14
15        Permission is granted to anyone to use this software for any
16        purpose, including commercial applications, and to alter it and
17        redistribute it freely, subject to the following restrictions:
18
19        1.      The origin of this software must not be misrepresented; you
20                        must not claim that you wrote the original software. If you use
21                        this software in a product, an acknowledgment in the product
22                        documentation would be appreciated but is not required.
23        2.      Altered source versions must be plainly marked as such, and
24                        must not be misrepresented as being the original software.
25        3.      This notice may not be removed or altered from any source
26                        distribution.
27
28---------------------------------------------------------------------------------*/
29
30#include <nds/jtypes.h>
31#include <nds/system.h>
32#include <nds/arm7/touch.h>
33#include <nds/interrupts.h>
34
35#include <stdlib.h>
36
37static u8 last_time_touched = 0;
38
39static u8 range_counter_1 = 0;
40static u8 range_counter_2 = 0;
41static u8 range = 20;
42static u8 min_range = 20;
43
44//---------------------------------------------------------------------------------
45u8 CheckStylus(void){
46//---------------------------------------------------------------------------------
47
48        SerialWaitBusy();
49
50        REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS; //0x8A01;
51        REG_SPIDATA = TSC_MEASURE_TEMP1;
52
53        SerialWaitBusy();
54
55        REG_SPIDATA = 0;
56
57        SerialWaitBusy();
58
59        REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH;// 0x8201;
60        REG_SPIDATA = 0;
61
62        SerialWaitBusy();
63
64        if(last_time_touched == 1){
65                if( !(REG_KEYXY & 0x40) )
66                        return 1;
67                else{
68                        REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS;
69                        REG_SPIDATA = TSC_MEASURE_TEMP1;
70
71                        SerialWaitBusy();
72
73                        REG_SPIDATA = 0;
74
75                        SerialWaitBusy();
76
77                        REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH;
78                        REG_SPIDATA = 0;
79
80                        SerialWaitBusy();
81
82                        return !(REG_KEYXY & 0x40) ? 2 : 0;
83                }
84        }else{
85                return !(REG_KEYXY & 0x40) ? 1 : 0;
86        }
87}
88
89//---------------------------------------------------------------------------------
90uint16 touchRead(uint32 command) {
91//---------------------------------------------------------------------------------
92        uint16 result, result2;
93
94        uint32 oldIME = REG_IME;
95
96        REG_IME = 0;
97
98        SerialWaitBusy();
99
100        // Write the command and wait for it to complete
101        REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS; //0x8A01;
102        REG_SPIDATA = command;
103        SerialWaitBusy();
104
105        // Write the second command and clock in part of the data
106        REG_SPIDATA = 0;
107        SerialWaitBusy();
108        result = REG_SPIDATA;
109
110        // Clock in the rest of the data (last transfer)
111        REG_SPICNT = SPI_ENABLE | 0x201;
112        REG_SPIDATA = 0;
113        SerialWaitBusy();
114
115        result2 = REG_SPIDATA >>3;
116
117        REG_IME = oldIME;
118
119        // Return the result
120        return ((result & 0x7F) << 5) | result2;
121}
122
123
124//---------------------------------------------------------------------------------
125uint32 touchReadTemperature(int * t1, int * t2) {
126//---------------------------------------------------------------------------------
127        *t1 = touchRead(TSC_MEASURE_TEMP1);
128        *t2 = touchRead(TSC_MEASURE_TEMP2);
129        return 8490 * (*t2 - *t1) - 273*4096;
130}
131
132
133static bool touchInit = false;
134static s32 xscale, yscale;
135static s32 xoffset, yoffset;
136
137//---------------------------------------------------------------------------------
138int16 readTouchValue(uint32 command, int16 *dist_max, u8 *err){
139//---------------------------------------------------------------------------------
140        int16 values[5];
141        int32 aux1, aux2, aux3, dist, dist2, result = 0;
142        u8 i, j, k;
143
144        *err = 1;
145
146        SerialWaitBusy();
147
148        REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS;
149        REG_SPIDATA = command;
150
151        SerialWaitBusy();
152
153        for(i=0; i<5; i++){
154                REG_SPIDATA = 0;
155                SerialWaitBusy();
156
157                aux1 = REG_SPIDATA;
158                aux1 = aux1 & 0xFF;
159                aux1 = aux1 << 16;
160                aux1 = aux1 >> 8;
161
162                values[4-i] = aux1;
163
164                REG_SPIDATA = command;
165                SerialWaitBusy();
166
167                aux1 = REG_SPIDATA;
168                aux1 = aux1 & 0xFF;
169                aux1 = aux1 << 16;
170
171                aux1 = values[4-i] | (aux1 >> 16);
172                values[4-i] = ((aux1 & 0x7FF8) >> 3);
173        }
174
175        REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH;
176        REG_SPIDATA = 0;
177        SerialWaitBusy();
178
179        dist = 0;
180        for(i=0; i<4; i++){
181                aux1 = values[i];
182
183                for(j=i+1; j<5; j++){
184                        aux2 = values[j];
185                        aux2 = abs(aux1 - aux2);
186                        if(aux2>dist) dist = aux2;
187                }
188        }
189
190        *dist_max = dist;
191
192        for(i=0; i<3; i++){
193                aux1 = values[i];
194
195                for(j=i+1; j<4; j++){
196                        aux2 = values[j];
197                        dist = abs(aux1 - aux2);
198
199                        if( dist <= range ){
200                                for(k=j+1; k<5; k++){
201                                        aux3 = values[k];
202                                        dist2 = abs(aux1 - aux3);
203
204                                        if( dist2 <= range ){
205                                                result = aux2 + (aux1 << 1);
206                                                result = result + aux3;
207                                                result = result >> 2;
208                                                result = result & (~7);
209
210                                                *err = 0;
211
212                                                break;
213                                        }
214                                }
215                        }
216                }
217        }
218
219        if((*err) == 1){
220                result = values[0] + values[4];
221                result = result >> 1;
222                result = result & (~7);
223        }
224
225        return (result & 0xFFF);
226}
227
228//---------------------------------------------------------------------------------
229void UpdateRange(uint8 *this_range, int16 last_dist_max, u8 data_error, u8 tsc_touched){
230//---------------------------------------------------------------------------------
231        //range_counter_1 = counter_0x380A98C
232        //range_counter_2 = counter_0x380A990
233        //Initial values:
234        // range = 20
235        // min_range = 20
236
237        if(tsc_touched != 0){
238                if( data_error == 0){
239                        range_counter_2 = 0;
240
241                        if( last_dist_max >= ((*this_range) >> 1)){
242                                range_counter_1 = 0;
243                        }else{
244                                range_counter_1++;
245
246                                if(range_counter_1 >= 4){
247                                        range_counter_1 = 0;
248
249                                        if((*this_range) > min_range){
250                                                (*this_range)--;
251                                                range_counter_2 = 3;
252                                        }
253                                }
254                        }
255                }else{
256                        range_counter_1 = 0;
257                        range_counter_2++;
258
259                        if(range_counter_2 >= 4){
260
261                                range_counter_2 = 0;
262
263                                if((*this_range) < 35){  //0x23 = 35
264                                        *this_range = (*this_range) + 1;
265                                }
266                        }
267                }
268        }else{
269                range_counter_2 = 0;
270                range_counter_1 = 0;
271        }
272}
273
274//---------------------------------------------------------------------------------
275// reading pixel position:
276//---------------------------------------------------------------------------------
277touchPosition touchReadXY() {
278//---------------------------------------------------------------------------------
279
280        int16 dist_max_y, dist_max_x, dist_max;
281        u8 error, error_where, first_check, i;
282
283        touchPosition touchPos = { 0, 0, 0, 0, 0, 0 };
284
285        if ( !touchInit ) {
286
287                xscale = ((PersonalData->calX2px - PersonalData->calX1px) << 19) / ((PersonalData->calX2) - (PersonalData->calX1));
288                yscale = ((PersonalData->calY2px - PersonalData->calY1px) << 19) / ((PersonalData->calY2) - (PersonalData->calY1));
289
290                xoffset = ((PersonalData->calX1 + PersonalData->calX2) * xscale  - ((PersonalData->calX1px + PersonalData->calX2px) << 19) ) / 2;
291                yoffset = ((PersonalData->calY1 + PersonalData->calY2) * yscale  - ((PersonalData->calY1px + PersonalData->calY2px) << 19) ) / 2;
292                touchInit = true;
293        }
294
295        uint32 oldIME = REG_IME;
296
297        REG_IME = 0;
298
299        first_check = CheckStylus();
300        if(first_check != 0){
301                error_where = 0;
302
303                touchPos.z1 =  readTouchValue(TSC_MEASURE_Z1 | 1, &dist_max, &error);
304                touchPos.z2 =  readTouchValue(TSC_MEASURE_Z2 | 1, &dist_max, &error);
305
306                touchPos.x = readTouchValue(TSC_MEASURE_X | 1, &dist_max_x, &error);
307                if(error==1) error_where += 1;
308
309                touchPos.y = readTouchValue(TSC_MEASURE_Y | 1, &dist_max_y, &error);
310                if(error==1) error_where += 2;
311
312                REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS;
313                for(i=0; i<12; i++){
314                        REG_SPIDATA = 0;
315
316                        SerialWaitBusy();
317                }
318
319                REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH;
320                REG_SPIDATA = 0;
321
322                SerialWaitBusy();
323
324                if(first_check == 2) error_where = 3;
325
326                switch( CheckStylus() ){
327                case 0:
328                        last_time_touched = 0;
329                        break;
330                case 1:
331                        last_time_touched = 1;
332
333                        if(dist_max_x > dist_max_y)
334                                dist_max = dist_max_x;
335                        else
336                                dist_max = dist_max_y;
337
338                        break;
339                case 2:
340                        last_time_touched = 0;
341                        error_where = 3;
342
343                        break;
344                }
345
346                s16 px = ( touchPos.x * xscale - xoffset + xscale/2 ) >>19;
347                s16 py = ( touchPos.y * yscale - yoffset + yscale/2 ) >>19;
348
349                if ( px < 0) px = 0;
350                if ( py < 0) py = 0;
351                if ( px > (SCREEN_WIDTH -1)) px = SCREEN_WIDTH -1;
352                if ( py > (SCREEN_HEIGHT -1)) py = SCREEN_HEIGHT -1;
353
354                touchPos.px = px;
355                touchPos.py = py;
356
357
358        }else{
359                error_where = 3;
360                touchPos.x = 0;
361                touchPos.y = 0;
362                last_time_touched = 0;
363        }
364
365        UpdateRange(&range, dist_max, error_where, last_time_touched);
366
367        REG_IME = oldIME;
368
369
370        return touchPos;
371
372}
373
Note: See TracBrowser for help on using the repository browser.