Fix libusb-1.0.22 deprecated libusb_set_debug with libusb_set_option
[openocd.git] / src / jtag / drivers / ft232r.c
1 /***************************************************************************
2 * Copyright (C) 2010 Serge Vakulenko *
3 * serge@vak.ru *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #if IS_CYGWIN == 1
24 #include "windows.h"
25 #undef LOG_ERROR
26 #endif
27
28 /* project specific includes */
29 #include <jtag/interface.h>
30 #include <jtag/commands.h>
31 #include <helper/time_support.h>
32 #include "libusb1_common.h"
33
34 /* system includes */
35 #include <string.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <sys/time.h>
39 #include <time.h>
40
41 /*
42 * Bit 7 (0x80, pin 6, RI ): unused.
43 * Bit 6 (0x40, pin 10,DCD): /SYSRST output.
44 * Bit 5 (0x20, pin 9, DSR): unused.
45 * Bit 4 (0x10, pin 2, DTR): /TRST output.
46 * Bit 3 (0x08, pin 11,CTS): TMS output.
47 * Bit 2 (0x04, pin 3, RTS): TDO input.
48 * Bit 1 (0x02, pin 5, RXD): TDI output.
49 * Bit 0 (0x01, pin 1, TXD): TCK output.
50 *
51 * Sync bit bang mode is implemented as described in FTDI Application
52 * Note AN232R-01: "Bit Bang Modes for the FT232R and FT245R".
53 */
54 #define TCK (1 << 0)
55 #define TDI (1 << 1)
56 #define READ_TDO (1 << 2)
57 #define TMS (1 << 3)
58 #define NTRST (1 << 4)
59 #define NSYSRST (1 << 6)
60
61 /*
62 * USB endpoints.
63 */
64 #define IN_EP 0x02
65 #define OUT_EP 0x81
66
67 /* Requests */
68 #define SIO_RESET 0 /* Reset the port */
69 #define SIO_MODEM_CTRL 1 /* Set the modem control register */
70 #define SIO_SET_FLOW_CTRL 2 /* Set flow control register */
71 #define SIO_SET_BAUD_RATE 3 /* Set baud rate */
72 #define SIO_SET_DATA 4 /* Set the data characteristics of the port */
73 #define SIO_POLL_MODEM_STATUS 5
74 #define SIO_SET_EVENT_CHAR 6
75 #define SIO_SET_ERROR_CHAR 7
76 #define SIO_SET_LATENCY_TIMER 9
77 #define SIO_GET_LATENCY_TIMER 10
78 #define SIO_SET_BITMODE 11
79 #define SIO_READ_PINS 12
80 #define SIO_READ_EEPROM 0x90
81 #define SIO_WRITE_EEPROM 0x91
82 #define SIO_ERASE_EEPROM 0x92
83
84 #define FT232R_BUF_SIZE 4000
85
86 static char *ft232r_serial_desc;
87 static uint16_t ft232r_vid = 0x0403; /* FTDI */
88 static uint16_t ft232r_pid = 0x6001; /* FT232R */
89 static jtag_libusb_device_handle *adapter;
90
91 static uint8_t *ft232r_output;
92 static size_t ft232r_output_len;
93
94 /**
95 * Perform sync bitbang output/input transaction.
96 * Before call, an array ft232r_output[] should be filled with data to send.
97 * Counter ft232r_output_len contains the number of bytes to send.
98 * On return, received data is put back to array ft232r_output[].
99 */
100 static int ft232r_send_recv(void)
101 {
102 /* FIFO TX buffer has 128 bytes.
103 * FIFO RX buffer has 256 bytes.
104 * First two bytes of received packet contain contain modem
105 * and line status and are ignored.
106 * Unfortunately, transfer sizes bigger than 64 bytes
107 * frequently cause hang ups. */
108 assert(ft232r_output_len > 0);
109
110 size_t total_written = 0;
111 size_t total_read = 0;
112 int rxfifo_free = 128;
113
114 while (total_read < ft232r_output_len) {
115 /* Write */
116 int bytes_to_write = ft232r_output_len - total_written;
117 if (bytes_to_write > 64)
118 bytes_to_write = 64;
119 if (bytes_to_write > rxfifo_free)
120 bytes_to_write = rxfifo_free;
121
122 if (bytes_to_write) {
123 int n = jtag_libusb_bulk_write(adapter, IN_EP,
124 (char *) ft232r_output + total_written,
125 bytes_to_write, 1000);
126
127 if (n == 0) {
128 LOG_ERROR("usb bulk write failed");
129 return ERROR_JTAG_DEVICE_ERROR;
130 }
131
132 total_written += n;
133 rxfifo_free -= n;
134 }
135
136 /* Read */
137 uint8_t reply[64];
138
139 int n = jtag_libusb_bulk_read(adapter, OUT_EP,
140 (char *) reply,
141 sizeof(reply), 1000);
142
143 if (n == 0) {
144 LOG_ERROR("usb bulk read failed");
145 return ERROR_JTAG_DEVICE_ERROR;
146 }
147 if (n > 2) {
148 /* Copy data, ignoring first 2 bytes. */
149 memcpy(ft232r_output + total_read, reply + 2, n - 2);
150 int bytes_read = n - 2;
151 total_read += bytes_read;
152 rxfifo_free += bytes_read;
153 if (total_read > total_written) {
154 LOG_ERROR("read more bytes than wrote");
155 return ERROR_JTAG_DEVICE_ERROR;
156 }
157 }
158 }
159 ft232r_output_len = 0;
160 return ERROR_OK;
161 }
162
163 /**
164 * Add one TCK/TMS/TDI sample to send buffer.
165 */
166 static void ft232r_write(int tck, int tms, int tdi)
167 {
168 unsigned out_value = NTRST | NSYSRST;
169 if (tck)
170 out_value |= TCK;
171 if (tms)
172 out_value |= TMS;
173 if (tdi)
174 out_value |= TDI;
175
176 if (ft232r_output_len >= FT232R_BUF_SIZE) {
177 /* FIXME: should we just execute queue here? */
178 LOG_ERROR("ft232r_write: buffer overflow");
179 return;
180 }
181 ft232r_output[ft232r_output_len++] = out_value;
182 }
183
184 /**
185 * Control /TRST and /SYSRST pins.
186 * Perform immediate bitbang transaction.
187 */
188 static void ft232r_reset(int trst, int srst)
189 {
190 unsigned out_value = NTRST | NSYSRST;
191 LOG_DEBUG("ft232r_reset(%d,%d)", trst, srst);
192
193 if (trst == 1)
194 out_value &= ~NTRST; /* switch /TRST low */
195 else if (trst == 0)
196 out_value |= NTRST; /* switch /TRST high */
197
198 if (srst == 1)
199 out_value &= ~NSYSRST; /* switch /SYSRST low */
200 else if (srst == 0)
201 out_value |= NSYSRST; /* switch /SYSRST high */
202
203 if (ft232r_output_len >= FT232R_BUF_SIZE) {
204 /* FIXME: should we just execute queue here? */
205 LOG_ERROR("ft232r_write: buffer overflow");
206 return;
207 }
208
209 ft232r_output[ft232r_output_len++] = out_value;
210 ft232r_send_recv();
211 }
212
213 static int ft232r_speed(int divisor)
214 {
215 int baud = (divisor == 0) ? 3000000 :
216 (divisor == 1) ? 2000000 :
217 3000000 / divisor;
218 LOG_DEBUG("ft232r_speed(%d) rate %d bits/sec", divisor, baud);
219
220 if (jtag_libusb_control_transfer(adapter,
221 LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,
222 SIO_SET_BAUD_RATE, divisor, 0, 0, 0, 1000) != 0) {
223 LOG_ERROR("cannot set baud rate");
224 return ERROR_JTAG_DEVICE_ERROR;
225 }
226 return ERROR_OK;
227 }
228
229 static int ft232r_init(void)
230 {
231 uint16_t avids[] = {ft232r_vid, 0};
232 uint16_t apids[] = {ft232r_pid, 0};
233 if (jtag_libusb_open(avids, apids, ft232r_serial_desc, &adapter)) {
234 LOG_ERROR("ft232r not found: vid=%04x, pid=%04x, serial=%s\n",
235 ft232r_vid, ft232r_pid, (ft232r_serial_desc == NULL) ? "[any]" : ft232r_serial_desc);
236 return ERROR_JTAG_INIT_FAILED;
237 }
238
239 libusb_detach_kernel_driver(adapter, 0);
240
241 if (jtag_libusb_claim_interface(adapter, 0)) {
242 LOG_ERROR("unable to claim interface");
243 return ERROR_JTAG_INIT_FAILED;
244 }
245
246 /* Reset the device. */
247 if (jtag_libusb_control_transfer(adapter,
248 LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,
249 SIO_RESET, 0, 0, 0, 0, 1000) != 0) {
250 LOG_ERROR("unable to reset device");
251 return ERROR_JTAG_INIT_FAILED;
252 }
253
254 /* Sync bit bang mode. */
255 if (jtag_libusb_control_transfer(adapter,
256 LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,
257 SIO_SET_BITMODE, TCK | TDI | TMS | NTRST | NSYSRST | 0x400,
258 0, 0, 0, 1000) != 0) {
259 LOG_ERROR("cannot set sync bitbang mode");
260 return ERROR_JTAG_INIT_FAILED;
261 }
262
263 /* Exactly 500 nsec between updates. */
264 unsigned divisor = 1;
265 unsigned char latency_timer = 1;
266
267 /* Frequency divisor is 14-bit non-zero value. */
268 if (jtag_libusb_control_transfer(adapter,
269 LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,
270 SIO_SET_BAUD_RATE, divisor,
271 0, 0, 0, 1000) != 0) {
272 LOG_ERROR("cannot set baud rate");
273 return ERROR_JTAG_INIT_FAILED;
274 }
275 if (jtag_libusb_control_transfer(adapter,
276 LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,
277 SIO_SET_LATENCY_TIMER, latency_timer, 0, 0, 0, 1000) != 0) {
278 LOG_ERROR("unable to set latency timer");
279 return ERROR_JTAG_INIT_FAILED;
280 }
281
282 ft232r_output = malloc(FT232R_BUF_SIZE);
283 if (ft232r_output == NULL) {
284 LOG_ERROR("Unable to allocate memory for the buffer");
285 return ERROR_JTAG_INIT_FAILED;
286 }
287
288 return ERROR_OK;
289 }
290
291 static int ft232r_quit(void)
292 {
293 if (jtag_libusb_release_interface(adapter, 0) != 0)
294 LOG_ERROR("usb release interface failed");
295
296 jtag_libusb_close(adapter);
297 free(ft232r_output);
298
299 return ERROR_OK;
300 }
301
302 static int ft232r_speed_div(int divisor, int *khz)
303 {
304 /* Maximum 3 Mbaud for bit bang mode. */
305 if (divisor == 0)
306 *khz = 3000;
307 else if (divisor == 1)
308 *khz = 2000;
309 else
310 *khz = 3000 / divisor;
311 return ERROR_OK;
312 }
313
314 static int ft232r_khz(int khz, int *divisor)
315 {
316 if (khz == 0) {
317 LOG_DEBUG("RCLK not supported");
318 return ERROR_FAIL;
319 }
320
321 /* Calculate frequency divisor. */
322 if (khz > 2500)
323 *divisor = 0; /* Special case: 3 MHz */
324 else if (khz > 1700)
325 *divisor = 1; /* Special case: 2 MHz */
326 else {
327 *divisor = (2*3000 / khz + 1) / 2;
328 if (*divisor > 0x3FFF)
329 *divisor = 0x3FFF;
330 }
331 return ERROR_OK;
332 }
333
334 COMMAND_HANDLER(ft232r_handle_serial_desc_command)
335 {
336 if (CMD_ARGC == 1)
337 ft232r_serial_desc = strdup(CMD_ARGV[0]);
338 else
339 LOG_ERROR("require exactly one argument to "
340 "ft232r_serial_desc <serial>");
341 return ERROR_OK;
342 }
343
344 COMMAND_HANDLER(ft232r_handle_vid_pid_command)
345 {
346 if (CMD_ARGC > 2) {
347 LOG_WARNING("ignoring extra IDs in ft232r_vid_pid "
348 "(maximum is 1 pair)");
349 CMD_ARGC = 2;
350 }
351 if (CMD_ARGC == 2) {
352 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], ft232r_vid);
353 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], ft232r_pid);
354 } else
355 LOG_WARNING("incomplete ft232r_vid_pid configuration");
356
357 return ERROR_OK;
358 }
359
360 static const struct command_registration ft232r_command_handlers[] = {
361 {
362 .name = "ft232r_serial_desc",
363 .handler = ft232r_handle_serial_desc_command,
364 .mode = COMMAND_CONFIG,
365 .help = "USB serial descriptor of the adapter",
366 .usage = "serial string",
367 },
368 {
369 .name = "ft232r_vid_pid",
370 .handler = ft232r_handle_vid_pid_command,
371 .mode = COMMAND_CONFIG,
372 .help = "USB VID and PID of the adapter",
373 .usage = "vid pid",
374 },
375 COMMAND_REGISTRATION_DONE
376 };
377
378 /*
379 * Synchronous bitbang protocol implementation.
380 */
381
382 static void syncbb_end_state(tap_state_t state)
383 {
384 if (tap_is_state_stable(state))
385 tap_set_end_state(state);
386 else {
387 LOG_ERROR("BUG: %i is not a valid end state", state);
388 exit(-1);
389 }
390 }
391
392 static void syncbb_state_move(int skip)
393 {
394 int i = 0, tms = 0;
395 uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
396 int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
397
398 for (i = skip; i < tms_count; i++) {
399 tms = (tms_scan >> i) & 1;
400 ft232r_write(0, tms, 0);
401 ft232r_write(1, tms, 0);
402 }
403 ft232r_write(0, tms, 0);
404
405 tap_set_state(tap_get_end_state());
406 }
407
408 /**
409 * Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG
410 * (or SWD) state machine.
411 */
412 static int syncbb_execute_tms(struct jtag_command *cmd)
413 {
414 unsigned num_bits = cmd->cmd.tms->num_bits;
415 const uint8_t *bits = cmd->cmd.tms->bits;
416
417 DEBUG_JTAG_IO("TMS: %d bits", num_bits);
418
419 int tms = 0;
420 for (unsigned i = 0; i < num_bits; i++) {
421 tms = ((bits[i/8] >> (i % 8)) & 1);
422 ft232r_write(0, tms, 0);
423 ft232r_write(1, tms, 0);
424 }
425 ft232r_write(0, tms, 0);
426
427 return ERROR_OK;
428 }
429
430 static void syncbb_path_move(struct pathmove_command *cmd)
431 {
432 int num_states = cmd->num_states;
433 int state_count;
434 int tms = 0;
435
436 state_count = 0;
437 while (num_states) {
438 if (tap_state_transition(tap_get_state(), false) == cmd->path[state_count]) {
439 tms = 0;
440 } else if (tap_state_transition(tap_get_state(), true) == cmd->path[state_count]) {
441 tms = 1;
442 } else {
443 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
444 tap_state_name(tap_get_state()),
445 tap_state_name(cmd->path[state_count]));
446 exit(-1);
447 }
448
449 ft232r_write(0, tms, 0);
450 ft232r_write(1, tms, 0);
451
452 tap_set_state(cmd->path[state_count]);
453 state_count++;
454 num_states--;
455 }
456
457 ft232r_write(0, tms, 0);
458
459 tap_set_end_state(tap_get_state());
460 }
461
462 static void syncbb_runtest(int num_cycles)
463 {
464 int i;
465
466 tap_state_t saved_end_state = tap_get_end_state();
467
468 /* only do a state_move when we're not already in IDLE */
469 if (tap_get_state() != TAP_IDLE) {
470 syncbb_end_state(TAP_IDLE);
471 syncbb_state_move(0);
472 }
473
474 /* execute num_cycles */
475 for (i = 0; i < num_cycles; i++) {
476 ft232r_write(0, 0, 0);
477 ft232r_write(1, 0, 0);
478 }
479 ft232r_write(0, 0, 0);
480
481 /* finish in end_state */
482 syncbb_end_state(saved_end_state);
483 if (tap_get_state() != tap_get_end_state())
484 syncbb_state_move(0);
485 }
486
487 /**
488 * Function syncbb_stableclocks
489 * issues a number of clock cycles while staying in a stable state.
490 * Because the TMS value required to stay in the RESET state is a 1, whereas
491 * the TMS value required to stay in any of the other stable states is a 0,
492 * this function checks the current stable state to decide on the value of TMS
493 * to use.
494 */
495 static void syncbb_stableclocks(int num_cycles)
496 {
497 int tms = (tap_get_state() == TAP_RESET ? 1 : 0);
498 int i;
499
500 /* send num_cycles clocks onto the cable */
501 for (i = 0; i < num_cycles; i++) {
502 ft232r_write(1, tms, 0);
503 ft232r_write(0, tms, 0);
504 }
505 }
506
507 static void syncbb_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size)
508 {
509 tap_state_t saved_end_state = tap_get_end_state();
510 int bit_cnt, bit0_index;
511
512 if (!((!ir_scan && (tap_get_state() == TAP_DRSHIFT)) || (ir_scan && (tap_get_state() == TAP_IRSHIFT)))) {
513 if (ir_scan)
514 syncbb_end_state(TAP_IRSHIFT);
515 else
516 syncbb_end_state(TAP_DRSHIFT);
517
518 syncbb_state_move(0);
519 syncbb_end_state(saved_end_state);
520 }
521
522 bit0_index = ft232r_output_len;
523 for (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++) {
524 int tms = (bit_cnt == scan_size-1) ? 1 : 0;
525 int tdi;
526 int bytec = bit_cnt/8;
527 int bcval = 1 << (bit_cnt % 8);
528
529 /* if we're just reading the scan, but don't care about the output
530 * default to outputting 'low', this also makes valgrind traces more readable,
531 * as it removes the dependency on an uninitialised value
532 */
533 tdi = 0;
534 if ((type != SCAN_IN) && (buffer[bytec] & bcval))
535 tdi = 1;
536
537 ft232r_write(0, tms, tdi);
538 ft232r_write(1, tms, tdi);
539 }
540
541 if (tap_get_state() != tap_get_end_state()) {
542 /* we *KNOW* the above loop transitioned out of
543 * the shift state, so we skip the first state
544 * and move directly to the end state.
545 */
546 syncbb_state_move(1);
547 }
548 ft232r_send_recv();
549
550 if (type != SCAN_OUT)
551 for (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++) {
552 int bytec = bit_cnt/8;
553 int bcval = 1 << (bit_cnt % 8);
554 int val = ft232r_output[bit0_index + bit_cnt*2 + 1];
555
556 if (val & READ_TDO)
557 buffer[bytec] |= bcval;
558 else
559 buffer[bytec] &= ~bcval;
560 }
561 }
562
563 static int syncbb_execute_queue(void)
564 {
565 struct jtag_command *cmd = jtag_command_queue; /* currently processed command */
566 int scan_size;
567 enum scan_type type;
568 uint8_t *buffer;
569 int retval;
570
571 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
572 * that wasn't handled by a caller-provided error handler
573 */
574 retval = ERROR_OK;
575
576 /* ft232r_blink(1);*/
577
578 while (cmd) {
579 switch (cmd->type) {
580 case JTAG_RESET:
581 LOG_DEBUG_IO("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
582
583 if ((cmd->cmd.reset->trst == 1) ||
584 (cmd->cmd.reset->srst &&
585 (jtag_get_reset_config() & RESET_SRST_PULLS_TRST))) {
586 tap_set_state(TAP_RESET);
587 }
588 ft232r_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
589 break;
590
591 case JTAG_RUNTEST:
592 LOG_DEBUG_IO("runtest %i cycles, end in %s", cmd->cmd.runtest->num_cycles,
593 tap_state_name(cmd->cmd.runtest->end_state));
594
595 syncbb_end_state(cmd->cmd.runtest->end_state);
596 syncbb_runtest(cmd->cmd.runtest->num_cycles);
597 break;
598
599 case JTAG_STABLECLOCKS:
600 /* this is only allowed while in a stable state. A check for a stable
601 * state was done in jtag_add_clocks()
602 */
603 syncbb_stableclocks(cmd->cmd.stableclocks->num_cycles);
604 break;
605
606 case JTAG_TLR_RESET: /* renamed from JTAG_STATEMOVE */
607 LOG_DEBUG_IO("statemove end in %s", tap_state_name(cmd->cmd.statemove->end_state));
608
609 syncbb_end_state(cmd->cmd.statemove->end_state);
610 syncbb_state_move(0);
611 break;
612
613 case JTAG_PATHMOVE:
614 LOG_DEBUG_IO("pathmove: %i states, end in %s", cmd->cmd.pathmove->num_states,
615 tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
616
617 syncbb_path_move(cmd->cmd.pathmove);
618 break;
619
620 case JTAG_SCAN:
621 LOG_DEBUG_IO("%s scan end in %s", (cmd->cmd.scan->ir_scan) ? "IR" : "DR",
622 tap_state_name(cmd->cmd.scan->end_state));
623
624 syncbb_end_state(cmd->cmd.scan->end_state);
625 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
626 type = jtag_scan_type(cmd->cmd.scan);
627 syncbb_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
628 if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
629 retval = ERROR_JTAG_QUEUE_FAILED;
630 if (buffer)
631 free(buffer);
632 break;
633
634 case JTAG_SLEEP:
635 LOG_DEBUG_IO("sleep %" PRIi32, cmd->cmd.sleep->us);
636
637 jtag_sleep(cmd->cmd.sleep->us);
638 break;
639
640 case JTAG_TMS:
641 retval = syncbb_execute_tms(cmd);
642 break;
643 default:
644 LOG_ERROR("BUG: unknown JTAG command type encountered");
645 exit(-1);
646 }
647 if (ft232r_output_len > 0)
648 ft232r_send_recv();
649 cmd = cmd->next;
650 }
651 /* ft232r_blink(0);*/
652
653 return retval;
654 }
655
656 struct jtag_interface ft232r_interface = {
657 .name = "ft232r",
658 .commands = ft232r_command_handlers,
659 .transports = jtag_only,
660 .supported = DEBUG_CAP_TMS_SEQ,
661
662 .execute_queue = syncbb_execute_queue,
663
664 .speed = ft232r_speed,
665 .init = ft232r_init,
666 .quit = ft232r_quit,
667 .speed_div = ft232r_speed_div,
668 .khz = ft232r_khz,
669 };

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)