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_SetTimeouts(ftdih
, 5000, 5000)) != FT_OK
)
1015 ERROR("unable to set timeouts: %i", status
);
1016 return ERROR_JTAG_INIT_FAILED
;
1019 if ((status
= FT_SetBitMode(ftdih
, 0x0b, 2)) != FT_OK
)
1021 ERROR("unable to enable bit i/o mode: %i", status
);
1022 return ERROR_JTAG_INIT_FAILED
;
1024 #elif BUILD_FT2232_LIBFTDI == 1
1025 if (ftdi_init(&ftdic
) < 0)
1026 return ERROR_JTAG_INIT_FAILED
;
1028 /* context, vendor id, product id */
1029 if (ftdi_usb_open(&ftdic
, ft2232_vid
, ft2232_pid
) < 0)
1031 ERROR("unable to open ftdi device: %s", ftdic
.error_str
);
1032 return ERROR_JTAG_INIT_FAILED
;
1035 if (ftdi_usb_reset(&ftdic
) < 0)
1037 ERROR("unable to reset ftdi device");
1038 return ERROR_JTAG_INIT_FAILED
;
1041 if (ftdi_set_latency_timer(&ftdic
, 2) < 0)
1043 ERROR("unable to set latency timer");
1044 return ERROR_JTAG_INIT_FAILED
;
1047 if (ftdi_get_latency_timer(&ftdic
, &latency_timer
) < 0)
1049 ERROR("unable to get latency timer");
1050 return ERROR_JTAG_INIT_FAILED
;
1054 DEBUG("current latency timer: %i", latency_timer
);
1057 ftdic
.bitbang_mode
= 0; /* Reset controller */
1058 ftdi_enable_bitbang(&ftdic
, 0x0b); /* ctx, JTAG I/O mask */
1060 ftdic
.bitbang_mode
= 2; /* MPSSE mode */
1061 ftdi_enable_bitbang(&ftdic
, 0x0b); /* ctx, JTAG I/O mask */
1064 ft2232_buffer_size
= 0;
1065 ft2232_buffer
= malloc(FT2232_BUFFER_SIZE
);
1067 if (layout
->init() != ERROR_OK
)
1068 return ERROR_JTAG_INIT_FAILED
;
1070 ft2232_speed(jtag_speed
);
1072 buf
[0] = 0x85; /* Disconnect TDI/DO to TDO/DI for Loopback */
1073 if (((retval
= ft2232_write(buf
, 1, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 1))
1075 ERROR("couldn't write to FT2232 to disable loopback");
1076 return ERROR_JTAG_INIT_FAILED
;
1079 #if BUILD_FT2232_FTD2XX == 1
1080 if ((status
= FT_Purge(ftdih
, FT_PURGE_RX
| FT_PURGE_TX
)) != FT_OK
)
1082 ERROR("error purging ftd2xx device: %i", status
);
1083 return ERROR_JTAG_INIT_FAILED
;
1085 #elif BUILD_FT2232_LIBFTDI == 1
1086 if (ftdi_usb_purge_buffers(&ftdic
) < 0)
1088 ERROR("ftdi_purge_buffers: %s", ftdic
.error_str
);
1089 return ERROR_JTAG_INIT_FAILED
;
1096 int usbjtag_init(void)
1102 low_direction
= 0x0b;
1104 if (strcmp(ft2232_layout
, "usbjtag") == 0)
1111 else if (strcmp(ft2232_layout
, "signalyzer") == 0)
1120 ERROR("BUG: usbjtag_init called for unknown layout '%s'", ft2232_layout
);
1121 return ERROR_JTAG_INIT_FAILED
;
1124 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1126 low_direction
&= ~nTRSTnOE
; /* nTRST input */
1127 low_output
&= ~nTRST
; /* nTRST = 0 */
1131 low_direction
|= nTRSTnOE
; /* nTRST output */
1132 low_output
|= nTRST
; /* nTRST = 1 */
1135 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
1137 low_direction
|= nSRSTnOE
; /* nSRST output */
1138 low_output
|= nSRST
; /* nSRST = 1 */
1142 low_direction
&= ~nSRSTnOE
; /* nSRST input */
1143 low_output
&= ~nSRST
; /* nSRST = 0 */
1146 /* initialize low byte for jtag */
1147 buf
[0] = 0x80; /* command "set data bits low byte" */
1148 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, xRST high) */
1149 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in */
1150 DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1152 if (((ft2232_write(buf
, 3, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 3))
1154 ERROR("couldn't initialize FT2232 with 'USBJTAG' layout");
1155 return ERROR_JTAG_INIT_FAILED
;
1161 int jtagkey_init(void)
1167 low_direction
= 0x1b;
1169 /* initialize low byte for jtag */
1170 buf
[0] = 0x80; /* command "set data bits low byte" */
1171 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
1172 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
1173 DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1175 if (((ft2232_write(buf
, 3, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 3))
1177 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1178 return ERROR_JTAG_INIT_FAILED
;
1181 if (strcmp(layout
->name
, "jtagkey") == 0)
1188 else if (strcmp(layout
->name
, "jtagkey_prototype_v1") == 0)
1197 ERROR("BUG: jtagkey_init called for non jtagkey layout");
1202 high_direction
= 0x0f;
1204 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1206 high_output
|= nTRSTnOE
;
1207 high_output
&= ~nTRST
;
1211 high_output
&= ~nTRSTnOE
;
1212 high_output
|= nTRST
;
1215 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
1217 high_output
&= ~nSRSTnOE
;
1218 high_output
|= nSRST
;
1222 high_output
|= nSRSTnOE
;
1223 high_output
&= ~nSRST
;
1226 /* initialize high port */
1227 buf
[0] = 0x82; /* command "set data bits high byte" */
1228 buf
[1] = high_output
; /* value */
1229 buf
[2] = high_direction
; /* all outputs (xRST and xRSTnOE) */
1230 DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1232 if (((ft2232_write(buf
, 3, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 3))
1234 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1235 return ERROR_JTAG_INIT_FAILED
;
1241 int olimex_jtag_init(void)
1247 low_direction
= 0x1b;
1249 /* initialize low byte for jtag */
1250 buf
[0] = 0x80; /* command "set data bits low byte" */
1251 buf
[1] = low_output
; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
1252 buf
[2] = low_direction
; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
1253 DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1255 if (((ft2232_write(buf
, 3, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 3))
1257 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1258 return ERROR_JTAG_INIT_FAILED
;
1264 nSRSTnOE
= 0x00; /* no output enable for nSRST */
1267 high_direction
= 0x0f;
1269 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
1271 high_output
|= nTRSTnOE
;
1272 high_output
&= ~nTRST
;
1276 high_output
&= ~nTRSTnOE
;
1277 high_output
|= nTRST
;
1280 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
1282 ERROR("can't set nSRST to push-pull on the Olimex ARM-USB-OCD");
1286 high_output
&= ~nSRST
;
1289 /* turn red LED on */
1290 high_output
|= 0x08;
1292 /* initialize high port */
1293 buf
[0] = 0x82; /* command "set data bits high byte" */
1294 buf
[1] = high_output
; /* value */
1295 buf
[2] = high_direction
; /* all outputs (xRST and xRSTnOE) */
1296 DEBUG("%2.2x %2.2x %2.2x", buf
[0], buf
[1], buf
[2]);
1298 if (((ft2232_write(buf
, 3, &bytes_written
)) != ERROR_OK
) || (bytes_written
!= 3))
1300 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1301 return ERROR_JTAG_INIT_FAILED
;
1307 void olimex_jtag_blink(void)
1309 /* Olimex ARM-USB-OCD has a LED connected to ACBUS3
1310 * ACBUS3 is bit 3 of the GPIOH port
1312 if (high_output
& 0x08)
1314 /* set port pin high */
1315 high_output
&= 0x07;
1319 /* set port pin low */
1320 high_output
|= 0x08;
1324 BUFFER_ADD
= high_output
;
1325 BUFFER_ADD
= high_direction
;
1328 int ft2232_quit(void)
1330 #if BUILD_FT2232_FTD2XX == 1
1333 status
= FT_Close(ftdih
);
1334 #elif BUILD_FT2232_LIBFTDI == 1
1335 ftdi_disable_bitbang(&ftdic
);
1337 ftdi_usb_close(&ftdic
);
1339 ftdi_deinit(&ftdic
);
1342 free(ft2232_buffer
);
1347 int ft2232_handle_device_desc_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1351 ft2232_device_desc
= strdup(args
[0]);
1355 ERROR("expected exactly one argument to ft2232_device_desc <description>");
1361 int ft2232_handle_layout_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1366 ft2232_layout
= malloc(strlen(args
[0]) + 1);
1367 strcpy(ft2232_layout
, args
[0]);
1372 int ft2232_handle_vid_pid_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1376 ft2232_vid
= strtol(args
[0], NULL
, 0);
1377 ft2232_pid
= strtol(args
[1], NULL
, 0);
1381 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)