commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] r10676 - in gnuradio/branches/releases/3.2: . config g


From: jcorgan
Subject: [Commit-gnuradio] r10676 - in gnuradio/branches/releases/3.2: . config gnuradio-core/src/lib/general gnuradio-core/src/lib/runtime gnuradio-core/src/python/gnuradio/gr gr-usrp/apps gr-utils/src/python usrp/host/apps
Date: Tue, 24 Mar 2009 09:30:01 -0600 (MDT)

Author: jcorgan
Date: 2009-03-24 09:30:01 -0600 (Tue, 24 Mar 2009)
New Revision: 10676

Modified:
   gnuradio/branches/releases/3.2/
   gnuradio/branches/releases/3.2/config/grc_gr_wxgui.m4
   
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.cc
   gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_hier_block2.h
   gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_hier_block2.i
   
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
   gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_top_block.h
   
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc
   gnuradio/branches/releases/3.2/gnuradio-core/src/python/gnuradio/gr/pubsub.py
   
gnuradio/branches/releases/3.2/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py
   
gnuradio/branches/releases/3.2/gnuradio-core/src/python/gnuradio/gr/top_block.py
   gnuradio/branches/releases/3.2/gr-usrp/apps/usrp_siggen.cc
   gnuradio/branches/releases/3.2/gr-usrp/apps/usrp_siggen.h
   gnuradio/branches/releases/3.2/gr-utils/src/python/usrp_siggen.py
   gnuradio/branches/releases/3.2/usrp/host/apps/Makefile.am
   gnuradio/branches/releases/3.2/usrp/host/apps/test_usrp_standard_tx.cc
Log:
Applied changesets r10646, r10648:10650, r10652:10655, r10661, r10671 to 
release 3.2 branch.


Property changes on: gnuradio/branches/releases/3.2
___________________________________________________________________
Modified: svn:mergeinfo
   - /gnuradio/branches/developers/michaelld/am_swig_4:10555-10595
/gnuradio/branches/developers/michaelld/two_mods:10540-10546
/gnuradio/trunk:10356-10359,10481-10482,10497-10499,10506-10507,10511,10514,10521,10523-10524,10529,10531,10535,10537-10538,10550-10551,10556,10558-10560,10562-10563,10565,10574-10576,10578-10579,10581-10582,10585,10587,10596-10600,10623-10624,10629,10632-10634,10645
   + /gnuradio/branches/developers/eb/t348:10638-10648
/gnuradio/branches/developers/michaelld/am_swig_4:10555-10595
/gnuradio/branches/developers/michaelld/two_mods:10540-10546
/gnuradio/trunk:10356-10359,10481-10482,10497-10499,10506-10507,10511,10514,10521,10523-10524,10529,10531,10535,10537-10538,10550-10551,10556,10558-10560,10562-10563,10565,10574-10576,10578-10579,10581-10582,10585,10587,10596-10600,10623-10624,10629,10632-10634,10645-10646,10649-10650,10653-10655,10661,10671

Modified: gnuradio/branches/releases/3.2/config/grc_gr_wxgui.m4
===================================================================
--- gnuradio/branches/releases/3.2/config/grc_gr_wxgui.m4       2009-03-24 
15:11:47 UTC (rev 10675)
+++ gnuradio/branches/releases/3.2/config/grc_gr_wxgui.m4       2009-03-24 
15:30:01 UTC (rev 10676)
@@ -29,8 +29,8 @@
     dnl   yes  : if the --enable code passed muster and all dependencies are 
met
     dnl   no   : otherwise
     if test $passed = yes; then
-       PYTHON_CHECK_MODULE([wx],[Python wxWidgets wrappers],[],[passed=no])
-       PYTHON_CHECK_MODULE([numpy],[Numeric Python extensions],[],[passed=no])
+        PYTHON_CHECK_MODULE([wx],[Python wxWidgets wrappers >= 
2.8],[],[passed=no],[wx.version().split()[[0]] >= "2.8"])
+        PYTHON_CHECK_MODULE([numpy],[Numeric Python extensions],[],[passed=no])
     fi
 
     AC_CONFIG_FILES([ \
@@ -38,7 +38,7 @@
         gr-wxgui/gr-wxgui.pc \
         gr-wxgui/src/Makefile \
         gr-wxgui/src/python/Makefile \
-       gr-wxgui/src/python/plotter/Makefile \
+        gr-wxgui/src/python/plotter/Makefile \
     ])
 
     GRC_BUILD_CONDITIONAL(gr-wxgui)

Modified: 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.cc
===================================================================
--- 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.cc
     2009-03-24 15:11:47 UTC (rev 10675)
+++ 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.cc
     2009-03-24 15:30:01 UTC (rev 10676)
@@ -108,9 +108,10 @@
 
   int  ii = 0;                         // input index
   int          oo = 0;                         // output index
+  int   ni = ninput_items[0] - d_interp->ntaps(); // don't use more input than 
this
   float mm_val;
 
