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

📄 lcd_support.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 3 页
字号:
            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_uint8
lcd_comm_getc(void* __ch_data)
{
    cyg_uint8 ch;

    while (!lcd_comm_getc_nonblock(__ch_data, &ch)) ;
    return ch;
}

static void
lcd_comm_putc(void* __ch_data, cyg_uint8 c)
{
    lcd_putc(c);
}

static void
lcd_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 void
lcd_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_bool
lcd_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 int
lcd_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 int
lcd_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 bool
init_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 bool
close(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 console

void
lcd_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 layers

void
lcd_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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -