summaryrefslogtreecommitdiff
path: root/firmware/usbstack/usb_hid.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/usbstack/usb_hid.c')
-rw-r--r--firmware/usbstack/usb_hid.c349
1 files changed, 275 insertions, 74 deletions
diff --git a/firmware/usbstack/usb_hid.c b/firmware/usbstack/usb_hid.c
index 4eb25841bb..4e9795b210 100644
--- a/firmware/usbstack/usb_hid.c
+++ b/firmware/usbstack/usb_hid.c
@@ -28,11 +28,6 @@
28//#define LOGF_ENABLE 28//#define LOGF_ENABLE
29#include "logf.h" 29#include "logf.h"
30 30
31#define CONCAT(low, high) ((high << 8) | low)
32#define PACK_VAL1(dest, val) *(dest)++ = (val) & 0xff
33#define PACK_VAL2(dest, val) PACK_VAL1((dest), (val)); \
34 PACK_VAL1((dest), (val >> 8))
35
36/* Documents avaiable here: http://www.usb.org/developers/devclass_docs/ */ 31/* Documents avaiable here: http://www.usb.org/developers/devclass_docs/ */
37 32
38#define HID_VER 0x0110 /* 1.1 */ 33#define HID_VER 0x0110 /* 1.1 */
@@ -47,6 +42,7 @@
47#define INPUT 0x80 42#define INPUT 0x80
48#define OUTPUT 0x90 43#define OUTPUT 0x90
49#define COLLECTION 0xA0 44#define COLLECTION 0xA0
45#define COLLECTION_PHYSICAL 0x00
50#define COLLECTION_APPLICATION 0x01 46#define COLLECTION_APPLICATION 0x01
51#define END_COLLECTION 0xC0 47#define END_COLLECTION 0xC0
52/* Parts (HID1_11.pdf, page 40) */ 48/* Parts (HID1_11.pdf, page 40) */
@@ -90,24 +86,30 @@
90 86
91#define HID_BUF_SIZE_MSG 16 87#define HID_BUF_SIZE_MSG 16
92#define HID_BUF_SIZE_CMD 16 88#define HID_BUF_SIZE_CMD 16
93#define HID_BUF_SIZE_REPORT 96 89#define HID_BUF_SIZE_REPORT 160
94#define HID_NUM_BUFFERS 5 90#define HID_NUM_BUFFERS 5
95#define SET_REPORT_BUF_LEN 2 91#define SET_REPORT_BUF_LEN 2
96 92
93//#ifdef LOGF_ENABLE
97#ifdef LOGF_ENABLE 94#ifdef LOGF_ENABLE
95
98#define BUF_DUMP_BUF_LEN HID_BUF_SIZE_REPORT 96#define BUF_DUMP_BUF_LEN HID_BUF_SIZE_REPORT
99#define BUF_DUMP_PREFIX_SIZE 5 97#define BUF_DUMP_PREFIX_SIZE 5
100#define BUF_DUMP_LINE_SIZE (MAX_LOGF_ENTRY - BUF_DUMP_PREFIX_SIZE) 98#define BUF_DUMP_ITEMS_IN_LINE 8
101#define BUF_DUMP_ITEMS_IN_LINE (BUF_DUMP_LINE_SIZE / 3) 99#define BUF_DUMP_LINE_SIZE (BUF_DUMP_ITEMS_IN_LINE * 3)
102#define BUF_DUMP_NUM_LINES (BUF_DUMP_BUF_LEN / (BUF_DUMP_LINE_SIZE / 3)) 100#define BUF_DUMP_NUM_LINES (BUF_DUMP_BUF_LEN / BUF_DUMP_ITEMS_IN_LINE)
103#endif 101#endif
104 102
105#define HID_BUF_INC(i) do { (i) = ((i) + 1) % HID_NUM_BUFFERS; } while (0) 103#define HID_BUF_INC(i) do { (i) = ((i) + 1) % HID_NUM_BUFFERS; } while (0)
104#define PACK_VAL(dest, val) *(dest)++ = (val) & 0xff
106 105
107typedef enum 106typedef enum
108{ 107{
109 REPORT_ID_KEYBOARD = 1, 108 REPORT_ID_KEYBOARD = 1,
110 REPORT_ID_CONSUMER, 109 REPORT_ID_CONSUMER,
110#ifdef HAVE_USB_HID_MOUSE
111 REPORT_ID_MOUSE,
112#endif
111 REPORT_ID_COUNT, 113 REPORT_ID_COUNT,
112} report_id_t; 114} report_id_t;
113 115
@@ -164,6 +166,7 @@ typedef struct
164 /* Write the id into the buffer in the appropriate location, and returns the 166 /* Write the id into the buffer in the appropriate location, and returns the
165 * buffer length */ 167 * buffer length */
166 uint8_t (*buf_set)(unsigned char *buf, int id); 168 uint8_t (*buf_set)(unsigned char *buf, int id);
169 bool is_key_released;
167} usb_hid_report_t; 170} usb_hid_report_t;
168 171
169usb_hid_report_t usb_hid_reports[REPORT_ID_COUNT]; 172usb_hid_report_t usb_hid_reports[REPORT_ID_COUNT];
@@ -183,7 +186,7 @@ static int usb_interface;
183 186
184static void usb_hid_try_send_drv(void); 187static void usb_hid_try_send_drv(void);
185 188
186static void pack_parameter(unsigned char **dest, bool is_signed, 189static void pack_parameter(unsigned char **dest, bool is_signed, bool mark_size,
187 uint8_t parameter, uint32_t value) 190 uint8_t parameter, uint32_t value)
188{ 191{
189 uint8_t size_value = 1; /* # of bytes */ 192 uint8_t size_value = 1; /* # of bytes */
@@ -216,7 +219,7 @@ static void pack_parameter(unsigned char **dest, bool is_signed,
216 size_value++; 219 size_value++;
217 } 220 }
218 221
219 **dest = parameter | size_value; 222 **dest = parameter | (mark_size ? size_value : 0);
220 (*dest)++; 223 (*dest)++;
221 224
222 while (size_value--) 225 while (size_value--)
@@ -244,11 +247,10 @@ int usb_hid_set_first_interface(int interface)
244} 247}
245 248
246#ifdef LOGF_ENABLE 249#ifdef LOGF_ENABLE
247static unsigned char 250static unsigned char buf_dump_ar[BUF_DUMP_NUM_LINES][BUF_DUMP_LINE_SIZE + 1]
248 buf_dump_ar[BUF_DUMP_NUM_LINES][BUF_DUMP_LINE_SIZE + 1]
249 USB_DEVBSS_ATTR __attribute__((aligned(32))); 251 USB_DEVBSS_ATTR __attribute__((aligned(32)));
250 252
251void buf_dump(unsigned char *buf, size_t size) 253void buf_dump(unsigned char *buf, size_t size, char *msg)
252{ 254{
253 size_t i; 255 size_t i;
254 int line; 256 int line;
@@ -269,7 +271,7 @@ void buf_dump(unsigned char *buf, size_t size)
269 *b = 0; 271 *b = 0;
270 272
271 /* Prefix must be of len BUF_DUMP_PREFIX_SIZE */ 273 /* Prefix must be of len BUF_DUMP_PREFIX_SIZE */
272 logf("%03d: %s", i0, buf_dump_ar[line]); 274 logf("%03d: %s %s", i0, buf_dump_ar[line], msg);
273 } 275 }
274} 276}
275#else 277#else
@@ -277,26 +279,178 @@ void buf_dump(unsigned char *buf, size_t size)
277#define buf_dump(...) 279#define buf_dump(...)
278#endif 280#endif
279 281
282#define BUF_LEN_KEYBOARD 7
280static uint8_t buf_set_keyboard(unsigned char *buf, int id) 283static uint8_t buf_set_keyboard(unsigned char *buf, int id)
281{ 284{
282 memset(buf, 0, 7); 285 memset(buf, 0, BUF_LEN_KEYBOARD);
286 int key, i = 1;
283 287
284 if (HID_KEYBOARD_LEFT_CONTROL <= id && id <= HID_KEYBOARD_RIGHT_GUI) 288 /* Each key is a word in id (up to 4 keys supported) */
285 buf[0] = (1 << (id - HID_KEYBOARD_LEFT_CONTROL)); 289 while ((key = id & 0xff))
286 else 290 {
287 buf[1] = (uint8_t)id; 291 /* Each modifier key is a bit in the first byte */
292 if (HID_KEYBOARD_LEFT_CONTROL <= key && key <= HID_KEYBOARD_RIGHT_GUI)
293 buf[0] |= (1 << (key - HID_KEYBOARD_LEFT_CONTROL));
294 else /* Any other key should be set in a separate byte */
295 buf[i++] = (uint8_t)key;
288 296
289 return 7; 297 id >>= 8;
298 }
299
300 return BUF_LEN_KEYBOARD;
290} 301}
291 302
303#define BUF_LEN_CONSUMER 4
292static uint8_t buf_set_consumer(unsigned char *buf, int id) 304static uint8_t buf_set_consumer(unsigned char *buf, int id)
293{ 305{
294 memset(buf, 0, 4); 306 memset(buf, 0, BUF_LEN_CONSUMER);
295 buf[0] = (uint8_t)id; 307 buf[0] = (uint8_t)id;
296 308
297 return 4; 309 return BUF_LEN_CONSUMER;
298} 310}
299 311
312#ifdef HAVE_USB_HID_MOUSE
313#define MOUSE_WHEEL_STEP 1
314#define MOUSE_STEP 8
315#define MOUSE_BUTTON_LEFT 0x1
316#define MOUSE_BUTTON_RIGHT 0x2
317//#define MOUSE_BUTTON_MIDDLE 0x4
318#define MOUSE_BUTTON 0
319#define MOUSE_X 1
320#define MOUSE_Y 2
321#define MOUSE_WHEEL 3
322#define BUF_LEN_MOUSE 4
323#define MOUSE_ACCEL_FACTOR(count) ((count) / 2)
324#define MOUSE_DO(item, step) (buf[(item)] = ((uint8_t)(step)))
325
326static uint8_t buf_set_mouse(unsigned char *buf, int id)
327{
328 static int count = 0;
329 int step = MOUSE_STEP;
330
331 memset(buf, 0, BUF_LEN_MOUSE);
332
333 /* Set proper button */
334 switch (id)
335 {
336 case HID_MOUSE_BUTTON_LEFT:
337 case HID_MOUSE_LDRAG_UP:
338 case HID_MOUSE_LDRAG_UP_REP:
339 case HID_MOUSE_LDRAG_DOWN:
340 case HID_MOUSE_LDRAG_DOWN_REP:
341 case HID_MOUSE_LDRAG_LEFT:
342 case HID_MOUSE_LDRAG_LEFT_REP:
343 case HID_MOUSE_LDRAG_RIGHT:
344 case HID_MOUSE_LDRAG_RIGHT_REP:
345 MOUSE_DO(MOUSE_BUTTON, MOUSE_BUTTON_LEFT);
346 break;
347 case HID_MOUSE_BUTTON_RIGHT:
348 case HID_MOUSE_RDRAG_UP:
349 case HID_MOUSE_RDRAG_UP_REP:
350 case HID_MOUSE_RDRAG_DOWN:
351 case HID_MOUSE_RDRAG_DOWN_REP:
352 case HID_MOUSE_RDRAG_LEFT:
353 case HID_MOUSE_RDRAG_LEFT_REP:
354 case HID_MOUSE_RDRAG_RIGHT:
355 case HID_MOUSE_RDRAG_RIGHT_REP:
356 MOUSE_DO(MOUSE_BUTTON, MOUSE_BUTTON_RIGHT);
357 break;
358 case HID_MOUSE_BUTTON_LEFT_REL:
359 case HID_MOUSE_BUTTON_RIGHT_REL:
360 /* Keep buf empty, to mark mouse button release */
361 break;
362 default:
363 break;
364 }
365
366 /* Handle mouse accelarated movement */
367 switch (id)
368 {
369 case HID_MOUSE_UP:
370 case HID_MOUSE_DOWN:
371 case HID_MOUSE_LEFT:
372 case HID_MOUSE_RIGHT:
373 case HID_MOUSE_LDRAG_UP:
374 case HID_MOUSE_LDRAG_DOWN:
375 case HID_MOUSE_LDRAG_LEFT:
376 case HID_MOUSE_LDRAG_RIGHT:
377 case HID_MOUSE_RDRAG_UP:
378 case HID_MOUSE_RDRAG_DOWN:
379 case HID_MOUSE_RDRAG_LEFT:
380 case HID_MOUSE_RDRAG_RIGHT:
381 count = 0;
382 break;
383 case HID_MOUSE_UP_REP:
384 case HID_MOUSE_DOWN_REP:
385 case HID_MOUSE_LEFT_REP:
386 case HID_MOUSE_RIGHT_REP:
387 case HID_MOUSE_LDRAG_UP_REP:
388 case HID_MOUSE_LDRAG_DOWN_REP:
389 case HID_MOUSE_LDRAG_LEFT_REP:
390 case HID_MOUSE_LDRAG_RIGHT_REP:
391 case HID_MOUSE_RDRAG_UP_REP:
392 case HID_MOUSE_RDRAG_DOWN_REP:
393 case HID_MOUSE_RDRAG_LEFT_REP:
394 case HID_MOUSE_RDRAG_RIGHT_REP:
395 count++;
396 /* TODO: Find a better mouse accellaration algorithm */
397 step *= 1 + MOUSE_ACCEL_FACTOR(count);
398 if (step > 255)
399 step = 255;
400 break;
401 default:
402 break;
403 }
404
405 /* Move/scroll mouse */
406 switch (id)
407 {
408 case HID_MOUSE_UP:
409 case HID_MOUSE_UP_REP:
410 case HID_MOUSE_LDRAG_UP:
411 case HID_MOUSE_LDRAG_UP_REP:
412 case HID_MOUSE_RDRAG_UP:
413 case HID_MOUSE_RDRAG_UP_REP:
414 MOUSE_DO(MOUSE_Y, -step);
415 break;
416 case HID_MOUSE_DOWN:
417 case HID_MOUSE_DOWN_REP:
418 case HID_MOUSE_LDRAG_DOWN:
419 case HID_MOUSE_LDRAG_DOWN_REP:
420 case HID_MOUSE_RDRAG_DOWN:
421 case HID_MOUSE_RDRAG_DOWN_REP:
422 MOUSE_DO(MOUSE_Y, step);
423 break;
424 case HID_MOUSE_LEFT:
425 case HID_MOUSE_LEFT_REP:
426 case HID_MOUSE_LDRAG_LEFT:
427 case HID_MOUSE_LDRAG_LEFT_REP:
428 case HID_MOUSE_RDRAG_LEFT:
429 case HID_MOUSE_RDRAG_LEFT_REP:
430 MOUSE_DO(MOUSE_X, -step);
431 break;
432 case HID_MOUSE_RIGHT:
433 case HID_MOUSE_RIGHT_REP:
434 case HID_MOUSE_LDRAG_RIGHT:
435 case HID_MOUSE_LDRAG_RIGHT_REP:
436 case HID_MOUSE_RDRAG_RIGHT:
437 case HID_MOUSE_RDRAG_RIGHT_REP:
438 MOUSE_DO(MOUSE_X, step);
439 break;
440 case HID_MOUSE_SCROLL_UP:
441 MOUSE_DO(MOUSE_WHEEL, MOUSE_WHEEL_STEP);
442 break;
443 case HID_MOUSE_SCROLL_DOWN:
444 MOUSE_DO(MOUSE_WHEEL, -MOUSE_WHEEL_STEP);
445 break;
446 default:
447 break;
448 }
449
450 return BUF_LEN_MOUSE;
451}
452#endif /* HAVE_USB_HID_MOUSE */
453
300static size_t descriptor_report_get(unsigned char *dest) 454static size_t descriptor_report_get(unsigned char *dest)
301{ 455{
302 unsigned char *report = dest; 456 unsigned char *report = dest;
@@ -306,59 +460,97 @@ static size_t descriptor_report_get(unsigned char *dest)
306 usb_hid_report = &usb_hid_reports[REPORT_ID_KEYBOARD]; 460 usb_hid_report = &usb_hid_reports[REPORT_ID_KEYBOARD];
307 usb_hid_report->usage_page = HID_USAGE_PAGE_KEYBOARD_KEYPAD; 461 usb_hid_report->usage_page = HID_USAGE_PAGE_KEYBOARD_KEYPAD;
308 usb_hid_report->buf_set = buf_set_keyboard; 462 usb_hid_report->buf_set = buf_set_keyboard;
463 usb_hid_report->is_key_released = 1;
309 464
310 pack_parameter(&report, 0, USAGE_PAGE, 465 pack_parameter(&report, 0, 1, USAGE_PAGE,
311 HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS); 466 HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS);
312 PACK_VAL2(report, CONCAT(CONSUMER_USAGE, HID_GENERIC_DESKTOP_KEYBOARD)); 467 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_KEYBOARD);
313 pack_parameter(&report, 0, COLLECTION, COLLECTION_APPLICATION); 468 pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_APPLICATION);
314 pack_parameter(&report, 0, REPORT_ID, REPORT_ID_KEYBOARD); 469 pack_parameter(&report, 0, 1, REPORT_ID, REPORT_ID_KEYBOARD);
315 pack_parameter(&report, 0, USAGE_PAGE, HID_GENERIC_DESKTOP_KEYPAD); 470 pack_parameter(&report, 0, 1, USAGE_PAGE, HID_GENERIC_DESKTOP_KEYPAD);
316 pack_parameter(&report, 0, USAGE_MINIMUM, HID_KEYBOARD_LEFT_CONTROL); 471 pack_parameter(&report, 0, 1, USAGE_MINIMUM, HID_KEYBOARD_LEFT_CONTROL);
317 pack_parameter(&report, 0, USAGE_MAXIMUM, HID_KEYBOARD_RIGHT_GUI); 472 pack_parameter(&report, 0, 1, USAGE_MAXIMUM, HID_KEYBOARD_RIGHT_GUI);
318 pack_parameter(&report, 1, LOGICAL_MINIMUM, 0); 473 pack_parameter(&report, 1, 1, LOGICAL_MINIMUM, 0);
319 pack_parameter(&report, 1, LOGICAL_MAXIMUM, 1); 474 pack_parameter(&report, 1, 1, LOGICAL_MAXIMUM, 1);
320 pack_parameter(&report, 0, REPORT_SIZE, 1); 475 pack_parameter(&report, 0, 1, REPORT_SIZE, 1);
321 pack_parameter(&report, 0, REPORT_COUNT, 8); 476 pack_parameter(&report, 0, 1, REPORT_COUNT, 8);
322 pack_parameter(&report, 0, INPUT, MAIN_ITEM_VARIABLE); 477 pack_parameter(&report, 0, 1, INPUT, MAIN_ITEM_VARIABLE);
323 pack_parameter(&report, 0, REPORT_SIZE, 1); 478 pack_parameter(&report, 0, 1, REPORT_SIZE, 1);
324 pack_parameter(&report, 0, REPORT_COUNT, 5); 479 pack_parameter(&report, 0, 1, REPORT_COUNT, 5);
325 pack_parameter(&report, 0, USAGE_PAGE, HID_USAGE_PAGE_LEDS); 480 pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_LEDS);
326 pack_parameter(&report, 0, USAGE_MINIMUM, HID_LED_NUM_LOCK); 481 pack_parameter(&report, 0, 1, USAGE_MINIMUM, HID_LED_NUM_LOCK);
327 pack_parameter(&report, 0, USAGE_MAXIMUM, HID_LED_KANA); 482 pack_parameter(&report, 0, 1, USAGE_MAXIMUM, HID_LED_KANA);
328 pack_parameter(&report, 0, OUTPUT, MAIN_ITEM_VARIABLE); 483 pack_parameter(&report, 0, 1, OUTPUT, MAIN_ITEM_VARIABLE);
329 pack_parameter(&report, 0, REPORT_SIZE, 3); 484 pack_parameter(&report, 0, 1, REPORT_SIZE, 3);
330 pack_parameter(&report, 0, REPORT_COUNT, 1); 485 pack_parameter(&report, 0, 1, REPORT_COUNT, 1);
331 pack_parameter(&report, 0, OUTPUT, MAIN_ITEM_CONSTANT); 486 pack_parameter(&report, 0, 1, OUTPUT, MAIN_ITEM_CONSTANT);
332 pack_parameter(&report, 0, REPORT_SIZE, 8); 487 pack_parameter(&report, 0, 1, REPORT_SIZE, 8);
333 pack_parameter(&report, 0, REPORT_COUNT, 6); 488 pack_parameter(&report, 0, 1, REPORT_COUNT, 6);
334 pack_parameter(&report, 1, LOGICAL_MINIMUM, 0); 489 pack_parameter(&report, 1, 1, LOGICAL_MINIMUM, 0);
335 pack_parameter(&report, 1, LOGICAL_MAXIMUM, HID_KEYBOARD_EX_SEL); 490 pack_parameter(&report, 1, 1, LOGICAL_MAXIMUM, HID_KEYBOARD_EX_SEL);
336 pack_parameter(&report, 0, USAGE_PAGE, HID_USAGE_PAGE_KEYBOARD_KEYPAD); 491 pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_KEYBOARD_KEYPAD);
337 pack_parameter(&report, 0, USAGE_MINIMUM, 0); 492 pack_parameter(&report, 0, 1, USAGE_MINIMUM, 0);
338 pack_parameter(&report, 0, USAGE_MAXIMUM, HID_KEYBOARD_EX_SEL); 493 pack_parameter(&report, 0, 1, USAGE_MAXIMUM, HID_KEYBOARD_EX_SEL);
339 pack_parameter(&report, 0, INPUT, 0); 494 pack_parameter(&report, 0, 1, INPUT, 0);
340 PACK_VAL1(report, END_COLLECTION); 495 PACK_VAL(report, END_COLLECTION);
341 496
342 /* Consumer usage controls - play/pause, stop, etc. */ 497 /* Consumer usage controls - play/pause, stop, etc. */
343 usb_hid_report = &usb_hid_reports[REPORT_ID_CONSUMER]; 498 usb_hid_report = &usb_hid_reports[REPORT_ID_CONSUMER];
344 usb_hid_report->usage_page = HID_USAGE_PAGE_CONSUMER; 499 usb_hid_report->usage_page = HID_USAGE_PAGE_CONSUMER;
345 usb_hid_report->buf_set = buf_set_consumer; 500 usb_hid_report->buf_set = buf_set_consumer;
501 usb_hid_report->is_key_released = 1;
346 502
347 pack_parameter(&report, 0, USAGE_PAGE, HID_USAGE_PAGE_CONSUMER); 503 pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_CONSUMER);
348 PACK_VAL2(report, CONCAT(CONSUMER_USAGE, 504 pack_parameter(&report, 0, 0, CONSUMER_USAGE,
349 HID_CONSUMER_USAGE_CONSUMER_CONTROL));
350 pack_parameter(&report, 0, COLLECTION, COLLECTION_APPLICATION);
351 pack_parameter(&report, 0, REPORT_ID, REPORT_ID_CONSUMER);
352 pack_parameter(&report, 0, REPORT_SIZE, 16);
353 pack_parameter(&report, 0, REPORT_COUNT, 2);
354 pack_parameter(&report, 1, LOGICAL_MINIMUM, 1);
355 pack_parameter(&report, 1, LOGICAL_MAXIMUM, 652);
356 pack_parameter(&report, 0, USAGE_MINIMUM,
357 HID_CONSUMER_USAGE_CONSUMER_CONTROL); 505 HID_CONSUMER_USAGE_CONSUMER_CONTROL);
358 pack_parameter(&report, 0, USAGE_MAXIMUM, HID_CONSUMER_USAGE_AC_SEND); 506 pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_APPLICATION);
359 pack_parameter(&report, 0, INPUT, MAIN_ITEM_NO_PREFERRED | 507 pack_parameter(&report, 0, 1, REPORT_ID, REPORT_ID_CONSUMER);
508 pack_parameter(&report, 0, 1, REPORT_SIZE, 16);
509 pack_parameter(&report, 0, 1, REPORT_COUNT, 2);
510 pack_parameter(&report, 1, 1, LOGICAL_MINIMUM, 1);
511 pack_parameter(&report, 1, 1, LOGICAL_MAXIMUM, 652);
512 pack_parameter(&report, 0, 1, USAGE_MINIMUM,
513 HID_CONSUMER_USAGE_CONSUMER_CONTROL);
514 pack_parameter(&report, 0, 1, USAGE_MAXIMUM, HID_CONSUMER_USAGE_AC_SEND);
515 pack_parameter(&report, 0, 1, INPUT, MAIN_ITEM_NO_PREFERRED |
360 MAIN_ITEM_NULL_STATE); 516 MAIN_ITEM_NULL_STATE);
361 PACK_VAL1(report, END_COLLECTION); 517 PACK_VAL(report, END_COLLECTION);
518
519#ifdef HAVE_USB_HID_MOUSE
520 /* Mouse control */
521 usb_hid_report = &usb_hid_reports[REPORT_ID_MOUSE];
522 usb_hid_report->usage_page = HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS;
523 usb_hid_report->buf_set = buf_set_mouse;
524 usb_hid_report->is_key_released = 0;
525
526 pack_parameter(&report, 0, 1, USAGE_PAGE,
527 HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS);
528 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_MOUSE);
529 pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_APPLICATION);
530 pack_parameter(&report, 0, 1, REPORT_ID, REPORT_ID_MOUSE);
531 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_POINTER);
532 pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_PHYSICAL);
533 pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_BUTTON);
534 pack_parameter(&report, 0, 1, USAGE_MINIMUM, 1);
535 pack_parameter(&report, 0, 1, USAGE_MAXIMUM, 8);
536 pack_parameter(&report, 1, 1, LOGICAL_MINIMUM, 0);
537 pack_parameter(&report, 1, 1, LOGICAL_MAXIMUM, 1);
538 pack_parameter(&report, 0, 1, REPORT_SIZE, 1);
539 pack_parameter(&report, 0, 1, REPORT_COUNT, 8);
540 pack_parameter(&report, 0, 1, INPUT, MAIN_ITEM_VARIABLE);
541 pack_parameter(&report, 0, 1, USAGE_PAGE,
542 HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS);
543 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_X);
544 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_Y);
545 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_WHEEL);
546 pack_parameter(&report, 0, 1, LOGICAL_MINIMUM, -127 & 0xFF);
547 pack_parameter(&report, 0, 1, LOGICAL_MAXIMUM, 127);
548 pack_parameter(&report, 0, 1, REPORT_SIZE, 8);
549 pack_parameter(&report, 0, 1, REPORT_COUNT, 3);
550 pack_parameter(&report, 0, 1, INPUT, MAIN_ITEM_VARIABLE | MAIN_ITEM_RELATIVE);
551 PACK_VAL(report, END_COLLECTION);
552 PACK_VAL(report, END_COLLECTION);
553#endif /* HAVE_USB_HID_MOUSE */
362 554
363 return (size_t)((uint32_t)report - (uint32_t)dest); 555 return (size_t)((uint32_t)report - (uint32_t)dest);
364} 556}
@@ -368,6 +560,9 @@ static void descriptor_hid_get(unsigned char **dest)
368 hid_descriptor.wDescriptorLength0 = 560 hid_descriptor.wDescriptorLength0 =
369 (uint16_t)descriptor_report_get(report_descriptor); 561 (uint16_t)descriptor_report_get(report_descriptor);
370 562
563 logf("hid: desc len %u", hid_descriptor.wDescriptorLength0);
564 buf_dump(report_descriptor, hid_descriptor.wDescriptorLength0, "desc");
565
371 PACK_DATA(*dest, hid_descriptor); 566 PACK_DATA(*dest, hid_descriptor);
372} 567}
373 568
@@ -457,8 +652,8 @@ void usb_hid_transfer_complete(int ep, int dir, int status, int length)
457 * to the DAP using the host's custom driver */ 652 * to the DAP using the host's custom driver */
458static int usb_hid_set_report(struct usb_ctrlrequest *req) 653static int usb_hid_set_report(struct usb_ctrlrequest *req)
459{ 654{
460 static unsigned char buf[SET_REPORT_BUF_LEN] 655 static unsigned char buf[SET_REPORT_BUF_LEN] USB_DEVBSS_ATTR
461 USB_DEVBSS_ATTR __attribute__((aligned(32))); 656 __attribute__((aligned(32)));
462 int length; 657 int length;
463 int rc = 0; 658 int rc = 0;
464 659
@@ -645,16 +840,22 @@ void usb_hid_send(usage_page_t usage_page, int id)
645 length = report->buf_set(&buf[1], id) + 1; 840 length = report->buf_set(&buf[1], id) + 1;
646 logf("length %u", length); 841 logf("length %u", length);
647 842
843 if (!length)
844 return;
845
648 /* Key pressed */ 846 /* Key pressed */
649 buf_dump(buf, length); 847 buf_dump(buf, length, "key press");
650 usb_hid_queue(buf, length); 848 usb_hid_queue(buf, length);
651 849
652 /* Key released */ 850 if (report->is_key_released)
653 memset(buf, 0, length); 851 {
654 buf[0] = report_id; 852 /* Key released */
853 memset(buf, 0, length);
854 buf[0] = report_id;
655 855
656 buf_dump(buf, length); 856 buf_dump(buf, length, "key release");
657 usb_hid_queue(buf, length); 857 usb_hid_queue(buf, length);
858 }
658 859
659 usb_hid_try_send_drv(); 860 usb_hid_try_send_drv();
660} 861}