1 /*******************************************************************************
2 * Driver for OpenJTAG Project (www.openjtag.org) *
3 * Compatible with libftdi and ftd2xx drivers. *
5 * Cypress CY7C65215 support *
6 * Copyright (C) 2015 Vianney le Clément de Saint-Marcq, Essensium NV *
7 * <vianney.leclement@essensium.com> *
9 * Copyright (C) 2010 by Ivan Meleca <mileca@gmail.com> *
11 * Copyright (C) 2013 by Ryan Corbin, GlueLogix Inc. <corbin.ryan@gmail.com> *
12 * Updated to work with OpenOCD v0.7.0. Fixed libftdi read speed issue. *
14 * Based on usb_blaster.c *
15 * Copyright (C) 2009 Catalin Patulea *
16 * Copyright (C) 2006 Kolja Waschk *
19 * Copyright (C) 2008 by Spencer Oliver *
20 * spen@spen-soft.co.uk *
22 * This program is free software; you can redistribute it and/or modify *
23 * it under the terms of the GNU General Public License as published by *
24 * the Free Software Foundation; either version 2 of the License, or *
25 * (at your option) any later version. *
27 * This program is distributed in the hope that it will be useful, *
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
30 * GNU General Public License for more details. *
32 * You should have received a copy of the GNU General Public License *
33 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
34 ***************************************************************************/
36 /***************************************************************************
37 * Version 1.0 Tested on a MCBSTM32 board using a Cortex-M3 (stm32f103x), *
38 * GDB and Eclipse under Linux (Ubuntu 10.04) *
40 ***************************************************************************/
46 #include <jtag/interface.h>
47 #include <jtag/commands.h>
48 #include "libusb_common.h"
51 OPENJTAG_VARIANT_STANDARD
,
52 OPENJTAG_VARIANT_CY7C65215
,
53 } openjtag_variant
= OPENJTAG_VARIANT_STANDARD
;
55 static const char * const openjtag_variant_names
[] = {
62 * OpenJTAG-OpenOCD state conversion
64 typedef enum openjtag_tap_state
{
65 OPENJTAG_TAP_INVALID
= -1,
66 OPENJTAG_TAP_RESET
= 0,
67 OPENJTAG_TAP_IDLE
= 1,
68 OPENJTAG_TAP_SELECT_DR
= 2,
69 OPENJTAG_TAP_CAPTURE_DR
= 3,
70 OPENJTAG_TAP_SHIFT_DR
= 4,
71 OPENJTAG_TAP_EXIT1_DR
= 5,
72 OPENJTAG_TAP_PAUSE_DR
= 6,
73 OPENJTAG_TAP_EXIT2_DR
= 7,
74 OPENJTAG_TAP_UPDATE_DR
= 8,
75 OPENJTAG_TAP_SELECT_IR
= 9,
76 OPENJTAG_TAP_CAPURE_IR
= 10,
77 OPENJTAG_TAP_SHIFT_IR
= 11,
78 OPENJTAG_TAP_EXIT1_IR
= 12,
79 OPENJTAG_TAP_PAUSE_IR
= 13,
80 OPENJTAG_TAP_EXIT2_IR
= 14,
81 OPENJTAG_TAP_UPDATE_IR
= 15,
82 } openjtag_tap_state_t
;
84 /* OPENJTAG access library includes */
87 /* OpenJTAG vid/pid */
88 static uint16_t openjtag_vid
= 0x0403;
89 static uint16_t openjtag_pid
= 0x6001;
91 static char *openjtag_device_desc
;
93 static struct ftdi_context ftdic
;
95 #define OPENJTAG_BUFFER_SIZE 504
96 #define OPENJTAG_MAX_PENDING_RESULTS 256
98 struct openjtag_scan_result
{
99 uint32_t bits
; /* Length in bits*/
100 struct scan_command
*command
; /* Corresponding scan command */
104 /* USB RX/TX buffers */
105 static int usb_tx_buf_offs
;
106 static uint8_t usb_tx_buf
[OPENJTAG_BUFFER_SIZE
];
107 static uint32_t usb_rx_buf_len
;
108 static uint8_t usb_rx_buf
[OPENJTAG_BUFFER_SIZE
];
110 /* Pending readings */
111 static struct openjtag_scan_result openjtag_scan_result_buffer
[OPENJTAG_MAX_PENDING_RESULTS
];
112 static int openjtag_scan_result_count
;
114 static jtag_libusb_device_handle
*usbh
;
116 /* CY7C65215 model only */
117 #define CY7C65215_JTAG_REQUEST 0x40 /* bmRequestType: vendor host-to-device */
118 #define CY7C65215_JTAG_ENABLE 0xD0 /* bRequest: enable JTAG */
119 #define CY7C65215_JTAG_DISABLE 0xD1 /* bRequest: disable JTAG */
120 #define CY7C65215_JTAG_READ 0xD2 /* bRequest: read buffer */
121 #define CY7C65215_JTAG_WRITE 0xD3 /* bRequest: write buffer */
123 #define CY7C65215_USB_TIMEOUT 100
125 static const uint16_t cy7c65215_vids
[] = {0x04b4, 0};
126 static const uint16_t cy7c65215_pids
[] = {0x0007, 0};
128 #define CY7C65215_JTAG_CLASS 0xff
129 #define CY7C65215_JTAG_SUBCLASS 0x04
131 static unsigned int ep_in
, ep_out
;
133 #ifdef _DEBUG_USB_COMMS_
135 #define DEBUG_TYPE_READ 0
136 #define DEBUG_TYPE_WRITE 1
137 #define DEBUG_TYPE_OCD_READ 2
138 #define DEBUG_TYPE_BUFFER 3
141 static void openjtag_debug_buffer(uint8_t *buffer
, int length
, uint8_t type
)
149 case DEBUG_TYPE_READ
:
150 sprintf(line
, "USB READ %d bytes", length
);
152 case DEBUG_TYPE_WRITE
:
153 sprintf(line
, "USB WRITE %d bytes", length
);
155 case DEBUG_TYPE_OCD_READ
:
156 sprintf(line
, "TO OpenOCD %d bytes", length
);
158 case DEBUG_TYPE_BUFFER
:
159 sprintf(line
, "Buffer %d bytes", length
);
163 LOG_DEBUG("%s", line
);
165 for (i
= 0; i
< length
; i
+= LINE_LEN
) {
167 case DEBUG_TYPE_READ
:
168 sprintf(line
, "USB READ: %04x", i
);
170 case DEBUG_TYPE_WRITE
:
171 sprintf(line
, "USB WRITE: %04x", i
);
173 case DEBUG_TYPE_OCD_READ
:
174 sprintf(line
, "TO OpenOCD: %04x", i
);
176 case DEBUG_TYPE_BUFFER
:
177 sprintf(line
, "BUFFER: %04x", i
);
181 for (j
= i
; j
< i
+ LINE_LEN
&& j
< length
; j
++) {
182 sprintf(s
, " %02x", buffer
[j
]);
185 LOG_DEBUG("%s", line
);
192 static int8_t openjtag_get_tap_state(int8_t state
)
196 case TAP_DREXIT2
: return OPENJTAG_TAP_EXIT2_DR
;
197 case TAP_DREXIT1
: return OPENJTAG_TAP_EXIT1_DR
;
198 case TAP_DRSHIFT
: return OPENJTAG_TAP_SHIFT_DR
;
199 case TAP_DRPAUSE
: return OPENJTAG_TAP_PAUSE_DR
;
200 case TAP_IRSELECT
: return OPENJTAG_TAP_SELECT_IR
;
201 case TAP_DRUPDATE
: return OPENJTAG_TAP_UPDATE_DR
;
202 case TAP_DRCAPTURE
: return OPENJTAG_TAP_CAPTURE_DR
;
203 case TAP_DRSELECT
: return OPENJTAG_TAP_SELECT_DR
;
204 case TAP_IREXIT2
: return OPENJTAG_TAP_EXIT2_IR
;
205 case TAP_IREXIT1
: return OPENJTAG_TAP_EXIT1_IR
;
206 case TAP_IRSHIFT
: return OPENJTAG_TAP_SHIFT_IR
;
207 case TAP_IRPAUSE
: return OPENJTAG_TAP_PAUSE_IR
;
208 case TAP_IDLE
: return OPENJTAG_TAP_IDLE
;
209 case TAP_IRUPDATE
: return OPENJTAG_TAP_UPDATE_IR
;
210 case TAP_IRCAPTURE
: return OPENJTAG_TAP_CAPURE_IR
;
211 case TAP_RESET
: return OPENJTAG_TAP_RESET
;
213 default: return OPENJTAG_TAP_INVALID
;
217 static int openjtag_buf_write_standard(
218 uint8_t *buf
, int size
, uint32_t *bytes_written
)
221 #ifdef _DEBUG_USB_COMMS_
222 openjtag_debug_buffer(buf
, size
, DEBUG_TYPE_WRITE
);
225 retval
= ftdi_write_data(&ftdic
, buf
, size
);
228 LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&ftdic
));
229 return ERROR_JTAG_DEVICE_ERROR
;
232 *bytes_written
+= retval
;
237 static int openjtag_buf_write_cy7c65215(
238 uint8_t *buf
, int size
, uint32_t *bytes_written
)
242 #ifdef _DEBUG_USB_COMMS_
243 openjtag_debug_buffer(buf
, size
, DEBUG_TYPE_WRITE
);
251 ret
= jtag_libusb_control_transfer(usbh
, CY7C65215_JTAG_REQUEST
,
252 CY7C65215_JTAG_WRITE
, size
, 0,
253 NULL
, 0, CY7C65215_USB_TIMEOUT
);
255 LOG_ERROR("vendor command failed, error %d", ret
);
256 return ERROR_JTAG_DEVICE_ERROR
;
259 ret
= jtag_libusb_bulk_write(usbh
, ep_out
, (char *)buf
, size
,
260 CY7C65215_USB_TIMEOUT
);
262 LOG_ERROR("bulk write failed, error %d", ret
);
263 return ERROR_JTAG_DEVICE_ERROR
;
265 *bytes_written
= ret
;
270 static int openjtag_buf_write(
271 uint8_t *buf
, int size
, uint32_t *bytes_written
)
273 switch (openjtag_variant
) {
274 case OPENJTAG_VARIANT_CY7C65215
:
275 return openjtag_buf_write_cy7c65215(buf
, size
, bytes_written
);
277 return openjtag_buf_write_standard(buf
, size
, bytes_written
);
281 static int openjtag_buf_read_standard(
282 uint8_t *buf
, uint32_t qty
, uint32_t *bytes_read
)
290 while ((*bytes_read
< qty
) && timeout
--) {
291 retval
= ftdi_read_data(&ftdic
, buf
+ *bytes_read
,
295 LOG_DEBUG_IO("ftdi_read_data: %s",
296 ftdi_get_error_string(&ftdic
));
297 return ERROR_JTAG_DEVICE_ERROR
;
299 *bytes_read
+= retval
;
302 #ifdef _DEBUG_USB_COMMS_
303 openjtag_debug_buffer(buf
, *bytes_read
, DEBUG_TYPE_READ
);
309 static int openjtag_buf_read_cy7c65215(
310 uint8_t *buf
, uint32_t qty
, uint32_t *bytes_read
)
319 ret
= jtag_libusb_control_transfer(usbh
, CY7C65215_JTAG_REQUEST
,
320 CY7C65215_JTAG_READ
, qty
, 0,
321 NULL
, 0, CY7C65215_USB_TIMEOUT
);
323 LOG_ERROR("vendor command failed, error %d", ret
);
324 return ERROR_JTAG_DEVICE_ERROR
;
327 ret
= jtag_libusb_bulk_read(usbh
, ep_in
, (char *)buf
, qty
,
328 CY7C65215_USB_TIMEOUT
);
330 LOG_ERROR("bulk read failed, error %d", ret
);
331 return ERROR_JTAG_DEVICE_ERROR
;
336 #ifdef _DEBUG_USB_COMMS_
337 openjtag_debug_buffer(buf
, *bytes_read
, DEBUG_TYPE_READ
);
343 static int openjtag_buf_read(uint8_t *buf
, uint32_t qty
, uint32_t *bytes_read
)
345 switch (openjtag_variant
) {
346 case OPENJTAG_VARIANT_CY7C65215
:
347 return openjtag_buf_read_cy7c65215(buf
, qty
, bytes_read
);
349 return openjtag_buf_read_standard(buf
, qty
, bytes_read
);
353 static int openjtag_sendcommand(uint8_t cmd
)
356 return openjtag_buf_write(&cmd
, 1, &written
);
359 static int openjtag_speed(int speed
)
389 LOG_WARNING("adapter speed not recognized, reverting to 375 kHz");
392 openjtag_sendcommand(clockcmd
);
397 static int openjtag_init_standard(void)
399 uint8_t latency_timer
;
401 /* Open by device description */
402 if (openjtag_device_desc
== NULL
) {
403 LOG_WARNING("no openjtag device description specified, "
404 "using default 'Open JTAG Project'");
405 openjtag_device_desc
= "Open JTAG Project";
408 if (ftdi_init(&ftdic
) < 0)
409 return ERROR_JTAG_INIT_FAILED
;
411 /* context, vendor id, product id, description, serial id */
412 if (ftdi_usb_open_desc(&ftdic
, openjtag_vid
, openjtag_pid
, openjtag_device_desc
, NULL
) < 0) {
413 LOG_ERROR("unable to open ftdi device: %s", ftdic
.error_str
);
414 return ERROR_JTAG_INIT_FAILED
;
417 if (ftdi_usb_reset(&ftdic
) < 0) {
418 LOG_ERROR("unable to reset ftdi device");
419 return ERROR_JTAG_INIT_FAILED
;
422 if (ftdi_set_latency_timer(&ftdic
, 2) < 0) {
423 LOG_ERROR("unable to set latency timer");
424 return ERROR_JTAG_INIT_FAILED
;
427 if (ftdi_get_latency_timer(&ftdic
, &latency_timer
) < 0) {
428 LOG_ERROR("unable to get latency timer");
429 return ERROR_JTAG_INIT_FAILED
;
431 LOG_DEBUG("current latency timer: %u", latency_timer
);
433 ftdi_disable_bitbang(&ftdic
);
434 /* was (3000000 / 4) with a comment about a bug in libftdi when using high baudrate */
435 if (ftdi_set_baudrate(&ftdic
, 3000000) < 0) {
436 LOG_ERROR("Can't set baud rate to max: %s",
437 ftdi_get_error_string(&ftdic
));
438 return ERROR_JTAG_DEVICE_ERROR
;
441 if (ftdi_usb_purge_buffers(&ftdic
) < 0) {
442 LOG_ERROR("ftdi_purge_buffers: %s", ftdic
.error_str
);
443 return ERROR_JTAG_INIT_FAILED
;
449 static int openjtag_init_cy7c65215(void)
454 ret
= jtag_libusb_open(cy7c65215_vids
, cy7c65215_pids
, NULL
, &usbh
);
455 if (ret
!= ERROR_OK
) {
456 LOG_ERROR("unable to open cy7c65215 device");
460 ret
= jtag_libusb_choose_interface(usbh
, &ep_in
, &ep_out
,
461 CY7C65215_JTAG_CLASS
,
462 CY7C65215_JTAG_SUBCLASS
, -1, LIBUSB_TRANSFER_TYPE_BULK
);
463 if (ret
!= ERROR_OK
) {
464 LOG_ERROR("unable to claim JTAG interface");
468 ret
= jtag_libusb_control_transfer(usbh
,
469 CY7C65215_JTAG_REQUEST
,
470 CY7C65215_JTAG_ENABLE
,
471 0, 0, NULL
, 0, CY7C65215_USB_TIMEOUT
);
473 LOG_ERROR("could not enable JTAG module");
481 jtag_libusb_close(usbh
);
482 return ERROR_JTAG_INIT_FAILED
;
485 static int openjtag_init(void)
491 openjtag_scan_result_count
= 0;
493 switch (openjtag_variant
) {
494 case OPENJTAG_VARIANT_CY7C65215
:
495 ret
= openjtag_init_cy7c65215();
498 ret
= openjtag_init_standard();
503 openjtag_speed(375); /* Start at slowest adapter speed */
504 openjtag_sendcommand(0x75); /* MSB */
509 static int openjtag_quit_standard(void)
511 ftdi_usb_close(&ftdic
);
517 static int openjtag_quit_cy7c65215(void)
521 ret
= jtag_libusb_control_transfer(usbh
,
522 CY7C65215_JTAG_REQUEST
,
523 CY7C65215_JTAG_DISABLE
,
524 0, 0, NULL
, 0, CY7C65215_USB_TIMEOUT
);
526 LOG_WARNING("could not disable JTAG module");
528 jtag_libusb_close(usbh
);
533 static int openjtag_quit(void)
535 switch (openjtag_variant
) {
536 case OPENJTAG_VARIANT_CY7C65215
:
537 return openjtag_quit_cy7c65215();
539 return openjtag_quit_standard();
543 static void openjtag_write_tap_buffer(void)
547 openjtag_buf_write(usb_tx_buf
, usb_tx_buf_offs
, &written
);
548 openjtag_buf_read(usb_rx_buf
, usb_tx_buf_offs
, &usb_rx_buf_len
);
553 static int openjtag_execute_tap_queue(void)
555 openjtag_write_tap_buffer();
559 if (openjtag_scan_result_count
&& usb_rx_buf_len
) {
565 /* for every pending result */
566 while (res_count
< openjtag_scan_result_count
) {
569 len
= openjtag_scan_result_buffer
[res_count
].bits
;
573 uint8_t *buffer
= openjtag_scan_result_buffer
[res_count
].buffer
;
576 if (len
<= 8 && openjtag_variant
!= OPENJTAG_VARIANT_CY7C65215
) {
577 LOG_DEBUG_IO("bits < 8 buf = 0x%X, will be 0x%X",
578 usb_rx_buf
[rx_offs
], usb_rx_buf
[rx_offs
] >> (8 - len
));
579 buffer
[count
] = usb_rx_buf
[rx_offs
] >> (8 - len
);
582 buffer
[count
] = usb_rx_buf
[rx_offs
];
590 #ifdef _DEBUG_USB_COMMS_
591 openjtag_debug_buffer(buffer
,
592 DIV_ROUND_UP(openjtag_scan_result_buffer
[res_count
].bits
, 8), DEBUG_TYPE_OCD_READ
);
594 jtag_read_buffer(buffer
, openjtag_scan_result_buffer
[res_count
].command
);
596 if (openjtag_scan_result_buffer
[res_count
].buffer
)
597 free(openjtag_scan_result_buffer
[res_count
].buffer
);
603 openjtag_scan_result_count
= 0;
608 static void openjtag_add_byte(char buf
)
611 if (usb_tx_buf_offs
== OPENJTAG_BUFFER_SIZE
) {
612 LOG_DEBUG_IO("Forcing execute_tap_queue");
613 LOG_DEBUG_IO("TX Buff offs=%d", usb_tx_buf_offs
);
614 openjtag_execute_tap_queue();
617 usb_tx_buf
[usb_tx_buf_offs
] = buf
;
621 static void openjtag_add_scan(uint8_t *buffer
, int length
, struct scan_command
*scan_cmd
)
624 /* Ensure space to send long chains */
625 /* We add two byte for each eight (or less) bits, one for command, one for data */
626 if (usb_tx_buf_offs
+ (DIV_ROUND_UP(length
, 8) * 2) >= OPENJTAG_BUFFER_SIZE
) {
627 LOG_DEBUG_IO("Forcing execute_tap_queue from scan");
628 LOG_DEBUG_IO("TX Buff offs=%d len=%d", usb_tx_buf_offs
, DIV_ROUND_UP(length
, 8) * 2);
629 openjtag_execute_tap_queue();
632 openjtag_scan_result_buffer
[openjtag_scan_result_count
].bits
= length
;
633 openjtag_scan_result_buffer
[openjtag_scan_result_count
].command
= scan_cmd
;
634 openjtag_scan_result_buffer
[openjtag_scan_result_count
].buffer
= buffer
;
649 /* bits to transfer */
651 command
|= bits
<< 5;
656 /* bits to transfer */
662 openjtag_add_byte(command
);
663 openjtag_add_byte(buffer
[count
]);
667 openjtag_scan_result_count
++;
670 static void openjtag_execute_reset(struct jtag_command
*cmd
)
673 LOG_DEBUG_IO("reset trst: %i srst %i",
674 cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
678 if (cmd
->cmd
.reset
->trst
) {
685 openjtag_add_byte(buf
);
688 static void openjtag_execute_sleep(struct jtag_command
*cmd
)
690 jtag_sleep(cmd
->cmd
.sleep
->us
);
693 static void openjtag_set_state(uint8_t openocd_state
)
695 int8_t state
= openjtag_get_tap_state(openocd_state
);
701 openjtag_add_byte(buf
);
704 static void openjtag_execute_statemove(struct jtag_command
*cmd
)
706 LOG_DEBUG_IO("state move to %i", cmd
->cmd
.statemove
->end_state
);
708 tap_set_end_state(cmd
->cmd
.statemove
->end_state
);
710 openjtag_set_state(cmd
->cmd
.statemove
->end_state
);
712 tap_set_state(tap_get_end_state());
716 static void openjtag_execute_scan(struct jtag_command
*cmd
)
719 int scan_size
, old_state
;
722 LOG_DEBUG_IO("scan ends in %s", tap_state_name(cmd
->cmd
.scan
->end_state
));
725 tap_set_end_state(cmd
->cmd
.scan
->end_state
);
726 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
728 #ifdef _DEBUG_USB_COMMS_
729 openjtag_debug_buffer(buffer
, (scan_size
+ 7) / 8, DEBUG_TYPE_BUFFER
);
732 old_state
= tap_get_end_state();
733 openjtag_set_state(cmd
->cmd
.scan
->ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
734 tap_set_state(cmd
->cmd
.scan
->ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
735 tap_set_end_state(old_state
);
737 openjtag_add_scan(buffer
, scan_size
, cmd
->cmd
.scan
);
739 openjtag_set_state(cmd
->cmd
.scan
->ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
740 tap_set_state(cmd
->cmd
.scan
->ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
742 if (tap_get_state() != tap_get_end_state()) {
743 openjtag_set_state(tap_get_end_state());
744 tap_set_state(tap_get_end_state());
748 static void openjtag_execute_runtest(struct jtag_command
*cmd
)
751 tap_state_t end_state
= cmd
->cmd
.runtest
->end_state
;
752 tap_set_end_state(end_state
);
754 /* only do a state_move when we're not already in IDLE */
755 if (tap_get_state() != TAP_IDLE
) {
756 openjtag_set_state(TAP_IDLE
);
757 tap_set_state(TAP_IDLE
);
760 if (cmd
->cmd
.runtest
->num_cycles
> 16)
761 LOG_WARNING("num_cycles > 16 on run test");
763 if (openjtag_variant
!= OPENJTAG_VARIANT_CY7C65215
||
764 cmd
->cmd
.runtest
->num_cycles
) {
767 command
|= ((cmd
->cmd
.runtest
->num_cycles
- 1) & 0x0F) << 4;
769 openjtag_add_byte(command
);
772 tap_set_end_state(end_state
);
773 if (tap_get_end_state() != tap_get_state()) {
774 openjtag_set_state(end_state
);
775 tap_set_state(end_state
);
779 static void openjtag_execute_command(struct jtag_command
*cmd
)
781 LOG_DEBUG_IO("openjtag_execute_command %i", cmd
->type
);
784 openjtag_execute_reset(cmd
);
787 openjtag_execute_sleep(cmd
);
790 openjtag_execute_statemove(cmd
);
793 openjtag_execute_scan(cmd
);
796 openjtag_execute_runtest(cmd
);
799 /* jlink_execute_pathmove(cmd); break; */
801 LOG_ERROR("BUG: unknown Open JTAG command type encountered");
806 static int openjtag_execute_queue(void)
808 struct jtag_command
*cmd
= jtag_command_queue
;
810 while (cmd
!= NULL
) {
811 openjtag_execute_command(cmd
);
815 return openjtag_execute_tap_queue();
818 static int openjtag_speed_div(int speed
, int *khz
)
825 static int openjtag_khz(int khz
, int *jtag_speed
)
830 else if (khz
>= 24000)
832 else if (khz
>= 12000)
834 else if (khz
>= 6000)
836 else if (khz
>= 3000)
838 else if (khz
>= 1500)
848 COMMAND_HANDLER(openjtag_handle_device_desc_command
)
851 openjtag_device_desc
= strdup(CMD_ARGV
[0]);
853 LOG_ERROR("require exactly one argument to "
854 "openjtag_device_desc <description>");
858 COMMAND_HANDLER(openjtag_handle_variant_command
)
861 const char * const *name
= openjtag_variant_names
;
863 for (; *name
; name
++, variant
++) {
864 if (strcasecmp(CMD_ARGV
[0], *name
) == 0) {
865 openjtag_variant
= variant
;
869 LOG_ERROR("unknown openjtag variant '%s'", CMD_ARGV
[0]);
871 LOG_ERROR("require exactly one argument to "
872 "openjtag_variant <variant>");
877 static const struct command_registration openjtag_command_handlers
[] = {
879 .name
= "openjtag_device_desc",
880 .handler
= openjtag_handle_device_desc_command
,
881 .mode
= COMMAND_CONFIG
,
882 .help
= "set the USB device description of the OpenJTAG",
883 .usage
= "description-string",
886 .name
= "openjtag_variant",
887 .handler
= openjtag_handle_variant_command
,
888 .mode
= COMMAND_CONFIG
,
889 .help
= "set the OpenJTAG variant",
890 .usage
= "variant-string",
892 COMMAND_REGISTRATION_DONE
895 static struct jtag_interface openjtag_interface
= {
896 .execute_queue
= openjtag_execute_queue
,
899 struct adapter_driver openjtag_adapter_driver
= {
901 .transports
= jtag_only
,
902 .commands
= openjtag_command_handlers
,
904 .init
= openjtag_init
,
905 .quit
= openjtag_quit
,
906 .speed
= openjtag_speed
,
908 .speed_div
= openjtag_speed_div
,
910 .jtag_ops
= &openjtag_interface
,
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)