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/TimingEndpointControllerConf.hpp"
12 : #include "timinglibs/dal/TimingEndpointControllerBase.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 0 : : dunedaq::timinglibs::TimingController(name, number_hw_commands) // 2nd arg: how many hw commands can this module send?
36 : {
37 : // timing endpoint hardware commands
38 0 : register_command("endpoint_enable", &TimingEndpointControllerBase::do_endpoint_enable);
39 0 : register_command("endpoint_disable", &TimingEndpointControllerBase::do_endpoint_disable);
40 0 : register_command("endpoint_reset", &TimingEndpointControllerBase::do_endpoint_reset);
41 0 : }
42 :
43 : void
44 0 : TimingEndpointControllerBase::do_configure(const CommandData_t& data)
45 : {
46 0 : auto mdal = m_params->cast<dal::TimingEndpointControllerConf>();
47 :
48 0 : TimingController::do_configure(data); // configure hw command connection
49 :
50 : // endpoint per device in config for now...
51 0 : m_managed_endpoint_id = {mdal->get_endpoint_id()};
52 :
53 0 : configure_hardware_or_recover_state<TimingEndpointNotReady>(data, "Timing endpoint", m_endpoint_state);
54 :
55 0 : TLOG() << get_name() << " conf done for endpoint, device: " << m_timing_device;
56 0 : }
57 :
58 : void
59 0 : TimingEndpointControllerBase::send_configure_hardware_commands(const CommandData_t& data)
60 : {
61 0 : do_io_reset(data);
62 0 : std::this_thread::sleep_for(std::chrono::microseconds(7000000));
63 0 : do_endpoint_enable(data);
64 0 : }
65 :
66 : timingcmd::TimingHwCmd
67 0 : TimingEndpointControllerBase::construct_endpoint_hw_cmd( const std::string& cmd_id, uint endpoint_id)
68 : {
69 0 : timingcmd::TimingHwCmd hw_cmd;
70 0 : timingcmd::TimingEndpointCmdPayload cmd_payload;
71 : // where to check endpoint id validity
72 0 : cmd_payload.endpoint_id = endpoint_id;
73 0 : timingcmd::to_json(hw_cmd.payload, cmd_payload);
74 :
75 0 : hw_cmd.id = cmd_id;
76 0 : hw_cmd.device = m_timing_device;
77 0 : return hw_cmd;
78 0 : }
79 :
80 : void
81 0 : TimingEndpointControllerBase::do_endpoint_enable(const CommandData_t& data)
82 : {
83 0 : timingcmd::TimingHwCmd hw_cmd =
84 0 : 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 =
99 0 : construct_hw_cmd( "endpoint_disable", data);
100 0 : send_hw_cmd(std::move(hw_cmd));
101 0 : ++(m_sent_hw_command_counters.at(3).atomic);
102 0 : }
103 :
104 : void
105 0 : TimingEndpointControllerBase::do_endpoint_reset(const CommandData_t& data)
106 : {
107 0 : timingcmd::TimingHwCmd hw_cmd =
108 0 : construct_hw_cmd( "endpoint_reset", data);
109 :
110 0 : send_hw_cmd(std::move(hw_cmd));
111 0 : ++(m_sent_hw_command_counters.at(4).atomic);
112 0 : }
113 :
114 : //void
115 : //TimingEndpointControllerBase::get_info(opmonlib::InfoCollector& ci, int /*level*/)
116 : //{
117 :
118 : // send counters internal to the module
119 : // timingendpointcontrollerinfo::Info module_info;
120 : // module_info.sent_endpoint_io_reset_cmds = m_sent_hw_command_counters.at(0).atomic.load();
121 : // module_info.sent_endpoint_print_status_cmds = m_sent_hw_command_counters.at(1).atomic.load();
122 :
123 : // module_info.sent_endpoint_enable_cmds = m_sent_hw_command_counters.at(2).atomic.load();
124 : // module_info.sent_endpoint_disable_cmds = m_sent_hw_command_counters.at(3).atomic.load();
125 : // module_info.sent_endpoint_reset_cmds = m_sent_hw_command_counters.at(4).atomic.load();
126 : // module_info.sent_endpoint_print_timestamp_cmds = m_sent_hw_command_counters.at(5).atomic.load();
127 : // ci.add(module_info);
128 : //}
129 :
130 : void
131 0 : TimingEndpointControllerBase::process_device_info(nlohmann::json info)
132 : {
133 0 : ++m_device_infos_received_count;
134 :
135 0 : timing::timingfirmwareinfo::TimingDeviceInfo device_info;
136 0 : from_json(info, device_info);
137 :
138 0 : auto ept_info = device_info.endpoint_info;
139 :
140 0 : m_endpoint_state = ept_info.state;
141 0 : bool ready = ept_info.ready;
142 :
143 0 : TLOG_DEBUG(3) << "state: 0x" << std::hex << m_endpoint_state << ", ready: " << ready << std::dec << ", infos received: " << m_device_infos_received_count;
144 :
145 0 : if (m_endpoint_state == 0x8 && ready)
146 : {
147 0 : if (!m_device_ready)
148 : {
149 0 : m_device_ready = true;
150 0 : TLOG_DEBUG(2) << "Timing endpoint became ready";
151 : }
152 : }
153 : else
154 : {
155 0 : if (m_device_ready)
156 : {
157 0 : m_device_ready = false;
158 0 : TLOG_DEBUG(2) << "Timing endpoint no longer ready";
159 : }
160 : }
161 0 : }
162 : } // namespace timinglibs
163 : } // namespace dunedaq
164 :
165 : // Local Variables:
166 : // c-basic-offset: 2
167 : // End:
|