October 18, 2010

advance info. about usrp trans.

new examples for the 802.11b trans. (here)

======================

btw, there is an excellent discussion about how to run the code.

(1)
 
Hi

I am trying to establish communication between USRP2 and USRP1. I am using RFX2400 daughterboard. I am using Ubuntu 8.10. I am using the svn version of GNU Radio. I dont know the revision number. I am not able to receive anything on USRP2 when USRP1 is transmitting and vice versa. The python codes for USRP2 work perfectly fine. I guess there is some problem with the ADC and DAC incompatibility (interpolation and decimation) between USRP2 and USRP1. I am attaching all the necessary files that I am using currently. I would appreciate if someone can look at these files and help me to sort out the problem.  

benchmark_tx.py

#!/usr/bin/env python
#
# Copyright 2005, 2006, 2007 Free Software Foundation, Inc.
# 
# This file is part of GNU Radio
# 
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# 
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
# 

from gnuradio import gr, gru, modulation_utils
from gnuradio import usrp2
from gnuradio import eng_notation
from gnuradio.eng_option import eng_option
from optparse import OptionParser

import random
import time
import struct
import sys

# from current dir
from transmit_path_usrp2 import transmit_path
import fusb_options

#import os 
#print os.getpid()
#raw_input('Attach and press enter')

class my_top_block(gr.top_block):
    def __init__(self, modulator, options):
        gr.top_block.__init__(self)
        self.txpath = transmit_path(modulator, options)
        self.connect(self.txpath)

#
/////////////////////////////////////////////////////////////////////////////
#                                   main
#
/////////////////////////////////////////////////////////////////////////////

def main():

    def send_pkt(payload='', eof=False):
        return tb.txpath.send_pkt(payload, eof)

    def rx_callback(ok, payload):
        print "ok = %r, payload = '%s'" % (ok, payload)

    mods = modulation_utils.type_1_mods()

    parser = OptionParser(option_class=eng_option,
conflict_handler="resolve")
    expert_grp = parser.add_option_group("Expert")

    parser.add_option("-m", "--modulation", type="choice",
choices=mods.keys(),
                      default='gmsk',
                      help="Select modulation from: %s [default=%%default]"
                            % (', '.join(mods.keys()),))

    parser.add_option("-s", "--size", type="eng_float", default=1500,
                      help="set packet size [default=%default]")
    parser.add_option("-M", "--megabytes", type="eng_float", default=1.0,
                      help="set megabytes to transmit [default=%default]")
    parser.add_option("","--discontinuous", action="store_true",
default=False,
                      help="enable discontinous transmission (bursts of 5
packets)")
    parser.add_option("","--from-file", default=None,
                      help="use file for packet contents")

    transmit_path.add_options(parser, expert_grp)

    for mod in mods.values():
        mod.add_options(expert_grp)

    fusb_options.add_options(expert_grp)
    (options, args) = parser.parse_args ()

    if len(args) != 0:
        parser.print_help()
        sys.exit(1)

    if options.tx_freq is None:
        sys.stderr.write("You must specify -f FREQ or --freq FREQ\n")
        parser.print_help(sys.stderr)
        sys.exit(1)

    if options.from_file is not None:
        source_file = open(options.from_file, 'r')

    # build the graph
    tb = my_top_block(mods[options.modulation], options)

    r = gr.enable_realtime_scheduling()
    if r != gr.RT_OK:
        print "Warning: failed to enable realtime scheduling"

    tb.start()                       # start flow graph
        
    # generate and send packets
    nbytes = int(1e6 * options.megabytes)
    n = 0
    pktno = 0
    pkt_size = int(options.size)

    while n < nbytes:
        if options.from_file is None:
            data = (pkt_size - 2) * chr(pktno & 0xff) 
        else:
            data = source_file.read(pkt_size - 2)
            if data == '':
                break;

        payload = struct.pack('!H', pktno & 0xffff) + data
        send_pkt(payload)
        n += len(payload)
        sys.stderr.write('.')
        if options.discontinuous and pktno % 5 == 4:
            time.sleep(1)
        pktno += 1
        
    send_pkt(eof=True)

    tb.wait()                       # wait for it to finish

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        pass


transmit_path_usrp2.py

#
# Copyright 2005,2006,2007 Free Software Foundation, Inc.
# 
# This file is part of GNU Radio
# 
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# 
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
# 