-  while (oo < noutput_items){
+  while (oo < noutput_items && ii < ni ){
 
     // produce output sample
     out[oo] = d_interp->interpolate (&in[ii], d_mu);
@@ -132,5 +133,5 @@
 
   consume_each (ii);
 
-  return noutput_items;
+  return oo;
 }

Modified: 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_hier_block2.h
===================================================================
--- 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_hier_block2.h   
    2009-03-24 15:11:47 UTC (rev 10675)
+++ 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_hier_block2.h   
    2009-03-24 15:30:01 UTC (rev 10676)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006,2007,2008 Free Software Foundation, Inc.
+ * Copyright 2006,2007,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -124,9 +124,9 @@
   /*!
    * Lock a flowgraph in preparation for reconfiguration.  When an equal
    * number of calls to lock() and unlock() have occurred, the flowgraph
-   * will be restarted automatically.
+   * will be reconfigured.
    *
-   * N.B. lock() and unlock() cannot be called from a flowgraph thread
+   * N.B. lock() and unlock() may not be called from a flowgraph thread
    * (E.g., gr_block::work method) or deadlock will occur when
    * reconfiguration happens.
    */
@@ -135,9 +135,9 @@
   /*!
    * Unlock a flowgraph in preparation for reconfiguration.  When an equal
    * number of calls to lock() and unlock() have occurred, the flowgraph
-   * will be restarted automatically.
+   * will be reconfigured.
    *
-   * N.B. lock() and unlock() cannot be called from a flowgraph thread
+   * N.B. lock() and unlock() may not be called from a flowgraph thread
    * (E.g., gr_block::work method) or deadlock will occur when
    * reconfiguration happens.
    */

Modified: 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_hier_block2.i
===================================================================
--- 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_hier_block2.i   
    2009-03-24 15:11:47 UTC (rev 10675)
+++ 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_hier_block2.i   
    2009-03-24 15:30:01 UTC (rev 10676)
@@ -31,7 +31,8 @@
 %rename(hier_block2_swig) gr_make_hier_block2;
 gr_hier_block2_sptr gr_make_hier_block2(const std::string name,
                                         gr_io_signature_sptr input_signature,
-                                        gr_io_signature_sptr output_signature);
+                                        gr_io_signature_sptr output_signature)
+  throw (std::runtime_error);
 
 class gr_hier_block2 : public gr_basic_block
 {

Modified: 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
===================================================================
--- 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
       2009-03-24 15:11:47 UTC (rev 10675)
+++ 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
       2009-03-24 15:30:01 UTC (rev 10676)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006,2007 Free Software Foundation, Inc.
+ * Copyright 2006,2007,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -33,10 +33,24 @@
 gr_hier_block2_detail::gr_hier_block2_detail(gr_hier_block2 *owner) :
   d_owner(owner), 
   d_parent_detail(0),
-  d_fg(gr_make_flowgraph()),
-  d_inputs(owner->input_signature()->max_streams()),
-  d_outputs(owner->output_signature()->max_streams())
+  d_fg(gr_make_flowgraph())
 {
+  int min_inputs = owner->input_signature()->min_streams();
+  int max_inputs = owner->input_signature()->max_streams();
+  int min_outputs = owner->output_signature()->min_streams();
+  int max_outputs = owner->output_signature()->max_streams();
+
+  if (max_inputs == gr_io_signature::IO_INFINITE ||
+      max_outputs == gr_io_signature::IO_INFINITE ||
+      (min_inputs != max_inputs) ||(min_outputs != max_outputs) ) {
+    std::stringstream msg;
+    msg << "Hierarchical blocks do not yet support arbitrary or"
+       << " variable numbers of inputs or outputs (" << d_owner->name() << ")";
+    throw std::runtime_error(msg.str());
+  }
+
+  d_inputs = gr_endpoint_vector_t(max_inputs);
+  d_outputs = gr_endpoint_vector_t(max_outputs);
 }
 
 gr_hier_block2_detail::~gr_hier_block2_detail()
@@ -267,6 +281,12 @@
       throw std::runtime_error(msg.str());
     }
 
+    if (d_inputs[port] == gr_endpoint()) {
+      msg << "hierarchical block '" << d_owner->name() << "' input " << port
+         << " is not connected internally";
+      throw std::runtime_error(msg.str());
+    }
+
     result = resolve_endpoint(d_inputs[port], true);
   }
   else {
@@ -275,6 +295,12 @@
       throw std::runtime_error(msg.str());
     }
 
+    if (d_outputs[port] == gr_endpoint()) {
+      msg << "hierarchical block '" << d_owner->name() << "' output " << port
+         << " is not connected internally";
+      throw std::runtime_error(msg.str());
+    }
+
     result = resolve_endpoint(d_outputs[port], false);
   }
 

Modified: 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_top_block.h
===================================================================
--- gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_top_block.h 
2009-03-24 15:11:47 UTC (rev 10675)
+++ gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/gr_top_block.h 
2009-03-24 15:30:01 UTC (rev 10676)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007,2008 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -51,21 +51,22 @@
    * \brief The simple interface to running a flowgraph.
    *
    * Calls start() then wait().  Used to run a flowgraph that will stop
-   * on its own, or to run a flowgraph indefinitely until SIGINT is
-   * received.
+   * on its own, or when another thread will call stop().
    */
   void run();
 
   /*!
    * Start the contained flowgraph.  Creates one or more threads to
    * execute the flow graph.  Returns to the caller once the threads
-   * are created.
+   * are created.  Calling start() on a top_block that is already
+   * started IS an error.
    */
   void start();
   
   /*!
    * Stop the running flowgraph.  Notifies each thread created by the
-   * scheduler to shutdown, then returns to caller.
+   * scheduler to shutdown, then returns to caller. Calling stop() on
+   * a top_block that is already stopped IS NOT an error.
    */
   void stop();
 
