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