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_helper.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 struct 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 if (jtag_libusb_bulk_write(usbh
, ep_out
, (char *)buf
, size
,
260 CY7C65215_USB_TIMEOUT
, &ret
)) {
261 LOG_ERROR("bulk write failed, error");
262 return ERROR_JTAG_DEVICE_ERROR
;
264 *bytes_written
= ret
;
269 static int openjtag_buf_write(
270 uint8_t *buf
, int size
, uint32_t *bytes_written
)
272 switch (openjtag_variant
) {
273 case OPENJTAG_VARIANT_CY7C65215
:
274 return openjtag_buf_write_cy7c65215(buf
, size
, bytes_written
);
276 return openjtag_buf_write_standard(buf
, size
, bytes_written
);
280 static int openjtag_buf_read_standard(
281 uint8_t *buf
, uint32_t qty
, uint32_t *bytes_read
)
289 while ((*bytes_read
< qty
) && timeout
--) {
290 retval
= ftdi_read_data(&ftdic
, buf
+ *bytes_read
,
294 LOG_DEBUG_IO("ftdi_read_data: %s",
295 ftdi_get_error_string(&ftdic
));
296 return ERROR_JTAG_DEVICE_ERROR
;
298 *bytes_read
+= retval
;
301 #ifdef _DEBUG_USB_COMMS_
302 openjtag_debug_buffer(buf
, *bytes_read
, DEBUG_TYPE_READ
);
308 static int openjtag_buf_read_cy7c65215(
309 uint8_t *buf
, uint32_t qty
, uint32_t *bytes_read
)
318 ret
= jtag_libusb_control_transfer(usbh
, CY7C65215_JTAG_REQUEST
,
319 CY7C65215_JTAG_READ
, qty
, 0,
320 NULL
, 0, CY7C65215_USB_TIMEOUT
);
322 LOG_ERROR("vendor command failed, error %d", ret
);
323 return ERROR_JTAG_DEVICE_ERROR
;
326 if (jtag_libusb_bulk_read(usbh
, ep_in
, (char *)buf
, qty
,
327 CY7C65215_USB_TIMEOUT
, &ret
)) {
328 LOG_ERROR("bulk read failed, error");
329 return ERROR_JTAG_DEVICE_ERROR
;
334 #ifdef _DEBUG_USB_COMMS_
335 openjtag_debug_buffer(buf
, *bytes_read
, DEBUG_TYPE_READ
);
341 static int openjtag_buf_read(uint8_t *buf
, uint32_t qty
, uint32_t *bytes_read
)
343 switch (openjtag_variant
) {
344 case OPENJTAG_VARIANT_CY7C65215
:
345 return openjtag_buf_read_cy7c65215(buf
, qty
, bytes_read
);
347 return openjtag_buf_read_standard(buf
, qty
, bytes_read
);
351 static int openjtag_sendcommand(uint8_t cmd
)
354 return openjtag_buf_write(&cmd
, 1, &written
);
357 static int openjtag_speed(int speed
)
387 LOG_WARNING("adapter speed not recognized, reverting to 375 kHz");
390 openjtag_sendcommand(clockcmd
);
395 static int openjtag_init_standard(void)
397 uint8_t latency_timer
;
399 /* Open by device description */
400 if (openjtag_device_desc
== NULL
) {
401 LOG_WARNING("no openjtag device description specified, "
402 "using default 'Open JTAG Project'");
403 openjtag_device_desc
= "Open JTAG Project";
406 if (ftdi_init(&ftdic
) < 0)
407 return ERROR_JTAG_INIT_FAILED
;
409 /* context, vendor id, product id, description, serial id */
410 if (ftdi_usb_open_desc(&ftdic
, openjtag_vid
, openjtag_pid
, openjtag_device_desc
, NULL
) < 0) {
411 LOG_ERROR("unable to open ftdi device: %s", ftdic
.error_str
);
412 return ERROR_JTAG_INIT_FAILED
;
415 if (ftdi_usb_reset(&ftdic
) < 0) {
416 LOG_ERROR("unable to reset ftdi device");
417 return ERROR_JTAG_INIT_FAILED
;
420 if (ftdi_set_latency_timer(&ftdic
, 2) < 0) {
421 LOG_ERROR("unable to set latency timer");
422 return ERROR_JTAG_INIT_FAILED
;
425 if (ftdi_get_latency_timer(&ftdic
, &latency_timer
) < 0) {
426 LOG_ERROR("unable to get latency timer");
427 return ERROR_JTAG_INIT_FAILED
;
429 LOG_DEBUG("current latency timer: %u", latency_timer
);
431 ftdi_disable_bitbang(&ftdic
);
432 /* was (3000000 / 4) with a comment about a bug in libftdi when using high baudrate */
433 if (ftdi_set_baudrate(&ftdic
, 3000000) < 0) {
434 LOG_ERROR("Can't set baud rate to max: %s",
435 ftdi_get_error_string(&ftdic
));
436 return ERROR_JTAG_DEVICE_ERROR
;
439 if (ftdi_usb_purge_buffers(&ftdic
) < 0) {
440 LOG_ERROR("ftdi_purge_buffers: %s", ftdic
.error_str
);
441 return ERROR_JTAG_INIT_FAILED
;
447 static int openjtag_init_cy7c65215(void)
452 ret
= jtag_libusb_open(cy7c65215_vids
, cy7c65215_pids
, NULL
, &usbh
);
453 if (ret
!= ERROR_OK
) {
454 LOG_ERROR("unable to open cy7c65215 device");
458 ret
= jtag_libusb_choose_interface(usbh
, &ep_in
, &ep_out
,
459 CY7C65215_JTAG_CLASS
,
460 CY7C65215_JTAG_SUBCLASS
, -1, LIBUSB_TRANSFER_TYPE_BULK
);
461 if (ret
!= ERROR_OK
) {
462 LOG_ERROR("unable to claim JTAG interface");
466 ret
= jtag_libusb_control_transfer(usbh
,
467 CY7C65215_JTAG_REQUEST
,
468 CY7C65215_JTAG_ENABLE
,
469 0, 0, NULL
, 0, CY7C65215_USB_TIMEOUT
);
471 LOG_ERROR("could not enable JTAG module");
479 jtag_libusb_close(usbh
);
480 return ERROR_JTAG_INIT_FAILED
;
483 static int openjtag_init(void)
489 openjtag_scan_result_count
= 0;
491 switch (openjtag_variant
) {
492 case OPENJTAG_VARIANT_CY7C65215
:
493 ret
= openjtag_init_cy7c65215();
496 ret
= openjtag_init_standard();
501 openjtag_speed(375); /* Start at slowest adapter speed */
502 openjtag_sendcommand(0x75); /* MSB */
507 static int openjtag_quit_standard(void)
509 ftdi_usb_close(&ftdic
);
515 static int openjtag_quit_cy7c65215(void)
519 ret
= jtag_libusb_control_transfer(usbh
,
520 CY7C65215_JTAG_REQUEST
,
521 CY7C65215_JTAG_DISABLE
,
522 0, 0, NULL
, 0, CY7C65215_USB_TIMEOUT
);
524 LOG_WARNING("could not disable JTAG module");
526 jtag_libusb_close(usbh
);
531 static int openjtag_quit(void)
533 switch (openjtag_variant
) {
534 case OPENJTAG_VARIANT_CY7C65215
:
535 return openjtag_quit_cy7c65215();
537 return openjtag_quit_standard();
541 static void openjtag_write_tap_buffer(void)
545 openjtag_buf_write(usb_tx_buf
, usb_tx_buf_offs
, &written
);
546 openjtag_buf_read(usb_rx_buf
, usb_tx_buf_offs
, &usb_rx_buf_len
);
551 static int openjtag_execute_tap_queue(void)
553 openjtag_write_tap_buffer();
557 if (openjtag_scan_result_count
&& usb_rx_buf_len
) {
563 /* for every pending result */
564 while (res_count
< openjtag_scan_result_count
) {
567 len
= openjtag_scan_result_buffer
[res_count
].bits
;
571 uint8_t *buffer
= openjtag_scan_result_buffer
[res_count
].buffer
;
574 if (len
<= 8 && openjtag_variant
!= OPENJTAG_VARIANT_CY7C65215
) {
575 LOG_DEBUG_IO("bits < 8 buf = 0x%X, will be 0x%X",
576 usb_rx_buf
[rx_offs
], usb_rx_buf
[rx_offs
] >> (8 - len
));
577 buffer
[count
] = usb_rx_buf
[rx_offs
] >> (8 - len
);
580 buffer
[count
] = usb_rx_buf
[rx_offs
];
588 #ifdef _DEBUG_USB_COMMS_
589 openjtag_debug_buffer(buffer
,
590 DIV_ROUND_UP(openjtag_scan_result_buffer
[res_count
].bits
, 8), DEBUG_TYPE_OCD_READ
);
592 jtag_read_buffer(buffer
, openjtag_scan_result_buffer
[res_count
].command
);
594 if (openjtag_scan_result_buffer
[res_count
].buffer
)
595 free(openjtag_scan_result_buffer
[res_count
].buffer
);
601 openjtag_scan_result_count
= 0;
606 static void openjtag_add_byte(char buf
)
609 if (usb_tx_buf_offs
== OPENJTAG_BUFFER_SIZE
) {
610 LOG_DEBUG_IO("Forcing execute_tap_queue");
611 LOG_DEBUG_IO("TX Buff offs=%d", usb_tx_buf_offs
);
612 openjtag_execute_tap_queue();
615 usb_tx_buf
[usb_tx_buf_offs
] = buf
;
619 static void openjtag_add_scan(uint8_t *buffer
, int length
, struct scan_command
*scan_cmd
)
622 /* Ensure space to send long chains */
623 /* We add two byte for each eight (or less) bits, one for command, one for data */
624 if (usb_tx_buf_offs
+ (DIV_ROUND_UP(length
, 8) * 2) >= OPENJTAG_BUFFER_SIZE
) {
625 LOG_DEBUG_IO("Forcing execute_tap_queue from scan");
626 LOG_DEBUG_IO("TX Buff offs=%d len=%d", usb_tx_buf_offs
, DIV_ROUND_UP(length
, 8) * 2);
627 openjtag_execute_tap_queue();
630 openjtag_scan_result_buffer
[openjtag_scan_result_count
].bits
= length
;
631 openjtag_scan_result_buffer
[openjtag_scan_result_count
].command
= scan_cmd
;
632 openjtag_scan_result_buffer
[openjtag_scan_result_count
].buffer
= buffer
;
647 /* bits to transfer */
649 command
|= bits
<< 5;
654 /* bits to transfer */
660 openjtag_add_byte(command
);
661 openjtag_add_byte(buffer
[count
]);
665 openjtag_scan_result_count
++;
668 static void openjtag_execute_reset(struct jtag_command
*cmd
)
671 LOG_DEBUG_IO("reset trst: %i srst %i",
672 cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
676 if (cmd
->cmd
.reset
->trst
) {
683 openjtag_add_byte(buf
);
686 static void openjtag_execute_sleep(struct jtag_command
*cmd
)
688 jtag_sleep(cmd
->cmd
.sleep
->us
);
691 static void openjtag_set_state(uint8_t openocd_state
)
693 int8_t state
= openjtag_get_tap_state(openocd_state
);
699 openjtag_add_byte(buf
);
702 static void openjtag_execute_statemove(struct jtag_command
*cmd
)
704 LOG_DEBUG_IO("state move to %i", cmd
->cmd
.statemove
->end_state
);
706 tap_set_end_state(cmd
->cmd
.statemove
->end_state
);
708 openjtag_set_state(cmd
->cmd
.statemove
->end_state
);
710 tap_set_state(tap_get_end_state());
714 static void openjtag_execute_scan(struct jtag_command
*cmd
)
717 int scan_size
, old_state
;
720 LOG_DEBUG_IO("scan ends in %s", tap_state_name(cmd
->cmd
.scan
->end_state
));
723 tap_set_end_state(cmd
->cmd
.scan
->end_state
);
724 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
726 #ifdef _DEBUG_USB_COMMS_
727 openjtag_debug_buffer(buffer
, (scan_size
+ 7) / 8, DEBUG_TYPE_BUFFER
);
730 old_state
= tap_get_end_state();
731 openjtag_set_state(cmd
->cmd
.scan
->ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
732 tap_set_state(cmd
->cmd
.scan
->ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
733 tap_set_end_state(old_state
);
735 openjtag_add_scan(buffer
, scan_size
, cmd
->cmd
.scan
);
737 openjtag_set_state(cmd
->cmd
.scan
->ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
738 tap_set_state(cmd
->cmd
.scan
->ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
740 if (tap_get_state() != tap_get_end_state()) {
741 openjtag_set_state(tap_get_end_state());
742 tap_set_state(tap_get_end_state());
746 static void openjtag_execute_runtest(struct jtag_command
*cmd
)
749 tap_state_t end_state
= cmd
->cmd
.runtest
->end_state
;
750 tap_set_end_state(end_state
);
752 /* only do a state_move when we're not already in IDLE */
753 if (tap_get_state() != TAP_IDLE
) {
754 openjtag_set_state(TAP_IDLE
);
755 tap_set_state(TAP_IDLE
);
758 if (cmd
->cmd
.runtest
->num_cycles
> 16)
759 LOG_WARNING("num_cycles > 16 on run test");
761 if (openjtag_variant
!= OPENJTAG_VARIANT_CY7C65215
||
762 cmd
->cmd
.runtest
->num_cycles
) {
765 command
|= ((cmd
->cmd
.runtest
->num_cycles
- 1) & 0x0F) << 4;
767 openjtag_add_byte(command
);
770 tap_set_end_state(end_state
);
771 if (tap_get_end_state() != tap_get_state()) {
772 openjtag_set_state(end_state
);
773 tap_set_state(end_state
);
777 static void openjtag_execute_command(struct jtag_command
*cmd
)
779 LOG_DEBUG_IO("openjtag_execute_command %i", cmd
->type
);
782 openjtag_execute_reset(cmd
);
785 openjtag_execute_sleep(cmd
);
788 openjtag_execute_statemove(cmd
);
791 openjtag_execute_scan(cmd
);
794 openjtag_execute_runtest(cmd
);
797 /* jlink_execute_pathmove(cmd); break; */
799 LOG_ERROR("BUG: unknown Open JTAG command type encountered");
804 static int openjtag_execute_queue(void)
806 struct jtag_command
*cmd
= jtag_command_queue
;
808 while (cmd
!= NULL
) {
809 openjtag_execute_command(cmd
);
813 return openjtag_execute_tap_queue();
816 static int openjtag_speed_div(int speed
, int *khz
)
823 static int openjtag_khz(int khz
, int *jtag_speed
)
828 else if (khz
>= 24000)
830 else if (khz
>= 12000)
832 else if (khz
>= 6000)
834 else if (khz
>= 3000)
836 else if (khz
>= 1500)
846 COMMAND_HANDLER(openjtag_handle_device_desc_command
)
849 openjtag_device_desc
= strdup(CMD_ARGV
[0]);
851 LOG_ERROR("require exactly one argument to "
852 "openjtag_device_desc <description>");
856 COMMAND_HANDLER(openjtag_handle_variant_command
)
859 const char * const *name
= openjtag_variant_names
;
861 for (; *name
; name
++, variant
++) {
862 if (strcasecmp(CMD_ARGV
[0], *name
) == 0) {
863 openjtag_variant
= variant
;
867 LOG_ERROR("unknown openjtag variant '%s'", CMD_ARGV
[0]);
869 LOG_ERROR("require exactly one argument to "
870 "openjtag_variant <variant>");
875 static const struct command_registration openjtag_command_handlers
[] = {
877 .name
= "openjtag_device_desc",
878 .handler
= openjtag_handle_device_desc_command
,
879 .mode
= COMMAND_CONFIG
,
880 .help
= "set the USB device description of the OpenJTAG",
881 .usage
= "description-string",
884 .name
= "openjtag_variant",
885 .handler
= openjtag_handle_variant_command
,
886 .mode
= COMMAND_CONFIG
,
887 .help
= "set the OpenJTAG variant",
888 .usage
= "variant-string",
890 COMMAND_REGISTRATION_DONE
893 static struct jtag_interface openjtag_interface
= {
894 .execute_queue
= openjtag_execute_queue
,
897 struct adapter_driver openjtag_adapter_driver
= {
899 .transports
= jtag_only
,
900 .commands
= openjtag_command_handlers
,
902 .init
= openjtag_init
,
903 .quit
= openjtag_quit
,
904 .speed
= openjtag_speed
,
906 .speed_div
= openjtag_speed_div
,
908 .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)