aboutsummaryrefslogtreecommitdiff
path: root/protocol
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2013-11-20 11:19:59 +0900
committertmk <nobody@nowhere>2013-11-20 11:32:09 +0900
commitd7f663a1ea4487a6dc5be76085eff7b00bec9704 (patch)
tree8bbec9b81d8154aebb765b9734a7ce6abc47b832 /protocol
parent755e4d8b00a4f9be0c50c2b005d063b94c528f8c (diff)
downloadqmk_firmware-d7f663a1ea4487a6dc5be76085eff7b00bec9704.tar.gz
qmk_firmware-d7f663a1ea4487a6dc5be76085eff7b00bec9704.zip
Fix to build ps2_mouse with both LUFA and PJRC
- change API of ps2_mouse; ps2_mouse_task() - remove mouse_report from host.c
Diffstat (limited to 'protocol')
-rw-r--r--protocol/ps2_mouse.c180
-rw-r--r--protocol/ps2_mouse.h21
2 files changed, 117 insertions, 84 deletions
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