lcd_support.c
来自「eCos操作系统源码」· C语言 代码 · 共 1,400 行 · 第 1/3 页
C
1,400 行
{ 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, },};static int KBIndexTab[8] = { 0, 1, 2, 2, 3, 3, 3, 3 };//-----------------------------------------------------------------------------static __inline__ cyg_uint8inb(cyg_uint32 port){ cyg_uint8 val; HAL_READ_UINT8(port, val); return val;}static __inline__ voidoutb(cyg_uint32 port, cyg_uint8 val){ HAL_WRITE_UINT8(port, val);}static cyg_boolKeyboardInit(void){ unsigned char c, s; /* flush input queue */ while ((inb(KBSTATPORT) & KBINRDY)) { (void)inb(KBDATAPORT); } /* Send self-test - controller local */ while (inb(KBSTATPORT) & KBOUTRDY) ; outb(KBCMDPORT,0xAA); while ((inb(KBSTATPORT) & KBINRDY) == 0) ; /* wait input ready */ if ((c = inb(KBDATAPORT)) != 0x55) {#ifdef DEBUG_KBD_INIT diag_printf("Keyboard self test failed - result: %x\n", c);#endif return false; } /* Enable interrupts and keyboard controller */ while (inb(KBSTATPORT) & KBOUTRDY) ; outb(KBCMDPORT,0x60); while (inb(KBSTATPORT) & KBOUTRDY) ; outb(KBCMDPORT,0x45); CYGACC_CALL_IF_DELAY_US(10000); // 10ms while (inb(KBSTATPORT) & KBOUTRDY) ; outb(KBCMDPORT,0xAE); // Enable keyboard /* See if a keyboard is connected */ while (inb(KBSTATPORT) & KBOUTRDY) ; outb(KBDATAPORT,0xFF); while (((s = inb(KBSTATPORT)) & (KBINRDY|KBTXTO)) == 0) ; /* wait input ready */ if ((s & KBTXTO) || ((c = inb(KBDATAPORT)) != 0xFA)) {#ifdef DEBUG_KBD_INIT diag_printf("Keyboard reset failed - no ACK: %x, stat: %x\n", c, s);#endif return false; } while (((s = inb(KBSTATPORT)) & KBINRDY) == 0) ; /* wait input ready */ if ((s & KBTXTO) || ((c = inb(KBDATAPORT)) != 0xAA)) {#ifdef DEBUG_KBD_INIT diag_printf("Keyboard reset failed - bad code: %x, stat: %x\n", c, s);#endif return false; } // Set scan mode while (inb(KBSTATPORT) & KBOUTRDY) ; outb(KBCMDPORT,0x20); while ((inb(KBSTATPORT) & KBINRDY) == 0) ; /* wait input ready */ if (! (inb(KBDATAPORT) & 0x40)) { /* * Quote from PS/2 System Reference Manual: * * "Address hex 0060 and address hex 0064 should be * written only when the input-buffer-full bit and * output-buffer-full bit in the Controller Status * register are set 0." (KBINRDY and KBOUTRDY) */ while (inb(KBSTATPORT) & (KBINRDY | KBOUTRDY)) ; outb(KBDATAPORT,0xF0); while (inb(KBSTATPORT) & (KBINRDY | KBOUTRDY)) ; outb(KBDATAPORT,0x01); } KBFlags = 0; return true;} /* KeyboardInit *///-----------------------------------------------------------------------------static CYG_BYTE KeyboardAscii(CYG_BYTE scancode){ CYG_BYTE ascii = 0xFF; // Start by handling all shift/ctl keys: switch( scancode ) { case 0xe0: KBFlags |= KBExtend; return 0xFF; case 0xfa: KBFlags |= KBAck; return 0xFF; case 0xfe: KBFlags |= KBResend; return 0xFF; case LSHIFT: KBFlags |= KBShiftL; return 0xFF; case LSHIFT | BREAK: KBFlags &= ~KBShiftL; return 0xFF; case RSHIFT: KBFlags |= KBShiftR; return 0xFF; case RSHIFT | BREAK: KBFlags &= ~KBShiftR; return 0xFF; case CTRL: if( KBFlags & KBExtend ) { KBFlags |= KBCtrlR; KBFlags &= ~KBExtend; } else KBFlags |= KBCtrlL; return 0xFF; case CTRL | BREAK: if( KBFlags & KBExtend ) { KBFlags &= ~KBCtrlR; KBFlags &= ~KBExtend; } else KBFlags &= ~KBCtrlL; return 0xFF; case ALT: if( KBFlags & KBExtend ) { KBFlags |= KBAltR; KBFlags &= ~KBExtend; } else KBFlags |= KBAltL; return 0xFF; case ALT | BREAK: if( KBFlags & KBExtend ) { KBFlags &= ~KBAltR; KBFlags &= ~KBExtend; } else KBFlags &= ~KBAltL; return 0xFF; case CAPS: KBFlags ^= KBCapsLock; case CAPS | BREAK: return 0xFF; case NUMS: KBFlags ^= KBNumLock; case NUMS | BREAK: return 0xFF; case KBArrowUp: case KBArrowDown: screen_pan = 0; lcd_refresh(); break; case KBArrowLeft: screen_pan -= SCREEN_PAN; if (screen_pan < 0) screen_pan = 0; lcd_refresh(); break; case KBArrowRight: screen_pan += SCREEN_PAN; if (screen_pan > (SCREEN_WIDTH-SCREEN_PAN)) screen_pan = SCREEN_WIDTH-SCREEN_PAN; lcd_refresh(); break; } // Clear Extend flag if set KBFlags &= ~KBExtend; // Ignore all other BREAK codes if( scancode & 0x80 ) return 0xFF; // Here the scancode is for something we can turn // into an ASCII value ascii = KBScanTable[scancode & 0x7F][KBIndexTab[KBFlags & KBIndex]]; return ascii;} /* KeyboardAscii *///-----------------------------------------------------------------------------static int KeyboardTest(void){ // If there is a pending character, return True if( KBPending != 0xFF ) return true; // If there is something waiting at the port, get it for(;;) { CYG_BYTE stat, code; CYG_BYTE c; HAL_READ_UINT8( KBSTATPORT, stat ); if( (stat & KBINRDY) == 0 ) break; HAL_READ_UINT8( KBDATAPORT, code ); // Translate to ASCII c = KeyboardAscii(code); // if it is a real ASCII char, save it and // return True. if( c != 0xFF ) { KBPending = c; return true; } } // Otherwise return False return false; } /* KeyboardTest */char KeyboardChar(void){ char c = KBPending; KBPending = 0xFF; return c;}static int _timeout = 500;static cyg_boollcd_comm_getc_nonblock(void* __ch_data, cyg_uint8* ch){ if( !KeyboardTest() ) return false; *ch = KBPending; KBPending = 0xFF; return true;}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 * 2; // delay in .5 ms steps for(;;) { res = lcd_comm_getc_nonblock(__ch_data, ch); if (res || 0 == delay_count--) break; CYGACC_CALL_IF_DELAY_US(500); } 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; break; case __COMMCTL_IRQ_DISABLE: ret = irq_state; irq_state = 0; 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: 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;#else return 0;#endif}voidlcd_comm_init(void){ static int init = 0; if (!init) { hal_virtual_comm_table_t* comm; int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); init = 1; if (!KeyboardInit()) { // No keyboard - no LCD/CRT display return; } // Initialize screen cursor_enable = true; lcd_init(16); lcd_on(true); lcd_screen_clear(); // Setup procs in the vector table CYGACC_CALL_IF_SET_CONSOLE_COMM(2); // FIXME - should be controlled by CDL 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); }}#ifdef CYGPKG_REDBOOT#include <redboot.h>// Get here when RedBoot is idle. If it's been long enough, then// dim the LCD. The problem is - how to determine other activities// so at this doesn't get in the way. In the default case, this will// be called from RedBoot every 10ms (CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT)#define MAX_IDLE_TIME (30*100)static voididle(bool is_idle){ static int idle_time = 0; static bool was_idled = false; if (is_idle) { if (!was_idled) { if (++idle_time == MAX_IDLE_TIME) { was_idled = true; lcd_on(false); } } } else { idle_time = 0; if (was_idled) { was_idled = false; lcd_on(true); } }}RedBoot_idle(idle, RedBoot_AFTER_NETIO);#endif#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?