Merge commit 'jblum/grc/tooltip'
authorJohnathan Corgan <jcorgan@corganenterprises.com>
Thu, 15 Apr 2010 16:39:36 +0000 (09:39 -0700)
committerJohnathan Corgan <jcorgan@corganenterprises.com>
Thu, 15 Apr 2010 16:39:36 +0000 (09:39 -0700)
* commit 'jblum/grc/tooltip':
  work on the string representations for parameters (large vectors could be too much to render, ie use truncation)

21 files changed:
config/grc_usrp2.m4
gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.cc
gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.h
gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.i
gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py
gnuradio-examples/python/pfb/channelize.py
gruel/src/include/gruel/thread.h
gruel/src/lib/Makefile.am
gruel/src/lib/thread.cc [new file with mode: 0644]
usrp/firmware/include/usrp_ids.h
usrp/firmware/src/common/build_eeprom.py
usrp2/host/apps/Makefile.am
usrp2/host/lib/Makefile.am
usrp2/host/lib/control.cc
usrp2/host/lib/control.h
usrp2/host/lib/ring.cc
usrp2/host/lib/ring.h
usrp2/host/lib/usrp2_impl.cc
usrp2/host/lib/usrp2_impl.h
usrp2/host/lib/usrp2_thread.cc [deleted file]
usrp2/host/lib/usrp2_thread.h [deleted file]

index f7064c9168ff6964b55b5aa4724dc9157606632c..701b100ad98a3c7e5f91c2eb8870644ed146aa33 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright 2008 Free Software Foundation, Inc.
+dnl Copyright 2008,2010 Free Software Foundation, Inc.
 dnl 
 dnl This file is part of GNU Radio
 dnl 
@@ -23,9 +23,8 @@ AC_DEFUN([GRC_USRP2],[
     dnl firmware uses a subsidiary configure.ac
     AC_CONFIG_SUBDIRS([usrp2/firmware])
 
-    dnl Don't do usrp if omnithread or gruel is skipped
+    dnl Don't do usrp if gruel is skipped
     GRC_CHECK_DEPENDENCY(usrp2, gruel)
-    GRC_CHECK_DEPENDENCY(usrp2, omnithread)
 
     dnl USRP2 host code only works on Linux at the moment
     AC_MSG_CHECKING([whether host_os is linux*])
index 7e34551c8ed4ce8e62ed4f85f4d33ddb28dad349..5fda47880f5cea77a62c54806f6bdd1c0a654468 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2009 Free Software Foundation, Inc.
+ * Copyright 2009,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <cstring>
 
 gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans, 
-                                                        const std::vector<float> &taps)
+                                                        const std::vector<float> &taps,
+                                                        float oversample_rate)
 {
-  return gr_pfb_channelizer_ccf_sptr (new gr_pfb_channelizer_ccf (numchans, taps));
+  return gr_pfb_channelizer_ccf_sptr (new gr_pfb_channelizer_ccf (numchans, taps,
+                                                                 oversample_rate));
 }
 
 
 gr_pfb_channelizer_ccf::gr_pfb_channelizer_ccf (unsigned int numchans, 
-                                     const std::vector<float> &taps)
-  : gr_sync_block ("pfb_channelizer_ccf",
-                  gr_make_io_signature (numchans, numchans, sizeof(gr_complex)),
-                  gr_make_io_signature (1, 1, numchans*sizeof(gr_complex))),
-    d_updated (false)
+                                               const std::vector<float> &taps,
+                                               float oversample_rate)
+  : gr_block ("pfb_channelizer_ccf",
+             gr_make_io_signature (numchans, numchans, sizeof(gr_complex)),
+             gr_make_io_signature (1, 1, numchans*sizeof(gr_complex))),
+    d_updated (false), d_numchans(numchans), d_oversample_rate(oversample_rate)
 {
-  d_numchans = numchans;
+  // The over sampling rate must be rationally related to the number of channels
+  // in that it must be N/i for i in [1,N], which gives an outputsample rate 
+  // of [fs/N, fs] where fs is the input sample rate.
+  // This tests the specified input sample rate to see if it conforms to this
+  // requirement within a few significant figures.
+  double intp = 0;
+  double x = (10000.0*rint(numchans / oversample_rate)) / 10000.0;
+  double fltp = modf(numchans / oversample_rate, &intp);
+  if(fltp != 0.0)
+    throw std::invalid_argument("gr_pfb_channelizer: oversample rate must be N/i for i in [1, N]"); 
+
   d_filters = std::vector<gr_fir_ccf*>(d_numchans);
 
   // Create an FIR filter for each channel and zero out the taps
@@ -60,10 +73,28 @@ gr_pfb_channelizer_ccf::gr_pfb_channelizer_ccf (unsigned int numchans,
 
   // Create the FFT to handle the output de-spinning of the channels
   d_fft = new gri_fft_complex (d_numchans, false);
+
+  // Although the filters change, we use this look up table
+  // to set the index of the FFT input buffer, which equivalently
+  // performs the FFT shift operation on every other turn.
+  d_rate_ratio = (int)rintf(d_numchans / d_oversample_rate);
+  d_idxlut = new int[d_numchans];
+  for(unsigned int i = 0; i < d_numchans; i++) {
+    d_idxlut[i] = d_numchans - ((i + d_rate_ratio) % d_numchans) - 1;
+  }
+
+  // Calculate the number of filtering rounds to do to evenly
+  // align the input vectors with the output channels
+  d_output_multiple = 1;
+  while((d_output_multiple * d_rate_ratio) % d_numchans != 0)
+    d_output_multiple++;
+  set_output_multiple(d_output_multiple);
 }
 
 gr_pfb_channelizer_ccf::~gr_pfb_channelizer_ccf ()
 {
+  delete [] d_idxlut; 
+  
   for(unsigned int i = 0; i < d_numchans; i++) {
     delete d_filters[i];
   }
@@ -101,7 +132,7 @@ gr_pfb_channelizer_ccf::set_taps (const std::vector<float> &taps)
   }
 
   // Set the history to ensure enough input items for each filter
-  set_history (d_taps_per_filter);
+  set_history (d_taps_per_filter+1);
 
   d_updated = true;
 }
