X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fft2232.c;h=cee55e0cf933053c05623b3d4bb8bbcc39b58af2;hp=839976faa1aee37b41673a472144030615c27faf;hb=ab3bdfb2cb7b0c16800195951e4ee549cf8e86a5;hpb=7035b37e71c8c8805a2148c7c454537b903b0d51;ds=sidebyside diff --git a/src/jtag/ft2232.c b/src/jtag/ft2232.c index 839976faa1..cee55e0cf9 100644 --- a/src/jtag/ft2232.c +++ b/src/jtag/ft2232.c @@ -71,6 +71,17 @@ /* 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 }; @@ -79,20 +90,6 @@ #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, @@ -103,7 +100,7 @@ static int ft2232_handle_latency_command(struct command_context_s* cmd_ctx, char * * @returns ERROR_OK on success, or ERROR_JTAG_QUEUE_FAILED on failure. */ -static int ft2232_stableclocks(int num_cycles, jtag_command_t* cmd); +static int ft2232_stableclocks(int num_cycles, struct jtag_command* cmd); static char * ft2232_device_desc_A = NULL; static char* ft2232_device_desc = NULL; @@ -117,13 +114,12 @@ static unsigned ft2232_max_tck = FTDI_2232C_MAX_TCK; static uint16_t ft2232_vid[MAX_USB_IDS + 1] = { 0x0403, 0 }; static uint16_t ft2232_pid[MAX_USB_IDS + 1] = { 0x6010, 0 }; -typedef struct ft2232_layout_s -{ +struct ft2232_layout { char* name; int (*init)(void); void (*reset)(int trst, int srst); void (*blink)(void); -} ft2232_layout_t; +}; /* init procedures for supported layouts */ static int usbjtag_init(void); @@ -137,6 +133,8 @@ 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_h_init(void); +static int ktlink_init(void); /* reset procedures for supported layouts */ static void usbjtag_reset(int trst, int srst); @@ -149,13 +147,17 @@ static void stm32stick_reset(int trst, int srst); 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[] = +static const struct ft2232_layout ft2232_layouts[] = { { "usbjtag", usbjtag_init, usbjtag_reset, NULL }, { "jtagkey", jtagkey_init, jtagkey_reset, NULL }, @@ -173,12 +175,14 @@ static const ft2232_layout_t ft2232_layouts[] = { "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 }, }; static uint8_t nTRST, nTRSTnOE, nSRST, nSRSTnOE; -static const ft2232_layout_t *layout; +static const struct ft2232_layout *layout; static uint8_t low_output = 0x0; static uint8_t low_direction = 0x0; static uint8_t high_output = 0x0; @@ -192,7 +196,7 @@ static struct ftdi_context ftdic; static enum ftdi_chip_type ftdi_device; #endif -static jtag_command_t* first_unsent; /* next command that has to be sent */ +static struct jtag_command* first_unsent; /* next command that has to be sent */ static int require_send; /* http://urjtag.wiki.sourceforge.net/Cable + FT2232 says: @@ -330,18 +334,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 @@ -396,7 +388,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--) @@ -414,9 +406,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; } @@ -570,21 +563,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)) @@ -639,9 +617,9 @@ static void ft2232_debug_dump_buffer(void) LOG_DEBUG("%s", line); } -static int ft2232_send_and_recv(jtag_command_t* first, jtag_command_t* last) +static int ft2232_send_and_recv(struct jtag_command* first, struct jtag_command* last) { - jtag_command_t* cmd; + struct jtag_command* cmd; uint8_t* buffer; int scan_size; enum scan_type type; @@ -675,7 +653,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_ @@ -705,16 +684,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 } @@ -972,7 +956,7 @@ static void ft2232_add_scan(bool ir_scan, enum scan_type type, uint8_t* buffer, } } -static int ft2232_large_scan(scan_command_t* cmd, enum scan_type type, uint8_t* buffer, int scan_size) +static int ft2232_large_scan(struct scan_command* cmd, enum scan_type type, uint8_t* buffer, int scan_size) { int num_bytes = (scan_size + 7) / 8; int bits_left = scan_size; @@ -1507,7 +1491,7 @@ 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 int ft2232_execute_runtest(jtag_command_t *cmd) +static int ft2232_execute_runtest(struct jtag_command *cmd) { int retval; int i; @@ -1552,7 +1536,6 @@ static int ft2232_execute_runtest(jtag_command_t *cmd) /* TMS data bits */ buffer_write(0x0); - tap_set_state(TAP_IDLE); i -= (i > 7) ? 7 : i; /* LOG_DEBUG("added TMS scan (no read)"); */ @@ -1572,7 +1555,7 @@ static int ft2232_execute_runtest(jtag_command_t *cmd) return retval; } -static int ft2232_execute_statemove(jtag_command_t *cmd) +static int ft2232_execute_statemove(struct jtag_command *cmd) { int predicted_size = 0; int retval = ERROR_OK; @@ -1609,7 +1592,7 @@ static int ft2232_execute_statemove(jtag_command_t *cmd) return retval; } -static int ft2232_execute_pathmove(jtag_command_t *cmd) +static int ft2232_execute_pathmove(struct jtag_command *cmd) { int predicted_size = 0; int retval = ERROR_OK; @@ -1638,7 +1621,7 @@ static int ft2232_execute_pathmove(jtag_command_t *cmd) return retval; } -static int ft2232_execute_scan(jtag_command_t *cmd) +static int ft2232_execute_scan(struct jtag_command *cmd) { uint8_t* buffer; int scan_size; /* size of IR or DR scan */ @@ -1693,7 +1676,7 @@ static int ft2232_execute_scan(jtag_command_t *cmd) } -static int ft2232_execute_reset(jtag_command_t *cmd) +static int ft2232_execute_reset(struct jtag_command *cmd) { int retval; int predicted_size = 0; @@ -1725,24 +1708,24 @@ static int ft2232_execute_reset(jtag_command_t *cmd) return retval; } -static int ft2232_execute_sleep(jtag_command_t *cmd) +static int ft2232_execute_sleep(struct jtag_command *cmd) { int retval; retval = ERROR_OK; - DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us); + DEBUG_JTAG_IO("sleep %" PRIi32, cmd->cmd.sleep->us); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) retval = ERROR_JTAG_QUEUE_FAILED; first_unsent = cmd->next; jtag_sleep(cmd->cmd.sleep->us); - DEBUG_JTAG_IO("sleep %i usec while in %s", + DEBUG_JTAG_IO("sleep %" PRIi32 " usec while in %s", cmd->cmd.sleep->us, tap_state_name(tap_get_state())); return retval; } -static int ft2232_execute_stableclocks(jtag_command_t *cmd) +static int ft2232_execute_stableclocks(struct jtag_command *cmd) { int retval; retval = ERROR_OK; @@ -1758,7 +1741,7 @@ static int ft2232_execute_stableclocks(jtag_command_t *cmd) return retval; } -static int ft2232_execute_command(jtag_command_t *cmd) +static int ft2232_execute_command(struct jtag_command *cmd) { int retval; retval = ERROR_OK; @@ -1779,9 +1762,9 @@ 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 */ + struct jtag_command* cmd = jtag_command_queue; /* currently processed command */ int retval; first_unsent = cmd; /* next command that has to be sent */ @@ -2076,7 +2059,7 @@ static int ft2232_init(void) uint8_t buf[1]; int retval; uint32_t bytes_written; - const ft2232_layout_t* cur_layout = ft2232_layouts; + const struct ft2232_layout* cur_layout = ft2232_layouts; int i; if (tap_get_tms_path_len(TAP_IRPAUSE,TAP_IRPAUSE) == 7) @@ -2814,7 +2797,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]; @@ -2848,7 +2831,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) { @@ -2862,7 +2845,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; @@ -2873,7 +2856,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) { @@ -2890,16 +2873,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]); } /* @@ -2908,10 +2886,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) { @@ -2925,7 +2903,7 @@ static int ft2232_handle_latency_command(struct command_context_s* cmd_ctx, char return ERROR_OK; } -static int ft2232_stableclocks(int num_cycles, jtag_command_t* cmd) +static int ft2232_stableclocks(int num_cycles, struct jtag_command* cmd) { int retval = 0; @@ -3071,3 +3049,956 @@ static void icebear_jtag_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); } + +/* --------------------------------------------------------------------- + * Support for Signalyzer H2 and Signalyzer H4 + * JTAG adapter from Xverve Technologies Inc. + * http://www.signalyzer.com or http://www.xverve.com + * + * Author: Oleg Seiljus, oleg@signalyzer.com + */ +static unsigned char signalyzer_h_side; +static unsigned int signalyzer_h_adapter_type; + +static int signalyzer_h_ctrl_write(int address, unsigned short value); + +#if BUILD_FT2232_FTD2XX == 1 +static int signalyzer_h_ctrl_read(int address, unsigned short *value); +#endif + +#define SIGNALYZER_COMMAND_ADDR 128 +#define SIGNALYZER_DATA_BUFFER_ADDR 129 + +#define SIGNALYZER_COMMAND_VERSION 0x41 +#define SIGNALYZER_COMMAND_RESET 0x42 +#define SIGNALYZER_COMMAND_POWERCONTROL_GET 0x50 +#define SIGNALYZER_COMMAND_POWERCONTROL_SET 0x51 +#define SIGNALYZER_COMMAND_PWM_SET 0x52 +#define SIGNALYZER_COMMAND_LED_SET 0x53 +#define SIGNALYZER_COMMAND_ADC 0x54 +#define SIGNALYZER_COMMAND_GPIO_STATE 0x55 +#define SIGNALYZER_COMMAND_GPIO_MODE 0x56 +#define SIGNALYZER_COMMAND_GPIO_PORT 0x57 +#define SIGNALYZER_COMMAND_I2C 0x58 + +#define SIGNALYZER_CHAN_A 1 +#define SIGNALYZER_CHAN_B 2 +/* LEDS use channel C */ +#define SIGNALYZER_CHAN_C 4 + +#define SIGNALYZER_LED_GREEN 1 +#define SIGNALYZER_LED_RED 2 + +#define SIGNALYZER_MODULE_TYPE_EM_LT16_A 0x0301 +#define SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG 0x0302 +#define SIGNALYZER_MODULE_TYPE_EM_JTAG 0x0303 +#define SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG_P 0x0304 +#define SIGNALYZER_MODULE_TYPE_EM_JTAG_P 0x0305 + + +static int signalyzer_h_ctrl_write(int address, unsigned short value) +{ +#if BUILD_FT2232_FTD2XX == 1 + return FT_WriteEE(ftdih, address, value); +#elif BUILD_FT2232_LIBFTDI == 1 + return 0; +#endif +} + +#if BUILD_FT2232_FTD2XX == 1 +static int signalyzer_h_ctrl_read(int address, unsigned short *value) +{ + return FT_ReadEE(ftdih, address, value); +} +#endif + +static int signalyzer_h_led_set(unsigned char channel, unsigned char led, + int on_time_ms, int off_time_ms, unsigned char cycles) +{ + unsigned char on_time; + unsigned char off_time; + + if (on_time_ms < 0xFFFF) + on_time = (unsigned char)(on_time_ms / 62); + else + on_time = 0xFF; + + off_time = (unsigned char)(off_time_ms / 62); + +#if BUILD_FT2232_FTD2XX == 1 + FT_STATUS status; + + 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); + return ERROR_JTAG_DEVICE_ERROR; + } + + if ((status = signalyzer_h_ctrl_write( + (SIGNALYZER_DATA_BUFFER_ADDR + 1), + ((uint32_t)(on_time << 8) | off_time))) != FT_OK) + { + LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", status); + return ERROR_JTAG_DEVICE_ERROR; + } + + if ((status = signalyzer_h_ctrl_write( + (SIGNALYZER_DATA_BUFFER_ADDR + 2), + ((uint32_t)cycles))) != FT_OK) + { + LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", 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); + return ERROR_JTAG_DEVICE_ERROR; + } + + return ERROR_OK; +#elif BUILD_FT2232_LIBFTDI == 1 + int retval; + + if ((retval = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR, + ((uint32_t)(channel << 8) | led))) < 0) + { + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftdi_get_error_string(&ftdic)); + return ERROR_JTAG_DEVICE_ERROR; + } + + if ((retval = signalyzer_h_ctrl_write( + (SIGNALYZER_DATA_BUFFER_ADDR + 1), + ((uint32_t)(on_time << 8) | off_time))) < 0) + { + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftdi_get_error_string(&ftdic)); + return ERROR_JTAG_DEVICE_ERROR; + } + + if ((retval = signalyzer_h_ctrl_write( + (SIGNALYZER_DATA_BUFFER_ADDR + 2), + (uint32_t)cycles)) < 0) + { + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftdi_get_error_string(&ftdic)); + return ERROR_JTAG_DEVICE_ERROR; + } + + if ((retval = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, + SIGNALYZER_COMMAND_LED_SET)) < 0) + { + LOG_ERROR("signalyzer_h_ctrl_write returned: %s", + ftdi_get_error_string(&ftdic)); + return ERROR_JTAG_DEVICE_ERROR; + } + + return ERROR_OK; +#endif +} + +static int signalyzer_h_init(void) +{ +#if BUILD_FT2232_FTD2XX == 1 + FT_STATUS status; + int i; +#endif + + 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, + 0xFFFF, 0x00, 0x00); + + /* determine what channel config wants to open + * TODO: change me... current implementation is made to work + * with openocd description parsing. + */ + end_of_desc = strrchr(ft2232_device_desc, 0x00); + + if (end_of_desc) + { + signalyzer_h_side = *(end_of_desc - 1); + if (signalyzer_h_side == 'B') + signalyzer_h_side = SIGNALYZER_CHAN_B; + else + signalyzer_h_side = SIGNALYZER_CHAN_A; + } + else + { + LOG_ERROR("No Channel was specified"); + return ERROR_FAIL; + } + + signalyzer_h_led_set(signalyzer_h_side, SIGNALYZER_LED_GREEN, + 1000, 1000, 0xFF); + +#if BUILD_FT2232_FTD2XX == 1 + /* read signalyzer versionining information */ + if ((status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, + SIGNALYZER_COMMAND_VERSION)) != FT_OK) + { + LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", status); + return ERROR_JTAG_DEVICE_ERROR; + } + + for (i = 0; i < 10; i++) + { + if ((status = signalyzer_h_ctrl_read( + (SIGNALYZER_DATA_BUFFER_ADDR + i), + &read_buf[i])) != FT_OK) + { + LOG_ERROR("signalyzer_h_ctrl_read returned: %lu", + status); + return ERROR_JTAG_DEVICE_ERROR; + } + } + + LOG_INFO("Signalyzer: ID info: { %.4x %.4x %.4x %.4x %.4x %.4x %.4x }", + read_buf[0], read_buf[1], read_buf[2], read_buf[3], + read_buf[4], read_buf[5], read_buf[6]); + + /* set gpio register */ + 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); + 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); + 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); + return ERROR_JTAG_DEVICE_ERROR; + } + + /* read adapter type information */ + 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); + 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); + 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); + 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); + return ERROR_JTAG_DEVICE_ERROR; + } + + usleep(100000); + + if ((status = signalyzer_h_ctrl_read(SIGNALYZER_COMMAND_ADDR, + &read_buf[0])) != FT_OK) + { + LOG_ERROR("signalyzer_h_ctrl_read returned: %lu", status); + return ERROR_JTAG_DEVICE_ERROR; + } + + if (read_buf[0] != 0x0498) + signalyzer_h_adapter_type = 0x0000; + else + { + for (i = 0; i < 4; i++) + { + if ((status = signalyzer_h_ctrl_read( + (SIGNALYZER_DATA_BUFFER_ADDR + i), + &read_buf[i])) != FT_OK) + { + LOG_ERROR("signalyzer_h_ctrl_read returned: %lu", + status); + return ERROR_JTAG_DEVICE_ERROR; + } + } + + signalyzer_h_adapter_type = read_buf[0]; + } + +#elif BUILD_FT2232_LIBFTDI == 1 + /* currently libftdi does not allow reading individual eeprom + * locations, therefore adapter type cannot be detected. + * override with most common type + */ + signalyzer_h_adapter_type = SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG; +#endif + + enum reset_types jtag_reset_config = jtag_get_reset_config(); + + /* ADAPTOR: EM_LT16_A */ + if (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_LT16_A) + { + LOG_INFO("Signalyzer: EM-LT (16-channel level translator) " + "detected. (HW: %2x).", (read_buf[1] >> 8)); + + nTRST = 0x10; + nTRSTnOE = 0x10; + nSRST = 0x20; + nSRSTnOE = 0x20; + + low_output = 0x08; + low_direction = 0x1b; + + high_output = 0x0; + high_direction = 0x0; + + if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) + { + low_direction &= ~nTRSTnOE; /* nTRST input */ + low_output &= ~nTRST; /* nTRST = 0 */ + } + else + { + low_direction |= nTRSTnOE; /* nTRST output */ + low_output |= nTRST; /* nTRST = 1 */ + } + + if (jtag_reset_config & RESET_SRST_PUSH_PULL) + { + low_direction |= nSRSTnOE; /* nSRST output */ + low_output |= nSRST; /* nSRST = 1 */ + } + else + { + low_direction &= ~nSRSTnOE; /* nSRST input */ + low_output &= ~nSRST; /* nSRST = 0 */ + } + +#if BUILD_FT2232_FTD2XX == 1 + /* enable power to the module */ + 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); + 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); + return ERROR_JTAG_DEVICE_ERROR; + } + + /* set gpio mode register */ + 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); + return ERROR_JTAG_DEVICE_ERROR; + } + + if ((status = signalyzer_h_ctrl_write( + SIGNALYZER_DATA_BUFFER_ADDR + 1, 0x0000)) + != FT_OK) + { + LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", + 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); + return ERROR_JTAG_DEVICE_ERROR; + } + + /* set gpio register */ + 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); + return ERROR_JTAG_DEVICE_ERROR; + } + + if ((status = signalyzer_h_ctrl_write( + SIGNALYZER_DATA_BUFFER_ADDR + 1, 0x4040)) + != FT_OK) + { + LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", + 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); + return ERROR_JTAG_DEVICE_ERROR; + } +#endif + } + + /* ADAPTOR: EM_ARM_JTAG, EM_ARM_JTAG_P, EM_JTAG, EM_JTAG_P */ + else if ((signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG) || + (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG_P) || + (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_JTAG) || + (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_JTAG_P)) + { + if (signalyzer_h_adapter_type + == SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG) + LOG_INFO("Signalyzer: EM-ARM-JTAG (ARM JTAG) " + "detected. (HW: %2x).", (read_buf[1] >> 8)); + else if (signalyzer_h_adapter_type + == SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG_P) + LOG_INFO("Signalyzer: EM-ARM-JTAG_P " + "(ARM JTAG with PSU) detected. (HW: %2x).", + (read_buf[1] >> 8)); + else if (signalyzer_h_adapter_type + == SIGNALYZER_MODULE_TYPE_EM_JTAG) + LOG_INFO("Signalyzer: EM-JTAG (Generic JTAG) " + "detected. (HW: %2x).", (read_buf[1] >> 8)); + else if (signalyzer_h_adapter_type + == SIGNALYZER_MODULE_TYPE_EM_JTAG_P) + LOG_INFO("Signalyzer: EM-JTAG-P " + "(Generic JTAG with PSU) detected. (HW: %2x).", + (read_buf[1] >> 8)); + + nTRST = 0x02; + nTRSTnOE = 0x04; + nSRST = 0x08; + nSRSTnOE = 0x10; + + low_output = 0x08; + low_direction = 0x1b; + + high_output = 0x0; + high_direction = 0x1f; + + 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; + } + +#if BUILD_FT2232_FTD2XX == 1 + /* enable power to the module */ + 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); + 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); + return ERROR_JTAG_DEVICE_ERROR; + } + + /* set gpio mode register (IO_16 and IO_17 set as analog + * inputs, other is gpio) + */ + 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); + return ERROR_JTAG_DEVICE_ERROR; + } + + if ((status = signalyzer_h_ctrl_write( + SIGNALYZER_DATA_BUFFER_ADDR + 1, 0x0060)) + != FT_OK) + { + LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", + 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); + return ERROR_JTAG_DEVICE_ERROR; + } + + /* set gpio register (all inputs, for -P modules, + * PSU will be turned off) + */ + 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); + return ERROR_JTAG_DEVICE_ERROR; + } + + if ((status = signalyzer_h_ctrl_write( + SIGNALYZER_DATA_BUFFER_ADDR + 1, 0x0000)) + != FT_OK) + { + LOG_ERROR("signalyzer_h_ctrl_write returned: %lu", + 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); + return ERROR_JTAG_DEVICE_ERROR; + } +#endif + } + + else if (signalyzer_h_adapter_type == 0x0000) + { + LOG_INFO("Signalyzer: No external modules were detected."); + + nTRST = 0x10; + nTRSTnOE = 0x10; + nSRST = 0x20; + nSRSTnOE = 0x20; + + low_output = 0x08; + low_direction = 0x1b; + + high_output = 0x0; + high_direction = 0x0; + + if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) + { + low_direction &= ~nTRSTnOE; /* nTRST input */ + low_output &= ~nTRST; /* nTRST = 0 */ + } + else + { + low_direction |= nTRSTnOE; /* nTRST output */ + low_output |= nTRST; /* nTRST = 1 */ + } + + if (jtag_reset_config & RESET_SRST_PUSH_PULL) + { + low_direction |= nSRSTnOE; /* nSRST output */ + low_output |= nSRST; /* nSRST = 1 */ + } + else + { + low_direction &= ~nSRSTnOE; /* nSRST input */ + low_output &= ~nSRST; /* nSRST = 0 */ + } + } + else + { + LOG_ERROR("Unknown module type is detected: %.4x", + signalyzer_h_adapter_type); + return ERROR_JTAG_DEVICE_ERROR; + } + + /* 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)) + { + LOG_ERROR("couldn't initialize Signalyzer-H layout"); + return ERROR_JTAG_INIT_FAILED; + } + +#if BUILD_FT2232_FTD2XX == 1 + 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)) + { + LOG_ERROR("couldn't initialize Signalyzer-H layout"); + return ERROR_JTAG_INIT_FAILED; + } + } +#elif BUILD_FT2232_LIBFTDI == 1 + 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)) + { + LOG_ERROR("couldn't initialize Signalyzer-H layout"); + return ERROR_JTAG_INIT_FAILED; + } + } +#endif + return ERROR_OK; +} + +static void signalyzer_h_reset(int trst, int srst) +{ + enum reset_types jtag_reset_config = jtag_get_reset_config(); + + /* ADAPTOR: EM_LT16_A */ + if (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_LT16_A) + { + if (trst == 1) + { + if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) + /* switch to output pin (output is low) */ + low_direction |= nTRSTnOE; + else + /* switch output low */ + low_output &= ~nTRST; + } + else if (trst == 0) + { + if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) + /* switch to input pin (high-Z + internal + * and external pullup) */ + low_direction &= ~nTRSTnOE; + else + /* switch output high */ + low_output |= nTRST; + } + + if (srst == 1) + { + if (jtag_reset_config & RESET_SRST_PUSH_PULL) + /* switch output low */ + low_output &= ~nSRST; + else + /* switch to output pin (output is low) */ + low_direction |= nSRSTnOE; + } + else if (srst == 0) + { + if (jtag_reset_config & RESET_SRST_PUSH_PULL) + /* switch output high */ + low_output |= nSRST; + else + /* switch to input pin (high-Z) */ + low_direction &= ~nSRSTnOE; + } + + /* 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); + } + /* ADAPTOR: EM_ARM_JTAG, EM_ARM_JTAG_P, EM_JTAG, EM_JTAG_P */ + else if ((signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG) || + (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG_P) || + (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_JTAG) || + (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_JTAG_P)) + { + 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; + } + + /* command "set data bits high byte" */ + buffer_write(0x82); + buffer_write(high_output); + buffer_write(high_direction); + LOG_INFO("trst: %i, srst: %i, high_output: 0x%2.2x, " + "high_direction: 0x%2.2x", + trst, srst, high_output, high_direction); + } + else if (signalyzer_h_adapter_type == 0x0000) + { + if (trst == 1) + { + if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) + /* switch to output pin (output is low) */ + low_direction |= nTRSTnOE; + else + /* switch output low */ + low_output &= ~nTRST; + } + else if (trst == 0) + { + if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) + /* switch to input pin (high-Z + internal + * and external pullup) */ + low_direction &= ~nTRSTnOE; + else + /* switch output high */ + low_output |= nTRST; + } + + if (srst == 1) + { + if (jtag_reset_config & RESET_SRST_PUSH_PULL) + /* switch output low */ + low_output &= ~nSRST; + else + /* switch to output pin (output is low) */ + low_direction |= nSRSTnOE; + } + else if (srst == 0) + { + if (jtag_reset_config & RESET_SRST_PUSH_PULL) + /* switch output high */ + low_output |= nSRST; + else + /* switch to input pin (high-Z) */ + low_direction &= ~nSRSTnOE; + } + + /* 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 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* 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; +} + + +struct jtag_interface 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, + };