X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Fft2232.c;h=4b9bdef7dd5ae789faa4796f38fda6412f19f3ce;hp=82132d3b2d41159eb7974c370ce63a61a74752ff;hb=16b6b5e7a86353dbc0c4823fe3d772c0faca7c1c;hpb=237a707f9653d7ca8a1ec550b497e9a8d0ce0311 diff --git a/src/jtag/drivers/ft2232.c b/src/jtag/drivers/ft2232.c index 82132d3b2d..4b9bdef7dd 100644 --- a/src/jtag/drivers/ft2232.c +++ b/src/jtag/drivers/ft2232.c @@ -32,12 +32,24 @@ * JTAG adapters based on the FT2232 full and high speed USB parts are * popular low cost JTAG debug solutions. Many FT2232 based JTAG adapters * are discrete, but development boards may integrate them as alternatives - * to more capable (and expensive) third party JTAG pods. Since JTAG uses - * only one of the two ports on these devices, on integrated boards the - * second port often serves as a USB-to-serial adapter for the target's - * console UART even when the JTAG port is not in use. (Systems which - * support ARM's SWD in addition to JTAG, or instead of it, may use that - * second port for reading SWV trace data.) + * to more capable (and expensive) third party JTAG pods. + * + * JTAG uses only one of the two communications channels ("MPSSE engines") + * on these devices. Adapters based on FT4232 parts have four ports/channels + * (A/B/C/D), instead of just two (A/B). + * + * Especially on development boards integrating one of these chips (as + * opposed to discrete pods/dongles), the additional channels can be used + * for a variety of purposes, but OpenOCD only uses one channel at a time. + * + * - As a USB-to-serial adapter for the target's console UART ... + * which may be able to support ROM boot loaders that load initial + * firmware images to flash (or SRAM). + * + * - On systems which support ARM's SWD in addition to JTAG, or instead + * of it, that second port can be used for reading SWV/SWO trace data. + * + * - Additional JTAG links, e.g. to a CPLD or * FPGA. * * FT2232 based JTAG adapters are "dumb" not "smart", because most JTAG * request/response interactions involve round trips over the USB link. @@ -69,6 +81,7 @@ /* project specific includes */ #include +#include #include #if IS_CYGWIN == 1 @@ -86,6 +99,17 @@ /* FT2232 access library includes */ #if BUILD_FT2232_FTD2XX == 1 #include +#include "ftd2xx_common.h" + +enum ftdi_interface +{ + INTERFACE_ANY = 0, + INTERFACE_A = 1, + INTERFACE_B = 2, + INTERFACE_C = 3, + INTERFACE_D = 4 +}; + #elif BUILD_FT2232_LIBFTDI == 1 #include #endif @@ -131,7 +155,6 @@ static int ft2232_stableclocks(int num_cycles, struct jtag_command* cmd); static char * ft2232_device_desc_A = NULL; static char* ft2232_device_desc = NULL; static char* ft2232_serial = NULL; -static char* ft2232_layout = NULL; static uint8_t ft2232_latency = 2; static unsigned ft2232_max_tck = FTDI_2232C_MAX_TCK; @@ -145,13 +168,18 @@ struct ft2232_layout { int (*init)(void); void (*reset)(int trst, int srst); void (*blink)(void); + int channel; }; /* init procedures for supported layouts */ static int usbjtag_init(void); static int jtagkey_init(void); +static int lm3s811_jtag_init(void); +static int icdi_jtag_init(void); static int olimex_jtag_init(void); -static int flyswatter_init(void); +static int flyswatter1_init(void); +static int flyswatter2_init(void); +static int minimodule_init(void); static int turtle_init(void); static int comstick_init(void); static int stm32stick_init(void); @@ -159,14 +187,21 @@ static int axm0432_jtag_init(void); static int sheevaplug_init(void); static int icebear_jtag_init(void); static int cortino_jtag_init(void); +static int signalyzer_init(void); static int signalyzer_h_init(void); static int ktlink_init(void); +static int redbee_init(void); +static int lisa_l_init(void); +static int flossjtag_init(void); +static int xds100v2_init(void); /* reset procedures for supported layouts */ -static void usbjtag_reset(int trst, int srst); +static void ftx23_reset(int trst, int srst); static void jtagkey_reset(int trst, int srst); static void olimex_jtag_reset(int trst, int srst); -static void flyswatter_reset(int trst, int srst); +static void flyswatter1_reset(int trst, int srst); +static void flyswatter2_reset(int trst, int srst); +static void minimodule_reset(int trst, int srst); static void turtle_reset(int trst, int srst); static void comstick_reset(int trst, int srst); static void stm32stick_reset(int trst, int srst); @@ -175,43 +210,158 @@ 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); +static void redbee_reset(int trst, int srst); +static void xds100v2_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 flyswatter1_jtag_blink(void); +static void flyswatter2_jtag_blink(void); static void turtle_jtag_blink(void); static void signalyzer_h_blink(void); static void ktlink_blink(void); +static void lisa_l_blink(void); +static void flossjtag_blink(void); + +/* common transport support options */ + +//static const char *jtag_and_swd[] = { "jtag", "swd", NULL }; static const struct ft2232_layout ft2232_layouts[] = { - { "usbjtag", usbjtag_init, usbjtag_reset, NULL }, - { "jtagkey", jtagkey_init, jtagkey_reset, NULL }, - { "jtagkey_prototype_v1", jtagkey_init, jtagkey_reset, NULL }, - { "oocdlink", jtagkey_init, jtagkey_reset, NULL }, - { "signalyzer", usbjtag_init, usbjtag_reset, NULL }, - { "evb_lm3s811", usbjtag_init, usbjtag_reset, NULL }, - { "luminary_icdi", usbjtag_init, usbjtag_reset, NULL }, - { "olimex-jtag", olimex_jtag_init, olimex_jtag_reset, olimex_jtag_blink }, - { "flyswatter", flyswatter_init, flyswatter_reset, flyswatter_jtag_blink }, - { "turtelizer2", turtle_init, turtle_reset, turtle_jtag_blink }, - { "comstick", comstick_init, comstick_reset, NULL }, - { "stm32stick", stm32stick_init, stm32stick_reset, NULL }, - { "axm0432_jtag", axm0432_jtag_init, axm0432_jtag_reset, NULL }, - { "sheevaplug", sheevaplug_init, sheevaplug_reset, NULL }, - { "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 }, + { .name = "usbjtag", + .init = usbjtag_init, + .reset = ftx23_reset, + }, + { .name = "jtagkey", + .init = jtagkey_init, + .reset = jtagkey_reset, + }, + { .name = "jtagkey_prototype_v1", + .init = jtagkey_init, + .reset = jtagkey_reset, + }, + { .name = "oocdlink", + .init = jtagkey_init, + .reset = jtagkey_reset, + }, + { .name = "signalyzer", + .init = signalyzer_init, + .reset = ftx23_reset, + }, + { .name = "evb_lm3s811", + .init = lm3s811_jtag_init, + .reset = ftx23_reset, + }, + { .name = "luminary_icdi", + .init = icdi_jtag_init, + .reset = ftx23_reset, + }, + { .name = "olimex-jtag", + .init = olimex_jtag_init, + .reset = olimex_jtag_reset, + .blink = olimex_jtag_blink + }, + { .name = "flyswatter", + .init = flyswatter1_init, + .reset = flyswatter1_reset, + .blink = flyswatter1_jtag_blink + }, + { .name = "flyswatter2", + .init = flyswatter2_init, + .reset = flyswatter2_reset, + .blink = flyswatter2_jtag_blink + }, + { .name = "minimodule", + .init = minimodule_init, + .reset = minimodule_reset, + }, + { .name = "turtelizer2", + .init = turtle_init, + .reset = turtle_reset, + .blink = turtle_jtag_blink + }, + { .name = "comstick", + .init = comstick_init, + .reset = comstick_reset, + }, + { .name = "stm32stick", + .init = stm32stick_init, + .reset = stm32stick_reset, + }, + { .name = "axm0432_jtag", + .init = axm0432_jtag_init, + .reset = axm0432_jtag_reset, + }, + { .name = "sheevaplug", + .init = sheevaplug_init, + .reset = sheevaplug_reset, + }, + { .name = "icebear", + .init = icebear_jtag_init, + .reset = icebear_jtag_reset, + }, + { .name = "cortino", + .init = cortino_jtag_init, + .reset = comstick_reset, + }, + { .name = "signalyzer-h", + .init = signalyzer_h_init, + .reset = signalyzer_h_reset, + .blink = signalyzer_h_blink + }, + { .name = "ktlink", + .init = ktlink_init, + .reset = ktlink_reset, + .blink = ktlink_blink + }, + { .name = "redbee-econotag", + .init = redbee_init, + .reset = redbee_reset, + }, + { .name = "redbee-usb", + .init = redbee_init, + .reset = redbee_reset, + .channel = INTERFACE_B, + }, + { .name = "lisa-l", + .init = lisa_l_init, + .reset = ftx23_reset, + .blink = lisa_l_blink, + .channel = INTERFACE_B, + }, + { .name = "flossjtag", + .init = flossjtag_init, + .reset = ftx23_reset, + .blink = flossjtag_blink, + }, + { .name = "xds100v2", + .init = xds100v2_init, + .reset = xds100v2_reset, + }, + { .name = NULL, /* END OF TABLE */ }, }; -static uint8_t nTRST, nTRSTnOE, nSRST, nSRSTnOE; +/* bitmask used to drive nTRST; usually a GPIOLx signal */ +static uint8_t nTRST; +static uint8_t nTRSTnOE; +/* bitmask used to drive nSRST; usually a GPIOLx signal */ +static uint8_t nSRST; +static uint8_t nSRSTnOE; +/** the layout being used with this debug session */ static const struct ft2232_layout *layout; + +/** default bitmask values driven on DBUS: TCK/TDI/TDO/TMS and GPIOL(0..4) */ static uint8_t low_output = 0x0; + +/* note that direction bit == 1 means that signal is an output */ + +/** default direction bitmask for DBUS: TCK/TDI/TDO/TMS and GPIOL(0..4) */ static uint8_t low_direction = 0x0; +/** default value bitmask for CBUS GPIOH(0..4) */ static uint8_t high_output = 0x0; +/** default direction bitmask for CBUS GPIOH(0..4) */ static uint8_t high_direction = 0x0; #if BUILD_FT2232_FTD2XX == 1 @@ -238,6 +388,12 @@ static int require_send; a comment would have been nice. */ +#if BUILD_FT2232_FTD2XX == 1 +#define FT2232_BUFFER_READ_QUEUE_SIZE (64*64) +#else +#define FT2232_BUFFER_READ_QUEUE_SIZE (64*4) +#endif + #define FT2232_BUFFER_SIZE 131072 static uint8_t* ft2232_buffer = NULL; @@ -364,17 +520,16 @@ static int ft2232_write(uint8_t* buf, int size, uint32_t* bytes_written) { #if BUILD_FT2232_FTD2XX == 1 FT_STATUS status; - DWORD dw_bytes_written; + DWORD dw_bytes_written = 0; if ((status = FT_Write(ftdih, buf, size, &dw_bytes_written)) != FT_OK) { *bytes_written = dw_bytes_written; - LOG_ERROR("FT_Write returned: %lu", status); + LOG_ERROR("FT_Write returned: %s", ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } else { *bytes_written = dw_bytes_written; - return ERROR_OK; } #elif BUILD_FT2232_LIBFTDI == 1 int retval; @@ -387,9 +542,15 @@ static int ft2232_write(uint8_t* buf, int size, uint32_t* bytes_written) else { *bytes_written = retval; - return ERROR_OK; } #endif + + if (*bytes_written != (uint32_t)size) + { + return ERROR_JTAG_DEVICE_ERROR; + } + + return ERROR_OK; } static int ft2232_read(uint8_t* buf, uint32_t size, uint32_t* bytes_read) @@ -406,7 +567,7 @@ static int ft2232_read(uint8_t* buf, uint32_t size, uint32_t* bytes_read) *bytes_read, &dw_bytes_read)) != FT_OK) { *bytes_read = 0; - LOG_ERROR("FT_Read returned: %lu", status); + LOG_ERROR("FT_Read returned: %s", ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } *bytes_read += dw_bytes_read; @@ -463,8 +624,9 @@ static int ft2232h_ft4232h_adaptive_clocking(bool enable) LOG_DEBUG("%2.2x", buf); uint32_t bytes_written; - int retval = ft2232_write(&buf, 1, &bytes_written); - if ((ERROR_OK != retval) || (bytes_written != 1)) + int retval; + + if ((retval = ft2232_write(&buf, sizeof(buf), &bytes_written)) != ERROR_OK) { LOG_ERROR("couldn't write command to %s adaptive clocking" , enable ? "enable" : "disable"); @@ -483,8 +645,8 @@ static int ft2232h_ft4232h_clk_divide_by_5(bool enable) { uint32_t bytes_written; uint8_t buf = enable ? 0x8b : 0x8a; - int retval = ft2232_write(&buf, 1, &bytes_written); - if ((ERROR_OK != retval) || (bytes_written != 1)) + + if (ft2232_write(&buf, sizeof(buf), &bytes_written) != ERROR_OK) { LOG_ERROR("couldn't write command to %s clk divide by 5" , enable ? "enable" : "disable"); @@ -521,7 +683,7 @@ static int ft2232_speed(int speed) buf[2] = (speed >> 8) & 0xff; /* valueH */ LOG_DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]); - if (((retval = ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3)) + if ((retval = ft2232_write(buf, sizeof(buf), &bytes_written)) != ERROR_OK) { LOG_ERROR("couldn't set FT2232 TCK speed"); return retval; @@ -631,7 +793,7 @@ static void ft2232_debug_dump_buffer(void) for (i = 0; i < ft2232_buffer_size; i++) { - line_p += snprintf(line_p, 256 - (line_p - line), "%2.2x ", ft2232_buffer[i]); + line_p += snprintf(line_p, sizeof(line) - (line_p - line), "%2.2x ", ft2232_buffer[i]); if (i % 16 == 15) { LOG_DEBUG("%s", line); @@ -1191,7 +1353,6 @@ static int ft2232_large_scan(struct scan_command* cmd, enum scan_type type, uint LOG_DEBUG("thisrun_read: %i, bytes_read: %i", thisrun_read, (int)bytes_read); - receive_pointer += bytes_read; } return ERROR_OK; @@ -1246,7 +1407,8 @@ static int ft2232_predict_scan_in(int scan_size, enum scan_type type) return predicted_size; } -static void usbjtag_reset(int trst, int srst) +/* semi-generic FT2232/FT4232 reset code */ +static void ftx23_reset(int trst, int srst) { enum reset_types jtag_reset_config = jtag_get_reset_config(); if (trst == 1) @@ -1417,6 +1579,34 @@ static void flyswatter_reset(int trst, int srst) LOG_DEBUG("trst: %i, srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", trst, srst, low_output, low_direction); } +static void flyswatter1_reset(int trst, int srst) +{ + flyswatter_reset(trst, srst); +} + +static void flyswatter2_reset(int trst, int srst) +{ + flyswatter_reset(trst, !srst); +} + +static void minimodule_reset(int trst, int srst) +{ + if (srst == 1) + { + low_output &= ~nSRST; + } + else if (srst == 0) + { + low_output |= nSRST; + } + + /* command "set data bits low byte" */ + buffer_write(0x80); + buffer_write(low_output); + buffer_write(low_direction); + LOG_DEBUG("trst: %i, srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", trst, srst, low_output, low_direction); +} + static void turtle_reset(int trst, int srst) { trst = trst; @@ -1517,6 +1707,66 @@ static void sheevaplug_reset(int trst, int srst) LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction); } +static void redbee_reset(int trst, int srst) +{ + if (trst == 1) + { + tap_set_state(TAP_RESET); + high_output &= ~nTRST; + } + else if (trst == 0) + { + high_output |= nTRST; + } + + if (srst == 1) + { + high_output &= ~nSRST; + } + else if (srst == 0) + { + high_output |= nSRST; + } + + /* command "set data bits low byte" */ + buffer_write(0x82); + 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 xds100v2_reset(int trst, int srst) +{ + if (trst == 1) + { + tap_set_state(TAP_RESET); + high_output &= ~nTRST; + } + else if (trst == 0) + { + high_output |= nTRST; + } + + if (srst == 1) + { + high_output |= nSRST; + } + else if (srst == 0) + { + high_output &= ~nSRST; + } + + /* command "set data bits low byte" */ + buffer_write(0x82); + 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 int ft2232_execute_runtest(struct jtag_command *cmd) { int retval; @@ -1618,6 +1868,72 @@ static int ft2232_execute_statemove(struct jtag_command *cmd) return retval; } +/** + * Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG + * (or SWD) state machine. + */ +static int ft2232_execute_tms(struct jtag_command *cmd) +{ + int retval = ERROR_OK; + unsigned num_bits = cmd->cmd.tms->num_bits; + const uint8_t *bits = cmd->cmd.tms->bits; + unsigned count; + + DEBUG_JTAG_IO("TMS: %d bits", num_bits); + + /* only send the maximum buffer size that FT2232C can handle */ + count = 3 * DIV_ROUND_UP(num_bits, 4); + if (ft2232_buffer_size + 3*count + 1 > FT2232_BUFFER_SIZE) { + if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) + retval = ERROR_JTAG_QUEUE_FAILED; + + require_send = 0; + first_unsent = cmd; + } + + /* Shift out in batches of at most 6 bits; there's a report of an + * FT2232 bug in this area, where shifting exactly 7 bits can make + * problems with TMS signaling for the last clock cycle: + * + * http://developer.intra2net.com/mailarchive/html/ + * libftdi/2009/msg00292.html + * + * Command 0x4b is: "Clock Data to TMS/CS Pin (no Read)" + * + * Note that pathmoves in JTAG are not often seven bits, so that + * isn't a particularly likely situation outside of "special" + * signaling such as switching between JTAG and SWD modes. + */ + while (num_bits) { + if (num_bits <= 6) { + buffer_write(0x4b); + buffer_write(num_bits - 1); + buffer_write(*bits & 0x3f); + break; + } + + /* Yes, this is lazy ... we COULD shift out more data + * bits per operation, but doing it in nybbles is easy + */ + buffer_write(0x4b); + buffer_write(3); + buffer_write(*bits & 0xf); + num_bits -= 4; + + count = (num_bits > 4) ? 4 : num_bits; + + buffer_write(0x4b); + buffer_write(count - 1); + buffer_write((*bits >> 4) & 0xf); + num_bits -= count; + + bits++; + } + + require_send = 1; + return retval; +} + static int ft2232_execute_pathmove(struct jtag_command *cmd) { int predicted_size = 0; @@ -1770,20 +2086,23 @@ static int ft2232_execute_stableclocks(struct jtag_command *cmd) static int ft2232_execute_command(struct jtag_command *cmd) { int retval; - retval = ERROR_OK; switch (cmd->type) { case JTAG_RESET: retval = ft2232_execute_reset(cmd); break; case JTAG_RUNTEST: retval = ft2232_execute_runtest(cmd); break; - case JTAG_STATEMOVE: retval = ft2232_execute_statemove(cmd); break; + case JTAG_TLR_RESET: retval = ft2232_execute_statemove(cmd); break; case JTAG_PATHMOVE: retval = ft2232_execute_pathmove(cmd); break; case JTAG_SCAN: retval = ft2232_execute_scan(cmd); break; case JTAG_SLEEP: retval = ft2232_execute_sleep(cmd); break; case JTAG_STABLECLOCKS: retval = ft2232_execute_stableclocks(cmd); break; + case JTAG_TMS: + retval = ft2232_execute_tms(cmd); + break; default: LOG_ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); + retval = ERROR_JTAG_QUEUE_FAILED; + break; } return retval; } @@ -1810,12 +2129,20 @@ static int ft2232_execute_queue(void) while (cmd) { + /* fill the write buffer with the desired command */ if (ft2232_execute_command(cmd) != ERROR_OK) retval = ERROR_JTAG_QUEUE_FAILED; - /* Start reading input before FT2232 TX buffer fills up */ + /* Start reading input before FT2232 TX buffer fills up. + * Sometimes this happens because we don't know the + * length of the last command before we execute it. So + * we simple inform the user. + */ cmd = cmd->next; - if (ft2232_expect_read > 256) + + if (ft2232_expect_read >= FT2232_BUFFER_READ_QUEUE_SIZE ) { + if (ft2232_expect_read > (FT2232_BUFFER_READ_QUEUE_SIZE+1) ) + LOG_DEBUG("read buffer size looks too high %d/%d",ft2232_expect_read,(FT2232_BUFFER_READ_QUEUE_SIZE+1)); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) retval = ERROR_JTAG_QUEUE_FAILED; first_unsent = cmd; @@ -1840,7 +2167,12 @@ static int ft2232_init_ftd2xx(uint16_t vid, uint16_t pid, int more, int* try_mor char* openex_string = NULL; uint8_t latency_timer; - LOG_DEBUG("'ft2232' interface using FTD2XX with '%s' layout (%4.4x:%4.4x)", ft2232_layout, vid, pid); + if (layout == NULL) { + LOG_WARNING("No ft2232 layout specified'"); + return ERROR_JTAG_INIT_FAILED; + } + + LOG_DEBUG("'ft2232' interface using FTD2XX with '%s' layout (%4.4x:%4.4x)", layout->name, vid, pid); #if IS_WIN32 == 0 /* Add non-standard Vid/Pid to the linux driver */ @@ -1888,7 +2220,7 @@ static int ft2232_init_ftd2xx(uint16_t vid, uint16_t pid, int more, int* try_mor } else { /* drat, give the user a meaningfull message. * telling the use we tried *BOTH* methods. */ - LOG_WARNING("Unable to open FTDI Device tried: '%s' and '%s'\n", + LOG_WARNING("Unable to open FTDI Device tried: '%s' and '%s'", ft2232_device_desc, ft2232_device_desc_A); } @@ -1901,11 +2233,13 @@ static int ft2232_init_ftd2xx(uint16_t vid, uint16_t pid, int more, int* try_mor if (more) { - LOG_WARNING("unable to open ftdi device (trying more): %lu", status); + LOG_WARNING("unable to open ftdi device (trying more): %s", + ftd2xx_status_string(status)); *try_more = 1; return ERROR_JTAG_INIT_FAILED; } - LOG_ERROR("unable to open ftdi device: %lu", status); + LOG_ERROR("unable to open ftdi device: %s", + ftd2xx_status_string(status)); status = FT_ListDevices(&num_devices, NULL, FT_LIST_NUMBER_ONLY); if (status == FT_OK) { @@ -1921,7 +2255,7 @@ static int ft2232_init_ftd2xx(uint16_t vid, uint16_t pid, int more, int* try_mor if (status == FT_OK) { - LOG_ERROR("ListDevices: %lu\n", num_devices); + LOG_ERROR("ListDevices: %" PRIu32, (uint32_t)num_devices); for (i = 0; i < num_devices; i++) LOG_ERROR("%" PRIu32 ": \"%s\"", i, desc_array[i]); } @@ -1933,21 +2267,35 @@ static int ft2232_init_ftd2xx(uint16_t vid, uint16_t pid, int more, int* try_mor } else { - LOG_ERROR("ListDevices: NONE\n"); + LOG_ERROR("ListDevices: NONE"); } return ERROR_JTAG_INIT_FAILED; } if ((status = FT_SetLatencyTimer(ftdih, ft2232_latency)) != FT_OK) { - LOG_ERROR("unable to set latency timer: %lu", status); + LOG_ERROR("unable to set latency timer: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_INIT_FAILED; } if ((status = FT_GetLatencyTimer(ftdih, &latency_timer)) != FT_OK) { - LOG_ERROR("unable to get latency timer: %lu", status); - return ERROR_JTAG_INIT_FAILED; + /* ftd2xx 1.04 (linux) has a bug when calling FT_GetLatencyTimer + * so ignore errors if using this driver version */ + DWORD dw_version; + + status = FT_GetDriverVersion(ftdih, &dw_version); + LOG_ERROR("unable to get latency timer: %s", + ftd2xx_status_string(status)); + + if ((status == FT_OK) && (dw_version == 0x10004)) { + LOG_ERROR("ftd2xx 1.04 detected - this has known issues " \ + "with FT_GetLatencyTimer, upgrade to a newer version"); + } + else { + return ERROR_JTAG_INIT_FAILED; + } } else { @@ -1956,19 +2304,22 @@ static int ft2232_init_ftd2xx(uint16_t vid, uint16_t pid, int more, int* try_mor if ((status = FT_SetTimeouts(ftdih, 5000, 5000)) != FT_OK) { - LOG_ERROR("unable to set timeouts: %lu", status); + LOG_ERROR("unable to set timeouts: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_INIT_FAILED; } if ((status = FT_SetBitMode(ftdih, 0x0b, 2)) != FT_OK) { - LOG_ERROR("unable to enable bit i/o mode: %lu", status); + LOG_ERROR("unable to enable bit i/o mode: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_INIT_FAILED; } if ((status = FT_GetDeviceInfo(ftdih, &ftdi_device, &deviceID, SerialNumber, Description, NULL)) != FT_OK) { - LOG_ERROR("unable to get FT_GetDeviceInfo: %lu", status); + LOG_ERROR("unable to get FT_GetDeviceInfo: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_INIT_FAILED; } else @@ -1978,8 +2329,8 @@ static int ft2232_init_ftd2xx(uint16_t vid, uint16_t pid, int more, int* try_mor unsigned no_of_known_types = ARRAY_SIZE(type_str) - 1; unsigned type_index = ((unsigned)ftdi_device <= no_of_known_types) ? ftdi_device : FT_DEVICE_UNKNOWN; - LOG_INFO("device: %lu \"%s\"", ftdi_device, type_str[type_index]); - LOG_INFO("deviceID: %lu", deviceID); + LOG_INFO("device: %" PRIu32 " \"%s\"", (uint32_t)ftdi_device, type_str[type_index]); + LOG_INFO("deviceID: %" PRIu32, (uint32_t)deviceID); LOG_INFO("SerialNumber: %s", SerialNumber); LOG_INFO("Description: %s", Description); } @@ -1993,7 +2344,8 @@ static int ft2232_purge_ftd2xx(void) if ((status = FT_Purge(ftdih, FT_PURGE_RX | FT_PURGE_TX)) != FT_OK) { - LOG_ERROR("error purging ftd2xx device: %lu", status); + LOG_ERROR("error purging ftd2xx device: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_INIT_FAILED; } @@ -2003,17 +2355,25 @@ static int ft2232_purge_ftd2xx(void) #endif /* BUILD_FT2232_FTD2XX == 1 */ #if BUILD_FT2232_LIBFTDI == 1 -static int ft2232_init_libftdi(uint16_t vid, uint16_t pid, int more, int* try_more) +static int ft2232_init_libftdi(uint16_t vid, uint16_t pid, int more, int* try_more, int channel) { uint8_t latency_timer; + if (layout == NULL) { + LOG_WARNING("No ft2232 layout specified'"); + return ERROR_JTAG_INIT_FAILED; + } + LOG_DEBUG("'ft2232' interface using libftdi with '%s' layout (%4.4x:%4.4x)", - ft2232_layout, vid, pid); + layout->name, vid, pid); if (ftdi_init(&ftdic) < 0) return ERROR_JTAG_INIT_FAILED; - if (ftdi_set_interface(&ftdic, INTERFACE_A) < 0) + /* default to INTERFACE_A */ + if(channel == INTERFACE_ANY) { channel = INTERFACE_A; } + + if (ftdi_set_interface(&ftdic, channel) < 0) { LOG_ERROR("unable to select FT2232 channel A: %s", ftdic.error_str); return ERROR_JTAG_INIT_FAILED; @@ -2080,13 +2440,51 @@ static int ft2232_purge_libftdi(void) #endif /* BUILD_FT2232_LIBFTDI == 1 */ +static int ft2232_set_data_bits_low_byte( uint8_t value, uint8_t direction ) +{ + uint8_t buf[3]; + uint32_t bytes_written; + + buf[0] = 0x80; /* command "set data bits low byte" */ + buf[1] = value; /* value */ + buf[2] = direction; /* direction */ + + LOG_DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]); + + if (ft2232_write(buf, sizeof(buf), &bytes_written) != ERROR_OK) + { + LOG_ERROR("couldn't initialize data bits low byte"); + return ERROR_JTAG_INIT_FAILED; + } + + return ERROR_OK; +} + +static int ft2232_set_data_bits_high_byte( uint8_t value, uint8_t direction ) +{ + uint8_t buf[3]; + uint32_t bytes_written; + + buf[0] = 0x82; /* command "set data bits high byte" */ + buf[1] = value; /* value */ + buf[2] = direction; /* direction */ + + LOG_DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]); + + if (ft2232_write(buf, sizeof(buf), &bytes_written) != ERROR_OK) + { + LOG_ERROR("couldn't initialize data bits high byte"); + return ERROR_JTAG_INIT_FAILED; + } + + return ERROR_OK; +} + static int ft2232_init(void) { uint8_t buf[1]; int retval; uint32_t bytes_written; - const struct ft2232_layout* cur_layout = ft2232_layouts; - int i; if (tap_get_tms_path_len(TAP_IRPAUSE,TAP_IRPAUSE) == 7) { @@ -2097,29 +2495,12 @@ static int ft2232_init(void) LOG_DEBUG("ft2232 interface using shortest path jtag state transitions"); } - if ((ft2232_layout == NULL) || (ft2232_layout[0] == 0)) - { - ft2232_layout = "usbjtag"; - LOG_WARNING("No ft2232 layout specified, using default 'usbjtag'"); - } - - while (cur_layout->name) - { - if (strcmp(cur_layout->name, ft2232_layout) == 0) - { - layout = cur_layout; - break; - } - cur_layout++; - } - - if (!layout) - { - LOG_ERROR("No matching layout found for %s", ft2232_layout); + if (layout == NULL) { + LOG_WARNING("No ft2232 layout specified'"); return ERROR_JTAG_INIT_FAILED; } - for (i = 0; 1; i++) + for (int i = 0; 1; i++) { /* * "more indicates that there are more IDs to try, so we should @@ -2138,7 +2519,7 @@ static int ft2232_init(void) more, &try_more); #elif BUILD_FT2232_LIBFTDI == 1 retval = ft2232_init_libftdi(ft2232_vid[i], ft2232_pid[i], - more, &try_more); + more, &try_more, layout->channel); #endif if (retval >= 0) break; @@ -2166,10 +2547,8 @@ static int ft2232_init(void) return ERROR_JTAG_INIT_FAILED; } - ft2232_speed(jtag_get_speed()); - buf[0] = 0x85; /* Disconnect TDI/DO to TDO/DI for Loopback */ - if (((retval = ft2232_write(buf, 1, &bytes_written)) != ERROR_OK) || (bytes_written != 1)) + if ((retval = ft2232_write(buf, 1, &bytes_written)) != ERROR_OK) { LOG_ERROR("couldn't write to FT2232 to disable loopback"); return ERROR_JTAG_INIT_FAILED; @@ -2184,60 +2563,21 @@ static int ft2232_init(void) return ERROR_OK; } -static int usbjtag_init(void) +/** Updates defaults for DBUS signals: the four JTAG signals + * (TCK, TDI, TDO, TMS) and * the four GPIOL signals. + */ +static inline void ftx232_dbus_init(void) { - uint8_t buf[3]; - uint32_t bytes_written; - low_output = 0x08; low_direction = 0x0b; +} - if (strcmp(ft2232_layout, "usbjtag") == 0) - { - nTRST = 0x10; - nTRSTnOE = 0x10; - nSRST = 0x40; - nSRSTnOE = 0x40; - } - else if (strcmp(ft2232_layout, "signalyzer") == 0) - { - nTRST = 0x10; - nTRSTnOE = 0x10; - nSRST = 0x20; - nSRSTnOE = 0x20; - } - else if (strcmp(ft2232_layout, "evb_lm3s811") == 0) - { - /* There are multiple revisions of LM3S811 eval boards: - * - Rev B (and older?) boards have no SWO trace support. - * - Rev C boards add ADBUS_6 DBG_ENn and BDBUS_4 SWO_EN; - * they should use the "luminary_icdi" layout instead. - */ - nTRST = 0x0; - nTRSTnOE = 0x00; - nSRST = 0x20; - nSRSTnOE = 0x20; - low_output = 0x88; - low_direction = 0x8b; - } - else if (strcmp(ft2232_layout, "luminary_icdi") == 0) - { - /* Most Luminary eval boards support SWO trace output, - * and should use this "luminary_icdi" layout. - */ - nTRST = 0x0; - nTRSTnOE = 0x00; - nSRST = 0x20; - nSRSTnOE = 0x20; - low_output = 0x88; - low_direction = 0xcb; - } - else - { - LOG_ERROR("BUG: usbjtag_init called for unknown layout '%s'", ft2232_layout); - return ERROR_JTAG_INIT_FAILED; - } - +/** Initializes DBUS signals: the four JTAG signals (TCK, TDI, TDO, TMS), + * the four GPIOL signals. Initialization covers value and direction, + * as customized for each layout. + */ +static int ftx232_dbus_write(void) +{ enum reset_types jtag_reset_config = jtag_get_reset_config(); if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) { @@ -2262,35 +2602,111 @@ static int usbjtag_init(void) } /* initialize low byte for jtag */ - buf[0] = 0x80; /* command "set data bits low byte" */ - buf[1] = low_output; /* value (TMS = 1,TCK = 0, TDI = 0, xRST high) */ - buf[2] = low_direction; /* dir (output = 1), TCK/TDI/TMS = out, TDO = in */ - 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)) + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'USBJTAG' layout"); + LOG_ERROR("couldn't initialize FT2232 DBUS"); return ERROR_JTAG_INIT_FAILED; } return ERROR_OK; } -static int axm0432_jtag_init(void) +static int usbjtag_init(void) { - uint8_t buf[3]; - uint32_t bytes_written; + /* + * NOTE: This is now _specific_ to the "usbjtag" layout. + * Don't try cram any more layouts into this. + */ + ftx232_dbus_init(); + + nTRST = 0x10; + nTRSTnOE = 0x10; + nSRST = 0x40; + nSRSTnOE = 0x40; + return ftx232_dbus_write(); +} + +static int lm3s811_jtag_init(void) +{ + ftx232_dbus_init(); + + /* There are multiple revisions of LM3S811 eval boards: + * - Rev B (and older?) boards have no SWO trace support. + * - Rev C boards add ADBUS_6 DBG_ENn and BDBUS_4 SWO_EN; + * they should use the "luminary_icdi" layout instead. + */ + nTRST = 0x0; + nTRSTnOE = 0x00; + nSRST = 0x20; + nSRSTnOE = 0x20; + low_output = 0x88; + low_direction = 0x8b; + + return ftx232_dbus_write(); +} + +static int icdi_jtag_init(void) +{ + ftx232_dbus_init(); + + /* Most Luminary eval boards support SWO trace output, + * and should use this "luminary_icdi" layout. + * + * ADBUS 0..3 are used for JTAG as usual. GPIOs are used + * to switch between JTAG and SWD, or switch the ft2232 UART + * on the second MPSSE channel/interface (BDBUS) + * between (i) the stellaris UART (on Luminary boards) + * or (ii) SWO trace data (generic). + * + * We come up in JTAG mode and may switch to SWD later (with + * SWO/trace option if SWD is active). + * + * DBUS == GPIO-Lx + * CBUS == GPIO-Hx + */ + + +#define ICDI_JTAG_EN (1 << 7) /* ADBUS 7 (a.k.a. DBGMOD) */ +#define ICDI_DBG_ENn (1 << 6) /* ADBUS 6 */ +#define ICDI_SRST (1 << 5) /* ADBUS 5 */ + + + /* GPIOs on second channel/interface (UART) ... */ +#define ICDI_SWO_EN (1 << 4) /* BDBUS 4 */ +#define ICDI_TX_SWO (1 << 1) /* BDBUS 1 */ +#define ICDI_VCP_RX (1 << 0) /* BDBUS 0 (to stellaris UART) */ + + nTRST = 0x0; + nTRSTnOE = 0x00; + nSRST = ICDI_SRST; + nSRSTnOE = ICDI_SRST; + + low_direction |= ICDI_JTAG_EN | ICDI_DBG_ENn; + low_output |= ICDI_JTAG_EN; + low_output &= ~ICDI_DBG_ENn; + + return ftx232_dbus_write(); +} + +static int signalyzer_init(void) +{ + ftx232_dbus_init(); + + nTRST = 0x10; + nTRSTnOE = 0x10; + nSRST = 0x20; + nSRSTnOE = 0x20; + return ftx232_dbus_write(); +} + +static int axm0432_jtag_init(void) +{ low_output = 0x08; low_direction = 0x2b; /* initialize low byte for jtag */ - buf[0] = 0x80; /* command "set data bits low byte" */ - buf[1] = low_output; /* value (TMS = 1,TCK = 0, TDI = 0, nOE = 0) */ - buf[2] = low_direction; /* dir (output = 1), TCK/TDI/TMS = out, TDO = in, nOE = out */ - 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)) + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2331,13 +2747,8 @@ static int axm0432_jtag_init(void) high_output |= nSRST; } - /* initialize high port */ - buf[0] = 0x82; /* command "set data bits high byte" */ - buf[1] = high_output; /* value */ - buf[2] = high_direction; /* all outputs (xRST and xRSTnOE) */ - 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)) + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'Dicarlo' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2346,21 +2757,62 @@ static int axm0432_jtag_init(void) return ERROR_OK; } -static int jtagkey_init(void) +static int redbee_init(void) { - uint8_t buf[3]; - uint32_t bytes_written; + low_output = 0x08; + low_direction = 0x2b; + + /* initialize low byte for jtag */ + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) + { + LOG_ERROR("couldn't initialize FT2232 with 'redbee' layout"); + return ERROR_JTAG_INIT_FAILED; + } + + nTRST = 0x08; + nTRSTnOE = 0x0; /* No output enable for TRST*/ + nSRST = 0x04; + nSRSTnOE = 0x0; /* No output enable for SRST*/ + + high_output = 0x0; + high_direction = 0x0c; + + enum reset_types jtag_reset_config = jtag_get_reset_config(); + if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) + { + LOG_ERROR("can't set nTRSTOE to push-pull on redbee"); + } + else + { + high_output |= nTRST; + } + + if (jtag_reset_config & RESET_SRST_PUSH_PULL) + { + LOG_ERROR("can't set nSRST to push-pull on redbee"); + } + else + { + high_output |= nSRST; + } + + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) + { + LOG_ERROR("couldn't initialize FT2232 with 'redbee' layout"); + return ERROR_JTAG_INIT_FAILED; + } + + return ERROR_OK; +} +static int jtagkey_init(void) +{ low_output = 0x08; low_direction = 0x1b; /* initialize low byte for jtag */ - buf[0] = 0x80; /* command "set data bits low byte" */ - buf[1] = low_output; /* value (TMS = 1,TCK = 0, TDI = 0, nOE = 0) */ - buf[2] = low_direction; /* dir (output = 1), TCK/TDI/TMS = out, TDO = in, nOE = out */ - 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)) + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2413,13 +2865,8 @@ static int jtagkey_init(void) high_output &= ~nSRST; } - /* initialize high port */ - buf[0] = 0x82; /* command "set data bits high byte" */ - buf[1] = high_output; /* value */ - buf[2] = high_direction; /* all outputs (xRST and xRSTnOE) */ - 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)) + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2430,19 +2877,11 @@ static int jtagkey_init(void) static int olimex_jtag_init(void) { - uint8_t buf[3]; - uint32_t bytes_written; - low_output = 0x08; low_direction = 0x1b; /* initialize low byte for jtag */ - buf[0] = 0x80; /* command "set data bits low byte" */ - buf[1] = low_output; /* value (TMS = 1,TCK = 0, TDI = 0, nOE = 0) */ - buf[2] = low_direction; /* dir (output = 1), TCK/TDI/TMS = out, TDO = in, nOE = out */ - 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)) + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'Olimex' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2480,13 +2919,8 @@ static int olimex_jtag_init(void) /* turn red LED on */ high_output |= 0x08; - /* initialize high port */ - buf[0] = 0x82; /* command "set data bits high byte" */ - buf[1] = high_output; /* value */ - buf[2] = high_direction; /* all outputs (xRST and xRSTnOE) */ - 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)) + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'Olimex' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2495,21 +2929,21 @@ static int olimex_jtag_init(void) return ERROR_OK; } -static int flyswatter_init(void) +static int flyswatter_init(int rev) { - uint8_t buf[3]; - uint32_t bytes_written; - low_output = 0x18; - low_direction = 0xfb; + low_direction = 0x7b; - /* initialize low byte for jtag */ - buf[0] = 0x80; /* command "set data bits low byte" */ - buf[1] = low_output; /* value (TMS = 1,TCK = 0, TDI = 0, nOE = 0) */ - buf[2] = low_direction; /* dir (output = 1), TCK/TDI/TMS = out, TDO = in, nOE[12]=out, n[ST]srst = out */ - LOG_DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]); + if ((rev < 0) || (rev > 3)) { + LOG_ERROR("bogus 'flyswatter' revision supplied (%i)", rev); + return ERROR_JTAG_INIT_FAILED; + } - if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3)) + if (rev == 1) + low_direction |= 1 << 7; + + /* initialize low byte for jtag */ + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'flyswatter' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2521,18 +2955,17 @@ static int flyswatter_init(void) nSRSTnOE = 0x00; /* no output enable for nSRST */ high_output = 0x00; - high_direction = 0x0c; + + if (rev == 1) + high_direction = 0x0c; + else + high_direction = 0x01; /* turn red LED3 on, LED2 off */ high_output |= 0x08; - /* initialize high port */ - buf[0] = 0x82; /* command "set data bits high byte" */ - buf[1] = high_output; /* value */ - buf[2] = high_direction; /* all outputs (xRST and xRSTnOE) */ - 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)) + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'flyswatter' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2541,21 +2974,54 @@ static int flyswatter_init(void) return ERROR_OK; } -static int turtle_init(void) +static int flyswatter1_init(void) { - uint8_t buf[3]; - uint32_t bytes_written; + return flyswatter_init(1); +} +static int flyswatter2_init(void) +{ + return flyswatter_init(2); +} + +static int minimodule_init(void) +{ + low_output = 0x18;//check if srst should be 1 or 0 initially. (0x08) (flyswatter was 0x18) + low_direction = 0xfb;//0xfb; + + /* initialize low byte for jtag */ + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) + { + LOG_ERROR("couldn't initialize FT2232 with 'minimodule' layout"); + return ERROR_JTAG_INIT_FAILED; + } + + + nSRST = 0x20; + + high_output = 0x00; + high_direction = 0x05; + + /* turn red LED3 on, LED2 off */ + //high_output |= 0x08; + + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) + { + LOG_ERROR("couldn't initialize FT2232 with 'minimodule' layout"); + return ERROR_JTAG_INIT_FAILED; + } + + return ERROR_OK; +} + +static int turtle_init(void) +{ low_output = 0x08; low_direction = 0x5b; /* initialize low byte for jtag */ - buf[0] = 0x80; /* command "set data bits low byte" */ - buf[1] = low_output; /* value (TMS = 1,TCK = 0, TDI = 0, nOE = 0) */ - buf[2] = low_direction; /* dir (output = 1), TCK/TDI/TMS = out, TDO = in, nOE = out */ - 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)) + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'turtelizer2' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2566,13 +3032,8 @@ static int turtle_init(void) high_output = 0x00; high_direction = 0x0C; - /* initialize high port */ - buf[0] = 0x82; /* command "set data bits high byte" */ - buf[1] = high_output; - 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)) + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'turtelizer2' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2583,19 +3044,11 @@ static int turtle_init(void) static int comstick_init(void) { - uint8_t buf[3]; - uint32_t bytes_written; - low_output = 0x08; low_direction = 0x0b; /* initialize low byte for jtag */ - buf[0] = 0x80; /* command "set data bits low byte" */ - buf[1] = low_output; /* value (TMS = 1,TCK = 0, TDI = 0, nOE = 0) */ - buf[2] = low_direction; /* dir (output = 1), TCK/TDI/TMS = out, TDO = in, nOE = out */ - 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)) + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'comstick' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2609,13 +3062,8 @@ static int comstick_init(void) high_output = 0x03; high_direction = 0x03; - /* initialize high port */ - buf[0] = 0x82; /* command "set data bits high byte" */ - buf[1] = high_output; - 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)) + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'comstick' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2626,19 +3074,11 @@ static int comstick_init(void) static int stm32stick_init(void) { - uint8_t buf[3]; - uint32_t bytes_written; - low_output = 0x88; low_direction = 0x8b; /* initialize low byte for jtag */ - buf[0] = 0x80; /* command "set data bits low byte" */ - buf[1] = low_output; /* value (TMS = 1,TCK = 0, TDI = 0, nOE = 0) */ - buf[2] = low_direction; /* dir (output = 1), TCK/TDI/TMS = out, TDO = in, nOE = out */ - 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)) + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'stm32stick' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2652,13 +3092,8 @@ static int stm32stick_init(void) high_output = 0x01; high_direction = 0x03; - /* initialize high port */ - buf[0] = 0x82; /* command "set data bits high byte" */ - buf[1] = high_output; - 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)) + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'stm32stick' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2669,19 +3104,11 @@ static int stm32stick_init(void) static int sheevaplug_init(void) { - uint8_t buf[3]; - uint32_t bytes_written; - low_output = 0x08; low_direction = 0x1b; /* initialize low byte for jtag */ - buf[0] = 0x80; /* command "set data bits low byte" */ - buf[1] = low_output; /* value (TMS = 1,TCK = 0, TDI = 0, nOE = 0) */ - buf[2] = low_direction; /* dir (output = 1), TCK/TDI/TMS = out, TDO = in */ - 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)) + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'sheevaplug' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2703,13 +3130,8 @@ static int sheevaplug_init(void) 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; /* all outputs - xRST */ - 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)) + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'sheevaplug' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2720,19 +3142,11 @@ static int sheevaplug_init(void) static int cortino_jtag_init(void) { - uint8_t buf[3]; - uint32_t bytes_written; - low_output = 0x08; low_direction = 0x1b; /* initialize low byte for jtag */ - buf[0] = 0x80; /* command "set data bits low byte" */ - buf[1] = low_output; /* value (TMS = 1,TCK = 0, TDI = 0, nOE = 0) */ - buf[2] = low_direction; /* dir (output = 1), TCK/TDI/TMS = out, TDO = in, nOE = out */ - 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)) + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'cortino' layout"); return ERROR_JTAG_INIT_FAILED; @@ -2746,15 +3160,119 @@ static int cortino_jtag_init(void) high_output = 0x03; high_direction = 0x03; - /* initialize high port */ - buf[0] = 0x82; /* command "set data bits high byte" */ - buf[1] = high_output; - buf[2] = high_direction; - LOG_DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]); + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) + { + LOG_ERROR("couldn't initialize FT2232 with 'cortino' layout"); + return ERROR_JTAG_INIT_FAILED; + } + + return ERROR_OK; +} + +static int lisa_l_init(void) +{ + ftx232_dbus_init(); + + nTRST = 0x10; + nTRSTnOE = 0x10; + nSRST = 0x40; + nSRSTnOE = 0x40; - if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3)) + high_output = 0x00; + high_direction = 0x18; + + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'stm32stick' layout"); + LOG_ERROR("couldn't initialize FT2232 with 'lisa_l' layout"); + return ERROR_JTAG_INIT_FAILED; + } + + return ftx232_dbus_write(); +} + +static int flossjtag_init(void) +{ + ftx232_dbus_init(); + + nTRST = 0x10; + nTRSTnOE = 0x10; + nSRST = 0x40; + nSRSTnOE = 0x40; + + high_output = 0x00; + high_direction = 0x18; + + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) + { + LOG_ERROR("couldn't initialize FT2232 with 'Floss-JTAG' layout"); + return ERROR_JTAG_INIT_FAILED; + } + + return ftx232_dbus_write(); +} + +/* + * The reference schematic from TI for the XDS100v2 has a CPLD on which opens + * the door for a number of different configurations + * + * Known Implementations: + * http://processors.wiki.ti.com/images/9/93/TMS570LS20216_USB_STICK_Schematic.pdf + * + * http://processors.wiki.ti.com/index.php/XDS100 (rev2) + * * CLPD logic: Rising edge to enable outputs (XDS100_PWR_RST) + * * ACBUS3 to transition 0->1 (OE rising edge) + * * CPLD logic: Put the EMU0/1 pins in Hi-Z: + * * ADBUS5/GPIOL1 = EMU_EN = 1 + * * ADBUS6/GPIOL2 = EMU0 = 0 + * * ACBUS4/SPARE0 = EMU1 = 0 + * * CPLD logic: Disable loopback + * * ACBUS6/SPARE2 = LOOPBACK = 0 + */ +#define XDS100_nEMU_EN (1<<5) +#define XDS100_nEMU0 (1<<6) + +#define XDS100_PWR_RST (1<<3) +#define XDS100_nEMU1 (1<<4) +#define XDS100_LOOPBACK (1<<6) +static int xds100v2_init(void) +{ + /* These are in the lower byte */ + nTRST = 0x10; + nTRSTnOE = 0x10; + + /* These aren't actually used on 14 pin connectors */ + /* These are in the upper byte */ + nSRST = 0x01; + nSRSTnOE = 0x01; + + low_output = 0x08 | nTRST | XDS100_nEMU_EN; + low_direction = 0x0b | nTRSTnOE | XDS100_nEMU_EN | XDS100_nEMU0; + + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) + { + LOG_ERROR("couldn't initialize FT2232 with 'xds100v2' layout"); + return ERROR_JTAG_INIT_FAILED; + } + + high_output = 0; + high_direction = nSRSTnOE | XDS100_LOOPBACK | XDS100_PWR_RST | XDS100_nEMU1; + + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) + { + LOG_ERROR("couldn't put CPLD in to reset with 'xds100v2' layout"); + return ERROR_JTAG_INIT_FAILED; + } + + high_output |= XDS100_PWR_RST; + + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) + { + LOG_ERROR("couldn't bring CPLD out of reset with 'xds100v2' layout"); return ERROR_JTAG_INIT_FAILED; } @@ -2766,15 +3284,48 @@ static void olimex_jtag_blink(void) /* Olimex ARM-USB-OCD has a LED connected to ACBUS3 * ACBUS3 is bit 3 of the GPIOH port */ + high_output ^= 0x08; + + buffer_write(0x82); + buffer_write(high_output); + buffer_write(high_direction); +} + +static void flyswatter_jtag_blink(unsigned char led) +{ + buffer_write(0x82); + buffer_write(high_output ^ led); + buffer_write(high_direction); +} + +static void flyswatter1_jtag_blink(void) +{ + /* + * Flyswatter has two LEDs connected to ACBUS2 and ACBUS3 + */ + flyswatter_jtag_blink(0xc); +} + +static void flyswatter2_jtag_blink(void) +{ + /* + * Flyswatter2 only has one LED connected to ACBUS2 + */ + flyswatter_jtag_blink(0x4); +} + +static void turtle_jtag_blink(void) +{ + /* + * Turtelizer2 has two LEDs connected to ACBUS2 and ACBUS3 + */ if (high_output & 0x08) { - /* set port pin high */ - high_output &= 0x07; + high_output = 0x04; } else { - /* set port pin low */ - high_output |= 0x08; + high_output = 0x08; } buffer_write(0x82); @@ -2782,30 +3333,37 @@ static void olimex_jtag_blink(void) buffer_write(high_direction); } -static void flyswatter_jtag_blink(void) +static void lisa_l_blink(void) { /* - * Flyswatter has two LEDs connected to ACBUS2 and ACBUS3 + * Lisa/L has two LEDs connected to BCBUS3 and BCBUS4 */ - high_output ^= 0x0c; + if (high_output & 0x10) + { + high_output = 0x08; + } + else + { + high_output = 0x10; + } buffer_write(0x82); buffer_write(high_output); buffer_write(high_direction); } -static void turtle_jtag_blink(void) +static void flossjtag_blink(void) { /* - * Turtelizer2 has two LEDs connected to ACBUS2 and ACBUS3 + * Floss-JTAG has two LEDs connected to ACBUS3 and ACBUS4 */ - if (high_output & 0x08) + if (high_output & 0x10) { - high_output = 0x04; + high_output = 0x08; } else { - high_output = 0x08; + high_output = 0x10; } buffer_write(0x82); @@ -2873,7 +3431,7 @@ COMMAND_HANDLER(ft2232_handle_serial_command) } else { - LOG_ERROR("expected exactly one argument to ft2232_serial "); + return ERROR_COMMAND_SYNTAX_ERROR; } return ERROR_OK; @@ -2881,13 +3439,27 @@ COMMAND_HANDLER(ft2232_handle_serial_command) COMMAND_HANDLER(ft2232_handle_layout_command) { - if (CMD_ARGC == 0) - return ERROR_OK; + if (CMD_ARGC != 1) { + return ERROR_COMMAND_SYNTAX_ERROR; + } - ft2232_layout = malloc(strlen(CMD_ARGV[0]) + 1); - strcpy(ft2232_layout, CMD_ARGV[0]); + if (layout) { + LOG_ERROR("already specified ft2232_layout %s", + layout->name); + return (strcmp(layout->name, CMD_ARGV[0]) != 0) + ? ERROR_FAIL + : ERROR_OK; + } - return ERROR_OK; + for (const struct ft2232_layout *l = ft2232_layouts; l->name; l++) { + if (strcmp(l->name, CMD_ARGV[0]) == 0) { + layout = l; + return ERROR_OK; + } + } + + LOG_ERROR("No FT2232 layout '%s' found", CMD_ARGV[0]); + return ERROR_FAIL; } COMMAND_HANDLER(ft2232_handle_vid_pid_command) @@ -2931,7 +3503,7 @@ COMMAND_HANDLER(ft2232_handle_latency_command) } else { - LOG_ERROR("expected exactly one argument to ft2232_latency "); + return ERROR_COMMAND_SYNTAX_ERROR; } return ERROR_OK; @@ -3006,9 +3578,6 @@ static int ft2232_stableclocks(int num_cycles, struct jtag_command* cmd) * ADBUS7 - GND */ static int icebear_jtag_init(void) { - uint8_t buf[3]; - uint32_t bytes_written; - low_direction = 0x0b; /* output: TCK TDI TMS; input: TDO */ low_output = 0x08; /* high: TMS; low: TCK TDI */ nTRST = 0x10; @@ -3027,12 +3596,7 @@ static int icebear_jtag_init(void) { low_output |= nSRST; /* initialize low byte for jtag */ - 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)) { + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'IceBear' layout (low)"); return ERROR_JTAG_INIT_FAILED; } @@ -3040,14 +3604,8 @@ static int icebear_jtag_init(void) { high_output = 0x0; high_direction = 0x00; - - /* initialize high port */ - buf[0] = 0x82; /* command "set data bits high byte" */ - buf[1] = high_output; /* value */ - buf[2] = high_direction; /* all outputs (xRST and xRSTnOE) */ - 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)) { + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'IceBear' layout (high)"); return ERROR_JTAG_INIT_FAILED; } @@ -3165,7 +3723,8 @@ static int signalyzer_h_led_set(unsigned char channel, unsigned char led, if ((status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR, ((uint32_t)(channel << 8) | led))) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3173,7 +3732,8 @@ static int signalyzer_h_led_set(unsigned char channel, unsigned char led, (SIGNALYZER_DATA_BUFFER_ADDR + 1), ((uint32_t)(on_time << 8) | off_time))) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3181,14 +3741,16 @@ static int signalyzer_h_led_set(unsigned char channel, unsigned char led, (SIGNALYZER_DATA_BUFFER_ADDR + 2), ((uint32_t)cycles))) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } if ((status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, SIGNALYZER_COMMAND_LED_SET)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3244,8 +3806,6 @@ static int signalyzer_h_init(void) char *end_of_desc; uint16_t read_buf[12] = { 0 }; - uint8_t buf[3]; - uint32_t bytes_written; /* turn on center green led */ signalyzer_h_led_set(SIGNALYZER_CHAN_C, SIGNALYZER_LED_GREEN, @@ -3279,7 +3839,8 @@ static int signalyzer_h_init(void) if ((status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, SIGNALYZER_COMMAND_VERSION)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3289,8 +3850,8 @@ static int signalyzer_h_init(void) (SIGNALYZER_DATA_BUFFER_ADDR + i), &read_buf[i])) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_read returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_read returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } } @@ -3303,21 +3864,24 @@ static int signalyzer_h_init(void) if ((status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR, (uint32_t)(signalyzer_h_side << 8))) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } if ((status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR + 1, 0x0404)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } if ((status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, SIGNALYZER_COMMAND_GPIO_STATE)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3325,28 +3889,32 @@ static int signalyzer_h_init(void) if ((status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR, ((uint32_t)(signalyzer_h_side << 8) | 0x01))) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } if ((status = signalyzer_h_ctrl_write( (SIGNALYZER_DATA_BUFFER_ADDR + 1), 0xA000)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } if ((status = signalyzer_h_ctrl_write( (SIGNALYZER_DATA_BUFFER_ADDR + 2), 0x0008)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } if ((status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, SIGNALYZER_COMMAND_I2C)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3355,7 +3923,8 @@ static int signalyzer_h_init(void) if ((status = signalyzer_h_ctrl_read(SIGNALYZER_COMMAND_ADDR, &read_buf[0])) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_read returned: %lu", status); + LOG_ERROR("signalyzer_h_ctrl_read returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3369,8 +3938,8 @@ static int signalyzer_h_init(void) (SIGNALYZER_DATA_BUFFER_ADDR + i), &read_buf[i])) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_read returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_read returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } } @@ -3434,16 +4003,16 @@ static int signalyzer_h_init(void) ((uint32_t)(signalyzer_h_side << 8) | 0x01))) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } if ((status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, SIGNALYZER_COMMAND_POWERCONTROL_SET)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3452,8 +4021,8 @@ static int signalyzer_h_init(void) SIGNALYZER_DATA_BUFFER_ADDR, (uint32_t)(signalyzer_h_side << 8))) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3461,16 +4030,16 @@ static int signalyzer_h_init(void) SIGNALYZER_DATA_BUFFER_ADDR + 1, 0x0000)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } if ((status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, SIGNALYZER_COMMAND_GPIO_MODE)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3479,8 +4048,8 @@ static int signalyzer_h_init(void) SIGNALYZER_DATA_BUFFER_ADDR, (uint32_t)(signalyzer_h_side << 8))) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3488,8 +4057,8 @@ static int signalyzer_h_init(void) SIGNALYZER_DATA_BUFFER_ADDR + 1, 0x4040)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3497,8 +4066,8 @@ static int signalyzer_h_init(void) SIGNALYZER_COMMAND_ADDR, SIGNALYZER_COMMAND_GPIO_STATE)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } #endif @@ -3569,8 +4138,8 @@ static int signalyzer_h_init(void) ((uint32_t)(signalyzer_h_side << 8) | 0x01))) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3578,8 +4147,8 @@ static int signalyzer_h_init(void) SIGNALYZER_COMMAND_ADDR, SIGNALYZER_COMMAND_POWERCONTROL_SET)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3590,8 +4159,8 @@ static int signalyzer_h_init(void) SIGNALYZER_DATA_BUFFER_ADDR, (uint32_t)(signalyzer_h_side << 8))) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3599,8 +4168,8 @@ static int signalyzer_h_init(void) SIGNALYZER_DATA_BUFFER_ADDR + 1, 0x0060)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3608,8 +4177,8 @@ static int signalyzer_h_init(void) SIGNALYZER_COMMAND_ADDR, SIGNALYZER_COMMAND_GPIO_MODE)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3620,8 +4189,8 @@ static int signalyzer_h_init(void) SIGNALYZER_DATA_BUFFER_ADDR, (uint32_t)(signalyzer_h_side << 8))) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3629,8 +4198,8 @@ static int signalyzer_h_init(void) SIGNALYZER_DATA_BUFFER_ADDR + 1, 0x0000)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } @@ -3638,8 +4207,8 @@ static int signalyzer_h_init(void) SIGNALYZER_COMMAND_ADDR, SIGNALYZER_COMMAND_GPIO_STATE)) != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", - status); + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftd2xx_status_string(status)); return ERROR_JTAG_DEVICE_ERROR; } #endif @@ -3690,12 +4259,7 @@ static int signalyzer_h_init(void) } /* initialize low byte of controller for jtag operation */ - buf[0] = 0x80; - buf[1] = low_output; - buf[2] = low_direction; - - if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) - || (bytes_written != 3)) + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize Signalyzer-H layout"); return ERROR_JTAG_INIT_FAILED; @@ -3705,12 +4269,7 @@ static int signalyzer_h_init(void) if (ftdi_device == FT_DEVICE_2232H) { /* initialize high byte of controller for jtag operation */ - buf[0] = 0x82; - buf[1] = high_output; - buf[2] = high_direction; - - if ((ft2232_write(buf, 3, &bytes_written) != ERROR_OK) - || (bytes_written != 3)) + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize Signalyzer-H layout"); return ERROR_JTAG_INIT_FAILED; @@ -3720,12 +4279,7 @@ static int signalyzer_h_init(void) if (ftdi_device == TYPE_2232H) { /* initialize high byte of controller for jtag operation */ - buf[0] = 0x82; - buf[1] = high_output; - buf[2] = high_direction; - - if ((ft2232_write(buf, 3, &bytes_written) != ERROR_OK) - || (bytes_written != 3)) + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize Signalyzer-H layout"); return ERROR_JTAG_INIT_FAILED; @@ -3896,20 +4450,13 @@ static void signalyzer_h_blink(void) *******************************************************************/ 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)) + /* initialize low byte for jtag */ + if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'ktlink' layout"); return ERROR_JTAG_INIT_FAILED; @@ -3941,13 +4488,8 @@ static int ktlink_init(void) 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)) + /* initialize high byte for jtag */ + if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK) { LOG_ERROR("couldn't initialize FT2232 with 'ktlink' layout"); return ERROR_JTAG_INIT_FAILED; @@ -3993,10 +4535,7 @@ static void ktlink_reset(int trst, int srst) static void ktlink_blink(void) { /* LED connected to ACBUS7 */ - if (high_output & 0x80) - high_output &= 0x7F; - else - high_output |= 0x80; + high_output ^= 0x80; buffer_write(0x82); // command "set data bits high byte" buffer_write(high_output); @@ -4045,7 +4584,9 @@ static const struct command_registration ft2232_command_handlers[] = { struct jtag_interface ft2232_interface = { .name = "ft2232", + .supported = DEBUG_CAP_TMS_SEQ, .commands = ft2232_command_handlers, + .transports = jtag_only, .init = ft2232_init, .quit = ft2232_quit,