Exemple #1
0
    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
Exemple #2
0
    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)
Exemple #6
0
def gen_and_append_crc32(s):
    crc = digital.crc32(s)
    return s + struct.pack(">I", gru.hexint(crc) & 0xFFFFFFFF)
Exemple #7
0
    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)
Exemple #8
0
    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")          
Exemple #9
0
    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)])
Exemple #11
0
    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")
Exemple #14
0
    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
Exemple #16
0
def gen_and_append_crc32(s):
    crc = digital_swig.crc32(s)
    return s + struct.pack(">I", gru.hexint(crc) & 0xFFFFFFFF)
Exemple #17
0
    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)