1 /**
2 @file Connection_uLimeSDR.h
3 @author Lime Microsystems
4 @brief Implementation of STREAM board connection.
5 */
6 
7 #pragma once
8 #include <ConnectionRegistry.h>
9 #include <IConnection.h>
10 #include "LMS64CProtocol.h"
11 #include <vector>
12 #include <string>
13 #include <atomic>
14 #include <memory>
15 #include <thread>
16 
17 #ifndef __unix__
18 #include "windows.h"
19 #include "FTD3XXLibrary/FTD3XX.h"
20 #else
21 #include <libusb.h>
22 #include <mutex>
23 #include <condition_variable>
24 #include <chrono>
25 #endif
26 
27 namespace lime{
28 
29 class ConnectionFT601 : public LMS64CProtocol
30 {
31 public:
32     /** @brief Wrapper class for holding USB asynchronous transfers contexts
33     */
34     class USBTransferContext
35     {
36     public:
USBTransferContext()37         USBTransferContext() : used(false)
38         {
39 #ifndef __unix__
40             context = NULL;
41 #else
42             transfer = libusb_alloc_transfer(0);
43             bytesXfered = 0;
44             done = 0;
45 #endif
46         }
~USBTransferContext()47         ~USBTransferContext()
48         {
49 #ifdef __unix__
50             libusb_free_transfer(transfer);
51 #endif
52         }
53         bool used;
54 #ifndef __unix__
55         PUCHAR context;
56         OVERLAPPED inOvLap;
57 #else
58         libusb_transfer* transfer;
59         long bytesXfered;
60         std::atomic<bool> done;
61         std::mutex transferLock;
62         std::condition_variable cv;
63 #endif
64     };
65 
66     ConnectionFT601(void *arg);
67     ConnectionFT601(void *ctx, const ConnectionHandle &handle);
68 
69     virtual ~ConnectionFT601(void);
70 
71     int Open(const std::string &serial, int vid, int pid);
72     void Close();
73     bool IsOpen();
74     int GetOpenedIndex();
75 
76     int Write(const unsigned char *buffer, int length, int timeout_ms = 100) override;
77     int Read(unsigned char *buffer, int length, int timeout_ms = 100) override;
78 
79     int ProgramWrite(const char *data_src, size_t length, int prog_mode, int device, ProgrammingCallback callback) override;
80 
81     DeviceInfo GetDeviceInfo(void)override;
82 
83     int GPIOWrite(const uint8_t *buffer, size_t bufLength) override;
84     int GPIORead(uint8_t *buffer, size_t bufLength) override;
85     int GPIODirWrite(const uint8_t *buffer, size_t bufLength) override;
86     int GPIODirRead(uint8_t *buffer, size_t bufLength) override;
87 
88 protected:
89     int GetBuffersCount() const override;
90     int CheckStreamSize(int size) const override;
91     int BeginDataReading(char* buffer, uint32_t length, int ep) override;
92     bool WaitForReading(int contextHandle, unsigned int timeout_ms) override;
93     int FinishDataReading(char* buffer, uint32_t length, int contextHandle) override;
94     void AbortReading(int ep) override;
95 
96     int BeginDataSending(const char* buffer, uint32_t length, int ep) override;
97     bool WaitForSending(int contextHandle, uint32_t timeout_ms) override;
98     int FinishDataSending(const char* buffer, uint32_t length, int contextHandle) override;
99     void AbortSending(int ep) override;
100 
101     int ResetStreamBuffers() override;
102 
GetType(void)103     eConnectionType GetType(void) {return USB_PORT;}
104 
105     static const int USB_MAX_CONTEXTS = 16; //maximum number of contexts for asynchronous transfers
106 
107     USBTransferContext contexts[USB_MAX_CONTEXTS];
108     USBTransferContext contextsToSend[USB_MAX_CONTEXTS];
109 
110     bool isConnected;
111 
112     static const int streamWrEp;
113     static const int streamRdEp;
114     static const int ctrlWrEp;
115     static const int ctrlRdEp;
116 #ifndef __unix__
117     FT_HANDLE mFTHandle;
118     int ReinitPipe(unsigned char ep);
119 #else
120     int FT_SetStreamPipe(unsigned char ep, size_t size);
121     int FT_FlushPipe(unsigned char ep);
122     uint32_t mUsbCounter;
123     libusb_device_handle *dev_handle; //a device handle
124     libusb_context *ctx; //a libusb session
125 #endif
126     std::mutex mExtraUsbMutex;
127     uint64_t mSerial;
128 };
129 
130 class ConnectionFT601Entry : public ConnectionRegistryEntry
131 {
132 public:
133     ConnectionFT601Entry(void);
134     ~ConnectionFT601Entry(void);
135     std::vector<ConnectionHandle> enumerate(const ConnectionHandle &hint);
136     IConnection *make(const ConnectionHandle &handle);
137 private:
138 #ifndef __unix__
139     FT_HANDLE* mFTHandle;
140 #else
141     libusb_context *ctx; //a libusb session
142     std::thread mUSBProcessingThread;
143     void handle_libusb_events();
144     std::atomic<bool> mProcessUSBEvents;
145 #endif
146 };
147 
148 }
149