@@ -73,16 +74,17 @@
    * Wait for a flowgraph to complete.  Flowgraphs complete when
    * either (1) all blocks indicate that they are done (typically only
    * when using gr.file_source, or gr.head, or (2) after stop() has been
-   * called to request shutdown.
+   * called to request shutdown.  Calling wait on a top_block that is
+   * not running IS NOT an error (wait returns w/o blocking).
    */
   void wait();
 
   /*!
    * Lock a flowgraph in preparation for reconfiguration.  When an equal
    * number of calls to lock() and unlock() have occurred, the flowgraph
-   * will be restarted automatically.
+   * will be reconfigured.
    *
-   * N.B. lock() and unlock() cannot be called from a flowgraph thread
+   * N.B. lock() and unlock() may not be called from a flowgraph thread
    * (E.g., gr_block::work method) or deadlock will occur when
    * reconfiguration happens.
    */
@@ -91,9 +93,9 @@
   /*!
    * Unlock a flowgraph in preparation for reconfiguration.  When an equal
    * number of calls to lock() and unlock() have occurred, the flowgraph
-   * will be restarted automatically.
+   * will be reconfigured.
    *
-   * N.B. lock() and unlock() cannot be called from a flowgraph thread
+   * N.B. lock() and unlock() may not be called from a flowgraph thread
    * (E.g., gr_block::work method) or deadlock will occur when
    * reconfiguration happens.
    */

Modified: 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc
===================================================================
--- 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc
   2009-03-24 15:11:47 UTC (rev 10675)
+++ 
gnuradio/branches/releases/3.2/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc
   2009-03-24 15:30:01 UTC (rev 10676)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006,2008 Free Software Foundation, Inc.
+ * Copyright 2006,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -33,8 +33,8 @@
 void qa_gr_hier_block2::test_make()
 {
     gr_hier_block2_sptr src1(gr_make_hier_block2("test",
-                                                gr_make_io_signature(1, 2, 1 * 
sizeof(int)),
-                                                gr_make_io_signature(3, 4, 2 * 
sizeof(int))));
+                                                gr_make_io_signature(1, 1, 1 * 
sizeof(int)),
+                                                gr_make_io_signature(1, 1, 1 * 
sizeof(int))));
 
     CPPUNIT_ASSERT(src1);
     CPPUNIT_ASSERT_EQUAL(std::string("test"), src1->name());
@@ -43,14 +43,14 @@
                         src1->input_signature()->sizeof_stream_item(0));
 
     CPPUNIT_ASSERT_EQUAL(1, src1->input_signature()->min_streams());
-    CPPUNIT_ASSERT_EQUAL(2, src1->input_signature()->max_streams());
+    CPPUNIT_ASSERT_EQUAL(1, src1->input_signature()->max_streams());
 
 
-    CPPUNIT_ASSERT_EQUAL(2 * (int) sizeof(int), 
+    CPPUNIT_ASSERT_EQUAL(1 * (int) sizeof(int), 
                         src1->output_signature()->sizeof_stream_item(0));
 
-    CPPUNIT_ASSERT_EQUAL(3, src1->output_signature()->min_streams());
-    CPPUNIT_ASSERT_EQUAL(4, src1->output_signature()->max_streams());
+    CPPUNIT_ASSERT_EQUAL(1, src1->output_signature()->min_streams());
+    CPPUNIT_ASSERT_EQUAL(1, src1->output_signature()->max_streams());
 
 }
 


Property changes on: 
gnuradio/branches/releases/3.2/gnuradio-core/src/python/gnuradio/gr/pubsub.py
___________________________________________________________________
Added: svn:mergeinfo
   + 
/gnuradio/branches/developers/eb/t348/gnuradio-core/src/python/gnuradio/gr/pubsub.py:10638-10648
/gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/pubsub.py:10653-10655,10661,10671

Modified: 
gnuradio/branches/releases/3.2/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py
===================================================================
--- 
gnuradio/branches/releases/3.2/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py
       2009-03-24 15:11:47 UTC (rev 10675)
+++ 
gnuradio/branches/releases/3.2/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py
       2009-03-24 15:30:01 UTC (rev 10676)
@@ -239,6 +239,18 @@
         tb.connect(hb)
         tb.run()
         self.assertEquals(expected_data, dst.data())
+
+    def test_027_disconnected_internal(self):
+        tb = gr.top_block()
+        hb = gr.hier_block2("block",
+                            gr.io_signature(1, 1, 1),
+                            gr.io_signature(1, 1, 1))
+        src = gr.vector_source_b([1, ])
+        dst = gr.vector_sink_b()
+        tb.connect(src, hb, dst) # hb is not connected internally
+        self.assertRaises(RuntimeError, 
+                          lambda: tb.run())
+
     
 if __name__ == "__main__":
     gr_unittest.main()

Modified: 
gnuradio/branches/releases/3.2/gnuradio-core/src/python/gnuradio/gr/top_block.py
===================================================================
--- 
gnuradio/branches/releases/3.2/gnuradio-core/src/python/gnuradio/gr/top_block.py
    2009-03-24 15:11:47 UTC (rev 10675)
+++ 
gnuradio/branches/releases/3.2/gnuradio-core/src/python/gnuradio/gr/top_block.py
    2009-03-24 15:30:01 UTC (rev 10676)
@@ -32,6 +32,25 @@
 #
 # This kludge allows ^C to interrupt top_block.run and top_block.wait
 #
