From 10c6cd7403d2a5761cc6508c1a2fc8a1a5c1735a Mon Sep 17 00:00:00 2001
From: Aaron Cuevas Lopez <aacuelo@teleco.upv.es>
Date: Mon, 2 May 2016 19:11:42 +0200
Subject: [PATCH] Add 1-sample threshold output and overflow checks

---
 Source/Plugins/PCIeRhythm/RHD2000Thread.cpp   | 42 +++++++++++++++----
 Source/Plugins/PCIeRhythm/RHD2000Thread.h     |  4 ++
 .../PCIeRhythm/rhythm-api/rhd2000PCIe.cpp     | 31 ++++++++++++--
 .../PCIeRhythm/rhythm-api/rhd2000PCIe.h       |  3 ++
 .../PCIeRhythm/rhythm-api/rhd2000datablock.h  |  2 +-
 5 files changed, 68 insertions(+), 14 deletions(-)

diff --git a/Source/Plugins/PCIeRhythm/RHD2000Thread.cpp b/Source/Plugins/PCIeRhythm/RHD2000Thread.cpp
index 827d816bf..d4ec664c9 100644
--- a/Source/Plugins/PCIeRhythm/RHD2000Thread.cpp
+++ b/Source/Plugins/PCIeRhythm/RHD2000Thread.cpp
@@ -44,6 +44,8 @@
 #define REGISTER_59_MISO_B  58
 #define RHD2132_16CH_OFFSET 8
 
+#define THRESHOLD_CHECK 1.0f
+
 //#define DEBUG_EMULATE_HEADSTAGES 8
 //#define DEBUG_EMULATE_64CH
 //#define DEBUG_REAL_HEADSTAGE 5
@@ -1304,7 +1306,7 @@ bool RHD2000Thread::startAcquisition()
     dataBlock = new Rhd2000DataBlock(evalBoard->getNumEnabledDataStreams());
 
     std::cout << "Expecting " << getNumChannels() << " channels." << std::endl;
