LCOV - code coverage report
Current view: top level - wibmod/src/WIB1 - WIB.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 359 0
Test Date: 2026-10-11 15:05:20 Functions: 0.0 % 21 0

            Line data    Source code
       1              : #include "wibmod/WIB1/WIB.hh"
       2              : #include "wibmod/WIB1/BNL_UDP_Exception.hh"
       3              : #include "wibmod/WIB1/WIBException.hh"
       4              : #include <iostream>
       5              : #include <stdio.h> //snprintf
       6              : 
       7            0 : WIB::WIB(std::string const& address,
       8              :          std::string const& WIBAddressTable,
       9              :          std::string const& FEMBAddressTable,
      10            0 :          bool fullStart)
      11              :   : WIBBase(address, WIBAddressTable, FEMBAddressTable)
      12            0 :   , DAQMode(UNKNOWN)
      13            0 :   , FEMBStreamCount(4)
      14            0 :   , FEMBCDACount(2)
      15            0 :   , ContinueOnFEMBRegReadError(false)
      16            0 :   , ContinueOnFEMBSPIError(false)
      17            0 :   , ContinueOnFEMBSyncError(true)
      18            0 :   , ContinueIfListOfFEMBClockPhasesDontSync(true)
      19              : {
      20              : 
      21            0 :   if (fullStart) {
      22              :     // Figure out what kind of WIB firmware we are dealing with
      23            0 :     FEMBCount = Read("SYSTEM.FEMB_COUNT");
      24            0 :     DAQLinkCount = Read("SYSTEM.DAQ_LINK_COUNT");
      25              :     // Hardcoded lookup for RCE and FELIX
      26            0 :     if ((FEMBCount == 4) && (DAQLinkCount == 4)) {
      27            0 :       DAQMode = RCE;
      28            0 :     } else if ((FEMBCount == 4) && (DAQLinkCount == 2)) {
      29            0 :       DAQMode = FELIX;
      30              :     }
      31              :     // TODO check FEMBStreamCount and FEMCDACount from registers on the WIB
      32              :     // TODO create those registers
      33            0 :     Write("POWER.ENABLE.MASTER_BIAS", 1);
      34            0 :     started = true;
      35              :   }
      36            0 : }
      37              : 
      38            0 : WIB::~WIB() {}
      39              : 
      40              : void
      41            0 : WIB::FullStart()
      42              : {
      43              :   // Figure out what kind of WIB firmware we are dealing with
      44            0 :   FEMBCount = Read("SYSTEM.FEMB_COUNT");
      45            0 :   DAQLinkCount = Read("SYSTEM.DAQ_LINK_COUNT");
      46              :   // Hardcoded lookup for RCE and FELIX
      47            0 :   if ((FEMBCount == 4) && (DAQLinkCount == 4)) {
      48            0 :     DAQMode = RCE;
      49            0 :   } else if ((FEMBCount == 4) && (DAQLinkCount == 2)) {
      50            0 :     DAQMode = FELIX;
      51              :   }
      52              :   // TODO check FEMBStreamCount and FEMCDACount from registers on the WIB
      53              :   // TODO create those registers
      54            0 :   Write("POWER.ENABLE.MASTER_BIAS", 1);
      55            0 :   started = true;
      56            0 : }
      57              : 
      58              : void
      59            0 : WIB::EnableDAQLink(uint8_t iDAQLink)
      60              : {
      61              :   // CHeck if we know how to dael with this firmware
      62            0 :   if (!((DAQMode == RCE) || (DAQMode == FELIX))) {
      63              :     // Not RCE or FELIX firmware, return
      64            0 :     BUException::WIB_FEATURE_NOT_SUPPORTED e;
      65            0 :     e.Append("Automatic DAQLink configuration not supported with this firmware.\n");
      66            0 :     throw e;
      67            0 :   }
      68              : 
      69              :   // Build the base string for this DAQLINK
      70            0 :   std::string base("DAQ_LINK_");
      71            0 :   base.push_back(GetDAQLinkChar(iDAQLink));
      72            0 :   base.append(".CONTROL.");
      73            0 :   printf("%s\n", base.c_str());
      74              : 
      75              :   // set the CD stream enable mask from that
      76              :   uint32_t enable_mask = 0;
      77            0 :   for (size_t iStream = 0; iStream < (4 * FEMBCount / DAQLinkCount); iStream++) {
      78              :     enable_mask <<= 0x1;
      79              :   }
      80              : 
      81            0 :   Write(base + "ENABLE_CDA_STREAM", enable_mask);
      82              : 
      83            0 :   Write(base + "ENABLE", 0x1);
      84            0 : }
      85              : 
      86              : void
      87            0 : WIB::EnableDAQLink_Lite(uint8_t iDAQLink, uint8_t enable)
      88              : {
      89              :   // CHeck if we know how to dael with this firmware
      90            0 :   if (!((DAQMode == RCE) || (DAQMode == FELIX))) {
      91              :     // Not RCE or FELIX firmware, return
      92            0 :     BUException::WIB_FEATURE_NOT_SUPPORTED e;
      93            0 :     e.Append("Automatic DAQLink configuration not supported with this firmware.\n");
      94            0 :     throw e;
      95            0 :   }
      96              : 
      97              :   // Build the base string for this DAQLINK
      98            0 :   std::string base("DAQ_LINK_");
      99            0 :   base.push_back(GetDAQLinkChar(iDAQLink));
     100            0 :   base.append(".CONTROL.");
     101              : 
     102            0 :   uint8_t stream = 0;
     103            0 :   if (enable) {
     104            0 :     if (DAQMode == RCE)
     105              :       stream = 0xF;
     106              :     else
     107            0 :       stream = 0xFF;
     108              :   }
     109              : 
     110            0 :   Write(base + "ENABLE_CDA_STREAM", stream);
     111            0 :   Write(base + "ENABLE", enable);
     112            0 : }
     113              : 
     114              : /*void WIB::DisableDAQLink_Lite(uint8_t iDAQLink, uint8_t enable){
     115              :   //CHeck if we know how to dael with this firmware
     116              :   if(!((DAQMode == RCE)||(DAQMode == FELIX))){
     117              :     //Not RCE or FELIX firmware, return
     118              :     BUException::WIB_FEATURE_NOT_SUPPORTED e;
     119              :     e.Append("Automatic DAQLink configuration not supported with this firmware.\n");
     120              :     throw e;
     121              :   }
     122              : 
     123              :   //Build the base string for this DAQLINK
     124              :   std::string base("DAQ_LINK_");
     125              :   base.push_back(GetDAQLinkChar(iDAQLink));
     126              :   base.append(".CONTROL.");
     127              : 
     128              :   uint8_t stream = 0;
     129              :   if(DAQMode == RCE) stream = 0xF;
     130              :   else stream = 0xFF;
     131              : 
     132              :   if(enable){
     133              :     Write(base+"ENABLE_CDA_STREAM",stream);
     134              : 
     135              :     Write(base+"ENABLE",enable);
     136              :   }
     137              :   else{
     138              :     Write(base+"ENABLE_CDA_STREAM",0);
     139              :     Write(base+"ENABLE",0);
     140              :   }
     141              : }*/
     142              : 
     143              : void
     144            0 : WIB::InitializeWIB()
     145              : {
     146              :   // run resets
     147            0 :   Write("SYSTEM.RESET", 0xFF);
     148              :   // Set clock settings
     149            0 :   Write("POWER.ENABLE.MASTER_BIAS", 0x1); // Turn on DC/DC converter
     150            0 : }
     151              : 
     152              : // void WIB::ResetWIB(bool cntrlRegister=true, bool global=false, bool daq_path=false, bool udp=false){
     153              : void
     154            0 : WIB::ResetWIB(bool reset_udp)
     155              : {
     156              : 
     157            0 :   if (reset_udp) {
     158              :     // Resetting the UDP will stop the reply packet which will cause an error.
     159            0 :     try {
     160            0 :       Write("SYSTEM.RESET.UDP_RESET", 1);
     161            0 :     } catch (BUException::BAD_REPLY& e) {
     162              :       // do nothing
     163            0 :     }
     164              :     // Since we don't know this happened since we lack a udp response, do it again.
     165              :     // This could be extended to read register REG
     166            0 :     usleep(10000);
     167            0 :     try {
     168            0 :       Write("SYSTEM.RESET.UDP_RESET", 1);
     169            0 :     } catch (BUException::BAD_REPLY& e) {
     170              :       // do nothing
     171            0 :     }
     172            0 :     usleep(10000);
     173              :   }
     174              : 
     175              :   // Reset the control register
     176            0 :   WriteWithRetry("SYSTEM.RESET.CONTROL_REGISTER_RESET", 1);
     177            0 :   usleep(1000);
     178              : 
     179              :   // If this is felix, make sure we configure the SI5342
     180            0 :   if (DAQMode == FELIX) {
     181            0 :     Write("DAQ.SI5342.RESET", 1);
     182              :     usleep(10000);
     183            0 :     Write("DAQ.SI5342.RESET", 0);
     184            0 :     usleep(10000);
     185            0 :     printf("Configuring SI5342 for FELIX\n");
     186            0 :     LoadConfigDAQ_SI5342("default"); // use the default config file for the SI5342
     187            0 :     usleep(10000);                   // Wait for
     188            0 :     SelectSI5342(1,                  // Set input to be local oscillator for FELIX clock
     189              :                  1);                 // enable the output of the SI5342
     190              :   }
     191              : 
     192              :   // Reset the Eventbuilder PLL
     193            0 :   Write("SYSTEM.RESET.EB_PLL_RESET", 1);
     194            0 :   usleep(10000);
     195              : 
     196              :   // Reset the DAQ path
     197            0 :   Write("SYSTEM.RESET.DAQ_PATH_RESET", 1);
     198              : 
     199            0 :   usleep(10000);
     200              : 
     201              :   // Set clock settings
     202            0 :   Write("DTS.CMD_COUNT_RESET", 0xFFFFFFFF);
     203            0 :   Write("DTS.CMD_COUNT_RESET", 0);
     204              : 
     205              :   // Halt signals
     206            0 :   Write("DTS.CONVERT_CONTROL.HALT", 1);
     207            0 :   Write("DTS.CONVERT_CONTROL.ENABLE", 0);
     208              : 
     209              :   // Make sure DC/DC is on
     210            0 :   Write("POWER.ENABLE.MASTER_BIAS", 1);
     211            0 : }
     212              : 
     213              : void
     214            0 : WIB::ResetWIBAndCfgDTS(uint8_t localClock, uint8_t PDTS_TGRP, uint8_t PDTSsource, uint32_t PDTSAlignment_timeout)
     215              : {
     216            0 :   if (DAQMode == UNKNOWN) {
     217            0 :     BUException::WIB_DAQMODE_UNKNOWN e;
     218            0 :     throw e;
     219            0 :   }
     220            0 :   if (localClock > 1) {
     221            0 :     BUException::WIB_BAD_ARGS e;
     222            0 :     e.Append("localClock > 1; must be 0 (for DTS) or 1 (for local clock)\n");
     223            0 :     throw e;
     224            0 :   }
     225            0 :   if (PDTSsource > 1) {
     226            0 :     BUException::WIB_BAD_ARGS e;
     227            0 :     e.Append("PDTSsource > 1; must be 0 (for backplane) or 1 (for front panel)\n");
     228            0 :     throw e;
     229            0 :   }
     230            0 :   if (16 <= PDTS_TGRP) {
     231            0 :     BUException::WIB_BAD_ARGS e;
     232            0 :     e.Append("PDTS TGRP > 15; must be 0 to 15\n");
     233            0 :     throw e;
     234            0 :   }
     235              : 
     236              :   // get this register so we can leave it in the state it started in
     237            0 :   uint32_t slow_control_dnd = Read("SYSTEM.SLOW_CONTROL_DND");
     238              : 
     239            0 :   ResetWIB();
     240            0 :   Write("SYSTEM.SLOW_CONTROL_DND", 1);
     241            0 :   sleep(1);
     242              : 
     243            0 :   for (size_t iFEMB = 1; iFEMB <= 4; iFEMB++) {
     244            0 :     FEMBPower(iFEMB, 0);
     245              :   }
     246              : 
     247              :   // make sure everything DTS is off
     248            0 :   Write("DTS.CONVERT_CONTROL.HALT", 1);
     249            0 :   Write("DTS.CONVERT_CONTROL.ENABLE", 0);
     250            0 :   Write("DTS.CONVERT_CONTROL.START_SYNC", 0);
     251            0 :   sleep(1);
     252              : 
     253            0 :   if (localClock > 0) {
     254            0 :     printf("Configuring local clock\n");
     255              :     // Configure the SI5344 to use the local oscillator instead of the PDTS
     256            0 :     LoadConfigDTS_SI5344("default");
     257            0 :     sleep(1);
     258            0 :     SelectSI5344(1, 1);
     259            0 :     sleep(1);
     260            0 :     Write("DTS.CONVERT_CONTROL.EN_FAKE", 1);
     261            0 :     Write("DTS.CONVERT_CONTROL.LOCAL_TIMESTAMP", 1);
     262            0 :     Write("FEMB_CNC.CNC_CLOCK_SELECT", 1);
     263              :     //    Write("FEMB_CNC.ENABLE_DTS_CMDS",1);
     264            0 :     sleep(1);
     265              :   } else {
     266              :     // Configure the clocking for the PDTS (assumes the PDTS is sending idle or something)
     267            0 :     printf("Configuring DTS\n");
     268            0 :     Write("DTS.PDTS_TGRP", PDTS_TGRP);
     269            0 :     printf("Using timing group 0x%X\n", PDTS_TGRP);
     270            0 :     InitializeDTS(PDTSsource, 0, PDTSAlignment_timeout);
     271            0 :     sleep(1);
     272            0 :     Write("FEMB_CNC.CNC_CLOCK_SELECT", 1);
     273            0 :     sleep(1);
     274              :     // We are ready for the PDTS, start searching
     275            0 :     Write("DTS.PDTS_ENABLE", 1);
     276            0 :     sleep(1);
     277              :   }
     278              : 
     279              :   // Now we have the 128MHz clock
     280            0 :   Write("FEMB1.DAQ.ENABLE", 0);
     281            0 :   Write("FEMB2.DAQ.ENABLE", 0);
     282            0 :   Write("FEMB3.DAQ.ENABLE", 0);
     283            0 :   Write("FEMB4.DAQ.ENABLE", 0);
     284              : 
     285            0 :   Write("SYSTEM.SLOW_CONTROL_DND", slow_control_dnd);
     286            0 : }
     287              : 
     288              : void
     289            0 : WIB::CheckedResetWIBAndCfgDTS(uint8_t localClock, uint8_t PDTS_TGRP, uint8_t PDTSsource, uint32_t PDTSAlignment_timeout)
     290              : {
     291            0 :   if (DAQMode == UNKNOWN) {
     292            0 :     BUException::WIB_DAQMODE_UNKNOWN e;
     293            0 :     throw e;
     294            0 :   }
     295            0 :   if (localClock > 1) {
     296            0 :     BUException::WIB_BAD_ARGS e;
     297            0 :     e.Append("localClock > 1; must be 0 (for DTS) or 1 (for local clock)\n");
     298            0 :     throw e;
     299            0 :   }
     300            0 :   if (PDTSsource > 1) {
     301            0 :     BUException::WIB_BAD_ARGS e;
     302            0 :     e.Append("PDTSsource > 1; must be 0 (for backplane) or 1 (for front panel)\n");
     303            0 :     throw e;
     304            0 :   }
     305            0 :   if (16 <= PDTS_TGRP) {
     306            0 :     BUException::WIB_BAD_ARGS e;
     307            0 :     e.Append("PDTS TGRP > 15; must be 0 to 15\n");
     308            0 :     throw e;
     309            0 :   }
     310              : 
     311            0 :   bool reset_check = false;
     312              :   // Check if we are already in a good state
     313            0 :   if (localClock > 0) {
     314            0 :     printf("Checking if locked on local clock\n");
     315            0 :     reset_check = ((Read("DTS.CONVERT_CONTROL.EN_FAKE") != 1) || (Read("DTS.CCONVERT_CONTROL.LOCAL_TIMESTAMP") != 1) ||
     316            0 :                    (Read("FEMB_CNC.CNC_CLOCK_SELECT") != 1)
     317              :                    //                  || (Read("FEMB_CNC.ENABLE_DTS_CMDS") != 1)
     318            0 :                    || (Read("DTS.SI5344.INPUT_SELECT") != 1) || (Read("DTS.SI5344.ENABLE") != 1));
     319            0 :     if (!reset_check) {
     320            0 :       printf("Already in a good state\n");
     321              :     } else {
     322            0 :       printf("Need to reset for local clocking\n");
     323              :     }
     324              :   } else {
     325            0 :     printf("Checking if locked on PDTS\n");
     326            0 :     reset_check = ((Read("DTS.PDTS_TGRP") != PDTS_TGRP) || (Read("FEMB_CNC.CNC_CLOCK_SELECT") != 1) ||
     327            0 :                    (Read("DTS.PDTS_ENABLE") != 1) || (Read("DTS.CDS.LOL") != 0) || (Read("DTS.CDS.LOS") != 0) ||
     328            0 :                    (ReadWithRetry("DTS.SI5344.INPUT_SELECT") != 0) || (ReadWithRetry("DTS.SI5344.LOS") != 0) ||
     329            0 :                    (ReadWithRetry("DTS.SI5344.LOL") != 0) || (ReadWithRetry("DTS.SI5344.ENABLE") != 1) ||
     330            0 :                    (ReadWithRetry("DTS.PDTS_STATE") != 0x8));
     331            0 :     if (!reset_check) {
     332            0 :       printf("Already in a good state\n");
     333              :     } else {
     334            0 :       printf("Need to reset for PDTS\n");
     335              :     }
     336              :   }
     337              : 
     338              :   // Check the SI5342 if we're attached to FELIX
     339            0 :   if (DAQMode == FELIX) {
     340              : 
     341            0 :     if ((Read("DAQ.SI5342.ENABLE") == 0) || (Read("DAQ.SI5342.INPUT_SELECT") != 1) || (Read("DAQ.SI5342.LOL") == 1) ||
     342            0 :         (Read("DAQ.SI5342.LOS_XAXB") == 1) || (Read("DAQ.SI5342.LOS_2") == 1)) {
     343            0 :       printf("Need to reset for SI5342\n");
     344            0 :       reset_check = true;
     345              :     } else {
     346            0 :       printf("SI5342 in good state\n");
     347              :     }
     348              :   }
     349              : 
     350            0 :   if (reset_check) {
     351              :     // get this register so we can leave it in the state it started in
     352            0 :     uint32_t slow_control_dnd = Read("SYSTEM.SLOW_CONTROL_DND");
     353              : 
     354            0 :     ResetWIB();
     355            0 :     Write("SYSTEM.SLOW_CONTROL_DND", 1);
     356              : 
     357            0 :     for (size_t iFEMB = 1; iFEMB <= 4; iFEMB++) {
     358            0 :       FEMBPower(iFEMB, 0);
     359              :     }
     360              : 
     361              :     // make sure everything DTS is off
     362            0 :     Write("DTS.CONVERT_CONTROL.HALT", 1);
     363            0 :     Write("DTS.CONVERT_CONTROL.ENABLE", 0);
     364            0 :     Write("DTS.CONVERT_CONTROL.START_SYNC", 0);
     365            0 :     sleep(1);
     366              : 
     367            0 :     if (localClock > 0) {
     368            0 :       printf("Configuring local clock\n");
     369              :       // Configure the SI5344 to use the local oscillator instead of the PDTS
     370            0 :       LoadConfigDTS_SI5344("default");
     371            0 :       sleep(1);
     372            0 :       SelectSI5344(1, 1);
     373            0 :       sleep(1);
     374            0 :       Write("DTS.CONVERT_CONTROL.EN_FAKE", 1);
     375            0 :       Write("DTS.CONVERT_CONTROL.LOCAL_TIMESTAMP", 1);
     376            0 :       Write("FEMB_CNC.CNC_CLOCK_SELECT", 1);
     377              :       //      Write("FEMB_CNC.ENABLE_DTS_CMDS",1);
     378            0 :       sleep(1);
     379              :     } else {
     380              :       // Configure the clocking for the PDTS (assumes the PDTS is sending idle or something)
     381            0 :       printf("Configuring DTS\n");
     382            0 :       Write("DTS.PDTS_TGRP", PDTS_TGRP);
     383            0 :       printf("Using timing group 0x%X\n", PDTS_TGRP);
     384            0 :       InitializeDTS(PDTSsource, 0, PDTSAlignment_timeout);
     385            0 :       sleep(1);
     386            0 :       Write("FEMB_CNC.CNC_CLOCK_SELECT", 1);
     387            0 :       sleep(1);
     388              :       // We are ready for the PDTS, start searching
     389            0 :       Write("DTS.PDTS_ENABLE", 1);
     390            0 :       sleep(1);
     391              :     }
     392              : 
     393            0 :     Write("SYSTEM.SLOW_CONTROL_DND", slow_control_dnd);
     394              :   }
     395              :   // Now we have the 128MHz clock
     396            0 :   std::cout << "Resetting DAQ Links" << std::endl;
     397            0 :   size_t nLinks = 4;
     398            0 :   if (DAQMode == FELIX) {
     399            0 :     nLinks = 2;
     400              :   }
     401            0 :   for (size_t iLink = 1; iLink <= nLinks; ++iLink) {
     402            0 :     std::cout << iLink << std::endl;
     403            0 :     EnableDAQLink_Lite(iLink, 0);
     404              :   }
     405              : 
     406            0 :   Write("FEMB1.DAQ.ENABLE", 0);
     407            0 :   Write("FEMB2.DAQ.ENABLE", 0);
     408            0 :   Write("FEMB3.DAQ.ENABLE", 0);
     409            0 :   Write("FEMB4.DAQ.ENABLE", 0);
     410            0 : }
     411              : 
     412              : void
     413            0 : WIB::StartStreamToDAQ(bool link1_enabled, bool link2_enabled, bool link3_enabled, bool link4_enabled)
     414              : {
     415            0 :   if (DAQMode == UNKNOWN) {
     416            0 :     BUException::WIB_DAQMODE_UNKNOWN e;
     417            0 :     throw e;
     418            0 :   }
     419            0 :   WriteWithRetry("DTS.CONVERT_CONTROL.HALT", 1);
     420            0 :   WriteWithRetry("DTS.CONVERT_CONTROL.ENABLE", 0);
     421              : 
     422              :   // get this register so we can leave it in the state it started in
     423            0 :   uint32_t slow_control_dnd = Read("SYSTEM.SLOW_CONTROL_DND");
     424            0 :   Write("SYSTEM.SLOW_CONTROL_DND", 1);
     425              : 
     426            0 :   sleep(1);
     427            0 :   Write("FEMB_CNC.FEMB_STOP", 1);
     428            0 :   sleep(1);
     429            0 :   Write("SYSTEM.RESET.DAQ_PATH_RESET", 1);
     430            0 :   sleep(1);
     431              : 
     432              :   // Enable DAQ links
     433            0 :   if (DAQMode == FELIX) {
     434            0 :     if (link1_enabled)
     435            0 :       EnableDAQLink_Lite(1, 1);
     436            0 :     if (link2_enabled)
     437            0 :       EnableDAQLink_Lite(2, 1);
     438              :   } else {
     439            0 :     if (link3_enabled)
     440            0 :       EnableDAQLink_Lite(3, 1);
     441            0 :     if (link4_enabled)
     442            0 :       EnableDAQLink_Lite(4, 1);
     443              :   }
     444              : 
     445              :   // Enable the FEMB to align to idle and wait for convert
     446            0 :   Write("FEMB1.DAQ.ENABLE", 0xF);
     447            0 :   Write("FEMB2.DAQ.ENABLE", 0xF);
     448            0 :   Write("FEMB3.DAQ.ENABLE", 0xF);
     449            0 :   Write("FEMB4.DAQ.ENABLE", 0xF);
     450              : 
     451              :   // Start sending characters from the FEMB
     452            0 :   Write("FEMB_CNC.ENABLE_DTS_CMDS", 1);
     453            0 :   StartSyncDTS();
     454              :   //  Write("FEMB_CNC.TIMESTAMP_RESET",1);
     455              :   // Write("FEMB_CNC.FEMB_START",1);
     456              :   //  Write("SYSTEM.RESET.FEMB_COUNTER_RESET",1);
     457              : 
     458            0 :   Write("SYSTEM.SLOW_CONTROL_DND", slow_control_dnd);
     459            0 : }
     460              : 
     461              : void
     462            0 : WIB::FEMBPower(uint8_t iFEMB, bool turnOn)
     463              : {
     464            0 :   std::string reg = "POWER.ENABLE.FEMB";
     465            0 :   reg.push_back(GetFEMBChar(iFEMB));
     466            0 :   if (turnOn) {
     467            0 :     Write(reg, 0x1F);
     468              :   } else {
     469            0 :     Write(reg, 0x0);
     470              :   }
     471            0 : }
     472              : 
     473              : // void WIB::PowerOnFEMB(uint8_t iFEMB){
     474              : //   //Turn on power
     475              : //   std::string reg = "POWER.ENABLE.FEMB";
     476              : //   reg.push_back(GetFEMBChar(iFEMB));
     477              : //
     478              : //
     479              : //   const int REG_COUNT = 6;
     480              : //   uint8_t mon_reg_val = 0x1+REG_COUNT*(iFEMB-1); // starts at 0x1 and there are 6 per FEMB
     481              : //
     482              : //   for(uint8_t iReg=0;iReg < REG_COUNT;iReg++){
     483              : //     //Go measure the reg value
     484              : //     //    int iTries = 0;
     485              : //     //    const int NUM_TRIES = 100;
     486              : //     //Set the value to be read
     487              : //     Write("POWER.MON_CONTROL.ADDRESS",mon_reg_val+iReg);
     488              : //     //Wait till the output is valid
     489              : ////    for(;iTries < NUM_TRIES;iTries++){
     490              : ////      sleep(1);
     491              : ////      if(0x1 == Read("POWER.MON_CONTROL.VALID")){
     492              : ////    break;
     493              : ////      }
     494              : ////    }
     495              : ////    if (NUM_TRIES == iTries){
     496              : ////      printf("Timeout on reading FEMB: %d power reg %d\n",iFEMB,iReg);
     497              : ////    }else{
     498              : //      uint32_t reg_val = Read("POWER.MON_VALUE.MEASUREMENT");
     499              : //      printf("Reg %u 0x%04X 0x%04X\n",iReg,reg_val >> 16,reg_val&0xFFFF);
     500              : //      //    }
     501              : //  }
     502              : //
     503              : //}
     504              : //
     505              : void
     506            0 : WIB::EnableFEMBCNC()
     507              : {
     508              :   // Enable the clock and control stream to the FEMBs
     509            0 :   Write("FEMB_CNC.CNC_CLOCK_SELECT", 1);
     510            0 :   Write("FEMB_CNC.CNC_COMMAND_SELECT", 1);
     511            0 : }
     512              : void
     513            0 : WIB::DisableFEMBCNC()
     514              : {
     515              :   // Enable the clock and control stream to the FEMBs
     516            0 :   Write("FEMB_CNC.CNC_CLOCK_SELECT", 0);
     517            0 :   Write("FEMB_CNC.CNC_COMMAND_SELECT", 0);
     518            0 : }
     519              : 
     520              : bool
     521            0 : WIB::CheckDAQLinkInRange(uint8_t iDAQLink)
     522              : {
     523            0 :   if (!((iDAQLink > 0) && (iDAQLink <= DAQLinkCount))) {
     524            0 :     BUException::WIB_INDEX_OUT_OF_RANGE e;
     525            0 :     e.Append("DAQ Link\n");
     526            0 :     throw e;
     527            0 :   }
     528            0 :   return true;
     529              : }
     530              : 
     531              : char
     532            0 : WIB::GetDAQLinkChar(uint8_t iDAQLink)
     533              : {
     534            0 :   char c = '0';
     535              :   // Check if the link is in range given DAQLinkCount (throws)
     536            0 :   CheckDAQLinkInRange(iDAQLink);
     537              :   // Convert the numeric daq link number to a char
     538            0 :   switch (iDAQLink) {
     539              :     case 1:
     540              :       c = '1';
     541              :       break;
     542              :     case 2:
     543              :       c = '2';
     544              :       break;
     545              :     case 3:
     546              :       c = '3';
     547              :       break;
     548              :     case 4:
     549              :       c = '4';
     550              :       break;
     551            0 :     default:
     552            0 :       BUException::WIB_INDEX_OUT_OF_RANGE e;
     553            0 :       e.Append("DAQ Link\n");
     554            0 :       char estr[] = "0";
     555            0 :       estr[0] = c;
     556            0 :       e.Append(estr);
     557            0 :       throw e;
     558              :   }
     559            0 :   return c;
     560              : }
     561              : 
     562              : bool
     563            0 : WIB::CheckFEMBInRange(uint8_t iFEMB)
     564              : {
     565            0 :   if (!((iFEMB > 0) && (iFEMB <= FEMBCount))) {
     566            0 :     BUException::WIB_INDEX_OUT_OF_RANGE e;
     567            0 :     e.Append("FEMB\n");
     568            0 :     throw e;
     569            0 :   }
     570            0 :   return true;
     571              : }
     572              : 
     573              : char
     574            0 : WIB::GetFEMBChar(uint8_t iFEMB)
     575              : {
     576            0 :   char c = '0';
     577              :   // Check if the link is in range given FEMBCount (throws)
     578            0 :   CheckFEMBInRange(iFEMB);
     579              :   // Convert the numeric daq link number to a char
     580            0 :   switch (iFEMB) {
     581              :     case 1:
     582              :       c = '1';
     583              :       break;
     584              :     case 2:
     585              :       c = '2';
     586              :       break;
     587              :     case 3:
     588              :       c = '3';
     589              :       break;
     590              :     case 4:
     591              :       c = '4';
     592              :       break;
     593            0 :     default:
     594            0 :       BUException::WIB_INDEX_OUT_OF_RANGE e;
     595            0 :       e.Append("FEMB\n");
     596            0 :       char estr[] = "0";
     597            0 :       estr[0] = c;
     598            0 :       e.Append(estr);
     599            0 :       throw e;
     600              :   }
     601            0 :   return c;
     602              : }
     603              : 
     604              : bool
     605            0 : WIB::CheckFEMBStreamInRange(uint8_t iStream)
     606              : {
     607            0 :   if (!((iStream > 0) && (iStream <= FEMBStreamCount))) {
     608            0 :     BUException::WIB_INDEX_OUT_OF_RANGE e;
     609            0 :     e.Append("FEMB Stream");
     610            0 :     throw e;
     611            0 :   }
     612            0 :   return true;
     613              : }
     614              : 
     615              : bool
     616            0 : WIB::CheckFEMBCDInRange(uint8_t iCDA)
     617              : {
     618            0 :   if (!((iCDA > 0) && (iCDA <= FEMBCDACount))) {
     619            0 :     BUException::WIB_INDEX_OUT_OF_RANGE e;
     620            0 :     e.Append("FEMB CDA");
     621            0 :     throw e;
     622            0 :   }
     623            0 :   return true;
     624              : }
     625              : 
     626              : char
     627            0 : WIB::GetFEMBCDChar(uint8_t iCD)
     628              : {
     629            0 :   char c = '0';
     630              :   // Check if the link is in range given FEMBCount (throws)
     631            0 :   CheckFEMBCDInRange(iCD);
     632              :   // Convert the numeric daq link number to a char
     633            0 :   switch (iCD) {
     634              :     case 1:
     635              :       c = '1';
     636              :       break;
     637            0 :     case 2:
     638            0 :       c = '2';
     639            0 :       break;
     640            0 :     default:
     641            0 :       BUException::WIB_INDEX_OUT_OF_RANGE e;
     642            0 :       e.Append("FEMB CDA\n");
     643            0 :       char estr[] = "0";
     644            0 :       estr[0] = c;
     645            0 :       e.Append(estr);
     646            0 :       throw e;
     647              :   }
     648            0 :   return c;
     649              : }
     650              : 
     651              : void
     652            0 : WIB::SourceFEMB(uint64_t iFEMB, uint64_t real)
     653              : {
     654            0 :   if (iFEMB < 1) {
     655            0 :     printf("FEMB index out of range < 1\n");
     656            0 :     return;
     657              :   }
     658              : 
     659              :   /*  if(DAQMode == RCE && iFEMB > 4){
     660              :       printf("FEMB index out of range > 4 (RCE) \n");
     661              :       return;}
     662              :     if(DAQMode == FELIX && iFEMB > 2){
     663              :       printf("FEMB index out of range > 2 (FELIX) \n");
     664              :       return;}
     665              :     */
     666            0 :   std::string address("FEMB");
     667            0 :   address.push_back(GetFEMBChar(iFEMB));
     668            0 :   address.append(".DAQ.FAKE_CD.FAKE_SOURCE");
     669            0 :   Write(address, real);
     670            0 : }
        

Generated by: LCOV version 2.0-1