Line data Source code
1 : /**
2 : * @file CardControllerWrapper.cpp
3 : *
4 : * This is part of the DUNE DAQ , copyright 2020.
5 : * Licensing/copyright details are in the COPYING file that you should have
6 : * received with this code.
7 : */
8 : // From Module
9 : #include "CardControllerWrapper.hpp"
10 : #include "FelixDefinitions.hpp"
11 : #include "FelixIssues.hpp"
12 : #include "flxlibs/opmon/CardControllerWrapper.pb.h"
13 :
14 : #include "appmodel/FelixDataSender.hpp"
15 : #include "appmodel/FelixInterface.hpp"
16 : #include "logging/Logging.hpp"
17 :
18 : #include "flxcard/FlxException.h"
19 :
20 : #include "fmt/core.h"
21 :
22 : // From STD
23 : #include <iomanip>
24 : #include <memory>
25 : #include <string>
26 :
27 : /**
28 : * @brief TRACE debug levels used in this source file
29 : */
30 : enum
31 : {
32 : TLVL_ENTER_EXIT_METHODS = 5,
33 : TLVL_WORK_STEPS = 10,
34 : TLVL_BOOKKEEPING = 15
35 : };
36 :
37 : namespace dunedaq {
38 : namespace flxlibs {
39 :
40 0 : CardControllerWrapper::CardControllerWrapper(uint32_t device_id,
41 : const appmodel::FelixInterface* flx_cfg,
42 0 : const std::vector<const appmodel::FelixDataSender*>& flx_senders)
43 0 : : m_device_id(device_id)
44 0 : , m_flx_cfg(flx_cfg)
45 0 : , m_flx_senders(flx_senders)
46 : {
47 :
48 0 : TLOG_DEBUG(TLVL_ENTER_EXIT_METHODS) << "CardControllerWrapper constructor called. Open card " << m_device_id;
49 :
50 0 : m_flx_card = std::make_unique<FlxCard>();
51 0 : if (m_flx_card == nullptr) {
52 0 : ers::fatal(flxlibs::CardError(ERS_HERE, "Couldn't create FlxCard object."));
53 : }
54 0 : open_card();
55 0 : TLOG_DEBUG(TLVL_ENTER_EXIT_METHODS) << "CardControllerWrapper constructed.";
56 0 : }
57 :
58 0 : CardControllerWrapper::~CardControllerWrapper()
59 : {
60 0 : TLOG_DEBUG(TLVL_ENTER_EXIT_METHODS)
61 0 : << "CardControllerWrapper destructor called. First stop check, then closing card.";
62 0 : close_card();
63 0 : TLOG_DEBUG(TLVL_ENTER_EXIT_METHODS) << "CardControllerWrapper destroyed.";
64 0 : }
65 :
66 : void
67 0 : CardControllerWrapper::init()
68 : {
69 :
70 : // Card initialization
71 : // this is complicated....should we repeat all code in flx_init?
72 : // For now do not do the configs of the clock chips
73 0 : const std::lock_guard<std::mutex> lock(m_card_mutex);
74 0 : m_flx_card->cfg_set_option(BF_MMCM_MAIN_LCLK_SEL, 1); // local clock
75 0 : m_flx_card->soft_reset();
76 : // si5328_configure();
77 : // si5345_configure(0);
78 0 : m_flx_card->cfg_set_option(BF_GBT_SOFT_RESET, 0xFFFFFFFFFFFF);
79 0 : m_flx_card->cfg_set_option(BF_GBT_SOFT_RESET, 0);
80 :
81 0 : int bad_channels = m_flx_card->gbt_setup(FLX_GBT_ALIGNMENT_ONE, FLX_GBT_TMODE_FEC); // What does this do?
82 0 : if (bad_channels) {
83 0 : TLOG() << bad_channels << " not aligned.";
84 : }
85 0 : m_flx_card->irq_disable(ALL_IRQS);
86 0 : }
87 :
88 : void
89 0 : CardControllerWrapper::configure(uint16_t super_chunk_size, bool emu_fanout)
90 : {
91 : // Disable all links
92 0 : for (size_t i = 0; i < 12; ++i) {
93 : // std::stringstream ss;
94 : // ss << "DECODING_LINK" << std::setw(2) << std::setfill('0') << i << "_EGROUP0_CTRL_EPATH_ENA";
95 0 : set_bitfield(fmt::format("DECODING_LINK{:02}_EGROUP0_CTRL_EPATH_ENA", i), 0);
96 : }
97 :
98 : // Enable/disable emulation
99 0 : if (emu_fanout) {
100 : // set_bitfield("FE_EMU_LOGIC_IDLES", 0); // FIXME
101 : // set_bitfield("FE_EMU_LOGIC_CHUNK_LENGTH", 0);
102 : // set_bitfield("FE_EMU_LOGIC_ENA", 0);
103 : // set_bitfield("FE_EMU_LOGIC_L1A_TRIGGERED", 0);
104 :
105 0 : set_bitfield("GBT_TOFRONTEND_FANOUT_SEL", 0);
106 0 : set_bitfield("GBT_TOHOST_FANOUT_SEL", 0xffffff);
107 0 : set_bitfield("FE_EMU_ENA_EMU_TOFRONTEND", 0);
108 0 : set_bitfield("FE_EMU_ENA_EMU_TOHOST", 1);
109 : } else {
110 : // set_register("FE_EMU_LOGIC_ENA", 0);
111 : // set_register("FE_EMU_LOGIC_L1A_TRIGGERED", 0);
112 : // set_register("FE_EMU_LOGIC_IDLES", 0);
113 : // set_register("FE_EMU_LOGIC_CHUNK_LENGTH", 0);
114 :
115 0 : set_bitfield("FE_EMU_ENA_EMU_TOFRONTEND", 0);
116 0 : set_bitfield("FE_EMU_ENA_EMU_TOHOST", 0);
117 0 : set_bitfield("GBT_TOFRONTEND_FANOUT_SEL", 0);
118 0 : set_bitfield("GBT_TOHOST_FANOUT_SEL", 0);
119 : }
120 : // Enable and configure the right links
121 :
122 0 : for (auto s : m_flx_senders) {
123 0 : set_bitfield(fmt::format("SUPER_CHUNK_FACTOR_LINK_{:02}", s->get_link()), super_chunk_size);
124 0 : set_bitfield(fmt::format("DECODING_LINK{:02}_EGROUP0_CTRL_EPATH_ENA", s->get_link()), 1);
125 : }
126 0 : }
127 :
128 : void
129 0 : CardControllerWrapper::open_card()
130 : {
131 0 : TLOG_DEBUG(TLVL_WORK_STEPS) << "Opening FELIX card " << m_device_id;
132 0 : try {
133 0 : const std::lock_guard<std::mutex> lock(m_card_mutex);
134 0 : m_flx_card->card_open(static_cast<int>(m_device_id), LOCK_NONE); // FlxCard.h
135 0 : } catch (FlxException& ex) {
136 0 : ers::error(flxlibs::CardError(ERS_HERE, ex.what()));
137 0 : exit(EXIT_FAILURE);
138 0 : }
139 0 : }
140 :
141 : void
142 0 : CardControllerWrapper::close_card()
143 : {
144 0 : TLOG_DEBUG(TLVL_WORK_STEPS) << "Closing FELIX card " << m_device_id;
145 0 : try {
146 0 : const std::lock_guard<std::mutex> lock(m_card_mutex);
147 0 : m_flx_card->card_close();
148 0 : } catch (FlxException& ex) {
149 0 : ers::error(flxlibs::CardError(ERS_HERE, ex.what()));
150 0 : exit(EXIT_FAILURE);
151 0 : }
152 0 : }
153 :
154 : uint64_t // NOLINT(build/unsigned)
155 0 : CardControllerWrapper::get_register(std::string key)
156 : {
157 0 : TLOG_DEBUG(TLVL_WORK_STEPS) << "Reading value of register " << key;
158 0 : const std::lock_guard<std::mutex> lock(m_card_mutex);
159 0 : auto reg_val = m_flx_card->cfg_get_reg(key.c_str());
160 0 : return reg_val;
161 0 : }
162 :
163 : void
164 0 : CardControllerWrapper::set_register(std::string key, uint64_t value) // NOLINT(build/unsigned)
165 : {
166 0 : TLOG_DEBUG(TLVL_WORK_STEPS) << "Setting value of register " << key << " to " << value;
167 0 : const std::lock_guard<std::mutex> lock(m_card_mutex);
168 0 : m_flx_card->cfg_set_reg(key.c_str(), value);
169 0 : }
170 :
171 : uint64_t // NOLINT(build/unsigned)
172 0 : CardControllerWrapper::get_bitfield(std::string key)
173 : {
174 0 : TLOG_DEBUG(TLVL_WORK_STEPS) << "Reading value of bitfield " << key;
175 0 : const std::lock_guard<std::mutex> lock(m_card_mutex);
176 0 : auto bf_val = m_flx_card->cfg_get_option(key.c_str(), false);
177 0 : return bf_val;
178 0 : }
179 :
180 : void
181 0 : CardControllerWrapper::set_bitfield(std::string key, uint64_t value) // NOLINT(build/unsigned)
182 : {
183 0 : TLOG_DEBUG(TLVL_WORK_STEPS) << "Setting value of bitfield " << key << " to " << value;
184 0 : ;
185 0 : const std::lock_guard<std::mutex> lock(m_card_mutex);
186 0 : m_flx_card->cfg_set_option(key.c_str(), value, false);
187 0 : }
188 :
189 : void
190 0 : CardControllerWrapper::gth_reset()
191 : {
192 0 : TLOG_DEBUG(TLVL_WORK_STEPS) << "Resetting GTH";
193 0 : const std::lock_guard<std::mutex> lock(m_card_mutex);
194 0 : for (auto i = 0; i < 6; ++i) {
195 0 : m_flx_card->gth_rx_reset(i);
196 : }
197 0 : }
198 :
199 : void
200 0 : CardControllerWrapper::check_alignment(uint64_t aligned)
201 : {
202 0 : TLOG_DEBUG(TLVL_WORK_STEPS) << "Checking link alignment for " << m_flx_cfg->get_slr();
203 :
204 0 : bool emu_fanout = get_bitfield("FE_EMU_ENA_EMU_TOHOST");
205 : // check the alingment on a logical unit
206 0 : for (auto s : m_flx_senders) {
207 : // here we want to print out a log message when the links do not appear to be aligned.
208 : // for WIB readout link_id 5 is always reserved for tp links, so alignemnt is not expected fort these
209 : #warning FIXME: Horrible remapping workaround. Temporary fix only!
210 0 : auto id_to_check = m_flx_cfg->get_slr() * 6 + s->get_link();
211 0 : bool is_aligned = aligned & (1 << id_to_check);
212 : // auto found_link = std::find(std::begin(alignment_mask), std::end(alignment_mask), li.link_id);
213 : // if(found_link == std::end(alignment_mask)) {
214 : // if(!lu_cfg.emu_fanout && !is_aligned) {
215 : // ers::error(flxlibs::ChannelAlignment(ERS_HERE, li.link_id));
216 : // }
217 : // }
218 0 : if (!emu_fanout && !is_aligned) {
219 0 : ers::error(flxlibs::ChannelAlignment(ERS_HERE, s->get_link()));
220 : }
221 : }
222 0 : }
223 :
224 : void
225 0 : CardControllerWrapper::generate_opmon_data()
226 : {
227 0 : TLOG_DEBUG(TLVL_WORK_STEPS) << "Monitoring link alignment for " << m_flx_cfg->get_slr();
228 :
229 0 : uint64_t aligned = get_register(REG_GBT_ALIGNMENT_DONE);
230 :
231 0 : for (auto s : m_flx_senders) {
232 :
233 0 : opmon::LinkInfo i;
234 0 : i.set_enabled(true);
235 : #warning FIXME: Horrible remapping workaround. Temporary fix only!
236 0 : auto id_to_check = m_flx_cfg->get_slr() * 6 + s->get_link();
237 0 : bool is_aligned = aligned & (1 << id_to_check);
238 0 : i.set_aligned(is_aligned);
239 0 : publish(std::move(i),
240 0 : { { "device", fmt::format("{}", m_device_id) }, { "link", fmt::format("{}", s->get_link()) } });
241 :
242 0 : } // loop over links
243 0 : }
244 :
245 : } // namespace flxlibs
246 : } // namespace dunedaq
|