29TimingMasterControllerBase::TimingMasterControllerBase(
const std::string& name)
30 : dunedaq::timinglibs::TimingController(name, 7)
31 , m_endpoint_scan_period(0)
32 , endpoint_scan_thread(std::bind(&TimingMasterControllerBase::endpoint_scan, this, std::placeholders::_1))
34 register_command(
"conf", &TimingMasterControllerBase::do_configure);
35 register_command(
"scrap", &TimingMasterControllerBase::do_scrap);
37 register_command(
"start_scanning_endpoints", &TimingMasterControllerBase::do_start);
38 register_command(
"stop_scanning_endpoints", &TimingMasterControllerBase::do_stop);
41 register_command(
"master_set_timestamp", &TimingMasterControllerBase::do_master_set_timestamp);
42 register_command(
"master_set_endpoint_delay", &TimingMasterControllerBase::do_master_set_endpoint_delay);
43 register_command(
"master_send_fl_command", &TimingMasterControllerBase::do_master_send_fl_command);
44 register_command(
"master_measure_endpoint_rtt", &TimingMasterControllerBase::do_master_measure_endpoint_rtt);
45 register_command(
"master_endpoint_scan", &TimingMasterControllerBase::do_master_endpoint_scan);
49TimingMasterControllerBase::do_configure(
const CommandData_t& data)
51 auto mdal = m_params->cast<dal::TimingMasterControllerConf>();
53 auto monitored_endpoints = mdal->get_monitored_endpoints();
55 for (
auto endpoint : monitored_endpoints) {
56 timingcmd::EndpointLocation endpoint_location;
57 endpoint_location.address =
endpoint->get_address();
58 endpoint_location.fanout_slot =
endpoint->get_fanout_slot();
59 endpoint_location.sfp_slot =
endpoint->get_sfp_slot();
60 m_monitored_endpoint_locations.push_back(endpoint_location);
63 TimingController::do_configure(data);
65 configure_hardware_or_recover_state<TimingMasterNotReady>(data,
"Timing master");
67 TLOG() << get_name() <<
" conf done on master, device: " << m_timing_device;
69 m_endpoint_scan_period = mdal->get_endpoint_scan_period();
70 if (m_endpoint_scan_period) {
71 TLOG() << get_name() <<
" conf: master, will send delays with period [ms] " << m_endpoint_scan_period;
73 TLOG() << get_name() <<
" conf: master, will not send delays";
78TimingMasterControllerBase::do_start(
const CommandData_t& data)
80 TimingController::do_start(data);
81 if (m_endpoint_scan_period)
82 endpoint_scan_thread.start_working_thread();
83 TLOG() <<
"Endpoint monitoring started";
87TimingMasterControllerBase::do_stop(
const CommandData_t& )
89 if (endpoint_scan_thread.thread_running())
90 endpoint_scan_thread.stop_working_thread();
91 TLOG() <<
"Endpoint monitoring stopped";
95TimingMasterControllerBase::send_configure_hardware_commands(
const CommandData_t& data)
98 do_master_set_timestamp(data);
102TimingMasterControllerBase::do_master_set_timestamp(
const CommandData_t&)
104 timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd(
"set_timestamp");
106 auto mdal = m_params->cast<dal::TimingMasterControllerConf>();
107 hw_cmd.payload[
"timestamp_source"] = mdal->get_timestamp_source();
109 send_hw_cmd(std::move(hw_cmd));
110 ++(m_sent_hw_command_counters.at(1).atomic);
114TimingMasterControllerBase::do_master_set_endpoint_delay(
const CommandData_t& data)
116 timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd(
"set_endpoint_delay", data);
120 send_hw_cmd(std::move(hw_cmd));
121 ++(m_sent_hw_command_counters.at(3).atomic);
125TimingMasterControllerBase::do_master_send_fl_command(
const CommandData_t& data)
127 timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd(
"send_fl_command", data);
131 send_hw_cmd(std::move(hw_cmd));
132 ++(m_sent_hw_command_counters.at(4).atomic);
136TimingMasterControllerBase::do_master_measure_endpoint_rtt(
const CommandData_t& data)
138 timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd(
"master_measure_endpoint_rtt");
142 send_hw_cmd(std::move(hw_cmd));
143 ++(m_sent_hw_command_counters.at(5).atomic);
147TimingMasterControllerBase::do_master_endpoint_scan(
const CommandData_t& data)
149 timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd(
"master_endpoint_scan");
153 send_hw_cmd(std::move(hw_cmd));
154 ++(m_sent_hw_command_counters.at(6).atomic);
176TimingMasterControllerBase::endpoint_scan(std::atomic<bool>& running_flag)
179 std::ostringstream starting_stream;
180 starting_stream <<
": Starting endpoint_scan() method.";
181 TLOG_DEBUG(0) << get_name() << starting_stream.str();
183 while (running_flag.load() && m_endpoint_scan_period) {
185 timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd(
"master_endpoint_scan");
187 timingcmd::TimingMasterEndpointScanPayload cmd_payload;
188 cmd_payload.endpoints = m_monitored_endpoint_locations;
193 hw_cmd.payload = cmd_payload;
194 send_hw_cmd(std::move(hw_cmd));
196 ++(m_sent_hw_command_counters.at(3).atomic);
197 if (m_endpoint_scan_period) {
198 auto prev_gather_time = std::chrono::steady_clock::now();
199 auto next_gather_time = prev_gather_time + std::chrono::milliseconds(m_endpoint_scan_period);
202 auto slice_period = std::chrono::microseconds(10000);
203 auto next_slice_gather_time = prev_gather_time + slice_period;
205 bool break_flag =
false;
206 while (next_gather_time > next_slice_gather_time + slice_period) {
207 if (!running_flag.load()) {
208 TLOG_DEBUG(0) <<
"while waiting to send delays, negative run gatherer flag detected.";
212 std::this_thread::sleep_until(next_slice_gather_time);
213 next_slice_gather_time = next_slice_gather_time + slice_period;
215 if (break_flag ==
false) {
216 std::this_thread::sleep_until(next_gather_time);
219 TLOG() <<
"m_endpoint_scan_period is 0 and send delays thread is running! breaking loop!";
224 std::ostringstream exiting_stream;
225 exiting_stream <<
": Exiting endpoint_scan() method. Received " << m_sent_hw_command_counters.at(3).atomic.load()
227 TLOG_DEBUG(0) << get_name() << exiting_stream.str();
#define TLOG_DEBUG(lvl,...)
endpoint(obj, id, device)