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