@@ -121,9 +152,10 @@ gr_pfb_channelizer_ccf::print_taps()
 
 
 int
-gr_pfb_channelizer_ccf::work (int noutput_items,
-                             gr_vector_const_void_star &input_items,
-                             gr_vector_void_star &output_items)
+gr_pfb_channelizer_ccf::general_work (int noutput_items,
+                                     gr_vector_int &ninput_items,
+                                     gr_vector_const_void_star &input_items,
+                                     gr_vector_void_star &output_items)
 {
   gr_complex *in = (gr_complex *) input_items[0];
   gr_complex *out = (gr_complex *) output_items[0];
@@ -133,20 +165,35 @@ gr_pfb_channelizer_ccf::work (int noutput_items,
     return 0;               // history requirements may have changed.
   }
 
-  for(int i = 0; i < noutput_items; i++) {
-    // Move through filters from bottom to top
-    for(int j = d_numchans-1; j >= 0; j--) {
-      // Take in the items from the first input stream to d_numchans
-      in = (gr_complex*)input_items[d_numchans - 1 - j];
+  int n=1, i=-1, j=0, last;
+  int toconsume = (int)rintf(noutput_items/d_oversample_rate);
+  while(n <= toconsume) {
+    j = 0;
+    i = (i + d_rate_ratio) % d_numchans;
+    last = i;
+    while(i >= 0) {
+      in = (gr_complex*)input_items[j];
+      d_fft->get_inbuf()[d_idxlut[j]] = d_filters[i]->filter(&in[n]);
+      j++;
+      i--;
+    }
 
-      // Filter current input stream from bottom filter to top
-      d_fft->get_inbuf()[j] = d_filters[j]->filter(&in[i]);
+    i = d_numchans-1;
+    while(i > last) {
+      in = (gr_complex*)input_items[j];
+      d_fft->get_inbuf()[d_idxlut[j]] = d_filters[i]->filter(&in[n-1]);
+      j++;
+      i--;
     }
 
+    n += (i+d_rate_ratio) >= (int)d_numchans;
+
     // despin through FFT
     d_fft->execute();
-    memcpy(&out[d_numchans*i], d_fft->get_outbuf(), d_numchans*sizeof(gr_complex));
+    memcpy(out, d_fft->get_outbuf(), d_numchans*sizeof(gr_complex));
+    out += d_numchans;
   }
-  
+
+  consume_each(toconsume);
   return noutput_items;
 }
index b2e67e8173a5558b16499698d4134d6da480c860..d56ccdbc6c3fca32b6cb86539b18cd82bb4f60fc 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2009 Free Software Foundation, Inc.
+ * Copyright 2009,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #ifndef INCLUDED_GR_PFB_CHANNELIZER_CCF_H
 #define        INCLUDED_GR_PFB_CHANNELIZER_CCF_H
 
-#include <gr_sync_block.h>
+#include <gr_block.h>
 
 class gr_pfb_channelizer_ccf;
 typedef boost::shared_ptr<gr_pfb_channelizer_ccf> gr_pfb_channelizer_ccf_sptr;
 gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans, 
-                                                        const std::vector<float> &taps);
+                                                        const std::vector<float> &taps,
+                                                        float oversample_rate=1);
 
 class gr_fir_ccf;
 class gri_fft_complex;
