summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.common3
-rw-r--r--README.building-boost2
-rw-r--r--config/grc_gr_usrp.m42
-rw-r--r--configure.ac2
-rw-r--r--gnuradio-examples/c++/Makefile.am4
-rwxr-xr-xgnuradio-examples/python/apps/hf_explorer/hfx2.py4
-rw-r--r--gnuradio-examples/python/dect/usrp_source.py4
-rwxr-xr-xgnuradio-examples/python/digital-bert/benchmark_tx.py2
-rw-r--r--gnuradio-examples/python/digital/transmit_path.py2
-rwxr-xr-xgnuradio-examples/python/multi-antenna/multi_fft.py10
-rwxr-xr-xgnuradio-examples/python/multi-antenna/multi_file.py10
-rwxr-xr-xgnuradio-examples/python/multi-antenna/multi_scope.py10
-rwxr-xr-xgnuradio-examples/python/multi_usrp/multi_usrp_oscope.py4
-rwxr-xr-xgnuradio-examples/python/ofdm/benchmark_ofdm_tx.py2
-rwxr-xr-xgnuradio-examples/python/ofdm/tunnel.py4
-rwxr-xr-xgnuradio-examples/python/usrp/fm_tx4.py14
-rwxr-xr-xgnuradio-examples/python/usrp/fm_tx_2_daughterboards.py4
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_nbfm_ptt.py2
-rw-r--r--gr-usrp/Makefile.am10
-rw-r--r--gr-usrp/apps/Makefile.am57
-rw-r--r--gr-usrp/apps/usrp_rx_cfile.cc245
-rw-r--r--gr-usrp/apps/usrp_rx_cfile.h62
-rw-r--r--gr-usrp/apps/usrp_siggen.cc214
-rw-r--r--gr-usrp/apps/usrp_siggen.h52
-rw-r--r--gr-usrp/gnuradio-usrp.pc.in11
-rw-r--r--gr-usrp/src/Makefile.am179
-rw-r--r--gr-usrp/src/__init__.py (renamed from gr-usrp/src/db_instantiator.py)15
-rw-r--r--gr-usrp/src/db_base.py264
-rw-r--r--gr-usrp/src/db_basic.py252
-rw-r--r--gr-usrp/src/db_dbs_rx.py345
-rw-r--r--gr-usrp/src/db_dtt754.py229
-rw-r--r--gr-usrp/src/db_dtt768.py203
-rw-r--r--gr-usrp/src/db_flexrf.py701
-rw-r--r--gr-usrp/src/db_flexrf_mimo.py286
-rw-r--r--gr-usrp/src/db_tv_rx.py198
-rw-r--r--gr-usrp/src/db_wbx.py622
-rw-r--r--gr-usrp/src/db_xcvr2450.py538
-rwxr-xr-xgr-usrp/src/qa_usrp.py2
-rw-r--r--gr-usrp/src/usrp.i144
-rw-r--r--gr-usrp/src/usrp.py482
-rw-r--r--gr-usrp/src/usrp1.i657
-rw-r--r--gr-usrp/src/usrp1_sink_base.cc359
-rw-r--r--gr-usrp/src/usrp1_sink_base.h359
-rw-r--r--gr-usrp/src/usrp1_source_base.cc425
-rw-r--r--gr-usrp/src/usrp_base.cc316
-rw-r--r--gr-usrp/src/usrp_base.h (renamed from gr-usrp/src/usrp1_source_base.h)456
-rw-r--r--gr-usrp/src/usrp_base.i83
-rw-r--r--gr-usrp/src/usrp_sink_base.cc241
-rw-r--r--gr-usrp/src/usrp_sink_base.h151
-rw-r--r--gr-usrp/src/usrp_sink_base.i54
-rw-r--r--gr-usrp/src/usrp_sink_c.cc (renamed from gr-usrp/src/usrp1_sink_c.cc)16
-rw-r--r--gr-usrp/src/usrp_sink_c.h (renamed from gr-usrp/src/usrp1_sink_c.h)42
-rw-r--r--gr-usrp/src/usrp_sink_c.i47
-rw-r--r--gr-usrp/src/usrp_sink_s.cc (renamed from gr-usrp/src/usrp1_sink_s.cc)16
-rw-r--r--gr-usrp/src/usrp_sink_s.h (renamed from gr-usrp/src/usrp1_sink_s.h)42
-rw-r--r--gr-usrp/src/usrp_sink_s.i47
-rw-r--r--gr-usrp/src/usrp_source_base.cc295
-rw-r--r--gr-usrp/src/usrp_source_base.h219
-rw-r--r--gr-usrp/src/usrp_source_base.i63
-rw-r--r--gr-usrp/src/usrp_source_c.cc (renamed from gr-usrp/src/usrp1_source_c.cc)18
-rw-r--r--gr-usrp/src/usrp_source_c.h (renamed from gr-usrp/src/usrp1_source_c.h)42
-rw-r--r--gr-usrp/src/usrp_source_c.i48
-rw-r--r--gr-usrp/src/usrp_source_s.cc (renamed from gr-usrp/src/usrp1_source_s.cc)18
-rw-r--r--gr-usrp/src/usrp_source_s.h (renamed from gr-usrp/src/usrp1_source_s.h)44
-rw-r--r--gr-usrp/src/usrp_source_s.i48
-rw-r--r--gr-usrp/src/usrp_standard.i36
-rwxr-xr-xgr-utils/src/python/usrp_fft.py4
-rwxr-xr-xgr-utils/src/python/usrp_oscope.py4
-rwxr-xr-xgr-utils/src/python/usrp_siggen.py3
-rw-r--r--grc/src/grc_gnuradio/usrp/simple_usrp.py34
-rw-r--r--usrp/host/apps/test_usrp_standard_rx.cc10
-rw-r--r--usrp/host/apps/test_usrp_standard_tx.cc12
-rw-r--r--usrp/host/apps/usrp_cal_dc_offset.cc10
-rw-r--r--usrp/host/lib/inband/qa_inband_usrp_server.cc6
-rw-r--r--usrp/host/lib/inband/usrp_usb_interface.cc17
-rw-r--r--usrp/host/lib/inband/usrp_usb_interface.h6
-rw-r--r--usrp/host/lib/legacy/Makefile.am40
-rw-r--r--usrp/host/lib/legacy/db_base.cc245
-rw-r--r--usrp/host/lib/legacy/db_base.h114
-rw-r--r--usrp/host/lib/legacy/db_base.i101
-rw-r--r--usrp/host/lib/legacy/db_base_impl.h33
-rw-r--r--usrp/host/lib/legacy/db_basic.cc263
-rw-r--r--usrp/host/lib/legacy/db_basic.h99
-rw-r--r--usrp/host/lib/legacy/db_boards.cc215
-rw-r--r--usrp/host/lib/legacy/db_boards.h33
-rw-r--r--usrp/host/lib/legacy/db_dbs_rx.cc491
-rw-r--r--usrp/host/lib/legacy/db_dbs_rx.h81
-rw-r--r--usrp/host/lib/legacy/db_dtt754.cc321
-rw-r--r--usrp/host/lib/legacy/db_dtt754.h57
-rw-r--r--usrp/host/lib/legacy/db_dtt768.cc294
-rw-r--r--usrp/host/lib/legacy/db_dtt768.h57
-rw-r--r--usrp/host/lib/legacy/db_flexrf.cc1148
-rw-r--r--usrp/host/lib/legacy/db_flexrf.h355
-rw-r--r--usrp/host/lib/legacy/db_flexrf_mimo.cc276
-rw-r--r--usrp/host/lib/legacy/db_flexrf_mimo.h163
-rw-r--r--usrp/host/lib/legacy/db_tv_rx.cc274
-rw-r--r--usrp/host/lib/legacy/db_tv_rx.h56
-rw-r--r--usrp/host/lib/legacy/db_util.cc54
-rw-r--r--usrp/host/lib/legacy/db_util.h31
-rw-r--r--usrp/host/lib/legacy/db_wbx.cc953
-rw-r--r--usrp/host/lib/legacy/db_wbx.h221
-rw-r--r--usrp/host/lib/legacy/db_xcvr2450.cc762
-rw-r--r--usrp/host/lib/legacy/db_xcvr2450.h221
-rw-r--r--usrp/host/lib/legacy/usrp_basic.cc694
-rw-r--r--usrp/host/lib/legacy/usrp_basic.h809
-rw-r--r--usrp/host/lib/legacy/usrp_standard.cc370
-rw-r--r--usrp/host/lib/legacy/usrp_standard.h114
-rw-r--r--usrp/host/lib/legacy/usrp_subdev_spec.h50
-rw-r--r--usrp/host/lib/legacy/usrp_tune_result.h44
-rw-r--r--usrp2/host/include/usrp2/tune_result.h11
110 files changed, 11465 insertions, 7029 deletions
diff --git a/Makefile.common b/Makefile.common
index f7c88b0d97..35cd1a300e 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -56,7 +56,8 @@ WITH_INCLUDES = @with_INCLUDES@
WITH_SWIG_INCLUDES = @with_SWIG_INCLUDES@
# swig flags
-SWIGPYTHONFLAGS = -fvirtual -python -modern
+# -w511 turns off keyword argument warning
+SWIGPYTHONFLAGS = -fvirtual -python -modern -keyword -w511
# How to link in the top-level omnithreads library from inside the tree
OMNITHREAD_INCLUDES = @omnithread_INCLUDES@
diff --git a/README.building-boost b/README.building-boost
index 0e7059de3a..511adb58bb 100644
--- a/README.building-boost
+++ b/README.building-boost
@@ -14,7 +14,7 @@ $ cd boost_1_36_0
$ BOOST_PREFIX=/opt/boost_1_36_0
-$ ./configure --prefix=$BOOST_PREFIX --with-libraries=thread,date_time
+$ ./configure --prefix=$BOOST_PREFIX --with-libraries=thread,date_time,program_options
$ make
$ make install
diff --git a/config/grc_gr_usrp.m4 b/config/grc_gr_usrp.m4
index c28d9757d5..1f2cd1ac73 100644
--- a/config/grc_gr_usrp.m4
+++ b/config/grc_gr_usrp.m4
@@ -26,8 +26,10 @@ AC_DEFUN([GRC_GR_USRP],[
AC_CONFIG_FILES([ \
gr-usrp/Makefile \
+ gr-usrp/gnuradio-usrp.pc \
gr-usrp/src/Makefile \
gr-usrp/src/run_tests \
+ gr-usrp/apps/Makefile \
])
GRC_BUILD_CONDITIONAL(gr-usrp,[
diff --git a/configure.ac b/configure.ac
index cd63f5b1bc..bb70dd0cd5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -230,7 +230,7 @@ dnl
AX_BOOST_DATE_TIME
dnl AX_BOOST_FILESYSTEM
dnl AX_BOOST_IOSTREAMS
-dnl AX_BOOST_PROGRAM_OPTIONS
+AX_BOOST_PROGRAM_OPTIONS
dnl AX_BOOST_REGEX
dnl AX_BOOST_SERIALIZATION
dnl AX_BOOST_SIGNALS
diff --git a/gnuradio-examples/c++/Makefile.am b/gnuradio-examples/c++/Makefile.am
index 5ac086075b..43c63847a7 100644
--- a/gnuradio-examples/c++/Makefile.am
+++ b/gnuradio-examples/c++/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2006 Free Software Foundation, Inc.
+# Copyright 2006,2008 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -20,4 +20,4 @@
#
include $(top_srcdir)/Makefile.common
-# SUBDIRS = dial_tone
+#SUBDIRS = dial_tone
diff --git a/gnuradio-examples/python/apps/hf_explorer/hfx2.py b/gnuradio-examples/python/apps/hf_explorer/hfx2.py
index 00b1eddfd4..00a3b90476 100755
--- a/gnuradio-examples/python/apps/hf_explorer/hfx2.py
+++ b/gnuradio-examples/python/apps/hf_explorer/hfx2.py
@@ -118,9 +118,9 @@ def pick_subdevice(u):
If there's a daughterboard on B, select B.
Otherwise, select A.
"""
- if u.db[0][0].dbid() >= 0: # dbid is < 0 if there's no d'board or a problem
+ if u.db(0, 0).dbid() >= 0: # dbid is < 0 if there's no d'board or a problem
return (0, 0)
- if u.db[1][0].dbid() >= 0:
+ if u.db(1, 0).dbid() >= 0:
return (1, 0)
return (0, 0)
diff --git a/gnuradio-examples/python/dect/usrp_source.py b/gnuradio-examples/python/dect/usrp_source.py
index 6a779840f2..df19ff2784 100644
--- a/gnuradio-examples/python/dect/usrp_source.py
+++ b/gnuradio-examples/python/dect/usrp_source.py
@@ -64,9 +64,9 @@ class usrp_source_c(gr.hier_block2):
If there's a daughterboard on B, select B.
Otherwise, select A.
"""
- if self._u.db[0][0].dbid() >= 0: # dbid is < 0 if there's no d'board or a problem
+ if self._u.db(0, 0).dbid() >= 0: # dbid is < 0 if there's no d'board or a problem
return (0, 0)
- if self._u.db[1][0].dbid() >= 0:
+ if self._u.db(1, 0).dbid() >= 0:
return (1, 0)
return (0, 0)
diff --git a/gnuradio-examples/python/digital-bert/benchmark_tx.py b/gnuradio-examples/python/digital-bert/benchmark_tx.py
index 1778a74b5d..000f4bca2e 100755
--- a/gnuradio-examples/python/digital-bert/benchmark_tx.py
+++ b/gnuradio-examples/python/digital-bert/benchmark_tx.py
@@ -60,7 +60,7 @@ class tx_bpsk_block(gr.top_block):
subdev_spec = usrp.pick_tx_subdevice(self._usrp)
self._usrp.set_mux(usrp.determine_tx_mux_value(self._usrp, subdev_spec))
self._subdev = usrp.selected_subdev(self._usrp, subdev_spec)
- tr = usrp.tune(self._usrp, self._subdev._which, self._subdev, freq)
+ tr = usrp.tune(self._usrp, self._subdev.which(), self._subdev, freq)
if not (tr):
print "Failed to tune to center frequency!"
else:
diff --git a/gnuradio-examples/python/digital/transmit_path.py b/gnuradio-examples/python/digital/transmit_path.py
index 69989606a7..250c3f0488 100644
--- a/gnuradio-examples/python/digital/transmit_path.py
+++ b/gnuradio-examples/python/digital/transmit_path.py
@@ -141,7 +141,7 @@ class transmit_path(gr.hier_block2):
the result of that operation and our target_frequency to
determine the value for the digital up converter.
"""
- r = self.u.tune(self.subdev._which, self.subdev, target_freq)
+ r = self.u.tune(self.subdev.which(), self.subdev, target_freq)
if r:
return True
diff --git a/gnuradio-examples/python/multi-antenna/multi_fft.py b/gnuradio-examples/python/multi-antenna/multi_fft.py
index 0f1dbb1027..54d8286d43 100755
--- a/gnuradio-examples/python/multi-antenna/multi_fft.py
+++ b/gnuradio-examples/python/multi-antenna/multi_fft.py
@@ -49,9 +49,9 @@ class my_graph(stdgui2.std_top_block):
sw_decim = 1
self.u = usrp.source_c(0, options.decim, fpga_filename="std_4rx_0tx.rbf")
- if self.u.nddc() < nchan:
+ if self.u.nddcs() < nchan:
sys.stderr.write('This code requires an FPGA build with %d DDCs. This FPGA has only %d.\n' % (
- nchan, self.u.nddc()))
+ nchan, self.u.nddcs()))
raise SystemExit
if not self.u.set_nchannels(nchan):
@@ -62,11 +62,11 @@ class my_graph(stdgui2.std_top_block):
print "USB data rate = %s" % (eng_notation.num_to_str(input_rate),)
print "Scope data rate = %s" % (eng_notation.num_to_str(input_rate/sw_decim),)
- self.subdev = self.u.db[0] + self.u.db[1]
+ self.subdev = self.u.db(0) + self.u.db(1)
if (len (self.subdev) != 4 or
- self.u.db[0][0].dbid() != usrp_dbid.BASIC_RX or
- self.u.db[1][0].dbid() != usrp_dbid.BASIC_RX):
+ self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX or
+ self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX):
sys.stderr.write('This code requires a Basic Rx board on Sides A & B\n')
sys.exit(1)
diff --git a/gnuradio-examples/python/multi-antenna/multi_file.py b/gnuradio-examples/python/multi-antenna/multi_file.py
index f887b9cf6c..6f09546eaf 100755
--- a/gnuradio-examples/python/multi-antenna/multi_file.py
+++ b/gnuradio-examples/python/multi-antenna/multi_file.py
@@ -54,9 +54,9 @@ class my_graph(gr.top_block):
sw_decim = 1
self.u = usrp.source_c(0, options.decim, fpga_filename="std_4rx_0tx.rbf")
- if self.u.nddc() < nchan:
+ if self.u.nddcs() < nchan:
sys.stderr.write('This code requires an FPGA build with %d DDCs. This FPGA has only %d.\n' % (
- nchan, self.u.nddc()))
+ nchan, self.u.nddcs()))
raise SystemExit
if not self.u.set_nchannels(nchan):
@@ -68,11 +68,11 @@ class my_graph(gr.top_block):
sink_data_rate = input_rate/sw_decim
print "Scope data rate = %s" % (eng_notation.num_to_str(sink_data_rate),)
- self.subdev = self.u.db[0] + self.u.db[1]
+ self.subdev = self.u.db(0) + self.u.db(1)
if (len(self.subdev) != 4 or
- self.u.db[0][0].dbid() != usrp_dbid.BASIC_RX or
- self.u.db[1][0].dbid() != usrp_dbid.BASIC_RX):
+ self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX or
+ self.u.db(1, 0).dbid() != usrp_dbid.BASIC_RX):
sys.stderr.write('This code requires a Basic Rx board on Sides A & B\n')
sys.exit(1)
diff --git a/gnuradio-examples/python/multi-antenna/multi_scope.py b/gnuradio-examples/python/multi-antenna/multi_scope.py
index 8db183d6f8..5d6b1e920c 100755
--- a/gnuradio-examples/python/multi-antenna/multi_scope.py
+++ b/gnuradio-examples/python/multi-antenna/multi_scope.py
@@ -49,9 +49,9 @@ class my_top_block(stdgui2.std_top_block):
sw_decim = 1
self.u = usrp.source_c(0, options.decim, fpga_filename="std_4rx_0tx.rbf")
- if self.u.nddc() < nchan:
+ if self.u.nddcs() < nchan:
sys.stderr.write('This code requires an FPGA build with %d DDCs. This FPGA has only %d.\n' % (
- nchan, self.u.nddc()))
+ nchan, self.u.nddcs()))
raise SystemExit
if not self.u.set_nchannels(nchan):
@@ -62,11 +62,11 @@ class my_top_block(stdgui2.std_top_block):
print "USB data rate = %s" % (eng_notation.num_to_str(input_rate),)
print "Scope data rate = %s" % (eng_notation.num_to_str(input_rate/sw_decim),)
- self.subdev = self.u.db[0] + self.u.db[1]
+ self.subdev = self.u.db(0) + self.u.db(1)
if (len(self.subdev) != 4 or
- self.u.db[0][0].dbid() != usrp_dbid.BASIC_RX or
- self.u.db[1][0].dbid() != usrp_dbid.BASIC_RX):
+ self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX or
+ self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX):
sys.stderr.write('This code requires a Basic Rx board on Sides A & B\n')
sys.exit(1)
diff --git a/gnuradio-examples/python/multi_usrp/multi_usrp_oscope.py b/gnuradio-examples/python/multi_usrp/multi_usrp_oscope.py
index 3d426b45b4..512b125a47 100755
--- a/gnuradio-examples/python/multi_usrp/multi_usrp_oscope.py
+++ b/gnuradio-examples/python/multi_usrp/multi_usrp_oscope.py
@@ -42,9 +42,9 @@ def pick_subdevice(u):
If there's a daughterboard on B, select B.
Otherwise, select A.
"""
- if u.db[0][0].dbid() >= 0: # dbid is < 0 if there's no d'board or a problem
+ if u.db(0, 0).dbid() >= 0: # dbid is < 0 if there's no d'board or a problem
return (0, 0)
- if u.db[1][0].dbid() >= 0:
+ if u.db(0, 0).dbid() >= 0:
return (1, 0)
return (0, 0)
diff --git a/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py b/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py
index fb41ab1293..918ff08420 100755
--- a/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py
+++ b/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py
@@ -98,7 +98,7 @@ class my_top_block(gr.top_block):
the result of that operation and our target_frequency to
determine the value for the digital up converter.
"""
- r = self.u.tune(self.subdev._which, self.subdev, target_freq)
+ r = self.u.tune(self.subdev.which(), self.subdev, target_freq)
if r:
return True
diff --git a/gnuradio-examples/python/ofdm/tunnel.py b/gnuradio-examples/python/ofdm/tunnel.py
index 74f0f04d78..7e75c3ee86 100755
--- a/gnuradio-examples/python/ofdm/tunnel.py
+++ b/gnuradio-examples/python/ofdm/tunnel.py
@@ -182,8 +182,8 @@ class usrp_graph(gr.top_block):
the result of that operation and our target_frequency to
determine the value for the digital up converter.
"""
- r_snk = self.u_snk.tune(self.subdev._which, self.subdev, target_freq)
- r_src = self.u_src.tune(self.subdev._which, self.subdev, target_freq)
+ r_snk = self.u_snk.tune(self.subdev.which(), self.subdev, target_freq)
+ r_src = self.u_src.tune(self.subdev.which(), self.subdev, target_freq)
if r_snk and r_src:
return True
diff --git a/gnuradio-examples/python/usrp/fm_tx4.py b/gnuradio-examples/python/usrp/fm_tx4.py
index a71eeaa5aa..a51668dde8 100755
--- a/gnuradio-examples/python/usrp/fm_tx4.py
+++ b/gnuradio-examples/python/usrp/fm_tx4.py
@@ -43,7 +43,7 @@ import math
import sys
from gnuradio.wxgui import stdgui2, fftsink2
-from gnuradio import tx_debug_gui
+#from gnuradio import tx_debug_gui
import wx
@@ -84,8 +84,8 @@ class fm_tx_block(stdgui2.std_top_block):
help="set Tx frequency to FREQ [required]", metavar="FREQ")
parser.add_option("-n", "--nchannels", type="int", default=4,
help="number of Tx channels [1,4]")
- parser.add_option("","--debug", action="store_true", default=False,
- help="Launch Tx debugger")
+ #parser.add_option("","--debug", action="store_true", default=False,
+ # help="Launch Tx debugger")
(options, args) = parser.parse_args ()
if len(args) != 0:
@@ -158,9 +158,9 @@ class fm_tx_block(stdgui2.std_top_block):
vbox.Add (post_mod.win, 1, wx.EXPAND)
- if options.debug:
- self.debugger = tx_debug_gui.tx_debug_gui(self.subdev)
- self.debugger.Show(True)
+ #if options.debug:
+ # self.debugger = tx_debug_gui.tx_debug_gui(self.subdev)
+ # self.debugger.Show(True)
def set_freq(self, target_freq):
@@ -177,7 +177,7 @@ class fm_tx_block(stdgui2.std_top_block):
any residual_freq to the s/w freq translater.
"""
- r = self.u.tune(self.subdev._which, self.subdev, target_freq)
+ r = self.u.tune(self.subdev.which(), self.subdev, target_freq)
if r:
print "r.baseband_freq =", eng_notation.num_to_str(r.baseband_freq)
print "r.dxc_freq =", eng_notation.num_to_str(r.dxc_freq)
diff --git a/gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py b/gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py
index 499c7230be..15fdf2831c 100755
--- a/gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py
+++ b/gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py
@@ -112,7 +112,7 @@ class my_top_block(gr.top_block):
self.usrp_rate = self.dac_rate / self.usrp_interp # 320 kS/s
# we're using both daughterboard slots, thus subdev is a 2-tuple
- self.subdev = (self.u.db[0][0], self.u.db[1][0])
+ self.subdev = (self.u.db(0, 0), self.u.db(1, 0))
print "Using TX d'board %s" % (self.subdev[0].side_and_name(),)
print "Using TX d'board %s" % (self.subdev[1].side_and_name(),)
@@ -161,7 +161,7 @@ class my_top_block(gr.top_block):
"""
print "Tuning side %s to %sHz" % (("A", "B")[side], num_to_str(target_freq))
- r = self.u.tune(self.subdev[side]._which, self.subdev[side], target_freq)
+ r = self.u.tune(self.subdev[side].which(), self.subdev[side], target_freq)
if r:
print " r.baseband_freq =", num_to_str(r.baseband_freq)
print " r.dxc_freq =", num_to_str(r.dxc_freq)
diff --git a/gnuradio-examples/python/usrp/usrp_nbfm_ptt.py b/gnuradio-examples/python/usrp/usrp_nbfm_ptt.py
index 35f015215b..3ce1e0c49f 100755
--- a/gnuradio-examples/python/usrp/usrp_nbfm_ptt.py
+++ b/gnuradio-examples/python/usrp/usrp_nbfm_ptt.py
@@ -337,7 +337,7 @@ class transmit_path(gr.hier_block2):
determine the value for the digital up converter. Finally, we feed
any residual_freq to the s/w freq translater.
"""
- r = self.u.tune(self.subdev._which, self.subdev, target_freq)
+ r = self.u.tune(self.subdev.which(), self.subdev, target_freq)
if r:
# Use residual_freq in s/w freq translator
return True
diff --git a/gr-usrp/Makefile.am b/gr-usrp/Makefile.am
index 8980c5178b..136ce15799 100644
--- a/gr-usrp/Makefile.am
+++ b/gr-usrp/Makefile.am
@@ -21,5 +21,11 @@
include $(top_srcdir)/Makefile.common
-EXTRA_DIST = README_MULTI_USRP.txt
-SUBDIRS = src
+EXTRA_DIST = \
+ README_MULTI_USRP.txt \
+ gnuradio-usrp.pc.in
+
+SUBDIRS = src apps
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = gnuradio-usrp.pc
diff --git a/gr-usrp/apps/Makefile.am b/gr-usrp/apps/Makefile.am
new file mode 100644
index 0000000000..e1ac1b8553
--- /dev/null
+++ b/gr-usrp/apps/Makefile.am
@@ -0,0 +1,57 @@
+#
+# Copyright 2008 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+# For compiling within the GNU Radio build tree
+AM_CPPFLAGS=$(STD_DEFINES_AND_INCLUDES) \
+ -I$(top_srcdir)/gr-usrp/src \
+ -I$(top_srcdir)/usrp/host/lib/legacy \
+ -I$(top_srcdir)/usrp/firmware/include \
+ $(WITH_INCLUDES)
+
+GR_USRP_LA=$(top_builddir)/gr-usrp/src/libgnuradio-usrp.la
+
+# For compiling outside the tree, these will get fished out by pkgconfig
+
+noinst_PROGRAMS = \
+ usrp_rx_cfile \
+ usrp_siggen
+
+noinst_HEADERS = \
+ usrp_rx_cfile.h \
+ usrp_siggen.h
+
+usrp_rx_cfile_SOURCES = \
+ usrp_rx_cfile.cc
+
+usrp_rx_cfile_LDADD = \
+ $(BOOST_PROGRAM_OPTIONS_LIB) \
+ $(GR_USRP_LA)
+
+usrp_siggen_SOURCES = \
+ usrp_siggen.cc
+
+usrp_siggen_LDADD = \
+ $(BOOST_PROGRAM_OPTIONS_LIB) \
+ $(GR_USRP_LA)
+
+MOSTLYCLEANFILES = *~
diff --git a/gr-usrp/apps/usrp_rx_cfile.cc b/gr-usrp/apps/usrp_rx_cfile.cc
new file mode 100644
index 0000000000..c41a8deb41
--- /dev/null
+++ b/gr-usrp/apps/usrp_rx_cfile.cc
@@ -0,0 +1,245 @@
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <usrp_rx_cfile.h>
+#include <gr_io_signature.h>
+#include <gr_head.h>
+#include <stdexcept>
+#include <iostream>
+#include <boost/program_options.hpp>
+
+namespace po = boost::program_options;
+
+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;
+}
+
+
+// Shared pointer constructor
+usrp_rx_cfile_sptr make_usrp_rx_cfile(int which, usrp_subdev_spec spec,
+ int decim, double freq, float gain,
+ bool width8, bool nohb,
+ bool output_shorts, int nsamples,
+ const std::string &filename)
+{
+ return gnuradio::get_initial_sptr(new usrp_rx_cfile(which, spec,
+ decim, freq, gain,
+ width8, nohb,
+ output_shorts,
+ nsamples,
+ filename));
+}
+
+// Hierarchical block constructor, with no inputs or outputs
+usrp_rx_cfile::usrp_rx_cfile(int which, usrp_subdev_spec spec,
+ int decim, double freq, float gain,
+ bool width8, bool nohb,
+ bool output_shorts, int nsamples,
+ const std::string &filename) :
+ gr_top_block("usrp_rx_cfile"),
+ d_which(which), d_spec(spec), d_decim(decim), d_freq(freq),
+ d_gain(gain), d_width8(width8), d_nohb(nohb), d_nsamples(nsamples),
+ d_filename(filename)
+{
+ usrp_source_c_sptr usrp;
+
+ if(d_nohb || (d_decim<8)) {
+ // Min decimation of this firmware is 4.
+ // contains 4 Rx paths without halfbands and 0 tx paths.
+ std::string fpga_filename="std_4rx_0tx.rbf";
+
+ // use default values and add fpga_filename
+ usrp = usrp_make_source_c(d_which, d_decim,
+ 1, -1, 0, 0, 0,
+ fpga_filename.c_str());
+ }
+ else {
+ // standard fpga firmware "std_2rxhb_2tx.rbf" contains
+ // 2 Rx paths with halfband filters and 2 tx paths
+ //(the default) min decimation 8
+ usrp = usrp_make_source_c(d_which, d_decim);
+ }
+
+ if(d_width8) {
+ int sample_width = 8;
+ int sample_shift = 8;
+ int format = usrp->make_format(sample_width, sample_shift);
+ int r = usrp->set_format(format);
+ printf("width8: format=%d r=%d\n", format, r);
+ }
+
+
+ /* Get subdevice and process it */
+ db_base_sptr subdev = usrp->selected_subdev(d_spec);
+ printf("\nSubdevice name is %s\n", subdev->side_and_name().c_str());
+ printf("Subdevice freq range: (%g, %g)\n",
+ subdev->freq_min(), subdev->freq_max());
+
+ unsigned int mux = usrp->determine_rx_mux_value(d_spec);
+ printf("mux: %#08x\n", mux);
+ usrp->set_mux(mux);
+
+ float gain_min = subdev->gain_min();
+ float gain_max = subdev->gain_max();
+ if(d_gain == -1) {
+ d_gain = (gain_min + gain_max)/2.0;
+ }
+ printf("gain: %g\n", d_gain);
+ subdev->set_gain(d_gain);
+
+
+ /* Set the USRP/dboard frequency */
+ usrp_tune_result r;
+ bool ok = usrp->tune(subdev->which(), subdev, freq, &r);
+
+ if(!ok) {
+ throw std::runtime_error("Could not set frequency.");
+ }
+
+ /* The rest */
+ d_dst = gr_make_file_sink(sizeof(gr_complex), d_filename.c_str());
+
+ if(d_nsamples == -1) {
+ connect(usrp, 0, d_dst, 0);
+ }
+ else {
+ d_head = gr_make_head(sizeof(gr_complex), d_nsamples*2);
+ connect(usrp, 0, d_head, 0);
+ connect(d_head, 0, d_dst, 0);
+ }
+}
+
+
+int main(int argc, char *argv[])
+{
+ int which = 0; // specify which USRP board
+ usrp_subdev_spec spec(0,0); // specify the d'board side
+ int decim = 16; // set the decimation rate
+ double freq = 0; // set the frequency
+ float gain = -1; // set the gain; -1 will set the mid-point gain
+ int nsamples = -1; // set the number of samples to collect; -1 will continue
+ bool width8 = false; // use 8-bit samples across USB
+ bool nohb = false; // don't use halfband filter in USRP
+ bool output_shorts = false; // use shorts
+ std::string filename = "received.dat";
+
+ po::options_description cmdconfig("Program options: usrp_text_rx [options] filename");
+ cmdconfig.add_options()
+ ("help,h", "produce help message")
+ ("which,W", po::value<int>(&which), "select which USRP board")
+ ("rx-subdev-spec,R", po::value<std::string>(), "select USRP Rx side A or B (default=A)")
+ ("decim,d", po::value<int>(&decim), "set fgpa decimation rate to DECIM")
+ ("freq,f", po::value<double>(), "set frequency to FREQ")
+ ("gain,g", po::value<float>(), "set gain in dB (default is midpoint)")
+ ("width-8,8", "Enable 8-bit samples across USB")
+ ("no-hb", "don't use halfband filter in usrp")
+ //("output-shorts,s", "output interleaved shorts in stead of complex floats")
+ ("nsamples,N", po::value<int>(&nsamples), "number of samples to collect")
+ ;
+
+ po::options_description fileconfig("Input file options");
+ fileconfig.add_options()
+ ("filename", po::value<std::string>(), "input file")
+ ;
+
+ po::positional_options_description inputfile;
+ inputfile.add("filename", -1);
+
+ po::options_description config;
+ config.add(cmdconfig).add(fileconfig);
+
+ po::variables_map vm;
+ po::store(po::command_line_parser(argc, argv).
+ options(config).positional(inputfile).run(), vm);
+ po::notify(vm);
+
+ if (vm.count("help")) {
+ std::cout << cmdconfig << "\n";
+ return 1;
+ }
+
+ if(vm.count("filename")) {
+ filename = vm["filename"].as<std::string>();
+ }
+
+ if(vm.count("freq")) {
+ freq = vm["freq"].as<double>();
+ }
+ else {
+ fprintf(stderr, "You must specify a frequency.\n");
+ return -1;
+ }
+
+ if(vm.count("rx-subdev-spec")) {
+ std::string s = vm["rx-subdev-spec"].as<std::string>();
+ spec = str_to_subdev(s);
+ }
+
+ if(vm.count("width-8")) {
+ width8 = true;
+ }
+ if(vm.count("nohb")) {
+ nohb = true;
+ }
+ if(vm.count("output-shorts")) {
+ output_shorts = true;
+ }
+
+ std::cout << "which: " << which << std::endl;
+ std::cout << "decim: " << decim << std::endl;
+ std::cout << "freq: " << freq << std::endl;
+ std::cout << "gain: " << gain << std::endl;
+ std::cout << "width-8 " << (width8 ? "Yes" : "No") << std::endl;
+ std::cout << "no-hb " << (nohb ? "Yes" : "no") << std::endl;
+ std::cout << "shorts: " << (output_shorts ? "Yes" : "No") << std::endl;
+ std::cout << "samples: " << nsamples << std::endl;
+
+ usrp_rx_cfile_sptr top_block = make_usrp_rx_cfile(which, spec, decim, freq,
+ gain, width8, nohb,
+ output_shorts, nsamples,
+ filename);
+ top_block->run();
+
+ return 0;
+}
diff --git a/gr-usrp/apps/usrp_rx_cfile.h b/gr-usrp/apps/usrp_rx_cfile.h
new file mode 100644
index 0000000000..3a42972caf
--- /dev/null
+++ b/gr-usrp/apps/usrp_rx_cfile.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_top_block.h>
+#include <usrp_source_base.h>
+#include <usrp_source_c.h>
+#include <usrp_source_s.h>
+#include <gr_file_sink.h>
+
+class usrp_rx_cfile;
+typedef boost::shared_ptr<usrp_rx_cfile> usrp_rx_cfile_sptr;
+usrp_rx_cfile_sptr make_usrp_rx_cfile(int which, usrp_subdev_spec spec,
+ int decim, double freq, float gain,
+ bool width8, bool nohb,
+ bool output_shorts, int nsamples,
+ const std::string &filename);
+
+class usrp_rx_cfile : public gr_top_block
+{
+private:
+ usrp_rx_cfile(int which, usrp_subdev_spec spec,
+ int decim, double freq, float gain,
+ bool width8, bool nohb,
+ bool output_shorts, int nsamples,
+ const std::string &filename);
+ friend usrp_rx_cfile_sptr make_usrp_rx_cfile(int which, usrp_subdev_spec spec,
+ int decim, double freq, float gain,
+ bool width8, bool nohb,
+ bool output_shorts, int nsamples,
+ const std::string &filename);
+
+ int d_which;
+ usrp_subdev_spec d_spec;
+ int d_decim;
+ double d_freq;
+ float d_gain;
+ bool d_width8, d_nohb;
+ int d_nsamples;
+ std::string d_filename;
+
+ public:
+ gr_block_sptr d_head;
+ gr_block_sptr d_dst;
+};
diff --git a/gr-usrp/apps/usrp_siggen.cc b/gr-usrp/apps/usrp_siggen.cc
new file mode 100644
index 0000000000..b88e811fe5
--- /dev/null
+++ b/gr-usrp/apps/usrp_siggen.cc
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <usrp_siggen.h>
+#include <gr_io_signature.h>
+#include <gr_head.h>
+#include <gr_noise_type.h>
+#include <stdexcept>
+#include <iostream>
+#include <boost/program_options.hpp>
+
+namespace po = boost::program_options;
+
+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;
+}
+
+// Shared pointer constructor
+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)
+{
+ return gnuradio::get_initial_sptr(new usrp_siggen(which, spec,
+ rf_freq, interp, wfreq,
+ waveform, amp, gain,
+ offset));
+}
+
+// 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")
+{
+ usrp_sink_c_sptr usrp = usrp_make_sink_c(which, interp);
+
+ db_base_sptr subdev = usrp->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());
+
+ unsigned int mux = usrp->determine_tx_mux_value(spec);
+ printf("mux: %#08x\n", mux);
+ usrp->set_mux(mux);
+
+ if(gain == -1) {
+ gain = subdev->gain_max();
+ }
+ subdev->set_gain(gain);
+
+ float input_rate = usrp->dac_freq() / usrp->interp_rate();
+ printf("baseband rate: %g\n", input_rate);
+
+ usrp_tune_result r;
+ double target_freq = rf_freq;
+ bool ok = usrp->tune(subdev->which(), subdev, target_freq, &r);
+
+ if(!ok) {
+ throw std::runtime_error("Could not set frequency.");
+ }
+
+ 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);
+
+ /* Set up the signal source */
+ siggen = gr_make_sig_source_c(input_rate, GR_SIN_WAVE, wfreq, amp);
+ noisegen = gr_make_noise_source_c (GR_UNIFORM, amp);
+ if(waveform == GR_SIN_WAVE || waveform == GR_CONST_WAVE) {
+ source = siggen;
+ }
+ else if(waveform == GR_UNIFORM || waveform == GR_GAUSSIAN) {
+ source = noisegen;
+ }
+ else {
+ throw std::range_error("Unknown waveform type.\n");
+ }
+
+ siggen->set_waveform((gr_waveform_t)waveform);
+
+ connect(source, 0, usrp, 0);
+}
+
+int main(int argc, char *argv[])
+{
+ int which = 0; // specify which USRP board
+ usrp_subdev_spec spec(0,0); // specify the d'board side
+ int interp = 128; // set the interpolation rate
+ double rf_freq = 0; // set the frequency
+ double wfreq = 100e3; // set the waveform frequency
+ float amp = 5; // set the amplitude of the output
+ float gain = -1; // set the d'board PGA gain
+ float offset = 0; // set waveform offset
+ int waveform;
+
+ 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")
+
+ ("sine", "generate a complex sinusoid [default]")
+ ("const", "generate a constant output")
+ ("gaussian", "generate Gaussian random output")
+ ("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")
+ ("gain,g", po::value<float>(&gain), "set output gain to GAIN")
+ ("offset,o", po::value<float>(&offset), "set waveform offset to OFFSET")
+ ;
+
+ 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("rf-freq")) {
+ rf_freq = vm["rf-freq"].as<double>();
+ }
+ else {
+ fprintf(stderr, "You must specify a frequency.\n");
+ return -1;
+ }
+
+ if(vm.count("tx-subdev-spec")) {
+ std::string s = vm["tx-subdev-spec"].as<std::string>();
+ spec = str_to_subdev(s);
+ }
+
+ if(vm.count("sine")) {
+ waveform = GR_SIN_WAVE;
+ }
+ else if(vm.count("const")) {
+ waveform = GR_CONST_WAVE;
+ }
+ else if(vm.count("gaussian")) {
+ waveform = GR_GAUSSIAN;
+ }
+ else if(vm.count("uniform")) {
+ waveform = GR_UNIFORM;
+ }
+ else {
+ 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);
+
+ usrp_siggen_sptr top_block = make_usrp_siggen(which, spec, rf_freq,
+ interp, wfreq, waveform,
+ amp, gain, offset);
+
+ top_block->run();
+
+ return 0;
+}
diff --git a/gr-usrp/apps/usrp_siggen.h b/gr-usrp/apps/usrp_siggen.h
new file mode 100644
index 0000000000..009a2447e5
--- /dev/null
+++ b/gr-usrp/apps/usrp_siggen.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_top_block.h>
+#include <usrp_sink_c.h>
+#include <gr_sig_source_c.h>
+#include <gr_noise_source_c.h>
+
+usrp_subdev_spec str_to_subdev(std::string spec_str);
+
+class usrp_siggen;
+typedef boost::shared_ptr<usrp_siggen> usrp_siggen_sptr;
+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);
+
+class usrp_siggen : public gr_top_block
+{
+private:
+ usrp_siggen(int which, usrp_subdev_spec spec,
+ double rf_freq, int interp, double wfreq,
+ int waveform, float amp, float gain,
+ float offset);
+ 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);
+
+ public:
+ gr_block_sptr source;
+ gr_sig_source_c_sptr siggen;
+ gr_noise_source_c_sptr noisegen;
+};
diff --git a/gr-usrp/gnuradio-usrp.pc.in b/gr-usrp/gnuradio-usrp.pc.in
new file mode 100644
index 0000000000..6c1d75d439
--- /dev/null
+++ b/gr-usrp/gnuradio-usrp.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/gnuradio
+
+Name: gnuradio-usrp
+Description: GNU Software Radio support for Universal Software Radio Peripheral
+Requires: gnuradio-core usrp
+Version: @VERSION@
+Libs: -L${libdir} -lgnuradio-usrp
+Cflags: -I${includedir}
diff --git a/gr-usrp/src/Makefile.am b/gr-usrp/src/Makefile.am
index 03ca34db00..122f977be6 100644
--- a/gr-usrp/src/Makefile.am
+++ b/gr-usrp/src/Makefile.am
@@ -21,107 +21,116 @@
include $(top_srcdir)/Makefile.common
+# ----------------------------------------------------------------
+# The straight C++ library
+
+AM_CPPFLAGS = \
+ $(STD_DEFINES_AND_INCLUDES) \
+ $(PYTHON_CPPFLAGS) \
+ $(USRP_INCLUDES) \
+ $(WITH_INCLUDES)
+
+lib_LTLIBRARIES = \
+ libgnuradio-usrp.la
+
+libgnuradio_usrp_la_SOURCES = \
+ usrp_base.cc \
+ usrp_sink_base.cc \
+ usrp_sink_c.cc \
+ usrp_sink_s.cc \
+ usrp_source_base.cc \
+ usrp_source_c.cc \
+ usrp_source_s.cc
+
+libgnuradio_usrp_la_LIBADD = \
+ $(GNURADIO_CORE_LA) \
+ $(USRP_LA)
+
+libgnuradio_usrp_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
+
+grinclude_HEADERS = \
+ usrp_base.h \
+ usrp_sink_base.h \
+ usrp_sink_c.h \
+ usrp_sink_s.h \
+ usrp_source_base.h \
+ usrp_source_c.h \
+ usrp_source_s.h
+
+# ----------------------------------------------------------------
+# The SWIG library and Python modules
+#
# Install this stuff so that it ends up as the gnuradio.usrp module
# This usually ends up at:
-# ${prefix}/lib/python${python_version}/site-packages/gnuradio
-
-ourpythondir = $(grpythondir)
-ourlibdir = $(grpyexecdir)
-
-EXTRA_DIST = run_tests.in
-TESTS = run_tests
-
-LOCAL_IFILES = \
- $(top_srcdir)/gr-usrp/src/usrp1.i
-
-NON_LOCAL_IFILES = $(GNURADIO_I)
-
-ALL_IFILES = \
- $(LOCAL_IFILES) \
+# ${prefix}/lib/python${python_version}/site-packages/gnuradio/usrp
+
+ourpythondir = $(grpythondir)/usrp
+ourlibdir = $(grpyexecdir)/usrp
+
+BUILT_SOURCES = \
+ usrp_swig.cc \
+ usrp_swig.py
+
+LOCAL_IFILES = \
+ $(srcdir)/usrp.i \
+ $(srcdir)/usrp_base.i \
+ $(srcdir)/usrp_source_base.i \
+ $(srcdir)/usrp_source_c.i \
+ $(srcdir)/usrp_source_s.i \
+ $(srcdir)/usrp_sink_base.i \
+ $(srcdir)/usrp_sink_c.i \
+ $(srcdir)/usrp_sink_s.i \
+ $(srcdir)/usrp_standard.i
+
+NON_LOCAL_IFILES = \
+ $(GNURADIO_I)
+
+ALL_IFILES = \
+ $(LOCAL_IFILES) \
$(NON_LOCAL_IFILES)
-BUILT_SOURCES = \
- usrp1.cc \
- usrp1.py
-
-ourpython_PYTHON = \
- db_base.py \
- db_basic.py \
- db_dbs_rx.py \
- db_flexrf.py \
- db_flexrf_mimo.py \
- db_wbx.py \
- db_xcvr2450.py \
- db_instantiator.py \
- db_tv_rx.py \
- db_dtt754.py \
- db_dtt768.py \
- flexrf_debug_gui.py \
- tx_debug_gui.py \
- usrp.py \
- usrp1.py \
- usrp_multi.py
-
-
-AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) \
- $(PYTHON_CPPFLAGS) \
- $(USRP_INCLUDES) \
- $(WITH_INCLUDES)
-
-SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) \
- $(STD_DEFINES_AND_INCLUDES) \
- $(USRP_INCLUDES) \
- $(WITH_INCLUDES) \
- $(WITH_SWIG_INCLUDES)
-
-grinclude_HEADERS = \
- usrp1_sink_base.h \
- usrp1_sink_c.h \
- usrp1_sink_s.h \
- usrp1_source_base.h \
- usrp1_source_c.h \
- usrp1_source_s.h
-
-swiginclude_HEADERS = \
- $(LOCAL_IFILES)
-
+ourlib_LTLIBRARIES = \
+ _usrp_swig.la
-ourlib_LTLIBRARIES = _usrp1.la
+ourlib_PYTHON = \
+ __init__.py \
+ usrp_swig.py
+_usrp_swig_la_SOURCES = \
+ usrp_swig.cc
-_usrp1_la_SOURCES = \
- usrp1.cc \
- usrp1_sink_base.cc \
- usrp1_sink_c.cc \
- usrp1_sink_s.cc \
- usrp1_source_base.cc \
- usrp1_source_c.cc \
- usrp1_source_s.cc
+_usrp_swig_la_LIBADD = \
+ $(PYTHON_LDFLAGS) \
+ libgnuradio-usrp.la
+_usrp_swig_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
-_usrp1_la_LIBADD = \
- $(PYTHON_LDFLAGS) \
- $(GNURADIO_CORE_LA) \
- $(USRP_LA) \
- -lstdc++
+_usrp_swig_la_CXXFLAGS = @swig_CXXFLAGS@
+SWIGPYTHONARGS = \
+ $(SWIGPYTHONFLAGS) \
+ $(STD_DEFINES_AND_INCLUDES) \
+ $(USRP_INCLUDES) \
+ $(WITH_INCLUDES) \
+ $(WITH_SWIG_INCLUDES)
-_usrp1_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+usrp_swig.cc usrp_swig.py: $(ALL_IFILES)
+ $(SWIG) $(SWIGPYTHONARGS) -module usrp_swig -o usrp_swig.cc $(srcdir)/usrp.i
-_usrp1_la_CXXFLAGS = @swig_CXXFLAGS@
-
-usrp1.cc usrp1.py: usrp1.i $(NON_LOCAL_IFILES) $(LOCAL_IFILES)
- $(SWIG) $(SWIGPYTHONARGS) -module usrp1 -o usrp1.cc $(LOCAL_IFILES)
-
-
-noinst_PYTHON = \
+noinst_PYTHON = \
qa_usrp.py
-MOSTLYCLEANFILES = \
- $(BUILT_SOURCES) *~ *.pyc
-
+swiginclude_HEADERS = \
+ $(LOCAL_IFILES)
# Don't distribute output of swig
dist-hook:
@for file in $(BUILT_SOURCES); do echo $(RM) $(distdir)/$$file; done
@for file in $(BUILT_SOURCES); do $(RM) $(distdir)/$$file; done
+
+# ----------------------------------------------------------------
+# Misc. build/installation activities
+
+MOSTLYCLEANFILES = $(BUILT_SOURCES) *~ *.pyc
+EXTRA_DIST = run_tests.in
+TESTS = run_tests
diff --git a/gr-usrp/src/db_instantiator.py b/gr-usrp/src/__init__.py
index b76cdeee3e..c81b2f2b0b 100644
--- a/gr-usrp/src/db_instantiator.py
+++ b/gr-usrp/src/__init__.py
@@ -1,5 +1,5 @@
#
-# Copyright 2005 Free Software Foundation, Inc.
+# Copyright 2008 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -19,13 +19,10 @@
# Boston, MA 02110-1301, USA.
#
-_instantiator_map = {}
+# The presence of this file turns this directory into a Python package
-def add(dbid, instantiator):
- _instantiator_map[dbid] = instantiator
+# Add SWIG generated code to this namespace
+from usrp_swig import *
+
+# Add other content from pure-Python modules here
-def instantiate(usrp, which):
- dbid = usrp.daughterboard_id(which)
- if _instantiator_map.has_key(dbid):
- return _instantiator_map[dbid](usrp, which)
- raise ValueError, "No class defined to handle daughterboard (dbid = %d)" % (dbid,)
diff --git a/gr-usrp/src/db_base.py b/gr-usrp/src/db_base.py
deleted file mode 100644
index 947f815592..0000000000
--- a/gr-usrp/src/db_base.py
+++ /dev/null
@@ -1,264 +0,0 @@
-#
-# Copyright 2005,2006,2007 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 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.
-#
-
-import weakref
-from usrpm import usrp_prims
-from usrpm.usrp_fpga_regs import *
-
-class db_base(object):
- """
- Abstract base class for all daughterboards.
-
- This defines the required operations and interfaces for all d'boards.
- """
- def __init__(self, usrp, which):
- """
- Initialize daughterboard interface.
-
- @param usrp: instance of usrp
- @param which: which daughterboard side: A = 0, B = 1
- @type which: int
- """
-
- if not (which in (0, 1)):
- raise ValueError, "Invalid value of which: %s" % (which,)
-
- self._u = weakref.proxy(usrp)
-
- self._which = which
- if hasattr(self._u, 'tx_freq'): # is this a tx or rx daughterboard?
- self._tx = True
- self._slot = which * 2
- else:
- self._tx = False
- self._slot = which * 2 + 1
-
- self._refclk_reg = (FR_TX_A_REFCLK,FR_RX_A_REFCLK,FR_TX_B_REFCLK,FR_RX_B_REFCLK)[self._slot]
-
- def dbid(self):
- return self._u.daughterboard_id(self._which)
-
- def name(self):
- return usrp_prims.usrp_dbid_to_string(self.dbid())
-
- def side_and_name(self):
- return "AB"[self._which] + ': ' + self.name()
-
- # Function to bypass ADC buffers. Any board which is DC-coupled should bypass the buffers
- def bypass_adc_buffers(self,bypass):
- if self._tx:
- raise RuntimeError, "TX Board has no adc buffers"
- if self._which==0:
- self._u.set_adc_buffer_bypass(0, bypass)
- self._u.set_adc_buffer_bypass(1, bypass)
- else:
- self._u.set_adc_buffer_bypass(2, bypass)
- self._u.set_adc_buffer_bypass(3, bypass)
-
- # ------------------------------------------------------------------------
- # Reference Clock section
-
- # Control whether a reference clock is sent to the daughterboards,
- # and what frequency
- #
- # Bit 7 -- 1 turns on refclk, 0 allows IO use
- # Bits 6:0 Divider value
- #
-
- def _refclk_freq(self):
- return self._u.fpga_master_clock_freq()/self._refclk_divisor()
-
- def _enable_refclk(self,enable):
- CLOCK_OUT = 1 # Clock is on lowest bit
- REFCLK_ENABLE = 0x80
- REFCLK_DIVISOR_MASK = 0x7f
- if enable:
- self._u._write_oe(self._which, CLOCK_OUT, CLOCK_OUT) # output enable
- self._u._write_fpga_reg(self._refclk_reg,
- ((self._refclk_divisor() & REFCLK_DIVISOR_MASK)
- | REFCLK_ENABLE))
- else:
- self._u._write_fpga_reg(self._refclk_reg, 0)
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- raise NotImplementedError
-
- # ------------------------------------------------------------------------
- # Automatic Transmit/Receive switching
- #
- # The presence or absence of data in the FPGA transmit fifo
- # selects between two sets of values for each of the 4 banks of
- # daughterboard i/o pins.
- #
- # Each daughterboard slot has 3 16-bit registers associated with it:
- # FR_ATR_MASK_*, FR_ATR_TXVAL_* and FR_ATR_RXVAL_*
- #
- # FR_ATR_MASK_{0,1,2,3}:
- #
- # These registers determine which of the daugherboard i/o pins are
- # affected by ATR switching. If a bit in the mask is set, the
- # corresponding i/o bit is controlled by ATR, else it's output
- # value comes from the normal i/o pin output register:
- # FR_IO_{0,1,2,3}.
- #
- # FR_ATR_TXVAL_{0,1,2,3}:
- # FR_ATR_RXVAL_{0,1,2,3}:
- #
- # If the Tx fifo contains data, then the bits from TXVAL that are
- # selected by MASK are output. Otherwise, the bits from RXVAL that
- # are selected by MASK are output.
-
- def set_atr_mask(self, v):
- """
- Set Auto T/R mask.
- """
- return self._u._write_fpga_reg(FR_ATR_MASK_0 + 3 * self._slot, v)
-
- def set_atr_txval(self, v):
- """
- Set Auto T/R register value to be used when transmitting.
- """
- return self._u._write_fpga_reg(FR_ATR_TXVAL_0 + 3 * self._slot, v)
-
- def set_atr_rxval(self, v):
- """
- Set Auto T/R register value to be used when receiving.
- """
- return self._u._write_fpga_reg(FR_ATR_RXVAL_0 + 3 * self._slot, v)
-
- def set_atr_tx_delay(self, v):
- """
- Set Auto T/R delay (in clock ticks) from when Tx fifo gets data to
- when T/R switches.
- """
- return self._u._write_fpga_reg(FR_ATR_TX_DELAY, v)
-
- def set_atr_rx_delay(self, v):
- """
- Set Auto T/R delay (in clock ticks) from when Tx fifo goes empty to
- when T/R switches.
- """
- return self._u._write_fpga_reg(FR_ATR_RX_DELAY, v)
-
- # derived classes should override the following methods
-
- def freq_range(self):
- """
- Return range of frequencies in Hz that can be tuned by this d'board.
-
- @returns (min_freq, max_freq, step_size)
- @rtype tuple
- """
- raise NotImplementedError
-
- def set_freq(self, target_freq):
- """
- Set the frequency.
-
- @param freq: target RF frequency in Hz
- @type freq: float
-
- @returns (ok, actual_baseband_freq) where:
- ok is True or False and indicates success or failure,
- actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
- """
- raise NotImplementedError
-
- def gain_range(self):
- """
- Return range of gain that can be set by this d'board.
-
- @returns (min_gain, max_gain, step_size)
- Where gains are expressed in decibels (your mileage may vary)
- """
- raise NotImplementedError
-
- def set_gain(self, gain):
- """
- Set the gain.
-
- @param gain: gain in decibels
- @returns True/False
- """
- raise NotImplementedError
-
- def is_quadrature(self):
- """
- Return True if this daughterboard does quadrature up or down conversion.
- That is, return True if this board requires both I & Q analog channels.
-
- This bit of info is useful when setting up the USRP Rx mux register.
- """
- raise NotImplementedError
-
- def i_and_q_swapped(self):
- """
- Return True if this is a quadrature device and (for RX) ADC 0 is Q
- or (for TX) DAC 0 is Q
- """
- return False
-
- def spectrum_inverted(self):
- """
- Return True if the dboard gives an inverted spectrum
- """
- return False
-
- def set_enable(self, on):
- """
- For tx daughterboards, this controls the transmitter enable.
- """
- pass
-
- def set_auto_tr(self,on):
- """
- Enable automatic Transmit/Receive switching (ATR).
-
- Should be overridden in subclasses that care. This will typically
- set the atr_mask, txval and rxval.
- """
- pass
-
- def set_lo_offset(self, offset):
- """
- Set how much LO is offset from requested frequency
-
- Should be overriden by daughterboards that care.
- """
- pass
-
- def lo_offset(self, offset):
- """
- Get how much LO is offset from requested frequency
-
- Should be overriden by daughterboards that care.
- """
- return 0.0
-
- def select_rx_antenna(self, which_antenna):
- """
- Specify which antenna port to use for reception.
- Should be overriden by daughterboards that care.
- """
- pass
diff --git a/gr-usrp/src/db_basic.py b/gr-usrp/src/db_basic.py
deleted file mode 100644
index c9947aa0b1..0000000000
--- a/gr-usrp/src/db_basic.py
+++ /dev/null
@@ -1,252 +0,0 @@
-#
-# Copyright 2005 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 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.
-#
-
-import sys
-from usrpm import usrp_dbid
-import db_base
-import db_instantiator
-
-class db_basic_tx(db_base.db_base):
- def __init__(self, usrp, which):
- """
- Handler for Basic Tx daughterboards.
-
- @param usrp: instance of usrp.source_c
- @param which: which side: 0 or 1 corresponding to TX_A or TX_B respectively
- """
- # sets _u and _which
- db_base.db_base.__init__(self, usrp, which)
-
- if 0: # Doing this would give us a different default than the historical values...
- g = self.gain_range() # initialize gain
- self.set_gain(float(g[0]+g[1]) / 2)
-
-
- def freq_range(self):
- """
- Return range of frequencies in Hz that can be tuned by this d'board.
-
- @returns (min_freq, max_freq, step_size)
- @rtype tuple
-
- We say we can do pretty much anything...
- """
- return (-90e9, 90e9, 1e-6)
-
- def set_freq(self, target_freq):
- """
- Set the frequency.
-
- @param freq: target RF frequency in Hz
- @type freq: float
-
- @returns (ok, actual_baseband_freq) where:
- ok is True or False and indicates success or failure,
- actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
- """
- return (True, 0)
-
- def gain_range(self):
- """
- Return range of gain that can be set by this d'board.
-
- @returns (min_gain, max_gain, step_size)
- Where gains are expressed in decibels (your mileage may vary)
- """
- return (self._u.pga_min(), self._u.pga_max(), self._u.pga_db_per_step())
-
- def set_gain(self, gain):
- """
- Set the gain.
-
- @param gain: gain in decibels
- @returns True/False
- """
- ok = self._u.set_pga(self._which * 2 + 0, gain)
- ok = ok and self._u.set_pga(self._which * 2 + 1, gain)
- return ok
-
- def is_quadrature(self):
- """
- Return True if this board requires both I & Q analog channels.
- """
- return True
-
-
-class db_basic_rx(db_base.db_base):
- def __init__(self, usrp, which, subdev):
- """
- Handler for Basic Rx daughterboards.
-
- @param usrp: instance of usrp.source_c
- @param which: which side: 0 or 1 corresponding to RX_A or RX_B respectively
- @param subdev: which analog i/o channel: 0 or 1
- @type subdev: int
- """
- # sets _u and _which
- db_base.db_base.__init__(self, usrp, which)
- self._subdev = subdev
-
- self.bypass_adc_buffers(True)
-
- if 0: # Doing this would give us a different default than the historical values...
- g = self.gain_range() # initialize gain
- self.set_gain(float(g[0]+g[1]) / 2)
-
-
- def freq_range(self):
- """
- Return range of frequencies in Hz that can be tuned by this d'board.
-
- @returns (min_freq, max_freq, step_size)
- @rtype tuple
-
- We say we can do pretty much anything...
- """
- return (0, 90e9, 1e-6)
-
- def set_freq(self, target_freq):
- """
- Set the frequency.
-
- @param freq: target RF frequency in Hz
- @type freq: float
-
- @returns (ok, actual_baseband_freq) where:
- ok is True or False and indicates success or failure,
- actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
- """
- return (True, 0)
-
-
- def gain_range(self):
- """
- Return range of gain that can be set by this d'board.
-
- @returns (min_gain, max_gain, step_size)
- Where gains are expressed in decibels (your mileage may vary)
- """
- return (self._u.pga_min(), self._u.pga_max(), self._u.pga_db_per_step())
-
- def set_gain(self, gain):
- """
- Set the gain.
-
- @param gain: gain in decibels
- @returns True/False
- """
- return self._u.set_pga(self._which * 2 + self._subdev, gain)
-
- def is_quadrature(self):
- """
- Return True if this board requires both I & Q analog channels.
-
- This bit of info is useful when setting up the USRP Rx mux register.
- """
- return False
-
-class db_lf_rx(db_basic_rx):
- def __init__(self, usrp, which, subdev):
- """
- Handler for Low Freq Rx daughterboards.
-
- @param usrp: instance of usrp.source_c
- @param which: which side: 0 or 1 corresponding to RX_A or RX_B respectively
- @param subdev: which analog i/o channel: 0 or 1
- @type subdev: int
- """
- # sets _u and _which
- db_basic_rx.__init__(self, usrp, which, subdev)
-
- def freq_range(self):
- """
- Return range of frequencies in Hz that can be tuned by this d'board.
-
- @returns (min_freq, max_freq, step_size)
- @rtype tuple
-
- We cover the first nyquist zone only
- """
- return (0, 32e6, 1e-6)
-
-class db_lf_tx(db_basic_tx):
- def __init__(self, usrp, which):
- """
- Handler for Low Freq Tx daughterboards.
-
- @param usrp: instance of usrp.source_c
- @param which: which side: 0 or 1 corresponding to RX_A or RX_B respectively
- """
- # sets _u and _which
- db_basic_tx.__init__(self, usrp, which)
-
- def freq_range(self):
- """
- Return range of frequencies in Hz that can be tuned by this d'board.
-
- @returns (min_freq, max_freq, step_size)
- @rtype tuple
-
- We cover the first nyquist zone only
- """
- return (-32e6, 32e6, 1e-6)
-
-
-# hook these daughterboard classes into the auto-instantiation framework
-
-def _basic_rx_instantiator(usrp, which):
- # two single channel subdevices
- return (db_basic_rx(usrp, which, 0), db_basic_rx(usrp, which, 1))
-
-def _lf_rx_instantiator(usrp, which):
- # two single channel subdevices
- return (db_lf_rx(usrp, which, 0), db_lf_rx(usrp, which, 1))
-
-def _basic_tx_instantiator(usrp, which):
- # one quadrature subdevice
- return (db_basic_tx(usrp, which),)
-
-def _lf_tx_instantiator(usrp, which):
- # one quadrature subdevice
- return (db_lf_tx(usrp, which),)
-
-def _no_db_instantiator(usrp, which):
- if hasattr(usrp, 'tx_freq'): # is this a tx or rx daughterboard?
- return (_basic_tx_instantiator(usrp, which))
- else:
- return (_basic_rx_instantiator(usrp, which))
-
-def _invalid_instantiator(usrp, which):
- if hasattr(usrp, 'tx_freq'): # is this a tx or rx daughterboard?
- sys.stderr.write('\n\aWarning: Treating daughterboard with invalid EEPROM contents as if it were a "Basic Tx."\n')
- sys.stderr.write('Warning: This is almost certainly wrong... Use appropriate burn-*-eeprom utility.\n\n')
- return _basic_tx_instantiator(usrp, which)
- else:
- sys.stderr.write('\n\aWarning: Treating daughterboard with invalid EEPROM contents as if it were a "Basic Rx."\n')
- sys.stderr.write('Warning: This is almost certainly wrong... Use appropriate burn-*-eeprom utility.\n\n')
- return _basic_rx_instantiator(usrp, which)
-
-db_instantiator.add(-1, _no_db_instantiator) # no daughterboard
-db_instantiator.add(-2, _invalid_instantiator) # invalid eeprom contents
-db_instantiator.add(usrp_dbid.BASIC_TX, _basic_tx_instantiator)
-db_instantiator.add(usrp_dbid.BASIC_RX, _basic_rx_instantiator)
-db_instantiator.add(usrp_dbid.LF_TX, _lf_tx_instantiator)
-db_instantiator.add(usrp_dbid.LF_RX, _lf_rx_instantiator)
diff --git a/gr-usrp/src/db_dbs_rx.py b/gr-usrp/src/db_dbs_rx.py
deleted file mode 100644
index 699753aa89..0000000000
--- a/gr-usrp/src/db_dbs_rx.py
+++ /dev/null
@@ -1,345 +0,0 @@
-#
-# Copyright 2005 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 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.
-#
-
-import math
-from usrpm import usrp_dbid
-import db_base
-import db_instantiator
-
-def int_seq_to_str (seq):
- """convert a sequence of integers into a string"""
- return ''.join (map (chr, seq))
-
-def str_to_int_seq (str):
- """convert a string to a list of integers"""
- return map (ord, str)
-
-class db_dbs_rx (db_base.db_base):
- def __init__ (self, usrp, which):
- """
- Control DBS receiver based USRP daughterboard.
-
- @param usrp: instance of usrp.source_c
- @param which: which side: 0 or 1 corresponding to RX_A or RX_B respectively
- @type which: int
- """
- # sets _u and _which
- db_base.db_base.__init__(self, usrp, which)
-
- self._u._write_oe(self._which,0x0001,0x0001)
- self.i2c_addr = (0x67, 0x65)[self._which]
- # set basic parameters
- # set default values
- self.n = 950
- self.div2 = 0
- self.osc = 5
- self.cp = 3
- self.r = 4
- self.r_int = 1
- self.fdac = 127
- self.m = 2
- self.dl = 0
- self.ade = 0
- self.adl = 0
- self.gc2 = 31
- self.diag = 0
-
- # FIXME this should be in the core dboard class
- self.refclk_divisor = 16
- self._enable_refclk(True)
-
- g = self.gain_range()
- self.set_gain(float(g[0]+g[1]) / 2)
- self.bypass_adc_buffers(True)
-
- def __del__(self):
- if self._u:
- self._enable_refclk(False)
-
- def _write_reg (self, regno, v):
- """regno is in [0,5], v is value to write to register"""
- assert (0 <= regno and regno <= 5)
- self._u.write_i2c (self.i2c_addr, int_seq_to_str ((regno, v)))
-
- def _write_regs (self, starting_regno, vals):
- """starting_regno is in [0,5],
- vals is a seq of integers to write to consecutive registers"""
- self._u.write_i2c (self.i2c_addr,
- int_seq_to_str ((starting_regno,) + tuple (vals)))
-
- def _read_status (self):
- """If successful, return list of two ints: [status_info, filter_DAC]"""
- s = self._u.read_i2c (self.i2c_addr, 2)
- if len (s) != 2:
- return None
- return str_to_int_seq (s)
-
- def _send_reg(self,regno):
- assert (0 <= regno and regno <= 5)
- if regno == 0:
- self._write_reg(0,(self.div2<<7) + (self.n>>8))
- if regno == 1:
- self._write_reg(1,self.n & 255)
- if regno == 2:
- self._write_reg(2,self.osc + (self.cp<<3) + (self.r_int<<5))
- if regno == 3:
- self._write_reg(3,self.fdac)
- if regno == 4:
- self._write_reg(4,self.m + (self.dl<<5) + (self.ade<<6) + (self.adl<<7))
- if regno == 5:
- self._write_reg(5,self.gc2 + (self.diag<<5))
-
- # BW setting
- def _set_m(self,m):
- assert m>0 and m<32
- self.m = m
- self._send_reg(4)
-
- def _set_fdac(self,fdac):
- assert fdac>=0 and fdac<128
- self.fdac = fdac
- self._send_reg(3)
-
- def set_bw (self, bw):
- #assert (bw>=4e6 and bw<=33e6)
- assert (bw>=1e6 and bw<=33e6)
- if bw >= 4e6:
- m_max = int(min(31,math.floor(self._refclk_freq()/1e6)))
- elif bw >= 2e6: # Outside of Specs!
- m_max = int(min(31,math.floor(self._refclk_freq()/.5e6)))
- else: # Way outside of Specs!
- m_max = int(min(31,math.floor(self._refclk_freq()/.25e6)))
-
- m_min = int(math.ceil(self._refclk_freq()/2.5e6))
- m_test = m_max
- while m_test >= m_min:
- fdac_test = int(round(((bw * m_test / self._refclk_freq())-4)/.145))
- if fdac_test>127:
- m_test = m_test - 1
- else:
- break
- if (m_test>=m_min and fdac_test >=0):
- self._set_m(m_test)
- self._set_fdac(fdac_test)
- return (self.m,self.fdac,self._refclk_freq()/self.m*(4+0.145*self.fdac))
- else:
- print "Failed to set bw"
-
- # Gain setting
- def _set_dl(self,dl):
- assert dl == 0 or dl == 1
- self.dl = dl
- self._send_reg(4)
-
- def _set_gc2(self,gc2):
- assert gc2<32 and gc2>=0
- self.gc2 = gc2
- self._send_reg(5)
-
- def _set_gc1(self,gc1):
- assert gc1>=0 and gc1<4096
- self.gc1 = gc1
- self._u.write_aux_dac(self._which,0,int(gc1))
-
- def _set_pga(self, pga_gain):
- assert pga_gain >=0 and pga_gain <=20
- if(self._which == 0):
- self._u.set_pga (0, pga_gain)
- self._u.set_pga (1, pga_gain)
- else:
- self._u.set_pga (2, pga_gain)
- self._u.set_pga (3, pga_gain)
-
- def gain_range(self):
- return (0, 104, 1)
-
- def set_gain(self,gain):
- if not (gain>=0 and gain<105):
- raise ValueError, "gain out of range"
- gc1 = 0
- gc2 = 0
- dl = 0
- pga = 0
- if gain <56:
- gc1 = int((-gain*1.85/56.0 + 2.6)*4096.0/3.3)
- gain = 0
- else:
- gc1 = 0
- gain = gain - 56
- if gain < 24:
- gc2 = int(round(31.0 * (1-gain/24.0)))
- gain = 0
- else:
- gc2 = 0
- gain = gain - 24
- if gain >= 4.58:
- dl = 1
- gain = gain - 4.58
- pga = gain
- self._set_gc1(gc1)
- self._set_gc2(gc2)
- self._set_dl(dl)
- self._set_pga(pga)
-
- # Frequency setting
- def _set_osc(self,osc):
- assert osc>=0 and osc<8
- self.osc = osc
- self._send_reg(2)
-
- def _set_cp(self,cp):
- assert cp>=0 and cp<4
- self.cp = cp
- self._send_reg(2)
-
- def _set_n(self,n):
- assert n>256 and n<32768
- self.n = n
- self._send_reg(0)
- self._send_reg(1)
-
- def _set_div2(self,div2):
- assert div2 == 0 or div2 == 1
- self.div2 = div2
- self._send_reg(0)
-
- def _set_r(self,r):
- assert r>=0 and r<128
- self.r = r
- self.r_int = int(round(math.log10(r)/math.log10(2)) - 1)
- self._send_reg(2)
-
- # FIXME How do we handle ADE and ADL properly?
- def _set_ade(self,ade):
- assert ade == 0 or ade == 1
- self.ade = ade
- self._send_reg(4)
-
- def freq_range(self):
- return (500e6, 2.6e9, 1e6)
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 16
-
- def set_freq(self, freq):
- """
- Set the frequency.
-
- @param freq: target frequency in Hz
- @type freq: float
-
- @returns (ok, actual_baseband_freq) where:
- ok is True or False and indicates success or failure,
- actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
- """
- if not (freq>=500e6 and freq<=2.6e9):
- return (False, 0)
-
- if(freq<1150e6):
- self._set_div2(0)
- vcofreq = 4 * freq
- else:
- self._set_div2(1)
- vcofreq = 2 * freq
- self._set_ade(1)
- rmin=max(2,self._refclk_freq()/2e6)
- rmax=min(128,self._refclk_freq()/500e3)
- r = 2
- n=0
- best_r = 2
- best_n =0
- best_delta = 10e6
- while r <= rmax:
- n = round(freq/(self._refclk_freq()/r))
- if r<rmin or n<256:
- r = r * 2
- continue
- delta = abs(n*self._refclk_freq()/r - freq)
- if delta < 75e3:
- best_r = r
- best_n = n
- break
- if delta < best_delta*0.9:
- best_r = r
- best_n = n
- best_delta = delta
- r = r * 2
- self._set_r(int(best_r))
-
- self._set_n(int(round(best_n)))
-
- if vcofreq < 2433e6:
- vco = 0
- elif vcofreq < 2711e6:
- vco=1
- elif vcofreq < 3025e6:
- vco=2
- elif vcofreq < 3341e6:
- vco=3
- elif vcofreq < 3727e6:
- vco=4
- elif vcofreq < 4143e6:
- vco=5
- elif vcofreq < 4493e6:
- vco=6
- else:
- vco=7
-
- self._set_osc(vco)
-
- # Set CP current
- adc_val = 0
- while adc_val == 0 or adc_val == 7:
- (byte1,byte2) = self._read_status()
- adc_val = byte1 >> 2
- if(adc_val == 0):
- if vco <= 0:
- return (False, 0)
- else:
- vco = vco - 1
- elif(adc_val == 7):
- if(vco >= 7):
- return (False, 0)
- else:
- vco = vco + 1
- self._set_osc(vco)
- if adc_val == 1 or adc_val == 2:
- self._set_cp(1)
- elif adc_val == 3 or adc_val == 4:
- self._set_cp(2)
- else:
- self._set_cp(3)
-
- return (True, self.n * self._refclk_freq() / self.r)
-
- def is_quadrature(self):
- """
- Return True if this board requires both I & Q analog channels.
-
- This bit of info is useful when setting up the USRP Rx mux register.
- """
- return True
-
-# hook this daughterboard class into the auto-instantiation framework
-db_instantiator.add(usrp_dbid.DBS_RX, lambda usrp, which : (db_dbs_rx(usrp, which),))
diff --git a/gr-usrp/src/db_dtt754.py b/gr-usrp/src/db_dtt754.py
deleted file mode 100644
index 019eae6a59..0000000000
--- a/gr-usrp/src/db_dtt754.py
+++ /dev/null
@@ -1,229 +0,0 @@
-#
-# Copyright 2005 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 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.
-#
-
-__all__ = ['tv_rx']
-
-import math
-from usrpm import usrp_dbid
-import db_base
-import db_instantiator
-
-def int_seq_to_str(seq):
- """convert a sequence of integers into a string"""
- return ''.join (map (chr, seq))
-
-def str_to_int_seq(str):
- """convert a string to a list of integers"""
- return map (ord, str)
-
-def control_byte_1():
- RS = 0 # 0 = 166.66kHz reference
- ATP = 7 # Disable internal AGC
- return 0x80 | ATP<<3 | RS
-
-def control_byte_2():
- STBY = 0 # powered on
- XTO = 1 # turn off xtal out, which we don't have
- ATC = 0 # not clear exactly, possibly speeds up or slows down AGC, which we are not using
-
- c = 0xc2 | ATC<<5 | STBY<<4 | XTO
- return c
-
-def bandswitch_byte(freq,bw):
- if(bw>7.5e6):
- P5 = 1
- else:
- P5 = 0
-
- if freq < 121e6:
- CP = 0
- BS = 1
- elif freq < 141e6:
- CP = 1
- BS = 1
- elif freq < 166e6:
- CP = 2
- BS = 1
- elif freq < 182e6:
- CP = 3
- BS = 1
- elif freq < 286e6:
- CP = 0
- BS = 2
- elif freq < 386e6:
- CP = 1
- BS = 2
- elif freq < 446e6:
- CP = 2
- BS = 2
- elif freq < 466e6:
- CP = 3
- BS = 2
- elif freq < 506e6:
- CP = 0
- BS = 8
- elif freq < 761e6:
- CP = 1
- BS = 8
- elif freq < 846e6:
- CP = 2
- BS = 8
- else: # limit is ~905 MHz
- CP = 3
- BS = 8
- return CP<<6 | P5 << 4 | BS
-
-class db_dtt754(db_base.db_base):
- def __init__(self, usrp, which):
- """
- Control custom DTT75403-based daughterboard.
-
- @param usrp: instance of usrp.source_c
- @param which: which side: 0 or 1 corresponding to RX_A or RX_B respectively
- @type which: int
- """
- # sets _u and _which
- db_base.db_base.__init__(self, usrp, which)
-
- self._i2c_addr = (0x60, 0x62)[which]
- self.bw = 7e6
- self._IF = 36e6
-
- self.f_ref = 166.6666e3
- self._inverted = False
-
- g = self.gain_range() # initialize gain
- self.set_gain(float(g[0]+g[1]) / 2)
-
- self.bypass_adc_buffers(False)
-
- # Gain setting
- def _set_rfagc(self,gain):
- assert gain <= 60 and gain >= 0
- # FIXME this has a 0.5V step between gain = 60 and gain = 59.
- # Why are there two cases instead of a single linear case?
- if gain == 60:
- voltage = 4
- else:
- voltage = gain/60.0 * 2.25 + 1.25
- dacword = int(4096*voltage/1.22/3.3) # 1.22 = opamp gain
-
- assert dacword>=0 and dacword<4096
- self._u.write_aux_dac(self._which, 1, dacword)
-
- def _set_ifagc(self,gain):
- assert gain <= 35 and gain >= 0
- voltage = gain/35.0 * 2.1 + 1.4
- dacword = int(4096*voltage/1.22/3.3) # 1.22 = opamp gain
-
- assert dacword>=0 and dacword<4096
- self._u.write_aux_dac(self._which, 0, dacword)
-
- def _set_pga(self,pga_gain):
- assert pga_gain >=0 and pga_gain <=20
- if(self._which == 0):
- self._u.set_pga (0, pga_gain)
- else:
- self._u.set_pga (2, pga_gain)
-
- def gain_range(self):
- return (0, 115, 1)
-
- def set_gain(self,gain):
- assert gain>=0 and gain<=115
- if gain>60:
- rfgain = 60
- gain = gain - 60
- else:
- rfgain = gain
- gain = 0
- if gain > 35:
- ifgain = 35
- gain = gain - 35
- else:
- ifgain = gain
- gain = 0
- pgagain = gain
- self._set_rfagc(rfgain)
- self._set_ifagc(ifgain)
- self._set_pga(pgagain)
-
- def freq_range(self):
- return (44e6, 900e6, 10e3)
-
- def set_freq(self, target_freq):
- """
- @returns (ok, actual_baseband_freq) where:
- ok is True or False and indicates success or failure,
- actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
- """
- r = self.freq_range()
- if target_freq < r[0] or target_freq > r[1]:
- return (False, 0)
-
- target_lo_freq = target_freq + self._IF; # High side mixing
-
- divisor = int(0.5+(target_lo_freq / self.f_ref))
- actual_lo_freq = self.f_ref*divisor
-
- if (divisor & ~0x7fff) != 0: # must be 15-bits or less
- return (False, 0)
-
- # build i2c command string
- buf = [0] * 5
- buf[0] = (divisor >> 8) & 0xff # DB1
- buf[1] = divisor & 0xff # DB2
- buf[2] = control_byte_1()
- buf[3] = bandswitch_byte(actual_lo_freq,self.bw)
- buf[4] = control_byte_2()
-
- ok = self._u.write_i2c(self._i2c_addr, int_seq_to_str (buf))
-
- self.freq = actual_lo_freq - self._IF
-
- return (ok, actual_lo_freq)
-
- def is_quadrature(self):
- """
- Return True if this board requires both I & Q analog channels.
-
- This bit of info is useful when setting up the USRP Rx mux register.
- """
- return False
-
- def spectrum_inverted(self):
- """
- The 43.75 MHz version is inverted
- """
- return self._inverted
-
- def set_bw(self,bw):
- """
- Choose the SAW filter bandwidth, either 7MHz or 8MHz)
- """
- self.bw = bw
- self.set_freq(self.freq)
-
-# hook this daughterboard class into the auto-instantiation framework
-
-# With DTT75403
-db_instantiator.add(usrp_dbid.DTT754,
- lambda usrp, which : (db_dtt754(usrp, which),))
diff --git a/gr-usrp/src/db_dtt768.py b/gr-usrp/src/db_dtt768.py
deleted file mode 100644
index dd342bd20d..0000000000
--- a/gr-usrp/src/db_dtt768.py
+++ /dev/null
@@ -1,203 +0,0 @@
-#
-# Copyright 2005 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 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.
-#
-
-__all__ = ['tv_rx']
-
-import math
-from usrpm import usrp_dbid
-import db_base
-import db_instantiator
-
-def int_seq_to_str(seq):
- """convert a sequence of integers into a string"""
- return ''.join (map (chr, seq))
-
-def str_to_int_seq(str):
- """convert a string to a list of integers"""
- return map (ord, str)
-
-def control_byte_4():
- C = 0 # Charge Pump Current, no info on how to choose
- R = 4 # 125 kHz fref
-
-
- ATP = 7 # Disable internal AGC
- return 0x80 | C<<5 | R
-
-def control_byte_5(freq,agcmode = 1):
- if(agcmode):
- if freq < 150e6:
- return 0x3B
- elif freq < 420e6:
- return 0x7E
- else:
- return 0xB7
- else:
- if freq < 150e6:
- return 0x39
- elif freq < 420e6:
- return 0x7C
- else:
- return 0xB5
-
-def control_byte_6():
- ATC = 0 # AGC time constant = 100ms, 1 = 3S
- IFE = 1 # IF AGC amplifier enable
- AT = 0 # AGC control, ???
-
- return ATC << 5 | IFE << 4 | AT
-
-def control_byte_7():
- SAS = 1 # SAW Digital mode
- AGD = 1 # AGC disable
- ADS = 0 # AGC detector into ADC converter
- T = 0 # Test mode, undocumented
- return SAS << 7 | AGD << 5 | ADS << 4 | T
-
-class db_dtt768(db_base.db_base):
- def __init__(self, usrp, which):
- """
- Control custom DTT76803-based daughterboard.
-
- @param usrp: instance of usrp.source_c
- @param which: which side: 0 or 1 corresponding to RX_A or RX_B respectively
- @type which: int
- """
- # sets _u and _which
- db_base.db_base.__init__(self, usrp, which)
-
- self._i2c_addr = (0x60, 0x62)[which]
- self._IF = 44e6
-
- self.f_ref = 125e3
- self._inverted = False
-
- g = self.gain_range() # initialize gain
- self.set_gain(float(g[0]+g[1]) / 2)
-
- self.bypass_adc_buffers(False)
-
- # Gain setting
- def _set_rfagc(self,gain):
- assert gain <= 60 and gain >= 0
- # FIXME this has a 0.5V step between gain = 60 and gain = 59.
- # Why are there two cases instead of a single linear case?
- if gain == 60:
- voltage = 4
- else:
- voltage = gain/60.0 * 2.25 + 1.25
- dacword = int(4096*voltage/1.22/3.3) # 1.22 = opamp gain
-
- assert dacword>=0 and dacword<4096
- self._u.write_aux_dac(self._which, 1, dacword)
-
- def _set_ifagc(self,gain):
- assert gain <= 35 and gain >= 0
- voltage = gain/35.0 * 2.1 + 1.4
- dacword = int(4096*voltage/1.22/3.3) # 1.22 = opamp gain
-
- assert dacword>=0 and dacword<4096
- self._u.write_aux_dac(self._which, 0, dacword)
-
- def _set_pga(self,pga_gain):
- assert pga_gain >=0 and pga_gain <=20
- if(self._which == 0):
- self._u.set_pga (0, pga_gain)
- else:
- self._u.set_pga (2, pga_gain)
-
- def gain_range(self):
- return (0, 115, 1)
-
- def set_gain(self,gain):
- assert gain>=0 and gain<=115
- if gain>60:
- rfgain = 60
- gain = gain - 60
- else:
- rfgain = gain
- gain = 0
- if gain > 35:
- ifgain = 35
- gain = gain - 35
- else:
- ifgain = gain
- gain = 0
- pgagain = gain
- self._set_rfagc(rfgain)
- self._set_ifagc(ifgain)
- self._set_pga(pgagain)
-
- def freq_range(self):
- return (44e6, 900e6, 10e3)
-
- def set_freq(self, target_freq):
- """
- @returns (ok, actual_baseband_freq) where:
- ok is True or False and indicates success or failure,
- actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
- """
- r = self.freq_range()
- if target_freq < r[0] or target_freq > r[1]:
- return (False, 0)
-
- target_lo_freq = target_freq + self._IF; # High side mixing
-
- divisor = int(0.5+(target_lo_freq / self.f_ref))
- actual_lo_freq = self.f_ref*divisor
-
- if (divisor & ~0x7fff) != 0: # must be 15-bits or less
- return (False, 0)
-
- # build i2c command string
- buf = [0] * 6
- buf[0] = (divisor >> 8) & 0xff # DB1
- buf[1] = divisor & 0xff # DB2
- buf[2] = control_byte_4()
- buf[3] = control_byte_5(target_freq)
- buf[4] = control_byte_6()
- buf[5] = control_byte_7()
-
- ok = self._u.write_i2c(self._i2c_addr, int_seq_to_str (buf))
-
- self.freq = actual_lo_freq - self._IF
-
- return (ok, actual_lo_freq)
-
- def is_quadrature(self):
- """
- Return True if this board requires both I & Q analog channels.
-
- This bit of info is useful when setting up the USRP Rx mux register.
- """
- return False
-
- def spectrum_inverted(self):
- """
- The 43.75 MHz version is inverted
- """
- return self._inverted
-
-# hook this daughterboard class into the auto-instantiation framework
-
-# With DTT76803
-db_instantiator.add(usrp_dbid.DTT768,
- lambda usrp, which : (db_dtt768(usrp, which),))
diff --git a/gr-usrp/src/db_flexrf.py b/gr-usrp/src/db_flexrf.py
deleted file mode 100644
index b5a0cab13e..0000000000
--- a/gr-usrp/src/db_flexrf.py
+++ /dev/null
@@ -1,701 +0,0 @@
-#
-# Copyright 2005,2007 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 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.
-#
-
-from gnuradio import usrp1
-import time,math
-
-from usrpm import usrp_dbid
-import db_base
-import db_instantiator
-from usrpm.usrp_fpga_regs import *
-
-#debug_using_gui = True # Must be set to True or False
-debug_using_gui = False # Must be set to True or False
-
-if debug_using_gui:
- import flexrf_debug_gui
-
-# d'board i/o pin defs
-# Tx and Rx have shared defs, but different i/o regs
-AUX_RXAGC = (1 << 8)
-POWER_UP = (1 << 7) # enables power supply
-RX_TXN = (1 << 6) # Tx only: T/R antenna switch for TX/RX port
-RX2_RX1N = (1 << 6) # Rx only: antenna switch between RX2 and TX/RX port
-ENABLE = (1 << 5) # enables mixer
-AUX_SEN = (1 << 4)
-AUX_SCLK = (1 << 3)
-PLL_LOCK_DETECT = (1 << 2)
-AUX_SDO = (1 << 1)
-CLOCK_OUT = (1 << 0)
-
-SPI_ENABLE_TX_A = usrp1.SPI_ENABLE_TX_A
-SPI_ENABLE_TX_B = usrp1.SPI_ENABLE_TX_B
-SPI_ENABLE_RX_A = usrp1.SPI_ENABLE_RX_A
-SPI_ENABLE_RX_B = usrp1.SPI_ENABLE_RX_B
-
-class flexrf_base(db_base.db_base):
- """
- Abstract base class for all flexrf boards.
-
- Derive board specific subclasses from db_flexrf_base_{tx,rx}
- """
- def __init__(self, usrp, which):
- """
- @param usrp: instance of usrp.source_c
- @param which: which side: 0 or 1 corresponding to side A or B respectively
- @type which: int
- """
- # sets _u _which _tx and _slot
- db_base.db_base.__init__(self, usrp, which)
-
- self.first = True
- self.spi_format = usrp1.SPI_FMT_MSB | usrp1.SPI_FMT_HDR_0
-
- self._u._write_oe(self._which, 0, 0xffff) # turn off all outputs
- self._enable_refclk(False) # disable refclk
-
- g = self.gain_range() # initialize gain
- self.set_gain(float(g[0]+g[1]) / 2)
-
- self.set_auto_tr(False)
-
- if debug_using_gui:
- title = "FlexRF Debug Rx"
- if self._tx:
- title = "FlexRF Debug Tx"
- self.gui = flexrf_debug_gui.flexrf_debug_gui(self, title)
- self.gui.Show(True)
-
-
- def __del__(self):
- #print "flexrf_base.__del__"
- self._u.write_io(self._which, self.power_off, POWER_UP) # turn off power to board
- # Power down VCO/PLL
- self.PD = 3
- self._write_control(self._compute_control_reg())
- self._enable_refclk(False) # turn off refclk
- self.set_auto_tr(False)
-
- def _write_all(self, R, control, N):
- """
- Write R counter latch, control latch and N counter latch to VCO.
-
- Adds 10ms delay between writing control and N if this is first call.
- This is the required power-up sequence.
-
- @param R: 24-bit R counter latch
- @type R: int
- @param control: 24-bit control latch
- @type control: int
- @param N: 24-bit N counter latch
- @type N: int
- """
- self._write_R(R)
- self._write_control( control)
- if self.first:
- time.sleep(0.010)
- self.first = False
- self._write_N(N)
-
- def _write_control(self, control):
- self._write_it((control & ~0x3) | 0)
-
- def _write_R(self, R):
- self._write_it((R & ~0x3) | 1)
-
- def _write_N(self, N):
- self._write_it((N & ~0x3) | 2)
-
- def _write_it(self, v):
- s = ''.join((chr((v >> 16) & 0xff),
- chr((v >> 8) & 0xff),
- chr(v & 0xff)))
- self._u._write_spi(0, self.spi_enable, self.spi_format, s)
-
- def _lock_detect(self):
- """
- @returns: the value of the VCO/PLL lock detect bit.
- @rtype: 0 or 1
- """
- if self._u.read_io(self._which) & PLL_LOCK_DETECT:
- return True
- else: # Give it a second chance
- if self._u.read_io(self._which) & PLL_LOCK_DETECT:
- return True
- else:
- return False
-
- def _compute_regs(self, freq):
- """
- Determine values of R, control, and N registers, along with actual freq.
-
- @param freq: target frequency in Hz
- @type freq: float
- @returns: (R, control, N, actual_freq)
- @rtype: tuple(int, int, int, float)
-
- Override this in derived classes.
- """
- raise NotImplementedError
-
- def _refclk_freq(self):
- # return float(self._u.fpga_master_clock_freq())/self._refclk_divisor()
- return 64e6/self._refclk_divisor()
-
- def set_freq(self, freq):
- """
- @returns (ok, actual_baseband_freq) where:
- ok is True or False and indicates success or failure,
- actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
- """
-
- # Offsetting the LO helps get the Tx carrier leakage out of the way.
- # This also ensures that on Rx, we're not getting hosed by the
- # FPGA's DC removal loop's time constant. We were seeing a
- # problem when running with discontinuous transmission.
- # Offsetting the LO made the problem go away.
- freq += self._lo_offset
-
- R, control, N, actual_freq = self._compute_regs(freq)
- if R==0:
- return(False,0)
- self._write_all(R, control, N)
- return (self._lock_detect(), actual_freq)
-
- def gain_range(self):
- """
- Return range of gain that can be set by this d'board.
-
- @returns (min_gain, max_gain, step_size)
- Where gains are expressed in decibels (your mileage may vary)
- """
- return (self._u.pga_min(), self._u.pga_max(), self._u.pga_db_per_step())
-
- def set_gain(self, gain):
- """
- Set the gain.
-
- @param gain: gain in decibels
- @returns True/False
- """
- return self._set_pga(gain)
-
- def _set_pga(self, pga_gain):
- if(self._which == 0):
- self._u.set_pga (0, pga_gain)
- self._u.set_pga (1, pga_gain)
- else:
- self._u.set_pga (2, pga_gain)
- self._u.set_pga (3, pga_gain)
-
- def is_quadrature(self):
- """
- Return True if this board requires both I & Q analog channels.
-
- This bit of info is useful when setting up the USRP Rx mux register.
- """
- return True
-
- def set_lo_offset(self, offset):
- """
- Set amount by which LO is offset from requested tuning frequency.
-
- @param offset: offset in Hz
- """
- self._lo_offset = offset
-
- def lo_offset(self):
- """
- Get amount by which LO is offset from requested tuning frequency.
-
- @returns Offset in Hz
- """
- return self._lo_offset
-
-# ----------------------------------------------------------------
-
-class flexrf_base_tx(flexrf_base):
- def __init__(self, usrp, which):
- """
- @param usrp: instance of usrp.sink_c
- @param which: 0 or 1 corresponding to side TX_A or TX_B respectively.
- """
- flexrf_base.__init__(self, usrp, which)
- self.spi_enable = (SPI_ENABLE_TX_A, SPI_ENABLE_TX_B)[which]
-
- # power up the transmit side, but don't enable the mixer
- self._u._write_oe(self._which,(POWER_UP|RX_TXN|ENABLE), 0xffff)
- self._u.write_io(self._which, (self.power_on|RX_TXN), (POWER_UP|RX_TXN|ENABLE))
- self.set_lo_offset(4e6)
-
- def __del__(self):
- #print "flexrf_base_tx.__del__"
- # Power down and leave the T/R switch in the R position
- self._u.write_io(self._which, (self.power_off|RX_TXN), (POWER_UP|RX_TXN|ENABLE))
- flexrf_base.__del__(self)
-
- def set_auto_tr(self, on):
- if on:
- self.set_atr_mask (RX_TXN | ENABLE)
- self.set_atr_txval(0 | ENABLE)
- self.set_atr_rxval(RX_TXN | 0)
- else:
- self.set_atr_mask (0)
- self.set_atr_txval(0)
- self.set_atr_rxval(0)
-
- def set_enable(self, on):
- """
- Enable transmitter if on is True
- """
- mask = RX_TXN | ENABLE
- if on:
- v = ENABLE
- else:
- v = RX_TXN
- self._u.write_io(self._which, v, mask)
-
- def gain_range(self):
- """
- Return range of gain that can be set by this d'board.
-
- @returns (min_gain, max_gain, step_size)
- Where gains are expressed in decibels (your mileage may vary)
-
- Flex Tx boards require that the PGA be maxed out to properly bias their circuitry.
- """
- g = self._u.pga_max()
- return (g, g, 1.0)
-
- def set_gain(self, gain):
- """
- Set the gain.
-
- @param gain: gain in decibels
- @returns True/False
- """
- return self._set_pga(self._u.pga_max())
-
-class flexrf_base_rx(flexrf_base):
- def __init__(self, usrp, which):
- """
- @param usrp: instance of usrp.source_c
- @param which: 0 or 1 corresponding to side RX_A or RX_B respectively.
- """
- flexrf_base.__init__(self, usrp, which)
- self.spi_enable = (SPI_ENABLE_RX_A, SPI_ENABLE_RX_B)[which]
-
- self._u._write_oe(self._which, (POWER_UP|RX2_RX1N|ENABLE), 0xffff)
- self._u.write_io(self._which, (self.power_on|RX2_RX1N|ENABLE), (POWER_UP|RX2_RX1N|ENABLE))
-
- # set up for RX on TX/RX port
- self.select_rx_antenna('TX/RX')
-
- self.bypass_adc_buffers(True)
- self.set_lo_offset(-4e6)
-
- def __del__(self):
- # print "flexrf_base_rx.__del__"
- # Power down
- self._u.write_io(self._which, self.power_off, (POWER_UP|ENABLE))
- flexrf_base.__del__(self)
-
- def set_auto_tr(self, on):
- if on:
- self.set_atr_mask (ENABLE)
- self.set_atr_txval( 0)
- self.set_atr_rxval(ENABLE)
- else:
- self.set_atr_mask (0)
- self.set_atr_txval(0)
- self.set_atr_rxval(0)
-
- def select_rx_antenna(self, which_antenna):
- """
- Specify which antenna port to use for reception.
- @param which_antenna: either 'TX/RX' or 'RX2'
- """
- if which_antenna in (0, 'TX/RX'):
- self._u.write_io(self._which, 0, RX2_RX1N)
- elif which_antenna in (1, 'RX2'):
- self._u.write_io(self._which, RX2_RX1N, RX2_RX1N)
- else:
- raise ValueError, "which_antenna must be either 'TX/RX' or 'RX2'"
-
- def set_gain(self, gain):
- """
- Set the gain.
-
- @param gain: gain in decibels
- @returns True/False
- """
- maxgain = self.gain_range()[1] - self._u.pga_max()
- mingain = self.gain_range()[0]
- if gain > maxgain:
- pga_gain = gain-maxgain
- assert pga_gain <= self._u.pga_max()
- agc_gain = maxgain
- else:
- pga_gain = 0
- agc_gain = gain
- V_maxgain = .2
- V_mingain = 1.2
- V_fullscale = 3.3
- dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale
- assert dac_value>=0 and dac_value<4096
- return self._u.write_aux_dac(self._which, 0, int(dac_value)) and \
- self._set_pga(int(pga_gain))
-
-# ----------------------------------------------------------------
-
-class _AD4360_common(object):
- def __init__(self):
- # R-Register Common Values
- self.R_RSV = 0 # bits 23,22
- self.BSC = 3 # bits 21,20 Div by 8 to be safe
- self.TEST = 0 # bit 19
- self.LDP = 1 # bit 18
- self.ABP = 0 # bit 17,16 3ns
-
- # N-Register Common Values
- self.N_RSV = 0 # bit 7
-
- # Control Register Common Values
- self.PD = 0 # bits 21,20 Normal operation
- self.PL = 0 # bits 13,12 11mA
- self.MTLD = 1 # bit 11 enabled
- self.CPG = 0 # bit 10 CP setting 1
- self.CP3S = 0 # bit 9 Normal
- self.PDP = 1 # bit 8 Positive
- self.MUXOUT = 1 # bits 7:5 Digital Lock Detect
- self.CR = 0 # bit 4 Normal
- self.PC = 1 # bits 3,2 Core power 10mA
-
- def _compute_regs(self, freq):
- """
- Determine values of R, control, and N registers, along with actual freq.
-
- @param freq: target frequency in Hz
- @type freq: float
- @returns: (R, control, N, actual_freq)
- @rtype: tuple(int, int, int, float)
- """
-
- # Band-specific N-Register Values
- phdet_freq = self._refclk_freq()/self.R_DIV
- desired_n = round(freq*self.freq_mult/phdet_freq)
- actual_freq = desired_n * phdet_freq
- B = math.floor(desired_n/self._prescaler())
- A = desired_n - self._prescaler()*B
- self.B_DIV = int(B) # bits 20:8
- self.A_DIV = int(A) # bit 6:2
- #assert self.B_DIV >= self.A_DIV
- if self.B_DIV < self.A_DIV:
- return (0,0,0,0)
- R = (self.R_RSV<<22) | (self.BSC<<20) | (self.TEST<<19) | (self.LDP<<18) \
- | (self.ABP<<16) | (self.R_DIV<<2)
-
- control = self._compute_control_reg()
-
- N = (self.DIVSEL<<23) | (self.DIV2<<22) | (self.CPGAIN<<21) | (self.B_DIV<<8) | \
- (self.N_RSV<<7) | (self.A_DIV<<2)
-
- return (R,control,N,actual_freq/self.freq_mult)
-
- def _compute_control_reg(self):
- control = (self.P<<22) | (self.PD<<20) | (self.CP2<<17) | (self.CP1<<14) | (self.PL<<12) \
- | (self.MTLD<<11) | (self.CPG<<10) | (self.CP3S<<9) | (self.PDP<<8) | \
- (self.MUXOUT<<5) | (self.CR<<4) | (self.PC<<2)
- return control
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 1
-
- def _prescaler(self):
- if self.P == 0:
- return 8
- elif self.P == 1:
- return 16
- else:
- return 32
-
-#----------------------------------------------------------------------
-class _2400_common(_AD4360_common):
- def __init__(self):
- _AD4360_common.__init__(self)
-
- # Band-specific R-Register Values
- self.R_DIV = 16 # bits 15:2
-
- # Band-specific C-Register values
- self.P = 1 # bits 23,22 Div by 16/17
- self.CP2 = 7 # bits 19:17
- self.CP1 = 7 # bits 16:14
-
- # Band specifc N-Register Values
- self.DIVSEL = 0 # bit 23
- self.DIV2 = 0 # bit 22
- self.CPGAIN = 0 # bit 21
- self.freq_mult = 1
-
- def freq_range(self): # FIXME
- return (2300e6, 2700e6, 4e6)
-
-#----------------------------------------------------------------------
-class _1200_common(_AD4360_common):
- def __init__(self):
- _AD4360_common.__init__(self)
-
- # Band-specific R-Register Values
- self.R_DIV = 16 # bits 15:2 DIV by 16 for a 1 MHz phase detector freq
-
- # Band-specific C-Register values
- self.P = 1 # bits 23,22 Div by 16/17
- self.CP2 = 7 # bits 19:17 1.25 mA
- self.CP1 = 7 # bits 16:14 1.25 mA
-
- # Band specifc N-Register Values
- self.DIVSEL = 0 # bit 23
- self.DIV2 = 1 # bit 22
- self.CPGAIN = 0 # bit 21
- self.freq_mult = 2
-
- def freq_range(self): # FIXME
- return (1150e6, 1350e6, 4e6)
-
-#-------------------------------------------------------------------------
-class _1800_common(_AD4360_common):
- def __init__(self):
- _AD4360_common.__init__(self)
-
- # Band-specific R-Register Values
- self.R_DIV = 16 # bits 15:2 DIV by 16 for a 1 MHz phase detector freq
-
- # Band-specific C-Register values
- self.P = 1 # bits 23,22 Div by 16/17
- self.CP2 = 7 # bits 19:17 1.25 mA
- self.CP1 = 7 # bits 16:14 1.25 mA
-
- # Band specifc N-Register Values
- self.DIVSEL = 0 # bit 23
- self.DIV2 = 0 # bit 22
- self.freq_mult = 1
- self.CPGAIN = 0 # bit 21
-
- def freq_range(self): # FIXME
- return (1600e6, 2000e6, 4e6)
-
-#-------------------------------------------------------------------------
-class _900_common(_AD4360_common):
- def __init__(self):
- _AD4360_common.__init__(self)
-
- # Band-specific R-Register Values
- self.R_DIV = 16 # bits 15:2 DIV by 16 for a 1 MHz phase detector freq
-
- # Band-specific C-Register values
- self.P = 1 # bits 23,22 Div by 16/17
- self.CP2 = 7 # bits 19:17 1.25 mA
- self.CP1 = 7 # bits 16:14 1.25 mA
-
- # Band specifc N-Register Values
- self.DIVSEL = 0 # bit 23
- self.DIV2 = 1 # bit 22
- self.freq_mult = 2
- self.CPGAIN = 0 # bit 21
-
- def freq_range(self): # FIXME
- return (800e6, 1000e6, 4e6)
-
-#-------------------------------------------------------------------------
-class _400_common(_AD4360_common):
- def __init__(self):
- _AD4360_common.__init__(self)
-
- # Band-specific R-Register Values
- self.R_DIV = 16 # bits 15:2
-
- # Band-specific C-Register values
- self.P = 0 # bits 23,22 Div by 8/9
- self.CP2 = 7 # bits 19:17 1.25 mA
- self.CP1 = 7 # bits 16:14 1.25 mA
-
- # Band specifc N-Register Values These are different for TX/RX
- self.DIVSEL = 0 # bit 23
- if self._tx:
- self.DIV2 = 1 # bit 22
- else:
- self.DIV2 = 0 # bit 22 # RX side has built-in DIV2 in AD8348
- self.freq_mult = 2
-
- self.CPGAIN = 0 # bit 21
-
- def freq_range(self):
- #return (350e6, 465e6, 1e6) # FIXME prototype
- return (400e6, 500e6, 1e6) # final version
-
-
-#------------------------------------------------------------
-class db_flexrf_2400_tx(_2400_common, flexrf_base_tx):
- def __init__(self, usrp, which):
- self.power_on = 0
- self.power_off = 0 # powering it off kills the serial bus
- flexrf_base_tx.__init__(self, usrp, which)
- _2400_common.__init__(self)
-
-class db_flexrf_2400_rx(_2400_common, flexrf_base_rx):
- def __init__(self, usrp, which):
- self.power_on = 0
- self.power_off = 0 # Powering it off kills the serial bus
- flexrf_base_rx.__init__(self, usrp, which)
- _2400_common.__init__(self)
-
- def gain_range(self):
- """
- Return range of gain that can be set by this d'board.
-
- @returns (min_gain, max_gain, step_size)
- Where gains are expressed in decibels (your mileage may vary)
- """
- return (self._u.pga_min(), self._u.pga_max() + 70, 0.05)
-
- def i_and_q_swapped(self):
- return True
-
-class db_flexrf_1200_tx(_1200_common, flexrf_base_tx):
- def __init__(self, usrp, which):
- self.power_on = 0
- self.power_off = 0 # powering it off kills the serial bus
- flexrf_base_tx.__init__(self, usrp, which)
- _1200_common.__init__(self)
-
-class db_flexrf_1200_rx(_1200_common, flexrf_base_rx):
- def __init__(self, usrp, which):
- self.power_on = 0
- self.power_off = 0 # powering it off kills the serial bus
- flexrf_base_rx.__init__(self, usrp, which)
- _1200_common.__init__(self)
-
- def gain_range(self):
- """
- Return range of gain that can be set by this d'board.
-
- @returns (min_gain, max_gain, step_size)
- Where gains are expressed in decibels (your mileage may vary)
- """
- return (self._u.pga_min(), self._u.pga_max() + 70, 0.05)
-
- def i_and_q_swapped(self):
- return True
-
-class db_flexrf_1800_tx(_1800_common, flexrf_base_tx):
- def __init__(self, usrp, which):
- self.power_on = 0
- self.power_off = 0 # powering it off kills the serial bus
- flexrf_base_tx.__init__(self, usrp, which)
- _1800_common.__init__(self)
-
-class db_flexrf_1800_rx(_1800_common, flexrf_base_rx):
- def __init__(self, usrp, which):
- self.power_on = 0
- self.power_off = 0 # powering it off kills the serial bus
- flexrf_base_rx.__init__(self, usrp, which)
- _1800_common.__init__(self)
-
- def gain_range(self):
- """
- Return range of gain that can be set by this d'board.
-
- @returns (min_gain, max_gain, step_size)
- Where gains are expressed in decibels (your mileage may vary)
- """
- return (self._u.pga_min(), self._u.pga_max() + 70, 0.05)
-
- def i_and_q_swapped(self):
- return True
-
-class db_flexrf_900_tx(_900_common, flexrf_base_tx):
- def __init__(self, usrp, which):
- self.power_on = 0
- self.power_off = 0 # powering it off kills the serial bus
- flexrf_base_tx.__init__(self, usrp, which)
- _900_common.__init__(self)
-
-class db_flexrf_900_rx(_900_common, flexrf_base_rx):
- def __init__(self, usrp, which):
- self.power_on = 0
- self.power_off = 0 # powering it off kills the serial bus
- flexrf_base_rx.__init__(self, usrp, which)
- _900_common.__init__(self)
-
- def gain_range(self):
- """
- Return range of gain that can be set by this d'board.
-
- @returns (min_gain, max_gain, step_size)
- Where gains are expressed in decibels (your mileage may vary)
- """
- return (self._u.pga_min(), self._u.pga_max() + 70, 0.05)
-
- def i_and_q_swapped(self):
- return True
-
-class db_flexrf_400_tx(_400_common, flexrf_base_tx):
- def __init__(self, usrp, which):
- self.power_on = POWER_UP
- self.power_off = 0
- flexrf_base_tx.__init__(self, usrp, which)
- _400_common.__init__(self)
-
-class db_flexrf_400_rx(_400_common, flexrf_base_rx):
- def __init__(self, usrp, which):
- self.power_on = POWER_UP
- self.power_off = 0
- flexrf_base_rx.__init__(self, usrp, which)
- _400_common.__init__(self)
-
- def gain_range(self):
- """
- Return range of gain that can be set by this d'board.
-
- @returns (min_gain, max_gain, step_size)
- Where gains are expressed in decibels (your mileage may vary)
- """
- return (self._u.pga_min(), self._u.pga_max() + 45, 0.035)
-
- def i_and_q_swapped(self):
- return True
-
-# hook these daughterboard classes into the auto-instantiation framework
-
-db_instantiator.add(usrp_dbid.FLEX_2400_TX, lambda usrp, which : (db_flexrf_2400_tx(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_2400_RX, lambda usrp, which : (db_flexrf_2400_rx(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_1200_TX, lambda usrp, which : (db_flexrf_1200_tx(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_1200_RX, lambda usrp, which : (db_flexrf_1200_rx(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_1800_TX, lambda usrp, which : (db_flexrf_1800_tx(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_1800_RX, lambda usrp, which : (db_flexrf_1800_rx(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_900_TX, lambda usrp, which : (db_flexrf_900_tx(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_900_RX, lambda usrp, which : (db_flexrf_900_rx(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_400_TX, lambda usrp, which : (db_flexrf_400_tx(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_400_RX, lambda usrp, which : (db_flexrf_400_rx(usrp, which),))
diff --git a/gr-usrp/src/db_flexrf_mimo.py b/gr-usrp/src/db_flexrf_mimo.py
deleted file mode 100644
index 755979bcb5..0000000000
--- a/gr-usrp/src/db_flexrf_mimo.py
+++ /dev/null
@@ -1,286 +0,0 @@
-#
-# Copyright 2005 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 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.
-#
-
-from gnuradio import usrp1
-import time,math
-
-from usrpm import usrp_dbid
-import db_base
-import db_instantiator
-from usrpm.usrp_fpga_regs import *
-from db_flexrf import *
-
-# self._u.fpga_master_clock_freq()
-
-# MIMO Classes
-class db_flexrf_2400_tx_mimo_a(db_flexrf_2400_tx):
- def __init__(self, usrp, which):
- db_flexrf_2400_tx.__init__(self, usrp, which)
- self._enable_refclk(True)
- self.R_DIV = 1
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 16
-
-class db_flexrf_2400_rx_mimo_a(db_flexrf_2400_rx):
- def __init__(self, usrp, which):
- db_flexrf_2400_rx.__init__(self, usrp, which)
- self._enable_refclk(True)
- self.R_DIV = 1
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 16
-
-class db_flexrf_2400_tx_mimo_b(db_flexrf_2400_tx):
- def __init__(self, usrp, which):
- db_flexrf_2400_tx.__init__(self, usrp, which)
- self.R_DIV = 16
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 1
-
-class db_flexrf_2400_rx_mimo_b(db_flexrf_2400_rx):
- def __init__(self, usrp, which):
- db_flexrf_2400_rx.__init__(self, usrp, which)
- self.R_DIV = 16
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 1
-
-class db_flexrf_1800_tx_mimo_a(db_flexrf_1800_tx):
- def __init__(self, usrp, which):
- db_flexrf_1800_tx.__init__(self, usrp, which)
- self._enable_refclk(True)
- self.R_DIV = 1
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 16
-
-class db_flexrf_1800_rx_mimo_a(db_flexrf_1800_rx):
- def __init__(self, usrp, which):
- db_flexrf_1800_rx.__init__(self, usrp, which)
- self._enable_refclk(True)
- self.R_DIV = 1
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 16
-
-class db_flexrf_1800_tx_mimo_b(db_flexrf_1800_tx):
- def __init__(self, usrp, which):
- db_flexrf_1800_tx.__init__(self, usrp, which)
- self.R_DIV = 16
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 1
-
-class db_flexrf_1800_rx_mimo_b(db_flexrf_1800_rx):
- def __init__(self, usrp, which):
- db_flexrf_1800_rx.__init__(self, usrp, which)
- self.R_DIV = 16
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 1
-
-class db_flexrf_1200_tx_mimo_a(db_flexrf_1200_tx):
- def __init__(self, usrp, which):
- db_flexrf_1200_tx.__init__(self, usrp, which)
- self._enable_refclk(True)
- self.R_DIV = 1
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 16
-
-class db_flexrf_1200_rx_mimo_a(db_flexrf_1200_rx):
- def __init__(self, usrp, which):
- db_flexrf_1200_rx.__init__(self, usrp, which)
- self._enable_refclk(True)
- self.R_DIV = 1
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 16
-
-class db_flexrf_1200_tx_mimo_b(db_flexrf_1200_tx):
- def __init__(self, usrp, which):
- db_flexrf_1200_tx.__init__(self, usrp, which)
- self.R_DIV = 16
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 1
-
-class db_flexrf_1200_rx_mimo_b(db_flexrf_1200_rx):
- def __init__(self, usrp, which):
- db_flexrf_1200_rx.__init__(self, usrp, which)
- self.R_DIV = 16
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 1
-
-class db_flexrf_900_tx_mimo_a(db_flexrf_900_tx):
- def __init__(self, usrp, which):
- db_flexrf_900_tx.__init__(self, usrp, which)
- self._enable_refclk(True)
- self.R_DIV = 1
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 16
-
-class db_flexrf_900_rx_mimo_a(db_flexrf_900_rx):
- def __init__(self, usrp, which):
- db_flexrf_900_rx.__init__(self, usrp, which)
- self._enable_refclk(True)
- self.R_DIV = 1
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 16
-
-class db_flexrf_900_tx_mimo_b(db_flexrf_900_tx):
- def __init__(self, usrp, which):
- db_flexrf_900_tx.__init__(self, usrp, which)
- self.R_DIV = 16
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 1
-
-class db_flexrf_900_rx_mimo_b(db_flexrf_900_rx):
- def __init__(self, usrp, which):
- db_flexrf_900_rx.__init__(self, usrp, which)
- self.R_DIV = 16
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 1
-
-class db_flexrf_400_tx_mimo_a(db_flexrf_400_tx):
- def __init__(self, usrp, which):
- db_flexrf_400_tx.__init__(self, usrp, which)
- self._enable_refclk(True)
- self.R_DIV = 1
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 16
-
-class db_flexrf_400_rx_mimo_a(db_flexrf_400_rx):
- def __init__(self, usrp, which):
- db_flexrf_400_rx.__init__(self, usrp, which)
- self._enable_refclk(True)
- self.R_DIV = 1
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 16
-
-class db_flexrf_400_tx_mimo_b(db_flexrf_400_tx):
- def __init__(self, usrp, which):
- db_flexrf_400_tx.__init__(self, usrp, which)
- self.R_DIV = 16
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 1
-
-class db_flexrf_400_rx_mimo_b(db_flexrf_400_rx):
- def __init__(self, usrp, which):
- db_flexrf_400_rx.__init__(self, usrp, which)
- self.R_DIV = 16
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 1
-
-# hook these daughterboard classes into the auto-instantiation framework
-db_instantiator.add(usrp_dbid.FLEX_2400_TX_MIMO_A, lambda usrp, which : (db_flexrf_2400_tx_mimo_a(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_2400_RX_MIMO_A, lambda usrp, which : (db_flexrf_2400_rx_mimo_a(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_1800_TX_MIMO_A, lambda usrp, which : (db_flexrf_1800_tx_mimo_a(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_1800_RX_MIMO_A, lambda usrp, which : (db_flexrf_1800_rx_mimo_a(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_1200_TX_MIMO_A, lambda usrp, which : (db_flexrf_1200_tx_mimo_a(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_1200_RX_MIMO_A, lambda usrp, which : (db_flexrf_1200_rx_mimo_a(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_900_TX_MIMO_A, lambda usrp, which : (db_flexrf_900_tx_mimo_a(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_900_RX_MIMO_A, lambda usrp, which : (db_flexrf_900_rx_mimo_a(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_400_TX_MIMO_A, lambda usrp, which : (db_flexrf_400_tx_mimo_a(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_400_RX_MIMO_A, lambda usrp, which : (db_flexrf_400_rx_mimo_a(usrp, which),))
-
-db_instantiator.add(usrp_dbid.FLEX_2400_TX_MIMO_B, lambda usrp, which : (db_flexrf_2400_tx_mimo_b(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_2400_RX_MIMO_B, lambda usrp, which : (db_flexrf_2400_rx_mimo_b(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_1800_TX_MIMO_B, lambda usrp, which : (db_flexrf_1800_tx_mimo_b(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_1800_RX_MIMO_B, lambda usrp, which : (db_flexrf_1800_rx_mimo_b(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_1200_TX_MIMO_B, lambda usrp, which : (db_flexrf_1200_tx_mimo_b(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_1200_RX_MIMO_B, lambda usrp, which : (db_flexrf_1200_rx_mimo_b(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_900_TX_MIMO_B, lambda usrp, which : (db_flexrf_900_tx_mimo_b(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_900_RX_MIMO_B, lambda usrp, which : (db_flexrf_900_rx_mimo_b(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_400_TX_MIMO_B, lambda usrp, which : (db_flexrf_400_tx_mimo_b(usrp, which),))
-db_instantiator.add(usrp_dbid.FLEX_400_RX_MIMO_B, lambda usrp, which : (db_flexrf_400_rx_mimo_b(usrp, which),))
-
diff --git a/gr-usrp/src/db_tv_rx.py b/gr-usrp/src/db_tv_rx.py
deleted file mode 100644
index 48fe6ca05e..0000000000
--- a/gr-usrp/src/db_tv_rx.py
+++ /dev/null
@@ -1,198 +0,0 @@
-#
-# Copyright 2005 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 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.
-#
-
-__all__ = ['tv_rx']
-
-import math
-from usrpm import usrp_dbid
-import db_base
-import db_instantiator
-
-def int_seq_to_str(seq):
- """convert a sequence of integers into a string"""
- return ''.join (map (chr, seq))
-
-def str_to_int_seq(str):
- """convert a string to a list of integers"""
- return map (ord, str)
-
-def control_byte_1(fast_tuning_p, reference_divisor):
- c = 0x88
- if fast_tuning_p:
- c |= 0x40
- if reference_divisor == 512:
- c |= 0x3 << 1
- elif reference_divisor == 640:
- c |= 0x0 << 1
- elif reference_divisor == 1024:
- c |= 0x1 << 1
- else:
- assert 0
- return c
-
-def control_byte_2(target_freq, shutdown_tx_PGA):
- if target_freq < 158e6: # VHF low
- c = 0xa0
- elif target_freq < 464e6: # VHF high
- c = 0x90
- else: # UHF
- c = 0x30
- if shutdown_tx_PGA:
- c |= 0x08
- return c
-
-class db_tv_rx(db_base.db_base):
- def __init__(self, usrp, which, first_IF, second_IF, inverted):
- """
- Control Microtune 4937 based USRP daughterboard.
-
- @param usrp: instance of usrp.source_c
- @param which: which side: 0 or 1 corresponding to RX_A or RX_B respectively
- @type which: int
- """
- # sets _u and _which
- db_base.db_base.__init__(self, usrp, which)
-
- self._i2c_addr = (0x60, 0x61)[which]
-
- self._first_IF = first_IF
- self._second_IF = second_IF
- self._reference_divisor = 640
- self._fast_tuning = False
- self._inverted = inverted
-
- g = self.gain_range()
- self.set_gain(float(g[0]+g[1]) / 2) # default gain is halfscale
-
- self.bypass_adc_buffers(False)
-
- # Gain setting
- def _set_rfagc(self,gain):
- assert gain <= 60 and gain >= 0
- # FIXME this has a 0.5V step between gain = 60 and gain = 59.
- # Why are there two cases instead of a single linear case?
- if gain == 60:
- voltage = 4
- else:
- voltage = gain/60.0 * 2.25 + 1.25
- dacword = int(4096*voltage/1.22/3.3) # 1.22 = opamp gain
-
- assert dacword>=0 and dacword<4096
- self._u.write_aux_dac(self._which, 1, dacword)
-
- def _set_ifagc(self,gain):
- assert gain <= 35 and gain >= 0
- voltage = gain/35.0 * 2.1 + 1.4
- dacword = int(4096*voltage/1.22/3.3) # 1.22 = opamp gain
-
- assert dacword>=0 and dacword<4096
- self._u.write_aux_dac(self._which, 0, dacword)
-
- def _set_pga(self,pga_gain):
- assert pga_gain >=0 and pga_gain <=20
- if(self._which == 0):
- self._u.set_pga (0, pga_gain)
- else:
- self._u.set_pga (2, pga_gain)
-
- def gain_range(self):
- return (0, 115, 1)
-
- def set_gain(self,gain):
- assert gain>=0 and gain<=115
- if gain>60:
- rfgain = 60
- gain = gain - 60
- else:
- rfgain = gain
- gain = 0
- if gain > 35:
- ifgain = 35
- gain = gain - 35
- else:
- ifgain = gain
- gain = 0
- pgagain = gain
- self._set_rfagc(rfgain)
- self._set_ifagc(ifgain)
- self._set_pga(pgagain)
-
- def freq_range(self):
- return (50e6, 860e6, 10e3)
-
- def set_freq(self, target_freq):
- """
- @returns (ok, actual_baseband_freq) where:
- ok is True or False and indicates success or failure,
- actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
- """
- r = self.freq_range()
- if target_freq < r[0] or target_freq > r[1]:
- return (False, 0)
-
- target_lo_freq = target_freq + self._first_IF; # High side mixing
- f_ref = 4e6 / self._reference_divisor # frequency steps
-
- divisor = int((target_lo_freq + (f_ref * 4)) / (f_ref * 8))
- actual_lo_freq = (f_ref * 8 * divisor)
- actual_freq = actual_lo_freq - self._first_IF;
-
- if (divisor & ~0x7fff) != 0: # must be 15-bits or less
- return (False, 0)
-
- # build i2c command string
- buf = [0] * 4
- buf[0] = (divisor >> 8) & 0xff # DB1
- buf[1] = divisor & 0xff # DB2
- buf[2] = control_byte_1(self._fast_tuning, self._reference_divisor)
- buf[3] = control_byte_2(actual_freq, True)
-
- ok = self._u.write_i2c(self._i2c_addr, int_seq_to_str (buf))
-
- return (ok, actual_freq - self._second_IF)
-
- def is_quadrature(self):
- """
- Return True if this board requires both I & Q analog channels.
-
- This bit of info is useful when setting up the USRP Rx mux register.
- """
- return False
-
- def spectrum_inverted(self):
- """
- The 43.75 MHz version is inverted
- """
- return self._inverted
-
-# hook this daughterboard class into the auto-instantiation framework
-
-# With MT4937DI5-3x7702 with second downconversion
-db_instantiator.add(usrp_dbid.TV_RX,
- lambda usrp, which : (db_tv_rx(usrp, which, 43.75e6, 5.75e6, False),))
-
-# With MT4937DI5-3x8680, and 3x8769 without second downconversion
-db_instantiator.add(usrp_dbid.TV_RX_REV_2,
- lambda usrp, which : (db_tv_rx(usrp, which, 44e6, 44e6, True),))
-
-# With MT4937DI5-3x7901 without second downconversion, basically the same as tvrx2
-db_instantiator.add(usrp_dbid.TV_RX_REV_3,
- lambda usrp, which : (db_tv_rx(usrp, which, 44e6, 44e6, True),))
diff --git a/gr-usrp/src/db_wbx.py b/gr-usrp/src/db_wbx.py
deleted file mode 100644
index 72b3e35c13..0000000000
--- a/gr-usrp/src/db_wbx.py
+++ /dev/null
@@ -1,622 +0,0 @@
-#
-# Copyright 2007 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import usrp1
-import time,math
-
-from usrpm import usrp_dbid
-import db_base
-import db_instantiator
-from usrpm.usrp_fpga_regs import *
-
-#debug_using_gui = True # Must be set to True or False
-debug_using_gui = False # Must be set to True or False
-
-#if debug_using_gui:
-# import flexrf_debug_gui
-
-# d'board i/o pin defs
-
-# TX IO Pins
-TX_POWER = (1 << 0) # TX Side Power
-RX_TXN = (1 << 1) # T/R antenna switch for TX/RX port
-TX_ENB_MIX = (1 << 2) # Enable IQ mixer
-TX_ENB_VGA = (1 << 3)
-
-# RX IO Pins
-RX2_RX1N = (1 << 0) # antenna switch between RX2 and TX/RX port
-RXENABLE = (1 << 1) # enables mixer
-PLL_LOCK_DETECT = (1 << 2) # Muxout pin from PLL -- MUST BE INPUT
-MReset = (1 << 3) # NB6L239 Master Reset, asserted low
-SELA0 = (1 << 4) # NB6L239 SelA0
-SELA1 = (1 << 5) # NB6L239 SelA1
-SELB0 = (1 << 6) # NB6L239 SelB0
-SELB1 = (1 << 7) # NB6L239 SelB1
-PLL_ENABLE = (1 << 8) # CE Pin on PLL
-AUX_SCLK = (1 << 9) # ALT SPI SCLK
-AUX_SDO = (1 << 10) # ALT SPI SDO
-AUX_SEN = (1 << 11) # ALT SPI SEN
-
-SPI_ENABLE_TX_A = usrp1.SPI_ENABLE_TX_A
-SPI_ENABLE_TX_B = usrp1.SPI_ENABLE_TX_B
-SPI_ENABLE_RX_A = usrp1.SPI_ENABLE_RX_A
-SPI_ENABLE_RX_B = usrp1.SPI_ENABLE_RX_B
-
-
-"""
-A few comments about the WBX boards:
- They are half-duplex. I.e., transmit and receive are mutually exclusive.
- There is a single LO for both the Tx and Rx sides.
- The the shared control signals are hung off of the Rx side.
- The shared io controls are duplexed onto the Rx side pins.
- The wbx_high d'board always needs to be in 'auto_tr_mode'
-"""
-
-
-class wbx_base(db_base.db_base):
- """
- Abstract base class for all wbx boards.
-
- Derive board specific subclasses from db_wbx_base_{tx,rx}
- """
- def __init__(self, usrp, which):
- """
- @param usrp: instance of usrp.source_c
- @param which: which side: 0 or 1 corresponding to side A or B respectively
- @type which: int
- """
- # sets _u _which _tx and _slot
- db_base.db_base.__init__(self, usrp, which)
-
- self.first = True
- self.spi_format = usrp1.SPI_FMT_MSB | usrp1.SPI_FMT_HDR_0
-
- # FIXME -- the write reg functions don't work with 0xffff for masks
- self._rx_write_oe(int(PLL_ENABLE|MReset|SELA0|SELA1|SELB0|SELB1|RX2_RX1N|RXENABLE), 0x7fff)
- self._rx_write_io((PLL_ENABLE|MReset|0|RXENABLE), (PLL_ENABLE|MReset|RX2_RX1N|RXENABLE))
-
- self._tx_write_oe((TX_POWER|RX_TXN|TX_ENB_MIX|TX_ENB_VGA), 0x7fff)
- self._tx_write_io((0|RX_TXN), (TX_POWER|RX_TXN|TX_ENB_MIX|TX_ENB_VGA)) # TX off, TR switch set to RX
-
- self.spi_enable = (SPI_ENABLE_RX_A, SPI_ENABLE_RX_B)[which]
-
- self.set_auto_tr(False)
-
- #if debug_using_gui:
- # title = "FlexRF Debug Rx"
- # if self._tx:
- # title = "FlexRF Debug Tx"
- # self.gui = flexrf_debug_gui.flexrf_debug_gui(self, title)
- # self.gui.Show(True)
-
-
- def __del__(self):
- #self._u.write_io(self._which, self.power_off, POWER_UP) # turn off power to board
- #self._u._write_oe(self._which, 0, 0xffff) # turn off all outputs
- self.set_auto_tr(False)
-
- def _lock_detect(self):
- """
- @returns: the value of the VCO/PLL lock detect bit.
- @rtype: 0 or 1
- """
- if self._rx_read_io() & PLL_LOCK_DETECT:
- return True
- else: # Give it a second chance
- if self._rx_read_io() & PLL_LOCK_DETECT:
- return True
- else:
- return False
-
- # Both sides need access to the Rx pins.
- # Write them directly, bypassing the convenience routines.
- # (Sort of breaks modularity, but will work...)
-
- def _tx_write_oe(self, value, mask):
- return self._u._write_fpga_reg((FR_OE_0, FR_OE_2)[self._which],
- ((mask & 0xffff) << 16) | (value & 0xffff))
-
- def _rx_write_oe(self, value, mask):
- return self._u._write_fpga_reg((FR_OE_1, FR_OE_3)[self._which],
- ((mask & 0xffff) << 16) | (value & 0xffff))
-
- def _tx_write_io(self, value, mask):
- return self._u._write_fpga_reg((FR_IO_0, FR_IO_2)[self._which],
- ((mask & 0xffff) << 16) | (value & 0xffff))
-
- def _rx_write_io(self, value, mask):
- return self._u._write_fpga_reg((FR_IO_1, FR_IO_3)[self._which],
- ((mask & 0xffff) << 16) | (value & 0xffff))
-
- def _rx_read_io(self):
- t = self._u._read_fpga_reg((FR_RB_IO_RX_A_IO_TX_A, FR_RB_IO_RX_B_IO_TX_B)[self._which])
- return (t >> 16) & 0xffff
-
- def _tx_read_io(self):
- t = self._u._read_fpga_reg((FR_RB_IO_RX_A_IO_TX_A, FR_RB_IO_RX_B_IO_TX_B)[self._which])
- return t & 0xffff
-
-
- def _compute_regs(self, freq):
- """
- Determine values of registers, along with actual freq.
-
- @param freq: target frequency in Hz
- @type freq: float
- @returns: (R, N, func, init, actual_freq)
- @rtype: tuple(int, int, int, int, float)
-
- Override this in derived classes.
- """
- raise NotImplementedError
-
- def _refclk_freq(self):
- return float(self._u.fpga_master_clock_freq())/self._refclk_divisor()
-
- def _refclk_divisor(self):
- """
- Return value to stick in REFCLK_DIVISOR register
- """
- return 1
-
- # ----------------------------------------------------------------
-
- def set_freq(self, freq):
- """
- @returns (ok, actual_baseband_freq) where:
- ok is True or False and indicates success or failure,
- actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
- """
- raise NotImplementedError
-
- def gain_range(self):
- """
- Return range of gain that can be set by this d'board.
-
- @returns (min_gain, max_gain, step_size)
- Where gains are expressed in decibels (your mileage may vary)
- """
- raise NotImplementedError
-
- def set_gain(self, gain):
- """
- Set the gain.
-
- @param gain: gain in decibels
- @returns True/False
- """
- raise NotImplementedError
-
- def _set_pga(self, pga_gain):
- if(self._which == 0):
- self._u.set_pga (0, pga_gain)
- self._u.set_pga (1, pga_gain)
- else:
- self._u.set_pga (2, pga_gain)
- self._u.set_pga (3, pga_gain)
-
- def is_quadrature(self):
- """
- Return True if this board requires both I & Q analog channels.
-
- This bit of info is useful when setting up the USRP Rx mux register.
- """
- return True
-
-# ----------------------------------------------------------------
-
-class wbx_base_tx(wbx_base):
- def __init__(self, usrp, which):
- """
- @param usrp: instance of usrp.sink_c
- @param which: 0 or 1 corresponding to side TX_A or TX_B respectively.
- """
- wbx_base.__init__(self, usrp, which)
-
- # power up the transmit side, NO -- but set antenna to receive
- self._u.write_io(self._which, (TX_POWER), (TX_POWER|RX_TXN))
- self._lo_offset = 0e6
-
- # Gain is not set by the PGA, but the PGA must be set at max gain in the TX
- return self._set_pga(self._u.pga_max())
-
- def __del__(self):
- # Power down and leave the T/R switch in the R position
- self._u.write_io(self._which, (RX_TXN), (TX_POWER|RX_TXN|TX_ENB_MIX|TX_ENB_VGA))
- wbx_base.__del__(self)
-
- def set_auto_tr(self, on):
- if on:
- self.set_atr_mask (RX_TXN)
- self.set_atr_txval(0)
- self.set_atr_rxval(RX_TXN)
- else:
- self.set_atr_mask (0)
- self.set_atr_txval(0)
- self.set_atr_rxval(0)
-
- def set_enable(self, on):
- """
- Enable transmitter if on is True
- """
- mask = RX_TXN|TX_ENB_MIX|TX_ENB_VGA
- print "HERE!!!!"
- if on:
- self._u.write_io(self._which, TX_ENB_MIX|TX_ENB_VGA, mask)
- else:
- self._u.write_io(self._which, RX_TXN, mask)
-
-
- def set_lo_offset(self, offset):
- """
- Set amount by which LO is offset from requested tuning frequency.
-
- @param offset: offset in Hz
- """
- self._lo_offset = offset
-
- def lo_offset(self):
- """
- Get amount by which LO is offset from requested tuning frequency.
-
- @returns Offset in Hz
- """
- return self._lo_offset
-
-class wbx_base_rx(wbx_base):
- def __init__(self, usrp, which):
- """
- @param usrp: instance of usrp.source_c
- @param which: 0 or 1 corresponding to side RX_A or RX_B respectively.
- """
- wbx_base.__init__(self, usrp, which)
-
- # set up for RX on TX/RX port
- self.select_rx_antenna('TX/RX')
-
- self.bypass_adc_buffers(True)
-
- self._lo_offset = 0.0
-
- def __del__(self):
- # Power down
- self._u.write_io(self._which, 0, (RXENABLE))
- wbx_base.__del__(self)
-
- def set_auto_tr(self, on):
- if on:
- self.set_atr_mask (ENABLE)
- self.set_atr_txval( 0)
- self.set_atr_rxval(ENABLE)
- else:
- self.set_atr_mask (0)
- self.set_atr_txval(0)
- self.set_atr_rxval(0)
-
- def select_rx_antenna(self, which_antenna):
- """
- Specify which antenna port to use for reception.
- @param which_antenna: either 'TX/RX' or 'RX2'
- """
- if which_antenna in (0, 'TX/RX'):
- self._u.write_io(self._which, 0, RX2_RX1N)
- elif which_antenna in (1, 'RX2'):
- self._u.write_io(self._which, RX2_RX1N, RX2_RX1N)
- else:
- raise ValueError, "which_antenna must be either 'TX/RX' or 'RX2'"
-
- def set_gain(self, gain):
- """
- Set the gain.
-
- @param gain: gain in decibels
- @returns True/False
- """
- maxgain = self.gain_range()[1] - self._u.pga_max()
- mingain = self.gain_range()[0]
- if gain > maxgain:
- pga_gain = gain-maxgain
- assert pga_gain <= self._u.pga_max()
- agc_gain = maxgain
- else:
- pga_gain = 0
- agc_gain = gain
- V_maxgain = .2
- V_mingain = 1.2
- V_fullscale = 3.3
- dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale
- assert dac_value>=0 and dac_value<4096
- return self._u.write_aux_dac(self._which, 0, int(dac_value)) and \
- self._set_pga(int(pga_gain))
-
- def set_lo_offset(self, offset):
- """
- Set amount by which LO is offset from requested tuning frequency.
-
- @param offset: offset in Hz
- """
- self._lo_offset = offset
-
- def lo_offset(self):
- """
- Get amount by which LO is offset from requested tuning frequency.
-
- @returns Offset in Hz
- """
- return self._lo_offset
-
-
- def i_and_q_swapped(self):
- """
- Return True if this is a quadrature device and ADC 0 is Q.
- """
- return False
-
-# ----------------------------------------------------------------
-
-class _ADF410X_common(object):
- def __init__(self):
- # R-Register Common Values
- self.R_RSV = 0 # bits 23,22,21
- self.LDP = 1 # bit 20 Lock detect in 5 cycles
- self.TEST = 0 # bit 19,18 Normal
- self.ABP = 0 # bit 17,16 2.9ns
-
- # N-Register Common Values
- self.N_RSV = 0 # 23,22
- self.CP_GAIN = 0 # 21
-
- # Function Register Common Values
- self.P = 0 # bits 23,22 0 = 8/9, 1 = 16/17, 2 = 32/33, 3 = 64/65
- self.PD2 = 0 # bit 21 Normal operation
- self.CP2 = 4 # bits 20,19,18 CP Gain = 5mA
- self.CP1 = 4 # bits 17,16,15 CP Gain = 5mA
- self.TC = 0 # bits 14-11 PFD Timeout
- self.FL = 0 # bit 10,9 Fastlock Disabled
- self.CP3S = 0 # bit 8 CP Enabled
- self.PDP = 0 # bit 7 Phase detector polarity, Positive=1
- self.MUXOUT = 1 # bits 6:4 Digital Lock Detect
- self.PD1 = 0 # bit 3 Normal operation
- self.CR = 0 # bit 2 Normal operation
-
- def _compute_regs(self, freq):
- """
- Determine values of R, control, and N registers, along with actual freq.
-
- @param freq: target frequency in Hz
- @type freq: float
- @returns: (R, N, control, actual_freq)
- @rtype: tuple(int, int, int, float)
- """
-
- # Band-specific N-Register Values
- phdet_freq = self._refclk_freq()/self.R_DIV
- print "phdet_freq = %f" % (phdet_freq,)
- desired_n = round(freq*self.freq_mult/phdet_freq)
- print "desired_n %f" % (desired_n,)
- actual_freq = desired_n * phdet_freq
- print "actual freq %f" % (actual_freq,)
- B = math.floor(desired_n/self._prescaler())
- A = desired_n - self._prescaler()*B
- print "A %d B %d" % (A,B)
- self.B_DIV = int(B) # bits 20:8
- self.A_DIV = int(A) # bit 6:2
- #assert self.B_DIV >= self.A_DIV
- if self.B_DIV < self.A_DIV:
- return (0,0,0,0)
- R = (self.R_RSV<<21) | (self.LDP<<20) | (self.TEST<<18) | \
- (self.ABP<<16) | (self.R_DIV<<2)
-
- N = (self.N_RSV<<22) | (self.CP_GAIN<<21) | (self.B_DIV<<8) | (self.A_DIV<<2)
-
- control = (self.P<<22) | (self.PD2<<21) | (self.CP2<<18) | (self.CP1<<15) | \
- (self.TC<<11) | (self.FL<<9) | (self.CP3S<<8) | (self.PDP<<7) | \
- (self.MUXOUT<<4) | (self.PD1<<3) | (self.CR<<2)
-
- return (R,N,control,actual_freq/self.freq_mult)
-
- def _write_all(self, R, N, control):
- """
- Write all PLL registers:
- R counter latch,
- N counter latch,
- Function latch,
- Initialization latch
-
- Adds 10ms delay between writing control and N if this is first call.
- This is the required power-up sequence.
-
- @param R: 24-bit R counter latch
- @type R: int
- @param N: 24-bit N counter latch
- @type N: int
- @param control: 24-bit control latch
- @type control: int
- """
- self._write_R(R)
- self._write_func(control)
- self._write_init(control)
- if self.first:
- time.sleep(0.010)
- self.first = False
- self._write_N(N)
-
- def _write_R(self, R):
- self._write_it((R & ~0x3) | 0)
-
- def _write_N(self, N):
- self._write_it((N & ~0x3) | 1)
-
- def _write_func(self, func):
- self._write_it((func & ~0x3) | 2)
-
- def _write_init(self, init):
- self._write_it((init & ~0x3) | 3)
-
- def _write_it(self, v):
- s = ''.join((chr((v >> 16) & 0xff),
- chr((v >> 8) & 0xff),
- chr(v & 0xff)))
- self._u._write_spi(0, self.spi_enable, self.spi_format, s)
-
- def _prescaler(self):
- if self.P == 0:
- return 8
- elif self.P == 1:
- return 16
- elif self.P == 2:
- return 32
- elif self.P == 3:
- return 64
- else:
- raise ValueError, "Prescaler out of range"
-
-#----------------------------------------------------------------------
-class _lo_common(_ADF410X_common):
- def __init__(self):
- _ADF410X_common.__init__(self)
-
- # Band-specific R-Register Values
- self.R_DIV = 4 # bits 15:2
-
- # Band-specific C-Register values
- self.P = 0 # bits 23,22 0 = Div by 8/9
- self.CP2 = 4 # bits 19:17
- self.CP1 = 4 # bits 16:14
-
- # Band specifc N-Register Values
- self.DIVSEL = 0 # bit 23
- self.DIV2 = 0 # bit 22
- self.CPGAIN = 0 # bit 21
- self.freq_mult = 1
-
- self.div = 1
- self.aux_div = 2
-
- def freq_range(self): # FIXME
- return (50e6, 1000e6, 16e6)
-
- def set_divider(self, main_or_aux, divisor):
- if main_or_aux not in (0, 'main', 1, 'aux'):
- raise ValueError, "main_or_aux must be 'main' or 'aux'"
- if main_or_aux in (0, 'main'):
- if divisor not in (1,2,4,8):
- raise ValueError, "Main Divider Must be 1, 2, 4, or 8"
- for (div,val) in ((1,0),(2,1),(4,2),(8,3)):
- if(div == divisor):
- self.main_div = val
- else:
- if divisor not in (2,4,8,16):
- raise ValueError, "Aux Divider Must be 2, 4, 8 or 16"
- for (div,val) in ((2,0),(4,1),(8,2),(16,3)):
- if(div == divisor):
- self.aux_div = val
-
- vala = self.main_div*SELA0
- valb = self.aux_div*SELB0
- mask = SELA0|SELA1|SELB0|SELB1
-
- self._rx_write_io(((self.main_div*SELA0) | (self.aux_div*SELB0)),
- (SELA0|SELA1|SELB0|SELB1))
-
- def set_freq(self, freq):
- #freq += self._lo_offset
-
- if(freq < 20e6 or freq > 1200e6):
- raise ValueError, "Requested frequency out of range"
- div = 1
- lo_freq = freq * 2
- while lo_freq < 1e9 and div < 8:
- div = div * 2
- lo_freq = lo_freq * 2
- print "For RF freq of %f, we set DIV=%d and LO Freq=%f" % (freq, div, lo_freq)
- self.set_divider('main', div)
- self.set_divider('aux', div*2)
-
- R, N, control, actual_freq = self._compute_regs(lo_freq)
- print "R %d N %d control %d actual freq %f" % (R,N,control,actual_freq)
- if R==0:
- return(False,0)
- self._write_all(R, N, control)
- return (self._lock_detect(), actual_freq/div/2)
-
-
-#------------------------------------------------------------
-class db_wbx_lo_tx(_lo_common, wbx_base_tx):
- def __init__(self, usrp, which):
- wbx_base_tx.__init__(self, usrp, which)
- _lo_common.__init__(self)
-
- def gain_range(self):
- """
- Return range of gain that can be set by this d'board.
-
- @returns (min_gain, max_gain, step_size)
- Where gains are expressed in decibels (your mileage may vary)
-
- Gain is controlled by a VGA in the output amplifier, not the PGA
- """
- return (-56, 0, 0.1)
-
- def set_gain(self, gain):
- """
- Set the gain.
-
- @param gain: gain in decibels
- @returns True/False
- """
- maxgain = self.gain_range()[1]
- mingain = self.gain_range()[0]
- if gain > maxgain:
- txvga_gain = maxgain
- elif gain < mingain:
- txvga_gain = mingain
- else:
- txvga_gain = gain
-
- V_maxgain = 1.4
- V_mingain = 0.1
- V_fullscale = 3.3
- dac_value = ((txvga_gain-mingain)*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale
- assert dac_value>=0 and dac_value<4096
- print "DAC value %d" % (dac_value,)
- return self._u.write_aux_dac(self._which, 1, int(dac_value))
-
-class db_wbx_lo_rx(_lo_common, wbx_base_rx):
- def __init__(self, usrp, which):
- wbx_base_rx.__init__(self, usrp, which)
- _lo_common.__init__(self)
-
- def gain_range(self):
- """
- Return range of gain that can be set by this d'board.
-
- @returns (min_gain, max_gain, step_size)
- Where gains are expressed in decibels (your mileage may vary)
- """
- return (self._u.pga_min(), self._u.pga_max() + 45, 0.05)
-
-#------------------------------------------------------------
-# hook these daughterboard classes into the auto-instantiation framework
-db_instantiator.add(usrp_dbid.WBX_LO_TX, lambda usrp, which : (db_wbx_lo_tx(usrp, which),))
-db_instantiator.add(usrp_dbid.WBX_LO_RX, lambda usrp, which : (db_wbx_lo_rx(usrp, which),))
-
-
diff --git a/gr-usrp/src/db_xcvr2450.py b/gr-usrp/src/db_xcvr2450.py
deleted file mode 100644
index ec0587635c..0000000000
--- a/gr-usrp/src/db_xcvr2450.py
+++ /dev/null
@@ -1,538 +0,0 @@
-#
-# Copyright 2007 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import usrp1, gru, eng_notation
-import time, math, weakref
-
-from usrpm import usrp_dbid
-import db_base
-import db_instantiator
-from usrpm.usrp_fpga_regs import *
-
-# Convenience function
-n2s = eng_notation.num_to_str
-
-# d'board i/o pin defs
-
-# TX IO Pins
-HB_PA_OFF = (1 << 15) # 5GHz PA, 1 = off, 0 = on
-LB_PA_OFF = (1 << 14) # 2.4GHz PA, 1 = off, 0 = on
-ANTSEL_TX1_RX2 = (1 << 13) # 1 = Ant 1 to TX, Ant 2 to RX
-ANTSEL_TX2_RX1 = (1 << 12) # 1 = Ant 2 to TX, Ant 1 to RX
-TX_EN = (1 << 11) # 1 = TX on, 0 = TX off
-AD9515DIV = (1 << 4) # 1 = Div by 3, 0 = Div by 2
-
-TX_OE_MASK = HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|ANTSEL_TX2_RX1|TX_EN|AD9515DIV
-TX_SAFE_IO = HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|AD9515DIV
-
-# RX IO Pins
-LOCKDET = (1 << 15) # This is an INPUT!!!
-EN = (1 << 14)
-RX_EN = (1 << 13) # 1 = RX on, 0 = RX off
-RX_HP = (1 << 12)
-B1 = (1 << 11)
-B2 = (1 << 10)
-B3 = (1 << 9)
-B4 = (1 << 8)
-B5 = (1 << 7)
-B6 = (1 << 6)
-B7 = (1 << 5)
-RX_OE_MASK = EN|RX_EN|RX_HP|B1|B2|B3|B4|B5|B6|B7
-RX_SAFE_IO = EN
-
-
-# ------------------------------------------------------------------------
-# A few comments about the XCVR2450:
-#
-# It is half-duplex. I.e., transmit and receive are mutually exclusive.
-# There is a single LO for both the Tx and Rx sides.
-# For our purposes the board is always either receiving or transmitting.
-#
-# Each board is uniquely identified by the *USRP hardware* instance and side
-# This dictionary holds a weak reference to existing board controller so it
-# can be created or retrieved as needed.
-
-_xcvr2450_inst = weakref.WeakValueDictionary()
-def _get_or_make_xcvr2450(usrp, which):
- key = (usrp.serial_number(), which)
- if not _xcvr2450_inst.has_key(key):
- print "Creating new xcvr2450 instance"
- inst = xcvr2450(usrp, which)
- _xcvr2450_inst[key] = inst
- else:
- print "Using existing xcvr2450 instance"
- inst = _xcvr2450_inst[key]
- return inst
-
-# ------------------------------------------------------------------------
-# Common, shared object for xcvr2450 board. Transmit and receive classes
-# operate on an instance of this; one instance is created per physical
-# daughterboard.
-
-class xcvr2450(object):
- def __init__(self, usrp, which):
- print "xcvr2450: __init__ with %s: %d" % (usrp.serial_number(), which)
- self.u = usrp
- self.which = which
-
- # Use MSB with no header
- self.spi_format = usrp1.SPI_FMT_MSB | usrp1.SPI_FMT_HDR_0
- self.spi_enable = (usrp1.SPI_ENABLE_RX_A, usrp1.SPI_ENABLE_RX_B)[which]
-
- # Sane defaults
- self.mimo = 1 # 0 = OFF, 1 = ON
- self.int_div = 192 # 128 = min, 255 = max
- self.frac_div = 0 # 0 = min, 65535 = max
- self.highband = 0 # 0 = freq <= 5.4e9, 1 = freq > 5.4e9
- self.five_gig = 0 # 0 = freq <= 3.e9, 1 = freq > 3e9
- self.cp_current = 0 # 0 = 2mA, 1 = 4mA
- self.ref_div = 4 # 1 to 7
- self.rssi_hbw = 0 # 0 = 2 MHz, 1 = 6 MHz
- self.txlpf_bw = 1 # 1 = 12 MHz, 2 = 18 MHz, 3 = 24 MHz
- self.rxlpf_bw = 1 # 0 = 7.5 MHz, 1 = 9.5 MHz, 2 = 14 MHz, 3 = 18 MHz
- self.rxlpf_fine = 2 # 0 = 90%, 1 = 95%, 2 = 100%, 3 = 105%, 4 = 110%
- self.rxvga_ser = 1 # 0 = RXVGA controlled by B7:1, 1 = controlled serially
- self.rssi_range = 1 # 0 = low range (datasheet typo), 1 = high range (0.5V - 2.0V)
- self.rssi_mode = 1 # 0 = enable follows RXHP, 1 = enabled
- self.rssi_mux = 0 # 0 = RSSI, 1 = TEMP
- self.rx_hp_pin = 0 # 0 = Fc set by rx_hpf, 1 = 600 KHz
- self.rx_hpf = 0 # 0 = 100Hz, 1 = 30KHz
- self.rx_ant = 0 # 0 = Ant. #1, 1 = Ant. #2
- self.tx_ant = 0 # 0 = Ant. #1, 1 = Ant. #2
- self.txvga_ser = 1 # 0 = TXVGA controlled by B6:1, 1 = controlled serially
- self.tx_driver_lin = 2 # 0 = 50% (worst linearity), 1 = 63%, 2 = 78%, 3 = 100% (best lin)
- self.tx_vga_lin = 2 # 0 = 50% (worst linearity), 1 = 63%, 2 = 78%, 3 = 100% (best lin)
- self.tx_upconv_lin = 2 # 0 = 50% (worst linearity), 1 = 63%, 2 = 78%, 3 = 100% (best lin)
- self.tx_bb_gain = 3 # 0 = maxgain-5dB, 1 = max-3dB, 2 = max-1.5dB, 3 = max
- self.pabias_delay = 15 # 0 = 0, 15 = 7uS
- self.pabias = 0 # 0 = 0 uA, 63 = 315uA
- self.rx_rf_gain = 0 # 0 = 0dB, 1 = 0dB, 2 = 15dB, 3 = 30dB
- self.rx_bb_gain = 16 # 0 = min, 31 = max (0 - 62 dB)
-
- self.txgain = 63 # 0 = min, 63 = max
-
- # Initialize GPIO and ATR
- self.tx_write_io(TX_SAFE_IO, TX_OE_MASK)
- self.tx_write_oe(TX_OE_MASK, ~0)
- self.tx_set_atr_txval(TX_SAFE_IO)
- self.tx_set_atr_rxval(TX_SAFE_IO)
- self.tx_set_atr_mask(TX_OE_MASK)
- self.rx_write_io(RX_SAFE_IO, RX_OE_MASK)
- self.rx_write_oe(RX_OE_MASK, ~0)
- self.rx_set_atr_rxval(RX_SAFE_IO)
- self.rx_set_atr_txval(RX_SAFE_IO)
- self.rx_set_atr_mask(RX_OE_MASK)
-
- # Initialize chipset
- # TODO: perform reset sequence to ensure power up defaults
- self.set_reg_standby()
- self.set_reg_bandselpll()
- self.set_reg_cal()
- self.set_reg_lpf()
- self.set_reg_rxrssi_ctrl()
- self.set_reg_txlin_gain()
- self.set_reg_pabias()
- self.set_reg_rxgain()
- self.set_reg_txgain()
- self.set_freq(2.45e9)
-
- def __del__(self):
- print "xcvr2450: __del__"
- self.tx_set_atr_txval(TX_SAFE_IO)
- self.tx_set_atr_rxval(TX_SAFE_IO)
- self.rx_set_atr_rxval(RX_SAFE_IO)
- self.rx_set_atr_txval(RX_SAFE_IO)
-
-
- # --------------------------------------------------------------------
- # These methods set the MAX2829 onboard registers over the SPI bus.
- # The SPI format is 18 bits, with the four LSBs holding the register no.
- # Thus, the shift values used here are the D0-D13 values from the data
- # sheet, *plus* four.
-
- # Standby (2)
- def set_reg_standby(self):
- self.reg_standby = (
- (self.mimo<<17) |
- (1<<16) |
- (1<<6) |
- (1<<5) |
- (1<<4) | 2)
- self.send_reg(self.reg_standby)
-
- # Integer-Divider Ratio (3)
- def set_reg_int_divider(self):
- self.reg_int_divider = (
- ((self.frac_div & 0x03)<<16) |
- (self.int_div<<4) | 3)
- self.send_reg(self.reg_int_divider)
-
- # Fractional-Divider Ratio (4)
- def set_reg_frac_divider(self):
- self.reg_frac_divider = ((self.frac_div & 0xfffc)<<2) | 4
- self.send_reg(self.reg_frac_divider)
-
- # Band Select and PLL (5)
- def set_reg_bandselpll(self):
- self.reg_bandselpll = (
- (self.mimo<<17) |
- (1<<16) |
- (1<<15) |
- (1<<11) |
- (self.highband<<10) |
- (self.cp_current<<9) |
- (self.ref_div<<5) |
- (self.five_gig<<4) | 5)
- self.send_reg(self.reg_bandselpll)
-
-
- # Calibration (6)
- def set_reg_cal(self):
- # FIXME do calibration
- self.reg_cal = (1<<14)|6
- self.send_reg(self.reg_cal)
-
-
- # Lowpass Filter (7)
- def set_reg_lpf(self):
- self.reg_lpf = (
- (self.rssi_hbw<<15) |
- (self.txlpf_bw<<10) |
- (self.rxlpf_bw<<9) |
- (self.rxlpf_fine<<4) | 7)
- self.send_reg(self.reg_lpf)
-
-
- # Rx Control/RSSI (8)
- def set_reg_rxrssi_ctrl(self):
- self.reg_rxrssi_ctrl = (
- (self.rxvga_ser<<16) |
- (self.rssi_range<<15) |
- (self.rssi_mode<<14) |
- (self.rssi_mux<<12) |
- (1<<9) |
- (self.rx_hpf<<6) |
- (1<<4) | 8)
- self.send_reg(self.reg_rxrssi_ctrl)
-
-
- # Tx Linearity/Baseband Gain (9)
- def set_reg_txlin_gain(self):
- self.reg_txlin_gain = (
- (self.txvga_ser<<14) |
- (self.tx_driver_lin<<12) |
- (self.tx_vga_lin<<10) |
- (self.tx_upconv_lin<<6) |
- (self.tx_bb_gain<<4) | 9)
- self.send_reg(self.reg_txlin_gain)
-
-
- # PA Bias DAC (10)
- def set_reg_pabias(self):
- self.reg_pabias = (
- (self.pabias_delay<<10) |
- (self.pabias<<4) | 10)
- self.send_reg(self.reg_pabias)
-
-
- # Rx Gain (11)
- def set_reg_rxgain(self):
- self.reg_rxgain = (
- (self.rx_rf_gain<<9) |
- (self.rx_bb_gain<<4) | 11)
- self.send_reg(self.reg_rxgain)
-
-
- # Tx Gain (12)
- def set_reg_txgain(self):
- self.reg_txgain = (self.txgain<<4) | 12
- self.send_reg(self.reg_txgain)
-
-
- # Send register write to SPI
- def send_reg(self, v):
- # Send 24 bits, it keeps last 18 clocked in
- s = ''.join((chr((v >> 16) & 0xff),
- chr((v >> 8) & 0xff),
- chr(v & 0xff)))
- self.u._write_spi(0, self.spi_enable, self.spi_format, s)
- #print "xcvr2450: Setting reg %d to %06X" % ((v&15), v)
-
- # --------------------------------------------------------------------
- # These methods control the GPIO bus. Since the board has to access
- # both the io_rx_* and io_tx_* pins, we define our own methods to do so.
- # This bypasses any code in db_base.
- #
- # The board operates in ATR mode, always. Thus, when the board is first
- # initialized, it is in receive mode, until bits show up in the TX FIFO.
- #
- def tx_write_oe(self, value, mask):
- return self.u._write_fpga_reg((FR_OE_0, FR_OE_2)[self.which],
- gru.hexint((mask << 16) | value))
-
- def tx_write_io(self, value, mask):
- return self.u._write_fpga_reg((FR_IO_0, FR_IO_2)[self.which],
- gru.hexint((mask << 16) | value))
-
- def tx_read_io(self):
- t = self.u._read_fpga_reg((FR_RB_IO_RX_A_IO_TX_A, FR_RB_IO_RX_B_IO_TX_B)[self.which])
- return t & 0xffff
-
-
- def rx_write_oe(self, value, mask):
- return self.u._write_fpga_reg((FR_OE_1, FR_OE_3)[self.which],
- gru.hexint((mask << 16) | value))
-
- def rx_write_io(self, value, mask):
- return self.u._write_fpga_reg((FR_IO_1, FR_IO_3)[self.which],
- gru.hexint((mask << 16) | value))
-
- def rx_read_io(self):
- t = self.u._read_fpga_reg((FR_RB_IO_RX_A_IO_TX_A, FR_RB_IO_RX_B_IO_TX_B)[self.which])
- return (t >> 16) & 0xffff
-
- def tx_set_atr_mask(self, v):
- return self.u._write_fpga_reg((FR_ATR_MASK_0,FR_ATR_MASK_2)[self.which],
- gru.hexint(v))
-
- def tx_set_atr_txval(self, v):
- return self.u._write_fpga_reg((FR_ATR_TXVAL_0,FR_ATR_TXVAL_2)[self.which],
- gru.hexint(v))
-
- def tx_set_atr_rxval(self, v):
- return self.u._write_fpga_reg((FR_ATR_RXVAL_0,FR_ATR_RXVAL_2)[self.which],
- gru.hexint(v))
-
- def rx_set_atr_mask(self, v):
- return self.u._write_fpga_reg((FR_ATR_MASK_1,FR_ATR_MASK_3)[self.which],
- gru.hexint(v))
-
- def rx_set_atr_txval(self, v):
- return self.u._write_fpga_reg((FR_ATR_TXVAL_1,FR_ATR_TXVAL_3)[self.which],
- gru.hexint(v))
-
- def rx_set_atr_rxval(self, v):
- return self.u._write_fpga_reg((FR_ATR_RXVAL_1,FR_ATR_RXVAL_3)[self.which],
- gru.hexint(v))
-
- def set_gpio(self):
- # We calculate four values:
- #
- # io_rx_while_rx: what to drive onto io_rx_* when receiving
- # io_rx_while_tx: what to drive onto io_rx_* when transmitting
- # io_tx_while_rx: what to drive onto io_tx_* when receiving
- # io_tx_while_tx: what to drive onto io_tx_* when transmitting
- #
- # B1-B7 is ignored as gain is set serially for now.
-
- rx_hp = (0, RX_HP)[self.rx_hp_pin]
- tx_antsel = (ANTSEL_TX1_RX2, ANTSEL_TX2_RX1)[self.tx_ant]
- rx_antsel = (ANTSEL_TX1_RX2, ANTSEL_TX2_RX1)[self.rx_ant]
- tx_pa_sel = (HB_PA_OFF, LB_PA_OFF)[self.five_gig]
- io_rx_while_rx = EN|rx_hp|RX_EN
- io_rx_while_tx = EN|rx_hp
- io_tx_while_rx = HB_PA_OFF|LB_PA_OFF|rx_antsel|AD9515DIV
- io_tx_while_tx = tx_pa_sel|tx_antsel|TX_EN|AD9515DIV
- self.rx_set_atr_rxval(io_rx_while_rx)
- self.rx_set_atr_txval(io_rx_while_tx)
- self.tx_set_atr_rxval(io_tx_while_rx)
- self.tx_set_atr_txval(io_tx_while_tx)
-
- #print "GPIO: RXRX=%04X RXTX=%04X TXRX=%04X TXTX=%04X" % (
- #io_rx_while_rx, io_rx_while_tx, io_tx_while_rx, io_tx_while_tx)
-
- # --------------------------------------------------------------------
- # These methods set control the high-level operating parameters.
-
- def set_freq(self, target_freq):
- if target_freq > 3e9:
- self.five_gig = 1
- self.ref_div = 1
- self.ad9515_div = 3
- scaler = 4.0/5.0
- else:
- self.five_gig = 0
- self.ref_div = 1
- self.ad9515_div = 3
- scaler = 4.0/3.0;
-
- if target_freq > 5.275e9:
- self.highband = 1
- else:
- self.highband = 0
-
- vco_freq = target_freq*scaler;
- sys_clk = self.u.fpga_master_clock_freq() # Usually 64e6
- ref_clk = sys_clk / self.ad9515_div
-
- phdet_freq = ref_clk/self.ref_div
- div = vco_freq/phdet_freq
- self.int_div = int(math.floor(div))
- self.frac_div = int((div-self.int_div)*65536.0)
- actual_freq = phdet_freq*(self.int_div+(self.frac_div/65536.0))/scaler
-
- #print "RF=%s VCO=%s R=%d PHD=%s DIV=%3.5f I=%3d F=%5d ACT=%s" % (
- # n2s(target_freq), n2s(vco_freq), self.ref_div, n2s(phdet_freq),
- # div, self.int_div, self.frac_div, n2s(actual_freq))
-
- self.set_gpio()
- self.set_reg_int_divider()
- self.set_reg_frac_divider()
- self.set_reg_bandselpll()
-
- ok = self.lock_detect()
- #if(not ok):
- # ok = self.lock_detect()
- # if ok:
- # print "lock detect on 2nd try %f" % (target_freq,)
-
- if(not ok):
- if (target_freq > 5.275e9) and (target_freq <= 5.35e9):
- self.highband = 0
- self.set_reg_bandselpll()
- ok = self.lock_detect()
- print "swap to 0 at %f, ok %d" % (target_freq,ok)
- if (target_freq >= 5.25e9) and (target_freq <= 5.275e9):
- self.highband = 1
- self.set_reg_bandselpll()
- ok = self.lock_detect()
- print "swap to 1 at %f, ok %d" % (target_freq,ok)
-
- if(not ok):
- print "Fail %f" % (target_freq,)
- return (ok, actual_freq)
-
- def lock_detect(self):
- """
- @returns: the value of the VCO/PLL lock detect bit.
- @rtype: 0 or 1
- """
- if self.rx_read_io() & LOCKDET:
- return True
- else: # Give it a second chance
- if self.rx_read_io() & LOCKDET:
- return True
- else:
- return False
-
- def set_rx_gain(self, gain):
- if gain < 0.0: gain = 0.0
- if gain > 92.0: gain = 92.0
-
- # Split the gain between RF and baseband
- # This is experimental, not prescribed
- if gain < 31.0:
- self.rx_rf_gain = 0 # 0 dB RF gain
- self.rx_bb_gain = int(gain/2.0)
-
- if gain >= 30.0 and gain < 60.5:
- self.rx_rf_gain = 2 # 15 dB RF gain
- self.rx_bb_gain = int((gain-15.0)/2.0)
-
- if gain >= 60.5:
- self.rx_rf_gain = 3 # 30.5 dB RF gain
- self.rx_bb_gain = int((gain-30.5)/2.0)
-
- self.set_reg_rxgain()
-
- def set_tx_gain(self, gain):
- if gain < 0.0: gain = 0.0
- if gain > 30.0: gain = 30.0
- self.txgain = int((gain/30.0)*63)
- self.set_reg_txgain()
-
-class db_xcvr2450_base(db_base.db_base):
- """
- Abstract base class for all xcvr2450 boards.
-
- Derive board specific subclasses from db_xcvr2450_base_{tx,rx}
- """
- def __init__(self, usrp, which):
- """
- @param usrp: instance of usrp.source_c
- @param which: which side: 0 or 1 corresponding to side A or B respectively
- @type which: int
- """
- # sets _u _which _tx and _slot
- db_base.db_base.__init__(self, usrp, which)
- self.xcvr = _get_or_make_xcvr2450(usrp, which)
-
- def set_freq(self, target_freq):
- """
- @returns (ok, actual_baseband_freq) where:
- ok is True or False and indicates success or failure,
- actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
- """
- return self.xcvr.set_freq(target_freq)
-
- def is_quadrature(self):
- """
- Return True if this board requires both I & Q analog channels.
-
- This bit of info is useful when setting up the USRP Rx mux register.
- """
- return True
-
- def freq_range(self):
- return (2.4e9, 6e9, 1e6)
-
- def set_freq(self, target_freq):
- return self.xcvr.set_freq(target_freq)
-
-# ----------------------------------------------------------------
-
-class db_xcvr2450_tx(db_xcvr2450_base):
- def __init__(self, usrp, which):
- """
- @param usrp: instance of usrp.sink_c
- @param which: 0 or 1 corresponding to side TX_A or TX_B respectively.
- """
- print "db_xcvr2450_tx: __init__"
- db_xcvr2450_base.__init__(self, usrp, which)
-
- def gain_range(self):
- return (0, 30, (30.0/63.0))
-
- def set_gain(self, gain):
- return self.xcvr.set_tx_gain(gain)
-
- def i_and_q_swapped(self):
- return True
-
-class db_xcvr2450_rx(db_xcvr2450_base):
- def __init__(self, usrp, which):
- """
- @param usrp: instance of usrp.source_c
- @param which: 0 or 1 corresponding to side RX_A or RX_B respectively.
- """
- print "db_xcvr2450_rx: __init__"
- db_xcvr2450_base.__init__(self, usrp, which)
-
- def gain_range(self):
- return (0.0, 92.0, 1)
-
- def set_gain(self, gain):
- return self.xcvr.set_rx_gain(gain)
-
-#------------------------------------------------------------
-# hook these daughterboard classes into the auto-instantiation framework
-db_instantiator.add(usrp_dbid.XCVR2450_TX, lambda usrp, which : (db_xcvr2450_tx(usrp, which),))
-db_instantiator.add(usrp_dbid.XCVR2450_RX, lambda usrp, which : (db_xcvr2450_rx(usrp, which),))
diff --git a/gr-usrp/src/qa_usrp.py b/gr-usrp/src/qa_usrp.py
index 99d1cfa6fe..db2d32624a 100755
--- a/gr-usrp/src/qa_usrp.py
+++ b/gr-usrp/src/qa_usrp.py
@@ -21,7 +21,7 @@
#
from gnuradio import gr, gr_unittest
-import usrp1
+import usrp_swig
class qa_usrp (gr_unittest.TestCase):
diff --git a/gr-usrp/src/usrp.i b/gr-usrp/src/usrp.i
new file mode 100644
index 0000000000..40fa471b01
--- /dev/null
+++ b/gr-usrp/src/usrp.i
@@ -0,0 +1,144 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%feature("autodoc", "1"); // generate python docstrings
+
+%include "exception.i"
+%import "gnuradio.i" // the common stuff
+
+%{
+#include "gnuradio_swig_bug_workaround.h" // mandatory bug fix
+#include <stdexcept>
+#include <vector>
+%}
+
+%include <usrp_subdev_spec.h>
+%include <db_base.i>
+%include <fpga_regs_common.h>
+%include <fpga_regs_standard.h>
+%include "usrp_standard.i"
+%include "usrp_base.i"
+%include "usrp_source_base.i"
+%include "usrp_source_c.i"
+%include "usrp_source_s.i"
+%include "usrp_sink_base.i"
+%include "usrp_sink_c.i"
+%include "usrp_sink_s.i"
+
+//---Allow a more Pythonic interface
+%pythoncode %{
+
+# Allow subdev_spec to be tuple
+def __selected_subdev(self, subdev_spec):
+ ss = usrp_subdev_spec(subdev_spec[0], subdev_spec[1])
+ return self._real_selected_subdev(ss)
+
+# Allow subdev_spec to be tuple
+def __determine_tx_mux_value(self, subdev_spec):
+ ss = usrp_subdev_spec(subdev_spec[0], subdev_spec[1])
+ return self._real_determine_tx_mux_value(ss)
+
+# Allow subdev_spec to be tuple
+def __determine_rx_mux_value(self, subdev_spec):
+ ss = usrp_subdev_spec(subdev_spec[0], subdev_spec[1])
+ return self._real_determine_rx_mux_value(ss)
+
+# Allow subdev_spec to be tuple
+def __pick_subdev(self, candidates=[]):
+ ss = self._real_pick_subdev(candidates)
+ return (ss.side, ss.subdev)
+
+# Allow subdev_spec to be tuple
+def __pick_tx_subdevice(self):
+ ss = self._real_pick_tx_subdevice()
+ return (ss.side, ss.subdev)
+
+# Allow subdev_spec to be tuple
+def __pick_rx_subdevice(self):
+ ss = self._real_pick_rx_subdevice()
+ return (ss.side, ss.subdev)
+
+# Make return tune_result or None on failure
+def __tune(self, chan, db, target_freq):
+ tr = usrp_tune_result()
+ r = self._real_tune(chan, db, target_freq, tr)
+ if r:
+ return tr
+ else:
+ return None
+
+# Allow to be called as a free function
+def tune(u, chan, subdev, target_freq):
+ return u.tune(chan, subdev, target_freq)
+
+# Allow to be called as free function
+def determine_tx_mux_value(u, subdev_spec):
+ return u.determine_tx_mux_value(subdev_spec)
+
+# Allow to be called as free function
+def determine_rx_mux_value(u, subdev_spec):
+ return u.determine_rx_mux_value(subdev_spec)
+
+# Allow to be called as free function
+def selected_subdev(u, subdev_spec):
+ return u.selected_subdev(subdev_spec)
+
+# Allow to be called as free function
+def pick_subdev(u, candidates=[]):
+ return u.pick_subdev(candidates);
+
+# Allow to be called as free function
+def pick_tx_subdevice(u):
+ return u.pick_tx_subdevice();
+
+# Allow to be called as free function
+def pick_rx_subdevice(u):
+ return u.pick_rx_subdevice();
+
+# Jam into Python objects
+usrp_sink_c_sptr.determine_tx_mux_value = __determine_tx_mux_value
+usrp_sink_s_sptr.determine_tx_mux_value = __determine_tx_mux_value
+
+usrp_source_c_sptr.determine_rx_mux_value = __determine_rx_mux_value
+usrp_source_s_sptr.determine_rx_mux_value = __determine_rx_mux_value
+
+usrp_sink_c_sptr.selected_subdev = __selected_subdev
+usrp_sink_s_sptr.selected_subdev = __selected_subdev
+usrp_source_c_sptr.selected_subdev = __selected_subdev
+usrp_source_s_sptr.selected_subdev = __selected_subdev
+
+usrp_sink_c_sptr.tune = __tune
+usrp_sink_s_sptr.tune = __tune
+usrp_source_c_sptr.tune = __tune
+usrp_source_s_sptr.tune = __tune
+
+usrp_sink_c_sptr.pick_subdev = __pick_subdev
+usrp_sink_s_sptr.pick_subdev = __pick_subdev
+usrp_source_c_sptr.pick_subdev = __pick_subdev
+usrp_source_s_sptr.pick_subdev = __pick_subdev
+
+usrp_sink_c_sptr.pick_tx_subdevice = __pick_tx_subdevice
+usrp_sink_s_sptr.pick_tx_subdevice = __pick_tx_subdevice
+usrp_source_c_sptr.pick_rx_subdevice = __pick_rx_subdevice
+usrp_source_s_sptr.pick_rx_subdevice = __pick_rx_subdevice
+
+%}
diff --git a/gr-usrp/src/usrp.py b/gr-usrp/src/usrp.py
deleted file mode 100644
index 0fe6a2c478..0000000000
--- a/gr-usrp/src/usrp.py
+++ /dev/null
@@ -1,482 +0,0 @@
-#
-# Copyright 2004,2005,2007 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 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.
-#
-
-
-
-from usrpm import usrp_prims
-from usrpm import usrp_dbid
-from gnuradio import usrp1 # usrp Rev 1 and later
-from gnuradio import gru
-from usrpm.usrp_fpga_regs import *
-import weakref
-
-FPGA_MODE_NORMAL = usrp1.FPGA_MODE_NORMAL
-FPGA_MODE_LOOPBACK = usrp1.FPGA_MODE_LOOPBACK
-FPGA_MODE_COUNTING = usrp1.FPGA_MODE_COUNTING
-
-SPI_FMT_xSB_MASK = usrp1.SPI_FMT_xSB_MASK
-SPI_FMT_LSB = usrp1.SPI_FMT_LSB
-SPI_FMT_MSB = usrp1.SPI_FMT_MSB
-SPI_FMT_HDR_MASK = usrp1.SPI_FMT_HDR_MASK
-SPI_FMT_HDR_0 = usrp1.SPI_FMT_HDR_0
-SPI_FMT_HDR_1 = usrp1.SPI_FMT_HDR_1
-SPI_FMT_HDR_2 = usrp1.SPI_FMT_HDR_2
-
-SPI_ENABLE_FPGA = usrp1.SPI_ENABLE_FPGA
-SPI_ENABLE_CODEC_A = usrp1.SPI_ENABLE_CODEC_A
-SPI_ENABLE_CODEC_B = usrp1.SPI_ENABLE_CODEC_B
-SPI_ENABLE_reserved = usrp1.SPI_ENABLE_reserved
-SPI_ENABLE_TX_A = usrp1.SPI_ENABLE_TX_A
-SPI_ENABLE_RX_A = usrp1.SPI_ENABLE_RX_A
-SPI_ENABLE_TX_B = usrp1.SPI_ENABLE_TX_B
-SPI_ENABLE_RX_B = usrp1.SPI_ENABLE_RX_B
-
-
-# Import all the daughterboard classes we know about.
-# This hooks them into the auto-instantiation framework.
-
-import db_instantiator
-
-import db_basic
-import db_dbs_rx
-import db_flexrf
-import db_flexrf_mimo
-import db_tv_rx
-import db_wbx
-import db_xcvr2450
-import db_dtt754
-import db_dtt768
-
-def _look_for_usrp(which):
- """
- Try to open the specified usrp.
-
- @param which: int >= 0 specifying which USRP to open
- @type which: int
-
- @return: Returns version number, or raises RuntimeError
- @rtype: int
- """
- d = usrp_prims.usrp_find_device(which)
- if not d:
- raise RuntimeError, "Unable to find USRP #%d" % (which,)
-
- return usrp_prims.usrp_hw_rev(d)
-
-
-def _ensure_rev2(which):
- v = _look_for_usrp(which)
- if not v in (2, 4):
- raise RuntimeError, "Sorry, unsupported USRP revision (rev=%d)" % (v,)
-
-
-class tune_result(object):
- """
- Container for intermediate tuning information.
- """
- def __init__(self, baseband_freq, dxc_freq, residual_freq, inverted):
- self.baseband_freq = baseband_freq
- self.dxc_freq = dxc_freq
- self.residual_freq = residual_freq
- self.inverted = inverted
-
-
-def tune(u, chan, subdev, target_freq):
- """
- Set the center frequency we're interested in.
-
- @param u: instance of usrp.source_* or usrp.sink_*
- @param chan: DDC/DUC channel
- @type chan: int
- @param subdev: daughterboard subdevice
- @param target_freq: frequency in Hz
- @returns False if failure else tune_result
-
- Tuning is a two step process. First we ask the front-end to
- tune as close to the desired frequency as it can. Then we use
- the result of that operation and our target_frequency to
- determine the value for the digital down converter.
- """
-
- # Does this usrp instance do Tx or Rx?
- rx_p = True
- try:
- u.rx_freq
- except AttributeError:
- rx_p = False
-
- ok, baseband_freq = subdev.set_freq(target_freq)
- dxc_freq, inverted = calc_dxc_freq(target_freq, baseband_freq, u.converter_rate())
-
- # If the spectrum is inverted, and the daughterboard doesn't do
- # quadrature downconversion, we can fix the inversion by flipping the
- # sign of the dxc_freq... (This only happens using the basic_rx board)
-
- if subdev.spectrum_inverted():
- inverted = not(inverted)
-
- if inverted and not(subdev.is_quadrature()):
- dxc_freq = -dxc_freq
- inverted = not(inverted)
-
- if rx_p:
- ok = ok and u.set_rx_freq(chan, dxc_freq)
- else:
- dxc_freq = -dxc_freq
- ok = ok and u.set_tx_freq(chan, dxc_freq)
-
- if not(ok):
- return False
-
- # residual_freq is the offset left over because of dxc tuning step size
- if rx_p:
- residual_freq = dxc_freq - u.rx_freq(chan)
- else:
- residual_freq = dxc_freq - u.tx_freq(chan)
-
- return tune_result(baseband_freq, dxc_freq, residual_freq, inverted)
-
-
-# ------------------------------------------------------------------------
-# Build subclasses of raw usrp1.* class that add the db attribute
-# by automatically instantiating the appropriate daughterboard classes.
-# [Also provides keyword args.]
-# ------------------------------------------------------------------------
-
-class usrp_common(object):
- def __init__(self):
- # read capability register
- r = self._u._read_fpga_reg(FR_RB_CAPS)
- if r < 0:
- r += 2**32
- if r == 0xaa55ff77: # value of this reg prior to being defined as cap reg
- r = ((2 << bmFR_RB_CAPS_NDUC_SHIFT)
- | (2 << bmFR_RB_CAPS_NDDC_SHIFT)
- | bmFR_RB_CAPS_RX_HAS_HALFBAND)
- self._fpga_caps = r
-
- if False:
- print "FR_RB_CAPS = %#08x" % (self._fpga_caps,)
- print "has_rx_halfband =", self.has_rx_halfband()
- print "nDDCs =", self.nddc()
- print "has_tx_halfband =", self.has_tx_halfband()
- print "nDUCs =", self.nduc()
-
- def __getattr__(self, name):
- return getattr(self._u, name)
-
- def tune(self, chan, subdev, target_freq):
- return tune(self, chan, subdev, target_freq)
-
- def has_rx_halfband(self):
- return self._fpga_caps & bmFR_RB_CAPS_RX_HAS_HALFBAND != 0
-
- def has_tx_halfband(self):
- return self._fpga_caps & bmFR_RB_CAPS_TX_HAS_HALFBAND != 0
-
- def nddc(self):
- """
- Number of Digital Down Converters implemented in FPGA
- """
- return (self._fpga_caps & bmFR_RB_CAPS_NDDC_MASK) >> bmFR_RB_CAPS_NDDC_SHIFT
-
- def nduc(self):
- """
- Number of Digital Up Converters implemented in FPGA
- """
- return (self._fpga_caps & bmFR_RB_CAPS_NDUC_MASK) >> bmFR_RB_CAPS_NDUC_SHIFT
-
-
-class sink_c(usrp_common):
- def __init__(self, which=0, interp_rate=128, nchan=1, mux=0x98,
- fusb_block_size=0, fusb_nblocks=0,
- fpga_filename="", firmware_filename=""):
- _ensure_rev2(which)
- self._u = usrp1.sink_c(which, interp_rate, nchan, mux,
- fusb_block_size, fusb_nblocks,
- fpga_filename, firmware_filename)
- # Add the db attribute, which contains a 2-tuple of tuples of daughterboard classes
- self.db = (db_instantiator.instantiate(self._u, 0),
- db_instantiator.instantiate(self._u, 1))
- usrp_common.__init__(self)
-
- def __del__(self):
- self.db = None # will fire d'board destructors
- self._u = None # will fire usrp1.* destructor
-
-
-class sink_s(usrp_common):
- def __init__(self, which=0, interp_rate=128, nchan=1, mux=0x98,
- fusb_block_size=0, fusb_nblocks=0,
- fpga_filename="", firmware_filename=""):
- _ensure_rev2(which)
- self._u = usrp1.sink_s(which, interp_rate, nchan, mux,
- fusb_block_size, fusb_nblocks,
- fpga_filename, firmware_filename)
- # Add the db attribute, which contains a 2-tuple of tuples of daughterboard classes
- self.db = (db_instantiator.instantiate(self._u, 0),
- db_instantiator.instantiate(self._u, 1))
- usrp_common.__init__(self)
-
- def __del__(self):
- self.db = None # will fire d'board destructors
- self._u = None # will fire usrp1.* destructor
-
-
-class source_c(usrp_common):
- def __init__(self, which=0, decim_rate=64, nchan=1, mux=0x32103210, mode=0,
- fusb_block_size=0, fusb_nblocks=0,
- fpga_filename="", firmware_filename=""):
- _ensure_rev2(which)
- self._u = usrp1.source_c(which, decim_rate, nchan, mux, mode,
- fusb_block_size, fusb_nblocks,
- fpga_filename, firmware_filename)
- # Add the db attribute, which contains a 2-tuple of tuples of daughterboard classes
- self.db = (db_instantiator.instantiate(self._u, 0),
- db_instantiator.instantiate(self._u, 1))
- usrp_common.__init__(self)
-
- def __del__(self):
- self.db = None # will fire d'board destructors
- self._u = None # will fire usrp1.* destructor
-
-
-class source_s(usrp_common):
- def __init__(self, which=0, decim_rate=64, nchan=1, mux=0x32103210, mode=0,
- fusb_block_size=0, fusb_nblocks=0,
- fpga_filename="", firmware_filename=""):
- _ensure_rev2(which)
- self._u = usrp1.source_s(which, decim_rate, nchan, mux, mode,
- fusb_block_size, fusb_nblocks,
- fpga_filename, firmware_filename)
- # Add the db attribute, which contains a 2-tuple of tuples of daughterboard classes
- self.db = (db_instantiator.instantiate(self._u, 0),
- db_instantiator.instantiate(self._u, 1))
- usrp_common.__init__(self)
-
- def __del__(self):
- self.db = None # will fire d'board destructors
- self._u = None # will fire usrp1.* destructor
-
-
-# ------------------------------------------------------------------------
-# utilities
-# ------------------------------------------------------------------------
-
-def determine_rx_mux_value(u, subdev_spec):
- """
- Determine appropriate Rx mux value as a function of the subdevice choosen and the
- characteristics of the respective daughterboard.
-
- @param u: instance of USRP source
- @param subdev_spec: return value from subdev option parser.
- @type subdev_spec: (side, subdev), where side is 0 or 1 and subdev is 0 or 1
- @returns: the Rx mux value
- """
- # Figure out which A/D's to connect to the DDC.
- #
- # Each daughterboard consists of 1 or 2 subdevices. (At this time,
- # all but the Basic Rx have a single subdevice. The Basic Rx
- # has two independent channels, treated as separate subdevices).
- # subdevice 0 of a daughterboard may use 1 or 2 A/D's. We determine this
- # by checking the is_quadrature() method. If subdevice 0 uses only a single
- # A/D, it's possible that the daughterboard has a second subdevice, subdevice 1,
- # and it uses the second A/D.
- #
- # If the card uses only a single A/D, we wire a zero into the DDC Q input.
- #
- # (side, 0) says connect only the A/D's used by subdevice 0 to the DDC.
- # (side, 1) says connect only the A/D's used by subdevice 1 to the DDC.
- #
-
- side = subdev_spec[0] # side A = 0, side B = 1
-
- if not(side in (0, 1)):
- raise ValueError, "Invalid subdev_spec: %r:" % (subdev_spec,)
-
- db = u.db[side] # This is a tuple of length 1 or 2 containing the subdevice
- # classes for the selected side.
-
- # compute bitmasks of used A/D's
-
- if db[0].is_quadrature():
- subdev0_uses = 0x3 # uses A/D 0 and 1
- else:
- subdev0_uses = 0x1 # uses A/D 0 only
-
- if len(db) > 1:
- subdev1_uses = 0x2 # uses A/D 1 only
- else:
- subdev1_uses = 0x0 # uses no A/D (doesn't exist)
-
- if subdev_spec[1] == 0:
- uses = subdev0_uses
- elif subdev_spec[1] == 1:
- uses = subdev1_uses
- else:
- raise ValueError, "Invalid subdev_spec: %r: " % (subdev_spec,)
-
- if uses == 0:
- raise RuntimeError, "Daughterboard doesn't have a subdevice 1: %r: " % (subdev_spec,)
-
- swap_iq = db[0].i_and_q_swapped()
-
- truth_table = {
- # (side, uses, swap_iq) : mux_val
- (0, 0x1, False) : 0xf0f0f0f0,
- (0, 0x2, False) : 0xf0f0f0f1,
- (0, 0x3, False) : 0x00000010,
- (0, 0x3, True) : 0x00000001,
- (1, 0x1, False) : 0xf0f0f0f2,
- (1, 0x2, False) : 0xf0f0f0f3,
- (1, 0x3, False) : 0x00000032,
- (1, 0x3, True) : 0x00000023
- }
-
- return gru.hexint(truth_table[(side, uses, swap_iq)])
-
-
-def determine_tx_mux_value(u, subdev_spec):
- """
- Determine appropriate Tx mux value as a function of the subdevice choosen.
-
- @param u: instance of USRP source
- @param subdev_spec: return value from subdev option parser.
- @type subdev_spec: (side, subdev), where side is 0 or 1 and subdev is 0
- @returns: the Rx mux value
- """
- # This is simpler than the rx case. Either you want to talk
- # to side A or side B. If you want to talk to both sides at once,
- # determine the value manually.
-
- side = subdev_spec[0] # side A = 0, side B = 1
- if not(side in (0, 1)):
- raise ValueError, "Invalid subdev_spec: %r:" % (subdev_spec,)
-
- db = u.db[side]
-
- if(db[0].i_and_q_swapped()):
- return gru.hexint([0x0089, 0x8900][side])
- else:
- return gru.hexint([0x0098, 0x9800][side])
-
-
-def selected_subdev(u, subdev_spec):
- """
- Return the user specified daughterboard subdevice.
-
- @param u: an instance of usrp.source_* or usrp.sink_*
- @param subdev_spec: return value from subdev option parser.
- @type subdev_spec: (side, subdev), where side is 0 or 1 and subdev is 0 or 1
- @returns: an weakref to an instance derived from db_base
- """
- side, subdev = subdev_spec
- # Note: This allows db to go out of scope at the right time
- return weakref.proxy(u.db[side][subdev])
-
-
-def calc_dxc_freq(target_freq, baseband_freq, fs):
- """
- Calculate the frequency to use for setting the digital up or down converter.
-
- @param target_freq: desired RF frequency (Hz)
- @type target_freq: number
- @param baseband_freq: the RF frequency that corresponds to DC in the IF.
- @type baseband_freq: number
- @param fs: converter sample rate
- @type fs: number
-
- @returns: 2-tuple (ddc_freq, inverted) where ddc_freq is the value
- for the ddc and inverted is True if we're operating in an inverted
- Nyquist zone.
- """
-
- delta = target_freq - baseband_freq
-
- if delta >= 0:
- while delta > fs:
- delta -= fs
- if delta <= fs/2:
- return (-delta, False) # non-inverted region
- else:
- return (delta - fs, True) # inverted region
- else:
- while delta < -fs:
- delta += fs
- if delta >= -fs/2:
- return (-delta, False) # non-inverted region
- else:
- return (delta + fs, True) # inverted region
-
-
-# ------------------------------------------------------------------------
-# Utilities
-# ------------------------------------------------------------------------
-
-def pick_tx_subdevice(u):
- """
- The user didn't specify a tx subdevice on the command line.
- Try for one of these, in order: FLEX_400, FLEX_900, FLEX_1200, FLEX_2400,
- BASIC_TX, whatever's on side A.
-
- @return a subdev_spec
- """
- return pick_subdev(u, (usrp_dbid.FLEX_400_TX,
- usrp_dbid.FLEX_900_TX,
- usrp_dbid.FLEX_1200_TX,
- usrp_dbid.FLEX_2400_TX,
- usrp_dbid.BASIC_TX))
-
-def pick_rx_subdevice(u):
- """
- The user didn't specify an rx subdevice on the command line.
- Try for one of these, in order: FLEX_400, FLEX_900, FLEX_1200, FLEX_2400,
- TV_RX, DBS_RX, BASIC_RX, whatever's on side A.
-
- @return a subdev_spec
- """
- return pick_subdev(u, (usrp_dbid.FLEX_400_RX,
- usrp_dbid.FLEX_900_RX,
- usrp_dbid.FLEX_1200_RX,
- usrp_dbid.FLEX_2400_RX,
- usrp_dbid.TV_RX,
- usrp_dbid.TV_RX_REV_2,
- usrp_dbid.DBS_RX,
- usrp_dbid.DBS_RX_REV_2_1,
- usrp_dbid.BASIC_RX))
-
-def pick_subdev(u, candidates):
- """
- @param u: usrp instance
- @param candidates: list of dbids
- @returns: subdev specification
- """
- db0 = u.db[0][0].dbid()
- db1 = u.db[1][0].dbid()
- for c in candidates:
- if c == db0: return (0, 0)
- if c == db1: return (1, 0)
- if db0 >= 0:
- return (0, 0)
- if db1 >= 0:
- return (1, 0)
- raise RuntimeError, "No suitable daughterboard found!"
-
diff --git a/gr-usrp/src/usrp1.i b/gr-usrp/src/usrp1.i
deleted file mode 100644
index 24d229f510..0000000000
--- a/gr-usrp/src/usrp1.i
+++ /dev/null
@@ -1,657 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 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.
- */
-
-%feature("autodoc", "1"); // generate python docstrings
-
-%include "exception.i"
-%import "gnuradio.i" // the common stuff
-
-%{
-
-#include "gnuradio_swig_bug_workaround.h" // mandatory bug fix
-#include "usrp1_sink_c.h"
-#include "usrp1_sink_s.h"
-#include "usrp1_source_c.h"
-#include "usrp1_source_s.h"
-#include <stdexcept>
-#include <usrp_standard.h>
-#include <usrp_spi_defs.h>
-%}
-
-%include <usrp_spi_defs.h>
-
-%constant int FPGA_MODE_NORMAL = usrp_standard_rx::FPGA_MODE_NORMAL;
-%constant int FPGA_MODE_LOOPBACK = usrp_standard_rx::FPGA_MODE_LOOPBACK;
-%constant int FPGA_MODE_COUNTING = usrp_standard_rx::FPGA_MODE_COUNTING;
-
-// ================================================================
-// abstract classes
-// ================================================================
-
-class usrp1_sink_base : public gr_sync_block {
-protected:
- usrp1_sink_base (const std::string &name,
- gr_io_signature_sptr input_signature,
- int which_board,
- unsigned int interp_rate,
- int nchan,
- int mux,
- int fusb_block_size,
- int fusb_nblocks,
- const std::string fpga_filename,
- const std::string firmware_filename
- ) throw (std::runtime_error);
-
- virtual void copy_to_usrp_buffer (gr_vector_const_void_star &input_items,
- int input_index,
- int input_items_available,
- int &input_items_consumed,
- void *usrp_buffer,
- int usrp_buffer_length,
- int &bytes_written) = 0;
- public:
- ~usrp1_sink_base ();
-
- /*!
- * \brief Set interpolator rate. \p rate must be in [4, 1024] and a multiple of 4.
- *
- * The final complex sample rate across the USB is
- * dac_freq () * nchannels () / interp_rate ()
- */
- bool set_interp_rate (unsigned int rate);
- bool set_nchannels (int nchan);
- bool set_mux (int mux);
-
- /*!
- * \brief set the frequency of the digital up converter.
- *
- * \p channel must be 0 or 1. \p freq is the center frequency in Hz.
- * It must be in the range [-44M, 44M]. The frequency specified is
- * quantized. Use tx_freq to retrieve the actual value used.
- */
- bool set_tx_freq (int channel, double freq);
-
- void set_verbose (bool verbose);
-
- // ACCESSORS
-
- long fpga_master_clock_freq() const;
- long converter_rate() const; // D/A sample rate
- long dac_rate() const; // alias
- long dac_freq () const; // deprecated name. Use converter_rate() or dac_rate().
-
- unsigned int interp_rate () const;
- double tx_freq (int channel) const;
- int nunderruns () const { return d_nunderruns; }
-
- /*!
- * \brief Set Programmable Gain Amplifier (PGA)
- *
- * \param which which D/A [0,3]
- * \param gain_in_db gain value (linear in dB)
- *
- * gain is rounded to closest setting supported by hardware.
- * Note that DAC 0 and DAC 1 share a gain setting as do DAC 2 and DAC 3.
- * Setting DAC 0 affects DAC 1 and vice versa. Same with DAC 2 and DAC 3.
- *
- * \returns true iff sucessful.
- *
- * \sa pga_min(), pga_max(), pga_db_per_step()
- */
- bool set_pga (int which, double gain_in_db);
-
- /*!
- * \brief Return programmable gain amplifier gain in dB.
- *
- * \param which which D/A [0,3]
- */
- double pga (int which) const;
-
- /*!
- * \brief Return minimum legal PGA gain in dB.
- */
- double pga_min () const;
-
- /*!
- * \brief Return maximum legal PGA gain in dB.
- */
- double pga_max () const;
-
- /*!
- * \brief Return hardware step size of PGA (linear in dB).
- */
- double pga_db_per_step () const;
-
- /*!
- * \brief Return daughterboard ID for given Tx daughterboard slot [0,1].
- *
- * \return daughterboard id >= 0 if successful
- * \return -1 if no daugherboard
- * \return -2 if invalid EEPROM on daughterboard
- */
- int daughterboard_id (int which_dboard) const;
-
- /*!
- * \brief Set ADC offset correction
- * \param which which ADC[0,3]: 0 = RX_A I, 1 = RX_A Q...
- * \param offset 16-bit value to subtract from raw ADC input.
- */
- bool set_adc_offset (int which, int offset);
-
- /*!
- * \brief Set DAC offset correction
- * \param which which DAC[0,3]: 0 = TX_A I, 1 = TX_A Q...
- * \param offset 10-bit offset value (ambiguous format: See AD9862 datasheet).
- * \param offset_pin 1-bit value. If 0 offset applied to -ve differential pin;
- * If 1 offset applied to +ve differential pin.
- */
- bool set_dac_offset (int which, int offset, int offset_pin);
-
- /*!
- * \brief Control ADC input buffer
- * \param which which ADC[0,3]
- * \param bypass if non-zero, bypass input buffer and connect input
- * directly to switched cap SHA input of RxPGA.
- */
- bool set_adc_buffer_bypass (int which, bool bypass);
-
- /*!
- * \brief return the usrp's serial number.
- *
- * \returns non-zero length string iff successful.
- */
- std::string serial_number();
-
- /*!
- * \brief Write direction register (output enables) for pins that go to daughterboard.
- *
- * \param which_dboard [0,1] which d'board
- * \param value value to write into register
- * \param mask which bits of value to write into reg
- *
- * Each d'board has 16-bits of general purpose i/o.
- * Setting the bit makes it an output from the FPGA to the d'board.
- *
- * This register is initialized based on a value stored in the
- * d'board EEPROM. In general, you shouldn't be using this routine
- * without a very good reason. Using this method incorrectly will
- * kill your USRP motherboard and/or daughterboard.
- */
- bool _write_oe (int which_dboard, int value, int mask);
-
- /*!
- * \brief Write daughterboard i/o pin value
- *
- * \param which_dboard [0,1] which d'board
- * \param value value to write into register
- * \param mask which bits of value to write into reg
- */
- bool write_io (int which_dboard, int value, int mask);
-
- /*!
- * \brief Read daughterboard i/o pin value
- *
- * \param which_dboard [0,1] which d'board
- * \returns register value if successful, else READ_FAILED
- */
- int read_io (int which_dboard);
-
- bool write_aux_dac (int which_dboard, int which_dac, int value);
- int read_aux_adc (int which_dboard, int which_adc);
- bool write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf);
- std::string read_eeprom (int i2c_addr, int eeprom_offset, int len);
- bool write_i2c (int i2c_addr, const std::string buf);
- std::string read_i2c (int i2c_addr, int len);
-
- bool _write_fpga_reg (int regno, int value); //< 7-bit regno, 32-bit value
- int _read_fpga_reg (int regno);
- bool _write_9862 (int which_codec, int regno, unsigned char value);
- int _read_9862 (int which_codec, int regno) const;
-
- /*!
- * \brief Write data to SPI bus peripheral.
- *
- * \param optional_header 0,1 or 2 bytes to write before buf.
- * \param enables bitmask of peripherals to write. See usrp_spi_defs.h
- * \param format transaction format. See usrp_spi_defs.h SPI_FMT_*
- * \param buf the data to write
- * \returns true iff successful
- * Writes are limited to a maximum of 64 bytes.
- *
- * If \p format specifies that optional_header bytes are present, they are
- * written to the peripheral immediately prior to writing \p buf.
- */
- bool _write_spi (int optional_header, int enables, int format, std::string buf);
-
- /*
- * \brief Read data from SPI bus peripheral.
- *
- * \param optional_header 0,1 or 2 bytes to write before buf.
- * \param enables bitmask of peripheral to read. See usrp_spi_defs.h
- * \param format transaction format. See usrp_spi_defs.h SPI_FMT_*
- * \param len number of bytes to read. Must be in [0,64].
- * \returns the data read if sucessful, else a zero length string.
- *
- * Reads are limited to a maximum of 64 bytes.
- *
- * If \p format specifies that optional_header bytes are present, they
- * are written to the peripheral first. Then \p len bytes are read from
- * the peripheral and returned.
- */
- std::string _read_spi (int optional_header, int enables, int format, int len);
-};
-
-// ----------------------------------------------------------------
-
-class usrp1_source_base : public gr_sync_block {
- protected:
-
- usrp1_source_base (const std::string &name,
- gr_io_signature_sptr input_signature,
- int which_board,
- unsigned int interp_rate,
- int nchan,
- int mux,
- int fusb_block_size,
- int fusb_nblocks,
- const std::string fpga_filename,
- const std::string firmware_filename
- ) throw (std::runtime_error);
-
- virtual int ninput_bytes_reqd_for_noutput_items (int noutput_items) = 0;
-
- virtual void copy_from_usrp_buffer (gr_vector_void_star &output_items,
- int output_index,
- int output_items_available,
- int &output_items_produced,
- const void *usrp_buffer,
- int usrp_buffer_length,
- int &bytes_read) = 0;
- public:
- ~usrp1_source_base ();
-
-
- /*!
- * \brief Set decimator rate. \p rate must be EVEN and in [8, 256].
- *
- * The final complex sample rate across the USB is
- * adc_freq () / decim_rate ()
- */
- bool set_decim_rate (unsigned int rate);
- bool set_nchannels (int nchan);
- bool set_mux (int mux);
-
- /*!
- * \brief set the center frequency of the digital down converter.
- *
- * \p channel must be 0. \p freq is the center frequency in Hz.
- * It must be in the range [-FIXME, FIXME]. The frequency specified is
- * quantized. Use rx_freq to retrieve the actual value used.
- */
- bool set_rx_freq (int channel, double freq);
-
- /*!
- * \brief set fpga special modes
- */
- bool set_fpga_mode (int mode);
-
- /*!
- * \brief Set the digital down converter phase register.
- *
- * \param channel which ddc channel [0, 3]
- * \param phase 32-bit integer phase value.
- */
- bool set_ddc_phase(int channel, int phase);
-
-
- void set_verbose (bool verbose);
-
- // ACCESSORS
-
- long fpga_master_clock_freq() const;
- long converter_rate() const; // A/D sample rate
- long adc_rate() const; // alias
- long adc_freq() const; // Deprecated name. Use converter_rate() or adc_rate().
-
- unsigned int decim_rate () const;
- double rx_freq (int channel) const;
- int noverruns () const { return d_noverruns; }
-
-
- // PGA stuff
- /*!
- * \brief Set Programmable Gain Amplifier (PGA)
- *
- * \param which which A/D [0,3]
- * \param gain_in_db gain value (linear in dB)
- *
- * gain is rounded to closest setting supported by hardware.
- *
- * \returns true iff sucessful.
- *
- * \sa pga_min(), pga_max(), pga_db_per_step()
- */
- bool set_pga (int which, double gain_in_db);
-
- /*!
- * \brief Return programmable gain amplifier gain setting in dB.
- *
- * \param which which A/D [0,3]
- */
- double pga (int which) const;
-
- /*!
- * \brief Return minimum legal PGA setting in dB.
- */
- double pga_min () const;
-
- /*!
- * \brief Return maximum legal PGA setting in dB.
- */
- double pga_max () const;
-
- /*!
- * \brief Return hardware step size of PGA (linear in dB).
- */
- double pga_db_per_step () const;
-
- /*!
- * \brief Return daughterboard ID for given Rx daughterboard slot [0,1].
- *
- * \return daughterboard id >= 0 if successful
- * \return -1 if no daugherboard
- * \return -2 if invalid EEPROM on daughterboard
- */
- int daughterboard_id (int which_dboard) const;
-
- /*!
- * \brief Set ADC offset correction
- * \param which which ADC[0,3]: 0 = RX_A I, 1 = RX_A Q...
- * \param offset 16-bit value to subtract from raw ADC input.
- */
- bool set_adc_offset (int which, int offset);
-
- /*!
- * \brief Set DAC offset correction
- * \param which which DAC[0,3]: 0 = TX_A I, 1 = TX_A Q...
- * \param offset 10-bit offset value (ambiguous format: See AD9862 datasheet).
- * \param offset_pin 1-bit value. If 0 offset applied to -ve differential pin;
- * If 1 offset applied to +ve differential pin.
- */
- bool set_dac_offset (int which, int offset, int offset_pin);
-
- /*!
- * \brief Control ADC input buffer
- * \param which which ADC[0,3]
- * \param bypass if non-zero, bypass input buffer and connect input
- * directly to switched cap SHA input of RxPGA.
- */
- bool set_adc_buffer_bypass (int which, bool bypass);
-
- /*!
- * \brief return the usrp's serial number.
- *
- * \returns non-zero length string iff successful.
- */
- std::string serial_number();
-
- /*!
- * \brief Write direction register (output enables) for pins that go to daughterboard.
- *
- * \param which_dboard [0,1] which d'board
- * \param value value to write into register
- * \param mask which bits of value to write into reg
- *
- * Each d'board has 16-bits of general purpose i/o.
- * Setting the bit makes it an output from the FPGA to the d'board.
- *
- * This register is initialized based on a value stored in the
- * d'board EEPROM. In general, you shouldn't be using this routine
- * without a very good reason. Using this method incorrectly will
- * kill your USRP motherboard and/or daughterboard.
- */
- bool _write_oe (int which_dboard, int value, int mask);
-
- /*!
- * \brief Write daughterboard i/o pin value
- *
- * \param which_dboard [0,1] which d'board
- * \param value value to write into register
- * \param mask which bits of value to write into reg
- */
- bool write_io (int which_dboard, int value, int mask);
-
- /*!
- * \brief Read daughterboard i/o pin value
- *
- * \param which_dboard [0,1] which d'board
- * \returns register value if successful, else READ_FAILED
- */
- int read_io (int which_dboard);
-
- /*!
- * \brief Enable/disable automatic DC offset removal control loop in FPGA
- *
- * \param bits which control loops to enable
- * \param mask which \p bits to pay attention to
- *
- * If the corresponding bit is set, enable the automatic DC
- * offset correction control loop.
- *
- * <pre>
- * The 4 low bits are significant:
- *
- * ADC0 = (1 << 0)
- * ADC1 = (1 << 1)
- * ADC2 = (1 << 2)
- * ADC3 = (1 << 3)
- * </pre>
- *
- * By default the control loop is enabled on all ADC's.
- */
- bool set_dc_offset_cl_enable(int bits, int mask);
-
- /*!
- * \brief Specify Rx data format.
- *
- * \param format format specifier
- *
- * Rx data format control register
- *
- * 3 2 1
- * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- * +-----------------------------------------+-+-+---------+-------+
- * | Reserved (Must be zero) |B|Q| WIDTH | SHIFT |
- * +-----------------------------------------+-+-+---------+-------+
- *
- * SHIFT specifies arithmetic right shift [0, 15]
- * WIDTH specifies bit-width of I & Q samples across the USB [1, 16] (not all valid)
- * Q if set deliver both I & Q, else just I
- * B if set bypass half-band filter.
- *
- * Right now the acceptable values are:
- *
- * B Q WIDTH SHIFT
- * 0 1 16 0
- * 0 1 8 8
- *
- * More valid combos to come.
- *
- * Default value is 0x00000300 16-bits, 0 shift, deliver both I & Q.
- */
- bool set_format(unsigned int format);
-
- /*!
- * \brief return current format
- */
- unsigned int format () const;
-
- static unsigned int make_format(int width=16, int shift=0,
- bool want_q=true, bool bypass_halfband=false);
- static int format_width(unsigned int format);
- static int format_shift(unsigned int format);
- static bool format_want_q(unsigned int format);
- static bool format_bypass_halfband(unsigned int format);
-
-
-
-
- bool write_aux_dac (int which_dboard, int which_dac, int value);
- int read_aux_adc (int which_dboard, int which_adc);
- bool write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf);
- std::string read_eeprom (int i2c_addr, int eeprom_offset, int len);
- bool write_i2c (int i2c_addr, const std::string buf);
- std::string read_i2c (int i2c_addr, int len);
- bool _write_fpga_reg (int regno, int value); //< 7-bit regno, 32-bit value
- bool _write_fpga_reg_masked (int regno, int value, int mask); //< 7-bit regno, 16-bit value, 16-bit mask
- int _read_fpga_reg (int regno);
- bool _write_9862 (int which_codec, int regno, unsigned char value);
- int _read_9862 (int which_codec, int regno) const;
-
- bool _write_spi (int optional_header, int enables, int format, std::string buf);
-
- /*
- * \brief Read data from SPI bus peripheral.
- *
- * \param optional_header 0,1 or 2 bytes to write before buf.
- * \param enables bitmask of peripheral to read. See usrp_spi_defs.h
- * \param format transaction format. See usrp_spi_defs.h SPI_FMT_*
- * \param len number of bytes to read. Must be in [0,64].
- * \returns the data read if sucessful, else a zero length string.
- *
- * Reads are limited to a maximum of 64 bytes.
- *
- * If \p format specifies that optional_header bytes are present, they
- * are written to the peripheral first. Then \p len bytes are read from
- * the peripheral and returned.
- */
- std::string _read_spi (int optional_header, int enables, int format, int len);
-};
-
-
-// ================================================================
-// concrete sinks
-// ================================================================
-
-
-GR_SWIG_BLOCK_MAGIC(usrp1,sink_c)
-
-usrp1_sink_c_sptr
-usrp1_make_sink_c (int which_board,
- unsigned int interp_rate,
- int nchan,
- int mux,
- int fusb_block_size,
- int fusb_nblocks,
- const std::string fpga_filename,
- const std::string firmware_filename
- ) throw (std::runtime_error);
-
-
-class usrp1_sink_c : public usrp1_sink_base {
- protected:
- usrp1_sink_c (int which_board, unsigned int interp_rate,
- int nchan, int mux);
-
- public:
- ~usrp1_sink_c ();
-};
-
-// ----------------------------------------------------------------
-
-GR_SWIG_BLOCK_MAGIC(usrp1,sink_s)
-
-usrp1_sink_s_sptr
-usrp1_make_sink_s (int which_board,
- unsigned int interp_rate,
- int nchan,
- int mux,
- int fusb_block_size,
- int fusb_nblocks,
- const std::string fpga_filename,
- const std::string firmware_filename
- ) throw (std::runtime_error);
-
-
-class usrp1_sink_s : public usrp1_sink_base {
- protected:
- usrp1_sink_s (int which_board, unsigned int interp_rate,
- int nchan, int mux);
-
- public:
- ~usrp1_sink_s ();
-};
-
-// ================================================================
-// concrete sources
-// ================================================================
-
-GR_SWIG_BLOCK_MAGIC(usrp1,source_c)
-
-
-usrp1_source_c_sptr
-usrp1_make_source_c (int which_board,
- unsigned int decim_rate,
- int nchan,
- int mux,
- int mode,
- int fusb_block_size,
- int fusb_nblocks,
- const std::string fpga_filename,
- const std::string firmware_filename
- ) throw (std::runtime_error);
-
-class usrp1_source_c : public usrp1_source_base {
- protected:
- usrp1_source_c (int which_board, unsigned int decim_rate,
- int nchan, int mux, int mode);
-
- public:
- ~usrp1_source_c ();
-};
-
-// ----------------------------------------------------------------
-
-GR_SWIG_BLOCK_MAGIC(usrp1,source_s)
-
-usrp1_source_s_sptr
-usrp1_make_source_s (int which_board,
- unsigned int decim_rate,
- int nchan,
- int mux,
- int mode,
- int fusb_block_size,
- int fusb_nblocks,
- const std::string fpga_filename,
- const std::string firmware_filename
- ) throw (std::runtime_error);
-
-
-class usrp1_source_s : public usrp1_source_base {
- protected:
- usrp1_source_s (int which_board, unsigned int decim_rate,
- int nchan, int mux, int mode);
-
- public:
- ~usrp1_source_s ();
-};
-
diff --git a/gr-usrp/src/usrp1_sink_base.cc b/gr-usrp/src/usrp1_sink_base.cc
deleted file mode 100644
index 331be5f8ce..0000000000
--- a/gr-usrp/src/usrp1_sink_base.cc
+++ /dev/null
@@ -1,359 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <usrp1_sink_base.h>
-#include <gr_io_signature.h>
-#include <usrp_standard.h>
-#include <assert.h>
-
-static const int OUTPUT_MULTIPLE_SAMPLES = 128; // DON'T CHANGE THIS VALUE!
-
-usrp1_sink_base::usrp1_sink_base (const std::string &name,
- gr_io_signature_sptr input_signature,
- int which_board,
- unsigned int interp_rate,
- int nchan,
- int mux,
- int fusb_block_size,
- int fusb_nblocks,
- const std::string fpga_filename,
- const std::string firmware_filename
- ) throw (std::runtime_error)
- : gr_sync_block (name,
- input_signature,
- gr_make_io_signature (0, 0, 0)),
- d_nunderruns (0)
-{
- d_usrp = usrp_standard_tx::make (which_board,
- interp_rate,
- nchan, mux,
- fusb_block_size,
- fusb_nblocks,
- fpga_filename,
- firmware_filename
- );
- if (d_usrp == 0)
- throw std::runtime_error ("can't open usrp1");
-
- // All calls to d_usrp->write must be multiples of 512 bytes.
-
- set_output_multiple (OUTPUT_MULTIPLE_SAMPLES);
-}
-
-usrp1_sink_base::~usrp1_sink_base ()
-{
- delete d_usrp;
-}
-
-bool
-usrp1_sink_base::start()
-{
- return d_usrp->start();
-}
-
-bool
-usrp1_sink_base::stop()
-{
- return d_usrp->stop();
-}
-
-int
-usrp1_sink_base::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- static const int BUFSIZE = 16 * (1L << 10); // 16kB
- unsigned char outbuf[BUFSIZE];
- int obi = 0;
- int input_index = 0;
- int input_items_consumed;
- int bytes_written;
- bool underrun;
-
-
- while (input_index < noutput_items){
-
- copy_to_usrp_buffer (input_items,
- input_index,
- noutput_items - input_index, // input_items_available
- input_items_consumed, // [out]
- &outbuf[obi], // [out] usrp_buffer
- BUFSIZE - obi, // usrp_buffer_length
- bytes_written); // [out]
-
- assert (input_index + input_items_consumed <= noutput_items);
- assert (obi + bytes_written <= BUFSIZE);
-
- input_index += input_items_consumed;
- obi += bytes_written;
-
- if (obi >= BUFSIZE){ // flush
- if (d_usrp->write (outbuf, obi, &underrun) != obi)
- return -1; // indicate we're done
-
- if (underrun){
- d_nunderruns++;
- // fprintf (stderr, "usrp1_sink: underrun\n");
- fputs ("uU", stderr);
- }
- obi = 0;
- }
- }
-
- if (obi != 0){
- assert (obi % 512 == 0);
- if (d_usrp->write (outbuf, obi, &underrun) != obi)
- return -1; // indicate we're done
-
- if (underrun){
- d_nunderruns++;
- // fprintf (stderr, "usrp1_sink: underrun\n");
- fputs ("uU", stderr);
- }
- }
-
- return noutput_items;
-}
-
-bool
-usrp1_sink_base::set_interp_rate (unsigned int rate)
-{
- return d_usrp->set_interp_rate (rate);
-}
-
-bool
-usrp1_sink_base::set_nchannels (int nchan)
-{
- return d_usrp->set_nchannels (nchan);
-}
-
-bool
-usrp1_sink_base::set_mux (int mux)
-{
- return d_usrp->set_mux (mux);
-}
-
-bool
-usrp1_sink_base::set_tx_freq (int channel, double freq)
-{
- return d_usrp->set_tx_freq (channel, freq);
-}
-
-long
-usrp1_sink_base::fpga_master_clock_freq() const
-{
- return d_usrp->fpga_master_clock_freq();
-}
-
-long
-usrp1_sink_base::converter_rate () const
-{
- return d_usrp->converter_rate ();
-}
-
-unsigned int
-usrp1_sink_base::interp_rate () const
-{
- return d_usrp->interp_rate ();
-}
-
-int
-usrp1_sink_base::nchannels () const
-{
- return d_usrp->nchannels ();
-}
-
-int
-usrp1_sink_base::mux () const
-{
- return d_usrp->mux ();
-}
-
-
-double
-usrp1_sink_base::tx_freq (int channel) const
-{
- return d_usrp->tx_freq (channel);
-}
-
-void
-usrp1_sink_base::set_verbose (bool verbose)
-{
- d_usrp->set_verbose (verbose);
-}
-
-bool
-usrp1_sink_base::write_aux_dac (int which_dboard, int which_dac, int value)
-{
- return d_usrp->write_aux_dac (which_dboard, which_dac, value);
-}
-
-int
-usrp1_sink_base::read_aux_adc (int which_dboard, int which_adc)
-{
- return d_usrp->read_aux_adc (which_dboard, which_adc);
-}
-
-bool
-usrp1_sink_base::write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf)
-{
- return d_usrp->write_eeprom (i2c_addr, eeprom_offset, buf);
-}
-
-std::string
-usrp1_sink_base::read_eeprom (int i2c_addr, int eeprom_offset, int len)
-{
- return d_usrp->read_eeprom (i2c_addr, eeprom_offset, len);
-}
-
-bool
-usrp1_sink_base::write_i2c (int i2c_addr, const std::string buf)
-{
- return d_usrp->write_i2c (i2c_addr, buf);
-}
-
-std::string
-usrp1_sink_base::read_i2c (int i2c_addr, int len)
-{
- return d_usrp->read_i2c (i2c_addr, len);
-}
-
-bool
-usrp1_sink_base::set_pga (int which, double gain)
-{
- return d_usrp->set_pga (which, gain);
-}
-
-double
-usrp1_sink_base::pga (int which) const
-{
- return d_usrp->pga (which);
-}
-
-double
-usrp1_sink_base::pga_min () const
-{
- return d_usrp->pga_min ();
-}
-
-double
-usrp1_sink_base::pga_max () const
-{
- return d_usrp->pga_max ();
-}
-
-double
-usrp1_sink_base::pga_db_per_step () const
-{
- return d_usrp->pga_db_per_step ();
-}
-
-int
-usrp1_sink_base::daughterboard_id (int which) const
-{
- return d_usrp->daughterboard_id (which);
-}
-
-bool
-usrp1_sink_base::set_adc_offset (int which, int offset)
-{
- return d_usrp->set_adc_offset (which, offset);
-}
-
-bool
-usrp1_sink_base::set_dac_offset (int which, int offset, int offset_pin)
-{
- return d_usrp->set_dac_offset (which, offset, offset_pin);
-}
-
-bool
-usrp1_sink_base::set_adc_buffer_bypass (int which, bool bypass)
-{
- return d_usrp->set_adc_buffer_bypass (which, bypass);
-}
-
-std::string
-usrp1_sink_base::serial_number()
-{
- return d_usrp->serial_number();
-}
-
-bool
-usrp1_sink_base::_write_oe (int which_dboard, int value, int mask)
-{
- return d_usrp->_write_oe (which_dboard, value, mask);
-}
-
-bool
-usrp1_sink_base::write_io (int which_dboard, int value, int mask)
-{
- return d_usrp->write_io (which_dboard, value, mask);
-}
-
-int
-usrp1_sink_base::read_io (int which_dboard)
-{
- return d_usrp->read_io (which_dboard);
-}
-
-// internal routines...
-
-bool
-usrp1_sink_base::_write_fpga_reg (int regno, int value)
-{
- return d_usrp->_write_fpga_reg (regno, value);
-}
-
-int
-usrp1_sink_base::_read_fpga_reg (int regno)
-{
- return d_usrp->_read_fpga_reg (regno);
-}
-
-bool
-usrp1_sink_base::_write_9862 (int which_codec, int regno, unsigned char value)
-{
- return d_usrp->_write_9862 (which_codec, regno, value);
-}
-
-int
-usrp1_sink_base::_read_9862 (int which_codec, int regno) const
-{
- return d_usrp->_read_9862 (which_codec, regno);
-}
-
-bool
-usrp1_sink_base::_write_spi (int optional_header, int enables,
- int format, std::string buf)
-{
- return d_usrp->_write_spi (optional_header, enables, format, buf);
-}
-
-std::string
-usrp1_sink_base::_read_spi (int optional_header, int enables, int format, int len)
-{
- return d_usrp->_read_spi (optional_header, enables, format, len);
-}
diff --git a/gr-usrp/src/usrp1_sink_base.h b/gr-usrp/src/usrp1_sink_base.h
deleted file mode 100644
index c628494748..0000000000
--- a/gr-usrp/src/usrp1_sink_base.h
+++ /dev/null
@@ -1,359 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2006 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_USRP1_SINK_BASE_H
-#define INCLUDED_USRP1_SINK_BASE_H
-
-#include <gr_sync_block.h>
-#include <stdexcept>
-
-class usrp_standard_tx;
-
-
-/*!
- * \brief abstract interface to Universal Software Radio Peripheral Tx path (Rev 1)
- */
-class usrp1_sink_base : public gr_sync_block {
- private:
- usrp_standard_tx *d_usrp;
- int d_nunderruns;
-
- protected:
- usrp1_sink_base (const std::string &name,
- gr_io_signature_sptr input_signature,
- int which_board,
- unsigned int interp_rate,
- int nchan,
- int mux,
- int fusb_block_size,
- int fusb_nblocks,
- const std::string fpga_filename,
- const std::string firmware_filename
- ) throw (std::runtime_error);
-
- /*!
- * \brief convert between input item format and usrp native format
- *
- * \param input_items[in] stream(s) of input items
- * \param input_index[in] starting index in input_items
- * \param input_items_available[in] number of items available starting at item[index]
- * \param input_items_consumed[out] number of input items consumed by copy
- * \param usrp_buffer[out] destination buffer
- * \param usrp_buffer_length[in] \p usrp_buffer length in bytes
- * \param bytes_written[out] number of bytes written into \p usrp_buffer
- */
- virtual void copy_to_usrp_buffer (gr_vector_const_void_star &input_items,
- int input_index,
- int input_items_available,
- int &input_items_consumed,
- void *usrp_buffer,
- int usrp_buffer_length,
- int &bytes_written) = 0;
-
- public:
- //! magic value used on alternate register read interfaces
- static const int READ_FAILED = -99999;
-
-
- ~usrp1_sink_base ();
-
- int work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-
- bool start();
- bool stop();
-
- /*!
- * \brief Set interpolator rate. \p rate must be in [4, 1024] and a multiple of 4.
- *
- * The final complex sample rate across the USB is
- * dac_freq () / interp_rate () * nchannels ()
- */
- bool set_interp_rate (unsigned int rate);
- bool set_nchannels (int nchan);
- bool set_mux (int mux);
-
- /*!
- * \brief set the frequency of the digital up converter.
- *
- * \p channel must be 0. \p freq is the center frequency in Hz.
- * It must be in the range [-44M, 44M]. The frequency specified is
- * quantized. Use tx_freq to retrieve the actual value used.
- */
- bool set_tx_freq (int channel, double freq);
-
- void set_verbose (bool verbose);
-
- /*!
- * \brief Set Programmable Gain Amplifier (PGA)
- *
- * \param which which D/A [0,3]
- * \param gain_in_db gain value (linear in dB)
- *
- * gain is rounded to closest setting supported by hardware.
- * Note that DAC 0 and DAC 1 share a gain setting as do DAC 2 and DAC 3.
- * Setting DAC 0 affects DAC 1 and vice versa. Same with DAC 2 and DAC 3.
- *
- * \returns true iff sucessful.
- *
- * \sa pga_min(), pga_max(), pga_db_per_step()
- */
- bool set_pga (int which, double gain_in_db);
-
- /*!
- * \brief Return programmable gain amplifier gain in dB.
- *
- * \param which which D/A [0,3]
- */
- double pga (int which) const;
-
- /*!
- * \brief Return minimum legal PGA gain in dB.
- */
- double pga_min () const;
-
- /*!
- * \brief Return maximum legal PGA gain in dB.
- */
- double pga_max () const;
-
- /*!
- * \brief Return hardware step size of PGA (linear in dB).
- */
- double pga_db_per_step () const;
-
-
- // ACCESSORS
-
- long fpga_master_clock_freq() const;
- long converter_rate() const;
- long dac_rate() const { return converter_rate(); } // alias
- long dac_freq() const { return converter_rate(); } // deprecated alias
-
- unsigned int interp_rate () const;
- int nchannels () const;
- int mux () const;
- double tx_freq (int channel) const;
- int nunderruns () const { return d_nunderruns; }
-
- /*!
- * \brief Return daughterboard ID for given Rx daughterboard slot [0,1].
- *
- * \return daughterboard id >= 0 if successful
- * \return -1 if no daugherboard
- * \return -2 if invalid EEPROM on daughterboard
- */
- int daughterboard_id (int which_dboard) const;
-
- /*!
- * \brief Write auxiliary digital to analog converter.
- *
- * \param which_dboard [0,1] which d'board
- * N.B., SLOT_TX_A and SLOT_RX_A share the same AUX DAC's.
- * SLOT_TX_B and SLOT_RX_B share the same AUX DAC's.
- * \param which_dac [2,3] TX slots must use only 2 and 3.
- * \param value [0,4095]
- * \returns true iff successful
- */
- bool write_aux_dac (int which_board, int which_dac, int value);
-
- /*!
- * \brief Read auxiliary analog to digital converter.
- *
- * \param which_dboard [0,1] which d'board
- * \param which_adc [0,1]
- * \returns value in the range [0,4095] if successful, else READ_FAILED.
- */
- int read_aux_adc (int which_dboard, int which_adc);
-
- /*!
- * \brief Write EEPROM on motherboard or any daughterboard.
- * \param i2c_addr I2C bus address of EEPROM
- * \param eeprom_offset byte offset in EEPROM to begin writing
- * \param buf the data to write
- * \returns true iff sucessful
- */
- bool write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf);
-
- /*!
- * \brief Write EEPROM on motherboard or any daughterboard.
- * \param i2c_addr I2C bus address of EEPROM
- * \param eeprom_offset byte offset in EEPROM to begin reading
- * \param len number of bytes to read
- * \returns the data read if successful, else a zero length string.
- */
- std::string read_eeprom (int i2c_addr, int eeprom_offset, int len);
-
- /*!
- * \brief Write to I2C peripheral
- * \param i2c_addr I2C bus address (7-bits)
- * \param buf the data to write
- * \returns true iff successful
- * Writes are limited to a maximum of of 64 bytes.
- */
- bool write_i2c (int i2c_addr, const std::string buf);
-
- /*!
- * \brief Read from I2C peripheral
- * \param i2c_addr I2C bus address (7-bits)
- * \param len number of bytes to read
- * \returns the data read if successful, else a zero length string.
- * Reads are limited to a maximum of of 64 bytes.
- */
- std::string read_i2c (int i2c_addr, int len);
-
- /*!
- * \brief Set ADC offset correction
- * \param which which ADC[0,3]: 0 = RX_A I, 1 = RX_A Q...
- * \param offset 16-bit value to subtract from raw ADC input.
- */
- bool set_adc_offset (int which, int offset);
-
- /*!
- * \brief Set DAC offset correction
- * \param which which DAC[0,3]: 0 = TX_A I, 1 = TX_A Q...
- * \param offset 10-bit offset value (ambiguous format: See AD9862 datasheet).
- * \param offset_pin 1-bit value. If 0 offset applied to -ve differential pin;
- * If 1 offset applied to +ve differential pin.
- */
- bool set_dac_offset (int which, int offset, int offset_pin);
-
- /*!
- * \brief Control ADC input buffer
- * \param which which ADC[0,3]
- * \param bypass if non-zero, bypass input buffer and connect input
- * directly to switched cap SHA input of RxPGA.
- */
- bool set_adc_buffer_bypass (int which, bool bypass);
-
- /*!
- * \brief return the usrp's serial number.
- *
- * \returns non-zero length string iff successful.
- */
- std::string serial_number();
-
- /*!
- * \brief Write direction register (output enables) for pins that go to daughterboard.
- *
- * \param which_dboard [0,1] which d'board
- * \param value value to write into register
- * \param mask which bits of value to write into reg
- *
- * Each d'board has 16-bits of general purpose i/o.
- * Setting the bit makes it an output from the FPGA to the d'board.
- *
- * This register is initialized based on a value stored in the
- * d'board EEPROM. In general, you shouldn't be using this routine
- * without a very good reason. Using this method incorrectly will
- * kill your USRP motherboard and/or daughterboard.
- */
- bool _write_oe (int which_dboard, int value, int mask);
-
- /*!
- * \brief Write daughterboard i/o pin value
- *
- * \param which_dboard [0,1] which d'board
- * \param value value to write into register
- * \param mask which bits of value to write into reg
- */
- bool write_io (int which_dboard, int value, int mask);
-
- /*!
- * \brief Read daughterboard i/o pin value
- *
- * \param which_dboard [0,1] which d'board
- * \returns register value if successful, else READ_FAILED
- */
- int read_io (int which_dboard);
-
- //
- // internal routines...
- // You probably shouldn't be using these...
- //
- /*!
- * \brief Write FPGA register.
- * \param regno 7-bit register number
- * \param value 32-bit value
- * \returns true iff successful
- */
- bool _write_fpga_reg (int regno, int value); //< 7-bit regno, 32-bit value
-
- /*!
- * \brief Read FPGA register.
- * \param regno 7-bit register number
- * \returns register value if successful, else READ_FAILED
- */
- int _read_fpga_reg (int regno);
-
- /*!
- * \brief Write AD9862 register.
- * \param which_codec 0 or 1
- * \param regno 6-bit register number
- * \param value 8-bit value
- * \returns true iff successful
- */
- bool _write_9862 (int which_codec, int regno, unsigned char value);
-
- /*!
- * \brief Read AD9862 register.
- * \param which_codec 0 or 1
- * \param regno 6-bit register number
- * \returns register value if successful, else READ_FAILED
- */
- int _read_9862 (int which_codec, int regno) const;
-
- /*!
- * \brief Write data to SPI bus peripheral.
- *
- * \param optional_header 0,1 or 2 bytes to write before buf.
- * \param enables bitmask of peripherals to write. See usrp_spi_defs.h
- * \param format transaction format. See usrp_spi_defs.h SPI_FMT_*
- * \param buf the data to write
- * \returns true iff successful
- * Writes are limited to a maximum of 64 bytes.
- *
- * If \p format specifies that optional_header bytes are present, they are
- * written to the peripheral immediately prior to writing \p buf.
- */
- bool _write_spi (int optional_header, int enables, int format, std::string buf);
-
- /*
- * \brief Read data from SPI bus peripheral.
- *
- * \param optional_header 0,1 or 2 bytes to write before buf.
- * \param enables bitmask of peripheral to read. See usrp_spi_defs.h
- * \param format transaction format. See usrp_spi_defs.h SPI_FMT_*
- * \param len number of bytes to read. Must be in [0,64].
- * \returns the data read if sucessful, else a zero length string.
- *
- * Reads are limited to a maximum of 64 bytes.
- *
- * If \p format specifies that optional_header bytes are present, they
- * are written to the peripheral first. Then \p len bytes are read from
- * the peripheral and returned.
- */
- std::string _read_spi (int optional_header, int enables, int format, int len);
-};
-
-#endif /* INCLUDED_USRP1_SINK_BASE_H */
diff --git a/gr-usrp/src/usrp1_source_base.cc b/gr-usrp/src/usrp1_source_base.cc
deleted file mode 100644
index 1aefa8a235..0000000000
--- a/gr-usrp/src/usrp1_source_base.cc
+++ /dev/null
@@ -1,425 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <usrp1_source_base.h>
-#include <gr_io_signature.h>
-#include <usrp_standard.h>
-#include <assert.h>
-
-static const int OUTPUT_MULTIPLE_BYTES = 4 * 1024;
-
-usrp1_source_base::usrp1_source_base (const std::string &name,
- gr_io_signature_sptr output_signature,
- int which_board,
- unsigned int decim_rate,
- int nchan,
- int mux,
- int mode,
- int fusb_block_size,
- int fusb_nblocks,
- const std::string fpga_filename,
- const std::string firmware_filename
- ) throw (std::runtime_error)
- : gr_sync_block (name,
- gr_make_io_signature (0, 0, 0),
- output_signature),
- d_noverruns (0)
-{
- d_usrp = usrp_standard_rx::make (which_board, decim_rate,
- nchan, mux, mode,
- fusb_block_size,
- fusb_nblocks,
- fpga_filename,
- firmware_filename);
- if (d_usrp == 0)
- throw std::runtime_error ("can't open usrp1");
-
- // All calls to d_usrp->read must be multiples of 512 bytes.
- // We jack this up to 4k to reduce overhead.
-
- set_output_multiple (OUTPUT_MULTIPLE_BYTES / output_signature->sizeof_stream_item (0));
-}
-
-usrp1_source_base::~usrp1_source_base ()
-{
- delete d_usrp;
-}
-
-unsigned int
-usrp1_source_base::sizeof_basic_sample() const
-{
- return usrp_standard_rx::format_width(d_usrp->format()) / 8;
-}
-
-bool
-usrp1_source_base::start()
-{
- return d_usrp->start();
-}
-
-bool
-usrp1_source_base::stop()
-{
- return d_usrp->stop();
-}
-
-int
-usrp1_source_base::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- static const int BUFSIZE = 4 * OUTPUT_MULTIPLE_BYTES;
- unsigned char buf[BUFSIZE];
- int output_index = 0;
- int output_items_produced;
- int bytes_read;
- bool overrun;
-
- while (output_index < noutput_items){
- int nbytes = ninput_bytes_reqd_for_noutput_items (noutput_items - output_index);
- nbytes = std::min (nbytes, BUFSIZE);
-
- int result_nbytes = d_usrp->read (buf, nbytes, &overrun);
- if (overrun){
- // fprintf (stderr, "usrp1_source: overrun\n");
- fputs ("uO", stderr);
- d_noverruns++;
- }
-
- if (result_nbytes < 0) // We've got a problem. Usually board unplugged or powered down.
- return -1; // Indicate we're done.
-
- if (result_nbytes != nbytes){ // not really an error, but unexpected
- fprintf (stderr, "usrp1_source: short read. Expected %d, got %d\n",
- nbytes, result_nbytes);
- }
-
- copy_from_usrp_buffer (output_items,
- output_index,
- noutput_items - output_index, // output_items_available
- output_items_produced, // [out]
- buf, // usrp_buffer
- result_nbytes, // usrp_buffer_length
- bytes_read); // [out]
-
- assert (output_index + output_items_produced <= noutput_items);
- assert (bytes_read == result_nbytes);
-
- output_index += output_items_produced;
- }
-
- return noutput_items;
-}
-
-
-bool
-usrp1_source_base::set_decim_rate (unsigned int rate)
-{
- return d_usrp->set_decim_rate (rate);
-}
-
-bool
-usrp1_source_base::set_nchannels (int nchan)
-{
- return d_usrp->set_nchannels (nchan);
-}
-
-bool
-usrp1_source_base::set_mux (int mux)
-{
- return d_usrp->set_mux (mux);
-}
-
-bool
-usrp1_source_base::set_rx_freq (int channel, double freq)
-{
- return d_usrp->set_rx_freq (channel, freq);
-}
-
-long
-usrp1_source_base::fpga_master_clock_freq() const
-{
- return d_usrp->fpga_master_clock_freq();
-}
-
-long
-usrp1_source_base::converter_rate() const
-{
- return d_usrp->converter_rate();
-}
-
-unsigned int
-usrp1_source_base::decim_rate () const
-{
- return d_usrp->decim_rate ();
-}
-
-int
-usrp1_source_base::nchannels () const
-{
- return d_usrp->nchannels ();
-}
-
-int
-usrp1_source_base::mux () const
-{
- return d_usrp->mux ();
-}
-
-double
-usrp1_source_base::rx_freq (int channel) const
-{
- return d_usrp->rx_freq (channel);
-}
-
-bool
-usrp1_source_base::set_fpga_mode (int mode)
-{
- return d_usrp->set_fpga_mode (mode);
-}
-
-bool
-usrp1_source_base::set_ddc_phase (int channel, int phase)
-{
- return d_usrp->set_ddc_phase(channel, phase);
-}
-
-bool
-usrp1_source_base::set_dc_offset_cl_enable(int bits, int mask)
-{
- return d_usrp->set_dc_offset_cl_enable(bits, mask);
-}
-
-void
-usrp1_source_base::set_verbose (bool verbose)
-{
- d_usrp->set_verbose (verbose);
-}
-
-bool
-usrp1_source_base::write_aux_dac (int which_dboard, int which_dac, int value)
-{
- return d_usrp->write_aux_dac (which_dboard, which_dac, value);
-}
-
-int
-usrp1_source_base::read_aux_adc (int which_dboard, int which_adc)
-{
- return d_usrp->read_aux_adc (which_dboard, which_adc);
-}
-
-bool
-usrp1_source_base::write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf)
-{
- return d_usrp->write_eeprom (i2c_addr, eeprom_offset, buf);
-}
-
-std::string
-usrp1_source_base::read_eeprom (int i2c_addr, int eeprom_offset, int len)
-{
- return d_usrp->read_eeprom (i2c_addr, eeprom_offset, len);
-}
-
-bool
-usrp1_source_base::write_i2c (int i2c_addr, const std::string buf)
-{
- return d_usrp->write_i2c (i2c_addr, buf);
-}
-
-std::string
-usrp1_source_base::read_i2c (int i2c_addr, int len)
-{
- return d_usrp->read_i2c (i2c_addr, len);
-}
-
-bool
-usrp1_source_base::set_pga (int which, double gain)
-{
- return d_usrp->set_pga (which, gain);
-}
-
-double
-usrp1_source_base::pga (int which) const
-{
- return d_usrp->pga (which);
-}
-
-double
-usrp1_source_base::pga_min () const
-{
- return d_usrp->pga_min ();
-}
-
-double
-usrp1_source_base::pga_max () const
-{
- return d_usrp->pga_max ();
-}
-
-double
-usrp1_source_base::pga_db_per_step () const
-{
- return d_usrp->pga_db_per_step ();
-}
-
-int
-usrp1_source_base::daughterboard_id (int which) const
-{
- return d_usrp->daughterboard_id (which);
-}
-
-
-bool
-usrp1_source_base::set_adc_offset (int which, int offset)
-{
- return d_usrp->set_adc_offset (which, offset);
-}
-
-bool
-usrp1_source_base::set_dac_offset (int which, int offset, int offset_pin)
-{
- return d_usrp->set_dac_offset (which, offset, offset_pin);
-}
-
-bool
-usrp1_source_base::set_adc_buffer_bypass (int which, bool bypass)
-{
- return d_usrp->set_adc_buffer_bypass (which, bypass);
-}
-
-std::string
-usrp1_source_base::serial_number()
-{
- return d_usrp->serial_number();
-}
-
-bool
-usrp1_source_base::_write_oe (int which_dboard, int value, int mask)
-{
- return d_usrp->_write_oe (which_dboard, value, mask);
-}
-
-bool
-usrp1_source_base::write_io (int which_dboard, int value, int mask)
-{
- return d_usrp->write_io (which_dboard, value, mask);
-}
-
-int
-usrp1_source_base::read_io (int which_dboard)
-{
- return d_usrp->read_io (which_dboard);
-}
-
-
-
-
-// internal routines...
-
-bool
-usrp1_source_base::_write_fpga_reg (int regno, int value)
-{
- return d_usrp->_write_fpga_reg (regno, value);
-}
-
-bool
-usrp1_source_base::_write_fpga_reg_masked (int regno, int value, int mask)
-{
- return d_usrp->_write_fpga_reg_masked (regno, value, mask);
-}
-
-int
-usrp1_source_base::_read_fpga_reg (int regno)
-{
- return d_usrp->_read_fpga_reg (regno);
-}
-
-bool
-usrp1_source_base::_write_9862 (int which_codec, int regno, unsigned char value)
-{
- return d_usrp->_write_9862 (which_codec, regno, value);
-}
-
-int
-usrp1_source_base::_read_9862 (int which_codec, int regno) const
-{
- return d_usrp->_read_9862 (which_codec, regno);
-}
-
-bool
-usrp1_source_base::_write_spi (int optional_header, int enables,
- int format, std::string buf)
-{
- return d_usrp->_write_spi (optional_header, enables, format, buf);
-}
-
-std::string
-usrp1_source_base::_read_spi (int optional_header, int enables, int format, int len)
-{
- return d_usrp->_read_spi (optional_header, enables, format, len);
-}
-
-bool
-usrp1_source_base::set_format(unsigned int format)
-{
- return d_usrp->set_format(format);
-}
-
-unsigned int
-usrp1_source_base::format() const
-{
- return d_usrp->format();
-}
-
-unsigned int
-usrp1_source_base::make_format(int width, int shift, bool want_q, bool bypass_halfband)
-{
- return usrp_standard_rx::make_format(width, shift, want_q, bypass_halfband);
-}
-
-int
-usrp1_source_base::format_width(unsigned int format)
-{
- return usrp_standard_rx::format_width(format);
-}
-
-int
-usrp1_source_base::format_shift(unsigned int format)
-{
- return usrp_standard_rx::format_shift(format);
-}
-
-bool
-usrp1_source_base::format_want_q(unsigned int format)
-{
- return usrp_standard_rx::format_want_q(format);
-}
-
-bool
-usrp1_source_base::format_bypass_halfband(unsigned int format)
-{
- return usrp_standard_rx::format_bypass_halfband(format);
-}
diff --git a/gr-usrp/src/usrp_base.cc b/gr-usrp/src/usrp_base.cc
new file mode 100644
index 0000000000..1709c7a44c
--- /dev/null
+++ b/gr-usrp/src/usrp_base.cc
@@ -0,0 +1,316 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <usrp_base.h>
+#include <usrp_basic.h>
+
+class truth_table_element_t
+{
+public:
+ truth_table_element_t(int side, unsigned int uses, bool swap_iq, unsigned int mux_val);
+ bool operator==(const truth_table_element_t &in);
+ bool operator!=(const truth_table_element_t &in);
+
+ unsigned int mux_val() { return d_mux_val; }
+
+private:
+ int d_side;
+ unsigned int d_uses;
+ bool d_swap_iq;
+ unsigned int d_mux_val;
+};
+
+
+usrp_base::~usrp_base()
+{
+}
+
+void
+usrp_base::set_usrp_basic(boost::shared_ptr<usrp_basic> u)
+{
+ d_usrp_basic = u;
+}
+
+std::vector<std::vector<db_base_sptr> >
+usrp_base::db()
+{
+ return d_usrp_basic->db();
+}
+
+std::vector<db_base_sptr>
+usrp_base::db(int which_side)
+{
+ return d_usrp_basic->db(which_side);
+}
+
+db_base_sptr
+usrp_base::db(int which_side, int which_dev)
+{
+ return d_usrp_basic->selected_subdev(usrp_subdev_spec(which_side, which_dev));
+}
+
+db_base_sptr
+usrp_base::selected_subdev(usrp_subdev_spec ss)
+{
+ return d_usrp_basic->selected_subdev(ss);
+}
+
+long
+usrp_base::fpga_master_clock_freq() const
+{
+ return d_usrp_basic->fpga_master_clock_freq();
+}
+
+void
+usrp_base::set_verbose (bool verbose)
+{
+ d_usrp_basic->set_verbose (verbose);
+}
+
+bool
+usrp_base::write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf)
+{
+ return d_usrp_basic->write_eeprom (i2c_addr, eeprom_offset, buf);
+}
+
+std::string
+usrp_base::read_eeprom (int i2c_addr, int eeprom_offset, int len)
+{
+ return d_usrp_basic->read_eeprom (i2c_addr, eeprom_offset, len);
+}
+
+bool
+usrp_base::write_i2c (int i2c_addr, const std::string buf)
+{
+ return d_usrp_basic->write_i2c (i2c_addr, buf);
+}
+
+std::string
+usrp_base::read_i2c (int i2c_addr, int len)
+{
+ return d_usrp_basic->read_i2c (i2c_addr, len);
+}
+
+bool
+usrp_base::set_adc_offset (int which, int offset)
+{
+ return d_usrp_basic->set_adc_offset (which, offset);
+}
+
+bool
+usrp_base::set_dac_offset (int which, int offset, int offset_pin)
+{
+ return d_usrp_basic->set_dac_offset (which, offset, offset_pin);
+}
+
+bool
+usrp_base::set_adc_buffer_bypass (int which, bool bypass)
+{
+ return d_usrp_basic->set_adc_buffer_bypass (which, bypass);
+}
+
+bool
+usrp_base::set_dc_offset_cl_enable(int bits, int mask)
+{
+ return d_usrp_basic->set_dc_offset_cl_enable(bits, mask);
+}
+
+std::string
+usrp_base::serial_number()
+{
+ return d_usrp_basic->serial_number();
+}
+
+int
+usrp_base::daughterboard_id (int which) const
+{
+ return d_usrp_basic->daughterboard_id (which);
+}
+
+bool
+usrp_base::write_atr_tx_delay(int value)
+{
+ return d_usrp_basic->write_atr_tx_delay(value);
+}
+
+bool
+usrp_base::write_atr_rx_delay(int value)
+{
+ return d_usrp_basic->write_atr_rx_delay(value);
+}
+
+bool
+usrp_base::set_pga (int which, double gain)
+{
+ return d_usrp_basic->set_pga (which, gain);
+}
+
+double
+usrp_base::pga (int which) const
+{
+ return d_usrp_basic->pga (which);
+}
+
+double
+usrp_base::pga_min () const
+{
+ return d_usrp_basic->pga_min ();
+}
+
+double
+usrp_base::pga_max () const
+{
+ return d_usrp_basic->pga_max ();
+}
+
+double
+usrp_base::pga_db_per_step () const
+{
+ return d_usrp_basic->pga_db_per_step ();
+}
+
+bool
+usrp_base::_write_oe (int which_dboard, int value, int mask)
+{
+ return d_usrp_basic->_write_oe (which_dboard, value, mask);
+}
+
+bool
+usrp_base::write_io (int which_dboard, int value, int mask)
+{
+ return d_usrp_basic->write_io (which_dboard, value, mask);
+}
+
+int
+usrp_base::read_io (int which_dboard)
+{
+ return d_usrp_basic->read_io (which_dboard);
+}
+
+bool
+usrp_base::write_atr_mask(int which_side, int value)
+{
+ return d_usrp_basic->write_atr_mask(which_side, value);
+}
+
+bool
+usrp_base::write_atr_txval(int which_side, int value)
+{
+ return d_usrp_basic->write_atr_txval(which_side, value);
+}
+
+bool
+usrp_base::write_atr_rxval(int which_side, int value)
+{
+ return d_usrp_basic->write_atr_rxval(which_side, value);
+}
+
+bool
+usrp_base::write_aux_dac (int which_dboard, int which_dac, int value)
+{
+ return d_usrp_basic->write_aux_dac (which_dboard, which_dac, value);
+}
+
+int
+usrp_base::read_aux_adc (int which_dboard, int which_adc)
+{
+ return d_usrp_basic->read_aux_adc (which_dboard, which_adc);
+}
+
+long
+usrp_base::converter_rate() const
+{
+ return d_usrp_basic->converter_rate();
+}
+
+bool
+usrp_base::_set_led(int which_led, bool on)
+{
+ return d_usrp_basic->_set_led(which_led, on);
+}
+
+bool
+usrp_base::_write_fpga_reg (int regno, int value)
+{
+ return d_usrp_basic->_write_fpga_reg (regno, value);
+}
+
+bool
+usrp_base::_write_fpga_reg_masked (int regno, int value, int mask)
+{
+ return d_usrp_basic->_write_fpga_reg_masked (regno, value, mask);
+}
+
+int
+usrp_base::_read_fpga_reg (int regno)
+{
+ return d_usrp_basic->_read_fpga_reg (regno);
+}
+
+bool
+usrp_base::_write_9862 (int which_codec, int regno, unsigned char value)
+{
+ return d_usrp_basic->_write_9862 (which_codec, regno, value);
+}
+
+int
+usrp_base::_read_9862 (int which_codec, int regno) const
+{
+ return d_usrp_basic->_read_9862 (which_codec, regno);
+}
+
+bool
+usrp_base::_write_spi (int optional_header, int enables,
+ int format, std::string buf)
+{
+ return d_usrp_basic->_write_spi (optional_header, enables, format, buf);
+}
+
+std::string
+usrp_base::_read_spi (int optional_header, int enables, int format, int len)
+{
+ return d_usrp_basic->_read_spi (optional_header, enables, format, len);
+}
+
+usrp_subdev_spec
+usrp_base::pick_subdev(std::vector<int> candidates)
+{
+ int dbid0 = db(0, 0)->dbid();
+ int dbid1 = db(1, 0)->dbid();
+
+ for (int i = 0; i < candidates.size(); i++) {
+ int dbid = candidates[i];
+ if (dbid0 == dbid)
+ return usrp_subdev_spec(0, 0);
+ if (dbid1 == dbid)
+ return usrp_subdev_spec(1, 0);
+ }
+
+ if (dbid0 >= 0)
+ return usrp_subdev_spec(0, 0);
+ if (dbid1 >= 0)
+ return usrp_subdev_spec(1, 0);
+
+ throw std::runtime_error("No suitable daughterboard found!");
+}
diff --git a/gr-usrp/src/usrp1_source_base.h b/gr-usrp/src/usrp_base.h
index 5d29ba6047..83aa699abf 100644
--- a/gr-usrp/src/usrp1_source_base.h
+++ b/gr-usrp/src/usrp_base.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2008 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -14,199 +14,96 @@
* 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.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-
-#ifndef INCLUDED_USRP1_SOURCE_BASE_H
-#define INCLUDED_USRP1_SOURCE_BASE_H
+#ifndef INCLUDED_USRP_BASE_H
+#define INCLUDED_USRP_BASE_H
#include <gr_sync_block.h>
#include <stdexcept>
+#include <boost/shared_ptr.hpp>
+#include <db_base.h>
+#include <usrp_subdev_spec.h>
-class usrp_standard_rx;
+class usrp_basic;
/*!
- * \brief abstract interface to Universal Software Radio Peripheral Rx path (Rev 1)
+ * \brief base class for GNU Radio interface to the USRP
*/
-class usrp1_source_base : public gr_sync_block {
- private:
- usrp_standard_rx *d_usrp;
- int d_noverruns;
-
- protected:
- usrp1_source_base (const std::string &name,
- gr_io_signature_sptr output_signature,
- int which_board,
- unsigned int decim_rate,
- int nchan,
- int mux,
- int mode,
- int fusb_block_size,
- int fusb_nblocks,
- const std::string fpga_filename,
- const std::string firmware_filename
- ) throw (std::runtime_error);
-
- /*!
- * \brief return number of usrp input bytes required to produce noutput items.
- */
- virtual int ninput_bytes_reqd_for_noutput_items (int noutput_items) = 0;
-
- /*!
- * \brief number of bytes in a low-level sample
- */
- unsigned int sizeof_basic_sample() const;
-
- /*!
- * \brief convert between native usrp format and output item format
- *
- * \param output_items[out] stream(s) of output items
- * \param output_index[in] starting index in output_items
- * \param output_items_available[in] number of empty items available at item[index]
- * \param output_items_produced[out] number of items produced by copy
- * \param usrp_buffer[in] source buffer
- * \param usrp_buffer_length[in] number of bytes available in \p usrp_buffer
- * \param bytes_read[out] number of bytes read from \p usrp_buffer
- *
- * The copy must consume all bytes available. That is, \p bytes_read must equal
- * \p usrp_buffer_length.
- */
- virtual void copy_from_usrp_buffer (gr_vector_void_star &output_items,
- int output_index,
- int output_items_available,
- int &output_items_produced,
- const void *usrp_buffer,
- int usrp_buffer_length,
- int &bytes_read) = 0;
-
- public:
- //! magic value used on alternate register read interfaces
- static const int READ_FAILED = -99999;
+class usrp_base : public gr_sync_block {
+private:
+ boost::shared_ptr<usrp_basic> d_usrp_basic;
- ~usrp1_source_base ();
+protected:
+ usrp_base(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature)
+ : gr_sync_block(name, input_signature, output_signature) {}
+
- int work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
+ void set_usrp_basic(boost::shared_ptr<usrp_basic> u);
- bool start();
- bool stop();
+public:
+ virtual ~usrp_base();
- /*!
- * \brief Set decimator rate. \p rate must be EVEN and in [8, 256].
+ /* !
+ * Return a vector of vectors of daughterboard instances associated with
+ * the USRP source or sink. The first dimension of the returned vector
+ * corresponds to the side of the USRP, the second dimension, the subdevice
+ * on the particular daughterboard.
*
- * The final complex sample rate across the USB is
- * adc_freq () / decim_rate ()
+ * N.B. To ensure proper lifetime management, the caller should
+ * continue to hold these as weak pointers, not shared pointers.
+ * As long as the caller does not attempt to directly use the weak
+ * pointers after this usrp object has been destroyed, everything
+ * will work out fine.
*/
- bool set_decim_rate (unsigned int rate);
- bool set_nchannels (int nchan);
- bool set_mux (int mux);
+ std::vector<std::vector<db_base_sptr> > db();
/*!
- * \brief set the center frequency of the digital down converter.
+ * Return a vector of size 1 or 2 that contains shared pointers
+ * to the daughterboard instance(s) associated with the specified side.
*
- * \p channel must be 0. \p freq is the center frequency in Hz.
- * It must be in the range [-FIXME, FIXME]. The frequency specified is
- * quantized. Use rx_freq to retrieve the actual value used.
- */
- bool set_rx_freq (int channel, double freq);
-
- /*!
- * \brief set fpga special modes
- */
- bool set_fpga_mode (int mode);
-
- void set_verbose (bool verbose);
-
- /*!
- * \brief Set the digital down converter phase register.
+ * \param which_side [0,1] which daughterboard
*
- * \param channel which ddc channel [0, 3]
- * \param phase 32-bit integer phase value.
+ * N.B. To ensure proper lifetime management, the caller should
+ * continue to hold these as weak pointers, not shared pointers.
+ * As long as the caller does not attempt to directly use the weak
+ * pointers after this usrp object has been destroyed, everything
+ * will work out fine.
*/
- bool set_ddc_phase(int channel, int phase);
+ std::vector<db_base_sptr> db(int which_side);
/*!
- * \brief Set Programmable Gain Amplifier (PGA)
- *
- * \param which which A/D [0,3]
- * \param gain_in_db gain value (linear in dB)
- *
- * gain is rounded to closest setting supported by hardware.
- *
- * \returns true iff sucessful.
- *
- * \sa pga_min(), pga_max(), pga_db_per_step()
+ * Return the daughterboard instance corresponding to the selected
+ * side of the USRP and selected daughterboard subdevice.
+ * N.B. To ensure proper lifetime management, the caller should
+ * continue to hold these as weak pointers, not shared pointers.
+ * As long as the caller does not attempt to directly use the weak
+ * pointers after this usrp object has been destroyed, everything
+ * will work out fine.
*/
- bool set_pga (int which, double gain_in_db);
+ db_base_sptr db(int which_side, int which_dev);
/*!
- * \brief Return programmable gain amplifier gain setting in dB.
+ * \brief given a usrp_subdev_spec, return the corresponding daughterboard object.
+ * \throws std::invalid_argument if ss is invalid.
*
- * \param which which A/D [0,3]
+ * \param ss specifies the side and subdevice
*/
- double pga (int which) const;
+ db_base_sptr selected_subdev(usrp_subdev_spec ss);
/*!
- * \brief Return minimum legal PGA setting in dB.
+ * \brief return frequency of master oscillator on USRP
*/
- double pga_min () const;
+ long fpga_master_clock_freq() const;
- /*!
- * \brief Return maximum legal PGA setting in dB.
- */
- double pga_max () const;
-
- /*!
- * \brief Return hardware step size of PGA (linear in dB).
- */
- double pga_db_per_step () const;
-
- // ACCESSORS
-
- long fpga_master_clock_freq() const;
- long converter_rate() const;
- long adc_rate() const { return converter_rate(); } // alias
- long adc_freq() const { return converter_rate(); } // deprecated alias
+ void set_verbose (bool on);
- unsigned int decim_rate () const;
- int nchannels () const;
- int mux () const;
- double rx_freq (int channel) const;
- int noverruns () const { return d_noverruns; }
-
- /*!
- * \brief Return daughterboard ID for given Rx daughterboard slot [0,1].
- *
- * \return daughterboard id >= 0 if successful
- * \return -1 if no daugherboard
- * \return -2 if invalid EEPROM on daughterboard
- */
- int daughterboard_id (int which_dboard) const;
-
- /*!
- * \brief Write auxiliary digital to analog converter.
- *
- * \param which_dboard [0,1] which d'board
- * N.B., SLOT_TX_A and SLOT_RX_A share the same AUX DAC's.
- * SLOT_TX_B and SLOT_RX_B share the same AUX DAC's.
- * \param which_dac [2,3] TX slots must use only 2 and 3.
- * \param value [0,4095]
- * \returns true iff successful
- */
- bool write_aux_dac (int which_board, int which_dac, int value);
-
- /*!
- * \brief Read auxiliary analog to digital converter.
- *
- * \param which_dboard [0,1] which d'board
- * \param which_adc [0,1]
- * \returns value in the range [0,4095] if successful, else READ_FAILED.
- */
- int read_aux_adc (int which_dboard, int which_adc);
+ //! magic value used on alternate register read interfaces
+ static const int READ_FAILED = -99999;
/*!
* \brief Write EEPROM on motherboard or any daughterboard.
@@ -218,7 +115,7 @@ class usrp1_source_base : public gr_sync_block {
bool write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf);
/*!
- * \brief Write EEPROM on motherboard or any daughterboard.
+ * \brief Read EEPROM on motherboard or any daughterboard.
* \param i2c_addr I2C bus address of EEPROM
* \param eeprom_offset byte offset in EEPROM to begin reading
* \param len number of bytes to read
@@ -240,7 +137,7 @@ class usrp1_source_base : public gr_sync_block {
* \param i2c_addr I2C bus address (7-bits)
* \param len number of bytes to read
* \returns the data read if successful, else a zero length string.
- * Reads are limited to a maximum of of 64 bytes.
+ * Reads are limited to a maximum of 64 bytes.
*/
std::string read_i2c (int i2c_addr, int len);
@@ -249,7 +146,7 @@ class usrp1_source_base : public gr_sync_block {
* \param which which ADC[0,3]: 0 = RX_A I, 1 = RX_A Q...
* \param offset 16-bit value to subtract from raw ADC input.
*/
- bool set_adc_offset (int which, int offset);
+ bool set_adc_offset (int which_adc, int offset);
/*!
* \brief Set DAC offset correction
@@ -258,15 +155,37 @@ class usrp1_source_base : public gr_sync_block {
* \param offset_pin 1-bit value. If 0 offset applied to -ve differential pin;
* If 1 offset applied to +ve differential pin.
*/
- bool set_dac_offset (int which, int offset, int offset_pin);
+ bool set_dac_offset (int which_dac, int offset, int offset_pin);
/*!
* \brief Control ADC input buffer
- * \param which which ADC[0,3]
+ * \param which_adc which ADC[0,3]
* \param bypass if non-zero, bypass input buffer and connect input
* directly to switched cap SHA input of RxPGA.
*/
- bool set_adc_buffer_bypass (int which, bool bypass);
+ bool set_adc_buffer_bypass (int which_adc, bool bypass);
+
+ /*!
+ * \brief Enable/disable automatic DC offset removal control loop in FPGA
+ *
+ * \param bits which control loops to enable
+ * \param mask which \p bits to pay attention to
+ *
+ * If the corresponding bit is set, enable the automatic DC
+ * offset correction control loop.
+ *
+ * <pre>
+ * The 4 low bits are significant:
+ *
+ * ADC0 = (1 << 0)
+ * ADC1 = (1 << 1)
+ * ADC2 = (1 << 2)
+ * ADC3 = (1 << 3)
+ * </pre>
+ *
+ * By default the control loop is enabled on all ADC's.
+ */
+ bool set_dc_offset_cl_enable(int bits, int mask);
/*!
* \brief return the usrp's serial number.
@@ -276,11 +195,70 @@ class usrp1_source_base : public gr_sync_block {
std::string serial_number();
/*!
+ * \brief Return daughterboard ID for given side [0,1].
+ *
+ * \param which_side [0,1] which daughterboard
+ *
+ * \return daughterboard id >= 0 if successful
+ * \return -1 if no daugherboard
+ * \return -2 if invalid EEPROM on daughterboard
+ */
+ virtual int daughterboard_id (int which_side) const;
+
+ /*!
+ * \brief Clock ticks to delay rising of T/R signal
+ * \sa write_atr_mask, write_atr_txval, write_atr_rxval
+ */
+ bool write_atr_tx_delay(int value);
+
+ /*!
+ * \brief Clock ticks to delay falling edge of T/R signal
+ * \sa write_atr_mask, write_atr_txval, write_atr_rxval
+ */
+ bool write_atr_rx_delay(int value);
+
+ /*!
+ * \brief Set Programmable Gain Amplifier (PGA)
+ *
+ * \param which_amp which amp [0,3]
+ * \param gain_in_db gain value (linear in dB)
+ *
+ * gain is rounded to closest setting supported by hardware.
+ *
+ * \returns true iff sucessful.
+ *
+ * \sa pga_min(), pga_max(), pga_db_per_step()
+ */
+ bool set_pga (int which_amp, double gain_in_db);
+
+ /*!
+ * \brief Return programmable gain amplifier gain setting in dB.
+ *
+ * \param which_amp which amp [0,3]
+ */
+ double pga (int which_amp) const;
+
+ /*!
+ * \brief Return minimum legal PGA gain in dB.
+ */
+ double pga_min () const;
+
+ /*!
+ * \brief Return maximum legal PGA gain in dB.
+ */
+ double pga_max () const;
+
+ /*!
+ * \brief Return hardware step size of PGA (linear in dB).
+ */
+ double pga_db_per_step () const;
+
+ /*!
* \brief Write direction register (output enables) for pins that go to daughterboard.
*
- * \param which_dboard [0,1] which d'board
- * \param value value to write into register
- * \param mask which bits of value to write into reg
+ * \param which_side [0,1] which size
+ * \param value value to write into register
+ * \param mask which bits of value to write into reg
*
* Each d'board has 16-bits of general purpose i/o.
* Setting the bit makes it an output from the FPGA to the d'board.
@@ -290,93 +268,84 @@ class usrp1_source_base : public gr_sync_block {
* without a very good reason. Using this method incorrectly will
* kill your USRP motherboard and/or daughterboard.
*/
- bool _write_oe (int which_dboard, int value, int mask);
+ bool _write_oe (int which_side, int value, int mask);
/*!
* \brief Write daughterboard i/o pin value
*
- * \param which_dboard [0,1] which d'board
- * \param value value to write into register
- * \param mask which bits of value to write into reg
+ * \param which_side [0,1] which d'board
+ * \param value value to write into register
+ * \param mask which bits of value to write into reg
*/
- bool write_io (int which_dboard, int value, int mask);
+ bool write_io (int which_side, int value, int mask);
/*!
* \brief Read daughterboard i/o pin value
*
- * \param which_dboard [0,1] which d'board
+ * \param which_side [0,1] which d'board
* \returns register value if successful, else READ_FAILED
*/
- int read_io (int which_dboard);
+ int read_io (int which_side);
/*!
- * \brief Enable/disable automatic DC offset removal control loop in FPGA
+ * \brief Write daughterboard refclk config register
*
- * \param bits which control loops to enable
- * \param mask which \p bits to pay attention to
- *
- * If the corresponding bit is set, enable the automatic DC
- * offset correction control loop.
+ * \param which_side [0,1] which d'board
+ * \param value value to write into register, see below
*
* <pre>
- * The 4 low bits are significant:
- *
- * ADC0 = (1 << 0)
- * ADC1 = (1 << 1)
- * ADC2 = (1 << 2)
- * ADC3 = (1 << 3)
+ * Control whether a reference clock is sent to the daughterboards,
+ * and what frequency. The refclk is sent on d'board i/o pin 0.
+ *
+ * 3 2 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-----------------------------------------------+-+------------+
+ * | Reserved (Must be zero) |E| DIVISOR |
+ * +-----------------------------------------------+-+------------+
+ *
+ * Bit 7 -- 1 turns on refclk, 0 allows IO use
+ * Bits 6:0 Divider value
* </pre>
- *
- * By default the control loop is enabled on all ADC's.
*/
- bool set_dc_offset_cl_enable(int bits, int mask);
+ bool write_refclk(int which_side, int value);
+
+ bool write_atr_mask(int which_side, int value);
+ bool write_atr_txval(int which_side, int value);
+ bool write_atr_rxval(int which_side, int value);
/*!
- * \brief Specify Rx data format.
- *
- * \param format format specifier
- *
- * Rx data format control register
- *
- * 3 2 1
- * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- * +-----------------------------------------+-+-+---------+-------+
- * | Reserved (Must be zero) |B|Q| WIDTH | SHIFT |
- * +-----------------------------------------+-+-+---------+-------+
- *
- * SHIFT specifies arithmetic right shift [0, 15]
- * WIDTH specifies bit-width of I & Q samples across the USB [1, 16] (not all valid)
- * Q if set deliver both I & Q, else just I
- * B if set bypass half-band filter.
- *
- * Right now the acceptable values are:
- *
- * B Q WIDTH SHIFT
- * 0 1 16 0
- * 0 1 8 8
+ * \brief Write auxiliary digital to analog converter.
*
- * More valid combos to come.
+ * \param which_side [0,1] which d'board
+ * N.B., SLOT_TX_A and SLOT_RX_A share the same AUX DAC's.
+ * SLOT_TX_B and SLOT_RX_B share the same AUX DAC's.
+ * \param which_dac [2,3] TX slots must use only 2 and 3.
+ * \param value [0,4095]
+ * \returns true iff successful
+ */
+ bool write_aux_dac (int which_side, int which_dac, int value);
+
+ /*!
+ * \brief Read auxiliary analog to digital converter.
*
- * Default value is 0x00000300 16-bits, 0 shift, deliver both I & Q.
+ * \param which_side [0,1] which d'board
+ * \param which_adc [0,1]
+ * \returns value in the range [0,4095] if successful, else READ_FAILED.
*/
- bool set_format(unsigned int format);
+ int read_aux_adc (int which_side, int which_adc);
/*!
- * \brief return current format
+ * \brief returns A/D or D/A converter rate in Hz
*/
- unsigned int format () const;
+ long converter_rate() const;
- static unsigned int make_format(int width=16, int shift=0,
- bool want_q=true, bool bypass_halfband=false);
- static int format_width(unsigned int format);
- static int format_shift(unsigned int format);
- static bool format_want_q(unsigned int format);
- static bool format_bypass_halfband(unsigned int format);
// ----------------------------------------------------------------
- // internal routines...
+ // Low level implementation routines.
// You probably shouldn't be using these...
- // ----------------------------------------------------------------
+ //
+
+ bool _set_led (int which_led, bool on);
/*!
* \brief Write FPGA register.
@@ -387,13 +356,12 @@ class usrp1_source_base : public gr_sync_block {
bool _write_fpga_reg (int regno, int value); //< 7-bit regno, 32-bit value
/*!
- * \brief Write FPGA register masked.
+ * \brief Read FPGA register.
* \param regno 7-bit register number
- * \param value 16-bit value
- * \param mask 16-bit mask
+ * \param value 32-bit value
* \returns true iff successful
*/
- bool _write_fpga_reg_masked (int regno, int value, int mask); //< 7-bit regno, 16-bit value, 16-bit mask
+ bool _read_fpga_reg (int regno, int *value); //< 7-bit regno, 32-bit value
/*!
* \brief Read FPGA register.
@@ -403,6 +371,16 @@ class usrp1_source_base : public gr_sync_block {
int _read_fpga_reg (int regno);
/*!
+ * \brief Write FPGA register with mask.
+ * \param regno 7-bit register number
+ * \param value 16-bit value
+ * \param mask 16-bit value
+ * \returns true if successful
+ * Only use this for registers who actually implement a mask in the verilog firmware, like FR_RX_MASTER_SLAVE
+ */
+ bool _write_fpga_reg_masked (int regno, int value, int mask);
+
+ /*!
* \brief Write AD9862 register.
* \param which_codec 0 or 1
* \param regno 6-bit register number
@@ -450,6 +428,16 @@ class usrp1_source_base : public gr_sync_block {
* the peripheral and returned.
*/
std::string _read_spi (int optional_header, int enables, int format, int len);
+
+ /*!
+ * Return an existing daughterboard from list of candidate dbids, or the first found
+ * on side A or side B.
+ *
+ * \param candidates Vector of candidate dbids
+ *
+ * Throws std::runtime_error if not found
+ */
+ usrp_subdev_spec pick_subdev(std::vector<int> candidates=std::vector<int>(0));
};
-#endif /* INCLUDED_USRP1_SOURCE_BASE_H */
+#endif /* INCLUDED_USRP_BASE_H */
diff --git a/gr-usrp/src/usrp_base.i b/gr-usrp/src/usrp_base.i
new file mode 100644
index 0000000000..8f0c8368d4
--- /dev/null
+++ b/gr-usrp/src/usrp_base.i
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+#include "usrp_base.h"
+%}
+
+class usrp_base : public gr_sync_block
+{
+protected:
+ usrp_base(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature)
+ : gr_sync_block(name, input_signature, output_signature) {}
+
+public:
+ std::vector<std::vector<db_base_sptr> > db();
+ std::vector<db_base_sptr> db(int which_side);
+ db_base_sptr db(int which_side, int which_dev);
+ %rename (_real_selected_subdev) selected_subdev;
+ db_base_sptr selected_subdev(usrp_subdev_spec ss);
+ long fpga_master_clock_freq() const;
+ void set_verbose (bool on);
+ static const int READ_FAILED = -99999;
+ bool write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf);
+ std::string read_eeprom (int i2c_addr, int eeprom_offset, int len);
+ bool write_i2c (int i2c_addr, const std::string buf);
+ std::string read_i2c (int i2c_addr, int len);
+ bool set_adc_offset (int which_adc, int offset);
+ bool set_dac_offset (int which_dac, int offset, int offset_pin);
+ bool set_adc_buffer_bypass (int which_adc, bool bypass);
+ bool set_dc_offset_cl_enable(int bits, int mask);
+ std::string serial_number();
+ virtual int daughterboard_id (int which_side) const;
+ bool write_atr_tx_delay(int value);
+ bool write_atr_rx_delay(int value);
+ bool set_pga (int which_amp, double gain_in_db);
+ double pga (int which_amp) const;
+ double pga_min () const;
+ double pga_max () const;
+ double pga_db_per_step () const;
+ bool _write_oe (int which_side, int value, int mask);
+ bool write_io (int which_side, int value, int mask);
+ int read_io (int which_side);
+ //bool write_refclk(int which_side, int value);
+ bool write_atr_mask(int which_side, int value);
+ bool write_atr_txval(int which_side, int value);
+ bool write_atr_rxval(int which_side, int value);
+ bool write_aux_dac (int which_side, int which_dac, int value);
+ int read_aux_adc (int which_side, int which_adc);
+ long converter_rate() const;
+ bool _set_led (int which_led, bool on);
+ bool _write_fpga_reg (int regno, int value);
+ //bool _read_fpga_reg (int regno, int *value);
+ int _read_fpga_reg (int regno);
+ bool _write_fpga_reg_masked (int regno, int value, int mask);
+ bool _write_9862 (int which_codec, int regno, unsigned char value);
+ int _read_9862 (int which_codec, int regno) const;
+ bool _write_spi (int optional_header, int enables, int format, std::string buf);
+ std::string _read_spi (int optional_header, int enables, int format, int len);
+ %rename(_real_pick_subdev) pick_subdev;
+ usrp_subdev_spec pick_subdev(std::vector<int> candidates=std::vector<int>(0))
+ throw (std::runtime_error);
+};
diff --git a/gr-usrp/src/usrp_sink_base.cc b/gr-usrp/src/usrp_sink_base.cc
new file mode 100644
index 0000000000..963f4dd6d5
--- /dev/null
+++ b/gr-usrp/src/usrp_sink_base.cc
@@ -0,0 +1,241 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <usrp_sink_base.h>
+#include <gr_io_signature.h>
+#include <usrp_standard.h>
+#include <assert.h>
+
+static const int OUTPUT_MULTIPLE_SAMPLES = 128; // DON'T CHANGE THIS VALUE!
+
+usrp_sink_base::usrp_sink_base (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ int which_board,
+ unsigned int interp_rate,
+ int nchan,
+ int mux,
+ int fusb_block_size,
+ int fusb_nblocks,
+ const std::string fpga_filename,
+ const std::string firmware_filename
+ ) throw (std::runtime_error)
+ : usrp_base(name,
+ input_signature,
+ gr_make_io_signature (0, 0, 0)),
+ d_nunderruns (0)
+{
+ d_usrp = usrp_standard_tx::make (which_board,
+ interp_rate,
+ nchan, mux,
+ fusb_block_size,
+ fusb_nblocks,
+ fpga_filename,
+ firmware_filename
+ );
+ if (d_usrp == 0)
+ throw std::runtime_error ("can't open usrp");
+
+ set_usrp_basic(d_usrp);
+
+ // All calls to d_usrp->write must be multiples of 512 bytes.
+
+ set_output_multiple (OUTPUT_MULTIPLE_SAMPLES);
+}
+
+usrp_sink_base::~usrp_sink_base ()
+{
+}
+
+int
+usrp_sink_base::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ static const int BUFSIZE = 16 * (1L << 10); // 16kB
+ unsigned char outbuf[BUFSIZE];
+ int obi = 0;
+ int input_index = 0;
+ int input_items_consumed;
+ int bytes_written;
+ bool underrun;
+
+
+ while (input_index < noutput_items){
+
+ copy_to_usrp_buffer (input_items,
+ input_index,
+ noutput_items - input_index, // input_items_available
+ input_items_consumed, // [out]
+ &outbuf[obi], // [out] usrp_buffer
+ BUFSIZE - obi, // usrp_buffer_length
+ bytes_written); // [out]
+
+ assert (input_index + input_items_consumed <= noutput_items);
+ assert (obi + bytes_written <= BUFSIZE);
+
+ input_index += input_items_consumed;
+ obi += bytes_written;
+
+ if (obi >= BUFSIZE){ // flush
+ if (d_usrp->write (outbuf, obi, &underrun) != obi)
+ return -1; // indicate we're done
+
+ if (underrun){
+ d_nunderruns++;
+ // fprintf (stderr, "usrp_sink: underrun\n");
+ fputs ("uU", stderr);
+ }
+ obi = 0;
+ }
+ }
+
+ if (obi != 0){
+ assert (obi % 512 == 0);
+ if (d_usrp->write (outbuf, obi, &underrun) != obi)
+ return -1; // indicate we're done
+
+ if (underrun){
+ d_nunderruns++;
+ // fprintf (stderr, "usrp_sink: underrun\n");
+ fputs ("uU", stderr);
+ }
+ }
+
+ return noutput_items;
+}
+
+bool
+usrp_sink_base::set_interp_rate (unsigned int rate)
+{
+ return d_usrp->set_interp_rate (rate);
+}
+
+bool
+usrp_sink_base::set_nchannels (int nchan)
+{
+ return d_usrp->set_nchannels (nchan);
+}
+
+bool
+usrp_sink_base::set_mux (int mux)
+{
+ return d_usrp->set_mux (mux);
+}
+
+int
+usrp_sink_base::determine_tx_mux_value(usrp_subdev_spec ss)
+{
+ return d_usrp->determine_tx_mux_value(ss);
+}
+
+bool
+usrp_sink_base::set_tx_freq (int channel, double freq)
+{
+ return d_usrp->set_tx_freq (channel, freq);
+}
+
+unsigned int
+usrp_sink_base::interp_rate () const
+{
+ return d_usrp->interp_rate ();
+}
+
+int
+usrp_sink_base::nchannels () const
+{
+ return d_usrp->nchannels ();
+}
+
+int
+usrp_sink_base::mux () const
+{
+ return d_usrp->mux ();
+}
+
+
+double
+usrp_sink_base::tx_freq (int channel) const
+{
+ return d_usrp->tx_freq (channel);
+}
+
+bool
+usrp_sink_base::has_rx_halfband()
+{
+ return d_usrp->has_rx_halfband();
+}
+
+bool
+usrp_sink_base::has_tx_halfband()
+{
+ return d_usrp->has_tx_halfband();
+}
+
+int
+usrp_sink_base::nddcs()
+{
+ return d_usrp->nddcs();
+}
+
+int
+usrp_sink_base::nducs()
+{
+ return d_usrp->nducs();
+}
+
+bool
+usrp_sink_base::start()
+{
+ return d_usrp->start();
+}
+
+bool
+usrp_sink_base::stop()
+{
+ return d_usrp->stop();
+}
+
+
+bool
+usrp_sink_base::tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result)
+{
+ return d_usrp->tune(chan, db, target_freq, result);
+}
+
+usrp_subdev_spec
+usrp_sink_base::pick_tx_subdevice()
+{
+ int dbids[] = {
+ USRP_DBID_FLEX_400_TX,
+ USRP_DBID_FLEX_900_TX,
+ USRP_DBID_FLEX_1200_TX,
+ USRP_DBID_FLEX_2400_TX,
+ USRP_DBID_BASIC_TX
+ };
+
+ std::vector<int> candidates(dbids, dbids+(sizeof(dbids)/sizeof(int)));
+ return pick_subdev(candidates);
+}
diff --git a/gr-usrp/src/usrp_sink_base.h b/gr-usrp/src/usrp_sink_base.h
new file mode 100644
index 0000000000..12dd51c659
--- /dev/null
+++ b/gr-usrp/src/usrp_sink_base.h
@@ -0,0 +1,151 @@
+
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_USRP_SINK_BASE_H
+#define INCLUDED_USRP_SINK_BASE_H
+
+#include <usrp_base.h>
+#include <stdexcept>
+#include <usrp_tune_result.h>
+#include <usrp_dbid.h>
+
+class usrp_standard_tx;
+
+/*!
+ * \brief abstract interface to Universal Software Radio Peripheral Tx path (Rev 1)
+ */
+class usrp_sink_base : public usrp_base {
+ private:
+ boost::shared_ptr<usrp_standard_tx> d_usrp;
+ int d_nunderruns;
+
+ protected:
+ usrp_sink_base (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ int which_board,
+ unsigned int interp_rate,
+ int nchan,
+ int mux,
+ int fusb_block_size,
+ int fusb_nblocks,
+ const std::string fpga_filename,
+ const std::string firmware_filename
+ ) throw (std::runtime_error);
+
+ /*!
+ * \brief convert between input item format and usrp native format
+ *
+ * \param input_items[in] stream(s) of input items
+ * \param input_index[in] starting index in input_items
+ * \param input_items_available[in] number of items available starting at item[index]
+ * \param input_items_consumed[out] number of input items consumed by copy
+ * \param usrp_buffer[out] destination buffer
+ * \param usrp_buffer_length[in] \p usrp_buffer length in bytes
+ * \param bytes_written[out] number of bytes written into \p usrp_buffer
+ */
+ virtual void copy_to_usrp_buffer (gr_vector_const_void_star &input_items,
+ int input_index,
+ int input_items_available,
+ int &input_items_consumed,
+ void *usrp_buffer,
+ int usrp_buffer_length,
+ int &bytes_written) = 0;
+
+ public:
+ ~usrp_sink_base ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ /*!
+ * \brief Set interpolator rate. \p rate must be in [4, 1024] and a multiple of 4.
+ *
+ * The final complex sample rate across the USB is
+ * dac_freq () / interp_rate () * nchannels ()
+ */
+ bool set_interp_rate (unsigned int rate);
+ bool set_nchannels (int nchan);
+ bool set_mux (int mux);
+ int determine_tx_mux_value(usrp_subdev_spec ss);
+
+ /*!
+ * \brief set the frequency of the digital up converter.
+ *
+ * \p channel must be 0. \p freq is the center frequency in Hz.
+ * It must be in the range [-44M, 44M]. The frequency specified is
+ * quantized. Use tx_freq to retrieve the actual value used.
+ */
+ bool set_tx_freq (int channel, double freq);
+
+ long dac_rate() const { return converter_rate(); } // alias
+ long dac_freq() const { return converter_rate(); } // deprecated alias
+
+ unsigned int interp_rate () const;
+ int nchannels () const;
+ int mux () const;
+ double tx_freq (int channel) const;
+ int nunderruns () const { return d_nunderruns; }
+
+ bool has_rx_halfband();
+ bool has_tx_halfband();
+ int nddcs();
+ int nducs();
+
+ /*!
+ * \brief Called to enable drivers, etc for i/o devices.
+ *
+ * This allows a block to enable an associated driver to begin
+ * transfering data just before we start to execute the scheduler.
+ * The end result is that this reduces latency in the pipeline when
+ * dealing with audio devices, usrps, etc.
+ */
+ bool start();
+
+ /*!
+ * \brief Called to disable drivers, etc for i/o devices.
+ */
+ bool stop();
+
+ /*!
+ * \brief High-level "tune" method. Works for the single channel case.
+ *
+ * This method adjusts both the daughterboard LO and the DUC so that
+ * DC in the complex baseband samples ends up at RF target_freq.
+ *
+ * \param chan which DUC channel we're controlling (usually == which_side).
+ * \param db the daughterboard we're controlling.
+ * \param target_freq the RF frequency we want our baseband translated to.
+ * \param[out] tune_result details how the hardware was configured.
+ *
+ * \returns true iff everything was successful.
+ */
+ bool tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result);
+
+ /*!
+ * \brief Select suitable Tx daughterboard
+ */
+ usrp_subdev_spec pick_tx_subdevice();
+};
+
+#endif /* INCLUDED_USRP_SINK_BASE_H */
diff --git a/gr-usrp/src/usrp_sink_base.i b/gr-usrp/src/usrp_sink_base.i
new file mode 100644
index 0000000000..ffc70a9842
--- /dev/null
+++ b/gr-usrp/src/usrp_sink_base.i
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+#include "usrp_sink_base.h"
+%}
+
+class usrp_sink_base : public usrp_base
+{
+private:
+ usrp_sink_base() throw (std::runtime_error);
+
+public:
+ bool set_interp_rate (unsigned int rate);
+ bool set_nchannels (int nchan);
+ bool set_mux (int mux);
+ %rename(_real_determine_tx_mux_value) determine_tx_mux_value;
+ int determine_tx_mux_value(usrp_subdev_spec ss);
+ bool set_tx_freq (int channel, double freq);
+ long dac_rate() const { return converter_rate(); }
+ long dac_freq() const { return converter_rate(); }
+ unsigned int interp_rate () const;
+ int nchannels () const;
+ int mux () const;
+ double tx_freq (int channel) const;
+ int nunderruns () const { return d_nunderruns; }
+ bool has_rx_halfband();
+ bool has_tx_halfband();
+ int nddcs();
+ int nducs();
+ %rename(_real_tune) tune;
+ bool tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result);
+ %rename(_real_pick_tx_subdevice) pick_tx_subdevice();
+ usrp_subdev_spec pick_tx_subdevice();
+};
diff --git a/gr-usrp/src/usrp1_sink_c.cc b/gr-usrp/src/usrp_sink_c.cc
index b38306090f..363a113fc8 100644
--- a/gr-usrp/src/usrp1_sink_c.cc
+++ b/gr-usrp/src/usrp_sink_c.cc
@@ -24,13 +24,13 @@
#include "config.h"
#endif
-#include <usrp1_sink_c.h>
+#include <usrp_sink_c.h>
#include <gr_io_signature.h>
#include <usrp_standard.h>
#include <usrp_bytesex.h>
-usrp1_sink_c_sptr
-usrp1_make_sink_c (int which_board,
+usrp_sink_c_sptr
+usrp_make_sink_c (int which_board,
unsigned int interp_rate,
int nchan,
int mux,
@@ -40,7 +40,7 @@ usrp1_make_sink_c (int which_board,
const std::string firmware_filename
) throw (std::runtime_error)
{
- return usrp1_sink_c_sptr (new usrp1_sink_c (which_board,
+ return usrp_sink_c_sptr (new usrp_sink_c (which_board,
interp_rate,
nchan,
mux,
@@ -52,7 +52,7 @@ usrp1_make_sink_c (int which_board,
}
-usrp1_sink_c::usrp1_sink_c (int which_board,
+usrp_sink_c::usrp_sink_c (int which_board,
unsigned int interp_rate,
int nchan,
int mux,
@@ -61,7 +61,7 @@ usrp1_sink_c::usrp1_sink_c (int which_board,
const std::string fpga_filename,
const std::string firmware_filename
) throw (std::runtime_error)
- : usrp1_sink_base ("usrp1_sink_c",
+ : usrp_sink_base ("usrp_sink_c",
gr_make_io_signature (1, 1, sizeof (gr_complex)),
which_board, interp_rate, nchan, mux,
fusb_block_size, fusb_nblocks,
@@ -69,7 +69,7 @@ usrp1_sink_c::usrp1_sink_c (int which_board,
{
}
-usrp1_sink_c::~usrp1_sink_c ()
+usrp_sink_c::~usrp_sink_c ()
{
// NOP
}
@@ -79,7 +79,7 @@ usrp1_sink_c::~usrp1_sink_c ()
* for the usrp.
*/
void
-usrp1_sink_c::copy_to_usrp_buffer (gr_vector_const_void_star &input_items,
+usrp_sink_c::copy_to_usrp_buffer (gr_vector_const_void_star &input_items,
int input_index,
int input_items_available,
int &input_items_consumed, // out
diff --git a/gr-usrp/src/usrp1_sink_c.h b/gr-usrp/src/usrp_sink_c.h
index 9e1d3f009e..32be5e8bb7 100644
--- a/gr-usrp/src/usrp1_sink_c.h
+++ b/gr-usrp/src/usrp_sink_c.h
@@ -20,27 +20,27 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef INCLUDED_USRP1_SINK_C_H
-#define INCLUDED_USRP1_SINK_C_H
+#ifndef INCLUDED_USRP_SINK_C_H
+#define INCLUDED_USRP_SINK_C_H
-#include <usrp1_sink_base.h>
+#include <usrp_sink_base.h>
-class usrp1_sink_c;
-typedef boost::shared_ptr<usrp1_sink_c> usrp1_sink_c_sptr;
+class usrp_sink_c;
+typedef boost::shared_ptr<usrp_sink_c> usrp_sink_c_sptr;
// public shared_ptr constructor
-usrp1_sink_c_sptr
-usrp1_make_sink_c (int which_board,
- unsigned int interp_rate,
- int nchan,
- int mux,
- int fusb_block_size,
- int fusb_nblocks,
- const std::string fpga_filename,
- const std::string firmware_filename
- ) throw (std::runtime_error);
+usrp_sink_c_sptr
+usrp_make_sink_c (int which_board=0,
+ unsigned int interp_rate=32,
+ int nchan=1,
+ int mux=-1,
+ int fusb_block_size=0,
+ int fusb_nblocks=0,
+ const std::string fpga_filename="",
+ const std::string firmware_filename=""
+ ) throw (std::runtime_error);
/*!
@@ -48,11 +48,11 @@ usrp1_make_sink_c (int which_board,
*
* input: gr_complex
*/
-class usrp1_sink_c : public usrp1_sink_base {
+class usrp_sink_c : public usrp_sink_base {
private:
- friend usrp1_sink_c_sptr
- usrp1_make_sink_c (int which_board,
+ friend usrp_sink_c_sptr
+ usrp_make_sink_c (int which_board,
unsigned int interp_rate,
int nchan,
int mux,
@@ -63,7 +63,7 @@ class usrp1_sink_c : public usrp1_sink_base {
) throw (std::runtime_error);
protected:
- usrp1_sink_c (int which_board,
+ usrp_sink_c (int which_board,
unsigned int interp_rate,
int nchan,
int mux,
@@ -81,7 +81,7 @@ class usrp1_sink_c : public usrp1_sink_base {
int usrp_buffer_length,
int &bytes_written);
public:
- ~usrp1_sink_c ();
+ ~usrp_sink_c ();
};
-#endif /* INCLUDED_USRP1_SINK_C_H */
+#endif /* INCLUDED_USRP_SINK_C_H */
diff --git a/gr-usrp/src/usrp_sink_c.i b/gr-usrp/src/usrp_sink_c.i
new file mode 100644
index 0000000000..15480883eb
--- /dev/null
+++ b/gr-usrp/src/usrp_sink_c.i
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+#include "usrp_sink_c.h"
+%}
+
+GR_SWIG_BLOCK_MAGIC(usrp,sink_c)
+
+class usrp_sink_c;
+typedef boost::shared_ptr<usrp_sink_c> usrp_sink_c_sptr;
+
+usrp_sink_c_sptr
+usrp_make_sink_c(int which=0,
+ unsigned int interp_rate=32,
+ int nchan=1,
+ int mux=-1,
+ int fusb_block_size=0,
+ int fusb_nblocks=0,
+ const std::string fpga_filename="",
+ const std::string firmware_filename=""
+ ) throw (std::runtime_error);
+
+class usrp_sink_c : public usrp_sink_base
+{
+private:
+ usrp_sink_c() throw (std::runtime_error);
+};
diff --git a/gr-usrp/src/usrp1_sink_s.cc b/gr-usrp/src/usrp_sink_s.cc
index 3ce3363282..adbf3acbd9 100644
--- a/gr-usrp/src/usrp1_sink_s.cc
+++ b/gr-usrp/src/usrp_sink_s.cc
@@ -24,13 +24,13 @@
#include "config.h"
#endif
-#include <usrp1_sink_s.h>
+#include <usrp_sink_s.h>
#include <gr_io_signature.h>
#include <usrp_standard.h>
#include <usrp_bytesex.h>
-usrp1_sink_s_sptr
-usrp1_make_sink_s (int which_board,
+usrp_sink_s_sptr
+usrp_make_sink_s (int which_board,
unsigned int interp_rate,
int nchan,
int mux,
@@ -40,7 +40,7 @@ usrp1_make_sink_s (int which_board,
const std::string firmware_filename
) throw (std::runtime_error)
{
- return usrp1_sink_s_sptr (new usrp1_sink_s (which_board,
+ return usrp_sink_s_sptr (new usrp_sink_s (which_board,
interp_rate,
nchan,
mux,
@@ -52,7 +52,7 @@ usrp1_make_sink_s (int which_board,
}
-usrp1_sink_s::usrp1_sink_s (int which_board,
+usrp_sink_s::usrp_sink_s (int which_board,
unsigned int interp_rate,
int nchan,
int mux,
@@ -61,7 +61,7 @@ usrp1_sink_s::usrp1_sink_s (int which_board,
const std::string fpga_filename,
const std::string firmware_filename
) throw (std::runtime_error)
- : usrp1_sink_base ("usrp1_sink_s",
+ : usrp_sink_base ("usrp_sink_s",
gr_make_io_signature (1, 1, sizeof (short)),
which_board, interp_rate, nchan, mux,
fusb_block_size, fusb_nblocks,
@@ -70,7 +70,7 @@ usrp1_sink_s::usrp1_sink_s (int which_board,
set_output_multiple (512 / sizeof(short)); // don't change
}
-usrp1_sink_s::~usrp1_sink_s ()
+usrp_sink_s::~usrp_sink_s ()
{
// NOP
}
@@ -80,7 +80,7 @@ usrp1_sink_s::~usrp1_sink_s ()
* for the usrp.
*/
void
-usrp1_sink_s::copy_to_usrp_buffer (gr_vector_const_void_star &input_items,
+usrp_sink_s::copy_to_usrp_buffer (gr_vector_const_void_star &input_items,
int input_index,
int input_items_available,
int &input_items_consumed, // out
diff --git a/gr-usrp/src/usrp1_sink_s.h b/gr-usrp/src/usrp_sink_s.h
index 2420b1e36d..17352a5af7 100644
--- a/gr-usrp/src/usrp1_sink_s.h
+++ b/gr-usrp/src/usrp_sink_s.h
@@ -20,38 +20,38 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef INCLUDED_USRP1_SINK_S_H
-#define INCLUDED_USRP1_SINK_S_H
+#ifndef INCLUDED_USRP_SINK_S_H
+#define INCLUDED_USRP_SINK_S_H
-#include <usrp1_sink_base.h>
+#include <usrp_sink_base.h>
-class usrp1_sink_s;
-typedef boost::shared_ptr<usrp1_sink_s> usrp1_sink_s_sptr;
+class usrp_sink_s;
+typedef boost::shared_ptr<usrp_sink_s> usrp_sink_s_sptr;
// public shared_ptr constructor
-usrp1_sink_s_sptr
-usrp1_make_sink_s (int which_board,
- unsigned int interp_rate,
- int nchan,
- int mux,
- int fusb_block_size,
- int fusb_nblocks,
- const std::string fpga_filename,
- const std::string firmware_filename
- ) throw (std::runtime_error);
+usrp_sink_s_sptr
+usrp_make_sink_s (int which_board=0,
+ unsigned int interp_rate=32,
+ int nchan=1,
+ int mux=-1,
+ int fusb_block_size=0,
+ int fusb_nblocks=0,
+ const std::string fpga_filename="",
+ const std::string firmware_filename=""
+ ) throw (std::runtime_error);
/*!
* \brief interface to Universal Software Radio Peripheral Tx path (Rev 1)
*
* input: short
*/
-class usrp1_sink_s : public usrp1_sink_base {
+class usrp_sink_s : public usrp_sink_base {
private:
- friend usrp1_sink_s_sptr
- usrp1_make_sink_s (int which_board,
+ friend usrp_sink_s_sptr
+ usrp_make_sink_s (int which_board,
unsigned int interp_rate,
int nchan,
int mux,
@@ -62,7 +62,7 @@ class usrp1_sink_s : public usrp1_sink_base {
) throw (std::runtime_error);
protected:
- usrp1_sink_s (int which_board,
+ usrp_sink_s (int which_board,
unsigned int interp_rate,
int nchan,
int mux,
@@ -80,7 +80,7 @@ class usrp1_sink_s : public usrp1_sink_base {
int usrp_buffer_length,
int &bytes_written);
public:
- ~usrp1_sink_s ();
+ ~usrp_sink_s ();
};
-#endif /* INCLUDED_USRP1_SINK_S_H */
+#endif /* INCLUDED_USRP_SINK_S_H */
diff --git a/gr-usrp/src/usrp_sink_s.i b/gr-usrp/src/usrp_sink_s.i
new file mode 100644
index 0000000000..9993d52147
--- /dev/null
+++ b/gr-usrp/src/usrp_sink_s.i
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+#include "usrp_sink_s.h"
+%}
+
+GR_SWIG_BLOCK_MAGIC(usrp,sink_s)
+
+class usrp_sink_s;
+typedef boost::shared_ptr<usrp_sink_s> usrp_sink_s_sptr;
+
+usrp_sink_s_sptr
+usrp_make_sink_s(int which=0,
+ unsigned int interp_rate=32,
+ int nchan=1,
+ int mux=-1,
+ int fusb_block_size=0,
+ int fusb_nblocks=0,
+ const std::string fpga_filename="",
+ const std::string firmware_filename=""
+ ) throw (std::runtime_error);
+
+class usrp_sink_s : public usrp_sink_base
+{
+private:
+ usrp_sink_s() throw (std::runtime_error);
+};
diff --git a/gr-usrp/src/usrp_source_base.cc b/gr-usrp/src/usrp_source_base.cc
new file mode 100644
index 0000000000..778fa1017e
--- /dev/null
+++ b/gr-usrp/src/usrp_source_base.cc
@@ -0,0 +1,295 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <usrp_source_base.h>
+#include <gr_io_signature.h>
+#include <usrp_standard.h>
+#include <assert.h>
+
+static const int OUTPUT_MULTIPLE_BYTES = 4 * 1024;
+
+usrp_source_base::usrp_source_base (const std::string &name,
+ gr_io_signature_sptr output_signature,
+ int which_board,
+ unsigned int decim_rate,
+ int nchan,
+ int mux,
+ int mode,
+ int fusb_block_size,
+ int fusb_nblocks,
+ const std::string fpga_filename,
+ const std::string firmware_filename
+ ) throw (std::runtime_error)
+ : usrp_base(name,
+ gr_make_io_signature (0, 0, 0),
+ output_signature),
+ d_noverruns (0)
+{
+ d_usrp = usrp_standard_rx::make (which_board, decim_rate,
+ nchan, mux, mode,
+ fusb_block_size,
+ fusb_nblocks,
+ fpga_filename,
+ firmware_filename);
+ if (d_usrp == 0)
+ throw std::runtime_error ("can't open usrp");
+
+ set_usrp_basic(d_usrp);
+
+ // All calls to d_usrp->read must be multiples of 512 bytes.
+ // We jack this up to 4k to reduce overhead.
+
+ set_output_multiple (OUTPUT_MULTIPLE_BYTES / output_signature->sizeof_stream_item (0));
+}
+
+usrp_source_base::~usrp_source_base ()
+{
+}
+
+unsigned int
+usrp_source_base::sizeof_basic_sample() const
+{
+ return usrp_standard_rx::format_width(d_usrp->format()) / 8;
+}
+
+int
+usrp_source_base::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ static const int BUFSIZE = 4 * OUTPUT_MULTIPLE_BYTES;
+ unsigned char buf[BUFSIZE];
+ int output_index = 0;
+ int output_items_produced;
+ int bytes_read;
+ bool overrun;
+
+ while (output_index < noutput_items){
+ int nbytes = ninput_bytes_reqd_for_noutput_items (noutput_items - output_index);
+ nbytes = std::min (nbytes, BUFSIZE);
+
+ int result_nbytes = d_usrp->read (buf, nbytes, &overrun);
+ if (overrun){
+ // fprintf (stderr, "usrp_source: overrun\n");
+ fputs ("uO", stderr);
+ d_noverruns++;
+ }
+
+ if (result_nbytes < 0) // We've got a problem. Usually board unplugged or powered down.
+ return -1; // Indicate we're done.
+
+ if (result_nbytes != nbytes){ // not really an error, but unexpected
+ fprintf (stderr, "usrp_source: short read. Expected %d, got %d\n",
+ nbytes, result_nbytes);
+ }
+
+ copy_from_usrp_buffer (output_items,
+ output_index,
+ noutput_items - output_index, // output_items_available
+ output_items_produced, // [out]
+ buf, // usrp_buffer
+ result_nbytes, // usrp_buffer_length
+ bytes_read); // [out]
+
+ assert (output_index + output_items_produced <= noutput_items);
+ assert (bytes_read == result_nbytes);
+
+ output_index += output_items_produced;
+ }
+
+ return noutput_items;
+}
+
+
+bool
+usrp_source_base::set_decim_rate (unsigned int rate)
+{
+ return d_usrp->set_decim_rate (rate);
+}
+
+bool
+usrp_source_base::set_nchannels (int nchan)
+{
+ return d_usrp->set_nchannels (nchan);
+}
+
+bool
+usrp_source_base::set_mux (int mux)
+{
+ return d_usrp->set_mux (mux);
+}
+
+int
+usrp_source_base::determine_rx_mux_value(usrp_subdev_spec ss)
+{
+ return d_usrp->determine_rx_mux_value(ss);
+}
+
+bool
+usrp_source_base::set_rx_freq (int channel, double freq)
+{
+ return d_usrp->set_rx_freq (channel, freq);
+}
+
+unsigned int
+usrp_source_base::decim_rate () const
+{
+ return d_usrp->decim_rate ();
+}
+
+int
+usrp_source_base::nchannels () const
+{
+ return d_usrp->nchannels ();
+}
+
+int
+usrp_source_base::mux () const
+{
+ return d_usrp->mux ();
+}
+
+double
+usrp_source_base::rx_freq (int channel) const
+{
+ return d_usrp->rx_freq (channel);
+}
+
+bool
+usrp_source_base::set_fpga_mode (int mode)
+{
+ return d_usrp->set_fpga_mode (mode);
+}
+
+bool
+usrp_source_base::set_ddc_phase (int channel, int phase)
+{
+ return d_usrp->set_ddc_phase(channel, phase);
+}
+
+
+bool
+usrp_source_base::set_format(unsigned int format)
+{
+ return d_usrp->set_format(format);
+}
+
+unsigned int
+usrp_source_base::format() const
+{
+ return d_usrp->format();
+}
+
+unsigned int
+usrp_source_base::make_format(int width, int shift, bool want_q, bool bypass_halfband)
+{
+ return usrp_standard_rx::make_format(width, shift, want_q, bypass_halfband);
+}
+
+int
+usrp_source_base::format_width(unsigned int format)
+{
+ return usrp_standard_rx::format_width(format);
+}
+
+int
+usrp_source_base::format_shift(unsigned int format)
+{
+ return usrp_standard_rx::format_shift(format);
+}
+
+bool
+usrp_source_base::format_want_q(unsigned int format)
+{
+ return usrp_standard_rx::format_want_q(format);
+}
+
+bool
+usrp_source_base::format_bypass_halfband(unsigned int format)
+{
+ return usrp_standard_rx::format_bypass_halfband(format);
+}
+
+bool
+usrp_source_base::has_rx_halfband()
+{
+ return d_usrp->has_rx_halfband();
+}
+
+bool
+usrp_source_base::has_tx_halfband()
+{
+ return d_usrp->has_tx_halfband();
+}
+
+int
+usrp_source_base::nddcs()
+{
+ return d_usrp->nddcs();
+}
+
+int
+usrp_source_base::nducs()
+{
+ return d_usrp->nducs();
+}
+
+bool
+usrp_source_base::start()
+{
+ return d_usrp->start();
+}
+
+bool
+usrp_source_base::stop()
+{
+ return d_usrp->stop();
+}
+
+bool
+usrp_source_base::tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result)
+{
+ return d_usrp->tune(chan, db, target_freq, result);
+}
+
+usrp_subdev_spec
+usrp_source_base::pick_rx_subdevice()
+{
+ int dbids[] = {
+ USRP_DBID_FLEX_400_RX,
+ USRP_DBID_FLEX_900_RX,
+ USRP_DBID_FLEX_1200_RX,
+ USRP_DBID_FLEX_2400_RX,
+ USRP_DBID_TV_RX,
+ USRP_DBID_TV_RX_REV_2,
+ USRP_DBID_DBS_RX,
+ USRP_DBID_DBS_RX_REV_2_1,
+ USRP_DBID_BASIC_RX
+ };
+
+ std::vector<int> candidates(dbids, dbids+(sizeof(dbids)/sizeof(int)));
+ return pick_subdev(candidates);
+}
diff --git a/gr-usrp/src/usrp_source_base.h b/gr-usrp/src/usrp_source_base.h
new file mode 100644
index 0000000000..9d8f32ac73
--- /dev/null
+++ b/gr-usrp/src/usrp_source_base.h
@@ -0,0 +1,219 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_USRP_SOURCE_BASE_H
+#define INCLUDED_USRP_SOURCE_BASE_H
+
+#include <usrp_base.h>
+#include <stdexcept>
+#include <usrp_tune_result.h>
+#include <usrp_dbid.h>
+
+class usrp_standard_rx;
+
+/*!
+ * \brief abstract interface to Universal Software Radio Peripheral Rx path (Rev 1)
+ */
+class usrp_source_base : public usrp_base {
+ private:
+ boost::shared_ptr<usrp_standard_rx> d_usrp;
+ int d_noverruns;
+
+ protected:
+ usrp_source_base (const std::string &name,
+ gr_io_signature_sptr output_signature,
+ int which_board,
+ unsigned int decim_rate,
+ int nchan,
+ int mux,
+ int mode,
+ int fusb_block_size,
+ int fusb_nblocks,
+ const std::string fpga_filename,
+ const std::string firmware_filename
+ ) throw (std::runtime_error);
+
+ /*!
+ * \brief return number of usrp input bytes required to produce noutput items.
+ */
+ virtual int ninput_bytes_reqd_for_noutput_items (int noutput_items) = 0;
+
+ /*!
+ * \brief number of bytes in a low-level sample
+ */
+ unsigned int sizeof_basic_sample() const;
+
+ /*!
+ * \brief convert between native usrp format and output item format
+ *
+ * \param output_items[out] stream(s) of output items
+ * \param output_index[in] starting index in output_items
+ * \param output_items_available[in] number of empty items available at item[index]
+ * \param output_items_produced[out] number of items produced by copy
+ * \param usrp_buffer[in] source buffer
+ * \param usrp_buffer_length[in] number of bytes available in \p usrp_buffer
+ * \param bytes_read[out] number of bytes read from \p usrp_buffer
+ *
+ * The copy must consume all bytes available. That is, \p bytes_read must equal
+ * \p usrp_buffer_length.
+ */
+ virtual void copy_from_usrp_buffer (gr_vector_void_star &output_items,
+ int output_index,
+ int output_items_available,
+ int &output_items_produced,
+ const void *usrp_buffer,
+ int usrp_buffer_length,
+ int &bytes_read) = 0;
+
+ public:
+ ~usrp_source_base ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ /*!
+ * \brief Set decimator rate. \p rate must be EVEN and in [8, 256].
+ *
+ * The final complex sample rate across the USB is
+ * adc_freq () / decim_rate ()
+ */
+ bool set_decim_rate (unsigned int rate);
+ bool set_nchannels (int nchan);
+ bool set_mux (int mux);
+ int determine_rx_mux_value(usrp_subdev_spec ss);
+
+ /*!
+ * \brief set the center frequency of the digital down converter.
+ *
+ * \p channel must be 0. \p freq is the center frequency in Hz.
+ * It must be in the range [-FIXME, FIXME]. The frequency specified is
+ * quantized. Use rx_freq to retrieve the actual value used.
+ */
+ bool set_rx_freq (int channel, double freq);
+
+ /*!
+ * \brief set fpga special modes
+ */
+ bool set_fpga_mode (int mode);
+
+ /*!
+ * \brief Set the digital down converter phase register.
+ *
+ * \param channel which ddc channel [0, 3]
+ * \param phase 32-bit integer phase value.
+ */
+ bool set_ddc_phase(int channel, int phase);
+
+ long adc_rate() const { return converter_rate(); } // alias
+ long adc_freq() const { return converter_rate(); } // deprecated alias
+
+ unsigned int decim_rate () const;
+ int nchannels () const;
+ int mux () const;
+ double rx_freq (int channel) const;
+ int noverruns () const { return d_noverruns; }
+
+ bool has_rx_halfband();
+ bool has_tx_halfband();
+ int nddcs();
+ int nducs();
+
+ /*!
+ * \brief Called to enable drivers, etc for i/o devices.
+ *
+ * This allows a block to enable an associated driver to begin
+ * transfering data just before we start to execute the scheduler.
+ * The end result is that this reduces latency in the pipeline when
+ * dealing with audio devices, usrps, etc.
+ */
+ bool start();
+
+ /*!
+ * \brief Called to disable drivers, etc for i/o devices.
+ */
+ bool stop();
+
+ /*!
+ * \brief Specify Rx data format.
+ *
+ * \param format format specifier
+ *
+ * Rx data format control register
+ *
+ * 3 2 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-----------------------------------------+-+-+---------+-------+
+ * | Reserved (Must be zero) |B|Q| WIDTH | SHIFT |
+ * +-----------------------------------------+-+-+---------+-------+
+ *
+ * SHIFT specifies arithmetic right shift [0, 15]
+ * WIDTH specifies bit-width of I & Q samples across the USB [1, 16] (not all valid)
+ * Q if set deliver both I & Q, else just I
+ * B if set bypass half-band filter.
+ *
+ * Right now the acceptable values are:
+ *
+ * B Q WIDTH SHIFT
+ * 0 1 16 0
+ * 0 1 8 8
+ *
+ * More valid combos to come.
+ *
+ * Default value is 0x00000300 16-bits, 0 shift, deliver both I & Q.
+ */
+ bool set_format(unsigned int format);
+
+ /*!
+ * \brief return current format
+ */
+ unsigned int format () const;
+
+ static unsigned int make_format(int width=16, int shift=0,
+ bool want_q=true, bool bypass_halfband=false);
+ static int format_width(unsigned int format);
+ static int format_shift(unsigned int format);
+ static bool format_want_q(unsigned int format);
+ static bool format_bypass_halfband(unsigned int format);
+
+ /*!
+ * \brief High-level "tune" method. Works for the single channel case.
+ *
+ * This method adjusts both the daughterboard LO and the DDC so that
+ * target_freq ends up at DC in the complex baseband samples.
+ *
+ * \param chan which DDC channel we're controlling (almost always 0).
+ * \param db the daughterboard we're controlling.
+ * \param target_freq the RF frequency we want at DC in the complex baseband.
+ * \param[out] tune_result details how the hardware was configured.
+ *
+ * \returns true iff everything was successful.
+ */
+ bool tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result);
+
+ /*!
+ * \brief Select suitable Rx daughterboard
+ */
+ usrp_subdev_spec pick_rx_subdevice();
+};
+
+#endif /* INCLUDED_USRP_SOURCE_BASE_H */
diff --git a/gr-usrp/src/usrp_source_base.i b/gr-usrp/src/usrp_source_base.i
new file mode 100644
index 0000000000..6a70c74129
--- /dev/null
+++ b/gr-usrp/src/usrp_source_base.i
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+#include "usrp_source_base.h"
+%}
+
+class usrp_source_base : public usrp_base
+{
+private:
+ usrp_source_base() throw (std::runtime_error);
+
+public:
+ bool set_decim_rate (unsigned int rate);
+ bool set_nchannels (int nchan);
+ bool set_mux (int mux);
+ %rename(_real_determine_rx_mux_value) determine_rx_mux_value;
+ int determine_rx_mux_value(usrp_subdev_spec ss);
+ bool set_rx_freq (int channel, double freq);
+ bool set_fpga_mode (int mode);
+ bool set_ddc_phase(int channel, int phase);
+ long adc_rate() const { return converter_rate(); }
+ long adc_freq() const { return converter_rate(); }
+ unsigned int decim_rate () const;
+ int nchannels () const;
+ int mux () const;
+ double rx_freq (int channel) const;
+ int noverruns () const { return d_noverruns; }
+ bool has_rx_halfband();
+ bool has_tx_halfband();
+ int nddcs();
+ int nducs();
+ bool set_format(unsigned int format);
+ static unsigned int make_format(int width=16, int shift=0,
+ bool want_q=true, bool bypass_halfband=false);
+ static int format_width(unsigned int format);
+ static int format_shift(unsigned int format);
+ static bool format_want_q(unsigned int format);
+ static bool format_bypass_halfband(unsigned int format);
+ %rename(_real_tune) tune;
+ bool tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result);
+ %rename(_real_pick_rx_subdevice) pick_rx_subdevice();
+ usrp_subdev_spec pick_rx_subdevice();
+};
diff --git a/gr-usrp/src/usrp1_source_c.cc b/gr-usrp/src/usrp_source_c.cc
index a5b82ab728..71ca1e0d7c 100644
--- a/gr-usrp/src/usrp1_source_c.cc
+++ b/gr-usrp/src/usrp_source_c.cc
@@ -24,15 +24,15 @@
#include "config.h"
#endif
-#include <usrp1_source_c.h>
+#include <usrp_source_c.h>
#include <gr_io_signature.h>
#include <usrp_standard.h>
#include <usrp_bytesex.h>
static const int NBASIC_SAMPLES_PER_ITEM = 2; // I & Q
-usrp1_source_c_sptr
-usrp1_make_source_c (int which_board,
+usrp_source_c_sptr
+usrp_make_source_c (int which_board,
unsigned int decim_rate,
int nchan,
int mux,
@@ -43,7 +43,7 @@ usrp1_make_source_c (int which_board,
const std::string firmware_filename
) throw (std::runtime_error)
{
- return usrp1_source_c_sptr (new usrp1_source_c (which_board,
+ return usrp_source_c_sptr (new usrp_source_c (which_board,
decim_rate,
nchan,
mux,
@@ -56,7 +56,7 @@ usrp1_make_source_c (int which_board,
}
-usrp1_source_c::usrp1_source_c (int which_board,
+usrp_source_c::usrp_source_c (int which_board,
unsigned int decim_rate,
int nchan,
int mux,
@@ -66,7 +66,7 @@ usrp1_source_c::usrp1_source_c (int which_board,
const std::string fpga_filename,
const std::string firmware_filename
) throw (std::runtime_error)
- : usrp1_source_base ("usrp1_source_c",
+ : usrp_source_base ("usrp_source_c",
gr_make_io_signature (1, 1, sizeof (gr_complex)),
which_board, decim_rate, nchan, mux, mode,
fusb_block_size, fusb_nblocks,
@@ -74,13 +74,13 @@ usrp1_source_c::usrp1_source_c (int which_board,
{
}
-usrp1_source_c::~usrp1_source_c ()
+usrp_source_c::~usrp_source_c ()
{
// NOP
}
int
-usrp1_source_c::ninput_bytes_reqd_for_noutput_items (int noutput_items)
+usrp_source_c::ninput_bytes_reqd_for_noutput_items (int noutput_items)
{
return noutput_items * NBASIC_SAMPLES_PER_ITEM * sizeof_basic_sample();
}
@@ -90,7 +90,7 @@ usrp1_source_c::ninput_bytes_reqd_for_noutput_items (int noutput_items)
* complex output stream.
*/
void
-usrp1_source_c::copy_from_usrp_buffer (gr_vector_void_star &output_items,
+usrp_source_c::copy_from_usrp_buffer (gr_vector_void_star &output_items,
int output_index,
int output_items_available,
int &output_items_produced,
diff --git a/gr-usrp/src/usrp1_source_c.h b/gr-usrp/src/usrp_source_c.h
index 0d6e50e034..39a282b8da 100644
--- a/gr-usrp/src/usrp1_source_c.h
+++ b/gr-usrp/src/usrp_source_c.h
@@ -20,40 +20,40 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef INCLUDED_USRP1_SOURCE_C_H
-#define INCLUDED_USRP1_SOURCE_C_H
+#ifndef INCLUDED_USRP_SOURCE_C_H
+#define INCLUDED_USRP_SOURCE_C_H
-#include <usrp1_source_base.h>
+#include <usrp_source_base.h>
#include <stdexcept>
class usrp_standard_rx;
-class usrp1_source_c;
-typedef boost::shared_ptr<usrp1_source_c> usrp1_source_c_sptr;
+class usrp_source_c;
+typedef boost::shared_ptr<usrp_source_c> usrp_source_c_sptr;
// public shared_ptr constructor
-usrp1_source_c_sptr
-usrp1_make_source_c (int which_board,
- unsigned int decim_rate,
- int nchan,
- int mux,
- int mode,
- int fusb_block_size,
- int fusb_nblocks,
- const std::string fpga_filename,
- const std::string firmware_filename
+usrp_source_c_sptr
+usrp_make_source_c (int which_board=0,
+ unsigned int decim_rate=16,
+ int nchan = 1,
+ int mux = -1,
+ int mode = 0,
+ int fusb_block_size = 0,
+ int fusb_nblocks = 0,
+ const std::string fpga_filename = "",
+ const std::string firmware_filename = ""
) throw (std::runtime_error);
/*!
* \brief interface to Universal Software Radio Peripheral Rx path (Rev 1)
*/
-class usrp1_source_c : public usrp1_source_base {
+class usrp_source_c : public usrp_source_base {
private:
- friend usrp1_source_c_sptr
- usrp1_make_source_c (int which_board,
+ friend usrp_source_c_sptr
+ usrp_make_source_c (int which_board,
unsigned int decim_rate,
int nchan,
int mux,
@@ -65,7 +65,7 @@ class usrp1_source_c : public usrp1_source_base {
) throw (std::runtime_error);
protected:
- usrp1_source_c (int which_board,
+ usrp_source_c (int which_board,
unsigned int decim_rate,
int nchan,
int mux,
@@ -87,7 +87,7 @@ class usrp1_source_c : public usrp1_source_base {
int &bytes_read);
public:
- ~usrp1_source_c ();
+ ~usrp_source_c ();
};
-#endif /* INCLUDED_USRP1_SOURCE_C_H */
+#endif /* INCLUDED_USRP_SOURCE_C_H */
diff --git a/gr-usrp/src/usrp_source_c.i b/gr-usrp/src/usrp_source_c.i
new file mode 100644
index 0000000000..499f7f740b
--- /dev/null
+++ b/gr-usrp/src/usrp_source_c.i
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+#include "usrp_source_c.h"
+%}
+
+GR_SWIG_BLOCK_MAGIC(usrp,source_c)
+
+class usrp_source_c;
+typedef boost::shared_ptr<usrp_source_c> usrp_source_c_sptr;
+
+usrp_source_c_sptr
+usrp_make_source_c(int which=0,
+ unsigned int decim_rate=16,
+ int nchan=1,
+ int mux=-1,
+ int mode=0,
+ int fusb_block_size=0,
+ int fusb_nblocks=0,
+ const std::string fpga_filename="",
+ const std::string firmware_filename=""
+ ) throw (std::runtime_error);
+
+class usrp_source_c : public usrp_source_base
+{
+private:
+ usrp_source_c() throw (std::runtime_error);
+};
diff --git a/gr-usrp/src/usrp1_source_s.cc b/gr-usrp/src/usrp_source_s.cc
index 8295d929bc..f20384599f 100644
--- a/gr-usrp/src/usrp1_source_s.cc
+++ b/gr-usrp/src/usrp_source_s.cc
@@ -24,15 +24,15 @@
#include "config.h"
#endif
-#include <usrp1_source_s.h>
+#include <usrp_source_s.h>
#include <gr_io_signature.h>
#include <usrp_standard.h>
#include <usrp_bytesex.h>
static const int NBASIC_SAMPLES_PER_ITEM = 1;
-usrp1_source_s_sptr
-usrp1_make_source_s (int which_board,
+usrp_source_s_sptr
+usrp_make_source_s (int which_board,
unsigned int decim_rate,
int nchan,
int mux,
@@ -43,7 +43,7 @@ usrp1_make_source_s (int which_board,
const std::string firmware_filename
) throw (std::runtime_error)
{
- return usrp1_source_s_sptr (new usrp1_source_s (which_board,
+ return usrp_source_s_sptr (new usrp_source_s (which_board,
decim_rate,
nchan,
mux,
@@ -56,7 +56,7 @@ usrp1_make_source_s (int which_board,
}
-usrp1_source_s::usrp1_source_s (int which_board,
+usrp_source_s::usrp_source_s (int which_board,
unsigned int decim_rate,
int nchan,
int mux,
@@ -66,7 +66,7 @@ usrp1_source_s::usrp1_source_s (int which_board,
const std::string fpga_filename,
const std::string firmware_filename
) throw (std::runtime_error)
- : usrp1_source_base ("usrp1_source_s",
+ : usrp_source_base ("usrp_source_s",
gr_make_io_signature (1, 1, sizeof (short)),
which_board, decim_rate, nchan, mux, mode,
fusb_block_size,
@@ -75,13 +75,13 @@ usrp1_source_s::usrp1_source_s (int which_board,
{
}
-usrp1_source_s::~usrp1_source_s ()
+usrp_source_s::~usrp_source_s ()
{
// NOP
}
int
-usrp1_source_s::ninput_bytes_reqd_for_noutput_items (int noutput_items)
+usrp_source_s::ninput_bytes_reqd_for_noutput_items (int noutput_items)
{
return noutput_items * NBASIC_SAMPLES_PER_ITEM * sizeof_basic_sample();
}
@@ -91,7 +91,7 @@ usrp1_source_s::ninput_bytes_reqd_for_noutput_items (int noutput_items)
* short output stream.
*/
void
-usrp1_source_s::copy_from_usrp_buffer (gr_vector_void_star &output_items,
+usrp_source_s::copy_from_usrp_buffer (gr_vector_void_star &output_items,
int output_index,
int output_items_available,
int &output_items_produced,
diff --git a/gr-usrp/src/usrp1_source_s.h b/gr-usrp/src/usrp_source_s.h
index 35beb42a82..6f7f98b2b4 100644
--- a/gr-usrp/src/usrp1_source_s.h
+++ b/gr-usrp/src/usrp_source_s.h
@@ -20,42 +20,42 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef INCLUDED_USRP1_SOURCE_S_H
-#define INCLUDED_USRP1_SOURCE_S_H
+#ifndef INCLUDED_USRP_SOURCE_S_H
+#define INCLUDED_USRP_SOURCE_S_H
-#include <usrp1_source_base.h>
+#include <usrp_source_base.h>
#include <stdexcept>
class usrp_standard_rx;
-class usrp1_source_s;
-typedef boost::shared_ptr<usrp1_source_s> usrp1_source_s_sptr;
+class usrp_source_s;
+typedef boost::shared_ptr<usrp_source_s> usrp_source_s_sptr;
// public shared_ptr constructor
-usrp1_source_s_sptr
-usrp1_make_source_s (int which_board,
- unsigned int decim_rate,
- int nchan,
- int mux,
- int mode,
- int fusb_block_size,
- int fusb_nblocks,
- const std::string fpga_filename,
- const std::string firmware_filename
- ) throw (std::runtime_error);
+usrp_source_s_sptr
+usrp_make_source_s (int which_board=0,
+ unsigned int decim_rate=16,
+ int nchan=1,
+ int mux=-1,
+ int mode=0,
+ int fusb_block_size=0,
+ int fusb_nblocks=0,
+ const std::string fpga_filename="",
+ const std::string firmware_filename=""
+ ) throw (std::runtime_error);
/*!
* \brief interface to Universal Software Radio Peripheral Rx path (Rev 1)
*
* output: 1 stream of short
*/
-class usrp1_source_s : public usrp1_source_base {
+class usrp_source_s : public usrp_source_base {
private:
- friend usrp1_source_s_sptr
- usrp1_make_source_s (int which_board,
+ friend usrp_source_s_sptr
+ usrp_make_source_s (int which_board,
unsigned int decim_rate,
int nchan,
int mux,
@@ -67,7 +67,7 @@ class usrp1_source_s : public usrp1_source_base {
) throw (std::runtime_error);
protected:
- usrp1_source_s (int which_board,
+ usrp_source_s (int which_board,
unsigned int decim_rate,
int nchan,
int mux,
@@ -88,7 +88,7 @@ class usrp1_source_s : public usrp1_source_base {
int usrp_buffer_length,
int &bytes_read);
public:
- ~usrp1_source_s ();
+ ~usrp_source_s ();
};
-#endif /* INCLUDED_USRP1_SOURCE_S_H */
+#endif /* INCLUDED_USRP_SOURCE_S_H */
diff --git a/gr-usrp/src/usrp_source_s.i b/gr-usrp/src/usrp_source_s.i
new file mode 100644
index 0000000000..d8b285c99f
--- /dev/null
+++ b/gr-usrp/src/usrp_source_s.i
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+#include "usrp_source_s.h"
+%}
+
+GR_SWIG_BLOCK_MAGIC(usrp,source_s)
+
+class usrp_source_s;
+typedef boost::shared_ptr<usrp_source_s> usrp_source_s_sptr;
+
+usrp_source_s_sptr
+usrp_make_source_s(int which=0,
+ unsigned int decim_rate=16,
+ int nchan=1,
+ int mux=-1,
+ int mode=0,
+ int fusb_block_size=0,
+ int fusb_nblocks=0,
+ const std::string fpga_filename="",
+ const std::string firmware_filename=""
+ ) throw (std::runtime_error);
+
+class usrp_source_s : public usrp_source_base
+{
+private:
+ usrp_source_s() throw (std::runtime_error);
+};
diff --git a/gr-usrp/src/usrp_standard.i b/gr-usrp/src/usrp_standard.i
new file mode 100644
index 0000000000..7d32cdf813
--- /dev/null
+++ b/gr-usrp/src/usrp_standard.i
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// FIXME: move to usrp/usrpm component
+
+%{
+#include <usrp_standard.h>
+#include <usrp_spi_defs.h>
+#include <usrp_dbid.h>
+%}
+
+%include <usrp_spi_defs.h>
+%include <usrp_dbid.h>
+
+%constant int FPGA_MODE_NORMAL = usrp_standard_rx::FPGA_MODE_NORMAL;
+%constant int FPGA_MODE_LOOPBACK = usrp_standard_rx::FPGA_MODE_LOOPBACK;
+%constant int FPGA_MODE_COUNTING = usrp_standard_rx::FPGA_MODE_COUNTING;
diff --git a/gr-utils/src/python/usrp_fft.py b/gr-utils/src/python/usrp_fft.py
index fcf4c0535d..4aa70adab9 100755
--- a/gr-utils/src/python/usrp_fft.py
+++ b/gr-utils/src/python/usrp_fft.py
@@ -37,9 +37,9 @@ def pick_subdevice(u):
If there's a daughterboard on B, select B.
Otherwise, select A.
"""
- if u.db[0][0].dbid() >= 0: # dbid is < 0 if there's no d'board or a problem
+ if u.db(0, 0).dbid() >= 0: # dbid is < 0 if there's no d'board or a problem
return (0, 0)
- if u.db[1][0].dbid() >= 0:
+ if u.db(0, 0).dbid() >= 0:
return (1, 0)
return (0, 0)
diff --git a/gr-utils/src/python/usrp_oscope.py b/gr-utils/src/python/usrp_oscope.py
index d3223cba31..f4a539dd59 100755
--- a/gr-utils/src/python/usrp_oscope.py
+++ b/gr-utils/src/python/usrp_oscope.py
@@ -40,9 +40,9 @@ def pick_subdevice(u):
If there's a daughterboard on B, select B.
Otherwise, select A.
"""
- if u.db[0][0].dbid() >= 0: # dbid is < 0 if there's no d'board or a problem
+ if u.db(0, 0).dbid() >= 0: # dbid is < 0 if there's no d'board or a problem
return (0, 0)
- if u.db[1][0].dbid() >= 0:
+ if u.db(0, 0).dbid() >= 0:
return (1, 0)
return (0, 0)
diff --git a/gr-utils/src/python/usrp_siggen.py b/gr-utils/src/python/usrp_siggen.py
index fe29787f9a..3e7751c00f 100755
--- a/gr-utils/src/python/usrp_siggen.py
+++ b/gr-utils/src/python/usrp_siggen.py
@@ -118,7 +118,7 @@ class my_top_block(gr.top_block):
the result of that operation and our target_frequency to
determine the value for the digital up converter.
"""
- r = self.u.tune(self.subdev._which, self.subdev, target_freq)
+ r = self.u.tune(self.subdev.which(), self.subdev, target_freq)
if r:
#print "r.baseband_freq =", eng_notation.num_to_str(r.baseband_freq)
#print "r.dxc_freq =", eng_notation.num_to_str(r.dxc_freq)
@@ -200,5 +200,6 @@ def main ():
except KeyboardInterrupt:
pass
+
if __name__ == '__main__':
main ()
diff --git a/grc/src/grc_gnuradio/usrp/simple_usrp.py b/grc/src/grc_gnuradio/usrp/simple_usrp.py
index dd33ef12bc..c1019d334a 100644
--- a/grc/src/grc_gnuradio/usrp/simple_usrp.py
+++ b/grc/src/grc_gnuradio/usrp/simple_usrp.py
@@ -79,7 +79,7 @@ def _setup_tx_subdev(u, subdev_spec, gain, frequency, auto_tr=None, tx_enb=None)
"""
subdev = usrp.selected_subdev(u, subdev_spec)#get the subdev
subdev.set_gain(gain)
- _set_frequency(u, subdev._which, subdev, frequency, verbose=True)
+ _set_frequency(u, subdev.which(), subdev, frequency, verbose=True)
if auto_tr is not None: subdev.set_auto_tr(auto_tr)
if tx_enb is not None: subdev.set_enable(tx_enb)
return subdev
@@ -162,10 +162,10 @@ class _simple_source(gr.hier_block2, _simple_usrp):
gr.hier_block2.__init__(
self, 'usrp_simple_source',
gr.io_signature(0, 0, 0),
- gr.io_signature(1, 1, constructor_to_size[self.constructor]),
+ gr.io_signature(1, 1, constructor_to_size[self.constructor[0]]),
)
#create usrp object
- u = self.constructor(number, nchan=1)
+ u = self.constructor[0](number, nchan=1)
if subdev_spec is None: subdev_spec = usrp.pick_rx_subdevice(u)
u.set_decim_rate(decimation)
if mux is None: mux = usrp.determine_rx_mux_value(u, subdev_spec)
@@ -177,8 +177,8 @@ class _simple_source(gr.hier_block2, _simple_usrp):
def set_decim_rate(self, decim): self.get_u().set_decim_rate(int(decim))
-class simple_source_c(_simple_source): constructor = usrp.source_c
-class simple_source_s(_simple_source): constructor = usrp.source_s
+class simple_source_c(_simple_source): constructor = (usrp.source_c, )
+class simple_source_s(_simple_source): constructor = (usrp.source_s, )
####################################################################
# Simple USRP Sink
@@ -201,24 +201,24 @@ class _simple_sink(gr.hier_block2, _simple_usrp):
#initialize hier2 block
gr.hier_block2.__init__(
self, 'usrp_simple_sink',
- gr.io_signature(1, 1, constructor_to_size[self.constructor]),
+ gr.io_signature(1, 1, constructor_to_size[self.constructor[0]]),
gr.io_signature(0, 0, 0),
)
#create usrp object
- u = self.constructor(number, nchan=1)
+ u = self.constructor[0](number, nchan=1)
if subdev_spec is None: subdev_spec = usrp.pick_tx_subdevice(u)
u.set_interp_rate(interpolation)
if mux is None: mux = usrp.determine_tx_mux_value(u, subdev_spec)
u.set_mux(mux)
subdev = _setup_tx_subdev(u, subdev_spec, gain, frequency, auto_tr, tx_enb)
- _simple_usrp.__init__(self, u, subdev, subdev._which)
+ _simple_usrp.__init__(self, u, subdev, subdev.which())
#connect
self.connect(self, u)
def set_interp_rate(self, interp): self.get_u().set_interp_rate(int(interp))
-class simple_sink_c(_simple_sink): constructor = usrp.sink_c
-class simple_sink_s(_simple_sink): constructor = usrp.sink_s
+class simple_sink_c(_simple_sink): constructor = (usrp.sink_c, )
+class simple_sink_s(_simple_sink): constructor = (usrp.sink_s, )
####################################################################
####################################################################
@@ -317,17 +317,17 @@ class _dual_source(gr.hier_block2, _dual_usrp):
gr.hier_block2.__init__(
self, 'usrp_dual_source',
gr.io_signature(0, 0, 0),
- gr.io_signature(2, 2, constructor_to_size[self.constructor]),
+ gr.io_signature(2, 2, constructor_to_size[self.constructor[0]]),
)
#create usrp object
- u = self.constructor(number, nchan=2)
+ u = self.constructor[0](number, nchan=2)
u.set_decim_rate(decimation)
u.set_mux(mux)
subdev_a = _setup_rx_subdev(u, (0, 0), 0, gain_a, frequency_a, auto_tr, rx_ant_a)
subdev_b = _setup_rx_subdev(u, (1, 0), 1, gain_b, frequency_b, auto_tr, rx_ant_b)
_dual_usrp.__init__(self, u, subdev_a, subdev_b, 0, 1)
#connect
- deinter = gr.deinterleave(constructor_to_size[self.constructor])
+ deinter = gr.deinterleave(constructor_to_size[self.constructor[0]])
self.connect(u, deinter)
for i in range(2): self.connect((deinter, i), (self, i))
@@ -357,18 +357,18 @@ class _dual_sink(gr.hier_block2, _dual_usrp):
#initialize hier2 block
gr.hier_block2.__init__(
self, 'usrp_dual_sink',
- gr.io_signature(2, 2, constructor_to_size[self.constructor]),
+ gr.io_signature(2, 2, constructor_to_size[self.constructor[0]]),
gr.io_signature(0, 0, 0),
)
#create usrp object
- u = self.constructor(number, nchan=2)
+ u = self.constructor[0](number, nchan=2)
u.set_interp_rate(interpolation)
u.set_mux(mux)
subdev_a = _setup_tx_subdev(u, (0, 0), gain_a, frequency_a, auto_tr, tx_enb_a)
subdev_b = _setup_tx_subdev(u, (1, 0), gain_b, frequency_b, auto_tr, tx_enb_b)
- _dual_usrp.__init__(self, u, subdev_a, subdev_b, subdev_a._which, subdev_b._which)
+ _dual_usrp.__init__(self, u, subdev_a, subdev_b, subdev_a.which(), subdev_b.which())
#connect
- inter = gr.interleave(constructor_to_size[self.constructor])
+ inter = gr.interleave(constructor_to_size[self.constructor[0]])
self.connect(inter, u)
for i in range(2): self.connect((self, i), (inter, i))
diff --git a/usrp/host/apps/test_usrp_standard_rx.cc b/usrp/host/apps/test_usrp_standard_rx.cc
index 49f1f21bb5..4a47daa95b 100644
--- a/usrp/host/apps/test_usrp_standard_rx.cc
+++ b/usrp/host/apps/test_usrp_standard_rx.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2003,2006 Free Software Foundation, Inc.
+ * Copyright 2003,2006,2008 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -44,7 +44,7 @@
char *prog_name;
-static bool test_input (usrp_standard_rx *urx, int max_bytes, FILE *fp);
+static bool test_input (usrp_standard_rx_sptr urx, int max_bytes, FILE *fp);
static void
set_progname (char *path)
@@ -189,7 +189,7 @@ main (int argc, char **argv)
mode |= usrp_standard_rx::FPGA_MODE_COUNTING;
- usrp_standard_rx *urx =
+ usrp_standard_rx_sptr urx =
usrp_standard_rx::make (which_board, decim, 1, -1, mode,
fusb_block_size, fusb_nblocks);
@@ -214,14 +214,12 @@ main (int argc, char **argv)
if (fp)
fclose (fp);
- delete urx;
-
return 0;
}
static bool
-test_input (usrp_standard_rx *urx, int max_bytes, FILE *fp)
+test_input (usrp_standard_rx_sptr urx, int max_bytes, FILE *fp)
{
int fd = -1;
static const int BUFSIZE = urx->block_size();
diff --git a/usrp/host/apps/test_usrp_standard_tx.cc b/usrp/host/apps/test_usrp_standard_tx.cc
index 6418c4abff..4889955263 100644
--- a/usrp/host/apps/test_usrp_standard_tx.cc
+++ b/usrp/host/apps/test_usrp_standard_tx.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2003,2004 Free Software Foundation, Inc.
+ * Copyright 2003,2004,2008 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -42,7 +42,7 @@
char *prog_name;
-static bool test_output (usrp_standard_tx *utx, int max_bytes, double ampl,
+static bool test_output (usrp_standard_tx_sptr utx, int max_bytes, double ampl,
bool dc_p, bool counting_p);
static void
@@ -210,7 +210,7 @@ main (int argc, char **argv)
}
#endif
- usrp_standard_tx *utx;
+ usrp_standard_tx_sptr utx;
utx = usrp_standard_tx::make (which_board,
interp,
@@ -226,7 +226,7 @@ main (int argc, char **argv)
die ("utx->set_tx_freq");
if (dump_regs_p)
- do_dump_codec_regs (utx);
+ do_dump_codec_regs (utx.get());
fflush (stdout);
@@ -236,14 +236,12 @@ main (int argc, char **argv)
test_output (utx, max_bytes, ampl, dc_p, counting_p);
- delete utx;
-
return 0;
}
static bool
-test_output (usrp_standard_tx *utx, int max_bytes, double ampl,
+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();
diff --git a/usrp/host/apps/usrp_cal_dc_offset.cc b/usrp/host/apps/usrp_cal_dc_offset.cc
index e836e1aabe..5ebac12a36 100644
--- a/usrp/host/apps/usrp_cal_dc_offset.cc
+++ b/usrp/host/apps/usrp_cal_dc_offset.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2005 Free Software Foundation, Inc.
+ * Copyright 2005,2008 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -43,7 +43,7 @@ char *prog_name;
static void
-run_cal(usrp_standard_rx *u, int which_side, int decim, bool verbose_p)
+run_cal(usrp_standard_rx_sptr u, int which_side, int decim, bool verbose_p)
{
static const int BUFSIZE = u->block_size();
static const int N = BUFSIZE/sizeof (short);
@@ -213,11 +213,11 @@ main (int argc, char **argv)
usrp_local_sighandler sigquit (SIGQUIT, usrp_local_sighandler::throw_signal);
#endif
- usrp_standard_rx *urx =
+ usrp_standard_rx_sptr urx =
usrp_standard_rx::make(which_board, decim,
nchannels, mux, mode,
fusb_block_size, fusb_nblocks);
- if (urx == 0)
+ if (!urx)
die("usrp_standard_rx::make");
try {
@@ -236,7 +236,5 @@ main (int argc, char **argv)
catch(...){
fprintf (stderr, "usrp_cal_dc_offset: caught something\n");
}
-
- delete urx;
}
diff --git a/usrp/host/lib/inband/qa_inband_usrp_server.cc b/usrp/host/lib/inband/qa_inband_usrp_server.cc
index c66418392a..6049a8a874 100644
--- a/usrp/host/lib/inband/qa_inband_usrp_server.cc
+++ b/usrp/host/lib/inband/qa_inband_usrp_server.cc
@@ -1543,6 +1543,9 @@ qa_inband_usrp_server::test_rx()
void
qa_inband_usrp_server::test_cs()
{
+ // FIXME This test is disabled because it hangs with the change to use usrp_standard_*_sptr's
+ return;
+
mb_runtime_sptr rt = mb_make_runtime();
pmt_t result = PMT_T;
@@ -1557,6 +1560,9 @@ qa_inband_usrp_server::test_cs()
void
qa_inband_usrp_server::test_rid()
{
+ // FIXME This test is disabled because it hangs with the change to use usrp_standard_*_sptr's
+ return;
+
mb_runtime_sptr rt = mb_make_runtime();
pmt_t result = PMT_T;
diff --git a/usrp/host/lib/inband/usrp_usb_interface.cc b/usrp/host/lib/inband/usrp_usb_interface.cc
index c69eb0b005..d82b589b48 100644
--- a/usrp/host/lib/inband/usrp_usb_interface.cc
+++ b/usrp/host/lib/inband/usrp_usb_interface.cc
@@ -143,13 +143,9 @@ usrp_usb_interface::usrp_usb_interface(mb_runtime *rt, const std::string &instan
connect("self", "rx_cs", "rx", "cs");
connect("self", "tx_cs", "tx", "cs");
- // FIX ME: the code should query the FPGA to retrieve the number of channels and such
+ // FIXME: the code should query the FPGA to retrieve the number of channels and such
d_ntx_chan = 2;
d_nrx_chan = 2;
-
- d_utx = NULL;
- d_urx = NULL;
-
}
usrp_usb_interface::~usrp_usb_interface()
@@ -394,8 +390,6 @@ usrp_usb_interface::handle_cmd_write(pmt_t data)
channel,
pkts,
tx_handle));
-
- return;
}
/*!
@@ -482,14 +476,13 @@ usrp_usb_interface::handle_cmd_close(pmt_t data)
if (verbose)
std::cout << "[USRP_USB_INTERFACE] Handling close request for USRP\n";
- delete d_utx;
- d_utx = 0;
-
- delete d_urx;
- d_urx = 0;
+ d_utx.reset();
+ d_urx.reset();
d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T));
+ // FIXME This seems like a _very_ strange place to be calling shutdown_all.
+ // That decision should be left to high-level code, not low-level code like this.
shutdown_all(PMT_T);
}
diff --git a/usrp/host/lib/inband/usrp_usb_interface.h b/usrp/host/lib/inband/usrp_usb_interface.h
index 5151f155c1..c10741516d 100644
--- a/usrp/host/lib/inband/usrp_usb_interface.h
+++ b/usrp/host/lib/inband/usrp_usb_interface.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2007 Free Software Foundation, Inc.
+ * Copyright 2007,2008 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -32,8 +32,8 @@ class usrp_usb_interface : public mb_mblock
{
public:
- usrp_standard_tx* d_utx;
- usrp_standard_rx* d_urx;
+ usrp_standard_tx_sptr d_utx;
+ usrp_standard_rx_sptr d_urx;
mb_port_sptr d_cs;
mb_port_sptr d_rx_cs;
diff --git a/usrp/host/lib/legacy/Makefile.am b/usrp/host/lib/legacy/Makefile.am
index d913b6bb12..7b880924cd 100644
--- a/usrp/host/lib/legacy/Makefile.am
+++ b/usrp/host/lib/legacy/Makefile.am
@@ -32,11 +32,11 @@ libusrp_la_common_LIBADD = \
# darwin fusb requires omnithreads
if FUSB_TECH_darwin
-AM_CPPFLAGS = $(common_INCLUDES) $(OMNITHREAD_INCLUDES) $(WITH_INCLUDES)
+AM_CPPFLAGS = $(common_INCLUDES) $(OMNITHREAD_INCLUDES) $(BOOST_CPPFLAGS) $(WITH_INCLUDES)
libusrp_la_LIBADD = $(libusrp_la_common_LIBADD) $(OMNITHREAD_LA)
libusrp_la_LDFLAGS = $(libusrp_la_common_LDFLAGS) -framework CoreFoundation
else
-AM_CPPFLAGS = $(common_INCLUDES) $(WITH_INCLUDES)
+AM_CPPFLAGS = $(common_INCLUDES) $(BOOST_CPPFLAGS) $(WITH_INCLUDES)
libusrp_la_LIBADD = $(libusrp_la_common_LIBADD)
libusrp_la_LDFLAGS = $(libusrp_la_common_LDFLAGS)
endif
@@ -104,7 +104,20 @@ libusrp_la_common_SOURCES = \
usrp_dbid.cc \
usrp_local_sighandler.cc \
usrp_prims.cc \
- usrp_standard.cc
+ usrp_standard.cc \
+ db_boards.cc \
+ db_base.cc \
+ db_basic.cc \
+ db_tv_rx.cc \
+ db_flexrf.cc \
+ db_flexrf_mimo.cc \
+ db_dbs_rx.cc \
+ db_xcvr2450.cc \
+ db_dtt754.cc \
+ db_dtt768.cc \
+ db_util.cc
+
+# db_wbx.cc
if FUSB_TECH_generic
@@ -128,22 +141,37 @@ libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(ra_wb_CODE)
endif
include_HEADERS = \
+ db_base.h \
usrp_basic.h \
usrp_bytesex.h \
usrp_config.h \
usrp_dbid.h \
usrp_prims.h \
usrp_slots.h \
- usrp_standard.h
+ usrp_standard.h \
+ usrp_subdev_spec.h \
+ usrp_tune_result.h
noinst_HEADERS = \
ad9862.h \
+ db_base_impl.h \
+ db_basic.h \
+ db_boards.h \
+ db_dbs_rx.h \
+ db_dtt754.h \
+ db_dtt768.h \
+ db_flexrf.h \
+ db_flexrf_mimo.h \
+ db_tv_rx.h \
+ db_util.h \
+ db_wbx.h \
+ db_xcvr2450.h \
fusb.h \
fusb_darwin.h \
- fusb_win32.h \
fusb_generic.h \
fusb_linux.h \
fusb_ra_wb.h \
+ fusb_win32.h \
md5.h \
rate_to_regval.h \
usrp_local_sighandler.h
@@ -159,5 +187,7 @@ noinst_PYTHON = \
usrp_dbid.py usrp_dbid.h usrp_dbid.cc: gen_usrp_dbid.py usrp_dbid.dat
PYTHONPATH=$(top_srcdir)/usrp/src srcdir=$(srcdir) $(PYTHON) $(srcdir)/gen_usrp_dbid.py $(srcdir)/usrp_dbid.dat
+swiginclude_HEADERS = db_base.i
+
MOSTLYCLEANFILES = \
$(BUILT_SOURCES) *~ *.pyc
diff --git a/usrp/host/lib/legacy/db_base.cc b/usrp/host/lib/legacy/db_base.cc
new file mode 100644
index 0000000000..9d970435f4
--- /dev/null
+++ b/usrp/host/lib/legacy/db_base.cc
@@ -0,0 +1,245 @@
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 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.
+//
+
+#include <db_base.h>
+#include <db_base_impl.h>
+
+#if 0
+tune_result::tune_result(double baseband, double dxc, double residual, bool inv)
+ : ok(false), baseband_freq(baseband), dxc_freq(dxc),
+ residual_freq(residual), inverted(inv)
+{
+}
+
+tune_result::~tune_result()
+{
+}
+#endif
+
+
+/*****************************************************************************/
+
+db_base::db_base(usrp_basic_sptr usrp, int which)
+ : d_is_shutdown(false), d_raw_usrp(usrp.get()), d_which(which), d_lo_offset(0.0)
+{
+}
+
+db_base::~db_base()
+{
+ shutdown();
+}
+
+void
+db_base::shutdown()
+{
+ if (!d_is_shutdown){
+ d_is_shutdown = true;
+ // do whatever there is to do to shutdown
+ }
+}
+
+int
+db_base::dbid()
+{
+ return usrp()->daughterboard_id(d_which);
+}
+
+std::string
+db_base::name()
+{
+ return usrp_dbid_to_string(dbid());
+}
+
+std::string
+db_base::side_and_name()
+{
+ if(d_which == 0)
+ return "A: " + name();
+ else
+ return "B: " + name();
+}
+
+// Function to bypass ADC buffers. Any board which is DC-coupled
+// should bypass the buffers
+
+bool
+db_base::bypass_adc_buffers(bool bypass)
+{
+ //if(d_tx) {
+ // throw std::runtime_error("TX Board has no adc buffers\n");
+ //}
+
+ bool ok = true;
+ if(d_which==0) {
+ ok &= usrp()->set_adc_buffer_bypass(0, bypass);
+ ok &= usrp()->set_adc_buffer_bypass(1, bypass);
+ }
+ else {
+ ok &= usrp()->set_adc_buffer_bypass(2, bypass);
+ ok &= usrp()->set_adc_buffer_bypass(3, bypass);
+ }
+ return ok;
+}
+
+bool
+db_base::set_atr_mask(int v)
+{
+ // Set Auto T/R mask.
+ return usrp()->write_atr_mask(d_which, v);
+}
+
+bool
+db_base::set_atr_txval(int v)
+{
+ // Set Auto T/R register value to be used when transmitting.
+ return usrp()->write_atr_txval(d_which, v);
+}
+
+bool
+db_base::set_atr_rxval(int v)
+{
+ // Set Auto T/R register value to be used when receiving.
+ return usrp()->write_atr_rxval(d_which, v);
+}
+
+bool
+db_base::set_atr_tx_delay(int v)
+{
+ // Set Auto T/R delay (in clock ticks) from when Tx fifo gets data to
+ // when T/R switches.
+ return usrp()->write_atr_tx_delay(v);
+}
+
+bool
+db_base::set_atr_rx_delay(int v)
+{
+ // Set Auto T/R delay (in clock ticks) from when Tx fifo goes empty to
+ // when T/R switches.
+ return usrp()->write_atr_rx_delay(v);
+}
+
+bool
+db_base::i_and_q_swapped()
+{
+ // Return True if this is a quadrature device and (for RX) ADC 0 is Q
+ // or (for TX) DAC 0 is Q
+ return false;
+}
+
+bool
+db_base::spectrum_inverted()
+{
+ // Return True if the dboard gives an inverted spectrum
+
+ return false;
+}
+
+bool
+db_base::set_enable(bool on)
+{
+ // For tx daughterboards, this controls the transmitter enable.
+
+ return true; // default is nop
+}
+
+bool
+db_base::set_auto_tr(bool on)
+{
+ // Enable automatic Transmit/Receive switching (ATR).
+ //
+ // Should be overridden in subclasses that care. This will typically
+ // set the atr_mask, txval and rxval.
+
+ return true;
+}
+
+bool
+db_base::set_lo_offset(double offset)
+{
+ // Set how much LO is offset from requested frequency
+
+ d_lo_offset = offset;
+ return true;
+}
+
+bool
+db_base::select_rx_antenna(int which_antenna)
+{
+ // Specify which antenna port to use for reception.
+ // Should be overriden by daughterboards that care.
+
+ return which_antenna == 0;
+}
+
+bool
+db_base::select_rx_antenna(const std::string &which_antenna)
+{
+ // Specify which antenna port to use for reception.
+ // Should be overriden by daughterboards that care.
+
+ return which_antenna == "";
+}
+
+
+// Reference Clock section
+//
+// Control whether a reference clock is sent to the daughterboards,
+// and what frequency
+//
+// Bit 7 -- 1 turns on refclk, 0 allows IO use
+// Bits 6:0 Divider value
+//
+
+double
+db_base::_refclk_freq()
+{
+ return usrp()->fpga_master_clock_freq() / _refclk_divisor();
+}
+
+void
+db_base::_enable_refclk(bool enable)
+{
+ int CLOCK_OUT = 1; // Clock is on lowest bit
+ int REFCLK_ENABLE = 0x80;
+ int REFCLK_DIVISOR_MASK = 0x7f;
+
+ if(enable) {
+ usrp()->_write_oe(d_which, CLOCK_OUT, CLOCK_OUT); // output enable
+ usrp()->write_refclk(d_which, (_refclk_divisor() & REFCLK_DIVISOR_MASK) | REFCLK_ENABLE);
+ }
+ else {
+ usrp()->write_refclk(d_which, 0);
+ }
+}
+
+int
+db_base::_refclk_divisor()
+{
+ // Return value to stick in REFCLK_DIVISOR register
+ throw std::runtime_error("_reflck_divisor() called from base class\n");;
+}
+
+
+std::ostream &operator<<(std::ostream &os, db_base &x)
+{
+ os << x.side_and_name();
+ return os;
+}
diff --git a/usrp/host/lib/legacy/db_base.h b/usrp/host/lib/legacy/db_base.h
new file mode 100644
index 0000000000..ff0a412e75
--- /dev/null
+++ b/usrp/host/lib/legacy/db_base.h
@@ -0,0 +1,114 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 3, or (at your option)
+// any later version.
+//
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+//
+
+#ifndef INCLUDED_DB_BASE_H
+#define INCLUDED_DB_BASE_H
+
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <iosfwd>
+
+class db_base;
+typedef boost::shared_ptr<db_base> db_base_sptr;
+
+class usrp_basic;
+typedef boost::shared_ptr<usrp_basic> usrp_basic_sptr;
+
+struct freq_result_t
+{
+ bool ok;
+ double baseband_freq;
+};
+
+/******************************************************************************/
+
+class db_base
+{
+ protected:
+ bool d_is_shutdown;
+ usrp_basic *d_raw_usrp;
+ int d_which;
+ double d_lo_offset;
+
+ void _enable_refclk(bool enable);
+ virtual double _refclk_freq();
+ virtual int _refclk_divisor();
+
+ usrp_basic *usrp(){
+ return d_raw_usrp;
+ }
+
+ public:
+ db_base(boost::shared_ptr<usrp_basic> usrp, int which);
+ virtual ~db_base();
+
+ int dbid();
+ std::string name();
+ std::string side_and_name();
+ int which() { return d_which; }
+
+ bool bypass_adc_buffers(bool bypass);
+ bool set_atr_mask(int v);
+ bool set_atr_txval(int v);
+ bool set_atr_rxval(int v);
+ bool set_atr_tx_delay(int v);
+ bool set_atr_rx_delay(int v);
+ bool set_lo_offset(double offset);
+ double lo_offset() { return d_lo_offset; }
+
+
+ ////////////////////////////////////////////////////////
+ // derived classes should override the following methods
+
+protected:
+ friend class usrp_basic;
+
+ /*!
+ * Called to shutdown daughterboard. Called from dtor and usrp_basic dtor.
+ *
+ * N.B., any class that overrides shutdown MUST call shutdown in its destructor.
+ */
+ virtual void shutdown();
+
+
+public:
+ virtual float gain_min() = 0;
+ virtual float gain_max() = 0;
+ virtual float gain_db_per_step() = 0;
+ virtual double freq_min() = 0;
+ virtual double freq_max() = 0;
+ virtual struct freq_result_t set_freq(double target_freq) = 0;
+ virtual bool set_gain(float gain) = 0;
+ virtual bool is_quadrature() = 0;
+ virtual bool i_and_q_swapped();
+ virtual bool spectrum_inverted();
+ virtual bool set_enable(bool on);
+ virtual bool set_auto_tr(bool on);
+ virtual bool select_rx_antenna(int which_antenna);
+ virtual bool select_rx_antenna(const std::string &which_antenna);
+};
+
+
+std::ostream & operator<<(std::ostream &os, db_base &x);
+
+#endif /* INCLUDED_DB_BASE_H */
diff --git a/usrp/host/lib/legacy/db_base.i b/usrp/host/lib/legacy/db_base.i
new file mode 100644
index 0000000000..36bb59a7ee
--- /dev/null
+++ b/usrp/host/lib/legacy/db_base.i
@@ -0,0 +1,101 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 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.
+//
+
+
+%{
+#include "db_base.h"
+%}
+
+%include <shared_ptr.i>
+
+class usrp_tune_result
+{
+public:
+ usrp_tune_result(double baseband=0, double dxc=0,
+ double residual=0, bool inv=0);
+ ~usrp_tune_result();
+
+ double baseband_freq;
+ double dxc_freq;
+ double residual_freq;
+ bool inverted;
+};
+
+struct freq_result_t
+{
+ bool ok;
+ double baseband_freq;
+};
+
+class db_base
+{
+ private:
+ db_base(boost::shared_ptr<usrp_basic> usrp, int which);
+
+ public:
+ virtual ~db_base();
+
+ int dbid();
+ std::string name();
+ std::string side_and_name();
+ int which() { return d_which; }
+
+ bool bypass_adc_buffers(bool bypass);
+ bool set_atr_mask(int v);
+ bool set_atr_txval(int v);
+ bool set_atr_rxval(int v);
+ bool set_atr_tx_delay(int v);
+ bool set_atr_rx_delay(int v);
+ bool set_lo_offset(double offset);
+ double lo_offset() { return d_lo_offset; }
+
+ virtual float gain_min() = 0;
+ virtual float gain_max() = 0;
+ virtual float gain_db_per_step() = 0;
+ virtual double freq_min() = 0;
+ virtual double freq_max() = 0;
+ virtual struct freq_result_t set_freq(double target_freq) = 0;
+ virtual bool set_gain(float gain) = 0;
+ virtual bool is_quadrature() = 0;
+ virtual bool i_and_q_swapped();
+ virtual bool spectrum_inverted();
+ virtual bool set_enable(bool on);
+ virtual bool set_auto_tr(bool on);
+ virtual bool select_rx_antenna(int which_antenna);
+ virtual bool select_rx_antenna(const std::string &antenna);
+};
+
+// Create templates for db's, vectors of db's, and vector of vectors of db's
+typedef boost::shared_ptr<db_base> db_base_sptr;
+%template(db_base_sptr) boost::shared_ptr<db_base>;
+%template(db_base_sptr_vector) std::vector<db_base_sptr>;
+%template(db_base_sptr_vector_vector) std::vector<std::vector<db_base_sptr> >;
+
+// Set better class name in Python
+// Enable freq_range and gain_range from public methods of class not implemented in C++
+// And create a dummy wrapper for backwards compatability with some of the example code
+%pythoncode %{
+ db_base_sptr.__repr__ = lambda self: "<db_base::%s>" % (self.name(),)
+ db_base_sptr.freq_range = lambda self: (self.freq_min(), self.freq_max(), 1)
+ db_base_sptr.gain_range = lambda self: (self.gain_min(), self.gain_max(), self.gain_db_per_step())
+
+%}
diff --git a/usrp/host/lib/legacy/db_base_impl.h b/usrp/host/lib/legacy/db_base_impl.h
new file mode 100644
index 0000000000..bb4d95d738
--- /dev/null
+++ b/usrp/host/lib/legacy/db_base_impl.h
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_DB_BASE_IMPL_H
+#define INCLUDED_DB_BASE_IMPL_H
+
+#include <db_base.h>
+#include <db_util.h>
+#include <usrp_basic.h>
+#include <fpga_regs_standard.h>
+#include <fpga_regs_common.h>
+#include <usrp_prims.h>
+#include <usrp_spi_defs.h>
+#include <stdexcept>
+
+#endif /* INCLUDED_DB_BASE_IMPL_H */
diff --git a/usrp/host/lib/legacy/db_basic.cc b/usrp/host/lib/legacy/db_basic.cc
new file mode 100644
index 0000000000..9c37c438e8
--- /dev/null
+++ b/usrp/host/lib/legacy/db_basic.cc
@@ -0,0 +1,263 @@
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 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.
+
+#include <db_basic.h>
+#include <db_base_impl.h>
+
+
+db_basic_tx::db_basic_tx(boost::shared_ptr<usrp_basic> usrp, int which)
+ : db_base(usrp, which)
+{
+ // Handler for Basic Tx daughterboards.
+ //
+ // @param usrp: instance of usrp.source_c
+ // @param which: which side: 0 or 1 corresponding to TX_A or TX_B respectively
+
+ set_gain((gain_min() + gain_max()) / 2); // initialize gain
+}
+
+db_basic_tx::~db_basic_tx()
+{
+}
+
+double
+db_basic_tx::freq_min()
+{
+ return -90e9;
+}
+
+double
+db_basic_tx::freq_max()
+{
+ return 90e9;
+}
+
+struct freq_result_t
+db_basic_tx::set_freq(double target_freq)
+{
+ // Set the frequency.
+ //
+ // @param freq: target RF frequency in Hz
+ // @type freq: double
+ //
+ // @returns (ok, actual_baseband_freq) where:
+ // ok is True or False and indicates success or failure,
+ // actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+
+ struct freq_result_t args = {false, 0};
+ args.ok = true;
+ args.baseband_freq = 0.0;
+ return args;
+}
+
+float
+db_basic_tx::gain_min()
+{
+ return usrp()->pga_min();
+}
+
+float
+db_basic_tx::gain_max()
+{
+ return usrp()->pga_max();
+}
+
+float
+db_basic_tx::gain_db_per_step()
+{
+ return usrp()->pga_db_per_step();
+}
+
+bool
+db_basic_tx::set_gain(float gain)
+{
+ // Set the gain.
+ //
+ // @param gain: gain in decibels
+ // @returns True/False
+
+ bool ok = usrp()->set_pga(d_which * 2 + 0, gain);
+ ok = ok && usrp()->set_pga(d_which * 2 + 1, gain);
+ return ok;
+}
+
+bool
+db_basic_tx::is_quadrature()
+{
+ // Return True if this board requires both I & Q analog channels.
+
+ return true;
+}
+
+
+/******************************************************************************/
+
+
+db_basic_rx::db_basic_rx(usrp_basic_sptr usrp, int which, int subdev)
+ : db_base(usrp, which)
+{
+ // Handler for Basic Rx daughterboards.
+ //
+ // @param usrp: instance of usrp.source_c
+ // @param which: which side: 0 or 1 corresponding to TX_A or TX_B respectively
+ // @param subdev: which analog i/o channel: 0 or 1
+ // @type subdev: int
+
+ d_subdev = subdev;
+
+ bypass_adc_buffers(true);
+
+ if(0) { // Doing this would give us a different default than the historical values...
+ set_gain(float(gain_min() + gain_max()) / 2.0); // initialize gain
+ }
+}
+
+db_basic_rx::~db_basic_rx()
+{
+}
+
+double
+db_basic_rx::freq_min()
+{
+ return -90e9;
+}
+
+double
+db_basic_rx::freq_max()
+{
+ return 90e9;
+}
+
+struct freq_result_t
+db_basic_rx::set_freq(double target_freq)
+{
+ // Set the frequency.
+ //
+ // @param freq: target RF frequency in Hz
+ // @type freq: double
+ //
+ // @returns (ok, actual_baseband_freq) where:
+ // ok is True or False and indicates success or failure,
+ // actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+
+ struct freq_result_t args = {true, 0.0};
+ return args;
+}
+
+float
+db_basic_rx::gain_min()
+{
+ return usrp()->pga_min();
+}
+
+float
+db_basic_rx::gain_max()
+{
+ return usrp()->pga_max();
+}
+
+float
+db_basic_rx::gain_db_per_step()
+{
+ return usrp()->pga_db_per_step();
+}
+
+bool
+db_basic_rx::set_gain(float gain)
+{
+ // Set the gain.
+ //
+ // @param gain: gain in decibels
+ // @returns True/False
+
+ return usrp()->set_pga(d_which * 2 + d_subdev, gain);
+}
+
+bool
+db_basic_rx::is_quadrature()
+{
+ // Return True if this board requires both I & Q analog channels.
+
+ // This bit of info is useful when setting up the USRP Rx mux register.
+
+ return false;
+}
+
+
+
+/******************************************************************************/
+
+
+db_lf_tx::db_lf_tx(usrp_basic_sptr usrp, int which)
+ : db_basic_tx(usrp, which)
+{
+ // Handler for Low Freq Tx daughterboards.
+ //
+ // @param usrp: instance of usrp.source_c
+ // @param which: which side: 0 or 1 corresponding to RX_A or RX_B respectively
+}
+
+db_lf_tx::~db_lf_tx()
+{
+}
+
+double
+db_lf_tx::freq_min()
+{
+ return -32e6;
+}
+
+double
+db_lf_tx::freq_max()
+{
+ return 32e6;
+}
+
+/******************************************************************************/
+
+
+db_lf_rx::db_lf_rx(usrp_basic_sptr usrp, int which, int subdev)
+ : db_basic_rx(usrp, which, subdev)
+{
+ // Handler for Low Freq Rx daughterboards.
+ //
+ // @param usrp: instance of usrp.source_c
+ // @param which: which side: 0 or 1 corresponding to RX_A or RX_B respectively
+ // @param subdev: which analog i/o channel: 0 or 1
+ // @type subdev: int
+}
+
+db_lf_rx::~db_lf_rx()
+{
+}
+
+double
+db_lf_rx::freq_min()
+{
+ return 0.0;
+}
+
+double
+db_lf_rx::freq_max()
+{
+ return 32e6;
+}
+
+
diff --git a/usrp/host/lib/legacy/db_basic.h b/usrp/host/lib/legacy/db_basic.h
new file mode 100644
index 0000000000..4dd92b997f
--- /dev/null
+++ b/usrp/host/lib/legacy/db_basic.h
@@ -0,0 +1,99 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 3, or (at your option)
+// any later version.
+//
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+
+#ifndef DB_BASIC_H
+#define DB_BASIC_H
+
+#include <db_base.h>
+
+
+/******************************************************************************/
+
+
+class db_basic_tx : public db_base
+{
+public:
+ db_basic_tx(usrp_basic_sptr usrp, int which);
+ ~db_basic_tx();
+
+ float gain_min();
+ float gain_max();
+ float gain_db_per_step();
+ double freq_min();
+ double freq_max();
+ struct freq_result_t set_freq(double target_freq);
+ bool set_gain(float gain);
+ bool is_quadrature();
+};
+
+
+/******************************************************************************/
+
+
+class db_basic_rx : public db_base
+{
+ public:
+ db_basic_rx(usrp_basic_sptr usrp, int which, int subdev);
+ ~db_basic_rx();
+
+ float gain_min();
+ float gain_max();
+ float gain_db_per_step();
+ double freq_min();
+ double freq_max();
+ struct freq_result_t set_freq(double target_freq);
+ bool set_gain(float gain);
+ bool is_quadrature();
+
+private:
+ int d_subdev;
+};
+
+
+/******************************************************************************/
+
+
+class db_lf_rx : public db_basic_rx
+{
+ public:
+ db_lf_rx(usrp_basic_sptr usrp, int which, int subdev);
+ ~db_lf_rx();
+
+ double freq_min();
+ double freq_max();
+};
+
+
+/******************************************************************************/
+
+
+class db_lf_tx : public db_basic_tx
+{
+ public:
+ db_lf_tx(usrp_basic_sptr usrp, int which);
+ ~db_lf_tx();
+
+ double freq_min();
+ double freq_max();
+};
+
+
+#endif
diff --git a/usrp/host/lib/legacy/db_boards.cc b/usrp/host/lib/legacy/db_boards.cc
new file mode 100644
index 0000000000..1ba8b0e7fc
--- /dev/null
+++ b/usrp/host/lib/legacy/db_boards.cc
@@ -0,0 +1,215 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 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.
+//
+
+#include <db_boards.h>
+#include <usrp_dbid.h>
+#include <db_basic.h>
+#include <db_tv_rx.h>
+#include <db_dbs_rx.h>
+#include <db_flexrf.h>
+#include <db_flexrf_mimo.h>
+#include <db_xcvr2450.h>
+#include <db_wbx.h>
+#include <db_dtt754.h>
+#include <db_dtt768.h>
+
+std::vector<db_base_sptr>
+instantiate_dbs(int dbid, usrp_basic_sptr usrp, int which_side)
+{
+ std::vector<db_base_sptr> db;
+
+ switch(dbid) {
+
+ case(USRP_DBID_BASIC_TX):
+ db.push_back(db_base_sptr(new db_basic_tx(usrp, which_side)));
+ break;
+
+ case(USRP_DBID_BASIC_RX):
+ db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 0)));
+ db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 1)));
+ break;
+
+ case(USRP_DBID_LF_TX):
+ db.push_back(db_base_sptr(new db_lf_tx(usrp, which_side)));
+ break;
+
+ case(USRP_DBID_LF_RX):
+ db.push_back(db_base_sptr(new db_lf_rx(usrp, which_side, 0)));
+ db.push_back(db_base_sptr(new db_lf_rx(usrp, which_side, 1)));
+ break;
+
+ case(USRP_DBID_DBS_RX):
+ db.push_back(db_base_sptr(new db_dbs_rx(usrp, which_side)));
+ break;
+
+ case(USRP_DBID_TV_RX):
+ db.push_back(db_base_sptr(new db_tv_rx(usrp, which_side, 43.75e6, 5.75e6)));
+ break;
+ case(USRP_DBID_TV_RX_REV_2):
+ db.push_back(db_base_sptr(new db_tv_rx(usrp, which_side, 44e6, 20e6)));
+ break;
+ case(USRP_DBID_TV_RX_REV_3):
+ db.push_back(db_base_sptr(new db_tv_rx(usrp, which_side, 44e6, 20e6)));
+ break;
+
+ case(USRP_DBID_FLEX_2400_TX):
+ db.push_back(db_base_sptr(new db_flexrf_2400_tx(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_2400_RX):
+ db.push_back(db_base_sptr(new db_flexrf_2400_rx(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_1200_TX):
+ db.push_back(db_base_sptr(new db_flexrf_1200_tx(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_1200_RX):
+ db.push_back(db_base_sptr(new db_flexrf_1200_rx(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_1800_TX):
+ db.push_back(db_base_sptr(new db_flexrf_1800_tx(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_1800_RX):
+ db.push_back(db_base_sptr(new db_flexrf_1800_rx(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_900_TX):
+ db.push_back(db_base_sptr(new db_flexrf_900_tx(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_900_RX):
+ db.push_back(db_base_sptr(new db_flexrf_900_rx(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_400_TX):
+ db.push_back(db_base_sptr(new db_flexrf_400_tx(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_400_RX):
+ db.push_back(db_base_sptr(new db_flexrf_400_rx(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_2400_TX_MIMO_A):
+ db.push_back(db_base_sptr(new db_flexrf_2400_tx_mimo_a(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_2400_RX_MIMO_A):
+ db.push_back(db_base_sptr(new db_flexrf_2400_rx_mimo_a(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_1800_TX_MIMO_A):
+ db.push_back(db_base_sptr(new db_flexrf_1800_tx_mimo_a(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_1800_RX_MIMO_A):
+ db.push_back(db_base_sptr(new db_flexrf_1800_rx_mimo_a(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_1200_TX_MIMO_A):
+ db.push_back(db_base_sptr(new db_flexrf_1200_tx_mimo_a(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_1200_RX_MIMO_A):
+ db.push_back(db_base_sptr(new db_flexrf_1200_rx_mimo_a(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_900_TX_MIMO_A):
+ db.push_back(db_base_sptr(new db_flexrf_900_tx_mimo_a(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_900_RX_MIMO_A):
+ db.push_back(db_base_sptr(new db_flexrf_900_rx_mimo_a(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_400_TX_MIMO_A):
+ db.push_back(db_base_sptr(new db_flexrf_400_tx_mimo_a(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_400_RX_MIMO_A):
+ db.push_back(db_base_sptr(new db_flexrf_400_rx_mimo_a(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_2400_TX_MIMO_B):
+ db.push_back(db_base_sptr(new db_flexrf_2400_tx_mimo_b(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_2400_RX_MIMO_B):
+ db.push_back(db_base_sptr(new db_flexrf_2400_rx_mimo_b(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_1800_TX_MIMO_B):
+ db.push_back(db_base_sptr(new db_flexrf_1800_tx_mimo_b(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_1800_RX_MIMO_B):
+ db.push_back(db_base_sptr(new db_flexrf_1800_rx_mimo_b(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_1200_TX_MIMO_B):
+ db.push_back(db_base_sptr(new db_flexrf_1200_tx_mimo_b(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_1200_RX_MIMO_B):
+ db.push_back(db_base_sptr(new db_flexrf_1200_rx_mimo_b(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_900_TX_MIMO_B):
+ db.push_back(db_base_sptr(new db_flexrf_900_tx_mimo_b(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_900_RX_MIMO_B):
+ db.push_back(db_base_sptr(new db_flexrf_900_rx_mimo_b(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_400_TX_MIMO_B):
+ db.push_back(db_base_sptr(new db_flexrf_400_tx_mimo_b(usrp, which_side)));
+ break;
+ case(USRP_DBID_FLEX_400_RX_MIMO_B):
+ db.push_back(db_base_sptr(new db_flexrf_400_rx_mimo_b(usrp, which_side)));
+ break;
+
+ case(USRP_DBID_XCVR2450_TX):
+ db.push_back(db_base_sptr(new db_xcvr2450_tx(usrp, which_side)));
+ break;
+ case(USRP_DBID_XCVR2450_RX):
+ db.push_back(db_base_sptr(new db_xcvr2450_rx(usrp, which_side)));
+ break;
+
+#if 0 // FIXME wbx doesn't compile
+ case(USRP_DBID_WBX_LO_TX):
+ db.push_back(db_base_sptr(new db_wbx_lo_tx(usrp, which_side)));
+ break;
+ case(USRP_DBID_WBX_LO_RX):
+ db.push_back(db_base_sptr(new db_wbx_lo_rx(usrp, which_side)));
+ break;
+#endif
+
+ case(USRP_DBID_DTT754):
+ db.push_back(db_base_sptr(new db_dtt754(usrp, which_side)));
+ break;
+ case(USRP_DBID_DTT768):
+ db.push_back(db_base_sptr(new db_dtt768(usrp, which_side)));
+ break;
+
+ case(-1):
+ if (boost::dynamic_pointer_cast<usrp_basic_tx>(usrp)){
+ db.push_back(db_base_sptr(new db_basic_tx(usrp, which_side)));
+ }
+ else {
+ db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 0)));
+ db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 1)));
+ }
+ break;
+
+ case(-2):
+ default:
+ if (boost::dynamic_pointer_cast<usrp_basic_tx>(usrp)){
+ fprintf(stderr, "\n\aWarning: Treating daughterboard with invalid EEPROM contents as if it were a \"Basic Tx.\"\n");
+ fprintf(stderr, "Warning: This is almost certainly wrong... Use appropriate burn-*-eeprom utility.\n\n");
+ db.push_back(db_base_sptr(new db_basic_tx(usrp, which_side)));
+ }
+ else {
+ fprintf(stderr, "\n\aWarning: Treating daughterboard with invalid EEPROM contents as if it were a \"Basic Rx.\"\n");
+ fprintf(stderr, "Warning: This is almost certainly wrong... Use appropriate burn-*-eeprom utility.\n\n");
+ db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 0)));
+ db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 1)));
+ }
+ break;
+ }
+
+ return db;
+}
diff --git a/usrp/host/lib/legacy/db_boards.h b/usrp/host/lib/legacy/db_boards.h
new file mode 100644
index 0000000000..037c460371
--- /dev/null
+++ b/usrp/host/lib/legacy/db_boards.h
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 3, or (at your option)
+// any later version.
+//
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+//
+
+#ifndef DB_BOARDS_H
+#define DB_BOARDS_H
+
+#include <db_base.h>
+#include <usrp_basic.h>
+
+std::vector<db_base_sptr> instantiate_dbs(int dbid, usrp_basic_sptr usrp, int which_side);
+
+#endif
+
+
diff --git a/usrp/host/lib/legacy/db_dbs_rx.cc b/usrp/host/lib/legacy/db_dbs_rx.cc
new file mode 100644
index 0000000000..5f3b32f92e
--- /dev/null
+++ b/usrp/host/lib/legacy/db_dbs_rx.cc
@@ -0,0 +1,491 @@
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 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.
+
+#include <db_dbs_rx.h>
+#include <db_base_impl.h>
+#include <cmath>
+
+
+/*****************************************************************************/
+
+
+db_dbs_rx::db_dbs_rx(usrp_basic_sptr _usrp, int which)
+ : db_base(_usrp, which)
+{
+ // Control DBS receiver based USRP daughterboard.
+ //
+ // @param usrp: instance of usrp.source_c
+ // @param which: which side: 0, 1 corresponding to RX_A or RX_B respectively
+
+ usrp()->_write_oe(d_which, 0x0001, 0x0001);
+ if(which == 0) {
+ d_i2c_addr = 0x67;
+ }
+ else {
+ d_i2c_addr = 0x65;
+ }
+
+ d_n = 950;
+ d_div2 = 0;
+ d_osc = 5;
+ d_cp = 3;
+ d_r = 4;
+ d_r_int = 1;
+ d_fdac = 127;
+ d_m = 2;
+ d_dl = 0;
+ d_ade = 0;
+ d_adl = 0;
+ d_gc1 = 0;
+ d_gc2 = 31;
+ d_diag = 0;
+
+ _enable_refclk(true);
+
+ set_gain((gain_min() + gain_max()) / 2.0); // initialize gain
+
+ bypass_adc_buffers(true);
+}
+
+db_dbs_rx::~db_dbs_rx()
+{
+ shutdown();
+}
+
+void
+db_dbs_rx::shutdown()
+{
+ if (!d_is_shutdown){
+ d_is_shutdown = true;
+ // do whatever there is to do to shutdown orderly
+ _enable_refclk(false);
+ }
+}
+
+void
+db_dbs_rx::_write_reg (int regno, int v)
+{
+ //regno is in [0,5], v is value to write to register"""
+ assert (0 <= regno && regno <= 5);
+ std::vector<int> args(2);
+ args[0] = regno;
+ args[1] = v;
+ usrp()->write_i2c (d_i2c_addr, int_seq_to_str (args));
+}
+
+void
+db_dbs_rx::_write_regs (int starting_regno, const std::vector<int> &vals)
+{
+ // starting_regno is in [0,5],
+ // vals is a seq of integers to write to consecutive registers"""
+
+ //FIXME
+ std::vector<int> args;
+ args.push_back(starting_regno);
+ args.insert(args.end(), vals.begin(), vals.end());
+ usrp()->write_i2c (d_i2c_addr, int_seq_to_str (args));
+}
+
+std::vector<int>
+db_dbs_rx::_read_status ()
+{
+ //If successful, return list of two ints: [status_info, filter_DAC]"""
+ std::string s = usrp()->read_i2c (d_i2c_addr, 2);
+ if(s.size() != 2) {
+ std::vector<int> ret(0);
+ return ret;
+ }
+ return str_to_int_seq (s);
+}
+
+void
+db_dbs_rx::_send_reg(int regno)
+{
+ assert(0 <= regno && regno <= 5);
+ if(regno == 0)
+ _write_reg(0,(d_div2<<7) + (d_n>>8));
+ if(regno == 1)
+ _write_reg(1,d_n & 255);
+ if(regno == 2)
+ _write_reg(2,d_osc + (d_cp<<3) + (d_r_int<<5));
+ if(regno == 3)
+ _write_reg(3,d_fdac);
+ if(regno == 4)
+ _write_reg(4,d_m + (d_dl<<5) + (d_ade<<6) + (d_adl<<7));
+ if(regno == 5)
+ _write_reg(5,d_gc2 + (d_diag<<5));
+}
+
+// BW setting
+void
+db_dbs_rx::_set_m(int m)
+{
+ assert(m>0 && m<32);
+ d_m = m;
+ _send_reg(4);
+}
+
+void
+db_dbs_rx::_set_fdac(int fdac)
+{
+ assert(fdac>=0 && fdac<128);
+ d_fdac = fdac;
+ _send_reg(3);
+}
+
+struct bw_t
+db_dbs_rx::set_bw (float bw)
+{
+ assert(bw>=1e6 && bw<=33e6);
+
+ struct bw_t ret = {0, 0, 0};
+ int m_max, m_min, m_test, fdac_test;
+ if(bw >= 4e6)
+ m_max = int(std::min(31, (int)floor(_refclk_freq()/1e6)));
+ else if(bw >= 2e6) // Outside of Specs!
+ m_max = int(std::min(31, (int)floor(_refclk_freq()/.5e6)));
+ else // Way outside of Specs!
+ m_max = int(std::min(31, (int)floor(_refclk_freq()/.25e6)));
+
+ m_min = int(ceil(_refclk_freq()/2.5e6));
+ m_test = m_max;
+ while(m_test >= m_min) {
+ fdac_test = static_cast<int>(round(((bw * m_test / _refclk_freq())-4)/.145));
+ if(fdac_test > 127)
+ m_test = m_test - 1;
+ else
+ break;
+ }
+
+ if(m_test>=m_min && fdac_test>=0) {
+ _set_m(m_test);
+ _set_fdac(fdac_test);
+
+ ret.m = d_m;
+ ret.fdac = d_fdac;
+ ret.div = _refclk_freq()/d_m*(4+0.145*d_fdac);
+ }
+ else {
+ fprintf(stderr, "Failed to set bw\n");
+ }
+ return ret;
+}
+
+// Gain setting
+void
+db_dbs_rx::_set_dl(int dl)
+{
+ assert(dl == 0 || dl == 1);
+ d_dl = dl;
+ _send_reg(4);
+}
+
+void
+db_dbs_rx::_set_gc2(int gc2)
+{
+ assert(gc2<32 && gc2>=0);
+ d_gc2 = gc2;
+ _send_reg(5);
+}
+
+void
+db_dbs_rx::_set_gc1(int gc1)
+{
+ assert(gc1>=0 && gc1<4096);
+ d_gc1 = gc1;
+ usrp()->write_aux_dac(d_which, 0, gc1);
+}
+
+void
+db_dbs_rx::_set_pga(int pga_gain)
+{
+ assert(pga_gain>=0 && pga_gain<=20);
+ if(d_which == 0) {
+ usrp()->set_pga (0, pga_gain);
+ usrp()->set_pga (1, pga_gain);
+ }
+ else {
+ usrp()->set_pga (2, pga_gain);
+ usrp()->set_pga (3, pga_gain);
+ }
+}
+
+float
+db_dbs_rx::gain_min()
+{
+ return 0;
+}
+
+float
+db_dbs_rx::gain_max()
+{
+ return 104;
+}
+
+float
+db_dbs_rx::gain_db_per_step()
+{
+ return 1;
+}
+
+bool
+db_dbs_rx::set_gain(float gain)
+{
+ // Set the gain.
+ //
+ // @param gain: gain in decibels
+ // @returns True/False
+
+ if(!(gain>=0 && gain<105)) {
+ throw std::runtime_error("gain out of range\n");
+ }
+
+ int gc1=0, gc2=0, dl=0, pga=0;
+
+ if(gain < 56) {
+ gc1 = int((-gain*1.85/56.0 + 2.6)*4096.0/3.3);
+ gain = 0;
+ }
+ else {
+ gc1 = 0;
+ gain -= 56;
+ }
+
+ if(gain < 24) {
+ gc2 = static_cast<int>(round(31.0 * (1-gain/24.0)));
+ gain = 0;
+ }
+ else {
+ gc2 = 0;
+ gain -=24;
+ }
+
+ if(gain >= 4.58) {
+ dl = 1;
+ gain -= 4.58;
+ }
+
+ pga = gain;
+ _set_gc1(gc1);
+ _set_gc2(gc2);
+ _set_dl(dl);
+ _set_pga(pga);
+
+ return true;
+}
+
+// Frequency setting
+void
+db_dbs_rx::_set_osc(int osc)
+{
+ assert(osc>=0 && osc<8);
+ d_osc = osc;
+ _send_reg(2);
+}
+
+void
+db_dbs_rx::_set_cp(int cp)
+{
+ assert(cp>=0 && cp<4);
+ d_cp = cp;
+ _send_reg(2);
+}
+
+void
+db_dbs_rx::_set_n(int n)
+{
+ assert(n>256 && n<32768);
+ d_n = n;
+ _send_reg(0);
+ _send_reg(1);
+}
+
+void
+db_dbs_rx::_set_div2(int div2)
+{
+ assert(div2 == 0 || div2 == 1);
+ d_div2 = div2;
+ _send_reg(0);
+}
+
+void
+db_dbs_rx::_set_r(int r)
+{
+ assert(r>=0 && r<128);
+ d_r = r;
+ d_r_int = static_cast<int>(round(log10(r)/log10(2)) - 1);
+ _send_reg(2);
+}
+
+// FIXME How do we handle ADE and ADL properly?
+void
+db_dbs_rx::_set_ade(int ade)
+{
+ assert(ade == 0 || ade == 1);
+ d_ade = ade;
+ _send_reg(4);
+}
+
+double
+db_dbs_rx::freq_min()
+{
+ return 500e6;
+}
+
+double
+db_dbs_rx::freq_max()
+{
+ return 2.6e9;
+}
+
+struct freq_result_t
+db_dbs_rx::set_freq(double freq)
+{
+ // Set the frequency.
+ //
+ // @param freq: target RF frequency in Hz
+ // @type freq: double
+ //
+ // @returns (ok, actual_baseband_freq) where:
+ // ok is True or False and indicates success or failure,
+ // actual_baseband_freq is RF frequency that corresponds to DC in the IF.
+
+ freq_result_t args = {false, 0};
+
+ if(!(freq>=freq_min() && freq<=freq_max())) {
+ return args;
+ }
+
+ double vcofreq;
+ if(freq<1150e6) {
+ _set_div2(0);
+ vcofreq = 4 * freq;
+ }
+ else {
+ _set_div2(1);
+ vcofreq = 2 * freq;
+ }
+
+ _set_ade(1);
+ int rmin = std::max(2, (int)(_refclk_freq()/2e6));
+ int rmax = std::min(128, (int)(_refclk_freq()/500e3));
+ int r = 2;
+ int n = 0;
+ int best_r = 2;
+ int best_n = 0;
+ int best_delta = 10e6;
+ int delta;
+
+ while(r <= rmax) {
+ n = static_cast<int>(round(freq/(_refclk_freq()/r)));
+ if(r<rmin || n<256) {
+ r = r * 2;
+ continue;
+ }
+ delta = (int)fabs(n*_refclk_freq()/r - freq);
+ if(delta < 75e3) {
+ best_r = r;
+ best_n = n;
+ break;
+ }
+ if(delta < best_delta*0.9) {
+ best_r = r;
+ best_n = n;
+ best_delta = delta;
+ }
+ r = r * 2;
+ }
+ _set_r(best_r);
+
+ _set_n(static_cast<int>(round(best_n)));
+
+ int vco;
+ if(vcofreq < 2433e6)
+ vco = 0;
+ else if(vcofreq < 2711e6)
+ vco=1;
+ else if(vcofreq < 3025e6)
+ vco=2;
+ else if(vcofreq < 3341e6)
+ vco=3;
+ else if(vcofreq < 3727e6)
+ vco=4;
+ else if(vcofreq < 4143e6)
+ vco=5;
+ else if(vcofreq < 4493e6)
+ vco=6;
+ else
+ vco=7;
+
+ _set_osc(vco);
+
+ // Set CP current
+ int adc_val = 0;
+ std::vector<int> bytes(2);
+ while(adc_val == 0 || adc_val == 7) {
+ bytes = _read_status();
+ adc_val = bytes[0] >> 2;
+ if(adc_val == 0) {
+ if(vco <= 0) {
+ return args;
+ }
+ else {
+ vco = vco - 1;
+ }
+ }
+ else if(adc_val == 7) {
+ if(vco >= 7) {
+ return args;
+ }
+ else {
+ vco = vco + 1;
+ }
+ }
+ _set_osc(vco);
+ }
+
+ if(adc_val == 1 || adc_val == 2) {
+ _set_cp(1);
+ }
+ else if(adc_val == 3 || adc_val == 4) {
+ _set_cp(2);
+ }
+ else {
+ _set_cp(3);
+ }
+
+ args.ok = true;
+ args.baseband_freq = d_n * _refclk_freq() / d_r;
+ return args;
+}
+
+int
+db_dbs_rx::_refclk_divisor()
+{
+ //Return value to stick in REFCLK_DIVISOR register
+ return 16;
+}
+
+bool
+db_dbs_rx::is_quadrature()
+{
+ // Return True if this board requires both I & Q analog channels.
+ return true;
+}
diff --git a/usrp/host/lib/legacy/db_dbs_rx.h b/usrp/host/lib/legacy/db_dbs_rx.h
new file mode 100644
index 0000000000..f3348af8cf
--- /dev/null
+++ b/usrp/host/lib/legacy/db_dbs_rx.h
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 3, or (at your option)
+// any later version.
+//
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+
+#ifndef DB_DBS_RX_H
+#define DB_DBS_RX_H
+
+#include <db_base.h>
+#include <vector>
+
+struct bw_t {
+ int m;
+ int fdac;
+ float div;
+};
+
+class db_dbs_rx : public db_base
+{
+private:
+ int d_osc, d_cp, d_n, d_div2, d_r, d_r_int;
+ int d_fdac, d_m, d_dl, d_ade, d_adl, d_gc1, d_gc2, d_diag;
+ int d_i2c_addr;
+
+ // Internal gain functions
+ void _write_reg(int regno, int v);
+ void _write_regs(int starting_regno, const std::vector<int> &vals);
+ std::vector<int> _read_status();
+ void _send_reg(int regno);
+ void _set_m(int m);
+ void _set_fdac(int fdac);
+ bw_t set_bw(float bw);
+ void _set_dl(int dl);
+ void _set_gc2(int gc2);
+ void _set_gc1(int gc1);
+ void _set_pga(int pga_gain);
+
+ // Internal frequency function
+ void _set_osc(int osc);
+ void _set_cp(int cp);
+ void _set_n(int n);
+ void _set_div2(int div2);
+ void _set_r(int r);
+ void _set_ade(int ade);
+
+ int _refclk_divisor();
+
+protected:
+ void shutdown();
+
+public:
+ db_dbs_rx(usrp_basic_sptr usrp, int which);
+ ~db_dbs_rx();
+
+ float gain_min();
+ float gain_max();
+ float gain_db_per_step();
+ double freq_min();
+ double freq_max();
+ struct freq_result_t set_freq(double freq);
+ bool set_gain(float gain);
+ bool is_quadrature();
+};
+
+#endif
diff --git a/usrp/host/lib/legacy/db_dtt754.cc b/usrp/host/lib/legacy/db_dtt754.cc
new file mode 100644
index 0000000000..39f8c3f9e2
--- /dev/null
+++ b/usrp/host/lib/legacy/db_dtt754.cc
@@ -0,0 +1,321 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 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.
+
+#include <db_dtt754.h>
+#include <db_base_impl.h>
+
+int
+control_byte_1()
+{
+ int RS = 0; // 0 = 166.66kHz reference
+ int ATP = 7; // Disable internal AGC
+ return (0x80 | ATP<<3 | RS);
+}
+
+int
+control_byte_2()
+{
+ int STBY = 0; // powered on
+ int XTO = 1; // turn off xtal out, which we don't have
+ int ATC = 0; // not clear exactly, possibly speeds up or slows down AGC, which we are not using
+
+ int c = 0xc2 | ATC<<5 | STBY<<4 | XTO;
+ return c;
+}
+
+int
+bandswitch_byte(float freq, float bw)
+{
+ int P5, CP, BS;
+
+ if(bw>7.5e6) {
+ P5 = 1;
+ }
+ else {
+ P5 = 0;
+ }
+
+ if(freq < 121e6) {
+ CP = 0;
+ BS = 1;
+ }
+ else if(freq < 141e6) {
+ CP = 1;
+ BS = 1;
+ }
+ else if(freq < 166e6) {
+ CP = 2;
+ BS = 1;
+ }
+ else if(freq < 182e6) {
+ CP = 3;
+ BS = 1;
+ }
+ else if(freq < 286e6) {
+ CP = 0;
+ BS = 2;
+ }
+ else if(freq < 386e6) {
+ CP = 1;
+ BS = 2;
+ }
+ else if(freq < 446e6) {
+ CP = 2;
+ BS = 2;
+ }
+ else if(freq < 466e6) {
+ CP = 3;
+ BS = 2;
+ }
+ else if(freq < 506e6) {
+ CP = 0;
+ BS = 8;
+ }
+ else if(freq < 761e6) {
+ CP = 1;
+ BS = 8;
+ }
+ else if(freq < 846e6) {
+ CP = 2;
+ BS = 8;
+ }
+ else { // limit is ~905 MHz
+ CP = 3;
+ BS = 8;
+ }
+ return (CP<<6 | P5 << 4 | BS);
+}
+
+db_dtt754::db_dtt754(usrp_basic_sptr _usrp, int which)
+ : db_base(_usrp, which)
+{
+ /*
+ * Control custom DTT75403-based daughterboard.
+ *
+ * @param usrp: instance of usrp.source_c
+ * @param which: which side: 0 or 1 corresponding to RX_A or RX_B respectively
+ * @type which: int
+ */
+
+ // FIXME: DTT754 and DTT768 can probably inherit from a DTT class
+
+ if(d_which == 0) {
+ d_i2c_addr = 0x60;
+ }
+ else {
+ d_i2c_addr = 0x62;
+ }
+
+ d_bw = 7e6;
+ d_IF = 36e6;
+
+ d_f_ref = 166.6666e3;
+ d_inverted = false;
+
+ set_gain((gain_min() + gain_max()) / 2.0);
+
+ bypass_adc_buffers(false);
+}
+
+db_dtt754::~db_dtt754()
+{
+}
+
+float
+db_dtt754::gain_min()
+{
+ return 0;
+}
+
+float
+db_dtt754::gain_max()
+{
+ return 115;
+}
+
+float
+db_dtt754::gain_db_per_step()
+{
+ return 1;
+}
+
+bool
+db_dtt754::set_gain(float gain)
+{
+ assert(gain>=0 && gain<=115);
+
+ float rfgain, ifgain, pgagain;
+ if(gain > 60) {
+ rfgain = 60;
+ gain = gain - 60;
+ }
+ else {
+ rfgain = gain;
+ gain = 0;
+ }
+
+ if(gain > 35) {
+ ifgain = 35;
+ gain = gain - 35;
+ }
+ else {
+ ifgain = gain;
+ gain = 0;
+ }
+ pgagain = gain;
+
+ _set_rfagc(rfgain);
+ _set_ifagc(ifgain);
+ _set_pga(pgagain);
+
+ return true; // can't fail with the assert in place
+}
+
+double
+db_dtt754::freq_min()
+{
+ return 44e6;
+}
+
+double
+db_dtt754::freq_max()
+{
+ return 900e6;
+}
+
+struct freq_result_t
+db_dtt754::set_freq(double target_freq)
+{
+ /*
+ * @returns (ok, actual_baseband_freq) where:
+ * ok is True or False and indicates success or failure,
+ * actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+ */
+
+ freq_result_t ret = {false, 0.0};
+
+ if(target_freq < freq_min() || target_freq > freq_max()) {
+ return ret;
+ }
+
+ double target_lo_freq = target_freq + d_IF; // High side mixing
+
+ int divisor = (int)(0.5+(target_lo_freq / d_f_ref));
+ double actual_lo_freq = d_f_ref*divisor;
+
+ if((divisor & ~0x7fff) != 0) { // must be 15-bits or less
+ return ret;
+ }
+
+ // build i2c command string
+ std::vector<int> buf(5);
+ buf[0] = (divisor >> 8) & 0xff; // DB1
+ buf[1] = divisor & 0xff; // DB2
+ buf[2] = control_byte_1();
+ buf[3] = bandswitch_byte(actual_lo_freq, d_bw);
+ buf[4] = control_byte_2();
+
+ bool ok = usrp()->write_i2c(d_i2c_addr, int_seq_to_str (buf));
+
+ d_freq = actual_lo_freq - d_IF;
+
+ ret.ok = ok;
+ ret.baseband_freq = actual_lo_freq;
+
+ return ret;
+
+}
+
+bool
+db_dtt754::is_quadrature()
+{
+ /*
+ * Return True if this board requires both I & Q analog channels.
+ *
+ * This bit of info is useful when setting up the USRP Rx mux register.
+ */
+
+ return false;
+}
+
+bool
+db_dtt754::spectrum_inverted()
+{
+ /*
+ * The 43.75 MHz version is inverted
+ */
+
+ return d_inverted;
+}
+
+void
+db_dtt754::set_bw(float bw)
+{
+ /*
+ * Choose the SAW filter bandwidth, either 7MHz or 8MHz)
+ */
+
+ d_bw = bw;
+ set_freq(d_freq);
+}
+
+void
+db_dtt754::_set_rfagc(float gain)
+{
+ assert(gain <= 60 && gain >= 0);
+ // FIXME this has a 0.5V step between gain = 60 and gain = 59.
+ // Why are there two cases instead of a single linear case?
+ float voltage;
+ if(gain == 60) {
+ voltage = 4;
+ }
+ else {
+ voltage = gain/60.0 * 2.25 + 1.25;
+ }
+
+ int dacword = (int)(4096*voltage/1.22/3.3); // 1.22 = opamp gain
+
+ assert(dacword>=0 && dacword<4096);
+ usrp()->write_aux_dac(d_which, 1, dacword);
+}
+
+void
+db_dtt754::_set_ifagc(float gain)
+{
+ assert(gain <= 35 && gain >= 0);
+ float voltage = gain/35.0 * 2.1 + 1.4;
+ int dacword = (int)(4096*voltage/1.22/3.3); // 1.22 = opamp gain
+
+ assert(dacword>=0 && dacword<4096);
+ usrp()->write_aux_dac(d_which, 0, dacword);
+}
+
+void
+db_dtt754::_set_pga(float pga_gain)
+{
+ assert(pga_gain >=0 && pga_gain <=20);
+ if(d_which == 0) {
+ usrp()->set_pga (0, pga_gain);
+ }
+ else {
+ usrp()->set_pga (2, pga_gain);
+ }
+}
diff --git a/usrp/host/lib/legacy/db_dtt754.h b/usrp/host/lib/legacy/db_dtt754.h
new file mode 100644
index 0000000000..93b9164e96
--- /dev/null
+++ b/usrp/host/lib/legacy/db_dtt754.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 3, or (at your option)
+// any later version.
+//
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+
+#ifndef DB_DTT754_H
+#define DB_DTT754_H
+
+#include <db_base.h>
+#include <boost/shared_ptr.hpp>
+
+class db_dtt754 : public db_base
+{
+public:
+ db_dtt754(usrp_basic_sptr usrp, int which);
+ ~db_dtt754();
+
+ float gain_min();
+ float gain_max();
+ float gain_db_per_step();
+ bool set_gain(float gain);
+
+ double freq_min();
+ double freq_max();
+ struct freq_result_t set_freq(double target_freq);
+
+ bool is_quadrature();
+ bool spectrum_inverted();
+ void set_bw(float bw);
+
+private:
+ void _set_rfagc(float gain);
+ void _set_ifagc(float gain);
+ void _set_pga(float pga_gain);
+
+ int d_i2c_addr;
+ float d_bw, d_freq, d_IF, d_f_ref;
+ bool d_inverted;
+};
+
+#endif
diff --git a/usrp/host/lib/legacy/db_dtt768.cc b/usrp/host/lib/legacy/db_dtt768.cc
new file mode 100644
index 0000000000..c2e9c9821a
--- /dev/null
+++ b/usrp/host/lib/legacy/db_dtt768.cc
@@ -0,0 +1,294 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 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.
+
+#include <db_dtt768.h>
+#include <db_base_impl.h>
+
+int
+control_byte_4()
+{
+ int C = 0; // Charge Pump Current, no info on how to choose
+ int R = 4; // 125 kHz fref
+
+ // int ATP = 7; // Disable internal AGC
+ return (0x80 | C<<5 | R);
+}
+
+int
+control_byte_5(float freq, int agcmode = 1)
+{
+ if(agcmode) {
+ if(freq < 150e6) {
+ return 0x3B;
+ }
+ else if(freq < 420e6) {
+ return 0x7E;
+ }
+ else {
+ return 0xB7;
+ }
+ }
+ else {
+ if(freq < 150e6) {
+ return 0x39;
+ }
+ else if(freq < 420e6) {
+ return 0x7C;
+ }
+ else {
+ return 0xB5;
+ }
+ }
+}
+
+int
+control_byte_6()
+{
+ int ATC = 0; // AGC time constant = 100ms, 1 = 3S
+ int IFE = 1; // IF AGC amplifier enable
+ int AT = 0; // AGC control, ???
+
+ return (ATC << 5 | IFE << 4 | AT);
+}
+
+int
+control_byte_7()
+{
+ int SAS = 1; // SAW Digital mode
+ int AGD = 1; // AGC disable
+ int ADS = 0; // AGC detector into ADC converter
+ int T = 0; // Test mode, undocumented
+ return (SAS << 7 | AGD << 5 | ADS << 4 | T);
+}
+
+db_dtt768::db_dtt768(usrp_basic_sptr _usrp, int which)
+ : db_base(_usrp, which)
+{
+ /*
+ * Control custom DTT76803-based daughterboard.
+ *
+ * @param usrp: instance of usrp.source_c
+ * @param which: which side: 0 or 1 corresponding to RX_A or RX_B respectively
+ * @type which: int
+ */
+
+ if(d_which == 0) {
+ d_i2c_addr = 0x60;
+ }
+ else {
+ d_i2c_addr = 0x62;
+ }
+
+ d_IF = 44e6;
+
+ d_f_ref = 125e3;
+ d_inverted = false;
+
+ set_gain((gain_min() + gain_max()) / 2.0);
+
+ bypass_adc_buffers(false);
+}
+
+db_dtt768::~db_dtt768()
+{
+}
+
+float
+db_dtt768::gain_min()
+{
+ return 0;
+}
+
+float
+db_dtt768::gain_max()
+{
+ return 115;
+}
+
+float
+db_dtt768::gain_db_per_step()
+{
+ return 1;
+}
+
+bool
+db_dtt768::set_gain(float gain)
+{
+ assert(gain>=0 && gain<=115);
+
+ float rfgain, ifgain, pgagain;
+ if(gain > 60) {
+ rfgain = 60;
+ gain = gain - 60;
+ }
+ else {
+ rfgain = gain;
+ gain = 0;
+ }
+
+ if(gain > 35) {
+ ifgain = 35;
+ gain = gain - 35;
+ }
+ else {
+ ifgain = gain;
+ gain = 0;
+ }
+ pgagain = gain;
+
+ _set_rfagc(rfgain);
+ _set_ifagc(ifgain);
+ _set_pga(pgagain);
+
+ return true;
+}
+
+double
+db_dtt768::freq_min()
+{
+ return 44e6;
+}
+
+double
+db_dtt768::freq_max()
+{
+ return 900e6;
+}
+
+struct freq_result_t
+db_dtt768::set_freq(double target_freq)
+{
+ /*
+ * @returns (ok, actual_baseband_freq) where:
+ * ok is True or False and indicates success or failure,
+ * actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+ */
+
+ freq_result_t ret = {false, 0.0};
+
+ if(target_freq < freq_min() || target_freq > freq_max()) {
+ return ret;
+ }
+
+ double target_lo_freq = target_freq + d_IF; // High side mixing
+
+ int divisor = (int)(0.5+(target_lo_freq / d_f_ref));
+ double actual_lo_freq = d_f_ref*divisor;
+
+ if((divisor & ~0x7fff) != 0) { // must be 15-bits or less
+ return ret;
+ }
+
+ // build i2c command string
+ std::vector<int> buf(6);
+ buf[0] = (divisor >> 8) & 0xff; // DB1
+ buf[1] = divisor & 0xff; // DB2
+ buf[2] = control_byte_4();
+ buf[3] = control_byte_5(target_freq);
+ buf[4] = control_byte_6();
+ buf[5] = control_byte_7();
+
+ bool ok = usrp()->write_i2c(d_i2c_addr, int_seq_to_str (buf));
+
+ d_freq = actual_lo_freq - d_IF;
+
+ ret.ok = ok;
+ ret.baseband_freq = actual_lo_freq;
+
+ return ret;
+
+}
+
+bool
+db_dtt768::is_quadrature()
+{
+ /*
+ * Return True if this board requires both I & Q analog channels.
+ *
+ * This bit of info is useful when setting up the USRP Rx mux register.
+ */
+
+ return false;
+}
+
+bool
+db_dtt768::spectrum_inverted()
+{
+ /*
+ * The 43.75 MHz version is inverted
+ */
+
+ return d_inverted;
+}
+
+void
+db_dtt768::set_bw(float bw)
+{
+ /*
+ * Choose the SAW filter bandwidth, either 7MHz or 8MHz)
+ */
+
+ d_bw = bw;
+ set_freq(d_freq);
+}
+
+void
+db_dtt768::_set_rfagc(float gain)
+{
+ assert(gain <= 60 && gain >= 0);
+ // FIXME this has a 0.5V step between gain = 60 and gain = 59.
+ // Why are there two cases instead of a single linear case?
+ float voltage;
+ if(gain == 60) {
+ voltage = 4;
+ }
+ else {
+ voltage = gain/60.0 * 2.25 + 1.25;
+ }
+
+ int dacword = (int)(4096*voltage/1.22/3.3); // 1.22 = opamp gain
+
+ assert(dacword>=0 && dacword<4096);
+ usrp()->write_aux_dac(d_which, 1, dacword);
+}
+
+void
+db_dtt768::_set_ifagc(float gain)
+{
+ assert(gain <= 35 && gain >= 0);
+ float voltage = gain/35.0 * 2.1 + 1.4;
+ int dacword = (int)(4096*voltage/1.22/3.3); // 1.22 = opamp gain
+
+ assert(dacword>=0 && dacword<4096);
+ usrp()->write_aux_dac(d_which, 0, dacword);
+}
+
+void
+db_dtt768::_set_pga(float pga_gain)
+{
+ assert(pga_gain >=0 && pga_gain <=20);
+ if(d_which == 0) {
+ usrp()->set_pga (0, pga_gain);
+ }
+ else {
+ usrp()->set_pga (2, pga_gain);
+ }
+}
diff --git a/usrp/host/lib/legacy/db_dtt768.h b/usrp/host/lib/legacy/db_dtt768.h
new file mode 100644
index 0000000000..b5560437b3
--- /dev/null
+++ b/usrp/host/lib/legacy/db_dtt768.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 3, or (at your option)
+// any later version.
+//
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+
+#ifndef DB_DTT768_H
+#define DB_DTT768_H
+
+#include <db_base.h>
+#include <boost/shared_ptr.hpp>
+
+class db_dtt768 : public db_base
+{
+public:
+ db_dtt768(usrp_basic_sptr usrp, int which);
+ ~db_dtt768();
+
+ float gain_min();
+ float gain_max();
+ float gain_db_per_step();
+ bool set_gain(float gain);
+
+ double freq_min();
+ double freq_max();
+ struct freq_result_t set_freq(double target_freq);
+
+ bool is_quadrature();
+ bool spectrum_inverted();
+ void set_bw(float bw);
+
+private:
+ void _set_rfagc(float gain);
+ void _set_ifagc(float gain);
+ void _set_pga(float pga_gain);
+
+ int d_i2c_addr;
+ float d_bw, d_freq, d_IF, d_f_ref;
+ bool d_inverted;
+};
+
+#endif
diff --git a/usrp/host/lib/legacy/db_flexrf.cc b/usrp/host/lib/legacy/db_flexrf.cc
new file mode 100644
index 0000000000..662d9095ca
--- /dev/null
+++ b/usrp/host/lib/legacy/db_flexrf.cc
@@ -0,0 +1,1148 @@
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 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.
+
+#include <db_flexrf.h>
+#include <db_base_impl.h>
+
+// d'board i/o pin defs
+// Tx and Rx have shared defs, but different i/o regs
+#define AUX_RXAGC (1 << 8)
+#define POWER_UP (1 << 7) // enables power supply
+#define RX_TXN (1 << 6) // Tx only: T/R antenna switch for TX/RX port
+#define RX2_RX1N (1 << 6) // Rx only: antenna switch between RX2 and TX/RX port
+#define ENABLE (1 << 5) // enables mixer
+#define AUX_SEN (1 << 4)
+#define AUX_SCLK (1 << 3)
+#define PLL_LOCK_DETECT (1 << 2)
+#define AUX_SDO (1 << 1)
+#define CLOCK_OUT (1 << 0)
+
+flexrf_base::flexrf_base(usrp_basic_sptr _usrp, int which, int _power_on)
+ : db_base(_usrp, which), d_power_on(_power_on)
+{
+ /*
+ @param usrp: instance of usrp.source_c
+ @param which: which side: 0 or 1 corresponding to side A or B respectively
+ @type which: int
+ */
+
+ d_first = true;
+ d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0;
+
+ usrp()->_write_oe(d_which, 0, 0xffff); // turn off all outputs
+ _enable_refclk(false); // disable refclk
+
+ set_auto_tr(false);
+}
+
+flexrf_base::~flexrf_base()
+{
+ delete d_common;
+}
+
+void
+flexrf_base::_write_all(int R, int control, int N)
+{
+ /*
+ Write R counter latch, control latch and N counter latch to VCO.
+
+ Adds 10ms delay between writing control and N if this is first call.
+ This is the required power-up sequence.
+
+ @param R: 24-bit R counter latch
+ @type R: int
+ @param control: 24-bit control latch
+ @type control: int
+ @param N: 24-bit N counter latch
+ @type N: int
+ */
+ timespec t;
+ t.tv_sec = 0;
+ t.tv_nsec = 10000000;
+
+ _write_R(R);
+ _write_control(control);
+ if(d_first) {
+ //time.sleep(0.010);
+ nanosleep(&t, NULL);
+ d_first = false;
+ }
+ _write_N(N);
+}
+
+void
+flexrf_base::_write_control(int control)
+{
+ _write_it((control & ~0x3) | 0);
+}
+
+void
+flexrf_base::_write_R(int R)
+{
+ _write_it((R & ~0x3) | 1);
+}
+
+void
+flexrf_base::_write_N(int N)
+{
+ _write_it((N & ~0x3) | 2);
+}
+
+void
+flexrf_base::_write_it(int v)
+{
+ char s[3];
+ s[0] = (char)((v >> 16) & 0xff);
+ s[1] = (char)((v >> 8) & 0xff);
+ s[2] = (char)(v & 0xff);
+ std::string str(s, 3);
+ usrp()->_write_spi(0, d_spi_enable, d_spi_format, str);
+}
+
+bool
+flexrf_base::_lock_detect()
+{
+ /*
+ @returns: the value of the VCO/PLL lock detect bit.
+ @rtype: 0 or 1
+ */
+ if(usrp()->read_io(d_which) & PLL_LOCK_DETECT) {
+ return true;
+ }
+ else { // Give it a second chance
+ // FIXME: make portable sleep
+ timespec t;
+ t.tv_sec = 0;
+ t.tv_nsec = 100000000;
+ nanosleep(&t, NULL);
+
+ if(usrp()->read_io(d_which) & PLL_LOCK_DETECT) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+}
+
+bool
+flexrf_base::_compute_regs(double freq, int &retR, int &retcontrol,
+ int &retN, double &retfreq)
+{
+ /*
+ Determine values of R, control, and N registers, along with actual freq.
+
+ @param freq: target frequency in Hz
+ @type freq: float
+ @returns: (R, control, N, actual_freq)
+ @rtype: tuple(int, int, int, float)
+
+ Override this in derived classes.
+ */
+
+ //raise NotImplementedError;
+ throw std::runtime_error("_compute_regs called from flexrf_base\n");
+}
+
+int
+flexrf_base::_compute_control_reg()
+{
+ return d_common->_compute_control_reg();
+}
+
+int
+flexrf_base::_refclk_divisor()
+{
+ return d_common->_refclk_divisor();
+}
+
+double
+flexrf_base::_refclk_freq()
+{
+ return 64e6/_refclk_divisor();
+}
+
+struct freq_result_t
+flexrf_base::set_freq(double freq)
+{
+ /*
+ @returns (ok, actual_baseband_freq) where:
+ ok is True or False and indicates success or failure,
+ actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+ */
+
+ struct freq_result_t args = {false, 0};
+
+ // Offsetting the LO helps get the Tx carrier leakage out of the way.
+ // This also ensures that on Rx, we're not getting hosed by the
+ // FPGA's DC removal loop's time constant. We were seeing a
+ // problem when running with discontinuous transmission.
+ // Offsetting the LO made the problem go away.
+ freq += d_lo_offset;
+
+ int R, control, N;
+ double actual_freq;
+ _compute_regs(freq, R, control, N, actual_freq);
+
+ if(R==0) {
+ return args;
+ }
+
+ _write_all(R, control, N);
+ args.ok = _lock_detect();
+ args.baseband_freq = actual_freq;
+ return args;
+}
+
+bool
+flexrf_base::_set_pga(float pga_gain)
+{
+ if(d_which == 0) {
+ usrp()->set_pga(0, pga_gain);
+ usrp()->set_pga(1, pga_gain);
+ }
+ else {
+ usrp()->set_pga(2, pga_gain);
+ usrp()->set_pga(3, pga_gain);
+ }
+ return true;
+}
+
+bool
+flexrf_base::is_quadrature()
+{
+ /*
+ Return True if this board requires both I & Q analog channels.
+
+ This bit of info is useful when setting up the USRP Rx mux register.
+ */
+ return true;
+}
+
+double
+flexrf_base::freq_min()
+{
+ return d_common->freq_min();
+}
+
+double
+flexrf_base::freq_max()
+{
+ return d_common->freq_max();
+}
+
+// ----------------------------------------------------------------
+
+flexrf_base_tx::flexrf_base_tx(usrp_basic_sptr _usrp, int which, int _power_on)
+ : flexrf_base(_usrp, which, _power_on)
+{
+ /*
+ @param usrp: instance of usrp.sink_c
+ @param which: 0 or 1 corresponding to side TX_A or TX_B respectively.
+ */
+
+ if(which == 0) {
+ d_spi_enable = SPI_ENABLE_TX_A;
+ }
+ else {
+ d_spi_enable = SPI_ENABLE_TX_B;
+ }
+
+ // power up the transmit side, but don't enable the mixer
+ usrp()->_write_oe(d_which,(POWER_UP|RX_TXN|ENABLE), 0xffff);
+ usrp()->write_io(d_which, (power_on()|RX_TXN), (POWER_UP|RX_TXN|ENABLE));
+ set_lo_offset(4e6);
+
+ set_gain((gain_min() + gain_max()) / 2.0); // initialize gain
+}
+
+flexrf_base_tx::~flexrf_base_tx()
+{
+ shutdown();
+}
+
+
+void
+flexrf_base_tx::shutdown()
+{
+ // fprintf(stderr, "flexrf_base_tx::shutdown d_is_shutdown = %d\n", d_is_shutdown);
+
+ if (!d_is_shutdown){
+ d_is_shutdown = true;
+ // do whatever there is to do to shutdown
+
+ // Power down and leave the T/R switch in the R position
+ usrp()->write_io(d_which, (power_off()|RX_TXN), (POWER_UP|RX_TXN|ENABLE));
+
+ // Power down VCO/PLL
+ d_PD = 3;
+
+ _write_control(_compute_control_reg());
+ _enable_refclk(false); // turn off refclk
+ set_auto_tr(false);
+ }
+}
+
+bool
+flexrf_base_tx::set_auto_tr(bool on)
+{
+ bool ok = true;
+ if(on) {
+ ok &= set_atr_mask (RX_TXN | ENABLE);
+ ok &= set_atr_txval(0 | ENABLE);
+ ok &= set_atr_rxval(RX_TXN | 0);
+ }
+ else {
+ ok &= set_atr_mask (0);
+ ok &= set_atr_txval(0);
+ ok &= set_atr_rxval(0);
+ }
+ return ok;
+}
+
+bool
+flexrf_base_tx::set_enable(bool on)
+{
+ /*
+ Enable transmitter if on is true
+ */
+
+ int v;
+ int mask = RX_TXN | ENABLE;
+ if(on) {
+ v = ENABLE;
+ }
+ else {
+ v = RX_TXN;
+ }
+ return usrp()->write_io(d_which, v, mask);
+}
+
+float
+flexrf_base_tx::gain_min()
+{
+ return usrp()->pga_max();
+}
+
+float
+flexrf_base_tx::gain_max()
+{
+ return usrp()->pga_max();
+}
+
+float
+flexrf_base_tx::gain_db_per_step()
+{
+ return 1;
+}
+
+bool
+flexrf_base_tx::set_gain(float gain)
+{
+ /*
+ Set the gain.
+
+ @param gain: gain in decibels
+ @returns True/False
+ */
+ return _set_pga(usrp()->pga_max());
+}
+
+
+/**************************************************************************/
+
+
+flexrf_base_rx::flexrf_base_rx(usrp_basic_sptr _usrp, int which, int _power_on)
+ : flexrf_base(_usrp, which, _power_on)
+{
+ /*
+ @param usrp: instance of usrp.source_c
+ @param which: 0 or 1 corresponding to side RX_A or RX_B respectively.
+ */
+
+ if(which == 0) {
+ d_spi_enable = SPI_ENABLE_RX_A;
+ }
+ else {
+ d_spi_enable = SPI_ENABLE_RX_B;
+ }
+
+ usrp()->_write_oe(d_which, (POWER_UP|RX2_RX1N|ENABLE), 0xffff);
+ usrp()->write_io(d_which, (power_on()|RX2_RX1N|ENABLE),
+ (POWER_UP|RX2_RX1N|ENABLE));
+
+ // set up for RX on TX/RX port
+ select_rx_antenna("TX/RX");
+
+ bypass_adc_buffers(true);
+
+ set_lo_offset(-4e6);
+}
+
+flexrf_base_rx::~flexrf_base_rx()
+{
+ shutdown();
+}
+
+void
+flexrf_base_rx::shutdown()
+{
+ // fprintf(stderr, "flexrf_base_rx::shutdown d_is_shutdown = %d\n", d_is_shutdown);
+
+ if (!d_is_shutdown){
+ d_is_shutdown = true;
+ // do whatever there is to do to shutdown
+
+ // Power down
+ usrp()->common_write_io(C_RX, d_which, power_off(), (POWER_UP|ENABLE));
+
+ // Power down VCO/PLL
+ d_PD = 3;
+
+
+ // fprintf(stderr, "flexrf_base_rx::shutdown before _write_control\n");
+ _write_control(_compute_control_reg());
+
+ // fprintf(stderr, "flexrf_base_rx::shutdown before _enable_refclk\n");
+ _enable_refclk(false); // turn off refclk
+
+ // fprintf(stderr, "flexrf_base_rx::shutdown before set_auto_tr\n");
+ set_auto_tr(false);
+
+ // fprintf(stderr, "flexrf_base_rx::shutdown after set_auto_tr\n");
+ }
+}
+
+bool
+flexrf_base_rx::set_auto_tr(bool on)
+{
+ bool ok = true;
+ if(on) {
+ ok &= set_atr_mask (ENABLE);
+ ok &= set_atr_txval( 0);
+ ok &= set_atr_rxval(ENABLE);
+ }
+ else {
+ ok &= set_atr_mask (0);
+ ok &= set_atr_txval(0);
+ ok &= set_atr_rxval(0);
+ }
+ return true;
+}
+
+bool
+flexrf_base_rx::select_rx_antenna(int which_antenna)
+{
+ /*
+ Specify which antenna port to use for reception.
+ @param which_antenna: either 'TX/RX' or 'RX2'
+ */
+
+ if(which_antenna == 0) {
+ usrp()->write_io(d_which, 0,RX2_RX1N);
+ }
+ else if(which_antenna == 1) {
+ usrp()->write_io(d_which, RX2_RX1N, RX2_RX1N);
+ }
+ else {
+ return false;
+ // throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
+ }
+ return true;
+}
+
+bool
+flexrf_base_rx::select_rx_antenna(const std::string &which_antenna)
+{
+ /*
+ Specify which antenna port to use for reception.
+ @param which_antenna: either 'TX/RX' or 'RX2'
+ */
+
+ if(which_antenna == "TX/RX") {
+ usrp()->write_io(d_which, 0, RX2_RX1N);
+ }
+ else if(which_antenna == "RX2") {
+ usrp()->write_io(d_which, RX2_RX1N, RX2_RX1N);
+ }
+ else {
+ // throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
+ return false;
+ }
+ return true;
+}
+
+bool
+flexrf_base_rx::set_gain(float gain)
+{
+ /*
+ Set the gain.
+
+ @param gain: gain in decibels
+ @returns True/False
+ */
+
+ // clamp gain
+ gain = std::max(gain_min(), std::min(gain, gain_max()));
+
+ float pga_gain, agc_gain;
+ float V_maxgain, V_mingain, V_fullscale, dac_value;
+
+ float maxgain = gain_max() - usrp()->pga_max();
+ float mingain = gain_min();
+ if(gain > maxgain) {
+ pga_gain = gain-maxgain;
+ assert(pga_gain <= usrp()->pga_max());
+ agc_gain = maxgain;
+ }
+ else {
+ pga_gain = 0;
+ agc_gain = gain;
+ }
+
+ V_maxgain = .2;
+ V_mingain = 1.2;
+ V_fullscale = 3.3;
+ dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale;
+
+ assert(dac_value>=0 && dac_value<4096);
+
+ return (usrp()->write_aux_dac(d_which, 0, int(dac_value))
+ && _set_pga(int(pga_gain)));
+}
+
+// ----------------------------------------------------------------
+
+
+_AD4360_common::_AD4360_common()
+{
+ // R-Register Common Values
+ d_R_RSV = 0; // bits 23,22
+ d_BSC = 3; // bits 21,20 Div by 8 to be safe
+ d_TEST = 0; // bit 19
+ d_LDP = 1; // bit 18
+ d_ABP = 0; // bit 17,16 3ns
+
+ // N-Register Common Values
+ d_N_RSV = 0; // bit 7
+
+ // Control Register Common Values
+ d_PD = 0; // bits 21,20 Normal operation
+ d_PL = 0; // bits 13,12 11mA
+ d_MTLD = 1; // bit 11 enabled
+ d_CPG = 0; // bit 10 CP setting 1
+ d_CP3S = 0; // bit 9 Normal
+ d_PDP = 1; // bit 8 Positive
+ d_MUXOUT = 1; // bits 7:5 Digital Lock Detect
+ d_CR = 0; // bit 4 Normal
+ d_PC = 1; // bits 3,2 Core power 10mA
+}
+
+_AD4360_common::~_AD4360_common()
+{
+}
+
+bool
+_AD4360_common::_compute_regs(double refclk_freq, double freq, int &retR,
+ int &retcontrol, int &retN, double &retfreq)
+{
+ /*
+ Determine values of R, control, and N registers, along with actual freq.
+
+ @param freq: target frequency in Hz
+ @type freq: float
+ @returns: (R, control, N, actual_freq)
+ @rtype: tuple(int, int, int, float)
+ */
+
+ // Band-specific N-Register Values
+ //float phdet_freq = _refclk_freq()/d_R_DIV;
+ double phdet_freq = refclk_freq/d_R_DIV;
+ double desired_n = round(freq*d_freq_mult/phdet_freq);
+ double actual_freq = desired_n * phdet_freq;
+ int B = floor(desired_n/_prescaler());
+ int A = desired_n - _prescaler()*B;
+ d_B_DIV = int(B); // bits 20:8
+ d_A_DIV = int(A); // bit 6:2
+
+ //assert db_B_DIV >= db_A_DIV
+ if(d_B_DIV < d_A_DIV) {
+ retR = 0;
+ retcontrol = 0;
+ retN = 0;
+ retfreq = 0;
+ return false;
+ }
+
+ int R = (d_R_RSV<<22) | (d_BSC<<20) | (d_TEST<<19) |
+ (d_LDP<<18) | (d_ABP<<16) | (d_R_DIV<<2);
+
+ int control = _compute_control_reg();
+
+ int N = (d_DIVSEL<<23) | (d_DIV2<<22) | (d_CPGAIN<<21) |
+ (d_B_DIV<<8) | (d_N_RSV<<7) | (d_A_DIV<<2);
+
+ retR = R;
+ retcontrol = control;
+ retN = N;
+ retfreq = actual_freq/d_freq_mult;
+ return true;
+}
+
+int
+_AD4360_common::_compute_control_reg()
+{
+ int control = (d_P<<22) | (d_PD<<20) | (d_CP2<<17) | (d_CP1<<14)
+ | (d_PL<<12) | (d_MTLD<<11) | (d_CPG<<10) | (d_CP3S<<9) | (d_PDP<<8)
+ | (d_MUXOUT<<5) | (d_CR<<4) | (d_PC<<2);
+
+ return control;
+}
+
+int
+_AD4360_common::_refclk_divisor()
+{
+ /*
+ Return value to stick in REFCLK_DIVISOR register
+ */
+ return 1;
+}
+
+int
+_AD4360_common::_prescaler()
+{
+ if(d_P == 0) {
+ return 8;
+ }
+ else if(d_P == 1) {
+ return 16;
+ }
+ else {
+ return 32;
+ }
+}
+
+//----------------------------------------------------------------------
+
+_2400_common::_2400_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
+_2400_common::freq_min()
+{
+ return 2300e6;
+}
+
+double
+_2400_common::freq_max()
+{
+ return 2700e6;
+}
+
+//----------------------------------------------------------------------
+
+_1200_common::_1200_common()
+ : _AD4360_common()
+{
+ // Band-specific R-Register Values
+ d_R_DIV = 16; // bits 15:2 DIV by 16 for a 1 MHz phase detector freq
+
+ // Band-specific C-Register values
+ d_P = 1; // bits 23,22 Div by 16/17
+ d_CP2 = 7; // bits 19:17 1.25 mA
+ d_CP1 = 7; // bits 16:14 1.25 mA
+
+ // Band specifc N-Register Values
+ d_DIVSEL = 0; // bit 23
+ d_DIV2 = 1; // bit 22
+ d_CPGAIN = 0; // bit 21
+ d_freq_mult = 2;
+}
+
+double
+_1200_common::freq_min()
+{
+ return 1150e6;
+}
+
+double
+_1200_common::freq_max()
+{
+ return 1350e6;
+}
+
+//-------------------------------------------------------------------------
+
+_1800_common::_1800_common()
+ : _AD4360_common()
+{
+ // Band-specific R-Register Values
+ d_R_DIV = 16; // bits 15:2 DIV by 16 for a 1 MHz phase detector freq
+
+ // Band-specific C-Register values
+ d_P = 1; // bits 23,22 Div by 16/17
+ d_CP2 = 7; // bits 19:17 1.25 mA
+ d_CP1 = 7; // bits 16:14 1.25 mA
+
+ // Band specifc N-Register Values
+ d_DIVSEL = 0; // bit 23
+ d_DIV2 = 0; // bit 22
+ d_freq_mult = 1;
+ d_CPGAIN = 0; // bit 21
+}
+
+double
+_1800_common::freq_min()
+{
+ return 1600e6;
+}
+
+double
+_1800_common::freq_max()
+{
+ return 2000e6;
+}
+
+//-------------------------------------------------------------------------
+
+_900_common::_900_common()
+ : _AD4360_common()
+{
+ // Band-specific R-Register Values
+ d_R_DIV = 16; // bits 15:2 DIV by 16 for a 1 MHz phase detector freq
+
+ // Band-specific C-Register values
+ d_P = 1; // bits 23,22 Div by 16/17
+ d_CP2 = 7; // bits 19:17 1.25 mA
+ d_CP1 = 7; // bits 16:14 1.25 mA
+
+ // Band specifc N-Register Values
+ d_DIVSEL = 0; // bit 23
+ d_DIV2 = 1; // bit 22
+ d_freq_mult = 2;
+ d_CPGAIN = 0; // bit 21
+}
+
+double
+_900_common::freq_min()
+{
+ return 800e6;
+}
+
+double
+_900_common::freq_max()
+{
+ return 1000e6;
+}
+
+//-------------------------------------------------------------------------
+
+_400_common::_400_common()
+ : _AD4360_common()
+{
+ // Band-specific R-Register Values
+ d_R_DIV = 16; // bits 15:2
+
+ // Band-specific C-Register values
+ d_P = 0; // bits 23,22 Div by 8/9
+ d_CP2 = 7; // bits 19:17 1.25 mA
+ d_CP1 = 7; // bits 16:14 1.25 mA
+
+ // Band specifc N-Register Values These are different for TX/RX
+ d_DIVSEL = 0; // bit 23
+ d_freq_mult = 2;
+
+ d_CPGAIN = 0; // bit 21
+}
+
+double
+_400_common::freq_min()
+{
+ return 400e6;
+}
+
+double
+_400_common::freq_max()
+{
+ return 500e6;
+}
+
+_400_tx::_400_tx()
+ : _400_common()
+{
+ d_DIV2 = 1; // bit 22
+}
+
+_400_rx::_400_rx()
+ : _400_common()
+{
+ d_DIV2 = 0; // bit 22 // RX side has built-in DIV2 in AD8348
+}
+
+//------------------------------------------------------------
+
+db_flexrf_2400_tx::db_flexrf_2400_tx(usrp_basic_sptr usrp, int which)
+ : flexrf_base_tx(usrp, which)
+{
+ d_common = new _2400_common();
+}
+
+db_flexrf_2400_tx::~db_flexrf_2400_tx()
+{
+}
+
+bool
+db_flexrf_2400_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_2400_rx::db_flexrf_2400_rx(usrp_basic_sptr usrp, int which)
+ : flexrf_base_rx(usrp, which)
+{
+ d_common = new _2400_common();
+ set_gain((gain_min() + gain_max()) / 2.0); // initialize gain
+}
+
+db_flexrf_2400_rx::~db_flexrf_2400_rx()
+{
+}
+
+float
+db_flexrf_2400_rx::gain_min()
+{
+ return usrp()->pga_min();
+}
+
+float
+db_flexrf_2400_rx::gain_max()
+{
+ return usrp()->pga_max()+70;
+}
+
+float
+db_flexrf_2400_rx::gain_db_per_step()
+{
+ return 0.05;
+}
+
+
+bool
+db_flexrf_2400_rx::i_and_q_swapped()
+{
+ return true;
+}
+
+bool
+db_flexrf_2400_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_1200_tx::db_flexrf_1200_tx(usrp_basic_sptr usrp, int which)
+ : flexrf_base_tx(usrp, which)
+{
+ d_common = new _1200_common();
+}
+
+db_flexrf_1200_tx::~db_flexrf_1200_tx()
+{
+}
+
+bool
+db_flexrf_1200_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_1200_rx::db_flexrf_1200_rx(usrp_basic_sptr usrp, int which)
+ : flexrf_base_rx(usrp, which)
+{
+ d_common = new _1200_common();
+ set_gain((gain_min() + gain_max()) / 2.0); // initialize gain
+}
+
+db_flexrf_1200_rx::~db_flexrf_1200_rx()
+{
+}
+
+float
+db_flexrf_1200_rx::gain_min()
+{
+ return usrp()->pga_min();
+}
+
+float
+db_flexrf_1200_rx::gain_max()
+{
+ return usrp()->pga_max()+70;
+}
+
+float
+db_flexrf_1200_rx::gain_db_per_step()
+{
+ return 0.05;
+}
+
+bool
+db_flexrf_1200_rx::i_and_q_swapped()
+{
+ return true;
+}
+
+bool
+db_flexrf_1200_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_1800_tx::db_flexrf_1800_tx(usrp_basic_sptr usrp, int which)
+ : flexrf_base_tx(usrp, which)
+{
+ d_common = new _1800_common();
+}
+
+db_flexrf_1800_tx::~db_flexrf_1800_tx()
+{
+}
+
+bool
+db_flexrf_1800_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_1800_rx::db_flexrf_1800_rx(usrp_basic_sptr usrp, int which)
+ : flexrf_base_rx(usrp, which)
+{
+ d_common = new _1800_common();
+ set_gain((gain_min() + gain_max()) / 2.0); // initialize gain
+}
+
+db_flexrf_1800_rx::~db_flexrf_1800_rx()
+{
+}
+
+
+float
+db_flexrf_1800_rx::gain_min()
+{
+ return usrp()->pga_min();
+}
+
+float
+db_flexrf_1800_rx::gain_max()
+{
+ return usrp()->pga_max()+70;
+}
+
+float
+db_flexrf_1800_rx::gain_db_per_step()
+{
+ return 0.05;
+}
+
+bool
+db_flexrf_1800_rx::i_and_q_swapped()
+{
+ return true;
+}
+
+bool
+db_flexrf_1800_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_900_tx::db_flexrf_900_tx(usrp_basic_sptr usrp, int which)
+ : flexrf_base_tx(usrp, which)
+{
+ d_common = new _900_common();
+}
+
+db_flexrf_900_tx::~db_flexrf_900_tx()
+{
+}
+
+bool
+db_flexrf_900_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_900_rx::db_flexrf_900_rx(usrp_basic_sptr usrp, int which)
+ : flexrf_base_rx(usrp, which)
+{
+ d_common = new _900_common();
+ set_gain((gain_min() + gain_max()) / 2.0); // initialize gain
+}
+
+db_flexrf_900_rx::~db_flexrf_900_rx()
+{
+}
+
+float
+db_flexrf_900_rx::gain_min()
+{
+ return usrp()->pga_min();
+}
+
+float
+db_flexrf_900_rx::gain_max()
+{
+ return usrp()->pga_max()+70;
+}
+
+float
+db_flexrf_900_rx::gain_db_per_step()
+{
+ return 0.05;
+}
+
+bool
+db_flexrf_900_rx::i_and_q_swapped()
+{
+ return true;
+}
+
+bool
+db_flexrf_900_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_400_tx::db_flexrf_400_tx(usrp_basic_sptr usrp, int which)
+ : flexrf_base_tx(usrp, which, POWER_UP)
+{
+ d_common = new _400_tx();
+}
+
+db_flexrf_400_tx::~db_flexrf_400_tx()
+{
+}
+
+bool
+db_flexrf_400_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_400_rx::db_flexrf_400_rx(usrp_basic_sptr usrp, int which)
+ : flexrf_base_rx(usrp, which, POWER_UP)
+{
+ d_common = new _400_rx();
+ set_gain((gain_min() + gain_max()) / 2.0); // initialize gain
+}
+
+db_flexrf_400_rx::~db_flexrf_400_rx()
+{
+}
+
+float
+db_flexrf_400_rx::gain_min()
+{
+ return usrp()->pga_min();
+}
+
+float
+db_flexrf_400_rx::gain_max()
+{
+ return usrp()->pga_max()+45;
+}
+
+float
+
+db_flexrf_400_rx::gain_db_per_step()
+{
+ return 0.035;
+}
+
+
+bool
+db_flexrf_400_rx::i_and_q_swapped()
+{
+ return true;
+}
+
+bool
+db_flexrf_400_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);
+}
+
diff --git a/usrp/host/lib/legacy/db_flexrf.h b/usrp/host/lib/legacy/db_flexrf.h
new file mode 100644
index 0000000000..b9ccfc3acf
--- /dev/null
+++ b/usrp/host/lib/legacy/db_flexrf.h
@@ -0,0 +1,355 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 3, or (at your option)
+// any later version.
+//
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+
+#ifndef DB_FLEXRF_H
+#define DB_FLEXRF_H
+
+#include <db_base.h>
+#include <cmath>
+
+//debug_using_gui = true // Must be set to True or False
+#define debug_using_gui false // Must be set to True or False
+
+class _AD4360_common;
+
+class flexrf_base : public db_base
+{
+public:
+ flexrf_base(usrp_basic_sptr usrp, int which, int _power_on=0);
+ ~flexrf_base();
+
+ struct freq_result_t set_freq(double freq);
+
+ bool is_quadrature();
+ double freq_min();
+ double freq_max();
+
+protected:
+ void _write_all(int R, int control, int N);
+ void _write_control(int control);
+ void _write_R(int R);
+ void _write_N(int N);
+ void _write_it(int v);
+ bool _lock_detect();
+
+ virtual bool _compute_regs(double freq, int &retR, int &retcontrol,
+ int &retN, double &retfreq);
+ int _compute_control_reg();
+ int _refclk_divisor();
+ double _refclk_freq();
+
+ bool _set_pga(float pga_gain);
+
+ int power_on() { return d_power_on; }
+ int power_off() { return 0; }
+
+ bool d_first;
+ int d_spi_format;
+ int d_spi_enable;
+ int d_power_on;
+ int d_PD;
+
+ _AD4360_common *d_common;
+};
+
+// ----------------------------------------------------------------
+
+class flexrf_base_tx : public flexrf_base
+{
+protected:
+ void shutdown();
+
+public:
+ flexrf_base_tx(usrp_basic_sptr usrp, int which, int _power_on=0);
+ ~flexrf_base_tx();
+
+ // All RFX tx d'boards have fixed gain
+ float gain_min();
+ float gain_max();
+ float gain_db_per_step();
+
+ bool set_auto_tr(bool on);
+ bool set_enable(bool on);
+ bool set_gain(float gain);
+};
+
+class flexrf_base_rx : public flexrf_base
+{
+protected:
+ void shutdown();
+
+public:
+ flexrf_base_rx(usrp_basic_sptr usrp, int which, int _power_on=0);
+ ~flexrf_base_rx();
+
+ bool set_auto_tr(bool on);
+ bool select_rx_antenna(int which_antenna);
+ bool select_rx_antenna(const std::string &which_antenna);
+ bool set_gain(float gain);
+
+};
+
+// ----------------------------------------------------------------
+
+
+class _AD4360_common
+{
+public:
+ _AD4360_common();
+ virtual ~_AD4360_common();
+
+ virtual double freq_min() = 0;
+ virtual double freq_max() = 0;
+
+ bool _compute_regs(double refclk_freq, double freq, int &retR,
+ int &retcontrol, int &retN, double &retfreq);
+ int _compute_control_reg();
+ virtual int _refclk_divisor();
+ int _prescaler();
+
+ void R_DIV(int div) { d_R_DIV = div; }
+
+protected:
+ int d_R_RSV, d_BSC, d_TEST, d_LDP, d_ABP, d_N_RSV, d_PL, d_MTLD;
+ int d_CPG, d_CP3S, d_PDP, d_MUXOUT, d_CR, d_PC;
+
+ // FIXME: d_PD might cause conflict from flexrf_base
+ int d_A_DIV, d_B_DIV, d_R_DIV, d_P, d_PD, d_CP2, d_CP1, d_DIVSEL;
+ int d_DIV2, d_CPGAIN, d_freq_mult;
+
+};
+
+//----------------------------------------------------------------------
+
+class _2400_common : public _AD4360_common
+{
+ public:
+ _2400_common();
+ ~_2400_common() {}
+
+ double freq_min();
+ double freq_max();
+};
+
+//----------------------------------------------------------------------
+
+class _1200_common : public _AD4360_common
+{
+public:
+ _1200_common();
+ ~_1200_common() {}
+
+ double freq_min();
+ double freq_max();
+};
+
+//-------------------------------------------------------------------------
+
+class _1800_common : public _AD4360_common
+{
+ public:
+ _1800_common();
+ ~_1800_common() {}
+
+ double freq_min();
+ double freq_max();
+};
+
+//-------------------------------------------------------------------------
+
+class _900_common : public _AD4360_common
+{
+public:
+ _900_common();
+ ~_900_common() {}
+
+ double freq_min();
+ double freq_max();
+};
+
+//-------------------------------------------------------------------------
+
+class _400_common : public _AD4360_common
+{
+public:
+ _400_common();
+ ~_400_common() {}
+
+ double freq_min();
+ double freq_max();
+};
+
+class _400_tx : public _400_common
+{
+public:
+ _400_tx();
+ ~_400_tx() {}
+};
+
+class _400_rx : public _400_common
+{
+public:
+ _400_rx();
+ ~_400_rx() {}
+};
+
+//------------------------------------------------------------
+
+class db_flexrf_2400_tx : public flexrf_base_tx
+{
+ public:
+ db_flexrf_2400_tx(usrp_basic_sptr usrp, int which);
+ ~db_flexrf_2400_tx();
+
+ // Wrapper calls to d_common functions
+ bool _compute_regs(double freq, int &retR, int &retcontrol,
+ int &retN, double &retfreq);
+};
+
+class db_flexrf_2400_rx : public flexrf_base_rx
+{
+public:
+ db_flexrf_2400_rx(usrp_basic_sptr usrp, int which);
+ ~db_flexrf_2400_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_1200_tx : public flexrf_base_tx
+{
+public:
+ db_flexrf_1200_tx(usrp_basic_sptr usrp, int which);
+ ~db_flexrf_1200_tx();
+
+ // Wrapper calls to d_common functions
+ bool _compute_regs(double freq, int &retR, int &retcontrol,
+ int &retN, double &retfreq);
+};
+
+class db_flexrf_1200_rx : public flexrf_base_rx
+{
+public:
+ db_flexrf_1200_rx(usrp_basic_sptr usrp, int which);
+ ~db_flexrf_1200_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_1800_tx : public flexrf_base_tx
+{
+ public:
+ db_flexrf_1800_tx(usrp_basic_sptr usrp, int which);
+ ~db_flexrf_1800_tx();
+
+ // Wrapper calls to d_common functions
+ bool _compute_regs(double freq, int &retR, int &retcontrol,
+ int &retN, double &retfreq);
+};
+
+class db_flexrf_1800_rx : public flexrf_base_rx
+{
+public:
+ db_flexrf_1800_rx(usrp_basic_sptr usrp, int which);
+ ~db_flexrf_1800_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_900_tx : public flexrf_base_tx
+{
+ public:
+ db_flexrf_900_tx(usrp_basic_sptr usrp, int which);
+ ~db_flexrf_900_tx();
+
+ // Wrapper calls to d_common functions
+ bool _compute_regs(double freq, int &retR, int &retcontrol,
+ int &retN, double &retfreq);
+};
+
+class db_flexrf_900_rx : public flexrf_base_rx
+{
+public:
+ db_flexrf_900_rx(usrp_basic_sptr usrp, int which);
+ ~db_flexrf_900_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_400_tx : public flexrf_base_tx
+{
+ public:
+ db_flexrf_400_tx(usrp_basic_sptr usrp, int which);
+ ~db_flexrf_400_tx();
+
+ // Wrapper calls to d_common functions
+ bool _compute_regs(double freq, int &retR, int &retcontrol,
+ int &retN, double &retfreq);
+};
+
+class db_flexrf_400_rx : public flexrf_base_rx
+{
+public:
+ db_flexrf_400_rx(usrp_basic_sptr usrp, int which);
+ ~db_flexrf_400_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);
+};
+
+#endif
diff --git a/usrp/host/lib/legacy/db_flexrf_mimo.cc b/usrp/host/lib/legacy/db_flexrf_mimo.cc
new file mode 100644
index 0000000000..fd996bfa9d
--- /dev/null
+++ b/usrp/host/lib/legacy/db_flexrf_mimo.cc
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <db_flexrf_mimo.h>
+#include <fpga_regs_standard.h>
+#include <fpga_regs_common.h>
+#include <usrp_prims.h>
+#include <usrp_spi_defs.h>
+
+
+db_flexrf_2400_tx_mimo_a::db_flexrf_2400_tx_mimo_a(usrp_basic_sptr usrp, int which)
+ : db_flexrf_2400_tx(usrp, which)
+{
+ _enable_refclk(true);
+ d_common->R_DIV(1);
+}
+
+int
+db_flexrf_2400_tx_mimo_a::_refclk_divisor()
+{
+ return 16;
+}
+
+db_flexrf_2400_rx_mimo_a::db_flexrf_2400_rx_mimo_a(usrp_basic_sptr usrp, int which)
+ : db_flexrf_2400_rx(usrp, which)
+{
+ _enable_refclk(true);
+ d_common->R_DIV(1);
+}
+
+int
+db_flexrf_2400_rx_mimo_a::_refclk_divisor()
+{
+ return 16;
+}
+
+db_flexrf_2400_tx_mimo_b::db_flexrf_2400_tx_mimo_b(usrp_basic_sptr usrp, int which)
+ : db_flexrf_2400_tx(usrp, which)
+{
+ d_common->R_DIV(16);
+}
+
+int
+db_flexrf_2400_tx_mimo_b::_refclk_divisor()
+{
+ return 1;
+}
+
+db_flexrf_2400_rx_mimo_b::db_flexrf_2400_rx_mimo_b(usrp_basic_sptr usrp, int which)
+ : db_flexrf_2400_rx(usrp, which)
+{
+ d_common->R_DIV(16);
+}
+
+int
+db_flexrf_2400_rx_mimo_b::_refclk_divisor()
+{
+ return 1;
+}
+
+db_flexrf_1800_tx_mimo_a::db_flexrf_1800_tx_mimo_a(usrp_basic_sptr usrp, int which)
+ : db_flexrf_1800_tx(usrp, which)
+{
+ _enable_refclk(true);
+ d_common->R_DIV(1);
+}
+
+int
+db_flexrf_1800_tx_mimo_a::_refclk_divisor()
+{
+ return 16;
+}
+
+db_flexrf_1800_rx_mimo_a::db_flexrf_1800_rx_mimo_a(usrp_basic_sptr usrp, int which)
+ : db_flexrf_1800_rx(usrp, which)
+{
+ _enable_refclk(true);
+ d_common->R_DIV(1);
+}
+
+int
+db_flexrf_1800_rx_mimo_a::_refclk_divisor()
+{
+ return 16;
+}
+
+db_flexrf_1800_tx_mimo_b::db_flexrf_1800_tx_mimo_b(usrp_basic_sptr usrp, int which)
+ : db_flexrf_1800_tx(usrp, which)
+{
+ d_common->R_DIV(16);
+}
+
+int
+db_flexrf_1800_tx_mimo_b::_refclk_divisor()
+{
+ return 1;
+}
+
+db_flexrf_1800_rx_mimo_b::db_flexrf_1800_rx_mimo_b(usrp_basic_sptr usrp, int which)
+ : db_flexrf_1800_rx(usrp, which)
+{
+ d_common->R_DIV(16);
+}
+
+int
+db_flexrf_1800_rx_mimo_b::_refclk_divisor()
+{
+ return 1;
+}
+
+db_flexrf_1200_tx_mimo_a::db_flexrf_1200_tx_mimo_a(usrp_basic_sptr usrp, int which)
+ : db_flexrf_1200_tx(usrp, which)
+{
+ _enable_refclk(true);
+ d_common->R_DIV(1);
+}
+
+int
+db_flexrf_1200_tx_mimo_a::_refclk_divisor()
+{
+ return 16;
+}
+
+db_flexrf_1200_rx_mimo_a::db_flexrf_1200_rx_mimo_a(usrp_basic_sptr usrp, int which)
+ : db_flexrf_1200_rx(usrp, which)
+{
+ _enable_refclk(true);
+ d_common->R_DIV(1);
+}
+
+int
+db_flexrf_1200_rx_mimo_a::_refclk_divisor()
+{
+ return 16;
+}
+
+db_flexrf_1200_tx_mimo_b::db_flexrf_1200_tx_mimo_b(usrp_basic_sptr usrp, int which)
+ : db_flexrf_1200_tx(usrp, which)
+{
+ d_common->R_DIV(16);
+}
+
+int
+db_flexrf_1200_tx_mimo_b::_refclk_divisor()
+{
+ return 1;
+}
+
+db_flexrf_1200_rx_mimo_b::db_flexrf_1200_rx_mimo_b(usrp_basic_sptr usrp, int which)
+ : db_flexrf_1200_rx(usrp, which)
+{
+ d_common->R_DIV(16);
+}
+
+int
+db_flexrf_1200_rx_mimo_b::_refclk_divisor()
+{
+ return 1;
+}
+
+db_flexrf_900_tx_mimo_a::db_flexrf_900_tx_mimo_a(usrp_basic_sptr usrp, int which)
+ : db_flexrf_900_tx(usrp, which)
+{
+ _enable_refclk(true);
+ d_common->R_DIV(1);
+}
+
+int
+db_flexrf_900_tx_mimo_a::_refclk_divisor()
+{
+ return 16;
+}
+
+db_flexrf_900_rx_mimo_a::db_flexrf_900_rx_mimo_a(usrp_basic_sptr usrp, int which)
+ : db_flexrf_900_rx(usrp, which)
+{
+ _enable_refclk(true);
+ d_common->R_DIV(1);
+}
+
+int
+db_flexrf_900_rx_mimo_a::_refclk_divisor()
+{
+ return 16;
+}
+
+db_flexrf_900_tx_mimo_b::db_flexrf_900_tx_mimo_b(usrp_basic_sptr usrp, int which)
+ : db_flexrf_900_tx(usrp, which)
+{
+ d_common->R_DIV(16);
+}
+
+int
+db_flexrf_900_tx_mimo_b::_refclk_divisor()
+{
+ return 1;
+}
+
+db_flexrf_900_rx_mimo_b::db_flexrf_900_rx_mimo_b(usrp_basic_sptr usrp, int which)
+ : db_flexrf_900_rx(usrp, which)
+{
+ d_common->R_DIV(16);
+}
+
+int db_flexrf_900_rx_mimo_b::_refclk_divisor()
+{
+ return 1;
+}
+
+db_flexrf_400_tx_mimo_a::db_flexrf_400_tx_mimo_a(usrp_basic_sptr usrp, int which)
+ : db_flexrf_400_tx(usrp, which)
+{
+ _enable_refclk(true);
+ d_common->R_DIV(1);
+}
+
+int
+db_flexrf_400_tx_mimo_a::_refclk_divisor()
+{
+ return 16;
+}
+
+db_flexrf_400_rx_mimo_a::db_flexrf_400_rx_mimo_a(usrp_basic_sptr usrp, int which)
+ : db_flexrf_400_rx(usrp, which)
+{
+ _enable_refclk(true);
+ d_common->R_DIV(1);
+}
+
+int
+db_flexrf_400_rx_mimo_a::_refclk_divisor()
+{
+ return 16;
+}
+
+db_flexrf_400_tx_mimo_b::db_flexrf_400_tx_mimo_b(usrp_basic_sptr usrp, int which)
+ : db_flexrf_400_tx(usrp, which)
+{
+ d_common->R_DIV(16);
+}
+
+int
+db_flexrf_400_tx_mimo_b::_refclk_divisor()
+{
+ return 1;
+}
+
+db_flexrf_400_rx_mimo_b::db_flexrf_400_rx_mimo_b(usrp_basic_sptr usrp, int which)
+ : db_flexrf_400_rx(usrp, which)
+{
+ d_common->R_DIV(16);
+}
+
+int
+db_flexrf_400_rx_mimo_b::_refclk_divisor()
+{
+ return 1;
+}
diff --git a/usrp/host/lib/legacy/db_flexrf_mimo.h b/usrp/host/lib/legacy/db_flexrf_mimo.h
new file mode 100644
index 0000000000..aeff53258e
--- /dev/null
+++ b/usrp/host/lib/legacy/db_flexrf_mimo.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <db_flexrf.h>
+
+class db_flexrf_2400_tx_mimo_a : public db_flexrf_2400_tx
+{
+ public:
+ db_flexrf_2400_tx_mimo_a(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_2400_rx_mimo_a : public db_flexrf_2400_rx
+{
+ public:
+ db_flexrf_2400_rx_mimo_a(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_2400_tx_mimo_b : public db_flexrf_2400_tx
+{
+ public:
+ db_flexrf_2400_tx_mimo_b(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_2400_rx_mimo_b : public db_flexrf_2400_rx
+{
+ public:
+ db_flexrf_2400_rx_mimo_b(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+
+class db_flexrf_1800_tx_mimo_a : public db_flexrf_1800_tx
+{
+ public:
+ db_flexrf_1800_tx_mimo_a(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_1800_rx_mimo_a : public db_flexrf_1800_rx
+{
+ public:
+ db_flexrf_1800_rx_mimo_a(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_1800_tx_mimo_b : public db_flexrf_1800_tx
+{
+ public:
+ db_flexrf_1800_tx_mimo_b(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_1800_rx_mimo_b : public db_flexrf_1800_rx
+{
+ public:
+ db_flexrf_1800_rx_mimo_b(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_1200_tx_mimo_a : public db_flexrf_1200_tx
+{
+ public:
+ db_flexrf_1200_tx_mimo_a(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_1200_rx_mimo_a : public db_flexrf_1200_rx
+{
+ public:
+ db_flexrf_1200_rx_mimo_a(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_1200_tx_mimo_b : public db_flexrf_1200_tx
+{
+ public:
+ db_flexrf_1200_tx_mimo_b(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_1200_rx_mimo_b : public db_flexrf_1200_rx
+{
+ public:
+ db_flexrf_1200_rx_mimo_b(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_900_tx_mimo_a : public db_flexrf_900_tx
+{
+ public:
+ db_flexrf_900_tx_mimo_a(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_900_rx_mimo_a : public db_flexrf_900_rx
+{
+ public:
+ db_flexrf_900_rx_mimo_a(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_900_tx_mimo_b : public db_flexrf_900_tx
+{
+ public:
+ db_flexrf_900_tx_mimo_b(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_900_rx_mimo_b : public db_flexrf_900_rx
+{
+ public:
+ db_flexrf_900_rx_mimo_b(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_400_tx_mimo_a : public db_flexrf_400_tx
+{
+ public:
+ db_flexrf_400_tx_mimo_a(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_400_rx_mimo_a : public db_flexrf_400_rx
+{
+ public:
+ db_flexrf_400_rx_mimo_a(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_400_tx_mimo_b : public db_flexrf_400_tx
+{
+ public:
+ db_flexrf_400_tx_mimo_b(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
+
+class db_flexrf_400_rx_mimo_b : public db_flexrf_400_rx
+{
+ public:
+ db_flexrf_400_rx_mimo_b(usrp_basic_sptr usrp, int which);
+ int _refclk_divisor();
+};
diff --git a/usrp/host/lib/legacy/db_tv_rx.cc b/usrp/host/lib/legacy/db_tv_rx.cc
new file mode 100644
index 0000000000..803ebf86d4
--- /dev/null
+++ b/usrp/host/lib/legacy/db_tv_rx.cc
@@ -0,0 +1,274 @@
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 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.
+
+#include <db_tv_rx.h>
+#include <db_base_impl.h>
+
+/*****************************************************************************/
+
+int
+control_byte_1(bool fast_tuning_p, int reference_divisor)
+{
+ int c = 0x88;
+ if(fast_tuning_p) {
+ c |= 0x40;
+ }
+
+ if(reference_divisor == 512) {
+ c |= 0x3 << 1;
+ }
+ else if(reference_divisor == 640) {
+ c |= 0x0 << 1;
+ }
+ else if(reference_divisor == 1024) {
+ c |= 0x1 << 1;
+ }
+ else {
+ assert(0);
+ }
+
+ return c;
+}
+
+int
+control_byte_2(double target_freq, bool shutdown_tx_PGA)
+{
+ int c;
+ if(target_freq < 158e6) { // VHF low
+ c = 0xa0;
+ }
+ else if(target_freq < 464e6) { // VHF high
+ c = 0x90;
+ }
+ else { // UHF
+ c = 0x30;
+ }
+
+ if(shutdown_tx_PGA) {
+ c |= 0x08;
+ }
+
+ return c;
+}
+
+
+/*****************************************************************************/
+
+
+db_tv_rx::db_tv_rx(usrp_basic_sptr usrp, int which,
+ double first_IF, double second_IF)
+ : db_base(usrp, which)
+{
+ // Handler for Tv Rx daughterboards.
+ //
+ // @param usrp: instance of usrp.source_c
+ // @param which: which side: 0, 1 corresponding to RX_A or RX_B respectively
+
+ if(which == 0) {
+ d_i2c_addr = 0x60;
+ }
+ else {
+ d_i2c_addr = 0x61;
+ }
+
+ d_first_IF = first_IF;
+ d_second_IF = second_IF;
+ d_reference_divisor = 640;
+ d_fast_tuning = false;
+ d_inverted = false; // FIXME get rid of this
+
+ set_gain((gain_min() + gain_max()) / 2.0); // initialize gain
+
+ bypass_adc_buffers(false);
+}
+
+db_tv_rx::~db_tv_rx()
+{
+}
+
+// Gain setting
+void
+db_tv_rx::_set_rfagc(float gain)
+{
+ float voltage;
+
+ assert(gain <= 60 && gain >= 0);
+ // FIXME this has a 0.5V step between gain = 60 and gain = 59.
+ // Why are there two cases instead of a single linear case?
+ if(gain == 60) {
+ voltage = 4;
+ }
+ else {
+ voltage = gain/60.0 * 2.25 + 1.25;
+ }
+ int dacword = int(4096*voltage/1.22/3.3); // 1.22 = opamp gain
+
+ assert(dacword>=0 && dacword<4096);
+ usrp()->write_aux_dac(d_which, 1, dacword);
+}
+
+void
+db_tv_rx::_set_ifagc(float gain)
+{
+ float voltage;
+
+ assert(gain <= 35 && gain >= 0);
+ voltage = gain/35.0 * 2.1 + 1.4;
+ int dacword = int(4096*voltage/1.22/3.3); // 1.22 = opamp gain
+
+ assert(dacword>=0 && dacword<4096);
+ usrp()->write_aux_dac(d_which, 0, dacword);
+}
+
+void
+db_tv_rx::_set_pga(float pga_gain)
+{
+ assert(pga_gain >=0 && pga_gain <=20);
+ if(d_which == 0) {
+ usrp()->set_pga(0, pga_gain);
+ }
+ else {
+ usrp()->set_pga (2, pga_gain);
+ }
+}
+
+double
+db_tv_rx::freq_min()
+{
+ return 50e6;
+}
+
+double
+db_tv_rx::freq_max()
+{
+ return 860e6;
+}
+
+struct freq_result_t
+db_tv_rx::set_freq(double target_freq)
+{
+ // Set the frequency.
+ //
+ // @param freq: target RF frequency in Hz
+ // @type freq: double
+ //
+ // @returns (ok, actual_baseband_freq) where:
+ // ok is True or False and indicates success or failure,
+ // actual_baseband_freq is RF frequency that corresponds to DC in the IF.
+
+ freq_result_t args = {false, 0};
+
+ double fmin = freq_min();
+ double fmax = freq_max();
+ if((target_freq < fmin) || (target_freq > fmax)) {
+ return args;
+ }
+
+ double target_lo_freq = target_freq + d_first_IF; // High side mixing
+ double f_ref = 4.0e6 / (double)(d_reference_divisor); // frequency steps
+
+ int divisor = int((target_lo_freq + (f_ref * 4)) / (f_ref * 8));
+ double actual_lo_freq = (f_ref * 8 * divisor);
+ double actual_freq = actual_lo_freq - d_first_IF;
+
+ if((divisor & ~0x7fff) != 0) { // must be 15-bits or less
+ return args;
+ }
+
+ // build i2c command string
+ std::vector<int> buf(4);
+ buf[0] = (divisor >> 8) & 0xff; // DB1
+ buf[1] = divisor & 0xff; // DB2
+ buf[2] = control_byte_1(d_fast_tuning, d_reference_divisor);
+ buf[3] = control_byte_2(actual_freq, true);
+
+ args.ok = usrp()->write_i2c(d_i2c_addr, int_seq_to_str (buf));
+ args.baseband_freq = actual_freq - d_second_IF;
+ return args;
+}
+
+float
+db_tv_rx::gain_min()
+{
+ return 0;
+}
+
+float
+db_tv_rx::gain_max()
+{
+ return 115;
+}
+
+float
+db_tv_rx::gain_db_per_step()
+{
+ return 1;
+}
+
+bool
+db_tv_rx::set_gain(float gain)
+{
+ // Set the gain.
+ //
+ // @param gain: gain in decibels
+ // @returns True/False
+
+ float rfgain, ifgain, pgagain;
+
+ assert(gain>=0 && gain<=115);
+ if(gain>60) {
+ rfgain = 60;
+ gain = gain - 60;
+ }
+ else {
+ rfgain = gain;
+ gain = 0;
+ }
+
+ if(gain > 35) {
+ ifgain = 35;
+ gain = gain - 35;
+ }
+ else {
+ ifgain = gain;
+ gain = 0;
+ }
+
+ pgagain = gain;
+ _set_rfagc(rfgain);
+ _set_ifagc(ifgain);
+ _set_pga(pgagain);
+
+ return true;
+}
+
+bool
+db_tv_rx::is_quadrature()
+{
+ // Return True if this board requires both I & Q analog channels.
+ return false;
+}
+
+bool
+db_tv_rx::spectrum_inverted()
+{
+ // The 43.75 MHz version is inverted
+ return d_inverted;
+}
diff --git a/usrp/host/lib/legacy/db_tv_rx.h b/usrp/host/lib/legacy/db_tv_rx.h
new file mode 100644
index 0000000000..ed91626370
--- /dev/null
+++ b/usrp/host/lib/legacy/db_tv_rx.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 3, or (at your option)
+// any later version.
+//
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+
+#ifndef DB_TV_RX_H
+#define DB_TV_RX_H
+
+#include <db_base.h>
+
+class db_tv_rx : public db_base
+{
+private:
+ void _set_rfagc(float gain);
+ void _set_ifagc(float gain);
+ void _set_pga(float pga_gain);
+
+ int d_i2c_addr;
+ double d_first_IF, d_second_IF;
+ int d_reference_divisor;
+ bool d_fast_tuning;
+ bool d_inverted;
+
+public:
+ db_tv_rx(usrp_basic_sptr usrp, int which,
+ double first_IF, double second_IF);
+ ~db_tv_rx();
+
+ float gain_min();
+ float gain_max();
+ float gain_db_per_step();
+ double freq_min();
+ double freq_max();
+ struct freq_result_t set_freq(double target_freq);
+ bool set_gain(float gain);
+ bool is_quadrature();
+ bool spectrum_inverted();
+};
+
+#endif
diff --git a/usrp/host/lib/legacy/db_util.cc b/usrp/host/lib/legacy/db_util.cc
new file mode 100644
index 0000000000..4b46383bba
--- /dev/null
+++ b/usrp/host/lib/legacy/db_util.cc
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <db_util.h>
+#include <sstream>
+
+std::string
+int_seq_to_str(std::vector<int> &seq)
+{
+ //convert a sequence of integers into a string
+
+ std::stringstream str;
+ std::vector<int>::iterator i;
+ for(i = seq.begin(); i != seq.end(); i++) {
+ str << char((unsigned int)*i);
+ }
+ return str.str();
+}
+
+std::vector<int>
+str_to_int_seq(std::string str)
+{
+ //convert a string to a list of integers
+ std::vector<int> seq;
+ std::vector<int>::iterator sitr;
+ std::string::iterator i;
+ for(i=str.begin(); i != str.end(); i++) {
+ int a = (int)(*i);
+ seq.push_back(a);
+ }
+ return seq;
+}
+
diff --git a/usrp/host/lib/legacy/db_util.h b/usrp/host/lib/legacy/db_util.h
new file mode 100644
index 0000000000..e07abb6080
--- /dev/null
+++ b/usrp/host/lib/legacy/db_util.h
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_DB_UTIL_H
+#define INCLUDED_DB_UTIL_H
+
+#include <string>
+#include <vector>
+
+std::string int_seq_to_str(std::vector<int> &seq);
+std::vector<int> str_to_int_seq(std::string str);
+
+#endif /* INCLUDED_DB_UTIL_H */
diff --git a/usrp/host/lib/legacy/db_wbx.cc b/usrp/host/lib/legacy/db_wbx.cc
new file mode 100644
index 0000000000..9f1d72939a
--- /dev/null
+++ b/usrp/host/lib/legacy/db_wbx.cc
@@ -0,0 +1,953 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 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.
+
+#include <db_wbx.h>
+#include <fpga_regs_standard.h>
+#include <fpga_regs_common.h>
+#include <usrp_prims.h>
+#include <usrp_spi_defs.h>
+#include <stdexcept>
+#include <cmath>
+
+// d'board i/o pin defs
+
+// TX IO Pins
+#define TX_POWER (1 << 0) // TX Side Power
+#define RX_TXN (1 << 1) // T/R antenna switch for TX/RX port
+#define TX_ENB_MIX (1 << 2) // Enable IQ mixer
+#define TX_ENB_VGA (1 << 3)
+
+// RX IO Pins
+#define RX2_RX1N (1 << 0) // antenna switch between RX2 and TX/RX port
+#define RXENABLE (1 << 1) // enables mixer
+#define PLL_LOCK_DETECT (1 << 2) // Muxout pin from PLL -- MUST BE INPUT
+#define MReset (1 << 3) // NB6L239 Master Reset, asserted low
+#define SELA0 (1 << 4) // NB6L239 SelA0
+#define SELA1 (1 << 5) // NB6L239 SelA1
+#define SELB0 (1 << 6) // NB6L239 SelB0
+#define SELB1 (1 << 7) // NB6L239 SelB1
+#define PLL_ENABLE (1 << 8) // CE Pin on PLL
+#define AUX_SCLK (1 << 9) // ALT SPI SCLK
+#define AUX_SDO (1 << 10) // ALT SPI SDO
+#define AUX_SEN (1 << 11) // ALT SPI SEN
+
+
+wbx_base::wbx_base(usrp_basic_sptr usrp, int which)
+ : db_base(usrp, which)
+{
+ /*
+ * @param usrp: instance of usrp.source_c
+ * @param which: which side: 0 or 1 corresponding to side A or B respectively
+ * @type which: int
+ */
+
+ d_first = true;
+ d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0;
+
+ // FIXME -- the write reg functions don't work with 0xffff for masks
+ _rx_write_oe(int(PLL_ENABLE|MReset|SELA0|SELA1|SELB0|SELB1|RX2_RX1N|RXENABLE), 0x7fff);
+ _rx_write_io((PLL_ENABLE|MReset|0|RXENABLE), (PLL_ENABLE|MReset|RX2_RX1N|RXENABLE));
+
+ _tx_write_oe((TX_POWER|RX_TXN|TX_ENB_MIX|TX_ENB_VGA), 0x7fff);
+ _tx_write_io((0|RX_TXN), (TX_POWER|RX_TXN|TX_ENB_MIX|TX_ENB_VGA)); // TX off, TR switch set to RX
+
+ if(d_which == 0) {
+ d_spi_enable = SPI_ENABLE_RX_A;
+ }
+ else {
+ d_spi_enable = SPI_ENABLE_RX_B;
+ }
+
+ set_auto_tr(false);
+
+}
+
+wbx_base::~wbx_base()
+{
+ shutdown();
+}
+
+
+void
+wbx_base::shutdown()
+{
+ if (!d_is_shutdown){
+ d_is_shutdown = true;
+ // do whatever there is to do to shutdown
+
+ write_io(d_which, d_power_off, POWER_UP); // turn off power to board
+ _write_oe(d_which, 0, 0xffff); // turn off all outputs
+ set_auto_tr(false); // disable auto transmit
+ }
+}
+
+bool
+wbx_base::_lock_detect()
+{
+ /*
+ * @returns: the value of the VCO/PLL lock detect bit.
+ * @rtype: 0 or 1
+ */
+
+ if(_rx_read_io() & PLL_LOCK_DETECT) {
+ return true;
+ }
+ else { // Give it a second chance
+ if(_rx_read_io() & PLL_LOCK_DETECT) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+}
+
+bool
+wbx_base::_tx_write_oe(int value, int mask)
+{
+ int reg = (d_which == 0 ? FR_OE_0 : FR_OE_2);
+ return d_usrp->_write_fpga_reg(reg, ((mask & 0xffff) << 16) | (value & 0xffff));
+}
+
+bool
+wbx_base::_rx_write_oe(int value, int mask)
+{
+ int reg = (d_which == 0 ? FR_OE_1 : FR_OE_3);
+ return d_usrp->_write_fpga_reg(reg, ((mask & 0xffff) << 16) | (value & 0xffff));
+}
+
+bool
+wbx_base::_tx_write_io(int value, int mask)
+{
+ int reg = (d_which == 0 ? FR_IO_0 : FR_IO_2);
+ return d_usrp->_write_fpga_reg(reg, ((mask & 0xffff) << 16) | (value & 0xffff));
+}
+
+bool
+wbx_base::_rx_write_io(int value, int mask)
+{
+ int reg = (d_which == 0 ? FR_IO_1 : FR_IO_3);
+ return d_usrp->_write_fpga_reg(reg, ((mask & 0xffff) << 16) | (value & 0xffff));
+}
+
+bool
+wbx_base::_rx_read_io()
+{
+ int reg = (d_which == 0 ? FR_RB_IO_RX_A_IO_TX_A : FR_RB_IO_RX_B_IO_TX_B);
+ int t = d_usrp->_read_fpga_reg(reg);
+ return (t >> 16) & 0xffff;
+}
+
+bool
+wbx_base::_tx_read_io()
+{
+ int reg = (d_which == 0 ? FR_RB_IO_RX_A_IO_TX_A : FR_RB_IO_RX_B_IO_TX_B);
+ int t = d_usrp->_read_fpga_reg(reg);
+ return (t & 0xffff);
+}
+
+bool
+wbx_base::_compute_regs(double freq)
+{
+ /*
+ * Determine values of registers, along with actual freq.
+ *
+ * @param freq: target frequency in Hz
+ * @type freq: double
+ * @returns: (R, N, func, init, actual_freq)
+ * @rtype: tuple(int, int, int, int, double)
+ *
+ * Override this in derived classes.
+ */
+ throw std::runtime_error("_compute_regs called from base class\n");
+}
+
+double
+wbx_base::_refclk_freq()
+{
+ return (double)(d_usrp->fpga_master_clock_freq())/_refclk_divisor();
+}
+
+int
+wbx_base::_refclk_divisor()
+{
+ /*
+ * Return value to stick in REFCLK_DIVISOR register
+ */
+ return 1;
+}
+
+struct freq_result_t
+wbx_base::set_freq(double freq)
+{
+ /*
+ * @returns (ok, actual_baseband_freq) where:
+ * ok is True or False and indicates success or failure,
+ * actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+ */
+ throw std::runtime_error("set_freq called from base class\n");
+}
+
+float
+wbx_base::gain_min()
+{
+ throw std::runtime_error("gain_min called from base class\n");
+}
+
+float
+wbx_base::gain_max()
+{
+ throw std::runtime_error("gain_max called from base class\n");
+}
+
+float
+wbx_base::gain_db_per_step()
+{
+ throw std::runtime_error("gain_db_per_step called from base class\n");
+}
+
+bool
+wbx_base::set_gain(float gain)
+{
+ /*
+ * Set the gain.
+ *
+ * @param gain: gain in decibels
+ * @returns True/False
+ */
+ throw std::runtime_error("set_gain called from base class\n");
+}
+
+bool
+wbx_base::_set_pga(float pga_gain)
+{
+ bool ok;
+ if(d_which == 0) {
+ ok = d_usrp->set_pga(0, pga_gain);
+ ok |= d_usrp->set_pga(1, pga_gain);
+ }
+ else {
+ ok = d_usrp->set_pga(2, pga_gain);
+ ok |= d_usrp->set_pga(3, pga_gain);
+ }
+ return ok;
+}
+
+bool
+wbx_base::is_quadrature()
+{
+ /*
+ * Return True if this board requires both I & Q analog channels.
+ *
+ * This bit of info is useful when setting up the USRP Rx mux register.
+ */
+ return true;
+}
+
+
+/****************************************************************************/
+
+
+wbx_base_tx::wbx_base_tx(usrp_basic_sptr usrp, int which)
+ : wbx_base(usrp, which)
+{
+ /*
+ * @param usrp: instance of usrp.sink_c
+ * @param which: 0 or 1 corresponding to side TX_A or TX_B respectively.
+ */
+
+ // power up the transmit side, NO -- but set antenna to receive
+ d_usrp->write_io(d_which, (TX_POWER), (TX_POWER|RX_TXN));
+ d_lo_offset = 0e6;
+
+ // Gain is not set by the PGA, but the PGA must be set at max gain in the TX
+ _set_pga(d_usrp->pga_max());
+}
+
+wbx_base_tx::~wbx_base_tx()
+{
+ // Power down and leave the T/R switch in the R position
+ d_usrp->write_io(d_which, (RX_TXN), (TX_POWER|RX_TXN|TX_ENB_MIX|TX_ENB_VGA));
+}
+
+void
+wbx_base_tx::set_auto_tr(bool on)
+{
+ if(on) {
+ set_atr_mask (RX_TXN);
+ set_atr_txval(0);
+ set_atr_rxval(RX_TXN);
+ }
+ else {
+ set_atr_mask (0);
+ set_atr_txval(0);
+ set_atr_rxval(0);
+ }
+}
+
+void
+wbx_base_tx::set_enable(bool on)
+{
+ /*
+ * Enable transmitter if on is True
+ */
+
+ int mask = RX_TXN|TX_ENB_MIX|TX_ENB_VGA;
+ //printf("HERE!!!!\n");
+ if(on) {
+ d_usrp->write_io(d_which, TX_ENB_MIX|TX_ENB_VGA, mask);
+ }
+ else {
+ d_usrp->write_io(d_which, RX_TXN, mask);
+ }
+}
+
+void
+wbx_base_tx::set_lo_offset(double offset)
+{
+ /*
+ * Set amount by which LO is offset from requested tuning frequency.
+ *
+ * @param offset: offset in Hz
+ */
+
+ d_lo_offset = offset;
+}
+
+double
+wbx_base_tx::lo_offset()
+{
+ /*
+ * Get amount by which LO is offset from requested tuning frequency.
+ *
+ * @returns Offset in Hz
+ */
+
+ return d_lo_offset;
+}
+
+
+/****************************************************************************/
+
+
+wbx_base_rx::wbx_base_rx(usrp_basic_sptr usrp, int which)
+ : wbx_base(usrp, which)
+{
+ /*
+ * @param usrp: instance of usrp.source_c
+ * @param which: 0 or 1 corresponding to side RX_A or RX_B respectively.
+ */
+
+ // set up for RX on TX/RX port
+ select_rx_antenna("TX/RX");
+
+ bypass_adc_buffers(true);
+
+ d_lo_offset = 0.0;
+}
+
+wbx_base_rx::~wbx_base_rx()
+{
+ // Power down
+ d_usrp->write_io(d_which, 0, (RXENABLE));
+}
+
+void
+wbx_base_rx::set_auto_tr(bool on)
+{
+ if(on) {
+ // FIXME: where does ENABLE come from?
+ //set_atr_mask (ENABLE);
+ set_atr_txval( 0);
+ //set_atr_rxval(ENABLE);
+ }
+ else {
+ set_atr_mask (0);
+ set_atr_txval(0);
+ set_atr_rxval(0);
+ }
+}
+
+void
+wbx_base_rx::select_rx_antenna(int which_antenna)
+{
+ /*
+ * Specify which antenna port to use for reception.
+ * @param which_antenna: either 'TX/RX' or 'RX2'
+ */
+
+ if(which_antenna == 0) {
+ d_usrp->write_io(d_which, 0, RX2_RX1N);
+ }
+ else if(which_antenna == 1) {
+ d_usrp->write_io(d_which, RX2_RX1N, RX2_RX1N);
+ }
+ else {
+ throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
+ }
+}
+
+void
+wbx_base_rx::select_rx_antenna(const std::string &which_antenna)
+{
+ if(which_antenna == "TX/RX") {
+ select_rx_antenna(0);
+ }
+ else if(which_antenna == "RX2") {
+ select_rx_antenna(1);
+ }
+ else {
+ throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
+ }
+}
+
+bool
+wbx_base_rx::set_gain(float gain)
+{
+ /*
+ * Set the gain.
+ *
+ * @param gain: gain in decibels
+ * @returns True/False
+ */
+
+ float pga_gain, agc_gain;
+ float maxgain = gain_max() - d_usrp->pga_max();
+ float mingain = gain_min();
+ if(gain > maxgain) {
+ pga_gain = gain-maxgain;
+ assert(pga_gain <= d_usrp->pga_max());
+ agc_gain = maxgain;
+ }
+ else {
+ pga_gain = 0;
+ agc_gain = gain;
+ }
+
+ float V_maxgain = .2;
+ float V_mingain = 1.2;
+ float V_fullscale = 3.3;
+ float dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale;
+
+ assert(dac_value>=0 && dac_value<4096);
+
+ return d_usrp->write_aux_dac(d_which, 0, (int)(dac_value)) && _set_pga((int)(pga_gain));
+}
+
+void
+wbx_base_rx::set_lo_offset(double offset)
+{
+ /*
+ * Set amount by which LO is offset from requested tuning frequency.
+ *
+ * @param offset: offset in Hz
+ */
+ d_lo_offset = offset;
+}
+
+double
+wbx_base_rx::lo_offset()
+{
+ /*
+ * Get amount by which LO is offset from requested tuning frequency.
+ *
+ * @returns Offset in Hz
+ */
+ return d_lo_offset;
+}
+
+bool
+wbx_base_rx::i_and_q_swapped()
+{
+ /*
+ * Return True if this is a quadrature device and ADC 0 is Q.
+ */
+ return false;
+}
+
+
+/****************************************************************************/
+
+_ADF410X_common::_ADF410X_common()
+{
+ // R-Register Common Values
+ d_R_RSV = 0; // bits 23,22,21
+ d_LDP = 1; // bit 20 Lock detect in 5 cycles
+ d_TEST = 0; // bit 19,18 Normal
+ d_ABP = 0; // bit 17,16 2.9ns
+
+ // N-Register Common Values
+ d_N_RSV = 0; // 23,22
+ d_CP_GAIN = 0; // 21
+
+ // Function Register Common Values
+ d_P = 0; // bits 23,22 0 = 8/9, 1 = 16/17, 2 = 32/33, 3 = 64/65
+ d_PD2 = 0; // bit 21 Normal operation
+ d_CP2 = 4; // bits 20,19,18 CP Gain = 5mA
+ d_CP1 = 4; // bits 17,16,15 CP Gain = 5mA
+ d_TC = 0; // bits 14-11 PFD Timeout
+ d_FL = 0; // bit 10,9 Fastlock Disabled
+ d_CP3S = 0; // bit 8 CP Enabled
+ d_PDP = 0; // bit 7 Phase detector polarity, Positive=1
+ d_MUXOUT = 1; // bits 6:4 Digital Lock Detect
+ d_PD1 = 0; // bit 3 Normal operation
+ d_CR = 0; // bit 2 Normal operation
+}
+
+_ADF410X_common::~_ADF410X_common()
+{
+}
+
+bool
+_ADF410X_common::_compute_regs(double freq, int &retR, int &retcontrol,
+ int &retN, double &retfreq)
+{
+ /*
+ * Determine values of R, control, and N registers, along with actual freq.
+ *
+ * @param freq: target frequency in Hz
+ * @type freq: double
+ * @returns: (R, N, control, actual_freq)
+ * @rtype: tuple(int, int, int, double)
+ */
+
+ // Band-specific N-Register Values
+ double phdet_freq = _refclk_freq()/d_R_DIV;
+ printf("phdet_freq = %f\n", phdet_freq);
+
+ double desired_n = round(freq*d_freq_mult/phdet_freq);
+ printf("desired_n %f\n", desired_n);
+
+ double actual_freq = desired_n * phdet_freq;
+ printf("actual freq %f\n", actual_freq);
+
+ double B = floor(desired_n/_prescaler());
+ double A = desired_n - _prescaler()*B;
+ printf("A %f B %f\n", A, B);
+
+ d_B_DIV = int(B); // bits 20:8;
+ d_A_DIV = int(A); // bit 6:2;
+
+ if(d_B_DIV < d_A_DIV) {
+ retR = 0;
+ retN = 0;
+ retcontrol = 0;
+ retfreq = 0;
+ return false;
+ }
+
+ retR = (d_R_RSV<<21) | (d_LDP<<20) | (d_TEST<<18) |
+ (d_ABP<<16) | (d_R_DIV<<2);
+
+ retN = (d_N_RSV<<22) | (d_CP_GAIN<<21) | (d_B_DIV<<8) | (d_A_DIV<<2);
+
+ retcontrol = (d_P<<22) | (d_PD2<<21) | (d_CP2<<18) | (d_CP1<<15) |
+ (d_TC<<11) | (d_FL<<9) | (d_CP3S<<8) | (d_PDP<<7) |
+ (d_MUXOUT<<4) | (d_PD1<<3) | (d_CR<<2);
+
+ retfreq = actual_freq/d_freq_mult;
+
+ return true;
+}
+
+void
+_ADF410X_common::_write_all(int R, int N, int control)
+{
+ /*
+ * Write all PLL registers:
+ * R counter latch,
+ * N counter latch,
+ * Function latch,
+ * Initialization latch
+ *
+ * Adds 10ms delay between writing control and N if this is first call.
+ * This is the required power-up sequence.
+ *
+ * @param R: 24-bit R counter latch
+ * @type R: int
+ * @param N: 24-bit N counter latch
+ * @type N: int
+ * @param control: 24-bit control latch
+ * @type control: int
+ */
+ static bool first = true;
+
+ timespec t;
+ t.tv_sec = 0;
+ t.tv_nsec = 10000000;
+
+ _write_R(R);
+ _write_func(control);
+ _write_init(control);
+ if(first) {
+ //time.sleep(0.010);
+ nanosleep(&t, NULL);
+ first = false;
+ }
+ _write_N(N);
+}
+
+void
+_ADF410X_common::_write_R(int R)
+{
+ _write_it((R & ~0x3) | 0);
+}
+
+void
+_ADF410X_common::_write_N(int N)
+{
+ _write_it((N & ~0x3) | 1);
+}
+
+void
+_ADF410X_common::_write_func(int func)
+{
+ _write_it((func & ~0x3) | 2);
+}
+
+void
+_ADF410X_common::_write_init(int init)
+{
+ _write_it((init & ~0x3) | 3);
+}
+
+void
+_ADF410X_common::_write_it(int v)
+{
+ char c[3];
+ c[0] = (char)((v >> 16) & 0xff);
+ c[1] = (char)((v >> 8) & 0xff);
+ c[2] = (char)((v & 0xff));
+ std::string s(c, 3);
+ //d_usrp->_write_spi(0, d_spi_enable, d_spi_format, s);
+ usrp()->_write_spi(0, d_spi_enable, d_spi_format, s);
+}
+
+int
+_ADF410X_common::_prescaler()
+{
+ if(d_P == 0) {
+ return 8;
+ }
+ else if(d_P == 1) {
+ return 16;
+ }
+ else if(d_P == 2) {
+ return 32;
+ }
+ else if(d_P == 3) {
+ return 64;
+ }
+ else {
+ throw std::invalid_argument("Prescaler out of range\n");
+ }
+}
+
+double
+_ADF410X_common::_refclk_freq()
+{
+ throw std::runtime_error("_refclk_freq called from base class.");
+}
+
+bool
+_ADF410X_common::_rx_write_io(int value, int mask)
+{
+ throw std::runtime_error("_rx_write_io called from base class.");
+}
+
+bool
+_ADF410X_common::_lock_detect()
+{
+ throw std::runtime_error("_lock_detect called from base class.");
+}
+
+usrp_basic*
+_ADF410X_common::usrp()
+{
+ throw std::runtime_error("usrp() called from base class.");
+}
+
+
+/****************************************************************************/
+
+
+_lo_common::_lo_common()
+ : _ADF410X_common()
+{
+ // Band-specific R-Register Values
+ d_R_DIV = 4; // bits 15:2
+
+ // Band-specific C-Register values
+ d_P = 0; // bits 23,22 0 = Div by 8/9
+ d_CP2 = 4; // bits 19:17
+ d_CP1 = 4; // 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;
+
+ d_div = 1;
+ d_aux_div = 2;
+ d_main_div = 0;
+}
+
+_lo_common::~_lo_common()
+{
+}
+
+double
+_lo_common::freq_min()
+{
+ return 50e6;
+}
+
+double
+_lo_common::freq_max()
+{
+ return 1000e6;
+}
+
+void
+_lo_common::set_divider(int main_or_aux, int divisor)
+{
+ if(main_or_aux == 0) {
+ if((divisor != 1) || (divisor != 2) || (divisor != 4) || (divisor != 8)) {
+ throw std::invalid_argument("Main Divider Must be 1, 2, 4, or 8\n");
+ }
+ d_main_div = (int)(log10(divisor)/log10(2.0));
+ }
+ else if(main_or_aux == 1) {
+ if((divisor != 2) || (divisor != 4) || (divisor != 8) || (divisor != 16)) {
+ throw std::invalid_argument("Aux Divider Must be 2, 4, 8 or 16\n");
+ }
+ d_main_div = (int)(log10(divisor/2.0)/log10(2.0));
+ }
+ else {
+ throw std::invalid_argument("main_or_aux must be 'main' or 'aux'\n");
+ }
+
+ int vala = d_main_div*SELA0;
+ int valb = d_aux_div*SELB0;
+ int mask = SELA0|SELA1|SELB0|SELB1;
+
+ _rx_write_io((vala | valb), mask);
+}
+
+void
+_lo_common::set_divider(const std::string &main_or_aux, int divisor)
+{
+ if(main_or_aux == "main") {
+ set_divider(0, divisor);
+ }
+ else if(main_or_aux == "aux") {
+ set_divider(1, divisor);
+ }
+ else {
+ throw std::invalid_argument("main_or_aux must be 'main' or 'aux'\n");
+ }
+}
+
+struct freq_result_t
+_lo_common::set_freq(double freq)
+{
+ struct freq_result_t ret;
+
+ if(freq < 20e6 or freq > 1200e6) {
+ throw std::invalid_argument("Requested frequency out of range\n");
+ }
+
+ int div = 1;
+ double lo_freq = freq * 2;
+ while((lo_freq < 1e9) && (div < 8)) {
+ div = div * 2;
+ lo_freq = lo_freq * 2;
+ }
+
+ printf("For RF freq of %f, we set DIV=%d and LO Freq=%f\n", freq, div, lo_freq);
+
+ set_divider("main", div);
+ set_divider("aux", div*2);
+
+ int R, N, control;
+ double actual_freq;
+ _compute_regs(lo_freq, R, N, control, actual_freq);
+
+ printf("R %d N %d control %d actual freq %f\n", R, N, control, actual_freq);
+ if(R==0) {
+ ret.ok = false;
+ ret.baseband_freq = 0.0;
+ return ret;
+ }
+ _write_all(R, N, control);
+
+ ret.ok = _lock_detect();
+ ret.baseband_freq = actual_freq/div/2;
+ return ret;
+}
+
+
+/****************************************************************************/
+
+
+db_wbx_lo_tx::db_wbx_lo_tx(usrp_basic_sptr usrp, int which)
+ : _lo_common(),
+ wbx_base_tx(usrp, which)
+{
+}
+
+db_wbx_lo_tx::~db_wbx_lo_tx()
+{
+}
+
+float
+db_wbx_lo_tx::gain_min()
+{
+ return -56.0;
+}
+
+float
+db_wbx_lo_tx::gain_max()
+{
+ return 0.0;
+}
+
+float
+db_wbx_lo_tx::gain_db_per_step()
+{
+ return 0.1;
+}
+
+bool
+db_wbx_lo_tx::set_gain(float gain)
+{
+ /*
+ * Set the gain.
+ *
+ * @param gain: gain in decibels
+ * @returns True/False
+ */
+
+ float txvga_gain;
+ float maxgain = gain_max();
+ float mingain = gain_min();
+ if(gain > maxgain) {
+ txvga_gain = maxgain;
+ }
+ else if(gain < mingain) {
+ txvga_gain = mingain;
+ }
+ else {
+ txvga_gain = gain;
+ }
+
+ float V_maxgain = 1.4;
+ float V_mingain = 0.1;
+ float V_fullscale = 3.3;
+ float dac_value = ((txvga_gain-mingain)*(V_maxgain-V_mingain)/
+ (maxgain-mingain) + V_mingain)*4096/V_fullscale;
+
+ assert(dac_value>=0 && dac_value<4096);
+ printf("DAC value %f\n", dac_value);
+
+ return d_usrp->write_aux_dac(d_which, 1, (int)(dac_value));
+}
+
+double
+db_wbx_lo_tx::_refclk_freq()
+{
+ return wbx_base::_refclk_freq();
+}
+
+bool
+db_wbx_lo_tx::_rx_write_io(int value, int mask)
+{
+ return wbx_base::_rx_write_io(value, mask);
+}
+
+bool
+db_wbx_lo_tx::_lock_detect()
+{
+ return wbx_base::_lock_detect();
+}
+
+usrp_basic*
+db_wbx_lo_tx::usrp()
+{
+ return d_usrp;
+}
+
+
+/****************************************************************************/
+
+
+db_wbx_lo_rx::db_wbx_lo_rx(usrp_basic_sptr usrp, int which)
+ : _lo_common(),
+ wbx_base_rx(usrp, which)
+{
+}
+
+db_wbx_lo_rx::~db_wbx_lo_rx()
+{
+}
+
+float
+db_wbx_lo_rx::gain_min()
+{
+ return d_usrp->pga_min();
+}
+
+float
+db_wbx_lo_rx::gain_max()
+{
+ return d_usrp->pga_max() + 45;
+}
+
+float
+db_wbx_lo_rx::gain_db_per_step()
+{
+ return 0.05;
+}
+
+double
+db_wbx_lo_rx::_refclk_freq()
+{
+ return wbx_base::_refclk_freq();
+}
+
+bool
+db_wbx_lo_rx::_rx_write_io(int value, int mask)
+{
+ return wbx_base::_rx_write_io(value, mask);
+}
+
+bool
+db_wbx_lo_rx::_lock_detect()
+{
+ return wbx_base::_lock_detect();
+}
+
+usrp_basic*
+db_wbx_lo_rx::usrp()
+{
+ return d_usrp;
+}
diff --git a/usrp/host/lib/legacy/db_wbx.h b/usrp/host/lib/legacy/db_wbx.h
new file mode 100644
index 0000000000..3202d368c8
--- /dev/null
+++ b/usrp/host/lib/legacy/db_wbx.h
@@ -0,0 +1,221 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 3, or (at your option)
+// any later version.
+//
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+
+#ifndef DB_WBX_H
+#define DB_WBX_H
+
+#include <db_base.h>
+#include <boost/shared_ptr.hpp>
+
+
+/*
+ A few comments about the WBX boards:
+ They are half-duplex. I.e., transmit and receive are mutually exclusive.
+ There is a single LO for both the Tx and Rx sides.
+ The the shared control signals are hung off of the Rx side.
+ The shared io controls are duplexed onto the Rx side pins.
+ The wbx_high d'board always needs to be in 'auto_tr_mode'
+*/
+
+
+class wbx_base : public db_base
+{
+protected:
+ void shutdown();
+
+ /*
+ * Abstract base class for all wbx boards.
+ *
+ * Derive board specific subclasses from db_wbx_base_{tx,rx}
+ */
+
+public:
+ wbx_base(usrp_basic_sptr usrp, int which);
+ ~wbx_base();
+
+ struct freq_result_t set_freq(double freq);
+ float gain_min();
+ float gain_max();
+ float gain_db_per_step();
+ bool set_gain(float gain);
+ bool is_quadrature();
+
+
+protected:
+ virtual bool _lock_detect();
+
+ // FIXME: After testing, replace these with usrp_basic::common_write_io/oe
+ bool _tx_write_oe(int value, int mask);
+ bool _rx_write_oe(int value, int mask);
+ bool _tx_write_io(int value, int mask);
+ bool _rx_write_io(int value, int mask);
+ virtual bool _rx_read_io();
+ bool _tx_read_io();
+ bool _compute_regs(double freq);
+ virtual double _refclk_freq();
+ int _refclk_divisor();
+
+ bool _set_pga(float pga_gain);
+
+ bool d_first;
+ int d_spi_format;
+ int d_spi_enable;
+ double d_lo_offset;
+};
+
+
+/****************************************************************************/
+
+
+class wbx_base_tx : public wbx_base
+{
+public:
+ wbx_base_tx(usrp_basic_sptr usrp, int which);
+ ~wbx_base_tx();
+
+ bool set_auto_tr(bool on);
+ bool set_enable(bool on);
+};
+
+
+/****************************************************************************/
+
+
+class wbx_base_rx : public wbx_base
+{
+public:
+ wbx_base_rx(usrp_basic_sptr usrp, int which);
+ ~wbx_base_rx();
+
+ bool set_auto_tr(bool on);
+ bool select_rx_antenna(int which_antenna);
+ bool select_rx_antenna(const std::string &which_antenna);
+ bool set_gain(float gain);
+ bool i_and_q_swapped();
+};
+
+
+/****************************************************************************/
+
+
+class _ADF410X_common
+{
+public:
+ _ADF410X_common();
+ virtual ~_ADF410X_common();
+
+ bool _compute_regs(double freq, int &retR, int &retcontrol,
+ int &retN, double &retfreq);
+ void _write_all(int R, int N, int control);
+ void _write_R(int R);
+ void _write_N(int N);
+ void _write_func(int func);
+ void _write_init(int init);
+ int _prescaler();
+ virtual void _write_it(int v);
+ virtual double _refclk_freq();
+ virtual bool _rx_write_io(int value, int mask);
+ virtual bool _lock_detect();
+
+protected:
+ virtual usrp_basic* usrp();
+
+ int d_R_RSV, d_LDP, d_TEST, d_ABP;
+ int d_N_RSV, d_CP_GAIN;
+ int d_P, d_PD2, d_CP2, d_CP1, d_TC, d_FL;
+ int d_CP3S, d_PDP, d_MUXOUT, d_PD1, d_CR;
+ int d_R_DIV, d_A_DIV, d_B_DIV;
+ int d_freq_mult;
+
+ int d_spi_format;
+ int d_spi_enable;
+};
+
+
+/****************************************************************************/
+
+
+class _lo_common : public _ADF410X_common
+{
+public:
+ _lo_common();
+ ~_lo_common();
+
+ double freq_min();
+ double freq_max();
+
+ void set_divider(int main_or_aux, int divisor);
+ void set_divider(const std::string &main_or_aux, int divisor);
+
+ struct freq_result_t set_freq(double freq);
+
+protected:
+ int d_R_DIV, d_P, d_CP2, d_CP1;
+ int d_DIVSEL, d_DIV2, d_CPGAIN;
+ int d_div, d_aux_div, d_main_div;
+};
+
+
+/****************************************************************************/
+
+
+class db_wbx_lo_tx : public _lo_common, public wbx_base_tx
+{
+public:
+ db_wbx_lo_tx(usrp_basic_sptr usrp, int which);
+ ~db_wbx_lo_tx();
+
+ float gain_min();
+ float gain_max();
+ float gain_db_per_step();
+ bool set_gain(float gain);
+
+ double _refclk_freq();
+ bool _rx_write_io(int value, int mask);
+ bool _lock_detect();
+
+protected:
+ usrp_basic* usrp();
+};
+
+
+/****************************************************************************/
+
+
+class db_wbx_lo_rx : public _lo_common, public wbx_base_rx
+{
+public:
+ db_wbx_lo_rx(usrp_basic_sptr usrp, int which);
+ ~db_wbx_lo_rx();
+
+ float gain_min();
+ float gain_max();
+ float gain_db_per_step();
+
+ double _refclk_freq();
+ bool _rx_write_io(int value, int mask);
+ bool _lock_detect();
+
+protected:
+ usrp_basic* usrp();
+};
+
+#endif
diff --git a/usrp/host/lib/legacy/db_xcvr2450.cc b/usrp/host/lib/legacy/db_xcvr2450.cc
new file mode 100644
index 0000000000..e0c3f91c24
--- /dev/null
+++ b/usrp/host/lib/legacy/db_xcvr2450.cc
@@ -0,0 +1,762 @@
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 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.
+
+#include <db_xcvr2450.h>
+#include <db_base_impl.h>
+#include <cmath>
+
+
+/* ------------------------------------------------------------------------
+ * A few comments about the XCVR2450:
+ *
+ * It is half-duplex. I.e., transmit and receive are mutually exclusive.
+ * There is a single LO for both the Tx and Rx sides.
+ * For our purposes the board is always either receiving or transmitting.
+ *
+ * Each board is uniquely identified by the *USRP hardware* instance and side
+ * This dictionary holds a weak reference to existing board controller so it
+ * can be created or retrieved as needed.
+ */
+
+
+/*****************************************************************************/
+
+
+xcvr2450::xcvr2450(usrp_basic_sptr _usrp, int which)
+ : d_weak_usrp(_usrp), d_which(which)
+{
+ // Handler for Tv Rx daughterboards.
+ //
+ // @param usrp: instance of usrp.source_c
+ // @param which: which side: 0, 1 corresponding to RX_A or RX_B respectively
+
+ // Use MSB with no header
+ d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0;
+
+ if(which == 0) {
+ d_spi_enable = SPI_ENABLE_RX_A;
+ }
+ else {
+ d_spi_enable = SPI_ENABLE_RX_B;
+ }
+
+ // Sane defaults
+ d_mimo = 1; // 0 = OFF, 1 = ON
+ d_int_div = 192; // 128 = min, 255 = max
+ d_frac_div = 0; // 0 = min, 65535 = max
+ d_highband = 0; // 0 = freq <= 5.4e9, 1 = freq > 5.4e9
+ d_five_gig = 0; // 0 = freq <= 3.e9, 1 = freq > 3e9
+ d_cp_current = 0; // 0 = 2mA, 1 = 4mA
+ d_ref_div = 4; // 1 to 7
+ d_rssi_hbw = 0; // 0 = 2 MHz, 1 = 6 MHz
+ d_txlpf_bw = 1; // 1 = 12 MHz, 2 = 18 MHz, 3 = 24 MHz
+ d_rxlpf_bw = 1; // 0 = 7.5 MHz, 1 = 9.5 MHz, 2 = 14 MHz, 3 = 18 MHz
+ d_rxlpf_fine = 2; // 0 = 90%, 1 = 95%, 2 = 100%, 3 = 105%, 4 = 110%
+ d_rxvga_ser = 1; // 0 = RXVGA controlled by B7:1, 1=controlled serially
+ d_rssi_range = 1; // 0 = low range (datasheet typo), 1=high range (0.5V - 2.0V)
+ d_rssi_mode = 1; // 0 = enable follows RXHP, 1 = enabled
+ d_rssi_mux = 0; // 0 = RSSI, 1 = TEMP
+ d_rx_hp_pin = 0; // 0 = Fc set by rx_hpf, 1 = 600 KHz
+ d_rx_hpf = 0; // 0 = 100Hz, 1 = 30KHz
+ d_rx_ant = 0; // 0 = Ant. #1, 1 = Ant. #2
+ d_tx_ant = 0; // 0 = Ant. #1, 1 = Ant. #2
+ d_txvga_ser = 1; // 0 = TXVGA controlled by B6:1, 1=controlled serially
+ d_tx_driver_lin = 2; // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin)
+ d_tx_vga_lin = 2; // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin)
+ d_tx_upconv_lin = 2; // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin)
+ d_tx_bb_gain = 3; // 0=maxgain-5dB, 1=max-3dB, 2=max-1.5dB, 3=max
+ d_pabias_delay = 15; // 0 = 0, 15 = 7uS
+ d_pabias = 0; // 0 = 0 uA, 63 = 315uA
+ d_rx_rf_gain = 0; // 0 = 0dB, 1 = 0dB, 2 = 15dB, 3 = 30dB
+ d_rx_bb_gain = 16; // 0 = min, 31 = max (0 - 62 dB)
+
+ d_txgain = 63; // 0 = min, 63 = max
+
+ // Initialize GPIO and ATR
+ tx_write_io(TX_SAFE_IO, TX_OE_MASK);
+ tx_write_oe(TX_OE_MASK, ~0);
+ tx_set_atr_txval(TX_SAFE_IO);
+ tx_set_atr_rxval(TX_SAFE_IO);
+ tx_set_atr_mask(TX_OE_MASK);
+ rx_write_io(RX_SAFE_IO, RX_OE_MASK);
+ rx_write_oe(RX_OE_MASK, ~0);
+ rx_set_atr_rxval(RX_SAFE_IO);
+ rx_set_atr_txval(RX_SAFE_IO);
+ rx_set_atr_mask(RX_OE_MASK);
+
+ // Initialize chipset
+ // TODO: perform reset sequence to ensure power up defaults
+ set_reg_standby();
+ set_reg_bandselpll();
+ set_reg_cal();
+ set_reg_lpf();
+ set_reg_rxrssi_ctrl();
+ set_reg_txlin_gain();
+ set_reg_pabias();
+ set_reg_rxgain();
+ set_reg_txgain();
+ //FIXME: set_freq(2.45e9);
+}
+
+xcvr2450::~xcvr2450()
+{
+ //printf("xcvr2450::destructor\n");
+ tx_set_atr_txval(TX_SAFE_IO);
+ tx_set_atr_rxval(TX_SAFE_IO);
+ rx_set_atr_rxval(RX_SAFE_IO);
+ rx_set_atr_txval(RX_SAFE_IO);
+}
+
+bool
+xcvr2450::operator==(xcvr2450_key x)
+{
+ if((x.serial_no == usrp()->serial_number()) && (x.which == d_which)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+void
+xcvr2450::set_reg_standby()
+{
+ d_reg_standby = ((d_mimo<<17) |
+ (1<<16) |
+ (1<<6) |
+ (1<<5) |
+ (1<<4) | 2);
+ send_reg(d_reg_standby);
+}
+
+void
+xcvr2450::set_reg_int_divider()
+{
+ d_reg_int_divider = (((d_frac_div & 0x03)<<16) |
+ (d_int_div<<4) | 3);
+ send_reg(d_reg_int_divider);
+}
+
+void
+xcvr2450::set_reg_frac_divider()
+{
+ d_reg_frac_divider = ((d_frac_div & 0xfffc)<<2) | 4;
+ send_reg(d_reg_frac_divider);
+}
+
+void
+xcvr2450::set_reg_bandselpll()
+{
+ d_reg_bandselpll = ((d_mimo<<17) |
+ (1<<16) |
+ (1<<15) |
+ (1<<11) |
+ (d_highband<<10) |
+ (d_cp_current<<9) |
+ (d_ref_div<<5) |
+ (d_five_gig<<4) | 5);
+ send_reg(d_reg_bandselpll);
+}
+
+void
+xcvr2450::set_reg_cal()
+{
+ // FIXME do calibration
+ d_reg_cal = (1<<14)|6;
+ send_reg(d_reg_cal);
+}
+
+void
+xcvr2450::set_reg_lpf()
+{
+ d_reg_lpf = (
+ (d_rssi_hbw<<15) |
+ (d_txlpf_bw<<10) |
+ (d_rxlpf_bw<<9) |
+ (d_rxlpf_fine<<4) | 7);
+ send_reg(d_reg_lpf);
+}
+
+void
+xcvr2450::set_reg_rxrssi_ctrl()
+{
+ d_reg_rxrssi_ctrl = ((d_rxvga_ser<<16) |
+ (d_rssi_range<<15) |
+ (d_rssi_mode<<14) |
+ (d_rssi_mux<<12) |
+ (1<<9) |
+ (d_rx_hpf<<6) |
+ (1<<4) | 8);
+ send_reg(d_reg_rxrssi_ctrl);
+}
+
+void
+xcvr2450::set_reg_txlin_gain()
+{
+ d_reg_txlin_gain = ((d_txvga_ser<<14) |
+ (d_tx_driver_lin<<12) |
+ (d_tx_vga_lin<<10) |
+ (d_tx_upconv_lin<<6) |
+ (d_tx_bb_gain<<4) | 9);
+ send_reg(d_reg_txlin_gain);
+}
+
+void
+xcvr2450::set_reg_pabias()
+{
+ d_reg_pabias = (
+ (d_pabias_delay<<10) |
+ (d_pabias<<4) | 10);
+ send_reg(d_reg_pabias);
+}
+
+void
+xcvr2450::set_reg_rxgain()
+{
+ d_reg_rxgain = (
+ (d_rx_rf_gain<<9) |
+ (d_rx_bb_gain<<4) | 11);
+ send_reg(d_reg_rxgain);
+}
+
+void
+xcvr2450::set_reg_txgain()
+{
+ d_reg_txgain = (d_txgain<<4) | 12;
+ send_reg(d_reg_txgain);
+}
+
+void
+xcvr2450::send_reg(int v)
+{
+ // Send 24 bits, it keeps last 18 clocked in
+ char c[3];
+ c[0] = (char)((v >> 16) & 0xff);
+ c[1] = (char)((v >> 8) & 0xff);
+ c[2] = (char)((v & 0xff));
+ std::string s(c, 3);
+
+ usrp()->_write_spi(0, d_spi_enable, d_spi_format, s);
+ //printf("xcvr2450: Setting reg %d to %06X\n", (v&15), v);
+}
+
+// --------------------------------------------------------------------
+// These methods control the GPIO bus. Since the board has to access
+// both the io_rx_* and io_tx_* pins, we define our own methods to do so.
+// This bypasses any code in db_base.
+//
+// The board operates in ATR mode, always. Thus, when the board is first
+// initialized, it is in receive mode, until bits show up in the TX FIFO.
+//
+
+// FIXME these should just call the similarly named common_* method on usrp_basic
+
+bool
+xcvr2450::tx_write_oe(int value, int mask)
+{
+ int reg;
+ if(d_which)
+ reg = FR_OE_0;
+ else
+ reg = FR_OE_2;
+ return usrp()->_write_fpga_reg(reg, (mask << 16) | value);
+}
+
+bool
+xcvr2450::tx_write_io(int value, int mask)
+{
+ int reg;
+ if(d_which)
+ reg = FR_IO_0;
+ else
+ reg = FR_IO_2;
+ return usrp()->_write_fpga_reg(reg, (mask << 16) | value);
+}
+
+int
+xcvr2450::tx_read_io()
+{
+ int val;
+ if(d_which)
+ val = FR_RB_IO_RX_A_IO_TX_A;
+ else
+ val = FR_RB_IO_RX_B_IO_TX_B;
+ int t = usrp()->_read_fpga_reg(val);
+ return t & 0xffff;
+}
+
+bool
+xcvr2450::rx_write_oe(int value, int mask)
+{
+ int reg;
+ if(d_which)
+ reg = FR_OE_1;
+ else
+ reg = FR_OE_3;
+ return usrp()->_write_fpga_reg(reg, (mask << 16) | value);
+}
+
+bool
+xcvr2450::rx_write_io(int value, int mask)
+{
+ int reg;
+ if(d_which)
+ reg = FR_IO_1;
+ else
+ reg = FR_IO_3;
+ return usrp()->_write_fpga_reg(reg, (mask << 16) | value);
+}
+
+int
+xcvr2450::rx_read_io()
+{
+ int val;
+ if(d_which)
+ val = FR_RB_IO_RX_A_IO_TX_A;
+ else
+ val = FR_RB_IO_RX_B_IO_TX_B;
+ int t = usrp()->_read_fpga_reg(val);
+ return (t >> 16) & 0xffff;
+}
+
+bool
+xcvr2450::tx_set_atr_mask(int v)
+{
+ int reg;
+ if(d_which)
+ reg = FR_ATR_MASK_0;
+ else
+ reg = FR_ATR_MASK_2;
+ return usrp()->_write_fpga_reg(reg, v);
+}
+
+bool
+xcvr2450::tx_set_atr_txval(int v)
+{
+ int reg;
+ if(d_which)
+ reg = FR_ATR_TXVAL_0;
+ else
+ reg = FR_ATR_TXVAL_2;
+ return usrp()->_write_fpga_reg(reg, v);
+}
+
+bool
+xcvr2450::tx_set_atr_rxval(int v)
+{
+ int reg;
+ if(d_which)
+ reg = FR_ATR_RXVAL_0;
+ else
+ reg = FR_ATR_RXVAL_2;
+ return usrp()->_write_fpga_reg(reg, v);
+}
+
+bool
+xcvr2450::rx_set_atr_mask(int v)
+{
+ int reg;
+ if(d_which)
+ reg = FR_ATR_MASK_1;
+ else
+ reg = FR_ATR_MASK_3;
+ return usrp()->_write_fpga_reg(reg, v);
+}
+
+bool
+xcvr2450::rx_set_atr_txval(int v)
+{
+ int reg;
+ if(d_which)
+ reg = FR_ATR_TXVAL_1;
+ else
+ reg = FR_ATR_TXVAL_3;
+ return usrp()->_write_fpga_reg(reg, v);
+}
+
+bool
+xcvr2450::rx_set_atr_rxval(int v)
+{
+ int reg;
+ if(d_which)
+ reg = FR_ATR_RXVAL_1;
+ else
+ reg = FR_ATR_RXVAL_3;
+ return usrp()->_write_fpga_reg(reg, v);
+}
+
+// ----------------------------------------------------------------
+
+void
+xcvr2450::set_gpio()
+{
+ // We calculate four values:
+ //
+ // io_rx_while_rx: what to drive onto io_rx_* when receiving
+ // io_rx_while_tx: what to drive onto io_rx_* when transmitting
+ // io_tx_while_rx: what to drive onto io_tx_* when receiving
+ // io_tx_while_tx: what to drive onto io_tx_* when transmitting
+ //
+ // B1-B7 is ignored as gain is set serially for now.
+
+ int rx_hp, tx_antsel, rx_antsel, tx_pa_sel;
+ if(d_rx_hp_pin)
+ rx_hp = 0;
+ else
+ rx_hp = RX_HP;
+
+ if(d_tx_ant)
+ tx_antsel = ANTSEL_TX1_RX2;
+ else
+ tx_antsel = ANTSEL_TX2_RX1;
+
+ if(d_rx_ant)
+ rx_antsel = ANTSEL_TX1_RX2;
+ else
+ rx_antsel = ANTSEL_TX2_RX1;
+
+ if(d_five_gig)
+ tx_pa_sel = HB_PA_OFF;
+ else
+ tx_pa_sel = LB_PA_OFF;
+
+ int io_rx_while_rx = EN|rx_hp|RX_EN;
+ int io_rx_while_tx = EN|rx_hp;
+ int io_tx_while_rx = HB_PA_OFF|LB_PA_OFF|rx_antsel|AD9515DIV;
+ int io_tx_while_tx = tx_pa_sel|tx_antsel|TX_EN|AD9515DIV;
+ rx_set_atr_rxval(io_rx_while_rx);
+ rx_set_atr_txval(io_rx_while_tx);
+ tx_set_atr_rxval(io_tx_while_rx);
+ tx_set_atr_txval(io_tx_while_tx);
+
+ //printf("GPIO: RXRX=%04X RXTX=%04X TXRX=%04X TXTX=%04X",
+ // io_rx_while_rx, io_rx_while_tx, io_tx_while_rx, io_tx_while_tx);
+}
+
+
+struct freq_result_t
+xcvr2450::set_freq(double target_freq)
+{
+ struct freq_result_t args = {false, 0};
+
+ double scaler;
+
+ if(target_freq > 3e9) {
+ d_five_gig = 1;
+ d_ref_div = 1;
+ d_ad9515_div = 3;
+ scaler = 4.0/5.0;
+ }
+ else {
+ d_five_gig = 0;
+ d_ref_div = 1;
+ d_ad9515_div = 3;
+ scaler = 4.0/3.0;
+ }
+
+ if(target_freq > 5.27e9) {
+ d_highband = 1;
+ }
+ else {
+ d_highband = 0;
+ }
+
+ double vco_freq = target_freq*scaler;
+ double sys_clk = usrp()->fpga_master_clock_freq(); // Usually 64e6
+ double ref_clk = sys_clk / d_ad9515_div;
+
+ double phdet_freq = ref_clk/d_ref_div;
+ double div = vco_freq/phdet_freq;
+ d_int_div = int(floor(div));
+ d_frac_div = int((div-d_int_div)*65536.0);
+ double actual_freq = phdet_freq*(d_int_div+(d_frac_div/65536.0))/scaler;
+
+ //printf("RF=%f VCO=%f R=%d PHD=%f DIV=%3.5f I=%3d F=%5d ACT=%f",
+ // target_freq, vco_freq, d_ref_div, phdet_freq,
+ // div, d_int_div, d_frac_div, actual_freq);
+
+ set_gpio();
+ set_reg_int_divider();
+ set_reg_frac_divider();
+ set_reg_bandselpll();
+
+ args.ok = lock_detect();
+ args.baseband_freq = actual_freq;
+
+ if(args.ok) {
+ if((target_freq > 5.275e9) && (target_freq <= 5.35e9)) {
+ d_highband = 0;
+ set_reg_bandselpll();
+ args.ok = lock_detect();
+ printf("swap to 0 at %f, ok %d\n", target_freq, args.ok);
+ }
+ if((target_freq >= 5.25e9) && (target_freq <= 5.275e9)) {
+ d_highband = 1;
+ set_reg_bandselpll();
+ args.ok = lock_detect();
+ printf("swap to 1 at %f, ok %d\n", target_freq, args.ok);
+ }
+ if(!args.ok){
+ printf("Fail %f\n", target_freq);
+ }
+ }
+ return args;
+}
+
+bool
+xcvr2450::lock_detect()
+{
+ /*
+ @returns: the value of the VCO/PLL lock detect bit.
+ @rtype: 0 or 1
+ */
+ if(rx_read_io() & LOCKDET) {
+ return true;
+ }
+ else { // Give it a second chance
+ if(rx_read_io() & LOCKDET)
+ return true;
+ else
+ return false;
+ }
+}
+
+bool
+xcvr2450::set_rx_gain(float gain)
+{
+ if(gain < 0.0)
+ gain = 0.0;
+ if(gain > 92.0)
+ gain = 92.0;
+
+ // Split the gain between RF and baseband
+ // This is experimental, not prescribed
+ if(gain < 31.0) {
+ d_rx_rf_gain = 0; // 0 dB RF gain
+ rx_bb_gain = int(gain/2.0);
+ }
+
+ if(gain >= 30.0 and gain < 60.5) {
+ d_rx_rf_gain = 2; // 15 dB RF gain
+ d_rx_bb_gain = int((gain-15.0)/2.0);
+ }
+
+ if(gain >= 60.5) {
+ d_rx_rf_gain = 3; // 30.5 dB RF gain
+ d_rx_bb_gain = int((gain-30.5)/2.0);
+ }
+
+ set_reg_rxgain();
+
+ return true;
+}
+
+bool
+xcvr2450::set_tx_gain(float gain)
+{
+ if(gain < 0.0) {
+ gain = 0.0;
+ }
+ if(gain > 30.0) {
+ gain = 30.0;
+ }
+
+ d_txgain = int((gain/30.0)*63);
+ set_reg_txgain();
+
+ return true;
+}
+
+
+/*****************************************************************************/
+
+
+//_xcvr2450_inst = weakref.WeakValueDictionary()
+std::vector<xcvr2450_sptr> _xcvr2450_inst;
+
+xcvr2450_sptr
+_get_or_make_xcvr2450(usrp_basic_sptr usrp, int which)
+{
+ xcvr2450_sptr inst;
+ xcvr2450_key key = {usrp->serial_number(), which};
+ std::vector<xcvr2450_sptr>::iterator itr; // =
+ //std::find(_xcvr2450_inst.begin(), _xcvr2450_inst.end(), key);
+
+ for(itr = _xcvr2450_inst.begin(); itr != _xcvr2450_inst.end(); itr++) {
+ if(*(*itr) == key) {
+ printf("Using existing xcvr2450 instance\n");
+ inst = *itr;
+ break;
+ }
+ }
+
+ if(itr != _xcvr2450_inst.end()) {
+ printf("Creating new xcvr2450 instance\n");
+ inst = xcvr2450_sptr(new xcvr2450(usrp, which));
+ _xcvr2450_inst.push_back(inst);
+ }
+
+ return inst;
+}
+
+
+/*****************************************************************************/
+
+
+db_xcvr2450_base::db_xcvr2450_base(usrp_basic_sptr usrp, int which)
+ : db_base(usrp, which)
+{
+ /*
+ * Abstract base class for all xcvr2450 boards.
+ *
+ * Derive board specific subclasses from db_xcvr2450_base_{tx,rx}
+ *
+ * @param usrp: instance of usrp.source_c
+ * @param which: which side: 0 or 1 corresponding to side A or B respectively
+ * @type which: int
+ */
+
+ d_xcvr = _get_or_make_xcvr2450(usrp, which);
+}
+
+db_xcvr2450_base::~db_xcvr2450_base()
+{
+}
+
+struct freq_result_t
+db_xcvr2450_base::set_freq(double target_freq)
+{
+ /*
+ * @returns (ok, actual_baseband_freq) where:
+ * ok is True or False and indicates success or failure,
+ * actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+ */
+ return d_xcvr->set_freq(target_freq);
+}
+
+bool
+db_xcvr2450_base::is_quadrature()
+{
+ /*
+ * Return True if this board requires both I & Q analog channels.
+ *
+ * This bit of info is useful when setting up the USRP Rx mux register.
+ */
+ return true;
+}
+
+double
+db_xcvr2450_base::freq_min()
+{
+ return 2.4e9;
+}
+
+double
+db_xcvr2450_base::freq_max()
+{
+ return 6.0e9;
+}
+
+
+/******************************************************************************/
+
+
+db_xcvr2450_tx::db_xcvr2450_tx(usrp_basic_sptr usrp, int which)
+ : db_xcvr2450_base(usrp, which)
+{
+ printf("db_xcvr2450_tx::db_xcvr2450_tx\n");
+}
+
+db_xcvr2450_tx::~db_xcvr2450_tx()
+{
+}
+
+float
+db_xcvr2450_tx::gain_min()
+{
+ return 0;
+}
+
+float
+db_xcvr2450_tx::gain_max()
+{
+ return 30;
+}
+
+float
+db_xcvr2450_tx::gain_db_per_step()
+{
+ return (30.0/63.0);
+}
+
+bool
+db_xcvr2450_tx::set_gain(float gain)
+{
+ return d_xcvr->set_tx_gain(gain);
+}
+
+bool
+db_xcvr2450_tx::i_and_q_swapped()
+{
+ return true;
+}
+
+
+/******************************************************************************/
+
+
+db_xcvr2450_rx::db_xcvr2450_rx(usrp_basic_sptr usrp, int which)
+ : db_xcvr2450_base(usrp, which)
+{
+ /*
+ * @param usrp: instance of usrp.source_c
+ * @param which: 0 or 1 corresponding to side RX_A or RX_B respectively.
+ */
+
+ printf("db_xcvr2450_rx:d_xcvr_2450_rx\n");
+}
+
+db_xcvr2450_rx::~db_xcvr2450_rx()
+{
+}
+
+float
+db_xcvr2450_rx::gain_min()
+{
+ return 0.0;
+}
+
+float
+db_xcvr2450_rx::gain_max()
+{
+ return 92.0;
+}
+
+float
+db_xcvr2450_rx::gain_db_per_step()
+{
+ return 1;
+}
+
+bool
+db_xcvr2450_rx::set_gain(float gain)
+{
+ return d_xcvr->set_rx_gain(gain);
+}
diff --git a/usrp/host/lib/legacy/db_xcvr2450.h b/usrp/host/lib/legacy/db_xcvr2450.h
new file mode 100644
index 0000000000..a67c4302f9
--- /dev/null
+++ b/usrp/host/lib/legacy/db_xcvr2450.h
@@ -0,0 +1,221 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 3, or (at your option)
+// any later version.
+//
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+
+#ifndef DB_XCVR2450_H
+#define DB_XCVR2450_H
+
+#include <db_base.h>
+#include <boost/shared_ptr.hpp>
+
+// TX IO Pins
+#define HB_PA_OFF (1 << 15) // 5GHz PA, 1 = off, 0 = on
+#define LB_PA_OFF (1 << 14) // 2.4GHz PA, 1 = off, 0 = on
+#define ANTSEL_TX1_RX2 (1 << 13) // 1 = Ant 1 to TX, Ant 2 to RX
+#define ANTSEL_TX2_RX1 (1 << 12) // 1 = Ant 2 to TX, Ant 1 to RX
+#define TX_EN (1 << 11) // 1 = TX on, 0 = TX off
+#define AD9515DIV (1 << 4) // 1 = Div by 3, 0 = Div by 2
+
+#define TX_OE_MASK HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|ANTSEL_TX2_RX1|TX_EN|AD9515DIV
+#define TX_SAFE_IO HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|AD9515DIV
+
+// RX IO Pins
+#define LOCKDET (1 << 15) // This is an INPUT!!!
+#define EN (1 << 14)
+#define RX_EN (1 << 13) // 1 = RX on, 0 = RX off
+#define RX_HP (1 << 12)
+#define B1 (1 << 11)
+#define B2 (1 << 10)
+#define B3 (1 << 9)
+#define B4 (1 << 8)
+#define B5 (1 << 7)
+#define B6 (1 << 6)
+#define B7 (1 << 5)
+#define RX_OE_MASK EN|RX_EN|RX_HP|B1|B2|B3|B4|B5|B6|B7
+#define RX_SAFE_IO EN
+
+struct xcvr2450_key {
+ std::string serial_no;
+ int which;
+};
+
+class xcvr2450;
+typedef boost::shared_ptr<xcvr2450> xcvr2450_sptr;
+
+class xcvr2450
+{
+private:
+ boost::weak_ptr<usrp_basic> d_weak_usrp;
+ int d_which;
+
+ int d_spi_format, d_spi_enable;
+
+ int d_mimo, d_int_div, d_frac_div, d_highband, d_five_gig;
+ int d_cp_current, d_ref_div, d_rssi_hbw;
+ int d_txlpf_bw, d_rxlpf_bw, d_rxlpf_fine, d_rxvga_ser;
+ int d_rssi_range, d_rssi_mode, d_rssi_mux;
+ int d_rx_hp_pin, d_rx_hpf, d_rx_ant;
+ int d_tx_ant, d_txvga_ser, d_tx_driver_lin;
+ int d_tx_vga_lin, d_tx_upconv_lin, d_tx_bb_gain;
+ int d_pabias_delay, d_pabias, rx_rf_gain, rx_bb_gain, d_txgain;
+ int d_rx_rf_gain, d_rx_bb_gain;
+
+ int d_reg_standby, d_reg_int_divider, d_reg_frac_divider, d_reg_bandselpll;
+ int d_reg_cal, dsend_reg, d_reg_lpf, d_reg_rxrssi_ctrl, d_reg_txlin_gain;
+ int d_reg_pabias, d_reg_rxgain, d_reg_txgain;
+
+ int d_ad9515_div;
+
+ void _set_rfagc(float gain);
+ void _set_ifagc(float gain);
+ void _set_pga(float pga_gain);
+
+ usrp_basic_sptr usrp(){
+ return usrp_basic_sptr(d_weak_usrp); // throws bad_weak_ptr if d_usrp.use_count() == 0
+ }
+
+public:
+ xcvr2450(usrp_basic_sptr usrp, int which);
+ ~xcvr2450();
+
+ bool operator==(xcvr2450_key x);
+
+ void set_reg_standby();
+
+ // Integer-Divider Ratio (3)
+ void set_reg_int_divider();
+
+ // Fractional-Divider Ratio (4)
+ void set_reg_frac_divider();
+
+ // Band Select and PLL (5)
+ void set_reg_bandselpll();
+
+ // Calibration (6)
+ void set_reg_cal();
+
+ // Lowpass Filter (7)
+ void set_reg_lpf();
+
+ // Rx Control/RSSI (8)
+ void set_reg_rxrssi_ctrl();
+
+ // Tx Linearity/Baseband Gain (9)
+ void set_reg_txlin_gain();
+
+ // PA Bias DAC (10)
+ void set_reg_pabias();
+
+ // Rx Gain (11)
+ void set_reg_rxgain();
+
+ // Tx Gain (12)
+ void set_reg_txgain();
+
+ // Send register write to SPI
+ void send_reg(int v);
+
+ // --------------------------------------------------------------------
+ // These methods control the GPIO bus. Since the board has to access
+ // both the io_rx_* and io_tx_* pins, we define our own methods to do so.
+ // This bypasses any code in db_base.
+ //
+ // The board operates in ATR mode, always. Thus, when the board is first
+ // initialized, it is in receive mode, until bits show up in the TX FIFO.
+ //
+
+ // FIXME these should just call the similarly named common_* method on usrp_basic
+
+ bool tx_write_oe(int value, int mask);
+ bool tx_write_io(int value, int mask);
+ int tx_read_io();
+ bool rx_write_oe(int value, int mask);
+ bool rx_write_io(int value, int mask);
+ int rx_read_io();
+ bool tx_set_atr_mask(int v);
+ bool tx_set_atr_txval(int v);
+ bool tx_set_atr_rxval(int v);
+ bool rx_set_atr_mask(int v);
+ bool rx_set_atr_txval(int v);
+ bool rx_set_atr_rxval(int v);
+
+ void set_gpio();
+ bool lock_detect();
+ bool set_rx_gain(float gain);
+ bool set_tx_gain(float gain);
+
+ struct freq_result_t set_freq(double target_freq);
+};
+
+
+/******************************************************************************/
+
+
+class db_xcvr2450_base: public db_base
+{
+ /*
+ * Abstract base class for all xcvr2450 boards.
+ *
+ * Derive board specific subclasses from db_xcvr2450_base_{tx,rx}
+ */
+public:
+ db_xcvr2450_base(usrp_basic_sptr usrp, int which);
+ ~db_xcvr2450_base();
+ struct freq_result_t set_freq(double target_freq);
+ bool is_quadrature();
+ double freq_min();
+ double freq_max();
+
+protected:
+ xcvr2450_sptr d_xcvr;
+};
+
+
+/******************************************************************************/
+
+
+class db_xcvr2450_tx : public db_xcvr2450_base
+{
+public:
+ db_xcvr2450_tx(usrp_basic_sptr usrp, int which);
+ ~db_xcvr2450_tx();
+
+ float gain_min();
+ float gain_max();
+ float gain_db_per_step();
+ bool set_gain(float gain);
+ bool i_and_q_swapped();
+};
+
+class db_xcvr2450_rx : public db_xcvr2450_base
+{
+public:
+ db_xcvr2450_rx(usrp_basic_sptr usrp, int which);
+ ~db_xcvr2450_rx();
+
+ float gain_min();
+ float gain_max();
+ float gain_db_per_step();
+ bool set_gain(float gain);
+};
+
+
+
+#endif
diff --git a/usrp/host/lib/legacy/usrp_basic.cc b/usrp/host/lib/legacy/usrp_basic.cc
index f673003064..e63a097ac9 100644
--- a/usrp/host/lib/legacy/usrp_basic.cc
+++ b/usrp/host/lib/legacy/usrp_basic.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2003,2004 Free Software Foundation, Inc.
+ * Copyright 2003,2004,2008 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -28,7 +28,9 @@
#include "usrp_prims.h"
#include "usrp_interfaces.h"
#include "fpga_regs_common.h"
+#include "fpga_regs_standard.h"
#include "fusb.h"
+#include "db_boards.h"
#include <usb.h>
#include <stdexcept>
#include <assert.h>
@@ -110,7 +112,7 @@ usrp_basic::usrp_basic (int which_board,
: d_udh (0),
d_usb_data_rate (16000000), // SWAG, see below
d_bytes_per_poll ((int) (POLLING_INTERVAL * d_usb_data_rate)),
- d_verbose (false)
+ d_verbose (false), d_db(2)
{
/*
* SWAG: Scientific Wild Ass Guess.
@@ -154,12 +156,65 @@ usrp_basic::usrp_basic (int which_board,
_write_fpga_reg (FR_DEBUG_EN, 0); // disable debug outputs
}
+void
+usrp_basic::shutdown_daughterboards()
+{
+ // nuke d'boards before we close down USB in ~usrp_basic
+ // shutdown() will do any board shutdown while the USRP can still
+ // be talked to
+ for(size_t i = 0; i < d_db.size(); i++)
+ for(size_t j = 0; j < d_db[i].size(); j++)
+ d_db[i][j]->shutdown();
+}
+
usrp_basic::~usrp_basic ()
{
+ // shutdown_daughterboards(); // call from ~usrp_basic_{tx,rx}
+
+ d_db.resize(0); // forget db shared ptrs
+
if (d_udh)
usb_close (d_udh);
}
+void
+usrp_basic::init_db(usrp_basic_sptr u)
+{
+ if (u.get() != this)
+ throw std::invalid_argument("u is not this");
+
+ d_db[0] = instantiate_dbs(d_dbid[0], u, 0);
+ d_db[1] = instantiate_dbs(d_dbid[1], u, 1);
+}
+
+std::vector<db_base_sptr>
+usrp_basic::db(int which_side)
+{
+ which_side &= 0x1; // clamp it to avoid any reporting any errors
+ return d_db[which_side];
+}
+
+bool
+usrp_basic::is_valid(const usrp_subdev_spec &ss)
+{
+ if (ss.side < 0 || ss.side > 1)
+ return false;
+
+ if (ss.subdev < 0 || ss.subdev >= d_db[ss.side].size())
+ return false;
+
+ return true;
+}
+
+db_base_sptr
+usrp_basic::selected_subdev(const usrp_subdev_spec &ss)
+{
+ if (!is_valid(ss))
+ throw std::invalid_argument("invalid subdev_spec");
+
+ return d_db[ss.side][ss.subdev];
+}
+
bool
usrp_basic::start ()
{
@@ -180,22 +235,22 @@ usrp_basic::set_usb_data_rate (int usb_data_rate)
}
bool
-usrp_basic::write_aux_dac (int slot, int which_dac, int value)
+usrp_basic::_write_aux_dac (int slot, int which_dac, int value)
{
return usrp_write_aux_dac (d_udh, slot, which_dac, value);
}
bool
-usrp_basic::read_aux_adc (int slot, int which_adc, int *value)
+usrp_basic::_read_aux_adc (int slot, int which_adc, int *value)
{
return usrp_read_aux_adc (d_udh, slot, which_adc, value);
}
int
-usrp_basic::read_aux_adc (int slot, int which_adc)
+usrp_basic::_read_aux_adc (int slot, int which_adc)
{
int value;
- if (!read_aux_adc (slot, which_adc, &value))
+ if (!_read_aux_adc (slot, which_adc, &value))
return READ_FAILED;
return value;
@@ -250,22 +305,22 @@ usrp_basic::serial_number()
// ----------------------------------------------------------------
bool
-usrp_basic::set_adc_offset (int which, int offset)
+usrp_basic::set_adc_offset (int which_adc, int offset)
{
- if (which < 0 || which > 3)
+ if (which_adc < 0 || which_adc > 3)
return false;
- return _write_fpga_reg (FR_ADC_OFFSET_0 + which, offset);
+ return _write_fpga_reg (FR_ADC_OFFSET_0 + which_adc, offset);
}
bool
-usrp_basic::set_dac_offset (int which, int offset, int offset_pin)
+usrp_basic::set_dac_offset (int which_dac, int offset, int offset_pin)
{
- if (which < 0 || which > 3)
+ if (which_dac < 0 || which_dac > 3)
return false;
- int which_codec = which >> 1;
- int tx_a = (which & 0x1) == 0;
+ int which_codec = which_dac >> 1;
+ int tx_a = (which_dac & 0x1) == 0;
int lo = ((offset & 0x3) << 6) | (offset_pin & 0x1);
int hi = (offset >> 2);
bool ok;
@@ -282,13 +337,13 @@ usrp_basic::set_dac_offset (int which, int offset, int offset_pin)
}
bool
-usrp_basic::set_adc_buffer_bypass (int which, bool bypass)
+usrp_basic::set_adc_buffer_bypass (int which_adc, bool bypass)
{
- if (which < 0 || which > 3)
+ if (which_adc < 0 || which_adc > 3)
return false;
- int codec = which >> 1;
- int reg = (which & 1) == 0 ? REG_RX_A : REG_RX_B;
+ int codec = which_adc >> 1;
+ int reg = (which_adc & 1) == 0 ? REG_RX_A : REG_RX_B;
unsigned char cur_rx;
unsigned char cur_pwr_dn;
@@ -302,11 +357,11 @@ usrp_basic::set_adc_buffer_bypass (int which, bool bypass)
if (bypass){
cur_rx |= RX_X_BYPASS_INPUT_BUFFER;
- cur_pwr_dn |= ((which & 1) == 0) ? RX_PWR_DN_BUF_A : RX_PWR_DN_BUF_B;
+ cur_pwr_dn |= ((which_adc & 1) == 0) ? RX_PWR_DN_BUF_A : RX_PWR_DN_BUF_B;
}
else {
cur_rx &= ~RX_X_BYPASS_INPUT_BUFFER;
- cur_pwr_dn &= ~(((which & 1) == 0) ? RX_PWR_DN_BUF_A : RX_PWR_DN_BUF_B);
+ cur_pwr_dn &= ~(((which_adc & 1) == 0) ? RX_PWR_DN_BUF_A : RX_PWR_DN_BUF_B);
}
ok &= _write_9862 (codec, reg, cur_rx);
@@ -314,6 +369,13 @@ usrp_basic::set_adc_buffer_bypass (int which, bool bypass)
return ok;
}
+bool
+usrp_basic::set_dc_offset_cl_enable(int bits, int mask)
+{
+ return _write_fpga_reg(FR_DC_OFFSET_CL_EN,
+ (d_fpga_shadows[FR_DC_OFFSET_CL_EN] & ~mask) | (bits & mask));
+}
+
// ----------------------------------------------------------------
bool
@@ -413,11 +475,278 @@ usrp_basic::_read_spi (int optional_header, int enables, int format, int len)
bool
-usrp_basic::_set_led (int which, bool on)
+usrp_basic::_set_led (int which_led, bool on)
+{
+ return usrp_set_led (d_udh, which_led, on);
+}
+
+bool
+usrp_basic::write_atr_tx_delay(int value)
+{
+ return _write_fpga_reg(FR_ATR_TX_DELAY, value);
+}
+
+bool
+usrp_basic::write_atr_rx_delay(int value)
+{
+ return _write_fpga_reg(FR_ATR_RX_DELAY, value);
+}
+
+/*
+ * ----------------------------------------------------------------
+ * Routines to access and control daughterboard specific i/o
+ * ----------------------------------------------------------------
+ */
+static int
+slot_id_to_oe_reg (int slot_id)
+{
+ static int reg[4] = { FR_OE_0, FR_OE_1, FR_OE_2, FR_OE_3 };
+ assert (0 <= slot_id && slot_id < 4);
+ return reg[slot_id];
+}
+
+static int
+slot_id_to_io_reg (int slot_id)
+{
+ static int reg[4] = { FR_IO_0, FR_IO_1, FR_IO_2, FR_IO_3 };
+ assert (0 <= slot_id && slot_id < 4);
+ return reg[slot_id];
+}
+
+static int
+slot_id_to_refclk_reg(int slot_id)
+{
+ static int reg[4] = { FR_TX_A_REFCLK, FR_RX_A_REFCLK, FR_TX_B_REFCLK, FR_RX_B_REFCLK };
+ assert (0 <= slot_id && slot_id < 4);
+ return reg[slot_id];
+}
+
+static int
+slot_id_to_atr_mask_reg(int slot_id)
+{
+ static int reg[4] = { FR_ATR_MASK_0, FR_ATR_MASK_1, FR_ATR_MASK_2, FR_ATR_MASK_3 };
+ assert (0 <= slot_id && slot_id < 4);
+ return reg[slot_id];
+}
+
+static int
+slot_id_to_atr_txval_reg(int slot_id)
+{
+ static int reg[4] = { FR_ATR_TXVAL_0, FR_ATR_TXVAL_1, FR_ATR_TXVAL_2, FR_ATR_TXVAL_3 };
+ assert (0 <= slot_id && slot_id < 4);
+ return reg[slot_id];
+}
+
+static int
+slot_id_to_atr_rxval_reg(int slot_id)
+{
+ static int reg[4] = { FR_ATR_RXVAL_0, FR_ATR_RXVAL_1, FR_ATR_RXVAL_2, FR_ATR_RXVAL_3 };
+ assert (0 <= slot_id && slot_id < 4);
+ return reg[slot_id];
+}
+
+static int
+to_slot(txrx_t txrx, int which_side)
+{
+ // TX_A = 0
+ // RX_A = 1
+ // TX_B = 2
+ // RX_B = 3
+ return ((which_side & 0x1) << 1) | ((txrx & 0x1) == C_RX);
+}
+
+bool
+usrp_basic::common_set_pga(txrx_t txrx, int which_amp, double gain)
+{
+ if (which_amp < 0 || which_amp > 3)
+ return false;
+
+ gain = std::min(common_pga_max(txrx),
+ std::max(common_pga_min(txrx), gain));
+
+ int codec = which_amp >> 1;
+ int int_gain = (int) rint((gain - common_pga_min(txrx)) / common_pga_db_per_step(txrx));
+
+ if (txrx == C_TX){ // 0 and 1 are same, as are 2 and 3
+ return _write_9862(codec, REG_TX_PGA, int_gain);
+ }
+ else {
+ int reg = (which_amp & 1) == 0 ? REG_RX_A : REG_RX_B;
+
+ // read current value to get input buffer bypass flag.
+ unsigned char cur_rx;
+ if (!_read_9862(codec, reg, &cur_rx))
+ return false;
+
+ cur_rx = (cur_rx & RX_X_BYPASS_INPUT_BUFFER) | (int_gain & 0x7f);
+ return _write_9862(codec, reg, cur_rx);
+ }
+}
+
+double
+usrp_basic::common_pga(txrx_t txrx, int which_amp) const
+{
+ if (which_amp < 0 || which_amp > 3)
+ return READ_FAILED;
+
+ if (txrx == C_TX){
+ int codec = which_amp >> 1;
+ unsigned char v;
+ bool ok = _read_9862 (codec, REG_TX_PGA, &v);
+ if (!ok)
+ return READ_FAILED;
+
+ return (pga_db_per_step() * v) + pga_min();
+ }
+ else {
+ int codec = which_amp >> 1;
+ int reg = (which_amp & 1) == 0 ? REG_RX_A : REG_RX_B;
+ unsigned char v;
+ bool ok = _read_9862 (codec, reg, &v);
+ if (!ok)
+ return READ_FAILED;
+
+ return (pga_db_per_step() * (v & 0x1f)) + pga_min();
+ }
+}
+
+double
+usrp_basic::common_pga_min(txrx_t txrx) const
+{
+ if (txrx == C_TX)
+ return -20.0;
+ else
+ return 0.0;
+}
+
+double
+usrp_basic::common_pga_max(txrx_t txrx) const
+{
+ if (txrx == C_TX)
+ return 0.0;
+ else
+ return 20.0;
+}
+
+double
+usrp_basic::common_pga_db_per_step(txrx_t txrx) const
+{
+ if (txrx == C_TX)
+ return 20.0 / 255;
+ else
+ return 20.0 / 20;
+}
+
+bool
+usrp_basic::_common_write_oe(txrx_t txrx, int which_side, int value, int mask)
+{
+ if (! (0 <= which_side && which_side <= 1))
+ return false;
+
+ return _write_fpga_reg(slot_id_to_oe_reg(to_slot(txrx, which_side)),
+ (mask << 16) | (value & 0xffff));
+}
+
+bool
+usrp_basic::common_write_io(txrx_t txrx, int which_side, int value, int mask)
+{
+ if (! (0 <= which_side && which_side <= 1))
+ return false;
+
+ return _write_fpga_reg(slot_id_to_io_reg(to_slot(txrx, which_side)),
+ (mask << 16) | (value & 0xffff));
+}
+
+bool
+usrp_basic::common_read_io(txrx_t txrx, int which_side, int *value)
+{
+ if (! (0 <= which_side && which_side <= 1))
+ return false;
+
+ int t;
+ int reg = which_side + 1; // FIXME, *very* magic number (fix in serial_io.v)
+ bool ok = _read_fpga_reg(reg, &t);
+ if (!ok)
+ return false;
+
+ if (txrx == C_TX){
+ *value = t & 0xffff; // FIXME, more magic
+ return true;
+ }
+ else {
+ *value = (t >> 16) & 0xffff; // FIXME, more magic
+ return true;
+ }
+}
+
+int
+usrp_basic::common_read_io(txrx_t txrx, int which_side)
+{
+ int value;
+ if (!common_read_io(txrx, which_side, &value))
+ return READ_FAILED;
+ return value;
+}
+
+bool
+usrp_basic::common_write_refclk(txrx_t txrx, int which_side, int value)
+{
+ if (! (0 <= which_side && which_side <= 1))
+ return false;
+
+ return _write_fpga_reg(slot_id_to_refclk_reg(to_slot(txrx, which_side)),
+ value);
+}
+
+bool
+usrp_basic::common_write_atr_mask(txrx_t txrx, int which_side, int value)
+{
+ if (! (0 <= which_side && which_side <= 1))
+ return false;
+
+ return _write_fpga_reg(slot_id_to_atr_mask_reg(to_slot(txrx, which_side)),
+ value);
+}
+
+bool
+usrp_basic::common_write_atr_txval(txrx_t txrx, int which_side, int value)
+{
+ if (! (0 <= which_side && which_side <= 1))
+ return false;
+
+ return _write_fpga_reg(slot_id_to_atr_txval_reg(to_slot(txrx, which_side)),
+ value);
+}
+
+bool
+usrp_basic::common_write_atr_rxval(txrx_t txrx, int which_side, int value)
+{
+ if (! (0 <= which_side && which_side <= 1))
+ return false;
+
+ return _write_fpga_reg(slot_id_to_atr_rxval_reg(to_slot(txrx, which_side)),
+ value);
+}
+
+bool
+usrp_basic::common_write_aux_dac(txrx_t txrx, int which_side, int which_dac, int value)
{
- return usrp_set_led (d_udh, which, on);
+ return _write_aux_dac(to_slot(txrx, which_side), which_dac, value);
}
+bool
+usrp_basic::common_read_aux_adc(txrx_t txrx, int which_side, int which_adc, int *value)
+{
+ return _read_aux_adc(to_slot(txrx, which_side), which_adc, value);
+}
+
+int
+usrp_basic::common_read_aux_adc(txrx_t txrx, int which_side, int which_adc)
+{
+ return _read_aux_adc(to_slot(txrx, which_side), which_adc);
+}
+
+
////////////////////////////////////////////////////////////////
//
// usrp_basic_rx
@@ -467,6 +796,9 @@ usrp_basic_rx::usrp_basic_rx (int which_board, int fusb_block_size, int fusb_nbl
probe_rx_slots (false);
+ //d_db[0] = instantiate_dbs(d_dbid[0], this, 0);
+ //d_db[1] = instantiate_dbs(d_dbid[1], this, 1);
+
// check fusb buffering parameters
if (fusb_block_size < 0 || fusb_block_size > FUSB_BLOCK_SIZE)
@@ -485,12 +817,12 @@ usrp_basic_rx::usrp_basic_rx (int which_board, int fusb_block_size, int fusb_nbl
d_ephandle = d_devhandle->make_ephandle (USRP_RX_ENDPOINT, true,
fusb_block_size, fusb_nblocks);
- _write_fpga_reg(FR_ATR_MASK_1, 0); // zero Rx side Auto Transmit/Receive regs
- _write_fpga_reg(FR_ATR_TXVAL_1, 0);
- _write_fpga_reg(FR_ATR_RXVAL_1, 0);
- _write_fpga_reg(FR_ATR_MASK_3, 0);
- _write_fpga_reg(FR_ATR_TXVAL_3, 0);
- _write_fpga_reg(FR_ATR_RXVAL_3, 0);
+ write_atr_mask(0, 0); // zero Rx A Auto Transmit/Receive regs
+ write_atr_txval(0, 0);
+ write_atr_rxval(0, 0);
+ write_atr_mask(1, 0); // zero Rx B Auto Transmit/Receive regs
+ write_atr_txval(1, 0);
+ write_atr_rxval(1, 0);
}
static unsigned char rx_fini_regs[] = {
@@ -511,6 +843,8 @@ usrp_basic_rx::~usrp_basic_rx ()
if (!usrp_9862_write_many_all (d_udh, rx_fini_regs, sizeof (rx_fini_regs))){
fprintf (stderr, "usrp_basic_rx: failed to fini AD9862 RX regs\n");
}
+
+ shutdown_daughterboards();
}
@@ -656,61 +990,6 @@ usrp_basic_rx::restore_rx (bool on)
set_rx_enable (on);
}
-bool
-usrp_basic_rx::set_pga (int which, double gain)
-{
- if (which < 0 || which > 3)
- return false;
-
- gain = std::max (pga_min (), gain);
- gain = std::min (pga_max (), gain);
-
- int codec = which >> 1;
- int reg = (which & 1) == 0 ? REG_RX_A : REG_RX_B;
-
- // read current value to get input buffer bypass flag.
- unsigned char cur_rx;
- if (!_read_9862 (codec, reg, &cur_rx))
- return false;
-
- int int_gain = (int) rint ((gain - pga_min ()) / pga_db_per_step());
-
- cur_rx = (cur_rx & RX_X_BYPASS_INPUT_BUFFER) | (int_gain & 0x7f);
- return _write_9862 (codec, reg, cur_rx);
-}
-
-double
-usrp_basic_rx::pga (int which) const
-{
- if (which < 0 || which > 3)
- return READ_FAILED;
-
- int codec = which >> 1;
- int reg = (which & 1) == 0 ? REG_RX_A : REG_RX_B;
- unsigned char v;
- bool ok = _read_9862 (codec, reg, &v);
- if (!ok)
- return READ_FAILED;
-
- return (pga_db_per_step() * (v & 0x1f)) + pga_min();
-}
-
-static int
-slot_id_to_oe_reg (int slot_id)
-{
- static int reg[4] = { FR_OE_0, FR_OE_1, FR_OE_2, FR_OE_3 };
- assert (0 <= slot_id && slot_id < 4);
- return reg[slot_id];
-}
-
-static int
-slot_id_to_io_reg (int slot_id)
-{
- static int reg[4] = { FR_IO_0, FR_IO_1, FR_IO_2, FR_IO_3 };
- assert (0 <= slot_id && slot_id < 4);
- return reg[slot_id];
-}
-
void
usrp_basic_rx::probe_rx_slots (bool verbose)
{
@@ -760,80 +1039,104 @@ usrp_basic_rx::probe_rx_slots (bool verbose)
}
bool
-usrp_basic_rx::_write_oe (int which_dboard, int value, int mask)
+usrp_basic_rx::set_pga (int which_amp, double gain)
{
- if (! (0 <= which_dboard && which_dboard <= 1))
- return false;
+ return common_set_pga(C_RX, which_amp, gain);
+}
- return _write_fpga_reg (slot_id_to_oe_reg (dboard_to_slot (which_dboard)),
- (mask << 16) | (value & 0xffff));
+double
+usrp_basic_rx::pga(int which_amp) const
+{
+ return common_pga(C_RX, which_amp);
}
-bool
-usrp_basic_rx::write_io (int which_dboard, int value, int mask)
+double
+usrp_basic_rx::pga_min() const
{
- if (! (0 <= which_dboard && which_dboard <= 1))
- return false;
+ return common_pga_min(C_RX);
+}
- return _write_fpga_reg (slot_id_to_io_reg (dboard_to_slot (which_dboard)),
- (mask << 16) | (value & 0xffff));
+double
+usrp_basic_rx::pga_max() const
+{
+ return common_pga_max(C_RX);
+}
+
+double
+usrp_basic_rx::pga_db_per_step() const
+{
+ return common_pga_db_per_step(C_RX);
}
bool
-usrp_basic_rx::read_io (int which_dboard, int *value)
+usrp_basic_rx::_write_oe (int which_side, int value, int mask)
{
- if (! (0 <= which_dboard && which_dboard <= 1))
- return false;
+ return _common_write_oe(C_RX, which_side, value, mask);
+}
- int t;
- int reg = which_dboard + 1; // FIXME, *very* magic number (fix in serial_io.v)
- bool ok = _read_fpga_reg (reg, &t);
- if (!ok)
- return false;
+bool
+usrp_basic_rx::write_io (int which_side, int value, int mask)
+{
+ return common_write_io(C_RX, which_side, value, mask);
+}
- *value = (t >> 16) & 0xffff; // FIXME, more magic
- return true;
+bool
+usrp_basic_rx::read_io (int which_side, int *value)
+{
+ return common_read_io(C_RX, which_side, value);
}
int
-usrp_basic_rx::read_io (int which_dboard)
+usrp_basic_rx::read_io (int which_side)
{
- int value;
- if (!read_io (which_dboard, &value))
- return READ_FAILED;
- return value;
+ return common_read_io(C_RX, which_side);
}
bool
-usrp_basic_rx::write_aux_dac (int which_dboard, int which_dac, int value)
+usrp_basic_rx::write_refclk(int which_side, int value)
{
- return usrp_basic::write_aux_dac (dboard_to_slot (which_dboard),
- which_dac, value);
+ return common_write_refclk(C_RX, which_side, value);
}
bool
-usrp_basic_rx::read_aux_adc (int which_dboard, int which_adc, int *value)
+usrp_basic_rx::write_atr_mask(int which_side, int value)
{
- return usrp_basic::read_aux_adc (dboard_to_slot (which_dboard),
- which_adc, value);
+ return common_write_atr_mask(C_RX, which_side, value);
}
-int
-usrp_basic_rx::read_aux_adc (int which_dboard, int which_adc)
+bool
+usrp_basic_rx::write_atr_txval(int which_side, int value)
{
- return usrp_basic::read_aux_adc (dboard_to_slot (which_dboard), which_adc);
+ return common_write_atr_txval(C_RX, which_side, value);
}
-int
-usrp_basic_rx::block_size () const { return d_ephandle->block_size(); }
+bool
+usrp_basic_rx::write_atr_rxval(int which_side, int value)
+{
+ return common_write_atr_rxval(C_RX, which_side, value);
+}
bool
-usrp_basic_rx::set_dc_offset_cl_enable(int bits, int mask)
+usrp_basic_rx::write_aux_dac (int which_side, int which_dac, int value)
{
- return _write_fpga_reg(FR_DC_OFFSET_CL_EN,
- (d_fpga_shadows[FR_DC_OFFSET_CL_EN] & ~mask) | (bits & mask));
+ return common_write_aux_dac(C_RX, which_side, which_dac, value);
+}
+
+bool
+usrp_basic_rx::read_aux_adc (int which_side, int which_adc, int *value)
+{
+ return common_read_aux_adc(C_RX, which_side, which_adc, value);
}
+int
+usrp_basic_rx::read_aux_adc (int which_side, int which_adc)
+{
+ return common_read_aux_adc(C_RX, which_side, which_adc);
+}
+
+int
+usrp_basic_rx::block_size () const { return d_ephandle->block_size(); }
+
////////////////////////////////////////////////////////////////
//
// usrp_basic_tx
@@ -902,6 +1205,9 @@ usrp_basic_tx::usrp_basic_tx (int which_board, int fusb_block_size, int fusb_nbl
probe_tx_slots (false);
+ //d_db[0] = instantiate_dbs(d_dbid[0], this, 0);
+ //d_db[1] = instantiate_dbs(d_dbid[1], this, 1);
+
// check fusb buffering parameters
if (fusb_block_size < 0 || fusb_block_size > FUSB_BLOCK_SIZE)
@@ -920,12 +1226,12 @@ usrp_basic_tx::usrp_basic_tx (int which_board, int fusb_block_size, int fusb_nbl
d_ephandle = d_devhandle->make_ephandle (USRP_TX_ENDPOINT, false,
fusb_block_size, fusb_nblocks);
- _write_fpga_reg(FR_ATR_MASK_0, 0); // zero Tx side Auto Transmit/Receive regs
- _write_fpga_reg(FR_ATR_TXVAL_0, 0);
- _write_fpga_reg(FR_ATR_RXVAL_0, 0);
- _write_fpga_reg(FR_ATR_MASK_2, 0);
- _write_fpga_reg(FR_ATR_TXVAL_2, 0);
- _write_fpga_reg(FR_ATR_RXVAL_2, 0);
+ write_atr_mask(0, 0); // zero Tx A Auto Transmit/Receive regs
+ write_atr_txval(0, 0);
+ write_atr_rxval(0, 0);
+ write_atr_mask(1, 0); // zero Tx B Auto Transmit/Receive regs
+ write_atr_txval(1, 0);
+ write_atr_rxval(1, 0);
}
@@ -945,6 +1251,8 @@ usrp_basic_tx::~usrp_basic_tx ()
if (!usrp_9862_write_many_all (d_udh, tx_fini_regs, sizeof (tx_fini_regs))){
fprintf (stderr, "usrp_basic_tx: failed to fini AD9862 TX regs\n");
}
+
+ shutdown_daughterboards();
}
bool
@@ -1094,37 +1402,6 @@ usrp_basic_tx::restore_tx (bool on)
set_tx_enable (on);
}
-bool
-usrp_basic_tx::set_pga (int which, double gain)
-{
- if (which < 0 || which > 3)
- return false;
-
- gain = std::max (pga_min (), gain);
- gain = std::min (pga_max (), gain);
-
- int codec = which >> 1; // 0 and 1 are same, as are 2 and 3
-
- int int_gain = (int) rint ((gain - pga_min ()) / pga_db_per_step());
-
- return _write_9862 (codec, REG_TX_PGA, int_gain);
-}
-
-double
-usrp_basic_tx::pga (int which) const
-{
- if (which < 0 || which > 3)
- return READ_FAILED;
-
- int codec = which >> 1;
- unsigned char v;
- bool ok = _read_9862 (codec, REG_TX_PGA, &v);
- if (!ok)
- return READ_FAILED;
-
- return (pga_db_per_step() * v) + pga_min();
-}
-
void
usrp_basic_tx::probe_tx_slots (bool verbose)
{
@@ -1174,68 +1451,99 @@ usrp_basic_tx::probe_tx_slots (bool verbose)
}
bool
-usrp_basic_tx::_write_oe (int which_dboard, int value, int mask)
+usrp_basic_tx::set_pga (int which_amp, double gain)
{
- if (! (0 <= which_dboard && which_dboard <= 1))
- return false;
+ return common_set_pga(C_TX, which_amp, gain);
+}
- return _write_fpga_reg (slot_id_to_oe_reg (dboard_to_slot (which_dboard)),
- (mask << 16) | (value & 0xffff));
+double
+usrp_basic_tx::pga (int which_amp) const
+{
+ return common_pga(C_TX, which_amp);
}
-bool
-usrp_basic_tx::write_io (int which_dboard, int value, int mask)
+double
+usrp_basic_tx::pga_min() const
{
- if (! (0 <= which_dboard && which_dboard <= 1))
- return false;
+ return common_pga_min(C_TX);
+}
- return _write_fpga_reg (slot_id_to_io_reg (dboard_to_slot (which_dboard)),
- (mask << 16) | (value & 0xffff));
+double
+usrp_basic_tx::pga_max() const
+{
+ return common_pga_max(C_TX);
+}
+
+double
+usrp_basic_tx::pga_db_per_step() const
+{
+ return common_pga_db_per_step(C_TX);
}
bool
-usrp_basic_tx::read_io (int which_dboard, int *value)
+usrp_basic_tx::_write_oe (int which_side, int value, int mask)
{
- if (! (0 <= which_dboard && which_dboard <= 1))
- return false;
+ return _common_write_oe(C_TX, which_side, value, mask);
+}
- int t;
- int reg = which_dboard + 1; // FIXME, *very* magic number (fix in serial_io.v)
- bool ok = _read_fpga_reg (reg, &t);
- if (!ok)
- return false;
+bool
+usrp_basic_tx::write_io (int which_side, int value, int mask)
+{
+ return common_write_io(C_TX, which_side, value, mask);
+}
- *value = t & 0xffff; // FIXME, more magic
- return true;
+bool
+usrp_basic_tx::read_io (int which_side, int *value)
+{
+ return common_read_io(C_TX, which_side, value);
}
int
-usrp_basic_tx::read_io (int which_dboard)
+usrp_basic_tx::read_io (int which_side)
{
- int value;
- if (!read_io (which_dboard, &value))
- return READ_FAILED;
- return value;
+ return common_read_io(C_TX, which_side);
+}
+
+bool
+usrp_basic_tx::write_refclk(int which_side, int value)
+{
+ return common_write_refclk(C_TX, which_side, value);
+}
+
+bool
+usrp_basic_tx::write_atr_mask(int which_side, int value)
+{
+ return common_write_atr_mask(C_TX, which_side, value);
+}
+
+bool
+usrp_basic_tx::write_atr_txval(int which_side, int value)
+{
+ return common_write_atr_txval(C_TX, which_side, value);
+}
+
+bool
+usrp_basic_tx::write_atr_rxval(int which_side, int value)
+{
+ return common_write_atr_rxval(C_TX, which_side, value);
}
bool
-usrp_basic_tx::write_aux_dac (int which_dboard, int which_dac, int value)
+usrp_basic_tx::write_aux_dac (int which_side, int which_dac, int value)
{
- return usrp_basic::write_aux_dac (dboard_to_slot (which_dboard),
- which_dac, value);
+ return common_write_aux_dac(C_TX, which_side, which_dac, value);
}
bool
-usrp_basic_tx::read_aux_adc (int which_dboard, int which_adc, int *value)
+usrp_basic_tx::read_aux_adc (int which_side, int which_adc, int *value)
{
- return usrp_basic::read_aux_adc (dboard_to_slot (which_dboard),
- which_adc, value);
+ return common_read_aux_adc(C_TX, which_side, which_adc, value);
}
int
-usrp_basic_tx::read_aux_adc (int which_dboard, int which_adc)
+usrp_basic_tx::read_aux_adc (int which_side, int which_adc)
{
- return usrp_basic::read_aux_adc (dboard_to_slot (which_dboard), which_adc);
+ return common_read_aux_adc(C_TX, which_side, which_adc);
}
int
diff --git a/usrp/host/lib/legacy/usrp_basic.h b/usrp/host/lib/legacy/usrp_basic.h
index 395a1dac02..c5e3d28241 100644
--- a/usrp/host/lib/legacy/usrp_basic.h
+++ b/usrp/host/lib/legacy/usrp_basic.h
@@ -1,6 +1,7 @@
+
/* -*- c++ -*- */
/*
- * Copyright 2003,2004 Free Software Foundation, Inc.
+ * Copyright 2003,2004,2008 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -39,24 +40,30 @@
#ifndef INCLUDED_USRP_BASIC_H
#define INCLUDED_USRP_BASIC_H
+#include <db_base.h>
#include <usrp_slots.h>
#include <string>
+#include <vector>
+#include <boost/utility.hpp>
+#include <usrp_subdev_spec.h>
struct usb_dev_handle;
class fusb_devhandle;
class fusb_ephandle;
+enum txrx_t {
+ C_RX = 0,
+ C_TX = 1
+};
+
/*!
- * \brief base class for usrp operations
+ * \brief abstract base class for usrp operations
*/
-class usrp_basic
+class usrp_basic : boost::noncopyable
{
-private:
- // NOT IMPLEMENTED
- usrp_basic (const usrp_basic &rhs); // no copy constructor
- usrp_basic &operator= (const usrp_basic &rhs); // no assignment operator
+protected:
+ void shutdown_daughterboards();
-
protected:
struct usb_dev_handle *d_udh;
int d_usb_data_rate; // bytes/sec
@@ -66,6 +73,22 @@ protected:
static const int MAX_REGS = 128;
unsigned int d_fpga_shadows[MAX_REGS];
+ int d_dbid[2]; // daughterboard ID's (side A, side B)
+
+ /*!
+ * Shared pointers to subclasses of db_base.
+ *
+ * The outer vector is of length 2 (0 = side A, 1 = side B). The
+ * inner vectors are of length 1, 2 or 3 depending on the number of
+ * subdevices implemented by the daugherboard. At this time, only
+ * the Basic Rx and LF Rx implement more than 1 subdevice.
+ */
+ std::vector< std::vector<db_base_sptr> > d_db;
+
+ //! One time call, made only only from usrp_standard_*::make after shared_ptr is created.
+ void init_db(usrp_basic_sptr u);
+
+
usrp_basic (int which_board,
struct usb_dev_handle *open_interface (struct usb_device *dev),
const std::string fpga_filename = "",
@@ -92,7 +115,7 @@ protected:
* \param value [0,4095]
* \returns true iff successful
*/
- bool write_aux_dac (int slot, int which_dac, int value);
+ bool _write_aux_dac (int slot, int which_dac, int value);
/*!
* \brief Read auxiliary analog to digital converter.
@@ -102,7 +125,7 @@ protected:
* \param value return 12-bit value [0,4095]
* \returns true iff successful
*/
- bool read_aux_adc (int slot, int which_adc, int *value);
+ bool _read_aux_adc (int slot, int which_adc, int *value);
/*!
* \brief Read auxiliary analog to digital converter.
@@ -111,11 +134,46 @@ protected:
* \param which_adc [0,1]
* \returns value in the range [0,4095] if successful, else READ_FAILED.
*/
- int read_aux_adc (int slot, int which_adc);
+ int _read_aux_adc (int slot, int which_adc);
+
public:
virtual ~usrp_basic ();
+
+ /*!
+ * Return a vector of vectors that contain shared pointers
+ * to the daughterboard instance(s) associated with the specified side.
+ *
+ * It is an error to use the returned objects after the usrp_basic
+ * object has been destroyed.
+ */
+ std::vector<std::vector<db_base_sptr> > db() const { return d_db; }
+
+ /*!
+ * Return a vector of size >= 1 that contains shared pointers
+ * to the daughterboard instance(s) associated with the specified side.
+ *
+ * \param which_side [0,1] which daughterboard
+ *
+ * It is an error to use the returned objects after the usrp_basic
+ * object has been destroyed.
+ */
+ std::vector<db_base_sptr> db(int which_side);
+
+ /*!
+ * \brief is the subdev_spec valid?
+ */
+ bool is_valid(const usrp_subdev_spec &ss);
+
+ /*!
+ * \brief given a subdev_spec, return the corresponding daughterboard object.
+ * \throws std::invalid_ argument if ss is invalid.
+ *
+ * \param ss specifies the side and subdevice
+ */
+ db_base_sptr selected_subdev(const usrp_subdev_spec &ss);
+
/*!
* \brief return frequency of master oscillator on USRP
*/
@@ -172,7 +230,7 @@ public:
* \param which which ADC[0,3]: 0 = RX_A I, 1 = RX_A Q...
* \param offset 16-bit value to subtract from raw ADC input.
*/
- bool set_adc_offset (int which, int offset);
+ bool set_adc_offset (int which_adc, int offset);
/*!
* \brief Set DAC offset correction
@@ -181,16 +239,37 @@ public:
* \param offset_pin 1-bit value. If 0 offset applied to -ve differential pin;
* If 1 offset applied to +ve differential pin.
*/
- bool set_dac_offset (int which, int offset, int offset_pin);
+ bool set_dac_offset (int which_dac, int offset, int offset_pin);
/*!
* \brief Control ADC input buffer
- * \param which which ADC[0,3]
+ * \param which_adc which ADC[0,3]
* \param bypass if non-zero, bypass input buffer and connect input
* directly to switched cap SHA input of RxPGA.
*/
- bool set_adc_buffer_bypass (int which, bool bypass);
+ bool set_adc_buffer_bypass (int which_adc, bool bypass);
+ /*!
+ * \brief Enable/disable automatic DC offset removal control loop in FPGA
+ *
+ * \param bits which control loops to enable
+ * \param mask which \p bits to pay attention to
+ *
+ * If the corresponding bit is set, enable the automatic DC
+ * offset correction control loop.
+ *
+ * <pre>
+ * The 4 low bits are significant:
+ *
+ * ADC0 = (1 << 0)
+ * ADC1 = (1 << 1)
+ * ADC2 = (1 << 2)
+ * ADC3 = (1 << 3)
+ * </pre>
+ *
+ * By default the control loop is enabled on all ADC's.
+ */
+ bool set_dc_offset_cl_enable(int bits, int mask);
/*!
* \brief return the usrp's serial number.
@@ -199,12 +278,376 @@ public:
*/
std::string serial_number();
+ /*!
+ * \brief Return daughterboard ID for given side [0,1].
+ *
+ * \param which_side [0,1] which daughterboard
+ *
+ * \return daughterboard id >= 0 if successful
+ * \return -1 if no daugherboard
+ * \return -2 if invalid EEPROM on daughterboard
+ */
+ virtual int daughterboard_id (int which_side) const = 0;
+
+ /*!
+ * \brief Clock ticks to delay rising of T/R signal
+ * \sa write_atr_mask, write_atr_txval, write_atr_rxval
+ */
+ bool write_atr_tx_delay(int value);
+
+ /*!
+ * \brief Clock ticks to delay falling edge of T/R signal
+ * \sa write_atr_mask, write_atr_txval, write_atr_rxval
+ */
+ bool write_atr_rx_delay(int value);
+
+
+ // ================================================================
+ // Routines to access and control daughterboard specific i/o
+ //
+ // Those with a common_ prefix access either the Tx or Rx side depending
+ // on the txrx parameter. Those without the common_ prefix are virtual
+ // and are overriden in usrp_basic_rx and usrp_basic_tx to access the
+ // the Rx or Tx sides automatically. We provide the common_ versions
+ // for those daughterboards such as the WBX and XCVR2450 that share
+ // h/w resources (such as the LO) between the Tx and Rx sides.
+
+ // ----------------------------------------------------------------
+ // BEGIN common_ daughterboard control functions
+
+ /*!
+ * \brief Set Programmable Gain Amplifier(PGA)
+ *
+ * \param txrx Tx or Rx?
+ * \param which_amp which amp [0,3]
+ * \param gain_in_db gain value(linear in dB)
+ *
+ * gain is rounded to closest setting supported by hardware.
+ *
+ * \returns true iff sucessful.
+ *
+ * \sa pga_min(), pga_max(), pga_db_per_step()
+ */
+ bool common_set_pga(txrx_t txrx, int which_amp, double gain_in_db);
+
+ /*!
+ * \brief Return programmable gain amplifier gain setting in dB.
+ *
+ * \param txrx Tx or Rx?
+ * \param which_amp which amp [0,3]
+ */
+ double common_pga(txrx_t txrx, int which_amp) const;
+
+ /*!
+ * \brief Return minimum legal PGA gain in dB.
+ * \param txrx Tx or Rx?
+ */
+ double common_pga_min(txrx_t txrx) const;
+
+ /*!
+ * \brief Return maximum legal PGA gain in dB.
+ * \param txrx Tx or Rx?
+ */
+ double common_pga_max(txrx_t txrx) const;
+
+ /*!
+ * \brief Return hardware step size of PGA(linear in dB).
+ * \param txrx Tx or Rx?
+ */
+ double common_pga_db_per_step(txrx_t txrx) const;
+
+ /*!
+ * \brief Write direction register(output enables) for pins that go to daughterboard.
+ *
+ * \param txrx Tx or Rx?
+ * \param which_side [0,1] which size
+ * \param value value to write into register
+ * \param mask which bits of value to write into reg
+ *
+ * Each d'board has 16-bits of general purpose i/o.
+ * Setting the bit makes it an output from the FPGA to the d'board.
+ *
+ * This register is initialized based on a value stored in the
+ * d'board EEPROM. In general, you shouldn't be using this routine
+ * without a very good reason. Using this method incorrectly will
+ * kill your USRP motherboard and/or daughterboard.
+ */
+ bool _common_write_oe(txrx_t txrx, int which_side, int value, int mask);
+
+ /*!
+ * \brief Write daughterboard i/o pin value
+ *
+ * \param txrx Tx or Rx?
+ * \param which_side [0,1] which d'board
+ * \param value value to write into register
+ * \param mask which bits of value to write into reg
+ */
+ bool common_write_io(txrx_t txrx, int which_side, int value, int mask);
+
+ /*!
+ * \brief Read daughterboard i/o pin value
+ *
+ * \param txrx Tx or Rx?
+ * \param which_side [0,1] which d'board
+ * \param value output
+ */
+ bool common_read_io(txrx_t txrx, int which_side, int *value);
+
+ /*!
+ * \brief Read daughterboard i/o pin value
+ *
+ * \param txrx Tx or Rx?
+ * \param which_side [0,1] which d'board
+ * \returns register value if successful, else READ_FAILED
+ */
+ int common_read_io(txrx_t txrx, int which_side);
+
+ /*!
+ * \brief Write daughterboard refclk config register
+ *
+ * \param txrx Tx or Rx?
+ * \param which_side [0,1] which d'board
+ * \param value value to write into register, see below
+ *
+ * <pre>
+ * Control whether a reference clock is sent to the daughterboards,
+ * and what frequency. The refclk is sent on d'board i/o pin 0.
+ *
+ * 3 2 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-----------------------------------------------+-+------------+
+ * | Reserved (Must be zero) |E| DIVISOR |
+ * +-----------------------------------------------+-+------------+
+ *
+ * Bit 7 -- 1 turns on refclk, 0 allows IO use
+ * Bits 6:0 Divider value
+ * </pre>
+ */
+ bool common_write_refclk(txrx_t txrx, int which_side, int value);
+
+ /*!
+ * \brief Automatic Transmit/Receive switching
+ * <pre>
+ *
+ * If automatic transmit/receive (ATR) switching is enabled in the
+ * FR_ATR_CTL register, the presence or absence of data in the FPGA
+ * transmit fifo selects between two sets of values for each of the 4
+ * banks of daughterboard i/o pins.
+ *
+ * Each daughterboard slot has 3 16-bit registers associated with it:
+ * FR_ATR_MASK_*, FR_ATR_TXVAL_* and FR_ATR_RXVAL_*
+ *
+ * FR_ATR_MASK_{0,1,2,3}:
+ *
+ * These registers determine which of the daugherboard i/o pins are
+ * affected by ATR switching. If a bit in the mask is set, the
+ * corresponding i/o bit is controlled by ATR, else it's output
+ * value comes from the normal i/o pin output register:
+ * FR_IO_{0,1,2,3}.
+ *
+ * FR_ATR_TXVAL_{0,1,2,3}:
+ * FR_ATR_RXVAL_{0,1,2,3}:
+ *
+ * If the Tx fifo contains data, then the bits from TXVAL that are
+ * selected by MASK are output. Otherwise, the bits from RXVAL that
+ * are selected by MASK are output.
+ * </pre>
+ */
+ bool common_write_atr_mask(txrx_t txrx, int which_side, int value);
+ bool common_write_atr_txval(txrx_t txrx, int which_side, int value);
+ bool common_write_atr_rxval(txrx_t txrx, int which_side, int value);
+
+ /*!
+ * \brief Write auxiliary digital to analog converter.
+ *
+ * \param txrx Tx or Rx?
+ * \param which_side [0,1] which d'board
+ * N.B., SLOT_TX_A and SLOT_RX_A share the same AUX DAC's.
+ * SLOT_TX_B and SLOT_RX_B share the same AUX DAC's.
+ * \param which_dac [2,3] TX slots must use only 2 and 3.
+ * \param value [0,4095]
+ * \returns true iff successful
+ */
+ bool common_write_aux_dac(txrx_t txrx, int which_side, int which_dac, int value);
+
+ /*!
+ * \brief Read auxiliary analog to digital converter.
+ *
+ * \param txrx Tx or Rx?
+ * \param which_side [0,1] which d'board
+ * \param which_adc [0,1]
+ * \param value return 12-bit value [0,4095]
+ * \returns true iff successful
+ */
+ bool common_read_aux_adc(txrx_t txrx, int which_side, int which_adc, int *value);
+
+ /*!
+ * \brief Read auxiliary analog to digital converter.
+ *
+ * \param txrx Tx or Rx?
+ * \param which_side [0,1] which d'board
+ * \param which_adc [0,1]
+ * \returns value in the range [0,4095] if successful, else READ_FAILED.
+ */
+ int common_read_aux_adc(txrx_t txrx, int which_side, int which_adc);
+
+ // END common_ daughterboard control functions
+ // ----------------------------------------------------------------
+ // BEGIN virtual daughterboard control functions
+
+ /*!
+ * \brief Set Programmable Gain Amplifier (PGA)
+ *
+ * \param which_amp which amp [0,3]
+ * \param gain_in_db gain value (linear in dB)
+ *
+ * gain is rounded to closest setting supported by hardware.
+ *
+ * \returns true iff sucessful.
+ *
+ * \sa pga_min(), pga_max(), pga_db_per_step()
+ */
+ virtual bool set_pga (int which_amp, double gain_in_db) = 0;
+
+ /*!
+ * \brief Return programmable gain amplifier gain setting in dB.
+ *
+ * \param which_amp which amp [0,3]
+ */
+ virtual double pga (int which_amp) const = 0;
+
+ /*!
+ * \brief Return minimum legal PGA gain in dB.
+ */
+ virtual double pga_min () const = 0;
+
+ /*!
+ * \brief Return maximum legal PGA gain in dB.
+ */
+ virtual double pga_max () const = 0;
+
+ /*!
+ * \brief Return hardware step size of PGA (linear in dB).
+ */
+ virtual double pga_db_per_step () const = 0;
+
+ /*!
+ * \brief Write direction register (output enables) for pins that go to daughterboard.
+ *
+ * \param which_side [0,1] which size
+ * \param value value to write into register
+ * \param mask which bits of value to write into reg
+ *
+ * Each d'board has 16-bits of general purpose i/o.
+ * Setting the bit makes it an output from the FPGA to the d'board.
+ *
+ * This register is initialized based on a value stored in the
+ * d'board EEPROM. In general, you shouldn't be using this routine
+ * without a very good reason. Using this method incorrectly will
+ * kill your USRP motherboard and/or daughterboard.
+ */
+ virtual bool _write_oe (int which_side, int value, int mask) = 0;
+
+ /*!
+ * \brief Write daughterboard i/o pin value
+ *
+ * \param which_side [0,1] which d'board
+ * \param value value to write into register
+ * \param mask which bits of value to write into reg
+ */
+ virtual bool write_io (int which_side, int value, int mask) = 0;
+
+ /*!
+ * \brief Read daughterboard i/o pin value
+ *
+ * \param which_side [0,1] which d'board
+ * \param value output
+ */
+ virtual bool read_io (int which_side, int *value) = 0;
+
+ /*!
+ * \brief Read daughterboard i/o pin value
+ *
+ * \param which_side [0,1] which d'board
+ * \returns register value if successful, else READ_FAILED
+ */
+ virtual int read_io (int which_side) = 0;
+
+ /*!
+ * \brief Write daughterboard refclk config register
+ *
+ * \param which_side [0,1] which d'board
+ * \param value value to write into register, see below
+ *
+ * <pre>
+ * Control whether a reference clock is sent to the daughterboards,
+ * and what frequency. The refclk is sent on d'board i/o pin 0.
+ *
+ * 3 2 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-----------------------------------------------+-+------------+
+ * | Reserved (Must be zero) |E| DIVISOR |
+ * +-----------------------------------------------+-+------------+
+ *
+ * Bit 7 -- 1 turns on refclk, 0 allows IO use
+ * Bits 6:0 Divider value
+ * </pre>
+ */
+ virtual bool write_refclk(int which_side, int value) = 0;
+
+ virtual bool write_atr_mask(int which_side, int value) = 0;
+ virtual bool write_atr_txval(int which_side, int value) = 0;
+ virtual bool write_atr_rxval(int which_side, int value) = 0;
+
+ /*!
+ * \brief Write auxiliary digital to analog converter.
+ *
+ * \param which_side [0,1] which d'board
+ * N.B., SLOT_TX_A and SLOT_RX_A share the same AUX DAC's.
+ * SLOT_TX_B and SLOT_RX_B share the same AUX DAC's.
+ * \param which_dac [2,3] TX slots must use only 2 and 3.
+ * \param value [0,4095]
+ * \returns true iff successful
+ */
+ virtual bool write_aux_dac (int which_side, int which_dac, int value) = 0;
+
+ /*!
+ * \brief Read auxiliary analog to digital converter.
+ *
+ * \param which_side [0,1] which d'board
+ * \param which_adc [0,1]
+ * \param value return 12-bit value [0,4095]
+ * \returns true iff successful
+ */
+ virtual bool read_aux_adc (int which_side, int which_adc, int *value) = 0;
+
+ /*!
+ * \brief Read auxiliary analog to digital converter.
+ *
+ * \param which_side [0,1] which d'board
+ * \param which_adc [0,1]
+ * \returns value in the range [0,4095] if successful, else READ_FAILED.
+ */
+ virtual int read_aux_adc (int which_side, int which_adc) = 0;
+
+ /*!
+ * \brief returns current fusb block size
+ */
+ virtual int block_size() const = 0;
+
+ /*!
+ * \brief returns A/D or D/A converter rate in Hz
+ */
+ virtual long converter_rate() const = 0;
+
+ // END virtual daughterboard control functions
+
// ----------------------------------------------------------------
// Low level implementation routines.
// You probably shouldn't be using these...
//
- bool _set_led (int which, bool on);
+ bool _set_led (int which_led, bool on);
/*!
* \brief Write FPGA register.
@@ -229,7 +672,6 @@ public:
*/
int _read_fpga_reg (int regno);
-
/*!
* \brief Write FPGA register with mask.
* \param regno 7-bit register number
@@ -324,8 +766,6 @@ private:
bool d_rx_enable;
protected:
- int d_dbid[2]; // Rx daughterboard ID's
-
/*!
* \param which_board Which USRP board on usb (not particularly useful; use 0)
* \param fusb_block_size fast usb xfer block size. Must be a multiple of 512.
@@ -346,7 +786,6 @@ protected:
void restore_rx (bool on); // conditional set
void probe_rx_slots (bool verbose);
- int dboard_to_slot (int dboard) { return (dboard << 1) | 1; }
public:
~usrp_basic_rx ();
@@ -358,6 +797,8 @@ public:
* \param fusb_block_size fast usb xfer block size. Must be a multiple of 512.
* Use zero for a reasonable default.
* \param fusb_nblocks number of fast usb URBs to allocate. Use zero for a reasonable default.
+ * \param fpga_filename name of file that contains image to load into FPGA
+ * \param firmware_filename name of file that contains image to load into FX2
*/
static usrp_basic_rx *make (int which_board,
int fusb_block_size=0,
@@ -366,8 +807,6 @@ public:
const std::string firmware_filename = ""
);
- // MANIPULATORS
-
/*!
* \brief tell the fpga the rate rx samples are coming from the A/D's
*
@@ -389,162 +828,33 @@ public:
*/
int read (void *buf, int len, bool *overrun);
- // ACCESSORS
//! sampling rate of A/D converter
virtual long converter_rate() const { return fpga_master_clock_freq(); } // 64M
long adc_rate() const { return converter_rate(); }
- long adc_freq() const { return converter_rate(); } //!< deprecated method name
-
- /*!
- * \brief Return daughterboard ID for given Rx daughterboard slot [0,1].
- *
- * \param which_dboard [0,1] which Rx daughterboard
- *
- * \return daughterboard id >= 0 if successful
- * \return -1 if no daugherboard
- * \return -2 if invalid EEPROM on daughterboard
- */
- int daughterboard_id (int which_dboard) const { return d_dbid[which_dboard & 0x1]; }
-
- // ----------------------------------------------------------------
- // routines for controlling the Programmable Gain Amplifier
- /*!
- * \brief Set Programmable Gain Amplifier (PGA)
- *
- * \param which which A/D [0,3]
- * \param gain_in_db gain value (linear in dB)
- *
- * gain is rounded to closest setting supported by hardware.
- *
- * \returns true iff sucessful.
- *
- * \sa pga_min(), pga_max(), pga_db_per_step()
- */
- bool set_pga (int which, double gain_in_db);
-
- /*!
- * \brief Return programmable gain amplifier gain setting in dB.
- *
- * \param which which A/D [0,3]
- */
- double pga (int which) const;
-
- /*!
- * \brief Return minimum legal PGA gain in dB.
- */
- double pga_min () const { return 0.0; }
-
- /*!
- * \brief Return maximum legal PGA gain in dB.
- */
- double pga_max () const { return 20.0; }
-
- /*!
- * \brief Return hardware step size of PGA (linear in dB).
- */
- double pga_db_per_step () const { return 20.0 / 20; }
-
- /*!
- * \brief Write direction register (output enables) for pins that go to daughterboard.
- *
- * \param which_dboard [0,1] which d'board
- * \param value value to write into register
- * \param mask which bits of value to write into reg
- *
- * Each d'board has 16-bits of general purpose i/o.
- * Setting the bit makes it an output from the FPGA to the d'board.
- *
- * This register is initialized based on a value stored in the
- * d'board EEPROM. In general, you shouldn't be using this routine
- * without a very good reason. Using this method incorrectly will
- * kill your USRP motherboard and/or daughterboard.
- */
- bool _write_oe (int which_dboard, int value, int mask);
-
- /*!
- * \brief Write daughterboard i/o pin value
- *
- * \param which_dboard [0,1] which d'board
- * \param value value to write into register
- * \param mask which bits of value to write into reg
- */
- bool write_io (int which_dboard, int value, int mask);
-
- /*!
- * \brief Read daughterboard i/o pin value
- *
- * \param which_dboard [0,1] which d'board
- * \param value output
- */
- bool read_io (int which_dboard, int *value);
-
- /*!
- * \brief Read daughterboard i/o pin value
- *
- * \param which_dboard [0,1] which d'board
- * \returns register value if successful, else READ_FAILED
- */
- int read_io (int which_dboard);
-
- /*!
- * \brief Write auxiliary digital to analog converter.
- *
- * \param which_dboard [0,1] which d'board
- * N.B., SLOT_TX_A and SLOT_RX_A share the same AUX DAC's.
- * SLOT_TX_B and SLOT_RX_B share the same AUX DAC's.
- * \param which_dac [2,3] TX slots must use only 2 and 3.
- * \param value [0,4095]
- * \returns true iff successful
- */
- bool write_aux_dac (int which_board, int which_dac, int value);
-
- /*!
- * \brief Read auxiliary analog to digital converter.
- *
- * \param which_dboard [0,1] which d'board
- * \param which_adc [0,1]
- * \param value return 12-bit value [0,4095]
- * \returns true iff successful
- */
- bool read_aux_adc (int which_dboard, int which_adc, int *value);
-
- /*!
- * \brief Read auxiliary analog to digital converter.
- *
- * \param which_dboard [0,1] which d'board
- * \param which_adc [0,1]
- * \returns value in the range [0,4095] if successful, else READ_FAILED.
- */
- int read_aux_adc (int which_dboard, int which_adc);
+ int daughterboard_id (int which_side) const { return d_dbid[which_side & 0x1]; }
+
+ bool set_pga (int which_amp, double gain_in_db);
+ double pga (int which_amp) const;
+ double pga_min () const;
+ double pga_max () const;
+ double pga_db_per_step () const;
+
+ bool _write_oe (int which_side, int value, int mask);
+ bool write_io (int which_side, int value, int mask);
+ bool read_io (int which_side, int *value);
+ int read_io (int which_side);
+ bool write_refclk(int which_side, int value);
+ bool write_atr_mask(int which_side, int value);
+ bool write_atr_txval(int which_side, int value);
+ bool write_atr_rxval(int which_side, int value);
+
+ bool write_aux_dac (int which_side, int which_dac, int value);
+ bool read_aux_adc (int which_side, int which_adc, int *value);
+ int read_aux_adc (int which_side, int which_adc);
- /*!
- * \brief returns current fusb block size
- */
int block_size() const;
- /*!
- * \brief Enable/disable automatic DC offset removal control loop in FPGA
- *
- * \param bits which control loops to enable
- * \param mask which \p bits to pay attention to
- *
- * If the corresponding bit is set, enable the automatic DC
- * offset correction control loop.
- *
- * <pre>
- * The 4 low bits are significant:
- *
- * ADC0 = (1 << 0)
- * ADC1 = (1 << 1)
- * ADC2 = (1 << 2)
- * ADC3 = (1 << 3)
- * </pre>
- *
- * By default the control loop is enabled on all ADC's.
- */
- bool set_dc_offset_cl_enable(int bits, int mask);
-
// called in base class to derived class order
bool start ();
bool stop ();
@@ -563,13 +873,13 @@ private:
bool d_tx_enable;
protected:
- int d_dbid[2]; // Tx daughterboard ID's
-
/*!
* \param which_board Which USRP board on usb (not particularly useful; use 0)
* \param fusb_block_size fast usb xfer block size. Must be a multiple of 512.
* Use zero for a reasonable default.
* \param fusb_nblocks number of fast usb URBs to allocate. Use zero for a reasonable default.
+ * \param fpga_filename name of file that contains image to load into FPGA
+ * \param firmware_filename name of file that contains image to load into FX2
*/
usrp_basic_tx (int which_board,
int fusb_block_size=0,
@@ -585,7 +895,6 @@ private:
void restore_tx (bool on); // conditional set
void probe_tx_slots (bool verbose);
- int dboard_to_slot (int dboard) { return (dboard << 1) | 0; }
public:
@@ -598,14 +907,14 @@ public:
* \param fusb_block_size fast usb xfer block size. Must be a multiple of 512.
* Use zero for a reasonable default.
* \param fusb_nblocks number of fast usb URBs to allocate. Use zero for a reasonable default.
+ * \param fpga_filename name of file that contains image to load into FPGA
+ * \param firmware_filename name of file that contains image to load into FX2
*/
static usrp_basic_tx *make (int which_board, int fusb_block_size=0, int fusb_nblocks=0,
const std::string fpga_filename = "",
const std::string firmware_filename = ""
);
- // MANIPULATORS
-
/*!
* \brief tell the fpga the rate tx samples are going to the D/A's
*
@@ -634,138 +943,30 @@ public:
*/
void wait_for_completion ();
- // ACCESSORS
-
//! sampling rate of D/A converter
virtual long converter_rate() const { return fpga_master_clock_freq () * 2; } // 128M
long dac_rate() const { return converter_rate(); }
- long dac_freq() const { return converter_rate(); } //!< deprecated method name
-
- /*!
- * \brief Return daughterboard ID for given Tx daughterboard slot [0,1].
- *
- * \return daughterboard id >= 0 if successful
- * \return -1 if no daugherboard
- * \return -2 if invalid EEPROM on daughterboard
- */
- int daughterboard_id (int which_dboard) const { return d_dbid[which_dboard & 0x1]; }
-
- // ----------------------------------------------------------------
- // routines for controlling the Programmable Gain Amplifier
- /*!
- * \brief Set Programmable Gain Amplifier (PGA)
- *
- * \param which which D/A [0,3]
- * \param gain_in_db gain value (linear in dB)
- *
- * gain is rounded to closest setting supported by hardware.
- * Note that DAC 0 and DAC 1 share a gain setting as do DAC 2 and DAC 3.
- * Setting DAC 0 affects DAC 1 and vice versa. Same with DAC 2 and DAC 3.
- *
- * \returns true iff sucessful.
- *
- * \sa pga_min(), pga_max(), pga_db_per_step()
- */
- bool set_pga (int which, double gain_in_db);
-
- /*!
- * \brief Return programmable gain amplifier gain in dB.
- *
- * \param which which D/A [0,3]
- */
- double pga (int which) const;
-
- /*!
- * \brief Return minimum legal PGA gain in dB.
- */
- double pga_min () const { return -20.0; }
+ int daughterboard_id (int which_side) const { return d_dbid[which_side & 0x1]; }
+
+ bool set_pga (int which_amp, double gain_in_db);
+ double pga (int which_amp) const;
+ double pga_min () const;
+ double pga_max () const;
+ double pga_db_per_step () const;
+
+ bool _write_oe (int which_side, int value, int mask);
+ bool write_io (int which_side, int value, int mask);
+ bool read_io (int which_side, int *value);
+ int read_io (int which_side);
+ bool write_refclk(int which_side, int value);
+ bool write_atr_mask(int which_side, int value);
+ bool write_atr_txval(int which_side, int value);
+ bool write_atr_rxval(int which_side, int value);
+
+ bool write_aux_dac (int which_side, int which_dac, int value);
+ bool read_aux_adc (int which_side, int which_adc, int *value);
+ int read_aux_adc (int which_side, int which_adc);
- /*!
- * \brief Return maximum legal PGA gain in dB.
- */
- double pga_max () const { return 0.0; }
-
- /*!
- * \brief Return hardware step size of PGA (linear in dB).
- */
- double pga_db_per_step () const { return 20.0/255; }
-
- /*!
- * \brief Write direction register (output enables) for pins that go to daughterboard.
- *
- * \param which_dboard [0,1] which d'board
- * \param value value to write into register
- * \param mask which bits of value to write into reg
- *
- * Each d'board has 16-bits of general purpose i/o.
- * Setting the bit makes it an output from the FPGA to the d'board.
- *
- * This register is initialized based on a value stored in the
- * d'board EEPROM. In general, you shouldn't be using this routine
- * without a very good reason. Using this method incorrectly will
- * kill your USRP motherboard and/or daughterboard.
- */
- bool _write_oe (int which_dboard, int value, int mask);
-
- /*!
- * \brief Write daughterboard i/o pin value
- *
- * \param which_dboard [0,1] which d'board
- * \param value value to write into register
- * \param mask which bits of value to write into reg
- */
- bool write_io (int which_dboard, int value, int mask);
-
- /*!
- * \brief Read daughterboard i/o pin value
- *
- * \param which_dboard [0,1] which d'board
- * \param value return value
- */
- bool read_io (int which_dboard, int *value);
-
- /*!
- * \brief Read daughterboard i/o pin value
- *
- * \param which_dboard [0,1] which d'board
- * \returns register value if successful, else READ_FAILED
- */
- int read_io (int which_dboard);
-
- /*!
- * \brief Write auxiliary digital to analog converter.
- *
- * \param which_dboard [0,1] which d'board
- * N.B., SLOT_TX_A and SLOT_RX_A share the same AUX DAC's.
- * SLOT_TX_B and SLOT_RX_B share the same AUX DAC's.
- * \param which_dac [2,3] TX slots must use only 2 and 3.
- * \param value [0,4095]
- * \returns true iff successful
- */
- bool write_aux_dac (int which_board, int which_dac, int value);
-
- /*!
- * \brief Read auxiliary analog to digital converter.
- *
- * \param which_dboard [0,1] which d'board
- * \param which_adc [0,1]
- * \param value return 12-bit value [0,4095]
- * \returns true iff successful
- */
- bool read_aux_adc (int which_dboard, int which_adc, int *value);
-
- /*!
- * \brief Read auxiliary analog to digital converter.
- *
- * \param which_dboard [0,1] which d'board
- * \param which_adc [0,1]
- * \returns value in the range [0,4095] if successful, else READ_FAILED.
- */
- int read_aux_adc (int which_dboard, int which_adc);
-
- /*!
- * \brief returns current fusb block size
- */
int block_size() const;
// called in base class to derived class order
diff --git a/usrp/host/lib/legacy/usrp_standard.cc b/usrp/host/lib/legacy/usrp_standard.cc
index 768a8f24e6..d27bbbec3b 100644
--- a/usrp/host/lib/legacy/usrp_standard.cc
+++ b/usrp/host/lib/legacy/usrp_standard.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2008 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -44,6 +44,168 @@ using namespace ad9862;
#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+void
+usrp_standard_common::calc_dxc_freq(double target_freq, double baseband_freq, double fs,
+ double *dxc_freq, bool *inverted)
+{
+ /*
+ Calculate the frequency to use for setting the digital up or down converter.
+
+ @param target_freq: desired RF frequency (Hz)
+ @param baseband_freq: the RF frequency that corresponds to DC in the IF.
+ @param fs: converter sample rate
+
+ @returns: 2-tuple (ddc_freq, inverted) where ddc_freq is the value
+ for the ddc and inverted is True if we're operating in an inverted
+ Nyquist zone.
+ */
+
+#if 0
+ printf("calc_dxc_freq:\n");
+ printf(" target = %f\n", target_freq);
+ printf(" baseband = %f\n", baseband_freq);
+ printf(" fs = %f\n", fs);
+#endif
+
+ double delta = target_freq - baseband_freq;
+
+ if(delta >= 0) {
+ while(delta > fs) {
+ delta -= fs;
+ }
+ if(delta <= fs/2) { // non-inverted region
+ *dxc_freq = -delta;
+ *inverted = false;
+ }
+ else { // inverted region
+ *dxc_freq = delta - fs;
+ *inverted = true;
+ }
+ }
+ else {
+ while(delta < -fs) {
+ delta += fs;
+ }
+ if(delta >= -fs/2) {
+ *dxc_freq = -delta; // non-inverted region
+ *inverted = false;
+ }
+ else { // inverted region
+ *dxc_freq = delta + fs;
+ *inverted = true;
+ }
+ }
+
+#if 0
+ printf(" dxc_freq = %f\n", *dxc_freq);
+ printf(" inverted = %s\n", *inverted ? "true" : "false");
+#endif
+}
+
+
+/*
+ * Real lambda expressions would be _so_ much easier...
+ */
+class dxc_control {
+public:
+ virtual bool is_tx() = 0;
+ virtual bool set_dxc_freq(double dxc_freq) = 0;
+ virtual double dxc_freq() = 0;
+};
+
+class ddc_control : public dxc_control {
+ usrp_standard_rx *d_u;
+ int d_chan;
+
+public:
+ ddc_control(usrp_standard_rx *u, int chan)
+ : d_u(u), d_chan(chan) {}
+
+ bool is_tx(){ return false; }
+ bool set_dxc_freq(double dxc_freq){ return d_u->set_rx_freq(d_chan, dxc_freq); }
+ double dxc_freq(){ return d_u->rx_freq(d_chan); }
+};
+
+class duc_control : public dxc_control {
+ usrp_standard_tx *d_u;
+ int d_chan;
+
+public:
+ duc_control(usrp_standard_tx *u, int chan)
+ : d_u(u), d_chan(chan) {}
+
+ bool is_tx(){ return true; }
+ bool set_dxc_freq(double dxc_freq){ return d_u->set_tx_freq(d_chan, dxc_freq); }
+ double dxc_freq() { return d_u->tx_freq(d_chan); }
+};
+
+
+/*!
+ * \brief Tune such that target_frequency ends up at DC in the complex baseband
+ *
+ * \param db the daughterboard to use
+ * \param target_freq the center frequency we want at baseband (DC)
+ * \param fs the sample rate
+ * \param dxc DDC or DUC access and control object
+ * \param[out] result details of what we did
+ *
+ * \returns true iff operation was successful
+ *
+ * Tuning is a two step process. First we ask the front-end to
+ * tune as close to the desired frequency as it can. Then we use
+ * the result of that operation and our target_frequency to
+ * determine the value for the digital down converter.
+ */
+static bool
+tune_a_helper(db_base_sptr db, double target_freq, double fs,
+ dxc_control &dxc, usrp_tune_result *result)
+{
+ bool inverted = false;
+ double dxc_freq;
+ double actual_dxc_freq;
+
+ // Ask the d'board to tune as closely as it can to target_freq
+#if 0
+ bool ok = db->set_freq(target_freq, &result->baseband_freq);
+#else
+ bool ok;
+ {
+ freq_result_t fr = db->set_freq(target_freq);
+ ok = fr.ok;
+ result->baseband_freq = fr.baseband_freq;
+ }
+#endif
+
+ // Calculate the DDC setting that will downconvert the baseband from the
+ // daughterboard to our target frequency.
+ usrp_standard_common::calc_dxc_freq(target_freq, result->baseband_freq, fs,
+ &dxc_freq, &inverted);
+
+ // If the spectrum is inverted, and the daughterboard doesn't do
+ // quadrature downconversion, we can fix the inversion by flipping the
+ // sign of the dxc_freq... (This only happens using the basic_rx board)
+
+ if(db->spectrum_inverted())
+ inverted = !inverted;
+
+ if(inverted && !db->is_quadrature()){
+ dxc_freq = -dxc_freq;
+ inverted = !inverted;
+ }
+
+ if (dxc.is_tx()) // down conversion versus up conversion
+ dxc_freq = -dxc_freq;
+
+ ok &= dxc.set_dxc_freq(dxc_freq);
+ actual_dxc_freq = dxc.dxc_freq();
+
+ result->dxc_freq = dxc_freq;
+ result->residual_freq = dxc_freq - actual_dxc_freq;
+ result->inverted = inverted;
+ return ok;
+}
+
+
static unsigned int
compute_freq_control_word_fpga (double master_freq, double target_freq,
double *actual_freq, bool verbose)
@@ -210,7 +372,7 @@ usrp_standard_rx::stop ()
return ok;
}
-usrp_standard_rx *
+usrp_standard_rx_sptr
usrp_standard_rx::make (int which_board,
unsigned int decim_rate,
int nchan, int mux, int mode,
@@ -219,21 +381,18 @@ usrp_standard_rx::make (int which_board,
const std::string firmware_filename
)
{
- usrp_standard_rx *u = 0;
-
try {
- u = new usrp_standard_rx (which_board, decim_rate,
- nchan, mux, mode,
- fusb_block_size, fusb_nblocks,
- fpga_filename, firmware_filename);
+ usrp_standard_rx_sptr u =
+ usrp_standard_rx_sptr(new usrp_standard_rx(which_board, decim_rate,
+ nchan, mux, mode,
+ fusb_block_size, fusb_nblocks,
+ fpga_filename, firmware_filename));
+ u->init_db(u);
return u;
}
catch (...){
- delete u;
- return 0;
+ return usrp_standard_rx_sptr();
}
-
- return u;
}
bool
@@ -371,6 +530,112 @@ usrp_standard_rx::write_hw_mux_reg ()
return ok;
}
+int
+usrp_standard_rx::determine_rx_mux_value(const usrp_subdev_spec &ss)
+{
+ /*
+ Determine appropriate Rx mux value as a function of the subdevice choosen and the
+ characteristics of the respective daughterboard.
+
+ @param u: instance of USRP source
+ @param subdev_spec: return value from subdev option parser.
+ @type subdev_spec: (side, subdev), where side is 0 or 1 and subdev is 0 or 1
+ @returns: the Rx mux value
+
+ Figure out which A/D's to connect to the DDC.
+
+ Each daughterboard consists of 1 or 2 subdevices. (At this time,
+ all but the Basic Rx have a single subdevice. The Basic Rx
+ has two independent channels, treated as separate subdevices).
+ subdevice 0 of a daughterboard may use 1 or 2 A/D's. We determine this
+ by checking the is_quadrature() method. If subdevice 0 uses only a single
+ A/D, it's possible that the daughterboard has a second subdevice, subdevice 1,
+ and it uses the second A/D.
+
+ If the card uses only a single A/D, we wire a zero into the DDC Q input.
+
+ (side, 0) says connect only the A/D's used by subdevice 0 to the DDC.
+ (side, 1) says connect only the A/D's used by subdevice 1 to the DDC.
+ */
+
+ struct truth_table_element
+ {
+ int d_side;
+ int d_uses;
+ bool d_swap_iq;
+ unsigned int d_mux_val;
+
+ truth_table_element(int side, unsigned int uses, bool swap_iq, unsigned int mux_val=0)
+ : d_side(side), d_uses(uses), d_swap_iq(swap_iq), d_mux_val(mux_val){}
+
+ bool operator==(const truth_table_element &in)
+ {
+ return (d_side == in.d_side && d_uses == in.d_uses && d_swap_iq == in.d_swap_iq);
+ }
+
+ unsigned int mux_val() { return d_mux_val; }
+ };
+
+
+ if (!is_valid(ss))
+ throw std::invalid_argument("subdev_spec");
+
+
+ // This is a tuple of length 1 or 2 containing the subdevice
+ // classes for the selected side.
+ std::vector<db_base_sptr> db = this->db(ss.side);
+
+ unsigned int subdev0_uses, subdev1_uses, uses;
+
+ // compute bitmasks of used A/D's
+
+ if(db[0]->is_quadrature())
+ subdev0_uses = 0x3; // uses A/D 0 and 1
+ else
+ subdev0_uses = 0x1; // uses A/D 0 only
+
+ if(db.size() > 1) // more than 1 subdevice?
+ subdev1_uses = 0x2; // uses A/D 1 only
+ else
+ subdev1_uses = 0x0; // uses no A/D (doesn't exist)
+
+ if(ss.subdev == 0)
+ uses = subdev0_uses;
+ else if(ss.subdev == 1)
+ uses = subdev1_uses;
+ else
+ throw std::invalid_argument("subdev_spec");
+
+ if(uses == 0){
+ throw std::runtime_error("Daughterboard doesn't have a subdevice 1");
+ }
+
+ bool swap_iq = db[0]->i_and_q_swapped();
+
+ truth_table_element truth_table[8] = {
+ // (side, uses, swap_iq) : mux_val
+ truth_table_element(0, 0x1, false, 0xf0f0f0f0),
+ truth_table_element(0, 0x2, false, 0xf0f0f0f1),
+ truth_table_element(0, 0x3, false, 0x00000010),
+ truth_table_element(0, 0x3, true, 0x00000001),
+ truth_table_element(1, 0x1, false, 0xf0f0f0f2),
+ truth_table_element(1, 0x2, false, 0xf0f0f0f3),
+ truth_table_element(1, 0x3, false, 0x00000032),
+ truth_table_element(1, 0x3, true, 0x00000023)
+ };
+ size_t nelements = sizeof(truth_table)/sizeof(truth_table[0]);
+
+ truth_table_element target(ss.side, uses, swap_iq, 0);
+
+ size_t i;
+ for(i = 0; i < nelements; i++){
+ if (truth_table[i] == target)
+ return truth_table[i].mux_val();
+ }
+ throw std::runtime_error("internal error");
+}
+
+
bool
usrp_standard_rx::set_rx_freq (int channel, double freq)
@@ -379,7 +644,7 @@ usrp_standard_rx::set_rx_freq (int channel, double freq)
return false;
unsigned int v =
- compute_freq_control_word_fpga (adc_freq(),
+ compute_freq_control_word_fpga (adc_rate(),
freq, &d_rx_freq[channel],
d_verbose);
@@ -493,6 +758,14 @@ usrp_standard_rx::format_bypass_halfband(unsigned int format)
return (format & bmFR_RX_FORMAT_BYPASS_HB) != 0;
}
+bool
+usrp_standard_rx::tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result)
+{
+ ddc_control dxc(this, chan);
+ return tune_a_helper(db, target_freq, converter_rate(), dxc, result);
+}
+
+
//////////////////////////////////////////////////////////////////
@@ -589,7 +862,7 @@ usrp_standard_tx::stop ()
return ok;
}
-usrp_standard_tx *
+usrp_standard_tx_sptr
usrp_standard_tx::make (int which_board,
unsigned int interp_rate,
int nchan, int mux,
@@ -598,20 +871,17 @@ usrp_standard_tx::make (int which_board,
const std::string firmware_filename
)
{
- usrp_standard_tx *u = 0;
-
try {
- u = new usrp_standard_tx (which_board, interp_rate, nchan, mux,
- fusb_block_size, fusb_nblocks,
- fpga_filename, firmware_filename);
+ usrp_standard_tx_sptr u =
+ usrp_standard_tx_sptr(new usrp_standard_tx(which_board, interp_rate, nchan, mux,
+ fusb_block_size, fusb_nblocks,
+ fpga_filename, firmware_filename));
+ u->init_db(u);
return u;
}
catch (...){
- delete u;
- return 0;
+ return usrp_standard_tx_sptr();
}
-
- return u;
}
bool
@@ -668,6 +938,39 @@ usrp_standard_tx::write_hw_mux_reg ()
return ok;
}
+int
+usrp_standard_tx::determine_tx_mux_value(const usrp_subdev_spec &ss)
+{
+ /*
+ Determine appropriate Tx mux value as a function of the subdevice choosen.
+
+ @param u: instance of USRP source
+ @param subdev_spec: return value from subdev option parser.
+ @type subdev_spec: (side, subdev), where side is 0 or 1 and subdev is 0
+ @returns: the Rx mux value
+
+ This is simpler than the rx case. Either you want to talk
+ to side A or side B. If you want to talk to both sides at once,
+ determine the value manually.
+ */
+
+ if (!is_valid(ss))
+ throw std::invalid_argument("subdev_spec");
+
+ std::vector<db_base_sptr> db = this->db(ss.side);
+
+ if(db[0]->i_and_q_swapped()) {
+ unsigned int mask[2] = {0x0089, 0x8900};
+ return mask[ss.side];
+ }
+ else {
+ unsigned int mask[2] = {0x0098, 0x9800};
+ return mask[ss.side];
+ }
+}
+
+
+
#ifdef USE_FPGA_TX_CORDIC
bool
@@ -679,7 +982,7 @@ usrp_standard_tx::set_tx_freq (int channel, double freq)
// This assumes we're running the 4x on-chip interpolator.
unsigned int v =
- compute_freq_control_word_fpga (dac_freq () / 4,
+ compute_freq_control_word_fpga (dac_rate () / 4,
freq, &d_tx_freq[channel],
d_verbose);
@@ -700,17 +1003,17 @@ usrp_standard_tx::set_tx_freq (int channel, double freq)
coarse_mod_t cm;
double coarse;
- assert (dac_freq () == 128000000);
+ assert (dac_rate () == 128000000);
if (freq < -44e6) // too low
return false;
else if (freq < -24e6){ // [-44, -24)
cm = CM_NEG_FDAC_OVER_4;
- coarse = -dac_freq () / 4;
+ coarse = -dac_rate () / 4;
}
else if (freq < -8e6){ // [-24, -8)
cm = CM_NEG_FDAC_OVER_8;
- coarse = -dac_freq () / 8;
+ coarse = -dac_rate () / 8;
}
else if (freq < 8e6){ // [-8, 8)
cm = CM_OFF;
@@ -718,11 +1021,11 @@ usrp_standard_tx::set_tx_freq (int channel, double freq)
}
else if (freq < 24e6){ // [8, 24)
cm = CM_POS_FDAC_OVER_8;
- coarse = dac_freq () / 8;
+ coarse = dac_rate () / 8;
}
else if (freq <= 44e6){ // [24, 44]
cm = CM_POS_FDAC_OVER_4;
- coarse = dac_freq () / 4;
+ coarse = dac_rate () / 4;
}
else // too high
return false;
@@ -738,7 +1041,7 @@ usrp_standard_tx::set_tx_freq (int channel, double freq)
// (This is required to use the fine modulator.)
unsigned int v =
- compute_freq_control_word_9862 (dac_freq () / 4,
+ compute_freq_control_word_9862 (dac_rate () / 4,
fine, &d_tx_freq[channel], d_verbose);
d_tx_freq[channel] += coarse; // adjust actual
@@ -837,3 +1140,10 @@ usrp_standard_tx::coarse_modulator (int channel) const
return d_coarse_mod[channel];
}
+
+bool
+usrp_standard_tx::tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result)
+{
+ duc_control dxc(this, chan);
+ return tune_a_helper(db, target_freq, converter_rate(), dxc, result);
+}
diff --git a/usrp/host/lib/legacy/usrp_standard.h b/usrp/host/lib/legacy/usrp_standard.h
index 93a8aa56d9..b7145b843f 100644
--- a/usrp/host/lib/legacy/usrp_standard.h
+++ b/usrp/host/lib/legacy/usrp_standard.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2008 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -24,10 +24,18 @@
#define INCLUDED_USRP_STANDARD_H
#include <usrp_basic.h>
+#include <boost/shared_ptr.hpp>
+#include <usrp_tune_result.h>
+
+class usrp_standard_tx;
+class usrp_standard_rx;
+
+typedef boost::shared_ptr<usrp_standard_tx> usrp_standard_tx_sptr;
+typedef boost::shared_ptr<usrp_standard_rx> usrp_standard_rx_sptr;
class usrp_standard_common
{
- int d_fpga_caps; // capability register val
+ int d_fpga_caps; // capability register val
protected:
usrp_standard_common(usrp_basic *parent);
@@ -56,6 +64,18 @@ public:
* This will be 0, 1, or 2.
*/
int nducs() const;
+
+ /*!
+ * \brief Calculate the frequency to use for setting the digital up or down converter.
+ *
+ * \param target_freq is the desired RF frequency (Hz).
+ * \param baseband_freq is the RF frequency that corresponds to DC in the IF coming from the d'board.
+ * \param fs is the sampling frequency.
+ * \param[out] dxc_freq the frequency to program into the DDC (or DUC).
+ * \param[out] inverted is true if we're operating in an inverted Nyquist zone.
+ */
+ static void calc_dxc_freq(double target_freq, double baseband_freq, double fs,
+ double *dxc_freq, bool *inverted);
};
/*!
@@ -63,7 +83,7 @@ public:
*
* Assumes digital down converter in FPGA
*/
-class usrp_standard_rx : public usrp_basic_rx, usrp_standard_common
+class usrp_standard_rx : public usrp_basic_rx, public usrp_standard_common
{
private:
static const int MAX_CHAN = 4;
@@ -99,23 +119,23 @@ class usrp_standard_rx : public usrp_basic_rx, usrp_standard_common
~usrp_standard_rx ();
/*!
- * \brief invokes constructor, returns instance or 0 if trouble
+ * \brief invokes constructor, returns shared_ptr or shared_ptr equivalent of 0 if trouble
*
* \param which_board Which USRP board on usb (not particularly useful; use 0)
* \param fusb_block_size fast usb xfer block size. Must be a multiple of 512.
* Use zero for a reasonable default.
* \param fusb_nblocks number of fast usb URBs to allocate. Use zero for a reasonable default.
*/
- static usrp_standard_rx *make (int which_board,
- unsigned int decim_rate,
- int nchan = 1,
- int mux = -1,
- int mode = 0,
- int fusb_block_size = 0,
- int fusb_nblocks = 0,
- const std::string fpga_filename = "",
- const std::string firmware_filename = ""
- );
+ static usrp_standard_rx_sptr make(int which_board,
+ unsigned int decim_rate,
+ int nchan = 1,
+ int mux = -1,
+ int mode = 0,
+ int fusb_block_size = 0,
+ int fusb_nblocks = 0,
+ const std::string fpga_filename = "",
+ const std::string firmware_filename = ""
+ );
/*!
* \brief Set decimator rate. \p rate MUST BE EVEN and in [8, 256].
*
@@ -155,6 +175,12 @@ class usrp_standard_rx : public usrp_basic_rx, usrp_standard_common
bool set_mux (int mux);
/*!
+ * Determine the appropriate Rx mux value as a function of the subdevice choosen
+ * and the characteristics of the respective daughterboard.
+ */
+ int determine_rx_mux_value(const usrp_subdev_spec &ss);
+
+ /*!
* \brief set the frequency of the digital down converter.
*
* \p channel must be in the range [0,3]. \p freq is the center
@@ -214,6 +240,22 @@ class usrp_standard_rx : public usrp_basic_rx, usrp_standard_common
static bool format_want_q(unsigned int format);
static bool format_bypass_halfband(unsigned int format);
+ /*!
+ * \brief High-level "tune" method. Works for the single channel case.
+ *
+ * This method adjusts both the daughterboard LO and the DDC so that
+ * target_freq ends up at DC in the complex baseband samples.
+ *
+ * \param chan which DDC channel we're controlling (almost always 0).
+ * \param db the daughterboard we're controlling.
+ * \param target_freq the RF frequency we want at DC in the complex baseband.
+ * \param[out] tune_result details how the hardware was configured.
+ *
+ * \returns true iff everything was successful.
+ */
+ bool tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result);
+
+
// ACCESSORS
unsigned int decim_rate () const;
double rx_freq (int channel) const;
@@ -233,7 +275,7 @@ class usrp_standard_rx : public usrp_basic_rx, usrp_standard_common
*
* Uses digital upconverter (coarse & fine modulators) in AD9862...
*/
-class usrp_standard_tx : public usrp_basic_tx, usrp_standard_common
+class usrp_standard_tx : public usrp_basic_tx, public usrp_standard_common
{
public:
enum coarse_mod_t {
@@ -274,22 +316,22 @@ class usrp_standard_tx : public usrp_basic_tx, usrp_standard_common
~usrp_standard_tx ();
/*!
- * \brief invokes constructor, returns instance or 0 if trouble
+ * \brief invokes constructor, returns shared_ptr or shared_ptr equivalent of 0 if trouble
*
* \param which_board Which USRP board on usb (not particularly useful; use 0)
* \param fusb_block_size fast usb xfer block size. Must be a multiple of 512.
* Use zero for a reasonable default.
* \param fusb_nblocks number of fast usb URBs to allocate. Use zero for a reasonable default.
*/
- static usrp_standard_tx *make (int which_board,
- unsigned int interp_rate,
- int nchan = 1,
- int mux = -1,
- int fusb_block_size = 0,
- int fusb_nblocks = 0,
- const std::string fpga_filename = "",
- const std::string firmware_filename = ""
- );
+ static usrp_standard_tx_sptr make(int which_board,
+ unsigned int interp_rate,
+ int nchan = 1,
+ int mux = -1,
+ int fusb_block_size = 0,
+ int fusb_nblocks = 0,
+ const std::string fpga_filename = "",
+ const std::string firmware_filename = ""
+ );
/*!
* \brief Set interpolator rate. \p rate must be in [4, 512] and a multiple of 4.
@@ -343,6 +385,12 @@ class usrp_standard_tx : public usrp_basic_tx, usrp_standard_common
bool set_mux (int mux);
/*!
+ * Determine the appropriate Tx mux value as a function of the subdevice choosen
+ * and the characteristics of the respective daughterboard.
+ */
+ int determine_tx_mux_value(const usrp_subdev_spec &ss);
+
+ /*!
* \brief set the frequency of the digital up converter.
*
* \p channel must be in the range [0,1]. \p freq is the center
@@ -358,6 +406,22 @@ class usrp_standard_tx : public usrp_basic_tx, usrp_standard_common
int nchannels () const;
int mux () const;
+ /*!
+ * \brief High-level "tune" method. Works for the single channel case.
+ *
+ * This method adjusts both the daughterboard LO and the DUC so that
+ * DC in the complex baseband samples ends up at RF target_freq.
+ *
+ * \param chan which DUC channel we're controlling (usually == which_side).
+ * \param db the daughterboard we're controlling.
+ * \param target_freq the RF frequency we want our baseband translated to.
+ * \param[out] tune_result details how the hardware was configured.
+ *
+ * \returns true iff everything was successful.
+ */
+ bool tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result);
+
+
// called in base class to derived class order
bool start ();
bool stop ();
diff --git a/usrp/host/lib/legacy/usrp_subdev_spec.h b/usrp/host/lib/legacy/usrp_subdev_spec.h
new file mode 100644
index 0000000000..e841ff8322
--- /dev/null
+++ b/usrp/host/lib/legacy/usrp_subdev_spec.h
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_USRP_SUBDEV_SPEC_H
+#define INCLUDED_USRP_SUBDEV_SPEC_H
+
+/*!
+ * \brief specify a daughterboard and subdevice on a daughterboard.
+ *
+ * In the USRP1, there are two sides, A and B.
+ *
+ * A daughterboard generally implements a single subdevice, but may in
+ * general implement any number of subdevices. At this time, all daughterboards
+ * with the exception of the Basic Rx and LF Rx implement a single subdevice.
+ *
+ * The Basic Rx and LF Rx implement 2 subdevices (soon 3). Subdevice
+ * 0 routes input RX-A to the DDC I input and routes a constant zero
+ * to the DDC Q input. Similarly, subdevice 1 routes input RX-B to
+ * the DDC I input and routes a constant zero to the DDC Q
+ * input. Subdevice 2 (when implemented) will route RX-A to the DDC I
+ * input and RX-B to the DDC Q input.
+ */
+
+struct usrp_subdev_spec {
+ unsigned int side; // 0 -> A; 1 -> B
+ unsigned int subdev; // which subdevice (usually zero)
+
+ usrp_subdev_spec(unsigned int _side = 0, unsigned int _subdev = 0)
+ : side(_side), subdev(_subdev) {}
+};
+
+#endif /* INCLUDED_USRP_SUBDEV_SPEC_H */
diff --git a/usrp/host/lib/legacy/usrp_tune_result.h b/usrp/host/lib/legacy/usrp_tune_result.h
new file mode 100644
index 0000000000..200541a37b
--- /dev/null
+++ b/usrp/host/lib/legacy/usrp_tune_result.h
@@ -0,0 +1,44 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_USRP_TUNE_RESULT_H
+#define INCLUDED_USRP_TUNE_RESULT_H
+
+class usrp_tune_result
+{
+public:
+ // RF frequency that corresponds to DC in the IF
+ double baseband_freq;
+
+ // frequency programmed into the DDC/DUC
+ double dxc_freq;
+
+ // residual frequency (typically < 0.01 Hz)
+ double residual_freq;
+
+ // is the spectrum inverted?
+ bool inverted;
+
+ usrp_tune_result(double baseband=0, double dxc=0, double residual=0, bool _inverted=false)
+ : baseband_freq(baseband), dxc_freq(dxc),
+ residual_freq(residual), inverted(_inverted) {}
+};
+
+#endif /* INCLUDED_USRP_TUNE_RESULT_H */
diff --git a/usrp2/host/include/usrp2/tune_result.h b/usrp2/host/include/usrp2/tune_result.h
index 6fb2a68241..9075596f41 100644
--- a/usrp2/host/include/usrp2/tune_result.h
+++ b/usrp2/host/include/usrp2/tune_result.h
@@ -16,8 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef INCLUDED_TUNE_RESULT_H
-#define INCLUDED_TUNE_RESULT_H
+#ifndef INCLUDED_USRP2_TUNE_RESULT_H
+#define INCLUDED_USRP2_TUNE_RESULT_H
namespace usrp2 {
@@ -36,10 +36,11 @@ namespace usrp2 {
// is the spectrum inverted?
bool spectrum_inverted;
- tune_result()
- : baseband_freq(0), dxc_freq(0), residual_freq(0), spectrum_inverted(false) {}
+ tune_result(double baseband=0, double dxc=0, double residual=0, bool inverted=false)
+ : baseband_freq(baseband), dxc_freq(dxc),
+ residual_freq(residual), spectrum_inverted(inverted) {}
};
} // namespace usrp2
-#endif /* INCLUDED_TUNE_RESULT_H */
+#endif /* INCLUDED_USRP2_TUNE_RESULT_H */