diff options
author | Johnathan Corgan <johnathan@corganlabs.com> | 2017-10-05 16:09:55 -0700 |
---|---|---|
committer | Johnathan Corgan <johnathan@corganlabs.com> | 2017-10-05 16:36:29 -0700 |
commit | 3c63f7334d6de70d655aa97fcccbfb950645f4d4 (patch) | |
tree | ac06cdb228d00e02fcab9a47852bfc57b5957d0c /gr-uhd | |
parent | 8fe518ce740ae728f658c1854a7ffa074e800e9d (diff) | |
parent | a0adcd3347c7ffd6ef3c42ce7705a23978774d3b (diff) |
Merge branch 'master' into next
Conflicts:
gr-digital/examples/CMakeLists.txt
gr-uhd/lib/usrp_source_impl.cc
gr-uhd/lib/usrp_source_impl.h
Diffstat (limited to 'gr-uhd')
-rw-r--r-- | gr-uhd/doc/uhd.dox | 1 | ||||
-rw-r--r-- | gr-uhd/include/gnuradio/uhd/usrp_source.h | 27 | ||||
-rw-r--r-- | gr-uhd/lib/usrp_block_impl.cc | 16 | ||||
-rw-r--r-- | gr-uhd/lib/usrp_block_impl.h | 12 | ||||
-rw-r--r-- | gr-uhd/lib/usrp_sink_impl.cc | 12 | ||||
-rw-r--r-- | gr-uhd/lib/usrp_sink_impl.h | 2 | ||||
-rw-r--r-- | gr-uhd/lib/usrp_source_impl.cc | 25 | ||||
-rw-r--r-- | gr-uhd/lib/usrp_source_impl.h | 7 |
8 files changed, 82 insertions, 20 deletions
diff --git a/gr-uhd/doc/uhd.dox b/gr-uhd/doc/uhd.dox index a3de8e3a24..69381610cd 100644 --- a/gr-uhd/doc/uhd.dox +++ b/gr-uhd/doc/uhd.dox @@ -93,6 +93,7 @@ Command name | Value Type | Description `tune` | tune_request | Like freq, but sets a full tune request (i.e. center frequency and DSP offset). Defaults to all channels. `lo_freq` | double | For fully manual tuning: Set the LO frequency (RF frequency). Conflicts with `freq`, `lo_offset`, and `tune`. `dsp_freq` | double | For fully manual tuning: Set the DSP frequency (CORDIC frequency). Conflicts with `freq`, `lo_offset`, and `tune`. +`direction` | string | Used for timed transceiver tuning to ensure tuning order is maintained. Values other than 'TX' or 'RX' will be ignored. `rate` | double | See usrp_block::set_samp_rate(). *Always* affects all channels. `bandwidth` | double | See usrp_block::set_bandwidth(). Defaults to all channels. `time` | timestamp | Sets a command time. See usrp_block::set_command_time(). A value of PMT_NIL will clear the command time. diff --git a/gr-uhd/include/gnuradio/uhd/usrp_source.h b/gr-uhd/include/gnuradio/uhd/usrp_source.h index 552c518f1c..60413e35d4 100644 --- a/gr-uhd/include/gnuradio/uhd/usrp_source.h +++ b/gr-uhd/include/gnuradio/uhd/usrp_source.h @@ -98,6 +98,33 @@ namespace gr { */ virtual void issue_stream_cmd(const ::uhd::stream_cmd_t &cmd) = 0; + /*! Configure the timeout value on the UHD recv() call + * + * This is an advanced use parameter. Changing the timeout value affects + * the latency of this block; a high timeout value can be more optimal + * for high-throughput applications (e.g., 1 second) and setting it to + * zero will have the best latency. Changing the timeout value may also + * be useful for custom FPGA modifications, where traffic might not be + * continuously streaming. + * For specialized high-performance use cases, twiddling these knobs may + * improve performance, but changes are not generally applicable. + * + * Note that UHD's recv() call may block until the timeout is over, which + * means this block might also block for up to the timeout value. + * + * \param timeout Timeout parameter in seconds. Cf. the UHD manual for + * uhd::rx_streamer::recv() for more details. A lower + * value will mean lower latency, but higher CPU load. + * \param one_packet If true, only receive one packet at a time. Cf. the + * UHD manual for uhd::rx_streamer::recv() for more + * details. A value of true will mean lower latency, + * but higher CPU load. + */ + virtual void set_recv_timeout( + const double timeout, + const bool one_packet=true + ) = 0; + /*! * Returns identifying information about this USRP's configuration. * Returns motherboard ID, name, and serial. diff --git a/gr-uhd/lib/usrp_block_impl.cc b/gr-uhd/lib/usrp_block_impl.cc index 341e1a9fd8..df1832ed2e 100644 --- a/gr-uhd/lib/usrp_block_impl.cc +++ b/gr-uhd/lib/usrp_block_impl.cc @@ -39,6 +39,7 @@ const pmt::pmt_t CMD_BANDWIDTH_KEY = pmt::mp("bandwidth"); const pmt::pmt_t CMD_TIME_KEY = pmt::mp("time"); const pmt::pmt_t CMD_MBOARD_KEY = pmt::mp("mboard"); const pmt::pmt_t CMD_ANTENNA_KEY = pmt::mp("antenna"); +const pmt::pmt_t CMD_DIRECTION_KEY = pmt::mp("direction"); /********************************************************************** @@ -209,11 +210,11 @@ bool usrp_block_impl::_check_mboard_sensors_locked() } void -usrp_block_impl::_set_center_freq_from_internals_allchans() +usrp_block_impl::_set_center_freq_from_internals_allchans(pmt::pmt_t direction) { while (_chans_to_tune.any()) { // This resets() bits, so this loop should not run indefinitely - _set_center_freq_from_internals(_chans_to_tune.find_first()); + _set_center_freq_from_internals(_chans_to_tune.find_first(), direction); } } @@ -503,8 +504,14 @@ void usrp_block_impl::msg_handler_command(pmt::pmt_t msg) } } - /// 4) Check if we need to re-tune - _set_center_freq_from_internals_allchans(); + /// 4) See if a direction was specified + pmt::pmt_t direction = pmt::dict_ref( + msg, CMD_DIRECTION_KEY, + pmt::PMT_NIL // Anything except "TX" or "RX will default to the messaged block direction" + ); + + /// 5) Check if we need to re-tune + _set_center_freq_from_internals_allchans(direction); } @@ -663,4 +670,3 @@ void usrp_block_impl::_cmd_handler_dspfreq(const pmt::pmt_t &dspfreq, int chan, _update_curr_tune_req(new_tune_request, chan); } - diff --git a/gr-uhd/lib/usrp_block_impl.h b/gr-uhd/lib/usrp_block_impl.h index 8285bda42c..b4618479e2 100644 --- a/gr-uhd/lib/usrp_block_impl.h +++ b/gr-uhd/lib/usrp_block_impl.h @@ -29,13 +29,6 @@ #include <boost/dynamic_bitset.hpp> #include <boost/bind.hpp> -#define SET_CENTER_FREQ_FROM_INTERNALS(usrp_class, tune_method) \ - ::uhd::tune_result_t \ - usrp_class::_set_center_freq_from_internals(size_t chan) \ - { \ - _chans_to_tune.reset(chan); \ - return _dev->tune_method(_curr_tune_req[chan], _stream_args.channels[chan]); \ - } namespace gr { namespace uhd { @@ -213,10 +206,10 @@ namespace gr { } //! Like set_center_freq(), but uses _curr_freq and _curr_lo_offset - virtual ::uhd::tune_result_t _set_center_freq_from_internals(size_t chan) = 0; + virtual ::uhd::tune_result_t _set_center_freq_from_internals(size_t chan, pmt::pmt_t direction) = 0; //! Calls _set_center_freq_from_internals() on all channels - void _set_center_freq_from_internals_allchans(); + void _set_center_freq_from_internals_allchans(pmt::pmt_t direction); /********************************************************************** * Members @@ -247,4 +240,3 @@ namespace gr { } /* namespace gr */ #endif /* INCLUDED_GR_UHD_BLOCK_IMPL_H */ - diff --git a/gr-uhd/lib/usrp_sink_impl.cc b/gr-uhd/lib/usrp_sink_impl.cc index ef49c1048e..7eaf93f438 100644 --- a/gr-uhd/lib/usrp_sink_impl.cc +++ b/gr-uhd/lib/usrp_sink_impl.cc @@ -107,7 +107,17 @@ namespace gr { return _dev->set_tx_freq(tune_request, chan); } - SET_CENTER_FREQ_FROM_INTERNALS(usrp_sink_impl, set_tx_freq); + ::uhd::tune_result_t + usrp_sink_impl::_set_center_freq_from_internals(size_t chan, pmt::pmt_t direction) + { + _chans_to_tune.reset(chan); + if (pmt::eqv(direction, pmt::mp("RX"))) { + // TODO: what happens if the RX device is not instantiated? Catch error? + return _dev->set_rx_freq(_curr_tune_req[chan], _stream_args.channels[chan]); + } else { + return _dev->set_tx_freq(_curr_tune_req[chan], _stream_args.channels[chan]); + } + } double usrp_sink_impl::get_center_freq(size_t chan) diff --git a/gr-uhd/lib/usrp_sink_impl.h b/gr-uhd/lib/usrp_sink_impl.h index 304a02ca7b..fbf4e2a42e 100644 --- a/gr-uhd/lib/usrp_sink_impl.h +++ b/gr-uhd/lib/usrp_sink_impl.h @@ -99,7 +99,7 @@ namespace gr { private: //! Like set_center_freq(), but uses _curr_freq and _curr_lo_offset - ::uhd::tune_result_t _set_center_freq_from_internals(size_t chan); + ::uhd::tune_result_t _set_center_freq_from_internals(size_t chan, pmt::pmt_t direction); ::uhd::tx_streamer::sptr _tx_stream; ::uhd::tx_metadata_t _metadata; diff --git a/gr-uhd/lib/usrp_source_impl.cc b/gr-uhd/lib/usrp_source_impl.cc index 52e67baccf..069cff9430 100644 --- a/gr-uhd/lib/usrp_source_impl.cc +++ b/gr-uhd/lib/usrp_source_impl.cc @@ -51,6 +51,7 @@ namespace gr { args_to_io_sig(stream_args)), usrp_block_impl(device_addr, stream_args, ""), _recv_timeout(0.1), // seconds + _recv_one_packet(true), _tag_now(false), _issue_stream_cmd_on_start(issue_stream_cmd_on_start) { @@ -119,7 +120,17 @@ namespace gr { return res; } - SET_CENTER_FREQ_FROM_INTERNALS(usrp_source_impl, set_rx_freq); + ::uhd::tune_result_t + usrp_source_impl::_set_center_freq_from_internals(size_t chan, pmt::pmt_t direction) + { + _chans_to_tune.reset(chan); + if (pmt::eqv(direction, pmt::mp("TX"))) { + // TODO: what happens if the TX device is not instantiated? Catch error? + return _dev->set_tx_freq(_curr_tune_req[chan], _stream_args.channels[chan]); + } else { + return _dev->set_rx_freq(_curr_tune_req[chan], _stream_args.channels[chan]); + } + } double usrp_source_impl::get_center_freq(size_t chan) @@ -449,6 +460,15 @@ namespace gr { _tag_now = true; } + void + usrp_source_impl::set_recv_timeout( + const double timeout, + const bool one_packet + ) { + _recv_timeout = timeout; + _recv_one_packet = one_packet; + } + bool usrp_source_impl::start(void) { @@ -492,6 +512,7 @@ namespace gr { else // no rx streamer -- nothing to flush break; + if(_metadata.error_code == ::uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) break; } @@ -572,7 +593,7 @@ namespace gr { noutput_items, _metadata, _recv_timeout, - true /* one packet -> minimize latency */ + _recv_one_packet ); boost::this_thread::restore_interruption restore_interrupt(disable_interrupt); diff --git a/gr-uhd/lib/usrp_source_impl.h b/gr-uhd/lib/usrp_source_impl.h index 2e5c1d31de..6a592aa887 100644 --- a/gr-uhd/lib/usrp_source_impl.h +++ b/gr-uhd/lib/usrp_source_impl.h @@ -99,6 +99,7 @@ namespace gr { double set_lo_freq(double freq, const std::string &name, size_t chan); void issue_stream_cmd(const ::uhd::stream_cmd_t &cmd); + void set_recv_timeout(const double timeout, const bool one_packet); void flush(void); bool start(void); bool stop(void); @@ -112,12 +113,16 @@ namespace gr { private: //! Like set_center_freq(), but uses _curr_freq and _curr_lo_offset - ::uhd::tune_result_t _set_center_freq_from_internals(size_t chan); + ::uhd::tune_result_t _set_center_freq_from_internals(size_t chan, pmt::pmt_t direction); void _cmd_handler_tag(const pmt::pmt_t &tag); ::uhd::rx_streamer::sptr _rx_stream; size_t _samps_per_packet; + //! Timeout value for UHD's recv() call. Lower values mean lower latency. double _recv_timeout; + //! one_packet value for UHD's recv() call. 'true' is lower latency. + bool _recv_one_packet; + bool _tag_now; ::uhd::rx_metadata_t _metadata; pmt::pmt_t _id; |