-
+	lastThreshold = false;
     //memset(filter_states,0,256*sizeof(double));
 
     /*int ledArray[8] = {1, 1, 0, 0, 0, 0, 0, 0};
@@ -1354,14 +1356,17 @@ bool RHD2000Thread::stopAcquisition()
 
     }
 
-    if (waitForThreadToExit(500))
-    {
-        std::cout << "Thread exited." << std::endl;
-    }
-    else
-    {
-        std::cout << "Thread failed to exit, continuing anyway..." << std::endl;
-    }
+	if (getThreadId() != getCurrentThreadId())
+	{
+		if (waitForThreadToExit(500))
+		{
+			std::cout << "Thread exited." << std::endl;
+		}
+		else
+		{
+			std::cout << "Thread failed to exit, continuing anyway..." << std::endl;
+		}
+	}
 
     if (deviceFound)
     {
@@ -1406,6 +1411,12 @@ bool RHD2000Thread::updateBuffer()
 		bool return_code;
 
 		return_code = evalBoard->readRawDataBlock(&bufferPtr);
+		if (!return_code)
+		{
+			MessageManagerLock lockM;
+			CoreServices::setAcquisitionStatus(false);
+			return true;
+		}
 
 		int index = 0;
 		int auxIndex, chanIndex;
@@ -1443,6 +1454,8 @@ bool RHD2000Thread::updateBuffer()
 					channel++;
 					thisSample[channel] = float(*(uint16*)(bufferPtr + chanIndex) - 32768)*0.195f;
 					chanIndex += 2*numStreams;
+					if (dataStream == 0 && chan == 0) //First channel of the first enabled stream
+						checkThreshold(thisSample[channel]);
 				}
 			}
 			index += 64 * numStreams;
@@ -1627,6 +1640,17 @@ bool RHD2000Thread::updateBuffer()
 
 }
 
+void RHD2000Thread::checkThreshold(float s)
+{
+	bool check = (s > THRESHOLD_CHECK);
+	if (!check != !lastThreshold)
+	{
+		//std::cout << "SIG" << std::endl;
+		lastThreshold = check;
+		evalBoard->setOuputSigs(check ? 0x0001 : 0x0000);
+	}
+}
+
 int RHD2000Thread::getChannelFromHeadstage(int hs, int ch)
 {
     int channelCount = 0;
diff --git a/Source/Plugins/PCIeRhythm/RHD2000Thread.h b/Source/Plugins/PCIeRhythm/RHD2000Thread.h
index 66fe3a216..18d4bc998 100644
--- a/Source/Plugins/PCIeRhythm/RHD2000Thread.h
+++ b/Source/Plugins/PCIeRhythm/RHD2000Thread.h
@@ -207,6 +207,10 @@ namespace PCIeRhythm {
 		ScopedPointer<RHDImpedanceMeasure> impedanceThread;
 		bool ledsEnabled;
 
+		bool lastThreshold;
+
+		void checkThreshold(float s);
+
 		// Sync ouput divide factor
 		uint16 clockDivideFactor;
 
diff --git a/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.cpp b/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.cpp
index bd898d827..87f3544cb 100644
--- a/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.cpp
+++ b/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.cpp
@@ -897,9 +897,15 @@ bool rhd2000PCIe::readRawDataBlock(unsigned char** bufferPtr, int nSamples)
 	do {
 		int nr = Read(fidFIFO, dataBuffer, numBytesToRead);
 
-		if (nr < 0)
+		if (nr == 0)
+		{
+			std::cout << "DMA buffer overflow. Stop acquisition" << std::endl;
+			return false;
+		}
+		else if (nr < 0)
 		{
 			std::cerr << "Error reading from pipe" << std::endl;
+			return false;
 		}
 		numread += nr;
 	} while (numread < numBytesToRead);
@@ -938,10 +944,15 @@ bool rhd2000PCIe::readDataBlock(Rhd2000DataBlock *dataBlock, int nSamples)
 	do {
 		int nr = Read(fidFIFO, dataBuffer, numBytesToRead);
 
-		if (nr < 0)
+		if (nr == 0)
+		{
+			std::cout << "DMA buffer overflow. Stop acquisition" << std::endl;
+			return false;
+		}
+		else if (nr < 0)
 		{
 			std::cerr << "Error reading from pipe" << std::endl;
-			break;
+			return false;
 		}
 		numread += nr;
 	} while (numread < numBytesToRead);
@@ -977,9 +988,16 @@ bool rhd2000PCIe::readDataBlocks(int numBlocks, queue<Rhd2000DataBlock> &dataQue
 	do {
 		int nr = Read(fidFIFO, dataBuffer, numBytesToRead);
 
-		if (nr < 0)
+		if (nr == 0)
+		{
+			std::cout << "DMA buffer overflow. Stop acquisition" << std::endl;
+			return false;
+
+		}
+		else if (nr < 0)
 		{
 			std::cerr << "Error reading from pipe" << std::endl;
+			return false;
 		}
 		numread += nr;
 	} while (numread < numBytesToRead);
@@ -992,4 +1010,9 @@ bool rhd2000PCIe::readDataBlocks(int numBlocks, queue<Rhd2000DataBlock> &dataQue
 	delete dataBlock;
 
 	return true;
+}
+
+void rhd2000PCIe::setOuputSigs(int sigs)
+{
+	writeRegister(AuxOutputs, sigs);
 }
\ No newline at end of file
diff --git a/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.h b/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.h
index 255f2554d..a37fddcfa 100644
--- a/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.h
+++ b/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.h
@@ -112,6 +112,8 @@ namespace PCIeRhythm {
 		bool openPipe();
 		void closePipe();
 
+		void setOuputSigs(int sigs);
+
 		//void flush();
 
 
@@ -138,6 +140,7 @@ namespace PCIeRhythm {
 			DataStreamSel9ABC = 0x28,
 			DataStreamSelDEF10 = 0x2A,
 			DataStreamEn = 0x2C,
+			AuxOutputs = 0x2E,
 			StartTrigger = 0x3E
 		};
 		enum statusAddr {
diff --git a/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000datablock.h b/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000datablock.h
index d4aff22f4..67ab19735 100644
--- a/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000datablock.h
+++ b/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000datablock.h
@@ -21,7 +21,7 @@
 #ifndef RHD2000DATABLOCK_H
 #define RHD2000DATABLOCK_H
 
-#define SAMPLES_PER_DATA_BLOCK_PCIE 16
+#define SAMPLES_PER_DATA_BLOCK_PCIE 1
 #define RHD2000_HEADER_MAGIC_NUMBER 0xc691199927021942
 
 using namespace std;
-- 
GitLab