LCOV - code coverage report
Current view: top level - flxlibs/src - CardControllerWrapper.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 116 0
Test Date: 2025-12-21 13:07:08 Functions: 0.0 % 27 0

            Line data    Source code
       1              : /**
       2              :  * @file CardControllerWrapper.cpp
       3              :  *
       4              :  * This is part of the DUNE DAQ , copyright 2020.
       5              :  * Licensing/copyright details are in the COPYING file that you should have
       6              :  * received with this code.
       7              :  */
       8              : // From Module
       9              : #include "CardControllerWrapper.hpp"
      10              : #include "flxlibs/opmon/CardControllerWrapper.pb.h"
      11              : #include "FelixDefinitions.hpp"
      12              : #include "FelixIssues.hpp"
      13              : 
      14              : #include "logging/Logging.hpp"
      15              : #include "appmodel/FelixDataSender.hpp"
      16              : #include "appmodel/FelixInterface.hpp"
      17              : 
      18              : #include "flxcard/FlxException.h"
      19              : 
      20              : #include "fmt/core.h"
      21              : 
      22              : // From STD
      23              : #include <iomanip>
      24              : #include <memory>
      25              : #include <string>
      26              : 
      27              : /**
      28              :  * @brief TRACE debug levels used in this source file
      29              :  */
      30              : enum
      31              : {
      32              :   TLVL_ENTER_EXIT_METHODS = 5,
      33              :   TLVL_WORK_STEPS = 10,
      34              :   TLVL_BOOKKEEPING = 15
      35              : };
      36              : 
      37              : namespace dunedaq {
      38              : namespace flxlibs {
      39              : 
      40            0 : CardControllerWrapper::CardControllerWrapper(uint32_t device_id, const appmodel::FelixInterface * flx_cfg, const std::vector<const appmodel::FelixDataSender*>& flx_senders) : 
      41            0 : m_device_id(device_id),
      42            0 : m_flx_cfg(flx_cfg),
      43            0 : m_flx_senders(flx_senders)
      44              : {
      45              : 
      46            0 :   TLOG_DEBUG(TLVL_ENTER_EXIT_METHODS)
      47            0 :     << "CardControllerWrapper constructor called. Open card " << m_device_id;
      48              :         
      49            0 :   m_flx_card = std::make_unique<FlxCard>();
      50            0 :   if (m_flx_card == nullptr) {
      51            0 :     ers::fatal(flxlibs::CardError(ERS_HERE, "Couldn't create FlxCard object."));
      52              :   }
      53            0 :   open_card();
      54            0 :   TLOG_DEBUG(TLVL_ENTER_EXIT_METHODS) << "CardControllerWrapper constructed.";
      55              : 
      56            0 : }
      57              : 
      58            0 : CardControllerWrapper::~CardControllerWrapper()
      59              : {
      60            0 :   TLOG_DEBUG(TLVL_ENTER_EXIT_METHODS)
      61            0 :     << "CardControllerWrapper destructor called. First stop check, then closing card.";
      62            0 :   close_card();
      63            0 :   TLOG_DEBUG(TLVL_ENTER_EXIT_METHODS) << "CardControllerWrapper destroyed.";
      64            0 : }
      65              : 
      66              : void
      67            0 : CardControllerWrapper::init() {
      68              : 
      69              :  // Card initialization
      70              :  // this is complicated....should we repeat all code in flx_init?
      71              :  // For now do not do the configs of the clock chips
      72            0 :  const std::lock_guard<std::mutex> lock(m_card_mutex);
      73            0 :  m_flx_card->cfg_set_option( BF_MMCM_MAIN_LCLK_SEL, 1 ); // local clock
      74            0 :  m_flx_card->soft_reset();
      75              :  //si5328_configure();
      76              :  //si5345_configure(0);
      77            0 :  m_flx_card->cfg_set_option(BF_GBT_SOFT_RESET, 0xFFFFFFFFFFFF);
      78            0 :  m_flx_card->cfg_set_option(BF_GBT_SOFT_RESET, 0);
      79              : 
      80            0 :  int bad_channels = m_flx_card->gbt_setup( FLX_GBT_ALIGNMENT_ONE, FLX_GBT_TMODE_FEC ); //What does this do?
      81            0 :  if(bad_channels) {
      82            0 :     TLOG()<< bad_channels << " not aligned.";
      83              :  }
      84            0 :  m_flx_card->irq_disable( ALL_IRQS );
      85              :  
      86            0 : }
      87              : 
      88              : void
      89            0 : CardControllerWrapper::configure(uint16_t super_chunk_size, bool emu_fanout)
      90              : {
      91              :   // Disable all links
      92            0 :   for(size_t i=0 ; i<12; ++i) {
      93              :     // std::stringstream ss;
      94              :     // ss << "DECODING_LINK" << std::setw(2) << std::setfill('0') << i << "_EGROUP0_CTRL_EPATH_ENA";
      95            0 :     set_bitfield(fmt::format("DECODING_LINK{:02}_EGROUP0_CTRL_EPATH_ENA", i), 0);
      96              :   }
      97              : 
      98              :   // Enable/disable emulation
      99            0 :   if(emu_fanout) {
     100              :     //set_bitfield("FE_EMU_LOGIC_IDLES", 0); // FIXME
     101              :     //set_bitfield("FE_EMU_LOGIC_CHUNK_LENGTH", 0);
     102              :     //set_bitfield("FE_EMU_LOGIC_ENA", 0);
     103              :     //set_bitfield("FE_EMU_LOGIC_L1A_TRIGGERED", 0);
     104              : 
     105            0 :     set_bitfield("GBT_TOFRONTEND_FANOUT_SEL", 0);
     106            0 :     set_bitfield("GBT_TOHOST_FANOUT_SEL", 0xffffff);
     107            0 :     set_bitfield("FE_EMU_ENA_EMU_TOFRONTEND", 0);
     108            0 :     set_bitfield("FE_EMU_ENA_EMU_TOHOST", 1);
     109              :   }
     110              :   else {
     111              :     //set_register("FE_EMU_LOGIC_ENA", 0);
     112              :     //set_register("FE_EMU_LOGIC_L1A_TRIGGERED", 0);
     113              :     //set_register("FE_EMU_LOGIC_IDLES", 0);
     114              :     //set_register("FE_EMU_LOGIC_CHUNK_LENGTH", 0);
     115              : 
     116            0 :     set_bitfield("FE_EMU_ENA_EMU_TOFRONTEND", 0);
     117            0 :     set_bitfield("FE_EMU_ENA_EMU_TOHOST", 0);
     118            0 :     set_bitfield("GBT_TOFRONTEND_FANOUT_SEL", 0);
     119            0 :     set_bitfield("GBT_TOHOST_FANOUT_SEL", 0);
     120              :   }
     121              :   // Enable and configure the right links
     122              :  
     123            0 :   for(auto s : m_flx_senders) {
     124            0 :     set_bitfield(fmt::format("SUPER_CHUNK_FACTOR_LINK_{:02}",s->get_link()), super_chunk_size);
     125            0 :     set_bitfield(fmt::format("DECODING_LINK{:02}_EGROUP0_CTRL_EPATH_ENA",s->get_link()), 1);
     126              :   }
     127            0 : }
     128              : 
     129              : void
     130            0 : CardControllerWrapper::open_card()
     131              : {
     132            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Opening FELIX card " << m_device_id;
     133            0 :   try {
     134            0 :     const std::lock_guard<std::mutex> lock(m_card_mutex);
     135            0 :     m_flx_card->card_open(static_cast<int>(m_device_id), LOCK_NONE); // FlxCard.h
     136            0 :   } catch (FlxException& ex) {
     137            0 :     ers::error(flxlibs::CardError(ERS_HERE, ex.what()));
     138            0 :     exit(EXIT_FAILURE);
     139            0 :   }
     140            0 : }
     141              : 
     142              : void
     143            0 : CardControllerWrapper::close_card()
     144              : {
     145            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Closing FELIX card " << m_device_id;
     146            0 :   try {
     147            0 :     const std::lock_guard<std::mutex> lock(m_card_mutex);
     148            0 :     m_flx_card->card_close();
     149            0 :   } catch (FlxException& ex) {
     150            0 :     ers::error(flxlibs::CardError(ERS_HERE, ex.what()));
     151            0 :     exit(EXIT_FAILURE);
     152            0 :   }
     153            0 : }
     154              : 
     155              : uint64_t // NOLINT(build/unsigned)
     156            0 : CardControllerWrapper::get_register(std::string key)
     157              : {
     158            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Reading value of register " << key;
     159            0 :   const std::lock_guard<std::mutex> lock(m_card_mutex);
     160            0 :   auto reg_val = m_flx_card->cfg_get_reg(key.c_str());
     161            0 :   return reg_val;
     162            0 : }
     163              : 
     164              : void
     165            0 : CardControllerWrapper::set_register(std::string key, uint64_t value) // NOLINT(build/unsigned)
     166              : {
     167            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Setting value of register " << key << " to " << value;
     168            0 :   const std::lock_guard<std::mutex> lock(m_card_mutex);
     169            0 :   m_flx_card->cfg_set_reg(key.c_str(), value);
     170            0 : }
     171              : 
     172              : uint64_t // NOLINT(build/unsigned)
     173            0 : CardControllerWrapper::get_bitfield(std::string key)
     174              : {
     175            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Reading value of bitfield " << key;
     176            0 :   const std::lock_guard<std::mutex> lock(m_card_mutex);
     177            0 :   auto bf_val = m_flx_card->cfg_get_option(key.c_str(), false);
     178            0 :   return bf_val;
     179            0 : }
     180              : 
     181              : void
     182            0 : CardControllerWrapper::set_bitfield(std::string key, uint64_t value) // NOLINT(build/unsigned)
     183              : {
     184            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Setting value of bitfield " << key << " to " << value;;
     185            0 :   const std::lock_guard<std::mutex> lock(m_card_mutex);
     186            0 :   m_flx_card->cfg_set_option(key.c_str(), value, false);
     187            0 : }
     188              : 
     189              : void
     190            0 : CardControllerWrapper::gth_reset()
     191              : {
     192            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Resetting GTH";
     193            0 :   const std::lock_guard<std::mutex> lock(m_card_mutex);
     194            0 :   for (auto i=0 ; i< 6; ++i) {
     195            0 :       m_flx_card->gth_rx_reset(i);
     196              :   }    
     197            0 : }
     198              : 
     199              : void
     200            0 : CardControllerWrapper::check_alignment( uint64_t aligned )
     201              : {
     202            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Checking link alignment for " << m_flx_cfg->get_slr();
     203              : 
     204            0 :   bool emu_fanout = get_bitfield("FE_EMU_ENA_EMU_TOHOST");
     205              :   // check the alingment on a logical unit
     206            0 :   for(auto s : m_flx_senders) {
     207              :     // here we want to print out a log message when the links do not appear to be aligned.
     208              :     // for WIB readout link_id 5 is always reserved for tp links, so alignemnt is not expected fort these
     209              : #warning FIXME: Horrible remapping workaround. Temporary fix only! 
     210            0 :     auto id_to_check = m_flx_cfg->get_slr() * 6 + s->get_link();
     211            0 :     bool is_aligned = aligned & (1<<id_to_check);
     212              :     // auto found_link = std::find(std::begin(alignment_mask), std::end(alignment_mask), li.link_id);
     213              :     // if(found_link == std::end(alignment_mask)) {
     214              :     //   if(!lu_cfg.emu_fanout && !is_aligned) {
     215              :     //     ers::error(flxlibs::ChannelAlignment(ERS_HERE, li.link_id));
     216              :     //   }
     217              :     // }
     218            0 :     if(!emu_fanout && !is_aligned) {
     219            0 :       ers::error(flxlibs::ChannelAlignment(ERS_HERE, s->get_link()));
     220              :     }
     221              :   }
     222            0 : }
     223              : 
     224              : void
     225            0 : CardControllerWrapper::generate_opmon_data()
     226              : {
     227            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Monitoring link alignment for " << m_flx_cfg->get_slr();
     228              : 
     229            0 :   uint64_t aligned = get_register(REG_GBT_ALIGNMENT_DONE);
     230              :   
     231            0 :   for(auto s : m_flx_senders) {
     232              : 
     233            0 :     opmon::LinkInfo i;
     234            0 :     i.set_enabled(true);
     235              : #warning FIXME: Horrible remapping workaround. Temporary fix only!
     236            0 :     auto id_to_check = m_flx_cfg->get_slr() * 6 + s->get_link();
     237            0 :     bool is_aligned = aligned & (1<<id_to_check);
     238            0 :     i.set_aligned( is_aligned );
     239            0 :     publish( std::move(i),
     240            0 :              { {"device", fmt::format("{}", m_device_id) },
     241            0 :                {"link",   fmt::format("{}", s->get_link()) } });
     242              :     
     243            0 :   } // loop over links
     244            0 : }
     245              : 
     246              :   
     247              : } // namespace flxlibs
     248              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1