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

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)