Line data Source code
1 : /**
2 : * @file FelixCardControllerModule.cpp FelixCardControllerModule DAQModule implementation
3 : *
4 : * This is part of the DUNE DAQ Application Framework, copyright 2020.
5 : * Licensing/copyright details are in the COPYING file that you should have
6 : * received with this code.
7 : */
8 : #include "flxlibs/felixcardcontroller/Nljs.hpp"
9 :
10 : #include "FelixCardControllerModule.hpp"
11 : #include "FelixIssues.hpp"
12 :
13 : #include "appmodel/FelixCardControllerModule.hpp"
14 : #include "appmodel/FelixDataSender.hpp"
15 : #include "appmodel/FelixDetectorToDaqConnection.hpp"
16 : #include "appmodel/FelixInterface.hpp"
17 : #include "confmodel/DetectorToDaqConnection.hpp"
18 :
19 : #include "logging/Logging.hpp"
20 :
21 : #include <nlohmann/json.hpp>
22 :
23 : #include <bitset>
24 : #include <iomanip>
25 : #include <memory>
26 : #include <string>
27 : #include <utility>
28 : #include <vector>
29 :
30 : /**
31 : * @brief Name used by TRACE TLOG calls from this source file
32 : */
33 : #define TRACE_NAME "FelixCardControllerModule" // NOLINT
34 :
35 : /**
36 : * @brief TRACE debug levels used in this source file
37 : */
38 : enum
39 : {
40 : TLVL_ENTER_EXIT_METHODS = 5,
41 : TLVL_WORK_STEPS = 10,
42 : TLVL_BOOKKEEPING = 15
43 : };
44 :
45 : namespace dunedaq {
46 : namespace flxlibs {
47 :
48 0 : FelixCardControllerModule::FelixCardControllerModule(const std::string& name)
49 : : DAQModule(name)
50 0 : , m_cfg(nullptr)
51 : {
52 :
53 0 : register_command("conf", &FelixCardControllerModule::do_configure);
54 0 : register_command("start", &FelixCardControllerModule::gth_reset);
55 0 : register_command("getregister", &FelixCardControllerModule::get_reg);
56 0 : register_command("setregister", &FelixCardControllerModule::set_reg);
57 0 : register_command("getbitfield", &FelixCardControllerModule::get_bf);
58 0 : register_command("setbifield", &FelixCardControllerModule::set_bf);
59 0 : register_command("gthreset", &FelixCardControllerModule::gth_reset);
60 0 : }
61 :
62 : void
63 0 : FelixCardControllerModule::init(const std::shared_ptr<appfwk::ConfigurationManager> cfgMgr)
64 : {
65 :
66 0 : m_cfg = cfgMgr->get_dal<appmodel::FelixCardControllerModule>(get_name());
67 0 : auto session = cfgMgr->get_session();
68 :
69 0 : auto det_connections = m_cfg->get_controls();
70 :
71 0 : for (auto det_conn : det_connections) {
72 :
73 : // Extract felix infos
74 0 : auto flx_if = det_conn->receiver()->cast<appmodel::FelixInterface>();
75 :
76 0 : auto det_senders = det_conn->senders();
77 :
78 0 : std::vector<const appmodel::FelixDataSender*> flx_senders;
79 0 : for (auto ds : det_senders) {
80 :
81 0 : if (ds->is_excluded(*session))
82 0 : continue;
83 :
84 0 : flx_senders.push_back(ds->cast<appmodel::FelixDataSender>());
85 : }
86 :
87 0 : uint32_t id = flx_if->get_card() + flx_if->get_slr();
88 :
89 0 : auto cw_p = std::make_shared<CardControllerWrapper>(id, flx_if, flx_senders);
90 0 : m_card_wrappers[id] = cw_p;
91 0 : register_node(fmt::format("controller-{}", id), cw_p);
92 :
93 0 : if (m_card_wrappers.size() == 1) {
94 : // Do the init only for the first device (whole card)
95 0 : m_card_wrappers.begin()->second->init();
96 : }
97 0 : }
98 0 : }
99 :
100 : void
101 0 : FelixCardControllerModule::do_configure(const CommandData_t& /*args*/)
102 : {
103 :
104 0 : for (auto const& [id, cw] : m_card_wrappers) {
105 0 : uint64_t aligned = cw->get_register(REG_GBT_ALIGNMENT_DONE);
106 0 : cw->configure(m_cfg->get_super_chunk_size(), m_cfg->get_emu_fanout());
107 0 : cw->check_alignment(aligned);
108 : }
109 0 : }
110 :
111 : void
112 0 : FelixCardControllerModule::get_reg(const CommandData_t& args)
113 : {
114 0 : auto conf = args.get<felixcardcontroller::GetRegisters>();
115 0 : auto id = conf.card_id + conf.log_unit_id;
116 0 : for (auto reg_name : conf.reg_names) {
117 0 : auto reg_val = m_card_wrappers.at(id)->get_register(reg_name);
118 0 : TLOG() << reg_name << " 0x" << std::hex << reg_val;
119 0 : }
120 0 : }
121 :
122 : void
123 0 : FelixCardControllerModule::set_reg(const CommandData_t& args)
124 : {
125 0 : auto conf = args.get<felixcardcontroller::SetRegisters>();
126 0 : auto id = conf.card_id + conf.log_unit_id;
127 :
128 0 : for (auto p : conf.reg_val_pairs) {
129 0 : m_card_wrappers.at(id)->set_register(p.reg_name, p.reg_val);
130 0 : }
131 0 : }
132 :
133 : void
134 0 : FelixCardControllerModule::get_bf(const CommandData_t& args)
135 : {
136 0 : auto conf = args.get<felixcardcontroller::GetBFs>();
137 0 : auto id = conf.card_id + conf.log_unit_id;
138 :
139 0 : for (auto bf_name : conf.bf_names) {
140 0 : auto bf_val = m_card_wrappers.at(id)->get_bitfield(bf_name);
141 0 : TLOG() << bf_name << " 0x" << std::hex << bf_val;
142 0 : }
143 0 : }
144 :
145 : void
146 0 : FelixCardControllerModule::set_bf(const CommandData_t& args)
147 : {
148 0 : auto conf = args.get<felixcardcontroller::SetBFs>();
149 0 : auto id = conf.card_id + conf.log_unit_id;
150 :
151 0 : for (auto p : conf.bf_val_pairs) {
152 0 : m_card_wrappers.at(id)->set_bitfield(p.reg_name, p.reg_val);
153 0 : }
154 0 : }
155 :
156 : void
157 0 : FelixCardControllerModule::gth_reset(const CommandData_t& /*args*/)
158 : {
159 : // Do the reset only for the first device (whole card)
160 0 : m_card_wrappers.begin()->second->gth_reset();
161 0 : }
162 :
163 : } // namespace flxlibs
164 : } // namespace dunedaq
165 :
166 0 : DEFINE_DUNE_DAQ_MODULE(dunedaq::flxlibs::FelixCardControllerModule)
|