20UHAL_REGISTER_DERIVED_NODE(FLCmdGeneratorNode)
36 std::stringstream status;
40 TLOG() << status.str();
51 throw InvalidFixedLatencyCommand(
ERS_HERE, command);
62 throw InvalidFixedLatencyCommandChannel(
ERS_HERE, channel);
70 uint32_t channel)
const
72 validate_command(command);
73 validate_channel(channel);
75 getNode(
"sel").write(channel);
77 reset_sub_nodes(getNode(
"chan_ctrl"));
79 getNode(
"chan_ctrl.type").write(command);
80 getNode(
"ctrl.force").write(0x1);
81 getClient().dispatch();
83 getNode(
"ctrl.force").write(0x0);
84 getClient().dispatch();
93 uint32_t clock_frequency_hz)
const
105 uint32_t clock_frequency_hz)
const
113 TLOG() <<
"Requested rate, actual rate: " << rate <<
", " << actual_rate;
114 TLOG() <<
"prescale, divisor: " << prescale <<
", " << divisor;
116 std::stringstream trig_stream;
117 trig_stream <<
"> Periodic rate for command 0x" << std::hex << command <<
", on channel 0x" << channel
118 <<
" set to " << std::setprecision(3) << std::scientific << actual_rate <<
" Hz";
119 TLOG() << trig_stream.str();
121 std::stringstream trigger_mode_stream;
122 trigger_mode_stream <<
"> Trigger mode: ";
125 trigger_mode_stream <<
"poisson";
127 trigger_mode_stream <<
"periodic";
129 TLOG() << trigger_mode_stream.str();
157 getNode(
"sel").write(channel);
159 getNode(
"chan_ctrl.type").write(command);
160 getNode(
"chan_ctrl.rate_div_d").write(divisor);
161 getNode(
"chan_ctrl.rate_div_p").write(prescale);
162 getNode(
"chan_ctrl.patt").write(poisson);
163 getNode(
"chan_ctrl.en").write(1);
164 getClient().dispatch();
172 validate_channel(channel);
175 getNode(
"sel").write(channel);
176 reset_sub_nodes(getNode(
"chan_ctrl"));
185 std::stringstream counters_table;
186 auto accepted_counters = getNode(
"actrs").readBlock(getNode(
"actrs").getSize());
187 auto rejected_counters = getNode(
"rctrs").readBlock(getNode(
"actrs").getSize());
188 getClient().dispatch();
190 std::vector<uhal::ValVector<uint32_t>> counters_container = { accepted_counters, rejected_counters };
193 {
"Accept counters",
"Reject counters" },
195 {
"0x0",
"0x1",
"0x2",
"0x3",
"0x4" },
199 TLOG() << counters_table.str();
200 return counters_table.str();
232 uint32_t clock_frequency_hz,
246 double div = ceil(log(clock_frequency_hz / (requested_rate * 256 * 256)) / log(2));
249 }
else if (div > 15) {
255 uint32_t ps = (uint32_t)((clock_frequency_hz / (requested_rate * 256 * (1 << divisor))) + 0.5);
256 if (ps == 0 || ps > 256)
258 throw BadRequestedFakeTriggerRate(
ERS_HERE, requested_rate, ps);
262 actual_rate =
static_cast<double>(clock_frequency_hz) / (256 * prescale * (1 << divisor));
Class for master global node.
void disable_fake_trigger(uint32_t channel) const
Clear fake trigger configuration.
virtual ~FLCmdGeneratorNode()
virtual void send_fl_cmd(uint32_t command, uint32_t channel) const
Send a fixed length command.
std::string get_cmd_counters_table(bool print_out=false) const
Get command counters status string.
void validate_channel(uint32_t channel) const
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 enable_periodic_fl_cmd(uint32_t channel, double rate, bool poisson, uint32_t clock_frequency_hz) const
Configure fake trigger.
void validate_command(uint32_t command) const
std::string get_status(bool print_out=false) const override
Get status string, optionally print.
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.
std::string format_reg_table(T data, std::string title, std::vector< std::string > headers)
Format reg-value table.
std::string format_counters_table(std::vector< T > counter_nodes, std::vector< std::string > counter_node_titles, std::string table_title, std::vector< std::string > counter_labels, std::string counter_labels_header)
Format reg-value table.
std::string format_reg_value(T reg_value, uint32_t base)