#include <uhd/rfnoc/mb_controller.hpp>
Public Types | |
using | sptr = std::shared_ptr< timekeeper > |
using | write_period_fn_t = std::function< void(uint64_t)> |
Public Member Functions | |
timekeeper () | |
virtual | ~timekeeper () |
uhd::time_spec_t | get_time_now (void) |
virtual uint64_t | get_ticks_now ()=0 |
uhd::time_spec_t | get_time_last_pps (void) |
virtual uint64_t | get_ticks_last_pps ()=0 |
void | set_time_now (const uhd::time_spec_t &time) |
virtual void | set_ticks_now (const uint64_t ticks)=0 |
void | set_time_next_pps (const uhd::time_spec_t &time) |
virtual void | set_ticks_next_pps (const uint64_t ticks)=0 |
double | get_tick_rate () |
Protected Member Functions | |
void | set_tick_rate (const double rate) |
virtual void | set_period (const uint64_t period_ns)=0 |
Interface to interact with timekeepers
A timekeeper is an entity within a USRPs FPGA to track the time. For example, the execution of timed commands requires the existence of a timekeeper.
Timekeepers are objects separate from RFNoC blocks, but RFNoC blocks can have access to the time provided by timekeepers in order to execute commands at a certain time (e.g., the radio blocks use this to be able to assign a timestamp to samples). Note that most other RFNoC blocks do not require access to a timekeeper to execute timed commands, as they will execute commands relative to the incoming data.
using uhd::rfnoc::mb_controller::timekeeper::sptr = std::shared_ptr<timekeeper> |
using uhd::rfnoc::mb_controller::timekeeper::write_period_fn_t = std::function<void(uint64_t)> |
uhd::rfnoc::mb_controller::timekeeper::timekeeper | ( | ) |
|
inlinevirtual |
|
inline |
Return the current tick rate
|
pure virtual |
Return the time from the last PPS as a tick count
See also get_time_last_pps()
|
pure virtual |
Return the current time as a tick count
When using the RFNoC API, radio blocks also provide API calls (uhd::rfnoc::radio_control::get_time_now() and uhd::rfnoc::radio_control::get_ticks_now()) which directly returns the current time from the radio block itself. This has the advantage that it is not necessary to know which timekeeper is providing the time to which radio block when reading the current time, and generally has a lower latency than executing this call.
See also get_time_now().
uhd::time_spec_t uhd::rfnoc::mb_controller::timekeeper::get_time_last_pps | ( | void | ) |
Return the time from the last PPS as a time spec
Note that there is no control over when this command gets executed, it will read the time "as soon as possible", and then return that value. Calling this on two synchronized clocks sequentially will definitely return two different values.
uhd::time_spec_t uhd::rfnoc::mb_controller::timekeeper::get_time_now | ( | void | ) |
Return the current time as a time spec
Note that there is no control over when this command gets executed, it will read the time "as soon as possible", and then return that value. Calling this on two synchronized clocks sequentially will definitely return two different values.
When using the RFNoC API, radio blocks also provide API calls (uhd::rfnoc::radio_control::get_time_now() and uhd::rfnoc::radio_control::get_ticks_now()) which directly returns the current time from the radio block itself. This has the advantage that it is not necessary to know which timekeeper is providing the time to which radio block when reading the current time, and generally has a lower latency than executing this call.
|
protectedpure virtual |
Set the time period as a 64-bit Q32 value
period_ns | The period as nanoseconds per tick, in Q32 format |
|
protected |
Set the tick rate
This doesn't change the input clock to the timekeeper, but does two things:
|
pure virtual |
Set the ticks at next PPS
This will instruct the remote device to set its tick count when the next PPS edge is detected. Use this to set multiple devices to the same time (assuming they are synchronized in time and frequency).
To guarantee that devices are synchronized in time it is recommended to wait for a PPS edge before calling this command. Otherwise, it could happen that due to network latency or other reasons, this command reaches different devices on different sides of the same PPS edge, causing devices to be unsynchronized in time by exactly one second.
|
pure virtual |
Set the ticks "now"
This will set the tick count on the remote device's timekeeper as soon as possible. Note that there is some amount of lag between executing this call and when the device's time will be updated, e.g., due to network latency.
void uhd::rfnoc::mb_controller::timekeeper::set_time_next_pps | ( | const uhd::time_spec_t & | time | ) |
Set the time at next PPS from a time spec
Note: When changing clock sources, a previously set time will most likely be lost. It is recommended to set the time after changing the clock source. Otherwise, an unexpected time may line up with future PPS edges.
This will convert time
into a tick count value and use that to call set_ticks_next_pps().
void uhd::rfnoc::mb_controller::timekeeper::set_time_now | ( | const uhd::time_spec_t & | time | ) |
Set the time "now" from a time spec
This will convert time
into a tick count value and call set_ticks_now().