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

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)