cosmetic fixes to debug output + phasing out printf() in favour of logging system...
[fw/openocd] / src / jtag / ft2232.c
1 /***************************************************************************\r
2  *   Copyright (C) 2004, 2006 by Dominic Rath                              *\r
3  *   Dominic.Rath@gmx.de                                                   *\r
4  *                                                                         *\r
5  *   This program is free software; you can redistribute it and/or modify  *\r
6  *   it under the terms of the GNU General Public License as published by  *\r
7  *   the Free Software Foundation; either version 2 of the License, or     *\r
8  *   (at your option) any later version.                                   *\r
9  *                                                                         *\r
10  *   This program is distributed in the hope that it will be useful,       *\r
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
13  *   GNU General Public License for more details.                          *\r
14  *                                                                         *\r
15  *   You should have received a copy of the GNU General Public License     *\r
16  *   along with this program; if not, write to the                         *\r
17  *   Free Software Foundation, Inc.,                                       *\r
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
19  ***************************************************************************/\r
20 #ifdef HAVE_CONFIG_H\r
21 #include "config.h"\r
22 #endif\r
23 \r
24 #if IS_CYGWIN == 1\r
25 #include "windows.h"\r
26 #undef ERROR\r
27 #endif\r
28 \r
29 #include "replacements.h"\r
30 \r
31 /* project specific includes */\r
32 #include "log.h"\r
33 #include "types.h"\r
34 #include "jtag.h"\r
35 #include "configuration.h"\r
36 #include "time_support.h"\r
37 \r
38 /* system includes */\r
39 #include <string.h>\r
40 #include <stdlib.h>\r
41 #include <unistd.h>\r
42 \r
43 /* FT2232 access library includes */\r
44 #if BUILD_FT2232_FTD2XX == 1\r
45 #include <ftd2xx.h>\r
46 #elif BUILD_FT2232_LIBFTDI == 1\r
47 #include <ftdi.h>\r
48 #endif\r
49 \r
50 #include <sys/time.h>\r
51 #include <time.h>\r
52 \r
53 /* enable this to debug io latency\r
54  */\r
55 #if 0\r
56 #define _DEBUG_USB_IO_\r
57 #endif\r
58 \r
59 /* enable this to debug communication\r
60  */\r
61 #if 0\r
62 #define _DEBUG_USB_COMMS_\r
63 #endif\r
64 \r
65 int ft2232_execute_queue(void);\r
66 \r
67 int ft2232_speed(int speed);\r
68 int ft2232_register_commands(struct command_context_s *cmd_ctx);\r
69 int ft2232_init(void);\r
70 int ft2232_quit(void);\r
71 \r
72 int ft2232_handle_device_desc_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
73 int ft2232_handle_serial_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
74 int ft2232_handle_layout_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
75 int ft2232_handle_vid_pid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
76 int ft2232_handle_latency_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
77 \r
78 char *ft2232_device_desc = NULL;\r
79 char *ft2232_serial = NULL;\r
80 char *ft2232_layout = NULL;\r
81 unsigned char ft2232_latency = 2;\r
82 \r
83 #define MAX_USB_IDS     8\r
84 /* vid = pid = 0 marks the end of the list */\r
85 static u16 ft2232_vid[MAX_USB_IDS+1] = { 0x0403, 0 };\r
86 static u16 ft2232_pid[MAX_USB_IDS+1] = { 0x6010, 0 };\r
87 \r
88 typedef struct ft2232_layout_s\r
89 {\r
90         char* name;\r
91         int(*init)(void);\r
92         void(*reset)(int trst, int srst);\r
93         void(*blink)(void);\r
94 } ft2232_layout_t;\r
95 \r
96 /* init procedures for supported layouts */\r
97 int usbjtag_init(void);\r
98 int jtagkey_init(void);\r
99 int olimex_jtag_init(void);\r
100 int flyswatter_init(void);\r
101 int turtle_init(void);\r
102 int comstick_init(void);\r
103 int stm32stick_init(void);\r
104 \r
105 /* reset procedures for supported layouts */\r
106 void usbjtag_reset(int trst, int srst);\r
107 void jtagkey_reset(int trst, int srst);\r
108 void olimex_jtag_reset(int trst, int srst);\r
109 void flyswatter_reset(int trst, int srst);\r
110 void turtle_reset(int trst, int srst);\r
111 void comstick_reset(int trst, int srst);\r
112 void stm32stick_reset(int trst, int srst);\r
113 \r
114 /* blink procedures for layouts that support a blinking led */\r
115 void olimex_jtag_blink(void);\r
116 void turtle_jtag_blink(void);\r
117 \r
118 ft2232_layout_t ft2232_layouts[] =\r
119 {\r
120         {"usbjtag", usbjtag_init, usbjtag_reset, NULL},\r
121         {"jtagkey", jtagkey_init, jtagkey_reset, NULL},\r
122         {"jtagkey_prototype_v1", jtagkey_init, jtagkey_reset, NULL},\r
123         {"oocdlink", jtagkey_init, jtagkey_reset, NULL},\r
124         {"signalyzer", usbjtag_init, usbjtag_reset, NULL},\r
125         {"evb_lm3s811", usbjtag_init, usbjtag_reset, NULL},\r
126         {"olimex-jtag", olimex_jtag_init, olimex_jtag_reset, olimex_jtag_blink},\r
127         {"flyswatter", flyswatter_init, flyswatter_reset, NULL},\r
128         {"turtelizer2", turtle_init, turtle_reset, turtle_jtag_blink},\r
129         {"comstick", comstick_init, comstick_reset, NULL},\r
130         {"stm32stick", stm32stick_init, stm32stick_reset, NULL},\r
131         {NULL, NULL, NULL},\r
132 };\r
133 \r
134 static u8 nTRST, nTRSTnOE, nSRST, nSRSTnOE;\r
135 \r
136 static ft2232_layout_t *layout;\r
137 static u8 low_output = 0x0;\r
138 static u8 low_direction = 0x0;\r
139 static u8 high_output = 0x0;\r
140 static u8 high_direction = 0x0;\r
141 \r
142 #if BUILD_FT2232_FTD2XX == 1\r
143 static FT_HANDLE ftdih = NULL;\r
144 #elif BUILD_FT2232_LIBFTDI == 1\r
145 static struct ftdi_context ftdic;\r
146 #endif\r
147 \r
148 static u8 *ft2232_buffer = NULL;\r
149 static int ft2232_buffer_size = 0;\r
150 static int ft2232_read_pointer = 0;\r
151 static int ft2232_expect_read = 0;\r
152 #define FT2232_BUFFER_SIZE      131072\r
153 #define BUFFER_ADD ft2232_buffer[ft2232_buffer_size++]\r
154 #define BUFFER_READ ft2232_buffer[ft2232_read_pointer++]\r
155 \r
156 jtag_interface_t ft2232_interface = \r
157 {\r
158         \r
159         .name = "ft2232",\r
160         \r
161         .execute_queue = ft2232_execute_queue,\r
162         \r
163         .speed = ft2232_speed,\r
164         .register_commands = ft2232_register_commands,\r
165         .init = ft2232_init,\r
166         .quit = ft2232_quit,\r
167 };\r
168 \r
169 int ft2232_write(u8 *buf, int size, u32* bytes_written)\r
170 {\r
171 #if BUILD_FT2232_FTD2XX == 1\r
172         FT_STATUS status;\r
173         DWORD dw_bytes_written;\r
174         if ((status = FT_Write(ftdih, buf, size, &dw_bytes_written)) != FT_OK)\r
175         {\r
176                 *bytes_written = dw_bytes_written;\r
177                 ERROR("FT_Write returned: %lu", status);\r
178                 return ERROR_JTAG_DEVICE_ERROR;\r
179         }\r
180         else\r
181         {\r
182                 *bytes_written = dw_bytes_written;\r
183                 return ERROR_OK;        \r
184         }\r
185 #elif BUILD_FT2232_LIBFTDI == 1\r
186         int retval;\r
187         if ((retval = ftdi_write_data(&ftdic, buf, size)) < 0)\r
188         {\r
189                 *bytes_written = 0;\r
190                 ERROR("ftdi_write_data: %s", ftdi_get_error_string(&ftdic));\r
191                 return ERROR_JTAG_DEVICE_ERROR;\r
192         }\r
193         else\r
194         {\r
195                 *bytes_written = retval;\r
196                 return ERROR_OK;        \r
197         }\r
198 #endif\r
199 }\r
200 \r
201 int ft2232_read(u8* buf, int size, u32* bytes_read)\r
202 {\r
203 #if BUILD_FT2232_FTD2XX == 1\r
204         DWORD dw_bytes_read;\r
205         FT_STATUS status;\r
206         int timeout = 5;\r
207         *bytes_read = 0;\r
208 \r
209         while ((*bytes_read < size) && timeout--)\r
210         {\r
211                 if ((status = FT_Read(ftdih, buf + *bytes_read, size - \r
212                         *bytes_read, &dw_bytes_read)) != FT_OK)         \r
213                 {\r
214                         *bytes_read = 0; \r
215                         ERROR("FT_Read returned: %lu", status);\r
216                         return ERROR_JTAG_DEVICE_ERROR;\r
217                 }\r
218                 *bytes_read += dw_bytes_read; \r
219         }\r
220 #elif BUILD_FT2232_LIBFTDI == 1\r
221         int retval;\r
222         int timeout = 100;\r
223         *bytes_read = 0;\r
224         \r
225         while ((*bytes_read < size) && timeout--)\r
226         {\r
227                 if ((retval = ftdi_read_data(&ftdic, buf + *bytes_read, size - *bytes_read)) < 0)\r
228                 {\r
229                         *bytes_read = 0;\r
230                         ERROR("ftdi_read_data: %s", ftdi_get_error_string(&ftdic));\r
231                         return ERROR_JTAG_DEVICE_ERROR;\r
232                 }\r
233                 *bytes_read += retval;\r
234         }\r
235 #endif\r
236 \r
237         if (*bytes_read < size)\r
238         {\r
239                 ERROR("couldn't read the requested number of bytes from FT2232 device (%i < %i)", *bytes_read, size);\r
240                 return ERROR_JTAG_DEVICE_ERROR;\r
241         }\r
242         \r
243         return ERROR_OK;\r
244 }\r
245 \r
246 int ft2232_speed(int speed)\r
247 {\r
248         u8 buf[3];\r
249         int retval;\r
250         u32 bytes_written;\r
251 \r
252         buf[0] = 0x86; /* command "set divisor" */\r
253         buf[1] = speed & 0xff; /* valueL (0=6MHz, 1=3MHz, 2=2.0MHz, ...*/\r
254         buf[2] = (speed >> 8) & 0xff; /* valueH */\r
255         \r
256         DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
257         if (((retval = ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
258         {\r
259                 ERROR("couldn't set FT2232 TCK speed");\r
260                 return retval;\r
261         }\r
262 \r
263         jtag_speed = speed;\r
264         \r
265         return ERROR_OK;\r
266 }\r
267 \r
268 int ft2232_register_commands(struct command_context_s *cmd_ctx)\r
269 {\r
270         register_command(cmd_ctx, NULL, "ft2232_device_desc", ft2232_handle_device_desc_command,\r
271                 COMMAND_CONFIG, NULL);\r
272         register_command(cmd_ctx, NULL, "ft2232_serial", ft2232_handle_serial_command,\r
273                 COMMAND_CONFIG, NULL);\r
274         register_command(cmd_ctx, NULL, "ft2232_layout", ft2232_handle_layout_command,\r
275                 COMMAND_CONFIG, NULL);\r
276         register_command(cmd_ctx, NULL, "ft2232_vid_pid", ft2232_handle_vid_pid_command,\r
277                                          COMMAND_CONFIG, NULL);\r
278         register_command(cmd_ctx, NULL, "ft2232_latency", ft2232_handle_latency_command,\r
279                                          COMMAND_CONFIG, NULL);\r
280         return ERROR_OK;\r
281 }\r
282 \r
283 void ft2232_end_state(enum tap_state state)\r
284 {\r
285         if (tap_move_map[state] != -1)\r
286                 end_state = state;\r
287         else\r
288         {\r
289                 ERROR("BUG: %i is not a valid end state", state);\r
290                 exit(-1);\r
291         }\r
292 }\r
293 \r
294 void ft2232_read_scan(enum scan_type type, u8* buffer, int scan_size)\r
295 {\r
296         int num_bytes = ((scan_size + 7) / 8);\r
297         int bits_left = scan_size;\r
298         int cur_byte = 0;\r
299 \r
300         while(num_bytes-- > 1)\r
301         {\r
302                 buffer[cur_byte] = BUFFER_READ;\r
303                 cur_byte++;\r
304                 bits_left -= 8;\r
305         }\r
306 \r
307         buffer[cur_byte] = 0x0;\r
308 \r
309         if (bits_left > 1)\r
310         {\r
311                 buffer[cur_byte] = BUFFER_READ >> 1;\r
312         }\r
313 \r
314         buffer[cur_byte] = (buffer[cur_byte] | ((BUFFER_READ & 0x02) << 6)) >> (8 - bits_left);\r
315 \r
316 }\r
317 \r
318 void ft2232_debug_dump_buffer(void)\r
319 {\r
320         int i;\r
321         char line[256];\r
322         char *line_p = line;\r
323         \r
324         for (i = 0; i < ft2232_buffer_size; i++)\r
325         {\r
326                 line_p += snprintf(line_p, 256 - (line_p - line), "%2.2x ", ft2232_buffer[i]);\r
327                 if (i % 16 == 15)\r
328                 {\r
329                         DEBUG("%s", line);\r
330                         line_p = line;\r
331                 }\r
332         }\r
333         \r
334         if (line_p != line)\r
335                 DEBUG("%s", line);\r
336 }\r
337 \r
338 int ft2232_send_and_recv(jtag_command_t *first, jtag_command_t *last)\r
339 {\r
340         jtag_command_t *cmd;\r
341         u8 *buffer;\r
342         int scan_size;\r
343         enum scan_type type;\r
344         int retval;\r
345         u32 bytes_written;\r
346         u32 bytes_read;\r
347         \r
348 #ifdef _DEBUG_USB_IO_\r
349         struct timeval start, inter, inter2, end;\r
350         struct timeval d_inter, d_inter2, d_end;\r
351 #endif\r
352 \r
353 #ifdef _DEBUG_USB_COMMS_\r
354         DEBUG("write buffer (size %i):", ft2232_buffer_size);\r
355         ft2232_debug_dump_buffer();\r
356 #endif\r
357 \r
358 #ifdef _DEBUG_USB_IO_\r
359         gettimeofday(&start, NULL);     \r
360 #endif\r
361 \r
362         if ((retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written)) != ERROR_OK)\r
363         {\r
364                 ERROR("couldn't write MPSSE commands to FT2232");\r
365                 exit(-1);\r
366         }\r
367         \r
368 #ifdef _DEBUG_USB_IO_\r
369         gettimeofday(&inter, NULL);     \r
370 #endif\r
371         \r
372         if (ft2232_expect_read)\r
373         {\r
374                 int timeout = 100;\r
375                 ft2232_buffer_size = 0;\r
376                 \r
377 #ifdef _DEBUG_USB_IO_\r
378                 gettimeofday(&inter2, NULL);    \r
379 #endif\r
380                 \r
381                 if ((retval = ft2232_read(ft2232_buffer, ft2232_expect_read, &bytes_read)) != ERROR_OK)\r
382                 {\r
383                         ERROR("couldn't read from FT2232");\r
384                         exit(-1);\r
385                 }\r
386                 \r
387 #ifdef _DEBUG_USB_IO_\r
388                 gettimeofday(&end, NULL);       \r
389 \r
390                 timeval_subtract(&d_inter, &inter, &start);\r
391                 timeval_subtract(&d_inter2, &inter2, &start);\r
392                 timeval_subtract(&d_end, &end, &start);\r
393 \r
394                 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);\r
395 #endif\r
396         \r
397                 \r
398                 ft2232_buffer_size = bytes_read;\r
399                 \r
400                 if (ft2232_expect_read != ft2232_buffer_size)\r
401                 {\r
402                         ERROR("ft2232_expect_read (%i) != ft2232_buffer_size (%i) (%i retries)", ft2232_expect_read, ft2232_buffer_size, 100 - timeout);\r
403                         ft2232_debug_dump_buffer();     \r
404 \r
405                         exit(-1);\r
406                 }\r
407 \r
408 #ifdef _DEBUG_USB_COMMS_\r
409                 DEBUG("read buffer (%i retries): %i bytes", 100 - timeout, ft2232_buffer_size);\r
410                 ft2232_debug_dump_buffer();\r
411 #endif\r
412         }\r
413 \r
414         ft2232_expect_read = 0;\r
415         ft2232_read_pointer = 0;\r
416         \r
417         /* return ERROR_OK, unless a jtag_read_buffer returns a failed check\r
418          * that wasn't handled by a caller-provided error handler\r
419          */ \r
420         retval = ERROR_OK;\r
421         \r
422         cmd = first;\r
423         while (cmd != last)\r
424         {\r
425                 switch (cmd->type)\r
426                 {\r
427                         case JTAG_SCAN:\r
428                                 type = jtag_scan_type(cmd->cmd.scan);\r
429                                 if (type != SCAN_OUT)\r
430                                 {\r
431                                         scan_size = jtag_scan_size(cmd->cmd.scan);\r
432                                         buffer = calloc(CEIL(scan_size, 8), 1);\r
433                                         ft2232_read_scan(type, buffer, scan_size);\r
434                                         if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)\r
435                                                 retval = ERROR_JTAG_QUEUE_FAILED;\r
436                                         free(buffer);\r
437                                 }\r
438                                 break;\r
439                         default:\r
440                                 break;\r
441                 }\r
442                 cmd = cmd->next;\r
443         }\r
444         \r
445         ft2232_buffer_size = 0;\r
446 \r
447         return retval;\r
448 }\r
449 \r
450 void ft2232_add_pathmove(pathmove_command_t *cmd)\r
451 {\r
452         int num_states = cmd->num_states;\r
453         u8 tms_byte;\r
454         int state_count;\r
455 \r
456         state_count = 0;\r
457         while (num_states)\r
458         {\r
459                 tms_byte = 0x0;\r
460                 int bit_count = 0;\r
461                 \r
462                 /* command "Clock Data to TMS/CS Pin (no Read)" */\r
463                 BUFFER_ADD = 0x4b;\r
464                 /* number of states remaining */\r
465                 BUFFER_ADD = (num_states % 7) - 1;\r
466                 \r
467                 while (num_states % 7)\r
468                 {\r
469                         if (tap_transitions[cur_state].low == cmd->path[state_count])\r
470                                 buf_set_u32(&tms_byte, bit_count++, 1, 0x0);\r
471                         else if (tap_transitions[cur_state].high == cmd->path[state_count])\r
472                                 buf_set_u32(&tms_byte, bit_count++, 1, 0x1);\r
473                         else\r
474                         {\r
475                                 ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]);\r
476                                 exit(-1);\r
477                         }\r
478 \r
479                         cur_state = cmd->path[state_count];\r
480                         state_count++;\r
481                         num_states--;\r
482                 }\r
483                 \r
484                 BUFFER_ADD = tms_byte;\r
485         }\r
486         \r
487         end_state = cur_state;\r
488 }\r
489 \r
490 void ft2232_add_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)\r
491 {\r
492         int num_bytes = (scan_size + 7) / 8;\r
493         int bits_left = scan_size;\r
494         int cur_byte = 0;\r
495         int last_bit;\r
496 \r
497         if (!((!ir_scan && (cur_state == TAP_SD)) || (ir_scan && (cur_state == TAP_SI))))\r
498         {\r
499                 /* command "Clock Data to TMS/CS Pin (no Read)" */\r
500                 BUFFER_ADD = 0x4b;\r
501                 /* scan 7 bit */\r
502                 BUFFER_ADD = 0x6;\r
503                 /* TMS data bits */\r
504                 if (ir_scan)\r
505                 {\r
506                         BUFFER_ADD = TAP_MOVE(cur_state, TAP_SI);\r
507                         cur_state = TAP_SI;\r
508                 }\r
509                 else\r
510                 {\r
511                         BUFFER_ADD = TAP_MOVE(cur_state, TAP_SD);\r
512                         cur_state = TAP_SD;\r
513                 }\r
514                 //DEBUG("added TMS scan (no read)");\r
515         }\r
516         \r
517         /* add command for complete bytes */\r
518         while (num_bytes > 1)\r
519         {\r
520                 int thisrun_bytes;\r
521                 if (type == SCAN_IO)\r
522                 {\r
523                         /* Clock Data Bytes In and Out LSB First */\r
524                         BUFFER_ADD = 0x39;\r
525                         //DEBUG("added TDI bytes (io %i)", num_bytes);\r
526                 }\r
527                 else if (type == SCAN_OUT)\r
528                 {\r
529                         /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */\r
530                         BUFFER_ADD = 0x19;\r
531                         //DEBUG("added TDI bytes (o)");\r
532                 }\r
533                 else if (type == SCAN_IN)\r
534                 {\r
535                         /* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */\r
536                         BUFFER_ADD = 0x28;\r
537                         //DEBUG("added TDI bytes (i %i)", num_bytes);\r
538                 }\r
539                 thisrun_bytes = (num_bytes > 65537) ? 65536 : (num_bytes - 1);\r
540                 num_bytes -= thisrun_bytes;\r
541                 BUFFER_ADD = (thisrun_bytes - 1) & 0xff;\r
542                 BUFFER_ADD = ((thisrun_bytes - 1) >> 8) & 0xff;\r
543                 if (type != SCAN_IN)\r
544                 {\r
545                         /* add complete bytes */\r
546                         while(thisrun_bytes-- > 0)\r
547                         {\r
548                                 BUFFER_ADD = buffer[cur_byte];\r
549                                 cur_byte++;\r
550                                 bits_left -= 8;\r
551                         }\r
552                 }\r
553                 else /* (type == SCAN_IN) */\r
554                 {\r
555                         bits_left -= 8 * (thisrun_bytes);\r
556                 }\r
557         }\r
558         \r
559         /* the most signifcant bit is scanned during TAP movement */\r
560         if (type != SCAN_IN)\r
561                 last_bit = (buffer[cur_byte] >> (bits_left - 1)) & 0x1;\r
562         else\r
563                 last_bit = 0;\r
564 \r
565         /* process remaining bits but the last one */\r
566         if (bits_left > 1)\r
567         {\r
568                 if (type == SCAN_IO)\r
569                 {\r
570                         /* Clock Data Bits In and Out LSB First */\r
571                         BUFFER_ADD = 0x3b;\r
572                         //DEBUG("added TDI bits (io) %i", bits_left - 1);\r
573                 }\r
574                 else if (type == SCAN_OUT)\r
575                 {\r
576                         /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */\r
577                         BUFFER_ADD = 0x1b;\r
578                         //DEBUG("added TDI bits (o)");\r
579                 }\r
580                 else if (type == SCAN_IN)\r
581                 {\r
582                         /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */\r
583                         BUFFER_ADD = 0x2a;\r
584                         //DEBUG("added TDI bits (i %i)", bits_left - 1);\r
585                 }\r
586                 BUFFER_ADD = bits_left - 2;\r
587                 if (type != SCAN_IN)\r
588                         BUFFER_ADD = buffer[cur_byte];\r
589         }\r
590 \r
591         if ((ir_scan && (end_state == TAP_SI)) ||\r
592                 (!ir_scan && (end_state == TAP_SD)))\r
593         {\r
594                 if (type == SCAN_IO)\r
595                 {\r
596                         /* Clock Data Bits In and Out LSB First */\r
597                         BUFFER_ADD = 0x3b;\r
598                         //DEBUG("added TDI bits (io) %i", bits_left - 1);\r
599                 }\r
600                 else if (type == SCAN_OUT)\r
601                 {\r
602                         /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */\r
603                         BUFFER_ADD = 0x1b;\r
604                         //DEBUG("added TDI bits (o)");\r
605                 }\r
606                 else if (type == SCAN_IN)\r
607                 {\r
608                         /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */\r
609                         BUFFER_ADD = 0x2a;\r
610                         //DEBUG("added TDI bits (i %i)", bits_left - 1);\r
611                 }\r
612                 BUFFER_ADD = 0x0;\r
613                 BUFFER_ADD = last_bit;\r
614         }\r
615         else\r
616         {\r
617                 /* move from Shift-IR/DR to end state */\r
618                 if (type != SCAN_OUT)\r
619                 {\r
620                         /* Clock Data to TMS/CS Pin with Read */\r
621                         BUFFER_ADD = 0x6b;\r
622                         //DEBUG("added TMS scan (read)");\r
623                 }\r
624                 else\r
625                 {\r
626                         /* Clock Data to TMS/CS Pin (no Read) */\r
627                         BUFFER_ADD = 0x4b;\r
628                         //DEBUG("added TMS scan (no read)");\r
629                 }\r
630                 BUFFER_ADD = 0x6;\r
631                 BUFFER_ADD = TAP_MOVE(cur_state, end_state) | (last_bit << 7);\r
632                 cur_state = end_state;\r
633         }\r
634 }\r
635 \r
636 int ft2232_large_scan(scan_command_t *cmd, enum scan_type type, u8 *buffer, int scan_size)\r
637 {\r
638         int num_bytes = (scan_size + 7) / 8;\r
639         int bits_left = scan_size;\r
640         int cur_byte = 0;\r
641         int last_bit;\r
642         u8 *receive_buffer = malloc(CEIL(scan_size, 8));\r
643         u8 *receive_pointer = receive_buffer;\r
644         u32 bytes_written;\r
645         u32 bytes_read;\r
646         int retval;\r
647         int thisrun_read = 0;\r
648         \r
649         if (cmd->ir_scan)\r
650         {\r
651                 ERROR("BUG: large IR scans are not supported");\r
652                 exit(-1);\r
653         }\r
654 \r
655         if (cur_state != TAP_SD)\r
656         {\r
657                 /* command "Clock Data to TMS/CS Pin (no Read)" */\r
658                 BUFFER_ADD = 0x4b;\r
659                 /* scan 7 bit */\r
660                 BUFFER_ADD = 0x6;\r
661                 /* TMS data bits */\r
662                 BUFFER_ADD = TAP_MOVE(cur_state, TAP_SD);\r
663                 cur_state = TAP_SD;\r
664         }\r
665         \r
666         if ((retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written)) != ERROR_OK)\r
667         {\r
668                 ERROR("couldn't write MPSSE commands to FT2232");\r
669                 exit(-1);\r
670         }\r
671         DEBUG("ft2232_buffer_size: %i, bytes_written: %i", ft2232_buffer_size, bytes_written);\r
672         ft2232_buffer_size = 0;\r
673         \r
674         /* add command for complete bytes */\r
675         while (num_bytes > 1)\r
676         {\r
677                 int thisrun_bytes;\r
678                 \r
679                 if (type == SCAN_IO)\r
680                 {\r
681                         /* Clock Data Bytes In and Out LSB First */\r
682                         BUFFER_ADD = 0x39;\r
683                         //DEBUG("added TDI bytes (io %i)", num_bytes);\r
684                 }\r
685                 else if (type == SCAN_OUT)\r
686                 {\r
687                         /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */\r
688                         BUFFER_ADD = 0x19;\r
689                         //DEBUG("added TDI bytes (o)");\r
690                 }\r
691                 else if (type == SCAN_IN)\r
692                 {\r
693                         /* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */\r
694                         BUFFER_ADD = 0x28;\r
695                         //DEBUG("added TDI bytes (i %i)", num_bytes);\r
696                 }\r
697                 thisrun_bytes = (num_bytes > 65537) ? 65536 : (num_bytes - 1);\r
698                 thisrun_read = thisrun_bytes;\r
699                 num_bytes -= thisrun_bytes;\r
700                 BUFFER_ADD = (thisrun_bytes - 1) & 0xff;\r
701                 BUFFER_ADD = ((thisrun_bytes - 1) >> 8) & 0xff;\r
702                 if (type != SCAN_IN)\r
703                 {\r
704                         /* add complete bytes */\r
705                         while(thisrun_bytes-- > 0)\r
706                         {\r
707                                 BUFFER_ADD = buffer[cur_byte];\r
708                                 cur_byte++;\r
709                                 bits_left -= 8;\r
710                         }\r
711                 }\r
712                 else /* (type == SCAN_IN) */\r
713                 {\r
714                         bits_left -= 8 * (thisrun_bytes);\r
715                 }\r
716 \r
717                 if ((retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written)) != ERROR_OK)\r
718                 {\r
719                         ERROR("couldn't write MPSSE commands to FT2232");\r
720                         exit(-1);\r
721                 }\r
722                 DEBUG("ft2232_buffer_size: %i, bytes_written: %i", ft2232_buffer_size, bytes_written);\r
723                 ft2232_buffer_size = 0;\r
724                 \r
725                 if (type != SCAN_OUT)\r
726                 {\r
727                         if ((retval = ft2232_read(receive_pointer, thisrun_read, &bytes_read)) != ERROR_OK)\r
728                         {\r
729                                 ERROR("couldn't read from FT2232");\r
730                                 exit(-1);\r
731                         }\r
732                         DEBUG("thisrun_read: %i, bytes_read: %i", thisrun_read, bytes_read);\r
733                         receive_pointer += bytes_read;\r
734                 }\r
735         }\r
736         \r
737         thisrun_read = 0;\r
738         \r
739         /* the most signifcant bit is scanned during TAP movement */\r
740         if (type != SCAN_IN)\r
741                 last_bit = (buffer[cur_byte] >> (bits_left - 1)) & 0x1;\r
742         else\r
743                 last_bit = 0;\r
744 \r
745         /* process remaining bits but the last one */\r
746         if (bits_left > 1)\r
747         {\r
748                 if (type == SCAN_IO)\r
749                 {\r
750                         /* Clock Data Bits In and Out LSB First */\r
751                         BUFFER_ADD = 0x3b;\r
752                         //DEBUG("added TDI bits (io) %i", bits_left - 1);\r
753                 }\r
754                 else if (type == SCAN_OUT)\r
755                 {\r
756                         /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */\r
757                         BUFFER_ADD = 0x1b;\r
758                         //DEBUG("added TDI bits (o)");\r
759                 }\r
760                 else if (type == SCAN_IN)\r
761                 {\r
762                         /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */\r
763                         BUFFER_ADD = 0x2a;\r
764                         //DEBUG("added TDI bits (i %i)", bits_left - 1);\r
765                 }\r
766                 BUFFER_ADD = bits_left - 2;\r
767                 if (type != SCAN_IN)\r
768                         BUFFER_ADD = buffer[cur_byte];\r
769                         \r
770                 if (type != SCAN_OUT)\r
771                         thisrun_read += 2;\r
772         }\r
773 \r
774         if (end_state == TAP_SD)\r
775         {\r
776                 if (type == SCAN_IO)\r
777                 {\r
778                         /* Clock Data Bits In and Out LSB First */\r
779                         BUFFER_ADD = 0x3b;\r
780                         //DEBUG("added TDI bits (io) %i", bits_left - 1);\r
781                 }\r
782                 else if (type == SCAN_OUT)\r
783                 {\r
784                         /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */\r
785                         BUFFER_ADD = 0x1b;\r
786                         //DEBUG("added TDI bits (o)");\r
787                 }\r
788                 else if (type == SCAN_IN)\r
789                 {\r
790                         /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */\r
791                         BUFFER_ADD = 0x2a;\r
792                         //DEBUG("added TDI bits (i %i)", bits_left - 1);\r
793                 }\r
794                 BUFFER_ADD = 0x0;\r
795                 BUFFER_ADD = last_bit;\r
796         }\r
797         else\r
798         {\r
799                 /* move from Shift-IR/DR to end state */\r
800                 if (type != SCAN_OUT)\r
801                 {\r
802                         /* Clock Data to TMS/CS Pin with Read */\r
803                         BUFFER_ADD = 0x6b;\r
804                         //DEBUG("added TMS scan (read)");\r
805                 }\r
806                 else\r
807                 {\r
808                         /* Clock Data to TMS/CS Pin (no Read) */\r
809                         BUFFER_ADD = 0x4b;\r
810                         //DEBUG("added TMS scan (no read)");\r
811                 }\r
812                 BUFFER_ADD = 0x6;\r
813                 BUFFER_ADD = TAP_MOVE(cur_state, end_state) | (last_bit << 7);\r
814                 cur_state = end_state;\r
815         }\r
816         \r
817         if (type != SCAN_OUT)\r
818                 thisrun_read += 1;\r
819         \r
820         if ((retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written)) != ERROR_OK)\r
821         {\r
822                 ERROR("couldn't write MPSSE commands to FT2232");\r
823                 exit(-1);\r
824         }\r
825         DEBUG("ft2232_buffer_size: %i, bytes_written: %i", ft2232_buffer_size, bytes_written);\r
826         ft2232_buffer_size = 0;\r
827         \r
828         if (type != SCAN_OUT)\r
829         {\r
830                 if ((retval = ft2232_read(receive_pointer, thisrun_read, &bytes_read)) != ERROR_OK)\r
831                 {\r
832                         ERROR("couldn't read from FT2232");\r
833                         exit(-1);\r
834                 }\r
835                 DEBUG("thisrun_read: %i, bytes_read: %i", thisrun_read, bytes_read);\r
836                 receive_pointer += bytes_read;\r
837         }\r
838         \r
839         return ERROR_OK;\r
840 }\r
841 \r
842 int ft2232_predict_scan_out(int scan_size, enum scan_type type)\r
843 {\r
844         int predicted_size = 3;\r
845         int num_bytes = (scan_size - 1) / 8;\r
846         \r
847         if (cur_state != TAP_SD)\r
848                 predicted_size += 3;\r
849         \r
850         if (type == SCAN_IN)    /* only from device to host */\r
851         {\r
852                 /* complete bytes */\r
853                 predicted_size += (CEIL(num_bytes, 65536)) * 3;\r
854                 /* remaining bits - 1 (up to 7) */\r
855                 predicted_size += ((scan_size - 1) % 8) ? 2 : 0;\r
856         }\r
857         else                                    /* host to device, or bidirectional */\r
858         {\r
859                 /* complete bytes */\r
860                 predicted_size += num_bytes + (CEIL(num_bytes, 65536)) * 3;\r
861                 /* remaining bits -1 (up to 7) */\r
862                 predicted_size += ((scan_size - 1) % 8) ? 3 : 0;\r
863         }\r
864 \r
865         return predicted_size;\r
866 }\r
867 \r
868 int ft2232_predict_scan_in(int scan_size, enum scan_type type)\r
869 {\r
870         int predicted_size = 0;\r
871         \r
872         if (type != SCAN_OUT)\r
873         {\r
874                 /* complete bytes */\r
875                 predicted_size += (CEIL(scan_size, 8) > 1) ? (CEIL(scan_size, 8) - 1) : 0;\r
876                 /* remaining bits - 1 */\r
877                 predicted_size += ((scan_size - 1) % 8) ? 1 : 0;\r
878                 /* last bit (from TMS scan) */\r
879                 predicted_size += 1;\r
880         }\r
881         \r
882         //DEBUG("scan_size: %i, predicted_size: %i", scan_size, predicted_size);\r
883 \r
884         return predicted_size;\r
885 }\r
886 \r
887 void usbjtag_reset(int trst, int srst)\r
888 {\r
889         if (trst == 1)\r
890         {\r
891                 cur_state = TAP_TLR;\r
892                 if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
893                         low_direction |= nTRSTnOE;      /* switch to output pin (output is low) */\r
894                 else\r
895                         low_output &= ~nTRST;   /* switch output low */\r
896         }\r
897         else if (trst == 0)\r
898         {\r
899                 if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
900                         low_direction &= ~nTRSTnOE; /* switch to input pin (high-Z + internal and external pullup) */\r
901                 else\r
902                         low_output |= nTRST; /* switch output high */\r
903         }\r
904 \r
905         if (srst == 1)\r
906         {\r
907                 if (jtag_reset_config & RESET_SRST_PUSH_PULL)\r
908                         low_output &= ~nSRST;   /* switch output low */\r
909                 else\r
910                         low_direction |= nSRSTnOE;      /* switch to output pin (output is low) */\r
911         }\r
912         else if (srst == 0)\r
913         {\r
914                 if (jtag_reset_config & RESET_SRST_PUSH_PULL)\r
915                         low_output |= nSRST;    /* switch output high */\r
916                 else\r
917                         low_direction &= ~nSRSTnOE;     /* switch to input pin (high-Z) */\r
918         }\r
919         \r
920         /* command "set data bits low byte" */\r
921         BUFFER_ADD = 0x80;\r
922         BUFFER_ADD = low_output;\r
923         BUFFER_ADD = low_direction;\r
924 \r
925 }\r
926 \r
927 void jtagkey_reset(int trst, int srst)\r
928 {\r
929         if (trst == 1)\r
930         {\r
931                 cur_state = TAP_TLR;\r
932                 if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
933                         high_output &= ~nTRSTnOE;\r
934                 else\r
935                         high_output &= ~nTRST;\r
936         }\r
937         else if (trst == 0)\r
938         {\r
939                 if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
940                         high_output |= nTRSTnOE;\r
941                 else\r
942                         high_output |= nTRST;\r
943         }\r
944 \r
945         if (srst == 1)\r
946         {\r
947                 if (jtag_reset_config & RESET_SRST_PUSH_PULL)\r
948                         high_output &= ~nSRST;\r
949                 else\r
950                         high_output &= ~nSRSTnOE;\r
951         }\r
952         else if (srst == 0)\r
953         {\r
954                 if (jtag_reset_config & RESET_SRST_PUSH_PULL)\r
955                         high_output |= nSRST;\r
956                 else\r
957                         high_output |= nSRSTnOE;\r
958         }\r
959         \r
960         /* command "set data bits high byte" */\r
961         BUFFER_ADD = 0x82;\r
962         BUFFER_ADD = high_output;\r
963         BUFFER_ADD = high_direction;\r
964         DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);\r
965 }\r
966 \r
967 void olimex_jtag_reset(int trst, int srst)\r
968 {\r
969         if (trst == 1)\r
970         {\r
971                 cur_state = TAP_TLR;\r
972                 if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
973                         high_output &= ~nTRSTnOE;\r
974                 else\r
975                         high_output &= ~nTRST;\r
976         }\r
977         else if (trst == 0)\r
978         {\r
979                 if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
980                         high_output |= nTRSTnOE;\r
981                 else\r
982                         high_output |= nTRST;\r
983         }\r
984 \r
985     if (srst == 1)\r
986     {\r
987         high_output |= nSRST;\r
988     }\r
989     else if (srst == 0)\r
990     {\r
991         high_output &= ~nSRST;\r
992     }\r
993 \r
994     /* command "set data bits high byte" */\r
995     BUFFER_ADD = 0x82;\r
996     BUFFER_ADD = high_output;\r
997     BUFFER_ADD = high_direction;\r
998     DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);\r
999 }\r
1000 \r
1001 void flyswatter_reset(int trst, int srst)\r
1002 {\r
1003         if (trst == 1)\r
1004         {\r
1005                 cur_state = TAP_TLR;\r
1006                 low_output &= ~nTRST;\r
1007         }\r
1008         else if (trst == 0)\r
1009         {\r
1010                 low_output |= nTRST;\r
1011         }\r
1012 \r
1013     if (srst == 1)\r
1014     {\r
1015         low_output |= nSRST;\r
1016     }\r
1017     else if (srst == 0)\r
1018     {\r
1019         low_output &= ~nSRST;\r
1020     }\r
1021 \r
1022     /* command "set data bits low byte" */\r
1023     BUFFER_ADD = 0x80;\r
1024     BUFFER_ADD = low_output;\r
1025     BUFFER_ADD = low_direction;\r
1026     DEBUG("trst: %i, srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", trst, srst, low_output, low_direction);\r
1027 }\r
1028 \r
1029 void turtle_reset(int trst, int srst)\r
1030 {\r
1031         trst = trst;\r
1032         \r
1033         if (srst == 1)\r
1034         {\r
1035                 low_output |= nSRST;\r
1036         }\r
1037         else if (srst == 0)\r
1038         {\r
1039                 low_output &= ~nSRST;\r
1040         }\r
1041         \r
1042         /* command "set data bits low byte" */\r
1043         BUFFER_ADD = 0x80;\r
1044         BUFFER_ADD = low_output;\r
1045         BUFFER_ADD = low_direction;\r
1046         DEBUG("srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", srst, low_output, low_direction);\r
1047 }\r
1048 \r
1049 void comstick_reset(int trst, int srst)\r
1050 {\r
1051         if (trst == 1)\r
1052         {\r
1053                 cur_state = TAP_TLR;\r
1054                 high_output &= ~nTRST;\r
1055         }\r
1056         else if (trst == 0)\r
1057         {\r
1058                 high_output |= nTRST;\r
1059         }\r
1060 \r
1061     if (srst == 1)\r
1062     {\r
1063         high_output &= ~nSRST;\r
1064     }\r
1065     else if (srst == 0)\r
1066     {\r
1067         high_output |= nSRST;\r
1068     }\r
1069         \r
1070         /* command "set data bits high byte" */\r
1071         BUFFER_ADD = 0x82;\r
1072         BUFFER_ADD = high_output;\r
1073         BUFFER_ADD = high_direction;\r
1074         DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);\r
1075 }\r
1076 \r
1077 void stm32stick_reset(int trst, int srst)\r
1078 {\r
1079         if (trst == 1)\r
1080         {\r
1081                 cur_state = TAP_TLR;\r
1082                 high_output &= ~nTRST;\r
1083         }\r
1084         else if (trst == 0)\r
1085         {\r
1086                 high_output |= nTRST;\r
1087         }\r
1088 \r
1089     if (srst == 1)\r
1090     {\r
1091         low_output &= ~nSRST;\r
1092     }\r
1093     else if (srst == 0)\r
1094     {\r
1095         low_output |= nSRST;\r
1096     }\r
1097         \r
1098         /* command "set data bits low byte" */\r
1099         BUFFER_ADD = 0x80;\r
1100         BUFFER_ADD = low_output;\r
1101         BUFFER_ADD = low_direction;\r
1102         \r
1103         /* command "set data bits high byte" */\r
1104         BUFFER_ADD = 0x82;\r
1105         BUFFER_ADD = high_output;\r
1106         BUFFER_ADD = high_direction;\r
1107         DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);\r
1108 }\r
1109 \r
1110 int ft2232_execute_queue()\r
1111 {\r
1112         jtag_command_t *cmd = jtag_command_queue; /* currently processed command */\r
1113         jtag_command_t *first_unsent = cmd;     /* next command that has to be sent */\r
1114         u8 *buffer;\r
1115         int scan_size;  /* size of IR or DR scan */\r
1116         enum scan_type type;\r
1117         int i;\r
1118         int predicted_size = 0;\r
1119         int require_send = 0;\r
1120         int retval;\r
1121         \r
1122         /* return ERROR_OK, unless ft2232_send_and_recv reports a failed check\r
1123          * that wasn't handled by a caller-provided error handler\r
1124          */ \r
1125         retval = ERROR_OK;\r
1126 \r
1127         ft2232_buffer_size = 0;\r
1128         ft2232_expect_read = 0;\r
1129         \r
1130         /* blink, if the current layout has that feature */\r
1131         if (layout->blink)\r
1132                 layout->blink();\r
1133 \r
1134         while (cmd)\r
1135         {\r
1136                 switch(cmd->type)\r
1137                 {\r
1138                         case JTAG_END_STATE:\r
1139                                 if (cmd->cmd.end_state->end_state != -1)\r
1140                                         ft2232_end_state(cmd->cmd.end_state->end_state);\r
1141                                 break;\r
1142                         case JTAG_RESET:\r
1143                                 /* only send the maximum buffer size that FT2232C can handle */\r
1144                                 predicted_size = 3;\r
1145                                 if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)\r
1146                                 {\r
1147                                         if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
1148                                                 retval = ERROR_JTAG_QUEUE_FAILED;\r
1149                                         require_send = 0;\r
1150                                         first_unsent = cmd;\r
1151                                 }\r
1152 \r
1153                                 layout->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);\r
1154                                 require_send = 1;\r
1155                                 \r
1156 #ifdef _DEBUG_JTAG_IO_                          \r
1157                                 DEBUG("trst: %i, srst: %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);\r
1158 #endif\r
1159                                 break;\r
1160                         case JTAG_RUNTEST:\r
1161                                 /* only send the maximum buffer size that FT2232C can handle */\r
1162                                 predicted_size = 0;\r
1163                                 if (cur_state != TAP_RTI)\r
1164                                         predicted_size += 3;\r
1165                                 predicted_size += 3 * CEIL(cmd->cmd.runtest->num_cycles, 7);\r
1166                                 if ((cmd->cmd.runtest->end_state != -1) && (cmd->cmd.runtest->end_state != TAP_RTI))\r
1167                                         predicted_size += 3;\r
1168                                 if ((cmd->cmd.runtest->end_state == -1) && (end_state != TAP_RTI))\r
1169                                         predicted_size += 3;\r
1170                                 if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)\r
1171                                 {\r
1172                                         if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
1173                                                 retval = ERROR_JTAG_QUEUE_FAILED;\r
1174                                         require_send = 0;\r
1175                                         first_unsent = cmd;\r
1176                                 }\r
1177                                 if (cur_state != TAP_RTI)\r
1178                                 {\r
1179                                         /* command "Clock Data to TMS/CS Pin (no Read)" */\r
1180                                         BUFFER_ADD = 0x4b;\r
1181                                         /* scan 7 bit */\r
1182                                         BUFFER_ADD = 0x6;\r
1183                                         /* TMS data bits */\r
1184                                         BUFFER_ADD = TAP_MOVE(cur_state, TAP_RTI);\r
1185                                         cur_state = TAP_RTI;\r
1186                                         require_send = 1;\r
1187                                 }\r
1188                                 i = cmd->cmd.runtest->num_cycles;\r
1189                                 while (i > 0)\r
1190                                 {\r
1191                                         /* command "Clock Data to TMS/CS Pin (no Read)" */\r
1192                                         BUFFER_ADD = 0x4b;\r
1193                                         /* scan 7 bit */\r
1194                                         BUFFER_ADD = (i > 7) ? 6 : (i - 1);\r
1195                                         /* TMS data bits */\r
1196                                         BUFFER_ADD = 0x0;\r
1197                                         cur_state = TAP_RTI;\r
1198                                         i -= (i > 7) ? 7 : i;\r
1199                                         //DEBUG("added TMS scan (no read)");\r
1200                                 }\r
1201                                 if (cmd->cmd.runtest->end_state != -1)\r
1202                                         ft2232_end_state(cmd->cmd.runtest->end_state);\r
1203                                 if (cur_state != end_state)\r
1204                                 {\r
1205                                         /* command "Clock Data to TMS/CS Pin (no Read)" */\r
1206                                         BUFFER_ADD = 0x4b;\r
1207                                         /* scan 7 bit */\r
1208                                         BUFFER_ADD = 0x6;\r
1209                                         /* TMS data bits */\r
1210                                         BUFFER_ADD = TAP_MOVE(cur_state, end_state);\r
1211                                         cur_state = end_state;\r
1212                                         //DEBUG("added TMS scan (no read)");\r
1213                                 }\r
1214                                 require_send = 1;\r
1215 #ifdef _DEBUG_JTAG_IO_                          \r
1216                                 DEBUG("runtest: %i, end in %i", cmd->cmd.runtest->num_cycles, end_state);\r
1217 #endif\r
1218                                 break;\r
1219                         case JTAG_STATEMOVE:\r
1220                                 /* only send the maximum buffer size that FT2232C can handle */\r
1221                                 predicted_size = 3;\r
1222                                 if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)\r
1223                                 {\r
1224                                         if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
1225                                                 retval = ERROR_JTAG_QUEUE_FAILED;\r
1226                                         require_send = 0;\r
1227                                         first_unsent = cmd;\r
1228                                 }\r
1229                                 if (cmd->cmd.statemove->end_state != -1)\r
1230                                         ft2232_end_state(cmd->cmd.statemove->end_state);\r
1231                                 /* command "Clock Data to TMS/CS Pin (no Read)" */\r
1232                                 BUFFER_ADD = 0x4b;\r
1233                                 /* scan 7 bit */\r
1234                                 BUFFER_ADD = 0x6;\r
1235                                 /* TMS data bits */\r
1236                                 BUFFER_ADD = TAP_MOVE(cur_state, end_state);\r
1237                                 //DEBUG("added TMS scan (no read)");\r
1238                                 cur_state = end_state;\r
1239                                 require_send = 1;\r
1240 #ifdef _DEBUG_JTAG_IO_                          \r
1241                                 DEBUG("statemove: %i", end_state);\r
1242 #endif\r
1243                                 break;\r
1244                         case JTAG_PATHMOVE:\r
1245                                 /* only send the maximum buffer size that FT2232C can handle */\r
1246                                 predicted_size = 3 * CEIL(cmd->cmd.pathmove->num_states, 7);\r
1247                                 if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)\r
1248                                 {\r
1249                                         if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
1250                                                 retval = ERROR_JTAG_QUEUE_FAILED;\r
1251                                         require_send = 0;\r
1252                                         first_unsent = cmd;\r
1253                                 }\r
1254                                 ft2232_add_pathmove(cmd->cmd.pathmove);\r
1255                                 require_send = 1;\r
1256 #ifdef _DEBUG_JTAG_IO_                          \r
1257                                 DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);\r
1258 #endif\r
1259                                 break;\r
1260                         case JTAG_SCAN:\r
1261                                 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);\r
1262                                 type = jtag_scan_type(cmd->cmd.scan);\r
1263                                 predicted_size = ft2232_predict_scan_out(scan_size, type);\r
1264                                 if ((predicted_size + 1) > FT2232_BUFFER_SIZE)\r
1265                                 {\r
1266                                         DEBUG("oversized ft2232 scan (predicted_size > FT2232_BUFFER_SIZE)");\r
1267                                         /* unsent commands before this */\r
1268                                         if (first_unsent != cmd)\r
1269                                                 if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
1270                                                         retval = ERROR_JTAG_QUEUE_FAILED;\r
1271                                         \r
1272                                         /* current command */\r
1273                                         if (cmd->cmd.scan->end_state != -1)\r
1274                                                 ft2232_end_state(cmd->cmd.scan->end_state);\r
1275                                         ft2232_large_scan(cmd->cmd.scan, type, buffer, scan_size);\r
1276                                         require_send = 0;\r
1277                                         first_unsent = cmd->next;\r
1278                                         if (buffer)\r
1279                                                 free(buffer);\r
1280                                         break;\r
1281                                 }\r
1282                                 else if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)\r
1283                                 {\r
1284                                         DEBUG("ft2232 buffer size reached, sending queued commands (first_unsent: %p, cmd: %p)", first_unsent, cmd);\r
1285                                         if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
1286                                                 retval = ERROR_JTAG_QUEUE_FAILED;\r
1287                                         require_send = 0;\r
1288                                         first_unsent = cmd;\r
1289                                 }\r
1290                                 ft2232_expect_read += ft2232_predict_scan_in(scan_size, type);\r
1291                                 //DEBUG("new read size: %i", ft2232_expect_read);\r
1292                                 if (cmd->cmd.scan->end_state != -1)\r
1293                                         ft2232_end_state(cmd->cmd.scan->end_state);\r
1294                                 ft2232_add_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);\r
1295                                 require_send = 1;\r
1296                                 if (buffer)\r
1297                                         free(buffer);\r
1298 #ifdef _DEBUG_JTAG_IO_                          \r
1299                                 DEBUG("%s scan, %i bit, end in %i", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size, end_state);\r
1300 #endif\r
1301                                 break;\r
1302                         case JTAG_SLEEP:\r
1303                                 if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
1304                                         retval = ERROR_JTAG_QUEUE_FAILED;\r
1305                                 first_unsent = cmd->next;\r
1306                                 jtag_sleep(cmd->cmd.sleep->us);\r
1307 #ifdef _DEBUG_JTAG_IO_                          \r
1308                                 DEBUG("sleep %i usec", cmd->cmd.sleep->us);\r
1309 #endif\r
1310                                 break;\r
1311                         default:\r
1312                                 ERROR("BUG: unknown JTAG command type encountered");\r
1313                                 exit(-1);\r
1314                 }\r
1315                 cmd = cmd->next;\r
1316         }\r
1317 \r
1318         if (require_send > 0)\r
1319                 if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
1320                         retval = ERROR_JTAG_QUEUE_FAILED;\r
1321 \r
1322         return retval;\r
1323 }\r
1324 \r
1325 #if BUILD_FT2232_FTD2XX == 1\r
1326 static int ft2232_init_ftd2xx(u16 vid, u16 pid, int more, int *try_more)\r
1327 {\r
1328         FT_STATUS status;\r
1329         DWORD openex_flags = 0;\r
1330         char *openex_string = NULL;\r
1331         u8 latency_timer;\r
1332 \r
1333         DEBUG("'ft2232' interface using FTD2XX with '%s' layout (%4.4x:%4.4x)",\r
1334             ft2232_layout, vid, pid);\r
1335 \r
1336 #if IS_WIN32 == 0\r
1337         /* Add non-standard Vid/Pid to the linux driver */\r
1338         if ((status = FT_SetVIDPID(vid, pid)) != FT_OK)\r
1339         {\r
1340                 WARNING("couldn't add %4.4x:%4.4x",\r
1341                     vid, pid);\r
1342         }\r
1343 #endif\r
1344 \r
1345         if (ft2232_device_desc && ft2232_serial)\r
1346         {\r
1347                 WARNING("can't open by device description and serial number, giving precedence to serial");\r
1348                 ft2232_device_desc = NULL;\r
1349         }\r
1350         \r
1351         if (ft2232_device_desc)\r
1352         {\r
1353                 openex_string = ft2232_device_desc;\r
1354                 openex_flags = FT_OPEN_BY_DESCRIPTION;\r
1355         }\r
1356         else if (ft2232_serial)\r
1357         {\r
1358                 openex_string = ft2232_serial;\r
1359                 openex_flags = FT_OPEN_BY_SERIAL_NUMBER;\r
1360         }\r
1361         else\r
1362         {\r
1363                 ERROR("neither device description nor serial number specified");\r
1364                 ERROR("please add \"ft2232_device_desc <string>\" or \"ft2232_serial <string>\" to your .cfg file");\r
1365                 \r
1366                 return ERROR_JTAG_INIT_FAILED;  \r
1367         }\r
1368 \r
1369         if ((status = FT_OpenEx(openex_string, openex_flags, &ftdih)) != FT_OK)\r
1370         {\r
1371                 DWORD num_devices;\r
1372                 \r
1373                 if (more) {\r
1374                         WARNING("unable to open ftdi device (trying more): %lu",\r
1375                             status);\r
1376                         *try_more = 1;\r
1377                         return ERROR_JTAG_INIT_FAILED;\r
1378                 }\r
1379                 ERROR("unable to open ftdi device: %lu", status);\r
1380                 status = FT_ListDevices(&num_devices, NULL, FT_LIST_NUMBER_ONLY);\r
1381                 if (status == FT_OK)\r
1382                 {\r
1383                         char **desc_array = malloc(sizeof(char*) * (num_devices + 1));\r
1384                         int i;\r
1385 \r
1386                         for (i = 0; i < num_devices; i++)\r
1387                                 desc_array[i] = malloc(64);\r
1388                         desc_array[num_devices] = NULL;\r
1389 \r
1390                         status = FT_ListDevices(desc_array, &num_devices, FT_LIST_ALL | openex_flags);\r
1391 \r
1392                         if (status == FT_OK)\r
1393                         {\r
1394                                 ERROR("ListDevices: %lu\n", num_devices);\r
1395                                 for (i = 0; i < num_devices; i++)\r
1396                                         ERROR("%i: %s", i, desc_array[i]);\r
1397                         }\r
1398                         \r
1399                         for (i = 0; i < num_devices; i++)\r
1400                                 free(desc_array[i]);\r
1401                         free(desc_array);\r
1402                 }\r
1403                 else\r
1404                 {\r
1405                         ERROR("ListDevices: NONE\n");\r
1406                 }\r
1407                 return ERROR_JTAG_INIT_FAILED;\r
1408         }\r
1409 \r
1410         if ((status = FT_SetLatencyTimer(ftdih, ft2232_latency)) != FT_OK)\r
1411         {\r
1412                 ERROR("unable to set latency timer: %lu", status);\r
1413                 return ERROR_JTAG_INIT_FAILED;\r
1414         }\r
1415         \r
1416         if ((status = FT_GetLatencyTimer(ftdih, &latency_timer)) != FT_OK)\r
1417         {\r
1418                 ERROR("unable to get latency timer: %lu", status);\r
1419                 return ERROR_JTAG_INIT_FAILED;\r
1420         }\r
1421         else\r
1422         {\r
1423                 DEBUG("current latency timer: %i", latency_timer);\r
1424         }\r
1425         \r
1426         if ((status = FT_SetTimeouts(ftdih, 5000, 5000)) != FT_OK)\r
1427         {\r
1428                 ERROR("unable to set timeouts: %lu", status);\r
1429                 return ERROR_JTAG_INIT_FAILED;\r
1430         }\r
1431 \r
1432         if ((status = FT_SetBitMode(ftdih, 0x0b, 2)) != FT_OK)\r
1433         {\r
1434                 ERROR("unable to enable bit i/o mode: %lu", status);\r
1435                 return ERROR_JTAG_INIT_FAILED;\r
1436         }\r
1437 \r
1438         return ERROR_OK;\r
1439 }\r
1440 \r
1441 static int ft2232_purge_ftd2xx(void)\r
1442 {\r
1443         FT_STATUS status;\r
1444 \r
1445         if ((status = FT_Purge(ftdih, FT_PURGE_RX | FT_PURGE_TX)) != FT_OK)\r
1446         {\r
1447                 ERROR("error purging ftd2xx device: %lu", status);\r
1448                 return ERROR_JTAG_INIT_FAILED;\r
1449         }\r
1450 \r
1451         return ERROR_OK;\r
1452 }\r
1453 #endif /* BUILD_FT2232_FTD2XX == 1 */\r
1454 \r
1455 #if BUILD_FT2232_LIBFTDI == 1\r
1456 static int ft2232_init_libftdi(u16 vid, u16 pid, int more, int *try_more)\r
1457 {\r
1458         u8 latency_timer;\r
1459 \r
1460         DEBUG("'ft2232' interface using libftdi with '%s' layout (%4.4x:%4.4x)",\r
1461             ft2232_layout, vid, pid);\r
1462 \r
1463         if (ftdi_init(&ftdic) < 0)\r
1464                 return ERROR_JTAG_INIT_FAILED;\r
1465 \r
1466         /* context, vendor id, product id */\r
1467         if (ftdi_usb_open_desc(&ftdic, vid, pid, ft2232_device_desc,\r
1468             ft2232_serial) < 0) {\r
1469                 if (more)\r
1470                         WARNING("unable to open ftdi device (trying more): %s",\r
1471                              ftdic.error_str);\r
1472                 else\r
1473                         ERROR("unable to open ftdi device: %s", ftdic.error_str);\r
1474                 *try_more = 1;\r
1475                 return ERROR_JTAG_INIT_FAILED;\r
1476         }\r
1477 \r
1478         if (ftdi_set_interface(&ftdic, INTERFACE_A) < 0)\r
1479         {\r
1480                 ERROR("unable to select FT2232 channel A: %s", ftdic.error_str);\r
1481                 return ERROR_JTAG_INIT_FAILED;\r
1482         }\r
1483 \r
1484         if (ftdi_usb_reset(&ftdic) < 0)\r
1485         {\r
1486                 ERROR("unable to reset ftdi device");\r
1487                 return ERROR_JTAG_INIT_FAILED;\r
1488         }\r
1489 \r
1490         if (ftdi_set_latency_timer(&ftdic, ft2232_latency) < 0)\r
1491         {\r
1492                 ERROR("unable to set latency timer");\r
1493                 return ERROR_JTAG_INIT_FAILED;\r
1494         }\r
1495         \r
1496         if (ftdi_get_latency_timer(&ftdic, &latency_timer) < 0)\r
1497         {\r
1498                 ERROR("unable to get latency timer");\r
1499                 return ERROR_JTAG_INIT_FAILED;\r
1500         }\r
1501         else\r
1502         {\r
1503                 DEBUG("current latency timer: %i", latency_timer);\r
1504         }\r
1505 \r
1506         ftdi_set_bitmode(&ftdic, 0x0b, 2); /* ctx, JTAG I/O mask */\r
1507 \r
1508         return ERROR_OK;\r
1509 }\r
1510 \r
1511 static int ft2232_purge_libftdi(void)\r
1512 {\r
1513         if (ftdi_usb_purge_buffers(&ftdic) < 0)\r
1514         {\r
1515                 ERROR("ftdi_purge_buffers: %s", ftdic.error_str);\r
1516                 return ERROR_JTAG_INIT_FAILED;\r
1517         }\r
1518 \r
1519         return ERROR_OK;\r
1520 }\r
1521 #endif /* BUILD_FT2232_LIBFTDI == 1 */\r
1522 \r
1523 int ft2232_init(void)\r
1524 {\r
1525         u8 buf[1];\r
1526         int retval;\r
1527         u32 bytes_written;\r
1528         ft2232_layout_t *cur_layout = ft2232_layouts;\r
1529         int i;\r
1530         \r
1531         if ((ft2232_layout == NULL) || (ft2232_layout[0] == 0))\r
1532         {\r
1533                 ft2232_layout = "usbjtag";\r
1534                 WARNING("No ft2232 layout specified, using default 'usbjtag'");\r
1535         }\r
1536         \r
1537         while (cur_layout->name)\r
1538         {\r
1539                 if (strcmp(cur_layout->name, ft2232_layout) == 0)\r
1540                 {\r
1541                         layout = cur_layout;\r
1542                         break;\r
1543                 }\r
1544                 cur_layout++;\r
1545         }\r
1546 \r
1547         if (!layout)\r
1548         {\r
1549                 ERROR("No matching layout found for %s", ft2232_layout);\r
1550                 return ERROR_JTAG_INIT_FAILED;\r
1551         }\r
1552         \r
1553         for (i = 0; 1; i++) {\r
1554                 /*\r
1555                  * "more indicates that there are more IDs to try, so we should\r
1556                  * not print an error for an ID mismatch (but for anything\r
1557                  * else, we should).\r
1558                  *\r
1559                  * try_more indicates that the error code returned indicates an\r
1560                  * ID mismatch (and nothing else) and that we should proceeed\r
1561                  * with the next ID pair.\r
1562                  */\r
1563                 int more = ft2232_vid[i+1] || ft2232_pid[i+1];\r
1564                 int try_more = 0;\r
1565 \r
1566 #if BUILD_FT2232_FTD2XX == 1\r
1567                 retval = ft2232_init_ftd2xx(ft2232_vid[i], ft2232_pid[i],\r
1568                     more, &try_more);\r
1569 #elif BUILD_FT2232_LIBFTDI == 1\r
1570                 retval = ft2232_init_libftdi(ft2232_vid[i], ft2232_pid[i],\r
1571                     more, &try_more);\r
1572 #endif  \r
1573                 if (retval >= 0)\r
1574                         break;\r
1575                 if (!more || !try_more)\r
1576                         return retval;\r
1577         }\r
1578 \r
1579         ft2232_buffer_size = 0;\r
1580         ft2232_buffer = malloc(FT2232_BUFFER_SIZE);\r
1581 \r
1582         if (layout->init() != ERROR_OK)\r
1583                 return ERROR_JTAG_INIT_FAILED;\r
1584 \r
1585         ft2232_speed(jtag_speed);\r
1586 \r
1587         buf[0] = 0x85; /* Disconnect TDI/DO to TDO/DI for Loopback */\r
1588         if (((retval = ft2232_write(buf, 1, &bytes_written)) != ERROR_OK) || (bytes_written != 1))\r
1589         {\r
1590                 ERROR("couldn't write to FT2232 to disable loopback");\r
1591                 return ERROR_JTAG_INIT_FAILED;\r
1592         }\r
1593 \r
1594 #if BUILD_FT2232_FTD2XX == 1\r
1595         return ft2232_purge_ftd2xx();\r
1596 #elif BUILD_FT2232_LIBFTDI == 1\r
1597         return ft2232_purge_libftdi();\r
1598 #endif  \r
1599 \r
1600         return ERROR_OK;\r
1601 }\r
1602 \r
1603 int usbjtag_init(void)\r
1604 {\r
1605         u8 buf[3];\r
1606         u32 bytes_written;\r
1607         \r
1608         low_output = 0x08;\r
1609         low_direction = 0x0b;\r
1610         \r
1611         if (strcmp(ft2232_layout, "usbjtag") == 0)\r
1612         {\r
1613                 nTRST = 0x10;\r
1614                 nTRSTnOE = 0x10;\r
1615                 nSRST = 0x40;\r
1616                 nSRSTnOE = 0x40;\r
1617         }\r
1618         else if (strcmp(ft2232_layout, "signalyzer") == 0)\r
1619         {\r
1620                 nTRST = 0x10;\r
1621                 nTRSTnOE = 0x10;\r
1622                 nSRST = 0x20;\r
1623                 nSRSTnOE = 0x20;\r
1624         }\r
1625         else if (strcmp(ft2232_layout, "evb_lm3s811") == 0)\r
1626         {\r
1627                 nTRST = 0x0;\r
1628                 nTRSTnOE = 0x00;\r
1629                 nSRST = 0x20;\r
1630                 nSRSTnOE = 0x20;\r
1631                 low_output = 0x88;\r
1632                 low_direction = 0x8b;\r
1633         }\r
1634         else\r
1635         {\r
1636                 ERROR("BUG: usbjtag_init called for unknown layout '%s'", ft2232_layout);\r
1637                 return ERROR_JTAG_INIT_FAILED;  \r
1638         }\r
1639         \r
1640         if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
1641         {\r
1642                 low_direction &= ~nTRSTnOE; /* nTRST input */\r
1643                 low_output &= ~nTRST; /* nTRST = 0 */\r
1644         }\r
1645         else\r
1646         {\r
1647                 low_direction |= nTRSTnOE; /* nTRST output */\r
1648                 low_output |= nTRST; /* nTRST = 1 */\r
1649         }\r
1650         \r
1651         if (jtag_reset_config & RESET_SRST_PUSH_PULL)\r
1652         {\r
1653                 low_direction |= nSRSTnOE; /* nSRST output */\r
1654                 low_output |= nSRST; /* nSRST = 1 */\r
1655         }\r
1656         else\r
1657         {\r
1658                 low_direction &= ~nSRSTnOE; /* nSRST input */\r
1659                 low_output &= ~nSRST; /* nSRST = 0 */\r
1660         }\r
1661         \r
1662         /* initialize low byte for jtag */\r
1663         buf[0] = 0x80; /* command "set data bits low byte" */\r
1664         buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, xRST high) */\r
1665         buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in */\r
1666         DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
1667         \r
1668         if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
1669         {\r
1670                 ERROR("couldn't initialize FT2232 with 'USBJTAG' layout"); \r
1671                 return ERROR_JTAG_INIT_FAILED;\r
1672         }\r
1673 \r
1674         return ERROR_OK;\r
1675 }\r
1676 \r
1677 int jtagkey_init(void)\r
1678 {\r
1679         u8 buf[3];\r
1680         u32 bytes_written;\r
1681         \r
1682         low_output = 0x08;\r
1683         low_direction = 0x1b;\r
1684         \r
1685         /* initialize low byte for jtag */\r
1686         buf[0] = 0x80; /* command "set data bits low byte" */\r
1687         buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */\r
1688         buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */\r
1689         DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
1690         \r
1691         if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
1692         {\r
1693                 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); \r
1694                 return ERROR_JTAG_INIT_FAILED;\r
1695         }\r
1696         \r
1697         if (strcmp(layout->name, "jtagkey") == 0)\r
1698         {\r
1699                 nTRST = 0x01;\r
1700                 nTRSTnOE = 0x4;\r
1701                 nSRST = 0x02;\r
1702                 nSRSTnOE = 0x08;\r
1703         }\r
1704         else if ((strcmp(layout->name, "jtagkey_prototype_v1") == 0) ||\r
1705                 (strcmp(layout->name, "oocdlink") == 0))\r
1706         {\r
1707                 nTRST = 0x02;\r
1708                 nTRSTnOE = 0x1;\r
1709                 nSRST = 0x08;\r
1710                 nSRSTnOE = 0x04;\r
1711         }\r
1712         else\r
1713         {\r
1714                 ERROR("BUG: jtagkey_init called for non jtagkey layout");\r
1715                 exit(-1);\r
1716         }\r
1717         \r
1718         high_output = 0x0;\r
1719         high_direction = 0x0f;\r
1720 \r
1721         if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
1722         {\r
1723                 high_output |= nTRSTnOE;\r
1724                 high_output &= ~nTRST;\r
1725         }\r
1726         else\r
1727         {\r
1728                 high_output &= ~nTRSTnOE;\r
1729                 high_output |= nTRST;\r
1730         }\r
1731         \r
1732         if (jtag_reset_config & RESET_SRST_PUSH_PULL)\r
1733         {\r
1734                 high_output &= ~nSRSTnOE;\r
1735                 high_output |= nSRST;\r
1736         }\r
1737         else\r
1738         {\r
1739                 high_output |= nSRSTnOE;\r
1740                 high_output &= ~nSRST;\r
1741         }\r
1742         \r
1743         /* initialize high port */\r
1744         buf[0] = 0x82; /* command "set data bits high byte" */\r
1745         buf[1] = high_output; /* value */\r
1746         buf[2] = high_direction;   /* all outputs (xRST and xRSTnOE) */\r
1747         DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
1748         \r
1749         if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
1750         {\r
1751                 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); \r
1752                 return ERROR_JTAG_INIT_FAILED;\r
1753         }\r
1754         \r
1755         return ERROR_OK;\r
1756 }\r
1757 \r
1758 int olimex_jtag_init(void)\r
1759 {\r
1760         u8 buf[3];\r
1761         u32 bytes_written;\r
1762         \r
1763         low_output = 0x08;\r
1764         low_direction = 0x1b;\r
1765         \r
1766         /* initialize low byte for jtag */\r
1767         buf[0] = 0x80; /* command "set data bits low byte" */\r
1768         buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */\r
1769         buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */\r
1770         DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
1771         \r
1772         if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
1773         {\r
1774                 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); \r
1775                 return ERROR_JTAG_INIT_FAILED;\r
1776         }\r
1777         \r
1778         nTRST = 0x01;\r
1779         nTRSTnOE = 0x4;\r
1780         nSRST = 0x02;\r
1781         nSRSTnOE = 0x00; /* no output enable for nSRST */\r
1782 \r
1783         high_output = 0x0;\r
1784         high_direction = 0x0f;\r
1785 \r
1786         if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
1787         {\r
1788                 high_output |= nTRSTnOE;\r
1789                 high_output &= ~nTRST;\r
1790         }\r
1791         else\r
1792         {\r
1793                 high_output &= ~nTRSTnOE;\r
1794                 high_output |= nTRST;\r
1795         }\r
1796         \r
1797         if (jtag_reset_config & RESET_SRST_PUSH_PULL)\r
1798         {\r
1799                 ERROR("can't set nSRST to push-pull on the Olimex ARM-USB-OCD");\r
1800         }\r
1801         else\r
1802         {\r
1803                 high_output &= ~nSRST;\r
1804         }\r
1805         \r
1806         /* turn red LED on */\r
1807         high_output |= 0x08;\r
1808         \r
1809         /* initialize high port */\r
1810         buf[0] = 0x82; /* command "set data bits high byte" */\r
1811         buf[1] = high_output; /* value */\r
1812         buf[2] = high_direction;   /* all outputs (xRST and xRSTnOE) */\r
1813         DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
1814         \r
1815         if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
1816         {\r
1817                 ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); \r
1818                 return ERROR_JTAG_INIT_FAILED;\r
1819         }\r
1820         \r
1821         return ERROR_OK;\r
1822 }\r
1823 \r
1824 int flyswatter_init(void)\r
1825 {\r
1826         u8 buf[3];\r
1827         u32 bytes_written;\r
1828         \r
1829         low_output = 0x18;\r
1830         low_direction = 0xfb;\r
1831         \r
1832         /* initialize low byte for jtag */\r
1833         buf[0] = 0x80; /* command "set data bits low byte" */\r
1834         buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */\r
1835         buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE[12]=out, n[ST]srst=out */\r
1836         DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
1837         \r
1838         if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
1839         {\r
1840                 ERROR("couldn't initialize FT2232 with 'flyswatter' layout"); \r
1841                 return ERROR_JTAG_INIT_FAILED;\r
1842         }\r
1843         \r
1844         nTRST = 0x10;\r
1845         nTRSTnOE = 0x0; /* not output enable for nTRST */\r
1846         nSRST = 0x20;\r
1847         nSRSTnOE = 0x00; /* no output enable for nSRST */\r
1848 \r
1849         high_output = 0x00;\r
1850         high_direction = 0x0c;\r
1851 \r
1852         /* turn red LED1 on, LED2 off */\r
1853         high_output |= 0x08;\r
1854         \r
1855         /* initialize high port */\r
1856         buf[0] = 0x82; /* command "set data bits high byte" */\r
1857         buf[1] = high_output; /* value */\r
1858         buf[2] = high_direction;   /* all outputs (xRST and xRSTnOE) */\r
1859         DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
1860         \r
1861         if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
1862         {\r
1863                 ERROR("couldn't initialize FT2232 with 'flyswatter' layout"); \r
1864                 return ERROR_JTAG_INIT_FAILED;\r
1865         }\r
1866         \r
1867         return ERROR_OK;\r
1868 }\r
1869 \r
1870 int turtle_init(void)\r
1871 {\r
1872         u8 buf[3];\r
1873         u32 bytes_written;\r
1874         \r
1875         low_output = 0x08;\r
1876         low_direction = 0x5b;\r
1877         \r
1878         /* initialize low byte for jtag */\r
1879         buf[0] = 0x80; /* command "set data bits low byte" */\r
1880         buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */\r
1881         buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */\r
1882         DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
1883         \r
1884         if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
1885         {\r
1886                 ERROR("couldn't initialize FT2232 with 'turtelizer2' layout"); \r
1887                 return ERROR_JTAG_INIT_FAILED;\r
1888         }\r
1889         \r
1890         nSRST = 0x40;\r
1891         \r
1892         high_output = 0x00;\r
1893         high_direction = 0x0C;\r
1894         \r
1895         /* initialize high port */\r
1896         buf[0] = 0x82; /* command "set data bits high byte" */\r
1897         buf[1] = high_output;\r
1898         buf[2] = high_direction;\r
1899         DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
1900         \r
1901         if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
1902         {\r
1903                 ERROR("couldn't initialize FT2232 with 'turtelizer2' layout"); \r
1904                 return ERROR_JTAG_INIT_FAILED;\r
1905         }\r
1906         \r
1907         return ERROR_OK;\r
1908 }\r
1909 \r
1910 int comstick_init(void)\r
1911 {\r
1912         u8 buf[3];\r
1913         u32 bytes_written;\r
1914         \r
1915         low_output = 0x08;\r
1916         low_direction = 0x0b;\r
1917         \r
1918         /* initialize low byte for jtag */\r
1919         buf[0] = 0x80; /* command "set data bits low byte" */\r
1920         buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */\r
1921         buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */\r
1922         DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
1923         \r
1924         if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
1925         {\r
1926                 ERROR("couldn't initialize FT2232 with 'comstick' layout"); \r
1927                 return ERROR_JTAG_INIT_FAILED;\r
1928         }\r
1929         \r
1930         nTRST = 0x01;\r
1931         nTRSTnOE = 0x00; /* no output enable for nTRST */\r
1932         nSRST = 0x02;\r
1933         nSRSTnOE = 0x00; /* no output enable for nSRST */\r
1934         \r
1935         high_output = 0x03;\r
1936         high_direction = 0x03;\r
1937         \r
1938         /* initialize high port */\r
1939         buf[0] = 0x82; /* command "set data bits high byte" */\r
1940         buf[1] = high_output;\r
1941         buf[2] = high_direction;\r
1942         DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
1943         \r
1944         if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
1945         {\r
1946                 ERROR("couldn't initialize FT2232 with 'comstick' layout"); \r
1947                 return ERROR_JTAG_INIT_FAILED;\r
1948         }\r
1949         \r
1950         return ERROR_OK;\r
1951 }\r
1952 \r
1953 int stm32stick_init(void)\r
1954 {\r
1955         u8 buf[3];\r
1956         u32 bytes_written;\r
1957         \r
1958         low_output = 0x88;\r
1959         low_direction = 0x8b;\r
1960         \r
1961         /* initialize low byte for jtag */\r
1962         buf[0] = 0x80; /* command "set data bits low byte" */\r
1963         buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */\r
1964         buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */\r
1965         DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
1966         \r
1967         if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
1968         {\r
1969                 ERROR("couldn't initialize FT2232 with 'stm32stick' layout"); \r
1970                 return ERROR_JTAG_INIT_FAILED;\r
1971         }\r
1972                 \r
1973         nTRST = 0x01;\r
1974         nTRSTnOE = 0x00; /* no output enable for nTRST */\r
1975         nSRST = 0x80;\r
1976         nSRSTnOE = 0x00; /* no output enable for nSRST */\r
1977         \r
1978         high_output = 0x01;\r
1979         high_direction = 0x03;\r
1980         \r
1981         /* initialize high port */\r
1982         buf[0] = 0x82; /* command "set data bits high byte" */\r
1983         buf[1] = high_output;\r
1984         buf[2] = high_direction;\r
1985         DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
1986         \r
1987         if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
1988         {\r
1989                 ERROR("couldn't initialize FT2232 with 'stm32stick' layout"); \r
1990                 return ERROR_JTAG_INIT_FAILED;\r
1991         }\r
1992         \r
1993         return ERROR_OK;\r
1994 }\r
1995 \r
1996 void olimex_jtag_blink(void)\r
1997 {\r
1998         /* Olimex ARM-USB-OCD has a LED connected to ACBUS3\r
1999          * ACBUS3 is bit 3 of the GPIOH port\r
2000          */\r
2001         if (high_output & 0x08)\r
2002         {\r
2003                 /* set port pin high */\r
2004                 high_output &= 0x07;\r
2005         }\r
2006         else\r
2007         {\r
2008                 /* set port pin low */\r
2009                 high_output |= 0x08;\r
2010         }\r
2011         \r
2012         BUFFER_ADD = 0x82;\r
2013         BUFFER_ADD = high_output;\r
2014         BUFFER_ADD = high_direction;\r
2015 }\r
2016 \r
2017 void turtle_jtag_blink(void)\r
2018 {\r
2019         /* \r
2020    * Turtelizer2 has two LEDs connected to ACBUS2 and ACBUS3\r
2021          */\r
2022         if (high_output & 0x08)\r
2023         {\r
2024                 high_output = 0x04;\r
2025         }\r
2026         else\r
2027         {\r
2028                 high_output = 0x08;\r
2029         }\r
2030         \r
2031         BUFFER_ADD = 0x82;\r
2032         BUFFER_ADD = high_output;\r
2033         BUFFER_ADD = high_direction;\r
2034 }\r
2035 \r
2036 \r
2037 int ft2232_quit(void)\r
2038 {\r
2039 #if BUILD_FT2232_FTD2XX == 1\r
2040         FT_STATUS status;\r
2041 \r
2042         status = FT_Close(ftdih);\r
2043 #elif BUILD_FT2232_LIBFTDI == 1\r
2044         ftdi_disable_bitbang(&ftdic);\r
2045         \r
2046         ftdi_usb_close(&ftdic);\r
2047         \r
2048         ftdi_deinit(&ftdic);\r
2049 #endif\r
2050 \r
2051         free(ft2232_buffer);\r
2052         ft2232_buffer = NULL;\r
2053 \r
2054         return ERROR_OK;\r
2055 }\r
2056 \r
2057 int ft2232_handle_device_desc_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
2058 {\r
2059         if (argc == 1)\r
2060         {\r
2061                 ft2232_device_desc = strdup(args[0]);\r
2062         }\r
2063         else\r
2064         {\r
2065                 ERROR("expected exactly one argument to ft2232_device_desc <description>");\r
2066         }\r
2067         \r
2068         return ERROR_OK;\r
2069 }\r
2070 \r
2071 int ft2232_handle_serial_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
2072 {\r
2073         if (argc == 1)\r
2074         {\r
2075                 ft2232_serial = strdup(args[0]);\r
2076         }\r
2077         else\r
2078         {\r
2079                 ERROR("expected exactly one argument to ft2232_serial <serial-number>");\r
2080         }\r
2081         \r
2082         return ERROR_OK;\r
2083 }\r
2084 \r
2085 int ft2232_handle_layout_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
2086 {\r
2087         if (argc == 0)\r
2088                 return ERROR_OK;\r
2089 \r
2090         ft2232_layout = malloc(strlen(args[0]) + 1);\r
2091         strcpy(ft2232_layout, args[0]);\r
2092 \r
2093         return ERROR_OK;\r
2094 }\r
2095 \r
2096 int ft2232_handle_vid_pid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
2097 {\r
2098         int i;\r
2099 \r
2100         if (argc > MAX_USB_IDS*2) {\r
2101                 WARNING("ignoring extra IDs in ft2232_vid_pid "\r
2102                     "(maximum is %d pairs)", MAX_USB_IDS);\r
2103                 argc = MAX_USB_IDS*2;\r
2104         }\r
2105         if (argc < 2 || (argc & 1))\r
2106         {\r
2107                 WARNING("incomplete ft2232_vid_pid configuration directive");\r
2108                 if (argc < 2)\r
2109                         return ERROR_OK;\r
2110         }\r
2111 \r
2112         for (i = 0; i+1 < argc; i += 2) {\r
2113                 ft2232_vid[i >> 1] = strtol(args[i], NULL, 0);\r
2114                 ft2232_pid[i >> 1] = strtol(args[i+1], NULL, 0);\r
2115         }\r
2116         /*\r
2117          * Explicitly terminate, in case there are multiples instances of\r
2118          * ft2232_vid_pid.\r
2119          */\r
2120         ft2232_vid[i >> 1] = ft2232_pid[i >> 1] = 0;\r
2121 \r
2122         return ERROR_OK;\r
2123 }\r
2124 \r
2125 int ft2232_handle_latency_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
2126 {\r
2127         if (argc == 1)\r
2128         {\r
2129                 ft2232_latency = atoi(args[0]);\r
2130         }\r
2131         else\r
2132         {\r
2133                 ERROR("expected exactly one argument to ft2232_latency <ms>");\r
2134         }\r
2135         \r
2136         return ERROR_OK;\r
2137 }\r
2138 \r
2139 \r