Remove libftdi dependency

Libusb was already doing the bulk of the work...
This commit just removes what basically was a dependency
for a very small amount of code.
This commit is contained in:
Lorenzooone 2025-03-25 21:16:35 +01:00
parent dc24a41394
commit facf6b4ce5
12 changed files with 604 additions and 539 deletions

View File

@ -13,10 +13,10 @@ set(OLD_DS_3DS_LOOPY_SUPPORT 1)
set(CYPRESS_NISETRO_SUPPORT 1)
set(USE_FTD2XX_FOR_NEW_DS_LOOPY ${NEW_DS_LOOPY_SUPPORT})
set(USE_LIBFTDI_FOR_NEW_DS_LOOPY ${NEW_DS_LOOPY_SUPPORT})
set(USE_LIBUSB_FOR_NEW_DS_LOOPY ${NEW_DS_LOOPY_SUPPORT})
set(USE_FTD3XX_FOR_N3DSXL_LOOPY ${N3DSXL_LOOPY_SUPPORT})
set(USE_LIBUSB_FOR_N3DSXL_LOOPY ${N3DSXL_LOOPY_SUPPORT})
set(USE_LIBUSB_SUPPORT ${IS_DEVICES_SUPPORT} OR ${OLD_DS_3DS_LOOPY_SUPPORT} OR ${USE_LIBFTDI_FOR_NEW_DS_LOOPY} OR ${CYPRESS_NISETRO_SUPPORT} OR ${USE_LIBUSB_FOR_N3DSXL_LOOPY})
set(USE_LIBUSB_SUPPORT ${IS_DEVICES_SUPPORT} OR ${OLD_DS_3DS_LOOPY_SUPPORT} OR ${USE_LIBUSB_FOR_NEW_DS_LOOPY} OR ${CYPRESS_NISETRO_SUPPORT} OR ${USE_LIBUSB_FOR_N3DSXL_LOOPY})
if(NOT (${CMAKE_SYSTEM_NAME} STREQUAL "Windows"))
#Performance outside of Windows is very bad for the official drivers...
set(USE_FTD2XX_FOR_NEW_DS_LOOPY 0)
@ -101,13 +101,6 @@ if(USE_LIBUSB_SUPPORT)
OVERRIDE_FIND_PACKAGE)
endif()
if(USE_LIBFTDI_FOR_NEW_DS_LOOPY)
FetchContent_Declare(libftdi1
GIT_REPOSITORY git://developer.intra2net.com/libftdi
GIT_TAG master
)
endif()
if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows")
set(HOST_FINAL_EXTENSION ".exe")
set(SCRIPT_EXTENSION ".bat")
@ -379,13 +372,12 @@ if(NEW_DS_LOOPY_SUPPORT)
list(APPEND EXTRA_CXX_FLAGS "-DUSE_FTD2")
endif()
endif()
if(USE_LIBFTDI_FOR_NEW_DS_LOOPY)
list(APPEND FETCH_CONTENT_MAKE_AVAILABLE_LIBRARIES_SEPARATE libftdi1)
list(APPEND SOURCE_CPP_EXTRA_FILES ${SOURCE_CPP_FTD2_FILES_BASE_PATH}/dscapture_libftdi2.cpp)
if(USE_LIBUSB_FOR_NEW_DS_LOOPY)
list(APPEND SOURCE_CPP_EXTRA_FILES ${SOURCE_CPP_FTD2_FILES_BASE_PATH}/dscapture_ftd2_libusb.cpp)
if(MSVC)
list(APPEND EXTRA_CXX_FLAGS "/DUSE_FTD2_LIBFTDI")
list(APPEND EXTRA_CXX_FLAGS "/DUSE_FTD2_LIBUSB")
else()
list(APPEND EXTRA_CXX_FLAGS "-DUSE_FTD2_LIBFTDI")
list(APPEND EXTRA_CXX_FLAGS "-DUSE_FTD2_LIBUSB")
endif()
endif()
if(USE_FTD2XX_FOR_NEW_DS_LOOPY)
@ -414,9 +406,6 @@ endif()
if(USE_LIBUSB_SUPPORT)
list(APPEND EXTRA_INCLUDE_DIRECTORIES ${libusb_SOURCE_DIR}/libusb/libusb)
endif()
if(USE_LIBFTDI_FOR_NEW_DS_LOOPY)
list(APPEND EXTRA_INCLUDE_DIRECTORIES ${libftdi1_SOURCE_DIR}/src)
endif()
if(IS_DIRECTORY "${sfml_SOURCE_DIR}")
set_property(DIRECTORY ${sfml_SOURCE_DIR} PROPERTY EXCLUDE_FROM_ALL YES)
@ -428,12 +417,6 @@ if(USE_LIBUSB_SUPPORT)
endif()
endif()
if(USE_LIBFTDI_FOR_NEW_DS_LOOPY)
if(IS_DIRECTORY "${libftdi1_SOURCE_DIR}")
set_property(DIRECTORY ${libftdi1_SOURCE_DIR} PROPERTY EXCLUDE_FROM_ALL YES)
endif()
endif()
if(USE_FTD3XX_FOR_N3DSXL_LOOPY)
file(MAKE_DIRECTORY ${ftd3xx_BINARY_DIR}/win)
file(MAKE_DIRECTORY ${ftd3xx_BINARY_DIR}/macos)
@ -538,9 +521,6 @@ endif()
if(USE_FTD3XX_FOR_N3DSXL_LOOPY)
target_link_libraries(${OUTPUT_NAME} PRIVATE ${ftd3xx_BINARY_DIR}/${FTD3XX_SUBFOLDER}/${FTD3XX_LIB})
endif()
if(USE_LIBFTDI_FOR_NEW_DS_LOOPY)
target_link_libraries(${OUTPUT_NAME} PRIVATE ftdi1-static)
endif()
if(USE_FTD2XX_FOR_NEW_DS_LOOPY)
target_link_libraries(${OUTPUT_NAME} PRIVATE ${ftd2xx_BINARY_DIR}/${FTD2XX_SUBFOLDER}/${FTD2XX_LIB})
endif()

View File

