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

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)