1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2018 by Mickaël Thomas *
7 * Copyright (C) 2016 by Maksym Hilliaka *
8 * oter@frozen-team.com *
10 * Copyright (C) 2016 by Phillip Pearson *
13 * Copyright (C) 2014 by Paul Fertser *
14 * fercerpav@gmail.com *
16 * Copyright (C) 2013 by mike brown *
17 * mike@theshedworks.org.uk *
19 * Copyright (C) 2013 by Spencer Oliver *
20 * spen@spen-soft.co.uk *
21 ***************************************************************************/
27 #include <helper/system.h>
29 #include <helper/log.h>
30 #include <helper/replacements.h>
32 #include "cmsis_dap.h"
34 struct cmsis_dap_backend_data
{
35 struct libusb_context
*usb_ctx
;
36 struct libusb_device_handle
*dev_handle
;
42 static int cmsis_dap_usb_interface
= -1;
44 static void cmsis_dap_usb_close(struct cmsis_dap
*dap
);
45 static int cmsis_dap_usb_alloc(struct cmsis_dap
*dap
, unsigned int pkt_sz
);
47 static int cmsis_dap_usb_open(struct cmsis_dap
*dap
, uint16_t vids
[], uint16_t pids
[], const char *serial
)
50 struct libusb_context
*ctx
;
51 struct libusb_device
**device_list
;
53 err
= libusb_init(&ctx
);
55 LOG_ERROR("libusb initialization failed: %s", libusb_strerror(err
));
59 int num_devices
= libusb_get_device_list(ctx
, &device_list
);
60 if (num_devices
< 0) {
61 LOG_ERROR("could not enumerate USB devices: %s", libusb_strerror(num_devices
));
66 for (int i
= 0; i
< num_devices
; i
++) {
67 struct libusb_device
*dev
= device_list
[i
];
68 struct libusb_device_descriptor dev_desc
;
70 err
= libusb_get_device_descriptor(dev
, &dev_desc
);
72 LOG_ERROR("could not get device descriptor for device %d: %s", i
, libusb_strerror(err
));
78 bool id_match
= false;
79 bool id_filter
= vids
[0] || pids
[0];
80 for (int id
= 0; vids
[id
] || pids
[id
]; id
++) {
81 id_match
= !vids
[id
] || dev_desc
.idVendor
== vids
[id
];
82 id_match
&= !pids
[id
] || dev_desc
.idProduct
== pids
[id
];
88 if (id_filter
&& !id_match
)
91 /* Don't continue if we asked for a serial number and the device doesn't have one */
92 if (dev_desc
.iSerialNumber
== 0 && serial
&& serial
[0])
95 struct libusb_device_handle
*dev_handle
= NULL
;
96 err
= libusb_open(dev
, &dev_handle
);
98 /* It's to be expected that most USB devices can't be opened
99 * so only report an error if it was explicitly selected
102 LOG_ERROR("could not open device 0x%04x:0x%04x: %s",
103 dev_desc
.idVendor
, dev_desc
.idProduct
, libusb_strerror(err
));
105 LOG_DEBUG("could not open device 0x%04x:0x%04x: %s",
106 dev_desc
.idVendor
, dev_desc
.idProduct
, libusb_strerror(err
));
111 /* Match serial number */
113 bool serial_match
= false;
114 char dev_serial
[256] = {0};
115 if (dev_desc
.iSerialNumber
> 0) {
116 err
= libusb_get_string_descriptor_ascii(
117 dev_handle
, dev_desc
.iSerialNumber
,
118 (uint8_t *)dev_serial
, sizeof(dev_serial
));
121 const char *msg
= "could not read serial number for device 0x%04x:0x%04x: %s";
123 LOG_WARNING(msg
, dev_desc
.idVendor
, dev_desc
.idProduct
,
124 libusb_strerror(err
));
126 LOG_DEBUG(msg
, dev_desc
.idVendor
, dev_desc
.idProduct
,
127 libusb_strerror(err
));
128 } else if (serial
&& strncmp(dev_serial
, serial
, sizeof(dev_serial
)) == 0) {
133 if (serial
&& !serial_match
) {
134 libusb_close(dev_handle
);
138 /* Find the CMSIS-DAP string in product string */
140 bool cmsis_dap_in_product_str
= false;
141 char product_string
[256] = {0};
142 if (dev_desc
.iProduct
> 0) {
143 err
= libusb_get_string_descriptor_ascii(
144 dev_handle
, dev_desc
.iProduct
,
145 (uint8_t *)product_string
, sizeof(product_string
));
147 LOG_WARNING("could not read product string for device 0x%04x:0x%04x: %s",
148 dev_desc
.idVendor
, dev_desc
.idProduct
, libusb_strerror(err
));
149 } else if (strstr(product_string
, "CMSIS-DAP")) {
150 LOG_DEBUG("found product string of 0x%04x:0x%04x '%s'",
151 dev_desc
.idVendor
, dev_desc
.idProduct
, product_string
);
152 cmsis_dap_in_product_str
= true;
156 bool device_identified_reliably
= cmsis_dap_in_product_str
157 || serial_match
|| id_match
;
159 /* Find the CMSIS-DAP interface */
161 for (int config
= 0; config
< dev_desc
.bNumConfigurations
; config
++) {
162 struct libusb_config_descriptor
*config_desc
;
163 err
= libusb_get_config_descriptor(dev
, config
, &config_desc
);
165 LOG_ERROR("could not get configuration descriptor %d for device 0x%04x:0x%04x: %s",
166 config
, dev_desc
.idVendor
, dev_desc
.idProduct
, libusb_strerror(err
));
170 LOG_DEBUG("enumerating interfaces of 0x%04x:0x%04x",
171 dev_desc
.idVendor
, dev_desc
.idProduct
);
172 int config_num
= config_desc
->bConfigurationValue
;
173 const struct libusb_interface_descriptor
*intf_desc_candidate
= NULL
;
174 const struct libusb_interface_descriptor
*intf_desc_found
= NULL
;
176 for (int interface
= 0; interface
< config_desc
->bNumInterfaces
; interface
++) {
177 const struct libusb_interface_descriptor
*intf_desc
= &config_desc
->interface
[interface
].altsetting
[0];
178 int interface_num
= intf_desc
->bInterfaceNumber
;
180 /* Skip this interface if another one was requested explicitly */
181 if (cmsis_dap_usb_interface
!= -1 && cmsis_dap_usb_interface
!= interface_num
)
184 /* CMSIS-DAP v2 spec says:
186 * CMSIS-DAP with default V2 configuration uses WinUSB and is therefore faster.
187 * Optionally support for streaming SWO trace is provided via an additional USB endpoint.
189 * The WinUSB configuration requires custom class support with the interface setting
190 * Class Code: 0xFF (Vendor specific)
192 * Protocol code: 0x00
194 * Depending on the configuration it uses the following USB endpoints which should be configured
195 * in the interface descriptor in this order:
196 * - Endpoint 1: Bulk Out – used for commands received from host PC.
197 * - Endpoint 2: Bulk In – used for responses send to host PC.
198 * - Endpoint 3: Bulk In (optional) – used for streaming SWO trace (if enabled with SWO_STREAM).
201 /* Search for "CMSIS-DAP" in the interface string */
202 bool cmsis_dap_in_interface_str
= false;
203 if (intf_desc
->iInterface
!= 0) {
205 char interface_str
[256] = {0};
207 err
= libusb_get_string_descriptor_ascii(
208 dev_handle
, intf_desc
->iInterface
,
209 (uint8_t *)interface_str
, sizeof(interface_str
));
211 LOG_DEBUG("could not read interface string %d for device 0x%04x:0x%04x: %s",
212 intf_desc
->iInterface
,
213 dev_desc
.idVendor
, dev_desc
.idProduct
,
214 libusb_strerror(err
));
215 } else if (strstr(interface_str
, "CMSIS-DAP")) {
216 cmsis_dap_in_interface_str
= true;
217 LOG_DEBUG("found interface %d string '%s'",
218 interface_num
, interface_str
);
222 /* Bypass the following check if this interface was explicitly requested. */
223 if (cmsis_dap_usb_interface
== -1) {
224 if (!cmsis_dap_in_product_str
&& !cmsis_dap_in_interface_str
)
228 /* check endpoints */
229 if (intf_desc
->bNumEndpoints
< 2) {
230 LOG_DEBUG("skipping interface %d, has only %d endpoints",
231 interface_num
, intf_desc
->bNumEndpoints
);
235 if ((intf_desc
->endpoint
[0].bmAttributes
& 3) != LIBUSB_TRANSFER_TYPE_BULK
||
236 (intf_desc
->endpoint
[0].bEndpointAddress
& 0x80) != LIBUSB_ENDPOINT_OUT
) {
237 LOG_DEBUG("skipping interface %d, endpoint[0] is not bulk out",
242 if ((intf_desc
->endpoint
[1].bmAttributes
& 3) != LIBUSB_TRANSFER_TYPE_BULK
||
243 (intf_desc
->endpoint
[1].bEndpointAddress
& 0x80) != LIBUSB_ENDPOINT_IN
) {
244 LOG_DEBUG("skipping interface %d, endpoint[1] is not bulk in",
249 /* We can rely on the interface is really CMSIS-DAP if
250 * - we've seen CMSIS-DAP in the interface string
251 * - config asked explicitly for an interface number
252 * - the device has only one interface
253 * The later two cases should be honored only if we know
254 * we are on the right device */
255 bool intf_identified_reliably
= cmsis_dap_in_interface_str
256 || (device_identified_reliably
&&
257 (cmsis_dap_usb_interface
!= -1
258 || config_desc
->bNumInterfaces
== 1));
260 if (intf_desc
->bInterfaceClass
!= LIBUSB_CLASS_VENDOR_SPEC
||
261 intf_desc
->bInterfaceSubClass
!= 0 || intf_desc
->bInterfaceProtocol
!= 0) {
262 /* If the interface is reliably identified
263 * then we need not insist on setting USB class, subclass and protocol
264 * exactly as the specification requires.
265 * Just filter out the well known classes, mainly CDC and MSC.
266 * At least KitProg3 uses class 0 contrary to the specification */
267 if (intf_identified_reliably
&&
268 (intf_desc
->bInterfaceClass
== 0 || intf_desc
->bInterfaceClass
> 0x12)) {
269 LOG_WARNING("Using CMSIS-DAPv2 interface %d with wrong class %" PRId8
270 " subclass %" PRId8
" or protocol %" PRId8
,
272 intf_desc
->bInterfaceClass
,
273 intf_desc
->bInterfaceSubClass
,
274 intf_desc
->bInterfaceProtocol
);
276 LOG_DEBUG("skipping interface %d, class %" PRId8
277 " subclass %" PRId8
" protocol %" PRId8
,
279 intf_desc
->bInterfaceClass
,
280 intf_desc
->bInterfaceSubClass
,
281 intf_desc
->bInterfaceProtocol
);
287 if (intf_identified_reliably
) {
288 /* That's the one! */
289 intf_desc_found
= intf_desc
;
293 if (!intf_desc_candidate
&& device_identified_reliably
) {
294 /* This interface looks suitable for CMSIS-DAP. Store the pointer to it
295 * and keep searching for another one with CMSIS-DAP in interface string */
296 intf_desc_candidate
= intf_desc
;
300 if (!intf_desc_found
) {
301 /* We were not able to identify reliably which interface is CMSIS-DAP.
302 * Let's use the first suitable if we found one */
303 intf_desc_found
= intf_desc_candidate
;
306 if (!intf_desc_found
) {
307 libusb_free_config_descriptor(config_desc
);
311 /* We've chosen an interface, connect to it */
312 int interface_num
= intf_desc_found
->bInterfaceNumber
;
313 int packet_size
= intf_desc_found
->endpoint
[0].wMaxPacketSize
;
314 int ep_out
= intf_desc_found
->endpoint
[0].bEndpointAddress
;
315 int ep_in
= intf_desc_found
->endpoint
[1].bEndpointAddress
;
317 libusb_free_config_descriptor(config_desc
);
318 libusb_free_device_list(device_list
, true);
320 LOG_INFO("Using CMSIS-DAPv2 interface with VID:PID=0x%04x:0x%04x, serial=%s",
321 dev_desc
.idVendor
, dev_desc
.idProduct
, dev_serial
);
324 err
= libusb_get_configuration(dev_handle
, ¤t_config
);
326 LOG_ERROR("could not find current configuration: %s", libusb_strerror(err
));
327 libusb_close(dev_handle
);
332 if (config_num
!= current_config
) {
333 err
= libusb_set_configuration(dev_handle
, config_num
);
335 LOG_ERROR("could not set configuration: %s", libusb_strerror(err
));
336 libusb_close(dev_handle
);
342 err
= libusb_claim_interface(dev_handle
, interface_num
);
344 LOG_WARNING("could not claim interface: %s", libusb_strerror(err
));
346 dap
->bdata
= malloc(sizeof(struct cmsis_dap_backend_data
));
348 LOG_ERROR("unable to allocate memory");
349 libusb_release_interface(dev_handle
, interface_num
);
350 libusb_close(dev_handle
);
355 dap
->bdata
->usb_ctx
= ctx
;
356 dap
->bdata
->dev_handle
= dev_handle
;
357 dap
->bdata
->ep_out
= ep_out
;
358 dap
->bdata
->ep_in
= ep_in
;
359 dap
->bdata
->interface
= interface_num
;
361 err
= cmsis_dap_usb_alloc(dap
, packet_size
);
363 cmsis_dap_usb_close(dap
);
368 libusb_close(dev_handle
);
371 libusb_free_device_list(device_list
, true);
377 static void cmsis_dap_usb_close(struct cmsis_dap
*dap
)
379 libusb_release_interface(dap
->bdata
->dev_handle
, dap
->bdata
->interface
);
380 libusb_close(dap
->bdata
->dev_handle
);
381 libusb_exit(dap
->bdata
->usb_ctx
);
384 free(dap
->packet_buffer
);
385 dap
->packet_buffer
= NULL
;
388 static int cmsis_dap_usb_read(struct cmsis_dap
*dap
, int timeout_ms
)
393 err
= libusb_bulk_transfer(dap
->bdata
->dev_handle
, dap
->bdata
->ep_in
,
394 dap
->packet_buffer
, dap
->packet_size
, &transferred
, timeout_ms
);
396 if (err
== LIBUSB_ERROR_TIMEOUT
) {
397 return ERROR_TIMEOUT_REACHED
;
399 LOG_ERROR("error reading data: %s", libusb_strerror(err
));
404 memset(&dap
->packet_buffer
[transferred
], 0, dap
->packet_buffer_size
- transferred
);
409 static int cmsis_dap_usb_write(struct cmsis_dap
*dap
, int txlen
, int timeout_ms
)
414 /* skip the first byte that is only used by the HID backend */
415 err
= libusb_bulk_transfer(dap
->bdata
->dev_handle
, dap
->bdata
->ep_out
,
416 dap
->packet_buffer
, txlen
, &transferred
, timeout_ms
);
418 if (err
== LIBUSB_ERROR_TIMEOUT
) {
419 return ERROR_TIMEOUT_REACHED
;
421 LOG_ERROR("error writing data: %s", libusb_strerror(err
));
429 static int cmsis_dap_usb_alloc(struct cmsis_dap
*dap
, unsigned int pkt_sz
)
431 uint8_t *buf
= malloc(pkt_sz
);
433 LOG_ERROR("unable to allocate CMSIS-DAP packet buffer");
437 dap
->packet_buffer
= buf
;
438 dap
->packet_size
= pkt_sz
;
439 dap
->packet_buffer_size
= pkt_sz
;
440 /* Prevent sending zero size USB packets */
441 dap
->packet_usable_size
= pkt_sz
- 1;
443 dap
->command
= dap
->packet_buffer
;
444 dap
->response
= dap
->packet_buffer
;
449 COMMAND_HANDLER(cmsis_dap_handle_usb_interface_command
)
452 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], cmsis_dap_usb_interface
);
454 LOG_ERROR("expected exactly one argument to cmsis_dap_usb_interface <interface_number>");
459 const struct command_registration cmsis_dap_usb_subcommand_handlers
[] = {
462 .handler
= &cmsis_dap_handle_usb_interface_command
,
463 .mode
= COMMAND_CONFIG
,
464 .help
= "set the USB interface number to use (for USB bulk backend only)",
465 .usage
= "<interface_number>",
467 COMMAND_REGISTRATION_DONE
470 const struct cmsis_dap_backend cmsis_dap_usb_backend
= {
472 .open
= cmsis_dap_usb_open
,
473 .close
= cmsis_dap_usb_close
,
474 .read
= cmsis_dap_usb_read
,
475 .write
= cmsis_dap_usb_write
,
476 .packet_buffer_alloc
= cmsis_dap_usb_alloc
,