blob: 22a81d38a3cc0be16638a9e1b6cd0299bb32f464 [file] [log] [blame]
Sylvain Munautbc9f5c42020-09-14 10:22:29 +02001/*
2 * usb_desc_app.c
3 *
4 * Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
5 * SPDX-License-Identifier: GPL-3.0-or-later
6 */
7
8#include <no2usb/usb_proto.h>
Sylvain Munautb9d93632021-05-31 14:03:44 +02009#include <no2usb/usb_cdc_proto.h>
Sylvain Munaut4ea7d272020-10-29 13:17:11 +010010#include <no2usb/usb_dfu_proto.h>
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020011#include <no2usb/usb.h>
12
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +010013#include "usb_desc_ids.h"
14
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020015#define NULL ((void*)0)
16#define num_elem(a) (sizeof(a) / sizeof(a[0]))
17
18
Sylvain Munautb9d93632021-05-31 14:03:44 +020019usb_cdc_union_desc_def(1);
20
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020021static const struct {
22 /* Configuration */
23 struct usb_conf_desc conf;
24
25 /* E1 */
26 struct {
Harald Welte30fc5602020-12-14 15:56:28 +010027 /* Two altsettings are required, as isochronous
28 * interfaces must have a setting where they don't
Sylvain Munaut96744362022-01-03 17:03:26 +010029 * transceive any data. We just remove the isochronous
30 * endpoints in the 'off' altsetting */
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020031 struct {
32 struct usb_intf_desc intf;
Harald Welte805f2cf2020-12-14 17:31:03 +010033 struct usb_ep_desc ep_interrupt;
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020034 } __attribute__ ((packed)) off;
35 struct {
36 struct usb_intf_desc intf;
37 struct usb_ep_desc ep_data_in;
38 struct usb_ep_desc ep_data_out;
39 struct usb_ep_desc ep_fb;
Harald Welte805f2cf2020-12-14 17:31:03 +010040 struct usb_ep_desc ep_interrupt;
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020041 } __attribute__ ((packed)) on;
Sylvain Munaut41c98b62022-01-05 21:11:35 +010042 } __attribute__ ((packed)) e1[2];
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020043
44 /* CDC */
45#if 0
46 struct {
47 struct usb_intf_desc intf_ctl;
Sylvain Munautb9d93632021-05-31 14:03:44 +020048 struct usb_cdc_hdr_desc cdc_hdr;
49 struct usb_cdc_acm_desc cdc_acm;
50 struct usb_cdc_union_desc__1 cdc_union;
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020051 struct usb_ep_desc ep_ctl;
52 struct usb_intf_desc intf_data;
53 struct usb_ep_desc ep_data_out;
54 struct usb_ep_desc ep_data_in;
55 } __attribute__ ((packed)) cdc;
56#endif
57
58 /* DFU Runtime */
59 struct {
60 struct usb_intf_desc intf;
Sylvain Munaut4ea7d272020-10-29 13:17:11 +010061 struct usb_dfu_func_desc func;
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020062 } __attribute__ ((packed)) dfu;
63} __attribute__ ((packed)) _app_conf_desc = {
64 .conf = {
65 .bLength = sizeof(struct usb_conf_desc),
66 .bDescriptorType = USB_DT_CONF,
67 .wTotalLength = sizeof(_app_conf_desc),
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +010068 .bNumInterfaces = USB_INTF_NUM,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020069 .bConfigurationValue = 1,
70 .iConfiguration = 4,
71 .bmAttributes = 0x80,
72 .bMaxPower = 0x32, /* 100 mA */
73 },
Sylvain Munaut41c98b62022-01-05 21:11:35 +010074 .e1[0] = {
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020075 .off = {
76 .intf = {
77 .bLength = sizeof(struct usb_intf_desc),
78 .bDescriptorType = USB_DT_INTF,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +010079 .bInterfaceNumber = USB_INTF_E1(0),
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020080 .bAlternateSetting = 0,
Sylvain Munaut96744362022-01-03 17:03:26 +010081 .bNumEndpoints = 1,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020082 .bInterfaceClass = 0xff,
83 .bInterfaceSubClass = 0xe1,
84 .bInterfaceProtocol = 0x00,
85 .iInterface = 5,
86 },
Harald Welte805f2cf2020-12-14 17:31:03 +010087 .ep_interrupt = {
88 .bLength = sizeof(struct usb_ep_desc),
89 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +010090 .bEndpointAddress = USB_EP_E1_INT(0),
Harald Welte805f2cf2020-12-14 17:31:03 +010091 .bmAttributes = 0x03,
92 .wMaxPacketSize = 10,
Sylvain Munaut1d987092022-01-05 21:04:09 +010093 .bInterval = 4, /* every 4 ms */
Harald Welte805f2cf2020-12-14 17:31:03 +010094 },
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020095 },
96 .on = {
97 .intf = {
98 .bLength = sizeof(struct usb_intf_desc),
99 .bDescriptorType = USB_DT_INTF,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100100 .bInterfaceNumber = USB_INTF_E1(0),
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200101 .bAlternateSetting = 1,
Harald Welte805f2cf2020-12-14 17:31:03 +0100102 .bNumEndpoints = 4,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200103 .bInterfaceClass = 0xff,
104 .bInterfaceSubClass = 0xe1,
105 .bInterfaceProtocol = 0x00,
Sylvain Munaut41c98b62022-01-05 21:11:35 +0100106 .iInterface = 6,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200107 },
108 .ep_data_in = {
109 .bLength = sizeof(struct usb_ep_desc),
110 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100111 .bEndpointAddress = USB_EP_E1_IN(0),
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200112 .bmAttributes = 0x05,
Sylvain Munaut1d987092022-01-05 21:04:09 +0100113 .wMaxPacketSize = 292,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200114 .bInterval = 1,
115 },
116 .ep_data_out = {
117 .bLength = sizeof(struct usb_ep_desc),
118 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100119 .bEndpointAddress = USB_EP_E1_OUT(0),
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200120 .bmAttributes = 0x05,
Sylvain Munaut1d987092022-01-05 21:04:09 +0100121 .wMaxPacketSize = 292,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200122 .bInterval = 1,
123 },
124 .ep_fb = {
125 .bLength = sizeof(struct usb_ep_desc),
126 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100127 .bEndpointAddress = USB_EP_E1_FB(0),
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200128 .bmAttributes = 0x11,
Sylvain Munaut1d987092022-01-05 21:04:09 +0100129 .wMaxPacketSize = 3,
130 .bInterval = 3, /* every 2^(3-1) = 4 ms */
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200131 },
Harald Welte805f2cf2020-12-14 17:31:03 +0100132 .ep_interrupt = {
133 .bLength = sizeof(struct usb_ep_desc),
134 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100135 .bEndpointAddress = USB_EP_E1_INT(0),
Harald Welte805f2cf2020-12-14 17:31:03 +0100136 .bmAttributes = 0x03,
137 .wMaxPacketSize = 10,
Sylvain Munaut1d987092022-01-05 21:04:09 +0100138 .bInterval = 4, /* every 4 ms */
Harald Welte805f2cf2020-12-14 17:31:03 +0100139 },
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200140 },
141 },
Sylvain Munaut41c98b62022-01-05 21:11:35 +0100142 .e1[1] = {
143 .off = {
144 .intf = {
145 .bLength = sizeof(struct usb_intf_desc),
146 .bDescriptorType = USB_DT_INTF,
147 .bInterfaceNumber = USB_INTF_E1(1),
148 .bAlternateSetting = 0,
149 .bNumEndpoints = 1,
150 .bInterfaceClass = 0xff,
151 .bInterfaceSubClass = 0xe1,
152 .bInterfaceProtocol = 0x00,
153 .iInterface = 7,
154 },
155 .ep_interrupt = {
156 .bLength = sizeof(struct usb_ep_desc),
157 .bDescriptorType = USB_DT_EP,
158 .bEndpointAddress = USB_EP_E1_INT(1),
159 .bmAttributes = 0x03,
160 .wMaxPacketSize = 10,
161 .bInterval = 4, /* every 4 ms */
162 },
163 },
164 .on = {
165 .intf = {
166 .bLength = sizeof(struct usb_intf_desc),
167 .bDescriptorType = USB_DT_INTF,
168 .bInterfaceNumber = USB_INTF_E1(1),
169 .bAlternateSetting = 1,
170 .bNumEndpoints = 4,
171 .bInterfaceClass = 0xff,
172 .bInterfaceSubClass = 0xe1,
173 .bInterfaceProtocol = 0x00,
174 .iInterface = 8,
175 },
176 .ep_data_in = {
177 .bLength = sizeof(struct usb_ep_desc),
178 .bDescriptorType = USB_DT_EP,
179 .bEndpointAddress = USB_EP_E1_IN(1),
180 .bmAttributes = 0x05,
181 .wMaxPacketSize = 292,
182 .bInterval = 1,
183 },
184 .ep_data_out = {
185 .bLength = sizeof(struct usb_ep_desc),
186 .bDescriptorType = USB_DT_EP,
187 .bEndpointAddress = USB_EP_E1_OUT(1),
188 .bmAttributes = 0x05,
189 .wMaxPacketSize = 292,
190 .bInterval = 1,
191 },
192 .ep_fb = {
193 .bLength = sizeof(struct usb_ep_desc),
194 .bDescriptorType = USB_DT_EP,
195 .bEndpointAddress = USB_EP_E1_FB(1),
196 .bmAttributes = 0x11,
197 .wMaxPacketSize = 3,
198 .bInterval = 3, /* every 2^(3-1) = 4 ms */
199 },
200 .ep_interrupt = {
201 .bLength = sizeof(struct usb_ep_desc),
202 .bDescriptorType = USB_DT_EP,
203 .bEndpointAddress = USB_EP_E1_INT(1),
204 .bmAttributes = 0x03,
205 .wMaxPacketSize = 10,
206 .bInterval = 4, /* every 4 ms */
207 },
208 },
209 },
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200210#if 0
211 .cdc = {
212 .intf_ctl = {
213 .bLength = sizeof(struct usb_intf_desc),
214 .bDescriptorType = USB_DT_INTF,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100215 .bInterfaceNumber = USB_INTF_GPS_CDC_CTL,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200216 .bAlternateSetting = 0,
217 .bNumEndpoints = 1,
Sylvain Munautb9d93632021-05-31 14:03:44 +0200218 .bInterfaceClass = USB_CLS_CDC_CONTROL,
219 .bInterfaceSubClass = USB_CDC_SCLS_ACM,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200220 .bInterfaceProtocol = 0x00,
Sylvain Munaut41c98b62022-01-05 21:11:35 +0100221 .iInterface = 9,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200222 },
Sylvain Munautb9d93632021-05-31 14:03:44 +0200223 .cdc_hdr = {
224 .bLength = sizeof(struct usb_cdc_hdr_desc),
225 .bDescriptorType = USB_CS_DT_INTF,
226 .bDescriptorsubtype = USB_CDC_DST_HEADER,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200227 .bcdCDC = 0x0110,
228 },
Sylvain Munautb9d93632021-05-31 14:03:44 +0200229 .cdc_acm = {
230 .bLength = sizeof(struct usb_cdc_acm_desc),
231 .bDescriptorType = USB_CS_DT_INTF,
232 .bDescriptorsubtype = USB_CDC_DST_ACM,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200233 .bmCapabilities = 0x02,
234 },
Sylvain Munautb9d93632021-05-31 14:03:44 +0200235 .cdc_union = {
236 .bLength = sizeof(struct usb_cdc_union_desc) + 1,
237 .bDescriptorType = USB_CS_DT_INTF,
238 .bDescriptorsubtype = USB_CDC_DST_UNION,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200239 .bMasterInterface = 1,
Sylvain Munautb9d93632021-05-31 14:03:44 +0200240 .bSlaveInterface = { 2 },
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200241 },
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200242 .ep_ctl = {
243 .bLength = sizeof(struct usb_ep_desc),
244 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100245 .bEndpointAddress = USB_EP_GPS_CDC_CTL,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200246 .bmAttributes = 0x03,
247 .wMaxPacketSize = 64,
248 .bInterval = 0x40,
249 },
250 .intf_data = {
251 .bLength = sizeof(struct usb_intf_desc),
252 .bDescriptorType = USB_DT_INTF,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100253 .bInterfaceNumber = USB_INTF_GPS_CDC_DATA,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200254 .bAlternateSetting = 0,
255 .bNumEndpoints = 2,
Sylvain Munautb9d93632021-05-31 14:03:44 +0200256 .bInterfaceClass = USB_CLS_CDC_DATA,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200257 .bInterfaceSubClass = 0x00,
258 .bInterfaceProtocol = 0x00,
Sylvain Munaut41c98b62022-01-05 21:11:35 +0100259 .iInterface = 10,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200260 },
261 .ep_data_out = {
262 .bLength = sizeof(struct usb_ep_desc),
263 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100264 .bEndpointAddress = USB_EP_GPS_CDC_OUT,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200265 .bmAttributes = 0x02,
266 .wMaxPacketSize = 64,
267 .bInterval = 0x00,
268 },
269 .ep_data_in = {
270 .bLength = sizeof(struct usb_ep_desc),
271 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100272 .bEndpointAddress = USB_EP_GPS_CDC_IN,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200273 .bmAttributes = 0x02,
274 .wMaxPacketSize = 64,
275 .bInterval = 0x00,
276 },
277 },
278#endif
279 .dfu = {
280 .intf = {
281 .bLength = sizeof(struct usb_intf_desc),
282 .bDescriptorType = USB_DT_INTF,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100283 .bInterfaceNumber = USB_INTF_DFU,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200284 .bAlternateSetting = 0,
285 .bNumEndpoints = 0,
286 .bInterfaceClass = 0xfe,
287 .bInterfaceSubClass = 0x01,
288 .bInterfaceProtocol = 0x01,
Sylvain Munaut41c98b62022-01-05 21:11:35 +0100289 .iInterface = 11,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200290 },
291 .func = {
Sylvain Munaut4ea7d272020-10-29 13:17:11 +0100292 .bLength = sizeof(struct usb_dfu_func_desc),
293 .bDescriptorType = USB_DFU_DT_FUNC,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200294 .bmAttributes = 0x0d,
Sylvain Munaut3c3ae792022-01-05 20:55:37 +0100295 .wDetachTimeOut = 0,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200296 .wTransferSize = 4096,
297 .bcdDFUVersion = 0x0101,
298 },
299 },
300};
301
302static const struct usb_conf_desc * const _conf_desc_array[] = {
303 &_app_conf_desc.conf,
304};
305
306static const struct usb_dev_desc _dev_desc = {
307 .bLength = sizeof(struct usb_dev_desc),
308 .bDescriptorType = USB_DT_DEV,
309 .bcdUSB = 0x0200,
310 .bDeviceClass = 0,
311 .bDeviceSubClass = 0,
312 .bDeviceProtocol = 0,
313 .bMaxPacketSize0 = 64,
314 .idVendor = 0x1d50,
315 .idProduct = 0x6145,
316 .bcdDevice = 0x0003, /* v0.3 */
317 .iManufacturer = 2,
318 .iProduct = 3,
319 .iSerialNumber = 1,
320 .bNumConfigurations = num_elem(_conf_desc_array),
321};
322
323#include "usb_str_app.gen.h"
324
325const struct usb_stack_descriptors app_stack_desc = {
326 .dev = &_dev_desc,
327 .conf = _conf_desc_array,
328 .n_conf = num_elem(_conf_desc_array),
329 .str = _str_desc_array,
330 .n_str = num_elem(_str_desc_array),
331};