22UHAL_REGISTER_DERIVED_NODE(HSINode)
39 std::stringstream status;
41 std::vector<std::pair<std::string, std::string>> ept_summary;
42 std::vector<std::pair<std::string, std::string>> hsi_summary;
49 auto hsi_buffer_count = getNode(
"buf.count").read();
51 auto hsi_re_mask = getNode(
"csr.re_mask").read();
52 auto hsi_fe_mask = getNode(
"csr.fe_mask").read();
53 auto hsi_inv_mask = getNode(
"csr.inv_mask").read();
55 getClient().dispatch();
57 hsi_summary.push_back(std::make_pair(
"Source",
format_reg_value(hsi_control.find(
"src")->second.value(), 16)));
58 hsi_summary.push_back(std::make_pair(
"Enabled",
format_reg_value(hsi_control.find(
"en")->second.value(), 16)));
59 hsi_summary.push_back(std::make_pair(
"Rising edge mask",
format_reg_value(hsi_re_mask.value(), 16)));
60 hsi_summary.push_back(std::make_pair(
"Falling edge mask",
format_reg_value(hsi_fe_mask.value(), 16)));
61 hsi_summary.push_back(std::make_pair(
"Invert mask",
format_reg_value(hsi_inv_mask.value(), 16)));
62 hsi_summary.push_back(
63 std::make_pair(
"Buffer enabled",
format_reg_value(hsi_control.find(
"buf_en")->second.value(), 16)));
64 hsi_summary.push_back(
65 std::make_pair(
"Buffer error",
format_reg_value(hsi_state.find(
"buf_err")->second.value(), 16)));
66 hsi_summary.push_back(
67 std::make_pair(
"Buffer warning",
format_reg_value(hsi_state.find(
"buf_warn")->second.value(), 16)));
68 hsi_summary.push_back(std::make_pair(
"Buffer occupancy",
to_string(hsi_buffer_count.value())));
70 status <<
format_reg_table(hsi_summary,
"HSI summary", {
"",
"" }) << std::endl;
73 TLOG() << status.str();
82 auto buffer_count = getNode(
"buf.count").read();
83 getClient().dispatch();
84 return buffer_count.value();
89uhal::ValVector<uint32_t>
93 uint32_t buffer_state = read_buffer_state();
95 uint16_t n_hsi_words = buffer_state >> 0x10;
97 n_words = n_hsi_words;
101 uhal::ValVector<uint32_t> buffer_data;
103 if (buffer_state & 0x2) {
107 if (buffer_state & 0x1) {
114 if (n_hsi_words > 1024) {
121 uint32_t events_to_read = n_hsi_words / hsi_buffer_event_words_number;
125 uint32_t words_to_read = read_all ? n_hsi_words : events_to_read * hsi_buffer_event_words_number;
129 if (!words_to_read) {
133 buffer_data = getNode(
"buf.data").readBlock(words_to_read);
134 getClient().dispatch();
141uhal::ValVector<uint32_t>
153 std::stringstream table;
156 std::vector<std::pair<std::string, uint32_t>> buffer_table;
159 for (
auto it = buffer_data.begin(); it != buffer_data.end(); ++it, ++i) {
160 std::stringstream index_stream;
161 index_stream << std::setfill(
'0') << std::setw(4) << i;
162 buffer_table.push_back(std::make_pair(index_stream.str(), *it));
167 TLOG() << table.str();
179 uint32_t clock_frequency_hz,
183 getNode(
"csr.ctrl.src").write(src);
184 getNode(
"csr.re_mask").write(re_mask);
185 getNode(
"csr.fe_mask").write(fe_mask);
186 getNode(
"csr.inv_mask").write(inv_mask);
206 TLOG() <<
"Requested rate, actual rate: " << rate <<
", " << actual_rate;
207 TLOG() <<
"prescale, divisor: " << prescale <<
", " << divisor;
209 std::stringstream trig_stream;
210 trig_stream <<
"> Random trigger rate for HSI set to " << std::setprecision(3) << std::scientific << actual_rate <<
" Hz. d: " << divisor <<
" p: " << prescale;
211 TLOG() << trig_stream.str();
213 getNode(
"csr.ctrl.rate_div_p").write(prescale);
214 getNode(
"csr.ctrl.rate_div_d").write(divisor);
216 catch (
const timing::BadRequestedFakeTriggerRate& e)
222 getClient().dispatch();
230 getNode(
"csr.ctrl.en").write(0x1);
232 getClient().dispatch();
240 getNode(
"csr.ctrl.en").write(0x0);
242 getClient().dispatch();
250 getNode(
"csr.ctrl.en").write(0x0);
252 getNode(
"csr.ctrl.buf_en").write(0x0);
253 getNode(
"csr.ctrl.buf_en").write(0x1);
255 getNode(
"csr.re_mask").write(0x0);
256 getNode(
"csr.fe_mask").write(0x0);
257 getNode(
"csr.inv_mask").write(0x0);
258 getNode(
"csr.ctrl.src").write(0x0);
261 getClient().dispatch();
269 auto buf_warning = getNode(
"csr.stat.buf_warn").read();
270 getClient().dispatch();
271 return buf_warning.value();
279 auto buf_error = getNode(
"csr.stat.buf_err").read();
280 getClient().dispatch();
281 return buf_error.value();
291 auto hsi_buffer_count = getNode(
"buf.count").read();
292 getClient().dispatch();
294 uint8_t buffer_error =
static_cast<uint8_t
>(buf_state.find(
"buf_err")->second.value());
295 uint8_t buffer_warning =
static_cast<uint8_t
>(buf_state.find(
"buf_warn")->second.value());
297 uint32_t buffer_state = buffer_error | (buffer_warning << 1);
298 buffer_state = buffer_state |
static_cast<uint32_t
>(hsi_buffer_count.value()) << 0x10;
307 auto source = getNode(
"csr.ctrl.src").read();
308 getClient().dispatch();
309 return source.value();
320 auto hsi_buffer_count = getNode(
"buf.count").read();
322 auto hsi_re_mask = getNode(
"csr.re_mask").read();
323 auto hsi_fe_mask = getNode(
"csr.fe_mask").read();
324 auto hsi_inv_mask = getNode(
"csr.inv_mask").read();
326 getClient().dispatch();
328 mon_data.
source = hsi_control.find(
"src")->second.value();
329 mon_data.
re_mask = hsi_re_mask.value();
330 mon_data.
fe_mask = hsi_fe_mask.value();
331 mon_data.
inv_mask = hsi_inv_mask.value();
332 mon_data.
buffer_enabled = hsi_control.find(
"buf_en")->second.value();
333 mon_data.
buffer_error = hsi_state.find(
"buf_err")->second.value();
334 mon_data.
buffer_warning = hsi_state.find(
"buf_warn")->second.value();
336 mon_data.
enabled = hsi_control.find(
"en")->second.value();
static void parse_periodic_fl_cmd_rate(double requested_rate, uint32_t clock_frequency_hz, double &actual_rate, uint32_t &divisor, uint32_t &prescale)
void get_info(timingfirmwareinfo::HSIFirmwareMonitorData &mon_data) const
Collect monitoring information for timing endpoint.
bool read_buffer_warning() const
Read butffer warning flag.
std::string get_status(bool print_out=false) const override
Print the status of the timing node.
void stop_hsi(bool dispatch=true) const
Stop HSI triggering.
bool read_buffer_error() const
Read butffer error flag.
void configure_hsi(uint32_t src, uint32_t re_mask, uint32_t fe_mask, uint32_t inv_mask, double rate, uint32_t clock_frequency_hz, bool dispatch=true) const
Configure HSI triggering.
uhal::ValVector< uint32_t > read_data_buffer(uint16_t &n_words, bool read_all=false, bool fail_on_error=false) const
Read the contents of the endpoint data buffer.
uint32_t read_buffer_state() const
Read butffer error/warning/word count.
void start_hsi(bool dispatch=true) const
Start HSI triggering.
std::string get_data_buffer_table(bool read_all=false, bool print_out=false) const
Print the contents of the endpoint data buffer.
uint32_t read_buffer_count() const
Read the number of words in the data buffer.
uint32_t read_signal_source_mode() const
Read signal source, 0 - hardware, 1 - internal emulation.
void reset_hsi(bool dispatch=true) const
Reset HSI.
Base class for timing nodes.
std::map< std::string, uhal::ValWord< uint32_t > > read_sub_nodes(const uhal::Node &node, bool dispatch=true) const
Read subnodes.
#define TLOG_DEBUG(lvl,...)
std::string format_reg_table(T data, std::string title, std::vector< std::string > headers)
Format reg-value table.
std::string to_string(const T &v)
std::string format_reg_value(T reg_value, uint32_t base)
void warning(const Issue &issue)
void error(const Issue &issue)
RegValue buffer_occupancy