Merge branch 'maint'
authorEric Blossom <eb@comsec.com>
Tue, 14 Sep 2010 19:43:45 +0000 (12:43 -0700)
committerEric Blossom <eb@comsec.com>
Tue, 14 Sep 2010 19:43:45 +0000 (12:43 -0700)
* maint:
  Avoid divide by zero in persistence code when using default args
  Update config.guess and config.sub in gr-howoto-write-a-block too
  Update config.guess and config.sub from canonical home
  Update script to pull config.* from git repo

43 files changed:
dtools/bin/fix-copyright-years [new file with mode: 0755]
gnuradio-core/src/lib/general/gri_agc2_cc.i
gnuradio-core/src/lib/general/gri_agc2_ff.i
gnuradio-core/src/lib/io/gr_file_sink.cc
gnuradio-core/src/lib/io/gr_file_sink_base.cc
gnuradio-core/src/lib/io/gr_file_sink_base.h
gnuradio-core/src/lib/io/gr_file_sink_base.i
gnuradio-core/src/lib/io/gr_oscope_guts.cc
gnuradio-core/src/lib/io/gr_trigger_mode.h
gr-qtgui/src/lib/highResTimeFunctions.h
gr-usrp2/src/usrp2.i
gr-usrp2/src/usrp2_sink_16sc.cc
gr-usrp2/src/usrp2_sink_32fc.cc
gr-usrp2/src/usrp2_sink_base.cc
gr-usrp2/src/usrp2_sink_base.h
gr-wxgui/src/python/common.py
gr-wxgui/src/python/scope_window.py
gr-wxgui/src/python/scopesink_gl.py
gr-wxgui/src/python/waterfall_window.py
grc/blocks/Makefile.am
grc/blocks/block_tree.xml
grc/blocks/gr_agc2_xx.xml
grc/blocks/gr_and_const_xx.xml [new file with mode: 0644]
grc/blocks/gr_file_sink.xml
grc/blocks/wxgui_scopesink2.xml
grc/freedesktop/Makefile.am
grc/freedesktop/gnuradio-gnuradio-companion.desktop [deleted file]
grc/freedesktop/gnuradio-grc.desktop [new file with mode: 0644]
grc/freedesktop/grc_setup_freedesktop.in
grc/python/Block.py
grc/python/Port.py
gruel/src/include/gruel/pmt.h
gruel/src/lib/pmt/pmt.cc
gruel/src/lib/pmt/pmt_int.h
gruel/src/lib/pmt/pmt_io.cc
gruel/src/lib/pmt/qa_pmt_prims.cc
gruel/src/lib/pmt/qa_pmt_prims.h
usrp/host/apps/burn-db-eeprom
usrp/host/include/usrp/db_flexrf.h
usrp/host/lib/db_flexrf.cc
usrp/host/lib/usrp_dbid.dat
usrp2/firmware/lib/db_rfx.c
version.sh

diff --git a/dtools/bin/fix-copyright-years b/dtools/bin/fix-copyright-years
new file mode 100755 (executable)
index 0000000..bb0f300
--- /dev/null
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+
+import re
+import datetime
+import subprocess
+import multiprocessing
+
+def command(*args): return subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0]
+
+def is_gnuradio_co_source(lines):
+    for line in lines[:20]:
+        if 'GNU Radio is free software' in line: return True
+    return False
+
+def get_gnuradio_co_line(lines):
+    for i, line in enumerate(lines[:5]):
+        if 'Copyright' in line and 'Free Software Foundation' in line: return line, i
+    return None
+
+def fix_co_years(files):
+    for file in files:
+        print file
+        lines = open(file).readlines()
+        if not is_gnuradio_co_source(lines): continue
+
+        #extract the years from the git history
+        years = set(map(
+            lambda l: int(l.split()[-2]),
+            filter(
+                lambda l: l.startswith('Date'),
+                command('git', 'log', file).splitlines(),
+            ),
+        ))
+
+        #extract line and line number for co line
+        try: line, num = get_gnuradio_co_line(lines)
+        except: continue
+
+        #extract years from co string
+        try:
+            co_years_str = re.match('^.*Copyright (.*) Free Software Foundation.*$', line).groups()[0]
+            co_years = set(map(int, co_years_str.split(',')))
+        except: print '    format error on line %d: "%s"'%(num, line); continue
+
+        #update the years if missing any
+        all_years = co_years.union(years)
+        if all_years != co_years:
+            print '    missing years: %s'%(', '.join(map(str, sorted(all_years - co_years))))
+            all_years.add(datetime.datetime.now().year) #add the current year
+            all_years_str = ', '.join(map(str, sorted(all_years)))
+            new_text = ''.join(lines[:num] + [line.replace(co_years_str, all_years_str)] + lines[num+1:])
+            open(file, 'w').write(new_text)
+
+if __name__ == "__main__":
+    #get recursive list of files in the repo
+    files = command('git', 'ls-tree', '--name-only', 'HEAD', '-r').splitlines()
+
+    #start n+1 processes to handle the files
+    num_procs = multiprocessing.cpu_count()
+    procs = [multiprocessing.Process(
+        target=lambda *files: fix_co_years(files),
+        args=files[num::num_procs],
+    ) for num in range(num_procs)]
+    map(multiprocessing.Process.start, procs)
+    map(multiprocessing.Process.join, procs)
index e7d6da97f3b96f2b4a42d97bb70fdf4a2a74622c..0f97f1d8e3799f2775932d5898bed9c27a44867d 100644 (file)
@@ -39,4 +39,9 @@ class gri_agc2_cc {
   float reference ();
   float gain ();
   float max_gain ();
+  void set_decay_rate (float rate);
+  void set_attack_rate (float rate);
+  void set_reference (float reference);
+  void set_gain (float gain);
+  void set_max_gain(float max_gain);
   };
index 3825ce225a1b29e756585ca7142cd8aa640443cd..d04b638a6edee55bbe87568108652ef5fce7740f 100644 (file)
@@ -34,4 +34,14 @@ class gri_agc2_ff {
  public:
   gri_agc2_ff (float attack_rate = 1e-1, float decay_rate = 1e-2,
               float reference = 1.0, float gain = 1.0, float max_gain = 0.0);
+  float attack_rate ();
+  float decay_rate ();
+  float reference ();
+  float gain ();
+  float max_gain ();
+  void set_attack_rate (float rate);
+  void set_decay_rate (float rate);
+  void set_reference (float reference);
+  void set_gain (float gain);
+  void set_max_gain (float max_gain);
   };
index 706837c7a99a66aecac3e2291b7b3293cb88190e..aab0158e7ba8bc7ee1b9eafce6045e88ceb3c3be 100644 (file)
@@ -70,5 +70,8 @@ gr_file_sink::work (int noutput_items,
     nwritten += count;
     inbuf += count * d_itemsize;
   }
+  if (d_unbuffered)
+         fflush (d_fp);
+         
   return nwritten;
 }
index 5ddeeb4d5686fffc8aadfc0ca1e725ce95d03ffb..c43304b0d37f1d07859b53a85a45e54f27b5f263 100644 (file)
@@ -118,3 +118,9 @@ gr_file_sink_base::do_update()
     d_updated = false;
   }
 }  
+
+void
+gr_file_sink_base::set_unbuffered(bool unbuffered)
+{
+       d_unbuffered = unbuffered;
+}
index 0c028d7fd3adcf7413f688d68bf5e8aaca602321..7b96cdb7f3758bbe5ef2d1c578dc0d50d0e8fe10 100644 (file)
@@ -37,6 +37,7 @@ class gr_file_sink_base
   bool         d_updated;      // is there a new FILE pointer?
   bool         d_is_binary;
   boost::mutex d_mutex;
+  bool         d_unbuffered;
 
  protected:
   gr_file_sink_base(const char *filename, bool is_binary);
@@ -61,6 +62,12 @@ class gr_file_sink_base
    * \brief if we've had an update, do it now.
    */
   void do_update();
+  
+  
+  /*!
+   * \brief turn on unbuffered writes for slower outputs
+   */
+  void set_unbuffered(bool unbuffered);
 };
 
 
index 05a3353bb4e6010da558a1c599a062ad81874bc8..ed4342482ddef2c343a56edfec1a7ee58e750070 100644 (file)
@@ -43,4 +43,9 @@ class gr_file_sink_base
    * \brief if we've had an update, do it now.
    */
   void do_update();
