jtag: align adapter speed code to new structure
[openocd.git] / src / jtag / drivers / vsllink.c
1 /***************************************************************************
2 * Copyright (C) 2009-2010 by Simon Qian <SimonQian@SimonQian.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
16 ***************************************************************************/
17
18 /* Versaloon is a programming tool for multiple MCUs.
19 * It's distributed under GPLv3.
20 * You can find it at http://www.Versaloon.com/.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <jtag/adapter.h>
28 #include <jtag/interface.h>
29 #include <jtag/commands.h>
30 #include <jtag/swd.h>
31 #include <libusb.h>
32
33 #include "versaloon/versaloon_include.h"
34 #include "versaloon/versaloon.h"
35
36 static int vsllink_tms_offset;
37
38 struct pending_scan_result {
39 int src_offset;
40 int dest_offset;
41 int length; /* Number of bits to read */
42 struct scan_command *command; /* Corresponding scan command */
43 uint8_t *ack;
44 uint8_t *buffer;
45 bool last; /* indicate the last scan pending */
46 };
47
48 #define MAX_PENDING_SCAN_RESULTS 256
49
50 static int pending_scan_results_length;
51 static struct pending_scan_result
52 pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];
53
54 /* Queue command functions */
55 static void vsllink_end_state(tap_state_t state);
56 static void vsllink_state_move(void);
57 static void vsllink_path_move(int num_states, tap_state_t *path);
58 static void vsllink_tms(int num_bits, const uint8_t *bits);
59 static void vsllink_runtest(int num_cycles);
60 static void vsllink_stableclocks(int num_cycles, int tms);
61 static void vsllink_scan(bool ir_scan, enum scan_type type,
62 uint8_t *buffer, int scan_size, struct scan_command *command);
63 static int vsllink_reset(int trst, int srst);
64
65 /* VSLLink tap buffer functions */
66 static void vsllink_tap_append_step(int tms, int tdi);
67 static void vsllink_tap_init(void);
68 static int vsllink_tap_execute(void);
69 static void vsllink_tap_ensure_pending(int scans);
70 static void vsllink_tap_append_scan(int length, uint8_t *buffer,
71 struct scan_command *command);
72
73 /* VSLLink SWD functions */
74 static int_least32_t vsllink_swd_frequency(int_least32_t hz);
75 static int vsllink_swd_switch_seq(enum swd_special_seq seq);
76
77 /* VSLLink lowlevel functions */
78 struct vsllink {
79 struct libusb_context *libusb_ctx;
80 struct libusb_device_handle *usb_device_handle;
81 };
82
83 static int vsllink_usb_open(struct vsllink *vsllink);
84 static void vsllink_usb_close(struct vsllink *vsllink);
85
86 static void vsllink_debug_buffer(uint8_t *buffer, int length);
87
88 static int tap_length;
89 static int tap_buffer_size;
90 static uint8_t *tms_buffer;
91 static uint8_t *tdi_buffer;
92 static uint8_t *tdo_buffer;
93
94 static bool swd_mode;
95
96 static struct vsllink *vsllink_handle;
97
98 static int vsllink_execute_queue(void)
99 {
100 struct jtag_command *cmd = jtag_command_queue;
101 int scan_size;
102 enum scan_type type;
103 uint8_t *buffer;
104
105 LOG_DEBUG_IO("-------------------------------------"
106 " vsllink "
107 "-------------------------------------");
108
109 while (cmd) {
110 switch (cmd->type) {
111 case JTAG_RUNTEST:
112 LOG_DEBUG_IO("runtest %i cycles, end in %s",
113 cmd->cmd.runtest->num_cycles,
114 tap_state_name(cmd->cmd.runtest->end_state));
115
116 vsllink_end_state(cmd->cmd.runtest->end_state);
117 vsllink_runtest(cmd->cmd.runtest->num_cycles);
118 break;
119
120 case JTAG_TLR_RESET:
121 LOG_DEBUG_IO("statemove end in %s",
122 tap_state_name(cmd->cmd.statemove->end_state));
123
124 vsllink_end_state(cmd->cmd.statemove->end_state);
125 vsllink_state_move();
126 break;
127
128 case JTAG_PATHMOVE:
129 LOG_DEBUG_IO("pathmove: %i states, end in %s",
130 cmd->cmd.pathmove->num_states,
131 tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
132
133 vsllink_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);
134 break;
135
136 case JTAG_SCAN:
137 LOG_DEBUG_IO("JTAG Scan...");
138
139 vsllink_end_state(cmd->cmd.scan->end_state);
140
141 scan_size = jtag_build_buffer(
142 cmd->cmd.scan, &buffer);
143
144 if (cmd->cmd.scan->ir_scan)
145 LOG_DEBUG_IO(
146 "JTAG Scan write IR(%d bits), "
147 "end in %s:",
148 scan_size,
149 tap_state_name(cmd->cmd.scan->end_state));
150
151 else
152 LOG_DEBUG_IO(
153 "JTAG Scan write DR(%d bits), "
154 "end in %s:",
155 scan_size,
156 tap_state_name(cmd->cmd.scan->end_state));
157
158 if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO))
159 vsllink_debug_buffer(buffer, DIV_ROUND_UP(scan_size, 8));
160
161 type = jtag_scan_type(cmd->cmd.scan);
162
163 vsllink_scan(cmd->cmd.scan->ir_scan,
164 type, buffer, scan_size,
165 cmd->cmd.scan);
166 break;
167
168 case JTAG_SLEEP:
169 LOG_DEBUG_IO("sleep %" PRIu32, cmd->cmd.sleep->us);
170 vsllink_tap_execute();
171 jtag_sleep(cmd->cmd.sleep->us);
172 break;
173
174 case JTAG_STABLECLOCKS:
175 LOG_DEBUG_IO("add %d clocks",
176 cmd->cmd.stableclocks->num_cycles);
177
178 switch (tap_get_state()) {
179 case TAP_RESET:
180 /* tms must be '1' to stay
181 * n TAP_RESET mode
182 */
183 scan_size = 1;
184 break;
185 case TAP_DRSHIFT:
186 case TAP_IDLE:
187 case TAP_DRPAUSE:
188 case TAP_IRSHIFT:
189 case TAP_IRPAUSE:
190 /* else, tms should be '0' */
191 scan_size = 0;
192 break;
193 /* above stable states are OK */
194 default:
195 LOG_ERROR("jtag_add_clocks() "
196 "in non-stable state \"%s\"",
197 tap_state_name(tap_get_state())
198 );
199 exit(-1);
200 }
201 vsllink_stableclocks(cmd->cmd.stableclocks->num_cycles, scan_size);
202 break;
203
204 case JTAG_TMS:
205 LOG_DEBUG_IO("add %d jtag tms",
206 cmd->cmd.tms->num_bits);
207
208 vsllink_tms(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits);
209 break;
210
211 default:
212 LOG_ERROR("BUG: unknown JTAG command type "
213 "encountered: %d", cmd->type);
214 exit(-1);
215 }
216 cmd = cmd->next;
217 }
218
219 return vsllink_tap_execute();
220 }
221
222 static int vsllink_speed(int speed)
223 {
224 if (swd_mode) {
225 vsllink_swd_frequency(speed * 1000);
226 return ERROR_OK;
227 }
228
229 versaloon_interface.adaptors.jtag_raw.config(0, (uint16_t)speed);
230 return versaloon_interface.adaptors.peripheral_commit();
231 }
232
233 static int vsllink_khz(int khz, int *jtag_speed)
234 {
235 *jtag_speed = khz;
236
237 return ERROR_OK;
238 }
239
240 static int vsllink_speed_div(int jtag_speed, int *khz)
241 {
242 *khz = jtag_speed;
243
244 return ERROR_OK;
245 }
246
247 static void vsllink_free_buffer(void)
248 {
249 free(tdi_buffer);
250 tdi_buffer = NULL;
251
252 free(tdo_buffer);
253 tdo_buffer = NULL;
254
255 free(tms_buffer);
256 tms_buffer = NULL;
257 }
258
259 static int vsllink_quit(void)
260 {
261 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST,
262 0, 0, GPIO_SRST | GPIO_TRST);
263 versaloon_interface.adaptors.gpio.fini(0);
264
265 if (swd_mode)
266 versaloon_interface.adaptors.swd.fini(0);
267 else
268 versaloon_interface.adaptors.jtag_raw.fini(0);
269
270 versaloon_interface.adaptors.peripheral_commit();
271 versaloon_interface.fini();
272
273 vsllink_free_buffer();
274 vsllink_usb_close(vsllink_handle);
275
276 free(vsllink_handle);
277
278 return ERROR_OK;
279 }
280
281 static int vsllink_interface_init(void)
282 {
283 vsllink_handle = malloc(sizeof(struct vsllink));
284 if (!vsllink_handle) {
285 LOG_ERROR("unable to allocate memory");
286 return ERROR_FAIL;
287 }
288
289 libusb_init(&vsllink_handle->libusb_ctx);
290
291 if (vsllink_usb_open(vsllink_handle) != ERROR_OK) {
292 LOG_ERROR("Can't find USB JTAG Interface!"
293 "Please check connection and permissions.");
294 return ERROR_JTAG_INIT_FAILED;
295 }
296 LOG_DEBUG("vsllink found on %04X:%04X",
297 versaloon_interface.usb_setting.vid,
298 versaloon_interface.usb_setting.pid);
299 versaloon_usb_device_handle = vsllink_handle->usb_device_handle;
300
301 if (versaloon_interface.init() != ERROR_OK)
302 return ERROR_FAIL;
303 if (versaloon_interface.usb_setting.buf_size < 32) {
304 versaloon_interface.fini();
305 return ERROR_FAIL;
306 }
307
308 return ERROR_OK;
309 }
310
311 static int vsllink_init(void)
312 {
313 int retval = vsllink_interface_init();
314 if (retval != ERROR_OK)
315 return retval;
316
317 versaloon_interface.adaptors.gpio.init(0);
318 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, 0, GPIO_SRST,
319 GPIO_SRST);
320 versaloon_interface.adaptors.delay.delayms(100);
321 versaloon_interface.adaptors.peripheral_commit();
322
323 if (swd_mode) {
324 versaloon_interface.adaptors.gpio.config(0, GPIO_TRST, 0,
325 GPIO_TRST, GPIO_TRST);
326 versaloon_interface.adaptors.swd.init(0);
327 vsllink_swd_frequency(adapter_get_speed_khz() * 1000);
328 vsllink_swd_switch_seq(JTAG_TO_SWD);
329
330 } else {
331 /* malloc buffer size for tap */
332 tap_buffer_size = versaloon_interface.usb_setting.buf_size / 2 - 32;
333 vsllink_free_buffer();
334 tdi_buffer = malloc(tap_buffer_size);
335 tdo_buffer = malloc(tap_buffer_size);
336 tms_buffer = malloc(tap_buffer_size);
337 if ((!tdi_buffer) || (!tdo_buffer) || (!tms_buffer)) {
338 vsllink_quit();
339 return ERROR_FAIL;
340 }
341
342 versaloon_interface.adaptors.jtag_raw.init(0);
343 versaloon_interface.adaptors.jtag_raw.config(0, adapter_get_speed_khz());
344 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST,
345 GPIO_TRST, GPIO_SRST, GPIO_SRST);
346 }
347
348 if (versaloon_interface.adaptors.peripheral_commit() != ERROR_OK)
349 return ERROR_FAIL;
350
351 vsllink_reset(0, 0);
352 vsllink_tap_init();
353 return ERROR_OK;
354 }
355
356 /**************************************************************************
357 * Queue command implementations */
358
359 static void vsllink_end_state(tap_state_t state)
360 {
361 if (tap_is_state_stable(state))
362 tap_set_end_state(state);
363 else {
364 LOG_ERROR("BUG: %i is not a valid end state", state);
365 exit(-1);
366 }
367 }
368
369 /* Goes to the end state. */
370 static void vsllink_state_move(void)
371 {
372 int i;
373 uint8_t tms_scan = tap_get_tms_path(tap_get_state(),
374 tap_get_end_state());
375 uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(),
376 tap_get_end_state());
377
378 for (i = 0; i < tms_scan_bits; i++)
379 vsllink_tap_append_step((tms_scan >> i) & 1, 0);
380
381 tap_set_state(tap_get_end_state());
382 }
383
384 static void vsllink_path_move(int num_states, tap_state_t *path)
385 {
386 for (int i = 0; i < num_states; i++) {
387 if (path[i] == tap_state_transition(tap_get_state(), false))
388 vsllink_tap_append_step(0, 0);
389 else if (path[i] == tap_state_transition(tap_get_state(), true))
390 vsllink_tap_append_step(1, 0);
391 else {
392 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
393 tap_state_name(tap_get_state()),
394 tap_state_name(path[i]));
395 exit(-1);
396 }
397
398 tap_set_state(path[i]);
399 }
400
401 tap_set_end_state(tap_get_state());
402 }
403
404 static void vsllink_tms(int num_bits, const uint8_t *bits)
405 {
406 for (int i = 0; i < num_bits; i++)
407 vsllink_tap_append_step((bits[i / 8] >> (i % 8)) & 1, 0);
408 }
409
410 static void vsllink_stableclocks(int num_cycles, int tms)
411 {
412 while (num_cycles > 0) {
413 vsllink_tap_append_step(tms, 0);
414 num_cycles--;
415 }
416 }
417
418 static void vsllink_runtest(int num_cycles)
419 {
420 tap_state_t saved_end_state = tap_get_end_state();
421
422 if (tap_get_state() != TAP_IDLE) {
423 /* enter IDLE state */
424 vsllink_end_state(TAP_IDLE);
425 vsllink_state_move();
426 }
427
428 vsllink_stableclocks(num_cycles, 0);
429
430 /* post-process */
431 /* set end_state */
432 vsllink_end_state(saved_end_state);
433 if (tap_get_end_state() != tap_get_end_state())
434 vsllink_state_move();
435 }
436
437 static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
438 int scan_size, struct scan_command *command)
439 {
440 tap_state_t saved_end_state;
441
442 saved_end_state = tap_get_end_state();
443
444 /* Move to appropriate scan state */
445 vsllink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
446
447 if (tap_get_state() != tap_get_end_state())
448 vsllink_state_move();
449 vsllink_end_state(saved_end_state);
450
451 /* Scan */
452 vsllink_tap_append_scan(scan_size, buffer, command);
453
454 /* Goto Pause and record position to insert tms:0 */
455 vsllink_tap_append_step(0, 0);
456 vsllink_tms_offset = tap_length;
457
458 tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
459
460 if (tap_get_state() != tap_get_end_state())
461 vsllink_state_move();
462 }
463
464 static int vsllink_reset(int trst, int srst)
465 {
466 LOG_DEBUG("trst: %i, srst: %i", trst, srst);
467
468 if (!srst)
469 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, 0, GPIO_SRST, GPIO_SRST);
470 else
471 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, GPIO_SRST, 0, 0);
472
473 if (!swd_mode) {
474 if (!trst)
475 versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, GPIO_TRST);
476 else
477 versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, 0);
478 }
479
480 return versaloon_interface.adaptors.peripheral_commit();
481 }
482
483 COMMAND_HANDLER(vsllink_handle_usb_vid_command)
484 {
485 if (CMD_ARGC != 1)
486 return ERROR_COMMAND_SYNTAX_ERROR;
487
488 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
489 versaloon_interface.usb_setting.vid);
490 return ERROR_OK;
491 }
492
493 COMMAND_HANDLER(vsllink_handle_usb_pid_command)
494 {
495 if (CMD_ARGC != 1)
496 return ERROR_COMMAND_SYNTAX_ERROR;
497 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
498 versaloon_interface.usb_setting.pid);
499 return ERROR_OK;
500 }
501
502 COMMAND_HANDLER(vsllink_handle_usb_serial_command)
503 {
504 if (CMD_ARGC > 1)
505 return ERROR_COMMAND_SYNTAX_ERROR;
506
507 free(versaloon_interface.usb_setting.serialstring);
508
509 if (CMD_ARGC == 1)
510 versaloon_interface.usb_setting.serialstring = strdup(CMD_ARGV[0]);
511 else
512 versaloon_interface.usb_setting.serialstring = NULL;
513
514 return ERROR_OK;
515 }
516
517 COMMAND_HANDLER(vsllink_handle_usb_bulkin_command)
518 {
519 if (CMD_ARGC != 1)
520 return ERROR_COMMAND_SYNTAX_ERROR;
521
522 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
523 versaloon_interface.usb_setting.ep_in);
524
525 versaloon_interface.usb_setting.ep_in |= 0x80;
526
527 return ERROR_OK;
528 }
529
530 COMMAND_HANDLER(vsllink_handle_usb_bulkout_command)
531 {
532 if (CMD_ARGC != 1)
533 return ERROR_COMMAND_SYNTAX_ERROR;
534
535 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
536 versaloon_interface.usb_setting.ep_out);
537
538 versaloon_interface.usb_setting.ep_out &= ~0x80;
539
540 return ERROR_OK;
541 }
542
543 COMMAND_HANDLER(vsllink_handle_usb_interface_command)
544 {
545 if (CMD_ARGC != 1)
546 return ERROR_COMMAND_SYNTAX_ERROR;
547
548 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
549 versaloon_interface.usb_setting.interface);
550 return ERROR_OK;
551 }
552
553 /**************************************************************************
554 * VSLLink tap functions */
555
556 static void vsllink_tap_init(void)
557 {
558 tap_length = 0;
559 pending_scan_results_length = 0;
560 vsllink_tms_offset = 0;
561 }
562
563 static void vsllink_tap_ensure_pending(int scans)
564 {
565 int available_scans =
566 MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
567
568 if (scans > available_scans)
569 vsllink_tap_execute();
570 }
571
572 static void vsllink_tap_append_step(int tms, int tdi)
573 {
574 int index_var = tap_length / 8;
575
576 int bit_index = tap_length % 8;
577 uint8_t bit = 1 << bit_index;
578
579 if (tms)
580 tms_buffer[index_var] |= bit;
581 else
582 tms_buffer[index_var] &= ~bit;
583
584 if (tdi)
585 tdi_buffer[index_var] |= bit;
586 else
587 tdi_buffer[index_var] &= ~bit;
588
589 tap_length++;
590
591 if (tap_buffer_size * 8 <= tap_length)
592 vsllink_tap_execute();
593 }
594
595 static void vsllink_tap_append_scan(int length, uint8_t *buffer,
596 struct scan_command *command)
597 {
598 struct pending_scan_result *pending_scan_result;
599 int len_tmp, len_all, i;
600
601 len_all = 0;
602 while (len_all < length) {
603 vsllink_tap_ensure_pending(1);
604 pending_scan_result =
605 &pending_scan_results_buffer[
606 pending_scan_results_length];
607
608 if ((length - len_all) > (tap_buffer_size * 8 - tap_length)) {
609 /* Use all memory available
610 vsllink_tap_append_step will commit automatically */
611 len_tmp = tap_buffer_size * 8 - tap_length;
612 pending_scan_result->last = false;
613 } else {
614 len_tmp = length - len_all;
615 pending_scan_result->last = true;
616 }
617 pending_scan_result->src_offset = tap_length;
618 pending_scan_result->dest_offset = len_all;
619 pending_scan_result->length = len_tmp;
620 pending_scan_result->command = command;
621 pending_scan_result->buffer = buffer;
622 pending_scan_results_length++;
623
624 for (i = 0; i < len_tmp; i++) {
625 vsllink_tap_append_step(((len_all + i) < length-1
626 ? 0 : 1),
627 (buffer[(len_all + i)/8]
628 >> ((len_all + i)%8)) & 1);
629 }
630
631 len_all += len_tmp;
632 }
633 }
634
635 static int vsllink_jtag_execute(void)
636 {
637 int i;
638 int result;
639
640 if (tap_length <= 0)
641 return ERROR_OK;
642
643 versaloon_interface.adaptors.jtag_raw.execute(0, tdi_buffer, tms_buffer,
644 tdo_buffer, tap_length);
645
646 result = versaloon_interface.adaptors.peripheral_commit();
647
648 if (result == ERROR_OK) {
649 for (i = 0; i < pending_scan_results_length; i++) {
650 struct pending_scan_result *pending_scan_result =
651 &pending_scan_results_buffer[i];
652 uint8_t *buffer = pending_scan_result->buffer;
653 int length = pending_scan_result->length;
654 int src_first = pending_scan_result->src_offset;
655 int dest_first = pending_scan_result->dest_offset;
656 bool last = pending_scan_result->last;
657
658 struct scan_command *command;
659
660 command = pending_scan_result->command;
661 buf_set_buf(tdo_buffer, src_first, buffer, dest_first, length);
662
663 LOG_DEBUG_IO(
664 "JTAG scan read(%d bits, from src %d bits to dest %d bits):",
665 length, src_first, dest_first);
666 if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO))
667 vsllink_debug_buffer(buffer + dest_first / 8, DIV_ROUND_UP(length, 7));
668
669 if (last) {
670 if (jtag_read_buffer(buffer, command)
671 != ERROR_OK) {
672 vsllink_tap_init();
673 return ERROR_JTAG_QUEUE_FAILED;
674 }
675
676 free(pending_scan_result->buffer);
677 }
678 }
679 } else {
680 LOG_ERROR("vsllink_jtag_execute failure");
681 return ERROR_JTAG_QUEUE_FAILED;
682 }
683
684 vsllink_tap_init();
685
686 return ERROR_OK;
687 }
688
689 static int vsllink_tap_execute(void)
690 {
691 if (swd_mode)
692 return ERROR_OK;
693
694 return vsllink_jtag_execute();
695 }
696
697 static int vsllink_swd_init(void)
698 {
699 LOG_INFO("VSLLink SWD mode enabled");
700 swd_mode = true;
701
702 return ERROR_OK;
703 }
704
705 static int_least32_t vsllink_swd_frequency(int_least32_t hz)
706 {
707 const int_least32_t delay2hz[] = {
708 1850000, 235000, 130000, 102000, 85000, 72000
709 };
710
711 if (hz > 0) {
712 uint16_t delay = UINT16_MAX;
713
714 for (uint16_t i = 0; i < ARRAY_SIZE(delay2hz); i++) {
715 if (hz >= delay2hz[i]) {
716 hz = delay2hz[i];
717 delay = i;
718 break;
719 }
720 }
721
722 if (delay == UINT16_MAX)
723 delay = (500000 / hz) - 1;
724
725 /* Calculate retry count after a WAIT response. This will give
726 * a retry timeout at about ~250 ms. 54 is the number of bits
727 * found in a transaction. */
728 uint16_t retry_count = 250 * hz / 1000 / 54;
729
730 LOG_DEBUG("SWD delay: %d, retry count: %d", delay, retry_count);
731
732 versaloon_interface.adaptors.swd.config(0, 2, retry_count, delay);
733 }
734
735 return hz;
736 }
737
738 static int vsllink_swd_switch_seq(enum swd_special_seq seq)
739 {
740 switch (seq) {
741 case LINE_RESET:
742 LOG_DEBUG("SWD line reset");
743 versaloon_interface.adaptors.swd.seqout(0, swd_seq_line_reset,
744 swd_seq_line_reset_len);
745 break;
746 case JTAG_TO_SWD:
747 LOG_DEBUG("JTAG-to-SWD");
748 versaloon_interface.adaptors.swd.seqout(0, swd_seq_jtag_to_swd,
749 swd_seq_jtag_to_swd_len);
750 break;
751 case SWD_TO_JTAG:
752 LOG_DEBUG("SWD-to-JTAG");
753 versaloon_interface.adaptors.swd.seqout(0, swd_seq_swd_to_jtag,
754 swd_seq_swd_to_jtag_len);
755 break;
756 default:
757 LOG_ERROR("Sequence %d not supported", seq);
758 return ERROR_FAIL;
759 }
760
761 return ERROR_OK;
762 }
763
764 static void vsllink_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
765 {
766 versaloon_interface.adaptors.swd.transact(0, cmd, value, NULL);
767 }
768
769 static void vsllink_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
770 {
771 versaloon_interface.adaptors.swd.transact(0, cmd, &value, NULL);
772 }
773
774 static int vsllink_swd_run_queue(void)
775 {
776 return versaloon_interface.adaptors.peripheral_commit();
777 }
778
779 /****************************************************************************
780 * VSLLink USB low-level functions */
781
782 static int vsllink_check_usb_strings(
783 struct libusb_device_handle *usb_device_handle,
784 struct libusb_device_descriptor *usb_desc)
785 {
786 char desc_string[256];
787 int retval;
788
789 if (versaloon_interface.usb_setting.serialstring) {
790 retval = libusb_get_string_descriptor_ascii(usb_device_handle,
791 usb_desc->iSerialNumber, (unsigned char *)desc_string,
792 sizeof(desc_string));
793 if (retval < 0)
794 return ERROR_FAIL;
795
796 if (strncmp(desc_string, versaloon_interface.usb_setting.serialstring,
797 sizeof(desc_string)))
798 return ERROR_FAIL;
799 }
800
801 retval = libusb_get_string_descriptor_ascii(usb_device_handle,
802 usb_desc->iProduct, (unsigned char *)desc_string,
803 sizeof(desc_string));
804 if (retval < 0)
805 return ERROR_FAIL;
806
807 if (!strstr(desc_string, "Versaloon"))
808 return ERROR_FAIL;
809
810 return ERROR_OK;
811 }
812
813 static int vsllink_usb_open(struct vsllink *vsllink)
814 {
815 ssize_t num_devices, i;
816 struct libusb_device **usb_devices;
817 struct libusb_device_descriptor usb_desc;
818 struct libusb_device_handle *usb_device_handle;
819 int retval;
820
821 num_devices = libusb_get_device_list(vsllink->libusb_ctx, &usb_devices);
822
823 if (num_devices <= 0)
824 return ERROR_FAIL;
825
826 for (i = 0; i < num_devices; i++) {
827 struct libusb_device *device = usb_devices[i];
828
829 retval = libusb_get_device_descriptor(device, &usb_desc);
830 if (retval != 0)
831 continue;
832
833 if (usb_desc.idVendor != versaloon_interface.usb_setting.vid ||
834 usb_desc.idProduct != versaloon_interface.usb_setting.pid)
835 continue;
836
837 retval = libusb_open(device, &usb_device_handle);
838 if (retval != 0)
839 continue;
840
841 retval = vsllink_check_usb_strings(usb_device_handle, &usb_desc);
842 if (retval == ERROR_OK)
843 break;
844
845 libusb_close(usb_device_handle);
846 }
847
848 libusb_free_device_list(usb_devices, 1);
849
850 if (i == num_devices)
851 return ERROR_FAIL;
852
853 retval = libusb_claim_interface(usb_device_handle,
854 versaloon_interface.usb_setting.interface);
855 if (retval != 0) {
856 LOG_ERROR("unable to claim interface");
857 libusb_close(usb_device_handle);
858 return ERROR_FAIL;
859 }
860
861 vsllink->usb_device_handle = usb_device_handle;
862 return ERROR_OK;
863 }
864
865 static void vsllink_usb_close(struct vsllink *vsllink)
866 {
867 libusb_release_interface(vsllink->usb_device_handle,
868 versaloon_interface.usb_setting.interface);
869 libusb_close(vsllink->usb_device_handle);
870 }
871
872 #define BYTES_PER_LINE 16
873
874 static void vsllink_debug_buffer(uint8_t *buffer, int length)
875 {
876 char line[81];
877 char s[4];
878 int i;
879 int j;
880
881 for (i = 0; i < length; i += BYTES_PER_LINE) {
882 snprintf(line, 5, "%04x", i & 0xffff);
883 for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
884 snprintf(s, 4, " %02x", buffer[j]);
885 strcat(line, s);
886 }
887 LOG_DEBUG_IO("%s", line);
888 }
889 }
890
891 static const struct command_registration vsllink_subcommand_handlers[] = {
892 {
893 .name = "usb_vid",
894 .handler = &vsllink_handle_usb_vid_command,
895 .mode = COMMAND_CONFIG,
896 .help = "Set USB VID",
897 .usage = "<vid>",
898 },
899 {
900 .name = "usb_pid",
901 .handler = &vsllink_handle_usb_pid_command,
902 .mode = COMMAND_CONFIG,
903 .help = "Set USB PID",
904 .usage = "<pid>",
905 },
906 {
907 .name = "usb_serial",
908 .handler = &vsllink_handle_usb_serial_command,
909 .mode = COMMAND_CONFIG,
910 .help = "Set or disable check for USB serial",
911 .usage = "[<serial>]",
912 },
913 {
914 .name = "usb_bulkin",
915 .handler = &vsllink_handle_usb_bulkin_command,
916 .mode = COMMAND_CONFIG,
917 .help = "Set USB input endpoint",
918 .usage = "<ep_in>",
919 },
920 {
921 .name = "usb_bulkout",
922 .handler = &vsllink_handle_usb_bulkout_command,
923 .mode = COMMAND_CONFIG,
924 .help = "Set USB output endpoint",
925 .usage = "<ep_out>",
926 },
927 {
928 .name = "usb_interface",
929 .handler = &vsllink_handle_usb_interface_command,
930 .mode = COMMAND_CONFIG,
931 .help = "Set USB output interface",
932 .usage = "<interface>",
933 },
934 COMMAND_REGISTRATION_DONE
935 };
936
937 static const struct command_registration vsllink_command_handlers[] = {
938 {
939 .name = "vsllink",
940 .mode = COMMAND_ANY,
941 .help = "perform vsllink management",
942 .chain = vsllink_subcommand_handlers,
943 .usage = "",
944 },
945 COMMAND_REGISTRATION_DONE
946 };
947
948 static const char * const vsllink_transports[] = {"jtag", "swd", NULL};
949
950 static const struct swd_driver vsllink_swd_driver = {
951 .init = vsllink_swd_init,
952 .switch_seq = vsllink_swd_switch_seq,
953 .read_reg = vsllink_swd_read_reg,
954 .write_reg = vsllink_swd_write_reg,
955 .run = vsllink_swd_run_queue,
956 };
957
958 static struct jtag_interface vsllink_interface = {
959 .supported = DEBUG_CAP_TMS_SEQ,
960 .execute_queue = vsllink_execute_queue,
961 };
962
963 struct adapter_driver vsllink_adapter_driver = {
964 .name = "vsllink",
965 .transports = vsllink_transports,
966 .commands = vsllink_command_handlers,
967
968 .init = vsllink_init,
969 .quit = vsllink_quit,
970 .reset = vsllink_reset,
971 .speed = vsllink_speed,
972 .khz = vsllink_khz,
973 .speed_div = vsllink_speed_div,
974
975 .jtag_ops = &vsllink_interface,
976 .swd_ops = &vsllink_swd_driver,
977 };

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)