+# The problem that we are working around is that Python only services
+# signals (e.g., KeyboardInterrupt) in its main thread.  If the main
+# thread is blocked in our C++ version of wait, even though Python's
+# SIGINT handler fires, and even though there may be other python
+# threads running, no one will know.  Thus instead of directly waiting
+# in the thread that calls wait (which is likely to be the Python main
+# thread), we create a separate thread that does the blocking wait,
+# and then use the thread that called wait to do a slow poll of an
+# event queue.  That thread, which is executing "wait" below is
+# interruptable, and if it sees a KeyboardInterrupt, executes a stop
+# on the top_block, then goes back to waiting for it to complete.
+# This ensures that the unlocked wait that was in progress (in the
+# _top_block_waiter thread) can complete, release its mutex and back
+# out.  If we don't do that, we are never able to clean up, and nasty
+# things occur like leaving the USRP transmitter sending a carrier.
+#
+# See also top_block.wait (below), which uses this class to implement
+# the interruptable wait.
+#
 class _top_block_waiter(_threading.Thread):
     def __init__(self, tb):
         _threading.Thread.__init__(self)
@@ -45,8 +64,12 @@
         self.event.set()
 
     def wait(self):
-        while not self.event.isSet():
-            self.event.wait(0.100)
+        try:
+            while not self.event.isSet():
+                self.event.wait(0.100)
+        except KeyboardInterrupt:
+            self.tb.stop()
+            self.wait()
 
 
 #

Modified: gnuradio/branches/releases/3.2/gr-usrp/apps/usrp_siggen.cc
===================================================================
--- gnuradio/branches/releases/3.2/gr-usrp/apps/usrp_siggen.cc  2009-03-24 
15:11:47 UTC (rev 10675)
+++ gnuradio/branches/releases/3.2/gr-usrp/apps/usrp_siggen.cc  2009-03-24 
15:30:01 UTC (rev 10676)
@@ -60,20 +60,20 @@
 usrp_siggen_sptr make_usrp_siggen(int which, usrp_subdev_spec spec, 
                                  double rf_freq, int interp, double wfreq,
                                  int waveform, float amp, float gain, 
-                                 float offset)
+                                 float offset, long long nsamples)
 {
   return gnuradio::get_initial_sptr(new usrp_siggen(which, spec, 
                                                    rf_freq, interp, wfreq,
                                                    waveform, amp, gain, 
-                                                   offset));
+                                                   offset, nsamples));
 }
 
 // Hierarchical block constructor, with no inputs or outputs
 usrp_siggen::usrp_siggen(int which, usrp_subdev_spec spec, 
                         double rf_freq, int interp, double wfreq,
                         int waveform, float amp, float gain, 
-                        float offset) :
-  gr_top_block("usrp_siggen")
+                        float offset, long long nsamples)
+  : gr_top_block("usrp_siggen")
 {
   usrp_sink_c_sptr usrp = usrp_make_sink_c(which, interp);
 
@@ -126,7 +126,14 @@
 
   siggen->set_waveform((gr_waveform_t)waveform);
 
-  connect(source, 0, usrp, 0);
+  if (nsamples > 0){
+    gr_block_sptr head = gr_make_head(sizeof(gr_complex), nsamples);
+    connect(source, 0, head, 0);
+    connect(head, 0, usrp, 0);
+  }
+  else {
+    connect(source, 0, usrp, 0);
+  }
 }
 
 int main(int argc, char *argv[])
@@ -140,6 +147,7 @@
   float gain = -1;                     // set the d'board PGA gain
   float offset = 0;                    // set waveform offset
   int waveform;
+  double nsamples = 0;                // set the number of samples to transmit 
(0 -> inf)
 
   po::options_description cmdconfig("Program options");
   cmdconfig.add_options()
@@ -155,9 +163,10 @@
     ("uniform", "generate Uniform random output")
 
     ("waveform-freq,w", po::value<double>(&wfreq), "set waveform frequency to 
FREQ")
-    ("amplitdue,a", po::value<float>(&amp), "set amplitude")
+    ("amplitude,a", po::value<float>(&amp), "set amplitude")
     ("gain,g", po::value<float>(&gain), "set output gain to GAIN")
     ("offset,o", po::value<float>(&offset), "set waveform offset to OFFSET")
+    ("nsamples,N", po::value<double>(&nsamples), "number of samples to send 
[default=+inf]")
     ;
   
   po::variables_map vm;
@@ -199,14 +208,15 @@
     waveform = GR_SIN_WAVE;
   }
 
-  printf("which:   %d\n", which);
-  printf("interp:  %d\n", interp);
-  printf("rf_freq: %g\n", rf_freq);
-  printf("amp:     %f\n", amp);
+  printf("which:    %d\n", which);
+  printf("interp:   %d\n", interp);
+  printf("rf_freq:  %g\n", rf_freq);
+  printf("amp:      %f\n", amp);
+  printf("nsamples: %g\n", nsamples);
 
   usrp_siggen_sptr top_block = make_usrp_siggen(which, spec, rf_freq, 
                                                interp, wfreq, waveform,
-                                               amp, gain, offset);
+                                               amp, gain, offset, (long long) 
nsamples);
 
   top_block->run();
   