from gnuradio import gr, gru, blks2
from gnuradio import usrp2
from gnuradio import eng_notation

import copy
import sys

# from current dir
from pick_bitrate import pick_tx_bitrate

#
/////////////////////////////////////////////////////////////////////////////
#                              transmit path
#
/////////////////////////////////////////////////////////////////////////////

class transmit_path(gr.hier_block2): 
    def __init__(self, modulator_class, options):
        '''
        See below for what options should hold
        '''
        gr.hier_block2.__init__(self, "transmit_path",
                                gr.io_signature(0, 0, 0), # Input signature
                                gr.io_signature(0, 0, 0)) # Output signature

        options = copy.copy(options)    # make a copy so we can
destructively modify

        self._interface          = options.interface           # the USRP
board attached
        self._mac_addr           = options.mac_addr
        self._verbose            = options.verbose
        self._tx_freq            = options.tx_freq         # tranmitter's
center frequency
        self._tx_amplitude       = options.tx_amplitude    # digital
amplitude sent to USRP
        #self._tx_subdev_spec     = options.tx_subdev_spec  # daughterboard
to use
        self._bitrate            = options.bitrate         # desired bit
rate
        self._interp             = options.interp          # interpolating rate 
for
the USRP (prelim) 
        self._samples_per_symbol = options.samples_per_symbol  # desired
samples/baud 
        #self._fusb_block_size    = options.fusb_block_size # usb info for USRP
        #self._fusb_nblocks       = options.fusb_nblocks    # usb info for
USRP
        self._use_whitener_offset = options.use_whitener_offset # increment
start of whitener XOR data
        
        self._modulator_class = modulator_class         # the
