dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pios_usb_desc_hid_cdc.c
Go to the documentation of this file.
1 
16 /*
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation; either version 3 of the License, or
20  * (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful, but
23  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25  * for more details.
26  *
27  * You should have received a copy of the GNU General Public License along
28  * with this program; if not, see <http://www.gnu.org/licenses/>
29  */
30 
31 #include "pios_usb_desc_hid_cdc_priv.h" /* exported API */
32 #include "pios_usb_defs.h" /* struct usb_*, USB_* */
33 #include "pios_usb_board_data.h" /* PIOS_USB_BOARD_* */
34 #include "pios_usbhook.h" /* PIOS_USBHOOK_Register* */
35 #include "pios_usb_hid.h" /* PIOS_USB_HID_Register* */
36 
37 static const struct usb_device_desc device_desc = {
38  .bLength = sizeof(struct usb_device_desc),
39  .bDescriptorType = USB_DESC_TYPE_DEVICE,
40  .bcdUSB = htousbs(0x0200),
41  .bDeviceClass = 0xef,
42  .bDeviceSubClass = 0x02,
43  .bDeviceProtocol = 0x01,
44  .bMaxPacketSize0 = 64, /* Must be 64 for high-speed devices */
45  .idVendor = htousbs(PIOS_USB_BOARD_VENDOR_ID),
46  .idProduct = htousbs(PIOS_USB_BOARD_PRODUCT_ID),
47  .bcdDevice = htousbs(PIOS_USB_BOARD_DEVICE_VER),
48  .iManufacturer = USB_STRING_DESC_VENDOR,
49  .iProduct = USB_STRING_DESC_PRODUCT,
50  .iSerialNumber = USB_STRING_DESC_SERIAL,
51  .bNumConfigurations = 1,
52 };
53 
54 static const uint8_t hid_report_desc[] = {
56  0x9C, 0xFF, /* Usage Page 0xFF9C (Vendor Defined) */
58  0x01, /* Usage ID 0x0001 (0x01-0x1F uaually for top-level collections) */
59 
61  0x01, /* Application */
62 
63  /* Device -> Host emulated serial channel */
65  0x01, /* OpenPilot emulated serial channel (Device -> Host) */
67  0x02,
69  0x00, /* Values range from min = 0x00 */
71  0xFF, /* Values range to max = 0xFF */
73  0x08, /* 8 bits wide */
75  PIOS_USB_BOARD_HID_DATA_LENGTH-1, /* Need to leave room for a report ID */
77  0x03, /* Variable, Constant (read-only) */
78 
79  /* Host -> Host emulated serial channel */
81  0x02, /* OpenPilot emulated Serial Channel (Host -> Device) */
83  0x02,
85  0x00, /* Values range from min = 0x00 */
87  0xFF, /* Values range to max = 0xFF */
89  0x08, /* 8 bits wide */
91  PIOS_USB_BOARD_HID_DATA_LENGTH-1, /* Need to leave room for a report ID */
93  0x82, /* Volatile, Variable */
94 
96 
97 /* 36 bytes to here */
98 };
99 
116 } __attribute__((packed));
117 
118 static const struct usb_config_hid_cdc config_hid_cdc = {
119  .config = {
120  .bLength = sizeof(struct usb_configuration_desc),
121  .bDescriptorType = USB_DESC_TYPE_CONFIGURATION,
122  .wTotalLength = htousbs(sizeof(struct usb_config_hid_cdc)),
123  .bNumInterfaces = 3,
124  .bConfigurationValue = 1,
125  .iConfiguration = 0,
126  .bmAttributes = 0xC0,
127  .bMaxPower = 250/2, /* in units of 2ma */
128  },
129  .iad = {
130  .bLength = sizeof(struct usb_interface_association_desc),
131  .bDescriptorType = USB_DESC_TYPE_IAD,
132  .bFirstInterface = 0,
133  .bInterfaceCount = 2,
134  .bFunctionClass = USB_INTERFACE_CLASS_CDC, /* Communication */
135  .bFunctionSubClass = USB_CDC_DESC_SUBTYPE_ABSTRACT_CTRL, /* Abstract Control Model */
136  .bFunctionProtocol = 1, /* V.25ter, Common AT commands */
137  .iInterface = 0,
138  },
139  .cdc_control_if = {
140  .bLength = sizeof(struct usb_interface_desc),
141  .bDescriptorType = USB_DESC_TYPE_INTERFACE,
142  .bInterfaceNumber = 0,
143  .bAlternateSetting = 0,
144  .bNumEndpoints = 1,
145  .bInterfaceClass = USB_INTERFACE_CLASS_CDC,
146  .bInterfaceSubClass = USB_CDC_DESC_SUBTYPE_ABSTRACT_CTRL, /* Abstract Control Model */
147  .nInterfaceProtocol = 1, /* V.25ter, Common AT commands */
148  .iInterface = 0,
149  },
150  .cdc_header = {
151  .bLength = sizeof(struct usb_cdc_header_func_desc),
152  .bDescriptorType = USB_DESC_TYPE_CLASS_SPECIFIC,
153  .bDescriptorSubType = USB_CDC_DESC_SUBTYPE_HEADER,
154  .bcdCDC = htousbs(0x0110),
155  },
156  .cdc_callmgmt = {
157  .bLength = sizeof(struct usb_cdc_callmgmt_func_desc),
158  .bDescriptorType = USB_DESC_TYPE_CLASS_SPECIFIC,
159  .bDescriptorSubType = USB_CDC_DESC_SUBTYPE_CALLMGMT,
160  .bmCapabilities = 0x00, /* No call handling */
161  .bDataInterface = 1,
162  },
163  .cdc_acm = {
164  .bLength = sizeof(struct usb_cdc_acm_func_desc),
165  .bDescriptorType = USB_DESC_TYPE_CLASS_SPECIFIC,
166  .bDescriptorSubType = USB_CDC_DESC_SUBTYPE_ABSTRACT_CTRL,
167  .bmCapabilities = 0x02, /* line coding and serial state */
168  },
169  .cdc_union = {
170  .bLength = sizeof(struct usb_cdc_union_func_desc),
171  .bDescriptorType = USB_DESC_TYPE_CLASS_SPECIFIC,
172  .bDescriptorSubType = USB_CDC_DESC_SUBTYPE_UNION,
173  .bMasterInterface = 0,
174  .bSlaveInterface = 1,
175  },
176  .cdc_mgmt_in = {
177  .bLength = sizeof(struct usb_endpoint_desc),
178  .bDescriptorType = USB_DESC_TYPE_ENDPOINT,
179  .bEndpointAddress = USB_EP_IN(2),
180  .bmAttributes = USB_EP_ATTR_TT_INTERRUPT,
181  .wMaxPacketSize = htousbs(PIOS_USB_BOARD_CDC_MGMT_LENGTH),
182  .bInterval = 4, /* ms */
183  },
184  .cdc_data_if = {
185  .bLength = sizeof(struct usb_interface_desc),
186  .bDescriptorType = USB_DESC_TYPE_INTERFACE,
187  .bInterfaceNumber = 1,
188  .bAlternateSetting = 0,
189  .bNumEndpoints = 2,
190  .bInterfaceClass = USB_INTERFACE_CLASS_DATA,
191  .bInterfaceSubClass = 0,
192  .nInterfaceProtocol = 0, /* No class specific protocol */
193  .iInterface = 0,
194  },
195  .cdc_in = {
196  .bLength = sizeof(struct usb_endpoint_desc),
197  .bDescriptorType = USB_DESC_TYPE_ENDPOINT,
198  .bEndpointAddress = USB_EP_IN(3),
199  .bmAttributes = USB_EP_ATTR_TT_BULK,
200  .wMaxPacketSize = htousbs(PIOS_USB_BOARD_CDC_DATA_LENGTH),
201  .bInterval = 0, /* ms */
202  },
203  .cdc_out = {
204  .bLength = sizeof(struct usb_endpoint_desc),
205  .bDescriptorType = USB_DESC_TYPE_ENDPOINT,
206  .bEndpointAddress = USB_EP_OUT(3),
207  .bmAttributes = USB_EP_ATTR_TT_BULK, /* Bulk */
208  .wMaxPacketSize = htousbs(PIOS_USB_BOARD_CDC_DATA_LENGTH),
209  .bInterval = 0, /* ms */
210  },
211  .hid_if = {
212  .bLength = sizeof(struct usb_interface_desc),
213  .bDescriptorType = USB_DESC_TYPE_INTERFACE,
214  .bInterfaceNumber = 2,
215  .bAlternateSetting = 0,
216  .bNumEndpoints = 2,
217  .bInterfaceClass = USB_INTERFACE_CLASS_HID,
218  .bInterfaceSubClass = 0, /* no boot */
219  .nInterfaceProtocol = 0, /* none */
220  .iInterface = 0,
221  },
222  .hid = {
223  .bLength = sizeof(struct usb_hid_desc),
224  .bDescriptorType = USB_DESC_TYPE_HID,
225  .bcdHID = htousbs(0x0110),
226  .bCountryCode = 0,
227  .bNumDescriptors = 1,
228  .bClassDescriptorType = USB_DESC_TYPE_REPORT,
229  .wItemLength = htousbs(sizeof(hid_report_desc)),
230  },
231  .hid_in = {
232  .bLength = sizeof(struct usb_endpoint_desc),
233  .bDescriptorType = USB_DESC_TYPE_ENDPOINT,
234  .bEndpointAddress = USB_EP_IN(1),
235  .bmAttributes = USB_EP_ATTR_TT_INTERRUPT,
236  .wMaxPacketSize = htousbs(PIOS_USB_BOARD_HID_DATA_LENGTH),
237  .bInterval = 4, /* ms */
238  },
239  .hid_out = {
240  .bLength = sizeof(struct usb_endpoint_desc),
241  .bDescriptorType = USB_DESC_TYPE_ENDPOINT,
242  .bEndpointAddress = USB_EP_OUT(1),
243  .bmAttributes = USB_EP_ATTR_TT_INTERRUPT,
244  .wMaxPacketSize = htousbs(PIOS_USB_BOARD_HID_DATA_LENGTH),
245  .bInterval = 4, /* ms */
246  },
247 };
248 
250 {
251  PIOS_USBHOOK_RegisterConfig(1, (uint8_t *)&config_hid_cdc, sizeof(config_hid_cdc));
252 
253  PIOS_USBHOOK_RegisterDevice((uint8_t *)&device_desc, sizeof(device_desc));
254 
255  PIOS_USB_HID_RegisterHidDescriptor((uint8_t *)&(config_hid_cdc.hid), sizeof(config_hid_cdc.hid));
257 
258  return 0;
259 }
USB_CDC_DESC_SUBTYPE_ABSTRACT_CTRL
Definition: pios_usb_defs.h:43
static const struct usb_device_desc device_desc
#define HID_TAG_GLOBAL_REPORT_ID
Definition: pios_usb_defs.h:97
int32_t PIOS_USB_DESC_HID_CDC_Init(void)
struct usb_cdc_header_func_desc cdc_header
struct usb_endpoint_desc hid_out
USB_INTERFACE_CLASS_CDC
Definition: pios_usb_defs.h:41
#define PIOS_USB_BOARD_VENDOR_ID
USB_DESC_TYPE_CLASS_SPECIFIC
Definition: pios_usb_defs.h:49
#define USB_EP_OUT(ep)
Definition: pios_usb_defs.h:82
USB_DESC_TYPE_IAD
Definition: pios_usb_defs.h:46
struct usb_configuration_desc config
APIs for PIOS_USBHOOK layer.
#define HID_TAG_LOCAL_USAGE
static const uint8_t hid_report_desc[]
#define HID_TAG_GLOBAL_LOGICAL_MAX
Definition: pios_usb_defs.h:91
struct usb_endpoint_desc hid_in
USB HID layer functions header.
#define USB_EP_IN(ep)
Definition: pios_usb_defs.h:81
USB_CDC_DESC_SUBTYPE_HEADER
Definition: pios_usb_defs.h:41
Defines the API to set up the HID + CDC USB descriptor config.
#define PIOS_USB_BOARD_DEVICE_VER
struct usb_endpoint_desc cdc_in
USB_EP_ATTR_TT_BULK
Definition: pios_usb_defs.h:43
USB_STRING_DESC_VENDOR
Definition: pios_usbhook.h:37
USB_STRING_DESC_SERIAL
Definition: pios_usbhook.h:39
#define PIOS_USB_BOARD_CDC_MGMT_LENGTH
struct usb_interface_desc cdc_control_if
#define HID_LOCAL_ITEM_1(tag)
USB_EP_ATTR_TT_INTERRUPT
Definition: pios_usb_defs.h:44
#define htousbs(v)
Definition: pios_usb_defs.h:77
USB_CDC_DESC_SUBTYPE_CALLMGMT
Definition: pios_usb_defs.h:42
#define HID_TAG_MAIN_INPUT
#define HID_TAG_GLOBAL_REPORT_SIZE
Definition: pios_usb_defs.h:96
USB_DESC_TYPE_CONFIGURATION
Definition: pios_usb_defs.h:42
struct usb_endpoint_desc cdc_mgmt_in
struct usb_config_hid_cdc __attribute__((packed))
Definition: serial_4way.h:38
USB_DESC_TYPE_REPORT
Definition: pios_usb_defs.h:48
USB_CDC_DESC_SUBTYPE_UNION
Definition: pios_usb_defs.h:44
USB_DESC_TYPE_HID
Definition: pios_usb_defs.h:47
USB_INTERFACE_CLASS_HID
Definition: pios_usb_defs.h:42
#define HID_GLOBAL_ITEM_2(tag)
void PIOS_USBHOOK_RegisterConfig(uint8_t config_id, const uint8_t *desc, uint16_t desc_size)
Definition: pios_usbhook.c:52
USB_STRING_DESC_PRODUCT
Definition: pios_usbhook.h:38
#define PIOS_USB_BOARD_PRODUCT_ID
#define HID_TAG_GLOBAL_LOGICAL_MIN
Definition: pios_usb_defs.h:90
struct usb_interface_association_desc iad
#define HID_GLOBAL_ITEM_1(tag)
struct usb_endpoint_desc cdc_out
USB_INTERFACE_CLASS_DATA
Definition: pios_usb_defs.h:43
void PIOS_USBHOOK_RegisterDevice(const uint8_t *desc, uint16_t desc_size)
Definition: pios_usbhook.c:44
#define HID_TAG_MAIN_COLLECTION
#define PIOS_USB_BOARD_HID_DATA_LENGTH
void PIOS_USB_HID_RegisterHidReport(const uint8_t *desc, uint16_t length)
Definition: pios_usbhook.c:78
#define HID_TAG_MAIN_OUTPUT
struct usb_cdc_union_func_desc cdc_union
#define HID_MAIN_ITEM_1(tag)
struct usb_cdc_acm_func_desc cdc_acm
void PIOS_USB_HID_RegisterHidDescriptor(const uint8_t *desc, uint16_t length)
Definition: pios_usbhook.c:70
struct usb_interface_desc cdc_data_if
#define PIOS_USB_BOARD_CDC_DATA_LENGTH
USB_DESC_TYPE_DEVICE
Definition: pios_usb_defs.h:41
#define HID_TAG_GLOBAL_REPORT_CNT
Definition: pios_usb_defs.h:98
USB_DESC_TYPE_INTERFACE
Definition: pios_usb_defs.h:44
USB_DESC_TYPE_ENDPOINT
Definition: pios_usb_defs.h:45
#define HID_TAG_MAIN_ENDCOLLECTION
#define HID_TAG_GLOBAL_USAGE_PAGE
Definition: pios_usb_defs.h:89
#define HID_MAIN_ITEM_0(tag)
struct usb_cdc_callmgmt_func_desc cdc_callmgmt
struct usb_hid_desc hid
struct usb_interface_desc hid_if
static const struct usb_config_hid_cdc config_hid_cdc