Forum: GNU Radio transmitting from file stored by usrp_rx_cfile.py

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
4241213c7ece59019e316258a750e543?d=identicon&s=25 Jaze Dalton (Guest)
on 2009-04-02 22:00
(Received via mailing list)
I am trying to transmit from a file stored using usrp_rx_cfile.py (or
usrp_rx_cfile created using usrp_rx_cfile.cc/h).  I have been able to
successfully do this using a usrp_tx_cfile.cc/h program derived from the
rx
version.  I can't, however, get similar functionality using python.  I
am
new to python, so I am hoping I have just missed some key insight.  I
have
listed below the source for my cc and py versions of usrp_tx_cfile and
the
associated command line output from the transmit side.  I am running on
Mac
OS X with gnuradio code pulled down on Feb 13, 2009.  My daughterboards
are
RFX2400 and I am receiving on two other machines with the same USRP set
up,
but different hardware and OS (Linux).  I am using usrp_fft and
usrp_oscope
on the receiving side.  To test functionality, I stored data on the Mac
using usrp_rx_cfile while running "usrp_siggen -f 2500000000" on one of
the
other machines.

Also, I noticed that when I use the subdev->gain_min() and
subdev->gain_max() functions, both return 0 instead of correct values.

C++ code is shown below first, followed by the non-working python code.
Any
help is much appreciated!
-Jaze


So, when I compile and run this code, I see the waveform on the
receiver:

/*
 * usrp_tx_cfile.cc  - code based on usrp_rx_cfile.cc
 */

#include <usrp_tx_cfile.h>
#include <gr_io_signature.h>
#include <gr_head.h>
#include <stdexcept>
#include <iostream>
#include <boost/program_options.hpp>

namespace po = boost::program_options;

usrp_subdev_spec
str_to_subdev(std::string spec_str)
{
  usrp_subdev_spec spec;
  if(spec_str == "A" || spec_str == "A:0" || spec_str == "0:0") {
    spec.side = 0;
    spec.subdev = 0;
  }
  else if(spec_str == "A:1" || spec_str == "0:1") {
    spec.side = 0;
    spec.subdev = 1;
  }
  else if(spec_str == "B" || spec_str == "B:0" || spec_str == "1:0") {
    spec.side = 1;
    spec.subdev = 0;
  }
  else if(spec_str == "B:1" || spec_str == "1:1") {
    spec.side = 1;
    spec.subdev = 1;
  }
  else {
    throw std::range_error("Incorrect subdevice specifications.\n");
  }

  return spec;
}


// Shared pointer constructor
usrp_tx_cfile_sptr make_usrp_tx_cfile(int which, usrp_subdev_spec spec,
                      int interp, double freq, float gain,
                      bool width8, bool nohb,
                      bool output_shorts, int nsamples,
                      const std::string &filename)
{
  return gnuradio::get_initial_sptr(new usrp_tx_cfile(which, spec,
                              interp, freq, gain,
                              width8, nohb,
                              output_shorts,
                              nsamples,
                              filename));
}

// Hierarchical block constructor, with no inputs or outputs
usrp_tx_cfile::usrp_tx_cfile(int which, usrp_subdev_spec spec,
                 int interp, double freq, float gain,
                 bool width8, bool nohb,
                 bool output_shorts, int nsamples,
                 const std::string &filename) :
  gr_top_block("usrp_tx_cfile"),
  d_which(which),  d_spec(spec), d_interp(interp), d_freq(freq),
  d_gain(gain), d_width8(width8), d_nohb(nohb), d_nsamples(nsamples),
  d_filename(filename)
{
  usrp_sink_c_sptr usrp = usrp_make_sink_c(d_which, d_interp);

  // standard fpga firmware "std_2rxhb_2tx.rbf" contains
  // 2 Rx paths with halfband filters and 2 tx paths
  //(the default) min decimation 8
  //usrp = usrp_make_source_c(d_which, d_decim);

  /* Get subdevice and process it */
  db_base_sptr subdev = usrp->selected_subdev(d_spec);
  printf("\nSubdevice name is %s\n", subdev->side_and_name().c_str());
  printf("Subdevice freq range: (%g, %g)\n",
     subdev->freq_min(), subdev->freq_max());

  unsigned int mux = usrp->determine_tx_mux_value(d_spec);
  printf("mux: %#08x\n",  mux);
  usrp->set_mux(mux);

  float gain_min = subdev->gain_min();
  float gain_max = subdev->gain_max();
  printf ("gain min is %g.  gain max is %g.\n", gain_min, gain_max);
  if(d_gain == -1) {
    //d_gain = (gain_min + gain_max)/2.0;
    printf("No gain specified.  Setting to max gain.\n");
    d_gain = gain_max;
    d_gain = 90;
  }
  printf("gain: %g\n", d_gain);
  subdev->set_gain(d_gain);

  float input_rate = usrp->dac_freq() / usrp->interp_rate();
  printf("baseband rate: %g\n",  input_rate);

  /* Set the USRP/dboard frequency */
  usrp_tune_result r;
  //bool ok = usrp->tune(0, subdev, freq, &r); //DDC 0
  bool ok = usrp->tune(subdev->which(), subdev, d_freq, &r);

  if(!ok) {
    throw std::runtime_error("Could not set frequency.");
  }

  subdev->set_enable(true);

  /* The rest */
  d_src = gr_make_file_source(sizeof(gr_complex), d_filename.c_str());



  //if(d_nsamples == -1) {
  connect(d_src, 0, usrp, 0);
  //}
  //else {
  //  d_head = gr_make_head(sizeof(gr_complex), d_nsamples*2);
  //  connect(usrp, 0, d_head, 0);
  //  connect(d_head, 0, d_dst, 0);
  //}
}


