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
);
89 /* init procedures for supported layouts */
90 int usbjtag_init(void);
91 int jtagkey_init(void);
92 int olimex_jtag_init(void);
94 /* reset procedures for supported layouts */
95 void usbjtag_reset(int trst
, int srst
);
96 void jtagkey_reset(int trst
, int srst
);
97 void olimex_jtag_reset(int trst
, int srst
);
99 /* blink procedures for layouts that support a blinking led */
100 void olimex_jtag_blink(void);
102 ft2232_layout_t ft2232_layouts
[] =
104 {"usbjtag", usbjtag_init
, usbjtag_reset
, NULL
},
105 {"jtagkey", jtagkey_init
, jtagkey_reset
, NULL
},
106 {"jtagkey_prototype_v1", jtagkey_init
, jtagkey_reset
, NULL
},
107 {"signalyzer", usbjtag_init
, usbjtag_reset
, NULL
},
108 {"olimex-jtag", olimex_jtag_init
, olimex_jtag_reset
, olimex_jtag_blink
},
112 static u8 nTRST
, nTRSTnOE
, nSRST
, nSRSTnOE
;
114 static ft2232_layout_t
*layout
;
115 static u8 low_output
= 0x0;
116 static u8 low_direction
= 0x0;
117 static u8 high_output
= 0x0;
118 static u8 high_direction
= 0x0;
120 #if BUILD_FT2232_FTD2XX == 1
121 static FT_HANDLE ftdih
= NULL
;
122 #elif BUILD_FT2232_LIBFTDI == 1
123 static struct ftdi_context ftdic
;
126 static u8
*ft2232_buffer
= NULL
;
127 static int ft2232_buffer_size
= 0;
128 static int ft2232_read_pointer
= 0;
129 static int ft2232_expect_read
= 0;
130 #define FT2232_BUFFER_SIZE 131072
131 #define BUFFER_ADD ft2232_buffer[ft2232_buffer_size++]
132 #define BUFFER_READ ft2232_buffer[ft2232_read_pointer++]
134 jtag_interface_t ft2232_interface
=
139 .execute_queue
= ft2232_execute_queue
,
141 .support_pathmove
= 1,
143 .speed
= ft2232_speed
,
144 .register_commands
= ft2232_register_commands
,
149 int ft2232_write(u8
*buf
, int size
, u32
* bytes_written
)
151 #if BUILD_FT2232_FTD2XX == 1
153 DWORD dw_bytes_written
;
154 if ((status
= FT_Write(ftdih
, buf
, size
, &dw_bytes_written
)) != FT_OK
)
156 *bytes_written
= dw_bytes_written
;
157 ERROR("FT_Write returned: %i", status
);
158 return ERROR_JTAG_DEVICE_ERROR
;
162 *bytes_written
= dw_bytes_written
;
165 #elif BUILD_FT2232_LIBFTDI == 1
167 if ((retval
= ftdi_write_data(&ftdic
, buf
, size
)) < 0)
170 ERROR("ftdi_write_data: %s", ftdi_get_error_string(&ftdic
));
171 return ERROR_JTAG_DEVICE_ERROR
;
175 *bytes_written
= retval
;
181 int ft2232_read(u8
* buf
, int size
, u32
* bytes_read
)
183 #if BUILD_FT2232_FTD2XX == 1
186 if ((status
= FT_Read(ftdih
, buf
, size
, &dw_bytes_read
)) != FT_OK
)
188 *bytes_read
= dw_bytes_read
;
189 ERROR("FT_Read returned: %i", status
);
190 return ERROR_JTAG_DEVICE_ERROR
;
192 *bytes_read
= dw_bytes_read
;
195 #elif BUILD_FT2232_LIBFTDI == 1
200 while ((*bytes_read
< size
) && timeout
--)
202 if ((retval
= ftdi_read_data(&ftdic
, buf
+ *bytes_read
, size
- *bytes_read
)) < 0)
205 ERROR("ftdi_read_data: %s", ftdi_get_error_string(&ftdic
));
206 return ERROR_JTAG_DEVICE_ERROR
;
208 *bytes_read
+= retval
;
214 int ft2232_speed(int speed
)
220 buf
[0] = 0x86; /* command "set divisor" */
221 buf
[1] = speed
& 0xff; /* valueL (0=6MHz, 1=3MHz, 2=1.5MHz, ...*/
222 buf
[2] = (speed
>> 8) & 0xff; /* valueH */
224 DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
225 if (((retval
= ft2232_write(buf
, 3, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 3))
227 ERROR("couldn't set FT2232 TCK speed");
234 int ft2232_register_commands(struct command_context_s
*cmd_ctx
)
236 register_command(cmd_ctx
, NULL
, "ft2232_device_desc", ft2232_handle_device_desc_command
,
237 COMMAND_CONFIG
, NULL
);
238 register_command(cmd_ctx
, NULL
, "ft2232_layout", ft2232_handle_layout_command
,
239 COMMAND_CONFIG
, NULL
);
240 register_command(cmd_ctx
, NULL
, "ft2232_vid_pid", ft2232_handle_vid_pid_command
,
241 COMMAND_CONFIG
, NULL
);
245 void ft2232_end_state(state
)
247 if (tap_move_map
[state
] != -1)
251 ERROR("BUG: %i is not a valid end state", state
);
256 void ft2232_read_scan(enum scan_type type
, u8
* buffer
, int scan_size
)
258 int num_bytes
= ((scan_size
+ 7) / 8);
259 int bits_left
= scan_size
;
262 while(num_bytes
-- > 1)
264 buffer
[cur_byte
] = BUFFER_READ
;
269 buffer
[cur_byte
] = 0x0;
273 buffer
[cur_byte
] = BUFFER_READ
>> 1;
276 buffer
[cur_byte
] = (buffer
[cur_byte
] | ((BUFFER_READ
& 0x02) << 6)) >> (8 - bits_left
);
280 void ft2232_debug_dump_buffer(void)
286 for (i
= 0; i
< ft2232_buffer_size
; i
++)
288 line_p
+= snprintf(line_p
, 256 - (line_p
- line
), "%2.2x ", ft2232_buffer
[i
]);
300 int ft2232_send_and_recv(jtag_command_t
*first
, jtag_command_t
*last
)
310 #ifdef _DEBUG_USB_IO_
311 struct timeval start
, inter
, inter2
, end
;
312 struct timeval d_inter
, d_inter2
, d_end
;
315 #ifdef _DEBUG_USB_COMMS_
316 DEBUG("write buffer (size %i):", ft2232_buffer_size
);
317 ft2232_debug_dump_buffer();
320 #ifdef _DEBUG_USB_IO_
321 gettimeofday(&start
, NULL
);
324 if ((retval
= ft2232_write(ft2232_buffer
, ft2232_buffer_size
, &bytes_written
)) != ERROR_OK
)
326 ERROR("couldn't write MPSSE commands to FT2232");
330 #ifdef _DEBUG_USB_IO_
331 gettimeofday(&inter
, NULL
);
334 if (ft2232_expect_read
)
337 ft2232_buffer_size
= 0;
339 #ifdef _DEBUG_USB_IO_
340 gettimeofday(&inter2
, NULL
);
343 if ((retval
= ft2232_read(ft2232_buffer
, ft2232_expect_read
, &bytes_read
)) != ERROR_OK
)
345 ERROR("couldn't read from FT2232");
349 #ifdef _DEBUG_USB_IO_
350 gettimeofday(&end
, NULL
);
352 timeval_subtract(&d_inter
, &inter
, &start
);
353 timeval_subtract(&d_inter2
, &inter2
, &start
);
354 timeval_subtract(&d_end
, &end
, &start
);
356 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
);
360 ft2232_buffer_size
= bytes_read
;
362 if (ft2232_expect_read
!= ft2232_buffer_size
)
364 ERROR("ft2232_expect_read (%i) != ft2232_buffer_size (%i) (%i retries)", ft2232_expect_read
, ft2232_buffer_size
, 100 - timeout
);
365 ft2232_debug_dump_buffer();
370 #ifdef _DEBUG_USB_COMMS_
371 DEBUG("read buffer (%i retries): %i bytes", 100 - timeout
, ft2232_buffer_size
);
372 ft2232_debug_dump_buffer();
376 ft2232_expect_read
= 0;
377 ft2232_read_pointer
= 0;
385 type
= jtag_scan_type(cmd
->cmd
.scan
);
386 if (type
!= SCAN_OUT
)
388 scan_size
= jtag_scan_size(cmd
->cmd
.scan
);
389 buffer
= calloc(CEIL(scan_size
, 8), 1);
390 ft2232_read_scan(type
, buffer
, scan_size
);
391 jtag_read_buffer(buffer
, cmd
->cmd
.scan
);
401 ft2232_buffer_size
= 0;
406 void ft2232_add_pathmove(pathmove_command_t
*cmd
)
408 int num_states
= cmd
->num_states
;
418 /* command "Clock Data to TMS/CS Pin (no Read)" */
420 /* number of states remaining */
421 BUFFER_ADD
= (num_states
% 7) - 1;
423 while (num_states
% 7)
425 if (tap_transitions
[cur_state
].low
== cmd
->path
[state_count
])
426 buf_set_u32(&tms_byte
, bit_count
++, 1, 0x0);
427 else if (tap_transitions
[cur_state
].high
== cmd
->path
[state_count
])
428 buf_set_u32(&tms_byte
, bit_count
++, 1, 0x1);
431 ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings
[cur_state
], tap_state_strings
[cmd
->path
[state_count
]]);
435 cur_state
= cmd
->path
[state_count
];
440 BUFFER_ADD
= tms_byte
;
443 end_state
= cur_state
;
446 void ft2232_add_scan(int ir_scan
, enum scan_type type
, u8
*buffer
, int scan_size
)
448 int num_bytes
= (scan_size
+ 7) / 8;
449 int bits_left
= scan_size
;
453 if ((!ir_scan
&& (cur_state
!= TAP_SD
)) || (ir_scan
&& (cur_state
!= TAP_SI
)))
455 /* command "Clock Data to TMS/CS Pin (no Read)" */
462 BUFFER_ADD
= TAP_MOVE(cur_state
, TAP_SI
);
467 BUFFER_ADD
= TAP_MOVE(cur_state
, TAP_SD
);
470 //DEBUG("added TMS scan (no read)");
473 /* add command for complete bytes */
478 /* Clock Data Bytes In and Out LSB First */
480 //DEBUG("added TDI bytes (io %i)", num_bytes);
482 else if (type
== SCAN_OUT
)
484 /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */
486 //DEBUG("added TDI bytes (o)");
488 else if (type
== SCAN_IN
)
490 /* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */
492 //DEBUG("added TDI bytes (i %i)", num_bytes);
494 BUFFER_ADD
= (num_bytes
-2) & 0xff;
495 BUFFER_ADD
= ((num_bytes
-2) >> 8) & 0xff;
499 /* add complete bytes */
500 while(num_bytes
-- > 1)
502 BUFFER_ADD
= buffer
[cur_byte
];
509 bits_left
-= 8 * (num_bytes
- 1);
512 /* the most signifcant bit is scanned during TAP movement */
514 last_bit
= (buffer
[cur_byte
] >> (bits_left
- 1)) & 0x1;
518 /* process remaining bits but the last one */
523 /* Clock Data Bits In and Out LSB First */
525 //DEBUG("added TDI bits (io) %i", bits_left - 1);
527 else if (type
== SCAN_OUT
)
529 /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
531 //DEBUG("added TDI bits (o)");
533 else if (type
== SCAN_IN
)
535 /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
537 //DEBUG("added TDI bits (i %i)", bits_left - 1);
539 BUFFER_ADD
= bits_left
- 2;
541 BUFFER_ADD
= buffer
[cur_byte
];
544 /* move from Shift-IR/DR to end state */
545 if (type
!= SCAN_OUT
)
547 /* Clock Data to TMS/CS Pin with Read */
549 //DEBUG("added TMS scan (read)");
553 /* Clock Data to TMS/CS Pin (no Read) */
555 //DEBUG("added TMS scan (no read)");
558 BUFFER_ADD
= TAP_MOVE(cur_state
, end_state
) | (last_bit
<< 7);
559 cur_state
= end_state
;
563 int ft2232_predict_scan_out(int scan_size
, enum scan_type type
)
565 int predicted_size
= 3;
567 if (cur_state
!= TAP_SD
)
570 if (type
== SCAN_IN
) /* only from device to host */
573 predicted_size
+= (CEIL(scan_size
, 8) > 1) ? 3 : 0;
574 /* remaining bits - 1 (up to 7) */
575 predicted_size
+= ((scan_size
- 1) % 8) ? 2 : 0;
577 else /* host to device, or bidirectional */
580 predicted_size
+= (CEIL(scan_size
, 8) > 1) ? (CEIL(scan_size
, 8) + 3 - 1) : 0;
581 /* remaining bits -1 (up to 7) */
582 predicted_size
+= ((scan_size
- 1) % 8) ? 3 : 0;
585 return predicted_size
;
588 int ft2232_predict_scan_in(int scan_size
, enum scan_type type
)
590 int predicted_size
= 0;
592 if (type
!= SCAN_OUT
)
595 predicted_size
+= (CEIL(scan_size
, 8) > 1) ? (CEIL(scan_size
, 8) - 1) : 0;
596 /* remaining bits - 1 */
597 predicted_size
+= ((scan_size
- 1) % 8) ? 1 : 0;
598 /* last bit (from TMS scan) */
602 //DEBUG("scan_size: %i, predicted_size: %i", scan_size, predicted_size);
604 return predicted_size
;
607 void usbjtag_reset(int trst
, int srst
)
612 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
613 low_direction
|= nTRSTnOE
; /* switch to output pin (output is low) */
615 low_output
&= ~nTRST
; /* switch output low */
619 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
620 low_direction
&= ~nTRSTnOE
; /* switch to input pin (high-Z + internal and external pullup) */
622 low_output
|= nTRST
; /* switch output high */
627 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
628 low_output
&= ~nSRST
; /* switch output low */
630 low_direction
|= nSRSTnOE
; /* switch to output pin (output is low) */
634 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
635 low_output
|= nSRST
; /* switch output high */
637 low_direction
&= ~nSRSTnOE
; /* switch to input pin (high-Z) */
640 /* command "set data bits low byte" */
642 BUFFER_ADD
= low_output
;
643 BUFFER_ADD
= low_direction
;
647 void jtagkey_reset(int trst
, int srst
)
652 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
653 high_output
&= ~nTRSTnOE
;
655 high_output
&= ~nTRST
;
659 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
660 high_output
|= nTRSTnOE
;
662 high_output
|= nTRST
;
667 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
668 high_output
&= ~nSRST
;
670 high_output
&= ~nSRSTnOE
;
674 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
675 high_output
|= nSRST
;
677 high_output
|= nSRSTnOE
;
680 /* command "set data bits high byte" */
682 BUFFER_ADD
= high_output
;
683 BUFFER_ADD
= high_direction
;
684 DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst
, srst
, high_output
, high_direction
);
687 void olimex_jtag_reset(int trst
, int srst
)
692 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
693 high_output
&= ~nTRSTnOE
;
695 high_output
&= ~nTRST
;
699 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
700 high_output
|= nTRSTnOE
;
702 high_output
|= nTRST
;
707 high_output
|= nSRST
;
711 high_output
&= ~nSRST
;
714 /* command "set data bits high byte" */
716 BUFFER_ADD
= high_output
;
717 BUFFER_ADD
= high_direction
;
718 DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst
, srst
, high_output
, high_direction
);
721 int ft2232_execute_queue()
723 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
724 jtag_command_t
*first_unsent
= cmd
; /* next command that has to be sent */
726 int scan_size
; /* size of IR or DR scan */
729 int predicted_size
= 0;
730 int require_send
= 0;
732 ft2232_buffer_size
= 0;
733 ft2232_expect_read
= 0;
735 /* blink, if the current layout has that feature */
744 if (cmd
->cmd
.end_state
->end_state
!= -1)
745 ft2232_end_state(cmd
->cmd
.end_state
->end_state
);
748 /* only send the maximum buffer size that FT2232C can handle */
750 if (ft2232_buffer_size
+ predicted_size
+ 1 > FT2232_BUFFER_SIZE
)
752 ft2232_send_and_recv(first_unsent
, cmd
);
757 layout
->reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
760 #ifdef _DEBUG_JTAG_IO_
761 DEBUG("trst: %i, srst: %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
765 /* only send the maximum buffer size that FT2232C can handle */
767 if (cur_state
!= TAP_RTI
)
769 predicted_size
+= 3 * CEIL(cmd
->cmd
.runtest
->num_cycles
, 7);
770 if ((cmd
->cmd
.runtest
->end_state
!= -1) && (cmd
->cmd
.runtest
->end_state
!= TAP_RTI
))
772 if ((cmd
->cmd
.runtest
->end_state
== -1) && (end_state
!= TAP_RTI
))
774 if (ft2232_buffer_size
+ predicted_size
+ 1 > FT2232_BUFFER_SIZE
)
776 ft2232_send_and_recv(first_unsent
, cmd
);
780 if (cur_state
!= TAP_RTI
)
782 /* command "Clock Data to TMS/CS Pin (no Read)" */
787 BUFFER_ADD
= TAP_MOVE(cur_state
, TAP_RTI
);
791 i
= cmd
->cmd
.runtest
->num_cycles
;
794 /* command "Clock Data to TMS/CS Pin (no Read)" */
797 BUFFER_ADD
= (i
> 7) ? 6 : (i
- 1);
801 i
-= (i
> 7) ? 7 : i
;
802 //DEBUG("added TMS scan (no read)");
804 if (cmd
->cmd
.runtest
->end_state
!= -1)
805 ft2232_end_state(cmd
->cmd
.runtest
->end_state
);
806 if (cur_state
!= end_state
)
808 /* command "Clock Data to TMS/CS Pin (no Read)" */
813 BUFFER_ADD
= TAP_MOVE(cur_state
, end_state
);
814 cur_state
= end_state
;
815 //DEBUG("added TMS scan (no read)");
818 #ifdef _DEBUG_JTAG_IO_
819 DEBUG("runtest: %i, end in %i", cmd
->cmd
.runtest
->num_cycles
, end_state
);
823 /* only send the maximum buffer size that FT2232C can handle */
825 if (ft2232_buffer_size
+ predicted_size
+ 1 > FT2232_BUFFER_SIZE
)
827 ft2232_send_and_recv(first_unsent
, cmd
);
831 if (cmd
->cmd
.statemove
->end_state
!= -1)
832 ft2232_end_state(cmd
->cmd
.statemove
->end_state
);
833 /* command "Clock Data to TMS/CS Pin (no Read)" */
838 BUFFER_ADD
= TAP_MOVE(cur_state
, end_state
);
839 //DEBUG("added TMS scan (no read)");
840 cur_state
= end_state
;
842 #ifdef _DEBUG_JTAG_IO_
843 DEBUG("statemove: %i", end_state
);
847 /* only send the maximum buffer size that FT2232C can handle */
848 predicted_size
= 3 * CEIL(cmd
->cmd
.pathmove
->num_states
, 7);
849 if (ft2232_buffer_size
+ predicted_size
+ 1 > FT2232_BUFFER_SIZE
)
851 ft2232_send_and_recv(first_unsent
, cmd
);
855 ft2232_add_pathmove(cmd
->cmd
.pathmove
);
857 #ifdef _DEBUG_JTAG_IO_
858 DEBUG("pathmove: %i states, end in %i", cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
862 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
863 type
= jtag_scan_type(cmd
->cmd
.scan
);
864 predicted_size
= ft2232_predict_scan_out(scan_size
, type
);
865 if (ft2232_buffer_size
+ predicted_size
+ 1 > FT2232_BUFFER_SIZE
)
867 DEBUG("ftd2xx buffer size reached, sending queued commands (first_unsent: %x, cmd: %x)", first_unsent
, cmd
);
868 ft2232_send_and_recv(first_unsent
, cmd
);
872 ft2232_expect_read
+= ft2232_predict_scan_in(scan_size
, type
);
873 //DEBUG("new read size: %i", ft2232_expect_read);
874 if (cmd
->cmd
.scan
->end_state
!= -1)
875 ft2232_end_state(cmd
->cmd
.scan
->end_state
);
876 ft2232_add_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
880 #ifdef _DEBUG_JTAG_IO_
881 DEBUG("%s scan, %i bit, end in %i", (cmd
->cmd
.scan
->ir_scan
) ? "IR" : "DR", scan_size
, end_state
);
885 ft2232_send_and_recv(first_unsent
, cmd
);
886 first_unsent
= cmd
->next
;
887 jtag_sleep(cmd
->cmd
.sleep
->us
);
888 #ifdef _DEBUG_JTAG_IO_
889 DEBUG("sleep %i usec", cmd
->cmd
.sleep
->us
);
893 ERROR("BUG: unknown JTAG command type encountered");
899 if (require_send
> 0)
900 ft2232_send_and_recv(first_unsent
, cmd
);
905 int ft2232_init(void)
912 #if BUILD_FT2232_FTD2XX == 1
916 ft2232_layout_t
*cur_layout
= ft2232_layouts
;
918 if ((ft2232_layout
== NULL
) || (ft2232_layout
[0] == 0))
920 ft2232_layout
= "usbjtag";
921 WARNING("No ft2232 layout specified, using default 'usbjtag'");
924 while (cur_layout
->name
)
926 if (strcmp(cur_layout
->name
, ft2232_layout
) == 0)
936 ERROR("No matching layout found for %s", ft2232_layout
);
937 return ERROR_JTAG_INIT_FAILED
;
940 #if BUILD_FT2232_FTD2XX == 1
941 DEBUG("'ft2232' interface using FTD2XX with '%s' layout", ft2232_layout
);
942 #elif BUILD_FT2232_LIBFTDI == 1
943 DEBUG("'ft2232' interface using libftdi with '%s' layout", ft2232_layout
);
946 #if BUILD_FT2232_FTD2XX == 1
947 /* Open by device description */
948 if (ft2232_device_desc
== NULL
)
950 WARNING("no ftd2xx device description specified, using default 'Dual RS232'");
951 ft2232_device_desc
= "Dual RS232";
955 /* Add non-standard Vid/Pid to the linux driver */
956 if ((status
= FT_SetVIDPID(ft2232_vid
, ft2232_pid
)) != FT_OK
)
958 WARNING("couldn't add %4.4x:%4.4x", ft2232_vid
, ft2232_pid
);
962 if ((status
= FT_OpenEx(ft2232_device_desc
, FT_OPEN_BY_DESCRIPTION
, &ftdih
)) != FT_OK
)
966 ERROR("unable to open ftdi device: %i", status
);
967 status
= FT_ListDevices(&num_devices
, NULL
, FT_LIST_NUMBER_ONLY
);
970 char **desc_array
= malloc(sizeof(char*) * (num_devices
+ 1));
973 for (i
= 0; i
< num_devices
; i
++)
974 desc_array
[i
] = malloc(64);
975 desc_array
[num_devices
] = NULL
;
977 status
= FT_ListDevices(desc_array
, &num_devices
, FT_LIST_ALL
| FT_OPEN_BY_DESCRIPTION
);
981 ERROR("ListDevices: %d\n", num_devices
);
982 for (i
= 0; i
< num_devices
; i
++)
983 ERROR("%i: %s", i
, desc_array
[i
]);
986 for (i
= 0; i
< num_devices
; i
++)
992 printf("ListDevices: NONE\n");
994 return ERROR_JTAG_INIT_FAILED
;
997 if ((status
= FT_SetLatencyTimer(ftdih
, 2)) != FT_OK
)
999 ERROR("unable to set latency timer: %i", status
);
1000 return ERROR_JTAG_INIT_FAILED
;
1003 if ((status
= FT_GetLatencyTimer(ftdih
, &latency_timer
)) != FT_OK
)
1005 ERROR("unable to get latency timer: %i", status
);
1006 return ERROR_JTAG_INIT_FAILED
;
1010 DEBUG("current latency timer: %i", latency_timer
);
1013 if ((status
= FT_SetBitMode(ftdih
, 0x0b, 2)) != FT_OK
)
1015 ERROR("unable to enable bit i/o mode: %i", status
);
1016 return ERROR_JTAG_INIT_FAILED
;
1018 #elif BUILD_FT2232_LIBFTDI == 1
1019 if (ftdi_init(&ftdic
) < 0)
1020 return ERROR_JTAG_INIT_FAILED
;
1022 /* context, vendor id, product id */
1023 if (ftdi_usb_open(&ftdic
, ft2232_vid
, ft2232_pid
) < 0)
1025 ERROR("unable to open ftdi device: %s", ftdic
.error_str
);
1026 return ERROR_JTAG_INIT_FAILED
;
1029 if (ftdi_usb_reset(&ftdic
) < 0)
1031 ERROR("unable to reset ftdi device");
1032 return ERROR_JTAG_INIT_FAILED
;
1035 if (ftdi_set_latency_timer(&ftdic
, 2) < 0)
1037 ERROR("unable to set latency timer");
1038 return ERROR_JTAG_INIT_FAILED
;
1041 if (ftdi_get_latency_timer(&ftdic
, &latency_timer
) < 0)
1043 ERROR("unable to get latency timer");
1044 return ERROR_JTAG_INIT_FAILED
;
1048 DEBUG("current latency timer: %i", latency_timer
);
1051 ftdic
.bitbang_mode
= 0; /* Reset controller */
1052 ftdi_enable_bitbang(&ftdic
, 0x0b); /* ctx, JTAG I/O mask */
1054 ftdic
.bitbang_mode
= 2; /* MPSSE mode */
1055 ftdi_enable_bitbang(&ftdic
, 0x0b); /* ctx, JTAG I/O mask */
1058 ft2232_buffer_size
= 0;
1059 ft2232_buffer
= malloc(FT2232_BUFFER_SIZE
);
1061 if (layout
->init() != ERROR_OK
)
1062 return ERROR_JTAG_INIT_FAILED
;
1064 ft2232_speed(jtag_speed
);
1066 buf
[0] = 0x85; /* Disconnect TDI/DO to TDO/DI for Loopback */
1067 if (((retval
= ft2232_write(buf
, 1, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 1))
1069 ERROR("couldn't write to FT2232 to disable loopback");
1070 return ERROR_JTAG_INIT_FAILED
;
1073 #if BUILD_FT2232_FTD2XX == 1
1074 if ((status
= FT_Purge(ftdih
, FT_PURGE_RX
| FT_PURGE_TX
)) != FT_OK
)
1076 ERROR("error purging ftd2xx device: %i", status
);
1077 return ERROR_JTAG_INIT_FAILED
;
1079 #elif BUILD_FT2232_LIBFTDI == 1
1080 if (ftdi_usb_purge_buffers(&ftdic
) < 0)
1082 ERROR("ftdi_purge_buffers: %s", ftdic
.error_str
);
1083 return ERROR_JTAG_INIT_FAILED
;
1090 int usbjtag_init(void)
1096 low_direction
= 0x0b;
1098 if (strcmp(ft2232_layout
, "usbjtag") == 0)
1105 else if (strcmp(ft2232_layout
, "signalyzer") == 0)
1114 ERROR("BUG: usbjtag_init called for unknown layout '%s'", ft2232_layout
);
1115 return ERROR_JTAG_INIT_FAILED
;
1118 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1120 low_direction
&= ~nTRSTnOE
; /* nTRST input */
1121 low_output
&= ~nTRST
; /* nTRST = 0 */
1125 low_direction
|= nTRSTnOE
; /* nTRST output */
1126 low_output
|= nTRST
; /* nTRST = 1 */
1129 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
1131 low_direction
|= nSRSTnOE
; /* nSRST output */
1132 low_output
|= nSRST
; /* nSRST = 1 */
1136 low_direction
&= ~nSRSTnOE
; /* nSRST input */
1137 low_output
&= ~nSRST
; /* nSRST = 0 */
1140 /* initialize low byte for jtag */
1141 buf
[0] = 0x80; /* command "set data bits low byte" */
1142 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, xRST high) */
1143 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in */
1144 DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1146 if (((ft2232_write(buf
, 3, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 3))
1148 ERROR("couldn't initialize FT2232 with 'USBJTAG' layout");
1149 return ERROR_JTAG_INIT_FAILED
;
1155 int jtagkey_init(void)
1161 low_direction
= 0x1b;
1163 /* initialize low byte for jtag */
1164 buf
[0] = 0x80; /* command "set data bits low byte" */
1165 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
1166 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
1167 DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1169 if (((ft2232_write(buf
, 3, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 3))
1171 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1172 return ERROR_JTAG_INIT_FAILED
;
1175 if (strcmp(layout
->name
, "jtagkey") == 0)
1182 else if (strcmp(layout
->name
, "jtagkey_prototype_v1") == 0)
1191 ERROR("BUG: jtagkey_init called for non jtagkey layout");
1196 high_direction
= 0x0f;
1198 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1200 high_output
|= nTRSTnOE
;
1201 high_output
&= ~nTRST
;
1205 high_output
&= ~nTRSTnOE
;
1206 high_output
|= nTRST
;
1209 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
1211 high_output
&= ~nSRSTnOE
;
1212 high_output
|= nSRST
;
1216 high_output
|= nSRSTnOE
;
1217 high_output
&= ~nSRST
;
1220 /* initialize high port */
1221 buf
[0] = 0x82; /* command "set data bits high byte" */
1222 buf
[1] = high_output
; /* value */
1223 buf
[2] = high_direction
; /* all outputs (xRST and xRSTnOE) */
1224 DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1226 if (((ft2232_write(buf
, 3, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 3))
1228 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1229 return ERROR_JTAG_INIT_FAILED
;
1235 int olimex_jtag_init(void)
1241 low_direction
= 0x1b;
1243 /* initialize low byte for jtag */
1244 buf
[0] = 0x80; /* command "set data bits low byte" */
1245 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
1246 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
1247 DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1249 if (((ft2232_write(buf
, 3, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 3))
1251 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1252 return ERROR_JTAG_INIT_FAILED
;
1258 nSRSTnOE
= 0x00; /* no output enable for nSRST */
1261 high_direction
= 0x0f;
1263 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1265 high_output
|= nTRSTnOE
;
1266 high_output
&= ~nTRST
;
1270 high_output
&= ~nTRSTnOE
;
1271 high_output
|= nTRST
;
1274 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
1276 ERROR("can't set nSRST to push-pull on the Olimex ARM-USB-OCD");
1280 high_output
&= ~nSRST
;
1283 /* turn red LED on */
1284 high_output
|= 0x08;
1286 /* initialize high port */
1287 buf
[0] = 0x82; /* command "set data bits high byte" */
1288 buf
[1] = high_output
; /* value */
1289 buf
[2] = high_direction
; /* all outputs (xRST and xRSTnOE) */
1290 DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1292 if (((ft2232_write(buf
, 3, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 3))
1294 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1295 return ERROR_JTAG_INIT_FAILED
;
1301 void olimex_jtag_blink(void)
1303 /* Olimex ARM-USB-OCD has a LED connected to ACBUS3
1304 * ACBUS3 is bit 3 of the GPIOH port
1306 if (high_output
& 0x08)
1308 /* set port pin high */
1309 high_output
&= 0x07;
1313 /* set port pin low */
1314 high_output
|= 0x08;
1318 BUFFER_ADD
= high_output
;
1319 BUFFER_ADD
= high_direction
;
1322 int ft2232_quit(void)
1324 #if BUILD_FT2232_FTD2XX == 1
1327 status
= FT_Close(ftdih
);
1328 #elif BUILD_FT2232_LIBFTDI == 1
1329 ftdi_disable_bitbang(&ftdic
);
1331 ftdi_usb_close(&ftdic
);
1333 ftdi_deinit(&ftdic
);
1336 free(ft2232_buffer
);
1341 int ft2232_handle_device_desc_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1345 ft2232_device_desc
= strdup(args
[0]);
1349 ERROR("expected exactly one argument to ft2232_device_desc <description>");
1355 int ft2232_handle_layout_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1360 ft2232_layout
= malloc(strlen(args
[0]) + 1);
1361 strcpy(ft2232_layout
, args
[0]);
1366 int ft2232_handle_vid_pid_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1370 ft2232_vid
= strtol(args
[0], NULL
, 0);
1371 ft2232_pid
= strtol(args
[1], NULL
, 0);
1375 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)