@@ -88,6 +89,19 @@ class gri_fft_complex;
  *      <B><EM>self._taps = gr.firdes.low_pass_2(1, fs, BW, TB, 
  *           attenuation_dB=ATT, window=gr.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
  *
+ * The filter output can also be overs ampled. The over sampling rate 
+ * is the ratio of the the actual output sampling rate to the normal 
+ * output sampling rate. It must be rationally related to the number 
+ * of channels as N/i for i in [1,N], which gives an outputsample rate
+ * of [fs/N, fs] where fs is the input sample rate and N is the number
+ * of channels.
+ *
+ * For example, for 6 channels with fs = 6000 Hz, the normal rate is 
+ * 6000/6 = 1000 Hz. Allowable oversampling rates are 6/6, 6/5, 6/4, 
+ * 6/3, 6/2, and 6/1 where the output sample rate of a 6/1 oversample
+ * ratio is 6000 Hz, or 6 times the normal 1000 Hz. A rate of 6/5 = 1.2,
+ * so the output rate would be 1200 Hz.
+ *
  * The theory behind this block can be found in Chapter 6 of 
  * the following book.
  *
@@ -96,23 +110,40 @@ class gri_fft_complex;
  *
  */
 
-class gr_pfb_channelizer_ccf : public gr_sync_block
+class gr_pfb_channelizer_ccf : public gr_block
 {
  private:
   /*!
    * Build the polyphase filterbank decimator.
    * \param numchans (unsigned integer) Specifies the number of channels <EM>M</EM>
    * \param taps    (vector/list of floats) The prototype filter to populate the filterbank.
+   * \param oversample_rate (float)   The over sampling rate is the ratio of the the actual
+   *                                  output sampling rate to the normal output sampling rate.
+   *                                   It must be rationally related to the number of channels
+   *                                 as N/i for i in [1,N], which gives an outputsample rate 
+   *                                 of [fs/N, fs] where fs is the input sample rate and N is
+   *                                 the number of channels.
+   *                                 
+   *                                 For example, for 6 channels with fs = 6000 Hz, the normal
+   *                                 rate is 6000/6 = 1000 Hz. Allowable oversampling rates
+   *                                 are 6/6, 6/5, 6/4, 6/3, 6/2, and 6/1 where the output
+   *                                 sample rate of a 6/1 oversample ratio is 6000 Hz, or
+   *                                 6 times the normal 1000 Hz.
    */
   friend gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans,
-                                                                 const std::vector<float> &taps);
+                                                                 const std::vector<float> &taps,
+                                                                 float oversample_rate);
 
+  bool                    d_updated;
+  unsigned int             d_numchans;
+  float                    d_oversample_rate;
   std::vector<gr_fir_ccf*> d_filters;
   std::vector< std::vector<float> > d_taps;
-  gri_fft_complex         *d_fft;
-  unsigned int             d_numchans;
   unsigned int             d_taps_per_filter;
-  bool                    d_updated;
+  gri_fft_complex         *d_fft;
+  int                     *d_idxlut;
+  int                      d_rate_ratio;
+  int                      d_output_multiple;
 
   /*!
    * Build the polyphase filterbank decimator.
@@ -120,7 +151,8 @@ class gr_pfb_channelizer_ccf : public gr_sync_block
    * \param taps    (vector/list of floats) The prototype filter to populate the filterbank.
    */
   gr_pfb_channelizer_ccf (unsigned int numchans, 
-                         const std::vector<float> &taps);
+                         const std::vector<float> &taps,
+                         float oversample_rate);
 
 public:
   ~gr_pfb_channelizer_ccf ();
@@ -136,9 +168,10 @@ public:
    */
   void print_taps();
   
-  int work (int noutput_items,
-           gr_vector_const_void_star &input_items,
-           gr_vector_void_star &output_items);
+  int general_work (int noutput_items,
+                   gr_vector_int &ninput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
 };
 
 #endif
index 4bef90e2222b2b0609489dbe3a0da4bcabd60324..63e3e0fe6a45544af7e17cc44b94dfea3bb295e5 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2009 Free Software Foundation, Inc.
+ * Copyright 2009,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 GR_SWIG_BLOCK_MAGIC(gr,pfb_channelizer_ccf);
 
 gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans,
-                                                        const std::vector<float> &taps);
+                                                        const std::vector<float> &taps,
+                                                        float oversample_rate=1);
 
-class gr_pfb_channelizer_ccf : public gr_sync_block
+class gr_pfb_channelizer_ccf : public gr_block
 {
  private:
   gr_pfb_channelizer_ccf (unsigned int numchans,
-                         const std::vector<float> &taps);
+                         const std::vector<float> &taps,
+                         float oversample_rate);
 
  public:
   ~gr_pfb_channelizer_ccf ();
