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

4.115
Last change on this file since ef4c461 was ef4c461, checked in by Joel Sherrill <joel.sherrill@…>, on 10/09/14 at 20:35:10

arm/nds: Warning clean up

This patch eliminates most of the warnings in this BSP but attempts
very little clean up. This BSP includes copies of a lot of code
from free NDS libraries and modifications should be kept to a minimum.

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