Gary Carlson <gcarlson@carlson-minot.com>
authorntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Mon, 13 Jul 2009 06:36:51 +0000 (06:36 +0000)
committerntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Mon, 13 Jul 2009 06:36:51 +0000 (06:36 +0000)
Spencer Oliver <spen@spen-soft.co.uk>

- fix jlink win32/linux/darwin startup issues
- see https://lists.berlios.de/pipermail/openocd-development/2009-July/009438.html

git-svn-id: svn://svn.berlios.de/openocd/trunk@2513 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/jtag/jlink.c

index aff1a6cae7aa3dd4a511b0786e7d15ff95b96d38..d8bfb0f391162b0e9f461ba855b4e851d4789a67 100644 (file)
@@ -835,13 +835,37 @@ static int jlink_tap_execute(void)
        return ERROR_OK;
 }
 
+static struct usb_device* find_jlink_device(void)
+{
+       struct usb_bus *busses;
+       struct usb_bus *bus;
+       struct usb_device *dev;
+
+       usb_find_busses();
+       usb_find_devices();
+
+       busses = usb_get_busses();
+
+       /* find jlink_jtag device in usb bus */
+
+       for (bus = busses; bus; bus = bus->next)
+       {
+               for (dev = bus->devices; dev; dev = dev->next)
+               {
+                       if ((dev->descriptor.idVendor == VID) && (dev->descriptor.idProduct == PID)) {
+                               return dev;
+                       }
+               }
+       }
+
+       return NULL;
+}
+
 /*****************************************************************************/
 /* JLink USB low-level functions */
 
 static jlink_jtag_t* jlink_usb_open()
 {
-       struct usb_bus *busses;
-       struct usb_bus *bus;
        struct usb_device *dev;
 
        jlink_jtag_t *result;
@@ -849,56 +873,81 @@ static jlink_jtag_t* jlink_usb_open()
        result = (jlink_jtag_t*) malloc(sizeof(jlink_jtag_t));
 
        usb_init();
-       usb_find_busses();
-       usb_find_devices();
 
-       busses = usb_get_busses();
+       if ((dev = find_jlink_device()) == NULL) {
+               free(result);
+               return NULL;
+       }
 
-       /* find jlink_jtag device in usb bus */
+       result->usb_handle = usb_open(dev);
 
-       for (bus = busses; bus; bus = bus->next)
+       if (result->usb_handle)
        {
-               for (dev = bus->devices; dev; dev = dev->next)
+       
+               /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS AREA!!!!!!!!!!!
+                * The behavior of libusb is not completely consistent across Windows, Linux, and Mac OS X platforms.  The actions taken
+                * in the following compiler conditionals may not agree with published documentation for libusb, but were found
+                * to be necessary through trials and tribulations.  Even little tweaks can break one or more platforms, so if you do make changes
+                * test them carefully on all platforms before committing them!
+                */
+
+#if IS_WIN32 == 0
+
+               usb_reset(result->usb_handle);
+
+#if IS_DARWIN == 0
+
+               int timeout = 5;
+
+               /* reopen jlink after usb_reset
+                * on win32 this may take a second or two to re-enumerate */
+               while ((dev = find_jlink_device()) == NULL)
                {
-                       if ((dev->descriptor.idVendor == VID) && (dev->descriptor.idProduct == PID))
-                       {
-                               result->usb_handle = usb_open(dev);
-                               
-                               /*
-                                *      Some j-link dongles experience intermittent communication issues at startup to varying degrees
-                                *      depending on the host operating system.  Troubleshooting this problem all the way back to libusb
-                                *      revealed that without a usb reset, the hardware can start in an uncertain state causing a litany
-                                *      of annoying problems.  The next step was added to the original code to address this problem.
-                                */
-                               
-                               usb_reset(result->usb_handle);
-
-                               /* usb_set_configuration required under win32 */
-                               usb_set_configuration(result->usb_handle, dev->config[0].bConfigurationValue);
-                               usb_claim_interface(result->usb_handle, 0);
+                       usleep(1000);
+                       timeout--;
+                       if (!timeout) {
+                               break;
+                       }
+               }
+
+               if (dev == NULL)
+               {
+                       free(result);
+                       return NULL;
+               }
+
+               result->usb_handle = usb_open(dev);
+#endif
+
+#endif
+
+               if (result->usb_handle)
+               {
+                       /* usb_set_configuration required under win32 */
+                       usb_set_configuration(result->usb_handle, dev->config[0].bConfigurationValue);
+                       usb_claim_interface(result->usb_handle, 0);
 
 #if 0
-                               /*
-                                * This makes problems under Mac OS X. And is not needed
-                                * under Windows. Hopefully this will not break a linux build
-                                */
-                               usb_set_altinterface(result->usb_handle, 0);
+                       /*
+                        * This makes problems under Mac OS X. And is not needed
+                        * under Windows. Hopefully this will not break a linux build
+                        */
+                       usb_set_altinterface(result->usb_handle, 0);
 #endif
-                               struct usb_interface *iface = dev->config->interface;
-                               struct usb_interface_descriptor *desc = iface->altsetting;
-                               for (int i = 0; i < desc->bNumEndpoints; i++)
-                               {
-                                       uint8_t epnum = desc->endpoint[i].bEndpointAddress;
-                                       bool is_input = epnum & 0x80;
-                                       LOG_DEBUG("usb ep %s %02x", is_input ? "in" : "out", epnum);
-                                       if (is_input)
-                                               jlink_read_ep = epnum;
-                                       else
-                                               jlink_write_ep = epnum;
-                               }
-
-                               return result;
+                       struct usb_interface *iface = dev->config->interface;
+                       struct usb_interface_descriptor *desc = iface->altsetting;
+                       for (int i = 0; i < desc->bNumEndpoints; i++)
+                       {
+                               uint8_t epnum = desc->endpoint[i].bEndpointAddress;
+                               bool is_input = epnum & 0x80;
+                               LOG_DEBUG("usb ep %s %02x", is_input ? "in" : "out", epnum);
+                               if (is_input)
+                                       jlink_read_ep = epnum;
+                               else
+                                       jlink_write_ep = epnum;
                        }
+
+                       return result;
                }
        }
 

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)