commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r8786 - gnuradio/trunk/gr-msdd6000/src/python-examples


From: n4hy
Subject: [Commit-gnuradio] r8786 - gnuradio/trunk/gr-msdd6000/src/python-examples
Date: Thu, 3 Jul 2008 21:05:34 -0600 (MDT)

Author: n4hy
Date: 2008-07-03 21:05:33 -0600 (Thu, 03 Jul 2008)
New Revision: 8786

Added:
   gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_dynamics.py
   gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_fft.py
   gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_plot_psd.py
   gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_rcv.py
   gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_spectrum_sense.py
   gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_spectrum_waterfall.py
   gnuradio/trunk/gr-msdd6000/src/python-examples/new_msdd_fft.py
   gnuradio/trunk/gr-msdd6000/src/python-examples/playback_samples.m
   gnuradio/trunk/gr-msdd6000/src/python-examples/read_complex_binary.m
Log:
This completes the msdd6000 update with all example code and other utilities

Added: gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_dynamics.py
===================================================================
--- gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_dynamics.py             
                (rev 0)
+++ gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_dynamics.py     
2008-07-04 03:05:33 UTC (rev 8786)
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr
+from gnuradio import msdd
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import time
+
+class benchmark_msdd6000(gr.top_block):
+    def __init__(self, address, options):
+        gr.top_block.__init__(self)
+
+        # Extract the initial options
+        self.frequency = options.frequency
+        self.filename  = options.filename
+        self.decim     = options.decim
+        self.gain      = options.gain
+        self.address   = address
+
+        # Set up and initialize the MSDD receiver
+        self.port = 10001 # required port
+        self.src = msdd.source_c(0, 1, self.address, self.port)
+        self.src.set_decim_rate(self.decim)
+        self.src.set_desired_packet_size(0, 1460)
+        self.src.set_pga(0, self.gain)
+        self.src.set_rx_freq(0, self.frequency)
+
+        # Display some info
+        print "Min PGA: ", self.src.pga_min()
+        print "Max PGA: ", self.src.pga_max()
+        print "PGA:     ", self.src.pga(0)
+        print "Decim:   ", self.src.decim_rate()
+        print "Freq:    ", self.src.rx_freq(0)
+        
+        # Build a file sink to save the info for post analysis
+        self.snk = gr.file_sink(gr.sizeof_gr_complex, self.filename)
+
+        # Connect the reciever source to file sink
+        self.connect(self.src, self.snk)
+        
+def main():
+    ''' This is a simple little script to play with retunning of the MSDD 
board.
+    You can cycle through frequencies or the attenuation of the board here.
+    '''
+
+    usage="%prog: [options] host_address"
+    parser = OptionParser(usage=usage, option_class=eng_option, 
conflict_handler="resolve")
+    parser.add_option("-f", "--frequency", type="eng_float", default=100e6,
+                      help="set frequency (Hz) [default=%default]")
+    parser.add_option("-d", "--decim", type="int", default=256,
+                      help="set decimation rate [default=%default]")
+    parser.add_option("-g", "--gain", type="int", default=32,
+                      help="set receiver gain (dB) [default=%default]")
+    parser.add_option("-F", "--filename", type="string", default="output.dat",
+                      help="set output filename [default=%default]")
+    (options, args) = parser.parse_args ()
+    host_address = args[0]
+
+    # Set up benchmark system that simply connects the MSDD source to a file 
sink
+    tb = benchmark_msdd6000(host_address, options)
+    tb.start() # start it here
+
+    # Adjust your parameters here. Use the time.sleep(x) function to set a 
wait period
+    # between adjusting the parameter.
+    for i in range(7):
+        time.sleep(0.5)
+        if 0:
+            freq = (tb.src.rx_freq(0) + 1) * 1e6
+            tb.src.set_rx_freq(0, freq)
+            print "Setting frequency: ", freq
+        if 1:
+            pga = tb.src.pga(0)+10
+            tb.src.set_pga(0, pga)
+            print "Setting PGA: ", pga
+
+    tb.stop()  # stop the radio
+
+if __name__ == '__main__':
+    main()


Property changes on: 
gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_dynamics.py
___________________________________________________________________
Name: svn:executable
   + *

Added: gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_fft.py
===================================================================
--- gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_fft.py                  
        (rev 0)
