Some ft2232 based devices (such as the FLOSS-JTAG) do
not include an on-board eeprom.  Without an eeprom, the
devices do not have a unique serial number.  When you
have multiple of these devices plugged into the same
PC, openocd has no way to distinguish between them.

This commit adds the 'ft2232_bus_addr' configuration
command which allows the user to specify the fully
qualified bus address of the ft2232 device.  The
format of the address is the same as for the
equivalent -s option in lsusb for selecting the device:
  <bus>:<devnum>

For example, if lsusb reports something like this:
  Bus 002 Device 084: ID 0403:6010 Future Technology Devices
                                   International, Ltd FT2232C
                                   Dual USB-UART/FIFO IC

Then this configuration command will select this device in
openocd:
  ft2232_bus_addr 002:084

Hint: You can use 'lsusb -tv' to display your devices in
tree format to find the device address associated with a
specific port on a USB hub.

Signed-off-by: Stacey Sheldon <[email protected]>
---
 src/jtag/drivers/ft2232.c |   75 ++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 74 insertions(+), 1 deletions(-)

diff --git a/src/jtag/drivers/ft2232.c b/src/jtag/drivers/ft2232.c
index 2ac410a..e866625 100644
--- a/src/jtag/drivers/ft2232.c
+++ b/src/jtag/drivers/ft2232.c
@@ -1,4 +1,7 @@
 /***************************************************************************
+*   Copyright (C) 2010 by Stacey Sheldon                                  *
+*       Stacey Sheldon <[email protected]>                           *
+*                                                                         *
 *   Copyright (C) 2009 by Øyvind Harboe                                   *
 *      Øyvind Harboe <[email protected]>                               *
 *                                                                         *
@@ -153,6 +156,7 @@ 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_bus_addr = NULL;
 static uint8_t         ft2232_latency = 2;
 static unsigned                ft2232_max_tck = FTDI_2232C_MAX_TCK;
 
@@ -2238,8 +2242,56 @@ static int ft2232_init_libftdi(uint16_t vid, uint16_t 
pid, int more, int* try_mo
                return ERROR_JTAG_INIT_FAILED;
        }
 
+       if (ft2232_bus_addr)
+       {
+               struct ftdi_device_list *ftdi_list;
+               struct ftdi_device_list *ftdi_dev;
+
+               if (ftdi_usb_find_all(&ftdic, &ftdi_list, vid, pid) < 0)
+               {
+                       LOG_ERROR("unable to scan for FT2232 devices: %s", 
ftdic.error_str);
+                       return ERROR_JTAG_INIT_FAILED;
+               }
+       
+               /* got the list of devices, look for a match */
+               for (ftdi_dev = ftdi_list; ftdi_dev != NULL; ftdi_dev = 
ftdi_dev->next)
+               {
+                       char path[PATH_MAX + 1] = { 0 };
+
+                       if(ftdi_dev->dev->bus)
+                       {
+                               strncat(path, ftdi_dev->dev->bus->dirname, 
sizeof(path)-1);
+                               strncat(path, ":", sizeof(path)-1);
+                       }
+                       strncat(path, ftdi_dev->dev->filename, sizeof(path)-1);
+                       /* check if we have a match on bus address */
+                       LOG_DEBUG ("Considering ftdi device at bus addr: %s", 
path);
+                       if (strcmp(ft2232_bus_addr, path) == 0)
+                       {
+                               /* found a match, break out */
+                               LOG_DEBUG ("Matched ftdi device at bus addr: 
%s", path);
+                               break;
+                       }
+               }
+
+               if (!ftdi_dev)
+               {
+                       ftdi_list_free(&ftdi_list);
+                       LOG_ERROR("failed to match FT2232 device by addr: %s", 
ft2232_bus_addr);
+                       return ERROR_JTAG_INIT_FAILED;
+               }
+
+               if (ftdi_usb_open_dev(&ftdic, ftdi_dev->dev) < 0)
+               {
+                       ftdi_list_free(&ftdi_list);
+                       LOG_ERROR("unable to open ftdi device: %s", 
ftdic.error_str);
+                       return ERROR_JTAG_INIT_FAILED;
+               }
+
+               ftdi_list_free(&ftdi_list);
+       }
        /* context, vendor id, product id */
-       if (ftdi_usb_open_desc(&ftdic, vid, pid, ft2232_device_desc,
+       else if (ftdi_usb_open_desc(&ftdic, vid, pid, ft2232_device_desc,
                                ft2232_serial) < 0)
        {
                if (more)
@@ -3246,6 +3298,20 @@ COMMAND_HANDLER(ft2232_handle_latency_command)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(ft2232_handle_bus_addr_command)
+{
+       if (CMD_ARGC == 1)
+       {
+               ft2232_bus_addr = strdup(CMD_ARGV[0]);
+       }
+       else
+       {
+               LOG_ERROR("expected exactly one argument to ft2232_bus_addr 
<bus:devnum>");
+       }
+
+       return ERROR_OK;
+}
+
 static int ft2232_stableclocks(int num_cycles, struct jtag_command* cmd)
 {
        int retval = 0;
@@ -4343,6 +4409,13 @@ static const struct command_registration 
ft2232_command_handlers[] = {
                .usage = "(vid pid)* ",
        },
        {
+               .name = "ft2232_bus_addr",
+               .handler = &ft2232_handle_bus_addr_command,
+               .mode = COMMAND_CONFIG,
+               .help = "the bus address of the FTDI FT2232 device",
+               .usage = "bus:devnum",
+       },
+       {
                .name = "ft2232_latency",
                .handler = &ft2232_handle_latency_command,
                .mode = COMMAND_CONFIG,
-- 
1.7.0

_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to