Merged r5950:5978 from features/pager into trunk. Trunk passes distcheck.
authorjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Mon, 16 Jul 2007 05:28:38 +0000 (05:28 +0000)
committerjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Mon, 16 Jul 2007 05:28:38 +0000 (05:28 +0000)
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@5979 221aa14e-8319-0410-a670-987f0aec2ac5

20 files changed:
gnuradio-core/src/lib/runtime/gr_hier_block2.cc
gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
gnuradio-core/src/python/gnuradio/blksimpl2/Makefile.am
gnuradio-core/src/python/gnuradio/blksimpl2/filterbank.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl2/rational_resampler.py [new file with mode: 0644]
gr-pager/src/Makefile.am
gr-pager/src/aypabtu.py [deleted file]
gr-pager/src/flex_demod.py
gr-pager/src/pager.i
gr-pager/src/pager_flex_parse.cc
gr-pager/src/pager_flex_parse.h
gr-pager/src/pager_slicer_fb.cc
gr-pager/src/pager_slicer_fb.h
gr-pager/src/pageri_flex_modes.cc
gr-pager/src/pageri_flex_modes.h
gr-pager/src/usrp_flex.py
gr-pager/src/usrp_flex_all.py [new file with mode: 0755]
gr-usrp/src/db_dbs_rx.py

index 9811b9defa5c185c0ea1c062a53b21f434310f24..fc74ff431b011e987ef9287f0adabf46b156f201 100644 (file)
@@ -29,7 +29,7 @@
 #include <gr_hier_block2_detail.h>
 #include <iostream>
 
