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

📄 ps2kbdmou_ecos.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 4 页
字号:

    // Start by masking out the interrupts. Other code such as the HAL
    // or RedBoot may think it currently owns the keyboard, and I do
    // not want any interference from them while setting up the
    // interrupt handlers.
    cyg_drv_interrupt_mask_intunsafe(CYGNUM_HAL_INTERRUPT_KEYBOARD);
    cyg_drv_interrupt_mask_intunsafe(CYGNUM_HAL_INTERRUPT_IRQ12);

    // Install my own interrupt handler, overwriting anything that might
    // be there already.
    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_KEYBOARD, 0, 0,
                             &ps2_isr, &ps2_dsr, &ps2kbd_interrupt_handle, &ps2kbd_interrupt_data);
    cyg_drv_interrupt_attach(ps2kbd_interrupt_handle);
    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_IRQ12, 0, 0,
                             &ps2_isr, &ps2_dsr, &ps2mouse_interrupt_handle, &ps2mouse_interrupt_data);
    cyg_drv_interrupt_attach(ps2mouse_interrupt_handle);

    // Get the device into a known state.
    ps2_send_command(KC_CONTROL_DISABLE_AUX, NULL, 0, 0);
    ps2_send_command(KC_CONTROL_DISABLE_KBD, NULL, 0, 0);
    
    // Discard any current data.
    HAL_READ_UINT8(KC_STATUS, status);
    while (status & KC_STATUS_OUTB) {
        HAL_READ_UINT8(KC_OUTPUT, data);
        HAL_READ_UINT8(KC_STATUS, status);
    }

    // Now restart and reset the keyboard.
    ps2_send_command(KC_CONTROL_ENABLE_KBD, NULL, 0, 0);
    buf[0] = KC_KBDC_STANDARD_DISABLE;
    ps2_send_command_poll(KC_CONTROL_NULL, buf, 1, 0);
    buf[0] = KC_KBDC_LED_ONOFF;
    buf[1] = 0;
    ps2_send_command_poll(KC_CONTROL_NULL, buf, 2, 0);
    // The keyboard-specific initialization can now reenable the keyboard
    // using enable

    // Similarly for a mouse
    // Standard mode means 100 samples/s, 1:1 scaling, stream mode, 4 counts/mm resolution,
    // and transferdisabled. Stream mode is important, that means mouse data will
    // be immediately available rather than requiring separate control messages to
    // read a packet.
    ps2_send_command(KC_CONTROL_ENABLE_AUX, NULL, 0, 0);
    buf[0] = KC_MOUSEC_SET_STANDARD;
    ps2_send_command_poll(KC_CONTROL_NULL, buf, 1, 1);
    buf[0] = KC_MOUSEC_SET_SAMPLE_RATE;
    buf[1] = 0x0A;
    ps2_send_command_poll(KC_CONTROL_NULL, buf, 2, 1);

    // WRITE_MODE does not appear to involve an ACK
    ps2_send_command_poll(KC_CONTROL_WRITE_MODE, NULL, 0, 0);
    do {
        HAL_READ_UINT8(KC_STATUS, status);
    } while (status & KC_STATUS_INPB);
    HAL_WRITE_UINT8(KC_INPUT, KC_MODE_KBD_INT | KC_MODE_MOU_INT | KC_MODE_SYS | KC_MODE_KCC);
    
    cyg_drv_interrupt_unmask_intunsafe(CYGNUM_HAL_INTERRUPT_KEYBOARD);
    cyg_drv_interrupt_unmask_intunsafe(CYGNUM_HAL_INTERRUPT_IRQ12);
}

// ----------------------------------------------------------------------------
static int
PS2Mouse_Open(MOUSEDEVICE* pmd)
{
    unsigned char buf[1];
    ps2_initialize();
    buf[0] = KC_MOUSEC_ENABLE;
    ps2_send_command_wait(KC_CONTROL_NULL, buf, 1, 1);
}

// Closing the mouse is equivalent to disabling. It is assumed that we
// are not in the middle of a packet transfer, which could really
// confuse things.
static void
PS2Mouse_Close(void)
{
    unsigned char buf[1];
    buf[0] = KC_MOUSEC_SET_STANDARD;
    ps2_send_command_wait(KC_CONTROL_NULL, buf, 1, 1);
    ps2mou_buffer_index = 0;
}

static int
PS2Mouse_GetButtonInfo(void)
{
    return MWBUTTON_L | MWBUTTON_R;
}

// The mouse is used in its default setup, which means 1:1 scaling.
// Setting the threshold to 5 seems to match most other drivers...
static void
PS2Mouse_GetDefaultAccel(int* pscale, int* pthresh)
{
    if (NULL != pscale) {
        *pscale = 1;
    }
    if (NULL != pthresh) {
        *pthresh = 5;
    }
}

static int
PS2Mouse_Read(MWCOORD* dx_arg, MWCOORD* dy_arg, MWCOORD* dz_arg, int* bp_arg)
{
    int         result  = 0;
    MWCOORD     dx      = 0;
    MWCOORD     dy      = 0;
    int         buttons = 0;

    cyg_drv_isr_lock();
    if (ps2mou_changed) {
        dx              = ps2mou_dx;
        dy              = 0 - ps2mou_dy;    // microwindows directions are the opposite from the hardware
        buttons         = ps2mou_buttons;
        ps2mou_dx       = 0;
        ps2mou_dy       = 0;
        ps2mou_changed  = 0;
        result = 1;
    }
    cyg_drv_isr_unlock();
    if (result) {
        if (NULL != dx_arg) {
            *dx_arg = dx;
        }
        if (NULL != dy_arg) {
            *dy_arg = dy;
        }
        if (NULL != dz_arg) {
            *dz_arg = 0;
        }
        if (NULL != bp_arg) {
            *bp_arg = buttons;
        }
    }
    return result;
}

static int
PS2Mouse_Poll(void)
{
    return 0 != ps2mou_changed;
}

MOUSEDEVICE mousedev = {
    PS2Mouse_Open,
    PS2Mouse_Close,
    PS2Mouse_GetButtonInfo,
    PS2Mouse_GetDefaultAccel,
    PS2Mouse_Read,
    PS2Mouse_Poll
};

// ----------------------------------------------------------------------------
// Extracting data from the scancode buffer and turning it into
// ASCII. This is only called from thread context by the poll() and
// read() routines, although the scancode buffer is updated in ISR
// context.

// The current keyboard event, if any. This involves processing
// the scancodes held in the circular buffer and translating them
// to ASCII.
static MWKEY        ps2kbd_current_key          = MWKEY_UNKNOWN;
static MWKEYMOD     ps2kbd_current_modifiers    = 0;
static MWSCANCODE   ps2kbd_current_scancode     = 0;
static int          ps2kbd_current_keydown      = 0;

// Translation between scancodes and characters, i.e. keymaps.
// For now a relatively simple approach is used. The keymaps
// only cope with shifted vs. unshifted. The control key
// is handled specially. Anything cleverer is left to microwindows.
//
// Microwindows excepts key events in the form of MWKEY's, which
// are unsigned shorts. Special keys such as the function keys
// have suitable #define's in mwtypes.h.
//
// There is a complication with PC keyboards in that some keys
// generate multi-byte sequences, usually starting with 0xE0

typedef struct ps2kbd_keymap_entry {
    MWKEY       normal;
    MWKEY       shifted;
} ps2kbd_keymap_entry;

// This keymap is for a Dell Inspiron laptop with a Japanese
// keyboard. It may not match exactly with other keyboards,
// but is probably good enough for now.

static const ps2kbd_keymap_entry ps2kbd_keymap[] = {
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },            // Scancode 0 unused
    { MWKEY_ESCAPE,     MWKEY_ESCAPE },
    { '1',              '!' },
    { '2',              '"' },
    { '3',              '#' },
    { '4',              '$' },
    { '5',              '%' },
    { '6',              '&' },
    { '7',              '\'' },
    { '8',              '(' },
    { '9',              ')' },                      // Scancode 10
    { '0',              '~' },
    { '-',              '=' },
    { '^',              '_' },
    { MWKEY_BACKSPACE,  MWKEY_BACKSPACE },
    { MWKEY_TAB,        MWKEY_TAB },
    { 'q',              'Q' },                      // 0x10
    { 'w',              'W' },
    { 'e',              'E' },
    { 'r',              'R' },
    { 't',              'T' },                      // 20
    { 'y',              'Y' },
    { 'u',              'U' },
    { 'i',              'I' },
    { 'o',              'O' },
    { 'p',              'P' },
    { '@',              '`' },
    { '[',              '{' },
    { MWKEY_ENTER,      MWKEY_ENTER },
    { MWKEY_LCTRL,      MWKEY_LCTRL },
    { 'a',              'A' },                      // 30
    { 's',              'S' },
    { 'd',              'D' },                      // 0x20
    { 'f',              'F' },
    { 'g',              'G' },
    { 'h',              'H' },
    { 'j',              'J' },
    { 'k',              'K' },
    { 'l',              'L' },
    { ';',              '+' },
    { ':',              '*' },                      // 40
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },            // Japanese-only, top-left below escape
    { MWKEY_LSHIFT,     MWKEY_LSHIFT },
    { ']',              '}' },
    { 'z',              'Z' },
    { 'x',              'X' },
    { 'c',              'C' },
    { 'v',              'V' },
    { 'b',              'B' },                      // 0x30
    { 'n',              'N' },
    { 'm',              'M' },                      // 50
    { ',',              '<' },
    { '.',              '>' },
    { '/',              '?' },
    { MWKEY_RSHIFT,     MWKEY_RSHIFT },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },            // unused ?
    { MWKEY_LALT,       MWKEY_LALT },
    { ' ',              ' ' },                      // space bar
    { MWKEY_CAPSLOCK,   MWKEY_CAPSLOCK },
    { MWKEY_F1,         MWKEY_F1 },
    { MWKEY_F2,         MWKEY_F2 },                 // 60
    { MWKEY_F3,         MWKEY_F3 },
    { MWKEY_F4,         MWKEY_F4 },
    { MWKEY_F5,         MWKEY_F5 },
    { MWKEY_F6,         MWKEY_F6 },                 // 0x40
    { MWKEY_F7,         MWKEY_F7 },
    { MWKEY_F8,         MWKEY_F8 },
    { MWKEY_F9,         MWKEY_F9 },
    { MWKEY_F10,        MWKEY_F10 },
    { MWKEY_NUMLOCK,    MWKEY_NUMLOCK },
    { MWKEY_SCROLLOCK,  MWKEY_SCROLLOCK },          // 70
    { MWKEY_KP7,        MWKEY_KP7 },                // Keypad, not actually present on laptop
    { MWKEY_KP8,        MWKEY_KP8 },                // But accessible via Fn and some centre keys
    { MWKEY_KP9,        MWKEY_KP9 },    
    { MWKEY_KP_MINUS,   MWKEY_KP_MINUS },
    { MWKEY_KP4,        MWKEY_KP4 },
    { MWKEY_KP5,        MWKEY_KP5 },
    { MWKEY_KP6,        MWKEY_KP6 },
    { MWKEY_KP_PLUS,    MWKEY_KP_PLUS },
    { MWKEY_KP1,        MWKEY_KP1 },
    { MWKEY_KP2,        MWKEY_KP2 },                // 80, 0x50
    { MWKEY_KP3,        MWKEY_KP3 },
    { MWKEY_KP0,        MWKEY_KP0 },
    { MWKEY_KP_PERIOD,  MWKEY_KP_PERIOD },
    // There are now big gaps 
    // F11 and F12 are 0x57 and 0x58
    // 0x70, 0x79 and 0x7b are Japanese compose keys.
    // 0x73 is backslash and another _
    // 0x7d is yen and pipe.
    // These could be handled by special-case code in the scancode
    // translation routine, but at 4 bytes per table entry
    // it is probably just as efficient to extend the table.
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },            // 84, 0x53
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_F11,        MWKEY_F11 },
    { MWKEY_F12,        MWKEY_F12 },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },            // 90
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },            // 0x60
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },            // 100
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },            // 110
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },            // 0x70
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },
    { '\\',             '_' },
    { MWKEY_UNKNOWN,    MWKEY_UNKNOWN },

⌨️ 快捷键说明

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