- allow FT2232 devices to be opened by serial number instead of device description...
[openocd.git] / src / jtag / ft2232.c
1 /***************************************************************************
2 * Copyright (C) 2004, 2006 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #if IS_CYGWIN == 1
25 #include "windows.h"
26 #undef ERROR
27 #endif
28
29 #include "replacements.h"
30
31 /* project specific includes */
32 #include "log.h"
33 #include "types.h"
34 #include "jtag.h"
35 #include "configuration.h"
36 #include "time_support.h"
37
38 /* system includes */
39 #include <string.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42
43 /* FT2232 access library includes */
44 #if BUILD_FT2232_FTD2XX == 1
45 #include <ftd2xx.h>
46 #elif BUILD_FT2232_LIBFTDI == 1
47 #include <ftdi.h>
48 #endif
49
50 #include <sys/time.h>
51 #include <time.h>
52
53 /* enable this to debug io latency
54 */
55 #if 0
56 #define _DEBUG_USB_IO_
57 #endif
58
59 /* enable this to debug communication
60 */
61 #if 0
62 #define _DEBUG_USB_COMMS_
63 #endif
64
65 int ft2232_execute_queue(void);
66
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);
71
72 int ft2232_handle_device_desc_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
73 int ft2232_handle_serial_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
74 int ft2232_handle_layout_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
75 int ft2232_handle_vid_pid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
76
77 char *ft2232_device_desc = NULL;
78 char *ft2232_serial = NULL;
79 char *ft2232_layout = NULL;
80 u16 ft2232_vid = 0x0403;
81 u16 ft2232_pid = 0x6010;
82
83 typedef struct ft2232_layout_s
84 {
85 char* name;
86 int(*init)(void);
87 void(*reset)(int trst, int srst);
88 void(*blink)(void);
89 } ft2232_layout_t;
90
91 /* init procedures for supported layouts */
92 int usbjtag_init(void);
93 int jtagkey_init(void);
94 int olimex_jtag_init(void);
95 int m5960_init(void);
96
97 /* reset procedures for supported layouts */
98 void usbjtag_reset(int trst, int srst);
99 void jtagkey_reset(int trst, int srst);
100 void olimex_jtag_reset(int trst, int srst);
101 void m5960_reset(int trst, int srst);
102
103 /* blink procedures for layouts that support a blinking led */
104 void olimex_jtag_blink(void);
105
106 ft2232_layout_t ft2232_layouts[] =
107 {
108 {"usbjtag", usbjtag_init, usbjtag_reset, NULL},
109 {"jtagkey", jtagkey_init, jtagkey_reset, NULL},
110 {"jtagkey_prototype_v1", jtagkey_init, jtagkey_reset, NULL},
111 {"signalyzer", usbjtag_init, usbjtag_reset, NULL},
112 {"olimex-jtag", olimex_jtag_init, olimex_jtag_reset, olimex_jtag_blink},
113 {"m5960", m5960_init, m5960_reset, NULL},
114 {NULL, NULL, NULL},
115 };
116
117 static u8 nTRST, nTRSTnOE, nSRST, nSRSTnOE;
118
119 static ft2232_layout_t *layout;
120 static u8 low_output = 0x0;
121 static u8 low_direction = 0x0;
122 static u8 high_output = 0x0;
123 static u8 high_direction = 0x0;
124
125 #if BUILD_FT2232_FTD2XX == 1
126 static FT_HANDLE ftdih = NULL;
127 #elif BUILD_FT2232_LIBFTDI == 1
128 static struct ftdi_context ftdic;
129 #endif
130
131 static u8 *ft2232_buffer = NULL;
132 static int ft2232_buffer_size = 0;
133 static int ft2232_read_pointer = 0;
134 static int ft2232_expect_read = 0;
135 #define FT2232_BUFFER_SIZE 131072
136 #define BUFFER_ADD ft2232_buffer[ft2232_buffer_size++]
137 #define BUFFER_READ ft2232_buffer[ft2232_read_pointer++]
138
139 jtag_interface_t ft2232_interface =
140 {
141
142 .name = "ft2232",
143
144 .execute_queue = ft2232_execute_queue,
145
146 .support_pathmove = 1,
147
148 .speed = ft2232_speed,
149 .register_commands = ft2232_register_commands,
150 .init = ft2232_init,
151 .quit = ft2232_quit,
152 };
153
154 int ft2232_write(u8 *buf, int size, u32* bytes_written)
155 {
156 #if BUILD_FT2232_FTD2XX == 1
157 FT_STATUS status;
158 DWORD dw_bytes_written;
159 if ((status = FT_Write(ftdih, buf, size, &dw_bytes_written)) != FT_OK)
160 {
161 *bytes_written = dw_bytes_written;
162 ERROR("FT_Write returned: %i", status);
163 return ERROR_JTAG_DEVICE_ERROR;
164 }
165 else
166 {
167 *bytes_written = dw_bytes_written;
168 return ERROR_OK;
169 }
170 #elif BUILD_FT2232_LIBFTDI == 1
171 int retval;
172 if ((retval = ftdi_write_data(&ftdic, buf, size)) < 0)
173 {
174 *bytes_written = 0;
175 ERROR("ftdi_write_data: %s", ftdi_get_error_string(&ftdic));
176 return ERROR_JTAG_DEVICE_ERROR;
177 }
178 else
179 {
180 *bytes_written = retval;
181 return ERROR_OK;
182 }
183 #endif
184 }
185
186 int ft2232_read(u8* buf, int size, u32* bytes_read)
187 {
188 #if BUILD_FT2232_FTD2XX == 1
189 DWORD dw_bytes_read;
190 FT_STATUS status;
191 if ((status = FT_Read(ftdih, buf, size, &dw_bytes_read)) != FT_OK)
192 {
193 *bytes_read = dw_bytes_read;
194 ERROR("FT_Read returned: %i", status);
195 return ERROR_JTAG_DEVICE_ERROR;
196 }
197 *bytes_read = dw_bytes_read;
198 return ERROR_OK;
199
200 #elif BUILD_FT2232_LIBFTDI == 1
201 int retval;
202 int timeout = 100;
203 *bytes_read = 0;
204
205 while ((*bytes_read < size) && timeout--)
206 {
207 if ((retval = ftdi_read_data(&ftdic, buf + *bytes_read, size - *bytes_read)) < 0)
208 {
209 *bytes_read = 0;
210 ERROR("ftdi_read_data: %s", ftdi_get_error_string(&ftdic));
211 return ERROR_JTAG_DEVICE_ERROR;
212 }
213 *bytes_read += retval;
214 }
215 return ERROR_OK;
216 #endif
217 }
218
219 int ft2232_speed(int speed)
220 {
221 u8 buf[3];
222 int retval;
223 u32 bytes_written;
224
225 buf[0] = 0x86; /* command "set divisor" */
226 buf[1] = speed & 0xff; /* valueL (0=6MHz, 1=3MHz, 2=1.5MHz, ...*/
227 buf[2] = (speed >> 8) & 0xff; /* valueH */
228
229 DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
230 if (((retval = ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
231 {
232 ERROR("couldn't set FT2232 TCK speed");
233 return retval;
234 }
235
236 return ERROR_OK;
237 }
238
239 int ft2232_register_commands(struct command_context_s *cmd_ctx)
240 {
241 register_command(cmd_ctx, NULL, "ft2232_device_desc", ft2232_handle_device_desc_command,
242 COMMAND_CONFIG, NULL);
243 register_command(cmd_ctx, NULL, "ft2232_serial", ft2232_handle_serial_command,
244 COMMAND_CONFIG, NULL);
245 register_command(cmd_ctx, NULL, "ft2232_layout", ft2232_handle_layout_command,
246 COMMAND_CONFIG, NULL);
247 register_command(cmd_ctx, NULL, "ft2232_vid_pid", ft2232_handle_vid_pid_command,
248 COMMAND_CONFIG, NULL);
249 return ERROR_OK;
250 }
251
252 void ft2232_end_state(state)
253 {
254 if (tap_move_map[state] != -1)
255 end_state = state;
256 else
257 {
258 ERROR("BUG: %i is not a valid end state", state);
259 exit(-1);
260 }
261 }
262
263 void ft2232_read_scan(enum scan_type type, u8* buffer, int scan_size)
264 {
265 int num_bytes = ((scan_size + 7) / 8);
266 int bits_left = scan_size;
267 int cur_byte = 0;
268
269 while(num_bytes-- > 1)
270 {
271 buffer[cur_byte] = BUFFER_READ;
272 cur_byte++;
273 bits_left -= 8;
274 }
275
276 buffer[cur_byte] = 0x0;
277
278 if (bits_left > 1)
279 {
280 buffer[cur_byte] = BUFFER_READ >> 1;
281 }
282
283 buffer[cur_byte] = (buffer[cur_byte] | ((BUFFER_READ & 0x02) << 6)) >> (8 - bits_left);
284
285 }
286
287 void ft2232_debug_dump_buffer(void)
288 {
289 int i;
290 char line[256];
291 char *line_p = line;
292
293 for (i = 0; i < ft2232_buffer_size; i++)
294 {
295 line_p += snprintf(line_p, 256 - (line_p - line), "%2.2x ", ft2232_buffer[i]);
296 if (i % 16 == 15)
297 {
298 DEBUG("%s", line);
299 line_p = line;
300 }
301 }
302
303 if (line_p != line)
304 DEBUG("%s", line);
305 }
306
307 int ft2232_send_and_recv(jtag_command_t *first, jtag_command_t *last)
308 {
309 jtag_command_t *cmd;
310 u8 *buffer;
311 int scan_size;
312 enum scan_type type;
313 int retval;
314 u32 bytes_written;
315 u32 bytes_read;
316
317 #ifdef _DEBUG_USB_IO_
318 struct timeval start, inter, inter2, end;
319 struct timeval d_inter, d_inter2, d_end;
320 #endif
321
322 #ifdef _DEBUG_USB_COMMS_
323 DEBUG("write buffer (size %i):", ft2232_buffer_size);
324 ft2232_debug_dump_buffer();
325 #endif
326
327 #ifdef _DEBUG_USB_IO_
328 gettimeofday(&start, NULL);
329 #endif
330
331 if ((retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written)) != ERROR_OK)
332 {
333 ERROR("couldn't write MPSSE commands to FT2232");
334 exit(-1);
335 }
336
337 #ifdef _DEBUG_USB_IO_
338 gettimeofday(&inter, NULL);
339 #endif
340
341 if (ft2232_expect_read)
342 {
343 int timeout = 100;
344 ft2232_buffer_size = 0;
345
346 #ifdef _DEBUG_USB_IO_
347 gettimeofday(&inter2, NULL);
348 #endif
349
350 if ((retval = ft2232_read(ft2232_buffer, ft2232_expect_read, &bytes_read)) != ERROR_OK)
351 {
352 ERROR("couldn't read from FT2232");
353 exit(-1);
354 }
355
356 #ifdef _DEBUG_USB_IO_
357 gettimeofday(&end, NULL);
358
359 timeval_subtract(&d_inter, &inter, &start);
360 timeval_subtract(&d_inter2, &inter2, &start);
361 timeval_subtract(&d_end, &end, &start);
362
363 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);
364 #endif
365
366
367 ft2232_buffer_size = bytes_read;
368
369 if (ft2232_expect_read != ft2232_buffer_size)
370 {
371 ERROR("ft2232_expect_read (%i) != ft2232_buffer_size (%i) (%i retries)", ft2232_expect_read, ft2232_buffer_size, 100 - timeout);
372 ft2232_debug_dump_buffer();
373
374 exit(-1);
375 }
376
377 #ifdef _DEBUG_USB_COMMS_
378 DEBUG("read buffer (%i retries): %i bytes", 100 - timeout, ft2232_buffer_size);
379 ft2232_debug_dump_buffer();
380 #endif
381 }
382
383 ft2232_expect_read = 0;
384 ft2232_read_pointer = 0;
385
386 cmd = first;
387 while (cmd != last)
388 {
389 switch (cmd->type)
390 {
391 case JTAG_SCAN:
392 type = jtag_scan_type(cmd->cmd.scan);
393 if (type != SCAN_OUT)
394 {
395 scan_size = jtag_scan_size(cmd->cmd.scan);
396 buffer = calloc(CEIL(scan_size, 8), 1);
397 ft2232_read_scan(type, buffer, scan_size);
398 jtag_read_buffer(buffer, cmd->cmd.scan);
399 free(buffer);
400 }
401 break;
402 default:
403 break;
404 }
405 cmd = cmd->next;
406 }
407
408 ft2232_buffer_size = 0;
409
410 return ERROR_OK;
411 }
412
413 void ft2232_add_pathmove(pathmove_command_t *cmd)
414 {
415 int num_states = cmd->num_states;
416 u8 tms_byte;
417 int state_count;
418
419 state_count = 0;
420 while (num_states)
421 {
422 tms_byte = 0x0;
423 int bit_count = 0;
424
425 /* command "Clock Data to TMS/CS Pin (no Read)" */
426 BUFFER_ADD = 0x4b;
427 /* number of states remaining */
428 BUFFER_ADD = (num_states % 7) - 1;
429
430 while (num_states % 7)
431 {
432 if (tap_transitions[cur_state].low == cmd->path[state_count])
433 buf_set_u32(&tms_byte, bit_count++, 1, 0x0);
434 else if (tap_transitions[cur_state].high == cmd->path[state_count])
435 buf_set_u32(&tms_byte, bit_count++, 1, 0x1);
436 else
437 {
438 ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]);
439 exit(-1);
440 }
441
442 cur_state = cmd->path[state_count];
443 state_count++;
444 num_states--;
445 }
446
447 BUFFER_ADD = tms_byte;
448 }
449
450 end_state = cur_state;
451 }
452
453 void ft2232_add_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
454 {
455 int num_bytes = (scan_size + 7) / 8;
456 int bits_left = scan_size;
457 int cur_byte = 0;
458 int last_bit;
459
460 if ((!ir_scan && (cur_state != TAP_SD)) || (ir_scan && (cur_state != TAP_SI)))
461 {
462 /* command "Clock Data to TMS/CS Pin (no Read)" */
463 BUFFER_ADD = 0x4b;
464 /* scan 7 bit */
465 BUFFER_ADD = 0x6;
466 /* TMS data bits */
467 if (ir_scan)
468 {
469 BUFFER_ADD = TAP_MOVE(cur_state, TAP_SI);
470 cur_state = TAP_SI;
471 }
472 else
473 {
474 BUFFER_ADD = TAP_MOVE(cur_state, TAP_SD);
475 cur_state = TAP_SD;
476 }
477 //DEBUG("added TMS scan (no read)");
478 }
479
480 /* add command for complete bytes */
481 if (num_bytes > 1)
482 {
483 if (type == SCAN_IO)
484 {
485 /* Clock Data Bytes In and Out LSB First */
486 BUFFER_ADD = 0x39;
487 //DEBUG("added TDI bytes (io %i)", num_bytes);
488 }
489 else if (type == SCAN_OUT)
490 {
491 /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */
492 BUFFER_ADD = 0x19;
493 //DEBUG("added TDI bytes (o)");
494 }
495 else if (type == SCAN_IN)
496 {
497 /* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */
498 BUFFER_ADD = 0x28;
499 //DEBUG("added TDI bytes (i %i)", num_bytes);
500 }
501 BUFFER_ADD = (num_bytes-2) & 0xff;
502 BUFFER_ADD = ((num_bytes-2) >> 8) & 0xff;
503 }
504 if (type != SCAN_IN)
505 {
506 /* add complete bytes */
507 while(num_bytes-- > 1)
508 {
509 BUFFER_ADD = buffer[cur_byte];
510 cur_byte++;
511 bits_left -= 8;
512 }
513 }
514 if (type == SCAN_IN)
515 {
516 bits_left -= 8 * (num_bytes - 1);
517 }
518
519 /* the most signifcant bit is scanned during TAP movement */
520 if (type != SCAN_IN)
521 last_bit = (buffer[cur_byte] >> (bits_left - 1)) & 0x1;
522 else
523 last_bit = 0;
524
525 /* process remaining bits but the last one */
526 if (bits_left > 1)
527 {
528 if (type == SCAN_IO)
529 {
530 /* Clock Data Bits In and Out LSB First */
531 BUFFER_ADD = 0x3b;
532 //DEBUG("added TDI bits (io) %i", bits_left - 1);
533 }
534 else if (type == SCAN_OUT)
535 {
536 /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
537 BUFFER_ADD = 0x1b;
538 //DEBUG("added TDI bits (o)");
539 }
540 else if (type == SCAN_IN)
541 {
542 /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
543 BUFFER_ADD = 0x2a;
544 //DEBUG("added TDI bits (i %i)", bits_left - 1);
545 }
546 BUFFER_ADD = bits_left - 2;
547 if (type != SCAN_IN)
548 BUFFER_ADD = buffer[cur_byte];
549 }
550
551 /* move from Shift-IR/DR to end state */
552 if (type != SCAN_OUT)
553 {
554 /* Clock Data to TMS/CS Pin with Read */
555 BUFFER_ADD = 0x6b;
556 //DEBUG("added TMS scan (read)");
557 }
558 else
559 {
560 /* Clock Data to TMS/CS Pin (no Read) */
561 BUFFER_ADD = 0x4b;
562 //DEBUG("added TMS scan (no read)");
563 }
564 BUFFER_ADD = 0x6;
565 BUFFER_ADD = TAP_MOVE(cur_state, end_state) | (last_bit << 7);
566 cur_state = end_state;
567
568 }
569
570 int ft2232_predict_scan_out(int scan_size, enum scan_type type)
571 {
572 int predicted_size = 3;
573
574 if (cur_state != TAP_SD)
575 predicted_size += 3;
576
577 if (type == SCAN_IN) /* only from device to host */
578 {
579 /* complete bytes */
580 predicted_size += (CEIL(scan_size, 8) > 1) ? 3 : 0;
581 /* remaining bits - 1 (up to 7) */
582 predicted_size += ((scan_size - 1) % 8) ? 2 : 0;
583 }
584 else /* host to device, or bidirectional */
585 {
586 /* complete bytes */
587 predicted_size += (CEIL(scan_size, 8) > 1) ? (CEIL(scan_size, 8) + 3 - 1) : 0;
588 /* remaining bits -1 (up to 7) */
589 predicted_size += ((scan_size - 1) % 8) ? 3 : 0;
590 }
591
592 return predicted_size;
593 }
594
595 int ft2232_predict_scan_in(int scan_size, enum scan_type type)
596 {
597 int predicted_size = 0;
598
599 if (type != SCAN_OUT)
600 {
601 /* complete bytes */
602 predicted_size += (CEIL(scan_size, 8) > 1) ? (CEIL(scan_size, 8) - 1) : 0;
603 /* remaining bits - 1 */
604 predicted_size += ((scan_size - 1) % 8) ? 1 : 0;
605 /* last bit (from TMS scan) */
606 predicted_size += 1;
607 }
608
609 //DEBUG("scan_size: %i, predicted_size: %i", scan_size, predicted_size);
610
611 return predicted_size;
612 }
613
614 void usbjtag_reset(int trst, int srst)
615 {
616 if (trst == 1)
617 {
618 cur_state = TAP_TLR;
619 if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
620 low_direction |= nTRSTnOE; /* switch to output pin (output is low) */
621 else
622 low_output &= ~nTRST; /* switch output low */
623 }
624 else if (trst == 0)
625 {
626 if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
627 low_direction &= ~nTRSTnOE; /* switch to input pin (high-Z + internal and external pullup) */
628 else
629 low_output |= nTRST; /* switch output high */
630 }
631
632 if (srst == 1)
633 {
634 if (jtag_reset_config & RESET_SRST_PUSH_PULL)
635 low_output &= ~nSRST; /* switch output low */
636 else
637 low_direction |= nSRSTnOE; /* switch to output pin (output is low) */
638 }
639 else if (srst == 0)
640 {
641 if (jtag_reset_config & RESET_SRST_PUSH_PULL)
642 low_output |= nSRST; /* switch output high */
643 else
644 low_direction &= ~nSRSTnOE; /* switch to input pin (high-Z) */
645 }
646
647 /* command "set data bits low byte" */
648 BUFFER_ADD = 0x80;
649 BUFFER_ADD = low_output;
650 BUFFER_ADD = low_direction;
651
652 }
653
654 void jtagkey_reset(int trst, int srst)
655 {
656 if (trst == 1)
657 {
658 cur_state = TAP_TLR;
659 if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
660 high_output &= ~nTRSTnOE;
661 else
662 high_output &= ~nTRST;
663 }
664 else if (trst == 0)
665 {
666 if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
667 high_output |= nTRSTnOE;
668 else
669 high_output |= nTRST;
670 }
671
672 if (srst == 1)
673 {
674 if (jtag_reset_config & RESET_SRST_PUSH_PULL)
675 high_output &= ~nSRST;
676 else
677 high_output &= ~nSRSTnOE;
678 }
679 else if (srst == 0)
680 {
681 if (jtag_reset_config & RESET_SRST_PUSH_PULL)
682 high_output |= nSRST;
683 else
684 high_output |= nSRSTnOE;
685 }
686
687 /* command "set data bits high byte" */
688 BUFFER_ADD = 0x82;
689 BUFFER_ADD = high_output;
690 BUFFER_ADD = high_direction;
691 DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);
692 }
693
694 void olimex_jtag_reset(int trst, int srst)
695 {
696 if (trst == 1)
697 {
698 cur_state = TAP_TLR;
699 if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
700 high_output &= ~nTRSTnOE;
701 else
702 high_output &= ~nTRST;
703 }
704 else if (trst == 0)
705 {
706 if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
707 high_output |= nTRSTnOE;
708 else
709 high_output |= nTRST;
710 }
711
712 if (srst == 1)
713 {
714 high_output |= nSRST;
715 }
716 else if (srst == 0)
717 {
718 high_output &= ~nSRST;
719 }
720
721 /* command "set data bits high byte" */
722 BUFFER_ADD = 0x82;
723 BUFFER_ADD = high_output;
724 BUFFER_ADD = high_direction;
725 DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);
726 }
727
728 void m5960_reset(int trst, int srst)
729 {
730 if (trst == 1)
731 {
732 cur_state = TAP_TLR;
733 low_output &= ~nTRST;
734 }
735 else if (trst == 0)
736 {
737 low_output |= nTRST;
738 }
739
740 if (srst == 1)
741 {
742 low_output |= nSRST;
743 }
744 else if (srst == 0)
745 {
746 low_output &= ~nSRST;
747 }
748
749 /* command "set data bits low byte" */
750 BUFFER_ADD = 0x80;
751 BUFFER_ADD = low_output;
752 BUFFER_ADD = low_direction;
753 DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);
754 }
755
756 int ft2232_execute_queue()
757 {
758 jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
759 jtag_command_t *first_unsent = cmd; /* next command that has to be sent */
760 u8 *buffer;
761 int scan_size; /* size of IR or DR scan */
762 enum scan_type type;
763 int i;
764 int predicted_size = 0;
765 int require_send = 0;
766
767 ft2232_buffer_size = 0;
768 ft2232_expect_read = 0;
769
770 /* blink, if the current layout has that feature */
771 if (layout->blink)
772 layout->blink();
773
774 while (cmd)
775 {
776 switch(cmd->type)
777 {
778 case JTAG_END_STATE:
779 if (cmd->cmd.end_state->end_state != -1)
780 ft2232_end_state(cmd->cmd.end_state->end_state);
781 break;
782 case JTAG_RESET:
783 /* only send the maximum buffer size that FT2232C can handle */
784 predicted_size = 3;
785 if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
786 {
787 ft2232_send_and_recv(first_unsent, cmd);
788 require_send = 0;
789 first_unsent = cmd;
790 }
791
792 layout->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
793 require_send = 1;
794
795 #ifdef _DEBUG_JTAG_IO_
796 DEBUG("trst: %i, srst: %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
797 #endif
798 break;
799 case JTAG_RUNTEST:
800 /* only send the maximum buffer size that FT2232C can handle */
801 predicted_size = 0;
802 if (cur_state != TAP_RTI)
803 predicted_size += 3;
804 predicted_size += 3 * CEIL(cmd->cmd.runtest->num_cycles, 7);
805 if ((cmd->cmd.runtest->end_state != -1) && (cmd->cmd.runtest->end_state != TAP_RTI))
806 predicted_size += 3;
807 if ((cmd->cmd.runtest->end_state == -1) && (end_state != TAP_RTI))
808 predicted_size += 3;
809 if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
810 {
811 ft2232_send_and_recv(first_unsent, cmd);
812 require_send = 0;
813 first_unsent = cmd;
814 }
815 if (cur_state != TAP_RTI)
816 {
817 /* command "Clock Data to TMS/CS Pin (no Read)" */
818 BUFFER_ADD = 0x4b;
819 /* scan 7 bit */
820 BUFFER_ADD = 0x6;
821 /* TMS data bits */
822 BUFFER_ADD = TAP_MOVE(cur_state, TAP_RTI);
823 cur_state = TAP_RTI;
824 require_send = 1;
825 }
826 i = cmd->cmd.runtest->num_cycles;
827 while (i > 0)
828 {
829 /* command "Clock Data to TMS/CS Pin (no Read)" */
830 BUFFER_ADD = 0x4b;
831 /* scan 7 bit */
832 BUFFER_ADD = (i > 7) ? 6 : (i - 1);
833 /* TMS data bits */
834 BUFFER_ADD = 0x0;
835 cur_state = TAP_RTI;
836 i -= (i > 7) ? 7 : i;
837 //DEBUG("added TMS scan (no read)");
838 }
839 if (cmd->cmd.runtest->end_state != -1)
840 ft2232_end_state(cmd->cmd.runtest->end_state);
841 if (cur_state != end_state)
842 {
843 /* command "Clock Data to TMS/CS Pin (no Read)" */
844 BUFFER_ADD = 0x4b;
845 /* scan 7 bit */
846 BUFFER_ADD = 0x6;
847 /* TMS data bits */
848 BUFFER_ADD = TAP_MOVE(cur_state, end_state);
849 cur_state = end_state;
850 //DEBUG("added TMS scan (no read)");
851 }
852 require_send = 1;
853 #ifdef _DEBUG_JTAG_IO_
854 DEBUG("runtest: %i, end in %i", cmd->cmd.runtest->num_cycles, end_state);
855 #endif
856 break;
857 case JTAG_STATEMOVE:
858 /* only send the maximum buffer size that FT2232C can handle */
859 predicted_size = 3;
860 if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
861 {
862 ft2232_send_and_recv(first_unsent, cmd);
863 require_send = 0;
864 first_unsent = cmd;
865 }
866 if (cmd->cmd.statemove->end_state != -1)
867 ft2232_end_state(cmd->cmd.statemove->end_state);
868 /* command "Clock Data to TMS/CS Pin (no Read)" */
869 BUFFER_ADD = 0x4b;
870 /* scan 7 bit */
871 BUFFER_ADD = 0x6;
872 /* TMS data bits */
873 BUFFER_ADD = TAP_MOVE(cur_state, end_state);
874 //DEBUG("added TMS scan (no read)");
875 cur_state = end_state;
876 require_send = 1;
877 #ifdef _DEBUG_JTAG_IO_
878 DEBUG("statemove: %i", end_state);
879 #endif
880 break;
881 case JTAG_PATHMOVE:
882 /* only send the maximum buffer size that FT2232C can handle */
883 predicted_size = 3 * CEIL(cmd->cmd.pathmove->num_states, 7);
884 if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
885 {
886 ft2232_send_and_recv(first_unsent, cmd);
887 require_send = 0;
888 first_unsent = cmd;
889 }
890 ft2232_add_pathmove(cmd->cmd.pathmove);
891 require_send = 1;
892 #ifdef _DEBUG_JTAG_IO_
893 DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
894 #endif
895 break;
896 case JTAG_SCAN:
897 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
898 type = jtag_scan_type(cmd->cmd.scan);
899 predicted_size = ft2232_predict_scan_out(scan_size, type);
900 if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
901 {
902 DEBUG("ftd2xx buffer size reached, sending queued commands (first_unsent: %x, cmd: %x)", first_unsent, cmd);
903 ft2232_send_and_recv(first_unsent, cmd);
904 require_send = 0;
905 first_unsent = cmd;
906 }
907 ft2232_expect_read += ft2232_predict_scan_in(scan_size, type);
908 //DEBUG("new read size: %i", ft2232_expect_read);
909 if (cmd->cmd.scan->end_state != -1)
910 ft2232_end_state(cmd->cmd.scan->end_state);
911 ft2232_add_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
912 require_send = 1;
913 if (buffer)
914 free(buffer);
915 #ifdef _DEBUG_JTAG_IO_
916 DEBUG("%s scan, %i bit, end in %i", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size, end_state);
917 #endif
918 break;
919 case JTAG_SLEEP:
920 ft2232_send_and_recv(first_unsent, cmd);
921 first_unsent = cmd->next;
922 jtag_sleep(cmd->cmd.sleep->us);
923 #ifdef _DEBUG_JTAG_IO_
924 DEBUG("sleep %i usec", cmd->cmd.sleep->us);
925 #endif
926 break;
927 default:
928 ERROR("BUG: unknown JTAG command type encountered");
929 exit(-1);
930 }
931 cmd = cmd->next;
932 }
933
934 if (require_send > 0)
935 ft2232_send_and_recv(first_unsent, cmd);
936
937 return ERROR_OK;
938 }
939
940 int ft2232_init(void)
941 {
942 u8 latency_timer;
943 u8 buf[1];
944 int retval;
945 u32 bytes_written;
946
947 #if BUILD_FT2232_FTD2XX == 1
948 FT_STATUS status;
949 DWORD openex_flags = 0;
950 char *openex_string = NULL;
951 #endif
952
953 ft2232_layout_t *cur_layout = ft2232_layouts;
954
955 if ((ft2232_layout == NULL) || (ft2232_layout[0] == 0))
956 {
957 ft2232_layout = "usbjtag";
958 WARNING("No ft2232 layout specified, using default 'usbjtag'");
959 }
960
961 while (cur_layout->name)
962 {
963 if (strcmp(cur_layout->name, ft2232_layout) == 0)
964 {
965 layout = cur_layout;
966 break;
967 }
968 cur_layout++;
969 }
970
971 if (!layout)
972 {
973 ERROR("No matching layout found for %s", ft2232_layout);
974 return ERROR_JTAG_INIT_FAILED;
975 }
976
977 #if BUILD_FT2232_FTD2XX == 1
978 DEBUG("'ft2232' interface using FTD2XX with '%s' layout", ft2232_layout);
979 #elif BUILD_FT2232_LIBFTDI == 1
980 DEBUG("'ft2232' interface using libftdi with '%s' layout", ft2232_layout);
981 #endif
982
983 #if BUILD_FT2232_FTD2XX == 1
984 #if IS_WIN32 == 0
985 /* Add non-standard Vid/Pid to the linux driver */
986 if ((status = FT_SetVIDPID(ft2232_vid, ft2232_pid)) != FT_OK)
987 {
988 WARNING("couldn't add %4.4x:%4.4x", ft2232_vid, ft2232_pid);
989 }
990 #endif
991
992 if (ft2232_device_desc && ft2232_serial)
993 {
994 WARNING("can't open by device description and serial number, giving precedence to serial");
995 ft2232_device_desc = NULL;
996 }
997 else if (ft2232_device_desc)
998 {
999 openex_string = ft2232_device_desc;
1000 openex_flags = FT_OPEN_BY_DESCRIPTION;
1001 }
1002 else if (ft2232_serial)
1003 {
1004 openex_string = ft2232_serial;
1005 openex_flags = FT_OPEN_BY_SERIAL_NUMBER;
1006 }
1007 else
1008 {
1009 ERROR("neither device description nor serial number specified");
1010 ERROR("please add \"ft2232_device_desc <string>\" or \"ft2232_serial <string>\" to your .cfg file");
1011
1012 return ERROR_JTAG_INIT_FAILED;
1013 }
1014
1015 if ((status = FT_OpenEx(openex_string, openex_flags, &ftdih)) != FT_OK)
1016 {
1017 DWORD num_devices;
1018
1019 ERROR("unable to open ftdi device: %i", status);
1020 status = FT_ListDevices(&num_devices, NULL, FT_LIST_NUMBER_ONLY);
1021 if (status == FT_OK)
1022 {
1023 char **desc_array = malloc(sizeof(char*) * (num_devices + 1));
1024 int i;
1025
1026 for (i = 0; i < num_devices; i++)
1027 desc_array[i] = malloc(64);
1028 desc_array[num_devices] = NULL;
1029
1030 status = FT_ListDevices(desc_array, &num_devices, FT_LIST_ALL | openex_flags);
1031
1032 if (status == FT_OK)
1033 {
1034 ERROR("ListDevices: %d\n", num_devices);
1035 for (i = 0; i < num_devices; i++)
1036 ERROR("%i: %s", i, desc_array[i]);
1037 }
1038
1039 for (i = 0; i < num_devices; i++)
1040 free(desc_array[i]);
1041 free(desc_array);
1042 }
1043 else
1044 {
1045 printf("ListDevices: NONE\n");
1046 }
1047 return ERROR_JTAG_INIT_FAILED;
1048 }
1049
1050 if ((status = FT_SetLatencyTimer(ftdih, 2)) != FT_OK)
1051 {
1052 ERROR("unable to set latency timer: %i", status);
1053 return ERROR_JTAG_INIT_FAILED;
1054 }
1055
1056 if ((status = FT_GetLatencyTimer(ftdih, &latency_timer)) != FT_OK)
1057 {
1058 ERROR("unable to get latency timer: %i", status);
1059 return ERROR_JTAG_INIT_FAILED;
1060 }
1061 else
1062 {
1063 DEBUG("current latency timer: %i", latency_timer);
1064 }
1065
1066 if ((status = FT_SetTimeouts(ftdih, 5000, 5000)) != FT_OK)
1067 {
1068 ERROR("unable to set timeouts: %i", status);
1069 return ERROR_JTAG_INIT_FAILED;
1070 }
1071
1072 if ((status = FT_SetBitMode(ftdih, 0x0b, 2)) != FT_OK)
1073 {
1074 ERROR("unable to enable bit i/o mode: %i", status);
1075 return ERROR_JTAG_INIT_FAILED;
1076 }
1077 #elif BUILD_FT2232_LIBFTDI == 1
1078 if (ftdi_init(&ftdic) < 0)
1079 return ERROR_JTAG_INIT_FAILED;
1080
1081 /* context, vendor id, product id */
1082 if (ftdi_usb_open(&ftdic, ft2232_vid, ft2232_pid) < 0)
1083 {
1084 ERROR("unable to open ftdi device: %s", ftdic.error_str);
1085 return ERROR_JTAG_INIT_FAILED;
1086 }
1087
1088 if (ftdi_usb_reset(&ftdic) < 0)
1089 {
1090 ERROR("unable to reset ftdi device");
1091 return ERROR_JTAG_INIT_FAILED;
1092 }
1093
1094 if (ftdi_set_latency_timer(&ftdic, 2) < 0)
1095 {
1096 ERROR("unable to set latency timer");
1097 return ERROR_JTAG_INIT_FAILED;
1098 }
1099
1100 if (ftdi_get_latency_timer(&ftdic, &latency_timer) < 0)
1101 {
1102 ERROR("unable to get latency timer");
1103 return ERROR_JTAG_INIT_FAILED;
1104 }
1105 else
1106 {
1107 DEBUG("current latency timer: %i", latency_timer);
1108 }
1109
1110 ftdic.bitbang_mode = 0; /* Reset controller */
1111 ftdi_enable_bitbang(&ftdic, 0x0b); /* ctx, JTAG I/O mask */
1112
1113 ftdic.bitbang_mode = 2; /* MPSSE mode */
1114 ftdi_enable_bitbang(&ftdic, 0x0b); /* ctx, JTAG I/O mask */
1115 #endif
1116
1117 ft2232_buffer_size = 0;
1118 ft2232_buffer = malloc(FT2232_BUFFER_SIZE);
1119
1120 if (layout->init() != ERROR_OK)
1121 return ERROR_JTAG_INIT_FAILED;
1122
1123 ft2232_speed(jtag_speed);
1124
1125 buf[0] = 0x85; /* Disconnect TDI/DO to TDO/DI for Loopback */
1126 if (((retval = ft2232_write(buf, 1, &bytes_written)) != ERROR_OK) || (bytes_written != 1))
1127 {
1128 ERROR("couldn't write to FT2232 to disable loopback");
1129 return ERROR_JTAG_INIT_FAILED;
1130 }
1131
1132 #if BUILD_FT2232_FTD2XX == 1
1133 if ((status = FT_Purge(ftdih, FT_PURGE_RX | FT_PURGE_TX)) != FT_OK)
1134 {
1135 ERROR("error purging ftd2xx device: %i", status);
1136 return ERROR_JTAG_INIT_FAILED;
1137 }
1138 #elif BUILD_FT2232_LIBFTDI == 1
1139 if (ftdi_usb_purge_buffers(&ftdic) < 0)
1140 {
1141 ERROR("ftdi_purge_buffers: %s", ftdic.error_str);
1142 return ERROR_JTAG_INIT_FAILED;
1143 }
1144 #endif
1145
1146 return ERROR_OK;
1147 }
1148
1149 int usbjtag_init(void)
1150 {
1151 u8 buf[3];
1152 u32 bytes_written;
1153
1154 low_output = 0x08;
1155 low_direction = 0x0b;
1156
1157 if (strcmp(ft2232_layout, "usbjtag") == 0)
1158 {
1159 nTRST = 0x10;
1160 nTRSTnOE = 0x10;
1161 nSRST = 0x40;
1162 nSRSTnOE = 0x40;
1163 }
1164 else if (strcmp(ft2232_layout, "signalyzer") == 0)
1165 {
1166 nTRST = 0x10;
1167 nTRSTnOE = 0x10;
1168 nSRST = 0x20;
1169 nSRSTnOE = 0x20;
1170 }
1171 else
1172 {
1173 ERROR("BUG: usbjtag_init called for unknown layout '%s'", ft2232_layout);
1174 return ERROR_JTAG_INIT_FAILED;
1175 }
1176
1177 if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
1178 {
1179 low_direction &= ~nTRSTnOE; /* nTRST input */
1180 low_output &= ~nTRST; /* nTRST = 0 */
1181 }
1182 else
1183 {
1184 low_direction |= nTRSTnOE; /* nTRST output */
1185 low_output |= nTRST; /* nTRST = 1 */
1186 }
1187
1188 if (jtag_reset_config & RESET_SRST_PUSH_PULL)
1189 {
1190 low_direction |= nSRSTnOE; /* nSRST output */
1191 low_output |= nSRST; /* nSRST = 1 */
1192 }
1193 else
1194 {
1195 low_direction &= ~nSRSTnOE; /* nSRST input */
1196 low_output &= ~nSRST; /* nSRST = 0 */
1197 }
1198
1199 /* initialize low byte for jtag */
1200 buf[0] = 0x80; /* command "set data bits low byte" */
1201 buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, xRST high) */
1202 buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in */
1203 DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
1204
1205 if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
1206 {
1207 ERROR("couldn't initialize FT2232 with 'USBJTAG' layout");
1208 return ERROR_JTAG_INIT_FAILED;
1209 }
1210
1211 return ERROR_OK;
1212 }
1213
1214 int jtagkey_init(void)
1215 {
1216 u8 buf[3];
1217 u32 bytes_written;
1218
1219 low_output = 0x08;
1220 low_direction = 0x1b;
1221
1222 /* initialize low byte for jtag */
1223 buf[0] = 0x80; /* command "set data bits low byte" */
1224 buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
1225 buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
1226 DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
1227
1228 if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
1229 {
1230 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1231 return ERROR_JTAG_INIT_FAILED;
1232 }
1233
1234 if (strcmp(layout->name, "jtagkey") == 0)
1235 {
1236 nTRST = 0x01;
1237 nTRSTnOE = 0x4;
1238 nSRST = 0x02;
1239 nSRSTnOE = 0x08;
1240 }
1241 else if (strcmp(layout->name, "jtagkey_prototype_v1") == 0)
1242 {
1243 nTRST = 0x02;
1244 nTRSTnOE = 0x1;
1245 nSRST = 0x08;
1246 nSRSTnOE = 0x04;
1247 }
1248 else
1249 {
1250 ERROR("BUG: jtagkey_init called for non jtagkey layout");
1251 exit(-1);
1252 }
1253
1254 high_output = 0x0;
1255 high_direction = 0x0f;
1256
1257 if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
1258 {
1259 high_output |= nTRSTnOE;
1260 high_output &= ~nTRST;
1261 }
1262 else
1263 {
1264 high_output &= ~nTRSTnOE;
1265 high_output |= nTRST;
1266 }
1267
1268 if (jtag_reset_config & RESET_SRST_PUSH_PULL)
1269 {
1270 high_output &= ~nSRSTnOE;
1271 high_output |= nSRST;
1272 }
1273 else
1274 {
1275 high_output |= nSRSTnOE;
1276 high_output &= ~nSRST;
1277 }
1278
1279 /* initialize high port */
1280 buf[0] = 0x82; /* command "set data bits high byte" */
1281 buf[1] = high_output; /* value */
1282 buf[2] = high_direction; /* all outputs (xRST and xRSTnOE) */
1283 DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
1284
1285 if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
1286 {
1287 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1288 return ERROR_JTAG_INIT_FAILED;
1289 }
1290
1291 return ERROR_OK;
1292 }
1293
1294 int olimex_jtag_init(void)
1295 {
1296 u8 buf[3];
1297 u32 bytes_written;
1298
1299 low_output = 0x08;
1300 low_direction = 0x1b;
1301
1302 /* initialize low byte for jtag */
1303 buf[0] = 0x80; /* command "set data bits low byte" */
1304 buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
1305 buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
1306 DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
1307
1308 if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
1309 {
1310 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1311 return ERROR_JTAG_INIT_FAILED;
1312 }
1313
1314 nTRST = 0x01;
1315 nTRSTnOE = 0x4;
1316 nSRST = 0x02;
1317 nSRSTnOE = 0x00; /* no output enable for nSRST */
1318
1319 high_output = 0x0;
1320 high_direction = 0x0f;
1321
1322 if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
1323 {
1324 high_output |= nTRSTnOE;
1325 high_output &= ~nTRST;
1326 }
1327 else
1328 {
1329 high_output &= ~nTRSTnOE;
1330 high_output |= nTRST;
1331 }
1332
1333 if (jtag_reset_config & RESET_SRST_PUSH_PULL)
1334 {
1335 ERROR("can't set nSRST to push-pull on the Olimex ARM-USB-OCD");
1336 }
1337 else
1338 {
1339 high_output &= ~nSRST;
1340 }
1341
1342 /* turn red LED on */
1343 high_output |= 0x08;
1344
1345 /* initialize high port */
1346 buf[0] = 0x82; /* command "set data bits high byte" */
1347 buf[1] = high_output; /* value */
1348 buf[2] = high_direction; /* all outputs (xRST and xRSTnOE) */
1349 DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
1350
1351 if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
1352 {
1353 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout");
1354 return ERROR_JTAG_INIT_FAILED;
1355 }
1356
1357 return ERROR_OK;
1358 }
1359
1360 int m5960_init(void)
1361 {
1362 u8 buf[3];
1363 u32 bytes_written;
1364
1365 low_output = 0x18;
1366 low_direction = 0xfb;
1367
1368 /* initialize low byte for jtag */
1369 buf[0] = 0x80; /* command "set data bits low byte" */
1370 buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
1371 buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE[12]=out, n[ST]srst=out */
1372 DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
1373
1374 if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
1375 {
1376 ERROR("couldn't initialize FT2232 with 'm5960' layout");
1377 return ERROR_JTAG_INIT_FAILED;
1378 }
1379
1380 nTRST = 0x10;
1381 nTRSTnOE = 0x0; /* not output enable for nTRST */
1382 nSRST = 0x20;
1383 nSRSTnOE = 0x00; /* no output enable for nSRST */
1384
1385 high_output = 0x00;
1386 high_direction = 0x0c;
1387
1388 /* turn red LED1 on, LED2 off */
1389 high_output |= 0x08;
1390
1391 /* initialize high port */
1392 buf[0] = 0x82; /* command "set data bits high byte" */
1393 buf[1] = high_output; /* value */
1394 buf[2] = high_direction; /* all outputs (xRST and xRSTnOE) */
1395 DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
1396
1397 if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
1398 {
1399 ERROR("couldn't initialize FT2232 with 'm5960' layout");
1400 return ERROR_JTAG_INIT_FAILED;
1401 }
1402
1403 return ERROR_OK;
1404 }
1405
1406 void olimex_jtag_blink(void)
1407 {
1408 /* Olimex ARM-USB-OCD has a LED connected to ACBUS3
1409 * ACBUS3 is bit 3 of the GPIOH port
1410 */
1411 if (high_output & 0x08)
1412 {
1413 /* set port pin high */
1414 high_output &= 0x07;
1415 }
1416 else
1417 {
1418 /* set port pin low */
1419 high_output |= 0x08;
1420 }
1421
1422 BUFFER_ADD = 0x82;
1423 BUFFER_ADD = high_output;
1424 BUFFER_ADD = high_direction;
1425 }
1426
1427 int ft2232_quit(void)
1428 {
1429 #if BUILD_FT2232_FTD2XX == 1
1430 FT_STATUS status;
1431
1432 status = FT_Close(ftdih);
1433 #elif BUILD_FT2232_LIBFTDI == 1
1434 ftdi_disable_bitbang(&ftdic);
1435
1436 ftdi_usb_close(&ftdic);
1437
1438 ftdi_deinit(&ftdic);
1439 #endif
1440
1441 free(ft2232_buffer);
1442
1443 return ERROR_OK;
1444 }
1445
1446 int ft2232_handle_device_desc_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1447 {
1448 if (argc == 1)
1449 {
1450 ft2232_device_desc = strdup(args[0]);
1451 }
1452 else
1453 {
1454 ERROR("expected exactly one argument to ft2232_device_desc <description>");
1455 }
1456
1457 return ERROR_OK;
1458 }
1459
1460 int ft2232_handle_serial_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1461 {
1462 if (argc == 1)
1463 {
1464 ft2232_serial = strdup(args[0]);
1465 }
1466 else
1467 {
1468 ERROR("expected exactly one argument to ft2232_serial <serial-number>");
1469 }
1470
1471 return ERROR_OK;
1472 }
1473
1474 int ft2232_handle_layout_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1475 {
1476 if (argc == 0)
1477 return ERROR_OK;
1478
1479 ft2232_layout = malloc(strlen(args[0]) + 1);
1480 strcpy(ft2232_layout, args[0]);
1481
1482 return ERROR_OK;
1483 }
1484
1485 int ft2232_handle_vid_pid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1486 {
1487 if (argc >= 2)
1488 {
1489 ft2232_vid = strtol(args[0], NULL, 0);
1490 ft2232_pid = strtol(args[1], NULL, 0);
1491 }
1492 else
1493 {
1494 WARNING("incomplete ft2232_vid_pid configuration directive");
1495 }
1496
1497 return ERROR_OK;
1498 }

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)