Files
discoverpixy/emulator/libs/Pixy/src/usblink.cpp
2015-04-25 14:05:44 +02:00

177 lines
4.2 KiB
C++

//
// begin license header
//
// This file is part of Pixy CMUcam5 or "Pixy" for short
//
// All Pixy source code is provided under the terms of the
// GNU General Public License v2 (http://www.gnu.org/licenses/gpl-2.0.html).
// Those wishing to use Pixy source code, software and/or
// technologies under different licensing terms should contact us at
// cmucam@cs.cmu.edu. Such licensing terms are available for
// all portions of the Pixy codebase presented here.
//
// end license header
//
#include <unistd.h>
#include <stdio.h>
#include "usblink.h"
#include "pixy.h"
#include "timer.hpp"
#include "debuglog.h"
#define PIXY_VID 0xB1AC
#define PIXY_DID 0xF000
#define PIXY_DFU_VID 0x1FC9
#define PIXY_DFU_DID 0x000C
#define PIXY_ERROR_USB_IO LIBUSB_ERROR_IO
#define PIXY_ERROR_USB_NOT_FOUND LIBUSB_ERROR_NOT_FOUND
#define PIXY_ERROR_USB_BUSY LIBUSB_ERROR_BUSY
#define PIXY_ERROR_USB_NO_DEVICE LIBUSB_ERROR_NO_DEVICE
USBLink::USBLink()
{
m_handle = 0;
m_context = 0;
m_blockSize = 64;
m_flags = LINK_FLAG_ERROR_CORRECTED;
}
USBLink::~USBLink()
{
if (m_handle)
libusb_close(m_handle);
if (m_context)
libusb_exit(m_context);
}
int USBLink::open()
{
int return_value;
#ifdef __MACOS__
const unsigned int MILLISECONDS_TO_SLEEP = 100;
#endif
log("pixydebug: USBLink::open()\n");
return_value = libusb_init(&m_context);
log("pixydebug: libusb_init() = %d\n", return_value);
if (return_value) {
goto usblink_open__exit;
}
m_handle = libusb_open_device_with_vid_pid(m_context, PIXY_VID, PIXY_DID);
log("pixydebug: libusb_open_device_with_vid_pid() = %d\n", m_handle);
if (m_handle == NULL) {
return_value = PIXY_ERROR_USB_NOT_FOUND;
goto usblink_open__exit;
}
#ifdef __MACOS__
return_value = libusb_reset_device(m_handle);
log("pixydebug: libusb_reset_device() = %d\n", return_value);
usleep(MILLISECONDS_TO_SLEEP * 1000);
#endif
return_value = libusb_set_configuration(m_handle, 1);
log("pixydebug: libusb_set_configuration() = %d\n", return_value);
if (return_value < 0) {
goto usblink_open__close_and_exit;
}
return_value = libusb_claim_interface(m_handle, 1);
log("pixydebug: libusb_claim_interface() = %d\n", return_value);
if (return_value < 0) {
goto usblink_open__close_and_exit;
}
#ifdef __LINUX__
return_value = libusb_reset_device(m_handle);
log("pixydebug: libusb_reset_device() = %d\n", return_value);
#endif
/* Success */
return_value = 0;
goto usblink_open__exit;
usblink_open__close_and_exit:
/* Cleanup after error */
libusb_close(m_handle);
m_handle = 0;
usblink_open__exit:
log("pixydebug: USBLink::open() returned %d\n", return_value);
usleep(100* 1000); //let pixy init pass
return return_value;
}
int USBLink::send(const uint8_t *data, uint32_t len, uint16_t timeoutMs)
{
int res, transferred;
log("pixydebug: USBLink::send()\n");
if (timeoutMs==0) // 0 equals infinity
timeoutMs = 10;
if ((res=libusb_bulk_transfer(m_handle, 0x02, (unsigned char *)data, len, &transferred, timeoutMs))<0)
{
log("pixydebug: libusb_bulk_transfer() = %d\n", res);
#ifdef __MACOS__
libusb_clear_halt(m_handle, 0x02);
#endif
log("pixydebug: USBLink::send() returned %d\n", res);
return res;
}
log("pixydebug: USBLink::send() returned %d\n", transferred);
return transferred;
}
int USBLink::receive(uint8_t *data, uint32_t len, uint16_t timeoutMs)
{
int res, transferred;
log("pixydebug: USBLink::receive()\n");
if (timeoutMs==0) // 0 equals infinity
timeoutMs = 50;
if ((res=libusb_bulk_transfer(m_handle, 0x82, (unsigned char *)data, len, &transferred, timeoutMs))<0)
{
log("pixydebug: libusb_bulk_transfer() = %d\n", res);
#ifdef __MACOS__
libusb_clear_halt(m_handle, 0x82);
#endif
return res;
}
log("pixydebug: libusb_bulk_transfer(%d bytes) = %d\n", len, res);
log("pixydebug: USBLink::receive() returned %d (bytes transferred)\n", transferred);
return transferred;
}
void USBLink::setTimer()
{
timer_.reset();
}
uint32_t USBLink::getTimer()
{
return timer_.elapsed();
}