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

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)