]> git.sur5r.net Git - openocd/blob - src/jtag/ft2232.c
- allow FT2232 devices to be opened by serial number instead of device description...
[openocd] / 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 }