19UHAL_REGISTER_DERIVED_NODE(TimestampGeneratorNode)
22TimestampGeneratorNode::TimestampGeneratorNode(
const uhal::Node& node)
28TimestampGeneratorNode::~TimestampGeneratorNode() {}
33TimestampGeneratorNode::get_status(
bool print_out)
const
36 status <<
"Current timestamp: 0x" << std::hex << read_timestamp() << std::endl;
37 status <<
"Start timestamp: 0x" << std::hex << read_start_timestamp() << std::endl;
38 status <<
"SW init timestamp: 0x" << std::hex << read_sw_init_timestamp() << std::endl;
40 auto ctrl_subnodes = read_sub_nodes(getNode(
"csr.ctrl"));
43 auto stat_subnodes = read_sub_nodes(getNode(
"csr.stat"));
54uhal::ValVector<uint32_t>
55TimestampGeneratorNode::read_raw_timestamp(
bool dispatch)
const
57 auto timestamp = getNode(
"ctr").readBlock(2);
59 getClient().dispatch();
66TimestampGeneratorNode::read_timestamp()
const
74TimestampGeneratorNode::read_start_timestamp()
const
76 auto start_ts_l = getNode(
"csr.tstamp_start_l").read();
77 auto start_ts_h = getNode(
"csr.tstamp_start_h").read();
78 getClient().dispatch();
79 return (uint64_t)start_ts_l.value() + ((uint64_t)start_ts_h.value() << 32);
85TimestampGeneratorNode::read_sw_init_timestamp()
const
87 auto sw_init_ts_l = getNode(
"csr.tstamp_sw_init_l").read();
88 auto sw_init_ts_h = getNode(
"csr.tstamp_sw_init_h").read();
89 getClient().dispatch();
90 return (uint64_t)sw_init_ts_l.value() + ((uint64_t)sw_init_ts_h.value() << 32);
96TimestampGeneratorNode::set_timestamp(TimestampSource source)
const
99 const uint clock_frequency_hz = 62500000;
101 const uint64_t old_timestamp = read_timestamp();
104 getNode(
"csr.ctrl.rst").write(0x1);
105 getNode(
"csr.ctrl.tstamp_source_sel").write(source);
106 getClient().dispatch();
108 uint64_t now_timestamp;
109 if (source == kSoftware)
113 else if (source == kMixed)
119 throw UnknownTimestampSource(
ERS_HERE, source);
123 if (source != kUpstream)
127 uint32_t now_ts_low = (now_timestamp >> 0) & ((1UL << 32) - 1);
128 uint32_t now_ts_high = (now_timestamp >> 32) & ((1UL << 32) - 1);
130 getNode(
"csr.tstamp_sw_init_l").write(now_ts_low);
131 getNode(
"csr.tstamp_sw_init_h").write(now_ts_high);
134 getNode(
"csr.ctrl.rst").write(0x0);
135 getNode(
"csr.ctrl.load").write(0x1);
136 getNode(
"csr.ctrl.load").write(0x0);
137 getClient().dispatch();
139 auto start = std::chrono::high_resolution_clock::now();
141 auto ts_loaded = getNode(
"csr.stat.tstamp_loaded").read();
142 auto ts_error = getNode(
"csr.stat.tstamp_error").read();
143 getClient().dispatch();
145 TLOG_DEBUG(6) << std::hex <<
"ts loaded: 0x" << ts_loaded.value() <<
", ts error: " << ts_error.value();
147 if (ts_loaded.value() && !ts_error.value())
149 const uint64_t start_ts = read_start_timestamp();
154 auto now = std::chrono::high_resolution_clock::now();
155 auto ms_since_start = std::chrono::duration_cast<std::chrono::milliseconds>(
now - start);
157 if (ms_since_start.count() > 1000)
158 throw TimestampNotReady(
ERS_HERE, ts_loaded.value(), ts_error.value());
160 std::this_thread::sleep_for(std::chrono::microseconds(10));
163 const uint64_t new_timestamp = read_timestamp();
166 getClient().dispatch();
#define TLOG_DEBUG(lvl,...)
int64_t get_seconds_since_epoch()
int64_t get_milliseconds_since_epoch()
std::string format_reg_table(T data, std::string title, std::vector< std::string > headers)
Format reg-value table.
std::string format_timestamp(uhal::ValVector< uint32_t > raw_timestamp, uint32_t clock_frequency_hz)
uint64_t tstamp2int(uhal::ValVector< uint32_t > raw_timestamp)
std::string format_reg_value(T reg_value, uint32_t base)