f59a7033ee7abe5d9202c35178a2707914323873
[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_bulkin_command)
503 {
504 if (CMD_ARGC != 1)
505 return ERROR_COMMAND_SYNTAX_ERROR;
506
507 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
508 versaloon_interface.usb_setting.ep_in);
509
510 versaloon_interface.usb_setting.ep_in |= 0x80;
511
512 return ERROR_OK;
513 }
514
515 COMMAND_HANDLER(vsllink_handle_usb_bulkout_command)
516 {
517 if (CMD_ARGC != 1)
518 return ERROR_COMMAND_SYNTAX_ERROR;
519
520 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
521 versaloon_interface.usb_setting.ep_out);
522
523 versaloon_interface.usb_setting.ep_out &= ~0x80;
524
525 return ERROR_OK;
526 }
527
528 COMMAND_HANDLER(vsllink_handle_usb_interface_command)
529 {
530 if (CMD_ARGC != 1)
531 return ERROR_COMMAND_SYNTAX_ERROR;
532
533 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
534 versaloon_interface.usb_setting.interface);
535 return ERROR_OK;
536 }
537
538 /**************************************************************************
539 * VSLLink tap functions */
540
541 static void vsllink_tap_init(void)
542 {
543 tap_length = 0;
544 pending_scan_results_length = 0;
545 vsllink_tms_offset = 0;
546 }
547
548 static void vsllink_tap_ensure_pending(int scans)
549 {
550 int available_scans =
551 MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
552
553 if (scans > available_scans)
554 vsllink_tap_execute();
555 }
556
557 static void vsllink_tap_append_step(int tms, int tdi)
558 {
559 int index_var = tap_length / 8;
560
561 int bit_index = tap_length % 8;
562 uint8_t bit = 1 << bit_index;
563
564 if (tms)
565 tms_buffer[index_var] |= bit;
566 else
567 tms_buffer[index_var] &= ~bit;
568
569 if (tdi)
570 tdi_buffer[index_var] |= bit;
571 else
572 tdi_buffer[index_var] &= ~bit;
573
574 tap_length++;
575
576 if (tap_buffer_size * 8 <= tap_length)
577 vsllink_tap_execute();
578 }
579
580 static void vsllink_tap_append_scan(int length, uint8_t *buffer,
581 struct scan_command *command)
582 {
583 struct pending_scan_result *pending_scan_result;
584 int len_tmp, len_all, i;
585
586 len_all = 0;
587 while (len_all < length) {
588 vsllink_tap_ensure_pending(1);
589 pending_scan_result =
590 &pending_scan_results_buffer[
591 pending_scan_results_length];
592
593 if ((length - len_all) > (tap_buffer_size * 8 - tap_length)) {
594 /* Use all memory available
595 vsllink_tap_append_step will commit automatically */
596 len_tmp = tap_buffer_size * 8 - tap_length;
597 pending_scan_result->last = false;
598 } else {
599 len_tmp = length - len_all;
600 pending_scan_result->last = true;
601 }
602 pending_scan_result->src_offset = tap_length;
603 pending_scan_result->dest_offset = len_all;
604 pending_scan_result->length = len_tmp;
605 pending_scan_result->command = command;
606 pending_scan_result->buffer = buffer;
607 pending_scan_results_length++;
608
609 for (i = 0; i < len_tmp; i++) {
610 vsllink_tap_append_step(((len_all + i) < length-1
611 ? 0 : 1),
612 (buffer[(len_all + i)/8]
613 >> ((len_all + i)%8)) & 1);
614 }
615
616 len_all += len_tmp;
617 }
618 }
619
620 static int vsllink_jtag_execute(void)
621 {
622 int i;
623 int result;
624
625 if (tap_length <= 0)
626 return ERROR_OK;
627
628 versaloon_interface.adaptors.jtag_raw.execute(0, tdi_buffer, tms_buffer,
629 tdo_buffer, tap_length);
630
631 result = versaloon_interface.adaptors.peripheral_commit();
632
633 if (result == ERROR_OK) {
634 for (i = 0; i < pending_scan_results_length; i++) {
635 struct pending_scan_result *pending_scan_result =
636 &pending_scan_results_buffer[i];
637 uint8_t *buffer = pending_scan_result->buffer;
638 int length = pending_scan_result->length;
639 int src_first = pending_scan_result->src_offset;
640 int dest_first = pending_scan_result->dest_offset;
641 bool last = pending_scan_result->last;
642
643 struct scan_command *command;
644
645 command = pending_scan_result->command;
646 buf_set_buf(tdo_buffer, src_first, buffer, dest_first, length);
647
648 LOG_DEBUG_IO(
649 "JTAG scan read(%d bits, from src %d bits to dest %d bits):",
650 length, src_first, dest_first);
651 if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO))
652 vsllink_debug_buffer(buffer + dest_first / 8, DIV_ROUND_UP(length, 7));
653
654 if (last) {
655 if (jtag_read_buffer(buffer, command)
656 != ERROR_OK) {
657 vsllink_tap_init();
658 return ERROR_JTAG_QUEUE_FAILED;
659 }
660
661 free(pending_scan_result->buffer);
662 }
663 }
664 } else {
665 LOG_ERROR("vsllink_jtag_execute failure");
666 return ERROR_JTAG_QUEUE_FAILED;
667 }
668
669 vsllink_tap_init();
670
671 return ERROR_OK;
672 }
673
674 static int vsllink_tap_execute(void)
675 {
676 if (swd_mode)
677 return ERROR_OK;
678
679 return vsllink_jtag_execute();
680 }
681
682 static int vsllink_swd_init(void)
683 {
684 LOG_INFO("VSLLink SWD mode enabled");
685 swd_mode = true;
686
687 return ERROR_OK;
688 }
689
690 static int_least32_t vsllink_swd_frequency(int_least32_t hz)
691 {
692 const int_least32_t delay2hz[] = {
693 1850000, 235000, 130000, 102000, 85000, 72000
694 };
695
696 if (hz > 0) {
697 uint16_t delay = UINT16_MAX;
698
699 for (uint16_t i = 0; i < ARRAY_SIZE(delay2hz); i++) {
700 if (hz >= delay2hz[i]) {
701 hz = delay2hz[i];
702 delay = i;
703 break;
704 }
705 }
706
707 if (delay == UINT16_MAX)
708 delay = (500000 / hz) - 1;
709
710 /* Calculate retry count after a WAIT response. This will give
711 * a retry timeout at about ~250 ms. 54 is the number of bits
712 * found in a transaction. */
713 uint16_t retry_count = 250 * hz / 1000 / 54;
714
715 LOG_DEBUG("SWD delay: %d, retry count: %d", delay, retry_count);
716
717 versaloon_interface.adaptors.swd.config(0, 2, retry_count, delay);
718 }
719
720 return hz;
721 }
722
723 static int vsllink_swd_switch_seq(enum swd_special_seq seq)
724 {
725 switch (seq) {
726 case LINE_RESET:
727 LOG_DEBUG("SWD line reset");
728 versaloon_interface.adaptors.swd.seqout(0, swd_seq_line_reset,
729 swd_seq_line_reset_len);
730 break;
731 case JTAG_TO_SWD:
732 LOG_DEBUG("JTAG-to-SWD");
733 versaloon_interface.adaptors.swd.seqout(0, swd_seq_jtag_to_swd,
734 swd_seq_jtag_to_swd_len);
735 break;
736 case SWD_TO_JTAG:
737 LOG_DEBUG("SWD-to-JTAG");
738 versaloon_interface.adaptors.swd.seqout(0, swd_seq_swd_to_jtag,
739 swd_seq_swd_to_jtag_len);
740 break;
741 default:
742 LOG_ERROR("Sequence %d not supported", seq);
743 return ERROR_FAIL;
744 }
745
746 return ERROR_OK;
747 }
748
749 static void vsllink_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
750 {
751 versaloon_interface.adaptors.swd.transact(0, cmd, value, NULL);
752 }
753
754 static void vsllink_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
755 {
756 versaloon_interface.adaptors.swd.transact(0, cmd, &value, NULL);
757 }
758
759 static int vsllink_swd_run_queue(void)
760 {
761 return versaloon_interface.adaptors.peripheral_commit();
762 }
763
764 /****************************************************************************
765 * VSLLink USB low-level functions */
766
767 static int vsllink_check_usb_strings(
768 struct libusb_device_handle *usb_device_handle,
769 struct libusb_device_descriptor *usb_desc)
770 {
771 char desc_string[256];
772 int retval;
773
774 if (adapter_get_required_serial()) {
775 retval = libusb_get_string_descriptor_ascii(usb_device_handle,
776 usb_desc->iSerialNumber, (unsigned char *)desc_string,
777 sizeof(desc_string));
778 if (retval < 0)
779 return ERROR_FAIL;
780
781 if (strncmp(desc_string, adapter_get_required_serial(),
782 sizeof(desc_string)))
783 return ERROR_FAIL;
784 }
785
786 retval = libusb_get_string_descriptor_ascii(usb_device_handle,
787 usb_desc->iProduct, (unsigned char *)desc_string,
788 sizeof(desc_string));
789 if (retval < 0)
790 return ERROR_FAIL;
791
792 if (!strstr(desc_string, "Versaloon"))
793 return ERROR_FAIL;
794
795 return ERROR_OK;
796 }
797
798 static int vsllink_usb_open(struct vsllink *vsllink)
799 {
800 ssize_t num_devices, i;
801 struct libusb_device **usb_devices;
802 struct libusb_device_descriptor usb_desc;
803 struct libusb_device_handle *usb_device_handle;
804 int retval;
805
806 num_devices = libusb_get_device_list(vsllink->libusb_ctx, &usb_devices);
807
808 if (num_devices <= 0)
809 return ERROR_FAIL;
810
811 for (i = 0; i < num_devices; i++) {
812 struct libusb_device *device = usb_devices[i];
813
814 retval = libusb_get_device_descriptor(device, &usb_desc);
815 if (retval != 0)
816 continue;
817
818 if (usb_desc.idVendor != versaloon_interface.usb_setting.vid ||
819 usb_desc.idProduct != versaloon_interface.usb_setting.pid)
820 continue;
821
822 retval = libusb_open(device, &usb_device_handle);
823 if (retval != 0)
824 continue;
825
826 retval = vsllink_check_usb_strings(usb_device_handle, &usb_desc);
827 if (retval == ERROR_OK)
828 break;
829
830 libusb_close(usb_device_handle);
831 }
832
833 libusb_free_device_list(usb_devices, 1);
834
835 if (i == num_devices)
836 return ERROR_FAIL;
837
838 retval = libusb_claim_interface(usb_device_handle,
839 versaloon_interface.usb_setting.interface);
840 if (retval != 0) {
841 LOG_ERROR("unable to claim interface");
842 libusb_close(usb_device_handle);
843 return ERROR_FAIL;
844 }
845
846 vsllink->usb_device_handle = usb_device_handle;
847 return ERROR_OK;
848 }
849
850 static void vsllink_usb_close(struct vsllink *vsllink)
851 {
852 libusb_release_interface(vsllink->usb_device_handle,
853 versaloon_interface.usb_setting.interface);
854 libusb_close(vsllink->usb_device_handle);
855 }
856
857 #define BYTES_PER_LINE 16
858
859 static void vsllink_debug_buffer(uint8_t *buffer, int length)
860 {
861 char line[81];
862 char s[4];
863 int i;
864 int j;
865
866 for (i = 0; i < length; i += BYTES_PER_LINE) {
867 snprintf(line, 5, "%04x", i & 0xffff);
868 for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
869 snprintf(s, 4, " %02x", buffer[j]);
870 strcat(line, s);
871 }
872 LOG_DEBUG_IO("%s", line);
873 }
874 }
875
876 static const struct command_registration vsllink_subcommand_handlers[] = {
877 {
878 .name = "usb_vid",
879 .handler = &vsllink_handle_usb_vid_command,
880 .mode = COMMAND_CONFIG,
881 .help = "Set USB VID",
882 .usage = "<vid>",
883 },
884 {
885 .name = "usb_pid",
886 .handler = &vsllink_handle_usb_pid_command,
887 .mode = COMMAND_CONFIG,
888 .help = "Set USB PID",
889 .usage = "<pid>",
890 },
891 {
892 .name = "usb_bulkin",
893 .handler = &vsllink_handle_usb_bulkin_command,
894 .mode = COMMAND_CONFIG,
895 .help = "Set USB input endpoint",
896 .usage = "<ep_in>",
897 },
898 {
899 .name = "usb_bulkout",
900 .handler = &vsllink_handle_usb_bulkout_command,
901 .mode = COMMAND_CONFIG,
902 .help = "Set USB output endpoint",
903 .usage = "<ep_out>",
904 },
905 {
906 .name = "usb_interface",
907 .handler = &vsllink_handle_usb_interface_command,
908 .mode = COMMAND_CONFIG,
909 .help = "Set USB output interface",
910 .usage = "<interface>",
911 },
912 COMMAND_REGISTRATION_DONE
913 };
914
915 static const struct command_registration vsllink_command_handlers[] = {
916 {
917 .name = "vsllink",
918 .mode = COMMAND_ANY,
919 .help = "perform vsllink management",
920 .chain = vsllink_subcommand_handlers,
921 .usage = "",
922 },
923 COMMAND_REGISTRATION_DONE
924 };
925
926 static const char * const vsllink_transports[] = {"jtag", "swd", NULL};
927
928 static const struct swd_driver vsllink_swd_driver = {
929 .init = vsllink_swd_init,
930 .switch_seq = vsllink_swd_switch_seq,
931 .read_reg = vsllink_swd_read_reg,
932 .write_reg = vsllink_swd_write_reg,
933 .run = vsllink_swd_run_queue,
934 };
935
936 static struct jtag_interface vsllink_interface = {
937 .supported = DEBUG_CAP_TMS_SEQ,
938 .execute_queue = vsllink_execute_queue,
939 };
940
941 struct adapter_driver vsllink_adapter_driver = {
942 .name = "vsllink",
943 .transports = vsllink_transports,
944 .commands = vsllink_command_handlers,
945
946 .init = vsllink_init,
947 .quit = vsllink_quit,
948 .reset = vsllink_reset,
949 .speed = vsllink_speed,
950 .khz = vsllink_khz,
951 .speed_div = vsllink_speed_div,
952
953 .jtag_ops = &vsllink_interface,
954 .swd_ops = &vsllink_swd_driver,
955 };

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)