[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] [gnuradio] 07/11: uhd: Added retune-by-tag and a comma
From: |
git |
Subject: |
[Commit-gnuradio] [gnuradio] 07/11: uhd: Added retune-by-tag and a command interface via message passing |
Date: |
Sat, 26 Apr 2014 22:34:12 +0000 (UTC) |
This is an automated email from the git hooks/post-receive script.
jcorgan pushed a commit to branch master
in repository gnuradio.
commit fe815bdd4f79c0159ebee0361d0d7e15e7b920aa
Author: Martin Braun <address@hidden>
Date: Fri Apr 4 17:56:25 2014 +0200
uhd: Added retune-by-tag and a command interface via message passing
---
gr-uhd/include/gnuradio/uhd/usrp_sink.h | 10 ++-
gr-uhd/lib/usrp_sink_impl.cc | 117 +++++++++++++++++++++++++++++++-
gr-uhd/lib/usrp_sink_impl.h | 19 ++++++
3 files changed, 142 insertions(+), 4 deletions(-)
diff --git a/gr-uhd/include/gnuradio/uhd/usrp_sink.h
b/gr-uhd/include/gnuradio/uhd/usrp_sink.h
index c57524e..cac3e01 100644
--- a/gr-uhd/include/gnuradio/uhd/usrp_sink.h
+++ b/gr-uhd/include/gnuradio/uhd/usrp_sink.h
@@ -72,6 +72,7 @@ namespace gr {
* - pmt::string_to_symbol("tx_sob")
* - pmt::string_to_symbol("tx_eob")
* - pmt::string_to_symbol("tx_time")
+ * - pmt::string_to_symbol("tx_freq")
* - pmt::string_to_symbol(length_tag_name)
*
* The sob and eob (start and end of burst) tag values are pmt booleans.
@@ -86,10 +87,13 @@ namespace gr {
* The timstamp tag value is a pmt tuple of the following:
* (uint64 seconds, and double fractional seconds).
*
+ * The tx_freq tag has to be a double, and will re-tune the USRP to the
given frequency,
+ * if possible.
+ *
* See the UHD manual for more detailed documentation:
* http://code.ettus.com/redmine/ettus/projects/uhd/wiki
*
- * \param device_addr the address to identify the hardware
+ * \param device_addr the address to identify the hardware (e.g.
"type=b200", "addr=192.168.10.2")
* \param io_type the desired input data type
* \param num_channels number of stream from the device
* \param length_tag_name the name of the tag identifying tagged stream
length
@@ -112,6 +116,7 @@ namespace gr {
* - pmt::string_to_symbol("tx_sob")
* - pmt::string_to_symbol("tx_eob")
* - pmt::string_to_symbol("tx_time")
+ * - pmt::string_to_symbol("tx_freq")
* - pmt::string_to_symbol(length_tag_name)
*
* The sob and eob (start and end of burst) tag values are pmt booleans.
@@ -126,6 +131,9 @@ namespace gr {
* The timstamp tag value is a pmt tuple of the following:
* (uint64 seconds, and double fractional seconds).
*
+ * The tx_freq tag has to be a double, and will re-tune the USRP to the
given frequency,
+ * if possible.
+ *
* See the UHD manual for more detailed documentation:
* http://code.ettus.com/redmine/ettus/projects/uhd/wiki
*
diff --git a/gr-uhd/lib/usrp_sink_impl.cc b/gr-uhd/lib/usrp_sink_impl.cc
index 413952a..f55d1f5 100644
--- a/gr-uhd/lib/usrp_sink_impl.cc
+++ b/gr-uhd/lib/usrp_sink_impl.cc
@@ -71,13 +71,27 @@ namespace gr {
_stream_now(_nchan == 1),
_start_time_set(false),
_length_tag_key(length_tag_name.empty() ? pmt::PMT_NIL :
pmt::string_to_symbol(length_tag_name)),
- _nitems_to_send(0)
+ _nitems_to_send(0),
+ _curr_freq(stream_args.channels.size(), 0.0),
+ _curr_lo_offset(stream_args.channels.size(), 0.0),
+ _curr_gain(stream_args.channels.size(), 0.0)
{
if(stream_args.cpu_format == "fc32")
_type = boost::make_shared< ::uhd::io_type_t
>(::uhd::io_type_t::COMPLEX_FLOAT32);
if(stream_args.cpu_format == "sc16")
_type = boost::make_shared< ::uhd::io_type_t
>(::uhd::io_type_t::COMPLEX_INT16);
_dev = ::uhd::usrp::multi_usrp::make(device_addr);
+
+ message_port_register_in(pmt::mp("command"));
+ set_msg_handler(
+ pmt::mp("command"),
+ boost::bind(&usrp_sink_impl::msg_handler_command, this, _1)
+ );
+ message_port_register_in(pmt::mp("query"));
+ set_msg_handler(
+ pmt::mp("query"),
+ boost::bind(&usrp_sink_impl::msg_handler_query, this, _1)
+ );
}
usrp_sink_impl::~usrp_sink_impl()
@@ -138,10 +152,29 @@ namespace gr {
usrp_sink_impl::set_center_freq(const ::uhd::tune_request_t tune_request,
size_t chan)
{
+ _curr_freq[chan] = tune_request.target_freq;
+ if (tune_request.rf_freq_policy == ::uhd::tune_request_t::POLICY_MANUAL)
{
+ _curr_lo_offset[chan] = tune_request.rf_freq -
tune_request.target_freq;
+ } else {
+ _curr_lo_offset[chan] = 0.0;
+ }
chan = _stream_args.channels[chan];
return _dev->set_tx_freq(tune_request, chan);
}
+ ::uhd::tune_result_t
+ usrp_sink_impl::_set_center_freq_from_internals(size_t chan)
+ {
+ if (_curr_lo_offset[chan] == 0.0) {
+ return _dev->set_tx_freq(_curr_freq[chan], _stream_args.channels[chan]);
+ } else {
+ return _dev->set_tx_freq(
+ ::uhd::tune_request_t(_curr_freq[chan], _curr_lo_offset[chan]),
+ _stream_args.channels[chan]
+ );
+ }
+ }
+
double
usrp_sink_impl::get_center_freq(size_t chan)
{
@@ -159,6 +192,7 @@ namespace gr {
void
usrp_sink_impl::set_gain(double gain, size_t chan)
{
+ _curr_gain[chan] = gain;
chan = _stream_args.channels[chan];
return _dev->set_tx_gain(gain, chan);
}
@@ -168,6 +202,7 @@ namespace gr {
const std::string &name,
size_t chan)
{
+ _curr_gain[chan] = gain;
chan = _stream_args.channels[chan];
return _dev->set_tx_gain(gain, name, chan);
}
@@ -546,6 +581,8 @@ namespace gr {
//time will not be set unless a time tag is found
_metadata.has_time_spec = false;
+ bool call_tune_loop = false;
+ std::vector<bool> do_tune(_nchan, false);
//process all of the tags found with the same count as tag0
BOOST_FOREACH(const tag_t &my_tag, _tags) {
const uint64_t my_tag_count = my_tag.offset;
@@ -590,8 +627,38 @@ namespace gr {
(pmt::to_uint64(pmt::tuple_ref(value, 0)),
pmt::to_double(pmt::tuple_ref(value, 1)));
}
- }
- }
+
+ //set the new tx frequency
+ else if(pmt::equal(key, FREQ_KEY)) {
+ int chan = pmt::to_long(pmt::tuple_ref(value, 0));
+ double new_freq = pmt::to_double(pmt::tuple_ref(value, 1));
+ if (new_freq != _curr_freq[chan]) {
+ call_tune_loop = true;
+ do_tune[chan] = true;
+ _curr_freq[chan] = new_freq;
+ }
+ }
+
+ //set the new lo offset
+ else if(pmt::equal(key, LO_OFFS_KEY)) {
+ int chan = pmt::to_long(pmt::tuple_ref(value, 0));
+ double new_lo_offs = pmt::to_double(pmt::tuple_ref(value, 1));
+ if (new_lo_offs != _curr_lo_offset[chan]) {
+ call_tune_loop = true;
+ do_tune[chan] = true;
+ _curr_lo_offset[chan] = new_lo_offs;
+ }
+ }
+ } // end foreach
+ // If there was a freq tag, tune the transmitter(s)
+ if (call_tune_loop) {
+ for (size_t chan = 0; chan < _nchan; chan++) {
+ if (do_tune[chan]) {
+ _set_center_freq_from_internals(chan);
+ }
+ }
+ } // end if call_tune_loop
+ } // end tag_work()
void
usrp_sink_impl::set_start_time(const ::uhd::time_spec_t &time)
@@ -653,6 +720,50 @@ namespace gr {
return true;
}
+
+ /************** External interfaces (RPC + Message passing)
********************/
+ // Helper function for msg_handler_command: Extracts chan and command
value from
+ // the 2-tuple in cmd_val, updates the value in vector_to_update[chan] and
returns
+ // true if it was different from the old value.
+ bool _unpack_chan_command(pmt::pmt_t &cmd_val, int &chan,
std::vector<double> &vector_to_update)
+ {
+ chan = pmt::to_long(pmt::tuple_ref(cmd_val, 0));
+ double new_value = pmt::to_double(pmt::tuple_ref(cmd_val, 1));
+ if (new_value == vector_to_update[chan]) {
+ return false;
+ } else {
+ vector_to_update[chan] = new_value;
+ return true;
+ }
+ }
+
+ void usrp_sink_impl::msg_handler_command(pmt::pmt_t msg)
+ {
+ const std::string command(pmt::symbol_to_string(pmt::car(msg)));
+ pmt::pmt_t value(pmt::cdr(msg));
+ int chan = 0;
+ if (command == "freq") {
+ if (_unpack_chan_command(value, chan, _curr_freq)) {
+ _set_center_freq_from_internals(chan);
+ }
+ } else if (command == "lo_offset") {
+ if (_unpack_chan_command(value, chan, _curr_lo_offset)) {
+ _set_center_freq_from_internals(chan);
+ }
+ } else if (command == "gain") {
+ if (_unpack_chan_command(value, chan, _curr_gain)) {
+ set_gain(_curr_gain[chan], chan);
+ }
+ } else {
+ GR_LOG_ALERT(d_logger, boost::format("Received unknown command: %s") %
command);
+ }
+ }
+
+ void usrp_sink_impl::msg_handler_query(pmt::pmt_t msg)
+ {
+
+ }
+
void
usrp_sink_impl::setup_rpc()
{
diff --git a/gr-uhd/lib/usrp_sink_impl.h b/gr-uhd/lib/usrp_sink_impl.h
index ae31b51..c2e488e 100644
--- a/gr-uhd/lib/usrp_sink_impl.h
+++ b/gr-uhd/lib/usrp_sink_impl.h
@@ -26,6 +26,8 @@
static const pmt::pmt_t SOB_KEY = pmt::string_to_symbol("tx_sob");
static const pmt::pmt_t EOB_KEY = pmt::string_to_symbol("tx_eob");
static const pmt::pmt_t TIME_KEY = pmt::string_to_symbol("tx_time");
+static const pmt::pmt_t FREQ_KEY = pmt::string_to_symbol("tx_freq");
+static const pmt::pmt_t LO_OFFS_KEY = pmt::string_to_symbol("tx_lo_offset");
namespace gr {
namespace uhd {
@@ -120,6 +122,13 @@ namespace gr {
inline void tag_work(int &ninput_items);
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);
+ //! Receives commands and handles them
+ void msg_handler_command(pmt::pmt_t msg);
+ //! Receives queries and posts a response
+ void msg_handler_query(pmt::pmt_t msg);
+
::uhd::usrp::multi_usrp::sptr _dev;
const ::uhd::stream_args_t _stream_args;
boost::shared_ptr< ::uhd::io_type_t > _type;
@@ -138,6 +147,16 @@ namespace gr {
std::vector<tag_t> _tags;
const pmt::pmt_t _length_tag_key;
long _nitems_to_send;
+
+ //! Stores the last value we told the USRP to tune to for every channel
+ // (this is not necessarily the true value the USRP is currently tuned
to!).
+ // We could theoretically ask the device, but during streaming, we want
to minimize
+ // communication with the USRP.
+ std::vector<double> _curr_freq;
+ //! Stores the last value we told the USRP to have the LO offset for
every channel.
+ std::vector<double> _curr_lo_offset;
+ //! Stores the last gain value we told the USRP to have for every
channel.
+ std::vector<double> _curr_gain;
};
} /* namespace uhd */
- [Commit-gnuradio] [gnuradio] branch master updated (754cfa7 -> a337dcb), git, 2014/04/26
- [Commit-gnuradio] [gnuradio] 02/11: uhd: fixed tags_demo, git, 2014/04/26
- [Commit-gnuradio] [gnuradio] 01/11: gr-uhd: added tagged stream support, git, 2014/04/26
- [Commit-gnuradio] [gnuradio] 10/11: uhd: Added freq hopping example, improved tag handling in usrp_sink, git, 2014/04/26
- [Commit-gnuradio] [gnuradio] 06/11: uhd: modified tag preemption/gap handling, git, 2014/04/26
- [Commit-gnuradio] [gnuradio] 03/11: uhd: changed length_tag member variable from string to pmt symbol, git, 2014/04/26
- [Commit-gnuradio] [gnuradio] 11/11: uhd: Used uhd-internal fragmentation handling, bursty tx w/o time tags now no longer uses time specs, git, 2014/04/26
- [Commit-gnuradio] [gnuradio] 05/11: uhd: added length tag name parameter in GRC, git, 2014/04/26
- [Commit-gnuradio] [gnuradio] 07/11: uhd: Added retune-by-tag and a command interface via message passing,
git <=
- [Commit-gnuradio] [gnuradio] 08/11: uhd: Allow post-burst tune; tag handling less restrictive, git, 2014/04/26
- [Commit-gnuradio] [gnuradio] 04/11: uhd: added notification for tagged stream preemptions/gaps, git, 2014/04/26
- [Commit-gnuradio] [gnuradio] 09/11: docs: Updated uhd to reflect tag changes., git, 2014/04/26