root/vtcross/branches/sriram/transmit_path.py @ 319

Revision 319, 8.9 KB (checked in by sriram, 15 years ago)

Adding files for DSA gnuradio app

Line 
1#
2# Copyright 2005,2006,2007,2009 Free Software Foundation, Inc.
3#
4# This file is part of GNU Radio
5#
6# GNU Radio is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 3, or (at your option)
9# any later version.
10#
11# GNU Radio is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with GNU Radio; see the file COPYING.  If not, write to
18# the Free Software Foundation, Inc., 51 Franklin Street,
19# Boston, MA 02110-1301, USA.
20#
21
22from gnuradio import gr, gru, blks2
23from gnuradio import usrp
24from gnuradio import eng_notation
25
26import copy
27import sys
28
29# from current dir
30from pick_bitrate import pick_tx_bitrate
31import usrp_options
32
33# /////////////////////////////////////////////////////////////////////////////
34#                              transmit path
35# /////////////////////////////////////////////////////////////////////////////
36
37class transmit_path(gr.hier_block2):
38    def __init__(self, modulator_class, options):
39        '''
40        See below for what options should hold
41        '''
42        gr.hier_block2.__init__(self, "transmit_path",
43                                gr.io_signature(0, 0, 0), # Input signature
44                                gr.io_signature(0, 0, 0)) # Output signature
45
46        options = copy.copy(options)    # make a copy so we can destructively modify
47
48        self._verbose            = options.verbose
49        self._tx_freq            = options.tx_freq         # tranmitter's center frequency
50        self._tx_amplitude       = options.tx_amplitude    # digital amplitude sent to USRP
51        self._bitrate            = options.bitrate         # desired bit rate
52        self._interp             = options.interp          # interpolating rate for the USRP (prelim)
53        self._samples_per_symbol = options.samples_per_symbol  # desired samples/baud
54        self._use_whitener_offset = options.use_whitener_offset # increment start of whitener XOR data
55       
56        self._modulator_class = modulator_class         # the modulator_class we are using
57   
58        if self._tx_freq is None:
59            sys.stderr.write("-f FREQ or --freq FREQ or --tx-freq FREQ must be specified\n")
60            raise SystemExit
61
62        # Set up USRP sink; also adjusts interp, samples_per_symbol, and bitrate
63        self._setup_usrp_sink(options)
64
65        if options.show_tx_ampl_range:
66            print "Tx Amplitude Range: minimum = %g, maximum = %g"%tuple(self.u.ampl_range())
67
68        # copy the final answers back into options for use by modulator
69        options.samples_per_symbol = self._samples_per_symbol
70        options.bitrate = self._bitrate
71        options.interp = self._interp
72
73        # Get mod_kwargs
74        mod_kwargs = self._modulator_class.extract_kwargs_from_options(options)
75
76        # Set center frequency of USRP
77        ok = self.set_freq(self._tx_freq)
78        if not ok:
79            print "Failed to set Tx frequency to %s" % (eng_notation.num_to_str(self._tx_freq),)
80            raise ValueError
81   
82        # transmitter
83        self.packet_transmitter = \
84            blks2.mod_pkts(self._modulator_class(**mod_kwargs),
85                           access_code=None,
86                           msgq_limit=4,
87                           pad_for_usrp=True,
88                           use_whitener_offset=options.use_whitener_offset)
89
90
91        # Set the USRP for maximum transmit gain
92        # (Note that on the RFX cards this is a nop.)
93        self.set_gain(self.u.gain_range()[1])
94
95        self.amp = gr.multiply_const_cc(1)
96        self.set_tx_amplitude(self._tx_amplitude)
97
98        # Display some information about the setup
99        if self._verbose:
100            self._print_verbage()
101
102        # Create and setup transmit path flow graph
103        self.connect(self.packet_transmitter, self.amp, self.u)
104
105    def _setup_usrp_sink(self, options):
106        """
107        Creates a USRP sink, determines the settings for best bitrate,
108        and attaches to the transmitter's subdevice.
109        """
110        self.u = usrp_options.create_usrp_sink(options)
111        dac_rate = self.u.dac_rate();
112
113        # derive values of bitrate, samples_per_symbol, and interp from desired info
114        (self._bitrate, self._samples_per_symbol, self._interp) = \
115            pick_tx_bitrate(self._bitrate, self._modulator_class.bits_per_symbol(),
116                            self._samples_per_symbol, self._interp, dac_rate)
117       
118        self.u.set_interp(self._interp)
119        print "printing interpolation ",self._interp,"\n"
120
121    def set_freq(self, target_freq):
122        """
123        Set the center frequency we're interested in.
124
125        @param target_freq: frequency in Hz
126        @rypte: bool
127
128        Tuning is a two step process.  First we ask the front-end to
129        tune as close to the desired frequency as it can.  Then we use
130        the result of that operation and our target_frequency to
131        determine the value for the digital up converter.
132        """
133        return self.u.set_center_freq(target_freq)
134       
135    def set_gain(self, gain):
136        """
137        Sets the analog gain in the USRP
138        """
139        return self.u.set_gain(gain)
140
141    def set_tx_amplitude(self, ampl):
142        """
143        Sets the transmit amplitude sent to the USRP
144        @param ampl the amplitude or None for automatic
145        """
146        ampl_range = self.u.ampl_range()
147        if ampl is None: ampl = (ampl_range[1] - ampl_range[0])*0.15 + ampl_range[0]
148        self._tx_amplitude = max(ampl_range[0], min(ampl, ampl_range[1]))
149        self.amp.set_k(self._tx_amplitude)
150
151    def send_pkt(self, payload='', eof=False):
152        """
153        Calls the transmitter method to send a packet
154        """
155        return self.packet_transmitter.send_pkt(payload, eof)
156       
157    def bitrate(self):
158        return self._bitrate
159
160    def samples_per_symbol(self):
161        return self._samples_per_symbol
162
163    def interp(self):
164        return self._interp
165
166    def add_options(normal, expert):
167        """
168        Adds transmitter-specific options to the Options Parser
169        """
170        add_freq_option(normal)
171        if not normal.has_option('--bitrate'):
172            normal.add_option("-r", "--bitrate", type="eng_float", default=None,
173                              help="specify bitrate.  samples-per-symbol and interp/decim will be derived.")
174        usrp_options.add_tx_options(normal, expert)
175        normal.add_option("--tx-amplitude", type="eng_float", default=None, metavar="AMPL",
176                          help="set transmitter digital amplitude [default=midpoint].  See also --show-tx-ampl-range")
177        normal.add_option("--show-tx-ampl-range", action="store_true", default=False,
178                          help="print min and max Tx amplitude available")
179        normal.add_option("-v", "--verbose", action="store_true", default=False)
180        expert.add_option("-S", "--samples-per-symbol", type="int", default=None,
181                          help="set samples/symbol [default=%default]")
182        expert.add_option("", "--tx-freq", type="eng_float", default=None,
183                          help="set transmit frequency to FREQ [default=%default]", metavar="FREQ")
184        expert.add_option("", "--log", action="store_true", default=False,
185                          help="Log all parts of flow graph to file (CAUTION: lots of data)")
186        expert.add_option("","--use-whitener-offset", action="store_true", default=False,
187                          help="make sequential packets use different whitening")
188
189    # Make a static method to call before instantiation
190    add_options = staticmethod(add_options)
191
192    def _print_verbage(self):
193        """
194        Prints information about the transmit path
195        """
196        print "Using TX d'board %s"    % (self.u,)
197        print "Tx amplitude     %s"    % (self._tx_amplitude)
198        print "modulation:      %s"    % (self._modulator_class.__name__)
199        print "bitrate:         %sb/s" % (eng_notation.num_to_str(self._bitrate))
200        print "samples/symbol:  %3d"   % (self._samples_per_symbol)
201        print "interp:          %3d"   % (self._interp)
202        print "Tx Frequency:    %s"    % (eng_notation.num_to_str(self._tx_freq))
203       
204
205def add_freq_option(parser):
206    """
207    Hackery that has the -f / --freq option set both tx_freq and rx_freq
208    """
209    def freq_callback(option, opt_str, value, parser):
210        parser.values.rx_freq = value
211        parser.values.tx_freq = value
212
213    if not parser.has_option('--freq'):
214        parser.add_option('-f', '--freq', type="eng_float",
215                          action="callback", callback=freq_callback,
216                          help="set Tx and/or Rx frequency to FREQ [default=%default]",
217                          metavar="FREQ")
Note: See TracBrowser for help on using the browser.