Modified: gnuradio/branches/releases/3.2/gr-usrp/apps/usrp_siggen.h
===================================================================
--- gnuradio/branches/releases/3.2/gr-usrp/apps/usrp_siggen.h   2009-03-24 
15:11:47 UTC (rev 10675)
+++ gnuradio/branches/releases/3.2/gr-usrp/apps/usrp_siggen.h   2009-03-24 
15:30:01 UTC (rev 10676)
@@ -31,7 +31,7 @@
 usrp_siggen_sptr make_usrp_siggen(int which, usrp_subdev_spec spec, 
                                  double rf_freq, int interp, double wfreq,
                                  int waveform, float amp, float gain, 
-                                 float offset);
+                                 float offset, long long nsamples);
 
 class usrp_siggen : public gr_top_block
 {
@@ -39,11 +39,12 @@
     usrp_siggen(int which, usrp_subdev_spec spec, 
                double rf_freq, int interp, double wfreq,
                int waveform, float amp, float gain, 
-               float offset);
+               float offset, long long nsamples);
     friend usrp_siggen_sptr make_usrp_siggen(int which, usrp_subdev_spec spec, 
                                             double rf_freq, int interp, double 
wfreq,
                                             int waveform, float amp, float 
gain, 
-                                            float offset);
+                                            float offset,
+                                            long long nsamples);
     
  public:
     gr_block_sptr source;

Modified: gnuradio/branches/releases/3.2/gr-utils/src/python/usrp_siggen.py
===================================================================
--- gnuradio/branches/releases/3.2/gr-utils/src/python/usrp_siggen.py   
2009-03-24 15:11:47 UTC (rev 10675)
+++ gnuradio/branches/releases/3.2/gr-utils/src/python/usrp_siggen.py   
2009-03-24 15:30:01 UTC (rev 10676)
@@ -29,7 +29,7 @@
 
 
 class my_top_block(gr.top_block):
-    def __init__ (self):
+    def __init__ (self, nsamples):
         gr.top_block.__init__(self)
         
         # controllable values
@@ -38,6 +38,7 @@
         self.waveform_ampl = 16000
         self.waveform_freq = 100.12345e3
         self.waveform_offset = 0
+        self.nsamples = nsamples
         self._instantiate_blocks ()
         self.set_waveform_type (self.waveform_type)
 
@@ -86,19 +87,30 @@
         self.noisegen = gr.noise_source_c (gr.GR_UNIFORM,
                                            self.waveform_ampl)
 
+        self.head = None
+        if self.nsamples > 0:
+            self.head = gr.head(gr.sizeof_gr_complex, int(self.nsamples))
+
         # self.file_sink = gr.file_sink (gr.sizeof_gr_complex, "siggen.dat")
 
     def _configure_graph (self, type):
         try:
             self.lock()
             self.disconnect_all ()
+
+            if self.head:
+                self.connect(self.head, self.u)
+                tail = self.head
+            else:
+                tail = self.u
+                
             if type == gr.GR_SIN_WAVE or type == gr.GR_CONST_WAVE:
-                self.connect (self.siggen, self.u)
+                self.connect (self.siggen, tail)
                 # self.connect (self.siggen, self.file_sink)
                 self.siggen.set_waveform (type)
                 self.src = self.siggen
             elif type == gr.GR_UNIFORM or type == gr.GR_GAUSSIAN:
-                self.connect (self.noisegen, self.u)
+                self.connect (self.noisegen, tail)
                 self.noisegen.set_type (type)
                 self.src = self.noisegen
             else:
@@ -156,6 +168,8 @@
                        help="set output gain to GAIN [default=%default]")
     parser.add_option ("-o", "--offset", type="eng_float", default=0,
                        help="set waveform offset to OFFSET [default=%default]")
+    parser.add_option ("-N", "--nsamples", type="eng_float", default=0,
+                       help="set number of samples to transmit [default=+inf]")
     (options, args) = parser.parse_args ()
 
     if len(args) != 0:
@@ -167,7 +181,7 @@
         parser.print_help()
         raise SystemExit
 
-    tb = my_top_block()
+    tb = my_top_block(options.nsamples)
     tb.set_interpolator (options.interp)
     tb.set_waveform_type (options.type)
     tb.set_waveform_freq (options.waveform_freq)

Modified: gnuradio/branches/releases/3.2/usrp/host/apps/Makefile.am
===================================================================
--- gnuradio/branches/releases/3.2/usrp/host/apps/Makefile.am   2009-03-24 
15:11:47 UTC (rev 10675)
+++ gnuradio/branches/releases/3.2/usrp/host/apps/Makefile.am   2009-03-24 
15:30:01 UTC (rev 10676)
@@ -47,7 +47,7 @@
 test_usrp_standard_rx_LDADD    = $(USRP_LA)
 
 test_usrp_standard_tx_SOURCES  = test_usrp_standard_tx.cc time_stuff.c
-test_usrp_standard_tx_LDADD    = $(USRP_LA)
+test_usrp_standard_tx_LDADD    = $(USRP_LA) $(BOOST_LDFLAGS) 
$(BOOST_PROGRAM_OPTIONS_LIB)
 
 usrper_SOURCES                 = usrper.cc
 usrper_LDADD                   = $(USRP_LA)

Modified: gnuradio/branches/releases/3.2/usrp/host/apps/test_usrp_standard_tx.cc
===================================================================
--- gnuradio/branches/releases/3.2/usrp/host/apps/test_usrp_standard_tx.cc      
2009-03-24 15:11:47 UTC (rev 10675)
+++ gnuradio/branches/releases/3.2/usrp/host/apps/test_usrp_standard_tx.cc      
2009-03-24 15:30:01 UTC (rev 10676)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2003,2004,2008 Free Software Foundation, Inc.
+ * Copyright 2003,2004,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -24,6 +24,7 @@
 #include "config.h"
 #endif
 
+#include <iostream>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -35,16 +36,45 @@
 #include "time_stuff.h"
 #include "usrp_standard.h"
 #include "usrp_bytesex.h"
+#include <boost/program_options.hpp>
 
