diff --git a/src/ANT.cpp b/src/ANT.cpp index a727143f2..6d767e9c7 100644 --- a/src/ANT.cpp +++ b/src/ANT.cpp @@ -108,7 +108,7 @@ ANT::ANT(QObject *parent, DeviceConfiguration *devConf) : QThread(parent) // sticks, if it is not available we use stubs #if defined GC_HAVE_LIBUSB usbMode = USBNone; - usb2 = new LibUsb(); + usb2 = new LibUsb(TYPE_ANT); #endif } @@ -671,7 +671,7 @@ int ANT::openPort() int rc; // on windows we try on USB2 then on USB1 then fail... - if ((rc=usb2->open(TYPE_ANT)) != -1) { + if ((rc=usb2->open()) != -1) { usbMode = USB2; return rc; } else if ((rc= USBXpress::open(&devicePort)) != -1) { @@ -693,7 +693,7 @@ int ANT::openPort() #ifdef GC_HAVE_LIBUSB int rc; - if ((rc=usb2->open(TYPE_ANT)) != -1) { + if ((rc=usb2->open()) != -1) { usbMode = USB2; return rc; } else { diff --git a/src/Fortius.cpp b/src/Fortius.cpp index 13ad85813..e20fee161 100644 --- a/src/Fortius.cpp +++ b/src/Fortius.cpp @@ -66,7 +66,7 @@ Fortius::Fortius(QObject *parent, QString) : QThread(parent) memcpy(SLOPE_Command, slope_command, 12); // for interacting over the USB port - usb2 = new LibUsb(); + usb2 = new LibUsb(TYPE_FORTIUS); } Fortius::~Fortius() @@ -327,6 +327,10 @@ void Fortius::run() if (readMessage() > 0) { + msleep(60); //slow down - need to wait for previous interrupt to clear + // before reading. Not sure why, but solves issues + // when working on OSX, and possibly Windows + //---------------------------------------------------------------- // UPDATE BASIC TELEMETRY (HR, CAD, SPD et al) // The data structure is very simple, no bit twiddling needed here @@ -499,7 +503,7 @@ int Fortius::closePort() int Fortius::openPort() { // on windows we try on USB2 then on USB1 then fail... - return usb2->open(TYPE_FORTIUS); + return usb2->open(); } int Fortius::rawWrite(uint8_t *bytes, int size) // unix!! diff --git a/src/LibUsb.cpp b/src/LibUsb.cpp index cd554387a..525d1fead 100644 --- a/src/LibUsb.cpp +++ b/src/LibUsb.cpp @@ -26,7 +26,7 @@ #include "Settings.h" #include "MainWindow.h" -LibUsb::LibUsb() +LibUsb::LibUsb(int type) : type(type) { // dynamic load of libusb on Windows, it is statically linked in Linux @@ -63,34 +63,36 @@ LibUsb::LibUsb() usb_set_debug(0); -#ifdef WIN32 // we initialise whenever we open on Linux/Mac - // Initialize the library. - usb_init(); + if (OperatingSystem != WINDOWS) { + // Initialize the library. + usb_init(); - // Find all busses. - usb_find_busses(); + // Find all busses. + usb_find_busses(); - // Find all connected devices. - usb_find_devices(); -#endif + // Find all connected devices. + usb_find_devices(); + } } -int LibUsb::open(int type) +int LibUsb::open() { -#ifdef WIN32 - if (!isDllLoaded) return -1; -#else + if (OperatingSystem == WINDOWS) { - // Initialize the library. - usb_init(); + if (!isDllLoaded) return -1; - // Find all busses. - usb_find_busses(); + } else { - // Find all connected devices. - usb_find_devices(); -#endif + // Initialize the library. + usb_init(); + + // Find all busses. + usb_find_busses(); + + // Find all connected devices. + usb_find_devices(); + } readBufSize = 0; readBufIndex = 0; @@ -108,23 +110,11 @@ int LibUsb::open(int type) if (device == NULL) return -1; - int rc; -#ifndef WIN32 - // reset the device, god only knows what mess we left it in... - rc = usb_reset(device); - if (rc < 0) qDebug()<<"usb_reset Error: "<< usb_strerror(); -#endif + // Clear halt is needed, but ignore return code + usb_clear_halt(device, writeEndpoint); + usb_clear_halt(device, readEndpoint); -#ifndef Q_OS_MAC - // these functions fail on OS X Lion - rc = usb_clear_halt(device, writeEndpoint); - if (rc < 0) qDebug()<<"usb_clear_halt writeEndpoint Error: "<< usb_strerror(); - - rc = usb_clear_halt(device, readEndpoint); - if (rc < 0) qDebug()<<"usb_clear_halt readEndpoint Error: "<< usb_strerror(); -#endif - - return rc; + return 0; } void LibUsb::close() @@ -145,9 +135,7 @@ int LibUsb::read(char *buf, int bytes) // check it isn't closed already if (!device) return -1; -#ifdef WIN32 - if (!isDllLoaded) return -1; -#endif + if (OperatingSystem == WINDOWS && !isDllLoaded) return -1; // The USB2 stick really doesn't like you reading 1 byte when more are available // so we use a local buffered read @@ -203,18 +191,17 @@ int LibUsb::write(char *buf, int bytes) // check it isn't closed if (!device) return -1; -#ifdef WIN32 - if (!isDllLoaded) return -1; -#endif + if (OperatingSystem == WINDOWS && !isDllLoaded) return -1; -#ifdef WIN32 - int rc = usb_interrupt_write(device, writeEndpoint, buf, bytes, 1000); -#else - // we use a non-interrupted write on Linux/Mac since the interrupt - // write block size is incorectly implemented in the version of - // libusb we build with. It is no less efficent. - int rc = usb_bulk_write(device, writeEndpoint, buf, bytes, 125); -#endif + int rc; + if (OperatingSystem == WINDOWS) { + rc = usb_interrupt_write(device, writeEndpoint, buf, bytes, 1000); + } else { + // we use a non-interrupted write on Linux/Mac since the interrupt + // write block size is incorectly implemented in the version of + // libusb we build with. It is no less efficent. + rc = usb_bulk_write(device, writeEndpoint, buf, bytes, 125); + } if (rc < 0) { @@ -324,21 +311,22 @@ struct usb_dev_handle* LibUsb::OpenFortius() int rc = usb_set_configuration(udev, 1); if (rc < 0) { qDebug()<<"usb_set_configuration Error: "<< usb_strerror(); -#ifdef __linux__ - // looks like the udev rule has not been implemented - qDebug()<<"check permissions on:"<dirname).arg(dev->filename); - qDebug()<<"did you remember to setup a udev rule for this device?"; -#endif + + if (OperatingSystem == LINUX) { + // looks like the udev rule has not been implemented + qDebug()<<"check permissions on:"<dirname).arg(dev->filename); + qDebug()<<"did you remember to setup a udev rule for this device?"; + } } rc = usb_claim_interface(udev, interface); if (rc < 0) qDebug()<<"usb_claim_interface Error: "<< usb_strerror(); -#ifndef Q_OS_MAC - // fails on Mac OS X, we don't actually need it anyway - rc = usb_set_altinterface(udev, alternate); - if (rc < 0) qDebug()<<"usb_set_altinterface Error: "<< usb_strerror(); -#endif + if (OperatingSystem != OSX) { + // fails on Mac OS X, we don't actually need it anyway + rc = usb_set_altinterface(udev, alternate); + if (rc < 0) qDebug()<<"usb_set_altinterface Error: "<< usb_strerror(); + } return udev; } @@ -376,21 +364,21 @@ struct usb_dev_handle* LibUsb::OpenAntStick() int rc = usb_set_configuration(udev, 1); if (rc < 0) { qDebug()<<"usb_set_configuration Error: "<< usb_strerror(); -#ifdef __linux__ - // looks like the udev rule has not been implemented - qDebug()<<"check permissions on:"<dirname).arg(dev->filename); - qDebug()<<"did you remember to setup a udev rule for this device?"; -#endif + if (OperatingSystem == LINUX) { + // looks like the udev rule has not been implemented + qDebug()<<"check permissions on:"<dirname).arg(dev->filename); + qDebug()<<"did you remember to setup a udev rule for this device?"; + } } rc = usb_claim_interface(udev, interface); if (rc < 0) qDebug()<<"usb_claim_interface Error: "<< usb_strerror(); -#ifndef Q_OS_MAC - // fails on Mac OS X, we don't actually need it anyway - rc = usb_set_altinterface(udev, alternate); - if (rc < 0) qDebug()<<"usb_set_altinterface Error: "<< usb_strerror(); -#endif + if (OperatingSystem != OSX) { + // fails on Mac OS X, we don't actually need it anyway + rc = usb_set_altinterface(udev, alternate); + if (rc < 0) qDebug()<<"usb_set_altinterface Error: "<< usb_strerror(); + } return udev; } diff --git a/src/LibUsb.h b/src/LibUsb.h index c6bfbe317..f33bc4b10 100644 --- a/src/LibUsb.h +++ b/src/LibUsb.h @@ -52,8 +52,8 @@ class MainWindow; class LibUsb { public: - LibUsb(); - int open(int type); + LibUsb(int type); + int open(); void close(); int read(char *buf, int bytes); int write(char *buf, int bytes); @@ -107,6 +107,7 @@ private: int readBufSize; bool isDllLoaded; + int type; }; #endif #endif // gc_LibUsb_h