OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [edb7xxx/] [v2_0/] [misc/] [lcd_panel_support.c] - Blame information for rev 565

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//        panel_support.c
4
//
5
//        Cirrus Logic EDB7xxx eval board LCD touch panel support code
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:          1999-09-13
46
// Description:   Tool used to support the LCD touch panel
47
//####DESCRIPTIONEND####
48
 
49
static char lcd_panel_server_stack[STACK_SIZE];
50
static cyg_thread lcd_panel_server_thread_data;
51
static cyg_handle_t lcd_panel_server_thread_handle;
52
 
53
static cyg_interrupt lcd_panel_interrupt;
54
static cyg_handle_t  lcd_panel_interrupt_handle;
55
 
56
static cyg_mbox      lcd_panel_events_mbox;
57
static cyg_handle_t  lcd_panel_events_mbox_handle;
58
static cyg_sem_t     lcd_panel_sem;
59
 
60
#define SYNCIO_TXFRMEN     (1<<14)
61
#define SYNCIO_FRAMELEN(n) (n<<8)
62
#define ADC_START          (1<<7)
63
#define ADC_CHAN(n)        (n<<4)
64
#define ADC_UNIPOLAR       (1<<3)
65
#define ADC_SINGLE         (1<<2)
66
#define ADC_EXT_CLOCK      (3<<0)
67
#define TOUCH_CTL          KBD_PORT
68
 
69
// FUNCTIONS
70
 
71
static cyg_uint32
72
adc_sample(int chan)
73
{
74
    cyg_uint32 val;
75
    *(volatile cyg_uint32 *)SYNCIO = SYNCIO_TXFRMEN | SYNCIO_FRAMELEN(24) |
76
        ADC_START | ADC_CHAN(chan) | ADC_UNIPOLAR | ADC_SINGLE | ADC_EXT_CLOCK;
77
    while (*(volatile cyg_uint32 *)SYSFLG1 & SYSFLG1_SSIBUSY) ;
78
    val = *(volatile cyg_uint32 *)SYNCIO;
79
    return (val & 0xFFFF);
80
}
81
 
82
static void
83
panel_delay(void)
84
{
85
    volatile int i;
86
    for (i = 0;  i < 800;  i++) ;
87
}
88
 
89
// This ISR is called when the touch panel interrupt occurs
90
static int
91
lcd_panel_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
92
{
93
    cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_EINT2);
94
    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
95
}
96
 
97
// This DSR starts up the touch panel [logical] processing
98
static void
99
lcd_panel_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
100
{
101
    // Tell the panel processing thread to give it a shot
102
    cyg_semaphore_post(&lcd_panel_sem);
103
}
104
 
105
// Assumption: if the keypress vanishes for 5*20 ms, it probably isn't there
106
#define LCD_PANEL_TIMEOUT 5
107
 
108
static __inline__ int
109
abs(int x)
110
{
111
    if (x < 0) return -x;
112
    return x;
113
}
114
 