+++ gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_fft.py  2008-07-04 
03:05:33 UTC (rev 8786)
@@ -0,0 +1,277 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005,2007 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gru
+from gnuradio import msdd
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, 
form, slider
+from optparse import OptionParser
+import wx
+import sys
+
+
+def pick_subdevice(u):
+    """
+    The user didn't specify a subdevice on the command line.
+    If there's a daughterboard on A, select A.
+    If there's a daughterboard on B, select B.
+    Otherwise, select A.
+    """
+    if u.db[0][0].dbid() >= 0:       # dbid is < 0 if there's no d'board or a 
problem
+        return (0, 0)
+    if u.db[1][0].dbid() >= 0:
+        return (1, 0)
+    return (0, 0)
+
+
+class app_top_block(stdgui2.std_top_block):
+    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("-w", "--which", type="int", default=0,
+                          help="select which MSDD (0, 1, ...) default is 
%default",
+                         metavar="NUM")
+        parser.add_option("-R", "--rx-subdev-spec", type="subdev", 
default=None,
+                          help="select MSDD Rx side A or B (default=first one 
with a daughterboard)")
+        parser.add_option("-A", "--antenna", default=None,
+                          help="select Rx Antenna (only on RFX-series boards)")
+        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("-W", "--waterfall", action="store_true", 
default=False,
+                          help="Enable waterfall display")
+        parser.add_option("-8", "--width-8", action="store_true", 
default=False,
+                          help="Enable 8-bit samples across USB")
+        parser.add_option("-S", "--oscilloscope", action="store_true", 
default=False,
+                          help="Enable oscilloscope display")
+        (options, args) = parser.parse_args()
+        if len(args) != 0:
+            parser.print_help()
+            sys.exit(1)
+
+        self.show_debug_info = True
+        
+        # build the graph
+
+        #self.u = MSDD.source_simo(which=options.which, 
decim_rate=options.decim)
+        self.u = msdd.source_simple("192.168.1.200", 0)
+        self.u.set_decim_rate(options.decim) #(16)
+
+#        msdd_src = gr.file_source(gr.sizeof_gr_complex, 'msdd.dat')
+#        thr = gr.throttle(gr.sizeof_gr_complex, 200000)
+#        self.connect(msdd_src, thr)
+
+#        if options.rx_subdev_spec is None:
+#           options.rx_subdev_spec = pick_subdevice(self.u)
+#        self.u.set_mux(MSDD.determine_rx_mux_value(self.u, 
options.rx_subdev_spec))
+
+#        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 = MSDD.selected_subdev(self.u, options.rx_subdev_spec)
+
+#        print "Initial Freq", self.u.rx_freq(0), "deci: ", self.u.decim_rate()
+#        input_rate = 50e6 / self.u.decim_rate()
+        input_rate = 50e6 / options.decim;
+
+        if options.waterfall:
+            self.scope = \
+              waterfallsink2.waterfall_sink_c (panel, fft_size=1024, 
sample_rate=input_rate)
+        elif options.oscilloscope:
+            self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate)
+        else:
+            self.scope = fftsink2.fft_sink_c (panel, fft_size=1024, 
sample_rate=input_rate)
+
+#        self.connect(self.u, self.scope)
+               
+        msdd_sink = gr.file_sink(gr.sizeof_gr_complex, 'schmen1.dat')
+       
+       self.conv = gr.interleaved_short_to_complex();
+        self.connect(self.u, self.conv,  msdd_sink)
+        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()
+            self.gain_range = (20,70,.5);
+           options.gain = float(self.gain_range[0]+self.gain_range[1])/2
+
+        if options.freq is None:
+            # if no freq was specified, use the mid-point
+            #r = self.subdev.freq_range()
+           r = (30e6,6e9,1e6)
+            options.freq = float(r[0]+r[1])/2
+
+        self.set_gain(options.gain)
+#
+#      if options.antenna is not None:
+#            print "Selecting antenna %s" % (options.antenna,)
+#            self.subdev.select_rx_antenna(options.antenna)
+
+        if self.show_debug_info:
+            #self.myform['decim'].set_value(self.u.decim_rate())
+            self.myform['decim'].set_value(options.decim)
+ #           self.myform['address@hidden'].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 not(self.set_freq(options.freq)):
+            self._set_status_msg("Failed to set initial frequency")
+
+    def _set_status_msg(self, msg):
+        self.frame.GetStatusBar().SetStatusText(msg, 0)
+
+    def _build_gui(self, vbox):
+
+        def _form_set_freq(kv):
+            return self.set_freq(kv['freq'])
+            
+        vbox.Add(self.scope.win, 10, wx.EXPAND)
+        
+        # add control area at the bottom
+        self.myform = myform = form.form()
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((5,0), 0, 0)
+        myform['freq'] = form.float_field(
+            parent=self.panel, sizer=hbox, label="Center freq", weight=1,
+            callback=myform.check_input_and_call(_form_set_freq, 
self._set_status_msg))
+
+        hbox.Add((5,0), 0, 0)
+        g = self.gain_range = (20,50,.5);
+        myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, 
label="Gain",
+                                           weight=3,
+                                           min=int(g[0]), max=int(g[1]),
+                                           callback=self.set_gain)
+
+        hbox.Add((5,0), 0, 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+        self._build_subpanel(vbox)
+
+    def _build_subpanel(self, vbox_arg):
+        # build a secondary information panel (sometimes hidden)
+
+        # FIXME figure out how to have this be a subpanel that is always
+        # created, but has its visibility controlled by foo.Show(True/False)
+        
+        def _form_set_decim(kv):
+            return self.set_decim(kv['decim'])
+
+        if not(self.show_debug_info):
+            return
+
+        panel = self.panel
+        vbox = vbox_arg
+        myform = self.myform
+
+        #panel = wx.Panel(self.panel, -1)
+        #vbox = wx.BoxSizer(wx.VERTICAL)
+
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((5,0), 0)
+
+        myform['decim'] = form.int_field(
+            parent=panel, sizer=hbox, label="Decim",
+            callback=myform.check_input_and_call(_form_set_decim, 
self._set_status_msg))
+
+#        hbox.Add((5,0), 1)
+#        myform['address@hidden'] = form.static_float_field(
+#            parent=panel, sizer=hbox, label="address@hidden")
+
+        hbox.Add((5,0), 1)
+        myform['dbname'] = form.static_text_field(
+            parent=panel, sizer=hbox)
+
+        hbox.Add((5,0), 1)
+        myform['baseband'] = form.static_float_field(
+            parent=panel, sizer=hbox, label="Analog BB")
+
+        hbox.Add((5,0), 1)
+        myform['ddc'] = form.static_float_field(
+            parent=panel, sizer=hbox, label="DDC")
+
+        hbox.Add((5,0), 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+        
+    def set_freq(self, target_freq):
+        """
+        Set the center frequency we're interested in.
+
+        @param target_freq: frequency in Hz
+        @rypte: bool
+
+        Tuning is a two step process.  First we ask the front-end to
+        tune as close to the desired frequency as it can.  Then we use
+        the result of that operation and our target_frequency to
+        determine the value for the digital down converter.
+        """
+       r = self.u.set_rx_freq  (0, target_freq)
+        #r = self.u.tune(0, self.subdev, target_freq)
+        if r:
+            self.myform['freq'].set_value(target_freq)     # update displayed 
value
+#            if self.show_debug_info:
+#                self.myform['baseband'].set_value(r.baseband_freq)
+#                self.myform['ddc'].set_value(r.dxc_freq)
+            return True
+
+        return False
+
+    def set_gain(self, gain):
+        self.myform['gain'].set_value(gain)     # update displayed value
+        #self.subdev.set_gain(gain)
+        self.u.set_pga(0, gain)
+
+    def set_decim(self, decim):
+        ok = self.u.set_decim_rate(decim)
+        if not ok:
+            print "set_decim failed"
+        #input_rate = 20e6 / self.u.decim_rate()
+        #self.scope.set_sample_rate(input_rate)
+        if self.show_debug_info:  # update displayed values
+            self.myform['decim'].set_value(decim)
+            #self.myform['address@hidden'].set_value(self.u.adc_freq() / 
self.u.decim_rate())
+        return ok
+
+def main ():
+    app = stdgui2.stdapp(app_top_block, "MSDD FFT", nstatus=1)
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main ()


Property changes on: gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_fft.py
___________________________________________________________________
Name: svn:executable
   + *

Added: gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_plot_psd.py
===================================================================
--- gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_plot_psd.py             
                (rev 0)
+++ gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_plot_psd.py     
2008-07-04 03:05:33 UTC (rev 8786)
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+
+address = "10.45.4.43";
+fc = 3.5;
+decim = 8;
+num_avg = 10
+
+fs = 102.4;
+packet_size=1400;
+gain = 0;
+port = 10001;
+
+import math;
+import time;
+import Numeric;
+from gnuradio import msdd,gr,window,wimax;
+from pylab import *;
+
+src = msdd.source_simple(address, port)  # build source object
+
+fft_size = 2048;
+
+w = window.blackmanharris(fft_size);
+s2v = gr.stream_to_vector(2*gr.sizeof_float, fft_size);
+fft = gr.fft_vcc(fft_size, True, w, True);
+conj = wimax.conj_vcc(fft_size);
+mul = gr.multiply_vcc(fft_size);
+norm = wimax.norm_cf();
+avg = wimax.average_vXX(gr.sizeof_float, 2*fft_size, num_avg);
+v2s = gr.vector_to_stream(2*gr.sizeof_float, fft_size);
+#sink = gr.vector_sink_f();
+
+src.set_decim_rate(decim);
+
+src.set_pga(0,gain);
+src.set_rx_freq(0,fc);
+
+q = gr.msg_queue(fft_size);
+sink = gr.message_sink(gr.sizeof_float, q, True);
+
+tb = gr.top_block();
+tb.connect(src,s2v,fft,(mul,0),avg,v2s,norm,sink);
+tb.connect(fft,conj,(mul,1));
+
+tb.start();
+
+print "running"
+
+v = []
+x = [];
+
+bw = fs/(pow(2,decim));
+for i in range(0,fft_size):
+       norm_freq = (i - fft_size/2.0)/fft_size;
+       bin_frequency = fc + norm_freq * bw;
+       x.append( norm_freq );
+
+
+
+for i in range(0,fft_size):
+
+       d = q.delete_head();
+       d =  d.to_string();
+       d =  Numeric.fromstring(d, Numeric.Float32);
+       d = 10*log10(d);
+
+       print "plotting\n";
+       plot(x,d);
+       show();
+       print "done\n"
+
+
+
+


Property changes on: 
gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_plot_psd.py
___________________________________________________________________
Name: svn:executable
   + *

Added: gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_rcv.py
===================================================================
--- gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_rcv.py                  
        (rev 0)
+++ gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_rcv.py  2008-07-04 
03:05:33 UTC (rev 8786)
@@ -0,0 +1,287 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2006,2007 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gru, eng_notation
+from gnuradio import msdd
+from gnuradio import blks2
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import slider, powermate
+from gnuradio.wxgui import stdgui2, form
+from gnuradio.wxgui import fftsink2
+from optparse import OptionParser
+#from usrpm import usrp_dbid
+import sys
+import math
+import wx
+
+class wfm_rx_block (stdgui2.std_top_block):
+    def __init__(self,frame,panel,vbox,argv):
+        stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv)
+
+        parser=OptionParser(option_class=eng_option)        
+#        parser.add_option("-R", "--rx-subdev-spec", type="subdev", 
default=None,
+#                          help="select MSDD Rx side A or B (default=A)")
+        parser.add_option("-f", "--freq", type="eng_float", default=100.1e6,
+                          help="set frequency to FREQ", metavar="FREQ")
+        parser.add_option("-g", "--gain", type="eng_float", default=40,
+                          help="set gain in dB (default is midpoint)")
+#        parser.add_option("-V", "--volume", type="eng_float", default=None,
+#                          help="set volume (default is midpoint)")
+#        parser.add_option("-O", "--audio-output", type="string", default="",
+#                          help="pcm device name.  E.g., hw:0,0 or surround51 
or /dev/dsp")
+
+        (options, args) = parser.parse_args()
+        if len(args) != 0:
+            parser.print_help()
+            sys.exit(1)
+        
+        self.frame = frame
+        self.panel = panel
+        
+        self.vol = 0
+        self.gain_range = (10, 70, .5)
+        self.state = "FREQ"
+        self.freq = 0
+        msdd_decim = 2
+
+        # build graph
+        self.fft_size = 8192
+        self.sample_rate = 200
+        self.u = msdd.source_c(0, 1, "10.45.4.44", 10000)
+        self.u.set_decim_rate(4)
+        self.u.set_desired_packet_size(0, 1460*100)        
+
+
+        #self.u.set_decim_rate(msdd_decim)
+#        usrp_rate = adc_rate / msdd_decim           # 320 kS/s
+#        chanfilt_decim = 1
+#        demod_rate = usrp_rate / chanfilt_decim
+#        audio_decimation = 10
+#        audio_rate = demod_rate / audio_decimation  # 32 kHz
+#
+#        if options.rx_subdev_spec is None:
+#            options.rx_subdev_spec = pick_subdevice(self.u)
+#
+#        self.u.set_mux(usrp.determine_rx_mux_value(self.u, 
options.rx_subdev_spec))
+#        self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+#        print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+#
+#
+#        chan_filt_coeffs = optfir.low_pass (1,           # gain
+#                                            usrp_rate,   # sampling rate
+#                                            80e3,        # passband cutoff
+#                                            115e3,       # stopband cutoff
+#                                            0.1,         # passband ripple
+#                                            60)          # stopband 
attenuation
+#        #print len(chan_filt_coeffs)
+#        chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs)
+#
+#        self.guts = blks2.wfm_rcv (demod_rate, audio_decimation)
+#
+#        self.volume_control = gr.multiply_const_ff(self.vol)
+#
+#        # sound card as final sink
+#        audio_sink = audio.sink (int (audio_rate),
+#                                 options.audio_output,
+#                                 False)  # ok_to_block
+        
+        # now wire it all together
+        #self.connect (self.u, chan_filt, self.guts, self.volume_control, 
audio_sink)
+
+        self._build_gui(vbox)
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            #g = self.subdev.gain_range()
+            g = self.gain_range
+            options.gain = float(g[0]+g[1])/2
+#
+#        if options.volume is None:
+#            g = self.volume_range()
+#            options.volume = float(g[0]+g[1])/2
+#            
+#        if abs(options.freq) < 1e6:
+#            options.freq *= 1e6
+
+        # set initial values
+#
+        self.set_gain(options.gain)
+#        self.set_vol(options.volume)
+        if not(self.set_freq(options.freq)):
+            self._set_status_msg("Failed to set initial frequency")
+        print "Frequency: ", self.u.rx_freq(0)
+
+
+    def _set_status_msg(self, msg, which=0):
+        self.frame.GetStatusBar().SetStatusText(msg, which)
+
+
+    def _build_gui(self, vbox):
+
+        def _form_set_freq(kv):
+            return self.set_freq(kv['freq'])
+
+        self.src_fft = None
+        if 1:
+            self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from 
MSDD",
+                                               fft_size=512, sample_rate=512)
+#            self.s2f1 = gr.short_to_float()
+#            self.scope = scopesink2.scope_sink_f(self.panel, 
sample_rate=self.sample_rate*self.fft_size)
+            
+            self.connect (self.u, self.src_fft)
+            #self.connect (self.s2f1, self.scope)
+            vbox.Add (self.src_fft.win, 4, wx.EXPAND)
+#
+#        if 1:
+#            post_filt_fft = fftsink2.fft_sink_f(self.panel, title="Post 
Demod", 
+#                                                fft_size=1024, 
sample_rate=usrp_rate,
+#                                                y_per_div=10, ref_level=0)
+#            self.connect (self.guts.fm_demod, post_filt_fft)
+#            vbox.Add (post_filt_fft.win, 4, wx.EXPAND)
+#
+#        if 0:
+#            post_deemph_fft = fftsink2.fft_sink_f(self.panel, title="Post 
Deemph",
+#                                                  fft_size=512, 
sample_rate=audio_rate,
+#                                                  y_per_div=10, ref_level=-20)
+#            self.connect (self.guts.deemph, post_deemph_fft)
+#            vbox.Add (post_deemph_fft.win, 4, wx.EXPAND)
+
+        
+        # control area form at bottom
+        self.myform = myform = form.form()
+
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((5,0), 0)
+        myform['freq'] = form.float_field(
+            parent=self.panel, sizer=hbox, label="Freq", weight=1,
+            callback=myform.check_input_and_call(_form_set_freq, 
self._set_status_msg))
+
+        hbox.Add((5,0), 0)
+        myform['freq_slider'] = \
+            form.quantized_slider_field(parent=self.panel, sizer=hbox, 
weight=3,
+                                        range=(30e6, 6e9, 1e6),
+                                        callback=self.set_freq)
+        hbox.Add((5,0), 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((5,0), 0)
+#
+#        myform['volume'] = \
+#            form.quantized_slider_field(parent=self.panel, sizer=hbox, 
label="Volume",
+#                                        weight=3, range=self.volume_range(),
+#                                        callback=self.set_vol)
+#        hbox.Add((5,0), 1)
+
+        myform['gain'] = \
+            form.quantized_slider_field(parent=self.panel, sizer=hbox, 
label="Gain",
+                                        weight=3, range=self.gain_range,
+                                        callback=self.set_gain)
+        hbox.Add((5,0), 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+#
+#        try:
+#            self.knob = powermate.powermate(self.frame)
+#            self.rot = 0
+#            powermate.EVT_POWERMATE_ROTATE (self.frame, self.on_rotate)
+#            powermate.EVT_POWERMATE_BUTTON (self.frame, self.on_button)
+#        except:
+#            print "FYI: No Powermate or Contour Knob found"
+
+
+    def on_rotate (self, event):
+        self.rot += event.delta
+        if (self.state == "FREQ"):
+            if self.rot >= 3:
+                self.set_freq(self.freq + .1e6)
+                self.rot -= 3
+            elif self.rot <=-3:
+                self.set_freq(self.freq - .1e6)
+                self.rot += 3
+        else:
+            step = self.volume_range()[2]
+            if self.rot >= 3:
+                self.set_vol(self.vol + step)
+                self.rot -= 3
+            elif self.rot <=-3:
+                self.set_vol(self.vol - step)
+                self.rot += 3
+            
+    def on_button (self, event):
+        if event.value == 0:        # button up
+            return
+        self.rot = 0
+        if self.state == "FREQ":
+            self.state = "VOL"
+        else:
+            self.state = "FREQ"
+        self.update_status_bar ()
+#        
+#
+#    def set_vol (self, vol):
+#        g = self.volume_range()
+#        self.vol = max(g[0], min(g[1], vol))
+#        self.volume_control.set_k(10**(self.vol/10))
+#        self.myform['volume'].set_value(self.vol)
+#        self.update_status_bar ()
+                                        
+    def set_freq(self, target_freq):
+        """
+        Set the center frequency we're interested in.
+
+        @param target_freq: frequency in Hz
+        @rypte: bool
+
+        Tuning is a two step process.  First we ask the front-end to
+        tune as close to the desired frequency as it can.  Then we use
+        the result of that operation and our target_frequency to
+        determine the value for the digital down converter.
+        """
+        r = self.u.set_rx_freq(0, target_freq);
+        
+        if r:
+            self.freq = target_freq
+            self.myform['freq'].set_value(target_freq)         # update 
displayed value
+            self.myform['freq_slider'].set_value(target_freq)  # update 
displayed value
+            self.update_status_bar()
+            self._set_status_msg("OK", 0)
+            return True
+
+        self._set_status_msg("Failed", 0)
+        return False
+
+    def set_gain(self, gain):
+        self.myform['gain'].set_value(gain)     # update displayed value
+        self.u.set_pga(0,gain)
+        
+    def update_status_bar (self):
+        msg = "Volume:%r  Setting:%s" % (self.vol, self.state)
+        self._set_status_msg(msg, 1)
+        #self.src_fft.set_baseband_freq(self.freq)
+#
+#    def volume_range(self):
+#        return (-20.0, 0.0, 0.5)
+        
+
+if __name__ == '__main__':
+    app = stdgui2.stdapp (wfm_rx_block, "MSDD FFT RX")
+    app.MainLoop ()


Property changes on: gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_rcv.py
___________________________________________________________________
Name: svn:executable
   + *

Added: gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_spectrum_sense.py
===================================================================
--- gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_spectrum_sense.py       
                        (rev 0)
+++ gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_spectrum_sense.py       
2008-07-04 03:05:33 UTC (rev 8786)
@@ -0,0 +1,296 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gru, eng_notation, optfir, window
+from gnuradio import msdd
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+import struct
+from pylab import *
+from numpy import array
+import time
+
+matplotlib.interactive(True)
+matplotlib.use('TkAgg')
+
+class tune(gr.feval_dd):
+    """
+    This class allows C++ code to callback into python.
+    """
+    def __init__(self, tb):
+        gr.feval_dd.__init__(self)
+        self.tb = tb
+
+    def eval(self, ignore):
+        """
+        This method is called from gr.bin_statistics_f when it wants to change
+        the center frequency.  This method tunes the front end to the new 
center
+        frequency, and returns the new frequency as its result.
+        """
+        try:
+            # We use this try block so that if something goes wrong from here 
+            # down, at least we'll have a prayer of knowing what went wrong.
+            # Without this, you get a very mysterious:
+            #
+            #   terminate called after throwing an instance of 
'Swig::DirectorMethodException'
+            #   Aborted
+            #
+            # message on stderr.  Not exactly helpful ;)
+
+            new_freq = self.tb.set_next_freq()
+            return new_freq
+
+        except Exception, e:
+            print "tune: Exception: ", e
+
+
+class parse_msg(object):
+    def __init__(self, sample_rate, percent, alpha=0.01):
+        self.axis_font_size = 16
+        self.label_font_size = 18
+        self.title_font_size = 20
+        self.text_size = 22
+
+        self.fig = figure(1, facecolor="w", figsize=(12,9))
+        self.sp  = self.fig.add_subplot(1,1,1)
+        self.pl  = self.sp.plot(range(100), 100*[1,])
+
+        params = {'backend': 'ps',
+                  'xtick.labelsize': self.axis_font_size,
+                  'ytick.labelsize': self.axis_font_size,
+                  'text.usetex': False}
+        rcParams.update(params)
+
+        self.sp.set_title(("FFT"), fontsize=self.title_font_size, 
fontweight="bold")
+        self.sp.set_xlabel("Frequency (Hz)", fontsize=self.label_font_size, 
fontweight="bold")
+        self.sp.set_ylabel("Magnitude (dB)", fontsize=self.label_font_size, 
fontweight="bold")
+        self.text_alpha = figtext(0.10, 0.94, ('Moving average alpha: %s' % 
alpha), weight="heavy", size=self.text_size)
+
+        self.cfreqs = list()
+        self.freqrange = list()
+        self.data = list() #array('f')
+
+        self.alpha = alpha
+
+        self.index = 0
+        self.full = False
+        self.last_cfreq = 0
+        
+        self.sample_rate = sample_rate
+        self.percent = (1.0-percent)/2.0
+        
+    def parse(self, msg):
+        self.center_freq = msg.arg1()
+        self.vlen = int(msg.arg2())
+        assert(msg.length() == self.vlen * gr.sizeof_float)
+
+
+        if(self.center_freq < self.last_cfreq):
+            print "Plotting spectrum\n"
+            self.full = True
+
+            self.pl[0].set_data([self.freqrange, self.data])
+            self.sp.set_ylim([min(self.data), max(self.data)])
+            self.sp.set_xlim([min(self.freqrange), max(self.freqrange)])
+            draw()
+
+            self.index = 0
+            del self.freqrange
+            self.freqrange = list()
+            #raw_input()
+
+        self.last_cfreq = self.center_freq
+
+        startind = int(self.percent * self.vlen)
+        endind = int((1.0 - self.percent) * self.vlen)
+        
+        fstep = self.sample_rate / self.vlen
+        f = [self.center_freq - self.sample_rate/2.0 + i*fstep for i in 
range(startind, endind)]
+        self.freqrange += f
+
+        t = msg.to_string()
+        d = struct.unpack('%df' % (self.vlen,), t)
+
+        if self.full:
+            for i in range(startind, endind):
+                self.data[self.index] = (1.0-self.alpha)*self.data[self.index] 
+ (self.alpha)*d[i]
+                self.index += 1
+        else:
+            self.data += [di for di in d[startind:endind]]
+        
+
+class my_top_block(gr.top_block):
+
+    def __init__(self):
+        gr.top_block.__init__(self)
+
+        usage = "usage: %prog [options] host min_freq max_freq"
+        parser = OptionParser(option_class=eng_option, usage=usage)
+        parser.add_option("-g", "--gain", type="eng_float", default=None,
+                          help="set gain in dB (default is midpoint)")
+        parser.add_option("", "--tune-delay", type="eng_float", default=5e-5, 
metavar="SECS",
+                          help="time to delay (in seconds) after changing 
frequency [default=%default]")
+        parser.add_option("", "--dwell-delay", type="eng_float", 
default=50e-5, metavar="SECS",
+                          help="time to dwell (in seconds) at a given frequncy 
[default=%default]")
+        parser.add_option("-F", "--fft-size", type="int", default=256,
+                          help="specify number of FFT bins [default=%default]")
+        parser.add_option("-d", "--decim", type="intx", default=16,
+                          help="set decimation to DECIM [default=%default]")
+        parser.add_option("", "--real-time", action="store_true", 
default=False,
+                          help="Attempt to enable real-time scheduling")
+
+        (options, args) = parser.parse_args()
+        if len(args) != 3:
+            parser.print_help()
+            sys.exit(1)
+
+        self.address  = args[0]
+        self.min_freq = eng_notation.str_to_num(args[1])
+        self.max_freq = eng_notation.str_to_num(args[2])
+
+        self.decim = options.decim
+        self.gain  = options.gain
+        
+        if self.min_freq > self.max_freq:
+            self.min_freq, self.max_freq = self.max_freq, self.min_freq   # 
swap them
+
+       self.fft_size = options.fft_size
+
+        if not options.real_time:
+            realtime = False
+        else:
+            # Attempt to enable realtime scheduling
+            r = gr.enable_realtime_scheduling()
+            if r == gr.RT_OK:
+                realtime = True
+            else:
+                realtime = False
+                print "Note: failed to enable realtime scheduling"
+
+        adc_rate = 102.4e6
+        self.int_rate = adc_rate / self.decim
+        print "Sampling rate: ", self.int_rate
+
+        # build graph
+        self.port = 10001
+        self.src = msdd.source_simple(self.address, self.port)
+        self.src.set_decim_rate(self.decim)
+
+        self.set_gain(self.gain)
+        self.set_freq(self.min_freq)
+
+       s2v = gr.stream_to_vector(gr.sizeof_gr_complex, self.fft_size)
+
+        mywindow = window.blackmanharris(self.fft_size)
+        fft = gr.fft_vcc(self.fft_size, True, mywindow, True)
+        power = 0
+        for tap in mywindow:
+            power += tap*tap
+        
+        norm = gr.multiply_const_cc(1.0/self.fft_size)
+        c2mag = gr.complex_to_mag_squared(self.fft_size)
+
+        # FIXME the log10 primitive is dog slow
+        log = gr.nlog10_ff(10, self.fft_size,
+                           
-20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size))
+               
+        # Set the freq_step to % of the actual data throughput.
+        # This allows us to discard the bins on both ends of the spectrum.
+        self.percent = 0.4
+
+        self.freq_step = self.percent * self.int_rate
+        self.min_center_freq = self.min_freq + self.freq_step/2
+        nsteps = math.ceil((self.max_freq - self.min_freq) / self.freq_step)
+        self.max_center_freq = self.min_center_freq + (nsteps * self.freq_step)
+
+        self.next_freq = self.min_center_freq
+        
+        tune_delay  = max(0, int(round(options.tune_delay * self.int_rate / 
self.fft_size)))  # in fft_frames
+        dwell_delay = max(1, int(round(options.dwell_delay * self.int_rate / 
self.fft_size))) # in fft_frames
+
+        self.msgq = gr.msg_queue(16)
+        self._tune_callback = tune(self)        # hang on to this to keep it 
from being GC'd
+        stats = gr.bin_statistics_f(self.fft_size, self.msgq,
+                                    self._tune_callback, tune_delay, 
dwell_delay)
+
+        # FIXME leave out the log10 until we speed it up
+       self.connect(self.src, s2v, fft, c2mag, log, stats)
+
+
+    def set_next_freq(self):
+        target_freq = self.next_freq
+        self.next_freq = self.next_freq + self.freq_step
+        if self.next_freq >= self.max_center_freq:
+            self.next_freq = self.min_center_freq
+
+        if not self.set_freq(target_freq):
+            print "Failed to set frequency to", target_freq
+
+        return target_freq
+                          
+
+    def set_freq(self, target_freq):
+        """
+        Set the center frequency we're interested in.
+
+        @param target_freq: frequency in Hz
+        @rypte: bool
+
+        """
+        return self.src.set_rx_freq(0, target_freq)
+
+
+    def set_gain(self, gain):
+        self.src.set_pga(0, gain)
+
+
+def main_loop(tb):
+    msgparser = parse_msg(tb.int_rate, tb.percent)
+    
+    while 1:
+
+        # Get the next message sent from the C++ code (blocking call).
+        # It contains the center frequency and the mag squared of the fft
+        msgparser.parse(tb.msgq.delete_head())
+
+        # Print center freq so we know that something is happening...
+        print msgparser.center_freq
+
+        # FIXME do something useful with the data...
+        
+        # m.data are the mag_squared of the fft output (they are in the
+        # standard order.  I.e., bin 0 == DC.)
+        # You'll probably want to do the equivalent of "fftshift" on them
+        # m.raw_data is a string that contains the binary floats.
+        # You could write this as binary to a file.
+
+    
+if __name__ == '__main__':
+    tb = my_top_block()
+    try:
+        tb.start()              # start executing flow graph in another 
thread...
+        main_loop(tb)
+        
+    except KeyboardInterrupt:
+        pass


Property changes on: 
gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_spectrum_sense.py
___________________________________________________________________
Name: svn:executable
   + *

Added: gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_spectrum_waterfall.py
===================================================================
--- gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_spectrum_waterfall.py   
                        (rev 0)
+++ gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_spectrum_waterfall.py   
2008-07-04 03:05:33 UTC (rev 8786)
@@ -0,0 +1,306 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gru, eng_notation, optfir, window
+from gnuradio import msdd
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+import struct
+from pylab import *
+from numpy import array
+import time
+
+matplotlib.interactive(True)
+matplotlib.use('TkAgg')
+
+class tune(gr.feval_dd):
+    """
+    This class allows C++ code to callback into python.
+    """
+    def __init__(self, tb):
+        gr.feval_dd.__init__(self)
+        self.tb = tb
+
+    def eval(self, ignore):
+        """
+        This method is called from gr.bin_statistics_f when it wants to change
+        the center frequency.  This method tunes the front end to the new 
center
+        frequency, and returns the new frequency as its result.
+        """
+        try:
+            # We use this try block so that if something goes wrong from here 
+            # down, at least we'll have a prayer of knowing what went wrong.
+            # Without this, you get a very mysterious:
+            #
+            #   terminate called after throwing an instance of 
'Swig::DirectorMethodException'
+            #   Aborted
+            #
+            # message on stderr.  Not exactly helpful ;)
+
+            new_freq = self.tb.set_next_freq()
+            return new_freq
+
+        except Exception, e:
+            print "tune: Exception: ", e
+
+
+class parse_msg(object):
+    def __init__(self, sample_rate, percent):
+        self.axis_font_size = 16
+        self.label_font_size = 18
+        self.title_font_size = 20
+        self.text_size = 22
+
+        # Set up figures and subplots
+        self.fig = figure(1, facecolor="w", figsize=(12,9))
+        self.sp  = self.fig.add_subplot(1,1,1)
+        self.pl  = self.sp.matshow(100*[range(100),])
+
+        params = {'xtick.labelsize': self.axis_font_size,
+                  'ytick.labelsize': self.axis_font_size}
+        rcParams.update(params)
+
+        # Throw up some title info
+        self.sp.set_title(("FFT"), fontsize=self.title_font_size, 
fontweight="bold")
+        self.sp.set_xlabel("Frequency (Hz)", fontsize=self.label_font_size, 
fontweight="bold")
+        self.sp.set_ylabel("Sample index (should be time)", 
fontsize=self.label_font_size, fontweight="bold")
+
+        self.freqrange = list()
+        self.data = list()
+        self.data3 = list()
+
+        self.index = 0
+        self.last_cfreq = 0
+
+        # So we know how to splice the data
+        self.sample_rate = sample_rate
+        self.percent = (1.0-percent)/2.0
+        
+    def parse(self, msg):
+        self.center_freq = msg.arg1()    # read the current center frequency
+        self.vlen = int(msg.arg2())      # read the length of the data set 
received
+
+        # wait until we wrap around before plotting the entire collected band
+        if(self.center_freq < self.last_cfreq):
+            #print "Plotting spectrum\n"
+
+            # If we have 100 sets, start dropping the oldest
+            if(len(self.data3) > 100):
+                self.data3.pop(0)
+            self.data3.append(self.data)
+
+            # add the new data to the plot
+            self.pl.set_data(self.data3)
+            draw()
+
+            # reset lists to collect next round
+            self.index = 0
+            del self.freqrange
+            self.freqrange = list()
+            del self.data
+            self.data = list()
+            #raw_input()
+
+        self.last_cfreq = self.center_freq
+
+        startind = int(self.percent * self.vlen)
+        endind = int((1.0 - self.percent) * self.vlen)
+        
+        fstep = self.sample_rate / self.vlen
+        f = [self.center_freq - self.sample_rate/2.0 + i*fstep for i in 
range(startind, endind)]
+        self.freqrange += f
+
+        t = msg.to_string();
+
+        d = struct.unpack('%df' % (self.vlen,), t)
+
+        self.data += [di for di in d[startind:endind]]
+        
+
+class my_top_block(gr.top_block):
+    def __init__(self):
+        gr.top_block.__init__(self)
+
+        # Build an options parser to bring in information from the user on 
usage
+        usage = "usage: %prog [options] host min_freq max_freq"
+        parser = OptionParser(option_class=eng_option, usage=usage)
+        parser.add_option("-g", "--gain", type="eng_float", default=32,
+                          help="set gain in dB (default is midpoint)")
+        parser.add_option("", "--tune-delay", type="eng_float", default=5e-5, 
metavar="SECS",
+                          help="time to delay (in seconds) after changing 
frequency [default=%default]")
+        parser.add_option("", "--dwell-delay", type="eng_float", 
default=50e-5, metavar="SECS",
+                          help="time to dwell (in seconds) at a given frequncy 
[default=%default]")
+        parser.add_option("-F", "--fft-size", type="int", default=256,
+                          help="specify number of FFT bins [default=%default]")
+        parser.add_option("-d", "--decim", type="intx", default=16,
+                          help="set decimation to DECIM [default=%default]")
+        parser.add_option("", "--real-time", action="store_true", 
default=False,
+                          help="Attempt to enable real-time scheduling")
+
+        (options, args) = parser.parse_args()
+        if len(args) != 3:
+            parser.print_help()
+            sys.exit(1)
+
+        # get user-provided info on address of MSDD and frequency to sweep
+        self.address  = args[0]
+        self.min_freq = eng_notation.str_to_num(args[1])
+        self.max_freq = eng_notation.str_to_num(args[2])
+
+        self.decim = options.decim
+        self.gain  = options.gain
+        
+        if self.min_freq > self.max_freq:
+            self.min_freq, self.max_freq = self.max_freq, self.min_freq   # 
swap them
+
+       self.fft_size = options.fft_size
+
+        if not options.real_time:
+            realtime = False
+        else:
+            # Attempt to enable realtime scheduling
+            r = gr.enable_realtime_scheduling()
+            if r == gr.RT_OK:
+                realtime = True
+            else:
+                realtime = False
+                print "Note: failed to enable realtime scheduling"
+
+        # Sampling rate is hardcoded and cannot be read off device
+        adc_rate = 102.4e6
+        self.int_rate = adc_rate / self.decim
+        print "Sampling rate: ", self.int_rate
+
+        # build graph
+        self.port = 10001   # required port for UDP packets
+       
+       #       which board,    op mode,        adx,    port
+#        self.src = msdd.source_c(0, 1, self.address, self.port)  # build 
source object
+
+       self.conv = gr.interleaved_short_to_complex();
+
+       self.src = msdd.source_simple(self.address,self.port);
+        self.src.set_decim_rate(self.decim)                      # set 
decimation rate
+#        self.src.set_desired_packet_size(0, 1460)                # set packet 
size to collect
+
+        self.set_gain(self.gain)                                 # set 
receiver's attenuation
+        self.set_freq(self.min_freq)                             # set 
receiver's rx frequency
+        
+        # restructure into vector format for FFT input
+       s2v = gr.stream_to_vector(gr.sizeof_gr_complex, self.fft_size)
+
+        # set up FFT processing block
+        mywindow = window.blackmanharris(self.fft_size)
+        fft = gr.fft_vcc(self.fft_size, True, mywindow, True)
+        power = 0
+        for tap in mywindow:
+            power += tap*tap
+        
+        # calculate magnitude squared of output of FFT
+        c2mag = gr.complex_to_mag_squared(self.fft_size)
+
+        # FIXME the log10 primitive is dog slow
+        log = gr.nlog10_ff(10, self.fft_size,
+                           
-20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size))
+               
+        # Set the freq_step to % of the actual data throughput.
+        # This allows us to discard the bins on both ends of the spectrum.
+        self.percent = 0.4
+
+        # Calculate the frequency steps to use in the collection over the 
whole bandwidth
+        self.freq_step = self.percent * self.int_rate
+        self.min_center_freq = self.min_freq + self.freq_step/2
+        nsteps = math.ceil((self.max_freq - self.min_freq) / self.freq_step)
+        self.max_center_freq = self.min_center_freq + (nsteps * self.freq_step)
+
+        self.next_freq = self.min_center_freq
+        
+        # use these values to set receiver settling time between samples and 
sampling time
+        # the default values provided seem to work well with the MSDD over 100 
Mbps ethernet
+        tune_delay  = max(0, int(round(options.tune_delay * self.int_rate / 
self.fft_size)))  # in fft_frames
+        dwell_delay = max(1, int(round(options.dwell_delay * self.int_rate / 
self.fft_size))) # in fft_frames
+
+        # set up message callback routine to get data from bin_statistics_f 
block
+        self.msgq = gr.msg_queue(16)
+        self._tune_callback = tune(self)        # hang on to this to keep it 
from being GC'd
+
+        # FIXME this block doesn't like to work with negatives because of the 
"d_max[i]=0" on line
+        # 151 of gr_bin_statistics_f.cc file. Set this to -10000 or something 
to get it to work.
+        stats = gr.bin_statistics_f(self.fft_size, self.msgq,
+                                    self._tune_callback, tune_delay, 
dwell_delay)
+
+        # FIXME there's a concern over the speed of the log calculation
+        # We can probably calculate the log inside the stats block
+       self.connect(self.src, self.conv, s2v, fft, c2mag, log, stats)
+
+
+    def set_next_freq(self):
+        ''' Find and set the next frequency of the reciver. After going past 
the maximum frequency,
+        the frequency is wrapped around to the start again'''
+        target_freq = self.next_freq
+        self.next_freq = self.next_freq + self.freq_step
+        if self.next_freq >= self.max_center_freq:
+            self.next_freq = self.min_center_freq
+
+        if not self.set_freq(target_freq):
+            print "Failed to set frequency to", target_freq
+
+        return target_freq
+                          
+
+    def set_freq(self, target_freq):
+        """
+        Set the center frequency we're interested in.
+
+        @param target_freq: frequency in Hz
+        @rypte: bool
+
+        """
+        return self.src.set_rx_freq(0, target_freq)
+
+
+    def set_gain(self, gain):
+        self.src.set_pga(0, gain)
+
+
+def main_loop(tb):
+    # Set up parser to get data from stats block and display them.
+    msgparser = parse_msg(tb.int_rate, tb.percent)
+    
+    while 1:
+        # Get the next message sent from the C++ code (blocking call).
+        # It contains the center frequency and the mag squared of the fft
+       d = tb.msgq.delete_head();
+       print d.to_string();
+        msgparser.parse(d)
+        #print msgparser.center_freq
+    
+if __name__ == '__main__':
+    tb = my_top_block()
+    try:
+        tb.start()              # start executing flow graph in another 
thread...
+        main_loop(tb)
+        
+    except KeyboardInterrupt:
+        pass


Property changes on: 
gnuradio/trunk/gr-msdd6000/src/python-examples/msdd_spectrum_waterfall.py
___________________________________________________________________
Name: svn:executable
   + *

Added: gnuradio/trunk/gr-msdd6000/src/python-examples/new_msdd_fft.py
===================================================================
--- gnuradio/trunk/gr-msdd6000/src/python-examples/new_msdd_fft.py              
                (rev 0)
+++ gnuradio/trunk/gr-msdd6000/src/python-examples/new_msdd_fft.py      
2008-07-04 03:05:33 UTC (rev 8786)
@@ -0,0 +1,299 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005,2007,2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+from gnuradio import msdd
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, 
form, slider
+from optparse import OptionParser
+import wx
+import sys
+import numpy
+
+def pick_subdevice(u):
+    """
+    The user didn't specify a subdevice on the command line.
+    If there's a daughterboard on A, select A.
+    If there's a daughterboard on B, select B.
+    Otherwise, select A.
+    """
+    return (0, 0)
+
+
+class app_top_block(stdgui2.std_top_block):
+    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("-w", "--which", type="int", default=0,
+                          help="select which USRP (0, 1, ...) default is 
%default",
+                         metavar="NUM")
+        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("-A", "--antenna", default=None,
+                          help="select Rx Antenna (only on RFX-series boards)")
+        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("-W", "--waterfall", action="store_true", 
default=False,
+                          help="Enable waterfall display")
+        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("-S", "--oscilloscope", action="store_true", 
default=False,
+                          help="Enable oscilloscope display")
+       parser.add_option("", "--avg-alpha", type="eng_float", default=1e-1,
+                         help="Set fftsink averaging factor, 
default=[%default]")
+       parser.add_option("", "--ref-scale", type="eng_float", default=13490.0,
+                         help="Set dBFS=0dB input value, default=[%default]")
+        (options, args) = parser.parse_args()
+        if len(args) != 0:
+            parser.print_help()
+            sys.exit(1)
+       self.options = options
+        self.show_debug_info = True
+        
+        # build the graph
+        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(which=options.which, 
decim_rate=options.decim, fpga_filename=self.fpga_filename)
+         self.u = msdd.source_simple("192.168.1.200",0);
+        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(which=options.which, 
decim_rate=options.decim)
+         self.u = msdd.source_simple("192.168.1.200",0);
+
+            
+        input_rate = self.u.adc_freq() / self.u.decim_rate()
+
+        if options.waterfall:
+            self.scope = \
+              waterfallsink2.waterfall_sink_c (panel, fft_size=1024, 
sample_rate=input_rate)
+        elif options.oscilloscope:
+            self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate)
+        else:
+            self.scope = fftsink2.fft_sink_c (panel, fft_size=1024, 
sample_rate=input_rate, 
+                                             ref_scale=options.ref_scale, 
ref_level=0.0, y_divs = 10,
+                                             avg_alpha=options.avg_alpha)
+
+       self.conv = gr.interleaved_short_to_complex();
+        self.connect(self.u, self.conv,  self.scope)
+
+        self._build_gui(vbox)
+       self._setup_events()
+       
+        # set initial values
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            #g = self.subdev.gain_range()
+            #g = self.u.gain_range()
+            g = [0,10]
+            options.gain = float(g[0]+g[1])/2
+
+        if options.freq is None:
+            # if no freq was specified, use the mid-point
+            #r = self.subdev.freq_range()
+            #r = self.u.freq_range()
+           r = [30e6, 6e9]
+            options.freq = float(r[0]+r[1])/2
+
+        self.set_gain(options.gain)
+
+       if options.antenna is not None:
+            print "Selecting antenna %s" % (options.antenna,)
+            self.subdev.select_rx_antenna(options.antenna)
+
+        if self.show_debug_info:
+            self.myform['decim'].set_value(self.u.decim_rate())
+            self.myform['address@hidden'].set_value(self.u.adc_freq() / 
self.u.decim_rate())
+            self.myform['dbname'].set_value("no subdevs used")
+            self.myform['baseband'].set_value(0)
+            self.myform['ddc'].set_value(0)
+
+        if not(self.set_freq(options.freq)):
+            self._set_status_msg("Failed to set initial frequency")
+
+    def _set_status_msg(self, msg):
+        self.frame.GetStatusBar().SetStatusText(msg, 0)
+
+    def _build_gui(self, vbox):
+
+        def _form_set_freq(kv):
+            return self.set_freq(kv['freq'])
+            
+        vbox.Add(self.scope.win, 10, wx.EXPAND)
+        
+        # add control area at the bottom
+        self.myform = myform = form.form()
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((5,0), 0, 0)
+        myform['freq'] = form.float_field(
+            parent=self.panel, sizer=hbox, label="Center freq", weight=1,
+            callback=myform.check_input_and_call(_form_set_freq, 
self._set_status_msg))
+
+        hbox.Add((5,0), 0, 0)
+        #g = self.subdev.gain_range()
+        #g = self.u.gain_range()
+        g = [0,10]
+        myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, 
label="Gain",
+                                           weight=3,
+                                           min=int(g[0]), max=int(g[1]),
+                                           callback=self.set_gain)
+
+        hbox.Add((5,0), 0, 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+        self._build_subpanel(vbox)
+
+    def _build_subpanel(self, vbox_arg):
+        # build a secondary information panel (sometimes hidden)
+
+        # FIXME figure out how to have this be a subpanel that is always
+        # created, but has its visibility controlled by foo.Show(True/False)
+        
+        def _form_set_decim(kv):
+            return self.set_decim(kv['decim'])
+
+        if not(self.show_debug_info):
+            return
+
+        panel = self.panel
+        vbox = vbox_arg
+        myform = self.myform
+
+        #panel = wx.Panel(self.panel, -1)
+        #vbox = wx.BoxSizer(wx.VERTICAL)
+
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((5,0), 0)
+
+        myform['decim'] = form.int_field(
+            parent=panel, sizer=hbox, label="Decim",
+            callback=myform.check_input_and_call(_form_set_decim, 
self._set_status_msg))
+
+        hbox.Add((5,0), 1)
+        myform['address@hidden'] = form.static_float_field(
+            parent=panel, sizer=hbox, label="address@hidden")
+
+        hbox.Add((5,0), 1)
+        myform['dbname'] = form.static_text_field(
+            parent=panel, sizer=hbox)
+
+        hbox.Add((5,0), 1)
+        myform['baseband'] = form.static_float_field(
+            parent=panel, sizer=hbox, label="Analog BB")
+
+        hbox.Add((5,0), 1)
+        myform['ddc'] = form.static_float_field(
+            parent=panel, sizer=hbox, label="DDC")
+
+        hbox.Add((5,0), 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+        
+    def set_freq(self, target_freq):
+        """
+        Set the center frequency we're interested in.
+
+        @param target_freq: frequency in Hz
+        @rypte: bool
+
+        Tuning is a two step process.  First we ask the front-end to
+        tune as close to the desired frequency as it can.  Then we use
+        the result of that operation and our target_frequency to
+        determine the value for the digital down converter.
+        """
+        #r = self.u.tune(0, self.subdev, target_freq)
+        r = self.u.set_rx_freq(0, target_freq)
+        
+        if r:
+            self.myform['freq'].set_value(target_freq)     # update displayed 
value
+#            if self.show_debug_info:
+#                self.myform['baseband'].set_value(r.baseband_freq)
+#                self.myform['ddc'].set_value(r.dxc_freq)
+           if not self.options.waterfall and not self.options.oscilloscope:
+               self.scope.win.set_baseband_freq(target_freq)
+           return True
+
+        return False
+
+    def set_gain(self, gain):
+        self.myform['gain'].set_value(gain)     # update displayed value
+        self.u.set_pga(0,gain)
+
+    def set_decim(self, decim):
+        ok = self.u.set_decim_rate(decim)
+        if not ok:
+            print "set_decim failed"
+        input_rate = self.u.adc_freq() / self.u.decim_rate()
+        self.scope.set_sample_rate(input_rate)
+        if self.show_debug_info:  # update displayed values
+            self.myform['decim'].set_value(self.u.decim_rate())
+            self.myform['address@hidden'].set_value(self.u.adc_freq() / 
self.u.decim_rate())
+        return ok
+
+    def _setup_events(self):
+       if not self.options.waterfall and not self.options.oscilloscope:
+           self.scope.win.Bind(wx.EVT_LEFT_DCLICK, self.evt_left_dclick)
+           
+    def evt_left_dclick(self, event):
+       (ux, uy) = self.scope.win.GetXY(event)
+       if event.CmdDown():
+           # Re-center on maximum power
+           points = self.scope.win._points
+           if self.scope.win.peak_hold:
+               if self.scope.win.peak_vals is not None:
+                   ind = numpy.argmax(self.scope.win.peak_vals)
+               else:
+                   ind = int(points.shape()[0]/2)
+           else:
+               ind = numpy.argmax(points[:,1])
+            (freq, pwr) = points[ind]
+           target_freq = freq/self.scope.win._scale_factor
+           print ind, freq, pwr
+            self.set_freq(target_freq)            
+       else:
+           # Re-center on clicked frequency
+           target_freq = ux/self.scope.win._scale_factor
+           self.set_freq(target_freq)
+           
+       
+def main ():
+    app = stdgui2.stdapp(app_top_block, "USRP FFT", nstatus=1)
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main ()


Property changes on: 
gnuradio/trunk/gr-msdd6000/src/python-examples/new_msdd_fft.py
___________________________________________________________________
Name: svn:executable
   + *

Added: gnuradio/trunk/gr-msdd6000/src/python-examples/playback_samples.m
===================================================================
--- gnuradio/trunk/gr-msdd6000/src/python-examples/playback_samples.m           
                (rev 0)
+++ gnuradio/trunk/gr-msdd6000/src/python-examples/playback_samples.m   
2008-07-04 03:05:33 UTC (rev 8786)
@@ -0,0 +1,12 @@
+t = read_complex_binary('msdd.dat',10000000);
+
+fftsize=256;
+w = [0:pi/fftsize:pi];
+
+for i = 0:length(t)/fftsize
+       fftdata = fft(i*fftsize:i*fftsize+fftsize);
+       clear plot;
+       plot(w,fftdata);
+endfor
+
+pause;

Added: gnuradio/trunk/gr-msdd6000/src/python-examples/read_complex_binary.m
===================================================================
--- gnuradio/trunk/gr-msdd6000/src/python-examples/read_complex_binary.m        
                        (rev 0)
+++ gnuradio/trunk/gr-msdd6000/src/python-examples/read_complex_binary.m        
2008-07-04 03:05:33 UTC (rev 8786)
@@ -0,0 +1,48 @@
+%
+% Copyright 2001 Free Software Foundation, Inc.
+% 
+% This file is part of GNU Radio
+% 
+% GNU Radio is free software; you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation; either version 3, or (at your option)
+% any later version.
+% 
+% GNU Radio is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+% 
+% You should have received a copy of the GNU General Public License
+% along with GNU Radio; see the file COPYING.  If not, write to
+% the Free Software Foundation, Inc., 51 Franklin Street,
+% Boston, MA 02110-1301, USA.
+% 
+
+function v = read_complex_binary (filename, count)
+
+  %% usage: read_complex_binary (filename, [count])
+  %%
+  %%  open filename and return the contents as a column vector, 
+  %%  treating them as 32 bit complex numbers
+  %%
+
+  m = nargchk (1,2,nargin);
+  if (m)
+    usage (m);
+  end
+
+  if (nargin < 2)
+    count = Inf;
+  end
+
+  f = fopen (filename, 'rb');
+  if (f < 0)
+    v = 0;
+  else
+    t = fread (f, [2, count], 'float');
+    fclose (f);
+    v = t(1,:) + t(2,:)*i;
+    [r, c] = size (v);
+    v = reshape (v, c, r);
+  end





reply via email to

[Prev in Thread] Current Thread [Next in Thread]