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
;
100 static int queued_retval
;
102 static struct vsllink
*vsllink_handle
;
104 static int vsllink_execute_queue(void)
106 struct jtag_command
*cmd
= jtag_command_queue
;
111 DEBUG_JTAG_IO("-------------------------------------"
113 "-------------------------------------");
115 while (cmd
!= NULL
) {
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
));
122 vsllink_end_state(cmd
->cmd
.runtest
->end_state
);
123 vsllink_runtest(cmd
->cmd
.runtest
->num_cycles
);
127 DEBUG_JTAG_IO("statemove end in %s",
128 tap_state_name(cmd
->cmd
.statemove
->end_state
));
130 vsllink_end_state(cmd
->cmd
.statemove
->end_state
);
131 vsllink_state_move();
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]));
139 vsllink_path_move(cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
);
143 DEBUG_JTAG_IO("JTAG Scan...");
145 vsllink_end_state(cmd
->cmd
.scan
->end_state
);
147 scan_size
= jtag_build_buffer(
148 cmd
->cmd
.scan
, &buffer
);
150 if (cmd
->cmd
.scan
->ir_scan
)
152 "JTAG Scan write IR(%d bits), "
155 tap_state_name(cmd
->cmd
.scan
->end_state
));
159 "JTAG Scan write DR(%d bits), "
162 tap_state_name(cmd
->cmd
.scan
->end_state
));
164 #ifdef _DEBUG_JTAG_IO_
165 vsllink_debug_buffer(buffer
,
166 DIV_ROUND_UP(scan_size
, 8));
169 type
= jtag_scan_type(cmd
->cmd
.scan
);
171 vsllink_scan(cmd
->cmd
.scan
->ir_scan
,
172 type
, buffer
, scan_size
,
177 DEBUG_JTAG_IO("reset trst: %i srst %i",
178 cmd
->cmd
.reset
->trst
,
179 cmd
->cmd
.reset
->srst
);
181 vsllink_tap_execute();
183 if (cmd
->cmd
.reset
->trst
== 1)
184 tap_set_state(TAP_RESET
);
186 vsllink_reset(cmd
->cmd
.reset
->trst
,
187 cmd
->cmd
.reset
->srst
);
191 DEBUG_JTAG_IO("sleep %i", cmd
->cmd
.sleep
->us
);
192 vsllink_tap_execute();
193 jtag_sleep(cmd
->cmd
.sleep
->us
);
196 case JTAG_STABLECLOCKS
:
197 DEBUG_JTAG_IO("add %d clocks",
198 cmd
->cmd
.stableclocks
->num_cycles
);
200 switch (tap_get_state()) {
202 /* tms must be '1' to stay
212 /* else, tms should be '0' */
215 /* above stable states are OK */
217 LOG_ERROR("jtag_add_clocks() "
218 "in non-stable state \"%s\"",
219 tap_state_name(tap_get_state())
223 vsllink_stableclocks(cmd
->cmd
.stableclocks
->num_cycles
, scan_size
);
227 DEBUG_JTAG_IO("add %d jtag tms",
228 cmd
->cmd
.tms
->num_bits
);
230 vsllink_tms(cmd
->cmd
.tms
->num_bits
, cmd
->cmd
.tms
->bits
);
234 LOG_ERROR("BUG: unknown JTAG command type "
235 "encountered: %d", cmd
->type
);
241 return vsllink_tap_execute();
244 static int vsllink_speed(int speed
)
249 versaloon_interface
.adaptors
.jtag_raw
.config(0, (uint16_t)speed
);
250 return versaloon_interface
.adaptors
.peripheral_commit();
253 static int vsllink_khz(int khz
, int *jtag_speed
)
260 static int vsllink_speed_div(int jtag_speed
, int *khz
)
267 static void vsllink_free_buffer(void)
269 if (tdi_buffer
!= NULL
) {
273 if (tdo_buffer
!= NULL
) {
277 if (tms_buffer
!= NULL
) {
283 static int vsllink_quit(void)
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);
290 versaloon_interface
.adaptors
.swd
.fini(0);
292 versaloon_interface
.adaptors
.jtag_raw
.fini(0);
294 versaloon_interface
.adaptors
.peripheral_commit();
295 versaloon_interface
.fini();
297 vsllink_free_buffer();
298 vsllink_usb_close(vsllink_handle
);
300 free(vsllink_handle
);
305 static int vsllink_interface_init(void)
307 vsllink_handle
= malloc(sizeof(struct vsllink
));
308 if (NULL
== vsllink_handle
) {
309 LOG_ERROR("unable to allocate memory");
313 libusb_init(&vsllink_handle
->libusb_ctx
);
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
;
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
;
325 if (ERROR_OK
!= versaloon_interface
.init())
327 if (versaloon_interface
.usb_setting
.buf_size
< 32) {
328 versaloon_interface
.fini();
335 static int vsllink_init(void)
337 int retval
= vsllink_interface_init();
338 if (ERROR_OK
!= retval
)
341 versaloon_interface
.adaptors
.gpio
.init(0);
342 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
, 0, GPIO_SRST
,
344 versaloon_interface
.adaptors
.delay
.delayms(100);
345 versaloon_interface
.adaptors
.peripheral_commit();
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
);
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
)) {
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
);
372 if (ERROR_OK
!= versaloon_interface
.adaptors
.peripheral_commit())
380 /**************************************************************************
381 * Queue command implementations */
383 static void vsllink_end_state(tap_state_t state
)
385 if (tap_is_state_stable(state
))
386 tap_set_end_state(state
);
388 LOG_ERROR("BUG: %i is not a valid end state", state
);
393 /* Goes to the end state. */
394 static void vsllink_state_move(void)
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());
402 for (i
= 0; i
< tms_scan_bits
; i
++)
403 vsllink_tap_append_step((tms_scan
>> i
) & 1, 0);
405 tap_set_state(tap_get_end_state());
408 static void vsllink_path_move(int num_states
, tap_state_t
*path
)
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);
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
]));
422 tap_set_state(path
[i
]);
425 tap_set_end_state(tap_get_state());
428 static void vsllink_tms(int num_bits
, const uint8_t *bits
)
430 for (int i
= 0; i
< num_bits
; i
++)
431 vsllink_tap_append_step((bits
[i
/ 8] >> (i
% 8)) & 1, 0);
434 static void vsllink_stableclocks(int num_cycles
, int tms
)
436 while (num_cycles
> 0) {
437 vsllink_tap_append_step(tms
, 0);
442 static void vsllink_runtest(int num_cycles
)
444 tap_state_t saved_end_state
= tap_get_end_state();
446 if (tap_get_state() != TAP_IDLE
) {
447 /* enter IDLE state */
448 vsllink_end_state(TAP_IDLE
);
449 vsllink_state_move();
452 vsllink_stableclocks(num_cycles
, 0);
456 vsllink_end_state(saved_end_state
);
457 if (tap_get_end_state() != tap_get_end_state())
458 vsllink_state_move();
461 static void vsllink_scan(bool ir_scan
, enum scan_type type
, uint8_t *buffer
,
462 int scan_size
, struct scan_command
*command
)
464 tap_state_t saved_end_state
;
466 saved_end_state
= tap_get_end_state();
468 /* Move to appropriate scan state */
469 vsllink_end_state(ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
471 if (tap_get_state() != tap_get_end_state())
472 vsllink_state_move();
473 vsllink_end_state(saved_end_state
);
476 vsllink_tap_append_scan(scan_size
, buffer
, command
);
478 /* Goto Pause and record position to insert tms:0 */
479 vsllink_tap_append_step(0, 0);
480 vsllink_tms_offset
= tap_length
;
482 tap_set_state(ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
484 if (tap_get_state() != tap_get_end_state())
485 vsllink_state_move();
488 static void vsllink_reset(int trst
, int srst
)
490 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
493 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
, 0, GPIO_SRST
, GPIO_SRST
);
495 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
, GPIO_SRST
, 0, 0);
499 versaloon_interface
.adaptors
.gpio
.out(0, GPIO_TRST
, GPIO_TRST
);
501 versaloon_interface
.adaptors
.gpio
.out(0, GPIO_TRST
, 0);
504 versaloon_interface
.adaptors
.peripheral_commit();
507 COMMAND_HANDLER(vsllink_handle_usb_vid_command
)
510 return ERROR_COMMAND_SYNTAX_ERROR
;
512 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0],
513 versaloon_interface
.usb_setting
.vid
);
517 COMMAND_HANDLER(vsllink_handle_usb_pid_command
)
520 return ERROR_COMMAND_SYNTAX_ERROR
;
521 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0],
522 versaloon_interface
.usb_setting
.pid
);
526 COMMAND_HANDLER(vsllink_handle_usb_serial_command
)
529 return ERROR_COMMAND_SYNTAX_ERROR
;
531 free(versaloon_interface
.usb_setting
.serialstring
);
534 versaloon_interface
.usb_setting
.serialstring
= strdup(CMD_ARGV
[0]);
536 versaloon_interface
.usb_setting
.serialstring
= NULL
;
541 COMMAND_HANDLER(vsllink_handle_usb_bulkin_command
)
544 return ERROR_COMMAND_SYNTAX_ERROR
;
546 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
547 versaloon_interface
.usb_setting
.ep_in
);
549 versaloon_interface
.usb_setting
.ep_in
|= 0x80;
554 COMMAND_HANDLER(vsllink_handle_usb_bulkout_command
)
557 return ERROR_COMMAND_SYNTAX_ERROR
;
559 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
560 versaloon_interface
.usb_setting
.ep_out
);
562 versaloon_interface
.usb_setting
.ep_out
&= ~0x80;
567 COMMAND_HANDLER(vsllink_handle_usb_interface_command
)
570 return ERROR_COMMAND_SYNTAX_ERROR
;
572 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
573 versaloon_interface
.usb_setting
.interface
);
577 /**************************************************************************
578 * VSLLink tap functions */
580 static void vsllink_tap_init(void)
583 pending_scan_results_length
= 0;
584 vsllink_tms_offset
= 0;
587 static void vsllink_tap_ensure_pending(int scans
)
589 int available_scans
=
590 MAX_PENDING_SCAN_RESULTS
- pending_scan_results_length
;
592 if (scans
> available_scans
)
593 vsllink_tap_execute();
596 static void vsllink_tap_append_step(int tms
, int tdi
)
598 int index_var
= tap_length
/ 8;
600 int bit_index
= tap_length
% 8;
601 uint8_t bit
= 1 << bit_index
;
604 tms_buffer
[index_var
] |= bit
;
606 tms_buffer
[index_var
] &= ~bit
;
609 tdi_buffer
[index_var
] |= bit
;
611 tdi_buffer
[index_var
] &= ~bit
;
615 if (tap_buffer_size
* 8 <= tap_length
)
616 vsllink_tap_execute();
619 static void vsllink_tap_append_scan(int length
, uint8_t *buffer
,
620 struct scan_command
*command
)
622 struct pending_scan_result
*pending_scan_result
;
623 int len_tmp
, len_all
, i
;
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
];
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;
638 len_tmp
= length
- len_all
;
639 pending_scan_result
->last
= true;
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
++;
648 for (i
= 0; i
< len_tmp
; i
++) {
649 vsllink_tap_append_step(((len_all
+ i
) < length
-1
651 (buffer
[(len_all
+ i
)/8]
652 >> ((len_all
+ i
)%8)) & 1);
659 static int vsllink_jtag_execute(void)
667 versaloon_interface
.adaptors
.jtag_raw
.execute(0, tdi_buffer
, tms_buffer
,
668 tdo_buffer
, tap_length
);
670 result
= versaloon_interface
.adaptors
.peripheral_commit();
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
;
682 struct scan_command
*command
;
684 command
= pending_scan_result
->command
;
685 buf_set_buf(tdo_buffer
, src_first
, buffer
, dest_first
, length
);
687 #ifdef _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));
696 if (jtag_read_buffer(buffer
, command
)
699 return ERROR_JTAG_QUEUE_FAILED
;
702 if (pending_scan_result
->buffer
!= NULL
)
703 free(pending_scan_result
->buffer
);
707 LOG_ERROR("vsllink_jtag_execute failure");
708 return ERROR_JTAG_QUEUE_FAILED
;
716 static int vsllink_tap_execute(void)
721 return vsllink_jtag_execute();
724 static int vsllink_swd_init(void)
726 LOG_INFO("VSLLink SWD mode enabled");
732 static int_least32_t vsllink_swd_frequency(struct adiv5_dap
*dap
,
735 const int_least32_t delay2hz
[] = {
736 1850000, 235000, 130000, 102000, 85000, 72000
740 uint16_t delay
= UINT16_MAX
;
742 for (uint16_t i
= 0; i
< ARRAY_SIZE(delay2hz
); i
++) {
743 if (hz
>= delay2hz
[i
]) {
750 if (delay
== UINT16_MAX
)
751 delay
= (500000 / hz
) - 1;
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;
758 LOG_DEBUG("SWD delay: %d, retry count: %d", delay
, retry_count
);
760 versaloon_interface
.adaptors
.swd
.config(0, 2, retry_count
, delay
);
761 queued_retval
= versaloon_interface
.adaptors
.peripheral_commit();
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
);
791 return versaloon_interface
.adaptors
.peripheral_commit();
794 static void vsllink_swd_read_reg(struct adiv5_dap
*dap
, uint8_t cmd
,
797 if (queued_retval
!= ERROR_OK
)
804 versaloon_interface
.adaptors
.swd
.transact(0, cmd
, &val
, &ack
);
805 retval
= versaloon_interface
.adaptors
.peripheral_commit();
807 if (retval
!= ERROR_OK
) {
808 queued_retval
= ERROR_FAIL
;
820 queued_retval
= retval
;
823 static void vsllink_swd_write_reg(struct adiv5_dap
*dap
, uint8_t cmd
,
826 if (queued_retval
!= ERROR_OK
)
832 versaloon_interface
.adaptors
.swd
.transact(0, cmd
, &value
, &ack
);
833 retval
= versaloon_interface
.adaptors
.peripheral_commit();
835 if (retval
!= ERROR_OK
) {
836 queued_retval
= ERROR_FAIL
;
845 queued_retval
= retval
;
848 static int vsllink_swd_run_queue(struct adiv5_dap
*dap
)
850 int retval
= queued_retval
;
851 queued_retval
= ERROR_OK
;
855 /****************************************************************************
856 * VSLLink USB low-level functions */
858 static int vsllink_check_usb_strings(
859 struct libusb_device_handle
*usb_device_handle
,
860 struct libusb_device_descriptor
*usb_desc
)
862 char desc_string
[256];
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
));
872 if (strncmp(desc_string
, versaloon_interface
.usb_setting
.serialstring
,
873 sizeof(desc_string
)))
877 retval
= libusb_get_string_descriptor_ascii(usb_device_handle
,
878 usb_desc
->iProduct
, (unsigned char *)desc_string
,
879 sizeof(desc_string
));
883 if (strstr(desc_string
, "Versaloon") == NULL
)
889 static int vsllink_usb_open(struct vsllink
*vsllink
)
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
;
897 num_devices
= libusb_get_device_list(vsllink
->libusb_ctx
, &usb_devices
);
899 if (num_devices
<= 0)
902 for (i
= 0; i
< num_devices
; i
++) {
903 libusb_device
*device
= usb_devices
[i
];
905 retval
= libusb_get_device_descriptor(device
, &usb_desc
);
909 if (usb_desc
.idVendor
!= versaloon_interface
.usb_setting
.vid
||
910 usb_desc
.idProduct
!= versaloon_interface
.usb_setting
.pid
)
913 retval
= libusb_open(device
, &usb_device_handle
);
917 retval
= vsllink_check_usb_strings(usb_device_handle
, &usb_desc
);
918 if (ERROR_OK
== retval
)
921 libusb_close(usb_device_handle
);
924 libusb_free_device_list(usb_devices
, 1);
926 if (i
== num_devices
)
929 retval
= libusb_claim_interface(usb_device_handle
,
930 versaloon_interface
.usb_setting
.interface
);
932 LOG_ERROR("unable to claim interface");
933 libusb_close(usb_device_handle
);
937 vsllink
->usb_device_handle
= usb_device_handle
;
941 static void vsllink_usb_close(struct vsllink
*vsllink
)
943 libusb_release_interface(vsllink
->usb_device_handle
,
944 versaloon_interface
.usb_setting
.interface
);
945 libusb_close(vsllink
->usb_device_handle
);
948 #define BYTES_PER_LINE 16
950 #if defined _DEBUG_JTAG_IO_
951 static void vsllink_debug_buffer(uint8_t *buffer
, int length
)
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
]);
964 LOG_DEBUG("%s", line
);
967 #endif /* _DEBUG_JTAG_IO_ */
969 static const struct command_registration vsllink_command_handlers
[] = {
971 .name
= "vsllink_usb_vid",
972 .handler
= &vsllink_handle_usb_vid_command
,
973 .mode
= COMMAND_CONFIG
,
976 .name
= "vsllink_usb_pid",
977 .handler
= &vsllink_handle_usb_pid_command
,
978 .mode
= COMMAND_CONFIG
,
981 .name
= "vsllink_usb_serial",
982 .handler
= &vsllink_handle_usb_serial_command
,
983 .mode
= COMMAND_CONFIG
,
986 .name
= "vsllink_usb_bulkin",
987 .handler
= &vsllink_handle_usb_bulkin_command
,
988 .mode
= COMMAND_CONFIG
,
991 .name
= "vsllink_usb_bulkout",
992 .handler
= &vsllink_handle_usb_bulkout_command
,
993 .mode
= COMMAND_CONFIG
,
996 .name
= "vsllink_usb_interface",
997 .handler
= &vsllink_handle_usb_interface_command
,
998 .mode
= COMMAND_CONFIG
,
1000 COMMAND_REGISTRATION_DONE
1003 static const char * const vsllink_transports
[] = {"jtag", "swd", NULL
};
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
,
1014 struct jtag_interface vsllink_interface
= {
1016 .supported
= DEBUG_CAP_TMS_SEQ
,
1017 .commands
= vsllink_command_handlers
,
1018 .transports
= vsllink_transports
,
1019 .swd
= &vsllink_swd_driver
,
1021 .init
= vsllink_init
,
1022 .quit
= vsllink_quit
,
1024 .speed
= vsllink_speed
,
1025 .speed_div
= vsllink_speed_div
,
1026 .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)