LCOV - code coverage report
Current view: top level - mu2e-pcie-utils/dtcInterfaceLib - mu2edev.h (source / functions) Coverage Total Hit
Test: mu2edaq.info.cleaned Lines: 0.0 % 7 0
Test Date: 2026-07-30 01:56:44 Functions: 0.0 % 7 0

            Line data    Source code
       1              : #ifndef MU2EDEV_H
       2              : #define MU2EDEV_H
       3              : 
       4              : // This file (mu2edev.hh) was created by Ron Rechenmacher <ron@fnal.gov> on
       5              : // Feb 13, 2014. "TERMS AND CONDITIONS" governing this file are in the README
       6              : // or COPYING file. If you do not have such a file, one can be obtained by
       7              : // contacting Ron or Fermi Lab in Batavia IL, 60510, phone: 630-840-3000.
       8              : // $RCSfile: .emacs.gnu,v $
       9              : // rev="$Revision: 1.23 $$Date: 2012/01/23 15:32:40 $";
      10              : 
      11              : #include "mu2e_driver/mu2e_mmap_ioctl.h"  //
      12              : 
      13              : #include "mu2esim.h"
      14              : 
      15              : #include <atomic>
      16              : #include <chrono>
      17              : #include <thread>
      18              : 
      19              : /// <summary>
      20              : /// This class handles the raw interaction with the mu2e device driver
      21              : /// It also will pass through device commands to the mu2esim class if it is active.
      22              : /// </summary>
      23              : class mu2edev
      24              : {
      25              :   public:
      26              :         /// <summary>
      27              :         /// Initialize counters and other data needed by the mu2edev class.
      28              :         /// Does not initialize the DTC, call init(DTC_SimMode) to do that.
      29              :         /// </summary>
      30              :         mu2edev();
      31              :         virtual ~mu2edev();
      32              : 
      33              :         /// <summary>
      34              :         /// Get the amount of time spent by the hardware executing requests, in seconds.
      35              :         /// Time counter is measured in nanoseconds, but this precision should not be relied upon, it's measured by the CPU
      36              :         /// not the hardware.
      37              :         /// </summary>
      38              :         /// <returns>Current amount of time spent in hardware calls, in seconds</returns>
      39            0 :         double GetDeviceTime() const { return deviceTime_ / 1000000000.0; }
      40              : 
      41              :         /// <summary>
      42              :         /// Reset the device time counter
      43              :         /// </summary>
      44            0 :         void ResetDeviceTime() { deviceTime_ = 0; }
      45              : 
      46              :         /// <summary>
      47              :         /// Get the current value of the write size counter
      48              :         /// </summary>
      49              :         /// <returns>Value of the write size counter</returns>
      50            0 :         size_t GetWriteSize() const { return writeSize_; }
      51              : 
      52              :         /// <summary>
      53              :         /// Reset the write size counter
      54              :         /// </summary>
      55              :         void ResetWriteSize() { writeSize_ = 0; }
      56              : 
      57              :         /// <summary>
      58              :         /// Gets the current value of the read size counter
      59              :         /// </summary>
      60              :         /// <returns>Value of the read size counter</returns>
      61            0 :         size_t GetReadSize() const { return readSize_; }
      62              : 
      63              :         /// <summary>
      64              :         /// Reset the read size counter
      65              :         /// </summary>
      66              :         void ResetReadSize() { readSize_ = 0; }
      67              : 
      68              :         /// <summary>
      69              :         /// Initialize the simulator if simMode requires it, otherwise set up DMA engines
      70              :         /// </summary>
      71              :         /// <param name="simMode">Desired simulation mode</param>
      72              :         /// <param name="dtc">Desired DTC card to use (/dev/mu2eX)</param>
      73              :         /// <param name="simMemoryFileName">If using simulated DTC, name of the memory file ("mu2esim.bin")</param>
      74              :         /// <returns>0 on success</returns>
      75              :         int  init(DTCLib::DTC_SimMode simMode, int deviceIndex, std::string simMemoryFileName = "mu2esim.bin", const std::string& uid = "");
      76              :         void initDMAEngine();
      77              : 
      78              :         /// <summary>
      79              :         /// Reads data from the DTC.
      80              :         /// Returns the number of bytes read. Negative values indicate errors.
      81              :         /// </summary>
      82              :         /// <param name="chn">Channel to read</param>
      83              :         /// <param name="buffer">Pointer to output buffer</param>
      84              :         /// <param name="tmo_ms">Timeout for read</param>
      85              :         /// <returns>Byte count of data read into buffer. Negative value indicates error.</returns>
      86              :         int read_data(DTC_DMA_Engine const& chn, void** buffer, int tmo_ms);
      87              :         /// <summary>
      88              :         /// Convert a DMA buffer pointer into the receive-ring slot index [0, MU2E_NUM_RECV_BUFFS) for
      89              :         /// the active device on the given channel. Returns -1 if ptr falls outside the mmap'd region.
      90              :         /// Useful for diagnostic prints.
      91              :         /// </summary>
      92              :         int GetBufferIndex(DTC_DMA_Engine const& chn, const void* ptr) const;
      93              :         /// <summary>
      94              :         /// Release a number of buffers held by the software on the given channel
      95              :         /// </summary>
      96              :         /// <param name="chn">Channel to release</param>
      97              :         /// <param name="num">Number of buffers to release</param>
      98              :         /// <returns>0 when successful (always)</returns>
      99              :         int read_release(DTC_DMA_Engine const& chn, unsigned num);
     100              :         /// <summary>
     101              :         /// Release all buffers held by software on the given channel
     102              :         /// </summary>
     103              :         /// <param name="chn">Channel to release (DAQ or DCS)</param>
     104              :         /// <returns>0 on success</returns>
     105              :         int release_all(DTC_DMA_Engine const& chn);
     106              :         /// <summary>
     107              :         /// Read a DTC register
     108              :         /// </summary>
     109              :         /// <param name="address">Address to read</param>
     110              :         /// <param name="tmo_ms">Timeout for read</param>
     111              :         /// <param name="output">Pointer to output word</param>
     112              :         /// <returns>0 on success</returns>
     113              :         int read_register(uint16_t address, int tmo_ms, uint32_t* output);
     114              :         /// <summary>
     115              :         /// Write to a DTC register
     116              :         /// </summary>
     117              :         /// <param name="address">Address to write</param>
     118              :         /// <param name="tmo_ms">Timeout for write</param>
     119              :         /// <param name="data">Data to write</param>
     120              :         /// <returns>0 on success</returns>
     121              :         int write_register(uint16_t address, int tmo_ms, uint32_t data);
     122              :         /// <summary>
     123              :         /// Write to a DTC register
     124              :         /// </summary>
     125              :         /// <param name="address">Address to write</param>
     126              :         /// <param name="tmo_ms">Timeout for write</param>
     127              :         /// <param name="data">Data to write</param>
     128              :         /// <param name="output">Pointer to output word</param>
     129              :         /// <returns>0 on success</returns>
     130              :         int write_register_checked(uint16_t address, int tmo_ms, uint32_t data, uint32_t* output);
     131              :         /// <summary>
     132              :         /// Write out the DMA metadata to screen
     133              :         /// </summary>
     134              :         void meta_dump();
     135              :         /// <summary>
     136              :         /// Write data to the DTC
     137              :         /// </summary>
     138              :         /// <param name="chn">Channel to write</param>
     139              :         /// <param name="buffer">Buffer containing data to write</param>
     140              :         /// <param name="bytes">Size of the buffer, in bytes</param>
     141              :         /// <returns>0 on success</returns>
     142              :         int write_data(DTC_DMA_Engine const& chn, void* buffer, size_t bytes);
     143              :         /// <summary>
     144              :         /// Close the connection to the DTC
     145              :         /// </summary>
     146              :         void close();
     147              : 
     148              :         /// <summary>
     149              :         /// Gets the file descriptor for the mu2e block device (/dev/mu2eX)
     150              :         /// </summary>
     151              :         /// <returns>File descriptor for the mu2e block device</returns>
     152              :         int get_devfd_() const { return devfd_; }
     153              : 
     154              :         /// <summary>
     155              :         /// Get the current Device Index for this instance
     156              :         /// </summary>
     157              :         /// <returns>The current Device Index for this instance</returns>
     158            0 :         int getDeviceIndex() { return activeDeviceIndex_; }
     159              :         // int  read_pcie_state(m_ioc_pcistate_t *output);
     160              :         // int  read_dma_state(int chn, int dir, m_ioc_engstate_t *output);
     161              :         // int  read_dma_stats(m_ioc_engstats_t *output);
     162              :         // int  read_trn_stats(TRNStatsArray *output);
     163              :         // int  read_test_command(m_ioc_cmd_t *output);
     164              :         // int  write_test_command(m_ioc_cmd_t input, bool start);
     165              : 
     166              :         void        begin_dcs_transaction();
     167              :         void        end_dcs_transaction(bool force = false);
     168              :         bool        thread_owns_dcs_lock();
     169              :         bool        dcs_lock_free();
     170              :         std::string get_driver_version();
     171              : 
     172              :         /// <summary>
     173              :         /// Get the current DTC UID for this instance
     174              :         /// </summary>
     175              :         /// <returns>The current DTC UID for this instance</returns>
     176            0 :         std::string getDeviceUID() { return UID_; }
     177              : 
     178              :         /// <summary>
     179              :         /// For this DTC, "spy" on C2S buffers associated with chn.
     180              :         /// Output a small portion of each buffer to stdout until ^C.
     181              :         /// Only executes once per instance lifetime (or until resetSpyHasOccurred() is called) to avoid log-file chaos.
     182              :         /// </summary>
     183              :         /// <returns>No value is returned.</returns>
     184              :         void spy(int chn, unsigned flags, std::ostream& out = std::cout);
     185              : 
     186              :         /// <summary>
     187              :         /// Reset the spy-has-occurred flag so that spy() will produce output again on the next call.
     188              :         /// </summary>
     189            0 :         void resetSpyHasOccurred() { spyHasOccurred_ = false; }
     190              : 
     191              :   private:
     192              :         // unsigned delta_(int chn, int dir);
     193              : 
     194              :         int              devfd_ = -1;
     195              :         volatile void*   mu2e_mmap_ptrs_[MU2E_MAX_NUM_DTCS][MU2E_MAX_CHANNELS][2][2];
     196              :         m_ioc_get_info_t mu2e_channel_info_[MU2E_MAX_NUM_DTCS][MU2E_MAX_CHANNELS][2];
     197              :         unsigned         buffers_held_;
     198              :         mu2esim*         simulator_;
     199              :         int              activeDeviceIndex_;
     200              :         struct DCSLock
     201              :         {
     202              :                 std::atomic<std::thread::id> thread_id{std::thread::id()};
     203              :                 std::atomic<int>             lock_count{0};
     204              :         };
     205              :         static std::array<DCSLock, MU2E_MAX_NUM_DTCS> dcs_locks_;
     206              : 
     207              :         std::atomic<long long> deviceTime_;
     208              :         std::atomic<size_t>    writeSize_;
     209              :         std::atomic<size_t>    readSize_;
     210              : 
     211              :         std::string                           UID_;
     212              :         FILE*                                 debugFp_ = 0;
     213              :         std::chrono::steady_clock::time_point lastWriteTime_;
     214              :         bool                                  spyHasOccurred_ = false;  ///< Limits spy() printout to a single invocation per instance lifetime (or until resetSpyHasOccurred() is called) to avoid log-file chaos.
     215              :         unsigned                              spyIteration_   = 0;
     216              : };
     217              : 
     218              : #endif
        

Generated by: LCOV version 2.0-1