-#ifdef HAVE_SCHED_H
-#include <sched.h>
-#endif
+enum {
+  GR_SIN_WAVE,
+  GR_CONST_WAVE
+};
 
+namespace po = boost::program_options;
+
 char *prog_name;
 
-static bool test_output (usrp_standard_tx_sptr utx, int max_bytes, double ampl,
-                        bool dc_p, bool counting_p);
+usrp_subdev_spec
+str_to_subdev(std::string spec_str)
+{
+  usrp_subdev_spec spec;
+  if(spec_str == "A" || spec_str == "A:0" || spec_str == "0:0") {
+    spec.side = 0;
+    spec.subdev = 0;
+  }
+  else if(spec_str == "A:1" || spec_str == "0:1") {
+    spec.side = 0;
+    spec.subdev = 1;
+  }
+  else if(spec_str == "B" || spec_str == "B:0" || spec_str == "1:0") {
+    spec.side = 1;
+    spec.subdev = 0;
+  }
+  else if(spec_str == "B:1" || spec_str == "1:1") {
+    spec.side = 1;
+    spec.subdev = 1;
+  }
+  else {
+    throw std::range_error("Incorrect subdevice specifications.\n");
+  }
 
+  return spec;
+}
+
+
 static void
 set_progname (char *path)
 {
@@ -56,163 +86,160 @@
 }
 
 static void
