1 /***************************************************************************
2 * Copyright (C) 2009-2010 by Simon Qian <SimonQian@SimonQian.com> *
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. *
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. *
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 ***************************************************************************/
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/.
29 #include <jtag/interface.h>
30 #include <jtag/commands.h>
34 #include "versaloon/versaloon_include.h"
35 #include "versaloon/versaloon.h"
37 static int vsllink_tms_offset
;
39 struct pending_scan_result
{
42 int length
; /* Number of bits to read */
43 struct scan_command
*command
; /* Corresponding scan command */
46 bool last
; /* indicate the last scan pending */
49 #define MAX_PENDING_SCAN_RESULTS 256
51 static int pending_scan_results_length
;
52 static struct pending_scan_result
53 pending_scan_results_buffer
[MAX_PENDING_SCAN_RESULTS
];
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
);
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
);
74 /* VSLLink SWD functions */
75 static int_least32_t vsllink_swd_frequency(struct adiv5_dap
*dap
,
77 static int vsllink_swd_switch_seq(struct adiv5_dap
*dap
,
78 enum swd_special_seq seq
);
80 /* VSLLink lowlevel functions */
82 struct libusb_context
*libusb_ctx
;
83 struct libusb_device_handle
*usb_device_handle
;
86 static int vsllink_usb_open(struct vsllink
*vsllink
);
87 static void vsllink_usb_close(struct vsllink
*vsllink
);
89 #if defined _DEBUG_JTAG_IO_
90 static void vsllink_debug_buffer(uint8_t *buffer
, int length
);
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
;
101 static struct vsllink
*vsllink_handle
;
103 static int vsllink_execute_queue(void)
105 struct jtag_command
*cmd
= jtag_command_queue
;
110 DEBUG_JTAG_IO("-------------------------------------"
112 "-------------------------------------");
114 while (cmd
!= NULL
) {
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
));
121 vsllink_end_state(cmd
->cmd
.runtest
->end_state
);
122 vsllink_runtest(cmd
->cmd
.runtest
->num_cycles
);
126 DEBUG_JTAG_IO("statemove end in %s",
127 tap_state_name(cmd
->cmd
.statemove
->end_state
));
129 vsllink_end_state(cmd
->cmd
.statemove
->end_state
);
130 vsllink_state_move();
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]));
138 vsllink_path_move(cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
);
142 DEBUG_JTAG_IO("JTAG Scan...");
144 vsllink_end_state(cmd
->cmd
.scan
->end_state
);
146 scan_size
= jtag_build_buffer(
147 cmd
->cmd
.scan
, &buffer
);
149 if (cmd
->cmd
.scan
->ir_scan
)
151 "JTAG Scan write IR(%d bits), "
154 tap_state_name(cmd
->cmd
.scan
->end_state
));
158 "JTAG Scan write DR(%d bits), "
161 tap_state_name(cmd
->cmd
.scan
->end_state
));
163 #ifdef _DEBUG_JTAG_IO_
164 vsllink_debug_buffer(buffer
,
165 DIV_ROUND_UP(scan_size
, 8));
168 type
= jtag_scan_type(cmd
->cmd
.scan
);
170 vsllink_scan(cmd
->cmd
.scan
->ir_scan
,
171 type
, buffer
, scan_size
,
176 DEBUG_JTAG_IO("reset trst: %i srst %i",
177 cmd
->cmd
.reset
->trst
,
178 cmd
->cmd
.reset
->srst
);
180 vsllink_tap_execute();
182 if (cmd
->cmd
.reset
->trst
== 1)
183 tap_set_state(TAP_RESET
);
185 vsllink_reset(cmd
->cmd
.reset
->trst
,
186 cmd
->cmd
.reset
->srst
);
190 DEBUG_JTAG_IO("sleep %i", cmd
->cmd
.sleep
->us
);
191 vsllink_tap_execute();
192 jtag_sleep(cmd
->cmd
.sleep
->us
);
195 case JTAG_STABLECLOCKS
:
196 DEBUG_JTAG_IO("add %d clocks",
197 cmd
->cmd
.stableclocks
->num_cycles
);
199 switch (tap_get_state()) {
201 /* tms must be '1' to stay
211 /* else, tms should be '0' */
214 /* above stable states are OK */
216 LOG_ERROR("jtag_add_clocks() "
217 "in non-stable state \"%s\"",
218 tap_state_name(tap_get_state())
222 vsllink_stableclocks(cmd
->cmd
.stableclocks
->num_cycles
, scan_size
);
226 DEBUG_JTAG_IO("add %d jtag tms",
227 cmd
->cmd
.tms
->num_bits
);
229 vsllink_tms(cmd
->cmd
.tms
->num_bits
, cmd
->cmd
.tms
->bits
);
233 LOG_ERROR("BUG: unknown JTAG command type "
234 "encountered: %d", cmd
->type
);
240 return vsllink_tap_execute();
243 static int vsllink_speed(int speed
)
246 vsllink_swd_frequency(NULL
, speed
* 1000);
250 versaloon_interface
.adaptors
.jtag_raw
.config(0, (uint16_t)speed
);
251 return versaloon_interface
.adaptors
.peripheral_commit();
254 static int vsllink_khz(int khz
, int *jtag_speed
)
261 static int vsllink_speed_div(int jtag_speed
, int *khz
)
268 static void vsllink_free_buffer(void)
270 if (tdi_buffer
!= NULL
) {
274 if (tdo_buffer
!= NULL
) {
278 if (tms_buffer
!= NULL
) {
284 static int vsllink_quit(void)
286 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
| GPIO_TRST
,
287 0, 0, GPIO_SRST
| GPIO_TRST
);
288 versaloon_interface
.adaptors
.gpio
.fini(0);
291 versaloon_interface
.adaptors
.swd
.fini(0);
293 versaloon_interface
.adaptors
.jtag_raw
.fini(0);
295 versaloon_interface
.adaptors
.peripheral_commit();
296 versaloon_interface
.fini();
298 vsllink_free_buffer();
299 vsllink_usb_close(vsllink_handle
);
301 free(vsllink_handle
);
306 static int vsllink_interface_init(void)
308 vsllink_handle
= malloc(sizeof(struct vsllink
));
309 if (NULL
== vsllink_handle
) {
310 LOG_ERROR("unable to allocate memory");
314 libusb_init(&vsllink_handle
->libusb_ctx
);
316 if (ERROR_OK
!= vsllink_usb_open(vsllink_handle
)) {
317 LOG_ERROR("Can't find USB JTAG Interface!" \
318 "Please check connection and permissions.");
319 return ERROR_JTAG_INIT_FAILED
;
321 LOG_DEBUG("vsllink found on %04X:%04X",
322 versaloon_interface
.usb_setting
.vid
,
323 versaloon_interface
.usb_setting
.pid
);
324 versaloon_usb_device_handle
= vsllink_handle
->usb_device_handle
;
326 if (ERROR_OK
!= versaloon_interface
.init())
328 if (versaloon_interface
.usb_setting
.buf_size
< 32) {
329 versaloon_interface
.fini();
336 static int vsllink_init(void)
338 int retval
= vsllink_interface_init();
339 if (ERROR_OK
!= retval
)
342 versaloon_interface
.adaptors
.gpio
.init(0);
343 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
, 0, GPIO_SRST
,
345 versaloon_interface
.adaptors
.delay
.delayms(100);
346 versaloon_interface
.adaptors
.peripheral_commit();
349 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_TRST
, 0,
350 GPIO_TRST
, GPIO_TRST
);
351 versaloon_interface
.adaptors
.swd
.init(0);
352 vsllink_swd_frequency(NULL
, jtag_get_speed_khz() * 1000);
353 vsllink_swd_switch_seq(NULL
, JTAG_TO_SWD
);
356 /* malloc buffer size for tap */
357 tap_buffer_size
= versaloon_interface
.usb_setting
.buf_size
/ 2 - 32;
358 vsllink_free_buffer();
359 tdi_buffer
= malloc(tap_buffer_size
);
360 tdo_buffer
= malloc(tap_buffer_size
);
361 tms_buffer
= malloc(tap_buffer_size
);
362 if ((NULL
== tdi_buffer
) || (NULL
== tdo_buffer
) || (NULL
== tms_buffer
)) {
367 versaloon_interface
.adaptors
.jtag_raw
.init(0);
368 versaloon_interface
.adaptors
.jtag_raw
.config(0, jtag_get_speed_khz());
369 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
| GPIO_TRST
,
370 GPIO_TRST
, GPIO_SRST
, GPIO_SRST
);
373 if (ERROR_OK
!= versaloon_interface
.adaptors
.peripheral_commit())
381 /**************************************************************************
382 * Queue command implementations */
384 static void vsllink_end_state(tap_state_t state
)
386 if (tap_is_state_stable(state
))
387 tap_set_end_state(state
);
389 LOG_ERROR("BUG: %i is not a valid end state", state
);
394 /* Goes to the end state. */
395 static void vsllink_state_move(void)
398 uint8_t tms_scan
= tap_get_tms_path(tap_get_state(),
399 tap_get_end_state());
400 uint8_t tms_scan_bits
= tap_get_tms_path_len(tap_get_state(),
401 tap_get_end_state());
403 for (i
= 0; i
< tms_scan_bits
; i
++)
404 vsllink_tap_append_step((tms_scan
>> i
) & 1, 0);
406 tap_set_state(tap_get_end_state());
409 static void vsllink_path_move(int num_states
, tap_state_t
*path
)
411 for (int i
= 0; i
< num_states
; i
++) {
412 if (path
[i
] == tap_state_transition(tap_get_state(), false))
413 vsllink_tap_append_step(0, 0);
414 else if (path
[i
] == tap_state_transition(tap_get_state(), true))
415 vsllink_tap_append_step(1, 0);
417 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
418 tap_state_name(tap_get_state()),
419 tap_state_name(path
[i
]));
423 tap_set_state(path
[i
]);
426 tap_set_end_state(tap_get_state());
429 static void vsllink_tms(int num_bits
, const uint8_t *bits
)
431 for (int i
= 0; i
< num_bits
; i
++)
432 vsllink_tap_append_step((bits
[i
/ 8] >> (i
% 8)) & 1, 0);
435 static void vsllink_stableclocks(int num_cycles
, int tms
)
437 while (num_cycles
> 0) {
438 vsllink_tap_append_step(tms
, 0);
443 static void vsllink_runtest(int num_cycles
)
445 tap_state_t saved_end_state
= tap_get_end_state();
447 if (tap_get_state() != TAP_IDLE
) {
448 /* enter IDLE state */
449 vsllink_end_state(TAP_IDLE
);
450 vsllink_state_move();
453 vsllink_stableclocks(num_cycles
, 0);
457 vsllink_end_state(saved_end_state
);
458 if (tap_get_end_state() != tap_get_end_state())
459 vsllink_state_move();
462 static void vsllink_scan(bool ir_scan
, enum scan_type type
, uint8_t *buffer
,
463 int scan_size
, struct scan_command
*command
)
465 tap_state_t saved_end_state
;
467 saved_end_state
= tap_get_end_state();
469 /* Move to appropriate scan state */
470 vsllink_end_state(ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
472 if (tap_get_state() != tap_get_end_state())
473 vsllink_state_move();
474 vsllink_end_state(saved_end_state
);
477 vsllink_tap_append_scan(scan_size
, buffer
, command
);
479 /* Goto Pause and record position to insert tms:0 */
480 vsllink_tap_append_step(0, 0);
481 vsllink_tms_offset
= tap_length
;
483 tap_set_state(ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
485 if (tap_get_state() != tap_get_end_state())
486 vsllink_state_move();
489 static void vsllink_reset(int trst
, int srst
)
491 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
494 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
, 0, GPIO_SRST
, GPIO_SRST
);
496 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
, GPIO_SRST
, 0, 0);
500 versaloon_interface
.adaptors
.gpio
.out(0, GPIO_TRST
, GPIO_TRST
);
502 versaloon_interface
.adaptors
.gpio
.out(0, GPIO_TRST
, 0);
505 versaloon_interface
.adaptors
.peripheral_commit();
508 COMMAND_HANDLER(vsllink_handle_usb_vid_command
)
511 return ERROR_COMMAND_SYNTAX_ERROR
;
513 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0],
514 versaloon_interface
.usb_setting
.vid
);
518 COMMAND_HANDLER(vsllink_handle_usb_pid_command
)
521 return ERROR_COMMAND_SYNTAX_ERROR
;
522 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0],
523 versaloon_interface
.usb_setting
.pid
);
527 COMMAND_HANDLER(vsllink_handle_usb_serial_command
)
530 return ERROR_COMMAND_SYNTAX_ERROR
;
532 free(versaloon_interface
.usb_setting
.serialstring
);
535 versaloon_interface
.usb_setting
.serialstring
= strdup(CMD_ARGV
[0]);
537 versaloon_interface
.usb_setting
.serialstring
= NULL
;
542 COMMAND_HANDLER(vsllink_handle_usb_bulkin_command
)
545 return ERROR_COMMAND_SYNTAX_ERROR
;
547 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
548 versaloon_interface
.usb_setting
.ep_in
);
550 versaloon_interface
.usb_setting
.ep_in
|= 0x80;
555 COMMAND_HANDLER(vsllink_handle_usb_bulkout_command
)
558 return ERROR_COMMAND_SYNTAX_ERROR
;
560 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
561 versaloon_interface
.usb_setting
.ep_out
);
563 versaloon_interface
.usb_setting
.ep_out
&= ~0x80;
568 COMMAND_HANDLER(vsllink_handle_usb_interface_command
)
571 return ERROR_COMMAND_SYNTAX_ERROR
;
573 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
574 versaloon_interface
.usb_setting
.interface
);
578 /**************************************************************************
579 * VSLLink tap functions */
581 static void vsllink_tap_init(void)
584 pending_scan_results_length
= 0;
585 vsllink_tms_offset
= 0;
588 static void vsllink_tap_ensure_pending(int scans
)
590 int available_scans
=
591 MAX_PENDING_SCAN_RESULTS
- pending_scan_results_length
;
593 if (scans
> available_scans
)
594 vsllink_tap_execute();
597 static void vsllink_tap_append_step(int tms
, int tdi
)
599 int index_var
= tap_length
/ 8;
601 int bit_index
= tap_length
% 8;
602 uint8_t bit
= 1 << bit_index
;
605 tms_buffer
[index_var
] |= bit
;
607 tms_buffer
[index_var
] &= ~bit
;
610 tdi_buffer
[index_var
] |= bit
;
612 tdi_buffer
[index_var
] &= ~bit
;
616 if (tap_buffer_size
* 8 <= tap_length
)
617 vsllink_tap_execute();
620 static void vsllink_tap_append_scan(int length
, uint8_t *buffer
,
621 struct scan_command
*command
)
623 struct pending_scan_result
*pending_scan_result
;
624 int len_tmp
, len_all
, i
;
627 while (len_all
< length
) {
628 vsllink_tap_ensure_pending(1);
629 pending_scan_result
=
630 &pending_scan_results_buffer
[
631 pending_scan_results_length
];
633 if ((length
- len_all
) > (tap_buffer_size
* 8 - tap_length
)) {
634 /* Use all memory available
635 vsllink_tap_append_step will commit automatically */
636 len_tmp
= tap_buffer_size
* 8 - tap_length
;
637 pending_scan_result
->last
= false;
639 len_tmp
= length
- len_all
;
640 pending_scan_result
->last
= true;
642 pending_scan_result
->src_offset
= tap_length
;
643 pending_scan_result
->dest_offset
= len_all
;
644 pending_scan_result
->length
= len_tmp
;
645 pending_scan_result
->command
= command
;
646 pending_scan_result
->buffer
= buffer
;
647 pending_scan_results_length
++;
649 for (i
= 0; i
< len_tmp
; i
++) {
650 vsllink_tap_append_step(((len_all
+ i
) < length
-1
652 (buffer
[(len_all
+ i
)/8]
653 >> ((len_all
+ i
)%8)) & 1);
660 static int vsllink_jtag_execute(void)
668 versaloon_interface
.adaptors
.jtag_raw
.execute(0, tdi_buffer
, tms_buffer
,
669 tdo_buffer
, tap_length
);
671 result
= versaloon_interface
.adaptors
.peripheral_commit();
673 if (result
== ERROR_OK
) {
674 for (i
= 0; i
< pending_scan_results_length
; i
++) {
675 struct pending_scan_result
*pending_scan_result
=
676 &pending_scan_results_buffer
[i
];
677 uint8_t *buffer
= pending_scan_result
->buffer
;
678 int length
= pending_scan_result
->length
;
679 int src_first
= pending_scan_result
->src_offset
;
680 int dest_first
= pending_scan_result
->dest_offset
;
681 bool last
= pending_scan_result
->last
;
683 struct scan_command
*command
;
685 command
= pending_scan_result
->command
;
686 buf_set_buf(tdo_buffer
, src_first
, buffer
, dest_first
, length
);
688 #ifdef _DEBUG_JTAG_IO_
690 "JTAG scan read(%d bits, from src %d bits to dest %d bits):",
691 length
, src_first
, dest_first
);
692 vsllink_debug_buffer(buffer
+ dest_first
/ 8,
693 DIV_ROUND_UP(length
, 7));
697 if (jtag_read_buffer(buffer
, command
)
700 return ERROR_JTAG_QUEUE_FAILED
;
703 if (pending_scan_result
->buffer
!= NULL
)
704 free(pending_scan_result
->buffer
);
708 LOG_ERROR("vsllink_jtag_execute failure");
709 return ERROR_JTAG_QUEUE_FAILED
;
717 static int vsllink_tap_execute(void)
722 return vsllink_jtag_execute();
725 static int vsllink_swd_init(void)
727 LOG_INFO("VSLLink SWD mode enabled");
733 static int_least32_t vsllink_swd_frequency(struct adiv5_dap
*dap
,
736 const int_least32_t delay2hz
[] = {
737 1850000, 235000, 130000, 102000, 85000, 72000
741 uint16_t delay
= UINT16_MAX
;
743 for (uint16_t i
= 0; i
< ARRAY_SIZE(delay2hz
); i
++) {
744 if (hz
>= delay2hz
[i
]) {
751 if (delay
== UINT16_MAX
)
752 delay
= (500000 / hz
) - 1;
754 /* Calculate retry count after a WAIT response. This will give
755 * a retry timeout at about ~250 ms. 54 is the number of bits
756 * found in a transaction. */
757 uint16_t retry_count
= 250 * hz
/ 1000 / 54;
759 LOG_DEBUG("SWD delay: %d, retry count: %d", delay
, retry_count
);
761 versaloon_interface
.adaptors
.swd
.config(0, 2, retry_count
, delay
);
767 static int vsllink_swd_switch_seq(struct adiv5_dap
*dap
,
768 enum swd_special_seq seq
)
772 LOG_DEBUG("SWD line reset");
773 versaloon_interface
.adaptors
.swd
.seqout(0, swd_seq_line_reset
,
774 swd_seq_line_reset_len
);
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
);
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
);
787 LOG_ERROR("Sequence %d not supported", seq
);
794 static void vsllink_swd_read_reg(struct adiv5_dap
*dap
, uint8_t cmd
,
797 versaloon_interface
.adaptors
.swd
.transact(0, cmd
, value
, NULL
);
800 static void vsllink_swd_write_reg(struct adiv5_dap
*dap
, uint8_t cmd
,
803 versaloon_interface
.adaptors
.swd
.transact(0, cmd
, &value
, NULL
);
806 static int vsllink_swd_run_queue(struct adiv5_dap
*dap
)
808 return versaloon_interface
.adaptors
.peripheral_commit();
811 /****************************************************************************
812 * VSLLink USB low-level functions */
814 static int vsllink_check_usb_strings(
815 struct libusb_device_handle
*usb_device_handle
,
816 struct libusb_device_descriptor
*usb_desc
)
818 char desc_string
[256];
821 if (NULL
!= versaloon_interface
.usb_setting
.serialstring
) {
822 retval
= libusb_get_string_descriptor_ascii(usb_device_handle
,
823 usb_desc
->iSerialNumber
, (unsigned char *)desc_string
,
824 sizeof(desc_string
));
828 if (strncmp(desc_string
, versaloon_interface
.usb_setting
.serialstring
,
829 sizeof(desc_string
)))
833 retval
= libusb_get_string_descriptor_ascii(usb_device_handle
,
834 usb_desc
->iProduct
, (unsigned char *)desc_string
,
835 sizeof(desc_string
));
839 if (strstr(desc_string
, "Versaloon") == NULL
)
845 static int vsllink_usb_open(struct vsllink
*vsllink
)
847 ssize_t num_devices
, i
;
848 libusb_device
**usb_devices
;
849 struct libusb_device_descriptor usb_desc
;
850 struct libusb_device_handle
*usb_device_handle
;
853 num_devices
= libusb_get_device_list(vsllink
->libusb_ctx
, &usb_devices
);
855 if (num_devices
<= 0)
858 for (i
= 0; i
< num_devices
; i
++) {
859 libusb_device
*device
= usb_devices
[i
];
861 retval
= libusb_get_device_descriptor(device
, &usb_desc
);
865 if (usb_desc
.idVendor
!= versaloon_interface
.usb_setting
.vid
||
866 usb_desc
.idProduct
!= versaloon_interface
.usb_setting
.pid
)
869 retval
= libusb_open(device
, &usb_device_handle
);
873 retval
= vsllink_check_usb_strings(usb_device_handle
, &usb_desc
);
874 if (ERROR_OK
== retval
)
877 libusb_close(usb_device_handle
);
880 libusb_free_device_list(usb_devices
, 1);
882 if (i
== num_devices
)
885 retval
= libusb_claim_interface(usb_device_handle
,
886 versaloon_interface
.usb_setting
.interface
);
888 LOG_ERROR("unable to claim interface");
889 libusb_close(usb_device_handle
);
893 vsllink
->usb_device_handle
= usb_device_handle
;
897 static void vsllink_usb_close(struct vsllink
*vsllink
)
899 libusb_release_interface(vsllink
->usb_device_handle
,
900 versaloon_interface
.usb_setting
.interface
);
901 libusb_close(vsllink
->usb_device_handle
);
904 #define BYTES_PER_LINE 16
906 #if defined _DEBUG_JTAG_IO_
907 static void vsllink_debug_buffer(uint8_t *buffer
, int length
)
914 for (i
= 0; i
< length
; i
+= BYTES_PER_LINE
) {
915 snprintf(line
, 5, "%04x", i
);
916 for (j
= i
; j
< i
+ BYTES_PER_LINE
&& j
< length
; j
++) {
917 snprintf(s
, 4, " %02x", buffer
[j
]);
920 LOG_DEBUG("%s", line
);
923 #endif /* _DEBUG_JTAG_IO_ */
925 static const struct command_registration vsllink_command_handlers
[] = {
927 .name
= "vsllink_usb_vid",
928 .handler
= &vsllink_handle_usb_vid_command
,
929 .mode
= COMMAND_CONFIG
,
932 .name
= "vsllink_usb_pid",
933 .handler
= &vsllink_handle_usb_pid_command
,
934 .mode
= COMMAND_CONFIG
,
937 .name
= "vsllink_usb_serial",
938 .handler
= &vsllink_handle_usb_serial_command
,
939 .mode
= COMMAND_CONFIG
,
942 .name
= "vsllink_usb_bulkin",
943 .handler
= &vsllink_handle_usb_bulkin_command
,
944 .mode
= COMMAND_CONFIG
,
947 .name
= "vsllink_usb_bulkout",
948 .handler
= &vsllink_handle_usb_bulkout_command
,
949 .mode
= COMMAND_CONFIG
,
952 .name
= "vsllink_usb_interface",
953 .handler
= &vsllink_handle_usb_interface_command
,
954 .mode
= COMMAND_CONFIG
,
956 COMMAND_REGISTRATION_DONE
959 static const char * const vsllink_transports
[] = {"jtag", "swd", NULL
};
961 static const struct swd_driver vsllink_swd_driver
= {
962 .init
= vsllink_swd_init
,
963 .frequency
= vsllink_swd_frequency
,
964 .switch_seq
= vsllink_swd_switch_seq
,
965 .read_reg
= vsllink_swd_read_reg
,
966 .write_reg
= vsllink_swd_write_reg
,
967 .run
= vsllink_swd_run_queue
,
970 struct jtag_interface vsllink_interface
= {
972 .supported
= DEBUG_CAP_TMS_SEQ
,
973 .commands
= vsllink_command_handlers
,
974 .transports
= vsllink_transports
,
975 .swd
= &vsllink_swd_driver
,
977 .init
= vsllink_init
,
978 .quit
= vsllink_quit
,
980 .speed
= vsllink_speed
,
981 .speed_div
= vsllink_speed_div
,
982 .execute_queue
= vsllink_execute_queue
,
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)