diff --git a/CMakeLists.txt b/CMakeLists.txt index b4312cd..bdfea8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,23 @@ find_package(artdaq_core_demo 1.11.00 REQUIRED EXPORT) find_package(otsdaq_mu2e 1.02.00 REQUIRED EXPORT) find_package(mu2e_pcie_utils 3.02.00 REQUIRED EXPORT) +message("-- P.Murat: otsdaq-mu2e-tracker: MIDASSYS=."$ENV{MIDASSYS}) + +# message("---------- otsdaq-mu2e-tracker: PRINT CMAKE VARIABLES " ) +# +# get_cmake_property(_variableNames VARIABLES) +# list (SORT _variableNames) +# foreach (_variableName ${_variableNames}) +# message(STATUS "${_variableName}=${${_variableName}}") +# endforeach() + +# if (DEFINED ENV{MIDASSYS}) +# message(-- P.Murat: otsdaq-mu2e-tracker: MIDASSYS=.$ENV{MIDASSYS}. ) +# find_package(Midas REQUIRED) +# else() +# message("-- P.Murat: no MIDASSYS") +# endif() + # XDAQ Extra setup include_directories($ENV{XDAQ_ROOT}/include) diff --git a/config/pasha/mu2edaq07_pcie0.C b/config/pasha/mu2edaq07_pcie0.C new file mode 100644 index 0000000..105213a --- /dev/null +++ b/config/pasha/mu2edaq07_pcie0.C @@ -0,0 +1,37 @@ +/////////////////////////////////////////////////////////////////////////////// +// mu2edaq22 : DTC0: ROC tower +// init_run_configuration : the name and the call signature are is fixed +// and can't be changed +/////////////////////////////////////////////////////////////////////////////// +#include "otsdaq-mu2e-tracker/Gui/DtcGui.hh" +int init_run_configuration(DtcGui* X) { + int rc(0); + + printf("[init_run_configuration] : host:%s\n",gSystem->Getenv("HOSTNAME")); + + DtcGui::DtcData_t* dtc = (DtcGui::DtcData_t*) X->fDtcData; + + X->fNDtcs = 1; // 2; // installed on a machine + + // dtc[0].fName = "CFO"; + // dtc[0].fPcieAddr = 0; + // dtc[0].fLinkMask = 0x2; // 2 DTCs on link0 + // gSystem->Setenv("CFOLIB_CFO","0"); + + dtc[0].fName = "DTC"; + dtc[0].fPcieAddr = 0; + // dtc[0].fLinkMask = 0x000001; // ROC0 + dtc[0].fLinkMask = 0x111111; // 6 ROCs + dtc[0].fReadoutMode = 0; // 0:patterns 1:digis + dtc[0].fJAMode = 0x01; // ROC tower@IERC: external clock (internal_clock << 4) + reset + dtc[0].fEmulateCfo = 1; // + + dtc[0].fDtcID = 7; // for one machine, make it the same as the PcieAddr + dtc[0].fPartitionID = 0; + dtc[0].fMode = 0; + dtc[0].fMacAddrByte = 0; + + gSystem->Setenv("DTCLIB_DTC","0"); + + return rc; +} diff --git a/config/pasha/mu2edaq07_pcie1.C b/config/pasha/mu2edaq07_pcie1.C new file mode 100644 index 0000000..01151e2 --- /dev/null +++ b/config/pasha/mu2edaq07_pcie1.C @@ -0,0 +1,35 @@ +/////////////////////////////////////////////////////////////////////////////// +// mu2edaq22 : +// init_run_configuration : the name and the call signature are is fixed +// and can't be changed +/////////////////////////////////////////////////////////////////////////////// +#include "otsdaq-mu2e-tracker/Gui/DtcGui.hh" +int init_run_configuration(DtcGui* X) { + int rc(0); + + printf("[init_run_configuration] : host:%s\n",gSystem->Getenv("HOSTNAME")); + + DtcGui::DtcData_t* dtc = (DtcGui::DtcData_t*) X->fDtcData; + + X->fNDtcs = 1; // 2; // installed on a machine + + // dtc[0].fName = "CFO"; + // dtc[0].fPcieAddr = 0; + // dtc[0].fLinkMask = 0x2; // 2 DTCs on link0 + // gSystem->Setenv("CFOLIB_CFO","0"); + + dtc[0].fName = "DTC"; + dtc[0].fPcieAddr = 1; + dtc[0].fLinkMask = 0x011; // TS2 (0x10) +TS1 + dtc[0].fJAMode = 0x01; + dtc[0].fReadoutMode = 1; // 0:patterns 1:digis + + dtc[0].fDtcID = 1; // for 1 node, make it the same as PcieAddr + dtc[0].fPartitionID = 0; + dtc[0].fMode = 0; + dtc[0].fMacAddrByte = 0; + + gSystem->Setenv("DTCLIB_DTC","1"); + + return rc; +} diff --git a/config/pasha/mu2edaq09_pcie0.C b/config/pasha/mu2edaq09_pcie0.C index a549775..842487b 100644 --- a/config/pasha/mu2edaq09_pcie0.C +++ b/config/pasha/mu2edaq09_pcie0.C @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// mu2edaq09 : +// mu2edaq09/pcie0 : // init_run_configuration : the name and the call signature are is fixed // and can't be changed /////////////////////////////////////////////////////////////////////////////// @@ -15,8 +15,18 @@ int init_run_configuration(DtcGui* X) { dtc[0].fName = "DTC" ; // "CFO"; dtc[0].fPcieAddr = 0; - dtc[0].fLinkMask = 0x1; // start from 2 DTCs on link0 + dtc[0].fLinkMask = 0x111111; // start from 2 DTCs on link0 + // dtc[0].fLinkMask = 0x0010; // MN180 + // dtc[0].fLinkMask = 0x1000; // MN162 + // dtc[0].fLinkMask = 0x1001; // MN234+MN162 + dtc[0].fJAMode = 0x01; // no ext clock //gSystem->Setenv("CFOLIB_CFO","0"); + + dtc[0].fDtcID = 0; // for one machine, make it the same as the PcieAddr + dtc[0].fPartitionID = 0; + dtc[0].fMode = 0; + dtc[0].fMacAddrByte = 0; + gSystem->Setenv("DTCLIB_DTC","0"); // dtc[0].fName = "DTC"; diff --git a/config/pasha/mu2edaq09_pcie1.C b/config/pasha/mu2edaq09_pcie1.C index e136f38..e9c2131 100644 --- a/config/pasha/mu2edaq09_pcie1.C +++ b/config/pasha/mu2edaq09_pcie1.C @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// mu2edaq09 : +// mu2edaq09/pcie1 : // init_run_configuration : the name and the call signature are is fixed // and can't be changed /////////////////////////////////////////////////////////////////////////////// @@ -13,17 +13,25 @@ int init_run_configuration(DtcGui* X) { X->fNDtcs = 1; // 2; // installed on a machine - // dtc[0].fName = "CFO"; - // dtc[0].fPcieAddr = 0; - // dtc[0].fLinkMask = 0x2; // 2 DTCs on link0 - // gSystem->Setenv("CFOLIB_CFO","0"); - - dtc[0].fName = "DTC"; + dtc[0].fName = "DTC" ; // "CFO"; dtc[0].fPcieAddr = 1; - // dtc[0].fLinkMask = 0x00111111; // ROC tower: all ROCs - dtc[0].fLinkMask = 0x111; - dtc[0].fReadoutMode = 1; // 0:patterns 1:digis + // dtc[0].fLinkMask = 0x11111; // start from 2 DTCs on link0 + // dtc[0].fLinkMask = 0x11111; // can read 3 ROCs + dtc[0].fLinkMask = 0x111111 ; // leave only 2, + dtc[0].fJAMode = 0x01; // no ext clock + //gSystem->Setenv("CFOLIB_CFO","0"); + + dtc[0].fDtcID = 1; // for one machine, make it the same as the PcieAddr + dtc[0].fPartitionID = 0; + dtc[0].fMode = 0; + dtc[0].fMacAddrByte = 0; + gSystem->Setenv("DTCLIB_DTC","1"); + // dtc[0].fName = "DTC"; + // dtc[0].fPcieAddr = 1; + // dtc[0].fLinkMask = 0x111; // ROC0 and ROC1 + // gSystem->Setenv("DTCLIB_DTC","1"); + return rc; } diff --git a/config/pasha/mu2edaq22_pcie0.C b/config/pasha/mu2edaq22_pcie0.C index 2ca9f83..105213a 100644 --- a/config/pasha/mu2edaq22_pcie0.C +++ b/config/pasha/mu2edaq22_pcie0.C @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// mu2edaq22 : +// mu2edaq22 : DTC0: ROC tower // init_run_configuration : the name and the call signature are is fixed // and can't be changed /////////////////////////////////////////////////////////////////////////////// @@ -20,8 +20,17 @@ int init_run_configuration(DtcGui* X) { dtc[0].fName = "DTC"; dtc[0].fPcieAddr = 0; - dtc[0].fLinkMask = 0x1; // ROC0 + // dtc[0].fLinkMask = 0x000001; // ROC0 + dtc[0].fLinkMask = 0x111111; // 6 ROCs dtc[0].fReadoutMode = 0; // 0:patterns 1:digis + dtc[0].fJAMode = 0x01; // ROC tower@IERC: external clock (internal_clock << 4) + reset + dtc[0].fEmulateCfo = 1; // + + dtc[0].fDtcID = 7; // for one machine, make it the same as the PcieAddr + dtc[0].fPartitionID = 0; + dtc[0].fMode = 0; + dtc[0].fMacAddrByte = 0; + gSystem->Setenv("DTCLIB_DTC","0"); return rc; diff --git a/config/pasha/mu2edaq22_pcie1.C b/config/pasha/mu2edaq22_pcie1.C index ac3897c..305597e 100644 --- a/config/pasha/mu2edaq22_pcie1.C +++ b/config/pasha/mu2edaq22_pcie1.C @@ -20,10 +20,16 @@ int init_run_configuration(DtcGui* X) { dtc[0].fName = "DTC"; dtc[0].fPcieAddr = 1; - // dtc[0].fLinkMask = 0x111111; // full ROC tower - dtc[0].fLinkMask = 0x1; // ROC0 - // dtc[0].fLinkMask = 0x00011; // ROC0 and 1 : ROC tower, draq3 and draq5 + dtc[0].fLinkMask = 0x011; // TS2 (0x10) +TS1 + // dtc[0].fLinkMask = 0x01; // TS1 + dtc[0].fJAMode = 0x01; dtc[0].fReadoutMode = 1; // 0:patterns 1:digis + + dtc[0].fDtcID = 1; // for 1 node, make it the same as PcieAddr + dtc[0].fPartitionID = 0; + dtc[0].fMode = 0; + dtc[0].fMacAddrByte = 0; + gSystem->Setenv("DTCLIB_DTC","1"); return rc; diff --git a/doc/control_roc.org b/doc/control_roc.org index fcb7a3e..a130c50 100644 --- a/doc/control_roc.org +++ b/doc/control_roc.org @@ -48,9 +48,19 @@ readDeviceID - read -a 0 -t 3 -s 1 -l 8 -T 10 -m 3 -p 0 -C 0 -D 0 -E 08000000 : enable channel 91 -a mode : output test mode -| mode | pattern name | digital output word | -|------+--------------+---------------------| -| | | | +| mode | pattern name | digital output word 1 | digital output word2 | +|------+-------------------+-------------------------+-------------------------| +| 0000 | off | default | none | +| 0001 | midscale short | 1000 0000 0000 (12 bit) | none | +| | | 10 0000 0000 (10 bit) | none | +| 0010 | +full-scale short | 1111 1111 1111 (12 bit) | | +| | | 11 1111 1111 (10 bit) | none | +| 0011 | -full-scale short | 0000 0000 0000 (12 bit) | none | +| | | 00 0000 0000 (10 bit) | | +| 0100 | checkerboard | 1010 1010 1010 (12 bit) | 0101 0101 0101 (12 bit) | +| | | 10 1010 1010 (10 bit) | 01 0101 0101 (10 bit) | +| | | | | +Vadim's cheatsheet: file:images/vadim_digi_pattern_codes.png -m 3 : mode ... need -m 3 for internal pulser -l 8 : defines the look-back number of ADC samples for the waveform readout (may want to set to 0) @@ -305,13 +315,10 @@ Loading settings ... ======================================================= Ending... #+end_src - -- or , if thresholds need to be adjusted: - +** 2.5) update and save thresholds #+begin_src python3 diagnostic.py -m V -tv 30 -f settings_pasha_002.dat -p /dev/ttyUSB0 #+end_src - ** 3) login back to control_ROC, measure thresholds, set pulser #+begin_src python3 control_ROC.py --ts 1 @@ -371,7 +378,7 @@ set_digi_rw -s 0 #+end_src * 1) after each DIGIs power up, run control_ROC.py on trackerpi1/trackerpi5 1. start control_ROC.py on the PI - 1.a : let serial drives commands to DIGI + 1.a : let serial drive commands to DIGI 1.b : do alignment, what is alignment ? 1.c : read smth, why ? 1.d : in the end, let fiber drive commands to DIGI diff --git a/doc/images/vadim_digi_pattern_codes.png b/doc/images/vadim_digi_pattern_codes.png new file mode 100644 index 0000000..b6a86bb Binary files /dev/null and b/doc/images/vadim_digi_pattern_codes.png differ diff --git a/doc/otsdaq_mu2e_tracker.org b/doc/otsdaq_mu2e_tracker.org index d162c1b..e1a5133 100644 --- a/doc/otsdaq_mu2e_tracker.org +++ b/doc/otsdaq_mu2e_tracker.org @@ -165,6 +165,18 @@ And that no TIMEOUT should be observed on the very first event after a DTC_Reset * [[file:./dtc_gui.org][DtcGui interface]] * LVHVBox : https://github.com/vlrusu/LVHVBox - local repo: file:~mu2etrk/products/LVHVBox +- client commands: + - powerOn 3 + - powerOff +#+begin_src readMonV48 +readMonV48 +Channel 0 47.64 V +Channel 1 47.96 V +Channel 2 47.88 V +Channel 3 0.62 V +Channel 4 0.62 V +Channel 5 0.61 V +#+end_src * slow control of DTCs ** DTC_0 FPGA: 4 parameters -- 0x9010 : temperature @@ -468,7 +480,7 @@ readDeviceID ('DRAC ROC ID #', '7a7fb') ** [[file:roc_id_1b561.org][ROC ID 1b561]] : <2024-05-09 Thu> installed at TS1 ** [[file:roc_id_805d6.org][ROC ID 805d6]] : <2024-02-25 Sun> installed at TS2 -* DRAC Tower6 +* ROC Tower - new PI ... mu2e@ ... (local) ** window 1: cd ~/LVHVBox/GServer/build sudo ~/Server @@ -477,7 +489,7 @@ readDeviceID python3 Client.py ** Commands: - powerOn 1 # [or 2 or 3 ... 0=all) - - powerOff 1 # same semantics + - powerOff # same semantics - readMonI6 .. readMonI48 .. readMonV6 .. readMonV48 * test stands TS0, TS1, TS2 ** last update <2024-07-15 Mon> diff --git a/fcl/test_dqm_client01_input_file.fcl b/fcl/test_dqm_client01_input_file.fcl index a0c2f8e..b1eb27c 100644 --- a/fcl/test_dqm_client01_input_file.fcl +++ b/fcl/test_dqm_client01_input_file.fcl @@ -178,7 +178,7 @@ physics: { # new format: offset 0x20 : 40 (80 bytes = (0x20 + 0x08) in 2-byte words) # currently redefined in beginRun #------------------------------------------------------------------------------ - dataHeaderOffset : 32 + dataHeaderOffset : 24 dumpDTCRegisters : 0 #------------------------------------------------------------------------------ # reference channel to calculate dt(i) = T(0,i)-T(0,referenceChannel) diff --git a/otsdaq-mu2e-tracker/ArtModules/TrackerDQM_module.cc b/otsdaq-mu2e-tracker/ArtModules/TrackerDQM_module.cc index 81ecd11..c2977f5 100644 --- a/otsdaq-mu2e-tracker/ArtModules/TrackerDQM_module.cc +++ b/otsdaq-mu2e-tracker/ArtModules/TrackerDQM_module.cc @@ -209,7 +209,8 @@ void TrackerDQM::book_channel_histograms(art::TFileDirectory* Dir, int RunNumber // waveform histograms, assume number of samples < 30 //----------------------------------------------------------------------------- for (int j=0; jwf[j] = Dir->make(Form("h_wf_ch_%02i_%i",I,j),Form("run %06i: ch [%02i][%i] waveform",RunNumber,I,j),30, 0.,30.); + Hist->wf [j] = Dir->make(Form("h_wf_ch_%02i_%i",I,j) ,Form("run %06i: ch [%02i][%i] waveform" ,RunNumber,I,j),30, 0.,30.); + Hist->raw_wf[j] = Dir->make(Form("h_raw_wf_ch_%02i_%i",I,j),Form("run %06i: ch [%02i][%i] raw waveform",RunNumber,I,j),30, 0.,30.); } } @@ -410,7 +411,9 @@ void TrackerDQM::unpack_adc_waveform(mu2e::TrackerDataDecoder::TrackerDataPacket Wf[ 2] = reverseBits(Hit->ADC02); for (int i=0; iADC0); @@ -421,8 +424,8 @@ void TrackerDQM::unpack_adc_waveform(mu2e::TrackerDataDecoder::TrackerDataPacket Wf[loc+ 6] = reverseBits(ahit->ADC5); Wf[loc+ 7] = reverseBits(ahit->ADC6); Wf[loc+ 8] = reverseBits(ahit->ADC7A + (ahit->ADC7B << 6)); - Wf[loc+ 9] = reverseBits(ahit->ADC5); - Wf[loc+10] = reverseBits(ahit->ADC6); + Wf[loc+ 9] = reverseBits(ahit->ADC8); + Wf[loc+10] = reverseBits(ahit->ADC9); Wf[loc+11] = reverseBits(ahit->ADC10A + (ahit->ADC10B << 6)); Wf[loc+12] = reverseBits(ahit->ADC11); } @@ -566,12 +569,15 @@ void TrackerDQM::unpack_adc_waveform(mu2e::TrackerDataDecoder::TrackerDataPacket hch->wf[ih]->Reset(); for (int is=0; iswf[ih]->Fill(is,wform[is]); + hch->raw_wf[ih]->Fill(is,wform[is]+wpar->bl); } // also set bin errors to zero int nb = hch->wf[ih]->GetNbinsX(); for (int ib=0; ibwf[ih]->SetBinError(ib+1,0); hch->wf[ih]->SetOption("HIST"); + hch->raw_wf[ih]->SetBinError(ib+1,0); + hch->raw_wf[ih]->SetOption("HIST"); } //----------------------------------------------------------------------------- // reconstructed waveform parameters diff --git a/otsdaq-mu2e-tracker/ArtModules/TrackerDQM_module.hh b/otsdaq-mu2e-tracker/ArtModules/TrackerDQM_module.hh index e2e7834..a13c1c1 100644 --- a/otsdaq-mu2e-tracker/ArtModules/TrackerDQM_module.hh +++ b/otsdaq-mu2e-tracker/ArtModules/TrackerDQM_module.hh @@ -62,7 +62,7 @@ class TrackerDQM : public art::EDAnalyzer { kNPanelsPerPlane = 6, kNChannels = 96, kMaxNLinks = 6, - kMaxNHitsPerChannel = 15, + kMaxNHitsPerChannel = 10, kMaxNSamples = 30 }; @@ -100,7 +100,8 @@ class TrackerDQM : public art::EDAnalyzer { TH1F* qt; // tail charge Qt TH1F* qtq; // Qt/Q - TH1F* wf[kMaxNHitsPerChannel]; + TH1F* wf [kMaxNHitsPerChannel]; + TH1F* raw_wf[kMaxNHitsPerChannel]; }; //----------------------------------------------------------------------------- diff --git a/otsdaq-mu2e-tracker/Generators/CMakeLists.txt b/otsdaq-mu2e-tracker/Generators/CMakeLists.txt index f864780..91c45f3 100644 --- a/otsdaq-mu2e-tracker/Generators/CMakeLists.txt +++ b/otsdaq-mu2e-tracker/Generators/CMakeLists.txt @@ -12,25 +12,35 @@ add_subdirectory(ToyHW) install_headers() install_source() -cet_build_plugin(TrackerVST artdaq::commandableGenerator - LIBRARIES REG - artdaq_core_mu2e::artdaq-core-mu2e_Overlays - canvas::canvas - mu2e_pcie_utils::DTCInterface - ${XMLRPC_LIBRARIES} -) - -cet_build_plugin(TrackerBR artdaq::commandableGenerator - LIBRARIES REG - otsdaq_mu2e_tracker::otsdaq-mu2e-tracker_Ui - artdaq_core_mu2e::artdaq-core-mu2e_Overlays - canvas::canvas - mu2e_pcie_utils::DTCInterface - ${XMLRPC_LIBRARIES} -) - -target_include_directories(otsdaq-mu2e-tracker_Generators_TrackerVST_generator - PRIVATE ${XMLRPC_INCLUDE_DIRS}) - -target_include_directories(otsdaq-mu2e-tracker_Generators_TrackerBR_generator - PRIVATE ${XMLRPC_INCLUDE_DIRS}) +# cet_build_plugin(TrackerVST artdaq::commandableGenerator +# LIBRARIES REG +# artdaq_core_mu2e::artdaq-core-mu2e_Overlays +# canvas::canvas +# mu2e_pcie_utils::DTCInterface +# ${XMLRPC_LIBRARIES} +# ) + +set(MIDAS_LIBS "") +if( DEFINED $ENV{MIDASSYS}) + message(MIDASSYS defined: $ENV{MIDASSYS}) + set(MIDAS_LIBS midas) +endif() + +add_compile_definitions(USE_MIDAS) + +# cet_build_plugin(TrackerBR artdaq::commandableGenerator +# LIBRARIES REG +# otsdaq_mu2e_tracker::otsdaq-mu2e-tracker_Ui +# artdaq_core_mu2e::artdaq-core-mu2e_Overlays +# canvas::canvas +# mu2e_pcie_utils::DTCInterface +# ${XMLRPC_LIBRARIES} +# ${MIDAS_LIBS} +# # midas +# ) + +#target_include_directories(otsdaq-mu2e-tracker_Generators_TrackerVST_generator +# PRIVATE ${XMLRPC_INCLUDE_DIRS}) + +#target_include_directories(otsdaq-mu2e-tracker_Generators_TrackerBR_generator +# PRIVATE ${XMLRPC_INCLUDE_DIRS}) diff --git a/otsdaq-mu2e-tracker/Generators/TrackerBR_generator.cc b/otsdaq-mu2e-tracker/Generators/TrackerBR_generator.cc index ff8cb89..61ec5a1 100644 --- a/otsdaq-mu2e-tracker/Generators/TrackerBR_generator.cc +++ b/otsdaq-mu2e-tracker/Generators/TrackerBR_generator.cc @@ -28,6 +28,12 @@ #include "otsdaq-mu2e-tracker/Ui/DtcInterface.hh" +// #ifdef USE_MIDAS +// #include "midas.h" +// #include "utils/utils.hh" +// #include "utils/OdbInterface.hh" +// #ENDIF + #include #include #include @@ -52,24 +58,20 @@ namespace mu2e { // FHiCL-configurable variables. // C++ variable names are the FHiCL parameter names prepended with a "_" //----------------------------------------------------------------------------- - FragmentType const fragment_type_; // Type of fragment (see FragmentType.hh) - - std::chrono::steady_clock::time_point lastReportTime_; + std::string _artdaqLabel; + std::chrono::steady_clock::time_point _lastReportTime; std::chrono::steady_clock::time_point procStartTime_; - uint8_t _board_id; std::vector _fragment_ids; // handled by CommandableGenerator, but not a data member there int _debugLevel; size_t _nEventsDbg; int _pcieAddr; std::string _tfmHost; // used to send xmlrpc messages to - int _linkMask; + // int _linkMask; // 101:simulate data internally, DTC not used; default:0 int _readData; // 1: read data, 0: save empty fragment - int _resetROC; // 1: clear digis 2: also reset ROC every event int _readDTCRegisters; // 1: read and save the DTC registers - int _saveSPI; // int _printFreq; // printout frequency int _maxEventsPerSubrun; // int _readoutMode; // 0:digis; 1:ROC pattern (all defined externally); @@ -115,9 +117,9 @@ namespace mu2e { int readData (artdaq::FragmentPtrs& Frags, ulong& Timestamp); double _timeSinceLastSend() { - auto now = std::chrono::steady_clock::now(); - auto deltaw = std::chrono::duration_cast>>(now - lastReportTime_).count(); - lastReportTime_ = now; + auto now = std::chrono::steady_clock::now(); + auto deltaw = std::chrono::duration_cast>>(now - _lastReportTime).count(); + _lastReportTime = now; return deltaw; } @@ -150,7 +152,6 @@ std::vector mu2e::TrackerBR::fragmentIDs() { std::vector v; v.push_back(0); if (_readDTCRegisters) v.push_back(FragmentType::TRKDTC); - // if (_saveSPI) v.push_back(FragmentType::TRKSPI); return v; } @@ -158,36 +159,64 @@ std::vector mu2e::TrackerBR::fragmentIDs() { //----------------------------------------------------------------------------- // sim_mode="N" means real DTC //----------------------------------------------------------------------------- -mu2e::TrackerBR::TrackerBR(fhicl::ParameterSet const& ps) : CommandableFragmentGenerator(ps) - , fragment_type_ (toFragmentType("MU2E")) - , lastReportTime_ (std::chrono::steady_clock::now()) - , _fragment_ids (ps.get> ("fragment_ids" , std::vector())) // - , _debugLevel (ps.get ("debugLevel" , 0)) - , _nEventsDbg (ps.get ("nEventsDbg" , 100)) - , _pcieAddr (ps.get ("pcieAddr" , -1)) - , _tfmHost (ps.get ("tfmHost" )) // - , _linkMask (stoi(ps.get ("linkMask" ),0,16)) // - , _readData (ps.get ("readData" , 1)) // - , _saveSPI (ps.get ("saveSPI" , 1)) // - , _printFreq (ps.get ("printFreq" , 100)) // - , _maxEventsPerSubrun(ps.get ("maxEventsPerSubrun" , 10000)) // - , _readoutMode (ps.get ("readoutMode" , 1)) // +mu2e::TrackerBR::TrackerBR(fhicl::ParameterSet const& ps) + : CommandableFragmentGenerator(ps) + , _artdaqLabel (ps.get ("artdaqLabel" )) + , _lastReportTime (std::chrono::steady_clock::now()) + , _fragment_ids (ps.get> ("fragment_ids" , std::vector())) // + , _debugLevel (ps.get ("debugLevel" , 0)) + , _nEventsDbg (ps.get ("nEventsDbg" , 100)) + , _pcieAddr (ps.get ("pcieAddr" , -1)) + , _tfmHost (ps.get ("tfmHost" )) // + , _readData (ps.get ("readData" , 1)) // + , _printFreq (ps.get ("printFreq" , 100)) // + , _maxEventsPerSubrun(ps.get ("maxEventsPerSubrun" , 10000)) // + , _readoutMode (ps.get ("readoutMode" , 1)) // { - - TLOG(TLVL_INFO) << "TrackerBR_generator CONSTRUCTOR (1) readData:" << _readData; - printf("TrackerBR::TrackerBR readData=%i\n",_readData); + TLOG(TLVL_INFO) << "CONSTRUCTOR (1) readData:" << _readData; //----------------------------------------------------------------------------- // the BR interface should not be changing any settings, just read events // DTC is already initialized by the frontend, don't change anything ! +// for skip_init=true, the linkmask is not used. The board reader shouldn't even know +// about it, but it has to know about the DTC PCIE address //----------------------------------------------------------------------------- - bool skip_init(false); - _dtc_i = trkdaq::DtcInterface::Instance(_pcieAddr,_linkMask,skip_init); -// _dtc = new DTC(DTC_SimMode_NoCFO,_pcieAddr,_linkMask,"",false,""); - _dtc = _dtc_i->Dtc(); // new DTC(DTC_SimMode_Disabled,_pcieAddr,_linkMask,"",false,""); - - _dtc_i->InitExternalCFOReadoutMode(1); // daq_scripts::EdgeMode - // _dtc_i->RocConfigurePatternMode(); +// #ifdef USE_MIDAS +// //----------------------------------------------------------------------------- +// // figure out the PCIE address - nothing wrong with connecting to ODB and +// //----------------------------------------------------------------------------- +// HNDLE hDB; +// cm_get_experiment_database(&hDB, NULL); +// +// OdbInterface* odb_i = OdbInterface::Instance(hDB); +// std::string active_run_conf = odb_i->GetActiveRunConfig(hDB); +// HNDLE h_active_run_conf = odb_i->GetRunConfigHandle(hDB,active_run_conf); +// std::string rpc_host = get_short_host_name("local"); +// HNDLE h_daq_host_conf = odb_i->GetDaqHostHandle(hDB,h_active_run_conf,rpc_host); +// +// HNDLE h_component; +// KEY component; +// int ncomp(0); +// int pcie_addr(-1); +// for (int i=0; db_enum_key(hDB, h_daq_host_conf, i, &h_component) != DB_NO_MORE_SUBKEYS; ++i) { +// db_get_key(hDB, h_component, &component); +// TLOG(TLVL_DBG+1) << "index: " << " Subkey:" << component.name << " Type: " << component.type; +// if (component.name == _artdaqLabel) { +// //----------------------------------------------------------------------------- +// // the board reader configuration found, take the PCIE address from there +// //----------------------------------------------------------------------------- +// int sz(0); +// if (db_get_value(hDB, h_component, "DTC/PCIEAddress", &pcie_addr, &sz, TID_INT32, TRUE) != DB_SUCCESS) { +// TLOG(TLVL_ERROR) << "no PCIE address for" << component.name << " in" << active_run_conf ; +// } +// } +// } +// if (pcie_addr != -1) _pcieAddr = pcie_addr; +// #endif + + bool skip_init(true); + _dtc_i = trkdaq::DtcInterface::Instance(_pcieAddr,0x0,skip_init); + _dtc = _dtc_i->Dtc(); //----------------------------------------------------------------------------- // finally, initialize the environment for the XML-RPC messaging client //----------------------------------------------------------------------------- @@ -225,46 +254,8 @@ mu2e::TrackerBR::~TrackerBR() { //----------------------------------------------------------------------------- void mu2e::TrackerBR::stop() { - // _dtc->DisableDetectorEmulator(); - // _dtc->DisableCFOEmulation (); -} - -// //----------------------------------------------------------------------------- -// void mu2e::TrackerBR::print_dtc_registers(DTC* Dtc, const char* Header) { -// printf("---------------------- %s : DTC status :\n",Header); -// uint32_t res; -// int rc; -// rc = _device->read_register(0x9100,100,&res); printf("DTC status : 0x%08x rc:%i\n",res,rc); // expect: 0x40808404 -// rc = _device->read_register(0x91c8,100,&res); printf("debug packet type: 0x%08x rc:%i\n",res,rc); // expect: 0x00000000 -// } - -//----------------------------------------------------------------------------- -// print 16 bytes per line -// size - number of bytes to print, even -//----------------------------------------------------------------------------- -void mu2e::TrackerBR::printBuffer(const void* ptr, int sz) { - - int nw = sz/2; - ushort* p16 = (ushort*) ptr; - int n = 0; - - for (int i=0; i> subevents; // auto tmo_ms(1500); - TLOG(TLVL_INFO) << "------------- START TStamp=" << TStamp << std::endl; + TLOG(TLVL_DBG) << "------------- START TStamp=" << TStamp << std::endl; DTC_EventWindowTag event_tag = DTC_EventWindowTag(_tstamp); - // _dtc_i->PrintRocStatus(0); - try { //------------------------------------------------------------------------------ // sz: 1 (or 0, if nothing has been read out) //----------------------------------------------------------------------------- subevents = _dtc->GetSubEventData(event_tag,match_ts); int sz = subevents.size(); - TLOG(TLVL_INFO) << "read =" << sz << " DTC blocks" << std::endl; + TLOG(TLVL_DBG) << "read =" << sz << " DTC blocks" << std::endl; if (sz > 0) { _tstamp += 1; } @@ -303,7 +292,7 @@ int mu2e::TrackerBR::readData(artdaq::FragmentPtrs& Frags, ulong& TStamp) { TStamp = ew_tag; // hack - TLOG(TLVL_DBG+1) << "DTC block i: " << i<< " nbytes:" << nb << std::endl; + TLOG(TLVL_DBG) << "DTC block i: " << i<< " nbytes:" << nb << std::endl; nbytes += nb; if (nb > 0) { artdaq::Fragment* frag = new artdaq::Fragment(ev_counter(), _fragment_ids[0], FragmentType::TRK, TStamp); @@ -314,38 +303,16 @@ int mu2e::TrackerBR::readData(artdaq::FragmentPtrs& Frags, ulong& TStamp) { memcpy(afd,ev->GetRawBufferPointer(),nb); Frags.emplace_back(frag); - - if (nb >= 0x50) { -//----------------------------------------------------------------------------- -// patch format version - set it to 1 - do we still need to be going that ? -// looks that write to ROC r29 should've already accounted for that -//----------------------------------------------------------------------------- - struct DataHeaderPacket_t { - uint16_t nBytes; - uint16_t w2; - uint16_t nPackets; - uint16_t evtWindowTag[3]; - uint16_t w7; - uint16_t w8; - - void setVersion(int version) { w7 = (w7 & 0x00ff) + ((version & 0xff) << 8) ; } - void setStatus (int status ) { w7 = (w7 & 0xff00) + (status & 0xff) ; } - }; - - DataHeaderPacket_t* dhp = (DataHeaderPacket_t*) ((char*) afd + 0x40); - dhp->setVersion(1); - } //----------------------------------------------------------------------------- // this is essentially it, now - diagnostics //----------------------------------------------------------------------------- uint64_t ew_tag = ev->GetEventWindowTag().GetEventWindowTag(true); - // if ((_debugLevel > 0) and (ev_counter() < _nEventsDbg)) { - std::cout << " DTC: " << setw(2) << i << " EW tag:" - << setw(10) << ew_tag << " nbytes = " << setw(4) << nb << endl;; - printBuffer(ev->GetRawBufferPointer(),ev->GetSubEventByteCount()/2); - // } - rc = 0; + if ((_debugLevel > 0) and (ev_counter() < _nEventsDbg)) { + TLOG(TLVL_INFO) << " subevent:" << i << " EW tag:" << ew_tag << " nbytes: " << nb << std::endl; + _dtc_i->PrintBuffer(ev->GetRawBufferPointer(),ev->GetSubEventByteCount()/2); + } + rc = 0; } else { //----------------------------------------------------------------------------- @@ -355,20 +322,17 @@ int mu2e::TrackerBR::readData(artdaq::FragmentPtrs& Frags, ulong& TStamp) { message("alarm", "TrackerBR::ReadData::ERROR event="+std::to_string(ev_counter())+" nbytes=0") ; } } - if (_debugLevel > 0) std::cout << std::endl; - TLOG(TLVL_INFO) << "read data , NDTCs=" << sz << " nbytes=" << nbytes << std::endl; - // if (sz > 0) break; + TLOG(TLVL_DBG+1) << "read data , NDTCs=" << sz << " nbytes=" << nbytes << std::endl; } catch (...) { TLOG(TLVL_ERROR) << "ERROR reading data"; } - // } int print_event = (ev_counter() % _printFreq) == 0; if (print_event) { - TLOG(TLVL_INFO) << "event readSuccess timeout: nbytes\n" << ev_counter() << " " << readSuccess - << " " << timeout << " " << nbytes << std::endl; + TLOG(TLVL_DBG+1) << "event readSuccess timeout: nbytes\n" << ev_counter() << " " << readSuccess + << " " << timeout << " " << nbytes << std::endl; } return rc; @@ -380,12 +344,12 @@ bool mu2e::TrackerBR::readEvent(artdaq::FragmentPtrs& Frags) { //----------------------------------------------------------------------------- // read data //----------------------------------------------------------------------------- - TLOG(TLVL_INFO) << "start" << std::endl; + TLOG(TLVL_DBG) << "start" << std::endl; _dtc->GetDevice()->ResetDeviceTime(); //----------------------------------------------------------------------------- // a hack : reduce the PMT logfile size //----------------------------------------------------------------------------- -// int print_event = (ev_counter() % _printFreq) == 0; +// int print_event = (ev_counter() % _printFreq) == 0; // make sure even a fake fragment goes in //----------------------------------------------------------------------------- ulong tstamp = CommandableFragmentGenerator::ev_counter(); @@ -407,7 +371,7 @@ bool mu2e::TrackerBR::readEvent(artdaq::FragmentPtrs& Frags) { Frags.emplace_back(f1); } - TLOG(TLVL_INFO) << "bufferes released, end" << std::endl; + TLOG(TLVL_DBG) << "bufferes released, end" << std::endl; return true; } @@ -468,7 +432,7 @@ bool mu2e::TrackerBR::simulateEvent(artdaq::FragmentPtrs& Frags) { bool mu2e::TrackerBR::getNext_(artdaq::FragmentPtrs& Frags) { bool rc(true); - TLOG(TLVL_DEBUG) << "event: " << ev_counter() << "STARTING"; + TLOG(TLVL_DBG) << "event: " << ev_counter() << "STARTING"; //----------------------------------------------------------------------------- // in the beginning, send message to the Farm manager //----------------------------------------------------------------------------- diff --git a/otsdaq-mu2e-tracker/Generators/TrackerVST001_generator.CC b/otsdaq-mu2e-tracker/Generators/TrackerVST001_generator.CC deleted file mode 100644 index 180eb4e..0000000 --- a/otsdaq-mu2e-tracker/Generators/TrackerVST001_generator.CC +++ /dev/null @@ -1,969 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// P.Murat: test version, implements multiple DTC read tests -// test2: test_buffer in async mode -// test3: test_buffer in sync mode -// test4: read_digi -/////////////////////////////////////////////////////////////////////////////// -#include "artdaq/DAQdata/Globals.hh" - -#define TRACE_NAME (app_name + "_TrackerVST001").c_str() - -#include "canvas/Utilities/Exception.h" - -#include "artdaq-core/Utilities/SimpleLookupPolicy.hh" -#include "artdaq/Generators/GeneratorMacros.hh" -#include "cetlib_except/exception.h" -#include "fhiclcpp/ParameterSet.h" -#include "artdaq-core-mu2e/Overlays/FragmentType.hh" - -// #include "artdaq-core-mu2e/Overlays/mu2eFragmentWriter.hh" - -#include -#include -#include -#include -#include - -#include - -// TrackerVST001 is designed to call the DTCInterfaceLibrary a certain number of times -// (set in the mu2eFragment header) and pack that data into DTCFragments contained -// in a single mu2eFragment object. - -// Some C++ conventions used: - -// -Append a "_" to every private member function and variable - -#include "artdaq-core/Data/Fragment.hh" -#include "artdaq/Generators/CommandableFragmentGenerator.hh" -#include "fhiclcpp/fwd.h" -#include "artdaq-core-mu2e/Overlays/FragmentType.hh" - -#include "dtcInterfaceLib/DTC.h" -#include "dtcInterfaceLib/DTCSoftwareCFO.h" - -#include -#include -#include -#include -#include - -using namespace DTCLib; - -namespace mu2e { - class TrackerVST001 : public artdaq::CommandableFragmentGenerator { - public: - explicit TrackerVST001(fhicl::ParameterSet const& ps); - virtual ~TrackerVST001(); - - private: - // The "getNext_" function is used to implement user-specific - // functionality; it's a mandatory override of the pure virtual - // getNext_ function declared in CommandableFragmentGenerator - - bool getNext_ (artdaq::FragmentPtrs& output) override; - - bool sendEmpty_(artdaq::FragmentPtrs& output); - - void start () override {} - void stopNoMutex() override {} - void stop () override; - - void readSimFile_(std::string sim_file); - mu2e_databuff_t* readDTCBuffer(mu2edev* device, bool& success, bool& timeout, size_t& sts, bool continuedMode); - - void print_roc_registers(); - void print_dtc_registers(DTC* Dtc, const char* Header); - void printBuffer(const void* ptr, int sz); -//----------------------------------------------------------------------------- -// clones of Monica's scripts -//----------------------------------------------------------------------------- - void monica_digi_clear (DTC* Dtc); - void monica_var_link_config (DTC* Dtc); - void monica_var_pattern_config (DTC* Dtc); - - void buffer_test_002 (artdaq::FragmentPtrs& frags); - void buffer_test_003 (artdaq::FragmentPtrs& frags); - void buffer_test_004 (artdaq::FragmentPtrs& frags); - - // different tests - - void test_002 (artdaq::FragmentPtrs& frags); - void test_003 (artdaq::FragmentPtrs& frags); - void test_004 (artdaq::FragmentPtrs& frags); - - // Like "getNext_", "fragmentIDs_" is a mandatory override; it - // returns a vector of the fragment IDs an instance of this class - // is responsible for (in the case of TrackerVST001, this is just - // the fragment_id_ variable declared in the parent - // CommandableFragmentGenerator class) - - std::vector fragmentIDs_() { return fragment_ids_; } - - // FHiCL-configurable variables. Note that the C++ variable names - // are the FHiCL variable names with a "_" appended - - FragmentType const fragment_type_; // Type of fragment (see FragmentType.hh) - - std::vector fragment_ids_; - - // State - size_t timestamps_read_; - size_t highest_timestamp_seen_{0}; - size_t timestamp_loops_{0}; // For playback mode, so that we continually generate unique timestamps - DTC_SimMode _sim_mode; - uint8_t board_id_; - bool simFileRead_; - bool rawOutput_; - std::string rawOutputFile_; - std::ofstream rawOutputStream_; - size_t nSkip_; - bool sendEmpties_; - int _debugLevel; - size_t _nEvents; // n(events) to dump - - - std::string _test; - size_t request_delay_; - size_t _requestsAhead; - size_t _heartbeatsAfter; - int _heartbeatInterval; - int _dtc_id; - uint _roc_mask; - // hardware - DTC* _dtc; - mu2edev* _device; - DTCSoftwareCFO* _cfo; - - int _firstTime; - uint _nbuffers; - uint _ievent; - - std::chrono::steady_clock::time_point lastReportTime_; - std::chrono::steady_clock::time_point procStartTime_; - - double _timeSinceLastSend() { - auto now = std::chrono::steady_clock::now(); - auto deltaw = std::chrono::duration_cast>>(now - lastReportTime_).count(); - lastReportTime_ = now; - return deltaw; - } - - void _startProcTimer() { procStartTime_ = std::chrono::steady_clock::now(); } - - double _getProcTimerCount() { - auto now = std::chrono::steady_clock::now(); - auto deltaw = std::chrono::duration_cast>>(now - procStartTime_).count(); - return deltaw; - } - }; -} // namespace mu2e - -//----------------------------------------------------------------------------- -// the FHICL structure passed is fragment_receiver: {} -// no defaults in FCL -//----------------------------------------------------------------------------- -mu2e::TrackerVST001::TrackerVST001(fhicl::ParameterSet const& ps) : - CommandableFragmentGenerator(ps) - , fragment_type_ (toFragmentType("MU2E")) - , fragment_ids_ {static_cast(fragment_id())} - , timestamps_read_ (0) - , _sim_mode (DTC_SimModeConverter::ConvertToSimMode(ps.get("sim_mode", "Disabled"))) - , board_id_ (static_cast(ps.get("board_id", 0))) - , rawOutput_ (ps.get ("rawOutput" )) - , rawOutputFile_ (ps.get ("rawOutputFile" )) - , nSkip_ (ps.get ("nSkip" )) - , sendEmpties_ (ps.get ("sendEmpties" )) - , _debugLevel (ps.get ("debugLevel" )) - , _nEvents (ps.get ("nEvents" )) // default: 1 - , _test (ps.get ("test" )) // type of the test, default : "test2" - , request_delay_ (ps.get ("request_delay" )) - , _requestsAhead (ps.get ("requestsAhead" )) // default: 1 - , _heartbeatsAfter (ps.get ("heartbeatsAfter")) // default: 16 - , _heartbeatInterval(ps.get ("heartbeatInterval")) - , _dtc_id (ps.get ("dtc_id" )) // default: -1 - , _roc_mask (ps.get ("roc_mask" )) // default: 0x1 - , lastReportTime_ (std::chrono::steady_clock::now() ) - { - - TLOG(TLVL_DEBUG) << "TrackerVST001_generator CONSTRUCTOR"; - // _sim_mode can still be overridden by environment! - - _ievent = 0; -//----------------------------------------------------------------------------- -// _dtc_id = -1 : use $DTCLIB_DTC to determine the DTC's PCI ID -//----------------------------------------------------------------------------- - _dtc = new DTC(_sim_mode,_dtc_id,_roc_mask,""); - _device = _dtc->GetDevice(); - - // false, - // ps.get("simulator_memory_file_name","mu2esim.bin")); - _dtc->SetSequenceNumberDisable(); - - - bool useCFOEmulator (true); - unsigned packetCount (0); - DTC_DebugType debugType (DTC_DebugType_SpecialSequence); - bool stickyDebugType(true); - bool quiet (true); // was false - bool forceNoDebug (true) ; // (false); - bool useCFODRP (false); // was (true); - - TLOG(TLVL_DEBUG) << "useCFOEmulator, packetCount, debugType, stickyDebugType, quiet, forceNoDebug, useCFODRP:" - << useCFOEmulator << " " << packetCount << " " << debugType << " " << stickyDebugType - << " " << quiet << " " << forceNoDebug << " " << useCFODRP ; - - print_dtc_registers(_dtc,"buffer_test 000"); - - _cfo = new DTCSoftwareCFO(_dtc, useCFOEmulator, packetCount, debugType, stickyDebugType, quiet, false, forceNoDebug, useCFODRP); - - TLOG(TLVL_INFO) << "P,Murat: VST board reader created" ; - } - -//----------------------------------------------------------------------------- -void mu2e::TrackerVST001::readSimFile_(std::string sim_file) { - TLOG(TLVL_INFO) << "Starting read of simulation file " << sim_file << "." - << " Please wait to start the run until finished."; - _dtc->WriteSimFileToDTC(sim_file, true, true); - simFileRead_ = true; - TLOG(TLVL_INFO) << "Done reading simulation file into DTC memory."; -} - -//----------------------------------------------------------------------------- -mu2e::TrackerVST001::~TrackerVST001() { - rawOutputStream_.close(); - delete _cfo; - delete _dtc; -} - -//----------------------------------------------------------------------------- -void mu2e::TrackerVST001::stop() { - // _dtc->DisableDetectorEmulator(); - // _dtc->DisableCFOEmulation(); -} - -//----------------------------------------------------------------------------- -bool mu2e::TrackerVST001::getNext_(artdaq::FragmentPtrs& Frags) { - bool rc(true); - - printf("----------------------- mu2e::TrackerVST001::%s : event : %10i\n",__func__,_ievent); - - if (should_stop()) return false; - - // _startProcTimer(); - - if (_test == "test_002") { -//----------------------------------------------------------------------------- -// this is a syncronous read, need only one call -// it also looks that by using _nEvents I'm duplicating the existing functionality, -// if so, need to get rid of that -//----------------------------------------------------------------------------- - test_002(Frags); - _ievent += 1; - rc = false; - } - else if (_test == "test_003") { - test_003(Frags); - _ievent += 1; - // rc = (_nEvents > 0) and (_ievent < _nEvents); - } - else if (_test == "test_004") { - test_004(Frags); - _ievent += 1; - // rc = (_nEvents > 0) and (_ievent < _nEvents); - } - else { - printf("ERROR: undefined test mode: %s, STOP\n",_test.data()); - rc = false; - } - - ev_counter_inc(); - - TLOG(TLVL_DEBUG) << __func__ << ": end of getNext_, return " << rc; - return rc; -} - -//----------------------------------------------------------------------------- -bool mu2e::TrackerVST001::sendEmpty_(artdaq::FragmentPtrs& frags) { - frags.emplace_back(new artdaq::Fragment()); - frags.back()->setSystemType(artdaq::Fragment::EmptyFragmentType); - frags.back()->setSequenceID(ev_counter()); - frags.back()->setFragmentID(fragment_ids_[0]); - ev_counter_inc(); - return true; -} - -//----------------------------------------------------------------------------- -void mu2e::TrackerVST001::print_dtc_registers(DTC* Dtc, const char* Header) { - printf("---------------------- %s : DTC status :\n",Header); - uint32_t res; - int rc; - rc = Dtc->GetDevice()->read_register(0x9100,100,&res); printf(" 0x9100: status : 0x%08x rc:%i\n",res,rc); - rc = Dtc->GetDevice()->read_register(0x91c8,100,&res); printf(" 0x91c8: debug packet type: 0x%08x rc:%i\n",res,rc); -} - -//----------------------------------------------------------------------------- -void mu2e::TrackerVST001::monica_digi_clear(DTCLib::DTC* Dtc) { -//----------------------------------------------------------------------------- -// Monica's digi_clear -// this will proceed in 3 steps each for HV and CAL DIGIs: -// 1) pass TWI address and data toTWI controller (fiber is enabled by default) -// 2) write TWI INIT high -// 3) write TWI INIT low -//----------------------------------------------------------------------------- - Dtc->WriteROCRegister(DTCLib::DTC_Link_0,28,0x10,false,1000); // - - // Writing 0 & 1 to address=16 for HV DIGIs ??? - - Dtc->WriteROCRegister(DTCLib::DTC_Link_0,27,0x00,false,1000); // write 0 - Dtc->WriteROCRegister(DTCLib::DTC_Link_0,26,0x01,false,1000); // toggle INIT - Dtc->WriteROCRegister(DTCLib::DTC_Link_0,26,0x00,false,1000); // - - Dtc->WriteROCRegister(DTCLib::DTC_Link_0,27,0x01,false,1000); // write 1 - Dtc->WriteROCRegister(DTCLib::DTC_Link_0,26,0x01,false,1000); // toggle INIT - Dtc->WriteROCRegister(DTCLib::DTC_Link_0,26,0x00,false,1000); // - - // echo "Writing 0 & 1 to address=16 for CAL DIGIs" - Dtc->WriteROCRegister(DTCLib::DTC_Link_0,25,0x10,false,1000); // - - Dtc->WriteROCRegister(DTCLib::DTC_Link_0,24,0x00,false,1000); // write 0 - Dtc->WriteROCRegister(DTCLib::DTC_Link_0,23,0x01,false,1000); // toggle INIT - Dtc->WriteROCRegister(DTCLib::DTC_Link_0,23,0x00,false,1000); // - - Dtc->WriteROCRegister(DTCLib::DTC_Link_0,24,0x01,false,1000); // write 1 - Dtc->WriteROCRegister(DTCLib::DTC_Link_0,23,0x01,false,1000); // toggle INIT - Dtc->WriteROCRegister(DTCLib::DTC_Link_0,23,0x00,false,1000); // -} - -//----------------------------------------------------------------------------- -void mu2e::TrackerVST001::monica_var_link_config(DTCLib::DTC* Dtc) { - mu2edev* dev = Dtc->GetDevice(); - - dev->write_register(0x91a8,100,0); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - Dtc->WriteROCRegister(DTCLib::DTC_Link_0,14, 1,false,1000); // reset ROC - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - Dtc->WriteROCRegister(DTCLib::DTC_Link_0, 8,0x030f,false,1000); // configure ROC to read all 4 lanes - std::this_thread::sleep_for(std::chrono::milliseconds(100)); -} - - -//----------------------------------------------------------------------------- -void mu2e::TrackerVST001::monica_var_pattern_config(DTC* Dtc) { - TLOG(TLVL_DEBUG) << "---------------------------------- operation \"var_patern_config\"" << std::endl; - - // auto startTime = std::chrono::steady_clock::now(); - - print_dtc_registers(Dtc,"var_pattern_config 001"); // debug - - mu2edev* dev = Dtc->GetDevice(); - - dev->ResetDeviceTime(); - - dev->write_register(0x91a8,100,0); // _CFOEmulation_HeartbeatInterval); - sleep(1); - - int tmo_ms (1500); // 1500 is OK - int sleep_time( 100); // 300 is OK - - Dtc->WriteROCRegister(DTC_Link_0,14,0x01,false,tmo_ms); // this seems to be a reset - std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time)); - - Dtc->WriteROCRegister(DTC_Link_0, 8,0x10,false,tmo_ms); - std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time)); - - Dtc->WriteROCRegister(DTC_Link_0,30,0x00,false,tmo_ms); - std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time)); - - print_dtc_registers(Dtc,"var_pattern_config 002"); // debug -} - - -//----------------------------------------------------------------------------- -// this is a clone of Monica's var_read_all.sh script -//----------------------------------------------------------------------------- -void mu2e::TrackerVST001::print_roc_registers() { - TLOG(TLVL_DEBUG) << "---------------------------------- operation \"print_roc_registers\"" << std::endl; - - // auto startTime = std::chrono::steady_clock::now(); - - // Monica starts from disabling EWM's : my_cntl write 0x91a8 0x0 - - uint32_t hb_interval; - int rc = _device->read_register(0x91a8,100,&hb_interval); // DTC_Register_CFOEmulation_HeartbeatInterval - - TLOG(TLVL_DEBUG) << "-------------- mu2e::TrackerVst::" << __func__ - << " hb_interval=" << hb_interval << "rc:" << rc; - - // Try to comment out _dtc->WriteRegister_(0,DTC_Register_CFOEmulation_HeartbeatInterval); // 0x91a8 - - // step 1 : read everything : registers 0,8,18,23-59,64,65 - - roc_data_t r[256]; - - int tmo_ms(10); - - r[ 0] = _dtc->ReadROCRegister(DTC_Link_0, 0,tmo_ms); - r[ 8] = _dtc->ReadROCRegister(DTC_Link_0, 8,tmo_ms); - r[18] = _dtc->ReadROCRegister(DTC_Link_0,18,tmo_ms); - - for (int i=23; i<60; i++) { - r[i] = _dtc->ReadROCRegister(DTC_Link_0, i,tmo_ms); - } - - r[64] = _dtc->ReadROCRegister(DTC_Link_0,64,tmo_ms); - r[65] = _dtc->ReadROCRegister(DTC_Link_0,65,tmo_ms); -//----------------------------------------------------------------------------- -// now the hard part - formatted printout -//----------------------------------------------------------------------------- - int w1 = (r[24]<<16) | r[23] ; - int w2 = (r[26]<<16) | r[25] ; - int n_evm_seen = (r[65]<<16) | r[64] ; - int n_hbt_seen = (r[28]<<16) | r[27] ; - int n_null_hbt = (r[30]<<16) | r[29] ; - int n_hbt_hold = (r[32]<<16) | r[31] ; - int n_prefetch = (r[34]<<16) | r[33] ; - int n_data_req = (r[36]<<16) | r[35] ; - int n_data_req_read_ddr = (r[38]<<16) | r[37] ; - int n_data_req_sent_dtc = (r[40]<<16) | r[39] ; - int n_data_req_null_dat = (r[42]<<16) | r[41] ; - int last_spill_tag = (r[44]<<16) | r[43] ; - int last_hb_tag = (r[46]<<16) | r[45] ; - int last_prefetch_tag = (r[49]<<16) | r[48] ; - int last_fetched_tag = (r[52]<<16) | r[51] ; - int last_data_req_tag = (r[55]<<16) | r[54] ; - int last_offset_tag = (r[58]<<16) | r[57] ; - - TLOG(TLVL_DEBUG) << "--------------------------------" << std::endl - << "ROC registers:" - << " reg[ 0]: 0x" << std::hex << r[ 0] - << " reg[ 8]: 0x" << std::hex << r[ 8] - << " reg[18]: 0x" << std::hex << r[18] - << std::endl - << "SIZE_FIFO_FULL [28]+STORE_POS[25:24]+STORE_CNT[19:0]: 0x" << std::hex << w1 - << std::endl - << "SIZE_FIFO_EMPTY[28]+FETCH_POS[25:24]+FETCH_CNT[19:0]: 0x" << std::hex << w2 - << std::endl - << "N(EWM) seen : " << std::dec << n_evm_seen - << std::endl - << "N(HBT) seen : " << n_hbt_seen - << std::endl - << "N(null HBT) seen : " << n_null_hbt - << std::endl - << "N(HBT on hold) : " << n_hbt_hold - << std::endl - << "N(prefetch) : " << n_prefetch - << std::endl - << "N(data req) : " << n_data_req - << std::endl - << "N(data req read DDR): " << n_data_req_read_ddr - << std::endl - << "N(data req sent DTC): " << n_data_req_sent_dtc - << std::endl - << "N(data req null dat): " << n_data_req_null_dat - << std::endl - << "Last spill tag : 0x" << std::hex << last_spill_tag - << std::endl - << "Last HB tag : 0x" << std::hex << last_hb_tag - << std::endl - << "Last prefetch tag : 0x" << std::hex << last_prefetch_tag - << std::endl - << "Last fetched tag : 0x" << std::hex << last_fetched_tag - << std::endl - << "Last data req tag : 0x" << std::hex << last_data_req_tag - << std::endl - << "Last offset tag : 0x" << std::hex << last_offset_tag - ; - -} - -//----------------------------------------------------------------------------- -void mu2e::TrackerVST001::buffer_test_002(artdaq::FragmentPtrs& frags) { - - TLOG(TLVL_DEBUG) << "---------------------------------- operation \"buffer_test\"" << std::endl; - auto startTime = std::chrono::steady_clock::now(); - - auto initTime = _device->GetDeviceTime(); - _device->ResetDeviceTime(); - auto afterInit = std::chrono::steady_clock::now(); - - print_dtc_registers(_dtc,"buffer_test 001"); - - std::string timestampFile = ""; - - bool incrementTimestamp(true); - unsigned long timestampOffset = 1; - // unsigned cfodelay (200); - int _requestsAhead ( 0); - bool syncRequests = false; - - TLOG(TLVL_DEBUG) << "_nEvents, timestampOffset, incrementTimestamp,_heartbeatInterval,_requestsAhead,_heartbeatsAfter:" - << _nEvents << " " << timestampOffset << " " << incrementTimestamp << " " << _heartbeatInterval << " " - << _requestsAhead << " " << _heartbeatsAfter; - TLOG(TLVL_DEBUG) << "syncRequests:" << syncRequests; - - _cfo->SendRequestsForRange(_nEvents, - DTC_EventWindowTag(timestampOffset), - incrementTimestamp, - _heartbeatInterval, - _requestsAhead, - _heartbeatsAfter); - - auto readoutRequestTime = _device->GetDeviceTime(); - _device->ResetDeviceTime(); - - auto afterRequests = std::chrono::steady_clock::now(); - - print_dtc_registers(_dtc,"buffer_test 002"); - - // unsigned quietCount (5); // was 0 - // bool reallyQuiet (false); - - bool stopOnTimeout (false); - bool checkSERDES (false); - unsigned extraReads (1); - - for (unsigned ii = 0; ii < _nEvents + extraReads; ++ii) { - if (syncRequests && ii < _nEvents) { - auto startRequest = std::chrono::steady_clock::now(); - _cfo->SendRequestForTimestamp(DTC_EventWindowTag(timestampOffset + (incrementTimestamp ? ii : 0), _heartbeatsAfter)); - auto endRequest = std::chrono::steady_clock::now(); - readoutRequestTime += std::chrono::duration_cast>>(endRequest - startRequest).count(); - } - TLOG(TLVL_DEBUG) << "Reading buffer " << std::dec << ii << std::endl; - - bool readSuccess = false; - bool timeout = false; - size_t sts = 0; - - print_dtc_registers(_dtc,"buffer_test 003"); - - mu2e_databuff_t* buffer = readDTCBuffer(_device, readSuccess, timeout, sts, false); - - printf("BUFFER %5i read, sts=%5li readSuccess=%i timeout=%i\n",ii,sts,readSuccess,timeout); - - print_dtc_registers(_dtc,"buffer_test 004"); - - if (!readSuccess && checkSERDES) break; - else if (!readSuccess) continue; - - if (stopOnTimeout && timeout) { - TLOG(TLVL_ERROR) << "Timeout detected and stop-on-timeout mode enabled. Stopping after " << ii << " events!"; - break; - } - - DTCLib::Utilities::PrintBuffer(buffer, sts, 0); - - _device->read_release(DTC_DMA_Engine_DAQ, 1); - usleep(200); - - print_dtc_registers(_dtc,"buffer_test 005"); - } - - _device->release_all(DTC_DMA_Engine_DAQ); - - print_dtc_registers(_dtc,"buffer_test 006"); - - auto totalBytesRead = _device->GetReadSize(); - auto totalBytesWritten = _device->GetWriteSize(); - - auto readDevTime = _device->GetDeviceTime(); - auto doneTime = std::chrono::steady_clock::now(); - auto totalTime = std::chrono::duration_cast>>(doneTime - startTime).count(); - auto totalInitTime = std::chrono::duration_cast>>(afterInit - startTime).count(); - auto totalRequestTime = std::chrono::duration_cast>>(afterRequests - afterInit).count(); - auto totalReadTime = std::chrono::duration_cast>>(doneTime - afterRequests).count(); - - TLOG(TLVL_INFO) << "Total Elapsed Time: " << Utilities::FormatTimeString(totalTime) << "." << std::endl - << "Total Init Time: " << Utilities::FormatTimeString(totalInitTime) << "." << std::endl - << "Total Readout Request Time: " << Utilities::FormatTimeString(totalRequestTime) << "." << std::endl - << "Total Read Time: " << Utilities::FormatTimeString(totalReadTime) << "." << std::endl; - - TLOG(TLVL_INFO) << "Device Init Time: " << Utilities::FormatTimeString(initTime) << "." << std::endl - << "Device Request Time: " << Utilities::FormatTimeString(readoutRequestTime) << "." << std::endl - << "Device Read Time: " << Utilities::FormatTimeString(readDevTime) << "." << std::endl; - - TLOG(TLVL_INFO) << "Total Bytes Written: " << Utilities::FormatByteString(static_cast(totalBytesWritten), "") - << "." << std::endl - << "Total Bytes Read: " << Utilities::FormatByteString(static_cast(totalBytesRead), "") << "." - << std::endl; - - TLOG(TLVL_INFO) << "Total PCIe Rate: " - << Utilities::FormatByteString((totalBytesWritten + totalBytesRead) / totalTime, "/s") << std::endl - << "Read Rate: " << Utilities::FormatByteString(totalBytesRead / totalReadTime, "/s") << std::endl - << "Device Read Rate: " << Utilities::FormatByteString(totalBytesRead / readDevTime, "/s") << std::endl; -} - -//----------------------------------------------------------------------------- -// buffer_test in sync mode : syncRequests = true -//----------------------------------------------------------------------------- -void mu2e::TrackerVST001::buffer_test_003(artdaq::FragmentPtrs& frags) { - TLOG(TLVL_DEBUG) << "---------------------------------- operation \"__func__\"" << std::endl; - auto startTime = std::chrono::steady_clock::now(); - - auto initTime = _device->GetDeviceTime(); - _device->ResetDeviceTime(); - auto afterInit = std::chrono::steady_clock::now(); - - // bool useCFOEmulator (true); - // unsigned packetCount (0); - // DTC_DebugType debugType (DTC_DebugType_SpecialSequence); - // bool stickyDebugType(true); - // bool quiet (true); // was false - unsigned quietCount (5); // was 0 - // bool reallyQuiet (false); - // bool forceNoDebug (true ); // (false); - // bool useCFODRP (false); // was (true); - - uint number (1 ); // for test3 this is essential - bool stopOnTimeout (false); - bool checkSERDES (false); - - // TLOG(TLVL_DEBUG) << "useCFOEmulator, packetCount, debugType, stickyDebugType, quiet, forceNoDebug, useCFODRP:" - // << useCFOEmulator << " " << packetCount << " " << debugType << " " << stickyDebugType - // << " " << quiet << " " << forceNoDebug << " " << useCFODRP ; - - print_dtc_registers(_dtc,"buffer_test_003 000"); - - std::string timestampFile = ""; - - bool incrementTimestamp(true); - unsigned long timestampOffset = 1; - unsigned cfodelay (200); - int _requestsAhead ( 0); - unsigned _heartbeatsAfter(16); - bool syncRequests = true; - - TLOG(TLVL_DEBUG) << "number, timestampOffset, incrementTimestamp,cfodelay,_requestsAhead,_heartbeatsAfter:" - << number << " " << timestampOffset << " " << incrementTimestamp << " " << cfodelay << " " - << _requestsAhead << " " << _heartbeatsAfter; - TLOG(TLVL_DEBUG) << "syncRequests:" << syncRequests; - - - auto readoutRequestTime = _device->GetDeviceTime(); - _device->ResetDeviceTime(); - - auto afterRequests = std::chrono::steady_clock::now(); - - print_dtc_registers(_dtc,"buffer_test_003 002"); - - unsigned extraReads (1); - for (unsigned ii = 0; ii < number + extraReads; ++ii) { - if (syncRequests && ii < number) { - auto startRequest = std::chrono::steady_clock::now(); - _cfo->SendRequestForTimestamp(DTC_EventWindowTag(timestampOffset + (incrementTimestamp ? ii : 0), _heartbeatsAfter)); - auto endRequest = std::chrono::steady_clock::now(); - readoutRequestTime += std::chrono::duration_cast>>(endRequest - startRequest).count(); - } - TLOG(TLVL_DEBUG) << "Reading buffer " << std::dec << ii << std::endl; - - bool readSuccess = false; - bool timeout = false; - size_t sts = 0; - - print_dtc_registers(_dtc,"buffer_test_003 003"); - - mu2e_databuff_t* buffer = readDTCBuffer(_device, readSuccess, timeout, sts, false); - - printf("BUFFER %5i read, sts=%5li readSuccess=%i timeout=%i\n",ii,sts,readSuccess,timeout); - - print_dtc_registers(_dtc,"buffer_test_003 004"); - - if (!readSuccess && checkSERDES) break; - else if (!readSuccess) continue; - - if (stopOnTimeout && timeout) { - TLOG(TLVL_ERROR) << "Timeout detected and stop-on-timeout mode enabled. Stopping after " << ii << " events!"; - break; - } - - DTCLib::Utilities::PrintBuffer(buffer, sts, quietCount); - - _device->read_release(DTC_DMA_Engine_DAQ, 1); - usleep(200); - - print_dtc_registers(_dtc,"buffer_test_003 005"); - } - - _device->release_all(DTC_DMA_Engine_DAQ); - - print_dtc_registers(_dtc,"buffer_test3 006"); - - auto totalBytesRead = _device->GetReadSize(); - auto totalBytesWritten = _device->GetWriteSize(); - - auto readDevTime = _device->GetDeviceTime(); - auto doneTime = std::chrono::steady_clock::now(); - auto totalTime = std::chrono::duration_cast>>(doneTime - startTime).count(); - auto totalInitTime = std::chrono::duration_cast>>(afterInit - startTime).count(); - auto totalRequestTime = std::chrono::duration_cast>>(afterRequests - afterInit).count(); - auto totalReadTime = std::chrono::duration_cast>>(doneTime - afterRequests).count(); - - TLOG(TLVL_INFO) << "Total Elapsed Time: " << Utilities::FormatTimeString(totalTime) << "." << std::endl - << "Total Init Time: " << Utilities::FormatTimeString(totalInitTime) << "." << std::endl - << "Total Readout Request Time: " << Utilities::FormatTimeString(totalRequestTime) << "." << std::endl - << "Total Read Time: " << Utilities::FormatTimeString(totalReadTime) << "." << std::endl; - - TLOG(TLVL_INFO) << "Device Init Time: " << Utilities::FormatTimeString(initTime) << "." << std::endl - << "Device Request Time: " << Utilities::FormatTimeString(readoutRequestTime) << "." << std::endl - << "Device Read Time: " << Utilities::FormatTimeString(readDevTime) << "." << std::endl; - - TLOG(TLVL_INFO) << "Total Bytes Written: " << Utilities::FormatByteString(static_cast(totalBytesWritten), "") - << "." << std::endl - << "Total Bytes Read: " << Utilities::FormatByteString(static_cast(totalBytesRead), "") << "." - << std::endl; - - TLOG(TLVL_INFO) << "Total PCIe Rate: " - << Utilities::FormatByteString((totalBytesWritten + totalBytesRead) / totalTime, "/s") << std::endl - << "Read Rate: " << Utilities::FormatByteString(totalBytesRead / totalReadTime, "/s") << std::endl - << "Device Read Rate: " << Utilities::FormatByteString(totalBytesRead / readDevTime, "/s") << std::endl; -} - - -//----------------------------------------------------------------------------- -// buffer_test_004: read data in sync mode -//----------------------------------------------------------------------------- -void mu2e::TrackerVST001::buffer_test_004(artdaq::FragmentPtrs& Frags) { - uint32_t res; - int rc; - - TLOG(TLVL_DEBUG) << "---------------------------------- operation \"__func__\"" << std::endl; - - _device->ResetDeviceTime(); - - if (_debugLevel > 0) print_dtc_registers(_dtc,"buffer_test_003 000"); - - std::string timestampFile = ""; - - bool incrementTimestamp(true); - unsigned long timestampOffset = 1; - unsigned cfodelay (200); - int delay = 200; // 500 was OK; - - TLOG(TLVL_DEBUG) << "timestampOffset, incrementTimestamp,cfodelay,_requestsAhead,_heartbeatsAfter:" - << " " << timestampOffset << " " << incrementTimestamp << " " << cfodelay << " " - << _requestsAhead << " " << _heartbeatsAfter; - - _device->ResetDeviceTime(); - - if (_debugLevel > 0) print_dtc_registers(_dtc,"buffer_test_003 002"); -//----------------------------------------------------------------------------- -// each time read just one event -//----------------------------------------------------------------------------- - // for (int i=0; i<1; i++) { - monica_digi_clear (_dtc); - monica_var_link_config(_dtc); -//----------------------------------------------------------------------------- -// back to the time window of 25.6 us 0x400 = 1024 (x25 ns) -//----------------------------------------------------------------------------- - _device->write_register(0x91a8,100,_heartbeatInterval); - - int nev = 1; - _cfo->SendRequestsForRange(nev,DTC_EventWindowTag(uint64_t(_ievent)), - incrementTimestamp,cfodelay, - _requestsAhead,_heartbeatsAfter); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - _device->ResetDeviceTime(); - - // print_roc_registers(&_dtc,DTCLib::DTC_Link_0,"001 [after cfo.SendRequestForTimestamp]"); - - size_t nbytes(0); - bool timeout(false); - bool readSuccess(false); - - mu2e_databuff_t* buffer = readDTCBuffer(_device, readSuccess, timeout, nbytes, false); - // int nbytes = dev->read_data(DTC_DMA_Engine_DAQ, (void**) (&buffer), tmo_ms); - - // print_roc_registers(&dtc,DTCLib::DTC_Link_0,"002 [after readDTCBuffer]"); - - // if (_debugLevel > 0) DTCLib::Utilities::PrintBuffer(buffer, nbytes, 0); - - if (ev_counter() < _nEvents) { - printf(" ----------------------------------------------------------------------- reading event %i\n",_ievent); - printf(" readSuccess:%i timeout:%i nbytes: %5lu\n",readSuccess,timeout,nbytes); - printBuffer(buffer, (int) nbytes); - } -//----------------------------------------------------------------------------- -// first 0x40 bytes seem to be useless, they are followed by the data header packer, -// offline starts from there -//----------------------------------------------------------------------------- - int offset = 0x40; - double fragment_timestamp = _ievent; - artdaq::Fragment* frag = new artdaq::Fragment(ev_counter(), fragment_id(), FragmentType::TRK, fragment_timestamp); - frag->resizeBytes(nbytes-offset); - void* af = frag->dataBegin(); - Frags.emplace_back(frag); - - struct DataHeaderPacket_t { - uint16_t nBytes; - uint16_t w2; - uint16_t nPackets; - uint16_t evtWindowTag[3]; - uint16_t w7; - uint16_t w8; - - void setVersion(int version) { w7 = (w7 & 0x00ff) + ((version & 0xff) << 8) ; } - void setStatus (int status ) { w7 = (w7 & 0xff00) + (status & 0xff) ; } - }; - - char* cbuf = (char*) buffer; - memcpy(af, cbuf+offset,nbytes-offset); - - DataHeaderPacket_t* dp = (DataHeaderPacket_t*) af; - dp->setVersion(1); -//----------------------------------------------------------------------------- -// now print the block saved in the file -//----------------------------------------------------------------------------- - if (ev_counter() < _nEvents) { - printf(" ----------------------------------------------------------------------- saved Fragment %i\n",_ievent); - printf(" readSuccess:%i timeout:%i nbytes: %5lu\n",readSuccess,timeout,nbytes); - printBuffer(af, (int) nbytes-offset); - } -//----------------------------------------------------------------------------- -// release the DMA channel -//----------------------------------------------------------------------------- - _device->read_release(DTC_DMA_Engine_DAQ, 1); - - if (delay > 0) usleep(delay); - - if (_debugLevel > 0) { - rc = _device->read_register(0x9100,100,&res); printf("DTC status : 0x%08x rc:%i\n",res,rc); // expect: 0x40808404 - rc = _device->read_register(0x91c8,100,&res); printf("debug packet type: 0x%08x rc:%i\n",res,rc); // expect: 0x00000000 - } - - _device->release_all(DTC_DMA_Engine_DAQ); - -} - - -//----------------------------------------------------------------------------- -void mu2e::TrackerVST001::test_002(artdaq::FragmentPtrs& Frags) { - monica_var_pattern_config (_dtc); - - print_dtc_registers(_dtc,"test_002 001"); - print_roc_registers(); - - buffer_test_002 (Frags); - - print_dtc_registers(_dtc,"test_002 002"); - print_roc_registers(); -} - -//----------------------------------------------------------------------------- -void mu2e::TrackerVST001::test_003(artdaq::FragmentPtrs& Frags) { - monica_var_pattern_config (_dtc); - - print_dtc_registers(_dtc,"test_003 001"); - print_roc_registers(); - - buffer_test_003 (Frags); - - print_dtc_registers(_dtc,"test3 002"); - print_roc_registers(); -} - - -//----------------------------------------------------------------------------- -// read data -//----------------------------------------------------------------------------- -void mu2e::TrackerVST001::test_004(artdaq::FragmentPtrs& Frags) { - - monica_digi_clear (_dtc); - monica_var_link_config(_dtc); - - if (_debugLevel > 0) print_dtc_registers(_dtc,"test_004 001"); - // print_roc_registers(); - - buffer_test_004(Frags); - - if (_debugLevel > 0) print_dtc_registers(_dtc,"test4 002"); - // print_roc_registers(); -} - -//----------------------------------------------------------------------------- -// this is to make an organized transition -//----------------------------------------------------------------------------- -mu2e_databuff_t* mu2e::TrackerVST001::readDTCBuffer(mu2edev* Device, bool& readSuccess, bool& timeout, - size_t& sts, - bool continuedMode) { - mu2e_databuff_t* buffer; - auto tmo_ms = 1500; - readSuccess = false; - TLOG(TLVL_DEBUG) << "mu2e::TrackerVST001::readDTCBuffer: START : before read_data"; - sts = Device->read_data(DTC_DMA_Engine_DAQ, reinterpret_cast(&buffer), tmo_ms); - - TLOG(TLVL_DEBUG) << "mu2e::TrackerVST001::readDTCBuffer: after read for DAQ sts=" << sts << ", buffer=" << (void*)buffer; - - if (sts > 0) { - readSuccess = true; - void* readPtr = &buffer[0]; - uint16_t bufSize = static_cast(*static_cast(readPtr)); - readPtr = static_cast(readPtr) + 8; - - TLOG(TLVL_DEBUG) << "Buffer reports DMA size of " - << std::dec << bufSize << " bytes. Device driver reports read of " - << sts << " bytes," << std::endl; - - TLOG(TLVL_DEBUG) << "mu2e::TrackerVST001::readDTCBuffer: bufSize is " << bufSize; - - timeout = false; - if (!continuedMode && sts > sizeof(DTC_EventHeader) + sizeof(DTC_SubEventHeader) + 8) { - // Check for dead or cafe in first packet - readPtr = static_cast(readPtr) + sizeof(DTC_EventHeader) + sizeof(DTC_SubEventHeader); - std::vector wordsToCheck{ 1, 2, 3, 7, 8 }; - for (auto& word : wordsToCheck) { - auto wordPtr = static_cast(readPtr) + (word - 1); - TLOG(TLVL_DEBUG) << word << (word == 1 ? "st" : word == 2 ? "nd" - : word == 3 ? "rd" - : "th") - << " word of buffer: " << *wordPtr; - - if (*wordPtr == 0xcafe || *wordPtr == 0xdead) { - TLOG(TLVL_WARNING) << "Buffer Timeout detected! " - << word << (word == 1 ? "st" : word == 2 ? "nd" - : word == 3 ? "rd" : "th") - << " word of buffer is 0x" << std::hex << *wordPtr; - DTCLib::Utilities::PrintBuffer(readPtr, 16, 0, TLVL_DEBUG); - timeout = true; - break; - } - } - } - } - - printf("mu2e::TrackerVST001::readDTCBuffer: END\n") ; - - return buffer; -} - -//----------------------------------------------------------------------------- -// print 16 bytes per line -// size - number of bytes to print, even -//----------------------------------------------------------------------------- -void mu2e::TrackerVST001::printBuffer(const void* ptr, int sz) { - - int nw = sz/2; - ushort* p16 = (ushort*) ptr; - int n = 0; - - for (int i=0; iShowBottom(); // Restore old cout. cout.rdbuf( oldCoutStreamBuf ); diff --git a/otsdaq-mu2e-tracker/Gui/DtcGui_gui_DtcTab.cc b/otsdaq-mu2e-tracker/Gui/DtcGui_gui_DtcTab.cc index 5618d42..26cecb1 100644 --- a/otsdaq-mu2e-tracker/Gui/DtcGui_gui_DtcTab.cc +++ b/otsdaq-mu2e-tracker/Gui/DtcGui_gui_DtcTab.cc @@ -13,7 +13,14 @@ void DtcGui::BuildDtcTabElement(TGTab*& Tab, DtcTabElement_t& DtcTel, DtcData_t* DtcTel.fData = DtcData; DtcTel.fDTC_i = DtcInterface::Instance(DtcData->fPcieAddr,DtcData->fLinkMask); + DtcTel.fDTC_i->fDtcID = DtcData->fDtcID; + DtcTel.fDTC_i->fPartitionID = DtcData->fPartitionID; + DtcTel.fDTC_i->fMode = DtcData->fMode; + DtcTel.fDTC_i->fMacAddrByte = DtcData->fMacAddrByte; + DtcTel.fDTC_i->SetRocReadoutMode(DtcData->fReadoutMode); + DtcTel.fDTC_i->SetJAMode(DtcData->fJAMode); + DtcTel.fDTC_i->SetEmulateCfo(DtcData->fEmulateCfo); const char* device_name = DtcData->fName.Data(); diff --git a/otsdaq-mu2e-tracker/Gui/DtcGui_threads.cc b/otsdaq-mu2e-tracker/Gui/DtcGui_threads.cc index f78a837..0a6d56c 100644 --- a/otsdaq-mu2e-tracker/Gui/DtcGui_threads.cc +++ b/otsdaq-mu2e-tracker/Gui/DtcGui_threads.cc @@ -1,4 +1,4 @@ - +// -*- buffer-read-only:t -*- #include "otsdaq-mu2e-tracker/Gui/DtcGui.hh" using namespace trkdaq; @@ -46,7 +46,7 @@ void* DtcGui::ReaderThread(void* Context) { if (tc->fPrintLevel > 0) { // print header cout << Form(" CPU T Real T event DTC EW Tag nbytes nbytes_tot ------------- ROC status ---------------- nerr nerr_tot\n"); - cout << Form("-------------------------------------------------------------------------------------------------------------------------\n"); + cout << Form("---------------------------------------------------------------------------------------------------------------------------\n"); } for (int ir=0; ir<6; ir++) { @@ -73,7 +73,9 @@ void* DtcGui::ReaderThread(void* Context) { // read events until done; tstamp is incremented only upon a successful read //----------------------------------------------------------------------------- while (1) { + // TThread::Lock(); list_of_dtc_blocks = dtc->GetSubEventData(event_tag, match_ts); + // TThread::UnLock(); sz = list_of_dtc_blocks.size(); for (int i=0; i 10 // everything is read in, safe to release all buffers //----------------------------------------------------------------------------- +// TThread::Lock(); dtc_i->Dtc()->ReleaseAllBuffers(DTC_DMA_Engine_DAQ); + // TThread::UnLock(); if (tc->fPrintLevel > 10) { cout << Form(">>>> ------- tstamp = %10lu event_tg:%10lu NDTCs:%2i\n",tstamp,event_tag.GetEventWindowTag(true),sz); @@ -196,8 +200,10 @@ void* DtcGui::EmuCfoThread(void* Context) { while (tc->fStop == 0) { // gSystem->Sleep(sleep_us); usleep(sleep_us); - + // TThread::Lock(); + // dtc_i->InitReadout(); dtc_i->LaunchRunPlanEmulatedCfo(ew_length,nevents+1,first_ts); + // TThread::UnLock(); first_ts = first_ts+nevents; int t1 = first_ts/dtc_gui->fCfoPrintFreq; @@ -205,6 +211,11 @@ void* DtcGui::EmuCfoThread(void* Context) { TLOG(TLVL_DEBUG) << Form("first_ts: %10lu",first_ts); t0 = t1; } +//----------------------------------------------------------------------------- +// this is a kludge - so far, resetting in the end of the pulse train +// seems to be the only way to make the ROC not to complain +// not really +//----------------------------------------------------------------------------- } TLOG(TLVL_DEBUG) << "END" << std::endl; @@ -370,6 +381,9 @@ int DtcGui::manage_reader_thread() { TThread::Lock(); TGButton* btn = (TGButton*) gTQSender; btn->ChangeBackground(fRunningColor); +//----------------------------------------------------------------------------- +// if requested, open output file +//----------------------------------------------------------------------------- TThread::UnLock(); } else { diff --git a/otsdaq-mu2e-tracker/Ui/CfoInterface.cc b/otsdaq-mu2e-tracker/Ui/CfoInterface.cc index 5e3d13e..21cc985 100644 --- a/otsdaq-mu2e-tracker/Ui/CfoInterface.cc +++ b/otsdaq-mu2e-tracker/Ui/CfoInterface.cc @@ -140,7 +140,8 @@ namespace trkdaq { // this is a one-time initialization // CFO soft reset apparently restarts the execution , so keep the beam modes disabled //----------------------------------------------------------------------------- - void CfoInterface::InitReadout(const char* RunPlan, uint DtcMask) { + int CfoInterface::InitReadout(const char* RunPlan, uint DtcMask) { + int rc(0); TLOG(TLVL_INFO) << Form("runplan: %s DtcMask:0x%08x\n",RunPlan,DtcMask); @@ -169,6 +170,7 @@ namespace trkdaq { } } TLOG(TLVL_INFO) << Form("Done\n"); + return rc; } // void CfoInterface::InitReadout(const char* RunPlan, uint DtcMask) { diff --git a/otsdaq-mu2e-tracker/Ui/CfoInterface.hh b/otsdaq-mu2e-tracker/Ui/CfoInterface.hh index 98fbd31..da11d1a 100644 --- a/otsdaq-mu2e-tracker/Ui/CfoInterface.hh +++ b/otsdaq-mu2e-tracker/Ui/CfoInterface.hh @@ -38,7 +38,7 @@ namespace trkdaq { int ConfigureJA(int ClockSource, int Reset = 1); - void InitReadout(const char* RunPlan, uint DtcMask = 0xffffffff); + int InitReadout(const char* RunPlan, uint DtcMask = 0xffffffff); void Halt(); void LaunchRunPlan(); diff --git a/otsdaq-mu2e-tracker/Ui/ControlRoc_Read_Par_t.hh b/otsdaq-mu2e-tracker/Ui/ControlRoc_Read_Par_t.hh index fef878c..e7d1622 100644 --- a/otsdaq-mu2e-tracker/Ui/ControlRoc_Read_Par_t.hh +++ b/otsdaq-mu2e-tracker/Ui/ControlRoc_Read_Par_t.hh @@ -10,35 +10,66 @@ //----------------------------------------------------------------------------- namespace trkdaq { struct ControlRoc_Read_Input_t { - uint16_t adc_mode; // -a 8 (defailt: 0) [0] - uint16_t tdc_mode; // -t 8 (default: 0) [1] - uint16_t num_lookback; // -l 8 (default: 8) [2] - uint16_t num_samples; // -s 1 (default: 16) [3] if>63, set to 63 - uint16_t num_triggers[2]; // -T 10 (default: 0) [4-5] - uint16_t ch_mask[6]; // FFFF FFFF FFFF FFFF FFFF FFFF [6:11] - uint16_t enable_pulser; // -p 1 (default: 0) [12] - uint16_t marker_clock; // -m 3 ??? )default: 0) [13] - uint16_t mode; // [14] need to set mode=0 - uint16_t clock; // [15] need to set clock=99 + // *V2* uint16_t adc_mode; // -a 8 (defailt: 0) [0] + // *V2* uint16_t tdc_mode; // -t 8 (default: 0) [1] + // *V2* uint16_t num_lookback; // -l 8 (default: 8) [2] + // *V2* uint16_t num_samples; // -s 1 (default: 16) [3] if>63, set to 63 + // *V2* uint16_t num_triggers[2]; // -T 10 (default: 0) [4-5] + // *V2* uint16_t ch_mask[6]; // FFFF FFFF FFFF FFFF FFFF FFFF [6:11] + // *V2* uint16_t enable_pulser; // -p 1 (default: 0) [12] + // *V2* uint16_t marker_clock; // -m 3 ??? )default: 0) [13] + // *V2* uint16_t mode; // [14] need to set mode=0 + // *V2* uint16_t clock; // [15] need to set clock=99 + + uint16_t adc_mode; // = dtcbuffer[0]; // -a + uint16_t tdc_mode; // = dtcbuffer[1]; // -t + uint16_t num_lookback; // = dtcbuffer[2]; // -l + uint16_t num_triggers[2]; // num_triggers = (dtcbuffer[4] << 16) + dtcbuffer[3]; // -T + uint16_t ch_mask[6]; // channel_mask[0] = (dtcbuffer[6] << 16) + dtcbuffer[5]; // -C + // channel_mask[1] = (dtcbuffer[8] << 16) + dtcbuffer[7]; // -D + // channel_mask[2] = (dtcbuffer[10] << 16) + dtcbuffer[9]; // -E + uint16_t num_samples; // = dtcbuffer[11]; // -s + uint16_t enable_pulser; // = (uint8_t) dtcbuffer[12]; // -p + uint16_t max_total_delay; // = dtcbuffer[13]; // -d (def 1) + uint16_t marker_clock; // = (uint8_t) dtcbuffer[14]; // -m + + uint16_t mode; // need to set mode=0 + uint16_t clock; // need to set clock=99 + }; //----------------------------------------------------------------------------- // output parameters : same as input , plus four words //----------------------------------------------------------------------------- struct ControlRoc_Read_Output_t { - uint16_t adc_mode; // [0] - uint16_t tdc_mode; // [1] - uint16_t num_lookback; // [2] - uint16_t num_samples; // [3] - uint16_t num_triggers[2]; // [4-5] - uint16_t ch_mask[6]; // [6--11] - uint16_t enable_pulser; // [13] - uint16_t marker_clock; // [12] - uint16_t mode; // [14] returned 0 - uint16_t clock; // [15] returned 99, - uint16_t digi_read_0xb; // [16] - uint16_t digi_read_0xe; // [17] - uint16_t digi_read_0xd; // [18] - uint16_t digi_read_0xc; // [19] + // uint16_t adc_mode; // [0] + // uint16_t tdc_mode; // [1] + // uint16_t num_lookback; // [2] + // uint16_t num_samples; // [3] + // uint16_t num_triggers[2]; // [4-5] + // uint16_t ch_mask[6]; // [6--11] + // uint16_t enable_pulser; // [13] + // uint16_t marker_clock; // [12] + // uint16_t mode; // [14] returned 0 + // uint16_t clock; // [15] returned 99, + // uint16_t digi_read_0xb; // [16] + // uint16_t digi_read_0xe; // [17] + // uint16_t digi_read_0xd; // [18] + // uint16_t digi_read_0xc; // [19] + + uint16_t enable_pulser; // [0] *(registers_1_addr + CRDCS_WRITE_TX) = enable_pulser; + uint16_t num_samples; // [1] *(registers_1_addr + CRDCS_WRITE_TX) = num_samples; + uint16_t num_lookback; // [2] *(registers_1_addr + CRDCS_WRITE_TX) = num_lookback; + uint16_t ch_mask[6]; // [4-9] + uint16_t adc_mode; // [10] *(registers_1_addr + CRDCS_WRITE_TX) = adc_mode; + uint16_t tdc_mode; // [11] *(registers_1_addr + CRDCS_WRITE_TX) = tdc_mode; + uint16_t num_triggers[2]; // [12-13] + uint16_t digi_read_0xb; // [14] + uint16_t digi_read_0xe; // [15] + uint16_t digi_read_0xd; // [16] + uint16_t digi_read_0xc; // [17] + uint16_t mode; // [18] + uint16_t clock; // need to set clock=99 + uint16_t marker_clock; // }; }; diff --git a/otsdaq-mu2e-tracker/Ui/DtcInterface.cc b/otsdaq-mu2e-tracker/Ui/DtcInterface.cc index 0c255e9..b8410cc 100644 --- a/otsdaq-mu2e-tracker/Ui/DtcInterface.cc +++ b/otsdaq-mu2e-tracker/Ui/DtcInterface.cc @@ -23,9 +23,25 @@ using namespace DTCLib; using namespace std; namespace trkdaq { + + const char* kSpiVarName[TrkSpiDataNWords] = { + "I3_3", "I2_5", "I1_8HV" , "IHV5_0", // 0 + "VDMBHV5_0", "V1_8HV" , "V3_3HV", "V2_5" , // 4 + "A0" , "A1" , "A2" , "A3" , // 8 + "I1_8CAL", "I1_2" , "ICAL5_0" , // 12 + "ADCSPARE", // 15 + "V3_3" , "VCAL5_0", "V1_8CAL", "V1_0", // 16 + "ROCPCBTEMP", "HVPCBTEMP", "CALPCBTEMP", "RTD", // 20 + "ROC_RAIL_1V", "ROC_RAIL_1_8V", "ROC_RAIL_2_5V", "ROC_TEMP", // 24 + "CAL_RAIL_1V", "CAL_RAIL_1_8V", "CAL_RAIL_2_5V", "CAL_TEMP", // 28 + "HV_RAIL_1V" , "HV_RAIL_1_8V" , "HV_RAIL_2_5V" , "HV_TEMP" // 32 + }; + DtcInterface* DtcInterface::fgInstance[2] = {nullptr, nullptr}; - + + const char* DtcInterface::fgSpiVarName[TrkSpiDataNWords]; + //----------------------------------------------------------------------------- DtcInterface::DtcInterface(int PcieAddr, uint LinkMask, bool SkipInit) { std::string expected_version(""); // dont check @@ -36,7 +52,7 @@ namespace trkdaq { << " LinkMask:0x" << std::hex << LinkMask << std::dec << " SkipInit:" << SkipInit << std::endl; - + fEnabled = 1; // default: enabled fPcieAddr = PcieAddr; fLinkMask = LinkMask; fReadoutMode = 0; // for now, assume patterns are the default @@ -44,6 +60,11 @@ namespace trkdaq { fEmulateCfo = 0; fJAMode = 0x11; // by default, assume RTF clock and reset upon setting + fDtcID = 0; // needed for multi-DTC DAQ, default:0 + fPartitionID = 0; // use reasonable defaults, which would work for one DTC + fMode = 0; + fMacAddrByte = 0; // + fDtc = new DTC(DTC_SimMode_NoCFO,PcieAddr,LinkMask,expected_version,SkipInit,sim_file,uid); // constructor performs soft reset fDtc->SoftReset(); @@ -57,6 +78,8 @@ namespace trkdaq { //----------------------------------------------------------------------------- DtcInterface::~DtcInterface() { } +//----------------------------------------------------------------------------- +// in many cases, want SkipInit=false //----------------------------------------------------------------------------- DtcInterface* DtcInterface::Instance(int PcieAddr, uint LinkMask, bool SkipInit) { int pcie_addr = PcieAddr; @@ -70,13 +93,21 @@ namespace trkdaq { return nullptr; } } - +//----------------------------------------------------------------------------- +// initialize the variable names just once +//----------------------------------------------------------------------------- + if ((fgInstance[0] == nullptr) and (fgInstance[1] == nullptr)) { + for (int i=0; iPcieAddr() != pcie_addr) { TLOG(TLVL_ERROR) << Form("DtcInterface::Instance has been already initialized with PcieAddress = %i. BAIL out\n", @@ -92,10 +123,12 @@ namespace trkdaq { // on success, returns 1 //----------------------------------------------------------------------------- int DtcInterface::ConfigureJA(int ClockSource, int Reset) { + int nmax_iter(10); + fDtc->SetJitterAttenuatorSelect(ClockSource,Reset); // 0:internal clock sync, 1:RTF usleep(100000); int ok(0); - for (int i=0; i<3; i++) { + for (int i=0; iReadJitterAttenuatorLocked(); // in case of success, returns true usleep(100000); if (ok == 1) break; @@ -103,9 +136,14 @@ namespace trkdaq { // fDtc->FormatJitterAttenuatorCSR(); - if (ok == 0) TLOG(TLVL_ERROR) << Form("failed to setup JA\n"); + int rc = 0; + if (ok == 0) { + TLOG(TLVL_ERROR) << Form("failed to setup JA for ClockSource=%i and Reset=%i in %i attempts\n", + ClockSource,Reset,nmax_iter); + rc = -1; + } - return ok; + return rc; } @@ -118,8 +156,9 @@ namespace trkdaq { // EnableClockMarkers: set to 0 // EnableAutogenDRP : set to 1 //----------------------------------------------------------------------------- - void DtcInterface::InitEmulatedCFOReadoutMode() { + int DtcInterface::InitEmulatedCFOReadoutMode() { // int EWMode, int EnableClockMarkers, int EnableAutogenDRP) { + int rc(0); TLOG(TRK_DEBUG_LEVEL) << Form("START\n"); @@ -137,7 +176,8 @@ namespace trkdaq { int clock_source = (fJAMode >> 4) & 0x1; int reset = fJAMode & 0x1; - ConfigureJA(clock_source,reset); + rc = ConfigureJA(clock_source,reset); + if (rc < 0) return rc; // this one is OK... int EnableClockMarkers = 0; fDtc->SetCFO40MHzClockMarkerEnable (DTC_Link_ALL,EnableClockMarkers); @@ -150,6 +190,7 @@ namespace trkdaq { fDtc->EnableReceiveCFOLink(); // r_0x9114:bit_14 = 1 TLOG(TRK_DEBUG_LEVEL) << Form("END\n"); + return rc; } //----------------------------------------------------------------------------- @@ -159,7 +200,8 @@ namespace trkdaq { // DTC doesn' know about an external CFO, so it should only prepare itself to receive // EVMs/HBs from the outside //----------------------------------------------------------------------------- - void DtcInterface::InitExternalCFOReadoutMode(int SampleEdgeMode) { + int DtcInterface::InitExternalCFOReadoutMode(int SampleEdgeMode) { + int rc(0); TLOG(TLVL_DEBUG+1) << Form("START SampleEdgeMode=%i\n",fSampleEdgeMode); if (SampleEdgeMode != -1) fSampleEdgeMode = SampleEdgeMode; @@ -182,7 +224,8 @@ namespace trkdaq { int clock_source = (fJAMode >> 4) & 0x1; int reset = fJAMode & 0x1; - ConfigureJA(clock_source,reset); + rc = ConfigureJA(clock_source,reset); + if (rc < 0) return rc; // which ROC links should be enabled ? - all active ? int EnableClockMarkers = 0; // for now // this function handles DTC_Link_ALL correctly @@ -199,12 +242,14 @@ namespace trkdaq { fDtc->EnableReceiveCFOLink (); // r_0x9114:bit_14 = 1 TLOG(TLVL_DEBUG+1) << Form("END\n"); -} + return rc; + } //----------------------------------------------------------------------------- // Init Readout //----------------------------------------------------------------------------- - void DtcInterface::InitReadout(int EmulateCfo, int RocReadoutMode) { + int DtcInterface::InitReadout(int EmulateCfo, int RocReadoutMode) { + int rc(0); if (EmulateCfo != -1) fEmulateCfo = EmulateCfo; if (RocReadoutMode != -1) fReadoutMode = RocReadoutMode; @@ -214,24 +259,34 @@ namespace trkdaq { // both emulated and external modes perform soft reset of the DTC //----------------------------------------------------------------------------- if (fEmulateCfo == 0) { - InitExternalCFOReadoutMode(); + rc = InitExternalCFOReadoutMode(); } else { //----------------------------------------------------------------------------- // bit_30 will be restored on the 'emulated CFO side", in the call to InitEmulatedCFOReadoutMode //----------------------------------------------------------------------------- - InitEmulatedCFOReadoutMode(); + rc = InitEmulatedCFOReadoutMode(); } + if (rc < 0) return rc; //----------------------------------------------------------------------------- // the DTC link mask could be reset by the previous DTC hard reset, so restore it // also, release all buffers from the previous read - this is the initialization //----------------------------------------------------------------------------- - SetLinkMask(); + SetLinkMask(); + // this should do for now, later - set the partition ID + // at begin run, for example, as follows + + uint8_t id = fDtcID & 0xff; + uint8_t mode = fMode & 0xff; + uint8_t partition_id = fPartitionID & 0xff; + uint8_t mac_byte = fMacAddrByte & 0xff; + fDtc->SetEVBInfo(id,mode,partition_id,mac_byte); InitRocReadoutMode(); fDtc->ReleaseAllBuffers(DTC_DMA_Engine_DAQ); TLOG(TLVL_DEBUG+1) << "END" << std::endl; + return rc; } //----------------------------------------------------------------------------- @@ -240,6 +295,8 @@ namespace trkdaq { // = 1: read digis +//----------------------------------------------------------------------------- +// this si fully tracker-specific //----------------------------------------------------------------------------- void DtcInterface::InitRocReadoutMode() { TLOG(TLVL_DEBUG+1) << Form("START : fReadoutMode=%i\n",fReadoutMode); @@ -268,7 +325,7 @@ namespace trkdaq { int EWMode = 1; fDtc->SetCFOEmulationEventWindowInterval(EWLength); fDtc->SetCFOEmulationNumHeartbeats (NMarkers); - fDtc->SetCFOEmulationEventMode (EWMode); + fDtc->SetCFOEmulationEventMode (EWMode ); fDtc->SetCFOEmulationTimestamp (DTC_EventWindowTag((uint64_t) FirstEWTag)); // this command sends the EWM's @@ -381,8 +438,8 @@ namespace trkdaq { int nw = nb-4; - if (nw != TrkSpiRawData_t::nWords()) { - TLOG(TLVL_ERROR) << "expected N(words)=" << TrkSpiRawData_t::nWords() << " , reported nw=" << nw; + if (nw != TrkSpiDataNWords) { + TLOG(TLVL_ERROR) << "expected N(words)=" << TrkSpiDataNWords << " , reported nw=" << nw; rc = -1; } @@ -484,8 +541,8 @@ namespace trkdaq { } } } - cout << Form(" event DTC EW Tag nbytes nbytes_tot ------------- ROC status ---------------- nerr nerr_tot\n"); - cout << Form("-------------------------------------------------------------------------------------------------------\n"); + cout << Form(" event DTC EW Tag nbytes nbytes_tot link0 nb0 link1 nb1 link2 nb2 link3 nb3 link4 nb4 link5 nb5 nerr nerr_tot\n"); + cout << Form("--------------------------------------------------------------------------------------------------------------------------------------------\n"); //----------------------------------------------------------------------------- // reset per-roc error counters //----------------------------------------------------------------------------- @@ -531,15 +588,18 @@ namespace trkdaq { char* roc_data = data+0x30; + int nb_roc[6]; for (int roc=0; roc<6; roc++) { - int nb = *((ushort*) roc_data); - rs[roc] = *((ushort*)(roc_data+0x0c)); - roc_data += nb; + nb_roc[roc] = *((ushort*) roc_data); + rs[roc] = *((ushort*)(roc_data+0x0c)); + roc_data += nb_roc[roc]; } if (PrintLevel > 0) { - cout << Form(" %10li %2i %10li %5i %13li 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x %5i %8i %4i %4i %4i %4i %4i %4i\n", - ewt,i,ew_tag,nbytes,nbytes_tot,rs[0],rs[1],rs[2],rs[3],rs[4],rs[5],nerr,nerr_tot, + cout << Form(" %10li %2i %10li %5i %13li 0x%04x %5i 0x%04x %5i 0x%04x %5i 0x%04x %5i 0x%04x %5i 0x%04x %5i %5i %8i %4i %4i %4i %4i %4i %4i\n", + ewt,i,ew_tag,nbytes,nbytes_tot, + rs[0],nb_roc[0],rs[1],nb_roc[1],rs[2],nb_roc[2],rs[3],nb_roc[3],rs[4],nb_roc[4],rs[5],nb_roc[5], + nerr,nerr_tot, nerr_roc[0],nerr_roc[1],nerr_roc[2],nerr_roc[3],nerr_roc[4],nerr_roc[5] ); if (((nerr > 0) and (PrintLevel > 1)) or (PrintLevel > 2)) { PrintBuffer(ev->GetRawBufferPointer(),ev->GetSubEventByteCount()/2); @@ -994,20 +1054,20 @@ struct RocData_t { //----------------------------------------------------------------------------- // configure_ROC 'read' command should be followed by ROC reset //----------------------------------------------------------------------------- - // to be added +// to be added //----------------------------------------------------------------------------- int DtcInterface::MonicaVarLinkConfig(int LinkMask, int LaneMask) { - + int rc(0); + fReadoutMode = 1; // 1: read digis if (LinkMask != 0) SetLinkMask(LinkMask); - ResetRoc(); // use fLinkMask int lane_mask = 0x300 | LaneMask; for (int i=0; i<6; i++) { int used = (fLinkMask >> 4*i) & 0x1; if (used != 0) { - fDtc->WriteROCRegister(DTC_Link_ID(i), 8,lane_mask,false,1000); // configure ROC to send patterns + fDtc->WriteROCRegister(DTC_Link_ID(i), 8,lane_mask,false,1000); // enable lanes } } @@ -1015,8 +1075,31 @@ struct RocData_t { int data_version = 1; RocSetDataVersion(data_version); // Version --> R29 - // ResetRoc(); // use fLinkMask - return 0; + + ResetRoc(); // use fLinkMask +//----------------------------------------------------------------------------- +// according to Monica, this is the place for find_alignment and control_roc_read +// check if all lanes are ready to be read +//----------------------------------------------------------------------------- + for (int i=0; i<6; i++) { + int used = (fLinkMask >> 4*i) & 0x1; + if (used != 0) { + uint16_t u = fDtc->ReadROCRegister(DTC_Link_ID(i),18,100); + if ((u >> 0x8) != LaneMask) { + // try to recover + fDtc->WriteROCRegister(DTC_Link_ID(i), 13,0x1,false,1000); + // and check again + u = fDtc->ReadROCRegister(DTC_Link_ID(i),18,100); + if ((u >> 0x8) != LaneMask) { + // still in trouble + TLOG(TLVL_ERROR) << Form("ROC on link %i is not ready to read the DIGIs, call Monica and Richie\n",i); + rc -= 1; + } + } + } + } +//----------------------------------------------------------------------------- + return rc; } //----------------------------------------------------------------------------- @@ -1040,7 +1123,6 @@ struct RocData_t { int version = 1; RocSetDataVersion(version); // Version --> R29 - // ResetRoc(); // use fLinkMask return 0; } diff --git a/otsdaq-mu2e-tracker/Ui/DtcInterface.hh b/otsdaq-mu2e-tracker/Ui/DtcInterface.hh index fdc3776..9bbe2a6 100644 --- a/otsdaq-mu2e-tracker/Ui/DtcInterface.hh +++ b/otsdaq-mu2e-tracker/Ui/DtcInterface.hh @@ -28,7 +28,8 @@ namespace trkdaq { static DtcInterface* fgInstance[2]; DTCLib::DTC* fDtc; - int fPcieAddr; + int fEnabled; // if comes from ODB, could be 0 + int fPcieAddr; // int fLinkMask; // int is OK, bit 31 is never used for arithmetics // for now assume that all ROCs are doing the same int fReadoutMode; // 0: patterns 1:digis @@ -36,9 +37,16 @@ namespace trkdaq { int fEmulateCfo; // 1: this DTC operated in the emulated CFO mode int fJAMode; // clock_source << 4 | reset - int fSleepTimeROCWrite; // the two are different - int fSleepTimeROCReset; - int fPrintLevel; + int fDtcID; // unique DTC ID used by the DAQ (0x9154) + int fMode; // whatever it is + int fPartitionID; + int fMacAddrByte; + + int fSleepTimeROCWrite; // the two are different + int fSleepTimeROCReset; // + int fPrintLevel; // + + static const char* fgSpiVarName[TrkSpiDataNWords]; // //----------------------------------------------------------------------------- // functions //----------------------------------------------------------------------------- @@ -52,8 +60,11 @@ namespace trkdaq { int PcieAddr() { return fPcieAddr; } DTCLib::DTC* Dtc() { return fDtc; } - // clock source=0: internal, clock=1: RTF (RJ45) - + + static const char* SpiVarName(int I) { return fgSpiVarName[I]; } +//----------------------------------------------------------------------------- +// clock source= 0:internal, 1:RTF (RJ45) +//----------------------------------------------------------------------------- int ConfigureJA(int ClockSource, int Reset = 1); //----------------------------------------------------------------------------- // generic interface to control_ROC.py commands. @@ -61,27 +72,47 @@ namespace trkdaq { //----------------------------------------------------------------------------- int ControlRoc(const char* Command, void* Parameters); - int ControlRoc_Read(ControlRoc_Read_Input_t* Par, - int LinkMask = 0 , + int ControlRoc_Read(ControlRoc_Read_Input_t* Par , + int LinkMask = 0 , bool UpdateMask = false, int PrintLevel = 0 ); +//----------------------------------------------------------------------------- +// measure thresholds returns an array of thresholds, which needs to be parsed +// so far, do it internally +//----------------------------------------------------------------------------- + int ControlRoc_MeasureThresholds(int Link, + uint32_t MaskC = 0xFFFFFFFF, + uint32_t MaskD = 0xFFFFFFFF, + uint32_t MaskE = 0xFFFFFFFF); +//----------------------------------------------------------------------------- +// PreampType: 0:HV 1:CAL, or vice versa +// do one channel at a time +// shall we think of a block operation ? or not ? - channels could be masked OFFx +//----------------------------------------------------------------------------- + int ControlRoc_SetGain (int Link, int ChannelID, int PreampType, int Gain ); + int ControlRoc_SetThreshold(int Link, int ChannelID, int PreampType, int Threshold); + int Enabled () { return fEnabled; } int EmulateCfo() { return fEmulateCfo; } + int DtcID () { return fDtcID; } + + int InitEmulatedCFOReadoutMode(); + // EWLength - in 25 ns ticks // to be executed on the emulated CFO side - void InitEmulatedCFOReadoutMode(); void LaunchRunPlanEmulatedCfo (int EWLength, int NMarkers, int FirstEWTag); // SampleEdgeMode=0: force rising edge // 1: force falling edge // 2: auto // -1 means use the pre-fetched one + // success: returns rc=0 + // if rc < 0, can't continue + int InitExternalCFOReadoutMode(int SampleEdgeMode = -1); - void InitExternalCFOReadoutMode(int SampleEdgeMode = -1); - - void InitReadout (int EmulateCfo = -1, int RocReadoutMode = -1); + int InitReadout (int EmulateCfo = -1, int RocReadoutMode = -1); void InitRocReadoutMode(); int GetLinkMask() { return fLinkMask; } @@ -92,7 +123,9 @@ namespace trkdaq { //----------------------------------------------------------------------------- void PrintBuffer (const void* ptr, int nw); void PrintFireflyTemp(); - void PrintRegister (uint16_t Register, const char* Title = ""); + + void PrintDtcLinkRegisters(uint FirstReg, const char* Desc); + void PrintRegister (uint16_t Register, const char* Title = ""); //----------------------------------------------------------------------------- // Format = 0 : for each register, print a register and its value // Format = 1 : add short description of each register @@ -136,7 +169,10 @@ namespace trkdaq { // 'Value' : 0 or 1 void SetBit (int Register, int Bit, int Value); - void SetJAMode (int Mode) { fJAMode = Mode; } + void SetEmulateCfo(int EmulateCfo) { fEmulateCfo = EmulateCfo; } + // just cache the DTC ID for future, to evolve + + void SetJAMode (int Mode ) { fJAMode = Mode; } void SetLinkMask(int Mask = 0); //----------------------------------------------------------------------------- diff --git a/otsdaq-mu2e-tracker/Ui/DtcInterface_ControlRoc.cc b/otsdaq-mu2e-tracker/Ui/DtcInterface_ControlRoc.cc index d14034d..772224d 100644 --- a/otsdaq-mu2e-tracker/Ui/DtcInterface_ControlRoc.cc +++ b/otsdaq-mu2e-tracker/Ui/DtcInterface_ControlRoc.cc @@ -24,6 +24,19 @@ namespace trkdaq { //----------------------------------------------------------------------------- // write parameters into reg 266 (via block write), sleep for some time, // then wait till reg 128 returns 0x8000 +/* + adc_mode = dtcbuffer[0]; // -a + tdc_mode = dtcbuffer[1]; // -t + num_lookback = dtcbuffer[2]; // -l + num_triggers = (dtcbuffer[4] << 16) + dtcbuffer[3]; // -T + channel_mask[0] = (dtcbuffer[6] << 16) + dtcbuffer[5]; // -C + channel_mask[1] = (dtcbuffer[8] << 16) + dtcbuffer[7]; // -D + channel_mask[2] = (dtcbuffer[10] << 16) + dtcbuffer[9]; // -E + num_samples = dtcbuffer[11]; // -s + enable_pulser = (uint8_t) dtcbuffer[12]; // -p + max_total_delay = dtcbuffer[13]; // -d (def 1) + marker_clock = (uint8_t) dtcbuffer[14]; // -m +*/ //----------------------------------------------------------------------------- std::vector vec; @@ -35,7 +48,6 @@ namespace trkdaq { printf("WARNING: num_samples = %i > 63, truncate to 63\n",Par->num_samples); Par->num_samples = 63; } - vec.push_back(Par->num_samples); uint16_t w1 = Par->num_triggers[0]; uint16_t w2 = Par->num_triggers[1]; @@ -45,17 +57,26 @@ namespace trkdaq { for (int i=0; i<6; i++) vec.push_back(Par->ch_mask[i]); + vec.push_back(Par->num_samples); vec.push_back(Par->enable_pulser); + vec.push_back(1 ); // max_total_delay (unused) vec.push_back(Par->marker_clock ); - vec.push_back(0 ); - vec.push_back(99); + // vec.push_back(0 ); + // vec.push_back(99); bool increment_address(false); +//----------------------------------------------------------------------------- +// if LinkMask != -1, use it +// in addition, if UpdateMask=true, update the DTC link mask (fLinkMask) +//----------------------------------------------------------------------------- + int link_mask = fLinkMask; + if (LinkMask != -1) { + link_mask = LinkMask; + if (UpdateMask) fLinkMask = LinkMask; + } - if (UpdateMask and (LinkMask != 0)) fLinkMask = LinkMask; - for (int i=0; i<6; i++) { - int used = (fLinkMask >> 4*i) & 0x1; + int used = (link_mask >> 4*i) & 0x1; if (not used) continue; auto roc = DTC_Link_ID(i); fDtc->WriteROCBlock (roc,265,vec,false,increment_address,100); @@ -106,4 +127,148 @@ namespace trkdaq { return 0; } + +//----------------------------------------------------------------------------- + int DtcInterface::ControlRoc_SetGain(int Link, int ChannelID, int PreampType, int Gain) { +//----------------------------------------------------------------------------- +// convert into enum +//----------------------------------------------------------------------------- + auto roc = DTC_Link_ID(Link); +//----------------------------------------------------------------------------- +// write parameters into reg 266 (block write) , sleep for some time, +// then wait till reg 128 returns 0x8000 +//----------------------------------------------------------------------------- + std::vector vec; + vec.push_back(uint16_t(ChannelID )); + vec.push_back(uint16_t(Gain )); + vec.push_back(uint16_t(PreampType)); + + bool increment_address(false); + fDtc->WriteROCBlock (roc,266,vec,false,increment_address,100); + std::this_thread::sleep_for(std::chrono::microseconds(fSleepTimeROCWrite)); + + // 0x86 = 0x82 + 4 + uint16_t u; + while ((u = fDtc->ReadROCRegister(roc,128,100)) != 0x8000) {}; + TLOG(TLVL_DEBUG) << Form("reg:%03i val:0x%04x\n",128,u); +//----------------------------------------------------------------------------- +// register 129: number of words to read, currently- (+ 4) (ask Monica) +//----------------------------------------------------------------------------- + int nw = fDtc->ReadROCRegister(roc,129,100); + TLOG(TLVL_DEBUG) << Form("reg:%03i val:0x%04x\n",129,nw); + + nw = nw-4; + std::vector v2; + fDtc->ReadROCBlock(v2,roc,266,nw,false,100); + + PrintBuffer(v2.data(),nw); +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + ResetRoc(Link); + return 0; + } + + +//----------------------------------------------------------------------------- + int DtcInterface::ControlRoc_SetThreshold(int Link, int ChannelID, int PreampType, int Threshold) { +//----------------------------------------------------------------------------- +// convert into enum +//----------------------------------------------------------------------------- + auto roc = DTC_Link_ID(Link); +//----------------------------------------------------------------------------- +// write parameters into reg 267 (block write) , sleep for some time, +// then wait till reg 128 returns 0x8000 +//----------------------------------------------------------------------------- + std::vector vec; + vec.push_back(uint16_t(ChannelID)); + vec.push_back(uint16_t(Threshold)); + vec.push_back(uint16_t(PreampType)); + + bool increment_address(false); + fDtc->WriteROCBlock (roc,267,vec,false,increment_address,100); + std::this_thread::sleep_for(std::chrono::microseconds(fSleepTimeROCWrite)); + + // 0x86 = 0x82 + 4 + uint16_t u; + while ((u = fDtc->ReadROCRegister(roc,128,100)) != 0x8000) {}; + TLOG(TLVL_DEBUG) << Form("reg:%03i val:0x%04x\n",128,u); +//----------------------------------------------------------------------------- +// register 129: number of words to read, currently- (+ 4) (ask Monica) +//----------------------------------------------------------------------------- + int nw = fDtc->ReadROCRegister(roc,129,100); + TLOG(TLVL_DEBUG) << Form("reg:%03i val:0x%04x\n",129,nw); + + nw = nw-4; + std::vector v2; + fDtc->ReadROCBlock(v2,roc,267,nw,false,100); + + PrintBuffer(v2.data(),nw); +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + ResetRoc(Link); + return 0; + } + + +//----------------------------------------------------------------------------- + int DtcInterface::ControlRoc_MeasureThresholds(int Link, uint32_t MaskC, uint32_t MaskD, uint32_t MaskE) { +//----------------------------------------------------------------------------- +// convert into enum +//----------------------------------------------------------------------------- + auto roc = DTC_Link_ID(Link); + + // int roc_mask = 1 << (4*Link); +//----------------------------------------------------------------------------- +// write parameters into reg 264 (block write) , sleep for some time, +// then wait till reg 128 returns 0x8000 +//----------------------------------------------------------------------------- + // uint16_t chan_mask[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; + + + std::vector vec; + + vec.push_back((MaskC ) & 0xffff); + vec.push_back((MaskC >> 16) & 0xffff); + vec.push_back((MaskD ) & 0xffff); + vec.push_back((MaskD >> 16) & 0xffff); + vec.push_back((MaskE ) & 0xffff); + vec.push_back((MaskE >> 16) & 0xffff); + + bool increment_address(false); + fDtc->WriteROCBlock (roc,270,vec,false,increment_address,100); + std::this_thread::sleep_for(std::chrono::microseconds(fSleepTimeROCWrite)); + + // 0x86 = 0x82 + 4 + uint16_t u; + while ((u = fDtc->ReadROCRegister(roc,128,100)) != 0x8000) {}; + printf("reg:%03i val:0x%04x\n",128,u); +//----------------------------------------------------------------------------- +// register 129: number of words to read, currently- (+ 4) (ask Monica) +//----------------------------------------------------------------------------- + int nw = fDtc->ReadROCRegister(roc,129,100); printf("reg:%03i val:0x%04x\n",129,nw); + + nw = nw-4; + std::vector v2; + fDtc->ReadROCBlock(v2,roc,270,nw,false,100); +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + fDtc->WriteROCRegister(roc,14,0x01,false,1000); + + PrintBuffer(v2.data(),nw); + // expect nw=288 = 96*3, if not - in trouble + + for (int i=0; i<96; i++) { + float hw = (-1000. + v2[ i]*2000./1024.)/10.; + float cal = (-1000. + v2[96 +i]*2000./1024.)/10.; + float tot = (-1000. + v2[192+i]*2000./1024.)/10.; + + printf(" i, hw, cal, tot : %3i %10.3f %10.3f %10.3f\n",i,hw,cal,tot); + } + return 0; + } + + }; diff --git a/otsdaq-mu2e-tracker/Ui/DtcInterface_print.cc b/otsdaq-mu2e-tracker/Ui/DtcInterface_print.cc index 84d21ca..aebc71b 100644 --- a/otsdaq-mu2e-tracker/Ui/DtcInterface_print.cc +++ b/otsdaq-mu2e-tracker/Ui/DtcInterface_print.cc @@ -126,13 +126,30 @@ namespace trkdaq { cout << Form("%-18s%s\n",sreg.data(),text.data()); } - + +//----------------------------------------------------------------------------- + void DtcInterface::PrintDtcLinkRegisters(uint FirstReg, const char* Desc) { + + std::string text = Form("(0x%04x) : ",FirstReg); + + for (int i=0; i<6; i++) { + int used = (fLinkMask >> 4*i) & 0x1; + if (used == 0) continue; + uint32_t reg = FirstReg+4*i; + uint32_t iw = ReadRegister(reg); + text += Form(" 0x%08x",iw); + } + + text += Form(" %s",Desc); + cout << Form("%-s\n",text.data()); + } + //----------------------------------------------------------------------------- // most of the time LinkMask = -1 //----------------------------------------------------------------------------- void DtcInterface::PrintRocStatus(int Format, int LinkMask) { - TLOG(TLVL_DEBUG) << Form("Format=%i LinkMask 0x%08x \n",Format,LinkMask); + TLOG(TLVL_DBG+1) << Form("Format=%i LinkMask 0x%08x \n",Format,LinkMask); std::string desc; @@ -251,6 +268,19 @@ namespace trkdaq { reg = 75; desc = "Num DATA REQ tag lost"; PrintRocRegister(reg,desc,Format,link_mask); + reg = 0x90; desc = "total N packets (DCS+data)"; // r_144 + PrintRocRegister(reg,desc,Format,link_mask); // + reg = 0x91; desc = "N(DCS) packets sent to DTC"; // r_145 + PrintRocRegister(reg,desc,Format,link_mask); // + reg = 0x92; desc = "Num DATA REQ tag lost"; // r_146 + PrintRocRegister(reg,desc,Format,link_mask); // + reg = 0x93; desc = "Num DATA REQ tag lost"; // r_147 + PrintRocRegister(reg,desc,Format,link_mask); // + reg = 0x94; desc = "Num DATA REQ tag lost"; // r_148 + PrintRocRegister(reg,desc,Format,link_mask); // + reg = 0x95; desc = "Num DATA REQ tag lost"; // r_149 + PrintRocRegister(reg,desc,Format,link_mask); // + cout << "------------------------------------------------------------------------\n"; } @@ -278,6 +308,7 @@ namespace trkdaq { PrintRegister(0x9144,"DMA Timeout Preset "); PrintRegister(0x9148,"ROC reply timeout "); PrintRegister(0x914c,"ROC reply timeout error "); + PrintRegister(0x9154,"DTC ID/EVB partition ID/MAC address "); PrintRegister(0x9158,"Event Builder Configuration "); PrintRegister(0x91a8,"CFO Emulation Heartbeat Interval "); PrintRegister(0x91ac,"CFO Emulation Number of HB Packets "); @@ -287,48 +318,26 @@ namespace trkdaq { PrintRegister(0x9308,"Jitter Attenuator CSR "); - PrintRegister(0x9630,"TX Data Request Packet Count Link 0 "); - PrintRegister(0x9634,"TX Data Request Packet Count Link 1 "); - PrintRegister(0x9638,"TX Data Request Packet Count Link 2 "); - PrintRegister(0x963c,"TX Data Request Packet Count Link 3 "); - PrintRegister(0x963c,"TX Data Request Packet Count Link 3 "); - PrintRegister(0x9640,"TX Data Request Packet Count Link 4 "); - PrintRegister(0x9644,"TX Data Request Packet Count Link 5 "); - - PrintRegister(0x9650,"TX Heartbeat Packet Count Link 0 "); - PrintRegister(0x9654,"TX Heartbeat Packet Count Link 1 "); - PrintRegister(0x9658,"TX Heartbeat Packet Count Link 2 "); - PrintRegister(0x965c,"TX Heartbeat Packet Count Link 3 "); - PrintRegister(0x9660,"TX Heartbeat Packet Count Link 4 "); - PrintRegister(0x9664,"TX Heartbeat Packet Count Link 5 "); - - PrintRegister(0x9670,"RX Data Header Packet Count Link 0 "); - PrintRegister(0x9674,"RX Data Header Packet Count Link 1 "); - PrintRegister(0x9678,"RX Data Header Packet Count Link 2 "); - PrintRegister(0x967c,"RX Data Header Packet Count Link 3 "); - PrintRegister(0x9680,"RX Data Header Packet Count Link 4 "); - PrintRegister(0x9684,"RX Data Header Packet Count Link 5 "); - - PrintRegister(0x9690,"RX Data Packet Count Link 0 "); - PrintRegister(0x9694,"RX Data Packet Count Link 1 "); - PrintRegister(0x9698,"RX Data Packet Count Link 2 "); - PrintRegister(0x969c,"RX Data Packet Count Link 3 "); - PrintRegister(0x96a0,"RX Data Packet Count Link 4 "); - PrintRegister(0x96a4,"RX Data Packet Count Link 5 "); - - PrintRegister(0xa400,"TX Event Window Marker Count Link 0 "); - PrintRegister(0xa404,"TX Event Window Marker Count Link 1 "); - PrintRegister(0xa408,"TX Event Window Marker Count Link 2 "); - PrintRegister(0xa40c,"TX Event Window Marker Count Link 3 "); - PrintRegister(0xa410,"TX Event Window Marker Count Link 4 "); - PrintRegister(0xa414,"TX Event Window Marker Count Link 5 "); - - PrintRegister(0xa420,"RX Data Header Timeout Count Link 0 "); - PrintRegister(0xa424,"RX Data Header Timeout Count Link 1 "); - PrintRegister(0xa428,"RX Data Header Timeout Count Link 2 "); - PrintRegister(0xa42c,"RX Data Header Timeout Count Link 3 "); - PrintRegister(0xa430,"RX Data Header Timeout Count Link 4 "); - PrintRegister(0xa434,"RX Data Header Timeout Count Link 5 "); + std::string text1(" "); + std::string text2(" offset : "); + for (int i=0; i<6; i++) { + int used = (fLinkMask >> 4*i) & 0x1; + if (used == 0) continue; + int offset = 4*i; + text1 += Form(" link %i ",i); + text2 += Form(" (0x%02x) ",offset); + } + cout << std::endl; + cout << Form("%-s\n",text1.data()); + cout << Form("%-s\n",text2.data()); + + PrintDtcLinkRegisters(0x9630,"TX Data Request Packet Count"); + PrintDtcLinkRegisters(0x9650,"TX Heartbeat Packet Count"); + PrintDtcLinkRegisters(0x9670,"RX Data Header Packet Count"); + PrintDtcLinkRegisters(0x9690,"RX Data Packet Count"); + PrintDtcLinkRegisters(0xa400,"TX Event Window Marker Count"); + PrintDtcLinkRegisters(0xa420,"RX Data Header Timeout Count"); + } }; diff --git a/otsdaq-mu2e-tracker/Ui/TrkSpiData.hh b/otsdaq-mu2e-tracker/Ui/TrkSpiData.hh index bcb068b..e874a11 100644 --- a/otsdaq-mu2e-tracker/Ui/TrkSpiData.hh +++ b/otsdaq-mu2e-tracker/Ui/TrkSpiData.hh @@ -2,6 +2,7 @@ #define __TrkSpiData_hh__ namespace trkdaq { + //----------------------------------------------------------------------------- // Tracker ROC raw SPI data (mapping of the array of shorts //----------------------------------------------------------------------------- @@ -42,10 +43,9 @@ namespace trkdaq { uint16_t HV_RAIL_1_8V; // 33 uint16_t HV_RAIL_2_5V; // 34 uint16_t HV_TEMP; // 35 - - static int nWords () { return sizeof(TrkSpiRawData_t)/sizeof(uint16_t); } }; + int const TrkSpiDataNWords = sizeof(TrkSpiRawData_t)/sizeof(uint16_t); //----------------------------------------------------------------------------- // converted data //----------------------------------------------------------------------------- @@ -86,8 +86,6 @@ namespace trkdaq { float HV_RAIL_1_8V; // 33 float HV_RAIL_2_5V; // 34 float HV_TEMP; // 35 - - static int nWords () { return sizeof(TrkSpiData_t)/sizeof(float); } }; }; diff --git a/scripts/find_alignment.C b/scripts/control_roc_find_alignment.C similarity index 97% rename from scripts/find_alignment.C rename to scripts/control_roc_find_alignment.C index 834d1ae..b2dac37 100644 --- a/scripts/find_alignment.C +++ b/scripts/control_roc_find_alignment.C @@ -54,7 +54,7 @@ void parse_fi_output(char* Data, int NBytes) { // on mu2edaq09, a delay > 1.4 usec is needed after WriteROCRegister(258...) // so can't do that for every event ... //----------------------------------------------------------------------------- -void find_alignment(int Link, int PcieAddr, int ROCSleepTime = 2000) { +void control_roc_find_alignment(int Link, int PcieAddr, int ROCSleepTime = 2000) { //----------------------------------------------------------------------------- // convert into enum // interactive ROOT doesn't like the variable name 'link', use 'roc' instead @@ -129,5 +129,5 @@ void find_alignment_test_001(int Link, int PcieAddr = -1) { //----------------------------------------------------------------------------- void find_alignment_test_002(int Link, int PcieAddr = -1) { - find_alignment(Link,PcieAddr); + control_roc_find_alignment(Link,PcieAddr); } diff --git a/scripts/pulser_on.C b/scripts/control_roc_pulser_on.C similarity index 95% rename from scripts/pulser_on.C rename to scripts/control_roc_pulser_on.C index 029f28b..e53be54 100644 --- a/scripts/pulser_on.C +++ b/scripts/control_roc_pulser_on.C @@ -14,8 +14,8 @@ using namespace DTCLib; // so can't do that for every event ... // Firstchannel values: 0 to 7 //----------------------------------------------------------------------------- -void pulser_on(int Link, uint FirstChannel, int DutyCycle = 10, int Delay = 1000, - int ROCSleepTime = 5000) { +void control_roc_pulser_on(int Link, uint FirstChannel, int DutyCycle = 10, int Delay = 1000, + int ROCSleepTime = 5000) { //----------------------------------------------------------------------------- // convert into enum //----------------------------------------------------------------------------- diff --git a/scripts/control_roc_rates.C b/scripts/control_roc_rates.C new file mode 100644 index 0000000..63d0d36 --- /dev/null +++ b/scripts/control_roc_rates.C @@ -0,0 +1,99 @@ +// +#define __CLING__ 1 + +#include "scripts/trk_utils.C" + +#include "dtcInterfaceLib/DTC.h" +#include "dtcInterfaceLib/DTCSoftwareCFO.h" + +using namespace DTCLib; + +//----------------------------------------------------------------------------- +// should be 96*3*2+2*2 = 580 16-bit words +// 3 words per channel (straw) +//----------------------------------------------------------------------------- +void control_roc_print_rates(uint16_t* data, int nw) { + if (nw != 580) { + printf("ERROR: nw = %5i != 580. BAIL OUT\n",nw); + return; + } + + printf(" channel Total(HV) Total(CAL) Total(HV.and.CAL)\n"); + printf("------------------------------------------------\n"); + int loc(0); + for (int ich=0; ich<96; ich++) { + loc = 6*ich; + int rate_hv = int(data[loc ])+(int(data[loc+1]) << 16); + int rate_cal = int(data[loc+2])+(int(data[loc+3]) << 16); + int rate_coic = int(data[loc+4])+(int(data[loc+5]) << 16); + printf(" %5i %10i %10i %10i\n",ich,rate_hv, rate_cal, rate_coic); + } + // finally, the last two words - total counts + loc = 576; + int iw1 = int(data[loc ])+(int(data[loc+1]) << 16); + int iw2 = int(data[loc+2])+(int(data[loc+3]) << 16); + printf(" total_hv: %10i total_cal: %10i\n",iw1,iw2); +} + +//----------------------------------------------------------------------------- +// PrintLevel=0: no printout +// 1: hex dump +// 2: formatted printout +//----------------------------------------------------------------------------- +void control_roc_rates(int Link, int PrintLevel = 0) { +//----------------------------------------------------------------------------- +// convert into enum +// DTC has already been initialized, don't reco +//----------------------------------------------------------------------------- + auto roc = DTC_Link_ID(Link); + + + DtcInterface* dtc_i = trkdaq::DtcInterface::Instance(-1); + DTCLib::DTC* dtc = dtc_i->Dtc(); + + int roc_mask = 1 << (4*Link); + + dtc->WriteROCRegister(roc,14,0x01,false,1000); // reset the roc +//----------------------------------------------------------------------------- +// write parameters into reg *** (block write) , sleep for some time, +// then wait till reg 128 returns 0x8000 +// chan mask always includes the first channel +//----------------------------------------------------------------------------- + vector vec; + + int num_lookback = 100; + vec.push_back(uint16_t(num_lookback)); + int num_samples = 10; + vec.push_back(uint16_t(num_samples)); + + uint16_t ch_mask[6]; + for (int i=0; i<6; i++) { + ch_mask[i] = 0xffff; + vec.push_back(ch_mask[i]); + } + + dtc->WriteROCBlock (roc,271,vec,false,false,1000); + std::this_thread::sleep_for(std::chrono::microseconds(1000)); + + // 0x86 = 0x82 + 4 + uint16_t u; + while ((u = dtc->ReadROCRegister(roc,128,5000)) != 0x8000) {}; + printf("reg:%03i val:0x%04x\n",128,u); +//----------------------------------------------------------------------------- +// register 129: number of words to read, currently- (+ 4) (ask Monica) +//----------------------------------------------------------------------------- + int nw = dtc->ReadROCRegister(roc,129,100); printf("reg:%03i val:0x%04x\n",129,nw); + + nw = nw-4; + vector v2; + dtc->ReadROCBlock(v2,roc,271,nw,false,100); +//----------------------------------------------------------------------------- +// print output - in two formats +//----------------------------------------------------------------------------- + if (PrintLevel > 0) { + print_buffer(v2.data(),nw); + } + if (PrintLevel > 1) { + control_roc_print_rates(v2.data(),nw); + } +} diff --git a/scripts/set_gain.C b/scripts/control_roc_set_gain.C similarity index 95% rename from scripts/set_gain.C rename to scripts/control_roc_set_gain.C index d2b299f..b149ab6 100644 --- a/scripts/set_gain.C +++ b/scripts/control_roc_set_gain.C @@ -12,7 +12,7 @@ using namespace DTCLib; -void set_gain(int Link, int ChannelID, int PreampType, int Gain, int ROCSleepTime = 2000) { +void control_roc_set_gain(int Link, int ChannelID, int PreampType, int Gain, int ROCSleepTime = 2000) { //----------------------------------------------------------------------------- // convert into enum //----------------------------------------------------------------------------- diff --git a/scripts/set_threshold.C b/scripts/control_roc_set_threshold.C similarity index 90% rename from scripts/set_threshold.C rename to scripts/control_roc_set_threshold.C index dab6bfc..f80e2a6 100644 --- a/scripts/set_threshold.C +++ b/scripts/control_roc_set_threshold.C @@ -14,7 +14,7 @@ using namespace DTCLib; // so can't do that for every event ... // //----------------------------------------------------------------------------- -void set_threshold(int Link, int ChannelID, int Threshold, int PreampType, int ROCSleepTime = 2000) { +void control_roc_set_threshold(int Link, int ChannelID, int Threshold, int PreampType, int ROCSleepTime = 2000) { //----------------------------------------------------------------------------- // convert into enum //----------------------------------------------------------------------------- @@ -24,7 +24,7 @@ void set_threshold(int Link, int ChannelID, int Threshold, int PreampType, int R DTC dtc(DTC_SimMode_NoCFO,-1,roc_mask,""); std::this_thread::sleep_for(std::chrono::milliseconds(100)); //----------------------------------------------------------------------------- -// write parameters into reg 266 (block write) , sleep for some time, +// write parameters into reg 267 (block write) , sleep for some time, // then wait till reg 128 returns 0x8000 //----------------------------------------------------------------------------- vector vec; @@ -33,7 +33,7 @@ void set_threshold(int Link, int ChannelID, int Threshold, int PreampType, int R vec.push_back(uint16_t(PreampType)); bool increment_address(false); - dtc.WriteROCBlock (roc,266,vec,false,increment_address,100); + dtc.WriteROCBlock (roc,267,vec,false,increment_address,100); std::this_thread::sleep_for(std::chrono::microseconds(ROCSleepTime)); // 0x86 = 0x82 + 4 diff --git a/scripts/copy_data_to_exp.sh b/scripts/copy_data_to_exp.sh index 8103e65..9b87d04 100644 --- a/scripts/copy_data_to_exp.sh +++ b/scripts/copy_data_to_exp.sh @@ -6,6 +6,7 @@ # # call format: copy_data_to_exp.sh run1 run2 [doit] # +# if run2>run1 is defined, the range of runs is copied # if "doit" is undefined, the script only prints the commands to be executed #------------------------------------------------------------------------------ rn1=`printf "%06i" $1` @@ -14,11 +15,17 @@ if [ ".$2" != "." ] ; then rn2=$2 ; else rn2=$rn1 ; fi doit=$3 echo rn1=$rn1 rn2=$rn2 doit=$doit +name_stub=${USER}_`echo $MU2E_DAQ_DIR | awk -F / '{print $NF}'` + +dest=/exp/mu2e/data/projects/vst/datasets for rn in `seq $rn1 $rn2` ; do irn=`printf "%06i" $rn` - for f in `ls /scratch/mu2e/$DAQ_USER_STUB/$TFM_CONFIG_NAME/data/raw.mu2e.trkvst.annex.${irn}_*` ; do - cmd="scp $f murat@mu2egpvm06:/exp/mu2e/data/projects/tracker/vst/datasets/raw.mu2e.trkvst.annex.art/." + for f in `ls /scratch/mu2e/$name_stub/data/raw.mu2e.trkvst.*.*.art | grep $rn` ; do + bn=`basename $f` + dsconf=`echo $bn | awk -F . '{print $4}'` + dsid=raw.mu2e.trkvst.$dsconf.art + cmd="scp $f murat@mu2egpvm06:$dest/$dsid/." echo "$cmd" if [ ".$doit" != "." ] ; then # echo doit=$doit diff --git a/scripts/daq_scripts.C b/scripts/daq_scripts.C index 071a71a..edbdf5d 100644 --- a/scripts/daq_scripts.C +++ b/scripts/daq_scripts.C @@ -85,25 +85,24 @@ void cfo_compile_run_plan(const char* InputFn, const char* OutputFn) { //----------------------------------------------------------------------------- // assume one timing chain //----------------------------------------------------------------------------- -void cfo_init_readout_ext(const char* RunPlan, uint DtcMask) { +int cfo_init_readout_ext(const char* RunPlan, uint DtcMask) { + int rc(0); CfoInterface* cfo_i = CfoInterface::Instance(); // assume already initialized - cfo_i->InitReadout(RunPlan,DtcMask); + rc = cfo_i->InitReadout(RunPlan,DtcMask); + return rc; } //----------------------------------------------------------------------------- void cfo_launch_run_plan(int PcieAddress = -1) { CfoInterface::Instance(PcieAddress)->LaunchRunPlan(); +} + //----------------------------------------------------------------------------- -// this is what it really is +// default: 1700 ns //----------------------------------------------------------------------------- - // cfo->DisableBeamOnMode (CFO_Link_ID::CFO_Link_ALL); - // cfo->DisableBeamOffMode(CFO_Link_ID::CFO_Link_ALL); - // cfo->SoftReset(); - - // usleep(10); - // cfo->EnableBeamOffMode (CFO_Link_ID::CFO_Link_ALL); +void cfo_set_event_window(int EWLength = 68) { + daq_scripts::EWLength = EWLength; } - //----------------------------------------------------------------------------- // first 8 bytes contain nbytes, but written into the CFO are 0x10000 bytes // (the sizeof(mu2e_databuff_t) 0 @@ -140,28 +139,44 @@ int dtc_configure_ja(int Clock, int Reset, int PcieAddress = -1) { //----------------------------------------------------------------------------- // test of the 'READ' command implementation over the fiber -//----------------------------------------------------------------------------- -int dtc_control_roc_read(int PcieAddr = -1) { +// if LinkMask != -1, operate on the specified links only +//----------------------------------------------------------------------------- +int dtc_control_roc_read(int LinkMask = -1, + int AdcMode = 4, + int TdcMode = 0, + int EnablePulser = 1, + uint32_t MaskC = 0xFFFFFFFF, + uint32_t MaskD = 0xFFFFFFFF, + uint32_t MaskE = 0xFFFFFFFF, + int NumSamples = 1, + int PcieAddr = -1) { + DtcInterface* dtc_i = DtcInterface::Instance(PcieAddr); ControlRoc_Read_Input_t par; - par.adc_mode = 8; - par.tdc_mode = 0; - par.num_lookback = 8; - par.num_samples = 1; - par.num_triggers[0] = 10; - par.num_triggers[1] = 0; + par.adc_mode = AdcMode; // -a + par.tdc_mode = TdcMode; // -t + par.num_lookback = 8; // -l + par.num_samples = NumSamples; // -s + par.num_triggers[0] = 10; // -T 10 + par.num_triggers[1] = 0; // -T (high bytes) - for (int i=0; i<6; i++) par.ch_mask[i] = 0xffff; - - par.enable_pulser = 1; - par.marker_clock = 3; - par.mode = 0; // - par.clock = 99; // + par.ch_mask[0] = (MaskC >> 0) & 0xffff; + par.ch_mask[1] = (MaskC >> 16) & 0xffff; + par.ch_mask[2] = (MaskD >> 0) & 0xffff; + par.ch_mask[3] = (MaskD >> 16) & 0xffff; + par.ch_mask[4] = (MaskE >> 0) & 0xffff; + par.ch_mask[5] = (MaskE >> 16) & 0xffff; + + par.enable_pulser = EnablePulser; // -p 1 + par.marker_clock = 3; // -m 3 + par.mode = 0; // + par.clock = 99; // printf("dtc_i->fLinkMask: 0x%04x\n",dtc_i->fLinkMask); - dtc_i->ControlRoc_Read(&par,0,false,2); + bool update_mask(false), print_level(2); + dtc_i->ControlRoc_Read(&par,LinkMask,update_mask,print_level); return 0; } @@ -171,17 +186,19 @@ int dtc_control_roc_read(int PcieAddr = -1) { // EnableClockMarkers: set to 0 // EnableAutogenDRP : set to 1 //----------------------------------------------------------------------------- -void dtc_init_emulated_cfo_readout_mode(int PcieAddr = -1) { +int dtc_init_emulated_cfo_readout_mode(int PcieAddr = -1) { // int EWMode, int EnableClockMarkers, int EnableAutogenDRP) { DtcInterface* dtc_i = DtcInterface::Instance(PcieAddr); - dtc_i->InitEmulatedCFOReadoutMode(); + int rc = dtc_i->InitEmulatedCFOReadoutMode(); + return rc; } //----------------------------------------------------------------------------- -void dtc_init_readout(int EmulateCfo, int RocReadoutMode, int PcieAddr = -1) { +int dtc_init_readout(int EmulateCfo, int RocReadoutMode, int PcieAddr = -1) { DtcInterface* dtc_i = DtcInterface::Instance(PcieAddr); - dtc_i->InitReadout(EmulateCfo,RocReadoutMode); + int rc = dtc_i->InitReadout(EmulateCfo,RocReadoutMode); + return rc; } //----------------------------------------------------------------------------- @@ -354,11 +371,11 @@ void dtc_read_spi(int Link, int PrintLevel = 2, int PcieAddr = -1) { // RR : ROC readout mode : 00 : ROC patterns 01: digis // XX : reserved //----------------------------------------------------------------------------- -void dtc_buffer_test_emulated_cfo(int NEvents = 3 , +int dtc_buffer_test_emulated_cfo(int NEvents = 3 , int Mode = 0x01 , uint64_t FirstTS = 0 , const char* OutputFn = nullptr) { - int pcie_addr(-1); // assume initialized + int pcie_addr(-1), rc(0); // assume initialized DtcInterface* dtc_i = DtcInterface::Instance(pcie_addr); // assume already initialized @@ -368,27 +385,32 @@ void dtc_buffer_test_emulated_cfo(int NEvents = 3 , // 68x25ns = 1700 ns // this call doesn't send EWMs int emulate_cfo = 1; - dtc_i->InitReadout(emulate_cfo,roc_readout_mode); + rc = dtc_i->InitReadout(emulate_cfo,roc_readout_mode); + if (rc < 0) return rc; // in emulated mode, always read after dtc_i->LaunchRunPlanEmulatedCfo(daq_scripts::EWLength,NEvents+1,FirstTS); // dtc_read_subevents(FirstTS,print_level,validation_level,pcie_addr,OutputFn); + + return rc; } //----------------------------------------------------------------------------- -void dtc_buffer_test_external_cfo(const char* RunPlan = "commands.bin", +int dtc_buffer_test_external_cfo(const char* RunPlan = "commands.bin", int Mode = 0x1 , uint DtcMask = 0x1 , const char* OutputFn = nullptr ) { int pcie_addr = -1; // assume initialized + int rc(0); int print_level = (Mode >> 0) & 0xff; int validation_level = (Mode >> 8) & 0xff; int roc_readout_mode = (Mode >> 16) & 0xff; int emulate_cfo = 0; - dtc_init_readout(emulate_cfo,roc_readout_mode,pcie_addr); + rc = dtc_init_readout(emulate_cfo,roc_readout_mode,pcie_addr); + if (rc < 0) return rc; //----------------------------------------------------------------------------- // for now, assume only one time chain, but provide for future //----------------------------------------------------------------------------- @@ -399,6 +421,7 @@ void dtc_buffer_test_external_cfo(const char* RunPlan = "commands.bin", //----------------------------------------------------------------------------- uint64_t first_ts = 0; dtc_read_subevents(first_ts,print_level,validation_level,pcie_addr,OutputFn); + return rc; } //----------------------------------------------------------------------------- diff --git a/scripts/parse_diagnostics_py_output.sh b/scripts/parse_diagnostics_py_output.sh new file mode 100644 index 0000000..63462be --- /dev/null +++ b/scripts/parse_diagnostics_py_output.sh @@ -0,0 +1,6 @@ +#!/usr/bin/bash + +cat thresholds.dat | grep \"cal\" | awk -F , '{print $3}' | awk -F : '{print $2}' >| thresholds_cal.json +cat thresholds.dat | grep \"hv\" | awk -F , '{print $3}' | awk -F : '{print $2}' >| thresholds_hv.json +cat thresholds.dat | grep \"cal\" | awk -F , '{print $4}' | awk -F : '{print $2}' >| gains_cal.json +cat thresholds.dat | grep \"hv\" | awk -F , '{print $4}' | awk -F : '{print $2}' >| gains_hv.json diff --git a/scripts/rates.C b/scripts/rates.C deleted file mode 100644 index bb1d2eb..0000000 --- a/scripts/rates.C +++ /dev/null @@ -1,85 +0,0 @@ -// -#define __CLING__ 1 - -#include "scripts/trk_utils.C" - -#include "dtcInterfaceLib/DTC.h" -#include "dtcInterfaceLib/DTCSoftwareCFO.h" - -using namespace DTCLib; -//----------------------------------------------------------------------------- -// rates: not implemented yet -// on mu2edaq09, a delay > 1.4 usec is needed after WriteROCRegister(258...) -// so can't do that for every event ... -// Firstchannel values: 0 to 7 -//----------------------------------------------------------------------------- -void rates( , , int PrintLevel = 0, int ROCSleepTime = 5000) { -//----------------------------------------------------------------------------- -// convert into enum -//----------------------------------------------------------------------------- - auto roc = DTC_Link_ID(Link); - - int roc_mask = 1 << (4*Link); - DTC dtc(DTC_SimMode_NoCFO,-1,roc_mask,""); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - dtc.WriteROCRegister(roc,14,0x01,false,1000); // reset the roc -//----------------------------------------------------------------------------- -// write parameters into reg *** (block write) , sleep for some time, -// then wait till reg 128 returns 0x8000 -// chan mask always includes the first channel -//----------------------------------------------------------------------------- - vector vec; - - uint16_t chan_mask = 0x10 | (0x1 << FirstChannel); - - vec.push_back(uint16_t(chan_mask)); - vec.push_back(uint16_t(DutyCycle)); - - // next go two halves of the delay, no frequency - - uint16_t w1 = ((Delay ) & 0xffff); - uint16_t w2 = ((Delay >> 16) & 0xffff); - - vec.push_back(w1); - vec.push_back(w2); - - printf("vec[0]=0x%04x\n",vec[0]); - printf("vec[1]=%i\n" ,vec[1]); - printf("vec[2]=%i\n" ,vec[2]); - printf("vec[3]=%i\n" ,vec[3]); - - bool increment_address(false); - - dtc.ReadROCRegister(roc,129,100); - - dtc.WriteROCBlock (roc,***,vec,false,false,1000); - std::this_thread::sleep_for(std::chrono::microseconds(ROCSleepTime)); - - // 0x86 = 0x82 + 4 - uint16_t u; - while ((u = dtc.ReadROCRegister(roc,128,5000)) != 0x8000) {}; - printf("reg:%03i val:0x%04x\n",128,u); -//----------------------------------------------------------------------------- -// register 129: number of words to read, currently- (+ 4) (ask Monica) -//----------------------------------------------------------------------------- - int nw = dtc.ReadROCRegister(roc,129,100); printf("reg:%03i val:0x%04x\n",129,nw); - - nw = nw-4; - vector v2; - dtc.ReadROCBlock(v2,roc,***,nw,false,100); -//----------------------------------------------------------------------------- -// print output - in two formats -//----------------------------------------------------------------------------- - print_buffer(v2.data(),nw); - - int XXXX = v2[0]; - int XXX = v2[1]; - int XX = v2[2] | (v2[3] << 16); - - printf(" chmask = 0x%04x duty cycle = %5i delay = 0x%08x\n",chmask, duty_cycle, delay); -//----------------------------------------------------------------------------- -// sleep -//----------------------------------------------------------------------------- - // std::this_thread::sleep_for(std::chrono::milliseconds(SPISleepTime)); -}