mirror of
https://github.com/EEVengers/ThunderScope.git
synced 2025-04-22 17:43:44 +00:00
Basic Functional USB 3.0 Reading Implemented
This commit is contained in:
parent
cccfd8b8d2
commit
373424313b
.DS_Store.gitignore
DSO_Software/Xcode_Project/Scope
.DS_Store
Scope.xcodeproj
project.pbxproj
project.xcworkspace/xcuserdata/danielvasile.xcuserdatad
xcshareddata/xcschemes
xcuserdata/danielvasile.xcuserdatad
Scope
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
|
||||
DSO_Software/Xcode_Project/Scope/Scope.xcodeproj/project.xcworkspace/xcuserdata/danielvasile.xcuserdatad/UserInterfaceState.xcuserstate
|
||||
DSO_Software/Xcode_Project/Scope/Scope.xcodeproj/project.xcworkspace/xcuserdata/danielvasile.xcuserdatad/UserInterfaceState.xcuserstate
|
||||
DSO_Software/Xcode_Project/Scope/Scope.xcodeproj/project.xcworkspace/xcuserdata/danielvasile.xcuserdatad/UserInterfaceState.xcuserstate
|
||||
|
BIN
DSO_Software/Xcode_Project/Scope/.DS_Store
vendored
Normal file
BIN
DSO_Software/Xcode_Project/Scope/.DS_Store
vendored
Normal file
Binary file not shown.
@ -7,8 +7,11 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1D39341E22F108620097D2E8 /* SuperSpeedFIFIOBridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D39341C22F108620097D2E8 /* SuperSpeedFIFIOBridge.cpp */; };
|
||||
1D39342122F10BAF0097D2E8 /* DataTransferThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D39341F22F10BAF0097D2E8 /* DataTransferThread.cpp */; };
|
||||
1DCD2FA822EB63EF0007F762 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DCD2FA722EB63EF0007F762 /* main.cpp */; };
|
||||
1DCD2FB222EBB4AE0007F762 /* libftd3xx.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DCD2FB122EBB4AE0007F762 /* libftd3xx.dylib */; settings = {ATTRIBUTES = (Required, ); }; };
|
||||
1DCD2FB422EBBB320007F762 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DCD2FB322EBBB320007F762 /* libc++.tbd */; };
|
||||
1DCD2FB722EBC1280007F762 /* libftd3xx.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DCD2FB122EBB4AE0007F762 /* libftd3xx.dylib */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@ -24,11 +27,16 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1D39341C22F108620097D2E8 /* SuperSpeedFIFIOBridge.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SuperSpeedFIFIOBridge.cpp; sourceTree = "<group>"; };
|
||||
1D39341D22F108620097D2E8 /* SuperSpeedFIFIOBridge.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = SuperSpeedFIFIOBridge.hpp; sourceTree = "<group>"; };
|
||||
1D39341F22F10BAF0097D2E8 /* DataTransferThread.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DataTransferThread.cpp; sourceTree = "<group>"; };
|
||||
1D39342022F10BAF0097D2E8 /* DataTransferThread.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DataTransferThread.hpp; sourceTree = "<group>"; };
|
||||
1D39342222F10DEE0097D2E8 /* EVLibrary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EVLibrary.h; sourceTree = "<group>"; };
|
||||
1DCD2FA422EB63EF0007F762 /* Scope */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Scope; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1DCD2FA722EB63EF0007F762 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
|
||||
1DCD2FAE22EB6CFE0007F762 /* ftd3xx.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ftd3xx.h; sourceTree = "<group>"; };
|
||||
1DCD2FAF22EB6E540007F762 /* common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
|
||||
1DCD2FB122EBB4AE0007F762 /* libftd3xx.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libftd3xx.dylib; path = ../../../../../../../../../../usr/local/lib/libftd3xx.dylib; sourceTree = "<group>"; };
|
||||
1DCD2FB322EBBB320007F762 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -36,7 +44,8 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1DCD2FB222EBB4AE0007F762 /* libftd3xx.dylib in Frameworks */,
|
||||
1DCD2FB722EBC1280007F762 /* libftd3xx.dylib in Frameworks */,
|
||||
1DCD2FB422EBBB320007F762 /* libc++.tbd in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -65,7 +74,11 @@
|
||||
children = (
|
||||
1DCD2FA722EB63EF0007F762 /* main.cpp */,
|
||||
1DCD2FAE22EB6CFE0007F762 /* ftd3xx.h */,
|
||||
1DCD2FAF22EB6E540007F762 /* common.h */,
|
||||
1D39341C22F108620097D2E8 /* SuperSpeedFIFIOBridge.cpp */,
|
||||
1D39341D22F108620097D2E8 /* SuperSpeedFIFIOBridge.hpp */,
|
||||
1D39341F22F10BAF0097D2E8 /* DataTransferThread.cpp */,
|
||||
1D39342022F10BAF0097D2E8 /* DataTransferThread.hpp */,
|
||||
1D39342222F10DEE0097D2E8 /* EVLibrary.h */,
|
||||
);
|
||||
path = Scope;
|
||||
sourceTree = "<group>";
|
||||
@ -73,6 +86,7 @@
|
||||
1DCD2FB022EBB4AE0007F762 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1DCD2FB322EBBB320007F762 /* libc++.tbd */,
|
||||
1DCD2FB122EBB4AE0007F762 /* libftd3xx.dylib */,
|
||||
);
|
||||
name = Frameworks;
|
||||
@ -134,7 +148,9 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1D39341E22F108620097D2E8 /* SuperSpeedFIFIOBridge.cpp in Sources */,
|
||||
1DCD2FA822EB63EF0007F762 /* main.cpp in Sources */,
|
||||
1D39342122F10BAF0097D2E8 /* DataTransferThread.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
Binary file not shown.
@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1030"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1DCD2FA322EB63EF0007F762"
|
||||
BuildableName = "Scope"
|
||||
BlueprintName = "Scope"
|
||||
ReferencedContainer = "container:Scope.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1DCD2FA322EB63EF0007F762"
|
||||
BuildableName = "Scope"
|
||||
BlueprintName = "Scope"
|
||||
ReferencedContainer = "container:Scope.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1DCD2FA322EB63EF0007F762"
|
||||
BuildableName = "Scope"
|
||||
BlueprintName = "Scope"
|
||||
ReferencedContainer = "container:Scope.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1DCD2FA322EB63EF0007F762"
|
||||
BuildableName = "Scope"
|
||||
BlueprintName = "Scope"
|
||||
ReferencedContainer = "container:Scope.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Bucket
|
||||
type = "1"
|
||||
version = "2.0">
|
||||
</Bucket>
|
@ -10,5 +10,13 @@
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>1DCD2FA322EB63EF0007F762</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -0,0 +1,14 @@
|
||||
//
|
||||
// DataTransferThread.cpp
|
||||
// Scope
|
||||
//
|
||||
// Created by Daniel Vasile on 2019-07-30.
|
||||
// Copyright © 2019 EEVengers. All rights reserved.
|
||||
//
|
||||
|
||||
#include "DataTransferThread.hpp"
|
||||
|
||||
|
||||
void SuperSpeedFIFOBridgeHandler(FT_HANDLE SuperSpeedFIFOBridgeHandle, UCHAR **buffers) {
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
//
|
||||
// DataTransferThread.hpp
|
||||
// Scope
|
||||
//
|
||||
// Created by Daniel Vasile on 2019-07-30.
|
||||
// Copyright © 2019 EEVengers. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef DataTransferThread_hpp
|
||||
#define DataTransferThread_hpp
|
||||
|
||||
#include "EVLibrary.h"
|
||||
|
||||
/*
|
||||
*
|
||||
* @params
|
||||
* FT_HANDLE SuperSpeedFIFODridgeHandle - A Handle to the Super Speed FIFO Bridge that is opened using InitFTDISuperSpeedChip()
|
||||
* UCHAR **buffers - A 2D array that contains NUM_BUFFERS buffers of size BUFFER_SIZE
|
||||
* @return
|
||||
* Nothing
|
||||
*/
|
||||
void SuperSpeedFIFOBridgeHandler(FT_HANDLE SuperSpeedFIFOBridgeHandle, UCHAR **buffers);
|
||||
|
||||
#endif /* DataTransferThread_hpp */
|
17
DSO_Software/Xcode_Project/Scope/Scope/EVLibrary.h
Normal file
17
DSO_Software/Xcode_Project/Scope/Scope/EVLibrary.h
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// EVLibrary.h
|
||||
// Scope
|
||||
//
|
||||
// Created by Daniel Vasile on 2019-07-30.
|
||||
// Copyright © 2019 EEVengers. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef EVLibrary_h
|
||||
#define EVLibrary_h
|
||||
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include "ftd3xx.h"
|
||||
|
||||
#endif /* EVLibrary_h */
|
@ -0,0 +1,89 @@
|
||||
//
|
||||
// SuperSpeedFIFIOBridge.cpp
|
||||
// Scope
|
||||
//
|
||||
// Created by Daniel Vasile on 2019-07-30.
|
||||
// Copyright © 2019 EEVengers. All rights reserved.
|
||||
//
|
||||
|
||||
#include "SuperSpeedFIFIOBridge.hpp"
|
||||
|
||||
/*
|
||||
* Used To Get A Handle To The FTDI SuperSpeed FIFO Bridge
|
||||
* @params
|
||||
* FT_HANDLE *device_handle - A pointer to a variable which will hold the inialized handle to the FIFO SuperSpeed Bridge
|
||||
* @return
|
||||
* 0 on success
|
||||
*/
|
||||
int InitFTDISuperSpeedChip(FT_HANDLE *deviceHandle) {
|
||||
|
||||
FT_DEVICE_LIST_INFO_NODE deviceInfoList[1];
|
||||
DWORD numDevices;
|
||||
DWORD error;
|
||||
|
||||
//check the driver for a super speed FIFO buffer, if it exists, open it and set its configuration.
|
||||
if(FT_OK != (error = FT_CreateDeviceInfoList(&numDevices))) {
|
||||
std::cout << "Could Not Create Device Info List, Error: " << error << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( numDevices == 0 ) {
|
||||
std::cout << "No FTDI SuperSpeed Devices Have Been Detected" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(FT_OK != (error = FT_GetDeviceInfoList(deviceInfoList, &numDevices))) {
|
||||
std::cout << "Could Not Get Device Info List, Error: " << error << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(FT_OK != (error = FT_Create( (PVOID)deviceInfoList[0].SerialNumber, (DWORD)FT_OPEN_BY_SERIAL_NUMBER, deviceHandle))){
|
||||
std::cout << "Could Not Open SuperSpeed FIFO Bridge Handle, Error: " << error << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Set Channel Config to fifo600_mode and 100Mhz clk with appropiate flags
|
||||
FT_60XCONFIGURATION oldConfig, newConfig;
|
||||
if(FT_OK != (error = FT_GetChipConfiguration(*deviceHandle, &oldConfig))) {
|
||||
std::cout << "Could Not Get SuperSpeed FIFO Bridge Configuration, Error Code: " << error << std::endl;
|
||||
return 1;
|
||||
}
|
||||
memcpy(&newConfig, &oldConfig, sizeof(FT_60XCONFIGURATION));
|
||||
newConfig.FIFOClock = CONFIGURATION_FIFO_CLK_100;
|
||||
newConfig.FIFOMode = CONFIGURATION_FIFO_MODE_245;
|
||||
newConfig.OptionalFeatureSupport |= CONFIGURATION_OPTIONAL_FEATURE_ENABLENOTIFICATIONMESSAGE_INCHALL | CONFIGURATION_OPTIONAL_FEATURE_DISABLECANCELSESSIONUNDERRUN | CONFIGURATION_OPTIONAL_FEATURE_DISABLEUNDERRUN_INCHALL;
|
||||
newConfig.ChannelConfig = CONFIGURATION_CHANNEL_CONFIG_1_INPIPE;
|
||||
if(FT_OK != (error = FT_SetChipConfiguration(*deviceHandle, &newConfig))) {
|
||||
std::cout << "Could Not Set SuperSpeed FIFO Bridge Configuration, Error Code: " << error << std::endl;
|
||||
return 1;
|
||||
}
|
||||
FT_Close(*deviceHandle);
|
||||
|
||||
//Wait For The SuperSpeed FIFO Bridge To Power Cycle
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
|
||||
//reopen device since configuration causes a reset
|
||||
*deviceHandle = 0;
|
||||
deviceInfoList[0] = {0};
|
||||
if(FT_OK != (error = FT_CreateDeviceInfoList(&numDevices))) {
|
||||
std::cout << "Could Not Create Device Info List After SuperSpeed FIFO Bridge Configuration, Error: " << error << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( numDevices == 0 ) {
|
||||
std::cout << "No FTDI SuperSpeed Devices Have Been Detected After SuperSpeed FIFO Bridge Configuration" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(FT_OK != (error = FT_GetDeviceInfoList(deviceInfoList, &numDevices))) {
|
||||
std::cout << "Could Not Get Device Info List After SuperSpeed FIFO Bridge Configuration, Error: " << error << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(FT_OK != (error = FT_Create( (PVOID)deviceInfoList[0].SerialNumber, (DWORD)FT_OPEN_BY_SERIAL_NUMBER, deviceHandle))){
|
||||
std::cout << "Could Not Open SuperSpeed FIFO Bridge Handle After SuperSpeed FIFO Bridge Configuration, Error: " << error << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
//
|
||||
// SuperSpeedFIFIOBridge.hpp
|
||||
// Scope
|
||||
//
|
||||
// Created by Daniel Vasile on 2019-07-30.
|
||||
// Copyright © 2019 EEVengers. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SuperSpeedFIFIOBridge_hpp
|
||||
#define SuperSpeedFIFIOBridge_hpp
|
||||
|
||||
#include "EVLibrary.h"
|
||||
|
||||
/*
|
||||
* Used To Get A Handle To The FTDI SuperSpeed FIFO Bridge
|
||||
* @params
|
||||
* FT_HANDLE *device_handle - A pointer to a variable which will hold the inialized handle to the FIFO SuperSpeed Bridge
|
||||
* @return
|
||||
* 0 on success
|
||||
*/
|
||||
int InitFTDISuperSpeedChip(FT_HANDLE *deviceHandle);
|
||||
|
||||
|
||||
|
||||
#endif /* SuperSpeedFIFIOBridge_hpp */
|
@ -1,218 +0,0 @@
|
||||
//
|
||||
// common.h
|
||||
// Scope
|
||||
//
|
||||
// Copied by Daniel Vasile from FTDI Example Program on 2019-07-26.
|
||||
//
|
||||
|
||||
#ifndef COMMON_H_6J30YQFP
|
||||
#define COMMON_H_6J30YQFP
|
||||
#include <iostream>
|
||||
#include <atomic>
|
||||
#include <csignal>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <thread>
|
||||
#include "ftd3xx.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static bool do_exit;
|
||||
static atomic_int tx_count;
|
||||
static atomic_int rx_count;
|
||||
static uint8_t in_ch_cnt;
|
||||
static uint8_t out_ch_cnt;
|
||||
|
||||
static void sig_hdlr(int signum)
|
||||
{
|
||||
switch (signum) {
|
||||
case SIGINT:
|
||||
do_exit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void register_signals(void)
|
||||
{
|
||||
signal(SIGINT, sig_hdlr);
|
||||
}
|
||||
|
||||
static void get_version(void)
|
||||
{
|
||||
DWORD dwVersion;
|
||||
|
||||
FT_GetDriverVersion(NULL, &dwVersion);
|
||||
printf("Driver version:%d.%d.%d\r\n", dwVersion >> 24,
|
||||
(uint8_t)(dwVersion >> 16), dwVersion & 0xFFFF);
|
||||
|
||||
FT_GetLibraryVersion(&dwVersion);
|
||||
printf("Library version:%d.%d.%d\r\n", dwVersion >> 24,
|
||||
(uint8_t)(dwVersion >> 16), dwVersion & 0xFFFF);
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#define turn_off_thread_safe()
|
||||
#else /* _WIN32 || _WIN64 */
|
||||
static void turn_off_thread_safe(void)
|
||||
{
|
||||
FT_TRANSFER_CONF conf;
|
||||
|
||||
memset(&conf, 0, sizeof(FT_TRANSFER_CONF));
|
||||
conf.wStructSize = sizeof(FT_TRANSFER_CONF);
|
||||
conf.pipe[FT_PIPE_DIR_IN].fNonThreadSafeTransfer = true;
|
||||
conf.pipe[FT_PIPE_DIR_OUT].fNonThreadSafeTransfer = true;
|
||||
for (DWORD i = 0; i < 4; i++)
|
||||
FT_SetTransferParams(&conf, i);
|
||||
}
|
||||
#endif /* !_WIN32 && !_WIN64 */
|
||||
static bool get_device_lists(int timeout_ms)
|
||||
{
|
||||
DWORD count;
|
||||
FT_DEVICE_LIST_INFO_NODE nodes[16];
|
||||
|
||||
chrono::steady_clock::time_point const timeout =
|
||||
chrono::steady_clock::now() +
|
||||
chrono::milliseconds(timeout_ms);
|
||||
|
||||
do {
|
||||
if (FT_OK == FT_CreateDeviceInfoList(&count))
|
||||
break;
|
||||
this_thread::sleep_for(chrono::microseconds(10));
|
||||
} while (chrono::steady_clock::now() < timeout);
|
||||
printf("Total %u device(s)\r\n", count);
|
||||
if (!count)
|
||||
return false;
|
||||
|
||||
if (FT_OK != FT_GetDeviceInfoList(nodes, &count))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void show_throughput(FT_HANDLE handle)
|
||||
{
|
||||
auto next = chrono::steady_clock::now() + chrono::seconds(1);;
|
||||
(void)handle;
|
||||
|
||||
while (!do_exit) {
|
||||
this_thread::sleep_until(next);
|
||||
next += chrono::seconds(1);
|
||||
|
||||
int tx = tx_count.exchange(0);
|
||||
int rx = rx_count.exchange(0);
|
||||
|
||||
printf("TX:%.2fMiB/s RX:%.2fMiB/s, total:%.2fMiB\r\n",
|
||||
(float)tx/1000/1000, (float)rx/1000/1000,
|
||||
(float)(tx+ rx)/1000/1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void set_ft600_optional_features(USHORT *features)
|
||||
{
|
||||
USHORT flag;
|
||||
|
||||
flag = CONFIGURATION_OPTIONAL_FEATURE_ENABLENOTIFICATIONMESSAGE_INCHALL;
|
||||
if (flag & *features) {
|
||||
*features &= ~flag;
|
||||
printf("Notification feature is not supported\r\n");
|
||||
}
|
||||
|
||||
flag = CONFIGURATION_OPTIONAL_FEATURE_DISABLECANCELSESSIONUNDERRUN;
|
||||
if (!(flag & *features)) {
|
||||
*features |= flag;
|
||||
printf("Cancel session on underrun is not supported\r\n");
|
||||
}
|
||||
|
||||
flag = CONFIGURATION_OPTIONAL_FEATURE_DISABLEUNDERRUN_INCHALL;
|
||||
if (!(flag & *features)) {
|
||||
*features |= flag;
|
||||
printf("Set 'disable underrun' to get better performance\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void set_ft600_channels(UCHAR *channels, bool is_600_mode)
|
||||
{
|
||||
if (in_ch_cnt == 1 && out_ch_cnt == 0) {
|
||||
*channels = CONFIGURATION_CHANNEL_CONFIG_1_INPIPE;
|
||||
} else if (in_ch_cnt == 0 && out_ch_cnt == 1)
|
||||
*channels = CONFIGURATION_CHANNEL_CONFIG_1_OUTPIPE;
|
||||
else {
|
||||
UCHAR total = in_ch_cnt < out_ch_cnt ? out_ch_cnt : in_ch_cnt;
|
||||
|
||||
if (total == 4)
|
||||
*channels = CONFIGURATION_CHANNEL_CONFIG_4;
|
||||
else if (total == 2)
|
||||
*channels = CONFIGURATION_CHANNEL_CONFIG_2;
|
||||
else
|
||||
*channels = CONFIGURATION_CHANNEL_CONFIG_1;
|
||||
|
||||
if (!is_600_mode && total > 1) {
|
||||
printf("245 mode only support single channel\r\n");
|
||||
exit (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void set_ft600_channel_config(FT_60XCONFIGURATION *cfg,
|
||||
CONFIGURATION_FIFO_CLK clock, bool is_600_mode)
|
||||
{
|
||||
cfg->FIFOClock = clock;
|
||||
cfg->FIFOMode = is_600_mode ? CONFIGURATION_FIFO_MODE_600 :
|
||||
CONFIGURATION_FIFO_MODE_245;
|
||||
set_ft600_optional_features(&cfg->OptionalFeatureSupport);
|
||||
set_ft600_channels(&cfg->ChannelConfig, is_600_mode);
|
||||
|
||||
const char *const CH_STR[] = {
|
||||
"4CH",
|
||||
"2CH",
|
||||
"1CH",
|
||||
"1CH OUT",
|
||||
"1CH IN",
|
||||
};
|
||||
const char *const FIFO_STR[] = {
|
||||
"FT245",
|
||||
"FT600",
|
||||
};
|
||||
printf("%s %s @ 100MHz\r\n",
|
||||
CH_STR[cfg->ChannelConfig], FIFO_STR[cfg->FIFOMode]);
|
||||
}
|
||||
|
||||
static bool set_channel_config(bool is_600_mode, CONFIGURATION_FIFO_CLK clock)
|
||||
{
|
||||
FT_HANDLE handle = NULL;
|
||||
DWORD dwType = FT_DEVICE_UNKNOWN;
|
||||
|
||||
FT_Create(0, FT_OPEN_BY_INDEX, &handle);
|
||||
if (!handle)
|
||||
return false;
|
||||
FT_GetDeviceInfoDetail(0, NULL, &dwType, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
union CHIP_CONFIGURATION {
|
||||
FT_60XCONFIGURATION ft600;
|
||||
} old_cfg, new_cfg;
|
||||
|
||||
if (FT_OK != FT_GetChipConfiguration(handle, &old_cfg)) {
|
||||
printf("Failed to get chip conf\r\n");
|
||||
return false;
|
||||
}
|
||||
memcpy(&new_cfg, &old_cfg, sizeof(union CHIP_CONFIGURATION));
|
||||
|
||||
if (dwType == FT_DEVICE_600 || dwType == FT_DEVICE_601)
|
||||
set_ft600_channel_config(&new_cfg.ft600, clock, is_600_mode);
|
||||
else
|
||||
return false;
|
||||
if (memcmp(&new_cfg, &old_cfg, sizeof(union CHIP_CONFIGURATION))) {
|
||||
if (FT_OK != FT_SetChipConfiguration(handle, &new_cfg)) {
|
||||
printf("Failed to set chip conf\r\n");
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Configuration changed\r\n");
|
||||
this_thread::sleep_for(chrono::seconds(1));
|
||||
get_device_lists(6000);
|
||||
}
|
||||
}
|
||||
FT_Close(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* end of include guard: COMMON_H_6J30YQFP */
|
@ -6,153 +6,43 @@
|
||||
// Copyright © 2019 EEVengers. All rights reserved.
|
||||
//
|
||||
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include "common.h"
|
||||
#include "EVLibrary.h"
|
||||
#include "SuperSpeedFIFIOBridge.hpp"
|
||||
|
||||
#define FIFO_SUPER_SPEED_BRIDGE_NAME "FTDI SuperSpeed-FIFO Bridge"
|
||||
|
||||
static bool fifo_600mode;
|
||||
static thread measure_thread;
|
||||
static thread write_thread;
|
||||
static thread read_thread;
|
||||
static const int BUFFER_LEN = 32*1024;
|
||||
|
||||
static void write_test(FT_HANDLE handle)
|
||||
{
|
||||
unique_ptr<uint8_t[]> buf(new uint8_t[BUFFER_LEN]);
|
||||
|
||||
while (!do_exit) {
|
||||
for (uint8_t channel = 0; channel < out_ch_cnt; channel++) {
|
||||
ULONG count = 0;
|
||||
if (FT_OK != FT_WritePipeEx(handle, channel,
|
||||
buf.get(), BUFFER_LEN, &count, 1000)) {
|
||||
do_exit = true;
|
||||
break;
|
||||
}
|
||||
tx_count += count;
|
||||
}
|
||||
}
|
||||
printf("Write stopped\r\n");
|
||||
}
|
||||
|
||||
static void read_test(FT_HANDLE handle)
|
||||
{
|
||||
unique_ptr<uint8_t[]> buf(new uint8_t[BUFFER_LEN]);
|
||||
|
||||
while (!do_exit) {
|
||||
for (uint8_t channel = 0; channel < in_ch_cnt; channel++) {
|
||||
ULONG count = 0;
|
||||
if (FT_OK != FT_ReadPipeEx(handle, channel,
|
||||
buf.get(), BUFFER_LEN, &count, 1000)) {
|
||||
do_exit = true;
|
||||
break;
|
||||
}
|
||||
rx_count += count;
|
||||
}
|
||||
}
|
||||
printf("Read stopped\r\n");
|
||||
}
|
||||
|
||||
static void show_help(const char *bin)
|
||||
{
|
||||
printf("Usage: %s <out channel count> <in channel count> [mode]\r\n", bin);
|
||||
printf(" channel count: [0, 1] for 245 mode, [0-4] for 600 mode\r\n");
|
||||
printf(" mode: 0 = FT245 mode (default), 1 = FT600 mode\r\n");
|
||||
}
|
||||
|
||||
static void get_queue_status(HANDLE handle)
|
||||
{
|
||||
for (uint8_t channel = 0; channel < out_ch_cnt; channel++) {
|
||||
DWORD dwBufferred;
|
||||
|
||||
if (FT_OK != FT_GetUnsentBuffer(handle, channel,
|
||||
NULL, &dwBufferred)) {
|
||||
printf("Failed to get unsent buffer size\r\n");
|
||||
continue;
|
||||
}
|
||||
unique_ptr<uint8_t[]> p(new uint8_t[dwBufferred]);
|
||||
|
||||
printf("CH%d OUT unsent buffer size in queue:%u\r\n",
|
||||
channel, dwBufferred);
|
||||
if (FT_OK != FT_GetUnsentBuffer(handle, channel,
|
||||
p.get(), &dwBufferred)) {
|
||||
printf("Failed to read unsent buffer size\r\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t channel = 0; channel < in_ch_cnt; channel++) {
|
||||
DWORD dwBufferred;
|
||||
|
||||
if (FT_OK != FT_GetReadQueueStatus(handle, channel, &dwBufferred))
|
||||
continue;
|
||||
printf("CH%d IN unread buffer size in queue:%u\r\n",
|
||||
channel, dwBufferred);
|
||||
}
|
||||
}
|
||||
|
||||
static bool validate_arguments(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 3 && argc != 4)
|
||||
return false;
|
||||
|
||||
if (argc == 4) {
|
||||
int val = atoi(argv[3]);
|
||||
if (val != 0 && val != 1)
|
||||
return false;
|
||||
fifo_600mode = (bool)val;
|
||||
}
|
||||
|
||||
out_ch_cnt = atoi(argv[1]);
|
||||
in_ch_cnt = atoi(argv[2]);
|
||||
|
||||
if ((in_ch_cnt == 0 && out_ch_cnt == 0) ||
|
||||
in_ch_cnt > 4 || out_ch_cnt > 4) {
|
||||
show_help(argv[0]);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FT_HANDLE superSuperFIFOBridgeHandle = 0;
|
||||
UCHAR buffer[BUFFER_LEN] = {0};
|
||||
DWORD error;
|
||||
ULONG bytesRead;
|
||||
|
||||
get_version();
|
||||
|
||||
if (!validate_arguments(argc, argv)) {
|
||||
show_help(argv[0]);
|
||||
if(InitFTDISuperSpeedChip(&superSuperFIFOBridgeHandle)) {
|
||||
std::cout << "Error Failed To Open Handle To FTDI SuperSpeed FIFO Buffer" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!get_device_lists(500))
|
||||
return 1;
|
||||
// FT_ReadPipe(superSuperFIFOBridgeHandle, (UCHAR)0x82, buffer, BUFFER_LEN, &bytes_read, NULL);
|
||||
// std::cout << "# Of Bytes Read: " << bytes_read << std::endl;
|
||||
|
||||
// uint64_t total_bytes_read = 0;
|
||||
// auto start_time = std::chrono::high_resolution_clock::now();
|
||||
// while(total_bytes_read < (((uint64_t)1) << 32)) {
|
||||
// if(FT_OK != (error = FT_ReadPipe(superSuperFIFOBridgeHandle, (UCHAR)0x82, buffer, BUFFER_LEN, &bytesRead, NULL))) {
|
||||
// std::cout << "Could Not Read Pipe 0x82 from FIFO-SuperSpeed Bridge, Error Code: " << error << std::endl;
|
||||
// return 1;
|
||||
// }
|
||||
// total_bytes_read += bytesRead;
|
||||
// }
|
||||
// auto end_time = std::chrono::high_resolution_clock::now();
|
||||
// auto total_time = end_time - start_time;
|
||||
// std::cout << "Data Transfer Rate Average: " << ((double)(2^32) / (double)total_time.count()) / (8.0) * 1000000000000.0 << "MB/s" << std::endl;
|
||||
|
||||
if (!set_channel_config(fifo_600mode, CONFIGURATION_FIFO_CLK_100))
|
||||
return 1;
|
||||
FT_Close(superSuperFIFOBridgeHandle);
|
||||
|
||||
/* Must be called before FT_Create is called */
|
||||
turn_off_thread_safe();
|
||||
|
||||
FT_HANDLE handle = NULL;
|
||||
|
||||
FT_Create(0, FT_OPEN_BY_INDEX, &handle);
|
||||
if (!handle) {
|
||||
printf("Failed to create device\r\n");
|
||||
return -1;
|
||||
}
|
||||
if (out_ch_cnt)
|
||||
write_thread = thread(write_test, handle);
|
||||
if (in_ch_cnt)
|
||||
read_thread = thread(read_test, handle);
|
||||
measure_thread = thread(show_throughput, handle);
|
||||
register_signals();
|
||||
|
||||
if (write_thread.joinable())
|
||||
write_thread.join();
|
||||
if (read_thread.joinable())
|
||||
read_thread.join();
|
||||
if (measure_thread.joinable())
|
||||
measure_thread.join();
|
||||
get_queue_status(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user