lcd_support.c

来自「eCos操作系统源码」· C语言 代码 · 共 1,456 行 · 第 1/3 页

C
1,456
字号
            pen_down = false;            waiting_for_pen_down = true;#ifdef KBD_DEBUG            if (dump_info) {                int cur = start_console(0);                diag_printf("going idle\n");                end_console(cur);            }#endif        }        return false;    }#ifdef KBD_DEBUG    if (dump_info) {        int cur = start_console(0);        diag_printf("pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events);        end_console(cur);    }#endif    if (total_events == MIN_KBD_EVENTS) {        // If pen just went up then see if this was a valid        // character (inside the keyboard picture, etc)        int x = totalX/total_events;        int y = totalY/total_events;        int row, col;        int char_width, char_height;        unsigned char kbd_ch;#ifdef KBD_DEBUG        if (dump_info) {            int cur = start_console(0);            diag_printf("Pen[%d] at %d/%d\n", total_events, x, y);            end_console(cur);        }#endif        // Try and determine row/col in our keyboard matrix        if (inside(x, minX, maxX) && inside(y, minY, maxY)) {            // Point seems to be with the matrix            char_width = abs(minX - maxX) / 11;            char_height = abs(minY - maxY) / 4;            col = abs(x-maxX) / char_width;            row = abs(y-minY) / char_height;            kbd_ch = (*cur_kbd_map)[row][col];#ifdef KBD_DEBUG            if (dump_info) {                int cur = start_console(0);                diag_printf("Row/Col = %d/%d = %x\n", row, col, kbd_ch);                end_console(cur);            }#endif            switch (kbd_ch) {            case CODE_SHIFT:                if (cur_kbd_map == &kbd_shift_map) {                    cur_kbd_map = &kbd_norm_map;                    lcd_kbd(LCD_KBD_NORM);                } else {                    cur_kbd_map = &kbd_shift_map;                    lcd_kbd(LCD_KBD_SHIFT);                }                break;            case CODE_CTRL:                if (cur_kbd_map == &kbd_ctrl_map) {                    cur_kbd_map = &kbd_norm_map;                    lcd_kbd(LCD_KBD_NORM);                } else {                    cur_kbd_map = &kbd_ctrl_map;                    lcd_kbd(LCD_KBD_CTRL);                }                break;            case CODE_NUM:                if (cur_kbd_map == &kbd_num_map) {                    cur_kbd_map = &kbd_norm_map;                    lcd_kbd(LCD_KBD_NORM);                } else {                    cur_kbd_map = &kbd_num_map;                    lcd_kbd(LCD_KBD_NUM);                }                break;            case CODE_NONE:                break;            default:                *ch = kbd_ch;                return true;            }        }    }    return false;}static cyg_uint8lcd_comm_getc(void* __ch_data){    cyg_uint8 ch;    while (!lcd_comm_getc_nonblock(__ch_data, &ch)) ;    return ch;}static voidlcd_comm_putc(void* __ch_data, cyg_uint8 c){    lcd_putc(c);}static voidlcd_comm_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len){#if 0    CYGARC_HAL_SAVE_GP();    while(__len-- > 0)        lcd_comm_putc(__ch_data, *__buf++);    CYGARC_HAL_RESTORE_GP();#endif}static voidlcd_comm_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len){#if 0    CYGARC_HAL_SAVE_GP();    while(__len-- > 0)        *__buf++ = lcd_comm_getc(__ch_data);    CYGARC_HAL_RESTORE_GP();#endif}static cyg_boollcd_comm_getc_timeout(void* __ch_data, cyg_uint8* ch){    int delay_count;    cyg_bool res;    delay_count = _timeout * 10; // delay in .1 ms steps    for(;;) {        res = lcd_comm_getc_nonblock(__ch_data, ch);        if (res || 0 == delay_count--)            break;        CYGACC_CALL_IF_DELAY_US(100);    }    return res;}static intlcd_comm_control(void *__ch_data, __comm_control_cmd_t __func, ...){    static int vector = 0;    int ret = -1;    static int irq_state = 0;    CYGARC_HAL_SAVE_GP();    switch (__func) {    case __COMMCTL_IRQ_ENABLE:        ret = irq_state;        irq_state = 1;#if 0        if (vector == 0) {            vector = eth_drv_int_vector();        }        HAL_INTERRUPT_UNMASK(vector); #endif        break;    case __COMMCTL_IRQ_DISABLE:        ret = irq_state;        irq_state = 0;#if 0        HAL_INTERRUPT_MASK(vector);#endif        break;    case __COMMCTL_DBG_ISR_VECTOR:        ret = vector;        break;    case __COMMCTL_SET_TIMEOUT:    {        va_list ap;        va_start(ap, __func);        ret = _timeout;        _timeout = va_arg(ap, cyg_uint32);        va_end(ap);	break;    }    case __COMMCTL_FLUSH_OUTPUT:    case __COMMCTL_GETBAUD:    case __COMMCTL_SETBAUD:        ret = 0;	break;    default:        break;    }    CYGARC_HAL_RESTORE_GP();    return ret;}static intlcd_comm_isr(void *__ch_data, int* __ctrlc,            CYG_ADDRWORD __vector, CYG_ADDRWORD __data){#if 0    char ch;    cyg_drv_interrupt_acknowledge(__vector);    *__ctrlc = 0;    if (lcd_comm_getc_nonblock(__ch_data, &ch)) {        if (ch == 0x03) {            *__ctrlc = 1;        }    }    return CYG_ISR_HANDLED;#endif    return 0;}static boolinit_kbd_coord(int indx, char *prompt_char){    char prompt[] = "Press %s on kbd graphic";    int off = ((VISIBLE_SCREEN_WIDTH-sizeof(prompt))/2)-1;    int off2 = ((VISIBLE_SCREEN_WIDTH-20)/2)-1;    struct ts_event tse;    struct key_event ke;    bool pen_down;    int i, down_timer, total_events;    int timeout = 100000;    unsigned long totalX, totalY;    lcd_moveto(off, screen_height/2);    lcd_printf(prompt, prompt_char);    lcd_moveto(off2, (screen_height/2)+2);    lcd_printf("Keep pen down until");    lcd_moveto(off2, (screen_height/2)+3);    lcd_printf("message disappears");    pen_down = false;    down_timer = 0;    total_events = 0;    totalX = totalY = 0;    // Wait for a pen-down event    while (!pen_down) {        if (ts_get_event(&tse)) {            if (!tse.up) {                pen_down = true;            }        }        if (key_get_event(&ke)) {            if (ke.button_info == (ATMEL_BUTTON_STATE_UP|ATMEL_BUTTON_RETURN)) {                return true;            }        }        if (--timeout == 0) {            // Give up if the guy hasn't pressed anything            return true;        }    }    // Now accumulate data     // Assumption: the Atmel can send at most 3 position reports    // per millisecond.  We should wait for 50ms before moving on    while (total_events < 100) {        if (ts_get_event(&tse)) {            if (tse.up) {                pen_down = false;                continue;            } else {#ifdef PORTRAIT_MODE                totalX += tse.y;                totalY += tse.x;#else                totalX += tse.x;                totalY += tse.y;#endif                total_events++;                pen_down = true;            }        }        if (key_get_event(&ke)) {            if (ke.button_info == (ATMEL_BUTTON_STATE_UP|ATMEL_BUTTON_RETURN)) {                return true;            }        }    }    // Tell the guy we have enough data    lcd_moveto(off, screen_height/2);    for (i = 0;  i < screen_width;  i++) {        lcd_putc(' ');    }    // Now wait for the pen to go back up    while (pen_down) {        if (ts_get_event(&tse)) {            if (tse.up) {                pen_down = false;            }        }        if (key_get_event(&ke)) {            if (ke.button_info == (ATMEL_BUTTON_STATE_UP|ATMEL_BUTTON_RETURN)) {                return true;            }        }    }    kbd_limits[indx].x = totalX / total_events;    kbd_limits[indx].y = totalY / total_events;    return false;}static boolclose(int c1, int c2){    int diff = c1 - c2;    if (diff < 0) diff = -diff;    return (diff < 50);}#define LCD_COMM_CHANNEL 1  // Logical I/O channel used for LCD/TS consolevoidlcd_comm_init(void){    static int init = 0;    bool need_params = true;    unsigned short cksum, param;    int i;    if (!init) {        hal_virtual_comm_table_t* comm;        int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);        // Setup procs in the vector table        CYGACC_CALL_IF_SET_CONSOLE_COMM(LCD_COMM_CHANNEL);        comm = CYGACC_CALL_IF_CONSOLE_PROCS();        //CYGACC_COMM_IF_CH_DATA_SET(*comm, chan);        CYGACC_COMM_IF_WRITE_SET(*comm, lcd_comm_write);        CYGACC_COMM_IF_READ_SET(*comm, lcd_comm_read);        CYGACC_COMM_IF_PUTC_SET(*comm, lcd_comm_putc);        CYGACC_COMM_IF_GETC_SET(*comm, lcd_comm_getc);        CYGACC_COMM_IF_CONTROL_SET(*comm, lcd_comm_control);        CYGACC_COMM_IF_DBG_ISR_SET(*comm, lcd_comm_isr);        CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, lcd_comm_getc_timeout);        // Restore original console        CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);        init = 1;        // Pick up parameters for virtual keyboard from RAM        cksum = (unsigned short)&_ipaq_LCD_params[0];        for (i = 0;  i < 4;  i++) {            param = _ipaq_LCD_params[i*2];            kbd_limits[i].x = param;            cksum ^= param;            param = _ipaq_LCD_params[(i*2)+1];            kbd_limits[i].y = param;            cksum ^= param;        }        need_params = cksum != _ipaq_LCD_params[(4*2)+1];        // If the data are currently bad, set up some defaults        if (need_params) {            kbd_limits[CS_UL].x = 994;            kbd_limits[CS_UL].y = 710;            kbd_limits[CS_UR].x = 413;            kbd_limits[CS_UR].y = 710;            kbd_limits[CS_LL].x = 989;            kbd_limits[CS_LL].y = 839;            kbd_limits[CS_LR].x = 411;            kbd_limits[CS_LR].y = 836;        }        if (!need_params) {            // See if the guy wants to force new parameters            lcd_clear();            lcd_moveto(5, screen_height/2);            lcd_printf("Calibrate touch screen?\n");            lcd_moveto(5, (screen_height/2)+1);            for (i = 0;  i < 10;  i++) {                struct key_event ke;                if (key_get_event(&ke) && ((ke.button_info & ATMEL_BUTTON_STATE) == ATMEL_BUTTON_STATE_UP)) {                    need_params = (ke.button_info & ATMEL_BUTTON_VALUE) != ATMEL_BUTTON_RETURN;                    break;                }                CYGACC_CALL_IF_DELAY_US(50000);                lcd_putc('.');            }        }        while (need_params) {            cursor_enable = false;            lcd_clear();            lcd_kbd(LCD_KBD_NORM);            if (init_kbd_coord(CS_UL, "'q'")) {                goto no_kbd;            }            if (init_kbd_coord(CS_UR, "BS ")) {                goto no_kbd;            }            if (init_kbd_coord(CS_LL, "SHIFT")) {                goto no_kbd;            }            if (init_kbd_coord(CS_LR, "'/'  ")) {                goto no_kbd;            }            cursor_enable = true;            if (close(kbd_limits[CS_UL].x, kbd_limits[CS_LL].x) &&                close(kbd_limits[CS_UR].x, kbd_limits[CS_LR].x) &&                close(kbd_limits[CS_UL].y, kbd_limits[CS_UR].y) &&                close(kbd_limits[CS_LL].y, kbd_limits[CS_LR].y)) {                // Save values so we don't need to repeat this                cksum = (unsigned short)&_ipaq_LCD_params[0];                for (i = 0;  i < 4;  i++) {                    param = kbd_limits[i].x;                    cksum ^= param;                    _ipaq_LCD_params[i*2] = param;                    param = kbd_limits[i].y;                    cksum ^= param;                    _ipaq_LCD_params[(i*2)+1] = param;                }                _ipaq_LCD_params[(4*2)+1] = cksum;                break;            }        }    no_kbd:        // Munge the limits to allow for some slop        if (kbd_limits[CS_UL].x < kbd_limits[CS_UR].x) {            minX = min(kbd_limits[CS_UL].x, kbd_limits[CS_LL].x) - KBD_FUZZ;            maxX = max(kbd_limits[CS_UR].x, kbd_limits[CS_LR].x) + KBD_FUZZ;        } else {            minX = min(kbd_limits[CS_UR].x, kbd_limits[CS_LR].x) - KBD_FUZZ;            maxX = max(kbd_limits[CS_UL].x, kbd_limits[CS_LL].x) + KBD_FUZZ;        }        if (kbd_limits[CS_UL].y < kbd_limits[CS_LL].y) {            minY = min(kbd_limits[CS_UL].y, kbd_limits[CS_UR].y) - KBD_FUZZ;            maxY = max(kbd_limits[CS_LL].y, kbd_limits[CS_LR].y) + KBD_FUZZ;        } else {            minY = min(kbd_limits[CS_LR].y, kbd_limits[CS_LL].y) - KBD_FUZZ;            maxY = max(kbd_limits[CS_UL].y, kbd_limits[CS_UR].y) + KBD_FUZZ;        }        cursor_enable = true;        lcd_clear();        if (kbd_active) {            lcd_kbd(LCD_KBD_NORM);        }#if 0        diag_printf("KBD Limits[] = %d/%d, %d/%d, %d/%d, %d/%d\n",                    kbd_limits[CS_UL].x, kbd_limits[CS_UL].y,                    kbd_limits[CS_UR].x, kbd_limits[CS_UR].y,                    kbd_limits[CS_LL].x, kbd_limits[CS_LL].y,                    kbd_limits[CS_LR].x, kbd_limits[CS_LR].y);        diag_printf("KBD in %d/%d .. %d/%d\n", minX, minY, maxX, maxY);        diag_printf("screen %d x %d\n", screen_height, screen_width);#endif    }}// Control state of LCD display - only called by logical I/O layersvoidlcd_on(bool enable){    static bool enabled = true;    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);    if (cur != LCD_COMM_CHANNEL)         enable = false;  // Only enable display if LCD is the active "console"    if (enable) {        if (!enabled) {            ipaq_EGPIO(SA1110_EIO_LCD_3V3|SA1110_EIO_LCD_CTRL|SA1110_EIO_LCD_5V|SA1110_EIO_LCD_VDD,                       SA1110_EIO_LCD_3V3_ON|SA1110_EIO_LCD_CTRL_ON|SA1110_EIO_LCD_5V_ON|SA1110_EIO_LCD_VDD_ON);            lcd_brightness(_lcd_brightness);        }        enabled = true;    } else {        if (enabled) {            lcd_brightness(0);            ipaq_EGPIO(SA1110_EIO_LCD_3V3|SA1110_EIO_LCD_CTRL|SA1110_EIO_LCD_5V|SA1110_EIO_LCD_VDD,                       SA1110_EIO_LCD_3V3_OFF|SA1110_EIO_LCD_CTRL_OFF|SA1110_EIO_LCD_5V_OFF|SA1110_EIO_LCD_VDD_OFF);        }        enabled = false;    }}#endif

⌨️ 快捷键说明

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