-#define GR_HIER_BLOCK2_DEBUG 1
+#define GR_HIER_BLOCK2_DEBUG 0
 
 gr_hier_block2_sptr gr_make_hier_block2(const std::string &name, 
                                         gr_io_signature_sptr input_signature,
index 307cbabeb51b6fade3b0219ca6ecd4c26008543b..4fefed28b5c6bdb0aedfb4824d1ec61916e91e68 100644 (file)
@@ -30,7 +30,7 @@
 #include <stdexcept>
 #include <iostream>
 
-#define GR_HIER_BLOCK2_DETAIL_DEBUG 1
+#define GR_HIER_BLOCK2_DETAIL_DEBUG 0
 
 gr_hier_block2_detail::gr_hier_block2_detail(gr_hier_block2 *owner) :
   d_owner(owner), 
index 54fc7d19a6086fc2e4d3efd66bae0ce3eef8ac65..e792774b9215ceb0930683c99856210304d24d51 100644 (file)
@@ -38,7 +38,7 @@
 #include <stdexcept>
 #include <iostream>
 
-#define GR_RUNTIME_IMPL_DEBUG 1
+#define GR_RUNTIME_IMPL_DEBUG 0
 
 static gr_runtime_impl *s_runtime = 0;
 
index a725adb6eba2a7b5d47b937268ebb264ef67424c..432cde0aedb52e1df68a7a180766a418b092ca6c 100644 (file)
@@ -33,7 +33,7 @@
 #include <stdexcept>
 #include <map>
 
-#define GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG 1
+#define GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG 0
 
 gr_edge_sptr
 gr_make_edge(const gr_endpoint &src, const gr_endpoint &dst)
index 4852ff3fbfcced698dab9b0033905e5b31b59d22..201a85b39ae28a18d6c10f5f1f556f49b3273614 100644 (file)
@@ -31,9 +31,11 @@ grblkspython_PYTHON =                \
        dbpsk.py                \
        dqpsk.py                \
        d8psk.py                \
+       filterbank.py           \
        gmsk.py                 \
        pkt.py                  \
-       psk.py
+       psk.py                  \
+       rational_resampler.py
 
 noinst_PYTHON =                
 
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl2/filterbank.py b/gnuradio-core/src/python/gnuradio/blksimpl2/filterbank.py
new file mode 100644 (file)
index 0000000..38587ba
--- /dev/null
@@ -0,0 +1,174 @@
+#
+# Copyright 2005 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 2, 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.
+# 
+
+import sys
+from gnuradio import gr, gru
+
+def _generate_synthesis_taps(mpoints):
+    return []   # FIXME
+
+
+def _split_taps(taps, mpoints):
+    assert (len(taps) % mpoints) == 0
+    result = [list() for x in range(mpoints)]
+    for i in xrange(len(taps)):
+        (result[i % mpoints]).append(taps[i])
+    return [tuple(x) for x in result]
+
+
+class synthesis_filterbank(gr.hier_block2):
+    """
+    Uniformly modulated polyphase DFT filter bank: synthesis
+
+    See http://cnx.rice.edu/content/m10424/latest
+    """
+    def __init__(self, mpoints, taps=None):
+        """
+        Takes M complex streams in, produces single complex stream out
+        that runs at M times the input sample rate
+
+        @param fg:      flow_graph
+        @param mpoints: number of freq bins/interpolation factor/subbands
+        @param taps:    filter taps for subband filter
+
+        The channel spacing is equal to the input sample rate.
+        The total bandwidth and output sample rate are equal the input
+        sample rate * nchannels.
+
+        Output stream to frequency mapping:
+        
+          channel zero is at zero frequency.
+
+          if mpoints is odd:
+            
+            Channels with increasing positive frequencies come from
+            channels 1 through (N-1)/2.
+
+            Channel (N+1)/2 is the maximum negative frequency, and
+            frequency increases through N-1 which is one channel lower
+            than the zero frequency.
+
+          if mpoints is even:
+
+            Channels with increasing positive frequencies come from
+            channels 1 through (N/2)-1.
+
+            Channel (N/2) is evenly split between the max positive and
+            negative bins.
+
+            Channel (N/2)+1 is the maximum negative frequency, and
+            frequency increases through N-1 which is one channel lower
+            than the zero frequency.
+
+            Channels near the frequency extremes end up getting cut
+            off by subsequent filters and therefore have diminished
+            utility.
+        """
+        item_size = gr.sizeof_gr_complex
+       gr.hier_block2.__init__(self, "synthesis_filterbank",
+                               gr.io_signature(mpoints, mpoints, item_size),
+                               gr.io_signature(1, 1, item_size))
+
+        if taps is None:
+            taps = _generate_synthesis_taps(mpoints)
+
+        # pad taps to multiple of mpoints
+        r = len(taps) % mpoints
+        if r != 0:
+            taps = taps + (mpoints - r) * (0,)
+
+        # split in mpoints separate set of taps
+        sub_taps = _split_taps(taps, mpoints)
+
+        self.ss2v = gr.streams_to_vector(item_size, mpoints)
+        self.ifft = gr.fft_vcc(mpoints, False, [])
+        self.v2ss = gr.vector_to_streams(item_size, mpoints)
+        # mpoints filters go in here...
+        self.ss2s = gr.streams_to_stream(item_size, mpoints)
+
+       for i in range(mpoints):
+           self.connect((self, i), (self.ss2v, i))
+
+        self.connect(self.ss2v, self.ifft, self.v2ss, self)
+
+        # build mpoints fir filters...
+        for i in range(mpoints):
+            f = gr.fft_filter_ccc(1, sub_taps[i])
+            self.connect((self.v2ss, i), f)
+            self.connect(f, (self.ss2s, i))
+
+
+class analysis_filterbank(gr.hier_block2):
+    """
+    Uniformly modulated polyphase DFT filter bank: analysis
+
+    See http://cnx.rice.edu/content/m10424/latest
+    """
+    def __init__(self, mpoints, taps=None):
+        """
+        Takes 1 complex stream in, produces M complex streams out
+        that runs at 1/M times the input sample rate
+
+        @param fg:      flow_graph
+        @param mpoints: number of freq bins/interpolation factor/subbands
+        @param taps:    filter taps for subband filter
+
+        Same channel to frequency mapping as described above.
+        """
+        item_size = gr.sizeof_gr_complex
+       gr.hier_block2.__init__(self, "analysis_filterbank",
+                               gr.io_signature(1, 1, item_size),
+                               gr.io_signature(mpoints, mpoints, item_size))
+
+        if taps is None:
+            taps = _generate_synthesis_taps(mpoints)
+
+        # pad taps to multiple of mpoints
+        r = len(taps) % mpoints
+        if r != 0:
+            taps = taps + (mpoints - r) * (0,)
+        
+        # split in mpoints separate set of taps
+        sub_taps = _split_taps(taps, mpoints)
+
+        # print >> sys.stderr, "mpoints =", mpoints, "len(sub_taps) =", len(sub_taps) 
+        
+        self.s2ss = gr.stream_to_streams(item_size, mpoints)
+        # filters here
+        self.ss2v = gr.streams_to_vector(item_size, mpoints)
+        self.fft = gr.fft_vcc(mpoints, True, [])
+        self.v2ss = gr.vector_to_streams(item_size, mpoints)
+
+       self.connect(self, self.s2ss)
+
+        # build mpoints fir filters...
+        for i in range(mpoints):
+            f = gr.fft_filter_ccc(1, sub_taps[mpoints-i-1])
+            self.connect((self.s2ss, i), f)
+            self.connect(f, (self.ss2v, i))
+
+        self.connect(self.ss2v, self.fft, self.v2ss)
+
+       for i in range(mpoints):
+           self.connect((self.v2ss, i), (self, i))
+
+
+
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl2/rational_resampler.py b/gnuradio-core/src/python/gnuradio/blksimpl2/rational_resampler.py
new file mode 100644 (file)
index 0000000..93e90f3
--- /dev/null
@@ -0,0 +1,131 @@
+#
+# Copyright 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 2, 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
+
+_plot = None
+
+def design_filter(interpolation, decimation, fractional_bw):
+    """
+    Given the interpolation rate, decimation rate and a fractional bandwidth,
+    design a set of taps.
+
+    @param interpolation: interpolation factor
+    @type  interpolation: integer > 0
+    @param decimation: decimation factor
+    @type  decimation: integer > 0
+    @param fractional_bw: fractional bandwidth in (0, 0.5)  0.4 works well.
+    @type  fractional_bw: float
+    @returns: sequence of numbers
+    """
+
+    if fractional_bw >= 0.5 or fractional_bw <= 0:
+        raise ValueError, "Invalid fractional_bandwidth, must be in (0, 0.5)"
+
+    beta = 5.0
+    trans_width = 0.5 - fractional_bw
+    mid_transition_band = 0.5 - trans_width/2
+
+    taps = gr.firdes.low_pass(interpolation,                     # gain
+                              1,                                 # Fs
+                              mid_transition_band/interpolation, # trans mid point
+                              trans_width/interpolation,         # transition width
+                              gr.firdes.WIN_KAISER,
+                              beta                               # beta
+                              )
+
+    return taps
+
+
+
+class _rational_resampler_base(gr.hier_block2):
+    """
+    base class for all rational resampler variants.
+    """
+    def __init__(self, resampler_base,
+                 interpolation, decimation, taps=None, fractional_bw=None):
+        """
+        Rational resampling polyphase FIR filter.
+
+        Either taps or fractional_bw may be specified, but not both.
+        If neither is specified, a reasonable default, 0.4, is used as
+        the fractional_bw.
+
+        @param interpolation: interpolation factor
+        @type  interpolation: integer > 0
+        @param decimation: decimation factor
+        @type  decimation: integer > 0
+        @param taps: optional filter coefficients
+        @type  taps: sequence
+        @param fractional_bw: fractional bandwidth in (0, 0.5), measured at final freq (use 0.4)
+        @type  fractional_bw: float
+        """
+
+        if not isinstance(interpolation, int) or interpolation < 1:
+            raise ValueError, "interpolation must be an integer >= 1"
+
+        if not isinstance(decimation, int) or decimation < 1:
+            raise ValueError, "decimation must be an integer >= 1"
+
+        if taps is None and fractional_bw is None:
+            fractional_bw = 0.4
+
+        d = gru.gcd(interpolation, decimation)
+        interpolation = interpolation // d
+        decimation = decimation // d
+        
+        if taps is None:
+            taps = design_filter(interpolation, decimation, fractional_bw)
+
+        resampler = resampler_base(interpolation, decimation, taps)
+       gr.hier_block2.__init__(self, resampler.name(),
+                               gr.io_signature(1, 1, resampler.input_signature().sizeof_stream_item(0)),
+                               gr.io_signature(1, 1, resampler.output_signature().sizeof_stream_item(1)))
+
+       self.connect(self, resampler, self)
+
+
+class rational_resampler_fff(_rational_resampler_base):
+    def __init__(self, interpolation, decimation, taps=None, fractional_bw=None):
+        """
+        Rational resampling polyphase FIR filter with
+        float input, float output and float taps.
+        """
+        _rational_resampler_base.__init__(self, gr.rational_resampler_base_fff,
+                                         interpolation, decimation, taps, fractional_bw)
+
+class rational_resampler_ccf(_rational_resampler_base):
+    def __init__(self, interpolation, decimation, taps=None, fractional_bw=None):
+        """
+        Rational resampling polyphase FIR filter with
+        complex input, complex output and float taps.
+        """
+        _rational_resampler_base.__init__(self, gr.rational_resampler_base_ccf, 
+                                          interpolation, decimation, taps, fractional_bw)
+
+class rational_resampler_ccc(_rational_resampler_base):
+    def __init__(self, interpolation, decimation, taps=None, fractional_bw=None):
+        """
+        Rational resampling polyphase FIR filter with
+        complex input, complex output and complex taps.
+        """
+        _rational_resampler_base.__init__(self, gr.rational_resampler_base_ccc, 
+                                          interpolation, decimation, taps, fractional_bw)
index b818be0e3471e837938c3aaffbdecb91431336a1..85f34651193bef50969072dbe21334a87ff6e772 100644 (file)
@@ -29,7 +29,7 @@ TESTS = \
 
 bin_SCRIPTS = \
     usrp_flex.py \
-    aypabtu.py 
+    usrp_flex_all.py
     
 noinst_PYTHON = \
     qa_pager.py
@@ -70,8 +70,8 @@ ourpython_PYTHON = \
     pager_swig.py \
     flex_demod.py \
     usrp_flex.py \
-    aypabtu.py
-    
+    usrp_flex_all.py
+        
 ourlib_LTLIBRARIES = _pager_swig.la
 
 # These are the source files that go into the shared library
diff --git a/gr-pager/src/aypabtu.py b/gr-pager/src/aypabtu.py
deleted file mode 100755 (executable)
index c742744..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-#!/usr/bin/env python
-
-from math import pi
-from gnuradio import gr, gru, usrp, optfir, audio, eng_notation, blks, pager
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-from string import split, join, printable
-
-class usrp_source_c(gr.hier_block):
-    """
-    Create a USRP source object supplying complex floats.
-    
-    Selects user supplied subdevice or chooses first available one.
-
-    Calibration value is the offset from the tuned frequency to 
-    the actual frequency.       
-    """
-    def __init__(self, fg, subdev_spec, decim, gain=None, calibration=0.0):
-        self._decim = decim
-        self._src = usrp.source_c()
-        if subdev_spec is None:
-            subdev_spec = usrp.pick_rx_subdevice(self._src)
-        self._subdev = usrp.selected_subdev(self._src, subdev_spec)
-        self._src.set_mux(usrp.determine_rx_mux_value(self._src, subdev_spec))
-        self._src.set_decim_rate(self._decim)
-
-        # If no gain specified, set to midrange
-        if gain is None:
-            g = self._subdev.gain_range()
-            gain = (g[0]+g[1])/2.0
-
-        self._subdev.set_gain(gain)
-        self._cal = calibration
-
-        gr.hier_block.__init__(self, fg, self._src, self._src)
-
-    def tune(self, freq):
-        result = usrp.tune(self._src, 0, self._subdev, freq+self._cal)
-        # TODO: deal with residual
-
-    def rate(self):
-        return self._src.adc_rate()/self._decim
-
-class channelizer(blks.analysis_filterbank):
-    def __init__(self,
-                fg,            # Flow graph
-                if_rate,       # IF input sample rate (complex)
-                channel_rate,  # Final channel sample rate (complex)
-                channel_pass,  # Occupied spectrum for narrowband channel
-                channel_stop): # Total channel + guard band
-
-        num_channels = int(if_rate/channel_rate)
-        taps = optfir.low_pass(1.0, if_rate, channel_pass, channel_stop, 0.1, 60)
-        blks.analysis_filterbank.__init__(self, fg, num_channels, taps)
-
-class app_flow_graph(gr.flow_graph):
-    def __init__(self, options, args, queue):
-       gr.flow_graph.__init__(self)
-       self.options = options
-       self.args = args
-
-       # FIXME: Parameterize
-       #
-       # Difference between upper and lower must evenly divide into USRP sample rate
-       # and also must be divisible by 25000
-       options.channel_rate =     25000
-        options.channel_pass =      8000
-        options.channel_stop =     10000
-               
-       if_rate = options.upper_freq - options.lower_freq
-       center_freq = options.lower_freq + if_rate/2
-       num_channels = int(if_rate/options.channel_rate)
-       decim = int(64000000/if_rate)
-               
-       self.SRC = usrp_source_c(self, options.rx_board, decim, options.gain, options.calibration)
-        self.CHAN = channelizer(self, if_rate, options.channel_rate, options.channel_pass, options.channel_stop)
-
-        self.connect(self.SRC, self.CHAN)
-       for i in range(num_channels):
-           freq = options.lower_freq + i*options.channel_rate
-           if freq > center_freq:
-               freq -= if_rate/2
-           else:
-               freq += if_rate/2
-            FLEX = pager.flex_demod(self, options.channel_rate, queue)
-           self.connect((self.CHAN, i), FLEX.INPUT)
-
-       self.SRC.tune(center_freq)
-
-def make_printable(data):
-    return "".join(char for char in data if char in printable)
-
-def main():
-    parser = OptionParser(option_class=eng_option)
-    parser.add_option("",   "--upper-freq",   type="eng_float", help="lower Rx frequency", metavar="LOWER")
-    parser.add_option("",   "--lower-freq",   type="eng_float", help="upper Rx frequency", metavar="UPPER")
-    parser.add_option("-R", "--rx-board",     type="subdev", help="select USRP Rx side A or B (default=first daughterboard found)", metavar="SIDE")
-    parser.add_option("-c", "--calibration",  type="eng_float", default=0.0, help="set frequency offset to Hz", metavar="Hz")
-    parser.add_option("-g", "--gain",      type="int", help="set RF gain", metavar="dB")
-    (options, args) = parser.parse_args()
-
-    # FIXME: parameter sanity checks
-
-    queue = gr.msg_queue()
-    fg = app_flow_graph(options, args, queue)
-    try:
-        fg.start()
-       while 1:
-           msg = queue.delete_head() # Blocking read
-           fields = split(msg.to_string(), chr(128))
-           print join([make_printable(field) for field in fields], '|')
-
-    except KeyboardInterrupt:
-        fg.stop()
-
-if __name__ == "__main__":
-    main()
index 0d35cf3f4242ceed1f0dedca3a44bc0a04c33e62..fc9dfeeac535c1da10260dbcb56da6734f5c1d00 100644 (file)
 # Boston, MA 02110-1301, USA.
 # 
 
-from gnuradio import gr, gru, optfir, blks
+from gnuradio import gr, gru, optfir, blks2
 from math import pi
 import pager_swig
 
-chan_rate = 16000
-
-class flex_demod:
+class flex_demod(gr.hier_block2):
     """
     FLEX pager protocol demodulation block.
 
     This block demodulates a band-limited, complex down-converted baseband 
     channel into FLEX protocol frames.
 
-    Flow graph (so far):
-
-    RSAMP    - Resample incoming stream to 16000 sps
-    QUAD     - Quadrature demodulator converts FSK to baseband amplitudes  
-    LPF      - Low pass filter to remove noise prior to slicer
-    SLICER   - Converts input to one of four symbols (0, 1, 2, 3)
-    SYNC     - Converts symbol stream to four phases of FLEX blocks
-    DEINTx   - Deinterleaves FLEX blocks into datawords
-    PARSEx   - Parse a single FLEX phase worth of data words into pages
-    ---
-
-    @param fg: flowgraph
-    @param channel_rate:  incoming sample rate of the baseband channel
-    @type sample_rate: integer
     """
 
+    def __init__(self, queue, freq=0.0, verbose=False, log=False):
+       gr.hier_block2.__init__(self, "flex_demod",
+                               gr.io_signature(1, 1, gr.sizeof_gr_complex),
+                               gr.io_signature(0,0,0))
 
-    def __init__(self, fg, channel_rate, queue):
-        k = chan_rate/(2*pi*4800)        # 4800 Hz max deviation
-        QUAD = gr.quadrature_demod_cf(k)
-       self.INPUT = QUAD
-                       
-       if channel_rate != chan_rate:
-               interp = gru.lcm(channel_rate, chan_rate)/channel_rate
-               decim  = gru.lcm(channel_rate, chan_rate)/chan_rate
-               RESAMP = blks.rational_resampler_ccf(fg, interp, decim)
-               self.INPUT = RESAMP
-                       
-        taps = optfir.low_pass(1.0, chan_rate, 3200, 6400, 0.1, 60)
-        LPF = gr.fir_filter_fff(1, taps)
-        SLICER = pager_swig.slicer_fb(.001, .00001) # Attack, decay
-       SYNC = pager_swig.flex_sync(chan_rate)
-
-       if channel_rate != chan_rate:
-            fg.connect(RESAMP, QUAD, LPF, SLICER, SYNC)
-       else:
-           fg.connect(QUAD, LPF, SLICER, SYNC)
-
-       DEINTA = pager_swig.flex_deinterleave()
-       PARSEA = pager_swig.flex_parse(queue)
-
-       DEINTB = pager_swig.flex_deinterleave()
-       PARSEB = pager_swig.flex_parse(queue)
-
-       DEINTC = pager_swig.flex_deinterleave()
-       PARSEC = pager_swig.flex_parse(queue)
-
-       DEINTD = pager_swig.flex_deinterleave()
-       PARSED = pager_swig.flex_parse(queue)
+        k = 25000/(2*pi*1600)        # 4800 Hz max deviation
+        quad = gr.quadrature_demod_cf(k)
+       self.connect(self, quad)
        
-       fg.connect((SYNC, 0), DEINTA, PARSEA)
-       fg.connect((SYNC, 1), DEINTB, PARSEB)
-       fg.connect((SYNC, 2), DEINTC, PARSEC)
-       fg.connect((SYNC, 3), DEINTD, PARSED)
+        rsamp = blks2.rational_resampler_fff(16, 25)
+        slicer = pager_swig.slicer_fb(1e-5) # DC removal averaging filter constant
+       sync = pager_swig.flex_sync(16000)
+
+        self.connect(quad, rsamp, slicer, sync)
+
+       for i in range(4):
+           self.connect((sync, i), pager_swig.flex_deinterleave(), pager_swig.flex_parse(queue, freq))
+
+       if log:
+           suffix = '_'+ "%3.3f" % (freq/1e6,) + '.dat'
+           quad_sink = gr.file_sink(gr.sizeof_float, 'quad'+suffix)
+           rsamp_sink = gr.file_sink(gr.sizeof_float, 'rsamp'+suffix)
+           slicer_sink = gr.file_sink(gr.sizeof_char, 'slicer'+suffix)
+           self.connect(rsamp, rsamp_sink)
+           self.connect(quad, quad_sink)
+           self.connect(slicer, slicer_sink)
+           
\ No newline at end of file
index cc73a54734698d057020cd31297d10974d166c64..f8e17965bec19b8b74c27b4ab03e3c9f35b52945 100644 (file)
 
 GR_SWIG_BLOCK_MAGIC(pager,slicer_fb);
 
-pager_slicer_fb_sptr pager_make_slicer_fb(float alpha, float beta);
+pager_slicer_fb_sptr pager_make_slicer_fb(float alpha);
 
 class pager_slicer_fb : public gr_sync_block
 {
 private:
-    pager_slicer_fb(float alpha, float beta);
+    pager_slicer_fb(float alpha);
 
 public:
 };
@@ -81,12 +81,12 @@ public:
 
 GR_SWIG_BLOCK_MAGIC(pager,flex_parse);
 
-pager_flex_parse_sptr pager_make_flex_parse(gr_msg_queue_sptr queue);
+pager_flex_parse_sptr pager_make_flex_parse(gr_msg_queue_sptr queue, float freq);
 
 class pager_flex_parse : public gr_block
 {
 private:
-    pager_flex_parse(gr_msg_queue_sptr queue);
+    pager_flex_parse(gr_msg_queue_sptr queue, float freq);
 
 public:
 };
index 7178ba516cfa72e45d9c14e5f6ffb63f98aff905..012b171702ed484e978553a7b8320db762a84465 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2004,2006,2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <gr_io_signature.h>
 #include <ctype.h>
 #include <iostream>
+#include <iomanip>
 
-pager_flex_parse_sptr pager_make_flex_parse(gr_msg_queue_sptr queue)
+pager_flex_parse_sptr pager_make_flex_parse(gr_msg_queue_sptr queue, float freq)
 {
-    return pager_flex_parse_sptr(new pager_flex_parse(queue));
+    return pager_flex_parse_sptr(new pager_flex_parse(queue, freq));
 }
 
-pager_flex_parse::pager_flex_parse(gr_msg_queue_sptr queue) :
+pager_flex_parse::pager_flex_parse(gr_msg_queue_sptr queue, float freq) :
     gr_sync_block("flex_parse",
-       gr_make_io_signature(1, 1, sizeof(gr_int32)),
-       gr_make_io_signature(0, 0, 0)),
-    d_queue(queue)
+    gr_make_io_signature(1, 1, sizeof(gr_int32)),
+    gr_make_io_signature(0, 0, 0)),
+    d_queue(queue),
+    d_freq(freq)
 {
     d_count = 0;
 }
