⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd_panel_support.c

📁 Intel XScale PXA255 引导Linux的Redboot 版bootloader源代码!
💻 C
字号:
//==========================================================================////        panel_support.c////        Cirrus Logic EDB7xxx eval board LCD touch panel support code////==========================================================================//####COPYRIGHTBEGIN####//                                                                          // -------------------------------------------                              // The contents of this file are subject to the Red Hat eCos Public License // Version 1.1 (the "License"); you may not use this file except in         // compliance with the License.  You may obtain a copy of the License at    // http://www.redhat.com/                                                   //                                                                          // Software distributed under the License is distributed on an "AS IS"      // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the // License for the specific language governing rights and limitations under // the License.                                                             //                                                                          // The Original Code is eCos - Embedded Configurable Operating System,      // released September 30, 1998.                                             //                                                                          // The Initial Developer of the Original Code is Red Hat.                   // Portions created by Red Hat are                                          // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             // All Rights Reserved.                                                     // -------------------------------------------                              //                                                                          //####COPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):     gthomas// Contributors:  gthomas// Date:          1999-09-13// Description:   Tool used to support the LCD touch panel//####DESCRIPTIONEND####static char lcd_panel_server_stack[STACK_SIZE];static cyg_thread lcd_panel_server_thread_data;static cyg_handle_t lcd_panel_server_thread_handle;static cyg_interrupt lcd_panel_interrupt;static cyg_handle_t  lcd_panel_interrupt_handle;static cyg_mbox      lcd_panel_events_mbox;static cyg_handle_t  lcd_panel_events_mbox_handle;static cyg_sem_t     lcd_panel_sem;#define SYNCIO_TXFRMEN     (1<<14)#define SYNCIO_FRAMELEN(n) (n<<8)#define ADC_START          (1<<7)#define ADC_CHAN(n)        (n<<4)#define ADC_UNIPOLAR       (1<<3)#define ADC_SINGLE         (1<<2)#define ADC_EXT_CLOCK      (3<<0)#define TOUCH_CTL          KBD_PORT// FUNCTIONSstatic cyg_uint32adc_sample(int chan){    cyg_uint32 val;    *(volatile cyg_uint32 *)SYNCIO = SYNCIO_TXFRMEN | SYNCIO_FRAMELEN(24) |        ADC_START | ADC_CHAN(chan) | ADC_UNIPOLAR | ADC_SINGLE | ADC_EXT_CLOCK;    while (*(volatile cyg_uint32 *)SYSFLG1 & SYSFLG1_SSIBUSY) ;    val = *(volatile cyg_uint32 *)SYNCIO;    return (val & 0xFFFF);}static voidpanel_delay(void){    volatile int i;    for (i = 0;  i < 800;  i++) ;}// This ISR is called when the touch panel interrupt occursstatic int lcd_panel_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs){    cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_EINT2);    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR}// This DSR starts up the touch panel [logical] processingstatic voidlcd_panel_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data){    // Tell the panel processing thread to give it a shot    cyg_semaphore_post(&lcd_panel_sem);}// Assumption: if the keypress vanishes for 5*20 ms, it probably isn't there#define LCD_PANEL_TIMEOUT 5static __inline__ intabs(int x){    if (x < 0) return -x;    return x;}static voidlcd_panel_server(cyg_addrword_t p){    int iX, iY, newX, newY, diffX, diffY, timeout, samples;    cyg_uint32 event;    diag_printf("LCD panel server here\n");    while (TRUE) {        cyg_semaphore_wait(&lcd_panel_sem);        samples = 0;  iX = 0;  iY = 0;        // Wait for press to go away (no drag support)        timeout = 0;        while (timeout < LCD_PANEL_TIMEOUT) {            *(volatile cyg_uint8 *)TOUCH_CTL = 0x00;  // Disable drives            while (*(volatile cyg_uint32 *)INTSR1 & INTSR1_EINT2) ;            *(volatile cyg_uint8 *)TOUCH_CTL = 0x70;  // Idle state (so interrupt works)            cyg_thread_delay(2);  // Wait 20 ms            if (*(volatile cyg_uint32 *)INTSR1 & INTSR1_EINT2) {                // Still pressed                // Drive TSPY, ground TSMY, and disconnect TSPX and TSMX                *(volatile cyg_uint8 *)TOUCH_CTL = 0x50;                  panel_delay();                newY = adc_sample(2);                // Drive TSPX, ground TSMX, and disconnect TSPY and TSMY                *(volatile cyg_uint8 *)TOUCH_CTL = 0xA0;                  panel_delay();                newX = adc_sample(7);#if 0                diag_printf("timeout: %d, ISR: %x, newX: %d, newY: %d\n",                             timeout, *(volatile cyg_uint32 *)INTSR1, newX, newY);#endif                // See if this sample makes any sense                if (samples) {                    diffX = abs(iX/samples - newX);                    diffY = abs(iY/samples - newY);                    if ((diffX <= ((iX/samples)/4)) &&                        (diffY <= ((iY/samples)/4))) {                        samples++;                        iX += newX;                        iY += newY;                    } else {#if 0                        diag_printf("Discard - newX: %d, X: %d, newY: %d, Y: %d\n",                                    newX, iX/samples, newY, iY/samples);#endif                        break;                    }                } else {                    iX = newX;                    iY = newY;                    samples = 1;                }                timeout = 0;            } else {                timeout++;            }        }        if (samples) {            // Send event to user level            event = (iX/samples)<<16 | (iY/samples);            if (!cyg_mbox_tryput(lcd_panel_events_mbox_handle, (void *)event)) {                diag_printf("LCD event lost: %x\n", event);            }        }        *(volatile cyg_uint8 *)TOUCH_CTL = 0x00;  // Disable drives        while (*(volatile cyg_uint32 *)INTSR1 & INTSR1_EINT2) ;        *(volatile cyg_uint8 *)TOUCH_CTL = 0x70;  // Idle state (so interrupt works)        cyg_thread_delay(10);        cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EINT2);    }}static voidlcd_panel_init(void){    // Enable touch panel    *(volatile cyg_uint8 *)PEDR   |= 0x04;      // Idle state (so interrupt works)    *(volatile cyg_uint8 *)TOUCH_CTL = 0x70;      // Enable ADC machinery    *(volatile cyg_uint32 *)SYSCON1 |= SYSCON1_ADC_CLOCK_128kHZ;    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_EINT2,                             99,                     // Priority - what goes here?                             0,                      //  Data item passed to interrupt handler                             lcd_panel_isr,                             lcd_panel_dsr,                             &lcd_panel_interrupt_handle,                             &lcd_panel_interrupt);    cyg_drv_interrupt_attach(lcd_panel_interrupt_handle);    cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_EINT2);    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EINT2);    // Set up the mbox for panel data    cyg_mbox_create(&lcd_panel_events_mbox_handle, &lcd_panel_events_mbox);    // This semaphore is set when there is a touch    cyg_semaphore_init(&lcd_panel_sem, 0);      // Create a thread whose job it is to de-bounce the keyboard and    // actually process the input, turning it into a series of events    cyg_thread_create(10,                           // Priority - just a number                      lcd_panel_server,             // entry                      0,                            // initial parameter                      "LCD_PANEL_server",           // Name                      &lcd_panel_server_stack[0],   // Stack                      STACK_SIZE,                   // Size                      &lcd_panel_server_thread_handle,    // Handle                      &lcd_panel_server_thread_data       // Thread data structure            );    cyg_thread_resume(lcd_panel_server_thread_handle);  // Start it}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -