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

📄 ps2kbdmou_ecos.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 4 页
字号:
        new_buttons |= MWBUTTON_R;    }    ps2mou_buttons  = new_buttons;    dx = ps2mou_buffer[1];    if (0 != (ps2mou_buffer[0] & (0x001 << 4))) {        // Negative number.        if (0 != (ps2mou_buffer[0] & (0x01 << 6))) {            // -ve overflow            dx = -256;        } else {            dx = 0 - (256 - dx);        }    } else if (0 != (ps2mou_buffer[0] & (0x01 << 6))) {        // +ve overflow        dx = 256;    }    ps2mou_dx += dx;        dy = ps2mou_buffer[2];    if (0 != (ps2mou_buffer[0] & (0x01 << 5))) {        // Negative number.        if (0 != (ps2mou_buffer[0] & (0x01 << 7))) {            // -ve overflow            dy = -256;        } else {            // -ve signed, bottom byte only            dy = 0 - (256 - dy);        }    } else if (0 != (ps2mou_buffer[0] & (0x01 << 7))) {        // +ve overflow        dy = 256;    }    ps2mou_dy += dy;        ps2mou_changed      = 1;}// Mouse data. A PS/2 mouse sends events in the form of// eight-byte packets. Some of the fields are officially// reserved and ignored for now.#define KC_MOUSE_DATA_FLAGS         0x00#define KC_MOUSE_DATA_FLAGS_YOV     (0x01 << 7)#define KC_MOUSE_DATA_FLAGS_XOV     (0x01 << 6)#define KC_MOUSE_DATA_FLAGS_YNG     (0x01 << 5)#define KC_MOUSE_DATA_FLAGS_XNG     (0x01 << 4)#define KC_MOUSE_DATA_FLAGS_RIG     (0x01 << 1)#define KC_MOUSE_DATA_FLAGS_LEF     (0x01 << 0)#define KC_MOUSE_DATA_X             0x02#define KC_MOUSE_DATA_Y             0x04#define KC_MOUSE_DATA_SIZE          0x08// ----------------------------------------------------------------------------// An interrupt has occurred. Usually this means that there is data// in the output register, although errors are possible as well. The// data can be keyboard scancodes, parts of a mouse packet, or// replies to control messages.//// For now errors are ignored, including parity and timeout errors. In// theory these are supposed to be handled by requesting a resend. In// practice that seems to cause as many complications as it might// solve. For example what should happen if there is already a command// being sent?//// The controller interrupts at two separate vectors, one for keyboard// and another for mouse. If nested interrupts are enabled this could// cause problems with nested calls to ps2_isr() updating the global// data in the wrong order. It may be necessary to have a volatile flag// to detect nesting, accompanied by an early acknowledge and return to// the interrupted interrupt handler.static cyg_uint32ps2_isr(cyg_vector_t isr_vector, cyg_addrword_t isr_data){    int             status;    unsigned char   data;    CYG_UNUSED_PARAM(cyg_addrword_t, isr_data);    HAL_READ_UINT8(KC_STATUS, status);    while (status & KC_STATUS_OUTB) {        HAL_READ_UINT8(KC_OUTPUT, data);                if (status & KC_STATUS_AUXB) {            // Data from the mouse. This will be either an ACK for a            // command, a resend request, or a byte for the current            // packet. When a complete 8-byte packet has been received            // it can be processed. When an ACK is received the next            // byte for the current command should get sent, or on            // completion the sending code can be woken up.            //            // The mouse can also send back other data, e.g. in response            // to a determine-status request. These are disallowed            // because there is no obvious way of separating out such            // data from a current mouse packet being transferred.            //            // There may also be special bytes sent for disconnect and            // reconnect. It is not clear how to distinguish those            // from packet data either.            if (ps2_command_mouse_waiting_for_ack && ((KC_MOUSE_ACK == data) || (KC_MOUSE_RESEND == data))) {                int tmp;                                if (KC_MOUSE_ACK == data) {                    // Is there another byte to be sent?                    ps2_command_index++;                    if (ps2_command_index < ps2_command_length) {                        // Send the next byte for the current command                        do {                            HAL_READ_UINT8(KC_STATUS, tmp);                        } while (tmp & KC_STATUS_INPB);                        HAL_WRITE_UINT8(KC_CONTROL, KC_CONTROL_WRITE_AUX);                        do {                            HAL_READ_UINT8(KC_STATUS, tmp);                        } while (tmp & KC_STATUS_INPB);                        HAL_WRITE_UINT8(KC_INPUT, ps2_command[ps2_command_index]);                    } else {                        // The whole command has been sent and acknowledged.                        // Allow the polling thread to resume.                        ps2_command_index   = 0;                        ps2_command_length  = 0;                        ps2_command         = NULL;                        ps2_command_ack     = 1;                        ps2_command_mouse_waiting_for_ack = 0;                    }                } else {                    // A resend request for the current byte.                    do {                        HAL_READ_UINT8(KC_STATUS, tmp);                    } while (tmp & KC_STATUS_INPB);                    HAL_WRITE_UINT8(KC_CONTROL, KC_CONTROL_WRITE_AUX);                    do {                        HAL_READ_UINT8(KC_STATUS, tmp);                    } while (tmp & KC_STATUS_INPB);                    HAL_WRITE_UINT8(KC_INPUT, ps2_command[ps2_command_index]);                }            } else {                ps2mou_buffer[ps2mou_buffer_index++] = data;                if (ps2mou_packet_size == ps2mou_buffer_index) {                    // A complete packet has been received.                    ps2mou_synaptics_translate();                    ps2mou_buffer_index = 0;    // Ready for the next packet                }            }        } else {            // Data from the keyboard. Usually this will be a scancode.            // There are a number of other possibilities such as            // echo replies, resend requests, and acks.            if ((KC_KBD_ACK == data) && (NULL != ps2_command) && !ps2_command_mouse_waiting_for_ack) {                // Send the next byte for the current command, or                // else we have completed.                ps2_command_index++;                if (ps2_command_index < ps2_command_length) {                    int tmp;                    do {                        HAL_READ_UINT8(KC_STATUS, tmp);                    } while (tmp & KC_STATUS_INPB);                    HAL_WRITE_UINT8(KC_INPUT, ps2_command[ps2_command_index]);                } else {                    ps2_command_index   = 0;                    ps2_command_length  = 0;                    ps2_command         = NULL;                    ps2_command_ack     = 1;                }            } else if ((KC_KBD_RESEND == data) && (NULL != ps2_command) && !ps2_command_mouse_waiting_for_ack) {                int tmp;                do {                    HAL_READ_UINT8(KC_STATUS, tmp);                } while (tmp & KC_STATUS_INPB);                HAL_WRITE_UINT8(KC_INPUT, ps2_command[ps2_command_index]);            } else {                if (((ps2kbd_scancode_buffer_head + 1) % PS2KBD_SCANCODE_BUFSIZE) == ps2kbd_scancode_buffer_tail) {                    // Already full. The data has to be discarded.                } else {                    ps2kbd_scancode_buffer[ps2kbd_scancode_buffer_head] = data;                    ps2kbd_scancode_buffer_head = (ps2kbd_scancode_buffer_head + 1) % PS2KBD_SCANCODE_BUFSIZE;                }            }        }        // Just in case the keyboard controller is fast enough to send another byte,        // go around again.        HAL_READ_UINT8(KC_STATUS, status);    }    // The interrupt has been fully handled. For now there is no point    // in running a DSR.    cyg_drv_interrupt_acknowledge(isr_vector);    return CYG_ISR_HANDLED;}// For now the DSR does nothing. static voidps2_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data){    CYG_UNUSED_PARAM(cyg_vector_t, vector);    CYG_UNUSED_PARAM(cyg_ucount32, count);    CYG_UNUSED_PARAM(cyg_addrword_t, data);}// Sending out a command. The controller command, if any, gets sent here.// This is followed by the first byte for the keyboard or mouse. The// remaining bytes and any retransmits will be handled by the interrupt// handler.static voidps2_send_command(int controller_command, unsigned char* command, int length, int mouse){    int     status;        CYG_PRECONDITION(NULL == ps2_command, "Only one send command is allowed at a time");    CYG_PRECONDITION((KC_CONTROL_NULL != controller_command) || (NULL != command), "no-op");    CYG_PRECONDITION(!mouse || (KC_CONTROL_NULL == controller_command), "cannot combine controller and mouse commands");        ps2_command         = command;    ps2_command_index   = 0;    ps2_command_length  = length;    ps2_command_mouse   = 0;    ps2_command_ack     = 0;    if (KC_CONTROL_NULL != controller_command) {        do {            HAL_READ_UINT8(KC_STATUS, status);        } while (status & KC_STATUS_INPB);        HAL_WRITE_UINT8(KC_CONTROL, controller_command);    }    if (length > 0) {        if (mouse) {            do {                HAL_READ_UINT8(KC_STATUS, status);            } while (status & KC_STATUS_INPB);            HAL_WRITE_UINT8(KC_CONTROL, KC_CONTROL_WRITE_AUX);        }        do {            HAL_READ_UINT8(KC_STATUS, status);        } while (status & KC_STATUS_INPB);        HAL_WRITE_UINT8(KC_INPUT, command[0]);    }}// For now there is little difference between polled and non-polled// mode, they both just spin until the ACK byte is received. The// polled version just calls the interrupt handler as well. This is// probably acceptable for now because commands only get sent during// initialization, but eventually the non-polled version should be// using a synch primitive signalled by the dsr.//// ACKs are only generated when there is data to be sent, not for// operations on the control register.//// For keyboard commands there is no real problem because the ACK// character 0xFA does not match a valid scancode. For the mouse// things are more difficult because 0xFA could be present in the// data, e.g. as a fairly large movement. Therefore the interrupt// handler needs to know whether or not a mouse ACK is expected.// It is assumed that the ACK and any actual 0xFA data get sent// within a byte of each other so that the 0xFA still ends up in// the right place in the buffer.//// A couple of commands do not result in an ACK. For the mouse this// includes reset-wrap-mode and reset. For the keyboard this includes// echo. These commands are not currently used, so there is no need// to worry about the special cases.static voidps2_send_command_poll(int controller_command, unsigned char* command, int length, int mouse){    if ((NULL != command) && mouse) {        ps2_command_mouse_waiting_for_ack = 1;    }    ps2_send_command(controller_command, command, length, mouse);    if (NULL != command) {        for ( ; !ps2_command_ack; ) {            ps2_isr( CYGNUM_HAL_INTERRUPT_KEYBOARD, 0);        }        ps2_command_ack = 0;    }}static voidps2_send_command_wait(int controller_command, unsigned char* command, int length, int mouse){    if ((NULL != command) && mouse) {        ps2_command_mouse_waiting_for_ack = 1;    }    ps2_send_command(controller_command, command, length, mouse);    if (NULL != command) {        for ( ; !ps2_command_ack; )            ;        ps2_command_ack = 0;    }}// ----------------------------------------------------------------------------// Hardware initialization and the interrupt handling.static cyg_handle_t     ps2kbd_interrupt_handle;static cyg_interrupt    ps2kbd_interrupt_data;static cyg_handle_t     ps2mouse_interrupt_handle;static cyg_interrupt    ps2mouse_interrupt_data;static voidps2_initialize(void){    unsigned char   buf[2];    int             status, data;        // Only perform initialization once, not for both kbd and mouse.    static int  initialized = 0;    if (initialized) {        return;    }    initialized++;

⌨️ 快捷键说明

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