mirror of
https://github.com/EEVengers/ThunderScope.git
synced 2025-04-22 17:43:44 +00:00
MultiThreaded Reading, MultiThreaded Safe Shared Cache and Classes
This commit is contained in:
parent
f5372a3a34
commit
80ec2d9eee
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ DSO_Software/Xcode_Project/Scope/Scope.xcodeproj/project.xcworkspace/xcuserdata/
|
||||
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
|
||||
*.xcuserstate
|
||||
*.xcuserstate
|
||||
|
@ -13,6 +13,7 @@
|
||||
1D39342B22FB22400097D2E8 /* libftd3xx.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DCD2FB122EBB4AE0007F762 /* libftd3xx.dylib */; };
|
||||
1D39342D22FB22470097D2E8 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D39342C22FB22470097D2E8 /* OpenGL.framework */; };
|
||||
1D39342E22FB26F90097D2E8 /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D39342922FB1EFE0097D2E8 /* GLUT.framework */; };
|
||||
1DAA89BA236290E400E0F9D6 /* EVLibrary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DAA89B9236290E400E0F9D6 /* EVLibrary.cpp */; };
|
||||
1DCD2FA822EB63EF0007F762 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DCD2FA722EB63EF0007F762 /* main.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@ -38,6 +39,7 @@
|
||||
1D39342422F9D1C70097D2E8 /* EVDigitalProcessing.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = EVDigitalProcessing.hpp; sourceTree = "<group>"; };
|
||||
1D39342922FB1EFE0097D2E8 /* GLUT.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLUT.framework; path = System/Library/Frameworks/GLUT.framework; sourceTree = SDKROOT; };
|
||||
1D39342C22FB22470097D2E8 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
|
||||
1DAA89B9236290E400E0F9D6 /* EVLibrary.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = EVLibrary.cpp; 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>"; };
|
||||
@ -86,6 +88,7 @@
|
||||
1D39341F22F10BAF0097D2E8 /* EVDataTransferThread.cpp */,
|
||||
1D39342022F10BAF0097D2E8 /* EVDataTransferThread.hpp */,
|
||||
1D39342222F10DEE0097D2E8 /* EVLibrary.h */,
|
||||
1DAA89B9236290E400E0F9D6 /* EVLibrary.cpp */,
|
||||
1D39342322F9D1C70097D2E8 /* EVDigitalProcessing.cpp */,
|
||||
1D39342422F9D1C70097D2E8 /* EVDigitalProcessing.hpp */,
|
||||
);
|
||||
@ -159,6 +162,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1DAA89BA236290E400E0F9D6 /* EVLibrary.cpp in Sources */,
|
||||
1D39341E22F108620097D2E8 /* EVSuperSpeedFIFIOBridge.cpp in Sources */,
|
||||
1D39342522F9D1C70097D2E8 /* EVDigitalProcessing.cpp in Sources */,
|
||||
1DCD2FA822EB63EF0007F762 /* main.cpp in Sources */,
|
||||
|
@ -1,5 +1,104 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Bucket
|
||||
uuid = "BFC3C049-56A3-4459-B3BA-244C1FDEBD58"
|
||||
type = "1"
|
||||
version = "2.0">
|
||||
<Breakpoints>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "19599F2C-170A-4ADD-A4BC-0243A453DB10"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "Scope/EVLibrary.h"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "44"
|
||||
endingLineNumber = "44"
|
||||
landmarkName = "EVException"
|
||||
landmarkType = "3">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "2D420DF8-E3AD-48F3-86AF-7914D052CCB5"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "Scope/EVSuperSpeedFIFIOBridge.cpp"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "36"
|
||||
endingLineNumber = "36"
|
||||
landmarkName = "InitFTDISuperSpeedChip(deviceHandle)"
|
||||
landmarkType = "9">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "D360ED92-A6A2-4C7D-8604-F01C944411AC"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "Scope/EVDigitalProcessing.cpp"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "24"
|
||||
endingLineNumber = "24"
|
||||
landmarkName = "DigitalProcessor::Test()"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "C67344C1-3F45-478B-9EB5-3908ED0A9446"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "Scope/EVDigitalProcessing.cpp"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "30"
|
||||
endingLineNumber = "30"
|
||||
landmarkName = "DigitalProcessor::Test()"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "75C903E8-832B-4A1C-8BC2-7BF3E8ECC34C"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "Scope/EVLibrary.cpp"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "99"
|
||||
endingLineNumber = "99"
|
||||
landmarkName = "EVSharedCache::PartialSetWriteCache(buff, idx, size)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "FA5FE044-1CE8-4A08-9EF9-8E3F54A66150"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "Scope/main.cpp"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "47"
|
||||
endingLineNumber = "47"
|
||||
landmarkName = "main(argc, argv)"
|
||||
landmarkType = "9">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
|
@ -6,13 +6,104 @@
|
||||
// Copyright © 2019 EEVengers. All rights reserved.
|
||||
//
|
||||
|
||||
/*
|
||||
Class that runs all data transfers.
|
||||
From FTDI Chip -> DigitalProccesing
|
||||
From DigitalProcessing -> Electron App
|
||||
*/
|
||||
|
||||
#include "EVDataTransferThread.hpp"
|
||||
#include "EVSuperSpeedFIFIOBridge.hpp"
|
||||
|
||||
DataTransferHandler::DataTransferHandler()
|
||||
{
|
||||
try {
|
||||
|
||||
void SuperSpeedFIFOBridgeHandler(FT_HANDLE SuperSpeedFIFOBridgeHandle, UCHAR buffers[NUM_FTDI_DATA_BUFFERS][FTDI_DATA_BUFFER_SZIE]) {
|
||||
|
||||
while(!programClosing) {
|
||||
superSpeedFIFOBridgeHandle = 0;
|
||||
|
||||
dataBuffer = (unsigned char*) malloc(sizeof(unsigned char*) * FTDI_DATA_BUFFER_SIZE);
|
||||
if(dataBuffer == nullptr) throw EVException(EVErrorCodeMallocFailed,"DataTransferHandler:Constructor");
|
||||
|
||||
CopyFunc = [](unsigned char* buff, unsigned int& idx, unsigned int size, void* obj){ return; };
|
||||
|
||||
} catch (EVException e) {
|
||||
std::cout << "DataTransferHandler:Constructor - " << e.what <<std::endl;
|
||||
assert(false);
|
||||
} catch (std::exception e) {
|
||||
std::cout << "DataTransferHandler:Constructor - " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DataTransferHandler::FTDITransferThread(DataTransferHandler* handler)
|
||||
{
|
||||
unsigned int bytesRead;
|
||||
unsigned int idx = 0;
|
||||
while(!handler->closeFTDIDataTransferThread) {
|
||||
//read a chunck from the FTDI chip
|
||||
handler->lock.lock();
|
||||
auto errorCode = FT_ReadPipe(handler->superSpeedFIFOBridgeHandle,FTDI_FLAG_READ_CHIP_TO_COMPUTER,handler->dataBuffer,FTDI_DATA_BUFFER_SIZE,&bytesRead,nullptr);
|
||||
if(errorCode != 0 || bytesRead != FTDI_DATA_BUFFER_SIZE) throw EVException(errorCode,"DataTransferHandler:FTDITransferThread:FT_ReadPipe()");
|
||||
//transfer chunck to shared cache
|
||||
handler->CopyFunc(handler->dataBuffer, idx, bytesRead, (void*)handler);
|
||||
handler->lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void DataTransferHandler::StartFTDITransferThread()
|
||||
{
|
||||
if(superSpeedFIFOBridgeHandle != 0) {
|
||||
throw EVException(EVErrorCodeServiceAlreadyRunning,"DataTransferHandler:StartFTDITransferThread");
|
||||
}
|
||||
try {
|
||||
InitFTDISuperSpeedChip(&superSpeedFIFOBridgeHandle);
|
||||
} catch (EVException e) {
|
||||
std::cout << "EV Exceptiom Caught: " << e.what << std::endl;
|
||||
assert(false);
|
||||
return;
|
||||
} catch (std::exception e) {
|
||||
assert(false);
|
||||
std::cout << "Standard Exception Caught" << e.what() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
closeFTDIDataTransferThread = false;
|
||||
superSpeedFTDITransferThread = std::thread(DataTransferHandler::FTDITransferThread,this);
|
||||
}
|
||||
|
||||
void DataTransferHandler::SetCopyFunc(CopyFuncs Func) {
|
||||
lock.lock();
|
||||
switch(Func) {
|
||||
case digitalProcessorFunc:
|
||||
CopyFunc = [](unsigned char* buff, unsigned int &idx, unsigned int size, void* obj)
|
||||
{ ((DataTransferHandler*)obj)->processingThreadSharedCache->PartialSetWriteCache(buff, idx, size); };
|
||||
break;
|
||||
default:
|
||||
throw EVException(EVErrorCodeInvalidValue,"DataTransferHandler::SetCopyFunc()");
|
||||
break;
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
DataTransferHandler::~DataTransferHandler()
|
||||
{
|
||||
if(superSpeedFTDITransferThread.joinable())
|
||||
{
|
||||
closeFTDIDataTransferThread = true;
|
||||
superSpeedFTDITransferThread.join();
|
||||
}
|
||||
if(digitalProcessingTransferThread.joinable())
|
||||
{
|
||||
closeDigitalProcessingTransferThread = true;
|
||||
digitalProcessingTransferThread.join();
|
||||
}
|
||||
if(electronTransferThread.joinable())
|
||||
{
|
||||
closeElectronTransferThread = true;
|
||||
electronTransferThread.join();
|
||||
}
|
||||
if(superSpeedFIFOBridgeHandle != 0)
|
||||
{
|
||||
FT_Close(superSpeedFIFOBridgeHandle);
|
||||
}
|
||||
}
|
||||
|
@ -11,14 +11,52 @@
|
||||
|
||||
#include "EVLibrary.h"
|
||||
|
||||
enum CopyFuncs
|
||||
{
|
||||
digitalProcessorFunc
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
* @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
|
||||
Container class that encapsulates all data transfers that occur in this program.
|
||||
FTDIChip -> DataHandler
|
||||
DataHandler -> DigitalProcessingHandler
|
||||
DigitalProcessingHandler -> Electron app
|
||||
*/
|
||||
void SuperSpeedFIFOBridgeHandler(FT_HANDLE SuperSpeedFIFOBridgeHandle, UCHAR buffers[NUM_FTDI_DATA_BUFFERS][FTDI_DATA_BUFFER_SZIE]);
|
||||
class DataTransferHandler
|
||||
{
|
||||
public:
|
||||
|
||||
DataTransferHandler();
|
||||
|
||||
void StartFTDITransferThread();
|
||||
void SetFTDITransferCopyFunction();
|
||||
void SetCopyFunc(CopyFuncs Func);
|
||||
|
||||
EVSharedCache* processingThreadSharedCache;
|
||||
|
||||
~DataTransferHandler();
|
||||
|
||||
private:
|
||||
|
||||
static void FTDITransferThread(DataTransferHandler* handler);
|
||||
|
||||
FT_HANDLE superSpeedFIFOBridgeHandle;
|
||||
|
||||
void (*CopyFunc)(unsigned char* buff, unsigned int& idx, unsigned int size, void* obj);
|
||||
|
||||
unsigned char* dataBuffer;
|
||||
|
||||
bool closeFTDIDataTransferThread;
|
||||
bool closeDigitalProcessingTransferThread;
|
||||
bool closeElectronTransferThread;
|
||||
std::thread superSpeedFTDITransferThread;
|
||||
std::thread digitalProcessingTransferThread;
|
||||
std::thread electronTransferThread;
|
||||
|
||||
|
||||
protected:
|
||||
std::mutex lock;
|
||||
|
||||
};
|
||||
|
||||
#endif /* EVDataTransferThread_hpp */
|
||||
|
@ -7,8 +7,46 @@
|
||||
//
|
||||
|
||||
#include "EVDigitalProcessing.hpp"
|
||||
#include <fstream>
|
||||
|
||||
|
||||
void DigitalProcessingMain() {
|
||||
|
||||
DigitalProcessor::DigitalProcessor()
|
||||
{
|
||||
cache = new EVSharedCache(DIGITAL_PROCESSING_BUFFER_SIZE,DIGITAL_PROCESSING_BUFFER_NUM);
|
||||
}
|
||||
|
||||
void DigitalProcessor::Test()
|
||||
{
|
||||
unsigned char* buff = (unsigned char*)malloc(sizeof(unsigned char) * DIGITAL_PROCESSING_BUFFER_SIZE);
|
||||
unsigned char* totalBuff = (unsigned char*)malloc(sizeof(unsigned char) * DIGITAL_PROCESSING_BUFFER_SIZE * 8);
|
||||
unsigned int size = 0;
|
||||
for(int i = 0; i < 8; i++) {
|
||||
//wait until there is new data
|
||||
while(cache->CopyReadCache(buff, DIGITAL_PROCESSING_BUFFER_SIZE))
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(100));
|
||||
};
|
||||
memcpy(totalBuff + size,buff,DIGITAL_PROCESSING_BUFFER_SIZE);
|
||||
size += DIGITAL_PROCESSING_BUFFER_SIZE;
|
||||
}
|
||||
//write to file
|
||||
WriteToCSV(totalBuff, size, "Board Data.csv");
|
||||
free(buff);
|
||||
}
|
||||
|
||||
void DigitalProcessor::WriteToCSV(const unsigned char* buff, const unsigned int size, const char* filename) {
|
||||
std::fstream fs;
|
||||
fs.open(filename, std::fstream::in | std::fstream::app);
|
||||
//print each byte data in its own coloumn, 4 coloumns per row
|
||||
for(unsigned int i = 0; i < size - 3; i += 4) {
|
||||
fs << i << "," << (int)buff[i] << "," << (int)buff[i + 1]
|
||||
<< "," << (int)buff[i + 2] << "," << (int)buff[i + 3] << std::endl;
|
||||
}
|
||||
fs << std::endl;
|
||||
fs.close();
|
||||
}
|
||||
|
||||
DigitalProcessor::~DigitalProcessor() {
|
||||
if(cache != nullptr) {
|
||||
delete cache;
|
||||
}
|
||||
}
|
||||
|
@ -11,12 +11,24 @@
|
||||
|
||||
#include "EVLibrary.h"
|
||||
|
||||
/*
|
||||
* Digital Proccessing Main That Deals With all triggering and wave functions
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
void DigitalProcessingMain();
|
||||
class DigitalProcessor
|
||||
{
|
||||
public:
|
||||
DigitalProcessor();
|
||||
|
||||
void Test();
|
||||
EVSharedCache* cache;
|
||||
|
||||
~DigitalProcessor();
|
||||
|
||||
private:
|
||||
|
||||
void WriteToCSV(const unsigned char* buff, const unsigned int size, const char* filename);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* EVDigitalProcessing_hpp */
|
||||
|
152
DSO_Software/Xcode_Project/Scope/Scope/EVLibrary.cpp
Normal file
152
DSO_Software/Xcode_Project/Scope/Scope/EVLibrary.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
//
|
||||
// EVLibrary.cpp
|
||||
// Scope
|
||||
//
|
||||
// Created by Daniel Vasile on 2019-10-24.
|
||||
// Copyright © 2019 EEVengers. All rights reserved.
|
||||
//
|
||||
|
||||
#include "EVLibrary.h"
|
||||
|
||||
//global variable declerations
|
||||
volatile bool programClosing;
|
||||
std::mutex dataProcessingBufferLock;
|
||||
EVLogger logger;
|
||||
|
||||
//global classes defenitions
|
||||
|
||||
//---------------EVException---------------
|
||||
EVException::EVException(int errorCode, const char* subSystem)
|
||||
{
|
||||
std::string exceptionText = "Exception with error code - ";
|
||||
exceptionText += std::to_string(errorCode);
|
||||
exceptionText += " - from SubSystem: ";
|
||||
exceptionText += std::string(subSystem);
|
||||
|
||||
what = exceptionText.c_str();
|
||||
}
|
||||
|
||||
//---------------EVLogger---------------
|
||||
std::mutex EVLogger::lock;
|
||||
|
||||
void EVLogger::debug(const char* message)
|
||||
{
|
||||
lock.lock();
|
||||
std::cout << message << std::endl;
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
void EVLogger::error(const char* message)
|
||||
{
|
||||
lock.lock();
|
||||
std::cout << message << std::endl;
|
||||
lock.unlock();
|
||||
|
||||
}
|
||||
|
||||
void EVLogger::warning(const char* message)
|
||||
{
|
||||
lock.lock();
|
||||
std::cout << message << std::endl;
|
||||
lock.unlock();
|
||||
|
||||
}
|
||||
|
||||
void EVLogger::critical(const char* message)
|
||||
{
|
||||
lock.lock();
|
||||
std::cout << message << std::endl;
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
//---------------EVSharecCache---------------
|
||||
|
||||
EVSharedCache::EVSharedCache(unsigned int cacheSize, unsigned int numCaches)
|
||||
{
|
||||
if(cacheSize == 0 || numCaches < 2) throw EVException(EVErrorCodeInvalidValue,"EVSharedCache::Constructor");
|
||||
|
||||
this->numCaches = numCaches;
|
||||
this->cacheSize = cacheSize;
|
||||
caches = (unsigned char**)malloc(sizeof(unsigned char**) * numCaches);
|
||||
for(int i = 0; i < numCaches; i++) {
|
||||
caches[i] = (unsigned char*)malloc(sizeof(unsigned char*) * cacheSize);
|
||||
}
|
||||
|
||||
this->readCache = 0;
|
||||
this->writeCache = 0;
|
||||
}
|
||||
|
||||
void EVSharedCache::SetWriteCache(const unsigned char* buff)
|
||||
{
|
||||
this->lock.lock();
|
||||
|
||||
//copy data
|
||||
for(int i = 0; i < cacheSize; i++)
|
||||
{
|
||||
caches[writeCache][i] = buff[i];
|
||||
}
|
||||
//set write cache to next cache
|
||||
if(writeCache == numCaches - 1){
|
||||
writeCache = 0;
|
||||
} else {
|
||||
writeCache++;
|
||||
}
|
||||
|
||||
this->lock.unlock();
|
||||
}
|
||||
|
||||
void EVSharedCache::PartialSetWriteCache(const unsigned char* buff, unsigned int &idx, unsigned int size) {
|
||||
if(idx + size > cacheSize) throw EVException(EVErrorCodeInvalidValue,"EVSharedCache::PartialSetWriteCache()");
|
||||
|
||||
this->lock.lock();
|
||||
|
||||
for(int i = 0; i < size; i++) {
|
||||
caches[writeCache][idx + i] = buff[i];
|
||||
}
|
||||
idx += size;
|
||||
|
||||
//when this buffer is full
|
||||
if(idx == cacheSize) {
|
||||
//move onto next buffer
|
||||
if(writeCache == numCaches - 1) {
|
||||
writeCache = 0;
|
||||
} else {
|
||||
writeCache++;
|
||||
}
|
||||
//reset the idx
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
this->lock.unlock();
|
||||
}
|
||||
|
||||
int EVSharedCache::CopyReadCache(unsigned char* buff, unsigned int size)
|
||||
{
|
||||
//if there is no new data to return, exit function
|
||||
if(this->writeCache == this->readCache) return 1;
|
||||
if(this->cacheSize < size) throw EVException(EVErrorCodeInvalidValue,"EVSharedCache::CopyReadCache");
|
||||
|
||||
this->lock.lock();
|
||||
//copy data
|
||||
for(int i = 0; i < size; i++) {
|
||||
buff[i] = caches[readCache][i];
|
||||
}
|
||||
//advance to next cache
|
||||
if(readCache == numCaches - 1) {
|
||||
readCache = 0;
|
||||
} else {
|
||||
readCache++;
|
||||
}
|
||||
|
||||
this->lock.unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EVSharedCache::~EVSharedCache()
|
||||
{
|
||||
for(int i = 0; i < numCaches; i++) {
|
||||
free(caches[i]);
|
||||
}
|
||||
free(caches);
|
||||
}
|
@ -15,9 +15,80 @@
|
||||
#include "ftd3xx.h"
|
||||
#include <assert.h>
|
||||
|
||||
#define NUM_FTDI_DATA_BUFFERS (3)
|
||||
#define FTDI_DATA_BUFFER_SZIE (8 * 1024)
|
||||
#define FTDI_DATA_BUFFER_SIZE (2 * 1024 * 4) //8 smallest read size is 8KiBytes
|
||||
|
||||
#define DIGITAL_PROCESSING_BUFFER_NUM (3) //Have 3 cycling buffers
|
||||
#define DIGITAL_PROCESSING_BUFFER_SIZE (4 * FTDI_DATA_BUFFER_SIZE) //4 Mb chunks to be transfered to the DataProcessing Thread/Object
|
||||
|
||||
//Flags
|
||||
#define DATATRANSFERTHREAD_FLAG_PRINT_TO_FILE (1 << 1)
|
||||
#define DATATRANSFERTHREAD_FLAG_TREAT_CHANNELS_AS_ONE (1 << 2)
|
||||
|
||||
#define FTDI_FLAG_READ_CHIP_TO_COMPUTER (0x82)
|
||||
|
||||
//global enums
|
||||
enum EVErrorCodes
|
||||
{
|
||||
EVErrorCodeInvalidValue,
|
||||
EVErrorCodeMallocFailed,
|
||||
EVErrorCodeServiceAlreadyRunning
|
||||
};
|
||||
|
||||
//global classes
|
||||
class EVException: public std::exception
|
||||
{
|
||||
|
||||
public:
|
||||
const char* what;
|
||||
|
||||
EVException(int errorCode, const char* subSystem);
|
||||
};
|
||||
|
||||
class EVLogger
|
||||
{
|
||||
public:
|
||||
static std::mutex lock;
|
||||
static void debug(const char* message);
|
||||
static void error(const char* message);
|
||||
static void critical(const char* message);
|
||||
static void warning(const char* message);
|
||||
};
|
||||
|
||||
class EVSharedCache
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
EVSharedCache(unsigned int cacheSize, unsigned int numCaches);
|
||||
~EVSharedCache();
|
||||
|
||||
void SetWriteCache(const unsigned char* buff);
|
||||
void PartialSetWriteCache(const unsigned char* buff, unsigned int& idx, unsigned int size);
|
||||
int CopyReadCache(unsigned char* buff, unsigned int size);
|
||||
|
||||
private:
|
||||
std::mutex lock;
|
||||
unsigned char** caches;
|
||||
unsigned int cacheSize;
|
||||
unsigned int numCaches;
|
||||
|
||||
unsigned short writeCache;
|
||||
unsigned short readCache;
|
||||
};
|
||||
|
||||
class EVEvent
|
||||
{
|
||||
public:
|
||||
|
||||
EVEvent();
|
||||
|
||||
private:
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
//global variables
|
||||
extern volatile bool programClosing;
|
||||
extern EVLogger logger;
|
||||
|
||||
#endif /* EVLibrary_h */
|
||||
|
@ -12,10 +12,8 @@
|
||||
* 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) {
|
||||
void InitFTDISuperSpeedChip(FT_HANDLE *deviceHandle) {
|
||||
|
||||
FT_DEVICE_LIST_INFO_NODE deviceInfoList[1];
|
||||
DWORD numDevices;
|
||||
@ -23,30 +21,26 @@ int InitFTDISuperSpeedChip(FT_HANDLE *deviceHandle) {
|
||||
|
||||
//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;
|
||||
throw EVException(error,"EVSuperSpeedFIFOBRidge:InitFTDISuperSpeedChip:FT_CreateDeviceList()");
|
||||
}
|
||||
|
||||
if( numDevices == 0 ) {
|
||||
std::cout << "No FTDI SuperSpeed Devices Have Been Detected" << std::endl;
|
||||
return 1;
|
||||
error = EVErrorCodeInvalidValue;
|
||||
throw EVException(error,"EVSuperSpeedFIFOBRidge:InitFTDISuperSpeedChip");
|
||||
}
|
||||
|
||||
if(FT_OK != (error = FT_GetDeviceInfoList(deviceInfoList, &numDevices))) {
|
||||
std::cout << "Could Not Get Device Info List, Error: " << error << std::endl;
|
||||
return 1;
|
||||
throw EVException(error,"EVSuperSpeedFIFOBRidge:InitFTDISuperSpeedChip:FT_GetDeviceInfoList()");
|
||||
}
|
||||
|
||||
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;
|
||||
if(FT_OK != (error = FT_Create( (PVOID)(deviceInfoList[0].Description), (DWORD)FT_OPEN_BY_DESCRIPTION, deviceHandle))){
|
||||
throw EVException(error,"EVSuperSpeedFIFOBRidge:InitFTDISuperSpeedChip:FT_Create");
|
||||
}
|
||||
|
||||
//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;
|
||||
throw EVException(error,"EVSuperSpeedFIFOBRidge:InitFTDISuperSpeedChip:FT_GetChipConfiguration");
|
||||
}
|
||||
memcpy(&newConfig, &oldConfig, sizeof(FT_60XCONFIGURATION));
|
||||
newConfig.FIFOClock = CONFIGURATION_FIFO_CLK_100;
|
||||
@ -54,8 +48,7 @@ int InitFTDISuperSpeedChip(FT_HANDLE *deviceHandle) {
|
||||
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;
|
||||
throw new EVException(error,"EVSuperSpeedFIFOBRidge:InitFTDISuperSpeedChip:FT_SetChipConfiguration");
|
||||
}
|
||||
FT_Close(*deviceHandle);
|
||||
|
||||
@ -66,24 +59,20 @@ int InitFTDISuperSpeedChip(FT_HANDLE *deviceHandle) {
|
||||
*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;
|
||||
throw new EVException(error,"EVSuperSpeedFIFOBRidge:InitFTDISuperSpeedChip:FT_CreateDeviceInfoList");
|
||||
}
|
||||
|
||||
if( numDevices == 0 ) {
|
||||
std::cout << "No FTDI SuperSpeed Devices Have Been Detected After SuperSpeed FIFO Bridge Configuration" << std::endl;
|
||||
return 1;
|
||||
error = EVErrorCodeInvalidValue;
|
||||
throw new EVException(error,"EVSuperSpeedFIFOBRidge:InitFTDISuperSpeedChip");
|
||||
}
|
||||
|
||||
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;
|
||||
throw new EVException(error,"EVSuperSpeedFIFOBRidge:InitFTDISuperSpeedChip:FT_GetDeviceInfoList");
|
||||
}
|
||||
|
||||
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;
|
||||
throw new EVException(error,"EVSuperSpeedFIFOBRidge:InitFTDISuperSpeedChip:FT_Create");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
* @return
|
||||
* 0 on success
|
||||
*/
|
||||
int InitFTDISuperSpeedChip(FT_HANDLE *deviceHandle);
|
||||
void InitFTDISuperSpeedChip(FT_HANDLE *deviceHandle);
|
||||
|
||||
|
||||
|
||||
|
@ -13,32 +13,42 @@
|
||||
|
||||
#define FIFO_SUPER_SPEED_BRIDGE_NAME "FTDI SuperSpeed-FIFO Bridge"
|
||||
|
||||
volatile bool programClosing;
|
||||
DataTransferHandler* dataHandler;
|
||||
DigitalProcessor* digitalProcessor;
|
||||
|
||||
/* TODO Get Aleska His 4 channels to text file thingy */
|
||||
void run()
|
||||
{
|
||||
while(!programClosing){
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
logger.debug("Main:Run() - 1 second has passed");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FT_HANDLE superSuperFIFOBridgeHandle = 0;
|
||||
UCHAR dataBuffers[NUM_FTDI_DATA_BUFFERS][FTDI_DATA_BUFFER_SZIE];
|
||||
programClosing = false;
|
||||
//create classes -
|
||||
// DataTransferHandler gets data off of the board
|
||||
// DigitalProcessor currently prints to file, but will be responsible for triggering
|
||||
dataHandler = new DataTransferHandler();
|
||||
digitalProcessor = new DigitalProcessor();
|
||||
|
||||
// if(InitFTDISuperSpeedChip(&superSuperFIFOBridgeHandle)) {
|
||||
// std::cout << "Error Failed To Open Handle To FTDI SuperSpeed FIFO Buffer" << std::endl;
|
||||
// return 1;
|
||||
// }
|
||||
//share cache object
|
||||
dataHandler->processingThreadSharedCache = digitalProcessor->cache;
|
||||
|
||||
std::thread ftdiHandlerThread(SuperSpeedFIFOBridgeHandler,superSuperFIFOBridgeHandle,dataBuffers);
|
||||
std::thread digitalProcessingThread(DigitalProcessingMain);
|
||||
|
||||
programClosing = true;
|
||||
ftdiHandlerThread.join();
|
||||
std::cout << "Joined FTDI Thread" << std::endl;
|
||||
digitalProcessingThread.join();
|
||||
std::cout << "Joined Digital Processing Thread" << std::endl;
|
||||
|
||||
// FT_Close(superSuperFIFOBridgeHandle);
|
||||
//set the data handler to save data to the digitalprocessor's shared cache
|
||||
dataHandler->SetCopyFunc(digitalProcessorFunc);
|
||||
//start reading
|
||||
dataHandler->StartFTDITransferThread();
|
||||
|
||||
//Run test function which currently prints about 700kbytes of data to a csv file
|
||||
//It writes about 65,553 columns, and Numbers cant display more then 65,536
|
||||
//Output can be found in the same directory as the program.
|
||||
digitalProcessor->Test();
|
||||
|
||||
delete dataHandler;
|
||||
delete digitalProcessor;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user