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 "flxlibs/opmon/CardControllerWrapper.pb.h"
11 : #include "FelixDefinitions.hpp"
12 : #include "FelixIssues.hpp"
13 :
14 : #include "logging/Logging.hpp"
15 : #include "appmodel/FelixDataSender.hpp"
16 : #include "appmodel/FelixInterface.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, const appmodel::FelixInterface * flx_cfg, const std::vector<const appmodel::FelixDataSender*>& flx_senders) :
41 0 : m_device_id(device_id),
42 0 : m_flx_cfg(flx_cfg),
43 0 : m_flx_senders(flx_senders)
44 : {
45 :
46 0 : TLOG_DEBUG(TLVL_ENTER_EXIT_METHODS)
47 0 : << "CardControllerWrapper constructor called. Open card " << m_device_id;
48 :
49 0 : m_flx_card = std::make_unique<FlxCard>();
50 0 : if (m_flx_card == nullptr) {
51 0 : ers::fatal(flxlibs::CardError(ERS_HERE, "Couldn't create FlxCard object."));
52 : }
53 0 : open_card();
54 0 : TLOG_DEBUG(TLVL_ENTER_EXIT_METHODS) << "CardControllerWrapper constructed.";
55 :
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 : // Card initialization
70 : // this is complicated....should we repeat all code in flx_init?
71 : // For now do not do the configs of the clock chips
72 0 : const std::lock_guard<std::mutex> lock(m_card_mutex);
73 0 : m_flx_card->cfg_set_option( BF_MMCM_MAIN_LCLK_SEL, 1 ); // local clock
74 0 : m_flx_card->soft_reset();
75 : //si5328_configure();
76 : //si5345_configure(0);
77 0 : m_flx_card->cfg_set_option(BF_GBT_SOFT_RESET, 0xFFFFFFFFFFFF);
78 0 : m_flx_card->cfg_set_option(BF_GBT_SOFT_RESET, 0);
79 :
80 0 : int bad_channels = m_flx_card->gbt_setup( FLX_GBT_ALIGNMENT_ONE, FLX_GBT_TMODE_FEC ); //What does this do?
81 0 : if(bad_channels) {
82 0 : TLOG()<< bad_channels << " not aligned.";
83 : }
84 0 : m_flx_card->irq_disable( ALL_IRQS );
85 :
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 : }
110 : else {
111 : //set_register("FE_EMU_LOGIC_ENA", 0);
112 : //set_register("FE_EMU_LOGIC_L1A_TRIGGERED", 0);
113 : //set_register("FE_EMU_LOGIC_IDLES", 0);
114 : //set_register("FE_EMU_LOGIC_CHUNK_LENGTH", 0);
115 :
116 0 : set_bitfield("FE_EMU_ENA_EMU_TOFRONTEND", 0);
117 0 : set_bitfield("FE_EMU_ENA_EMU_TOHOST", 0);
118 0 : set_bitfield("GBT_TOFRONTEND_FANOUT_SEL", 0);
119 0 : set_bitfield("GBT_TOHOST_FANOUT_SEL", 0);
120 : }
121 : // Enable and configure the right links
122 :
123 0 : for(auto s : m_flx_senders) {
124 0 : set_bitfield(fmt::format("SUPER_CHUNK_FACTOR_LINK_{:02}",s->get_link()), super_chunk_size);
125 0 : set_bitfield(fmt::format("DECODING_LINK{:02}_EGROUP0_CTRL_EPATH_ENA",s->get_link()), 1);
126 : }
127 0 : }
128 :
129 : void
130 0 : CardControllerWrapper::open_card()
131 : {
132 0 : TLOG_DEBUG(TLVL_WORK_STEPS) << "Opening FELIX card " << m_device_id;
133 0 : try {
134 0 : const std::lock_guard<std::mutex> lock(m_card_mutex);
135 0 : m_flx_card->card_open(static_cast<int>(m_device_id), LOCK_NONE); // FlxCard.h
136 0 : } catch (FlxException& ex) {
137 0 : ers::error(flxlibs::CardError(ERS_HERE, ex.what()));
138 0 : exit(EXIT_FAILURE);
139 0 : }
140 0 : }
141 :
142 : void
143 0 : CardControllerWrapper::close_card()
144 : {
145 0 : TLOG_DEBUG(TLVL_WORK_STEPS) << "Closing FELIX card " << m_device_id;
146 0 : try {
147 0 : const std::lock_guard<std::mutex> lock(m_card_mutex);
148 0 : m_flx_card->card_close();
149 0 : } catch (FlxException& ex) {
150 0 : ers::error(flxlibs::CardError(ERS_HERE, ex.what()));
151 0 : exit(EXIT_FAILURE);
152 0 : }
153 0 : }
154 :
155 : uint64_t // NOLINT(build/unsigned)
156 0 : CardControllerWrapper::get_register(std::string key)
157 : {
158 0 : TLOG_DEBUG(TLVL_WORK_STEPS) << "Reading value of register " << key;
159 0 : const std::lock_guard<std::mutex> lock(m_card_mutex);
160 0 : auto reg_val = m_flx_card->cfg_get_reg(key.c_str());
161 0 : return reg_val;
162 0 : }
163 :
164 : void
165 0 : CardControllerWrapper::set_register(std::string key, uint64_t value) // NOLINT(build/unsigned)
166 : {
167 0 : TLOG_DEBUG(TLVL_WORK_STEPS) << "Setting value of register " << key << " to " << value;
168 0 : const std::lock_guard<std::mutex> lock(m_card_mutex);
169 0 : m_flx_card->cfg_set_reg(key.c_str(), value);
170 0 : }
171 :
172 : uint64_t // NOLINT(build/unsigned)
173 0 : CardControllerWrapper::get_bitfield(std::string key)
174 : {
175 0 : TLOG_DEBUG(TLVL_WORK_STEPS) << "Reading value of bitfield " << key;
176 0 : const std::lock_guard<std::mutex> lock(m_card_mutex);
177 0 : auto bf_val = m_flx_card->cfg_get_option(key.c_str(), false);
178 0 : return bf_val;
179 0 : }
180 :
181 : void
182 0 : CardControllerWrapper::set_bitfield(std::string key, uint64_t value) // NOLINT(build/unsigned)
183 : {
184 0 : TLOG_DEBUG(TLVL_WORK_STEPS) << "Setting value of bitfield " << key << " to " << value;;
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) },
241 0 : {"link", fmt::format("{}", s->get_link()) } });
242 :
243 0 : } // loop over links
244 0 : }
245 :
246 :
247 : } // namespace flxlibs
248 : } // namespace dunedaq
|