Line data Source code
1 : /**
2 : * @file TimingEndpointControllerBase.cpp TimingEndpointControllerBase class
3 : * implementation
4 : *
5 : * This is part of the DUNE DAQ Software Suite, copyright 2020.
6 : * Licensing/copyright details are in the COPYING file that you should have
7 : * received with this code.
8 : */
9 :
10 : #include "timinglibs/TimingEndpointControllerBase.hpp"
11 : #include "timinglibs/dal/TimingEndpointControllerBase.hpp"
12 : #include "timinglibs/dal/TimingEndpointControllerConf.hpp"
13 :
14 : #include "timinglibs/TimingIssues.hpp"
15 : #include "timinglibs/timingcmd/Nljs.hpp"
16 : #include "timinglibs/timingcmd/Structs.hpp"
17 :
18 : #include "timing/timingfirmwareinfo/Nljs.hpp"
19 : #include "timing/timingfirmwareinfo/Structs.hpp"
20 :
21 : #include "appfwk/cmd/Nljs.hpp"
22 : #include "ers/Issue.hpp"
23 : #include "logging/Logging.hpp"
24 :
25 : #include <chrono>
26 : #include <cstdlib>
27 : #include <string>
28 : #include <thread>
29 : #include <vector>
30 :
31 : namespace dunedaq {
32 : namespace timinglibs {
33 :
34 0 : TimingEndpointControllerBase::TimingEndpointControllerBase(const std::string& name, uint number_hw_commands)
35 : : dunedaq::timinglibs::TimingController(name,
36 0 : number_hw_commands) // 2nd arg: how many hw commands can this module send?
37 : {
38 : // timing endpoint hardware commands
39 0 : register_command("endpoint_enable", &TimingEndpointControllerBase::do_endpoint_enable);
40 0 : register_command("endpoint_disable", &TimingEndpointControllerBase::do_endpoint_disable);
41 0 : register_command("endpoint_reset", &TimingEndpointControllerBase::do_endpoint_reset);
42 0 : }
43 :
44 : void
45 0 : TimingEndpointControllerBase::do_configure(const CommandData_t& data)
46 : {
47 0 : auto mdal = m_params->cast<dal::TimingEndpointControllerConf>();
48 :
49 0 : TimingController::do_configure(data); // configure hw command connection
50 :
51 : // endpoint per device in config for now...
52 0 : m_managed_endpoint_id = { mdal->get_endpoint_id() };
53 :
54 0 : configure_hardware_or_recover_state<TimingEndpointNotReady>(data, "Timing endpoint", m_endpoint_state);
55 :
56 0 : TLOG() << get_name() << " conf done for endpoint, device: " << m_timing_device;
57 0 : }
58 :
59 : void
60 0 : TimingEndpointControllerBase::send_configure_hardware_commands(const CommandData_t& data)
61 : {
62 0 : do_io_reset(data);
63 0 : std::this_thread::sleep_for(std::chrono::microseconds(7000000));
64 0 : do_endpoint_enable(data);
65 0 : }
66 :
67 : timingcmd::TimingHwCmd
68 0 : TimingEndpointControllerBase::construct_endpoint_hw_cmd(const std::string& cmd_id, uint endpoint_id)
69 : {
70 0 : timingcmd::TimingHwCmd hw_cmd;
71 0 : timingcmd::TimingEndpointCmdPayload cmd_payload;
72 : // where to check endpoint id validity
73 0 : cmd_payload.endpoint_id = endpoint_id;
74 0 : timingcmd::to_json(hw_cmd.payload, cmd_payload);
75 :
76 0 : hw_cmd.id = cmd_id;
77 0 : hw_cmd.device = m_timing_device;
78 0 : return hw_cmd;
79 0 : }
80 :
81 : void
82 0 : TimingEndpointControllerBase::do_endpoint_enable(const CommandData_t& data)
83 : {
84 0 : timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd("endpoint_enable", data);
85 :
86 : // print out some debug info
87 0 : timingcmd::TimingEndpointConfigureCmdPayload cmd_payload;
88 0 : timingcmd::from_json(data, cmd_payload);
89 :
90 0 : TLOG_DEBUG(0) << "ept enable hw cmd; a: " << cmd_payload.address;
91 0 : send_hw_cmd(std::move(hw_cmd));
92 0 : ++(m_sent_hw_command_counters.at(2).atomic);
93 0 : }
94 :
95 : void
96 0 : TimingEndpointControllerBase::do_endpoint_disable(const CommandData_t& data)
97 : {
98 0 : timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd("endpoint_disable", data);
99 0 : send_hw_cmd(std::move(hw_cmd));
100 0 : ++(m_sent_hw_command_counters.at(3).atomic);
101 0 : }
102 :
103 : void
104 0 : TimingEndpointControllerBase::do_endpoint_reset(const CommandData_t& data)
105 : {
106 0 : timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd("endpoint_reset", data);
107 :
108 0 : send_hw_cmd(std::move(hw_cmd));
109 0 : ++(m_sent_hw_command_counters.at(4).atomic);
110 0 : }
111 :
112 : // void
113 : // TimingEndpointControllerBase::get_info(opmonlib::InfoCollector& ci, int /*level*/)
114 : //{
115 :
116 : // send counters internal to the module
117 : // timingendpointcontrollerinfo::Info module_info;
118 : // module_info.sent_endpoint_io_reset_cmds = m_sent_hw_command_counters.at(0).atomic.load();
119 : // module_info.sent_endpoint_print_status_cmds = m_sent_hw_command_counters.at(1).atomic.load();
120 :
121 : // module_info.sent_endpoint_enable_cmds = m_sent_hw_command_counters.at(2).atomic.load();
122 : // module_info.sent_endpoint_disable_cmds = m_sent_hw_command_counters.at(3).atomic.load();
123 : // module_info.sent_endpoint_reset_cmds = m_sent_hw_command_counters.at(4).atomic.load();
124 : // module_info.sent_endpoint_print_timestamp_cmds = m_sent_hw_command_counters.at(5).atomic.load();
125 : // ci.add(module_info);
126 : //}
127 :
128 : void
129 0 : TimingEndpointControllerBase::process_device_info(nlohmann::json info)
130 : {
131 0 : ++m_device_infos_received_count;
132 :
133 0 : timing::timingfirmwareinfo::TimingDeviceInfo device_info;
134 0 : from_json(info, device_info);
135 :
136 0 : auto ept_info = device_info.endpoint_info;
137 :
138 0 : m_endpoint_state = ept_info.state;
139 0 : bool ready = ept_info.ready;
140 :
141 0 : TLOG_DEBUG(3) << "state: 0x" << std::hex << m_endpoint_state << ", ready: " << ready << std::dec
142 0 : << ", infos received: " << m_device_infos_received_count;
143 :
144 0 : if (m_endpoint_state == 0x8 && ready) {
145 0 : if (!m_device_ready) {
146 0 : m_device_ready = true;
147 0 : TLOG_DEBUG(2) << "Timing endpoint became ready";
148 : }
149 : } else {
150 0 : if (m_device_ready) {
151 0 : m_device_ready = false;
152 0 : TLOG_DEBUG(2) << "Timing endpoint no longer ready";
153 : }
154 : }
155 0 : }
156 : } // namespace timinglibs
157 : } // namespace dunedaq
158 :
159 : // Local Variables:
160 : // c-basic-offset: 2
161 : // End:
|