1 /*******************************************************************************
2 * Driver for OpenJTAG Project (www.openjtag.org) *
3 * Compatible with libftdi and ftd2xx drivers. *
5 * Copyright (C) 2010 by Ivan Meleca <mileca@gmail.com> *
7 * Copyright (C) 2013 by Ryan Corbin, GlueLogix Inc. <corbin.ryan@gmail.com> *
8 * Updated to work with OpenOCD v0.7.0. Fixed libftdi read speed issue. *
10 * Based on usb_blaster.c *
11 * Copyright (C) 2009 Catalin Patulea *
12 * Copyright (C) 2006 Kolja Waschk *
15 * Copyright (C) 2008 by Spencer Oliver *
16 * spen@spen-soft.co.uk *
18 * This program is free software; you can redistribute it and/or modify *
19 * it under the terms of the GNU General Public License as published by *
20 * the Free Software Foundation; either version 2 of the License, or *
21 * (at your option) any later version. *
23 * This program is distributed in the hope that it will be useful, *
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
26 * GNU General Public License for more details. *
28 * You should have received a copy of the GNU General Public License *
29 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
30 ***************************************************************************/
32 /***************************************************************************
33 * Version 1.0 Tested on a MCBSTM32 board using a Cortex-M3 (stm32f103x), *
34 * GDB and Eclipse under Linux (Ubuntu 10.04) *
36 ***************************************************************************/
42 #include <jtag/interface.h>
43 #include <jtag/commands.h>
44 #include "usb_common.h"
47 * OpenJTAG-OpenOCD state conversion
49 typedef enum openjtag_tap_state
{
50 OPENJTAG_TAP_INVALID
= -1,
51 OPENJTAG_TAP_RESET
= 0,
52 OPENJTAG_TAP_IDLE
= 1,
53 OPENJTAG_TAP_SELECT_DR
= 2,
54 OPENJTAG_TAP_CAPTURE_DR
= 3,
55 OPENJTAG_TAP_SHIFT_DR
= 4,
56 OPENJTAG_TAP_EXIT1_DR
= 5,
57 OPENJTAG_TAP_PAUSE_DR
= 6,
58 OPENJTAG_TAP_EXIT2_DR
= 7,
59 OPENJTAG_TAP_UPDATE_DR
= 8,
60 OPENJTAG_TAP_SELECT_IR
= 9,
61 OPENJTAG_TAP_CAPURE_IR
= 10,
62 OPENJTAG_TAP_SHIFT_IR
= 11,
63 OPENJTAG_TAP_EXIT1_IR
= 12,
64 OPENJTAG_TAP_PAUSE_IR
= 13,
65 OPENJTAG_TAP_EXIT2_IR
= 14,
66 OPENJTAG_TAP_UPDATE_IR
= 15,
67 } openjtag_tap_state_t
;
69 #if (BUILD_OPENJTAG_FTD2XX == 1 && BUILD_OPENJTAG_LIBFTDI == 1)
70 #error "BUILD_OPENJTAG_FTD2XX && BUILD_OPENJTAG_LIBFTDI "
71 "are mutually exclusive"
72 #elif (BUILD_OPENJTAG_FTD2XX != 1 && BUILD_OPENJTAG_LIBFTDI != 1)
73 #error "BUILD_OPENJTAG_FTD2XX || BUILD_OPENJTAG_LIBFTDI must be chosen"
76 /* OPENJTAG access library includes */
77 #if BUILD_OPENJTAG_FTD2XX == 1
79 #elif BUILD_OPENJTAG_LIBFTDI == 1
83 /* OpenJTAG vid/pid */
84 static uint16_t openjtag_vid
= 0x0403;
85 static uint16_t openjtag_pid
= 0x6001;
87 static char *openjtag_device_desc
;
89 #if BUILD_OPENJTAG_FTD2XX == 1
90 static FT_HANDLE ftdih
;
92 #elif BUILD_OPENJTAG_LIBFTDI == 1
93 static struct ftdi_context ftdic
;
96 #define OPENJTAG_BUFFER_SIZE 504
97 #define OPENJTAG_MAX_PENDING_RESULTS 256
99 struct openjtag_scan_result
{
100 uint32_t bits
; /* Length in bits*/
101 struct scan_command
*command
; /* Corresponding scan command */
105 /* USB RX/TX buffers */
106 static int usb_tx_buf_offs
;
107 static uint8_t usb_tx_buf
[OPENJTAG_BUFFER_SIZE
];
108 static uint32_t usb_rx_buf_len
;
109 static uint8_t usb_rx_buf
[OPENJTAG_BUFFER_SIZE
];
111 /* Pending readings */
112 static struct openjtag_scan_result openjtag_scan_result_buffer
[OPENJTAG_MAX_PENDING_RESULTS
];
113 static int openjtag_scan_result_count
;
115 /* Openocd usb handler */
117 struct usb_dev_handle
*usb_handle
;
120 #ifdef _DEBUG_USB_COMMS_
122 #define DEBUG_TYPE_READ 0
123 #define DEBUG_TYPE_WRITE 1
124 #define DEBUG_TYPE_OCD_READ 2
125 #define DEBUG_TYPE_BUFFER 3
128 static void openjtag_debug_buffer(uint8_t *buffer
, int length
, uint8_t type
)
136 case DEBUG_TYPE_READ
:
137 sprintf(line
, "USB READ %d bytes", length
);
139 case DEBUG_TYPE_WRITE
:
140 sprintf(line
, "USB WRITE %d bytes", length
);
142 case DEBUG_TYPE_OCD_READ
:
143 sprintf(line
, "TO OpenOCD %d bytes", length
);
145 case DEBUG_TYPE_BUFFER
:
146 sprintf(line
, "Buffer %d bytes", length
);
150 LOG_DEBUG("%s", line
);
152 for (i
= 0; i
< length
; i
+= LINE_LEN
) {
154 case DEBUG_TYPE_READ
:
155 sprintf(line
, "USB READ: %04x", i
);
157 case DEBUG_TYPE_WRITE
:
158 sprintf(line
, "USB WRITE: %04x", i
);
160 case DEBUG_TYPE_OCD_READ
:
161 sprintf(line
, "TO OpenOCD: %04x", i
);
163 case DEBUG_TYPE_BUFFER
:
164 sprintf(line
, "BUFFER: %04x", i
);
168 for (j
= i
; j
< i
+ LINE_LEN
&& j
< length
; j
++) {
169 sprintf(s
, " %02x", buffer
[j
]);
172 LOG_DEBUG("%s", line
);
179 static int8_t openjtag_get_tap_state(int8_t state
)
183 case TAP_DREXIT2
: return OPENJTAG_TAP_EXIT2_DR
;
184 case TAP_DREXIT1
: return OPENJTAG_TAP_EXIT1_DR
;
185 case TAP_DRSHIFT
: return OPENJTAG_TAP_SHIFT_DR
;
186 case TAP_DRPAUSE
: return OPENJTAG_TAP_PAUSE_DR
;
187 case TAP_IRSELECT
: return OPENJTAG_TAP_SELECT_IR
;
188 case TAP_DRUPDATE
: return OPENJTAG_TAP_UPDATE_DR
;
189 case TAP_DRCAPTURE
: return OPENJTAG_TAP_CAPTURE_DR
;
190 case TAP_DRSELECT
: return OPENJTAG_TAP_SELECT_DR
;
191 case TAP_IREXIT2
: return OPENJTAG_TAP_EXIT2_IR
;
192 case TAP_IREXIT1
: return OPENJTAG_TAP_EXIT1_IR
;
193 case TAP_IRSHIFT
: return OPENJTAG_TAP_SHIFT_IR
;
194 case TAP_IRPAUSE
: return OPENJTAG_TAP_PAUSE_IR
;
195 case TAP_IDLE
: return OPENJTAG_TAP_IDLE
;
196 case TAP_IRUPDATE
: return OPENJTAG_TAP_UPDATE_IR
;
197 case TAP_IRCAPTURE
: return OPENJTAG_TAP_CAPURE_IR
;
198 case TAP_RESET
: return OPENJTAG_TAP_RESET
;
200 default: return OPENJTAG_TAP_INVALID
;
204 static int openjtag_buf_write(
205 uint8_t *buf
, int size
, uint32_t *bytes_written
)
207 #if BUILD_OPENJTAG_FTD2XX == 1
209 DWORD dw_bytes_written
;
211 #ifdef _DEBUG_USB_COMMS_
212 openjtag_debug_buffer(buf
, size
, DEBUG_TYPE_WRITE
);
215 status
= FT_Write(ftdih
, buf
, size
, &dw_bytes_written
);
216 if (status
!= FT_OK
) {
217 *bytes_written
= dw_bytes_written
;
218 LOG_ERROR("FT_Write returned: %u", status
);
219 return ERROR_JTAG_DEVICE_ERROR
;
221 *bytes_written
= dw_bytes_written
;
223 #elif BUILD_OPENJTAG_LIBFTDI == 1
225 #ifdef _DEBUG_USB_COMMS_
226 openjtag_debug_buffer(buf
, size
, DEBUG_TYPE_WRITE
);
229 retval
= ftdi_write_data(&ftdic
, buf
, size
);
232 LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&ftdic
));
233 return ERROR_JTAG_DEVICE_ERROR
;
236 *bytes_written
+= retval
;
242 static int openjtag_buf_read(uint8_t *buf
, uint32_t qty
, uint32_t *bytes_read
)
245 #if BUILD_OPENJTAG_FTD2XX == 1
251 while (qty
&& (*bytes_read
< qty
) && timeout
--) {
253 status
= FT_Read(ftdih
, buf
+ *bytes_read
,
254 qty
- *bytes_read
, &dw_bytes_read
);
255 if (status
!= FT_OK
) {
256 *bytes_read
= dw_bytes_read
;
257 LOG_ERROR("FT_Read returned: %u", status
);
258 return ERROR_JTAG_DEVICE_ERROR
;
260 *bytes_read
+= dw_bytes_read
;
263 #ifdef _DEBUG_USB_COMMS_
264 openjtag_debug_buffer(buf
, *bytes_read
, DEBUG_TYPE_READ
);
268 #elif BUILD_OPENJTAG_LIBFTDI == 1
274 while ((*bytes_read
< qty
) && timeout
--) {
275 retval
= ftdi_read_data(&ftdic
, buf
+ *bytes_read
,
279 DEBUG_JTAG_IO("ftdi_read_data: %s",
280 ftdi_get_error_string(&ftdic
));
281 return ERROR_JTAG_DEVICE_ERROR
;
283 *bytes_read
+= retval
;
286 #ifdef _DEBUG_USB_COMMS_
287 openjtag_debug_buffer(buf
, *bytes_read
, DEBUG_TYPE_READ
);
294 static int openjtag_sendcommand(uint8_t cmd
)
297 return openjtag_buf_write(&cmd
, 1, &written
);
300 static int openjtag_speed(int speed
)
330 LOG_WARNING("adapter speed not recognized, reverting to 375 kHz");
333 openjtag_sendcommand(clockcmd
);
338 static int openjtag_init(void)
340 uint8_t latency_timer
;
342 #if BUILD_OPENJTAG_FTD2XX == 1
348 openjtag_scan_result_count
= 0;
350 #if BUILD_OPENJTAG_FTD2XX == 1
351 LOG_DEBUG("'openjtag' interface using FTD2XX");
352 #elif BUILD_OPENJTAG_LIBFTDI == 1
353 LOG_DEBUG("'openjtag' interface using libftdi");
356 /* Open by device description */
357 if (openjtag_device_desc
== NULL
) {
358 LOG_WARNING("no openjtag device description specified, "
359 "using default 'Open JTAG Project'");
360 openjtag_device_desc
= "Open JTAG Project";
363 #if BUILD_OPENJTAG_FTD2XX == 1
366 /* Add non-standard Vid/Pid to the linux driver */
367 status
= FT_SetVIDPID(openjtag_vid
, openjtag_pid
);
368 if (status
!= FT_OK
) {
369 LOG_WARNING("couldn't add %4.4x:%4.4x",
370 openjtag_vid
, openjtag_pid
);
374 status
= FT_OpenEx(openjtag_device_desc
, FT_OPEN_BY_DESCRIPTION
,
376 if (status
!= FT_OK
) {
379 LOG_ERROR("unable to open ftdi device: %u", status
);
380 status
= FT_ListDevices(&num_devices
, NULL
,
381 FT_LIST_NUMBER_ONLY
);
382 if (status
== FT_OK
) {
383 char **desc_array
= malloc(sizeof(char *)
384 * (num_devices
+ 1));
387 for (i
= 0; i
< num_devices
; i
++)
388 desc_array
[i
] = malloc(64);
389 desc_array
[num_devices
] = NULL
;
391 status
= FT_ListDevices(desc_array
, &num_devices
,
392 FT_LIST_ALL
| FT_OPEN_BY_DESCRIPTION
);
394 if (status
== FT_OK
) {
395 LOG_ERROR("ListDevices: %u\n", num_devices
);
396 for (i
= 0; i
< num_devices
; i
++)
397 LOG_ERROR("%i: %s", i
, desc_array
[i
]);
400 for (i
= 0; i
< num_devices
; i
++)
404 LOG_ERROR("ListDevices: NONE\n");
406 return ERROR_JTAG_INIT_FAILED
;
409 status
= FT_SetLatencyTimer(ftdih
, 2);
410 if (status
!= FT_OK
) {
411 LOG_ERROR("unable to set latency timer: %u", status
);
412 return ERROR_JTAG_INIT_FAILED
;
415 status
= FT_GetLatencyTimer(ftdih
, &latency_timer
);
416 if (status
!= FT_OK
) {
417 LOG_ERROR("unable to get latency timer: %u", status
);
418 return ERROR_JTAG_INIT_FAILED
;
420 LOG_DEBUG("current latency timer: %i", latency_timer
);
422 status
= FT_SetBitMode(ftdih
, 0x00, 0x40);
423 if (status
!= FT_OK
) {
424 LOG_ERROR("unable to disable bit i/o mode: %u", status
);
425 return ERROR_JTAG_INIT_FAILED
;
428 status
= FT_SetTimeouts(ftdih
, 50, 0);
429 if (status
!= FT_OK
) {
430 LOG_ERROR("unable to set timeouts: %u", status
);
431 return ERROR_JTAG_INIT_FAILED
;
434 status
= FT_Purge(ftdih
, FT_PURGE_RX
| FT_PURGE_TX
);
435 if (status
!= FT_OK
) {
436 LOG_ERROR("unable to FT_Purge() %u", status
);
437 return ERROR_JTAG_INIT_FAILED
;
440 #elif BUILD_OPENJTAG_LIBFTDI == 1
441 if (ftdi_init(&ftdic
) < 0)
442 return ERROR_JTAG_INIT_FAILED
;
444 /* context, vendor id, product id, description, serial id */
445 if (ftdi_usb_open_desc(&ftdic
, openjtag_vid
, openjtag_pid
, openjtag_device_desc
, NULL
) < 0) {
446 LOG_ERROR("unable to open ftdi device: %s", ftdic
.error_str
);
447 return ERROR_JTAG_INIT_FAILED
;
450 if (ftdi_usb_reset(&ftdic
) < 0) {
451 LOG_ERROR("unable to reset ftdi device");
452 return ERROR_JTAG_INIT_FAILED
;
455 if (ftdi_set_latency_timer(&ftdic
, 2) < 0) {
456 LOG_ERROR("unable to set latency timer");
457 return ERROR_JTAG_INIT_FAILED
;
460 if (ftdi_get_latency_timer(&ftdic
, &latency_timer
) < 0) {
461 LOG_ERROR("unable to get latency timer");
462 return ERROR_JTAG_INIT_FAILED
;
464 LOG_DEBUG("current latency timer: %u", latency_timer
);
466 ftdi_disable_bitbang(&ftdic
);
467 /* was (3000000 / 4) with a comment about a bug in libftdi when using high baudrate */
468 if (ftdi_set_baudrate(&ftdic
, 3000000) < 0) {
469 LOG_ERROR("Can't set baud rate to max: %s",
470 ftdi_get_error_string(&ftdic
));
471 return ERROR_JTAG_DEVICE_ERROR
;
475 #if BUILD_OPENJTAG_FTD2XX == 1
476 status
= FT_Purge(ftdih
, FT_PURGE_RX
| FT_PURGE_TX
);
478 return ERROR_JTAG_INIT_FAILED
;
479 #elif BUILD_OPENJTAG_LIBFTDI == 1
480 if (ftdi_usb_purge_buffers(&ftdic
) < 0) {
481 LOG_ERROR("ftdi_purge_buffers: %s", ftdic
.error_str
);
482 return ERROR_JTAG_INIT_FAILED
;
487 openjtag_sendcommand(0xE0); /*Start at slowest adapter speed*/
490 openjtag_sendcommand(0x75);
495 static int openjtag_quit(void)
497 #if BUILD_OPENJTAG_FTD2XX == 1
499 #elif BUILD_OPENJTAG_LIBFTDI == 1
500 ftdi_usb_close(&ftdic
);
507 static void openjtag_write_tap_buffer(void)
511 openjtag_buf_write(usb_tx_buf
, usb_tx_buf_offs
, &written
);
512 openjtag_buf_read(usb_rx_buf
, usb_tx_buf_offs
, &usb_rx_buf_len
);
517 static int openjtag_execute_tap_queue(void)
519 openjtag_write_tap_buffer();
523 if (openjtag_scan_result_count
&& usb_rx_buf_len
) {
529 /* for every pending result */
530 while (res_count
< openjtag_scan_result_count
) {
533 len
= openjtag_scan_result_buffer
[res_count
].bits
;
537 uint8_t *buffer
= openjtag_scan_result_buffer
[res_count
].buffer
;
541 DEBUG_JTAG_IO("bits < 8 buf = 0x%X, will be 0x%X",
542 usb_rx_buf
[rx_offs
], usb_rx_buf
[rx_offs
] >> (8 - len
));
543 buffer
[count
] = usb_rx_buf
[rx_offs
] >> (8 - len
);
546 buffer
[count
] = usb_rx_buf
[rx_offs
];
554 #ifdef _DEBUG_USB_COMMS_
555 openjtag_debug_buffer(buffer
,
556 DIV_ROUND_UP(openjtag_scan_result_buffer
[res_count
].bits
, 8), DEBUG_TYPE_OCD_READ
);
558 jtag_read_buffer(buffer
, openjtag_scan_result_buffer
[res_count
].command
);
560 if (openjtag_scan_result_buffer
[res_count
].buffer
)
561 free(openjtag_scan_result_buffer
[res_count
].buffer
);
567 openjtag_scan_result_count
= 0;
572 static void openjtag_add_byte(char buf
)
575 if (usb_tx_buf_offs
== OPENJTAG_BUFFER_SIZE
) {
576 DEBUG_JTAG_IO("Forcing execute_tap_queue");
577 DEBUG_JTAG_IO("TX Buff offs=%d", usb_tx_buf_offs
);
578 openjtag_execute_tap_queue();
581 usb_tx_buf
[usb_tx_buf_offs
] = buf
;
585 static void openjtag_add_scan(uint8_t *buffer
, int length
, struct scan_command
*scan_cmd
)
588 /* Ensure space to send long chains */
589 /* We add two byte for each eight (or less) bits, one for command, one for data */
590 if (usb_tx_buf_offs
+ (DIV_ROUND_UP(length
, 8) * 2) >= OPENJTAG_BUFFER_SIZE
) {
591 DEBUG_JTAG_IO("Forcing execute_tap_queue from scan");
592 DEBUG_JTAG_IO("TX Buff offs=%d len=%d", usb_tx_buf_offs
, DIV_ROUND_UP(length
, 8) * 2);
593 openjtag_execute_tap_queue();
596 openjtag_scan_result_buffer
[openjtag_scan_result_count
].bits
= length
;
597 openjtag_scan_result_buffer
[openjtag_scan_result_count
].command
= scan_cmd
;
598 openjtag_scan_result_buffer
[openjtag_scan_result_count
].buffer
= buffer
;
613 /* bits to transfer */
615 command
|= bits
<< 5;
620 /* bits to transfer */
626 openjtag_add_byte(command
);
627 openjtag_add_byte(buffer
[count
]);
631 openjtag_scan_result_count
++;
634 static void openjtag_execute_reset(struct jtag_command
*cmd
)
637 DEBUG_JTAG_IO("reset trst: %i srst %i",
638 cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
642 if (cmd
->cmd
.reset
->trst
) {
649 openjtag_add_byte(buf
);
652 static void openjtag_execute_sleep(struct jtag_command
*cmd
)
654 jtag_sleep(cmd
->cmd
.sleep
->us
);
657 static void openjtag_set_state(uint8_t openocd_state
)
659 int8_t state
= openjtag_get_tap_state(openocd_state
);
665 openjtag_add_byte(buf
);
668 static void openjtag_execute_statemove(struct jtag_command
*cmd
)
670 DEBUG_JTAG_IO("state move to %i", cmd
->cmd
.statemove
->end_state
);
672 tap_set_end_state(cmd
->cmd
.statemove
->end_state
);
674 openjtag_set_state(cmd
->cmd
.statemove
->end_state
);
676 tap_set_state(tap_get_end_state());
680 static void openjtag_execute_scan(struct jtag_command
*cmd
)
683 int scan_size
, old_state
;
686 DEBUG_JTAG_IO("scan ends in %s", tap_state_name(cmd
->cmd
.scan
->end_state
));
689 tap_set_end_state(cmd
->cmd
.scan
->end_state
);
690 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
692 #ifdef _DEBUG_USB_COMMS_
693 openjtag_debug_buffer(buffer
, (scan_size
+ 7) / 8, DEBUG_TYPE_BUFFER
);
696 old_state
= tap_get_end_state();
697 openjtag_set_state(cmd
->cmd
.scan
->ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
698 tap_set_state(cmd
->cmd
.scan
->ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
699 tap_set_end_state(old_state
);
701 openjtag_add_scan(buffer
, scan_size
, cmd
->cmd
.scan
);
703 openjtag_set_state(cmd
->cmd
.scan
->ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
704 tap_set_state(cmd
->cmd
.scan
->ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
706 if (tap_get_state() != tap_get_end_state()) {
707 openjtag_set_state(tap_get_end_state());
708 tap_set_state(tap_get_end_state());
712 static void openjtag_execute_runtest(struct jtag_command
*cmd
)
715 tap_state_t end_state
= cmd
->cmd
.runtest
->end_state
;
716 tap_set_end_state(end_state
);
718 /* only do a state_move when we're not already in IDLE */
719 if (tap_get_state() != TAP_IDLE
) {
720 openjtag_set_state(TAP_IDLE
);
721 tap_set_state(TAP_IDLE
);
724 if (cmd
->cmd
.runtest
->num_cycles
> 16)
725 LOG_WARNING("num_cycles > 16 on run test");
729 command
|= ((cmd
->cmd
.runtest
->num_cycles
- 1) & 0x0F) << 4;
731 openjtag_add_byte(command
);
733 tap_set_end_state(end_state
);
734 if (tap_get_end_state() != tap_get_state()) {
735 openjtag_set_state(end_state
);
736 tap_set_state(end_state
);
740 static void openjtag_execute_command(struct jtag_command
*cmd
)
742 DEBUG_JTAG_IO("openjtag_execute_command %i", cmd
->type
);
745 openjtag_execute_reset(cmd
);
748 openjtag_execute_sleep(cmd
);
751 openjtag_execute_statemove(cmd
);
754 openjtag_execute_scan(cmd
);
757 openjtag_execute_runtest(cmd
);
760 /* jlink_execute_pathmove(cmd); break; */
762 LOG_ERROR("BUG: unknown Open JTAG command type encountered");
767 static int openjtag_execute_queue(void)
769 struct jtag_command
*cmd
= jtag_command_queue
;
771 while (cmd
!= NULL
) {
772 openjtag_execute_command(cmd
);
776 return openjtag_execute_tap_queue();
779 static int openjtag_speed_div(int speed
, int *khz
)
786 static int openjtag_khz(int khz
, int *jtag_speed
)
791 else if (khz
>= 24000)
793 else if (khz
>= 12000)
795 else if (khz
>= 6000)
797 else if (khz
>= 3000)
799 else if (khz
>= 1500)
809 COMMAND_HANDLER(openjtag_handle_device_desc_command
)
812 openjtag_device_desc
= strdup(CMD_ARGV
[0]);
814 LOG_ERROR("require exactly one argument to "
815 "openjtag_device_desc <description>");
820 static const struct command_registration openjtag_command_handlers
[] = {
822 .name
= "openjtag_device_desc",
823 .handler
= openjtag_handle_device_desc_command
,
824 .mode
= COMMAND_CONFIG
,
825 .help
= "set the USB device description of the OpenJTAG",
826 .usage
= "description-string",
828 COMMAND_REGISTRATION_DONE
831 struct jtag_interface openjtag_interface
= {
833 .commands
= openjtag_command_handlers
,
835 .execute_queue
= openjtag_execute_queue
,
836 .speed
= openjtag_speed
,
837 .speed_div
= openjtag_speed_div
,
839 .init
= openjtag_init
,
840 .quit
= openjtag_quit
,
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)