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 + -
显示快捷键?