Statistics
| Branch: | Tag: | Revision:

root / gnuradio-examples / python / multi-antenna / multi_scope.py @ 05005e3d

History | View | Annotate | Download (4.8 kB)

1
#!/usr/bin/env python
2
3
from gnuradio import gr, gru, eng_notation
4
from gnuradio import usrp
5
from gnuradio.eng_option import eng_option
6
from gnuradio import eng_notation
7
from gnuradio import optfir
8
from optparse import OptionParser
9
from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider
10
import wx
11
from usrpm import usrp_dbid
12
import time
13
import os.path
14
import sys
15
16
# required FPGA that can do 4 rx channels.
17
18
19
class my_top_block(stdgui2.std_top_block):
20
21
    def __init__(self, frame, panel, vbox, argv):
22
        stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv)
23
24
        self.frame = frame
25
        self.panel = panel
26
27
        parser = OptionParser (option_class=eng_option)
28
        #parser.add_option("-S", "--subdev", type="subdev", default=(0, None),
29
        #                  help="select USRP Rx side A or B (default=A)")
30
        parser.add_option("-d", "--decim", type="int", default=128,
31
                          help="set fgpa decimation rate to DECIM [default=%default]")
32
        parser.add_option("-f", "--freq", type="eng_float", default=146.585e6,
33
                          help="set frequency to FREQ [default=%default])", metavar="FREQ")
34
        parser.add_option("-g", "--gain", type="eng_float", default=20,
35
                          help="set gain in dB [default=%default]")
36
        parser.add_option("-F", "--filter", action="store_true", default=True,
37
                          help="Enable channel filter")
38
        (options, args) = parser.parse_args()
39
40
        if len(args) != 0:
41
            parser.print_help()
42
            raise SystemExit
43
44
        nchan = 4
45
46
        if options.filter:
47
            sw_decim = 4
48
        else:
49
            sw_decim = 1
50
51
        self.u = usrp.source_c(0, options.decim, fpga_filename="std_4rx_0tx.rbf")
52
        if self.u.nddc() < nchan:
53
            sys.stderr.write('This code requires an FPGA build with %d DDCs.  This FPGA has only %d.\n' % (
54
                nchan, self.u.nddc()))
55
            raise SystemExit
56
                             
57
        if not self.u.set_nchannels(nchan):
58
            sys.stderr.write('set_nchannels(%d) failed\n' % (nchan,))
59
            raise SystemExit
60
        
61
        input_rate = self.u.adc_freq() / self.u.decim_rate()
62
        print "USB data rate   = %s" % (eng_notation.num_to_str(input_rate),)
63
        print "Scope data rate = %s" % (eng_notation.num_to_str(input_rate/sw_decim),)
64
65
        self.subdev = self.u.db[0] + self.u.db[1]
66
67
        if (len(self.subdev) != 4 or
68
            self.u.db[0][0].dbid() != usrp_dbid.BASIC_RX or
69
            self.u.db[1][0].dbid() != usrp_dbid.BASIC_RX):
70
            sys.stderr.write('This code requires a Basic Rx board on Sides A & B\n')
71
            sys.exit(1)
72
73
        self.u.set_mux(gru.hexint(0xf3f2f1f0))
74
75
        # deinterleave four channels from FPGA
76
        di = gr.deinterleave(gr.sizeof_gr_complex)
77
78
        self.connect(self.u, di)
79
        
80
        # our destination (8 float inputs)
81
        self.scope = scopesink2.scope_sink_f(panel, sample_rate=input_rate/sw_decim,
82
                                             num_inputs=2*nchan)
83
84
        # taps for channel filter
85
        chan_filt_coeffs = optfir.low_pass (1,           # gain
86
                                            input_rate,  # sampling rate
87
                                            80e3,        # passband cutoff
88
                                            115e3,       # stopband cutoff
89
                                            0.1,         # passband ripple
90
                                            60)          # stopband attenuation
91
        #print len(chan_filt_coeffs)
92
93
        # bust the deinterleaved complex channels into floats
94
        for i in range(nchan):
95
96
            if options.filter:
97
                chan_filt = gr.fir_filter_ccf(sw_decim, chan_filt_coeffs)
98
                c2f = gr.complex_to_float()
99
                self.connect((di, i), chan_filt, c2f)
100
            else:
101
                c2f = gr.complex_to_float()
102
                self.connect((di, i), c2f)
103
104
            self.connect((c2f, 0), (self.scope, 2*i + 0))
105
            self.connect((c2f, 1), (self.scope, 2*i + 1))
106
107
108
        self._build_gui(vbox)
109
110
        self.set_gain(options.gain)
111
        self.set_freq(options.freq)
112
113
    def set_gain(self, gain):
114
        for i in range(len(self.subdev)):
115
            self.subdev[i].set_gain(gain)
116
117
    def set_freq(self, target_freq):
118
        ok = True
119
        for i in range(len(self.subdev)):
120
            r = usrp.tune(self.u, i, self.subdev[i], target_freq)
121
            if not r:
122
                ok = False
123
                print "set_freq: failed to set subdev[%d] freq to %f" % (
124
                    i, target_freq)
125
126
        return ok
127
128
129
    def _build_gui(self, vbox):
130
        vbox.Add(self.scope.win, 10, wx.EXPAND)
131
        
132
133
134
def main ():
135
    app = stdgui2.stdapp(my_top_block, "Multi Scope", nstatus=1)
136
    app.MainLoop()
137
138
if __name__ == '__main__':
139
    main ()