Fix PS/2 mouse support

This commit is contained in:
tmk 2013-11-02 03:10:49 +09:00
parent 1591764cfb
commit 676d94d137
5 changed files with 95 additions and 84 deletions

View file

@ -25,6 +25,7 @@ endif
ifdef MOUSEKEY_ENABLE ifdef MOUSEKEY_ENABLE
SRC += $(COMMON_DIR)/mousekey.c SRC += $(COMMON_DIR)/mousekey.c
OPT_DEFS += -DMOUSEKEY_ENABLE OPT_DEFS += -DMOUSEKEY_ENABLE
OPT_DEFS += -DMOUSE_ENABLE
endif endif
ifdef EXTRAKEY_ENABLE ifdef EXTRAKEY_ENABLE
@ -47,16 +48,6 @@ ifdef NKRO_ENABLE
OPT_DEFS += -DNKRO_ENABLE OPT_DEFS += -DNKRO_ENABLE
endif endif
ifdef PS2_MOUSE_ENABLE
SRC += $(COMMON_DIR)/ps2.c \
$(COMMON_DIR)/ps2_mouse.c
OPT_DEFS += -DPS2_MOUSE_ENABLE
endif
ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE)
OPT_DEFS += -DMOUSE_ENABLE
endif
ifdef SLEEP_LED_ENABLE ifdef SLEEP_LED_ENABLE
SRC += $(COMMON_DIR)/sleep_led.c SRC += $(COMMON_DIR)/sleep_led.c
OPT_DEFS += -DSLEEP_LED_ENABLE OPT_DEFS += -DSLEEP_LED_ENABLE

View file

