def _open_device(self, filename): try: self.handle = os.open(filename, os.O_RDWR) if self.handle < 0: return False # read event device name name = fcntl.ioctl(self.handle, gru.hexint(0x80ff4506), chr(0) * 256) name = name.replace(chr(0), '') # do we see anything we recognize? if name == 'Griffin PowerMate' or name == 'Griffin SoundKnob': self.id = ID_POWERMATE self.mapper = _powermate_remapper() elif name == 'CAVS SpaceShuttle A/V' or name == 'Contour Design ShuttleXpress': self.id = ID_SHUTTLE_XPRESS self.mapper = _contour_remapper() elif name == 'Contour Design ShuttlePRO': self.id = ID_SHUTTLE_PRO self.mapper = _contour_remapper() elif name == 'Contour Design ShuttlePRO v2': self.id = ID_SHUTTLE_PRO_V2 self.mapper = _contour_remapper() else: os.close(self.handle) self.handle = -1 return False # get exclusive control of the device, using ioctl EVIOCGRAB # there may be an issue with this on non x86 platforms and if # the _IOW,_IOC,... macros in <asm/ioctl.h> are changed fcntl.ioctl(self.handle,gru.hexint(0x40044590), 1) return True except exceptions.OSError: return False
def set_subdev (self, spec=None): """ assumes nchannels has been set """ """ call set_freq after subdev is set """ self.subdev = () if self.fake_rf: return # no subdev for fake rf """ get subdev spec """ if spec is None: srx1 = usrp.pick_rx_subdevice(self.src) else: srx1 = spec """ configure USRP mux and set rx/tx subdev """ ulist = [self.src] if self.nchannels == 1: assert len(ulist) == 1, "[radiorx]: Invalid number of USRP boards!" src = ulist[0] src.set_mux (usrp.determine_rx_mux_value(src, srx1) ) self.subdev += (usrp.selected_subdev(src, srx1), ) for s in self.subdev: exec("if not hasattr(s, '_u'): s._u = src") elif self.nchannels == 2: assert len(ulist) == 1, "[radiorx]: Invalid number of USRP boards!" srx2 = ((srx1[0]+1)%2, srx1[1]) src = ulist[0] src.set_mux(gru.hexint(0x23012301) ) #src.set_mux(gru.hexint(0x32103210) ) self.subdev += (usrp.selected_subdev(src, srx1), ) self.subdev += (usrp.selected_subdev(src, srx2), ) for s in self.subdev: exec("if not hasattr(s, '_u'): s._u = src") elif self.nchannels == 4: assert len(ulist) == 2, "[radiorx]: Invalid number of USRP boards!" srx2 = ((srx1[0]+1)%2, srx1[1]) for src in ulist: src.set_mux(gru.hexint(0x23012301) ) self.subdev += (usrp.selected_subdev(src, srx1), ) self.subdev += (usrp.selected_subdev(src, srx2), ) for s in self.subdev: exec("if not hasattr(s, '_u'): s._u = src") else: return self.error("Unable to set subdev; invalid value for " \ + "nchannels=%d"%(self.nchannels) ) self.set_auto_tr(True) # enable Automatic Tx/Rx Switching
def _open_device(self, filename): try: self.handle = os.open(filename, os.O_RDWR) if self.handle < 0: return False # read event device name name = fcntl.ioctl(self.handle, gru.hexint(0x80ff4506), chr(0) * 256) name = name.replace(chr(0), '') # do we see anything we recognize? if name == 'Griffin PowerMate' or name == 'Griffin SoundKnob': self.id = ID_POWERMATE self.mapper = _powermate_remapper() elif name == 'CAVS SpaceShuttle A/V' or name == 'Contour Design ShuttleXpress': self.id = ID_SHUTTLE_XPRESS self.mapper = _contour_remapper() elif name == 'Contour Design ShuttlePRO': self.id = ID_SHUTTLE_PRO self.mapper = _contour_remapper() elif name == 'Contour Design ShuttlePRO v2': self.id = ID_SHUTTLE_PRO_V2 self.mapper = _contour_remapper() else: os.close(self.handle) self.handle = -1 return False # get exclusive control of the device, using ioctl EVIOCGRAB # there may be an issue with this on non x86 platforms and if # the _IOW,_IOC,... macros in <asm/ioctl.h> are changed fcntl.ioctl(self.handle, gru.hexint(0x40044590), 1) return True except exceptions.OSError: return False
def determine_tx_mux_value(u, subdev_spec): """ Determine appropriate Tx mux value as a function of the subdevice choosen. @param u: instance of USRP source @param subdev_spec: return value from subdev option parser. @type subdev_spec: (side, subdev), where side is 0 or 1 and subdev is 0 @returns: the Rx mux value """ # This is simpler than the rx case. Either you want to talk # to side A or side B. If you want to talk to both sides at once, # determine the value manually. side = subdev_spec[0] # side A = 0, side B = 1 if not(side in (0, 1)): raise ValueError, "Invalid subdev_spec: %r:" % (subdev_spec,) return gru.hexint([0x0098, 0x9800][side])
def __init__(self): gr.flow_graph.__init__(self) parser = OptionParser (option_class=eng_option) #parser.add_option("-S", "--subdev", type="subdev", default=(0, None), # help="select USRP Rx side A or B (default=A)") parser.add_option("-d", "--decim", type="int", default=128, help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=146.585e6, help="set frequency to FREQ [default=%default])", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=20, help="set gain in dB [default=%default]") parser.add_option("-F", "--filter", action="store_true", default=True, help="Enable channel filter") parser.add_option("-o", "--output", type="string", default=None, help="set output basename") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() raise SystemExit if options.output is None: parser.print_help() sys.stderr.write("You must provide an output filename base with -o OUTPUT\n") raise SystemExit else: basename = options.output nchan = 4 nsecs = 4.0 if options.filter: sw_decim = 4 else: sw_decim = 1 self.u = usrp.source_c(0, options.decim, fpga_filename="std_4rx_0tx.rbf") if self.u.nddc() < nchan: sys.stderr.write('This code requires an FPGA build with %d DDCs. This FPGA has only %d.\n' % ( nchan, self.u.nddc())) raise SystemExit if not self.u.set_nchannels(nchan): sys.stderr.write('set_nchannels(%d) failed\n' % (nchan,)) raise SystemExit input_rate = self.u.adc_freq() / self.u.decim_rate() print "USB data rate = %s" % (eng_notation.num_to_str(input_rate),) sink_data_rate = input_rate/sw_decim print "Scope data rate = %s" % (eng_notation.num_to_str(sink_data_rate),) self.subdev = self.u.db[0] + self.u.db[1] if (len(self.subdev) != 4 or self.u.db[0][0].dbid() != usrp_dbid.BASIC_RX or self.u.db[1][0].dbid() != usrp_dbid.BASIC_RX): sys.stderr.write('This code requires a Basic Rx board on Sides A & B\n') sys.exit(1) self.u.set_mux(gru.hexint(0xf3f2f1f0)) # collect 1 second worth of data limit = int(nsecs * input_rate * nchan) print "limit = ", limit head = gr.head(gr.sizeof_gr_complex, limit) # deinterleave four channels from FPGA di = gr.deinterleave(gr.sizeof_gr_complex) self.connect(self.u, head, di) # taps for channel filter chan_filt_coeffs = optfir.low_pass (1, # gain input_rate, # sampling rate 80e3, # passband cutoff 115e3, # stopband cutoff 0.1, # passband ripple 60) # stopband attenuation #print len(chan_filt_coeffs) for i in range(nchan): sink = gr.file_sink(gr.sizeof_gr_complex, basename + ("-%s-%d.dat" % (eng_notation.num_to_str(sink_data_rate), i))) if options.filter: chan_filt = gr.fir_filter_ccf(sw_decim, chan_filt_coeffs) self.connect((di, i), chan_filt, sink) else: self.connect((di, i), sink) self.set_gain(options.gain) self.set_freq(options.freq)
def gen_and_append_crc32(s): crc = digital.crc32(s) return s + struct.pack(">I", gru.hexint(crc) & 0xFFFFFFFF)
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel parser = OptionParser(option_class=eng_option) #parser.add_option("-S", "--subdev", type="subdev", default=(0, None), # help="select USRP Rx side A or B (default=A)") parser.add_option( "-d", "--decim", type="int", default=128, help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=146.585e6, help="set frequency to FREQ [default=%default])", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=20, help="set gain in dB [default=%default]") parser.add_option("-F", "--filter", action="store_true", default=True, help="Enable channel filter") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() raise SystemExit nchan = 4 if options.filter: sw_decim = 4 else: sw_decim = 1 self.u = usrp.source_c(0, options.decim, fpga_filename="std_4rx_0tx.rbf") if self.u.nddcs() < nchan: sys.stderr.write( 'This code requires an FPGA build with %d DDCs. This FPGA has only %d.\n' % (nchan, self.u.nddcs())) raise SystemExit if not self.u.set_nchannels(nchan): sys.stderr.write('set_nchannels(%d) failed\n' % (nchan, )) raise SystemExit input_rate = self.u.adc_freq() / self.u.decim_rate() print "USB data rate = %s" % (eng_notation.num_to_str(input_rate), ) print "Scope data rate = %s" % (eng_notation.num_to_str( input_rate / sw_decim), ) self.subdev = self.u.db(0) + self.u.db(1) if (len(self.subdev) < 4 or self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX or self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX): sys.stderr.write( 'This code requires a Basic Rx board on Sides A & B\n') sys.exit(1) self.u.set_mux(gru.hexint(0xf3f2f1f0)) # deinterleave four channels from FPGA di = gr.deinterleave(gr.sizeof_gr_complex) self.connect(self.u, di) # our destination (8 float inputs) self.scope = scopesink2.scope_sink_f(panel, sample_rate=input_rate / sw_decim, num_inputs=2 * nchan) # taps for channel filter chan_filt_coeffs = optfir.low_pass( 1, # gain input_rate, # sampling rate 80e3, # passband cutoff 115e3, # stopband cutoff 0.1, # passband ripple 60) # stopband attenuation #print len(chan_filt_coeffs) # bust the deinterleaved complex channels into floats for i in range(nchan): if options.filter: chan_filt = gr.fir_filter_ccf(sw_decim, chan_filt_coeffs) c2f = gr.complex_to_float() self.connect((di, i), chan_filt, c2f) else: c2f = gr.complex_to_float() self.connect((di, i), c2f) self.connect((c2f, 0), (self.scope, 2 * i + 0)) self.connect((c2f, 1), (self.scope, 2 * i + 1)) self._build_gui(vbox) self.set_gain(options.gain) self.set_freq(options.freq)
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel parser = OptionParser(option_class=eng_option) parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, help="select USRP Rx side A or B (default=first one with a daughterboard)") parser.add_option("-d", "--decim", type="int", default=16, help="set fgpa decimation rate to DECIM [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)") parser.add_option("-8", "--width-8", action="store_true", default=False, help="Enable 8-bit samples across USB") parser.add_option( "--no-hb", action="store_true", default=False, help="don't use halfband filter in usrp") parser.add_option("-C", "--basic-complex", action="store_true", default=False, help="Use both inputs of a basicRX or LFRX as a single Complex input channel") parser.add_option("-D", "--basic-dualchan", action="store_true", default=False, help="Use both inputs of a basicRX or LFRX as seperate Real input channels") parser.add_option("-n", "--frame-decim", type="int", default=1, help="set oscope frame decimation factor to n [default=1]") parser.add_option("-v", "--v-scale", type="eng_float", default=1000, help="set oscope initial V/div to SCALE [default=%default]") parser.add_option("-t", "--t-scale", type="eng_float", default=49e-6, help="set oscope initial s/div to SCALE [default=50us]") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) self.show_debug_info = True # build the graph if options.basic_dualchan: self.num_inputs=2 else: self.num_inputs=1 if options.no_hb or (options.decim<8): #Min decimation of this firmware is 4. #contains 4 Rx paths without halfbands and 0 tx paths. self.fpga_filename="std_4rx_0tx.rbf" self.u = usrp.source_c(nchan=self.num_inputs,decim_rate=options.decim, fpga_filename=self.fpga_filename) else: #Min decimation of standard firmware is 8. #standard fpga firmware "std_2rxhb_2tx.rbf" #contains 2 Rx paths with halfband filters and 2 tx paths (the default) self.u = usrp.source_c(nchan=self.num_inputs,decim_rate=options.decim) if options.rx_subdev_spec is None: options.rx_subdev_spec = pick_subdevice(self.u) if options.width_8: width = 8 shift = 8 format = self.u.make_format(width, shift) #print "format =", hex(format) r = self.u.set_format(format) #print "set_format =", r # determine the daughterboard subdevice we're using self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) if (options.basic_complex or options.basic_dualchan ): if ((self.subdev.dbid()==usrp_dbid.BASIC_RX) or (self.subdev.dbid()==usrp_dbid.LF_RX)): side = options.rx_subdev_spec[0] # side A = 0, side B = 1 if options.basic_complex: #force Basic_RX and LF_RX in complex mode (use both I and Q channel) print "Receiver daughterboard forced in complex mode. Both inputs will combined to form a single complex channel." self.dualchan=False if side==0: self.u.set_mux(0x00000010) #enable adc 0 and 1 to form a single complex input on side A else: #side ==1 self.u.set_mux(0x00000032) #enable adc 3 and 2 to form a single complex input on side B elif options.basic_dualchan: #force Basic_RX and LF_RX in dualchan mode (use input A for channel 0 and input B for channel 1) print "Receiver daughterboard forced in dualchannel mode. Each input will be used to form a seperate channel." self.dualchan=True if side==0: self.u.set_mux(gru.hexint(0xf0f0f1f0)) #enable adc 0, side A to form a real input on channel 0 and adc1,side A to form a real input on channel 1 else: #side ==1 self.u.set_mux(0xf0f0f3f2) #enable adc 2, side B to form a real input on channel 0 and adc3,side B to form a real input on channel 1 else: sys.stderr.write('options basic_dualchan or basic_complex is only supported for Basic Rx or LFRX at the moment\n') sys.exit(1) else: self.dualchan=False self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) input_rate = self.u.adc_freq() / self.u.decim_rate() self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate, frame_decim=options.frame_decim, v_scale=options.v_scale, t_scale=options.t_scale, num_inputs=self.num_inputs) if self.dualchan: # deinterleave two channels from FPGA self.di = gr.deinterleave(gr.sizeof_gr_complex) self.connect(self.u,self.di) self.connect((self.di,0),(self.scope,0)) self.connect((self.di,1),(self.scope,1)) else: self.connect(self.u, self.scope) self._build_gui(vbox) # set initial values 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 if options.freq is None: if ((self.subdev.dbid()==usrp_dbid.BASIC_RX) or (self.subdev.dbid()==usrp_dbid.LF_RX)): #for Basic RX and LFRX if no freq is specified you probably want 0.0 Hz and not 45 GHz options.freq=0.0 else: # if no freq was specified, use the mid-point r = self.subdev.freq_range() options.freq = float(r[0]+r[1])/2 self.set_gain(options.gain) if self.show_debug_info: self.myform['decim'].set_value(self.u.decim_rate()) self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) self.myform['dbname'].set_value(self.subdev.name()) self.myform['baseband'].set_value(0) self.myform['ddc'].set_value(0) if self.num_inputs==2: self.myform['baseband2'].set_value(0) self.myform['ddc2'].set_value(0) if not(self.set_freq(options.freq)): self._set_status_msg("Failed to set initial frequency") if self.num_inputs==2: if not(self.set_freq2(options.freq)): self._set_status_msg("Failed to set initial frequency for channel 2")
def __init__(self, fg, master_serialno, decim, nchan=2, pga_gain=0.0, cordic_freq=0.0, mux=None, align_interval=-1, fpga_filename="multi_2rxhb_2tx.rbf"): """ Align multiple sources (usrps) using samplenumbers in the first channel. Takes two ore more sources producing interleaved shorts. produces nchan * nsources gr_complex output streams. @param nchan: number of interleaved channels in source @param align_interval: number of samples to minimally skip between alignments default = -1 which means align only once per work call. @param master_serial_no: serial number of the source which must be the master. Exported sub-blocks (attributes): master_source slave_source usrp_master usrp_slave """ mode = usrp.FPGA_MODE_NORMAL mode = mode | usrp_prims.bmFR_MODE_RX_COUNTING_32BIT #(1 << 2) #usrp1.FPGA_MODE_COUNTING_32BIT align = gr.align_on_samplenumbers_ss(nchan, align_interval) self.usrp_master = None self.usrp_slave = None # um is master usrp # us is slave usrp if mux is None: mux = self.get_default_mux( ) #Note that all channels have shifted left because of the added 32 bit counter channel u1 = usrp.source_s(1, decim, nchan, gru.hexint(mux), mode, fpga_filename=fpga_filename) u0 = usrp.source_s(0, decim, nchan, gru.hexint(mux), mode, fpga_filename=fpga_filename) print 'usrp[0] serial', u0.serial_number() print 'usrp[1] serial', u1.serial_number() #default, choose the second found usrp as master (which is usually the usrp which was first plugged in) um_index = 1 um = u1 us_index = 0 us = u0 if (not (master_serialno is None)): #((master_serialno>0) | (master_serialno <-2)): if (u0.serial_number() == master_serialno): um_index = 0 um = u0 us_index = 1 us = u1 elif (u1.serial_number() != master_serialno): errorstring = 'Error. requested master_serialno ' + master_serialno + ' not found\n' errorstring = errorstring + 'Available are:\n' errorstring = errorstring + 'usrp[1] serial_no = ' + u1.serial_number( ) + '\n' errorstring = errorstring + 'usrp[0] serial_no = ' + u0.serial_number( ) + '\n' print errorstring raise ValueError, errorstring else: #default, just choose the first found usrp as master um_index = 1 um = u1 us_index = 0 us = u0 self.usrp_master = um self.usrp_slave = us print 'usrp_master=usrp[%i] serial_no = %s' % ( um_index, self.usrp_master.serial_number(), ) print 'usrp_slave=usrp[%i] serial_no = %s' % ( us_index, self.usrp_slave.serial_number(), ) self.subdev_mAr = usrp.selected_subdev(self.usrp_master, (0, 0)) self.subdev_mBr = usrp.selected_subdev(self.usrp_master, (1, 0)) self.subdev_sAr = usrp.selected_subdev(self.usrp_slave, (0, 0)) self.subdev_sBr = usrp.selected_subdev(self.usrp_slave, (1, 0)) #throttle = gr.throttle(gr.sizeof_gr_complex, input_rate) if not (pga_gain is None): um.set_pga(0, pga_gain) um.set_pga(1, pga_gain) us.set_pga(0, pga_gain) us.set_pga(1, pga_gain) self.input_rate = um.adc_freq() / um.decim_rate() deintm = gr.deinterleave(gr.sizeof_gr_complex) deints = gr.deinterleave(gr.sizeof_gr_complex) nullsinkm = gr.null_sink(gr.sizeof_gr_complex) nullsinks = gr.null_sink(gr.sizeof_gr_complex) tocomplexm = gr.interleaved_short_to_complex() tocomplexs = gr.interleaved_short_to_complex() fg.connect(um, (align, 0)) fg.connect(us, (align, 1)) fg.connect((align, 0), tocomplexm) fg.connect((align, 1), tocomplexs) fg.connect(tocomplexm, deintm) fg.connect(tocomplexs, deints) fg.connect( (deintm, 0), nullsinkm ) #The counters are not usefull for the user but must be connected to something fg.connect( (deints, 0), nullsinks ) #The counters are not usefull for the user but must be connected to something if 4 == nchan: nullsinkm3 = gr.null_sink(gr.sizeof_gr_complex) nullsinks3 = gr.null_sink(gr.sizeof_gr_complex) fg.connect( (deintm, 3), nullsinkm3) #channel 4 is not used but must be connected fg.connect( (deints, 3), nullsinks3) #channel 4 is not used but must be connected self.fg = fg self.master_source = deintm self.slave_source = deints if not (cordic_freq is None): um.set_rx_freq(1, cordic_freq) um.set_rx_freq(0, cordic_freq) us.set_rx_freq(1, cordic_freq) us.set_rx_freq(0, cordic_freq) self.enable_master_and_slave() # add an idle handler self.unsynced = True
def determine_rx_mux_value(u, subdev_spec): """ Determine appropriate Rx mux value as a function of the subdevice choosen and the characteristics of the respective daughterboard. @param u: instance of USRP source @param subdev_spec: return value from subdev option parser. @type subdev_spec: (side, subdev), where side is 0 or 1 and subdev is 0 or 1 @returns: the Rx mux value """ # Figure out which A/D's to connect to the DDC. # # Each daughterboard consists of 1 or 2 subdevices. (At this time, # all but the Basic Rx have a single subdevice. The Basic Rx # has two independent channels, treated as separate subdevices). # subdevice 0 of a daughterboard may use 1 or 2 A/D's. We determine this # by checking the is_quadrature() method. If subdevice 0 uses only a single # A/D, it's possible that the daughterboard has a second subdevice, subdevice 1, # and it uses the second A/D. # # If the card uses only a single A/D, we wire a zero into the DDC Q input. # # (side, 0) says connect only the A/D's used by subdevice 0 to the DDC. # (side, 1) says connect only the A/D's used by subdevice 1 to the DDC. # side = subdev_spec[0] # side A = 0, side B = 1 if not(side in (0, 1)): raise ValueError, "Invalid subdev_spec: %r:" % (subdev_spec,) db = u.db[side] # This is a tuple of length 1 or 2 containing the subdevice # classes for the selected side. # compute bitmasks of used A/D's if db[0].is_quadrature(): subdev0_uses = 0x3 # uses A/D 0 and 1 else: subdev0_uses = 0x1 # uses A/D 0 only if len(db) > 1: subdev1_uses = 0x2 # uses A/D 1 only else: subdev1_uses = 0x0 # uses no A/D (doesn't exist) if subdev_spec[1] == 0: uses = subdev0_uses elif subdev_spec[1] == 1: uses = subdev1_uses else: raise ValueError, "Invalid subdev_spec: %r: " % (subdev_spec,) if uses == 0: raise RuntimeError, "Daughterboard doesn't have a subdevice 1: %r: " % (subdev_spec,) swap_iq = db[0].i_and_q_swapped() truth_table = { # (side, uses, swap_iq) : mux_val (0, 0x1, False) : 0xf0f0f0f0, (0, 0x2, False) : 0xf0f0f0f1, (0, 0x3, False) : 0x00000010, (0, 0x3, True) : 0x00000001, (1, 0x1, False) : 0xf0f0f0f2, (1, 0x2, False) : 0xf0f0f0f3, (1, 0x3, False) : 0x00000032, (1, 0x3, True) : 0x00000023 } return gru.hexint(truth_table[(side, uses, swap_iq)])
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel parser = OptionParser(option_class=eng_option) parser.add_option( "-R", "--rx-subdev-spec", type="subdev", default=None, help= "select USRP Rx side A or B (default=first one with a daughterboard)" ) parser.add_option( "-d", "--decim", type="int", default=16, help="set fgpa decimation rate to DECIM [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)") parser.add_option("-8", "--width-8", action="store_true", default=False, help="Enable 8-bit samples across USB") parser.add_option("--no-hb", action="store_true", default=False, help="don't use halfband filter in usrp") parser.add_option( "-C", "--basic-complex", action="store_true", default=False, help= "Use both inputs of a basicRX or LFRX as a single Complex input channel" ) parser.add_option( "-D", "--basic-dualchan", action="store_true", default=False, help= "Use both inputs of a basicRX or LFRX as seperate Real input channels" ) parser.add_option( "-n", "--frame-decim", type="int", default=1, help="set oscope frame decimation factor to n [default=1]") parser.add_option( "-v", "--v-scale", type="eng_float", default=1000, help="set oscope initial V/div to SCALE [default=%default]") parser.add_option( "-t", "--t-scale", type="eng_float", default=49e-6, help="set oscope initial s/div to SCALE [default=50us]") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) self.show_debug_info = True # build the graph if options.basic_dualchan: self.num_inputs = 2 else: self.num_inputs = 1 if options.no_hb or (options.decim < 8): #Min decimation of this firmware is 4. #contains 4 Rx paths without halfbands and 0 tx paths. self.fpga_filename = "std_4rx_0tx.rbf" self.u = usrp.source_c(nchan=self.num_inputs, decim_rate=options.decim, fpga_filename=self.fpga_filename) else: #Min decimation of standard firmware is 8. #standard fpga firmware "std_2rxhb_2tx.rbf" #contains 2 Rx paths with halfband filters and 2 tx paths (the default) self.u = usrp.source_c(nchan=self.num_inputs, decim_rate=options.decim) if options.rx_subdev_spec is None: options.rx_subdev_spec = pick_subdevice(self.u) if options.width_8: width = 8 shift = 8 format = self.u.make_format(width, shift) #print "format =", hex(format) r = self.u.set_format(format) #print "set_format =", r # determine the daughterboard subdevice we're using self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) if (options.basic_complex or options.basic_dualchan): if ((self.subdev.dbid() == usrp_dbid.BASIC_RX) or (self.subdev.dbid() == usrp_dbid.LF_RX)): side = options.rx_subdev_spec[0] # side A = 0, side B = 1 if options.basic_complex: #force Basic_RX and LF_RX in complex mode (use both I and Q channel) print "Receiver daughterboard forced in complex mode. Both inputs will combined to form a single complex channel." self.dualchan = False if side == 0: self.u.set_mux( 0x00000010 ) #enable adc 0 and 1 to form a single complex input on side A else: #side ==1 self.u.set_mux( 0x00000032 ) #enable adc 3 and 2 to form a single complex input on side B elif options.basic_dualchan: #force Basic_RX and LF_RX in dualchan mode (use input A for channel 0 and input B for channel 1) print "Receiver daughterboard forced in dualchannel mode. Each input will be used to form a seperate channel." self.dualchan = True if side == 0: self.u.set_mux( gru.hexint(0xf0f0f1f0) ) #enable adc 0, side A to form a real input on channel 0 and adc1,side A to form a real input on channel 1 else: #side ==1 self.u.set_mux( 0xf0f0f3f2 ) #enable adc 2, side B to form a real input on channel 0 and adc3,side B to form a real input on channel 1 else: sys.stderr.write( 'options basic_dualchan or basic_complex is only supported for Basic Rx or LFRX at the moment\n' ) sys.exit(1) else: self.dualchan = False self.u.set_mux( usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) input_rate = self.u.adc_freq() / self.u.decim_rate() self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate, frame_decim=options.frame_decim, v_scale=options.v_scale, t_scale=options.t_scale, num_inputs=self.num_inputs) if self.dualchan: # deinterleave two channels from FPGA self.di = gr.deinterleave(gr.sizeof_gr_complex) self.connect(self.u, self.di) self.connect((self.di, 0), (self.scope, 0)) self.connect((self.di, 1), (self.scope, 1)) else: self.connect(self.u, self.scope) self._build_gui(vbox) # set initial values 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 if options.freq is None: if ((self.subdev.dbid() == usrp_dbid.BASIC_RX) or (self.subdev.dbid() == usrp_dbid.LF_RX)): #for Basic RX and LFRX if no freq is specified you probably want 0.0 Hz and not 45 GHz options.freq = 0.0 else: # if no freq was specified, use the mid-point r = self.subdev.freq_range() options.freq = float(r[0] + r[1]) / 2 self.set_gain(options.gain) if self.show_debug_info: self.myform['decim'].set_value(self.u.decim_rate()) self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) self.myform['dbname'].set_value(self.subdev.name()) self.myform['baseband'].set_value(0) self.myform['ddc'].set_value(0) if self.num_inputs == 2: self.myform['baseband2'].set_value(0) self.myform['ddc2'].set_value(0) if not (self.set_freq(options.freq)): self._set_status_msg("Failed to set initial frequency") if self.num_inputs == 2: if not (self.set_freq2(options.freq)): self._set_status_msg( "Failed to set initial frequency for channel 2")
def __init__(self, frame, panel, vbox, argv): stdgui.gui_flow_graph.__init__(self) self.frame = frame self.panel = panel parser = OptionParser (option_class=eng_option) #parser.add_option("-S", "--subdev", type="subdev", default=(0, None), # help="select USRP Rx side A or B (default=A)") parser.add_option("-d", "--decim", type="int", default=128, help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=146.585e6, help="set frequency to FREQ [default=%default])", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=20, help="set gain in dB [default=%default]") parser.add_option("-F", "--filter", action="store_true", default=True, help="Enable channel filter") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() raise SystemExit nchan = 4 if options.filter: sw_decim = 4 else: sw_decim = 1 self.u = usrp.source_c(0, options.decim, fpga_filename="std_4rx_0tx.rbf") if self.u.nddc() < nchan: sys.stderr.write('This code requires an FPGA build with %d DDCs. This FPGA has only %d.\n' % ( nchan, self.u.nddc())) raise SystemExit if not self.u.set_nchannels(nchan): sys.stderr.write('set_nchannels(%d) failed\n' % (nchan,)) raise SystemExit input_rate = self.u.adc_freq() / self.u.decim_rate() print "USB data rate = %s" % (eng_notation.num_to_str(input_rate),) print "Scope data rate = %s" % (eng_notation.num_to_str(input_rate/sw_decim),) self.subdev = self.u.db[0] + self.u.db[1] if (len (self.subdev) != 4 or self.u.db[0][0].dbid() != usrp_dbid.BASIC_RX or self.u.db[1][0].dbid() != usrp_dbid.BASIC_RX): sys.stderr.write('This code requires a Basic Rx board on Sides A & B\n') sys.exit(1) self.u.set_mux(gru.hexint(0xf3f2f1f0)) # deinterleave four channels from FPGA di = gr.deinterleave(gr.sizeof_gr_complex) self.connect(self.u, di) # taps for channel filter chan_filt_coeffs = optfir.low_pass (1, # gain input_rate, # sampling rate 80e3, # passband cutoff 115e3, # stopband cutoff 0.1, # passband ripple 60) # stopband attenuation #print len(chan_filt_coeffs) for i in range(nchan): scope = fftsink.fft_sink_c(self, panel, sample_rate=input_rate/sw_decim, title="Input %d" % (i,), ref_level=80, y_per_div=20) vbox.Add(scope.win, 10, wx.EXPAND) if options.filter: chan_filt = gr.fir_filter_ccf(sw_decim, chan_filt_coeffs) self.connect((di, i), chan_filt, scope) else: self.connect((di, i), scope) self.set_gain(options.gain) self.set_freq(options.freq)
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel self.offset = 0.0 parser = OptionParser(option_class=eng_option) parser.add_option( "-R", "--rx-subdev-spec", type="subdev", default=None, help= "select USRP Rx side A or B (default=first one with a daughterboard)" ) parser.add_option( "-d", "--decim", type="int", default=256, help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=None, help="set frequency to FREQ", metavar="FREQ") parser.add_option( "-p", "--protocol", type="int", default=0, help="set protocol: 0 = RDLAP 19.2kbps (default); 1 = APCO25") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is midpoint)") parser.add_option("-8", "--width-8", action="store_true", default=False, help="Enable 8-bit samples across USB") parser.add_option("--no-hb", action="store_true", default=False, help="don't use halfband filter in usrp") parser.add_option( "-C", "--basic-complex", action="store_true", default=False, help= "Use both inputs of a basicRX or LFRX as a single Complex input channel" ) parser.add_option( "-D", "--basic-dualchan", action="store_true", default=False, help= "Use both inputs of a basicRX or LFRX as seperate Real input channels" ) parser.add_option( "-n", "--frame-decim", type="int", default=1, help="set oscope frame decimation factor to n [default=1]") parser.add_option( "-v", "--v-scale", type="eng_float", default=1000, help="set oscope initial V/div to SCALE [default=%default]") parser.add_option( "-t", "--t-scale", type="eng_float", default=49e-6, help="set oscope initial s/div to SCALE [default=50us]") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) self.show_debug_info = True # build the graph if options.basic_dualchan: self.num_inputs = 2 else: self.num_inputs = 1 if options.no_hb or (options.decim < 8): #Min decimation of this firmware is 4. #contains 4 Rx paths without halfbands and 0 tx paths. self.fpga_filename = "std_4rx_0tx.rbf" self.u = usrp.source_c(nchan=self.num_inputs, decim_rate=options.decim, fpga_filename=self.fpga_filename) else: #Min decimation of standard firmware is 8. #standard fpga firmware "std_2rxhb_2tx.rbf" #contains 2 Rx paths with halfband filters and 2 tx paths (the default) self.u = usrp.source_c(nchan=self.num_inputs, decim_rate=options.decim) if options.rx_subdev_spec is None: options.rx_subdev_spec = pick_subdevice(self.u) if options.width_8: width = 8 shift = 8 format = self.u.make_format(width, shift) #print "format =", hex(format) r = self.u.set_format(format) #print "set_format =", r # determine the daughterboard subdevice we're using self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) if (options.basic_complex or options.basic_dualchan): if ((self.subdev.dbid() == usrp_dbid.BASIC_RX) or (self.subdev.dbid() == usrp_dbid.LF_RX)): side = options.rx_subdev_spec[0] # side A = 0, side B = 1 if options.basic_complex: #force Basic_RX and LF_RX in complex mode (use both I and Q channel) print "Receiver daughterboard forced in complex mode. Both inputs will combined to form a single complex channel." self.dualchan = False if side == 0: self.u.set_mux( 0x00000010 ) #enable adc 0 and 1 to form a single complex input on side A else: #side ==1 self.u.set_mux( 0x00000032 ) #enable adc 3 and 2 to form a single complex input on side B elif options.basic_dualchan: #force Basic_RX and LF_RX in dualchan mode (use input A for channel 0 and input B for channel 1) print "Receiver daughterboard forced in dualchannel mode. Each input will be used to form a seperate channel." self.dualchan = True if side == 0: self.u.set_mux( gru.hexint(0xf0f0f1f0) ) #enable adc 0, side A to form a real input on channel 0 and adc1,side A to form a real input on channel 1 else: #side ==1 self.u.set_mux( 0xf0f0f3f2 ) #enable adc 2, side B to form a real input on channel 0 and adc3,side B to form a real input on channel 1 else: sys.stderr.write( 'options basic_dualchan or basic_complex is only supported for Basic Rx or LFRX at the moment\n' ) sys.exit(1) else: self.dualchan = False self.u.set_mux( usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) input_rate = self.u.adc_freq() / self.u.decim_rate() self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate, frame_decim=options.frame_decim, v_scale=options.v_scale, t_scale=options.t_scale, num_inputs=self.num_inputs) if self.dualchan: # deinterleave two channels from FPGA self.di = gr.deinterleave(gr.sizeof_gr_complex) self.connect(self.u, self.di) self.connect((self.di, 0), (self.scope, 0)) self.connect((self.di, 1), (self.scope, 1)) else: self.connect(self.u, self.scope) self.msgq = gr.msg_queue(2) # queue that holds a maximum of 2 messages self.queue_watcher = queue_watcher(self.msgq, self.adjust_freq_norm) #------------------------------------------------------------------------------- if options.protocol == 0: # ---------- RD-LAP 19.2 kbps (9600 ksps), 25kHz channel, self.symbol_rate = 9600 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps self.channel_decimation = 10 # decimation (final rate should be at least several symbol rate) self.max_frequency_offset = 12000.0 # coarse carrier tracker leash, ~ half a channel either way self.symbol_deviation = 1200.0 # this is frequency offset from center of channel to +1 / -1 symbols self.input_sample_rate = 64e6 / options.decim # for USRP: 64MHz / FPGA decimation rate self.protocol_processing = fsk4.rdlap_f( self.msgq, 0) # desired protocol processing block selected here self.channel_rate = self.input_sample_rate / self.channel_decimation # channel selection filter characteristics channel_taps = optfir.low_pass( 1.0, # Filter gain self.input_sample_rate, # Sample rate 10000, # One-sided modulation bandwidth 12000, # One-sided channel bandwidth 0.1, # Passband ripple 60) # Stopband attenuation # symbol shaping filter characteristics symbol_coeffs = gr.firdes.root_raised_cosine( 1.0, # gain self.channel_rate, # sampling rate self.symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type if options.protocol == 1: # ---------- APCO-25 C4FM Test Data self.symbol_rate = 4800 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps self.channel_decimation = 20 # decimation self.max_frequency_offset = 6000.0 # coarse carrier tracker leash self.symbol_deviation = 600.0 # this is frequency offset from center of channel to +1 / -1 symbols self.input_sample_rate = 64e6 / options.decim # for USRP: 64MHz / FPGA decimation rate self.protocol_processing = fsk4.apco25_f(self.msgq, 0) self.channel_rate = self.input_sample_rate / self.channel_decimation # channel selection filter channel_taps = optfir.low_pass( 1.0, # Filter gain self.input_sample_rate, # Sample rate 5000, # One-sided modulation bandwidth 6500, # One-sided channel bandwidth 0.1, # Passband ripple 60) # Stopband attenuation # symbol shaping filter symbol_coeffs = gr.firdes.root_raised_cosine( 1.0, # gain self.channel_rate, # sampling rate self.symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type # ----------------- End of setup block self.chan = gr.freq_xlating_fir_filter_ccf( self.channel_decimation, # Decimation rate channel_taps, # Filter taps 0.0, # Offset frequency self.input_sample_rate) # Sample rate self.scope2 = scopesink2.scope_sink_f(panel, sample_rate=self.symbol_rate, frame_decim=1, v_scale=2, t_scale=0.025, num_inputs=self.num_inputs) # also note: # this specifies the nominal frequency deviation for the 4-level fsk signal self.fm_demod_gain = self.channel_rate / (2.0 * pi * self.symbol_deviation) self.fm_demod = gr.quadrature_demod_cf(self.fm_demod_gain) symbol_decim = 1 self.symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs) # eventually specify: sample rate, symbol rate self.demod_fsk4 = fsk4.demod_ff(self.msgq, self.channel_rate, self.symbol_rate) #self.rdlap_processing = fsk4.rdlap_f(self.msgq, 0) self.connect(self.u, self.chan, self.fm_demod, self.symbol_filter, self.demod_fsk4, self.protocol_processing) self.connect(self.demod_fsk4, self.scope2) # --------------- End of most of the 4L-FSK hack & slash self._build_gui(vbox) # set initial values 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 if options.freq is None: if ((self.subdev.dbid() == usrp_dbid.BASIC_RX) or (self.subdev.dbid() == usrp_dbid.LF_RX)): #for Basic RX and LFRX if no freq is specified you probably want 0.0 Hz and not 45 GHz options.freq = 0.0 else: # if no freq was specified, use the mid-point r = self.subdev.freq_range() options.freq = float(r[0] + r[1]) / 2 self.set_gain(options.gain) if self.show_debug_info: # self.myform['decim'].set_value(self.u.decim_rate()) self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) self.myform['dbname'].set_value(self.subdev.name()) self.myform['baseband'].set_value(0) self.myform['ddc'].set_value(0) if self.num_inputs == 2: self.myform['baseband2'].set_value(0) self.myform['ddc2'].set_value(0) if not (self.set_freq(options.freq)): self._set_status_msg("Failed to set initial frequency") if self.num_inputs == 2: if not (self.set_freq2(options.freq)): self._set_status_msg( "Failed to set initial frequency for channel 2")
def __init__(self): gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) #parser.add_option("-S", "--subdev", type="subdev", default=(0, None), # help="select USRP Rx side A or B (default=A)") parser.add_option( "-d", "--decim", type="int", default=128, help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=146.585e6, help="set frequency to FREQ [default=%default])", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=20, help="set gain in dB [default=%default]") parser.add_option("-F", "--filter", action="store_true", default=True, help="Enable channel filter") parser.add_option("-o", "--output", type="string", default=None, help="set output basename") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() raise SystemExit if options.output is None: parser.print_help() sys.stderr.write( "You must provide an output filename base with -o OUTPUT\n") raise SystemExit else: basename = options.output nchan = 4 nsecs = 4.0 if options.filter: sw_decim = 4 else: sw_decim = 1 self.u = usrp.source_c(0, options.decim, fpga_filename="std_4rx_0tx.rbf") if self.u.nddcs() < nchan: sys.stderr.write( 'This code requires an FPGA build with %d DDCs. This FPGA has only %d.\n' % (nchan, self.u.nddcs())) raise SystemExit if not self.u.set_nchannels(nchan): sys.stderr.write('set_nchannels(%d) failed\n' % (nchan, )) raise SystemExit input_rate = self.u.adc_freq() / self.u.decim_rate() print "USB data rate = %s" % (eng_notation.num_to_str(input_rate), ) sink_data_rate = input_rate / sw_decim print "Scope data rate = %s" % ( eng_notation.num_to_str(sink_data_rate), ) self.subdev = self.u.db(0) + self.u.db(1) if (len(self.subdev) < 4 or self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX or self.u.db(1, 0).dbid() != usrp_dbid.BASIC_RX): sys.stderr.write( 'This code requires a Basic Rx board on Sides A & B\n') sys.exit(1) self.u.set_mux(gru.hexint(0xf3f2f1f0)) # collect 1 second worth of data limit = int(nsecs * input_rate * nchan) print "limit = ", limit head = gr.head(gr.sizeof_gr_complex, limit) # deinterleave four channels from FPGA di = gr.deinterleave(gr.sizeof_gr_complex) self.connect(self.u, head, di) # taps for channel filter chan_filt_coeffs = optfir.low_pass( 1, # gain input_rate, # sampling rate 80e3, # passband cutoff 115e3, # stopband cutoff 0.1, # passband ripple 60) # stopband attenuation #print len(chan_filt_coeffs) for i in range(nchan): sink = gr.file_sink( gr.sizeof_gr_complex, basename + ("-%s-%d.dat" % (eng_notation.num_to_str(sink_data_rate), i))) if options.filter: chan_filt = gr.fir_filter_ccf(sw_decim, chan_filt_coeffs) self.connect((di, i), chan_filt, sink) else: self.connect((di, i), sink) self.set_gain(options.gain) self.set_freq(options.freq)
def __init__(self, fg, master_serialno,decim,nchan=2,pga_gain=0.0,cordic_freq=0.0,mux=None,align_interval=-1): """ Align multiple sources (usrps) using samplenumbers in the first channel. Takes two ore more sources producing interleaved shorts. produces nchan * nsources gr_complex output streams. @param nchan: number of interleaved channels in source @param align_interval: number of samples to minimally skip between alignments default = -1 which means align only once per work call. @param master_serial_no: serial number of the source which must be the master. Exported sub-blocks (attributes): master_source slave_source usrp_master usrp_slave """ mode=usrp.FPGA_MODE_NORMAL mode = mode | usrp_prims.bmFR_MODE_RX_COUNTING_32BIT #(1 << 2) #usrp1.FPGA_MODE_COUNTING_32BIT align=gr.align_on_samplenumbers_ss (nchan,align_interval) self.usrp_master = None self.usrp_slave = None # um is master usrp # us is slave usrp if mux is None: mux=self.get_default_mux() #Note that all channels have shifted left because of the added 32 bit counter channel u1 = usrp.source_s (1, decim, nchan, gru.hexint(mux), mode,fpga_filename="multi_2rxhb_2tx.rbf" ) u0 = usrp.source_s (0, decim, nchan, gru.hexint(mux), mode,fpga_filename="multi_2rxhb_2tx.rbf" ) print 'usrp[0] serial',u0.serial_number() print 'usrp[1] serial',u1.serial_number() #default, choose the second found usrp as master (which is usually the usrp which was first plugged in) um_index=1 um=u1 us_index=0 us=u0 if (not (master_serialno is None)): #((master_serialno>0) | (master_serialno <-2)): if (u0.serial_number() == master_serialno): um_index=0 um=u0 us_index=1 us=u1 elif (u1.serial_number() != master_serialno): errorstring = 'Error. requested master_serialno ' + master_serialno +' not found\n' errorstring = errorstring + 'Available are:\n' errorstring = errorstring + 'usrp[1] serial_no = ' + u1.serial_number() +'\n' errorstring = errorstring + 'usrp[0] serial_no = ' + u0.serial_number() +'\n' print errorstring raise ValueError, errorstring else: #default, just choose the first found usrp as master um_index=0 um=u0 us_index=1 us=u1 self.usrp_master=um self.usrp_slave=us print 'usrp_master=usrp[%i] serial_no = %s' % (um_index,self.usrp_master.serial_number() ,) print 'usrp_slave=usrp[%i] serial_no = %s' % (us_index,self.usrp_slave.serial_number() ,) self.subdev_mAr = usrp.selected_subdev(self.usrp_master, (0,0)) self.subdev_mBr = usrp.selected_subdev(self.usrp_master, (1,0)) self.subdev_sAr = usrp.selected_subdev(self.usrp_slave, (0,0)) self.subdev_sBr = usrp.selected_subdev(self.usrp_slave, (1,0)) #throttle = gr.throttle(gr.sizeof_gr_complex, input_rate) if not (pga_gain is None): um.set_pga (0, pga_gain) um.set_pga (1, pga_gain) us.set_pga (0, pga_gain) us.set_pga (1, pga_gain) self.input_rate = um.adc_freq () / um.decim_rate () deintm=gr.deinterleave(gr.sizeof_gr_complex) deints=gr.deinterleave(gr.sizeof_gr_complex) nullsinkm=gr.null_sink(gr.sizeof_gr_complex) nullsinks=gr.null_sink(gr.sizeof_gr_complex) tocomplexm=gr.interleaved_short_to_complex() tocomplexs=gr.interleaved_short_to_complex() fg.connect(um,(align,0)) fg.connect(us,(align,1)) fg.connect((align,0),tocomplexm) fg.connect((align,1),tocomplexs) fg.connect(tocomplexm,deintm) fg.connect(tocomplexs,deints) fg.connect((deintm,0),nullsinkm) #The counters are not usefull for the user but must be connected to something fg.connect((deints,0),nullsinks) #The counters are not usefull for the user but must be connected to something if 4==nchan: nullsinkm3=gr.null_sink(gr.sizeof_gr_complex) nullsinks3=gr.null_sink(gr.sizeof_gr_complex) fg.connect((deintm,3), nullsinkm3) #channel 4 is not used but must be connected fg.connect((deints,3), nullsinks3) #channel 4 is not used but must be connected self.fg=fg self.master_source=deintm self.slave_source=deints if not (cordic_freq is None): um.set_rx_freq (1, cordic_freq) um.set_rx_freq (0, cordic_freq) us.set_rx_freq (1, cordic_freq) us.set_rx_freq (0, cordic_freq) self.enable_master_and_slave() # add an idle handler self.unsynced=True
def gen_and_append_crc32(s): crc = digital_swig.crc32(s) return s + struct.pack(">I", gru.hexint(crc) & 0xFFFFFFFF)
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel parser = OptionParser (option_class=eng_option) #parser.add_option("-S", "--subdev", type="subdev", default=(0, None), # help="select USRP Rx side A or B (default=A)") parser.add_option("-d", "--decim", type="int", default=128, help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=146.585e6, help="set frequency to FREQ [default=%default])", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=20, help="set gain in dB [default=%default]") parser.add_option("-F", "--filter", action="store_true", default=True, help="Enable channel filter") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() raise SystemExit nchan = 4 if options.filter: sw_decim = 4 else: sw_decim = 1 self.u = usrp.source_c(0, options.decim, fpga_filename="std_4rx_0tx.rbf") if self.u.nddcs() < nchan: sys.stderr.write('This code requires an FPGA build with %d DDCs. This FPGA has only %d.\n' % ( nchan, self.u.nddcs())) raise SystemExit if not self.u.set_nchannels(nchan): sys.stderr.write('set_nchannels(%d) failed\n' % (nchan,)) raise SystemExit input_rate = self.u.adc_freq() / self.u.decim_rate() print "USB data rate = %s" % (eng_notation.num_to_str(input_rate),) print "Scope data rate = %s" % (eng_notation.num_to_str(input_rate/sw_decim),) self.subdev = self.u.db(0) + self.u.db(1) if (len(self.subdev) < 4 or self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX or self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX): sys.stderr.write('This code requires a Basic Rx board on Sides A & B\n') sys.exit(1) self.u.set_mux(gru.hexint(0xf3f2f1f0)) # deinterleave four channels from FPGA di = gr.deinterleave(gr.sizeof_gr_complex) self.connect(self.u, di) # our destination (8 float inputs) self.scope = scopesink2.scope_sink_f(panel, sample_rate=input_rate/sw_decim, num_inputs=2*nchan) # taps for channel filter chan_filt_coeffs = optfir.low_pass (1, # gain input_rate, # sampling rate 80e3, # passband cutoff 115e3, # stopband cutoff 0.1, # passband ripple 60) # stopband attenuation #print len(chan_filt_coeffs) # bust the deinterleaved complex channels into floats for i in range(nchan): if options.filter: chan_filt = gr.fir_filter_ccf(sw_decim, chan_filt_coeffs) c2f = gr.complex_to_float() self.connect((di, i), chan_filt, c2f) else: c2f = gr.complex_to_float() self.connect((di, i), c2f) self.connect((c2f, 0), (self.scope, 2*i + 0)) self.connect((c2f, 1), (self.scope, 2*i + 1)) self._build_gui(vbox) self.set_gain(options.gain) self.set_freq(options.freq)