95f553b626f147e6718a1399a3d4ad6ee5626105
[openocd.git] / src / jtag / drivers / cmsis_dap_usb.c
1 /***************************************************************************
2 * Copyright (C) 2013 by mike brown *
3 * mike@theshedworks.org.uk *
4 * *
5 * Copyright (C) 2013 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
22 ***************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <transport/transport.h>
29 #include <jtag/swd.h>
30 #include <jtag/interface.h>
31 #include <jtag/commands.h>
32 #include <jtag/tcl.h>
33
34 #include <hidapi.h>
35
36 #ifdef _DEBUG_JTAG_IO_
37 #define DEBUG_IO(expr...) LOG_DEBUG(expr)
38 #else
39 #define DEBUG_IO(expr...) do {} while (0)
40 #endif
41
42 /*
43 * See CMSIS-DAP documentation:
44 * Version 0.01 - Beta.
45 */
46
47 /* USB Config */
48
49 /* Known vid/pid pairs:
50 * VID 0xc251: Keil Software
51 * PID 0xf001: LPC-Link-II CMSIS_DAP
52 * PID 0xf002: OPEN-SDA CMSIS_DAP (Freedom Board)
53 * PID 0x2722: Keil ULINK2 CMSIS-DAP
54 *
55 * VID 0x0d28: mbed Software
56 * PID 0x0204: MBED CMSIS-DAP
57 */
58
59 #define MAX_USB_IDS 8
60 /* vid = pid = 0 marks the end of the list */
61 static uint16_t cmsis_dap_vid[MAX_USB_IDS + 1] = { 0 };
62 static uint16_t cmsis_dap_pid[MAX_USB_IDS + 1] = { 0 };
63 static wchar_t *cmsis_dap_serial;
64 static bool swd_mode;
65
66 #define PACKET_SIZE (64 + 1) /* 64 bytes plus report id */
67 #define USB_TIMEOUT 1000
68
69 /* CMSIS-DAP General Commands */
70 #define CMD_DAP_INFO 0x00
71 #define CMD_DAP_LED 0x01
72 #define CMD_DAP_CONNECT 0x02
73 #define CMD_DAP_DISCONNECT 0x03
74 #define CMD_DAP_WRITE_ABORT 0x08
75 #define CMD_DAP_DELAY 0x09
76 #define CMD_DAP_RESET_TARGET 0x0A
77
78 /* CMD_INFO */
79 #define INFO_ID_VID 0x00 /* string */
80 #define INFO_ID_PID 0x02 /* string */
81 #define INFO_ID_SERNUM 0x03 /* string */
82 #define INFO_ID_FW_VER 0x04 /* string */
83 #define INFO_ID_TD_VEND 0x05 /* string */
84 #define INFO_ID_TD_NAME 0x06 /* string */
85 #define INFO_ID_CAPS 0xf0 /* byte */
86 #define INFO_ID_PKT_CNT 0xfe /* byte */
87 #define INFO_ID_PKT_SZ 0xff /* short */
88
89 #define INFO_CAPS_SWD 0x01
90 #define INFO_CAPS_JTAG 0x02
91
92 /* CMD_LED */
93 #define LED_ID_CONNECT 0x00
94 #define LED_ID_RUN 0x01
95
96 #define LED_OFF 0x00
97 #define LED_ON 0x01
98
99 /* CMD_CONNECT */
100 #define CONNECT_DEFAULT 0x00
101 #define CONNECT_SWD 0x01
102 #define CONNECT_JTAG 0x02
103
104 /* CMSIS-DAP Common SWD/JTAG Commands */
105 #define CMD_DAP_DELAY 0x09
106 #define CMD_DAP_SWJ_PINS 0x10
107 #define CMD_DAP_SWJ_CLOCK 0x11
108 #define CMD_DAP_SWJ_SEQ 0x12
109
110 /*
111 * PINS
112 * Bit 0: SWCLK/TCK
113 * Bit 1: SWDIO/TMS
114 * Bit 2: TDI
115 * Bit 3: TDO
116 * Bit 5: nTRST
117 * Bit 7: nRESET
118 */
119
120 /* CMSIS-DAP SWD Commands */
121 #define CMD_DAP_SWD_CONFIGURE 0x13
122
123 /* CMSIS-DAP JTAG Commands */
124 #define CMD_DAP_JTAG_SEQ 0x14
125 #define CMD_DAP_JTAG_CONFIGURE 0x15
126 #define CMD_DAP_JTAG_IDCODE 0x16
127
128 /* CMSIS-DAP Transfer Commands */
129 #define CMD_DAP_TFER_CONFIGURE 0x04
130 #define CMD_DAP_TFER 0x05
131 #define CMD_DAP_TFER_BLOCK 0x06
132 #define CMD_DAP_TFER_ABORT 0x07
133
134 /* DAP Status Code */
135 #define DAP_OK 0
136 #define DAP_ERROR 0xFF
137
138 /* CMSIS-DAP Vendor Commands
139 * None as yet... */
140
141 static const char * const info_caps_str[] = {
142 "SWD Supported",
143 "JTAG Supported"
144 };
145
146 /* max clock speed (kHz) */
147 #define DAP_MAX_CLOCK 5000
148
149 struct cmsis_dap {
150 hid_device *dev_handle;
151 uint16_t packet_size;
152 uint16_t packet_count;
153 uint8_t *packet_buffer;
154 uint8_t caps;
155 uint8_t mode;
156 };
157
158 static struct cmsis_dap *cmsis_dap_handle;
159
160 static int cmsis_dap_usb_open(void)
161 {
162 hid_device *dev = NULL;
163 int i;
164 struct hid_device_info *devs, *cur_dev;
165 unsigned short target_vid, target_pid;
166
167 bool found = false;
168
169 target_vid = 0;
170 target_pid = 0;
171
172 /*
173 * The CMSIS-DAP specification stipulates:
174 * "The Product String must contain "CMSIS-DAP" somewhere in the string. This is used by the
175 * debuggers to identify a CMSIS-DAP compliant Debug Unit that is connected to a host computer."
176 */
177 devs = hid_enumerate(0x0, 0x0);
178 cur_dev = devs;
179 while (NULL != cur_dev) {
180 if (0 == cmsis_dap_vid[0]) {
181 if (NULL == cur_dev->product_string) {
182 LOG_DEBUG("Cannot read product string of device 0x%x:0x%x",
183 cur_dev->vendor_id, cur_dev->product_id);
184 } else {
185 if (wcsstr(cur_dev->product_string, L"CMSIS-DAP")) {
186 /* if the user hasn't specified VID:PID *and*
187 * product string contains "CMSIS-DAP", pick it
188 */
189 found = true;
190 }
191 }
192 } else {
193 /* otherwise, exhaustively compare against all VID:PID in list */
194 for (i = 0; cmsis_dap_vid[i] || cmsis_dap_pid[i]; i++) {
195 if ((cmsis_dap_vid[i] == cur_dev->vendor_id) && (cmsis_dap_pid[i] == cur_dev->product_id))
196 found = true;
197 }
198
199 if (cmsis_dap_vid[i] || cmsis_dap_pid[i])
200 found = true;
201 }
202
203 if (found) {
204 /* we have found an adapter, so exit further checks */
205 /* check serial number matches if given */
206 if (cmsis_dap_serial != NULL) {
207 if (wcscmp(cmsis_dap_serial, cur_dev->serial_number) == 0)
208 break;
209 } else
210 break;
211 }
212
213 cur_dev = cur_dev->next;
214 }
215
216 if (NULL != cur_dev) {
217 target_vid = cur_dev->vendor_id;
218 target_pid = cur_dev->product_id;
219 }
220
221 hid_free_enumeration(devs);
222
223 if (target_vid == 0 && target_pid == 0) {
224 LOG_ERROR("unable to find CMSIS-DAP device");
225 return ERROR_FAIL;
226 }
227
228 if (hid_init() != 0) {
229 LOG_ERROR("unable to open HIDAPI");
230 return ERROR_FAIL;
231 }
232
233 dev = hid_open(target_vid, target_pid, NULL);
234
235 if (dev == NULL) {
236 LOG_ERROR("unable to open CMSIS-DAP device");
237 return ERROR_FAIL;
238 }
239
240 struct cmsis_dap *dap = malloc(sizeof(struct cmsis_dap));
241 if (dap == NULL) {
242 LOG_ERROR("unable to allocate memory");
243 return ERROR_FAIL;
244 }
245
246 dap->dev_handle = dev;
247 dap->caps = 0;
248 dap->mode = 0;
249
250 cmsis_dap_handle = dap;
251
252 /* allocate default packet buffer, may be changed later.
253 * currently with HIDAPI we have no way of getting the output report length
254 * without this info we cannot communicate with the adapter.
255 * For the moment we ahve to hard code the packet size */
256
257 int packet_size = PACKET_SIZE;
258
259 /* atmel cmsis-dap uses 512 byte reports */
260 if (target_vid == 0x03eb)
261 packet_size = 512 + 1;
262
263 cmsis_dap_handle->packet_buffer = malloc(packet_size);
264 cmsis_dap_handle->packet_size = packet_size;
265
266 if (cmsis_dap_handle->packet_buffer == NULL) {
267 LOG_ERROR("unable to allocate memory");
268 return ERROR_FAIL;
269 }
270
271 return ERROR_OK;
272 }
273
274 static void cmsis_dap_usb_close(struct cmsis_dap *dap)
275 {
276 hid_close(dap->dev_handle);
277 hid_exit();
278
279 if (cmsis_dap_handle->packet_buffer)
280 free(cmsis_dap_handle->packet_buffer);
281
282 if (cmsis_dap_handle) {
283 free(cmsis_dap_handle);
284 cmsis_dap_handle = NULL;
285 }
286
287 if (cmsis_dap_serial) {
288 free(cmsis_dap_serial);
289 cmsis_dap_serial = NULL;
290 }
291
292 return;
293 }
294
295 /* Send a message and receive the reply */
296 static int cmsis_dap_usb_xfer(struct cmsis_dap *dap, int txlen)
297 {
298 /* Pad the rest of the TX buffer with 0's */
299 memset(dap->packet_buffer + txlen, 0, dap->packet_size - 1 - txlen);
300
301 /* write data to device */
302 int retval = hid_write(dap->dev_handle, dap->packet_buffer, dap->packet_size);
303 if (retval == -1) {
304 LOG_ERROR("error writing data: %ls", hid_error(dap->dev_handle));
305 return ERROR_FAIL;
306 }
307
308 /* get reply */
309 retval = hid_read_timeout(dap->dev_handle, dap->packet_buffer, dap->packet_size, USB_TIMEOUT);
310 if (retval == -1 || retval == 0) {
311 LOG_DEBUG("error reading data: %ls", hid_error(dap->dev_handle));
312 return ERROR_FAIL;
313 }
314
315 return ERROR_OK;
316 }
317
318 static int cmsis_dap_cmd_DAP_SWJ_Pins(uint8_t pins, uint8_t mask, uint32_t delay, uint8_t *input)
319 {
320 int retval;
321 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
322
323 buffer[0] = 0; /* report number */
324 buffer[1] = CMD_DAP_SWJ_PINS;
325 buffer[2] = pins;
326 buffer[3] = mask;
327 buffer[4] = delay & 0xff;
328 buffer[5] = (delay >> 8) & 0xff;
329 buffer[6] = (delay >> 16) & 0xff;
330 buffer[7] = (delay >> 24) & 0xff;
331 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 8);
332
333 if (retval != ERROR_OK) {
334 LOG_ERROR("CMSIS-DAP command CMD_DAP_SWJ_PINS failed.");
335 return ERROR_JTAG_DEVICE_ERROR;
336 }
337
338 if (input)
339 *input = buffer[1];
340
341 return ERROR_OK;
342 }
343
344 static int cmsis_dap_cmd_DAP_SWJ_Clock(uint32_t swj_clock)
345 {
346 int retval;
347 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
348
349 /* set clock in Hz */
350 swj_clock *= 1000;
351 buffer[0] = 0; /* report number */
352 buffer[1] = CMD_DAP_SWJ_CLOCK;
353 buffer[2] = swj_clock & 0xff;
354 buffer[3] = (swj_clock >> 8) & 0xff;
355 buffer[4] = (swj_clock >> 16) & 0xff;
356 buffer[5] = (swj_clock >> 24) & 0xff;
357 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 6);
358
359 if (retval != ERROR_OK || buffer[1] != DAP_OK) {
360 LOG_ERROR("CMSIS-DAP command CMD_DAP_SWJ_CLOCK failed.");
361 return ERROR_JTAG_DEVICE_ERROR;
362 }
363
364 return ERROR_OK;
365 }
366
367 static int cmsis_dap_cmd_DAP_Info(uint8_t info, uint8_t **data)
368 {
369 int retval;
370 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
371
372 buffer[0] = 0; /* report number */
373 buffer[1] = CMD_DAP_INFO;
374 buffer[2] = info;
375 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 3);
376
377 if (retval != ERROR_OK) {
378 LOG_ERROR("CMSIS-DAP command CMD_INFO failed.");
379 return ERROR_JTAG_DEVICE_ERROR;
380 }
381
382 *data = &(buffer[1]);
383
384 return ERROR_OK;
385 }
386
387 static int cmsis_dap_cmd_DAP_LED(uint8_t leds)
388 {
389 int retval;
390 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
391
392 buffer[0] = 0; /* report number */
393 buffer[1] = CMD_DAP_LED;
394 buffer[2] = 0x00;
395 buffer[3] = leds;
396 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 4);
397
398 if (retval != ERROR_OK || buffer[1] != 0x00) {
399 LOG_ERROR("CMSIS-DAP command CMD_LED failed.");
400 return ERROR_JTAG_DEVICE_ERROR;
401 }
402
403 return ERROR_OK;
404 }
405
406 static int cmsis_dap_cmd_DAP_Connect(uint8_t mode)
407 {
408 int retval;
409 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
410
411 buffer[0] = 0; /* report number */
412 buffer[1] = CMD_DAP_CONNECT;
413 buffer[2] = mode;
414 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 3);
415
416 if (retval != ERROR_OK) {
417 LOG_ERROR("CMSIS-DAP command CMD_CONNECT failed.");
418 return ERROR_JTAG_DEVICE_ERROR;
419 }
420
421 if (buffer[1] != mode) {
422 LOG_ERROR("CMSIS-DAP failed to connect in mode (%d)", mode);
423 return ERROR_JTAG_DEVICE_ERROR;
424 }
425
426 return ERROR_OK;
427 }
428
429 static int cmsis_dap_cmd_DAP_Disconnect(void)
430 {
431 int retval;
432 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
433
434 buffer[0] = 0; /* report number */
435 buffer[1] = CMD_DAP_DISCONNECT;
436 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 2);
437
438 if (retval != ERROR_OK || buffer[1] != DAP_OK) {
439 LOG_ERROR("CMSIS-DAP command CMD_DISCONNECT failed.");
440 return ERROR_JTAG_DEVICE_ERROR;
441 }
442
443 return ERROR_OK;
444 }
445
446 static int cmsis_dap_cmd_DAP_TFER_Configure(uint8_t idle, uint16_t delay, uint16_t retry)
447 {
448 int retval;
449 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
450
451 buffer[0] = 0; /* report number */
452 buffer[1] = CMD_DAP_TFER_CONFIGURE;
453 buffer[2] = idle;
454 buffer[3] = delay & 0xff;
455 buffer[4] = (delay >> 8) & 0xff;
456 buffer[5] = retry & 0xff;
457 buffer[6] = (retry >> 8) & 0xff;
458 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 7);
459
460 if (retval != ERROR_OK || buffer[1] != DAP_OK) {
461 LOG_ERROR("CMSIS-DAP command CMD_TFER_Configure failed.");
462 return ERROR_JTAG_DEVICE_ERROR;
463 }
464
465 return ERROR_OK;
466 }
467
468 static int cmsis_dap_cmd_DAP_SWD_Configure(uint8_t cfg)
469 {
470 int retval;
471 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
472
473 buffer[0] = 0; /* report number */
474 buffer[1] = CMD_DAP_SWD_CONFIGURE;
475 buffer[2] = cfg;
476 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 3);
477
478 if (retval != ERROR_OK || buffer[1] != DAP_OK) {
479 LOG_ERROR("CMSIS-DAP command CMD_SWD_Configure failed.");
480 return ERROR_JTAG_DEVICE_ERROR;
481 }
482
483 return ERROR_OK;
484 }
485
486 #if 0
487 static int cmsis_dap_cmd_DAP_Delay(uint16_t delay_us)
488 {
489 int retval;
490 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
491
492 buffer[0] = 0; /* report number */
493 buffer[1] = CMD_DAP_DELAY;
494 buffer[2] = delay_us & 0xff;
495 buffer[3] = (delay_us >> 8) & 0xff;
496 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 4);
497
498 if (retval != ERROR_OK || buffer[1] != DAP_OK) {
499 LOG_ERROR("CMSIS-DAP command CMD_Delay failed.");
500 return ERROR_JTAG_DEVICE_ERROR;
501 }
502
503 return ERROR_OK;
504 }
505 #endif
506
507 static int queued_retval;
508
509 static void cmsis_dap_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *value)
510 {
511 if (queued_retval != ERROR_OK)
512 return;
513
514 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
515 int retval;
516 uint32_t val;
517
518 DEBUG_IO("CMSIS-DAP: Read Reg 0x%02" PRIx8, cmd);
519
520 buffer[0] = 0; /* report number */
521 buffer[1] = CMD_DAP_TFER;
522 buffer[2] = 0x00;
523 buffer[3] = 0x01;
524 buffer[4] = cmd;
525 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 5);
526
527 /* TODO - need better response checking */
528 if (retval != ERROR_OK || buffer[1] != 0x01) {
529 LOG_ERROR("CMSIS-DAP: Read Error (0x%02" PRIx8 ")", buffer[2]);
530 queued_retval = buffer[2];
531 return;
532 }
533
534 val = le_to_h_u32(&buffer[3]);
535 DEBUG_IO("0x%08" PRIx32, val);
536
537 if (value)
538 *value = val;
539
540 queued_retval = retval;
541 }
542
543 static void cmsis_dap_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t value)
544 {
545 if (queued_retval != ERROR_OK)
546 return;
547
548 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
549
550 DEBUG_IO("CMSIS-DAP: Write Reg 0x%02" PRIx8 " 0x%08" PRIx32, cmd, value);
551
552 buffer[0] = 0; /* report number */
553 buffer[1] = CMD_DAP_TFER;
554 buffer[2] = 0x00;
555 buffer[3] = 0x01;
556 buffer[4] = cmd;
557 buffer[5] = (value) & 0xff;
558 buffer[6] = (value >> 8) & 0xff;
559 buffer[7] = (value >> 16) & 0xff;
560 buffer[8] = (value >> 24) & 0xff;
561 int retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 9);
562
563 if (buffer[1] != 0x01) {
564 LOG_ERROR("CMSIS-DAP: Write Error (0x%02" PRIx8 ")", buffer[2]);
565 retval = buffer[2];
566 }
567
568 queued_retval = retval;
569 }
570
571 static int cmsis_dap_swd_run(struct adiv5_dap *dap)
572 {
573 int retval = queued_retval;
574 queued_retval = ERROR_OK;
575 return retval;
576 }
577
578 static int cmsis_dap_get_version_info(void)
579 {
580 uint8_t *data;
581
582 /* INFO_ID_FW_VER - string */
583 int retval = cmsis_dap_cmd_DAP_Info(INFO_ID_FW_VER, &data);
584 if (retval != ERROR_OK)
585 return retval;
586
587 if (data[0]) /* strlen */
588 LOG_INFO("CMSIS-DAP: FW Version = %s", &data[1]);
589
590 return ERROR_OK;
591 }
592
593 static int cmsis_dap_get_caps_info(void)
594 {
595 uint8_t *data;
596
597 /* INFO_ID_CAPS - byte */
598 int retval = cmsis_dap_cmd_DAP_Info(INFO_ID_CAPS, &data);
599 if (retval != ERROR_OK)
600 return retval;
601
602 if (data[0] == 1) {
603 uint8_t caps = data[1];
604
605 cmsis_dap_handle->caps = caps;
606
607 if (caps & INFO_CAPS_SWD)
608 LOG_INFO("CMSIS-DAP: %s", info_caps_str[0]);
609 if (caps & INFO_CAPS_JTAG)
610 LOG_INFO("CMSIS-DAP: %s", info_caps_str[1]);
611 }
612
613 return ERROR_OK;
614 }
615
616 static int cmsis_dap_get_status(void)
617 {
618 uint8_t d;
619
620 int retval = cmsis_dap_cmd_DAP_SWJ_Pins(0, 0, 0, &d);
621
622 if (retval == ERROR_OK) {
623 LOG_INFO("SWCLK/TCK = %d SWDIO/TMS = %d TDI = %d TDO = %d nTRST = %d nRESET = %d",
624 (d & (0x01 << 0)) ? 1 : 0, /* Bit 0: SWCLK/TCK */
625 (d & (0x01 << 1)) ? 1 : 0, /* Bit 1: SWDIO/TMS */
626 (d & (0x01 << 2)) ? 1 : 0, /* Bit 2: TDI */
627 (d & (0x01 << 3)) ? 1 : 0, /* Bit 3: TDO */
628 (d & (0x01 << 5)) ? 1 : 0, /* Bit 5: nTRST */
629 (d & (0x01 << 7)) ? 1 : 0); /* Bit 7: nRESET */
630 }
631
632 return retval;
633 }
634
635 static int cmsis_dap_reset_link(void)
636 {
637 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
638
639 LOG_DEBUG("CMSIS-DAP: cmsis_dap_reset_link");
640 LOG_INFO("DAP_SWJ Sequence (reset: 50+ '1' followed by 0)");
641
642 /* reset line with SWDIO high for >50 cycles */
643 buffer[0] = 0; /* report number */
644 buffer[1] = CMD_DAP_SWJ_SEQ;
645 buffer[2] = 7 * 8;
646 buffer[3] = 0xff;
647 buffer[4] = 0xff;
648 buffer[5] = 0xff;
649 buffer[6] = 0xff;
650 buffer[7] = 0xff;
651 buffer[8] = 0xff;
652 buffer[9] = 0xff;
653 int retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 10);
654
655 if (retval != ERROR_OK || buffer[1] != DAP_OK)
656 return ERROR_FAIL;
657
658 /* 16bit JTAG-SWD sequence */
659 buffer[0] = 0; /* report number */
660 buffer[1] = CMD_DAP_SWJ_SEQ;
661 buffer[2] = 2 * 8;
662 buffer[3] = 0x9e;
663 buffer[4] = 0xe7;
664 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 5);
665
666 if (retval != ERROR_OK || buffer[1] != DAP_OK)
667 return ERROR_FAIL;
668
669 /* another reset just incase */
670 buffer[0] = 0; /* report number */
671 buffer[1] = CMD_DAP_SWJ_SEQ;
672 buffer[2] = 7 * 8;
673 buffer[3] = 0xff;
674 buffer[4] = 0xff;
675 buffer[5] = 0xff;
676 buffer[6] = 0xff;
677 buffer[7] = 0xff;
678 buffer[8] = 0xff;
679 buffer[9] = 0xff;
680 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 10);
681
682 if (retval != ERROR_OK || buffer[1] != DAP_OK)
683 return ERROR_FAIL;
684
685 /* 16 cycle idle period */
686 buffer[0] = 0; /* report number */
687 buffer[1] = CMD_DAP_SWJ_SEQ;
688 buffer[2] = 2 * 8;
689 buffer[3] = 0x00;
690 buffer[4] = 0x00;
691 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 5);
692
693 if (retval != ERROR_OK || buffer[1] != DAP_OK)
694 return ERROR_FAIL;
695
696 DEBUG_IO("DAP Read IDCODE");
697
698 /* read the id code is always the next sequence */
699 buffer[0] = 0; /* report number */
700 buffer[1] = CMD_DAP_TFER;
701 buffer[2] = 0x00;
702 buffer[3] = 0x01;
703 buffer[4] = 0x02;
704 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 5);
705
706 if (retval != ERROR_OK)
707 return retval;
708
709 if (buffer[1] == 0) {
710 LOG_DEBUG("Result 0x%02" PRIx8 " 0x%02" PRIx8, buffer[1], buffer[2]);
711
712 LOG_DEBUG("DAP Reset Target");
713 buffer[0] = 0; /* report number */
714 buffer[1] = CMD_DAP_RESET_TARGET;
715 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 2);
716 LOG_DEBUG("Result 0x%02" PRIx8 " 0x%02" PRIx8, buffer[1], buffer[2]);
717
718 LOG_DEBUG("DAP Write Abort");
719 buffer[0] = 0; /* report number */
720 buffer[1] = CMD_DAP_WRITE_ABORT;
721 buffer[2] = 0x00;
722 buffer[3] = 0x1e/*0x1f*/;
723 buffer[4] = 0x00;
724 buffer[5] = 0x00;
725 buffer[6] = 0x00;
726 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 7);
727 LOG_DEBUG("Result 0x%02" PRIx8, buffer[1]);
728
729 return 0x80 + buffer[1];
730 }
731
732 LOG_DEBUG("DAP Write Abort");
733 buffer[0] = 0; /* report number */
734 buffer[1] = CMD_DAP_WRITE_ABORT;
735 buffer[2] = 0x00;
736 buffer[3] = 0x1e;
737 buffer[4] = 0x00;
738 buffer[5] = 0x00;
739 buffer[6] = 0x00;
740 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 7);
741 LOG_DEBUG("Result 0x%02" PRIx8, buffer[1]);
742
743 return retval;
744 }
745
746 static int cmsis_dap_swd_open(void)
747 {
748 int retval;
749
750 DEBUG_IO("CMSIS-DAP: cmsis_dap_swd_open");
751
752 if (cmsis_dap_handle == NULL) {
753
754 /* SWD init */
755 retval = cmsis_dap_usb_open();
756 if (retval != ERROR_OK)
757 return retval;
758
759 retval = cmsis_dap_get_caps_info();
760 if (retval != ERROR_OK)
761 return retval;
762 }
763
764 if (!(cmsis_dap_handle->caps & INFO_CAPS_SWD)) {
765 LOG_ERROR("CMSIS-DAP: SWD not supported");
766 return ERROR_JTAG_DEVICE_ERROR;
767 }
768
769 retval = cmsis_dap_cmd_DAP_Connect(CONNECT_SWD);
770 if (retval != ERROR_OK)
771 return retval;
772
773 /* Add more setup here.??... */
774
775 LOG_INFO("CMSIS-DAP: Interface Initialised (SWD)");
776 return ERROR_OK;
777 }
778
779 static int cmsis_dap_init(void)
780 {
781 int retval;
782 uint8_t *data;
783
784 if (swd_mode) {
785 retval = cmsis_dap_swd_open();
786 if (retval != ERROR_OK)
787 return retval;
788 }
789
790 if (cmsis_dap_handle == NULL) {
791
792 /* JTAG init */
793 retval = cmsis_dap_usb_open();
794 if (retval != ERROR_OK)
795 return retval;
796
797 retval = cmsis_dap_get_caps_info();
798 if (retval != ERROR_OK)
799 return retval;
800
801 /* Connect in JTAG mode */
802 if (!(cmsis_dap_handle->caps & INFO_CAPS_JTAG)) {
803 LOG_ERROR("CMSIS-DAP: JTAG not supported");
804 return ERROR_JTAG_DEVICE_ERROR;
805 }
806
807 retval = cmsis_dap_cmd_DAP_Connect(CONNECT_JTAG);
808 if (retval != ERROR_OK)
809 return retval;
810
811 LOG_INFO("CMSIS-DAP: Interface Initialised (JTAG)");
812 }
813
814 retval = cmsis_dap_get_version_info();
815 if (retval != ERROR_OK)
816 return retval;
817
818 /* INFO_ID_PKT_SZ - short */
819 retval = cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_SZ, &data);
820 if (retval != ERROR_OK)
821 return retval;
822
823 if (data[0] == 2) { /* short */
824 uint16_t pkt_sz = data[1] + (data[2] << 8);
825
826 if (cmsis_dap_handle->packet_size != pkt_sz + 1) {
827 /* reallocate buffer */
828 cmsis_dap_handle->packet_size = pkt_sz + 1;
829 cmsis_dap_handle->packet_buffer = realloc(cmsis_dap_handle->packet_buffer,
830 cmsis_dap_handle->packet_size);
831 if (cmsis_dap_handle->packet_buffer == NULL) {
832 LOG_ERROR("unable to reallocate memory");
833 return ERROR_FAIL;
834 }
835 }
836
837 LOG_DEBUG("CMSIS-DAP: Packet Size = %" PRId16, pkt_sz);
838 }
839
840 /* INFO_ID_PKT_CNT - byte */
841 retval = cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_CNT, &data);
842 if (retval != ERROR_OK)
843 return retval;
844
845 if (data[0] == 1) { /* byte */
846 uint16_t pkt_cnt = data[1];
847 cmsis_dap_handle->packet_count = pkt_cnt;
848 LOG_DEBUG("CMSIS-DAP: Packet Count = %" PRId16, pkt_cnt);
849 }
850
851 retval = cmsis_dap_get_status();
852 if (retval != ERROR_OK)
853 return ERROR_FAIL;
854
855 /* Now try to connect to the target
856 * TODO: This is all SWD only @ present */
857 retval = cmsis_dap_cmd_DAP_SWJ_Clock(100); /* 100kHz */
858 if (retval != ERROR_OK)
859 return ERROR_FAIL;
860
861 retval = cmsis_dap_cmd_DAP_TFER_Configure(0, 64, 0);
862 if (retval != ERROR_OK)
863 return ERROR_FAIL;
864 retval = cmsis_dap_cmd_DAP_SWD_Configure(0x00);
865 if (retval != ERROR_OK)
866 return ERROR_FAIL;
867
868 retval = cmsis_dap_cmd_DAP_LED(0x03); /* Both LEDs on */
869 if (retval != ERROR_OK)
870 return ERROR_FAIL;
871
872 /* support connecting with srst asserted */
873 enum reset_types jtag_reset_config = jtag_get_reset_config();
874
875 if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
876 if (jtag_reset_config & RESET_SRST_NO_GATING) {
877 retval = cmsis_dap_cmd_DAP_SWJ_Pins(0, (1 << 7), 0, NULL);
878 if (retval != ERROR_OK)
879 return ERROR_FAIL;
880 LOG_INFO("Connecting under reset");
881 }
882 }
883
884 retval = cmsis_dap_reset_link();
885 if (retval != ERROR_OK)
886 return ERROR_FAIL;
887
888 cmsis_dap_cmd_DAP_LED(0x00); /* Both LEDs off */
889
890 LOG_INFO("CMSIS-DAP: Interface ready");
891
892 return ERROR_OK;
893 }
894
895 static int cmsis_dap_swd_init(void)
896 {
897 swd_mode = true;
898 return ERROR_OK;
899 }
900
901 static int cmsis_dap_quit(void)
902 {
903 cmsis_dap_cmd_DAP_Disconnect();
904 cmsis_dap_cmd_DAP_LED(0x00); /* Both LEDs off */
905
906 cmsis_dap_usb_close(cmsis_dap_handle);
907
908 return ERROR_OK;
909 }
910
911 static void cmsis_dap_execute_reset(struct jtag_command *cmd)
912 {
913 int retval = cmsis_dap_cmd_DAP_SWJ_Pins(cmd->cmd.reset->srst ? 0 : (1 << 7), \
914 (1 << 7), 0, NULL);
915 if (retval != ERROR_OK)
916 LOG_ERROR("CMSIS-DAP: Interface reset failed");
917 }
918
919 static void cmsis_dap_execute_sleep(struct jtag_command *cmd)
920 {
921 #if 0
922 int retval = cmsis_dap_cmd_DAP_Delay(cmd->cmd.sleep->us);
923 if (retval != ERROR_OK)
924 #endif
925 jtag_sleep(cmd->cmd.sleep->us);
926 }
927
928 static void cmsis_dap_execute_command(struct jtag_command *cmd)
929 {
930 switch (cmd->type) {
931 case JTAG_RESET:
932 cmsis_dap_execute_reset(cmd);
933 break;
934 case JTAG_SLEEP:
935 cmsis_dap_execute_sleep(cmd);
936 break;
937 default:
938 LOG_ERROR("BUG: unknown JTAG command type encountered");
939 exit(-1);
940 }
941 }
942
943 static int cmsis_dap_execute_queue(void)
944 {
945 struct jtag_command *cmd = jtag_command_queue;
946
947 while (cmd != NULL) {
948 cmsis_dap_execute_command(cmd);
949 cmd = cmd->next;
950 }
951
952 return ERROR_OK;
953 }
954
955 static int cmsis_dap_speed(int speed)
956 {
957 if (speed > DAP_MAX_CLOCK) {
958 LOG_INFO("reduce speed request: %dkHz to %dkHz maximum", speed, DAP_MAX_CLOCK);
959 speed = DAP_MAX_CLOCK;
960 }
961
962 if (speed == 0) {
963 LOG_INFO("RTCK not supported");
964 return ERROR_JTAG_NOT_IMPLEMENTED;
965 }
966
967 return cmsis_dap_cmd_DAP_SWJ_Clock(speed);
968 }
969
970 static int cmsis_dap_speed_div(int speed, int *khz)
971 {
972 *khz = speed;
973 return ERROR_OK;
974 }
975
976 static int cmsis_dap_khz(int khz, int *jtag_speed)
977 {
978 *jtag_speed = khz;
979 return ERROR_OK;
980 }
981
982 COMMAND_HANDLER(cmsis_dap_handle_info_command)
983 {
984 if (cmsis_dap_get_version_info() == ERROR_OK)
985 cmsis_dap_get_status();
986
987 return ERROR_OK;
988 }
989
990 COMMAND_HANDLER(cmsis_dap_handle_vid_pid_command)
991 {
992 if (CMD_ARGC > MAX_USB_IDS * 2) {
993 LOG_WARNING("ignoring extra IDs in cmsis_dap_vid_pid "
994 "(maximum is %d pairs)", MAX_USB_IDS);
995 CMD_ARGC = MAX_USB_IDS * 2;
996 }
997 if (CMD_ARGC < 2 || (CMD_ARGC & 1)) {
998 LOG_WARNING("incomplete cmsis_dap_vid_pid configuration directive");
999 if (CMD_ARGC < 2)
1000 return ERROR_COMMAND_SYNTAX_ERROR;
1001 /* remove the incomplete trailing id */
1002 CMD_ARGC -= 1;
1003 }
1004
1005 unsigned i;
1006 for (i = 0; i < CMD_ARGC; i += 2) {
1007 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], cmsis_dap_vid[i >> 1]);
1008 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], cmsis_dap_pid[i >> 1]);
1009 }
1010
1011 /*
1012 * Explicitly terminate, in case there are multiples instances of
1013 * cmsis_dap_vid_pid.
1014 */
1015 cmsis_dap_vid[i >> 1] = cmsis_dap_pid[i >> 1] = 0;
1016
1017 return ERROR_OK;
1018 }
1019
1020 COMMAND_HANDLER(cmsis_dap_handle_serial_command)
1021 {
1022 if (CMD_ARGC == 1) {
1023 size_t len = mbstowcs(NULL, CMD_ARGV[0], 0);
1024 cmsis_dap_serial = calloc(len + 1, sizeof(wchar_t));
1025 if (cmsis_dap_serial == NULL) {
1026 LOG_ERROR("unable to allocate memory");
1027 return ERROR_OK;
1028 }
1029 if (mbstowcs(cmsis_dap_serial, CMD_ARGV[0], len + 1) == (size_t)-1) {
1030 free(cmsis_dap_serial);
1031 cmsis_dap_serial = NULL;
1032 LOG_ERROR("unable to convert serial");
1033 }
1034 } else {
1035 LOG_ERROR("expected exactly one argument to cmsis_dap_serial <serial-number>");
1036 }
1037
1038 return ERROR_OK;
1039 }
1040
1041 static const struct command_registration cmsis_dap_subcommand_handlers[] = {
1042 {
1043 .name = "info",
1044 .handler = &cmsis_dap_handle_info_command,
1045 .mode = COMMAND_EXEC,
1046 .usage = "",
1047 .help = "show cmsis-dap info",
1048 },
1049 COMMAND_REGISTRATION_DONE
1050 };
1051
1052 static const struct command_registration cmsis_dap_command_handlers[] = {
1053 {
1054 .name = "cmsis-dap",
1055 .mode = COMMAND_ANY,
1056 .help = "perform CMSIS-DAP management",
1057 .usage = "<cmd>",
1058 .chain = cmsis_dap_subcommand_handlers,
1059 },
1060 {
1061 .name = "cmsis_dap_vid_pid",
1062 .handler = &cmsis_dap_handle_vid_pid_command,
1063 .mode = COMMAND_CONFIG,
1064 .help = "the vendor ID and product ID of the CMSIS-DAP device",
1065 .usage = "(vid pid)* ",
1066 },
1067 {
1068 .name = "cmsis_dap_serial",
1069 .handler = &cmsis_dap_handle_serial_command,
1070 .mode = COMMAND_CONFIG,
1071 .help = "set the serial number of the adapter",
1072 .usage = "serial_string",
1073 },
1074 COMMAND_REGISTRATION_DONE
1075 };
1076
1077 static const struct swd_driver cmsis_dap_swd_driver = {
1078 .init = cmsis_dap_swd_init,
1079 .read_reg = cmsis_dap_swd_read_reg,
1080 .write_reg = cmsis_dap_swd_write_reg,
1081 .run = cmsis_dap_swd_run,
1082 };
1083
1084 const char *cmsis_dap_transport[] = {"cmsis-dap", NULL};
1085
1086 struct jtag_interface cmsis_dap_interface = {
1087 .name = "cmsis-dap",
1088 .commands = cmsis_dap_command_handlers,
1089 .swd = &cmsis_dap_swd_driver,
1090 .transports = cmsis_dap_transport,
1091
1092 .execute_queue = cmsis_dap_execute_queue,
1093 .speed = cmsis_dap_speed,
1094 .speed_div = cmsis_dap_speed_div,
1095 .khz = cmsis_dap_khz,
1096 .init = cmsis_dap_init,
1097 .quit = cmsis_dap_quit,
1098 };

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)