diff options
author | ofples <plesserofer@gmail.com> | 2016-12-03 13:05:02 +0200 |
---|---|---|
committer | ofples <plesserofer@gmail.com> | 2016-12-03 13:05:02 +0200 |
commit | d639e08a3131892c608760df4e3806d843a91176 (patch) | |
tree | d92c97122506de3b9bf46817a2e31fc94f48c360 | |
parent | 7f88c9506c1fbfb7de1ee51e0611eb8c46bee7f7 (diff) | |
download | qmk_firmware-d639e08a3131892c608760df4e3806d843a91176.tar.gz qmk_firmware-d639e08a3131892c608760df4e3806d843a91176.zip |
Refactored and improved ps2 mouse feature
-rw-r--r-- | tmk_core/protocol/ps2_mouse.c | 369 | ||||
-rw-r--r-- | tmk_core/protocol/ps2_mouse.h | 81 |
2 files changed, 286 insertions, 164 deletions
diff --git a/tmk_core/protocol/ps2_mouse.c b/tmk_core/protocol/ps2_mouse.c index 82f6966e8..f247ba8dc 100644 --- a/tmk_core/protocol/ps2_mouse.c +++ b/tmk_core/protocol/ps2_mouse.c | |||
@@ -18,63 +18,99 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
18 | #include <stdbool.h> | 18 | #include <stdbool.h> |
19 | #include<avr/io.h> | 19 | #include<avr/io.h> |
20 | #include<util/delay.h> | 20 | #include<util/delay.h> |
21 | #include "ps2.h" | ||
22 | #include "ps2_mouse.h" | 21 | #include "ps2_mouse.h" |
23 | #include "report.h" | ||
24 | #include "host.h" | 22 | #include "host.h" |
25 | #include "timer.h" | 23 | #include "timer.h" |
26 | #include "print.h" | 24 | #include "print.h" |
25 | #include "report.h" | ||
27 | #include "debug.h" | 26 | #include "debug.h" |
27 | #include "ps2.h" | ||
28 | 28 | ||
29 | #ifndef PS2_INIT_DELAY | 29 | /* ============================= MACROS ============================ */ |
30 | #define PS2_INIT_DELAY 1000 | 30 | |
31 | #endif | 31 | #define PS2_MOUSE_SEND(command, message) \ |
32 | do { \ | ||
33 | uint8_t rcv = ps2_host_send(command); \ | ||
34 | if (debug_mouse) { \ | ||
35 | print((message)); \ | ||
36 | xprintf(" command: %X, result: %X, error: %X \n", command, rcv, ps2_error); \ | ||
37 | } \ | ||
38 | } while(0) | ||
39 | |||
40 | #define PS2_MOUSE_SEND_SAFE(command, message) \ | ||
41 | do { \ | ||
42 | if (PS2_MOUSE_STREAM_MODE == ps2_mouse_mode) { \ | ||
43 | ps2_mouse_disable_data_reporting(); \ | ||
44 | } \ | ||
45 | PS2_MOUSE_SEND(command, message); \ | ||
46 | if (PS2_MOUSE_STREAM_MODE == ps2_mouse_mode) { \ | ||
47 | ps2_mouse_enable_data_reporting(); \ | ||
48 | } \ | ||
49 | } while(0) | ||
50 | |||
51 | #define PS2_MOUSE_SET_SAFE(command, value, message) \ | ||
52 | do { \ | ||
53 | if (PS2_MOUSE_STREAM_MODE == ps2_mouse_mode) { \ | ||
54 | ps2_mouse_disable_data_reporting(); \ | ||
55 | } \ | ||
56 | PS2_MOUSE_SEND(command, message); \ | ||
57 | PS2_MOUSE_SEND(value, "Sending value"); \ | ||
58 | if (PS2_MOUSE_STREAM_MODE == ps2_mouse_mode) { \ | ||
59 | ps2_mouse_enable_data_reporting(); \ | ||
60 | } \ | ||
61 | } while(0) | ||
62 | |||
63 | #define PS2_MOUSE_RECEIVE(message) \ | ||
64 | do { \ | ||
65 | uint8_t rcv = ps2_host_recv_response(); \ | ||
66 | if (debug_mouse) { \ | ||
67 | print((message)); \ | ||
68 | xprintf(" result: %X, error: %X \n", rcv, ps2_error); \ | ||
69 | } \ | ||
70 | } while(0) | ||
71 | |||
72 | static enum ps2_mouse_mode_e { | ||
73 | PS2_MOUSE_STREAM_MODE, | ||
74 | PS2_MOUSE_REMOTE_MODE, | ||
75 | } ps2_mouse_mode = PS2_MOUSE_STREAM_MODE; | ||
32 | 76 | ||
33 | static report_mouse_t mouse_report = {}; | 77 | static report_mouse_t mouse_report = {}; |
34 | 78 | ||
79 | static inline void ps2_mouse_print_report(report_mouse_t *mouse_report); | ||
80 | static inline void ps2_mouse_convert_report_to_hid(report_mouse_t *mouse_report); | ||
81 | static inline void ps2_mouse_clear_report(report_mouse_t *mouse_report); | ||
82 | static inline void ps2_mouse_enable_scrolling(void); | ||
83 | static inline void ps2_mouse_scroll_button_task(report_mouse_t *mouse_report); | ||
35 | 84 | ||
36 | static void print_usb_data(void); | 85 | /* ============================= IMPLEMENTATION ============================ */ |
37 | |||
38 | 86 | ||
39 | /* supports only 3 button mouse at this time */ | 87 | /* supports only 3 button mouse at this time */ |
40 | uint8_t ps2_mouse_init(void) { | 88 | void ps2_mouse_init(void) { |
41 | uint8_t rcv; | ||
42 | |||
43 | ps2_host_init(); | 89 | ps2_host_init(); |
44 | 90 | ||
45 | _delay_ms(PS2_INIT_DELAY); // wait for powering up | 91 | _delay_ms(1000); // wait for powering up |
46 | 92 | ||
47 | // send Reset | 93 | PS2_MOUSE_SEND(PS2_MOUSE_RESET, "ps2_mouse_init: sending reset"); |
48 | rcv = ps2_host_send(0xFF); | ||
49 | print("ps2_mouse_init: send Reset: "); | ||
50 | phex(rcv); phex(ps2_error); print("\n"); | ||
51 | 94 | ||
52 | // read completion code of BAT | 95 | PS2_MOUSE_RECEIVE("ps2_mouse_init: read BAT"); |
53 | rcv = ps2_host_recv_response(); | 96 | PS2_MOUSE_RECEIVE("ps2_mouse_init: read DevID"); |
54 | print("ps2_mouse_init: read BAT: "); | ||
55 | phex(rcv); phex(ps2_error); print("\n"); | ||
56 | 97 | ||
57 | // read Device ID | 98 | #ifdef PS2_MOUSE_USE_REMOTE_MODE |
58 | rcv = ps2_host_recv_response(); | 99 | ps2_mouse_set_remote_mode(); |
59 | print("ps2_mouse_init: read DevID: "); | 100 | #else |
60 | phex(rcv); phex(ps2_error); print("\n"); | 101 | ps2_mouse_enable_data_reporting(); |
102 | #endif | ||
61 | 103 | ||
62 | // send Set Remote mode | 104 | #ifdef PS2_MOUSE_ENABLE_SCROLLING |
63 | rcv = ps2_host_send(0xF0); | 105 | ps2_mouse_enable_scrolling(); |
64 | print("ps2_mouse_init: send 0xF0: "); | 106 | #endif |
65 | phex(rcv); phex(ps2_error); print("\n"); | ||
66 | 107 | ||
67 | return 0; | 108 | #ifdef PS2_MOUSE_USE_2_1_SCALING |
109 | ps2_mouse_set_scaling_2_1(); | ||
110 | #endif | ||
68 | } | 111 | } |
69 | 112 | ||
70 | #define X_IS_NEG (mouse_report.buttons & (1<<PS2_MOUSE_X_SIGN)) | 113 | void ps2_mouse_task(void) { |
71 | #define Y_IS_NEG (mouse_report.buttons & (1<<PS2_MOUSE_Y_SIGN)) | ||
72 | #define X_IS_OVF (mouse_report.buttons & (1<<PS2_MOUSE_X_OVFLW)) | ||
73 | #define Y_IS_OVF (mouse_report.buttons & (1<<PS2_MOUSE_Y_OVFLW)) | ||
74 | void ps2_mouse_task(void) | ||
75 | { | ||
76 | enum { SCROLL_NONE, SCROLL_BTN, SCROLL_SENT }; | ||
77 | static uint8_t scroll_state = SCROLL_NONE; | ||
78 | static uint8_t buttons_prev = 0; | 114 | static uint8_t buttons_prev = 0; |
79 | 115 | ||
80 | /* receives packet from mouse */ | 116 | /* receives packet from mouse */ |
@@ -82,142 +118,169 @@ void ps2_mouse_task(void) | |||
82 | rcv = ps2_host_send(PS2_MOUSE_READ_DATA); | 118 | rcv = ps2_host_send(PS2_MOUSE_READ_DATA); |
83 | if (rcv == PS2_ACK) { | 119 | if (rcv == PS2_ACK) { |
84 | mouse_report.buttons = ps2_host_recv_response(); | 120 | mouse_report.buttons = ps2_host_recv_response(); |
85 | mouse_report.x = ps2_host_recv_response(); | 121 | mouse_report.x = ps2_host_recv_response() * PS2_MOUSE_X_MULTIPLIER; |
86 | mouse_report.y = ps2_host_recv_response(); | 122 | mouse_report.y = ps2_host_recv_response() * PS2_MOUSE_Y_MULTIPLIER; |
123 | #ifdef PS2_MOUSE_ENABLE_SCROLLING | ||
124 | mouse_report.v = -(ps2_host_recv_response() & PS2_MOUSE_SCROLL_MASK) * PS2_MOUSE_V_MULTIPLIER; | ||
125 | #endif | ||
87 | } else { | 126 | } else { |
88 | if (debug_mouse) print("ps2_mouse: fail to get mouse packet\n"); | 127 | if (debug_mouse) print("ps2_mouse: fail to get mouse packet\n"); |
89 | return; | 128 | return; |
90 | } | 129 | } |
91 | xprintf("%ud ", timer_read()); | ||
92 | print("ps2_mouse raw: ["); | ||
93 | phex(mouse_report.buttons); print("|"); | ||
94 | print_hex8((uint8_t)mouse_report.x); print(" "); | ||
95 | print_hex8((uint8_t)mouse_report.y); print("]\n"); | ||
96 | 130 | ||
97 | /* if mouse moves or buttons state changes */ | 131 | /* if mouse moves or buttons state changes */ |
98 | if (mouse_report.x || mouse_report.y || | 132 | if (mouse_report.x || mouse_report.y || mouse_report.v || |
99 | ((mouse_report.buttons ^ buttons_prev) & PS2_MOUSE_BTN_MASK)) { | 133 | ((mouse_report.buttons ^ buttons_prev) & PS2_MOUSE_BTN_MASK)) { |
100 | 134 | #ifdef PS2_MOUSE_DEBUG_RAW | |
101 | #ifdef PS2_MOUSE_DEBUG | 135 | // Used to debug raw ps2 bytes from mouse |
102 | print("ps2_mouse raw: ["); | 136 | ps2_mouse_print_report(&mouse_report); |
103 | phex(mouse_report.buttons); print("|"); | ||
104 | print_hex8((uint8_t)mouse_report.x); print(" "); | ||
105 | print_hex8((uint8_t)mouse_report.y); print("]\n"); | ||
106 | #endif | 137 | #endif |
107 | |||
108 | buttons_prev = mouse_report.buttons; | 138 | buttons_prev = mouse_report.buttons; |
139 | ps2_mouse_convert_report_to_hid(&mouse_report); | ||
140 | #if PS2_MOUSE_SCROLL_BTN_MASK | ||
141 | ps2_mouse_scroll_button_task(&mouse_report); | ||
142 | #endif | ||
143 | #ifdef PS2_MOUSE_DEBUG_HID | ||
144 | // Used to debug the bytes sent to the host | ||
145 | ps2_mouse_print_report(&mouse_report); | ||
146 | #endif | ||
147 | host_mouse_send(&mouse_report); | ||
148 | } | ||
149 | |||
150 | ps2_mouse_clear_report(&mouse_report); | ||
151 | } | ||
109 | 152 | ||
110 | // PS/2 mouse data is '9-bit integer'(-256 to 255) which is comprised of sign-bit and 8-bit value. | 153 | void ps2_mouse_disable_data_reporting(void) { |
111 | // bit: 8 7 ... 0 | 154 | PS2_MOUSE_SEND(PS2_MOUSE_DISABLE_DATA_REPORTING, "ps2 mouse disable data reporting"); |
112 | // sign \8-bit/ | 155 | } |
113 | // | ||
114 | // Meanwhile USB HID mouse indicates 8bit data(-127 to 127), note that -128 is not used. | ||
115 | // | ||
116 | // This converts PS/2 data into HID value. Use only -127-127 out of PS/2 9-bit. | ||
117 | mouse_report.x = X_IS_NEG ? | ||
118 | ((!X_IS_OVF && -127 <= mouse_report.x && mouse_report.x <= -1) ? mouse_report.x : -127) : | ||
119 | ((!X_IS_OVF && 0 <= mouse_report.x && mouse_report.x <= 127) ? mouse_report.x : 127); | ||
120 | mouse_report.y = Y_IS_NEG ? | ||
121 | ((!Y_IS_OVF && -127 <= mouse_report.y && mouse_report.y <= -1) ? mouse_report.y : -127) : | ||
122 | ((!Y_IS_OVF && 0 <= mouse_report.y && mouse_report.y <= 127) ? mouse_report.y : 127); | ||
123 | 156 | ||
124 | // remove sign and overflow flags | 157 | void ps2_mouse_enable_data_reporting(void) { |
125 | mouse_report.buttons &= PS2_MOUSE_BTN_MASK; | 158 | PS2_MOUSE_SEND(PS2_MOUSE_ENABLE_DATA_REPORTING, "ps2 mouse enable data reporting"); |
159 | } | ||
126 | 160 | ||
127 | // invert coordinate of y to conform to USB HID mouse | 161 | void ps2_mouse_set_remote_mode(void) { |
128 | mouse_report.y = -mouse_report.y; | 162 | PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_REMOTE_MODE, "ps2 mouse set remote mode"); |
163 | ps2_mouse_mode = PS2_MOUSE_REMOTE_MODE; | ||
164 | } | ||
129 | 165 | ||
166 | void ps2_mouse_set_stream_mode(void) { | ||
167 | PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_STREAM_MODE, "ps2 mouse set stream mode"); | ||
168 | ps2_mouse_mode = PS2_MOUSE_STREAM_MODE; | ||
169 | } | ||
130 | 170 | ||
131 | #if PS2_MOUSE_SCROLL_BTN_MASK | 171 | void ps2_mouse_set_scaling_2_1(void) { |
132 | static uint16_t scroll_button_time = 0; | 172 | PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_SCALING_2_1, "ps2 mouse set scaling 2:1"); |
133 | if ((mouse_report.buttons & (PS2_MOUSE_SCROLL_BTN_MASK)) == (PS2_MOUSE_SCROLL_BTN_MASK)) { | 173 | } |
134 | if (scroll_state == SCROLL_NONE) { | ||
135 | scroll_button_time = timer_read(); | ||
136 | scroll_state = SCROLL_BTN; | ||
137 | } | ||
138 | |||
139 | // doesn't send Scroll Button | ||
140 | //mouse_report.buttons &= ~(PS2_MOUSE_SCROLL_BTN_MASK); | ||
141 | |||
142 | if (mouse_report.x || mouse_report.y) { | ||
143 | scroll_state = SCROLL_SENT; | ||
144 | |||
145 | mouse_report.v = -mouse_report.y/(PS2_MOUSE_SCROLL_DIVISOR_V); | ||
146 | mouse_report.h = mouse_report.x/(PS2_MOUSE_SCROLL_DIVISOR_H); | ||
147 | mouse_report.x = 0; | ||
148 | mouse_report.y = 0; | ||
149 | //host_mouse_send(&mouse_report); | ||
150 | } | ||
151 | } | ||
152 | else if ((mouse_report.buttons & (PS2_MOUSE_SCROLL_BTN_MASK)) == 0) { | ||
153 | #if PS2_MOUSE_SCROLL_BTN_SEND | ||
154 | if (scroll_state == SCROLL_BTN && | ||
155 | TIMER_DIFF_16(timer_read(), scroll_button_time) < PS2_MOUSE_SCROLL_BTN_SEND) { | ||
156 | // send Scroll Button(down and up at once) when not scrolled | ||
157 | mouse_report.buttons |= (PS2_MOUSE_SCROLL_BTN_MASK); | ||
158 | host_mouse_send(&mouse_report); | ||
159 | _delay_ms(100); | ||
160 | mouse_report.buttons &= ~(PS2_MOUSE_SCROLL_BTN_MASK); | ||
161 | } | ||
162 | #endif | ||
163 | scroll_state = SCROLL_NONE; | ||
164 | } | ||
165 | // doesn't send Scroll Button | ||
166 | mouse_report.buttons &= ~(PS2_MOUSE_SCROLL_BTN_MASK); | ||
167 | #endif | ||
168 | 174 | ||
175 | void ps2_mouse_set_scaling_1_1(void) { | ||
176 | PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_SCALING_1_1, "ps2 mouse set scaling 1:1"); | ||
177 | } | ||
169 | 178 | ||
170 | host_mouse_send(&mouse_report); | 179 | void ps2_mouse_set_resolution(ps2_mouse_resolution_t resolution) { |
171 | print_usb_data(); | 180 | PS2_MOUSE_SET_SAFE(PS2_MOUSE_SET_RESOLUTION, resolution, "ps2 mouse set resolution"); |
172 | } | 181 | } |
173 | // clear report | 182 | |
174 | mouse_report.x = 0; | 183 | void ps2_mouse_set_sample_rate(ps2_mouse_sample_rate_t sample_rate) { |
175 | mouse_report.y = 0; | 184 | PS2_MOUSE_SET_SAFE(PS2_MOUSE_SET_SAMPLE_RATE, sample_rate, "ps2 mouse set sample rate"); |
176 | mouse_report.v = 0; | 185 | } |
177 | mouse_report.h = 0; | 186 | |
178 | mouse_report.buttons = 0; | 187 | /* ============================= HELPERS ============================ */ |
188 | |||
189 | #define X_IS_NEG (mouse_report->buttons & (1<<PS2_MOUSE_X_SIGN)) | ||
190 | #define Y_IS_NEG (mouse_report->buttons & (1<<PS2_MOUSE_Y_SIGN)) | ||
191 | #define X_IS_OVF (mouse_report->buttons & (1<<PS2_MOUSE_X_OVFLW)) | ||
192 | #define Y_IS_OVF (mouse_report->buttons & (1<<PS2_MOUSE_Y_OVFLW)) | ||
193 | static inline void ps2_mouse_convert_report_to_hid(report_mouse_t *mouse_report) { | ||
194 | // PS/2 mouse data is '9-bit integer'(-256 to 255) which is comprised of sign-bit and 8-bit value. | ||
195 | // bit: 8 7 ... 0 | ||
196 | // sign \8-bit/ | ||
197 | // | ||
198 | // Meanwhile USB HID mouse indicates 8bit data(-127 to 127), note that -128 is not used. | ||
199 | // | ||
200 | // This converts PS/2 data into HID value. Use only -127-127 out of PS/2 9-bit. | ||
201 | mouse_report->x = X_IS_NEG ? | ||
202 | ((!X_IS_OVF && -127 <= mouse_report->x && mouse_report->x <= -1) ? mouse_report->x : -127) : | ||
203 | ((!X_IS_OVF && 0 <= mouse_report->x && mouse_report->x <= 127) ? mouse_report->x : 127); | ||
204 | mouse_report->y = Y_IS_NEG ? | ||
205 | ((!Y_IS_OVF && -127 <= mouse_report->y && mouse_report->y <= -1) ? mouse_report->y : -127) : | ||
206 | ((!Y_IS_OVF && 0 <= mouse_report->y && mouse_report->y <= 127) ? mouse_report->y : 127); | ||
207 | |||
208 | // remove sign and overflow flags | ||
209 | mouse_report->buttons &= PS2_MOUSE_BTN_MASK; | ||
210 | |||
211 | // invert coordinate of y to conform to USB HID mouse | ||
212 | mouse_report->y = -mouse_report->y; | ||
179 | } | 213 | } |
180 | 214 | ||
181 | static void print_usb_data(void) | 215 | static inline void ps2_mouse_clear_report(report_mouse_t *mouse_report) { |
182 | { | 216 | mouse_report->x = 0; |
217 | mouse_report->y = 0; | ||
218 | mouse_report->v = 0; | ||
219 | mouse_report->h = 0; | ||
220 | mouse_report->buttons = 0; | ||
221 | } | ||
222 | |||
223 | static inline void ps2_mouse_print_report(report_mouse_t *mouse_report) { | ||
183 | if (!debug_mouse) return; | 224 | if (!debug_mouse) return; |
184 | print("ps2_mouse usb: ["); | 225 | print("ps2_mouse: ["); |
185 | phex(mouse_report.buttons); print("|"); | 226 | phex(mouse_report->buttons); print("|"); |
186 | print_hex8((uint8_t)mouse_report.x); print(" "); | 227 | print_hex8((uint8_t)mouse_report->x); print(" "); |
187 | print_hex8((uint8_t)mouse_report.y); print(" "); | 228 | print_hex8((uint8_t)mouse_report->y); print(" "); |
188 | print_hex8((uint8_t)mouse_report.v); print(" "); | 229 | print_hex8((uint8_t)mouse_report->v); print(" "); |
189 | print_hex8((uint8_t)mouse_report.h); print("]\n"); | 230 | print_hex8((uint8_t)mouse_report->h); print("]\n"); |
231 | } | ||
232 | |||
233 | static inline void ps2_mouse_enable_scrolling(void) { | ||
234 | PS2_MOUSE_SEND(PS2_MOUSE_SET_SAMPLE_RATE, "Initiaing scroll wheel enable: Set sample rate"); | ||
235 | PS2_MOUSE_SEND(200, "200"); | ||
236 | PS2_MOUSE_SEND(PS2_MOUSE_SET_SAMPLE_RATE, "Set sample rate"); | ||
237 | PS2_MOUSE_SEND(100, "100"); | ||
238 | PS2_MOUSE_SEND(PS2_MOUSE_SET_SAMPLE_RATE, "Set sample rate"); | ||
239 | PS2_MOUSE_SEND(80, "80"); | ||
240 | PS2_MOUSE_SEND(PS2_MOUSE_GET_DEVICE_ID, "Finished enabling scroll wheel"); | ||
241 | _delay_ms(20); | ||
190 | } | 242 | } |
191 | 243 | ||
244 | #define PRESS_SCROLL_BUTTONS mouse_report->buttons |= (PS2_MOUSE_SCROLL_BTN_MASK) | ||
245 | #define RELEASE_SCROLL_BUTTONS mouse_report->buttons &= ~(PS2_MOUSE_SCROLL_BTN_MASK) | ||
246 | static inline void ps2_mouse_scroll_button_task(report_mouse_t *mouse_report) { | ||
247 | static enum { | ||
248 | SCROLL_NONE, | ||
249 | SCROLL_BTN, | ||
250 | SCROLL_SENT, | ||
251 | } scroll_state = SCROLL_NONE; | ||
252 | static uint16_t scroll_button_time = 0; | ||
253 | |||
254 | if (PS2_MOUSE_SCROLL_BTN_MASK == (mouse_report->buttons & (PS2_MOUSE_SCROLL_BTN_MASK))) { | ||
255 | // All scroll buttons are pressed | ||
256 | |||
257 | if (scroll_state == SCROLL_NONE) { | ||
258 | scroll_button_time = timer_read(); | ||
259 | scroll_state = SCROLL_BTN; | ||
260 | } | ||
261 | |||
262 | // If the mouse has moved, update the report to scroll instead of move the mouse | ||
263 | if (mouse_report->x || mouse_report->y) { | ||
264 | scroll_state = SCROLL_SENT; | ||
265 | mouse_report->v = -mouse_report->y/(PS2_MOUSE_SCROLL_DIVISOR_V); | ||
266 | mouse_report->h = mouse_report->x/(PS2_MOUSE_SCROLL_DIVISOR_H); | ||
267 | mouse_report->x = 0; | ||
268 | mouse_report->y = 0; | ||
269 | } | ||
270 | } else if (0 == (PS2_MOUSE_SCROLL_BTN_MASK & mouse_report->buttons)) { | ||
271 | // None of the scroll buttons are pressed | ||
272 | |||
273 | #if PS2_MOUSE_SCROLL_BTN_SEND | ||
274 | if (scroll_state == SCROLL_BTN | ||
275 | && timer_elapsed(scroll_button_time) < PS2_MOUSE_SCROLL_BTN_SEND) { | ||
276 | PRESS_SCROLL_BUTTONS; | ||
277 | host_mouse_send(mouse_report); | ||
278 | _delay_ms(100); | ||
279 | RELEASE_SCROLL_BUTTONS; | ||
280 | } | ||
281 | #endif | ||
282 | scroll_state = SCROLL_NONE; | ||
283 | } | ||
192 | 284 | ||
193 | /* PS/2 Mouse Synopsis | 285 | RELEASE_SCROLL_BUTTONS; |
194 | * http://www.computer-engineering.org/ps2mouse/ | 286 | } \ No newline at end of file |
195 | * | ||
196 | * Command: | ||
197 | * 0xFF: Reset | ||
198 | * 0xF6: Set Defaults Sampling; rate=100, resolution=4cnt/mm, scaling=1:1, reporting=disabled | ||
199 | * 0xF5: Disable Data Reporting | ||
200 | * 0xF4: Enable Data Reporting | ||
201 | * 0xF3: Set Sample Rate | ||
202 | * 0xF2: Get Device ID | ||
203 | * 0xF0: Set Remote Mode | ||
204 | * 0xEB: Read Data | ||
205 | * 0xEA: Set Stream Mode | ||
206 | * 0xE9: Status Request | ||
207 | * 0xE8: Set Resolution | ||
208 | * 0xE7: Set Scaling 2:1 | ||
209 | * 0xE6: Set Scaling 1:1 | ||
210 | * | ||
211 | * Mode: | ||
212 | * Stream Mode: devices sends the data when it changs its state | ||
213 | * Remote Mode: host polls the data periodically | ||
214 | * | ||
215 | * This code uses Remote Mode and polls the data with Read Data(0xEB). | ||
216 | * | ||
217 | * Data format: | ||
218 | * byte|7 6 5 4 3 2 1 0 | ||
219 | * ----+-------------------------------------------------------------- | ||
220 | * 0|Yovflw Xovflw Ysign Xsign 1 Middle Right Left | ||
221 | * 1| X movement | ||
222 | * 2| Y movement | ||
223 | */ | ||
diff --git a/tmk_core/protocol/ps2_mouse.h b/tmk_core/protocol/ps2_mouse.h index 27d9790d4..3b498059d 100644 --- a/tmk_core/protocol/ps2_mouse.h +++ b/tmk_core/protocol/ps2_mouse.h | |||
@@ -20,15 +20,13 @@ 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 | /* | 23 | /* |
26 | * Data format: | 24 | * Data format: |
27 | * byte|7 6 5 4 3 2 1 0 | 25 | * byte|7 6 5 4 3 2 1 0 |
28 | * ----+-------------------------------------------------------------- | 26 | * ----+---------------------------------------------------------------- |
29 | * 0|Yovflw Xovflw Ysign Xsign 1 Middle Right Left | 27 | * 0|[Yovflw][Xovflw][Ysign ][Xsign ][ 1 ][Middle][Right ][Left ] |
30 | * 1| X movement(0-255) | 28 | * 1|[ X movement(0-255) ] |
31 | * 2| Y movement(0-255) | 29 | * 2|[ Y movement(0-255) ] |
32 | */ | 30 | */ |
33 | #define PS2_MOUSE_BTN_MASK 0x07 | 31 | #define PS2_MOUSE_BTN_MASK 0x07 |
34 | #define PS2_MOUSE_BTN_LEFT 0 | 32 | #define PS2_MOUSE_BTN_LEFT 0 |
@@ -39,10 +37,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
39 | #define PS2_MOUSE_X_OVFLW 6 | 37 | #define PS2_MOUSE_X_OVFLW 6 |
40 | #define PS2_MOUSE_Y_OVFLW 7 | 38 | #define PS2_MOUSE_Y_OVFLW 7 |
41 | 39 | ||
42 | |||
43 | /* | ||
44 | * Scroll by mouse move with pressing button | ||
45 | */ | ||
46 | /* mouse button to start scrolling; set 0 to disable scroll */ | 40 | /* mouse button to start scrolling; set 0 to disable scroll */ |
47 | #ifndef PS2_MOUSE_SCROLL_BTN_MASK | 41 | #ifndef PS2_MOUSE_SCROLL_BTN_MASK |
48 | #define PS2_MOUSE_SCROLL_BTN_MASK (1<<PS2_MOUSE_BTN_MIDDLE) | 42 | #define PS2_MOUSE_SCROLL_BTN_MASK (1<<PS2_MOUSE_BTN_MIDDLE) |
@@ -58,9 +52,74 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
58 | #ifndef PS2_MOUSE_SCROLL_DIVISOR_H | 52 | #ifndef PS2_MOUSE_SCROLL_DIVISOR_H |
59 | #define PS2_MOUSE_SCROLL_DIVISOR_H 2 | 53 | #define PS2_MOUSE_SCROLL_DIVISOR_H 2 |
60 | #endif | 54 | #endif |
55 | /* multiply reported mouse values by these */ | ||
56 | #ifndef PS2_MOUSE_X_MULTIPLIER | ||
57 | #define PS2_MOUSE_X_MULTIPLIER 1 | ||
58 | #endif | ||
59 | #ifndef PS2_MOUSE_Y_MULTIPLIER | ||
60 | #define PS2_MOUSE_Y_MULTIPLIER 1 | ||
61 | #endif | ||
62 | #ifndef PS2_MOUSE_V_MULTIPLIER | ||
63 | #define PS2_MOUSE_V_MULTIPLIER 1 | ||
64 | #endif | ||
65 | /* For some mice this will need to be 0x0F */ | ||
66 | #ifndef PS2_MOUSE_SCROLL_MASK | ||
67 | #define PS2_MOUSE_SCROLL_MASK 0xFF | ||
68 | #endif | ||
69 | |||
70 | enum ps2_mouse_command_e { | ||
71 | PS2_MOUSE_RESET = 0xFF, | ||
72 | PS2_MOUSE_RESEND = 0xFE, | ||
73 | PS2_MOSUE_SET_DEFAULTS = 0xF6, | ||
74 | PS2_MOUSE_DISABLE_DATA_REPORTING = 0xF5, | ||
75 | PS2_MOUSE_ENABLE_DATA_REPORTING = 0xF4, | ||
76 | PS2_MOUSE_SET_SAMPLE_RATE = 0xF3, | ||
77 | PS2_MOUSE_GET_DEVICE_ID = 0xF2, | ||
78 | PS2_MOUSE_SET_REMOTE_MODE = 0xF0, | ||
79 | PS2_MOUSE_SET_WRAP_MODE = 0xEC, | ||
80 | PS2_MOUSE_READ_DATA = 0xEB, | ||
81 | PS2_MOUSE_SET_STREAM_MODE = 0xEA, | ||
82 | PS2_MOUSE_STATUS_REQUEST = 0xE9, | ||
83 | PS2_MOUSE_SET_RESOLUTION = 0xE8, | ||
84 | PS2_MOUSE_SET_SCALING_2_1 = 0xE7, | ||
85 | PS2_MOUSE_SET_SCALING_1_1 = 0xE6, | ||
86 | }; | ||
87 | |||
88 | typedef enum ps2_mouse_resolution_e { | ||
89 | PS2_MOUSE_1_COUNT_MM, | ||
90 | PS2_MOUSE_2_COUNT_MM, | ||
91 | PS2_MOUSE_4_COUNT_MM, | ||
92 | PS2_MOUSE_8_COUNT_MM, | ||
93 | } ps2_mouse_resolution_t; | ||
61 | 94 | ||
95 | typedef enum ps2_mouse_sample_rate_e { | ||
96 | PS2_MOUSE_10_SAMPLES_SEC = 10, | ||
97 | PS2_MOUSE_20_SAMPLES_SEC = 20, | ||
98 | PS2_MOUSE_40_SAMPLES_SEC = 40, | ||
99 | PS2_MOUSE_60_SAMPLES_SEC = 60, | ||
100 | PS2_MOUSE_80_SAMPLES_SEC = 80, | ||
101 | PS2_MOUSE_100_SAMPLES_SEC = 100, | ||
102 | PS2_MOUSE_200_SAMPLES_SEC = 200, | ||
103 | } ps2_mouse_sample_rate_t; | ||
104 | |||
105 | void ps2_mouse_init(void); | ||
62 | 106 | ||
63 | uint8_t ps2_mouse_init(void); | ||
64 | void ps2_mouse_task(void); | 107 | void ps2_mouse_task(void); |
65 | 108 | ||
109 | void ps2_mouse_disable_data_reporting(void); | ||
110 | |||
111 | void ps2_mouse_enable_data_reporting(void); | ||
112 | |||
113 | void ps2_mouse_set_remote_mode(void); | ||
114 | |||
115 | void ps2_mouse_set_stream_mode(void); | ||
116 | |||
117 | void ps2_mouse_set_scaling_2_1(void); | ||
118 | |||
119 | void ps2_mouse_set_scaling_1_1(void); | ||
120 | |||
121 | void ps2_mouse_set_resolution(ps2_mouse_resolution_t resolution); | ||
122 | |||
123 | void ps2_mouse_set_sample_rate(ps2_mouse_sample_rate_t sample_rate); | ||
124 | |||
66 | #endif | 125 | #endif |