+
+  /*!
+   *\brief turn on unbuffered mode for slow outputs
+   */
+  void set_unbuffered(bool unbuffered);
 };
index 80f78240d3a052ec942f80ef4972da8756084f2b..ce7feca13c49178437f99c3fccbe6cb831847ef9 100644 (file)
@@ -104,34 +104,49 @@ gr_oscope_guts::process_sample (const float *channel_data)
 
   d_decimator_count = d_decimator_count_init;
   
-  for (int i = 0; i < d_nchannels; i++)
-    d_buffer[i][d_obi] = channel_data[i];                // copy data into buffer
-
-  switch (d_state){
-  case HOLD_OFF:
-    d_hold_off_count--;
-    if (d_hold_off_count <= 0)
-      enter_look_for_trigger ();
-    break;
-
-  case LOOK_FOR_TRIGGER:
-    if (found_trigger ())
-      enter_post_trigger ();
-    break;
-
-  case POST_TRIGGER:
-    d_post_trigger_count--;
-    if (d_post_trigger_count <= 0){
-      write_output_records ();
-      enter_hold_off ();
-    }
-    break;
-
-  default:
-    assert (0);
+  if (d_trigger_mode != gr_TRIG_MODE_STRIPCHART)
+  {
+         for (int i = 0; i < d_nchannels; i++)
+               d_buffer[i][d_obi] = channel_data[i];                // copy data into buffer
+
+         switch (d_state){
+         case HOLD_OFF:
+               d_hold_off_count--;
+               if (d_hold_off_count <= 0)
+                 enter_look_for_trigger ();
+               break;
+
+         case LOOK_FOR_TRIGGER:
+               if (found_trigger ())
+                 enter_post_trigger ();
+               break;
+
+         case POST_TRIGGER:
+               d_post_trigger_count--;
+               if (d_post_trigger_count <= 0){
+                 write_output_records ();
+                 enter_hold_off ();
+               }
+               break;
+
+         default:
+               assert (0);
+         }
+
+         d_obi = incr_bi (d_obi);
+  }
+  else
+  {
+         for (int i = 0; i < d_nchannels; i++)
+         {
+           for (int j = OUTPUT_RECORD_SIZE-1; j >= 0; j--)
+           {
+                       d_buffer[i][j] = d_buffer[i][j-1];
+               }
+               d_buffer[i][0] = channel_data[i];
+         }
+         write_output_records();
   }
-
-  d_obi = incr_bi (d_obi);
 }
 
 /*
index 63f6b1c987f5fb4b6a9a115c3a6a4de2bd5146ae..8e1222856dd134737c6b4e48e30a99c2eddbea3d 100644 (file)
@@ -27,6 +27,7 @@ enum gr_trigger_mode {
   gr_TRIG_MODE_FREE,
   gr_TRIG_MODE_AUTO,
   gr_TRIG_MODE_NORM,
+  gr_TRIG_MODE_STRIPCHART,
 };
 
 enum gr_trigger_slope {
index b85b1acadeefbf218d44f72f9a66464763df0a81..251bbad8b1cb414908e0636e668ed7ea706e54f2 100644 (file)
@@ -8,41 +8,74 @@
 
 static const long NSEC_PER_SEC = 1000000000L;
 
-static inline bool timespec_greater(const struct timespec* t1, const struct timespec* t0){
-  return ((t1->tv_sec > t0->tv_sec) || ((t1->tv_sec == t0->tv_sec) && (t1->tv_nsec > t0->tv_nsec)));
+static inline bool
+timespec_greater(const struct timespec* t1,
+                const struct timespec* t0)
+{
+  return ((t1->tv_sec > t0->tv_sec) ||
+         ((t1->tv_sec == t0->tv_sec) &&
+          (t1->tv_nsec > t0->tv_nsec)));
 }
 
-static inline bool timespec_greater(const struct timespec t1, const struct timespec t0){
-  return ((t1.tv_sec > t0.tv_sec) || ((t1.tv_sec == t0.tv_sec) && (t1.tv_nsec > t0.tv_nsec)));
+static inline bool
+timespec_greater(const struct timespec t1,
+                const struct timespec t0)
+{
+  return ((t1.tv_sec > t0.tv_sec) ||
+         ((t1.tv_sec == t0.tv_sec) &&
+          (t1.tv_nsec > t0.tv_nsec)));
 }
 
-static inline bool timespec_less(const struct timespec* t1, const struct timespec* t0){
-  return ((t1->tv_sec < t0->tv_sec) || ((t1->tv_sec == t0->tv_sec) && (t1->tv_nsec < t0->tv_nsec)));
+static inline bool
+timespec_less(const struct timespec* t1,
+             const struct timespec* t0)
+{
+  return ((t1->tv_sec < t0->tv_sec) ||
+         ((t1->tv_sec == t0->tv_sec) &&
+          (t1->tv_nsec < t0->tv_nsec)));
 }
 
-static inline bool timespec_less(const struct timespec t1, const struct timespec t0){
-  return ((t1.tv_sec < t0.tv_sec) || ((t1.tv_sec == t0.tv_sec) && (t1.tv_nsec < t0.tv_nsec)));
+static inline bool
+timespec_less(const struct timespec t1,
+             const struct timespec t0)
+{
+  return ((t1.tv_sec < t0.tv_sec) ||
+         ((t1.tv_sec == t0.tv_sec) &&
+          (t1.tv_nsec < t0.tv_nsec)));
 }
 
-static inline bool timespec_equal(const struct timespec* t1, const struct timespec* t0){
-  return ((t1->tv_sec == t0->tv_sec) && (t1->tv_nsec == t0->tv_nsec));
+static inline bool
+timespec_equal(const struct timespec* t1,
+              const struct timespec* t0)
+{
+  return ((t1->tv_sec == t0->tv_sec) &&
+         (t1->tv_nsec == t0->tv_nsec));
 }
 
-static inline bool timespec_equal(const struct timespec t1, const struct timespec t0){
-  return ((t1.tv_sec == t0.tv_sec) && (t1.tv_nsec == t0.tv_nsec));
+static inline bool
+timespec_equal(const struct timespec t1,
+              const struct timespec t0)
+{
+  return ((t1.tv_sec == t0.tv_sec) &&
+         (t1.tv_nsec == t0.tv_nsec));
 }
 
-static inline void timespec_reset(struct timespec* ret){
+static inline void
+timespec_reset(struct timespec* ret)
+{
   ret->tv_sec = 0;
   ret->tv_nsec = 0;
 }
 
-static inline void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec){
-  while (nsec > NSEC_PER_SEC){
+static inline void
+set_normalized_timespec(struct timespec *ts,
+                       time_t sec, long nsec)
+{
+  while (nsec > NSEC_PER_SEC) {
     nsec -= NSEC_PER_SEC;
     ++sec;
   }
-  while(nsec < 0){
+  while(nsec < 0) {
     nsec += NSEC_PER_SEC;
     --sec;
   }
@@ -50,10 +83,13 @@ static inline void set_normalized_timespec(struct timespec *ts, time_t sec, long
   ts->tv_nsec = nsec;
 }
 
-static inline struct timespec convert_to_timespec(const double timeValue){
+static inline struct timespec
+convert_to_timespec(const double timeValue)
+{
   struct timespec ret;
   double seconds = 0;
-  long nsec = static_cast<long>(modf(timeValue, &seconds) * static_cast<double>(NSEC_PER_SEC));
+  long nsec = static_cast<long>(modf(timeValue, &seconds) * 
+                               static_cast<double>(NSEC_PER_SEC));
   time_t sec = static_cast<time_t>(seconds);
 
   set_normalized_timespec(&ret, sec, nsec);
@@ -61,28 +97,46 @@ static inline struct timespec convert_to_timespec(const double timeValue){
   return ret;
 }
 
-static inline double convert_from_timespec(const timespec actual){
-  return (static_cast<double>(actual.tv_sec) + (static_cast<double>(actual.tv_nsec) / static_cast<double>(NSEC_PER_SEC)));
+static inline double
+convert_from_timespec(const timespec actual)
+{
+  return (static_cast<double>(actual.tv_sec) +
+         (static_cast<double>(actual.tv_nsec) /
+          static_cast<double>(NSEC_PER_SEC)));
 }
 
-static inline void timespec_add(struct timespec *ret, const struct timespec* t1, const struct timespec* t0){
+static inline void
+timespec_add(struct timespec *ret,
+            const struct timespec* t1,
+            const struct timespec* t0)
+{
   time_t sec = t1->tv_sec + t0->tv_sec;
   long nsec = t1->tv_nsec + t0->tv_nsec;
 
   set_normalized_timespec(ret, sec, nsec);
 }
 
-static inline void timespec_add(struct timespec *ret, const struct timespec t1, const struct timespec t0){
+static inline void
+timespec_add(struct timespec *ret,
+            const struct timespec t1,
+            const struct timespec t0)
+{
   return timespec_add(ret, &t1, &t0);
 }
 
-static inline struct timespec timespec_add(const struct timespec t1, const struct timespec t0){
+static inline struct timespec
+timespec_add(const struct timespec t1,
+            const struct timespec t0)
+{
   struct timespec ret;
   timespec_add(&ret, &t1, &t0);
   return ret;
 }
 
-static inline struct timespec timespec_add(const struct timespec t1, const double time0){
+static inline struct timespec
+timespec_add(const struct timespec t1,
+            const double time0)
+{
   struct timespec ret;
   struct timespec t0;
   t0 = convert_to_timespec(time0);
@@ -92,24 +146,38 @@ static inline struct timespec timespec_add(const struct timespec t1, const doubl
   return ret;
 }
 
-static inline void timespec_subtract(struct timespec *ret, const struct timespec* t1, const struct timespec* t0){
+static inline void
+timespec_subtract(struct timespec *ret,
+                 const struct timespec* t1,
+                 const struct timespec* t0)
+{
   time_t sec = t1->tv_sec - t0->tv_sec;
   long nsec = t1->tv_nsec - t0->tv_nsec;
 
   set_normalized_timespec(ret, sec, nsec);
 }
 
-static inline void timespec_subtract(struct timespec *ret, const struct timespec t1, const struct timespec t0){
+static inline void
+timespec_subtract(struct timespec *ret,
+                 const struct timespec t1,
+                 const struct timespec t0)
+{
   return timespec_subtract(ret, &t1, &t0);
 }
 
-static inline struct timespec timespec_subtract(const struct timespec t1, const struct timespec t0){
+static inline struct timespec
+timespec_subtract(const struct timespec t1,
+                 const struct timespec t0)
+{
   struct timespec ret;
   timespec_subtract(&ret, &t1, &t0);
   return ret;
 }
 
-static inline struct timespec timespec_subtract(const struct timespec t1, const double time0){
+static inline struct timespec
+timespec_subtract(const struct timespec t1,
+                 const double time0)
+{
   struct timespec ret;
   struct timespec t0;
   t0 = convert_to_timespec(time0);
@@ -119,7 +187,11 @@ static inline struct timespec timespec_subtract(const struct timespec t1, const
   return ret;
 }
 
-static inline double diff_timespec(struct timespec* ret, const struct timespec *t1, const struct timespec* t0){
+static inline double
+diff_timespec(struct timespec* ret,
+             const struct timespec *t1,
+             const struct timespec* t0)
+{
   struct timespec actual;
   time_t sec = 0;
   long nsec = 0;
@@ -141,7 +213,8 @@ static inline double diff_timespec(struct timespec* ret, const struct timespec *
     sec = t0->tv_sec - t1->tv_sec;
     nsec = t0->tv_nsec - t1->tv_nsec;
 
-    // Do nothing with the ret value as the ret value would have to store a negative, which it can't.
+    // Do nothing with the ret value as the ret value
+    // would have to store a negative, which it can't.
 
     set_normalized_timespec(&actual, sec, nsec);
     
@@ -149,23 +222,39 @@ static inline double diff_timespec(struct timespec* ret, const struct timespec *
   }
 }
 
-static inline double diff_timespec(struct timespec* ret, const struct timespec t1, const struct timespec t0){
+static inline double
+diff_timespec(struct timespec* ret,
+             const struct timespec t1,
+             const struct timespec t0)
+{
   return diff_timespec(ret, &t1, &t0);
 }
 
-static inline double diff_timespec(const struct timespec t1, const struct timespec t0){
+static inline double
+diff_timespec(const struct timespec t1,
+             const struct timespec t0)
+{
   return diff_timespec(NULL, &t1, &t0);
 }
 
 
-static inline double diff_timespec(const struct timespec* t1, const struct timespec* t0){
+static inline double
+diff_timespec(const struct timespec* t1,
+             const struct timespec* t0)
+{
   return diff_timespec(NULL, t1, t0);
 }
 
 
-static inline void get_highres_clock(struct timespec* ret){
+#ifdef CLOCK_REALTIME
+// If we can use clock_gettime, use it;
+// otherwise, use gettimeofday
+static inline void
+get_highres_clock(struct timespec* ret)
+{
   if(clock_gettime(CLOCK_REALTIME, ret) != 0){
-    // Unable to get high resolution time - fail over to low resolution time
+    // Unable to get high resolution time - 
+    // fail over to low resolution time
     timeval lowResTime;
     gettimeofday(&lowResTime, NULL);
     ret->tv_sec = lowResTime.tv_sec;
@@ -173,17 +262,37 @@ static inline void get_highres_clock(struct timespec* ret){
   }
 }
 
-static inline struct timespec get_highres_clock(){
+#else
+
+// Trick timer functions into thinking it has an nsec timer
+// but only use the low resolution (usec) timer.
+static inline void
+get_highres_clock(struct timespec* ret)
+{
+  timeval lowResTime;
+  gettimeofday(&lowResTime, NULL);
+  ret->tv_sec = lowResTime.tv_sec;
+  ret->tv_nsec = lowResTime.tv_usec*1000;
+}
+#endif
+
+static inline struct timespec
+get_highres_clock()
+{
   struct timespec ret;
   get_highres_clock(&ret);
   return ret;
 }
 
-static inline bool timespec_empty(const struct timespec* ret){
+static inline bool
+timespec_empty(const struct timespec* ret)
+{
   return ( (ret->tv_sec == 0 ) &&  (ret->tv_nsec == 0) );
 }
 
-static inline bool timespec_empty(const struct timespec ret){
+static inline bool
+timespec_empty(const struct timespec ret)
+{
   return timespec_empty(&ret);
 }
 
index d1fa091f73f6d8c69e5409dfe688899be207683e..2a79fad44b8f5831a4dee3e96b97b2740254000b 100644 (file)
@@ -32,6 +32,7 @@
 
 %include <usrp2/tune_result.h>
 %include <usrp2/mimo_config.h>
+%include <usrp2/metadata.h>
 
 %template(uint32_t_vector) std::vector<uint32_t>;
 
@@ -163,6 +164,7 @@ public:
   bool write_gpio(uint16_t value, uint16_t mask);
   %rename(_real_read_gpio) read_gpio;
   bool read_gpio(uint16_t *value);
+  bool start_streaming_at(usrp2::fpga_timestamp time);
 };
 
 // ----------------------------------------------------------------
index 1e7c54dcdb16d8c0cb62f0281c39af9303b0c3bf..75cc1f4a6bebb5857ce4fe1ee9df03f2f8680c5c 100644 (file)
@@ -67,12 +67,20 @@ usrp2_sink_16sc::work(int noutput_items,
     return 0;
 
   usrp2::tx_metadata metadata;
-  metadata.timestamp = -1;
-  metadata.send_now = 1;
+
+  // Set TX metadata to either start time or now
+  if (d_should_wait == true) {
+    metadata.timestamp = d_tx_time;
+    metadata.send_now = 0;
+    d_should_wait = false;
+  }
+  else {
+    metadata.timestamp = -1;
+    metadata.send_now = 1;
+  }
   metadata.start_of_burst = 1;
 
-  bool ok = d_u2->tx_16sc(0,  // FIXME: someday, streams will have channel numbers
-                         in, noutput_items, &metadata);
+  bool ok = d_u2->tx_16sc(0, in, noutput_items, &metadata);
   if (!ok){
     std::cerr << "usrp2_sink_16sc: tx_16sc failed" << std::endl;
     return -1; // say we're done
index b1e28a8297ee83468801a8ebd57a43e916d86938..fa75b380571dc960fe4ea56449917f2d5c295362 100644 (file)
@@ -67,12 +67,20 @@ usrp2_sink_32fc::work(int noutput_items,
     return 0;
 
   usrp2::tx_metadata metadata;
-  metadata.timestamp = -1;
-  metadata.send_now = 1;
+
+  // Set TX metadata to either start time or now
+  if (d_should_wait == true) {
+    metadata.timestamp = d_tx_time;
+    metadata.send_now = 0;
+    d_should_wait = false;
+  }
+  else {
+    metadata.timestamp = -1;
+    metadata.send_now = 1;
+  }
   metadata.start_of_burst = 1;
 
-  bool ok = d_u2->tx_32fc(0, // FIXME: someday, streams will have channel numbers
-                         in, noutput_items, &metadata);
+  bool ok = d_u2->tx_32fc(0, in, noutput_items, &metadata);
   if (!ok){
     std::cerr << "usrp2_sink_32fc: tx_32fc failed" << std::endl;
     return -1; // say we're done
index ce473f2365e08b132237f219921d6d4b52c6d142..c9b34a54a93669974226ec79abba05bc87f7a132 100644 (file)
@@ -36,7 +36,9 @@ usrp2_sink_base::usrp2_sink_base(const char *name,
   : usrp2_base(name,
                input_signature,
               gr_make_io_signature(0, 0, 0),
-              ifc, mac)
+              ifc, mac),
+    d_should_wait(false),
+    d_tx_time(0)
 {
   // NOP
 }
@@ -155,3 +157,10 @@ bool usrp2_sink_base::read_gpio(uint16_t *value)
 {
   return d_u2->read_gpio(usrp2::GPIO_TX_BANK, value);
 }
+
+bool usrp2_sink_base::start_streaming_at(usrp2::fpga_timestamp time)
+{
+  d_should_wait = true;
+  d_tx_time = time;
+  return true;
+}
index 38dc4f2364a60fef6cbadc39c8394afcca9ed06a..d831d4df6951d4ee2e250e2f1059c610f820262b 100644 (file)
@@ -37,6 +37,9 @@ protected:
                  const std::string &mac)
     throw (std::runtime_error);
 
+  bool d_should_wait;
+  usrp2::fpga_timestamp d_tx_time;
+
 public:
   ~usrp2_sink_base();
 
@@ -139,6 +142,11 @@ public:
    * \brief Read daughterboard GPIO pin values
    */
   bool read_gpio(uint16_t *value);
