1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/**
@file ConnectionUSB.h
@author Lime Microsystems (www.limemicro.com)
@brief Class for data writing and reading through USB port
*/
#ifndef USB_PORT_CONNECTION_H
#define USB_PORT_CONNECTION_H
#include "IConnection.h"
#ifndef __unix__
#include "windows.h"
#include "CyAPI.h"
#else
#include <libusb-1.0/libusb.h>
#include <mutex>
#include <condition_variable>
#include <chrono>
#endif
#define USB_MAX_CONTEXTS 64 //maximum number of contexts for asynchronous transfers
/** @brief Wrapper class for holding USB asynchronous transfers contexts
*/
class USBTransferContext
{
public:
USBTransferContext() : used(false)
{
#ifndef __unix__
inOvLap = new OVERLAPPED;
memset(inOvLap, 0, sizeof(OVERLAPPED));
inOvLap->hEvent = CreateEvent(NULL, false, false, NULL);
context = NULL;
#else
transfer = libusb_alloc_transfer(0);
bytesXfered = 0;
bytesExpected = 0;
done = 0;
#endif
}
~USBTransferContext()
{
#ifndef __unix__
CloseHandle(inOvLap->hEvent);
delete inOvLap;
#else
libusb_free_transfer(transfer);
#endif
}
bool reset()
{
if(used)
return false;
#ifndef __unix__
CloseHandle(inOvLap->hEvent);
memset(inOvLap, 0, sizeof(OVERLAPPED));
inOvLap->hEvent = CreateEvent(NULL, false, false, NULL);
#endif
return true;
}
bool used;
#ifndef __unix__
PUCHAR context;
OVERLAPPED *inOvLap;
#else
libusb_transfer* transfer;
long bytesXfered;
long bytesExpected;
bool done;
std::mutex m_lock;
std::condition_variable mPacketProcessed;
#endif
};
class ConnectionUSB : public IConnection
{
public:
ConnectionUSB();
~ConnectionUSB();
void FindDevices();
DeviceStatus Open();
DeviceStatus Open(unsigned index);
void Close();
bool IsOpen();
int GetOpenedIndex();
int Write(const unsigned char *buffer, int length, int timeout_ms = 0);
int Read(unsigned char *buffer, int length, int timeout_ms = 0);
virtual int BeginDataReading(char *buffer, long length);
virtual int WaitForReading(int contextHandle, unsigned int timeout_ms);
virtual int FinishDataReading(char *buffer, long &length, int contextHandle);
virtual void AbortReading();
virtual int ReadDataBlocking(char *buffer, long &length, int timeout_ms);
virtual int BeginDataSending(const char *buffer, long length);
virtual int WaitForSending(int contextHandle, unsigned int timeout_ms);
virtual int FinishDataSending(const char *buffer, long &length, int contextHandle);
virtual void AbortSending();
std::vector<std::string> GetDeviceNames();
int RefreshDeviceList();
void ClearComm();
private:
int currentDeviceIndex;
std::string DeviceName();
std::vector<std::string> m_deviceNames;
std::string m_hardwareName;
int m_hardwareVer;
USBTransferContext contexts[USB_MAX_CONTEXTS];
USBTransferContext contextsToSend[USB_MAX_CONTEXTS];
void Initialize();
bool isConnected;
int currentPortIndex;
#ifndef __unix__
CCyUSBDevice *USBDevicePrimary;
//control endpoints for DigiRed
CCyControlEndPoint *InCtrlEndPt3;
CCyControlEndPoint *OutCtrlEndPt3;
//control endpoints for DigiGreen
CCyUSBEndPoint *OutCtrEndPt;
CCyUSBEndPoint *InCtrEndPt;
//end points for samples reading and writing
CCyUSBEndPoint *InEndPt;
CCyUSBEndPoint *OutEndPt;
#else
libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
libusb_device_handle *dev_handle; //a device handle
libusb_context *ctx; //a libusb session
std::vector<std::pair<int,int> > m_dev_pid_vid;
#endif
};
#endif