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

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)