Cleanup of config/includes.
[openocd.git] / src / jtag / drivers / cmsis_dap_usb_bulk.c
1 /***************************************************************************
2 * Copyright (C) 2018 by Mickaƫl Thomas *
3 * mickael9@gmail.com *
4 * *
5 * Copyright (C) 2016 by Maksym Hilliaka *
6 * oter@frozen-team.com *
7 * *
8 * Copyright (C) 2016 by Phillip Pearson *
9 * pp@myelin.co.nz *
10 * *
11 * Copyright (C) 2014 by Paul Fertser *
12 * fercerpav@gmail.com *
13 * *
14 * Copyright (C) 2013 by mike brown *
15 * mike@theshedworks.org.uk *
16 * *
17 * Copyright (C) 2013 by Spencer Oliver *
18 * spen@spen-soft.co.uk *
19 * *
20 * This program is free software; you can redistribute it and/or modify *
21 * it under the terms of the GNU General Public License as published by *
22 * the Free Software Foundation; either version 2 of the License, or *
23 * (at your option) any later version. *
24 * *
25 * This program is distributed in the hope that it will be useful, *
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
28 * GNU General Public License for more details. *
29 * *
30 * You should have received a copy of the GNU General Public License *
31 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
32 ***************************************************************************/
33
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37
38 #include <helper/system.h>
39 #include <libusb.h>
40 #include <helper/log.h>
41 #include <helper/replacements.h>
42
43 #include "cmsis_dap.h"
44
45 struct cmsis_dap_backend_data {
46 struct libusb_context *usb_ctx;
47 struct libusb_device_handle *dev_handle;
48 unsigned int ep_out;
49 unsigned int ep_in;
50 int interface;
51 };
52
53 static int cmsis_dap_usb_interface = -1;
54
55 static void cmsis_dap_usb_close(struct cmsis_dap *dap);
56 static int cmsis_dap_usb_alloc(struct cmsis_dap *dap, unsigned int pkt_sz);
57
58 static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], char *serial)
59 {
60 int err;
61 struct libusb_context *ctx;
62 struct libusb_device **device_list;
63
64 err = libusb_init(&ctx);
65 if (err) {
66 LOG_ERROR("libusb initialization failed: %s", libusb_strerror(err));
67 return ERROR_FAIL;
68 }
69
70 int num_devices = libusb_get_device_list(ctx, &device_list);
71 if (num_devices < 0) {
72 LOG_ERROR("could not enumerate USB devices: %s", libusb_strerror(num_devices));
73 libusb_exit(ctx);
74 return ERROR_FAIL;
75 }
76
77 for (int i = 0; i < num_devices; i++) {
78 struct libusb_device *dev = device_list[i];
79 struct libusb_device_descriptor dev_desc;
80
81 err = libusb_get_device_descriptor(dev, &dev_desc);
82 if (err) {
83 LOG_ERROR("could not get device descriptor for device %d: %s", i, libusb_strerror(err));
84 continue;
85 }
86
87 /* Match VID/PID */
88
89 bool id_match = false;
90 bool id_filter = vids[0] || pids[0];
91 for (int id = 0; vids[id] || pids[id]; id++) {
92 id_match = !vids[id] || dev_desc.idVendor == vids[id];
93 id_match &= !pids[id] || dev_desc.idProduct == pids[id];
94
95 if (id_match)
96 break;
97 }
98
99 if (id_filter && !id_match)
100 continue;
101
102 /* Don't continue if we asked for a serial number and the device doesn't have one */
103 if (dev_desc.iSerialNumber == 0 && serial && serial[0])
104 continue;
105
106 struct libusb_device_handle *dev_handle = NULL;
107 err = libusb_open(dev, &dev_handle);
108 if (err) {
109 /* It's to be expected that most USB devices can't be opened
110 * so only report an error if it was explicitly selected
111 */
112 if (id_filter) {
113 LOG_ERROR("could not open device 0x%04x:0x%04x: %s",
114 dev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));
115 } else {
116 LOG_DEBUG("could not open device 0x%04x:0x%04x: %s",
117 dev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));
118 }
119 continue;
120 }
121
122 /* Match serial number */
123
124 bool serial_match = false;
125 char dev_serial[256] = {0};
126 if (dev_desc.iSerialNumber > 0) {
127 err = libusb_get_string_descriptor_ascii(
128 dev_handle, dev_desc.iSerialNumber,
129 (uint8_t *)dev_serial, sizeof(dev_serial));
130
131 if (err < 0) {
132 const char *msg = "could not read serial number for device 0x%04x:0x%04x: %s";
133 if (serial)
134 LOG_WARNING(msg, dev_desc.idVendor, dev_desc.idProduct,
135 libusb_strerror(err));
136 else
137 LOG_DEBUG(msg, dev_desc.idVendor, dev_desc.idProduct,
138 libusb_strerror(err));
139 } else if (serial && strncmp(dev_serial, serial, sizeof(dev_serial)) == 0) {
140 serial_match = true;
141 }
142 }
143
144 if (serial && !serial_match) {
145 libusb_close(dev_handle);
146 continue;
147 }
148
149 /* Find the CMSIS-DAP string in product string */
150
151 bool cmsis_dap_in_product_str = false;
152 char product_string[256] = {0};
153 if (dev_desc.iProduct > 0) {
154 err = libusb_get_string_descriptor_ascii(
155 dev_handle, dev_desc.iProduct,
156 (uint8_t *)product_string, sizeof(product_string));
157 if (err < 0) {
158 LOG_WARNING("could not read product string for device 0x%04x:0x%04x: %s",
159 dev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));
160 } else if (strstr(product_string, "CMSIS-DAP")) {
161 LOG_DEBUG("found product string of 0x%04x:0x%04x '%s'",
162 dev_desc.idVendor, dev_desc.idProduct, product_string);
163 cmsis_dap_in_product_str = true;
164 }
165 }
166
167 bool device_identified_reliably = cmsis_dap_in_product_str
168 || serial_match || id_match;
169
170 /* Find the CMSIS-DAP interface */
171
172 for (int config = 0; config < dev_desc.bNumConfigurations; config++) {
173 struct libusb_config_descriptor *config_desc;
174 err = libusb_get_config_descriptor(dev, config, &config_desc);
175 if (err) {
176 LOG_ERROR("could not get configuration descriptor %d for device 0x%04x:0x%04x: %s",
177 config, dev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));
178 continue;
179 }
180
181 LOG_DEBUG("enumerating interfaces of 0x%04x:0x%04x",
182 dev_desc.idVendor, dev_desc.idProduct);
183 int config_num = config_desc->bConfigurationValue;
184 const struct libusb_interface_descriptor *intf_desc_candidate = NULL;
185 const struct libusb_interface_descriptor *intf_desc_found = NULL;
186
187 for (int interface = 0; interface < config_desc->bNumInterfaces; interface++) {
188 const struct libusb_interface_descriptor *intf_desc = &config_desc->interface[interface].altsetting[0];
189 int interface_num = intf_desc->bInterfaceNumber;
190
191 /* Skip this interface if another one was requested explicitly */
192 if (cmsis_dap_usb_interface != -1 && cmsis_dap_usb_interface != interface_num)
193 continue;
194
195 /* CMSIS-DAP v2 spec says:
196 *
197 * CMSIS-DAP with default V2 configuration uses WinUSB and is therefore faster.
198 * Optionally support for streaming SWO trace is provided via an additional USB endpoint.
199 *
200 * The WinUSB configuration requires custom class support with the interface setting
201 * Class Code: 0xFF (Vendor specific)
202 * Subclass: 0x00
203 * Protocol code: 0x00
204 *
205 * Depending on the configuration it uses the following USB endpoints which should be configured
206 * in the interface descriptor in this order:
207 * - Endpoint 1: Bulk Out ā€“ used for commands received from host PC.
208 * - Endpoint 2: Bulk In ā€“ used for responses send to host PC.
209 * - Endpoint 3: Bulk In (optional) ā€“ used for streaming SWO trace (if enabled with SWO_STREAM).
210 */
211
212 /* Search for "CMSIS-DAP" in the interface string */
213 bool cmsis_dap_in_interface_str = false;
214 if (intf_desc->iInterface != 0) {
215
216 char interface_str[256] = {0};
217
218 err = libusb_get_string_descriptor_ascii(
219 dev_handle, intf_desc->iInterface,
220 (uint8_t *)interface_str, sizeof(interface_str));
221 if (err < 0) {
222 LOG_DEBUG("could not read interface string %d for device 0x%04x:0x%04x: %s",
223 intf_desc->iInterface,
224 dev_desc.idVendor, dev_desc.idProduct,
225 libusb_strerror(err));
226 } else if (strstr(interface_str, "CMSIS-DAP")) {
227 cmsis_dap_in_interface_str = true;
228 LOG_DEBUG("found interface %d string '%s'",
229 interface_num, interface_str);
230 }
231 }
232
233 /* Bypass the following check if this interface was explicitly requested. */
234 if (cmsis_dap_usb_interface == -1) {
235 if (!cmsis_dap_in_product_str && !cmsis_dap_in_interface_str)
236 continue;
237 }
238
239 /* check endpoints */
240 if (intf_desc->bNumEndpoints < 2) {
241 LOG_DEBUG("skipping interface %d, has only %d endpoints",
242 interface_num, intf_desc->bNumEndpoints);
243 continue;
244 }
245
246 if ((intf_desc->endpoint[0].bmAttributes & 3) != LIBUSB_TRANSFER_TYPE_BULK ||
247 (intf_desc->endpoint[0].bEndpointAddress & 0x80) != LIBUSB_ENDPOINT_OUT) {
248 LOG_DEBUG("skipping interface %d, endpoint[0] is not bulk out",
249 interface_num);
250 continue;
251 }
252
253 if ((intf_desc->endpoint[1].bmAttributes & 3) != LIBUSB_TRANSFER_TYPE_BULK ||
254 (intf_desc->endpoint[1].bEndpointAddress & 0x80) != LIBUSB_ENDPOINT_IN) {
255 LOG_DEBUG("skipping interface %d, endpoint[1] is not bulk in",
256 interface_num);
257 continue;
258 }
259
260 /* We can rely on the interface is really CMSIS-DAP if
261 * - we've seen CMSIS-DAP in the interface string
262 * - config asked explicitly for an interface number
263 * - the device has only one interface
264 * The later two cases should be honored only if we know
265 * we are on the rigt device */
266 bool intf_identified_reliably = cmsis_dap_in_interface_str
267 || (device_identified_reliably &&
268 (cmsis_dap_usb_interface != -1
269 || config_desc->bNumInterfaces == 1));
270
271 if (intf_desc->bInterfaceClass != LIBUSB_CLASS_VENDOR_SPEC ||
272 intf_desc->bInterfaceSubClass != 0 || intf_desc->bInterfaceProtocol != 0) {
273 /* If the interface is reliably identified
274 * then we need not insist on setting USB class, subclass and protocol
275 * exactly as the specification requires.
276 * At least KitProg3 uses class 0 contrary to the specification */
277 if (intf_identified_reliably) {
278 LOG_WARNING("Using CMSIS-DAPv2 interface %d with wrong class %" PRId8
279 " subclass %" PRId8 " or protocol %" PRId8,
280 interface_num,
281 intf_desc->bInterfaceClass,
282 intf_desc->bInterfaceSubClass,
283 intf_desc->bInterfaceProtocol);
284 } else {
285 LOG_DEBUG("skipping interface %d, class %" PRId8
286 " subclass %" PRId8 " protocol %" PRId8,
287 interface_num,
288 intf_desc->bInterfaceClass,
289 intf_desc->bInterfaceSubClass,
290 intf_desc->bInterfaceProtocol);
291 continue;
292
293 }
294 }
295
296 if (intf_identified_reliably) {
297 /* That's the one! */
298 intf_desc_found = intf_desc;
299 break;
300 }
301
302 if (!intf_desc_candidate && device_identified_reliably) {
303 /* This interface looks suitable for CMSIS-DAP. Store the pointer to it
304 * and keep searching for another one with CMSIS-DAP in interface string */
305 intf_desc_candidate = intf_desc;
306 }
307 }
308
309 if (!intf_desc_found) {
310 /* We were not able to identify reliably which interface is CMSIS-DAP.
311 * Let's use the first suitable if we found one */
312 intf_desc_found = intf_desc_candidate;
313 }
314
315 if (!intf_desc_found) {
316 libusb_free_config_descriptor(config_desc);
317 continue;
318 }
319
320 /* We've chosen an interface, connect to it */
321 int interface_num = intf_desc_found->bInterfaceNumber;
322 int packet_size = intf_desc_found->endpoint[0].wMaxPacketSize;
323 int ep_out = intf_desc_found->endpoint[0].bEndpointAddress;
324 int ep_in = intf_desc_found->endpoint[1].bEndpointAddress;
325
326 libusb_free_config_descriptor(config_desc);
327 libusb_free_device_list(device_list, true);
328
329 LOG_INFO("Using CMSIS-DAPv2 interface with VID:PID=0x%04x:0x%04x, serial=%s",
330 dev_desc.idVendor, dev_desc.idProduct, dev_serial);
331
332 int current_config;
333 err = libusb_get_configuration(dev_handle, &current_config);
334 if (err) {
335 LOG_ERROR("could not find current configuration: %s", libusb_strerror(err));
336 libusb_close(dev_handle);
337 libusb_exit(ctx);
338 return ERROR_FAIL;
339 }
340
341 if (config_num != current_config) {
342 err = libusb_set_configuration(dev_handle, config_num);
343 if (err) {
344 LOG_ERROR("could not set configuration: %s", libusb_strerror(err));
345 libusb_close(dev_handle);
346 libusb_exit(ctx);
347 return ERROR_FAIL;
348 }
349 }
350
351 err = libusb_claim_interface(dev_handle, interface_num);
352 if (err)
353 LOG_WARNING("could not claim interface: %s", libusb_strerror(err));
354
355 dap->bdata = malloc(sizeof(struct cmsis_dap_backend_data));
356 if (dap->bdata == NULL) {
357 LOG_ERROR("unable to allocate memory");
358 libusb_release_interface(dev_handle, interface_num);
359 libusb_close(dev_handle);
360 libusb_exit(ctx);
361 return ERROR_FAIL;
362 }
363
364 dap->packet_size = packet_size;
365 dap->packet_buffer_size = packet_size;
366 dap->bdata->usb_ctx = ctx;
367 dap->bdata->dev_handle = dev_handle;
368 dap->bdata->ep_out = ep_out;
369 dap->bdata->ep_in = ep_in;
370 dap->bdata->interface = interface_num;
371
372 dap->packet_buffer = malloc(dap->packet_buffer_size);
373 if (dap->packet_buffer == NULL) {
374 LOG_ERROR("unable to allocate memory");
375 cmsis_dap_usb_close(dap);
376 return ERROR_FAIL;
377 }
378
379 dap->command = dap->packet_buffer;
380 dap->response = dap->packet_buffer;
381
382 return ERROR_OK;
383 }
384
385 libusb_close(dev_handle);
386 }
387
388 libusb_free_device_list(device_list, true);
389
390 libusb_exit(ctx);
391 return ERROR_FAIL;
392 }
393
394 static void cmsis_dap_usb_close(struct cmsis_dap *dap)
395 {
396 libusb_release_interface(dap->bdata->dev_handle, dap->bdata->interface);
397 libusb_close(dap->bdata->dev_handle);
398 libusb_exit(dap->bdata->usb_ctx);
399 free(dap->bdata);
400 dap->bdata = NULL;
401 free(dap->packet_buffer);
402 dap->packet_buffer = NULL;
403 }
404
405 static int cmsis_dap_usb_read(struct cmsis_dap *dap, int timeout_ms)
406 {
407 int transferred = 0;
408 int err;
409
410 err = libusb_bulk_transfer(dap->bdata->dev_handle, dap->bdata->ep_in,
411 dap->packet_buffer, dap->packet_size, &transferred, timeout_ms);
412 if (err) {
413 if (err == LIBUSB_ERROR_TIMEOUT) {
414 return ERROR_TIMEOUT_REACHED;
415 } else {
416 LOG_ERROR("error reading data: %s", libusb_strerror(err));
417 return ERROR_FAIL;
418 }
419 }
420
421 memset(&dap->packet_buffer[transferred], 0, dap->packet_buffer_size - transferred);
422
423 return transferred;
424 }
425
426 static int cmsis_dap_usb_write(struct cmsis_dap *dap, int txlen, int timeout_ms)
427 {
428 int transferred = 0;
429 int err;
430
431 /* skip the first byte that is only used by the HID backend */
432 err = libusb_bulk_transfer(dap->bdata->dev_handle, dap->bdata->ep_out,
433 dap->packet_buffer, txlen, &transferred, timeout_ms);
434 if (err) {
435 if (err == LIBUSB_ERROR_TIMEOUT) {
436 return ERROR_TIMEOUT_REACHED;
437 } else {
438 LOG_ERROR("error writing data: %s", libusb_strerror(err));
439 return ERROR_FAIL;
440 }
441 }
442
443 return transferred;
444 }
445
446 static int cmsis_dap_usb_alloc(struct cmsis_dap *dap, unsigned int pkt_sz)
447 {
448 uint8_t *buf = malloc(pkt_sz);
449 if (buf == NULL) {
450 LOG_ERROR("unable to allocate CMSIS-DAP packet buffer");
451 return ERROR_FAIL;
452 }
453
454 dap->packet_buffer = buf;
455 dap->packet_size = pkt_sz;
456 dap->packet_buffer_size = pkt_sz;
457
458 dap->command = dap->packet_buffer;
459 dap->response = dap->packet_buffer;
460
461 return ERROR_OK;
462 }
463
464 COMMAND_HANDLER(cmsis_dap_handle_usb_interface_command)
465 {
466 if (CMD_ARGC == 1)
467 cmsis_dap_usb_interface = strtoul(CMD_ARGV[0], NULL, 10);
468 else
469 LOG_ERROR("expected exactly one argument to cmsis_dap_usb_interface <interface_number>");
470
471 return ERROR_OK;
472 }
473
474 const struct command_registration cmsis_dap_usb_subcommand_handlers[] = {
475 {
476 .name = "interface",
477 .handler = &cmsis_dap_handle_usb_interface_command,
478 .mode = COMMAND_CONFIG,
479 .help = "set the USB interface number to use (for USB bulk backend only)",
480 .usage = "<interface_number>",
481 },
482 COMMAND_REGISTRATION_DONE
483 };
484
485 const struct cmsis_dap_backend cmsis_dap_usb_backend = {
486 .name = "usb_bulk",
487 .open = cmsis_dap_usb_open,
488 .close = cmsis_dap_usb_close,
489 .read = cmsis_dap_usb_read,
490 .write = cmsis_dap_usb_write,
491 .packet_buffer_alloc = cmsis_dap_usb_alloc,
492 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)