#!/usr/bin/env python # # Copyright 2008 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, eng_notation from gnuradio import usrp2 from gnuradio.eng_option import eng_option from optparse import OptionParser import sys import math n2s = eng_notation.num_to_str class siggen_top_block(gr.top_block): def __init__(self, options): gr.top_block.__init__(self) # Create a USRP2 sink with the requested interpolation rate self._u = usrp2.sink_32fc(options.interface, options.mac_addr) self._u.set_interp(options.interp) # Set the Tx daughterboard gain as requested if options.gain is None: g = self._u.gain_range() options.gain = float(g[0]+g[1])/2 self._u.set_gain(options.gain) # Tune the USRP2 FPGA and daughterboard to the requested center frequency tr = self._u.set_center_freq(options.tx_freq) if tr == None: sys.stderr.write('Failed to set center frequency\n') raise SystemExit, 1 eth_rate = self._u.dac_rate()/self._u.interp() # Create a source for the requested waveform type if options.type == gr.GR_SIN_WAVE or options.type == gr.GR_CONST_WAVE: self._src = gr.sig_source_c(eth_rate, # Sample rate options.type, # Waveform type options.waveform_freq, # Waveform frequency options.amplitude, # Waveform amplitude options.offset) # Waveform offset elif options.type == gr.GR_GAUSSIAN or options.type == gr.GR_UNIFORM: self._src = gr.noise_source_c(options.type, options.amplitude) elif options.type == "2tone": self._src1 = gr.sig_source_c(eth_rate, gr.GR_SIN_WAVE, options.waveform_freq, options.amplitude, 0) if(options.waveform2_freq is None): w2freq = -options.waveform_freq else: w2freq = options.waveform2_freq self._src2 = gr.sig_source_c(eth_rate, gr.GR_SIN_WAVE, w2freq, options.amplitude, 0) self._src = gr.add_cc() self.connect(self._src1,(self._src,0)) self.connect(self._src2,(self._src,1)) elif options.type == "sweep": # rf freq is center frequency # waveform_freq is total swept width # waveform2_freq is sweep rate # will sweep from (rf_freq-waveform_freq/2) to (rf_freq+waveform_freq/2) self._src1 = gr.sig_source_f(eth_rate, gr.GR_TRI_WAVE, options.waveform2_freq, 1.0, # options.waveform_freq, -0.5) self._src2 = gr.frequency_modulator_fc(options.waveform_freq*2*math.pi/eth_rate) self._src = gr.multiply_const_cc(options.amplitude) self.connect(self._src1,self._src2,self._src) else: sys.stderr.write('Unknown waveform type\n') raise SystemExit, 1 if options.verbose: print "Network interface:", options.interface print "USRP2 address:", self._u.mac_addr() #print "Using TX d'board %s" % (self._u.tx_name(),) print "Tx gain:", options.gain print "Tx baseband frequency:", n2s(tr.baseband_freq), "Hz" print "Tx DDC frequency:", n2s(tr.dxc_freq), "Hz" print "Tx residual frequency:", n2s(tr.residual_freq), "Hz" print "Tx interpolation rate:", options.interp print "Tx GbE sample rate:", n2s(eth_rate), "samples/sec" if options.type == gr.GR_SIN_WAVE: print "Baseband waveform type: Sine wave" print "Baseband waveform frequency:", n2s(options.waveform_freq), "Hz" elif options.type == gr.GR_CONST_WAVE: print "Baseband waveform type: Constant" elif options.type == gr.GR_GAUSSIAN: print "Baseband waveform type: Gaussian noise" elif options.type == gr.GR_UNIFORM: print "Baseband waveform type: Uniform noise" # Wire the flowgraph self.connect(self._src, self._u) def get_options(): usage="%prog: [options]" parser = OptionParser(option_class=eng_option, usage=usage) parser.add_option("-e", "--interface", type="string", default="eth0", help="use specified Ethernet interface [default=%default]") parser.add_option("-m", "--mac-addr", type="string", default="", help="use USRP2 at specified MAC address [default=None]") parser.add_option("-i", "--interp", type="int", default=16, help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set output gain to GAIN [default=%default]") parser.add_option("-f", "--tx-freq", type="eng_float", default=None, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-v", "--verbose", action="store_true", default=False, help="verbose output") parser.add_option("-w", "--waveform-freq", type="eng_float", default=0, help="set waveform frequency to FREQ [default=%default]") parser.add_option("-x", "--waveform2-freq", type="eng_float", default=None, help="set waveform frequency to FREQ [default=%default]") parser.add_option("-a", "--amplitude", type="eng_float", default=0.5, help="set waveform amplitude to AMPLITUDE (0-1.0) [default=%default]", metavar="AMPL") parser.add_option("--offset", type="eng_float", default=0, help="set waveform offset to OFFSET [default=%default]") parser.add_option("--sine", dest="type", action="store_const", const=gr.GR_SIN_WAVE, help="generate a complex sinusoid [default]", default=gr.GR_SIN_WAVE) parser.add_option("--const", dest="type", action="store_const", const=gr.GR_CONST_WAVE, help="generate a constant output") parser.add_option("--gaussian", dest="type", action="store_const", const=gr.GR_GAUSSIAN, help="generate Gaussian random output") parser.add_option("--uniform", dest="type", action="store_const", const=gr.GR_UNIFORM, help="generate Uniform random output") parser.add_option("--2tone", dest="type", action="store_const", const="2tone", help="generate Two Tone signal for IMD testing") parser.add_option("--sweep", dest="type", action="store_const", const="sweep", help="generate a swept sine wave") (options, args) = parser.parse_args () if len(args) != 0: parser.print_help() raise SystemExit, 1 if options.tx_freq is None: parser.print_help() sys.stderr.write('You must specify the frequency with -f FREQ\n'); raise SystemExit, 1 return options if __name__ == '__main__': options = get_options() tb = siggen_top_block(options) try: tb.run() except KeyboardInterrupt: pass