-usage ()
-{
-  fprintf (stderr, 
-          "usage: %s [-f] [-v] [-d] [-c] [-a <ampl>][-I <interp>] [-F freq] 
[-D]\n", prog_name);
-  fprintf (stderr, "  [-f] loop forever\n");
-  fprintf (stderr, "  [-M] how many Megabytes to transfer (default 128)\n");
-  fprintf (stderr, "  [-v] verbose\n");
-  fprintf (stderr, "  [-d] dump registers\n");
-  // fprintf (stderr, "  [-l] digital loopback in FPGA\n");
-  fprintf (stderr, "  [-c] Tx counting sequence\n");
-  fprintf (stderr, "  [-D] DC output\n");
-
-  fprintf (stderr, "  [-B <fusb_block_size>] set fast usb block_size\n");
-  fprintf (stderr, "  [-N <fusb_nblocks>] set fast usb nblocks\n");
-  fprintf (stderr, "  [-R] set real time scheduling: SCHED_FIFO; pri = 
midpoint\n");
-
-  exit (1);
-}
-
-static void
 die (const char *msg)
 {
   fprintf (stderr, "die: %s: %s\n", prog_name, msg);
   exit (1);
 }
 
-static void
-dump_codec_regs (usrp_basic *u, int which_codec, FILE *fp)
+
+static bool
+test_output (usrp_standard_tx_sptr utx, long long max_bytes, double ampl, int 
waveform)
 {
-  for (int i = 0; i < 64; i++){
-    unsigned char v;
-    u->_read_9862 (which_codec, i, &v);
-    fprintf (fp, "%2d:  0x%02x\n", i, v); 
+  const int BUFSIZE = utx->block_size();
+  const int N = BUFSIZE/sizeof (short);
+
+  short        buf[N];
+  long long    nbytes = 0;
+
+  // ----------------------------------------------------------------
+  // one time initialization of the pattern we're going to transmit
+
+  const int    PERIOD = 65;            // any value is valid
+  const int            PATLEN = 2 * PERIOD;    
+  short                pattern[PATLEN];
+
+  for (int i = 0; i < PERIOD; i++){
+    if (waveform == GR_CONST_WAVE){
+      pattern[2*i+0] = host_to_usrp_short((short) ampl);
+      pattern[2*i+1] = host_to_usrp_short((short) 0);
+    }
+    else {
+      pattern[2*i+0] = host_to_usrp_short((short) (ampl * cos(2*M_PI * i / 
PERIOD)));
+      pattern[2*i+1] = host_to_usrp_short((short) (ampl * sin(2*M_PI * i / 
PERIOD)));
+    }
   }
-  fflush (fp);
-}
 
-static void
-do_dump_codec_regs (usrp_basic *u)
-{
-  char name[100];
-  strcpy (name, "regsXXXXXX");
-  int fd = mkstemp (name);
-  if (fd == -1){
-    perror (name);
+  // ----------------------------------------------------------------
+
+  double start_wall_time = get_elapsed_time ();
+  double start_cpu_time  = get_cpu_usage ();
+
+  bool         underrun;
+  int  nunderruns = 0;
+  int  pi = 0;
+
+  for (nbytes = 0; max_bytes == 0 || nbytes < max_bytes; nbytes += BUFSIZE){
+
+    for (int i = 0; i < N; i++){
+      buf[i] = pattern[pi];
+      pi++;
+      if (pi >= PATLEN)
+       pi = 0;
+    }
+
+    int        ret = utx->write (buf, sizeof (buf), &underrun);
+    if ((unsigned) ret != sizeof (buf)){
+      fprintf (stderr, "test_output: error, ret = %d\n", ret);
+    }
+
+    if (underrun){
+      nunderruns++;
+      printf ("tx_underrun\n");
+      //printf ("tx_underrun %9d %6d\n", nbytes, nbytes/BUFSIZE);
+    }
   }
-  else {
-    FILE *fp = fdopen (fd, "w");
-    dump_codec_regs (u, 0, fp);
-    fclose (fp);
-  }
+
+  utx->wait_for_completion ();
+
+  double stop_wall_time = get_elapsed_time ();
+  double stop_cpu_time  = get_cpu_usage ();
+
+  double delta_wall = stop_wall_time - start_wall_time;
+  double delta_cpu  = stop_cpu_time  - start_cpu_time;
+
+  printf ("xfered %.3g bytes in %.3g seconds.  %.4g bytes/sec.  cpu time = 
%.3g\n",
+         (double) max_bytes, delta_wall, max_bytes / delta_wall, delta_cpu);
+
+  printf ("%d underruns\n", nunderruns);
+
+  return true;
 }
 
 int
 main (int argc, char **argv)
 {
-  bool         verbose_p = false;
-  bool  dump_regs_p = false;
-  bool dc_p = false;
-  // bool  loopback_p = false;
-  bool  counting_p = false;
-  int   max_bytes = 128 * (1L << 20);
-  int  ch;
-  int  which_board = 0;
-  int  interp = 16;                    // 32.0 MB/sec 
-  double       center_freq = 0;
-  double       ampl = 10000;
+  int which = 0;                       // specify which USRP board
+  usrp_subdev_spec spec(0,0);          // specify the d'board side
+  int interp = 16;                     // set the interpolation rate
+  double rf_freq = -1;                 // set the frequency
+  float amp = 10000;                   // set the amplitude of the output
+  float gain = -1;                     // set the d'board PGA gain
+  int waveform;
   int  fusb_block_size = 0;
   int  fusb_nblocks = 0;
   bool realtime_p = false;
+  double nsamples = 32e6;
 
-
   set_progname (argv[0]);
 
-  while ((ch = getopt (argc, argv, "vfdcI:F:a:DM:B:N:R")) != EOF){
-    switch (ch){
-    case 'f':
-      max_bytes = 0;
-      break;
+  po::options_description cmdconfig("Program options");
+  cmdconfig.add_options()
+    ("help,h", "produce help message")
+    ("which,W", po::value<int>(&which), "select which USRP board")
+    ("tx-subdev-spec,T", po::value<std::string>(), "select USRP Tx side A or 
B")
+    ("rf-freq,f", po::value<double>(), "set RF center frequency to FREQ")
+    ("interp,i", po::value<int>(&interp), "set fgpa interpolation rate to 
INTERP")
 
-    case 'v':
-      verbose_p = true;
-      break;
+    ("sine", "generate a complex sinusoid [default]")
+    ("const", "generate a constant output")
 
-    case 'd':
-      dump_regs_p = true;
-      break;
-      
-    case 'D':
-      dc_p = true;
-      break;
-      
-#if 0
-    case 'l':
-      loopback_p = true;
-      break;
-#endif
-      
-    case 'c':
-      counting_p = true;
-      break;
-      
-    case 'I':
-      interp = strtol (optarg, 0, 0);
-      break;
-                     
-    case 'F':
-      center_freq = strtod (optarg, 0);
-      break;
-      
-    case 'a':
-      ampl = strtod (optarg, 0);
-      break;
+    //("waveform-freq,w", po::value<double>(&wfreq), "set waveform frequency 
to FREQ")
+    ("amplitude,a", po::value<float>(&amp), "set amplitude")
+    ("gain,g", po::value<float>(&gain), "set output gain to GAIN 
[default=MAX]")
+    //("offset,o", po::value<float>(&offset), "set waveform offset to OFFSET")
+    ("nsamples,N", po::value<double>(&nsamples), "number of samples to send 
[default=32M]")
+    ;
+  
+  po::variables_map vm;
+  po::store(po::command_line_parser(argc, argv).
+           options(cmdconfig).run(), vm);
+  po::notify(vm);
+  
+  if (vm.count("help")) {
+    std::cout << cmdconfig << "\n";
+    return 1;
+  }
+  
+  if(vm.count("tx-subdev-spec")) {
+    std::string s = vm["tx-subdev-spec"].as<std::string>();
+    spec = str_to_subdev(s);
+  }
 
-    case 'M':
-      max_bytes = strtol (optarg, 0, 0) * (1L << 20);
-      if (max_bytes < 0) max_bytes = 0;
-      break;
+  if(vm.count("sine")) {
+    waveform = GR_SIN_WAVE;
+  }
+  else if(vm.count("const")) {
+    waveform = GR_CONST_WAVE;
+  }
+  else {
+    waveform = GR_SIN_WAVE;
+  }
 
-    case 'B':
-      fusb_block_size = strtol (optarg, 0, 0);
-      break;
+  printf("which:    %d\n", which);
+  printf("interp:   %d\n", interp);
+  printf("rf_freq:  %g\n", rf_freq);
+  printf("amp:      %f\n", amp);
+  printf("nsamples: %g\n", nsamples);
 
-    case 'N':
-      fusb_nblocks = strtol (optarg, 0, 0);
-      break;
 
-    case 'R':
-      realtime_p = true;
-      break;
-
-    default:
-      usage ();
-    }
-  }
-
-#ifdef HAVE_SCHED_SETSCHEDULER
   if (realtime_p){
-    int policy = SCHED_FIFO;
-    int pri = (sched_get_priority_max (policy) - sched_get_priority_min 
(policy)) / 2;
-    int pid = 0;  // this process
-
-    struct sched_param param;
-    memset(&param, 0, sizeof(param));
-    param.sched_priority = pri;
-    int result = sched_setscheduler(pid, policy, &param);
-    if (result != 0){
-      perror ("sched_setscheduler: failed to set real time priority");
-    }
-    else
-      printf("SCHED_FIFO enabled with priority = %d\n", pri);
+    // FIXME
   }
-#endif
 
   usrp_standard_tx_sptr utx;
 
-  utx = usrp_standard_tx::make (which_board,
+  utx = usrp_standard_tx::make (which,
                                interp,
                                1,      // nchan
                                -1,     // mux
@@ -221,97 +248,68 @@
 
   if (utx == 0)
     die ("usrp_standard_tx::make");
-    
-  if (!utx->set_tx_freq (0, center_freq))
-    die ("utx->set_tx_freq");
-    
-  if (dump_regs_p)
-    do_dump_codec_regs (utx.get());
-  
-  
-  fflush (stdout);
-  fflush (stderr);
 
-  utx->start();                // start data xfers
+  // FIXME
 
-  test_output (utx, max_bytes, ampl, dc_p, counting_p);
+  db_base_sptr subdev = utx->selected_subdev(spec);
+  printf("Subdevice name is %s\n", subdev->name().c_str());
+  printf("Subdevice freq range: (%g, %g)\n", 
+        subdev->freq_min(), subdev->freq_max());
 
-  return 0;
-}
+  unsigned int mux = utx->determine_tx_mux_value(spec);
+  printf("mux: %#08x\n",  mux);
+  utx->set_mux(mux);
 
+  if(gain == -1)
+    gain = subdev->gain_max();
+  subdev->set_gain(gain);
 
-static bool
-test_output (usrp_standard_tx_sptr utx, int max_bytes, double ampl,
-            bool dc_p, bool counting_p)
-{
-  static const int BUFSIZE = utx->block_size();
-  static const int N = BUFSIZE/sizeof (short);
+  float input_rate = utx->dac_rate() / utx->interp_rate();
+  printf("baseband rate: %g\n",  input_rate);
 
-  short           buf[N];
-  int             nbytes = 0;
-  int             counter = 0;
+  usrp_tune_result r;
 
-  static const int    PERIOD = 65;             // any value is valid
-  static const int    PATLEN = 2 * PERIOD;     
-  short                      pattern[PATLEN];
+  if (rf_freq < 0)
+    rf_freq = (subdev->freq_min() + subdev->freq_max()) * 0.5;
+  double target_freq = rf_freq;
+  bool ok = utx->tune(subdev->which(), subdev, target_freq, &r);
 
-  for (int i = 0; i < PERIOD; i++){
-    if (dc_p){
-      pattern[2*i+0] = host_to_usrp_short ((short) ampl);
-      pattern[2*i+1] = host_to_usrp_short ((short) 0);
-    }
-    else {
-      pattern[2*i+0] = host_to_usrp_short ((short) (ampl * cos (2*M_PI * i / 
PERIOD)));
-      pattern[2*i+1] = host_to_usrp_short ((short) (ampl * sin (2*M_PI * i / 
PERIOD)));
-    }
+  if(!ok) {
+    throw std::runtime_error("Could not set frequency.");
   }
 
-  double          start_wall_time = get_elapsed_time ();
-  double          start_cpu_time  = get_cpu_usage ();
+  subdev->set_enable(true);
+  
+  printf("target_freq:     %f\n", target_freq);
+  printf("ok:              %s\n", ok ? "true" : "false");
+  printf("r.baseband_freq: %f\n", r.baseband_freq);
+  printf("r.dxc_freq:      %f\n", r.dxc_freq);
+  printf("r.residual_freq: %f\n", r.residual_freq);
+  printf("r.inverted:      %d\n", r.inverted);
 
-  bool         underrun;
-  int  nunderruns = 0;
-  int  pi = 0;
 
-  for (nbytes = 0; max_bytes == 0 || nbytes < max_bytes; nbytes += BUFSIZE){
+  fflush (stdout);
+  fflush (stderr);
 
-    if (counting_p){
-      for (int i = 0; i < N; i++)
-       buf[i] = host_to_usrp_short (counter++ & 0xffff);
-    }
-    else {
-      for (int i = 0; i < N; i++){
-       buf[i] = pattern[pi];
-       pi++;
-       if (pi >= PATLEN)
-         pi = 0;
-      }
-    }
+  utx->start();                // start data xfers
 
-    int        ret = utx->write (buf, sizeof (buf), &underrun);
-    if ((unsigned) ret != sizeof (buf)){
-      fprintf (stderr, "test_output: error, ret = %d\n", ret);
-    }
+  test_output (utx, (long long) nsamples, amp, waveform);
 
-    if (underrun){
-      nunderruns++;
-      printf ("tx_underrun\n");
-      //printf ("tx_underrun %9d %6d\n", nbytes, nbytes/BUFSIZE);
-    }
-  }
+  return 0;
+}  
 
-  utx->wait_for_completion ();
 
-  double stop_wall_time = get_elapsed_time ();
-  double stop_cpu_time  = get_cpu_usage ();
+#if 0
+    case 'B':
+      fusb_block_size = strtol (optarg, 0, 0);
+      break;
 
-  double delta_wall = stop_wall_time - start_wall_time;
-  double delta_cpu  = stop_cpu_time  - start_cpu_time;
+    case 'N':
+      fusb_nblocks = strtol (optarg, 0, 0);
+      break;
 
-  printf ("xfered %.3g bytes in %.3g seconds.  %.4g bytes/sec.  cpu time = 
%.3g\n",
-         (double) max_bytes, delta_wall, max_bytes / delta_wall, delta_cpu);
+    case 'R':
+      realtime_p = true;
+      break;
 
-  printf ("%d underruns\n", nunderruns);
-
-  return true;
-}
+#endif





reply via email to

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