@ -27,7 +27,7 @@ cc3dsfs has three build dependencies: CMake, g++ and git.
Make sure all are installed.
On MacOS, [Homebrew](https://brew.sh/) can be used to install both CMake and git. An automatic popup should appear to install g++ at Compile time.
cc3dsfs has five library dependencies: [FTDI's D3XX driver](https://ftdichip.com/drivers/d3xx-drivers/) (on Windows), [FTDI's D2XX driver](https://ftdichip.com/drivers/d2xx-drivers/) (on Windows), [libusb](https://libusb.info/), [libftdi](https://www.intra2net.com/en/developer/libftdi/) and [SFML](https://www.sfml-dev.org/).
cc3dsfs has four library dependencies: [FTDI's D3XX driver](https://ftdichip.com/drivers/d3xx-drivers/) (on Windows), [FTDI's D2XX driver](https://ftdichip.com/drivers/d2xx-drivers/) (on Windows), [libusb](https://libusb.info/) and [SFML](https://www.sfml-dev.org/).
All of them should get downloaded automatically via CMake during the building process.
Linux users who wish to compile this, will also need to install the SFML dependencies. Different distributions will require slightly different processes.

View File

@ -7,23 +7,23 @@
void list_devices_ftd2_compatibility(std::vector<CaptureDevice> &devices_list, std::vector<no_access_recap_data> &no_access_list);
void ftd2_capture_main_loop(CaptureData* capture_data);
int ftd2_get_queue_status(void* handle, bool is_libftdi, size_t* bytes_in);
bool ftd2_is_error(int value, bool is_libftdi);
int ftd2_write(void* handle, bool is_libftdi, const uint8_t* data, size_t size, size_t *sent);
int ftd2_read(void* handle, bool is_libftdi, uint8_t* data, size_t size, size_t *bytesIn);
int ftd2_set_timeouts(void* handle, bool is_libftdi, int timeout_read, int timeout_write);
int ftd2_reset_device(void* handle, bool is_libftdi);
int ftd2_set_usb_parameters(void* handle, bool is_libftdi, size_t size_in, size_t size_out);
int ftd2_set_chars(void* handle, bool is_libftdi, unsigned char eventch, unsigned char event_enable, unsigned char errorch, unsigned char error_enable);
int ftd2_set_latency_timer(void* handle, bool is_libftdi, unsigned char latency);
int ftd2_set_flow_ctrl_rts_cts(void* handle, bool is_libftdi);
int ftd2_reset_bitmode(void* handle, bool is_libftdi);
int ftd2_set_mpsse_bitmode(void* handle, bool is_libftdi);
int ftd2_set_fifo_bitmode(void* handle, bool is_libftdi);
int ftd2_purge_all(void* handle, bool is_libftdi);
int ftd2_read_ee(void* handle, bool is_libftdi, int eeprom_addr, int *eeprom_val);
int ftd2_close(void* handle, bool is_libftdi);
int ftd2_open(CaptureDevice* device, void** handle, bool is_libftdi);
int ftd2_get_queue_status(void* handle, bool is_ftd2_libusb, size_t* bytes_in);
bool ftd2_is_error(int value, bool is_ftd2_libusb);
int ftd2_write(void* handle, bool is_ftd2_libusb, const uint8_t* data, size_t size, size_t *sent);
int ftd2_read(void* handle, bool is_ftd2_libusb, uint8_t* data, size_t size, size_t *bytesIn);
int ftd2_set_timeouts(void* handle, bool is_ftd2_libusb, int timeout_read, int timeout_write);
int ftd2_reset_device(void* handle, bool is_ftd2_libusb);
int ftd2_set_usb_parameters(void* handle, bool is_ftd2_libusb, size_t size_in, size_t size_out);
int ftd2_set_chars(void* handle, bool is_ftd2_libusb, unsigned char eventch, unsigned char event_enable, unsigned char errorch, unsigned char error_enable);
int ftd2_set_latency_timer(void* handle, bool is_ftd2_libusb, unsigned char latency);
int ftd2_set_flow_ctrl_rts_cts(void* handle, bool is_ftd2_libusb);
int ftd2_reset_bitmode(void* handle, bool is_ftd2_libusb);
int ftd2_set_mpsse_bitmode(void* handle, bool is_ftd2_libusb);
int ftd2_set_fifo_bitmode(void* handle, bool is_ftd2_libusb);
int ftd2_purge_all(void* handle, bool is_ftd2_libusb);
int ftd2_read_ee(void* handle, bool is_ftd2_libusb, int eeprom_addr, int *eeprom_val);
int ftd2_close(void* handle, bool is_ftd2_libusb);
int ftd2_open(CaptureDevice* device, void** handle, bool is_ftd2_libusb);
void ftd2_init();
void ftd2_end();

View File

@ -45,7 +45,7 @@ const int get_ftd2_fw_index(int index);
uint64_t get_max_samples(bool is_rgb888);
uint64_t get_capture_size(bool is_rgb888);
size_t remove_synch_from_final_length(uint32_t* out_buffer, size_t real_length);
bool enable_capture(void* handle, bool is_libftdi);
bool enable_capture(void* handle, bool is_ftd2_libusb);
bool synchronization_check(uint16_t* data_buffer, size_t size, uint16_t* next_data_buffer, size_t* next_size, bool special_check = false);
#endif

View File

@ -0,0 +1,37 @@
#ifndef __DSCAPTURE_FTD2_LIBUSB_HPP
#define __DSCAPTURE_FTD2_LIBUSB_HPP
#include "dscapture_ftd2_shared.hpp"
#include "capture_structs.hpp"
enum ftd2_mpsse_mode {
FTD2_MPSSE_BITMODE_RESET = 0x00,
FTD2_MPSSE_BITMODE_MPSSE = 0x02,
FTD2_MPSSE_BITMODE_SYNCFIFO = 0x40,
};
enum ftd2_flow_ctrls {
FTD2_SIO_RTS_CTS_HS = 0x1 << 8,
FTD2_SIO_XON_XOFF_HS = 0x4 << 8,
};
void ftd2_libusb_init();
void ftd2_libusb_end();
void list_devices_ftd2_libusb(std::vector<CaptureDevice> &devices_list, std::vector<no_access_recap_data> &no_access_list);
void ftd2_capture_main_loop_libusb(CaptureData* capture_data);
int ftd2_libusb_reset(void* handle);
int ftd2_libusb_set_latency_timer(void* handle, unsigned char latency);
int ftd2_libusb_setflowctrl(void* handle, int flowctrl, unsigned char xon, unsigned char xoff);
int ftd2_libusb_set_bitmode(void* handle, unsigned char bitmask, unsigned char mode);
int ftd2_libusb_purge(void* handle, bool do_read, bool do_write);
int ftd2_libusb_read_eeprom(void* handle, int eeprom_addr, int *eeprom_val);
int ftd2_libusb_set_chars(void* handle, unsigned char eventch, unsigned char event_enable, unsigned char errorch, unsigned char error_enable);
int ftd2_libusb_set_usb_chunksizes(void* handle, unsigned int chunksize_in, unsigned int chunksize_out);
void ftd2_libusb_set_timeouts(void* handle, int timeout_in_ms, int timeout_out_ms);
int ftd2_libusb_write(void* handle, const uint8_t* data, size_t size, size_t* bytesOut);
int ftd2_libusb_read(void* handle, uint8_t* data, size_t size, size_t* bytesIn);
int get_ftd2_libusb_read_queue_size(void* handle, size_t* bytesIn);
int ftd2_libusb_open_serial(CaptureDevice* device, void** handle);
int ftd2_libusb_close(void* handle);
#endif

View File

@ -1,27 +0,0 @@
#ifndef __DSCAPTURE_LIBFTDI2_HPP
#define __DSCAPTURE_LIBFTDI2_HPP
#include "dscapture_ftd2_shared.hpp"
#include "capture_structs.hpp"
void libftdi_init();
void libftdi_end();
void list_devices_libftdi(std::vector<CaptureDevice> &devices_list, std::vector<no_access_recap_data> &no_access_list);
void ftd2_capture_main_loop_libftdi(CaptureData* capture_data);
int libftdi_reset(void* handle);
int libftdi_set_latency_timer(void* handle, unsigned char latency);
int libftdi_setflowctrl(void* handle, int flowctrl, unsigned char xon, unsigned char xoff);
int libftdi_set_bitmode(void* handle, unsigned char bitmask, unsigned char mode);
int libftdi_purge(void* handle, bool do_read, bool do_write);
int libftdi_read_eeprom(void* handle, int eeprom_addr, int *eeprom_val);
int libftdi_set_chars(void* handle, unsigned char eventch, unsigned char event_enable, unsigned char errorch, unsigned char error_enable);
int libftdi_set_usb_chunksizes(void* handle, unsigned int chunksize_in, unsigned int chunksize_out);
void libftdi_set_timeouts(void* handle, int timeout_in_ms, int timeout_out_ms);
int libftdi_write(void* handle, const uint8_t* data, size_t size, size_t* bytesOut);
int libftdi_read(void* handle, uint8_t* data, size_t size, size_t* bytesIn);
int get_libftdi_read_queue_size(void* handle, size_t* bytesIn);
int libftdi_open_serial(CaptureDevice* device, void** handle);
int libftdi_close(void* handle);
#endif

View File

@ -1,26 +0,0 @@
The C library "libftdi1" is distributed under the
GNU Library General Public License version 2.
A copy of the GNU Library General Public License (LGPL) is included
in this distribution, in the file COPYING.LIB.
----------------------------------------------------------------------
The C++ wrapper "ftdipp1" is distributed under the GNU General
Public License version 2 (with a special exception described below).
A copy of the GNU General Public License (GPL) is included
in this distribution, in the file COPYING.GPL.
As a special exception, if other files instantiate templates or use macros
or inline functions from this file, or you compile this file and link it
with other works to produce a work based on this file, this file
does not by itself cause the resulting work to be covered
by the GNU General Public License.
However the source code for this file must still be made available
in accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.

View File

@ -1,11 +1,8 @@
#include "dscapture_libftdi2.hpp"
#include "dscapture_ftd2_libusb.hpp"
#include "dscapture_ftd2_driver.hpp"
#include "devicecapture.hpp"
#include "dscapture_ftd2_compatibility.hpp"
#ifdef USE_FTD2_LIBFTDI
#include <ftdi.h>
#endif
#ifdef USE_FTD2_DRIVER
#define FTD2XX_STATIC
#include "ftd2xx_symbols_renames.h"
@ -23,251 +20,251 @@ void list_devices_ftd2_compatibility(std::vector<CaptureDevice> &devices_list, s
#ifdef USE_FTD2_DRIVER
list_devices_ftd2_driver(devices_list, no_access_list);
#endif
#ifdef USE_FTD2_LIBFTDI
list_devices_libftdi(devices_list, no_access_list);
#ifdef USE_FTD2_LIBUSB
list_devices_ftd2_libusb(devices_list, no_access_list);
#endif
}
void ftd2_capture_main_loop(CaptureData* capture_data) {
bool is_libftdi = capture_data->status.device.descriptor != NULL;
bool is_ftd2_libusb = capture_data->status.device.descriptor != NULL;
#ifdef USE_FTD2_DRIVER
if(!is_libftdi)
if(!is_ftd2_libusb)
return ftd2_capture_main_loop_driver(capture_data);
#endif
#ifdef USE_FTD2_LIBFTDI
return ftd2_capture_main_loop_libftdi(capture_data);
#ifdef USE_FTD2_LIBUSB
return ftd2_capture_main_loop_libusb(capture_data);
#endif
}
int ftd2_get_queue_status(void* handle, bool is_libftdi, size_t* bytes_in) {
int ftd2_get_queue_status(void* handle, bool is_ftd2_libusb, size_t* bytes_in) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi) {
if(!is_ftd2_libusb) {
DWORD bytesIn = 0;
FT_STATUS ftStatus = FT_GetQueueStatus(handle, &bytesIn);
*bytes_in = bytesIn;
return ftStatus;
}
#endif
#ifdef USE_FTD2_LIBFTDI
return get_libftdi_read_queue_size(handle, bytes_in);
#ifdef USE_FTD2_LIBUSB
return get_ftd2_libusb_read_queue_size(handle, bytes_in);
#else
return FT_OK;
#endif
}
bool ftd2_is_error(int value, bool is_libftdi) {
bool ftd2_is_error(int value, bool is_ftd2_libusb) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi)
if(!is_ftd2_libusb)
return FT_FAILED(value);
#endif
#ifdef USE_FTD2_LIBFTDI
#ifdef USE_FTD2_LIBUSB
return value < 0;
#else
return FT_OK;
#endif
}
int ftd2_write(void* handle, bool is_libftdi, const uint8_t* data, size_t size, size_t *sent) {
int ftd2_write(void* handle, bool is_ftd2_libusb, const uint8_t* data, size_t size, size_t *sent) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi) {
if(!is_ftd2_libusb) {
DWORD inner_sent = 0;
FT_STATUS ftStatus = FT_Write(handle, (void*)data, size, &inner_sent);
*sent = inner_sent;
return ftStatus;
}
#endif
#ifdef USE_FTD2_LIBFTDI
return libftdi_write(handle, data, size, sent);
#ifdef USE_FTD2_LIBUSB
return ftd2_libusb_write(handle, data, size, sent);
#else
return FT_OK;
#endif
}
int ftd2_read(void* handle, bool is_libftdi, uint8_t* data, size_t size, size_t *bytesIn) {
int ftd2_read(void* handle, bool is_ftd2_libusb, uint8_t* data, size_t size, size_t *bytesIn) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi) {
if(!is_ftd2_libusb) {
DWORD inner_bytes_in = 0;
FT_STATUS ftStatus = FT_Read(handle, (void*)data, size, &inner_bytes_in);
*bytesIn = inner_bytes_in;
return ftStatus;
}
#endif
#ifdef USE_FTD2_LIBFTDI
return libftdi_read(handle, data, size, bytesIn);
#ifdef USE_FTD2_LIBUSB
return ftd2_libusb_read(handle, data, size, bytesIn);
#else
return FT_OK;
#endif
}
int ftd2_set_timeouts(void* handle, bool is_libftdi, int timeout_read, int timeout_write) {
int ftd2_set_timeouts(void* handle, bool is_ftd2_libusb, int timeout_read, int timeout_write) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi)
if(!is_ftd2_libusb)
return FT_SetTimeouts(handle, timeout_read, timeout_write);
#endif
#ifdef USE_FTD2_LIBFTDI
libftdi_set_timeouts(handle, timeout_read, timeout_write);
#ifdef USE_FTD2_LIBUSB
ftd2_libusb_set_timeouts(handle, timeout_read, timeout_write);
return 0;
#else
return FT_OK;
#endif
}
int ftd2_reset_device(void* handle, bool is_libftdi) {
int ftd2_reset_device(void* handle, bool is_ftd2_libusb) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi)
if(!is_ftd2_libusb)
return FT_ResetDevice(handle);
#endif
#ifdef USE_FTD2_LIBFTDI
return libftdi_reset(handle);
#ifdef USE_FTD2_LIBUSB
return ftd2_libusb_reset(handle);
#else
return FT_OK;
#endif
}
int ftd2_set_usb_parameters(void* handle, bool is_libftdi, size_t size_in, size_t size_out) {
int ftd2_set_usb_parameters(void* handle, bool is_ftd2_libusb, size_t size_in, size_t size_out) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi)
if(!is_ftd2_libusb)
return FT_SetUSBParameters(handle, size_in, size_out);
#endif
#ifdef USE_FTD2_LIBFTDI
return libftdi_set_usb_chunksizes(handle, size_in, size_out);
#ifdef USE_FTD2_LIBUSB
return ftd2_libusb_set_usb_chunksizes(handle, size_in, size_out);
#else
return FT_OK;
#endif
}
int ftd2_set_chars(void* handle, bool is_libftdi, unsigned char eventch, unsigned char event_enable, unsigned char errorch, unsigned char error_enable) {
int ftd2_set_chars(void* handle, bool is_ftd2_libusb, unsigned char eventch, unsigned char event_enable, unsigned char errorch, unsigned char error_enable) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi)
if(!is_ftd2_libusb)
return FT_SetChars(handle, eventch, event_enable, errorch, error_enable);
#endif
#ifdef USE_FTD2_LIBFTDI
return libftdi_set_chars(handle, eventch, event_enable, errorch, error_enable);
#ifdef USE_FTD2_LIBUSB
return ftd2_libusb_set_chars(handle, eventch, event_enable, errorch, error_enable);
#else
return FT_OK;
#endif
}
int ftd2_set_latency_timer(void* handle, bool is_libftdi, unsigned char latency) {
int ftd2_set_latency_timer(void* handle, bool is_ftd2_libusb, unsigned char latency) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi)
if(!is_ftd2_libusb)
return FT_SetLatencyTimer(handle, latency);
#endif
#ifdef USE_FTD2_LIBFTDI
return libftdi_set_latency_timer(handle, latency);
#ifdef USE_FTD2_LIBUSB
return ftd2_libusb_set_latency_timer(handle, latency);
#else
return FT_OK;
#endif
}
int ftd2_set_flow_ctrl_rts_cts(void* handle, bool is_libftdi) {
int ftd2_set_flow_ctrl_rts_cts(void* handle, bool is_ftd2_libusb) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi)
if(!is_ftd2_libusb)
return FT_SetFlowControl(handle, FT_FLOW_RTS_CTS, 0, 0);
#endif
#ifdef USE_FTD2_LIBFTDI
return libftdi_setflowctrl(handle, SIO_RTS_CTS_HS, 0, 0);
#ifdef USE_FTD2_LIBUSB
return ftd2_libusb_setflowctrl(handle, FTD2_SIO_RTS_CTS_HS, 0, 0);
#else
return FT_OK;
#endif
}
int ftd2_reset_bitmode(void* handle, bool is_libftdi) {
int ftd2_reset_bitmode(void* handle, bool is_ftd2_libusb) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi)
if(!is_ftd2_libusb)
return FT_SetBitMode(handle, 0x00, FT_BITMODE_RESET);
#endif
#ifdef USE_FTD2_LIBFTDI
return libftdi_set_bitmode(handle, 0x00, BITMODE_RESET);
#ifdef USE_FTD2_LIBUSB
return ftd2_libusb_set_bitmode(handle, 0x00, FTD2_MPSSE_BITMODE_RESET);
#else
return FT_OK;
#endif
}
int ftd2_set_mpsse_bitmode(void* handle, bool is_libftdi) {
int ftd2_set_mpsse_bitmode(void* handle, bool is_ftd2_libusb) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi)
if(!is_ftd2_libusb)
return FT_SetBitMode(handle, 0x00, FT_BITMODE_MPSSE);
#endif
#ifdef USE_FTD2_LIBFTDI
return libftdi_set_bitmode(handle, 0x00, BITMODE_MPSSE);
#ifdef USE_FTD2_LIBUSB
return ftd2_libusb_set_bitmode(handle, 0x00, FTD2_MPSSE_BITMODE_MPSSE);
#else
return FT_OK;
#endif
}
int ftd2_set_fifo_bitmode(void* handle, bool is_libftdi) {
int ftd2_set_fifo_bitmode(void* handle, bool is_ftd2_libusb) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi)
if(!is_ftd2_libusb)
return FT_SetBitMode(handle, 0x00, FT_BITMODE_SYNC_FIFO);
#endif
#ifdef USE_FTD2_LIBFTDI
return libftdi_set_bitmode(handle, 0x00, BITMODE_SYNCFF);
#ifdef USE_FTD2_LIBUSB
return ftd2_libusb_set_bitmode(handle, 0x00, FTD2_MPSSE_BITMODE_SYNCFIFO);
#else
return FT_OK;
#endif
}
int ftd2_purge_all(void* handle, bool is_libftdi) {
int ftd2_purge_all(void* handle, bool is_ftd2_libusb) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi)
if(!is_ftd2_libusb)
return FT_Purge(handle, FT_PURGE_RX | FT_PURGE_TX);
#endif
#ifdef USE_FTD2_LIBFTDI
return libftdi_purge(handle, true, true);
#ifdef USE_FTD2_LIBUSB
return ftd2_libusb_purge(handle, true, true);
#else
return FT_OK;
#endif
}
int ftd2_read_ee(void* handle, bool is_libftdi, int eeprom_addr, int *eeprom_val) {
int ftd2_read_ee(void* handle, bool is_ftd2_libusb, int eeprom_addr, int *eeprom_val) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi) {
if(!is_ftd2_libusb) {
WORD val = 0;
int retval = FT_ReadEE(handle, eeprom_addr, &val);
*eeprom_val = val;
return retval;
}
#endif
#ifdef USE_FTD2_LIBFTDI
return libftdi_read_eeprom(handle, eeprom_addr, eeprom_val);
#ifdef USE_FTD2_LIBUSB
return ftd2_libusb_read_eeprom(handle, eeprom_addr, eeprom_val);
#else
return FT_OK;
#endif
}
int ftd2_close(void* handle, bool is_libftdi) {
int ftd2_close(void* handle, bool is_ftd2_libusb) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi)
if(!is_ftd2_libusb)
return FT_Close(handle);
#endif
#ifdef USE_FTD2_LIBFTDI
return libftdi_close(handle);
#ifdef USE_FTD2_LIBUSB
return ftd2_libusb_close(handle);
#else
return FT_OK;
#endif
}
int ftd2_open(CaptureDevice* device, void** handle, bool is_libftdi) {
int ftd2_open(CaptureDevice* device, void** handle, bool is_ftd2_libusb) {
#ifdef USE_FTD2_DRIVER
if(!is_libftdi)
if(!is_ftd2_libusb)
return ftd2_driver_open_serial(device, handle);
#endif
#ifdef USE_FTD2_LIBFTDI
return libftdi_open_serial(device, handle);
#ifdef USE_FTD2_LIBUSB
return ftd2_libusb_open_serial(device, handle);
#else
return FT_OTHER_ERROR;
#endif
}
void ftd2_init() {
#ifdef USE_FTD2_LIBFTDI
libftdi_init();
#ifdef USE_FTD2_LIBUSB
ftd2_libusb_init();
#endif
}
void ftd2_end() {
#ifdef USE_FTD2_LIBFTDI
libftdi_end();
#ifdef USE_FTD2_LIBUSB
ftd2_libusb_end();
#endif
}

View File

@ -89,9 +89,9 @@ static void data_output_update(int curr_data_buffer_index, CaptureData* capture_
}
void ftd2_capture_main_loop_driver(CaptureData* capture_data) {
bool is_libftdi = false;
bool is_ftd2_libusb = false;
// Separate Capture Enable and put it here, for better control
if(!enable_capture(capture_data->handle, is_libftdi)) {
if(!enable_capture(capture_data->handle, is_ftd2_libusb)) {
capture_error_print(true, capture_data, "Capture enable error");
return;
}
@ -108,8 +108,8 @@ void ftd2_capture_main_loop_driver(CaptureData* capture_data) {
curr_data_buffer_index = next_data_buffer_index;
CaptureDataSingleBuffer* curr_full_data_buf = capture_data->data_buffers.GetWriterBuffer(curr_data_buffer_index);
CaptureReceived* curr_data_buffer = &curr_full_data_buf->capture_buf;
retval = ftd2_read(capture_data->handle, is_libftdi, ((uint8_t*)curr_data_buffer) + (full_size - next_size), next_size, &bytesIn);
if(ftd2_is_error(retval, is_libftdi)) {
retval = ftd2_read(capture_data->handle, is_ftd2_libusb, ((uint8_t*)curr_data_buffer) + (full_size - next_size), next_size, &bytesIn);
if(ftd2_is_error(retval, is_ftd2_libusb)) {
capture_error_print(true, capture_data, "Disconnected: Read failed");
break;
}

View File

@ -1,11 +1,9 @@
#include "dscapture_libftdi2.hpp"
#include "dscapture_ftd2_libusb.hpp"
#include "dscapture_ftd2_general.hpp"
#include "dscapture_ftd2_compatibility.hpp"
#include "devicecapture.hpp"
#include "usb_generic.hpp"
#include <ftdi.h>
#include <cstring>
#include <thread>
#include <chrono>
@ -27,6 +25,21 @@
#define IGNORE_FIRST_FEW_FRAMES_SYNC (NUM_CAPTURE_RECEIVED_DATA_BUFFERS * 2)
#define RESYNC_TIMEOUT 0.050
#define DEFAULT_INTERFACE 0
#define DEFAULT_CONFIGURATION 1
#define DEFAULT_EP_IN 2
#define DEFAULT_EP_OUT 0x81
struct ftd2_libusb_handle_data {
libusb_device_handle *usb_handle = NULL;
int timeout_r_ms = 500;
int timeout_w_ms = 500;
int ep_in = 0x81;
int ep_out = 2;
int chip_index = 1;
};
struct vid_pid_descriptor {
int vid;
int pid;
@ -47,13 +60,15 @@ static const vid_pid_descriptor* get_device_descriptor(int vid, int pid) {
return NULL;
}
void libftdi_init() {
void ftd2_libusb_init() {
return usb_init();
}
void libftdi_end() {
void ftd2_libusb_end() {
usb_close();
}
static void libftdi_usb_thread_function(bool* usb_thread_run, libusb_context *usb_ctx) {
static void ftd2_libusb_usb_thread_function(bool* usb_thread_run, libusb_context *usb_ctx) {
if(!usb_is_initialized())
return;
struct timeval tv;
@ -63,66 +78,111 @@ static void libftdi_usb_thread_function(bool* usb_thread_run, libusb_context *us
libusb_handle_events_timeout_completed(usb_ctx, &tv, NULL);
}
static void libftdi_start_thread(std::thread* thread_ptr, bool* usb_thread_run, libusb_context *usb_ctx) {
static void ftd2_libusb_start_thread(std::thread* thread_ptr, bool* usb_thread_run, libusb_context *usb_ctx) {
if(!usb_is_initialized())
return;
*usb_thread_run = true;
*thread_ptr = std::thread(libftdi_usb_thread_function, usb_thread_run, usb_ctx);
*thread_ptr = std::thread(ftd2_libusb_usb_thread_function, usb_thread_run, usb_ctx);
}
static void libftdi_close_thread(std::thread* thread_ptr, bool* usb_thread_run) {
static void ftd2_libusb_close_thread(std::thread* thread_ptr, bool* usb_thread_run) {
if(!usb_is_initialized())
return;
*usb_thread_run = false;
thread_ptr->join();
}
static int check_single_device_valid_libftdi(ftdi_context *handle, libusb_device* dev, char* description, char* SerialNumber, const vid_pid_descriptor** curr_descriptor) {
char manufacturer[MANUFACTURER_SIZE];
libusb_device_handle *dev_handle = NULL;
int retval = libusb_open(dev, &dev_handle);
if(retval || (dev_handle == NULL))
return retval;
retval = libusb_claim_interface(dev_handle, handle->interface);
if(retval == LIBUSB_SUCCESS)
libusb_release_interface(dev_handle, handle->interface);
static int read_strings(libusb_device_handle *handle, libusb_device_descriptor *usb_descriptor, char* manufacturer, char* description, char* serial) {
manufacturer[0] = 0;
description[0] = 0;
serial[0] = 0;
int result = libusb_get_string_descriptor_ascii(handle, usb_descriptor->iManufacturer, (uint8_t*)manufacturer, MANUFACTURER_SIZE);
if(result < 0)
return result;
result = libusb_get_string_descriptor_ascii(handle, usb_descriptor->iProduct, (uint8_t*)description, DESCRIPTION_SIZE);
if(result < 0)
return result;
result = libusb_get_string_descriptor_ascii(handle, usb_descriptor->iSerialNumber, (uint8_t*)serial, SERIAL_NUMBER_SIZE);
if(result < 0)
return result;
manufacturer[MANUFACTURER_SIZE - 1] = 0;
description[DESCRIPTION_SIZE - 1] = 0;
serial[SERIAL_NUMBER_SIZE - 1] = 0;
return 0;
}
static void close_handle_ftd2_libusb(libusb_device_handle *dev_handle, bool claimed) {
if(dev_handle == NULL)
return;
if(claimed)
libusb_release_interface(dev_handle, DEFAULT_INTERFACE);
libusb_close(dev_handle);
}
static int init_handle_and_populate_device_info_ftd2_libusb(libusb_device_handle **dev_handle, libusb_device* dev, char* description, char* SerialNumber, const vid_pid_descriptor** curr_descriptor) {
char manufacturer[MANUFACTURER_SIZE];
libusb_device_descriptor desc = {0};
int retval = libusb_get_device_descriptor(dev, &desc);
if(retval < 0)
return retval;
libusb_device_descriptor desc = {0};
retval = libusb_get_device_descriptor(dev, &desc);
retval = libusb_open(dev, dev_handle);
if(retval || ((*dev_handle) == NULL))
return retval;
retval = read_strings(*dev_handle, &desc, manufacturer, description, SerialNumber);
if(retval < 0) {
close_handle_ftd2_libusb(*dev_handle, false);
return retval;
}
retval = libusb_kernel_driver_active(*dev_handle, DEFAULT_INTERFACE);
if(retval == 1)
libusb_detach_kernel_driver(*dev_handle, DEFAULT_INTERFACE);
retval = libusb_set_configuration(*dev_handle, DEFAULT_CONFIGURATION);
if(retval != LIBUSB_SUCCESS)
return false;
retval = libusb_kernel_driver_active(*dev_handle, DEFAULT_INTERFACE);
if(retval == 1)
libusb_detach_kernel_driver(*dev_handle, DEFAULT_INTERFACE);
retval = libusb_claim_interface(*dev_handle, DEFAULT_INTERFACE);
if(retval != LIBUSB_SUCCESS) {
close_handle_ftd2_libusb(*dev_handle, false);
return retval;
}
*curr_descriptor = NULL;
if(retval >= 0)
*curr_descriptor = get_device_descriptor(desc.idVendor, desc.idProduct);
if((retval < 0) || ((retval = ftdi_usb_get_strings(handle, dev, manufacturer, MANUFACTURER_SIZE, description, DESCRIPTION_SIZE, SerialNumber, SERIAL_NUMBER_SIZE)) < 0))
return retval;
if((desc.bcdUSB < 0x0200) || ((*curr_descriptor) == NULL))
if((desc.bcdUSB < 0x0200) || ((*curr_descriptor) == NULL)) {
close_handle_ftd2_libusb(*dev_handle, true);
return LIBUSB_ERROR_OTHER;
}
return LIBUSB_SUCCESS;
}
void list_devices_libftdi(std::vector<CaptureDevice> &devices_list, std::vector<no_access_recap_data> &no_access_list) {
ftdi_device_list *devlist, *curdev;
ftdi_context *handle = ftdi_new();
static int check_single_device_valid_ftd2_libusb(libusb_device* dev, char* description, char* SerialNumber, const vid_pid_descriptor** curr_descriptor) {
libusb_device_handle *dev_handle = NULL;
int retval = init_handle_and_populate_device_info_ftd2_libusb(&dev_handle, dev, description, SerialNumber, curr_descriptor);
if(retval != LIBUSB_SUCCESS)
return retval;
close_handle_ftd2_libusb(dev_handle, true);
return retval;
}
void list_devices_ftd2_libusb(std::vector<CaptureDevice> &devices_list, std::vector<no_access_recap_data> &no_access_list) {
if(!usb_is_initialized())
return;
libusb_device **usb_devices;
int num_devices = libusb_get_device_list(get_usb_ctx(), &usb_devices);
libusb_device_descriptor usb_descriptor{};
char description[DESCRIPTION_SIZE], SerialNumber[SERIAL_NUMBER_SIZE];
int debug_multiplier = 1;
bool insert_anyway = false;
bool perm_error = false;
const vid_pid_descriptor* curr_descriptor;
int num_devices = ftdi_usb_find_all(handle, &devlist, 0, 0);
if(num_devices < 0) {
ftdi_free(handle);
return;
}
curdev = devlist;
while(curdev != NULL)
{
int retval = check_single_device_valid_libftdi(handle, curdev->dev, description, SerialNumber, &curr_descriptor);
for(int i = 0; i < num_devices; i++) {
int retval = check_single_device_valid_ftd2_libusb(usb_devices[i], description, SerialNumber, &curr_descriptor);
if(retval < 0) {
if(retval == LIBUSB_ERROR_ACCESS)
perm_error = true;
curdev = curdev->next;
continue;
}
std::string serial_number = std::string(SerialNumber);
@ -133,10 +193,8 @@ void list_devices_libftdi(std::vector<CaptureDevice> &devices_list, std::vector<
break;
}
}
if(is_already_inserted && (!insert_anyway)) {
curdev = curdev->next;
if(is_already_inserted && (!insert_anyway))
continue;
}
for(int j = 0; j < get_num_ftd2_device_types(); j++) {
if(description == get_ftd2_fw_desc(j)) {
for(int u = 0; u < debug_multiplier; u++)
@ -144,189 +202,143 @@ void list_devices_libftdi(std::vector<CaptureDevice> &devices_list, std::vector<
break;
}
}
curdev = curdev->next;
}
ftdi_list_free(&devlist);
ftdi_free(handle);
if(perm_error)
no_access_list.emplace_back("libftdi");
no_access_list.emplace_back("ftd2_libusb");
if(num_devices >= 0)
libusb_free_device_list(usb_devices, 1);
}
int libftdi_reset(void* handle) {
return ftdi_usb_reset((ftdi_context*)handle);
static int ftd2_libusb_ctrl_out(ftd2_libusb_handle_data* handle, uint8_t request, uint16_t value, uint16_t index, const uint8_t* data, size_t size) {
if(handle == NULL)
return -1;
if(handle->usb_handle == NULL)
return -1;
return libusb_control_transfer(handle->usb_handle, 0x40, request, value, index, (uint8_t*)data, size, handle->timeout_w_ms);
}
int libftdi_set_latency_timer(void* handle, unsigned char latency) {
return ftdi_set_latency_timer((ftdi_context*)handle, latency);
static int ftd2_libusb_ctrl_in(ftd2_libusb_handle_data* handle, uint8_t request, uint16_t value, uint16_t index, uint8_t* data, size_t size) {
if(handle == NULL)
return -1;
if(handle->usb_handle == NULL)
return -1;
return libusb_control_transfer(handle->usb_handle, 0xC0, request, value, index, data, size, handle->timeout_r_ms);
}
int libftdi_setflowctrl(void* handle, int flowctrl, unsigned char xon, unsigned char xoff) {
if((flowctrl == SIO_DISABLE_FLOW_CTRL) || (flowctrl == SIO_RTS_CTS_HS) || (flowctrl == SIO_DTR_DSR_HS))
return ftdi_setflowctrl((ftdi_context*)handle, flowctrl);
return ftdi_setflowctrl_xonxoff((ftdi_context*)handle, xon, xoff);
static int ftd2_libusb_ctrl_out_with_index(ftd2_libusb_handle_data* handle, uint8_t request, uint16_t value, uint16_t index, uint8_t* data, size_t size) {
if(handle == NULL)
return -1;
return ftd2_libusb_ctrl_out(handle, request, value, index | handle->chip_index, data, size);
}
int libftdi_set_bitmode(void* handle, unsigned char bitmask, unsigned char mode) {
return ftdi_set_bitmode((ftdi_context*)handle, bitmask, mode);
static int ftd2_libusb_bulk_out(ftd2_libusb_handle_data* handle, const uint8_t* data, size_t size, int* transferred) {
if(handle == NULL)
return -1;
if(handle->usb_handle == NULL)
return -1;
return libusb_bulk_transfer(handle->usb_handle, handle->ep_out, (uint8_t*)data, size, transferred, handle->timeout_w_ms);
}
int libftdi_purge(void* handle, bool do_read, bool do_write) {
if(do_read && do_write)
return ftdi_tcioflush((ftdi_context*)handle);
if(do_read)
return ftdi_tciflush((ftdi_context*)handle);
if(do_write)
return ftdi_tcoflush((ftdi_context*)handle);
static int ftd2_libusb_bulk_in(ftd2_libusb_handle_data* handle, uint8_t* data, size_t size, int* transferred) {
if(handle == NULL)
return -1;
if(handle->usb_handle == NULL)
return -1;
return libusb_bulk_transfer(handle->usb_handle, handle->ep_in, data, size, transferred, handle->timeout_r_ms);
}
static int ftd2_libusb_async_bulk_in_prepare(ftd2_libusb_handle_data* handle, libusb_transfer *transfer_in, uint8_t* data, size_t size, libusb_transfer_cb_fn cb_fn, void* cb_data, int timeout_multiplier = 1) {
if(handle == NULL)
return -1;
if(handle->usb_handle == NULL)
return -1;
if(!transfer_in)
return -1;
libusb_fill_bulk_transfer(transfer_in, handle->usb_handle, handle->ep_in, data, size, cb_fn, cb_data, handle->timeout_r_ms * timeout_multiplier);
return 0;
}
int libftdi_read_eeprom(void* handle, int eeprom_addr, int *eeprom_val) {
unsigned short val = 0;
int ret = ftdi_read_eeprom_location((ftdi_context*)handle, eeprom_addr, &val);
*eeprom_val = val;
int ftd2_libusb_reset(void* handle) {
return ftd2_libusb_ctrl_out_with_index((ftd2_libusb_handle_data*)handle, 0, 0, 0, NULL, 0);
}
int ftd2_libusb_set_latency_timer(void* handle, unsigned char latency) {
return ftd2_libusb_ctrl_out_with_index((ftd2_libusb_handle_data*)handle, 9, latency, 0, NULL, 0);
}
int ftd2_libusb_setflowctrl(void* handle, int flowctrl, unsigned char xon, unsigned char xoff) {
uint16_t value = 0;
if(flowctrl == FTD2_SIO_XON_XOFF_HS)
value = xon | (xoff << 8);
return ftd2_libusb_ctrl_out_with_index((ftd2_libusb_handle_data*)handle, 2, value, flowctrl, NULL, 0);
}
int ftd2_libusb_set_bitmode(void* handle, unsigned char bitmask, unsigned char mode) {
uint16_t value = bitmask | (mode << 8);
return ftd2_libusb_ctrl_out_with_index((ftd2_libusb_handle_data*)handle, 0xB, value, 0, NULL, 0);
}
int ftd2_libusb_purge(void* handle, bool do_read, bool do_write) {
int result = 0;
if(do_write)
result = ftd2_libusb_ctrl_out_with_index((ftd2_libusb_handle_data*)handle, 0, 1, 0, NULL, 0);
if(result < 0)
return result;
if(do_read)
result = ftd2_libusb_ctrl_out_with_index((ftd2_libusb_handle_data*)handle, 0, 2, 0, NULL, 0);
if(result < 0)
return result;
return 0;
}
int ftd2_libusb_read_eeprom(void* handle, int eeprom_addr, int *eeprom_val) {
uint8_t val[sizeof(uint16_t)];
int ret = ftd2_libusb_ctrl_in((ftd2_libusb_handle_data*)handle, 0x90, 0, eeprom_addr, val, sizeof(val));
*eeprom_val = read_le16(val, 0);
return ret;
}
int libftdi_set_chars(void* handle, unsigned char eventch, unsigned char event_enable, unsigned char errorch, unsigned char error_enable) {
int ret = ftdi_set_event_char((ftdi_context*)handle, eventch, event_enable);
int ftd2_libusb_set_chars(void* handle, unsigned char eventch, unsigned char event_enable, unsigned char errorch, unsigned char error_enable) {
if(event_enable)
event_enable = 1;
uint16_t value = eventch | (event_enable << 8);
int ret = ftd2_libusb_ctrl_out_with_index((ftd2_libusb_handle_data*)handle, 6, value, 0, NULL, 0);
if(ret < 0)
return ret;
return ftdi_set_error_char((ftdi_context*)handle, errorch, error_enable);
if(error_enable)
error_enable = 1;
value = errorch | (error_enable << 8);
return ftd2_libusb_ctrl_out_with_index((ftd2_libusb_handle_data*)handle, 7, value, 0, NULL, 0);
}
int libftdi_set_usb_chunksizes(void* handle, unsigned int chunksize_in, unsigned int chunksize_out) {
int ret = ftdi_read_data_set_chunksize((ftdi_context*)handle, chunksize_in);
if(ret < 0)
return ret;
return ftdi_write_data_set_chunksize((ftdi_context*)handle, chunksize_out);
int ftd2_libusb_set_usb_chunksizes(void* handle, unsigned int chunksize_in, unsigned int chunksize_out) {
return 0;
}
void libftdi_set_timeouts(void* handle, int timeout_in_ms, int timeout_out_ms) {
ftdi_context* in_handle = (ftdi_context*)handle;
in_handle->usb_read_timeout = timeout_in_ms;
in_handle->usb_write_timeout = timeout_out_ms;
}
int libftdi_write(void* handle, const uint8_t* data, size_t size, size_t* bytesOut) {
*bytesOut = ftdi_write_data((ftdi_context*)handle, data, size);
if((*bytesOut) >= 0)
return 0;
return *bytesOut;
}
int libftdi_read(void* handle, uint8_t* data, size_t size, size_t* bytesIn) {
*bytesIn = ftdi_read_data((ftdi_context*)handle, data, size);
if((*bytesIn) >= 0)
return 0;
return *bytesIn;
}
int get_libftdi_read_queue_size(void* handle, size_t* bytesIn) {
uint8_t buffer[64];
*bytesIn = 0;
ftdi_context* in_handle = (ftdi_context*)handle;
int timeout_in_ms = in_handle->usb_read_timeout;
in_handle->usb_read_timeout = 0;
size_t curr_bytes_in = 0;
bool done = false;
int retval = 0;
while(!done) {
retval = libftdi_read(handle, buffer, 64, &curr_bytes_in);
if(retval <= 0)
done = true;
else
*bytesIn += curr_bytes_in;
}
in_handle->usb_read_timeout = timeout_in_ms;
return LIBUSB_SUCCESS;
}
int libftdi_open_serial(CaptureDevice* device, void** handle) {
ftdi_device_list *devlist, *curdev;
ftdi_context *curr_handle = ftdi_new();
char description[DESCRIPTION_SIZE], SerialNumber[SERIAL_NUMBER_SIZE];
int debug_multiplier = 1;
bool insert_anyway = false;
bool perm_error = false;
const vid_pid_descriptor* curr_descriptor;
int ret = LIBUSB_ERROR_OTHER;
int num_devices = ftdi_usb_find_all(curr_handle, &devlist, 0, 0);
if(num_devices < 0) {
ftdi_free(curr_handle);
return LIBUSB_ERROR_OTHER;
}
curdev = devlist;
while(curdev != NULL)
{
int retval = check_single_device_valid_libftdi(curr_handle, curdev->dev, description, SerialNumber, &curr_descriptor);
if(retval < 0) {
curdev = curdev->next;
continue;
}
if(curr_descriptor != ((const vid_pid_descriptor*)device->descriptor)) {
curdev = curdev->next;
continue;
}
std::string serial_number = std::string(SerialNumber);
std::string desc = std::string(description);
if((serial_number != device->serial_number) || (desc != device->path)) {
curdev = curdev->next;
continue;
}
ret = ftdi_usb_open_dev(curr_handle, curdev->dev);
if(ret >= 0)
*handle = (void*)curr_handle;
curdev = NULL;
}
ftdi_list_free(&devlist);
if(ret < 0)
ftdi_free(curr_handle);
return ret;
}
int libftdi_close(void* handle) {
ftdi_usb_close((ftdi_context*)handle);
ftdi_free((ftdi_context*)handle);
return LIBUSB_SUCCESS;
}
void libftdi_cancel_callback(ftd2_async_callback_data* cb_data) {
cb_data->transfer_data_access.lock();
if(cb_data->transfer_data)
libusb_cancel_transfer((libusb_transfer*)cb_data->transfer_data);
cb_data->transfer_data_access.unlock();
}
static void STDCALL libftdi_read_callback(libusb_transfer* transfer) {
ftd2_async_callback_data* cb_data = (ftd2_async_callback_data*)transfer->user_data;
FTD2CaptureReceivedData* user_data = (FTD2CaptureReceivedData*)cb_data->actual_user_data;
cb_data->transfer_data_access.lock();
cb_data->transfer_data = NULL;
cb_data->is_transfer_done_mutex->specific_unlock(cb_data->internal_index);
cb_data->transfer_data_access.unlock();
cb_data->function((void*)user_data, transfer->actual_length, transfer->status);
}
// Read from bulk
static void libftdi_schedule_read(ftd2_async_callback_data* cb_data, uint8_t* buffer_raw, int length) {
const int max_packet_size = MAX_PACKET_SIZE_USB2;
libusb_transfer *transfer_in = libusb_alloc_transfer(0);
if(!transfer_in)
void ftd2_libusb_set_timeouts(void* handle, int timeout_in_ms, int timeout_out_ms) {
if(handle == NULL)
return;
cb_data->transfer_data_access.lock();
cb_data->transfer_data = transfer_in;
cb_data->is_transfer_done_mutex->specific_try_lock(cb_data->internal_index);
length += ((length + (max_packet_size - FTD2_INTRA_PACKET_HEADER_SIZE) - 1) / (max_packet_size - FTD2_INTRA_PACKET_HEADER_SIZE)) * FTD2_INTRA_PACKET_HEADER_SIZE;
cb_data->requested_length = length;
ftdi_context* in_handle = (ftdi_context*)cb_data->handle;
libusb_fill_bulk_transfer(transfer_in, in_handle->usb_dev, in_handle->out_ep, buffer_raw, length, libftdi_read_callback, (void*)cb_data, in_handle->usb_read_timeout * NUM_CAPTURE_RECEIVED_DATA_BUFFERS);
transfer_in->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
libusb_submit_transfer(transfer_in);
cb_data->transfer_data_access.unlock();
ftd2_libusb_handle_data* in_handle = (ftd2_libusb_handle_data*)handle;
in_handle->timeout_r_ms = timeout_in_ms;
in_handle->timeout_w_ms = timeout_out_ms;
}
static size_t libftdi_get_actual_length(const int max_packet_size, size_t length, size_t header_packet_size) {
int ftd2_libusb_write(void* handle, const uint8_t* data, size_t size, size_t* bytesOut) {
int transferred = 0;
int result = ftd2_libusb_bulk_out((ftd2_libusb_handle_data*)handle, data, size, &transferred);
*bytesOut = transferred;
return result;
}
static size_t ftd2_libusb_get_expanded_length(const int max_packet_size, size_t length, size_t header_packet_size) {
// Add the small headers every 512 bytes...
if(length == 0)
return header_packet_size;
return length + ((length + (max_packet_size - header_packet_size) - 1) / (max_packet_size - header_packet_size)) * header_packet_size;
}
static size_t ftd2_libusb_get_actual_length(const int max_packet_size, size_t length, size_t header_packet_size) {
// Remove the small headers every 512 bytes...
// The "- header_packet_size" instead of "-1" covers for partial header transfers...
int num_iters = (length + max_packet_size - header_packet_size) / max_packet_size;
@ -337,7 +349,7 @@ static size_t libftdi_get_actual_length(const int max_packet_size, size_t length
return length;
}
static void libftdi_copy_buffer_to_target(uint8_t* buffer_written, uint8_t* buffer_target, const int max_packet_size, size_t length, size_t header_packet_size) {
static void ftd2_libusb_copy_buffer_to_target(uint8_t* buffer_written, uint8_t* buffer_target, const int max_packet_size, size_t length, size_t header_packet_size) {
// Remove the small headers every 512 bytes...
// The "- header_packet_size" instead of "-1" covers for partial header transfers...
int num_iters = (length + max_packet_size - header_packet_size) / max_packet_size;
@ -356,26 +368,140 @@ static void libftdi_copy_buffer_to_target(uint8_t* buffer_written, uint8_t* buff
}
// Read from bulk
static int libftdi_direct_read(void* handle, uint8_t* buffer_raw, uint8_t* buffer_normal, size_t length, size_t* transferred) {
static int ftd2_libusb_direct_read(void* handle, uint8_t* buffer_raw, uint8_t* buffer_normal, size_t length, size_t* transferred) {
const int max_packet_size = MAX_PACKET_SIZE_USB2;
length += ((length + (max_packet_size - FTD2_INTRA_PACKET_HEADER_SIZE) - 1) / (max_packet_size - FTD2_INTRA_PACKET_HEADER_SIZE)) * FTD2_INTRA_PACKET_HEADER_SIZE;
ftdi_context* in_handle = (ftdi_context*)handle;
*transferred = 0;
int internal_transferred = 0;
int retval = libusb_bulk_transfer(in_handle->usb_dev, in_handle->out_ep, buffer_raw, length, &internal_transferred, in_handle->usb_read_timeout);
const int header_packet_size = FTD2_INTRA_PACKET_HEADER_SIZE;
length = ftd2_libusb_get_expanded_length(max_packet_size, length, header_packet_size);
int transferred_internal = 0;
int retval = ftd2_libusb_bulk_in((ftd2_libusb_handle_data*)handle, buffer_raw, length, &transferred_internal);
if(retval < 0)
return retval;
libftdi_copy_buffer_to_target(buffer_raw, buffer_normal, max_packet_size, internal_transferred, FTD2_INTRA_PACKET_HEADER_SIZE);
*transferred = libftdi_get_actual_length(max_packet_size, internal_transferred, FTD2_INTRA_PACKET_HEADER_SIZE);
ftd2_libusb_copy_buffer_to_target(buffer_raw, buffer_normal, max_packet_size, transferred_internal, header_packet_size);
*transferred = ftd2_libusb_get_actual_length(max_packet_size, transferred_internal, header_packet_size);
return LIBUSB_SUCCESS;
}
static int libftdi_full_read(void* handle, uint8_t* buffer_raw, uint8_t* buffer_normal, size_t length, double timeout) {
int ftd2_libusb_read(void* handle, uint8_t* data, size_t size, size_t* bytesIn) {
const int max_packet_size = MAX_PACKET_SIZE_USB2;
const int header_packet_size = FTD2_INTRA_PACKET_HEADER_SIZE;
size_t new_size = ftd2_libusb_get_expanded_length(max_packet_size, size, header_packet_size);
uint8_t* buffer_raw = new uint8_t[new_size];
int result = ftd2_libusb_direct_read(handle, buffer_raw, data, size, bytesIn);
delete []buffer_raw;
return result;
}
int get_ftd2_libusb_read_queue_size(void* handle, size_t* bytesIn) {
uint8_t buffer[64];
*bytesIn = 0;
ftd2_libusb_handle_data* in_handle = (ftd2_libusb_handle_data*)handle;
int timeout_in_ms = in_handle->timeout_r_ms;
in_handle->timeout_r_ms = 0;
size_t curr_bytes_in = 0;
bool done = false;
int retval = 0;
while(!done) {
retval = ftd2_libusb_read(handle, buffer, 64, &curr_bytes_in);
if(retval <= 0)
done = true;
else
*bytesIn += curr_bytes_in;
}
in_handle->timeout_r_ms = timeout_in_ms;
return LIBUSB_SUCCESS;
}
int ftd2_libusb_open_serial(CaptureDevice* device, void** handle) {
if(!usb_is_initialized())
return LIBUSB_ERROR_OTHER;
*handle = NULL;
libusb_device **usb_devices;
int num_devices = libusb_get_device_list(get_usb_ctx(), &usb_devices);
libusb_device_descriptor usb_descriptor{};
char description[DESCRIPTION_SIZE], SerialNumber[SERIAL_NUMBER_SIZE];
int debug_multiplier = 1;
bool insert_anyway = false;
bool perm_error = false;
const vid_pid_descriptor* curr_descriptor;
int ret = LIBUSB_ERROR_OTHER;
for(int i = 0; i < num_devices; i++) {
ftd2_libusb_handle_data out_handle;
int retval = init_handle_and_populate_device_info_ftd2_libusb(&out_handle.usb_handle, usb_devices[i], description, SerialNumber, &curr_descriptor);
if(retval != LIBUSB_SUCCESS)
continue;
if(curr_descriptor != ((const vid_pid_descriptor*)device->descriptor)) {
close_handle_ftd2_libusb(out_handle.usb_handle, true);
continue;
}
std::string serial_number = std::string(SerialNumber);
std::string desc = std::string(description);
if((serial_number != device->serial_number) || (desc != device->path)) {
close_handle_ftd2_libusb(out_handle.usb_handle, true);
continue;
}
ftd2_libusb_handle_data* final_handle = new ftd2_libusb_handle_data;
*final_handle = out_handle;
*handle = final_handle;
ret = LIBUSB_SUCCESS;
break;
}
if(num_devices >= 0)
libusb_free_device_list(usb_devices, 1);
return ret;
}
int ftd2_libusb_close(void* handle) {
if(handle == NULL)
return LIBUSB_SUCCESS;
ftd2_libusb_handle_data* in_handle = (ftd2_libusb_handle_data*)handle;
close_handle_ftd2_libusb(in_handle->usb_handle, true);
delete in_handle;
return LIBUSB_SUCCESS;
}
void ftd2_libusb_cancel_callback(ftd2_async_callback_data* cb_data) {
cb_data->transfer_data_access.lock();
if(cb_data->transfer_data)
libusb_cancel_transfer((libusb_transfer*)cb_data->transfer_data);
cb_data->transfer_data_access.unlock();
}
static void STDCALL ftd2_libusb_read_callback(libusb_transfer* transfer) {
ftd2_async_callback_data* cb_data = (ftd2_async_callback_data*)transfer->user_data;
FTD2CaptureReceivedData* user_data = (FTD2CaptureReceivedData*)cb_data->actual_user_data;
cb_data->transfer_data_access.lock();
cb_data->transfer_data = NULL;
cb_data->is_transfer_done_mutex->specific_unlock(cb_data->internal_index);
cb_data->transfer_data_access.unlock();
cb_data->function((void*)user_data, transfer->actual_length, transfer->status);
}
// Read from bulk
static void ftd2_libusb_schedule_read(ftd2_async_callback_data* cb_data, uint8_t* buffer_raw, int length) {
const int max_packet_size = MAX_PACKET_SIZE_USB2;
libusb_transfer *transfer_in = libusb_alloc_transfer(0);
if(!transfer_in)
return;
cb_data->transfer_data_access.lock();
cb_data->transfer_data = transfer_in;
cb_data->is_transfer_done_mutex->specific_try_lock(cb_data->internal_index);
length += ((length + (max_packet_size - FTD2_INTRA_PACKET_HEADER_SIZE) - 1) / (max_packet_size - FTD2_INTRA_PACKET_HEADER_SIZE)) * FTD2_INTRA_PACKET_HEADER_SIZE;
cb_data->requested_length = length;
ftd2_libusb_async_bulk_in_prepare((ftd2_libusb_handle_data*)cb_data->handle, transfer_in, buffer_raw, length, ftd2_libusb_read_callback, (void*)cb_data, NUM_CAPTURE_RECEIVED_DATA_BUFFERS);
transfer_in->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
libusb_submit_transfer(transfer_in);
cb_data->transfer_data_access.unlock();
}
static int ftd2_libusb_full_read(void* handle, uint8_t* buffer_raw, uint8_t* buffer_normal, size_t length, double timeout) {
size_t total_transferred = 0;
const auto start_time = std::chrono::high_resolution_clock::now();
while(total_transferred < length) {
size_t received = 0;
int retval = libftdi_direct_read(handle, buffer_raw, buffer_normal, length - total_transferred, &received);
int retval = ftd2_libusb_direct_read(handle, buffer_raw, buffer_normal, length - total_transferred, &received);
if(ftd2_is_error(retval, true))
return retval;
total_transferred += received;
@ -389,7 +515,7 @@ static int libftdi_full_read(void* handle, uint8_t* buffer_raw, uint8_t* buffer_
return LIBUSB_SUCCESS;
}
static void libftdi_copy_buffer_to_target_and_skip(uint8_t* buffer_written, uint8_t* buffer_target, const int max_packet_size, size_t length, size_t header_packet_size, size_t ignored_bytes) {
static void ftd2_libusb_copy_buffer_to_target_and_skip(uint8_t* buffer_written, uint8_t* buffer_target, const int max_packet_size, size_t length, size_t header_packet_size, size_t ignored_bytes) {
// This could be made faster for small "ignored_bytes", however this scales well...
// Plus, most of the time is used up by the memcpy routine, so...
@ -422,22 +548,22 @@ static void libftdi_copy_buffer_to_target_and_skip(uint8_t* buffer_written, uint
}
if(length <= (max_packet_size * partially_ignored_iters))
return;
libftdi_copy_buffer_to_target(buffer_written, buffer_target, max_packet_size, length - (max_packet_size * partially_ignored_iters), header_packet_size);
ftd2_libusb_copy_buffer_to_target(buffer_written, buffer_target, max_packet_size, length - (max_packet_size * partially_ignored_iters), header_packet_size);
}
static int get_libftdi_status(FTD2CaptureReceivedData* received_data_buffers) {
static int get_ftd2_libusb_status(FTD2CaptureReceivedData* received_data_buffers) {
return *received_data_buffers[0].status;
}
static void reset_libftdi_status(FTD2CaptureReceivedData* received_data_buffers) {
static void reset_ftd2_libusb_status(FTD2CaptureReceivedData* received_data_buffers) {
*received_data_buffers[0].status = 0;
}
static void error_libftdi_status(FTD2CaptureReceivedData* received_data_buffers, int error) {
static void error_ftd2_libusb_status(FTD2CaptureReceivedData* received_data_buffers, int error) {
*received_data_buffers[0].status = error;
}
static int libftdi_get_num_free_buffers(FTD2CaptureReceivedData* received_data_buffers) {
static int ftd2_libusb_get_num_free_buffers(FTD2CaptureReceivedData* received_data_buffers) {
int num_free = 0;
for(int i = 0; i < NUM_CAPTURE_RECEIVED_DATA_BUFFERS; i++)
if(!received_data_buffers[i].in_use)
@ -445,12 +571,12 @@ static int libftdi_get_num_free_buffers(FTD2CaptureReceivedData* received_data_b
return num_free;
}
static void wait_all_libftdi_transfers_done(FTD2CaptureReceivedData* received_data_buffers) {
static void wait_all_ftd2_libusb_transfers_done(FTD2CaptureReceivedData* received_data_buffers) {
if (received_data_buffers == NULL)
return;
if (*received_data_buffers[0].status < 0) {
for (int i = 0; i < NUM_CAPTURE_RECEIVED_DATA_BUFFERS; i++)
libftdi_cancel_callback(&received_data_buffers[i].cb_data);
ftd2_libusb_cancel_callback(&received_data_buffers[i].cb_data);
}
for (int i = 0; i < NUM_CAPTURE_RECEIVED_DATA_BUFFERS; i++) {
void* transfer_data;
@ -464,19 +590,19 @@ static void wait_all_libftdi_transfers_done(FTD2CaptureReceivedData* received_da
}
}
static void wait_all_libftdi_buffers_free(FTD2CaptureReceivedData* received_data_buffers) {
static void wait_all_ftd2_libusb_buffers_free(FTD2CaptureReceivedData* received_data_buffers) {
if(received_data_buffers == NULL)
return;
if(*received_data_buffers[0].status < 0) {
for(int i = 0; i < NUM_CAPTURE_RECEIVED_DATA_BUFFERS; i++)
libftdi_cancel_callback(&received_data_buffers[i].cb_data);
ftd2_libusb_cancel_callback(&received_data_buffers[i].cb_data);
}
for(int i = 0; i < NUM_CAPTURE_RECEIVED_DATA_BUFFERS; i++)
while(received_data_buffers[i].in_use)
received_data_buffers[i].is_buffer_free_shared_mutex->specific_timed_lock(i);
}
static void wait_one_libftdi_buffer_free(FTD2CaptureReceivedData* received_data_buffers) {
static void wait_one_ftd2_libusb_buffer_free(FTD2CaptureReceivedData* received_data_buffers) {
bool done = false;
while(!done) {
for(int i = 0; i < NUM_CAPTURE_RECEIVED_DATA_BUFFERS; i++) {
@ -492,12 +618,12 @@ static void wait_one_libftdi_buffer_free(FTD2CaptureReceivedData* received_data_
}
}
static bool libftdi_are_buffers_all_free(FTD2CaptureReceivedData* received_data_buffers) {
return libftdi_get_num_free_buffers(received_data_buffers) == NUM_CAPTURE_RECEIVED_DATA_BUFFERS;
static bool ftd2_libusb_are_buffers_all_free(FTD2CaptureReceivedData* received_data_buffers) {
return ftd2_libusb_get_num_free_buffers(received_data_buffers) == NUM_CAPTURE_RECEIVED_DATA_BUFFERS;
}
static FTD2CaptureReceivedData* libftdi_get_free_buffer(FTD2CaptureReceivedData* received_data_buffers) {
wait_one_libftdi_buffer_free(received_data_buffers);
static FTD2CaptureReceivedData* ftd2_libusb_get_free_buffer(FTD2CaptureReceivedData* received_data_buffers) {
wait_one_ftd2_libusb_buffer_free(received_data_buffers);
if(*received_data_buffers[0].status < 0)
return NULL;
for(int i = 0; i < NUM_CAPTURE_RECEIVED_DATA_BUFFERS; i++)
@ -509,7 +635,7 @@ static FTD2CaptureReceivedData* libftdi_get_free_buffer(FTD2CaptureReceivedData*
return NULL;
}
static void libftdi_start_read(FTD2CaptureReceivedData* received_data_buffer, int index, size_t size) {
static void ftd2_libusb_start_read(FTD2CaptureReceivedData* received_data_buffer, int index, size_t size) {
if(received_data_buffer == NULL)
return;
CaptureDataSingleBuffer* full_data_buf = received_data_buffer->capture_data->data_buffers.GetWriterBuffer(received_data_buffer->cb_data.internal_index);
@ -517,25 +643,25 @@ static void libftdi_start_read(FTD2CaptureReceivedData* received_data_buffer, in
received_data_buffer->buffer_raw = (uint8_t*)&data_buffer->ftd2_received_old_ds_normal_plus_raw.raw_data;
received_data_buffer->buffer_target = (uint32_t*)data_buffer;
received_data_buffer->index = index;
libftdi_schedule_read(&received_data_buffer->cb_data, received_data_buffer->buffer_raw, size);
ftd2_libusb_schedule_read(&received_data_buffer->cb_data, received_data_buffer->buffer_raw, size);
}
static void end_libftdi_read_frame_cb(FTD2CaptureReceivedData* received_data_buffer, bool has_succeded) {
static void end_ftd2_libusb_read_frame_cb(FTD2CaptureReceivedData* received_data_buffer, bool has_succeded) {
if(!has_succeded)
received_data_buffer->capture_data->data_buffers.ReleaseWriterBuffer(received_data_buffer->cb_data.internal_index, false);
received_data_buffer->in_use = false;
received_data_buffer->is_buffer_free_shared_mutex->specific_unlock(received_data_buffer->cb_data.internal_index);
}
static size_t libftdi_copy_buffer_to_target_and_skip_synch(uint8_t* in_buffer, uint32_t* out_buffer, int read_length, size_t* sync_offset) {
static size_t ftd2_libusb_copy_buffer_to_target_and_skip_synch(uint8_t* in_buffer, uint32_t* out_buffer, int read_length, size_t* sync_offset) {
// This is because the actual data seems to always start with a SYNCH
size_t ignored_halfwords = 0;
uint16_t* in_u16 = (uint16_t*)in_buffer;
size_t real_length = libftdi_get_actual_length(MAX_PACKET_SIZE_USB2, read_length, FTD2_INTRA_PACKET_HEADER_SIZE);
size_t real_length = ftd2_libusb_get_actual_length(MAX_PACKET_SIZE_USB2, read_length, FTD2_INTRA_PACKET_HEADER_SIZE);
while((ignored_halfwords < (real_length / 2)) && (in_u16[ignored_halfwords + 1 + (ignored_halfwords / (MAX_PACKET_SIZE_USB2 / 2))] == FTD2_OLDDS_SYNCH_VALUES))
ignored_halfwords++;
size_t copy_offset = ignored_halfwords * 2;
libftdi_copy_buffer_to_target_and_skip(in_buffer, (uint8_t*)out_buffer, MAX_PACKET_SIZE_USB2, read_length, FTD2_INTRA_PACKET_HEADER_SIZE, copy_offset);
ftd2_libusb_copy_buffer_to_target_and_skip(in_buffer, (uint8_t*)out_buffer, MAX_PACKET_SIZE_USB2, read_length, FTD2_INTRA_PACKET_HEADER_SIZE, copy_offset);
if((copy_offset == 0) || (copy_offset >= (MAX_PACKET_SIZE_USB2 - FTD2_INTRA_PACKET_HEADER_SIZE))) {
size_t internal_sync_offset = 0;
bool is_synced = synchronization_check((uint16_t*)out_buffer, real_length, NULL, &internal_sync_offset);
@ -561,7 +687,7 @@ static void output_to_thread(CaptureData* capture_data, int internal_index, uint
const std::chrono::duration<double> diff = curr_time - base_time;
base_time = curr_time;
// Copy data to buffer, with special memcpy which accounts for ftd2 header data and skips synch bytes
size_t real_length = libftdi_copy_buffer_to_target_and_skip_synch(buffer_raw, buffer_target, read_length, sync_offset);
size_t real_length = ftd2_libusb_copy_buffer_to_target_and_skip_synch(buffer_raw, buffer_target, read_length, sync_offset);
capture_data->data_buffers.WriteToBuffer(NULL, real_length, diff.count(), &capture_data->status.device, internal_index);
if(capture_data->status.cooldown_curr_in)
@ -571,21 +697,21 @@ static void output_to_thread(CaptureData* capture_data, int internal_index, uint
capture_data->status.audio_wait.unlock();
}
static void libftdi_capture_process_data(void* in_user_data, int transfer_length, int transfer_status) {
static void ftd2_libusb_capture_process_data(void* in_user_data, int transfer_length, int transfer_status) {
// Note: sometimes the data returned has length 0...
// It's because the code is too fast...
FTD2CaptureReceivedData* user_data = (FTD2CaptureReceivedData*)in_user_data;
if((*user_data->status) < 0)
return end_libftdi_read_frame_cb(user_data, false);
return end_ftd2_libusb_read_frame_cb(user_data, false);
if(transfer_status != LIBUSB_TRANSFER_COMPLETED) {
*user_data->status = LIBUSB_ERROR_OTHER;
return end_libftdi_read_frame_cb(user_data, false);
return end_ftd2_libusb_read_frame_cb(user_data, false);
}
if(transfer_length < user_data->cb_data.requested_length)
return end_libftdi_read_frame_cb(user_data, false);
return end_ftd2_libusb_read_frame_cb(user_data, false);
if(((int32_t)(user_data->index - (*user_data->last_used_index))) <= 0) {
//*user_data->status = LIBUSB_ERROR_INTERRUPTED;
return end_libftdi_read_frame_cb(user_data, false);
return end_ftd2_libusb_read_frame_cb(user_data, false);
}
*user_data->last_used_index = user_data->index;
@ -593,15 +719,15 @@ static void libftdi_capture_process_data(void* in_user_data, int transfer_length
// like this is way faster than loading it.
// Even if it's still needed to get the writer buffer...
output_to_thread(user_data->capture_data, user_data->cb_data.internal_index, user_data->buffer_raw, user_data->buffer_target, *user_data->clock_start, transfer_length, user_data->curr_offset);
end_libftdi_read_frame_cb(user_data, true);
end_ftd2_libusb_read_frame_cb(user_data, true);
}
static void resync_offset(FTD2CaptureReceivedData* received_data_buffers, uint32_t &index, size_t full_size) {
size_t wanted_offset = *received_data_buffers[0].curr_offset;
if(wanted_offset == 0)
return;
wait_all_libftdi_buffers_free(received_data_buffers);
if(get_libftdi_status(received_data_buffers) != 0)
wait_all_ftd2_libusb_buffers_free(received_data_buffers);
if(get_ftd2_libusb_status(received_data_buffers) != 0)
return;
wanted_offset = *received_data_buffers[0].curr_offset;
if(wanted_offset == 0)
@ -618,9 +744,9 @@ static void resync_offset(FTD2CaptureReceivedData* received_data_buffers, uint32
bool is_synced = false;
size_t chosen_transfer_size = (MAX_PACKET_SIZE_USB2 - FTD2_INTRA_PACKET_HEADER_SIZE) * 4;
while((!is_synced) && (capture_data->status.connected && capture_data->status.running)) {
int retval = libftdi_full_read(received_data_buffers[0].cb_data.handle, (uint8_t*)buffer_raw, (uint8_t*)buffer, chosen_transfer_size, RESYNC_TIMEOUT);
int retval = ftd2_libusb_full_read(received_data_buffers[0].cb_data.handle, (uint8_t*)buffer_raw, (uint8_t*)buffer, chosen_transfer_size, RESYNC_TIMEOUT);
if(ftd2_is_error(retval, true)) {
//error_libftdi_status(received_data_buffers, retval);
//error_ftd2_libusb_status(received_data_buffers, retval);
delete buffer_raw;
delete buffer;
return;
@ -632,9 +758,9 @@ static void resync_offset(FTD2CaptureReceivedData* received_data_buffers, uint32
else
is_synced = false;
}
int retval = libftdi_full_read(received_data_buffers[0].cb_data.handle, (uint8_t*)buffer_raw, (uint8_t*)buffer, full_size - chosen_transfer_size, RESYNC_TIMEOUT);
int retval = ftd2_libusb_full_read(received_data_buffers[0].cb_data.handle, (uint8_t*)buffer_raw, (uint8_t*)buffer, full_size - chosen_transfer_size, RESYNC_TIMEOUT);
if(ftd2_is_error(retval, true)) {
error_libftdi_status(received_data_buffers, retval);
error_ftd2_libusb_status(received_data_buffers, retval);
delete buffer_raw;
delete buffer;
return;
@ -644,8 +770,8 @@ static void resync_offset(FTD2CaptureReceivedData* received_data_buffers, uint32
delete buffer;
}
void ftd2_capture_main_loop_libftdi(CaptureData* capture_data) {
const bool is_libftdi = true;
void ftd2_capture_main_loop_libusb(CaptureData* capture_data) {
const bool is_ftd2_libusb = true;
bool is_done = false;
int inner_curr_in = 0;
int retval = 0;
@ -661,7 +787,7 @@ void ftd2_capture_main_loop_libftdi(CaptureData* capture_data) {
size_t bytesIn;
bool usb_thread_run = false;
std::thread processing_thread;
libftdi_start_thread(&processing_thread, &usb_thread_run, ((ftdi_context*)capture_data->handle)->usb_ctx);
ftd2_libusb_start_thread(&processing_thread, &usb_thread_run, get_usb_ctx());
SharedConsumerMutex is_buffer_free_shared_mutex(NUM_CAPTURE_RECEIVED_DATA_BUFFERS);
SharedConsumerMutex is_transfer_done_mutex(NUM_CAPTURE_RECEIVED_DATA_BUFFERS);
@ -676,7 +802,7 @@ void ftd2_capture_main_loop_libftdi(CaptureData* capture_data) {
received_data_buffers[i].last_used_index = &last_used_index;
received_data_buffers[i].capture_data = capture_data;
received_data_buffers[i].clock_start = &clock_start;
received_data_buffers[i].cb_data.function = libftdi_capture_process_data;
received_data_buffers[i].cb_data.function = ftd2_libusb_capture_process_data;
received_data_buffers[i].cb_data.actual_user_data = &received_data_buffers[i];
received_data_buffers[i].cb_data.transfer_data = NULL;
received_data_buffers[i].cb_data.handle = capture_data->handle;
@ -685,26 +811,26 @@ void ftd2_capture_main_loop_libftdi(CaptureData* capture_data) {
received_data_buffers[i].cb_data.requested_length = 0;
}
if(!enable_capture(capture_data->handle, is_libftdi)) {
if(!enable_capture(capture_data->handle, is_ftd2_libusb)) {
capture_error_print(true, capture_data, "Capture enable error");
is_done = true;
}
for(int i = 0; i < NUM_CAPTURE_RECEIVED_DATA_BUFFERS; i++)
libftdi_start_read(libftdi_get_free_buffer(received_data_buffers), index++, full_size);
ftd2_libusb_start_read(ftd2_libusb_get_free_buffer(received_data_buffers), index++, full_size);
while(capture_data->status.connected && capture_data->status.running) {
if(get_libftdi_status(received_data_buffers) != 0) {
if(get_ftd2_libusb_status(received_data_buffers) != 0) {
capture_error_print(true, capture_data, "Disconnected: Read error");
is_done = true;
}
if(is_done)
break;
libftdi_start_read(libftdi_get_free_buffer(received_data_buffers), index++, full_size);
ftd2_libusb_start_read(ftd2_libusb_get_free_buffer(received_data_buffers), index++, full_size);
resync_offset(received_data_buffers, index, full_size);
}
wait_all_libftdi_buffers_free(received_data_buffers);
libftdi_close_thread(&processing_thread, &usb_thread_run);
wait_all_ftd2_libusb_buffers_free(received_data_buffers);
ftd2_libusb_close_thread(&processing_thread, &usb_thread_run);
delete []received_data_buffers;
}

View File

@ -1,7 +1,7 @@
#include "dscapture_ftd2_shared.hpp"
#include "dscapture_ftd2_driver.hpp"
#include "dscapture_ftd2_general.hpp"
#include "dscapture_libftdi2.hpp"
#include "dscapture_ftd2_libusb.hpp"
#include "dscapture_ftd2_compatibility.hpp"
#include "devicecapture.hpp"
#include "usb_generic.hpp"
@ -79,42 +79,42 @@ uint64_t get_max_samples(bool is_rgb888) {
return ((get_capture_size(is_rgb888) - _ftd2_get_video_in_size(is_rgb888)) / 2) - 4; // The last 4 bytes should never be different from 0x43214321
}
static bool pass_if_FT_queue_empty(void* handle, bool is_libftdi) {
static bool pass_if_FT_queue_empty(void* handle, bool is_ftd2_libusb) {
size_t bytesIn = 0;
int retval = ftd2_get_queue_status(handle, is_libftdi, &bytesIn);
if(ftd2_is_error(retval, is_libftdi) || (bytesIn != 0)) //should be empty
int retval = ftd2_get_queue_status(handle, is_ftd2_libusb, &bytesIn);
if(ftd2_is_error(retval, is_ftd2_libusb) || (bytesIn != 0)) //should be empty
return false;
return true;
}
static bool ftd2_write_all_check(void* handle, bool is_libftdi, const uint8_t* data, size_t size) {
static bool ftd2_write_all_check(void* handle, bool is_ftd2_libusb, const uint8_t* data, size_t size) {
size_t sent = 0;
int retval = ftd2_write(handle, is_libftdi, data, size, &sent);
if(ftd2_is_error(retval, is_libftdi) || (sent != size))
int retval = ftd2_write(handle, is_ftd2_libusb, data, size, &sent);
if(ftd2_is_error(retval, is_ftd2_libusb) || (sent != size))
return false;
return true;
}
static bool full_ftd2_write(void* handle, bool is_libftdi, const uint8_t* data, size_t size) {
if(!pass_if_FT_queue_empty(handle, is_libftdi)) // maybe MPSSE error?
static bool full_ftd2_write(void* handle, bool is_ftd2_libusb, const uint8_t* data, size_t size) {
if(!pass_if_FT_queue_empty(handle, is_ftd2_libusb)) // maybe MPSSE error?
return false;
return ftd2_write_all_check(handle, is_libftdi, data, size);
return ftd2_write_all_check(handle, is_ftd2_libusb, data, size);
}
//verify CDONE==val
static bool check_cdone(void* handle, bool is_libftdi, bool want_active) {
static bool check_cdone(void* handle, bool is_ftd2_libusb, bool want_active) {
static const uint8_t cmd[] = {
0x81, //read D
0x83, //read C
};
uint8_t buf[2];
if(!full_ftd2_write(handle, is_libftdi, cmd, sizeof(cmd)))
if(!full_ftd2_write(handle, is_ftd2_libusb, cmd, sizeof(cmd)))
return false;
size_t bytesIn = 0;
int retval = ftd2_read(handle, is_libftdi, buf, 2, &bytesIn);
if(ftd2_is_error(retval, is_libftdi) || (bytesIn != 2) || (buf[0] == 0xFA))
int retval = ftd2_read(handle, is_ftd2_libusb, buf, 2, &bytesIn);
if(ftd2_is_error(retval, is_ftd2_libusb) || (bytesIn != 2) || (buf[0] == 0xFA))
return false;
if(want_active)
@ -127,7 +127,7 @@ static int end_spi_tx(uint8_t *txBuf, int retval) {
return retval;
}
static int ftd2_spi_tx(void* handle, bool is_libftdi, const uint8_t* buf, int size) {
static int ftd2_spi_tx(void* handle, bool is_ftd2_libusb, const uint8_t* buf, int size) {
uint8_t *txBuf = new uint8_t[TX_SPI_SIZE + TX_SPI_OFFSET];
int retval = 0;
int len;
@ -135,7 +135,7 @@ static int ftd2_spi_tx(void* handle, bool is_libftdi, const uint8_t* buf, int si
size_t bytesIn;
size_t wrote = 0;
if(!pass_if_FT_queue_empty(handle, is_libftdi))
if(!pass_if_FT_queue_empty(handle, is_ftd2_libusb))
return end_spi_tx(txBuf, -1);
while(size > 0) {
@ -148,13 +148,13 @@ static int ftd2_spi_tx(void* handle, bool is_libftdi, const uint8_t* buf, int si
txBuf[1] = (len - 1) & 0xFF;
txBuf[2] = ((len - 1) >> 8) & 0xFF;
retval = ftd2_write(handle, is_libftdi, txBuf, len + TX_SPI_OFFSET, &sent);
if(ftd2_is_error(retval, is_libftdi))
retval = ftd2_write(handle, is_ftd2_libusb, txBuf, len + TX_SPI_OFFSET, &sent);
if(ftd2_is_error(retval, is_ftd2_libusb))
return end_spi_tx(txBuf, retval);
if(sent != (len + TX_SPI_OFFSET))
return end_spi_tx(txBuf, -2);
if(!pass_if_FT_queue_empty(handle, is_libftdi))
if(!pass_if_FT_queue_empty(handle, is_ftd2_libusb))
return end_spi_tx(txBuf, -1);
wrote += sent - TX_SPI_OFFSET;
@ -163,7 +163,7 @@ static int ftd2_spi_tx(void* handle, bool is_libftdi, const uint8_t* buf, int si
return end_spi_tx(txBuf, 0);
}
static bool fpga_config(void* handle, bool is_libftdi, const uint8_t* bitstream, int size) {
static bool fpga_config(void* handle, bool is_ftd2_libusb, const uint8_t* bitstream, int size) {
//D6=CDONE (in)
//D3=SS (out)
//D2=TDO (in)
@ -195,19 +195,19 @@ static bool fpga_config(void* handle, bool is_libftdi, const uint8_t* bitstream,
};
int retval = 0;
retval = ftd2_set_timeouts(handle, is_libftdi, 300, 300);
if(ftd2_is_error(retval, is_libftdi))
retval = ftd2_set_timeouts(handle, is_ftd2_libusb, 300, 300);
if(ftd2_is_error(retval, is_ftd2_libusb))
return false;
if(!full_ftd2_write(handle, is_libftdi, cmd0, sizeof(cmd0)))
if(!full_ftd2_write(handle, is_ftd2_libusb, cmd0, sizeof(cmd0)))
return false;
//verify CDONE=0
if(!check_cdone(handle, is_libftdi, false))
if(!check_cdone(handle, is_ftd2_libusb, false))
return false;
//send configuration
retval = ftd2_spi_tx(handle, is_libftdi, bitstream, size);
if(ftd2_is_error(retval, is_libftdi))
retval = ftd2_spi_tx(handle, is_ftd2_libusb, bitstream, size);
if(ftd2_is_error(retval, is_ftd2_libusb))
return false;
//finish up
@ -217,17 +217,17 @@ static bool fpga_config(void* handle, bool is_libftdi, const uint8_t* bitstream,
0x80, 0x00, 0x00, //float Dx
0x82, 0x00, 0x00, //float Cx
};
if(!full_ftd2_write(handle, is_libftdi, cmd1, sizeof(cmd1)))
if(!full_ftd2_write(handle, is_ftd2_libusb, cmd1, sizeof(cmd1)))
return false;
//verify CDONE=1
if(!check_cdone(handle, is_libftdi, true))
if(!check_cdone(handle, is_ftd2_libusb, true))
return false;
return true;
}
static bool init_MPSSE(void* handle, bool is_libftdi) {
static bool init_MPSSE(void* handle, bool is_ftd2_libusb) {
static const uint8_t cmd[] = {
0x85, //no loopback
0x8d, //disable 3-phase clocking
@ -237,111 +237,111 @@ static bool init_MPSSE(void* handle, bool is_libftdi) {
};
int retval = 0;
retval = ftd2_reset_device(handle, is_libftdi);
if(ftd2_is_error(retval, is_libftdi))
retval = ftd2_reset_device(handle, is_ftd2_libusb);
if(ftd2_is_error(retval, is_ftd2_libusb))
return false;
retval = ftd2_set_usb_parameters(handle, is_libftdi, FTD2XX_IN_SIZE, FTD2XX_OUT_SIZE); //Multiple of 64 bytes up to 64k
if(ftd2_is_error(retval, is_libftdi))
retval = ftd2_set_usb_parameters(handle, is_ftd2_libusb, FTD2XX_IN_SIZE, FTD2XX_OUT_SIZE); //Multiple of 64 bytes up to 64k
if(ftd2_is_error(retval, is_ftd2_libusb))
return false;
retval = ftd2_set_chars(handle, is_libftdi, 0, 0, 0, 0);
if(ftd2_is_error(retval, is_libftdi))
retval = ftd2_set_chars(handle, is_ftd2_libusb, 0, 0, 0, 0);
if(ftd2_is_error(retval, is_ftd2_libusb))
return false;
retval = ftd2_set_timeouts(handle, is_libftdi, 300, 300); //read,write timeout (ms)
if(ftd2_is_error(retval, is_libftdi))
retval = ftd2_set_timeouts(handle, is_ftd2_libusb, 300, 300); //read,write timeout (ms)
if(ftd2_is_error(retval, is_ftd2_libusb))
return false;
retval = ftd2_set_latency_timer(handle, is_libftdi, 3); //time to wait before incomplete packet is sent (default=16ms). MPSSE read seems to fail on 2 sometimes, too fast?
if(ftd2_is_error(retval, is_libftdi))
retval = ftd2_set_latency_timer(handle, is_ftd2_libusb, 3); //time to wait before incomplete packet is sent (default=16ms). MPSSE read seems to fail on 2 sometimes, too fast?
if(ftd2_is_error(retval, is_ftd2_libusb))
return false;
retval = ftd2_set_flow_ctrl_rts_cts(handle, is_libftdi); //turn on flow control to synchronize IN requests
if(ftd2_is_error(retval, is_libftdi))
retval = ftd2_set_flow_ctrl_rts_cts(handle, is_ftd2_libusb); //turn on flow control to synchronize IN requests
if(ftd2_is_error(retval, is_ftd2_libusb))
return false;
retval = ftd2_reset_bitmode(handle, is_libftdi); //performs a general reset on MPSSE
if(ftd2_is_error(retval, is_libftdi))
retval = ftd2_reset_bitmode(handle, is_ftd2_libusb); //performs a general reset on MPSSE
if(ftd2_is_error(retval, is_ftd2_libusb))
return false;
retval = ftd2_set_mpsse_bitmode(handle, is_libftdi); //enable MPSSE mode
if(ftd2_is_error(retval, is_libftdi))
retval = ftd2_set_mpsse_bitmode(handle, is_ftd2_libusb); //enable MPSSE mode
if(ftd2_is_error(retval, is_ftd2_libusb))
return false;
//Try improving transfer rate
retval = ftd2_set_usb_parameters(handle, is_libftdi, ((sizeof(FTD2OldDSCaptureReceivedRaw) + DEFAULT_LIMIT_SIZE_TRANSFER - 1) / DEFAULT_LIMIT_SIZE_TRANSFER) * DEFAULT_LIMIT_SIZE_TRANSFER, FTD2XX_OUT_SIZE); //The programmer's guide lies?
if(ftd2_is_error(retval, is_libftdi))
retval = ftd2_set_usb_parameters(handle, is_libftdi, FTD2XX_IN_SIZE, FTD2XX_OUT_SIZE); //Backup to 64 bytes up to 64k, if more is not supported...
if(ftd2_is_error(retval, is_libftdi))
retval = ftd2_set_usb_parameters(handle, is_ftd2_libusb, ((sizeof(FTD2OldDSCaptureReceivedRaw) + DEFAULT_LIMIT_SIZE_TRANSFER - 1) / DEFAULT_LIMIT_SIZE_TRANSFER) * DEFAULT_LIMIT_SIZE_TRANSFER, FTD2XX_OUT_SIZE); //The programmer's guide lies?
if(ftd2_is_error(retval, is_ftd2_libusb))
retval = ftd2_set_usb_parameters(handle, is_ftd2_libusb, FTD2XX_IN_SIZE, FTD2XX_OUT_SIZE); //Backup to 64 bytes up to 64k, if more is not supported...
if(ftd2_is_error(retval, is_ftd2_libusb))
return false;
//MPSSE seems to choke on first write sometimes :/ Send, purge, resend.
size_t sent = 0;
retval = ftd2_write(handle, is_libftdi, cmd, 1, &sent); //enable MPSSE mode
if(ftd2_is_error(retval, is_libftdi))
retval = ftd2_write(handle, is_ftd2_libusb, cmd, 1, &sent); //enable MPSSE mode
if(ftd2_is_error(retval, is_ftd2_libusb))
return false;
default_sleep();
retval = ftd2_purge_all(handle, is_libftdi);
if(ftd2_is_error(retval, is_libftdi))
retval = ftd2_purge_all(handle, is_ftd2_libusb);
if(ftd2_is_error(retval, is_ftd2_libusb))
return false;
return full_ftd2_write(handle, is_libftdi, cmd, sizeof(cmd));
return full_ftd2_write(handle, is_ftd2_libusb, cmd, sizeof(cmd));
}
static bool preemptive_close_connection(CaptureData* capture_data, bool is_libftdi) {
ftd2_reset_device(capture_data->handle, is_libftdi);
ftd2_close(capture_data->handle, is_libftdi);
static bool preemptive_close_connection(CaptureData* capture_data, bool is_ftd2_libusb) {
ftd2_reset_device(capture_data->handle, is_ftd2_libusb);
ftd2_close(capture_data->handle, is_ftd2_libusb);
return false;
}
bool connect_ftd2_shared(bool print_failed, CaptureData* capture_data, CaptureDevice* device) {
bool is_libftdi = device->descriptor != NULL;
if(ftd2_open(device, &capture_data->handle, is_libftdi)) {
bool is_ftd2_libusb = device->descriptor != NULL;
if(ftd2_open(device, &capture_data->handle, is_ftd2_libusb)) {
capture_error_print(print_failed, capture_data, "Create failed");
return false;
}
if(!init_MPSSE(capture_data->handle, is_libftdi)) {
if(!init_MPSSE(capture_data->handle, is_ftd2_libusb)) {
capture_error_print(print_failed, capture_data, "MPSSE init failed");
return preemptive_close_connection(capture_data, is_libftdi);
return preemptive_close_connection(capture_data, is_ftd2_libusb);
}
if(!fpga_config(capture_data->handle, is_libftdi, ftd2_ds2_fws[device->firmware_id - 1], ftd2_ds2_sizes[device->firmware_id - 1])) {
if(!fpga_config(capture_data->handle, is_ftd2_libusb, ftd2_ds2_fws[device->firmware_id - 1], ftd2_ds2_sizes[device->firmware_id - 1])) {
capture_error_print(print_failed, capture_data, "FPGA config failed");
return preemptive_close_connection(capture_data, is_libftdi);
return preemptive_close_connection(capture_data, is_ftd2_libusb);
}
int retval = 0;
int val = 0;
retval = ftd2_read_ee(capture_data->handle, is_libftdi, 1, &val);
if(ftd2_is_error(retval, is_libftdi) || (val != 0x0403)) { //=85A8: something went wrong (fpga is configured but FT chip detected wrong eeprom size)
retval = ftd2_read_ee(capture_data->handle, is_ftd2_libusb, 1, &val);
if(ftd2_is_error(retval, is_ftd2_libusb) || (val != 0x0403)) { //=85A8: something went wrong (fpga is configured but FT chip detected wrong eeprom size)
capture_error_print(print_failed, capture_data, "EEPROM read error");
return preemptive_close_connection(capture_data, is_libftdi);
return preemptive_close_connection(capture_data, is_ftd2_libusb);
}
/*
int Firmware = 0;
int Hardware = 0;
retval = ftd2_read_ee(capture_data->handle, is_libftdi, 0x10, &Firmware);
if(ftd2_is_error(retval, is_libftdi)) {
retval = ftd2_read_ee(capture_data->handle, is_ftd2_libusb, 0x10, &Firmware);
if(ftd2_is_error(retval, is_ftd2_libusb)) {
capture_error_print(print_failed, capture_data, "Firmware ID read error");
return preemptive_close_connection(capture_data, is_libftdi);
return preemptive_close_connection(capture_data, is_ftd2_libusb);
}
retval = ftd2_read_ee(capture_data->handle, is_libftdi, 0x11, &Hardware);
if(ftd2_is_error(retval, is_libftdi)) {
retval = ftd2_read_ee(capture_data->handle, is_ftd2_libusb, 0x11, &Hardware);
if(ftd2_is_error(retval, is_ftd2_libusb)) {
capture_error_print(print_failed, capture_data, "Hardware ID read error");
return preemptive_close_connection(capture_data, is_libftdi);
return preemptive_close_connection(capture_data, is_ftd2_libusb);
}
*/
retval = ftd2_set_fifo_bitmode(capture_data->handle, is_libftdi); //to FIFO mode. This takes over port B, pins shouldn't get modified though
if(ftd2_is_error(retval, is_libftdi)) {
retval = ftd2_set_fifo_bitmode(capture_data->handle, is_ftd2_libusb); //to FIFO mode. This takes over port B, pins shouldn't get modified though
if(ftd2_is_error(retval, is_ftd2_libusb)) {
capture_error_print(print_failed, capture_data, "Bitmode setup error");
return preemptive_close_connection(capture_data, is_libftdi);
return preemptive_close_connection(capture_data, is_ftd2_libusb);
}
retval = ftd2_set_timeouts(capture_data->handle, is_libftdi, 50, 50);
if(ftd2_is_error(retval, is_libftdi)) {
retval = ftd2_set_timeouts(capture_data->handle, is_ftd2_libusb, 50, 50);
if(ftd2_is_error(retval, is_ftd2_libusb)) {
capture_error_print(print_failed, capture_data, "Timeouts setup error");
return preemptive_close_connection(capture_data, is_libftdi);
return preemptive_close_connection(capture_data, is_ftd2_libusb);
}
if(!pass_if_FT_queue_empty(capture_data->handle, is_libftdi)) {// maybe MPSSE error?
if(!pass_if_FT_queue_empty(capture_data->handle, is_ftd2_libusb)) {// maybe MPSSE error?
capture_error_print(print_failed, capture_data, "Intermediate error");
return preemptive_close_connection(capture_data, is_libftdi);
return preemptive_close_connection(capture_data, is_ftd2_libusb);
}
return true;
@ -389,9 +389,9 @@ size_t remove_synch_from_final_length(uint32_t* out_buffer, size_t real_length)
return real_length;
}
bool enable_capture(void* handle, bool is_libftdi) {
bool enable_capture(void* handle, bool is_ftd2_libusb) {
static const uint8_t cmd[]={ 0x80, 0x01 }; //enable capture
return ftd2_write_all_check(handle, is_libftdi, cmd, sizeof(cmd));
return ftd2_write_all_check(handle, is_ftd2_libusb, cmd, sizeof(cmd));
}
void ftd2_capture_main_loop_shared(CaptureData* capture_data) {
@ -401,8 +401,8 @@ void ftd2_capture_main_loop_shared(CaptureData* capture_data) {
void ftd2_capture_cleanup_shared(CaptureData* capture_data) {
for(int i = 0; i < NUM_CAPTURE_RECEIVED_DATA_BUFFERS; i++)
capture_data->data_buffers.ReleaseWriterBuffer(i, false);
bool is_libftdi = capture_data->status.device.descriptor != NULL;
if(ftd2_close(capture_data->handle, is_libftdi)) {
bool is_ftd2_libusb = capture_data->status.device.descriptor != NULL;
if(ftd2_close(capture_data->handle, is_ftd2_libusb)) {
capture_error_print(true, capture_data, "Disconnected: Close failed");
}
}

View File

@ -46,21 +46,6 @@ static const LicenseMenuOptionInfo ftd3xx_license_3_option = {
static const LicenseMenuOptionInfo ftd3xx_license_4_option = {
.base_name = "driver-licence-terms-details/"};
static const LicenseMenuOptionInfo libftdi_license_0_option = {
.base_name = "This software makes use of"};
static const LicenseMenuOptionInfo libftdi_license_1_option = {
.base_name = "libftdi1."};
static const LicenseMenuOptionInfo libftdi_license_2_option = {
.base_name = "For its license, check:"};
static const LicenseMenuOptionInfo libftdi_license_3_option = {
.base_name = "http://developer.intra2net.com/git/?p="};
static const LicenseMenuOptionInfo libftdi_license_4_option = {
.base_name = "libftdi;a=blob_plain;f=LICENSE;hb=HEAD/"};
static const LicenseMenuOptionInfo libusb_license_0_option = {
.base_name = "This software makes use of"};
@ -149,13 +134,6 @@ static const LicenseMenuOptionInfo* pollable_options[] = {
&ftd3xx_license_3_option,
&ftd3xx_license_4_option,
#endif
#ifdef USE_FTD2_LIBFTDI
&libftdi_license_0_option,
&libftdi_license_1_option,
&libftdi_license_2_option,
&libftdi_license_3_option,
&libftdi_license_4_option,
#endif
#if defined(USE_LIBUSB) || defined(USE_FTD3XX) || defined(USE_FTD2_DRIVER)
&libusb_license_0_option,
&libusb_license_1_option,