diff options
-rw-r--r-- | firmware/drivers/isp1583.c | 8 | ||||
-rw-r--r-- | firmware/export/usb.h | 2 | ||||
-rw-r--r-- | firmware/export/usb_core.h | 13 | ||||
-rw-r--r-- | firmware/export/usb_drv.h | 2 | ||||
-rw-r--r-- | firmware/ifp_usb_serial.c | 3 | ||||
-rw-r--r-- | firmware/target/arm/usb-drv-arc.c | 185 | ||||
-rw-r--r-- | firmware/target/arm/usb-tcc.c | 5 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/usb-jz4740.c | 7 | ||||
-rw-r--r-- | firmware/usb.c | 6 | ||||
-rw-r--r-- | firmware/usbstack/usb_charging_only.c | 2 | ||||
-rw-r--r-- | firmware/usbstack/usb_class_driver.h | 6 | ||||
-rw-r--r-- | firmware/usbstack/usb_core.c | 40 | ||||
-rw-r--r-- | firmware/usbstack/usb_hid.c | 346 | ||||
-rw-r--r-- | firmware/usbstack/usb_hid.h | 3 | ||||
-rw-r--r-- | firmware/usbstack/usb_serial.c | 11 | ||||
-rw-r--r-- | firmware/usbstack/usb_storage.c | 11 |
16 files changed, 416 insertions, 234 deletions
diff --git a/firmware/drivers/isp1583.c b/firmware/drivers/isp1583.c index f373741586..fa97305b52 100644 --- a/firmware/drivers/isp1583.c +++ b/firmware/drivers/isp1583.c | |||
@@ -29,9 +29,6 @@ | |||
29 | #include "logf.h" | 29 | #include "logf.h" |
30 | #include "stdio.h" | 30 | #include "stdio.h" |
31 | 31 | ||
32 | #define DIR_RX 0 | ||
33 | #define DIR_TX 1 | ||
34 | |||
35 | struct usb_endpoint | 32 | struct usb_endpoint |
36 | { | 33 | { |
37 | unsigned char *out_buf; | 34 | unsigned char *out_buf; |
@@ -602,9 +599,12 @@ void usb_drv_cancel_all_transfers(void) | |||
602 | endpoints[i].halt[0] = endpoints[i].halt[1] = 1; | 599 | endpoints[i].halt[0] = endpoints[i].halt[1] = 1; |
603 | } | 600 | } |
604 | 601 | ||
605 | int usb_drv_request_endpoint(int dir) | 602 | int usb_drv_request_endpoint(int type, int dir) |
606 | { | 603 | { |
607 | int i, bit; | 604 | int i, bit; |
605 | |||
606 | if (type != USB_ENDPOINT_XFER_BULK) | ||
607 | return -1; | ||
608 | 608 | ||
609 | bit=(dir & USB_DIR_IN)? 2:1; | 609 | bit=(dir & USB_DIR_IN)? 2:1; |
610 | 610 | ||
diff --git a/firmware/export/usb.h b/firmware/export/usb.h index e1bacfffc7..42893c3468 100644 --- a/firmware/export/usb.h +++ b/firmware/export/usb.h | |||
@@ -105,7 +105,7 @@ struct usb_transfer_completion_event_data | |||
105 | int length; | 105 | int length; |
106 | void* data; | 106 | void* data; |
107 | }; | 107 | }; |
108 | #endif | 108 | #endif /* HAVE_USBSTACK */ |
109 | 109 | ||
110 | void usb_init(void); | 110 | void usb_init(void); |
111 | void usb_enable(bool on); | 111 | void usb_enable(bool on); |
diff --git a/firmware/export/usb_core.h b/firmware/export/usb_core.h index abf090ed9d..9c105fbc7c 100644 --- a/firmware/export/usb_core.h +++ b/firmware/export/usb_core.h | |||
@@ -36,6 +36,17 @@ | |||
36 | 36 | ||
37 | /* endpoints */ | 37 | /* endpoints */ |
38 | #define EP_CONTROL 0 | 38 | #define EP_CONTROL 0 |
39 | |||
40 | #define DIR_OUT 0 | ||
41 | #define DIR_IN 1 | ||
42 | |||
43 | /* The USB core is a device, and OUT is RX from that P.O.V */ | ||
44 | #define DIR_RX DIR_OUT | ||
45 | #define DIR_TX DIR_IN | ||
46 | |||
47 | #define EP_DIR(ep) (((ep) & USB_ENDPOINT_DIR_MASK) ? DIR_IN : DIR_OUT) | ||
48 | #define EP_NUM(ep) ((ep) & USB_ENDPOINT_NUMBER_MASK) | ||
49 | |||
39 | extern int usb_max_pkt_size; | 50 | extern int usb_max_pkt_size; |
40 | 51 | ||
41 | struct usb_class_driver; | 52 | struct usb_class_driver; |
@@ -52,7 +63,7 @@ void usb_core_handle_transfer_completion( | |||
52 | struct usb_transfer_completion_event_data* event); | 63 | struct usb_transfer_completion_event_data* event); |
53 | int usb_core_ack_control(struct usb_ctrlrequest* req); | 64 | int usb_core_ack_control(struct usb_ctrlrequest* req); |
54 | 65 | ||
55 | int usb_core_request_endpoint(int dir,struct usb_class_driver* drv); | 66 | int usb_core_request_endpoint(int type, int dir,struct usb_class_driver* drv); |
56 | void usb_core_release_endpoint(int dir); | 67 | void usb_core_release_endpoint(int dir); |
57 | 68 | ||
58 | #ifdef HAVE_HOTSWAP | 69 | #ifdef HAVE_HOTSWAP |
diff --git a/firmware/export/usb_drv.h b/firmware/export/usb_drv.h index 0c99630b11..fad9c79c10 100644 --- a/firmware/export/usb_drv.h +++ b/firmware/export/usb_drv.h | |||
@@ -44,7 +44,7 @@ int usb_drv_port_speed(void); | |||
44 | void usb_drv_cancel_all_transfers(void); | 44 | void usb_drv_cancel_all_transfers(void); |
45 | void usb_drv_set_test_mode(int mode); | 45 | void usb_drv_set_test_mode(int mode); |
46 | bool usb_drv_connected(void); | 46 | bool usb_drv_connected(void); |
47 | int usb_drv_request_endpoint(int dir); | 47 | int usb_drv_request_endpoint(int type, int dir); |
48 | void usb_drv_release_endpoint(int ep); | 48 | void usb_drv_release_endpoint(int ep); |
49 | 49 | ||
50 | #endif /* _USB_DRV_H */ | 50 | #endif /* _USB_DRV_H */ |
diff --git a/firmware/ifp_usb_serial.c b/firmware/ifp_usb_serial.c index e6c8dadfc5..06b286ab85 100644 --- a/firmware/ifp_usb_serial.c +++ b/firmware/ifp_usb_serial.c | |||
@@ -63,9 +63,6 @@ | |||
63 | 63 | ||
64 | #define ISP1582_UNLOCK_CODE 0xaa37 | 64 | #define ISP1582_UNLOCK_CODE 0xaa37 |
65 | 65 | ||
66 | #define DIR_RX 0 | ||
67 | #define DIR_TX 1 | ||
68 | |||
69 | #define TYPE_BULK 2 | 66 | #define TYPE_BULK 2 |
70 | 67 | ||
71 | #define STATE_DEFAULT 0 | 68 | #define STATE_DEFAULT 0 |
diff --git a/firmware/target/arm/usb-drv-arc.c b/firmware/target/arm/usb-drv-arc.c index 200601eb24..8a10c5fbd6 100644 --- a/firmware/target/arm/usb-drv-arc.c +++ b/firmware/target/arm/usb-drv-arc.c | |||
@@ -248,10 +248,6 @@ | |||
248 | #define EPCTRL_RX_EP_STALL (0x00000001) | 248 | #define EPCTRL_RX_EP_STALL (0x00000001) |
249 | 249 | ||
250 | /* bit 19-18 and 3-2 are endpoint type */ | 250 | /* bit 19-18 and 3-2 are endpoint type */ |
251 | #define EPCTRL_EP_TYPE_CONTROL (0) | ||
252 | #define EPCTRL_EP_TYPE_ISO (1) | ||
253 | #define EPCTRL_EP_TYPE_BULK (2) | ||
254 | #define EPCTRL_EP_TYPE_INTERRUPT (3) | ||
255 | #define EPCTRL_TX_EP_TYPE_SHIFT (18) | 251 | #define EPCTRL_TX_EP_TYPE_SHIFT (18) |
256 | #define EPCTRL_RX_EP_TYPE_SHIFT (2) | 252 | #define EPCTRL_RX_EP_TYPE_SHIFT (2) |
257 | 253 | ||
@@ -312,6 +308,14 @@ | |||
312 | transfer size, so it seems like a good size */ | 308 | transfer size, so it seems like a good size */ |
313 | #define NUM_TDS_PER_EP 4 | 309 | #define NUM_TDS_PER_EP 4 |
314 | 310 | ||
311 | typedef struct usb_endpoint | ||
312 | { | ||
313 | bool allocated[2]; | ||
314 | short type[2]; | ||
315 | short max_pkt_size[2]; | ||
316 | } usb_endpoint_t; | ||
317 | static usb_endpoint_t endpoints[USB_NUM_ENDPOINTS]; | ||
318 | |||
315 | /* manual: 32.13.2 Endpoint Transfer Descriptor (dTD) */ | 319 | /* manual: 32.13.2 Endpoint Transfer Descriptor (dTD) */ |
316 | struct transfer_descriptor { | 320 | struct transfer_descriptor { |
317 | unsigned int next_td_ptr; /* Next TD pointer(31-5), T(0) set | 321 | unsigned int next_td_ptr; /* Next TD pointer(31-5), T(0) set |
@@ -356,16 +360,12 @@ static const unsigned int pipe2mask[] = { | |||
356 | 0x10, 0x100000, | 360 | 0x10, 0x100000, |
357 | }; | 361 | }; |
358 | 362 | ||
359 | static char ep_allocation[USB_NUM_ENDPOINTS]; | ||
360 | |||
361 | /*-------------------------------------------------------------------------*/ | 363 | /*-------------------------------------------------------------------------*/ |
362 | static void transfer_completed(void); | 364 | static void transfer_completed(void); |
363 | static void control_received(void); | 365 | static void control_received(void); |
364 | static int prime_transfer(int endpoint, void* ptr, | 366 | static int prime_transfer(int ep_num, void* ptr, int len, bool send, bool wait); |
365 | int len, bool send, bool wait); | ||
366 | static void prepare_td(struct transfer_descriptor* td, | 367 | static void prepare_td(struct transfer_descriptor* td, |
367 | struct transfer_descriptor* previous_td, | 368 | struct transfer_descriptor* previous_td, void *ptr, int len,int pipe); |
368 | void *ptr, int len,int pipe); | ||
369 | static void bus_reset(void); | 369 | static void bus_reset(void); |
370 | static void init_control_queue_heads(void); | 370 | static void init_control_queue_heads(void); |
371 | static void init_bulk_queue_heads(void); | 371 | static void init_bulk_queue_heads(void); |
@@ -394,7 +394,7 @@ void usb_drv_reset(void) | |||
394 | while (REG_USBCMD & USBCMD_CTRL_RESET); | 394 | while (REG_USBCMD & USBCMD_CTRL_RESET); |
395 | 395 | ||
396 | #if CONFIG_CPU == PP5022 || CONFIG_CPU == PP5024 | 396 | #if CONFIG_CPU == PP5022 || CONFIG_CPU == PP5024 |
397 | /* On a CPU which identifies as a PP5022, this | 397 | /* On a CPU which identifies as a PP5022, this |
398 | initialization must be done after USB is reset. | 398 | initialization must be done after USB is reset. |
399 | */ | 399 | */ |
400 | outl(inl(0x70000060) | 0xF, 0x70000060); | 400 | outl(inl(0x70000060) | 0xF, 0x70000060); |
@@ -475,6 +475,27 @@ static void _usb_drv_init(bool attach) | |||
475 | (void)attach; | 475 | (void)attach; |
476 | } | 476 | } |
477 | 477 | ||
478 | #ifdef LOGF_ENABLE | ||
479 | #define XFER_DIR_STR(dir) ((dir) ? "IN" : "OUT") | ||
480 | #define XFER_TYPE_STR(type) \ | ||
481 | ((type) == USB_ENDPOINT_XFER_CONTROL ? "CTRL" : \ | ||
482 | ((type) == USB_ENDPOINT_XFER_ISOC ? "ISOC" : \ | ||
483 | ((type) == USB_ENDPOINT_XFER_BULK ? "BULK" : \ | ||
484 | ((type) == USB_ENDPOINT_XFER_INT ? "INTR" : "INVL")))) | ||
485 | |||
486 | static void log_ep(int ep_num, int ep_dir, char* prefix) | ||
487 | { | ||
488 | usb_endpoint_t* endpoint = &endpoints[ep_num]; | ||
489 | |||
490 | logf("%s: ep%d %s %s %d", prefix, ep_num, XFER_DIR_STR(ep_dir), | ||
491 | XFER_TYPE_STR(endpoint->type[ep_dir]), | ||
492 | endpoint->max_pkt_size[ep_dir]); | ||
493 | } | ||
494 | #else | ||
495 | #undef log_ep | ||
496 | #define log_ep(...) | ||
497 | #endif | ||
498 | |||
478 | void usb_drv_init(void) | 499 | void usb_drv_init(void) |
479 | { | 500 | { |
480 | _usb_drv_init(false); | 501 | _usb_drv_init(false); |
@@ -483,6 +504,7 @@ void usb_drv_init(void) | |||
483 | /* fully enable driver */ | 504 | /* fully enable driver */ |
484 | void usb_drv_attach(void) | 505 | void usb_drv_attach(void) |
485 | { | 506 | { |
507 | logf("usb_drv_attach"); | ||
486 | sleep(HZ/10); | 508 | sleep(HZ/10); |
487 | _usb_drv_init(true); | 509 | _usb_drv_init(true); |
488 | } | 510 | } |
@@ -555,49 +577,51 @@ void usb_drv_int(void) | |||
555 | bool usb_drv_stalled(int endpoint,bool in) | 577 | bool usb_drv_stalled(int endpoint,bool in) |
556 | { | 578 | { |
557 | if(in) { | 579 | if(in) { |
558 | return ((REG_ENDPTCTRL(endpoint&0x7f) & EPCTRL_TX_EP_STALL)!=0); | 580 | return ((REG_ENDPTCTRL(EP_NUM(endpoint)) & EPCTRL_TX_EP_STALL)!=0); |
559 | } | 581 | } |
560 | else { | 582 | else { |
561 | return ((REG_ENDPTCTRL(endpoint&0x7f) & EPCTRL_RX_EP_STALL)!=0); | 583 | return ((REG_ENDPTCTRL(EP_NUM(endpoint)) & EPCTRL_RX_EP_STALL)!=0); |
562 | } | 584 | } |
563 | 585 | ||
564 | } | 586 | } |
565 | void usb_drv_stall(int endpoint, bool stall,bool in) | 587 | void usb_drv_stall(int endpoint, bool stall, bool in) |
566 | { | 588 | { |
567 | logf("%sstall %d", stall?"":"un", endpoint&0x7f); | 589 | int ep_num = EP_NUM(endpoint); |
590 | |||
591 | logf("%sstall %d", stall ? "" : "un", ep_num); | ||
568 | 592 | ||
569 | if(in) { | 593 | if(in) { |
570 | if (stall) { | 594 | if (stall) { |
571 | REG_ENDPTCTRL(endpoint&0x7f) |= EPCTRL_TX_EP_STALL; | 595 | REG_ENDPTCTRL(ep_num) |= EPCTRL_TX_EP_STALL; |
572 | } | 596 | } |
573 | else { | 597 | else { |
574 | REG_ENDPTCTRL(endpoint&0x7f) &= ~EPCTRL_TX_EP_STALL; | 598 | REG_ENDPTCTRL(ep_num) &= ~EPCTRL_TX_EP_STALL; |
575 | } | 599 | } |
576 | } | 600 | } |
577 | else { | 601 | else { |
578 | if (stall) { | 602 | if (stall) { |
579 | REG_ENDPTCTRL(endpoint) |= EPCTRL_RX_EP_STALL; | 603 | REG_ENDPTCTRL(ep_num) |= EPCTRL_RX_EP_STALL; |
580 | } | 604 | } |
581 | else { | 605 | else { |
582 | REG_ENDPTCTRL(endpoint) &= ~EPCTRL_RX_EP_STALL; | 606 | REG_ENDPTCTRL(ep_num) &= ~EPCTRL_RX_EP_STALL; |
583 | } | 607 | } |
584 | } | 608 | } |
585 | } | 609 | } |
586 | 610 | ||
587 | int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) | 611 | int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) |
588 | { | 612 | { |
589 | return prime_transfer(endpoint&0x7f, ptr, length, true, false); | 613 | return prime_transfer(EP_NUM(endpoint), ptr, length, true, false); |
590 | } | 614 | } |
591 | 615 | ||
592 | int usb_drv_send(int endpoint, void* ptr, int length) | 616 | int usb_drv_send(int endpoint, void* ptr, int length) |
593 | { | 617 | { |
594 | return prime_transfer(endpoint&0x7f, ptr, length, true, true); | 618 | return prime_transfer(EP_NUM(endpoint), ptr, length, true, true); |
595 | } | 619 | } |
596 | 620 | ||
597 | int usb_drv_recv(int endpoint, void* ptr, int length) | 621 | int usb_drv_recv(int endpoint, void* ptr, int length) |
598 | { | 622 | { |
599 | //logf("usbrecv(%x, %d)", ptr, length); | 623 | //logf("usbrecv(%x, %d)", ptr, length); |
600 | return prime_transfer(endpoint&0x7f, ptr, length, false, false); | 624 | return prime_transfer(EP_NUM(endpoint), ptr, length, false, false); |
601 | } | 625 | } |
602 | 626 | ||
603 | int usb_drv_port_speed(void) | 627 | int usb_drv_port_speed(void) |
@@ -627,7 +651,7 @@ void usb_drv_set_address(int address) | |||
627 | 651 | ||
628 | void usb_drv_reset_endpoint(int endpoint, bool send) | 652 | void usb_drv_reset_endpoint(int endpoint, bool send) |
629 | { | 653 | { |
630 | int pipe = (endpoint&0x7f) * 2 + (send ? 1 : 0); | 654 | int pipe = EP_NUM(endpoint) * 2 + (send ? 1 : 0); |
631 | unsigned int mask = pipe2mask[pipe]; | 655 | unsigned int mask = pipe2mask[pipe]; |
632 | REG_ENDPTFLUSH = mask; | 656 | REG_ENDPTFLUSH = mask; |
633 | while (REG_ENDPTFLUSH & mask); | 657 | while (REG_ENDPTFLUSH & mask); |
@@ -662,23 +686,23 @@ void usb_drv_set_test_mode(int mode) | |||
662 | /*-------------------------------------------------------------------------*/ | 686 | /*-------------------------------------------------------------------------*/ |
663 | 687 | ||
664 | /* manual: 32.14.5.2 */ | 688 | /* manual: 32.14.5.2 */ |
665 | static int prime_transfer(int endpoint, void* ptr, int len, bool send, bool wait) | 689 | static int prime_transfer(int ep_num, void* ptr, int len, bool send, bool wait) |
666 | { | 690 | { |
667 | int rc = 0; | 691 | int rc = 0; |
668 | int pipe = endpoint * 2 + (send ? 1 : 0); | 692 | int pipe = ep_num * 2 + (send ? 1 : 0); |
669 | unsigned int mask = pipe2mask[pipe]; | 693 | unsigned int mask = pipe2mask[pipe]; |
670 | struct queue_head* qh = &qh_array[pipe]; | 694 | struct queue_head* qh = &qh_array[pipe]; |
671 | static long last_tick; | 695 | static long last_tick; |
672 | struct transfer_descriptor* new_td,*cur_td,*prev_td; | 696 | struct transfer_descriptor *new_td, *cur_td, *prev_td; |
673 | 697 | ||
674 | int oldlevel = disable_irq_save(); | 698 | int oldlevel = disable_irq_save(); |
675 | /* | 699 | /* |
676 | if (send && endpoint > EP_CONTROL) { | 700 | if (send && ep_num > EP_CONTROL) { |
677 | logf("usb: sent %d bytes", len); | 701 | logf("usb: sent %d bytes", len); |
678 | } | 702 | } |
679 | */ | 703 | */ |
680 | qh->status = 0; | 704 | qh->status = 0; |
681 | qh->wait = wait; | 705 | qh->wait = wait; |
682 | 706 | ||
683 | new_td=&td_array[pipe*NUM_TDS_PER_EP]; | 707 | new_td=&td_array[pipe*NUM_TDS_PER_EP]; |
684 | cur_td=new_td; | 708 | cur_td=new_td; |
@@ -694,15 +718,15 @@ static int prime_transfer(int endpoint, void* ptr, int len, bool send, bool wait | |||
694 | cur_td++; | 718 | cur_td++; |
695 | len-=tdlen; | 719 | len-=tdlen; |
696 | } | 720 | } |
697 | while(len>0 ); | 721 | while(len>0); |
698 | //logf("starting ep %d %s",endpoint,send?"send":"receive"); | 722 | //logf("starting ep %d %s",ep_num,send?"send":"receive"); |
699 | 723 | ||
700 | qh->dtd.next_td_ptr = (unsigned int)new_td; | 724 | qh->dtd.next_td_ptr = (unsigned int)new_td; |
701 | qh->dtd.size_ioc_sts &= ~(QH_STATUS_HALT | QH_STATUS_ACTIVE); | 725 | qh->dtd.size_ioc_sts &= ~(QH_STATUS_HALT | QH_STATUS_ACTIVE); |
702 | 726 | ||
703 | REG_ENDPTPRIME |= mask; | 727 | REG_ENDPTPRIME |= mask; |
704 | 728 | ||
705 | if(endpoint == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) { | 729 | if(ep_num == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) { |
706 | /* 32.14.3.2.2 */ | 730 | /* 32.14.3.2.2 */ |
707 | logf("new setup arrived"); | 731 | logf("new setup arrived"); |
708 | rc = -4; | 732 | rc = -4; |
@@ -724,11 +748,11 @@ static int prime_transfer(int endpoint, void* ptr, int len, bool send, bool wait | |||
724 | } | 748 | } |
725 | 749 | ||
726 | if (!(REG_ENDPTSTATUS & mask)) { | 750 | if (!(REG_ENDPTSTATUS & mask)) { |
727 | logf("no prime! %d %d %x", endpoint, pipe, qh->dtd.size_ioc_sts & 0xff ); | 751 | logf("no prime! %d %d %x", ep_num, pipe, qh->dtd.size_ioc_sts & 0xff); |
728 | rc = -3; | 752 | rc = -3; |
729 | goto pt_error; | 753 | goto pt_error; |
730 | } | 754 | } |
731 | if(endpoint == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) { | 755 | if(ep_num == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) { |
732 | /* 32.14.3.2.2 */ | 756 | /* 32.14.3.2.2 */ |
733 | logf("new setup arrived"); | 757 | logf("new setup arrived"); |
734 | rc = -4; | 758 | rc = -4; |
@@ -780,17 +804,38 @@ void usb_drv_cancel_all_transfers(void) | |||
780 | } | 804 | } |
781 | } | 805 | } |
782 | 806 | ||
783 | int usb_drv_request_endpoint(int dir) | 807 | int usb_drv_request_endpoint(int type, int dir) |
784 | { | 808 | { |
785 | int i, bit; | 809 | int ep_num, ep_dir; |
810 | short ep_type; | ||
811 | |||
812 | /* Safety */ | ||
813 | ep_dir = EP_DIR(dir); | ||
814 | ep_type = type & USB_ENDPOINT_XFERTYPE_MASK; | ||
786 | 815 | ||
787 | bit=(dir & USB_DIR_IN)? 2:1; | 816 | logf("req: %s %s", XFER_DIR_STR(ep_dir), XFER_TYPE_STR(ep_type)); |
788 | 817 | ||
789 | for (i=1; i < USB_NUM_ENDPOINTS; i++) { | 818 | /* Find an available ep/dir pair */ |
790 | if((ep_allocation[i] & bit)!=0) | 819 | for (ep_num=1;ep_num<USB_NUM_ENDPOINTS;ep_num++) { |
820 | usb_endpoint_t* endpoint=&endpoints[ep_num]; | ||
821 | int other_dir=(ep_dir ? 0:1); | ||
822 | |||
823 | if (endpoint->allocated[ep_dir]) | ||
791 | continue; | 824 | continue; |
792 | ep_allocation[i] |= bit; | 825 | |
793 | return i | dir; | 826 | if (endpoint->allocated[other_dir] && |
827 | endpoint->type[other_dir] != ep_type) { | ||
828 | logf("ep of different type!"); | ||
829 | return -1; | ||
830 | } | ||
831 | |||
832 | log_ep(ep_num, ep_dir, "add"); | ||
833 | |||
834 | endpoint->allocated[ep_dir] = 1; | ||
835 | endpoint->type[ep_dir] = ep_type; | ||
836 | |||
837 | log_ep(ep_num, ep_dir, "got"); | ||
838 | return (ep_num | (dir & USB_ENDPOINT_DIR_MASK)); | ||
794 | } | 839 | } |
795 | 840 | ||
796 | return -1; | 841 | return -1; |
@@ -798,8 +843,11 @@ int usb_drv_request_endpoint(int dir) | |||
798 | 843 | ||
799 | void usb_drv_release_endpoint(int ep) | 844 | void usb_drv_release_endpoint(int ep) |
800 | { | 845 | { |
801 | int mask = (ep & USB_DIR_IN)? ~2:~1; | 846 | int ep_num = EP_NUM(ep); |
802 | ep_allocation[ep & 0x7f] &= mask; | 847 | int ep_dir = EP_DIR(ep); |
848 | |||
849 | log_ep(ep_num, ep_dir, "rel"); | ||
850 | endpoints[ep_num].allocated[ep_dir] = 0; | ||
803 | } | 851 | } |
804 | 852 | ||
805 | 853 | ||
@@ -870,11 +918,12 @@ static void transfer_completed(void) | |||
870 | struct transfer_descriptor* td=&td_array[pipe*NUM_TDS_PER_EP]; | 918 | struct transfer_descriptor* td=&td_array[pipe*NUM_TDS_PER_EP]; |
871 | while(td!=(struct transfer_descriptor*)DTD_NEXT_TERMINATE && td!=0) | 919 | while(td!=(struct transfer_descriptor*)DTD_NEXT_TERMINATE && td!=0) |
872 | { | 920 | { |
873 | length += ((td->reserved & DTD_RESERVED_LENGTH_MASK) - | 921 | length += ((td->reserved & DTD_RESERVED_LENGTH_MASK) - |
874 | ((td->size_ioc_sts & DTD_PACKET_SIZE) >> DTD_LENGTH_BIT_POS)); | 922 | ((td->size_ioc_sts & DTD_PACKET_SIZE) >> DTD_LENGTH_BIT_POS)); |
875 | td=(struct transfer_descriptor*) td->next_td_ptr; | 923 | td=(struct transfer_descriptor*) td->next_td_ptr; |
876 | } | 924 | } |
877 | usb_core_transfer_complete(ep, dir?USB_DIR_IN:USB_DIR_OUT, qh->status, length); | 925 | usb_core_transfer_complete(ep, dir?USB_DIR_IN:USB_DIR_OUT, |
926 | qh->status, length); | ||
878 | } | 927 | } |
879 | } | 928 | } |
880 | } | 929 | } |
@@ -906,7 +955,7 @@ static void bus_reset(void) | |||
906 | } | 955 | } |
907 | 956 | ||
908 | usb_drv_cancel_all_transfers(); | 957 | usb_drv_cancel_all_transfers(); |
909 | 958 | ||
910 | if (!(REG_PORTSC1 & PORTSCX_PORT_RESET)) { | 959 | if (!(REG_PORTSC1 & PORTSCX_PORT_RESET)) { |
911 | logf("usb: slow reset!"); | 960 | logf("usb: slow reset!"); |
912 | } | 961 | } |
@@ -926,39 +975,41 @@ static void init_control_queue_heads(void) | |||
926 | /* manual: 32.14.4.1 Queue Head Initialization */ | 975 | /* manual: 32.14.4.1 Queue Head Initialization */ |
927 | static void init_bulk_queue_heads(void) | 976 | static void init_bulk_queue_heads(void) |
928 | { | 977 | { |
929 | int tx_packetsize; | 978 | int packetsize = (usb_drv_port_speed() ? 512 : 64); |
930 | int rx_packetsize; | ||
931 | int i; | 979 | int i; |
932 | 980 | ||
933 | if (usb_drv_port_speed()) { | ||
934 | rx_packetsize = 512; | ||
935 | tx_packetsize = 512; | ||
936 | } | ||
937 | else { | ||
938 | rx_packetsize = 64; | ||
939 | tx_packetsize = 64; | ||
940 | } | ||
941 | /* TODO: this should take ep_allocation into account */ | 981 | /* TODO: this should take ep_allocation into account */ |
942 | 982 | for (i=1;i<USB_NUM_ENDPOINTS;i++) { | |
943 | /*** bulk ***/ | 983 | qh_array[i*2].max_pkt_length = packetsize << QH_MAX_PKT_LEN_POS | |
944 | for(i=1;i<USB_NUM_ENDPOINTS;i++) { | 984 | QH_ZLT_SEL; |
945 | qh_array[i*2].max_pkt_length = rx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; | ||
946 | qh_array[i*2].dtd.next_td_ptr = QH_NEXT_TERMINATE; | 985 | qh_array[i*2].dtd.next_td_ptr = QH_NEXT_TERMINATE; |
947 | qh_array[i*2+1].max_pkt_length = tx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; | 986 | qh_array[i*2+1].max_pkt_length = packetsize << QH_MAX_PKT_LEN_POS | |
987 | QH_ZLT_SEL; | ||
948 | qh_array[i*2+1].dtd.next_td_ptr = QH_NEXT_TERMINATE; | 988 | qh_array[i*2+1].dtd.next_td_ptr = QH_NEXT_TERMINATE; |
949 | } | 989 | } |
950 | } | 990 | } |
951 | 991 | ||
952 | static void init_endpoints(void) | 992 | static void init_endpoints(void) |
953 | { | 993 | { |
954 | int i; | 994 | int ep_num; |
955 | /* TODO: this should take ep_allocation into account */ | 995 | |
956 | /* bulk */ | 996 | logf("init_endpoints"); |
957 | for(i=1;i<USB_NUM_ENDPOINTS;i++) { | 997 | /* RX/TX from the device POV: OUT/IN, respectively */ |
958 | REG_ENDPTCTRL(i) = | 998 | for(ep_num=1;ep_num<USB_NUM_ENDPOINTS;ep_num++) { |
999 | usb_endpoint_t *endpoint = &endpoints[ep_num]; | ||
1000 | |||
1001 | /* manual: 32.9.5.18 (Caution) */ | ||
1002 | if (!endpoint->allocated[DIR_OUT]) { | ||
1003 | endpoint->type[DIR_OUT] = USB_ENDPOINT_XFER_BULK; | ||
1004 | } | ||
1005 | if (!endpoint->allocated[DIR_IN]) { | ||
1006 | endpoint->type[DIR_IN] = USB_ENDPOINT_XFER_BULK; | ||
1007 | } | ||
1008 | |||
1009 | REG_ENDPTCTRL(ep_num) = | ||
959 | EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE | | 1010 | EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE | |
960 | EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE | | 1011 | EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE | |
961 | (EPCTRL_EP_TYPE_BULK << EPCTRL_RX_EP_TYPE_SHIFT) | | 1012 | (endpoint->type[DIR_OUT] << EPCTRL_RX_EP_TYPE_SHIFT) | |
962 | (EPCTRL_EP_TYPE_BULK << EPCTRL_TX_EP_TYPE_SHIFT); | 1013 | (endpoint->type[DIR_IN] << EPCTRL_TX_EP_TYPE_SHIFT); |
963 | } | 1014 | } |
964 | } | 1015 | } |
diff --git a/firmware/target/arm/usb-tcc.c b/firmware/target/arm/usb-tcc.c index 611e4be195..2538efd12e 100644 --- a/firmware/target/arm/usb-tcc.c +++ b/firmware/target/arm/usb-tcc.c | |||
@@ -94,12 +94,15 @@ static struct tcc_ep tcc_endpoints[] = { | |||
94 | static bool usb_drv_write_ep(struct tcc_ep *ep); | 94 | static bool usb_drv_write_ep(struct tcc_ep *ep); |
95 | static void usb_set_speed(int); | 95 | static void usb_set_speed(int); |
96 | 96 | ||
97 | int usb_drv_request_endpoint(int dir) | 97 | int usb_drv_request_endpoint(int type, int dir) |
98 | { | 98 | { |
99 | int flags = disable_irq_save(); | 99 | int flags = disable_irq_save(); |
100 | size_t ep; | 100 | size_t ep; |
101 | int ret = 0; | 101 | int ret = 0; |
102 | 102 | ||
103 | if (type != USB_ENDPOINT_XFER_BULK) | ||
104 | return -1; | ||
105 | |||
103 | if (dir == USB_DIR_IN) | 106 | if (dir == USB_DIR_IN) |
104 | ep = 1; | 107 | ep = 1; |
105 | else | 108 | else |
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c index 14656eed5f..be245ede8c 100644 --- a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c | |||
@@ -852,10 +852,13 @@ void usb_drv_release_endpoint(int ep) | |||
852 | logf("usb_drv_release_endpoint(%d, %s)", (ep & 0x7F), (ep >> 7) ? "IN" : "OUT"); | 852 | logf("usb_drv_release_endpoint(%d, %s)", (ep & 0x7F), (ep >> 7) ? "IN" : "OUT"); |
853 | } | 853 | } |
854 | 854 | ||
855 | int usb_drv_request_endpoint(int dir) | 855 | int usb_drv_request_endpoint(int type, int dir) |
856 | { | 856 | { |
857 | logf("usb_drv_request_endpoint(%s)", (dir == USB_DIR_IN) ? "IN" : "OUT"); | 857 | logf("usb_drv_request_endpoint(%s)", (dir == USB_DIR_IN) ? "IN" : "OUT"); |
858 | 858 | ||
859 | if (type != USB_ENDPOINT_XFER_BULK) | ||
860 | return -1; | ||
861 | |||
859 | /* There are only 3+2 endpoints, so hardcode this ... */ | 862 | /* There are only 3+2 endpoints, so hardcode this ... */ |
860 | /* Currently only BULK endpoints ... */ | 863 | /* Currently only BULK endpoints ... */ |
861 | if(dir == USB_DIR_OUT) | 864 | if(dir == USB_DIR_OUT) |
diff --git a/firmware/usb.c b/firmware/usb.c index 3d94ccfce7..bb00a1be5f 100644 --- a/firmware/usb.c +++ b/firmware/usb.c | |||
@@ -273,6 +273,9 @@ static void usb_thread(void) | |||
273 | #ifdef USB_STORAGE | 273 | #ifdef USB_STORAGE |
274 | usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, false); | 274 | usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, false); |
275 | #endif | 275 | #endif |
276 | #ifdef USB_HID | ||
277 | usb_core_enable_driver(USB_DRIVER_HID, false); | ||
278 | #endif | ||
276 | #ifdef USB_CHARGING_ONLY | 279 | #ifdef USB_CHARGING_ONLY |
277 | usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true); | 280 | usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true); |
278 | #endif | 281 | #endif |
@@ -291,6 +294,9 @@ static void usb_thread(void) | |||
291 | #ifdef USB_STORAGE | 294 | #ifdef USB_STORAGE |
292 | usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, true); | 295 | usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, true); |
293 | #endif | 296 | #endif |
297 | #ifdef USB_HID | ||
298 | usb_core_enable_driver(USB_DRIVER_HID, true); | ||
299 | #endif | ||
294 | #ifdef USB_CHARGING_ONLY | 300 | #ifdef USB_CHARGING_ONLY |
295 | usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, false); | 301 | usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, false); |
296 | #endif | 302 | #endif |
diff --git a/firmware/usbstack/usb_charging_only.c b/firmware/usbstack/usb_charging_only.c index 3cbc4c3e96..fc6139c1ae 100644 --- a/firmware/usbstack/usb_charging_only.c +++ b/firmware/usbstack/usb_charging_only.c | |||
@@ -66,7 +66,7 @@ int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_s | |||
66 | unsigned char *orig_dest = dest; | 66 | unsigned char *orig_dest = dest; |
67 | 67 | ||
68 | interface_descriptor.bInterfaceNumber=usb_interface; | 68 | interface_descriptor.bInterfaceNumber=usb_interface; |
69 | PACK_DESCRIPTOR(dest, interface_descriptor); | 69 | PACK_DATA(dest, interface_descriptor); |
70 | 70 | ||
71 | return (dest-orig_dest); | 71 | return (dest-orig_dest); |
72 | } | 72 | } |
diff --git a/firmware/usbstack/usb_class_driver.h b/firmware/usbstack/usb_class_driver.h index 36f2ea9e3d..a9bc759a5b 100644 --- a/firmware/usbstack/usb_class_driver.h +++ b/firmware/usbstack/usb_class_driver.h | |||
@@ -85,10 +85,10 @@ struct usb_class_driver { | |||
85 | #endif | 85 | #endif |
86 | }; | 86 | }; |
87 | 87 | ||
88 | #define PACK_DESCRIPTOR(dest, descriptor) \ | 88 | #define PACK_DATA(dest, data) \ |
89 | do { \ | 89 | do { \ |
90 | memcpy(dest, &(descriptor), sizeof(descriptor)); \ | 90 | memcpy(dest, &(data), sizeof(data)); \ |
91 | dest += sizeof(descriptor); \ | 91 | dest += sizeof(data); \ |
92 | } while (0) | 92 | } while (0) |
93 | 93 | ||
94 | #endif | 94 | #endif |
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c index 1e22ead63b..250544f202 100644 --- a/firmware/usbstack/usb_core.c +++ b/firmware/usbstack/usb_core.c | |||
@@ -397,7 +397,7 @@ void usb_core_handle_transfer_completion( | |||
397 | (struct usb_ctrlrequest*)event->data); | 397 | (struct usb_ctrlrequest*)event->data); |
398 | break; | 398 | break; |
399 | default: | 399 | default: |
400 | handler = ep_data[ep].completion_handler[event->dir>>7]; | 400 | handler = ep_data[ep].completion_handler[EP_DIR(event->dir)]; |
401 | if(handler != NULL) | 401 | if(handler != NULL) |
402 | handler(ep,event->dir,event->status,event->length); | 402 | handler(ep,event->dir,event->status,event->length); |
403 | break; | 403 | break; |
@@ -451,17 +451,17 @@ static void usb_core_set_serial_function_id(void) | |||
451 | usb_string_iSerial.wString[0] = hex[id]; | 451 | usb_string_iSerial.wString[0] = hex[id]; |
452 | } | 452 | } |
453 | 453 | ||
454 | int usb_core_request_endpoint(int dir, struct usb_class_driver* drv) | 454 | int usb_core_request_endpoint(int type, int dir, struct usb_class_driver* drv) |
455 | { | 455 | { |
456 | int ret, ep; | 456 | int ret, ep; |
457 | 457 | ||
458 | ret = usb_drv_request_endpoint(dir); | 458 | ret = usb_drv_request_endpoint(type, dir); |
459 | 459 | ||
460 | if (ret==-1) | 460 | if (ret==-1) |
461 | return -1; | 461 | return -1; |
462 | 462 | ||
463 | ep = ret & 0x7f; | 463 | dir = EP_DIR(ret); |
464 | dir = ret >> 7; | 464 | ep = EP_NUM(ret); |
465 | 465 | ||
466 | ep_data[ep].completion_handler[dir] = drv->transfer_complete; | 466 | ep_data[ep].completion_handler[dir] = drv->transfer_complete; |
467 | ep_data[ep].control_handler[dir] = drv->control_request; | 467 | ep_data[ep].control_handler[dir] = drv->control_request; |
@@ -475,8 +475,8 @@ void usb_core_release_endpoint(int ep) | |||
475 | 475 | ||
476 | usb_drv_release_endpoint(ep); | 476 | usb_drv_release_endpoint(ep); |
477 | 477 | ||
478 | dir = ep >> 7; | 478 | dir = EP_DIR(ep); |
479 | ep &= 0x7f; | 479 | ep = EP_NUM(ep); |
480 | 480 | ||
481 | ep_data[ep].completion_handler[dir] = NULL; | 481 | ep_data[ep].completion_handler[dir] = NULL; |
482 | ep_data[ep].control_handler[dir] = NULL; | 482 | ep_data[ep].control_handler[dir] = NULL; |
@@ -512,13 +512,14 @@ static void allocate_interfaces_and_endpoints(void) | |||
512 | 512 | ||
513 | static void control_request_handler_drivers(struct usb_ctrlrequest* req) | 513 | static void control_request_handler_drivers(struct usb_ctrlrequest* req) |
514 | { | 514 | { |
515 | int i; | 515 | int i, interface = req->wIndex; |
516 | bool handled=false; | 516 | bool handled=false; |
517 | |||
517 | for(i=0;i<USB_NUM_DRIVERS;i++) { | 518 | for(i=0;i<USB_NUM_DRIVERS;i++) { |
518 | if(drivers[i].enabled && | 519 | if(drivers[i].enabled && |
519 | drivers[i].control_request && | 520 | drivers[i].control_request && |
520 | drivers[i].first_interface <= (req->wIndex) && | 521 | drivers[i].first_interface <= interface && |
521 | drivers[i].last_interface > (req->wIndex)) | 522 | drivers[i].last_interface > interface) |
522 | { | 523 | { |
523 | handled = drivers[i].control_request(req, response_data); | 524 | handled = drivers[i].control_request(req, response_data); |
524 | if(handled) | 525 | if(handled) |
@@ -528,7 +529,7 @@ static void control_request_handler_drivers(struct usb_ctrlrequest* req) | |||
528 | if(!handled) { | 529 | if(!handled) { |
529 | /* nope. flag error */ | 530 | /* nope. flag error */ |
530 | logf("bad req:desc %d:%d", req->bRequest, req->wValue>>8); | 531 | logf("bad req:desc %d:%d", req->bRequest, req->wValue>>8); |
531 | usb_drv_stall(EP_CONTROL, true,true); | 532 | usb_drv_stall(EP_CONTROL, true, true); |
532 | usb_core_ack_control(req); | 533 | usb_core_ack_control(req); |
533 | } | 534 | } |
534 | } | 535 | } |
@@ -730,15 +731,13 @@ static void request_handler_endpoint(struct usb_ctrlrequest* req) | |||
730 | switch (req->bRequest) { | 731 | switch (req->bRequest) { |
731 | case USB_REQ_CLEAR_FEATURE: | 732 | case USB_REQ_CLEAR_FEATURE: |
732 | if (req->wValue==USB_ENDPOINT_HALT) { | 733 | if (req->wValue==USB_ENDPOINT_HALT) { |
733 | usb_drv_stall(req->wIndex & 0xf, false, | 734 | usb_drv_stall(EP_NUM(req->wIndex), false, EP_DIR(req->wIndex)); |
734 | (req->wIndex & USB_DIR_IN)!=0); | ||
735 | } | 735 | } |
736 | usb_core_ack_control(req); | 736 | usb_core_ack_control(req); |
737 | break; | 737 | break; |
738 | case USB_REQ_SET_FEATURE: | 738 | case USB_REQ_SET_FEATURE: |
739 | if (req->wValue==USB_ENDPOINT_HALT) { | 739 | if (req->wValue==USB_ENDPOINT_HALT) { |
740 | usb_drv_stall(req->wIndex & 0xf,true, | 740 | usb_drv_stall(EP_NUM(req->wIndex), true, EP_DIR(req->wIndex)); |
741 | (req->wIndex & USB_DIR_IN)!=0); | ||
742 | } | 741 | } |
743 | usb_core_ack_control(req); | 742 | usb_core_ack_control(req); |
744 | break; | 743 | break; |
@@ -747,8 +746,8 @@ static void request_handler_endpoint(struct usb_ctrlrequest* req) | |||
747 | response_data[1]=0; | 746 | response_data[1]=0; |
748 | logf("usb_core: GET_STATUS"); | 747 | logf("usb_core: GET_STATUS"); |
749 | if(req->wIndex>0) { | 748 | if(req->wIndex>0) { |
750 | response_data[0]=usb_drv_stalled(req->wIndex & 0xf, | 749 | response_data[0]=usb_drv_stalled(EP_NUM(req->wIndex), |
751 | (req->wIndex & USB_DIR_IN)!=0); | 750 | EP_DIR(req->wIndex)); |
752 | } | 751 | } |
753 | if(!usb_drv_send(EP_CONTROL,response_data,2)) | 752 | if(!usb_drv_send(EP_CONTROL,response_data,2)) |
754 | usb_core_ack_control(req); | 753 | usb_core_ack_control(req); |
@@ -757,7 +756,8 @@ static void request_handler_endpoint(struct usb_ctrlrequest* req) | |||
757 | bool handled; | 756 | bool handled; |
758 | control_handler_t control_handler; | 757 | control_handler_t control_handler; |
759 | 758 | ||
760 | control_handler=ep_data[req->wIndex & 0xf].control_handler[0]; | 759 | control_handler= |
760 | ep_data[EP_NUM(req->wIndex)].control_handler[EP_CONTROL]; | ||
761 | if (!control_handler) | 761 | if (!control_handler) |
762 | break; | 762 | break; |
763 | 763 | ||
@@ -835,9 +835,9 @@ void usb_core_transfer_complete(int endpoint,int dir,int status,int length) | |||
835 | void usb_core_control_request(struct usb_ctrlrequest* req) | 835 | void usb_core_control_request(struct usb_ctrlrequest* req) |
836 | { | 836 | { |
837 | struct usb_transfer_completion_event_data* completion_event = | 837 | struct usb_transfer_completion_event_data* completion_event = |
838 | &ep_data[0].completion_event; | 838 | &ep_data[EP_CONTROL].completion_event; |
839 | 839 | ||
840 | completion_event->endpoint=0; | 840 | completion_event->endpoint=EP_CONTROL; |
841 | completion_event->dir=0; | 841 | completion_event->dir=0; |
842 | completion_event->data=(void*)req; | 842 | completion_event->data=(void*)req; |
843 | completion_event->status=0; | 843 | completion_event->status=0; |
diff --git a/firmware/usbstack/usb_hid.c b/firmware/usbstack/usb_hid.c index c3cd5d9a04..0c35da2acb 100644 --- a/firmware/usbstack/usb_hid.c +++ b/firmware/usbstack/usb_hid.c | |||
@@ -25,49 +25,66 @@ | |||
25 | #include "kernel.h" | 25 | #include "kernel.h" |
26 | #include "usb_hid.h" | 26 | #include "usb_hid.h" |
27 | #include "usb_class_driver.h" | 27 | #include "usb_class_driver.h" |
28 | #define LOGF_ENABLE | 28 | //#define LOGF_ENABLE |
29 | #include "logf.h" | 29 | #include "logf.h" |
30 | 30 | ||
31 | #ifdef USB_HID | 31 | #ifdef USB_HID |
32 | 32 | ||
33 | #define CONCAT(low, high) ((high << 8) | low) | 33 | #define CONCAT(low, high) ((high << 8) | low) |
34 | #define SIZE_VALUE 0x01 | 34 | #define PACK_VAL1(dest, val) *(dest)++ = (val) & 0xff |
35 | #define PACK_VAL2(dest, val) PACK_VAL1((dest), (val)); \ | ||
36 | PACK_VAL1((dest), (val >> 8)) | ||
37 | |||
38 | /* Documents avaiable here: http://www.usb.org/developers/devclass_docs/ */ | ||
39 | |||
40 | #define HID_VER 0x0110 /* 1.1 */ | ||
41 | /* Subclass Codes (HID1_11.pdf, page 18) */ | ||
42 | #define SUBCLASS_BOOT_INTERFACE 1 | ||
43 | /* Protocol Codes (HID1_11.pdf, page 19) */ | ||
44 | #define PROTOCOL_CODE_MOUSE 2 | ||
35 | /* HID main items (HID1_11.pdf, page 38) */ | 45 | /* HID main items (HID1_11.pdf, page 38) */ |
36 | #define INPUT (0x80 | SIZE_VALUE) | 46 | #define INPUT 0x80 |
37 | #define OUTPUT (0x90 | SIZE_VALUE) | 47 | #define COLLECTION 0xa0 |
38 | #define FEATURE (0xb0 | SIZE_VALUE) | 48 | #define COLLECTION_APPLICATION 0x01 |
39 | #define COLLECTION (0xa0 | SIZE_VALUE) | ||
40 | #define COLLECTION_APPLICATION CONCAT(COLLECTION, 0x01) | ||
41 | #define END_COLLECTION 0xc0 | 49 | #define END_COLLECTION 0xc0 |
50 | /* Parts (HID1_11.pdf, page 40) */ | ||
51 | #define PREFERERD (1 << 5) | ||
52 | #define NULL_STATE (1 << 6) | ||
42 | /* HID global items (HID1_11.pdf, page 45) */ | 53 | /* HID global items (HID1_11.pdf, page 45) */ |
43 | #define USAGE_PAGE (0x04 | SIZE_VALUE) | 54 | #define USAGE_PAGE 0x04 |
44 | #define LOGICAL_MINIMUM (0x14 | SIZE_VALUE) | 55 | #define LOGICAL_MINIMUM 0x14 |
45 | #define LOGICAL_MAXIMUM (0x24 | SIZE_VALUE) | 56 | #define LOGICAL_MAXIMUM 0x24 |
46 | #define PHYSICAL_MINIMUM (0x34 | SIZE_VALUE) | 57 | #define REPORT_SIZE 0x74 |
47 | #define PHYSICAL_MAXIMUM (0x44 | SIZE_VALUE) | 58 | #define REPORT_ID 0x84 |
48 | #define UNIT_EXPONENT (0x54 | SIZE_VALUE) | 59 | #define REPORT_COUNT 0x94 |
49 | #define UNIT (0x64 | SIZE_VALUE) | 60 | /* HID local items (HID1_11.pdf, page 50) */ |
50 | #define REPORT_SIZE (0x74 | SIZE_VALUE) | 61 | #define USAGE_MINIMUM 0x18 |
51 | #define REPORT_ID (0x84 | SIZE_VALUE) | 62 | #define USAGE_MAXIMUM 0x28 |
52 | #define REPORT_COUNT (0x94 | SIZE_VALUE) | 63 | /* Types of class descriptors (HID1_11.pdf, page 59) */ |
53 | #define PUSH (0xa4 | SIZE_VALUE) | 64 | #define USB_DT_HID 0x21 |
54 | #define POP (0xb4 | SIZE_VALUE) | 65 | #define USB_DT_REPORT 0x22 |
55 | /* Hut1_12.pdf, Table 1, page 14 */ | 66 | |
56 | #define USAGE_PAGE_CONSUMER CONCAT(USAGE_PAGE, 0x0c) | 67 | /* (Hut1_12.pdf, Table 1, page 14) */ |
57 | /* Hut1_12.pdf, Table 17, page 77 */ | 68 | #define USAGE_PAGE_CONSUMER 0x0c |
69 | |||
58 | #define CONSUMER_USAGE 0x09 | 70 | #define CONSUMER_USAGE 0x09 |
59 | #define CONSUMER_USAGE_CONTROL CONCAT(CONSUMER_USAGE, 0x01) | 71 | |
60 | #define CONSUMER_USAGE_MUTE CONCAT(CONSUMER_USAGE, 0xe2) | 72 | /* HID-only class specific requests */ |
61 | #define CONSUMER_USAGE_VOLUME_INCREMENT CONCAT(CONSUMER_USAGE, 0xe9) | 73 | #define USB_HID_GET_REPORT 0x01 |
62 | #define CONSUMER_USAGE_VOLUME_DECREMENT CONCAT(CONSUMER_USAGE, 0xea) | 74 | #define USB_HID_GET_IDLE 0x02 |
63 | /* Hut1_12.pdf, Table 4, page 20 */ | 75 | #define USB_HID_GET_PROTOCOL 0x03 |
64 | #define CONSUMER_CONTROL CONCAT(COLLECTION_APPLICATION, 0x01) | 76 | #define USB_HID_SET_REPORT 0x09 |
65 | 77 | #define USB_HID_SET_IDLE 0x0a | |
66 | #define USB_DT_HID 0x21 | 78 | #define USB_HID_SET_PROTOCOL 0x0b |
67 | #define USB_DT_REPORT 0x22 | 79 | |
68 | #define USB_DT_PHYSICAL_DESCRIPTOR 0x23 | 80 | #define HID_BUF_SIZE_MSG 16 |
69 | 81 | #define HID_BUF_SIZE_CMD 5 | |
70 | /* serial interface */ | 82 | #define HID_BUG_SIZE_REPORT 32 |
83 | #define HID_NUM_BUFFERS 5 | ||
84 | |||
85 | #define HID_BUF_INC(i) do { (i) = ((i) + 1) % HID_NUM_BUFFERS; } while (0) | ||
86 | |||
87 | /* hid interface */ | ||
71 | static struct usb_interface_descriptor __attribute__((aligned(2))) | 88 | static struct usb_interface_descriptor __attribute__((aligned(2))) |
72 | interface_descriptor = | 89 | interface_descriptor = |
73 | { | 90 | { |
@@ -77,12 +94,11 @@ static struct usb_interface_descriptor __attribute__((aligned(2))) | |||
77 | .bAlternateSetting = 0, | 94 | .bAlternateSetting = 0, |
78 | .bNumEndpoints = 1, | 95 | .bNumEndpoints = 1, |
79 | .bInterfaceClass = USB_CLASS_HID, | 96 | .bInterfaceClass = USB_CLASS_HID, |
80 | .bInterfaceSubClass = 0, | 97 | .bInterfaceSubClass = SUBCLASS_BOOT_INTERFACE, |
81 | .bInterfaceProtocol = 0, | 98 | .bInterfaceProtocol = PROTOCOL_CODE_MOUSE, |
82 | .iInterface = 0 | 99 | .iInterface = 0 |
83 | }; | 100 | }; |
84 | 101 | ||
85 | /* USB_DT_HID: Endpoint descriptor */ | ||
86 | struct usb_hid_descriptor { | 102 | struct usb_hid_descriptor { |
87 | uint8_t bLength; | 103 | uint8_t bLength; |
88 | uint8_t bDescriptorType; | 104 | uint8_t bDescriptorType; |
@@ -93,19 +109,19 @@ struct usb_hid_descriptor { | |||
93 | uint16_t wDescriptorLength0; | 109 | uint16_t wDescriptorLength0; |
94 | } __attribute__ ((packed)); | 110 | } __attribute__ ((packed)); |
95 | 111 | ||
96 | /* USB_DT_REPORT: Endpoint descriptor */ | ||
97 | static struct usb_hid_descriptor __attribute__((aligned(2))) hid_descriptor = | 112 | static struct usb_hid_descriptor __attribute__((aligned(2))) hid_descriptor = |
98 | { | 113 | { |
99 | .bLength = sizeof(struct usb_hid_descriptor), | 114 | .bLength = sizeof(struct usb_hid_descriptor), |
100 | .bDescriptorType = USB_DT_HID, | 115 | .bDescriptorType = USB_DT_HID, |
101 | .wBcdHID = 0x0100, | 116 | .wBcdHID = HID_VER, |
102 | .bCountryCode = 0, | 117 | .bCountryCode = 0, |
103 | .bNumDescriptors = 1, | 118 | .bNumDescriptors = 1, |
104 | .bDescriptorType0 = 0x22, | 119 | .bDescriptorType0 = USB_DT_REPORT, |
105 | .wDescriptorLength0 = 0 | 120 | .wDescriptorLength0 = 0 |
106 | }; | 121 | }; |
107 | 122 | ||
108 | static struct usb_endpoint_descriptor __attribute__((aligned(2))) endpoint_descriptor = | 123 | static struct usb_endpoint_descriptor __attribute__((aligned(2))) |
124 | endpoint_descriptor = | ||
109 | { | 125 | { |
110 | .bLength = sizeof(struct usb_endpoint_descriptor), | 126 | .bLength = sizeof(struct usb_endpoint_descriptor), |
111 | .bDescriptorType = USB_DT_ENDPOINT, | 127 | .bDescriptorType = USB_DT_ENDPOINT, |
@@ -115,43 +131,46 @@ static struct usb_endpoint_descriptor __attribute__((aligned(2))) endpoint_descr | |||
115 | .bInterval = 0 | 131 | .bInterval = 0 |
116 | }; | 132 | }; |
117 | 133 | ||
118 | /* USB_DT_REPORT: Endpoint descriptor */ | 134 | static unsigned char report_descriptor[HID_BUG_SIZE_REPORT] |
119 | struct usb_report_descriptor { | 135 | USB_DEVBSS_ATTR __attribute__((aligned(32))); |
120 | uint16_t wUsagePage; | ||
121 | uint16_t wUsage; | ||
122 | uint16_t wCollection; | ||
123 | uint16_t wCollectionItems[12]; | ||
124 | uint8_t wEndCollection; | ||
125 | } __attribute__ ((packed)); | ||
126 | 136 | ||
127 | static struct usb_report_descriptor __attribute__((aligned(2))) report_descriptor = | 137 | static unsigned char send_buffer[HID_NUM_BUFFERS][HID_BUF_SIZE_MSG] |
128 | { | 138 | USB_DEVBSS_ATTR __attribute__((aligned(32))); |
129 | .wUsagePage = USAGE_PAGE_CONSUMER, | 139 | size_t send_buffer_len[HID_NUM_BUFFERS]; |
130 | .wUsage = CONSUMER_USAGE_CONTROL, | 140 | static int cur_buf_prepare; |
131 | .wCollection = COLLECTION_APPLICATION, | 141 | static int cur_buf_send; |
132 | .wCollectionItems = { | ||
133 | CONCAT(LOGICAL_MINIMUM, 0x0), | ||
134 | CONCAT(LOGICAL_MAXIMUM, 0x1), | ||
135 | USAGE_PAGE_CONSUMER, | ||
136 | CONSUMER_USAGE_MUTE, | ||
137 | CONSUMER_USAGE_VOLUME_INCREMENT, | ||
138 | CONSUMER_USAGE_VOLUME_DECREMENT, | ||
139 | CONCAT(REPORT_COUNT, 0x3), | ||
140 | CONCAT(REPORT_SIZE, 0x1), | ||
141 | CONCAT(INPUT, 0x42), | ||
142 | CONCAT(REPORT_COUNT, 0x5), | ||
143 | CONCAT(REPORT_SIZE, 0x1), | ||
144 | CONCAT(INPUT, 0x01) | ||
145 | }, | ||
146 | .wEndCollection = END_COLLECTION | ||
147 | }; | ||
148 | 142 | ||
143 | static uint16_t report_descriptor_len; | ||
144 | static bool active = false; | ||
149 | static int ep_in; | 145 | static int ep_in; |
150 | static int usb_interface; | 146 | static int usb_interface; |
147 | static uint32_t report_id; | ||
148 | |||
149 | static void usb_hid_try_send_drv(void); | ||
150 | |||
151 | static void pack_parameter(unsigned char **dest, uint8_t parameter, | ||
152 | uint32_t value) | ||
153 | { | ||
154 | uint8_t size_value = 1; /* # of bytes */ | ||
155 | uint32_t v = value; | ||
156 | |||
157 | while (v >>= 8) | ||
158 | size_value++; | ||
159 | |||
160 | **dest = parameter | size_value; | ||
161 | (*dest)++; | ||
162 | |||
163 | while (size_value--) | ||
164 | { | ||
165 | **dest = value & 0xff; | ||
166 | (*dest)++; | ||
167 | value >>= 8; | ||
168 | } | ||
169 | } | ||
151 | 170 | ||
152 | int usb_hid_request_endpoints(struct usb_class_driver *drv) | 171 | int usb_hid_request_endpoints(struct usb_class_driver *drv) |
153 | { | 172 | { |
154 | ep_in = usb_core_request_endpoint(USB_DIR_IN, drv); | 173 | ep_in = usb_core_request_endpoint(USB_ENDPOINT_XFER_INT, USB_DIR_IN, drv); |
155 | if (ep_in < 0) | 174 | if (ep_in < 0) |
156 | return -1; | 175 | return -1; |
157 | 176 | ||
@@ -165,25 +184,46 @@ int usb_hid_set_first_interface(int interface) | |||
165 | return interface + 1; | 184 | return interface + 1; |
166 | } | 185 | } |
167 | 186 | ||
168 | |||
169 | int usb_hid_get_config_descriptor(unsigned char *dest,int max_packet_size) | 187 | int usb_hid_get_config_descriptor(unsigned char *dest,int max_packet_size) |
170 | { | 188 | { |
171 | unsigned char *orig_dest = dest; | 189 | unsigned char *report, *orig_dest = dest; |
172 | 190 | ||
173 | logf("hid: config desc."); | 191 | logf("hid: config desc."); |
174 | interface_descriptor.bInterfaceNumber = usb_interface; | ||
175 | PACK_DESCRIPTOR(dest, interface_descriptor); | ||
176 | |||
177 | hid_descriptor.wDescriptorLength0 = sizeof(report_descriptor); | ||
178 | PACK_DESCRIPTOR(dest, hid_descriptor); | ||
179 | 192 | ||
180 | /* Ignore max_packet_size and set to 1 bytes long packet size */ | 193 | /* Ignore given max_packet_size */ |
181 | (void)max_packet_size; | 194 | (void)max_packet_size; |
182 | endpoint_descriptor.wMaxPacketSize = 1; | 195 | |
196 | /* TODO: Increment report_id for each report, and send command with | ||
197 | * appropriate report id */ | ||
198 | report_id = 2; | ||
199 | |||
200 | /* Initialize report descriptor */ | ||
201 | report = report_descriptor; | ||
202 | pack_parameter(&report, USAGE_PAGE, USAGE_PAGE_CONSUMER); | ||
203 | PACK_VAL2(report, CONCAT(CONSUMER_USAGE, CONSUMER_CONTROL)); | ||
204 | pack_parameter(&report, COLLECTION, COLLECTION_APPLICATION); | ||
205 | pack_parameter(&report, REPORT_ID, report_id); | ||
206 | pack_parameter(&report, REPORT_SIZE, 16); | ||
207 | pack_parameter(&report, REPORT_COUNT, 2); | ||
208 | pack_parameter(&report, LOGICAL_MINIMUM, 1); | ||
209 | pack_parameter(&report, LOGICAL_MAXIMUM, 652); | ||
210 | pack_parameter(&report, USAGE_MINIMUM, CONSUMER_CONTROL); | ||
211 | pack_parameter(&report, USAGE_MAXIMUM, AC_SEND); | ||
212 | pack_parameter(&report, INPUT, PREFERERD | NULL_STATE); | ||
213 | PACK_VAL1(report, END_COLLECTION); | ||
214 | report_descriptor_len = (uint16_t)((uint32_t)report - | ||
215 | (uint32_t)report_descriptor); | ||
216 | |||
217 | interface_descriptor.bInterfaceNumber = usb_interface; | ||
218 | PACK_DATA(dest, interface_descriptor); | ||
219 | hid_descriptor.wDescriptorLength0 = report_descriptor_len; | ||
220 | PACK_DATA(dest, hid_descriptor); | ||
221 | |||
222 | endpoint_descriptor.wMaxPacketSize = 8; | ||
183 | endpoint_descriptor.bInterval = 8; | 223 | endpoint_descriptor.bInterval = 8; |
184 | 224 | ||
185 | endpoint_descriptor.bEndpointAddress = ep_in; | 225 | endpoint_descriptor.bEndpointAddress = ep_in; |
186 | PACK_DESCRIPTOR(dest, endpoint_descriptor); | 226 | PACK_DATA(dest, endpoint_descriptor); |
187 | 227 | ||
188 | return (dest - orig_dest); | 228 | return (dest - orig_dest); |
189 | } | 229 | } |
@@ -191,38 +231,54 @@ int usb_hid_get_config_descriptor(unsigned char *dest,int max_packet_size) | |||
191 | void usb_hid_init_connection(void) | 231 | void usb_hid_init_connection(void) |
192 | { | 232 | { |
193 | logf("hid: init connection"); | 233 | logf("hid: init connection"); |
234 | |||
235 | active = true; | ||
194 | } | 236 | } |
195 | 237 | ||
196 | /* called by usb_code_init() */ | 238 | /* called by usb_core_init() */ |
197 | void usb_hid_init(void) | 239 | void usb_hid_init(void) |
198 | { | 240 | { |
241 | int i; | ||
242 | |||
199 | logf("hid: init"); | 243 | logf("hid: init"); |
244 | |||
245 | for (i = 0; i < HID_NUM_BUFFERS; i++) | ||
246 | send_buffer_len[i] = 0; | ||
247 | |||
248 | cur_buf_prepare = 0; | ||
249 | cur_buf_send = 0; | ||
250 | |||
251 | active = true; | ||
200 | } | 252 | } |
201 | 253 | ||
202 | void usb_hid_disconnect(void) | 254 | void usb_hid_disconnect(void) |
203 | { | 255 | { |
204 | logf("hid: disconnect"); | 256 | logf("hid: disconnect"); |
257 | active = false; | ||
205 | } | 258 | } |
206 | 259 | ||
207 | /* called by usb_core_transfer_complete() */ | 260 | /* called by usb_core_transfer_complete() */ |
208 | void usb_hid_transfer_complete(int ep,int dir, int status, int length) | 261 | void usb_hid_transfer_complete(int ep, int dir, int status, int length) |
209 | { | 262 | { |
210 | (void)ep; | 263 | (void)ep; |
211 | (void)dir; | 264 | (void)dir; |
212 | (void)status; | 265 | (void)status; |
213 | (void)length; | 266 | (void)length; |
214 | 267 | ||
215 | logf("hid: transfer complete. ep %d, dir %d, status %d ,length %d", | 268 | switch (dir) { |
216 | ep, dir, status, length); | 269 | case USB_DIR_OUT: |
217 | } | 270 | break; |
271 | case USB_DIR_IN: { | ||
272 | if (status) | ||
273 | break; | ||
218 | 274 | ||
219 | /* HID-only class specific requests */ | 275 | send_buffer_len[cur_buf_send] = 0; |
220 | #define USB_HID_GET_REPORT 0x01 | 276 | HID_BUF_INC(cur_buf_send); |
221 | #define USB_HID_GET_IDLE 0x02 | 277 | usb_hid_try_send_drv(); |
222 | #define USB_HID_GET_PROTOCOL 0x03 | 278 | break; |
223 | #define USB_HID_SET_REPORT 0x09 | 279 | } |
224 | #define USB_HID_SET_IDLE 0x0a | 280 | } |
225 | #define USB_HID_SET_PROTOCOL 0x0b | 281 | } |
226 | 282 | ||
227 | /* called by usb_core_control_request() */ | 283 | /* called by usb_core_control_request() */ |
228 | bool usb_hid_control_request(struct usb_ctrlrequest* req, unsigned char* dest) | 284 | bool usb_hid_control_request(struct usb_ctrlrequest* req, unsigned char* dest) |
@@ -231,29 +287,32 @@ bool usb_hid_control_request(struct usb_ctrlrequest* req, unsigned char* dest) | |||
231 | 287 | ||
232 | switch(req->bRequestType & USB_TYPE_MASK) { | 288 | switch(req->bRequestType & USB_TYPE_MASK) { |
233 | case USB_TYPE_STANDARD: { | 289 | case USB_TYPE_STANDARD: { |
234 | switch(req->wValue>>8) { /* type */ | 290 | unsigned char *orig_dest = dest; |
235 | case USB_DT_REPORT: { | 291 | |
236 | logf("hid: report"); | 292 | switch(req->wValue>>8) { /* type */ |
237 | if (dest == NULL) { | 293 | case USB_DT_HID: { |
238 | logf("dest is NULL!"); | 294 | logf("hid: type hid"); |
239 | } | 295 | hid_descriptor.wDescriptorLength0 = report_descriptor_len; |
240 | if (dest) { | 296 | PACK_DATA(dest, hid_descriptor); |
241 | unsigned char *orig_dest = dest; | 297 | break; |
242 | PACK_DESCRIPTOR(dest, report_descriptor); | ||
243 | if(usb_drv_send(EP_CONTROL, orig_dest, dest - orig_dest)) | ||
244 | break; | ||
245 | usb_core_ack_control(req); | ||
246 | |||
247 | } | ||
248 | handled = true; | ||
249 | break; | ||
250 | } | ||
251 | default: | ||
252 | logf("hid: unsup. std. req"); | ||
253 | break; | ||
254 | } | 298 | } |
255 | break; | 299 | case USB_DT_REPORT: { |
300 | logf("hid: type report"); | ||
301 | memcpy(dest, &report_descriptor, report_descriptor_len); | ||
302 | dest += report_descriptor_len; | ||
303 | break; | ||
304 | } | ||
305 | default: | ||
306 | logf("hid: unsup. std. req"); | ||
307 | break; | ||
256 | } | 308 | } |
309 | if (dest != orig_dest && | ||
310 | !usb_drv_send(EP_CONTROL, orig_dest, dest - orig_dest)) { | ||
311 | usb_core_ack_control(req); | ||
312 | handled = true; | ||
313 | } | ||
314 | break; | ||
315 | } | ||
257 | 316 | ||
258 | case USB_TYPE_CLASS: { | 317 | case USB_TYPE_CLASS: { |
259 | switch (req->bRequest) { | 318 | switch (req->bRequest) { |
@@ -263,7 +322,6 @@ bool usb_hid_control_request(struct usb_ctrlrequest* req, unsigned char* dest) | |||
263 | handled = true; | 322 | handled = true; |
264 | break; | 323 | break; |
265 | default: | 324 | default: |
266 | //logf("hid: unsup. cls. req"); | ||
267 | logf("%d: unsup. cls. req", req->bRequest); | 325 | logf("%d: unsup. cls. req", req->bRequest); |
268 | break; | 326 | break; |
269 | } | 327 | } |
@@ -277,12 +335,62 @@ bool usb_hid_control_request(struct usb_ctrlrequest* req, unsigned char* dest) | |||
277 | return handled; | 335 | return handled; |
278 | } | 336 | } |
279 | 337 | ||
280 | void usb_hid_send(unsigned char *data, int length) | 338 | static void usb_hid_try_send_drv(void) |
281 | { | 339 | { |
282 | (void)data; | 340 | int rc; |
283 | (void)(length); | 341 | int length = send_buffer_len[cur_buf_send]; |
342 | |||
343 | if (!length) | ||
344 | return; | ||
345 | |||
346 | rc = usb_drv_send_nonblocking(ep_in, send_buffer[cur_buf_send], length); | ||
347 | if (rc) | ||
348 | { | ||
349 | send_buffer_len[cur_buf_send] = 0; | ||
350 | return; | ||
351 | } | ||
352 | } | ||
353 | |||
354 | static void usb_hid_queue(unsigned char *data, int length) | ||
355 | { | ||
356 | if (!active || length <= 0) | ||
357 | return; | ||
358 | |||
359 | /* Buffer overflow - item still in use */ | ||
360 | if (send_buffer_len[cur_buf_prepare]) | ||
361 | return; | ||
362 | |||
363 | /* Prepare buffer for sending */ | ||
364 | if (length > HID_BUF_SIZE_MSG) | ||
365 | length = HID_BUF_SIZE_MSG; | ||
366 | memcpy(send_buffer[cur_buf_prepare], data, length); | ||
367 | send_buffer_len[cur_buf_prepare] = length; | ||
368 | |||
369 | HID_BUF_INC(cur_buf_prepare); | ||
370 | } | ||
371 | |||
372 | void usb_hid_send_consumer_usage(consumer_usage_page_t id) | ||
373 | { | ||
374 | static unsigned char buf[HID_BUF_SIZE_CMD] USB_DEVBSS_ATTR | ||
375 | __attribute__((aligned(32))); | ||
376 | unsigned char *dest = buf; | ||
377 | |||
378 | memset(buf, 0, sizeof(buf)); | ||
379 | |||
380 | logf("HID: Sending 0x%x", id); | ||
381 | |||
382 | pack_parameter(&dest, 0, id); | ||
383 | buf[0] = report_id; | ||
384 | |||
385 | /* Key pressed */ | ||
386 | usb_hid_queue(buf, HID_BUF_SIZE_CMD); | ||
387 | |||
388 | /* Key released */ | ||
389 | memset(buf, 0, sizeof(buf)); | ||
390 | buf[0] = report_id; | ||
391 | usb_hid_queue(buf, HID_BUF_SIZE_CMD); | ||
284 | 392 | ||
285 | logf("hid: send %d bytes: \"%s\"", length, data); | 393 | usb_hid_try_send_drv(); |
286 | } | 394 | } |
287 | 395 | ||
288 | #endif /*USB_HID*/ | 396 | #endif /*USB_HID*/ |
diff --git a/firmware/usbstack/usb_hid.h b/firmware/usbstack/usb_hid.h index ff2a33dcbf..bce6943a4d 100644 --- a/firmware/usbstack/usb_hid.h +++ b/firmware/usbstack/usb_hid.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #define USB_HID_H | 22 | #define USB_HID_H |
23 | 23 | ||
24 | #include "usb_ch9.h" | 24 | #include "usb_ch9.h" |
25 | #include "usb_hid_usage_tables.h" | ||
25 | 26 | ||
26 | int usb_hid_request_endpoints(struct usb_class_driver *drv); | 27 | int usb_hid_request_endpoints(struct usb_class_driver *drv); |
27 | int usb_hid_set_first_interface(int interface); | 28 | int usb_hid_set_first_interface(int interface); |
@@ -32,7 +33,7 @@ void usb_hid_disconnect(void); | |||
32 | void usb_hid_transfer_complete(int ep, int dir, int status, int length); | 33 | void usb_hid_transfer_complete(int ep, int dir, int status, int length); |
33 | bool usb_hid_control_request(struct usb_ctrlrequest* req, unsigned char* dest); | 34 | bool usb_hid_control_request(struct usb_ctrlrequest* req, unsigned char* dest); |
34 | 35 | ||
35 | void usb_hid_send(unsigned char *data,int length); | 36 | void usb_hid_send_consumer_usage(consumer_usage_page_t id); |
36 | 37 | ||
37 | #endif | 38 | #endif |
38 | 39 | ||
diff --git a/firmware/usbstack/usb_serial.c b/firmware/usbstack/usb_serial.c index 370afcb7f1..246938a1ef 100644 --- a/firmware/usbstack/usb_serial.c +++ b/firmware/usbstack/usb_serial.c | |||
@@ -77,11 +77,12 @@ static int usb_interface; | |||
77 | 77 | ||
78 | int usb_serial_request_endpoints(struct usb_class_driver *drv) | 78 | int usb_serial_request_endpoints(struct usb_class_driver *drv) |
79 | { | 79 | { |
80 | ep_in = usb_core_request_endpoint(USB_DIR_IN, drv); | 80 | ep_in = usb_core_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_IN, drv); |
81 | if (ep_in < 0) | 81 | if (ep_in < 0) |
82 | return -1; | 82 | return -1; |
83 | 83 | ||
84 | ep_out = usb_core_request_endpoint(USB_DIR_OUT, drv); | 84 | ep_out = usb_core_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_OUT, |
85 | drv); | ||
85 | if (ep_out < 0) { | 86 | if (ep_out < 0) { |
86 | usb_core_release_endpoint(ep_in); | 87 | usb_core_release_endpoint(ep_in); |
87 | return -1; | 88 | return -1; |
@@ -101,15 +102,15 @@ int usb_serial_get_config_descriptor(unsigned char *dest, int max_packet_size) | |||
101 | unsigned char *orig_dest = dest; | 102 | unsigned char *orig_dest = dest; |
102 | 103 | ||
103 | interface_descriptor.bInterfaceNumber = usb_interface; | 104 | interface_descriptor.bInterfaceNumber = usb_interface; |
104 | PACK_DESCRIPTOR(dest, interface_descriptor); | 105 | PACK_DATA(dest, interface_descriptor); |
105 | 106 | ||
106 | endpoint_descriptor.wMaxPacketSize = max_packet_size; | 107 | endpoint_descriptor.wMaxPacketSize = max_packet_size; |
107 | 108 | ||
108 | endpoint_descriptor.bEndpointAddress = ep_in; | 109 | endpoint_descriptor.bEndpointAddress = ep_in; |
109 | PACK_DESCRIPTOR(dest, endpoint_descriptor); | 110 | PACK_DATA(dest, endpoint_descriptor); |
110 | 111 | ||
111 | endpoint_descriptor.bEndpointAddress = ep_out; | 112 | endpoint_descriptor.bEndpointAddress = ep_out; |
112 | PACK_DESCRIPTOR(dest, endpoint_descriptor); | 113 | PACK_DATA(dest, endpoint_descriptor); |
113 | 114 | ||
114 | return (dest - orig_dest); | 115 | return (dest - orig_dest); |
115 | } | 116 | } |
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c index 464283551a..73176ee93e 100644 --- a/firmware/usbstack/usb_storage.c +++ b/firmware/usbstack/usb_storage.c | |||
@@ -349,12 +349,13 @@ void usb_storage_init(void) | |||
349 | 349 | ||
350 | int usb_storage_request_endpoints(struct usb_class_driver *drv) | 350 | int usb_storage_request_endpoints(struct usb_class_driver *drv) |
351 | { | 351 | { |
352 | ep_in = usb_core_request_endpoint(USB_DIR_IN, drv); | 352 | ep_in = usb_core_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_IN, drv); |
353 | 353 | ||
354 | if(ep_in<0) | 354 | if(ep_in<0) |
355 | return -1; | 355 | return -1; |
356 | 356 | ||
357 | ep_out = usb_core_request_endpoint(USB_DIR_OUT, drv); | 357 | ep_out = usb_core_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_OUT, |
358 | drv); | ||
358 | 359 | ||
359 | if(ep_out<0) { | 360 | if(ep_out<0) { |
360 | usb_core_release_endpoint(ep_in); | 361 | usb_core_release_endpoint(ep_in); |
@@ -375,15 +376,15 @@ int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size) | |||
375 | unsigned char *orig_dest = dest; | 376 | unsigned char *orig_dest = dest; |
376 | 377 | ||
377 | interface_descriptor.bInterfaceNumber = usb_interface; | 378 | interface_descriptor.bInterfaceNumber = usb_interface; |
378 | PACK_DESCRIPTOR(dest, interface_descriptor); | 379 | PACK_DATA(dest, interface_descriptor); |
379 | 380 | ||
380 | endpoint_descriptor.wMaxPacketSize = max_packet_size; | 381 | endpoint_descriptor.wMaxPacketSize = max_packet_size; |
381 | 382 | ||
382 | endpoint_descriptor.bEndpointAddress = ep_in; | 383 | endpoint_descriptor.bEndpointAddress = ep_in; |
383 | PACK_DESCRIPTOR(dest, endpoint_descriptor); | 384 | PACK_DATA(dest, endpoint_descriptor); |
384 | 385 | ||
385 | endpoint_descriptor.bEndpointAddress = ep_out; | 386 | endpoint_descriptor.bEndpointAddress = ep_out; |
386 | PACK_DESCRIPTOR(dest, endpoint_descriptor); | 387 | PACK_DATA(dest, endpoint_descriptor); |
387 | 388 | ||
388 | return (dest - orig_dest); | 389 | return (dest - orig_dest); |
389 | } | 390 | } |