@ -30,8 +30,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "sendchar.h" #include "sendchar.h"
#include "bootmagic.h" #include "bootmagic.h"
#include "eeconfig.h" #include "eeconfig.h"
#include "mousekey.h"
#include "backlight.h" #include "backlight.h"
#ifdef MOUSEKEY_ENABLE
# include "mousekey.h"
#endif
#ifdef PS2_MOUSE_ENABLE
# include "ps2_mouse.h"
#endif
#ifdef MATRIX_HAS_GHOST #ifdef MATRIX_HAS_GHOST
@ -111,10 +116,18 @@ void keyboard_task(void)
action_exec(TICK); action_exec(TICK);
MATRIX_LOOP_END: MATRIX_LOOP_END:
#ifdef MOUSEKEY_ENABLE #ifdef MOUSEKEY_ENABLE
// mousekey repeat & acceleration // mousekey repeat & acceleration
mousekey_task(); mousekey_task();
#endif #endif
#ifdef PS2_MOUSE_ENABLE
if (ps2_mouse_read() == 0) {
ps2_mouse_usb_send();
}
#endif
// update LED // update LED
if (led_status != host_keyboard_leds()) { if (led_status != host_keyboard_leds()) {
led_status = host_keyboard_leds(); led_status = host_keyboard_leds();

View file

@ -1,2 +1,27 @@
PROTOCOL_DIR = protocol
ifdef PS2_MOUSE_ENABLE
SRC += $(PROTOCOL_DIR)/ps2_mouse.c
OPT_DEFS += -DPS2_MOUSE_ENABLE
OPT_DEFS += -DMOUSE_ENABLE
endif
ifdef PS2_USE_BUSYWAIT
SRC += protocol/ps2.c
OPT_DEFS += -DPS2_USE_BUSYWAIT
endif
ifdef PS2_USE_INT
SRC += protocol/ps2.c
OPT_DEFS += -DPS2_USE_INT
endif
ifdef PS2_USE_USART
SRC += protocol/ps2_usart.c
OPT_DEFS += -DPS2_USE_USART
endif
# Search Path # Search Path
VPATH += $(TOP_DIR)/protocol VPATH += $(TOP_DIR)/protocol

View file

@ -7,7 +7,11 @@ SRC += $(PJRC_DIR)/main.c \
$(PJRC_DIR)/usb.c $(PJRC_DIR)/usb.c
# Option modules # Option modules
ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE) ifdef MOUSEKEY_ENABLE
SRC += $(PJRC_DIR)/usb_mouse.c
endif
ifdef PS2_MOUSE_ENABLE
SRC += $(PJRC_DIR)/usb_mouse.c SRC += $(PJRC_DIR)/usb_mouse.c
endif endif

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2011 Jun Wako <wakojun@gmail.com> Copyright 2011,2013 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -32,27 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# define phex16(h) # define phex16(h)
#endif #endif
// disable when errors occur 255 times.
#define ERROR_RETURN() do { \
if (ps2_error) { \
if (ps2_mouse_error_count < 255) { \
ps2_mouse_error_count++; \
} else { \
ps2_mouse_error_count = 0; \
ps2_mouse_enable = false; \
} \
return ps2_error; \
} \
} while (0)
/*
TODO
----
- Stream mode
- Tracpoint command support: needed
- Middle button + move = Wheel traslation
*/
bool ps2_mouse_enable = true; bool ps2_mouse_enable = true;
uint8_t ps2_mouse_x = 0; uint8_t ps2_mouse_x = 0;
uint8_t ps2_mouse_y = 0; uint8_t ps2_mouse_y = 0;
@ -69,85 +49,50 @@ uint8_t ps2_mouse_init(void) {
ps2_host_init(); ps2_host_init();
// Reset // Not reliable: sometime fail to initialize mouse
// send Reset
_delay_ms(1000); // wait for powering up
rcv = ps2_host_send(0xFF); rcv = ps2_host_send(0xFF);
print("ps2_mouse_init: send 0xFF: "); print("ps2_mouse_init: send Reset: ");
phex(ps2_error); print("\n");
ERROR_RETURN();
// ACK
rcv = ps2_host_recv();
print("ps2_mouse_init: read ACK: ");
phex(rcv); phex(ps2_error); print("\n"); phex(rcv); phex(ps2_error); print("\n");
ERROR_RETURN();
// BAT takes some time // read completion code of BAT
_delay_ms(100); //_delay_ms(1000); // wait for Basic Assurance Test
rcv = ps2_host_recv(); rcv = ps2_host_recv();
print("ps2_mouse_init: read BAT: "); print("ps2_mouse_init: read BAT: ");
phex(rcv); phex(ps2_error); print("\n"); phex(rcv); phex(ps2_error); print("\n");
ERROR_RETURN();
// Device ID // read Device ID
rcv = ps2_host_recv(); rcv = ps2_host_recv();
print("ps2_mouse_init: read DevID: "); print("ps2_mouse_init: read DevID: ");
phex(rcv); phex(ps2_error); print("\n"); phex(rcv); phex(ps2_error); print("\n");
ERROR_RETURN();
// Enable data reporting // send Enable Data Reporting
ps2_host_send(0xF4); rcv = ps2_host_send(0xF4);
print("ps2_mouse_init: send 0xF4: "); print("ps2_mouse_init: send 0xF4: ");
phex(ps2_error); print("\n");
ERROR_RETURN();
// ACK
rcv = ps2_host_recv();
print("ps2_mouse_init: read ACK: ");
phex(rcv); phex(ps2_error); print("\n"); phex(rcv); phex(ps2_error); print("\n");
ERROR_RETURN();
// Set Remote mode // send Set Remote mode
ps2_host_send(0xF0); rcv = ps2_host_send(0xF0);
print("ps2_mouse_init: send 0xF0: "); print("ps2_mouse_init: send 0xF0: ");
phex(ps2_error); print("\n");
ERROR_RETURN();
// ACK
rcv = ps2_host_recv();
print("ps2_mouse_init: read ACK: ");
phex(rcv); phex(ps2_error); print("\n"); phex(rcv); phex(ps2_error); print("\n");
ERROR_RETURN();
return 0; return 0;
} }
/*
Data format:
bit: 7 6 5 4 3 2 1 0
-----------------------------------------------------------------------
0 btn: Yovflw Xovflw Ysign Xsign 1 Middle Right Left
1 x: X movement(0-255)
2 y: Y movement(0-255)
*/
uint8_t ps2_mouse_read(void) uint8_t ps2_mouse_read(void)
{ {
uint8_t rcv; uint8_t rcv;
if (!ps2_mouse_enable) return 1; if (!ps2_mouse_enable) return 1;
ps2_host_send(0xEB); rcv = ps2_host_send(0xEB);
ERROR_RETURN();
rcv=ps2_host_recv();
ERROR_RETURN();
if(rcv==0xFA) { if(rcv==0xFA) {
ps2_mouse_btn = ps2_host_recv(); ps2_mouse_btn = ps2_host_recv_response();
ERROR_RETURN(); ps2_mouse_x = ps2_host_recv_response();
ps2_mouse_x = ps2_host_recv(); ps2_mouse_y = ps2_host_recv_response();
ERROR_RETURN();
ps2_mouse_y = ps2_host_recv();
ERROR_RETURN();
} }
return 0; return 0;
} }
@ -216,3 +161,36 @@ void ps2_mouse_print(void)
phex(ps2_mouse_x); print(" "); phex(ps2_mouse_x); print(" ");
phex(ps2_mouse_y); print("\n"); phex(ps2_mouse_y); print("\n");
} }
/* PS/2 Mouse Synopsis
* http://www.computer-engineering.org/ps2mouse/
*
* Command:
* 0xFF: Reset
* 0xF6: Set Defaults Sampling; rate=100, resolution=4cnt/mm, scaling=1:1, reporting=disabled
* 0xF5: Disable Data Reporting
* 0xF4: Enable Data Reporting
* 0xF3: Set Sample Rate
* 0xF2: Get Device ID
* 0xF0: Set Remote Mode
* 0xEB: Read Data
* 0xEA: Set Stream Mode
* 0xE9: Status Request
* 0xE8: Set Resolution
* 0xE7: Set Scaling 2:1
* 0xE6: Set Scaling 1:1
*
* Mode:
* Stream Mode: devices sends the data when it changs its state
* Remote Mode: host polls the data periodically
*
* This code uses Remote Mode and polls the data with Read Data(0xEB).
*
* Data format:
* byte|7 6 5 4 3 2 1 0
* ----+--------------------------------------------------------------
* 0|Yovflw Xovflw Ysign Xsign 1 Middle Right Left
* 1| X movement(0-255)
* 2| Y movement(0-255)
*/