command_handler_t: make argc unsigned
[openocd.git] / src / jtag / ft2232.c
index cf3fc01261a465164e7c14971ff0c6268726585d..39036bcb9e6a51aba169daba0bb2d3681a5c09fc 100644 (file)
 /* this speed value tells that RTCK is requested */
 #define RTCK_SPEED -1
 
+/*
+ * On my Athlon XP 1900+ EHCI host with FT2232H JTAG dongle I get read timeout
+ * errors with a retry count of 100. Increasing it solves the problem for me.
+ *     - Dimitar
+ *
+ * FIXME There's likely an issue with the usb_read_timeout from libftdi.
+ * Fix that (libusb? kernel? libftdi? here?) and restore the retry count
+ * to something sane.
+ */
+#define LIBFTDI_READ_RETRY_COUNT               2000
+
 #ifndef BUILD_FT2232_HIGHSPEED
  #if BUILD_FT2232_FTD2XX == 1
        enum { FT_DEVICE_2232H = 6, FT_DEVICE_4232H };
  #endif
 #endif
 
-static int ft2232_execute_queue(void);
-static int ft2232_speed(int speed);
-static int ft2232_speed_div(int speed, int* khz);
-static int ft2232_khz(int khz, int* jtag_speed);
-static int ft2232_register_commands(struct command_context_s* cmd_ctx);
-static int ft2232_init(void);
-static int ft2232_quit(void);
-
-static int ft2232_handle_device_desc_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
-static int ft2232_handle_serial_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
-static int ft2232_handle_layout_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
-static int ft2232_handle_vid_pid_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
-static int ft2232_handle_latency_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
-
 /**
  * Send out \a num_cycles on the TCK line while the TAP(s) are in a
  * stable state.  Calling code must ensure that current state is stable,
@@ -138,6 +135,7 @@ static int sheevaplug_init(void);
 static int icebear_jtag_init(void);
 static int cortino_jtag_init(void);
 static int signalyzer_h_init(void);
+static int ktlink_init(void);
 
 /* reset procedures for supported layouts */
 static void usbjtag_reset(int trst, int srst);
@@ -151,12 +149,14 @@ static void axm0432_jtag_reset(int trst, int srst);
 static void sheevaplug_reset(int trst, int srst);
 static void icebear_jtag_reset(int trst, int srst);
 static void signalyzer_h_reset(int trst, int srst);
+static void ktlink_reset(int trst, int srst);
 
 /* blink procedures for layouts that support a blinking led */
 static void olimex_jtag_blink(void);
 static void flyswatter_jtag_blink(void);
 static void turtle_jtag_blink(void);
 static void signalyzer_h_blink(void);
+static void ktlink_blink(void);
 
 static const ft2232_layout_t  ft2232_layouts[] =
 {
@@ -177,6 +177,7 @@ static const ft2232_layout_t  ft2232_layouts[] =
        { "icebear",              icebear_jtag_init,         icebear_jtag_reset, NULL                    },
        { "cortino",              cortino_jtag_init,         comstick_reset, NULL                        },
        { "signalyzer-h",         signalyzer_h_init,         signalyzer_h_reset, signalyzer_h_blink      },
+       { "ktlink",               ktlink_init,               ktlink_reset,       ktlink_blink            },
        { NULL,                   NULL,                      NULL,               NULL                    },
 };
 
@@ -334,18 +335,6 @@ static void move_to_state(tap_state_t goal_state)
        clock_tms(0x4b,  tms_bits, tms_count, 0);
 }
 
