diff options
| -rw-r--r-- | host/include/uhd/types/time_spec.hpp | 20 | ||||
| -rw-r--r-- | host/lib/transport/super_recv_packet_handler.hpp | 8 | ||||
| -rw-r--r-- | host/lib/transport/super_send_packet_handler.hpp | 12 | ||||
| -rw-r--r-- | host/lib/types/time_spec.cpp | 29 | ||||
| -rw-r--r-- | host/lib/usrp/b100/b100_impl.cpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/b100/b100_regs.hpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/b100/io_impl.cpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/cores/rx_dsp_core_200.cpp | 10 | ||||
| -rw-r--r-- | host/lib/usrp/cores/time64_core_200.cpp | 34 | ||||
| -rw-r--r-- | host/lib/usrp/cores/time64_core_200.hpp | 4 | ||||
| -rw-r--r-- | host/lib/usrp/e100/e100_impl.cpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/e100/e100_regs.hpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/e100/io_impl.cpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/io_impl.cpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_iface.cpp | 4 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_regs.hpp | 8 | ||||
| -rw-r--r-- | host/tests/sph_recv_test.cpp | 24 | ||||
| -rw-r--r-- | host/tests/sph_send_test.cpp | 6 | ||||
| -rw-r--r-- | host/tests/time_spec_test.cpp | 6 | 
20 files changed, 120 insertions, 109 deletions
| diff --git a/host/include/uhd/types/time_spec.hpp b/host/include/uhd/types/time_spec.hpp index 02de20ea1..cf8588c5b 100644 --- a/host/include/uhd/types/time_spec.hpp +++ b/host/include/uhd/types/time_spec.hpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -60,7 +60,7 @@ namespace uhd{          time_spec_t(time_t full_secs, double frac_secs = 0);          /*! -         * Create a time_spec_t from whole and fractional seconds. +         * Create a time_spec_t from whole seconds and fractional ticks.           * Translation from clock-domain specific units.           * \param full_secs the whole/integer seconds count           * \param tick_count the fractional seconds tick count @@ -69,6 +69,14 @@ namespace uhd{          time_spec_t(time_t full_secs, long tick_count, double tick_rate);          /*! +         * Create a time_spec_t from a 64-bit tick count. +         * Translation from clock-domain specific units. +         * \param ticks an integer count of ticks +         * \param tick_rate the number of ticks per second +         */ +        static time_spec_t from_ticks(long long ticks, double tick_rate); + +        /*!           * Convert the fractional seconds to clock ticks.           * Translation into clock-domain specific units.           * \param tick_rate the number of ticks per second @@ -77,6 +85,14 @@ namespace uhd{          long get_tick_count(double tick_rate) const;          /*! +         * Convert the time spec into a 64-bit tick count. +         * Translation into clock-domain specific units. +         * \param tick_rate the number of ticks per second +         * \return an integer number of ticks +         */ +        long long to_ticks(const double tick_rate) const; + +        /*!           * Get the time as a real-valued seconds count.           * Note: If this time_spec_t represents an absolute time,           * the precision of the fractional seconds may be lost. diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp index a5876c8bf..939e7aeb3 100644 --- a/host/lib/transport/super_recv_packet_handler.hpp +++ b/host/lib/transport/super_recv_packet_handler.hpp @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -283,7 +283,7 @@ private:          info.ifpi.num_packet_words32 = num_packet_words32 - _header_offset_words32;          info.vrt_hdr = buff->cast<const boost::uint32_t *>() + _header_offset_words32;          _vrt_unpacker(info.vrt_hdr, info.ifpi); -        info.time = time_spec_t(time_t(info.ifpi.tsi), size_t(info.ifpi.tsf), _tick_rate); //assumes has_tsi and has_tsf are true +        info.time = time_spec_t::from_ticks(info.ifpi.tsf, _tick_rate); //assumes has_tsf is true          info.copy_buff = reinterpret_cast<const char *>(info.vrt_hdr + info.ifpi.num_header_words32);          //-------------------------------------------------------------- @@ -436,7 +436,7 @@ private:                  alignment_check(index, curr_info);                  std::swap(curr_info, next_info); //save progress from curr -> next                  curr_info.metadata.has_time_spec = prev_info.metadata.has_time_spec; -                curr_info.metadata.time_spec = prev_info.metadata.time_spec + time_spec_t(0, +                curr_info.metadata.time_spec = prev_info.metadata.time_spec + time_spec_t::from_ticks(                      prev_info[index].ifpi.num_payload_words32*sizeof(boost::uint32_t)/_bytes_per_otw_item, _samp_rate);                  curr_info.metadata.more_fragments = false;                  curr_info.metadata.fragment_offset = 0; @@ -508,7 +508,7 @@ private:          metadata = info.metadata;          //interpolate the time spec (useful when this is a fragment) -        metadata.time_spec += time_spec_t(0, info.fragment_offset_in_samps, _samp_rate); +        metadata.time_spec += time_spec_t::from_ticks(info.fragment_offset_in_samps, _samp_rate);          //extract the number of samples available to copy          const size_t nsamps_available = info.data_bytes_to_copy/_bytes_per_otw_item; diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp index 57304a7d4..3d68507ed 100644 --- a/host/lib/transport/super_send_packet_handler.hpp +++ b/host/lib/transport/super_send_packet_handler.hpp @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -135,10 +135,9 @@ public:          if_packet_info.has_sid = false;          if_packet_info.has_cid = false;          if_packet_info.has_tlr = true; -        if_packet_info.has_tsi = metadata.has_time_spec; +        if_packet_info.has_tsi = false;          if_packet_info.has_tsf = metadata.has_time_spec; -        if_packet_info.tsi     = boost::uint32_t(metadata.time_spec.get_full_secs()); -        if_packet_info.tsf     = boost::uint64_t(metadata.time_spec.get_tick_count(_tick_rate)); +        if_packet_info.tsf     = metadata.time_spec.to_ticks(_tick_rate);          if_packet_info.sob     = metadata.start_of_burst;          if_packet_info.eob     = metadata.end_of_burst; @@ -174,9 +173,8 @@ public:              if (num_samps_sent == 0) return total_num_samps_sent;              //setup metadata for the next fragment -            const time_spec_t time_spec = metadata.time_spec + time_spec_t(0, total_num_samps_sent, _samp_rate); -            if_packet_info.tsi = boost::uint32_t(time_spec.get_full_secs()); -            if_packet_info.tsf = boost::uint64_t(time_spec.get_tick_count(_tick_rate)); +            const time_spec_t time_spec = metadata.time_spec + time_spec_t::from_ticks(total_num_samps_sent, _samp_rate); +            if_packet_info.tsf = time_spec.to_ticks(_tick_rate);              if_packet_info.sob = false;          } diff --git a/host/lib/types/time_spec.cpp b/host/lib/types/time_spec.cpp index 8e540c14c..176ee8079 100644 --- a/host/lib/types/time_spec.cpp +++ b/host/lib/types/time_spec.cpp @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -16,6 +16,7 @@  //  #include <uhd/types/time_spec.hpp> +#include <inttypes.h> //imaxdiv, intmax_t  using namespace uhd; @@ -23,18 +24,6 @@ using namespace uhd;   * Time spec system time   **********************************************************************/ -/*! - * Creates a time spec from system counts: - * TODO make part of API as a static factory function - * The counts type is 64 bits and will overflow the ticks type of long. - * Therefore, divmod the counts into seconds + sub-second counts first. - */ -#include <inttypes.h> //imaxdiv, intmax_t -static UHD_INLINE time_spec_t time_spec_t_from_counts(intmax_t counts, intmax_t freq){ -    imaxdiv_t divres = imaxdiv(counts, freq); -    return time_spec_t(time_t(divres.quot), double(divres.rem)/freq); -} -  #ifdef HAVE_CLOCK_GETTIME  #include <time.h>  time_spec_t time_spec_t::get_system_time(void){ @@ -49,7 +38,7 @@ time_spec_t time_spec_t::get_system_time(void){  time_spec_t time_spec_t::get_system_time(void){      mach_timebase_info_data_t info; mach_timebase_info(&info);      intmax_t nanosecs = mach_absolute_time()*info.numer/info.denom; -    return time_spec_t_from_counts(nanosecs, intmax_t(1e9)); +    return time_spec_t::from_ticks(nanosecs, intmax_t(1e9));  }  #endif /* HAVE_MACH_ABSOLUTE_TIME */ @@ -60,7 +49,7 @@ time_spec_t time_spec_t::get_system_time(void){      LARGE_INTEGER counts, freq;      QueryPerformanceCounter(&counts);      QueryPerformanceFrequency(&freq); -    return time_spec_t_from_counts(counts.QuadPart, freq.QuadPart); +    return time_spec_t::from_ticks(counts.QuadPart, freq.QuadPart);  }  #endif /* HAVE_QUERY_PERFORMANCE_COUNTER */ @@ -104,6 +93,11 @@ time_spec_t::time_spec_t(time_t full_secs, long tick_count, double tick_rate){      time_spec_init(full_secs, frac_secs);  } +time_spec_t time_spec_t::from_ticks(long long ticks, double tick_rate){ +    const imaxdiv_t divres = imaxdiv(ticks, tick_rate); +    return time_spec_t(time_t(divres.quot), double(divres.rem)/tick_rate); +} +  /***********************************************************************   * Time spec accessors   **********************************************************************/ @@ -111,6 +105,11 @@ long time_spec_t::get_tick_count(double tick_rate) const{      return long(this->get_frac_secs()*tick_rate + 0.5);  } +long long time_spec_t::to_ticks(double tick_rate) const{ +    return (long long)(this->get_frac_secs()*tick_rate + 0.5) + \ +    (long long)((this->get_full_secs()) * (long long)(tick_rate)); +} +  double time_spec_t::get_real_secs(void) const{      return this->_full_secs + this->_frac_secs;  } diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index 08a2cdeec..ce0b9453b 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -364,10 +364,10 @@ b100_impl::b100_impl(const device_addr_t &device_addr){      // create time control objects      ////////////////////////////////////////////////////////////////////      time64_core_200::readback_bases_type time64_rb_bases; -    time64_rb_bases.rb_secs_now = B100_REG_RB_TIME_NOW_SECS; -    time64_rb_bases.rb_ticks_now = B100_REG_RB_TIME_NOW_TICKS; -    time64_rb_bases.rb_secs_pps = B100_REG_RB_TIME_PPS_SECS; -    time64_rb_bases.rb_ticks_pps = B100_REG_RB_TIME_PPS_TICKS; +    time64_rb_bases.rb_hi_now = B100_REG_RB_TIME_NOW_HI; +    time64_rb_bases.rb_lo_now = B100_REG_RB_TIME_NOW_LO; +    time64_rb_bases.rb_hi_pps = B100_REG_RB_TIME_PPS_HI; +    time64_rb_bases.rb_lo_pps = B100_REG_RB_TIME_PPS_LO;      _time64 = time64_core_200::make(          _fpga_ctrl, B100_REG_SR_ADDR(B100_SR_TIME64), time64_rb_bases      ); diff --git a/host/lib/usrp/b100/b100_regs.hpp b/host/lib/usrp/b100/b100_regs.hpp index 77b643372..987a09f03 100644 --- a/host/lib/usrp/b100/b100_regs.hpp +++ b/host/lib/usrp/b100/b100_regs.hpp @@ -76,10 +76,10 @@  #define B100_REG_RB_MUX_32_BASE  B100_REG_SLAVE(7) -#define B100_REG_RB_TIME_NOW_SECS   B100_REG_RB_MUX_32_BASE + 0 -#define B100_REG_RB_TIME_NOW_TICKS  B100_REG_RB_MUX_32_BASE + 4 -#define B100_REG_RB_TIME_PPS_SECS   B100_REG_RB_MUX_32_BASE + 8 -#define B100_REG_RB_TIME_PPS_TICKS  B100_REG_RB_MUX_32_BASE + 12 +#define B100_REG_RB_TIME_NOW_HI     B100_REG_RB_MUX_32_BASE + 0 +#define B100_REG_RB_TIME_NOW_LO     B100_REG_RB_MUX_32_BASE + 4 +#define B100_REG_RB_TIME_PPS_HI     B100_REG_RB_MUX_32_BASE + 8 +#define B100_REG_RB_TIME_PPS_LO     B100_REG_RB_MUX_32_BASE + 12  #define B100_REG_RB_MISC_TEST32     B100_REG_RB_MUX_32_BASE + 16  #define B100_REG_RB_COMPAT          B100_REG_RB_MUX_32_BASE + 24  #define B100_REG_RB_GPIO            B100_REG_RB_MUX_32_BASE + 28 diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index ac7c860d2..bd60e75cf 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -84,10 +84,8 @@ void b100_impl::handle_async_message(managed_recv_buffer::sptr rbuf){          //fill in the async metadata          async_metadata_t metadata;          metadata.channel = 0; -        metadata.has_time_spec = if_packet_info.has_tsi and if_packet_info.has_tsf; -        metadata.time_spec = time_spec_t( -            time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), _clock_ctrl->get_fpga_clock_rate() -        ); +        metadata.has_time_spec = if_packet_info.has_tsf; +        metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, _clock_ctrl->get_fpga_clock_rate());          metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(vrt_hdr, if_packet_info));          _io_impl->async_msg_fifo.push_with_pop_on_full(metadata);          if (metadata.event_code & @@ -206,6 +204,7 @@ rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t &args_){          + vrt::max_if_hdr_words32*sizeof(boost::uint32_t)          + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer          - sizeof(vrt::if_packet_info_t().cid) //no class id ever used +        - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used      ;      const size_t bpp = B100_MAX_PKT_BYTE_LIMIT - hdr_size;      const size_t bpi = convert::get_bytes_per_item(args.otw_format); @@ -262,6 +261,7 @@ tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){          + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer          - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used          - sizeof(vrt::if_packet_info_t().cid) //no class id ever used +        - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used      ;      static const size_t bpp = B100_MAX_PKT_BYTE_LIMIT - hdr_size;      const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp index d9ca84e0f..ea0384dbe 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp @@ -36,8 +36,8 @@  #define FLAG_DSP_RX_MUX_REAL_MODE (1 << 1)  #define REG_RX_CTRL_STREAM_CMD     _ctrl_base + 0 -#define REG_RX_CTRL_TIME_SECS      _ctrl_base + 4 -#define REG_RX_CTRL_TIME_TICKS     _ctrl_base + 8 +#define REG_RX_CTRL_TIME_HI        _ctrl_base + 4 +#define REG_RX_CTRL_TIME_LO        _ctrl_base + 8  #define REG_RX_CTRL_CLEAR          _ctrl_base + 12  #define REG_RX_CTRL_VRT_HDR        _ctrl_base + 16  #define REG_RX_CTRL_VRT_SID        _ctrl_base + 20 @@ -83,7 +83,6 @@ public:          _iface->poke32(REG_RX_CTRL_VRT_HDR, 0              | (0x1 << 28) //if data with stream id              | (0x1 << 26) //has trailer -            | (0x3 << 22) //integer time other              | (0x1 << 20) //fractional time sample count          );          _iface->poke32(REG_RX_CTRL_VRT_SID, _sid); @@ -122,8 +121,9 @@ public:          //issue the stream command          _iface->poke32(REG_RX_CTRL_STREAM_CMD, cmd_word); -        _iface->poke32(REG_RX_CTRL_TIME_SECS, boost::uint32_t(stream_cmd.time_spec.get_full_secs())); -        _iface->poke32(REG_RX_CTRL_TIME_TICKS, stream_cmd.time_spec.get_tick_count(_tick_rate)); //latches the command +        const boost::uint64_t ticks = stream_cmd.time_spec.to_ticks(_tick_rate); +        _iface->poke32(REG_RX_CTRL_TIME_HI, boost::uint32_t(ticks >> 32)); +        _iface->poke32(REG_RX_CTRL_TIME_LO, boost::uint32_t(ticks >> 0)); //latches the command      }      void set_mux(const std::string &mode, const bool fe_swapped){ diff --git a/host/lib/usrp/cores/time64_core_200.cpp b/host/lib/usrp/cores/time64_core_200.cpp index 23d1bdea2..e460d1106 100644 --- a/host/lib/usrp/cores/time64_core_200.cpp +++ b/host/lib/usrp/cores/time64_core_200.cpp @@ -20,11 +20,10 @@  #include <uhd/utils/assert_has.hpp>  #include <boost/math/special_functions/round.hpp> -#define REG_TIME64_SECS        _base + 0 -#define REG_TIME64_TICKS       _base + 4 +#define REG_TIME64_TICKS_HI    _base + 0 +#define REG_TIME64_TICKS_LO    _base + 4  #define REG_TIME64_FLAGS       _base + 8  #define REG_TIME64_IMM         _base + 12 -#define REG_TIME64_TPS         _base + 16  #define REG_TIME64_MIMO_SYNC   _base + 20 //lower byte is delay cycles  //pps flags (see above) @@ -59,39 +58,42 @@ public:      void set_tick_rate(const double rate){          _tick_rate = rate; -        _iface->poke32(REG_TIME64_TPS, boost::math::iround(rate));      }      uhd::time_spec_t get_time_now(void){          for (size_t i = 0; i < 3; i++){ //special algorithm because we cant read 64 bits synchronously -            const boost::uint32_t secs = _iface->peek32(_readback_bases.rb_secs_now); -            const boost::uint32_t ticks = _iface->peek32(_readback_bases.rb_ticks_now); -            if (secs != _iface->peek32(_readback_bases.rb_secs_now)) continue; -            return time_spec_t(secs, ticks, _tick_rate); +            const boost::uint32_t ticks_hi = _iface->peek32(_readback_bases.rb_hi_now); +            const boost::uint32_t ticks_lo = _iface->peek32(_readback_bases.rb_lo_now); +            if (ticks_hi != _iface->peek32(_readback_bases.rb_hi_now)) continue; +            const boost::uint64_t ticks = (boost::uint64_t(ticks_hi) << 32) | ticks_lo; +            return time_spec_t::from_ticks(ticks, _tick_rate);          }          throw uhd::runtime_error("time64_core_200: get time now timeout");      }      uhd::time_spec_t get_time_last_pps(void){          for (size_t i = 0; i < 3; i++){ //special algorithm because we cant read 64 bits synchronously -            const boost::uint32_t secs = _iface->peek32(_readback_bases.rb_secs_pps); -            const boost::uint32_t ticks = _iface->peek32(_readback_bases.rb_ticks_pps); -            if (secs != _iface->peek32(_readback_bases.rb_secs_pps)) continue; -            return time_spec_t(secs, ticks, _tick_rate); +            const boost::uint32_t ticks_hi = _iface->peek32(_readback_bases.rb_hi_pps); +            const boost::uint32_t ticks_lo = _iface->peek32(_readback_bases.rb_lo_pps); +            if (ticks_hi != _iface->peek32(_readback_bases.rb_hi_pps)) continue; +            const boost::uint64_t ticks = (boost::uint64_t(ticks_hi) << 32) | ticks_lo; +            return time_spec_t::from_ticks(ticks, _tick_rate);          }          throw uhd::runtime_error("time64_core_200: get time last pps timeout");      }      void set_time_now(const uhd::time_spec_t &time){ -        _iface->poke32(REG_TIME64_TICKS, time.get_tick_count(_tick_rate)); +        const boost::uint64_t ticks = time.to_ticks(_tick_rate); +        _iface->poke32(REG_TIME64_TICKS_LO, boost::uint32_t(ticks >> 0));          _iface->poke32(REG_TIME64_IMM, FLAG_TIME64_LATCH_NOW); -        _iface->poke32(REG_TIME64_SECS, boost::uint32_t(time.get_full_secs())); //latches all 3 +        _iface->poke32(REG_TIME64_TICKS_HI, boost::uint32_t(ticks >> 32)); //latches all 3      }      void set_time_next_pps(const uhd::time_spec_t &time){ -        _iface->poke32(REG_TIME64_TICKS, time.get_tick_count(_tick_rate)); +        const boost::uint64_t ticks = time.to_ticks(_tick_rate); +        _iface->poke32(REG_TIME64_TICKS_LO, boost::uint32_t(ticks >> 0));          _iface->poke32(REG_TIME64_IMM, FLAG_TIME64_LATCH_NEXT_PPS); -        _iface->poke32(REG_TIME64_SECS, boost::uint32_t(time.get_full_secs())); //latches all 3 +        _iface->poke32(REG_TIME64_TICKS_HI, boost::uint32_t(ticks >> 32)); //latches all 3      }      void set_time_source(const std::string &source){ diff --git a/host/lib/usrp/cores/time64_core_200.hpp b/host/lib/usrp/cores/time64_core_200.hpp index ebd51a02f..7571573a5 100644 --- a/host/lib/usrp/cores/time64_core_200.hpp +++ b/host/lib/usrp/cores/time64_core_200.hpp @@ -31,8 +31,8 @@ public:      typedef boost::shared_ptr<time64_core_200> sptr;      struct readback_bases_type{ -        size_t rb_secs_now, rb_ticks_now; -        size_t rb_secs_pps, rb_ticks_pps; +        size_t rb_hi_now, rb_lo_now; +        size_t rb_hi_pps, rb_lo_pps;      };      //! makes a new time64 core from iface and slave base diff --git a/host/lib/usrp/e100/e100_impl.cpp b/host/lib/usrp/e100/e100_impl.cpp index 8ab6ab533..a01ce4a7b 100644 --- a/host/lib/usrp/e100/e100_impl.cpp +++ b/host/lib/usrp/e100/e100_impl.cpp @@ -326,10 +326,10 @@ e100_impl::e100_impl(const uhd::device_addr_t &device_addr){      // create time control objects      ////////////////////////////////////////////////////////////////////      time64_core_200::readback_bases_type time64_rb_bases; -    time64_rb_bases.rb_secs_now = E100_REG_RB_TIME_NOW_SECS; -    time64_rb_bases.rb_ticks_now = E100_REG_RB_TIME_NOW_TICKS; -    time64_rb_bases.rb_secs_pps = E100_REG_RB_TIME_PPS_SECS; -    time64_rb_bases.rb_ticks_pps = E100_REG_RB_TIME_PPS_TICKS; +    time64_rb_bases.rb_hi_now = E100_REG_RB_TIME_NOW_HI; +    time64_rb_bases.rb_lo_now = E100_REG_RB_TIME_NOW_LO; +    time64_rb_bases.rb_hi_pps = E100_REG_RB_TIME_PPS_HI; +    time64_rb_bases.rb_lo_pps = E100_REG_RB_TIME_PPS_LO;      _time64 = time64_core_200::make(          _fpga_ctrl, E100_REG_SR_ADDR(UE_SR_TIME64), time64_rb_bases      ); diff --git a/host/lib/usrp/e100/e100_regs.hpp b/host/lib/usrp/e100/e100_regs.hpp index 0ec5f4de3..75be2cfbe 100644 --- a/host/lib/usrp/e100/e100_regs.hpp +++ b/host/lib/usrp/e100/e100_regs.hpp @@ -86,10 +86,10 @@  #define E100_REG_RB_MUX_32_BASE  E100_REG_SLAVE(7) -#define E100_REG_RB_TIME_NOW_SECS   E100_REG_RB_MUX_32_BASE + 0 -#define E100_REG_RB_TIME_NOW_TICKS  E100_REG_RB_MUX_32_BASE + 4 -#define E100_REG_RB_TIME_PPS_SECS   E100_REG_RB_MUX_32_BASE + 8 -#define E100_REG_RB_TIME_PPS_TICKS  E100_REG_RB_MUX_32_BASE + 12 +#define E100_REG_RB_TIME_NOW_HI     E100_REG_RB_MUX_32_BASE + 0 +#define E100_REG_RB_TIME_NOW_LO     E100_REG_RB_MUX_32_BASE + 4 +#define E100_REG_RB_TIME_PPS_HI     E100_REG_RB_MUX_32_BASE + 8 +#define E100_REG_RB_TIME_PPS_LO     E100_REG_RB_MUX_32_BASE + 12  #define E100_REG_RB_MISC_TEST32     E100_REG_RB_MUX_32_BASE + 16  #define E100_REG_RB_ERR_STATUS      E100_REG_RB_MUX_32_BASE + 20  #define E100_REG_RB_COMPAT          E100_REG_RB_MUX_32_BASE + 24 diff --git a/host/lib/usrp/e100/io_impl.cpp b/host/lib/usrp/e100/io_impl.cpp index 8c7f5e742..f8e15f3fd 100644 --- a/host/lib/usrp/e100/io_impl.cpp +++ b/host/lib/usrp/e100/io_impl.cpp @@ -124,10 +124,8 @@ void e100_impl::io_impl::handle_irq(void){          //fill in the async metadata          async_metadata_t metadata;          metadata.channel = 0; -        metadata.has_time_spec = if_packet_info.has_tsi and if_packet_info.has_tsf; -        metadata.time_spec = time_spec_t( -            time_t(if_packet_info.tsi), long(if_packet_info.tsf), tick_rate -        ); +        metadata.has_time_spec = if_packet_info.has_tsf; +        metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, tick_rate);          metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(data.buf, if_packet_info));          //push the message onto the queue @@ -285,6 +283,7 @@ rx_streamer::sptr e100_impl::get_rx_stream(const uhd::stream_args_t &args_){          + vrt::max_if_hdr_words32*sizeof(boost::uint32_t)          + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer          - sizeof(vrt::if_packet_info_t().cid) //no class id ever used +        - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used      ;      const size_t bpp = _data_transport->get_recv_frame_size() - hdr_size;      const size_t bpi = convert::get_bytes_per_item(args.otw_format); @@ -341,6 +340,7 @@ tx_streamer::sptr e100_impl::get_tx_stream(const uhd::stream_args_t &args_){          + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer          - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used          - sizeof(vrt::if_packet_info_t().cid) //no class id ever used +        - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used      ;      static const size_t bpp = _data_transport->get_send_frame_size() - hdr_size;      const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index f19f49e28..f0c159f16 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -202,10 +202,8 @@ void usrp2_impl::io_impl::recv_pirate_loop(                  //fill in the async metadata                  async_metadata_t metadata;                  metadata.channel = index; -                metadata.has_time_spec = if_packet_info.has_tsi and if_packet_info.has_tsf; -                metadata.time_spec = time_spec_t( -                    time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), tick_rate -                ); +                metadata.has_time_spec = if_packet_info.has_tsf; +                metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, tick_rate);                  metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(vrt_hdr, if_packet_info));                  //catch the flow control packets and react @@ -388,6 +386,7 @@ rx_streamer::sptr usrp2_impl::get_rx_stream(const uhd::stream_args_t &args_){          + vrt::max_if_hdr_words32*sizeof(boost::uint32_t)          + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer          - sizeof(vrt::if_packet_info_t().cid) //no class id ever used +        - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used      ;      const size_t bpp = _mbc[_mbc.keys().front()].rx_dsp_xports[0]->get_recv_frame_size() - hdr_size;      const size_t bpi = convert::get_bytes_per_item(args.otw_format); @@ -454,6 +453,7 @@ tx_streamer::sptr usrp2_impl::get_tx_stream(const uhd::stream_args_t &args_){          + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer          - sizeof(vrt::if_packet_info_t().cid) //no class id ever used          - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used +        - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used      ;      const size_t bpp = _mbc[_mbc.keys().front()].tx_dsp_xport->get_send_frame_size() - hdr_size;      const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index 4830c10d9..f3d474a2d 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -126,7 +126,7 @@ public:      bool is_device_locked(void){          boost::uint32_t lock_secs = this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FW_PEEK32>(U2_FW_REG_LOCK_TIME);          boost::uint32_t lock_gpid = this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FW_PEEK32>(U2_FW_REG_LOCK_GPID); -        boost::uint32_t curr_secs = this->peek32(U2_REG_TIME64_SECS_RB_IMM); +        boost::uint32_t curr_secs = this->peek32(U2_REG_TIME64_LO_RB_IMM)/100e6;          //if the difference is larger, assume not locked anymore          if (curr_secs - lock_secs >= 3) return false; @@ -137,7 +137,7 @@ public:      void lock_task(void){          //re-lock in task -        boost::uint32_t curr_secs = this->peek32(U2_REG_TIME64_SECS_RB_IMM); +        boost::uint32_t curr_secs = this->peek32(U2_REG_TIME64_LO_RB_IMM)/100e6;          this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FW_POKE32>(U2_FW_REG_LOCK_TIME, curr_secs);          //sleep for a bit          boost::this_thread::sleep(boost::posix_time::milliseconds(1500)); diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 7101e040a..2077ab009 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -546,10 +546,10 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){          // create time control objects          ////////////////////////////////////////////////////////////////          time64_core_200::readback_bases_type time64_rb_bases; -        time64_rb_bases.rb_secs_now = U2_REG_TIME64_SECS_RB_IMM; -        time64_rb_bases.rb_ticks_now = U2_REG_TIME64_TICKS_RB_IMM; -        time64_rb_bases.rb_secs_pps = U2_REG_TIME64_SECS_RB_PPS; -        time64_rb_bases.rb_ticks_pps = U2_REG_TIME64_TICKS_RB_PPS; +        time64_rb_bases.rb_hi_now = U2_REG_TIME64_HI_RB_IMM; +        time64_rb_bases.rb_lo_now = U2_REG_TIME64_LO_RB_IMM; +        time64_rb_bases.rb_hi_pps = U2_REG_TIME64_HI_RB_PPS; +        time64_rb_bases.rb_lo_pps = U2_REG_TIME64_LO_RB_PPS;          _mbc[mb].time64 = time64_core_200::make(              _mbc[mb].iface, U2_REG_SR_ADDR(SR_TIME64), time64_rb_bases, mimo_clock_sync_delay_cycles          ); diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index 5d39e527d..e14798ecb 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.hpp @@ -97,11 +97,11 @@  ////////////////////////////////////////////////  #define U2_REG_STATUS READBACK_BASE + 4*8  #define U2_REG_GPIO_RB READBACK_BASE + 4*9 -#define U2_REG_TIME64_SECS_RB_IMM READBACK_BASE + 4*10 -#define U2_REG_TIME64_TICKS_RB_IMM READBACK_BASE + 4*11 +#define U2_REG_TIME64_HI_RB_IMM READBACK_BASE + 4*10 +#define U2_REG_TIME64_LO_RB_IMM READBACK_BASE + 4*11  #define U2_REG_COMPAT_NUM_RB READBACK_BASE + 4*12  #define U2_REG_IRQ_RB READBACK_BASE + 4*13 -#define U2_REG_TIME64_SECS_RB_PPS READBACK_BASE + 4*14 -#define U2_REG_TIME64_TICKS_RB_PPS READBACK_BASE + 4*15 +#define U2_REG_TIME64_HI_RB_PPS READBACK_BASE + 4*14 +#define U2_REG_TIME64_LO_RB_PPS READBACK_BASE + 4*15  #endif /* INCLUDED_USRP2_REGS_HPP */ diff --git a/host/tests/sph_recv_test.cpp b/host/tests/sph_recv_test.cpp index 85d06aa0d..9b45d7016 100644 --- a/host/tests/sph_recv_test.cpp +++ b/host/tests/sph_recv_test.cpp @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -159,7 +159,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_normal){          BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE);          BOOST_CHECK(not metadata.more_fragments);          BOOST_CHECK(metadata.has_time_spec); -        BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); +        BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE));          BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10);          num_accum_samps += num_samps_ret;      } @@ -232,14 +232,14 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_sequence_error){          if (i == NUM_PKTS_TO_TEST/2){              //must get the soft overflow here              BOOST_REQUIRE(metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW); -            BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); +            BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE));              num_accum_samps += 10 + i%10;          }          else{              BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE);              BOOST_CHECK(not metadata.more_fragments);              BOOST_CHECK(metadata.has_time_spec); -            BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); +            BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE));              BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10);              num_accum_samps += num_samps_ret;          } @@ -323,7 +323,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_inline_message){          BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE);          BOOST_CHECK(not metadata.more_fragments);          BOOST_CHECK(metadata.has_time_spec); -        BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); +        BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE));          BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10);          num_accum_samps += num_samps_ret;          if (i == NUM_PKTS_TO_TEST/2){ @@ -332,7 +332,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_inline_message){              );              std::cout << "metadata.error_code " << metadata.error_code << std::endl;              BOOST_REQUIRE(metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW); -            BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); +            BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE));              BOOST_CHECK_EQUAL(overflow_handler.num_overflow, size_t(1));          }      } @@ -414,7 +414,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_normal){          BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE);          BOOST_CHECK(not metadata.more_fragments);          BOOST_CHECK(metadata.has_time_spec); -        BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); +        BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE));          BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10);          num_accum_samps += num_samps_ret;      } @@ -500,14 +500,14 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_sequence_error){          if (i == NUM_PKTS_TO_TEST/2){              //must get the soft overflow here              BOOST_REQUIRE(metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW); -            BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); +            BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE));              num_accum_samps += 10 + i%10;          }          else{              BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE);              BOOST_CHECK(not metadata.more_fragments);              BOOST_CHECK(metadata.has_time_spec); -            BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); +            BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE));              BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10);              num_accum_samps += num_samps_ret;          } @@ -593,7 +593,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_time_error){          BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE);          BOOST_CHECK(not metadata.more_fragments);          BOOST_CHECK(metadata.has_time_spec); -        BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); +        BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE));          BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10);          num_accum_samps += num_samps_ret;          if (i == NUM_PKTS_TO_TEST/2){ @@ -677,7 +677,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_fragment){          );          BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE);          BOOST_CHECK(metadata.has_time_spec); -        BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); +        BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE));          BOOST_CHECK_EQUAL(num_samps_ret, 10);          num_accum_samps += num_samps_ret; @@ -690,7 +690,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_fragment){          BOOST_CHECK(not metadata.more_fragments);          BOOST_CHECK_EQUAL(metadata.fragment_offset, 10);          BOOST_CHECK(metadata.has_time_spec); -        BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); +        BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE));          BOOST_CHECK_EQUAL(num_samps_ret, i%10);          num_accum_samps += num_samps_ret;      } diff --git a/host/tests/sph_send_test.cpp b/host/tests/sph_send_test.cpp index 25a3f97ee..c31399d12 100644 --- a/host/tests/sph_send_test.cpp +++ b/host/tests/sph_send_test.cpp @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -136,9 +136,7 @@ BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_one_packet_mode){          std::cout << "data check " << i << std::endl;          dummy_send_xport.pop_front_packet(ifpi);          BOOST_CHECK_EQUAL(ifpi.num_payload_words32, 10+i%10); -        BOOST_CHECK(ifpi.has_tsi);          BOOST_CHECK(ifpi.has_tsf); -        BOOST_CHECK_EQUAL(ifpi.tsi, 0);          BOOST_CHECK_EQUAL(ifpi.tsf, num_accum_samps*TICK_RATE/SAMP_RATE);          BOOST_CHECK_EQUAL(ifpi.sob, i == 0);          BOOST_CHECK_EQUAL(ifpi.eob, i == NUM_PKTS_TO_TEST-1); @@ -191,9 +189,7 @@ BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_full_buffer_mode){          std::cout << "data check " << i << std::endl;          dummy_send_xport.pop_front_packet(ifpi);          BOOST_CHECK_EQUAL(ifpi.num_payload_words32, 20); -        BOOST_CHECK(ifpi.has_tsi);          BOOST_CHECK(ifpi.has_tsf); -        BOOST_CHECK_EQUAL(ifpi.tsi, 0);          BOOST_CHECK_EQUAL(ifpi.tsf, num_accum_samps*TICK_RATE/SAMP_RATE);          BOOST_CHECK_EQUAL(ifpi.sob, i == 0);          BOOST_CHECK_EQUAL(ifpi.eob, i == NUM_PKTS_TO_TEST-1); diff --git a/host/tests/time_spec_test.cpp b/host/tests/time_spec_test.cpp index 467da5c18..102b7cda3 100644 --- a/host/tests/time_spec_test.cpp +++ b/host/tests/time_spec_test.cpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -54,11 +54,11 @@ BOOST_AUTO_TEST_CASE(test_time_spec_parts){      BOOST_CHECK_EQUAL(uhd::time_spec_t(1.1).get_full_secs(), 1);      BOOST_CHECK_CLOSE(uhd::time_spec_t(1.1).get_frac_secs(), 0.1, 0.001); -    BOOST_CHECK_EQUAL(uhd::time_spec_t(1.1).get_tick_count(100), 10); +    BOOST_CHECK_EQUAL(uhd::time_spec_t(1.1).to_ticks(100), 110);      BOOST_CHECK_EQUAL(uhd::time_spec_t(-1.1).get_full_secs(), -2);      BOOST_CHECK_CLOSE(uhd::time_spec_t(-1.1).get_frac_secs(), 0.9, 0.001); -    BOOST_CHECK_EQUAL(uhd::time_spec_t(-1.1).get_tick_count(100), 90); +    BOOST_CHECK_EQUAL(uhd::time_spec_t(-1.1).to_ticks(100), -110);  }  BOOST_AUTO_TEST_CASE(test_time_spec_get_system_time){ | 
