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

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)