diff options
Diffstat (limited to 'firmware/usbstack')
-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 |
7 files changed, 265 insertions, 154 deletions
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 | } |