-jtag_interface_t ft2232_interface =
-{
-       .name                   = "ft2232",
-       .execute_queue          = ft2232_execute_queue,
-       .speed                  = ft2232_speed,
-       .speed_div              = ft2232_speed_div,
-       .khz                    = ft2232_khz,
-       .register_commands      = ft2232_register_commands,
-       .init                   = ft2232_init,
-       .quit                   = ft2232_quit,
-};
-
 static int ft2232_write(uint8_t* buf, int size, uint32_t* bytes_written)
 {
 #if BUILD_FT2232_FTD2XX == 1
@@ -400,7 +389,7 @@ static int ft2232_read(uint8_t* buf, uint32_t size, uint32_t* bytes_read)
 
 #elif BUILD_FT2232_LIBFTDI == 1
        int retval;
-       int timeout = 100;
+       int timeout = LIBFTDI_READ_RETRY_COUNT;
        *bytes_read = 0;
 
        while ((*bytes_read < size) && timeout--)
@@ -418,9 +407,10 @@ static int ft2232_read(uint8_t* buf, uint32_t size, uint32_t* bytes_read)
 
        if (*bytes_read < size)
        {
-               LOG_ERROR("couldn't read the requested number of bytes from FT2232 device (%i < %i)",
-                         (unsigned int)(*bytes_read),
-                         (unsigned int)size);
+               LOG_ERROR("couldn't read enough bytes from "
+                               "FT2232 device (%i < %i)",
+                               (unsigned)*bytes_read,
+                               (unsigned)size);
                return ERROR_JTAG_DEVICE_ERROR;
        }
 
@@ -574,21 +564,6 @@ static int ft2232_khz(int khz, int* jtag_speed)
        return ERROR_OK;
 }
 
-static int ft2232_register_commands(struct command_context_s* cmd_ctx)
-{
-       register_command(cmd_ctx, NULL, "ft2232_device_desc", ft2232_handle_device_desc_command,
-                       COMMAND_CONFIG, "the USB device description of the FTDI FT2232 device");
-       register_command(cmd_ctx, NULL, "ft2232_serial", ft2232_handle_serial_command,
-                       COMMAND_CONFIG, "the serial number of the FTDI FT2232 device");
-       register_command(cmd_ctx, NULL, "ft2232_layout", ft2232_handle_layout_command,
-                       COMMAND_CONFIG, "the layout of the FT2232 GPIO signals used to control output-enables and reset signals");
-       register_command(cmd_ctx, NULL, "ft2232_vid_pid", ft2232_handle_vid_pid_command,
-                       COMMAND_CONFIG, "the vendor ID and product ID of the FTDI FT2232 device");
-       register_command(cmd_ctx, NULL, "ft2232_latency", ft2232_handle_latency_command,
-                       COMMAND_CONFIG, "set the FT2232 latency timer to a new value");
-       return ERROR_OK;
-}
-
 static void ft2232_end_state(tap_state_t state)
 {
        if (tap_is_state_stable(state))
@@ -679,7 +654,8 @@ static int ft2232_send_and_recv(jtag_command_t* first, jtag_command_t* last)
 
        if (ft2232_expect_read)
        {
-               int timeout = 100;
+               /* FIXME this "timeout" is never changed ... */
+               int timeout = LIBFTDI_READ_RETRY_COUNT;
                ft2232_buffer_size = 0;
 
 #ifdef _DEBUG_USB_IO_
@@ -709,16 +685,21 @@ static int ft2232_send_and_recv(jtag_command_t* first, jtag_command_t* last)
 
                if (ft2232_expect_read != ft2232_buffer_size)
                {
-                       LOG_ERROR("ft2232_expect_read (%i) != ft2232_buffer_size (%i) (%i retries)", ft2232_expect_read,
+                       LOG_ERROR("ft2232_expect_read (%i) != "
+                                       "ft2232_buffer_size (%i) "
+                                       "(%i retries)",
+                                       ft2232_expect_read,
                                        ft2232_buffer_size,
-                                       100 - timeout);
+                                       LIBFTDI_READ_RETRY_COUNT - timeout);
                        ft2232_debug_dump_buffer();
 
                        exit(-1);
                }
 
 #ifdef _DEBUG_USB_COMMS_
-               LOG_DEBUG("read buffer (%i retries): %i bytes", 100 - timeout, ft2232_buffer_size);
+               LOG_DEBUG("read buffer (%i retries): %i bytes",
+                               LIBFTDI_READ_RETRY_COUNT - timeout,
+                               ft2232_buffer_size);
                ft2232_debug_dump_buffer();
 #endif
        }
@@ -1782,7 +1763,7 @@ static int ft2232_execute_command(jtag_command_t *cmd)
        return retval;
 }
 