@@ -131,7 +133,11 @@ void pager_flex_parse::parse_data()
            continue;                           // Invalid offsets
 
        d_payload.str("");
-       d_payload << d_capcode << FIELD_DELIM << d_type << FIELD_DELIM;
+       d_payload.setf(std::ios::showpoint);
+       d_payload << std::setprecision(6) << std::setw(7)
+                 << d_freq/1e6 << FIELD_DELIM 
+                 << std::setw(10) << d_capcode << FIELD_DELIM
+                 << flex_page_desc[d_type] << FIELD_DELIM;
 
        if (is_alphanumeric_page(d_type))
            parse_alphanumeric(mw1, mw2-1, j);
@@ -142,9 +148,6 @@ void pager_flex_parse::parse_data()
        else
            parse_unknown(mw1, mw2);
 
-       //std::cout << d_payload.str() << std::endl;
-       //fflush(stdout);
-
        gr_message_sptr msg = gr_make_message_from_string(std::string(d_payload.str()));
        d_queue->handle(msg);
     }
@@ -166,8 +169,8 @@ void pager_flex_parse::parse_alphanumeric(int mw1, int mw2, int j)
        mw2--;
     }    
 
-    d_payload << frag << FIELD_DELIM;
-    d_payload << cont << FIELD_DELIM;
+    //d_payload << frag << FIELD_DELIM;
+    //d_payload << cont << FIELD_DELIM;
 
     for (int i = mw1; i <= mw2; i++) {
        gr_int32 dw = d_datawords[i];
index e5a225b28a59df08c8903edc16095d71c6072a8d..dd0510b6dc78b50698734ed0ff24623097033899 100644 (file)
@@ -30,7 +30,7 @@
 class pager_flex_parse;
 typedef boost::shared_ptr<pager_flex_parse> pager_flex_parse_sptr;
 
-pager_flex_parse_sptr pager_make_flex_parse(gr_msg_queue_sptr queue);
+pager_flex_parse_sptr pager_make_flex_parse(gr_msg_queue_sptr queue, float freq);
 
 /*!
  * \brief flex parse description
@@ -43,8 +43,8 @@ class pager_flex_parse : public gr_sync_block
 {
 private:
     // Constructors
-    friend pager_flex_parse_sptr pager_make_flex_parse(gr_msg_queue_sptr queue);
-    pager_flex_parse(gr_msg_queue_sptr queue);
+    friend pager_flex_parse_sptr pager_make_flex_parse(gr_msg_queue_sptr queue, float freq);
+    pager_flex_parse(gr_msg_queue_sptr queue, float freq);
 
     std::ostringstream d_payload;
     gr_msg_queue_sptr d_queue;           // Destination for decoded pages
@@ -52,10 +52,11 @@ private:
     int d_count;                         // Count of received codewords
     gr_int32 d_datawords[88];             // 11 blocks of 8 32-bit words
 
-    page_type_t d_type;                  // Current page type
+    page_type_t d_type;                          // Current page type
     int d_capcode;                       // Current page destination address
     bool d_laddr;                        // Current page has long address
-
+    float d_freq;                        // Channel frequency
+    
     void parse_data();                   // Handle a frame's worth of data
     void parse_capcode(gr_int32 aw1, gr_int32 aw2);     
     void parse_alphanumeric(int mw1, int mw2, int j);
index 98e8a2b000a3202dc903f8f1df4835b21d07ef7e..57b1b024987a4fada9bcc39831971cebed58501f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2004,2006,2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <pager_slicer_fb.h>
 #include <gr_io_signature.h>
 
-pager_slicer_fb_sptr pager_make_slicer_fb(float alpha, float beta)
+pager_slicer_fb_sptr pager_make_slicer_fb(float alpha)
 {
-    return pager_slicer_fb_sptr(new pager_slicer_fb(alpha, beta));
+    return pager_slicer_fb_sptr(new pager_slicer_fb(alpha));
 }
 
-pager_slicer_fb::pager_slicer_fb(float alpha, float beta) :
+pager_slicer_fb::pager_slicer_fb(float alpha) :
     gr_sync_block ("slicer_fb",
                    gr_make_io_signature (1, 1, sizeof(float)),
                    gr_make_io_signature (1, 1, sizeof(unsigned char)))
 {
     d_alpha = alpha;
-    d_beta = beta;
-    d_max = 0.0;
-    d_hi = 0.0;
+    d_beta = 1.0-alpha;
     d_avg = 0.0;
-    d_lo = 0.0;
-    d_min = 0.0;
 }
 
 // Tracks average, minimum, and peak, then converts input into one of:
@@ -53,34 +49,22 @@ unsigned char pager_slicer_fb::slice(float sample)
     unsigned char decision;
 
     // Update DC level and remove
-    d_avg = d_avg*(1.0-d_alpha)+sample*d_alpha;
+    d_avg = d_avg*d_beta+sample*d_alpha;
     sample -= d_avg;
 
     if (sample > 0) {
-        if (sample > d_hi) {                // In max region
-            d_max = d_max*(1.0-d_alpha) + sample*d_alpha;
+        if (sample > 2.0)          
             decision = 3;
-        }
-        else {
-            d_max -= (d_max-d_avg)*d_beta;  // decay otherwise
+        else
             decision = 2;
-        }
     }
     else {
-        if (sample < d_lo) {                // In min region
-            d_min = d_min*(1.0-d_alpha) + sample*d_alpha;
+        if (sample < -2.0)
             decision = 0;
-        }
-        else {
-            d_min -= (d_min-d_avg)*d_beta;  // decay otherwise
+        else
             decision = 1;
-        }
     }
 
-    d_hi = d_max*2.0/3.0;
-    d_lo = d_min*2.0/3.0;
-
-    //fprintf(stderr, "%f %d\n", sample, decision);
     return decision;
 }
 
index 4751bb47ebb2835ddf067f5f1e600e6cded09af0..cde7aa94e2408b5402044d5b1abf76a2565f1a67 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -27,7 +27,7 @@
 class pager_slicer_fb;
 typedef boost::shared_ptr<pager_slicer_fb> pager_slicer_fb_sptr;
 
-pager_slicer_fb_sptr pager_make_slicer_fb(float alpha, float beta);
+pager_slicer_fb_sptr pager_make_slicer_fb(float alpha);
 
 /*!
  * \brief slicer description
@@ -36,18 +36,14 @@ pager_slicer_fb_sptr pager_make_slicer_fb(float alpha, float beta);
 class pager_slicer_fb : public gr_sync_block
 {
 private:
-    friend pager_slicer_fb_sptr pager_make_slicer_fb(float alpha, float beta);
-    pager_slicer_fb(float alpha, float beta);
+    friend pager_slicer_fb_sptr pager_make_slicer_fb(float alpha);
+    pager_slicer_fb(float alpha);
 
     unsigned char slice(float sample);
 
-    float d_alpha;      // Attack constant
-    float d_beta;       // Decay constant
-    float d_max;        // Maximum value for symbol comparison
-    float d_hi;         // High side decision boundary
+    float d_alpha;      // DC removal time constant
+    float d_beta;      // 1.0-d_alpha
     float d_avg;        // Average value for DC offset subtraction
-    float d_lo;         // Low side decision boundary
-    float d_min;        // Minimum value for symbol comparison
 
 public:
     int work (int noutput_items,
index b2bb4e29ccc752fa9dae4b3ca60668c0d1e96909..7126a889a7ff45c345137be9b366e574e7ad46fe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -34,6 +34,18 @@ const int num_flex_modes = sizeof(flex_modes)/sizeof(flex_modes[0]);
 
 unsigned char flex_bcd[17] = "0123456789 U -][";
 
+const char *flex_page_desc[] =
+{
+    "ENC",
+    "UNK",
+    "TON",
+    "NUM",
+    "SPN",
+    "ALN",
+    "BIN",
+    "NNM"
+};
+
 int find_flex_mode(gr_int32 sync_code)
 {
     for (int i = 0; i < num_flex_modes; i++)
index 09e5952b9f815a82def21c74732508101ec26694..438579b27be8dc3109e4ba35d67ca0b67a33b0a3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -35,6 +35,7 @@ typedef struct flex_mode
 flex_mode_t;
 
 extern const flex_mode_t flex_modes[];
+extern const char *flex_page_desc[];
 extern const int num_flex_modes;
 int find_flex_mode(gr_int32 sync_code);
 extern unsigned char flex_bcd[];
index a1a790333e93ead787329fa58a6beeac2ca3c2f1..095a7cb9cbaee8d18c1001e970f31b1a9bd38b55 100755 (executable)
@@ -31,101 +31,92 @@ from string import split, join
 This example application demonstrates receiving and demodulating the
 FLEX pager protocol.
 
-A receive chain is built up of the following signal processing
-blocks:
-
-USRP  - Daughter board source generating complex baseband signal.
-CHAN  - Low pass filter to select channel bandwidth
-AGC   - Automatic gain control leveling signal at [-1.0, +1.0]
-FLEX  - FLEX pager protocol decoder
-
 The following are required command line parameters:
 
--f FREQ                USRP receive frequency
+-f FREQ            USRP receive frequency
 
 The following are optional command line parameters:
 
 -R SUBDEV   Daughter board specification, defaults to first found
+-F FILE     Read samples from a file instead of USRP.
 -c FREQ     Calibration offset.  Gets added to receive frequency.
             Defaults to 0.0 Hz.
 -g GAIN     Daughterboard gain setting. Defaults to mid-range.
--r RFSQL       RF squelch in db. Defaults to -50.0.
+-l          Log flow graph to files (LOTS of data)
+-v          Verbose output
 
 Once the program is running, ctrl-break (Ctrl-C) stops operation.
 """
 
-class usrp_source_c(gr.hier_block):
-    """
-    Create a USRP source object supplying complex floats.
-    
-    Selects user supplied subdevice or chooses first available one.
-
-    Calibration value is the offset from the tuned frequency to 
-    the actual frequency.       
-    """
-    def __init__(self, fg, subdev_spec, decim, gain=None, calibration=0.0):
-        self._decim = decim
-        self._src = usrp.source_c()
-        if subdev_spec is None:
-            subdev_spec = usrp.pick_rx_subdevice(self._src)
-        self._subdev = usrp.selected_subdev(self._src, subdev_spec)
-        self._src.set_mux(usrp.determine_rx_mux_value(self._src, subdev_spec))
-        self._src.set_decim_rate(self._decim)
-
-        # If no gain specified, set to midrange
-        if gain is None:
-            g = self._subdev.gain_range()
-            gain = (g[0]+g[1])/2.0
-
-        self._subdev.set_gain(gain)
-        self._cal = calibration
-
-        gr.hier_block.__init__(self, fg, self._src, self._src)
-
-    def tune(self, freq):
-        result = usrp.tune(self._src, 0, self._subdev, freq+self._cal)
-        # TODO: deal with residual
-
-    def rate(self):
-        return self._src.adc_rate()/self._decim
-
-class app_flow_graph(gr.flow_graph):
-    def __init__(self, options, args, queue):
-        gr.flow_graph.__init__(self)
+class app_top_block(gr.top_block):
+    def __init__(self, options, queue):
+        gr.top_block.__init__(self, "usrp_flex")
         self.options = options
-        self.args = args
-
-        USRP = usrp_source_c(self,          # Flow graph
-                    options.rx_subdev_spec, # Daugherboard spec
-                   256,                    # IF decimation ratio gets 250K if_rate
-                    options.gain,           # Receiver gain
-                    options.calibration)    # Frequency offset
-        USRP.tune(options.frequency)
-
-        if_rate = USRP.rate()
-        channel_rate = 25000                
-        channel_decim = int(if_rate / channel_rate)
-       
-        CHAN_taps = optfir.low_pass(1.0,          # Filter gain
-                                    if_rate,      # Sample rate
-                                   8000,         # One sided modulation bandwidth
-                                   10000,        # One sided channel bandwidth
-                                   0.1,          # Passband ripple
-                                   60)           # Stopband attenuation
-       
-        CHAN = gr.freq_xlating_fir_filter_ccf(channel_decim, # Decimation rate
-                                              CHAN_taps,     # Filter taps
-                                              0.0,           # Offset frequency
-                                              if_rate)       # Sample rate
-
-        AGC = gr.agc_cc(1.0/channel_rate,  # Time constant
-                        1.0,               # Reference power 
-                        1.0,               # Initial gain
-                        1.0)               # Maximum gain
+
+       if options.from_file is None:
+            # Set up USRP source with specified RX daughterboard
+            src = usrp.source_c()
+            if options.rx_subdev_spec == None:
+                options.subdev_spec = usrp.pick_rx_subdevice(src)
+            subdev = usrp.selected_subdev(src, options.rx_subdev_spec)
+            src.set_mux(usrp.determine_rx_mux_value(src, options.rx_subdev_spec))
+
+            # Grab 250 KHz of spectrum (sample rate becomes 250 ksps complex)
+            src.set_decim_rate(256)
+                   
+            # If no gain specified, set to midrange
+            if options.gain is None:
+                g = subdev.gain_range()
+                options.gain = (g[0]+g[1])/2.0
+            subdev.set_gain(options.gain)
+
+            # Tune daughterboard
+            actual_frequency = options.frequency+options.calibration
+            tune_result = usrp.tune(src, 0, subdev, actual_frequency)
+            if not tune_result:
+                sys.stderr.write("Failed to set center frequency to"+`actual_frequency`+"\n")
+                sys.exit(1)
+
+            if options.verbose:
+                print "Using RX daughterboard", subdev.side_and_name()
+                print "USRP gain is", options.gain
+                print "USRP tuned to", actual_frequency
+            
+        else:
+            # Use supplied file as source of samples
+            src = gr.file_source(gr.sizeof_gr_complex, options.from_file)
+            if options.verbose:
+                print "Reading samples from", options.from_file
+           
+        if options.log and not options.from_file:
+            usrp_sink = gr.file_sink(gr.sizeof_gr_complex, 'usrp.dat')
+            self.connect(src, usrp_sink)
+
+        # Set up 22KHz-wide bandpass about center frequency. Decimate by 10
+        # to get channel rate of 25Ksps
+        taps = optfir.low_pass(1.0,   # Filter gain
+                               250e3, # Sample rate
+                               11000, # One-sided modulation bandwidth
+                               12500, # One-sided channel bandwidth
+                               0.1,   # Passband ripple
+                               60)    # Stopband attenuation
        
-        FLEX = pager.flex_demod(self, 25000, queue)
+       if options.verbose:
+           print "Channel filter has", len(taps), "taps."
+
+        chan = gr.freq_xlating_fir_filter_ccf(10,    # Decimation rate
+                                              taps,  # Filter taps
+                                              0.0,   # Offset frequency
+                                              250e3) # Sample rate
 
-        self.connect(USRP, CHAN, AGC, FLEX.INPUT)
+       if options.log:
+           chan_sink = gr.file_sink(gr.sizeof_gr_complex, 'chan.dat')
+           self.connect(chan, chan_sink)
+
+        # FLEX protocol demodulator
+        flex = pager.flex_demod(queue, options.frequency, options.verbose, options.log)
+
+        self.connect(src, chan, flex)
        
 def main():
     parser = OptionParser(option_class=eng_option)
@@ -137,20 +128,28 @@ def main():
                       help="set frequency offset to Hz", metavar="Hz")
     parser.add_option("-g", "--gain", type="int", default=None,
                       help="set RF gain", metavar="dB")
+    parser.add_option("-l", "--log", action="store_true", default=False,
+                      help="log flowgraph to files (LOTS of data)")
+    parser.add_option("-v", "--verbose", action="store_true", default=False,
+                      help="display debug output")
+    parser.add_option("-F", "--from-file", default=None,
+                      help="read samples from file instead of USRP")
     (options, args) = parser.parse_args()
 
-    if len(args) > 0 or options.frequency == None:
+    if len(args) > 0 or (options.frequency == None and options.from_file == None):
        print "Run 'usrp_flex.py -h' for options."
        sys.exit(1)
 
-    if options.frequency < 1e6:
-       options.frequency *= 1e6
-       
-    queue = gr.msg_queue()
+    if options.frequency == None:
+       options.frequency = 0.0
 
-    fg = app_flow_graph(options, args, queue)
+    # Flow graph emits pages into message queue
+    queue = gr.msg_queue()
+    tb = app_top_block(options, queue)
+    r = gr.runtime(tb)
+    
     try:
-        fg.start()
+        r.start()
        while 1:
            if not queue.empty_p():
                msg = queue.delete_head() # Blocking read
@@ -167,7 +166,7 @@ def main():
                time.sleep(1)
 
     except KeyboardInterrupt:
-        fg.stop()
+        r.stop()
 
 if __name__ == "__main__":
     main()
diff --git a/gr-pager/src/usrp_flex_all.py b/gr-pager/src/usrp_flex_all.py
new file mode 100755 (executable)
index 0000000..6fe9bc3
--- /dev/null
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, usrp, optfir, eng_notation, blks2, pager
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+from string import split, join, printable
+import time
+
+class app_top_block(gr.top_block):
+    def __init__(self, options, queue):
+       gr.top_block.__init__(self, "usrp_flex_all")
+
+        if options.from_file is not None:
+            src = gr.file_source(gr.sizeof_gr_complex, options.from_file)
+            if options.verbose:
+                print "Reading samples from file", options.from_file
+        else:
+            src = usrp.source_c()
+            if options.rx_subdev_spec is None:
+                options.rx_subdev_spec = usrp.pick_rx_subdevice(src)
+            subdev = usrp.selected_subdev(src, options.rx_subdev_spec)
+            src.set_mux(usrp.determine_rx_mux_value(src, options.rx_subdev_spec))
+            src.set_decim_rate(20)
+            result = usrp.tune(src, 0, subdev, 930.5e6+options.calibration)
+            if options.verbose:
+                print "Using", subdev.name(), " for receiving."
+                print "Tuned USRP to", 930.5e6+options.calibration
+                
+        taps = gr.firdes.low_pass(1.0,
+                                  1.0,
+                                  1.0/128.0*0.4,
+                                  1.0/128.0*0.1,
+                                  gr.firdes.WIN_HANN)
+
+        if options.verbose:
+            print "Channel filter has", len(taps), "taps"
+
+        bank = blks2.analysis_filterbank(128, taps)
+        self.connect(src, bank)
+
+        if options.log and options.from_file == None:
+            src_sink = gr.file_sink(gr.sizeof_gr_complex, 'usrp.dat')
+            self.connect(src, src_sink)
+
+        for i in range(128):
+           if i < 64:
+               freq = 930.5e6+i*25e3
+           else:
+               freq = 928.9e6+(i-64)*25e3
+
+           if ((i < 20) or (i >= 60 and i < 68) or (i >= 108)): # Non-forward channel frequencies
+                self.connect((bank, i), gr.null_sink(gr.sizeof_gr_complex))
+           else:
+               self.connect((bank, i), pager.flex_demod(queue, freq, options.verbose, options.log))
+                if options.log:
+                    self.connect((bank, i), gr.file_sink(gr.sizeof_gr_complex, 'chan_'+'%3.3f'%(freq/1e6)+'.dat'))
+
+def main():
+    parser = OptionParser(option_class=eng_option)
+    parser.add_option("-R", "--rx-subdev-spec", type="subdev",
+                      help="select USRP Rx side A or B (default=first daughterboard found)")
+    parser.add_option("-c", "--calibration", type="eng_float", default=0.0,
+                      help="set frequency offset to Hz", metavar="Hz")
+    parser.add_option("-g", "--gain", type="int",
+                      help="set RF gain", metavar="dB")
+    parser.add_option("-F", "--from-file", default=None,
+                      help="Read from file instead of USRP")
+    parser.add_option("-l", "--log", action="store_true", default=False,
+                      help="log flowgraph to files (LOTS of data)")
+    parser.add_option("-v", "--verbose", action="store_true", default=False,
+                      help="display debug output")
+    (options, args) = parser.parse_args()
+
+    if options.verbose:
+        print options
+
+    queue = gr.msg_queue()
+    tb = app_top_block(options, queue)
+    r = gr.runtime(tb)
+
+    try:
+        r.start()
+       while 1:
+           if not queue.empty_p():
+               msg = queue.delete_head() # Blocking read
+               page = join(split(msg.to_string(), chr(128)), '|')
+               disp = []
+               for n in range(len(page)):
+                   if ord(page[n]) < 32:
+                       disp.append('.')
+                   else:
+                       disp.append(page[n])
+               print join(disp, '')
+                                               
+           else:
+               time.sleep(1)
+
+    except KeyboardInterrupt:
+        r.stop()
+    
+if __name__ == "__main__":
+    main()
index 5541df8c7407ab932413ac279d61065f0255ecc6..377bc2ba099bb3c3bf79c552678c63fda3daf06e 100644 (file)
@@ -264,7 +264,7 @@ class db_dbs_rx (db_base.db_base):
             vcofreq = 2 * freq
         self._set_ade(1)
         rmin=max(2,self._refclk_freq()/2e6)
-        rmax=min(128,self._refclk_freq()/150e3)
+        rmax=min(128,self._refclk_freq()/500e3)
         r = 2
         n=0
         best_r = 2