Skip to content

Commit 09d9496

Browse files
committed
Fix buffer overrun issue
1 parent 9957e3c commit 09d9496

4 files changed

Lines changed: 184 additions & 168 deletions

File tree

Source/Processors/DataThreads/RHD2000Thread.cpp

Lines changed: 176 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@
4444
#define REGISTER_59_MISO_B 58
4545
#define RHD2132_16CH_OFFSET 8
4646

47+
#define DEBUG_EMULATE_HEADSTAGES 8
48+
#define DEBUG_EMULATE_64CH
49+
4750
// Allocates memory for a 3-D array of doubles.
4851
void allocateDoubleArray3D(std::vector<std::vector<std::vector<double> > >& array3D,
4952
int xSize, int ySize, int zSize)
@@ -426,173 +429,184 @@ void RHD2000Thread::initializeBoard()
426429

427430
void RHD2000Thread::scanPorts()
428431
{
429-
if (!deviceFound) //Safety to avoid crashes if board not present
430-
{
431-
return;
432-
}
432+
if (!deviceFound) //Safety to avoid crashes if board not present
433+
{
434+
return;
435+
}
433436

434437
impedanceThread->stopThreadSafely();
435-
//Clear previous known streams
436-
enabledStreams.clear();
437-
438-
// Scan SPI ports
439-
440-
int delay, hs, id;
441-
int register59Value;
442-
//int numChannelsOnPort[4] = {0, 0, 0, 0};
443-
Rhd2000EvalBoard::BoardDataSource initStreamPorts[8] =
444-
{
445-
Rhd2000EvalBoard::PortA1,
446-
Rhd2000EvalBoard::PortA2,
447-
Rhd2000EvalBoard::PortB1,
448-
Rhd2000EvalBoard::PortB2,
449-
Rhd2000EvalBoard::PortC1,
450-
Rhd2000EvalBoard::PortC2,
451-
Rhd2000EvalBoard::PortD1,
452-
Rhd2000EvalBoard::PortD2
453-
};
454-
455-
/*
456-
Rhd2000EvalBoard::BoardDataSource initStreamDdrPorts[8] =
457-
{
458-
Rhd2000EvalBoard::PortA1Ddr,
459-
Rhd2000EvalBoard::PortA2Ddr,
460-
Rhd2000EvalBoard::PortB1Ddr,
461-
Rhd2000EvalBoard::PortB2Ddr,
462-
Rhd2000EvalBoard::PortC1Ddr,
463-
Rhd2000EvalBoard::PortC2Ddr,
464-
Rhd2000EvalBoard::PortD1Ddr,
465-
Rhd2000EvalBoard::PortD2Ddr
466-
};
467-
*/
468-
469-
chipId.insertMultiple(0,-1,8);
470-
Array<int> tmpChipId(chipId);
471-
472-
setSampleRate(Rhd2000EvalBoard::SampleRate30000Hz, true); // set to 30 kHz temporarily
473-
474-
// Enable all data streams, and set sources to cover one or two chips
475-
// on Ports A-D.
476-
evalBoard->setDataSource(0, initStreamPorts[0]);
477-
evalBoard->setDataSource(1, initStreamPorts[1]);
478-
evalBoard->setDataSource(2, initStreamPorts[2]);
479-
evalBoard->setDataSource(3, initStreamPorts[3]);
480-
evalBoard->setDataSource(4, initStreamPorts[4]);
481-
evalBoard->setDataSource(5, initStreamPorts[5]);
482-
evalBoard->setDataSource(6, initStreamPorts[6]);
483-
evalBoard->setDataSource(7, initStreamPorts[7]);
484-
485-
evalBoard->enableDataStream(0, true);
486-
evalBoard->enableDataStream(1, true);
487-
evalBoard->enableDataStream(2, true);
488-
evalBoard->enableDataStream(3, true);
489-
evalBoard->enableDataStream(4, true);
490-
evalBoard->enableDataStream(5, true);
491-
evalBoard->enableDataStream(6, true);
492-
evalBoard->enableDataStream(7, true);
493-
494-
std::cout << "Number of enabled data streams: " << evalBoard->getNumEnabledDataStreams() << std::endl;
495-
438+
//Clear previous known streams
439+
enabledStreams.clear();
496440

497-
evalBoard->selectAuxCommandBank(Rhd2000EvalBoard::PortA,
498-
Rhd2000EvalBoard::AuxCmd3, 0);
499-
evalBoard->selectAuxCommandBank(Rhd2000EvalBoard::PortB,
500-
Rhd2000EvalBoard::AuxCmd3, 0);
501-
evalBoard->selectAuxCommandBank(Rhd2000EvalBoard::PortC,
502-
Rhd2000EvalBoard::AuxCmd3, 0);
503-
evalBoard->selectAuxCommandBank(Rhd2000EvalBoard::PortD,
504-
Rhd2000EvalBoard::AuxCmd3, 0);
441+
// Scan SPI ports
505442

506-
// Since our longest command sequence is 60 commands, we run the SPI
507-
// interface for 60 samples. (64 for usb3 power-of two needs)
508-
evalBoard->setMaxTimeStep(64);
509-
evalBoard->setContinuousRunMode(false);
510-
511-
ScopedPointer<Rhd2000DataBlock> dataBlock =
512-
new Rhd2000DataBlock(evalBoard->getNumEnabledDataStreams(), evalBoard->isUSB3());
513-
514-
Array<int> sumGoodDelays;
515-
sumGoodDelays.insertMultiple(0,0,8);
516-
517-
Array<int> indexFirstGoodDelay;
518-
indexFirstGoodDelay.insertMultiple(0,-1,8);
519-
520-
Array<int> indexSecondGoodDelay;
521-
indexSecondGoodDelay.insertMultiple(0,-1,8);
522-
523-
524-
// Run SPI command sequence at all 16 possible FPGA MISO delay settings
525-
// to find optimum delay for each SPI interface cable.
526-
527-
std::cout << "Checking for connected amplifier chips..." << std::endl;
443+
int delay, hs, id;
444+
int register59Value;
445+
//int numChannelsOnPort[4] = {0, 0, 0, 0};
446+
Rhd2000EvalBoard::BoardDataSource initStreamPorts[8] =
447+
{
448+
Rhd2000EvalBoard::PortA1,
449+
Rhd2000EvalBoard::PortA2,
450+
Rhd2000EvalBoard::PortB1,
451+
Rhd2000EvalBoard::PortB2,
452+
Rhd2000EvalBoard::PortC1,
453+
Rhd2000EvalBoard::PortC2,
454+
Rhd2000EvalBoard::PortD1,
455+
Rhd2000EvalBoard::PortD2
456+
};
457+
458+
/*
459+
Rhd2000EvalBoard::BoardDataSource initStreamDdrPorts[8] =
460+
{
461+
Rhd2000EvalBoard::PortA1Ddr,
462+
Rhd2000EvalBoard::PortA2Ddr,
463+
Rhd2000EvalBoard::PortB1Ddr,
464+
Rhd2000EvalBoard::PortB2Ddr,
465+
Rhd2000EvalBoard::PortC1Ddr,
466+
Rhd2000EvalBoard::PortC2Ddr,
467+
Rhd2000EvalBoard::PortD1Ddr,
468+
Rhd2000EvalBoard::PortD2Ddr
469+
};
470+
*/
471+
472+
chipId.insertMultiple(0, -1, 8);
473+
Array<int> tmpChipId(chipId);
474+
475+
setSampleRate(Rhd2000EvalBoard::SampleRate30000Hz, true); // set to 30 kHz temporarily
476+
477+
// Enable all data streams, and set sources to cover one or two chips
478+
// on Ports A-D.
479+
evalBoard->setDataSource(0, initStreamPorts[0]);
480+
evalBoard->setDataSource(1, initStreamPorts[1]);
481+
evalBoard->setDataSource(2, initStreamPorts[2]);
482+
evalBoard->setDataSource(3, initStreamPorts[3]);
483+
evalBoard->setDataSource(4, initStreamPorts[4]);
484+
evalBoard->setDataSource(5, initStreamPorts[5]);
485+
evalBoard->setDataSource(6, initStreamPorts[6]);
486+
evalBoard->setDataSource(7, initStreamPorts[7]);
487+
488+
evalBoard->enableDataStream(0, true);
489+
evalBoard->enableDataStream(1, true);
490+
evalBoard->enableDataStream(2, true);
491+
evalBoard->enableDataStream(3, true);
492+
evalBoard->enableDataStream(4, true);
493+
evalBoard->enableDataStream(5, true);
494+
evalBoard->enableDataStream(6, true);
495+
evalBoard->enableDataStream(7, true);
496+
497+
std::cout << "Number of enabled data streams: " << evalBoard->getNumEnabledDataStreams() << std::endl;
498+
499+
500+
evalBoard->selectAuxCommandBank(Rhd2000EvalBoard::PortA,
501+
Rhd2000EvalBoard::AuxCmd3, 0);
502+
evalBoard->selectAuxCommandBank(Rhd2000EvalBoard::PortB,
503+
Rhd2000EvalBoard::AuxCmd3, 0);
504+
evalBoard->selectAuxCommandBank(Rhd2000EvalBoard::PortC,
505+
Rhd2000EvalBoard::AuxCmd3, 0);
506+
evalBoard->selectAuxCommandBank(Rhd2000EvalBoard::PortD,
507+
Rhd2000EvalBoard::AuxCmd3, 0);
508+
509+
// Since our longest command sequence is 60 commands, we run the SPI
510+
// interface for 60 samples. (64 for usb3 power-of two needs)
511+
evalBoard->setMaxTimeStep(64);
512+
evalBoard->setContinuousRunMode(false);
513+
514+
ScopedPointer<Rhd2000DataBlock> dataBlock =
515+
new Rhd2000DataBlock(evalBoard->getNumEnabledDataStreams(), evalBoard->isUSB3());
516+
517+
Array<int> sumGoodDelays;
518+
sumGoodDelays.insertMultiple(0, 0, 8);
519+
520+
Array<int> indexFirstGoodDelay;
521+
indexFirstGoodDelay.insertMultiple(0, -1, 8);
522+
523+
Array<int> indexSecondGoodDelay;
524+
indexSecondGoodDelay.insertMultiple(0, -1, 8);
525+
526+
527+
// Run SPI command sequence at all 16 possible FPGA MISO delay settings
528+
// to find optimum delay for each SPI interface cable.
529+
530+
std::cout << "Checking for connected amplifier chips..." << std::endl;
531+
532+
for (delay = 0; delay < 16; delay++)//(delay = 0; delay < 16; ++delay)
533+
{
534+
evalBoard->setCableDelay(Rhd2000EvalBoard::PortA, delay);
535+
evalBoard->setCableDelay(Rhd2000EvalBoard::PortB, delay);
536+
evalBoard->setCableDelay(Rhd2000EvalBoard::PortC, delay);
537+
evalBoard->setCableDelay(Rhd2000EvalBoard::PortD, delay);
528538

529-
for (delay = 0; delay < 16; delay++)//(delay = 0; delay < 16; ++delay)
530-
{
531-
evalBoard->setCableDelay(Rhd2000EvalBoard::PortA, delay);
532-
evalBoard->setCableDelay(Rhd2000EvalBoard::PortB, delay);
533-
evalBoard->setCableDelay(Rhd2000EvalBoard::PortC, delay);
534-
evalBoard->setCableDelay(Rhd2000EvalBoard::PortD, delay);
539+
// Start SPI interface.
540+
evalBoard->run();
535541

536-
// Start SPI interface.
537-
evalBoard->run();
538-
539-
// Wait for the 60-sample run to complete.
540-
while (evalBoard->isRunning())
541-
{
542-
;
543-
}
544-
// Read the resulting single data block from the USB interface.
545-
evalBoard->readDataBlock(dataBlock, 64);
542+
// Wait for the 60-sample run to complete.
543+
while (evalBoard->isRunning())
544+
{
545+
;
546+
}
547+
// Read the resulting single data block from the USB interface.
548+
evalBoard->readDataBlock(dataBlock, 64);
546549

547-
// Read the Intan chip ID number from each RHD2000 chip found.
548-
// Record delay settings that yield good communication with the chip.
549-
for (hs = 0; hs < MAX_NUM_HEADSTAGES; ++hs)//MAX_NUM_DATA_STREAMS; ++stream)
550-
{
551-
// std::cout << "Stream number " << stream << ", delay = " << delay << std::endl;
550+
// Read the Intan chip ID number from each RHD2000 chip found.
551+
// Record delay settings that yield good communication with the chip.
552+
for (hs = 0; hs < MAX_NUM_HEADSTAGES; ++hs)//MAX_NUM_DATA_STREAMS; ++stream)
553+
{
554+
// std::cout << "Stream number " << stream << ", delay = " << delay << std::endl;
552555

553-
id = deviceId(dataBlock, hs, register59Value);
556+
id = deviceId(dataBlock, hs, register59Value);
554557

555-
if (id == CHIP_ID_RHD2132 || id == CHIP_ID_RHD2216 ||
556-
(id == CHIP_ID_RHD2164 && register59Value == REGISTER_59_MISO_A))
557-
{
558-
// std::cout << "Device ID found: " << id << std::endl;
558+
if (id == CHIP_ID_RHD2132 || id == CHIP_ID_RHD2216 ||
559+
(id == CHIP_ID_RHD2164 && register59Value == REGISTER_59_MISO_A))
560+
{
561+
// std::cout << "Device ID found: " << id << std::endl;
559562

560-
sumGoodDelays.set(hs,sumGoodDelays[hs] + 1);
563+
sumGoodDelays.set(hs, sumGoodDelays[hs] + 1);
561564

562-
if (indexFirstGoodDelay[hs] == -1)
563-
{
564-
indexFirstGoodDelay.set(hs, delay);
565-
tmpChipId.set(hs,id);
566-
}
567-
else if (indexSecondGoodDelay[hs] == -1)
568-
{
569-
indexSecondGoodDelay.set(hs,delay);
570-
tmpChipId.set(hs,id);
571-
}
572-
}
573-
}
574-
}
565+
if (indexFirstGoodDelay[hs] == -1)
566+
{
567+
indexFirstGoodDelay.set(hs, delay);
568+
tmpChipId.set(hs, id);
569+
}
570+
else if (indexSecondGoodDelay[hs] == -1)
571+
{
572+
indexSecondGoodDelay.set(hs, delay);
573+
tmpChipId.set(hs, id);
574+
}
575+
}
576+
}
577+
}
575578

576-
// std::cout << "Chip IDs found: ";
577-
// for (int i = 0; i < MAX_NUM_DATA_STREAMS; ++i)
578-
// {
579-
// std::cout << chipId[i] << " ";
580-
// }
581-
//std::cout << std::endl;
579+
// std::cout << "Chip IDs found: ";
580+
// for (int i = 0; i < MAX_NUM_DATA_STREAMS; ++i)
581+
// {
582+
// std::cout << chipId[i] << " ";
583+
// }
584+
//std::cout << std::endl;
582585

583586
#if DEBUG_EMULATE_HEADSTAGES > 0
584-
for (int nd = 0; nd < MAX_NUM_DATA_STREAMS; ++nd)
585-
{
586-
if ((nd < DEBUG_EMULATE_HEADSTAGES) &&(tmpChipId[0] > 0))
587-
{
588-
evalBoard->setDataSource(nd,initStreamPorts[0]);
589-
enableHeadstage(nd,true);
590-
}
591-
else
592-
{
593-
enableHeadstage(stream,false);
594-
}
595-
}
587+
if (tmpChipId[0] > 0)
588+
{
589+
int chipIdx = 0;
590+
for (int hs = 0; hs < DEBUG_EMULATE_HEADSTAGES && hs < MAX_NUM_HEADSTAGES ; ++hs)
591+
{
592+
if (enabledStreams.size() < MAX_NUM_DATA_STREAMS(evalBoard->isUSB3()))
593+
{
594+
#ifdef DEBUG_EMULATE_64CH
595+
chipId.set(chipIdx++,CHIP_ID_RHD2164);
596+
chipId.set(chipIdx++,CHIP_ID_RHD2164_B);
597+
enableHeadstage(hs, true, 2, 32);
598+
#else
599+
chipId.set(chipIdx++,CHIP_ID_RHD2132);
600+
enableHeadstage(hs, true, 1, 32);
601+
#endif
602+
}
603+
}
604+
for (int i = 0; i < enabledStreams.size(); i++)
605+
{
606+
enabledStreams.set(i,Rhd2000EvalBoard::PortA1);
607+
}
608+
}
609+
596610
#else
597611
// Now, disable data streams where we did not find chips present.
598612
int chipIdx = 0;
@@ -624,8 +638,8 @@ void RHD2000Thread::scanPorts()
624638
enableHeadstage(hs, false);
625639
}
626640
}
627-
updateBoardStreams();
628641
#endif
642+
updateBoardStreams();
629643

