|
|
@@ -77,8 +77,11 @@ int ft2232_handle_vid_pid_command(struct command_context_s *cmd_ctx, char *cmd, |
|
|
|
char *ft2232_device_desc = NULL; |
|
|
|
char *ft2232_serial = NULL; |
|
|
|
char *ft2232_layout = NULL; |
|
|
|
u16 ft2232_vid = 0x0403; |
|
|
|
u16 ft2232_pid = 0x6010; |
|
|
|
|
|
|
|
#define MAX_USB_IDS 8 |
|
|
|
/* vid = pid = 0 marks the end of the list */ |
|
|
|
static u16 ft2232_vid[MAX_USB_IDS+1] = { 0x0403, 0 }; |
|
|
|
static u16 ft2232_pid[MAX_USB_IDS+1] = { 0x6010, 0 }; |
|
|
|
|
|
|
|
typedef struct ft2232_layout_s |
|
|
|
{ |
|
|
@@ -1227,55 +1230,23 @@ int ft2232_execute_queue() |
|
|
|
return ERROR_OK; |
|
|
|
} |
|
|
|
|
|
|
|
int ft2232_init(void) |
|
|
|
{ |
|
|
|
u8 latency_timer; |
|
|
|
u8 buf[1]; |
|
|
|
int retval; |
|
|
|
u32 bytes_written; |
|
|
|
|
|
|
|
#if BUILD_FT2232_FTD2XX == 1 |
|
|
|
static int ft2232_init_ftd2xx(u16 vid, u16 pid, int more, int *try_more) |
|
|
|
{ |
|
|
|
FT_STATUS status; |
|
|
|
DWORD openex_flags = 0; |
|
|
|
char *openex_string = NULL; |
|
|
|
#endif |
|
|
|
|
|
|
|
ft2232_layout_t *cur_layout = ft2232_layouts; |
|
|
|
|
|
|
|
if ((ft2232_layout == NULL) || (ft2232_layout[0] == 0)) |
|
|
|
{ |
|
|
|
ft2232_layout = "usbjtag"; |
|
|
|
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++; |
|
|
|
} |
|
|
|
u8 latency_timer; |
|
|
|
|
|
|
|
if (!layout) |
|
|
|
{ |
|
|
|
ERROR("No matching layout found for %s", ft2232_layout); |
|
|
|
return ERROR_JTAG_INIT_FAILED; |
|
|
|
} |
|
|
|
|
|
|
|
#if BUILD_FT2232_FTD2XX == 1 |
|
|
|
DEBUG("'ft2232' interface using FTD2XX with '%s' layout", ft2232_layout); |
|
|
|
#elif BUILD_FT2232_LIBFTDI == 1 |
|
|
|
DEBUG("'ft2232' interface using libftdi with '%s' layout", ft2232_layout); |
|
|
|
#endif |
|
|
|
DEBUG("'ft2232' interface using FTD2XX with '%s' layout (%4.4x:%4.4x)", |
|
|
|
ft2232_layout, vid, pid); |
|
|
|
|
|
|
|
#if BUILD_FT2232_FTD2XX == 1 |
|
|
|
#if IS_WIN32 == 0 |
|
|
|
/* Add non-standard Vid/Pid to the linux driver */ |
|
|
|
if ((status = FT_SetVIDPID(ft2232_vid, ft2232_pid)) != FT_OK) |
|
|
|
if ((status = FT_SetVIDPID(vid, pid)) != FT_OK) |
|
|
|
{ |
|
|
|
WARNING("couldn't add %4.4x:%4.4x", ft2232_vid, ft2232_pid); |
|
|
|
WARNING("couldn't add %4.4x:%4.4x", |
|
|
|
vid, pid); |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
@@ -1307,6 +1278,12 @@ int ft2232_init(void) |
|
|
|
{ |
|
|
|
DWORD num_devices; |
|
|
|
|
|
|
|
if (more) { |
|
|
|
WARNING("unable to open ftdi device (trying more): %lu", |
|
|
|
status); |
|
|
|
*try_more = 1; |
|
|
|
return ERROR_JTAG_INIT_FAILED; |
|
|
|
} |
|
|
|
ERROR("unable to open ftdi device: %lu", status); |
|
|
|
status = FT_ListDevices(&num_devices, NULL, FT_LIST_NUMBER_ONLY); |
|
|
|
if (status == FT_OK) |
|
|
@@ -1365,14 +1342,44 @@ int ft2232_init(void) |
|
|
|
ERROR("unable to enable bit i/o mode: %lu", status); |
|
|
|
return ERROR_JTAG_INIT_FAILED; |
|
|
|
} |
|
|
|
#elif BUILD_FT2232_LIBFTDI == 1 |
|
|
|
|
|
|
|
return ERROR_OK; |
|
|
|
} |
|
|
|
|
|
|
|
static int ft2232_purge_ftd2xx(void) |
|
|
|
{ |
|
|
|
FT_STATUS status; |
|
|
|
|
|
|
|
if ((status = FT_Purge(ftdih, FT_PURGE_RX | FT_PURGE_TX)) != FT_OK) |
|
|
|
{ |
|
|
|
ERROR("error purging ftd2xx device: %lu", status); |
|
|
|
return ERROR_JTAG_INIT_FAILED; |
|
|
|
} |
|
|
|
|
|
|
|
return ERROR_OK; |
|
|
|
} |
|
|
|
#endif /* BUILD_FT2232_FTD2XX == 1 */ |
|
|
|
|
|
|
|
#if BUILD_FT2232_LIBFTDI == 1 |
|
|
|
static int ft2232_init_libftdi(u16 vid, u16 pid, int more, int *try_more) |
|
|
|
{ |
|
|
|
u8 latency_timer; |
|
|
|
|
|
|
|
DEBUG("'ft2232' interface using libftdi with '%s' layout (%4.4x:%4.4x)", |
|
|
|
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, ft2232_vid, ft2232_pid, ft2232_device_desc, ft2232_serial) < 0) |
|
|
|
{ |
|
|
|
ERROR("unable to open ftdi device: %s", ftdic.error_str); |
|
|
|
if (ftdi_usb_open_desc(&ftdic, vid, pid, ft2232_device_desc, |
|
|
|
ft2232_serial) < 0) { |
|
|
|
if (more) |
|
|
|
WARNING("unable to open ftdi device (trying more): %s", |
|
|
|
ftdic.error_str); |
|
|
|
else |
|
|
|
ERROR("unable to open ftdi device: %s", ftdic.error_str); |
|
|
|
*try_more = 1; |
|
|
|
return ERROR_JTAG_INIT_FAILED; |
|
|
|
} |
|
|
|
|
|
|
@@ -1405,7 +1412,77 @@ int ft2232_init(void) |
|
|
|
} |
|
|
|
|
|
|
|
ftdi_set_bitmode(&ftdic, 0x0b, 2); /* ctx, JTAG I/O mask */ |
|
|
|
|
|
|
|
return ERROR_OK; |
|
|
|
} |
|
|
|
|
|
|
|
static int ft2232_purge_libftdi(void) |
|
|
|
{ |
|
|
|
if (ftdi_usb_purge_buffers(&ftdic) < 0) |
|
|
|
{ |
|
|
|
ERROR("ftdi_purge_buffers: %s", ftdic.error_str); |
|
|
|
return ERROR_JTAG_INIT_FAILED; |
|
|
|
} |
|
|
|
|
|
|
|
return ERROR_OK; |
|
|
|
} |
|
|
|
#endif /* BUILD_FT2232_LIBFTDI == 1 */ |
|
|
|
|
|
|
|
int ft2232_init(void) |
|
|
|
{ |
|
|
|
u8 buf[1]; |
|
|
|
int retval; |
|
|
|
u32 bytes_written; |
|
|
|
ft2232_layout_t *cur_layout = ft2232_layouts; |
|
|
|
int i; |
|
|
|
|
|
|
|
if ((ft2232_layout == NULL) || (ft2232_layout[0] == 0)) |
|
|
|
{ |
|
|
|
ft2232_layout = "usbjtag"; |
|
|
|
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) |
|
|
|
{ |
|
|
|
ERROR("No matching layout found for %s", ft2232_layout); |
|
|
|
return ERROR_JTAG_INIT_FAILED; |
|
|
|
} |
|
|
|
|
|
|
|
for (i = 0; 1; i++) { |
|
|
|
/* |
|
|
|
* "more indicates that there are more IDs to try, so we should |
|
|
|
* not print an error for an ID mismatch (but for anything |
|
|
|
* else, we should). |
|
|
|
* |
|
|
|
* try_more indicates that the error code returned indicates an |
|
|
|
* ID mismatch (and nothing else) and that we should proceeed |
|
|
|
* with the next ID pair. |
|
|
|
*/ |
|
|
|
int more = ft2232_vid[i+1] || ft2232_pid[i+1]; |
|
|
|
int try_more = 0; |
|
|
|
|
|
|
|
#if BUILD_FT2232_FTD2XX == 1 |
|
|
|
retval = ft2232_init_ftd2xx(ft2232_vid[i], ft2232_pid[i], |
|
|
|
more, &try_more); |
|
|
|
#elif BUILD_FT2232_LIBFTDI == 1 |
|
|
|
retval = ft2232_init_libftdi(ft2232_vid[i], ft2232_pid[i], |
|
|
|
more, &try_more); |
|
|
|
#endif |
|
|
|
if (retval >= 0) |
|
|
|
break; |
|
|
|
if (!more || !try_more) |
|
|
|
return retval; |
|
|
|
} |
|
|
|
|
|
|
|
ft2232_buffer_size = 0; |
|
|
|
ft2232_buffer = malloc(FT2232_BUFFER_SIZE); |
|
|
@@ -1423,17 +1500,9 @@ int ft2232_init(void) |
|
|
|
} |
|
|
|
|
|
|
|
#if BUILD_FT2232_FTD2XX == 1 |
|
|
|
if ((status = FT_Purge(ftdih, FT_PURGE_RX | FT_PURGE_TX)) != FT_OK) |
|
|
|
{ |
|
|
|
ERROR("error purging ftd2xx device: %lu", status); |
|
|
|
return ERROR_JTAG_INIT_FAILED; |
|
|
|
} |
|
|
|
return ft2232_purge_ftd2xx(); |
|
|
|
#elif BUILD_FT2232_LIBFTDI == 1 |
|
|
|
if (ftdi_usb_purge_buffers(&ftdic) < 0) |
|
|
|
{ |
|
|
|
ERROR("ftdi_purge_buffers: %s", ftdic.error_str); |
|
|
|
return ERROR_JTAG_INIT_FAILED; |
|
|
|
} |
|
|
|
return ft2232_purge_libftdi(); |
|
|
|
#endif |
|
|
|
|
|
|
|
return ERROR_OK; |
|
|
@@ -1847,15 +1916,29 @@ int ft2232_handle_layout_command(struct command_context_s *cmd_ctx, char *cmd, c |
|
|
|
|
|
|
|
int ft2232_handle_vid_pid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) |
|
|
|
{ |
|
|
|
if (argc >= 2) |
|
|
|
{ |
|
|
|
ft2232_vid = strtol(args[0], NULL, 0); |
|
|
|
ft2232_pid = strtol(args[1], NULL, 0); |
|
|
|
int i; |
|
|
|
|
|
|
|
if (argc > MAX_USB_IDS*2) { |
|
|
|
WARNING("ignoring extra IDs in ft2232_vid_pid " |
|
|
|
"(maximum is %d pairs)", MAX_USB_IDS); |
|
|
|
argc = MAX_USB_IDS*2; |
|
|
|
} |
|
|
|
else |
|
|
|
if (argc < 2 || (argc & 1)) |
|
|
|
{ |
|
|
|
WARNING("incomplete ft2232_vid_pid configuration directive"); |
|
|
|
if (argc < 2) |
|
|
|
return ERROR_OK; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i+1 < argc; i += 2) { |
|
|
|
ft2232_vid[i >> 1] = strtol(args[i], NULL, 0); |
|
|
|
ft2232_pid[i >> 1] = strtol(args[i+1], NULL, 0); |
|
|
|
} |
|
|
|
/* |
|
|
|
* Explicitly terminate, in case there are multiples instances of |
|
|
|
* ft2232_vid_pid. |
|
|
|
*/ |
|
|
|
ft2232_vid[i >> 1] = ft2232_pid[i >> 1] = 0; |
|
|
|
|
|
|
|
return ERROR_OK; |
|
|
|
} |