Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove libusb-0 and re-factor for libusb-1 #42

Merged
merged 1 commit into from
Jun 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 102 additions & 122 deletions adapter-mpsse.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,35 @@
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <usb.h>
#include <libusb-1.0/libusb.h>

#include "adapter.h"
#include "pic32.h"

struct olimex_devices {
uint16_t vid;
uint16_t pid;
const char *name;
uint8_t mhz;
uint16_t dir_control;
uint16_t trst_control;
uint8_t trst_inverted;
uint16_t sysrst_control;
uint8_t sysrst_inverted;
uint16_t led_control;
uint8_t led_inverted;
const char *product;
};


typedef struct {
/* Common part */
adapter_t adapter;
const char *name;

/* Device handle for libusb. */
usb_dev_handle *usbdev;
libusb_device_handle *usbdev;
libusb_context *context;

/* Transmit buffer for MPSSE packet. */
unsigned char output [256*16];
Expand Down Expand Up @@ -101,6 +118,17 @@ typedef struct {
#define RTDO 0x20
#define WTMS 0x40

const struct olimex_devices devlist[] = {
{ OLIMEX_VID, OLIMEX_ARM_USB_TINY, "Olimex ARM-USB-Tiny", 6, 0x0f10, 0x0100, 1, 0x0200, 0, 0x0800, 0, NULL},
{ OLIMEX_VID, OLIMEX_ARM_USB_TINY_H, "Olimex ARM-USB-Tiny-H", 30, 0x0f10, 0x0100, 1, 0x0200, 0, 0x0800, 0, NULL},
{ OLIMEX_VID, OLIMEX_ARM_USB_OCD_H, "Olimex ARM-USB-OCD-H", 30, 0x0f10, 0x0100, 1, 0x0200, 0, 0x0800, 0, NULL},
{ OLIMEX_VID, OLIMEX_MIPS_USB_OCD_H, "Olimex MIPS-USB-OCD-H", 30, 0x0f10, 0x0100, 1, 0x0200, 1, 0x0800, 0, NULL},
{ DP_BUSBLASTER_VID, DP_BUSBLASTER_PID, "TinCanTools Flyswatter", 6, 0x0cf0, 0x0010, 1, 0x0020, 1, 0x0c00, 1, "Flyswatter"},
{ DP_BUSBLASTER_VID, DP_BUSBLASTER_PID, "Dangerous Prototypes Bus Blaster", 30, 0x0f10, 0x0100, 1, 0x0200, 1, 0x0000, 0, NULL},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};

/*
* Calculate checksum.
*/
Expand Down Expand Up @@ -136,11 +164,13 @@ static void bulk_write(mpsse_adapter_t *a, unsigned char *output, int nbytes)
fprintf(stderr, "%c%02x", i ? '-' : ' ', output[i]);
fprintf(stderr, "\n");
}
bytes_written = usb_bulk_write(a->usbdev, IN_EP, (char*) output,
nbytes, 1000);
if (bytes_written < 0) {

int ret = libusb_bulk_transfer(a->usbdev, IN_EP, (unsigned char*) output,
nbytes, &bytes_written, 1000);

if (ret != 0) {
fprintf(stderr, "usb bulk write failed: %d: %s\n",
bytes_written, usb_strerror());
ret, libusb_strerror(ret));
exit(-1);
}
if (bytes_written != nbytes)
Expand Down Expand Up @@ -168,9 +198,9 @@ static void mpsse_flush_output(mpsse_adapter_t *a)
/* Get reply. */
bytes_read = 0;
while (bytes_read < a->bytes_to_read) {
n = usb_bulk_read(a->usbdev, OUT_EP, (char*) reply,
a->bytes_to_read - bytes_read + 2, 2000);
if (n < 0) {
int ret = libusb_bulk_transfer(a->usbdev, OUT_EP, (unsigned char*) reply,
a->bytes_to_read - bytes_read + 2, &n, 2000);
if (ret != 0) {
fprintf(stderr, "usb bulk read failed\n");
exit(-1);
}
Expand Down Expand Up @@ -430,8 +460,8 @@ static void mpsse_close(adapter_t *adapter, int power_on)
mpsse_reset(a, 0, 1, 1);
mpsse_reset(a, 0, 0, 0);

usb_release_interface(a->usbdev, 0);
usb_close(a->usbdev);
libusb_release_interface(a->usbdev, 0);
libusb_close(a->usbdev);
free(a);
}

Expand Down Expand Up @@ -866,159 +896,109 @@ static void mpsse_verify_data(adapter_t *adapter,
adapter_t *adapter_open_mpsse(void)
{
mpsse_adapter_t *a;
struct usb_bus *bus;
struct usb_device *dev;
char product [256];
// struct libusb_bus *bus;
unsigned char product [256];
int i;

a = calloc(1, sizeof(*a));
if (! a) {
fprintf(stderr, "adapter_open_mpsse: out of memory\n");
return 0;
}
usb_init();
usb_find_busses();
usb_find_devices();
for (bus = usb_get_busses(); bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) {
if (dev->descriptor.idVendor == OLIMEX_VID &&
dev->descriptor.idProduct == OLIMEX_ARM_USB_TINY) {
a->name = "Olimex ARM-USB-Tiny";
a->mhz = 6;
a->dir_control = 0x0f10;
a->trst_control = 0x0100;
a->trst_inverted = 1;
a->sysrst_control = 0x0200;
a->led_control = 0x0800;
goto found;
}
if (dev->descriptor.idVendor == OLIMEX_VID &&
dev->descriptor.idProduct == OLIMEX_ARM_USB_TINY_H) {
a->name = "Olimex ARM-USB-Tiny-H";
a->mhz = 30;
a->dir_control = 0x0f10;
a->trst_control = 0x0100;
a->trst_inverted = 1;
a->sysrst_control = 0x0200;
a->led_control = 0x0800;
goto found;
}
if (dev->descriptor.idVendor == OLIMEX_VID &&
dev->descriptor.idProduct == OLIMEX_ARM_USB_OCD_H) {
a->name = "Olimex ARM-USB-OCD-H";
a->mhz = 30;
a->dir_control = 0x0f10;
a->trst_control = 0x0100;
a->trst_inverted = 1;
a->sysrst_control = 0x0200;
a->led_control = 0x0800;
goto found;
}
if (dev->descriptor.idVendor == OLIMEX_VID &&
dev->descriptor.idProduct == OLIMEX_MIPS_USB_OCD_H) {
a->name = "Olimex MIPS-USB-OCD-H";
a->mhz = 30;
a->dir_control = 0x0f10;
a->trst_control = 0x0100;
a->trst_inverted = 1;
a->sysrst_control = 0x0200;
a->led_control = 0x0800;
a->sysrst_inverted = 1;
goto found;
a->context = NULL;
int ret = libusb_init(&a->context);

if (ret != 0) {
fprintf(stderr, "libusb init failed: %d: %s\n",
ret, libusb_strerror(ret));
exit(-1);
}

for (i = 0; devlist[i].vid; i++) {
a->usbdev = libusb_open_device_with_vid_pid(a->context, devlist[i].vid, devlist[i].pid);
if (a->usbdev != NULL) {
int match = 1;
if (devlist[i].product != NULL) {

struct libusb_device_descriptor desc = {0};
int rc = libusb_get_device_descriptor(libusb_get_device(a->usbdev), &desc);
if (rc != 0) {
match = 0;
} else {
rc = libusb_get_string_descriptor_ascii(a->usbdev, desc.iProduct, product, 256);

if (strcmp((const char *)product, devlist[i].product) != 0) {
match = 0;
}
}
}
if (dev->descriptor.idVendor == DP_BUSBLASTER_VID &&
dev->descriptor.idProduct == DP_BUSBLASTER_PID) {
a->name = "Dangerous Prototypes Bus Blaster";
a->mhz = 30;
a->dir_control = 0x0f10;
a->trst_control = 0x0100;
a->trst_inverted = 1;
a->sysrst_control = 0x0200;
a->sysrst_inverted = 1;

if (match == 1) {
a->name = devlist[i].name;
a->mhz = devlist[i].mhz;
a->dir_control = devlist[i].dir_control;
a->trst_control = devlist[i].trst_control;
a->trst_inverted = devlist[i].trst_inverted;
a->sysrst_control = devlist[i].sysrst_control;
a->sysrst_inverted = devlist[i].sysrst_inverted;
a->led_control = devlist[i].led_control;
a->led_inverted = devlist[i].led_inverted;
goto found;
}
}
}
/*fprintf(stderr, "USB adapter not found: vid=%04x, pid=%04x\n",
OLIMEX_VID, OLIMEX_PID);*/

free(a);
return 0;

found:
/*fprintf(stderr, "found USB adapter: vid %04x, pid %04x, type %03x\n",
dev->descriptor.idVendor, dev->descriptor.idProduct,
dev->descriptor.bcdDevice);*/
a->usbdev = usb_open(dev);
if (! a->usbdev) {
fprintf(stderr, "%s: usb_open() failed\n", a->name);
free(a);
return 0;
}
if (dev->descriptor.iProduct) {
if (usb_get_string_simple(a->usbdev, dev->descriptor.iProduct,
product, sizeof(product)) > 0)
{
if (strcmp("Flyswatter", product) == 0) {
/* TinCanTools Flyswatter.
* PID/VID the same as Dangerous Prototypes Bus Blaster. */
a->name = "TinCanTools Flyswatter";
a->mhz = 6;
a->dir_control = 0x0cf0;
a->trst_control = 0x0010;
a->trst_inverted = 1;
a->sysrst_control = 0x0020;
a->sysrst_inverted = 0;
a->led_control = 0x0c00;
a->led_inverted = 1;
}
}
}

#if ! defined(__CYGWIN32__) && ! defined(MINGW32) && ! defined(__APPLE__)
char driver_name [100];
if (usb_get_driver_np(a->usbdev, 0, driver_name, sizeof(driver_name)) == 0) {
if (usb_detach_kernel_driver_np(a->usbdev, 0) < 0) {
printf("%s: failed to detach the %s kernel driver.\n",
a->name, driver_name);
usb_close(a->usbdev);
free(a);
return 0;
}
ret = libusb_detach_kernel_driver(a->usbdev, 0);
if (ret != 0) {
fprintf(stderr, "Error detaching kernel driver: %d: %s\n",
ret, libusb_strerror(ret));
libusb_close(a->usbdev);
exit(-1);
}
#endif
usb_claim_interface(a->usbdev, 0);

libusb_claim_interface(a->usbdev, 0);

/* Reset the ftdi device. */
if (usb_control_msg(a->usbdev,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
if (libusb_control_transfer(a->usbdev,
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,
SIO_RESET, 0, 1, 0, 0, 1000) != 0) {
if (errno == EPERM)
fprintf(stderr, "%s: superuser privileges needed.\n", a->name);
else
fprintf(stderr, "%s: FTDI reset failed\n", a->name);
failed: usb_release_interface(a->usbdev, 0);
usb_close(a->usbdev);
failed: libusb_release_interface(a->usbdev, 0);
libusb_close(a->usbdev);
free(a);
return 0;
}

/* MPSSE mode. */
if (usb_control_msg(a->usbdev,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
if (libusb_control_transfer(a->usbdev,
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,
SIO_SET_BITMODE, 0x20b, 1, 0, 0, 1000) != 0) {
fprintf(stderr, "%s: can't set sync mpsse mode\n", a->name);
goto failed;
}

/* Optimal latency timer is 1 for slow mode and 0 for fast mode. */
unsigned latency_timer = (a->mhz > 6) ? 0 : 1;
if (usb_control_msg(a->usbdev,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
if (libusb_control_transfer(a->usbdev,
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,
SIO_SET_LATENCY_TIMER, latency_timer, 1, 0, 0, 1000) != 0) {
fprintf(stderr, "%s: unable to set latency timer\n", a->name);
goto failed;
}
if (usb_control_msg(a->usbdev,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
SIO_GET_LATENCY_TIMER, 0, 1, (char*) &latency_timer, 1, 1000) != 1) {
if (libusb_control_transfer(a->usbdev,
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
SIO_GET_LATENCY_TIMER, 0, 1, (unsigned char*) &latency_timer, 1, 1000) != 1) {
fprintf(stderr, "%s: unable to get latency timer\n", a->name);
goto failed;
}
Expand Down
18 changes: 9 additions & 9 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ PROG_OBJS = pic32prog.o target.o executive.o hid.o serial.o \
# Olimex ARM-USB-Tiny JTAG adapter: requires libusb-0.1
CFLAGS += -DUSE_MPSSE
PROG_OBJS += adapter-mpsse.o
ifeq ($(UNAME),Linux)
# Use 'sudo port install libusb-0.1-dev'
LIBS += -Wl,-Bstatic -lusb -Wl,-Bdynamic
endif
ifeq ($(UNAME),Darwin)
# Use 'sudo port install libusb-legacy'
CFLAGS += -I/opt/local/include/libusb-legacy
LIBS += /opt/local/lib/libusb-legacy/libusb-legacy.a
endif
#ifeq ($(UNAME),Linux)
# # Use 'sudo port install libusb-0.1-dev'
# LIBS += -Wl,-Bstatic -lusb -Wl,-Bdynamic
#endif
#ifeq ($(UNAME),Darwin)
# # Use 'sudo port install libusb-legacy'
# CFLAGS += -I/opt/local/include/libusb-legacy
# LIBS += /opt/local/lib/libusb-legacy/libusb-legacy.a
#endif

all: pic32prog

Expand Down