X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fft2232.c;h=b0c1c35c72af84f310981147acf896061c651f0a;hb=d6ed10a0023b8885c1ead022393eb5afe0208374;hp=2740c3be124da0c942aecc00a45bf50b24c96787;hpb=2585fc34200938fb3fa55a450ea37f68012aafa7;p=openocd.git diff --git a/src/jtag/ft2232.c b/src/jtag/ft2232.c index 2740c3be12..b0c1c35c72 100644 --- a/src/jtag/ft2232.c +++ b/src/jtag/ft2232.c @@ -2,6 +2,9 @@ * Copyright (C) 2004, 2006 by Dominic Rath * * Dominic.Rath@gmx.de * * * + * Copyright (C) 2008 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -61,6 +64,8 @@ int ft2232_execute_queue(void); int ft2232_speed(int speed); +int ft2232_speed_div(int speed, int *khz); +int ft2232_khz(int khz, int *jtag_speed); int ft2232_register_commands(struct command_context_s *cmd_ctx); int ft2232_init(void); int ft2232_quit(void); @@ -97,6 +102,7 @@ int flyswatter_init(void); int turtle_init(void); int comstick_init(void); int stm32stick_init(void); +int axm0432_jtag_init(void); /* reset procedures for supported layouts */ void usbjtag_reset(int trst, int srst); @@ -106,6 +112,7 @@ 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); +void axm0432_jtag_reset(int trst, int srst); /* blink procedures for layouts that support a blinking led */ void olimex_jtag_blink(void); @@ -124,6 +131,7 @@ ft2232_layout_t ft2232_layouts[] = {"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}, {NULL, NULL, NULL}, }; @@ -151,12 +159,11 @@ static int ft2232_expect_read = 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, @@ -256,7 +263,55 @@ int ft2232_speed(int speed) return retval; } - jtag_speed = speed; + return ERROR_OK; +} + +int ft2232_speed_div(int speed, int *khz) +{ + /* Take a look in the FT2232 manual, + * AN2232C-01 Command Processor for + * MPSSE and MCU Host Bus. Chapter 3.8 */ + + *khz = 6000 / (1+speed); + + return ERROR_OK; +} + +int ft2232_khz(int khz, int *jtag_speed) +{ + if (khz==0) + { + LOG_ERROR("RCLK not supported"); + return ERROR_FAIL; + } + /* Take a look in the FT2232 manual, + * AN2232C-01 Command Processor for + * MPSSE and MCU Host Bus. Chapter 3.8 + * + * We will calc here with a multiplier + * of 10 for better rounding later. */ + + /* Calc speed, (6000 / khz) - 1 */ + /* Use 65000 for better rounding */ + *jtag_speed = (60000 / khz) - 10; + + /* Add 0.9 for rounding */ + *jtag_speed += 9; + + /* Calc real speed */ + *jtag_speed = *jtag_speed / 10; + + /* Check if speed is greater than 0 */ + if (*jtag_speed < 0) + { + *jtag_speed = 0; + } + + /* Check max value */ + if (*jtag_speed > 0xFFFF) + { + *jtag_speed = 0xFFFF; + } return ERROR_OK; } @@ -264,15 +319,15 @@ int ft2232_speed(int speed) 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, NULL); + COMMAND_CONFIG, "the USB device description of the FTDI FT2232 device"); register_command(cmd_ctx, NULL, "ft2232_serial", ft2232_handle_serial_command, - COMMAND_CONFIG, NULL); + COMMAND_CONFIG, "the serial number of the FTDI FT2232 device"); register_command(cmd_ctx, NULL, "ft2232_layout", ft2232_handle_layout_command, - COMMAND_CONFIG, NULL); + 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, NULL); + 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, NULL); + COMMAND_CONFIG, "set the FT2232 latency timer to a new value"); return ERROR_OK; } @@ -358,7 +413,7 @@ int ft2232_send_and_recv(jtag_command_t *first, jtag_command_t *last) if ((retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written)) != ERROR_OK) { LOG_ERROR("couldn't write MPSSE commands to FT2232"); - exit(-1); + return retval; } #ifdef _DEBUG_USB_IO_ @@ -377,7 +432,7 @@ int ft2232_send_and_recv(jtag_command_t *first, jtag_command_t *last) if ((retval = ft2232_read(ft2232_buffer, ft2232_expect_read, &bytes_read)) != ERROR_OK) { LOG_ERROR("couldn't read from FT2232"); - exit(-1); + return retval; } #ifdef _DEBUG_USB_IO_ @@ -977,20 +1032,48 @@ void olimex_jtag_reset(int trst, int srst) high_output |= nTRST; } - if (srst == 1) - { - high_output |= nSRST; - } - else if (srst == 0) - { - high_output &= ~nSRST; - } - - /* command "set data bits high byte" */ - BUFFER_ADD = 0x82; - BUFFER_ADD = high_output; - BUFFER_ADD = high_direction; - LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction); + if (srst == 1) + { + high_output |= nSRST; + } + else if (srst == 0) + { + high_output &= ~nSRST; + } + + /* command "set data bits high byte" */ + BUFFER_ADD = 0x82; + BUFFER_ADD = high_output; + BUFFER_ADD = high_direction; + LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction); +} + +void axm0432_jtag_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) + { + high_output &= ~nSRST; + } + else if (srst == 0) + { + high_output |= nSRST; + } + + /* command "set data bits low byte" */ + BUFFER_ADD = 0x82; + BUFFER_ADD = high_output; + BUFFER_ADD = high_direction; + LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction); } void flyswatter_reset(int trst, int srst) @@ -1004,20 +1087,20 @@ void flyswatter_reset(int trst, int srst) low_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; - LOG_DEBUG("trst: %i, srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", trst, srst, low_output, low_direction); + 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; + LOG_DEBUG("trst: %i, srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", trst, srst, low_output, low_direction); } void turtle_reset(int trst, int srst) @@ -1051,14 +1134,14 @@ void comstick_reset(int trst, int srst) high_output |= nTRST; } - if (srst == 1) - { - high_output &= ~nSRST; - } - else if (srst == 0) - { - high_output |= nSRST; - } + if (srst == 1) + { + high_output &= ~nSRST; + } + else if (srst == 0) + { + high_output |= nSRST; + } /* command "set data bits high byte" */ BUFFER_ADD = 0x82; @@ -1078,14 +1161,14 @@ void stm32stick_reset(int trst, int srst) high_output |= nTRST; } - if (srst == 1) - { - low_output &= ~nSRST; - } - else if (srst == 0) - { - low_output |= nSRST; - } + if (srst == 1) + { + low_output &= ~nSRST; + } + else if (srst == 0) + { + low_output |= nSRST; + } /* command "set data bits low byte" */ BUFFER_ADD = 0x80; @@ -1326,15 +1409,13 @@ static int ft2232_init_ftd2xx(u16 vid, u16 pid, int more, int *try_more) char *openex_string = NULL; u8 latency_timer; - LOG_DEBUG("'ft2232' interface using FTD2XX with '%s' layout (%4.4x:%4.4x)", - ft2232_layout, vid, pid); + LOG_DEBUG("'ft2232' interface using FTD2XX with '%s' layout (%4.4x:%4.4x)",ft2232_layout, vid, pid); #if IS_WIN32 == 0 /* Add non-standard Vid/Pid to the linux driver */ if ((status = FT_SetVIDPID(vid, pid)) != FT_OK) { - LOG_WARNING("couldn't add %4.4x:%4.4x", - vid, pid); + LOG_WARNING("couldn't add %4.4x:%4.4x", vid, pid); } #endif @@ -1367,8 +1448,7 @@ static int ft2232_init_ftd2xx(u16 vid, u16 pid, int more, int *try_more) DWORD num_devices; if (more) { - LOG_WARNING("unable to open ftdi device (trying more): %lu", - status); + LOG_WARNING("unable to open ftdi device (trying more): %lu", status); *try_more = 1; return ERROR_JTAG_INIT_FAILED; } @@ -1454,17 +1534,17 @@ static int ft2232_init_libftdi(u16 vid, u16 pid, int more, int *try_more) u8 latency_timer; LOG_DEBUG("'ft2232' interface using libftdi with '%s' layout (%4.4x:%4.4x)", - ft2232_layout, vid, pid); + ft2232_layout, vid, pid); if (ftdi_init(&ftdic) < 0) return ERROR_JTAG_INIT_FAILED; /* context, vendor id, product id */ if (ftdi_usb_open_desc(&ftdic, vid, pid, ft2232_device_desc, - ft2232_serial) < 0) { + ft2232_serial) < 0) { if (more) LOG_WARNING("unable to open ftdi device (trying more): %s", - ftdic.error_str); + ftdic.error_str); else LOG_ERROR("unable to open ftdi device: %s", ftdic.error_str); *try_more = 1; @@ -1561,10 +1641,10 @@ int ft2232_init(void) #if BUILD_FT2232_FTD2XX == 1 retval = ft2232_init_ftd2xx(ft2232_vid[i], ft2232_pid[i], - more, &try_more); + more, &try_more); #elif BUILD_FT2232_LIBFTDI == 1 retval = ft2232_init_libftdi(ft2232_vid[i], ft2232_pid[i], - more, &try_more); + more, &try_more); #endif if (retval >= 0) break; @@ -1670,6 +1750,75 @@ int usbjtag_init(void) return ERROR_OK; } +int axm0432_jtag_init(void) +{ + u8 buf[3]; + u32 bytes_written; + + 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)) + { + LOG_ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); + return ERROR_JTAG_INIT_FAILED; + } + + if (strcmp(layout->name, "axm0432_jtag") == 0) + { + nTRST = 0x08; + nTRSTnOE = 0x0; /* No output enable for TRST*/ + nSRST = 0x04; + nSRSTnOE = 0x0; /* No output enable for SRST*/ + } + else + { + LOG_ERROR("BUG: axm0432_jtag_init called for non axm0432 layout"); + exit(-1); + } + + high_output = 0x0; + high_direction = 0x0c; + + if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) + { + LOG_ERROR("can't set nTRSTOE to push-pull on the Dicarlo jtag"); + } + else + { + high_output |= nTRST; + } + + if (jtag_reset_config & RESET_SRST_PUSH_PULL) + { + LOG_ERROR("can't set nSRST to push-pull on the Dicarlo jtag"); + } + else + { + 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)) + { + LOG_ERROR("couldn't initialize FT2232 with 'Dicarlo' layout"); + return ERROR_JTAG_INIT_FAILED; + } + + return ERROR_OK; +} + int jtagkey_init(void) { u8 buf[3]; @@ -1884,7 +2033,7 @@ int turtle_init(void) } nSRST = 0x40; - + high_output = 0x00; high_direction = 0x0C; @@ -1927,7 +2076,7 @@ int comstick_init(void) nTRSTnOE = 0x00; /* no output enable for nTRST */ nSRST = 0x02; nSRSTnOE = 0x00; /* no output enable for nSRST */ - + high_output = 0x03; high_direction = 0x03; @@ -1970,7 +2119,7 @@ int stm32stick_init(void) nTRSTnOE = 0x00; /* no output enable for nTRST */ nSRST = 0x80; nSRSTnOE = 0x00; /* no output enable for nSRST */ - + high_output = 0x01; high_direction = 0x03; @@ -2029,7 +2178,6 @@ void turtle_jtag_blink(void) BUFFER_ADD = high_direction; } - int ft2232_quit(void) { #if BUILD_FT2232_FTD2XX == 1 @@ -2095,7 +2243,7 @@ int ft2232_handle_vid_pid_command(struct command_context_s *cmd_ctx, char *cmd, if (argc > MAX_USB_IDS*2) { LOG_WARNING("ignoring extra IDs in ft2232_vid_pid " - "(maximum is %d pairs)", MAX_USB_IDS); + "(maximum is %d pairs)", MAX_USB_IDS); argc = MAX_USB_IDS*2; } if (argc < 2 || (argc & 1)) @@ -2131,5 +2279,3 @@ int ft2232_handle_latency_command(struct command_context_s *cmd_ctx, char *cmd, return ERROR_OK; } - -