+
+  /*!
+   * \brief First samples begin streaming to USRP2 at given time
+   */
+  bool start_streaming_at(usrp2::fpga_timestamp time);
 };
 
 #endif /* INCLUDED_USRP2_SINK_BASE_H */
index 17a7dc0de550fa8ae5fa32da1f938d3f5fd7edd8..3641ae6448f7ff4f4203c82e2210ea135d8d4579 100644 (file)
@@ -25,6 +25,8 @@
 import wx
 from gnuradio import gr
 
+RUN_ALWAYS = gr.prefs().get_bool ('wxgui', 'run_always', False)
+
 class wxgui_hb(object):
        """
        The wxgui hier block helper/wrapper class:
@@ -47,7 +49,10 @@ class wxgui_hb(object):
                        assert points[0] == self or points[0][0] == self
                        copy = gr.copy(self._hb.input_signature().sizeof_stream_item(0))
                        handler = self._handler_factory(copy.set_enabled)
-                       handler(False) #initially disable the copy block
+                       if RUN_ALWAYS == False:
+                               handler(False) #initially disable the copy block
+                       else:
+                               handler(True) #initially enable the copy block
                        self._bind_to_visible_event(win=self.win, handler=handler)
                        points = list(points)
                        points.insert(1, copy) #insert the copy block into the chain
@@ -67,7 +72,10 @@ class wxgui_hb(object):
                        if cache[0] == visible: return
                        cache[0] = visible
                        #print visible, handler
-                       handler(visible)
+                       if RUN_ALWAYS == False:
+                               handler(visible)
+                       else:
+                               handler(True)
                return callback
 
        @staticmethod
index c03b71f1e0c84494791265be416f9eef29ea2d55..a9917782f4f736b86f7cea5eaaa8cd327b638338 100644 (file)
@@ -38,6 +38,7 @@ import forms
 DEFAULT_FRAME_RATE = gr.prefs().get_long('wxgui', 'scope_rate', 30)
 PERSIST_ALPHA_MIN_EXP, PERSIST_ALPHA_MAX_EXP = -2, 0
 SLIDER_STEPS = 100
+DEFAULT_TRIG_MODE = gr.prefs().get_long('wxgui', 'trig_mode', gr.gr_TRIG_MODE_AUTO)
 DEFAULT_WIN_SIZE = (600, 300)
 COUPLING_MODES = (
        ('DC', False),
@@ -47,6 +48,7 @@ TRIGGER_MODES = (
        ('Freerun', gr.gr_TRIG_MODE_FREE),
        ('Auto', gr.gr_TRIG_MODE_AUTO),
        ('Normal', gr.gr_TRIG_MODE_NORM),
+       ('Stripchart', gr.gr_TRIG_MODE_STRIPCHART),
 )
 TRIGGER_SLOPES = (
        ('Pos +', gr.gr_TRIG_SLOPE_POS),
@@ -432,6 +434,7 @@ class scope_window(wx.Panel, pubsub.pubsub):
                msg_key,
                 use_persistence,
                 persist_alpha,
+               trig_mode,
        ):
                pubsub.pubsub.__init__(self)
                #check num inputs
@@ -471,11 +474,16 @@ class scope_window(wx.Panel, pubsub.pubsub):
                self[FRAME_RATE_KEY] = frame_rate
                self[TRIGGER_LEVEL_KEY] = 0
                self[TRIGGER_CHANNEL_KEY] = 0
-               self[TRIGGER_MODE_KEY] = gr.gr_TRIG_MODE_AUTO
+               self[TRIGGER_MODE_KEY] = trig_mode
+               
                self[TRIGGER_SLOPE_KEY] = gr.gr_TRIG_SLOPE_POS
                self[T_FRAC_OFF_KEY] = 0.5
                self[USE_PERSISTENCE_KEY] = use_persistence
                self[PERSIST_ALPHA_KEY] = persist_alpha
+               
+               if self[TRIGGER_MODE_KEY] == gr.gr_TRIG_MODE_STRIPCHART:
+                       self[T_FRAC_OFF_KEY] = 0.0
+
                for i in range(num_inputs):
                        self.proxy(common.index_key(AC_COUPLE_KEY, i), controller, common.index_key(ac_couple_key, i))
                #init panel and plot
index ebf9b29398479ff260b7f72b089f77571f1ca37e..15be23d5aee8c0f865a7ebb3115fce8857ff7acb 100644 (file)
@@ -76,6 +76,7 @@ class _scope_sink_base(gr.hier_block2, common.wxgui_hb):
                xy_mode=False,
                ac_couple=False,
                num_inputs=1,
+               trig_mode=scope_window.DEFAULT_TRIG_MODE,
                frame_rate=scope_window.DEFAULT_FRAME_RATE,
                 use_persistence=False,
                 persist_alpha=None,
@@ -132,6 +133,7 @@ class _scope_sink_base(gr.hier_block2, common.wxgui_hb):
                        v_scale=v_scale,
                        v_offset=v_offset,
                        xy_mode=xy_mode,
+                       trig_mode=trig_mode,
                        ac_couple_key=AC_COUPLE_KEY,
                        trigger_level_key=TRIGGER_LEVEL_KEY,
                        trigger_mode_key=TRIGGER_MODE_KEY,
index b7904e4d9742412269345dd870c8bb6657c9f89f..6536ada10100287b3348c8e8b6bea7e0227a9c14 100644 (file)
@@ -38,6 +38,7 @@ import forms
 SLIDER_STEPS = 100
 AVG_ALPHA_MIN_EXP, AVG_ALPHA_MAX_EXP = -3, 0
 DEFAULT_FRAME_RATE = gr.prefs().get_long('wxgui', 'waterfall_rate', 30)
+DEFAULT_COLOR_MODE = gr.prefs().get_string('wxgui', 'waterfall_color', 'rgb1')
 DEFAULT_WIN_SIZE = (600, 300)
 DIV_LEVELS = (1, 2, 5, 10, 20)
 MIN_DYNAMIC_RANGE, MAX_DYNAMIC_RANGE = 10, 200
@@ -156,6 +157,9 @@ class control_panel(wx.Panel):
        def _on_incr_time_scale(self, event):
                old_rate = self.parent[FRAME_RATE_KEY]
                self.parent[FRAME_RATE_KEY] *= 0.75
+               if self.parent[FRAME_RATE_KEY] < 1.0:
+                       self.parent[FRAME_RATE_KEY] = 1.0
+               
                if self.parent[FRAME_RATE_KEY] == old_rate:
                        self.parent[DECIMATION_KEY] += 1
        def _on_decr_time_scale(self, event):
@@ -217,6 +221,7 @@ class waterfall_window(wx.Panel, pubsub.pubsub):
                self[REF_LEVEL_KEY] = ref_level
                self[BASEBAND_FREQ_KEY] = baseband_freq
                self[COLOR_MODE_KEY] = COLOR_MODES[0][1]
+               self[COLOR_MODE_KEY] = DEFAULT_COLOR_MODE
                self[RUNNING_KEY] = True
                #setup the box with plot and controls
                self.control_panel = control_panel(self)
@@ -280,6 +285,8 @@ class waterfall_window(wx.Panel, pubsub.pubsub):
                #grid parameters
                sample_rate = self[SAMPLE_RATE_KEY]
                frame_rate = self[FRAME_RATE_KEY]
+               if frame_rate < 1.0 :
+                       frame_rate = 1.0
                baseband_freq = self[BASEBAND_FREQ_KEY]
                num_lines = self[NUM_LINES_KEY]
                y_divs = self[Y_DIVS_KEY]
index 2596eae45600c74013af035c18b07594c1368f67..18420a013320aa60aabe2adf9b87c72207486539 100644 (file)
@@ -71,6 +71,7 @@ dist_ourdata_DATA = \
        gr_agc2_xx.xml \
        gr_agc_xx.xml \
        gr_and_xx.xml \
+       gr_and_const_xx.xml \
        gr_argmax_xx.xml \
        gr_binary_slicer_fb.xml \
        gr_channel_model.xml \
index 8d91258e516f08417a64f361c0ff2007b57da3db..610a881026c12075b7c6ddfbb67bc42281cb990e 100644 (file)
@@ -58,6 +58,7 @@
 
                <block>gr_add_const_vxx</block>
                <block>gr_multiply_const_vxx</block>
+               <block>gr_and_const_xx</block>
 
                <block>gr_not_xx</block>
                <block>gr_and_xx</block>
index fb3ae57042dbe939ac4718eb74619218eae79552..55b20d4e82db2b051c5c673ba03731ad47c58ebb 100644 (file)
@@ -9,6 +9,11 @@
        <key>gr_agc2_xx</key>
        <import>from gnuradio import gr</import>
        <make>gr.agc2_$(type.fcn)($attack_rate, $decay_rate, $reference, $gain, $max_gain)</make>
+    <callback>set_attack_rate($attack_rate)</callback>
+    <callback>set_decay_rate($decay_rate)</callback>
+    <callback>set_reference($reference)</callback>
+    <callback>set_gain($gain)</callback>
+    <callback>set_max_gain($max_gain)</callback>
        <param>
                <name>Type</name>
                <key>type</key>
diff --git a/grc/blocks/gr_and_const_xx.xml b/grc/blocks/gr_and_const_xx.xml
new file mode 100644 (file)
index 0000000..dc96493
--- /dev/null
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## And Const Block:
+##     all types, 1 output, 1 input & const
+###################################################
+ -->
+<block>
+       <name>And Const</name>
+       <key>gr_and_const_xx</key>
+       <import>from gnuradio import gr</import>
+       <make>gr.and_const_$(type.fcn)($const)</make>
+       <callback>set_k($const)</callback>
+       <param>
+               <name>IO Type</name>
+               <key>type</key>
+               <type>enum</type>
+               <option>
+                       <name>Int</name>
+                       <key>int</key>
+                       <opt>fcn:ii</opt>
+               </option>
+               <option>
+                       <name>Short</name>
+                       <key>short</key>
+                       <opt>fcn:ss</opt>
+               </option>
+               <option>
+                       <name>Byte</name>
+                       <key>byte</key>
+                       <opt>fcn:bb</opt>
+               </option>
+       </param>
+       <param>
+               <name>Constant</name>
+               <key>const</key>
+               <value>0</value>
+               <type>int</type>
+       </param>
+       <sink>
+               <name>in</name>
+               <type>$type</type>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>$type</type>
+       </source>
+</block>
index 880dc27590c013447038f718849701c334505ca6..0081c93f8f5a25c15582c0f2acc73acfe36415e7 100644 (file)
@@ -8,7 +8,9 @@
        <name>File Sink</name>
        <key>gr_file_sink</key>
        <import>from gnuradio import gr</import>
-       <make>gr.file_sink($type.size*$vlen, $file)</make>
+       <make>gr.file_sink($type.size*$vlen, $file)
+self.$(id).set_unbuffered($unbuffered)</make>
+       <callback>set_unbuffered($unbuffered)</callback>
        <param>
                <name>File</name>
                <key>file</key>
                <value>1</value>
                <type>int</type>
        </param>
+       <param>
+               <name>Unbuffered</name>
+               <key>unbuffered</key>
+               <value>False</value>
+               <type>bool</type>
+               <option>
+                               <name>Off</name>
+                               <key>False</key>
+               </option>
+               <option>
+                               <name>On</name>
+                               <key>True</key>
+               </option>
+       </param>
+
        <check>$vlen &gt; 0</check>
        <sink>
                <name>in</name>
index eba45f48981af825c5ec658017b3e221b2e00f43..50cd977be21c8ee3c0ef031e03fded2ad515609d 100644 (file)
@@ -20,6 +20,7 @@ scopesink2.$(type.fcn)(
        ac_couple=$ac_couple,
        xy_mode=$xy_mode,
        num_inputs=$num_inputs,
+       trig_mode=$trig_mode,
 #if $win_size()
        size=$win_size,
 #end if
@@ -134,6 +135,27 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value></value>
                <type>notebook</type>
        </param>
+       <param>
+               <name>Trigger Mode</name>
+               <key>trig_mode</key>
+               <type>enum</type>
+               <option>
+                       <name>Auto</name>
+                       <key>gr.gr_TRIG_MODE_AUTO</key>
+               </option>
+               <option>
+                       <name>Normal</name>
+                       <key>gr.gr_TRIG_MODE_NORM</key>
+               </option>
+               <option>
+                       <name>Freerun</name>
+                       <key>gr.gr_TRIG_MODE_FREE</key>
+               </option>
+               <option>
+                       <name>Stripchart</name>
+                       <key>gr.gr_TRIG_MODE_STRIPCHART</key>
+               </option>
+       </param>
        <check>not $win_size or len($win_size) == 2</check>
        <check>not $xy_mode or '$type' == 'complex' or $num_inputs != 1</check>
        <sink>
index 23bb70bf54db8ef94a816e1b41e78cfdec70c40a..f6aa97a93ad63f94a37dd965a5beb3f3964451b1 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
 #
@@ -22,7 +22,6 @@
 include $(top_srcdir)/Makefile.common
 
 ourdatadir = $(pkgdatadir)/grc/freedesktop
-
 dist_ourdata_DATA = \
        grc-icon-256.png \
        grc-icon-128.png \
@@ -30,11 +29,12 @@ dist_ourdata_DATA = \
        grc-icon-48.png \
        grc-icon-32.png \
        gnuradio-grc.xml \
-       gnuradio-gnuradio-companion.desktop \
+       gnuradio-grc.desktop \
        gnuradio-usrp2_probe.desktop \
        gnuradio-usrp_probe.desktop
 
-dist_bin_SCRIPTS = grc_setup_freedesktop
+pkglibexecdir = $(libexecdir)/$(PACKAGE)
+dist_pkglibexec_SCRIPTS = grc_setup_freedesktop
 
 grc_setup_freedesktop: $(srcdir)/grc_setup_freedesktop.in Makefile
        sed -e 's|@SRCDIR[@]|$(ourdatadir)|g' $< > $@
@@ -46,10 +46,10 @@ install-data-hook:
        @printf "\n*** GRC Post-Install Message ***\
        \nTo install icons, mime type, and menu items\
        \nfor a freedesktop.org system (Gnome/KDE/Xfce):\
-       \n  >>> sudo grc_setup_freedesktop install\n\n"
+       \n  >>> sudo $(pkglibexecdir)/grc_setup_freedesktop install\n\n"
 
 uninstall-hook:
        @printf "\n*** GRC Post-Uninstall Message ***\
        \nTo uninstall icons, mime type, and menu items\
        \nfor a freedesktop.org system (Gnome/KDE/Xfce):\
-       \n  >>> sudo grc_setup_freedesktop uninstall\n\n"
+       \n  >>> sudo $(pkglibexecdir)/grc_setup_freedesktop uninstall\n\n"
diff --git a/grc/freedesktop/gnuradio-gnuradio-companion.desktop b/grc/freedesktop/gnuradio-gnuradio-companion.desktop
deleted file mode 100644 (file)
index 5fd0497..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-[Desktop Entry]
-Version=1.0
-Type=Application
-Name=GRC
-Exec=gnuradio-companion %F
-Categories=Development;
-MimeType=application/gnuradio-grc;
-Icon=gnuradio-grc
diff --git a/grc/freedesktop/gnuradio-grc.desktop b/grc/freedesktop/gnuradio-grc.desktop
new file mode 100644 (file)
index 0000000..5fd0497
--- /dev/null
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Version=1.0
+Type=Application
+Name=GRC
+Exec=gnuradio-companion %F
+Categories=Development;
+MimeType=application/gnuradio-grc;
+Icon=gnuradio-grc
index a0c5ac193bde67f06bf58ae60d6ea4564202d86f..ab4ce82ef883c20ee5238a3acca407b5a793b59c 100644 (file)
@@ -1,4 +1,24 @@
 #!/bin/bash
+#
+# Copyright 2008, 2009, 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 GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
 ##################################################
 # setup grc on a freedesktop platform
 # $1 should be install or uninstall
@@ -8,7 +28,7 @@
 ##################################################
 
 ICON_SIZES="32 48 64 128 256"
-MENU_ITEMS="gnuradio-companion usrp2_probe usrp_probe"
+MENU_ITEMS="grc usrp2_probe usrp_probe"
 if [ -n "$2" ]; then
        SRCDIR="$2"
 else
@@ -39,11 +59,12 @@ case "$1" in
        echo "Begin freedesktop uninstall..."
        for size in ${ICON_SIZES}; do \
                echo "Uninstall icon: ${size}x${size}"
-               xdg-icon-resource uninstall --context mimetypes --theme gnome --size ${size} application-gnuradio-grc; \
-               xdg-icon-resource uninstall --context mimetypes --size ${size} application-gnuradio-grc; \
-               xdg-icon-resource uninstall --context apps --theme gnome --size ${size} gnuradio-grc; \
-               xdg-icon-resource uninstall --context apps --size ${size} gnuradio-grc; \
+               xdg-icon-resource uninstall --noupdate --context mimetypes --theme gnome --size ${size} application-gnuradio-grc; \
+               xdg-icon-resource uninstall --noupdate --context mimetypes --size ${size} application-gnuradio-grc; \
+               xdg-icon-resource uninstall --noupdate --context apps --theme gnome --size ${size} gnuradio-grc; \
+               xdg-icon-resource uninstall --noupdate --context apps --size ${size} gnuradio-grc; \
        done
+       xdg-icon-resource forceupdate
        echo "Uninstall mime type"
        xdg-mime uninstall ${SRCDIR}/gnuradio-grc.xml
        echo "Uninstall menu items"
index dd39b095de5a0c14920ee1db2bed655c43e5ae1a..bd03eb5cdbfc7d078578a59fd8690be23e0fd4b4 100644 (file)
@@ -75,42 +75,48 @@ class Block(_Block, _GUIBlock):
                Add and remove ports to adjust for the nports.
                """
                _Block.rewrite(self)