int main(int argc, char *argv[])
{
  int which = 0;                       // specify which USRP board
  usrp_subdev_spec spec(0,0);          // specify the d'board side
  int interp = 128;                      // set the decimation rate
  double freq = 0;                     // set the frequency
  float gain = -1;                     // set the gain; -1 will set the
mid-point gain
  int nsamples = -1;                   // set the number of samples to
collect; -1 will continue
  bool width8 = false;                 // use 8-bit samples across USB
  bool nohb = false;                   // don't use halfband filter in
USRP
  bool output_shorts = false;          // use shorts
  std::string filename = "received.dat";

  po::options_description cmdconfig("Program options: usrp_tx_cfile
[options] filename");
  cmdconfig.add_options()
    ("help,h", "produce help message")
    ("which,W", po::value<int>(&which), "select which USRP board")
    ("rx-subdev-spec,R", po::value<std::string>(), "select USRP Rx side
A or
B (default=A)")
    ("interp,i", po::value<int>(&interp), "set fgpa interpolation rate
to
INTERP")
    ("freq,f", po::value<double>(), "set frequency to FREQ")
    ("gain,g", po::value<float>(), "set gain in dB (default is
midpoint)")
    ("width-8,8", "Enable 8-bit samples across USB")
    ("no-hb", "don't use halfband filter in usrp")
    //("output-shorts,s", "output interleaved shorts in stead of complex
floats")
    //("nsamples,N", po::value<int>(&nsamples), "number of samples to
collect")
    ;

  po::options_description fileconfig("Input file options");
  fileconfig.add_options()
    ("filename", po::value<std::string>(), "input file")
    ;

  po::positional_options_description inputfile;
  inputfile.add("filename", -1);

  po::options_description config;
  config.add(cmdconfig).add(fileconfig);

  po::variables_map vm;
  po::store(po::command_line_parser(argc, argv).
        options(config).positional(inputfile).run(), vm);
  po::notify(vm);

  if (vm.count("help")) {
    std::cout << cmdconfig << "\n";
    return 1;
  }

  if(vm.count("filename")) {
    filename = vm["filename"].as<std::string>();
  }

  if(vm.count("freq")) {
    freq = vm["freq"].as<double>();
  }
  else {
    fprintf(stderr, "You must specify a frequency.\n");
    return -1;
  }

  if(vm.count("rx-subdev-spec")) {
    std::string s = vm["rx-subdev-spec"].as<std::string>();
    spec = str_to_subdev(s);
  }

  if(vm.count("width-8")) {
    width8 = true;
  }
  if(vm.count("nohb")) {
    nohb = true;
  }
 // if(vm.count("output-shorts")) {
 //   output_shorts = true;
 // }

  std::cout << "which:   " << which << std::endl;
  std::cout << "interp:   " << interp << std::endl;
  std::cout << "freq:    " << freq << std::endl;
  std::cout << "gain:    " << gain << std::endl;
  std::cout << "width-8  " << (width8 ? "Yes" : "No") << std::endl;
  std::cout << "no-hb    " << (nohb ? "Yes" : "no") << std::endl;
//  std::cout << "shorts:  " << (output_shorts ? "Yes" : "No") <<
std::endl;
//  std::cout << "samples: " << nsamples << std::endl;

  usrp_tx_cfile_sptr top_block = make_usrp_tx_cfile(which, spec, interp,
freq,
                            gain, width8, nohb,
                            output_shorts, nsamples,
                            filename);
  top_block->run();

  return 0;
}

----------
Here's the command line output:

$ ~/gnuradio/gr-usrp/apps/usrp_tx_cfile -f 2500000000 in.dat
which:   0
interp:   128
freq:    2.5e+09
gain:    -1
width-8  No
no-hb    no

Subdevice name is A: Flex 2400 Tx MIMO B
Subdevice freq range: (2.3e+09, 2.7e+09)
mux: 0x000098
gain min is 0.  gain max is 0.
No gain specified.  Setting to max gain.
gain: 90
baseband rate: 1e+06
$

Here is the python version, which doesn't seem to transmit anything:

#!/usr/bin/env python

"""
Read samples a file and transmit using USRP

"""

from gnuradio import gr, eng_notation
from gnuradio import audio
from gnuradio import usrp
from gnuradio.eng_option import eng_option
from optparse import OptionParser
import sys

class my_top_block(gr.top_block):

    def __init__(self):
        gr.top_block.__init__(self)

        usage="%prog: [options] output_filename"
        parser = OptionParser(option_class=eng_option, usage=usage)
        parser.add_option("-R", "--tx-subdev-spec", type="subdev",
default=(0, 0),
                          help="select USRP tx side A or B (default=A)")
        parser.add_option("-i", "--interp", type="int", default=128,
                          help="set fgpa decimation rate to INTERP
[default=%default]")
        parser.add_option("-f", "--freq", type="eng_float",
default=None,
                          help="set frequency to FREQ", metavar="FREQ")
        parser.add_option("-g", "--gain", type="eng_float",
default=None,
                          help="set gain in dB (default is midpoint)")
        (options, args) = parser.parse_args ()
        if len(args) != 1:
            parser.print_help()
            raise SystemExit, 1
        filename = args[0]

        if options.freq is None:
            parser.print_help()
            sys.stderr.write('You must specify the frequency with -f
FREQ\n');
            raise SystemExit, 1

        # build the graph
        self.u = usrp.sink_c(interp_rate=options.interp)
        self.src = gr.file_source(gr.sizeof_gr_complex, filename)
        self.connect(self.src, self.u)

        if options.tx_subdev_spec is None:
            options.tx_subdev_spec = usrp.pick_tx_subdevice(self.u)
        self.u.set_mux(usrp.determine_tx_mux_value(self.u,
options.tx_subdev_spec))

        # determine the daughterboard subdevice we're using
        self.subdev = usrp.selected_subdev(self.u,
options.tx_subdev_spec)
        print "Using TX d'board %s" % (self.subdev.side_and_name(),)
        output_rate = self.u.dac_freq() / self.u.interp_rate()
        print "USB sample rate %s" %
(eng_notation.num_to_str(output_rate))

        if options.gain is None:
            # if no gain was specified, use the mid-point in dB
            g = self.subdev.gain_range()
            options.gain = float(g[0]+g[1])/2

        print "Gain: %s" % (eng_notation.num_to_str(options.gain))

        self.subdev.set_gain(options.gain)

        r = self.u.tune(0, self.subdev, options.freq)
        if not r:
            sys.stderr.write('Failed to set frequency\n')
            raise SystemExit, 1


if __name__ == '__main__':
    try:
        my_top_block().run()
    except KeyboardInterrupt:
        pass


Output on command line:
$ ./usrp_tx_cfile.py -f 2500000000 -i 128 -g 90 in.dat
Using TX d'board A: Flex 2400 Tx MIMO B
USB sample rate 1M
interp: 128
gain: 90
freq: 2.5G
No bandwidth specified.
745d8202ef5a58c1058d0e5395a78f9c?d=identicon&s=25 Eric Blossom (Guest)
on 2009-04-02 22:19
(Received via mailing list)
On Thu, Apr 02, 2009 at 03:59:22PM -0400, Jaze Dalton wrote:
> on the receiving side.  To test functionality, I stored data on the Mac
> using usrp_rx_cfile while running "usrp_siggen -f 2500000000" on one of the
> other machines.
>
> Also, I noticed that when I use the subdev->gain_min() and
> subdev->gain_max() functions, both return 0 instead of correct values.

Those are the right values.  min == max -> not adjustable


> Read samples a file and transmit using USRP
> class my_top_block(gr.top_block):
>                           help="set fgpa decimation rate to INTERP
>
>         if options.freq is None:
>             parser.print_help()
>             sys.stderr.write('You must specify the frequency with -f
> FREQ\n');
>             raise SystemExit, 1
>
>         # build the graph
>         self.u = usrp.sink_c(interp_rate=options.interp)

Try:

>         self.u = usrp.sink_c(0, interp_rate=options.interp)

Eric
4241213c7ece59019e316258a750e543?d=identicon&s=25 Jaze Dalton (Guest)
on 2009-04-03 14:20
(Received via mailing list)
>
>
> >
> > Also, I noticed that when I use the subdev->gain_min() and
> > subdev->gain_max() functions, both return 0 instead of correct values.
>
> Those are the right values.  min == max -> not adjustable
>

I see.  Thanks.  So  that means "self.subdev.set_gain(options.gain)" has
no
effect, right?

Mike - is this why in your usrp_replay_cfile.py file you use self.amp?

Try:
>
> >         self.u = usrp.sink_c(0, interp_rate=options.interp)
>
>
This change didn't actually make a difference, but
self.subdev.set_enable(True) that Mike suggested did the trick.  And in
fact, it's right there in my cc file.  Laughing at me for missing it.

Thanks a lot Eric and Mike!
745d8202ef5a58c1058d0e5395a78f9c?d=identicon&s=25 Eric Blossom (Guest)
on 2009-04-03 17:53
(Received via mailing list)
On Fri, Apr 03, 2009 at 08:18:32AM -0400, Jaze Dalton wrote:
> effect, right?
On that particular daughterboard.

Eric
This topic is locked and can not be replied to.