aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2013-11-21 13:01:47 +0900
committertmk <nobody@nowhere>2013-11-21 13:01:47 +0900
commit772ab7025ddf88126d9d6ddb654f62434985504b (patch)
treef0b4558bba2621a824736ceea0b09b51fdd41613
parent821578293c79c5612f9b77e447295f2947fd6c3d (diff)
parenta9c3f4750b3d703b8bbbc90db2566afd2aab0ec9 (diff)
downloadqmk_firmware-772ab7025ddf88126d9d6ddb654f62434985504b.tar.gz
qmk_firmware-772ab7025ddf88126d9d6ddb654f62434985504b.zip
Merge branch 'ps2_mouse_fix'
-rw-r--r--common.mk11
-rw-r--r--common/action.c6
-rw-r--r--common/action.h1
-rw-r--r--common/action_util.h1
-rw-r--r--common/host.c8
-rw-r--r--common/host.h6
-rw-r--r--common/keyboard.c13
-rw-r--r--common/mousekey.c1
-rw-r--r--keyboard/onekey/Makefile.lufa33
-rw-r--r--keyboard/onekey/Makefile.pjrc33
-rw-r--r--keyboard/onekey/config.h86
-rw-r--r--keyboard/onekey/matrix.c1
-rw-r--r--protocol.mk25
-rw-r--r--protocol/lufa/lufa.c9
-rw-r--r--protocol/pjrc.mk6
-rw-r--r--protocol/ps2.c59
-rw-r--r--protocol/ps2_mouse.c303
-rw-r--r--protocol/ps2_mouse.h40
-rw-r--r--protocol/ps2_usart.c54
19 files changed, 409 insertions, 287 deletions
diff --git a/common.mk b/common.mk
index 5b70db949..2ca06daae 100644
--- a/common.mk
+++ b/common.mk
@@ -25,6 +25,7 @@ endif
25ifdef MOUSEKEY_ENABLE 25ifdef MOUSEKEY_ENABLE
26 SRC += $(COMMON_DIR)/mousekey.c 26 SRC += $(COMMON_DIR)/mousekey.c
27 OPT_DEFS += -DMOUSEKEY_ENABLE 27 OPT_DEFS += -DMOUSEKEY_ENABLE
28 OPT_DEFS += -DMOUSE_ENABLE
28endif 29endif
29 30
30ifdef EXTRAKEY_ENABLE 31ifdef EXTRAKEY_ENABLE
@@ -47,16 +48,6 @@ ifdef NKRO_ENABLE
47 OPT_DEFS += -DNKRO_ENABLE 48 OPT_DEFS += -DNKRO_ENABLE
48endif 49endif
49 50
50ifdef PS2_MOUSE_ENABLE
51 SRC += $(COMMON_DIR)/ps2.c \
52 $(COMMON_DIR)/ps2_mouse.c
53 OPT_DEFS += -DPS2_MOUSE_ENABLE
54endif
55
56ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE)
57 OPT_DEFS += -DMOUSE_ENABLE
58endif
59
60ifdef SLEEP_LED_ENABLE 51ifdef SLEEP_LED_ENABLE
61 SRC += $(COMMON_DIR)/sleep_led.c 52 SRC += $(COMMON_DIR)/sleep_led.c
62 OPT_DEFS += -DSLEEP_LED_ENABLE 53 OPT_DEFS += -DSLEEP_LED_ENABLE
diff --git a/common/action.c b/common/action.c
index f7ae85b94..485abf81e 100644
--- a/common/action.c
+++ b/common/action.c
@@ -485,12 +485,6 @@ void clear_keyboard_but_mods(void)
485#endif 485#endif
486} 486}
487 487
488bool sending_anykey(void)
489{
490 return (has_anykey() || host_mouse_in_use() ||
491 host_last_sysytem_report() || host_last_consumer_report());
492}
493
494bool is_tap_key(key_t key) 488bool is_tap_key(key_t key)
495{ 489{
496 action_t action = layer_switch_get_action(key); 490 action_t action = layer_switch_get_action(key);
diff --git a/common/action.h b/common/action.h
index d57f4a86f..077711c23 100644
--- a/common/action.h
+++ b/common/action.h
@@ -64,7 +64,6 @@ void unregister_mods(uint8_t mods);
64//void set_mods(uint8_t mods); 64//void set_mods(uint8_t mods);
65void clear_keyboard(void); 65void clear_keyboard(void);
66void clear_keyboard_but_mods(void); 66void clear_keyboard_but_mods(void);
67bool sending_anykey(void);
68void layer_switch(uint8_t new_layer); 67void layer_switch(uint8_t new_layer);
69bool is_tap_key(key_t key); 68bool is_tap_key(key_t key);
70 69
diff --git a/common/action_util.h b/common/action_util.h
index 939bc2b66..f9d3161a8 100644
--- a/common/action_util.h
+++ b/common/action_util.h
@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
18#define ACTION_UTIL_H 18#define ACTION_UTIL_H
19 19
20#include <stdint.h> 20#include <stdint.h>
21#include "report.h"
21 22
22extern report_keyboard_t *keyboard_report; 23extern report_keyboard_t *keyboard_report;
23 24
diff --git a/common/host.c b/common/host.c
index 0703dba01..1eafef75c 100644
--- a/common/host.c
+++ b/common/host.c
@@ -27,9 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
27bool keyboard_nkro = false; 27bool keyboard_nkro = false;
28#endif 28#endif
29 29
30report_mouse_t mouse_report = {};
31
32
33static host_driver_t *driver; 30static host_driver_t *driver;
34static uint16_t last_system_report = 0; 31static uint16_t last_system_report = 0;
35static uint16_t last_consumer_report = 0; 32static uint16_t last_consumer_report = 0;
@@ -89,11 +86,6 @@ void host_consumer_send(uint16_t report)
89 (*driver->send_consumer)(report); 86 (*driver->send_consumer)(report);
90} 87}
91 88
92uint8_t host_mouse_in_use(void)
93{
94 return (mouse_report.buttons | mouse_report.x | mouse_report.y | mouse_report.v | mouse_report.h);
95}
96
97uint16_t host_last_sysytem_report(void) 89uint16_t host_last_sysytem_report(void)
98{ 90{
99 return last_system_report; 91 return last_system_report;
diff --git a/common/host.h b/common/host.h
index c1a0fbac4..8ff262985 100644
--- a/common/host.h
+++ b/common/host.h
@@ -32,9 +32,6 @@ extern "C" {
32extern bool keyboard_nkro; 32extern bool keyboard_nkro;
33#endif 33#endif
34 34
35/* report */
36extern report_mouse_t mouse_report;
37
38 35
39/* host driver */ 36/* host driver */
40void host_set_driver(host_driver_t *driver); 37void host_set_driver(host_driver_t *driver);
@@ -47,9 +44,6 @@ void host_mouse_send(report_mouse_t *report);
47void host_system_send(uint16_t data); 44void host_system_send(uint16_t data);
48void host_consumer_send(uint16_t data); 45void host_consumer_send(uint16_t data);
49 46
50/* mouse report utils */
51uint8_t host_mouse_in_use(void);
52
53uint16_t host_last_sysytem_report(void); 47uint16_t host_last_sysytem_report(void);
54uint16_t host_last_consumer_report(void); 48uint16_t host_last_consumer_report(void);
55 49
diff --git a/common/keyboard.c b/common/keyboard.c
index 601e3abe1..2b66f20a0 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -30,8 +30,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
30#include "sendchar.h" 30#include "sendchar.h"
31#include "bootmagic.h" 31#include "bootmagic.h"
32#include "eeconfig.h" 32#include "eeconfig.h"
33#include "mousekey.h"
34#include "backlight.h" 33#include "backlight.h"
34#ifdef MOUSEKEY_ENABLE
35# include "mousekey.h"
36#endif
37#ifdef PS2_MOUSE_ENABLE
38# include "ps2_mouse.h"
39#endif
35 40
36 41
37#ifdef MATRIX_HAS_GHOST 42#ifdef MATRIX_HAS_GHOST
@@ -111,10 +116,16 @@ void keyboard_task(void)
111 action_exec(TICK); 116 action_exec(TICK);
112 117
113MATRIX_LOOP_END: 118MATRIX_LOOP_END:
119
114#ifdef MOUSEKEY_ENABLE 120#ifdef MOUSEKEY_ENABLE
115 // mousekey repeat & acceleration 121 // mousekey repeat & acceleration
116 mousekey_task(); 122 mousekey_task();
117#endif 123#endif
124
125#ifdef PS2_MOUSE_ENABLE
126 ps2_mouse_task();
127#endif
128
118 // update LED 129 // update LED
119 if (led_status != host_keyboard_leds()) { 130 if (led_status != host_keyboard_leds()) {
120 led_status = host_keyboard_leds(); 131 led_status = host_keyboard_leds();
diff --git a/common/mousekey.c b/common/mousekey.c
index 3068fc5e3..017be9411 100644
--- a/common/mousekey.c
+++ b/common/mousekey.c
@@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
26 26
27 27
28 28
29static report_mouse_t mouse_report = {};
29static uint8_t mousekey_repeat = 0; 30static uint8_t mousekey_repeat = 0;
30static uint8_t mousekey_accel = 0; 31static uint8_t mousekey_accel = 0;
31 32
diff --git a/keyboard/onekey/Makefile.lufa b/keyboard/onekey/Makefile.lufa
index 03cfd83a5..60a84ba00 100644
--- a/keyboard/onekey/Makefile.lufa
+++ b/keyboard/onekey/Makefile.lufa
@@ -93,7 +93,7 @@ ARCH = AVR8
93F_USB = $(F_CPU) 93F_USB = $(F_CPU)
94 94
95# Interrupt driven control endpoint task(+60) 95# Interrupt driven control endpoint task(+60)
96#OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT 96OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
97 97
98 98
99# Boot Section Size in *bytes* 99# Boot Section Size in *bytes*
@@ -108,34 +108,25 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096
108# Build Options 108# Build Options
109# comment out to disable the options. 109# comment out to disable the options.
110# 110#
111BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) 111#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
112MOUSEKEY_ENABLE = yes # Mouse keys(+4700) 112#MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
113EXTRAKEY_ENABLE = yes # Audio control and System control(+450) 113#EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
114CONSOLE_ENABLE = yes # Console for debug(+400) 114CONSOLE_ENABLE = yes # Console for debug(+400)
115COMMAND_ENABLE = yes # Commands for debug and configuration 115#COMMAND_ENABLE = yes # Commands for debug and configuration
116SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend 116#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
117#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA 117#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
118 118
119PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support
120PS2_USE_BUSYWAIT = yes # uses primitive reference code
121#PS2_USE_INT = yes # uses external interrupt for falling edge of PS/2 clock pin
122#PS2_USE_USART = yes # uses hardware USART engine for PS/2 signal receive(recomened)
119 123
120# Optimize size but this may cause error "relocation truncated to fit"
121#EXTRALDFLAGS = -Wl,--relax
122 124
123# Search Path 125# Search Path
124VPATH += $(TARGET_DIR) 126VPATH += $(TARGET_DIR)
125VPATH += $(TOP_DIR) 127VPATH += $(TOP_DIR)
126 128
127include $(TOP_DIR)/protocol/lufa.mk
128include $(TOP_DIR)/common.mk 129include $(TOP_DIR)/common.mk
130include $(TOP_DIR)/protocol.mk
131include $(TOP_DIR)/protocol/lufa.mk
129include $(TOP_DIR)/rules.mk 132include $(TOP_DIR)/rules.mk
130
131plain: OPT_DEFS += -DKEYMAP_PLAIN
132plain: all
133
134poker: OPT_DEFS += -DKEYMAP_POKER
135poker: all
136
137poker_set: OPT_DEFS += -DKEYMAP_POKER_SET
138poker_set: all
139
140poker_bit: OPT_DEFS += -DKEYMAP_POKER_BIT
141poker_bit: all
diff --git a/keyboard/onekey/Makefile.pjrc b/keyboard/onekey/Makefile.pjrc
index 194a2b975..24ade3350 100644
--- a/keyboard/onekey/Makefile.pjrc
+++ b/keyboard/onekey/Makefile.pjrc
@@ -79,32 +79,25 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096
79# Build Options 79# Build Options
80# comment out to disable the options. 80# comment out to disable the options.
81# 81#
82BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) 82#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
83MOUSEKEY_ENABLE = yes # Mouse keys(+5000) 83#MOUSEKEY_ENABLE = yes # Mouse keys(+5000)
84EXTRAKEY_ENABLE = yes # Audio control and System control(+600) 84#EXTRAKEY_ENABLE = yes # Audio control and System control(+600)
85CONSOLE_ENABLE = yes # Console for debug 85CONSOLE_ENABLE = yes # Console for debug
86COMMAND_ENABLE = yes # Commands for debug and configuration 86#COMMAND_ENABLE = yes # Commands for debug and configuration
87SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend 87#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
88NKRO_ENABLE = yes # USB Nkey Rollover(+500) 88#NKRO_ENABLE = yes # USB Nkey Rollover(+500)
89#PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support 89
90PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support
91PS2_USE_BUSYWAIT = yes # uses primitive reference code
92#PS2_USE_INT = yes # uses external interrupt for falling edge of PS/2 clock pin
93#PS2_USE_USART = yes # uses hardware USART engine for PS/2 signal receive(recomened)
90 94
91 95
92# Search Path 96# Search Path
93VPATH += $(TARGET_DIR) 97VPATH += $(TARGET_DIR)
94VPATH += $(TOP_DIR) 98VPATH += $(TOP_DIR)
95 99
96include $(TOP_DIR)/protocol/pjrc.mk
97include $(TOP_DIR)/common.mk 100include $(TOP_DIR)/common.mk
101include $(TOP_DIR)/protocol.mk
102include $(TOP_DIR)/protocol/pjrc.mk
98include $(TOP_DIR)/rules.mk 103include $(TOP_DIR)/rules.mk
99
100plain: OPT_DEFS += -DKEYMAP_PLAIN
101plain: all
102
103poker: OPT_DEFS += -DKEYMAP_POKER
104poker: all
105
106poker_set: OPT_DEFS += -DKEYMAP_POKER_SET
107poker_set: all
108
109poker_bit: OPT_DEFS += -DKEYMAP_POKER_BIT
110poker_bit: all
diff --git a/keyboard/onekey/config.h b/keyboard/onekey/config.h
index c5bc64de9..1d2e052bf 100644
--- a/keyboard/onekey/config.h
+++ b/keyboard/onekey/config.h
@@ -67,4 +67,90 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
67//#define NO_ACTION_MACRO 67//#define NO_ACTION_MACRO
68//#define NO_ACTION_FUNCTION 68//#define NO_ACTION_FUNCTION
69 69
70
71/* PS/2 mouse */
72#ifdef PS2_USE_BUSYWAIT
73# define PS2_CLOCK_PORT PORTD
74# define PS2_CLOCK_PIN PIND
75# define PS2_CLOCK_DDR DDRD
76# define PS2_CLOCK_BIT 5
77# define PS2_DATA_PORT PORTD
78# define PS2_DATA_PIN PIND
79# define PS2_DATA_DDR DDRD
80# define PS2_DATA_BIT 2
81#endif
82
83
84/* PS/2 mouse interrupt version */
85#ifdef PS2_USE_INT
86/* uses INT1 for clock line(ATMega32U4) */
87#define PS2_CLOCK_PORT PORTD
88#define PS2_CLOCK_PIN PIND
89#define PS2_CLOCK_DDR DDRD
90#define PS2_CLOCK_BIT 5
91#define PS2_DATA_PORT PORTD
92#define PS2_DATA_PIN PIND
93#define PS2_DATA_DDR DDRD
94#define PS2_DATA_BIT 2
95
96#define PS2_INT_INIT() do { \
97 EICRA |= ((1<<ISC11) | \
98 (0<<ISC10)); \
99} while (0)
100#define PS2_INT_ON() do { \
101 EIMSK |= (1<<INT1); \
102} while (0)
103#define PS2_INT_OFF() do { \
104 EIMSK &= ~(1<<INT1); \
105} while (0)
106#define PS2_INT_VECT INT1_vect
107#endif
108
109
110/* PS/2 mouse USART version */
111#ifdef PS2_USE_USART
112#if defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)
113/* XCK for clock line and RXD for data line */
114#define PS2_CLOCK_PORT PORTD
115#define PS2_CLOCK_PIN PIND
116#define PS2_CLOCK_DDR DDRD
117#define PS2_CLOCK_BIT 5
118#define PS2_DATA_PORT PORTD
119#define PS2_DATA_PIN PIND
120#define PS2_DATA_DDR DDRD
121#define PS2_DATA_BIT 2
122
123/* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */
124/* set DDR of CLOCK as input to be slave */
125#define PS2_USART_INIT() do { \
126 PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT); \
127 PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); \
128 UCSR1C = ((1 << UMSEL10) | \
129 (3 << UPM10) | \
130 (0 << USBS1) | \
131 (3 << UCSZ10) | \
132 (0 << UCPOL1)); \
133 UCSR1A = 0; \
134 UBRR1H = 0; \
135 UBRR1L = 0; \
136} while (0)
137#define PS2_USART_RX_INT_ON() do { \
138 UCSR1B = ((1 << RXCIE1) | \
139 (1 << RXEN1)); \
140} while (0)
141#define PS2_USART_RX_POLL_ON() do { \
142 UCSR1B = (1 << RXEN1); \
143} while (0)
144#define PS2_USART_OFF() do { \
145 UCSR1C = 0; \
146 UCSR1B &= ~((1 << RXEN1) | \
147 (1 << TXEN1)); \
148} while (0)
149#define PS2_USART_RX_READY (UCSR1A & (1<<RXC1))
150#define PS2_USART_RX_DATA UDR1
151#define PS2_USART_ERROR (UCSR1A & ((1<<FE1) | (1<<DOR1) | (1<<UPE1)))
152#define PS2_USART_RX_VECT USART1_RX_vect
153#endif
154#endif
155
70#endif 156#endif
diff --git a/keyboard/onekey/matrix.c b/keyboard/onekey/matrix.c
index cd0789c60..a0a14ff82 100644
--- a/keyboard/onekey/matrix.c
+++ b/keyboard/onekey/matrix.c
@@ -59,6 +59,7 @@ void matrix_init(void)
59{ 59{
60 debug_enable = true; 60 debug_enable = true;
61 debug_matrix = true; 61 debug_matrix = true;
62 debug_mouse = true;
62 // initialize row and col 63 // initialize row and col
63 unselect_rows(); 64 unselect_rows();
64 init_cols(); 65 init_cols();
diff --git a/protocol.mk b/protocol.mk
index 1442c5206..0d5f06c7e 100644
--- a/protocol.mk
+++ b/protocol.mk
@@ -1,2 +1,27 @@
1PROTOCOL_DIR = protocol
2
3
4ifdef PS2_MOUSE_ENABLE
5 SRC += $(PROTOCOL_DIR)/ps2_mouse.c
6 OPT_DEFS += -DPS2_MOUSE_ENABLE
7 OPT_DEFS += -DMOUSE_ENABLE
8endif
9
10ifdef PS2_USE_BUSYWAIT
11 SRC += protocol/ps2.c
12 OPT_DEFS += -DPS2_USE_BUSYWAIT
13endif
14
15ifdef PS2_USE_INT
16 SRC += protocol/ps2.c
17 OPT_DEFS += -DPS2_USE_INT
18endif
19
20ifdef PS2_USE_USART
21 SRC += protocol/ps2_usart.c
22 OPT_DEFS += -DPS2_USE_USART
23endif
24
25
1# Search Path 26# Search Path
2VPATH += $(TOP_DIR)/protocol 27VPATH += $(TOP_DIR)/protocol
diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c
index a230d5ba2..04e8e78f3 100644
--- a/protocol/lufa/lufa.c
+++ b/protocol/lufa/lufa.c
@@ -539,11 +539,18 @@ int main(void)
539{ 539{
540 SetupHardware(); 540 SetupHardware();
541 sei(); 541 sei();
542
543 /* wait for USB startup & debug output */
544 while (USB_DeviceState != DEVICE_STATE_Configured) {
542#if defined(INTERRUPT_CONTROL_ENDPOINT) 545#if defined(INTERRUPT_CONTROL_ENDPOINT)
543 while (USB_DeviceState != DEVICE_STATE_Configured) ; 546 ;
547#else
548 USB_USBTask();
544#endif 549#endif
550 }
545 print("USB configured.\n"); 551 print("USB configured.\n");
546 552
553 /* init modules */
547 keyboard_init(); 554 keyboard_init();
548 host_set_driver(&lufa_driver); 555 host_set_driver(&lufa_driver);
549#ifdef SLEEP_LED_ENABLE 556#ifdef SLEEP_LED_ENABLE
diff --git a/protocol/pjrc.mk b/protocol/pjrc.mk
index 27f908b1c..5a4461382 100644
--- a/protocol/pjrc.mk
+++ b/protocol/pjrc.mk
@@ -7,7 +7,11 @@ SRC += $(PJRC_DIR)/main.c \
7 $(PJRC_DIR)/usb.c 7 $(PJRC_DIR)/usb.c
8 8
9# Option modules 9# Option modules
10ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE) 10ifdef MOUSEKEY_ENABLE
11 SRC += $(PJRC_DIR)/usb_mouse.c
12endif
13
14ifdef PS2_MOUSE_ENABLE
11 SRC += $(PJRC_DIR)/usb_mouse.c 15 SRC += $(PJRC_DIR)/usb_mouse.c
12endif 16endif
13 17
diff --git a/protocol/ps2.c b/protocol/ps2.c
index ed4560910..e5873a9bf 100644
--- a/protocol/ps2.c
+++ b/protocol/ps2.c
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2010,2011 Jun WAKO <wakojun@gmail.com> 2Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
3 3
4This software is licensed with a Modified BSD License. 4This software is licensed with a Modified BSD License.
5All of this is supposed to be Free Software, Open Source, DFSG-free, 5All of this is supposed to be Free Software, Open Source, DFSG-free,
@@ -43,7 +43,9 @@ POSSIBILITY OF SUCH DAMAGE.
43#include "debug.h" 43#include "debug.h"
44 44
45 45
46#ifndef PS2_USE_INT
46static uint8_t recv_data(void); 47static uint8_t recv_data(void);
48#endif
47static inline void clock_lo(void); 49static inline void clock_lo(void);
48static inline void clock_hi(void); 50static inline void clock_hi(void);
49static inline bool clock_in(void); 51static inline bool clock_in(void);
@@ -109,12 +111,12 @@ uint8_t ps2_host_send(uint8_t data)
109#endif 111#endif
110 /* terminate a transmission if we have */ 112 /* terminate a transmission if we have */
111 inhibit(); 113 inhibit();
112 _delay_us(100); 114 _delay_us(200); // at least 100us
113 115
114 /* start bit [1] */ 116 /* start bit [1] */
115 data_lo(); 117 data_lo();
116 clock_hi(); 118 clock_hi();
117 WAIT(clock_lo, 15000, 1); 119 WAIT(clock_lo, 20000, 10); // may take 15ms at most until device starts clocking
118 /* data [2-9] */ 120 /* data [2-9] */
119 for (uint8_t i = 0; i < 8; i++) { 121 for (uint8_t i = 0; i < 8; i++) {
120 _delay_us(15); 122 _delay_us(15);
@@ -143,6 +145,9 @@ uint8_t ps2_host_send(uint8_t data)
143 WAIT(clock_hi, 50, 8); 145 WAIT(clock_hi, 50, 8);
144 WAIT(data_hi, 50, 9); 146 WAIT(data_hi, 50, 9);
145 147
148#ifdef PS2_USE_INT
149 PS2_INT_ON();
150#endif
146 res = ps2_host_recv_response(); 151 res = ps2_host_recv_response();
147ERROR: 152ERROR:
148#ifdef PS2_USE_INT 153#ifdef PS2_USE_INT
@@ -154,11 +159,15 @@ ERROR:
154 return res; 159 return res;
155} 160}
156 161
162#ifndef PS2_USE_INT
157/* receive data when host want else inhibit communication */ 163/* receive data when host want else inhibit communication */
158uint8_t ps2_host_recv_response(void) 164uint8_t ps2_host_recv_response(void)
159{ 165{
160 uint8_t data = 0; 166 uint8_t data = 0;
161 167
168#ifdef PS2_USE_INT
169 PS2_INT_OFF();
170#endif
162 /* terminate a transmission if we have */ 171 /* terminate a transmission if we have */
163 inhibit(); 172 inhibit();
164 _delay_us(100); 173 _delay_us(100);
@@ -167,12 +176,13 @@ uint8_t ps2_host_recv_response(void)
167 idle(); 176 idle();
168 177
169 /* wait start bit */ 178 /* wait start bit */
170 wait_clock_lo(2000); 179 wait_clock_lo(25000); // command response may take 20 ms at most
171 data = recv_data(); 180 data = recv_data();
172 181
173 inhibit(); 182 inhibit();
174 return data; 183 return data;
175} 184}
185#endif
176 186
177#ifndef PS2_USE_INT 187#ifndef PS2_USE_INT
178uint8_t ps2_host_recv(void) 188uint8_t ps2_host_recv(void)
@@ -187,9 +197,6 @@ static uint8_t pbuf_head = 0;
187static uint8_t pbuf_tail = 0; 197static uint8_t pbuf_tail = 0;
188static inline void pbuf_enqueue(uint8_t data) 198static inline void pbuf_enqueue(uint8_t data)
189{ 199{
190 if (!data)
191 return;
192
193 uint8_t sreg = SREG; 200 uint8_t sreg = SREG;
194 cli(); 201 cli();
195 uint8_t next = (pbuf_head + 1) % PBUF_SIZE; 202 uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
@@ -215,6 +222,21 @@ static inline uint8_t pbuf_dequeue(void)
215 222
216 return val; 223 return val;
217} 224}
225static inline bool pbuf_has_data(void)
226{
227 uint8_t sreg = SREG;
228 cli();
229 bool has_data = (pbuf_head != pbuf_tail);
230 SREG = sreg;
231 return has_data;
232}
233static inline void pbuf_clear(void)
234{
235 uint8_t sreg = SREG;
236 cli();
237 pbuf_head = pbuf_tail = 0;
238 SREG = sreg;
239}
218 240
219/* get data received by interrupt */ 241/* get data received by interrupt */
220uint8_t ps2_host_recv(void) 242uint8_t ps2_host_recv(void)
@@ -229,13 +251,12 @@ uint8_t ps2_host_recv(void)
229 return pbuf_dequeue(); 251 return pbuf_dequeue();
230} 252}
231 253
232#if 0 254uint8_t ps2_host_recv_response(void)
233#define DEBUGP_INIT() do { DDRC = 0xFF; } while (0) 255{
234#define DEBUGP(x) do { PORTC = x; } while (0) 256 while (!pbuf_has_data()) ;
235#else 257 return pbuf_dequeue();
236#define DEBUGP_INIT() 258}
237#define DEBUGP(x) 259
238#endif
239ISR(PS2_INT_VECT) 260ISR(PS2_INT_VECT)
240{ 261{
241 static enum { 262 static enum {
@@ -256,7 +277,6 @@ ISR(PS2_INT_VECT)
256 } 277 }
257 278
258 state++; 279 state++;
259 DEBUGP(state);
260 switch (state) { 280 switch (state) {
261 case START: 281 case START:
262 if (data_in()) 282 if (data_in())
@@ -289,6 +309,7 @@ ISR(PS2_INT_VECT)
289 if (!data_in()) 309 if (!data_in())
290 goto ERROR; 310 goto ERROR;
291 pbuf_enqueue(data); 311 pbuf_enqueue(data);
312//phex(data);
292 goto DONE; 313 goto DONE;
293 break; 314 break;
294 default: 315 default:
@@ -296,7 +317,6 @@ ISR(PS2_INT_VECT)
296 } 317 }
297 goto RETURN; 318 goto RETURN;
298ERROR: 319ERROR:
299 DEBUGP(0x0F);
300 inhibit(); 320 inhibit();
301 ps2_error = state; 321 ps2_error = state;
302DONE: 322DONE:
@@ -309,11 +329,6 @@ RETURN:
309#endif 329#endif
310 330
311 331
312static void ps2_reset(void)
313{
314 ps2_host_send(0xFF);
315}
316
317/* send LED state to keyboard */ 332/* send LED state to keyboard */
318void ps2_host_set_led(uint8_t led) 333void ps2_host_set_led(uint8_t led)
319{ 334{
@@ -322,6 +337,7 @@ void ps2_host_set_led(uint8_t led)
322} 337}
323 338
324 339
340#ifndef PS2_USE_INT
325/* called after start bit comes */ 341/* called after start bit comes */
326static uint8_t recv_data(void) 342static uint8_t recv_data(void)
327{ 343{
@@ -361,6 +377,7 @@ static uint8_t recv_data(void)
361ERROR: 377ERROR:
362 return 0; 378 return 0;
363} 379}
380#endif
364 381
365static inline void clock_lo() 382static inline void clock_lo()
366{ 383{
diff --git a/protocol/ps2_mouse.c b/protocol/ps2_mouse.c
index f796b2b4d..4702f12c4 100644
--- a/protocol/ps2_mouse.c
+++ b/protocol/ps2_mouse.c
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2011 Jun Wako <wakojun@gmail.com> 2Copyright 2011,2013 Jun Wako <wakojun@gmail.com>
3 3
4This program is free software: you can redistribute it and/or modify 4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by 5it under the terms of the GNU General Public License as published by
@@ -20,199 +20,196 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
20#include<util/delay.h> 20#include<util/delay.h>
21#include "ps2.h" 21#include "ps2.h"
22#include "ps2_mouse.h" 22#include "ps2_mouse.h"
23#include "usb_mouse.h" 23#include "report.h"
24#include "host.h"
25#include "timer.h"
26#include "print.h"
27#include "debug.h"
24 28
25#define PS2_MOUSE_DEBUG
26#ifdef PS2_MOUSE_DEBUG
27# include "print.h"
28# include "debug.h"
29#else
30# define print(s)
31# define phex(h)
32# define phex16(h)
33#endif
34 29
35// disable when errors occur 255 times. 30static report_mouse_t mouse_report = {};
36#define ERROR_RETURN() do { \
37 if (ps2_error) { \
38 if (ps2_mouse_error_count < 255) { \
39 ps2_mouse_error_count++; \
40 } else { \
41 ps2_mouse_error_count = 0; \
42 ps2_mouse_enable = false; \
43 } \
44 return ps2_error; \
45 } \
46} while (0)
47 31
48 32
49/* 33static void print_usb_data(void);
50TODO
51----
52- Stream mode
53- Tracpoint command support: needed
54- Middle button + move = Wheel traslation
55*/
56bool ps2_mouse_enable = true;
57uint8_t ps2_mouse_x = 0;
58uint8_t ps2_mouse_y = 0;
59uint8_t ps2_mouse_btn = 0;
60uint8_t ps2_mouse_error_count = 0;
61
62static uint8_t ps2_mouse_btn_prev = 0;
63 34
64 35
36/* supports only 3 button mouse at this time */
65uint8_t ps2_mouse_init(void) { 37uint8_t ps2_mouse_init(void) {
66 uint8_t rcv; 38 uint8_t rcv;
67 39
68 if (!ps2_mouse_enable) return 1;
69
70 ps2_host_init(); 40 ps2_host_init();
71 41
72 // Reset 42 _delay_ms(1000); // wait for powering up
73 rcv = ps2_host_send(0xFF);
74 print("ps2_mouse_init: send 0xFF: ");
75 phex(ps2_error); print("\n");
76 ERROR_RETURN();
77 43
78 // ACK 44 // send Reset
79 rcv = ps2_host_recv(); 45 rcv = ps2_host_send(0xFF);
80 print("ps2_mouse_init: read ACK: "); 46 print("ps2_mouse_init: send Reset: ");
81 phex(rcv); phex(ps2_error); print("\n"); 47 phex(rcv); phex(ps2_error); print("\n");
82 ERROR_RETURN();
83 48
84 // BAT takes some time 49 // read completion code of BAT
85 _delay_ms(100); 50 rcv = ps2_host_recv_response();
86 rcv = ps2_host_recv();
87 print("ps2_mouse_init: read BAT: "); 51 print("ps2_mouse_init: read BAT: ");
88 phex(rcv); phex(ps2_error); print("\n"); 52 phex(rcv); phex(ps2_error); print("\n");
89 ERROR_RETURN();
90 53
91 // Device ID 54 // read Device ID
92 rcv = ps2_host_recv(); 55 rcv = ps2_host_recv_response();
93 print("ps2_mouse_init: read DevID: "); 56 print("ps2_mouse_init: read DevID: ");
94 phex(rcv); phex(ps2_error); print("\n"); 57 phex(rcv); phex(ps2_error); print("\n");
95 ERROR_RETURN();
96 58
97 // Enable data reporting 59 // send Set Remote mode
98 ps2_host_send(0xF4); 60 rcv = ps2_host_send(0xF0);
99 print("ps2_mouse_init: send 0xF4: ");
100 phex(ps2_error); print("\n");
101 ERROR_RETURN();
102
103 // ACK
104 rcv = ps2_host_recv();
105 print("ps2_mouse_init: read ACK: ");
106 phex(rcv); phex(ps2_error); print("\n");
107 ERROR_RETURN();
108
109 // Set Remote mode
110 ps2_host_send(0xF0);
111 print("ps2_mouse_init: send 0xF0: "); 61 print("ps2_mouse_init: send 0xF0: ");
112 phex(ps2_error); print("\n");
113 ERROR_RETURN();
114
115 // ACK
116 rcv = ps2_host_recv();
117 print("ps2_mouse_init: read ACK: ");
118 phex(rcv); phex(ps2_error); print("\n"); 62 phex(rcv); phex(ps2_error); print("\n");
119 ERROR_RETURN();
120 63
121 return 0; 64 return 0;
122} 65}
123 66
124/* 67#define X_IS_NEG (mouse_report.buttons & (1<<PS2_MOUSE_X_SIGN))
125Data format: 68#define Y_IS_NEG (mouse_report.buttons & (1<<PS2_MOUSE_Y_SIGN))
126 bit: 7 6 5 4 3 2 1 0 69#define X_IS_OVF (mouse_report.buttons & (1<<PS2_MOUSE_X_OVFLW))
127----------------------------------------------------------------------- 70#define Y_IS_OVF (mouse_report.buttons & (1<<PS2_MOUSE_Y_OVFLW))
1280 btn: Yovflw Xovflw Ysign Xsign 1 Middle Right Left 71void ps2_mouse_task(void)
1291 x: X movement(0-255)
1302 y: Y movement(0-255)
131*/
132uint8_t ps2_mouse_read(void)
133{ 72{
73 enum { SCROLL_NONE, SCROLL_BTN, SCROLL_SENT };
74 static uint8_t scroll_state = SCROLL_NONE;
75 static uint8_t buttons_prev = 0;
76
77 /* receives packet from mouse */
134 uint8_t rcv; 78 uint8_t rcv;
79 rcv = ps2_host_send(PS2_MOUSE_READ_DATA);
80 if (rcv == PS2_ACK) {
81 mouse_report.buttons = ps2_host_recv_response();
82 mouse_report.x = ps2_host_recv_response();
83 mouse_report.y = ps2_host_recv_response();
84 } else {
85 if (!debug_mouse) print("ps2_mouse: fail to get mouse packet\n");
86 return;
87 }
135 88
136 if (!ps2_mouse_enable) return 1; 89 /* if mouse moves or buttons state changes */
90 if (mouse_report.x || mouse_report.y ||
91 ((mouse_report.buttons ^ buttons_prev) & PS2_MOUSE_BTN_MASK)) {
137 92
138 ps2_host_send(0xEB); 93#ifdef PS2_MOUSE_DEBUG
139 ERROR_RETURN(); 94 print("ps2_mouse raw: [");
95 phex(mouse_report.buttons); print("|");
96 print_hex8((uint8_t)mouse_report.x); print(" ");
97 print_hex8((uint8_t)mouse_report.y); print("]\n");
98#endif
140 99
141 rcv=ps2_host_recv(); 100 buttons_prev = mouse_report.buttons;
142 ERROR_RETURN(); 101
102 // PS/2 mouse data is '9-bit integer'(-256 to 255) which is comprised of sign-bit and 8-bit value.
103 // bit: 8 7 ... 0
104 // sign \8-bit/
105 //
106 // Meanwhile USB HID mouse indicates 8bit data(-127 to 127), note that -128 is not used.
107 //
108 // This converts PS/2 data into HID value. Use only -127-127 out of PS/2 9-bit.
109 mouse_report.x = X_IS_NEG ?
110 ((!X_IS_OVF && -127 <= mouse_report.x && mouse_report.x <= -1) ? mouse_report.x : -127) :
111 ((!X_IS_OVF && 0 <= mouse_report.x && mouse_report.x <= 127) ? mouse_report.x : 127);
112 mouse_report.y = Y_IS_NEG ?
113 ((!Y_IS_OVF && -127 <= mouse_report.y && mouse_report.y <= -1) ? mouse_report.y : -127) :
114 ((!Y_IS_OVF && 0 <= mouse_report.y && mouse_report.y <= 127) ? mouse_report.y : 127);
115
116 // remove sign and overflow flags
117 mouse_report.buttons &= PS2_MOUSE_BTN_MASK;
118
119 // invert coordinate of y to conform to USB HID mouse
120 mouse_report.y = -mouse_report.y;
121
122
123#if PS2_MOUSE_SCROLL_BTN_MASK
124 static uint16_t scroll_button_time = 0;
125 if ((mouse_report.buttons & (PS2_MOUSE_SCROLL_BTN_MASK)) == (PS2_MOUSE_SCROLL_BTN_MASK)) {
126 if (scroll_state == SCROLL_NONE) {
127 scroll_button_time = timer_read();
128 scroll_state = SCROLL_BTN;
129 }
143 130
144 if(rcv==0xFA) { 131 // doesn't send Scroll Button
145 ps2_mouse_btn = ps2_host_recv(); 132 //mouse_report.buttons &= ~(PS2_MOUSE_SCROLL_BTN_MASK);
146 ERROR_RETURN();
147 ps2_mouse_x = ps2_host_recv();
148 ERROR_RETURN();
149 ps2_mouse_y = ps2_host_recv();
150 ERROR_RETURN();
151 }
152 return 0;
153}
154 133
155bool ps2_mouse_changed(void) 134 if (mouse_report.x || mouse_report.y) {
156{ 135 scroll_state = SCROLL_SENT;
157 return (ps2_mouse_x || ps2_mouse_y || (ps2_mouse_btn & PS2_MOUSE_BTN_MASK) != ps2_mouse_btn_prev);
158}
159 136
160#define PS2_MOUSE_SCROLL_BUTTON 0x04 137 mouse_report.v = -mouse_report.y/(PS2_MOUSE_SCROLL_DIVISOR_V);
161void ps2_mouse_usb_send(void) 138 mouse_report.h = mouse_report.x/(PS2_MOUSE_SCROLL_DIVISOR_H);
162{ 139 mouse_report.x = 0;
163 static bool scrolled = false; 140 mouse_report.y = 0;
164 141 //host_mouse_send(&mouse_report);
165 if (!ps2_mouse_enable) return; 142 }
166 143 }
167 if (ps2_mouse_changed()) { 144 else if ((mouse_report.buttons & (PS2_MOUSE_SCROLL_BTN_MASK)) == 0) {
168 int8_t x, y, v, h; 145#if PS2_MOUSE_SCROLL_BTN_SEND
169 x = y = v = h = 0; 146 if (scroll_state == SCROLL_BTN &&
170 147 TIMER_DIFF_16(timer_read(), scroll_button_time) < PS2_MOUSE_SCROLL_BTN_SEND) {
171 // convert scale of X, Y: PS/2(-256/255) -> USB(-127/127) 148 // send Scroll Button(down and up at once) when not scrolled
172 if (ps2_mouse_btn & (1<<PS2_MOUSE_X_SIGN)) 149 mouse_report.buttons |= (PS2_MOUSE_SCROLL_BTN_MASK);
173 x = ps2_mouse_x > 128 ? (int8_t)ps2_mouse_x : -127; 150 host_mouse_send(&mouse_report);
174 else
175 x = ps2_mouse_x < 128 ? (int8_t)ps2_mouse_x : 127;
176
177 if (ps2_mouse_btn & (1<<PS2_MOUSE_Y_SIGN))
178 y = ps2_mouse_y > 128 ? (int8_t)ps2_mouse_y : -127;
179 else
180 y = ps2_mouse_y < 128 ? (int8_t)ps2_mouse_y : 127;
181
182 // Y is needed to reverse
183 y = -y;
184
185 if (ps2_mouse_btn & PS2_MOUSE_SCROLL_BUTTON) {
186 // scroll
187 if (x > 0 || x < 0) h = (x > 64 ? 64 : (x < -64 ? -64 :x));
188 if (y > 0 || y < 0) v = (y > 64 ? 64 : (y < -64 ? -64 :y));
189 if (h || v) {
190 scrolled = true;
191 usb_mouse_send(0,0, -v/16, h/16, 0);
192 _delay_ms(100); 151 _delay_ms(100);
152 mouse_report.buttons &= ~(PS2_MOUSE_SCROLL_BTN_MASK);
193 } 153 }
194 } else if (!scrolled && (ps2_mouse_btn_prev & PS2_MOUSE_SCROLL_BUTTON)) { 154#endif
195 usb_mouse_send(0,0,0,0, PS2_MOUSE_SCROLL_BUTTON); 155 scroll_state = SCROLL_NONE;
196 _delay_ms(100);
197 usb_mouse_send(0,0,0,0, 0);
198 } else {
199 scrolled = false;
200 usb_mouse_send(x, y, 0, 0, ps2_mouse_btn & PS2_MOUSE_BTN_MASK);
201 } 156 }
157 // doesn't send Scroll Button
158 mouse_report.buttons &= ~(PS2_MOUSE_SCROLL_BTN_MASK);
159#endif
160
202 161
203 ps2_mouse_btn_prev = (ps2_mouse_btn & PS2_MOUSE_BTN_MASK); 162 host_mouse_send(&mouse_report);
204 ps2_mouse_print(); 163 print_usb_data();
205 } 164 }
206 ps2_mouse_x = 0; 165 // clear report
207 ps2_mouse_y = 0; 166 mouse_report.x = 0;
208 ps2_mouse_btn = 0; 167 mouse_report.y = 0;
168 mouse_report.v = 0;
169 mouse_report.h = 0;
170 mouse_report.buttons = 0;
209} 171}
210 172
211void ps2_mouse_print(void) 173static void print_usb_data(void)
212{ 174{
213 if (!debug_mouse) return; 175 if (!debug_mouse) return;
214 print("ps2_mouse[btn|x y]: "); 176 print("ps2_mouse usb: [");
215 phex(ps2_mouse_btn); print("|"); 177 phex(mouse_report.buttons); print("|");
216 phex(ps2_mouse_x); print(" "); 178 print_hex8((uint8_t)mouse_report.x); print(" ");
217 phex(ps2_mouse_y); print("\n"); 179 print_hex8((uint8_t)mouse_report.y); print(" ");
180 print_hex8((uint8_t)mouse_report.v); print(" ");
181 print_hex8((uint8_t)mouse_report.h); print("]\n");
218} 182}
183
184
185/* PS/2 Mouse Synopsis
186 * http://www.computer-engineering.org/ps2mouse/
187 *
188 * Command:
189 * 0xFF: Reset
190 * 0xF6: Set Defaults Sampling; rate=100, resolution=4cnt/mm, scaling=1:1, reporting=disabled
191 * 0xF5: Disable Data Reporting
192 * 0xF4: Enable Data Reporting
193 * 0xF3: Set Sample Rate
194 * 0xF2: Get Device ID
195 * 0xF0: Set Remote Mode
196 * 0xEB: Read Data
197 * 0xEA: Set Stream Mode
198 * 0xE9: Status Request
199 * 0xE8: Set Resolution
200 * 0xE7: Set Scaling 2:1
201 * 0xE6: Set Scaling 1:1
202 *
203 * Mode:
204 * Stream Mode: devices sends the data when it changs its state
205 * Remote Mode: host polls the data periodically
206 *
207 * This code uses Remote Mode and polls the data with Read Data(0xEB).
208 *
209 * Data format:
210 * byte|7 6 5 4 3 2 1 0
211 * ----+--------------------------------------------------------------
212 * 0|Yovflw Xovflw Ysign Xsign 1 Middle Right Left
213 * 1| X movement
214 * 2| Y movement
215 */
diff --git a/protocol/ps2_mouse.h b/protocol/ps2_mouse.h
index 4529ce113..27d9790d4 100644
--- a/protocol/ps2_mouse.h
+++ b/protocol/ps2_mouse.h
@@ -20,6 +20,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
20 20
21#include <stdbool.h> 21#include <stdbool.h>
22 22
23#define PS2_MOUSE_READ_DATA 0xEB
24
25/*
26 * Data format:
27 * byte|7 6 5 4 3 2 1 0
28 * ----+--------------------------------------------------------------
29 * 0|Yovflw Xovflw Ysign Xsign 1 Middle Right Left
30 * 1| X movement(0-255)
31 * 2| Y movement(0-255)
32 */
23#define PS2_MOUSE_BTN_MASK 0x07 33#define PS2_MOUSE_BTN_MASK 0x07
24#define PS2_MOUSE_BTN_LEFT 0 34#define PS2_MOUSE_BTN_LEFT 0
25#define PS2_MOUSE_BTN_RIGHT 1 35#define PS2_MOUSE_BTN_RIGHT 1
@@ -29,16 +39,28 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
29#define PS2_MOUSE_X_OVFLW 6 39#define PS2_MOUSE_X_OVFLW 6
30#define PS2_MOUSE_Y_OVFLW 7 40#define PS2_MOUSE_Y_OVFLW 7
31 41
32bool ps2_mouse_enable; 42
33extern uint8_t ps2_mouse_x; 43/*
34extern uint8_t ps2_mouse_y; 44 * Scroll by mouse move with pressing button
35extern uint8_t ps2_mouse_btn; 45 */
36extern uint8_t ps2_mouse_error_count; 46/* mouse button to start scrolling; set 0 to disable scroll */
47#ifndef PS2_MOUSE_SCROLL_BTN_MASK
48#define PS2_MOUSE_SCROLL_BTN_MASK (1<<PS2_MOUSE_BTN_MIDDLE)
49#endif
50/* send button event when button is released within this value(ms); set 0 to disable */
51#ifndef PS2_MOUSE_SCROLL_BTN_SEND
52#define PS2_MOUSE_SCROLL_BTN_SEND 300
53#endif
54/* divide virtical and horizontal mouse move by this to convert to scroll move */
55#ifndef PS2_MOUSE_SCROLL_DIVISOR_V
56#define PS2_MOUSE_SCROLL_DIVISOR_V 2
57#endif
58#ifndef PS2_MOUSE_SCROLL_DIVISOR_H
59#define PS2_MOUSE_SCROLL_DIVISOR_H 2
60#endif
61
37 62
38uint8_t ps2_mouse_init(void); 63uint8_t ps2_mouse_init(void);
39uint8_t ps2_mouse_read(void); 64void ps2_mouse_task(void);
40bool ps2_mouse_changed(void);
41void ps2_mouse_usb_send(void);
42void ps2_mouse_print(void);
43 65
44#endif 66#endif
diff --git a/protocol/ps2_usart.c b/protocol/ps2_usart.c
index 9ea6b7786..40c46c497 100644
--- a/protocol/ps2_usart.c
+++ b/protocol/ps2_usart.c
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2010,2011 Jun WAKO <wakojun@gmail.com> 2Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
3 3
4This software is licensed with a Modified BSD License. 4This software is licensed with a Modified BSD License.
5All of this is supposed to be Free Software, Open Source, DFSG-free, 5All of this is supposed to be Free Software, Open Source, DFSG-free,
@@ -64,14 +64,6 @@ http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
64#include "debug.h" 64#include "debug.h"
65 65
66 66
67#if 0
68#define DEBUGP_INIT() do { DDRC = 0xFF; } while (0)
69#define DEBUGP(x) do { PORTC = x; } while (0)
70#else
71#define DEBUGP_INIT()
72#define DEBUGP(x)
73#endif
74
75#define WAIT(stat, us, err) do { \ 67#define WAIT(stat, us, err) do { \
76 if (!wait_##stat(us)) { \ 68 if (!wait_##stat(us)) { \
77 ps2_error = err; \ 69 ps2_error = err; \
@@ -97,12 +89,12 @@ static inline void idle(void);
97static inline void inhibit(void); 89static inline void inhibit(void);
98static inline uint8_t pbuf_dequeue(void); 90static inline uint8_t pbuf_dequeue(void);
99static inline void pbuf_enqueue(uint8_t data); 91static inline void pbuf_enqueue(uint8_t data);
92static inline bool pbuf_has_data(void);
93static inline void pbuf_clear(void);
100 94
101 95
102void ps2_host_init(void) 96void ps2_host_init(void)
103{ 97{
104 DEBUGP_INIT();
105 DEBUGP(0x1);
106 idle(); 98 idle();
107 PS2_USART_INIT(); 99 PS2_USART_INIT();
108 PS2_USART_RX_INT_ON(); 100 PS2_USART_RX_INT_ON();
@@ -114,7 +106,6 @@ uint8_t ps2_host_send(uint8_t data)
114 bool parity = true; 106 bool parity = true;
115 ps2_error = PS2_ERR_NONE; 107 ps2_error = PS2_ERR_NONE;
116 108
117 DEBUGP(0x6);
118 PS2_USART_OFF(); 109 PS2_USART_OFF();
119 110
120 /* terminate a transmission if we have */ 111 /* terminate a transmission if we have */
@@ -153,6 +144,8 @@ uint8_t ps2_host_send(uint8_t data)
153 WAIT(clock_hi, 50, 8); 144 WAIT(clock_hi, 50, 8);
154 WAIT(data_hi, 50, 9); 145 WAIT(data_hi, 50, 9);
155 146
147 PS2_USART_INIT();
148 PS2_USART_RX_INT_ON();
156 res = ps2_host_recv_response(); 149 res = ps2_host_recv_response();
157ERROR: 150ERROR:
158 idle(); 151 idle();
@@ -164,15 +157,10 @@ ERROR:
164// Do polling data from keyboard to get response to last command. 157// Do polling data from keyboard to get response to last command.
165uint8_t ps2_host_recv_response(void) 158uint8_t ps2_host_recv_response(void)
166{ 159{
167 uint8_t data = 0; 160 while (!pbuf_has_data()) {
168 PS2_USART_INIT(); 161 _delay_ms(1); // without this delay it seems to fall into deadlock
169 PS2_USART_RX_POLL_ON(); 162 }
170 while (!PS2_USART_RX_READY) 163 return pbuf_dequeue();
171 ;
172 data = PS2_USART_RX_DATA;
173 PS2_USART_OFF();
174 DEBUGP(0x9);
175 return data;
176} 164}
177 165
178uint8_t ps2_host_recv(void) 166uint8_t ps2_host_recv(void)
@@ -182,15 +170,11 @@ uint8_t ps2_host_recv(void)
182 170
183ISR(PS2_USART_RX_VECT) 171ISR(PS2_USART_RX_VECT)
184{ 172{
185 DEBUGP(0x7);
186 uint8_t error = PS2_USART_ERROR; 173 uint8_t error = PS2_USART_ERROR;
187 uint8_t data = PS2_USART_RX_DATA; 174 uint8_t data = PS2_USART_RX_DATA;
188 if (error) { 175 if (!error) {
189 DEBUGP(error>>2);
190 } else {
191 pbuf_enqueue(data); 176 pbuf_enqueue(data);
192 } 177 }
193 DEBUGP(0x8);
194} 178}
195 179
196/* send LED state to keyboard */ 180/* send LED state to keyboard */
@@ -293,9 +277,6 @@ static uint8_t pbuf_head = 0;
293static uint8_t pbuf_tail = 0; 277static uint8_t pbuf_tail = 0;
294static inline void pbuf_enqueue(uint8_t data) 278static inline void pbuf_enqueue(uint8_t data)
295{ 279{
296 if (!data)
297 return;
298
299 uint8_t sreg = SREG; 280 uint8_t sreg = SREG;
300 cli(); 281 cli();
301 uint8_t next = (pbuf_head + 1) % PBUF_SIZE; 282 uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
@@ -322,3 +303,18 @@ static inline uint8_t pbuf_dequeue(void)
322 303
323 return val; 304 return val;
324} 305}
306static inline bool pbuf_has_data(void)
307{
308 uint8_t sreg = SREG;
309 cli();
310 bool has_data = (pbuf_head != pbuf_tail);
311 SREG = sreg;
312 return has_data;
313}
314static inline void pbuf_clear(void)
315{
316 uint8_t sreg = SREG;
317 cli();
318 pbuf_head = pbuf_tail = 0;
319 SREG = sreg;
320}