versaloon: Finish support for serial number matching
[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 "usb_common.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 void 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 lowlevel functions */
74 struct vsllink {
75 struct usb_dev_handle *usb_handle;
76 };
77
78 static struct vsllink *vsllink_usb_open(void);
79 static void vsllink_usb_close(struct vsllink *vsllink);
80
81 #if defined _DEBUG_JTAG_IO_
82 static void vsllink_debug_buffer(uint8_t *buffer, int length);
83 #endif
84
85 static int tap_length;
86 static int tap_buffer_size;
87 static uint8_t *tms_buffer;
88 static uint8_t *tdi_buffer;
89 static uint8_t *tdo_buffer;
90
91 struct vsllink *vsllink_handle;
92
93 static int vsllink_execute_queue(void)
94 {
95 struct jtag_command *cmd = jtag_command_queue;
96 int scan_size;
97 enum scan_type type;
98 uint8_t *buffer;
99
100 DEBUG_JTAG_IO("-------------------------------------"
101 " vsllink "
102 "-------------------------------------");
103
104 while (cmd != NULL) {
105 switch (cmd->type) {
106 case JTAG_RUNTEST:
107 DEBUG_JTAG_IO("runtest %i cycles, end in %s",
108 cmd->cmd.runtest->num_cycles,
109 tap_state_name(cmd->cmd.runtest->end_state));
110
111 vsllink_end_state(cmd->cmd.runtest->end_state);
112 vsllink_runtest(cmd->cmd.runtest->num_cycles);
113 break;
114
115 case JTAG_TLR_RESET:
116 DEBUG_JTAG_IO("statemove end in %s",
117 tap_state_name(cmd->cmd.statemove->end_state));
118
119 vsllink_end_state(cmd->cmd.statemove->end_state);
120 vsllink_state_move();
121 break;
122
123 case JTAG_PATHMOVE:
124 DEBUG_JTAG_IO("pathmove: %i states, end in %s",
125 cmd->cmd.pathmove->num_states,
126 tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
127
128 vsllink_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);
129 break;
130
131 case JTAG_SCAN:
132 DEBUG_JTAG_IO("JTAG Scan...");
133
134 vsllink_end_state(cmd->cmd.scan->end_state);
135
136 scan_size = jtag_build_buffer(
137 cmd->cmd.scan, &buffer);
138
139 if (cmd->cmd.scan->ir_scan)
140 DEBUG_JTAG_IO(
141 "JTAG Scan write IR(%d bits), "
142 "end in %s:",
143 scan_size,
144 tap_state_name(cmd->cmd.scan->end_state));
145
146 else
147 DEBUG_JTAG_IO(
148 "JTAG Scan write DR(%d bits), "
149 "end in %s:",
150 scan_size,
151 tap_state_name(cmd->cmd.scan->end_state));
152
153 #ifdef _DEBUG_JTAG_IO_
154 vsllink_debug_buffer(buffer,
155 DIV_ROUND_UP(scan_size, 8));
156 #endif
157
158 type = jtag_scan_type(cmd->cmd.scan);
159
160 vsllink_scan(cmd->cmd.scan->ir_scan,
161 type, buffer, scan_size,
162 cmd->cmd.scan);
163 break;
164
165 case JTAG_RESET:
166 DEBUG_JTAG_IO("reset trst: %i srst %i",
167 cmd->cmd.reset->trst,
168 cmd->cmd.reset->srst);
169
170 vsllink_tap_execute();
171
172 if (cmd->cmd.reset->trst == 1)
173 tap_set_state(TAP_RESET);
174
175 vsllink_reset(cmd->cmd.reset->trst,
176 cmd->cmd.reset->srst);
177 break;
178
179 case JTAG_SLEEP:
180 DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us);
181 vsllink_tap_execute();
182 jtag_sleep(cmd->cmd.sleep->us);
183 break;
184
185 case JTAG_STABLECLOCKS:
186 DEBUG_JTAG_IO("add %d clocks",
187 cmd->cmd.stableclocks->num_cycles);
188
189 switch (tap_get_state()) {
190 case TAP_RESET:
191 /* tms must be '1' to stay
192 * n TAP_RESET mode
193 */
194 scan_size = 1;
195 break;
196 case TAP_DRSHIFT:
197 case TAP_IDLE:
198 case TAP_DRPAUSE:
199 case TAP_IRSHIFT:
200 case TAP_IRPAUSE:
201 /* else, tms should be '0' */
202 scan_size = 0;
203 break;
204 /* above stable states are OK */
205 default:
206 LOG_ERROR("jtag_add_clocks() "
207 "in non-stable state \"%s\"",
208 tap_state_name(tap_get_state())
209 );
210 exit(-1);
211 }
212 vsllink_stableclocks(cmd->cmd.stableclocks->num_cycles, scan_size);
213 break;
214
215 case JTAG_TMS:
216 DEBUG_JTAG_IO("add %d jtag tms",
217 cmd->cmd.tms->num_bits);
218
219 vsllink_tms(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits);
220 break;
221
222 default:
223 LOG_ERROR("BUG: unknown JTAG command type "
224 "encountered: %d", cmd->type);
225 exit(-1);
226 }
227 cmd = cmd->next;
228 }
229
230 return vsllink_tap_execute();
231 }
232
233 static int vsllink_speed(int speed)
234 {
235 versaloon_interface.adaptors.jtag_raw.config(0, (uint16_t)speed);
236 return versaloon_interface.adaptors.peripheral_commit();
237 }
238
239 static int vsllink_khz(int khz, int *jtag_speed)
240 {
241 *jtag_speed = khz;
242
243 return ERROR_OK;
244 }
245
246 static int vsllink_speed_div(int jtag_speed, int *khz)
247 {
248 *khz = jtag_speed;
249
250 return ERROR_OK;
251 }
252
253 static void vsllink_free_buffer(void)
254 {
255 if (tdi_buffer != NULL) {
256 free(tdi_buffer);
257 tdi_buffer = NULL;
258 }
259 if (tdo_buffer != NULL) {
260 free(tdo_buffer);
261 tdo_buffer = NULL;
262 }
263 if (tms_buffer != NULL) {
264 free(tms_buffer);
265 tms_buffer = NULL;
266 }
267 }
268
269 static int vsllink_quit(void)
270 {
271 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST,
272 0, 0, GPIO_SRST | GPIO_TRST);
273 versaloon_interface.adaptors.gpio.fini(0);
274 versaloon_interface.adaptors.jtag_raw.fini(0);
275 versaloon_interface.adaptors.peripheral_commit();
276 versaloon_interface.fini();
277
278 vsllink_free_buffer();
279 vsllink_usb_close(vsllink_handle);
280
281 return ERROR_OK;
282 }
283
284 static int vsllink_init(void)
285 {
286 vsllink_handle = vsllink_usb_open();
287 if (vsllink_handle == 0) {
288 LOG_ERROR("Can't find USB JTAG Interface!" \
289 "Please check connection and permissions.");
290 return ERROR_JTAG_INIT_FAILED;
291 }
292 LOG_DEBUG("vsllink found on %04X:%04X",
293 versaloon_interface.usb_setting.vid,
294 versaloon_interface.usb_setting.pid);
295 versaloon_usb_device_handle = vsllink_handle->usb_handle;
296
297 if (ERROR_OK != versaloon_interface.init())
298 return ERROR_FAIL;
299 if (versaloon_interface.usb_setting.buf_size < 32) {
300 versaloon_interface.fini();
301 return ERROR_FAIL;
302 }
303
304 /* malloc buffer size for tap */
305 tap_buffer_size = versaloon_interface.usb_setting.buf_size / 2 - 32;
306 vsllink_free_buffer();
307 tdi_buffer = malloc(tap_buffer_size);
308 tdo_buffer = malloc(tap_buffer_size);
309 tms_buffer = malloc(tap_buffer_size);
310 if ((NULL == tdi_buffer) || (NULL == tdo_buffer) || (NULL == tms_buffer)) {
311 vsllink_quit();
312 return ERROR_FAIL;
313 }
314
315 versaloon_interface.adaptors.jtag_raw.init(0);
316 versaloon_interface.adaptors.jtag_raw.config(0, jtag_get_speed_khz());
317 versaloon_interface.adaptors.gpio.init(0);
318 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST,
319 GPIO_TRST, GPIO_SRST, GPIO_SRST);
320 if (ERROR_OK != versaloon_interface.adaptors.peripheral_commit())
321 return ERROR_FAIL;
322
323 vsllink_reset(0, 0);
324 vsllink_tap_init();
325 return ERROR_OK;
326 }
327
328 /**************************************************************************
329 * Queue command implementations */
330
331 static void vsllink_end_state(tap_state_t state)
332 {
333 if (tap_is_state_stable(state))
334 tap_set_end_state(state);
335 else {
336 LOG_ERROR("BUG: %i is not a valid end state", state);
337 exit(-1);
338 }
339 }
340
341 /* Goes to the end state. */
342 static void vsllink_state_move(void)
343 {
344 int i;
345 uint8_t tms_scan = tap_get_tms_path(tap_get_state(),
346 tap_get_end_state());
347 uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(),
348 tap_get_end_state());
349
350 for (i = 0; i < tms_scan_bits; i++)
351 vsllink_tap_append_step((tms_scan >> i) & 1, 0);
352
353 tap_set_state(tap_get_end_state());
354 }
355
356 static void vsllink_path_move(int num_states, tap_state_t *path)
357 {
358 for (int i = 0; i < num_states; i++) {
359 if (path[i] == tap_state_transition(tap_get_state(), false))
360 vsllink_tap_append_step(0, 0);
361 else if (path[i] == tap_state_transition(tap_get_state(), true))
362 vsllink_tap_append_step(1, 0);
363 else {
364 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
365 tap_state_name(tap_get_state()),
366 tap_state_name(path[i]));
367 exit(-1);
368 }
369
370 tap_set_state(path[i]);
371 }
372
373 tap_set_end_state(tap_get_state());
374 }
375
376 static void vsllink_tms(int num_bits, const uint8_t *bits)
377 {
378 for (int i = 0; i < num_bits; i++)
379 vsllink_tap_append_step((bits[i / 8] >> (i % 8)) & 1, 0);
380 }
381
382 static void vsllink_stableclocks(int num_cycles, int tms)
383 {
384 while (num_cycles > 0) {
385 vsllink_tap_append_step(tms, 0);
386 num_cycles--;
387 }
388 }
389
390 static void vsllink_runtest(int num_cycles)
391 {
392 tap_state_t saved_end_state = tap_get_end_state();
393
394 if (tap_get_state() != TAP_IDLE) {
395 /* enter IDLE state */
396 vsllink_end_state(TAP_IDLE);
397 vsllink_state_move();
398 }
399
400 vsllink_stableclocks(num_cycles, 0);
401
402 /* post-process */
403 /* set end_state */
404 vsllink_end_state(saved_end_state);
405 if (tap_get_end_state() != tap_get_end_state())
406 vsllink_state_move();
407 }
408
409 static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
410 int scan_size, struct scan_command *command)
411 {
412 tap_state_t saved_end_state;
413
414 saved_end_state = tap_get_end_state();
415
416 /* Move to appropriate scan state */
417 vsllink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
418
419 if (tap_get_state() != tap_get_end_state())
420 vsllink_state_move();
421 vsllink_end_state(saved_end_state);
422
423 /* Scan */
424 vsllink_tap_append_scan(scan_size, buffer, command);
425
426 /* Goto Pause and record position to insert tms:0 */
427 vsllink_tap_append_step(0, 0);
428 vsllink_tms_offset = tap_length;
429
430 tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
431
432 if (tap_get_state() != tap_get_end_state())
433 vsllink_state_move();
434 }
435
436 static void vsllink_reset(int trst, int srst)
437 {
438 LOG_DEBUG("trst: %i, srst: %i", trst, srst);
439
440 if (!srst)
441 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, 0, GPIO_SRST, GPIO_SRST);
442 else
443 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, GPIO_SRST, 0, 0);
444
445 if (!trst)
446 versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, GPIO_TRST);
447 else
448 versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, 0);
449 versaloon_interface.adaptors.peripheral_commit();
450 }
451
452 COMMAND_HANDLER(vsllink_handle_usb_vid_command)
453 {
454 if (CMD_ARGC != 1)
455 return ERROR_COMMAND_SYNTAX_ERROR;
456
457 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
458 versaloon_interface.usb_setting.vid);
459 return ERROR_OK;
460 }
461
462 COMMAND_HANDLER(vsllink_handle_usb_pid_command)
463 {
464 if (CMD_ARGC != 1)
465 return ERROR_COMMAND_SYNTAX_ERROR;
466 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
467 versaloon_interface.usb_setting.pid);
468 return ERROR_OK;
469 }
470
471 COMMAND_HANDLER(vsllink_handle_usb_serial_command)
472 {
473 if (CMD_ARGC > 1)
474 return ERROR_COMMAND_SYNTAX_ERROR;
475
476 free(versaloon_interface.usb_setting.serialstring);
477
478 if (CMD_ARGC == 1)
479 versaloon_interface.usb_setting.serialstring = strdup(CMD_ARGV[0]);
480 else
481 versaloon_interface.usb_setting.serialstring = NULL;
482
483 return ERROR_OK;
484 }
485
486 COMMAND_HANDLER(vsllink_handle_usb_bulkin_command)
487 {
488 if (CMD_ARGC != 1)
489 return ERROR_COMMAND_SYNTAX_ERROR;
490
491 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
492 versaloon_interface.usb_setting.ep_in);
493
494 versaloon_interface.usb_setting.ep_in |= 0x80;
495
496 return ERROR_OK;
497 }
498
499 COMMAND_HANDLER(vsllink_handle_usb_bulkout_command)
500 {
501 if (CMD_ARGC != 1)
502 return ERROR_COMMAND_SYNTAX_ERROR;
503
504 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
505 versaloon_interface.usb_setting.ep_out);
506
507 versaloon_interface.usb_setting.ep_out &= ~0x80;
508
509 return ERROR_OK;
510 }
511
512 COMMAND_HANDLER(vsllink_handle_usb_interface_command)
513 {
514 if (CMD_ARGC != 1)
515 return ERROR_COMMAND_SYNTAX_ERROR;
516
517 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
518 versaloon_interface.usb_setting.interface);
519 return ERROR_OK;
520 }
521
522 /**************************************************************************
523 * VSLLink tap functions */
524
525 static void vsllink_tap_init(void)
526 {
527 tap_length = 0;
528 pending_scan_results_length = 0;
529 vsllink_tms_offset = 0;
530 }
531
532 static void vsllink_tap_ensure_pending(int scans)
533 {
534 int available_scans =
535 MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
536
537 if (scans > available_scans)
538 vsllink_tap_execute();
539 }
540
541 static void vsllink_tap_append_step(int tms, int tdi)
542 {
543 int index_var = tap_length / 8;
544
545 int bit_index = tap_length % 8;
546 uint8_t bit = 1 << bit_index;
547
548 if (tms)
549 tms_buffer[index_var] |= bit;
550 else
551 tms_buffer[index_var] &= ~bit;
552
553 if (tdi)
554 tdi_buffer[index_var] |= bit;
555 else
556 tdi_buffer[index_var] &= ~bit;
557
558 tap_length++;
559
560 if (tap_buffer_size * 8 <= tap_length)
561 vsllink_tap_execute();
562 }
563
564 static void vsllink_tap_append_scan(int length, uint8_t *buffer,
565 struct scan_command *command)
566 {
567 struct pending_scan_result *pending_scan_result;
568 int len_tmp, len_all, i;
569
570 len_all = 0;
571 while (len_all < length) {
572 vsllink_tap_ensure_pending(1);
573 pending_scan_result =
574 &pending_scan_results_buffer[
575 pending_scan_results_length];
576
577 if ((length - len_all) > (tap_buffer_size * 8 - tap_length)) {
578 /* Use all memory available
579 vsllink_tap_append_step will commit automatically */
580 len_tmp = tap_buffer_size * 8 - tap_length;
581 pending_scan_result->last = false;
582 } else {
583 len_tmp = length - len_all;
584 pending_scan_result->last = true;
585 }
586 pending_scan_result->src_offset = tap_length;
587 pending_scan_result->dest_offset = len_all;
588 pending_scan_result->length = len_tmp;
589 pending_scan_result->command = command;
590 pending_scan_result->buffer = buffer;
591 pending_scan_results_length++;
592
593 for (i = 0; i < len_tmp; i++) {
594 vsllink_tap_append_step(((len_all + i) < length-1
595 ? 0 : 1),
596 (buffer[(len_all + i)/8]
597 >> ((len_all + i)%8)) & 1);
598 }
599
600 len_all += len_tmp;
601 }
602 }
603
604 static int vsllink_jtag_execute(void)
605 {
606 int i;
607 int result;
608
609 if (tap_length <= 0)
610 return ERROR_OK;
611
612 versaloon_interface.adaptors.jtag_raw.execute(0, tdi_buffer, tms_buffer,
613 tdo_buffer, tap_length);
614
615 result = versaloon_interface.adaptors.peripheral_commit();
616
617 if (result == ERROR_OK) {
618 for (i = 0; i < pending_scan_results_length; i++) {
619 struct pending_scan_result *pending_scan_result =
620 &pending_scan_results_buffer[i];
621 uint8_t *buffer = pending_scan_result->buffer;
622 int length = pending_scan_result->length;
623 int src_first = pending_scan_result->src_offset;
624 int dest_first = pending_scan_result->dest_offset;
625 bool last = pending_scan_result->last;
626
627 struct scan_command *command;
628
629 command = pending_scan_result->command;
630 buf_set_buf(tdo_buffer, src_first, buffer, dest_first, length);
631
632 #ifdef _DEBUG_JTAG_IO_
633 DEBUG_JTAG_IO(
634 "JTAG scan read(%d bits, from src %d bits to dest %d bits):",
635 length, src_first, dest_first);
636 vsllink_debug_buffer(buffer + dest_first / 8,
637 DIV_ROUND_UP(length, 7));
638 #endif
639
640 if (last) {
641 if (jtag_read_buffer(buffer, command)
642 != ERROR_OK) {
643 vsllink_tap_init();
644 return ERROR_JTAG_QUEUE_FAILED;
645 }
646
647 if (pending_scan_result->buffer != NULL)
648 free(pending_scan_result->buffer);
649 }
650 }
651 } else {
652 LOG_ERROR("vsllink_jtag_execute failure");
653 return ERROR_JTAG_QUEUE_FAILED;
654 }
655
656 vsllink_tap_init();
657
658 return ERROR_OK;
659 }
660
661 static int vsllink_tap_execute(void)
662 {
663 return vsllink_jtag_execute();
664 }
665
666 /****************************************************************************
667 * VSLLink USB low-level functions */
668
669 static uint8_t usb_check_string(usb_dev_handle *usb, uint8_t stringidx,
670 char *string, char *buff, uint16_t buf_size)
671 {
672 int len;
673 uint8_t alloced = 0;
674 uint8_t ret = 1;
675
676 if (NULL == buff) {
677 buf_size = 256;
678 buff = malloc(buf_size);
679 if (NULL == buff) {
680 ret = 0;
681 goto free_and_return;
682 }
683 alloced = 1;
684 }
685
686 strcpy(buff, "");
687 len = usb_get_string_simple(usb, stringidx, buff, buf_size);
688 if ((len < 0) || ((size_t)len != strlen(buff))) {
689 ret = 0;
690 goto free_and_return;
691 }
692
693 buff[len] = '\0';
694 if ((string != NULL) && strcmp(buff, string)) {
695 ret = 0;
696 goto free_and_return;
697 }
698
699 free_and_return:
700 if (alloced && (buff != NULL)) {
701 free(buff);
702 buff = NULL;
703 }
704 return ret;
705 }
706
707 static usb_dev_handle *find_usb_device(uint16_t VID, uint16_t PID, uint8_t interface,
708 char *serialstring, char *productstring)
709 {
710 usb_dev_handle *dev_handle = NULL;
711 struct usb_bus *busses;
712 struct usb_bus *bus;
713 struct usb_device *dev;
714
715 usb_init();
716 usb_find_busses();
717 usb_find_devices();
718 busses = usb_get_busses();
719
720 for (bus = busses; bus; bus = bus->next) {
721 for (dev = bus->devices; dev; dev = dev->next) {
722 if ((dev->descriptor.idVendor == VID)
723 && (dev->descriptor.idProduct == PID)) {
724 dev_handle = usb_open(dev);
725 if (NULL == dev_handle) {
726 LOG_ERROR("failed to open %04X:%04X, %s", VID, PID,
727 usb_strerror());
728 continue;
729 }
730
731 /* check description string */
732 if ((productstring != NULL && !usb_check_string(dev_handle,
733 dev->descriptor.iProduct, productstring, NULL, 0))
734 || (serialstring != NULL && !usb_check_string(dev_handle,
735 dev->descriptor.iSerialNumber, serialstring, NULL, 0))) {
736 usb_close(dev_handle);
737 dev_handle = NULL;
738 continue;
739 }
740
741 if (usb_claim_interface(dev_handle, interface) != 0) {
742 LOG_ERROR(ERRMSG_FAILURE_OPERATION_MESSAGE,
743 "claim interface", usb_strerror());
744 usb_close(dev_handle);
745 dev_handle = NULL;
746 continue;
747 }
748
749 if (dev_handle != NULL)
750 return dev_handle;
751 }
752 }
753 }
754
755 return dev_handle;
756 }
757
758 static struct vsllink *vsllink_usb_open(void)
759 {
760 usb_init();
761
762 struct usb_dev_handle *dev;
763
764 dev = find_usb_device(versaloon_interface.usb_setting.vid,
765 versaloon_interface.usb_setting.pid,
766 versaloon_interface.usb_setting.interface,
767 versaloon_interface.usb_setting.serialstring, "Versaloon");
768 if (NULL == dev)
769 return NULL;
770
771 struct vsllink *result = malloc(sizeof(struct vsllink));
772 result->usb_handle = dev;
773 return result;
774 }
775
776 static void vsllink_usb_close(struct vsllink *vsllink)
777 {
778 int ret;
779
780 ret = usb_release_interface(vsllink->usb_handle,
781 versaloon_interface.usb_setting.interface);
782 if (ret != 0) {
783 LOG_ERROR("fail to release interface %d, %d returned",
784 versaloon_interface.usb_setting.interface, ret);
785 exit(-1);
786 }
787
788 ret = usb_close(vsllink->usb_handle);
789 if (ret != 0) {
790 LOG_ERROR("fail to close usb, %d returned", ret);
791 exit(-1);
792 }
793
794 free(vsllink);
795 }
796
797 #define BYTES_PER_LINE 16
798
799 #if defined _DEBUG_JTAG_IO_
800 static void vsllink_debug_buffer(uint8_t *buffer, int length)
801 {
802 char line[81];
803 char s[4];
804 int i;
805 int j;
806
807 for (i = 0; i < length; i += BYTES_PER_LINE) {
808 snprintf(line, 5, "%04x", i);
809 for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
810 snprintf(s, 4, " %02x", buffer[j]);
811 strcat(line, s);
812 }
813 LOG_DEBUG("%s", line);
814 }
815 }
816 #endif /* _DEBUG_JTAG_IO_ */
817
818 static const struct command_registration vsllink_command_handlers[] = {
819 {
820 .name = "vsllink_usb_vid",
821 .handler = &vsllink_handle_usb_vid_command,
822 .mode = COMMAND_CONFIG,
823 },
824 {
825 .name = "vsllink_usb_pid",
826 .handler = &vsllink_handle_usb_pid_command,
827 .mode = COMMAND_CONFIG,
828 },
829 {
830 .name = "vsllink_usb_serial",
831 .handler = &vsllink_handle_usb_serial_command,
832 .mode = COMMAND_CONFIG,
833 },
834 {
835 .name = "vsllink_usb_bulkin",
836 .handler = &vsllink_handle_usb_bulkin_command,
837 .mode = COMMAND_CONFIG,
838 },
839 {
840 .name = "vsllink_usb_bulkout",
841 .handler = &vsllink_handle_usb_bulkout_command,
842 .mode = COMMAND_CONFIG,
843 },
844 {
845 .name = "vsllink_usb_interface",
846 .handler = &vsllink_handle_usb_interface_command,
847 .mode = COMMAND_CONFIG,
848 },
849 COMMAND_REGISTRATION_DONE
850 };
851
852 static const char *vsllink_transports[] = {"jtag", "swd", NULL};
853
854 struct jtag_interface vsllink_interface = {
855 .name = "vsllink",
856 .supported = DEBUG_CAP_TMS_SEQ,
857 .commands = vsllink_command_handlers,
858 .transports = vsllink_transports,
859
860 .init = vsllink_init,
861 .quit = vsllink_quit,
862 .khz = vsllink_khz,
863 .speed = vsllink_speed,
864 .speed_div = vsllink_speed_div,
865 .execute_queue = vsllink_execute_queue,
866 };

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)