summaryrefslogtreecommitdiff
path: root/gr-uhd
diff options
context:
space:
mode:
Diffstat (limited to 'gr-uhd')
-rw-r--r--gr-uhd/apps/uhd_app.py85
-rwxr-xr-xgr-uhd/apps/uhd_fft24
-rw-r--r--gr-uhd/doc/uhd.dox8
-rw-r--r--gr-uhd/lib/usrp_sink_impl.cc10
-rw-r--r--gr-uhd/lib/usrp_source_impl.cc10
5 files changed, 105 insertions, 32 deletions
diff --git a/gr-uhd/apps/uhd_app.py b/gr-uhd/apps/uhd_app.py
index 8e377f0b4d..f9b08a6457 100644
--- a/gr-uhd/apps/uhd_app.py
+++ b/gr-uhd/apps/uhd_app.py
@@ -135,6 +135,15 @@ class UHDApp(object):
))
return specs
+ def normalize_lo_source_export_sel(self, args):
+ lo_source = [x.strip() for x in args.lo_source.split(",")]
+ lo_export = [x.strip() for x in args.lo_export.split(",")]
+ if len(lo_source) != len(self.channels):
+ raise ValueError("Invalid number of lo-source settings {n} for {c} channels. Must be one argument per channel.".format(n=len(lo_source), c=len(args.channels)))
+ if len(lo_export) != len(self.channels):
+ raise ValueError("Invalid number of lo-export settings {n} for {c} channels. Must be one argument per channel.".format(n=len(lo_source), c=len(args.channels)))
+ return (lo_source, lo_export)
+
def async_callback(self, msg):
"""
Call this when USRP async metadata needs printing.
@@ -187,23 +196,49 @@ class UHDApp(object):
self.antenna = self.normalize_antenna_sel(args)
if self.antenna is not None:
for i, chan in enumerate(self.channels):
- if not self.antenna[i] in self.usrp.get_antennas(chan):
+ if not self.antenna[i] in self.usrp.get_antennas(i):
self.vprint("[ERROR] {} is not a valid antenna name for this USRP device!".format(self.antenna[i]))
exit(1)
- self.usrp.set_antenna(self.antenna[i], chan)
+ self.usrp.set_antenna(self.antenna[i], i)
self.vprint("[{prefix}] Channel {chan}: Using antenna {ant}.".format(
- prefix=self.prefix, chan=chan, ant=self.usrp.get_antenna(chan)
+ prefix=self.prefix, chan=chan, ant=self.usrp.get_antenna(i)
))
- self.antenna = self.usrp.get_antenna(self.channels[0])
+ self.antenna = self.usrp.get_antenna(0)
# Set receive daughterboard gain:
self.set_gain(args.gain)
- self.gain_range = self.usrp.get_gain_range(self.channels[0])
+ self.gain_range = self.usrp.get_gain_range(0)
# Set frequency (tune request takes lo_offset):
if hasattr(args, 'lo_offset') and args.lo_offset is not None:
treq = uhd.tune_request(args.freq, args.lo_offset)
else:
treq = uhd.tune_request(args.freq)
self.has_lo_sensor = 'lo_locked' in self.usrp.get_sensor_names()
+ # Set LO export and LO source operation
+ if (args.lo_export is not None) and (args.lo_source is not None):
+ (args.lo_source,args.lo_export) = self.normalize_lo_source_export_sel(args)
+ for chan,lo_source,lo_export in zip(self.channels,args.lo_source,args.lo_export):
+ if (lo_source == "None") or (lo_export == "None"):
+ continue
+ if lo_export == "True":
+ #If channel is LO source set frequency and store response
+ self.usrp.set_lo_export_enabled(True, uhd.ALL_LOS, chan)
+ if lo_source == "internal":
+ self.lo_source_channel = chan
+ tune_resp = self.usrp.set_center_freq(treq,chan)
+ self.usrp.set_lo_source(lo_source, uhd.ALL_LOS,chan)
+ # Use lo source tune response to tune dsp_freq on remaining channels
+ if getattr(args, 'lo_offset', None) is not None:
+ treq = uhd.tune_request(target_freq=args.freq, rf_freq=args.freq+args.lo_offset, rf_freq_policy=uhd.tune_request.POLICY_MANUAL,
+ dsp_freq=tune_resp.actual_dsp_freq,
+ dsp_freq_policy=uhd.tune_request.POLICY_MANUAL)
+ else:
+ treq = uhd.tune_request(target_freq=args.freq, rf_freq=args.freg, rf_freq_policy=uhd.tune_request.POLICY_MANUAL,
+ dsp_freq=tune_resp.actual_dsp_freq,
+ dsp_freq_policy=uhd.tune_request.POLICY_MANUAL)
+ for chan in args.channels:
+ if chan == self.lo_source_channel:
+ continue
+ self.usrp.set_center_freq(treq,chan)
# Make sure tuning is synched:
command_time_set = False
if len(self.channels) > 1:
@@ -216,8 +251,8 @@ class UHDApp(object):
command_time_set = True
except RuntimeError:
sys.stderr.write('[{prefix}] [WARNING] Failed to set command times.\n'.format(prefix=self.prefix))
- for chan in self.channels:
- self.tr = self.usrp.set_center_freq(treq, chan)
+ for i, chan in enumerate(self.channels):
+ self.tr = self.usrp.set_center_freq(treq, i)
if self.tr == None:
sys.stderr.write('[{prefix}] [ERROR] Failed to set center frequency on channel {chan}\n'.format(
prefix=self.prefix, chan=chan
@@ -228,7 +263,7 @@ class UHDApp(object):
self.usrp.clear_command_time(mb_idx)
self.vprint("Syncing channels...".format(prefix=self.prefix))
time.sleep(COMMAND_DELAY)
- self.freq = self.usrp.get_center_freq(self.channels[0])
+ self.freq = self.usrp.get_center_freq(0)
if args.show_async_msg:
self.async_msgq = gr.msg_queue(0)
self.async_src = uhd.amsg_source("", self.async_msgq)
@@ -243,17 +278,17 @@ class UHDApp(object):
if gain is None:
if self.args.verbose:
self.vprint("Defaulting to mid-point gains:".format(prefix=self.prefix))
- for chan in self.channels:
- self.usrp.set_normalized_gain(.5, chan)
+ for i, chan in enumerate(self.channels):
+ self.usrp.set_normalized_gain(.5, i)
if self.args.verbose:
self.vprint("Channel {chan} gain: {g} dB".format(
- prefix=self.prefix, chan=chan, g=self.usrp.get_gain(chan)
+ prefix=self.prefix, chan=chan, g=self.usrp.get_gain(i)
))
else:
self.vprint("Setting gain to {g} dB.".format(g=gain))
- for chan in self.channels:
+ for chan in range( len( self.channels ) ):
self.usrp.set_gain(gain, chan)
- self.gain = self.usrp.get_gain(self.channels[0])
+ self.gain = self.usrp.get_gain(0)
def set_freq(self, freq, skip_sync=False):
"""
@@ -265,6 +300,22 @@ class UHDApp(object):
treq = uhd.tune_request(freq, self.args.lo_offset)
else:
treq = uhd.tune_request(freq)
+ # Special TwinRX tuning due to LO sharing
+ if getattr(self, 'lo_source_channel', None) is not None:
+ tune_resp = self.usrp.set_center_freq(treq, self.lo_source_channel)
+ if getattr(self.args, 'lo_offset', None) is not None:
+ treq = uhd.tune_request(target_freq=freq, rf_freq=freq+self.args.lo_offset, rf_freq_policy=uhd.tune_request.POLICY_MANUAL,
+ dsp_freq=tune_resp.actual_dsp_freq,
+ dsp_freq_policy=uhd.tune_request.POLICY_MANUAL)
+ else:
+ treq = uhd.tune_request(target_freq=freq, rf_freq=freq, rf_freq_policy=uhd.tune_reqest.POLICY_MANUAL,
+ dsp_freq=tune_resp.actual_dsp_freq,
+ dsp_freq_policy=uhd.tune_request.POLICY_MANUAL)
+ for chan in self.channels:
+ if chan == self.lo_source_channel:
+ continue
+ self.usrp.set_center_freq(treq,chan)
+
# Make sure tuning is synched:
command_time_set = False
if len(self.channels) > 1 and not skip_sync:
@@ -275,8 +326,8 @@ class UHDApp(object):
command_time_set = True
except RuntimeError:
sys.stderr.write('[{prefix}] [WARNING] Failed to set command times.\n'.format(prefix=self.prefix))
- for chan in self.channels:
- self.tr = self.usrp.set_center_freq(treq, chan)
+ for i, chan in enumerate(self.channels ):
+ self.tr = self.usrp.set_center_freq(treq, i)
if self.tr == None:
sys.stderr.write('[{prefix}] [ERROR] Failed to set center frequency on channel {chan}\n'.format(
prefix=self.prefix, chan=chan
@@ -287,7 +338,7 @@ class UHDApp(object):
self.usrp.clear_command_time(mb_idx)
self.vprint("Syncing channels...".format(prefix=self.prefix))
time.sleep(COMMAND_DELAY)
- self.freq = self.usrp.get_center_freq(self.channels[0])
+ self.freq = self.usrp.get_center_freq(0)
self.vprint("First channel has freq: {freq} MHz.".format(freq=self.freq/1e6))
@staticmethod
@@ -333,6 +384,8 @@ class UHDApp(object):
if allow_mimo:
group.add_argument("-c", "--channels", default=[0,], type=cslist,
help="Select {xx} Channels".format(xx=tx_or_rx))
+ group.add_argument("--lo-export", help="Set TwinRX LO export {None, True, False} for each channel with a comma-separated list. None skips a channel.")
+ group.add_argument("--lo-source", help="Set TwinRX LO source {None, internal, companion, external} for each channel with a comma-separated list. None skips this channel. ")
group.add_argument("--otw-format", choices=['sc16', 'sc12', 'sc8'], default='sc16',
help="Choose over-the-wire data format")
group.add_argument("--stream-args", default="", help="Set additional stream arguments")
diff --git a/gr-uhd/apps/uhd_fft b/gr-uhd/apps/uhd_fft
index aa10cdf900..b65bb7a062 100755
--- a/gr-uhd/apps/uhd_fft
+++ b/gr-uhd/apps/uhd_fft
@@ -126,8 +126,8 @@ class uhd_fft(gr.top_block, Qt.QWidget, UHDApp):
# Blocks
##################################################
self.setup_usrp(uhd.usrp_source, args)
- self._ant_options = self.usrp.get_antennas(self.channels[0])
- for c in self.channels:
+ self._ant_options = self.usrp.get_antennas(0)
+ for c in range(len(self.channels)):
self.usrp.set_bandwidth(self.samp_rate, c)
self.usrp_device_info = self.get_usrp_info_string(compact=True, tx_or_rx='rx')
@@ -320,7 +320,7 @@ class uhd_fft(gr.top_block, Qt.QWidget, UHDApp):
self.top_grid_layout.addWidget(self._lo_locked_probe_tool_bar, 4,0,1,2)
def _current_freq_probe():
while True:
- val = self.usrp.get_center_freq(self.channels[0])
+ val = self.usrp.get_center_freq(0)
try:
if val != self.freq:
self.set_freq_qt(val, tune_source='freqsink_msg')
@@ -347,15 +347,15 @@ class uhd_fft(gr.top_block, Qt.QWidget, UHDApp):
##################################################
self.msg_connect((self.qtgui_freq_sink_x_0, 'freq'), (self.qtgui_freq_sink_x_0, 'freq'))
self.msg_connect((self.qtgui_freq_sink_x_0, 'freq'), (self.usrp, 'command'))
- for c, idx in enumerate(self.channels):
- self.connect((self.usrp, c), (self.qtgui_freq_sink_x_0, idx))
- self.connect((self.usrp, c), (self.qtgui_time_sink_x_0, idx))
- self.connect((self.usrp, c), (self.qtgui_waterfall_sink_x_0, idx))
+ for idx in range(len(self.channels)):
+ self.connect((self.usrp, idx), (self.qtgui_freq_sink_x_0, idx))
+ self.connect((self.usrp, idx), (self.qtgui_time_sink_x_0, idx))
+ self.connect((self.usrp, idx), (self.qtgui_waterfall_sink_x_0, idx))
if args.phase_relations and len(self.channels) > 1:
- for c, idx in enumerate(self.channels[:-1]):
+ for idx in range(len(self.channels[:-1])):
self.connect_phase_plot(
- (self.usrp, c),
- (self.usrp, self.channels[idx+1]),
+ (self.usrp, idx),
+ (self.usrp, idx+1),
(self.qtgui_phase_plot, idx)
)
@@ -430,7 +430,7 @@ class uhd_fft(gr.top_block, Qt.QWidget, UHDApp):
self.qtgui_time_sink_x_0.set_samp_rate(self.samp_rate)
self.qtgui_waterfall_sink_x_0.set_frequency_range(self.freq, self.samp_rate)
self.usrp.set_samp_rate(self.samp_rate)
- for c in self.channels:
+ for c in range(len(self.channels)):
self.usrp.set_bandwidth(self.samp_rate, c)
def set_lo_locked_probe(self, lo_locked_probe):
@@ -440,7 +440,7 @@ class uhd_fft(gr.top_block, Qt.QWidget, UHDApp):
def set_ant(self, ant):
self.antenna = ant
self._ant_callback(self.antenna)
- for c in self.channels:
+ for c in range(len(self.channels)):
self.usrp.set_antenna(self.antenna, c)
diff --git a/gr-uhd/doc/uhd.dox b/gr-uhd/doc/uhd.dox
index 27a1475566..a3de8e3a24 100644
--- a/gr-uhd/doc/uhd.dox
+++ b/gr-uhd/doc/uhd.dox
@@ -57,8 +57,8 @@ which automatically sets the PMT types. Assume we only want to set the frequency
(i.e. the second channel). In this case, we must construct a dictionary:
\code{.cpp}
pmt::pmt_t command = pmt::make_dict();
-pmt::dict_add(command, pmt::mp("freq"), pmt::mp(1.1e9)); // Specify frequency
-pmt::dict_add(command, pmt::mp("chan"), pmt::mp(1)); // Specify channel
+command = pmt::dict_add(command, pmt::mp("freq"), pmt::mp(1.1e9)); // Specify frequency
+command = pmt::dict_add(command, pmt::mp("chan"), pmt::mp(1)); // Specify channel
// Now pass 'command' into the USRP block's command port
\endcode
@@ -72,8 +72,8 @@ The main difference is that we can add more properties to the same
command PMT, e.g. as such:
\code{.cpp}
// 'command' is the same PMT as in the previous example
-pmt::dict_add(command, pmt::mp("gain"), pmt::mp(23.0)); // Specify gain
-pmt::dict_add(command, pmt::mp("antenna"), pmt::mp("TX/RX")); // Switch antenna
+command = pmt::dict_add(command, pmt::mp("gain"), pmt::mp(23.0)); // Specify gain
+command = pmt::dict_add(command, pmt::mp("antenna"), pmt::mp("TX/RX")); // Switch antenna
// Now pass 'command' into the USRP block's command port
\endcode
When the USRP block interprets this command PMT, all properties will be
diff --git a/gr-uhd/lib/usrp_sink_impl.cc b/gr-uhd/lib/usrp_sink_impl.cc
index 6288b80cc8..4e2e9467dd 100644
--- a/gr-uhd/lib/usrp_sink_impl.cc
+++ b/gr-uhd/lib/usrp_sink_impl.cc
@@ -141,12 +141,16 @@ namespace gr {
void usrp_sink_impl::set_normalized_gain(double norm_gain, size_t chan)
{
+#ifdef UHD_USRP_MULTI_USRP_NORMALIZED_GAIN
+ _dev->set_normalized_tx_gain(norm_gain, chan);
+#else
if (norm_gain > 1.0 || norm_gain < 0.0) {
throw std::runtime_error("Normalized gain out of range, must be in [0, 1].");
}
::uhd::gain_range_t gain_range = get_gain_range(chan);
double abs_gain = (norm_gain * (gain_range.stop() - gain_range.start())) + gain_range.start();
set_gain(abs_gain, chan);
+#endif
}
double
@@ -166,6 +170,9 @@ namespace gr {
double
usrp_sink_impl::get_normalized_gain(size_t chan)
{
+#ifdef UHD_USRP_MULTI_USRP_NORMALIZED_GAIN
+ return _dev->get_normalized_tx_gain(chan);
+#else
::uhd::gain_range_t gain_range = get_gain_range(chan);
double norm_gain =
(get_gain(chan) - gain_range.start()) /
@@ -174,6 +181,7 @@ namespace gr {
if (norm_gain > 1.0) return 1.0;
if (norm_gain < 0.0) return 0.0;
return norm_gain;
+#endif
}
std::vector<std::string>
@@ -329,9 +337,11 @@ namespace gr {
}
//send all ninput_items with metadata
+ boost::this_thread::disable_interruption disable_interrupt;
const size_t num_sent = _tx_stream->send(
input_items, ninput_items, _metadata, 1.0
);
+ boost::this_thread::restore_interruption restore_interrupt(disable_interrupt);
//if using length_tags, decrement items left to send by the number of samples sent
if(not pmt::is_null(_length_tag_key) && _nitems_to_send > 0) {
diff --git a/gr-uhd/lib/usrp_source_impl.cc b/gr-uhd/lib/usrp_source_impl.cc
index c840c43db1..8cdaebc4ca 100644
--- a/gr-uhd/lib/usrp_source_impl.cc
+++ b/gr-uhd/lib/usrp_source_impl.cc
@@ -154,12 +154,16 @@ namespace gr {
void usrp_source_impl::set_normalized_gain(double norm_gain, size_t chan)
{
+#ifdef UHD_USRP_MULTI_USRP_NORMALIZED_GAIN
+ _dev->set_normalized_rx_gain(norm_gain, chan);
+#else
if (norm_gain > 1.0 || norm_gain < 0.0) {
throw std::runtime_error("Normalized gain out of range, must be in [0, 1].");
}
::uhd::gain_range_t gain_range = get_gain_range(chan);
double abs_gain = (norm_gain * (gain_range.stop() - gain_range.start())) + gain_range.start();
set_gain(abs_gain, chan);
+#endif
}
double
@@ -179,6 +183,9 @@ namespace gr {
double
usrp_source_impl::get_normalized_gain(size_t chan)
{
+#ifdef UHD_USRP_MULTI_USRP_NORMALIZED_GAIN
+ return _dev->get_normalized_rx_gain(chan);
+#else
::uhd::gain_range_t gain_range = get_gain_range(chan);
double norm_gain =
(get_gain(chan) - gain_range.start()) /
@@ -187,6 +194,7 @@ namespace gr {
if (norm_gain > 1.0) return 1.0;
if (norm_gain < 0.0) return 0.0;
return norm_gain;
+#endif
}
std::vector<std::string>
@@ -553,6 +561,7 @@ namespace gr {
gr_vector_void_star &output_items)
{
boost::recursive_mutex::scoped_lock lock(d_mutex);
+ boost::this_thread::disable_interruption disable_interrupt;
//In order to allow for low-latency:
//We receive all available packets without timeout.
//This call can timeout under regular operation...
@@ -563,6 +572,7 @@ namespace gr {
_recv_timeout,
true /* one packet -> minimize latency */
);
+ boost::this_thread::restore_interruption restore_interrupt(disable_interrupt);
//handle possible errors conditions
switch(_metadata.error_code) {