-static int ft2232_execute_queue()
+static int ft2232_execute_queue(void)
 {
        jtag_command_t* cmd = jtag_command_queue;       /* currently processed command */
        int retval;
@@ -2817,7 +2798,7 @@ static int ft2232_quit(void)
        return ERROR_OK;
 }
 
-static int ft2232_handle_device_desc_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
+COMMAND_HANDLER(ft2232_handle_device_desc_command)
 {
        char *cp;
        char buf[200];
@@ -2851,7 +2832,7 @@ static int ft2232_handle_device_desc_command(struct command_context_s* cmd_ctx,
        return ERROR_OK;
 }
 
-static int ft2232_handle_serial_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
+COMMAND_HANDLER(ft2232_handle_serial_command)
 {
        if (argc == 1)
        {
@@ -2865,7 +2846,7 @@ static int ft2232_handle_serial_command(struct command_context_s* cmd_ctx, char*
        return ERROR_OK;
 }
 
-static int ft2232_handle_layout_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
+COMMAND_HANDLER(ft2232_handle_layout_command)
 {
        if (argc == 0)
                return ERROR_OK;
@@ -2876,7 +2857,7 @@ static int ft2232_handle_layout_command(struct command_context_s* cmd_ctx, char*
        return ERROR_OK;
 }
 
-static int ft2232_handle_vid_pid_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
+COMMAND_HANDLER(ft2232_handle_vid_pid_command)
 {
        if (argc > MAX_USB_IDS * 2)
        {
@@ -2893,16 +2874,11 @@ static int ft2232_handle_vid_pid_command(struct command_context_s* cmd_ctx, char
                argc -= 1;
        }
 
-       int i;
-       int retval = ERROR_OK;
+       unsigned i;
        for (i = 0; i < argc; i += 2)
        {
-               retval = parse_u16(args[i], &ft2232_vid[i >> 1]);
-               if (ERROR_OK != retval)
-                       break;
-               retval = parse_u16(args[i + 1], &ft2232_pid[i >> 1]);
-               if (ERROR_OK != retval)
-                       break;
+               COMMAND_PARSE_NUMBER(u16, args[i], ft2232_vid[i >> 1]);
+               COMMAND_PARSE_NUMBER(u16, args[i + 1], ft2232_pid[i >> 1]);
        }
 
        /*
@@ -2911,10 +2887,10 @@ static int ft2232_handle_vid_pid_command(struct command_context_s* cmd_ctx, char
         */
        ft2232_vid[i >> 1] = ft2232_pid[i >> 1] = 0;
 
-       return retval;
+       return ERROR_OK;
 }
 
-static int ft2232_handle_latency_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
+COMMAND_HANDLER(ft2232_handle_latency_command)
 {
        if (argc == 1)
        {
@@ -3234,7 +3210,7 @@ static int signalyzer_h_init(void)
 
        char *end_of_desc;
 
-       uint16_t read_buf[12];
+       uint16_t read_buf[12] = { 0 };
        uint8_t  buf[3];
        uint32_t bytes_written;
 
@@ -3879,3 +3855,151 @@ static void signalyzer_h_blink(void)
 {
        signalyzer_h_led_set(signalyzer_h_side, SIGNALYZER_LED_RED, 100, 0, 1);
 }
+
+/********************************************************************
+ * Support for KT-LINK
+ * JTAG adapter from KRISTECH
+ * http://www.kristech.eu
+ *******************************************************************/
+static int ktlink_init(void)
+{
+       uint8_t  buf[3];
+       uint32_t bytes_written;
+       uint8_t  swd_en = 0x20; //0x20 SWD disable, 0x00 SWD enable (ADBUS5)
+
+       low_output    = 0x08 | swd_en; // value; TMS=1,TCK=0,TDI=0,SWD=swd_en
+       low_direction = 0x3B;          // out=1; TCK/TDI/TMS=out,TDO=in,SWD=out,RTCK=in,SRSTIN=in
+
+       // initialize low port
+       buf[0] = 0x80;          // command "set data bits low byte"
+       buf[1] = low_output;
+       buf[2] = low_direction;
+       LOG_DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
+
+       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
+       {
+               LOG_ERROR("couldn't initialize FT2232 with 'ktlink' layout");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
+       nTRST    = 0x01;
+       nSRST    = 0x02;
+       nTRSTnOE = 0x04;
+       nSRSTnOE = 0x08;
+
+       high_output    = 0x80; // turn LED on
+       high_direction = 0xFF; // all outputs
+
+       enum reset_types jtag_reset_config = jtag_get_reset_config();
+
+       if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) {
+               high_output |= nTRSTnOE;
+               high_output &= ~nTRST;
+       } else {
+               high_output &= ~nTRSTnOE;
+               high_output |= nTRST;
+       }
+
+       if (jtag_reset_config & RESET_SRST_PUSH_PULL) {
+               high_output &= ~nSRSTnOE;
+               high_output |= nSRST;
+       } else {
+               high_output |= nSRSTnOE;
+               high_output &= ~nSRST;
+       }
+
+       // initialize high port
+       buf[0] = 0x82;              // command "set data bits high byte"
+       buf[1] = high_output;       // value
+       buf[2] = high_direction;
+       LOG_DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
+
+       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
+       {
+               LOG_ERROR("couldn't initialize FT2232 with 'ktlink' layout");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
+       return ERROR_OK;
+}
+
+static void ktlink_reset(int trst, int srst)
+{
+       enum reset_types jtag_reset_config = jtag_get_reset_config();
+
+       if (trst == 1) {
+               if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
+                       high_output &= ~nTRSTnOE;
+               else
+                       high_output &= ~nTRST;
+       } else if (trst == 0) {
+               if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
+                       high_output |= nTRSTnOE;
+               else
+                       high_output |= nTRST;
+       }
+
+       if (srst == 1) {
+               if (jtag_reset_config & RESET_SRST_PUSH_PULL)
+                       high_output &= ~nSRST;
+               else
+                       high_output &= ~nSRSTnOE;
+       } else if (srst == 0) {
+               if (jtag_reset_config & RESET_SRST_PUSH_PULL)
+                       high_output |= nSRST;
+               else
+                       high_output |= nSRSTnOE;
+       }
+
+       buffer_write(0x82); // command "set data bits high byte"
+       buffer_write(high_output);
+       buffer_write(high_direction);
+       LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output,high_direction);
+}
+
+static void ktlink_blink(void)
+{
+       /* LED connected to ACBUS7 */
+       if (high_output & 0x80)
+               high_output &= 0x7F;
+       else
+               high_output |= 0x80;
+
+       buffer_write(0x82);  // command "set data bits high byte"
+       buffer_write(high_output);
+       buffer_write(high_direction);
+}
+
+static int ft2232_register_commands(struct command_context_s* cmd_ctx)
+{
+       register_command(cmd_ctx, NULL, "ft2232_device_desc",
+                       ft2232_handle_device_desc_command, COMMAND_CONFIG,
+                       "the USB device description of the FTDI FT2232 device");
+       register_command(cmd_ctx, NULL, "ft2232_serial",
+                       ft2232_handle_serial_command, COMMAND_CONFIG,
+                       "the serial number of the FTDI FT2232 device");
+       register_command(cmd_ctx, NULL, "ft2232_layout",
+                       ft2232_handle_layout_command, COMMAND_CONFIG,
+                       "the layout of the FT2232 GPIO signals used "
+                       "to control output-enables and reset signals");
+       register_command(cmd_ctx, NULL, "ft2232_vid_pid",
+                       ft2232_handle_vid_pid_command, COMMAND_CONFIG,
+                       "the vendor ID and product ID of the FTDI FT2232 device");
+       register_command(cmd_ctx, NULL, "ft2232_latency",
+                       ft2232_handle_latency_command, COMMAND_CONFIG,
+                       "set the FT2232 latency timer to a new value");
+
+       return ERROR_OK;
+}
+
+
+jtag_interface_t ft2232_interface = {
+               .name = "ft2232",
+               .register_commands = &ft2232_register_commands,
+               .init = &ft2232_init,
+               .quit = &ft2232_quit,
+               .speed = &ft2232_speed,
+               .speed_div = &ft2232_speed_div,
+               .khz = &ft2232_khz,
+               .execute_queue = &ft2232_execute_queue,
+       };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)