.. _program_listing_file_register.hpp: Program Listing for File register.hpp ===================================== |exhale_lsh| :ref:`Return to documentation for file ` (``register.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "log.hpp" #include "config/config_register.hpp" #include "device.hpp" #include "regmap_manager.hpp" #include "register_device_controller.hpp" #include "hardware_monitor.hpp" #include #include #include "network/netio_evloop.hpp" template class Register { public: explicit Register(const ConfigRegister & conf); private: RegmapManager m_regmap; std::variant m_evt_loop; std::map> m_devices; std::map>> m_dev_registers; std::unique_ptr> hw_mon; void init_device(int dev_no); int get_or_init_primary(int dev_no); int get_or_init_secondary(int dev_no); int get_primary(int dev_no); }; template Register::Register(const ConfigRegister & c) : m_evt_loop{[&c](){ switch (c.evloop_type){ case EventLoopType::netio_next: return std::variant{NetioEventLoop()}; case EventLoopType::netio3_native: case EventLoopType::netio3_asio: throw std::runtime_error("Netio3 not implemented"); default: throw std::runtime_error("Unknown event loop type"); } }()} { log_init(c.verbose); for (const auto & dc : c.dconfs){ LOG_INFO("Opening device %d", dc.dev_no); init_device(dc.dev_no); } unsigned int idx = 0; //to pass the single-device configuration to DeviceRegister for (const auto & dc : c.dconfs) { LOG_INFO("Device %u: send commands to fid 0x%lx, get reply from 0x%lx", dc.dev_no, dc.fid_cmd, dc.fid_reply); int primary_no = get_or_init_primary(dc.dev_no); m_dev_registers.emplace(std::piecewise_construct, std::forward_as_tuple(dc.dev_no), std::forward_as_tuple( std::make_shared>( m_evt_loop, m_regmap, m_devices.at(dc.dev_no), m_devices.at(primary_no), c, idx)) ); ++idx; } if (c.enable_mon){ using device_pair = std::pair, std::shared_ptr>; std::vector all_devices; //make sure that that all requested devices are paired. for (const auto & dc : c.dconfs) { get_or_init_secondary(dc.dev_no); } //loop over all opened devices and match each primary with a secondary for (const auto &[dev_no, dev_ptr] : m_devices) { if (dev_ptr->is_primary()) { int secondary = get_or_init_secondary(dev_no); if (secondary != -1) { all_devices.push_back({m_devices.at(dev_no), m_devices.at(secondary)}); } else { all_devices.push_back({m_devices.at(dev_no), nullptr}); } } } LOG_INFO("Monitoring info for all devices on fid 0x%lx", c.fid_mon); hw_mon = std::make_unique>(all_devices, c); } std::visit([] (auto& evloop) { evloop.start(); }, m_evt_loop); } template void Register::init_device(int dev_no) { m_devices.emplace(dev_no, new DEV(dev_no)); unsigned int lock_mask = 0; m_devices.at(dev_no)->open_device(lock_mask); } template int Register::get_or_init_primary(int dev_no) { int primary = get_primary(dev_no); if (dev_no != primary and m_devices.count(primary) == 0){ LOG_INFO("Opening required primary device %d", primary); init_device(primary); } return primary; } template int Register::get_or_init_secondary(int dev_no) { int secondary = -1; if (m_devices.at(dev_no)->is_primary() and m_devices.at(dev_no)->get_card_endpoints() > 1){ secondary = dev_no + 1; if (m_devices.count(secondary) == 0){ LOG_INFO("Opening required secondary device (for monitoring) %d", secondary); init_device(secondary); } } else if (not m_devices.at(dev_no)->is_primary()){ secondary = dev_no; } return secondary; } template int Register::get_primary(int dev_no) { int primary{-1}; if ( m_devices.at(dev_no)->is_primary() ){ primary = dev_no; } else { primary = dev_no - 1; } return primary; }