deleted unnecessary files and added lmsSDR, lms7002m directories
This commit is contained in:
@@ -0,0 +1,771 @@
|
||||
/**
|
||||
@file ConnectionUSB.cpp
|
||||
@author Lime Microsystems (www.limemicro.com)
|
||||
@brief Data writing and reading through USB port
|
||||
*/
|
||||
|
||||
#include "ConnectionUSB.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __unix__
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#endif
|
||||
|
||||
#define USB_TIMEOUT 1000
|
||||
|
||||
#define HW_LDIGIRED L"DigiRed"
|
||||
#define HW_LDIGIGREEN L"DigiGreen"
|
||||
#define HW_LSTREAMER L"Stream"
|
||||
|
||||
#define HW_DIGIRED "DigiRed"
|
||||
#define HW_DIGIGREEN "DigiGreen"
|
||||
#define HW_STREAMER "Stream"
|
||||
|
||||
#define CTR_W_REQCODE 0xC1
|
||||
#define CTR_W_VALUE 0x0000
|
||||
#define CTR_W_INDEX 0x0000
|
||||
|
||||
#define CTR_R_REQCODE 0xC0
|
||||
#define CTR_R_VALUE 0x0000
|
||||
#define CTR_R_INDEX 0x0000
|
||||
|
||||
/** @brief Initializes port type and object necessary to communicate to usb device.
|
||||
*/
|
||||
ConnectionUSB::ConnectionUSB()
|
||||
{
|
||||
m_hardwareName = "";
|
||||
isConnected = false;
|
||||
m_connectionType = USB_PORT;
|
||||
#ifndef __unix__
|
||||
USBDevicePrimary = new CCyUSBDevice(NULL);
|
||||
OutCtrEndPt = NULL;
|
||||
InCtrEndPt = NULL;
|
||||
InCtrlEndPt3 = NULL;
|
||||
OutCtrlEndPt3 = NULL;
|
||||
#else
|
||||
dev_handle = 0;
|
||||
devs = 0;
|
||||
int r = libusb_init(&ctx); //initialize the library for the session we just declared
|
||||
if(r < 0)
|
||||
printf("Init Error %i\n", r); //there was an error
|
||||
libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation
|
||||
#endif
|
||||
currentDeviceIndex = -1;
|
||||
}
|
||||
|
||||
/** @brief Closes connection to chip and deallocates used memory.
|
||||
*/
|
||||
ConnectionUSB::~ConnectionUSB()
|
||||
{
|
||||
Close();
|
||||
#ifndef __unix__
|
||||
delete USBDevicePrimary;
|
||||
#else
|
||||
libusb_exit(ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @brief Automatically open first available chip connected to usb port.
|
||||
@return 0-success, other-failure
|
||||
*/
|
||||
IConnection::DeviceStatus ConnectionUSB::Open()
|
||||
{
|
||||
currentDeviceIndex = -1;
|
||||
if(m_deviceNames.size() == 0)
|
||||
RefreshDeviceList();
|
||||
|
||||
#ifndef __unix__
|
||||
for(int i=0; i<USBDevicePrimary->DeviceCount(); ++i)
|
||||
if( Open(i) == SUCCESS)
|
||||
{
|
||||
currentDeviceIndex = i;
|
||||
return SUCCESS;
|
||||
}
|
||||
#else
|
||||
if(Open(0) == SUCCESS)
|
||||
return SUCCESS;
|
||||
#endif
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/** @brief Tries to open connected USB device and find communication endpoints.
|
||||
@return Returns 1-Success, 0-EndPoints not found or device didn't connect.
|
||||
*/
|
||||
IConnection::DeviceStatus ConnectionUSB::Open(unsigned index)
|
||||
{
|
||||
#ifndef __unix__
|
||||
wstring m_hardwareDesc = L"";
|
||||
if( index < USBDevicePrimary->DeviceCount())
|
||||
{
|
||||
if(USBDevicePrimary->Open(index))
|
||||
{
|
||||
m_hardwareDesc = USBDevicePrimary->Product;
|
||||
unsigned int pos;
|
||||
//determine connected board type
|
||||
pos = m_hardwareDesc.find(HW_LDIGIRED, 0);
|
||||
if( pos != wstring::npos )
|
||||
m_hardwareName = HW_DIGIRED;
|
||||
else if (m_hardwareDesc.find(HW_LSTREAMER, 0) != wstring::npos)
|
||||
m_hardwareName = HW_STREAMER;
|
||||
else
|
||||
m_hardwareName = HW_STREAMER;
|
||||
|
||||
|
||||
if (InCtrlEndPt3)
|
||||
{
|
||||
delete InCtrlEndPt3;
|
||||
InCtrlEndPt3 = NULL;
|
||||
}
|
||||
InCtrlEndPt3 = new CCyControlEndPoint(*USBDevicePrimary->ControlEndPt);
|
||||
|
||||
if (OutCtrlEndPt3)
|
||||
{
|
||||
delete OutCtrlEndPt3;
|
||||
OutCtrlEndPt3 = NULL;
|
||||
}
|
||||
OutCtrlEndPt3 = new CCyControlEndPoint(*USBDevicePrimary->ControlEndPt);
|
||||
|
||||
InCtrlEndPt3->ReqCode = CTR_R_REQCODE;
|
||||
InCtrlEndPt3->Value = CTR_R_VALUE;
|
||||
InCtrlEndPt3->Index = CTR_R_INDEX;
|
||||
|
||||
OutCtrlEndPt3->ReqCode = CTR_W_REQCODE;
|
||||
OutCtrlEndPt3->Value = CTR_W_VALUE;
|
||||
OutCtrlEndPt3->Index = CTR_W_INDEX;
|
||||
|
||||
for (int i=0; i<USBDevicePrimary->EndPointCount(); i++)
|
||||
if(USBDevicePrimary->EndPoints[i]->Address == 0x01)
|
||||
{
|
||||
OutEndPt = USBDevicePrimary->EndPoints[i];
|
||||
long len = OutEndPt->MaxPktSize * 64;
|
||||
OutEndPt->SetXferSize(len);
|
||||
break;
|
||||
}
|
||||
for (int i=0; i<USBDevicePrimary->EndPointCount(); i++)
|
||||
if(USBDevicePrimary->EndPoints[i]->Address == 0x81)
|
||||
{
|
||||
InEndPt = USBDevicePrimary->EndPoints[i];
|
||||
long len = InEndPt->MaxPktSize * 64;
|
||||
InEndPt->SetXferSize(len);
|
||||
break;
|
||||
}
|
||||
isConnected = true;
|
||||
return SUCCESS;
|
||||
} //successfully opened device
|
||||
} //if has devices
|
||||
return FAILURE;
|
||||
#else
|
||||
if(index >= 0 && index < m_dev_pid_vid.size())
|
||||
{
|
||||
dev_handle = libusb_open_device_with_vid_pid(ctx, m_dev_pid_vid[index].second, m_dev_pid_vid[index].first);
|
||||
|
||||
if(dev_handle == 0)
|
||||
return FAILURE;
|
||||
if(libusb_kernel_driver_active(dev_handle, 0) == 1) //find out if kernel driver is attached
|
||||
{
|
||||
printf("Kernel Driver Active\n");
|
||||
if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it
|
||||
printf("Kernel Driver Detached!\n");
|
||||
}
|
||||
int r = libusb_claim_interface(dev_handle, 0); //claim interface 0 (the first) of device
|
||||
if(r < 0)
|
||||
{
|
||||
printf("Cannot Claim Interface\n");
|
||||
return CANNOT_CLAIM_INTERFACE;
|
||||
}
|
||||
printf("Claimed Interface\n");
|
||||
isConnected = true;
|
||||
return SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @brief Closes communication to device.
|
||||
*/
|
||||
void ConnectionUSB::Close()
|
||||
{
|
||||
#ifndef __unix__
|
||||
USBDevicePrimary->Close();
|
||||
InEndPt = NULL;
|
||||
OutEndPt = NULL;
|
||||
if (InCtrlEndPt3)
|
||||
{
|
||||
delete InCtrlEndPt3;
|
||||
InCtrlEndPt3 = NULL;
|
||||
}
|
||||
if (OutCtrlEndPt3)
|
||||
{
|
||||
delete OutCtrlEndPt3;
|
||||
OutCtrlEndPt3 = NULL;
|
||||
}
|
||||
#else
|
||||
if(dev_handle != 0)
|
||||
{
|
||||
libusb_release_interface(dev_handle, 0);
|
||||
libusb_close(dev_handle);
|
||||
dev_handle = 0;
|
||||
}
|
||||
#endif
|
||||
isConnected = false;
|
||||
}
|
||||
|
||||
/** @brief Returns connection status
|
||||
@return 1-connection open, 0-connection closed.
|
||||
*/
|
||||
bool ConnectionUSB::IsOpen()
|
||||
{
|
||||
#ifndef __unix__
|
||||
return USBDevicePrimary->IsOpen() && isConnected;
|
||||
#else
|
||||
return isConnected;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @brief Sends given data buffer to chip through USB port.
|
||||
@param buffer data buffer, must not be longer than 64 bytes.
|
||||
@param length given buffer size.
|
||||
@param timeout_ms timeout limit for operation in milliseconds
|
||||
@return number of bytes sent.
|
||||
*/
|
||||
int ConnectionUSB::Write(const unsigned char *buffer, const int length, int timeout_ms)
|
||||
{
|
||||
long len = length;
|
||||
if(IsOpen())
|
||||
{
|
||||
unsigned char* wbuffer = new unsigned char[length];
|
||||
memcpy(wbuffer, buffer, length);
|
||||
if(m_hardwareName == HW_DIGIRED || m_hardwareName == HW_STREAMER)
|
||||
{
|
||||
#ifndef __unix__
|
||||
if(OutCtrlEndPt3)
|
||||
OutCtrlEndPt3->Write(wbuffer, len);
|
||||
else
|
||||
len = 0;
|
||||
#else
|
||||
len = libusb_control_transfer(dev_handle, LIBUSB_REQUEST_TYPE_VENDOR,CTR_W_REQCODE ,CTR_W_VALUE, CTR_W_INDEX, wbuffer, length, USB_TIMEOUT);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef __unix__
|
||||
if(OutCtrEndPt)
|
||||
OutCtrEndPt->XferData(wbuffer, len);
|
||||
else
|
||||
len = 0;
|
||||
#else
|
||||
int actual = 0;
|
||||
libusb_bulk_transfer(dev_handle, 0x01, wbuffer, len, &actual, USB_TIMEOUT);
|
||||
len = actual;
|
||||
#endif
|
||||
}
|
||||
delete wbuffer;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
/** @brief Reads data coming from the chip through USB port.
|
||||
@param buffer pointer to array where received data will be copied, array must be
|
||||
big enough to fit received data.
|
||||
@param length number of bytes to read from chip.
|
||||
@param timeout_ms timeout limit for operation in milliseconds
|
||||
@return number of bytes received.
|
||||
*/
|
||||
int ConnectionUSB::Read(unsigned char *buffer, const int length, int timeout_ms)
|
||||
{
|
||||
long len = length;
|
||||
if(IsOpen())
|
||||
{
|
||||
if(m_hardwareName == HW_DIGIRED || m_hardwareName == HW_STREAMER)
|
||||
{
|
||||
#ifndef __unix__
|
||||
if(InCtrlEndPt3)
|
||||
InCtrlEndPt3->Read(buffer, len);
|
||||
else
|
||||
len = 0;
|
||||
#else
|
||||
len = libusb_control_transfer(dev_handle, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN ,CTR_R_REQCODE ,CTR_R_VALUE, CTR_R_INDEX, buffer, len, USB_TIMEOUT);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef __unix__
|
||||
if(InCtrEndPt)
|
||||
InCtrEndPt->XferData(buffer, len);
|
||||
else
|
||||
len = 0;
|
||||
#else
|
||||
int actual = 0;
|
||||
libusb_bulk_transfer(dev_handle, 0x81, buffer, len, &actual, USB_TIMEOUT);
|
||||
len = actual;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
#ifdef __unix__
|
||||
/** @brief Function for handling libusb callbacks
|
||||
*/
|
||||
void callback_libusbtransfer(libusb_transfer *trans)
|
||||
{
|
||||
USBTransferContext *context = reinterpret_cast<USBTransferContext*>(trans->user_data);
|
||||
switch(trans->status)
|
||||
{
|
||||
case LIBUSB_TRANSFER_CANCELLED:
|
||||
printf("Transfer canceled\n" );
|
||||
context->bytesXfered = trans->actual_length;
|
||||
context->done = true;
|
||||
context->used = false;
|
||||
context->reset();
|
||||
break;
|
||||
case LIBUSB_TRANSFER_COMPLETED:
|
||||
if(trans->actual_length == context->bytesExpected)
|
||||
{
|
||||
context->bytesXfered = trans->actual_length;
|
||||
context->done = true;
|
||||
}
|
||||
//printf("Transfer complete %i\n", trans->actual_length);
|
||||
break;
|
||||
case LIBUSB_TRANSFER_ERROR:
|
||||
printf("TRANSFER ERRRO\n");
|
||||
break;
|
||||
case LIBUSB_TRANSFER_TIMED_OUT:
|
||||
printf("transfer timed out\n");
|
||||
|
||||
break;
|
||||
case LIBUSB_TRANSFER_OVERFLOW:
|
||||
printf("transfer overflow\n");
|
||||
|
||||
break;
|
||||
case LIBUSB_TRANSFER_STALL:
|
||||
printf("transfer stalled\n");
|
||||
break;
|
||||
}
|
||||
context->mPacketProcessed.notify_one();
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @brief Finds all chips connected to usb ports
|
||||
@return number of devices found
|
||||
*/
|
||||
int ConnectionUSB::RefreshDeviceList()
|
||||
{
|
||||
#ifndef __unix__
|
||||
USBDevicePrimary->Close();
|
||||
currentDeviceIndex = -1;
|
||||
m_deviceNames.clear();
|
||||
string name;
|
||||
if (USBDevicePrimary->DeviceCount())
|
||||
{
|
||||
for (int i=0; i<USBDevicePrimary->DeviceCount(); ++i)
|
||||
{
|
||||
Open(i);
|
||||
name = DeviceName();
|
||||
m_deviceNames.push_back(name);
|
||||
}
|
||||
currentDeviceIndex = -1;
|
||||
}
|
||||
#else
|
||||
m_dev_pid_vid.clear();
|
||||
m_deviceNames.clear();
|
||||
int usbDeviceCount = libusb_get_device_list(ctx, &devs);
|
||||
if(usbDeviceCount > 0)
|
||||
{
|
||||
libusb_device_descriptor desc;
|
||||
for(int i=0; i<usbDeviceCount; ++i)
|
||||
{
|
||||
int r = libusb_get_device_descriptor(devs[i], &desc);
|
||||
if(r<0)
|
||||
printf("failed to get device description\n");
|
||||
int pid = desc.idProduct;
|
||||
int vid = desc.idVendor;
|
||||
|
||||
if( vid == 1204)
|
||||
{
|
||||
if(pid == 34323)
|
||||
{
|
||||
m_hardwareName = HW_DIGIGREEN;
|
||||
m_deviceNames.push_back("DigiGreen");
|
||||
m_dev_pid_vid.push_back( pair<int,int>(pid,vid));
|
||||
}
|
||||
else if(pid == 241)
|
||||
{
|
||||
m_hardwareName = HW_DIGIRED;
|
||||
libusb_device_handle *tempDev_handle;
|
||||
tempDev_handle = libusb_open_device_with_vid_pid(ctx, vid, pid);
|
||||
if(libusb_kernel_driver_active(tempDev_handle, 0) == 1) //find out if kernel driver is attached
|
||||
{
|
||||
if(libusb_detach_kernel_driver(tempDev_handle, 0) == 0) //detach it
|
||||
printf("Kernel Driver Detached!\n");
|
||||
}
|
||||
if(libusb_claim_interface(tempDev_handle, 0) < 0) //claim interface 0 (the first) of device
|
||||
{
|
||||
printf("Cannot Claim Interface\n");
|
||||
}
|
||||
|
||||
string fullName;
|
||||
//check operating speed
|
||||
int speed = libusb_get_device_speed(devs[i]);
|
||||
if(speed == LIBUSB_SPEED_HIGH)
|
||||
fullName = "USB 2.0";
|
||||
else if(speed == LIBUSB_SPEED_SUPER)
|
||||
fullName = "USB 3.0";
|
||||
else
|
||||
fullName = "USB";
|
||||
fullName += " (";
|
||||
//read device name
|
||||
char data[255];
|
||||
memset(data, 0, 255);
|
||||
int st = libusb_get_string_descriptor_ascii(tempDev_handle, 2, (unsigned char*)data, 255);
|
||||
if(strlen(data) > 0)
|
||||
fullName += data;
|
||||
fullName += ")";
|
||||
libusb_close(tempDev_handle);
|
||||
|
||||
m_deviceNames.push_back(fullName);
|
||||
m_dev_pid_vid.push_back( pair<int,int>(pid,vid));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
libusb_free_device_list(devs, 1);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return m_deviceNames.size();
|
||||
}
|
||||
|
||||
void ConnectionUSB::ClearComm()
|
||||
{
|
||||
}
|
||||
|
||||
/** @return name of currently opened device as string.
|
||||
*/
|
||||
string ConnectionUSB::DeviceName()
|
||||
{
|
||||
#ifndef __unix__
|
||||
string name;
|
||||
char tempName[USB_STRING_MAXLEN];
|
||||
//memcpy(tempName, USBDevicePrimary->FriendlyName, USB_STRING_MAXLEN);
|
||||
//name = tempName;
|
||||
|
||||
for (int i = 0; i < USB_STRING_MAXLEN; ++i)
|
||||
tempName[i] = USBDevicePrimary->DeviceName[i];
|
||||
if (USBDevicePrimary->bSuperSpeed == true)
|
||||
name = "USB 3.0";
|
||||
else if (USBDevicePrimary->bHighSpeed == true)
|
||||
name = "USB 2.0";
|
||||
else
|
||||
name = "USB";
|
||||
name += " (";
|
||||
name += tempName;
|
||||
name += ")";
|
||||
return name;
|
||||
#else
|
||||
if(dev_handle != 0)
|
||||
{
|
||||
char data[255];
|
||||
int st = libusb_get_string_descriptor_ascii(dev_handle, 2, (unsigned char*)data, 255);
|
||||
return string(data);
|
||||
}
|
||||
return "no name";
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Starts asynchronous data reading from board
|
||||
@param *buffer buffer where to store received data
|
||||
@param length number of bytes to read
|
||||
@return handle of transfer context
|
||||
*/
|
||||
int ConnectionUSB::BeginDataReading(char *buffer, long length)
|
||||
{
|
||||
int i = 0;
|
||||
bool contextFound = false;
|
||||
//find not used context
|
||||
for(i = 0; i<USB_MAX_CONTEXTS; i++)
|
||||
{
|
||||
if(!contexts[i].used)
|
||||
{
|
||||
contextFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!contextFound)
|
||||
return -1;
|
||||
contexts[i].used = true;
|
||||
#ifndef __unix__
|
||||
if(InEndPt)
|
||||
contexts[i].context = InEndPt->BeginDataXfer((unsigned char*)buffer, length, contexts[i].inOvLap);
|
||||
return i;
|
||||
#else
|
||||
unsigned int Timeout = 1000;
|
||||
libusb_transfer *tr = contexts[i].transfer;
|
||||
libusb_fill_bulk_transfer(tr, dev_handle, 0x81, (unsigned char*)buffer, length, callback_libusbtransfer, &contexts[i], Timeout);
|
||||
contexts[i].done = false;
|
||||
contexts[i].bytesXfered = 0;
|
||||
contexts[i].bytesExpected = length;
|
||||
int status = libusb_submit_transfer(tr);
|
||||
int actual = 0;
|
||||
//int status = libusb_bulk_transfer(dev_handle, 0x81, (unsigned char*)buffer, length, &actual, USB_TIMEOUT);
|
||||
if(status != 0)
|
||||
printf("ERROR BEGIN DATA TRANSFER %s\n", libusb_error_name(status));
|
||||
#endif
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Waits for asynchronous data reception
|
||||
@param contextHandle handle of which context data to wait
|
||||
@param timeout_ms number of miliseconds to wait
|
||||
@return 1-data received, 0-data not received
|
||||
*/
|
||||
int ConnectionUSB::WaitForReading(int contextHandle, unsigned int timeout_ms)
|
||||
{
|
||||
if( contexts[contextHandle].used == true && contextHandle >= 0)
|
||||
{
|
||||
int status = 0;
|
||||
#ifndef __unix__
|
||||
if(InEndPt)
|
||||
status = InEndPt->WaitForXfer(contexts[contextHandle].inOvLap, timeout_ms);
|
||||
return status;
|
||||
#else
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
if(libusb_handle_events_timeout_completed(ctx, &tv, NULL) != 0)
|
||||
printf("error libusb_handle_events %i\n", status);
|
||||
|
||||
auto t1 = chrono::high_resolution_clock::now();
|
||||
auto t2 = chrono::high_resolution_clock::now();
|
||||
|
||||
while(contexts[contextHandle].done == false && std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() < timeout_ms)
|
||||
{
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 300;
|
||||
std::this_thread::yield();
|
||||
//if(libusb_handle_events(ctx) != 0)
|
||||
if(libusb_handle_events_timeout_completed(ctx, &tv, NULL) != 0)
|
||||
printf("error libusb_handle_events %i\n", status);
|
||||
t2 = chrono::high_resolution_clock::now();
|
||||
//std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
std::unique_lock<std::mutex> lck(contexts[contextHandle].m_lock);
|
||||
while(contexts[contextHandle].done == false) //is changed in libusb callback
|
||||
{
|
||||
if(contexts[contextHandle].mPacketProcessed.wait_for(lck, std::chrono::milliseconds(timeout_ms)) == std::cv_status::timeout)
|
||||
return 0;
|
||||
}
|
||||
return contexts[contextHandle].done == true;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Finishes asynchronous data reading from board
|
||||
@param buffer array where to store received data
|
||||
@param length number of bytes to read, function changes this value to number of bytes actually received
|
||||
@param contextHandle handle of which context to finish
|
||||
@return false failure, true number of bytes received
|
||||
*/
|
||||
int ConnectionUSB::FinishDataReading(char *buffer, long &length, int contextHandle)
|
||||
{
|
||||
if( contexts[contextHandle].used == true && contextHandle >= 0)
|
||||
{
|
||||
#ifndef __unix__
|
||||
int status = 0;
|
||||
if(InEndPt)
|
||||
status = InEndPt->FinishDataXfer((unsigned char*)buffer, length, contexts[contextHandle].inOvLap, contexts[contextHandle].context);
|
||||
contexts[contextHandle].used = false;
|
||||
contexts[contextHandle].reset();
|
||||
return length;
|
||||
#else
|
||||
length = contexts[contextHandle].bytesXfered;
|
||||
contexts[contextHandle].used = false;
|
||||
contexts[contextHandle].reset();
|
||||
return length;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ConnectionUSB::ReadDataBlocking(char *buffer, long &length, int timeout_ms)
|
||||
{
|
||||
#ifndef __unix__
|
||||
return InEndPt->XferData((unsigned char*)buffer, length);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Aborts reading operations
|
||||
*/
|
||||
void ConnectionUSB::AbortReading()
|
||||
{
|
||||
#ifndef __unix__
|
||||
InEndPt->Abort();
|
||||
#else
|
||||
for(int i=0; i<USB_MAX_CONTEXTS; ++i)
|
||||
{
|
||||
libusb_cancel_transfer( contexts[i].transfer );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Starts asynchronous data Sending to board
|
||||
@param *buffer buffer to send
|
||||
@param length number of bytes to send
|
||||
@return handle of transfer context
|
||||
*/
|
||||
int ConnectionUSB::BeginDataSending(const char *buffer, long length)
|
||||
{
|
||||
int i = 0;
|
||||
//find not used context
|
||||
bool contextFound = false;
|
||||
for(i = 0; i<USB_MAX_CONTEXTS; i++)
|
||||
{
|
||||
if(!contextsToSend[i].used)
|
||||
{
|
||||
contextFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!contextFound)
|
||||
return -1;
|
||||
contextsToSend[i].used = true;
|
||||
#ifndef __unix__
|
||||
if(OutEndPt)
|
||||
contextsToSend[i].context = OutEndPt->BeginDataXfer((unsigned char*)buffer, length, contextsToSend[i].inOvLap);
|
||||
return i;
|
||||
#else
|
||||
unsigned int Timeout = 1000;
|
||||
libusb_transfer *tr = contextsToSend[i].transfer;
|
||||
//libusb_set_iso_packet_lengths(contexts[i].transfer, 512*64);
|
||||
libusb_fill_bulk_transfer(tr, dev_handle, 0x1, (unsigned char*)buffer, length, callback_libusbtransfer, &contextsToSend[i], Timeout);
|
||||
contextsToSend[i].done = false;
|
||||
contextsToSend[i].bytesXfered = 0;
|
||||
contextsToSend[i].bytesExpected = length;
|
||||
libusb_submit_transfer(tr);
|
||||
#endif
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Waits for asynchronous data sending
|
||||
@param contextHandle handle of which context data to wait
|
||||
@param timeout_ms number of miliseconds to wait
|
||||
@return 1-data received, 0-data not received
|
||||
*/
|
||||
int ConnectionUSB::WaitForSending(int contextHandle, unsigned int timeout_ms)
|
||||
{
|
||||
if( contextsToSend[contextHandle].used == true )
|
||||
{
|
||||
#ifndef __unix__
|
||||
int status = 0;
|
||||
if(OutEndPt)
|
||||
status = OutEndPt->WaitForXfer(contextsToSend[contextHandle].inOvLap, timeout_ms);
|
||||
return status;
|
||||
#else
|
||||
auto t1 = chrono::high_resolution_clock::now();
|
||||
auto t2 = chrono::high_resolution_clock::now();
|
||||
while(contextsToSend[contextHandle].done == false && std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() < timeout_ms)
|
||||
{
|
||||
/* struct timeval tv;
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
int status = libusb_handle_events_timeout_completed(ctx, &tv, NULL);
|
||||
if(status != 0)
|
||||
printf("error libusb_handle_events %i\n", status);*/
|
||||
t2 = chrono::high_resolution_clock::now();
|
||||
//std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
std::unique_lock<std::mutex> lck(contextsToSend[contextHandle].m_lock);
|
||||
while(contextsToSend[contextHandle].done == false) //is changed in libusb callback
|
||||
{
|
||||
if(contextsToSend[contextHandle].mPacketProcessed.wait_for(lck, std::chrono::milliseconds(timeout_ms)) == std::cv_status::timeout)
|
||||
return 0;
|
||||
}
|
||||
return contextsToSend[contextHandle].done == true;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Finishes asynchronous data sending to board
|
||||
@param buffer array where to store received data
|
||||
@param length number of bytes to read, function changes this value to number of bytes acctually received
|
||||
@param contextHandle handle of which context to finish
|
||||
@return false failure, true number of bytes sent
|
||||
*/
|
||||
int ConnectionUSB::FinishDataSending(const char *buffer, long &length, int contextHandle)
|
||||
{
|
||||
if( contextsToSend[contextHandle].used == true)
|
||||
{
|
||||
#ifndef __unix__
|
||||
if(OutEndPt)
|
||||
OutEndPt->FinishDataXfer((unsigned char*)buffer, length, contextsToSend[contextHandle].inOvLap, contextsToSend[contextHandle].context);
|
||||
contextsToSend[contextHandle].used = false;
|
||||
contextsToSend[contextHandle].reset();
|
||||
return length;
|
||||
#else
|
||||
length = contextsToSend[contextHandle].bytesXfered;
|
||||
contextsToSend[contextHandle].used = false;
|
||||
contextsToSend[contextHandle].reset();
|
||||
return length;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Aborts sending operations
|
||||
*/
|
||||
void ConnectionUSB::AbortSending()
|
||||
{
|
||||
#ifndef __unix__
|
||||
OutEndPt->Abort();
|
||||
#else
|
||||
for (int i = 0; i<USB_MAX_CONTEXTS; ++i)
|
||||
{
|
||||
libusb_cancel_transfer(contextsToSend[i].transfer);
|
||||
}
|
||||
for(int i=0; i<USB_MAX_CONTEXTS; ++i)
|
||||
{
|
||||
contextsToSend[i].used = false;
|
||||
contextsToSend[i].reset();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int ConnectionUSB::GetOpenedIndex()
|
||||
{
|
||||
return currentDeviceIndex;
|
||||
}
|
||||
|
||||
/** @brief Returns found devices names
|
||||
@return vector of device names
|
||||
*/
|
||||
vector<string> ConnectionUSB::GetDeviceNames()
|
||||
{
|
||||
return m_deviceNames;
|
||||
}
|
||||
Reference in New Issue
Block a user