aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/action.c6
-rw-r--r--common/action.h1
-rw-r--r--common/host.c8
-rw-r--r--common/host.h6
-rw-r--r--common/keyboard.c4
-rw-r--r--common/mousekey.c1
-rw-r--r--protocol/ps2_mouse.c180
-rw-r--r--protocol/ps2_mouse.h21
8 files changed, 119 insertions, 108 deletions
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/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 63a58b218..2b66f20a0 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -123,9 +123,7 @@ MATRIX_LOOP_END:
123#endif 123#endif
124 124
125#ifdef PS2_MOUSE_ENABLE 125#ifdef PS2_MOUSE_ENABLE
126 if (ps2_mouse_read() == 0) { 126 ps2_mouse_task();
127 ps2_mouse_usb_send();
128 }
129#endif 127#endif
130 128
131 // update LED 129 // update LED
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/protocol/ps2_mouse.c b/protocol/ps2_mouse.c
index 5e0b3657c..ff730196c 100644
--- a/protocol/ps2_mouse.c
+++ b/protocol/ps2_mouse.c
@@ -20,7 +20,8 @@ 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"
24 25
25#define PS2_MOUSE_DEBUG 26#define PS2_MOUSE_DEBUG
26#ifdef PS2_MOUSE_DEBUG 27#ifdef PS2_MOUSE_DEBUG
@@ -33,20 +34,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
33#endif 34#endif
34 35
35 36
36bool ps2_mouse_enable = true; 37static report_mouse_t mouse_report = {};
37uint8_t ps2_mouse_x = 0;
38uint8_t ps2_mouse_y = 0;
39uint8_t ps2_mouse_btn = 0;
40uint8_t ps2_mouse_error_count = 0;
41 38
42static uint8_t ps2_mouse_btn_prev = 0;
43 39
40static void ps2_mouse_print_raw_data(void);
41static void ps2_mouse_print_usb_data(void);
44 42
43
44/* supports only 3 button mouse at this time */
45uint8_t ps2_mouse_init(void) { 45uint8_t ps2_mouse_init(void) {
46 uint8_t rcv; 46 uint8_t rcv;
47 47
48 if (!ps2_mouse_enable) return 1;
49
50 ps2_host_init(); 48 ps2_host_init();
51 49
52 _delay_ms(1000); // wait for powering up 50 _delay_ms(1000); // wait for powering up
@@ -79,85 +77,119 @@ uint8_t ps2_mouse_init(void) {
79 return 0; 77 return 0;
80} 78}
81 79
82uint8_t ps2_mouse_read(void) 80/* scroll support
81 * TODO: should be build option
82 */
83#define PS2_MOUSE_SCROLL_BUTTON 0x04
84#define X_IS_NEG (mouse_report.buttons & (1<<PS2_MOUSE_X_SIGN))
85#define Y_IS_NEG (mouse_report.buttons & (1<<PS2_MOUSE_Y_SIGN))
86#define X_IS_OVF (mouse_report.buttons & (1<<PS2_MOUSE_X_OVFLW))
87#define Y_IS_OVF (mouse_report.buttons & (1<<PS2_MOUSE_Y_OVFLW))
88void ps2_mouse_task(void)
83{ 89{
90 enum { SCROLL_NONE, SCROLL_BTN, SCROLL_SENT };
91 static uint8_t scroll_state = SCROLL_NONE;
92 static uint8_t buttons_prev = 0;
93
94 /* receives packet from mouse */
84 uint8_t rcv; 95 uint8_t rcv;
96 rcv = ps2_host_send(PS2_MOUSE_READ_DATA);
97 if (rcv == PS2_ACK) {
98 mouse_report.buttons = ps2_host_recv_response();
99 mouse_report.x = ps2_host_recv_response();
100 mouse_report.y = ps2_host_recv_response();
101 } else {
102 if (!debug_mouse) print("ps2_mouse: fail to get mouse packet\n");
103 return;
104 }
85 105
86 if (!ps2_mouse_enable) return 1; 106 /* if mouse moves or buttons state changes */
107 if (mouse_report.x || mouse_report.y ||
108 ((mouse_report.buttons ^ buttons_prev) & PS2_MOUSE_BTN_MASK)) {
87 109
88 rcv = ps2_host_send(0xEB); 110 ps2_mouse_print_raw_data();
89 111
90 if(rcv==0xFA) { 112 buttons_prev = mouse_report.buttons;
91 ps2_mouse_btn = ps2_host_recv_response();
92 ps2_mouse_x = ps2_host_recv_response();
93 ps2_mouse_y = ps2_host_recv_response();
94 }
95 return 0;
96}
97 113
98bool ps2_mouse_changed(void) 114 // PS/2 mouse data is '9-bit integer'(-256 to 255) which is comprised of sign-bit and 8-bit value.
99{ 115 // bit: 8 7 ... 0
100 return (ps2_mouse_x || ps2_mouse_y || (ps2_mouse_btn & PS2_MOUSE_BTN_MASK) != ps2_mouse_btn_prev); 116 // sign \8-bit/
101} 117 //
118 // Meanwhile USB HID mouse indicates 8bit data(-127 to 127), note that -128 is not used.
119 //
120 // This converts PS/2 data into HID value. Use only -127-127 out of PS/2 9-bit.
121 mouse_report.x = X_IS_NEG ?
122 ((!X_IS_OVF && -127 <= mouse_report.x && mouse_report.x <= -1) ? mouse_report.x : -127) :
123 ((!X_IS_OVF && 0 <= mouse_report.x && mouse_report.x <= 127) ? mouse_report.x : 127);
124 mouse_report.y = Y_IS_NEG ?
125 ((!Y_IS_OVF && -127 <= mouse_report.y && mouse_report.y <= -1) ? mouse_report.y : -127) :
126 ((!Y_IS_OVF && 0 <= mouse_report.y && mouse_report.y <= 127) ? mouse_report.y : 127);
102 127
103#define PS2_MOUSE_SCROLL_BUTTON 0x04 128 // remove sign and overflow flags
104void ps2_mouse_usb_send(void) 129 mouse_report.buttons &= PS2_MOUSE_BTN_MASK;
105{ 130
106 static bool scrolled = false; 131 // invert coordinate of y to conform to USB HID mouse
107 132 mouse_report.y = -mouse_report.y;
108 if (!ps2_mouse_enable) return; 133
109 134
110 if (ps2_mouse_changed()) { 135 if ((mouse_report.buttons & PS2_MOUSE_SCROLL_BUTTON) == PS2_MOUSE_SCROLL_BUTTON) {
111 int8_t x, y, v, h; 136 if (scroll_state == SCROLL_NONE) scroll_state = SCROLL_BTN;
112 x = y = v = h = 0; 137
113 138 // doesn't send Scroll Button
114 // convert scale of X, Y: PS/2(-256/255) -> USB(-127/127) 139 mouse_report.buttons &= ~PS2_MOUSE_SCROLL_BUTTON;
115 if (ps2_mouse_btn & (1<<PS2_MOUSE_X_SIGN)) 140
116 x = ps2_mouse_x > 128 ? (int8_t)ps2_mouse_x : -127; 141 if (mouse_report.x || mouse_report.y) {
117 else 142 scroll_state = SCROLL_SENT;
118 x = ps2_mouse_x < 128 ? (int8_t)ps2_mouse_x : 127; 143
119 144 mouse_report.v = -mouse_report.y/2;
120 if (ps2_mouse_btn & (1<<PS2_MOUSE_Y_SIGN)) 145 mouse_report.h = mouse_report.x/2;
121 y = ps2_mouse_y > 128 ? (int8_t)ps2_mouse_y : -127; 146 mouse_report.x = 0;
122 else 147 mouse_report.y = 0;
123 y = ps2_mouse_y < 128 ? (int8_t)ps2_mouse_y : 127; 148 host_mouse_send(&mouse_report);
124
125 // Y is needed to reverse
126 y = -y;
127
128 if (ps2_mouse_btn & PS2_MOUSE_SCROLL_BUTTON) {
129 // scroll
130 if (x > 0 || x < 0) h = (x > 64 ? 64 : (x < -64 ? -64 :x));
131 if (y > 0 || y < 0) v = (y > 64 ? 64 : (y < -64 ? -64 :y));
132 if (h || v) {
133 scrolled = true;
134 usb_mouse_send(0,0, -v/16, h/16, 0);
135 _delay_ms(100);
136 } 149 }
137 } else if (!scrolled && (ps2_mouse_btn_prev & PS2_MOUSE_SCROLL_BUTTON)) { 150 } else if (scroll_state == SCROLL_BTN &&
138 usb_mouse_send(0,0,0,0, PS2_MOUSE_SCROLL_BUTTON); 151 (mouse_report.buttons & PS2_MOUSE_SCROLL_BUTTON) == 0) {
152 scroll_state = SCROLL_NONE;
153
154 // send Scroll Button(down and up at once) when not scrolled
155 mouse_report.buttons |= PS2_MOUSE_SCROLL_BUTTON;
156 host_mouse_send(&mouse_report);
139 _delay_ms(100); 157 _delay_ms(100);
140 usb_mouse_send(0,0,0,0, 0); 158 mouse_report.buttons &= ~PS2_MOUSE_SCROLL_BUTTON;
159 host_mouse_send(&mouse_report);
141 } else { 160 } else {
142 scrolled = false; 161 scroll_state = SCROLL_NONE;
143 usb_mouse_send(x, y, 0, 0, ps2_mouse_btn & PS2_MOUSE_BTN_MASK);
144 }
145 162
146 ps2_mouse_btn_prev = (ps2_mouse_btn & PS2_MOUSE_BTN_MASK); 163 host_mouse_send(&mouse_report);
147 ps2_mouse_print(); 164 }
165 ps2_mouse_print_usb_data();
148 } 166 }
149 ps2_mouse_x = 0; 167 // clear report
150 ps2_mouse_y = 0; 168 mouse_report.x = 0;
151 ps2_mouse_btn = 0; 169 mouse_report.y = 0;
170 mouse_report.v = 0;
171 mouse_report.h = 0;
172 mouse_report.buttons = 0;
173}
174
175static void ps2_mouse_print_raw_data(void)
176{
177 if (!debug_mouse) return;
178 print("ps2_mouse raw [btn|x y]: [");
179 phex(mouse_report.buttons); print("|");
180 print_hex8((uint8_t)mouse_report.x); print(" ");
181 print_hex8((uint8_t)mouse_report.y); print("]\n");
152} 182}
153 183
154void ps2_mouse_print(void) 184static void ps2_mouse_print_usb_data(void)
155{ 185{
156 if (!debug_mouse) return; 186 if (!debug_mouse) return;
157 print("ps2_mouse[btn|x y]: "); 187 print("ps2_mouse usb [btn|x y v h]: [");
158 phex(ps2_mouse_btn); print("|"); 188 phex(mouse_report.buttons); print("|");
159 phex(ps2_mouse_x); print(" "); 189 print_hex8((uint8_t)mouse_report.x); print(" ");
160 phex(ps2_mouse_y); print("\n"); 190 print_hex8((uint8_t)mouse_report.y); print(" ");
191 print_hex8((uint8_t)mouse_report.v); print(" ");
192 print_hex8((uint8_t)mouse_report.h); print("]\n");
161} 193}
162 194
163 195
@@ -189,6 +221,6 @@ void ps2_mouse_print(void)
189 * byte|7 6 5 4 3 2 1 0 221 * byte|7 6 5 4 3 2 1 0
190 * ----+-------------------------------------------------------------- 222 * ----+--------------------------------------------------------------
191 * 0|Yovflw Xovflw Ysign Xsign 1 Middle Right Left 223 * 0|Yovflw Xovflw Ysign Xsign 1 Middle Right Left
192 * 1| X movement(0-255) 224 * 1| X movement
193 * 2| Y movement(0-255) 225 * 2| Y movement
194 */ 226 */
diff --git a/protocol/ps2_mouse.h b/protocol/ps2_mouse.h
index 4529ce113..305a9bdba 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,7 @@ 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;
33extern uint8_t ps2_mouse_x;
34extern uint8_t ps2_mouse_y;
35extern uint8_t ps2_mouse_btn;
36extern uint8_t ps2_mouse_error_count;
37
38uint8_t ps2_mouse_init(void); 42uint8_t ps2_mouse_init(void);
39uint8_t ps2_mouse_read(void); 43void ps2_mouse_task(void);
40bool ps2_mouse_changed(void);
41void ps2_mouse_usb_send(void);
42void ps2_mouse_print(void);
43 44
44#endif 45#endif