+
+               def insert_port(get_ports, get_port, key):
+                       prev_port = get_port(str(int(key)-1))
+                       get_ports().insert(
+                               get_ports().index(prev_port)+1,
+                               prev_port.copy(new_key=key),
+                       )
+                       #restore integer contiguity after insertion
+                       for i, port in enumerate(get_ports()): port._key = str(i)
+
+               def remove_port(get_ports, get_port, key):
+                       port = get_port(key)
+                       for connection in port.get_connections():
+                               self.get_parent().remove_element(connection)
+                       get_ports().remove(port)
+                       #restore integer contiguity after insertion
+                       for i, port in enumerate(get_ports()): port._key = str(i)
+
                #adjust nports
                for get_ports, get_port in (
                        (self.get_sources, self.get_source),
                        (self.get_sinks, self.get_sink),
                ):
-                       #how many streaming (non-message) ports?
-                       num_ports = len(filter(lambda p: p.get_type() != 'msg', get_ports()))
-                       #do nothing for 0 ports
-                       if not num_ports: continue
-                       #get the nports setting
-                       port0 = get_port(str(0))
-                       nports = port0.get_nports()
-                       #do nothing for no nports
-                       if not nports: continue
-                       #do nothing if nports is already num ports
-                       if nports == num_ports: continue
-                       #remove excess ports and connections
-                       if nports < num_ports:
-                               #remove the connections
-                               for key in map(str, range(nports, num_ports)):
-                                       port = get_port(key)
-                                       for connection in port.get_connections():
-                                               self.get_parent().remove_element(connection)
-                               #remove the ports
-                               for key in map(str, range(nports, num_ports)):
-                                       get_ports().remove(get_port(key))
-                               continue
-                       #add more ports
-                       if nports > num_ports:
-                               for key in map(str, range(num_ports, nports)):
-                                       prev_port = get_port(str(int(key)-1))
-                                       get_ports().insert(
-                                               get_ports().index(prev_port)+1,
-                                               prev_port.copy(new_key=key),
-                                       )
-                               continue
+                       master_ports = filter(lambda p: p.get_nports(), get_ports())
+                       for i, master_port in enumerate(master_ports):
+                               nports = master_port.get_nports()
+                               index_first = get_ports().index(master_port)
+                               try: index_last = get_ports().index(master_ports[i+1])
+                               except IndexError: index_last = len(get_ports())
+                               num_ports = index_last - index_first
+                               #do nothing if nports is already num ports
+                               if nports == num_ports: continue
+                               #remove excess ports and connections
+                               if nports < num_ports:
+                                       for key in map(str, range(index_first+nports, index_first+num_ports)):
+                                               remove_port(get_ports, get_port, key)
+                                       continue
+                               #add more ports
+                               if nports > num_ports:
+                                       for key in map(str, range(index_first+num_ports, index_first+nports)):
+                                               insert_port(get_ports, get_port, key)
+                                       continue
 
        def port_controller_modify(self, direction):
                """
@@ -119,10 +125,8 @@ class Block(_Block, _GUIBlock):
                @return true for change
                """
                changed = False