modulator_class we are using
    
        if self._tx_freq is None:
            sys.stderr.write("-f FREQ or --freq FREQ or --tx-freq FREQ must
be specified\n")
            raise SystemExit

        # Set up USRP sink; also adjusts interp, samples_per_symbol, and
bitrate
        self._setup_usrp_sink()  

        # copy the final answers back into options for use by modulator
        options.samples_per_symbol = self._samples_per_symbol
        options.bitrate = self._bitrate
        options.interp = self._interp

        # Get mod_kwargs
        mod_kwargs =
self._modulator_class.extract_kwargs_from_options(options)

        # Set center frequency of USRP
        ok = self.set_freq(self._tx_freq)
        if not ok:
            print "Failed to set Tx frequency to %s" %
(eng_notation.num_to_str(self._tx_freq),)
            raise ValueError
    
        # transmitter
        self.packet_transmitter = \
            blks2.mod_pkts(self._modulator_class(**mod_kwargs),
                           access_code=None,
                           msgq_limit=4,
                           pad_for_usrp=True,
                           use_whitener_offset=options.use_whitener_offset)


        # Set the USRP for maximum transmit gain
        # (Note that on the RFX cards this is a nop.)
        self.set_gain(self.u.gain_range()[1])

        self.amp = gr.multiply_const_cc(1)
        self.set_tx_amplitude(self._tx_amplitude)

        # enable Auto Transmit/Receive switching
        #fiske_removed self.set_auto_tr(True)

        # Display some information about the setup
        if self._verbose:
            self._print_verbage()

        # Create and setup transmit path flow graph
        self.connect(self.packet_transmitter, self.amp, self.u)

    def _setup_usrp_sink(self):
        """
        Creates a USRP sink, determines the settings for best bitrate,
        and attaches to the transmitter's subdevice.
        """
        #self.u = usrp2.source_32fc(options.interface, options.mac_addr)
        #self.u = usrp2.sink_32fc (options._interface, options._mac_addr)
        self.u = usrp2.sink_32fc("eth0","00:50:C2:85:31:5A")  #fiske hard coded 
        dac_rate = self.u.dac_rate();

        # derive values of bitrate, samples_per_symbol, and interp from
desired info
        (self._bitrate, self._samples_per_symbol, self._interp) = \
            pick_tx_bitrate(self._bitrate,
self._modulator_class.bits_per_symbol(),
                            self._samples_per_symbol, self._interp,
dac_rate)
        
        #fiske_removed self.u.set_interp_rate(self._interp)

        # determine the daughterboard subdevice we're using
        #if self._tx_subdev_spec is None:
        #    self._tx_subdev_spec = usrp.pick_tx_subdevice(self.u)
        #self.u.set_mux(usrp.determine_tx_mux_value(self.u,
self._tx_subdev_spec))
        #self.subdev = usrp.selected_subdev(self.u, self._tx_subdev_spec)


    def set_freq(self, target_freq):
        """
        Set the center frequency we're interested in.

        @param target_freq: frequency in Hz
        @rypte: bool

        Tuning is a two step process.  First we ask the front-end to
        tune as close to the desired frequency as it can.  Then we use
        the result of that operation and our target_frequency to
        determine the value for the digital up converter.
        """
        r = self.u.set_center_freq(target_freq)
        if r:
            return True

        return False
        
    def set_gain(self, gain):
        """
        Sets the analog gain in the USRP
        """
        self.gain = gain
        self.u.set_gain(gain)

    def set_tx_amplitude(self, ampl):
        """
        Sets the transmit amplitude sent to the USRP
        @param: ampl 0 <= ampl < 32768.  Try 8000
        """
        self._tx_amplitude = max(0.0, min(ampl, 32767.0))
        self.amp.set_k(self._tx_amplitude)
        
    def set_auto_tr(self, enable):
        """
        Turns on auto transmit/receive of USRP daughterboard (if exits; else
ignored)
        """
        return self.u.set_auto_tr(enable)
        
    def send_pkt(self, payload='', eof=False):
        """
        Calls the transmitter method to send a packet
        """
        return self.packet_transmitter.send_pkt(payload, eof)
        
    def bitrate(self):
        return self._bitrate

    def samples_per_symbol(self):
        return self._samples_per_symbol

    def interp(self):
        return self._interp

    def add_options(normal, expert):
        """
        Adds transmitter-specific options to the Options Parser
        """
        add_freq_option(normal)
        if not normal.has_option('--bitrate'):
            normal.add_option("-r", "--bitrate", type="eng_float",
default=None,
                              help="specify bitrate.  samples-per-symbol and
interp/decim will be derived.")
        normal.add_option("-e", "--interface", type="string",
default="eth0",
                          help="select Ethernet interface, default is eth0")
        normal.add_option("-m", "--mac-addr", type="string", default="",
                          help="select USRP by MAC address, default is
auto-select")
        #normal.add_option("-T", "--tx-subdev-spec", type="subdev",
default=None,
        #                  help="select USRP Tx side A or B")
        normal.add_option("", "--tx-amplitude", type="eng_float",
default=12000, metavar="AMPL",
                          help="set transmitter digital amplitude: 0 <= AMPL
< 32768 [default=%default]")
        normal.add_option("-v", "--verbose", action="store_true",
default=False)

        expert.add_option("-S", "--samples-per-symbol", type="int",
default=None,
                          help="set samples/symbol [default=%default]")
        expert.add_option("", "--tx-freq", type="eng_float", default=None,
                          help="set transmit frequency to FREQ
[default=%default]", metavar="FREQ")
        expert.add_option("-i", "--interp", type="intx", default=None,
                          help="set fpga interpolation rate to INTERP
[default=%default]")
        expert.add_option("", "--log", action="store_true", default=False,
                          help="Log all parts of flow graph to file
(CAUTION: lots of data)")
        expert.add_option("","--use-whitener-offset", action="store_true",
default=False,
                          help="make sequential packets use different
whitening")

    # Make a static method to call before instantiation
    add_options = staticmethod(add_options)

    def _print_verbage(self):
        """
        Prints information about the transmit path
        """
        print "Using TX d'board %s"    % (self.u.daughterboard_id(),)
        print "Tx amplitude     %s"    % (self._tx_amplitude)
        print "modulation:      %s"    % (self._modulator_class.__name__)
        print "bitrate:         %sb/s" %
(eng_notation.num_to_str(self._bitrate))
        print "samples/symbol:  %3d"   % (self._samples_per_symbol)
        print "interp:          %3d"   % (self._interp)
        print "Tx Frequency:    %s"    %
(eng_notation.num_to_str(self._tx_freq))
        

def add_freq_option(parser):
    """
    Hackery that has the -f / --freq option set both tx_freq and rx_freq
    """
    def freq_callback(option, opt_str, value, parser):
        parser.values.rx_freq = value
        parser.values.tx_freq = value

    if not parser.has_option('--freq'):
        parser.add_option('-f', '--freq', type="eng_float",
                          action="callback", callback=freq_callback,
                          help="set Tx and/or Rx frequency to FREQ
[default=%default]",
                          metavar="FREQ")

benchmark_rx.py

#!/usr/bin/env python
#
# Copyright 2005,2006,2007 Free Software Foundation, Inc.
# 
# This file is part of GNU Radio
# 
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# 
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
# 

from gnuradio import gr, gru, modulation_utils
from gnuradio import usrp2
from gnuradio import eng_notation
from gnuradio.eng_option import eng_option
from optparse import OptionParser

import random
import struct
import sys

# from current dir
from receive_path_usrp2 import receive_path
import fusb_options

#import os
#print os.getpid()
#raw_input('Attach and press enter: ')

class my_top_block(gr.top_block):
    def __init__(self, demodulator, rx_callback, options):
        gr.top_block.__init__(self)
        self.rxpath = receive_path(demodulator, rx_callback, options) 
        self.connect(self.rxpath)

#
/////////////////////////////////////////////////////////////////////////////
#                                   main
#
/////////////////////////////////////////////////////////////////////////////

global n_rcvd, n_right

def main():
    global n_rcvd, n_right

    n_rcvd = 0
    n_right = 0
    
    def rx_callback(ok, payload):
        global n_rcvd, n_right
        (pktno,) = struct.unpack('!H', payload[0:2])
        n_rcvd += 1
        if ok:
            n_right += 1

        print "ok = %5s  pktno = %4d  n_rcvd = %4d  n_right = %4d" % (
            ok, pktno, n_rcvd, n_right)


    demods = modulation_utils.type_1_demods()

    # Create Options Parser:
    parser = OptionParser (option_class=eng_option,
conflict_handler="resolve")
    expert_grp = parser.add_option_group("Expert")

    parser.add_option("-m", "--modulation", type="choice",
choices=demods.keys(), 
                      default='gmsk',
                      help="Select modulation from: %s [default=%%default]"
                            % (', '.join(demods.keys()),))

    receive_path.add_options(parser, expert_grp)

    for mod in demods.values():
        mod.add_options(expert_grp)

    fusb_options.add_options(expert_grp)
    (options, args) = parser.parse_args ()

    if len(args) != 0:
        parser.print_help(sys.stderr)
        sys.exit(1)

    if options.rx_freq is None:
        sys.stderr.write("You must specify -f FREQ or --freq FREQ\n")
        parser.print_help(sys.stderr)
        sys.exit(1)


    # build the graph
    tb = my_top_block(demods[options.modulation], rx_callback, options)

    r = gr.enable_realtime_scheduling()
    if r != gr.RT_OK:
        print "Warning: Failed to enable realtime scheduling."

    tb.start()        # start flow graph
    tb.wait()         # wait for it to finish

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        pass

receive_path_usrp2.py

#!/usr/bin/env python
#
# Copyright 2005,2006,2007 Free Software Foundation, Inc.
# 
# This file is part of GNU Radio
# 
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# 
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
# 

from gnuradio import gr, gru, blks2
from gnuradio import usrp2
from gnuradio import eng_notation
import copy
import sys

# from current dir
from pick_bitrate import pick_rx_bitrate

#
/////////////////////////////////////////////////////////////////////////////
#                              receive path
#
/////////////////////////////////////////////////////////////////////////////

class receive_path(gr.hier_block2):
    def __init__(self, demod_class, rx_callback, options):

        gr.hier_block2.__init__(self, "receive_path",
                                gr.io_signature(0, 0, 0), # Input signature
                                gr.io_signature(0, 0, 0)) # Output signature

        options = copy.copy(options)    # make a copy so we can
destructively modify

        self._interface          = options.interface           # the USRP
board attached
        self._mac_addr           = options.mac_addr
        self._verbose            = options.verbose
        self._rx_freq            = options.rx_freq         # receiver's
center frequency
        self._rx_gain            = options.rx_gain         # receiver's gain
        #self._rx_subdev_spec     = options.rx_subdev_spec  # daughterboard
to use
        self._bitrate            = options.bitrate         # desired bit
rate 
        self._decim              = options.decim           # Decimating rate
for the USRP (prelim) 
        self._samples_per_symbol = options.samples_per_symbol  # desired
samples/symbol
        self._fusb_block_size    = options.fusb_block_size # usb info for USRP
        self._fusb_nblocks       = options.fusb_nblocks    # usb info for
USRP

        self._rx_callback   = rx_callback      # this callback is fired when
there's a packet available
        self._demod_class   = demod_class      # the demodulator_class we're
using

        if self._rx_freq is None:
            sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must
be specified\n")
            raise SystemExit

        # Set up USRP source; also adjusts decim, samples_per_symbol, and
bitrate
        self._setup_usrp_source()

        g = self.u.gain_range()
        if options.show_rx_gain_range:
            print "Rx Gain Range: minimum = %g, maximum = %g, step size =
%g" \
                  % (g[0], g[1], g[2])

        self.set_gain(options.rx_gain)

        self.set_auto_tr(True)                 # enable Auto
Transmit/Receive switching

        # Set RF frequency
        ok = self.set_freq(self._rx_freq)
        if not ok:
            print "Failed to set Rx frequency to %s" %
(eng_notation.num_to_str(self._rx_freq))
            raise ValueError, eng_notation.num_to_str(self._rx_freq)

        # copy the final answers back into options for use by demodulator
        options.samples_per_symbol = self._samples_per_symbol
        options.bitrate = self._bitrate
        options.decim = self._decim

        # Get demod_kwargs
        demod_kwargs =
self._demod_class.extract_kwargs_from_options(options)
        # Fix USRP2 -> USRP1 scaling
        self.scale = gr.multiply_const_cc(32768)
        # Design filter to get actual channel we want
        sw_decim = 1
        chan_coeffs = gr.firdes.low_pass (1.0,                  # gain
                                          sw_decim *
self._samples_per_symbol, # sampling rate
                                          1.0,                  # midpoint
of trans. band
                                          0.5,                  # width of
trans. band
                                          gr.firdes.WIN_HANN)   # filter
type 

        # Decimating channel filter
        # complex in and out, float taps
        self.chan_filt = gr.fft_filter_ccc(sw_decim, chan_coeffs)
        #self.chan_filt = gr.fir_filter_ccf(sw_decim, chan_coeffs)

        # receiver
        self.packet_receiver = \
            blks2.demod_pkts(self._demod_class(**demod_kwargs),
                             access_code=None,
                             callback=self._rx_callback,
                             threshold=-1)
    
        # Carrier Sensing Blocks
        alpha = 0.001
        thresh = 30   # in dB, will have to adjust

        if options.log_rx_power == True:
            self.probe = gr.probe_avg_mag_sqrd_cf(thresh,alpha)
            self.power_sink = gr.file_sink(gr.sizeof_float, "rxpower.dat")
            self.connect(self.chan_filt, self.probe, self.power_sink)
        else:
            self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha)
            self.connect(self.chan_filt, self.probe)

        # Display some information about the setup
        if self._verbose:
            self._print_verbage()
            
        self.connect(self.u, self.scale, self.chan_filt,
self.packet_receiver)

    def _setup_usrp_source(self):
        self.u = usrp2.source_32fc (self._interface, self._mac_addr)
        adc_rate = self.u.adc_rate()

        # derive values of bitrate, samples_per_symbol, and decim from
desired info
        (self._bitrate, self._samples_per_symbol, self._decim) = \ 
            pick_rx_bitrate(self._bitrate,
self._demod_class.bits_per_symbol(), \
                            self._samples_per_symbol, self._decim, adc_rate) 

        self.u.set_decim(self._decim)
        # determine the daughterboard subdevice we're using
        #if self._rx_subdev_spec is None:
        #    self._rx_subdev_spec = usrp.pick_rx_subdevice(self.u)
        #self.subdev = usrp.selected_subdev(self.u, self._rx_subdev_spec)

        #self.u.set_mux(usrp.determine_rx_mux_value(self.u,
self._rx_subdev_spec))

    def set_freq(self, target_freq):
        """
        Set the center frequency we're interested in.

        @param target_freq: frequency in Hz
        @rypte: bool

        Tuning is a two step process.  First we ask the front-end to
        tune as close to the desired frequency as it can.  Then we use
        the result of that operation and our target_frequency to
        determine the value for the digital up converter.
        """
        r = self.u.set_center_freq(target_freq)
        if r:
            return True

        return False

    def set_gain(self, gain):
        """
        Sets the analog gain in the USRP
        """
        if gain is None:
            r = self.u.gain_range()
            gain = (r[0] + r[1])/2               # set gain to midpoint
        self.gain = gain
        return self.u.set_gain(gain)

    def set_auto_tr(self, enable):
        #return self.u.set_auto_tr(enable)
        return
        
    def bitrate(self):
        return self._bitrate

    def samples_per_symbol(self):
        return self._samples_per_symbol

    def decim(self):
        return self._decim

    def carrier_sensed(self):
        """
        Return True if we think carrier is present.
        """
        #return self.probe.level() > X
        return self.probe.unmuted()

    def carrier_threshold(self):
        """
        Return current setting in dB.
        """
        return self.probe.threshold()

    def set_carrier_threshold(self, threshold_in_db):
        """
        Set carrier threshold.

        @param threshold_in_db: set detection threshold
        @type threshold_in_db:  float (dB)
        """
        self.probe.set_threshold(threshold_in_db)
    
        
    def add_options(normal, expert):
        """
        Adds receiver-specific options to the Options Parser
        """
        add_freq_option(normal)
        if not normal.has_option("--bitrate"):
            normal.add_option("-r", "--bitrate", type="eng_float",
default=None,
                              help="specify bitrate.  samples-per-symbol and
interp/decim will be derived.")
        normal.add_option("-e", "--interface", type="string",
default="eth0",
                          help="select Ethernet interface, default is eth0")
        normal.add_option("-m", "--mac-addr", type="string", default="",
                          help="select USRP by MAC address, default is
auto-select")
        #normal.add_option("-R", "--rx-subdev-spec", type="subdev",
default=None,
        #                  help="select USRP Rx side A or B")
        normal.add_option("", "--rx-gain", type="eng_float", default=None,
metavar="GAIN",
                          help="set receiver gain in dB [default=midpoint]. 
See also --show-rx-gain-range")
        normal.add_option("", "--show-rx-gain-range", action="store_true",
default=False, 
                          help="print min and max Rx gain available on
selected daughterboard")
        normal.add_option("-v", "--verbose", action="store_true",
default=False)
        expert.add_option("-S", "--samples-per-symbol", type="int",
default=None,
                          help="set samples/symbol [default=%default]")
        expert.add_option("", "--rx-freq", type="eng_float", default=None,
                          help="set Rx frequency to FREQ
[default=%default]", metavar="FREQ")
        expert.add_option("-d", "--decim", type="intx", default=None,
                          help="set fpga decimation rate to DECIM
[default=%default]")
        expert.add_option("", "--log", action="store_true", default=False,
                          help="Log all parts of flow graph to files
(CAUTION: lots of data)")
        expert.add_option("", "--log-rx-power", action="store_true",
default=False,
                          help="Log receive signal power to file (CAUTION:
lots of data)")

    # Make a static method to call before instantiation
    add_options = staticmethod(add_options)


    def _print_verbage(self):
        """
        Prints information about the receive path
        """
        print "\nReceive Path:"
        print "Using RX d'board %s"    % (self.u.daughterboard_id(),)
        print "Rx gain:         %g"    % (self.gain,)
        print "modulation:      %s"    % (self._demod_class.__name__)
        print "bitrate:         %sb/s" %
(eng_notation.num_to_str(self._bitrate))
        print "samples/symbol:  %3d"   % (self._samples_per_symbol)
        print "decim:           %3d"   % (self._decim)
        print "Rx Frequency:    %s"    %
(eng_notation.num_to_str(self._rx_freq))
        # print "Rx Frequency:    %f"    % (self._rx_freq)

    def __del__(self):
        # Avoid weak reference error
        #del self.subdev
        return
            
def add_freq_option(parser):
    """
    Hackery that has the -f / --freq option set both tx_freq and rx_freq
    """
    def freq_callback(option, opt_str, value, parser):
        parser.values.rx_freq = value
        parser.values.tx_freq = value

    if not parser.has_option('--freq'):
        parser.add_option('-f', '--freq', type="eng_float",
                          action="callback", callback=freq_callback,
                          help="set Tx and/or Rx frequency to FREQ
[default=%default]",
                          metavar="FREQ")

pick_bitrate.py

#
# Copyright 2005,2006 Free Software Foundation, Inc.
# 
# This file is part of GNU Radio
# 
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# 
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
# 

_default_bitrate = 500e3

_valid_samples_per_symbol = (2,3,4,5,6,7)

def _gen_tx_info(converter_rate):
    results = []
    for samples_per_symbol in _valid_samples_per_symbol:
        for interp in range(16, 512 + 1, 4):
            bitrate = converter_rate / interp / samples_per_symbol
            results.append((bitrate, samples_per_symbol, interp))
    results.sort()
    return results

def _gen_rx_info(converter_rate):
    results = []
    for samples_per_symbol in _valid_samples_per_symbol:
        for decim in range(8, 256 + 1, 2):
            bitrate = converter_rate / decim / samples_per_symbol
            results.append((bitrate, samples_per_symbol, decim))
    results.sort()
    return results
    
def _filter_info(info, samples_per_symbol, xrate):
    if samples_per_symbol is not None:
        info = [x for x in info if x[1] == samples_per_symbol]
    if xrate is not None:
        info = [x for x in info if x[2] == xrate]
    return info

def _pick_best(target_bitrate, bits_per_symbol, info):
    """
    @returns tuple (bitrate, samples_per_symbol, interp_rate_or_decim_rate)
    """
    if len(info) == 0:
        raise RuntimeError, "info is zero length!"

    if target_bitrate is None:     # return the fastest one
        return info[-1]
    
    # convert bit rate to symbol rate
    target_symbolrate = target_bitrate / bits_per_symbol
    
    # Find the closest matching symbol rate.
    # In the event of a tie, the one with the lowest samples_per_symbol
wins.
    # (We already sorted them, so the first one is the one we take)

    best = info[0]
    best_delta = abs(target_symbolrate - best[0])
    for x in info[1:]:
        delta = abs(target_symbolrate - x[0])
        if delta < best_delta:
            best_delta = delta
            best = x

    # convert symbol rate back to bit rate
    return ((best[0] * bits_per_symbol),) + best[1:]

def _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
                  xrate, converter_rate, gen_info):
    """
    @returns tuple (bitrate, samples_per_symbol, interp_rate_or_decim_rate)
    """
    if not isinstance(bits_per_symbol, int) or bits_per_symbol < 1:
        raise ValueError, "bits_per_symbol must be an int >= 1"
    
    if samples_per_symbol is not None and xrate is not None:  # completely
determined
        return (float(converter_rate) / xrate / samples_per_symbol,
                samples_per_symbol, xrate)

    if bitrate is None and samples_per_symbol is None and xrate is None:
        bitrate = _default_bitrate

    # now we have a target bitrate and possibly an xrate or
    # samples_per_symbol constraint, but not both of them.

    return _pick_best(bitrate, bits_per_symbol,
                      _filter_info(gen_info(converter_rate),
samples_per_symbol, xrate))
    
#
---------------------------------------------------------------------------------------

def pick_tx_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
                    interp_rate, converter_rate=128e6): 
    """
    Given the 4 input parameters, return at configuration that matches

    @param bitrate: desired bitrate or None
    @type bitrate: number or None
    @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3
    @type bits_per_symbol: integer >= 1
    @param samples_per_symbol: samples/baud (aka samples/symbol)
    @type samples_per_symbol: number or None
    @param interp_rate: USRP interpolation factor
    @type interp_rate: integer or None
    @param converter_rate: converter sample rate in Hz
    @type converter_rate: number

    @returns tuple (bitrate, samples_per_symbol, interp_rate)
    """
    return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
                         interp_rate, converter_rate, _gen_tx_info)


def pick_rx_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
                    decim_rate, converter_rate=64e6): 
    """
    Given the 4 input parameters, return at configuration that matches

    @param bitrate: desired bitrate or None
    @type bitrate: number or None
    @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3
    @type bits_per_symbol: integer >= 1
    @param samples_per_symbol: samples/baud (aka samples/symbol)
    @type samples_per_symbol: number or None
    @param decim_rate: USRP decimation factor
    @type decim_rate: integer or None
    @param converter_rate: converter sample rate in Hz
    @type converter_rate: number

    @returns tuple (bitrate, samples_per_symbol, decim_rate)
    """
    return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
                         decim_rate, converter_rate, _gen_rx_info)

Thanks in advance for your cooperation.

(2)

Hi,

This is what I get when I run benchmark _tx.py and benchmark_rx.py
respectively on USRP2 with transmit_path_usrp2.py and receive_path_usrp2.py
respectively:

benchmark_tx.py:-

m...@mcrl-desktop:~/gnuradio/gnuradio-examples/python/digital$ sudo
./benchmark_tx.py -f 2400M -v
usrp2::ctor reset_db failed
usrp2::ctor set_rx_gain failed
usrp2::ctor set_tx_interp failed
usrp2::ctor set_rx_scale_iq failed
>>> gr_fir_fff: using SSE
bits per symbol = 1
Gaussian filter bt = 0.35
Using TX d'board 43
Tx amplitude     12000
modulation:      gmsk_mod
bitrate:         500kb/s
samples/symbol:    2
interp:          100
Tx Frequency:    2.4G
...........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................m...@mcrl-desktop:~/gnuradio/gnuradio-examples/python/digital$
 

benchmark_rx.py:-

m...@mcrl-desktop:~/gnuradio/gnuradio-examples/python/digital$ sudo
./benchmark_rx.py -f 2400M -v
usrp2::ctor reset_db failed
>>> gr_fir_fff: using SSE
bits per symbol = 1
M&M clock recovery omega = 2.000000
M&M clock recovery gain mu = 0.175000
M&M clock recovery mu = 0.500000
M&M clock recovery omega rel. limit = 0.005000
frequency error = 0.000000

Receive Path:
Using RX d'board 39
Rx gain:         35
modulation:      gmsk_demod
bitrate:         500kb/s
samples/symbol:    2
decim:           100
Rx Frequency:    2.4G


Now the same thing for usrp1 but using transmit_path.py and receive_path.py
which is already provided in gnuradio:

benchmark_tx.py:-

m...@mcrl-desktop:~/gnuradio/gnuradio-examples/python/digital$ sudo
./benchmark_tx.py -f 2400M -v
>>> gr_fir_fff: using SSE
bits per symbol = 1
Gaussian filter bt = 0.35
Using TX d'board A: Flex 2400 Tx MIMO B
Tx amplitude     12000
modulation:      gmsk_mod
bitrate:         500kb/s
samples/symbol:    2
interp:          128
Tx Frequency:    2.4G
...........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................m...@mcrl-desktop:~/gnuradio/gnuradio-examples/python/digital$
 

benchmark_rx.py:-

m...@mcrl-desktop:~/gnuradio/gnuradio-examples/python/digital$ sudo
./benchmark_rx.py -f 2400M -v
>>> gr_fir_fff: using SSE
bits per symbol = 1
M&M clock recovery omega = 2.000000
M&M clock recovery gain mu = 0.175000
M&M clock recovery mu = 0.500000
M&M clock recovery omega rel. limit = 0.005000
frequency error = 0.000000

Receive Path:
Using RX d'board A: Flex 2400 Rx MIMO B
Rx gain:         45
modulation:      gmsk_demod
bitrate:         500kb/s
samples/symbol:    2
decim:            64
Rx Frequency:    2.4G

I am using the same pick_bitrate.py file that is already provided in
gnuradio. As it can be seen that both usrp systems have the default bit rate
irrespective of whether it acts as receiver or transmitter. My concern is
with the interpolation and decimation. Do I need to make changes to the
pick_bitrate.py file for USRP2? If yes, then what kind of changes. I also
observed that even though USRP2 shows a bit rate of 500kbps, however I
believe that its transmitting too fast which does not allow USRP1 to receive
correctly.I would greatly appreciate any help in this matter.

Thanks in advance.

(3)

At a minimum, you will need to call pick_tx_bitrate and
pick_rx_bitrate providing proper rates for the ADC and DAC.  They
default to the values appropriate for the USRP1.  However, it looks
like you'll need a USRP2 version since they encode the acceptable
ranges for interpolation and decimation which are different between
the USRP1 and USRP2.

Eric

(4)

Hi,

I already tried to set the value of the converter_rate in pick_tx_bitrate
and Pick_rx_bitrate according to the ADC and DAC specifications of u...@. I
set it to 200e6 in pick_tx_bitrate and in pick_rx_bitrate. But even that did
not worked. I am confused with how to modify the pick_bitrate.py file for
usrp2. I am not able to determine the different parameters that I need to
provide for usrp2. If anyone has already worked on it then please help me to
modify the pick_bitrate file for usrp2. Also if any other changes are
required in other python files.

Thanks in advance.

Smith

(5)

The DAC rate is 100e6. The "bitrate" is the desired data rate of the over the air modulation. It should be MUCH less, like 100k to 1M or so.
There is absolutely nothing in any of the systems for which 200e6 is a correct choice.
Matt

No comments:

Post a Comment

Days of our lives

Daisypath Anniversary tickers