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 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
28 #include "replacements.h"
30 /* project specific includes */
34 #include "configuration.h"
35 #include "time_support.h"
46 /* PRESTO access library includes */
47 #if BUILD_PRESTO_FTD2XX == 1
49 #elif BUILD_PRESTO_LIBFTDI == 1
52 #error "BUG: either FTD2XX and LIBFTDI has to be used"
56 int presto_jtag_speed(int speed
);
57 int presto_jtag_register_commands(struct command_context_s
*cmd_ctx
);
58 int presto_jtag_init(void);
59 int presto_jtag_quit(void);
61 jtag_interface_t presto_interface
=
64 .execute_queue
= bitq_execute_queue
,
65 .speed
= presto_jtag_speed
,
66 .register_commands
= presto_jtag_register_commands
,
67 .init
= presto_jtag_init
,
68 .quit
= presto_jtag_quit
,
72 int presto_bitq_out(int tms
, int tdi
, int tdo_req
);
73 int presto_bitq_flush(void);
74 int presto_bitq_sleep(unsigned long us
);
75 int presto_bitq_reset(int trst
, int srst
);
76 int presto_bitq_in_rdy(void);
77 int presto_bitq_in(void);
79 bitq_interface_t presto_bitq
=
81 .out
= presto_bitq_out
,
82 .flush
= presto_bitq_flush
,
83 .sleep
= presto_bitq_sleep
,
84 .reset
= presto_bitq_reset
,
85 .in_rdy
= presto_bitq_in_rdy
,
90 /* -------------------------------------------------------------------------- */
93 #define FT_DEVICE_NAME_LEN 64
94 #define FT_DEVICE_SERNUM_LEN 64
96 #define PRESTO_VID_PID 0x0403f1a0
97 #define PRESTO_VID (0x0403)
98 #define PRESTO_PID (0xf1a0)
100 #define BUFFER_SIZE (64*62)
102 typedef struct presto_s
104 #if BUILD_PRESTO_FTD2XX == 1
107 #elif BUILD_PRESTO_LIBFTDI == 1
108 struct ftdi_context ftdic
;
112 char serial
[FT_DEVICE_SERNUM_LEN
];
114 u8 buff_out
[BUFFER_SIZE
];
117 u8 buff_in
[BUFFER_SIZE
];
118 int buff_in_exp
; /* expected in buffer length */
119 int buff_in_len
; /* length of data received */
122 unsigned long total_out
;
123 unsigned long total_in
;
125 int jtag_tms
; /* last tms state */
126 int jtag_tck
; /* last tck state */
133 presto_t presto_state
;
134 presto_t
*presto
= &presto_state
;
136 u8 presto_init_seq
[] =
138 0x80, 0xA0, 0xA8, 0xB0, 0xC0, 0xE0
141 int presto_write(u8
*buf
, int size
)
143 #if BUILD_PRESTO_FTD2XX == 1
145 if ((presto
->status
= FT_Write(presto
->handle
, buf
, size
, &ftbytes
)) != FT_OK
)
147 LOG_ERROR("FT_Write returned: %lu", presto
->status
);
148 return ERROR_JTAG_DEVICE_ERROR
;
151 #elif BUILD_PRESTO_LIBFTDI == 1
153 if ((presto
->retval
= ftdi_write_data(&presto
->ftdic
, buf
, size
)) < 0)
155 LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&presto
->ftdic
));
156 return ERROR_JTAG_DEVICE_ERROR
;
158 ftbytes
= presto
->retval
;
163 LOG_ERROR("couldn't write the requested number of bytes to PRESTO (%i < %i)", ftbytes
, size
);
164 return ERROR_JTAG_DEVICE_ERROR
;
170 int presto_read(u8
* buf
, int size
)
172 #if BUILD_PRESTO_FTD2XX == 1
174 if ((presto
->status
= FT_Read(presto
->handle
, buf
, size
, &ftbytes
)) != FT_OK
)
176 LOG_ERROR("FT_Read returned: %lu", presto
->status
);
177 return ERROR_JTAG_DEVICE_ERROR
;
180 #elif BUILD_PRESTO_LIBFTDI == 1
183 struct timeval timeout
, now
;
184 gettimeofday(&timeout
, NULL
);
185 timeval_add_time(&timeout
, 1, 0); /* one second timeout */
187 while (ftbytes
< size
)
189 if ((presto
->retval
= ftdi_read_data(&presto
->ftdic
, buf
+ ftbytes
, size
- ftbytes
)) < 0)
191 LOG_ERROR("ftdi_read_data: %s", ftdi_get_error_string(&presto
->ftdic
));
192 return ERROR_JTAG_DEVICE_ERROR
;
194 ftbytes
+= presto
->retval
;
196 gettimeofday(&now
, NULL
);
197 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
) && (now
.tv_usec
> timeout
.tv_usec
)))
204 /* this is just a warning, there might have been timeout when detecting PRESTO, which is not fatal */
205 LOG_WARNING("couldn't read the requested number of bytes from PRESTO (%i < %i)", ftbytes
, size
);
206 return ERROR_JTAG_DEVICE_ERROR
;
212 #if BUILD_PRESTO_FTD2XX == 1
213 int presto_open_ftd2xx(char *req_serial
)
218 char devname
[FT_DEVICE_NAME_LEN
];
224 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
227 /* Add non-standard Vid/Pid to the linux driver */
228 if ((presto
->status
= FT_SetVIDPID(PRESTO_VID
, PRESTO_PID
)) != FT_OK
)
230 LOG_ERROR("couldn't add PRESTO VID/PID");
235 if ((presto
->status
= FT_ListDevices(&numdevs
, NULL
, FT_LIST_NUMBER_ONLY
)) != FT_OK
)
237 LOG_ERROR("FT_ListDevices failed: %i", (int)presto
->status
);
238 return ERROR_JTAG_DEVICE_ERROR
;
241 LOG_DEBUG("FTDI devices available: %i", numdevs
);
242 for (i
= 0; i
< numdevs
; i
++)
244 if ((presto
->status
= FT_Open(i
, &(presto
->handle
))) != FT_OK
)
246 /* this is not fatal, the device may be legitimately open by other process, hence debug message only */
247 LOG_DEBUG("FT_Open failed: %i", (int)presto
->status
);
250 LOG_DEBUG("FTDI device %i open", i
);
252 if ((presto
->status
= FT_GetDeviceInfo(presto
->handle
, &device
, &vidpid
,
253 presto
->serial
, devname
, NULL
)) == FT_OK
)
255 if (vidpid
== PRESTO_VID_PID
256 && (req_serial
== NULL
|| !strcmp(presto
->serial
, req_serial
)))
260 LOG_DEBUG("FT_GetDeviceInfo failed: %i", presto
->status
);
262 LOG_DEBUG("FTDI device %i does not match, closing", i
);
263 FT_Close(presto
->handle
);
264 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
267 if (presto
->handle
== (FT_HANDLE
)INVALID_HANDLE_VALUE
)
268 return ERROR_JTAG_DEVICE_ERROR
; /* presto not open, return */
270 if ((presto
->status
= FT_SetLatencyTimer(presto
->handle
, 1)) != FT_OK
)
271 return ERROR_JTAG_DEVICE_ERROR
;
274 if ((presto
->status
= FT_SetTimeouts(presto
->handle
, 100, 0)) != FT_OK
)
275 return ERROR_JTAG_DEVICE_ERROR
;
277 if ((presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
)) != FT_OK
)
278 return ERROR_JTAG_DEVICE_ERROR
;
281 if ((presto
->status
= FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
282 return ERROR_JTAG_DEVICE_ERROR
;
284 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
285 probably a bug in library threading */
287 if ((presto
->status
= FT_Read(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
288 return ERROR_JTAG_DEVICE_ERROR
;
292 LOG_DEBUG("PRESTO reset");
294 if ((presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
)) != FT_OK
)
295 return ERROR_JTAG_DEVICE_ERROR
;
296 if ((presto
->status
= FT_SetBitMode(presto
->handle
, 0x80, 1)) != FT_OK
)
297 return ERROR_JTAG_DEVICE_ERROR
;
298 if ((presto
->status
= FT_SetBaudRate(presto
->handle
, 9600)) != FT_OK
)
299 return ERROR_JTAG_DEVICE_ERROR
;
302 for (i
= 0; i
< 4 * 62; i
++)
303 if ((presto
->status
=FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
304 return ERROR_JTAG_DEVICE_ERROR
;
308 if ((presto
->status
= FT_SetBitMode(presto
->handle
, 0x00, 0)) != FT_OK
)
309 return ERROR_JTAG_DEVICE_ERROR
;
311 if ((presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
)) != FT_OK
)
312 return ERROR_JTAG_DEVICE_ERROR
;
315 if ((presto
->status
= FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
316 return ERROR_JTAG_DEVICE_ERROR
;
318 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
319 probably a bug in library threading */
321 if ((presto
->status
= FT_Read(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
322 return ERROR_JTAG_DEVICE_ERROR
;
326 LOG_DEBUG("PRESTO not responding");
327 return ERROR_JTAG_DEVICE_ERROR
;
331 if ((presto
->status
= FT_SetTimeouts(presto
->handle
, 0, 0)) != FT_OK
)
332 return ERROR_JTAG_DEVICE_ERROR
;
335 presto
->status
= FT_Write(presto
->handle
, &presto_init_seq
, sizeof(presto_init_seq
), &ftbytes
);
336 if (presto
->status
!= FT_OK
|| ftbytes
!= sizeof(presto_init_seq
))
337 return ERROR_JTAG_DEVICE_ERROR
;
342 #elif BUILD_PRESTO_LIBFTDI == 1
343 int presto_open_libftdi(char *req_serial
)
347 LOG_DEBUG("searching for PRESTO using libftdi");
349 /* initialize FTDI context structure */
350 if (ftdi_init(&presto
->ftdic
) < 0)
352 LOG_ERROR("unable to init libftdi: %s", presto
->ftdic
.error_str
);
353 return ERROR_JTAG_DEVICE_ERROR
;
356 /* context, vendor id, product id */
357 if (ftdi_usb_open_desc(&presto
->ftdic
, PRESTO_VID
, PRESTO_PID
, NULL
, req_serial
) < 0)
359 LOG_ERROR("unable to open PRESTO: %s", presto
->ftdic
.error_str
);
360 return ERROR_JTAG_DEVICE_ERROR
;
363 if (ftdi_usb_reset(&presto
->ftdic
) < 0)
365 LOG_ERROR("unable to reset PRESTO device");
366 return ERROR_JTAG_DEVICE_ERROR
;
369 if (ftdi_set_latency_timer(&presto
->ftdic
, 1) < 0)
371 LOG_ERROR("unable to set latency timer");
372 return ERROR_JTAG_DEVICE_ERROR
;
375 if (ftdi_usb_purge_buffers(&presto
->ftdic
) < 0)
377 LOG_ERROR("unable to purge PRESTO buffers");
378 return ERROR_JTAG_DEVICE_ERROR
;
382 if (presto_write(&presto_data
, 1) != ERROR_OK
)
384 LOG_ERROR("error writing to PRESTO");
385 return ERROR_JTAG_DEVICE_ERROR
;
388 if (presto_read(&presto_data
, 1) != ERROR_OK
)
390 LOG_DEBUG("no response from PRESTO, retrying");
392 if (ftdi_usb_purge_buffers(&presto
->ftdic
) < 0)
393 return ERROR_JTAG_DEVICE_ERROR
;
396 if (presto_write(&presto_data
, 1) != ERROR_OK
)
397 return ERROR_JTAG_DEVICE_ERROR
;
399 if (presto_read(&presto_data
, 1) != ERROR_OK
)
401 LOG_ERROR("no response from PRESTO, giving up");
402 return ERROR_JTAG_DEVICE_ERROR
;
406 if (presto_write(presto_init_seq
, sizeof(presto_init_seq
)) != ERROR_OK
)
408 LOG_ERROR("error writing PRESTO init sequence");
409 return ERROR_JTAG_DEVICE_ERROR
;
414 #endif /* BUILD_PRESTO_LIBFTDI == 1 */
416 int presto_open(char *req_serial
)
418 presto
->buff_out_pos
=0;
419 presto
->buff_in_pos
=0;
420 presto
->buff_in_len
=0;
421 presto
->buff_in_exp
=0;
428 presto
->jtag_tdi_data
=0;
429 presto
->jtag_tdi_count
=0;
431 #if BUILD_PRESTO_FTD2XX == 1
432 return presto_open_ftd2xx(req_serial
);
433 #elif BUILD_PRESTO_LIBFTDI == 1
434 return presto_open_libftdi(req_serial
);
438 int presto_close(void)
441 int result
= ERROR_OK
;
443 #if BUILD_PRESTO_FTD2XX == 1
444 unsigned long ftbytes
;
446 if (presto
->handle
== (FT_HANDLE
)INVALID_HANDLE_VALUE
)
449 presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
);
450 if (presto
->status
!= FT_OK
)
451 result
= ERROR_JTAG_DEVICE_ERROR
;
453 presto
->status
= FT_Write(presto
->handle
, &presto_init_seq
, sizeof(presto_init_seq
), &ftbytes
);
454 if (presto
->status
!= FT_OK
|| ftbytes
!= sizeof(presto_init_seq
))
455 result
= ERROR_JTAG_DEVICE_ERROR
;
457 if ((presto
->status
= FT_SetLatencyTimer(presto
->handle
, 16)) != FT_OK
)
458 result
= ERROR_JTAG_DEVICE_ERROR
;
460 if ((presto
->status
= FT_Close(presto
->handle
)) != FT_OK
)
461 result
= ERROR_JTAG_DEVICE_ERROR
;
463 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
465 #elif BUILD_PRESTO_LIBFTDI == 1
467 if ((presto
->retval
= ftdi_write_data(&presto
->ftdic
, presto_init_seq
, sizeof(presto_init_seq
))) != sizeof(presto_init_seq
))
468 result
= ERROR_JTAG_DEVICE_ERROR
;
470 if ((presto
->retval
= ftdi_set_latency_timer(&presto
->ftdic
, 16)) < 0)
471 result
= ERROR_JTAG_DEVICE_ERROR
;
473 if ((presto
->retval
= ftdi_usb_close(&presto
->ftdic
)) < 0)
474 result
= ERROR_JTAG_DEVICE_ERROR
;
476 ftdi_deinit(&presto
->ftdic
);
483 int presto_flush(void)
485 if (presto
->buff_out_pos
== 0)
488 #if BUILD_PRESTO_FTD2XX == 1
489 if (presto
->status
!= FT_OK
)
490 #elif BUILD_PRESTO_LIBFTDI == 1
491 if (presto
->retval
< 0)
494 LOG_DEBUG("error in previous communication, canceling I/O operation");
495 return ERROR_JTAG_DEVICE_ERROR
;
498 if (presto_write(presto
->buff_out
, presto
->buff_out_pos
) != ERROR_OK
)
500 presto
->buff_out_pos
= 0;
501 return ERROR_JTAG_DEVICE_ERROR
;
504 presto
->total_out
+= presto
->buff_out_pos
;
505 presto
->buff_out_pos
= 0;
507 if (presto
->buff_in_exp
== 0)
510 presto
->buff_in_pos
= 0;
511 presto
->buff_in_len
= 0;
513 if (presto_read(presto
->buff_in
, presto
->buff_in_exp
) != ERROR_OK
)
515 presto
->buff_in_exp
= 0;
516 return ERROR_JTAG_DEVICE_ERROR
;
519 presto
->total_in
+= presto
->buff_in_exp
;
520 presto
->buff_in_len
= presto
->buff_in_exp
;
521 presto
->buff_in_exp
= 0;
527 int presto_sendbyte(int data
)
529 if (data
== EOF
) return presto_flush();
531 if (presto
->buff_out_pos
< BUFFER_SIZE
)
533 presto
->buff_out
[presto
->buff_out_pos
++] = (u8
)data
;
534 if (((data
& 0xC0) == 0x40) || ((data
& 0xD0)== 0xD0))
535 presto
->buff_in_exp
++;
538 return ERROR_JTAG_DEVICE_ERROR
;
540 #if BUILD_PRESTO_FTD2XX == 1
541 if (presto
->buff_out_pos
>= BUFFER_SIZE
)
542 #elif BUILD_PRESTO_LIBFTDI == 1
543 /* libftdi does not do background read, be sure that USB IN buffer does not overflow (128 bytes only!) */
544 if (presto
->buff_out_pos
>= BUFFER_SIZE
|| presto
->buff_in_exp
==128)
546 return presto_flush();
552 int presto_getbyte(void)
554 if (presto
->buff_in_pos
< presto
->buff_in_len
)
555 return presto
->buff_in
[presto
->buff_in_pos
++];
557 if (presto
->buff_in_exp
== 0)
560 if (presto_flush() != ERROR_OK
)
563 if (presto
->buff_in_pos
<presto
->buff_in_len
)
564 return presto
->buff_in
[presto
->buff_in_pos
++];
570 /* -------------------------------------------------------------------------- */
573 int presto_bitq_out(int tms
, int tdi
, int tdo_req
)
575 unsigned char cmdparam
;
577 if (presto
->jtag_tck
== 0)
579 presto_sendbyte(0xA4);
580 presto
->jtag_tck
= 1;
583 else if (!tdo_req
&& tms
== presto
->jtag_tms
)
585 if (presto
->jtag_tdi_count
== 0)
586 presto
->jtag_tdi_data
= (tdi
!= 0);
588 presto
->jtag_tdi_data
|= (tdi
!= 0) << presto
->jtag_tdi_count
;
590 if (++presto
->jtag_tdi_count
== 4)
592 presto
->jtag_tdi_data
|= (presto
->jtag_tdi_count
- 1) << 4;
593 presto_sendbyte(presto
->jtag_tdi_data
);
594 presto
->jtag_tdi_count
= 0;
599 if (presto
->jtag_tdi_count
)
601 presto
->jtag_tdi_data
|= (presto
->jtag_tdi_count
- 1) << 4;
602 presto_sendbyte(presto
->jtag_tdi_data
);
603 presto
->jtag_tdi_count
= 0;
611 presto_sendbyte( 0xC0 | cmdparam
);
613 if (tms
!= presto
->jtag_tms
)
616 presto_sendbyte(0xEC);
618 presto_sendbyte(0xE8);
619 presto
->jtag_tms
= tms
;
623 presto_sendbyte(0xD4 | cmdparam
);
625 presto_sendbyte(0xC4|cmdparam
);
631 int presto_bitq_flush(void)
633 if (presto
->jtag_tdi_count
)
635 presto
->jtag_tdi_data
|= (presto
->jtag_tdi_count
- 1) << 4;
636 presto_sendbyte(presto
->jtag_tdi_data
);
637 presto
->jtag_tdi_count
= 0;
640 presto_sendbyte(0xCA);
641 presto
->jtag_tck
= 0;
643 presto_sendbyte(0xA0);
645 return presto_flush();
649 int presto_bitq_in_rdy(void)
651 if (presto
->buff_in_pos
>=presto
->buff_in_len
)
653 return presto
->buff_in_len
-presto
->buff_in_pos
;
657 int presto_bitq_in(void)
659 if (presto
->buff_in_pos
>=presto
->buff_in_len
)
661 if (presto
->buff_in
[presto
->buff_in_pos
++]&0x08) return 1;
666 int presto_bitq_sleep(unsigned long us
)
677 waits
= us
/ 170 + 2;
679 presto_sendbyte(0x80);
685 int presto_bitq_reset(int trst
, int srst
)
690 if (presto
->jtag_tms
)
696 presto_sendbyte(cmd
);
701 /* -------------------------------------------------------------------------- */
703 char *presto_speed_text
[4] =
711 int presto_jtag_speed(int speed
)
714 if ((speed
< 0) || (speed
> 3))
716 LOG_INFO("valid speed values: 0 (3 MHz), 1 (1.5 MHz), 2 (750 kHz) and 3 (93.75 kHz)");
717 return ERROR_INVALID_ARGUMENTS
;
721 LOG_INFO("setting speed to %d, max. TCK freq. is %s", speed
, presto_speed_text
[speed
]);
722 return presto_sendbyte(0xA8 | speed
);
728 int presto_handle_serial_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
734 presto_serial
= strdup(args
[0]);
738 LOG_ERROR("expected exactly one argument to presto_serial <serial-number>");
745 int presto_jtag_register_commands(struct command_context_s
*cmd_ctx
)
747 register_command(cmd_ctx
, NULL
, "presto_serial", presto_handle_serial_command
,
748 COMMAND_CONFIG
, NULL
);
753 int presto_jtag_init(void)
755 if (presto_open(presto_serial
) != ERROR_OK
)
758 if (presto_serial
!= NULL
)
759 LOG_ERROR("Cannot open PRESTO, serial number '%s'", presto_serial
);
761 LOG_ERROR("Cannot open PRESTO");
762 return ERROR_JTAG_INIT_FAILED
;
764 LOG_INFO("PRESTO open, serial number '%s'", presto
->serial
);
766 /* use JTAG speed setting from configuration file */
767 presto_jtag_speed(jtag_speed
);
769 bitq_interface
= &presto_bitq
;
774 int presto_jtag_quit(void)
778 LOG_INFO("PRESTO closed");
783 presto_serial
= NULL
;
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)