X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fft2232.c;h=1ac61abb705b0890f7c8ec36786abf3d83c764d3;hb=e66f9aaba94e232f87c725f2fce98cfb3f92679f;hp=44b0e6a8dca6d216304cc16920f36a5a32fcb586;hpb=290e01c62afdfd5f6eb76a4caef266344510f2c0;p=openocd.git diff --git a/src/jtag/ft2232.c b/src/jtag/ft2232.c index 44b0e6a8dc..1ac61abb70 100644 --- a/src/jtag/ft2232.c +++ b/src/jtag/ft2232.c @@ -73,10 +73,12 @@ int ft2232_handle_device_desc_command(struct command_context_s *cmd_ctx, char *c int ft2232_handle_serial_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int ft2232_handle_layout_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int ft2232_handle_vid_pid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +int ft2232_handle_latency_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); char *ft2232_device_desc = NULL; char *ft2232_serial = NULL; char *ft2232_layout = NULL; +unsigned char ft2232_latency = 2; #define MAX_USB_IDS 8 /* vid = pid = 0 marks the end of the list */ @@ -95,17 +97,19 @@ typedef struct ft2232_layout_s int usbjtag_init(void); int jtagkey_init(void); int olimex_jtag_init(void); -int m5960_init(void); +int flyswatter_init(void); int turtle_init(void); int comstick_init(void); +int stm32stick_init(void); /* reset procedures for supported layouts */ void usbjtag_reset(int trst, int srst); void jtagkey_reset(int trst, int srst); void olimex_jtag_reset(int trst, int srst); -void m5960_reset(int trst, int srst); +void flyswatter_reset(int trst, int srst); void turtle_reset(int trst, int srst); void comstick_reset(int trst, int srst); +void stm32stick_reset(int trst, int srst); /* blink procedures for layouts that support a blinking led */ void olimex_jtag_blink(void); @@ -120,9 +124,10 @@ ft2232_layout_t ft2232_layouts[] = {"signalyzer", usbjtag_init, usbjtag_reset, NULL}, {"evb_lm3s811", usbjtag_init, usbjtag_reset, NULL}, {"olimex-jtag", olimex_jtag_init, olimex_jtag_reset, olimex_jtag_blink}, - {"m5960", m5960_init, m5960_reset, NULL}, + {"flyswatter", flyswatter_init, flyswatter_reset, NULL}, {"turtelizer2", turtle_init, turtle_reset, turtle_jtag_blink}, {"comstick", comstick_init, comstick_reset, NULL}, + {"stm32stick", stm32stick_init, stm32stick_reset, NULL}, {NULL, NULL, NULL}, }; @@ -155,8 +160,6 @@ jtag_interface_t ft2232_interface = .execute_queue = ft2232_execute_queue, - .support_pathmove = 1, - .speed = ft2232_speed, .register_commands = ft2232_register_commands, .init = ft2232_init, @@ -247,7 +250,7 @@ int ft2232_speed(int speed) u32 bytes_written; buf[0] = 0x86; /* command "set divisor" */ - buf[1] = speed & 0xff; /* valueL (0=6MHz, 1=3MHz, 2=1.5MHz, ...*/ + buf[1] = speed & 0xff; /* valueL (0=6MHz, 1=3MHz, 2=2.0MHz, ...*/ buf[2] = (speed >> 8) & 0xff; /* valueH */ DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]); @@ -256,6 +259,8 @@ int ft2232_speed(int speed) ERROR("couldn't set FT2232 TCK speed"); return retval; } + + jtag_speed = speed; return ERROR_OK; } @@ -270,6 +275,8 @@ int ft2232_register_commands(struct command_context_s *cmd_ctx) COMMAND_CONFIG, NULL); register_command(cmd_ctx, NULL, "ft2232_vid_pid", ft2232_handle_vid_pid_command, COMMAND_CONFIG, NULL); + register_command(cmd_ctx, NULL, "ft2232_latency", ft2232_handle_latency_command, + COMMAND_CONFIG, NULL); return ERROR_OK; } @@ -452,12 +459,14 @@ void ft2232_add_pathmove(pathmove_command_t *cmd) tms_byte = 0x0; int bit_count = 0; + int num_states_batch = num_states > 7 ? 7 : num_states; + /* command "Clock Data to TMS/CS Pin (no Read)" */ BUFFER_ADD = 0x4b; /* number of states remaining */ - BUFFER_ADD = (num_states % 7) - 1; + BUFFER_ADD = num_states_batch - 1; - while (num_states % 7) + while (num_states_batch--) { if (tap_transitions[cur_state].low == cmd->path[state_count]) buf_set_u32(&tms_byte, bit_count++, 1, 0x0); @@ -504,7 +513,7 @@ void ft2232_add_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size BUFFER_ADD = TAP_MOVE(cur_state, TAP_SD); cur_state = TAP_SD; } - //DEBUG("added TMS scan (no read)"); + /* DEBUG("added TMS scan (no read)"); */ } /* add command for complete bytes */ @@ -515,19 +524,19 @@ void ft2232_add_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size { /* Clock Data Bytes In and Out LSB First */ BUFFER_ADD = 0x39; - //DEBUG("added TDI bytes (io %i)", num_bytes); + /* DEBUG("added TDI bytes (io %i)", num_bytes); */ } else if (type == SCAN_OUT) { /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */ BUFFER_ADD = 0x19; - //DEBUG("added TDI bytes (o)"); + /* DEBUG("added TDI bytes (o)"); */ } else if (type == SCAN_IN) { /* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */ BUFFER_ADD = 0x28; - //DEBUG("added TDI bytes (i %i)", num_bytes); + /* DEBUG("added TDI bytes (i %i)", num_bytes); */ } thisrun_bytes = (num_bytes > 65537) ? 65536 : (num_bytes - 1); num_bytes -= thisrun_bytes; @@ -562,19 +571,19 @@ void ft2232_add_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size { /* Clock Data Bits In and Out LSB First */ BUFFER_ADD = 0x3b; - //DEBUG("added TDI bits (io) %i", bits_left - 1); + /* DEBUG("added TDI bits (io) %i", bits_left - 1); */ } else if (type == SCAN_OUT) { /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */ BUFFER_ADD = 0x1b; - //DEBUG("added TDI bits (o)"); + /* DEBUG("added TDI bits (o)"); */ } else if (type == SCAN_IN) { /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */ BUFFER_ADD = 0x2a; - //DEBUG("added TDI bits (i %i)", bits_left - 1); + /* DEBUG("added TDI bits (i %i)", bits_left - 1); */ } BUFFER_ADD = bits_left - 2; if (type != SCAN_IN) @@ -588,19 +597,19 @@ void ft2232_add_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size { /* Clock Data Bits In and Out LSB First */ BUFFER_ADD = 0x3b; - //DEBUG("added TDI bits (io) %i", bits_left - 1); + /* DEBUG("added TDI bits (io) %i", bits_left - 1); */ } else if (type == SCAN_OUT) { /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */ BUFFER_ADD = 0x1b; - //DEBUG("added TDI bits (o)"); + /* DEBUG("added TDI bits (o)"); */ } else if (type == SCAN_IN) { /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */ BUFFER_ADD = 0x2a; - //DEBUG("added TDI bits (i %i)", bits_left - 1); + /* DEBUG("added TDI bits (i %i)", bits_left - 1); */ } BUFFER_ADD = 0x0; BUFFER_ADD = last_bit; @@ -612,13 +621,13 @@ void ft2232_add_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size { /* Clock Data to TMS/CS Pin with Read */ BUFFER_ADD = 0x6b; - //DEBUG("added TMS scan (read)"); + /* DEBUG("added TMS scan (read)"); */ } else { /* Clock Data to TMS/CS Pin (no Read) */ BUFFER_ADD = 0x4b; - //DEBUG("added TMS scan (no read)"); + /* DEBUG("added TMS scan (no read)"); */ } BUFFER_ADD = 0x6; BUFFER_ADD = TAP_MOVE(cur_state, end_state) | (last_bit << 7); @@ -673,19 +682,19 @@ int ft2232_large_scan(scan_command_t *cmd, enum scan_type type, u8 *buffer, int { /* Clock Data Bytes In and Out LSB First */ BUFFER_ADD = 0x39; - //DEBUG("added TDI bytes (io %i)", num_bytes); + /* DEBUG("added TDI bytes (io %i)", num_bytes); */ } else if (type == SCAN_OUT) { /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */ BUFFER_ADD = 0x19; - //DEBUG("added TDI bytes (o)"); + /* DEBUG("added TDI bytes (o)"); */ } else if (type == SCAN_IN) { /* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */ BUFFER_ADD = 0x28; - //DEBUG("added TDI bytes (i %i)", num_bytes); + /* DEBUG("added TDI bytes (i %i)", num_bytes); */ } thisrun_bytes = (num_bytes > 65537) ? 65536 : (num_bytes - 1); thisrun_read = thisrun_bytes; @@ -742,19 +751,19 @@ int ft2232_large_scan(scan_command_t *cmd, enum scan_type type, u8 *buffer, int { /* Clock Data Bits In and Out LSB First */ BUFFER_ADD = 0x3b; - //DEBUG("added TDI bits (io) %i", bits_left - 1); + /* DEBUG("added TDI bits (io) %i", bits_left - 1); */ } else if (type == SCAN_OUT) { /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */ BUFFER_ADD = 0x1b; - //DEBUG("added TDI bits (o)"); + /* DEBUG("added TDI bits (o)"); */ } else if (type == SCAN_IN) { /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */ BUFFER_ADD = 0x2a; - //DEBUG("added TDI bits (i %i)", bits_left - 1); + /* DEBUG("added TDI bits (i %i)", bits_left - 1); */ } BUFFER_ADD = bits_left - 2; if (type != SCAN_IN) @@ -770,19 +779,19 @@ int ft2232_large_scan(scan_command_t *cmd, enum scan_type type, u8 *buffer, int { /* Clock Data Bits In and Out LSB First */ BUFFER_ADD = 0x3b; - //DEBUG("added TDI bits (io) %i", bits_left - 1); + /* DEBUG("added TDI bits (io) %i", bits_left - 1); */ } else if (type == SCAN_OUT) { /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */ BUFFER_ADD = 0x1b; - //DEBUG("added TDI bits (o)"); + /* DEBUG("added TDI bits (o)"); */ } else if (type == SCAN_IN) { /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */ BUFFER_ADD = 0x2a; - //DEBUG("added TDI bits (i %i)", bits_left - 1); + /* DEBUG("added TDI bits (i %i)", bits_left - 1); */ } BUFFER_ADD = 0x0; BUFFER_ADD = last_bit; @@ -794,13 +803,13 @@ int ft2232_large_scan(scan_command_t *cmd, enum scan_type type, u8 *buffer, int { /* Clock Data to TMS/CS Pin with Read */ BUFFER_ADD = 0x6b; - //DEBUG("added TMS scan (read)"); + /* DEBUG("added TMS scan (read)"); */ } else { /* Clock Data to TMS/CS Pin (no Read) */ BUFFER_ADD = 0x4b; - //DEBUG("added TMS scan (no read)"); + /* DEBUG("added TMS scan (no read)"); */ } BUFFER_ADD = 0x6; BUFFER_ADD = TAP_MOVE(cur_state, end_state) | (last_bit << 7); @@ -872,7 +881,7 @@ int ft2232_predict_scan_in(int scan_size, enum scan_type type) predicted_size += 1; } - //DEBUG("scan_size: %i, predicted_size: %i", scan_size, predicted_size); + /* DEBUG("scan_size: %i, predicted_size: %i", scan_size, predicted_size); */ return predicted_size; } @@ -991,7 +1000,7 @@ void olimex_jtag_reset(int trst, int srst) DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction); } -void m5960_reset(int trst, int srst) +void flyswatter_reset(int trst, int srst) { if (trst == 1) { @@ -1067,6 +1076,39 @@ void comstick_reset(int trst, int srst) DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction); } +void stm32stick_reset(int trst, int srst) +{ + if (trst == 1) + { + cur_state = TAP_TLR; + high_output &= ~nTRST; + } + else if (trst == 0) + { + high_output |= nTRST; + } + + if (srst == 1) + { + low_output &= ~nSRST; + } + else if (srst == 0) + { + low_output |= nSRST; + } + + /* command "set data bits low byte" */ + BUFFER_ADD = 0x80; + BUFFER_ADD = low_output; + BUFFER_ADD = low_direction; + + /* command "set data bits high byte" */ + BUFFER_ADD = 0x82; + BUFFER_ADD = high_output; + BUFFER_ADD = high_direction; + DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction); +} + int ft2232_execute_queue() { jtag_command_t *cmd = jtag_command_queue; /* currently processed command */ @@ -1156,7 +1198,7 @@ int ft2232_execute_queue() BUFFER_ADD = 0x0; cur_state = TAP_RTI; i -= (i > 7) ? 7 : i; - //DEBUG("added TMS scan (no read)"); + /* DEBUG("added TMS scan (no read)"); */ } if (cmd->cmd.runtest->end_state != -1) ft2232_end_state(cmd->cmd.runtest->end_state); @@ -1169,7 +1211,7 @@ int ft2232_execute_queue() /* TMS data bits */ BUFFER_ADD = TAP_MOVE(cur_state, end_state); cur_state = end_state; - //DEBUG("added TMS scan (no read)"); + /* DEBUG("added TMS scan (no read)"); */ } require_send = 1; #ifdef _DEBUG_JTAG_IO_ @@ -1194,7 +1236,7 @@ int ft2232_execute_queue() BUFFER_ADD = 0x6; /* TMS data bits */ BUFFER_ADD = TAP_MOVE(cur_state, end_state); - //DEBUG("added TMS scan (no read)"); + /* DEBUG("added TMS scan (no read)"); */ cur_state = end_state; require_send = 1; #ifdef _DEBUG_JTAG_IO_ @@ -1248,7 +1290,7 @@ int ft2232_execute_queue() first_unsent = cmd; } ft2232_expect_read += ft2232_predict_scan_in(scan_size, type); - //DEBUG("new read size: %i", ft2232_expect_read); + /* DEBUG("new read size: %i", ft2232_expect_read); */ if (cmd->cmd.scan->end_state != -1) ft2232_end_state(cmd->cmd.scan->end_state); ft2232_add_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); @@ -1362,12 +1404,12 @@ static int ft2232_init_ftd2xx(u16 vid, u16 pid, int more, int *try_more) } else { - printf("ListDevices: NONE\n"); + ERROR("ListDevices: NONE\n"); } return ERROR_JTAG_INIT_FAILED; } - if ((status = FT_SetLatencyTimer(ftdih, 2)) != FT_OK) + if ((status = FT_SetLatencyTimer(ftdih, ft2232_latency)) != FT_OK) { ERROR("unable to set latency timer: %lu", status); return ERROR_JTAG_INIT_FAILED; @@ -1447,7 +1489,7 @@ static int ft2232_init_libftdi(u16 vid, u16 pid, int more, int *try_more) return ERROR_JTAG_INIT_FAILED; } - if (ftdi_set_latency_timer(&ftdic, 2) < 0) + if (ftdi_set_latency_timer(&ftdic, ft2232_latency) < 0) { ERROR("unable to set latency timer"); return ERROR_JTAG_INIT_FAILED; @@ -1781,7 +1823,7 @@ int olimex_jtag_init(void) return ERROR_OK; } -int m5960_init(void) +int flyswatter_init(void) { u8 buf[3]; u32 bytes_written; @@ -1797,7 +1839,7 @@ int m5960_init(void) if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3)) { - ERROR("couldn't initialize FT2232 with 'm5960' layout"); + ERROR("couldn't initialize FT2232 with 'flyswatter' layout"); return ERROR_JTAG_INIT_FAILED; } @@ -1820,7 +1862,7 @@ int m5960_init(void) if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3)) { - ERROR("couldn't initialize FT2232 with 'm5960' layout"); + ERROR("couldn't initialize FT2232 with 'flyswatter' layout"); return ERROR_JTAG_INIT_FAILED; } @@ -1910,6 +1952,49 @@ int comstick_init(void) return ERROR_OK; } +int stm32stick_init(void) +{ + u8 buf[3]; + u32 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 */ + 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)) + { + ERROR("couldn't initialize FT2232 with 'stm32stick' layout"); + return ERROR_JTAG_INIT_FAILED; + } + + nTRST = 0x01; + nTRSTnOE = 0x00; /* no output enable for nTRST */ + nSRST = 0x80; + nSRSTnOE = 0x00; /* no output enable for nSRST */ + + 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; + 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)) + { + ERROR("couldn't initialize FT2232 with 'stm32stick' layout"); + return ERROR_JTAG_INIT_FAILED; + } + + return ERROR_OK; +} + void olimex_jtag_blink(void) { /* Olimex ARM-USB-OCD has a LED connected to ACBUS3 @@ -1966,6 +2051,7 @@ int ft2232_quit(void) #endif free(ft2232_buffer); + ft2232_buffer = NULL; return ERROR_OK; } @@ -2037,3 +2123,19 @@ int ft2232_handle_vid_pid_command(struct command_context_s *cmd_ctx, char *cmd, return ERROR_OK; } + +int ft2232_handle_latency_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +{ + if (argc == 1) + { + ft2232_latency = atoi(args[0]); + } + else + { + ERROR("expected exactly one argument to ft2232_latency "); + } + + return ERROR_OK; +} + +