From 51cb8da5837adacbc626ee20aa58264e1b4b7a78 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 24 Jun 2010 20:29:11 -0700 Subject: uhd: reworked time_spec_t to be more flexible: arithmetic, comparison operators... Replaced nsecs with fractional seconds in units of seconds. Replaced nsecs and secs members with public function members. time_spec_t has a more diverse set of constructors and methods. It can handle the cases where frac secs are greater than 1 second. --- host/lib/transport/gen_vrt.py | 10 ++++--- host/lib/types.cpp | 52 ++++++++++++++++++++++++------------- host/lib/usrp/usrp2/mboard_impl.cpp | 8 +++--- 3 files changed, 44 insertions(+), 26 deletions(-) (limited to 'host/lib') diff --git a/host/lib/transport/gen_vrt.py b/host/lib/transport/gen_vrt.py index d1e553c41..8e0fce9ff 100755 --- a/host/lib/transport/gen_vrt.py +++ b/host/lib/transport/gen_vrt.py @@ -97,7 +97,7 @@ void vrt::pack_$(suffix)( #end if ########## Integer Time ########## #if $pred & $tsi_p - header_buff[$num_header_words] = $(XE_MACRO)(metadata.time_spec.secs); + header_buff[$num_header_words] = $(XE_MACRO)(boost::uint32_t(metadata.time_spec.get_full_secs())); #set $num_header_words += 1 #set $flags |= (0x3 << 22); #end if @@ -105,7 +105,7 @@ void vrt::pack_$(suffix)( #if $pred & $tsf_p header_buff[$num_header_words] = 0; #set $num_header_words += 1 - header_buff[$num_header_words] = $(XE_MACRO)(metadata.time_spec.get_ticks(tick_rate)); + header_buff[$num_header_words] = $(XE_MACRO)(boost::uint32_t(metadata.time_spec.get_tick_count(tick_rate))); #set $num_header_words += 1 #set $flags |= (0x1 << 20); #end if @@ -147,6 +147,7 @@ void vrt::unpack_$(suffix)( ){ //clear the metadata metadata = rx_metadata_t(); + boost::uint32_t secs = 0, ticks = 0; //extract vrt header boost::uint32_t vrt_hdr_word = $(XE_MACRO)(header_buff[0]); @@ -185,18 +186,19 @@ void vrt::unpack_$(suffix)( ########## Integer Time ########## #if $pred & $tsi_p #set $has_time_spec = True - metadata.time_spec.secs = $(XE_MACRO)(header_buff[$num_header_words]); + secs = $(XE_MACRO)(header_buff[$num_header_words]); #set $num_header_words += 1 #end if ########## Fractional Time ########## #if $pred & $tsf_p #set $has_time_spec = True #set $num_header_words += 1 - metadata.time_spec.set_ticks($(XE_MACRO)(header_buff[$num_header_words]), tick_rate); + ticks = $(XE_MACRO)(header_buff[$num_header_words]); #set $num_header_words += 1 #end if #if $has_time_spec metadata.has_time_spec = true; + metadata.time_spec = time_spec_t(secs, ticks, tick_rate); #end if ########## Trailer ########## #if $pred & $tlr_p diff --git a/host/lib/types.cpp b/host/lib/types.cpp index 78a3d22ce..6a9fcf5b5 100644 --- a/host/lib/types.cpp +++ b/host/lib/types.cpp @@ -120,47 +120,63 @@ tx_metadata_t::tx_metadata_t(void): /*********************************************************************** * time spec **********************************************************************/ -static inline void time_spec_normalize(time_spec_t &time_spec){ - time_spec.secs += boost::uint32_t(std::ceil(time_spec.nsecs/1e9)); - time_spec.nsecs = std::fmod(time_spec.nsecs, 1e9); +time_spec_t::time_spec_t(double secs): + _full_secs(0), + _frac_secs(secs) +{ + /* NOP */ } -time_spec_t::time_spec_t(boost::uint32_t secs, double nsecs): - secs(secs), - nsecs(nsecs) +time_spec_t::time_spec_t(time_t full_secs, double frac_secs): + _full_secs(full_secs), + _frac_secs(frac_secs) { /* NOP */ } -time_spec_t::time_spec_t(boost::uint32_t secs, boost::uint32_t ticks, double tick_rate): - secs(secs), - nsecs(double(ticks)*1e9/tick_rate) +time_spec_t::time_spec_t(time_t full_secs, size_t tick_count, double tick_rate): + _full_secs(full_secs), + _frac_secs(double(tick_count)/tick_rate) { /* NOP */ } -boost::uint32_t time_spec_t::get_ticks(double tick_rate) const{ - return boost::math::iround(nsecs*tick_rate*1e-9); +size_t time_spec_t::get_tick_count(double tick_rate) const{ + return boost::math::iround(this->get_frac_secs()*tick_rate); +} + +double time_spec_t::get_real_secs(void) const{ + return this->_full_secs + this->_frac_secs; } -void time_spec_t::set_ticks(boost::uint32_t ticks, double tick_rate){ - nsecs = double(ticks)*1e9/tick_rate; +time_t time_spec_t::get_full_secs(void) const{ + return this->_full_secs + time_t(std::floor(this->_frac_secs)); +} + +double time_spec_t::get_frac_secs(void) const{ + return std::fmod(this->_frac_secs, 1.0); } time_spec_t &time_spec_t::operator+=(const time_spec_t &rhs){ - this->secs += rhs.secs; - this->nsecs += rhs.nsecs; + this->_full_secs += rhs.get_full_secs(); + this->_frac_secs += rhs.get_frac_secs(); return *this; } time_spec_t &time_spec_t::operator-=(const time_spec_t &rhs){ - this->secs -= rhs.secs; - this->nsecs -= rhs.nsecs; + this->_full_secs -= rhs.get_full_secs(); + this->_frac_secs -= rhs.get_frac_secs(); return *this; } bool uhd::operator==(const time_spec_t &lhs, const time_spec_t &rhs){ - return lhs.secs == rhs.secs and lhs.nsecs == rhs.nsecs; + return lhs.get_full_secs() == rhs.get_full_secs() and lhs.get_frac_secs() == rhs.get_frac_secs(); +} + +bool uhd::operator<(const time_spec_t &lhs, const time_spec_t &rhs){ + if (lhs.get_full_secs() < rhs.get_full_secs()) return true; + if (lhs.get_full_secs() > rhs.get_full_secs()) return false; + return lhs.get_frac_secs() < rhs.get_frac_secs(); } /*********************************************************************** diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 78fc5dc23..1a0f9916b 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -84,14 +84,14 @@ void usrp2_impl::update_clock_config(void){ void usrp2_impl::set_time_spec(const time_spec_t &time_spec, bool now){ //set the ticks - _iface->poke32(U2_REG_TIME64_TICKS, time_spec.get_ticks(get_master_clock_freq())); + _iface->poke32(U2_REG_TIME64_TICKS, time_spec.get_tick_count(get_master_clock_freq())); //set the flags register boost::uint32_t imm_flags = (now)? U2_FLAG_TIME64_LATCH_NOW : U2_FLAG_TIME64_LATCH_NEXT_PPS; _iface->poke32(U2_REG_TIME64_IMM, imm_flags); //set the seconds (latches in all 3 registers) - _iface->poke32(U2_REG_TIME64_SECS, time_spec.secs); + _iface->poke32(U2_REG_TIME64_SECS, time_spec.get_full_secs()); } void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ @@ -118,8 +118,8 @@ void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ (inst_chain)? 1 : 0, (inst_reload)? 1 : 0 )); - _iface->poke32(U2_REG_RX_CTRL_TIME_SECS, stream_cmd.time_spec.secs); - _iface->poke32(U2_REG_RX_CTRL_TIME_TICKS, stream_cmd.time_spec.get_ticks(get_master_clock_freq())); + _iface->poke32(U2_REG_RX_CTRL_TIME_SECS, stream_cmd.time_spec.get_full_secs()); + _iface->poke32(U2_REG_RX_CTRL_TIME_TICKS, stream_cmd.time_spec.get_tick_count(get_master_clock_freq())); } /*********************************************************************** -- cgit v1.2.3