index c45ae4d1a95ced054a04ebdc37d72ae9d1097d1f..a479ed48ea9a357800fccd03dde273fccc3b69d3 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2009 Free Software Foundation, Inc.
+# Copyright 2009,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -29,16 +29,18 @@ class pfb_channelizer_ccf(gr.hier_block2):
     This simplifies the interface by allowing a single input stream to connect to this block.
     It will then output a stream for each channel.
     '''
-    def __init__(self, numchans, taps):
+    def __init__(self, numchans, taps, oversample_rate=1):
        gr.hier_block2.__init__(self, "pfb_channelizer_ccf",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
                                gr.io_signature(numchans, numchans, gr.sizeof_gr_complex)) # Output signature
 
         self._numchans = numchans
         self._taps = taps
+        self._oversample_rate = oversample_rate
 
         self.s2ss = gr.stream_to_streams(gr.sizeof_gr_complex, self._numchans)
-        self.pfb = gr.pfb_channelizer_ccf(self._numchans, self._taps)
+        self.pfb = gr.pfb_channelizer_ccf(self._numchans, self._taps,
+                                          self._oversample_rate)
         self.v2s = gr.vector_to_streams(gr.sizeof_gr_complex, self._numchans)
 
         self.connect(self, self.s2ss)
index bc83fae2739615b4603c41118566199477dadd55..27d87e558b4ee37d2351423b0f8a3391eafc01d6 100755 (executable)
@@ -101,7 +101,7 @@ def main():
         X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
                           window = lambda d: d*winfunc(fftlen),
                           scale_by_freq=True)
-        X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+        X_in = 10.0*scipy.log10(abs(X))
         f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
         pin_f = spin_f.plot(f_in, X_in, "b")
         spin_f.set_xlim([min(f_in), max(f_in)+1]) 
@@ -144,7 +144,7 @@ def main():
             X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs_o,
                               window = lambda d: d*winfunc(fftlen),
                               scale_by_freq=True)
-            X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+            X_o = 10.0*scipy.log10(abs(X))
             f_o = scipy.arange(-fs_o/2.0, fs_o/2.0, fs_o/float(X_o.size))
             p2_f = sp1_f.plot(f_o, X_o, "b")
             sp1_f.set_xlim([min(f_o), max(f_o)+1]) 
index 0e7acaa856d115967db9644b37a273cbd2bea252..d72e5520ce53926d47a77bdecb6d56a4aa868784 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2009 Free Software Foundation, Inc.
+ * Copyright 2009,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #define INCLUDED_THREAD_H
 
 #include <boost/thread.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
 
 namespace gruel {
 
+  typedef boost::thread                    thread;
   typedef boost::mutex                     mutex;
   typedef boost::unique_lock<boost::mutex> scoped_lock;
   typedef boost::condition_variable        condition_variable;
+  typedef boost::posix_time::time_duration duration;
+
+  /*!
+   * Returns absolute time 'secs' into the future
+   */
+  boost::system_time get_new_timeout(double secs);
 
 } /* namespace gruel */
 
index b21f8023c72e3f6d8d9b03bb38b291bf9e6355e5..6bde9ee272addaed96b97c1e8570803ea0c51458 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008,2009 Free Software Foundation, Inc.
+# Copyright 2008,2009,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -45,6 +45,7 @@ MSG_LIB = msg/libmsg.la
 libgruel_la_SOURCES =                  \
        realtime.cc                     \
        sys_pri.cc                      \
+       thread.cc                       \
        thread_body_wrapper.cc          \
        thread_group.cc
 
diff --git a/gruel/src/lib/thread.cc b/gruel/src/lib/thread.cc
new file mode 100644 (file)
index 0000000..d8f77b5
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gruel/thread.h>
+
+namespace gruel {
+
+  boost::system_time
+  get_new_timeout(double secs)
+  {
+    return boost::get_system_time() + boost::posix_time::milliseconds(long(secs*1e3));
+  }
+
+}
index dd5daed0122e84edaee5fb6a59d726d8968939a3..4152600bd25a8b324ea3a7d480c546ac2406609e 100644 (file)
@@ -55,6 +55,7 @@
 #define USB_PID_FSF_BDALE_8            0x0012    // Bdale Garbee <bdale@gag.com>
 #define USB_PID_FSF_BDALE_9            0x0013    // Bdale Garbee <bdale@gag.com>
 #define USB_PID_FSF_HPSDR_HERMES       0x0014    // HPSDR Hermes
+#define USB_PID_FSF_THINKRF            0x0015    // Catalin Patulea <catalin.patulea@thinkrf.com>
 
 #define USB_PID_FSF_LBNL_UXO            0x0018    // http://recycle.lbl.gov/~ldoolitt/uxo/
 
index ed9bb56a4816174b3d0d02f04ed64559a1022b16..d73cbbc4f74d647a80eef358a7bb34e33c41da1e 100755 (executable)
@@ -146,7 +146,7 @@ def build_shell_script (out, ihx_filename, rev, prefix):
 
     out.write ('#!/bin/sh\n')
     out.write ('usrper -x load_firmware ' + prefix + '/share/usrp/rev%d/std.ihx\n' % rev)
-    out.write ('sleep 1\n')
+    out.write ('sleep 2\n')
     
     # print "len(image) =", len(image)
     
@@ -161,7 +161,7 @@ def build_shell_script (out, ihx_filename, rev, prefix):
                    (i2c_addr, rom_addr, ''.join (hex_image[0:l])))
         hex_image = hex_image[l:]
         rom_addr = rom_addr + l
-        out.write ('sleep 1\n')
+        out.write ('sleep 2\n')
 
 if __name__ == '__main__':
     usage = "usage: %prog -p PREFIX -r REV [options] bootfile.ihx"
index db76601967611015358a0b1ca1ce8dbe22aa5d6d..4a26898fa7d9f5303f7b3f91ec5bc648d79ff9ee 100644 (file)
@@ -24,9 +24,8 @@ AM_CPPFLAGS = \
     $(GRUEL_INCLUDES)
 
 LDADD = \
-       $(USRP2_LA) \
-       $(GRUEL_LA) \
-        $(OMNITHREAD_LA)
+    $(USRP2_LA) \
+    $(GRUEL_LA)
 
 bin_PROGRAMS = \
        find_usrps \
index 772cf1446d80739753f99ebceaa7bf2b2f6a5bff..cda051bb07327f0ed20aabda8598f115598374e1 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2007,2008 Free Software Foundation, Inc.
+# Copyright 2007,2008,2010 Free Software Foundation, Inc.
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -45,11 +45,9 @@ libusrp2_la_SOURCES = \
        rx_sample_handler.cc \
        strtod_si.c \
        usrp2.cc \
-       usrp2_impl.cc \
-       usrp2_thread.cc
+       usrp2_impl.cc
 
 libusrp2_la_LIBADD = \
-       $(OMNITHREAD_LA) \
        $(GRUEL_LA) \
        $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB)
 
@@ -63,5 +61,4 @@ noinst_HEADERS = \
        pktfilter.h \
        ring.h \
        usrp2_bytesex.h \
-       usrp2_impl.h \
-       usrp2_thread.h
+       usrp2_impl.h
\ No newline at end of file
index bb71f79c27002bfadbecb305c0eae28a54495497..33a95c078722a8893e3ce9c5854a7d90a18fd6a2 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2009,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <config.h>
 #endif
 
-#include <gnuradio/omni_time.h>
 #include "control.h"
 #include <iostream>
+#include <gruel/thread.h>
 
 namespace usrp2 {
 
   pending_reply::pending_reply(unsigned int rid, void *buffer, size_t len)
-    : d_rid(rid), d_buffer(buffer), d_len(len), d_mutex(), d_cond(&d_mutex),
+    : d_rid(rid), d_buffer(buffer), d_len(len), d_mutex(), d_cond(),
       d_complete(false)
   {
   }
@@ -43,22 +43,23 @@ namespace usrp2 {
   int
   pending_reply::wait_for_completion(double secs)
   {
-    omni_time abs_timeout = omni_time::time(omni_time(secs));
-    omni_mutex_lock l(d_mutex);
-    while (!d_complete){
-      int r = d_cond.timedwait(abs_timeout.d_secs, abs_timeout.d_nsecs);
-      if (r == 0)              // timed out
-       return 0;
+    gruel::scoped_lock l(d_mutex);
+    boost::system_time to(gruel::get_new_timeout(secs));
+
+    while (!d_complete) {
+      if (!d_cond.timed_wait(l, to))
+       return 0; // timed out
     }
+
     return 1;
   }
 
   void
   pending_reply::notify_completion()
   {
-    omni_mutex_lock l(d_mutex);
+    gruel::scoped_lock l(d_mutex);
     d_complete = true;
-    d_cond.signal();
+    d_cond.notify_one();
   }
   
 } // namespace usrp2
index 46ce791ea3019915432ca498b639db143b4c2343..3515ba10fe6dc8de3c904dedc9de025d3a63d731 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008,2009 Free Software Foundation, Inc.
+ * Copyright 2008,2009,2010 Free Software Foundation, Inc.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 #ifndef INCLUDED_CONTROL_H
 #define INCLUDED_CONTROL_H
 
-#include <gnuradio/omnithread.h>
+#include <gruel/thread.h>
 #include <usrp2_eth_packet.h>
 
 namespace usrp2 {
@@ -130,8 +130,8 @@ namespace usrp2 {
     size_t         d_len;
 
     // d_mutex is used with d_cond and also protects d_complete
-    omni_mutex      d_mutex;
-    omni_condition  d_cond;
+    gruel::mutex      d_mutex;
+    gruel::condition_variable d_cond;
     bool           d_complete;
 
   public:
index 3c45821f84136373cb84261bab28fd07a51f19ff..d0048418cfe61eba72d833bd2a2dbc01badba72b 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -29,7 +29,7 @@ namespace usrp2 {
 
   ring::ring(unsigned int entries)
     : d_max(entries), d_read_ind(0), d_write_ind(0), d_ring(entries),
-      d_mutex(), d_not_empty(&d_mutex)
+      d_mutex(), d_not_empty()
   {
     for (unsigned int i = 0; i < entries; i++) {
       d_ring[i].d_base = 0;
@@ -40,15 +40,15 @@ namespace usrp2 {
   void 
   ring::wait_for_not_empty() 
   { 
-    omni_mutex_lock l(d_mutex);
+    gruel::scoped_lock l(d_mutex);
     while (empty()) 
-      d_not_empty.wait();
+      d_not_empty.wait(l);
   }
 
   bool
   ring::enqueue(void *p, size_t len)
   {
-    omni_mutex_lock l(d_mutex);
+    gruel::scoped_lock l(d_mutex);
     if (full())
       return false;
       
@@ -56,14 +56,14 @@ namespace usrp2 {
     d_ring[d_write_ind].d_base = p;
 
     inc_write_ind();
-    d_not_empty.signal();
+    d_not_empty.notify_one();
     return true;
   }
 
   bool
   ring::dequeue(void **p, size_t *len)
   {
-    omni_mutex_lock l(d_mutex);
+    gruel::scoped_lock l(d_mutex);
     if (empty())
       return false;
       
index 19ae9ae97221ff756e9f9bdc68a718631559c772..fd0ad0a9f3098e9e929feafd253df17ca99ee7eb 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #ifndef INCLUDED_RING_H
 #define INCLUDED_RING_H
 
-#include <gnuradio/omnithread.h>
 #include <stddef.h>
 #include <vector>
 #include <boost/shared_ptr.hpp>
+#include <gruel/thread.h>
 
 namespace usrp2 {
 
@@ -46,8 +46,8 @@ namespace usrp2 {
     };
     std::vector<ring_desc> d_ring;
 
-    omni_mutex d_mutex;
-    omni_condition d_not_empty;
+    gruel::mutex d_mutex;
+    gruel::condition_variable d_not_empty;
 
     void inc_read_ind()
     {
index d4f29baf0e73af23502aa43ec3e879f9629e1f00..5592c76ea932ee631914de62ad74e736a0c4063b 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008,2009 Free Software Foundation, Inc.
+ * Copyright 2008,2009,2010 Free Software Foundation, Inc.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,9 +24,9 @@
 #include <usrp2/tune_result.h>
 #include <usrp2/copiers.h>
 #include <gruel/inet.h>
+#include <gruel/realtime.h>
 #include <usrp2_types.h>
 #include "usrp2_impl.h"
-#include "usrp2_thread.h"
 #include "eth_buffer.h"
 #include "pktfilter.h"
 #include "control.h"
@@ -129,10 +129,10 @@ namespace usrp2 {
 
 
   usrp2::impl::impl(const std::string &ifc, props *p, size_t rx_bufsize)
-    : d_eth_buf(new eth_buffer(rx_bufsize)), d_interface_name(ifc), d_pf(0), d_bg_thread(0),
+    : d_eth_buf(new eth_buffer(rx_bufsize)), d_interface_name(ifc), d_pf(0),
       d_bg_running(false), d_rx_seqno(-1), d_tx_seqno(0), d_next_rid(0),
       d_num_rx_frames(0), d_num_rx_missing(0), d_num_rx_overruns(0), d_num_rx_bytes(0),
-      d_num_enqueued(0), d_enqueued_mutex(), d_bg_pending_cond(&d_enqueued_mutex),
+      d_num_enqueued(0), d_enqueued_mutex(), d_bg_pending_cond(),
       d_channel_rings(NCHANS), d_tx_interp(0), d_rx_decim(0), d_dont_enqueue(true)
   {
     if (!d_eth_buf->open(ifc, htons(U2_ETHERTYPE)))
@@ -152,8 +152,8 @@ namespace usrp2 {
 
     memset(d_pending_replies, 0, sizeof(d_pending_replies));
 
-    d_bg_thread = new usrp2_thread(this);
-    d_bg_thread->start();
+    // Kick off receive thread
+    start_bg();
 
     // In case the USRP2 was left streaming RX
     // FIXME: only one channel right now
@@ -208,7 +208,6 @@ namespace usrp2 {
   usrp2::impl::~impl()
   {
     stop_bg();
-    d_bg_thread = 0; // thread class deletes itself
     delete d_pf;
     d_eth_buf->close();
     delete d_eth_buf;
@@ -335,19 +334,25 @@ namespace usrp2 {
   //        Background loop: received packet demuxing
   // ----------------------------------------------------------------
 
+  void
+  usrp2::impl::start_bg()
+  {
+    d_rx_tg.create_thread(boost::bind(&usrp2::impl::bg_loop, this));
+  }
+
   void
   usrp2::impl::stop_bg()
   {
     d_bg_running = false;
-    d_bg_pending_cond.signal();
-
-    void *dummy_status;
-    d_bg_thread->join(&dummy_status);
+    d_bg_pending_cond.notify_one(); // FIXME: check if needed
+    d_rx_tg.join_all();
   }
 
   void
   usrp2::impl::bg_loop()
   {
+    gruel::enable_realtime_scheduling();
+
     d_bg_running = true;
     while(d_bg_running) {
       DEBUG_LOG(":");
@@ -362,9 +367,9 @@ namespace usrp2 {
       // The channel ring thread that decrements d_num_enqueued to zero
       // will signal this thread to continue.
       {
-        omni_mutex_lock l(d_enqueued_mutex);
+        gruel::scoped_lock l(d_enqueued_mutex);
         while(d_num_enqueued > 0 && d_bg_running)
-         d_bg_pending_cond.wait();
+         d_bg_pending_cond.wait(l);
       }
     }
     d_bg_running = false;
@@ -463,7 +468,7 @@ namespace usrp2 {
     unsigned int chan = u2p_chan(&pkt->hdrs.fixed);
 
     {
-      omni_mutex_lock l(d_channel_rings_mutex);
+      gruel::scoped_lock l(d_channel_rings_mutex);
 
       if (!d_channel_rings[chan]) {
        DEBUG_LOG("!");
@@ -650,7 +655,7 @@ namespace usrp2 {
     }
 
     {
-      omni_mutex_lock l(d_channel_rings_mutex);
+      gruel::scoped_lock l(d_channel_rings_mutex);
       if (d_channel_rings[channel]) {
        std::cerr << "usrp2: channel " << channel
                  << " already streaming" << std::endl;
@@ -704,7 +709,7 @@ namespace usrp2 {
     }
 
     {
-      omni_mutex_lock l(d_channel_rings_mutex);
+      gruel::scoped_lock guard(d_channel_rings_mutex);
       if (d_channel_rings[channel]) {
        std::cerr << "usrp2: channel " << channel
                  << " already streaming" << std::endl;
@@ -758,7 +763,7 @@ namespace usrp2 {
     }
 
     {
-      omni_mutex_lock l(d_channel_rings_mutex);
+      gruel::scoped_lock guard(d_channel_rings_mutex);
       if (d_channel_rings[channel]) {
        std::cerr << "usrp2: channel " << channel
                  << " already streaming" << std::endl;
@@ -820,7 +825,7 @@ namespace usrp2 {
     op_generic_t reply;
 
     {
-      omni_mutex_lock l(d_channel_rings_mutex);
+      gruel::scoped_lock l(d_channel_rings_mutex);
 
       memset(&cmd, 0, sizeof(cmd));
       init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
index a75947922faec6dd47088152ddab89d498342434..eee26358eaca556852b83f68e55cf9699719d0f7 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008,2009 Free Software Foundation, Inc.
+ * Copyright 2008,2009,2010 Free Software Foundation, Inc.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
 #include <usrp2/usrp2.h>
 #include <usrp2/data_handler.h>
 #include <usrp2_eth_packet.h>
+#include <gruel/thread.h>
 #include <boost/scoped_ptr.hpp>
 #include "control.h"
 #include "ring.h"
@@ -60,7 +61,8 @@ namespace usrp2 {
     std::string    d_interface_name;
     pktfilter     *d_pf;
     std::string    d_addr;       // FIXME: use u2_mac_addr_t instead
-    usrp2_thread  *d_bg_thread;
+
+    boost::thread_group d_rx_tg;
     volatile bool  d_bg_running; // TODO: multistate if needed
 
     int            d_rx_seqno;
@@ -72,14 +74,14 @@ namespace usrp2 {
     unsigned int   d_num_rx_bytes;
 
     unsigned int   d_num_enqueued;
-    omni_mutex     d_enqueued_mutex;
-    omni_condition d_bg_pending_cond;
+    gruel::mutex   d_enqueued_mutex;
+    gruel::condition_variable d_bg_pending_cond;
 
     // all pending_replies are stack allocated, thus no possibility of leaking these
     pending_reply *d_pending_replies[NRIDS]; // indexed by 8-bit reply id
 
     std::vector<ring_sptr>   d_channel_rings; // indexed by 5-bit channel number
-    omni_mutex     d_channel_rings_mutex;
+    gruel::mutex   d_channel_rings_mutex;
 
     db_info       d_tx_db_info;
     db_info       d_rx_db_info;
@@ -90,20 +92,21 @@ namespace usrp2 {
     bool          d_dont_enqueue;
 
     void inc_enqueued() {
-      omni_mutex_lock l(d_enqueued_mutex);
+      gruel::scoped_lock l(d_enqueued_mutex);
       d_num_enqueued++;
     }
 
     void dec_enqueued() {
-      omni_mutex_lock l(d_enqueued_mutex);
+      gruel::scoped_lock l(d_enqueued_mutex);
       if (--d_num_enqueued == 0)
-        d_bg_pending_cond.signal();
+        d_bg_pending_cond.notify_one();
     }
 
     static bool parse_mac_addr(const std::string &s, u2_mac_addr_t *p);
     void init_et_hdrs(u2_eth_packet_t *p, const std::string &dst);
     void init_etf_hdrs(u2_eth_packet_t *p, const std::string &dst,
                       int word0_flags, int chan, uint32_t timestamp);
+    void start_bg();
     void stop_bg();
     void init_config_rx_v2_cmd(op_config_rx_v2_cmd *cmd);
     void init_config_tx_v2_cmd(op_config_tx_v2_cmd *cmd);
@@ -119,8 +122,6 @@ namespace usrp2 {
     impl(const std::string &ifc, props *p, size_t rx_bufsize);
     ~impl();
 
-    void bg_loop();
-
     std::string mac_addr() const { return d_addr; } // FIXME: convert from u2_mac_addr_t
     std::string interface_name() const { return d_interface_name; }
 
@@ -199,6 +200,9 @@ namespace usrp2 {
     bool sync_every_pps(bool enable);
     std::vector<uint32_t> peek32(uint32_t addr, uint32_t words);
     bool poke32(uint32_t addr, const std::vector<uint32_t> &data);
+
+    // Receive thread, need to be public for boost::bind
+    void bg_loop();
   };
 
 } // namespace usrp2
diff --git a/usrp2/host/lib/usrp2_thread.cc b/usrp2/host/lib/usrp2_thread.cc
deleted file mode 100644 (file)
index d147703..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * This program 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 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "usrp2_thread.h"
-#include "usrp2_impl.h"
-#include <gruel/realtime.h>
-#include <gruel/sys_pri.h>
-#include <iostream>
-
-#define USRP2_THREAD_DEBUG 1
-
-namespace usrp2 {
-
-  usrp2_thread::usrp2_thread(usrp2::impl *u2) :
-    omni_thread(NULL, PRIORITY_HIGH),
-    d_u2(u2)
-  {
-  }
-  
-  usrp2_thread::~usrp2_thread()
-  {
-    // we don't own this, just forget it
-    d_u2 = 0;
-  }
-  
-  void
-  usrp2_thread::start()
-  {
-    start_undetached();
-  }
-  
-  void *
-  usrp2_thread::run_undetached(void *arg)
-  {
-    if (gruel::enable_realtime_scheduling(gruel::sys_pri::usrp2_backend()) != gruel::RT_OK)
-      std::cerr << "usrp2: failed to enable realtime scheduling" << std::endl;    
-
-    // This is the first code to run in the new thread context.
-    d_u2->bg_loop();
-    
-    return 0;
-  }
-
-} // namespace usrp2
-
diff --git a/usrp2/host/lib/usrp2_thread.h b/usrp2/host/lib/usrp2_thread.h
deleted file mode 100644 (file)
index 12723e9..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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.
- */
-
-#ifndef INCLUDED_USRP2_THREAD_H
-#define INCLUDED_USRP2_THREAD_H
-
-#include <gnuradio/omnithread.h>
-#include <usrp2_impl.h>
-
-namespace usrp2 {
-
-  class usrp2_thread : public omni_thread
-  {
-  private:
-    usrp2::impl *d_u2;    
-    
-  public:
-    usrp2_thread(usrp2::impl *u2);
-    ~usrp2_thread();
-    
-    void start();
-    
-    virtual void *run_undetached(void *arg);
-  };
-  
-} // namespace usrp2
-
-#endif /* INCLUDED_USRP2_THREAD_H */