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