Browse Source

Gary Carlson <gcarlson@carlson-minot.com>

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
tags/v0.2.0
ntfreak 12 years ago
parent
commit
ebd46e23b3
1 changed files with 92 additions and 43 deletions
  1. +92
    -43
      src/jtag/jlink.c

+ 92
- 43
src/jtag/jlink.c View 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;
}
}



Loading…
Cancel
Save