jtag: linuxgpiod: drop extra parenthesis
[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 libusb_exit(vsllink_handle->libusb_ctx);
277 free(vsllink_handle);
278
279 return ERROR_OK;
280 }
281
282 static int vsllink_interface_init(void)
283 {
284 vsllink_handle = malloc(sizeof(struct vsllink));
285 if (!vsllink_handle) {
286 LOG_ERROR("unable to allocate memory");
287 return ERROR_FAIL;
288 }
289
290 libusb_init(&vsllink_handle->libusb_ctx);
291
292 if (vsllink_usb_open(vsllink_handle) != ERROR_OK) {
293 LOG_ERROR("Can't find USB JTAG Interface!"
294 "Please check connection and permissions.");
295 return ERROR_JTAG_INIT_FAILED;
296 }
297 LOG_DEBUG("vsllink found on %04X:%04X",
298 versaloon_interface.usb_setting.vid,
299 versaloon_interface.usb_setting.pid);
300 versaloon_usb_device_handle = vsllink_handle->usb_device_handle;
301
302 if (versaloon_interface.init() != ERROR_OK)
303 return ERROR_FAIL;
304 if (versaloon_interface.usb_setting.buf_size < 32) {
305 versaloon_interface.fini();
306 return ERROR_FAIL;
307 }
308
309 return ERROR_OK;
310 }
311
312 static int vsllink_init(void)
313 {
314 int retval = vsllink_interface_init();
315 if (retval != ERROR_OK)
316 return retval;
317
318 versaloon_interface.adaptors.gpio.init(0);
319 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, 0, GPIO_SRST,
320 GPIO_SRST);
321 versaloon_interface.adaptors.delay.delayms(100);
322 versaloon_interface.adaptors.peripheral_commit();
323
324 if (swd_mode) {
325 versaloon_interface.adaptors.gpio.config(0, GPIO_TRST, 0,
326 GPIO_TRST, GPIO_TRST);
327 versaloon_interface.adaptors.swd.init(0);
328 vsllink_swd_frequency(adapter_get_speed_khz() * 1000);
329 vsllink_swd_switch_seq(JTAG_TO_SWD);
330
331 } else {
332 /* malloc buffer size for tap */
333 tap_buffer_size = versaloon_interface.usb_setting.buf_size / 2 - 32;
334 vsllink_free_buffer();
335 tdi_buffer = malloc(tap_buffer_size);
336 tdo_buffer = malloc(tap_buffer_size);
337 tms_buffer = malloc(tap_buffer_size);
338 if ((!tdi_buffer) || (!tdo_buffer) || (!tms_buffer)) {
339 vsllink_quit();
340 return ERROR_FAIL;
341 }
342
343 versaloon_interface.adaptors.jtag_raw.init(0);
344 versaloon_interface.adaptors.jtag_raw.config(0, adapter_get_speed_khz());
345 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST,
346 GPIO_TRST, GPIO_SRST, GPIO_SRST);
347 }
348
349 if (versaloon_interface.adaptors.peripheral_commit() != ERROR_OK)
350 return ERROR_FAIL;
351
352 vsllink_reset(0, 0);
353 vsllink_tap_init();
354 return ERROR_OK;
355 }
356
357 /**************************************************************************
358 * Queue command implementations */
359
360 static void vsllink_end_state(tap_state_t state)
361 {
362 if (tap_is_state_stable(state))
363 tap_set_end_state(state);
364 else {
365 LOG_ERROR("BUG: %i is not a valid end state", state);
366 exit(-1);
367 }
368 }
369
370 /* Goes to the end state. */
371 static void vsllink_state_move(void)
372 {
373 int i;
374 uint8_t tms_scan = tap_get_tms_path(tap_get_state(),
375 tap_get_end_state());
376 uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(),
377 tap_get_end_state());
378
379 for (i = 0; i < tms_scan_bits; i++)
380 vsllink_tap_append_step((tms_scan >> i) & 1, 0);
381
382 tap_set_state(tap_get_end_state());
383 }
384
385 static void vsllink_path_move(int num_states, tap_state_t *path)
386 {
387 for (int i = 0; i < num_states; i++) {
388 if (path[i] == tap_state_transition(tap_get_state(), false))
389 vsllink_tap_append_step(0, 0);
390 else if (path[i] == tap_state_transition(tap_get_state(), true))
391 vsllink_tap_append_step(1, 0);
392 else {
393 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
394 tap_state_name(tap_get_state()),
395 tap_state_name(path[i]));
396 exit(-1);
397 }
398
399 tap_set_state(path[i]);
400 }
401
402 tap_set_end_state(tap_get_state());
403 }
404
405 static void vsllink_tms(int num_bits, const uint8_t *bits)
406 {
407 for (int i = 0; i < num_bits; i++)
408 vsllink_tap_append_step((bits[i / 8] >> (i % 8)) & 1, 0);
409 }
410
411 static void vsllink_stableclocks(int num_cycles, int tms)
412 {
413 while (num_cycles > 0) {
414 vsllink_tap_append_step(tms, 0);
415 num_cycles--;
416 }
417 }
418
419 static void vsllink_runtest(int num_cycles)
420 {
421 tap_state_t saved_end_state = tap_get_end_state();
422
423 if (tap_get_state() != TAP_IDLE) {
424 /* enter IDLE state */
425 vsllink_end_state(TAP_IDLE);
426 vsllink_state_move();
427 }
428
429 vsllink_stableclocks(num_cycles, 0);
430
431 /* post-process */
432 /* set end_state */
433 vsllink_end_state(saved_end_state);
434 if (tap_get_end_state() != tap_get_end_state())
435 vsllink_state_move();
436 }
437
438 static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
439 int scan_size, struct scan_command *command)
440 {
441 tap_state_t saved_end_state;
442
443 saved_end_state = tap_get_end_state();
444
445 /* Move to appropriate scan state */
446 vsllink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
447
448 if (tap_get_state() != tap_get_end_state())
449 vsllink_state_move();
450 vsllink_end_state(saved_end_state);
451
452 /* Scan */
453 vsllink_tap_append_scan(scan_size, buffer, command);
454
455 /* Goto Pause and record position to insert tms:0 */
456 vsllink_tap_append_step(0, 0);
457 vsllink_tms_offset = tap_length;
458
459 tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
460
461 if (tap_get_state() != tap_get_end_state())
462 vsllink_state_move();
463 }
464
465 static int vsllink_reset(int trst, int srst)
466 {
467 LOG_DEBUG("trst: %i, srst: %i", trst, srst);
468
469 if (!srst)
470 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, 0, GPIO_SRST, GPIO_SRST);
471 else
472 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, GPIO_SRST, 0, 0);
473
474 if (!swd_mode) {
475 if (!trst)
476 versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, GPIO_TRST);
477 else
478 versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, 0);
479 }
480
481 return versaloon_interface.adaptors.peripheral_commit();
482 }
483
484 COMMAND_HANDLER(vsllink_handle_usb_vid_command)
485 {
486 if (CMD_ARGC != 1)
487 return ERROR_COMMAND_SYNTAX_ERROR;
488
489 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
490 versaloon_interface.usb_setting.vid);
491 return ERROR_OK;
492 }
493
494 COMMAND_HANDLER(vsllink_handle_usb_pid_command)
495 {
496 if (CMD_ARGC != 1)
497 return ERROR_COMMAND_SYNTAX_ERROR;
498 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
499 versaloon_interface.usb_setting.pid);
500 return ERROR_OK;
501 }
502
503 COMMAND_HANDLER(vsllink_handle_usb_bulkin_command)
504 {
505 if (CMD_ARGC != 1)
506 return ERROR_COMMAND_SYNTAX_ERROR;
507
508 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
509 versaloon_interface.usb_setting.ep_in);
510
511 versaloon_interface.usb_setting.ep_in |= 0x80;
512
513 return ERROR_OK;
514 }
515
516 COMMAND_HANDLER(vsllink_handle_usb_bulkout_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_out);
523
524 versaloon_interface.usb_setting.ep_out &= ~0x80;
525
526 return ERROR_OK;
527 }
528
529 COMMAND_HANDLER(vsllink_handle_usb_interface_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.interface);
536 return ERROR_OK;
537 }
538
539 /**************************************************************************
540 * VSLLink tap functions */
541
542 static void vsllink_tap_init(void)
543 {
544 tap_length = 0;
545 pending_scan_results_length = 0;
546 vsllink_tms_offset = 0;
547 }
548
549 static void vsllink_tap_ensure_pending(int scans)
550 {
551 int available_scans =
552 MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
553
554 if (scans > available_scans)
555 vsllink_tap_execute();
556 }
557
558 static void vsllink_tap_append_step(int tms, int tdi)
559 {
560 int index_var = tap_length / 8;
561
562 int bit_index = tap_length % 8;
563 uint8_t bit = 1 << bit_index;
564
565 if (tms)
566 tms_buffer[index_var] |= bit;
567 else
568 tms_buffer[index_var] &= ~bit;
569
570 if (tdi)
571 tdi_buffer[index_var] |= bit;
572 else
573 tdi_buffer[index_var] &= ~bit;
574
575 tap_length++;
576
577 if (tap_buffer_size * 8 <= tap_length)
578 vsllink_tap_execute();
579 }
580
581 static void vsllink_tap_append_scan(int length, uint8_t *buffer,
582 struct scan_command *command)
583 {
584 struct pending_scan_result *pending_scan_result;
585 int len_tmp, len_all, i;
586
587 len_all = 0;
588 while (len_all < length) {
589 vsllink_tap_ensure_pending(1);
590 pending_scan_result =
591 &pending_scan_results_buffer[
592 pending_scan_results_length];
593
594 if ((length - len_all) > (tap_buffer_size * 8 - tap_length)) {
595 /* Use all memory available
596 vsllink_tap_append_step will commit automatically */
597 len_tmp = tap_buffer_size * 8 - tap_length;
598 pending_scan_result->last = false;
599 } else {
600 len_tmp = length - len_all;
601 pending_scan_result->last = true;
602 }
603 pending_scan_result->src_offset = tap_length;
604 pending_scan_result->dest_offset = len_all;
605 pending_scan_result->length = len_tmp;
606 pending_scan_result->command = command;
607 pending_scan_result->buffer = buffer;
608 pending_scan_results_length++;
609
610 for (i = 0; i < len_tmp; i++) {
611 vsllink_tap_append_step(((len_all + i) < length-1
612 ? 0 : 1),
613 (buffer[(len_all + i)/8]
614 >> ((len_all + i)%8)) & 1);
615 }
616
617 len_all += len_tmp;
618 }
619 }
620
621 static int vsllink_jtag_execute(void)
622 {
623 int i;
624 int result;
625
626 if (tap_length <= 0)
627 return ERROR_OK;
628
629 versaloon_interface.adaptors.jtag_raw.execute(0, tdi_buffer, tms_buffer,
630 tdo_buffer, tap_length);
631
632 result = versaloon_interface.adaptors.peripheral_commit();
633
634 if (result == ERROR_OK) {
635 for (i = 0; i < pending_scan_results_length; i++) {
636 struct pending_scan_result *pending_scan_result =
637 &pending_scan_results_buffer[i];
638 uint8_t *buffer = pending_scan_result->buffer;
639 int length = pending_scan_result->length;
640 int src_first = pending_scan_result->src_offset;
641 int dest_first = pending_scan_result->dest_offset;
642 bool last = pending_scan_result->last;
643
644 struct scan_command *command;
645
646 command = pending_scan_result->command;
647 buf_set_buf(tdo_buffer, src_first, buffer, dest_first, length);
648
649 LOG_DEBUG_IO(
650 "JTAG scan read(%d bits, from src %d bits to dest %d bits):",
651 length, src_first, dest_first);
652 if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO))
653 vsllink_debug_buffer(buffer + dest_first / 8, DIV_ROUND_UP(length, 7));
654
655 if (last) {
656 if (jtag_read_buffer(buffer, command)
657 != ERROR_OK) {
658 vsllink_tap_init();
659 return ERROR_JTAG_QUEUE_FAILED;
660 }
661
662 free(pending_scan_result->buffer);
663 }
664 }
665 } else {
666 LOG_ERROR("vsllink_jtag_execute failure");
667 return ERROR_JTAG_QUEUE_FAILED;
668 }
669
670 vsllink_tap_init();
671
672 return ERROR_OK;
673 }
674
675 static int vsllink_tap_execute(void)
676 {
677 if (swd_mode)
678 return ERROR_OK;
679
680 return vsllink_jtag_execute();
681 }
682
683 static int vsllink_swd_init(void)
684 {
685 LOG_INFO("VSLLink SWD mode enabled");
686 swd_mode = true;
687
688 return ERROR_OK;
689 }
690
691 static int_least32_t vsllink_swd_frequency(int_least32_t hz)
692 {
693 const int_least32_t delay2hz[] = {
694 1850000, 235000, 130000, 102000, 85000, 72000
695 };
696
697 if (hz > 0) {
698 uint16_t delay = UINT16_MAX;
699
700 for (uint16_t i = 0; i < ARRAY_SIZE(delay2hz); i++) {
701 if (hz >= delay2hz[i]) {
702 hz = delay2hz[i];
703 delay = i;
704 break;
705 }
706 }
707
708 if (delay == UINT16_MAX)
709 delay = (500000 / hz) - 1;
710
711 /* Calculate retry count after a WAIT response. This will give
712 * a retry timeout at about ~250 ms. 54 is the number of bits
713 * found in a transaction. */
714 uint16_t retry_count = 250 * hz / 1000 / 54;
715
716 LOG_DEBUG("SWD delay: %d, retry count: %d", delay, retry_count);
717
718 versaloon_interface.adaptors.swd.config(0, 2, retry_count, delay);
719 }
720
721 return hz;
722 }
723
724 static int vsllink_swd_switch_seq(enum swd_special_seq seq)
725 {
726 switch (seq) {
727 case LINE_RESET:
728 LOG_DEBUG("SWD line reset");
729 versaloon_interface.adaptors.swd.seqout(0, swd_seq_line_reset,
730 swd_seq_line_reset_len);
731 break;
732 case JTAG_TO_SWD:
733 LOG_DEBUG("JTAG-to-SWD");
734 versaloon_interface.adaptors.swd.seqout(0, swd_seq_jtag_to_swd,
735 swd_seq_jtag_to_swd_len);
736 break;
737 case SWD_TO_JTAG:
738 LOG_DEBUG("SWD-to-JTAG");
739 versaloon_interface.adaptors.swd.seqout(0, swd_seq_swd_to_jtag,
740 swd_seq_swd_to_jtag_len);
741 break;
742 default:
743 LOG_ERROR("Sequence %d not supported", seq);
744 return ERROR_FAIL;
745 }
746
747 return ERROR_OK;
748 }
749
750 static void vsllink_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
751 {
752 versaloon_interface.adaptors.swd.transact(0, cmd, value, NULL);
753 }
754
755 static void vsllink_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
756 {
757 versaloon_interface.adaptors.swd.transact(0, cmd, &value, NULL);
758 }
759
760 static int vsllink_swd_run_queue(void)
761 {
762 return versaloon_interface.adaptors.peripheral_commit();
763 }
764
765 /****************************************************************************
766 * VSLLink USB low-level functions */
767
768 static int vsllink_check_usb_strings(
769 struct libusb_device_handle *usb_device_handle,
770 struct libusb_device_descriptor *usb_desc)
771 {
772 char desc_string[256];
773 int retval;
774
775 if (adapter_get_required_serial()) {
776 retval = libusb_get_string_descriptor_ascii(usb_device_handle,
777 usb_desc->iSerialNumber, (unsigned char *)desc_string,
778 sizeof(desc_string));
779 if (retval < 0)
780 return ERROR_FAIL;
781
782 if (strncmp(desc_string, adapter_get_required_serial(),
783 sizeof(desc_string)))
784 return ERROR_FAIL;
785 }
786
787 retval = libusb_get_string_descriptor_ascii(usb_device_handle,
788 usb_desc->iProduct, (unsigned char *)desc_string,
789 sizeof(desc_string));
790 if (retval < 0)
791 return ERROR_FAIL;
792
793 if (!strstr(desc_string, "Versaloon"))
794 return ERROR_FAIL;
795
796 return ERROR_OK;
797 }
798
799 static int vsllink_usb_open(struct vsllink *vsllink)
800 {
801 ssize_t num_devices, i;
802 struct libusb_device **usb_devices;
803 struct libusb_device_descriptor usb_desc;
804 struct libusb_device_handle *usb_device_handle;
805 int retval;
806
807 num_devices = libusb_get_device_list(vsllink->libusb_ctx, &usb_devices);
808
809 if (num_devices <= 0)
810 return ERROR_FAIL;
811
812 for (i = 0; i < num_devices; i++) {
813 struct libusb_device *device = usb_devices[i];
814
815 retval = libusb_get_device_descriptor(device, &usb_desc);
816 if (retval != 0)
817 continue;
818
819 if (usb_desc.idVendor != versaloon_interface.usb_setting.vid ||
820 usb_desc.idProduct != versaloon_interface.usb_setting.pid)
821 continue;
822
823 retval = libusb_open(device, &usb_device_handle);
824 if (retval != 0)
825 continue;
826
827 retval = vsllink_check_usb_strings(usb_device_handle, &usb_desc);
828 if (retval == ERROR_OK)
829 break;
830
831 libusb_close(usb_device_handle);
832 }
833
834 libusb_free_device_list(usb_devices, 1);
835
836 if (i == num_devices)
837 return ERROR_FAIL;
838
839 retval = libusb_claim_interface(usb_device_handle,
840 versaloon_interface.usb_setting.interface);
841 if (retval != 0) {
842 LOG_ERROR("unable to claim interface");
843 libusb_close(usb_device_handle);
844 return ERROR_FAIL;
845 }
846
847 vsllink->usb_device_handle = usb_device_handle;
848 return ERROR_OK;
849 }
850
851 static void vsllink_usb_close(struct vsllink *vsllink)
852 {
853 libusb_release_interface(vsllink->usb_device_handle,
854 versaloon_interface.usb_setting.interface);
855 libusb_close(vsllink->usb_device_handle);
856 }
857
858 #define BYTES_PER_LINE 16
859
860 static void vsllink_debug_buffer(uint8_t *buffer, int length)
861 {
862 char line[81];
863 char s[4];
864 int i;
865 int j;
866
867 for (i = 0; i < length; i += BYTES_PER_LINE) {
868 snprintf(line, 5, "%04x", i & 0xffff);
869 for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
870 snprintf(s, 4, " %02x", buffer[j]);
871 strcat(line, s);
872 }
873 LOG_DEBUG_IO("%s", line);
874 }
875 }
876
877 static const struct command_registration vsllink_subcommand_handlers[] = {
878 {
879 .name = "usb_vid",
880 .handler = &vsllink_handle_usb_vid_command,
881 .mode = COMMAND_CONFIG,
882 .help = "Set USB VID",
883 .usage = "<vid>",
884 },
885 {
886 .name = "usb_pid",
887 .handler = &vsllink_handle_usb_pid_command,
888 .mode = COMMAND_CONFIG,
889 .help = "Set USB PID",
890 .usage = "<pid>",
891 },
892 {
893 .name = "usb_bulkin",
894 .handler = &vsllink_handle_usb_bulkin_command,
895 .mode = COMMAND_CONFIG,
896 .help = "Set USB input endpoint",
897 .usage = "<ep_in>",
898 },
899 {
900 .name = "usb_bulkout",
901 .handler = &vsllink_handle_usb_bulkout_command,
902 .mode = COMMAND_CONFIG,
903 .help = "Set USB output endpoint",
904 .usage = "<ep_out>",
905 },
906 {
907 .name = "usb_interface",
908 .handler = &vsllink_handle_usb_interface_command,
909 .mode = COMMAND_CONFIG,
910 .help = "Set USB output interface",
911 .usage = "<interface>",
912 },
913 COMMAND_REGISTRATION_DONE
914 };
915
916 static const struct command_registration vsllink_command_handlers[] = {
917 {
918 .name = "vsllink",
919 .mode = COMMAND_ANY,
920 .help = "perform vsllink management",
921 .chain = vsllink_subcommand_handlers,
922 .usage = "",
923 },
924 COMMAND_REGISTRATION_DONE
925 };
926
927 static const char * const vsllink_transports[] = {"jtag", "swd", NULL};
928
929 static const struct swd_driver vsllink_swd_driver = {
930 .init = vsllink_swd_init,
931 .switch_seq = vsllink_swd_switch_seq,
932 .read_reg = vsllink_swd_read_reg,
933 .write_reg = vsllink_swd_write_reg,
934 .run = vsllink_swd_run_queue,
935 };
936
937 static struct jtag_interface vsllink_interface = {
938 .supported = DEBUG_CAP_TMS_SEQ,
939 .execute_queue = vsllink_execute_queue,
940 };
941
942 struct adapter_driver vsllink_adapter_driver = {
943 .name = "vsllink",
944 .transports = vsllink_transports,
945 .commands = vsllink_command_handlers,
946
947 .init = vsllink_init,
948 .quit = vsllink_quit,
949 .reset = vsllink_reset,
950 .speed = vsllink_speed,
951 .khz = vsllink_khz,
952 .speed_div = vsllink_speed_div,
953
954 .jtag_ops = &vsllink_interface,
955 .swd_ops = &vsllink_swd_driver,
956 };

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)