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, see <http://www.gnu.org/licenses/>. *
16 ***************************************************************************/
18 /* Versaloon is a programming tool for multiple MCUs.
19 * It's distributed under GPLv3.
20 * You can find it at http://www.Versaloon.com/.
27 #include <jtag/interface.h>
28 #include <jtag/commands.h>
32 #include "versaloon/versaloon_include.h"
33 #include "versaloon/versaloon.h"
35 static int vsllink_tms_offset
;
37 struct pending_scan_result
{
40 int length
; /* Number of bits to read */
41 struct scan_command
*command
; /* Corresponding scan command */
44 bool last
; /* indicate the last scan pending */
47 #define MAX_PENDING_SCAN_RESULTS 256
49 static int pending_scan_results_length
;
50 static struct pending_scan_result
51 pending_scan_results_buffer
[MAX_PENDING_SCAN_RESULTS
];
53 /* Queue command functions */
54 static void vsllink_end_state(tap_state_t state
);
55 static void vsllink_state_move(void);
56 static void vsllink_path_move(int num_states
, tap_state_t
*path
);
57 static void vsllink_tms(int num_bits
, const uint8_t *bits
);
58 static void vsllink_runtest(int num_cycles
);
59 static void vsllink_stableclocks(int num_cycles
, int tms
);
60 static void vsllink_scan(bool ir_scan
, enum scan_type type
,
61 uint8_t *buffer
, int scan_size
, struct scan_command
*command
);
62 static int vsllink_reset(int trst
, int srst
);
64 /* VSLLink tap buffer functions */
65 static void vsllink_tap_append_step(int tms
, int tdi
);
66 static void vsllink_tap_init(void);
67 static int vsllink_tap_execute(void);
68 static void vsllink_tap_ensure_pending(int scans
);
69 static void vsllink_tap_append_scan(int length
, uint8_t *buffer
,
70 struct scan_command
*command
);
72 /* VSLLink SWD functions */
73 static int_least32_t vsllink_swd_frequency(int_least32_t hz
);
74 static int vsllink_swd_switch_seq(enum swd_special_seq seq
);
76 /* VSLLink lowlevel functions */
78 struct libusb_context
*libusb_ctx
;
79 struct libusb_device_handle
*usb_device_handle
;
82 static int vsllink_usb_open(struct vsllink
*vsllink
);
83 static void vsllink_usb_close(struct vsllink
*vsllink
);
85 static void vsllink_debug_buffer(uint8_t *buffer
, int length
);
87 static int tap_length
;
88 static int tap_buffer_size
;
89 static uint8_t *tms_buffer
;
90 static uint8_t *tdi_buffer
;
91 static uint8_t *tdo_buffer
;
95 static struct vsllink
*vsllink_handle
;
97 static int vsllink_execute_queue(void)
99 struct jtag_command
*cmd
= jtag_command_queue
;
104 LOG_DEBUG_IO("-------------------------------------"
106 "-------------------------------------");
108 while (cmd
!= NULL
) {
111 LOG_DEBUG_IO("runtest %i cycles, end in %s",
112 cmd
->cmd
.runtest
->num_cycles
,
113 tap_state_name(cmd
->cmd
.runtest
->end_state
));
115 vsllink_end_state(cmd
->cmd
.runtest
->end_state
);
116 vsllink_runtest(cmd
->cmd
.runtest
->num_cycles
);
120 LOG_DEBUG_IO("statemove end in %s",
121 tap_state_name(cmd
->cmd
.statemove
->end_state
));
123 vsllink_end_state(cmd
->cmd
.statemove
->end_state
);
124 vsllink_state_move();
128 LOG_DEBUG_IO("pathmove: %i states, end in %s",
129 cmd
->cmd
.pathmove
->num_states
,
130 tap_state_name(cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]));
132 vsllink_path_move(cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
);
136 LOG_DEBUG_IO("JTAG Scan...");
138 vsllink_end_state(cmd
->cmd
.scan
->end_state
);
140 scan_size
= jtag_build_buffer(
141 cmd
->cmd
.scan
, &buffer
);
143 if (cmd
->cmd
.scan
->ir_scan
)
145 "JTAG Scan write IR(%d bits), "
148 tap_state_name(cmd
->cmd
.scan
->end_state
));
152 "JTAG Scan write DR(%d bits), "
155 tap_state_name(cmd
->cmd
.scan
->end_state
));
157 if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO
))
158 vsllink_debug_buffer(buffer
, DIV_ROUND_UP(scan_size
, 8));
160 type
= jtag_scan_type(cmd
->cmd
.scan
);
162 vsllink_scan(cmd
->cmd
.scan
->ir_scan
,
163 type
, buffer
, scan_size
,
168 LOG_DEBUG_IO("sleep %i", cmd
->cmd
.sleep
->us
);
169 vsllink_tap_execute();
170 jtag_sleep(cmd
->cmd
.sleep
->us
);
173 case JTAG_STABLECLOCKS
:
174 LOG_DEBUG_IO("add %d clocks",
175 cmd
->cmd
.stableclocks
->num_cycles
);
177 switch (tap_get_state()) {
179 /* tms must be '1' to stay
189 /* else, tms should be '0' */
192 /* above stable states are OK */
194 LOG_ERROR("jtag_add_clocks() "
195 "in non-stable state \"%s\"",
196 tap_state_name(tap_get_state())
200 vsllink_stableclocks(cmd
->cmd
.stableclocks
->num_cycles
, scan_size
);
204 LOG_DEBUG_IO("add %d jtag tms",
205 cmd
->cmd
.tms
->num_bits
);
207 vsllink_tms(cmd
->cmd
.tms
->num_bits
, cmd
->cmd
.tms
->bits
);
211 LOG_ERROR("BUG: unknown JTAG command type "
212 "encountered: %d", cmd
->type
);
218 return vsllink_tap_execute();
221 static int vsllink_speed(int speed
)
224 vsllink_swd_frequency(speed
* 1000);
228 versaloon_interface
.adaptors
.jtag_raw
.config(0, (uint16_t)speed
);
229 return versaloon_interface
.adaptors
.peripheral_commit();
232 static int vsllink_khz(int khz
, int *jtag_speed
)
239 static int vsllink_speed_div(int jtag_speed
, int *khz
)
246 static void vsllink_free_buffer(void)
248 if (tdi_buffer
!= NULL
) {
252 if (tdo_buffer
!= NULL
) {
256 if (tms_buffer
!= NULL
) {
262 static int vsllink_quit(void)
264 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
| GPIO_TRST
,
265 0, 0, GPIO_SRST
| GPIO_TRST
);
266 versaloon_interface
.adaptors
.gpio
.fini(0);
269 versaloon_interface
.adaptors
.swd
.fini(0);
271 versaloon_interface
.adaptors
.jtag_raw
.fini(0);
273 versaloon_interface
.adaptors
.peripheral_commit();
274 versaloon_interface
.fini();
276 vsllink_free_buffer();
277 vsllink_usb_close(vsllink_handle
);
279 free(vsllink_handle
);
284 static int vsllink_interface_init(void)
286 vsllink_handle
= malloc(sizeof(struct vsllink
));
287 if (NULL
== vsllink_handle
) {
288 LOG_ERROR("unable to allocate memory");
292 libusb_init(&vsllink_handle
->libusb_ctx
);
294 if (ERROR_OK
!= vsllink_usb_open(vsllink_handle
)) {
295 LOG_ERROR("Can't find USB JTAG Interface!" \
296 "Please check connection and permissions.");
297 return ERROR_JTAG_INIT_FAILED
;
299 LOG_DEBUG("vsllink found on %04X:%04X",
300 versaloon_interface
.usb_setting
.vid
,
301 versaloon_interface
.usb_setting
.pid
);
302 versaloon_usb_device_handle
= vsllink_handle
->usb_device_handle
;
304 if (ERROR_OK
!= versaloon_interface
.init())
306 if (versaloon_interface
.usb_setting
.buf_size
< 32) {
307 versaloon_interface
.fini();
314 static int vsllink_init(void)
316 int retval
= vsllink_interface_init();
317 if (ERROR_OK
!= retval
)
320 versaloon_interface
.adaptors
.gpio
.init(0);
321 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
, 0, GPIO_SRST
,
323 versaloon_interface
.adaptors
.delay
.delayms(100);
324 versaloon_interface
.adaptors
.peripheral_commit();
327 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_TRST
, 0,
328 GPIO_TRST
, GPIO_TRST
);
329 versaloon_interface
.adaptors
.swd
.init(0);
330 vsllink_swd_frequency(jtag_get_speed_khz() * 1000);
331 vsllink_swd_switch_seq(JTAG_TO_SWD
);
334 /* malloc buffer size for tap */
335 tap_buffer_size
= versaloon_interface
.usb_setting
.buf_size
/ 2 - 32;
336 vsllink_free_buffer();
337 tdi_buffer
= malloc(tap_buffer_size
);
338 tdo_buffer
= malloc(tap_buffer_size
);
339 tms_buffer
= malloc(tap_buffer_size
);
340 if ((NULL
== tdi_buffer
) || (NULL
== tdo_buffer
) || (NULL
== tms_buffer
)) {
345 versaloon_interface
.adaptors
.jtag_raw
.init(0);
346 versaloon_interface
.adaptors
.jtag_raw
.config(0, jtag_get_speed_khz());
347 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
| GPIO_TRST
,
348 GPIO_TRST
, GPIO_SRST
, GPIO_SRST
);
351 if (ERROR_OK
!= versaloon_interface
.adaptors
.peripheral_commit())
359 /**************************************************************************
360 * Queue command implementations */
362 static void vsllink_end_state(tap_state_t state
)
364 if (tap_is_state_stable(state
))
365 tap_set_end_state(state
);
367 LOG_ERROR("BUG: %i is not a valid end state", state
);
372 /* Goes to the end state. */
373 static void vsllink_state_move(void)
376 uint8_t tms_scan
= tap_get_tms_path(tap_get_state(),
377 tap_get_end_state());
378 uint8_t tms_scan_bits
= tap_get_tms_path_len(tap_get_state(),
379 tap_get_end_state());
381 for (i
= 0; i
< tms_scan_bits
; i
++)
382 vsllink_tap_append_step((tms_scan
>> i
) & 1, 0);
384 tap_set_state(tap_get_end_state());
387 static void vsllink_path_move(int num_states
, tap_state_t
*path
)
389 for (int i
= 0; i
< num_states
; i
++) {
390 if (path
[i
] == tap_state_transition(tap_get_state(), false))
391 vsllink_tap_append_step(0, 0);
392 else if (path
[i
] == tap_state_transition(tap_get_state(), true))
393 vsllink_tap_append_step(1, 0);
395 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
396 tap_state_name(tap_get_state()),
397 tap_state_name(path
[i
]));
401 tap_set_state(path
[i
]);
404 tap_set_end_state(tap_get_state());
407 static void vsllink_tms(int num_bits
, const uint8_t *bits
)
409 for (int i
= 0; i
< num_bits
; i
++)
410 vsllink_tap_append_step((bits
[i
/ 8] >> (i
% 8)) & 1, 0);
413 static void vsllink_stableclocks(int num_cycles
, int tms
)
415 while (num_cycles
> 0) {
416 vsllink_tap_append_step(tms
, 0);
421 static void vsllink_runtest(int num_cycles
)
423 tap_state_t saved_end_state
= tap_get_end_state();
425 if (tap_get_state() != TAP_IDLE
) {
426 /* enter IDLE state */
427 vsllink_end_state(TAP_IDLE
);
428 vsllink_state_move();
431 vsllink_stableclocks(num_cycles
, 0);
435 vsllink_end_state(saved_end_state
);
436 if (tap_get_end_state() != tap_get_end_state())
437 vsllink_state_move();
440 static void vsllink_scan(bool ir_scan
, enum scan_type type
, uint8_t *buffer
,
441 int scan_size
, struct scan_command
*command
)
443 tap_state_t saved_end_state
;
445 saved_end_state
= tap_get_end_state();
447 /* Move to appropriate scan state */
448 vsllink_end_state(ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
450 if (tap_get_state() != tap_get_end_state())
451 vsllink_state_move();
452 vsllink_end_state(saved_end_state
);
455 vsllink_tap_append_scan(scan_size
, buffer
, command
);
457 /* Goto Pause and record position to insert tms:0 */
458 vsllink_tap_append_step(0, 0);
459 vsllink_tms_offset
= tap_length
;
461 tap_set_state(ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
463 if (tap_get_state() != tap_get_end_state())
464 vsllink_state_move();
467 static int vsllink_reset(int trst
, int srst
)
469 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
472 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
, 0, GPIO_SRST
, GPIO_SRST
);
474 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
, GPIO_SRST
, 0, 0);
478 versaloon_interface
.adaptors
.gpio
.out(0, GPIO_TRST
, GPIO_TRST
);
480 versaloon_interface
.adaptors
.gpio
.out(0, GPIO_TRST
, 0);
483 return versaloon_interface
.adaptors
.peripheral_commit();
486 COMMAND_HANDLER(vsllink_handle_usb_vid_command
)
489 return ERROR_COMMAND_SYNTAX_ERROR
;
491 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0],
492 versaloon_interface
.usb_setting
.vid
);
496 COMMAND_HANDLER(vsllink_handle_usb_pid_command
)
499 return ERROR_COMMAND_SYNTAX_ERROR
;
500 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0],
501 versaloon_interface
.usb_setting
.pid
);
505 COMMAND_HANDLER(vsllink_handle_usb_serial_command
)
508 return ERROR_COMMAND_SYNTAX_ERROR
;
510 free(versaloon_interface
.usb_setting
.serialstring
);
513 versaloon_interface
.usb_setting
.serialstring
= strdup(CMD_ARGV
[0]);
515 versaloon_interface
.usb_setting
.serialstring
= NULL
;
520 COMMAND_HANDLER(vsllink_handle_usb_bulkin_command
)
523 return ERROR_COMMAND_SYNTAX_ERROR
;
525 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
526 versaloon_interface
.usb_setting
.ep_in
);
528 versaloon_interface
.usb_setting
.ep_in
|= 0x80;
533 COMMAND_HANDLER(vsllink_handle_usb_bulkout_command
)
536 return ERROR_COMMAND_SYNTAX_ERROR
;
538 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
539 versaloon_interface
.usb_setting
.ep_out
);
541 versaloon_interface
.usb_setting
.ep_out
&= ~0x80;
546 COMMAND_HANDLER(vsllink_handle_usb_interface_command
)
549 return ERROR_COMMAND_SYNTAX_ERROR
;
551 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
552 versaloon_interface
.usb_setting
.interface
);
556 /**************************************************************************
557 * VSLLink tap functions */
559 static void vsllink_tap_init(void)
562 pending_scan_results_length
= 0;
563 vsllink_tms_offset
= 0;
566 static void vsllink_tap_ensure_pending(int scans
)
568 int available_scans
=
569 MAX_PENDING_SCAN_RESULTS
- pending_scan_results_length
;
571 if (scans
> available_scans
)
572 vsllink_tap_execute();
575 static void vsllink_tap_append_step(int tms
, int tdi
)
577 int index_var
= tap_length
/ 8;
579 int bit_index
= tap_length
% 8;
580 uint8_t bit
= 1 << bit_index
;
583 tms_buffer
[index_var
] |= bit
;
585 tms_buffer
[index_var
] &= ~bit
;
588 tdi_buffer
[index_var
] |= bit
;
590 tdi_buffer
[index_var
] &= ~bit
;
594 if (tap_buffer_size
* 8 <= tap_length
)
595 vsllink_tap_execute();
598 static void vsllink_tap_append_scan(int length
, uint8_t *buffer
,
599 struct scan_command
*command
)
601 struct pending_scan_result
*pending_scan_result
;
602 int len_tmp
, len_all
, i
;
605 while (len_all
< length
) {
606 vsllink_tap_ensure_pending(1);
607 pending_scan_result
=
608 &pending_scan_results_buffer
[
609 pending_scan_results_length
];
611 if ((length
- len_all
) > (tap_buffer_size
* 8 - tap_length
)) {
612 /* Use all memory available
613 vsllink_tap_append_step will commit automatically */
614 len_tmp
= tap_buffer_size
* 8 - tap_length
;
615 pending_scan_result
->last
= false;
617 len_tmp
= length
- len_all
;
618 pending_scan_result
->last
= true;
620 pending_scan_result
->src_offset
= tap_length
;
621 pending_scan_result
->dest_offset
= len_all
;
622 pending_scan_result
->length
= len_tmp
;
623 pending_scan_result
->command
= command
;
624 pending_scan_result
->buffer
= buffer
;
625 pending_scan_results_length
++;
627 for (i
= 0; i
< len_tmp
; i
++) {
628 vsllink_tap_append_step(((len_all
+ i
) < length
-1
630 (buffer
[(len_all
+ i
)/8]
631 >> ((len_all
+ i
)%8)) & 1);
638 static int vsllink_jtag_execute(void)
646 versaloon_interface
.adaptors
.jtag_raw
.execute(0, tdi_buffer
, tms_buffer
,
647 tdo_buffer
, tap_length
);
649 result
= versaloon_interface
.adaptors
.peripheral_commit();
651 if (result
== ERROR_OK
) {
652 for (i
= 0; i
< pending_scan_results_length
; i
++) {
653 struct pending_scan_result
*pending_scan_result
=
654 &pending_scan_results_buffer
[i
];
655 uint8_t *buffer
= pending_scan_result
->buffer
;
656 int length
= pending_scan_result
->length
;
657 int src_first
= pending_scan_result
->src_offset
;
658 int dest_first
= pending_scan_result
->dest_offset
;
659 bool last
= pending_scan_result
->last
;
661 struct scan_command
*command
;
663 command
= pending_scan_result
->command
;
664 buf_set_buf(tdo_buffer
, src_first
, buffer
, dest_first
, length
);
667 "JTAG scan read(%d bits, from src %d bits to dest %d bits):",
668 length
, src_first
, dest_first
);
669 if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO
))
670 vsllink_debug_buffer(buffer
+ dest_first
/ 8, DIV_ROUND_UP(length
, 7));
673 if (jtag_read_buffer(buffer
, command
)
676 return ERROR_JTAG_QUEUE_FAILED
;
679 if (pending_scan_result
->buffer
!= NULL
)
680 free(pending_scan_result
->buffer
);
684 LOG_ERROR("vsllink_jtag_execute failure");
685 return ERROR_JTAG_QUEUE_FAILED
;
693 static int vsllink_tap_execute(void)
698 return vsllink_jtag_execute();
701 static int vsllink_swd_init(void)
703 LOG_INFO("VSLLink SWD mode enabled");
709 static int_least32_t vsllink_swd_frequency(int_least32_t hz
)
711 const int_least32_t delay2hz
[] = {
712 1850000, 235000, 130000, 102000, 85000, 72000
716 uint16_t delay
= UINT16_MAX
;
718 for (uint16_t i
= 0; i
< ARRAY_SIZE(delay2hz
); i
++) {
719 if (hz
>= delay2hz
[i
]) {
726 if (delay
== UINT16_MAX
)
727 delay
= (500000 / hz
) - 1;
729 /* Calculate retry count after a WAIT response. This will give
730 * a retry timeout at about ~250 ms. 54 is the number of bits
731 * found in a transaction. */
732 uint16_t retry_count
= 250 * hz
/ 1000 / 54;
734 LOG_DEBUG("SWD delay: %d, retry count: %d", delay
, retry_count
);
736 versaloon_interface
.adaptors
.swd
.config(0, 2, retry_count
, delay
);
742 static int vsllink_swd_switch_seq(enum swd_special_seq seq
)
746 LOG_DEBUG("SWD line reset");
747 versaloon_interface
.adaptors
.swd
.seqout(0, swd_seq_line_reset
,
748 swd_seq_line_reset_len
);
751 LOG_DEBUG("JTAG-to-SWD");
752 versaloon_interface
.adaptors
.swd
.seqout(0, swd_seq_jtag_to_swd
,
753 swd_seq_jtag_to_swd_len
);
756 LOG_DEBUG("SWD-to-JTAG");
757 versaloon_interface
.adaptors
.swd
.seqout(0, swd_seq_swd_to_jtag
,
758 swd_seq_swd_to_jtag_len
);
761 LOG_ERROR("Sequence %d not supported", seq
);
768 static void vsllink_swd_read_reg(uint8_t cmd
, uint32_t *value
, uint32_t ap_delay_clk
)
770 versaloon_interface
.adaptors
.swd
.transact(0, cmd
, value
, NULL
);
773 static void vsllink_swd_write_reg(uint8_t cmd
, uint32_t value
, uint32_t ap_delay_clk
)
775 versaloon_interface
.adaptors
.swd
.transact(0, cmd
, &value
, NULL
);
778 static int vsllink_swd_run_queue(void)
780 return versaloon_interface
.adaptors
.peripheral_commit();
783 /****************************************************************************
784 * VSLLink USB low-level functions */
786 static int vsllink_check_usb_strings(
787 struct libusb_device_handle
*usb_device_handle
,
788 struct libusb_device_descriptor
*usb_desc
)
790 char desc_string
[256];
793 if (NULL
!= versaloon_interface
.usb_setting
.serialstring
) {
794 retval
= libusb_get_string_descriptor_ascii(usb_device_handle
,
795 usb_desc
->iSerialNumber
, (unsigned char *)desc_string
,
796 sizeof(desc_string
));
800 if (strncmp(desc_string
, versaloon_interface
.usb_setting
.serialstring
,
801 sizeof(desc_string
)))
805 retval
= libusb_get_string_descriptor_ascii(usb_device_handle
,
806 usb_desc
->iProduct
, (unsigned char *)desc_string
,
807 sizeof(desc_string
));
811 if (strstr(desc_string
, "Versaloon") == NULL
)
817 static int vsllink_usb_open(struct vsllink
*vsllink
)
819 ssize_t num_devices
, i
;
820 libusb_device
**usb_devices
;
821 struct libusb_device_descriptor usb_desc
;
822 struct libusb_device_handle
*usb_device_handle
;
825 num_devices
= libusb_get_device_list(vsllink
->libusb_ctx
, &usb_devices
);
827 if (num_devices
<= 0)
830 for (i
= 0; i
< num_devices
; i
++) {
831 libusb_device
*device
= usb_devices
[i
];
833 retval
= libusb_get_device_descriptor(device
, &usb_desc
);
837 if (usb_desc
.idVendor
!= versaloon_interface
.usb_setting
.vid
||
838 usb_desc
.idProduct
!= versaloon_interface
.usb_setting
.pid
)
841 retval
= libusb_open(device
, &usb_device_handle
);
845 retval
= vsllink_check_usb_strings(usb_device_handle
, &usb_desc
);
846 if (ERROR_OK
== retval
)
849 libusb_close(usb_device_handle
);
852 libusb_free_device_list(usb_devices
, 1);
854 if (i
== num_devices
)
857 retval
= libusb_claim_interface(usb_device_handle
,
858 versaloon_interface
.usb_setting
.interface
);
860 LOG_ERROR("unable to claim interface");
861 libusb_close(usb_device_handle
);
865 vsllink
->usb_device_handle
= usb_device_handle
;
869 static void vsllink_usb_close(struct vsllink
*vsllink
)
871 libusb_release_interface(vsllink
->usb_device_handle
,
872 versaloon_interface
.usb_setting
.interface
);
873 libusb_close(vsllink
->usb_device_handle
);
876 #define BYTES_PER_LINE 16
878 static void vsllink_debug_buffer(uint8_t *buffer
, int length
)
885 for (i
= 0; i
< length
; i
+= BYTES_PER_LINE
) {
886 snprintf(line
, 5, "%04x", i
& 0xffff);
887 for (j
= i
; j
< i
+ BYTES_PER_LINE
&& j
< length
; j
++) {
888 snprintf(s
, 4, " %02x", buffer
[j
]);
891 LOG_DEBUG_IO("%s", line
);
895 static const struct command_registration vsllink_command_handlers
[] = {
897 .name
= "vsllink_usb_vid",
898 .handler
= &vsllink_handle_usb_vid_command
,
899 .mode
= COMMAND_CONFIG
,
900 .help
= "Set USB VID",
904 .name
= "vsllink_usb_pid",
905 .handler
= &vsllink_handle_usb_pid_command
,
906 .mode
= COMMAND_CONFIG
,
907 .help
= "Set USB PID",
911 .name
= "vsllink_usb_serial",
912 .handler
= &vsllink_handle_usb_serial_command
,
913 .mode
= COMMAND_CONFIG
,
914 .help
= "Set or disable check for USB serial",
915 .usage
= "[<serial>]",
918 .name
= "vsllink_usb_bulkin",
919 .handler
= &vsllink_handle_usb_bulkin_command
,
920 .mode
= COMMAND_CONFIG
,
921 .help
= "Set USB input endpoint",
925 .name
= "vsllink_usb_bulkout",
926 .handler
= &vsllink_handle_usb_bulkout_command
,
927 .mode
= COMMAND_CONFIG
,
928 .help
= "Set USB output endpoint",
932 .name
= "vsllink_usb_interface",
933 .handler
= &vsllink_handle_usb_interface_command
,
934 .mode
= COMMAND_CONFIG
,
935 .help
= "Set USB output interface",
936 .usage
= "<interface>",
938 COMMAND_REGISTRATION_DONE
941 static const char * const vsllink_transports
[] = {"jtag", "swd", NULL
};
943 static const struct swd_driver vsllink_swd_driver
= {
944 .init
= vsllink_swd_init
,
945 .switch_seq
= vsllink_swd_switch_seq
,
946 .read_reg
= vsllink_swd_read_reg
,
947 .write_reg
= vsllink_swd_write_reg
,
948 .run
= vsllink_swd_run_queue
,
951 static struct jtag_interface vsllink_interface
= {
952 .supported
= DEBUG_CAP_TMS_SEQ
,
953 .execute_queue
= vsllink_execute_queue
,
956 struct adapter_driver vsllink_adapter_driver
= {
958 .transports
= vsllink_transports
,
959 .commands
= vsllink_command_handlers
,
961 .init
= vsllink_init
,
962 .quit
= vsllink_quit
,
963 .reset
= vsllink_reset
,
964 .speed
= vsllink_speed
,
966 .speed_div
= vsllink_speed_div
,
968 .jtag_ops
= &vsllink_interface
,
969 .swd_ops
= &vsllink_swd_driver
,
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)