commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 02/04: uhd: uhd_rx_cfile updates


From: git
Subject: [Commit-gnuradio] [gnuradio] 02/04: uhd: uhd_rx_cfile updates
Date: Sun, 13 Sep 2015 15:17:45 +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 7ab2c36ffb7631464fef77bd12a067bf51d32c7b
Author: Martin Braun <address@hidden>
Date:   Fri Jun 26 21:02:56 2015 -0700

    uhd: uhd_rx_cfile updates
    
    - Multi-channel receive operation
    - Better phase alignment where possible
    - E310 verbose output fix
    - Normalized gain
    - Minor bugfixes
---
 gr-uhd/apps/uhd_rx_cfile       | 263 +++++++++++++++++++++++------------------
 gr-uhd/lib/usrp_source_impl.cc |   4 +-
 2 files changed, 153 insertions(+), 114 deletions(-)

diff --git a/gr-uhd/apps/uhd_rx_cfile b/gr-uhd/apps/uhd_rx_cfile
old mode 100644
new mode 100755
index 442dd46..80bbc87
--- a/gr-uhd/apps/uhd_rx_cfile
+++ b/gr-uhd/apps/uhd_rx_cfile
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2012,2013 Free Software Foundation, Inc.
+# Copyright 2012,2013,2015 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -26,103 +26,143 @@ outputs single precision complex float values or complex 
short values
 (interleaved 16 bit signed short integers).
 """
 
+import sys
+import os
+import pmt
+import time
 from gnuradio import gr, gru, eng_notation
 from gnuradio import blocks
 from gnuradio import uhd
 from gnuradio.eng_option import eng_option
 from optparse import OptionParser
-import pmt
-import sys
 
 n2s = eng_notation.num_to_str
+COMMAND_DELAY = .2
 
 class rx_cfile_block(gr.top_block):
-
+    """
+    Simple flowgraph that streams from USRP source to file.
+    """
     def __init__(self, options, filename):
         gr.top_block.__init__(self)
-
-        # Create a UHD device source
-        if options.output_shorts:
-            self._u = uhd.usrp_source(device_addr=options.args, 
stream_args=uhd.stream_args('sc16',
-                                      options.wire_format, 
args=options.stream_args))
+        # Dissect the channel list:
+        try:
+            self.channels = [int(x.strip()) for x in 
options.channels.split(",")]
+        except ValueError:
+            sys.stderr.write("[UHD_RX] [ERROR] Invalid channel list: 
{}".format(options.channels))
+            exit(1)
+        # Create file names:
+        if len(self.channels) == 1:
+            self.filenames = [filename,]
         else:
-            self._u = uhd.usrp_source(device_addr=options.args, 
stream_args=uhd.stream_args('fc32',
-                                      options.wire_format, 
args=options.stream_args))
-
-        # Set the subdevice spec
-        if(options.spec):
-            self._u.set_subdev_spec(options.spec, 0)
-
-        # Set the antenna
-        if(options.antenna):
-            self._u.set_antenna(options.antenna, 0)
-
-        # Set receiver sample rate
+            base, ext = os.path.splitext(filename)
+            self.filenames = []
+            for i in range(len(self.channels)):
+                self.filenames.append("{base}.{num}{ext}".format(base=base, 
num=i, ext=ext))
+        # Check CPU format:
+        self.cpu_format = 'fc32'
+        self.item_size = gr.sizeof_gr_complex
+        self.meta_file_type = blocks.GR_FILE_FLOAT
+        if options.output_shorts:
+            self.cpu_format = 'sc16'
+            self.item_size = gr.sizeof_short * 2
+            self.meta_file_type = blocks.GR_FILE_SHORT
+        # Create a UHD device source:
+        self._u = uhd.usrp_source(
+            device_addr=options.args,
+            stream_args=uhd.stream_args(
+                self.cpu_format,
+                options.wire_format,
+                args=options.stream_args,
+                channels=self.channels,
+            )
+        )
+        # Set the subdevice spec:
+        if options.spec:
+            for mb_idx in xrange(self._u.get_num_mboards()):
+                self._u.set_subdev_spec(options.spec, mb_idx)
+        # Set the antenna:
+        self.antenna = [x.strip() for x in options.antenna.split(",")]
+        if len(self.antenna) != 1 and len(self.antenna) != len(self.channels):
+            sys.stderr.write("[UHD_RX] [ERROR] Invalid antenna setting for {} 
channels: {}".format(
+                len(self.channels), options.antenna
+            ))
+            exit(1)
+        if len(self.antenna) == 1 and len(self.channels) > 1:
+            self.antenna = [self.antenna[0],] * len(self.channels)
+        for i, chan in enumerate(self.channels):
+            self._u.set_antenna(self.antenna[i], chan)
+            if options.verbose:
+                print("[UHD_RX] Channel {chan}: Using antenna {ant}.".format(
+                    chan=chan, ant=self._u.get_antenna(chan)
+                ))
+        # Set receiver sample rate:
         self._u.set_samp_rate(options.samp_rate)
         samp_rate = self._u.get_samp_rate()
-
-        # Set receive daughterboard gain
+        # Set receive daughterboard gain:
         if options.gain is None:
-            g = self._u.get_gain_range()
-            options.gain = float(g.start()+g.stop())/2
-           print "Using mid-point gain of", options.gain, "(", g.start(), "-", 
g.stop(), ")"
-        self._u.set_gain(options.gain)
-        gain = self._u.get_gain()
-
-        # Set frequency (tune request takes lo_offset)
-        if(options.lo_offset is not None):
+            print("[UHD_RX] Defaulting to mid-point gains:")
+            for chan in self.channels:
+                self._u.set_normalized_gain(.5, chan)
+                print("[UHD_RX] Channel {chan} gain: {g} dB".format(chan=chan, 
g=self._u.get_gain(chan)))
+        else:
+            for chan in self.channels:
+                self._u.set_gain(options.gain, chan)
+        gain = self._u.get_gain(self.channels[0])
+        # Set frequency (tune request takes lo_offset):
+        if options.lo_offset is not None:
             treq = uhd.tune_request(options.freq, options.lo_offset)
         else:
             treq = uhd.tune_request(options.freq)
-        tr = self._u.set_center_freq(treq)
-        if tr == None:
-            sys.stderr.write('Failed to set center frequency\n')
-            raise SystemExit, 1
-        freq = self._u.get_center_freq()
-
-        # Create file sink
-        if options.metafile:
-            # store additional metadata
-            extras = pmt.make_dict()
-            extras = pmt.dict_add(extras, pmt.intern("rx_gain"), 
pmt.from_double(gain))
-            extras_str = pmt.serialize_str(extras)
-            if options.output_shorts:
-                self._sink = blocks.file_meta_sink(gr.sizeof_short * 2, 
filename,
-                                                   samp_rate, 1,
-                                                   blocks.GR_FILE_SHORT, True,
-                                                   1000000, extras_str, False)
-            else:
-                self._sink = blocks.file_meta_sink(gr.sizeof_gr_complex, 
filename,
-                                                   samp_rate, 1,
-                                                   blocks.GR_FILE_FLOAT, True,
-                                                   1000000, extras_str, False)
-        else:
-            if options.output_shorts:
-                self._sink = blocks.file_sink(gr.sizeof_short*2, filename)
+        # Make sure tuning is synched:
+        if len(self.channels) > 1:
+            if options.sync == 'pps':
+                self._u.set_time_unknown_pps(uhd.time_spec())
+            cmd_time = self._u.get_time_now() + uhd.time_spec(COMMAND_DELAY)
+            for mb_idx in xrange(self._u.get_num_mboards()):
+                self._u.set_command_time(cmd_time, mb_idx)
+        for chan in self.channels:
+            tr = self._u.set_center_freq(treq, chan)
+            if tr == None:
+                sys.stderr.write('[UHD_RX] [ERROR] Failed to set center 
frequency on channel {chan}\n'.format(chan=chan))
+                exit(1)
+        if len(self.channels) > 1:
+            for mb_idx in xrange(self._u.get_num_mboards()):
+                self._u.clear_command_time(mb_idx)
+            print("[UHD_RX] Syncing channels...")
+            time.sleep(COMMAND_DELAY)
+        freq = self._u.get_center_freq(self.channels[0])
+        # Create file sink(s):
+        self._sink = []
+        for i in range(len(self.channels)):
+            if options.metafile:
+                # store additional metadata
+                extras = pmt.make_dict()
+                extras = pmt.dict_add(extras, pmt.intern("rx_gain"), 
pmt.from_double(gain))
+                extras_str = pmt.serialize_str(extras)
+                self._sink.append(blocks.file_meta_sink(
+                        self.item_size, self.filenames[i],
+                        samp_rate, 1,
+                        self.meta_file_type, True,
+                        1000000, extras_str, False
+                ))
             else:
-                self._sink = blocks.file_sink(gr.sizeof_gr_complex, filename)
-
-        # Create head block if needed and wire it up
-        if options.nsamples is None:
-            self.connect(self._u, self._sink)
-        else:
-            if options.output_shorts:
-                self._head = blocks.head(gr.sizeof_short*2, 
int(options.nsamples))
+                self._sink.append(blocks.file_sink(self.item_size, 
self.filenames[i]))
+            # Create head block if needed and wire it up:
+            if options.nsamples is None:
+                self.connect((self._u, i), self._sink[i])
             else:
-                self._head = blocks.head(gr.sizeof_gr_complex, 
int(options.nsamples))
-
-            self.connect(self._u, self._head, self._sink)
-
+                self._head = blocks.head(self.item_size, int(options.nsamples))
+                self.connect((self._u, i), self._head, self._sink[i])
+        # Output status info if requested:
         if options.verbose:
             try:
                 info = self._u.get_usrp_info()
-
                 mboard_id = info["mboard_id"].split(" ")[0]
                 if info["mboard_serial"] == "":
                     mboard_serial = "no serial"
                 else:
                     mboard_serial = info["mboard_serial"]
-
                 rx_id = info["rx_id"].split(" ")[0]
                 if info["rx_serial"] == "":
                     rx_serial = "no serial"
@@ -130,30 +170,29 @@ class rx_cfile_block(gr.top_block):
                     rx_serial = info["rx_serial"]
                 rx_antenna = info["rx_antenna"]
                 rx_subdev_spec = info["rx_subdev_spec"]
-
-                print "Motherboard: %s (%s)" % (mboard_id, mboard_serial)
-                if "B200" in mboard_id or "B210" in mboard_id:
-                    print "Daughterboard: %s (%s, %s)" % (mboard_id, 
rx_antenna, rx_subdev_spec)
+                print "[UHD_RX] Motherboard: %s (%s)" % (mboard_id, 
mboard_serial)
+                if "B200" in mboard_id or "B210" in mboard_id or "E310" in 
mboard_id:
+                    print "[UHD_RX] Daughterboard: %s (%s, %s)" % (mboard_id, 
rx_antenna, rx_subdev_spec)
                 else:
-                    print "Daughterboard: %s (%s, %s, %s)" % (rx_id, 
rx_serial, rx_antenna, rx_subdev_spec)
-            except:
-                print "Args: ", options.args
-
-            print "Rx gain:", options.gain
-            print "Rx baseband frequency:", n2s(tr.actual_rf_freq)
-            print "Rx DDC frequency:", n2s(tr.actual_dsp_freq)
-            print "Rx Sample Rate:", n2s(samp_rate)
+                    print "[UHD_RX] Daughterboard: %s (%s, %s, %s)" % (rx_id, 
rx_serial, rx_antenna, rx_subdev_spec)
+            except KeyError:
+                print "[UHD_RX] Args: ", options.args
+            print("[UHD_RX] Receiving on {} 
channels.".format(len(self.channels)))
+            print("[UHD_RX] Rx gain:               {gain}".format(gain=gain))
+            print("[UHD_RX] Rx frequency:          {freq}".format(freq=freq))
+            print("[UHD_RX] Rx baseband frequency: 
{actual}".format(actual=n2s(tr.actual_rf_freq)))
+            print("[UHD_RX] Rx DDC frequency:      
{dsp}".format(dsp=n2s(tr.actual_dsp_freq)))
+            print("[UHD_RX] Rx Sample Rate:        
{rate}".format(rate=n2s(samp_rate)))
             if options.nsamples is None:
-                print "Receiving samples until Ctrl-C"
+                print("[UHD_RX] Receiving samples until Ctrl-C")
             else:
-                print "Receving", n2s(options.nsamples), "samples"
+                print("[UHD_RX] Receiving {n} 
samples.".format(n2s(options.nsamples)))
             if options.output_shorts:
-                print "Writing 16-bit complex shorts"
+                print("[UHD_RX] Writing 16-bit complex shorts")
             else:
-                print "Writing 32-bit complex floats"
-            print "Output filename:", filename
-
-        # Direct asynchronous notifications to callback function
+                print("[UHD_RX] Writing 32-bit complex floats")
+            print("[UHD_RX] Output file(s): {files}".format(files=", 
".join(self.filenames)))
+        # Direct asynchronous notifications to callback function:
         if options.show_async_msg:
             self.async_msgq = gr.msg_queue(0)
             self.async_src = uhd.amsg_source("", self.async_msgq)
@@ -161,8 +200,7 @@ class rx_cfile_block(gr.top_block):
 
     def async_callback(self, msg):
         md = self.async_src.msg_to_async_metadata_t(msg)
-        print "Channel: %i Time: %f Event: %i" % (md.channel, 
md.time_spec.get_real_secs(), md.event_code)
-
+        print("[UHD_RX] Channel: %i Time: %f Event: %i" % (md.channel, 
md.time_spec.get_real_secs(), md.event_code))
 
 def get_options():
     usage="%prog: [options] output_filename"
@@ -171,49 +209,50 @@ def get_options():
                       help="UHD device address args , [default=%default]")
     parser.add_option("", "--spec", type="string", default=None,
                       help="Subdevice of UHD device where appropriate")
+    parser.add_option("-c", "--channels", type="string", default="0",
+                      help="Select receive channels")
     parser.add_option("-A", "--antenna", type="string", default=None,
-                      help="select Rx Antenna where appropriate")
-    parser.add_option("", "--samp-rate", type="eng_float", default=1e6,
-                      help="set sample rate (bandwidth) [default=%default]")
+                      help="Select Rx Antenna(s) where appropriate.\nUse a 
comma-delimited list if different channels have different antenna ports.")
+    parser.add_option("-r", "--samp-rate", type="eng_float", default=1e6,
+                      help="Set sample rate (bandwidth) [default=%default]")
     parser.add_option("-f", "--freq", type="eng_float", default=None,
-                      help="set frequency to FREQ", metavar="FREQ")
+                      help="Set frequency to FREQ", metavar="FREQ")
+    parser.add_option("", "--lo-offset", type="eng_float", default=None,
+                      help="Set daughterboard LO offset to OFFSET [default=hw 
default]")
     parser.add_option("-g", "--gain", type="eng_float", default=None,
-                      help="set gain in dB (default is midpoint)")
+                      help="Set gain in dB (default is midpoint)")
+    parser.add_option("--normalized-gain", action="store_true",
+                      help="Specify gain as normalized value (in [0, 1])")
     parser.add_option( "-m","--metafile", action="store_true", default=False,
                       help="output metadata to file [default=%default]")
     parser.add_option( "-s","--output-shorts", action="store_true", 
default=False,
-                      help="output interleaved shorts instead of complex 
floats")
+                      help="Output interleaved shorts instead of complex 
floats")
     parser.add_option("-N", "--nsamples", type="eng_float", default=None,
-                      help="number of samples to collect [default=+inf]")
+                      help="Number of samples to collect [default=+inf]")
     parser.add_option("-v", "--verbose", action="store_true", default=False,
                       help="verbose output")
-    parser.add_option("", "--lo-offset", type="eng_float", default=None,
-                      help="set daughterboard LO offset to OFFSET [default=hw 
default]")
     parser.add_option("", "--wire-format", type="string", default="sc16",
-                      help="set wire format from USRP [default=%default")
+                      help="Set wire format from USRP [default=%default")
     parser.add_option("", "--stream-args", type="string", default="",
-                      help="set stream arguments [default=%default]")
+                      help="Set additional stream arguments")
     parser.add_option("", "--show-async-msg", action="store_true", 
default=False,
                       help="Show asynchronous message notifications from UHD 
[default=%default]")
-
-    (options, args) = parser.parse_args ()
+    parser.add_option("", "--sync", type="choice", choices=('default', 'pps'),
+                      default='default', help="Set to 'pps' to sync devices to 
PPS instead of internal.")
+    (options, args) = parser.parse_args()
     if len(args) != 1:
         parser.print_help()
-        raise SystemExit, 1
-
+        exit(1)
     if options.freq is None:
         parser.print_help()
-        sys.stderr.write('You must specify the frequency with -f FREQ\n');
-        raise SystemExit, 1
-
+        sys.stderr.write('You must specify the frequency with -f FREQ\n')
+        exit(1)
     return (options, args[0])
 
-
 if __name__ == '__main__':
     (options, filename) = get_options()
     tb = rx_cfile_block(options, filename)
-
     try:
         tb.run()
     except KeyboardInterrupt:
-        pass
+        print("Receive terminated.")
diff --git a/gr-uhd/lib/usrp_source_impl.cc b/gr-uhd/lib/usrp_source_impl.cc
index 6f0283e..0514840 100644
--- a/gr-uhd/lib/usrp_source_impl.cc
+++ b/gr-uhd/lib/usrp_source_impl.cc
@@ -545,8 +545,8 @@ namespace gr {
         return work(noutput_items, input_items, output_items);
 
       default:
-        std::cout << boost::format("UHD source block got error code 0x%x")
-          % _metadata.error_code << std::endl;
+        //GR_LOG_WARN(d_logger, boost::format("USRP Source Block caught rx 
error: %d") % _metadata.strerror());
+        GR_LOG_WARN(d_logger, boost::format("USRP Source Block caught rx error 
code: %d") % _metadata.error_code);
         return num_samps;
       }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]