Commit 5177bcb2 authored by Sarah Seif El Nasr's avatar Sarah Seif El Nasr
Browse files

Minor update to threaded cont readout and regTester

parent 29512819
Subproject commit 54e593c146644aca1e110e44831aec0eeddf1f64
Subproject commit 20116de3a6a395b1b6dfaa365f9a461080b960b0
......@@ -138,7 +138,15 @@ int main(int argc, char* argv[])
cmd.defineOption("readIDs", "Read chip ids....", ArgvParser::NoOptionAttribute);
cmd.defineOption("memCheck", "Check memories of the following CBCs", ArgvParser::NoOptionAttribute);
cmd.defineOption("completeDataCheck", "Complete data check for the following CBCs", ArgvParser::OptionRequiresValue);
cmd.defineOption("registerTest", "Test I2C registers on ROCs", ArgvParser::NoOptionAttribute);
cmd.defineOption("registerTestWrite", "Test I2C registers on ROCs", ArgvParser::OptionRequiresValue);
cmd.defineOption("registerTestWriteAndToggle", "Test I2C registers on ROCs", ArgvParser::OptionRequiresValue);
cmd.defineOption("registerTestRead", "Test I2C registers on ROCs", ArgvParser::OptionRequiresValue);
cmd.defineOption("registerTestReadAndToggle", "Test I2C registers on ROCs", ArgvParser::OptionRequiresValue);
cmd.defineOption("sortOrder","Sort order for CBC registers : 0 - no sort other than page; 1 - page then increasing addresss; 2 - page then decreasing addresss", ArgvParser::OptionRequiresValue);
cmd.defineOption("bitToFlip","Bit to flip when testing register write", ArgvParser::OptionRequiresValue);
cmd.defineOption("testAttempts","Number of attempts", ArgvParser::OptionRequiresValue);
cmd.defineOption("returnToDefPage","Return to Def Page", ArgvParser::OptionRequiresValue);
cmd.defineOption("manualScan", "Manual scan of threshold", ArgvParser::NoOptionAttribute);
cmd.defineOption("injectionTest", "Manual scan of threshold", ArgvParser::OptionRequiresValue);
//
......@@ -363,7 +371,9 @@ int main(int argc, char* argv[])
{
for(auto cChip: *cHybrid)
{
auto cFusedId = cTool.fReadoutChipInterface->ReadChipReg(cChip, "ChipId");
if( cChip->getFrontEndType() != FrontEndType::CBC3 ) continue;
auto cFusedId = static_cast<CbcInterface*>(cTool.fReadoutChipInterface)->ReadCbcIDeFuse(cChip);
LOG(INFO) << BOLDMAGENTA << "Hybrid#" << +cChip->getId() << " CBC#" << +cChip->getId() << " Fused Id is " << +cFusedId << RESET;
}
}
......@@ -371,11 +381,84 @@ int main(int argc, char* argv[])
}
}
if(cmd.foundOption("registerTest"))
if(cmd.foundOption("registerTestWrite"))
{
uint8_t cNregistersToCheck = (cmd.foundOption("registerTestWrite")) ? convertAnyInt(cmd.optionValue("registerTestWrite").c_str()) : 1;
// 0 - no sorting other than page; 1 - page then increasing addresss ; 2 - page then decreasing address
uint8_t cSortOder = (cmd.foundOption("sortOrder")) ? convertAnyInt(cmd.optionValue("sortOrder").c_str()) : 0;
uint8_t cBitToFlip = (cmd.foundOption("bitToFlip")) ? convertAnyInt(cmd.optionValue("bitToFlip").c_str()) : 0;
uint32_t cAttempts = (cmd.foundOption("testAttempts")) ? convertAnyInt(cmd.optionValue("testAttempts").c_str()) : 10;
RegisterTester cRegTester;
cRegTester.Inherit(&cTool);
cRegTester.SetSortOrder(cSortOder);
cRegTester.SetBitToFlip(cBitToFlip);
cRegTester.Initialise();
for( size_t cAttempt=0; cAttempt < cAttempts; cAttempt++){
LOG (INFO) << BOLDBLUE << "Read - test#" << +cAttempt << RESET;
cRegTester.CheckWriteRegisters(1, cNregistersToCheck);
}
cRegTester.writeObjects();
}
if(cmd.foundOption("registerTestWriteAndToggle"))
{
uint8_t cNregistersToCheck = (cmd.foundOption("registerTestWriteAndToggle")) ? convertAnyInt(cmd.optionValue("registerTestWriteAndToggle").c_str()) : 1;
// 0 - no sorting other than page; 1 - page then increasing addresss ; 2 - page then decreasing address
uint8_t cSortOder = (cmd.foundOption("sortOrder")) ? convertAnyInt(cmd.optionValue("sortOrder").c_str()) : 0;
uint8_t cBitToFlip = (cmd.foundOption("bitToFlip")) ? convertAnyInt(cmd.optionValue("bitToFlip").c_str()) : 0;
uint8_t cReturnToDefPage = (cmd.foundOption("returnToDefPage")) ? convertAnyInt(cmd.optionValue("returnToDefPage").c_str()) : 1;
uint32_t cAttempts = (cmd.foundOption("testAttempts")) ? convertAnyInt(cmd.optionValue("testAttempts").c_str()) : 10;
LOG (INFO) << BOLDBLUE << "Will run register test " << cAttempts << " times..." << RESET;
RegisterTester cRegTester;
cRegTester.Inherit(&cTool);
cRegTester.RegisterTest();
cRegTester.SetSortOrder(cSortOder);
cRegTester.SetBitToFlip(cBitToFlip);
cRegTester.SetReturnToDefPage(cReturnToDefPage);
cRegTester.Initialise();
for( size_t cAttempt=0; cAttempt < cAttempts; cAttempt++){
LOG (INFO) << BOLDBLUE << "Page switch with read - test#" << +cAttempt << RESET;
cRegTester.CheckPageSwitchWrite(1,cNregistersToCheck);
}
cRegTester.writeObjects();
}
if(cmd.foundOption("registerTestRead"))
{
uint8_t cNregistersToCheck = (cmd.foundOption("registerTestRead")) ? convertAnyInt(cmd.optionValue("registerTestRead").c_str()) : 1;
// 0 - no sorting other than page; 1 - page then increasing addresss ; 2 - page then decreasing address
uint8_t cSortOder = (cmd.foundOption("sortOrder")) ? convertAnyInt(cmd.optionValue("sortOrder").c_str()) : 0;
uint32_t cAttempts = (cmd.foundOption("testAttempts")) ? convertAnyInt(cmd.optionValue("testAttempts").c_str()) : 10;
RegisterTester cRegTester;
cRegTester.Inherit(&cTool);
cRegTester.SetSortOrder(cSortOder);
cRegTester.Initialise();
for( size_t cAttempt=0; cAttempt < cAttempts; cAttempt++){
LOG (INFO) << BOLDBLUE << "Read - test#" << +cAttempt << RESET;
cRegTester.CheckReadRegisters(1, cNregistersToCheck);
}
cRegTester.writeObjects();
}
if(cmd.foundOption("registerTestReadAndToggle"))
{
uint8_t cNregistersToCheck = (cmd.foundOption("registerTestReadAndToggle")) ? convertAnyInt(cmd.optionValue("registerTestReadAndToggle").c_str()) : 1;
// 0 - no sorting other than page; 1 - page then increasing addresss ; 2 - page then decreasing address
uint8_t cSortOder = (cmd.foundOption("sortOrder")) ? convertAnyInt(cmd.optionValue("sortOrder").c_str()) : 0;
uint8_t cReturnToDefPage = (cmd.foundOption("returnToDefPage")) ? convertAnyInt(cmd.optionValue("returnToDefPage").c_str()) : 1;
uint32_t cAttempts = (cmd.foundOption("testAttempts")) ? convertAnyInt(cmd.optionValue("testAttempts").c_str()) : 10;
RegisterTester cRegTester;
cRegTester.Inherit(&cTool);
cRegTester.SetSortOrder(cSortOder);
cRegTester.SetReturnToDefPage(cReturnToDefPage);
cRegTester.Initialise();
for( size_t cAttempt=0; cAttempt < cAttempts; cAttempt++){
LOG (INFO) << BOLDBLUE << "Page switch with read - test#" << +cAttempt << RESET;
cRegTester.CheckPageSwitchRead(1,cNregistersToCheck);
}
cRegTester.writeObjects();
}
// align CIC-lpGBT-BE
......@@ -1104,9 +1187,9 @@ int main(int argc, char* argv[])
cCng.fPrintEvery = 1;
cBeamTestCheck.ConfigurePrintout(cCng);
cBeamTestCheck.ReadDataFromFile(cRawFileName);
cBeamTestCheck.ValidateRaw();
// cBeamTestCheck.ValidateRaw();
cBeamTestCheck.writeObjects();
cBeamTestCheck.Reset();
// cBeamTestCheck.Reset();
}
if(!cmd.foundOption("read")) { cTool.dumpConfigFiles(); }
......
......@@ -371,68 +371,75 @@ void OTTool::CatchStop()
}
// poll board from data
// one thread per BeBoard connected to this computer
void OTTool::ContinousReadout()
void OTTool::ContinousReadoutTh(uint8_t cBrdId)
{
// temporary thread object representing a new thread
// there will be one readout thread per board
std::thread* cReadoutThreads = new std::thread[fDetectorContainer->size()];
for(auto cBoard: *fDetectorContainer)
LOG(DEBUG) << BOLDBLUE << fMyName << ":Starting continuous readout thread for BeBoard#" << +cBrdId << RESET;
// get D19cFW Interface
auto cBoardIter = std::find_if(fDetectorContainer->begin(), fDetectorContainer->end(), [&cBrdId](Ph2_HwDescription::BeBoard* x) { return x->getId() == cBrdId; });
fBeBoardInterface->setBoard((*cBoardIter)->getId());
auto cInterface = static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface());
// wait until triggers have started
size_t cWaitCounter = 0;
size_t cMaxWait = 10000;
do
{
// launch threads for continuous readout
cReadoutThreads[cBoard->getIndex()] = std::thread(&OTTool::ContinousReadoutTh, this, cBoard->getIndex());
}
std::this_thread::sleep_for(std::chrono::microseconds(fThreadWait));
if(cWaitCounter % 100 == 0) LOG(DEBUG) << BOLDBLUE << "\t\t" << fMyName << ":Waiting for triggers to start on BeBoard#" << +cBrdId << RESET;
cWaitCounter++;
} while(cInterface->GetTriggerState() != 1 && cWaitCounter < cMaxWait);
std::vector<uint32_t> cBrdEvntCntrs(fDetectorContainer->size(), 0);
// reset all event counters
for(auto cBoard: *fDetectorContainer)
if(cWaitCounter == cMaxWait)
{
fBeBoardInterface->setBoard(cBoard->getId());
auto cInterface = static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface());
cInterface->ResetEventCounter();
cBrdEvntCntrs[cBoard->getIndex()] = cInterface->GetEventCounter();
LOG(INFO) << BOLDRED << "Triggers not started on this board.. start them myself!" << RESET;
cInterface->Start();
do
{
std::this_thread::sleep_for(std::chrono::microseconds(fThreadWait));
LOG(INFO) << BOLDRED << " ... waiting for triggers to start... " << RESET;
} while(cInterface->GetTriggerState() == 0);
}
// start triggers on all boards
for(auto cBoard: *fDetectorContainer) { fBeBoardInterface->Start(cBoard); }
// wait until you have all events from all boards
// exit condition for this run
bool cAllFinished = false;
size_t cWaitCounter = 0;
LOG(DEBUG) << BOLDBLUE << fMyName << ":Main thread - starting to wait for events to be readout.." << RESET;
LOG(DEBUG) << BOLDBLUE << fMyName << ":Triggers started .. now polling readout.." << RESET;
std::vector<uint32_t> cCompleteData(0);
bool cWait = false;
std::vector<size_t> cTriggerCounters(0);
// repeat until triggers have stopped
cWaitCounter = 0;
size_t cLclEvntCntr = 0;
auto cStartTime = std::chrono::high_resolution_clock::now(), cEndTime=cStartTime;
size_t cAccumulatedWaits=0;
do
{
size_t cNFinished = 0;
for(auto cBoard: *fDetectorContainer)
cAccumulatedWaits += fReadoutPause;
std::this_thread::sleep_for(std::chrono::microseconds(fReadoutPause));
auto cTriggerState = cInterface->GetTriggerState();
auto cTriggerSource = fBeBoardInterface->ReadBoardReg((*cBoardIter), "fc7_daq_cnfg.fast_command_block.trigger_source");
auto cTriggerCounter = fBeBoardInterface->ReadBoardReg((*cBoardIter), "fc7_daq_stat.fast_command_block.trigger_in_counter");
std::vector<uint32_t> cData(0);
cLclEvntCntr += fBeBoardInterface->ReadData((*cBoardIter), false, cData, cWait);
if(cData.size() != 0) std::move(cData.begin(), cData.end(), std::back_inserter(cCompleteData));
cTriggerCounters.push_back(cTriggerCounter);
if(cWaitCounter % 100 == 0 && cWaitCounter > 0)
{
fBeBoardInterface->setBoard(cBoard->getId());
auto cInterface = static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface());
cBrdEvntCntrs[cBoard->getIndex()] = cInterface->GetEventCounter();
if(cWaitCounter % 1000 == 0)
LOG(DEBUG) << BOLDBLUE << fMyName << ":Main thread ... read-back " << cBrdEvntCntrs[cBoard->getIndex()] << " events from BeBoard#" << +cBoard->getId() << RESET;
// finished if I've received all events or if someone else has stopped triggers for me
if(cBrdEvntCntrs[cBoard->getIndex()] >= fNevents || cInterface->GetTriggerState() == 0)
{
LOG(DEBUG) << BOLDBLUE << fMyName << ":Main thread ... finished collecting all requested events from BeBoard" << +cBoard->getId() << RESET;
cNFinished++;
}
LOG(DEBUG) << BOLDBLUE << "\t\t" << fMyName << ":Waiting for triggers to be stopped on BeBoard#" << +cBrdId << " continuousReadout loop ... "
<< +cTriggerCounters[cTriggerCounters.size() - 1] << " triggers received"
<< " trigger source is " << +cTriggerSource << " trigger state is " << +cTriggerState << " and " << cLclEvntCntr << " events in the readout so far ... " << RESET;
}
cWaitCounter++;
cAllFinished = (cNFinished == fDetectorContainer->size());
} while(!cAllFinished);
// make double sure that all triggers have
// been stopped here
// stop triggers on all boards
for(auto cBoard: *fDetectorContainer) { fBeBoardInterface->Stop(cBoard); }
// wait for all threads to finish
// this will just do in sequence for all boards
for(auto cBoard: *fDetectorContainer)
{
// launch threads for continuous readout
cReadoutThreads[cBoard->getIndex()].join(); // pauses until first finishes
}
} while(cInterface->GetTriggerState() == 1);
// now decode data
cAccumulatedWaits += 100*1e3;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::vector<uint32_t> cData(0);
cLclEvntCntr += fBeBoardInterface->ReadData((*cBoardIter), false, cData, cWait);
cEndTime = std::chrono::high_resolution_clock::now();
auto cDuration = std::chrono::duration_cast<std::chrono::milliseconds>(cEndTime - cStartTime).count();
if(cData.size() != 0) std::move(cData.begin(), cData.end(), std::back_inserter(cCompleteData));
LOG (DEBUG) << BOLDYELLOW << "Accumulated " << cAccumulatedWaits*1e-3 << " ms of waits.. read-out " << cCompleteData.size() << " 32-bit words in " << cDuration << " ms." << RESET;
DecodeData((*cBoardIter), cCompleteData, cLclEvntCntr, fBeBoardInterface->getBoardType((*cBoardIter)));
LOG(DEBUG) << BOLDYELLOW << fMyName << " : Mean trigger rate is " << cTriggerCounters[cTriggerCounters.size() - 1] / (cWaitCounter * fReadoutPause * 1e-6) << " Hz"
<< " .... readout " << cLclEvntCntr << " events from the FC7" << RESET;
}
// continuous readout
// this will continue to read data until the stop triggers command
......
This diff is collapsed.
......@@ -17,12 +17,11 @@
#include "../Utils/ContainerRecycleBin.h"
#include "Tool.h"
#ifdef __USE_ROOT__
#include "TCanvas.h"
#include "TGraphErrors.h"
#include "TProfile.h"
#include "TString.h"
#include "TText.h"
#include "../DQMUtils/DQMHistogramRegisterTest.h"
#include "TH1.h"
#endif
using namespace Ph2_System;
......@@ -67,6 +66,13 @@ class RegisterTester : public Tool
void Reset();
void initializeRecycleBin() { fRecycleBin.setDetectorContainer(fDetectorContainer); }
void CheckReadRegisters( uint8_t pPageToSelect=0, uint8_t pNRegisters=10);
void CheckWriteRegisters( uint8_t pPageToSelect=0, uint8_t pNRegisters=10);
void CheckPageSwitchRead(uint8_t pPageToSelect=0, uint8_t pNRegisters=1);
void CheckPageSwitchWrite(uint8_t pPageToSelect=0, uint8_t pNRegisters=1);
void SetSortOrder(uint8_t pSortOrder){ fSortOrder = pSortOrder; };
void SetBitToFlip(uint8_t pBit){ fBitToFlip = pBit; };
void SetReturnToDefPage(uint8_t pReturn){fReturnToDefPage =pReturn;};
private:
// timing
std::chrono::seconds::rep fStartTime;
......@@ -75,9 +81,19 @@ class RegisterTester : public Tool
// Containers
BadRegisters fBadRegisters;
ContainerRecycleBin<uint8_t> fRecycleBin;
DetectorDataContainer fRegList;
// Counters
uint32_t fNBadRegisters;
// sort order
uint8_t fSortOrder{0};
// bit to flip during register write test
uint8_t fBitToFlip{0};
// set page back to default after a write
uint8_t fReturnToDefPage{0};
// HardReset
void SendHardReset(const Ph2_HwDescription::OpticalGroup* pOpticalGroup, const Ph2_HwDescription::Chip* pFrontEndChip);
......@@ -97,5 +113,16 @@ class RegisterTester : public Tool
{
bool operator()(Register a, Register b) const { return a.second.fAddress > b.second.fAddress; }
} customGreaterThanAddress;
struct
{
bool operator()(Register a, Register b) const { return a.second.fAddress < b.second.fAddress; }
} customLessThanAddress;
#ifdef __USE_ROOT__
DQMHistogramRegisterTest fDQMHistogrammer;
#endif
// void CheckPageSwitch();
// void CheckPageSwitch();
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment