1 /***************************************************************************
2 * Copyright (C) 2007 by Pavel Chromy *
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. *
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. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
19 ***************************************************************************/
23 * Holds driver for PRESTO programmer from ASIX.
24 * http://tools.asix.net/prg_presto.htm
34 #include <jtag/interface.h>
35 #include <helper/time_support.h>
38 /* PRESTO access library includes */
39 #if BUILD_PRESTO_FTD2XX == 1
41 #include "ftd2xx_common.h"
42 #elif BUILD_PRESTO_LIBFTDI == 1
45 #error "BUG: either FTD2XX and LIBFTDI has to be used"
48 /* -------------------------------------------------------------------------- */
50 #define FT_DEVICE_NAME_LEN 64
51 #define FT_DEVICE_SERNUM_LEN 64
53 #define PRESTO_VID_PID 0x0403f1a0
54 #define PRESTO_VID (0x0403)
55 #define PRESTO_PID (0xf1a0)
57 #define BUFFER_SIZE (64*62)
60 #if BUILD_PRESTO_FTD2XX == 1
63 #elif BUILD_PRESTO_LIBFTDI == 1
64 struct ftdi_context ftdic
;
68 char serial
[FT_DEVICE_SERNUM_LEN
];
70 uint8_t buff_out
[BUFFER_SIZE
];
73 uint8_t buff_in
[BUFFER_SIZE
];
74 int buff_in_exp
;/* expected in buffer length */
75 int buff_in_len
;/* length of data received */
78 unsigned long total_out
;
79 unsigned long total_in
;
81 int jtag_tms
; /* last tms state */
82 int jtag_tck
; /* last tck state */
83 int jtag_rst
; /* last trst state */
91 static struct presto presto_state
;
92 static struct presto
*presto
= &presto_state
;
94 static uint8_t presto_init_seq
[] = {
95 0x80, 0xA0, 0xA8, 0xB0, 0xC0, 0xE0
98 static int presto_write(uint8_t *buf
, uint32_t size
)
100 #if BUILD_PRESTO_FTD2XX == 1
102 presto
->status
= FT_Write(presto
->handle
, buf
, size
, &ftbytes
);
103 if (presto
->status
!= FT_OK
) {
104 LOG_ERROR("FT_Write returned: %s", ftd2xx_status_string(presto
->status
));
105 return ERROR_JTAG_DEVICE_ERROR
;
108 #elif BUILD_PRESTO_LIBFTDI == 1
110 presto
->retval
= ftdi_write_data(&presto
->ftdic
, buf
, size
);
111 if (presto
->retval
< 0) {
112 LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&presto
->ftdic
));
113 return ERROR_JTAG_DEVICE_ERROR
;
115 ftbytes
= presto
->retval
;
118 if (ftbytes
!= size
) {
119 LOG_ERROR("couldn't write the requested number of bytes to PRESTO (%u < %u)",
120 (unsigned)ftbytes
, (unsigned)size
);
121 return ERROR_JTAG_DEVICE_ERROR
;
127 static int presto_read(uint8_t *buf
, uint32_t size
)
129 #if BUILD_PRESTO_FTD2XX == 1
131 presto
->status
= FT_Read(presto
->handle
, buf
, size
, &ftbytes
);
132 if (presto
->status
!= FT_OK
) {
133 LOG_ERROR("FT_Read returned: %s", ftd2xx_status_string(presto
->status
));
134 return ERROR_JTAG_DEVICE_ERROR
;
137 #elif BUILD_PRESTO_LIBFTDI == 1
138 uint32_t ftbytes
= 0;
140 struct timeval timeout
, now
;
141 gettimeofday(&timeout
, NULL
);
142 timeval_add_time(&timeout
, 1, 0); /* one second timeout */
144 while (ftbytes
< size
) {
145 presto
->retval
= ftdi_read_data(&presto
->ftdic
, buf
+ ftbytes
, size
- ftbytes
);
146 if (presto
->retval
< 0) {
147 LOG_ERROR("ftdi_read_data: %s", ftdi_get_error_string(&presto
->ftdic
));
148 return ERROR_JTAG_DEVICE_ERROR
;
150 ftbytes
+= presto
->retval
;
152 gettimeofday(&now
, NULL
);
153 if ((now
.tv_sec
> timeout
.tv_sec
) ||
154 ((now
.tv_sec
== timeout
.tv_sec
) && (now
.tv_usec
> timeout
.tv_usec
)))
159 if (ftbytes
!= size
) {
160 /* this is just a warning, there might have been timeout when detecting PRESTO,
161 *which is not fatal */
162 LOG_WARNING("couldn't read the requested number of bytes from PRESTO (%u < %u)",
163 (unsigned)ftbytes
, (unsigned)size
);
164 return ERROR_JTAG_DEVICE_ERROR
;
170 #if BUILD_PRESTO_FTD2XX == 1
171 static int presto_open_ftd2xx(char *req_serial
)
176 char devname
[FT_DEVICE_NAME_LEN
];
182 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
185 /* Add non-standard Vid/Pid to the linux driver */
186 presto
->status
= FT_SetVIDPID(PRESTO_VID
, PRESTO_PID
);
187 if (presto
->status
!= FT_OK
) {
188 LOG_ERROR("couldn't add PRESTO VID/PID");
193 presto
->status
= FT_ListDevices(&numdevs
, NULL
, FT_LIST_NUMBER_ONLY
);
194 if (presto
->status
!= FT_OK
) {
195 LOG_ERROR("FT_ListDevices failed: %s", ftd2xx_status_string(presto
->status
));
196 return ERROR_JTAG_DEVICE_ERROR
;
199 LOG_DEBUG("FTDI devices available: %" PRIu32
, (uint32_t)numdevs
);
200 for (i
= 0; i
< numdevs
; i
++) {
201 presto
->status
= FT_Open(i
, &(presto
->handle
));
202 if (presto
->status
!= FT_OK
) {
203 /* this is not fatal, the device may be legitimately open by other process,
204 *hence debug message only */
205 LOG_DEBUG("FT_Open failed: %s", ftd2xx_status_string(presto
->status
));
208 LOG_DEBUG("FTDI device %i open", (int)i
);
210 presto
->status
= FT_GetDeviceInfo(presto
->handle
, &device
,
211 &vidpid
, presto
->serial
, devname
, NULL
);
212 if (presto
->status
== FT_OK
) {
213 if (vidpid
== PRESTO_VID_PID
&& (req_serial
== NULL
||
214 !strcmp(presto
->serial
, req_serial
)))
217 LOG_DEBUG("FT_GetDeviceInfo failed: %s", ftd2xx_status_string(
220 LOG_DEBUG("FTDI device %i does not match, closing", (int)i
);
221 FT_Close(presto
->handle
);
222 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
225 if (presto
->handle
== (FT_HANDLE
)INVALID_HANDLE_VALUE
)
226 return ERROR_JTAG_DEVICE_ERROR
; /* presto not open, return */
228 presto
->status
= FT_SetLatencyTimer(presto
->handle
, 1);
229 if (presto
->status
!= FT_OK
)
230 return ERROR_JTAG_DEVICE_ERROR
;
232 presto
->status
= FT_SetTimeouts(presto
->handle
, 100, 0);
233 if (presto
->status
!= FT_OK
)
234 return ERROR_JTAG_DEVICE_ERROR
;
236 presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
);
237 if (presto
->status
!= FT_OK
)
238 return ERROR_JTAG_DEVICE_ERROR
;
241 presto
->status
= FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
);
242 if (presto
->status
!= FT_OK
)
243 return ERROR_JTAG_DEVICE_ERROR
;
245 /* delay between first write/read turnaround (after purge?) necessary
246 * under Linux for unknown reason,
247 * probably a bug in library threading */
249 presto
->status
= FT_Read(presto
->handle
, &presto_data
, 1, &ftbytes
);
250 if (presto
->status
!= FT_OK
)
251 return ERROR_JTAG_DEVICE_ERROR
;
254 LOG_DEBUG("PRESTO reset");
256 presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
);
257 if (presto
->status
!= FT_OK
)
258 return ERROR_JTAG_DEVICE_ERROR
;
259 presto
->status
= FT_SetBitMode(presto
->handle
, 0x80, 1);
260 if (presto
->status
!= FT_OK
)
261 return ERROR_JTAG_DEVICE_ERROR
;
262 presto
->status
= FT_SetBaudRate(presto
->handle
, 9600);
263 if (presto
->status
!= FT_OK
)
264 return ERROR_JTAG_DEVICE_ERROR
;
267 for (i
= 0; i
< 4 * 62; i
++) {
268 presto
->status
= FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
);
269 if (presto
->status
!= FT_OK
)
270 return ERROR_JTAG_DEVICE_ERROR
;
274 presto
->status
= FT_SetBitMode(presto
->handle
, 0x00, 0);
275 if (presto
->status
!= FT_OK
)
276 return ERROR_JTAG_DEVICE_ERROR
;
278 presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
);
279 if (presto
->status
!= FT_OK
)
280 return ERROR_JTAG_DEVICE_ERROR
;
283 presto
->status
= FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
);
284 if (presto
->status
!= FT_OK
)
285 return ERROR_JTAG_DEVICE_ERROR
;
287 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
288 probably a bug in library threading */
290 presto
->status
= FT_Read(presto
->handle
, &presto_data
, 1, &ftbytes
);
291 if (presto
->status
!= FT_OK
)
292 return ERROR_JTAG_DEVICE_ERROR
;
295 LOG_DEBUG("PRESTO not responding");
296 return ERROR_JTAG_DEVICE_ERROR
;
300 presto
->status
= FT_SetTimeouts(presto
->handle
, 0, 0);
301 if (presto
->status
!= FT_OK
)
302 return ERROR_JTAG_DEVICE_ERROR
;
304 presto
->status
= FT_Write(presto
->handle
, &presto_init_seq
,
305 sizeof(presto_init_seq
), &ftbytes
);
307 if (presto
->status
!= FT_OK
|| ftbytes
!= sizeof(presto_init_seq
))
308 return ERROR_JTAG_DEVICE_ERROR
;
313 #elif BUILD_PRESTO_LIBFTDI == 1
314 static int presto_open_libftdi(char *req_serial
)
318 LOG_DEBUG("searching for PRESTO using libftdi");
320 /* initialize FTDI context structure */
321 if (ftdi_init(&presto
->ftdic
) < 0) {
322 LOG_ERROR("unable to init libftdi: %s", presto
->ftdic
.error_str
);
323 return ERROR_JTAG_DEVICE_ERROR
;
326 /* context, vendor id, product id */
327 if (ftdi_usb_open_desc(&presto
->ftdic
, PRESTO_VID
, PRESTO_PID
, NULL
, req_serial
) < 0) {
328 LOG_ERROR("unable to open PRESTO: %s", presto
->ftdic
.error_str
);
329 return ERROR_JTAG_DEVICE_ERROR
;
332 if (ftdi_usb_reset(&presto
->ftdic
) < 0) {
333 LOG_ERROR("unable to reset PRESTO device");
334 return ERROR_JTAG_DEVICE_ERROR
;
337 if (ftdi_set_latency_timer(&presto
->ftdic
, 1) < 0) {
338 LOG_ERROR("unable to set latency timer");
339 return ERROR_JTAG_DEVICE_ERROR
;
342 if (ftdi_usb_purge_buffers(&presto
->ftdic
) < 0) {
343 LOG_ERROR("unable to purge PRESTO buffers");
344 return ERROR_JTAG_DEVICE_ERROR
;
348 if (presto_write(&presto_data
, 1) != ERROR_OK
) {
349 LOG_ERROR("error writing to PRESTO");
350 return ERROR_JTAG_DEVICE_ERROR
;
353 if (presto_read(&presto_data
, 1) != ERROR_OK
) {
354 LOG_DEBUG("no response from PRESTO, retrying");
356 if (ftdi_usb_purge_buffers(&presto
->ftdic
) < 0)
357 return ERROR_JTAG_DEVICE_ERROR
;
360 if (presto_write(&presto_data
, 1) != ERROR_OK
)
361 return ERROR_JTAG_DEVICE_ERROR
;
363 if (presto_read(&presto_data
, 1) != ERROR_OK
) {
364 LOG_ERROR("no response from PRESTO, giving up");
365 return ERROR_JTAG_DEVICE_ERROR
;
369 if (presto_write(presto_init_seq
, sizeof(presto_init_seq
)) != ERROR_OK
) {
370 LOG_ERROR("error writing PRESTO init sequence");
371 return ERROR_JTAG_DEVICE_ERROR
;
376 #endif /* BUILD_PRESTO_LIBFTDI == 1 */
378 static int presto_open(char *req_serial
)
380 presto
->buff_out_pos
= 0;
381 presto
->buff_in_pos
= 0;
382 presto
->buff_in_len
= 0;
383 presto
->buff_in_exp
= 0;
385 presto
->total_out
= 0;
386 presto
->total_in
= 0;
388 presto
->jtag_tms
= 0;
389 presto
->jtag_tck
= 0;
390 presto
->jtag_rst
= 0;
391 presto
->jtag_tdi_data
= 0;
392 presto
->jtag_tdi_count
= 0;
394 presto
->jtag_speed
= 0;
396 #if BUILD_PRESTO_FTD2XX == 1
397 return presto_open_ftd2xx(req_serial
);
398 #elif BUILD_PRESTO_LIBFTDI == 1
399 return presto_open_libftdi(req_serial
);
403 static int presto_close(void)
406 int result
= ERROR_OK
;
408 #if BUILD_PRESTO_FTD2XX == 1
411 if (presto
->handle
== (FT_HANDLE
)INVALID_HANDLE_VALUE
)
414 presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
);
415 if (presto
->status
!= FT_OK
)
416 result
= ERROR_JTAG_DEVICE_ERROR
;
418 presto
->status
= FT_Write(presto
->handle
,
420 sizeof(presto_init_seq
),
422 if (presto
->status
!= FT_OK
|| ftbytes
!= sizeof(presto_init_seq
))
423 result
= ERROR_JTAG_DEVICE_ERROR
;
425 presto
->status
= FT_SetLatencyTimer(presto
->handle
, 16);
426 if (presto
->status
!= FT_OK
)
427 result
= ERROR_JTAG_DEVICE_ERROR
;
429 presto
->status
= FT_Close(presto
->handle
);
430 if (presto
->status
!= FT_OK
)
431 result
= ERROR_JTAG_DEVICE_ERROR
;
433 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
435 #elif BUILD_PRESTO_LIBFTDI == 1
437 presto
->retval
= ftdi_write_data(&presto
->ftdic
, presto_init_seq
, sizeof(presto_init_seq
));
438 if (presto
->retval
!= sizeof(presto_init_seq
))
439 result
= ERROR_JTAG_DEVICE_ERROR
;
441 presto
->retval
= ftdi_set_latency_timer(&presto
->ftdic
, 16);
442 if (presto
->retval
< 0)
443 result
= ERROR_JTAG_DEVICE_ERROR
;
445 presto
->retval
= ftdi_usb_close(&presto
->ftdic
);
446 if (presto
->retval
< 0)
447 result
= ERROR_JTAG_DEVICE_ERROR
;
449 ftdi_deinit(&presto
->ftdic
);
455 static int presto_flush(void)
457 if (presto
->buff_out_pos
== 0)
460 #if BUILD_PRESTO_FTD2XX == 1
461 if (presto
->status
!= FT_OK
) {
462 #elif BUILD_PRESTO_LIBFTDI == 1
463 if (presto
->retval
< 0) {
465 LOG_DEBUG("error in previous communication, canceling I/O operation");
466 return ERROR_JTAG_DEVICE_ERROR
;
469 if (presto_write(presto
->buff_out
, presto
->buff_out_pos
) != ERROR_OK
) {
470 presto
->buff_out_pos
= 0;
471 return ERROR_JTAG_DEVICE_ERROR
;
474 presto
->total_out
+= presto
->buff_out_pos
;
475 presto
->buff_out_pos
= 0;
477 if (presto
->buff_in_exp
== 0)
480 presto
->buff_in_pos
= 0;
481 presto
->buff_in_len
= 0;
483 if (presto_read(presto
->buff_in
, presto
->buff_in_exp
) != ERROR_OK
) {
484 presto
->buff_in_exp
= 0;
485 return ERROR_JTAG_DEVICE_ERROR
;
488 presto
->total_in
+= presto
->buff_in_exp
;
489 presto
->buff_in_len
= presto
->buff_in_exp
;
490 presto
->buff_in_exp
= 0;
495 static int presto_sendbyte(int data
)
498 return presto_flush();
500 if (presto
->buff_out_pos
< BUFFER_SIZE
) {
501 presto
->buff_out
[presto
->buff_out_pos
++] = (uint8_t)data
;
502 if (((data
& 0xC0) == 0x40) || ((data
& 0xD0) == 0xD0))
503 presto
->buff_in_exp
++;
505 return ERROR_JTAG_DEVICE_ERROR
;
507 #if BUILD_PRESTO_FTD2XX == 1
508 if (presto
->buff_out_pos
>= BUFFER_SIZE
)
509 #elif BUILD_PRESTO_LIBFTDI == 1
510 /* libftdi does not do background read, be sure that USB IN buffer does not overflow (128
512 if (presto
->buff_out_pos
>= BUFFER_SIZE
|| presto
->buff_in_exp
== 128)
514 return presto_flush();
520 static int presto_getbyte(void)
522 if (presto
->buff_in_pos
< presto
->buff_in_len
)
523 return presto
->buff_in
[presto
->buff_in_pos
++];
525 if (presto
->buff_in_exp
== 0)
528 if (presto_flush() != ERROR_OK
)
531 if (presto
->buff_in_pos
< presto
->buff_in_len
)
532 return presto
->buff_in
[presto
->buff_in_pos
++];
538 /* -------------------------------------------------------------------------- */
540 static int presto_tdi_flush(void)
542 if (presto
->jtag_tdi_count
== 0)
545 if (presto
->jtag_tck
== 0) {
546 LOG_ERROR("BUG: unexpected TAP condition, TCK low");
550 presto
->jtag_tdi_data
|= (presto
->jtag_tdi_count
- 1) << 4;
551 presto_sendbyte(presto
->jtag_tdi_data
);
552 presto
->jtag_tdi_count
= 0;
553 presto
->jtag_tdi_data
= 0;
558 static int presto_tck_idle(void)
560 if (presto
->jtag_tck
== 1) {
561 presto_sendbyte(0xCA);
562 presto
->jtag_tck
= 0;
568 /* -------------------------------------------------------------------------- */
570 static int presto_bitq_out(int tms
, int tdi
, int tdo_req
)
575 if (presto
->jtag_tck
== 0)
576 presto_sendbyte(0xA4); /* LED idicator - JTAG active */
577 else if (presto
->jtag_speed
== 0 && !tdo_req
&& tms
== presto
->jtag_tms
) {
578 presto
->jtag_tdi_data
|= (tdi
!= 0) << presto
->jtag_tdi_count
;
580 if (++presto
->jtag_tdi_count
== 4)
588 cmd
= tdi
? 0xCB : 0xCA;
589 presto_sendbyte(cmd
);
591 if (tms
!= presto
->jtag_tms
) {
592 presto_sendbyte((tms
? 0xEC : 0xE8) | (presto
->jtag_rst
? 0x02 : 0));
593 presto
->jtag_tms
= tms
;
596 /* delay with TCK low */
597 for (i
= presto
->jtag_speed
; i
> 1; i
--)
598 presto_sendbyte(cmd
);
601 presto_sendbyte(cmd
| (tdo_req
? 0x10 : 0));
603 /* delay with TCK high */
604 for (i
= presto
->jtag_speed
; i
> 1; i
--)
605 presto_sendbyte(cmd
);
607 presto
->jtag_tck
= 1;
612 static int presto_bitq_flush(void)
617 presto_sendbyte(0xA0); /* LED idicator - JTAG idle */
619 return presto_flush();
622 static int presto_bitq_in_rdy(void)
624 if (presto
->buff_in_pos
>= presto
->buff_in_len
)
626 return presto
->buff_in_len
-presto
->buff_in_pos
;
629 static int presto_bitq_in(void)
631 if (presto
->buff_in_pos
>= presto
->buff_in_len
)
633 if (presto
->buff_in
[presto
->buff_in_pos
++]&0x08)
638 static int presto_bitq_sleep(unsigned long us
)
651 waits
= us
/ 170 + 2;
653 presto_sendbyte(0x80);
658 static int presto_bitq_reset(int trst
, int srst
)
663 /* add a delay after possible TCK transition */
664 presto_sendbyte(0x80);
665 presto_sendbyte(0x80);
667 presto
->jtag_rst
= trst
|| srst
;
668 presto_sendbyte((presto
->jtag_rst
? 0xEA : 0xE8) | (presto
->jtag_tms
? 0x04 : 0));
673 static struct bitq_interface presto_bitq
= {
674 .out
= &presto_bitq_out
,
675 .flush
= &presto_bitq_flush
,
676 .sleep
= &presto_bitq_sleep
,
677 .reset
= &presto_bitq_reset
,
678 .in_rdy
= &presto_bitq_in_rdy
,
679 .in
= &presto_bitq_in
,
682 /* -------------------------------------------------------------------------- */
684 static int presto_adapter_khz(int khz
, int *jtag_speed
)
688 return ERROR_COMMAND_SYNTAX_ERROR
;
694 *jtag_speed
= (1000 + khz
-1)/khz
;
699 static int presto_jtag_speed_div(int speed
, int *khz
)
701 if ((speed
< 0) || (speed
> 1000)) {
703 return ERROR_COMMAND_SYNTAX_ERROR
;
714 static int presto_jtag_speed(int speed
)
718 if (presto_jtag_speed_div(speed
, &khz
))
719 return ERROR_COMMAND_SYNTAX_ERROR
;
721 presto
->jtag_speed
= speed
;
724 LOG_INFO("setting speed to %d, max. TCK freq. is %d MHz", speed
, khz
/1000);
726 LOG_INFO("setting speed to %d, max. TCK freq. is %d kHz", speed
, khz
);
731 static char *presto_serial
;
733 COMMAND_HANDLER(presto_handle_serial_command
)
738 presto_serial
= strdup(CMD_ARGV
[0]);
740 return ERROR_COMMAND_SYNTAX_ERROR
;
745 static const struct command_registration presto_command_handlers
[] = {
747 .name
= "presto_serial",
748 .handler
= presto_handle_serial_command
,
749 .mode
= COMMAND_CONFIG
,
750 .help
= "Configure USB serial number of Presto device.",
751 .usage
= "serial_string",
753 COMMAND_REGISTRATION_DONE
756 static int presto_jtag_init(void)
758 if (presto_open(presto_serial
) != ERROR_OK
) {
760 if (presto_serial
!= NULL
)
761 LOG_ERROR("Cannot open PRESTO, serial number '%s'", presto_serial
);
763 LOG_ERROR("Cannot open PRESTO");
764 return ERROR_JTAG_INIT_FAILED
;
766 LOG_INFO("PRESTO open, serial number '%s'", presto
->serial
);
768 bitq_interface
= &presto_bitq
;
772 static int presto_jtag_quit(void)
776 LOG_INFO("PRESTO closed");
780 presto_serial
= NULL
;
786 struct jtag_interface presto_interface
= {
788 .commands
= presto_command_handlers
,
790 .execute_queue
= bitq_execute_queue
,
791 .speed
= presto_jtag_speed
,
792 .khz
= presto_adapter_khz
,
793 .speed_div
= presto_jtag_speed_div
,
794 .init
= presto_jtag_init
,
795 .quit
= presto_jtag_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)