jtag: fix minor typos
[openocd.git] / src / jtag / drivers / cmsis_dap_usb.c
1 /***************************************************************************
2 * Copyright (C) 2016 by Maksym Hilliaka *
3 * oter@frozen-team.com *
4 * *
5 * Copyright (C) 2016 by Phillip Pearson *
6 * pp@myelin.co.nz *
7 * *
8 * Copyright (C) 2014 by Paul Fertser *
9 * fercerpav@gmail.com *
10 * *
11 * Copyright (C) 2013 by mike brown *
12 * mike@theshedworks.org.uk *
13 * *
14 * Copyright (C) 2013 by Spencer Oliver *
15 * spen@spen-soft.co.uk *
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 2 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, *
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
25 * GNU General Public License for more details. *
26 * *
27 * You should have received a copy of the GNU General Public License *
28 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
29 ***************************************************************************/
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include <transport/transport.h>
36 #include <jtag/swd.h>
37 #include <jtag/interface.h>
38 #include <jtag/commands.h>
39 #include <jtag/tcl.h>
40
41 #include <hidapi.h>
42
43 /*
44 * See CMSIS-DAP documentation:
45 * Version 0.01 - Beta.
46 */
47
48 /* USB Config */
49
50 /* Known vid/pid pairs:
51 * VID 0xc251: Keil Software
52 * PID 0xf001: LPC-Link-II CMSIS_DAP
53 * PID 0xf002: OPEN-SDA CMSIS_DAP (Freedom Board)
54 * PID 0x2722: Keil ULINK2 CMSIS-DAP
55 *
56 * VID 0x0d28: mbed Software
57 * PID 0x0204: MBED CMSIS-DAP
58 */
59
60 #define MAX_USB_IDS 8
61 /* vid = pid = 0 marks the end of the list */
62 static uint16_t cmsis_dap_vid[MAX_USB_IDS + 1] = { 0 };
63 static uint16_t cmsis_dap_pid[MAX_USB_IDS + 1] = { 0 };
64 static wchar_t *cmsis_dap_serial;
65 static bool swd_mode;
66
67 #define PACKET_SIZE (64 + 1) /* 64 bytes plus report id */
68 #define USB_TIMEOUT 1000
69
70 /* CMSIS-DAP General Commands */
71 #define CMD_DAP_INFO 0x00
72 #define CMD_DAP_LED 0x01
73 #define CMD_DAP_CONNECT 0x02
74 #define CMD_DAP_DISCONNECT 0x03
75 #define CMD_DAP_WRITE_ABORT 0x08
76 #define CMD_DAP_DELAY 0x09
77 #define CMD_DAP_RESET_TARGET 0x0A
78
79 /* CMD_INFO */
80 #define INFO_ID_VENDOR 0x01 /* string */
81 #define INFO_ID_PRODUCT 0x02 /* string */
82 #define INFO_ID_SERNUM 0x03 /* string */
83 #define INFO_ID_FW_VER 0x04 /* string */
84 #define INFO_ID_TD_VEND 0x05 /* string */
85 #define INFO_ID_TD_NAME 0x06 /* string */
86 #define INFO_ID_CAPS 0xf0 /* byte */
87 #define INFO_ID_PKT_CNT 0xfe /* byte */
88 #define INFO_ID_PKT_SZ 0xff /* short */
89
90 #define INFO_CAPS_SWD 0x01
91 #define INFO_CAPS_JTAG 0x02
92
93 /* CMD_LED */
94 #define LED_ID_CONNECT 0x00
95 #define LED_ID_RUN 0x01
96
97 #define LED_OFF 0x00
98 #define LED_ON 0x01
99
100 /* CMD_CONNECT */
101 #define CONNECT_DEFAULT 0x00
102 #define CONNECT_SWD 0x01
103 #define CONNECT_JTAG 0x02
104
105 /* CMSIS-DAP Common SWD/JTAG Commands */
106 #define CMD_DAP_DELAY 0x09
107 #define CMD_DAP_SWJ_PINS 0x10
108 #define CMD_DAP_SWJ_CLOCK 0x11
109 #define CMD_DAP_SWJ_SEQ 0x12
110
111 /*
112 * PINS
113 * Bit 0: SWCLK/TCK
114 * Bit 1: SWDIO/TMS
115 * Bit 2: TDI
116 * Bit 3: TDO
117 * Bit 5: nTRST
118 * Bit 7: nRESET
119 */
120
121 #define SWJ_PIN_TCK (1<<0)
122 #define SWJ_PIN_TMS (1<<1)
123 #define SWJ_PIN_TDI (1<<2)
124 #define SWJ_PIN_TDO (1<<3)
125 #define SWJ_PIN_TRST (1<<5)
126 #define SWJ_PIN_SRST (1<<7)
127
128 /* CMSIS-DAP SWD Commands */
129 #define CMD_DAP_SWD_CONFIGURE 0x13
130
131 /* CMSIS-DAP JTAG Commands */
132 #define CMD_DAP_JTAG_SEQ 0x14
133 #define CMD_DAP_JTAG_CONFIGURE 0x15
134 #define CMD_DAP_JTAG_IDCODE 0x16
135
136 /* CMSIS-DAP JTAG sequence info masks */
137 /* Number of bits to clock through (0 means 64) */
138 #define DAP_JTAG_SEQ_TCK 0x3F
139 /* TMS will be set during the sequence if this bit is set */
140 #define DAP_JTAG_SEQ_TMS 0x40
141 /* TDO output will be captured if this bit is set */
142 #define DAP_JTAG_SEQ_TDO 0x80
143
144
145 /* CMSIS-DAP Transfer Commands */
146 #define CMD_DAP_TFER_CONFIGURE 0x04
147 #define CMD_DAP_TFER 0x05
148 #define CMD_DAP_TFER_BLOCK 0x06
149 #define CMD_DAP_TFER_ABORT 0x07
150
151 /* DAP Status Code */
152 #define DAP_OK 0
153 #define DAP_ERROR 0xFF
154
155 /* CMSIS-DAP Vendor Commands
156 * None as yet... */
157
158 static const char * const info_caps_str[] = {
159 "SWD Supported",
160 "JTAG Supported"
161 };
162
163 /* max clock speed (kHz) */
164 #define DAP_MAX_CLOCK 5000
165
166 struct cmsis_dap {
167 hid_device *dev_handle;
168 uint16_t packet_size;
169 int packet_count;
170 uint8_t *packet_buffer;
171 uint8_t caps;
172 uint8_t mode;
173 };
174
175 struct pending_transfer_result {
176 uint8_t cmd;
177 uint32_t data;
178 void *buffer;
179 };
180
181 struct pending_request_block {
182 struct pending_transfer_result *transfers;
183 int transfer_count;
184 };
185
186 struct pending_scan_result {
187 /** Offset in bytes in the CMD_DAP_JTAG_SEQ response buffer. */
188 unsigned first;
189 /** Number of bits to read. */
190 unsigned length;
191 /** Location to store the result */
192 uint8_t *buffer;
193 /** Offset in the destination buffer */
194 unsigned buffer_offset;
195 };
196
197 /* Up to MIN(packet_count, MAX_PENDING_REQUESTS) requests may be issued
198 * until the first response arrives */
199 #define MAX_PENDING_REQUESTS 3
200
201 /* Pending requests are organized as a FIFO - circular buffer */
202 /* Each block in FIFO can contain up to pending_queue_len transfers */
203 static int pending_queue_len;
204 static struct pending_request_block pending_fifo[MAX_PENDING_REQUESTS];
205 static int pending_fifo_put_idx, pending_fifo_get_idx;
206 static int pending_fifo_block_count;
207
208 /* pointers to buffers that will receive jtag scan results on the next flush */
209 #define MAX_PENDING_SCAN_RESULTS 256
210 static int pending_scan_result_count;
211 static struct pending_scan_result pending_scan_results[MAX_PENDING_SCAN_RESULTS];
212
213 /* queued JTAG sequences that will be executed on the next flush */
214 #define QUEUED_SEQ_BUF_LEN (cmsis_dap_handle->packet_size - 3)
215 static int queued_seq_count;
216 static int queued_seq_buf_end;
217 static int queued_seq_tdo_ptr;
218 static uint8_t queued_seq_buf[1024]; /* TODO: make dynamic / move into cmsis object */
219
220 static int queued_retval;
221
222 static uint8_t output_pins = SWJ_PIN_SRST | SWJ_PIN_TRST;
223
224 static struct cmsis_dap *cmsis_dap_handle;
225
226 static int cmsis_dap_usb_open(void)
227 {
228 hid_device *dev = NULL;
229 int i;
230 struct hid_device_info *devs, *cur_dev;
231 unsigned short target_vid, target_pid;
232 bool found = false;
233
234 target_vid = 0;
235 target_pid = 0;
236
237 if (hid_init() != 0) {
238 LOG_ERROR("unable to open HIDAPI");
239 return ERROR_FAIL;
240 }
241
242 /*
243 * The CMSIS-DAP specification stipulates:
244 * "The Product String must contain "CMSIS-DAP" somewhere in the string. This is used by the
245 * debuggers to identify a CMSIS-DAP compliant Debug Unit that is connected to a host computer."
246 */
247 devs = hid_enumerate(0x0, 0x0);
248 cur_dev = devs;
249 while (NULL != cur_dev) {
250 if (0 == cmsis_dap_vid[0]) {
251 if (NULL == cur_dev->product_string) {
252 LOG_DEBUG("Cannot read product string of device 0x%x:0x%x",
253 cur_dev->vendor_id, cur_dev->product_id);
254 } else {
255 if (wcsstr(cur_dev->product_string, L"CMSIS-DAP")) {
256 /* if the user hasn't specified VID:PID *and*
257 * product string contains "CMSIS-DAP", pick it
258 */
259 found = true;
260 }
261 }
262 } else {
263 /* otherwise, exhaustively compare against all VID:PID in list */
264 for (i = 0; cmsis_dap_vid[i] || cmsis_dap_pid[i]; i++) {
265 if ((cmsis_dap_vid[i] == cur_dev->vendor_id) && (cmsis_dap_pid[i] == cur_dev->product_id))
266 found = true;
267 }
268
269 if (cmsis_dap_vid[i] || cmsis_dap_pid[i])
270 found = true;
271 }
272
273 /* LPC-LINK2 has cmsis-dap on interface 0 and other HID functions on other interfaces */
274 if (cur_dev->vendor_id == 0x1fc9 && cur_dev->product_id == 0x0090 && cur_dev->interface_number != 0)
275 found = false;
276
277 if (found) {
278 /* we have found an adapter, so exit further checks */
279 /* check serial number matches if given */
280 if (cmsis_dap_serial != NULL) {
281 if ((cur_dev->serial_number != NULL) && wcscmp(cmsis_dap_serial, cur_dev->serial_number) == 0) {
282 break;
283 }
284 } else
285 break;
286
287 found = false;
288 }
289
290 cur_dev = cur_dev->next;
291 }
292
293 if (NULL != cur_dev) {
294 target_vid = cur_dev->vendor_id;
295 target_pid = cur_dev->product_id;
296 }
297
298 if (target_vid == 0 && target_pid == 0) {
299 LOG_ERROR("unable to find CMSIS-DAP device");
300 hid_free_enumeration(devs);
301 return ERROR_FAIL;
302 }
303
304 dev = hid_open_path(cur_dev->path);
305 hid_free_enumeration(devs);
306
307 if (dev == NULL) {
308 LOG_ERROR("unable to open CMSIS-DAP device 0x%x:0x%x", target_vid, target_pid);
309 return ERROR_FAIL;
310 }
311
312 struct cmsis_dap *dap = malloc(sizeof(struct cmsis_dap));
313 if (dap == NULL) {
314 LOG_ERROR("unable to allocate memory");
315 return ERROR_FAIL;
316 }
317
318 dap->dev_handle = dev;
319 dap->caps = 0;
320 dap->mode = 0;
321
322 cmsis_dap_handle = dap;
323
324 /* allocate default packet buffer, may be changed later.
325 * currently with HIDAPI we have no way of getting the output report length
326 * without this info we cannot communicate with the adapter.
327 * For the moment we ahve to hard code the packet size */
328
329 int packet_size = PACKET_SIZE;
330
331 /* atmel cmsis-dap uses 512 byte reports */
332 /* except when it doesn't e.g. with mEDBG on SAMD10 Xplained
333 * board */
334 /* TODO: HID report descriptor should be parsed instead of
335 * hardcoding a match by VID */
336 if (target_vid == 0x03eb && target_pid != 0x2145)
337 packet_size = 512 + 1;
338
339 cmsis_dap_handle->packet_buffer = malloc(packet_size);
340 cmsis_dap_handle->packet_size = packet_size;
341
342 if (cmsis_dap_handle->packet_buffer == NULL) {
343 LOG_ERROR("unable to allocate memory");
344 return ERROR_FAIL;
345 }
346
347 return ERROR_OK;
348 }
349
350 static void cmsis_dap_usb_close(struct cmsis_dap *dap)
351 {
352 hid_close(dap->dev_handle);
353 hid_exit();
354
355 free(cmsis_dap_handle->packet_buffer);
356 free(cmsis_dap_handle);
357 cmsis_dap_handle = NULL;
358 free(cmsis_dap_serial);
359 cmsis_dap_serial = NULL;
360
361 for (int i = 0; i < MAX_PENDING_REQUESTS; i++) {
362 free(pending_fifo[i].transfers);
363 pending_fifo[i].transfers = NULL;
364 }
365 }
366
367 static int cmsis_dap_usb_write(struct cmsis_dap *dap, int txlen)
368 {
369 #ifdef CMSIS_DAP_JTAG_DEBUG
370 LOG_DEBUG("cmsis-dap usb xfer cmd=%02X", dap->packet_buffer[1]);
371 #endif
372 /* Pad the rest of the TX buffer with 0's */
373 memset(dap->packet_buffer + txlen, 0, dap->packet_size - txlen);
374
375 /* write data to device */
376 int retval = hid_write(dap->dev_handle, dap->packet_buffer, dap->packet_size);
377 if (retval == -1) {
378 LOG_ERROR("error writing data: %ls", hid_error(dap->dev_handle));
379 return ERROR_FAIL;
380 }
381
382 return ERROR_OK;
383 }
384
385 /* Send a message and receive the reply */
386 static int cmsis_dap_usb_xfer(struct cmsis_dap *dap, int txlen)
387 {
388 if (pending_fifo_block_count) {
389 LOG_ERROR("pending %d blocks, flushing", pending_fifo_block_count);
390 while (pending_fifo_block_count) {
391 hid_read_timeout(dap->dev_handle, dap->packet_buffer, dap->packet_size, 10);
392 pending_fifo_block_count--;
393 }
394 pending_fifo_put_idx = 0;
395 pending_fifo_get_idx = 0;
396 }
397
398 int retval = cmsis_dap_usb_write(dap, txlen);
399 if (retval != ERROR_OK)
400 return retval;
401
402 /* get reply */
403 retval = hid_read_timeout(dap->dev_handle, dap->packet_buffer, dap->packet_size, USB_TIMEOUT);
404 if (retval == -1 || retval == 0) {
405 LOG_DEBUG("error reading data: %ls", hid_error(dap->dev_handle));
406 return ERROR_FAIL;
407 }
408
409 return ERROR_OK;
410 }
411
412 static int cmsis_dap_cmd_DAP_SWJ_Pins(uint8_t pins, uint8_t mask, uint32_t delay, uint8_t *input)
413 {
414 int retval;
415 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
416
417 buffer[0] = 0; /* report number */
418 buffer[1] = CMD_DAP_SWJ_PINS;
419 buffer[2] = pins;
420 buffer[3] = mask;
421 buffer[4] = delay & 0xff;
422 buffer[5] = (delay >> 8) & 0xff;
423 buffer[6] = (delay >> 16) & 0xff;
424 buffer[7] = (delay >> 24) & 0xff;
425 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 8);
426
427 if (retval != ERROR_OK) {
428 LOG_ERROR("CMSIS-DAP command CMD_DAP_SWJ_PINS failed.");
429 return ERROR_JTAG_DEVICE_ERROR;
430 }
431
432 if (input)
433 *input = buffer[1];
434
435 return ERROR_OK;
436 }
437
438 static int cmsis_dap_cmd_DAP_SWJ_Clock(uint32_t swj_clock)
439 {
440 int retval;
441 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
442
443 /* set clock in Hz */
444 swj_clock *= 1000;
445 buffer[0] = 0; /* report number */
446 buffer[1] = CMD_DAP_SWJ_CLOCK;
447 buffer[2] = swj_clock & 0xff;
448 buffer[3] = (swj_clock >> 8) & 0xff;
449 buffer[4] = (swj_clock >> 16) & 0xff;
450 buffer[5] = (swj_clock >> 24) & 0xff;
451 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 6);
452
453 if (retval != ERROR_OK || buffer[1] != DAP_OK) {
454 LOG_ERROR("CMSIS-DAP command CMD_DAP_SWJ_CLOCK failed.");
455 return ERROR_JTAG_DEVICE_ERROR;
456 }
457
458 return ERROR_OK;
459 }
460
461 /* clock a sequence of bits out on TMS, to change JTAG states */
462 static int cmsis_dap_cmd_DAP_SWJ_Sequence(uint8_t s_len, const uint8_t *sequence)
463 {
464 int retval;
465 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
466
467 #ifdef CMSIS_DAP_JTAG_DEBUG
468 LOG_DEBUG("cmsis-dap TMS sequence: len=%d", s_len);
469 for (int i = 0; i < DIV_ROUND_UP(s_len, 8); ++i)
470 printf("%02X ", sequence[i]);
471
472 printf("\n");
473 #endif
474
475 buffer[0] = 0; /* report number */
476 buffer[1] = CMD_DAP_SWJ_SEQ;
477 buffer[2] = s_len;
478 bit_copy(&buffer[3], 0, sequence, 0, s_len);
479
480 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, DIV_ROUND_UP(s_len, 8) + 3);
481
482 if (retval != ERROR_OK || buffer[1] != DAP_OK)
483 return ERROR_FAIL;
484
485 return ERROR_OK;
486 }
487
488 static int cmsis_dap_cmd_DAP_Info(uint8_t info, uint8_t **data)
489 {
490 int retval;
491 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
492
493 buffer[0] = 0; /* report number */
494 buffer[1] = CMD_DAP_INFO;
495 buffer[2] = info;
496 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 3);
497
498 if (retval != ERROR_OK) {
499 LOG_ERROR("CMSIS-DAP command CMD_INFO failed.");
500 return ERROR_JTAG_DEVICE_ERROR;
501 }
502
503 *data = &(buffer[1]);
504
505 return ERROR_OK;
506 }
507
508 static int cmsis_dap_cmd_DAP_LED(uint8_t led, uint8_t state)
509 {
510 int retval;
511 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
512
513 buffer[0] = 0; /* report number */
514 buffer[1] = CMD_DAP_LED;
515 buffer[2] = led;
516 buffer[3] = state;
517 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 4);
518
519 if (retval != ERROR_OK || buffer[1] != 0x00) {
520 LOG_ERROR("CMSIS-DAP command CMD_LED failed.");
521 return ERROR_JTAG_DEVICE_ERROR;
522 }
523
524 return ERROR_OK;
525 }
526
527 static int cmsis_dap_cmd_DAP_Connect(uint8_t mode)
528 {
529 int retval;
530 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
531
532 buffer[0] = 0; /* report number */
533 buffer[1] = CMD_DAP_CONNECT;
534 buffer[2] = mode;
535 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 3);
536
537 if (retval != ERROR_OK) {
538 LOG_ERROR("CMSIS-DAP command CMD_CONNECT failed.");
539 return ERROR_JTAG_DEVICE_ERROR;
540 }
541
542 if (buffer[1] != mode) {
543 LOG_ERROR("CMSIS-DAP failed to connect in mode (%d)", mode);
544 return ERROR_JTAG_DEVICE_ERROR;
545 }
546
547 return ERROR_OK;
548 }
549
550 static int cmsis_dap_cmd_DAP_Disconnect(void)
551 {
552 int retval;
553 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
554
555 buffer[0] = 0; /* report number */
556 buffer[1] = CMD_DAP_DISCONNECT;
557 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 2);
558
559 if (retval != ERROR_OK || buffer[1] != DAP_OK) {
560 LOG_ERROR("CMSIS-DAP command CMD_DISCONNECT failed.");
561 return ERROR_JTAG_DEVICE_ERROR;
562 }
563
564 return ERROR_OK;
565 }
566
567 static int cmsis_dap_cmd_DAP_TFER_Configure(uint8_t idle, uint16_t retry_count, uint16_t match_retry)
568 {
569 int retval;
570 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
571
572 buffer[0] = 0; /* report number */
573 buffer[1] = CMD_DAP_TFER_CONFIGURE;
574 buffer[2] = idle;
575 buffer[3] = retry_count & 0xff;
576 buffer[4] = (retry_count >> 8) & 0xff;
577 buffer[5] = match_retry & 0xff;
578 buffer[6] = (match_retry >> 8) & 0xff;
579 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 7);
580
581 if (retval != ERROR_OK || buffer[1] != DAP_OK) {
582 LOG_ERROR("CMSIS-DAP command CMD_TFER_Configure failed.");
583 return ERROR_JTAG_DEVICE_ERROR;
584 }
585
586 return ERROR_OK;
587 }
588
589 static int cmsis_dap_cmd_DAP_SWD_Configure(uint8_t cfg)
590 {
591 int retval;
592 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
593
594 buffer[0] = 0; /* report number */
595 buffer[1] = CMD_DAP_SWD_CONFIGURE;
596 buffer[2] = cfg;
597 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 3);
598
599 if (retval != ERROR_OK || buffer[1] != DAP_OK) {
600 LOG_ERROR("CMSIS-DAP command CMD_SWD_Configure failed.");
601 return ERROR_JTAG_DEVICE_ERROR;
602 }
603
604 return ERROR_OK;
605 }
606
607 #if 0
608 static int cmsis_dap_cmd_DAP_Delay(uint16_t delay_us)
609 {
610 int retval;
611 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
612
613 buffer[0] = 0; /* report number */
614 buffer[1] = CMD_DAP_DELAY;
615 buffer[2] = delay_us & 0xff;
616 buffer[3] = (delay_us >> 8) & 0xff;
617 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 4);
618
619 if (retval != ERROR_OK || buffer[1] != DAP_OK) {
620 LOG_ERROR("CMSIS-DAP command CMD_Delay failed.");
621 return ERROR_JTAG_DEVICE_ERROR;
622 }
623
624 return ERROR_OK;
625 }
626 #endif
627
628 static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap)
629 {
630 uint8_t *buffer = dap->packet_buffer;
631 struct pending_request_block *block = &pending_fifo[pending_fifo_put_idx];
632
633 LOG_DEBUG_IO("Executing %d queued transactions from FIFO index %d", block->transfer_count, pending_fifo_put_idx);
634
635 if (queued_retval != ERROR_OK) {
636 LOG_DEBUG("Skipping due to previous errors: %d", queued_retval);
637 goto skip;
638 }
639
640 if (block->transfer_count == 0)
641 goto skip;
642
643 size_t idx = 0;
644 buffer[idx++] = 0; /* report number */
645 buffer[idx++] = CMD_DAP_TFER;
646 buffer[idx++] = 0x00; /* DAP Index */
647 buffer[idx++] = block->transfer_count;
648
649 for (int i = 0; i < block->transfer_count; i++) {
650 struct pending_transfer_result *transfer = &(block->transfers[i]);
651 uint8_t cmd = transfer->cmd;
652 uint32_t data = transfer->data;
653
654 LOG_DEBUG_IO("%s %s reg %x %"PRIx32,
655 cmd & SWD_CMD_APnDP ? "AP" : "DP",
656 cmd & SWD_CMD_RnW ? "read" : "write",
657 (cmd & SWD_CMD_A32) >> 1, data);
658
659 /* When proper WAIT handling is implemented in the
660 * common SWD framework, this kludge can be
661 * removed. However, this might lead to minor
662 * performance degradation as the adapter wouldn't be
663 * able to automatically retry anything (because ARM
664 * has forgotten to implement sticky error flags
665 * clearing). See also comments regarding
666 * cmsis_dap_cmd_DAP_TFER_Configure() and
667 * cmsis_dap_cmd_DAP_SWD_Configure() in
668 * cmsis_dap_init().
669 */
670 if (!(cmd & SWD_CMD_RnW) &&
671 !(cmd & SWD_CMD_APnDP) &&
672 (cmd & SWD_CMD_A32) >> 1 == DP_CTRL_STAT &&
673 (data & CORUNDETECT)) {
674 LOG_DEBUG("refusing to enable sticky overrun detection");
675 data &= ~CORUNDETECT;
676 }
677
678 buffer[idx++] = (cmd >> 1) & 0x0f;
679 if (!(cmd & SWD_CMD_RnW)) {
680 buffer[idx++] = (data) & 0xff;
681 buffer[idx++] = (data >> 8) & 0xff;
682 buffer[idx++] = (data >> 16) & 0xff;
683 buffer[idx++] = (data >> 24) & 0xff;
684 }
685 }
686
687 queued_retval = cmsis_dap_usb_write(dap, idx);
688 if (queued_retval != ERROR_OK)
689 goto skip;
690
691 pending_fifo_put_idx = (pending_fifo_put_idx + 1) % dap->packet_count;
692 pending_fifo_block_count++;
693 if (pending_fifo_block_count > dap->packet_count)
694 LOG_ERROR("too much pending writes %d", pending_fifo_block_count);
695
696 return;
697
698 skip:
699 block->transfer_count = 0;
700 }
701
702 static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms)
703 {
704 uint8_t *buffer = dap->packet_buffer;
705 struct pending_request_block *block = &pending_fifo[pending_fifo_get_idx];
706
707 if (pending_fifo_block_count == 0)
708 LOG_ERROR("no pending write");
709
710 /* get reply */
711 int retval = hid_read_timeout(dap->dev_handle, dap->packet_buffer, dap->packet_size, timeout_ms);
712 if (retval == 0 && timeout_ms < USB_TIMEOUT)
713 return;
714
715 if (retval == -1 || retval == 0) {
716 LOG_DEBUG("error reading data: %ls", hid_error(dap->dev_handle));
717 queued_retval = ERROR_FAIL;
718 goto skip;
719 }
720
721 if (buffer[2] & 0x08) {
722 LOG_DEBUG("CMSIS-DAP Protocol Error @ %d (wrong parity)", buffer[1]);
723 queued_retval = ERROR_FAIL;
724 goto skip;
725 }
726 uint8_t ack = buffer[2] & 0x07;
727 if (ack != SWD_ACK_OK) {
728 LOG_DEBUG("SWD ack not OK @ %d %s", buffer[1],
729 ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK");
730 queued_retval = ack == SWD_ACK_WAIT ? ERROR_WAIT : ERROR_FAIL;
731 goto skip;
732 }
733
734 if (block->transfer_count != buffer[1])
735 LOG_ERROR("CMSIS-DAP transfer count mismatch: expected %d, got %d",
736 block->transfer_count, buffer[1]);
737
738 LOG_DEBUG_IO("Received results of %d queued transactions FIFO index %d", buffer[1], pending_fifo_get_idx);
739 size_t idx = 3;
740 for (int i = 0; i < buffer[1]; i++) {
741 struct pending_transfer_result *transfer = &(block->transfers[i]);
742 if (transfer->cmd & SWD_CMD_RnW) {
743 static uint32_t last_read;
744 uint32_t data = le_to_h_u32(&buffer[idx]);
745 uint32_t tmp = data;
746 idx += 4;
747
748 LOG_DEBUG_IO("Read result: %"PRIx32, data);
749
750 /* Imitate posted AP reads */
751 if ((transfer->cmd & SWD_CMD_APnDP) ||
752 ((transfer->cmd & SWD_CMD_A32) >> 1 == DP_RDBUFF)) {
753 tmp = last_read;
754 last_read = data;
755 }
756
757 if (transfer->buffer)
758 *(uint32_t *)(transfer->buffer) = tmp;
759 }
760 }
761
762 skip:
763 block->transfer_count = 0;
764 pending_fifo_get_idx = (pending_fifo_get_idx + 1) % dap->packet_count;
765 pending_fifo_block_count--;
766 }
767
768 static int cmsis_dap_swd_run_queue(void)
769 {
770 if (pending_fifo_block_count)
771 cmsis_dap_swd_read_process(cmsis_dap_handle, 0);
772
773 cmsis_dap_swd_write_from_queue(cmsis_dap_handle);
774
775 while (pending_fifo_block_count)
776 cmsis_dap_swd_read_process(cmsis_dap_handle, USB_TIMEOUT);
777
778 pending_fifo_put_idx = 0;
779 pending_fifo_get_idx = 0;
780
781 int retval = queued_retval;
782 queued_retval = ERROR_OK;
783
784 return retval;
785 }
786
787 static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data)
788 {
789 if (pending_fifo[pending_fifo_put_idx].transfer_count == pending_queue_len) {
790 if (pending_fifo_block_count)
791 cmsis_dap_swd_read_process(cmsis_dap_handle, 0);
792
793 /* Not enough room in the queue. Run the queue. */
794 cmsis_dap_swd_write_from_queue(cmsis_dap_handle);
795
796 if (pending_fifo_block_count >= cmsis_dap_handle->packet_count)
797 cmsis_dap_swd_read_process(cmsis_dap_handle, USB_TIMEOUT);
798 }
799
800 if (queued_retval != ERROR_OK)
801 return;
802
803 struct pending_request_block *block = &pending_fifo[pending_fifo_put_idx];
804 struct pending_transfer_result *transfer = &(block->transfers[block->transfer_count]);
805 transfer->data = data;
806 transfer->cmd = cmd;
807 if (cmd & SWD_CMD_RnW) {
808 /* Queue a read transaction */
809 transfer->buffer = dst;
810 }
811 block->transfer_count++;
812 }
813
814 static void cmsis_dap_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
815 {
816 assert(!(cmd & SWD_CMD_RnW));
817 cmsis_dap_swd_queue_cmd(cmd, NULL, value);
818 }
819
820 static void cmsis_dap_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
821 {
822 assert(cmd & SWD_CMD_RnW);
823 cmsis_dap_swd_queue_cmd(cmd, value, 0);
824 }
825
826 static int cmsis_dap_get_serial_info(void)
827 {
828 uint8_t *data;
829
830 int retval = cmsis_dap_cmd_DAP_Info(INFO_ID_SERNUM, &data);
831 if (retval != ERROR_OK)
832 return retval;
833
834 if (data[0]) /* strlen */
835 LOG_INFO("CMSIS-DAP: Serial# = %s", &data[1]);
836
837 return ERROR_OK;
838 }
839
840 static int cmsis_dap_get_version_info(void)
841 {
842 uint8_t *data;
843
844 /* INFO_ID_FW_VER - string */
845 int retval = cmsis_dap_cmd_DAP_Info(INFO_ID_FW_VER, &data);
846 if (retval != ERROR_OK)
847 return retval;
848
849 if (data[0]) /* strlen */
850 LOG_INFO("CMSIS-DAP: FW Version = %s", &data[1]);
851
852 return ERROR_OK;
853 }
854
855 static int cmsis_dap_get_caps_info(void)
856 {
857 uint8_t *data;
858
859 /* INFO_ID_CAPS - byte */
860 int retval = cmsis_dap_cmd_DAP_Info(INFO_ID_CAPS, &data);
861 if (retval != ERROR_OK)
862 return retval;
863
864 if (data[0] == 1) {
865 uint8_t caps = data[1];
866
867 cmsis_dap_handle->caps = caps;
868
869 if (caps & INFO_CAPS_SWD)
870 LOG_INFO("CMSIS-DAP: %s", info_caps_str[0]);
871 if (caps & INFO_CAPS_JTAG)
872 LOG_INFO("CMSIS-DAP: %s", info_caps_str[1]);
873 }
874
875 return ERROR_OK;
876 }
877
878 static int cmsis_dap_get_status(void)
879 {
880 uint8_t d;
881
882 int retval = cmsis_dap_cmd_DAP_SWJ_Pins(0, 0, 0, &d);
883
884 if (retval == ERROR_OK) {
885 LOG_INFO("SWCLK/TCK = %d SWDIO/TMS = %d TDI = %d TDO = %d nTRST = %d nRESET = %d",
886 (d & SWJ_PIN_TCK) ? 1 : 0,
887 (d & SWJ_PIN_TMS) ? 1 : 0,
888 (d & SWJ_PIN_TDI) ? 1 : 0,
889 (d & SWJ_PIN_TDO) ? 1 : 0,
890 (d & SWJ_PIN_TRST) ? 1 : 0,
891 (d & SWJ_PIN_SRST) ? 1 : 0);
892 }
893
894 return retval;
895 }
896
897 static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
898 {
899 const uint8_t *s;
900 unsigned int s_len;
901 int retval;
902
903 if ((output_pins & (SWJ_PIN_SRST | SWJ_PIN_TRST)) == (SWJ_PIN_SRST | SWJ_PIN_TRST)) {
904 /* Following workaround deasserts reset on most adapters.
905 * Do not reconnect if a reset line is active!
906 * Reconnecting would break connecting under reset. */
907
908 /* First disconnect before connecting, Atmel EDBG needs it for SAMD/R/L/C */
909 cmsis_dap_cmd_DAP_Disconnect();
910
911 /* When we are reconnecting, DAP_Connect needs to be rerun, at
912 * least on Keil ULINK-ME */
913 retval = cmsis_dap_cmd_DAP_Connect(CONNECT_SWD);
914 if (retval != ERROR_OK)
915 return retval;
916 }
917
918 switch (seq) {
919 case LINE_RESET:
920 LOG_DEBUG("SWD line reset");
921 s = swd_seq_line_reset;
922 s_len = swd_seq_line_reset_len;
923 break;
924 case JTAG_TO_SWD:
925 LOG_DEBUG("JTAG-to-SWD");
926 s = swd_seq_jtag_to_swd;
927 s_len = swd_seq_jtag_to_swd_len;
928 break;
929 case SWD_TO_JTAG:
930 LOG_DEBUG("SWD-to-JTAG");
931 s = swd_seq_swd_to_jtag;
932 s_len = swd_seq_swd_to_jtag_len;
933 break;
934 default:
935 LOG_ERROR("Sequence %d not supported", seq);
936 return ERROR_FAIL;
937 }
938
939 retval = cmsis_dap_cmd_DAP_SWJ_Sequence(s_len, s);
940 if (retval != ERROR_OK)
941 return retval;
942
943 /* Atmel EDBG needs renew clock setting after SWJ_Sequence
944 * otherwise default frequency is used */
945 return cmsis_dap_cmd_DAP_SWJ_Clock(jtag_get_speed_khz());
946 }
947
948 static int cmsis_dap_swd_open(void)
949 {
950 int retval;
951
952 if (!(cmsis_dap_handle->caps & INFO_CAPS_SWD)) {
953 LOG_ERROR("CMSIS-DAP: SWD not supported");
954 return ERROR_JTAG_DEVICE_ERROR;
955 }
956
957 retval = cmsis_dap_cmd_DAP_Connect(CONNECT_SWD);
958 if (retval != ERROR_OK)
959 return retval;
960
961 /* Add more setup here.??... */
962
963 LOG_INFO("CMSIS-DAP: Interface Initialised (SWD)");
964 return ERROR_OK;
965 }
966
967 static int cmsis_dap_init(void)
968 {
969 int retval;
970 uint8_t *data;
971
972 retval = cmsis_dap_usb_open();
973 if (retval != ERROR_OK)
974 return retval;
975
976 retval = cmsis_dap_get_caps_info();
977 if (retval != ERROR_OK)
978 return retval;
979
980 retval = cmsis_dap_get_version_info();
981 if (retval != ERROR_OK)
982 return retval;
983
984 retval = cmsis_dap_get_serial_info();
985 if (retval != ERROR_OK)
986 return retval;
987
988 if (swd_mode) {
989 retval = cmsis_dap_swd_open();
990 if (retval != ERROR_OK)
991 return retval;
992 } else {
993 /* Connect in JTAG mode */
994 if (!(cmsis_dap_handle->caps & INFO_CAPS_JTAG)) {
995 LOG_ERROR("CMSIS-DAP: JTAG not supported");
996 return ERROR_JTAG_DEVICE_ERROR;
997 }
998
999 retval = cmsis_dap_cmd_DAP_Connect(CONNECT_JTAG);
1000 if (retval != ERROR_OK)
1001 return retval;
1002
1003 LOG_INFO("CMSIS-DAP: Interface Initialised (JTAG)");
1004 }
1005
1006 /* Be conservative and suppress submitting multiple HID requests
1007 * until we get packet count info from the adaptor */
1008 cmsis_dap_handle->packet_count = 1;
1009 pending_queue_len = 12;
1010
1011 /* INFO_ID_PKT_SZ - short */
1012 retval = cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_SZ, &data);
1013 if (retval != ERROR_OK)
1014 return retval;
1015
1016 if (data[0] == 2) { /* short */
1017 uint16_t pkt_sz = data[1] + (data[2] << 8);
1018
1019 /* 4 bytes of command header + 5 bytes per register
1020 * write. For bulk read sequences just 4 bytes are
1021 * needed per transfer, so this is suboptimal. */
1022 pending_queue_len = (pkt_sz - 4) / 5;
1023
1024 if (cmsis_dap_handle->packet_size != pkt_sz + 1) {
1025 /* reallocate buffer */
1026 cmsis_dap_handle->packet_size = pkt_sz + 1;
1027 cmsis_dap_handle->packet_buffer = realloc(cmsis_dap_handle->packet_buffer,
1028 cmsis_dap_handle->packet_size);
1029 if (cmsis_dap_handle->packet_buffer == NULL) {
1030 LOG_ERROR("unable to reallocate memory");
1031 return ERROR_FAIL;
1032 }
1033 }
1034
1035 LOG_DEBUG("CMSIS-DAP: Packet Size = %" PRId16, pkt_sz);
1036 }
1037
1038 /* INFO_ID_PKT_CNT - byte */
1039 retval = cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_CNT, &data);
1040 if (retval != ERROR_OK)
1041 return retval;
1042
1043 if (data[0] == 1) { /* byte */
1044 int pkt_cnt = data[1];
1045 if (pkt_cnt > 1)
1046 cmsis_dap_handle->packet_count = MIN(MAX_PENDING_REQUESTS, pkt_cnt);
1047
1048 LOG_DEBUG("CMSIS-DAP: Packet Count = %d", pkt_cnt);
1049 }
1050
1051 LOG_DEBUG("Allocating FIFO for %d pending HID requests", cmsis_dap_handle->packet_count);
1052 for (int i = 0; i < cmsis_dap_handle->packet_count; i++) {
1053 pending_fifo[i].transfers = malloc(pending_queue_len * sizeof(struct pending_transfer_result));
1054 if (!pending_fifo[i].transfers) {
1055 LOG_ERROR("Unable to allocate memory for CMSIS-DAP queue");
1056 return ERROR_FAIL;
1057 }
1058 }
1059
1060
1061 retval = cmsis_dap_get_status();
1062 if (retval != ERROR_OK)
1063 return ERROR_FAIL;
1064
1065 /* Now try to connect to the target
1066 * TODO: This is all SWD only @ present */
1067 retval = cmsis_dap_cmd_DAP_SWJ_Clock(jtag_get_speed_khz());
1068 if (retval != ERROR_OK)
1069 return ERROR_FAIL;
1070
1071 /* Ask CMSIS-DAP to automatically retry on receiving WAIT for
1072 * up to 64 times. This must be changed to 0 if sticky
1073 * overrun detection is enabled. */
1074 retval = cmsis_dap_cmd_DAP_TFER_Configure(0, 64, 0);
1075 if (retval != ERROR_OK)
1076 return ERROR_FAIL;
1077
1078 if (swd_mode) {
1079 /* Data Phase (bit 2) must be set to 1 if sticky overrun
1080 * detection is enabled */
1081 retval = cmsis_dap_cmd_DAP_SWD_Configure(0); /* 1 TRN, no Data Phase */
1082 if (retval != ERROR_OK)
1083 return ERROR_FAIL;
1084 }
1085 /* Both LEDs on */
1086 retval = cmsis_dap_cmd_DAP_LED(LED_ID_CONNECT, LED_ON);
1087 if (retval != ERROR_OK)
1088 return ERROR_FAIL;
1089
1090 retval = cmsis_dap_cmd_DAP_LED(LED_ID_RUN, LED_ON);
1091 if (retval != ERROR_OK)
1092 return ERROR_FAIL;
1093
1094 /* support connecting with srst asserted */
1095 enum reset_types jtag_reset_config = jtag_get_reset_config();
1096
1097 if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
1098 if (jtag_reset_config & RESET_SRST_NO_GATING) {
1099 retval = cmsis_dap_cmd_DAP_SWJ_Pins(0, SWJ_PIN_SRST, 0, NULL);
1100 if (retval != ERROR_OK)
1101 return ERROR_FAIL;
1102 LOG_INFO("Connecting under reset");
1103 }
1104 }
1105 LOG_INFO("CMSIS-DAP: Interface ready");
1106
1107 return ERROR_OK;
1108 }
1109
1110 static int cmsis_dap_swd_init(void)
1111 {
1112 swd_mode = true;
1113 return ERROR_OK;
1114 }
1115
1116 static int cmsis_dap_quit(void)
1117 {
1118 cmsis_dap_cmd_DAP_Disconnect();
1119 /* Both LEDs off */
1120 cmsis_dap_cmd_DAP_LED(LED_ID_RUN, LED_OFF);
1121 cmsis_dap_cmd_DAP_LED(LED_ID_CONNECT, LED_OFF);
1122
1123 cmsis_dap_usb_close(cmsis_dap_handle);
1124
1125 return ERROR_OK;
1126 }
1127
1128 static int cmsis_dap_reset(int trst, int srst)
1129 {
1130 /* Set both TRST and SRST even if they're not enabled as
1131 * there's no way to tristate them */
1132
1133 output_pins = 0;
1134 if (!srst)
1135 output_pins |= SWJ_PIN_SRST;
1136 if (!trst)
1137 output_pins |= SWJ_PIN_TRST;
1138
1139 int retval = cmsis_dap_cmd_DAP_SWJ_Pins(output_pins,
1140 SWJ_PIN_TRST | SWJ_PIN_SRST, 0, NULL);
1141 if (retval != ERROR_OK)
1142 LOG_ERROR("CMSIS-DAP: Interface reset failed");
1143 return retval;
1144 }
1145
1146 static void cmsis_dap_execute_sleep(struct jtag_command *cmd)
1147 {
1148 #if 0
1149 int retval = cmsis_dap_cmd_DAP_Delay(cmd->cmd.sleep->us);
1150 if (retval != ERROR_OK)
1151 #endif
1152 jtag_sleep(cmd->cmd.sleep->us);
1153 }
1154
1155 /* Set TMS high for five TCK clocks, to move the TAP to the Test-Logic-Reset state */
1156 static int cmsis_dap_execute_tlr_reset(struct jtag_command *cmd)
1157 {
1158 LOG_INFO("cmsis-dap JTAG TLR_RESET");
1159 uint8_t seq = 0xff;
1160 int ret = cmsis_dap_cmd_DAP_SWJ_Sequence(8, &seq);
1161 if (ret == ERROR_OK)
1162 tap_set_state(TAP_RESET);
1163 return ret;
1164 }
1165
1166 /* Set new end state */
1167 static void cmsis_dap_end_state(tap_state_t state)
1168 {
1169 if (tap_is_state_stable(state))
1170 tap_set_end_state(state);
1171 else {
1172 LOG_ERROR("BUG: %i is not a valid end state", state);
1173 exit(-1);
1174 }
1175 }
1176
1177 #ifdef SPRINT_BINARY
1178 static void sprint_binary(char *s, const uint8_t *buf, int offset, int len)
1179 {
1180 if (!len)
1181 return;
1182
1183 /*
1184 buf = { 0x18 } len=5 should result in: 11000
1185 buf = { 0xff 0x18 } len=13 should result in: 11111111 11000
1186 buf = { 0xc0 0x18 } offset=3 len=10 should result in: 11000 11000
1187 i=3 there means i/8 = 0 so c = 0xFF, and
1188 */
1189 for (int i = offset; i < offset + len; ++i) {
1190 uint8_t c = buf[i / 8], mask = 1 << (i % 8);
1191 if ((i != offset) && !(i % 8))
1192 putchar(' ');
1193 *s++ = (c & mask) ? '1' : '0';
1194 }
1195 *s = 0;
1196 }
1197 #endif
1198
1199 #ifdef CMSIS_DAP_JTAG_DEBUG
1200 static void debug_parse_cmsis_buf(const uint8_t *cmd, int cmdlen)
1201 {
1202 /* cmd is a usb packet to go to the cmsis-dap interface */
1203 printf("cmsis-dap buffer (%d b): ", cmdlen);
1204 for (int i = 0; i < cmdlen; ++i)
1205 printf(" %02x", cmd[i]);
1206 printf("\n");
1207 switch (cmd[1]) {
1208 case CMD_DAP_JTAG_SEQ: {
1209 printf("cmsis-dap jtag sequence command %02x (n=%d)\n", cmd[1], cmd[2]);
1210 /*
1211 * #2 = number of sequences
1212 * #3 = sequence info 1
1213 * #4...4+n_bytes-1 = sequence 1
1214 * #4+n_bytes = sequence info 2
1215 * #5+n_bytes = sequence 2 (single bit)
1216 */
1217 int pos = 3;
1218 for (int seq = 0; seq < cmd[2]; ++seq) {
1219 uint8_t info = cmd[pos++];
1220 int len = info & DAP_JTAG_SEQ_TCK;
1221 if (len == 0)
1222 len = 64;
1223 printf(" sequence %d starting %d: info %02x (len=%d tms=%d read_tdo=%d): ",
1224 seq, pos, info, len, info & DAP_JTAG_SEQ_TMS, info & DAP_JTAG_SEQ_TDO);
1225 for (int i = 0; i < DIV_ROUND_UP(len, 8); ++i)
1226 printf(" %02x", cmd[pos+i]);
1227 pos += DIV_ROUND_UP(len, 8);
1228 printf("\n");
1229 }
1230 if (pos != cmdlen) {
1231 printf("BUFFER LENGTH MISMATCH looks like %d but %d specified", pos, cmdlen);
1232 exit(-1);
1233 }
1234
1235 break;
1236 }
1237 default:
1238 LOG_DEBUG("unknown cmsis-dap command %02x", cmd[1]);
1239 break;
1240 }
1241 }
1242 #endif
1243
1244 static void cmsis_dap_flush(void)
1245 {
1246 if (!queued_seq_count)
1247 return;
1248
1249 LOG_DEBUG_IO("Flushing %d queued sequences (%d bytes) with %d pending scan results to capture",
1250 queued_seq_count, queued_seq_buf_end, pending_scan_result_count);
1251
1252 /* prep CMSIS-DAP packet */
1253 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
1254 buffer[0] = 0; /* report number */
1255 buffer[1] = CMD_DAP_JTAG_SEQ;
1256 buffer[2] = queued_seq_count;
1257 memcpy(buffer + 3, queued_seq_buf, queued_seq_buf_end);
1258
1259 #ifdef CMSIS_DAP_JTAG_DEBUG
1260 debug_parse_cmsis_buf(buffer, queued_seq_buf_end + 3);
1261 #endif
1262
1263 /* send command to USB device */
1264 int retval = cmsis_dap_usb_xfer(cmsis_dap_handle, queued_seq_buf_end + 3);
1265 if (retval != ERROR_OK || buffer[1] != DAP_OK) {
1266 LOG_ERROR("CMSIS-DAP command CMD_DAP_JTAG_SEQ failed.");
1267 exit(-1);
1268 }
1269
1270 #ifdef CMSIS_DAP_JTAG_DEBUG
1271 LOG_DEBUG_IO("USB response buf:");
1272 for (int c = 0; c < queued_seq_buf_end + 3; ++c)
1273 printf("%02X ", buffer[c]);
1274 printf("\n");
1275 #endif
1276
1277 /* copy scan results into client buffers */
1278 for (int i = 0; i < pending_scan_result_count; ++i) {
1279 struct pending_scan_result *scan = &pending_scan_results[i];
1280 LOG_DEBUG_IO("Copying pending_scan_result %d/%d: %d bits from byte %d -> buffer + %d bits",
1281 i, pending_scan_result_count, scan->length, scan->first + 2, scan->buffer_offset);
1282 #ifdef CMSIS_DAP_JTAG_DEBUG
1283 for (uint32_t b = 0; b < DIV_ROUND_UP(scan->length, 8); ++b)
1284 printf("%02X ", buffer[2+scan->first+b]);
1285 printf("\n");
1286 #endif
1287 bit_copy(scan->buffer, scan->buffer_offset, buffer + 2 + scan->first, 0, scan->length);
1288 }
1289
1290 /* reset */
1291 queued_seq_count = 0;
1292 queued_seq_buf_end = 0;
1293 queued_seq_tdo_ptr = 0;
1294 pending_scan_result_count = 0;
1295 }
1296
1297 /* queue a sequence of bits to clock out TDI / in TDO, executing if the buffer is full.
1298 *
1299 * sequence=NULL means clock out zeros on TDI
1300 * tdo_buffer=NULL means don't capture TDO
1301 */
1302 static void cmsis_dap_add_jtag_sequence(int s_len, const uint8_t *sequence, int s_offset,
1303 bool tms, uint8_t *tdo_buffer, int tdo_buffer_offset)
1304 {
1305 LOG_DEBUG_IO("[at %d] %d bits, tms %s, seq offset %d, tdo buf %p, tdo offset %d",
1306 queued_seq_buf_end,
1307 s_len, tms ? "HIGH" : "LOW", s_offset, tdo_buffer, tdo_buffer_offset);
1308
1309 if (s_len == 0)
1310 return;
1311
1312 if (s_len > 64) {
1313 LOG_DEBUG_IO("START JTAG SEQ SPLIT");
1314 for (int offset = 0; offset < s_len; offset += 64) {
1315 int len = s_len - offset;
1316 if (len > 64)
1317 len = 64;
1318 LOG_DEBUG_IO("Splitting long jtag sequence: %d-bit chunk starting at offset %d", len, offset);
1319 cmsis_dap_add_jtag_sequence(
1320 len,
1321 sequence,
1322 s_offset + offset,
1323 tms,
1324 tdo_buffer,
1325 tdo_buffer == NULL ? 0 : (tdo_buffer_offset + offset)
1326 );
1327 }
1328 LOG_DEBUG_IO("END JTAG SEQ SPLIT");
1329 return;
1330 }
1331
1332 int cmd_len = 1 + DIV_ROUND_UP(s_len, 8);
1333 if (queued_seq_count >= 255 || queued_seq_buf_end + cmd_len > QUEUED_SEQ_BUF_LEN)
1334 /* empty out the buffer */
1335 cmsis_dap_flush();
1336
1337 ++queued_seq_count;
1338
1339 /* control byte */
1340 queued_seq_buf[queued_seq_buf_end] =
1341 (tms ? DAP_JTAG_SEQ_TMS : 0) |
1342 (tdo_buffer != NULL ? DAP_JTAG_SEQ_TDO : 0) |
1343 (s_len == 64 ? 0 : s_len);
1344
1345 if (sequence != NULL)
1346 bit_copy(&queued_seq_buf[queued_seq_buf_end + 1], 0, sequence, s_offset, s_len);
1347 else
1348 memset(&queued_seq_buf[queued_seq_buf_end + 1], 0, DIV_ROUND_UP(s_len, 8));
1349
1350 queued_seq_buf_end += cmd_len;
1351
1352 if (tdo_buffer != NULL) {
1353 struct pending_scan_result *scan = &pending_scan_results[pending_scan_result_count++];
1354 scan->first = queued_seq_tdo_ptr;
1355 queued_seq_tdo_ptr += DIV_ROUND_UP(s_len, 8);
1356 scan->length = s_len;
1357 scan->buffer = tdo_buffer;
1358 scan->buffer_offset = tdo_buffer_offset;
1359 }
1360 }
1361
1362 /* queue a sequence of bits to clock out TMS, executing if the buffer is full */
1363 static void cmsis_dap_add_tms_sequence(const uint8_t *sequence, int s_len)
1364 {
1365 LOG_DEBUG_IO("%d bits: %02X", s_len, *sequence);
1366 /* we use a series of CMD_DAP_JTAG_SEQ commands to toggle TMS,
1367 because even though it seems ridiculously inefficient, it
1368 allows us to combine TMS and scan sequences into the same
1369 USB packet. */
1370 /* TODO: combine runs of the same tms value */
1371 for (int i = 0; i < s_len; ++i) {
1372 bool bit = (sequence[i / 8] & (1 << (i % 8))) != 0;
1373 cmsis_dap_add_jtag_sequence(1, NULL, 0, bit, NULL, 0);
1374 }
1375 }
1376
1377 /* Move to the end state by queuing a sequence to clock into TMS */
1378 static void cmsis_dap_state_move(void)
1379 {
1380 uint8_t tms_scan;
1381 uint8_t tms_scan_bits;
1382
1383 tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
1384 tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
1385
1386 LOG_DEBUG_IO("state move from %s to %s: %d clocks, %02X on tms",
1387 tap_state_name(tap_get_state()), tap_state_name(tap_get_end_state()),
1388 tms_scan_bits, tms_scan);
1389 cmsis_dap_add_tms_sequence(&tms_scan, tms_scan_bits);
1390
1391 tap_set_state(tap_get_end_state());
1392 }
1393
1394
1395 /* Execute a JTAG scan operation by queueing TMS and TDI/TDO sequences */
1396 static void cmsis_dap_execute_scan(struct jtag_command *cmd)
1397 {
1398 LOG_DEBUG_IO("%s type:%d", cmd->cmd.scan->ir_scan ? "IRSCAN" : "DRSCAN",
1399 jtag_scan_type(cmd->cmd.scan));
1400
1401 /* Make sure there are no trailing fields with num_bits == 0, or the logic below will fail. */
1402 while (cmd->cmd.scan->num_fields > 0
1403 && cmd->cmd.scan->fields[cmd->cmd.scan->num_fields - 1].num_bits == 0) {
1404 cmd->cmd.scan->num_fields--;
1405 LOG_DEBUG("discarding trailing empty field");
1406 }
1407
1408 if (cmd->cmd.scan->num_fields == 0) {
1409 LOG_DEBUG("empty scan, doing nothing");
1410 return;
1411 }
1412
1413 if (cmd->cmd.scan->ir_scan) {
1414 if (tap_get_state() != TAP_IRSHIFT) {
1415 cmsis_dap_end_state(TAP_IRSHIFT);
1416 cmsis_dap_state_move();
1417 }
1418 } else {
1419 if (tap_get_state() != TAP_DRSHIFT) {
1420 cmsis_dap_end_state(TAP_DRSHIFT);
1421 cmsis_dap_state_move();
1422 }
1423 }
1424
1425 cmsis_dap_end_state(cmd->cmd.scan->end_state);
1426
1427 struct scan_field *field = cmd->cmd.scan->fields;
1428 unsigned scan_size = 0;
1429
1430 for (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
1431 scan_size += field->num_bits;
1432 LOG_DEBUG_IO("%s%s field %d/%d %d bits",
1433 field->in_value ? "in" : "",
1434 field->out_value ? "out" : "",
1435 i,
1436 cmd->cmd.scan->num_fields,
1437 field->num_bits);
1438
1439 if (i == cmd->cmd.scan->num_fields - 1 && tap_get_state() != tap_get_end_state()) {
1440 LOG_DEBUG_IO("Last field and have to move out of SHIFT state");
1441 /* Last field, and we're leaving IRSHIFT/DRSHIFT. Clock last bit during tap
1442 * movement. This last field can't have length zero, it was checked above. */
1443 cmsis_dap_add_jtag_sequence(
1444 field->num_bits - 1, /* number of bits to clock */
1445 field->out_value, /* output sequence */
1446 0, /* output offset */
1447 false, /* TMS low */
1448 field->in_value,
1449 0);
1450
1451 /* Clock the last bit out, with TMS high */
1452 uint8_t last_bit = 0;
1453 if (field->out_value)
1454 bit_copy(&last_bit, 0, field->out_value, field->num_bits - 1, 1);
1455 cmsis_dap_add_jtag_sequence(
1456 1,
1457 &last_bit,
1458 0,
1459 true,
1460 field->in_value,
1461 field->num_bits - 1);
1462 tap_set_state(tap_state_transition(tap_get_state(), 1));
1463
1464 /* Now clock one more cycle, with TMS low, to get us into a PAUSE state */
1465 cmsis_dap_add_jtag_sequence(
1466 1,
1467 &last_bit,
1468 0,
1469 false,
1470 NULL,
1471 0);
1472 tap_set_state(tap_state_transition(tap_get_state(), 0));
1473 } else {
1474 LOG_DEBUG_IO("Internal field, staying in SHIFT state afterwards");
1475 /* Clocking part of a sequence into DR or IR with TMS=0,
1476 leaving TMS=0 at the end so we can continue later */
1477 cmsis_dap_add_jtag_sequence(
1478 field->num_bits,
1479 field->out_value,
1480 0,
1481 false,
1482 field->in_value,
1483 0);
1484 }
1485 }
1486
1487 if (tap_get_state() != tap_get_end_state()) {
1488 cmsis_dap_end_state(tap_get_end_state());
1489 cmsis_dap_state_move();
1490 }
1491
1492 LOG_DEBUG_IO("%s scan, %i bits, end in %s",
1493 (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size,
1494 tap_state_name(tap_get_end_state()));
1495 }
1496
1497 static void cmsis_dap_pathmove(int num_states, tap_state_t *path)
1498 {
1499 int i;
1500 uint8_t tms0 = 0x00;
1501 uint8_t tms1 = 0xff;
1502
1503 for (i = 0; i < num_states; i++) {
1504 if (path[i] == tap_state_transition(tap_get_state(), false))
1505 cmsis_dap_add_tms_sequence(&tms0, 1);
1506 else if (path[i] == tap_state_transition(tap_get_state(), true))
1507 cmsis_dap_add_tms_sequence(&tms1, 1);
1508 else {
1509 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition.",
1510 tap_state_name(tap_get_state()), tap_state_name(path[i]));
1511 exit(-1);
1512 }
1513
1514 tap_set_state(path[i]);
1515 }
1516
1517 cmsis_dap_end_state(tap_get_state());
1518 }
1519
1520 static void cmsis_dap_execute_pathmove(struct jtag_command *cmd)
1521 {
1522 LOG_DEBUG_IO("pathmove: %i states, end in %i",
1523 cmd->cmd.pathmove->num_states,
1524 cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
1525
1526 cmsis_dap_pathmove(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);
1527 }
1528
1529 static void cmsis_dap_stableclocks(int num_cycles)
1530 {
1531 int i;
1532
1533 uint8_t tms = tap_get_state() == TAP_RESET;
1534 /* TODO: Perform optimizations? */
1535 /* Execute num_cycles. */
1536 for (i = 0; i < num_cycles; i++)
1537 cmsis_dap_add_tms_sequence(&tms, 1);
1538 }
1539
1540 static void cmsis_dap_runtest(int num_cycles)
1541 {
1542 tap_state_t saved_end_state = tap_get_end_state();
1543
1544 /* Only do a state_move when we're not already in IDLE. */
1545 if (tap_get_state() != TAP_IDLE) {
1546 cmsis_dap_end_state(TAP_IDLE);
1547 cmsis_dap_state_move();
1548 }
1549 cmsis_dap_stableclocks(num_cycles);
1550
1551 /* Finish in end_state. */
1552 cmsis_dap_end_state(saved_end_state);
1553
1554 if (tap_get_state() != tap_get_end_state())
1555 cmsis_dap_state_move();
1556 }
1557
1558 static void cmsis_dap_execute_runtest(struct jtag_command *cmd)
1559 {
1560 LOG_DEBUG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles,
1561 cmd->cmd.runtest->end_state);
1562
1563 cmsis_dap_end_state(cmd->cmd.runtest->end_state);
1564 cmsis_dap_runtest(cmd->cmd.runtest->num_cycles);
1565 }
1566
1567 static void cmsis_dap_execute_stableclocks(struct jtag_command *cmd)
1568 {
1569 LOG_DEBUG_IO("stableclocks %i cycles", cmd->cmd.runtest->num_cycles);
1570 cmsis_dap_stableclocks(cmd->cmd.runtest->num_cycles);
1571 }
1572
1573 static void cmsis_dap_execute_tms(struct jtag_command *cmd)
1574 {
1575 LOG_DEBUG_IO("TMS: %d bits", cmd->cmd.tms->num_bits);
1576 cmsis_dap_cmd_DAP_SWJ_Sequence(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits);
1577 }
1578
1579 /* TODO: Is there need to call cmsis_dap_flush() for the JTAG_PATHMOVE,
1580 * JTAG_RUNTEST, JTAG_STABLECLOCKS? */
1581 static void cmsis_dap_execute_command(struct jtag_command *cmd)
1582 {
1583 switch (cmd->type) {
1584 case JTAG_SLEEP:
1585 cmsis_dap_flush();
1586 cmsis_dap_execute_sleep(cmd);
1587 break;
1588 case JTAG_TLR_RESET:
1589 cmsis_dap_flush();
1590 cmsis_dap_execute_tlr_reset(cmd);
1591 break;
1592 case JTAG_SCAN:
1593 cmsis_dap_execute_scan(cmd);
1594 break;
1595 case JTAG_PATHMOVE:
1596 cmsis_dap_execute_pathmove(cmd);
1597 break;
1598 case JTAG_RUNTEST:
1599 cmsis_dap_execute_runtest(cmd);
1600 break;
1601 case JTAG_STABLECLOCKS:
1602 cmsis_dap_execute_stableclocks(cmd);
1603 break;
1604 case JTAG_TMS:
1605 cmsis_dap_execute_tms(cmd);
1606 break;
1607 default:
1608 LOG_ERROR("BUG: unknown JTAG command type 0x%X encountered", cmd->type);
1609 exit(-1);
1610 }
1611 }
1612
1613 static int cmsis_dap_execute_queue(void)
1614 {
1615 struct jtag_command *cmd = jtag_command_queue;
1616
1617 while (cmd != NULL) {
1618 cmsis_dap_execute_command(cmd);
1619 cmd = cmd->next;
1620 }
1621
1622 cmsis_dap_flush();
1623
1624 return ERROR_OK;
1625 }
1626
1627 static int cmsis_dap_speed(int speed)
1628 {
1629 if (speed > DAP_MAX_CLOCK)
1630 LOG_INFO("High speed (adapter speed %d) may be limited by adapter firmware.", speed);
1631
1632 if (speed == 0) {
1633 LOG_ERROR("RTCK not supported. Set nonzero \"adapter speed\".");
1634 return ERROR_JTAG_NOT_IMPLEMENTED;
1635 }
1636
1637 return cmsis_dap_cmd_DAP_SWJ_Clock(speed);
1638 }
1639
1640 static int cmsis_dap_speed_div(int speed, int *khz)
1641 {
1642 *khz = speed;
1643 return ERROR_OK;
1644 }
1645
1646 static int cmsis_dap_khz(int khz, int *jtag_speed)
1647 {
1648 *jtag_speed = khz;
1649 return ERROR_OK;
1650 }
1651
1652 COMMAND_HANDLER(cmsis_dap_handle_info_command)
1653 {
1654 if (cmsis_dap_get_version_info() == ERROR_OK)
1655 cmsis_dap_get_status();
1656
1657 return ERROR_OK;
1658 }
1659
1660 COMMAND_HANDLER(cmsis_dap_handle_cmd_command)
1661 {
1662 int retval;
1663 unsigned i;
1664 uint8_t *buffer = cmsis_dap_handle->packet_buffer;
1665
1666 buffer[0] = 0; /* report number */
1667
1668 for (i = 0; i < CMD_ARGC; i++)
1669 buffer[i + 1] = strtoul(CMD_ARGV[i], NULL, 16);
1670
1671 retval = cmsis_dap_usb_xfer(cmsis_dap_handle, CMD_ARGC + 1);
1672
1673 if (retval != ERROR_OK) {
1674 LOG_ERROR("CMSIS-DAP command failed.");
1675 return ERROR_JTAG_DEVICE_ERROR;
1676 }
1677
1678 LOG_INFO("Returned data %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8,
1679 buffer[1], buffer[2], buffer[3], buffer[4]);
1680
1681 return ERROR_OK;
1682 }
1683
1684 COMMAND_HANDLER(cmsis_dap_handle_vid_pid_command)
1685 {
1686 if (CMD_ARGC > MAX_USB_IDS * 2) {
1687 LOG_WARNING("ignoring extra IDs in cmsis_dap_vid_pid "
1688 "(maximum is %d pairs)", MAX_USB_IDS);
1689 CMD_ARGC = MAX_USB_IDS * 2;
1690 }
1691 if (CMD_ARGC < 2 || (CMD_ARGC & 1)) {
1692 LOG_WARNING("incomplete cmsis_dap_vid_pid configuration directive");
1693 if (CMD_ARGC < 2)
1694 return ERROR_COMMAND_SYNTAX_ERROR;
1695 /* remove the incomplete trailing id */
1696 CMD_ARGC -= 1;
1697 }
1698
1699 unsigned i;
1700 for (i = 0; i < CMD_ARGC; i += 2) {
1701 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], cmsis_dap_vid[i >> 1]);
1702 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], cmsis_dap_pid[i >> 1]);
1703 }
1704
1705 /*
1706 * Explicitly terminate, in case there are multiples instances of
1707 * cmsis_dap_vid_pid.
1708 */
1709 cmsis_dap_vid[i >> 1] = cmsis_dap_pid[i >> 1] = 0;
1710
1711 return ERROR_OK;
1712 }
1713
1714 COMMAND_HANDLER(cmsis_dap_handle_serial_command)
1715 {
1716 if (CMD_ARGC == 1) {
1717 size_t len = mbstowcs(NULL, CMD_ARGV[0], 0);
1718 cmsis_dap_serial = calloc(len + 1, sizeof(wchar_t));
1719 if (cmsis_dap_serial == NULL) {
1720 LOG_ERROR("unable to allocate memory");
1721 return ERROR_OK;
1722 }
1723 if (mbstowcs(cmsis_dap_serial, CMD_ARGV[0], len + 1) == (size_t)-1) {
1724 free(cmsis_dap_serial);
1725 cmsis_dap_serial = NULL;
1726 LOG_ERROR("unable to convert serial");
1727 }
1728 } else {
1729 LOG_ERROR("expected exactly one argument to cmsis_dap_serial <serial-number>");
1730 }
1731
1732 return ERROR_OK;
1733 }
1734
1735 static const struct command_registration cmsis_dap_subcommand_handlers[] = {
1736 {
1737 .name = "info",
1738 .handler = &cmsis_dap_handle_info_command,
1739 .mode = COMMAND_EXEC,
1740 .usage = "",
1741 .help = "show cmsis-dap info",
1742 },
1743 {
1744 .name = "cmd",
1745 .handler = &cmsis_dap_handle_cmd_command,
1746 .mode = COMMAND_EXEC,
1747 .usage = "",
1748 .help = "issue cmsis-dap command",
1749 },
1750 COMMAND_REGISTRATION_DONE
1751 };
1752
1753 static const struct command_registration cmsis_dap_command_handlers[] = {
1754 {
1755 .name = "cmsis-dap",
1756 .mode = COMMAND_ANY,
1757 .help = "perform CMSIS-DAP management",
1758 .usage = "<cmd>",
1759 .chain = cmsis_dap_subcommand_handlers,
1760 },
1761 {
1762 .name = "cmsis_dap_vid_pid",
1763 .handler = &cmsis_dap_handle_vid_pid_command,
1764 .mode = COMMAND_CONFIG,
1765 .help = "the vendor ID and product ID of the CMSIS-DAP device",
1766 .usage = "(vid pid)* ",
1767 },
1768 {
1769 .name = "cmsis_dap_serial",
1770 .handler = &cmsis_dap_handle_serial_command,
1771 .mode = COMMAND_CONFIG,
1772 .help = "set the serial number of the adapter",
1773 .usage = "serial_string",
1774 },
1775 COMMAND_REGISTRATION_DONE
1776 };
1777
1778 static const struct swd_driver cmsis_dap_swd_driver = {
1779 .init = cmsis_dap_swd_init,
1780 .switch_seq = cmsis_dap_swd_switch_seq,
1781 .read_reg = cmsis_dap_swd_read_reg,
1782 .write_reg = cmsis_dap_swd_write_reg,
1783 .run = cmsis_dap_swd_run_queue,
1784 };
1785
1786 static const char * const cmsis_dap_transport[] = { "swd", "jtag", NULL };
1787
1788 static struct jtag_interface cmsis_dap_interface = {
1789 .supported = DEBUG_CAP_TMS_SEQ,
1790 .execute_queue = cmsis_dap_execute_queue,
1791 };
1792
1793 struct adapter_driver cmsis_dap_adapter_driver = {
1794 .name = "cmsis-dap",
1795 .transports = cmsis_dap_transport,
1796 .commands = cmsis_dap_command_handlers,
1797
1798 .init = cmsis_dap_init,
1799 .quit = cmsis_dap_quit,
1800 .reset = cmsis_dap_reset,
1801 .speed = cmsis_dap_speed,
1802 .khz = cmsis_dap_khz,
1803 .speed_div = cmsis_dap_speed_div,
1804
1805 .jtag_ops = &cmsis_dap_interface,
1806 .swd_ops = &cmsis_dap_swd_driver,
1807 };

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)