Implemented AFC loop in gr-pager
authorjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Mon, 16 Jul 2007 06:46:06 +0000 (06:46 +0000)
committerjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Mon, 16 Jul 2007 06:46:06 +0000 (06:46 +0000)
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@5982 221aa14e-8319-0410-a670-987f0aec2ac5

gr-pager/src/flex_demod.py
gr-pager/src/pager.i
gr-pager/src/pager_flex_sync.cc
gr-pager/src/pager_flex_sync.h
gr-pager/src/pager_slicer_fb.h
gr-pager/src/usrp_flex.py

index 4e24c679c828d62883c8f0c920af818329a500e0..142a0c074cb5f82dc7a775917898a03d71f3d765 100644 (file)
@@ -42,13 +42,13 @@ class flex_demod(gr.hier_block2):
        self.connect(self, quad)
        
         rsamp = blks2.rational_resampler_fff(16, 25)
-        slicer = pager_swig.slicer_fb(5e-5) # DC removal averaging filter constant
-       sync = pager_swig.flex_sync(16000)
+        self.slicer = pager_swig.slicer_fb(5e-6) # DC removal averaging filter constant
+       self.sync = pager_swig.flex_sync()
 
-        self.connect(quad, rsamp, slicer, sync)
+        self.connect(quad, rsamp, self.slicer, self.sync)
 
        for i in range(4):
-           self.connect((sync, i), pager_swig.flex_deinterleave(), pager_swig.flex_parse(queue, freq))
+           self.connect((self.sync, i), pager_swig.flex_deinterleave(), pager_swig.flex_parse(queue, freq))
 
        if log:
            suffix = '_'+ "%3.3f" % (freq/1e6,) + '.dat'
@@ -57,5 +57,8 @@ class flex_demod(gr.hier_block2):
            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
+           self.connect(self.slicer, slicer_sink)
+
+    def dc_offset(self):
+       return self.slicer.dc_offset()
+                   
\ No newline at end of file
index f8e17965bec19b8b74c27b4ab03e3c9f35b52945..d39389e50434371c3323c5a8a7dc4b842d58c4f1 100644 (file)
@@ -47,18 +47,19 @@ private:
     pager_slicer_fb(float alpha);
 
 public:
+    float dc_offset() const { return d_avg; }
 };
 
 // ----------------------------------------------------------------
 
 GR_SWIG_BLOCK_MAGIC(pager,flex_sync);
 
-pager_flex_sync_sptr pager_make_flex_sync(int rate);
+pager_flex_sync_sptr pager_make_flex_sync();
 
 class pager_flex_sync : public gr_block
 {
 private:
-    pager_flex_sync(int rate);
+    pager_flex_sync();
 
 public:
 };
index c4e5f7c02fff8d55cbbf8c6dd4114bfa4e2adba5..e2e2e5f0b4cf81c7b3eb13b2083744070c8c5016 100644 (file)
@@ -30,9 +30,9 @@
 #include <gr_io_signature.h>
 #include <gr_count_bits.h>
 
-pager_flex_sync_sptr pager_make_flex_sync(int rate)
+pager_flex_sync_sptr pager_make_flex_sync()
 {
-    return pager_flex_sync_sptr(new pager_flex_sync(rate));
+    return pager_flex_sync_sptr(new pager_flex_sync());
 }
 
 // FLEX sync block takes input from sliced baseband stream [0-3] at specified 
@@ -41,13 +41,12 @@ pager_flex_sync_sptr pager_make_flex_sync(int rate)
 // worth of bits on each output phase for the data portion of the frame. Unused phases
 // get all zeros, which are considered idle code words.
 
-pager_flex_sync::pager_flex_sync(int rate) :
+pager_flex_sync::pager_flex_sync() :
     gr_block ("flex_sync",
     gr_make_io_signature (1, 1, sizeof(unsigned char)),
     gr_make_io_signature (4, 4, sizeof(unsigned char))),
-    d_sync(rate/1600) // Maximum samples per baud
+    d_sync(10) // Fixed at 10 samples per baud (@ 1600 baud)
 {
-    d_rate = rate;
     enter_idle();
 }
 
@@ -120,7 +119,7 @@ void pager_flex_sync::enter_idle()
     d_mode = 0;
     d_baudrate = 1600;
     d_levels = 2;
-    d_spb = d_rate/d_baudrate;
+    d_spb = 16000/d_baudrate;
     d_bit_a = 0;
     d_bit_b = 0;
     d_bit_c = 0;
@@ -141,7 +140,6 @@ void pager_flex_sync::enter_sync1()
     d_end = d_index;
     d_center = index_avg(d_start, d_end); // Center of goodness
     d_count = 0;