-               #concat the nports string from the private nports settings of both port0
-               nports_str = \
-                       (self.get_sinks() and self.get_sinks()[0]._nports or '') + \
-                       (self.get_sources() and self.get_sources()[0]._nports or '')
+               #concat the nports string from the private nports settings of all ports
+               nports_str = ' '.join([port._nports for port in self.get_ports()])
                #modify all params whose keys appear in the nports string
                for param in self.get_params():
                        if param.is_enum() or param.get_key() not in nports_str: continue
index 6965371df8a9e922dbeb808d78da53bf93c81a59..6e5a5c59f2a24045750caa8598e120291dcecaa0 100644 (file)
@@ -167,5 +167,7 @@ class Port(_Port, _GUIPort):
 
        def copy(self, new_key=None):
                n = self._n.copy()
+               #remove nports from the key so the copy cannot be a duplicator
+               if n.has_key('nports'): n.pop('nports')
                if new_key: n['key'] = new_key
                return self.__class__(self.get_parent(), n, self._dir)
index c371b023b539b79ec257133efe28bb36b6e837c5..514b24d8b0f26b6a44aa2f24f6b3b7267f1af557 100644 (file)
@@ -163,6 +163,27 @@ pmt_t pmt_from_long(long x);
  */
 long pmt_to_long(pmt_t x);
 
