OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [devs/] [touch/] [arm/] [ipaq/] [v2_0/] [src/] [ipaq_ts.c] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      ipaq_ts.c
4
//
5
//      Touchscreen driver for the Compaq iPAQ
6
//
7
//==========================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//==========================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):    gthomas
44
// Contributors: gthomas
45
// Date:         2001-03-05
46
// Purpose:      
47
// Description:  Touchscreen driver for Compaq IPAQ
48
//
49
//####DESCRIPTIONEND####
50
//
51
//==========================================================================
52
 
53
 
54
#include <pkgconf/devs_touch_ipaq.h>
55
 
56
#include <cyg/kernel/kapi.h>
57
#include <cyg/hal/hal_io.h>
58
#include <cyg/hal/hal_arch.h>
59
#include <cyg/hal/drv_api.h>
60
#include <cyg/hal/hal_intr.h>
61
#include <cyg/hal/hal_sa11x0.h>
62
#include <cyg/hal/ipaq.h>
63
#include <cyg/infra/cyg_type.h>
64
#include <cyg/infra/cyg_ass.h>
65
 
66
#include <cyg/fileio/fileio.h>  // For select() functionality
67
static cyg_selinfo      ts_select_info;
68
static cyg_bool         ts_select_active;
69
 
70
#include <cyg/io/devtab.h>
71
#include <cyg/hal/atmel_support.h>
72
 
73
// Functions in this module
74
 
75
static Cyg_ErrNo ts_read(cyg_io_handle_t handle,
76
                         void *buffer,
77
                         cyg_uint32 *len);
78
static cyg_bool  ts_select(cyg_io_handle_t handle,
79
                           cyg_uint32 which,
80
                           cyg_addrword_t info);
81
static Cyg_ErrNo ts_set_config(cyg_io_handle_t handle,
82
                               cyg_uint32 key,
83
                               const void *buffer,
84
                               cyg_uint32 *len);
85
static Cyg_ErrNo ts_get_config(cyg_io_handle_t handle,
86
                               cyg_uint32 key,
87
                               void *buffer,
88
                               cyg_uint32 *len);
89
static bool      ts_init(struct cyg_devtab_entry *tab);
90
static Cyg_ErrNo ts_lookup(struct cyg_devtab_entry **tab,
91
                           struct cyg_devtab_entry *st,
92
                           const char *name);
93
 
94
CHAR_DEVIO_TABLE(ipaq_ts_handlers,
95
                 NULL,                                   // Unsupported write() function
96
                 ts_read,
97
                 ts_select,
98
                 ts_get_config,
99
                 ts_set_config);
100
 
101
CHAR_DEVTAB_ENTRY(ipaq_ts_device,
102
                  CYGDAT_DEVS_TOUCH_IPAQ_NAME,
103
                  NULL,                                   // Base device name
104
                  &ipaq_ts_handlers,
105
                  ts_init,
106
                  ts_lookup,
107
                  NULL);                                  // Private data pointer
108
 
109
struct _event {
110
    short button_state;
111
    short xPos, yPos;
112
    short _unused;
113
};
114
#define MAX_EVENTS CYGNUM_DEVS_TOUCH_IPAQ_EVENT_BUFFER_SIZE
115
static int   num_events;
116
static int   _event_put, _event_get;
117
static bool  pen_down = false;
118
static struct _event _events[MAX_EVENTS];
119
 
120
static bool _is_open = false;
121
#ifdef DEBUG_RAW_EVENTS
122
static unsigned char _ts_buf[512];
123
static int _ts_buf_ptr = 0;
124
#endif
125
 
126
//
127
// Note: this routine is called from the Atmel processing DSR
128
//
129
static void
130
ts_handler(atmel_pkt *pkt)
131
{
132
    unsigned char *dp = pkt->data;
133
    static short lastX, lastY;
134
    short x, y;
135
    struct _event *ev;
136
 
137
#ifdef DEBUG_RAW_EVENTS
138
    memcpy(&_ts_buf[_ts_buf_ptr], pkt->data, 8);
139
    _ts_buf_ptr += 8;
140
    if (_ts_buf_ptr == 512) {
141
        diag_printf("TS handler\n");
142
        diag_dump_buf(_ts_buf, 512);
143
        _ts_buf_ptr = 0;
144
    }
145
#endif
146
    // Try and interpret the mouse data
147
    if ((dp[0] & 0x0F) == 0) {
148
        // This is a pen up event
149
        x = lastX;
150
        y = lastY;
151
        pen_down = false;
152
    } else {
153
        // Some sort of event with the pen down        
154
        x = lastX = (dp[1] << 8) | dp[2];
155
        y = lastY = (dp[3] << 8) | dp[4];
156
        pen_down = true;
157
    }
158
    if (num_events < MAX_EVENTS) {
159
        num_events++;
160
        ev = &_events[_event_put++];
161
        if (_event_put == MAX_EVENTS) {
162
            _event_put = 0;
163
        }
164
        ev->button_state = pen_down ? 0x04 : 0x00;
165
        ev->xPos = x;
166
        ev->yPos = y;
167
        if (ts_select_active) {
168
            ts_select_active = false;
169
            cyg_selwakeup(&ts_select_info);
170
        }
171
    }
172
}
173
 
