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

📄 ps2kbdmou_ecos.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 4 页
字号:
//=============================================================================////      ps2kbdmou_ecos.c////      eCos support for a PS/2 keyboard and mouse.////=============================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//=============================================================================//#####DESCRIPTIONBEGIN####//// Author(s):    bartv// Date:         2002-04-04// Purpose:      Implement basic keyboard and mouse support for microwindows//               only, interacting directly with the hardware.////####DESCRIPTIONEND####//=============================================================================#include <pkgconf/system.h>#include <cyg/infra/cyg_ass.h>#include <cyg/infra/diag.h>#include <cyg/hal/hal_io.h>#include <cyg/hal/hal_intr.h>#include <cyg/hal/drv_api.h>#include <cyg/kernel/kapi.h>#include <microwin/device.h>#ifdef CYGPKG_KERNEL# include <cyg/kernel/kapi.h>#endif// ----------------------------------------------------------------------------// Configuration options. For now local to this file.#define CYGDBG_DEVS_PS2KBDMOUSE_VERBOSE         1#ifdef CYGDBG_DEVS_PS2KBDMOUSE_VERBOSE# define DBG(format, args...)       diag_printf(format, ## args)#else# define DBG(format, args...)#endif// ----------------------------------------------------------------------------// The hardware.//// On PC's with PS/2 hardware both the mouse and the keyboard are// handled through a single keyboard controller chip. There are four// registers: status, control, input and output. There are also 8-bit// input and output ports which can be manipulated by writing certain// control messages. The registers are accessed via the I/O bus.//// Output means keyboard controller -> cpu.// Input means cpu -> keyboard controller.//// So you need to do a HAL_READ_UINT() to the output register,// and a HAL_WRITE_UINT8 to the input register. They are actually// at the same address...//// The following information was extracted from "The Indispensable// PC Hardware Book" by Messmer, third edition, chapter 34. #define KC_OUTPUT       0x060#define KC_INPUT        0x060#define KC_CONTROL      0x064#define KC_STATUS       0x064// Bits in the status register.#define KC_STATUS_PARE  (0x01 << 7)#define KC_STATUS_TIM   (0x01 << 6)#define KC_STATUS_AUXB  (0x01 << 5)#define KC_STATUS_KEYL  (0x01 << 4)#define KC_STATUS_CD    (0x01 << 3)#define KC_STATUS_SYSF  (0x01 << 2)#define KC_STATUS_INPB  (0x01 << 1)#define KC_STATUS_OUTB  (0x01 << 0)// Commands that can be written to the control register,// plus for some the results that would come back.#define KC_CONTROL_NULL                 -1#define KC_CONTROL_DISABLE_AUX          0x00A7#define KC_CONTROL_ENABLE_AUX           0x00A8#define KC_CONTROL_CHECK_AUX            0x00A9#define KC_CONTROL_CHECK_AUX_OK             0x000#define KC_CONTROL_CHECK_AUX_CLOCK_LOW      0x001#define KC_CONTROL_CHECK_AUX_CLOCK_HIGH     0x002#define KC_CONTROL_CHECK_AUX_DATA_LOW       0x003#define KC_CONTROL_CHECK_AUX_DATA_HIGH      0x004#define KC_CONTROL_CHECK_AUX_NONE           0x0FF#define KC_CONTROL_SELF_TEST            0x00AA#define KC_CONTROL_SELF_TEST_OK             0x055#define KC_CONTROL_CHECK_KBD            0x00AB#define KC_CONTROL_CHECK_KBD_OK             0x000#define KC_CONTROL_CHECK_KBD_CLOCK_LOW      0x001#define KC_CONTROL_CHECK_KBD_CLOCK_HIGH     0x002#define KC_CONTROL_CHECK_KBD_DATA_LOW       0x003#define KC_CONTROL_CHECK_KBD_DATA_HIGH      0x004#define KC_CONTROL_CHECK_KBD_ERROR          0x0FF#define KC_CONTROL_DISABLE_KBD          0x00AD#define KC_CONTROL_ENABLE_KBD           0x00AE#define KC_CONTROL_READ_INPUT_PORT      0x00C0#define KC_CONTROL_READ_INPUT_PORT_LOW  0x00C1#define KC_CONTROL_READ_INPUT_PORT_HIGH 0x00C2#define KC_CONTROL_READ_OUTPUT_PORT     0x00D0#define KC_CONTROL_WRITE_OUTPUT_PORT    0x00D1#define KC_CONTROL_WRITE_KBD_OUTPUT     0x00D2#define KC_CONTROL_WRITE_AUX_OUTPUT     0x00D3#define KC_CONTROL_WRITE_AUX            0x00D4#define KC_CONTROL_READ_TEST_INPUT      0x00E0#define KC_CONTROL_PULSE                0x00F0// Additional commands, not from the book...#define KC_CONTROL_READ_MODE            0x0020#define KC_CONTROL_WRITE_MODE           0x0060#define KC_MODE_KBD_INT                 (0x01 << 0)#define KC_MODE_MOU_INT                 (0x01 << 1)#define KC_MODE_SYS                     (0x01 << 2)#define KC_MODE_NO_KEYLOCK              (0x01 << 3)#define KC_MODE_DISABLE_KBD             (0x01 << 4)#define KC_MODE_ENABLE_KBD              (0x01 << 5)#define KC_MODE_KCC                     (0x01 << 6)#define KC_MODE_RFU                     (0x01 << 7)// The input port#define KC_INPUT_LOCK       (0x01 << 7)#define KC_INPUT_CM         (0x01 << 6)#define KC_INPUT_CM_MONO    (0x01 << 6)#define KC_INPUT_CM_COLOR   (0x00 << 6)#define KC_INPUT_CM_COLOUR  (0x00 << 6)#define KC_INPUT_AUX        (0x01 << 1)#define KC_INPUT_KBD        (0x01 << 0)// And the output port#define KC_OUTPUT_KBDO      (0x01 << 7)#define KC_OUTPUT_KCLK      (0x01 << 6)#define KC_OUTPUT_AUXB      (0x01 << 5)#define KC_OUTPUT_OUTB      (0x01 << 4)#define KC_OUTPUT_ACLK      (0x01 << 3)#define KC_OUTPUT_AXDO      (0x01 << 2)#define KC_OUTPUT_GA20      (0x01 << 1)#define KC_OUTPUT_SYSR      (0x01 << 0)// Data from the keyboard#define KC_KBD_OVERFLOW     0x000#define KC_KBD_KEY_ERROR    0x0FF#define KC_KBD_MFII_ID      0x0041AB#define KC_KBD_BAT_COMPLETE 0x0AA#define KC_KBD_ECHO         0x0EE#define KC_KBD_ACK          0x0FA#define KC_KBD_BAT_ERROR    0x0FC#define KC_KBD_RESEND       0x0FE#define KC_KBD_SCANCODE_MIN 0x001// Likely to be incorrect for some modern keyboards#define KC_KBD_SCANCODE_MAX 0x058// Commands that can be sent to the keyboard. These// are just written to the input register. Some of// them will be followed by additional data.#define KC_KBDC_LED_ONOFF           0x0ED#define KC_KBDC_ECHO                0x0EE#define KC_KBDC_SETSCAN             0x0F0#define KC_KBDC_IDENTIFY            0x0F2#define KC_KBDC_SETREPEAT           0x0F3#define KC_KBDC_ENABLE              0x0F4#define KC_KBDC_STANDARD_DISABLE    0x0F5#define KC_KBDC_STANDARD_ENABLE     0x0F6#define KC_KBDC_RESEND              0x0FE#define KC_KBDC_RESET               0x0FF// And commands that can be sent to the mouse. These// involve a controller write followed by another// write to the input register.#define KC_MOUSEC_RESET_SCALING     0x0E6#define KC_MOUSEC_SET_SCALING       0x0E7#define KC_MOUSEC_SET_RESOLUTION    0x0E8#define KC_MOUSEC_STATUS            0x0E9#define KC_MOUSEC_SET_STREAM_MODE   0x0EA#define KC_MOUSEC_READ_DATA         0x0EB#define KC_MOUSEC_RESET_WRAP_MODE   0x0EC#define KC_MOUSEC_SET_WRAP_MODE     0x0EE#define KC_MOUSEC_SET_REMOTE_MODE   0x0F0#define KC_MOUSEC_IDENTIFY          0x0F2#define KC_MOUSEC_SET_SAMPLE_RATE   0x0F3#define KC_MOUSEC_ENABLE            0x0F4#define KC_MOUSEC_DISABLE           0x0F5#define KC_MOUSEC_SET_STANDARD      0x0F6#define KC_MOUSEC_RESEND            0x0FE#define KC_MOUSEC_RESET             0x0FF// Data back from the mouse. Some special characters.#define KC_MOUSE_ACK                0x0FA#define KC_MOUSE_RESEND             0x0FE// ----------------------------------------------------------------------------// The low-level stuff. Managing the PS/2 hardware is actually quite// messy if you want a robust implementation because of the various// ack's, resend requests, etc.// The keyboard device. The interrupt handler is responsible for storing// key press and release events in a circular buffer. The poll and read code// will then try to convert these events into something closer to what// microwindows expects. There is an assumption that the poll() and read()// code will be called often enough that there is no risk of overflow.// A circular buffer of scancodes.#define PS2KBD_SCANCODE_BUFSIZE    64static unsigned char    ps2kbd_scancode_buffer[PS2KBD_SCANCODE_BUFSIZE];static volatile int     ps2kbd_scancode_buffer_head = 0;    // new data written herestatic volatile int     ps2kbd_scancode_buffer_tail = 0;    // old data extracted from here// The current mouse state. Just maintain the current X and Y deltas,// button state,, and a delta flag. The hardware will generate// eight-byte mouse data packets, and when a complete packet has been// received the interrupt handler will update the values and set the// delta flag.#define PS2MOU_DATA_BUFSIZE 12static MWCOORD          ps2mou_dx       = 0;static MWCOORD          ps2mou_dy       = 0;static int              ps2mou_buttons  = 0;static volatile int     ps2mou_changed  = 0;static unsigned char    ps2mou_buffer[PS2MOU_DATA_BUFSIZE];static int              ps2mou_buffer_index = 0;// Sending commands. In theory there are a number of variations of// these.//// 1) commands to be sent directly to the controller. The control byte//    goes to KC_CONTROL, and any additional bytes go to KC_INPUT.//    The hardware will either ACK the additional bytes or request//    a resend.  Any replies can be read from KC_OUTPUT, and errors//    are possible.////    For replies, it is not clear how to distinguish between keyboard//    events that happen at just the wrong moment and the reply data.//// 2) commands for the keyboard. These just get written directly to//    the input buffer, one character at a time with ACKs or resends//    in between.//// 3) commands for the mouse. These involve a write of 0xD4 to the//    control port followed by a write to the input buffer. The latter//    results in ACKs or resends.static unsigned char*   ps2_command             = NULL;static int              ps2_command_mouse       = 0;static int              ps2_command_index       = 0;static int              ps2_command_length      = 0;static volatile int     ps2_command_ack         = 0;static int              ps2_command_mouse_waiting_for_ack   = 0;// ----------------------------------------------------------------------------// Decoding of mouse packets. There are lots of different rodent or// rodent-like devices out there, all implementing subtly different// protocols. A general-purpose solution would try to cope with all// of them. The eCos approach would be to allow just one to be// configured statically.// Support for Synaptics touchpads and compatible. This assumes// default relative format. Byte 0 contains various flags and// the button state. Byte 1 contains X-offset, byte 2 contains// the y-offset.static int              ps2mou_packet_size  = 3;static voidps2mou_synaptics_translate(void){    int new_buttons = 0;    int dx, dy;        // The packet consists of six bytes. Bit 3 of the first packet    // should be set. If that condition is not satisfied then we    // are in trouble and we may need to perform some sort of reset.    if (0 == (ps2mou_buffer[0] & 0x08)) {        // FIXME: perform some sort of reset to get the world        // back in sync.        return;    }    // Byte 0 holds the button flags.    if (0 != (ps2mou_buffer[0] & (0x01 << 0))) {        new_buttons = MWBUTTON_L;    }    if (0 != (ps2mou_buffer[0] & (0x01 << 1))) {

⌨️ 快捷键说明

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