From 781cafa8717f00b883a4543b4a9150060691eee3 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 28 Jan 2012 17:21:40 -0800 Subject: gen2: added user setting regs api and user core --- host/lib/usrp/e100/e100_impl.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'host/lib/usrp/e100/e100_impl.cpp') diff --git a/host/lib/usrp/e100/e100_impl.cpp b/host/lib/usrp/e100/e100_impl.cpp index f58138ae6..cd6143a16 100644 --- a/host/lib/usrp/e100/e100_impl.cpp +++ b/host/lib/usrp/e100/e100_impl.cpp @@ -352,6 +352,13 @@ e100_impl::e100_impl(const uhd::device_addr_t &device_addr){ static const std::vector clock_sources = boost::assign::list_of("internal")("external")("auto"); _tree->create >(mb_path / "clock_source/options").set(clock_sources); + //////////////////////////////////////////////////////////////////// + // create user-defined control objects + //////////////////////////////////////////////////////////////////// + _user = user_settings_core_200::make(_fpga_ctrl, E100_REG_SR_ADDR(UE_SR_USER_REGS)); + _tree->create(mb_path / "user/regs") + .subscribe(boost::bind(&user_settings_core_200::set_reg, _user, _1)); + //////////////////////////////////////////////////////////////////// // create dboard control objects //////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From b7ff81c9a8316bb0310d9291afe722c48b441f29 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 2 Feb 2012 15:15:54 -0800 Subject: dsp rework: work on usb wrapper for smaller packets, large luts --- host/lib/transport/libusb1_zero_copy.cpp | 17 +++-- host/lib/transport/usb_zero_copy_wrapper.cpp | 100 +++++++++++++-------------- host/lib/usrp/b100/b100_impl.cpp | 5 +- host/lib/usrp/b100/b100_impl.hpp | 3 +- host/lib/usrp/b100/b100_regs.hpp | 17 ++++- host/lib/usrp/b100/io_impl.cpp | 10 +-- host/lib/usrp/e100/e100_impl.cpp | 2 +- host/lib/usrp/e100/e100_impl.hpp | 2 +- host/lib/usrp/e100/e100_regs.hpp | 17 ++++- host/lib/usrp/e100/io_impl.cpp | 2 +- host/lib/usrp/usrp1/io_impl.cpp | 2 +- host/lib/usrp/usrp2/io_impl.cpp | 2 +- host/lib/usrp/usrp2/usrp2_impl.cpp | 2 +- host/lib/usrp/usrp2/usrp2_impl.hpp | 2 +- host/lib/usrp/usrp2/usrp2_regs.hpp | 2 +- 15 files changed, 105 insertions(+), 80 deletions(-) (limited to 'host/lib/usrp/e100/e100_impl.cpp') diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp index 28d6cdd5b..3e67264cd 100644 --- a/host/lib/transport/libusb1_zero_copy.cpp +++ b/host/lib/transport/libusb1_zero_copy.cpp @@ -80,13 +80,14 @@ UHD_INLINE bool wait_for_completion(libusb_context *ctx, const double timeout, b **********************************************************************/ class libusb_zero_copy_mrb : public managed_recv_buffer{ public: - libusb_zero_copy_mrb(libusb_transfer *lut): + libusb_zero_copy_mrb(libusb_transfer *lut, const size_t frame_size): _ctx(libusb::session::get_global_session()->get_context()), - _lut(lut), _expired(false) { /* NOP */ } + _lut(lut), _expired(false), _frame_size(frame_size) { /* NOP */ } void release(void){ if (_expired) return; completed = false; + _lut->length = _frame_size; //always reset length UHD_ASSERT_THROW(libusb_submit_transfer(_lut) == 0); _expired = true; } @@ -109,6 +110,7 @@ private: libusb_context *_ctx; libusb_transfer *_lut; bool _expired; + const size_t _frame_size; }; /*********************************************************************** @@ -118,9 +120,9 @@ private: **********************************************************************/ class libusb_zero_copy_msb : public managed_send_buffer{ public: - libusb_zero_copy_msb(libusb_transfer *lut): + libusb_zero_copy_msb(libusb_transfer *lut, const size_t frame_size): _ctx(libusb::session::get_global_session()->get_context()), - _lut(lut), _expired(false) { /* NOP */ } + _lut(lut), _expired(false), _frame_size(frame_size) { /* NOP */ } void commit(size_t len){ if (_expired) return; @@ -144,11 +146,12 @@ public: private: void *get_buff(void) const{return _lut->buffer;} - size_t get_size(void) const{return _lut->length;} + size_t get_size(void) const{return _frame_size;} libusb_context *_ctx; libusb_transfer *_lut; bool _expired; + const size_t _frame_size; }; /*********************************************************************** @@ -184,7 +187,7 @@ public: libusb_transfer *lut = libusb_alloc_transfer(0); UHD_ASSERT_THROW(lut != NULL); - _mrb_pool.push_back(boost::shared_ptr(new libusb_zero_copy_mrb(lut))); + _mrb_pool.push_back(boost::shared_ptr(new libusb_zero_copy_mrb(lut, this->get_recv_frame_size()))); libusb_fill_bulk_transfer( lut, // transfer @@ -207,7 +210,7 @@ public: libusb_transfer *lut = libusb_alloc_transfer(0); UHD_ASSERT_THROW(lut != NULL); - _msb_pool.push_back(boost::shared_ptr(new libusb_zero_copy_msb(lut))); + _msb_pool.push_back(boost::shared_ptr(new libusb_zero_copy_msb(lut, this->get_send_frame_size()))); libusb_fill_bulk_transfer( lut, // transfer diff --git a/host/lib/transport/usb_zero_copy_wrapper.cpp b/host/lib/transport/usb_zero_copy_wrapper.cpp index 74f07f956..07105cad3 100644 --- a/host/lib/transport/usb_zero_copy_wrapper.cpp +++ b/host/lib/transport/usb_zero_copy_wrapper.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 @@ -18,17 +18,13 @@ #include #include #include +#include +#include #include #include #include using namespace uhd::transport; -bool debug = true; - -static inline size_t next_boundary(size_t length, size_t boundary){ - //pad to the boundary, assumes boundary is a power of 2 - return (length + (boundary-1)) & ~(boundary-1); -} /*********************************************************************** * USB zero copy wrapper - managed receive buffer @@ -45,7 +41,7 @@ public: _mrb.reset(); } - sptr get_new(managed_recv_buffer::sptr mrb, const void *mem, size_t len){ + UHD_INLINE sptr get_new(managed_recv_buffer::sptr mrb, const void *mem, size_t len){ _mrb = mrb; _mem = mem; _len = len; @@ -67,28 +63,46 @@ private: **********************************************************************/ class usb_zero_copy_wrapper_msb : public managed_send_buffer{ public: - usb_zero_copy_wrapper_msb(bounded_buffer &queue, size_t boundary): - _queue(queue), _boundary(boundary){/*NOP*/} + usb_zero_copy_wrapper_msb(const usb_zero_copy::sptr internal, const size_t fragmentation_size): + _internal(internal), _fragmentation_size(fragmentation_size){/*NOP*/} void commit(size_t len){ - if (_msb.get() == NULL) return; - _msb->commit(len); - _queue.push_with_haste(this); - _msb.reset(); + if (len == 0) return; + + //get a reference to the VITA header before incrementing + const boost::uint32_t vita_header = reinterpret_cast(_mem_buffer_tip)[0]; + + _bytes_in_buffer += len; + _mem_buffer_tip += len; + + //extract VITA end of packet flag, we must force flush under eof conditions + const bool eop = (uhd::wtohx(vita_header) & (0x1 << 24)) != 0; + const bool full = _bytes_in_buffer >= (_last_send_buff->size() - _fragmentation_size); + if (eop or full){ + _last_send_buff->commit(_bytes_in_buffer); + _last_send_buff.reset(); + } } - sptr get_new(managed_send_buffer::sptr msb){ - _msb = msb; + UHD_INLINE sptr get_new(const double timeout){ + if (not _last_send_buff){ + _last_send_buff = _internal->get_send_buff(timeout); + if (not _last_send_buff) return sptr(); + _mem_buffer_tip = _last_send_buff->cast(); + _bytes_in_buffer = 0; + } return make_managed_buffer(this); } private: - void *get_buff(void) const{return _msb->cast();} - size_t get_size(void) const{return _msb->size();} - - bounded_buffer &_queue; - size_t _boundary; - managed_send_buffer::sptr _msb; + void *get_buff(void) const{return reinterpret_cast(_mem_buffer_tip);} + size_t get_size(void) const{return _fragmentation_size;} + + usb_zero_copy::sptr _internal; + const size_t _fragmentation_size; + managed_send_buffer::sptr _last_send_buff; + size_t _bytes_in_buffer; + char *_mem_buffer_tip; }; /*********************************************************************** @@ -96,23 +110,15 @@ private: **********************************************************************/ class usb_zero_copy_wrapper : public usb_zero_copy{ public: - usb_zero_copy_wrapper( - sptr usb_zc, size_t usb_frame_boundary - ): + usb_zero_copy_wrapper(sptr usb_zc, const size_t frame_boundary): _internal_zc(usb_zc), - _usb_frame_boundary(usb_frame_boundary), _available_recv_buffs(this->get_num_recv_frames()), - _available_send_buffs(this->get_num_send_frames()), _mrb_pool(this->get_num_recv_frames(), usb_zero_copy_wrapper_mrb(_available_recv_buffs)), - _msb_pool(this->get_num_send_frames(), usb_zero_copy_wrapper_msb(_available_send_buffs, usb_frame_boundary)) + _the_only_msb(usb_zero_copy_wrapper_msb(usb_zc, frame_boundary)) { BOOST_FOREACH(usb_zero_copy_wrapper_mrb &mrb, _mrb_pool){ _available_recv_buffs.push_with_haste(&mrb); } - - BOOST_FOREACH(usb_zero_copy_wrapper_msb &msb, _msb_pool){ - _available_send_buffs.push_with_haste(&msb); - } } managed_recv_buffer::sptr get_recv_buff(double timeout){ @@ -128,18 +134,17 @@ public: //extract this packet's memory address and length in bytes const char *mem = _last_recv_buff->cast() + _last_recv_offset; const boost::uint32_t *mem32 = reinterpret_cast(mem); - size_t len = (mem32[0] & 0xffff)*sizeof(boost::uint32_t); //length in bytes (from VRT header) - + const size_t len = (uhd::wtohx(mem32[0]) & 0xffff)*sizeof(boost::uint32_t); //length in bytes (from VRT header) + managed_recv_buffer::sptr recv_buff; //the buffer to be returned to the user - recv_buff = wmrb->get_new(_last_recv_buff, mem, len); - _last_recv_offset = next_boundary(_last_recv_offset + len, 4); - + _last_recv_offset += len; + //check if this receive buffer has been exhausted if (_last_recv_offset >= _last_recv_buff->size()) { _last_recv_buff.reset(); } - + return recv_buff; } @@ -156,16 +161,7 @@ public: } managed_send_buffer::sptr get_send_buff(double timeout){ - managed_send_buffer::sptr send_buff = _internal_zc->get_send_buff(timeout); - - //attempt to get a wrapper for a managed send buffer - usb_zero_copy_wrapper_msb *wmsb = NULL; - if (send_buff.get() and _available_send_buffs.pop_with_haste(wmsb)){ - return wmsb->get_new(send_buff); - } - - //otherwise return a null sptr for failure - return managed_send_buffer::sptr(); + return _the_only_msb.get_new(timeout); } size_t get_num_send_frames(void) const{ @@ -178,15 +174,13 @@ public: private: sptr _internal_zc; - size_t _usb_frame_boundary; bounded_buffer _available_recv_buffs; - bounded_buffer _available_send_buffs; std::vector _mrb_pool; - std::vector _msb_pool; - + usb_zero_copy_wrapper_msb _the_only_msb; + //buffer to store partially-received VRT packets in buffer_pool::sptr _fragment_mem; - + //state for last recv buffer to create multiple managed buffers managed_recv_buffer::sptr _last_recv_buff; size_t _last_recv_offset; diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index 87aee9568..455efa2fe 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 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 @@ -229,7 +229,8 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ 2, 6, // IN interface, endpoint 1, 2, // OUT interface, endpoint data_xport_args // param hints - ) + ), + B100_MAX_PKT_BYTE_LIMIT ); //////////////////////////////////////////////////////////////////// diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp index 433f45aef..49a3139f0 100644 --- a/host/lib/usrp/b100/b100_impl.hpp +++ b/host/lib/usrp/b100/b100_impl.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 @@ -52,6 +52,7 @@ static const boost::uint16_t B100_FPGA_COMPAT_NUM = 0x09; static const boost::uint32_t B100_RX_SID_BASE = 2; static const boost::uint32_t B100_TX_ASYNC_SID = 1; static const double B100_DEFAULT_TICK_RATE = 64e6; +static const size_t B100_MAX_PKT_BYTE_LIMIT = 2048; //! Make a b100 dboard interface uhd::usrp::dboard_iface::sptr make_b100_dboard_iface( diff --git a/host/lib/usrp/b100/b100_regs.hpp b/host/lib/usrp/b100/b100_regs.hpp index b625e65a5..b87a0ad73 100644 --- a/host/lib/usrp/b100/b100_regs.hpp +++ b/host/lib/usrp/b100/b100_regs.hpp @@ -1,4 +1,19 @@ - +// +// 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 +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// //////////////////////////////////////////////////////////////// // diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index 7c07c6349..b1a44d70e 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.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 @@ -211,7 +211,7 @@ rx_streamer::sptr b100_impl::get_rx_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 ; - const size_t bpp = 2048 - hdr_size; //limited by FPGA pkt buffer size + const size_t bpp = B100_MAX_PKT_BYTE_LIMIT - hdr_size; const size_t bpi = convert::get_bytes_per_item(args.otw_format); const size_t spp = unsigned(args.args.cast("spp", bpp/bpi)); @@ -260,10 +260,6 @@ tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){ args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; args.channels = args.channels.empty()? std::vector(1, 0) : args.channels; - if (args.otw_format == "sc8"){ - throw uhd::value_error("USRP TX requested wire format not implemented in FPGA: " + args.otw_format); - } - //calculate packet size static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) @@ -271,7 +267,7 @@ tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){ - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used - sizeof(vrt::if_packet_info_t().cid) //no class id ever used ; - static const size_t bpp = _data_transport->get_send_frame_size() - hdr_size; + 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); //make the new streamer given the samples per packet diff --git a/host/lib/usrp/e100/e100_impl.cpp b/host/lib/usrp/e100/e100_impl.cpp index cd6143a16..8ab6ab533 100644 --- a/host/lib/usrp/e100/e100_impl.cpp +++ b/host/lib/usrp/e100/e100_impl.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 diff --git a/host/lib/usrp/e100/e100_impl.hpp b/host/lib/usrp/e100/e100_impl.hpp index e641aeea9..1d36cb2ac 100644 --- a/host/lib/usrp/e100/e100_impl.hpp +++ b/host/lib/usrp/e100/e100_impl.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 diff --git a/host/lib/usrp/e100/e100_regs.hpp b/host/lib/usrp/e100/e100_regs.hpp index 265086540..eee27b5b3 100644 --- a/host/lib/usrp/e100/e100_regs.hpp +++ b/host/lib/usrp/e100/e100_regs.hpp @@ -1,4 +1,19 @@ - +// +// 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 +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// //////////////////////////////////////////////////////////////// // diff --git a/host/lib/usrp/e100/io_impl.cpp b/host/lib/usrp/e100/io_impl.cpp index 2b64e7f17..4d530585b 100644 --- a/host/lib/usrp/e100/io_impl.cpp +++ b/host/lib/usrp/e100/io_impl.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 diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp index e9d9b65c2..f3cad188a 100644 --- a/host/lib/usrp/usrp1/io_impl.cpp +++ b/host/lib/usrp/usrp1/io_impl.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 diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 9b6c1c2f0..f19f49e28 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.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 diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 206016972..7101e040a 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.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 diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index c060f75b5..882a61f80 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.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 diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index 8f714cbbc..5d39e527d 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.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 -- cgit v1.2.3 From 5eec31fab45649b529428cda756d04bcdaeb3134 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 6 Feb 2012 16:40:42 -0800 Subject: dsp rework: implement 64 bit ticks, no seconds --- host/include/uhd/types/time_spec.hpp | 20 ++++++++++++-- host/lib/transport/super_recv_packet_handler.hpp | 8 +++--- host/lib/transport/super_send_packet_handler.hpp | 12 ++++----- host/lib/types/time_spec.cpp | 29 ++++++++++---------- host/lib/usrp/b100/b100_impl.cpp | 8 +++--- host/lib/usrp/b100/b100_regs.hpp | 8 +++--- host/lib/usrp/b100/io_impl.cpp | 8 +++--- host/lib/usrp/cores/rx_dsp_core_200.cpp | 10 +++---- host/lib/usrp/cores/time64_core_200.cpp | 34 +++++++++++++----------- host/lib/usrp/cores/time64_core_200.hpp | 4 +-- host/lib/usrp/e100/e100_impl.cpp | 8 +++--- host/lib/usrp/e100/e100_regs.hpp | 8 +++--- host/lib/usrp/e100/io_impl.cpp | 8 +++--- host/lib/usrp/usrp2/io_impl.cpp | 8 +++--- host/lib/usrp/usrp2/usrp2_iface.cpp | 4 +-- host/lib/usrp/usrp2/usrp2_impl.cpp | 8 +++--- host/lib/usrp/usrp2/usrp2_regs.hpp | 8 +++--- host/tests/sph_recv_test.cpp | 24 ++++++++--------- host/tests/sph_send_test.cpp | 6 +---- host/tests/time_spec_test.cpp | 6 ++--- 20 files changed, 120 insertions(+), 109 deletions(-) (limited to 'host/lib/usrp/e100/e100_impl.cpp') 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 @@ -68,6 +68,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. @@ -76,6 +84,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, 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() + _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(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 +#include //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 //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_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 #include -#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 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(U2_FW_REG_LOCK_TIME); boost::uint32_t lock_gpid = this->get_reg(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(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){ -- cgit v1.2.3