diff --git a/Source/Processors/DataThreads/DataThread.cpp b/Source/Processors/DataThreads/DataThread.cpp index a3033780cdf8cd238a395c35c009adbd72cbb580..3e72496f40d34efbc6fbfbd1e072aa71c5f2015d 100755 --- a/Source/Processors/DataThreads/DataThread.cpp +++ b/Source/Processors/DataThreads/DataThread.cpp @@ -38,7 +38,7 @@ DataThread::~DataThread() void DataThread::run() { - while (! threadShouldExit()) + while (!threadShouldExit()) { if (!updateBuffer()) { diff --git a/Source/Processors/DataThreads/RHD2000Thread.cpp b/Source/Processors/DataThreads/RHD2000Thread.cpp index a6ea3ce8c2e0584c9581c438e3cae0a1ad341ae9..0219c018bc57849c28d25a8e56298b6f06b317ca 100644 --- a/Source/Processors/DataThreads/RHD2000Thread.cpp +++ b/Source/Processors/DataThreads/RHD2000Thread.cpp @@ -29,40 +29,70 @@ RHD2000Thread::RHD2000Thread(SourceNode* sn) : DataThread(sn) evalBoard = new Rhd2000EvalBoard; // Open Opal Kelly XEM6010 board. - evalBoard->open(); + int return_code = evalBoard->open(); - string bitfilename; - bitfilename = "rhd2000.bit"; - evalBoard->uploadFpgaBitfile(bitfilename); + if (return_code == 1) + { + deviceFound = true; + } else { + deviceFound = false; + } - // Initialize board. - evalBoard->initialize(); - evalBoard->setDataSource(0, Rhd2000EvalBoard::PortA1); + if (deviceFound) + { + string bitfilename; + bitfilename = "rhd2000.bit"; + evalBoard->uploadFpgaBitfile(bitfilename); - numChannels = 32; + // Initialize board. + evalBoard->initialize(); + evalBoard->setDataSource(0, Rhd2000EvalBoard::PortA1); + evalBoard->setContinuousRunMode(false); - // Select per-channel amplifier sampling rate. - evalBoard->setSampleRate(Rhd2000EvalBoard::SampleRate20000Hz); + numChannels = 32; - // Now that we have set our sampling rate, we can set the MISO sampling delay - // which is dependent on the sample rate. We assume a 3-foot cable. - evalBoard->setCableLengthFeet(Rhd2000EvalBoard::PortA, 3.0); + // Select per-channel amplifier sampling rate. + evalBoard->setSampleRate(Rhd2000EvalBoard::SampleRate10000Hz); - // Let's turn one LED on to indicate that the program is running. - int ledArray[8] = {1, 0, 0, 0, 0, 0, 0, 0}; - evalBoard->setLedDisplay(ledArray); + // Now that we have set our sampling rate, we can set the MISO sampling delay + // which is dependent on the sample rate. We assume a 3-foot cable. + evalBoard->setCableLengthFeet(Rhd2000EvalBoard::PortA, 3.0); -} + // Let's turn one LED on to indicate that the program is running. + int ledArray[8] = {1, 0, 0, 0, 0, 0, 0, 0}; + evalBoard->setLedDisplay(ledArray); + + // Set up an RHD2000 register object using this sample rate to optimize MUX-related + // register settings. + chipRegisters = new Rhd2000Registers(evalBoard->getSampleRate()); + + // Before generating register configuration command sequences, set amplifier + // bandwidth paramters. + double dspCutoffFreq; + dspCutoffFreq = chipRegisters->setDspCutoffFreq(10.0); + cout << "Actual DSP cutoff frequency: " << dspCutoffFreq << " Hz" << endl; + chipRegisters->setLowerBandwidth(1.0); + chipRegisters->setUpperBandwidth(7500.0); + + dataBlock = new Rhd2000DataBlock(evalBoard->getNumEnabledDataStreams()); + + dataBuffer = new DataBuffer(numChannels, 10000); + + + } + +} RHD2000Thread::~RHD2000Thread() { std::cout << "RHD2000 interface destroyed." << std::endl; - int ledArray[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - evalBoard->setLedDisplay(ledArray); - - deleteAndZero(evalBoard); + if (deviceFound) + { + int ledArray[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + evalBoard->setLedDisplay(ledArray); + } } @@ -79,7 +109,7 @@ int RHD2000Thread::getNumEventChannels() float RHD2000Thread::getSampleRate() { - return 28344.67; + return 10000.00; } float RHD2000Thread::getBitVolts() @@ -90,7 +120,7 @@ float RHD2000Thread::getBitVolts() bool RHD2000Thread::foundInputSource() { - return true; + return deviceFound; } @@ -99,8 +129,31 @@ bool RHD2000Thread::startAcquisition() //memset(filter_states,0,256*sizeof(double)); + int ledArray[8] = {1, 1, 0, 0, 0, 0, 0, 0}; + evalBoard->setLedDisplay(ledArray); + + cout << "Number of 16-bit words in FIFO: " << evalBoard->numWordsInFifo() << endl; + cout << "Is eval board running: " << evalBoard->isRunning() << endl; + + + // If this happens too soon after acquisition is stopped, problems ensue + std::cout << "Flushing FIFO." << std::endl; + evalBoard->flush(); + + + std::cout << "Setting max timestep." << std::endl; + evalBoard->setMaxTimeStep(100); + evalBoard->setContinuousRunMode(true); + + std::cout << "Starting acquisition." << std::endl; + evalBoard->run(); + + blockSize = dataBlock->calculateDataBlockSizeInWords(evalBoard->getNumEnabledDataStreams()); + + startThread(); + // isTransmitting = true; // accumulator = 0; @@ -111,17 +164,63 @@ bool RHD2000Thread::stopAcquisition() { // isTransmitting = false; + std::cout << "RHD2000 data thread stopping acquisition." << std::endl; if (isThreadRunning()) { signalThreadShouldExit(); } + evalBoard->setContinuousRunMode(false); + evalBoard->setMaxTimeStep(0); + + cout << "Number of 16-bit words in FIFO: " << evalBoard->numWordsInFifo() << endl; + + std::cout << "Stopped eval board." << std::endl; + + + int ledArray[8] = {1, 0, 0, 0, 0, 0, 0, 0}; + evalBoard->setLedDisplay(ledArray); + return true; } bool RHD2000Thread::updateBuffer() { - // data transfer and sorting code goes here + //cout << "Number of 16-bit words in FIFO: " << evalBoard->numWordsInFifo() << endl; + //cout << "Block size: " << blockSize << endl; + + bool return_code; + int lastBlock; + + for (int n = 0; n < 1; n++) + { + if (evalBoard->numWordsInFifo() >= blockSize) + { + + return_code = evalBoard->readDataBlock(dataBlock); + + for (int samp = 0; samp < dataBlock->getSamplesPerDataBlock(); samp++) + { + + for (int chan = 0; chan < numChannels; chan++) + { + + int value = dataBlock->amplifierData[0][chan][samp]; + + thisSample[chan] = double(value)*0.01; + } + + timestamp = dataBlock->timeStamp[samp]; + eventCode = dataBlock->ttlIn[samp]; + + dataBuffer->addToBuffer(thisSample, ×tamp, &eventCode, 1); + } + + } + } + + + return true; } \ No newline at end of file diff --git a/Source/Processors/DataThreads/RHD2000Thread.h b/Source/Processors/DataThreads/RHD2000Thread.h index 49fc92c5544055222d7d430dd78e8399d6c9bd77..4f0b9dc4cd0a3c9a81e05781fe54a107ed5f63ac 100644 --- a/Source/Processors/DataThreads/RHD2000Thread.h +++ b/Source/Processors/DataThreads/RHD2000Thread.h @@ -66,14 +66,18 @@ public: int getNumEventChannels(); - // void setOutputHigh(); - //void setOutputLow(); - private: - Rhd2000EvalBoard *evalBoard; + ScopedPointer<Rhd2000EvalBoard> evalBoard; + ScopedPointer<Rhd2000Registers> chipRegisters; + ScopedPointer<Rhd2000DataBlock> dataBlock; int numChannels; + bool deviceFound; + + float thisSample[256]; + + int blockSize; bool startAcquisition(); bool stopAcquisition(); diff --git a/Source/Processors/DataThreads/rhythm-api/rhd2000datablock.h b/Source/Processors/DataThreads/rhythm-api/rhd2000datablock.h index 8dd535233e01bfa79f74d5c42b7ad31793fe76b3..47337dde8b7358d418baf98434ed07a103fcfb4c 100755 --- a/Source/Processors/DataThreads/rhythm-api/rhd2000datablock.h +++ b/Source/Processors/DataThreads/rhythm-api/rhd2000datablock.h @@ -20,7 +20,7 @@ #ifndef RHD2000DATABLOCK_H #define RHD2000DATABLOCK_H -#define SAMPLES_PER_DATA_BLOCK 60 +#define SAMPLES_PER_DATA_BLOCK 200 #define RHD2000_HEADER_MAGIC_NUMBER 0xc691199927021942 using namespace std;