ULINK driver: port from libusb-0.1 to libusb-1.0 API
The ULINK driver now uses libusb-1.0 calls (synchronous device I/O) directly (not the common layer provided by libusb1_common.c) Successfully tested with ULINK probe and STM32F103 (debug, erase and write flash). Change-Id: Ic037a3582db85e49a8cc1ec0dd36f629e4757929 Signed-off-by: Martin Schmölzer <martin.schmoelzer@student.tuwien.ac.at> Reviewed-on: http://openocd.zylin.com/1459 Tested-by: jenkins Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>__archive__
parent
8faa419fad
commit
f684252b25
|
@ -1177,7 +1177,7 @@ fi
|
|||
# check if some driver requires libusb-0.1
|
||||
need_usb0=no
|
||||
if test $build_vsllink = yes -o $build_usbprog = yes -o \
|
||||
$build_rlink = yes -o $build_ulink = yes -o $build_armjtagew = yes; then
|
||||
$build_rlink = yes -o $build_armjtagew = yes; then
|
||||
need_usb0=yes
|
||||
fi
|
||||
|
||||
|
@ -1191,7 +1191,7 @@ fi
|
|||
# check if some driver requires libusb-1.x
|
||||
need_usb_ng=no
|
||||
if test $build_ftdi = yes -o $build_hladapter_icdi = yes -o \
|
||||
$build_hladapter_stlink = yes; then
|
||||
$build_hladapter_stlink = yes -o $build_ulink = yes; then
|
||||
need_usb_ng=yes
|
||||
fi
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* Copyright (C) 2011-2013 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
|
@ -26,7 +26,7 @@
|
|||
#include <jtag/interface.h>
|
||||
#include <jtag/commands.h>
|
||||
#include <target/image.h>
|
||||
#include "usb_common.h"
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#include "OpenULINK/include/msgtypes.h"
|
||||
|
||||
/** USB Vendor ID of ULINK device in unconfigured state (no firmware loaded
|
||||
|
@ -146,7 +146,8 @@ struct ulink_cmd {
|
|||
|
||||
/** Describes one driver instance */
|
||||
struct ulink {
|
||||
struct usb_dev_handle *usb_handle;
|
||||
struct libusb_context *libusb_ctx;
|
||||
struct libusb_device_handle *usb_device_handle;
|
||||
enum ulink_type type;
|
||||
|
||||
int delay_scan_in; /* /< Delay value for SCAN_IN commands */
|
||||
|
@ -167,7 +168,7 @@ int ulink_usb_open(struct ulink **device);
|
|||
int ulink_usb_close(struct ulink **device);
|
||||
|
||||
/* ULINK MCU (Cypress EZ-USB) specific functions */
|
||||
int ulink_cpu_reset(struct ulink *device, char reset_bit);
|
||||
int ulink_cpu_reset(struct ulink *device, unsigned char reset_bit);
|
||||
int ulink_load_firmware_and_renumerate(struct ulink **device, char *filename,
|
||||
uint32_t delay);
|
||||
int ulink_load_firmware(struct ulink *device, char *filename);
|
||||
|
@ -258,30 +259,46 @@ struct ulink *ulink_handle;
|
|||
/**
|
||||
* Opens the ULINK device and claims its USB interface.
|
||||
*
|
||||
* Currently, only the original ULINK is supported
|
||||
*
|
||||
* @param device pointer to struct ulink identifying ULINK driver instance.
|
||||
* @return on success: ERROR_OK
|
||||
* @return on failure: ERROR_FAIL
|
||||
*/
|
||||
int ulink_usb_open(struct ulink **device)
|
||||
{
|
||||
int ret;
|
||||
struct usb_dev_handle *usb_handle;
|
||||
ssize_t num_devices, i;
|
||||
bool found;
|
||||
libusb_device **usb_devices;
|
||||
struct libusb_device_descriptor usb_desc;
|
||||
struct libusb_device_handle *usb_device_handle;
|
||||
|
||||
/* Currently, only original ULINK is supported */
|
||||
uint16_t vids[] = { ULINK_VID, 0 };
|
||||
uint16_t pids[] = { ULINK_PID, 0 };
|
||||
num_devices = libusb_get_device_list((*device)->libusb_ctx, &usb_devices);
|
||||
|
||||
ret = jtag_usb_open(vids, pids, &usb_handle);
|
||||
if (num_devices <= 0)
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (ret != ERROR_OK)
|
||||
return ret;
|
||||
found = false;
|
||||
for (i = 0; i < num_devices; i++) {
|
||||
if (libusb_get_device_descriptor(usb_devices[i], &usb_desc) != 0)
|
||||
continue;
|
||||
else if (usb_desc.idVendor == ULINK_VID && usb_desc.idProduct == ULINK_PID) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = usb_claim_interface(usb_handle, 0);
|
||||
if (!found)
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
if (libusb_open(usb_devices[i], &usb_device_handle) != 0)
|
||||
return ERROR_FAIL;
|
||||
libusb_free_device_list(usb_devices, 1);
|
||||
|
||||
(*device)->usb_handle = usb_handle;
|
||||
if (libusb_claim_interface(usb_device_handle, 0) != 0)
|
||||
return ERROR_FAIL;
|
||||
|
||||
(*device)->usb_device_handle = usb_device_handle;
|
||||
(*device)->type = ULINK_1;
|
||||
|
||||
return ERROR_OK;
|
||||
|
@ -296,13 +313,12 @@ int ulink_usb_open(struct ulink **device)
|
|||
*/
|
||||
int ulink_usb_close(struct ulink **device)
|
||||
{
|
||||
if (usb_release_interface((*device)->usb_handle, 0) != 0)
|
||||
if (libusb_release_interface((*device)->usb_device_handle, 0) != 0)
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (usb_close((*device)->usb_handle) != 0)
|
||||
return ERROR_FAIL;
|
||||
libusb_close((*device)->usb_device_handle);
|
||||
|
||||
(*device)->usb_handle = NULL;
|
||||
(*device)->usb_device_handle = NULL;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
@ -318,12 +334,12 @@ int ulink_usb_close(struct ulink **device)
|
|||
* @return on success: ERROR_OK
|
||||
* @return on failure: ERROR_FAIL
|
||||
*/
|
||||
int ulink_cpu_reset(struct ulink *device, char reset_bit)
|
||||
int ulink_cpu_reset(struct ulink *device, unsigned char reset_bit)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = usb_control_msg(device->usb_handle,
|
||||
(USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
|
||||
ret = libusb_control_transfer(device->usb_device_handle,
|
||||
(LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE),
|
||||
REQUEST_FIRMWARE_LOAD, CPUCS_REG, 0, &reset_bit, 1, USB_TIMEOUT);
|
||||
|
||||
/* usb_control_msg() returns the number of bytes transferred during the
|
||||
|
@ -467,9 +483,9 @@ int ulink_write_firmware_section(struct ulink *device,
|
|||
else
|
||||
chunk_size = bytes_remaining;
|
||||
|
||||
ret = usb_control_msg(device->usb_handle,
|
||||
(USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
|
||||
REQUEST_FIRMWARE_LOAD, addr, FIRMWARE_ADDR, (char *)data_ptr,
|
||||
ret = libusb_control_transfer(device->usb_device_handle,
|
||||
(LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE),
|
||||
REQUEST_FIRMWARE_LOAD, addr, FIRMWARE_ADDR, (unsigned char *)data_ptr,
|
||||
chunk_size, USB_TIMEOUT);
|
||||
|
||||
if (ret != (int)chunk_size) {
|
||||
|
@ -694,7 +710,7 @@ int ulink_append_queue(struct ulink *device, struct ulink_cmd *ulink_cmd)
|
|||
int ulink_execute_queued_commands(struct ulink *device, int timeout)
|
||||
{
|
||||
struct ulink_cmd *current;
|
||||
int ret, i, index_out, index_in, count_out, count_in;
|
||||
int ret, i, index_out, index_in, count_out, count_in, transferred;
|
||||
uint8_t buffer[64];
|
||||
|
||||
#ifdef _DEBUG_JTAG_IO_
|
||||
|
@ -719,20 +735,20 @@ int ulink_execute_queued_commands(struct ulink *device, int timeout)
|
|||
}
|
||||
|
||||
/* Send packet to ULINK */
|
||||
ret = usb_bulk_write(device->usb_handle, (2 | USB_ENDPOINT_OUT),
|
||||
(char *)buffer, count_out, timeout);
|
||||
if (ret < 0)
|
||||
ret = libusb_bulk_transfer(device->usb_device_handle, (2 | LIBUSB_ENDPOINT_OUT),
|
||||
(unsigned char *)buffer, count_out, &transferred, timeout);
|
||||
if (ret != 0)
|
||||
return ERROR_FAIL;
|
||||
if (ret != count_out)
|
||||
if (transferred != count_out)
|
||||
return ERROR_FAIL;
|
||||
|
||||
/* Wait for response if commands contain IN payload data */
|
||||
if (count_in > 0) {
|
||||
ret = usb_bulk_read(device->usb_handle, (2 | USB_ENDPOINT_IN),
|
||||
(char *)buffer, 64, timeout);
|
||||
if (ret < 0)
|
||||
ret = libusb_bulk_transfer(device->usb_device_handle, (2 | LIBUSB_ENDPOINT_IN),
|
||||
(unsigned char *)buffer, 64, &transferred, timeout);
|
||||
if (ret != 0)
|
||||
return ERROR_FAIL;
|
||||
if (ret != count_in)
|
||||
if (transferred != count_in)
|
||||
return ERROR_FAIL;
|
||||
|
||||
/* Write back IN payload data */
|
||||
|
@ -2142,17 +2158,17 @@ static int ulink_speed_div(int speed, int *khz)
|
|||
*/
|
||||
static int ulink_init(void)
|
||||
{
|
||||
int ret;
|
||||
int ret, transferred;
|
||||
char str_manufacturer[20];
|
||||
bool download_firmware = false;
|
||||
uint8_t *dummy;
|
||||
unsigned char *dummy;
|
||||
uint8_t input_signals, output_signals;
|
||||
|
||||
ulink_handle = calloc(1, sizeof(struct ulink));
|
||||
if (ulink_handle == NULL)
|
||||
return ERROR_FAIL;
|
||||
|
||||
usb_init();
|
||||
libusb_init(&ulink_handle->libusb_ctx);
|
||||
|
||||
ret = ulink_usb_open(&ulink_handle);
|
||||
if (ret != ERROR_OK) {
|
||||
|
@ -2163,7 +2179,7 @@ static int ulink_init(void)
|
|||
}
|
||||
|
||||
/* Get String Descriptor to determine if firmware needs to be loaded */
|
||||
ret = usb_get_string_simple(ulink_handle->usb_handle, 1, str_manufacturer, 20);
|
||||
ret = libusb_get_string_descriptor_ascii(ulink_handle->usb_device_handle, 1, (unsigned char *)str_manufacturer, 20);
|
||||
if (ret < 0) {
|
||||
/* Could not get descriptor -> Unconfigured or original Keil firmware */
|
||||
download_firmware = true;
|
||||
|
@ -2202,12 +2218,12 @@ static int ulink_init(void)
|
|||
* shut down by the user via Ctrl-C. Try to retrieve this Bulk IN packet. */
|
||||
dummy = calloc(64, sizeof(uint8_t));
|
||||
|
||||
ret = usb_bulk_read(ulink_handle->usb_handle, (2 | USB_ENDPOINT_IN),
|
||||
(char *)dummy, 64, 200);
|
||||
ret = libusb_bulk_transfer(ulink_handle->usb_device_handle, (2 | LIBUSB_ENDPOINT_IN),
|
||||
dummy, 64, &transferred, 200);
|
||||
|
||||
free(dummy);
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret != 0 || transferred == 0) {
|
||||
/* Bulk IN transfer failed -> unrecoverable error condition */
|
||||
LOG_ERROR("Cannot communicate with ULINK device. Disconnect ULINK from "
|
||||
"the USB port and re-connect, then re-run OpenOCD");
|
||||
|
|
Loading…
Reference in New Issue