4747#define DEBUG_EMULATE_HEADSTAGES 8
4848#define DEBUG_EMULATE_64CH
4949
50+ #define INIT_STEP ( evalBoard->isUSB3 () ? 256 : 60)
51+
5052// Allocates memory for a 3-D array of doubles.
5153void allocateDoubleArray3D(std::vector<std::vector<std::vector<double > > >& array3D,
5254 int xSize, int ySize, int zSize)
@@ -88,6 +90,8 @@ RHD2000Thread::RHD2000Thread(SourceNode* sn) : DataThread(sn),
8890 newScan(true ), ledsEnabled(true )
8991{
9092 impedanceThread = new RHDImpedanceMeasure (this );
93+ memset (auxBuffer, 0 , sizeof (auxBuffer));
94+ memset (auxSamples, 0 , sizeof (auxSamples));
9195
9296 for (int i=0 ; i < MAX_NUM_HEADSTAGES; i++)
9397 headstagesArray.add (new RHDHeadstage (static_cast <Rhd2000EvalBoard::BoardDataSource>(i)));
@@ -389,7 +393,7 @@ void RHD2000Thread::initializeBoard()
389393
390394 // Since our longest command sequence is 60 commands, run the SPI interface for
391395 // 60 samples (64 for usb3 power-of two needs)
392- evalBoard->setMaxTimeStep (64 );
396+ evalBoard->setMaxTimeStep (INIT_STEP );
393397 evalBoard->setContinuousRunMode (false );
394398
395399 // Start SPI interface
@@ -405,8 +409,7 @@ void RHD2000Thread::initializeBoard()
405409 // need to do anything with this, since it was only used for ADC calibration
406410 ScopedPointer<Rhd2000DataBlock> dataBlock = new Rhd2000DataBlock (evalBoard->getNumEnabledDataStreams (), evalBoard->isUSB3 ());
407411
408- evalBoard->readDataBlock (dataBlock, 64 );
409-
412+ evalBoard->readDataBlock (dataBlock, INIT_STEP);
410413 // Now that ADC calibration has been performed, we switch to the command sequence
411414 // that does not execute ADC calibration.
412415 evalBoard->selectAuxCommandBank (Rhd2000EvalBoard::PortA, Rhd2000EvalBoard::AuxCmd3,
@@ -508,7 +511,7 @@ void RHD2000Thread::scanPorts()
508511
509512 // Since our longest command sequence is 60 commands, we run the SPI
510513 // interface for 60 samples. (64 for usb3 power-of two needs)
511- evalBoard->setMaxTimeStep (64 );
514+ evalBoard->setMaxTimeStep (INIT_STEP );
512515 evalBoard->setContinuousRunMode (false );
513516
514517 ScopedPointer<Rhd2000DataBlock> dataBlock =
@@ -545,7 +548,7 @@ void RHD2000Thread::scanPorts()
545548 ;
546549 }
547550 // Read the resulting single data block from the USB interface.
548- evalBoard->readDataBlock (dataBlock, 64 );
551+ evalBoard->readDataBlock (dataBlock, INIT_STEP );
549552
550553 // Read the Intan chip ID number from each RHD2000 chip found.
551554 // Record delay settings that yield good communication with the chip.
@@ -1413,12 +1416,14 @@ bool RHD2000Thread::startAcquisition()
14131416 std::cout << " Flushing FIFO." << std::endl;
14141417 evalBoard->flush ();
14151418 evalBoard->setContinuousRunMode (true );
1419+ evalBoard->printFIFOmetrics ();
14161420 evalBoard->run ();
1421+ evalBoard->printFIFOmetrics ();
14171422 }
14181423
14191424 blockSize = dataBlock->calculateDataBlockSizeInWords (evalBoard->getNumEnabledDataStreams (), evalBoard->isUSB3 ());
14201425 std::cout << " Expecting blocksize of " << blockSize << " for " << evalBoard->getNumEnabledDataStreams () << " streams" << std::endl;
1421-
1426+ evalBoard-> printFIFOmetrics ();
14221427 startThread ();
14231428
14241429
@@ -1481,19 +1486,102 @@ bool RHD2000Thread::stopAcquisition()
14811486bool RHD2000Thread::updateBuffer ()
14821487{
14831488 int chOffset;
1489+ unsigned char * bufferPtr;
14841490 // cout << "Number of 16-bit words in FIFO: " << evalBoard->numWordsInFifo() << endl;
14851491 // cout << "Block size: " << blockSize << endl;
1486-
1487- bool return_code;
1492+
14881493 // std::cout << "Current number of words: " << evalBoard->numWordsInFifo() << " for " << blockSize << std::endl;
1489- if (evalBoard->numWordsInFifo () >= 189440 )
1494+ if (evalBoard->isUSB3 () || evalBoard-> numWordsInFifo () >= blockSize )
14901495 {
1491- return_code = evalBoard->readDataBlock (dataBlock);
1496+ bool return_code;
1497+
1498+ return_code = evalBoard->readRawDataBlock (&bufferPtr);
14921499
1493- for (int samp = 0 ; samp < dataBlock->getSamplesPerDataBlock (evalBoard->isUSB3 ()); samp++)
1500+ int index = 0 ;
1501+ int auxIndex, chanIndex;
1502+ int numStreams = enabledStreams.size ();
1503+ int nSamps = Rhd2000DataBlock::getSamplesPerDataBlock (evalBoard->isUSB3 ());
1504+
1505+ evalBoard->printFIFOmetrics ();
1506+ for (int samp = 0 ; samp < nSamps; samp++)
14941507 {
14951508 int channel = -1 ;
14961509
1510+ if (!Rhd2000DataBlock::checkUsbHeader (bufferPtr, index))
1511+ {
1512+ cerr << " Error in Rhd2000EvalBoard::readDataBlock: Incorrect header." << endl;
1513+ break ;
1514+ }
1515+
1516+ index += 8 ;
1517+ timestamp = Rhd2000DataBlock::convertUsbTimeStamp (bufferPtr,index);
1518+ index += 4 ;
1519+ auxIndex = index;
1520+ // skip the aux channels
1521+ index += numStreams * 6 ;
1522+ // do the neural data channels first
1523+ for (int dataStream = 0 ; dataStream < numStreams; dataStream++)
1524+ {
1525+ int nChans = numChannelsPerDataStream[dataStream];
1526+ chanIndex = index + 2 *dataStream;
1527+ if ((chipId[dataStream] == CHIP_ID_RHD2132) && (nChans == 16 )) // RHD2132 16ch. headstage
1528+ {
1529+ chanIndex += 2 * RHD2132_16CH_OFFSET*numStreams;
1530+ }
1531+ for (int chan = 0 ; chan < nChans; chan++)
1532+ {
1533+ channel++;
1534+ thisSample[channel] = float (Rhd2000DataBlock::convertUsbWord (bufferPtr, index) - 32768 )*0 .195f ;
1535+ chanIndex += 2 *numStreams;
1536+ }
1537+ }
1538+ index += 64 * numStreams;
1539+ // now we can do the aux channels
1540+ auxIndex += 2 *numStreams;
1541+ for (int dataStream = 0 ; dataStream < numStreams; dataStream++)
1542+ {
1543+ if (chipId[dataStream] != CHIP_ID_RHD2164_B)
1544+ {
1545+ int auxNum = (samp+3 ) % 4 ;
1546+ if (auxNum < 3 )
1547+ {
1548+ auxSamples[dataStream][auxNum] = float (Rhd2000DataBlock::convertUsbWord (bufferPtr, auxIndex) - 32768 )*0.0000374 ;
1549+ }
1550+ for (int chan = 0 ; chan < 3 ; chan++)
1551+ {
1552+ channel++;
1553+ if (auxNum == 3 )
1554+ {
1555+ auxBuffer[channel] = auxSamples[dataStream][chan];
1556+ }
1557+ thisSample[channel] = auxBuffer[channel];
1558+ }
1559+ }
1560+ auxIndex += 2 ;
1561+
1562+ }
1563+ index += 2 * numStreams;
1564+ if (acquireAdcChannels)
1565+ {
1566+ for (int adcChan = 0 ; adcChan < 8 ; ++adcChan)
1567+ {
1568+
1569+ channel++;
1570+ // ADC waveform units = volts
1571+ thisSample[channel] =
1572+ // 0.000050354 * float(dataBlock->boardAdcData[adcChan][samp]);
1573+ 0.00015258789 * float (Rhd2000DataBlock::convertUsbWord (bufferPtr, index)) - 5 - 0.4096 ; // account for +/-5V input range and DC offset
1574+ index += 2 ;
1575+ }
1576+ }
1577+ else
1578+ {
1579+ index += 16 ;
1580+ }
1581+ eventCode = Rhd2000DataBlock::convertUsbWord (bufferPtr, index);
1582+ index += 4 ;
1583+ dataBuffer->addToBuffer (thisSample, ×tamp, &eventCode, 1 );
1584+ #if 0
14971585 // do the neural data channels first
14981586 for (int dataStream = 0; dataStream < enabledStreams.size(); dataStream++)
14991587 {
@@ -1584,14 +1672,13 @@ bool RHD2000Thread::updateBuffer()
15841672 timestamp = dataBlock->timeStamp[samp];
15851673 //timestamp = timestamp;
15861674 eventCode = dataBlock->ttlIn[samp];
1587-
15881675 dataBuffer->addToBuffer(thisSample, ×tamp, &eventCode, 1);
1589-
1676+ # endif
15901677 }
15911678
15921679 }
15931680
1594-
1681+
15951682 if (dacOutputShouldChange)
15961683 {
15971684 std::cout << " DAC" << std::endl;
@@ -1624,8 +1711,7 @@ bool RHD2000Thread::updateBuffer()
16241711
16251712 dacOutputShouldChange = false ;
16261713 }
1627-
1628-
1714+
16291715 return true ;
16301716
16311717}
0 commit comments