1 /***************************************************************************
2 * Copyright (C) 2004, 2006 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
25 /* This code uses information contained in the MPSSE specification which was
27 * http://www.ftdichip.com/Documents/AppNotes/AN2232C-01_MPSSE_Cmnd.pdf
28 * Hereafter this is called the "MPSSE Spec".
40 #include "replacements.h"
42 /* project specific includes */
46 #include "configuration.h"
47 #include "time_support.h"
54 /* FT2232 access library includes */
55 #if BUILD_FT2232_FTD2XX == 1
57 #elif BUILD_FT2232_LIBFTDI == 1
61 /* enable this to debug io latency
64 #define _DEBUG_USB_IO_
67 /* enable this to debug communication
70 #define _DEBUG_USB_COMMS_
73 int ft2232_execute_queue(void);
75 int ft2232_speed(int speed
);
76 int ft2232_speed_div(int speed
, int* khz
);
77 int ft2232_khz(int khz
, int* jtag_speed
);
78 int ft2232_register_commands(struct command_context_s
* cmd_ctx
);
79 int ft2232_init(void);
80 int ft2232_quit(void);
82 int ft2232_handle_device_desc_command(struct command_context_s
* cmd_ctx
, char* cmd
, char** args
, int argc
);
83 int ft2232_handle_serial_command(struct command_context_s
* cmd_ctx
, char* cmd
, char** args
, int argc
);
84 int ft2232_handle_layout_command(struct command_context_s
* cmd_ctx
, char* cmd
, char** args
, int argc
);
85 int ft2232_handle_vid_pid_command(struct command_context_s
* cmd_ctx
, char* cmd
, char** args
, int argc
);
86 int ft2232_handle_latency_command(struct command_context_s
* cmd_ctx
, char* cmd
, char** args
, int argc
);
90 * Function ft2232_stableclocks
91 * will send out \a num_cycles on the TCK line while the TAP(s)
92 * are in a stable state. Calling code must ensure that current state is
93 * stable, that verification is not done in here.
94 * @param num_cycles is the count of clocks cycles to send.
95 * @return int - ERROR_OK or ERROR_JTAG_QUEUE_FAILED
97 static int ft2232_stableclocks(int num_cycles
, jtag_command_t
* cmd
);
100 char* ft2232_device_desc
= NULL
;
101 char* ft2232_serial
= NULL
;
102 char* ft2232_layout
= NULL
;
103 unsigned char ft2232_latency
= 2;
105 #define MAX_USB_IDS 8
106 /* vid = pid = 0 marks the end of the list */
107 static u16 ft2232_vid
[MAX_USB_IDS
+ 1] = { 0x0403, 0 };
108 static u16 ft2232_pid
[MAX_USB_IDS
+ 1] = { 0x6010, 0 };
110 typedef struct ft2232_layout_s
114 void (*reset
)(int trst
, int srst
);
118 /* init procedures for supported layouts */
119 int usbjtag_init(void);
120 int jtagkey_init(void);
121 int olimex_jtag_init(void);
122 int flyswatter_init(void);
123 int turtle_init(void);
124 int comstick_init(void);
125 int stm32stick_init(void);
126 int axm0432_jtag_init(void);
128 /* reset procedures for supported layouts */
129 void usbjtag_reset(int trst
, int srst
);
130 void jtagkey_reset(int trst
, int srst
);
131 void olimex_jtag_reset(int trst
, int srst
);
132 void flyswatter_reset(int trst
, int srst
);
133 void turtle_reset(int trst
, int srst
);
134 void comstick_reset(int trst
, int srst
);
135 void stm32stick_reset(int trst
, int srst
);
136 void axm0432_jtag_reset(int trst
, int srst
);
138 /* blink procedures for layouts that support a blinking led */
139 void olimex_jtag_blink(void);
140 void turtle_jtag_blink(void);
142 ft2232_layout_t ft2232_layouts
[] =
144 { "usbjtag", usbjtag_init
, usbjtag_reset
, NULL
},
145 { "jtagkey", jtagkey_init
, jtagkey_reset
, NULL
},
146 { "jtagkey_prototype_v1", jtagkey_init
, jtagkey_reset
, NULL
},
147 { "oocdlink", jtagkey_init
, jtagkey_reset
, NULL
},
148 { "signalyzer", usbjtag_init
, usbjtag_reset
, NULL
},
149 { "evb_lm3s811", usbjtag_init
, usbjtag_reset
, NULL
},
150 { "olimex-jtag", olimex_jtag_init
, olimex_jtag_reset
, olimex_jtag_blink
},
151 { "flyswatter", flyswatter_init
, flyswatter_reset
, NULL
},
152 { "turtelizer2", turtle_init
, turtle_reset
, turtle_jtag_blink
},
153 { "comstick", comstick_init
, comstick_reset
, NULL
},
154 { "stm32stick", stm32stick_init
, stm32stick_reset
, NULL
},
155 { "axm0432_jtag", axm0432_jtag_init
, axm0432_jtag_reset
, NULL
},
156 { NULL
, NULL
, NULL
},
159 static u8 nTRST
, nTRSTnOE
, nSRST
, nSRSTnOE
;
161 static ft2232_layout_t
* layout
;
162 static u8 low_output
= 0x0;
163 static u8 low_direction
= 0x0;
164 static u8 high_output
= 0x0;
165 static u8 high_direction
= 0x0;
167 #if BUILD_FT2232_FTD2XX == 1
168 static FT_HANDLE ftdih
= NULL
;
169 #elif BUILD_FT2232_LIBFTDI == 1
170 static struct ftdi_context ftdic
;
174 static jtag_command_t
* first_unsent
; /* next command that has to be sent */
175 static int require_send
;
177 static u8
* ft2232_buffer
= NULL
;
178 static int ft2232_buffer_size
= 0;
179 static int ft2232_read_pointer
= 0;
180 static int ft2232_expect_read
= 0;
182 #define FT2232_BUFFER_SIZE 131072
183 #define BUFFER_ADD ft2232_buffer[ft2232_buffer_size++]
184 #define BUFFER_READ ft2232_buffer[ft2232_read_pointer++]
186 jtag_interface_t ft2232_interface
=
189 .execute_queue
= ft2232_execute_queue
,
190 .speed
= ft2232_speed
,
191 .speed_div
= ft2232_speed_div
,
193 .register_commands
= ft2232_register_commands
,
198 int ft2232_write(u8
* buf
, int size
, u32
* bytes_written
)
200 #if BUILD_FT2232_FTD2XX == 1
202 DWORD dw_bytes_written
;
203 if ( ( status
= FT_Write(ftdih
, buf
, size
, &dw_bytes_written
) ) != FT_OK
)
205 *bytes_written
= dw_bytes_written
;
206 LOG_ERROR("FT_Write returned: %lu", status
);
207 return ERROR_JTAG_DEVICE_ERROR
;
211 *bytes_written
= dw_bytes_written
;
214 #elif BUILD_FT2232_LIBFTDI == 1
216 if ( ( retval
= ftdi_write_data(&ftdic
, buf
, size
) ) < 0 )
219 LOG_ERROR( "ftdi_write_data: %s", ftdi_get_error_string(&ftdic
) );
220 return ERROR_JTAG_DEVICE_ERROR
;
224 *bytes_written
= retval
;
231 int ft2232_read(u8
* buf
, int size
, u32
* bytes_read
)
233 #if BUILD_FT2232_FTD2XX == 1
239 while ( (*bytes_read
< size
) && timeout
-- )
241 if ( ( status
= FT_Read(ftdih
, buf
+ *bytes_read
, size
-
242 *bytes_read
, &dw_bytes_read
) ) != FT_OK
)
245 LOG_ERROR("FT_Read returned: %lu", status
);
246 return ERROR_JTAG_DEVICE_ERROR
;
248 *bytes_read
+= dw_bytes_read
;
251 #elif BUILD_FT2232_LIBFTDI == 1
256 while ( (*bytes_read
< size
) && timeout
-- )
258 if ( ( retval
= ftdi_read_data(&ftdic
, buf
+ *bytes_read
, size
- *bytes_read
) ) < 0 )
261 LOG_ERROR( "ftdi_read_data: %s", ftdi_get_error_string(&ftdic
) );
262 return ERROR_JTAG_DEVICE_ERROR
;
264 *bytes_read
+= retval
;
269 if (*bytes_read
< size
)
271 LOG_ERROR("couldn't read the requested number of bytes from FT2232 device (%i < %i)", *bytes_read
, size
);
272 return ERROR_JTAG_DEVICE_ERROR
;
279 int ft2232_speed(int speed
)
285 buf
[0] = 0x86; /* command "set divisor" */
286 buf
[1] = speed
& 0xff; /* valueL (0=6MHz, 1=3MHz, 2=2.0MHz, ...*/
287 buf
[2] = (speed
>> 8) & 0xff; /* valueH */
289 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
290 if ( ( ( retval
= ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
292 LOG_ERROR("couldn't set FT2232 TCK speed");
300 int ft2232_speed_div(int speed
, int* khz
)
302 /* Take a look in the FT2232 manual,
303 * AN2232C-01 Command Processor for
304 * MPSSE and MCU Host Bus. Chapter 3.8 */
306 *khz
= 6000 / (1 + speed
);
312 int ft2232_khz(int khz
, int* jtag_speed
)
316 LOG_ERROR("RCLK not supported");
320 /* Take a look in the FT2232 manual,
321 * AN2232C-01 Command Processor for
322 * MPSSE and MCU Host Bus. Chapter 3.8
324 * We will calc here with a multiplier
325 * of 10 for better rounding later. */
327 /* Calc speed, (6000 / khz) - 1 */
328 /* Use 65000 for better rounding */
329 *jtag_speed
= (60000 / khz
) - 10;
331 /* Add 0.9 for rounding */
334 /* Calc real speed */
335 *jtag_speed
= *jtag_speed
/ 10;
337 /* Check if speed is greater than 0 */
343 /* Check max value */
344 if (*jtag_speed
> 0xFFFF)
346 *jtag_speed
= 0xFFFF;
353 int ft2232_register_commands(struct command_context_s
* cmd_ctx
)
355 register_command(cmd_ctx
, NULL
, "ft2232_device_desc", ft2232_handle_device_desc_command
,
356 COMMAND_CONFIG
, "the USB device description of the FTDI FT2232 device");
357 register_command(cmd_ctx
, NULL
, "ft2232_serial", ft2232_handle_serial_command
,
358 COMMAND_CONFIG
, "the serial number of the FTDI FT2232 device");
359 register_command(cmd_ctx
, NULL
, "ft2232_layout", ft2232_handle_layout_command
,
360 COMMAND_CONFIG
, "the layout of the FT2232 GPIO signals used to control output-enables and reset signals");
361 register_command(cmd_ctx
, NULL
, "ft2232_vid_pid", ft2232_handle_vid_pid_command
,
362 COMMAND_CONFIG
, "the vendor ID and product ID of the FTDI FT2232 device");
363 register_command(cmd_ctx
, NULL
, "ft2232_latency", ft2232_handle_latency_command
,
364 COMMAND_CONFIG
, "set the FT2232 latency timer to a new value");
369 void ft2232_end_state(tap_state_t state
)
371 if (tap_is_state_stable(state
))
372 tap_set_end_state(state
);
375 LOG_ERROR("BUG: %i is not a valid end state", state
);
381 void ft2232_read_scan(enum scan_type type
, u8
* buffer
, int scan_size
)
383 int num_bytes
= (scan_size
+ 7) / 8;
384 int bits_left
= scan_size
;
387 while (num_bytes
-- > 1)
389 buffer
[cur_byte
] = BUFFER_READ
;
394 buffer
[cur_byte
] = 0x0;
398 buffer
[cur_byte
] = BUFFER_READ
>> 1;
401 buffer
[cur_byte
] = ( buffer
[cur_byte
] | ( (BUFFER_READ
& 0x02) << 6 ) ) >> (8 - bits_left
);
405 void ft2232_debug_dump_buffer(void)
411 for (i
= 0; i
< ft2232_buffer_size
; i
++)
413 line_p
+= snprintf(line_p
, 256 - (line_p
- line
), "%2.2x ", ft2232_buffer
[i
]);
416 LOG_DEBUG("%s", line
);
422 LOG_DEBUG("%s", line
);
426 int ft2232_send_and_recv(jtag_command_t
* first
, jtag_command_t
* last
)
436 #ifdef _DEBUG_USB_IO_
437 struct timeval start
, inter
, inter2
, end
;
438 struct timeval d_inter
, d_inter2
, d_end
;
441 #ifdef _DEBUG_USB_COMMS_
442 LOG_DEBUG("write buffer (size %i):", ft2232_buffer_size
);
443 ft2232_debug_dump_buffer();
446 #ifdef _DEBUG_USB_IO_
447 gettimeofday(&start
, NULL
);
450 if ( ( retval
= ft2232_write(ft2232_buffer
, ft2232_buffer_size
, &bytes_written
) ) != ERROR_OK
)
452 LOG_ERROR("couldn't write MPSSE commands to FT2232");
456 #ifdef _DEBUG_USB_IO_
457 gettimeofday(&inter
, NULL
);
460 if (ft2232_expect_read
)
463 ft2232_buffer_size
= 0;
465 #ifdef _DEBUG_USB_IO_
466 gettimeofday(&inter2
, NULL
);
469 if ( ( retval
= ft2232_read(ft2232_buffer
, ft2232_expect_read
, &bytes_read
) ) != ERROR_OK
)
471 LOG_ERROR("couldn't read from FT2232");
475 #ifdef _DEBUG_USB_IO_
476 gettimeofday(&end
, NULL
);
478 timeval_subtract(&d_inter
, &inter
, &start
);
479 timeval_subtract(&d_inter2
, &inter2
, &start
);
480 timeval_subtract(&d_end
, &end
, &start
);
482 LOG_INFO("inter: %i.%06i, inter2: %i.%06i end: %i.%06i", d_inter
.tv_sec
, d_inter
.tv_usec
, d_inter2
.tv_sec
,
483 d_inter2
.tv_usec
, d_end
.tv_sec
,
487 ft2232_buffer_size
= bytes_read
;
489 if (ft2232_expect_read
!= ft2232_buffer_size
)
491 LOG_ERROR("ft2232_expect_read (%i) != ft2232_buffer_size (%i) (%i retries)", ft2232_expect_read
,
494 ft2232_debug_dump_buffer();
499 #ifdef _DEBUG_USB_COMMS_
500 LOG_DEBUG("read buffer (%i retries): %i bytes", 100 - timeout
, ft2232_buffer_size
);
501 ft2232_debug_dump_buffer();
505 ft2232_expect_read
= 0;
506 ft2232_read_pointer
= 0;
508 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
509 * that wasn't handled by a caller-provided error handler
519 type
= jtag_scan_type(cmd
->cmd
.scan
);
520 if (type
!= SCAN_OUT
)
522 scan_size
= jtag_scan_size(cmd
->cmd
.scan
);
523 buffer
= calloc(CEIL(scan_size
, 8), 1);
524 ft2232_read_scan(type
, buffer
, scan_size
);
525 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
526 retval
= ERROR_JTAG_QUEUE_FAILED
;
538 ft2232_buffer_size
= 0;
544 void ft2232_add_pathmove(pathmove_command_t
* cmd
)
546 int num_states
= cmd
->num_states
;
551 u8 tms_byte
= 0; /* zero this on each MPSSE batch */
555 int num_states_batch
= num_states
> 7 ? 7 : num_states
;
557 /* command "Clock Data to TMS/CS Pin (no Read)" */
560 /* number of states remaining */
561 BUFFER_ADD
= num_states_batch
- 1;
563 while (num_states_batch
--)
565 if (tap_state_transition(tap_get_state(), false) == cmd
->path
[state_count
])
566 buf_set_u32(&tms_byte
, bit_count
++, 1, 0x0);
567 else if (tap_state_transition(tap_get_state(), true) == cmd
->path
[state_count
])
568 buf_set_u32(&tms_byte
, bit_count
++, 1, 0x1);
571 LOG_ERROR( "BUG: %s -> %s isn't a valid TAP transition", tap_state_name(
572 tap_get_state() ), tap_state_name(cmd
->path
[state_count
]) );
576 tap_set_state(cmd
->path
[state_count
]);
581 BUFFER_ADD
= tms_byte
;
584 tap_set_end_state(tap_get_state());
588 void ft2232_add_scan(int ir_scan
, enum scan_type type
, u8
* buffer
, int scan_size
)
590 int num_bytes
= (scan_size
+ 7) / 8;
591 int bits_left
= scan_size
;
595 if ( !( ( !ir_scan
&& (tap_get_state() == TAP_DRSHIFT
) )
596 || ( ir_scan
&& (tap_get_state() == TAP_IRSHIFT
) ) ) )
598 /* command "Clock Data to TMS/CS Pin (no Read)" */
601 BUFFER_ADD
= 0x6; /* scan 7 bits */
606 BUFFER_ADD
= tap_get_tms_path(tap_get_state(), TAP_IRSHIFT
);
607 tap_set_state(TAP_IRSHIFT
);
611 BUFFER_ADD
= tap_get_tms_path(tap_get_state(), TAP_DRSHIFT
);
612 tap_set_state(TAP_DRSHIFT
);
614 /* LOG_DEBUG("added TMS scan (no read)"); */
617 /* add command for complete bytes */
618 while (num_bytes
> 1)
623 /* Clock Data Bytes In and Out LSB First */
625 /* LOG_DEBUG("added TDI bytes (io %i)", num_bytes); */
627 else if (type
== SCAN_OUT
)
629 /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */
631 /* LOG_DEBUG("added TDI bytes (o)"); */
633 else if (type
== SCAN_IN
)
635 /* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */
637 /* LOG_DEBUG("added TDI bytes (i %i)", num_bytes); */
640 thisrun_bytes
= (num_bytes
> 65537) ? 65536 : (num_bytes
- 1);
641 num_bytes
-= thisrun_bytes
;
642 BUFFER_ADD
= (thisrun_bytes
- 1) & 0xff;
643 BUFFER_ADD
= ( (thisrun_bytes
- 1) >> 8 ) & 0xff;
647 /* add complete bytes */
648 while (thisrun_bytes
-- > 0)
650 BUFFER_ADD
= buffer
[cur_byte
];
655 else /* (type == SCAN_IN) */
657 bits_left
-= 8 * (thisrun_bytes
);
661 /* the most signifcant bit is scanned during TAP movement */
663 last_bit
= ( buffer
[cur_byte
] >> (bits_left
- 1) ) & 0x1;
667 /* process remaining bits but the last one */
672 /* Clock Data Bits In and Out LSB First */
674 /* LOG_DEBUG("added TDI bits (io) %i", bits_left - 1); */
676 else if (type
== SCAN_OUT
)
678 /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
680 /* LOG_DEBUG("added TDI bits (o)"); */
682 else if (type
== SCAN_IN
)
684 /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
686 /* LOG_DEBUG("added TDI bits (i %i)", bits_left - 1); */
688 BUFFER_ADD
= bits_left
- 2;
690 BUFFER_ADD
= buffer
[cur_byte
];
693 if ( ( ir_scan
&& (tap_get_end_state() == TAP_IRSHIFT
) )
694 || ( !ir_scan
&& (tap_get_end_state() == TAP_DRSHIFT
) ) )
698 /* Clock Data Bits In and Out LSB First */
700 /* LOG_DEBUG("added TDI bits (io) %i", bits_left - 1); */
702 else if (type
== SCAN_OUT
)
704 /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
706 /* LOG_DEBUG("added TDI bits (o)"); */
708 else if (type
== SCAN_IN
)
710 /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
712 /* LOG_DEBUG("added TDI bits (i %i)", bits_left - 1); */
715 BUFFER_ADD
= last_bit
;
719 /* move from Shift-IR/DR to end state */
720 if (type
!= SCAN_OUT
)
722 /* Clock Data to TMS/CS Pin with Read */
724 /* LOG_DEBUG("added TMS scan (read)"); */
728 /* Clock Data to TMS/CS Pin (no Read) */
730 /* LOG_DEBUG("added TMS scan (no read)"); */
732 BUFFER_ADD
= 0x6; /* scan 7 bits */
734 BUFFER_ADD
= tap_get_tms_path( tap_get_state(), tap_get_end_state() ) | (last_bit
<< 7);
735 tap_set_state( tap_get_end_state() );
740 int ft2232_large_scan(scan_command_t
* cmd
, enum scan_type type
, u8
* buffer
, int scan_size
)
742 int num_bytes
= (scan_size
+ 7) / 8;
743 int bits_left
= scan_size
;
746 u8
* receive_buffer
= malloc( CEIL(scan_size
, 8) );
747 u8
* receive_pointer
= receive_buffer
;
751 int thisrun_read
= 0;
755 LOG_ERROR("BUG: large IR scans are not supported");
759 if (tap_get_state() != TAP_DRSHIFT
)
761 /* command "Clock Data to TMS/CS Pin (no Read)" */
764 BUFFER_ADD
= 0x6; /* scan 7 bits */
767 BUFFER_ADD
= tap_get_tms_path(tap_get_state(), TAP_DRSHIFT
);
768 tap_set_state(TAP_DRSHIFT
);
771 if ( ( retval
= ft2232_write(ft2232_buffer
, ft2232_buffer_size
, &bytes_written
) ) != ERROR_OK
)
773 LOG_ERROR("couldn't write MPSSE commands to FT2232");
776 LOG_DEBUG("ft2232_buffer_size: %i, bytes_written: %i", ft2232_buffer_size
, bytes_written
);
777 ft2232_buffer_size
= 0;
779 /* add command for complete bytes */
780 while (num_bytes
> 1)
786 /* Clock Data Bytes In and Out LSB First */
788 /* LOG_DEBUG("added TDI bytes (io %i)", num_bytes); */
790 else if (type
== SCAN_OUT
)
792 /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */
794 /* LOG_DEBUG("added TDI bytes (o)"); */
796 else if (type
== SCAN_IN
)
798 /* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */
800 /* LOG_DEBUG("added TDI bytes (i %i)", num_bytes); */
803 thisrun_bytes
= (num_bytes
> 65537) ? 65536 : (num_bytes
- 1);
804 thisrun_read
= thisrun_bytes
;
805 num_bytes
-= thisrun_bytes
;
806 BUFFER_ADD
= (thisrun_bytes
- 1) & 0xff;
807 BUFFER_ADD
= ( (thisrun_bytes
- 1) >> 8 ) & 0xff;
811 /* add complete bytes */
812 while (thisrun_bytes
-- > 0)
814 BUFFER_ADD
= buffer
[cur_byte
];
819 else /* (type == SCAN_IN) */
821 bits_left
-= 8 * (thisrun_bytes
);
824 if ( ( retval
= ft2232_write(ft2232_buffer
, ft2232_buffer_size
, &bytes_written
) ) != ERROR_OK
)
826 LOG_ERROR("couldn't write MPSSE commands to FT2232");
829 LOG_DEBUG("ft2232_buffer_size: %i, bytes_written: %i", ft2232_buffer_size
, bytes_written
);
830 ft2232_buffer_size
= 0;
832 if (type
!= SCAN_OUT
)
834 if ( ( retval
= ft2232_read(receive_pointer
, thisrun_read
, &bytes_read
) ) != ERROR_OK
)
836 LOG_ERROR("couldn't read from FT2232");
839 LOG_DEBUG("thisrun_read: %i, bytes_read: %i", thisrun_read
, bytes_read
);
840 receive_pointer
+= bytes_read
;
846 /* the most signifcant bit is scanned during TAP movement */
848 last_bit
= ( buffer
[cur_byte
] >> (bits_left
- 1) ) & 0x1;
852 /* process remaining bits but the last one */
857 /* Clock Data Bits In and Out LSB First */
859 /* LOG_DEBUG("added TDI bits (io) %i", bits_left - 1); */
861 else if (type
== SCAN_OUT
)
863 /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
865 /* LOG_DEBUG("added TDI bits (o)"); */
867 else if (type
== SCAN_IN
)
869 /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
871 /* LOG_DEBUG("added TDI bits (i %i)", bits_left - 1); */
873 BUFFER_ADD
= bits_left
- 2;
875 BUFFER_ADD
= buffer
[cur_byte
];
877 if (type
!= SCAN_OUT
)
881 if (tap_get_end_state() == TAP_DRSHIFT
)
885 /* Clock Data Bits In and Out LSB First */
887 /* LOG_DEBUG("added TDI bits (io) %i", bits_left - 1); */
889 else if (type
== SCAN_OUT
)
891 /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
893 /* LOG_DEBUG("added TDI bits (o)"); */
895 else if (type
== SCAN_IN
)
897 /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
899 /* LOG_DEBUG("added TDI bits (i %i)", bits_left - 1); */
902 BUFFER_ADD
= last_bit
;
906 /* move from Shift-IR/DR to end state */
907 if (type
!= SCAN_OUT
)
909 /* Clock Data to TMS/CS Pin with Read */
911 /* LOG_DEBUG("added TMS scan (read)"); */
915 /* Clock Data to TMS/CS Pin (no Read) */
917 /* LOG_DEBUG("added TMS scan (no read)"); */
920 BUFFER_ADD
= tap_get_tms_path( tap_get_state(), tap_get_end_state() ) | (last_bit
<< 7);
921 tap_set_state( tap_get_end_state() );
924 if (type
!= SCAN_OUT
)
927 if ( ( retval
= ft2232_write(ft2232_buffer
, ft2232_buffer_size
, &bytes_written
) ) != ERROR_OK
)
929 LOG_ERROR("couldn't write MPSSE commands to FT2232");
932 LOG_DEBUG("ft2232_buffer_size: %i, bytes_written: %i", ft2232_buffer_size
, bytes_written
);
933 ft2232_buffer_size
= 0;
935 if (type
!= SCAN_OUT
)
937 if ( ( retval
= ft2232_read(receive_pointer
, thisrun_read
, &bytes_read
) ) != ERROR_OK
)
939 LOG_ERROR("couldn't read from FT2232");
942 LOG_DEBUG("thisrun_read: %i, bytes_read: %i", thisrun_read
, bytes_read
);
943 receive_pointer
+= bytes_read
;
950 int ft2232_predict_scan_out(int scan_size
, enum scan_type type
)
952 int predicted_size
= 3;
953 int num_bytes
= (scan_size
- 1) / 8;
955 if (tap_get_state() != TAP_DRSHIFT
)
958 if (type
== SCAN_IN
) /* only from device to host */
961 predicted_size
+= CEIL(num_bytes
, 65536) * 3;
962 /* remaining bits - 1 (up to 7) */
963 predicted_size
+= ( (scan_size
- 1) % 8 ) ? 2 : 0;
965 else /* host to device, or bidirectional */
968 predicted_size
+= num_bytes
+ CEIL(num_bytes
, 65536) * 3;
969 /* remaining bits -1 (up to 7) */
970 predicted_size
+= ( (scan_size
- 1) % 8 ) ? 3 : 0;
973 return predicted_size
;
977 int ft2232_predict_scan_in(int scan_size
, enum scan_type type
)
979 int predicted_size
= 0;
981 if (type
!= SCAN_OUT
)
984 predicted_size
+= (CEIL(scan_size
, 8) > 1) ? (CEIL(scan_size
, 8) - 1) : 0;
986 /* remaining bits - 1 */
987 predicted_size
+= ( (scan_size
- 1) % 8 ) ? 1 : 0;
989 /* last bit (from TMS scan) */
993 /* LOG_DEBUG("scan_size: %i, predicted_size: %i", scan_size, predicted_size); */
995 return predicted_size
;
999 void usbjtag_reset(int trst
, int srst
)
1003 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1004 low_direction
|= nTRSTnOE
; /* switch to output pin (output is low) */
1006 low_output
&= ~nTRST
; /* switch output low */
1010 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1011 low_direction
&= ~nTRSTnOE
; /* switch to input pin (high-Z + internal and external pullup) */
1013 low_output
|= nTRST
; /* switch output high */
1018 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
1019 low_output
&= ~nSRST
; /* switch output low */
1021 low_direction
|= nSRSTnOE
; /* switch to output pin (output is low) */
1025 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
1026 low_output
|= nSRST
; /* switch output high */
1028 low_direction
&= ~nSRSTnOE
; /* switch to input pin (high-Z) */
1031 /* command "set data bits low byte" */
1033 BUFFER_ADD
= low_output
;
1034 BUFFER_ADD
= low_direction
;
1038 void jtagkey_reset(int trst
, int srst
)
1042 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1043 high_output
&= ~nTRSTnOE
;
1045 high_output
&= ~nTRST
;
1049 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1050 high_output
|= nTRSTnOE
;
1052 high_output
|= nTRST
;
1057 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
1058 high_output
&= ~nSRST
;
1060 high_output
&= ~nSRSTnOE
;
1064 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
1065 high_output
|= nSRST
;
1067 high_output
|= nSRSTnOE
;
1070 /* command "set data bits high byte" */
1072 BUFFER_ADD
= high_output
;
1073 BUFFER_ADD
= high_direction
;
1074 LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst
, srst
, high_output
,
1079 void olimex_jtag_reset(int trst
, int srst
)
1083 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1084 high_output
&= ~nTRSTnOE
;
1086 high_output
&= ~nTRST
;
1090 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1091 high_output
|= nTRSTnOE
;
1093 high_output
|= nTRST
;
1098 high_output
|= nSRST
;
1102 high_output
&= ~nSRST
;
1105 /* command "set data bits high byte" */
1107 BUFFER_ADD
= high_output
;
1108 BUFFER_ADD
= high_direction
;
1109 LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst
, srst
, high_output
,
1114 void axm0432_jtag_reset(int trst
, int srst
)
1118 tap_set_state(TAP_RESET
);
1119 high_output
&= ~nTRST
;
1123 high_output
|= nTRST
;
1128 high_output
&= ~nSRST
;
1132 high_output
|= nSRST
;
1135 /* command "set data bits low byte" */
1137 BUFFER_ADD
= high_output
;
1138 BUFFER_ADD
= high_direction
;
1139 LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst
, srst
, high_output
,
1144 void flyswatter_reset(int trst
, int srst
)
1148 low_output
&= ~nTRST
;
1152 low_output
|= nTRST
;
1157 low_output
|= nSRST
;
1161 low_output
&= ~nSRST
;
1164 /* command "set data bits low byte" */
1166 BUFFER_ADD
= low_output
;
1167 BUFFER_ADD
= low_direction
;
1168 LOG_DEBUG("trst: %i, srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", trst
, srst
, low_output
, low_direction
);
1172 void turtle_reset(int trst
, int srst
)
1178 low_output
|= nSRST
;
1182 low_output
&= ~nSRST
;
1185 /* command "set data bits low byte" */
1187 BUFFER_ADD
= low_output
;
1188 BUFFER_ADD
= low_direction
;
1189 LOG_DEBUG("srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", srst
, low_output
, low_direction
);
1193 void comstick_reset(int trst
, int srst
)
1197 high_output
&= ~nTRST
;
1201 high_output
|= nTRST
;
1206 high_output
&= ~nSRST
;
1210 high_output
|= nSRST
;
1213 /* command "set data bits high byte" */
1215 BUFFER_ADD
= high_output
;
1216 BUFFER_ADD
= high_direction
;
1217 LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst
, srst
, high_output
,
1222 void stm32stick_reset(int trst
, int srst
)
1226 high_output
&= ~nTRST
;
1230 high_output
|= nTRST
;
1235 low_output
&= ~nSRST
;
1239 low_output
|= nSRST
;
1242 /* command "set data bits low byte" */
1244 BUFFER_ADD
= low_output
;
1245 BUFFER_ADD
= low_direction
;
1247 /* command "set data bits high byte" */
1249 BUFFER_ADD
= high_output
;
1250 BUFFER_ADD
= high_direction
;
1251 LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst
, srst
, high_output
,
1256 int ft2232_execute_queue()
1258 jtag_command_t
* cmd
= jtag_command_queue
; /* currently processed command */
1260 int scan_size
; /* size of IR or DR scan */
1261 enum scan_type type
;
1263 int predicted_size
= 0;
1266 first_unsent
= cmd
; /* next command that has to be sent */
1269 /* return ERROR_OK, unless ft2232_send_and_recv reports a failed check
1270 * that wasn't handled by a caller-provided error handler
1274 ft2232_buffer_size
= 0;
1275 ft2232_expect_read
= 0;
1277 /* blink, if the current layout has that feature */
1285 case JTAG_END_STATE
:
1286 if (cmd
->cmd
.end_state
->end_state
!= -1)
1287 ft2232_end_state(cmd
->cmd
.end_state
->end_state
);
1291 /* only send the maximum buffer size that FT2232C can handle */
1293 if (ft2232_buffer_size
+ predicted_size
+ 1 > FT2232_BUFFER_SIZE
)
1295 if (ft2232_send_and_recv(first_unsent
, cmd
) != ERROR_OK
)
1296 retval
= ERROR_JTAG_QUEUE_FAILED
;
1301 if ( (cmd
->cmd
.reset
->trst
== 1) || ( cmd
->cmd
.reset
->srst
&& (jtag_reset_config
& RESET_SRST_PULLS_TRST
) ) )
1303 tap_set_state(TAP_RESET
);
1305 layout
->reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
1308 #ifdef _DEBUG_JTAG_IO_
1309 LOG_DEBUG("trst: %i, srst: %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
1314 /* only send the maximum buffer size that FT2232C can handle */
1316 if (tap_get_state() != TAP_IDLE
)
1317 predicted_size
+= 3;
1318 predicted_size
+= 3 * CEIL(cmd
->cmd
.runtest
->num_cycles
, 7);
1319 if ( (cmd
->cmd
.runtest
->end_state
!= -1) && (cmd
->cmd
.runtest
->end_state
!= TAP_IDLE
) )
1320 predicted_size
+= 3;
1321 if ( (cmd
->cmd
.runtest
->end_state
== -1) && (tap_get_end_state() != TAP_IDLE
) )
1322 predicted_size
+= 3;
1323 if (ft2232_buffer_size
+ predicted_size
+ 1 > FT2232_BUFFER_SIZE
)
1325 if (ft2232_send_and_recv(first_unsent
, cmd
) != ERROR_OK
)
1326 retval
= ERROR_JTAG_QUEUE_FAILED
;
1330 if (tap_get_state() != TAP_IDLE
)
1332 /* command "Clock Data to TMS/CS Pin (no Read)" */
1334 BUFFER_ADD
= 0x6; /* scan 7 bits */
1337 BUFFER_ADD
= tap_get_tms_path(tap_get_state(), TAP_IDLE
);
1338 tap_set_state(TAP_IDLE
);
1341 i
= cmd
->cmd
.runtest
->num_cycles
;
1344 /* command "Clock Data to TMS/CS Pin (no Read)" */
1348 BUFFER_ADD
= (i
> 7) ? 6 : (i
- 1);
1352 tap_set_state(TAP_IDLE
);
1353 i
-= (i
> 7) ? 7 : i
;
1354 /* LOG_DEBUG("added TMS scan (no read)"); */
1357 if (cmd
->cmd
.runtest
->end_state
!= -1)
1358 ft2232_end_state(cmd
->cmd
.runtest
->end_state
);
1360 if ( tap_get_state() != tap_get_end_state() )
1362 /* command "Clock Data to TMS/CS Pin (no Read)" */
1367 BUFFER_ADD
= tap_get_tms_path( tap_get_state(), tap_get_end_state() );
1368 tap_set_state( tap_get_end_state() );
1369 /* LOG_DEBUG("added TMS scan (no read)"); */
1372 #ifdef _DEBUG_JTAG_IO_
1373 LOG_DEBUG( "runtest: %i, end in %s", cmd
->cmd
.runtest
->num_cycles
, tap_state_name( tap_get_end_state() ) );
1377 case JTAG_STATEMOVE
:
1378 /* only send the maximum buffer size that FT2232C can handle */
1380 if (ft2232_buffer_size
+ predicted_size
+ 1 > FT2232_BUFFER_SIZE
)
1382 if (ft2232_send_and_recv(first_unsent
, cmd
) != ERROR_OK
)
1383 retval
= ERROR_JTAG_QUEUE_FAILED
;
1387 if (cmd
->cmd
.statemove
->end_state
!= -1)
1388 ft2232_end_state(cmd
->cmd
.statemove
->end_state
);
1390 /* command "Clock Data to TMS/CS Pin (no Read)" */
1393 BUFFER_ADD
= 0x6; /* scan 7 bits */
1396 BUFFER_ADD
= tap_get_tms_path( tap_get_state(), tap_get_end_state() );
1397 /* LOG_DEBUG("added TMS scan (no read)"); */
1398 tap_set_state( tap_get_end_state() );
1400 #ifdef _DEBUG_JTAG_IO_
1401 LOG_DEBUG( "statemove: %s", tap_state_name( tap_get_end_state() ) );
1406 /* only send the maximum buffer size that FT2232C can handle */
1407 predicted_size
= 3 * CEIL(cmd
->cmd
.pathmove
->num_states
, 7);
1408 if (ft2232_buffer_size
+ predicted_size
+ 1 > FT2232_BUFFER_SIZE
)
1410 if (ft2232_send_and_recv(first_unsent
, cmd
) != ERROR_OK
)
1411 retval
= ERROR_JTAG_QUEUE_FAILED
;
1415 ft2232_add_pathmove(cmd
->cmd
.pathmove
);
1417 #ifdef _DEBUG_JTAG_IO_
1418 LOG_DEBUG( "pathmove: %i states, end in %s", cmd
->cmd
.pathmove
->num_states
,
1419 tap_state_name(cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]) );
1424 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
1425 type
= jtag_scan_type(cmd
->cmd
.scan
);
1426 predicted_size
= ft2232_predict_scan_out(scan_size
, type
);
1427 if ( (predicted_size
+ 1) > FT2232_BUFFER_SIZE
)
1429 LOG_DEBUG("oversized ft2232 scan (predicted_size > FT2232_BUFFER_SIZE)");
1430 /* unsent commands before this */
1431 if (first_unsent
!= cmd
)
1432 if (ft2232_send_and_recv(first_unsent
, cmd
) != ERROR_OK
)
1433 retval
= ERROR_JTAG_QUEUE_FAILED
;
1435 /* current command */
1436 if (cmd
->cmd
.scan
->end_state
!= -1)
1437 ft2232_end_state(cmd
->cmd
.scan
->end_state
);
1438 ft2232_large_scan(cmd
->cmd
.scan
, type
, buffer
, scan_size
);
1440 first_unsent
= cmd
->next
;
1445 else if (ft2232_buffer_size
+ predicted_size
+ 1 > FT2232_BUFFER_SIZE
)
1447 LOG_DEBUG("ft2232 buffer size reached, sending queued commands (first_unsent: %p, cmd: %p)",
1450 if (ft2232_send_and_recv(first_unsent
, cmd
) != ERROR_OK
)
1451 retval
= ERROR_JTAG_QUEUE_FAILED
;
1455 ft2232_expect_read
+= ft2232_predict_scan_in(scan_size
, type
);
1456 /* LOG_DEBUG("new read size: %i", ft2232_expect_read); */
1457 if (cmd
->cmd
.scan
->end_state
!= -1)
1458 ft2232_end_state(cmd
->cmd
.scan
->end_state
);
1459 ft2232_add_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
1463 #ifdef _DEBUG_JTAG_IO_
1464 LOG_DEBUG( "%s scan, %i bits, end in %s", (cmd
->cmd
.scan
->ir_scan
) ? "IR" : "DR", scan_size
,
1465 tap_state_name( tap_get_end_state() ) );
1470 if (ft2232_send_and_recv(first_unsent
, cmd
) != ERROR_OK
)
1471 retval
= ERROR_JTAG_QUEUE_FAILED
;
1472 first_unsent
= cmd
->next
;
1473 jtag_sleep(cmd
->cmd
.sleep
->us
);
1474 #ifdef _DEBUG_JTAG_IO_
1475 LOG_DEBUG( "sleep %i usec while in %s", cmd
->cmd
.sleep
->us
, tap_state_name( tap_get_state() ) );
1479 case JTAG_STABLECLOCKS
:
1481 /* this is only allowed while in a stable state. A check for a stable
1482 * state was done in jtag_add_clocks()
1484 if (ft2232_stableclocks(cmd
->cmd
.stableclocks
->num_cycles
, cmd
) != ERROR_OK
)
1485 retval
= ERROR_JTAG_QUEUE_FAILED
;
1486 #ifdef _DEBUG_JTAG_IO_
1487 LOG_DEBUG( "clocks %i while in %s", cmd
->cmd
.stableclocks
->num_cycles
, tap_state_name( tap_get_state() ) );
1492 LOG_ERROR("BUG: unknown JTAG command type encountered");
1499 if (require_send
> 0)
1500 if (ft2232_send_and_recv(first_unsent
, cmd
) != ERROR_OK
)
1501 retval
= ERROR_JTAG_QUEUE_FAILED
;
1507 #if BUILD_FT2232_FTD2XX == 1
1508 static int ft2232_init_ftd2xx(u16 vid
, u16 pid
, int more
, int* try_more
)
1511 DWORD openex_flags
= 0;
1512 char* openex_string
= NULL
;
1515 LOG_DEBUG("'ft2232' interface using FTD2XX with '%s' layout (%4.4x:%4.4x)", ft2232_layout
, vid
, pid
);
1518 /* Add non-standard Vid/Pid to the linux driver */
1519 if ( ( status
= FT_SetVIDPID(vid
, pid
) ) != FT_OK
)
1521 LOG_WARNING("couldn't add %4.4x:%4.4x", vid
, pid
);
1525 if (ft2232_device_desc
&& ft2232_serial
)
1527 LOG_WARNING("can't open by device description and serial number, giving precedence to serial");
1528 ft2232_device_desc
= NULL
;
1531 if (ft2232_device_desc
)
1533 openex_string
= ft2232_device_desc
;
1534 openex_flags
= FT_OPEN_BY_DESCRIPTION
;
1536 else if (ft2232_serial
)
1538 openex_string
= ft2232_serial
;
1539 openex_flags
= FT_OPEN_BY_SERIAL_NUMBER
;
1543 LOG_ERROR("neither device description nor serial number specified");
1544 LOG_ERROR("please add \"ft2232_device_desc <string>\" or \"ft2232_serial <string>\" to your .cfg file");
1546 return ERROR_JTAG_INIT_FAILED
;
1549 if ( ( status
= FT_OpenEx(openex_string
, openex_flags
, &ftdih
) ) != FT_OK
)
1555 LOG_WARNING("unable to open ftdi device (trying more): %lu", status
);
1557 return ERROR_JTAG_INIT_FAILED
;
1559 LOG_ERROR("unable to open ftdi device: %lu", status
);
1560 status
= FT_ListDevices(&num_devices
, NULL
, FT_LIST_NUMBER_ONLY
);
1561 if (status
== FT_OK
)
1563 char** desc_array
= malloc( sizeof(char*) * (num_devices
+ 1) );
1566 for (i
= 0; i
< num_devices
; i
++)
1567 desc_array
[i
] = malloc(64);
1569 desc_array
[num_devices
] = NULL
;
1571 status
= FT_ListDevices(desc_array
, &num_devices
, FT_LIST_ALL
| openex_flags
);
1573 if (status
== FT_OK
)
1575 LOG_ERROR("ListDevices: %lu\n", num_devices
);
1576 for (i
= 0; i
< num_devices
; i
++)
1577 LOG_ERROR("%i: \"%s\"", i
, desc_array
[i
]);
1580 for (i
= 0; i
< num_devices
; i
++)
1581 free(desc_array
[i
]);
1587 LOG_ERROR("ListDevices: NONE\n");
1589 return ERROR_JTAG_INIT_FAILED
;
1592 if ( ( status
= FT_SetLatencyTimer(ftdih
, ft2232_latency
) ) != FT_OK
)
1594 LOG_ERROR("unable to set latency timer: %lu", status
);
1595 return ERROR_JTAG_INIT_FAILED
;
1598 if ( ( status
= FT_GetLatencyTimer(ftdih
, &latency_timer
) ) != FT_OK
)
1600 LOG_ERROR("unable to get latency timer: %lu", status
);
1601 return ERROR_JTAG_INIT_FAILED
;
1605 LOG_DEBUG("current latency timer: %i", latency_timer
);
1608 if ( ( status
= FT_SetTimeouts(ftdih
, 5000, 5000) ) != FT_OK
)
1610 LOG_ERROR("unable to set timeouts: %lu", status
);
1611 return ERROR_JTAG_INIT_FAILED
;
1614 if ( ( status
= FT_SetBitMode(ftdih
, 0x0b, 2) ) != FT_OK
)
1616 LOG_ERROR("unable to enable bit i/o mode: %lu", status
);
1617 return ERROR_JTAG_INIT_FAILED
;
1624 static int ft2232_purge_ftd2xx(void)
1628 if ( ( status
= FT_Purge(ftdih
, FT_PURGE_RX
| FT_PURGE_TX
) ) != FT_OK
)
1630 LOG_ERROR("error purging ftd2xx device: %lu", status
);
1631 return ERROR_JTAG_INIT_FAILED
;
1638 #endif /* BUILD_FT2232_FTD2XX == 1 */
1640 #if BUILD_FT2232_LIBFTDI == 1
1641 static int ft2232_init_libftdi(u16 vid
, u16 pid
, int more
, int* try_more
)
1645 LOG_DEBUG("'ft2232' interface using libftdi with '%s' layout (%4.4x:%4.4x)",
1646 ft2232_layout
, vid
, pid
);
1648 if (ftdi_init(&ftdic
) < 0)
1649 return ERROR_JTAG_INIT_FAILED
;
1651 /* context, vendor id, product id */
1652 if (ftdi_usb_open_desc(&ftdic
, vid
, pid
, ft2232_device_desc
,
1656 LOG_WARNING("unable to open ftdi device (trying more): %s",
1659 LOG_ERROR("unable to open ftdi device: %s", ftdic
.error_str
);
1661 return ERROR_JTAG_INIT_FAILED
;
1664 if (ftdi_set_interface(&ftdic
, INTERFACE_A
) < 0)
1666 LOG_ERROR("unable to select FT2232 channel A: %s", ftdic
.error_str
);
1667 return ERROR_JTAG_INIT_FAILED
;
1670 if (ftdi_usb_reset(&ftdic
) < 0)
1672 LOG_ERROR("unable to reset ftdi device");
1673 return ERROR_JTAG_INIT_FAILED
;
1676 if (ftdi_set_latency_timer(&ftdic
, ft2232_latency
) < 0)
1678 LOG_ERROR("unable to set latency timer");
1679 return ERROR_JTAG_INIT_FAILED
;
1682 if (ftdi_get_latency_timer(&ftdic
, &latency_timer
) < 0)
1684 LOG_ERROR("unable to get latency timer");
1685 return ERROR_JTAG_INIT_FAILED
;
1689 LOG_DEBUG("current latency timer: %i", latency_timer
);
1692 ftdi_set_bitmode(&ftdic
, 0x0b, 2); /* ctx, JTAG I/O mask */
1698 static int ft2232_purge_libftdi(void)
1700 if (ftdi_usb_purge_buffers(&ftdic
) < 0)
1702 LOG_ERROR("ftdi_purge_buffers: %s", ftdic
.error_str
);
1703 return ERROR_JTAG_INIT_FAILED
;
1710 #endif /* BUILD_FT2232_LIBFTDI == 1 */
1712 int ft2232_init(void)
1717 ft2232_layout_t
* cur_layout
= ft2232_layouts
;
1720 if ( (ft2232_layout
== NULL
) || (ft2232_layout
[0] == 0) )
1722 ft2232_layout
= "usbjtag";
1723 LOG_WARNING("No ft2232 layout specified, using default 'usbjtag'");
1726 while (cur_layout
->name
)
1728 if (strcmp(cur_layout
->name
, ft2232_layout
) == 0)
1730 layout
= cur_layout
;
1738 LOG_ERROR("No matching layout found for %s", ft2232_layout
);
1739 return ERROR_JTAG_INIT_FAILED
;
1745 * "more indicates that there are more IDs to try, so we should
1746 * not print an error for an ID mismatch (but for anything
1749 * try_more indicates that the error code returned indicates an
1750 * ID mismatch (and nothing else) and that we should proceeed
1751 * with the next ID pair.
1753 int more
= ft2232_vid
[i
+ 1] || ft2232_pid
[i
+ 1];
1756 #if BUILD_FT2232_FTD2XX == 1
1757 retval
= ft2232_init_ftd2xx(ft2232_vid
[i
], ft2232_pid
[i
],
1759 #elif BUILD_FT2232_LIBFTDI == 1
1760 retval
= ft2232_init_libftdi(ft2232_vid
[i
], ft2232_pid
[i
],
1765 if (!more
|| !try_more
)
1769 ft2232_buffer_size
= 0;
1770 ft2232_buffer
= malloc(FT2232_BUFFER_SIZE
);
1772 if (layout
->init() != ERROR_OK
)
1773 return ERROR_JTAG_INIT_FAILED
;
1775 ft2232_speed(jtag_speed
);
1777 buf
[0] = 0x85; /* Disconnect TDI/DO to TDO/DI for Loopback */
1778 if ( ( ( retval
= ft2232_write(buf
, 1, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 1) )
1780 LOG_ERROR("couldn't write to FT2232 to disable loopback");
1781 return ERROR_JTAG_INIT_FAILED
;
1784 #if BUILD_FT2232_FTD2XX == 1
1785 return ft2232_purge_ftd2xx();
1786 #elif BUILD_FT2232_LIBFTDI == 1
1787 return ft2232_purge_libftdi();
1794 int usbjtag_init(void)
1800 low_direction
= 0x0b;
1802 if (strcmp(ft2232_layout
, "usbjtag") == 0)
1809 else if (strcmp(ft2232_layout
, "signalyzer") == 0)
1816 else if (strcmp(ft2232_layout
, "evb_lm3s811") == 0)
1823 low_direction
= 0x8b;
1827 LOG_ERROR("BUG: usbjtag_init called for unknown layout '%s'", ft2232_layout
);
1828 return ERROR_JTAG_INIT_FAILED
;
1831 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1833 low_direction
&= ~nTRSTnOE
; /* nTRST input */
1834 low_output
&= ~nTRST
; /* nTRST = 0 */
1838 low_direction
|= nTRSTnOE
; /* nTRST output */
1839 low_output
|= nTRST
; /* nTRST = 1 */
1842 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
1844 low_direction
|= nSRSTnOE
; /* nSRST output */
1845 low_output
|= nSRST
; /* nSRST = 1 */
1849 low_direction
&= ~nSRSTnOE
; /* nSRST input */
1850 low_output
&= ~nSRST
; /* nSRST = 0 */
1853 /* initialize low byte for jtag */
1854 buf
[0] = 0x80; /* command "set data bits low byte" */
1855 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, xRST high) */
1856 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in */
1857 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1859 if ( ( ( ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
1861 LOG_ERROR("couldn't initialize FT2232 with 'USBJTAG' layout");
1862 return ERROR_JTAG_INIT_FAILED
;
1869 int axm0432_jtag_init(void)
1875 low_direction
= 0x2b;
1877 /* initialize low byte for jtag */
1878 buf
[0] = 0x80; /* command "set data bits low byte" */
1879 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
1880 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
1881 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1883 if ( ( ( ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
1885 LOG_ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1886 return ERROR_JTAG_INIT_FAILED
;
1889 if (strcmp(layout
->name
, "axm0432_jtag") == 0)
1892 nTRSTnOE
= 0x0; /* No output enable for TRST*/
1894 nSRSTnOE
= 0x0; /* No output enable for SRST*/
1898 LOG_ERROR("BUG: axm0432_jtag_init called for non axm0432 layout");
1903 high_direction
= 0x0c;
1905 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1907 LOG_ERROR("can't set nTRSTOE to push-pull on the Dicarlo jtag");
1911 high_output
|= nTRST
;
1914 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
1916 LOG_ERROR("can't set nSRST to push-pull on the Dicarlo jtag");
1920 high_output
|= nSRST
;
1923 /* initialize high port */
1924 buf
[0] = 0x82; /* command "set data bits high byte" */
1925 buf
[1] = high_output
; /* value */
1926 buf
[2] = high_direction
; /* all outputs (xRST and xRSTnOE) */
1927 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1929 if ( ( ( ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
1931 LOG_ERROR("couldn't initialize FT2232 with 'Dicarlo' layout");
1932 return ERROR_JTAG_INIT_FAILED
;
1939 int jtagkey_init(void)
1945 low_direction
= 0x1b;
1947 /* initialize low byte for jtag */
1948 buf
[0] = 0x80; /* command "set data bits low byte" */
1949 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
1950 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
1951 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1953 if ( ( ( ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
1955 LOG_ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1956 return ERROR_JTAG_INIT_FAILED
;
1959 if (strcmp(layout
->name
, "jtagkey") == 0)
1966 else if ( (strcmp(layout
->name
, "jtagkey_prototype_v1") == 0)
1967 || (strcmp(layout
->name
, "oocdlink") == 0) )
1976 LOG_ERROR("BUG: jtagkey_init called for non jtagkey layout");
1981 high_direction
= 0x0f;
1983 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1985 high_output
|= nTRSTnOE
;
1986 high_output
&= ~nTRST
;
1990 high_output
&= ~nTRSTnOE
;
1991 high_output
|= nTRST
;
1994 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
1996 high_output
&= ~nSRSTnOE
;
1997 high_output
|= nSRST
;
2001 high_output
|= nSRSTnOE
;
2002 high_output
&= ~nSRST
;
2005 /* initialize high port */
2006 buf
[0] = 0x82; /* command "set data bits high byte" */
2007 buf
[1] = high_output
; /* value */
2008 buf
[2] = high_direction
; /* all outputs (xRST and xRSTnOE) */
2009 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
2011 if ( ( ( ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
2013 LOG_ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
2014 return ERROR_JTAG_INIT_FAILED
;
2021 int olimex_jtag_init(void)
2027 low_direction
= 0x1b;
2029 /* initialize low byte for jtag */
2030 buf
[0] = 0x80; /* command "set data bits low byte" */
2031 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
2032 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
2033 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
2035 if ( ( ( ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
2037 LOG_ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
2038 return ERROR_JTAG_INIT_FAILED
;
2044 nSRSTnOE
= 0x00; /* no output enable for nSRST */
2047 high_direction
= 0x0f;
2049 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
2051 high_output
|= nTRSTnOE
;
2052 high_output
&= ~nTRST
;
2056 high_output
&= ~nTRSTnOE
;
2057 high_output
|= nTRST
;
2060 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
2062 LOG_ERROR("can't set nSRST to push-pull on the Olimex ARM-USB-OCD");
2066 high_output
&= ~nSRST
;
2069 /* turn red LED on */
2070 high_output
|= 0x08;
2072 /* initialize high port */
2073 buf
[0] = 0x82; /* command "set data bits high byte" */
2074 buf
[1] = high_output
; /* value */
2075 buf
[2] = high_direction
; /* all outputs (xRST and xRSTnOE) */
2076 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
2078 if ( ( ( ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
2080 LOG_ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
2081 return ERROR_JTAG_INIT_FAILED
;
2088 int flyswatter_init(void)
2094 low_direction
= 0xfb;
2096 /* initialize low byte for jtag */
2097 buf
[0] = 0x80; /* command "set data bits low byte" */
2098 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
2099 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE[12]=out, n[ST]srst=out */
2100 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
2102 if ( ( ( ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
2104 LOG_ERROR("couldn't initialize FT2232 with 'flyswatter' layout");
2105 return ERROR_JTAG_INIT_FAILED
;
2109 nTRSTnOE
= 0x0; /* not output enable for nTRST */
2111 nSRSTnOE
= 0x00; /* no output enable for nSRST */
2114 high_direction
= 0x0c;
2116 /* turn red LED1 on, LED2 off */
2117 high_output
|= 0x08;
2119 /* initialize high port */
2120 buf
[0] = 0x82; /* command "set data bits high byte" */
2121 buf
[1] = high_output
; /* value */
2122 buf
[2] = high_direction
; /* all outputs (xRST and xRSTnOE) */
2123 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
2125 if ( ( ( ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
2127 LOG_ERROR("couldn't initialize FT2232 with 'flyswatter' layout");
2128 return ERROR_JTAG_INIT_FAILED
;
2135 int turtle_init(void)
2141 low_direction
= 0x5b;
2143 /* initialize low byte for jtag */
2144 buf
[0] = 0x80; /* command "set data bits low byte" */
2145 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
2146 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
2147 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
2149 if ( ( ( ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
2151 LOG_ERROR("couldn't initialize FT2232 with 'turtelizer2' layout");
2152 return ERROR_JTAG_INIT_FAILED
;
2158 high_direction
= 0x0C;
2160 /* initialize high port */
2161 buf
[0] = 0x82; /* command "set data bits high byte" */
2162 buf
[1] = high_output
;
2163 buf
[2] = high_direction
;
2164 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
2166 if ( ( ( ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
2168 LOG_ERROR("couldn't initialize FT2232 with 'turtelizer2' layout");
2169 return ERROR_JTAG_INIT_FAILED
;
2176 int comstick_init(void)
2182 low_direction
= 0x0b;
2184 /* initialize low byte for jtag */
2185 buf
[0] = 0x80; /* command "set data bits low byte" */
2186 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
2187 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
2188 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
2190 if ( ( ( ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
2192 LOG_ERROR("couldn't initialize FT2232 with 'comstick' layout");
2193 return ERROR_JTAG_INIT_FAILED
;
2197 nTRSTnOE
= 0x00; /* no output enable for nTRST */
2199 nSRSTnOE
= 0x00; /* no output enable for nSRST */
2202 high_direction
= 0x03;
2204 /* initialize high port */
2205 buf
[0] = 0x82; /* command "set data bits high byte" */
2206 buf
[1] = high_output
;
2207 buf
[2] = high_direction
;
2208 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
2210 if ( ( ( ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
2212 LOG_ERROR("couldn't initialize FT2232 with 'comstick' layout");
2213 return ERROR_JTAG_INIT_FAILED
;
2220 int stm32stick_init(void)
2226 low_direction
= 0x8b;
2228 /* initialize low byte for jtag */
2229 buf
[0] = 0x80; /* command "set data bits low byte" */
2230 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
2231 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
2232 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
2234 if ( ( ( ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
2236 LOG_ERROR("couldn't initialize FT2232 with 'stm32stick' layout");
2237 return ERROR_JTAG_INIT_FAILED
;
2241 nTRSTnOE
= 0x00; /* no output enable for nTRST */
2243 nSRSTnOE
= 0x00; /* no output enable for nSRST */
2246 high_direction
= 0x03;
2248 /* initialize high port */
2249 buf
[0] = 0x82; /* command "set data bits high byte" */
2250 buf
[1] = high_output
;
2251 buf
[2] = high_direction
;
2252 LOG_DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
2254 if ( ( ( ft2232_write(buf
, 3, &bytes_written
) ) != ERROR_OK
) || (bytes_written
!= 3) )
2256 LOG_ERROR("couldn't initialize FT2232 with 'stm32stick' layout");
2257 return ERROR_JTAG_INIT_FAILED
;
2264 void olimex_jtag_blink(void)
2266 /* Olimex ARM-USB-OCD has a LED connected to ACBUS3
2267 * ACBUS3 is bit 3 of the GPIOH port
2269 if (high_output
& 0x08)
2271 /* set port pin high */
2272 high_output
&= 0x07;
2276 /* set port pin low */
2277 high_output
|= 0x08;
2281 BUFFER_ADD
= high_output
;
2282 BUFFER_ADD
= high_direction
;
2286 void turtle_jtag_blink(void)
2289 * Turtelizer2 has two LEDs connected to ACBUS2 and ACBUS3
2291 if (high_output
& 0x08)
2301 BUFFER_ADD
= high_output
;
2302 BUFFER_ADD
= high_direction
;
2306 int ft2232_quit(void)
2308 #if BUILD_FT2232_FTD2XX == 1
2311 status
= FT_Close(ftdih
);
2312 #elif BUILD_FT2232_LIBFTDI == 1
2313 ftdi_disable_bitbang(&ftdic
);
2315 ftdi_usb_close(&ftdic
);
2317 ftdi_deinit(&ftdic
);
2320 free(ft2232_buffer
);
2321 ft2232_buffer
= NULL
;
2327 int ft2232_handle_device_desc_command(struct command_context_s
* cmd_ctx
, char* cmd
, char** args
, int argc
)
2331 ft2232_device_desc
= strdup(args
[0]);
2335 LOG_ERROR("expected exactly one argument to ft2232_device_desc <description>");
2342 int ft2232_handle_serial_command(struct command_context_s
* cmd_ctx
, char* cmd
, char** args
, int argc
)
2346 ft2232_serial
= strdup(args
[0]);
2350 LOG_ERROR("expected exactly one argument to ft2232_serial <serial-number>");
2357 int ft2232_handle_layout_command(struct command_context_s
* cmd_ctx
, char* cmd
, char** args
, int argc
)
2362 ft2232_layout
= malloc(strlen(args
[0]) + 1);
2363 strcpy(ft2232_layout
, args
[0]);
2369 int ft2232_handle_vid_pid_command(struct command_context_s
* cmd_ctx
, char* cmd
, char** args
, int argc
)
2373 if (argc
> MAX_USB_IDS
* 2)
2375 LOG_WARNING("ignoring extra IDs in ft2232_vid_pid "
2376 "(maximum is %d pairs)", MAX_USB_IDS
);
2377 argc
= MAX_USB_IDS
* 2;
2379 if ( argc
< 2 || (argc
& 1) )
2381 LOG_WARNING("incomplete ft2232_vid_pid configuration directive");
2386 for (i
= 0; i
+ 1 < argc
; i
+= 2)
2388 ft2232_vid
[i
>> 1] = strtol(args
[i
], NULL
, 0);
2389 ft2232_pid
[i
>> 1] = strtol(args
[i
+ 1], NULL
, 0);
2393 * Explicitly terminate, in case there are multiples instances of
2396 ft2232_vid
[i
>> 1] = ft2232_pid
[i
>> 1] = 0;
2402 int ft2232_handle_latency_command(struct command_context_s
* cmd_ctx
, char* cmd
, char** args
, int argc
)
2406 ft2232_latency
= atoi(args
[0]);
2410 LOG_ERROR("expected exactly one argument to ft2232_latency <ms>");
2417 static int ft2232_stableclocks(int num_cycles
, jtag_command_t
* cmd
)
2421 /* 7 bits of either ones or zeros. */
2422 u8 tms
= (tap_get_state() == TAP_RESET
? 0x7F : 0x00);
2424 while (num_cycles
> 0)
2426 /* the command 0x4b, "Clock Data to TMS/CS Pin (no Read)" handles
2427 * at most 7 bits per invocation. Here we invoke it potentially
2430 int bitcount_per_command
= (num_cycles
> 7) ? 7 : num_cycles
;
2432 if (ft2232_buffer_size
+ 3 >= FT2232_BUFFER_SIZE
)
2434 if (ft2232_send_and_recv(first_unsent
, cmd
) != ERROR_OK
)
2435 retval
= ERROR_JTAG_QUEUE_FAILED
;
2440 /* command "Clock Data to TMS/CS Pin (no Read)" */
2444 BUFFER_ADD
= bitcount_per_command
- 1;
2446 /* TMS data bits are either all zeros or ones to stay in the current stable state */
2451 num_cycles
-= bitcount_per_command
;
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)