115
static void
116
lcd_panel_server(cyg_addrword_t p)
117
{
118
    int iX, iY, newX, newY, diffX, diffY, timeout, samples;
119
    cyg_uint32 event;
120
    diag_printf("LCD panel server here\n");
121
    while (TRUE) {
122
        cyg_semaphore_wait(&lcd_panel_sem);
123
        samples = 0;  iX = 0;  iY = 0;
124
        // Wait for press to go away (no drag support)
125
        timeout = 0;
126
        while (timeout < LCD_PANEL_TIMEOUT) {
127
            *(volatile cyg_uint8 *)TOUCH_CTL = 0x00;  // Disable drives
128
            while (*(volatile cyg_uint32 *)INTSR1 & INTSR1_EINT2) ;
129
            *(volatile cyg_uint8 *)TOUCH_CTL = 0x70;  // Idle state (so interrupt works)
130
            cyg_thread_delay(2);  // Wait 20 ms
131
            if (*(volatile cyg_uint32 *)INTSR1 & INTSR1_EINT2) {
132
                // Still pressed
133
                // Drive TSPY, ground TSMY, and disconnect TSPX and TSMX
134
                *(volatile cyg_uint8 *)TOUCH_CTL = 0x50;
135
                panel_delay();
136
                newY = adc_sample(2);
137
                // Drive TSPX, ground TSMX, and disconnect TSPY and TSMY
138
                *(volatile cyg_uint8 *)TOUCH_CTL = 0xA0;
139
                panel_delay();
140
                newX = adc_sample(7);
141
#if 0
142
                diag_printf("timeout: %d, ISR: %x, newX: %d, newY: %d\n",
143
                            timeout, *(volatile cyg_uint32 *)INTSR1, newX, newY);
144
#endif
145
                // See if this sample makes any sense
146
                if (samples) {
147
                    diffX = abs(iX/samples - newX);
148
                    diffY = abs(iY/samples - newY);
149
                    if ((diffX <= ((iX/samples)/4)) &&
150
                        (diffY <= ((iY/samples)/4))) {
151
                        samples++;
152
                        iX += newX;
153
                        iY += newY;
154
                    } else {
155
#if 0
156
                        diag_printf("Discard - newX: %d, X: %d, newY: %d, Y: %d\n",
157
                                    newX, iX/samples, newY, iY/samples);
158
#endif
159
                        break;
160
                    }
161
                } else {
162
                    iX = newX;
163
                    iY = newY;
164
                    samples = 1;
165
                }
166
                timeout = 0;
167
            } else {
168
                timeout++;
169
            }
170
        }
171
        if (samples) {
172
            // Send event to user level
173
            event = (iX/samples)<<16 | (iY/samples);
174
            if (!cyg_mbox_tryput(lcd_panel_events_mbox_handle, (void *)event)) {
175
                diag_printf("LCD event lost: %x\n", event);
176
            }
177
        }
178
        *(volatile cyg_uint8 *)TOUCH_CTL = 0x00;  // Disable drives
179
        while (*(volatile cyg_uint32 *)INTSR1 & INTSR1_EINT2) ;
180
        *(volatile cyg_uint8 *)TOUCH_CTL = 0x70;  // Idle state (so interrupt works)
181
        cyg_thread_delay(10);
182
        cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EINT2);
183
    }
184
}
185
 
186
static void
187
lcd_panel_init(void)
188
{
189
    // Enable touch panel
190
    *(volatile cyg_uint8 *)PEDR   |= 0x04;
191
 
192
    // Idle state (so interrupt works)
193
    *(volatile cyg_uint8 *)TOUCH_CTL = 0x70;
194
 
195
    // Enable ADC machinery
196
    *(volatile cyg_uint32 *)SYSCON1 |= SYSCON1_ADC_CLOCK_128kHZ;
197
 
198
    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_EINT2,
199
                             99,                     // Priority - what goes here?
200
                             0,                      //  Data item passed to interrupt handler
201
                             lcd_panel_isr,
202
                             lcd_panel_dsr,
203
                             &lcd_panel_interrupt_handle,
204
                             &lcd_panel_interrupt);
205
    cyg_drv_interrupt_attach(lcd_panel_interrupt_handle);
206
    cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_EINT2);
207
    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EINT2);
208
    // Set up the mbox for panel data
209
    cyg_mbox_create(&lcd_panel_events_mbox_handle, &lcd_panel_events_mbox);
210
    // This semaphore is set when there is a touch
211
    cyg_semaphore_init(&lcd_panel_sem, 0);
212
    // Create a thread whose job it is to de-bounce the keyboard and
213
    // actually process the input, turning it into a series of events
214
    cyg_thread_create(10,                           // Priority - just a number
215
                      lcd_panel_server,             // entry
216
                      0,                            // initial parameter
217
                      "LCD_PANEL_server",           // Name
218
                      &lcd_panel_server_stack[0],   // Stack
219
                      STACK_SIZE,                   // Size
220
                      &lcd_panel_server_thread_handle,    // Handle
221
                      &lcd_panel_server_thread_data       // Thread data structure
222
            );
223
    cyg_thread_resume(lcd_panel_server_thread_handle);  // Start it
224
}

powered by: WebSVN 2.1.0

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