174
typedef struct {
175
    short min;
176
    short max;
177
    short span;
178
} bounds;
179
 
180
static bounds xBounds = {1024, 0, 1024};
181
static bounds yBounds = {1024, 0, 1024};
182
 
183
static Cyg_ErrNo
184
ts_read(cyg_io_handle_t handle,
185
        void *buffer,
186
        cyg_uint32 *len)
187
{
188
    struct _event *ev;
189
    int tot = *len;
190
    unsigned char *bp = (unsigned char *)buffer;
191
 
192
    cyg_scheduler_lock();  // Prevent interaction with DSR code
193
    while (tot >= sizeof(struct _event)) {
194
        if (num_events > 0) {
195
            ev = &_events[_event_get++];
196
            if (_event_get == MAX_EVENTS) {
197
                _event_get = 0;
198
            }
199
            // Self calibrate
200
            if (ev->xPos > xBounds.max) xBounds.max = ev->xPos;
201
            if (ev->xPos < xBounds.min) xBounds.min = ev->xPos;
202
            if (ev->yPos > yBounds.max) yBounds.max = ev->yPos;
203
            if (ev->yPos < yBounds.min) yBounds.min = ev->yPos;
204
            if ((xBounds.span = xBounds.max - xBounds.min) <= 1) {
205
                xBounds.span = 1;
206
            }
207
            if ((yBounds.span = yBounds.max - yBounds.min) <= 1) {
208
                yBounds.span = 1;
209
            }
210
            // Scale values - done here so these potentially lengthy
211
            // operations take place outside of interrupt processing
212
            ev->xPos = ((xBounds.max - ev->xPos) * 320) / xBounds.span;
213
            ev->yPos = ((yBounds.max - ev->yPos) * 240) / yBounds.span;
214
            memcpy(bp, ev, sizeof(*ev));
215
            bp += sizeof(*ev);
216
            tot -= sizeof(*ev);
217
            num_events--;
218
        } else {
219
            break;  // No more events
220
        }
221
    }
222
    cyg_scheduler_unlock(); // Allow DSRs again
223
    *len -= tot;
224
    return ENOERR;
225
}
226
 
227
static cyg_bool
228
ts_select(cyg_io_handle_t handle,
229
          cyg_uint32 which,
230
          cyg_addrword_t info)
231
{
232
    if (which == CYG_FREAD) {
233
        cyg_scheduler_lock();  // Prevent interaction with DSR code
234
        if (num_events > 0) {
235
            cyg_scheduler_unlock();  // Reallow interaction with DSR code
236
            return true;
237
        }
238
        if (!ts_select_active) {
239
            ts_select_active = true;
240
            cyg_selrecord(info, &ts_select_info);
241
        }
242
        cyg_scheduler_unlock();  // Reallow interaction with DSR code
243
    }
244
    return false;
245
}
246
 
247
static Cyg_ErrNo
248
ts_set_config(cyg_io_handle_t handle,
249
              cyg_uint32 key,
250
              const void *buffer,
251
              cyg_uint32 *len)
252
{
253
    return EINVAL;
254
}
255
 
256
static Cyg_ErrNo
257
ts_get_config(cyg_io_handle_t handle,
258
              cyg_uint32 key,
259
              void *buffer,
260
              cyg_uint32 *len)
261
{
262
    return EINVAL;
263
}
264
 
265
static bool
266
ts_init(struct cyg_devtab_entry *tab)
267
{
268
    cyg_selinit(&ts_select_info);
269
    return true;
270
}
271
 
272
static Cyg_ErrNo
273
ts_lookup(struct cyg_devtab_entry **tab,
274
          struct cyg_devtab_entry *st,
275
          const char *name)
276
{
277
    if (!_is_open) {
278
        _is_open = true;
279
        atmel_register(ATMEL_CMD_TOUCH, ts_handler);
280
        atmel_interrupt_mode(true);
281
    }
282
    return ENOERR;
283
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.