1 /***************************************************************************
2 * Copyright (C) 2004, 2006 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
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 ***************************************************************************/
29 #include "replacements.h"
31 /* project specific includes */
35 #include "configuration.h"
36 #include "time_support.h"
43 /* FT2232 access library includes */
44 #if BUILD_FT2232_FTD2XX == 1
46 #elif BUILD_FT2232_LIBFTDI == 1
53 /* enable this to debug io latency
56 #define _DEBUG_USB_IO_
59 /* enable this to debug communication
62 #define _DEBUG_USB_COMMS_
65 int ft2232_execute_queue(void);
67 int ft2232_speed(int speed
);
68 int ft2232_register_commands(struct command_context_s
*cmd_ctx
);
69 int ft2232_init(void);
70 int ft2232_quit(void);
72 int ft2232_handle_device_desc_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
73 int ft2232_handle_layout_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
74 int ft2232_handle_vid_pid_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
76 char *ft2232_device_desc
= NULL
;
77 char *ft2232_layout
= NULL
;
78 u16 ft2232_vid
= 0x0403;
79 u16 ft2232_pid
= 0x6010;
81 typedef struct ft2232_layout_s
85 void(*reset
)(int trst
, int srst
);
88 int usbjtag_init(void);
89 int jtagkey_init(void);
90 void usbjtag_reset(int trst
, int srst
);
91 void jtagkey_reset(int trst
, int srst
);
93 ft2232_layout_t ft2232_layouts
[] =
95 {"usbjtag", usbjtag_init
, usbjtag_reset
},
96 {"jtagkey", jtagkey_init
, jtagkey_reset
},
97 {"jtagkey_prototype_v1", jtagkey_init
, jtagkey_reset
},
98 {"signalyzer", usbjtag_init
, usbjtag_reset
},
102 static u8 nTRST
, nTRSTnOE
, nSRST
, nSRSTnOE
;
104 static ft2232_layout_t
*layout
;
105 static u8 low_output
= 0x0;
106 static u8 low_direction
= 0x0;
107 static u8 high_output
= 0x0;
108 static u8 high_direction
= 0x0;
110 #if BUILD_FT2232_FTD2XX == 1
111 static FT_HANDLE ftdih
= NULL
;
112 #elif BUILD_FT2232_LIBFTDI == 1
113 static struct ftdi_context ftdic
;
116 static u8
*ft2232_buffer
= NULL
;
117 static int ft2232_buffer_size
= 0;
118 static int ft2232_read_pointer
= 0;
119 static int ft2232_expect_read
= 0;
120 #define FT2232_BUFFER_SIZE 131072
121 #define BUFFER_ADD ft2232_buffer[ft2232_buffer_size++]
122 #define BUFFER_READ ft2232_buffer[ft2232_read_pointer++]
124 jtag_interface_t ft2232_interface
=
129 .execute_queue
= ft2232_execute_queue
,
131 .support_statemove
= 1,
133 .speed
= ft2232_speed
,
134 .register_commands
= ft2232_register_commands
,
139 int ft2232_write(u8
*buf
, int size
, u32
* bytes_written
)
141 #if BUILD_FT2232_FTD2XX == 1
143 DWORD dw_bytes_written
;
144 if ((status
= FT_Write(ftdih
, buf
, size
, &dw_bytes_written
)) != FT_OK
)
146 *bytes_written
= dw_bytes_written
;
147 ERROR("FT_Write returned: %i", status
);
148 return ERROR_JTAG_DEVICE_ERROR
;
152 *bytes_written
= dw_bytes_written
;
155 #elif BUILD_FT2232_LIBFTDI == 1
157 if ((retval
= ftdi_write_data(&ftdic
, buf
, size
)) < 0)
160 ERROR("ftdi_write_data: %s", ftdi_get_error_string(&ftdic
));
161 return ERROR_JTAG_DEVICE_ERROR
;
165 *bytes_written
= retval
;
171 int ft2232_read(u8
* buf
, int size
, u32
* bytes_read
)
173 #if BUILD_FT2232_FTD2XX == 1
176 if ((status
= FT_Read(ftdih
, buf
, size
, &dw_bytes_read
)) != FT_OK
)
178 *bytes_read
= dw_bytes_read
;
179 ERROR("FT_Read returned: %i", status
);
180 return ERROR_JTAG_DEVICE_ERROR
;
182 *bytes_read
= dw_bytes_read
;
185 #elif BUILD_FT2232_LIBFTDI == 1
190 while ((*bytes_read
< size
) && timeout
--)
192 if ((retval
= ftdi_read_data(&ftdic
, buf
+ *bytes_read
, size
- *bytes_read
)) < 0)
195 ERROR("ftdi_read_data: %s", ftdi_get_error_string(&ftdic
));
196 return ERROR_JTAG_DEVICE_ERROR
;
198 *bytes_read
+= retval
;
204 int ft2232_speed(int speed
)
210 buf
[0] = 0x86; /* command "set divisor" */
211 buf
[1] = speed
& 0xff; /* valueL (0=6MHz, 1=3MHz, 2=1.5MHz, ...*/
212 buf
[2] = (speed
>> 8) & 0xff; /* valueH */
214 DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
215 if (((retval
= ft2232_write(buf
, 3, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 3))
217 ERROR("couldn't set FT2232 TCK speed");
224 int ft2232_register_commands(struct command_context_s
*cmd_ctx
)
226 register_command(cmd_ctx
, NULL
, "ft2232_device_desc", ft2232_handle_device_desc_command
,
227 COMMAND_CONFIG
, NULL
);
228 register_command(cmd_ctx
, NULL
, "ft2232_layout", ft2232_handle_layout_command
,
229 COMMAND_CONFIG
, NULL
);
230 register_command(cmd_ctx
, NULL
, "ft2232_vid_pid", ft2232_handle_vid_pid_command
,
231 COMMAND_CONFIG
, NULL
);
235 void ft2232_end_state(state
)
237 if (tap_move_map
[state
] != -1)
241 ERROR("BUG: %i is not a valid end state", state
);
246 void ft2232_read_scan(enum scan_type type
, u8
* buffer
, int scan_size
)
248 int num_bytes
= ((scan_size
+ 7) / 8);
249 int bits_left
= scan_size
;
252 while(num_bytes
-- > 1)
254 buffer
[cur_byte
] = BUFFER_READ
;
259 buffer
[cur_byte
] = 0x0;
263 buffer
[cur_byte
] = BUFFER_READ
>> 1;
266 buffer
[cur_byte
] = (buffer
[cur_byte
] | ((BUFFER_READ
& 0x02) << 6)) >> (8 - bits_left
);
270 void ft2232_debug_dump_buffer(void)
276 for (i
= 0; i
< ft2232_buffer_size
; i
++)
278 line_p
+= snprintf(line_p
, 256 - (line_p
- line
), "%2.2x ", ft2232_buffer
[i
]);
290 int ft2232_send_and_recv(jtag_command_t
*first
, jtag_command_t
*last
)
300 #ifdef _DEBUG_USB_IO_
301 struct timeval start
, inter
, inter2
, end
;
302 struct timeval d_inter
, d_inter2
, d_end
;
305 #ifdef _DEBUG_USB_COMMS_
306 DEBUG("write buffer (size %i):", ft2232_buffer_size
);
307 ft2232_debug_dump_buffer();
310 #ifdef _DEBUG_USB_IO_
311 gettimeofday(&start
, NULL
);
314 if ((retval
= ft2232_write(ft2232_buffer
, ft2232_buffer_size
, &bytes_written
)) != ERROR_OK
)
316 ERROR("couldn't write MPSSE commands to FT2232");
320 #ifdef _DEBUG_USB_IO_
321 gettimeofday(&inter
, NULL
);
324 if (ft2232_expect_read
)
327 ft2232_buffer_size
= 0;
329 #ifdef _DEBUG_USB_IO_
330 gettimeofday(&inter2
, NULL
);
333 if ((retval
= ft2232_read(ft2232_buffer
, ft2232_expect_read
, &bytes_read
)) != ERROR_OK
)
335 ERROR("couldn't read from FT2232");
339 #ifdef _DEBUG_USB_IO_
340 gettimeofday(&end
, NULL
);
342 timeval_subtract(&d_inter
, &inter
, &start
);
343 timeval_subtract(&d_inter2
, &inter2
, &start
);
344 timeval_subtract(&d_end
, &end
, &start
);
346 INFO("inter: %i.%i, inter2: %i.%i end: %i.%i", d_inter
.tv_sec
, d_inter
.tv_usec
, d_inter2
.tv_sec
, d_inter2
.tv_usec
, d_end
.tv_sec
, d_end
.tv_usec
);
350 ft2232_buffer_size
= bytes_read
;
352 if (ft2232_expect_read
!= ft2232_buffer_size
)
354 ERROR("ft2232_expect_read (%i) != ft2232_buffer_size (%i) (%i retries)", ft2232_expect_read
, ft2232_buffer_size
, 100 - timeout
);
355 ft2232_debug_dump_buffer();
360 #ifdef _DEBUG_USB_COMMS_
361 DEBUG("read buffer (%i retries): %i bytes", 100 - timeout
, ft2232_buffer_size
);
362 ft2232_debug_dump_buffer();
366 ft2232_expect_read
= 0;
367 ft2232_read_pointer
= 0;
375 type
= jtag_scan_type(cmd
->cmd
.scan
);
376 if (type
!= SCAN_OUT
)
378 scan_size
= jtag_scan_size(cmd
->cmd
.scan
);
379 buffer
= calloc(CEIL(scan_size
, 8), 1);
380 ft2232_read_scan(type
, buffer
, scan_size
);
381 jtag_read_buffer(buffer
, cmd
->cmd
.scan
);
391 ft2232_buffer_size
= 0;
396 void ft2232_add_pathmove(pathmove_command_t
*cmd
)
398 int num_states
= cmd
->num_states
;
408 /* command "Clock Data to TMS/CS Pin (no Read)" */
410 /* number of states remaining */
411 BUFFER_ADD
= (num_states
% 7) - 1;
413 while (num_states
% 7)
415 if (tap_transitions
[cur_state
].low
== cmd
->path
[state_count
])
416 buf_set_u32(&tms_byte
, bit_count
++, 1, 0x0);
417 else if (tap_transitions
[cur_state
].high
== cmd
->path
[state_count
])
418 buf_set_u32(&tms_byte
, bit_count
++, 1, 0x1);
421 ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings
[cur_state
], tap_state_strings
[cmd
->path
[state_count
]]);
425 cur_state
= cmd
->path
[state_count
];
430 BUFFER_ADD
= tms_byte
;
433 end_state
= cur_state
;
436 void ft2232_add_scan(int ir_scan
, enum scan_type type
, u8
*buffer
, int scan_size
)
438 int num_bytes
= (scan_size
+ 7) / 8;
439 int bits_left
= scan_size
;
443 if ((!ir_scan
&& (cur_state
!= TAP_SD
)) || (ir_scan
&& (cur_state
!= TAP_SI
)))
445 /* command "Clock Data to TMS/CS Pin (no Read)" */
452 BUFFER_ADD
= TAP_MOVE(cur_state
, TAP_SI
);
457 BUFFER_ADD
= TAP_MOVE(cur_state
, TAP_SD
);
460 //DEBUG("added TMS scan (no read)");
463 /* add command for complete bytes */
468 /* Clock Data Bytes In and Out LSB First */
470 //DEBUG("added TDI bytes (io %i)", num_bytes);
472 else if (type
== SCAN_OUT
)
474 /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */
476 //DEBUG("added TDI bytes (o)");
478 else if (type
== SCAN_IN
)
480 /* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */
482 //DEBUG("added TDI bytes (i %i)", num_bytes);
484 BUFFER_ADD
= (num_bytes
-2) & 0xff;
485 BUFFER_ADD
= ((num_bytes
-2) >> 8) & 0xff;
489 /* add complete bytes */
490 while(num_bytes
-- > 1)
492 BUFFER_ADD
= buffer
[cur_byte
];
499 bits_left
-= 8 * (num_bytes
- 1);
502 /* the most signifcant bit is scanned during TAP movement */
504 last_bit
= (buffer
[cur_byte
] >> (bits_left
- 1)) & 0x1;
508 /* process remaining bits but the last one */
513 /* Clock Data Bits In and Out LSB First */
515 //DEBUG("added TDI bits (io) %i", bits_left - 1);
517 else if (type
== SCAN_OUT
)
519 /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
521 //DEBUG("added TDI bits (o)");
523 else if (type
== SCAN_IN
)
525 /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
527 //DEBUG("added TDI bits (i %i)", bits_left - 1);
529 BUFFER_ADD
= bits_left
- 2;
531 BUFFER_ADD
= buffer
[cur_byte
];
534 /* move from Shift-IR/DR to end state */
535 if (type
!= SCAN_OUT
)
537 /* Clock Data to TMS/CS Pin with Read */
539 //DEBUG("added TMS scan (read)");
543 /* Clock Data to TMS/CS Pin (no Read) */
545 //DEBUG("added TMS scan (no read)");
548 BUFFER_ADD
= TAP_MOVE(cur_state
, end_state
) | (last_bit
<< 7);
549 cur_state
= end_state
;
553 int ft2232_predict_scan_out(int scan_size
, enum scan_type type
)
555 int predicted_size
= 3;
557 if (cur_state
!= TAP_SD
)
560 if (type
== SCAN_IN
) /* only from device to host */
563 predicted_size
+= (CEIL(scan_size
, 8) > 1) ? 3 : 0;
564 /* remaining bits - 1 (up to 7) */
565 predicted_size
+= ((scan_size
- 1) % 8) ? 2 : 0;
567 else /* host to device, or bidirectional */
570 predicted_size
+= (CEIL(scan_size
, 8) > 1) ? (CEIL(scan_size
, 8) + 3 - 1) : 0;
571 /* remaining bits -1 (up to 7) */
572 predicted_size
+= ((scan_size
- 1) % 8) ? 3 : 0;
575 return predicted_size
;
578 int ft2232_predict_scan_in(int scan_size
, enum scan_type type
)
580 int predicted_size
= 0;
582 if (type
!= SCAN_OUT
)
585 predicted_size
+= (CEIL(scan_size
, 8) > 1) ? (CEIL(scan_size
, 8) - 1) : 0;
586 /* remaining bits - 1 */
587 predicted_size
+= ((scan_size
- 1) % 8) ? 1 : 0;
588 /* last bit (from TMS scan) */
592 //DEBUG("scan_size: %i, predicted_size: %i", scan_size, predicted_size);
594 return predicted_size
;
597 void usbjtag_reset(int trst
, int srst
)
602 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
603 low_direction
|= nTRSTnOE
; /* switch to output pin (output is low) */
605 low_output
&= ~nTRST
; /* switch output low */
609 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
610 low_direction
&= ~nTRSTnOE
; /* switch to input pin (high-Z + internal and external pullup) */
612 low_output
|= nTRST
; /* switch output high */
617 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
618 low_output
&= ~nSRST
; /* switch output low */
620 low_direction
|= nSRSTnOE
; /* switch to output pin (output is low) */
624 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
625 low_output
|= nSRST
; /* switch output high */
627 low_direction
&= ~nSRSTnOE
; /* switch to input pin (high-Z) */
630 /* command "set data bits low byte" */
632 BUFFER_ADD
= low_output
;
633 BUFFER_ADD
= low_direction
;
637 void jtagkey_reset(int trst
, int srst
)
642 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
643 high_output
&= ~nTRSTnOE
;
645 high_output
&= ~nTRST
;
649 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
650 high_output
|= nTRSTnOE
;
652 high_output
|= nTRST
;
657 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
658 high_output
&= ~nSRST
;
660 high_output
&= ~nSRSTnOE
;
664 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
665 high_output
|= nSRST
;
667 high_output
|= nSRSTnOE
;
670 /* command "set data bits high byte" */
672 BUFFER_ADD
= high_output
;
673 BUFFER_ADD
= high_direction
;
674 DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst
, srst
, high_output
, high_direction
);
677 int ft2232_execute_queue()
679 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
680 jtag_command_t
*first_unsent
= cmd
; /* next command that has to be sent */
682 int scan_size
; /* size of IR or DR scan */
685 int predicted_size
= 0;
686 int require_send
= 0;
688 ft2232_buffer_size
= 0;
689 ft2232_expect_read
= 0;
696 if (cmd
->cmd
.end_state
->end_state
!= -1)
697 ft2232_end_state(cmd
->cmd
.end_state
->end_state
);
700 /* only send the maximum buffer size that FT2232C can handle */
702 if (ft2232_buffer_size
+ predicted_size
+ 1 > FT2232_BUFFER_SIZE
)
704 ft2232_send_and_recv(first_unsent
, cmd
);
709 layout
->reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
712 #ifdef _DEBUG_JTAG_IO_
713 DEBUG("trst: %i, srst: %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
717 /* only send the maximum buffer size that FT2232C can handle */
719 if (cur_state
!= TAP_RTI
)
721 predicted_size
+= 3 * CEIL(cmd
->cmd
.runtest
->num_cycles
, 7);
722 if ((cmd
->cmd
.runtest
->end_state
!= -1) && (cmd
->cmd
.runtest
->end_state
!= TAP_RTI
))
724 if ((cmd
->cmd
.runtest
->end_state
== -1) && (end_state
!= TAP_RTI
))
726 if (ft2232_buffer_size
+ predicted_size
+ 1 > FT2232_BUFFER_SIZE
)
728 ft2232_send_and_recv(first_unsent
, cmd
);
732 if (cur_state
!= TAP_RTI
)
734 /* command "Clock Data to TMS/CS Pin (no Read)" */
739 BUFFER_ADD
= TAP_MOVE(cur_state
, TAP_RTI
);
743 i
= cmd
->cmd
.runtest
->num_cycles
;
746 /* command "Clock Data to TMS/CS Pin (no Read)" */
749 BUFFER_ADD
= (i
> 7) ? 6 : (i
- 1);
753 i
-= (i
> 7) ? 7 : i
;
754 //DEBUG("added TMS scan (no read)");
756 if (cmd
->cmd
.runtest
->end_state
!= -1)
757 ft2232_end_state(cmd
->cmd
.runtest
->end_state
);
758 if (cur_state
!= end_state
)
760 /* command "Clock Data to TMS/CS Pin (no Read)" */
765 BUFFER_ADD
= TAP_MOVE(cur_state
, end_state
);
766 cur_state
= end_state
;
767 //DEBUG("added TMS scan (no read)");
770 #ifdef _DEBUG_JTAG_IO_
771 DEBUG("runtest: %i, end in %i", cmd
->cmd
.runtest
->num_cycles
, end_state
);
775 /* only send the maximum buffer size that FT2232C can handle */
777 if (ft2232_buffer_size
+ predicted_size
+ 1 > FT2232_BUFFER_SIZE
)
779 ft2232_send_and_recv(first_unsent
, cmd
);
783 if (cmd
->cmd
.statemove
->end_state
!= -1)
784 ft2232_end_state(cmd
->cmd
.statemove
->end_state
);
785 /* command "Clock Data to TMS/CS Pin (no Read)" */
790 BUFFER_ADD
= TAP_MOVE(cur_state
, end_state
);
791 //DEBUG("added TMS scan (no read)");
792 cur_state
= end_state
;
794 #ifdef _DEBUG_JTAG_IO_
795 DEBUG("statemove: %i", end_state
);
799 /* only send the maximum buffer size that FT2232C can handle */
800 predicted_size
= 3 * CEIL(cmd
->cmd
.pathmove
->num_states
, 7);
801 if (ft2232_buffer_size
+ predicted_size
+ 1 > FT2232_BUFFER_SIZE
)
803 ft2232_send_and_recv(first_unsent
, cmd
);
807 ft2232_add_pathmove(cmd
->cmd
.pathmove
);
809 #ifdef _DEBUG_JTAG_IO_
810 DEBUG("pathmove: %i states, end in %i", cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
814 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
815 type
= jtag_scan_type(cmd
->cmd
.scan
);
816 predicted_size
= ft2232_predict_scan_out(scan_size
, type
);
817 if (ft2232_buffer_size
+ predicted_size
+ 1 > FT2232_BUFFER_SIZE
)
819 DEBUG("ftd2xx buffer size reached, sending queued commands (first_unsent: %x, cmd: %x)", first_unsent
, cmd
);
820 ft2232_send_and_recv(first_unsent
, cmd
);
824 ft2232_expect_read
+= ft2232_predict_scan_in(scan_size
, type
);
825 //DEBUG("new read size: %i", ft2232_expect_read);
826 if (cmd
->cmd
.scan
->end_state
!= -1)
827 ft2232_end_state(cmd
->cmd
.scan
->end_state
);
828 ft2232_add_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
832 #ifdef _DEBUG_JTAG_IO_
833 DEBUG("%s scan, %i bit, end in %i", (cmd
->cmd
.scan
->ir_scan
) ? "IR" : "DR", scan_size
, end_state
);
837 ft2232_send_and_recv(first_unsent
, cmd
);
838 first_unsent
= cmd
->next
;
839 jtag_sleep(cmd
->cmd
.sleep
->us
);
840 #ifdef _DEBUG_JTAG_IO_
841 DEBUG("sleep %i usec", cmd
->cmd
.sleep
->us
);
845 ERROR("BUG: unknown JTAG command type encountered");
851 if (require_send
> 0)
852 ft2232_send_and_recv(first_unsent
, cmd
);
857 int ft2232_init(void)
864 #if BUILD_FT2232_FTD2XX == 1
868 ft2232_layout_t
*cur_layout
= ft2232_layouts
;
870 if ((ft2232_layout
== NULL
) || (ft2232_layout
[0] == 0))
872 ft2232_layout
= "usbjtag";
873 WARNING("No ft2232 layout specified, using default 'usbjtag'");
876 while (cur_layout
->name
)
878 if (strcmp(cur_layout
->name
, ft2232_layout
) == 0)
888 ERROR("No matching layout found for %s", ft2232_layout
);
889 return ERROR_JTAG_INIT_FAILED
;
892 #if BUILD_FT2232_FTD2XX == 1
893 DEBUG("'ft2232' interface using FTD2XX with '%s' layout", ft2232_layout
);
894 #elif BUILD_FT2232_LIBFTDI == 1
895 DEBUG("'ft2232' interface using libftdi with '%s' layout", ft2232_layout
);
898 #if BUILD_FT2232_FTD2XX == 1
899 /* Open by device description */
900 if (ft2232_device_desc
== NULL
)
902 WARNING("no ftd2xx device description specified, using default 'Dual RS232'");
903 ft2232_device_desc
= "Dual RS232";
907 /* Add non-standard Vid/Pid to the linux driver */
908 if ((status
= FT_SetVIDPID(ft2232_vid
, ft2232_pid
)) != FT_OK
)
910 WARNING("couldn't add %4.4x:%4.4x", ft2232_vid
, ft2232_pid
);
914 if ((status
= FT_OpenEx(ft2232_device_desc
, FT_OPEN_BY_DESCRIPTION
, &ftdih
)) != FT_OK
)
918 ERROR("unable to open ftdi device: %i", status
);
919 status
= FT_ListDevices(&num_devices
, NULL
, FT_LIST_NUMBER_ONLY
);
922 char **desc_array
= malloc(sizeof(char*) * (num_devices
+ 1));
925 for (i
= 0; i
< num_devices
; i
++)
926 desc_array
[i
] = malloc(64);
927 desc_array
[num_devices
] = NULL
;
929 status
= FT_ListDevices(desc_array
, &num_devices
, FT_LIST_ALL
| FT_OPEN_BY_DESCRIPTION
);
933 ERROR("ListDevices: %d\n", num_devices
);
934 for (i
= 0; i
< num_devices
; i
++)
935 ERROR("%i: %s", i
, desc_array
[i
]);
938 for (i
= 0; i
< num_devices
; i
++)
944 printf("ListDevices: NONE\n");
946 return ERROR_JTAG_INIT_FAILED
;
949 if ((status
= FT_SetLatencyTimer(ftdih
, 2)) != FT_OK
)
951 ERROR("unable to set latency timer: %i", status
);
952 return ERROR_JTAG_INIT_FAILED
;
955 if ((status
= FT_GetLatencyTimer(ftdih
, &latency_timer
)) != FT_OK
)
957 ERROR("unable to get latency timer: %i", status
);
958 return ERROR_JTAG_INIT_FAILED
;
962 DEBUG("current latency timer: %i", latency_timer
);
965 if ((status
= FT_SetBitMode(ftdih
, 0x0b, 2)) != FT_OK
)
967 ERROR("unable to enable bit i/o mode: %i", status
);
968 return ERROR_JTAG_INIT_FAILED
;
970 #elif BUILD_FT2232_LIBFTDI == 1
971 if (ftdi_init(&ftdic
) < 0)
972 return ERROR_JTAG_INIT_FAILED
;
974 /* context, vendor id, product id */
975 if (ftdi_usb_open(&ftdic
, ft2232_vid
, ft2232_pid
) < 0)
977 ERROR("unable to open ftdi device: %s", ftdic
.error_str
);
978 return ERROR_JTAG_INIT_FAILED
;
981 if (ftdi_usb_reset(&ftdic
) < 0)
983 ERROR("unable to reset ftdi device");
984 return ERROR_JTAG_INIT_FAILED
;
987 if (ftdi_set_latency_timer(&ftdic
, 2) < 0)
989 ERROR("unable to set latency timer");
990 return ERROR_JTAG_INIT_FAILED
;
993 if (ftdi_get_latency_timer(&ftdic
, &latency_timer
) < 0)
995 ERROR("unable to get latency timer");
996 return ERROR_JTAG_INIT_FAILED
;
1000 DEBUG("current latency timer: %i", latency_timer
);
1003 ftdic
.bitbang_mode
= 0; /* Reset controller */
1004 ftdi_enable_bitbang(&ftdic
, 0x0b); /* ctx, JTAG I/O mask */
1006 ftdic
.bitbang_mode
= 2; /* MPSSE mode */
1007 ftdi_enable_bitbang(&ftdic
, 0x0b); /* ctx, JTAG I/O mask */
1010 ft2232_buffer_size
= 0;
1011 ft2232_buffer
= malloc(FT2232_BUFFER_SIZE
);
1013 if (layout
->init() != ERROR_OK
)
1014 return ERROR_JTAG_INIT_FAILED
;
1016 ft2232_speed(jtag_speed
);
1018 buf
[0] = 0x85; /* Disconnect TDI/DO to TDO/DI for Loopback */
1019 if (((retval
= ft2232_write(buf
, 1, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 1))
1021 ERROR("couldn't write to FT2232 to disable loopback");
1022 return ERROR_JTAG_INIT_FAILED
;
1025 #if BUILD_FT2232_FTD2XX == 1
1026 if ((status
= FT_Purge(ftdih
, FT_PURGE_RX
| FT_PURGE_TX
)) != FT_OK
)
1028 ERROR("error purging ftd2xx device: %i", status
);
1029 return ERROR_JTAG_INIT_FAILED
;
1031 #elif BUILD_FT2232_LIBFTDI == 1
1032 if (ftdi_usb_purge_buffers(&ftdic
) < 0)
1034 ERROR("ftdi_purge_buffers: %s", ftdic
.error_str
);
1035 return ERROR_JTAG_INIT_FAILED
;
1042 int usbjtag_init(void)
1048 low_direction
= 0x0b;
1050 if (strcmp(ft2232_layout
, "usbjtag") == 0)
1057 else if (strcmp(ft2232_layout
, "signalyzer") == 0)
1066 ERROR("BUG: usbjtag_init called for unknown layout '%s'", ft2232_layout
);
1067 return ERROR_JTAG_INIT_FAILED
;
1070 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1072 low_direction
&= ~nTRSTnOE
; /* nTRST input */
1073 low_output
&= ~nTRST
; /* nTRST = 0 */
1077 low_direction
|= nTRSTnOE
; /* nTRST output */
1078 low_output
|= nTRST
; /* nTRST = 1 */
1081 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
1083 low_direction
|= nSRSTnOE
; /* nSRST output */
1084 low_output
|= nSRST
; /* nSRST = 1 */
1088 low_direction
&= ~nSRSTnOE
; /* nSRST input */
1089 low_output
&= ~nSRST
; /* nSRST = 0 */
1092 /* initialize low byte for jtag */
1093 buf
[0] = 0x80; /* command "set data bits low byte" */
1094 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, xRST high) */
1095 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in */
1096 DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1098 if (((ft2232_write(buf
, 3, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 3))
1100 ERROR("couldn't initialize FT2232 with 'USBJTAG' layout");
1101 return ERROR_JTAG_INIT_FAILED
;
1107 int jtagkey_init(void)
1113 low_direction
= 0x1b;
1115 /* initialize low byte for jtag */
1116 buf
[0] = 0x80; /* command "set data bits low byte" */
1117 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
1118 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
1119 DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1121 if (((ft2232_write(buf
, 3, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 3))
1123 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1124 return ERROR_JTAG_INIT_FAILED
;
1127 if (strcmp(layout
->name
, "jtagkey") == 0)
1134 else if (strcmp(layout
->name
, "jtagkey_prototype_v1") == 0)
1143 ERROR("BUG: jtagkey_init called for non jtagkey layout");
1148 high_direction
= 0x0f;
1150 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1152 high_output
|= nTRSTnOE
;
1153 high_output
&= ~nTRST
;
1157 high_output
&= ~nTRSTnOE
;
1158 high_output
|= nTRST
;
1161 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
1163 high_output
&= ~nSRSTnOE
;
1164 high_output
|= nSRST
;
1168 high_output
|= nSRSTnOE
;
1169 high_output
&= ~nSRST
;
1172 /* initialize high port */
1173 buf
[0] = 0x82; /* command "set data bits low byte" */
1174 buf
[1] = high_output
; /* value */
1175 buf
[2] = high_direction
; /* all outputs (xRST and xRSTnOE) */
1176 DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1178 if (((ft2232_write(buf
, 3, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 3))
1180 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1181 return ERROR_JTAG_INIT_FAILED
;
1187 int ft2232_quit(void)
1189 #if BUILD_FT2232_FTD2XX == 1
1192 status
= FT_Close(ftdih
);
1193 #elif BUILD_FT2232_LIBFTDI == 1
1194 ftdi_disable_bitbang(&ftdic
);
1196 ftdi_usb_close(&ftdic
);
1198 ftdi_deinit(&ftdic
);
1201 free(ft2232_buffer
);
1206 int ft2232_handle_device_desc_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1210 ft2232_device_desc
= strdup(args
[0]);
1214 ERROR("expected exactly one argument to ft2232_device_desc <description>");
1220 int ft2232_handle_layout_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1225 ft2232_layout
= malloc(strlen(args
[0]) + 1);
1226 strcpy(ft2232_layout
, args
[0]);
1231 int ft2232_handle_vid_pid_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1235 ft2232_vid
= strtol(args
[0], NULL
, 0);
1236 ft2232_pid
= strtol(args
[1], NULL
, 0);
1240 WARNING("incomplete ft2232_vid_pid configuration directive");
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)