+/*
+ * ------------------------------------------------------------------------
+ *                            uint64_t
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is an uint64 number, else false
+bool pmt_is_uint64(pmt_t x);
+
+//! Return the pmt value that represents the uint64 \p x.
+pmt_t pmt_from_uint64(uint64_t x);
+
+/*!
+ * \brief Convert pmt to uint64 if possible.
+ *
+ * When \p x represents an exact integer that fits in a uint64,
+ * return that uint64.  Else raise an exception, either wrong_type
+ * when x is not an exact uint64, or out_of_range when it doesn't fit.
+ */
+uint64_t pmt_to_uint64(pmt_t x);
+
 /*
  * ------------------------------------------------------------------------
  *                             Reals
index aa1688d24a8b69f18fda47fb9393e3cb5b43f8a8..f9cf6b4bf681b3172786e6d4df0304d312f95023 100644 (file)
@@ -105,6 +105,12 @@ _integer(pmt_t x)
   return dynamic_cast<pmt_integer*>(x.get());
 }
 
+static pmt_uint64 *
+_uint64(pmt_t x)
+{
+  return dynamic_cast<pmt_uint64*>(x.get());
+}
+
 static pmt_real *
 _real(pmt_t x)
 {
@@ -304,6 +310,40 @@ pmt_to_long(pmt_t x)
   throw pmt_wrong_type("pmt_to_long", x);
 }
 
+////////////////////////////////////////////////////////////////////////////
+//                             Uint64
+////////////////////////////////////////////////////////////////////////////
+
+pmt_uint64::pmt_uint64(uint64_t value) : d_value(value) {}
+
+bool
+pmt_is_uint64(pmt_t x)
+{
+  return x->is_uint64();
+}
+
+
+pmt_t
+pmt_from_uint64(uint64_t x)
+{
+  return pmt_t(new pmt_uint64(x));
+}
+
+uint64_t
+pmt_to_uint64(pmt_t x)
+{
+  if(x->is_uint64())
+    return _uint64(x)->value();
+  if(x->is_integer())
+    {
+    long tmp = _integer(x)->value();
+    if(tmp >= 0)
+        return (uint64_t) tmp;
+    }
+
+  throw pmt_wrong_type("pmt_to_uint64", x);
+}
+
 ////////////////////////////////////////////////////////////////////////////
 //                              Real
 ////////////////////////////////////////////////////////////////////////////
@@ -929,6 +969,9 @@ pmt_eqv(const pmt_t& x, const pmt_t& y)
   if (x->is_integer() && y->is_integer())
     return _integer(x)->value() == _integer(y)->value();
 
+  if (x->is_uint64() && y->is_uint64())
+    return _uint64(x)->value() == _uint64(y)->value();
+
   if (x->is_real() && y->is_real())
     return _real(x)->value() == _real(y)->value();
 
@@ -947,6 +990,9 @@ pmt_eqv_raw(pmt_base *x, pmt_base *y)
   if (x->is_integer() && y->is_integer())
     return _integer(x)->value() == _integer(y)->value();
 
+  if (x->is_uint64() && y->is_uint64())
+    return _uint64(x)->value() == _uint64(y)->value();
+
   if (x->is_real() && y->is_real())
     return _real(x)->value() == _real(y)->value();
 
@@ -1328,6 +1374,7 @@ pmt_dump_sizeof()
   printf("sizeof(pmt_bool)           = %3zd\n", sizeof(pmt_bool));
   printf("sizeof(pmt_symbol)         = %3zd\n", sizeof(pmt_symbol));
   printf("sizeof(pmt_integer)        = %3zd\n", sizeof(pmt_integer));
+  printf("sizeof(pmt_uint64)         = %3zd\n", sizeof(pmt_uint64));
   printf("sizeof(pmt_real)           = %3zd\n", sizeof(pmt_real));
   printf("sizeof(pmt_complex)        = %3zd\n", sizeof(pmt_complex));
   printf("sizeof(pmt_null)           = %3zd\n", sizeof(pmt_null));
index 50683ffb525365ec10d6d39debe350be27d4c59b..ea28e37b41cc9630084947c1dd6c039ab8809216 100644 (file)
@@ -47,6 +47,7 @@ public:
   virtual bool is_symbol()  const { return false; }
   virtual bool is_number()  const { return false; }
   virtual bool is_integer() const { return false; }
+  virtual bool is_uint64()  const { return false; }
   virtual bool is_real()    const { return false; }
   virtual bool is_complex() const { return false; }
   virtual bool is_null()    const { return false; }
@@ -118,6 +119,19 @@ public:
   long value() const { return d_value; }
 };
 
+class pmt_uint64 : public pmt_base
+{
+public:
+  uint64_t             d_value;
+
+  pmt_uint64(uint64_t value);
+  //~pmt_uint64(){}
+
+  bool is_number()  const { return true; }
+  bool is_uint64() const { return true; }
+  uint64_t value() const { return d_value; }
+};
+
 class pmt_real : public pmt_base
 {
 public:
index 179e6b72cb4f0450bfde2ced2e9711e38d717b79..b909c1b64b8210f5f182ebd73baef4c7050d4fc3 100644 (file)
@@ -64,6 +64,8 @@ pmt_write(pmt_t obj, std::ostream &port)
   else if (pmt_is_number(obj)){
     if (pmt_is_integer(obj))
       port << pmt_to_long(obj);
+    else if (pmt_is_uint64(obj))
+      port << pmt_to_uint64(obj);
     else if (pmt_is_real(obj))
       port << pmt_to_double(obj);
     else if (pmt_is_complex(obj)){
index f2414c72cdc18528b9c3aebcf63298822473c573..985361f13f36e5fa7e0286703757b5b18eb07fe1 100644 (file)
@@ -103,6 +103,19 @@ qa_pmt_prims::test_integers()
   CPPUNIT_ASSERT_EQUAL(1L, pmt_to_long(p1));
 }
 
+void
+qa_pmt_prims::test_uint64s()
+{
+  pmt_t p1 = pmt_from_uint64((uint64_t)1);
+  pmt_t m1 = pmt_from_uint64((uint64_t)8589934592ULL);
+  CPPUNIT_ASSERT(!pmt_is_uint64(PMT_T));
+  CPPUNIT_ASSERT(pmt_is_uint64(p1));
+  CPPUNIT_ASSERT(pmt_is_uint64(m1));
+  CPPUNIT_ASSERT_THROW(pmt_to_uint64(PMT_T), pmt_wrong_type);
+  CPPUNIT_ASSERT_EQUAL((uint64_t)8589934592ULL, (uint64_t)pmt_to_uint64(m1));
+  CPPUNIT_ASSERT_EQUAL((uint64_t)1ULL, (uint64_t)pmt_to_uint64(p1));
+}
+
 void
 qa_pmt_prims::test_reals()
 {
index 29ba02f11cb28bcf50d0e547a4d46c593be9047d..efc5c6050650ecc04eba810570f135013872ec8e 100644 (file)
@@ -31,6 +31,7 @@ class qa_pmt_prims : public CppUnit::TestCase {
   CPPUNIT_TEST(test_symbols);
   CPPUNIT_TEST(test_booleans);
   CPPUNIT_TEST(test_integers);
+  CPPUNIT_TEST(test_uint64s);
   CPPUNIT_TEST(test_reals);
   CPPUNIT_TEST(test_complexes);
   CPPUNIT_TEST(test_pairs);
@@ -52,6 +53,7 @@ class qa_pmt_prims : public CppUnit::TestCase {
   void test_symbols();
   void test_booleans();
   void test_integers();
+  void test_uint64s();
   void test_reals();
   void test_complexes();
   void test_pairs();
index 8fb9143eb7a25fcfbea75cbd3c5f4a03d2d9cf88..0c908e3d55b05ba688e8952da054d960b0d7ceab 100755 (executable)
@@ -65,6 +65,7 @@ daughterboards = {
     'rfx900_mimo_b'   : ((FLEX_900_TX_MIMO_B, 0x0000),     (FLEX_900_RX_MIMO_B, 0x0000)),
     'rfx1200_mimo_b'  : ((FLEX_1200_TX_MIMO_B, 0x0000),    (FLEX_1200_RX_MIMO_B, 0x0000)),
     'rfx1800_mimo_b'  : ((FLEX_1800_TX_MIMO_B, 0x0000),    (FLEX_1800_RX_MIMO_B, 0x0000)),
+    'rfx2200_mimo_b'  : ((FLEX_2200_TX_MIMO_B, 0x0000),    (FLEX_2200_RX_MIMO_B, 0x0000)),
     'rfx2400_mimo_b'  : ((FLEX_2400_TX_MIMO_B, 0x0000),    (FLEX_2400_RX_MIMO_B, 0x0000)),
     'lftx'            : ((LF_TX, 0x0000),           None),
     'lfrx'            : (None,                      (LF_RX, 0x0000)),
index 0c834402d0e44f8fa4f70bec409bc85672fef007..70a55514ee5188fa4c0938567577cb229b796805 100644 (file)
@@ -138,6 +138,18 @@ protected:
 
 //----------------------------------------------------------------------
 
+class _2200_common : public _AD4360_common
+{
+ public:
+  _2200_common();
+  ~_2200_common() {}
+  double freq_min();
+  double freq_max();
+};
+
+//----------------------------------------------------------------------
+
 class _2400_common : public _AD4360_common
 {
  public:
@@ -212,6 +224,34 @@ public:
 
 //------------------------------------------------------------    
 
+class db_flexrf_2200_tx : public flexrf_base_tx
+{
+ public:
+  db_flexrf_2200_tx(usrp_basic_sptr usrp, int which);
+  ~db_flexrf_2200_tx();
+
+  // Wrapper calls to d_common functions
+  bool _compute_regs(double freq, int &retR, int &retcontrol,
+                    int &retN, double &retfreq);
+};
+
+class db_flexrf_2200_rx : public flexrf_base_rx
+{
+public:
+  db_flexrf_2200_rx(usrp_basic_sptr usrp, int which);
+  ~db_flexrf_2200_rx();
+  
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  bool i_and_q_swapped();
+
+  bool _compute_regs(double freq, int &retR, int &retcontrol,
+                    int &retN, double &retfreq);
+};
+
+//------------------------------------------------------------    
+
 class db_flexrf_2400_tx : public flexrf_base_tx
 {
  public:
index 07ac2be3bc22e1cafc1479e5dee61e2d31b9c245..2819c19bd79f73c443a3c0c13fd690e3b76f5947 100644 (file)
@@ -639,6 +639,38 @@ _AD4360_common::_prescaler()
 
 //----------------------------------------------------------------------
 
+_2200_common::_2200_common()
+  : _AD4360_common()
+{
+  // Band-specific R-Register Values
+  d_R_DIV = 16;  // bits 15:2
+   
+  // Band-specific C-Register values
+  d_P = 1;        // bits 23,22   Div by 16/17
+  d_CP2 = 7;      // bits 19:17
+  d_CP1 = 7;      // bits 16:14
+
+  // Band specifc N-Register Values
+  d_DIVSEL = 0;   // bit 23
+  d_DIV2 = 0;     // bit 22
+  d_CPGAIN = 0;   // bit 21
+  d_freq_mult = 1;
+}
+
+double
+_2200_common::freq_min()
+{
+  return 2000e6;
+}
+
+double
+_2200_common::freq_max()
+{
+  return 2400e6;
+}
+
+//----------------------------------------------------------------------
+
 _2400_common::_2400_common()
   : _AD4360_common()
 {
@@ -811,6 +843,72 @@ _400_rx::_400_rx()
 
 //------------------------------------------------------------    
 
+db_flexrf_2200_tx::db_flexrf_2200_tx(usrp_basic_sptr usrp, int which)
+  : flexrf_base_tx(usrp, which)
+{
+  d_common = new _2200_common();
+}
+
+db_flexrf_2200_tx::~db_flexrf_2200_tx()
+{
+}
+
+bool
+db_flexrf_2200_tx::_compute_regs(double freq, int &retR, int &retcontrol,
+                                int &retN, double &retfreq)
+{
+  return d_common->_compute_regs(_refclk_freq(), freq, retR,
+                                retcontrol, retN, retfreq);
+}
+
+
+
+db_flexrf_2200_rx::db_flexrf_2200_rx(usrp_basic_sptr usrp, int which)
+  : flexrf_base_rx(usrp, which)
+{
+  d_common = new _2200_common();
+  set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
+}
+
+db_flexrf_2200_rx::~db_flexrf_2200_rx()
+{
+}
+
+float
+db_flexrf_2200_rx::gain_min()
+{
+  return usrp()->pga_min();
+}
+
+float
+db_flexrf_2200_rx::gain_max()
+{
+  return usrp()->pga_max()+70;
+}
+
+float
+db_flexrf_2200_rx::gain_db_per_step()
+{
+  return 0.05;
+}
+
+
+bool
+db_flexrf_2200_rx::i_and_q_swapped()
+{
+  return true;
+}
+
+bool
+db_flexrf_2200_rx::_compute_regs(double freq, int &retR, int &retcontrol,
+                                int &retN, double &retfreq)
+{
+  return d_common->_compute_regs(_refclk_freq(), freq, retR,
+                                retcontrol, retN, retfreq);
+}
+
+//------------------------------------------------------------    
+
 db_flexrf_2400_tx::db_flexrf_2400_tx(usrp_basic_sptr usrp, int which)
   : flexrf_base_tx(usrp, which)
 {
index 5193a5fa0ef18b66f13985864d229205471c3681..2548d737e5cf0d6c1485d362c62bedac3b9ba421 100644 (file)
@@ -61,6 +61,9 @@
 "Flex 1200 Tx MIMO B"  0x002a
 "Flex 2400 Tx MIMO B"  0x002b
 
+"Flex 2200 Rx MIMO B"  0x002c
+"Flex 2200 Tx MIMO B"  0x002d
+
 "Flex 1800 Rx"         0x0030
 "Flex 1800 Tx"         0x0031
 "Flex 1800 Rx MIMO A"  0x0032
index 546559010de4bc42a2b6236a77f9d3ebf8197b39..d07d3c1fb4c0a3cf7f9e3146c478cb83f23877ec 100644 (file)
@@ -120,6 +120,16 @@ struct db_rfx_1800_tx {
   struct db_rfx_common common;
 };
 
+struct db_rfx_2200_rx {
+  struct db_base       base;
+  struct db_rfx_common common;
+};
+
+struct db_rfx_2200_tx {
+  struct db_base       base;
+  struct db_rfx_common common;
+};
+
 struct db_rfx_2400_rx {
   struct db_base       base;
   struct db_rfx_common common;
@@ -387,6 +397,70 @@ struct db_rfx_1800_tx db_rfx_1800_tx = {
 };
 
 
+struct db_rfx_2200_rx db_rfx_2200_rx = {
+  .base.dbid = 0x002c,
+  .base.is_tx = false,
+  .base.output_enables = 0x00E0,
+  .base.used_pins = 0x00FF,
+  .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(2000e6),
+  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2400e6),
+  .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
+  .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(70),
+  .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.034),
+  .base.is_quadrature = true,
+  .base.i_and_q_swapped = true,
+  .base.spectrum_inverted = false,
+  .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0),
+  .base.init = rfx_init_rx,
+  .base.set_freq = rfx_set_freq,
+  .base.set_gain = rfx_set_gain_rx,
+  .base.set_tx_enable = 0,
+  .base.atr_mask = 0x00E0,
+  .base.atr_txval = 0,
+  .base.atr_rxval = MIX_EN,
+  // .base.atr_tx_delay =
+  // .base.atr_rx_delay =
+  .base.set_antenna = 0,
+  .common.DIV2 = 0,
+  .common.CP1 = 7,
+  .common.CP2 = 7,
+  .common.spi_mask = SPI_SS_RX_DB,
+  .common.freq_mult = 1
+};
+
+
+struct db_rfx_2200_tx db_rfx_2200_tx = {
+  .base.dbid = 0x002d,
+  .base.is_tx = true,
+  .base.output_enables = 0x00E0,
+  .base.used_pins = 0x00FF,
+  .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(2000e6),
+  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2400e6),
+  //.base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(xxx),
+  //.base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(xxx),
+  //.base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(xxx),
+  .base.is_quadrature = true,
+  .base.i_and_q_swapped = false,
+  .base.spectrum_inverted = false,
+  .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(12.5e6),
+  .base.init = rfx_init_tx,
+  .base.set_freq = rfx_set_freq,
+  .base.set_gain = rfx_set_gain_tx,
+  .base.set_tx_enable = rfx_set_tx_enable,
+  .base.atr_mask = 0x00E0,
+  .base.atr_txval = MIX_EN, 
+  .base.atr_rxval = ANT_SW,
+  // .base.atr_tx_delay =
+  // .base.atr_rx_delay =
+  .base.set_antenna = 0,
+  .common.DIV2 = 0,
+  .common.CP1 = 7,
+  .common.CP2 = 7,
+  .common.spi_mask = SPI_SS_TX_DB,
+  .common.freq_mult = 1
+};
+
+
 struct db_rfx_2400_rx db_rfx_2400_rx = {
   .base.dbid = 0x0027,
   .base.is_tx = false,
index 01a47b5d9233cedff83f6428b8f8d7130b2d4db2..70d6d74f92cd15540af6b4d810aef1f125b95e74 100644 (file)
@@ -1,4 +1,4 @@
 MAJOR_VERSION=3
 API_COMPAT=3
-MINOR_VERSION=0
-MAINT_VERSION=0
+MINOR_VERSION=1
+MAINT_VERSION=git