630644

631645
std::cout << "Number of enabled data streams: " << evalBoard->getNumEnabledDataStreams() << std::endl;
@@ -1580,6 +1594,7 @@ bool RHD2000Thread::updateBuffer()
15801594

15811595
if (dacOutputShouldChange)
15821596
{
1597+
std::cout << "DAC" << std::endl;
15831598
for (int k=0; k<8; k++)
15841599
{
15851600
if (dacChannelsToUpdate[k])
@@ -1591,7 +1606,7 @@ bool RHD2000Thread::updateBuffer()
15911606
evalBoard->selectDacDataStream(k, dacStream[k]);
15921607
evalBoard->selectDacDataChannel(k, dacChannels[k]);
15931608
evalBoard->setDacThreshold(k, (int)abs((dacThresholds[k]/0.195) + 32768),dacThresholds[k] >= 0);
1594-
// evalBoard->setDacThresholdVoltage(k, (int) dacThresholds[k]);
1609+
// evalBoard->setDacThresholdVoltage(k, (int) dacThresholds[k]);
15951610
}
15961611
else
15971612
{
@@ -1600,12 +1615,12 @@ bool RHD2000Thread::updateBuffer()
16001615
}
16011616
}
16021617

1603-
//evalBoard->setTtlMode(ttlMode ? 1 : 0);
1604-
//evalBoard->enableExternalFastSettle(fastTTLSettleEnabled);
1605-
//evalBoard->setExternalFastSettleChannel(fastSettleTTLChannel);
1606-
//evalBoard->setDacHighpassFilter(desiredDAChpf);
1607-
//evalBoard->enableDacHighpassFilter(desiredDAChpfState);
1608-
//evalBoard->enableBoardLeds(ledsEnabled);
1618+
evalBoard->setTtlMode(ttlMode ? 1 : 0);
1619+
evalBoard->enableExternalFastSettle(fastTTLSettleEnabled);
1620+
evalBoard->setExternalFastSettleChannel(fastSettleTTLChannel);
1621+
evalBoard->setDacHighpassFilter(desiredDAChpf);
1622+
evalBoard->enableDacHighpassFilter(desiredDAChpfState);
1623+
evalBoard->enableBoardLeds(ledsEnabled);
16091624

16101625
dacOutputShouldChange = false;
16111626
}

0 commit comments

Comments
 (0)