Improve USB support:
- All USB errors are now reported in text format; - USB drivers now relies on libusb-win32 with version >= 1.2.4.x (1.2.4.6 recommended) (Many thanks to Glenn)
This commit is contained in:
parent
7c88fc27b5
commit
850b3c2375
3 changed files with 56 additions and 26 deletions
|
@ -7,8 +7,8 @@ Requirements
|
||||||
============
|
============
|
||||||
|
|
||||||
- MinGW-w64 compiler toolchain [1]
|
- MinGW-w64 compiler toolchain [1]
|
||||||
- LibUsb-Win32 0.1.12.2 [2]
|
- LibUsb-Win32 1.2.4.6 (or greater) [2]
|
||||||
- CMake 2.6 [3]
|
- CMake 2.8 [3]
|
||||||
|
|
||||||
This was tested on Windows 7 64 bit, but should work on Windows Vista and
|
This was tested on Windows 7 64 bit, but should work on Windows Vista and
|
||||||
Windows XP and 32 bit as well.
|
Windows XP and 32 bit as well.
|
||||||
|
@ -53,5 +53,5 @@ References
|
||||||
[1] the easiest way is to use the TDM-GCC installer.
|
[1] the easiest way is to use the TDM-GCC installer.
|
||||||
Make sure to select MinGW-w64 in the installer, the regular MinGW does not contain headers for PCSC.
|
Make sure to select MinGW-w64 in the installer, the regular MinGW does not contain headers for PCSC.
|
||||||
http://sourceforge.net/projects/tdm-gcc/files/TDM-GCC%20Installer/tdm64-gcc-4.5.1.exe/download
|
http://sourceforge.net/projects/tdm-gcc/files/TDM-GCC%20Installer/tdm64-gcc-4.5.1.exe/download
|
||||||
[2] http://libusb-win32.sourceforge.net/
|
[2] http://sourceforge.net/projects/libusb-win32/files/libusb-win32-snapshots/20110512/libusb-win32-snapshot-1.2.4.6.zip/download
|
||||||
[3] http://www.cmake.org
|
[3] http://www.cmake.org
|
||||||
|
|
|
@ -26,7 +26,7 @@ ENDIF(CMAKE_SYSTEM_NAME MATCHES FreeBSD)
|
||||||
|
|
||||||
IF(NOT LIBUSB_FOUND)
|
IF(NOT LIBUSB_FOUND)
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
FIND_PATH(LIBUSB_INCLUDE_DIRS usb.h "$ENV{ProgramFiles}/LibUSB-Win32/include" NO_SYSTEM_ENVIRONMENT_PATH)
|
FIND_PATH(LIBUSB_INCLUDE_DIRS lusb0_usb.h "$ENV{ProgramFiles}/LibUSB-Win32/include" NO_SYSTEM_ENVIRONMENT_PATH)
|
||||||
FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb PATHS "$ENV{ProgramFiles}/LibUSB-Win32/lib/gcc")
|
FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb PATHS "$ENV{ProgramFiles}/LibUSB-Win32/lib/gcc")
|
||||||
SET(LIBUSB_LIBRARY_DIR "$ENV{ProgramFiles}/LibUSB-Win32/bin/x86/")
|
SET(LIBUSB_LIBRARY_DIR "$ENV{ProgramFiles}/LibUSB-Win32/bin/x86/")
|
||||||
ELSE(WIN32)
|
ELSE(WIN32)
|
||||||
|
|
|
@ -36,7 +36,20 @@ Thanks to d18c7db and Okko for example code
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
// Under POSIX system, we use libusb (>= 0.1.12)
|
||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
|
#define USB_TIMEOUT 0
|
||||||
|
#define _usb_strerror( X ) strerror(-X)
|
||||||
|
#else
|
||||||
|
// Under Windows we use libusb-win32 (>= 1.2.4)
|
||||||
|
#include <lusb0_usb.h>
|
||||||
|
// libusb-win32's bug workaround: 0 as timeout does not means infite as expected
|
||||||
|
#define USB_TIMEOUT 10
|
||||||
|
#define _usb_strerror( X ) usb_strerror()
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <nfc/nfc.h>
|
#include <nfc/nfc.h>
|
||||||
|
@ -47,7 +60,6 @@ Thanks to d18c7db and Okko for example code
|
||||||
#include "drivers/pn53x_usb.h"
|
#include "drivers/pn53x_usb.h"
|
||||||
|
|
||||||
#define PN53X_USB_DRIVER_NAME "PN53x USB"
|
#define PN53X_USB_DRIVER_NAME "PN53x USB"
|
||||||
#define USB_TIMEOUT 0
|
|
||||||
|
|
||||||
#define DRIVER_DATA(pnd) ((struct pn53x_usb_data*)(pnd->driver_data))
|
#define DRIVER_DATA(pnd) ((struct pn53x_usb_data*)(pnd->driver_data))
|
||||||
|
|
||||||
|
@ -78,8 +90,11 @@ int
|
||||||
pn53x_usb_bulk_read (struct pn53x_usb_data *data, byte_t abtRx[], const size_t szRx)
|
pn53x_usb_bulk_read (struct pn53x_usb_data *data, byte_t abtRx[], const size_t szRx)
|
||||||
{
|
{
|
||||||
int res = usb_bulk_read (data->pudh, data->uiEndPointIn, (char *) abtRx, szRx, USB_TIMEOUT);
|
int res = usb_bulk_read (data->pudh, data->uiEndPointIn, (char *) abtRx, szRx, USB_TIMEOUT);
|
||||||
if (res > 0)
|
if (res > 0) {
|
||||||
PRINT_HEX ("RX", abtRx, res);
|
PRINT_HEX ("RX", abtRx, res);
|
||||||
|
} else if (res < 0) {
|
||||||
|
ERR ("Unable to read from USB (%s", _usb_strerror (res));
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
int
|
int
|
||||||
|
@ -87,8 +102,13 @@ int
|
||||||
pn53x_usb_bulk_read_ex (struct pn53x_usb_data *data, byte_t abtRx[], const size_t szRx, int timeout)
|
pn53x_usb_bulk_read_ex (struct pn53x_usb_data *data, byte_t abtRx[], const size_t szRx, int timeout)
|
||||||
{
|
{
|
||||||
int res = usb_bulk_read (data->pudh, data->uiEndPointIn, (char *) abtRx, szRx, timeout);
|
int res = usb_bulk_read (data->pudh, data->uiEndPointIn, (char *) abtRx, szRx, timeout);
|
||||||
if (res > 0)
|
if (res > 0) {
|
||||||
PRINT_HEX ("RX", abtRx, res);
|
PRINT_HEX ("RX", abtRx, res);
|
||||||
|
} else if (res < 0) {
|
||||||
|
if (-res != ETIMEDOUT) {
|
||||||
|
ERR ("Unable to read from USB (%s)", _usb_strerror (res));
|
||||||
|
}
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,10 +117,14 @@ pn53x_usb_bulk_write (struct pn53x_usb_data *data, byte_t abtTx[], const size_t
|
||||||
{
|
{
|
||||||
PRINT_HEX ("TX", abtTx, szTx);
|
PRINT_HEX ("TX", abtTx, szTx);
|
||||||
int res = usb_bulk_write (data->pudh, data->uiEndPointOut, (char *) abtTx, szTx, USB_TIMEOUT);
|
int res = usb_bulk_write (data->pudh, data->uiEndPointOut, (char *) abtTx, szTx, USB_TIMEOUT);
|
||||||
|
if (res > 0) {
|
||||||
// HACK This little hack is a well know problem of USB, see http://www.libusb.org/ticket/6 for more details
|
// HACK This little hack is a well know problem of USB, see http://www.libusb.org/ticket/6 for more details
|
||||||
if ((res % data->uiMaxPacketSize) == 0) {
|
if ((res % data->uiMaxPacketSize) == 0) {
|
||||||
usb_bulk_write (data->pudh, data->uiEndPointOut, "\0", 0, USB_TIMEOUT);
|
usb_bulk_write (data->pudh, data->uiEndPointOut, "\0", 0, USB_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ERR ("Unable to write to USB (%s)", _usb_strerror (res));
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,12 +198,20 @@ pn53x_usb_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * psz
|
||||||
usb_init ();
|
usb_init ();
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
// usb_find_busses will find all of the busses on the system. Returns the number of changes since previous call to this function (total of new busses and busses removed).
|
// usb_find_busses will find all of the busses on the system. Returns the
|
||||||
if ((res = usb_find_busses () < 0))
|
// number of changes since previous call to this function (total of new
|
||||||
|
// busses and busses removed).
|
||||||
|
if ((res = usb_find_busses () < 0)) {
|
||||||
|
ERR ("Unable to find USB busses (%s)", _usb_strerror (res));
|
||||||
return false;
|
return false;
|
||||||
// usb_find_devices will find all of the devices on each bus. This should be called after usb_find_busses. Returns the number of changes since the previous call to this function (total of new device and devices removed).
|
}
|
||||||
if ((res = usb_find_devices () < 0))
|
// usb_find_devices will find all of the devices on each bus. This should be
|
||||||
|
// called after usb_find_busses. Returns the number of changes since the
|
||||||
|
// previous call to this function (total of new device and devices removed).
|
||||||
|
if ((res = usb_find_devices () < 0)) {
|
||||||
|
ERR ("Unable to find USB devices (%s)", _usb_strerror (res));
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
*pszDeviceFound = 0;
|
*pszDeviceFound = 0;
|
||||||
|
|
||||||
|
@ -187,9 +219,10 @@ pn53x_usb_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * psz
|
||||||
struct usb_bus *bus;
|
struct usb_bus *bus;
|
||||||
for (bus = usb_get_busses (); bus; bus = bus->next) {
|
for (bus = usb_get_busses (); bus; bus = bus->next) {
|
||||||
struct usb_device *dev;
|
struct usb_device *dev;
|
||||||
|
|
||||||
for (dev = bus->devices; dev; dev = dev->next, uiBusIndex++) {
|
for (dev = bus->devices; dev; dev = dev->next, uiBusIndex++) {
|
||||||
for (size_t n = 0; n < sizeof (pn53x_usb_supported_devices) / sizeof (struct pn53x_usb_supported_device); n++) {
|
for (size_t n = 0; n < sizeof (pn53x_usb_supported_devices) / sizeof (struct pn53x_usb_supported_device); n++) {
|
||||||
// DBG("Checking device %04x:%04x (%04x:%04x)",dev->descriptor.idVendor,dev->descriptor.idProduct,candidates[i].idVendor,candidates[i].idProduct);
|
//DBG("Checking device %04x:%04x (%04x:%04x)",dev->descriptor.idVendor,dev->descriptor.idProduct);
|
||||||
if ((pn53x_usb_supported_devices[n].vendor_id == dev->descriptor.idVendor) &&
|
if ((pn53x_usb_supported_devices[n].vendor_id == dev->descriptor.idVendor) &&
|
||||||
(pn53x_usb_supported_devices[n].product_id == dev->descriptor.idProduct)) {
|
(pn53x_usb_supported_devices[n].product_id == dev->descriptor.idProduct)) {
|
||||||
// Make sure there are 2 endpoints available
|
// Make sure there are 2 endpoints available
|
||||||
|
@ -208,6 +241,7 @@ pn53x_usb_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * psz
|
||||||
// Set configuration
|
// Set configuration
|
||||||
int res = usb_set_configuration (udev, 1);
|
int res = usb_set_configuration (udev, 1);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
ERR ("Unable to set USB configuration (%s)", _usb_strerror (res));
|
||||||
usb_close (udev);
|
usb_close (udev);
|
||||||
// we failed to use the device
|
// we failed to use the device
|
||||||
continue;
|
continue;
|
||||||
|
@ -285,7 +319,7 @@ pn53x_usb_connect (const nfc_device_desc_t *pndd)
|
||||||
// Set configuration
|
// Set configuration
|
||||||
int res = usb_set_configuration (data.pudh, 1);
|
int res = usb_set_configuration (data.pudh, 1);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
ERR ("Unable to set USB configuration (%s)", strerror (-res));
|
ERR ("Unable to set USB configuration (%s)", _usb_strerror (res));
|
||||||
if (EPERM == -res) {
|
if (EPERM == -res) {
|
||||||
WARN ("Please double check USB permissions for device %04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
|
WARN ("Please double check USB permissions for device %04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
|
||||||
}
|
}
|
||||||
|
@ -296,7 +330,7 @@ pn53x_usb_connect (const nfc_device_desc_t *pndd)
|
||||||
|
|
||||||
res = usb_claim_interface (data.pudh, 0);
|
res = usb_claim_interface (data.pudh, 0);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
DBG ("Can't claim interface (%s)", strerror (-res));
|
ERR ("Unable to claim USB interface (%s)", _usb_strerror (res));
|
||||||
usb_close (data.pudh);
|
usb_close (data.pudh);
|
||||||
// we failed to use the specified device
|
// we failed to use the specified device
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -370,11 +404,11 @@ pn53x_usb_disconnect (nfc_device_t * pnd)
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
if ((res = usb_release_interface (DRIVER_DATA (pnd)->pudh, 0)) < 0) {
|
if ((res = usb_release_interface (DRIVER_DATA (pnd)->pudh, 0)) < 0) {
|
||||||
ERR ("usb_release_interface failed (%i)", res);
|
ERR ("Unable to release USB interface (%s)", _usb_strerror (res));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((res = usb_close (DRIVER_DATA (pnd)->pudh)) < 0) {
|
if ((res = usb_close (DRIVER_DATA (pnd)->pudh)) < 0) {
|
||||||
ERR ("usb_close failed (%i)", res);
|
ERR ("Unable to close USB connection (%s)", _usb_strerror (res));
|
||||||
}
|
}
|
||||||
pn53x_data_free (pnd);
|
pn53x_data_free (pnd);
|
||||||
nfc_device_free (pnd);
|
nfc_device_free (pnd);
|
||||||
|
@ -393,7 +427,6 @@ pn53x_usb_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData)
|
||||||
int res = pn53x_usb_bulk_write (DRIVER_DATA (pnd), abtFrame, szFrame);
|
int res = pn53x_usb_bulk_write (DRIVER_DATA (pnd), abtFrame, szFrame);
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
DBG ("usb_bulk_write failed with error %d", res);
|
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -401,7 +434,6 @@ pn53x_usb_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData)
|
||||||
byte_t abtRxBuf[PN53X_USB_BUFFER_LEN];
|
byte_t abtRxBuf[PN53X_USB_BUFFER_LEN];
|
||||||
res = pn53x_usb_bulk_read (DRIVER_DATA (pnd), abtRxBuf, sizeof (abtRxBuf));
|
res = pn53x_usb_bulk_read (DRIVER_DATA (pnd), abtRxBuf, sizeof (abtRxBuf));
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
DBG ("usb_bulk_read failed with error %d", res);
|
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
// try to interrupt current device state
|
// try to interrupt current device state
|
||||||
pn53x_usb_ack(pnd);
|
pn53x_usb_ack(pnd);
|
||||||
|
@ -419,7 +451,6 @@ pn53x_usb_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData)
|
||||||
// packet.
|
// packet.
|
||||||
int res = pn53x_usb_bulk_write (DRIVER_DATA (pnd), (byte_t *)nack_frame, sizeof(nack_frame));
|
int res = pn53x_usb_bulk_write (DRIVER_DATA (pnd), (byte_t *)nack_frame, sizeof(nack_frame));
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
DBG ("usb_bulk_write failed with error %d", res);
|
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
// try to interrupt current device state
|
// try to interrupt current device state
|
||||||
pn53x_usb_ack(pnd);
|
pn53x_usb_ack(pnd);
|
||||||
|
@ -466,7 +497,6 @@ read:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
DBG ("usb_bulk_read failed with error %d (%s)", res, strerror(-res));
|
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
// try to interrupt current device state
|
// try to interrupt current device state
|
||||||
pn53x_usb_ack(pnd);
|
pn53x_usb_ack(pnd);
|
||||||
|
|
Loading…
Reference in a new issue