-    //printf("SYNC1:%08X ", flex_modes[d_mode].sync);
 }
 
 void pager_flex_sync::enter_sync2()
@@ -150,7 +148,7 @@ void pager_flex_sync::enter_sync2()
     d_count = 0;
     d_baudrate = flex_modes[d_mode].baud;
     d_levels = flex_modes[d_mode].levels;
-    d_spb = d_rate/d_baudrate;
+    d_spb = 16000/d_baudrate;
 
     if (d_baudrate == 3200) {
         // Oversampling buffer just got halved
index 813b7cf26e98764a0c2e13812ced88c65624c576..666c5bc7924275f646e49b079a32389f173c2298 100644 (file)
@@ -28,7 +28,7 @@ class pager_flex_sync;
 typedef boost::shared_ptr<pager_flex_sync> pager_flex_sync_sptr;
 typedef std::vector<gr_int64> gr_int64_vector;
 
-pager_flex_sync_sptr pager_make_flex_sync(int rate);
+pager_flex_sync_sptr pager_make_flex_sync();
 
 /*!
  * \brief flex sync description
@@ -39,8 +39,8 @@ class pager_flex_sync : public gr_block
 {
 private:
     // Constructors
-    friend pager_flex_sync_sptr pager_make_flex_sync(int rate);
-    pager_flex_sync(int rate);
+    friend pager_flex_sync_sptr pager_make_flex_sync();
+    pager_flex_sync();
    
     // State machine transitions
     void enter_idle();
@@ -58,7 +58,6 @@ private:
     enum state_t { ST_IDLE, ST_SYNCING, ST_SYNC1, ST_SYNC2, ST_DATA };
     state_t d_state;     
 
-    int d_rate;     // Incoming sample rate
     int d_index;    // Index into current baud
     int d_start;    // Start of good sync 
     int d_center;   // Center of bit
index cde7aa94e2408b5402044d5b1abf76a2565f1a67..c5b15e7c65e3838e98c0077c522b27b3ccab18d1 100644 (file)
@@ -49,6 +49,8 @@ public:
     int work (int noutput_items,
               gr_vector_const_void_star &input_items, 
               gr_vector_void_star &output_items);
+
+    float dc_offset() const { return d_avg; }
 };
 
 #endif /* INCLUDED_PAGER_SLICER_FB_H */
index da6141fcc6ccc7b4dae214be8c47fe75df569a5c..0ff16f3e1e3c5c875425557870f523f03c9f1c19 100755 (executable)
@@ -52,7 +52,10 @@ class app_top_block(gr.top_block):
     def __init__(self, options, queue):
         gr.top_block.__init__(self, "usrp_flex")
         self.options = options
-
+       self.offset = 0.0
+       self.adj_time = time.time()
+       self.verbose = options.verbose
+                       
        if options.from_file is None:
             # Set up USRP source with specified RX daughterboard
             self.src = usrp.source_c()
@@ -104,20 +107,31 @@ class app_top_block(gr.top_block):
        if options.verbose:
            print "Channel filter has", len(taps), "taps."
 
-        chan = gr.freq_xlating_fir_filter_ccf(10,    # Decimation rate
+        self.chan = gr.freq_xlating_fir_filter_ccf(10,    # Decimation rate
                                               taps,  # Filter taps
                                               0.0,   # Offset frequency
                                               250e3) # Sample rate
 
        if options.log:
            chan_sink = gr.file_sink(gr.sizeof_gr_complex, 'chan.dat')
-           self.connect(chan, chan_sink)
+           self.connect(self.chan, chan_sink)
 
         # FLEX protocol demodulator
-        flex = pager.flex_demod(queue, options.frequency, options.verbose, options.log)
+        self.flex = pager.flex_demod(queue, options.frequency, options.verbose, options.log)
 
-        self.connect(self.src, chan, flex)
-       
+        self.connect(self.src, self.chan, self.flex)
+
+    def freq_offset(self):
+       return self.flex.dc_offset()*1600
+
+    def adjust_freq(self):
+       if time.time() - self.adj_time > 1.6:   # Only do it once per FLEX frame
+           self.adj_time = time.time()
+           self.offset -= self.freq_offset()
+           self.chan.set_center_freq(self.offset)
+           if self.verbose:
+               print "Channel frequency offset (Hz):", int(self.offset)
+                       
 def main():
     parser = OptionParser(option_class=eng_option)
     parser.add_option("-f", "--frequency", type="eng_float", default=None,
@@ -161,7 +175,8 @@ def main():
                    else:
                        disp.append(page[n])
                print join(disp, '')
-                                               
+               tb.adjust_freq()
+                                                                               
            else:
                time.sleep(1)