From ea7aed80a7a144bdaa90890c5439408167219004 Mon Sep 17 00:00:00 2001 From: Jeremiah Mans Date: Mon, 28 Mar 2022 11:01:13 -0500 Subject: [PATCH] Add support for external trigger/spill --- include/pflib/Backend.h | 15 ++++ include/pflib/rogue/RogueWishboneInterface.h | 6 ++ src/pflib/rogue/RogueWishboneInterface.cxx | 72 ++++++++++++++++++-- tool/pftool.cc | 25 ++++++- 4 files changed, 110 insertions(+), 8 deletions(-) diff --git a/include/pflib/Backend.h b/include/pflib/Backend.h index cd34153f..98060911 100644 --- a/include/pflib/Backend.h +++ b/include/pflib/Backend.h @@ -27,12 +27,27 @@ class Backend { /** send a single calib pulse */ virtual void fc_calibpulse() = 0; + /** reset counters for a new run */ + virtual void fc_clear_run() { } + /** calib pulse setup */ virtual void fc_setup_calib(int pulse_len, int l1a_offset) = 0; /** calib pulse setup */ virtual void fc_get_setup_calib(int& pulse_len, int& l1a_offset) = 0; + /** read counters from the FC side */ + virtual void fc_read_counters(int& spill_count, int& header_occ, int& event_count, int& vetoed_counter) { } + + /** check the enables for various trigger/spill sources */ + virtual void fc_enables_read(bool& ext_l1a, bool& ext_spill, bool& timer_l1a) { } + /** set the enables for various trigger/spill sources */ + virtual void fc_enables(bool ext_l1a, bool ext_spill, bool timer_l1a) { } + /** get the period in us for the timer trigger */ + virtual int fc_timer_setup_read() { return -1; } + /** set the period in us for the timer trigger */ + virtual void fc_timer_setup(int usdelay) { } + /** reset the daq buffers */ virtual void daq_reset() = 0; diff --git a/include/pflib/rogue/RogueWishboneInterface.h b/include/pflib/rogue/RogueWishboneInterface.h index fce877ba..f7501225 100644 --- a/include/pflib/rogue/RogueWishboneInterface.h +++ b/include/pflib/rogue/RogueWishboneInterface.h @@ -61,8 +61,14 @@ class RogueWishboneInterface : public WishboneInterface, public Backend { virtual void fc_linkreset(); virtual void fc_bufferclear(); virtual void fc_calibpulse(); + virtual void fc_clear_run(); virtual void fc_setup_calib(int pulse_len, int l1a_offset); virtual void fc_get_setup_calib(int& pulse_len, int& l1a_offset); + virtual void fc_read_counters(int& spill_count, int& header_occ, int& event_count, int& vetoed); + virtual void fc_enables_read(bool& ext_l1a, bool& ext_spill, bool& timer_l1a); + virtual void fc_enables(bool ext_l1a, bool ext_spill, bool timer_l1a); + virtual int fc_timer_setup_read(); + virtual void fc_timer_setup(int usdelay); virtual void daq_reset(); virtual void daq_advance_ptr(); diff --git a/src/pflib/rogue/RogueWishboneInterface.cxx b/src/pflib/rogue/RogueWishboneInterface.cxx index d13d88b1..546cdc84 100644 --- a/src/pflib/rogue/RogueWishboneInterface.cxx +++ b/src/pflib/rogue/RogueWishboneInterface.cxx @@ -63,16 +63,34 @@ void RogueWishboneInterface::wb_clear_counters() { static const int TARGET_FC_BACKEND = 257; static const int TARGET_DAQ_BACKEND = 258; +static const int REG_FC_CONTROL = 0; +static const int MASK_FC_CONTROL_ENABLE_EXT_SPILL = 0x01; +static const int MASK_FC_CONTROL_ENABLE_EXT_L1A = 0x02; +static const int MASK_FC_CONTROL_ENABLE_TIMER_L1A = 0x04; + static const int REG_FC_SINGLES = 1; -static const int MASK_FC_SINGLE_L1A = 0x1; -static const int MASK_FC_SINGLE_LINKRESET = 0x2; -static const int MASK_FC_SINGLE_BUFFERRESET = 0x4; -static const int MASK_FC_SINGLE_CALIBPULSE = 0x8; +static const int MASK_FC_SINGLE_L1A = 0x01; +static const int MASK_FC_SINGLE_LINKRESET = 0x02; +static const int MASK_FC_SINGLE_BUFFERRESET = 0x04; +static const int MASK_FC_SINGLE_CALIBPULSE = 0x08; +static const int MASK_FC_CLEAR_FIFO = 0x10; +static const int MASK_FC_SINGLE_NEWSPILL = 0x100; + static const int REG_FC_SETUP = 2; static const int SHIFT_FC_SETUP_CALIB_PULSELEN = 24; static const int MASK_FC_SETUP_CALIB_PULSELEN = 0xF; static const int SHIFT_FC_SETUP_CALIB_L1AOFFSET = 16; static const int MASK_FC_SETUP_CALIB_L1AOFFSET = 0xFF; + +static const int REG_FC_PERIODIC_VETO = 3; +static const int SHIFT_FC_PERIODIC = 12; +static const int MASK_FC_PERIODIC = 0xFFFFF; +static const int SHIFT_FC_VETO = 0; +static const int MASK_FC_VETO = 0xFFF; + +static const int REG_FC_STATUS_HEADER_SPILL = 0x44; +static const int REG_FC_STATUS_EVENT_COUNT = 0x45; +static const int REG_FC_STATUS_VETOED = 0x49; void RogueWishboneInterface::fc_sendL1A() { wb_write(TARGET_FC_BACKEND,REG_FC_SINGLES,MASK_FC_SINGLE_L1A); @@ -83,6 +101,9 @@ void RogueWishboneInterface::fc_linkreset() { void RogueWishboneInterface::fc_bufferclear() { wb_write(TARGET_FC_BACKEND,REG_FC_SINGLES,MASK_FC_SINGLE_BUFFERRESET); } +void RogueWishboneInterface::fc_clear_run() { + wb_write(TARGET_FC_BACKEND,REG_FC_SINGLES,MASK_FC_CLEAR_FIFO); +} void RogueWishboneInterface::fc_calibpulse() { wb_write(TARGET_FC_BACKEND,REG_FC_SINGLES,MASK_FC_SINGLE_CALIBPULSE); } @@ -101,8 +122,49 @@ void RogueWishboneInterface::fc_get_setup_calib(int& pulse_len, int& l1a_offset) pulse_len=(reg>>SHIFT_FC_SETUP_CALIB_PULSELEN)&MASK_FC_SETUP_CALIB_PULSELEN; l1a_offset=(reg>>SHIFT_FC_SETUP_CALIB_L1AOFFSET)&MASK_FC_SETUP_CALIB_L1AOFFSET; } +void RogueWishboneInterface::fc_read_counters(int& spill_count, int& header_occ, int& event_count, int& vetoed) { + uint32_t reg=wb_read(TARGET_FC_BACKEND,REG_FC_STATUS_HEADER_SPILL); + static const int OCC_SHIFT = 0; + static const int OCC_MASK = 0xFF; + static const int SPILL_SHIFT = 16; + static const int SPILL_MASK = 0xFFF; + static const int VETO_SHIFT = 0; + static const int VETO_MASK = 0xFFF; + spill_count=(reg>>SPILL_SHIFT)&SPILL_MASK; + header_occ=(reg>>OCC_SHIFT)&OCC_MASK; + event_count=wb_read(TARGET_FC_BACKEND,REG_FC_STATUS_EVENT_COUNT); + vetoed=(wb_read(TARGET_FC_BACKEND,REG_FC_STATUS_VETOED)>>VETO_SHIFT)&VETO_MASK; +} +int RogueWishboneInterface::fc_timer_setup_read() { + return (wb_read(TARGET_FC_BACKEND,REG_FC_PERIODIC_VETO)>>SHIFT_FC_PERIODIC)&MASK_FC_PERIODIC; +} +void RogueWishboneInterface::fc_timer_setup(int usdelay) { + uint32_t reg=wb_read(TARGET_FC_BACKEND,REG_FC_PERIODIC_VETO); + reg=reg&MASK_FC_VETO; + reg=reg|((usdelay&MASK_FC_PERIODIC)<backend->fc_linkreset(); printf("Sent LINK RESET\n"); } + if (cmd=="RUN_CLEAR") { + pft->backend->fc_clear_run(); + std::cout << "Cleared run counters" << std::endl; + } if (cmd=="BUFFER_CLEAR") { pft->backend->fc_bufferclear(); printf("Sent BUFFER CLEAR\n"); @@ -491,8 +495,8 @@ static void fc( const std::string& cmd, PolarfireTarget* pft ) { } if (cmd=="STATUS" || do_status) { static const std::vector bit_comments = { - "all requests", - "read requests", + "orbit requests", + "l1a/read requests", "", "", "", @@ -511,7 +515,18 @@ static void fc( const std::string& cmd, PolarfireTarget* pft ) { printf(" Single bit errors: %d Double bit errors: %d\n",sbe,dbe); std::vector cnt=pft->hcal.fc().getCmdCounters(); for (int i=0; i<8; i++) - printf(" Bit %d count: %u %s\n",i,cnt[i],bit_comments.at(i)); + printf(" Bit %d count: %20u (%s)\n",i,cnt[i],bit_comments.at(i)); + int spill_count, header_occ, event_count,vetoed_counter; + pft->backend->fc_read_counters(spill_count, header_occ, event_count, vetoed_counter); + printf(" Spills: %d Events: %d Header occupancy: %d Vetoed L1A: %d\n",spill_count,event_count,header_occ,vetoed_counter); + } + if (cmd=="ENABLES") { + bool ext_l1a, ext_spill, timer_l1a; + pft->backend->fc_enables_read(ext_l1a, ext_spill, timer_l1a); + ext_l1a=BaseMenu::readline_bool("Enable external L1A? ",ext_l1a); + ext_spill=BaseMenu::readline_bool("Enable external spill? ",ext_spill); + timer_l1a=BaseMenu::readline_bool("Enable timer L1A? ",timer_l1a); + pft->backend->fc_enables(ext_l1a, ext_spill, timer_l1a); } } @@ -1007,9 +1022,11 @@ static void RunMenu( PolarfireTarget* pft_ ) { }); pfMenu menu_link({ + /* pfMenu::Line("STATUS","Dump link status", &link ), pfMenu::Line("CONFIG","Setup link", &link ), pfMenu::Line("SPY", "Spy on the uplink", &link ), + */ pfMenu::Line("QUIT","Back to top menu") }); @@ -1056,10 +1073,12 @@ static void RunMenu( PolarfireTarget* pft_ ) { pfMenu::Line("SW_L1A","Send a software L1A", &fc ), pfMenu::Line("LINK_RESET","Send a link reset", &fc ), pfMenu::Line("BUFFER_CLEAR","Send a buffer clear", &fc ), + pfMenu::Line("RUN_CLEAR","Send a run clear", &fc ), pfMenu::Line("COUNTER_RESET","Reset counters", &fc ), pfMenu::Line("FC_RESET","Reset the fast control", &fc ), pfMenu::Line("MULTISAMPLE","Setup multisample readout", &fc ), pfMenu::Line("CALIB","Setup calibration pulse", &fc ), + pfMenu::Line("ENABLES","Enable various sources of signal", &fc ), pfMenu::Line("QUIT","Back to top menu") });