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