Merged r11377:11390 from jcorgan/usrp-headers in to trunk.
authorjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Thu, 9 Jul 2009 02:55:51 +0000 (02:55 +0000)
committerjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Thu, 9 Jul 2009 02:55:51 +0000 (02:55 +0000)
* Public USRP(1) header files are now in their own source directory
  and install into $(includedir)/usrp.  This was done to avoid name
  clashes in the top-level include directory.

  Only users who are developing directly to libusrp in C++ are
  affected; the GNU Radio C++ and Python APIs are unchanged.

  The simple change required by this update is to change:

  #include <usrp_*.h>

  to #include

  <usrp/usrp_*.h>

  ...in your source code.

* Removed usrp-inband code from tree (put into limbo directory.)
  This code has become unmaintained and has started to suffer
  from bitrot.  A checkpoint tag has been made for anyone still
  needing to use it:

  http://gnuradio.org/svn/gnuradio/tags/checkpoints/trunk-20090708-pre-usrp-reorg

  The plan during the 3.2->3.3 development cycle is to replace the
  functions done by the in-band code with extensions to the existing
  gr-usrp blocks using the new message passing architecture.

  The USRP hardware FPGA code that provided the inband interface
  has not been removed; however, it too has become unmaintained and
  will likely be rewritten/replaced during the 3.3 timeframe.

The trunk passes distcheck.

git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@11394 221aa14e-8319-0410-a670-987f0aec2ac5

269 files changed:
Makefile.common
config/grc_usrp.m4
gnuradio-core/src/lib/io/gri_wavfile.cc
gr-usrp/apps/Makefile.am
gr-usrp/src/usrp_base.cc
gr-usrp/src/usrp_base.h
gr-usrp/src/usrp_sink_base.cc
gr-usrp/src/usrp_sink_base.h
gr-usrp/src/usrp_sink_c.cc
gr-usrp/src/usrp_sink_s.cc
gr-usrp/src/usrp_source_base.cc
gr-usrp/src/usrp_source_base.h
gr-usrp/src/usrp_source_c.cc
gr-usrp/src/usrp_source_s.cc
gr-usrp/src/usrp_standard.i
gr-usrp/src/usrp_swig.i
usrp/Makefile.am
usrp/firmware/include/Makefile.am
usrp/host/Makefile.am
usrp/host/apps-inband/Makefile.am [deleted file]
usrp/host/apps-inband/read_packets.cc [deleted file]
usrp/host/apps-inband/test_usrp_inband_2rx.cc [deleted file]
usrp/host/apps-inband/test_usrp_inband_2tx.cc [deleted file]
usrp/host/apps-inband/test_usrp_inband_overrun.cc [deleted file]
usrp/host/apps-inband/test_usrp_inband_ping.cc [deleted file]
usrp/host/apps-inband/test_usrp_inband_registers.cc [deleted file]
usrp/host/apps-inband/test_usrp_inband_rx.cc [deleted file]
usrp/host/apps-inband/test_usrp_inband_timestamps.cc [deleted file]
usrp/host/apps-inband/test_usrp_inband_tx.cc [deleted file]
usrp/host/apps-inband/test_usrp_inband_underrun.cc [deleted file]
usrp/host/apps-inband/ui_nco.h [deleted file]
usrp/host/apps-inband/ui_sincos.c [deleted file]
usrp/host/apps-inband/ui_sincos.h [deleted file]
usrp/host/apps/test_usrp_standard_rx.cc
usrp/host/apps/test_usrp_standard_tx.cc
usrp/host/apps/usrp_cal_dc_offset.cc
usrp/host/apps/usrper.cc
usrp/host/include/Makefile.am [new file with mode: 0644]
usrp/host/include/usrp/Makefile.am [new file with mode: 0644]
usrp/host/include/usrp/db_base.h [new file with mode: 0644]
usrp/host/include/usrp/db_base.i [new file with mode: 0644]
usrp/host/include/usrp/db_basic.h [new file with mode: 0644]
usrp/host/include/usrp/db_dbs_rx.h [new file with mode: 0644]
usrp/host/include/usrp/db_dtt754.h [new file with mode: 0644]
usrp/host/include/usrp/db_dtt768.h [new file with mode: 0644]
usrp/host/include/usrp/db_flexrf.h [new file with mode: 0644]
usrp/host/include/usrp/db_flexrf_mimo.h [new file with mode: 0644]
usrp/host/include/usrp/db_tv_rx.h [new file with mode: 0644]
usrp/host/include/usrp/db_xcvr2450.h [new file with mode: 0644]
usrp/host/include/usrp/usrp_basic.h [new file with mode: 0644]
usrp/host/include/usrp/usrp_bytesex.h [new file with mode: 0644]
usrp/host/include/usrp/usrp_local_sighandler.h [new file with mode: 0644]
usrp/host/include/usrp/usrp_prims.h [new file with mode: 0644]
usrp/host/include/usrp/usrp_slots.h [new file with mode: 0644]
usrp/host/include/usrp/usrp_standard.h [new file with mode: 0644]
usrp/host/include/usrp/usrp_subdev_spec.h [new file with mode: 0644]
usrp/host/include/usrp/usrp_tune_result.h [new file with mode: 0644]
usrp/host/lib/Makefile.am
usrp/host/lib/README_OSX [new file with mode: 0644]
usrp/host/lib/ad9862.h [new file with mode: 0644]
usrp/host/lib/check_data.py [new file with mode: 0755]
usrp/host/lib/circular_buffer.h [new file with mode: 0644]
usrp/host/lib/circular_linked_list.h [new file with mode: 0644]
usrp/host/lib/darwin_libusb.h [new file with mode: 0644]
usrp/host/lib/db_base.cc [new file with mode: 0644]
usrp/host/lib/db_base_impl.h [new file with mode: 0644]
usrp/host/lib/db_basic.cc [new file with mode: 0644]
usrp/host/lib/db_boards.cc [new file with mode: 0644]
usrp/host/lib/db_boards.h [new file with mode: 0644]
usrp/host/lib/db_dbs_rx.cc [new file with mode: 0644]
usrp/host/lib/db_dtt754.cc [new file with mode: 0644]
usrp/host/lib/db_dtt768.cc [new file with mode: 0644]
usrp/host/lib/db_flexrf.cc [new file with mode: 0644]
usrp/host/lib/db_flexrf_mimo.cc [new file with mode: 0644]
usrp/host/lib/db_tv_rx.cc [new file with mode: 0644]
usrp/host/lib/db_util.cc [new file with mode: 0644]
usrp/host/lib/db_util.h [new file with mode: 0644]
usrp/host/lib/db_xcvr2450.cc [new file with mode: 0644]
usrp/host/lib/dump_data.py [new file with mode: 0755]
usrp/host/lib/fusb.cc [new file with mode: 0644]
usrp/host/lib/fusb.h [new file with mode: 0644]
usrp/host/lib/fusb_darwin.cc [new file with mode: 0644]
usrp/host/lib/fusb_darwin.h [new file with mode: 0644]
usrp/host/lib/fusb_generic.cc [new file with mode: 0644]
usrp/host/lib/fusb_generic.h [new file with mode: 0644]
usrp/host/lib/fusb_linux.cc [new file with mode: 0644]
usrp/host/lib/fusb_linux.h [new file with mode: 0644]
usrp/host/lib/fusb_ra_wb.cc [new file with mode: 0644]
usrp/host/lib/fusb_ra_wb.h [new file with mode: 0644]
usrp/host/lib/fusb_sysconfig_darwin.cc [new file with mode: 0644]
usrp/host/lib/fusb_sysconfig_generic.cc [new file with mode: 0644]
usrp/host/lib/fusb_sysconfig_linux.cc [new file with mode: 0644]
usrp/host/lib/fusb_sysconfig_ra_wb.cc [new file with mode: 0644]
usrp/host/lib/fusb_sysconfig_win32.cc [new file with mode: 0644]
usrp/host/lib/fusb_win32.cc [new file with mode: 0644]
usrp/host/lib/fusb_win32.h [new file with mode: 0644]
usrp/host/lib/gen_usrp_dbid.py [new file with mode: 0755]
usrp/host/lib/inband/Makefile.am [deleted file]
usrp/host/lib/inband/dump_packets.py [deleted file]
usrp/host/lib/inband/gen_test_packets.py [deleted file]
usrp/host/lib/inband/qa_inband.cc [deleted file]
usrp/host/lib/inband/qa_inband.h [deleted file]
usrp/host/lib/inband/qa_inband_packet_prims.cc [deleted file]
usrp/host/lib/inband/qa_inband_packet_prims.h [deleted file]
usrp/host/lib/inband/qa_inband_usrp_server.cc [deleted file]
usrp/host/lib/inband/qa_inband_usrp_server.h [deleted file]
usrp/host/lib/inband/symbols_usrp_channel.h [deleted file]
usrp/host/lib/inband/symbols_usrp_interface_cs.h [deleted file]
usrp/host/lib/inband/symbols_usrp_low_level_cs.h [deleted file]
usrp/host/lib/inband/symbols_usrp_rx.h [deleted file]
usrp/host/lib/inband/symbols_usrp_rx_cs.h [deleted file]
usrp/host/lib/inband/symbols_usrp_server_cs.h [deleted file]
usrp/host/lib/inband/symbols_usrp_tx.h [deleted file]
usrp/host/lib/inband/symbols_usrp_tx_cs.h [deleted file]
usrp/host/lib/inband/test_inband.cc [deleted file]
usrp/host/lib/inband/usb_packet.py [deleted file]
usrp/host/lib/inband/usrp_inband_usb_packet.cc [deleted file]
usrp/host/lib/inband/usrp_inband_usb_packet.h [deleted file]
usrp/host/lib/inband/usrp_interface.mbh [deleted file]
usrp/host/lib/inband/usrp_rx.cc [deleted file]
usrp/host/lib/inband/usrp_rx.h [deleted file]
usrp/host/lib/inband/usrp_rx_stub.cc [deleted file]
usrp/host/lib/inband/usrp_rx_stub.h [deleted file]
usrp/host/lib/inband/usrp_server.cc [deleted file]
usrp/host/lib/inband/usrp_server.h [deleted file]
usrp/host/lib/inband/usrp_server.mbh [deleted file]
usrp/host/lib/inband/usrp_tx.cc [deleted file]
usrp/host/lib/inband/usrp_tx.h [deleted file]
usrp/host/lib/inband/usrp_tx_stub.cc [deleted file]
usrp/host/lib/inband/usrp_tx_stub.h [deleted file]
usrp/host/lib/inband/usrp_usb_interface.cc [deleted file]
usrp/host/lib/inband/usrp_usb_interface.h [deleted file]
usrp/host/lib/legacy/Makefile.am [deleted file]
usrp/host/lib/legacy/README_OSX [deleted file]
usrp/host/lib/legacy/ad9862.h [deleted file]
usrp/host/lib/legacy/check_data.py [deleted file]
usrp/host/lib/legacy/circular_buffer.h [deleted file]
usrp/host/lib/legacy/circular_linked_list.h [deleted file]
usrp/host/lib/legacy/darwin_libusb.h [deleted file]
usrp/host/lib/legacy/db_base.cc [deleted file]
usrp/host/lib/legacy/db_base.h [deleted file]
usrp/host/lib/legacy/db_base.i [deleted file]
usrp/host/lib/legacy/db_base_impl.h [deleted file]
usrp/host/lib/legacy/db_basic.cc [deleted file]
usrp/host/lib/legacy/db_basic.h [deleted file]
usrp/host/lib/legacy/db_boards.cc [deleted file]
usrp/host/lib/legacy/db_boards.h [deleted file]
usrp/host/lib/legacy/db_dbs_rx.cc [deleted file]
usrp/host/lib/legacy/db_dbs_rx.h [deleted file]
usrp/host/lib/legacy/db_dtt754.cc [deleted file]
usrp/host/lib/legacy/db_dtt754.h [deleted file]
usrp/host/lib/legacy/db_dtt768.cc [deleted file]
usrp/host/lib/legacy/db_dtt768.h [deleted file]
usrp/host/lib/legacy/db_flexrf.cc [deleted file]
usrp/host/lib/legacy/db_flexrf.h [deleted file]
usrp/host/lib/legacy/db_flexrf_mimo.cc [deleted file]
usrp/host/lib/legacy/db_flexrf_mimo.h [deleted file]
usrp/host/lib/legacy/db_tv_rx.cc [deleted file]
usrp/host/lib/legacy/db_tv_rx.h [deleted file]
usrp/host/lib/legacy/db_util.cc [deleted file]
usrp/host/lib/legacy/db_util.h [deleted file]
usrp/host/lib/legacy/db_wbx.cc [deleted file]
usrp/host/lib/legacy/db_wbx.h [deleted file]
usrp/host/lib/legacy/db_xcvr2450.cc [deleted file]
usrp/host/lib/legacy/db_xcvr2450.h [deleted file]
usrp/host/lib/legacy/dump_data.py [deleted file]
usrp/host/lib/legacy/fusb.cc [deleted file]
usrp/host/lib/legacy/fusb.h [deleted file]
usrp/host/lib/legacy/fusb_darwin.cc [deleted file]
usrp/host/lib/legacy/fusb_darwin.h [deleted file]
usrp/host/lib/legacy/fusb_generic.cc [deleted file]
usrp/host/lib/legacy/fusb_generic.h [deleted file]
usrp/host/lib/legacy/fusb_linux.cc [deleted file]
usrp/host/lib/legacy/fusb_linux.h [deleted file]
usrp/host/lib/legacy/fusb_ra_wb.cc [deleted file]
usrp/host/lib/legacy/fusb_ra_wb.h [deleted file]
usrp/host/lib/legacy/fusb_sysconfig_darwin.cc [deleted file]
usrp/host/lib/legacy/fusb_sysconfig_generic.cc [deleted file]
usrp/host/lib/legacy/fusb_sysconfig_linux.cc [deleted file]
usrp/host/lib/legacy/fusb_sysconfig_ra_wb.cc [deleted file]
usrp/host/lib/legacy/fusb_sysconfig_win32.cc [deleted file]
usrp/host/lib/legacy/fusb_win32.cc [deleted file]
usrp/host/lib/legacy/fusb_win32.h [deleted file]
usrp/host/lib/legacy/gen_usrp_dbid.py [deleted file]
usrp/host/lib/legacy/md5.c [deleted file]
usrp/host/lib/legacy/md5.h [deleted file]
usrp/host/lib/legacy/mld_threads.h [deleted file]
usrp/host/lib/legacy/rate_to_regval.h [deleted file]
usrp/host/lib/legacy/std_paths.h.in [deleted file]
usrp/host/lib/legacy/usrp_basic.cc [deleted file]
usrp/host/lib/legacy/usrp_basic.h [deleted file]
usrp/host/lib/legacy/usrp_bytesex.h [deleted file]
usrp/host/lib/legacy/usrp_config.cc [deleted file]
usrp/host/lib/legacy/usrp_config.h [deleted file]
usrp/host/lib/legacy/usrp_dbid.dat [deleted file]
usrp/host/lib/legacy/usrp_local_sighandler.cc [deleted file]
usrp/host/lib/legacy/usrp_local_sighandler.h [deleted file]
usrp/host/lib/legacy/usrp_prims.cc [deleted file]
usrp/host/lib/legacy/usrp_prims.h [deleted file]
usrp/host/lib/legacy/usrp_slots.h [deleted file]
usrp/host/lib/legacy/usrp_standard.cc [deleted file]
usrp/host/lib/legacy/usrp_standard.h [deleted file]
usrp/host/lib/legacy/usrp_subdev_spec.h [deleted file]
usrp/host/lib/legacy/usrp_tune_result.h [deleted file]
usrp/host/lib/limbo/db_wbx.cc [new file with mode: 0644]
usrp/host/lib/limbo/db_wbx.h [new file with mode: 0644]
usrp/host/lib/md5.c [new file with mode: 0644]
usrp/host/lib/md5.h [new file with mode: 0644]
usrp/host/lib/mld_threads.h [new file with mode: 0644]
usrp/host/lib/rate_to_regval.h [new file with mode: 0644]
usrp/host/lib/std_paths.h.in [new file with mode: 0644]
usrp/host/lib/usrp_basic.cc [new file with mode: 0644]
usrp/host/lib/usrp_config.cc [new file with mode: 0644]
usrp/host/lib/usrp_config.h [new file with mode: 0644]
usrp/host/lib/usrp_dbid.dat [new file with mode: 0644]
usrp/host/lib/usrp_local_sighandler.cc [new file with mode: 0644]
usrp/host/lib/usrp_prims.cc [new file with mode: 0644]
usrp/host/lib/usrp_standard.cc [new file with mode: 0644]
usrp/host/swig/usrp_prims.i
usrp/limbo/apps-inband/Makefile.am [new file with mode: 0644]
usrp/limbo/apps-inband/read_packets.cc [new file with mode: 0644]
usrp/limbo/apps-inband/test_usrp_inband_2rx.cc [new file with mode: 0644]
usrp/limbo/apps-inband/test_usrp_inband_2tx.cc [new file with mode: 0644]
usrp/limbo/apps-inband/test_usrp_inband_overrun.cc [new file with mode: 0644]
usrp/limbo/apps-inband/test_usrp_inband_ping.cc [new file with mode: 0644]
usrp/limbo/apps-inband/test_usrp_inband_registers.cc [new file with mode: 0644]
usrp/limbo/apps-inband/test_usrp_inband_rx.cc [new file with mode: 0644]
usrp/limbo/apps-inband/test_usrp_inband_timestamps.cc [new file with mode: 0644]
usrp/limbo/apps-inband/test_usrp_inband_tx.cc [new file with mode: 0644]
usrp/limbo/apps-inband/test_usrp_inband_underrun.cc [new file with mode: 0644]
usrp/limbo/apps-inband/ui_nco.h [new file with mode: 0644]
usrp/limbo/apps-inband/ui_sincos.c [new file with mode: 0644]
usrp/limbo/apps-inband/ui_sincos.h [new file with mode: 0644]
usrp/limbo/inband/Makefile.am [new file with mode: 0644]
usrp/limbo/inband/dump_packets.py [new file with mode: 0755]
usrp/limbo/inband/gen_test_packets.py [new file with mode: 0755]
usrp/limbo/inband/qa_inband.cc [new file with mode: 0644]
usrp/limbo/inband/qa_inband.h [new file with mode: 0644]
usrp/limbo/inband/qa_inband_packet_prims.cc [new file with mode: 0644]
usrp/limbo/inband/qa_inband_packet_prims.h [new file with mode: 0644]
usrp/limbo/inband/qa_inband_usrp_server.cc [new file with mode: 0644]
usrp/limbo/inband/qa_inband_usrp_server.h [new file with mode: 0644]
usrp/limbo/inband/symbols_usrp_channel.h [new file with mode: 0644]
usrp/limbo/inband/symbols_usrp_interface_cs.h [new file with mode: 0644]
usrp/limbo/inband/symbols_usrp_low_level_cs.h [new file with mode: 0644]
usrp/limbo/inband/symbols_usrp_rx.h [new file with mode: 0644]
usrp/limbo/inband/symbols_usrp_rx_cs.h [new file with mode: 0644]
usrp/limbo/inband/symbols_usrp_server_cs.h [new file with mode: 0644]
usrp/limbo/inband/symbols_usrp_tx.h [new file with mode: 0644]
usrp/limbo/inband/symbols_usrp_tx_cs.h [new file with mode: 0644]
usrp/limbo/inband/test_inband.cc [new file with mode: 0644]
usrp/limbo/inband/usb_packet.py [new file with mode: 0644]
usrp/limbo/inband/usrp_inband_usb_packet.cc [new file with mode: 0644]
usrp/limbo/inband/usrp_inband_usb_packet.h [new file with mode: 0644]
usrp/limbo/inband/usrp_interface.mbh [new file with mode: 0644]
usrp/limbo/inband/usrp_rx.cc [new file with mode: 0644]
usrp/limbo/inband/usrp_rx.h [new file with mode: 0644]
usrp/limbo/inband/usrp_rx_stub.cc [new file with mode: 0644]
usrp/limbo/inband/usrp_rx_stub.h [new file with mode: 0644]
usrp/limbo/inband/usrp_server.cc [new file with mode: 0644]
usrp/limbo/inband/usrp_server.h [new file with mode: 0644]
usrp/limbo/inband/usrp_server.mbh [new file with mode: 0644]
usrp/limbo/inband/usrp_tx.cc [new file with mode: 0644]
usrp/limbo/inband/usrp_tx.h [new file with mode: 0644]
usrp/limbo/inband/usrp_tx_stub.cc [new file with mode: 0644]
usrp/limbo/inband/usrp_tx_stub.h [new file with mode: 0644]
usrp/limbo/inband/usrp_usb_interface.cc [new file with mode: 0644]
usrp/limbo/inband/usrp_usb_interface.h [new file with mode: 0644]
usrp/usrp-inband.pc.in [deleted file]

index c0625c7cb24038e606e27f519bbee2c45b129848..14cbe26928141d7f40195f6ca32e59d8a1634944 100644 (file)
@@ -81,10 +81,6 @@ GRUEL_LA = @gruel_LA@
 USRP_INCLUDES = @usrp_INCLUDES@
 USRP_LA = @usrp_LA@
 
-# How to link in usrp-inband library from inside the tree
-USRP_INBAND_INCLUDES = @usrp_inband_INCLUDES@
-USRP_INBAND_LA = @usrp_inband_LA@
-
 # How to link the PMT library from inside the tree
 PMT_INCLUDES = @pmt_INCLUDES@
 PMT_LA = @pmt_LA@
index 3b8bb28f4e6bc004642e19579c3badf15a0271b7..14c646081c3fcfe8b813344c9a5df92a1086eb6f 100644 (file)
@@ -20,12 +20,10 @@ dnl Boston, MA 02110-1301, USA.
 AC_DEFUN([GRC_USRP],[
     GRC_ENABLE(usrp)
 
-    GRC_WITH(usrp, [GRC_WITH_PKG_CONFIG_CHECK(usrp-inband)])
+    GRC_WITH(usrp)
 
-    dnl Don't do usrp if omnithread, mblock, or pmt skipped
+    dnl Don't do usrp if omnithread skipped
     GRC_CHECK_DEPENDENCY(usrp, omnithread)
-    GRC_CHECK_DEPENDENCY(usrp, mblock)
-    GRC_CHECK_DEPENDENCY(usrp, pmt)
 
     dnl Make sure the fast usb technique is set, OS dependent.
     dnl This is always performed, since it puts out CLI flags.
@@ -46,9 +44,6 @@ AC_DEFUN([GRC_USRP],[
         AC_CHECK_FUNCS([getrusage sched_setscheduler pthread_setschedparam])
         AC_CHECK_FUNCS([sigaction snprintf])
 
-       dnl Don't do usrp if guile not available (inband requires it)
-       GRC_CHECK_GUILE(usrp)
-
        dnl Make sure libusb is installed; required for legacy USB
         USRP_LIBUSB([],[passed=no;AC_MSG_RESULT([Unable to find dependency libusb.])])
 
@@ -57,20 +52,14 @@ AC_DEFUN([GRC_USRP],[
     fi
     if test $passed != with; then
        dnl how and where to find INCLUDES and LA
-       usrp_INCLUDES="-I\${abs_top_srcdir}/usrp/host/lib/legacy \
-               -I\${abs_top_srcdir}/usrp/firmware/include \
-               -I\${abs_top_builddir}/usrp/host/lib/legacy"
-        usrp_LA="\${abs_top_builddir}/usrp/host/lib/legacy/libusrp.la"
-       usrp_inband_INCLUDES="-I\${abs_top_srcdir}/usrp/host/lib/inband"
-       usrp_inband_LA="\${abs_top_builddir}/usrp/host/lib/inband/libusrp-inband.la"
+       usrp_INCLUDES=" \
+               -I\${abs_top_srcdir}/usrp/host/include \
+               -I\${abs_top_builddir}/usrp/host/include \
+               -I\${abs_top_srcdir}/usrp/firmware/include"
+        usrp_LA="\${abs_top_builddir}/usrp/host/lib/libusrp.la"
     fi
 
-    dnl Include the usrp-inband INCLUDES and LA
-    AC_SUBST(usrp_inband_INCLUDES)
-    AC_SUBST(usrp_inband_LA)
-
-    dnl There are 2 pkg-config files (usrp, and usrp-inband); the one
-    dnl for usrp requires omnithread for Darwin only.  Create a variable
+    dnl There pkg-config file for usrp requires omnithread for Darwin only.  Create a variable
     dnl for just the usrp.pc.in case.
     case "$host_os" in
       darwin*)
@@ -85,20 +74,18 @@ AC_DEFUN([GRC_USRP],[
     AC_CONFIG_FILES([ \
        usrp/Makefile \
        usrp/usrp.pc \
-       usrp/usrp-inband.pc \
         usrp/usrp.iss \
         usrp/doc/Doxyfile \
         usrp/doc/Makefile \
         usrp/doc/other/Makefile \
         usrp/host/Makefile \
+       usrp/host/include/Makefile \
+       usrp/host/include/usrp/Makefile \
         usrp/host/misc/Makefile \
         usrp/host/lib/Makefile \
-        usrp/host/lib/inband/Makefile \
-        usrp/host/lib/legacy/Makefile \
-        usrp/host/lib/legacy/std_paths.h \
+        usrp/host/lib/std_paths.h \
         usrp/host/swig/Makefile \
         usrp/host/apps/Makefile \
-        usrp/host/apps-inband/Makefile \
         usrp/firmware/Makefile \
         usrp/firmware/include/Makefile \
         usrp/firmware/lib/Makefile \
index c1a2b7c7373f497318d8ea370bb63f99b69a2d74..b8375edc20354bcd49576cb083a18edc17b60ae1 100644 (file)
@@ -32,8 +32,7 @@
 
 // WAV files are always little-endian, so we need some byte switching macros
 
-// FIXME: These need to be refactored into a separate endianess header file
-// as they duplicate routines defined in usrp/host/lib/legacy/usrp_bytesex.h
+// FIXME: Use libgruel versions
 
 #ifdef WORDS_BIGENDIAN
 
index 824a48974779ef3f3f3cfabda9fb371b38c6886b..92938061f6e1062ecdd876431d6ef303c0a1ce01 100644 (file)
@@ -24,9 +24,7 @@ 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\${abs_top_builddir}/usrp/host/lib/legacy \
-        -I$(top_srcdir)/usrp/firmware/include \
+        $(USRP_INCLUDES) \
         $(WITH_INCLUDES)
 
 GR_USRP_LA=$(top_builddir)/gr-usrp/src/libgnuradio-usrp.la
index a4cf64ed736797c3261c32787646527f0b66dbdd..1d632a5673c406cfb3bcca160bf503b0c64ece39 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -23,7 +23,7 @@
 #include <config.h>
 #endif
 #include <usrp_base.h>
-#include <usrp_basic.h>
+#include <usrp/usrp_basic.h>
 
 class truth_table_element_t 
 {
index a914159e61e9c5cbe87b88b4fb68d0c8b75f7624..7947723fba27dfe65085e01005f5857b408265a3 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -24,8 +24,8 @@
 #include <gr_sync_block.h>
 #include <stdexcept>
 #include <boost/shared_ptr.hpp>
-#include <db_base.h>
-#include <usrp_subdev_spec.h>
+#include <usrp/db_base.h>
+#include <usrp/usrp_subdev_spec.h>
 
 class usrp_basic;
 
index cb65e02cd9f3c62020017f4c8128355540f06571..635d9345f019a30c330b1c90c5afef0406712cf5 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,7 +26,7 @@
 
 #include <usrp_sink_base.h>
 #include <gr_io_signature.h>
-#include <usrp_standard.h>
+#include <usrp/usrp_standard.h>
 #include <assert.h>
 #include <cstdio>
 
index b27813a42ad89fb1ac2fbc1a9904a374f03a7714..8d573af1b05214aad97fd27c2d6c31a5187197f9 100644 (file)
@@ -1,7 +1,7 @@
 
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2006,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,8 +26,8 @@
 
 #include <usrp_base.h>
 #include <stdexcept>
-#include <usrp_tune_result.h>
-#include <usrp_dbid.h>
+#include <usrp/usrp_tune_result.h>
+#include <usrp/usrp_dbid.h>
 
 class usrp_standard_tx;
 
index 363a113fc8afab4e3e8414a3e969f739e38675ab..40750b477d23360dd26b56138b36c649d30a7bad 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2004,2006,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,8 +26,8 @@
 
 #include <usrp_sink_c.h>
 #include <gr_io_signature.h>
-#include <usrp_standard.h>
-#include <usrp_bytesex.h>
+#include <usrp/usrp_standard.h>
+#include <usrp/usrp_bytesex.h>
 
 usrp_sink_c_sptr
 usrp_make_sink_c (int which_board,
index adbf3acbd9330dc2434f6909907c5f3830160456..1f51da24db293c9918489938159e3e096c658bd6 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2004,2006,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,8 +26,8 @@
 
 #include <usrp_sink_s.h>
 #include <gr_io_signature.h>
-#include <usrp_standard.h>
-#include <usrp_bytesex.h>
+#include <usrp/usrp_standard.h>
+#include <usrp/usrp_bytesex.h>
 
 usrp_sink_s_sptr
 usrp_make_sink_s (int which_board,
index 99efbcdda9f8e00cae7ababd8eccb745df091216..85bd9171545a6643c9e75cb253a62483be1891fb 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,7 +26,7 @@
 
 #include <usrp_source_base.h>
 #include <gr_io_signature.h>
-#include <usrp_standard.h>
+#include <usrp/usrp_standard.h>
 #include <assert.h>
 #include <cstdio>
 
index e1d091d893b006b47eec85de3cc08c8a4566d2db..4def48e24c058f0c9ad560b56c18bc7ccff69ec1 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -25,8 +25,8 @@
 
 #include <usrp_base.h>
 #include <stdexcept>
-#include <usrp_tune_result.h>
-#include <usrp_dbid.h>
+#include <usrp/usrp_tune_result.h>
+#include <usrp/usrp_dbid.h>
 
 class usrp_standard_rx;
 
index 71ca1e0d7c8fa65e86b133d82d5f499bcfd53590..26d95dc1b36c1a5a9611bc9158b0ac9854b1d6bb 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2004,2006,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,8 +26,8 @@
 
 #include <usrp_source_c.h>
 #include <gr_io_signature.h>
-#include <usrp_standard.h>
-#include <usrp_bytesex.h>
+#include <usrp/usrp_standard.h>
+#include <usrp/usrp_bytesex.h>
 
 static const int NBASIC_SAMPLES_PER_ITEM = 2;  // I & Q
 
index f20384599fe1f286fe072d5e1bee28f54d5bb2e5..88b8495d3679512f165491146c6b5055850ec10d 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2004,2006,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,8 +26,8 @@
 
 #include <usrp_source_s.h>
 #include <gr_io_signature.h>
-#include <usrp_standard.h>
-#include <usrp_bytesex.h>
+#include <usrp/usrp_standard.h>
+#include <usrp/usrp_bytesex.h>
 
 static const int NBASIC_SAMPLES_PER_ITEM = 1;
 
index 7d32cdf8137018b73f056832803b9b17070ff37a..61053bb3b20dab549752a08999830a8f9773218b 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 // FIXME: move to usrp/usrpm component
 
 %{
-#include <usrp_standard.h>
+#include <usrp/usrp_standard.h>
 #include <usrp_spi_defs.h>
-#include <usrp_dbid.h>
+#include <usrp/usrp_dbid.h>
 %}
 
 %include <usrp_spi_defs.h>
-%include <usrp_dbid.h>
+%include <usrp/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;
index f5841985dda59543b78f68621f8de8aa75f61bec..2a47877c3ceef3027218e1edba1c9390162f6e25 100644 (file)
@@ -26,8 +26,8 @@
 #include <vector>
 %}
 
-%include <usrp_subdev_spec.h>
-%include <db_base.i>
+%include <usrp/usrp_subdev_spec.h>
+%include <usrp/db_base.i>
 %include <fpga_regs_common.h>
 %include <fpga_regs_standard.h>
 %include "usrp_standard.i"
index 6f5abbd5a8b0c4fae91f1c618e2037279fee30b3..c3e529da9834f098a050e2b7864be0e7c2f29411 100644 (file)
@@ -21,7 +21,6 @@
 
 EXTRA_DIST = \
        usrp.pc.in \
-       usrp-inband.pc.in \
        usrp.iss.in \
        usrp.inf
 
@@ -29,6 +28,4 @@ SUBDIRS = host firmware fpga doc
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = \
-       usrp.pc \
-       usrp-inband.pc
-
+       usrp.pc
index 97ca60bf21ed40cd776680e659a8e9cb98bc6f52..e17726c07baa7a15111744ceadd7ed71b33f7a57 100644 (file)
@@ -19,7 +19,9 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-include_HEADERS =              \
+usrpincludedir = $(includedir)/usrp
+
+usrpinclude_HEADERS =          \
        usrp_i2c_addr.h         \
        usrp_spi_defs.h         \
        fpga_regs_common.h      \
index 514b835a9d98a020c099b614395488cb24a3eb78..aa94fbd6ec31cece1a4d84d949c516c352245735 100644 (file)
@@ -19,7 +19,7 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-SUBDIRS = misc lib apps apps-inband
+SUBDIRS = misc lib include apps
 
 if PYTHON
 SUBDIRS += swig
diff --git a/usrp/host/apps-inband/Makefile.am b/usrp/host/apps-inband/Makefile.am
deleted file mode 100644 (file)
index 0a44d81..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-#
-# Copyright 2003,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.
-# 
-
-include $(top_srcdir)/Makefile.common
-
-AM_CPPFLAGS =  \
-       $(DEFINES) $(OMNITHREAD_INCLUDES) $(PMT_INCLUDES) $(MBLOCK_INCLUDES) \
-       $(USRP_INCLUDES) $(USRP_INBAND_INCLUDES) $(BOOST_CPPFLAGS) \
-       $(CPPUNIT_INCLUDES) $(WITH_INCLUDES) -I$(top_srcdir)/mblock/src/lib
-
-
-bin_PROGRAMS =                         
-
-noinst_PROGRAMS =                      \
-       test_usrp_inband_ping           \
-       test_usrp_inband_registers      \
-       test_usrp_inband_rx             \
-       test_usrp_inband_2rx            \
-       test_usrp_inband_tx             \
-       test_usrp_inband_2tx            \
-       test_usrp_inband_timestamps     \
-       test_usrp_inband_overrun        \
-       test_usrp_inband_underrun       \
-       read_packets
-
-noinst_HEADERS =                       \
-       ui_nco.h                        \
-       ui_sincos.h     
-
-
-test_usrp_inband_ping_SOURCES  = test_usrp_inband_ping.cc 
-test_usrp_inband_ping_LDADD    = $(USRP_LA) $(USRP_INBAND_LA)
-
-test_usrp_inband_tx_SOURCES    = test_usrp_inband_tx.cc ui_sincos.c
-test_usrp_inband_tx_LDADD      = $(USRP_LA) $(USRP_INBAND_LA)
-
-test_usrp_inband_2tx_SOURCES   = test_usrp_inband_2tx.cc ui_sincos.c
-test_usrp_inband_2tx_LDADD     = $(USRP_LA) $(USRP_INBAND_LA)
-
-test_usrp_inband_timestamps_SOURCES    = test_usrp_inband_timestamps.cc ui_sincos.c
-test_usrp_inband_timestamps_LDADD      = $(USRP_LA) $(USRP_INBAND_LA)
-
-test_usrp_inband_registers_SOURCES     = test_usrp_inband_registers.cc ui_sincos.c
-test_usrp_inband_registers_LDADD       = $(USRP_LA) $(USRP_INBAND_LA)
-
-test_usrp_inband_overrun_SOURCES       = test_usrp_inband_overrun.cc
-test_usrp_inband_overrun_LDADD         = $(USRP_LA) $(USRP_INBAND_LA)
-
-test_usrp_inband_underrun_SOURCES      = test_usrp_inband_underrun.cc
-test_usrp_inband_underrun_LDADD        = $(USRP_LA) $(USRP_INBAND_LA)
-
-test_usrp_inband_rx_SOURCES    = test_usrp_inband_rx.cc ui_sincos.c
-test_usrp_inband_rx_LDADD      = $(USRP_LA) $(USRP_INBAND_LA)
-
-test_usrp_inband_2rx_SOURCES   = test_usrp_inband_2rx.cc ui_sincos.c
-test_usrp_inband_2rx_LDADD     = $(USRP_LA) $(USRP_INBAND_LA)
-
-read_packets_SOURCES = read_packets.cc
-read_packets_LDADD = $(USRP_LA) $(USRP_INBAND_LA)
diff --git a/usrp/host/apps-inband/read_packets.cc b/usrp/host/apps-inband/read_packets.cc
deleted file mode 100644 (file)
index 24a1e88..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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 <iostream>
-#include <usrp_inband_usb_packet.h>
-#include <mblock/class_registry.h>
-#include <vector>
-#include <usrp_usb_interface.h>
-#include <fstream>
-
-typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit easy
-
-int main(int argc, char *argv[]) {
-
-  if(argc !=2) {
-    std::cout << "Usage: ./read_packets <data_file>\n";
-    return -1;
-  }
-
-  std::ifstream infile;
-  std::ofstream outfile;  
-
-  unsigned int pkt_size = transport_pkt::max_pkt_size();
-  unsigned int pkt_num=0;
-
-  transport_pkt *pkt;
-  char pkt_data[pkt_size];          // allocate the number of bytes for a single packet
-
-  pkt = (transport_pkt *)pkt_data;  // makes operations cleaner to read
-
-  // Open the file and read the packets, dumping information
-  infile.open(argv[1], std::ios::binary|std::ios::in);
-  if(!infile.is_open())
-    exit(-1);
-
-  //outfile.open("dump.dat",std::ios::out|std::ios::binary);  
-
-  // read 1 packet in to the memory
-  infile.read(pkt_data, pkt_size);
-
-  while(!infile.eof()) {
-  
-    printf("Packet %u\n", pkt_num);
-
-    if(pkt->start_of_burst())
-      printf("\tstart of burst\n");
-      
-    if(pkt->end_of_burst())
-      printf("\tend of burst\n");
-    
-//    if(pkt->carrier_sense())
-//      printf("\tcarrier sense\n");
-
-    if(pkt->underrun())
-      printf("\tunderrun\n");
-    
-    if(pkt->overrun())
-      printf("\toverrun\n");
-
-    printf("\tchannel: \t0x%x\n", pkt->chan());
-    printf("\ttimestamp: \t0x%x\n", pkt->timestamp());
-    //printf("\ttimestamp: \t%u\n", pkt->timestamp());
-    printf("\tlength: \t%u\n", pkt->payload_len());
-    printf("\trssi: \t%u\n", pkt->rssi());
-
-    printf("\tpayload: \n");
-    for(int i=0; i < pkt->payload_len(); i++)
-    //for(int i=0; i < pkt->max_payload(); i++)
-    {
-      printf("\t%d\t0x%x\n", i, *(pkt->payload()+i));
-      //outfile.write((const char*)(pkt->payload()+i),1);
-      //printf("\t\t0x%x\n", pkt->payload()+i);
-
-    }
-    printf("\n\n");
-
-    pkt_num++;
-  
-    // read 1 packet in to the memory
-    infile.read(pkt_data, pkt_size);
-
-  }
-
-  infile.close();
-  //outfile.close();
-
-}
diff --git a/usrp/host/apps-inband/test_usrp_inband_2rx.cc b/usrp/host/apps-inband/test_usrp_inband_2rx.cc
deleted file mode 100644 (file)
index c210f19..0000000
+++ /dev/null
@@ -1,371 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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 <mblock/mblock.h>
-#include <mblock/runtime.h>
-#include <mb_runtime_nop.h>            // QA only
-#include <mblock/protocol_class.h>
-#include <mblock/exception.h>
-#include <mblock/msg_queue.h>
-#include <mblock/message.h>
-#include <mb_mblock_impl.h>
-#include <mblock/msg_accepter.h>
-#include <mblock/class_registry.h>
-#include <pmt.h>
-#include <stdio.h>
-#include <string.h>
-#include <iostream>
-#include <fstream>
-
-// Include the symbols needed for communication with USRP server
-#include <symbols_usrp_server_cs.h>
-#include <symbols_usrp_channel.h>
-#include <symbols_usrp_low_level_cs.h>
-#include <symbols_usrp_rx.h>
-
-static bool verbose = true;
-
-class test_usrp_rx : public mb_mblock
-{
-  mb_port_sptr         d_rx;
-  mb_port_sptr         d_cs;
-  pmt_t                d_rx_chan0, d_rx_chan1;
-
-  enum state_t {
-    INIT,
-    OPENING_USRP,
-    ALLOCATING_CHANNEL,
-    RECEIVING,
-    CLOSING_CHANNEL,
-    CLOSING_USRP,
-  };
-
-  state_t      d_state;
-
-  std::ofstream d_ofile;
-
-  long d_samples_recvd;
-  long d_samples_to_recv;
-
- public:
-  test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~test_usrp_rx();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void open_usrp();
-  void close_usrp();
-  void allocate_channel();
-  void send_packets();
-  void enter_receiving();
-  void build_and_send_next_frame();
-  void handle_response_recv_raw_samples(pmt_t invocation_handle);
-  void enter_closing_channel();
-};
-
-test_usrp_rx::test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg),
-    d_rx_chan0(PMT_NIL), d_rx_chan1(PMT_NIL),
-    d_samples_recvd(0),
-    d_samples_to_recv(20e6)
-{ 
-  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-  
-  // Pass a dictionary to usrp_server which specifies which interface to use, the stub or USRP
-  pmt_t usrp_dict = pmt_make_dict();
-  
-  // To test the application without a USRP
-  bool fake_usrp_p = false;
-  if(fake_usrp_p) {
-    pmt_dict_set(usrp_dict, 
-                 pmt_intern("fake-usrp"),
-                            PMT_T);
-  }
-
-  // Specify the RBF to use
-  pmt_dict_set(usrp_dict,
-               pmt_intern("rbf"),
-               pmt_intern("inband_2rxhb_2tx.rbf"));
-
-  pmt_dict_set(usrp_dict,
-               pmt_intern("decim-rx"),
-               pmt_from_long(64));
-
-  define_component("server", "usrp_server", usrp_dict);
-
-  connect("self", "rx0", "server", "rx0");
-  connect("self", "cs", "server", "cs");
-
-}
-
-test_usrp_rx::~test_usrp_rx()
-{
-}
-
-void
-test_usrp_rx::initial_transition()
-{
-  open_usrp();
-}
-
-void
-test_usrp_rx::handle_message(mb_message_sptr msg)
-{
-  pmt_t        event = msg->signal();
-  pmt_t data = msg->data();
-
-  pmt_t handle = PMT_F;
-  pmt_t status = PMT_F;
-  std::string error_msg;
-  
-  switch(d_state){
-    
-    //----------------------------- OPENING_USRP ----------------------------//
-    // We only expect a response from opening the USRP which should be succesful
-    // or failed.
-    case OPENING_USRP:
-      if (pmt_eq(event, s_response_open)){
-        status = pmt_nth(1, data);
-        if (pmt_eq(status, PMT_T)){
-          allocate_channel();
-          return;
-        }
-        else {
-          error_msg = "failed to open usrp:";
-          goto bail;
-        }
-      }
-      goto unhandled;
-      
-    //----------------------- ALLOCATING CHANNELS --------------------//
-    // Allocate an RX channel to perform the overrun test.
-    case ALLOCATING_CHANNEL:
-      if (pmt_eq(event, s_response_allocate_channel)){
-        status = pmt_nth(1, data);
-        if(pmt_eqv(d_rx_chan0, PMT_NIL))
-          d_rx_chan0 = pmt_nth(2, data);
-        else
-          d_rx_chan1 = pmt_nth(2, data);
-
-        if (pmt_eq(status, PMT_T) && !pmt_eqv(d_rx_chan1, PMT_NIL)){
-          enter_receiving();
-          return;
-        }
-        else if(pmt_eq(status, PMT_F)){
-          error_msg = "failed to allocate channel:";
-          goto bail;
-        }
-        return;
-      }
-      goto unhandled;
-
-    //--------------------------- RECEIVING ------------------------------//
-    // In the receiving state, we receive samples until the specified amount
-    // while counting the number of overruns.
-    case RECEIVING:
-      if (pmt_eq(event, s_response_recv_raw_samples)){
-        status = pmt_nth(1, data);
-
-        if (pmt_eq(status, PMT_T)){
-          handle_response_recv_raw_samples(data);
-          return;
-        }
-        else {
-          error_msg = "bad response-xmit-raw-frame:";
-          goto bail;
-        }
-      }
-      goto unhandled;
-    
-    //------------------------- CLOSING CHANNEL ----------------------------//
-    // Check deallocation response for the RX channel 
-    case CLOSING_CHANNEL:
-      if (pmt_eq(event, s_response_deallocate_channel)){
-        status = pmt_nth(1, data);
-
-        if (pmt_eq(status, PMT_T)){
-          close_usrp();
-          return;
-        }
-        else {
-          error_msg = "failed to deallocate channel:";
-          goto bail;
-        }
-      }
-
-      // Alternately, we ignore all response recv samples while waiting for the
-      // channel to actually close
-      if (pmt_eq(event, s_response_recv_raw_samples))
-        return;
-
-      goto unhandled;
-
-    //--------------------------- CLOSING USRP ------------------------------//
-    // Once we have received a successful USRP close response, we shutdown all
-    // mblocks and exit.
-    case CLOSING_USRP:
-      if (pmt_eq(event, s_response_close)){
-        status = pmt_nth(1, data);
-
-        if (pmt_eq(status, PMT_T)){
-          fflush(stdout);
-          shutdown_all(PMT_T);
-          return;
-        }
-        else {
-          error_msg = "failed to close USRP:";
-          goto bail;
-        }
-      }
-      goto unhandled;
-
-    default:
-      goto unhandled;
-  }
-  return;
-
- // An error occured, print it, and shutdown all m-blocks
- bail:
-  std::cerr << error_msg << data
-           << "status = " << status << std::endl;
-  shutdown_all(PMT_F);
-  return;
-
- // Received an unhandled message for a specific state
- unhandled:
-  if(verbose && !pmt_eq(event, pmt_intern("%shutdown")))
-    std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
-              << "in state "<< d_state << std::endl;
-}
-
-
-void
-test_usrp_rx::open_usrp()
-{
-  pmt_t which_usrp = pmt_from_long(0);
-
-  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
-  d_state = OPENING_USRP;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_RX] Opening the USRP\n";
-}
-
-void
-test_usrp_rx::close_usrp()
-{
-
-  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
-  d_state = CLOSING_USRP;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_RX] Closing the USRP\n";
-}
-
-void
-test_usrp_rx::allocate_channel()
-{
-  long capacity = (long) 16e6;
-  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-  d_state = ALLOCATING_CHANNEL;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_RX] Requesting RX channel allocation\n";
-}
-
-void
-test_usrp_rx::enter_receiving()
-{
-  d_state = RECEIVING;
-
-  d_rx->send(s_cmd_start_recv_raw_samples,
-             pmt_list2(PMT_F,
-                       d_rx_chan0));
-  
-  d_rx->send(s_cmd_start_recv_raw_samples,
-             pmt_list2(PMT_F,
-                       d_rx_chan1));
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_RX] Receiving...\n";
-}
-
-void
-test_usrp_rx::handle_response_recv_raw_samples(pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  pmt_t status = pmt_nth(1, data);
-  pmt_t v_samples = pmt_nth(2, data);
-  pmt_t timestamp = pmt_nth(3, data);
-  pmt_t channel = pmt_nth(4, data);
-  pmt_t properties = pmt_nth(5, data);
-
-  d_samples_recvd += pmt_length(v_samples) / 4;
-
-  // Check for overrun
-  if(!pmt_is_dict(properties)) {
-    std::cout << "[TEST_USRP_INBAND_RX] Recv samples dictionary is improper\n";
-    return;
-  }
-
-  // Check if the number samples we have received meets the test
-  if(d_samples_recvd >= d_samples_to_recv) {
-    d_rx->send(s_cmd_stop_recv_raw_samples, pmt_list2(PMT_NIL, d_rx_chan0));
-    d_rx->send(s_cmd_stop_recv_raw_samples, pmt_list2(PMT_NIL, d_rx_chan1));
-    enter_closing_channel();
-    return;
-  }
-
-}
-
-void
-test_usrp_rx::enter_closing_channel()
-{
-  d_state = CLOSING_CHANNEL;
-
-  d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan0));
-  d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan1));
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_RX] Deallocating RX channel\n";
-}
-
-REGISTER_MBLOCK_CLASS(test_usrp_rx);
-
-
-// ----------------------------------------------------------------
-
-int
-main (int argc, char **argv)
-{
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_NIL;
-
-  rt->run("top", "test_usrp_rx", PMT_F, &result);
-
-}
diff --git a/usrp/host/apps-inband/test_usrp_inband_2tx.cc b/usrp/host/apps-inband/test_usrp_inband_2tx.cc
deleted file mode 100644 (file)
index 11a1a49..0000000
+++ /dev/null
@@ -1,430 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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 <mblock/mblock.h>
-#include <mblock/runtime.h>
-#include <mb_runtime_nop.h>            // QA only
-#include <mblock/protocol_class.h>
-#include <mblock/exception.h>
-#include <mblock/msg_queue.h>
-#include <mblock/message.h>
-#include <mb_mblock_impl.h>
-#include <mblock/msg_accepter.h>
-#include <mblock/class_registry.h>
-#include <pmt.h>
-#include <stdio.h>
-#include <string.h>
-#include <iostream>
-
-#include <ui_nco.h>
-#include <symbols_usrp_server_cs.h>
-#include <symbols_usrp_channel.h>
-#include <symbols_usrp_low_level_cs.h>
-#include <symbols_usrp_tx.h>
-
-static bool verbose = true;
-
-class test_usrp_tx : public mb_mblock
-{
-  mb_port_sptr         d_tx;
-  mb_port_sptr         d_cs;
-  pmt_t                d_tx_chan0, d_tx_chan1;
-
-  enum state_t {
-    INIT,
-    OPENING_USRP,
-    ALLOCATING_CHANNEL,
-    TRANSMITTING,
-    CLOSING_CHANNEL,
-    CLOSING_USRP,
-  };
-
-  state_t      d_state;
-  long         d_nsamples_to_send;
-  long         d_nsamples_xmitted;
-  long         d_nframes_xmitted;
-  long         d_samples_per_frame;
-  bool         d_done_sending;
-
-  // for generating sine wave output
-  ui_nco<float,float>  d_nco;
-  double               d_amplitude;
-
- public:
-  test_usrp_tx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~test_usrp_tx();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void open_usrp();
-  void close_usrp();
-  void allocate_channel();
-  void send_packets();
-  void enter_transmitting();
-  void build_and_send_next_frame();
-  void handle_xmit_response(pmt_t invocation_handle);
-  void enter_closing_channel();
-};
-
-test_usrp_tx::test_usrp_tx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg),
-    d_tx_chan0(PMT_NIL), d_tx_chan1(PMT_NIL),
-    d_state(INIT), d_nsamples_to_send((long) 80e6),
-    d_nsamples_xmitted(0),
-    d_nframes_xmitted(0),
-    d_samples_per_frame((long)(126 * 4)),      // full packet
-    d_done_sending(false),
-    d_amplitude(16384)
-{ 
-  // std::cout << "[TEST_USRP_TX] Initializing...\n";
-  
-  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-  
-  //bool fake_usrp_p = true;
-  bool fake_usrp_p = false;
-
-  // Test the TX side
-
-  pmt_t usrp_dict = pmt_make_dict();
-
-  if(fake_usrp_p) {
-    pmt_dict_set(usrp_dict, 
-                 pmt_intern("fake-usrp"),
-                            PMT_T);
-  }
-  
-  // Specify the RBF to use
-  pmt_dict_set(usrp_dict,
-               pmt_intern("rbf"),
-               pmt_intern("inband_2rxhb_2tx.rbf"));
-
-  // Set TX and RX interpolations
-  pmt_dict_set(usrp_dict,
-               pmt_intern("interp-tx"),
-               pmt_from_long(128));
-
-//  pmt_dict_set(usrp_dict,
-//               pmt_intern("rf-freq"),
-//               pmt_from_long(10e6));
-
-  define_component("server", "usrp_server", usrp_dict);
-
-  connect("self", "tx0", "server", "tx0");
-  connect("self", "cs", "server", "cs");
-
-  // initialize NCO
-  double freq = 100e3;
-  int interp = 32;                         // 32 -> 4MS/s
-  double sample_rate = 128e6 / interp; 
-  d_nco.set_freq(2*M_PI * freq/sample_rate);
-
-  // FIXME need to somehow set the interp rate in the USRP.
-  // for now, we'll have the low-level code hardwire it.
-}
-
-test_usrp_tx::~test_usrp_tx()
-{
-}
-
-void
-test_usrp_tx::initial_transition()
-{
-  open_usrp();
-}
-
-void
-test_usrp_tx::handle_message(mb_message_sptr msg)
-{
-  pmt_t        event = msg->signal();
-  pmt_t data = msg->data();
-
-  pmt_t handle = PMT_F;
-  pmt_t status = PMT_F;
-  std::string error_msg;
-  
-  //std::cout << msg << std::endl;
-
-  switch(d_state){
-  case OPENING_USRP:
-    if (pmt_eq(event, s_response_open)){
-      status = pmt_nth(1, data);
-      if (pmt_eq(status, PMT_T)){
-        allocate_channel();
-        return;
-      }
-      else {
-        error_msg = "failed to open usrp:";
-        goto bail;
-      }
-    }
-    goto unhandled;
-    
-  case ALLOCATING_CHANNEL:
-    if (pmt_eq(event, s_response_allocate_channel)){
-      status = pmt_nth(1, data);
-      if(pmt_eqv(d_tx_chan0, PMT_NIL))
-        d_tx_chan0 = pmt_nth(2, data);
-      else
-        d_tx_chan1 = pmt_nth(2, data);
-
-      if (pmt_eq(status, PMT_T) && !pmt_eqv(d_tx_chan1, PMT_NIL)){
-        enter_transmitting();
-        return;
-      }
-      else if(pmt_eq(status, PMT_F)){
-        error_msg = "failed to allocate channel:";
-        goto bail;
-      }
-      return;
-    }
-    goto unhandled;
-
-  case TRANSMITTING:
-    if (pmt_eq(event, s_response_xmit_raw_frame)){
-      handle = pmt_nth(0, data);
-      status = pmt_nth(1, data);
-
-      if (pmt_eq(status, PMT_T)){
-        handle_xmit_response(handle);
-        return;
-      }
-      else {
-        error_msg = "bad response-xmit-raw-frame:";
-        goto bail;
-      }
-    }
-    goto unhandled;
-
-  case CLOSING_CHANNEL:
-    if (pmt_eq(event, s_response_deallocate_channel)){
-      status = pmt_nth(1, data);
-
-      if (pmt_eq(status, PMT_T)){
-        close_usrp();
-        return;
-      }
-      else {
-        error_msg = "failed to deallocate channel:";
-        goto bail;
-      }
-    }
-    goto unhandled;
-
-  case CLOSING_USRP:
-    if (pmt_eq(event, s_response_close)){
-      status = pmt_nth(1, data);
-
-      if (pmt_eq(status, PMT_T)){
-        shutdown_all(PMT_T);
-        return;
-      }
-      else {
-        error_msg = "failed to close USRP:";
-        goto bail;
-      }
-    }
-    goto unhandled;
-
-  default:
-    goto unhandled;
-  }
-  return;
-
- bail:
-  std::cerr << error_msg << data
-           << "status = " << status << std::endl;
-  shutdown_all(PMT_F);
-  return;
-
- unhandled:
-  std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
-           << "in state "<< d_state << std::endl;
-}
-
-
-void
-test_usrp_tx::open_usrp()
-{
-  pmt_t which_usrp = pmt_from_long(0);
-
-  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
-  d_state = OPENING_USRP;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_TX] Opening the USRP\n";
-}
-
-void
-test_usrp_tx::close_usrp()
-{
-  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
-  d_state = CLOSING_USRP;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_TX] Closing the USRP\n";
-}
-
-void
-test_usrp_tx::allocate_channel()
-{
-  long capacity = (long) 16e6;
-
-  // Send two capacity requests, which will allocate us two channels
-  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-  d_state = ALLOCATING_CHANNEL;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_TX] Requesting TX channel allocation\n";
-}
-
-void
-test_usrp_tx::enter_transmitting()
-{
-  d_state = TRANSMITTING;
-  d_nsamples_xmitted = 0;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_TX] Transmitting...\n";
-  
-  build_and_send_next_frame(); // fire off 4 to start pipeline
-  build_and_send_next_frame();
-  build_and_send_next_frame();
-  build_and_send_next_frame();
-}
-
-void
-test_usrp_tx::build_and_send_next_frame()
-{
-  // allocate the uniform vector for the samples
-  // FIXME perhaps hold on to this between calls
-
-#if 1
-  long nsamples_this_frame =
-    std::min(d_nsamples_to_send - d_nsamples_xmitted,
-            d_samples_per_frame);
-#else
-  long nsamples_this_frame = d_samples_per_frame;
-#endif
-
-  if (nsamples_this_frame == 0){
-    d_done_sending = true;
-    return;
-  }
-    
-
-  size_t nshorts = 2 * nsamples_this_frame;    // 16-bit I & Q
-  pmt_t uvec = pmt_make_s16vector(nshorts, 0);
-  size_t ignore;
-  int16_t *samples = pmt_s16vector_writable_elements(uvec, ignore);
-
-  // fill in the complex sinusoid
-
-  for (int i = 0; i < nsamples_this_frame; i++){
-
-    if (1){
-      gr_complex s;
-      d_nco.sincos(&s, 1, d_amplitude);
-      // write 16-bit i & q
-      samples[2*i] =   (int16_t) s.real();
-      samples[2*i+1] = (int16_t) s.imag();
-    }
-    else {
-      gr_complex s(d_amplitude, d_amplitude);
-
-      // write 16-bit i & q
-      samples[2*i] =   (int16_t) s.real();
-      samples[2*i+1] = (int16_t) s.imag();
-    }
-  }
-
-  pmt_t tx_properties = pmt_make_dict();
-
-  pmt_t timestamp = pmt_from_long(0xffffffff); // NOW
-  d_tx->send(s_cmd_xmit_raw_frame,
-            pmt_list5(pmt_from_long(d_nframes_xmitted),  // invocation-handle
-                      d_tx_chan0,                        // channel
-                      uvec,                              // the samples
-                      timestamp,
-           tx_properties));
-  
-  // Resend on channel 1
-  d_tx->send(s_cmd_xmit_raw_frame,
-            pmt_list5(pmt_from_long(d_nframes_xmitted),  // invocation-handle
-                      d_tx_chan1,                        // channel
-                      uvec,                              // the samples
-                      timestamp,
-           tx_properties));
-
-  d_nsamples_xmitted += nsamples_this_frame;
-  d_nframes_xmitted++;
-
-  if(verbose && 0)
-    std::cout << "[TEST_USRP_INBAND_TX] Transmitted frame\n";
-}
-
-
-void
-test_usrp_tx::handle_xmit_response(pmt_t handle)
-{
-  if (d_done_sending &&
-      pmt_to_long(handle) == (d_nframes_xmitted - 1)){
-    // We're done sending and have received all responses
-    enter_closing_channel();
-  }
-
-  build_and_send_next_frame();
-}
-
-void
-test_usrp_tx::enter_closing_channel()
-{
-  d_state = CLOSING_CHANNEL;
-  
-  // Deallocate both channels
-  d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan0));
-  d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan1));
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_tX] Deallocating TX channel\n";
-}
-
-REGISTER_MBLOCK_CLASS(test_usrp_tx);
-
-
-// ----------------------------------------------------------------
-
-int
-main (int argc, char **argv)
-{
-  // handle any command line args here
-
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_NIL;
-
-  rt->run("top", "test_usrp_tx", PMT_F, &result);
-}
diff --git a/usrp/host/apps-inband/test_usrp_inband_overrun.cc b/usrp/host/apps-inband/test_usrp_inband_overrun.cc
deleted file mode 100644 (file)
index cd0fa52..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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 <mblock/mblock.h>
-#include <mblock/runtime.h>
-#include <mblock/protocol_class.h>
-#include <mblock/exception.h>
-#include <mblock/msg_queue.h>
-#include <mblock/message.h>
-#include <mblock/msg_accepter.h>
-#include <mblock/class_registry.h>
-#include <pmt.h>
-#include <stdio.h>
-#include <string.h>
-#include <iostream>
-#include <fstream>
-
-// Include the symbols needed for communication with USRP server
-#include <symbols_usrp_server_cs.h>
-#include <symbols_usrp_channel.h>
-#include <symbols_usrp_low_level_cs.h>
-#include <symbols_usrp_rx.h>
-
-static bool verbose = true;
-
-class test_usrp_rx : public mb_mblock
-{
-  mb_port_sptr         d_rx;
-  mb_port_sptr         d_cs;
-  pmt_t                d_rx_chan;      // returned tx channel handle
-
-  enum state_t {
-    INIT,
-    OPENING_USRP,
-    ALLOCATING_CHANNEL,
-    RECEIVING,
-    CLOSING_CHANNEL,
-    CLOSING_USRP,
-  };
-
-  state_t      d_state;
-
-  std::ofstream d_ofile;
-
-  long d_n_overruns;
-
-  long d_samples_recvd;
-  long d_samples_to_recv;
-
- public:
-  test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~test_usrp_rx();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void open_usrp();
-  void close_usrp();
-  void allocate_channel();
-  void send_packets();
-  void enter_receiving();
-  void build_and_send_next_frame();
-  void handle_response_recv_raw_samples(pmt_t invocation_handle);
-  void enter_closing_channel();
-};
-
-test_usrp_rx::test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg),
-    d_n_overruns(0),
-    d_samples_recvd(0),
-    d_samples_to_recv(10e6)
-{ 
-  
-  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-  
-  // Pass a dictionary to usrp_server which specifies which interface to use, the stub or USRP
-  pmt_t usrp_dict = pmt_make_dict();
-
-  // Specify the RBF to use
-  pmt_dict_set(usrp_dict,
-               pmt_intern("rbf"),
-               pmt_intern("inband_1rxhb_1tx.rbf"));
-
-  pmt_dict_set(usrp_dict,
-               pmt_intern("decim-rx"),
-               pmt_from_long(128));
-
-  define_component("server", "usrp_server", usrp_dict);
-
-  connect("self", "rx0", "server", "rx0");
-  connect("self", "cs", "server", "cs");
-
-}
-
-test_usrp_rx::~test_usrp_rx()
-{
-}
-
-void
-test_usrp_rx::initial_transition()
-{
-  open_usrp();
-}
-
-void
-test_usrp_rx::handle_message(mb_message_sptr msg)
-{
-  pmt_t        event = msg->signal();
-  pmt_t data = msg->data();
-
-  pmt_t handle = PMT_F;
-  pmt_t status = PMT_F;
-  std::string error_msg;
-  
-  switch(d_state){
-    
-    //----------------------------- OPENING_USRP ----------------------------//
-    // We only expect a response from opening the USRP which should be succesful
-    // or failed.
-    case OPENING_USRP:
-      if (pmt_eq(event, s_response_open)){
-        status = pmt_nth(1, data);
-        if (pmt_eq(status, PMT_T)){
-          allocate_channel();
-          return;
-        }
-        else {
-          error_msg = "failed to open usrp:";
-          goto bail;
-        }
-      }
-      goto unhandled;
-      
-    //----------------------- ALLOCATING CHANNELS --------------------//
-    // Allocate an RX channel to perform the overrun test.
-    case ALLOCATING_CHANNEL:
-      if (pmt_eq(event, s_response_allocate_channel)){
-        status = pmt_nth(1, data);
-        d_rx_chan = pmt_nth(2, data);
-
-        if (pmt_eq(status, PMT_T)){
-          enter_receiving();
-          return;
-        }
-        else {
-          error_msg = "failed to allocate channel:";
-          goto bail;
-        }
-      }
-      goto unhandled;
-
-    //--------------------------- RECEIVING ------------------------------//
-    // In the receiving state, we receive samples until the specified amount
-    // while counting the number of overruns.
-    case RECEIVING:
-      if (pmt_eq(event, s_response_recv_raw_samples)){
-        status = pmt_nth(1, data);
-
-        if (pmt_eq(status, PMT_T)){
-          handle_response_recv_raw_samples(data);
-          return;
-        }
-        else {
-          error_msg = "bad response-xmit-raw-frame:";
-          goto bail;
-        }
-      }
-      goto unhandled;
-    
-    //------------------------- CLOSING CHANNEL ----------------------------//
-    // Check deallocation response for the RX channel 
-    case CLOSING_CHANNEL:
-      if (pmt_eq(event, s_response_deallocate_channel)){
-        status = pmt_nth(1, data);
-
-        if (pmt_eq(status, PMT_T)){
-          close_usrp();
-          return;
-        }
-        else {
-          error_msg = "failed to deallocate channel:";
-          goto bail;
-        }
-      }
-
-      // Alternately, we ignore all response recv samples while waiting for the
-      // channel to actually close
-      if (pmt_eq(event, s_response_recv_raw_samples))
-        return;
-
-      goto unhandled;
-
-    //--------------------------- CLOSING USRP ------------------------------//
-    // Once we have received a successful USRP close response, we shutdown all
-    // mblocks and exit.
-    case CLOSING_USRP:
-      if (pmt_eq(event, s_response_close)){
-        status = pmt_nth(1, data);
-
-        if (pmt_eq(status, PMT_T)){
-          std::cout << "\nOverruns: " << d_n_overruns << std::endl;
-          fflush(stdout);
-          shutdown_all(PMT_T);
-          return;
-        }
-        else {
-          error_msg = "failed to close USRP:";
-          goto bail;
-        }
-      }
-      goto unhandled;
-
-    default:
-      goto unhandled;
-  }
-  return;
-
- // An error occured, print it, and shutdown all m-blocks
- bail:
-  std::cerr << error_msg << data
-           << "status = " << status << std::endl;
-  shutdown_all(PMT_F);
-  return;
-
- // Received an unhandled message for a specific state
- unhandled:
-  if(verbose && !pmt_eq(event, pmt_intern("%shutdown")))
-    std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
-              << "in state "<< d_state << std::endl;
-}
-
-
-void
-test_usrp_rx::open_usrp()
-{
-  pmt_t which_usrp = pmt_from_long(0);
-
-  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
-  d_state = OPENING_USRP;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_OVERRUN] Opening the USRP\n";
-}
-
-void
-test_usrp_rx::close_usrp()
-{
-  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
-  d_state = CLOSING_USRP;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_OVERRUN] Closing the USRP\n";
-}
-
-void
-test_usrp_rx::allocate_channel()
-{
-  long capacity = (long) 16e6;
-  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-  d_state = ALLOCATING_CHANNEL;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_OVERRUN] Requesting RX channel allocation\n";
-}
-
-void
-test_usrp_rx::enter_receiving()
-{
-  d_state = RECEIVING;
-
-  d_rx->send(s_cmd_start_recv_raw_samples,
-             pmt_list2(PMT_F,
-                       d_rx_chan));
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_OVERRUN] Receiving...\n";
-}
-
-void
-test_usrp_rx::handle_response_recv_raw_samples(pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  pmt_t status = pmt_nth(1, data);
-  pmt_t v_samples = pmt_nth(2, data);
-  pmt_t timestamp = pmt_nth(3, data);
-  pmt_t channel = pmt_nth(4, data);
-  pmt_t properties = pmt_nth(5, data);
-
-  d_samples_recvd += pmt_length(v_samples) / 4;
-
-  // Check for overrun
-  if(!pmt_is_dict(properties)) {
-    std::cout << "[TEST_USRP_INBAND_OVERRUN] Recv samples dictionary is improper\n";
-    return;
-  }
-
-  if(pmt_t overrun = pmt_dict_ref(properties, 
-                                  pmt_intern("overrun"), 
-                                  PMT_NIL)) {
-    if(pmt_eqv(overrun, PMT_T)) {
-      d_n_overruns++;
-
-      if(verbose && 0)
-        std::cout << "[TEST_USRP_INBAND_OVERRUN] Underrun\n";
-    }
-    else {
-    if(verbose && 0)
-      std::cout << "[TEST_USRP_INBAND_OVERRUN] No overrun\n" << overrun <<std::endl;
-    }
-  } else {
-
-    if(verbose && 0)
-      std::cout << "[TEST_USRP_INBAND_OVERRUN] No overrun\n";
-  }
-
-  // Check if the number samples we have received meets the test
-  if(d_samples_recvd >= d_samples_to_recv) {
-    d_rx->send(s_cmd_stop_recv_raw_samples, pmt_list2(PMT_NIL, d_rx_chan));
-    enter_closing_channel();
-    return;
-  }
-
-}
-
-void
-test_usrp_rx::enter_closing_channel()
-{
-  d_state = CLOSING_CHANNEL;
-  
-  sleep(2);
-  
-  d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan));
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_OVERRUN] Deallocating RX channel\n";
-}
-
-REGISTER_MBLOCK_CLASS(test_usrp_rx);
-
-
-// ----------------------------------------------------------------
-
-int
-main (int argc, char **argv)
-{
-  // handle any command line args here
-
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_NIL;
-
-  rt->run("top", "test_usrp_rx", PMT_F, &result);
-}
diff --git a/usrp/host/apps-inband/test_usrp_inband_ping.cc b/usrp/host/apps-inband/test_usrp_inband_ping.cc
deleted file mode 100644 (file)
index d779c9a..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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 <mblock/mblock.h>
-#include <mblock/runtime.h>
-#include <mblock/protocol_class.h>
-#include <mblock/exception.h>
-#include <mblock/msg_queue.h>
-#include <mblock/message.h>
-#include <mblock/msg_accepter.h>
-#include <mblock/class_registry.h>
-#include <pmt.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/time.h>
-#include <iostream>
-
-// Include the symbols needed for communication with USRP server
-#include <symbols_usrp_server_cs.h>
-#include <symbols_usrp_channel.h>
-#include <symbols_usrp_low_level_cs.h>
-#include <symbols_usrp_tx.h>
-#include <symbols_usrp_rx.h>
-
-static bool verbose = false;
-
-class test_usrp_inband_ping : public mb_mblock
-{
-
-  mb_port_sptr  d_tx;   // Ports connected to the USRP server
-  mb_port_sptr  d_rx;
-  mb_port_sptr  d_cs;
-
-  pmt_t   d_tx_chan;    // Returned channel from TX allocation
-  pmt_t   d_rx_chan;    // Returned channel from RX allocation
-
-  pmt_t   d_which_usrp; // The USRP to use for the test
-
-  long    d_warm_msgs;  // The number of messages to 'warm' the USRP
-  long    d_warm_recvd; // The number of msgs received in the 'warm' state
-
-  // Keep track of current state
-  enum state_t {
-    INIT,
-    OPENING_USRP,
-    ALLOCATING_CHANNELS,
-    WARMING_USRP,
-    PINGING,
-    CLOSING_CHANNELS,
-    CLOSING_USRP,
-  };
-  state_t d_state;
-
- public:
-  test_usrp_inband_ping(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~test_usrp_inband_ping();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void opening_usrp();
-  void allocating_channels();
-  void enter_warming_usrp();
-  void enter_pinging();
-  void build_and_send_ping();
-  void closing_channels();
-  void closing_usrp();
-};
-
-
-int
-main (int argc, char **argv)
-{
-  // handle any command line args here
-
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_NIL;
-
-  rt->run("top", "test_usrp_inband_ping", PMT_F, &result);
-}
-
-
-test_usrp_inband_ping::test_usrp_inband_ping(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg),
-  d_tx_chan(PMT_NIL),
-  d_rx_chan(PMT_NIL),
-  d_which_usrp(pmt_from_long(0)),
-  d_state(INIT)
-{
-  
-  // A dictionary is used to pass parameters to the USRP
-  pmt_t usrp_dict = pmt_make_dict();
-
-  // Specify the RBF to use
-  pmt_dict_set(usrp_dict,
-               pmt_intern("rbf"),
-               pmt_intern("fixed1.rbf"));
-
-  // Set TX and RX interpolations
-  pmt_dict_set(usrp_dict,
-               pmt_intern("interp-tx"),
-               pmt_from_long(128));
-
-  pmt_dict_set(usrp_dict,
-               pmt_intern("decim-rx"),
-               pmt_from_long(16));
-  
-  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
-  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-
-  // Create an instance of USRP server and connect ports
-  define_component("server", "usrp_server", usrp_dict);
-  connect("self", "tx0", "server", "tx0");
-  connect("self", "rx0", "server", "rx0");
-  connect("self", "cs", "server", "cs");
-
-}
-
-test_usrp_inband_ping::~test_usrp_inband_ping()
-{
-}
-
-void
-test_usrp_inband_ping::initial_transition()
-{
-  opening_usrp();
-}
-
-// Handle message reads all incoming messages from USRP server which will be
-// initialization and ping responses.  We perform actions based on the current
-// state and the event (ie, ping response)
-void
-test_usrp_inband_ping::handle_message(mb_message_sptr msg)
-{
-  pmt_t event = msg->signal();
-  pmt_t data = msg->data();
-  pmt_t port_id = msg->port_id();
-
-  pmt_t handle = PMT_F;
-  pmt_t status = PMT_F;
-  std::string error_msg;
-
-  // Dispatch based on state
-  switch(d_state) {
-
-    //----------------------------- OPENING_USRP ----------------------------//
-    // We only expect a response from opening the USRP which should be succesful
-    // or failed.
-    case OPENING_USRP:
-      
-      if(pmt_eq(event, s_response_open)) {
-
-        status = pmt_nth(1, data);          // failed/succes
-        
-        if(pmt_eq(status, PMT_T)) {
-          allocating_channels();
-          return;
-        }
-        else {
-          error_msg = "failed to open usrp:";
-          goto bail;
-        }
-
-      }
-
-      goto unhandled;   // all other messages not handled in this state
-      
-    
-    //----------------------- ALLOCATING CHANNELS --------------------//
-    // When allocating channels, we need to wait for 2 responses from
-    // USRP server: one for TX and one for RX.  Both are initialized to
-    // NIL so we know to continue to the next state once both are set.
-    case ALLOCATING_CHANNELS:
-
-      // A TX allocation response
-      if(pmt_eq(event, s_response_allocate_channel)
-          && pmt_eq(d_tx->port_symbol(), port_id)) 
-      {
-        status = pmt_nth(1, data);
-        
-        // If successful response, extract the channel
-        if(pmt_eq(status, PMT_T)) {
-          
-          d_tx_chan = pmt_nth(2, data);
-
-          if(verbose)
-            std::cout << "[TEST_USRP_INBAND_PING] Received TX allocation"
-                      << " on channel " << d_tx_chan << std::endl;
-
-          // If the RX has also been allocated already, we can continue
-          if(!pmt_eqv(d_rx_chan, PMT_NIL)) 
-            enter_warming_usrp();
-
-          return;
-        }
-        else {  // TX allocation failed
-          error_msg = "failed to allocate TX channel:";
-          goto bail;
-        }
-      }
-      
-      // A RX allocation response
-      if(pmt_eq(event, s_response_allocate_channel)
-          && pmt_eq(d_rx->port_symbol(), port_id)) 
-      {
-        status = pmt_nth(1, data);
-        
-        // If successful response, extract the channel
-        if(pmt_eq(status, PMT_T)) {
-          
-          d_rx_chan = pmt_nth(2, data);
-
-          if(verbose)
-            std::cout << "[TEST_USRP_INBAND_PING] Received RX allocation"
-                      << " on channel " << d_rx_chan << std::endl;
-
-          // If the TX has also been allocated already, we can continue
-          if(!pmt_eqv(d_tx_chan, PMT_NIL)) 
-            enter_warming_usrp();
-
-          return;
-        }
-        else {  // RX allocation failed
-          error_msg = "failed to allocate RX channel:";
-          goto bail;
-        }
-      }
-
-      goto unhandled;
-
-    //----------------------- WARMING USRP --------------------//
-    // The FX2 seems to need some amount of data to be buffered
-    // before it begins reading.  We use this state to simply
-    // warm up the USRP before benchmarking pings.
-    case WARMING_USRP:
-
-      // We really don't care about the responses from the
-      // control channel in the warming stage, but once we receive
-      // the proper number of responses we switch states.
-      if(pmt_eq(event, s_response_from_control_channel)
-          && pmt_eq(d_rx->port_symbol(), port_id))
-      {
-        d_warm_recvd++;
-
-        if(d_warm_recvd > d_warm_msgs)
-          enter_pinging();
-
-        return;
-      }
-
-      goto unhandled;
-
-    case PINGING:
-      goto unhandled;
-
-    case CLOSING_CHANNELS:
-      goto unhandled;
-
-    case CLOSING_USRP:
-      goto unhandled;
-
-    case INIT:
-      goto unhandled;
-
-  }
- // An error occured, print it, and shutdown all m-blocks
- bail:
-  std::cerr << error_msg << data
-           << "status = " << status << std::endl;
-  shutdown_all(PMT_F);
-  return;
-
- // Received an unhandled message for a specific state
- unhandled:
-  if(verbose)
-    std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
-              << "in state "<< d_state << std::endl;
-
-}
-
-
-// Sends a command to USRP server to open up a connection to the
-// specified USRP, which is defaulted to USRP 0 on the system
-void
-test_usrp_inband_ping::opening_usrp()
-{
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_PING] Opening USRP " 
-              << d_which_usrp << std::endl;
-
-  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, d_which_usrp));
-  d_state = OPENING_USRP;
-}
-
-// RX and TX channels must be allocated so that the USRP server can
-// properly share bandwidth across multiple USRPs.  No commands will be
-// successful to the USRP through the USRP server on the TX or RX channels until
-// a bandwidth allocation has been received.
-void
-test_usrp_inband_ping::allocating_channels()
-{
-  d_state = ALLOCATING_CHANNELS;
-
-  long capacity = (long) 16e6;
-  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-}
-
-// The USRP needs some amount of initial data to pass a buffering point such
-// that it begins to pull and read data from the FX2.  We send an arbitrary
-// amount of data to start the pipeline, which are just pings.
-void
-test_usrp_inband_ping::enter_warming_usrp()
-{
-  d_state = WARMING_USRP;
-
-  for(int i=0; i < d_warm_msgs; i++)
-    build_and_send_ping();
-}
-
-void
-test_usrp_inband_ping::enter_pinging()
-{
-  d_state = PINGING;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_PING] Running ping tests\n";
-
-}
-
-// Pings are sent over the TX channel using the signal 'cmd-to-control-channel'
-// to the USRP server.  Within this message there can be infinite subpackets
-// stored as a list (the second parameter) and sent.  The only subpacket we send
-// is a ping, interpreted by the 'op-ping-fixed' signal.
-void
-test_usrp_inband_ping::build_and_send_ping()
-{
-  
-  d_tx->send(s_cmd_to_control_channel,    // USRP server signal
-             pmt_list2(PMT_NIL,           // invocation handle 
-                       pmt_list1(pmt_list3(s_op_ping_fixed, 
-                                           pmt_from_long(0), 
-                                           pmt_from_long(0)))));
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_PING] Ping!!" << std::endl;
-}
-
-REGISTER_MBLOCK_CLASS(test_usrp_inband_ping);
diff --git a/usrp/host/apps-inband/test_usrp_inband_registers.cc b/usrp/host/apps-inband/test_usrp_inband_registers.cc
deleted file mode 100644 (file)
index d9bd2db..0000000
+++ /dev/null
@@ -1,435 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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 <mblock/mblock.h>
-#include <mblock/runtime.h>
-#include <mblock/protocol_class.h>
-#include <mblock/exception.h>
-#include <mblock/msg_queue.h>
-#include <mblock/message.h>
-//#include <mb_mblock_impl.h>
-#include <mblock/msg_accepter.h>
-#include <mblock/class_registry.h>
-#include <pmt.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/time.h>
-#include <iostream>
-
-// Include the symbols needed for communication with USRP server
-#include <symbols_usrp_server_cs.h>
-#include <symbols_usrp_channel.h>
-#include <symbols_usrp_low_level_cs.h>
-#include <symbols_usrp_tx.h>
-#include <symbols_usrp_rx.h>
-
-static bool verbose = true;
-
-class test_usrp_inband_registers : public mb_mblock
-{
-
-  mb_port_sptr  d_tx;   // Ports connected to the USRP server
-  mb_port_sptr  d_rx;
-  mb_port_sptr  d_cs;
-
-  pmt_t   d_tx_chan;    // Returned channel from TX allocation
-  pmt_t   d_rx_chan;    // Returned channel from RX allocation
-
-  pmt_t   d_which_usrp; // The USRP to use for the test
-
-  long    d_warm_msgs;  // The number of messages to 'warm' the USRP
-  long    d_warm_recvd; // The number of msgs received in the 'warm' state
-
-  // Keep track of current state
-  enum state_t {
-    INIT,
-    OPENING_USRP,
-    ALLOCATING_CHANNELS,
-    WRITE_REGISTER,
-    READ_REGISTER,
-    CLOSING_CHANNELS,
-    CLOSING_USRP,
-  };
-  state_t d_state;
-
- public:
-  test_usrp_inband_registers(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~test_usrp_inband_registers();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void opening_usrp();
-  void allocating_channels();
-  void write_register();
-  void read_register();
-  void closing_channels();
-  void closing_usrp();
-  void enter_receiving();
-  void build_and_send_ping();
-};
-
-
-int
-main (int argc, char **argv)
-{
-  // handle any command line args here
-
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_NIL;
-
-  rt->run("top", "test_usrp_inband_registers", PMT_F, &result);
-}
-
-
-test_usrp_inband_registers::test_usrp_inband_registers(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg),
-  d_tx_chan(PMT_NIL),
-  d_rx_chan(PMT_NIL),
-  d_which_usrp(pmt_from_long(0)),
-  d_state(INIT)
-{
-  
-  // A dictionary is used to pass parameters to the USRP
-  pmt_t usrp_dict = pmt_make_dict();
-
-  // Specify the RBF to use
-  pmt_dict_set(usrp_dict,
-               pmt_intern("rbf"),
-               pmt_intern("inband_1rxhb_1tx.rbf"));
-
-  // Set TX and RX interpolations
-  pmt_dict_set(usrp_dict,
-               pmt_intern("interp-tx"),
-               pmt_from_long(128));
-
-  pmt_dict_set(usrp_dict,
-               pmt_intern("decim-rx"),
-               pmt_from_long(16));
-  
-  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
-  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-
-  // Create an instance of USRP server and connect ports
-  define_component("server", "usrp_server", usrp_dict);
-  connect("self", "tx0", "server", "tx0");
-  connect("self", "rx0", "server", "rx0");
-  connect("self", "cs", "server", "cs");
-
-}
-
-test_usrp_inband_registers::~test_usrp_inband_registers()
-{
-}
-
-void
-test_usrp_inband_registers::initial_transition()
-{
-  opening_usrp();
-}
-
-// Handle message reads all incoming messages from USRP server which will be
-// initialization and ping responses.  We perform actions based on the current
-// state and the event (ie, ping response)
-void
-test_usrp_inband_registers::handle_message(mb_message_sptr msg)
-{
-  pmt_t event = msg->signal();
-  pmt_t data = msg->data();
-  pmt_t port_id = msg->port_id();
-
-  pmt_t handle = PMT_F;
-  pmt_t status = PMT_F;
-  std::string error_msg;
-
-  // Dispatch based on state
-  switch(d_state) {
-
-    //----------------------------- OPENING_USRP ----------------------------//
-    // We only expect a response from opening the USRP which should be succesful
-    // or failed.
-    case OPENING_USRP:
-      
-      if(pmt_eq(event, s_response_open)) {
-
-        status = pmt_nth(1, data);          // failed/succes
-        
-        if(pmt_eq(status, PMT_T)) {
-          allocating_channels();
-          return;
-        }
-        else {
-          error_msg = "failed to open usrp:";
-          goto bail;
-        }
-
-      }
-
-      goto unhandled;   // all other messages not handled in this state
-      
-    
-    //----------------------- ALLOCATING CHANNELS --------------------//
-    // When allocating channels, we need to wait for 2 responses from
-    // USRP server: one for TX and one for RX.  Both are initialized to
-    // NIL so we know to continue to the next state once both are set.
-    case ALLOCATING_CHANNELS:
-
-      // A TX allocation response
-      if(pmt_eq(event, s_response_allocate_channel)
-          && pmt_eq(d_tx->port_symbol(), port_id)) 
-      {
-        status = pmt_nth(1, data);
-        
-        // If successful response, extract the channel
-        if(pmt_eq(status, PMT_T)) {
-          
-          d_tx_chan = pmt_nth(2, data);
-
-          if(verbose)
-            std::cout << "[TEST_USRP_INBAND_PING] Received TX allocation"
-                      << " on channel " << d_tx_chan << std::endl;
-
-          // If the RX has also been allocated already, we can continue
-          if(!pmt_eqv(d_rx_chan, PMT_NIL)) {
-            enter_receiving();
-            write_register();
-          }
-
-          return;
-        }
-        else {  // TX allocation failed
-          error_msg = "failed to allocate TX channel:";
-          goto bail;
-        }
-      }
-      
-      // A RX allocation response
-      if(pmt_eq(event, s_response_allocate_channel)
-          && pmt_eq(d_rx->port_symbol(), port_id)) 
-      {
-        status = pmt_nth(1, data);
-        
-        // If successful response, extract the channel
-        if(pmt_eq(status, PMT_T)) {
-          
-          d_rx_chan = pmt_nth(2, data);
-
-          if(verbose)
-            std::cout << "[TEST_USRP_INBAND_PING] Received RX allocation"
-                      << " on channel " << d_rx_chan << std::endl;
-
-          // If the TX has also been allocated already, we can continue
-          if(!pmt_eqv(d_tx_chan, PMT_NIL)) {
-            enter_receiving();
-            write_register();
-          }
-
-          return;
-        }
-        else {  // RX allocation failed
-          error_msg = "failed to allocate RX channel:";
-          goto bail;
-        }
-      }
-
-      goto unhandled;
-
-    //-------------------------- WRITE REGISTER ----------------------------//
-    // In the write register state, we do not expect to receive any messages
-    // since the write does not directly generate a response until the USRP
-    // responds.
-    case WRITE_REGISTER:
-      goto unhandled;
-
-    //-------------------------- READ REGISTER ----------------------------//
-    // In the read register state, we only expect a read register response back
-    // that has the value we expect to have in it.  We read the response, ensure
-    // that the read was successful and display the register value.
-    case READ_REGISTER:
-
-      if(pmt_eq(event, s_response_from_control_channel)
-          && pmt_eq(d_tx->port_symbol(), port_id))
-      {
-        status = pmt_nth(1, data);
-
-        // If the read was successful, we extract the subpacket information
-        if(pmt_eq(status, PMT_T)) {
-          
-          pmt_t subp = pmt_nth(2, data);      // subpacket should be the read reg reply
-
-          pmt_t subp_sig  = pmt_nth(0, subp);
-          pmt_t subp_data = pmt_nth(1, subp);
-
-          if(!pmt_eqv(subp_sig, s_op_read_reg_reply)) {
-            error_msg = "received improper subpacket when expecting reg reply.";
-            goto bail;
-          }
-
-          pmt_t rid     = pmt_nth(0, subp_data);
-          pmt_t reg_num = pmt_nth(1, subp_data);
-          pmt_t reg_val = pmt_nth(2, subp_data);
-
-          if(verbose)
-            std::cout << "[TEST_USRP_INBAND_REGISTERS] Received read reg reply "
-                      << "("
-                      << "RID: " << rid << ", " 
-                      << "Reg: " << reg_num << ", "
-                      << "Val: " << reg_val
-                      << ")\n";
-          
-          // read_register();  FIX ME STATE TRANSITION
-          return;
-
-        } else {  // bail on unsuccessful write
-          error_msg = "failed to write to register.";
-          goto bail;
-        }
-      }
-      goto unhandled;
-
-    case CLOSING_CHANNELS:
-      goto unhandled;
-
-    case CLOSING_USRP:
-      goto unhandled;
-
-    case INIT:
-      goto unhandled;
-
-  }
- // An error occured, print it, and shutdown all m-blocks
- bail:
-  std::cerr << error_msg << data
-           << "status = " << status << std::endl;
-  shutdown_all(PMT_F);
-  return;
-
- // Received an unhandled message for a specific state
- unhandled:
-  if(verbose && !pmt_eq(event, s_response_recv_raw_samples))
-    std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
-              << "in state "<< d_state << std::endl;
-
-}
-
-
-// Sends a command to USRP server to open up a connection to the
-// specified USRP, which is defaulted to USRP 0 on the system
-void
-test_usrp_inband_registers::opening_usrp()
-{
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_PING] Opening USRP " 
-              << d_which_usrp << std::endl;
-
-  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, d_which_usrp));
-  d_state = OPENING_USRP;
-}
-
-// RX and TX channels must be allocated so that the USRP server can
-// properly share bandwidth across multiple USRPs.  No commands will be
-// successful to the USRP through the USRP server on the TX or RX channels until
-// a bandwidth allocation has been received.
-void
-test_usrp_inband_registers::allocating_channels()
-{
-  d_state = ALLOCATING_CHANNELS;
-
-  long capacity = (long) 16e6;
-  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-}
-
-// After allocating the channels, a write register command will be sent to the
-// USRP.
-void
-test_usrp_inband_registers::write_register()
-{
-  d_state = WRITE_REGISTER;
-
-  long reg = 0;
-
-  d_tx->send(s_cmd_to_control_channel,    // C/S packet
-             pmt_list2(PMT_NIL,           // invoc handle
-                       pmt_list1(
-                            pmt_list2(s_op_write_reg, 
-                                      pmt_list2(
-                                      pmt_from_long(reg), 
-                                      pmt_from_long(0xbeef))))));
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_REGISTERS] Writing 0xbeef to " 
-              << reg << std::endl;
-
-  read_register();  // immediately transition to read the register
-}
-
-// Temporary: for testing pings
-void
-test_usrp_inband_registers::build_and_send_ping()
-{
-  
-  d_tx->send(s_cmd_to_control_channel,
-             pmt_list2(PMT_NIL, pmt_list1(pmt_list2(s_op_ping_fixed,
-                                                    pmt_list2(pmt_from_long(0),
-                                                              pmt_from_long(0))))));
-
-  std::cout << "[TEST_USRP_INBAND_CS] Ping sent" << std::endl;
-}
-
-// After writing to the register, we want to read the value back and ensure that
-// it is the same value that we wrote.
-void
-test_usrp_inband_registers::read_register()
-{
-  d_state = READ_REGISTER;
-
-  long reg = 9;
-
-  d_tx->send(s_cmd_to_control_channel,    // C/S packet
-             pmt_list2(PMT_NIL,           // invoc handle
-                       pmt_list1(
-                            pmt_list2(s_op_read_reg, 
-                                      pmt_list2(
-                                      pmt_from_long(0),   // rid 
-                                      pmt_from_long(reg))))));
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_REGISTERS] Reading from register " 
-              << reg << std::endl;
-}
-
-// Used to enter the receiving state
-void
-test_usrp_inband_registers::enter_receiving()
-{
-  d_rx->send(s_cmd_start_recv_raw_samples,
-             pmt_list2(PMT_F,
-                       d_rx_chan));
-}
-
-REGISTER_MBLOCK_CLASS(test_usrp_inband_registers);
diff --git a/usrp/host/apps-inband/test_usrp_inband_rx.cc b/usrp/host/apps-inband/test_usrp_inband_rx.cc
deleted file mode 100644 (file)
index 4f21e4a..0000000
+++ /dev/null
@@ -1,362 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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 <mblock/mblock.h>
-#include <mblock/runtime.h>
-#include <mblock/protocol_class.h>
-#include <mblock/exception.h>
-#include <mblock/msg_queue.h>
-#include <mblock/message.h>
-#include <mblock/msg_accepter.h>
-#include <mblock/class_registry.h>
-#include <pmt.h>
-#include <stdio.h>
-#include <string.h>
-#include <iostream>
-#include <fstream>
-
-// Include the symbols needed for communication with USRP server
-#include <symbols_usrp_server_cs.h>
-#include <symbols_usrp_channel.h>
-#include <symbols_usrp_low_level_cs.h>
-#include <symbols_usrp_rx.h>
-
-static bool verbose = true;
-
-class test_usrp_rx : public mb_mblock
-{
-  mb_port_sptr         d_rx;
-  mb_port_sptr         d_cs;
-  pmt_t                d_rx_chan;      // returned tx channel handle
-
-  enum state_t {
-    INIT,
-    OPENING_USRP,
-    ALLOCATING_CHANNEL,
-    RECEIVING,
-    CLOSING_CHANNEL,
-    CLOSING_USRP,
-  };
-
-  state_t      d_state;
-
-  std::ofstream d_ofile;
-
-  long d_samples_recvd;
-  long d_samples_to_recv;
-
- public:
-  test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~test_usrp_rx();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void open_usrp();
-  void close_usrp();
-  void allocate_channel();
-  void send_packets();
-  void enter_receiving();
-  void build_and_send_next_frame();
-  void handle_response_recv_raw_samples(pmt_t invocation_handle);
-  void enter_closing_channel();
-};
-
-test_usrp_rx::test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg),
-    d_samples_recvd(0),
-    d_samples_to_recv(20e6)
-{ 
-  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-  
-  // Pass a dictionary to usrp_server which specifies which interface to use, the stub or USRP
-  pmt_t usrp_dict = pmt_make_dict();
-  
-  // To test the application without a USRP
-  bool fake_usrp_p = false;
-  if(fake_usrp_p) {
-    pmt_dict_set(usrp_dict, 
-                 pmt_intern("fake-usrp"),
-                            PMT_T);
-  }
-
-  // Specify the RBF to use
-  pmt_dict_set(usrp_dict,
-               pmt_intern("rbf"),
-               pmt_intern("inband_1rxhb_1tx.rbf"));
-
-  pmt_dict_set(usrp_dict,
-               pmt_intern("decim-rx"),
-               pmt_from_long(64));
-
-//  If unspecified, chooses center frequency from range
-//  pmt_dict_set(usrp_dict,
-//               pmt_intern("rf-freq"),
-//               pmt_from_long(10e6));
-
-  define_component("server", "usrp_server", usrp_dict);
-
-  connect("self", "rx0", "server", "rx0");
-  connect("self", "cs", "server", "cs");
-
-}
-
-test_usrp_rx::~test_usrp_rx()
-{
-}
-
-void
-test_usrp_rx::initial_transition()
-{
-  open_usrp();
-}
-
-void
-test_usrp_rx::handle_message(mb_message_sptr msg)
-{
-  pmt_t        event = msg->signal();
-  pmt_t data = msg->data();
-
-  pmt_t handle = PMT_F;
-  pmt_t status = PMT_F;
-  std::string error_msg;
-  
-  switch(d_state){
-    
-    //----------------------------- OPENING_USRP ----------------------------//
-    // We only expect a response from opening the USRP which should be succesful
-    // or failed.
-    case OPENING_USRP:
-      if (pmt_eq(event, s_response_open)){
-        status = pmt_nth(1, data);
-        if (pmt_eq(status, PMT_T)){
-          allocate_channel();
-          return;
-        }
-        else {
-          error_msg = "failed to open usrp:";
-          goto bail;
-        }
-      }
-      goto unhandled;
-      
-    //----------------------- ALLOCATING CHANNELS --------------------//
-    // Allocate an RX channel to perform the overrun test.
-    case ALLOCATING_CHANNEL:
-      if (pmt_eq(event, s_response_allocate_channel)){
-        status = pmt_nth(1, data);
-        d_rx_chan = pmt_nth(2, data);
-
-        if (pmt_eq(status, PMT_T)){
-          enter_receiving();
-          return;
-        }
-        else {
-          error_msg = "failed to allocate channel:";
-          goto bail;
-        }
-      }
-      goto unhandled;
-
-    //--------------------------- RECEIVING ------------------------------//
-    // In the receiving state, we receive samples until the specified amount
-    // while counting the number of overruns.
-    case RECEIVING:
-      if (pmt_eq(event, s_response_recv_raw_samples)){
-        status = pmt_nth(1, data);
-
-        if (pmt_eq(status, PMT_T)){
-          handle_response_recv_raw_samples(data);
-          return;
-        }
-        else {
-          error_msg = "bad response-xmit-raw-frame:";
-          goto bail;
-        }
-      }
-      goto unhandled;
-    
-    //------------------------- CLOSING CHANNEL ----------------------------//
-    // Check deallocation response for the RX channel 
-    case CLOSING_CHANNEL:
-      if (pmt_eq(event, s_response_deallocate_channel)){
-        status = pmt_nth(1, data);
-
-        if (pmt_eq(status, PMT_T)){
-          close_usrp();
-          return;
-        }
-        else {
-          error_msg = "failed to deallocate channel:";
-          goto bail;
-        }
-      }
-
-      // Alternately, we ignore all response recv samples while waiting for the
-      // channel to actually close
-      if (pmt_eq(event, s_response_recv_raw_samples))
-        return;
-
-      goto unhandled;
-
-    //--------------------------- CLOSING USRP ------------------------------//
-    // Once we have received a successful USRP close response, we shutdown all
-    // mblocks and exit.
-    case CLOSING_USRP:
-      if (pmt_eq(event, s_response_close)){
-        status = pmt_nth(1, data);
-
-        if (pmt_eq(status, PMT_T)){
-          fflush(stdout);
-          shutdown_all(PMT_T);
-          return;
-        }
-        else {
-          error_msg = "failed to close USRP:";
-          goto bail;
-        }
-      }
-      goto unhandled;
-
-    default:
-      goto unhandled;
-  }
-  return;
-
- // An error occured, print it, and shutdown all m-blocks
- bail:
-  std::cerr << error_msg << data
-           << "status = " << status << std::endl;
-  shutdown_all(PMT_F);
-  return;
-
- // Received an unhandled message for a specific state
- unhandled:
-  if(verbose && !pmt_eq(event, pmt_intern("%shutdown")))
-    std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
-              << "in state "<< d_state << std::endl;
-}
-
-
-void
-test_usrp_rx::open_usrp()
-{
-  pmt_t which_usrp = pmt_from_long(0);
-
-  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
-  d_state = OPENING_USRP;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_RX] Opening the USRP\n";
-}
-
-void
-test_usrp_rx::close_usrp()
-{
-
-  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
-  d_state = CLOSING_USRP;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_RX] Closing the USRP\n";
-}
-
-void
-test_usrp_rx::allocate_channel()
-{
-  long capacity = (long) 16e6;
-  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-  d_state = ALLOCATING_CHANNEL;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_RX] Requesting RX channel allocation\n";
-}
-
-void
-test_usrp_rx::enter_receiving()
-{
-  d_state = RECEIVING;
-
-  d_rx->send(s_cmd_start_recv_raw_samples,
-             pmt_list2(PMT_F,
-                       d_rx_chan));
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_RX] Receiving...\n";
-}
-
-void
-test_usrp_rx::handle_response_recv_raw_samples(pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  pmt_t status = pmt_nth(1, data);
-  pmt_t v_samples = pmt_nth(2, data);
-  pmt_t timestamp = pmt_nth(3, data);
-  pmt_t channel = pmt_nth(4, data);
-  pmt_t properties = pmt_nth(5, data);
-
-  d_samples_recvd += pmt_length(v_samples) / 4;
-
-  // Check for overrun
-  if(!pmt_is_dict(properties)) {
-    std::cout << "[TEST_USRP_INBAND_RX] Recv samples dictionary is improper\n";
-    return;
-  }
-
-  // Check if the number samples we have received meets the test
-  if(d_samples_recvd >= d_samples_to_recv) {
-    d_rx->send(s_cmd_stop_recv_raw_samples, pmt_list2(PMT_NIL, d_rx_chan));
-    enter_closing_channel();
-    return;
-  }
-
-}
-
-void
-test_usrp_rx::enter_closing_channel()
-{
-  d_state = CLOSING_CHANNEL;
-
-  d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan));
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_RX] Deallocating RX channel\n";
-}
-
-REGISTER_MBLOCK_CLASS(test_usrp_rx);
-
-
-// ----------------------------------------------------------------
-
-int
-main (int argc, char **argv)
-{
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_NIL;
-
-  rt->run("top", "test_usrp_rx", PMT_F, &result);
-
-}
diff --git a/usrp/host/apps-inband/test_usrp_inband_timestamps.cc b/usrp/host/apps-inband/test_usrp_inband_timestamps.cc
deleted file mode 100644 (file)
index 3b874d1..0000000
+++ /dev/null
@@ -1,506 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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 <mblock/mblock.h>
-#include <mblock/runtime.h>
-#include <mblock/protocol_class.h>
-#include <mblock/exception.h>
-#include <mblock/msg_queue.h>
-#include <mblock/message.h>
-#include <mblock/msg_accepter.h>
-#include <mblock/class_registry.h>
-#include <pmt.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/time.h>
-#include <iostream>
-
-#include <ui_nco.h>
-#include <symbols_usrp_server_cs.h>
-#include <symbols_usrp_channel.h>
-#include <symbols_usrp_low_level_cs.h>
-#include <symbols_usrp_tx.h>
-#include <symbols_usrp_rx.h>
-
-#define NBPING  10
-
-static bool verbose = true;
-bool bskip = false;
-long bstep = 10000;
-long bcurr = 0;
-long incr = 0x500;
-long ptime = 0x000;
-
-class test_usrp_inband_timestamps : public mb_mblock
-{
-  mb_port_sptr         d_tx;
-  mb_port_sptr         d_rx;
-  mb_port_sptr         d_cs;
-  pmt_t                d_tx_chan;      // returned tx channel handle
-  pmt_t                d_rx_chan;      // returned tx channel handle
-
-  struct timeval times[NBPING];
-
-  enum state_t {
-    INIT,
-    OPENING_USRP,
-    ALLOCATING_CHANNEL,
-    TRANSMITTING,
-    CLOSING_CHANNEL,
-    CLOSING_USRP,
-  };
-
-  state_t      d_state;
-  long         d_nsamples_to_send;
-  long         d_nsamples_xmitted;
-  long         d_nframes_xmitted;
-  long         d_samples_per_frame;
-  bool         d_done_sending;
-
-  // for generating sine wave output
-  ui_nco<float,float>  d_nco;
-  double               d_amplitude;
-
- public:
-  test_usrp_inband_timestamps(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~test_usrp_inband_timestamps();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void open_usrp();
-  void close_usrp();
-  void allocate_channel();
-  void send_packets();
-  void enter_receiving();
-  void enter_transmitting();
-  void build_and_send_ping();
-  void build_and_send_next_frame();
-  void handle_xmit_response(pmt_t invocation_handle);
-  void enter_closing_channel();
-};
-
-test_usrp_inband_timestamps::test_usrp_inband_timestamps(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg),
-    d_tx_chan(PMT_NIL),
-    d_rx_chan(PMT_NIL),
-    d_state(INIT), d_nsamples_to_send((long) 40e6),
-    d_nsamples_xmitted(0),
-    d_nframes_xmitted(0),
-    //d_samples_per_frame((long)(126)),
-    d_samples_per_frame((long)(126 * 2)),      // non-full packet
-    //d_samples_per_frame((long)(126 * 3.5)),  // non-full packet
-    //d_samples_per_frame((long)(126 * 4)),    // full packet
-    d_done_sending(false),
-    d_amplitude(16384)
-{ 
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Initializing...\n";
-  
-  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
-  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-  
-  bool fake_usrp_p = false;
-
-  // Test the TX side
-
-  pmt_t usrp_dict = pmt_make_dict();
-
-  if(fake_usrp_p) {
-    pmt_dict_set(usrp_dict, 
-                 pmt_intern("fake-usrp"),
-                            PMT_T);
-  }
-
-  // Set TX and RX interpolations
-  pmt_dict_set(usrp_dict,
-               pmt_intern("interp-tx"),
-               pmt_from_long(128));
-
-  pmt_dict_set(usrp_dict,
-               pmt_intern("decim-rx"),
-               pmt_from_long(16));
-
-  // Specify the RBF to use
-  pmt_dict_set(usrp_dict,
-               pmt_intern("rbf"),
-               pmt_intern("inband_1rxhb_1tx.rbf"));
-
-  define_component("server", "usrp_server", usrp_dict);
-
-  connect("self", "tx0", "server", "tx0");
-  connect("self", "rx0", "server", "rx0");
-  connect("self", "cs", "server", "cs");
-
-  // initialize NCO
-  double freq = 100e3;
-  int interp = 32;                         // 32 -> 4MS/s
-  double sample_rate = 128e6 / interp; 
-  d_nco.set_freq(2*M_PI * freq/sample_rate);
-
-}
-
-test_usrp_inband_timestamps::~test_usrp_inband_timestamps()
-{
-}
-
-void
-test_usrp_inband_timestamps::initial_transition()
-{
-  open_usrp();
-}
-
-void
-test_usrp_inband_timestamps::handle_message(mb_message_sptr msg)
-{
-  pmt_t        event = msg->signal();
-  pmt_t data = msg->data();
-  pmt_t port_id = msg->port_id();
-
-  pmt_t handle = PMT_F;
-  pmt_t status = PMT_F;
-  std::string error_msg;
-  
-  //std::cout << msg << std::endl;
-
-  switch(d_state){
-  case OPENING_USRP:
-    if (pmt_eq(event, s_response_open)){
-      status = pmt_nth(1, data);
-      if (pmt_eq(status, PMT_T)){
-        allocate_channel();
-        return;
-      }
-      else {
-        error_msg = "failed to open usrp:";
-        goto bail;
-      }
-    }
-    goto unhandled;
-    
-  case ALLOCATING_CHANNEL:
-    if (pmt_eq(event, s_response_allocate_channel)){
-
-      if(pmt_eq(d_tx->port_symbol(), port_id)) {
-        status = pmt_nth(1, data);
-        d_tx_chan = pmt_nth(2, data);
-
-        if (pmt_eq(status, PMT_T)){
-
-          if(verbose)
-            std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Received allocation for TX\n";
-
-          if(!pmt_eqv(d_rx_chan, PMT_NIL)) {
-            enter_receiving();
-            enter_transmitting();
-          }
-          return;
-        }
-        else {
-          error_msg = "failed to allocate channel:";
-          goto bail;
-        }
-      }
-      
-      if(pmt_eq(d_rx->port_symbol(), port_id)) {
-        status = pmt_nth(1, data);
-        d_rx_chan = pmt_nth(2, data);
-
-        if (pmt_eq(status, PMT_T)){
-
-          if(verbose)
-            std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Received allocation for TX\n";
-          
-          if(!pmt_eqv(d_tx_chan, PMT_NIL)) {
-            enter_receiving();
-            enter_transmitting();
-          }
-          return;
-        }
-        else {
-          error_msg = "failed to allocate channel:";
-          goto bail;
-        }
-      }
-    }
-    goto unhandled;
-
-  case TRANSMITTING:
-    if (pmt_eq(event, s_response_xmit_raw_frame)){
-      handle = pmt_nth(0, data);
-      status = pmt_nth(1, data);
-
-      if (pmt_eq(status, PMT_T)){
-        handle_xmit_response(handle);
-        return;
-      }
-      else {
-        error_msg = "bad response-xmit-raw-frame:";
-        goto bail;
-      }
-    }
-
-    if (pmt_eq(event, s_response_from_control_channel)) {
-      std::cout << "ping response!\n";
-    }
-    goto unhandled;
-
-  case CLOSING_CHANNEL:
-    if (pmt_eq(event, s_response_deallocate_channel)){
-      status = pmt_nth(1, data);
-
-      if (pmt_eq(status, PMT_T)){
-        close_usrp();
-        return;
-      }
-      else {
-        error_msg = "failed to deallocate channel:";
-        goto bail;
-      }
-    }
-    goto unhandled;
-
-  case CLOSING_USRP:
-    if (pmt_eq(event, s_response_close)){
-      status = pmt_nth(1, data);
-
-      if (pmt_eq(status, PMT_T)){
-        shutdown_all(PMT_T);
-        return;
-      }
-      else {
-        error_msg = "failed to close USRP:";
-        goto bail;
-      }
-    }
-    goto unhandled;
-
-  default:
-    goto unhandled;
-  }
-  return;
-
- bail:
-  std::cerr << error_msg << data
-           << "status = " << status << std::endl;
-  shutdown_all(PMT_F);
-  return;
-
- unhandled:
-  if(verbose && 0)
-    std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
-              << "in state "<< d_state << std::endl;
-}
-
-
-void
-test_usrp_inband_timestamps::open_usrp()
-{
-  pmt_t which_usrp = pmt_from_long(0);
-
-  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
-  d_state = OPENING_USRP;
-}
-
-void
-test_usrp_inband_timestamps::close_usrp()
-{
-  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
-  d_state = CLOSING_USRP;
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Closing USRP\n";
-}
-
-void
-test_usrp_inband_timestamps::allocate_channel()
-{
-  long capacity = (long) 16e6;
-  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-  d_state = ALLOCATING_CHANNEL;
-}
-
-void
-test_usrp_inband_timestamps::enter_receiving()
-{
-  d_rx->send(s_cmd_start_recv_raw_samples,
-             pmt_list2(PMT_F,
-                       d_rx_chan));
-}
-
-void
-test_usrp_inband_timestamps::enter_transmitting()
-{
-  d_state = TRANSMITTING;
-  d_nsamples_xmitted = 0;
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Beginning transmission\n";
-
-  sleep(1);
-
-  build_and_send_next_frame();
-  build_and_send_next_frame();
-  build_and_send_next_frame();
-  build_and_send_next_frame();
-
-}
-
-void
-test_usrp_inband_timestamps::build_and_send_ping()
-{
-  
-  d_tx->send(s_cmd_to_control_channel,
-             pmt_list2(PMT_NIL, pmt_list1(pmt_list2(s_op_ping_fixed,
-                                                    pmt_list2(pmt_from_long(0),
-                                                              pmt_from_long(0))))));
-  if(verbose && 0)
-    std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Ping sent" << std::endl;
-}
-
-void
-test_usrp_inband_timestamps::build_and_send_next_frame()
-{
-  // allocate the uniform vector for the samples
-  // FIXME perhaps hold on to this between calls
-
-#if 0
-  long nsamples_this_frame =
-    std::min(d_nsamples_to_send - d_nsamples_xmitted,
-            d_samples_per_frame);
-#else
-  long nsamples_this_frame = d_samples_per_frame;
-#endif
-
-  if (nsamples_this_frame == 0){
-    d_done_sending = true;
-    return;
-  }
-    
-
-  size_t nshorts = 2 * nsamples_this_frame;    // 16-bit I & Q
-  pmt_t uvec = pmt_make_s16vector(nshorts, 0);
-  size_t ignore;
-  int16_t *samples = pmt_s16vector_writable_elements(uvec, ignore);
-
-  // fill in the complex sinusoid
-
-  for (int i = 0; i < nsamples_this_frame; i++){
-
-    if (1){
-      gr_complex s;
-      d_nco.sincos(&s, 1, d_amplitude);
-      // write 16-bit i & q
-      samples[2*i] =   (int16_t) s.real();
-      samples[2*i+1] = (int16_t) s.imag();
-    }
-    else {
-      gr_complex s(d_amplitude, d_amplitude);
-
-      // write 16-bit i & q
-      samples[2*i] =   (int16_t) s.real();
-      samples[2*i+1] = (int16_t) s.imag();
-    }
-  }
-
-  pmt_t timestamp;
-
-  if(bskip) {
-    timestamp = pmt_from_long(0x0);    // throw away  
-    bcurr++;
-    if(bcurr == bstep) {
-      bskip = false;
-      bcurr = 0;
-    }
-  } else {
-    timestamp = pmt_from_long(0xffffffff);     // NOW
-    timestamp = pmt_from_long(ptime);
-    ptime += incr;
-    bcurr++;
-    if(bcurr == bstep) {
-      //bskip = true;
-      bcurr = 0;
-    }
-  }
-
-  std::cout << bskip << " -- " << bcurr << std::endl;
-
-  d_tx->send(s_cmd_xmit_raw_frame,
-            pmt_list4(pmt_from_long(d_nframes_xmitted),  // invocation-handle
-                      d_tx_chan,                         // channel
-                      uvec,                              // the samples
-                      timestamp));
-
-  d_nsamples_xmitted += nsamples_this_frame;
-  d_nframes_xmitted++;
-
-  if(verbose && 0)
-    std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Transmitted frame\n";
-  
-  //build_and_send_next_frame();
-}
-
-
-void
-test_usrp_inband_timestamps::handle_xmit_response(pmt_t handle)
-{
-  if (d_done_sending &&
-      pmt_to_long(handle) == (d_nframes_xmitted - 1)){
-    // We're done sending and have received all responses
-    enter_closing_channel();
-  }
-
-  build_and_send_next_frame();
-  //build_and_send_ping();
-}
-
-void
-test_usrp_inband_timestamps::enter_closing_channel()
-{
-  d_state = CLOSING_CHANNEL;
-  
-  d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan));
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Closing channel\n";
-}
-
-REGISTER_MBLOCK_CLASS(test_usrp_inband_timestamps);
-
-
-// ----------------------------------------------------------------
-
-int
-main (int argc, char **argv)
-{
-  // handle any command line args here
-
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_NIL;
-
-  rt->run("top", "test_usrp_inband_timestamps", PMT_F, &result);
-}
diff --git a/usrp/host/apps-inband/test_usrp_inband_tx.cc b/usrp/host/apps-inband/test_usrp_inband_tx.cc
deleted file mode 100644 (file)
index 9f294e7..0000000
+++ /dev/null
@@ -1,411 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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 <mblock/mblock.h>
-#include <mblock/runtime.h>
-#include <mblock/protocol_class.h>
-#include <mblock/exception.h>
-#include <mblock/msg_queue.h>
-#include <mblock/message.h>
-#include <mblock/msg_accepter.h>
-#include <mblock/class_registry.h>
-#include <pmt.h>
-#include <stdio.h>
-#include <string.h>
-#include <iostream>
-
-#include <ui_nco.h>
-#include <symbols_usrp_server_cs.h>
-#include <symbols_usrp_channel.h>
-#include <symbols_usrp_low_level_cs.h>
-#include <symbols_usrp_tx.h>
-
-static bool verbose = true;
-
-class test_usrp_tx : public mb_mblock
-{
-  mb_port_sptr         d_tx;
-  mb_port_sptr         d_cs;
-  pmt_t                d_tx_chan;      // returned tx channel handle
-
-  enum state_t {
-    INIT,
-    OPENING_USRP,
-    ALLOCATING_CHANNEL,
-    TRANSMITTING,
-    CLOSING_CHANNEL,
-    CLOSING_USRP,
-  };
-
-  state_t      d_state;
-  long         d_nsamples_to_send;
-  long         d_nsamples_xmitted;
-  long         d_nframes_xmitted;
-  long         d_samples_per_frame;
-  bool         d_done_sending;
-
-  // for generating sine wave output
-  ui_nco<float,float>  d_nco;
-  double               d_amplitude;
-
- public:
-  test_usrp_tx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~test_usrp_tx();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void open_usrp();
-  void close_usrp();
-  void allocate_channel();
-  void send_packets();
-  void enter_transmitting();
-  void build_and_send_next_frame();
-  void handle_xmit_response(pmt_t invocation_handle);
-  void enter_closing_channel();
-};
-
-test_usrp_tx::test_usrp_tx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg),
-    d_state(INIT), d_nsamples_to_send((long) 80e6),
-    d_nsamples_xmitted(0),
-    d_nframes_xmitted(0),
-    d_samples_per_frame((long)(126 * 4)),      // full packet
-    d_done_sending(false),
-    d_amplitude(16384)
-{ 
-  // std::cout << "[TEST_USRP_TX] Initializing...\n";
-  
-  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-  
-  //bool fake_usrp_p = true;
-  bool fake_usrp_p = false;
-
-  // Test the TX side
-
-  pmt_t usrp_dict = pmt_make_dict();
-
-  if(fake_usrp_p) {
-    pmt_dict_set(usrp_dict, 
-                 pmt_intern("fake-usrp"),
-                            PMT_T);
-  }
-  
-  // Specify the RBF to use
-  pmt_dict_set(usrp_dict,
-               pmt_intern("rbf"),
-               pmt_intern("inband_1rxhb_1tx.rbf"));
-
-  // Set TX and RX interpolations
-  pmt_dict_set(usrp_dict,
-               pmt_intern("interp-tx"),
-               pmt_from_long(64));
-
-//  If unspecified, chooses center frequency from range
-//  pmt_dict_set(usrp_dict,
-//               pmt_intern("rf-freq"),
-//               pmt_from_long(10e6));
-
-  define_component("server", "usrp_server", usrp_dict);
-
-  connect("self", "tx0", "server", "tx0");
-  connect("self", "cs", "server", "cs");
-
-  // initialize NCO
-  double freq = 100e3;
-  int interp = 32;                         // 32 -> 4MS/s
-  double sample_rate = 128e6 / interp; 
-  d_nco.set_freq(2*M_PI * freq/sample_rate);
-
-  // FIXME need to somehow set the interp rate in the USRP.
-  // for now, we'll have the low-level code hardwire it.
-}
-
-test_usrp_tx::~test_usrp_tx()
-{
-}
-
-void
-test_usrp_tx::initial_transition()
-{
-  open_usrp();
-}
-
-void
-test_usrp_tx::handle_message(mb_message_sptr msg)
-{
-  pmt_t        event = msg->signal();
-  pmt_t data = msg->data();
-
-  pmt_t handle = PMT_F;
-  pmt_t status = PMT_F;
-  std::string error_msg;
-  
-  //std::cout << msg << std::endl;
-
-  switch(d_state){
-  case OPENING_USRP:
-    if (pmt_eq(event, s_response_open)){
-      status = pmt_nth(1, data);
-      if (pmt_eq(status, PMT_T)){
-        allocate_channel();
-        return;
-      }
-      else {
-        error_msg = "failed to open usrp:";
-        goto bail;
-      }
-    }
-    goto unhandled;
-    
-  case ALLOCATING_CHANNEL:
-    if (pmt_eq(event, s_response_allocate_channel)){
-      status = pmt_nth(1, data);
-      d_tx_chan = pmt_nth(2, data);
-
-      if (pmt_eq(status, PMT_T)){
-        enter_transmitting();
-        return;
-      }
-      else {
-        error_msg = "failed to allocate channel:";
-        goto bail;
-      }
-    }
-    goto unhandled;
-
-  case TRANSMITTING:
-    if (pmt_eq(event, s_response_xmit_raw_frame)){
-      handle = pmt_nth(0, data);
-      status = pmt_nth(1, data);
-
-      if (pmt_eq(status, PMT_T)){
-        handle_xmit_response(handle);
-        return;
-      }
-      else {
-        error_msg = "bad response-xmit-raw-frame:";
-        goto bail;
-      }
-    }
-    goto unhandled;
-
-  case CLOSING_CHANNEL:
-    if (pmt_eq(event, s_response_deallocate_channel)){
-      status = pmt_nth(1, data);
-
-      if (pmt_eq(status, PMT_T)){
-        close_usrp();
-        return;
-      }
-      else {
-        error_msg = "failed to deallocate channel:";
-        goto bail;
-      }
-    }
-    goto unhandled;
-
-  case CLOSING_USRP:
-    if (pmt_eq(event, s_response_close)){
-      status = pmt_nth(1, data);
-
-      if (pmt_eq(status, PMT_T)){
-        shutdown_all(PMT_T);
-        return;
-      }
-      else {
-        error_msg = "failed to close USRP:";
-        goto bail;
-      }
-    }
-    goto unhandled;
-
-  default:
-    goto unhandled;
-  }
-  return;
-
- bail:
-  std::cerr << error_msg << data
-           << "status = " << status << std::endl;
-  shutdown_all(PMT_F);
-  return;
-
- unhandled:
-  std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
-           << "in state "<< d_state << std::endl;
-}
-
-
-void
-test_usrp_tx::open_usrp()
-{
-  pmt_t which_usrp = pmt_from_long(0);
-
-  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
-  d_state = OPENING_USRP;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_TX] Opening the USRP\n";
-}
-
-void
-test_usrp_tx::close_usrp()
-{
-  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
-  d_state = CLOSING_USRP;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_TX] Closing the USRP\n";
-}
-
-void
-test_usrp_tx::allocate_channel()
-{
-  long capacity = (long) 16e6;
-  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-  d_state = ALLOCATING_CHANNEL;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_TX] Requesting TX channel allocation\n";
-}
-
-void
-test_usrp_tx::enter_transmitting()
-{
-  d_state = TRANSMITTING;
-  d_nsamples_xmitted = 0;
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_TX] Transmitting...\n";
-  
-  build_and_send_next_frame(); // fire off 4 to start pipeline
-  build_and_send_next_frame();
-  build_and_send_next_frame();
-  build_and_send_next_frame();
-}
-
-void
-test_usrp_tx::build_and_send_next_frame()
-{
-  // allocate the uniform vector for the samples
-  // FIXME perhaps hold on to this between calls
-
-#if 1
-  long nsamples_this_frame =
-    std::min(d_nsamples_to_send - d_nsamples_xmitted,
-            d_samples_per_frame);
-#else
-  long nsamples_this_frame = d_samples_per_frame;
-#endif
-
-  if (nsamples_this_frame == 0){
-    d_done_sending = true;
-    return;
-  }
-    
-
-  size_t nshorts = 2 * nsamples_this_frame;    // 16-bit I & Q
-  pmt_t uvec = pmt_make_s16vector(nshorts, 0);
-  size_t ignore;
-  int16_t *samples = pmt_s16vector_writable_elements(uvec, ignore);
-
-  // fill in the complex sinusoid
-
-  for (int i = 0; i < nsamples_this_frame; i++){
-
-    if (1){
-      gr_complex s;
-      d_nco.sincos(&s, 1, d_amplitude);
-      // write 16-bit i & q
-      samples[2*i] =   (int16_t) s.real();
-      samples[2*i+1] = (int16_t) s.imag();
-    }
-    else {
-      gr_complex s(d_amplitude, d_amplitude);
-
-      // write 16-bit i & q
-      samples[2*i] =   (int16_t) s.real();
-      samples[2*i+1] = (int16_t) s.imag();
-    }
-  }
-
-  pmt_t tx_properties = pmt_make_dict();
-
-  pmt_t timestamp = pmt_from_long(0xffffffff); // NOW
-  d_tx->send(s_cmd_xmit_raw_frame,
-            pmt_list5(pmt_from_long(d_nframes_xmitted),  // invocation-handle
-                      d_tx_chan,                         // channel
-                      uvec,                              // the samples
-                      timestamp,
-           tx_properties));
-
-  d_nsamples_xmitted += nsamples_this_frame;
-  d_nframes_xmitted++;
-
-  if(verbose && 0)
-    std::cout << "[TEST_USRP_INBAND_TX] Transmitted frame\n";
-}
-
-
-void
-test_usrp_tx::handle_xmit_response(pmt_t handle)
-{
-  if (d_done_sending &&
-      pmt_to_long(handle) == (d_nframes_xmitted - 1)){
-    // We're done sending and have received all responses
-    enter_closing_channel();
-  }
-
-  build_and_send_next_frame();
-}
-
-void
-test_usrp_tx::enter_closing_channel()
-{
-  d_state = CLOSING_CHANNEL;
-  
-  d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan));
-  
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_tX] Deallocating TX channel\n";
-}
-
-REGISTER_MBLOCK_CLASS(test_usrp_tx);
-
-
-// ----------------------------------------------------------------
-
-int
-main (int argc, char **argv)
-{
-  // handle any command line args here
-
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_NIL;
-
-  rt->run("top", "test_usrp_tx", PMT_F, &result);
-}
diff --git a/usrp/host/apps-inband/test_usrp_inband_underrun.cc b/usrp/host/apps-inband/test_usrp_inband_underrun.cc
deleted file mode 100644 (file)
index 11babb0..0000000
+++ /dev/null
@@ -1,674 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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 <mblock/mblock.h>
-#include <mblock/runtime.h>
-#include <mblock/protocol_class.h>
-#include <mblock/exception.h>
-#include <mblock/msg_queue.h>
-#include <mblock/message.h>
-#include <mblock/msg_accepter.h>
-#include <mblock/class_registry.h>
-#include <pmt.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/time.h>
-#include <iostream>
-#include <ui_nco.h>
-
-// Include the symbols needed for communication with USRP server
-#include <symbols_usrp_server_cs.h>
-#include <symbols_usrp_channel.h>
-#include <symbols_usrp_low_level_cs.h>
-#include <symbols_usrp_tx.h>
-#include <symbols_usrp_rx.h>
-
-static bool verbose = true;
-
-class test_usrp_inband_underrun : public mb_mblock
-{
-
-  mb_port_sptr  d_tx;   // Ports connected to the USRP server
-  mb_port_sptr  d_rx;
-  mb_port_sptr  d_cs;
-
-  pmt_t   d_tx_chan;    // Returned channel from TX allocation
-  pmt_t   d_rx_chan;    // Returned channel from RX allocation
-
-  pmt_t   d_which_usrp; // The USRP to use for the test
-
-  long    d_warm_msgs;  // The number of messages to 'warm' the USRP
-  long    d_warm_recvd; // The number of msgs received in the 'warm' state
-
-  // Keep track of current state
-  enum state_t {
-    INIT,
-    OPENING_USRP,
-    ALLOCATING_CHANNELS,
-    WRITE_REGISTER,
-    READ_REGISTER,
-    TRANSMITTING,
-    CLOSING_CHANNELS,
-    CLOSING_USRP,
-  };
-  state_t d_state;
-  
-  long         d_nsamples_to_send;
-  long         d_nsamples_xmitted;
-  long         d_nframes_xmitted;
-  long         d_samples_per_frame;
-  bool         d_done_sending;
-
-  // for generating sine wave output
-  ui_nco<float,float>  d_nco;
-  double               d_amplitude;
-
-  long d_n_underruns;
-
- public:
-  test_usrp_inband_underrun(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~test_usrp_inband_underrun();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void opening_usrp();
-  void allocating_channels();
-  void write_register();
-  void read_register();
-  void closing_channels();
-  void closing_usrp();
-  void enter_receiving();
-  void enter_transmitting();
-  void build_and_send_ping();
-  void build_and_send_next_frame();
-  void handle_xmit_response(pmt_t handle);
-  void handle_recv_response(pmt_t dict);
-};
-
-
-int
-main (int argc, char **argv)
-{
-  // handle any command line args here
-
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_NIL;
-
-  rt->run("top", "test_usrp_inband_underrun", PMT_F, &result);
-}
-
-
-test_usrp_inband_underrun::test_usrp_inband_underrun(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg),
-  d_tx_chan(PMT_NIL),
-  d_rx_chan(PMT_NIL),
-  d_which_usrp(pmt_from_long(0)),
-  d_state(INIT),
-  d_nsamples_to_send((long) 27e6),
-  d_nsamples_xmitted(0),
-  d_nframes_xmitted(0),
-  d_samples_per_frame(d_nsamples_to_send),     // full packet
-
-  d_done_sending(false),
-  d_amplitude(16384),
-  d_n_underruns(0)
-{
-  
-  // A dictionary is used to pass parameters to the USRP
-  pmt_t usrp_dict = pmt_make_dict();
-
-  // Specify the RBF to use
-  pmt_dict_set(usrp_dict,
-               pmt_intern("rbf"),
-               pmt_intern("inband_1rxhb_1tx.rbf"));
-
-  // Set TX and RX interpolations
-  pmt_dict_set(usrp_dict,
-               pmt_intern("interp-tx"),
-               pmt_from_long(64));
-
-  pmt_dict_set(usrp_dict,
-               pmt_intern("decim-rx"),
-               pmt_from_long(128));
-  
-  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
-  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-
-  // Create an instance of USRP server and connect ports
-  define_component("server", "usrp_server", usrp_dict);
-  connect("self", "tx0", "server", "tx0");
-  connect("self", "rx0", "server", "rx0");
-  connect("self", "cs", "server", "cs");
-
-  // initialize NCO
-  double freq = 100e3;
-  int interp = 32;                         // 32 -> 4MS/s
-  double sample_rate = 128e6 / interp; 
-  d_nco.set_freq(2*M_PI * freq/sample_rate);
-}
-
-test_usrp_inband_underrun::~test_usrp_inband_underrun()
-{
-}
-
-void
-test_usrp_inband_underrun::initial_transition()
-{
-  opening_usrp();
-}
-
-// Handle message reads all incoming messages from USRP server which will be
-// initialization and ping responses.  We perform actions based on the current
-// state and the event (ie, ping response)
-void
-test_usrp_inband_underrun::handle_message(mb_message_sptr msg)
-{
-  pmt_t event = msg->signal();
-  pmt_t data = msg->data();
-  pmt_t port_id = msg->port_id();
-
-  pmt_t handle = PMT_F;
-  pmt_t status = PMT_F;
-  pmt_t dict = PMT_NIL;
-  std::string error_msg;
-      
-  // Check the recv sample responses for underruns and count
-  if(pmt_eq(event, s_response_recv_raw_samples)) {
-    handle = pmt_nth(0, data);
-    status = pmt_nth(1, data);
-    dict   = pmt_nth(4, data);
-
-    if(pmt_eq(status, PMT_T)) {
-      handle_recv_response(dict);
-      return;
-    }
-    else {
-      error_msg = "error while receiving samples:";
-      goto bail;
-    }
-  }
-
-
-  // Dispatch based on state
-  switch(d_state) {
-
-    //----------------------------- OPENING_USRP ----------------------------//
-    // We only expect a response from opening the USRP which should be succesful
-    // or failed.
-    case OPENING_USRP:
-      
-      if(pmt_eq(event, s_response_open)) {
-
-        status = pmt_nth(1, data);          // failed/succes
-        
-        if(pmt_eq(status, PMT_T)) {
-          allocating_channels();
-          return;
-        }
-        else {
-          error_msg = "failed to open usrp:";
-          goto bail;
-        }
-
-      }
-
-      goto unhandled;   // all other messages not handled in this state
-      
-    
-    //----------------------- ALLOCATING CHANNELS --------------------//
-    // When allocating channels, we need to wait for 2 responses from
-    // USRP server: one for TX and one for RX.  Both are initialized to
-    // NIL so we know to continue to the next state once both are set.
-    case ALLOCATING_CHANNELS:
-
-      // A TX allocation response
-      if(pmt_eq(event, s_response_allocate_channel)
-          && pmt_eq(d_tx->port_symbol(), port_id)) 
-      {
-        status = pmt_nth(1, data);
-        
-        // If successful response, extract the channel
-        if(pmt_eq(status, PMT_T)) {
-          
-          d_tx_chan = pmt_nth(2, data);
-
-          if(verbose)
-            std::cout << "[TEST_USRP_INBAND_UNDERRUN] Received TX allocation"
-                      << " on channel " << d_tx_chan << std::endl;
-
-          // If the RX has also been allocated already, we can continue
-          if(!pmt_eqv(d_rx_chan, PMT_NIL)) {
-            enter_receiving();
-            enter_transmitting();
-          }
-
-          return;
-        }
-        else {  // TX allocation failed
-          error_msg = "failed to allocate TX channel:";
-          goto bail;
-        }
-      }
-      
-      // A RX allocation response
-      if(pmt_eq(event, s_response_allocate_channel)
-          && pmt_eq(d_rx->port_symbol(), port_id)) 
-      {
-        status = pmt_nth(1, data);
-        
-        // If successful response, extract the channel
-        if(pmt_eq(status, PMT_T)) {
-          
-          d_rx_chan = pmt_nth(2, data);
-
-          if(verbose)
-            std::cout << "[TEST_USRP_INBAND_UNDERRUN] Received RX allocation"
-                      << " on channel " << d_rx_chan << std::endl;
-
-          // If the TX has also been allocated already, we can continue
-          if(!pmt_eqv(d_tx_chan, PMT_NIL)) {
-            enter_receiving();
-            enter_transmitting();
-          }
-
-          return;
-        }
-        else {  // RX allocation failed
-          error_msg = "failed to allocate RX channel:";
-          goto bail;
-        }
-      }
-
-      goto unhandled;
-
-    case WRITE_REGISTER:
-      goto unhandled;
-
-    case READ_REGISTER:
-      goto unhandled;
-
-    //-------------------------- TRANSMITTING ----------------------------//
-    // In the transmit state we count the number of underruns received and
-    // ballpark the number with an expected count (something >1 for starters)
-    case TRANSMITTING:
-      
-      // Check that the transmits are OK
-      if (pmt_eq(event, s_response_xmit_raw_frame)){
-        handle = pmt_nth(0, data);
-        status = pmt_nth(1, data);
-
-        if (pmt_eq(status, PMT_T)){
-          handle_xmit_response(handle);
-          return;
-        }
-        else {
-          error_msg = "bad response-xmit-raw-frame:";
-          goto bail;
-        }
-      }
-
-      goto unhandled;
-
-    //------------------------- CLOSING CHANNELS ----------------------------//
-    // Check deallocation responses, once the TX and RX channels are both
-    // deallocated then we close the USRP.
-    case CLOSING_CHANNELS:
-      
-      if (pmt_eq(event, s_response_deallocate_channel)
-          && pmt_eq(d_tx->port_symbol(), port_id))
-      {
-        status = pmt_nth(1, data);
-
-        // If successful, set the port to NIL
-        if(pmt_eq(status, PMT_T)) {
-          d_tx_chan = PMT_NIL;
-
-          if(verbose)
-            std::cout << "[TEST_USRP_INBAND_UNDERRUN] Received TX deallocation\n";
-
-          // If the RX is also deallocated, we can close the USRP
-          if(pmt_eq(d_rx_chan, PMT_NIL)) 
-            closing_usrp();
-
-          return;
-
-        } else {
-
-          error_msg = "failed to deallocate TX channel:";
-          goto bail;
-
-        }
-      }
-
-      if (pmt_eq(event, s_response_deallocate_channel)
-          && pmt_eq(d_rx->port_symbol(), port_id))
-      {
-        status = pmt_nth(1, data);
-
-        // If successful, set the port to NIL
-        if(pmt_eq(status, PMT_T)) {
-          d_rx_chan = PMT_NIL;
-
-          if(verbose)
-            std::cout << "[TEST_USRP_INBAND_UNDERRUN] Received RX deallocation\n";
-
-          // If the TX is also deallocated, we can close the USRP
-          if(pmt_eq(d_tx_chan, PMT_NIL)) 
-            closing_usrp();
-
-          return;
-
-        } else {
-          
-          error_msg = "failed to deallocate RX channel:";
-          goto bail;
-
-        }
-      }
-
-      goto unhandled;
-
-    //--------------------------- CLOSING USRP ------------------------------//
-    // Once we have received a successful USRP close response, we shutdown all
-    // mblocks and exit.
-    case CLOSING_USRP:
-      
-      if (pmt_eq(event, s_response_close)) {
-        
-        status = pmt_nth(1, data);
-
-        if(pmt_eq(status, PMT_T)) {
-
-          if(verbose)
-            std::cout << "[TEST_USRP_INBAND_UNDERRUN] Successfully closed USRP\n";
-
-          std::cout << "\nUnderruns: " << d_n_underruns << std::endl;
-          fflush(stdout);
-
-          shutdown_all(PMT_T);
-          return;
-
-        } else {
-
-          error_msg = "failed to close USRP:";
-          goto bail;
-        }
-      }
-
-      goto unhandled;
-
-    case INIT:
-      goto unhandled;
-
-  }
- // An error occured, print it, and shutdown all m-blocks
- bail:
-  std::cerr << error_msg << data
-           << "status = " << status << std::endl;
-  shutdown_all(PMT_F);
-  return;
-
- // Received an unhandled message for a specific state
- unhandled:
-  if(verbose && !pmt_eq(event, pmt_intern("%shutdown")))
-    std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
-              << "in state "<< d_state << std::endl;
-
-}
-
-
-// Sends a command to USRP server to open up a connection to the
-// specified USRP, which is defaulted to USRP 0 on the system
-void
-test_usrp_inband_underrun::opening_usrp()
-{
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_UNDERRUN] Opening USRP " 
-              << d_which_usrp << std::endl;
-
-  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, d_which_usrp));
-  d_state = OPENING_USRP;
-}
-
-// RX and TX channels must be allocated so that the USRP server can
-// properly share bandwidth across multiple USRPs.  No commands will be
-// successful to the USRP through the USRP server on the TX or RX channels until
-// a bandwidth allocation has been received.
-void
-test_usrp_inband_underrun::allocating_channels()
-{
-  d_state = ALLOCATING_CHANNELS;
-
-  long capacity = (long) 16e6;
-  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-}
-
-// After allocating the channels, a write register command will be sent to the
-// USRP.
-void
-test_usrp_inband_underrun::write_register()
-{
-  d_state = WRITE_REGISTER;
-
-  long reg = 0;
-
-  d_tx->send(s_cmd_to_control_channel,    // C/S packet
-             pmt_list2(PMT_NIL,           // invoc handle
-                       pmt_list1(
-                            pmt_list2(s_op_write_reg, 
-                                      pmt_list2(
-                                      pmt_from_long(reg), 
-                                      pmt_from_long(0xbeef))))));
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_REGISTERS] Writing 0xbeef to " 
-              << reg << std::endl;
-
-  read_register();  // immediately transition to read the register
-}
-
-// Temporary: for testing pings
-void
-test_usrp_inband_underrun::build_and_send_ping()
-{
-  
-  d_tx->send(s_cmd_to_control_channel,
-             pmt_list2(PMT_NIL, pmt_list1(pmt_list2(s_op_ping_fixed,
-                                                    pmt_list2(pmt_from_long(0),
-                                                              pmt_from_long(0))))));
-
-  std::cout << "[TEST_USRP_INBAND_UNDERRUN] Ping sent" << std::endl;
-}
-
-// After writing to the register, we want to read the value back and ensure that
-// it is the same value that we wrote.
-void
-test_usrp_inband_underrun::read_register()
-{
-  d_state = READ_REGISTER;
-
-  long reg = 9;
-
-  d_tx->send(s_cmd_to_control_channel,    // C/S packet
-             pmt_list2(PMT_NIL,           // invoc handle
-                       pmt_list1(
-                            pmt_list2(s_op_read_reg, 
-                                      pmt_list2(
-                                      pmt_from_long(0),   // rid 
-                                      pmt_from_long(reg))))));
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_UNDERRUN] Reading from register " 
-              << reg << std::endl;
-}
-
-// Used to enter the receiving state
-void
-test_usrp_inband_underrun::enter_receiving()
-{
-  d_rx->send(s_cmd_start_recv_raw_samples,
-             pmt_list2(PMT_F,
-                       d_rx_chan));
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_UNDERRUN] Started RX sample stream\n";
-}
-
-void
-test_usrp_inband_underrun::enter_transmitting()
-{
-  d_state = TRANSMITTING;
-  d_nsamples_xmitted = 0;
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_UNDERRUN] Entering transmit state...\n";
-  
-  build_and_send_next_frame(); // fire off 4 to start pipeline
-  build_and_send_next_frame();
-  build_and_send_next_frame();
-  build_and_send_next_frame();
-}
-
-void
-test_usrp_inband_underrun::build_and_send_next_frame()
-{
-
-  long nsamples_this_frame =
-    std::min(d_nsamples_to_send - d_nsamples_xmitted,
-            d_samples_per_frame);
-
-  if (nsamples_this_frame == 0){
-    d_done_sending = true;
-    return;
-  }
-    
-  size_t nshorts = 2 * nsamples_this_frame;    // 16-bit I & Q
-  pmt_t uvec = pmt_make_s16vector(nshorts, 0);
-  size_t ignore;
-  int16_t *samples = pmt_s16vector_writable_elements(uvec, ignore);
-
-  // fill in the complex sinusoid
-
-  for (int i = 0; i < nsamples_this_frame; i++){
-
-    if (1){
-      gr_complex s;
-      d_nco.sincos(&s, 1, d_amplitude);
-      // write 16-bit i & q
-      samples[2*i] =   (int16_t) s.real();
-      samples[2*i+1] = (int16_t) s.imag();
-    }
-    else {
-      gr_complex s(d_amplitude, d_amplitude);
-
-      // write 16-bit i & q
-      samples[2*i] =   (int16_t) s.real();
-      samples[2*i+1] = (int16_t) s.imag();
-    }
-  }
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_TX] Transmitting frame...\n";
-
-  pmt_t timestamp = pmt_from_long(0xffffffff); // NOW
-  d_tx->send(s_cmd_xmit_raw_frame,
-            pmt_list4(pmt_from_long(d_nframes_xmitted),  // invocation-handle
-                      d_tx_chan,                         // channel
-                      uvec,                              // the samples
-                      timestamp));
-
-  d_nsamples_xmitted += nsamples_this_frame;
-  d_nframes_xmitted++;
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_TX] Transmitted frame\n";
-
-}
-
-void
-test_usrp_inband_underrun::handle_xmit_response(pmt_t handle)
-{
-  if (d_done_sending &&
-    pmt_to_long(handle) == (d_nframes_xmitted - 1)){
-    // We're done sending and have received all responses
-    closing_channels();
-    return;
-  }
-
-  build_and_send_next_frame();
-}
-
-void
-test_usrp_inband_underrun::handle_recv_response(pmt_t dict)
-{
-  if(!pmt_is_dict(dict)) {
-    std::cout << "[TEST_USRP_INBAND_UNDERRUN] Recv samples dictionary is improper\n";
-    return;
-  }
-
-  // Read the TX interpolations
-  if(pmt_t underrun = pmt_dict_ref(dict, 
-                                  pmt_intern("underrun"), 
-                                  PMT_NIL)) {
-    if(pmt_eqv(underrun, PMT_T)) {
-      d_n_underruns++;
-
-      if(verbose && 0)
-        std::cout << "[TEST_USRP_INBAND_UNDERRUN] Underrun\n";
-    }
-    else {
-    if(verbose && 0)
-      std::cout << "[TEST_USRP_INBAND_UNDERRUN] No underrun\n" << underrun <<std::endl;
-    }
-  } else {
-
-    if(verbose && 0)
-      std::cout << "[TEST_USRP_INBAND_UNDERRUN] No underrun\n";
-  }
-  
-}
-
-void
-test_usrp_inband_underrun::closing_channels()
-{
-  d_state = CLOSING_CHANNELS;
-
-  d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan));
-  d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan));
-}
-
-void
-test_usrp_inband_underrun::closing_usrp()
-{
-  d_state = CLOSING_USRP;
-
-  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
-}
-
-REGISTER_MBLOCK_CLASS(test_usrp_inband_underrun);
diff --git a/usrp/host/apps-inband/ui_nco.h b/usrp/host/apps-inband/ui_nco.h
deleted file mode 100644 (file)
index e6d7814..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2002 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_UI_NCO_H
-#define INCLUDED_UI_NCO_H
-
-
-#include <vector>
-#include <ui_sincos.h>
-#include <cmath>
-
-#include <complex>
-typedef std::complex<float>                    gr_complex;
-
-
-/*!
- * \brief base class template for Numerically Controlled Oscillator (NCO)
- */
-
-
-//FIXME  Eventually generalize this to fixed point
-
-template<class o_type, class i_type> 
-class ui_nco {
-public:
-  ui_nco () : phase (0), phase_inc(0) {}
-
-  virtual ~ui_nco () {}
-
-  // radians
-  void set_phase (double angle) {
-    phase = angle;
-  }
-
-  void adjust_phase (double delta_phase) {
-    phase += delta_phase;
-  }
-
-
-  // angle_rate is in radians / step
-  void set_freq (double angle_rate){
-    phase_inc = angle_rate;
-  }
-
-  // angle_rate is a delta in radians / step
-  void adjust_freq (double delta_angle_rate)
-  {
-    phase_inc += delta_angle_rate;
-  }
-
-  // increment current phase angle
-
-  void step () 
-  { 
-    phase += phase_inc; 
-    if (fabs (phase) > M_PI){
-      
-      while (phase > M_PI)
-       phase -= 2*M_PI;
-
-      while (phase < -M_PI)
-       phase += 2*M_PI;
-    }
-  }
-
-  void step (int n)
-  {
-    phase += phase_inc * n;
-    if (fabs (phase) > M_PI){
-      
-      while (phase > M_PI)
-       phase -= 2*M_PI;
-
-      while (phase < -M_PI)
-       phase += 2*M_PI;
-    }
-  }
-
-  // units are radians / step
-  double get_phase () const { return phase; }
-  double get_freq () const { return phase_inc; }
-
-  // compute sin and cos for current phase angle
-  void sincos (float *sinx, float *cosx) const;
-
-  // compute cos or sin for current phase angle
-  float cos () const { return std::cos (phase); }
-  float sin () const { return std::sin (phase); }
-
-  // compute a block at a time
-  void sin (float *output, int noutput_items, double ampl = 1.0);
-  void cos (float *output, int noutput_items, double ampl = 1.0);
-  void sincos (gr_complex *output, int noutput_items, double ampl = 1.0);
-  void sin (short *output, int noutput_items, double ampl = 1.0);
-  void cos (short *output, int noutput_items, double ampl = 1.0);
-  void sin (int *output, int noutput_items, double ampl = 1.0);
-  void cos (int *output, int noutput_items, double ampl = 1.0);
-
-protected:
-  double phase;
-  double phase_inc;
-};
-
-template<class o_type, class i_type> 
-void
-ui_nco<o_type,i_type>::sincos (float *sinx, float *cosx) const
-{
-  ui_sincosf (phase, sinx, cosx);
-}
-
-template<class o_type, class i_type> 
-void
-ui_nco<o_type,i_type>::sin (float *output, int noutput_items, double ampl)
-{
-  for (int i = 0; i < noutput_items; i++){
-    output[i] = (float)(sin () * ampl);
-    step ();
-  }
-}
-
-template<class o_type, class i_type> 
-void
-ui_nco<o_type,i_type>::cos (float *output, int noutput_items, double ampl)
-{
-  for (int i = 0; i < noutput_items; i++){
-    output[i] = (float)(cos () * ampl);
-    step ();
-  }
-}
-
-template<class o_type, class i_type> 
-void
-ui_nco<o_type,i_type>::sin (short *output, int noutput_items, double ampl)
-{
-  for (int i = 0; i < noutput_items; i++){
-    output[i] = (short)(sin() * ampl);
-    step ();
-  }
-}
-
-template<class o_type, class i_type> 
-void
-ui_nco<o_type,i_type>::cos (short *output, int noutput_items, double ampl)
-{
-  for (int i = 0; i < noutput_items; i++){
-    output[i] = (short)(cos () * ampl);
-    step ();
-  }
-}
-
-template<class o_type, class i_type> 
-void
-ui_nco<o_type,i_type>::sin (int *output, int noutput_items, double ampl)
-{
-  for (int i = 0; i < noutput_items; i++){
-    output[i] = (int)(sin () * ampl);
-    step ();
-  }
-}
-
-template<class o_type, class i_type> 
-void
-ui_nco<o_type,i_type>::cos (int *output, int noutput_items, double ampl)
-{
-  for (int i = 0; i < noutput_items; i++){
-    output[i] = (int)(cos () * ampl);
-    step ();
-  }
-}
-
-template<class o_type, class i_type> 
-void
-ui_nco<o_type,i_type>::sincos (gr_complex *output, int noutput_items, double ampl)
-{
-  for (int i = 0; i < noutput_items; i++){
-    float cosx, sinx;
-    sincos (&sinx, &cosx);
-    output[i] = gr_complex(cosx * ampl, sinx * ampl);
-    step ();
-  }
-}
-
-#endif /* INCLUDED_UI_NCO_H */
-
diff --git a/usrp/host/apps-inband/ui_sincos.c b/usrp/host/apps-inband/ui_sincos.c
deleted file mode 100644 (file)
index 27841f0..0000000
+++ /dev/null
@@ -1,81 +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
-
-#define _GNU_SOURCE            // ask for GNU extensions if available
-
-#include "ui_sincos.h"
-#include <math.h>
-
-// ----------------------------------------------------------------
-
-#if defined (HAVE_SINCOS)
-
-void
-ui_sincos (double x, double *sinx, double *cosx)
-{
-  sincos (x, sinx, cosx);
-}
-
-#else
-
-void
-ui_sincos (double x, double *sinx, double *cosx)
-{
-  *sinx = sin (x);
-  *cosx = cos (x);
-}
-
-#endif
-
-// ----------------------------------------------------------------
-
-#if defined (HAVE_SINCOSF)
-
-void
-ui_sincosf (float x, float *sinx, float *cosx)
-{
-  sincosf (x, sinx, cosx);
-}
-
-#elif defined (HAVE_SINF) && defined (HAVE_COSF)
-
-void
-ui_sincosf (float x, float *sinx, float *cosx)
-{
-  *sinx = sinf (x);
-  *cosx = cosf (x);
-}
-
-#else
-
-void
-ui_sincosf (float x, float *sinx, float *cosx)
-{
-  *sinx = sin (x);
-  *cosx = cos (x);
-}
-
-#endif
diff --git a/usrp/host/apps-inband/ui_sincos.h b/usrp/host/apps-inband/ui_sincos.h
deleted file mode 100644 (file)
index d2d6e4b..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2002,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.
- */
-
-#ifndef INCLUDED_UI_SINCOS_H
-#define INCLUDED_UI_SINCOS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-  
-// compute sine and cosine at the same time
-
-void ui_sincos (double x, double *sin, double *cos);
-void ui_sincosf (float x, float *sin, float *cos);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif /* INCLUDED_UI_SINCOS_H */
index 4a47daa95b1d2c8630b6411ba12c8e5c8eb7fe45..f6897ed237cd0e1fd5d42ec2f9cf740187db0c93 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2003,2006,2008 Free Software Foundation, Inc.
+ * Copyright 2003,2006,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -33,8 +33,8 @@
 #include <assert.h>
 #include <math.h>
 #include "time_stuff.h"
-#include "usrp_standard.h"
-#include "usrp_bytesex.h"
+#include <usrp/usrp_standard.h>
+#include <usrp/usrp_bytesex.h>
 #include "fpga_regs_common.h"
 #include "fpga_regs_standard.h"
 
index 3cc20c4472a7e4988bc3663c1cbd45c02f4338e1..3f8817373f7751276ac0740ad7877941ca2fbbea 100644 (file)
@@ -34,8 +34,8 @@
 #include <assert.h>
 #include <math.h>
 #include "time_stuff.h"
-#include "usrp_standard.h"
-#include "usrp_bytesex.h"
+#include <usrp/usrp_standard.h>
+#include <usrp/usrp_bytesex.h>
 #include <boost/program_options.hpp>
 
 enum {
index 5ebac12a367b9bb973c5ee28d2a5e08b3dea2bb3..22d427dff6126608a1b6b27d9bde7f0fbb44823e 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2005,2008 Free Software Foundation, Inc.
+ * Copyright 2005,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -33,9 +33,9 @@
 #include <assert.h>
 #include <math.h>
 #include <boost/scoped_ptr.hpp>
-#include "usrp_local_sighandler.h"
-#include "usrp_standard.h"
-#include "usrp_bytesex.h"
+#include <usrp/usrp_local_sighandler.h>
+#include <usrp/usrp_standard.h>
+#include <usrp/usrp_bytesex.h>
 
 char *prog_name;
 
index 3740022e0ace1342840bc7d4aa5889755445c86f..fe8ff90d2f5471f13f2d0570911be65bd65f00d8 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * USRP - Universal Software Radio Peripheral
  *
- * Copyright (C) 2003,2004 Free Software Foundation, Inc.
+ * Copyright (C) 2003,2004,2009 Free Software Foundation, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@
 #include <assert.h>
 #include <errno.h>
 
-#include "usrp_prims.h"
+#include "usrp/usrp_prims.h"
 #include "usrp_spi_defs.h"
 #include <string.h>
 
diff --git a/usrp/host/include/Makefile.am b/usrp/host/include/Makefile.am
new file mode 100644 (file)
index 0000000..5de5fe5
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# Copyright 2009 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.
+# 
+
+SUBDIRS = usrp
+
diff --git a/usrp/host/include/usrp/Makefile.am b/usrp/host/include/usrp/Makefile.am
new file mode 100644 (file)
index 0000000..91d4392
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# Copyright 2009 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
+
+usrpincludedir = $(includedir)/usrp
+
+usrpinclude_HEADERS = \
+       db_base.h \
+       db_basic.h \
+       db_dbs_rx.h \
+       db_dtt754.h \
+       db_dtt768.h \
+       db_flexrf.h \
+       db_flexrf_mimo.h \
+       db_tv_rx.h \
+       db_xcvr2450.h \
+       usrp_basic.h \
+       usrp_bytesex.h \
+       usrp_dbid.h \
+       usrp_local_sighandler.h \
+       usrp_prims.h \
+       usrp_slots.h \
+       usrp_standard.h \
+       usrp_subdev_spec.h \
+       usrp_tune_result.h
+
+if PYTHON
+swiginclude_HEADERS = \
+       db_base.i
+endif
diff --git a/usrp/host/include/usrp/db_base.h b/usrp/host/include/usrp/db_base.h
new file mode 100644 (file)
index 0000000..3547089
--- /dev/null
@@ -0,0 +1,119 @@
+/* -*- 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;
+};
+
+/******************************************************************************/
+
+/*!
+ * \brief Abstract base class for all USRP daughterboards
+ * \ingroup usrp
+ */
+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);
+  virtual bool set_bw(float bw);
+};
+
+
+std::ostream & operator<<(std::ostream &os, db_base &x);
+
+#endif /* INCLUDED_DB_BASE_H */
diff --git a/usrp/host/include/usrp/db_base.i b/usrp/host/include/usrp/db_base.i
new file mode 100644 (file)
index 0000000..78c72b8
--- /dev/null
@@ -0,0 +1,102 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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/db_base.h>
+%}
+
+%include <gr_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);
+  virtual bool set_bw(float bw);
+};
+
+// 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/include/usrp/db_basic.h b/usrp/host/include/usrp/db_basic.h
new file mode 100644 (file)
index 0000000..7f81733
--- /dev/null
@@ -0,0 +1,99 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 <usrp/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/include/usrp/db_dbs_rx.h b/usrp/host/include/usrp/db_dbs_rx.h
new file mode 100644 (file)
index 0000000..7f86963
--- /dev/null
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 <usrp/db_base.h>
+#include <vector>
+
+#if 0
+struct bw_t {
+  int m;
+  int fdac;
+  float div;
+};
+#endif
+
+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);
+  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();
+  bool  set_bw(float bw);
+};
+
+#endif
diff --git a/usrp/host/include/usrp/db_dtt754.h b/usrp/host/include/usrp/db_dtt754.h
new file mode 100644 (file)
index 0000000..4fb9528
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 <usrp/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();
+  bool 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/include/usrp/db_dtt768.h b/usrp/host/include/usrp/db_dtt768.h
new file mode 100644 (file)
index 0000000..78e157e
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 <usrp/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();
+  bool 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/include/usrp/db_flexrf.h b/usrp/host/include/usrp/db_flexrf.h
new file mode 100644 (file)
index 0000000..3adad30
--- /dev/null
@@ -0,0 +1,355 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 <usrp/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/include/usrp/db_flexrf_mimo.h b/usrp/host/include/usrp/db_flexrf_mimo.h
new file mode 100644 (file)
index 0000000..771f3b2
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2008,2009 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/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/include/usrp/db_tv_rx.h b/usrp/host/include/usrp/db_tv_rx.h
new file mode 100644 (file)
index 0000000..ee3ed2b
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 <usrp/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/include/usrp/db_xcvr2450.h b/usrp/host/include/usrp/db_xcvr2450.h
new file mode 100644 (file)
index 0000000..305c60d
--- /dev/null
@@ -0,0 +1,92 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 <usrp/db_base.h>
+#include <boost/shared_ptr.hpp>
+
+class xcvr2450;
+typedef boost::shared_ptr<xcvr2450> xcvr2450_sptr;
+
+
+/******************************************************************************/
+
+
+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;
+  void shutdown_common();
+};
+
+
+/******************************************************************************/
+
+
+class db_xcvr2450_tx : public db_xcvr2450_base
+{
+protected:
+  void shutdown();
+
+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
+{
+protected:
+  void shutdown();
+
+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/include/usrp/usrp_basic.h b/usrp/host/include/usrp/usrp_basic.h
new file mode 100644 (file)
index 0000000..fbbf49d
--- /dev/null
@@ -0,0 +1,991 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004,2008,2009 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.
+ */
+
+/*
+ * ----------------------------------------------------------------------
+ * Mid level interface to the Universal Software Radio Peripheral (Rev 1)
+ *
+ * These classes implement the basic functionality for talking to the
+ * USRP.  They try to be as independent of the signal processing code
+ * in FPGA as possible.  They implement access to the low level
+ * peripherals on the board, provide a common way for reading and
+ * writing registers in the FPGA, and provide the high speed interface
+ * to streaming data across the USB.
+ *
+ * It is expected that subclasses will be derived that provide
+ * access to the functionality to a particular FPGA configuration.
+ * ----------------------------------------------------------------------
+ */
+
+#ifndef INCLUDED_USRP_BASIC_H
+#define INCLUDED_USRP_BASIC_H
+
+#include <usrp/db_base.h>
+#include <usrp/usrp_slots.h>
+#include <string>
+#include <vector>
+#include <boost/utility.hpp>
+#include <usrp/usrp_subdev_spec.h>
+
+struct usb_dev_handle;
+class  fusb_devhandle;
+class  fusb_ephandle;
+
+enum txrx_t {
+  C_RX = 0,
+  C_TX = 1
+};
+
+/*!
+ * \brief abstract base class for usrp operations
+ * \ingroup usrp
+ */
+class usrp_basic : boost::noncopyable
+{
+protected:
+  void shutdown_daughterboards();
+
+protected:
+  struct usb_dev_handle        *d_udh;
+  int                   d_usb_data_rate;       // bytes/sec
+  int                   d_bytes_per_poll;      // how often to poll for overruns
+  bool                  d_verbose;
+  long                   d_fpga_master_clock_freq;
+
+  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 = "",
+             const std::string firmware_filename = "");
+
+  /*!
+   * \brief advise usrp_basic of usb data rate (bytes/sec)
+   *
+   * N.B., this doesn't tweak any hardware.  Derived classes
+   * should call this to inform us of the data rate whenever it's
+   * first set or if it changes.
+   *
+   * \param usb_data_rate      bytes/sec
+   */
+  void set_usb_data_rate (int usb_data_rate);
+  
+  /*!
+   * \brief Write auxiliary digital to analog converter.
+   *
+   * \param slot       Which Tx or Rx slot to write.
+   *                   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  [0,3] RX slots must use only 0 and 1.  TX slots must use only 2 and 3.
+   * \param value      [0,4095]
+   * \returns true iff successful
+   */
+  bool _write_aux_dac (int slot, int which_dac, int value);
+
+  /*!
+   * \brief Read auxiliary analog to digital converter.
+   *
+   * \param slot       2-bit slot number. E.g., SLOT_TX_A
+   * \param which_adc  [0,1]
+   * \param value      return 12-bit value [0,4095]
+   * \returns true iff successful
+   */
+  bool _read_aux_adc (int slot, int which_adc, int *value);
+
+  /*!
+   * \brief Read auxiliary analog to digital converter.
+   *
+   * \param slot       2-bit slot number. E.g., SLOT_TX_A
+   * \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);
+
+
+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
+   */
+  long fpga_master_clock_freq () const { return d_fpga_master_clock_freq; }
+
+  /*!
+   * Tell API that the master oscillator on the USRP is operating at a non-standard 
+   * fixed frequency. This is only needed for custom USRP hardware modified to 
+   * operate at a different frequency from the default factory configuration. This
+   * function must be called prior to any other API function.
+   * \param master_clock USRP2 FPGA master clock frequency in Hz (10..64 MHz)
+   */
+  void set_fpga_master_clock_freq (long master_clock) { d_fpga_master_clock_freq = master_clock; }
+
+  /*!
+   * \returns usb data rate in bytes/sec
+   */
+  int usb_data_rate () const { return d_usb_data_rate; }
+
+  void set_verbose (bool on) { d_verbose = on; }
+
+  //! magic value used on alternate register read interfaces
+  static const int READ_FAILED = -99999;
+
+  /*!
+   * \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 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
+   * \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 64 bytes.
+   */
+  std::string read_i2c (int i2c_addr, int len);
+
+  /*!
+   * \brief Set ADC offset correction
+   * \param which_adc  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_adc, int offset);
+
+  /*!
+   * \brief Set DAC offset correction
+   * \param which_dac  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_dac, int offset, int offset_pin);
+
+  /*!
+   * \brief Control ADC input buffer
+   * \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_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.
+   *
+   * \returns non-zero length string iff successful.
+   */
+  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);
+
+
+\f  // ================================================================
+  // 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\f
+  // ----------------------------------------------------------------
+  // 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\f
+
+  // ----------------------------------------------------------------
+  // Low level implementation routines.
+  // You probably shouldn't be using these...
+  //
+
+  bool _set_led (int which_led, bool on);
+
+  /*!
+   * \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
+   * \param value      32-bit value
+   * \returns true iff successful
+   */
+  bool _read_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 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
+   * \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
+   * \param value      8-bit value
+   * \returns true iff successful
+   */
+  bool _read_9862 (int which_codec, int regno, unsigned char *value) const;
+
+  /*!
+   * \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);
+
+  /*!
+   * \brief Start data transfers.
+   * Called in base class to derived class order.
+   */
+  bool start ();
+
+  /*!
+   * \brief Stop data transfers.
+   * Called in base class to derived class order.
+   */
+  bool stop ();
+};
+
+\f/*!
+ * \brief class for accessing the receive side of the USRP
+ * \ingroup usrp
+ */
+class usrp_basic_rx : public usrp_basic 
+{
+private:
+  fusb_devhandle       *d_devhandle;
+  fusb_ephandle                *d_ephandle;
+  int                   d_bytes_seen;          // how many bytes we've seen
+  bool                  d_first_read;
+  bool                  d_rx_enable;
+
+protected:
+  /*!
+   * \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 the rbf file to load
+   * \param firmware_filename name of ihx file to load
+   */
+  usrp_basic_rx (int which_board,
+                int fusb_block_size=0,
+                int fusb_nblocks=0,
+                const std::string fpga_filename = "",
+                const std::string firmware_filename = ""
+                );  // throws if trouble
+
+  bool set_rx_enable (bool on);
+  bool rx_enable () const { return d_rx_enable; }
+
+  bool disable_rx ();          // conditional disable, return prev state
+  void restore_rx (bool on);   // conditional set
+
+  void probe_rx_slots (bool verbose);
+
+public:
+  ~usrp_basic_rx ();
+
+  /*!
+   * \brief invokes constructor, returns instance or 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. 
+   * \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,
+                             int fusb_nblocks=0,
+                             const std::string fpga_filename = "",
+                             const std::string firmware_filename = ""
+                             );
+
+  /*!
+   * \brief tell the fpga the rate rx samples are coming from the A/D's
+   *
+   * div = fpga_master_clock_freq () / sample_rate
+   *
+   * sample_rate is determined by a myriad of registers
+   * in the 9862.  That's why you have to tell us, so
+   * we can tell the fpga.
+   */
+  bool set_fpga_rx_sample_rate_divisor (unsigned int div);
+
+  /*!
+   * \brief read data from the D/A's via the FPGA.
+   * \p len must be a multiple of 512 bytes.
+   *
+   * \returns the number of bytes read, or -1 on error.
+   *
+   * If overrun is non-NULL it will be set true iff an RX overrun is detected.
+   */
+  int read (void *buf, int len, bool *overrun);
+
+
+  //! sampling rate of A/D converter
+  virtual long converter_rate() const { return fpga_master_clock_freq(); } // 64M
+  long adc_rate() const { return converter_rate(); }
+  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);
+
+  int block_size() const;
+
+  // called in base class to derived class order
+  bool start ();
+  bool stop ();
+};
+
+\f/*!
+ * \brief class for accessing the transmit side of the USRP
+ * \ingroup usrp
+ */
+class usrp_basic_tx : public usrp_basic 
+{
+private:
+  fusb_devhandle       *d_devhandle;
+  fusb_ephandle                *d_ephandle;
+  int                   d_bytes_seen;          // how many bytes we've seen
+  bool                  d_first_write;
+  bool                  d_tx_enable;
+
+ protected:
+  /*!
+   * \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,
+                int fusb_nblocks=0,
+                const std::string fpga_filename = "",
+                const std::string firmware_filename = ""
+                );             // throws if trouble
+
+  bool set_tx_enable (bool on);
+  bool tx_enable () const { return d_tx_enable; }
+
+  bool disable_tx ();          // conditional disable, return prev state
+  void restore_tx (bool on);   // conditional set
+
+  void probe_tx_slots (bool verbose);
+
+public:
+
+  ~usrp_basic_tx ();
+
+  /*!
+   * \brief invokes constructor, returns instance or 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. 
+   * \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 = ""
+                             );
+
+  /*!
+   * \brief tell the fpga the rate tx samples are going to the D/A's
+   *
+   * div = fpga_master_clock_freq () * 2
+   *
+   * sample_rate is determined by a myriad of registers
+   * in the 9862.  That's why you have to tell us, so
+   * we can tell the fpga.
+   */
+  bool set_fpga_tx_sample_rate_divisor (unsigned int div);
+
+  /*!
+   * \brief Write data to the A/D's via the FPGA.
+   *
+   * \p len must be a multiple of 512 bytes.
+   * \returns number of bytes written or -1 on error.
+   *
+   * if \p underrun is non-NULL, it will be set to true iff
+   * a transmit underrun condition is detected.
+   */
+  int write (const void *buf, int len, bool *underrun);
+
+  /*
+   * Block until all outstanding writes have completed.
+   * This is typically used to assist with benchmarking
+   */
+  void wait_for_completion ();
+
+  //! 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(); }
+  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);
+
+  int block_size() const;
+
+  // called in base class to derived class order
+  bool start ();
+  bool stop ();
+};
+
+#endif
diff --git a/usrp/host/include/usrp/usrp_bytesex.h b/usrp/host/include/usrp/usrp_bytesex.h
new file mode 100644 (file)
index 0000000..331db31
--- /dev/null
@@ -0,0 +1,108 @@
+/* -*- 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.
+ */
+#ifndef INCLUDED_USRP_BYTESEX_H
+#define INCLUDED_USRP_BYTESEX_H
+
+/*!
+ * \brief routines for convertering between host and usrp byte order
+ *
+ * Prior to including this file, the user must include "config.h"
+ * which will or won't define WORDS_BIGENDIAN based on the
+ * result of the AC_C_BIGENDIAN autoconf test.
+ */
+
+#ifdef HAVE_BYTESWAP_H
+#include <byteswap.h>
+#else
+
+#warning Using non-portable code (likely wrong other than ILP32).
+
+static inline unsigned short int
+bswap_16 (unsigned short int x)
+{
+  return ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8));
+}
+
+static inline unsigned int
+bswap_32 (unsigned int x)
+{
+  return ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) \
+        | (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24));
+}
+#endif
+
+
+#ifdef WORDS_BIGENDIAN
+
+static inline unsigned int
+host_to_usrp_u32 (unsigned int x)
+{
+  return bswap_32(x);
+}
+
+static inline unsigned int
+usrp_to_host_u32 (unsigned int x)
+{
+  return bswap_32(x);
+}
+
+static inline short int
+host_to_usrp_short (short int x)
+{
+  return bswap_16 (x);
+}
+
+static inline short int
+usrp_to_host_short (short int x)
+{
+  return bswap_16 (x);
+}
+
+#else
+
+static inline unsigned int
+host_to_usrp_u32 (unsigned int x)
+{
+  return x;
+}
+
+static inline unsigned int
+usrp_to_host_u32 (unsigned int x)
+{
+  return x;
+}
+
+static inline short int
+host_to_usrp_short (short int x)
+{
+  return x;
+}
+
+static inline short int
+usrp_to_host_short (unsigned short int x)
+{
+  return x;
+}
+
+#endif
+
+#endif /* INCLUDED_USRP_BYTESEX_H */
diff --git a/usrp/host/include/usrp/usrp_local_sighandler.h b/usrp/host/include/usrp/usrp_local_sighandler.h
new file mode 100644 (file)
index 0000000..ee33675
--- /dev/null
@@ -0,0 +1,61 @@
+/* -*- 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.
+ */
+
+#ifndef INCLUDED_USRP_LOCAL_SIGHANDLER_H
+#define INCLUDED_USRP_LOCAL_SIGHANDLER_H
+
+#include <signal.h>
+#include <string>
+
+/*!
+ * \brief Representation of signal.
+ */
+class usrp_signal
+{
+  int  d_signum;
+public:
+  usrp_signal (int signum) : d_signum (signum) {}
+  int signal () const { return d_signum; }
+  std::string name () const;
+};
+
+
+/*!
+ * \brief Get and set signal handler.
+ *
+ * Constructor installs new handler, destructor reinstalls
+ * original value.
+ */
+class usrp_local_sighandler {
+  int                  d_signum;
+#ifdef HAVE_SIGACTION
+  struct sigaction     d_old_action;
+#endif
+public:
+  usrp_local_sighandler (int signum, void (*new_handler)(int));
+  ~usrp_local_sighandler ();
+
+  /* throw usrp_signal (signum) */
+  static void throw_signal (int signum) throw (usrp_signal);
+};
+
+#endif /* INCLUDED_USRP_LOCAL_SIGHANDLER_H */
diff --git a/usrp/host/include/usrp/usrp_prims.h b/usrp/host/include/usrp/usrp_prims.h
new file mode 100644 (file)
index 0000000..aa08870
--- /dev/null
@@ -0,0 +1,294 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004,2006,2009 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.
+ */
+
+/*
+ * Low level primitives for directly messing with USRP hardware.
+ *
+ * If you're trying to use the USRP, you'll probably want to take a look
+ * at the usrp_rx and usrp_tx classes.  They hide a bunch of low level details
+ * and provide high performance streaming i/o.
+ *
+ * This interface is built on top of libusb, which allegedly works under
+ * Linux, *BSD and Mac OS/X.  http://libusb.sourceforge.net
+ */
+
+#ifndef _USRP_PRIMS_H_
+#define _USRP_PRIMS_H_
+
+#include <usrp/usrp_slots.h>
+#include <string>
+
+static const int USRP_HASH_SIZE = 16;
+
+enum usrp_load_status_t { ULS_ERROR = 0, ULS_OK, ULS_ALREADY_LOADED };
+
+struct usb_dev_handle;
+struct usb_device;
+
+/*!
+ * \brief initialize libusb; probe busses and devices.
+ * Safe to call more than once.
+ */
+void usrp_one_time_init ();
+
+/*
+ * force a rescan of the buses and devices
+ */
+void usrp_rescan ();
+
+/*!
+ * \brief locate Nth (zero based) USRP device in system.
+ * Return pointer or 0 if not found.
+ *
+ * The following kinds of devices are considered USRPs:
+ *
+ *   unconfigured USRP (no firwmare loaded)
+ *   configured USRP (firmware loaded)
+ *   unconfigured Cypress FX2 (only if fx2_ok_p is true)
+ */
+struct usb_device *usrp_find_device (int nth, bool fx2_ok_p = false);
+
+bool usrp_usrp_p (struct usb_device *q);               //< is this a USRP
+bool usrp_usrp0_p (struct usb_device *q);              //< is this a USRP Rev 0
+bool usrp_usrp1_p (struct usb_device *q);              //< is this a USRP Rev 1
+bool usrp_usrp2_p (struct usb_device *q);              //< is this a USRP Rev 2
+int  usrp_hw_rev (struct usb_device *q);               //< return h/w rev code
+
+bool usrp_fx2_p (struct usb_device *q);                        //< is this an unconfigured Cypress FX2
+
+bool usrp_unconfigured_usrp_p (struct usb_device *q);  //< some kind of unconfigured USRP
+bool usrp_configured_usrp_p (struct usb_device *q);    //< some kind of configured USRP
+
+/*!
+ * \brief given a usb_device return an instance of the appropriate usb_dev_handle
+ *
+ * These routines claim the specified interface and select the
+ * correct alternate interface.  (USB nomenclature is totally screwed!)
+ *
+ * If interface can't be opened, or is already claimed by some other
+ * process, 0 is returned.
+ */
+struct usb_dev_handle *usrp_open_cmd_interface (struct usb_device *dev);
+struct usb_dev_handle *usrp_open_rx_interface (struct usb_device *dev);
+struct usb_dev_handle *usrp_open_tx_interface (struct usb_device *dev);
+
+/*!
+ * \brief close interface.
+ */
+bool usrp_close_interface (struct usb_dev_handle *udh);
+
+/*!
+ * \brief load intel hex format file into USRP/Cypress FX2 (8051).
+ *
+ * The filename extension is typically *.ihx
+ *
+ * Note that loading firmware may cause the device to renumerate.  I.e.,
+ * change its configuration, invalidating the current device handle.
+ */
+
+usrp_load_status_t 
+usrp_load_firmware (struct usb_dev_handle *udh, const char *filename, bool force);
+
+/*!
+ * \brief load intel hex format file into USRP FX2 (8051).
+ *
+ * The filename extension is typically *.ihx
+ *
+ * Note that loading firmware may cause the device to renumerate.  I.e.,
+ * change its configuration, invalidating the current device handle.
+ * If the result is ULS_OK, usrp_load_firmware_nth delays 1 second
+ * then rescans the busses and devices.
+ */
+usrp_load_status_t
+usrp_load_firmware_nth (int nth, const char *filename, bool force);
+
+/*!
+ * \brief load fpga configuration bitstream
+ */
+usrp_load_status_t
+usrp_load_fpga (struct usb_dev_handle *udh, const char *filename, bool force);
+
+/*!
+ * \brief load the regular firmware and fpga bitstream in the Nth USRP.
+ *
+ * This is the normal starting point...
+ */
+bool usrp_load_standard_bits (int nth, bool force,
+                             const std::string fpga_filename = "",
+                             const std::string firmware_filename = "");
+
+/*!
+ * \brief copy the given \p hash into the USRP hash slot \p which.
+ * The usrp implements two hash slots, 0 and 1.
+ */
+bool usrp_set_hash (struct usb_dev_handle *udh, int which,
+                   const unsigned char hash[USRP_HASH_SIZE]);
+
+/*!
+ * \brief retrieve the \p hash from the USRP hash slot \p which.
+ * The usrp implements two hash slots, 0 and 1.
+ */
+bool usrp_get_hash (struct usb_dev_handle *udh, int which,
+                   unsigned char hash[USRP_HASH_SIZE]);
+
+bool usrp_write_fpga_reg (struct usb_dev_handle *udh, int reg, int value);
+bool usrp_read_fpga_reg (struct usb_dev_handle *udh, int reg, int *value);
+bool usrp_set_fpga_reset (struct usb_dev_handle *udh, bool on);
+bool usrp_set_fpga_tx_enable (struct usb_dev_handle *udh, bool on);
+bool usrp_set_fpga_rx_enable (struct usb_dev_handle *udh, bool on);
+bool usrp_set_fpga_tx_reset (struct usb_dev_handle *udh, bool on);
+bool usrp_set_fpga_rx_reset (struct usb_dev_handle *udh, bool on);
+bool usrp_set_led (struct usb_dev_handle *udh, int which, bool on);
+
+bool usrp_check_rx_overrun (struct usb_dev_handle *udh, bool *overrun_p);
+bool usrp_check_tx_underrun (struct usb_dev_handle *udh, bool *underrun_p);
+
+// i2c_read and i2c_write are limited to a maximum len of 64 bytes.
+
+bool usrp_i2c_write (struct usb_dev_handle *udh, int i2c_addr,
+                    const void *buf, int len);
+
+bool usrp_i2c_read (struct usb_dev_handle *udh, int i2c_addr,
+                   void *buf, int len);
+
+// spi_read and spi_write are limited to a maximum of 64 bytes
+// See usrp_spi_defs.h for more info
+
+bool usrp_spi_write (struct usb_dev_handle *udh,
+                    int optional_header, int enables, int format,
+                    const void *buf, int len);
+
+bool usrp_spi_read (struct usb_dev_handle *udh,
+                    int optional_header, int enables, int format,
+                    void *buf, int len);
+
+
+bool usrp_9862_write (struct usb_dev_handle *udh,
+                     int which_codec,                  // [0,  1]
+                     int regno,                        // [0, 63]
+                     int value);                       // [0, 255]     
+
+bool usrp_9862_read (struct usb_dev_handle *udh,
+                    int which_codec,                   // [0,  1]
+                    int regno,                         // [0, 63]
+                    unsigned char *value);             // [0, 255]
+
+/*!
+ * \brief Write multiple 9862 regs at once.
+ *
+ * \p buf contains alternating register_number, register_value pairs.
+ * \p len must be even and is the length of buf in bytes.
+ */
+bool usrp_9862_write_many (struct usb_dev_handle *udh, int which_codec,
+                          const unsigned char *buf, int len);
+                          
+
+/*!
+ * \brief write specified regs to all 9862's in the system
+ */
+bool usrp_9862_write_many_all (struct usb_dev_handle *udh,
+                              const unsigned char *buf, int len);
+                          
+
+// Write 24LC024 / 24LC025 EEPROM on motherboard or daughterboard.
+// Which EEPROM is determined by i2c_addr.  See i2c_addr.h
+
+bool usrp_eeprom_write (struct usb_dev_handle *udh, int i2c_addr,
+                       int eeprom_offset, const void *buf, int len);
+
+
+// Read 24LC024 / 24LC025 EEPROM on motherboard or daughterboard.
+// Which EEPROM is determined by i2c_addr.  See i2c_addr.h
+
+bool usrp_eeprom_read (struct usb_dev_handle *udh, int i2c_addr,
+                      int eeprom_offset, void *buf, int len);
+
+
+// Slot specific i/o routines
+
+/*!
+ * \brief write to the specified aux dac.
+ *
+ * \p slot: which Tx or Rx slot to write.
+ *    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
+ *
+ * \p which_dac: [0,3]  RX slots must use only 0 and 1.
+ *                     TX slots must use only 2 and 3.
+ *
+ * AUX DAC 3 is really the 9862 sigma delta output.
+ *
+ * \p value to write to aux dac.  All dacs take straight
+ * binary values.  Although dacs 0, 1 and 2 are 8-bit and dac 3 is 12-bit,
+ * the interface is in terms of 12-bit values [0,4095]
+ */
+bool usrp_write_aux_dac (struct usb_dev_handle *uhd, int slot,
+                        int which_dac, int value);
+
+/*!
+ * \brief Read the specified aux adc
+ *
+ * \p slot: which Tx or Rx slot to read aux dac
+ * \p which_adc: [0,1]  which of the two adcs to read
+ * \p *value: return value, 12-bit straight binary.
+ */
+bool usrp_read_aux_adc (struct usb_dev_handle *udh, int slot,
+                       int which_adc, int *value);
+
+
+/*!
+ * \brief usrp daughterboard id to name mapping
+ */
+const std::string usrp_dbid_to_string (int dbid);
+
+
+enum usrp_dbeeprom_status_t { UDBE_OK, UDBE_BAD_SLOT, UDBE_NO_EEPROM, UDBE_INVALID_EEPROM };
+
+struct usrp_dboard_eeprom {
+  unsigned short       id;             // d'board identifier code
+  unsigned short       oe;             // fpga output enables:
+                                       //   If bit set, i/o pin is an output from FPGA.
+  short                        offset[2];      // ADC/DAC offset correction
+};
+
+/*!
+ * \brief Read and return parsed daughterboard eeprom
+ */
+usrp_dbeeprom_status_t
+usrp_read_dboard_eeprom (struct usb_dev_handle *udh,
+                        int slot_id, usrp_dboard_eeprom *eeprom);
+
+/*!
+ * \brief write ADC/DAC offset calibration constants to d'board eeprom
+ */
+bool usrp_write_dboard_offsets (struct usb_dev_handle *udh, int slot_id,
+                               short offset0, short offset1);
+
+/*!
+ * \brief return a usrp's serial number.
+ *
+ * Note that this only works on a configured usrp.
+ * \returns non-zero length string iff successful.
+ */
+std::string usrp_serial_number(struct usb_dev_handle *udh);
+
+#endif /* _USRP_PRIMS_H_ */
diff --git a/usrp/host/include/usrp/usrp_slots.h b/usrp/host/include/usrp/usrp_slots.h
new file mode 100644 (file)
index 0000000..d2c50fc
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- 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.
+ */
+
+#ifndef INCLUDED_USRP_SLOTS_H
+#define INCLUDED_USRP_SLOTS_H
+
+// daughterboard slot numbers used in some calls
+
+static const int SLOT_TX_A = 0;
+static const int SLOT_RX_A = 1;
+static const int SLOT_TX_B = 2;
+static const int SLOT_RX_B = 3;
+
+#endif /* INCLUDED_USRP_SLOTS_H */
diff --git a/usrp/host/include/usrp/usrp_standard.h b/usrp/host/include/usrp/usrp_standard.h
new file mode 100644 (file)
index 0000000..a631f8b
--- /dev/null
@@ -0,0 +1,452 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2009 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_STANDARD_H
+#define INCLUDED_USRP_STANDARD_H
+
+#include <usrp/usrp_basic.h>
+#include <boost/shared_ptr.hpp>
+#include <usrp/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;
+
+/*!
+ * \ingroup usrp
+ */
+class usrp_standard_common
+{
+  int  d_fpga_caps;            // capability register val
+
+protected:
+  usrp_standard_common(usrp_basic *parent);
+
+public:
+  /*!
+   *\brief does the FPGA implement the final Rx half-band filter?
+   * If it doesn't, the maximum decimation factor with proper gain 
+   * is 1/2 of what it would otherwise be.
+   */
+  bool has_rx_halfband() const;
+
+  /*!
+   * \brief number of digital downconverters implemented in the FPGA
+   * This will be 0, 1, 2 or 4.
+   */
+  int nddcs() const;
+
+  /*!
+   *\brief does the FPGA implement the initial Tx half-band filter?
+   */
+  bool has_tx_halfband() const;
+
+  /*!
+   * \brief number of digital upconverters implemented in the FPGA
+   * 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);
+};
+
+/*!
+ * \brief The C++ interface the receive side of the USRP
+ * \ingroup usrp
+ *
+ * This is the recommended interface to USRP receive functionality
+ * for applications that use the USRP but not GNU Radio.
+ */
+class usrp_standard_rx : public usrp_basic_rx, public usrp_standard_common
+{
+ private:
+  static const int     MAX_CHAN = 4;
+  unsigned int         d_decim_rate;
+  int                  d_nchan;
+  int                  d_sw_mux;
+  int                  d_hw_mux;
+  double               d_rx_freq[MAX_CHAN];
+
+ protected:
+  usrp_standard_rx (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 = ""
+                   );  // throws if trouble
+
+  bool write_hw_mux_reg ();
+
+ public:
+
+  enum {
+    FPGA_MODE_NORMAL     = 0x00,
+    FPGA_MODE_LOOPBACK   = 0x01,
+    FPGA_MODE_COUNTING   = 0x02,
+    FPGA_MODE_COUNTING_32BIT   = 0x04
+  };
+
+  ~usrp_standard_rx ();
+
+  /*!
+   * \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 decim_rate      decimation factor
+   * \param nchan           number of channels
+   * \param mux                     Rx mux setting, \sa set_mux
+   * \param mode            mode
+   * \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 rbf file to load
+   * \param firmware_filename Name of ihx file to load
+   */
+  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].
+   *
+   * The final complex sample rate across the USB is
+   *   adc_freq () / decim_rate () * nchannels ()
+   */
+  bool set_decim_rate  (unsigned int rate);
+
+  /*!
+   * \brief Set number of active channels.  \p nchannels must be 1, 2 or 4.
+   *
+   * The final complex sample rate across the USB is
+   *   adc_freq () / decim_rate () * nchannels ()
+   */
+  bool set_nchannels (int nchannels);
+
+  /*!
+   * \brief Set input mux configuration.
+   *
+   * This determines which ADC (or constant zero) is connected to 
+   * each DDC input.  There are 4 DDCs.  Each has two inputs.
+   *
+   * <pre>
+   * Mux value:
+   *
+   *    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
+   * +-------+-------+-------+-------+-------+-------+-------+-------+
+   * |   Q3  |   I3  |   Q2  |   I2  |   Q1  |   I1  |   Q0  |   I0  |
+   * +-------+-------+-------+-------+-------+-------+-------+-------+
+   *
+   * Each 4-bit I field is either 0,1,2,3
+   * Each 4-bit Q field is either 0,1,2,3 or 0xf (input is const zero)
+   * All Q's must be 0xf or none of them may be 0xf
+   * </pre>
+   */
+  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);
+  int determine_rx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b);
+
+  /*!
+   * \brief set the frequency of the digital down converter.
+   *
+   * \p channel must be in the range [0,3].  \p freq is the center
+   * frequency in Hz.  \p freq may be either negative or postive.
+   * 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 mode
+   */
+  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);
+
+  /*!
+   * \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);
+
+  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] 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;
+  int nchannels () const;
+  int mux () const;
+  unsigned int format () const;
+
+  // called in base class to derived class order
+  bool start ();
+  bool stop ();
+};
+
+// ----------------------------------------------------------------
+
+/*!
+ * \brief The C++ interface the transmit side of the USRP
+ * \ingroup usrp
+ *
+ * This is the recommended interface to USRP transmit functionality
+ * for applications that use the USRP but not GNU Radio.
+ *
+ * Uses digital upconverter (coarse & fine modulators) in AD9862...
+ */
+class usrp_standard_tx : public usrp_basic_tx, public usrp_standard_common
+{
+ public:
+  enum coarse_mod_t {
+    CM_NEG_FDAC_OVER_4,                // -32 MHz
+    CM_NEG_FDAC_OVER_8,                // -16 MHz
+    CM_OFF,
+    CM_POS_FDAC_OVER_8,                // +16 MHz
+    CM_POS_FDAC_OVER_4         // +32 MHz
+  };
+
+ protected:
+  static const int     MAX_CHAN = 2;
+  unsigned int         d_interp_rate;
+  int                  d_nchan;
+  int                  d_sw_mux;
+  int                  d_hw_mux;
+  double               d_tx_freq[MAX_CHAN];
+  coarse_mod_t         d_coarse_mod[MAX_CHAN];
+  unsigned char                d_tx_modulator_shadow[MAX_CHAN];
+
+  virtual bool set_coarse_modulator (int channel, coarse_mod_t cm);
+  usrp_standard_tx::coarse_mod_t coarse_modulator (int channel) const;
+
+ protected:
+  usrp_standard_tx (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 = ""
+                   );  // throws if trouble
+
+  bool write_hw_mux_reg ();
+
+ public:
+  ~usrp_standard_tx ();
+
+  /*!
+   * \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 interp_rate             interpolation factor
+   * \param nchan           number of channels
+   * \param mux                     Tx mux setting, \sa set_mux
+   * \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 rbf file to load
+   * \param firmware_filename Name of ihx file to load
+   */
+  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.
+   *
+   * The final complex sample rate across the USB is
+   *   dac_freq () / interp_rate () * nchannels ()
+   */
+  virtual bool set_interp_rate (unsigned int rate);
+
+  /*!
+   * \brief Set number of active channels.  \p nchannels must be 1 or 2.
+   *
+   * The final complex sample rate across the USB is
+   *   dac_freq () / decim_rate () * nchannels ()
+   */
+  bool set_nchannels  (int nchannels);
+
+  /*!
+   * \brief Set output mux configuration.
+   *
+   * <pre>
+   *     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
+   *  +-------------------------------+-------+-------+-------+-------+
+   *  |                               | DAC3  | DAC2  | DAC1  |  DAC0 |
+   *  +-------------------------------+-------+-------+-------+-------+
+   * 
+   *  There are two interpolators with complex inputs and outputs.
+   *  There are four DACs.
+   * 
+   *  Each 4-bit DACx field specifies the source for the DAC and
+   *  whether or not that DAC is enabled.  Each subfield is coded
+   *  like this: 
+   * 
+   *     3 2 1 0
+   *    +-+-----+
+   *    |E|  N  |
+   *    +-+-----+
+   * 
+   *  Where E is set if the DAC is enabled, and N specifies which
+   *  interpolator output is connected to this DAC.
+   * 
+   *   N   which interp output
+   *  ---  -------------------
+   *   0   chan 0 I
+   *   1   chan 0 Q
+   *   2   chan 1 I
+   *   3   chan 1 Q
+   * </pre>
+   */
+  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);
+  int determine_tx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b);
+
+  /*!
+   * \brief set the frequency of the digital up converter.
+   *
+   * \p channel must be in the range [0,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.
+   */
+  virtual bool set_tx_freq (int channel, double freq);  // chan: [0,1]
+
+  // ACCESSORS
+  unsigned int interp_rate () const;
+  double tx_freq (int channel) const;
+  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] 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 ();
+};
+
+#endif /* INCLUDED_USRP_STANDARD_H */
diff --git a/usrp/host/include/usrp/usrp_subdev_spec.h b/usrp/host/include/usrp/usrp_subdev_spec.h
new file mode 100644 (file)
index 0000000..e841ff8
--- /dev/null
@@ -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/include/usrp/usrp_tune_result.h b/usrp/host/include/usrp/usrp_tune_result.h
new file mode 100644 (file)
index 0000000..200541a
--- /dev/null
@@ -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 */
index 2062bda62736ed32b6bd71ad165264b44fcd7b5f..8482485f58533090682703213bc32d79e271e0dc 100644 (file)
@@ -1,7 +1,7 @@
 #
 #  USRP - Universal Software Radio Peripheral
 # 
-#  Copyright (C) 2003,2004,2006,2007 Free Software Foundation, Inc.
+#  Copyright (C) 2003,2004,2006,2007,2008,2009 Free Software Foundation, Inc.
 # 
 #  This program is free software; you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
 
 include $(top_srcdir)/Makefile.common
 
-SUBDIRS = legacy inband
+common_INCLUDES = $(USRP_INCLUDES)
 
+lib_LTLIBRARIES = libusrp.la
+
+libusrp_la_common_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 $(BOOST_LDFLAGS)
+
+libusrp_la_common_LIBADD =             \
+       $(USB_LIBS)                     \
+       $(BOOST_THREAD_LIB)             \
+       ../misc/libmisc.la
+
+# darwin fusb requires omnithreads
+if FUSB_TECH_darwin
+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) $(BOOST_CPPFLAGS) $(WITH_INCLUDES)
+libusrp_la_LIBADD = $(libusrp_la_common_LIBADD)
+libusrp_la_LDFLAGS = $(libusrp_la_common_LDFLAGS)
+endif
+
+EXTRA_DIST =                           \
+       std_paths.h.in                  \
+       usrp_dbid.dat                   
+
+BUILT_SOURCES =                        \
+       $(abs_top_builddir)/usrp/host/include/usrp/usrp_dbid.h
+
+BUILT_SOURCES += usrp_dbid.cc \
+                usrp_dbid.py
+
+# ----------------------------------------------------------------
+# FUSB_TECH is set at configure time by way of
+#   usrp/config/usrp_fusb_tech.m4.
+#   It indicates which fast usb strategy we should be building.
+#   We currently implement "generic", "darwin", "win32" and "linux"
+
+
+generic_CODE =                                 \
+       fusb_generic.cc                 \
+       fusb_sysconfig_generic.cc
+
+darwin_CODE =                          \
+       fusb_darwin.cc                  \
+       fusb_sysconfig_darwin.cc        \
+       README_OSX                      \
+       circular_buffer.h               \
+       circular_linked_list.h          \
+       darwin_libusb.h                 \
+       mld_threads.h                   
+
+win32_CODE =                           \
+       fusb_win32.cc                   \
+       fusb_sysconfig_win32.cc         
+
+linux_CODE =                           \
+       fusb_linux.cc                   \
+       fusb_sysconfig_linux.cc         
+
+ra_wb_CODE =                           \
+       fusb_ra_wb.cc                   \
+       fusb_sysconfig_ra_wb.cc
+
+
+#
+# include each <foo>_CODE entry here...
+#
+EXTRA_libusrp_la_SOURCES =             \
+       $(generic_CODE)                 \
+       $(darwin_CODE)                  \
+       $(win32_CODE)                   \
+       $(linux_CODE)                   \
+       $(ra_wb_CODE)
+
+
+# work around automake deficiency
+libusrp_la_common_SOURCES =            \
+       fusb.cc                         \
+       md5.c                           \
+       usrp_basic.cc                   \
+       usrp_config.cc                  \
+       usrp_dbid.cc                    \
+       usrp_local_sighandler.cc        \
+       usrp_prims.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
+
+
+
+if FUSB_TECH_generic
+libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(generic_CODE)
+endif
+
+if FUSB_TECH_darwin
+libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(darwin_CODE)
+endif
+
+if FUSB_TECH_win32
+libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(win32_CODE)
+endif
+
+if FUSB_TECH_linux
+libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(linux_CODE)
+endif
+
+if FUSB_TECH_ra_wb
+libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(ra_wb_CODE)
+endif
+
+noinst_HEADERS =                       \
+       ad9862.h                        \
+       db_base_impl.h                  \
+       db_boards.h                     \
+       db_util.h                       \
+       fusb.h                          \
+       fusb_darwin.h                   \
+       fusb_generic.h                  \
+       fusb_linux.h                    \
+       fusb_ra_wb.h                    \
+       fusb_win32.h                    \
+       md5.h                           \
+       rate_to_regval.h                \
+       usrp_config.h
+
+if PYTHON
+usrppython_PYTHON =                    \
+       usrp_dbid.py                    
+
+noinst_PYTHON =                                \
+       gen_usrp_dbid.py                \
+       check_data.py                   \
+       dump_data.py
+endif
+
+# common way for generating sources from templates when using
+# BUILT_SOURCES, using parallel build protection.
+gen_sources = $(BUILT_SOURCES)
+gen_sources_deps = gen_usrp_dbid.py usrp_dbid.dat
+par_gen_command = PYTHONPATH=$(top_srcdir)/usrp/src srcdir=$(srcdir) $(PYTHON) $(srcdir)/gen_usrp_dbid.py $(srcdir)/usrp_dbid.dat
+include $(top_srcdir)/Makefile.par.gen
diff --git a/usrp/host/lib/README_OSX b/usrp/host/lib/README_OSX
new file mode 100644 (file)
index 0000000..37026f2
--- /dev/null
@@ -0,0 +1,63 @@
+USRP Darwin Fast USB Changes
+Version 0.2 of 2006-04-27
+Michael Dickens <mdickens @at@ nd .dot. edu>
+
+The files included in this archive are:
+
+circular_buffer.h
+circular_linked_list.h
+darwin_libusb.h
+fusb_darwin.cc
+fusb_darwin.h
+mld_threads.h
+
+These files allow GNURadio code for Darwin / MaxOS X to talk to the
+USRP via USB 2.0 at rates up to around 30 Mega-Bytes/sec (MBps), up
+from 4-8 MBps without the changes.
+
+I implemented the buffering myself; there are probably GR buffers
+available which would do the work but as this is "beta" software it's
+a good place to start.  Speed improvements are made by porting
+LIBUSB's non-true async bulk read and write functions into USRP's
+"fusb", and upgrading them to handle -true- async transfers.
+Unfortunately, the easiest way to do this is to spawn a thread or 2 to
+handle the "async" part of the transfers.  This implementation uses
+Darwin's pthreads to do the work for mutexes, conditions, and threads.
+Previous implementations (0.1 and before) used "omni_threads" as
+provided by gnuradio-core, which caused issues with compiling and
+execution ... I'm glad that this is no longer the case.
+
+As far as I have tested, there is no way to improve the throughput to
+32+ MBps without moving into Darwin's "port"s ... a kernel-level data
+transport method with a user/application layer for USB-specific
+functions.  Unfortunately, Apple's documentation for these "port"s is
+minimal; I have learned more from reading the Darwin source code
+< http://darwinsource.opendarwin.org/ > than by reading Apple's
+documents!  This would also require -not- using LIBUSB, of which the
+removal from the rest of the USRP code would be potentially tedious.
+
+If you run into issues either compiling or testing the USRP on
+OSX, please send me a note.
+
+(1) Go through the bootstrap, configure, compile, and install as
+usual (e.g. see < http://www.nd.edu/~mdickens/GNURadio/ > for my
+usual).
+
+(2) from .../usrp/host/apps :  run the scripts
+++++++++++++++++
+./test_usrp_standard_tx
+./test_usrp_standard_rx
+++++++++++++++++
+
+For -all- systems I've tested on thus far, both of these return
+exactly 41 overruns / underruns, and -most- systems start out with a
+stalled pipe.  This stall comes in a usb_control function call to
+LIBUSB; one would have to change the LIBUSB code to handle this issue.
+
+(3) from gr-build/gnuradio-examples/python/usrp :
+++++++++++++++++
+./benchmark_usb.py
+++++++++++++++++
+
+(4) If you get to here, the try doing the FM receiver (gui or not).
+If that sounds correct, then the USB is working.  Yay!
\ No newline at end of file
diff --git a/usrp/host/lib/ad9862.h b/usrp/host/lib/ad9862.h
new file mode 100644 (file)
index 0000000..4375d93
--- /dev/null
@@ -0,0 +1,221 @@
+/* -*- 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.
+ */
+
+#ifndef INCLUDED_AD9862_H
+#define INCLUDED_AD9862_H
+
+/*
+ * Analog Devices AD9862 registers and some fields
+ */
+
+#define BEGIN_AD9862   namespace ad9862 {
+#define        END_AD962       }
+#define        DEF static const int
+
+BEGIN_AD9862;
+
+DEF REG_GENERAL                =  0;
+DEF REG_RX_PWR_DN      =  1;
+DEF    RX_PWR_DN_VREF_DIFF             = (1 << 7);
+DEF    RX_PWR_DN_VREF                  = (1 << 6);
+DEF    RX_PWR_DN_RX_DIGIGAL            = (1 << 5);
+DEF    RX_PWR_DN_RX_B                  = (1 << 4);
+DEF    RX_PWR_DN_RX_A                  = (1 << 3);
+DEF    RX_PWR_DN_BUF_B                 = (1 << 2);
+DEF    RX_PWR_DN_BUF_A                 = (1 << 1);
+DEF    RX_PWR_DN_ALL                   = (1 << 0);
+
+DEF REG_RX_A           =  2;   // bypass input buffer / RxPGA
+DEF REG_RX_B           =  3;   // pypass input buffer / RxPGA
+DEF    RX_X_BYPASS_INPUT_BUFFER        = (1 << 7);
+
+DEF REG_RX_MISC                =  4;
+DEF    RX_MISC_HS_DUTY_CYCLE           = (1 << 2);
+DEF    RX_MISC_SHARED_REF              = (1 << 1);
+DEF    RX_MISC_CLK_DUTY                = (1 << 0);
+
+DEF REG_RX_IF          =  5;
+DEF    RX_IF_THREE_STATE               = (1 << 4);
+DEF    RX_IF_USE_CLKOUT1               = (0 << 3);     
+DEF    RX_IF_USE_CLKOUT2               = (1 << 3);     // aka Rx Retime
+DEF    RX_IF_2S_COMP                   = (1 << 2);
+DEF    RX_IF_INV_RX_SYNC               = (1 << 1);
+DEF    RX_IF_MUX_OUT                   = (1 << 0);
+
+DEF REG_RX_DIGITAL     =  6;
+DEF    RX_DIGITAL_2_CHAN               = (1 << 3);
+DEF    RX_DIGITAL_KEEP_MINUS_VE        = (1 << 2);
+DEF    RX_DIGITAL_HILBERT              = (1 << 1);
+DEF    RX_DIGITAL_DECIMATE             = (1 << 0);
+
+DEF REG_RESERVED_7     =  7;
+
+DEF REG_TX_PWR_DN      =  8;
+DEF    TX_PWR_DN_ALT_TIMING_MODE       = (1 << 5);
+DEF    TX_PWR_DN_TX_OFF_ENABLE         = (1 << 4);
+DEF    TX_PWR_DN_TX_DIGITAL            = (1 << 3);
+DEF    TX_PWR_DN_TX_ANALOG_B           = 0x4;
+DEF    TX_PWR_DN_TX_ANALOG_A           = 0x2;
+DEF    TX_PWR_DN_TX_ANALOG_BOTH        = 0x7;
+
+DEF REG_RESERVED_9     =  9;
+
+DEF REG_TX_A_OFFSET_LO = 10;
+DEF REG_TX_A_OFFSET_HI = 11;
+DEF REG_TX_B_OFFSET_LO = 12;
+DEF REG_TX_B_OFFSET_HI = 13;
+
+DEF REG_TX_A_GAIN      = 14;   // fine trim for matching
+DEF REG_TX_B_GAIN      = 15;   // fine trim for matching
+DEF    TX_X_GAIN_COARSE_FULL           = (3 << 6);
+DEF    TX_X_GAIN_COARSE_1_HALF         = (1 << 6);
+DEF    TX_X_GAIN_COARSE_1_ELEVENTH     = (0 << 6);
+
+DEF REG_TX_PGA         = 16;   // 20 dB continuous gain in 0.1 dB steps
+                               // 0x00 = min gain (-20 dB)
+                               // 0xff = max gain (  0 dB)
+
+DEF REG_TX_MISC                = 17;
+DEF    TX_MISC_SLAVE_ENABLE            = (1 << 1);
+DEF    TX_MISC_TX_PGA_FAST             = (1 << 0);
+
+DEF REG_TX_IF          = 18;
+DEF    TX_IF_USE_CLKOUT2               = (0 << 6);
+DEF    TX_IF_USE_CLKOUT1               = (1 << 6);     // aka Tx Retime
+DEF    TX_IF_I_FIRST                   = (0 << 5);
+DEF    TX_IF_Q_FIRST                   = (1 << 5);
+DEF    TX_IF_INV_TX_SYNC               = (1 << 4);
+DEF    TX_IF_2S_COMP                   = (1 << 3);
+DEF    TX_IF_INVERSE_SAMPLE            = (1 << 2);
+DEF    TX_IF_TWO_EDGES                 = (1 << 1);
+DEF    TX_IF_INTERLEAVED               = (1 << 0);
+
+DEF REG_TX_DIGITAL     = 19;
+DEF    TX_DIGITAL_2_DATA_PATHS         = (1 << 4);
+DEF    TX_DIGITAL_KEEP_NEGATIVE        = (1 << 3);
+DEF    TX_DIGITAL_HILBERT              = (1 << 2);
+DEF    TX_DIGITAL_INTERPOLATE_NONE     = 0x0;
+DEF    TX_DIGITAL_INTERPOLATE_2X       = 0x1;
+DEF    TX_DIGITAL_INTERPOLATE_4X       = 0x2;
+
+DEF REG_TX_MODULATOR   = 20;
+DEF    TX_MODULATOR_NEG_FINE_TUNE      = (1 << 5);
+DEF    TX_MODULATOR_DISABLE_NCO        = (0 << 4);
+DEF    TX_MODULATOR_ENABLE_NCO         = (1 << 4);     // aka Fine Mode
+DEF    TX_MODULATOR_REAL_MIX_MODE      = (1 << 3);
+DEF    TX_MODULATOR_NEG_COARSE_TUNE    = (1 << 2);
+DEF    TX_MODULATOR_COARSE_MODULATION_NONE     = 0x0;
+DEF    TX_MODULATOR_COARSE_MODULATION_F_OVER_4 = 0x1;
+DEF    TX_MODULATOR_COARSE_MODULATION_F_OVER_8 = 0x2;
+DEF    TX_MODULATOR_CM_MASK                    = 0x7;
+
+
+DEF REG_TX_NCO_FTW_7_0 = 21;
+DEF REG_TX_NCO_FTW_15_8        = 22;
+DEF REG_TX_NCO_FTW_23_16= 23;
+
+DEF REG_DLL            = 24;
+DEF    DLL_DISABLE_INTERNAL_XTAL_OSC   = (1 << 6);     // aka Input Clock Ctrl
+DEF    DLL_ADC_DIV2                    = (1 << 5);
+DEF    DLL_MULT_1X                     = (0 << 3);
+DEF    DLL_MULT_2X                     = (1 << 3);
+DEF    DLL_MULT_4X                     = (2 << 3);
+DEF    DLL_PWR_DN                      = (1 << 2);
+// undefined bit                       = (1 << 1);
+DEF    DLL_FAST                        = (1 << 0);
+
+DEF REG_CLKOUT         = 25;
+DEF    CLKOUT2_EQ_DLL                  = (0 << 6);
+DEF    CLKOUT2_EQ_DLL_OVER_2           = (1 << 6);
+DEF    CLKOUT2_EQ_DLL_OVER_4           = (2 << 6);
+DEF    CLKOUT2_EQ_DLL_OVER_8           = (3 << 6);
+DEF    CLKOUT_INVERT_CLKOUT2           = (1 << 5);
+DEF    CLKOUT_DISABLE_CLKOUT2          = (1 << 4);
+// undefined bit                       = (1 << 3);
+// undefined bit                       = (1 << 2);
+DEF    CLKOUT_INVERT_CLKOUT1           = (1 << 1);
+DEF    CLKOUT_DISABLE_CLKOUT1          = (1 << 0);
+
+DEF REG_AUX_ADC_A2_LO  = 26;
+DEF REG_AUX_ADC_A2_HI  = 27;
+DEF REG_AUX_ADC_A1_LO  = 28;
+DEF REG_AUX_ADC_A1_HI  = 29;
+DEF REG_AUX_ADC_B2_LO  = 30;
+DEF REG_AUX_ADC_B2_HI  = 31;
+DEF REG_AUX_ADC_B1_LO  = 32;
+DEF REG_AUX_ADC_B1_HI  = 33;
+
+DEF REG_AUX_ADC_CTRL   = 34;
+DEF    AUX_ADC_CTRL_AUX_SPI            = (1 << 7);
+DEF    AUX_ADC_CTRL_SELBNOTA           = (1 << 6);
+DEF    AUX_ADC_CTRL_REFSEL_B           = (1 << 5);
+DEF    AUX_ADC_CTRL_SELECT_B2          = (0 << 4);
+DEF    AUX_ADC_CTRL_SELECT_B1          = (1 << 4);
+DEF    AUX_ADC_CTRL_START_B            = (1 << 3);
+DEF    AUX_ADC_CTRL_REFSEL_A           = (1 << 2);
+DEF    AUX_ADC_CTRL_SELECT_A2          = (0 << 1);
+DEF    AUX_ADC_CTRL_SELECT_A1          = (1 << 1);
+DEF    AUX_ADC_CTRL_START_A            = (1 << 0);
+
+DEF REG_AUX_ADC_CLK    = 35;
+DEF    AUX_ADC_CLK_CLK_OVER_4          = (1 << 0);
+
+DEF REG_AUX_DAC_A      = 36;
+DEF REG_AUX_DAC_B      = 37;
+DEF REG_AUX_DAC_C      = 38;
+
+DEF REG_AUX_DAC_UPDATE = 39;
+DEF    AUX_DAC_UPDATE_SLAVE_ENABLE     = (1 << 7);
+DEF    AUX_DAC_UPDATE_C                = (1 << 2);
+DEF    AUX_DAC_UPDATE_B                = (1 << 1);
+DEF    AUX_DAC_UPDATE_A                = (1 << 0);
+
+DEF REG_AUX_DAC_PWR_DN = 40;
+DEF    AUX_DAC_PWR_DN_C                = (1 << 2);
+DEF    AUX_DAC_PWR_DN_B                = (1 << 1);
+DEF    AUX_DAC_PWR_DN_A                = (1 << 0);
+
+DEF REG_AUX_DAC_CTRL   = 41;
+DEF    AUX_DAC_CTRL_INV_C              = (1 << 4);
+DEF    AUX_DAC_CTRL_INV_B              = (1 << 2);
+DEF    AUX_DAC_CTRL_INV_A              = (1 << 0);
+
+DEF REG_SIGDELT_LO     = 42;
+DEF REG_SIGDELT_HI     = 43;
+
+// 44 to 48 reserved
+
+DEF REG_ADC_LOW_PWR_LO = 49;
+DEF REG_ADC_LOW_PWR_HI = 50;
+
+// 51 to 62 reserved
+
+DEF REG_CHIP_ID                = 63;
+
+
+END_AD962;
+
+#undef DEF
+#undef BEGIN_AD9862
+#undef END_AD962
+
+#endif /* INCLUDED_AD9862_H */
diff --git a/usrp/host/lib/check_data.py b/usrp/host/lib/check_data.py
new file mode 100755 (executable)
index 0000000..100f0f6
--- /dev/null
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+#
+# Copyright 2003 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
+import struct
+
+fin = sys.stdin
+
+count = 0
+expected = 0
+last_correction = 0
+
+while 1:
+    s = fin.read(2)
+    if not s or len(s) != 2:
+        break
+
+    v, = struct.unpack ('H', s)
+    iv = int(v) & 0xffff
+    # print "%8d  %6d  0x%04x" % (count, iv, iv)
+    if count & 0x1:                     # only counting on the Q channel
+        if (expected & 0xffff) != iv:
+            print "%8d  (%6d) %6d  0x%04x" % (count, count - last_correction, iv, iv)
+            expected = iv               # reset expected sequence
+            last_correction = count
+        expected = (expected + 1) & 0xffff 
+        
+    count += 1
+
+    
+
+
diff --git a/usrp/host/lib/circular_buffer.h b/usrp/host/lib/circular_buffer.h
new file mode 100644 (file)
index 0000000..8898e41
--- /dev/null
@@ -0,0 +1,317 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 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 _CIRCULAR_BUFFER_H_
+#define _CIRCULAR_BUFFER_H_
+
+#include "mld_threads.h"
+#include <stdexcept>
+
+#ifndef DO_DEBUG
+#define DO_DEBUG 0
+#endif
+
+#if DO_DEBUG
+#define DEBUG(X) do{X} while(0);
+#else
+#define DEBUG(X) do{} while(0);
+#endif
+
+template <class T> class circular_buffer
+{
+private:
+// the buffer to use
+  T* d_buffer;
+
+// the following are in Items (type T)
+  UInt32 d_bufLen_I, d_readNdx_I, d_writeNdx_I;
+  UInt32 d_n_avail_write_I, d_n_avail_read_I;
+
+// stuff to control access to class internals
+  mld_mutex_ptr d_internal;
+  mld_condition_ptr d_readBlock, d_writeBlock;
+
+// booleans to decide how to control reading, writing, and aborting
+  bool d_doWriteBlock, d_doFullRead, d_doAbort;
+
+  void delete_mutex_cond () {
+    if (d_internal) {
+      delete d_internal;
+      d_internal = NULL;
+    }
+    if (d_readBlock) {
+      delete d_readBlock;
+      d_readBlock = NULL;
+    }
+    if (d_writeBlock) {
+      delete d_writeBlock;
+      d_writeBlock = NULL;
+    }
+  };
+
+public:
+  circular_buffer (UInt32 bufLen_I,
+                  bool doWriteBlock = true, bool doFullRead = false) {
+    if (bufLen_I == 0)
+      throw std::runtime_error ("circular_buffer(): "
+                               "Number of items to buffer must be > 0.\n");
+    d_bufLen_I = bufLen_I;
+    d_buffer = (T*) new T[d_bufLen_I];
+    d_doWriteBlock = doWriteBlock;
+    d_doFullRead = doFullRead;
+    d_internal = NULL;
+    d_readBlock = d_writeBlock = NULL;
+    reset ();
+    DEBUG (fprintf (stderr, "c_b(): buf len (items) = %ld, "
+                   "doWriteBlock = %s, doFullRead = %s\n", d_bufLen_I,
+                   (d_doWriteBlock ? "true" : "false"),
+                   (d_doFullRead ? "true" : "false")););
+  };
+
+  ~circular_buffer () {
+    delete_mutex_cond ();
+    delete [] d_buffer;
+  };
+
+  inline UInt32 n_avail_write_items () {
+    d_internal->lock ();
+    UInt32 retVal = d_n_avail_write_I;
+    d_internal->unlock ();
+    return (retVal);
+  };
+
+  inline UInt32 n_avail_read_items () {
+    d_internal->lock ();
+    UInt32 retVal = d_n_avail_read_I;
+    d_internal->unlock ();
+    return (retVal);
+  };
+
+  inline UInt32 buffer_length_items () {return (d_bufLen_I);};
+  inline bool do_write_block () {return (d_doWriteBlock);};
+  inline bool do_full_read () {return (d_doFullRead);};
+
+  void reset () {
+    d_doAbort = false;
+    bzero (d_buffer, d_bufLen_I * sizeof (T));
+    d_readNdx_I = d_writeNdx_I = d_n_avail_read_I = 0;
+    d_n_avail_write_I = d_bufLen_I;
+    delete_mutex_cond ();
+    // create a mutex to handle contention of shared resources;
+    // any routine needed access to shared resources uses lock()
+    // before doing anything, then unlock() when finished.
+    d_internal = new mld_mutex ();
+    // link the internal mutex to the read and write conditions;
+    // when wait() is called, the internal mutex will automatically
+    // be unlock()'ed.  Upon return (from a signal() to the condition),
+    // the internal mutex will be lock()'ed.
+    d_readBlock = new mld_condition (d_internal);
+    d_writeBlock = new mld_condition (d_internal);
+  };
+
+/*
+ * enqueue: add the given buffer of item-length to the queue,
+ *     first-in-first-out (FIFO).
+ *
+ * inputs:
+ *     buf: a pointer to the buffer holding the data
+ *
+ *     bufLen_I: the buffer length in items (of the instantiated type)
+ *
+ * returns:
+ *    -1: on overflow (write is not blocking, and data is being
+ *                     written faster than it is being read)
+ *     0: if nothing to do (0 length buffer)
+ *     1: if success
+ *     2: in the process of aborting, do doing nothing
+ *
+ * will throw runtime errors if inputs are improper:
+ *     buffer pointer is NULL
+ *     buffer length is larger than the instantiated buffer length
+ */
+
+  int enqueue (T* buf, UInt32 bufLen_I) {
+    DEBUG (fprintf (stderr, "enqueue: buf = %X, bufLen = %ld, #av_wr = %ld, "
+                   "#av_rd = %ld.\n", (unsigned int)buf, bufLen_I,
+                   d_n_avail_write_I, d_n_avail_read_I););
+    if (bufLen_I > d_bufLen_I) {
+      fprintf (stderr, "cannot add buffer longer (%ld"
+              ") than instantiated length (%ld"
+              ").\n", bufLen_I, d_bufLen_I);
+      throw std::runtime_error ("circular_buffer::enqueue()");
+    }
+
+    if (bufLen_I == 0)
+      return (0);
+    if (!buf)
+      throw std::runtime_error ("circular_buffer::enqueue(): "
+                               "input buffer is NULL.\n");
+    d_internal->lock ();
+    if (d_doAbort) {
+      d_internal->unlock ();
+      return (2);
+    }
+    // set the return value to 1: success; change if needed
+    int retval = 1;
+    if (bufLen_I > d_n_avail_write_I) {
+      if (d_doWriteBlock) {
+       while (bufLen_I > d_n_avail_write_I) {
+         DEBUG (fprintf (stderr, "enqueue: #len > #a, waiting.\n"););
+         // wait will automatically unlock() the internal mutex
+         d_writeBlock->wait ();
+         // and lock() it here.
+         if (d_doAbort) {
+           d_internal->unlock ();
+           DEBUG (fprintf (stderr, "enqueue: #len > #a, aborting.\n"););
+           return (2);
+         }
+         DEBUG (fprintf (stderr, "enqueue: #len > #a, done waiting.\n"););
+       }
+      } else {
+       d_n_avail_read_I = d_bufLen_I - bufLen_I;
+       d_n_avail_write_I = bufLen_I;
+       DEBUG (fprintf (stderr, "circular_buffer::enqueue: overflow\n"););
+       retval = -1;
+      }
+    }
+    UInt32 n_now_I = d_bufLen_I - d_writeNdx_I, n_start_I = 0;
+    if (n_now_I > bufLen_I)
+      n_now_I = bufLen_I;
+    else if (n_now_I < bufLen_I)
+      n_start_I = bufLen_I - n_now_I;
+    bcopy (buf, &(d_buffer[d_writeNdx_I]), n_now_I * sizeof (T));
+    if (n_start_I) {
+      bcopy (&(buf[n_now_I]), d_buffer, n_start_I * sizeof (T));
+      d_writeNdx_I = n_start_I;
+    } else
+      d_writeNdx_I += n_now_I;
+    d_n_avail_read_I += bufLen_I;
+    d_n_avail_write_I -= bufLen_I;
+    d_readBlock->signal ();
+    d_internal->unlock ();
+    return (retval);
+  };
+
+/*
+ * dequeue: removes from the queue the number of items requested, or
+ *     available, into the given buffer on a FIFO basis.
+ *
+ * inputs:
+ *     buf: a pointer to the buffer into which to copy the data
+ *
+ *     bufLen_I: pointer to the number of items to remove in items
+ *         (of the instantiated type)
+ *
+ * returns:
+ *     0: if nothing to do (0 length buffer)
+ *     1: if success
+ *     2: in the process of aborting, do doing nothing
+ *
+ * will throw runtime errors if inputs are improper:
+ *     buffer pointer is NULL
+ *     buffer length pointer is NULL
+ *     buffer length is larger than the instantiated buffer length
+ */
+
+  int dequeue (T* buf, UInt32* bufLen_I) {
+    DEBUG (fprintf (stderr, "dequeue: buf = %X, *bufLen = %ld, #av_wr = %ld, "
+                   "#av_rd = %ld.\n", (unsigned int)buf, *bufLen_I,
+                   d_n_avail_write_I, d_n_avail_read_I););
+    if (!bufLen_I)
+      throw std::runtime_error ("circular_buffer::dequeue(): "
+                               "input bufLen pointer is NULL.\n");
+    if (!buf)
+      throw std::runtime_error ("circular_buffer::dequeue(): "
+                               "input buffer pointer is NULL.\n");
+    UInt32 l_bufLen_I = *bufLen_I;
+    if (l_bufLen_I == 0)
+      return (0);
+    if (l_bufLen_I > d_bufLen_I) {
+      fprintf (stderr, "cannot remove buffer longer (%ld"
+              ") than instantiated length (%ld"
+              ").\n", l_bufLen_I, d_bufLen_I);
+      throw std::runtime_error ("circular_buffer::dequeue()");
+    }
+
+    d_internal->lock ();
+    if (d_doAbort) {
+      d_internal->unlock ();
+      return (2);
+    }
+    if (d_doFullRead) {
+      while (d_n_avail_read_I < l_bufLen_I) {
+       DEBUG (fprintf (stderr, "dequeue: #a < #len, waiting.\n"););
+       // wait will automatically unlock() the internal mutex
+       d_readBlock->wait ();
+       // and lock() it here.
+       if (d_doAbort) {
+         d_internal->unlock ();
+         DEBUG (fprintf (stderr, "dequeue: #a < #len, aborting.\n"););
+         return (2);
+       }
+       DEBUG (fprintf (stderr, "dequeue: #a < #len, done waiting.\n"););
+     }
+    } else {
+      while (d_n_avail_read_I == 0) {
+       DEBUG (fprintf (stderr, "dequeue: #a == 0, waiting.\n"););
+       // wait will automatically unlock() the internal mutex
+       d_readBlock->wait ();
+       // and lock() it here.
+       if (d_doAbort) {
+         d_internal->unlock ();
+         DEBUG (fprintf (stderr, "dequeue: #a == 0, aborting.\n"););
+         return (2);
+       }
+       DEBUG (fprintf (stderr, "dequeue: #a == 0, done waiting.\n"););
+      }
+    }
+    if (l_bufLen_I > d_n_avail_read_I)
+      l_bufLen_I = d_n_avail_read_I;
+    UInt32 n_now_I = d_bufLen_I - d_readNdx_I, n_start_I = 0;
+    if (n_now_I > l_bufLen_I)
+      n_now_I = l_bufLen_I;
+    else if (n_now_I < l_bufLen_I)
+      n_start_I = l_bufLen_I - n_now_I;
+    bcopy (&(d_buffer[d_readNdx_I]), buf, n_now_I * sizeof (T));
+    if (n_start_I) {
+      bcopy (d_buffer, &(buf[n_now_I]), n_start_I * sizeof (T));
+      d_readNdx_I = n_start_I;
+    } else
+      d_readNdx_I += n_now_I;
+    *bufLen_I = l_bufLen_I;
+    d_n_avail_read_I -= l_bufLen_I;
+    d_n_avail_write_I += l_bufLen_I;
+    d_writeBlock->signal ();
+    d_internal->unlock ();
+    return (1);
+  };
+
+  void abort () {
+    d_internal->lock ();
+    d_doAbort = true;
+    d_writeBlock->signal ();
+    d_readBlock->signal ();
+    d_internal->unlock ();
+  };
+};
+
+#endif /* _CIRCULAR_BUFFER_H_ */
diff --git a/usrp/host/lib/circular_linked_list.h b/usrp/host/lib/circular_linked_list.h
new file mode 100644 (file)
index 0000000..e495d60
--- /dev/null
@@ -0,0 +1,284 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 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 _CIRCULAR_LINKED_LIST_H_
+#define _CIRCULAR_LINKED_LIST_H_
+
+#include <mld_threads.h>
+#include <stdexcept>
+
+#define __INLINE__ inline
+
+#ifndef DO_DEBUG
+#define DO_DEBUG 0
+#endif
+
+#if DO_DEBUG
+#define DEBUG(X) do{X} while(0);
+#else
+#define DEBUG(X) do{} while(0);
+#endif
+
+template <class T> class s_both;
+
+template <class T> class s_node
+{
+  typedef s_node<T>* s_node_ptr;
+
+private:
+  T d_object;
+  bool d_available;
+  s_node_ptr d_prev, d_next;
+  s_both<T>* d_both;
+
+public:
+  s_node (T l_object,
+         s_node_ptr l_prev = NULL,
+         s_node_ptr l_next = NULL)
+    : d_object (l_object), d_available (TRUE), d_prev (l_prev),
+    d_next (l_next), d_both (0) {};
+
+  __INLINE__ s_node (s_node_ptr l_prev, s_node_ptr l_next = NULL) {
+    s_node ((T) NULL, l_prev, l_next); };
+  __INLINE__ s_node () { s_node (NULL, NULL, NULL); };
+  __INLINE__ ~s_node () {};
+
+  void remove () {
+    d_prev->next (d_next);
+    d_next->prev (d_prev);
+    d_prev = d_next = this;
+  };
+
+  void insert_before (s_node_ptr l_next) {
+    if (l_next) {
+      s_node_ptr l_prev = l_next->prev ();
+      d_next = l_next;
+      d_prev = l_prev;
+      l_prev->next (this);
+      l_next->prev (this);
+    } else
+      d_next = d_prev = this;
+  };
+
+  void insert_after (s_node_ptr l_prev) {
+    if (l_prev) {
+      s_node_ptr l_next = l_prev->next ();
+      d_prev = l_prev;
+      d_next = l_next;
+      l_next->prev (this);
+      l_prev->next (this);
+    } else
+      d_prev = d_next = this;
+  };
+
+  __INLINE__ T object () { return (d_object); };
+  __INLINE__ void object (T l_object) { d_object = l_object; };
+  __INLINE__ bool available () { return (d_available); };
+  __INLINE__ void set_available () { d_available = TRUE; };
+  __INLINE__ void set_available (bool l_avail) { d_available = l_avail; };
+  __INLINE__ void set_not_available () { d_available = FALSE; };
+  __INLINE__ s_node_ptr next () { return (d_next); };
+  __INLINE__ s_node_ptr prev () { return (d_prev); };
+  __INLINE__ s_both<T>* both () { return (d_both); };
+  __INLINE__ void next (s_node_ptr l_next) { d_next = l_next; };
+  __INLINE__ void prev (s_node_ptr l_prev) { d_prev = l_prev; };
+  __INLINE__ void both (s_both<T>* l_both) { d_both = l_both; };
+};
+
+template <class T> class circular_linked_list {
+  typedef s_node<T>* s_node_ptr;
+
+private:
+  s_node_ptr d_current, d_iterate, d_available, d_inUse;
+  UInt32 d_n_nodes, d_n_used;
+  mld_mutex_ptr d_internal;
+  mld_condition_ptr d_ioBlock;
+
+public:
+  circular_linked_list (UInt32 n_nodes) {
+    if (n_nodes == 0)
+      throw std::runtime_error ("circular_linked_list(): n_nodes == 0");
+
+    d_iterate = NULL;
+    d_n_nodes = n_nodes;
+    d_n_used = 0;
+    s_node_ptr l_prev, l_next;
+    d_inUse = d_current = l_next = l_prev = NULL;
+
+    l_prev = new s_node<T> ();
+    l_prev->set_available ();
+    l_prev->next (l_prev);
+    l_prev->prev (l_prev);
+    if (n_nodes > 1) {
+      l_next = new s_node<T> (l_prev, l_prev);
+      l_next->set_available ();
+      l_next->next (l_prev);
+      l_next->prev (l_prev);
+      l_prev->next (l_next);
+      l_prev->prev (l_next);
+      if (n_nodes > 2) {
+       UInt32 n = n_nodes - 2;
+       while (n-- > 0) {
+         d_current = new s_node<T> (l_prev, l_next);
+         d_current->set_available ();
+         d_current->prev (l_prev);
+         d_current->next (l_next);
+         l_prev->next (d_current);
+         l_next->prev (d_current);
+         l_next = d_current;
+         d_current = NULL;
+       }
+      }
+    }
+    d_available = d_current = l_prev;
+    d_ioBlock = new mld_condition ();
+    d_internal = d_ioBlock->mutex ();
+  };
+
+  ~circular_linked_list () {
+    iterate_start ();
+    s_node_ptr l_node = iterate_next ();
+    while (l_node) {
+      delete l_node;
+      l_node = iterate_next ();
+    }
+    delete d_ioBlock;
+    d_ioBlock = NULL;
+    d_available = d_inUse = d_iterate = d_current = NULL;
+    d_n_used = d_n_nodes = 0;
+  };
+
+  s_node_ptr find_next_available_node () {
+    d_internal->lock ();
+// find an available node
+    s_node_ptr l_node = d_available; 
+    DEBUG (fprintf (stderr, "w "););
+    while (! l_node) {
+      DEBUG (fprintf (stderr, "x\n"););
+      // the ioBlock condition will automatically unlock() d_internal
+      d_ioBlock->wait ();
+      // and lock() is here
+      DEBUG (fprintf (stderr, "y\n"););
+      l_node = d_available;
+    }
+    DEBUG (fprintf (stderr, "::f_n_a_n: #u = %ld, node = %p\n",
+                   num_used(), l_node););
+// remove this one from the current available list
+    if (num_available () == 1) {
+// last one, just set available to NULL
+      d_available = NULL;
+    } else
+      d_available = l_node->next ();
+    l_node->remove ();
+// add is to the inUse list
+    if (! d_inUse)
+      d_inUse = l_node;
+    else
+      l_node->insert_before (d_inUse);
+    d_n_used++;
+    l_node->set_not_available ();
+    d_internal->unlock ();
+    return (l_node);
+  };
+
+  void make_node_available (s_node_ptr l_node) {
+    if (!l_node) return;
+    d_internal->lock ();
+    DEBUG (fprintf (stderr, "::m_n_a: #u = %ld, node = %p\n",
+                   num_used(), l_node););
+// remove this node from the inUse list
+    if (num_used () == 1) {
+// last one, just set inUse to NULL
+      d_inUse = NULL;
+    } else
+      d_inUse = l_node->next ();
+    l_node->remove ();
+// add this node to the available list
+    if (! d_available)
+      d_available = l_node;
+    else
+      l_node->insert_before (d_available);
+    d_n_used--;
+
+    DEBUG (fprintf (stderr, "s%ld ", d_n_used););
+// signal the condition when new data arrives
+    d_ioBlock->signal ();
+    DEBUG (fprintf (stderr, "t "););
+
+// unlock the mutex for thread safety
+    d_internal->unlock ();
+  };
+
+  __INLINE__ void iterate_start () { d_iterate = d_current; };
+
+  s_node_ptr iterate_next () {
+#if 0
+// lock the mutex for thread safety
+    d_internal->lock ();
+#endif
+    s_node_ptr l_this = NULL;
+    if (d_iterate) {
+      l_this = d_iterate;
+      d_iterate = d_iterate->next ();
+      if (d_iterate == d_current)
+       d_iterate = NULL;
+    }
+#if 0
+// unlock the mutex for thread safety
+    d_internal->unlock ();
+#endif
+    return (l_this);
+  };
+
+  __INLINE__ T object () { return (d_current->d_object); };
+  __INLINE__ void object (T l_object) { d_current->d_object = l_object; };
+  __INLINE__ UInt32 num_nodes () { return (d_n_nodes); };
+  __INLINE__ UInt32 num_used () { return (d_n_used); };
+  __INLINE__ void num_used (UInt32 l_n_used) { d_n_used = l_n_used; };
+  __INLINE__ UInt32 num_available () { return (d_n_nodes - d_n_used); };
+  __INLINE__ void num_used_inc (void) {
+    if (d_n_used < d_n_nodes) ++d_n_used;
+  };
+  __INLINE__ void num_used_dec (void) {
+    if (d_n_used != 0) --d_n_used;
+// signal the condition that new data has arrived
+    d_ioBlock->signal ();
+  };
+  __INLINE__ bool in_use () { return (d_n_used != 0); };
+};
+
+template <class T> class s_both
+{
+private:
+  s_node<T>* d_node;
+  void* d_this;
+public:
+  __INLINE__ s_both (s_node<T>* l_node, void* l_this)
+    : d_node (l_node), d_this (l_this) {};
+  __INLINE__ ~s_both () {};
+  __INLINE__ s_node<T>* node () { return (d_node); };
+  __INLINE__ void* This () { return (d_this); };
+  __INLINE__ void set (s_node<T>* l_node, void* l_this) {
+    d_node = l_node; d_this = l_this;};
+};
+
+#endif /* _CIRCULAR_LINKED_LIST_H_ */
diff --git a/usrp/host/lib/darwin_libusb.h b/usrp/host/lib/darwin_libusb.h
new file mode 100644 (file)
index 0000000..063a2e9
--- /dev/null
@@ -0,0 +1,190 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 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.
+ */
+
+/*
+ * The following code was taken from LIBUSB verion 0.1.10a,
+ * and makes the fusb_darwin codes do-able in the current GR
+ * programming framework.  Parts and pieces were taken from
+ * usbi.h, darwin.c, and error.h .
+ *
+ * LIBUSB version 0.1.10a is covered by the LGPL, version 2;
+ * These codes are used with permission from:
+ *   (c) 2000-2003 Johannes Erdfelt <johannes@erdfelt.com>
+ *   (c) 2002-2005 Nathan Hjelm <hjelmn@users.sourceforge.net>
+ * All rights reserved.
+ */
+
+#ifndef __DARWIN_LIBUSB_H__
+#define __DARWIN_LIBUSB_H__
+
+#include <IOKit/IOCFBundle.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/usb/IOUSBLib.h>
+#include <IOKit/IOKitLib.h>
+
+extern "C" {
+static char *
+darwin_error_str (int result)
+{
+  switch (result) {
+  case kIOReturnSuccess:
+    return "no error";
+  case kIOReturnNotOpen:
+    return "device not opened for exclusive access";
+  case kIOReturnNoDevice:
+    return "no connection to an IOService";
+  case kIOUSBNoAsyncPortErr:
+    return "no asyc port has been opened for interface";
+  case kIOReturnExclusiveAccess:
+    return "another process has device opened for exclusive access";
+  case kIOUSBPipeStalled:
+    return "pipe is stalled";
+  case kIOReturnError:
+    return "could not establish a connection to Darin kernel";
+  case kIOReturnBadArgument:
+    return "invalid argument";
+  default:
+    return "unknown error";
+  }
+}
+
+/* not a valid errorno outside darwin.c */
+#define LUSBDARWINSTALL (ELAST+1)
+
+static int
+darwin_to_errno (int result)
+{
+  switch (result) {
+  case kIOReturnSuccess:
+    return 0;
+  case kIOReturnNotOpen:
+    return EBADF;
+  case kIOReturnNoDevice:
+  case kIOUSBNoAsyncPortErr:
+    return ENXIO;
+  case kIOReturnExclusiveAccess:
+    return EBUSY;
+  case kIOUSBPipeStalled:
+    return LUSBDARWINSTALL;
+  case kIOReturnBadArgument:
+    return EINVAL;
+  case kIOReturnError:
+  default:
+    return 1;
+  }
+}
+
+typedef enum {
+  USB_ERROR_TYPE_NONE = 0,
+  USB_ERROR_TYPE_STRING,
+  USB_ERROR_TYPE_ERRNO,
+} usb_error_type_t;
+
+extern char usb_error_str[1024];
+extern int usb_error_errno;
+extern usb_error_type_t usb_error_type;
+
+#define USB_ERROR(r, x)                                \
+       do { \
+          usb_error_type = USB_ERROR_TYPE_ERRNO; \
+          usb_error_errno = x; \
+         return r; \
+       } while (0)
+
+#define USB_ERROR_STR(r, x, format, args...)   \
+       do { \
+         usb_error_type = USB_ERROR_TYPE_STRING; \
+         snprintf(usb_error_str, sizeof(usb_error_str) - 1, format, ## args); \
+          if (usb_debug) \
+            fprintf(stderr, "USB error: %s\n", usb_error_str); \
+         return r; \
+       } while (0)
+
+#define USB_ERROR_STR_ORIG(x, format, args...) \
+       do { \
+         usb_error_type = USB_ERROR_TYPE_STRING; \
+         snprintf(usb_error_str, sizeof(usb_error_str) - 1, format, ## args); \
+          if (usb_debug) \
+            fprintf(stderr, "USB error: %s\n", usb_error_str); \
+         return x; \
+       } while (0)
+
+#define USB_ERROR_STR_NO_RET(x, format, args...)       \
+       do { \
+         usb_error_type = USB_ERROR_TYPE_STRING; \
+         snprintf(usb_error_str, sizeof(usb_error_str) - 1, format, ## args); \
+          if (usb_debug) \
+            fprintf(stderr, "USB error: %s\n", usb_error_str); \
+       } while (0)
+
+/* simple function that figures out what pipeRef is associated with an endpoint */
+static int ep_to_pipeRef (darwin_dev_handle *device, int ep)
+{
+  io_return_t ret;
+  UInt8 numep, direction, number;
+  UInt8 dont_care1, dont_care3;
+  UInt16 dont_care2;
+  int i;
+
+  if (usb_debug > 3)
+    fprintf(stderr, "Converting ep address to pipeRef.\n");
+
+  /* retrieve the total number of endpoints on this interface */
+  ret = (*(device->interface))->GetNumEndpoints(device->interface, &numep);
+  if ( ret ) {
+    if ( usb_debug > 3 )
+      fprintf ( stderr, "ep_to_pipeRef: interface is %p\n", device->interface );
+    USB_ERROR_STR_ORIG ( -ret, "ep_to_pipeRef: can't get number of endpoints for interface" );
+  }
+
+  /* iterate through the pipeRefs until we find the correct one */
+  for (i = 1 ; i <= numep ; i++) {
+    ret = (*(device->interface))->GetPipeProperties(device->interface, i, &direction, &number,
+                                                   &dont_care1, &dont_care2, &dont_care3);
+
+    if (ret != kIOReturnSuccess) {
+      fprintf (stderr, "ep_to_pipeRef: an error occurred getting pipe information on pipe %d\n",
+              i );
+      USB_ERROR_STR_ORIG (-darwin_to_errno(ret), "ep_to_pipeRef(GetPipeProperties): %s", darwin_error_str(ret));
+    }
+
+    if (usb_debug > 3)
+      fprintf (stderr, "ep_to_pipeRef: Pipe %i: DIR: %i number: %i\n", i, direction, number);
+
+    /* calculate the endpoint of the pipe and check it versus the requested endpoint */
+    if ( ((direction << 7 & USB_ENDPOINT_DIR_MASK) | (number & USB_ENDPOINT_ADDRESS_MASK)) == ep ) {
+      if (usb_debug > 3)
+       fprintf(stderr, "ep_to_pipeRef: pipeRef for ep address 0x%02x found: 0x%02x\n", ep, i);
+
+      return i;
+    }
+  }
+
+  if (usb_debug > 3)
+    fprintf(stderr, "ep_to_pipeRef: No pipeRef found with endpoint address 0x%02x.\n", ep);
+  
+  /* none of the found pipes match the requested endpoint */
+  return -1;
+}
+
+}
+#endif /* __DARWIN_LIBUSB_H__ */
diff --git a/usrp/host/lib/db_base.cc b/usrp/host/lib/db_base.cc
new file mode 100644 (file)
index 0000000..102166a
--- /dev/null
@@ -0,0 +1,252 @@
+//
+// Copyright 2008,2009 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 <usrp/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");;
+}
+
+bool
+db_base::set_bw(float bw)
+{
+  // Set baseband bandwidth (board specific)
+  // Should be overriden by boards that implement variable IF filtering (e.g., DBSRX)
+  return false;
+}
+
+std::ostream &operator<<(std::ostream &os, db_base &x)
+{
+  os << x.side_and_name();
+  return os;
+}
diff --git a/usrp/host/lib/db_base_impl.h b/usrp/host/lib/db_base_impl.h
new file mode 100644 (file)
index 0000000..9d5ca43
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 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 <usrp/db_base.h>
+#include <db_util.h>
+#include <usrp/usrp_basic.h>
+#include <fpga_regs_standard.h>
+#include <fpga_regs_common.h>
+#include <usrp/usrp_prims.h>
+#include <usrp_spi_defs.h>
+#include <stdexcept>
+
+#endif /* INCLUDED_DB_BASE_IMPL_H */
diff --git a/usrp/host/lib/db_basic.cc b/usrp/host/lib/db_basic.cc
new file mode 100644 (file)
index 0000000..0c6bede
--- /dev/null
@@ -0,0 +1,262 @@
+//
+// Copyright 2008,2009 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 <usrp/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 (d_subdev == 2);
+}
+
+
+
+/******************************************************************************/
+
+
+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/db_boards.cc b/usrp/host/lib/db_boards.cc
new file mode 100644 (file)
index 0000000..070b8dd
--- /dev/null
@@ -0,0 +1,217 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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/usrp_dbid.h>
+#include <usrp/db_basic.h>
+#include <usrp/db_tv_rx.h>
+#include <usrp/db_dbs_rx.h>
+#include <usrp/db_flexrf.h>
+#include <usrp/db_flexrf_mimo.h>
+#include <usrp/db_xcvr2450.h>
+#include <usrp/db_dtt754.h>
+#include <usrp/db_dtt768.h>
+#include <cstdio>
+
+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)));
+    db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 2)));
+    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)));
+    db.push_back(db_base_sptr(new db_lf_rx(usrp, which_side, 2)));
+    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/db_boards.h b/usrp/host/lib/db_boards.h
new file mode 100644 (file)
index 0000000..136091c
--- /dev/null
@@ -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 <usrp/db_base.h>
+#include <usrp/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/db_dbs_rx.cc b/usrp/host/lib/db_dbs_rx.cc
new file mode 100644 (file)
index 0000000..99f66c7
--- /dev/null
@@ -0,0 +1,497 @@
+//
+// 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 <usrp/db_dbs_rx.h>
+#include <db_base_impl.h>
+#include <cmath>
+#include <cstdio>
+
+
+/*****************************************************************************/
+
+
+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);
+}
+
+bool
+db_dbs_rx::set_bw (float bw)
+{
+  if (bw < 1e6 || bw > 33e6) {
+    fprintf(stderr, "db_dbs_rx::set_bw: bw (=%f) must be between 1e6 and 33e6 inclusive\n", bw);
+    return false;
+  }
+
+  // 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, "db_dbs_rx::set_bw: failed\n");
+    return false;
+  }
+
+  return true;
+}
+
+// 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/db_dtt754.cc b/usrp/host/lib/db_dtt754.cc
new file mode 100644 (file)
index 0000000..d78c5b3
--- /dev/null
@@ -0,0 +1,323 @@
+/* -*- 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 <usrp/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;
+}
+
+bool
+db_dtt754::set_bw(float bw)
+{
+  /*
+   * Choose the SAW filter bandwidth, either 7MHz or 8MHz)
+   */
+
+  d_bw = bw;
+  set_freq(d_freq);
+
+  return true; // FIXME: propagate set_freq result
+}
+
+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/db_dtt768.cc b/usrp/host/lib/db_dtt768.cc
new file mode 100644 (file)
index 0000000..a520fdc
--- /dev/null
@@ -0,0 +1,296 @@
+/* -*- 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 <usrp/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;
+}
+
+bool
+db_dtt768::set_bw(float bw)
+{
+  /*
+   * Choose the SAW filter bandwidth, either 7MHz or 8MHz)
+   */
+
+  d_bw = bw;
+  set_freq(d_freq);
+
+  return true; // FIXME: propagate set_freq result
+}
+
+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/db_flexrf.cc b/usrp/host/lib/db_flexrf.cc
new file mode 100644 (file)
index 0000000..a8f4684
--- /dev/null
@@ -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 <usrp/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/db_flexrf_mimo.cc b/usrp/host/lib/db_flexrf_mimo.cc
new file mode 100644 (file)
index 0000000..e2db5cd
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2008,2009 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/db_flexrf_mimo.h>
+#include <fpga_regs_standard.h>
+#include <fpga_regs_common.h>
+#include <usrp/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/db_tv_rx.cc b/usrp/host/lib/db_tv_rx.cc
new file mode 100644 (file)
index 0000000..494ee7a
--- /dev/null
@@ -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 <usrp/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/db_util.cc b/usrp/host/lib/db_util.cc
new file mode 100644 (file)
index 0000000..4b46383
--- /dev/null
@@ -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/db_util.h b/usrp/host/lib/db_util.h
new file mode 100644 (file)
index 0000000..e07abb6
--- /dev/null
@@ -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/db_xcvr2450.cc b/usrp/host/lib/db_xcvr2450.cc
new file mode 100644 (file)
index 0000000..408a055
--- /dev/null
@@ -0,0 +1,791 @@
+//
+// Copyright 2008,2009 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 <usrp/db_xcvr2450.h>
+#include <db_base_impl.h>
+#include <cmath>
+#include <boost/thread.hpp>
+#include <boost/weak_ptr.hpp>
+#include <cstdio>
+
+#if 0
+#define LO_OFFSET 4.25e6
+#else
+#define LO_OFFSET 0
+#define NO_LO_OFFSET
+#endif
+
+
+/* ------------------------------------------------------------------------
+ *  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.
+ */
+
+
+
+// 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 RX_OE_MASK EN|RX_EN|RX_HP
+#define RX_SAFE_IO EN
+
+struct xcvr2450_key {
+  std::string serial_no;
+  int which;
+
+  bool operator==(const xcvr2450_key &x){
+    return x.serial_no ==serial_no && x.which == which;
+  }
+};
+
+class xcvr2450
+{
+private:
+  usrp_basic *d_raw_usrp;
+  int d_which;
+
+  bool d_is_shutdown;
+  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);
+
+public:
+  usrp_basic *usrp(){
+    return d_raw_usrp;
+  }
+
+  xcvr2450(usrp_basic_sptr usrp, int which);
+  ~xcvr2450();
+  void shutdown();
+
+  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);
+
+  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);
+};
+
+
+/*****************************************************************************/
+
+
+xcvr2450::xcvr2450(usrp_basic_sptr _usrp, int which)
+  : d_raw_usrp(_usrp.get()), d_which(which), d_is_shutdown(false)
+{
+  // 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 = 1;    // 0 = 2mA, 1 = 4mA
+  d_ref_div = 1;       // 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  
+  usrp()->common_write_io(C_TX, d_which, TX_SAFE_IO, TX_OE_MASK);
+  usrp()->_common_write_oe(C_TX, d_which, TX_OE_MASK, 0xffff);
+  usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO);
+  usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO);
+  usrp()->common_write_atr_mask(C_TX, d_which, TX_OE_MASK);
+
+  usrp()->common_write_io(C_RX, d_which, RX_SAFE_IO, RX_OE_MASK);
+  usrp()->_common_write_oe(C_RX, d_which, RX_OE_MASK, 0xffff);
+  usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO);
+  usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO);
+  usrp()->common_write_atr_mask(C_RX, d_which, 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");
+  shutdown();
+}
+
+void
+xcvr2450::shutdown()
+{
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO);
+    usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO);
+    usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO);
+    usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO);
+  }
+}
+
+
+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)           |
+                     (0<<11)           |
+                     (d_highband<<10)  |
+                     (d_cp_current<<9) |
+                     (d_ref_div<<5)    |
+                     (d_five_gig<<4)   | 5);
+  send_reg(d_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 %X\n", (v&15), 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 = RX_HP;
+  else
+    rx_hp = 0;
+  
+  if(d_tx_ant)
+    tx_antsel = ANTSEL_TX2_RX1;
+  else
+    tx_antsel = ANTSEL_TX1_RX2;
+
+  if(d_rx_ant)
+    rx_antsel = ANTSEL_TX2_RX1;
+  else
+    rx_antsel = ANTSEL_TX1_RX2;
+
+  if(d_five_gig)
+    tx_pa_sel = LB_PA_OFF;
+  else
+    tx_pa_sel = HB_PA_OFF;
+  // Reset GPIO and ATR
+  // FIXME: dont set io, oe, atr mask once basic code stops overriding our settings
+  usrp()->common_write_io(C_TX, d_which, TX_SAFE_IO, TX_OE_MASK);
+  usrp()->_common_write_oe(C_TX, d_which, TX_OE_MASK, 0xffff);
+  usrp()->common_write_atr_txval(C_TX, d_which, tx_pa_sel|tx_antsel|TX_EN|AD9515DIV);
+  usrp()->common_write_atr_rxval(C_TX, d_which, HB_PA_OFF|LB_PA_OFF|rx_antsel|AD9515DIV);
+  usrp()->common_write_atr_mask(C_TX, d_which, TX_OE_MASK);
+
+  usrp()->common_write_io(C_RX, d_which, RX_SAFE_IO, RX_OE_MASK);
+  usrp()->_common_write_oe(C_RX, d_which, RX_OE_MASK, 0xffff);
+  usrp()->common_write_atr_txval(C_RX, d_which, EN|rx_hp);
+  usrp()->common_write_atr_rxval(C_RX, d_which, EN|rx_hp|RX_EN);
+  usrp()->common_write_atr_mask(C_RX, d_which, RX_OE_MASK);
+
+  //printf("GPIO: RXRX=%04X RXTX=%04X TXRX=%04X TXTX=%04X\n",
+  //       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_ad9515_div = 3;
+    scaler = 4.0/5.0;
+  }
+  else {
+    d_five_gig = 0;
+    d_ad9515_div = 3;
+    scaler = 4.0/3.0;
+  }
+
+  if(target_freq > 5.408e9) {
+    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\n",
+  //    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();
+#ifdef NO_LO_OFFSET
+  args.baseband_freq = target_freq;
+#else
+  args.baseband_freq = actual_freq;
+#endif
+
+  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(usrp()->common_read_io(C_RX, d_which) & LOCKDET) {
+    return true;
+  }
+  else {      // Give it a second chance
+    if(usrp()->common_read_io(C_RX, d_which) & 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;
+}
+
+
+/*****************************************************************************/
+
+
+struct xcvr2450_table_entry {
+  xcvr2450_key                         key;
+  boost::weak_ptr<xcvr2450>    value;
+
+  xcvr2450_table_entry(const xcvr2450_key &_key, boost::weak_ptr<xcvr2450> _value)
+    : key(_key), value(_value) {}
+};
+
+typedef std::vector<xcvr2450_table_entry> xcvr2450_table;
+
+static boost::mutex s_table_mutex;
+static xcvr2450_table s_table;
+
+static xcvr2450_sptr
+_get_or_make_xcvr2450(usrp_basic_sptr usrp, int which)
+{
+  xcvr2450_key key = {usrp->serial_number(), which};
+
+  boost::mutex::scoped_lock    guard(s_table_mutex);
+
+  for (xcvr2450_table::iterator p = s_table.begin(); p != s_table.end();){
+    if (p->value.expired())    // weak pointer is now dead
+      p = s_table.erase(p);    // erase it
+    else {
+      if (key == p->key){      // found it
+       return xcvr2450_sptr(p->value);
+      }
+      else                     
+       ++p;                    // keep looking
+    }
+  }
+
+  // We don't have the xcvr2450 we're looking for
+
+  // create a new one and stick it in the table.
+  xcvr2450_sptr r(new xcvr2450(usrp, which));
+  xcvr2450_table_entry t(key, r);
+  s_table.push_back(t);
+
+  return r;
+}
+
+
+/*****************************************************************************/
+
+
+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()
+{
+}
+
+void
+db_xcvr2450_base::shutdown_common()
+{
+  // If the usrp_basic in the xcvr2450 is the same as the usrp_basic
+  // in the daughterboard, shutdown the xcvr now (when only one of Tx
+  // and Rx is open, this is always true).
+
+  if (d_xcvr->usrp() == usrp()){
+    //std::cerr << "db_xcvr2450_base::shutdown_common: same -> shutting down\n";
+    d_xcvr->shutdown();
+  }
+  else {
+    //std::cerr << "db_xcvr2450_base::shutdown_common: different -> ignoring\n";
+  }
+}
+
+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+d_lo_offset);
+}
+
+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)
+{
+  set_lo_offset(LO_OFFSET);
+  //printf("db_xcvr2450_tx::db_xcvr2450_tx\n");
+}
+
+db_xcvr2450_tx::~db_xcvr2450_tx()
+{
+  shutdown();
+}
+
+void
+db_xcvr2450_tx::shutdown()
+{
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    shutdown_common();
+  }
+}
+
+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.
+   */
+  set_lo_offset(LO_OFFSET);
+  //printf("db_xcvr2450_rx:d_xcvr_2450_rx\n");
+}
+
+db_xcvr2450_rx::~db_xcvr2450_rx()
+{
+  shutdown();
+}
+
+void
+db_xcvr2450_rx::shutdown()
+{
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    shutdown_common();
+  }
+}
+
+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/dump_data.py b/usrp/host/lib/dump_data.py
new file mode 100755 (executable)
index 0000000..034586d
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+#
+# Copyright 2003 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
+import struct
+
+fin = sys.stdin
+
+count = 0
+
+while 1:
+    s = fin.read(2)
+    if not s or len(s) != 2:
+        break
+
+    v, = struct.unpack ('H', s)
+    iv = int(v) & 0xffff
+    print "%8d  %6d  0x%04x" % (count, iv, iv)
+    count += 1
+    
+
+
diff --git a/usrp/host/lib/fusb.cc b/usrp/host/lib/fusb.cc
new file mode 100644 (file)
index 0000000..6e4358f
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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 <fusb.h>
+
+
+// ------------------------------------------------------------------------
+//                          device handle
+// ------------------------------------------------------------------------
+
+fusb_devhandle::fusb_devhandle (usb_dev_handle *udh)
+  : d_udh (udh)
+{
+  // that's it
+};
+
+fusb_devhandle::~fusb_devhandle ()
+{
+  // nop
+}
+
+// ------------------------------------------------------------------------
+//                          end point handle
+// ------------------------------------------------------------------------
+
+fusb_ephandle::fusb_ephandle (int endpoint, bool input_p,
+                             int block_size, int nblocks)
+  : d_endpoint (endpoint), d_input_p (input_p),
+    d_block_size (block_size), d_nblocks (nblocks), d_started (false)
+{
+  // that't it
+}
+
+fusb_ephandle::~fusb_ephandle ()
+{
+  // nop
+}
diff --git a/usrp/host/lib/fusb.h b/usrp/host/lib/fusb.h
new file mode 100644 (file)
index 0000000..769e51c
--- /dev/null
@@ -0,0 +1,138 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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.
+ */
+
+// Fast USB interface
+
+#ifndef _FUSB_H_
+#define _FUSB_H_
+
+
+struct  usb_dev_handle;
+class   fusb_ephandle;
+
+/*!
+ * \brief abstract usb device handle
+ */
+class fusb_devhandle {
+private:
+  // NOT IMPLEMENTED
+  fusb_devhandle (const fusb_devhandle &rhs);            // no copy constructor
+  fusb_devhandle &operator= (const fusb_devhandle &rhs);  // no assignment operator
+
+protected:
+  usb_dev_handle               *d_udh;
+
+public:
+  // CREATORS
+  fusb_devhandle (usb_dev_handle *udh);
+  virtual ~fusb_devhandle ();
+
+  // MANIPULATORS
+  
+  /*!
+   * \brief return an ephandle of the correct subtype
+   */
+  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
+                                       int block_size = 0, int nblocks = 0) = 0;
+  
+  // ACCESSORS
+  usb_dev_handle *get_usb_dev_handle () const { return d_udh; }
+};
+
+
+/*!
+ * \brief abstract usb end point handle
+ */
+class fusb_ephandle {
+private:
+  // NOT IMPLEMENTED
+  fusb_ephandle (const fusb_ephandle &rhs);            // no copy constructor
+  fusb_ephandle &operator= (const fusb_ephandle &rhs);  // no assignment operator
+
+protected:
+  int                          d_endpoint;
+  bool                         d_input_p;
+  int                          d_block_size;
+  int                          d_nblocks;
+  bool                         d_started;
+
+public:
+  fusb_ephandle (int endpoint, bool input_p,
+                int block_size = 0, int nblocks = 0);
+  virtual ~fusb_ephandle ();
+
+  virtual bool start () = 0;   //!< begin streaming i/o
+  virtual bool stop () = 0;    //!< stop streaming i/o
+
+  /*!
+   * \returns \p nbytes if write was successfully enqueued, else -1.
+   * Will block if no free buffers available.
+   */
+  virtual int write (const void *buffer, int nbytes) = 0;
+
+  /*!
+   * \returns number of bytes read or -1 if error.
+   * number of bytes read will be <= nbytes.
+   * Will block if no input available.
+   */
+  virtual int read (void *buffer, int nbytes) = 0;
+
+  /*
+   * block until all outstanding writes have completed
+   */
+  virtual void wait_for_completion () = 0;
+
+  /*!
+   * \brief returns current block size.
+   */
+  int block_size () { return d_block_size; };
+};
+
+
+/*!
+ * \brief factory for creating concrete instances of the appropriate subtype.
+ */
+class fusb_sysconfig {
+public:
+  /*!
+   * \brief returns fusb_devhandle or throws if trouble
+   */
+  static fusb_devhandle *make_devhandle (usb_dev_handle *udh);
+
+  /*!
+   * \brief Returns max block size in bytes (hard limit).
+   */
+  static int max_block_size ();
+
+  /*!
+   * \brief Returns default block size in bytes.
+   */
+  static int default_block_size ();
+
+  /*!
+   * \brief Returns the default buffer size in bytes.
+   */
+  static int default_buffer_size ();
+
+};
+
+#endif /* _FUSB_H_ */
diff --git a/usrp/host/lib/fusb_darwin.cc b/usrp/host/lib/fusb_darwin.cc
new file mode 100644 (file)
index 0000000..737387b
--- /dev/null
@@ -0,0 +1,572 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+// tell mld_threads to NOT use omni_threads,
+// but rather Darwin's pthreads
+#define _USE_OMNI_THREADS_
+#define DO_DEBUG 0
+
+#include <usb.h>
+#include "fusb.h"
+#include "fusb_darwin.h"
+#include "darwin_libusb.h"
+
+static const int USB_TIMEOUT = 100;    // in milliseconds
+static const UInt8 NUM_QUEUE_ITEMS = 20;
+
+fusb_devhandle_darwin::fusb_devhandle_darwin (usb_dev_handle* udh)
+  : fusb_devhandle (udh)
+{
+  // that's it
+}
+
+fusb_devhandle_darwin::~fusb_devhandle_darwin ()
+{
+  // nop
+}
+
+fusb_ephandle*
+fusb_devhandle_darwin::make_ephandle (int endpoint, bool input_p,
+                                     int block_size, int nblocks)
+{
+  return new fusb_ephandle_darwin (this, endpoint, input_p,
+                                  block_size, nblocks);
+}
+
+// ----------------------------------------------------------------
+
+fusb_ephandle_darwin::fusb_ephandle_darwin (fusb_devhandle_darwin* dh,
+                                           int endpoint, bool input_p,
+                                           int block_size, int nblocks)
+  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
+    d_devhandle (dh), d_pipeRef (0), d_transferType (0),
+    d_interfaceRef (0),  d_interface (0), d_queue (0),
+    d_buffer (0), d_bufLenBytes (0)
+{
+  d_bufLenBytes = fusb_sysconfig::max_block_size();
+
+// create circular buffer
+  d_buffer = new circular_buffer<char> (NUM_QUEUE_ITEMS * d_bufLenBytes,
+                                       !d_input_p, d_input_p);
+
+// create the queue
+  d_queue = new circular_linked_list <s_buffer_ptr> (NUM_QUEUE_ITEMS);
+  d_queue->iterate_start ();
+  s_node_ptr l_node = d_queue->iterate_next ();
+  while (l_node) {
+    l_node->both (new s_both<s_buffer_ptr> (l_node, this));
+    s_buffer_ptr l_buf = new s_buffer (d_bufLenBytes);
+    l_node->object (l_buf);
+    l_node = d_queue->iterate_next ();
+    l_buf = NULL;
+  }
+
+  d_readRunning = new mld_mutex ();
+  d_runThreadRunning = new mld_mutex ();
+  d_runBlock = new mld_condition ();
+  d_readBlock = new mld_condition ();
+}
+
+fusb_ephandle_darwin::~fusb_ephandle_darwin ()
+{
+  stop ();
+
+  d_queue->iterate_start ();
+  s_node_ptr l_node = d_queue->iterate_next ();
+  while (l_node) {
+    s_both_ptr l_both = l_node->both ();
+    delete l_both;
+    l_both = NULL;
+    l_node->both (NULL);
+    s_buffer_ptr l_buf = l_node->object ();
+    delete l_buf;
+    l_buf = NULL;
+    l_node->object (NULL);
+    l_node = d_queue->iterate_next ();
+  }
+  delete d_queue;
+  d_queue = NULL;
+  delete d_buffer;
+  d_buffer = NULL;
+  delete d_readRunning;
+  d_readRunning = NULL;
+  delete d_runThreadRunning;
+  d_runThreadRunning = NULL;
+  delete d_runBlock;
+  d_runBlock = NULL;
+  delete d_readBlock;
+  d_readBlock = NULL;
+}
+
+bool
+fusb_ephandle_darwin::start ()
+{
+  UInt8  direction, number, interval;
+  UInt16 maxPacketSize;
+
+// reset circular buffer
+  d_buffer->reset ();
+
+// reset the queue
+  d_queue->num_used (0);
+  d_queue->iterate_start ();
+  s_node_ptr l_node = d_queue->iterate_next ();
+  while (l_node) {
+    l_node->both()->set (l_node, this);
+    l_node->object()->reset ();
+    l_node->set_available ();
+    l_node = d_queue->iterate_next ();
+  }
+
+  d_pipeRef = d_transferType = 0;
+
+  usb_dev_handle* dev = d_devhandle->get_usb_dev_handle ();
+  if (! dev)
+    USB_ERROR_STR (false, -ENXIO, "fusb_ephandle_darwin::start: "
+                  "null device");
+
+  darwin_dev_handle* device = (darwin_dev_handle*) dev->impl_info;
+  if (! device)
+    USB_ERROR_STR (false, -ENOENT, "fusb_ephandle_darwin::start: "
+                  "device not initialized");
+
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::start: "
+            "dev = %p, device = %p\n", dev, device);
+
+  d_interfaceRef = device->interface;
+  if (! d_interfaceRef)
+    USB_ERROR_STR (false, -EACCES, "fusb_ephandle_darwin::start: "
+                  "interface used without being claimed");
+  d_interface = *d_interfaceRef;
+
+// get read or write pipe info (depends on "d_input_p")
+
+  if (usb_debug > 3)
+    fprintf (stderr, "fusb_ephandle_darwin::start "
+            "d_endpoint = %d, d_input_p = %s\n",
+            d_endpoint, d_input_p ? "TRUE" : "FALSE");
+
+  int l_endpoint = (d_input_p ? USB_ENDPOINT_IN : USB_ENDPOINT_OUT);
+  int pipeRef = ep_to_pipeRef (device, d_endpoint | l_endpoint);
+  if (pipeRef < 0)
+    USB_ERROR_STR (false, -EINVAL, "fusb_ephandle_darwin::start "
+                  " invalid pipeRef.\n");
+
+  d_pipeRef = pipeRef;
+  d_interface->GetPipeProperties (d_interfaceRef,
+                                 d_pipeRef,
+                                 &direction,
+                                 &number,
+                                 &d_transferType,
+                                 &maxPacketSize,
+                                 &interval);
+  if (usb_debug == 3)
+    fprintf (stderr, "fusb_ephandle_darwin::start: %s: ep = 0x%02x, "
+            "pipeRef = %d, d_i = %p, d_iR = %p, if_dir = %d, if_# = %d, "
+            "if_int = %d, if_maxPS = %d\n", d_input_p ? "read" : "write",
+            d_endpoint, d_pipeRef, d_interface, d_interfaceRef, direction,
+            number, interval, maxPacketSize);
+
+  // set global start boolean
+  d_started = true;
+
+  // lock the runBlock mutex, before creating the run thread.
+  // this guarantees that we can control execution between these 2 threads
+  d_runBlock->mutex ()->lock ();
+
+  // create the run thread, which allows OSX to process I/O separately
+  d_runThread = new mld_thread (run_thread, this);
+
+  // wait until the run thread (and possibky read thread) are -really-
+  // going; this will unlock the mutex before waiting for a signal ()
+  d_runBlock->wait ();
+
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::start: %s started.\n",
+            d_input_p ? "read" : "write");
+
+  return (true);
+}
+
+void
+fusb_ephandle_darwin::run_thread (void* arg)
+{
+  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(arg);
+
+  // lock the run thread running mutex; if ::stop() is called, it will
+  // first abort() the pipe then wait for the run thread to finish,
+  // via a lock() on this mutex
+  mld_mutex_ptr l_runThreadRunning = This->d_runThreadRunning;
+  l_runThreadRunning->lock ();
+
+  mld_mutex_ptr l_readRunning = This->d_readRunning;
+  mld_condition_ptr l_readBlock = This->d_readBlock;
+  mld_mutex_ptr l_readBlock_mutex = l_readBlock->mutex ();
+
+  bool l_input_p = This->d_input_p;
+
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::run_thread: "
+            "starting for %s.\n",
+            l_input_p ? "read" : "write");
+
+  usb_interface_t** l_interfaceRef = This->d_interfaceRef;
+  usb_interface_t* l_interface = This->d_interface;
+  CFRunLoopSourceRef l_cfSource;
+
+// create async run loop
+  l_interface->CreateInterfaceAsyncEventSource (l_interfaceRef, &l_cfSource);
+  CFRunLoopAddSource (CFRunLoopGetCurrent (), l_cfSource,
+                     kCFRunLoopDefaultMode);
+// get run loop reference, to allow other threads to stop
+  This->d_CFRunLoopRef = CFRunLoopGetCurrent ();
+
+  mld_thread_ptr l_rwThread = NULL;
+
+  if (l_input_p) {
+    // lock the readBlock mutex, before creating the read thread.
+    // this guarantees that we can control execution between these 2 threads
+    l_readBlock_mutex->lock ();
+    // create the read thread, which just issues all of the starting
+    // async read commands, then returns
+    l_rwThread = new mld_thread (read_thread, arg);
+    // wait until the the read thread is -really- going; this will
+    // unlock the read block mutex before waiting for a signal ()
+    l_readBlock->wait ();
+  }
+
+  // now signal the run condition to release and finish ::start().
+
+  // lock the runBlock mutex first; this will force waiting until the
+  // ->wait() command is issued in ::start()
+  mld_mutex_ptr l_run_block_mutex = This->d_runBlock->mutex ();
+  l_run_block_mutex->lock ();
+
+  // now that the lock is in place, signal the parent thread that
+  // things are running
+  This->d_runBlock->signal ();
+
+  // release the run_block mutex, just in case
+  l_run_block_mutex->unlock ();
+
+  // run the loop
+  CFRunLoopRun ();
+
+  if (l_input_p) {
+    // wait for read_thread () to finish, if needed
+    l_readRunning->lock ();
+    l_readRunning->unlock ();
+  }
+
+  // remove run loop stuff
+  CFRunLoopRemoveSource (CFRunLoopGetCurrent (),
+                        l_cfSource, kCFRunLoopDefaultMode);
+
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::run_thread: finished for %s.\n",
+            l_input_p ? "read" : "write");
+
+  // release the run thread running mutex
+  l_runThreadRunning->unlock ();
+}
+
+void
+fusb_ephandle_darwin::read_thread (void* arg)
+{
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::read_thread: starting.\n");
+
+  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(arg);
+
+  // before doing anything else, lock the read running mutex.  this
+  // mutex does flow control between this thread and the run_thread
+  mld_mutex_ptr l_readRunning = This->d_readRunning;
+  l_readRunning->lock ();
+
+  // signal the read condition from run_thread() to continue
+
+  // lock the readBlock mutex first; this will force waiting until the
+  // ->wait() command is issued in ::run_thread()
+  mld_condition_ptr l_readBlock = This->d_readBlock;
+  mld_mutex_ptr l_read_block_mutex = l_readBlock->mutex ();
+  l_read_block_mutex->lock ();
+
+  // now that the lock is in place, signal the parent thread that
+  // things are running here
+  l_readBlock->signal ();
+
+  // release the run_block mutex, just in case
+  l_read_block_mutex->unlock ();
+
+  // queue up all of the available read requests
+  s_queue_ptr l_queue = This->d_queue;
+  l_queue->iterate_start ();
+  s_node_ptr l_node = l_queue->iterate_next ();
+  while (l_node) {
+    This->read_issue (l_node->both ());
+    l_node = l_queue->iterate_next ();
+  }
+
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::read_thread: finished.\n");
+
+  // release the read running mutex, to let the parent thread knows
+  // that this thread is finished
+  l_readRunning->unlock ();
+}
+
+void
+fusb_ephandle_darwin::read_issue (s_both_ptr l_both)
+{
+  if ((! l_both) || (! d_started)) {
+    if (usb_debug > 4)
+      fprintf (stderr, "fusb_ephandle_darwin::read_issue: Doing nothing; "
+              "l_both is %X; started is %s\n", (unsigned int) l_both,
+              d_started ? "TRUE" : "FALSE");
+    return;
+  }
+
+// set the node and buffer from the input "both"
+  s_node_ptr l_node = l_both->node ();
+  s_buffer_ptr l_buf = l_node->object ();
+  void* v_buffer = (void*) l_buf->buffer ();
+
+// read up to d_bufLenBytes
+  UInt32 bufLen = d_bufLenBytes;
+  l_buf->n_used (bufLen);
+
+// setup system call result
+  io_return_t result = kIOReturnSuccess;
+
+  if (d_transferType == kUSBInterrupt)
+/* This is an interrupt pipe. We can't specify a timeout. */
+    result = d_interface->ReadPipeAsync
+      (d_interfaceRef, d_pipeRef, v_buffer, bufLen,
+       (IOAsyncCallback1) read_completed, (void*) l_both);
+  else
+    result = d_interface->ReadPipeAsyncTO
+      (d_interfaceRef, d_pipeRef, v_buffer, bufLen, 0, USB_TIMEOUT,
+       (IOAsyncCallback1) read_completed, (void*) l_both);
+
+  if (result != kIOReturnSuccess)
+    USB_ERROR_STR_NO_RET (- darwin_to_errno (result),
+                         "fusb_ephandle_darwin::read_issue "
+                         "(ReadPipeAsync%s): %s",
+                         d_transferType == kUSBInterrupt ? "" : "TO",
+                         darwin_error_str (result));
+  else if (usb_debug > 4)
+    fprintf (stderr, "fusb_ephandle_darwin::read_issue: "
+            "Queued %X (%ld Bytes)\n", (unsigned int) l_both, bufLen);
+}
+
+void
+fusb_ephandle_darwin::read_completed (void* refCon,
+                                     io_return_t result,
+                                     void* io_size)
+{
+  UInt32 l_size = (UInt32) io_size;
+  s_both_ptr l_both = static_cast<s_both_ptr>(refCon);
+  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(l_both->This ());
+  s_node_ptr l_node = l_both->node ();
+  circular_buffer<char>* l_buffer = This->d_buffer;
+  s_buffer_ptr l_buf = l_node->object ();
+  UInt32 l_i_size = l_buf->n_used ();
+
+  if (This->d_started && (l_i_size != l_size))
+    fprintf (stderr, "fusb_ephandle_darwin::read_completed: "
+            "Expected %ld bytes; read %ld.\n",
+            l_i_size, l_size);
+  else if (usb_debug > 4)
+    fprintf (stderr, "fusb_ephandle_darwin::read_completed: "
+            "Read %X (%ld bytes)\n",
+            (unsigned int) l_both, l_size);
+
+// add this read to the transfer buffer
+  if (l_buffer->enqueue (l_buf->buffer (), l_size) == -1) {
+    fputs ("iU", stderr);
+    fflush (stderr);
+  }
+
+// set buffer's # data to 0
+  l_buf->n_used (0);
+
+// issue another read for this "both"
+  This->read_issue (l_both);
+}
+
+int
+fusb_ephandle_darwin::read (void* buffer, int nbytes)
+{
+  UInt32 l_nbytes = (UInt32) nbytes;
+  d_buffer->dequeue ((char*) buffer, &l_nbytes);
+
+  if (usb_debug > 4)
+    fprintf (stderr, "fusb_ephandle_darwin::read: request for %d bytes, %ld bytes retrieved.\n", nbytes, l_nbytes);
+
+  return ((int) l_nbytes);
+}
+
+int
+fusb_ephandle_darwin::write (const void* buffer, int nbytes)
+{
+  UInt32 l_nbytes = (UInt32) nbytes;
+
+  if (! d_started) {
+    if (usb_debug)
+      fprintf (stderr, "fusb_ephandle_darwin::write: Not yet started.\n");
+
+    return (0);
+  }
+
+  while (l_nbytes != 0) {
+// find out how much data to copy; limited to "d_bufLenBytes" per node
+    UInt32 t_nbytes = (l_nbytes > d_bufLenBytes) ? d_bufLenBytes : l_nbytes;
+
+// get next available node to write into;
+// blocks internally if none available
+    s_node_ptr l_node = d_queue->find_next_available_node ();
+
+// copy the input into the node's buffer
+    s_buffer_ptr l_buf = l_node->object ();
+    l_buf->buffer ((char*) buffer, t_nbytes);
+    void* v_buffer = (void*) l_buf->buffer ();
+
+// setup callback parameter & system call return
+    s_both_ptr l_both = l_node->both ();
+    io_return_t result = kIOReturnSuccess;
+
+    if (d_transferType == kUSBInterrupt)
+/* This is an interrupt pipe ... can't specify a timeout. */
+      result = d_interface->WritePipeAsync
+       (d_interfaceRef, d_pipeRef, v_buffer, t_nbytes,
+        (IOAsyncCallback1) write_completed, (void*) l_both);
+    else
+      result = d_interface->WritePipeAsyncTO
+       (d_interfaceRef, d_pipeRef, v_buffer, t_nbytes, 0, USB_TIMEOUT,
+        (IOAsyncCallback1) write_completed, (void*) l_both);
+
+    if (result != kIOReturnSuccess)
+      USB_ERROR_STR (-1, - darwin_to_errno (result),
+                    "fusb_ephandle_darwin::write_thread "
+                    "(WritePipeAsync%s): %s",
+                    d_transferType == kUSBInterrupt ? "" : "TO",
+                    darwin_error_str (result));
+    else if (usb_debug > 4) {
+      fprintf (stderr, "fusb_ephandle_darwin::write_thread: "
+              "Queued %X (%ld Bytes)\n", (unsigned int) l_both, t_nbytes);
+    }
+    l_nbytes -= t_nbytes;
+  }
+
+  return (nbytes);
+}
+
+void
+fusb_ephandle_darwin::write_completed (void* refCon,
+                                      io_return_t result,
+                                      void* io_size)
+{
+  s_both_ptr l_both = static_cast<s_both_ptr>(refCon);
+  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(l_both->This ());
+  UInt32 l_size = (UInt32) io_size;
+  s_node_ptr l_node = l_both->node ();
+  s_queue_ptr l_queue = This->d_queue;
+  s_buffer_ptr l_buf = l_node->object ();
+  UInt32 l_i_size = l_buf->n_used ();
+
+  if (This->d_started && (l_i_size != l_size))
+    fprintf (stderr, "fusb_ephandle_darwin::write_completed: "
+            "Expected %ld bytes written; wrote %ld.\n",
+            l_i_size, l_size);
+  else if (usb_debug > 4)
+    fprintf (stderr, "fusb_ephandle_darwin::write_completed: "
+            "Wrote %X (%ld Bytes)\n", (unsigned int) l_both, l_size);
+
+// set buffer's # data to 0
+  l_buf->n_used (0);
+// make the node available for reuse
+  l_queue->make_node_available (l_node);
+}
+
+void
+fusb_ephandle_darwin::abort ()
+{
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::abort: starting.\n");
+
+  io_return_t result = d_interface->AbortPipe (d_interfaceRef, d_pipeRef);
+
+  if (result != kIOReturnSuccess)
+    USB_ERROR_STR_NO_RET (- darwin_to_errno (result),
+                         "fusb_ephandle_darwin::abort "
+                         "(AbortPipe): %s", darwin_error_str (result));
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::abort: finished.\n");
+}
+
+bool
+fusb_ephandle_darwin::stop ()
+{
+  if (! d_started)
+    return (true);
+
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::stop: stopping %s.\n",
+            d_input_p ? "read" : "write");
+
+  d_started = false;
+
+// abort any pending IO transfers
+  abort ();
+
+// wait for write transfer to finish
+  wait_for_completion ();
+
+// tell IO buffer to abort any waiting conditions
+  d_buffer->abort ();
+
+// stop the run loop
+  CFRunLoopStop (d_CFRunLoopRef);
+
+// wait for the runThread to stop
+  d_runThreadRunning->lock ();
+  d_runThreadRunning->unlock ();
+
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::stop: %s stopped.\n",
+            d_input_p ? "read" : "write");
+
+  return (true);
+}
+
+void
+fusb_ephandle_darwin::wait_for_completion ()
+{
+  if (d_queue)
+    while (d_queue->in_use ())
+      usleep (1000);
+}
diff --git a/usrp/host/lib/fusb_darwin.h b/usrp/host/lib/fusb_darwin.h
new file mode 100644 (file)
index 0000000..bb717b5
--- /dev/null
@@ -0,0 +1,215 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 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 _FUSB_DARWIN_H_
+#define _FUSB_DARWIN_H_
+
+#include <usb.h>
+#include "fusb.h"
+#include <IOKit/IOCFBundle.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/usb/IOUSBLib.h>
+#include <IOKit/IOKitLib.h>
+#include "circular_linked_list.h"
+#include "circular_buffer.h"
+
+// for MacOS X 10.4.[0-3]
+#define usb_interface_t IOUSBInterfaceInterface220
+#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID220
+#define InterfaceVersion 220
+
+// for MacOS X 10.3.[0-9] and 10.4.[0-3]
+#define usb_device_t    IOUSBDeviceInterface197
+#define DeviceInterfaceID kIOUSBDeviceInterfaceID197
+#define DeviceVersion 197
+
+extern "C" {
+typedef struct usb_dev_handle {
+  int fd;
+
+  struct usb_bus *bus;
+  struct usb_device *device;
+
+  int config;
+  int interface;
+  int altsetting;
+
+  /* Added by RMT so implementations can store other per-open-device data */
+  void *impl_info;
+} usb_dev_handle;
+
+/* Darwin/OS X impl does not use fd field, instead it uses this */
+typedef struct darwin_dev_handle {
+  usb_device_t** device;
+  usb_interface_t** interface;
+  int open;
+} darwin_dev_handle;
+
+typedef IOReturn io_return_t;
+typedef IOCFPlugInInterface *io_cf_plugin_ref_t;
+
+static int ep_to_pipeRef (darwin_dev_handle* device, int ep);
+extern int usb_debug;
+}
+
+class s_buffer
+{
+private:
+  char* d_buffer;
+  UInt32 d_n_used, d_n_alloc;
+
+public:
+  inline s_buffer (UInt32 n_alloc = 0) {
+    d_n_used = 0;
+    d_n_alloc = n_alloc;
+    if (n_alloc) {
+      d_buffer = (char*) new char [n_alloc];
+    } else {
+      d_buffer = 0;
+    }
+  };
+  inline ~s_buffer () {
+    if (d_n_alloc) {
+      delete [] d_buffer;
+    }
+  };
+  inline UInt32 n_used () { return (d_n_used); };
+  inline void n_used (UInt32 bufLen) {
+    d_n_used = (bufLen > d_n_alloc) ? d_n_alloc : bufLen; };
+  inline UInt32 n_alloc () { return (d_n_alloc); };
+  void buffer (char* l_buffer, UInt32 bufLen) {
+    if (bufLen > d_n_alloc) {
+      fprintf (stderr, "s_buffer::set: Copying only allocated bytes.\n");
+      bufLen = d_n_alloc;
+    }
+    if (!l_buffer) {
+      fprintf (stderr, "s_buffer::set: NULL buffer.\n");
+      return;
+    }
+    bcopy (l_buffer, d_buffer, bufLen);
+    d_n_used = bufLen;
+  };
+  inline char* buffer () { return (d_buffer); };
+  inline void reset () {
+    bzero (d_buffer, d_n_alloc);
+    d_n_used = 0;
+  };
+};
+
+typedef s_buffer* s_buffer_ptr;
+typedef s_node<s_buffer_ptr>* s_node_ptr;
+typedef circular_linked_list<s_buffer_ptr>* s_queue_ptr;
+typedef s_both<s_buffer_ptr>* s_both_ptr;
+
+/*!
+ * \brief darwin implementation of fusb_devhandle
+ *
+ * This is currently identical to the generic implementation
+ * and is intended as a starting point for whatever magic is
+ * required to make usb fly.
+ */
+class fusb_devhandle_darwin : public fusb_devhandle
+{
+public:
+  // CREATORS
+  fusb_devhandle_darwin (usb_dev_handle* udh);
+  virtual ~fusb_devhandle_darwin ();
+
+  // MANIPULATORS
+  virtual fusb_ephandle* make_ephandle (int endpoint, bool input_p,
+                                       int block_size = 0, int nblocks = 0);
+};
+
+/*!
+ * \brief darwin implementation of fusb_ephandle
+ *
+ * This is currently identical to the generic implementation
+ * and is intended as a starting point for whatever magic is
+ * required to make usb fly.
+ */
+class fusb_ephandle_darwin : public fusb_ephandle
+{
+private:
+  fusb_devhandle_darwin* d_devhandle;
+  mld_thread_ptr d_runThread;
+  mld_mutex_ptr d_runThreadRunning;
+
+  CFRunLoopRef d_CFRunLoopRef;
+
+  static void write_completed (void* ret_io_size,
+                              io_return_t result,
+                              void* io_size);
+  static void read_completed (void* ret_io_size,
+                             io_return_t result,
+                             void* io_size);
+  static void run_thread (void* arg);
+  static void read_thread (void* arg);
+
+  void read_issue (s_both_ptr l_both);
+
+public:
+  // variables, for now
+  UInt8 d_pipeRef, d_transferType;
+  usb_interface_t** d_interfaceRef;
+  usb_interface_t* d_interface;
+  s_queue_ptr d_queue;
+  circular_buffer<char>* d_buffer;
+  UInt32 d_bufLenBytes;
+  mld_mutex_ptr d_readRunning;
+  mld_condition_ptr d_runBlock, d_readBlock;
+
+// CREATORS
+
+  fusb_ephandle_darwin (fusb_devhandle_darwin *dh, int endpoint, bool input_p,
+                        int block_size = 0, int nblocks = 0);
+  virtual ~fusb_ephandle_darwin ();
+
+// MANIPULATORS
+
+  virtual bool start ();       //!< begin streaming i/o
+  virtual bool stop ();                //!< stop streaming i/o
+
+  /*!
+   * \returns \p nbytes if write was successfully enqueued, else -1.
+   * Will block if no free buffers available.
+   */
+  virtual int write (const void* buffer, int nbytes);
+
+  /*!
+   * \returns number of bytes read or -1 if error.
+   * number of bytes read will be <= nbytes.
+   * Will block if no input available.
+   */
+  virtual int read (void* buffer, int nbytes);
+
+  /*
+   * abort any pending IO transfers
+   */
+  void abort ();
+
+  /*
+   * block until all outstanding writes have completed
+   */
+  virtual void wait_for_completion ();
+};
+
+#endif /* _FUSB_DARWIN_H_ */
diff --git a/usrp/host/lib/fusb_generic.cc b/usrp/host/lib/fusb_generic.cc
new file mode 100644 (file)
index 0000000..0958716
--- /dev/null
@@ -0,0 +1,108 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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 <fusb_generic.h>
+#include <usb.h>
+
+
+static const int USB_TIMEOUT = 1000;   // in milliseconds
+
+
+fusb_devhandle_generic::fusb_devhandle_generic (usb_dev_handle *udh)
+  : fusb_devhandle (udh)
+{
+  // that's it
+}
+
+fusb_devhandle_generic::~fusb_devhandle_generic ()
+{
+  // nop
+}
+
+fusb_ephandle *
+fusb_devhandle_generic::make_ephandle (int endpoint, bool input_p,
+                                      int block_size, int nblocks)
+{
+  return new fusb_ephandle_generic (this, endpoint, input_p,
+                                   block_size, nblocks);
+}
+
+// ----------------------------------------------------------------
+
+fusb_ephandle_generic::fusb_ephandle_generic (fusb_devhandle_generic *dh,
+                                             int endpoint, bool input_p,
+                                             int block_size, int nblocks)
+  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
+    d_devhandle (dh)
+{
+  // that's it
+}
+
+fusb_ephandle_generic::~fusb_ephandle_generic ()
+{
+  // nop
+}
+
+bool
+fusb_ephandle_generic::start ()
+{
+  d_started = true;
+  return true;
+}
+
+bool
+fusb_ephandle_generic::stop ()
+{
+  d_started = false;
+  return true;
+}
+
+int
+fusb_ephandle_generic::write (const void *buffer, int nbytes)
+{
+  if (!d_started)      // doesn't matter here, but keeps semantics constant
+    return -1;
+  
+  if (d_input_p)
+    return -1;
+  
+  return usb_bulk_write (d_devhandle->get_usb_dev_handle (),
+                        d_endpoint, (char *) buffer, nbytes, USB_TIMEOUT);
+}
+
+int
+fusb_ephandle_generic::read (void *buffer, int nbytes)
+{
+  if (!d_started)      // doesn't matter here, but keeps semantics constant
+    return -1;
+
+  if (!d_input_p)
+    return -1;
+
+  return usb_bulk_read (d_devhandle->get_usb_dev_handle (),
+                       d_endpoint|USB_ENDPOINT_IN, (char *) buffer, nbytes,
+                       USB_TIMEOUT);
+}
diff --git a/usrp/host/lib/fusb_generic.h b/usrp/host/lib/fusb_generic.h
new file mode 100644 (file)
index 0000000..b9aef27
--- /dev/null
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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 _FUSB_GENERIC_H_
+#define _FUSB_GENERIC_H_
+
+#include <fusb.h>
+
+/*!
+ * \brief generic implementation of fusb_devhandle using only libusb
+ */
+class fusb_devhandle_generic : public fusb_devhandle
+{
+public:
+  // CREATORS
+  fusb_devhandle_generic (usb_dev_handle *udh);
+  virtual ~fusb_devhandle_generic ();
+
+  // MANIPULATORS
+  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
+                                       int block_size = 0, int nblocks = 0);
+};
+
+
+/*!
+ * \brief generic implementation of fusb_ephandle using only libusb
+ */
+class fusb_ephandle_generic : public fusb_ephandle
+{
+private:
+  fusb_devhandle_generic       *d_devhandle;
+  
+public:
+  // CREATORS
+  fusb_ephandle_generic (fusb_devhandle_generic *dh, int endpoint, bool input_p,
+                        int block_size = 0, int nblocks = 0);
+  virtual ~fusb_ephandle_generic ();
+
+  // MANIPULATORS
+
+  virtual bool start ();       //!< begin streaming i/o
+  virtual bool stop ();                //!< stop streaming i/o
+
+  /*!
+   * \returns \p nbytes if write was successfully enqueued, else -1.
+   * Will block if no free buffers available.
+   */
+  virtual int write (const void *buffer, int nbytes);
+
+  /*!
+   * \returns number of bytes read or -1 if error.
+   * number of bytes read will be <= nbytes.
+   * Will block if no input available.
+   */
+  virtual int read (void *buffer, int nbytes);
+
+  /*
+   * block until all outstanding writes have completed
+   */
+  virtual void wait_for_completion () { };
+};
+
+#endif /* _FUSB_GENERIC_H_ */
+
diff --git a/usrp/host/lib/fusb_linux.cc b/usrp/host/lib/fusb_linux.cc
new file mode 100644 (file)
index 0000000..6c48456
--- /dev/null
@@ -0,0 +1,692 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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 <fusb_linux.h>
+#include <usb.h>               // libusb header
+#include <stdexcept>
+#ifdef HAVE_LINUX_COMPILER_H
+#include <linux/compiler.h>
+#endif
+#include <linux/usbdevice_fs.h>        // interface to kernel portion of user mode usb driver
+#include <sys/ioctl.h>
+#include <assert.h>
+#include <string.h>
+#include <algorithm>
+#include <errno.h>
+#include <string.h>
+#include <cstdio>
+
+#define MINIMIZE_TX_BUFFERING 1                // must be defined to 0 or 1
+
+
+static const int MAX_BLOCK_SIZE = fusb_sysconfig::max_block_size();            // hard limit
+static const int DEFAULT_BLOCK_SIZE = MAX_BLOCK_SIZE;
+static const int DEFAULT_BUFFER_SIZE = 4 * (1L << 20);                         // 4 MB / endpoint
+
+
+// Totally evil and fragile extraction of file descriptor from
+// guts of libusb.  They don't install usbi.h, which is what we'd need
+// to do this nicely.
+//
+// FIXME if everything breaks someday in the future, look here...
+
+static int
+fd_from_usb_dev_handle (usb_dev_handle *udh)
+{
+  return *((int *) udh);
+}
+
+inline static void
+urb_set_ephandle (usbdevfs_urb *urb, fusb_ephandle_linux *handle)
+{
+  urb->usercontext = handle;
+}
+
+inline static fusb_ephandle_linux *
+urb_get_ephandle (usbdevfs_urb *urb)
+{
+  return (fusb_ephandle_linux *) urb->usercontext;
+}
+
+// ------------------------------------------------------------------------
+//                USB request block (urb) allocation
+// ------------------------------------------------------------------------
+
+static usbdevfs_urb *
+alloc_urb (fusb_ephandle_linux *self, int buffer_length, int endpoint,
+          bool input_p, unsigned char *write_buffer)
+{
+  usbdevfs_urb *urb = new usbdevfs_urb;
+  memset (urb, 0, sizeof (*urb));
+
+  urb->buffer_length = buffer_length;
+
+  // We allocate dedicated memory only for input buffers.
+  // For output buffers we reuse the same buffer (the kernel 
+  // copies the data at submital time)
+
+  if (input_p)
+    urb->buffer = new unsigned char [buffer_length];
+  else
+    urb->buffer = write_buffer;
+
+  // init common values
+
+  urb->type = USBDEVFS_URB_TYPE_BULK;
+  urb->endpoint = (endpoint & 0x7f) | (input_p ? 0x80 : 0);
+
+  // USBDEVFS_URB_QUEUE_BULK goes away in linux 2.5, but is needed if
+  // we are using a 2.4 usb-uhci host controller driver.  This is
+  // unlikely since we're almost always going to be plugged into a
+  // high speed host controller (ehci)
+#if 0 && defined (USBDEVFS_URB_QUEUE_BULK)
+  urb->flags = USBDEVFS_URB_QUEUE_BULK;
+#endif
+
+  urb->signr = 0;
+  urb_set_ephandle (urb, self);
+
+  return urb;
+}
+
+static void
+free_urb (usbdevfs_urb *urb)
+{
+  // if this was an input urb, free the buffer
+  if (urb->endpoint & 0x80)
+    delete [] ((unsigned char *) urb->buffer);
+
+  delete urb;
+}
+
+// ------------------------------------------------------------------------
+//                             device handle
+// ------------------------------------------------------------------------
+
+fusb_devhandle_linux::fusb_devhandle_linux (usb_dev_handle *udh)
+  : fusb_devhandle (udh)
+{
+  // that's all
+}
+
+fusb_devhandle_linux::~fusb_devhandle_linux ()
+{
+  // if there are any pending requests, cancel them and free the urbs.
+  
+  std::list<usbdevfs_urb*>::reverse_iterator it;
+
+  for (it = d_pending_rqsts.rbegin (); it != d_pending_rqsts.rend (); it++){
+    _cancel_urb (*it);
+    free_urb (*it);
+  }
+}
+
+fusb_ephandle *
+fusb_devhandle_linux::make_ephandle (int endpoint, bool input_p,
+                                    int block_size, int nblocks)
+{
+  return new fusb_ephandle_linux (this, endpoint, input_p,
+                                 block_size, nblocks);
+}
+
+
+// Attempt to cancel all transactions associated with eph.
+
+void
+fusb_devhandle_linux::_cancel_pending_rqsts (fusb_ephandle_linux *eph)
+{
+  std::list<usbdevfs_urb*>::reverse_iterator it;
+
+  for (it = d_pending_rqsts.rbegin (); it != d_pending_rqsts.rend (); it++){
+    if (urb_get_ephandle (*it) == eph)
+      _cancel_urb (*it);
+  }
+}
+
+void 
+fusb_devhandle_linux::pending_add (usbdevfs_urb *urb)
+{
+  d_pending_rqsts.push_back (urb);
+}
+
+usbdevfs_urb *
+fusb_devhandle_linux::pending_get ()
+{
+  if (d_pending_rqsts.empty ())
+    return 0;
+
+  usbdevfs_urb *urb = d_pending_rqsts.front ();
+  d_pending_rqsts.pop_front ();
+  return urb;
+}
+
+bool
+fusb_devhandle_linux::pending_remove (usbdevfs_urb *urb)
+{
+  std::list<usbdevfs_urb*>::iterator   result = find (d_pending_rqsts.begin (),
+                                                      d_pending_rqsts.end (),
+                                                      urb);
+  if (result == d_pending_rqsts.end ()){
+    fprintf (stderr, "fusb::pending_remove: failed to find urb in pending_rqsts: %p\n", urb);
+    return false;
+  }
+  d_pending_rqsts.erase (result);
+  return true;
+}
+
+/*
+ * Submit the urb to the kernel.
+ * iff successful, the urb will be placed on the devhandle's pending list.
+ */
+bool
+fusb_devhandle_linux::_submit_urb (usbdevfs_urb *urb)
+{
+  int  ret;
+
+  ret = ioctl (fd_from_usb_dev_handle (d_udh), USBDEVFS_SUBMITURB, urb);
+  if (ret < 0){
+    perror ("fusb::_submit_urb");
+    return false;
+  }
+  
+  pending_add (urb);
+  return true;
+}
+
+/*
+ * Attempt to cancel the in pending or in-progress urb transaction.
+ * Return true iff transaction was sucessfully cancelled.
+ *
+ * Failure to cancel should not be considered a problem.  This frequently
+ * occurs if the transaction has already completed in the kernel but hasn't
+ * yet been reaped by the user mode code.
+ *
+ * urbs which were cancelled have their status field set to -ENOENT when
+ * they are reaped.
+ */
+bool
+fusb_devhandle_linux::_cancel_urb (usbdevfs_urb *urb)
+{
+  int ret = ioctl (fd_from_usb_dev_handle (d_udh), USBDEVFS_DISCARDURB, urb);
+  if (ret < 0){
+    // perror ("fusb::_cancel_urb");
+    return false;
+  }
+  return true;
+}
+
+/*
+ * Check with the kernel and see if any of our outstanding requests
+ * have completed.  For each completed transaction, remove it from the
+ * devhandle's pending list and append it to the completed list for
+ * the corresponding endpoint.
+ *
+ * If any transactions are reaped return true.
+ *
+ * If ok_to_block_p is true, then this will block until at least one
+ * transaction completes or an unrecoverable error occurs.
+ */
+bool
+fusb_devhandle_linux::_reap (bool ok_to_block_p)
+{
+  int          ret;
+  int          nreaped = 0;
+  usbdevfs_urb *urb = 0;
+
+  int  fd = fd_from_usb_dev_handle (d_udh);
+  
+  // try to reap as many as possible without blocking...
+
+  while ((ret = ioctl (fd, USBDEVFS_REAPURBNDELAY, &urb)) == 0){
+    if (urb->status != 0 && urb->status != -ENOENT){
+      fprintf (stderr, "_reap: usb->status = %d, actual_length = %5d\n",
+              urb->status, urb->actual_length);
+    }
+    pending_remove (urb);
+    urb_get_ephandle (urb)->completed_list_add (urb);
+    nreaped++;
+  }
+
+  if (nreaped > 0)             // if we got any, return w/o blocking
+    return true;
+
+  if (!ok_to_block_p)
+    return false;
+  
+  ret = ioctl (fd, USBDEVFS_REAPURB, &urb);
+  if (ret < 0){
+    perror ("fusb::_reap");
+    return false;
+  }
+
+  pending_remove (urb);
+  urb_get_ephandle (urb)->completed_list_add (urb);
+  return true;
+}
+
+void
+fusb_devhandle_linux::_wait_for_completion ()
+{
+  while (!d_pending_rqsts.empty ())
+    if (!_reap(true))
+      break;
+}
+\f// ------------------------------------------------------------------------
+//                          end point handle
+// ------------------------------------------------------------------------
+
+fusb_ephandle_linux::fusb_ephandle_linux (fusb_devhandle_linux *devhandle,
+                                         int endpoint,
+                                         bool input_p,
+                                         int block_size, int nblocks)
+  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
+    d_devhandle (devhandle), 
+    d_write_work_in_progress (0), d_write_buffer (0),
+    d_read_work_in_progress (0), d_read_buffer (0), d_read_buffer_end (0)
+{
+
+  if (d_block_size < 0 || d_block_size > MAX_BLOCK_SIZE)
+    throw std::out_of_range ("fusb_ephandle_linux: block_size");
+
+  if (d_nblocks < 0)
+    throw std::out_of_range ("fusb_ephandle_linux: nblocks");
+
+  if (d_block_size == 0)
+    d_block_size = DEFAULT_BLOCK_SIZE;
+
+  if (d_nblocks == 0)
+    d_nblocks = std::max (1, DEFAULT_BUFFER_SIZE / d_block_size);
+
+  if (!d_input_p)
+    if (!MINIMIZE_TX_BUFFERING)
+      d_write_buffer = new unsigned char [d_block_size];
+
+  if (0)
+    fprintf(stderr, "fusb_ephandle_linux::ctor: d_block_size = %d  d_nblocks = %d\n",
+           d_block_size, d_nblocks);
+
+  // allocate urbs
+
+  for (int i = 0; i < d_nblocks; i++)
+    d_free_list.push_back (alloc_urb (this, d_block_size, d_endpoint,
+                                     d_input_p, d_write_buffer));
+}
+
+fusb_ephandle_linux::~fusb_ephandle_linux ()
+{
+  stop ();
+
+  usbdevfs_urb *urb;
+
+  while ((urb = free_list_get ()) != 0)
+    free_urb (urb);
+
+  while ((urb = completed_list_get ()) != 0)
+    free_urb (urb);
+
+  if (d_write_work_in_progress)
+    free_urb (d_write_work_in_progress);
+
+  delete [] d_write_buffer;
+
+  if (d_read_work_in_progress)
+    free_urb (d_read_work_in_progress);
+}
+
+// ----------------------------------------------------------------
+
+bool
+fusb_ephandle_linux::start ()
+{
+  if (d_started)
+    return true;               // already running
+
+  d_started = true;
+
+  if (d_input_p){              // fire off all the reads
+    usbdevfs_urb *urb;
+
+    int nerrors = 0;
+    while ((urb = free_list_get ()) != 0 && nerrors < d_nblocks){
+      if (!submit_urb (urb))
+       nerrors++;
+    }
+  }
+
+  return true;
+}
+
+//
+// kill all i/o in progress.
+// kill any completed but unprocessed transactions.
+//
+bool
+fusb_ephandle_linux::stop ()
+{
+  if (!d_started)
+    return true;
+
+  if (d_write_work_in_progress){
+    free_list_add (d_write_work_in_progress);
+    d_write_work_in_progress = 0;
+  }
+
+  if (d_read_work_in_progress){
+    free_list_add (d_read_work_in_progress);
+    d_read_work_in_progress = 0;
+    d_read_buffer = 0;
+    d_read_buffer_end = 0;
+  }
+
+  d_devhandle->_cancel_pending_rqsts (this);
+  d_devhandle->_reap (false);
+
+  while (1){
+    usbdevfs_urb *urb;
+    while ((urb = completed_list_get ()) != 0)
+      free_list_add (urb);
+
+    if (d_free_list.size () == (unsigned) d_nblocks)
+      break;
+
+    if (!d_devhandle->_reap(true))
+      break;
+  }
+
+  d_started = false;
+  return true;
+}
+
+// ----------------------------------------------------------------
+//                     routines for writing 
+// ----------------------------------------------------------------
+
+#if (MINIMIZE_TX_BUFFERING)
+
+int 
+fusb_ephandle_linux::write(const void *buffer, int nbytes)
+{
+  if (!d_started)
+    return -1;
+  
+  if (d_input_p)
+    return -1;
+
+  assert(nbytes % 512 == 0);
+
+  unsigned char *src = (unsigned char *) buffer;
+
+  int n = 0;
+  while (n < nbytes){
+
+    usbdevfs_urb *urb = get_write_work_in_progress();
+    if (!urb)
+      return -1;
+    assert(urb->actual_length == 0);
+    int m = std::min(nbytes - n, MAX_BLOCK_SIZE);
+    urb->buffer = src;
+    urb->buffer_length = m;
+
+    n += m;
+    src += m;
+
+    if (!submit_urb(urb))
+      return -1;
+
+    d_write_work_in_progress = 0;
+  }
+
+  return n;
+}
+
+#else
+
+int 
+fusb_ephandle_linux::write (const void *buffer, int nbytes)
+{
+  if (!d_started)
+    return -1;
+  
+  if (d_input_p)
+    return -1;
+
+  unsigned char *src = (unsigned char *) buffer;
+
+  int n = 0;
+  while (n < nbytes){
+
+    usbdevfs_urb *urb = get_write_work_in_progress ();
+    if (!urb)
+      return -1;
+    unsigned char *dst = (unsigned char *) urb->buffer;
+    int m = std::min (nbytes - n, urb->buffer_length - urb->actual_length);
+
+    memcpy (&dst[urb->actual_length], &src[n], m);
+    urb->actual_length += m;
+    n += m;
+
+    if (urb->actual_length == urb->buffer_length){
+      if (!submit_urb (urb))
+       return -1;
+      d_write_work_in_progress = 0;
+    }
+  }
+
+  return n;
+}
+
+#endif
+
+usbdevfs_urb *
+fusb_ephandle_linux::get_write_work_in_progress ()
+{
+  // if we've already got some work in progress, return it
+
+  if (d_write_work_in_progress)
+    return d_write_work_in_progress;
+
+  while (1){
+
+    reap_complete_writes ();
+
+    usbdevfs_urb *urb = free_list_get ();
+
+    if (urb != 0){
+      assert (urb->actual_length == 0);
+      d_write_work_in_progress = urb;
+      return urb;
+    }
+
+    // The free list is empty.  Tell the device handle to reap.
+    // Anything it reaps for us will end up on our completed list.
+
+    if (!d_devhandle->_reap (true))
+      return 0;
+  }
+}
+
+void
+fusb_ephandle_linux::reap_complete_writes ()
+{
+  // take a look at the completed_list and xfer to free list after
+  // checking for errors.
+
+  usbdevfs_urb *urb;
+  
+  while ((urb = completed_list_get ()) != 0){
+
+    // Check for any errors or short writes that were reported in the urb.
+    // The kernel sets status, actual_length and error_count.
+    // error_count is only used for ISO xfers.
+    // status is 0 if successful, else is an errno kind of thing
+
+    if (urb->status != 0){
+      fprintf (stderr, "fusb: (status %d) %s\n", urb->status, strerror (-urb->status));
+    }
+    else if (urb->actual_length != urb->buffer_length){
+      fprintf (stderr, "fusb: short write xfer: %d != %d\n",
+              urb->actual_length, urb->buffer_length);
+    }
+
+    free_list_add (urb);
+  }
+}
+
+void
+fusb_ephandle_linux::wait_for_completion ()
+{
+  d_devhandle->_wait_for_completion ();
+}
+
+// ----------------------------------------------------------------
+//                    routines for reading
+// ----------------------------------------------------------------
+
+int
+fusb_ephandle_linux::read (void *buffer, int nbytes)
+{
+  if (!d_started)
+    return -1;
+  
+  if (!d_input_p)
+    return -1;
+
+  unsigned char *dst = (unsigned char *) buffer;
+
+  int n = 0;
+  while (n < nbytes){
+
+    if (d_read_buffer >= d_read_buffer_end)
+      if (!reload_read_buffer ())
+       return -1;
+
+    int m = std::min (nbytes - n, (int) (d_read_buffer_end - d_read_buffer));
+
+    memcpy (&dst[n], d_read_buffer, m);
+    d_read_buffer += m;
+    n += m;
+  }
+
+  return n;
+}
+
+bool
+fusb_ephandle_linux::reload_read_buffer ()
+{
+  assert (d_read_buffer >= d_read_buffer_end);
+
+  usbdevfs_urb *urb;
+
+  if (d_read_work_in_progress){
+    // We're done with this urb.  Fire off a read to refill it.
+    urb = d_read_work_in_progress;
+    d_read_work_in_progress = 0;
+    d_read_buffer = 0;
+    d_read_buffer_end = 0;
+    urb->actual_length = 0;
+    if (!submit_urb (urb))
+      return false;
+  }
+
+  while (1){
+
+    while ((urb = completed_list_get ()) == 0)
+      if (!d_devhandle->_reap (true))
+       return false;
+
+    // check result of completed read
+
+    if (urb->status != 0){
+      // We've got a problem. Report it and fail.
+      fprintf (stderr, "fusb: (rd status %d) %s\n", urb->status, strerror (-urb->status));
+      urb->actual_length = 0;
+      free_list_add (urb);
+      return false;
+    }
+
+    // we've got a happy urb, full of data...
+
+    d_read_work_in_progress = urb;
+    d_read_buffer = (unsigned char *) urb->buffer;
+    d_read_buffer_end = d_read_buffer + urb->actual_length;
+
+    return true;
+  }
+}
+
+// ----------------------------------------------------------------
+
+void
+fusb_ephandle_linux::free_list_add (usbdevfs_urb *urb)
+{
+  assert (urb_get_ephandle (urb) == this);
+  urb->actual_length = 0;
+  d_free_list.push_back (urb);
+}
+
+usbdevfs_urb *
+fusb_ephandle_linux::free_list_get ()
+{
+  if (d_free_list.empty ())
+    return 0;
+
+  usbdevfs_urb *urb = d_free_list.front ();
+  d_free_list.pop_front ();
+  return urb;
+}
+
+void
+fusb_ephandle_linux::completed_list_add (usbdevfs_urb *urb)
+{
+  assert (urb_get_ephandle (urb) == this);
+  d_completed_list.push_back (urb);
+}
+
+usbdevfs_urb *
+fusb_ephandle_linux::completed_list_get ()
+{
+  if (d_completed_list.empty ())
+    return 0;
+
+  usbdevfs_urb *urb = d_completed_list.front ();
+  d_completed_list.pop_front ();
+  return urb;
+}
+
+/*
+ * Submit the urb.  If successful the urb ends up on the devhandle's
+ * pending list, otherwise, it's back on our free list.
+ */
+bool
+fusb_ephandle_linux::submit_urb (usbdevfs_urb *urb)
+{
+  if (!d_devhandle->_submit_urb (urb)){    // FIXME record the problem somewhere
+    fprintf (stderr, "_submit_urb failed\n");
+    free_list_add (urb);
+    return false;
+  }
+  return true;
+}
diff --git a/usrp/host/lib/fusb_linux.h b/usrp/host/lib/fusb_linux.h
new file mode 100644 (file)
index 0000000..107e1af
--- /dev/null
@@ -0,0 +1,116 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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.
+ */
+
+// Fast USB interface
+
+#ifndef _FUSB_LINUX_H_
+#define _FUSB_LINUX_H_
+
+#include <fusb.h>
+#include <list>
+
+struct  usbdevfs_urb;
+class   fusb_ephandle_linux;
+
+/*!
+ * \brief linux specific implementation of fusb_devhandle using usbdevice_fs
+ */
+class fusb_devhandle_linux : public fusb_devhandle {
+private:
+  std::list<usbdevfs_urb*>      d_pending_rqsts;
+
+  void pending_add (usbdevfs_urb *urb);
+  bool pending_remove (usbdevfs_urb *urb);
+  usbdevfs_urb * pending_get ();
+
+
+public:
+  // CREATORS
+  fusb_devhandle_linux (usb_dev_handle *udh);
+  virtual ~fusb_devhandle_linux ();
+
+  // MANIPULATORS
+  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
+                                       int block_size = 0, int nblocks = 0);
+
+  // internal use only
+  bool _submit_urb (usbdevfs_urb *urb);
+  bool _cancel_urb (usbdevfs_urb *urb);
+  void _cancel_pending_rqsts (fusb_ephandle_linux *eph);
+  bool _reap (bool ok_to_block_p);
+  void _wait_for_completion ();
+};
+
+\f/*!
+ * \brief linux specific implementation of fusb_ephandle using usbdevice_fs
+ */
+
+class fusb_ephandle_linux : public fusb_ephandle {
+private:
+  fusb_devhandle_linux        *d_devhandle;
+  std::list<usbdevfs_urb*>     d_free_list;
+  std::list<usbdevfs_urb*>     d_completed_list;
+  usbdevfs_urb                *d_write_work_in_progress;
+  unsigned char                       *d_write_buffer;
+  usbdevfs_urb                *d_read_work_in_progress;
+  unsigned char                       *d_read_buffer;
+  unsigned char                       *d_read_buffer_end;
+
+  usbdevfs_urb *get_write_work_in_progress ();
+  void reap_complete_writes ();
+  bool reload_read_buffer ();
+  bool submit_urb (usbdevfs_urb *urb);
+  
+public:
+  fusb_ephandle_linux (fusb_devhandle_linux *dh, int endpoint, bool input_p,
+                      int block_size = 0, int nblocks = 0);
+  virtual ~fusb_ephandle_linux ();
+
+  virtual bool start ();       //!< begin streaming i/o
+  virtual bool stop ();                //!< stop streaming i/o
+
+  /*!
+   * \returns \p nbytes if write was successfully enqueued, else -1.
+   * Will block if no free buffers available.
+   */
+  virtual int write (const void *buffer, int nbytes);
+
+  /*!
+   * \returns number of bytes read or -1 if error.
+   * number of bytes read will be <= nbytes.
+   * Will block if no input available.
+   */
+  virtual int read (void *buffer, int nbytes);
+
+  /*
+   * block until all outstanding writes have completed
+   */
+  virtual void wait_for_completion ();
+
+  // internal use only
+  void free_list_add (usbdevfs_urb *urb);
+  void completed_list_add (usbdevfs_urb *urb);
+  usbdevfs_urb *free_list_get ();              // pop and return head of list or 0
+  usbdevfs_urb *completed_list_get ();         // pop and return head of list or 0
+};
+
+#endif /* _FUSB_LINUX_H_ */
diff --git a/usrp/host/lib/fusb_ra_wb.cc b/usrp/host/lib/fusb_ra_wb.cc
new file mode 100644 (file)
index 0000000..699a34b
--- /dev/null
@@ -0,0 +1,258 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <fusb_ra_wb.h>
+#include <usb.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include <sys/event.h>
+#include <dev/usb/usb.h>
+
+static const int USB_TIMEOUT = 1000;   // in milliseconds
+
+// the following comment and function is from fusb_linux.cc
+#if 0
+// Totally evil and fragile extraction of file descriptor from
+// guts of libusb.  They don't install usbi.h, which is what we'd need
+// to do this nicely.
+//
+// FIXME if everything breaks someday in the future, look here...
+
+static int
+fd_from_usb_dev_handle (usb_dev_handle *udh)
+{
+  return *((int *) udh);
+}
+#endif
+
+// the control endpoint doesn't actually do us any good so here is a
+// new "fragile extraction"
+static int
+ep_fd_from_usb_dev_handle (usb_dev_handle *udh, int endpoint)
+{
+  struct usb_dev_handle_kludge2 { // see also usrp_prims.cc
+    int                         fd;
+    struct usb_bus     *bus;
+    struct usb_device  *device;
+    int                         config;
+    int                         interface;
+    int                         altsetting;
+    void               *impl_info;
+  };
+  struct bsd_usb_dev_handle_info_kludge {
+    int                         ep_fd[USB_MAX_ENDPOINTS];
+  };
+  struct bsd_usb_dev_handle_info_kludge *info
+      = (struct bsd_usb_dev_handle_info_kludge *)
+           ((struct usb_dev_handle_kludge2 *)udh)->impl_info;
+  return info->ep_fd[UE_GET_ADDR(endpoint)];
+}
+
+
+fusb_devhandle_ra_wb::fusb_devhandle_ra_wb (usb_dev_handle *udh)
+  : fusb_devhandle (udh)
+{
+  // that's it
+}
+
+fusb_devhandle_ra_wb::~fusb_devhandle_ra_wb ()
+{
+  // nop
+}
+
+fusb_ephandle *
+fusb_devhandle_ra_wb::make_ephandle (int endpoint, bool input_p,
+                                    int block_size, int nblocks)
+{
+  return new fusb_ephandle_ra_wb (this, endpoint, input_p,
+                                 block_size, nblocks);
+}
+
+// ----------------------------------------------------------------
+
+fusb_ephandle_ra_wb::fusb_ephandle_ra_wb (fusb_devhandle_ra_wb *dh,
+                                         int endpoint, bool input_p,
+                                         int block_size, int nblocks)
+  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
+    d_devhandle (dh), d_ra_wb_on (false)
+{
+  // that's it 
+}
+
+fusb_ephandle_ra_wb::~fusb_ephandle_ra_wb ()
+{
+  // nop
+}
+
+bool
+fusb_ephandle_ra_wb::start ()
+{
+  d_started = true;
+
+  char buf = '\0';
+  int fd;
+
+  // this is to cause libusb to open the endpoint
+  if (!d_input_p) {
+    write(&buf, 0);
+    fd = ep_fd_from_usb_dev_handle (d_devhandle->get_usb_dev_handle(),
+                                   d_endpoint);
+  }
+  else {
+    read(&buf, 0);
+    fd = ep_fd_from_usb_dev_handle (d_devhandle->get_usb_dev_handle(),
+                                   d_endpoint|USB_ENDPOINT_IN);
+  }
+
+  // enable read ahead/write behind
+  int ret;
+  struct usb_bulk_ra_wb_opt opts;
+  int enable = 1;
+
+  opts.ra_wb_buffer_size = d_block_size*d_nblocks;
+  opts.ra_wb_request_size = d_block_size;
+//  fprintf (stderr, "setting buffer size to %d, request size to %d\n",
+//        opts.ra_wb_buffer_size, opts.ra_wb_request_size);
+  if (!d_input_p) {
+    ret = ioctl (fd, USB_SET_BULK_WB_OPT, &opts);
+    if (ret < 0)
+      fprintf (stderr, "USB_SET_BULK_WB_OPT: %s\n", strerror(errno));
+    else {
+      ret = ioctl (fd, USB_SET_BULK_WB, &enable);
+      if (ret < 0)
+       fprintf (stderr, "USB_SET_BULK_WB: %s\n", strerror(errno));
+      else
+       d_ra_wb_on = true;
+    }
+  }
+  else {
+    ret = ioctl (fd, USB_SET_BULK_RA_OPT, &opts);
+    if (ret < 0)
+      fprintf (stderr, "USB_SET_BULK_RA_OPT: %s\n", strerror(errno));
+    else {
+      ret = ioctl (fd, USB_SET_BULK_RA, &enable);
+      if (ret < 0)
+       fprintf (stderr, "USB_SET_BULK_RA: %s\n", strerror(errno));
+      else
+       d_ra_wb_on = true;
+    }
+  }
+
+  return true;
+}
+
+bool
+fusb_ephandle_ra_wb::stop ()
+{
+  int fd;
+  int ret;
+  int enable = 0;
+  if (d_ra_wb_on) {
+    if (!d_input_p) {
+      fd = ep_fd_from_usb_dev_handle (d_devhandle->get_usb_dev_handle(),
+                                     d_endpoint);
+      ret = ioctl (fd, USB_SET_BULK_WB, &enable);
+      if (ret < 0)
+       fprintf (stderr, "USB_SET_BULK_WB: %s\n", strerror(errno));
+      else
+       d_ra_wb_on = false;
+    }
+    else {
+      fd = ep_fd_from_usb_dev_handle (d_devhandle->get_usb_dev_handle(),
+                                     d_endpoint|USB_ENDPOINT_IN);
+      ret = ioctl (fd, USB_SET_BULK_RA, &enable);
+      if (ret < 0)
+       fprintf (stderr, "USB_SET_BULK_RA: %s\n", strerror(errno));
+      else
+       d_ra_wb_on = false;
+    }
+  }
+
+  d_started = false;
+  return true;
+}
+
+int
+fusb_ephandle_ra_wb::write (const void *buffer, int nbytes)
+{
+  if (!d_started)
+    return -1;
+  
+  if (d_input_p)
+    return -1;
+  
+  return usb_bulk_write (d_devhandle->get_usb_dev_handle (),
+                        d_endpoint, (char *) buffer, nbytes, USB_TIMEOUT);
+}
+
+int
+fusb_ephandle_ra_wb::read (void *buffer, int nbytes)
+{
+  if (!d_started)
+    return -1;
+
+  if (!d_input_p)
+    return -1;
+
+  return usb_bulk_read (d_devhandle->get_usb_dev_handle (),
+                       d_endpoint|USB_ENDPOINT_IN, (char *) buffer, nbytes,
+                       USB_TIMEOUT);
+}
+
+void
+fusb_ephandle_ra_wb::wait_for_completion ()
+{
+  // as the driver is implemented this only makes sense for write 
+  if (d_ra_wb_on && !d_input_p) {
+    int fd = ep_fd_from_usb_dev_handle (d_devhandle->get_usb_dev_handle(),
+                                       d_endpoint);
+    int kq = kqueue();
+    if (kq < 0)
+      return;
+    struct kevent evt;
+    int nevents;
+    EV_SET (&evt, fd, EVFILT_WRITE, EV_ADD | EV_ENABLE, 0, 0, 0/*NULL*/);
+    nevents = kevent (kq, &evt, 1, &evt, 1, NULL);
+    if (nevents < 1) {
+      close(kq);
+      return;
+    }
+    while (!(evt.flags & EV_ERROR) && evt.data < (d_block_size*d_nblocks)) {
+      // it's a busy loop, but that's all I can do at the moment
+      nevents = kevent (kq, NULL, 0, &evt, 1, NULL);
+      // let's see if this improves the test_usrp_standard_tx throughput &
+      // "CPU usage" by looping less frequently
+      struct timeval timeout;
+      timeout.tv_sec = 0;
+      timeout.tv_usec = 1000; // 1 ms
+      select (0, NULL, NULL, NULL, &timeout);
+    }
+    close (kq);
+  }
+}
diff --git a/usrp/host/lib/fusb_ra_wb.h b/usrp/host/lib/fusb_ra_wb.h
new file mode 100644 (file)
index 0000000..233976a
--- /dev/null
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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 _FUSB_RA_WB_H_
+#define _FUSB_RA_WB_H_
+
+#include <fusb.h>
+
+/*!
+ * \brief generic implementation of fusb_devhandle using only libusb
+ */
+class fusb_devhandle_ra_wb : public fusb_devhandle
+{
+public:
+  // CREATORS
+  fusb_devhandle_ra_wb (usb_dev_handle *udh);
+  virtual ~fusb_devhandle_ra_wb ();
+
+  // MANIPULATORS
+  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
+                                       int block_size = 0, int nblocks = 0);
+};
+
+
+/*!
+ * \brief generic implementation of fusb_ephandle using only libusb
+ */
+class fusb_ephandle_ra_wb : public fusb_ephandle
+{
+private:
+  fusb_devhandle_ra_wb *d_devhandle;
+  bool d_ra_wb_on;
+  
+public:
+  // CREATORS
+  fusb_ephandle_ra_wb (fusb_devhandle_ra_wb *dh, int endpoint, bool input_p,
+                      int block_size = 0, int nblocks = 0);
+  virtual ~fusb_ephandle_ra_wb ();
+
+  // MANIPULATORS
+
+  virtual bool start ();       //!< begin streaming i/o
+  virtual bool stop ();                //!< stop streaming i/o
+
+  /*!
+   * \returns \p nbytes if write was successfully enqueued, else -1.
+   * Will block if no free buffers available.
+   */
+  virtual int write (const void *buffer, int nbytes);
+
+  /*!
+   * \returns number of bytes read or -1 if error.
+   * number of bytes read will be <= nbytes.
+   * Will block if no input available.
+   */
+  virtual int read (void *buffer, int nbytes);
+
+  /*
+   * block until all outstanding writes have completed
+   */
+  virtual void wait_for_completion ();
+};
+
+#endif /* _FUSB_RA_WB_H_ */
+
diff --git a/usrp/host/lib/fusb_sysconfig_darwin.cc b/usrp/host/lib/fusb_sysconfig_darwin.cc
new file mode 100644 (file)
index 0000000..4d19d12
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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 <fusb.h>
+#include <fusb_darwin.h>
+
+static const int MAX_BLOCK_SIZE = 32 * 1024;           // hard limit
+static const int FUSB_BUFFER_SIZE = 2 * (1L << 20);    // 2 MB
+
+fusb_devhandle *
+fusb_sysconfig::make_devhandle (usb_dev_handle *udh)
+{
+  return new fusb_devhandle_darwin (udh);
+}
+
+int fusb_sysconfig::max_block_size ()
+{
+  return MAX_BLOCK_SIZE;
+}
+
+int fusb_sysconfig::default_block_size ()
+{
+  return fusb_sysconfig::max_block_size ();
+}
+
+int fusb_sysconfig::default_buffer_size ()
+{
+  return FUSB_BUFFER_SIZE;
+}
+
diff --git a/usrp/host/lib/fusb_sysconfig_generic.cc b/usrp/host/lib/fusb_sysconfig_generic.cc
new file mode 100644 (file)
index 0000000..58baba5
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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 <fusb.h>
+#include <fusb_generic.h>
+
+static const int MAX_BLOCK_SIZE = 16 * 1024;           // hard limit
+static const int FUSB_BUFFER_SIZE = 2 * (1L << 20);    // 2 MB
+
+fusb_devhandle *
+fusb_sysconfig::make_devhandle (usb_dev_handle *udh)
+{
+  return new fusb_devhandle_generic (udh);
+}
+       
+int fusb_sysconfig::max_block_size ()
+{
+  return MAX_BLOCK_SIZE;
+}
+
+int fusb_sysconfig::default_block_size ()
+{
+  return fusb_sysconfig::max_block_size ();
+}
+
+int fusb_sysconfig::default_buffer_size ()
+{
+  return FUSB_BUFFER_SIZE;
+}
diff --git a/usrp/host/lib/fusb_sysconfig_linux.cc b/usrp/host/lib/fusb_sysconfig_linux.cc
new file mode 100644 (file)
index 0000000..3c2f593
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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 <fusb.h>
+#include <fusb_linux.h>
+
+static const int MAX_BLOCK_SIZE     =  16 * 1024;      // hard limit
+static const int DEFAULT_BLOCK_SIZE =   4 * 1024;      // fewer kernel memory problems
+static const int FUSB_BUFFER_SIZE   =   1 * (1L << 20); // 1MB
+
+fusb_devhandle *
+fusb_sysconfig::make_devhandle (usb_dev_handle *udh)
+{
+  return new fusb_devhandle_linux (udh);
+}
+
+int fusb_sysconfig::max_block_size ()
+{
+  return MAX_BLOCK_SIZE;
+}
+
+int fusb_sysconfig::default_block_size ()
+{
+  return DEFAULT_BLOCK_SIZE;
+}
+
+int fusb_sysconfig::default_buffer_size ()
+{
+  return FUSB_BUFFER_SIZE;
+}
diff --git a/usrp/host/lib/fusb_sysconfig_ra_wb.cc b/usrp/host/lib/fusb_sysconfig_ra_wb.cc
new file mode 100644 (file)
index 0000000..9da831f
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#include <fusb.h>
+#include <fusb_ra_wb.h>
+
+//static const int MAX_BLOCK_SIZE = 16 * 1024;         // hard limit
+// there's no hard limit, even before making any changes to the driver
+// 64k is empirically a pretty good number
+static const int MAX_BLOCK_SIZE = 64 * 1024;
+// there is a limit of 1 MB in the driver for the buffer size
+static const int FUSB_BUFFER_SIZE = 256 * (1L << 10);  // 256 kB
+
+fusb_devhandle *
+fusb_sysconfig::make_devhandle (usb_dev_handle *udh)
+{
+  return new fusb_devhandle_ra_wb (udh);
+}
+       
+int fusb_sysconfig::max_block_size ()
+{
+  return MAX_BLOCK_SIZE;
+}
+
+int fusb_sysconfig::default_block_size ()
+{
+  return fusb_sysconfig::max_block_size ();
+}
+
+int fusb_sysconfig::default_buffer_size ()
+{
+  return FUSB_BUFFER_SIZE;
+}
diff --git a/usrp/host/lib/fusb_sysconfig_win32.cc b/usrp/host/lib/fusb_sysconfig_win32.cc
new file mode 100644 (file)
index 0000000..16eaaa6
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#include <fusb.h>
+#include <fusb_win32.h>
+
+static const int MAX_BLOCK_SIZE = 64 * 1024;           // Windows kernel hard limit
+static const int FUSB_BUFFER_SIZE = 2 * (1L << 20);    // 2 MB
+       
+fusb_devhandle *
+fusb_sysconfig::make_devhandle (usb_dev_handle *udh)
+{
+  return new fusb_devhandle_win32 (udh);
+}
+
+int fusb_sysconfig::max_block_size ()
+{
+  return MAX_BLOCK_SIZE;
+}
+
+int fusb_sysconfig::default_block_size ()
+{
+  return fusb_sysconfig::max_block_size ();
+}
+
+int fusb_sysconfig::default_buffer_size ()
+{
+  return FUSB_BUFFER_SIZE;
+}
diff --git a/usrp/host/lib/fusb_win32.cc b/usrp/host/lib/fusb_win32.cc
new file mode 100644 (file)
index 0000000..8900576
--- /dev/null
@@ -0,0 +1,266 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <fusb_win32.h>
+#include <usb.h>
+#include <assert.h>
+#include <stdexcept>
+#include <string.h>
+
+static const int MAX_BLOCK_SIZE = fusb_sysconfig::max_block_size();
+static const int DEFAULT_BLOCK_SIZE = MAX_BLOCK_SIZE;
+static const int DEFAULT_BUFFER_SIZE = 16 * (1L << 20);                // 16 MB / endpoint
+
+
+static const int USB_TIMEOUT = 1000;   // in milliseconds
+
+
+fusb_devhandle_win32::fusb_devhandle_win32 (usb_dev_handle *udh)
+  : fusb_devhandle (udh)
+{
+  // that's it
+}
+
+fusb_devhandle_win32::~fusb_devhandle_win32 ()
+{
+  // nop
+}
+
+fusb_ephandle *
+fusb_devhandle_win32::make_ephandle (int endpoint, bool input_p,
+                                      int block_size, int nblocks)
+{
+  return new fusb_ephandle_win32 (this, endpoint, input_p,
+                                   block_size, nblocks);
+}
+
+// ----------------------------------------------------------------
+
+fusb_ephandle_win32::fusb_ephandle_win32 (fusb_devhandle_win32 *dh,
+                                             int endpoint, bool input_p,
+                                             int block_size, int nblocks)
+  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
+    d_devhandle (dh), d_input_leftover(0),d_output_short(0)
+{
+  if (d_block_size < 0 || d_block_size > MAX_BLOCK_SIZE)
+    throw std::out_of_range ("fusb_ephandle_win32: block_size");
+
+  if (d_nblocks < 0)
+    throw std::out_of_range ("fusb_ephandle_win32: nblocks");
+
+  if (d_block_size == 0)
+    d_block_size = DEFAULT_BLOCK_SIZE;
+
+  if (d_nblocks == 0)
+    d_nblocks = std::max (1, DEFAULT_BUFFER_SIZE / d_block_size);
+
+  d_buffer = new char [d_block_size*d_nblocks];
+  d_context = new void * [d_nblocks];
+
+  // allocate contexts
+
+  usb_dev_handle *dev = dh->get_usb_dev_handle ();
+  int i;
+
+  if (d_input_p)
+    endpoint |= USB_ENDPOINT_IN;
+
+  for (i=0; i<d_nblocks; i++)
+    usb_bulk_setup_async(dev, &d_context[i], endpoint);
+}
+
+fusb_ephandle_win32::~fusb_ephandle_win32 ()
+{
+  int i;
+
+  stop ();
+
+  for (i=0; i<d_nblocks; i++)
+    usb_free_async(&d_context[i]);
+
+  delete [] d_buffer;
+  delete [] d_context;
+}
+
+bool
+fusb_ephandle_win32::start ()
+{
+  if (d_started)
+    return true;       // already running
+
+  d_started = true;
+
+  d_curr = d_nblocks-1;
+  d_outstanding_write = 0;
+  d_input_leftover =0;
+  d_output_short = 0;
+
+  if (d_input_p){      // fire off all the reads
+    int i;
+
+    for (i=0; i<d_nblocks; i++) {
+      usb_submit_async(d_context[i], (char * ) d_buffer+i*d_block_size,
+                     d_block_size);
+    }
+  }
+
+  return true;
+}
+
+bool
+fusb_ephandle_win32::stop ()
+{
+  if (!d_started)
+    return true;
+
+  if (!d_input_p)
+    wait_for_completion ();
+
+  d_started = false;
+  return true;
+}
+
+int
+fusb_ephandle_win32::write (const void *buffer, int nbytes)
+{
+  int retval=0;
+  char *buf;
+
+  if (!d_started)      // doesn't matter here, but keeps semantics constant
+    return -1;
+
+  if (d_input_p)
+    return -1;
+
+  int bytes_to_write = nbytes;
+  int a=0;
+
+  if (d_output_short != 0) {
+
+       buf = &d_buffer[d_curr*d_block_size + d_block_size - d_output_short];
+       a = std::min(nbytes, d_output_short);
+       memcpy(buf, buffer, a);
+       bytes_to_write -= a;
+       d_output_short -= a;
+
+    if (d_output_short == 0)
+        usb_submit_async(d_context[d_curr],
+                        &d_buffer[d_curr*d_block_size], d_block_size);
+  }
+
+  while (bytes_to_write > 0) {
+    d_curr = (d_curr+1)%d_nblocks;
+    buf = &d_buffer[d_curr*d_block_size];
+
+    if (d_outstanding_write != d_nblocks) {
+      d_outstanding_write++;
+    } else {
+      retval = usb_reap_async(d_context[d_curr], USB_TIMEOUT);
+      if (retval < 0) {
+                 fprintf(stderr, "%s: usb_reap_async: %s\n",
+                         __FUNCTION__, usb_strerror());
+         return retval;
+       }
+    }
+
+    int ncopy = std::min(bytes_to_write, d_block_size);
+    memcpy(buf, (void *) &(((char*)buffer)[a]), ncopy);
+    bytes_to_write -= ncopy;
+    a += ncopy;
+
+    d_output_short = d_block_size - ncopy;
+    if (d_output_short == 0)
+           usb_submit_async(d_context[d_curr], buf, d_block_size);
+  }
+
+  return retval < 0 ? retval : nbytes;
+}
+
+int
+fusb_ephandle_win32::read (void *buffer, int nbytes)
+{
+  int retval=0;
+  char *buf;
+
+  if (!d_started)      // doesn't matter here, but keeps semantics constant
+    return -1;
+
+  if (!d_input_p)
+    return -1;
+
+  int bytes_to_read = nbytes;
+
+  int a=0;
+  if (d_input_leftover != 0) {
+
+       buf = &d_buffer[d_curr*d_block_size + d_block_size - d_input_leftover];
+       a = std::min(nbytes, d_input_leftover);
+       memcpy(buffer, buf, a);
+       bytes_to_read -= a;
+       d_input_leftover -= a;
+
+    if (d_input_leftover == 0)
+        usb_submit_async(d_context[d_curr],
+                        &d_buffer[d_curr*d_block_size], d_block_size);
+  }
+
+  while (bytes_to_read > 0) {
+
+    d_curr = (d_curr+1)%d_nblocks;
+    buf = &d_buffer[d_curr*d_block_size];
+
+    retval = usb_reap_async(d_context[d_curr], USB_TIMEOUT);
+    if (retval < 0)
+         fprintf(stderr, "%s: usb_reap_async: %s\n",
+                         __FUNCTION__, usb_strerror());
+
+    int ncopy = std::min(bytes_to_read, d_block_size);
+    memcpy((void *) &(((char*)buffer)[a]), buf, ncopy);
+    bytes_to_read -= ncopy;
+    a += ncopy;
+
+    d_input_leftover = d_block_size - ncopy;
+    if (d_input_leftover == 0)
+           usb_submit_async(d_context[d_curr], buf, d_block_size);
+  }
+
+  return retval < 0 ? retval : nbytes;
+}
+
+void
+fusb_ephandle_win32::wait_for_completion ()
+{
+  int i;
+
+  for (i=0; i<d_outstanding_write; i++) {
+    int context_num;
+
+    context_num = (d_curr+d_outstanding_write+i+1)%d_nblocks;
+    usb_reap_async(d_context[context_num], USB_TIMEOUT);
+  }
+
+  d_outstanding_write = 0;
+}
diff --git a/usrp/host/lib/fusb_win32.h b/usrp/host/lib/fusb_win32.h
new file mode 100644 (file)
index 0000000..3ad2132
--- /dev/null
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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 _FUSB_WIN32_H_
+#define _FUSB_WIN32_H_
+
+#include <fusb.h>
+
+/*!
+ * \brief win32 implementation of fusb_devhandle using libusb-win32
+ */
+class fusb_devhandle_win32 : public fusb_devhandle
+{
+public:
+  // CREATORS
+  fusb_devhandle_win32 (usb_dev_handle *udh);
+  virtual ~fusb_devhandle_win32 ();
+
+  // MANIPULATORS
+  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
+                                       int block_size = 0, int nblocks = 0);
+};
+
+
+/*!
+ * \brief win32 implementation of fusb_ephandle using libusb-win32
+ */
+class fusb_ephandle_win32 : public fusb_ephandle
+{
+private:
+  fusb_devhandle_win32 *d_devhandle;
+
+  unsigned d_curr;
+  unsigned d_outstanding_write;
+  int d_output_short;
+  int d_input_leftover;
+  void ** d_context;
+  char * d_buffer;
+
+public:
+  // CREATORS
+  fusb_ephandle_win32 (fusb_devhandle_win32 *dh, int endpoint, bool input_p,
+                        int block_size = 0, int nblocks = 0);
+  virtual ~fusb_ephandle_win32 ();
+
+  // MANIPULATORS
+
+  virtual bool start ();       //!< begin streaming i/o
+  virtual bool stop ();                //!< stop streaming i/o
+
+  /*!
+   * \returns \p nbytes if write was successfully enqueued, else -1.
+   * Will block if no free buffers available.
+   */
+  virtual int write (const void *buffer, int nbytes);
+
+  /*!
+   * \returns number of bytes read or -1 if error.
+   * number of bytes read will be <= nbytes.
+   * Will block if no input available.
+   */
+  virtual int read (void *buffer, int nbytes);
+
+  /*
+   * block until all outstanding writes have completed
+   */
+  virtual void wait_for_completion ();
+};
+
+#endif /* _FUSB_WIN32_H_ */
+
diff --git a/usrp/host/lib/gen_usrp_dbid.py b/usrp/host/lib/gen_usrp_dbid.py
new file mode 100755 (executable)
index 0000000..c7d3770
--- /dev/null
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+
+import sys
+import os
+import os.path
+import re
+from optparse import OptionParser
+
+def write_header(f, comment_char):
+    f.write(comment_char); f.write('\n')
+    f.write(comment_char); f.write(' Machine generated by gen_usrp_dbid.py from usrp_dbid.dat\n')
+    f.write(comment_char); f.write(' Do not edit by hand.  All edits will be overwritten.\n')
+    f.write(comment_char); f.write('\n')
+    f.write('\n')
+
+def gen_dbid_py(r):
+    f = open('usrp_dbid.py', 'w')
+    comment_char = '#'
+    write_header(f, comment_char)
+    f.write(comment_char); f.write('\n')
+    f.write(comment_char); f.write(" USRP Daughterboard ID's\n")
+    f.write(comment_char); f.write('\n')
+    f.write('\n')
+    for x in r:
+        f.write('%-16s = %s\n' % (x[1], x[2]))
+
+def gen_dbid_h(r):
+    f = open('../include/usrp/usrp_dbid.h', 'w')
+    comment_char = '//'
+    write_header(f, comment_char)
+    f.write(comment_char); f.write('\n')
+    f.write(comment_char); f.write(" USRP Daughterboard ID's\n")
+    f.write(comment_char); f.write('\n')
+    f.write('\n')
+    f.write('#ifndef INCLUDED_USRP_DBID_H\n')
+    f.write('#define INCLUDED_USRP_DBID_H\n')
+    f.write('\n')
+    for x in r:
+        f.write('#define %-25s %s\n' % ('USRP_DBID_' + x[1], x[2]))
+    f.write('\n')
+    f.write('#endif /* INCLUDED_USRP_DBID_H */\n')
+
+def gen_dbid_cc(r):
+    f = open('usrp_dbid.cc', 'w')
+    write_header(f, '//')
+    head = '''/*
+ * 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.
+ */
+
+#include <usrp/usrp_prims.h>
+#include <usrp/usrp_dbid.h>
+#include <stdio.h>
+
+#define NELEM(x) sizeof(x)/sizeof(x[0])
+
+static struct {
+  unsigned short       dbid;
+  const char          *name;
+} dbid_map[] = {
+'''
+    
+    tail = '''};
+
+const std::string
+usrp_dbid_to_string (int dbid)
+{
+  if (dbid == -1)
+    return "<none>";
+
+  if (dbid == -2)
+    return "<invalid EEPROM contents>";
+
+  for (unsigned i = 0; i < NELEM (dbid_map); i++)
+    if (dbid == dbid_map[i].dbid)
+      return dbid_map[i].name;
+
+  char tmp[64];
+  snprintf (tmp, sizeof (tmp), "Unknown (0x%04x)", dbid);
+  return tmp;
+}
+'''
+    f.write(head)
+    for x in r:
+        f.write('  { %-27s "%s" },\n' % (
+            'USRP_DBID_' + x[1] + ',', x[0]))
+    f.write(tail)
+
+def gen_all(src_filename):
+    src_file = open(src_filename, 'r')
+    r = []
+    for line in src_file:
+        line = line.strip()
+        line = re.sub(r'\s*#.*$','', line)
+        if len(line) == 0:
+            continue
+        mo = re.match('"([^"]+)"\s*(0x[0-9a-fA-F]+)', line)
+        if mo:
+            str_name = mo.group(1)
+            id_name = str_name.upper().replace(' ', '_')
+            id_val = mo.group(2)
+            r.append((str_name, id_name, id_val))
+            #sys.stdout.write('%-16s\t%-16s\t%s\n' % ('"'+str_name+'"', id_name, id_val))
+
+    gen_dbid_h(r)
+    gen_dbid_py(r)
+    gen_dbid_cc(r)
+    
+
+def main():
+    usage = "usage: %prog [options] usrp_dbid.dat"
+    parser = OptionParser(usage=usage)
+    (options, args) = parser.parse_args()
+    if len(args) != 1:
+        parser.print_help()
+        sys.exit(1)
+
+    gen_all(args[0])
+
+if __name__ == '__main__':
+    main()
diff --git a/usrp/host/lib/inband/Makefile.am b/usrp/host/lib/inband/Makefile.am
deleted file mode 100644 (file)
index 650a25f..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-#
-# Copyright 2007,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.
-#
-
-include $(top_srcdir)/Makefile.common
-
-AM_CPPFLAGS =  \
-       $(DEFINES) $(OMNITHREAD_INCLUDES) $(PMT_INCLUDES) $(MBLOCK_INCLUDES) \
-       $(USRP_INCLUDES) $(BOOST_CPPFLAGS) $(CPPUNIT_INCLUDES) \
-       -I$(srcdir)/../../apps-inband $(WITH_INCLUDES)
-
-TESTS = test_inband
-
-EXTRA_DIST =                           \
-       usrp_server.mbh                 \
-       usrp_interface.mbh 
-
-lib_LTLIBRARIES =                      \
-       libusrp-inband.la               \
-       libusrp-inband-qa.la
-
-# ------------------------------------------------------------------------
-# Build the inband library
-
-BUILT_SOURCES =                                \
-       usrp_server_mbh.cc              \
-       usrp_interface_mbh.cc 
-
-usrp_server_mbh.cc : usrp_server.mbh
-       $(COMPILE_MBH) $(srcdir)/usrp_server.mbh usrp_server_mbh.cc
-
-usrp_interface_mbh.cc : usrp_interface.mbh
-       $(COMPILE_MBH) $(srcdir)/usrp_interface.mbh usrp_interface_mbh.cc
-
-libusrp_inband_la_SOURCES =            \
-       $(BUILT_SOURCES)                \
-       $(srcdir)/../../apps-inband/ui_sincos.c \
-       usrp_inband_usb_packet.cc       \
-       usrp_rx.cc                      \
-       usrp_rx_stub.cc                 \
-       usrp_server.cc                  \
-       usrp_tx.cc                      \
-       usrp_tx_stub.cc                 \
-       usrp_usb_interface.cc           
-
-libusrp_inband_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
-
-libusrp_inband_la_LIBADD =             \
-       $(MBLOCK_LA)                    \
-       $(USRP_LA)                      \
-       -lstdc++
-
-include_HEADERS =                      \
-       usrp_inband_usb_packet.h        \
-       usrp_rx.h                       \
-       usrp_rx_stub.h                  \
-       usrp_server.h                   \
-       usrp_tx.h                       \
-       usrp_tx_stub.h                  \
-       usrp_usb_interface.h
-
-noinst_HEADERS =                       \
-       qa_inband.h                     \
-       qa_inband_packet_prims.h        \
-       qa_inband_usrp_server.h         \
-       symbols_usrp_channel.h          \
-       symbols_usrp_interface_cs.h     \
-       symbols_usrp_low_level_cs.h     \
-       symbols_usrp_rx.h               \
-       symbols_usrp_rx_cs.h            \
-       symbols_usrp_server_cs.h        \
-       symbols_usrp_tx.h               \
-       symbols_usrp_tx_cs.h
-
-# ------------------------------------------------------------------------
-# Build the qa code in its own library
-
-libusrp_inband_qa_la_SOURCES =         \
-       qa_inband.cc                    \
-       qa_inband_packet_prims.cc       \
-       qa_inband_usrp_server.cc
-
-# magic flags
-libusrp_inband_qa_la_LDFLAGS = $(NO_UNDEFINED) -avoid-version
-
-libusrp_inband_qa_la_LIBADD =          \
-       libusrp-inband.la               \
-       $(PMT_LA)                       \
-       $(CPPUNIT_LIBS)                 \
-       -lstdc++
-
-# ------------------------------------------------------------------------
-
-noinst_PROGRAMS =                      \
-       test_inband
-
-test_inband_SOURCES = test_inband.cc
-test_inband_LDADD   = libusrp-inband-qa.la
diff --git a/usrp/host/lib/inband/dump_packets.py b/usrp/host/lib/inband/dump_packets.py
deleted file mode 100755 (executable)
index 2373624..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env python
-#
-# 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 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.
-#
-
-import sys
-import struct
-from optparse import OptionParser
-
-from usb_packet import *
-
-def dump_packet(raw_pkt, outfile, dump_payload):
-    pkt = usb_packet(raw_pkt)
-    outfile.write(pkt.decoded_flags())
-    outfile.write(' chan= %2d  len= %3d timestamp= 0x%08x rssi= % 2d  tag= %2d\n' % (
-        pkt.chan(), pkt.payload_len(), pkt.timestamp(), pkt.rssi(), pkt.tag()))
-    if dump_payload:
-        assert pkt.payload_len() % 4 == 0
-        shorts = struct.unpack('<%dh' % (pkt.payload_len() // 2), pkt.payload())
-        for i in range(0, len(shorts), 2):
-            outfile.write('  %6d, %6d\n' % (shorts[i], shorts[i+1]))
-        
-
-def dump_packets(infile, outfile, dump_payload):
-    raw_pkt = infile.read(512)
-    while raw_pkt:
-        if len(raw_pkt) != 512:
-            sys.stderr.write("File length is not a multiple of 512 bytes")
-            raise SystemExit, 1
-
-        dump_packet(raw_pkt, outfile, dump_payload)
-        raw_pkt = infile.read(512)
-
-
-def main():
-    parser = OptionParser()
-    parser.add_option('-p', '--dump-payload', action='store_true', default=False,
-                      help='dump payload in decimal and hex')
-
-    (options, files) = parser.parse_args()
-    if len(files) == 0:
-        dump_packets(sys.stdin, sys.stdout, options.dump_payload)
-    else:
-        for f in files:
-            dump_packets(open(f, "r"), sys.stdout, options.dump_payload)
-
-
-if __name__ == '__main__':
-    main()
diff --git a/usrp/host/lib/inband/gen_test_packets.py b/usrp/host/lib/inband/gen_test_packets.py
deleted file mode 100755 (executable)
index 2ee6463..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env python
-
-import random
-import struct
-from pprint import pprint
-from usb_packet import *
-
-MAX_PAYLOAD = 504
-TIME_NOW = 0xffffffff
-
-
-class sequence_generator(object):
-    def __init__(self):
-        self.i = 0
-    
-    def __call__(self):
-        t = self.i
-        self.i += 1
-        return t
-
-def gen_shuffled_lengths():
-    valid_lengths = range(0, MAX_PAYLOAD+1, 4)  # [0, 4, 8, ... 504]
-    random.shuffle(valid_lengths)
-    return valid_lengths
-
-
-class packet_sequence_generator(object):
-    def __init__(self, channel, lengths):
-        self.next = sequence_generator()
-        self.channel = channel
-        self.lengths = lengths
-
-    def __call__(self, output_file):
-        gen_packet(output_file, self.channel, self.next, self.lengths[0])
-        del self.lengths[0]
-
-
-def gen_packet(output_file, channel, content_generator, payload_len):
-    assert (payload_len % 4) == 0
-    payload = []
-    n_iq = payload_len // 4
-    for n in range(n_iq):
-        payload.append(content_generator())  # I
-        payload.append(content_generator())  # Q
-    for n in range(MAX_PAYLOAD // 4 - n_iq):
-        payload.append(0x0000)
-        payload.append(0xffff)
-
-    assert (len(payload) == MAX_PAYLOAD // 2)
-
-    #print "\npayload_len =", payload_len
-    #pprint(payload)
-
-    output_file.write(make_header(FL_START_OF_BURST|FL_END_OF_BURST,
-                                  channel, payload_len, TIME_NOW))
-    output_file.write(struct.pack('<252h', *payload))
-
-
-def gen_all_valid_packet_lengths_1_channel(output_file):
-    lengths = gen_shuffled_lengths()
-    npkts = len(lengths)                # number of packets we'll generator on each stream
-    pkt_gen_0 = packet_sequence_generator(0, lengths)
-    for i in range(npkts):
-        pkt_gen_0(output_file)
-    
-    assert pkt_gen_0.next() == 16002    # 2*sum(1, 2, ..., 126) == 126 * 127
-
-
-def gen_all_valid_packet_lengths_2_channels(output_file):
-    lengths = gen_shuffled_lengths()
-    npkts = len(lengths)                # number of packets we'll generator on each stream
-    pkt_gen_0 = packet_sequence_generator(0, lengths)
-    pkt_gen_1 = packet_sequence_generator(0x1f, gen_shuffled_lengths())
-    pkt_gen = (pkt_gen_0, pkt_gen_1)
-    
-    which_gen = (npkts * [0]) + (npkts * [1])
-    random.shuffle(which_gen)
-    
-    for i in which_gen:
-        pkt_gen[i](output_file)
-    
-    assert pkt_gen_0.next() == 16002    # 2*sum(1, 2, ..., 126) == 126 * 127
-    assert pkt_gen_1.next() == 16002    # 2*sum(1, 2, ..., 126) == 126 * 127
-
-if __name__ == '__main__':
-    random.seed(0)
-    gen_all_valid_packet_lengths_1_channel(open("all_valid_packet_lengths_1_channel.dat", "w"))
-    gen_all_valid_packet_lengths_2_channels(open("all_valid_packet_lengths_2_channels.dat", "w"))
diff --git a/usrp/host/lib/inband/qa_inband.cc b/usrp/host/lib/inband/qa_inband.cc
deleted file mode 100644 (file)
index 6f33a6e..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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.
- */
-
-#include <qa_inband.h>
-#include <qa_inband_packet_prims.h>
-#include <qa_inband_usrp_server.h>
-
-CppUnit::TestSuite *
-qa_inband::suite()
-{
-  CppUnit::TestSuite   *s = new CppUnit::TestSuite("inband");
-
-  s->addTest (qa_inband_packet_prims::suite());
-  s->addTest (qa_inband_usrp_server::suite());
-
-  return s;
-}
diff --git a/usrp/host/lib/inband/qa_inband.h b/usrp/host/lib/inband/qa_inband.h
deleted file mode 100644 (file)
index ab8f7f2..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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_QA_INBAND_H
-#define INCLUDED_QA_INBAND_H
-
-#include <cppunit/TestSuite.h>
-
-//! collect all the tests for the user server
-
-class qa_inband {
- public:
-  //! return suite of tests for all of usrp server
-  static CppUnit::TestSuite *suite();
-};
-
-#endif /* INCLUDED_QA_INBAND_H */
diff --git a/usrp/host/lib/inband/qa_inband_packet_prims.cc b/usrp/host/lib/inband/qa_inband_packet_prims.cc
deleted file mode 100644 (file)
index d9bbbec..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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 <qa_inband_packet_prims.h>
-#include <cppunit/TestAssert.h>
-#include <stdio.h>
-#include <string.h>
-#include <usrp_inband_usb_packet.h>             // will change on gigabit crossover
-
-typedef usrp_inband_usb_packet transport_pkt;
-
-void
-qa_inband_packet_prims::test_flags()
-{
-  transport_pkt pkt;
-
-  // Test each one of the flags while ensuring no other fields become set in the process
-  pkt.set_header(pkt.FL_START_OF_BURST,0,0,0);
-  CPPUNIT_ASSERT_EQUAL(1, pkt.start_of_burst());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.overrun());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.underrun());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.dropped());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
-
-  pkt.set_header(pkt.FL_END_OF_BURST,0,0,0);
-  CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst());
-  CPPUNIT_ASSERT_EQUAL(1, pkt.end_of_burst());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.overrun());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.underrun());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.dropped());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
-
-  pkt.set_header(pkt.FL_OVERRUN,0,0,0);
-  CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst());
-  CPPUNIT_ASSERT_EQUAL(1, pkt.overrun());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.underrun());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.dropped());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
-
-  pkt.set_header(pkt.FL_UNDERRUN,0,0,0);
-  CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.overrun());
-  CPPUNIT_ASSERT_EQUAL(1, pkt.underrun());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.dropped());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
-
-  pkt.set_header(pkt.FL_DROPPED,0,0,0);
-  CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.overrun());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.underrun());
-  CPPUNIT_ASSERT_EQUAL(1, pkt.dropped());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
-
-  // test of all fields set
-  pkt.set_header(
-    pkt.FL_START_OF_BURST |
-    pkt.FL_END_OF_BURST |
-    pkt.FL_UNDERRUN |
-    pkt.FL_OVERRUN |
-    pkt.FL_DROPPED 
-    ,0,0,0);
-  CPPUNIT_ASSERT_EQUAL(1, pkt.start_of_burst());
-  CPPUNIT_ASSERT_EQUAL(1, pkt.end_of_burst());
-  CPPUNIT_ASSERT_EQUAL(1, pkt.overrun());
-  CPPUNIT_ASSERT_EQUAL(1, pkt.underrun());
-  CPPUNIT_ASSERT_EQUAL(1, pkt.dropped());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
-
-
-}
-//////////////////////////////////////////////////////////////////////
-
-void
-qa_inband_packet_prims::test_fields()
-{
-  transport_pkt pkt;
-  void * payload;
-  
-  // test word0 field exclusiveness
-  //
-  // I want to test max values of each field to ensure field boundaries
-  // but these max values could change based on technology?  The
-  // max payload is returned by a private method so the code is not
-  // technology dependent
-  pkt.set_header(0,16,0,0);
-  CPPUNIT_ASSERT_EQUAL(16, pkt.chan());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
-
-  pkt.set_header(0,0,8,0);
-  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
-  CPPUNIT_ASSERT_EQUAL(8, pkt.tag());
-  CPPUNIT_ASSERT_EQUAL(0,pkt.payload_len());
-
-  pkt.set_header(0,0,0,pkt.max_payload());  
-  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
-  CPPUNIT_ASSERT_EQUAL(pkt.max_payload(), pkt.payload_len());
-
-  // test timestamp, shouldn't have to test other fields since
-  // setting the timestamp only has the ability to affect one word
-  pkt.set_timestamp(54);
-  CPPUNIT_ASSERT_EQUAL(uint32_t(54), pkt.timestamp());
-
-  // test the payload, ensure no other fields overwritten
-  //
-  // is there a better test for this?
-  pkt.set_header(0,0,0,0);
-  payload = malloc(pkt.payload_len());
-  memset(payload, 'f', pkt.payload_len());
-  memcpy(pkt.payload(), payload, pkt.payload_len());
-  CPPUNIT_ASSERT_EQUAL(0, memcmp(pkt.payload(), payload, pkt.payload_len()));
-  CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.overrun());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.underrun());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.dropped());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
-  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
-  free(payload);
-
-}
-//////////////////////////////////////////////////////////////////////
diff --git a/usrp/host/lib/inband/qa_inband_packet_prims.h b/usrp/host/lib/inband/qa_inband_packet_prims.h
deleted file mode 100644 (file)
index 71c0d73..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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 QA_INBAND_PACKET_PRIMS_H
-#define QA_INBAND_PACKET_PRIMS_H
-
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/TestCase.h>
-
-class qa_inband_packet_prims : public CppUnit::TestCase {
-
-  CPPUNIT_TEST_SUITE(qa_inband_packet_prims);
-  CPPUNIT_TEST(test_flags);
-  CPPUNIT_TEST(test_fields);
-  CPPUNIT_TEST_SUITE_END();
-
- private:
-  void test_flags();
-  void test_fields();
-
-};
-
-#endif /* INCLUDED_QA_INBAND_PACKET_PRIMS_H */
diff --git a/usrp/host/lib/inband/qa_inband_usrp_server.cc b/usrp/host/lib/inband/qa_inband_usrp_server.cc
deleted file mode 100644 (file)
index 6049a8a..0000000
+++ /dev/null
@@ -1,1575 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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_inband_usb_packet.h>
-#include <qa_inband_usrp_server.h>
-#include <cppunit/TestAssert.h>
-#include <stdio.h>
-#include <usrp_server.h>
-#include <mblock/mblock.h>
-#include <mblock/runtime.h>
-#include <mblock/protocol_class.h>
-#include <mblock/class_registry.h>
-#include <vector>
-#include <iostream>
-#include <pmt.h>
-
-#include <symbols_usrp_server_cs.h>
-#include <symbols_usrp_tx.h>
-#include <symbols_usrp_rx.h>
-#include <symbols_usrp_channel.h>
-#include <symbols_usrp_low_level_cs.h>
-
-typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit easy
-
-static bool verbose = false;
-
-static pmt_t s_timeout = pmt_intern("%timeout");
-
-// ----------------------------------------------------------------------------------------------
-
-class qa_alloc_top : public mb_mblock
-{
-  mb_port_sptr d_tx;
-  mb_port_sptr d_rx;
-  mb_port_sptr d_cs;
-
-  long d_nmsgs_to_recv;
-  long d_nrecvd;
-
-  long d_max_capacity;
-  long d_ntx_chan, d_nrx_chan;
-
-  long d_nstatus;
-  long d_nstatus_to_recv;
-
- public:
-  qa_alloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~qa_alloc_top();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void check_message(mb_message_sptr msg);
-  void run_tests();
-};
-
-qa_alloc_top::qa_alloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg)
-{ 
-  d_nrecvd=0;
-  d_nmsgs_to_recv = 6;
-  d_nstatus=0;
-  d_nstatus_to_recv = 50;
-  
-  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
-  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-  // Use the stub with the usrp_server
-  pmt_t usrp_server_dict = pmt_make_dict();
-  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
-
-  // Test the TX side
-  define_component("server", "usrp_server", usrp_server_dict);
-  connect("self", "tx0", "server", "tx0");
-  connect("self", "rx0", "server", "rx0");
-  connect("self", "cs", "server", "cs");
-
-}
-
-qa_alloc_top::~qa_alloc_top(){}
-
-void
-qa_alloc_top::initial_transition()
-{
-  // Allocations should fail before open
-  d_tx->send(s_cmd_allocate_channel, 
-             pmt_list2(pmt_list2(s_response_allocate_channel, 
-                                 s_err_usrp_not_opened), 
-                       pmt_from_long(1)));
-
-  d_rx->send(s_cmd_allocate_channel, 
-             pmt_list2(pmt_list2(s_response_allocate_channel,
-                                 s_err_usrp_not_opened), 
-                       pmt_from_long(1)));
-
-  // Retrieve information about the USRP, then run tests
-  d_cs->send(s_cmd_open, 
-             pmt_list2(pmt_list2(s_response_open, PMT_T), 
-             pmt_from_long(0)));
-
-  d_cs->send(s_cmd_max_capacity, 
-             pmt_list1(pmt_list2(s_response_max_capacity, PMT_T)));
-  
-  d_cs->send(s_cmd_ntx_chan, 
-             pmt_list1(pmt_list2(s_response_ntx_chan, PMT_T)));
-  
-  d_cs->send(s_cmd_nrx_chan, 
-             pmt_list1(pmt_list2(s_response_nrx_chan,PMT_T)));
-}
-
-void
-qa_alloc_top::run_tests()
-{
-  if(verbose)
-    std::cout << "[qa_alloc_top] Starting tests...\n";
-
-  // should be able to allocate 1 byte
-  d_tx->send(s_cmd_allocate_channel, 
-             pmt_list2(PMT_T, pmt_from_long(1)));
-  
-  // should not be able to allocate max capacity after 100 bytes were allocated
-  d_tx->send(s_cmd_allocate_channel, 
-             pmt_list2(s_err_requested_capacity_unavailable, 
-                       pmt_from_long(d_max_capacity)));  
-  
-  // keep allocating a little more until all of the channels are used and test
-  // the error response we start at 1 since we've already allocated 1 channel
-  for(int i=1; i < d_ntx_chan; i++) {
-
-    if(verbose)
-      std::cout << "[qa_alloc_top] Sent allocation request...\n";
-  
-    d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
-
-    d_nmsgs_to_recv++;
-  }
-
-  // No more channels after allocating all of them is expected
-  d_tx->send(s_cmd_allocate_channel, 
-             pmt_list2(s_err_channel_unavailable, 
-                       pmt_from_long(1)));
-
-  // test out the same on the RX side
-  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
-
-  d_rx->send(s_cmd_allocate_channel, 
-             pmt_list2(s_err_requested_capacity_unavailable, 
-                       pmt_from_long(d_max_capacity)));  
-
-  for(int i=1; i < d_nrx_chan; i++) {
-    
-    d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
-    
-    d_nmsgs_to_recv++;
-  }
-
-  d_rx->send(s_cmd_allocate_channel, 
-             pmt_list2(s_err_channel_unavailable, 
-             pmt_from_long(1)));
-
-  // when all is said and done, there should be d_ntx_chan+d_ntx_chan bytes
-  // allocated
-  d_cs->send(s_cmd_current_capacity_allocation, 
-             pmt_list1(pmt_from_long(d_ntx_chan+d_nrx_chan)));
-}
-
-void
-qa_alloc_top::handle_message(mb_message_sptr msg)
-{
-  pmt_t data = msg->data();
-
-  if ((pmt_eq(msg->port_id(), d_tx->port_symbol())
-       || pmt_eq(msg->port_id(), d_rx->port_symbol()))
-       && pmt_eq(msg->signal(), s_response_allocate_channel))
-    check_message(msg);
-  
-  if (pmt_eq(msg->port_id(), d_cs->port_symbol())) {
-      
-    if(pmt_eq(msg->signal(), s_response_max_capacity)) {
-      d_max_capacity = pmt_to_long(pmt_nth(2, data));
-      if(verbose)
-        std::cout << "[qa_alloc_top] USRP has max capacity of " 
-                  << d_max_capacity << "\n";
-    }
-    else if(pmt_eq(msg->signal(), s_response_ntx_chan)) {
-      d_ntx_chan = pmt_to_long(pmt_nth(2, data));
-      if(verbose)
-        std::cout << "[qa_alloc_top] USRP tx channels: " 
-                  << d_ntx_chan << "\n";
-    }
-    else if(pmt_eq(msg->signal(), s_response_nrx_chan)) {
-      d_nrx_chan = pmt_to_long(pmt_nth(2, data));
-      if(verbose)
-        std::cout << "[qa_alloc_top] USRP rx channels: " 
-                  << d_nrx_chan << "\n";
-    }
-    else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) {
-      check_message(msg);
-    }
-    
-    d_nstatus++;
-
-    check_message(msg);
-
-    if(d_nstatus==d_nstatus_to_recv)
-      run_tests();
-  }
-}
-
-void
-qa_alloc_top::check_message(mb_message_sptr msg)
-{
-  pmt_t data = msg->data();
-  pmt_t event = msg->signal();
-
-  pmt_t expected = pmt_nth(0, data);
-  pmt_t status = pmt_nth(1, data);
-
-  pmt_t e_event = pmt_nth(0, expected);
-  pmt_t e_status = pmt_nth(1, expected);
-  
-  d_nrecvd++;
-
-
-  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
-    if(verbose)
-      std::cout << "Got: " << status << " Expected: " << e_status << "\n";
-    shutdown_all(PMT_F);
-    return;
-  } else {
-    if(verbose)
-      std::cout << "[qa_alloc_top] Received expected response for message " 
-                << d_nrecvd << " (" << event << ")\n";
-  }
-
-  if(d_nrecvd == d_nmsgs_to_recv)
-    shutdown_all(PMT_T);
-}
-
-REGISTER_MBLOCK_CLASS(qa_alloc_top);
-
-// ----------------------------------------------------------------------------------------------
-
-class qa_dealloc_top : public mb_mblock
-{
-  mb_port_sptr d_tx;
-  mb_port_sptr d_rx;
-  mb_port_sptr d_cs;
-  
-  long d_max_capacity;
-  long d_ntx_chan, d_nrx_chan;
-
-  long d_nstatus;
-  long d_nstatus_to_recv;
-
-  long d_nalloc_to_recv;
-  long d_nalloc_recvd;
-
-  long d_ndealloc_to_recv;
-  long d_ndealloc_recvd;
-
-  std::vector<long> d_tx_chans;
-  std::vector<long> d_rx_chans;
-
- public:
-  qa_dealloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~qa_dealloc_top();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void check_allocation(mb_message_sptr msg);
-  void check_deallocation(mb_message_sptr msg);
-  void allocate_max();
-  void deallocate_all();
-};
-
-qa_dealloc_top::qa_dealloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg)
-{ 
-  d_ndealloc_recvd=0;
-  d_ndealloc_to_recv = 0;
-  d_nalloc_recvd=0;
-  d_nalloc_to_recv = 0;   // auto-set
-  d_nstatus=0;
-  d_nstatus_to_recv = 4;
-  
-  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
-  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-
-  // Use the stub with the usrp_server
-  pmt_t usrp_server_dict = pmt_make_dict();
-  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
-
-  // Test the TX side
-  define_component("server", "usrp_server", usrp_server_dict);
-  connect("self", "tx0", "server", "tx0");
-  connect("self", "rx0", "server", "rx0");
-  connect("self", "cs", "server", "cs");
-}
-
-qa_dealloc_top::~qa_dealloc_top(){}
-
-void
-qa_dealloc_top::initial_transition()
-{
-
-  if(verbose)
-    std::cout << "[qa_dealloc_top] Initializing...\n";
-
-  // Retrieve information about the USRP, then run tests
-  d_cs->send(s_cmd_open, 
-             pmt_list2(pmt_list2(s_response_open,PMT_T), 
-             pmt_from_long(0)));
-
-  d_cs->send(s_cmd_max_capacity, 
-             pmt_list1(pmt_list2(s_response_max_capacity,PMT_T)));
-
-  d_cs->send(s_cmd_ntx_chan, 
-             pmt_list1(pmt_list2(s_response_ntx_chan,PMT_T)));
-
-  d_cs->send(s_cmd_nrx_chan, 
-             pmt_list1(pmt_list2(s_response_nrx_chan,PMT_T)));
-}
-
-void
-qa_dealloc_top::allocate_max()
-{
-
-  // Keep allocating until we hit the maximum number of channels
-  for(int i=0; i < d_ntx_chan; i++) {
-    d_tx->send(s_cmd_allocate_channel, 
-               pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T),
-               pmt_from_long(1)));  // 1 byte is good enough
-
-    d_nalloc_to_recv++;
-  }
-
-  for(int i=0; i < d_nrx_chan; i++) {
-    d_rx->send(s_cmd_allocate_channel, 
-               pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T), 
-               pmt_from_long(1)));
-
-    d_nalloc_to_recv++;
-  }
-
-}
-
-void
-qa_dealloc_top::deallocate_all() {
-  
-  // Deallocate all of the channels that were allocated from allocate_max()
-  for(int i=0; i < (int)d_tx_chans.size(); i++) {
-
-    if(verbose)
-      std::cout << "[qa_dealloc_top] Trying to dealloc TX " 
-                << d_tx_chans[i] << std::endl;
-
-    d_tx->send(s_cmd_deallocate_channel, 
-               pmt_list2(pmt_list2(s_response_deallocate_channel,PMT_T), 
-               pmt_from_long(d_tx_chans[i])));
-
-    d_ndealloc_to_recv++;
-  }
-
-  // Deallocate the RX side now
-  for(int i=0; i < (int)d_rx_chans.size(); i++) {
-
-    if(verbose)
-      std::cout << "[qa_dealloc_top] Trying to dealloc RX " 
-                << d_tx_chans[i] << std::endl;
-
-    d_rx->send(s_cmd_deallocate_channel, 
-               pmt_list2(pmt_list2(s_response_deallocate_channel,PMT_T), 
-               pmt_from_long(d_rx_chans[i])));
-
-    d_ndealloc_to_recv++;
-  }
-
-  // Should get permission denied errors trying to re-dealloc the channels, as
-  // we no longer have permission to them after deallocating
-  for(int i=0; i < (int)d_tx_chans.size(); i++) {
-
-    d_tx->send(s_cmd_deallocate_channel, 
-               pmt_list2(pmt_list2(s_response_deallocate_channel,
-                             s_err_channel_permission_denied), 
-                         pmt_from_long(d_tx_chans[i])));
-
-    d_ndealloc_to_recv++;
-  }
-
-  // Same for RX
-  for(int i=0; i < (int)d_rx_chans.size(); i++) {
-
-    d_rx->send(s_cmd_deallocate_channel, 
-               pmt_list2(pmt_list2(s_response_deallocate_channel,
-                             s_err_channel_permission_denied), 
-                         pmt_from_long(d_rx_chans[i])));
-  
-    d_ndealloc_to_recv++;
-  }
-
-  // Try to deallocate a channel that doesn't exist on both sides, the last
-  // element in the vectors is the highest channel number, so we take that plus
-  // 1
-  d_ndealloc_to_recv+=2;
-  d_tx->send(s_cmd_deallocate_channel, 
-             pmt_list2(pmt_list2(s_response_deallocate_channel,
-                                 s_err_channel_invalid), 
-                       pmt_from_long(d_rx_chans.back()+1)));
-
-  d_rx->send(s_cmd_deallocate_channel, 
-             pmt_list2(pmt_list2(s_response_deallocate_channel,
-                                 s_err_channel_invalid), 
-                       pmt_from_long(d_rx_chans.back()+1)));
-
-
-  // The used capacity should be back to 0 now that we've deallocated everything
-  d_cs->send(s_cmd_current_capacity_allocation,
-             pmt_list1(pmt_list2(s_response_current_capacity_allocation,
-                                 PMT_T)));
-}
-
-void
-qa_dealloc_top::handle_message(mb_message_sptr msg)
-{
-  pmt_t data = msg->data();
-  pmt_t event = msg->signal();
-  
-  if(pmt_eq(event, pmt_intern("%shutdown")))
-    return;
-
-  pmt_t expected = pmt_nth(0, data);
-  pmt_t status = pmt_nth(1, data);
-
-  pmt_t e_event = pmt_nth(0, expected);
-  pmt_t e_status = pmt_nth(1, expected);
-
-  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
-    if(verbose)
-      std::cout << "Got: " << status << " Expected: " << e_status << "\n";
-    shutdown_all(PMT_F);
-    return;
-  } else {
-    if(verbose)
-      std::cout << "[qa_alloc_top] Received expected response for message " 
-                << d_ndealloc_recvd
-      << " (" << event << ")\n";
-  }
-
-  if (pmt_eq(msg->port_id(), d_tx->port_symbol())
-       || pmt_eq(msg->port_id(), d_rx->port_symbol())) {
-    
-    if(pmt_eq(msg->signal(), s_response_allocate_channel)) {
-      check_allocation(msg);
-    }
-    
-  }
-  
-  if (pmt_eq(msg->port_id(), d_cs->port_symbol())) {
-      
-    if(pmt_eq(msg->signal(), s_response_max_capacity)) {
-      d_max_capacity = pmt_to_long(pmt_nth(2, data));
-    }
-    else if(pmt_eq(msg->signal(), s_response_ntx_chan)) {
-      d_ntx_chan = pmt_to_long(pmt_nth(2, data));
-    }
-    else if(pmt_eq(msg->signal(), s_response_nrx_chan)) {
-      d_nrx_chan = pmt_to_long(pmt_nth(2, data));
-    }
-    else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) {
-      // the final command is a capacity check which should be 0, then we
-      // shutdown
-      pmt_t expected_result = pmt_from_long(0);
-      pmt_t result = pmt_nth(2, data);
-
-      if(pmt_eqv(expected_result, result)) {
-        shutdown_all(PMT_T);
-        return;
-      } else {
-        shutdown_all(PMT_F);
-        return;
-      }
-    }
-    
-    d_nstatus++;
-
-    if(d_nstatus==d_nstatus_to_recv)
-      allocate_max();
-  }
-}
-
-
-void
-qa_dealloc_top::check_allocation(mb_message_sptr msg)
-{
-  pmt_t data = msg->data();
-  pmt_t event = msg->signal();
-
-  pmt_t expected = pmt_nth(0, data);
-  pmt_t status = pmt_nth(1, data);
-  pmt_t channel = pmt_nth(2, data);
-
-  d_nalloc_recvd++;
-
-  if(!pmt_eqv(status, PMT_T)) {
-    shutdown_all(PMT_F);
-    return;
-  } else {
-    // store all of the allocate channel numbers
-    if(pmt_eq(msg->port_id(), d_tx->port_symbol()))
-      d_tx_chans.push_back(pmt_to_long(channel));
-    if(pmt_eq(msg->port_id(), d_rx->port_symbol()))
-      d_rx_chans.push_back(pmt_to_long(channel));
-  }
-
-  if(d_nalloc_recvd == d_nalloc_to_recv) {
-
-    if(verbose) {
-      std::cout << "[qa_dealloc_top] Allocated TX channels: ";
-      for(int i=0; i < (int)d_tx_chans.size(); i++)
-        std::cout << d_tx_chans[i] << " ";
-
-      std::cout << "\n[qa_dealloc_top] Allocated RX channels: ";
-      for(int i=0; i < (int)d_rx_chans.size(); i++)
-        std::cout << d_rx_chans[i] << " ";
-      std::cout << "\n";
-    }
-
-    deallocate_all();   // once we've allocated all of our channels, try to
-                        // dealloc them
-  }
-}
-
-REGISTER_MBLOCK_CLASS(qa_dealloc_top);
-
-// ----------------------------------------------------------------------------------------------
-
-class qa_open_close_top : public mb_mblock
-{
-  mb_port_sptr d_cs;
-  
-  long d_max_capacity;
-
-  long d_nmsg_to_recv;
-  long d_nmsg_recvd;
-
- public:
-  qa_open_close_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~qa_open_close_top();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void check_cs(mb_message_sptr msg);
-  void run_tests();
-};
-
-qa_open_close_top::qa_open_close_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg)
-{ 
-
-  d_nmsg_to_recv=7;
-  d_nmsg_recvd=0;
-  
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-
-  // Use the stub with the usrp_server
-  pmt_t usrp_server_dict = pmt_make_dict();
-  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
-
-  // Test the TX side
-  define_component("server", "usrp_server", usrp_server_dict);
-  connect("self", "cs", "server", "cs");
-}
-
-qa_open_close_top::~qa_open_close_top(){}
-
-void
-qa_open_close_top::initial_transition()
-{
-  run_tests();
-}
-
-void
-qa_open_close_top::run_tests()
-{
-  // std::cout << "[qa_open_close_top] Starting tests\n";
-
-  // A close before an open should fail
-  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close, 
-                                              s_err_usrp_already_closed)));
-  
-  // Perform an open, and a second open which should fail
-  d_cs->send(s_cmd_open, 
-             pmt_list2(pmt_list2(s_response_open,PMT_T), 
-                       pmt_from_long(0)));
-
-  d_cs->send(s_cmd_open, 
-             pmt_list2(pmt_list2(s_response_open,
-                                 s_err_usrp_already_opened), 
-                       pmt_from_long(0)));
-
-  // A close should now be successful since the interface is open
-  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
-
-  // But, a second close should fail
-  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,
-                                              s_err_usrp_already_closed)));
-  
-  // Just to be thorough, try an open and close again
-  d_cs->send(s_cmd_open, 
-             pmt_list2(pmt_list2(s_response_open,PMT_T), 
-                       pmt_from_long(0)));
-
-  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
-  
-}
-
-
-void
-qa_open_close_top::handle_message(mb_message_sptr msg)
-{
-  pmt_t data = msg->data();
-
-  if (pmt_eq(msg->port_id(), d_cs->port_symbol())) {
-      check_cs(msg);
-  }
-
-  d_nmsg_recvd++;
-
-  if(d_nmsg_to_recv == d_nmsg_recvd)
-    shutdown_all(PMT_T);
-}
-
-void
-qa_open_close_top::check_cs(mb_message_sptr msg)
-{
-  pmt_t data = msg->data();
-  pmt_t event = msg->signal();
-
-  pmt_t expected = pmt_nth(0, data);
-  pmt_t status = pmt_nth(1, data);
-
-  pmt_t e_event = pmt_nth(0, expected);
-  pmt_t e_status = pmt_nth(1, expected);
-
-  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
-
-    if(verbose)
-      std::cout << "[qa_open_close_top] FAILED check_cs... Got: " << status
-                << " Expected: " << e_status
-                << " for event " << event << "\n";
-
-    shutdown_all(PMT_F);
-  } else {
-    if(verbose)
-      std::cout << "[qa_open_close_top] Received expected CS response (" 
-                << event << ")\n";
-  }
-
-}
-
-REGISTER_MBLOCK_CLASS(qa_open_close_top);
-
-// ----------------------------------------------------------------------------------------------
-
-class qa_tx_top : public mb_mblock
-{
-  mb_port_sptr d_tx;
-  mb_port_sptr d_rx;
-  mb_port_sptr d_cs;
-  
-  long d_max_capacity;
-  long d_ntx_chan, d_nrx_chan;
-
-  long d_tx_chan;
-  long d_rx_chan;
-
-  long d_nmsg_to_recv;
-  long d_nmsg_recvd;
-
- public:
-  qa_tx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~qa_tx_top();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void check_allocation(mb_message_sptr msg);
-  void check_deallocation(mb_message_sptr msg);
-  void check_xmit(mb_message_sptr msg);
-  void check_cs(mb_message_sptr msg);
-  void run_tests();
-};
-
-qa_tx_top::qa_tx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg)
-{ 
-
-  d_nmsg_to_recv=10;
-  d_nmsg_recvd=0;
-  
-  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
-  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-
-  // Use the stub with the usrp_server
-  pmt_t usrp_server_dict = pmt_make_dict();
-  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
-
-  // Test the TX side
-  define_component("server", "usrp_server", usrp_server_dict);
-  connect("self", "tx0", "server", "tx0");
-  connect("self", "rx0", "server", "rx0");
-  connect("self", "cs", "server", "cs");
-}
-
-qa_tx_top::~qa_tx_top(){}
-
-void
-qa_tx_top::initial_transition()
-{
-  run_tests();
-}
-
-void
-qa_tx_top::run_tests()
-{
-  if(verbose)
-   std::cout << "[qa_tx_top] Starting tests\n";
-
-  // A transmit before an open should fail
-  d_tx->send(s_cmd_xmit_raw_frame, 
-             pmt_list4(pmt_list2(s_response_xmit_raw_frame, 
-                                 s_err_usrp_not_opened), 
-                       pmt_from_long(0), 
-                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0),
-                       pmt_from_long(0)));
-  
-  // Now open
-  d_cs->send(s_cmd_open, 
-             pmt_list2(pmt_list2(s_response_open,PMT_T), 
-                       pmt_from_long(0)));
-
-  // Try to transmit on a channel that we have no allocation for
-  d_tx->send(s_cmd_xmit_raw_frame, 
-             pmt_list4(pmt_list2(s_response_xmit_raw_frame,
-                                 s_err_channel_permission_denied), 
-                       pmt_from_long(0), 
-                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0), 
-                       pmt_from_long(0)));
-
-  // Get a channel allocation and send on it, we assume 0 (FIXME) until 'defer'
-  // is implemented for simplicity
-  d_tx->send(s_cmd_allocate_channel, 
-             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
-                       pmt_from_long(1)));
-
-  d_tx->send(s_cmd_xmit_raw_frame, 
-             pmt_list4(pmt_list2(s_response_xmit_raw_frame, PMT_T), 
-                       pmt_from_long(0), 
-                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0), 
-                       pmt_from_long(0)));
-
-  // Close should be successful
-  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
-
-  // After closing, a new transmit raw frame should fail again
-  d_tx->send(s_cmd_xmit_raw_frame, 
-             pmt_list4(pmt_list2(s_response_xmit_raw_frame, 
-                                 s_err_usrp_not_opened), 
-                       pmt_from_long(0), 
-                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0), 
-                       pmt_from_long(0)));
-
-  // Reopen and retry before getting an allocation, the first xmit should fail,
-  // after we allocate it should work again
-  d_cs->send(s_cmd_open, 
-             pmt_list2(pmt_list2(s_response_open, PMT_T), 
-                       pmt_from_long(0)));
-
-  d_tx->send(s_cmd_xmit_raw_frame, 
-             pmt_list4(pmt_list2(s_response_xmit_raw_frame,
-                                 s_err_channel_permission_denied), 
-                       pmt_from_long(0), 
-                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0), 
-                       pmt_from_long(0)));
-
-  d_tx->send(s_cmd_allocate_channel, 
-             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
-                       pmt_from_long(1)));
-
-  d_tx->send(s_cmd_xmit_raw_frame, 
-             pmt_list4(pmt_list2(s_response_xmit_raw_frame,PMT_T), 
-                       pmt_from_long(0), 
-                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0), 
-                       pmt_from_long(0)));
-
-  // A final close which should be successful
-  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
-  
-}
-
-
-void
-qa_tx_top::handle_message(mb_message_sptr msg)
-{
-  pmt_t data = msg->data();
-  pmt_t event = msg->signal();
-  
-  if(pmt_eq(event, pmt_intern("%shutdown")))
-    return;
-
-  pmt_t expected = pmt_nth(0, data);
-  pmt_t status = pmt_nth(1, data);
-
-  pmt_t e_event = pmt_nth(0, expected);
-  pmt_t e_status = pmt_nth(1, expected);
-
-  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
-    if(verbose)
-      std::cout << "[qa_xmit_top] Got: " << status 
-                << " Expected: " << e_status 
-                << "For signal: " << event << "\n";
-    shutdown_all(PMT_F);
-    return;
-  } else {
-    if(verbose)
-      std::cout << "[qa_xmit_top] Received expected response for message " 
-                << d_nmsg_recvd
-      << " (" << event << ")\n";
-  }
-
-  if (pmt_eq(msg->port_id(), d_tx->port_symbol())
-       || pmt_eq(msg->port_id(), d_rx->port_symbol())) {
-    
-    if(pmt_eq(msg->signal(), s_response_allocate_channel)) 
-      check_allocation(msg);
-    
-  }
-  
-  d_nmsg_recvd++;
-
-  if(d_nmsg_to_recv == d_nmsg_recvd){
-    shutdown_all(PMT_T);
-    return;
-  }
-}
-
-void
-qa_tx_top::check_allocation(mb_message_sptr msg)
-{
-  pmt_t data = msg->data();
-  pmt_t event = msg->signal();
-  
-  pmt_t expected = pmt_nth(0, data);
-  pmt_t status = pmt_nth(1, data);
-  pmt_t channel = pmt_nth(2, data);
-
-  if(pmt_eqv(status, PMT_T)) {
-    // store all of the allocate channel numbers
-    if(pmt_eq(msg->port_id(), d_tx->port_symbol()))
-      d_tx_chan = pmt_to_long(channel);
-    if(pmt_eq(msg->port_id(), d_rx->port_symbol()))
-      d_rx_chan = pmt_to_long(channel);
-  }
-}
-
-REGISTER_MBLOCK_CLASS(qa_tx_top);
-
-// ----------------------------------------------------------------------------------------------
-
-class qa_rx_top : public mb_mblock
-{
-  mb_port_sptr d_rx;
-  mb_port_sptr d_cs;
-  
-  long d_max_capacity;
-  long d_ntx_chan, d_nrx_chan;
-
-  long d_rx_chan;
-
-  bool d_got_response_recv;
-
-  mb_time d_t0;
-  double d_delta_t;
-
- public:
-  qa_rx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~qa_rx_top();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void check_allocation(mb_message_sptr msg);
-  void check_deallocation(mb_message_sptr msg);
-  void check_xmit(mb_message_sptr msg);
-  void check_cs(mb_message_sptr msg);
-  void run_tests();
-};
-
-qa_rx_top::qa_rx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg),
-    d_got_response_recv(false)
-{ 
-
-  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-
-  // Use the stub with the usrp_server
-  pmt_t usrp_dict = pmt_make_dict();
-  // Set TX and RX interpolations
-  pmt_dict_set(usrp_dict,
-               pmt_intern("decim-rx"),
-               pmt_from_long(128));
-  pmt_dict_set(usrp_dict, pmt_intern("fake-usrp"), PMT_T);
-
-  // Test the TX side
-  define_component("server", "usrp_server", usrp_dict);
-  connect("self", "rx0", "server", "rx0");
-  connect("self", "cs", "server", "cs");
-}
-
-qa_rx_top::~qa_rx_top(){}
-
-void
-qa_rx_top::initial_transition()
-{
-  run_tests();
-}
-
-void
-qa_rx_top::run_tests()
-{
-  if(verbose)
-    std::cout << "[qa_rx_top] Starting tests\n";
-
-  d_cs->send(s_cmd_open, pmt_list2(pmt_list2(s_response_open,PMT_T), pmt_from_long(0)));
-
-  d_rx->send(s_cmd_allocate_channel, 
-             pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T), 
-             pmt_from_long(1)));
-
-  d_rx->send(s_cmd_start_recv_raw_samples, 
-             pmt_list2(PMT_NIL, 
-                       pmt_from_long(0)));
-
-  // Schedule a small timeout in which we expect to have received at least one
-  // packet worth of samples from the stub
-  d_t0 = mb_time::time();
-  schedule_one_shot_timeout(d_t0 + 0.01, PMT_NIL);
-}
-
-
-void
-qa_rx_top::handle_message(mb_message_sptr msg)
-{
-  pmt_t data = msg->data();
-  pmt_t event = msg->signal();
-  
-  if(pmt_eq(event, pmt_intern("%shutdown")))
-    return;
-  
-  pmt_t expected = pmt_nth(0, data);
-  pmt_t status = pmt_nth(1, data);
-
-  // If we get a timeout we shutdown
-  if(pmt_eq(event, s_timeout)) {
-    if(verbose)
-      std::cout << "[qa_rx_top] Got timeout\n";
-    d_rx->send(s_cmd_stop_recv_raw_samples, 
-               pmt_list2(PMT_NIL, 
-                         pmt_from_long(0)));
-
-    d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
-    return;
-  }
-  
-  // For testing RX, an invocation handle is not generated by the stub,
-  // therefore the same approach for testing is not used.  We simply
-  // expect all responses to be true.
-  if(pmt_eq(event, s_response_recv_raw_samples)) {
-    if(pmt_eqv(status, PMT_T)) {
-
-      if(verbose)
-        std::cout << "[qa_rx_top] Received expected response for message " 
-                  << " (" << event << ")\n";
-
-      // All we want is 1 response receive!  Can't guarantee exact numbers
-      d_got_response_recv = true;
-    }
-    else {
-      if(verbose)
-        std::cout << "Got: " << status << " Expected: " << PMT_T << "\n";
-      shutdown_all(PMT_F);
-    }
-    return;
-  }
-
-  pmt_t e_event = pmt_nth(0, expected);
-  pmt_t e_status = pmt_nth(1, expected);
-
-  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
-   if(verbose)
-      std::cout << "Got: " << status << " Expected: " << e_status << "\n";
-    shutdown_all(PMT_F);
-    return;
-  } else {
-    if(verbose)
-      std::cout << "[qa_rx_top] Received expected response for message " 
-                << " (" << event << ")\n";
-  }
-
-  if (pmt_eq(msg->port_id(), d_rx->port_symbol())) {
-    
-    if(pmt_eq(msg->signal(), s_response_allocate_channel)) 
-      check_allocation(msg);
-
-  }
-
-  // We stop when we get a close, we are successful if we
-  // got a response from recv, fail if we never got a recv response
-  if(pmt_eq(msg->signal(), s_response_close)) {
-    
-    if(d_got_response_recv) {
-      shutdown_all(PMT_T);
-      return;
-    }
-    else {
-      shutdown_all(PMT_F);
-      if(verbose)
-        std::cout << "[qa_rx_top] No response message before close\n";
-      return;
-    }
-  }
-}
-
-
-void
-qa_rx_top::check_allocation(mb_message_sptr msg)
-{
-  pmt_t data = msg->data();
-  pmt_t event = msg->signal();
-  
-  pmt_t expected = pmt_nth(0, data);
-  pmt_t status = pmt_nth(1, data);
-  pmt_t channel = pmt_nth(2, data);
-
-  if(pmt_eqv(status, PMT_T)) {
-    // store all of the allocate channel numbers
-    if(pmt_eq(msg->port_id(), d_rx->port_symbol()))
-      d_rx_chan = pmt_to_long(channel);
-  }
-}
-
-REGISTER_MBLOCK_CLASS(qa_rx_top);
-
-// ----------------------------------------------------------------------------------------------
-
-class qa_rid_top : public mb_mblock
-{
-  mb_port_sptr d_tx;
-  mb_port_sptr d_rx;
-  mb_port_sptr d_cs;
-
-  long d_npongs;
-  long d_tcycles;
-  long d_cycles;
-  long d_max_rid;
-  
-  mb_time d_t0;
-  double d_delta_t;
-
- public:
-  qa_rid_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~qa_rid_top();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void run_tests();
-  void send_max_pings();
-};
-
-qa_rid_top::qa_rid_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg)
-{ 
-  d_npongs = 0;
-  d_tcycles = 3;
-  d_cycles = d_tcycles;
-  d_max_rid = usrp_server::D_MAX_RID;
-  d_delta_t = 0.1;
-
-
-  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
-  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-  // Use the stub with the usrp_server
-  pmt_t usrp_server_dict = pmt_make_dict();
-  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
-
-  // Test the TX side
-  define_component("server", "usrp_server", usrp_server_dict);
-  connect("self", "tx0", "server", "tx0");
-  connect("self", "rx0", "server", "rx0");
-  connect("self", "cs", "server", "cs");
-
-}
-
-qa_rid_top::~qa_rid_top(){}
-
-void
-qa_rid_top::initial_transition()
-{
-  run_tests();
-}
-
-void
-qa_rid_top::run_tests()
-{
-  if(verbose)
-    std::cout << "[qa_rid_top] Starting tests...\n";
-  
-  // Retrieve information about the USRP, then run tests
-  d_cs->send(s_cmd_open, 
-             pmt_list2(pmt_list2(s_response_open, PMT_T), 
-             pmt_from_long(0)));
-
-  // should be able to allocate 1 byte
-  d_tx->send(s_cmd_allocate_channel, 
-             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
-                       pmt_from_long(1)));
-  
-  d_rx->send(s_cmd_allocate_channel, 
-             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
-                       pmt_from_long(1)));
-  
-  // Need to start receiving to read from the USRP to get C/S responses
-  d_rx->send(s_cmd_start_recv_raw_samples, 
-             pmt_list2(PMT_NIL, 
-                       pmt_from_long(0)));
-
-  // Build a subpacket of MAX_RID pings and wait a small amount for all of the
-  // responses and fire off another MAX_RID.  If MAX_RID*2 responses are
-  // received, the RID recycling is working correctly.
-  // Schedule a timer in which we expect to have received all of the responses,
-  // which will send off another MAX_RID worth.
-  send_max_pings();
-  d_t0 = mb_time::time();
-  schedule_one_shot_timeout(d_t0 + d_delta_t, PMT_NIL);
-}
-
-void
-qa_rid_top::send_max_pings()
-{
-  pmt_t ping = pmt_list2(s_op_ping_fixed,
-                         pmt_list2(pmt_from_long(0),
-                                   pmt_from_long(0)));
-
-  pmt_t sub_packets = PMT_NIL;
-
-  for(int i=0; i<d_max_rid; i++) 
-    sub_packets = pmt_list_add(sub_packets, ping);
-
-  d_tx->send(s_cmd_to_control_channel,
-             pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
-                       sub_packets));
-}
-
-void
-qa_rid_top::handle_message(mb_message_sptr msg)
-{
-  pmt_t data = msg->data();
-  pmt_t event = msg->signal();
-
-  // If we get a timeout we ensure we got a maximum RID number of responses.
-  if(pmt_eq(event, s_timeout)) {
-    if(verbose)
-      std::cout << "[qa_rid_top] Got timeout, received so far: " 
-                << d_npongs << "\n";
-
-    d_cycles--;
-    
-    if(d_cycles==0 && d_npongs == d_max_rid*d_tcycles) {
-      shutdown_all(PMT_T);
-    }
-    else if(d_cycles==0) {
-
-      std::cout << "[qa_rid_top] d_npongs: " << d_npongs
-                << " expected: " << d_max_rid*d_tcycles
-                << std::endl;
-
-      shutdown_all(PMT_F);
-    }
-    else {
-      send_max_pings();
-      d_t0 = mb_time::time();
-      schedule_one_shot_timeout(d_t0 + d_delta_t, PMT_NIL);
-    }
-
-  }
-  else if(pmt_eq(event, s_response_from_control_channel))
-  {
-    d_npongs++;
-  }
-
-}
-
-REGISTER_MBLOCK_CLASS(qa_rid_top);
-
-
-// ----------------------------------------------------------------------------------------------
-
-class qa_cs_top : public mb_mblock
-{
-  mb_port_sptr d_tx;
-  mb_port_sptr d_rx;
-  mb_port_sptr d_cs;
-
-  long d_nmsgs_to_recv;
-  long d_nrecvd;
-
-  long d_max_capacity;
-  long d_ntx_chan, d_nrx_chan;
-
-  long d_nstatus;
-  long d_nstatus_to_recv;
-
- public:
-  qa_cs_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~qa_cs_top();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void check_message(mb_message_sptr msg);
-  void run_tests();
-};
-
-qa_cs_top::qa_cs_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg)
-{ 
-  d_nrecvd=0;
-  d_nmsgs_to_recv = 8;
-  d_nstatus=0;
-  d_nstatus_to_recv = 50;
-  
-  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
-  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-  // Use the stub with the usrp_server
-  pmt_t usrp_server_dict = pmt_make_dict();
-  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
-
-  // Test the TX side
-  define_component("server", "usrp_server", usrp_server_dict);
-  connect("self", "tx0", "server", "tx0");
-  connect("self", "rx0", "server", "rx0");
-  connect("self", "cs", "server", "cs");
-
-}
-
-qa_cs_top::~qa_cs_top(){}
-
-void
-qa_cs_top::initial_transition()
-{
-  run_tests();
-}
-
-void
-qa_cs_top::run_tests()
-{
-  if(verbose)
-    std::cout << "[qa_cs_top] Starting tests...\n";
-  
-  // Retrieve information about the USRP, then run tests
-  d_cs->send(s_cmd_open, 
-             pmt_list2(pmt_list2(s_response_open, PMT_T), 
-             pmt_from_long(0)));
-
-  // should be able to allocate 1 byte
-  d_tx->send(s_cmd_allocate_channel, 
-             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
-                       pmt_from_long(1)));
-  
-  d_rx->send(s_cmd_allocate_channel, 
-             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
-                       pmt_from_long(1)));
-  
-  // Need to start receiving to read from the USRP to get C/S responses
-  d_rx->send(s_cmd_start_recv_raw_samples, 
-             pmt_list2(PMT_NIL, 
-                       pmt_from_long(0)));
-
-  d_tx->send(s_cmd_to_control_channel,
-             pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
-                       pmt_list1(
-                            pmt_list2(s_op_ping_fixed, 
-                                      pmt_list2(pmt_from_long(3), 
-                                      pmt_from_long(0))))));
-  
-  d_tx->send(s_cmd_to_control_channel,
-             pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
-                       pmt_list1(
-                            pmt_list2(s_op_write_reg, 
-                                      pmt_list2(
-                                      pmt_from_long(0x3), 
-                                      pmt_from_long(0x4))))));
-  
-  d_tx->send(s_cmd_to_control_channel,
-             pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
-                       pmt_list1(
-                            pmt_list2(s_op_write_reg_masked, 
-                                      pmt_list3(
-                                      pmt_from_long(0x3), 
-                                      pmt_from_long(0x4),
-                                      pmt_from_long(0x5))))));
-  
-  d_tx->send(s_cmd_to_control_channel,
-             pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
-                       pmt_list1(
-                            pmt_list2(s_op_read_reg, 
-                                      pmt_list2(pmt_from_long(0), 
-                                      pmt_from_long(0x6))))));
-  
-  d_tx->send(s_cmd_to_control_channel,
-             pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
-                       pmt_list1(
-                            pmt_list2(s_op_delay, 
-                                      pmt_list1(pmt_from_long(0x7))))));
-
-  pmt_t subpackets = pmt_list5(
-                        pmt_list2(s_op_ping_fixed, pmt_list2(pmt_from_long(0), pmt_from_long(0))),
-                        pmt_list2(s_op_delay, pmt_list1(pmt_from_long(0x7))),
-                        pmt_list2(s_op_write_reg_masked, pmt_list3(pmt_from_long(3),
-                                                                   pmt_from_long(4),
-                                                                   pmt_from_long(5))),
-                        pmt_list2(s_op_write_reg, pmt_list2(pmt_from_long(3),
-                                                            pmt_from_long(4))),
-                        pmt_list2(s_op_read_reg, pmt_list2(pmt_from_long(0),
-                                                           pmt_from_long(6)))
-                     );
-
-  d_tx->send(s_cmd_to_control_channel, 
-              pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
-                        subpackets));
-
-  pmt_t i2c_data = pmt_make_u8vector(8, 0xff);
-
-  subpackets = pmt_list2(
-                        pmt_list2(s_op_i2c_write, 
-                                  pmt_list2(pmt_from_long(8), i2c_data)),
-                        pmt_list2(s_op_i2c_read,
-                                  pmt_list3(pmt_from_long(0), pmt_from_long(9), pmt_from_long(1)))
-
-                     );
-
-  d_tx->send(s_cmd_to_control_channel, 
-              pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
-                        subpackets));
-  
-}
-
-void
-qa_cs_top::handle_message(mb_message_sptr msg)
-{
-  pmt_t data = msg->data();
-
-  if ((pmt_eq(msg->port_id(), d_tx->port_symbol())
-       || pmt_eq(msg->port_id(), d_rx->port_symbol()))
-       && pmt_eq(msg->signal(), s_response_allocate_channel))
-    check_message(msg);
-
-  if (pmt_eq(msg->port_id(), d_tx->port_symbol())
-      && pmt_eq(msg->signal(), s_response_from_control_channel))
-    check_message(msg);
-  
-  if (pmt_eq(msg->port_id(), d_cs->port_symbol())) {
-      
-    if(pmt_eq(msg->signal(), s_response_max_capacity)) {
-      d_max_capacity = pmt_to_long(pmt_nth(2, data));
-      if(verbose)
-        std::cout << "[qa_cs_top] USRP has max capacity of " 
-                  << d_max_capacity << "\n";
-    }
-    else if(pmt_eq(msg->signal(), s_response_ntx_chan)) {
-      d_ntx_chan = pmt_to_long(pmt_nth(2, data));
-      if(verbose)
-        std::cout << "[qa_cs_top] USRP tx channels: " 
-                  << d_ntx_chan << "\n";
-    }
-    else if(pmt_eq(msg->signal(), s_response_nrx_chan)) {
-      d_nrx_chan = pmt_to_long(pmt_nth(2, data));
-      if(verbose)
-        std::cout << "[qa_cs_top] USRP rx channels: " 
-                  << d_nrx_chan << "\n";
-    }
-    else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) {
-      check_message(msg);
-    }
-    
-    d_nstatus++;
-
-    check_message(msg);
-
-    if(d_nstatus==d_nstatus_to_recv)
-      run_tests();
-  }
-}
-
-void
-qa_cs_top::check_message(mb_message_sptr msg)
-{
-  pmt_t data = msg->data();
-  pmt_t event = msg->signal();
-
-  pmt_t expected = pmt_nth(0, data);
-  pmt_t status = pmt_nth(1, data);
-
-  pmt_t e_event = pmt_nth(0, expected);
-  pmt_t e_status = pmt_nth(1, expected);
-  
-  d_nrecvd++;
-
-
-  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
-    if(verbose)
-      std::cout << "[qa_cs_top] Got: " << status << " Expected: " << e_status << "\n";
-    shutdown_all(PMT_F);
-    return;
-  } else {
-    if(verbose)
-      std::cout << "[qa_cs_top] Received expected response for message " 
-                << d_nrecvd << " (" << event << ")\n";
-  }
-
-  if(d_nrecvd == d_nmsgs_to_recv)
-    shutdown_all(PMT_T);
-}
-
-REGISTER_MBLOCK_CLASS(qa_cs_top);
-
-// ----------------------------------------------------------------------------------------------
-
-void 
-qa_inband_usrp_server::test_open_close()
-{
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_T;
-
-  // std::cout << "\n\n----------------------------\n";
-  // std::cout << "    RUNNING OPEN/CLOSE TESTS  \n";
-
-  rt->run("top", "qa_open_close_top", PMT_F, &result);
-
-  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
-}
-
-void 
-qa_inband_usrp_server::test_chan_allocation()
-{
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_T;
-
-  // std::cout << "\n\n----------------------------\n";
-  // std::cout << "    RUNNING ALLOCATION TESTS  \n";
-
-  rt->run("qa_alloc_top", "qa_alloc_top", PMT_F, &result);
-  
-  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
-}
-
-void
-qa_inband_usrp_server::test_chan_deallocation()
-{
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_T;
-
-  // std::cout << "\n\n----------------------------\n";
-  // std::cout << "  RUNNING DEALLOCATION TESTS  \n";
-
-  rt->run("qa_dealloc_top", "qa_dealloc_top", PMT_F, &result);
-  
-  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
-}
-
-void
-qa_inband_usrp_server::test_tx()
-{
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_T;
-
-  // std::cout << "\n\n-----------------\n";
-  // std::cout << "  RUNNING TX TESTS  \n";
-
-  rt->run("top", "qa_tx_top", PMT_F, &result);
-  
-  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
-}
-
-void
-qa_inband_usrp_server::test_rx()
-{
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_T;
-
-  // std::cout << "\n\n-----------------\n";
-  // std::cout << "  RUNNING RX TESTS  \n";
-
-  rt->run("top", "qa_rx_top", PMT_F, &result);
-  
-  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
-}
-
-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;
-
-  // std::cout << "\n\n-----------------\n";
-  // std::cout << "  RUNNING CS TESTS  \n";
-
-  rt->run("top", "qa_cs_top", PMT_F, &result);
-  
-  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
-}
-
-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;
-
-  // std::cout << "\n\n-----------------\n";
-  // std::cout << "  RUNNING RID TESTS  \n";
-
-  rt->run("top", "qa_rid_top", PMT_F, &result);
-  
-  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
-}
diff --git a/usrp/host/lib/inband/qa_inband_usrp_server.h b/usrp/host/lib/inband/qa_inband_usrp_server.h
deleted file mode 100644 (file)
index 52a4a0b..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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 QA_INBAND_USRP_SERVER_H
-#define QA_INBAND_USRP_SERVER_H
-
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/TestCase.h>
-
-class qa_inband_usrp_server : public CppUnit::TestCase {
-
-  CPPUNIT_TEST_SUITE(qa_inband_usrp_server);
-  CPPUNIT_TEST(test_open_close);
-  CPPUNIT_TEST(test_chan_allocation);
-  CPPUNIT_TEST(test_chan_deallocation);
-  CPPUNIT_TEST(test_tx);
-  CPPUNIT_TEST(test_rx);
-  CPPUNIT_TEST(test_cs);
-  CPPUNIT_TEST(test_rid);
-  CPPUNIT_TEST_SUITE_END();
-
- private:
-  void test_chan_allocation();
-  void test_chan_deallocation();
-  void test_open_close();
-  void test_tx();
-  void test_rx();
-  void test_cs();
-  void test_rid();
-};
-
-#endif /* INCLUDED_QA_INBAND_USRP_SERVER_H */
diff --git a/usrp/host/lib/inband/symbols_usrp_channel.h b/usrp/host/lib/inband/symbols_usrp_channel.h
deleted file mode 100644 (file)
index a0114cf..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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_SYMBOLS_USRP_CHANNEL_H
-#define INCLUDED_SYMBOLS_USRP_CHANNEL_H
-
-#include <pmt.h>
-
-// Outgoing
-static pmt_t s_cmd_allocate_channel = pmt_intern("cmd-allocate-channel");
-static pmt_t s_cmd_deallocate_channel = pmt_intern("cmd-deallocate-channel");
-
-// Incoming
-static pmt_t s_response_allocate_channel = pmt_intern("response-allocate-channel");
-static pmt_t s_response_deallocate_channel = pmt_intern("response-deallocate-channel");
-
-// Errors
-static pmt_t s_err_requested_capacity_unavailable = pmt_intern("err-requested-capacity-unavailable");
-static pmt_t s_err_channel_unavailable = pmt_intern("err-channel-unavailable");
-static pmt_t s_err_channel_invalid = pmt_intern("err-channel-invalid");
-static pmt_t s_err_channel_permission_denied = pmt_intern("err-channel-permission-denied");
-
-#endif /* INCLUDED_SYMBOLS_USRP_CHANNEL_H */
diff --git a/usrp/host/lib/inband/symbols_usrp_interface_cs.h b/usrp/host/lib/inband/symbols_usrp_interface_cs.h
deleted file mode 100644 (file)
index 72c8fcc..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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_SYMBOLS_USRP_INTERFACE_CS_H
-#define INCLUDED_SYMBOLS_USRP_INTERFACE_CS_H
-
-#include <pmt.h>
-
-// Outgoing
-static pmt_t s_cmd_usrp_open = pmt_intern("cmd-usrp-open");
-static pmt_t s_cmd_usrp_close = pmt_intern("cmd-usrp-close");
-static pmt_t s_cmd_usrp_ntx_chan = pmt_intern("cmd-usrp-ntx-chan");
-static pmt_t s_cmd_usrp_nrx_chan = pmt_intern("cmd-usrp-nrx-chan");
-static pmt_t s_cmd_usrp_write = pmt_intern("cmd-usrp-write");
-static pmt_t s_cmd_usrp_start_reading = pmt_intern("cmd-usrp-start-reading");
-static pmt_t s_cmd_usrp_stop_reading = pmt_intern("cmd-usrp-stop-reading");
-
-// Incoming
-static pmt_t s_response_usrp_open = pmt_intern("response-usrp-open");
-static pmt_t s_response_usrp_close = pmt_intern("response-usrp-close");
-static pmt_t s_response_usrp_ntx_chan = pmt_intern("response-usrp-ntx-chan");
-static pmt_t s_response_usrp_nrx_chan = pmt_intern("response-usrp-nrx-chan");
-static pmt_t s_response_usrp_write = pmt_intern("response-usrp-write");
-static pmt_t s_response_usrp_read = pmt_intern("response-usrp-read");
-
-#endif /* INCLUDED_SYMBOLS_USRP_INTERFACE_CS_H */
diff --git a/usrp/host/lib/inband/symbols_usrp_low_level_cs.h b/usrp/host/lib/inband/symbols_usrp_low_level_cs.h
deleted file mode 100644 (file)
index a726060..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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_SYMBOLS_USRP_LOW_LEVEL_CS_H
-#define INCLUDED_SYMBOLS_USRP_LOW_LEVEL_CS_H
-
-#include <pmt.h>
-
-// Outgoing
-static pmt_t s_cmd_to_control_channel = pmt_intern("cmd-to-control-channel");
-
-// Incoming
-static pmt_t s_response_from_control_channel = pmt_intern("response-from-control-channel");
-
-// Subpackets
-static pmt_t s_op_ping_fixed = pmt_intern("op-ping-fixed");
-static pmt_t s_op_ping_fixed_reply = pmt_intern("op-ping-fixed-reply");
-static pmt_t s_op_write_reg = pmt_intern("op-write-reg");
-static pmt_t s_op_write_reg_masked = pmt_intern("op-write-reg-masked");
-static pmt_t s_op_read_reg = pmt_intern("op-read-reg");
-static pmt_t s_op_read_reg_reply = pmt_intern("op-read-reg-reply");
-static pmt_t s_op_i2c_write = pmt_intern("op-i2c-write");
-static pmt_t s_op_i2c_read = pmt_intern("op-i2c-read");
-static pmt_t s_op_i2c_read_reply = pmt_intern("op-i2c-read-reply");
-static pmt_t s_op_spi_write = pmt_intern("op-spi-write");
-static pmt_t s_op_spi_read = pmt_intern("op-spi-read");
-static pmt_t s_op_spi_read_reply = pmt_intern("op-spi-read-reply");
-static pmt_t s_op_delay = pmt_intern("op-delay");
-
-#endif /* INCLUDED_SYMBOLS_USRP_LOW_LEVEL_CS_H */
diff --git a/usrp/host/lib/inband/symbols_usrp_rx.h b/usrp/host/lib/inband/symbols_usrp_rx.h
deleted file mode 100644 (file)
index 07d58a3..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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_SYMBOLS_USRP_RX_H
-#define INCLUDED_SYMBOLS_USRP_RX_H
-
-#include <pmt.h>
-
-// Outgoing
-static pmt_t s_cmd_start_recv_raw_samples = pmt_intern("cmd-start-recv-raw-samples");
-static pmt_t s_cmd_stop_recv_raw_samples = pmt_intern("cmd-stop-recv-raw-samples");
-
-// Incoming
-static pmt_t s_response_recv_raw_samples = pmt_intern("response-recv-raw-samples");
-
-// Errors
-static pmt_t s_err_already_receiving = pmt_intern("err-already-receiving");
-
-#endif /* INCLUDED_SYMBOLS_USRP_RX_H */
diff --git a/usrp/host/lib/inband/symbols_usrp_rx_cs.h b/usrp/host/lib/inband/symbols_usrp_rx_cs.h
deleted file mode 100644 (file)
index bf4f033..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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_SYMBOLS_USRP_RX_CS_H
-#define INCLUDED_SYMBOLS_USRP_RX_CS_H
-
-#include <pmt.h>
-
-// Outgoing
-static pmt_t s_cmd_usrp_rx_start_reading = pmt_intern("cmd-usrp-rx-start-reading");
-
-// Incoming
-static pmt_t s_response_usrp_rx_read = pmt_intern("response-usrp-rx-read");
-
-#endif /* INCLUDED_SYMBOLS_USRP_RX_CS_H */
diff --git a/usrp/host/lib/inband/symbols_usrp_server_cs.h b/usrp/host/lib/inband/symbols_usrp_server_cs.h
deleted file mode 100644 (file)
index e612e24..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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_SYMBOLS_USRP_SERVER_CS_H
-#define INCLUDED_SYMBOLS_USRP_SERVER_CS_H
-
-#include <pmt.h>
-
-// Outgoing
-static pmt_t s_cmd_open = pmt_intern("cmd-open");
-static pmt_t s_cmd_close = pmt_intern("cmd-close");
-static pmt_t s_cmd_max_capacity  = pmt_intern("cmd-max-capacity");
-static pmt_t s_cmd_ntx_chan  = pmt_intern("cmd-ntx-chan");
-static pmt_t s_cmd_nrx_chan  = pmt_intern("cmd-nrx-chan");
-static pmt_t s_cmd_current_capacity_allocation  = pmt_intern("cmd-current-capacity-allocation");
-
-// Incoming
-static pmt_t s_response_open = pmt_intern("response-open");
-static pmt_t s_response_close = pmt_intern("response-close");
-static pmt_t s_response_max_capacity = pmt_intern("response-max-capacity");
-static pmt_t s_response_ntx_chan = pmt_intern("response-ntx-chan");
-static pmt_t s_response_nrx_chan = pmt_intern("response-nrx-chan");
-static pmt_t s_response_current_capacity_allocation  = pmt_intern("response-current-capacity-allocation");
-
-// Errors
-static pmt_t s_err_usrp_not_opened = pmt_intern("err-usrp-not-opened");
-static pmt_t s_err_usrp_already_opened = pmt_intern("err-usrp-already-opened");
-static pmt_t s_err_usrp_already_closed = pmt_intern("err-usrp-already-closed");
-
-#endif /* INCLUDED_SYMBOLS_USRP_SERVER_CS_H */
diff --git a/usrp/host/lib/inband/symbols_usrp_tx.h b/usrp/host/lib/inband/symbols_usrp_tx.h
deleted file mode 100644 (file)
index 4e58e2c..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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_SYMBOLS_USRP_TX_H
-#define INCLUDED_SYMBOLS_USRP_TX_H
-
-#include <pmt.h>
-
-// Outgoing
-static pmt_t s_cmd_xmit_raw_frame  = pmt_intern("cmd-xmit-raw-frame");
-
-// Incoming
-static pmt_t s_response_xmit_raw_frame = pmt_intern("response-xmit-raw-frame");
-
-#endif /* INCLUDED_SYMBOLS_USRP_TX_H */
diff --git a/usrp/host/lib/inband/symbols_usrp_tx_cs.h b/usrp/host/lib/inband/symbols_usrp_tx_cs.h
deleted file mode 100644 (file)
index d02ef1d..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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_SYMBOLS_USRP_TX_CS_H
-#define INCLUDED_SYMBOLS_USRP_TX_CS_H
-
-#include <pmt.h>
-
-// Outgoing
-static pmt_t s_cmd_usrp_tx_write = pmt_intern("cmd-usrp-tx-write");
-
-// Incoming
-static pmt_t s_response_usrp_tx_write = pmt_intern("response-usrp-tx-write");
-
-#endif /* INCLUDED_SYMBOLS_USRP_TX_CS_H */
diff --git a/usrp/host/lib/inband/test_inband.cc b/usrp/host/lib/inband/test_inband.cc
deleted file mode 100644 (file)
index 77cdca5..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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.
- */
-
-#include <cppunit/TextTestRunner.h>
-#include <qa_inband.h>
-
-int 
-main(int argc, char **argv)
-{
-  
-  CppUnit::TextTestRunner      runner;
-
-  runner.addTest(qa_inband::suite ());
-  
-  bool was_successful = runner.run("", false);
-
-  return was_successful ? 0 : 1;
-}
diff --git a/usrp/host/lib/inband/usb_packet.py b/usrp/host/lib/inband/usb_packet.py
deleted file mode 100644 (file)
index 6dfcf86..0000000
+++ /dev/null
@@ -1,115 +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 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.
-#
-
-import struct
-
-
-FL_OVERRUN        = 0x80000000
-FL_UNDERRUN       = 0x40000000
-FL_DROPPED        = 0x20000000
-FL_END_OF_BURST   = 0x10000000
-FL_START_OF_BURST = 0x08000000
-
-FL_ALL_FLAGS      = 0xf8000000
-
-FL_OVERRUN_SHIFT = 31
-FL_UNDERRUN_SHIFT = 30
-FL_DROPPED_SHIFT = 29
-FL_END_OF_BURST_SHIFT = 28
-FL_START_OF_BURST_SHIFT = 27
-  
-RSSI_MASK = 0x3f
-RSSI_SHIFT = 21
-
-CHAN_MASK = 0x1f
-CHAN_SHIFT = 16
-
-TAG_MASK = 0xf
-TAG_SHIFT = 9
-
-PAYLOAD_LEN_MASK = 0x1ff
-PAYLOAD_LEN_SHIFT = 0
-
-def make_header(flags, chan, payload_len, timestamp, rssi=0, tag=0):
-    word0 =  ((flags & FL_ALL_FLAGS)
-              | ((rssi & RSSI_MASK) << RSSI_SHIFT)
-              | ((chan & CHAN_MASK) << CHAN_SHIFT)
-              | ((tag & TAG_MASK) << TAG_SHIFT)
-              | ((payload_len & PAYLOAD_LEN_MASK) << PAYLOAD_LEN_SHIFT))
-    word1 = timestamp
-    return struct.pack('<2I', word0, word1)
-
-
-def _decode(pred, indicator):
-    if pred:
-        return indicator
-    else:
-        return '-'
-
-
-class usb_packet(object):
-    def __init__(self, raw_pkt):
-        assert isinstance(raw_pkt, str) and len(raw_pkt) == 512
-        self._raw_pkt = raw_pkt;
-        (self._word0, self._word1) = struct.unpack('<2I', self._raw_pkt[0:8])
-
-    def timestamp(self):
-        return self._word1
-
-    def rssi(self):
-        return (self._word0 >> RSSI_SHIFT) & RSSI_MASK
-
-    def chan(self):
-        return (self._word0 >> CHAN_SHIFT) & CHAN_MASK
-
-    def tag(self):
-        return (self._word0 >> TAG_SHIFT) & TAG_MASK
-
-    def payload_len(self):
-        return (self._word0 >> PAYLOAD_LEN_SHIFT) & PAYLOAD_LEN_MASK
-
-    def flags(self):
-        return self._word0 & FL_ALL_FLAGS
-
-    def overrun(self):
-        return (self._word0 >> FL_OVERRUN_SHIFT) & 0x1
-
-    def underrun(self):
-        return (self._word0 >> FL_UNDERRUN_SHIFT) & 0x1
-
-    def start_of_burst(self):
-        return (self._word0 >> FL_START_OF_BURST_SHIFT) & 0x1
-
-    def end_of_burst(self):
-        return (self._word0 >> FL_END_OF_BURST_SHIFT) & 0x1
-
-    def dropped(self):
-        return (self._word0 >> FL_DROPPED_SHIFT) & 0x1
-
-    def payload(self):
-        return self._raw_pkt[8:8+self.payload_len()]
-
-    def decoded_flags(self):
-        s = (_decode(self.overrun(), 'O')
-             + _decode(self.underrun(), 'U')
-             + _decode(self.dropped(), 'D')
-             + _decode(self.end_of_burst(), 'E')
-             + _decode(self.start_of_burst(), 'S'))
-        return s
diff --git a/usrp/host/lib/inband/usrp_inband_usb_packet.cc b/usrp/host/lib/inband/usrp_inband_usb_packet.cc
deleted file mode 100644 (file)
index 72bc45c..0000000
+++ /dev/null
@@ -1,793 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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_inband_usb_packet.h>
-
-#include <usrp_bytesex.h>
-#include <iostream>
-#include <stdio.h>
-#include <string.h>
-
-/*!
- * \brief Aligns the packet payload on a 32 bit boundary.  This is essential to
- * all control/status packets so that the inband FPGA code can parse them
- * easily.
- *
- * \returns true if successful or if the packet was already aligned; false if it
- * cannot be aligned.
- */
-bool usrp_inband_usb_packet::align32()
-{
-  int p_len = payload_len();
-
-  int bytes_needed = 4 - (p_len % 4);
-
-  if(bytes_needed == 4)
-    return true;
-
-  // If the room left in the packet is less than the number of bytes
-  // needed, return false to indicate no room to align
-  if((MAX_PAYLOAD - p_len) < bytes_needed)
-    return false;
-    
-  incr_header_len(bytes_needed);
-
-  return true;
-}
-
-/*!
- * \brief Adds a ping command to the current control packet.
- *
- * The \p rid is the rid to be associated with the ping response and \p ping_val
- * is currently unused.
- *
- * \returns true if adding the ping command was successful, false otherwise
- * (i.e. no space in the current packet).
- */
-bool usrp_inband_usb_packet::cs_ping(long rid, long ping_val)
-{
-  if(!align32())
-    return false;
-  
-  int p_len = payload_len();
-
-  if((MAX_PAYLOAD - p_len) < (CS_PING_LEN + CS_FIXED_LEN))
-    return false;
-
-  uint32_t ping = ( 
-      ((OP_PING_FIXED & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
-    | ((CS_PING_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
-    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
-    | (ping_val & CS_PINGVAL_MASK)
-
-    );
-
-  uint32_t *payload = (uint32_t *) (d_payload + p_len);
-  *payload = host_to_usrp_u32(ping);
-
-  // Update payload length
-  incr_header_len(CS_FIXED_LEN + CS_PING_LEN);
-
-  return true;
-}
-
-/*!
- * \brief Adds a ping response to the packet.  This is used by the fake USRP
- * code to generate fake responses for pings.
- *
- * The \p rid is the RID to be associated with the response and \p ping_val is
- * currently unused.
- *
- * \returns true if the ping reply was added successfully, false otherwise.
- */
-bool usrp_inband_usb_packet::cs_ping_reply(long rid, long ping_val) 
-{
-  if(!align32())
-    return false;
-
-  int p_len = payload_len();
-
-  if((MAX_PAYLOAD - p_len) < (CS_PING_LEN + CS_FIXED_LEN))
-    return false;
-
-  uint32_t ping = ( 
-      ((OP_PING_FIXED_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
-    | ((CS_PING_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
-    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
-    | ((ping_val & CS_PINGVAL_MASK) << CS_PINGVAL_SHIFT)
-
-    );
-
-  uint32_t *payload = (uint32_t *) (d_payload + p_len);
-  *payload = host_to_usrp_u32(ping);
-
-  // Update payload length
-  incr_header_len(CS_FIXED_LEN + CS_PING_LEN);
-
-  return true;
-}
-
-/*!
- * \brief Adds a write register command to the packet.
- *
- * The \p reg_num is the register number for which the value \p val will be
- * written to.
- *
- * \returns true if the command was added to the packet successfully, false
- * otherwise.
- */
-bool usrp_inband_usb_packet::cs_write_reg(long reg_num, long val)
-{
-  if(!align32())
-    return false;
-
-  int p_len = payload_len();
-
-  if((MAX_PAYLOAD - p_len) < (CS_WRITEREG_LEN + CS_FIXED_LEN))
-    return false;
-
-  uint32_t word0 = 0;
-
-  // Build the first word which includes the register number
-  word0 = (
-      ((OP_WRITE_REG & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
-    | ((CS_WRITEREG_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
-    | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT)
-  );
-
-  uint32_t *payload = (uint32_t *) (d_payload + p_len);
-  *payload = host_to_usrp_u32(word0);
-
-  // The second word is solely the register value to be written
-  // FIXME: should this be unsigned?
-  payload += 1; 
-  *payload = host_to_usrp_u32((uint32_t) val);
-  
-  // Rebuild the header to update the payload length
-  incr_header_len(CS_FIXED_LEN + CS_WRITEREG_LEN);
-
-  return true;
-}
-
-/*!
- * \brief Adds a write register masked command to the packet.
- *
- * The \p reg_num is the register number for which the value \p val will be
- * written, masked by \p mask
- *
- * \returns true if the command was added to the packet, false otherwise.
- */
-bool usrp_inband_usb_packet::cs_write_reg_masked(long reg_num, long val, long mask)
-{
-  if(!align32())
-    return false;
-
-  int p_len = payload_len();
-
-  if((MAX_PAYLOAD - p_len) < (CS_WRITEREGMASKED_LEN + CS_FIXED_LEN))
-    return false;
-
-  uint32_t word0 = 0;
-
-  // Build the first word which includes the register number
-  word0 = (
-      ((OP_WRITE_REG_MASKED & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
-    | ((CS_WRITEREGMASKED_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
-    | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT)
-  );
-
-  uint32_t *payload = (uint32_t *) (d_payload + p_len);
-  *payload = host_to_usrp_u32(word0);
-
-  // Skip over the first word and write the register value
-  payload += 1;
-  *payload = host_to_usrp_u32((uint32_t) val);
-
-  // Skip over the register value and write the mask
-  payload += 1;
-  *payload = host_to_usrp_u32((uint32_t) mask);
-  
-  // Rebuild the header to update the payload length
-  incr_header_len(CS_FIXED_LEN + CS_WRITEREGMASKED_LEN);
-
-  return true;
-}
-
-/*!
- * \brief Adds a read register message to the packet. 
- *
- * The \p rid will be the associated RID returned with the response, and \p
- * reg_num is the register to be read.
- * 
- * \returns true if the command was added to the packet, false otherwise.
- */
-bool usrp_inband_usb_packet::cs_read_reg(long rid, long reg_num)
-{
-  if(!align32())
-    return false;
-
-  int p_len = payload_len();
-
-  if((MAX_PAYLOAD - p_len) < (CS_READREG_LEN + CS_FIXED_LEN))
-    return false;
-
-  uint32_t read_reg = ( 
-      ((OP_READ_REG & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
-    | ((CS_READREG_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
-    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
-    | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT)
-
-    );
-
-  uint32_t *payload = (uint32_t *) (d_payload + p_len);
-  *payload = host_to_usrp_u32(read_reg);
-
-  // Update payload length
-  incr_header_len(CS_FIXED_LEN + CS_READREG_LEN);
-
-  return true;
-}
-
-/*!
- * \brief Adds a read register reply response to the current packet.  This is
- * used by the fake USRP code to generate fake register read responses for
- * testing.
- *
- * The \p rid is the associated RID to be included in the response, \p reg_num
- * is the register the read is coming from, and \p reg_val is the value of the
- * read.
- *
- * \returns true if the command was added to the packet, false otherwise.
- */
-bool usrp_inband_usb_packet::cs_read_reg_reply(long rid, long reg_num, long reg_val)
-{
-  if(!align32())
-    return false;
-
-  int p_len = payload_len();
-
-  if((MAX_PAYLOAD - p_len) < (CS_READREGREPLY_LEN + CS_FIXED_LEN))
-    return false;
-
-  uint32_t word0 = ( 
-      ((OP_READ_REG_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
-    | ((CS_READREGREPLY_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
-    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
-    | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT)
-
-    );
-
-  uint32_t *payload = (uint32_t *) (d_payload + p_len);
-  *payload = host_to_usrp_u32(word0);
-
-  // Hop to the next word and write the reg value
-  payload += 1;
-  *payload = host_to_usrp_u32((uint32_t) reg_val); 
-
-  // Update payload length
-  incr_header_len(CS_FIXED_LEN + CS_READREGREPLY_LEN);
-
-  return true;
-}
-
-/*!
- * \brief Adds a delay command to the current packet.
- *
- * The \p ticks parameter is the number of clock ticks the FPGA should delay
- * parsing for, which is added to the packet.
- *
- * \returns true if the command was added to the packet, false otherwise.
- */
-bool usrp_inband_usb_packet::cs_delay(long ticks)
-{
-  if(!align32())
-    return false;
-
-  int p_len = payload_len();
-
-  if((MAX_PAYLOAD - p_len) < (CS_DELAY_LEN + CS_FIXED_LEN))
-    return false;
-
-  uint32_t delay = ( 
-      ((OP_DELAY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
-    | ((CS_DELAY_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
-    | ((ticks & CS_DELAY_MASK) << CS_DELAY_SHIFT)
-
-    );
-
-  uint32_t *payload = (uint32_t *) (d_payload + p_len);
-  *payload = host_to_usrp_u32(delay);
-
-  // Update payload length
-  incr_header_len(CS_FIXED_LEN + CS_DELAY_LEN);
-
-  return true;
-}
-
-/*!
- * \brief
- *
- * \returns true if the command was added to the packet, false otherwise.
- */
-bool usrp_inband_usb_packet::cs_i2c_write(long i2c_addr, uint8_t *i2c_data, size_t data_len)
-{
-  if(!align32())
-    return false;
-
-  int p_len = payload_len();
-
-  int i2c_len = data_len + 2;   // 2 bytes between mbz and addr
-
-  if((MAX_PAYLOAD - p_len) < (i2c_len + CS_FIXED_LEN))
-    return false;
-
-  uint32_t word0 = 0;
-
-  word0 = (
-      ((OP_I2C_WRITE & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
-    | ((i2c_len & CS_LEN_MASK) << CS_LEN_SHIFT)
-    | ((i2c_addr & CS_I2CADDR_MASK) << CS_I2CADDR_SHIFT)
-  );
-
-  uint32_t *payload = (uint32_t *) (d_payload + p_len);
-   *payload = host_to_usrp_u32(word0);
-
-   // Jump over the first word and write the data
-   // FIXME: Should the data be changed to usrp byte order?
-   payload += 1;
-   memcpy(payload, i2c_data, data_len);
-
-  // Update payload length
-  incr_header_len(CS_FIXED_LEN + i2c_len);
-
-  return true;
-}
-
-/*!
- * \brief Adds an I2C read command to the current packet.
- *
- * The \p rid is the associated RID to return with the read response, \p
- * i2c_addr is the address to read from on the I2C bus, and \p n_bytes is the
- * number of bytes to be read from the bus.
- *
- * \returns true if the command was added to the packet, false otherwise.
- */
-bool usrp_inband_usb_packet::cs_i2c_read(long rid, long i2c_addr, long n_bytes)
-{
-  if(!align32())
-    return false;
-
-  int p_len = payload_len();
-
-  if((MAX_PAYLOAD - p_len) < (CS_I2CREAD_LEN + CS_FIXED_LEN))
-    return false;
-
-  uint32_t word0 = 0;
-  
-  word0 = ( 
-      ((OP_I2C_READ & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
-    | ((CS_I2CREAD_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
-    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
-    | ((i2c_addr & CS_I2CADDR_MASK) << CS_I2CADDR_SHIFT)
-    );
-
-  uint32_t *payload = (uint32_t *) (d_payload + p_len);
-  *payload = host_to_usrp_u32(word0);
-
-  // Jump a word and write the number of bytes to read
-  payload += 1;
-  uint32_t word1 = 
-    (n_bytes & CS_I2CREADBYTES_MASK) << CS_I2CREADBYTES_SHIFT;
-  *payload = host_to_usrp_u32(word1);
-
-  // Update payload length
-  incr_header_len(CS_FIXED_LEN + CS_I2CREAD_LEN);
-
-  return true;
-}
-
-/*!
- * \brief Adds an I2C read reply response to the current packet.  This is used
- * by the fake USRP code to generate fake I2C responses.
- *
- * The \p rid is the RID to be associated with the response, \p i2c_addr is the
- * address on the I2C bus that the \p i2c_data of \p i2c_data_len was read from.
- *
- * \returns true if the command was added to the packet, false otherwise.
- */
-bool usrp_inband_usb_packet::cs_i2c_read_reply(long rid, long i2c_addr, uint8_t *i2c_data, long i2c_data_len)
-{
-  if(!align32())
-    return false;
-
-  int p_len = payload_len();
-
-  int i2c_len = i2c_data_len + 2;
-
-  if((MAX_PAYLOAD - p_len) < (i2c_len + CS_FIXED_LEN)) 
-    return false;
-  
-  uint32_t word0 = 0;
-  
-  word0 = ( 
-      ((OP_I2C_READ_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
-    | ((i2c_len & CS_LEN_MASK) << CS_LEN_SHIFT)
-    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
-    | ((i2c_addr & CS_I2CADDR_MASK) << CS_I2CADDR_SHIFT)
-    );
-
-  uint32_t *payload = (uint32_t *) (d_payload + p_len);
-  *payload = host_to_usrp_u32(word0);
-
-  // Jump a word and write the actual data
-  payload += 1;
-  memcpy(payload, i2c_data, i2c_data_len);
-
-  // Update payload length
-  incr_header_len(CS_FIXED_LEN + i2c_len);
-
-  return true;
-}
-
-/*!
- * \brief Adds a SPI write command to the current packet.
- *
- * \returns true if the command was added to the packet, false otherwise.
- */
-bool usrp_inband_usb_packet::cs_spi_write(long enables, long format, long opt_header_bytes, uint8_t *spi_data, long spi_data_len)
-{
-  if(!align32())
-    return false;
-
-  int p_len = payload_len();
-
-  int spi_len = spi_data_len + 6;
-
-  if((MAX_PAYLOAD - p_len) < (spi_len + CS_FIXED_LEN))
-    return false;
-
-  uint32_t word = 0;
-
-  // First word contains the opcode and length, then mbz
-  word = (
-      ((OP_SPI_WRITE & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
-    | ((spi_len & CS_LEN_MASK) << CS_LEN_SHIFT)
-    );
-  uint32_t *payload = (uint32_t *) (d_payload + p_len);
-  *payload = host_to_usrp_u32(word);
-
-  payload += 1;
-
-  // Second word contains the enables, format, and optional tx bytes
-  word = 0;
-  word = (
-      ((enables & CS_SPIENABLES_MASK) << CS_SPIENABLES_SHIFT)
-    | ((format & CS_SPIFORMAT_MASK) << CS_SPIFORMAT_SHIFT)
-    | ((opt_header_bytes & CS_SPIOPT_MASK) << CS_SPIOPT_SHIFT)
-    );
-  payload = (uint32_t *) (d_payload + p_len);
-  *payload = host_to_usrp_u32(word);
-
-  payload += 1;
-  memcpy(payload, spi_data, spi_data_len);
-
-  // Update payload length
-  incr_header_len(CS_FIXED_LEN + spi_len);
-
-  return true;
-}
-
-/*!
- * \brief Adds a SPI bus read command to the packet.
- *
- * \returns true if the command was added to the packet, false otherwise.
- */
-bool usrp_inband_usb_packet::cs_spi_read(long rid, long enables, long format, long opt_header_bytes, long n_bytes)
-{
-  if(!align32())
-    return false;
-
-  int p_len = payload_len();
-
-  if((MAX_PAYLOAD - p_len) < (CS_SPIREAD_LEN + CS_FIXED_LEN))
-    return false;
-
-  uint32_t word = 0;
-
-  // First word contains the opcode, length, and RID
-  word = (
-      ((OP_SPI_READ & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
-    | ((CS_SPIREAD_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
-    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
-    );
-  uint32_t *payload = (uint32_t *) (d_payload + p_len);
-  *payload = host_to_usrp_u32(word);
-
-  payload += 1;
-
-  // Second word contains the enables, format, and optional tx bytes
-  word = 0;
-  word = (
-      ((enables & CS_SPIENABLES_MASK) << CS_SPIENABLES_SHIFT)
-    | ((format & CS_SPIFORMAT_MASK) << CS_SPIFORMAT_SHIFT)
-    | ((opt_header_bytes & CS_SPIOPT_MASK) << CS_SPIOPT_SHIFT)
-    );
-  payload = (uint32_t *) (d_payload + p_len);
-  *payload = host_to_usrp_u32(word);
-
-  payload += 1;
-
-  // The third word contains the number of bytes
-  word = 0;
-  word = (
-      ((n_bytes & CS_SPINBYTES_MASK) << CS_SPINBYTES_SHIFT)
-    );
-  payload = (uint32_t *) (d_payload + p_len);
-  *payload = host_to_usrp_u32(word);
-
-  // Update payload length
-  incr_header_len(CS_FIXED_LEN + CS_SPIREAD_LEN);
-
-  return true;
-}
-
-/*!
- * \brief Adds an SPI read reply to the current packet.  This is used by the
- * fake USRP code to generate fake responses for SPI reads.
- *
- * \returns true if the command was added to the packet, false otherwise.
- */
-bool usrp_inband_usb_packet::cs_spi_read_reply(long rid, uint8_t *spi_data, long spi_data_len)
-{
-  if(!align32())
-    return false;
-
-  int p_len = payload_len();
-
-  int spi_len = spi_data_len + 2;
-
-  if((MAX_PAYLOAD - p_len) < (spi_len + CS_FIXED_LEN))
-    return false;
-
-  uint32_t word = 0;
-
-  // First word contains the opcode, length, and RID
-  word = (
-      ((OP_SPI_READ_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
-    | ((spi_len & CS_LEN_MASK) << CS_LEN_SHIFT)
-    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
-    );
-  uint32_t *payload = (uint32_t *) (d_payload + p_len);
-  *payload = host_to_usrp_u32(word);
-
-  // Jump a word and write the actual data
-  payload += 1;
-  memcpy(payload, spi_data, spi_data_len);
-
-  // Update payload length
-  incr_header_len(CS_FIXED_LEN + spi_len);
-
-  return true;
-}
-
-/*!
- * \brief Since all control packets contain subpackets which have the length of
- * the subpacket at a uniform location in the subpacket, this will return the
- * subpacket length given a byte offset of the start of the subpacket from the beginning of the packet.
- *
- * \returns the length of the subpacket
- */
-int usrp_inband_usb_packet::cs_len(int payload_offset) {
-  uint32_t subpkt = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset)));
-  return (subpkt >> CS_LEN_SHIFT) & CS_LEN_MASK;
-}
-
-/*!
- * \brief The following method takes an offset within the packet payload to
- * extract a control/status subpacket and constructs a pmt response which
- * includes the proper signal and arguments specified by usrp-low-level-cs.  The
- * USRP server could therefore use this to read subpackets and pass them
- * responses back up to the application.  It's arguable that only reply packets
- * should be parsed here, however we parse others for use in debugging or
- * failure reporting on the transmit side of packets.
- */
-pmt_t usrp_inband_usb_packet::read_subpacket(int payload_offset) {
-
-  uint32_t subpkt = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset)));
-  uint32_t opcode = (subpkt >> CS_OPCODE_SHIFT) & CS_OPCODE_MASK;
-  uint32_t len = (subpkt >> CS_LEN_SHIFT) & CS_LEN_MASK;
-
-  switch(opcode) {
-    
-    case OP_PING_FIXED_REPLY:
-    {
-      pmt_t rid     = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
-      pmt_t pingval = pmt_from_long((subpkt >> CS_PINGVAL_SHIFT) & CS_PINGVAL_MASK);
-      return pmt_list3(s_op_ping_fixed_reply, rid, pingval);
-    }
-
-    case OP_READ_REG_REPLY:
-    {
-      pmt_t rid     = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
-      pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK);
-
-      // To get the register value we just read the next 32 bits
-      uint32_t val  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4)));
-      pmt_t reg_val = pmt_from_long(val);
-
-      return pmt_list4(s_op_read_reg_reply, rid, reg_num, reg_val);
-    }
-
-    case OP_I2C_READ_REPLY:
-    {
-      pmt_t rid       = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
-      pmt_t i2c_addr  = pmt_from_long((subpkt >> CS_I2CADDR_SHIFT) & CS_I2CADDR_MASK);
-
-      // Make a u8 vector to dump the data from the packet into
-      size_t i2c_data_len;
-      pmt_t i2c_data  = pmt_make_u8vector(len - 2, 0);   // skip rid+mbz+addr = 2 bytes
-      uint8_t *w_data  = 
-          (uint8_t *) pmt_u8vector_writable_elements(i2c_data, i2c_data_len);
-
-      memcpy(w_data, d_payload + payload_offset + 4, i2c_data_len);  // skip first word
-
-      return pmt_list4(s_op_i2c_read_reply, rid, i2c_addr, i2c_data);
-    }
-
-    case OP_SPI_READ_REPLY:
-    {
-      pmt_t rid       = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
-      
-      // Make a u8 vector to dump the data from the packet into
-      size_t spi_data_len;
-      pmt_t spi_data  = pmt_make_u8vector(len - 2, 0);   // skip rid+mbz+addr = 2 bytes
-      uint8_t *w_data  = 
-          (uint8_t *) pmt_u8vector_writable_elements(spi_data, spi_data_len);
-
-      memcpy(w_data, d_payload + payload_offset + 4, spi_data_len);  // skip first word
-
-      return pmt_list3(s_op_spi_read_reply, rid, spi_data);
-    }
-
-    case OP_PING_FIXED:
-    {
-      pmt_t rid     = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
-      pmt_t pingval = pmt_from_long((subpkt >> CS_PINGVAL_SHIFT) & CS_PINGVAL_MASK);
-      return pmt_list3(s_op_ping_fixed, rid, pingval);
-    }
-
-    case OP_WRITE_REG:
-    {
-      pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK);
-
-      // To get the register value we just read the next 32 bits
-      uint32_t val  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4)));
-      pmt_t reg_val = pmt_from_long(val);
-
-      return pmt_list3(s_op_write_reg, reg_num, reg_val);
-    }
-
-    case OP_WRITE_REG_MASKED:
-    {
-      pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK);
-
-      // To get the register value we just read the next 32 bits
-      uint32_t val  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4)));
-      pmt_t reg_val = pmt_from_long(val);
-
-      // The mask is the next 32 bits
-      uint32_t mask  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 8)));
-      pmt_t reg_mask = pmt_from_long(mask);
-
-      return pmt_list4(s_op_write_reg_masked, reg_num, reg_val, reg_mask);
-    }
-
-    case OP_READ_REG:
-    {
-      pmt_t rid     = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
-      pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK);
-
-      return pmt_list3(s_op_read_reg, rid, reg_num);
-    }
-
-    case OP_I2C_WRITE:
-    {
-      pmt_t i2c_addr    = pmt_from_long((subpkt >> CS_I2CADDR_SHIFT) & CS_I2CADDR_MASK);
-
-      // The length includes an extra 2 bytes for storing the mbz and addr
-      pmt_t i2c_data    = pmt_make_u8vector(len-2, 0);
-
-      // Get a writable address to copy the data from the packet
-      size_t ignore;
-      uint8_t *w_data = (uint8_t *) pmt_u8vector_writable_elements(i2c_data, ignore);
-      memcpy(w_data, d_payload + payload_offset + 4, len-2);
-
-      
-      return pmt_list3(s_op_i2c_write, i2c_addr, i2c_data);
-    }
-
-    case OP_I2C_READ:
-    {
-      pmt_t rid       = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
-      pmt_t i2c_addr  = pmt_from_long((subpkt >> CS_I2CADDR_SHIFT) & CS_I2CADDR_MASK);
-      
-      // The number of bytes is in the next word
-      uint32_t bytes  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4)));
-      bytes = (bytes >> CS_I2CREADBYTES_SHIFT) & CS_I2CREADBYTES_MASK;
-      pmt_t i2c_bytes = pmt_from_long(bytes);
-
-      return pmt_list4(s_op_i2c_read, rid, i2c_addr, i2c_bytes);
-    }
-
-    case OP_SPI_WRITE:
-    {
-      // Nothing interesting in the first word, skip to the next
-      uint32_t word  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4)));
-      pmt_t enables   = pmt_from_long((word >> CS_SPIENABLES_SHIFT) & CS_SPIENABLES_MASK);
-      pmt_t format    = pmt_from_long((word >> CS_SPIFORMAT_SHIFT) & CS_SPIFORMAT_MASK);
-      pmt_t opt       = pmt_from_long((word >> CS_SPIOPT_SHIFT) & CS_SPIOPT_MASK);
-
-      // From the next word and on is data
-      size_t spi_data_len;
-      pmt_t spi_data  = pmt_make_u8vector(len - 6, 0);   // skip rid+mbz+addr = 2 bytes
-      uint8_t *w_data  = 
-          (uint8_t *) pmt_u8vector_writable_elements(spi_data, spi_data_len);
-
-      memcpy(w_data, d_payload + payload_offset + 8, spi_data_len);  // skip first 2 words
-
-      return pmt_list5(s_op_spi_write, enables, format, opt, spi_data);
-    }
-
-    case OP_SPI_READ:
-    {
-      // Read the RID from the first word, the rest is mbz
-      pmt_t rid       = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
-
-      // Continue at the next word...
-      uint32_t word  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4)));
-      pmt_t enables   = pmt_from_long((word >> CS_SPIENABLES_SHIFT) & CS_SPIENABLES_MASK);
-      pmt_t format    = pmt_from_long((word >> CS_SPIFORMAT_SHIFT) & CS_SPIFORMAT_MASK);
-      pmt_t opt       = pmt_from_long((word >> CS_SPIOPT_SHIFT) & CS_SPIOPT_MASK);
-
-      // The number of bytes is the only thing to read in the next word
-      word  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 8)));
-      pmt_t n_bytes   = pmt_from_long((word >> CS_SPINBYTES_SHIFT) & CS_SPINBYTES_MASK);
-
-      return pmt_list6(s_op_spi_read, rid, enables, format, opt, n_bytes);
-    }
-
-    case OP_DELAY:
-    {
-      pmt_t ticks = pmt_from_long((subpkt >> CS_DELAY_SHIFT) & CS_DELAY_MASK);
-
-      return pmt_list2(s_op_delay, ticks);
-    }
-    
-    default:
-      return PMT_NIL;
-
-  }
-}
-
diff --git a/usrp/host/lib/inband/usrp_inband_usb_packet.h b/usrp/host/lib/inband/usrp_inband_usb_packet.h
deleted file mode 100644 (file)
index 6f1a3fe..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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_INBAND_USB_PACKET_H_
-#define INCLUDED_USRP_INBAND_USB_PACKET_H_
-
-#include <usrp_bytesex.h>
-#include <mblock/mblock.h>
-#include <pmt.h>
-#include <iostream>
-
-#include <symbols_usrp_low_level_cs.h>
-
-static const int USB_PKT_SIZE = 512;   // bytes
-static const int MAX_PAYLOAD = USB_PKT_SIZE-2*sizeof(uint32_t);
-static const int CONTROL_CHAN = 0x1f;
-
-class usrp_inband_usb_packet {
-  //
-  // keep raw packet in USRP-endian order
-  //
-  uint32_t           d_word0;
-  uint32_t           d_timestamp;
-  unsigned char          d_payload[MAX_PAYLOAD];
-
-public:
-
-  enum opcodes {
-    OP_PING_FIXED         = 0x00,
-    OP_PING_FIXED_REPLY   = 0x01,
-    OP_WRITE_REG          = 0x02,
-    OP_WRITE_REG_MASKED   = 0x03,
-    OP_READ_REG           = 0x04,
-    OP_READ_REG_REPLY     = 0x05,
-    OP_I2C_WRITE          = 0x06,
-    OP_I2C_READ           = 0x07,
-    OP_I2C_READ_REPLY     = 0x08,
-    OP_SPI_WRITE          = 0x09,
-    OP_SPI_READ           = 0x0a,
-    OP_SPI_READ_REPLY     = 0x0b,
-    OP_DELAY              = 0x0c
-  };
-
-  enum flags {
-    FL_OVERRUN        = 0x80000000,
-    FL_UNDERRUN       = 0x40000000,
-    FL_DROPPED        = 0x20000000,
-    FL_START_OF_BURST = 0x10000000,
-    FL_END_OF_BURST   = 0x08000000,
-    FL_CARRIER_SENSE  = 0x04000000,
-
-    FL_ALL_FLAGS      = 0xfc000000
-  };
-
-  static const int FL_OVERRUN_SHIFT = 31;
-  static const int FL_UNDERRUN_SHIFT = 30;
-  static const int FL_DROPPED_SHIFT = 29;
-  static const int FL_END_OF_BURST_SHIFT = 27;
-  static const int FL_START_OF_BURST_SHIFT = 28;
-  
-  static const int RSSI_MASK = 0x3f;
-  static const int RSSI_SHIFT = 21;
-
-  static const int CHAN_MASK = 0x1f;
-  static const int CHAN_SHIFT = 16;
-
-  static const int TAG_MASK = 0xf;
-  static const int TAG_SHIFT = 9;
-
-  static const int PAYLOAD_LEN_MASK = 0x1ff;
-  static const int PAYLOAD_LEN_SHIFT = 0;
-
-  // Fixed size for opcode and length fields
-  static const int CS_FIXED_LEN = 2;
-
-  static const int CS_OPCODE_MASK = 0xff;
-  static const int CS_OPCODE_SHIFT = 24;
-
-  static const int CS_LEN_MASK = 0xff;
-  static const int CS_LEN_SHIFT = 16;
-
-  static const int CS_RID_MASK = 0x3f;
-  static const int CS_RID_SHIFT = 10;
-
-  static const int CS_PING_LEN = 2;
-  static const int CS_PINGVAL_MASK = 0x3ff;
-  static const int CS_PINGVAL_SHIFT = 0;
-
-  static const int CS_WRITEREG_LEN = 6;
-  static const int CS_WRITEREGMASKED_LEN = 10;
-  static const int CS_READREG_LEN = 2;
-  static const int CS_READREGREPLY_LEN = 6;
-  static const int CS_REGNUM_MASK = 0x3ff;
-  static const int CS_REGNUM_SHIFT = 0;
-
-  static const int CS_DELAY_LEN = 2;
-  static const int CS_DELAY_MASK = 0xffff;
-  static const int CS_DELAY_SHIFT = 0;
-
-  static const int CS_I2CADDR_MASK = 0x7f;
-  static const int CS_I2CADDR_SHIFT = 0;
-
-  static const int CS_I2CREAD_LEN = 3;
-  static const int CS_I2CREADBYTES_MASK = 0x7f;
-  static const int CS_I2CREADBYTES_SHIFT = 24;
-
-  static const int CS_SPIOPT_MASK = 0xffff;
-  static const int CS_SPIOPT_SHIFT = 0;
-  static const int CS_SPIFORMAT_MASK = 0xff;
-  static const int CS_SPIFORMAT_SHIFT = 16;
-  static const int CS_SPIENABLES_MASK = 0xff;
-  static const int CS_SPIENABLES_SHIFT = 24;
-  static const int CS_SPIREAD_LEN = 7;
-  static const int CS_SPINBYTES_MASK = 0xff;
-  static const int CS_SPINBYTES_SHIFT = 24;
-
-public:
-  
-  void set_timestamp(uint32_t timestamp){
-    d_timestamp = host_to_usrp_u32(timestamp);
-  }
-
-  void set_end_of_burst() {
-    uint32_t word0 = usrp_to_host_u32(d_word0);
-    word0 |= 1<<FL_END_OF_BURST_SHIFT;
-    d_word0 = host_to_usrp_u32(word0);
-  }
-  
-  void set_header(int flags, int chan, int tag, int payload_len){
-    uint32_t word0 =  ((flags & FL_ALL_FLAGS)
-                       | ((chan & CHAN_MASK) << CHAN_SHIFT)
-                       | ((tag & TAG_MASK) << TAG_SHIFT)
-                       | ((payload_len & PAYLOAD_LEN_MASK) << PAYLOAD_LEN_SHIFT));
-    d_word0 = host_to_usrp_u32(word0);
-  }
-
-  void incr_header_len(int val) {
-    set_header(flags(), chan(), tag(), payload_len() + val);
-  }
-  
-  uint32_t timestamp() const {
-    return usrp_to_host_u32(d_timestamp);
-  }
-
-  int rssi() const {
-    uint32_t word0 = usrp_to_host_u32(d_word0);
-    return (word0 >> RSSI_SHIFT) & RSSI_MASK;
-  }
-
-  int chan() const {
-    uint32_t word0 = usrp_to_host_u32(d_word0);
-    return (word0 >> CHAN_SHIFT) & CHAN_MASK;
-  }
-
-  int tag() const {
-    uint32_t word0 = usrp_to_host_u32(d_word0);
-    return (word0 >> TAG_SHIFT) & TAG_MASK;
-  }
-
-  int payload_len() const {
-    uint32_t word0 = usrp_to_host_u32(d_word0);
-    return (word0 >> PAYLOAD_LEN_SHIFT) & PAYLOAD_LEN_MASK;
-  }
-  
-  int flags() const {
-    return usrp_to_host_u32(d_word0) & FL_ALL_FLAGS;
-  }
-
-  int overrun() const {
-    return (usrp_to_host_u32(d_word0) & FL_OVERRUN) >> FL_OVERRUN_SHIFT;
-  }
-  
-
-  int underrun() const {
-    return (usrp_to_host_u32(d_word0) & FL_UNDERRUN) >> FL_UNDERRUN_SHIFT;
-  }
-
-
-  int start_of_burst() const {
-    return (usrp_to_host_u32(d_word0) & FL_START_OF_BURST) >> FL_START_OF_BURST_SHIFT;
-  }
-
-  int end_of_burst() const {
-    return (usrp_to_host_u32(d_word0) & FL_END_OF_BURST) >> FL_END_OF_BURST_SHIFT;
-  }
-
-  int dropped() const {
-    return (usrp_to_host_u32(d_word0) & FL_DROPPED) >> FL_DROPPED_SHIFT;
-  }
-
-  unsigned char *payload() { 
-    return d_payload; 
-  }
-
-  static int max_payload() {
-    return MAX_PAYLOAD;
-  }
-
-  static int max_pkt_size() {
-    return USB_PKT_SIZE;
-  }
-
-  // C/S methods
-  bool align32();
-  bool cs_ping(long rid, long ping_val);
-  bool cs_ping_reply(long rid, long ping_val);
-  bool cs_write_reg(long reg_num, long val);
-  bool cs_write_reg_masked(long reg_num, long val, long mask);
-  bool cs_read_reg(long rid, long reg_num);
-  bool cs_read_reg_reply(long rid, long reg_num, long reg_val);
-  bool cs_delay(long ticks);
-  bool cs_i2c_write(long i2c_addr, uint8_t *i2c_data, size_t data_len);
-  bool cs_i2c_read(long rid, long i2c_addr, long n_bytes);
-  bool cs_i2c_read_reply(long rid, long i2c_addr, uint8_t *i2c_data, long i2c_data_len);
-  bool cs_spi_write(long enables, long format, long opt_header_bytes, uint8_t *spi_data, long spi_data_len);
-  bool cs_spi_read(long rid, long enables, long format, long opt_header_bytes, long n_bytes);
-  bool cs_spi_read_reply(long rid, uint8_t *spi_data, long spi_data_len);
-  int cs_len(int payload_offset);
-  pmt_t read_subpacket(int payload_offset);
-};
-
-#endif
diff --git a/usrp/host/lib/inband/usrp_interface.mbh b/usrp/host/lib/inband/usrp_interface.mbh
deleted file mode 100644 (file)
index ad0f78b..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-;; -*- scheme -*- ; not really, but tells emacs how to format this
-;;
-;; 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 this program; if not, write to the Free Software Foundation, Inc.,
-;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-;;
-
-;; ----------------------------------------------------------------
-;;              This is an mblock header file
-;;
-;; The format is very much a work-in-progress.
-;; It'll be compiled to C++.
-;; ----------------------------------------------------------------
-
-;; ----------------------------------------------------------------
-;; usrp-interface-cs
-;;
-;; Handles interaction between the usrp_sever and the USB interface
-
-(define-protocol-class usrp-interface-cs
-
-  (:outgoing
-   (cmd-usrp-open invocation-handle which-usrp)
-   (cmd-usrp-close invocation-handle)
-   (cmd-usrp-ntx-chan invocation-handle)
-   (cmd-usrp-nrx-chan invocation-handle)
-   (cmd-usrp-write invocation-handle channel data)
-   (cmd-usrp-start-reading invocation-handle channel)
-   )
-
-  (:incoming
-   (response-usrp-open invocation-handle status)
-   (response-usrp-close invocation-handle status)
-   (response-usrp-ntx-chan invocation-handle ntx-chan)
-   (response-usrp-nrx-chan invocation-handle nrx-chan)
-   (response-usrp-write invocation-handle status channel)
-   (response-usrp-read invocation-handle status data)
-   )
-  )
-
-;; ----------------------------------------------------------------
-;; usrp-tx-cs
-;;
-;; Handles interaction between the USB interface and TX interface
-
-(define-protocol-class usrp-tx-cs
-
-  (:outgoing
-   (cmd-usrp-tx-write invocation-handle channel data tx-handle)
-   )
-
-  (:incoming
-   (response-usrp-tx-write invocation-handle status channel)
-   )
-  )
-
-;; ----------------------------------------------------------------
-;; usrp-rx-cs
-;;
-;; Handles interaction between the USB interface and RX interface
-
-(define-protocol-class usrp-rx-cs
-
-  (:outgoing
-   (cmd-usrp-rx-start-reading invocation-handle rx-handle)
-   (cmd-usrp-rx-stop-reading invocation-handle)
-   )
-
-  (:incoming
-   (response-usrp-rx-read invocation-handle status data)
-
-   ;; There is currently no response to a stop reading
-   )
-  )
diff --git a/usrp/host/lib/inband/usrp_rx.cc b/usrp/host/lib/inband/usrp_rx.cc
deleted file mode 100644 (file)
index fe9486c..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 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_rx.h>
-
-#include <usrp_standard.h>
-#include <iostream>
-#include <vector>
-#include <usb.h>
-#include <mblock/class_registry.h>
-#include <usrp_inband_usb_packet.h>
-#include <fpga_regs_common.h>
-#include <stdio.h>
-
-#include <symbols_usrp_rx_cs.h>
-
-typedef usrp_inband_usb_packet transport_pkt;
-
-static const bool verbose = false;
-
-bool usrp_rx_stop;
-
-usrp_rx::usrp_rx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(rt, instance_name, user_arg),
-    d_disk_write(false),
-    d_disk_write_pkt(false)   // if true, writes full packet, else just the payload
-{
-  d_cs = define_port("cs", "usrp-rx-cs", true, mb_port::EXTERNAL);
-  
-  if(d_disk_write) {
-    d_ofile0.open("rx_data_chan0.dat",std::ios::binary|std::ios::out);
-    d_ofile1.open("rx_data_chan1.dat",std::ios::binary|std::ios::out);
-    d_cs_ofile.open("rx_cs.dat",std::ios::binary|std::ios::out);
-  }
-  
-  usrp_rx_stop = false;
-
-}
-
-usrp_rx::~usrp_rx() 
-{
-  if(d_disk_write) {
-    d_ofile0.close();
-    d_ofile1.close();
-    d_cs_ofile.close();
-  }
-}
-
-void 
-usrp_rx::initial_transition()
-{
-  
-}
-
-/*!
- * \brief Handles incoming signals to to the m-block, wihch should only ever be
- * a single message: cmd-usrrp-rx-start-reading.  There is no signal to stop
- * reading as the m-block goes in to a forever loop to read inband packets from
- * the bus.
- */
-void
-usrp_rx::handle_message(mb_message_sptr msg)
-{
-  pmt_t event = msg->signal();
-  pmt_t port_id = msg->port_id();
-  pmt_t data = msg->data(); 
-
-  // Theoretically only have 1 message to ever expect, but
-  // want to make sure its at least what we want
-  if(pmt_eq(port_id, d_cs->port_symbol())) {
-    
-    if(pmt_eqv(event, s_cmd_usrp_rx_start_reading))
-      read_and_respond(data);
-  }
-}
-
-/*!
- * \brief Performs the actual reading of data from the USB bus, called by
- * handle_message() when a cmd-usrp-rx-start-reading signal is received.  
- *
- * The method enters a forever loop where it continues to read data from the bus
- * and generate read responses to the higher layer.  Currently, shared memory is
- * used to exit this loop.
- *
- * The \p data parameter is a PMT list which contains only a single element, an
- * invocation handle which will be returned with all read respones.
- */
-void
-usrp_rx::read_and_respond(pmt_t data)
-{
-  size_t ignore;
-  bool underrun;
-  unsigned int n_read;
-  unsigned int pkt_size = sizeof(transport_pkt);
-
-  pmt_t invocation_handle = pmt_nth(0, data);
-
-  // Need the handle to the RX port to send responses, this is passed
-  // by the USRP interface m-block
-  pmt_t handle = pmt_nth(1, data);
-  d_urx = 
-    boost::any_cast<usrp_standard_rx_sptr>(pmt_any_ref(handle));
-
-  if(verbose)
-    std::cout << "[usrp_rx] Waiting for packets..\n";
-
-  // Read by 512 which is packet size and send them back up
-  while(!usrp_rx_stop) {
-
-    pmt_t v_pkt = pmt_make_u8vector(pkt_size, 0);
-    transport_pkt *pkt = 
-      (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, ignore);
-
-    n_read = d_urx->read(pkt, pkt_size, &underrun);
-
-    if(n_read != pkt_size) {
-      std::cerr << "[usrp_rx] Error reading packet, shutting down\n";
-      d_cs->send(s_response_usrp_rx_read, 
-                 pmt_list3(PMT_NIL, PMT_F, PMT_NIL));
-      return;
-    }
-
-    if(underrun && verbose && 0)
-      std::cout << "[usrp_rx] Underrun\n";
-
-    d_cs->send(s_response_usrp_rx_read, 
-               pmt_list3(PMT_NIL, PMT_T, v_pkt));
-    if(verbose && 0)
-      std::cout << "[usrp_rx] Read 1 packet\n";
-    
-    if(d_disk_write) {
-      if(pkt->chan() == CONTROL_CHAN)
-        d_cs_ofile.write((const char *)pkt, transport_pkt::max_pkt_size());
-      else {
-        if(d_disk_write_pkt) {
-          if(pkt->chan() == 0)
-            d_ofile0.write((const char *)pkt, transport_pkt::max_pkt_size());
-          else if(pkt->chan() == 1)
-            d_ofile1.write((const char *)pkt, transport_pkt::max_pkt_size());
-        } else {
-          if(pkt->chan() == 0)
-            d_ofile0.write((const char *)pkt->payload(), transport_pkt::max_payload());
-          else if(pkt->chan() == 1)
-            d_ofile1.write((const char *)pkt->payload(), transport_pkt::max_payload());
-        }
-      }
-
-      d_cs_ofile.flush();
-      d_ofile0.flush();
-      d_ofile1.flush();
-    }
-  }
-  
-  usrp_rx_stop = false;
-
-  if(verbose) {
-    std::cout << "[USRP_RX] Stopping...\n";
-    fflush(stdout);
-  }
-}
-
-REGISTER_MBLOCK_CLASS(usrp_rx);
diff --git a/usrp/host/lib/inband/usrp_rx.h b/usrp/host/lib/inband/usrp_rx.h
deleted file mode 100644 (file)
index 1006235..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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_RX_H
-#define INCLUDED_USRP_RX_H
-
-#include <mblock/mblock.h>
-#include <fstream>
-#include "usrp_standard.h"
-
-extern bool usrp_rx_stop;   // used to communicate a 'stop' to the RX stub
-
-/*!
- * \brief Implements the low level usb interface to the USRP
- */
-class usrp_rx : public mb_mblock
-{
-  mb_port_sptr         d_cs;
-  usrp_standard_rx_sptr     d_urx;
-  
-  bool d_disk_write;
-  bool d_disk_write_pkt;
-  std::ofstream d_ofile0;
-  std::ofstream d_ofile1;
-  std::ofstream d_cs_ofile;
-  
- public:
-  usrp_rx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg);
-  ~usrp_rx();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- private:
-  void read_and_respond(pmt_t data);
-  void read_data();
-};
-  
-
-#endif /* INCLUDED_USRP_RX_H */
-
diff --git a/usrp/host/lib/inband/usrp_rx_stub.cc b/usrp/host/lib/inband/usrp_rx_stub.cc
deleted file mode 100644 (file)
index e5c454d..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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_rx_stub.h>
-
-#include <iostream>
-#include <vector>
-#include <usb.h>
-#include <mblock/class_registry.h>
-#include <usrp_inband_usb_packet.h>
-#include <fpga_regs_common.h>
-#include "usrp_standard.h"
-#include <stdio.h>
-#include <string.h>
-#include <ui_nco.h>
-#include <fstream>
-
-#include <symbols_usrp_rx_cs.h>
-
-typedef usrp_inband_usb_packet transport_pkt;
-
-static const bool verbose = false;
-
-bool usrp_rx_stop_stub;
-
-// Used for the fake control packet response code to send the responses back up
-// the RX.  The TX stub dumps responses in to this queue.
-std::queue<pmt_t> d_cs_queue;
-
-usrp_rx_stub::usrp_rx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(rt, instance_name, user_arg),
-    d_samples_per_frame((long)(126)),
-    d_decim_rx(128),
-    d_amplitude(16384),
-    d_disk_write(false)
-{
-
-  // Information about the rates are passed all the way from the app in the form
-  // of a dictionary.  We use this to read the RX decimation rate and compute
-  // the approximate number of MS/s as a form of flow control for the stub.
-  pmt_t usrp_dict = user_arg;
-
-  if (pmt_is_dict(usrp_dict)) {
-    // Read the RX decimation rate
-    if(pmt_t decim_rx = pmt_dict_ref(usrp_dict, 
-                                      pmt_intern("decim-rx"), 
-                                      PMT_NIL)) {
-      if(!pmt_eqv(decim_rx, PMT_NIL)) 
-        d_decim_rx = pmt_to_long(decim_rx);
-    }
-  }
-
-  d_cs = define_port("cs", "usrp-rx-cs", true, mb_port::EXTERNAL);
-  
-  // initialize NCO
-  double freq = 100e3;
-  int interp = 32;                         // 32 -> 4MS/s
-  double sample_rate = 64e6 / interp;  
-  d_nco.set_freq(2*M_PI * freq/sample_rate);
-
-  //d_disk_write = true;
-  
-  if(d_disk_write)
-    d_ofile.open("raw_rx.dat",std::ios::binary|std::ios::out);
-  
-  usrp_rx_stop_stub = false;
-}
-
-usrp_rx_stub::~usrp_rx_stub() 
-{
-  if(d_disk_write)
-    d_ofile.close();
-}
-
-void 
-usrp_rx_stub::initial_transition()
-{
-}
-
-void
-usrp_rx_stub::handle_message(mb_message_sptr msg)
-{
-  pmt_t event = msg->signal();
-  pmt_t port_id = msg->port_id();
-  pmt_t data = msg->data(); 
-
-  if (pmt_eq(msg->signal(), s_timeout)
-      && !pmt_eq(msg->data(), s_done)) {
-  
-    if(!usrp_rx_stop_stub) 
-      read_and_respond();
-    else {  // requested to stop
-      cancel_timeout(msg->metadata());
-      usrp_rx_stop_stub=false;
-      if(verbose)
-        std::cout << "[USRP_RX_STUB] Stopping RX stub\n";
-    }
-
-  }
-
-  // Theoretically only have 1 message to ever expect, but
-  // want to make sure its at least what we want
-  if(pmt_eq(port_id, d_cs->port_symbol())
-      && pmt_eqv(event, s_cmd_usrp_rx_start_reading)) {
-
-    if(verbose)
-      std::cout << "[USRP_RX_STUB] Starting with decim @ " 
-                << d_decim_rx << std::endl;
-    
-      start_packet_timer();
-  }
-}
-
-// Setup a periodic timer which will drive packet generation
-void
-usrp_rx_stub::start_packet_timer()
-{
-  d_t0 = mb_time::time();   // current time
-
-  // Calculate the inter-packet arrival time.  
-  double samples_per_sec = (64.0/(double)d_decim_rx)*1000000.0;
-  double frames_per_sec = samples_per_sec / (double)d_samples_per_frame;
-  double frame_rate = 1.0 / frames_per_sec;
-
-  if(verbose) {
-    std::cout << "[USRP_RX_STUB] Scheduling periodic packet generator\n";
-    std::cout << "\tsamples_per_sec: " << samples_per_sec << std::endl;
-    std::cout << "\tframes_per_sec: " << frames_per_sec << std::endl;
-    std::cout << "\tframe_rate: " << frame_rate << std::endl;
-  }
-
-  schedule_periodic_timeout(d_t0 + frame_rate, mb_time(frame_rate), PMT_T);
-}
-
-void
-usrp_rx_stub::read_and_respond()
-{
-
-  long nsamples_this_frame = d_samples_per_frame;
-
-  size_t nshorts = 2 * nsamples_this_frame;    // 16-bit I & Q
-  long channel = 0;
-  long n_bytes = nshorts*2;
-  pmt_t uvec = pmt_make_s16vector(nshorts, 0);
-  size_t ignore;
-  int16_t *samples = pmt_s16vector_writable_elements(uvec, ignore);
-
-  // fill in the complex sinusoid
-
-  for (int i = 0; i < nsamples_this_frame; i++){
-
-    if (1){
-      gr_complex s;
-      d_nco.sincos(&s, 1, d_amplitude);
-      // write 16-bit i & q
-      samples[2*i] =   (int16_t) s.real();
-      samples[2*i+1] = (int16_t) s.imag();
-    }
-    else {
-      gr_complex s(d_amplitude, d_amplitude);
-
-      // write 16-bit i & q
-      samples[2*i] =   (int16_t) s.real();
-      samples[2*i+1] = (int16_t) s.imag();
-    }
-  }
-  
-  if(d_disk_write)
-    d_ofile.write((const char *)samples, n_bytes);
-
-  pmt_t v_pkt = pmt_make_u8vector(sizeof(transport_pkt), 0);
-  transport_pkt *pkt =
-    (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, ignore);
-
-  pkt->set_header(0, channel, 0, n_bytes);
-  pkt->set_timestamp(0xffffffff);
-  memcpy(pkt->payload(), samples, n_bytes);
-  
-  d_cs->send(s_response_usrp_rx_read, pmt_list3(PMT_NIL, PMT_T, v_pkt));
-
-  // Now lets check the shared CS queue between the TX and RX stub.  Each
-  // element in a queue is a list where the first element is an invocation
-  // handle and the second element is a PMT u8 vect representation of the
-  // CS packet response which can just be passed transparently.
-  while(!d_cs_queue.empty()) {
-    
-    pmt_t cs_pkt = d_cs_queue.front();
-    d_cs_queue.pop();
-
-    pmt_t invocation_handle = pmt_nth(0, cs_pkt);
-    pmt_t v_pkt = pmt_nth(1, cs_pkt);
-
-    d_cs->send(s_response_usrp_rx_read,   
-               pmt_list3(invocation_handle, 
-                         PMT_T, 
-                         v_pkt));  // Take the front CS pkt
-
-    
-    if(verbose)
-      std::cout << "[USRP_RX_STUB] Received CS response from TX stub\n";
-  }
-
-}
-
-REGISTER_MBLOCK_CLASS(usrp_rx_stub);
diff --git a/usrp/host/lib/inband/usrp_rx_stub.h b/usrp/host/lib/inband/usrp_rx_stub.h
deleted file mode 100644 (file)
index 238b456..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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_RX_STUB_H
-#define INCLUDED_USRP_RX_STUB_H
-
-#include <mblock/mblock.h>
-#include <vector>
-#include "usrp_standard.h"
-#include <ui_nco.h>
-#include <fstream>
-#include <queue>
-#include <usrp_inband_usb_packet.h>
-
-typedef usrp_inband_usb_packet transport_pkt;
-
-extern bool usrp_rx_stop_stub;   // used to communicate a 'stop' to the RX stub
-extern std::queue<pmt_t> d_cs_queue;
-
-static pmt_t s_timeout = pmt_intern("%timeout");
-static pmt_t s_done = pmt_intern("done");
-
-/*!
- * \brief Implements the low level usb interface to the USRP
- */
-class usrp_rx_stub : public mb_mblock
-{
- public:
-
-  mb_port_sptr d_cs;
-  usrp_standard_rx* d_urx;
-  
-  long         d_samples_per_frame;
-  long    d_decim_rx;
-
-  mb_time d_t0;
-  double d_delta_t;
-  
-  // for generating sine wave output
-  ui_nco<float,float>  d_nco;
-  double               d_amplitude;
-
-  bool d_disk_write;
-
-  std::ofstream d_ofile;
-  
- public:
-  usrp_rx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg);
-  ~usrp_rx_stub();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- private:
-  void read_and_respond();
-  void read_data();
-  void start_packet_timer();
-};
-  
-
-#endif /* INCLUDED_USRP_RX_H */
-
diff --git a/usrp/host/lib/inband/usrp_server.cc b/usrp/host/lib/inband/usrp_server.cc
deleted file mode 100644 (file)
index ac26363..0000000
+++ /dev/null
@@ -1,1860 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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_server.h>
-#include <iostream>
-#include <usrp_inband_usb_packet.h>
-#include <mblock/class_registry.h>
-#include <vector>
-#include <usrp_usb_interface.h>
-#include <string.h>
-#include <fpga_regs_common.h>
-#include <fpga_regs_standard.h>
-
-#include <symbols_usrp_server_cs.h>
-#include <symbols_usrp_channel.h>
-#include <symbols_usrp_tx.h>
-#include <symbols_usrp_rx.h>
-#include <symbols_usrp_low_level_cs.h>
-#include <symbols_usrp_interface_cs.h>
-
-static pmt_t s_shutdown = pmt_intern("%shutdown");
-
-typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit easy
-
-const static bool verbose = false;
-
-static std::string
-str(long x)
-{
-  std::ostringstream s;
-  s << x;
-  return s.str();
-}
-
-usrp_server::usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(rt, instance_name, user_arg),
-  d_fpga_debug(false),
-  d_interp_tx(128),     // these should match the lower level defaults (rx also)
-  d_decim_rx(128),
-  d_fake_rx(false)
-{
-  if(verbose)
-    std::cout << "[USRP_SERVER] Initializing...\n";
-
-  // Dictionary for arguments to all of the components
-  d_usrp_dict = user_arg;
-  
-  if (pmt_is_dict(d_usrp_dict)) {
-
-    if(pmt_t fpga_debug = pmt_dict_ref(d_usrp_dict, 
-                                      pmt_intern("fpga-debug"), 
-                                      PMT_NIL)) {
-      if(pmt_eqv(fpga_debug, PMT_T)) 
-        d_fpga_debug=true;
-    }
-    
-    // Read the TX interpolations
-    if(pmt_t interp_tx = pmt_dict_ref(d_usrp_dict, 
-                                      pmt_intern("interp-tx"), 
-                                      PMT_NIL)) {
-      if(!pmt_eqv(interp_tx, PMT_NIL)) 
-        d_interp_tx = pmt_to_long(interp_tx);
-    }
-    
-    // Read the RX decimation rate
-    if(pmt_t decim_rx = pmt_dict_ref(d_usrp_dict, 
-                                      pmt_intern("decim-rx"), 
-                                      PMT_NIL)) {
-      if(!pmt_eqv(decim_rx, PMT_NIL)) 
-        d_decim_rx = pmt_to_long(decim_rx);
-    }
-  }
-  
-  // control & status port
-  d_cs = define_port("cs", "usrp-server-cs", true, mb_port::EXTERNAL); 
-  d_cs_usrp = define_port("cs_usrp", "usrp-interface-cs", false, mb_port::INTERNAL);   
-
-  // ports
-  //
-  // (if/when we do replicated ports, these will be replaced by a
-  //  single replicated port)
-  for(int port=0; port < N_PORTS; port++) {
-
-    d_tx.push_back(define_port("tx"+str(port), 
-                               "usrp-tx", 
-                               true, 
-                               mb_port::EXTERNAL));
-
-    d_rx.push_back(define_port("rx"+str(port), 
-                               "usrp-rx", 
-                               true, 
-                               mb_port::EXTERNAL));
-  }
-
-  define_component("usrp", "usrp_usb_interface", d_usrp_dict);
-  connect("self", "cs_usrp", "usrp", "cs");
-
-  d_defer=false;
-  d_opened=false;
-
-  // FIXME: needs to be returned from open, if we want to use this
-  d_nrx_chan = 2;
-  d_ntx_chan = 2;
-
-  // Initialize capacity on each channel to 0 and to no owner
-  // Also initialize the USRP standard tx/rx pointers to NULL
-  for(int chan=0; chan < d_ntx_chan; chan++)
-    d_chaninfo_tx.push_back(channel_info());
-
-  for(int chan=0; chan < d_nrx_chan; chan++)
-    d_chaninfo_rx.push_back(channel_info());
-
-  d_rx_chan_mask = 0;
-
-  for(int i=0; i < D_MAX_RID; i++) 
-    d_rids.push_back(rid_info());
-
-  //d_fake_rx=true;
-}
-
-/*!
- * \brief resets the assigned capacity and owners of each RX and TX channel from
- * allocations.
- */
-void
-usrp_server::reset_channels()
-{
-
-  for(int chan=0; chan < d_ntx_chan; chan++) {
-    d_chaninfo_tx[chan].assigned_capacity = 0;
-    d_chaninfo_tx[chan].owner = PMT_NIL;
-  }
-
-  for(int chan=0; chan < d_nrx_chan; chan++) {
-    d_chaninfo_rx[chan].assigned_capacity = 0;
-    d_chaninfo_rx[chan].owner = PMT_NIL;
-  }
-
-  d_rx_chan_mask = 0;
-}
-
-usrp_server::~usrp_server()
-{
-}
-
-
-void
-usrp_server::initial_transition()
-{
-  // the initial transition
-}
-
-/*!
- * \brief Reads all incoming messages to USRP server from the TX, RX, and the CS
- * ports.  This drives the state of USRP server and dispatches based on the
- * message.
- */
-void
-usrp_server::handle_message(mb_message_sptr msg)
-{
-  pmt_t event = msg->signal();         // the "name" of the message
-  pmt_t port_id = msg->port_id();      // which port it came in on
-  pmt_t data = msg->data();
-  pmt_t invocation_handle;
-  pmt_t metadata = msg->metadata();
-  pmt_t status;
-
-  long port;
-
-  if (pmt_eq(event, s_shutdown))       // ignore (for now)
-    return;
-
-  invocation_handle = pmt_nth(0, data);
-
-  if (0){
-    std::cout << "[USRP_SERVER] event: " << event << std::endl;
-    std::cout << "[USRP_SERVER] port_id: " << port_id << std::endl;
-  }
-
-  // It would be nice if this were all table driven, and we could compute our
-  // state transition as f(current_state, port_id, signal)
-  
-  // A message from the USRP CS, which should *only* be responses
-  //
-  // It is important that this set come before checking messages of any other
-  // components.  This is since we always want to listen to the low level USRP
-  // server, even if we aren't initialized we are waiting for responses to
-  // become initialized.  Likewise, after the usrp_server is "closed", we still
-  // want to pass responses back from the low level.
-
-  //---------------- USRP RESPONSE ---------------//
-  if (pmt_eq(port_id, d_cs_usrp->port_symbol())) { 
-    
-    //-------------- USRP OPEN ------------------//
-    if(pmt_eq(event, s_response_usrp_open)) {
-      // pass the response back over the regular CS port
-      pmt_t status = pmt_nth(1, data);
-      d_cs->send(s_response_open, pmt_list2(invocation_handle, status));
-
-      //reset_all_registers();
-      //initialize_registers();
-
-      if(pmt_eqv(status,PMT_T)) {
-        d_opened = true;
-        d_defer = false;
-        recall_defer_queue();
-      }
-
-      return;
-    }
-    //------------- USRP CLOSE -------------------//
-    else if (pmt_eq(event, s_response_usrp_close)) {
-      pmt_t status = pmt_nth(1, data);
-      d_cs->send(s_response_close, pmt_list2(invocation_handle, status));
-
-      if(pmt_eqv(status,PMT_T)) {
-        d_opened = false;
-        d_defer = false;
-        reset_channels();
-        recall_defer_queue();
-      }
-      
-      return;
-    }
-    //--------------- USRP WRITE --------------//
-    else if (pmt_eq(event, s_response_usrp_write)) {
-      
-      pmt_t status = pmt_nth(1, data);
-      long channel = pmt_to_long(pmt_nth(2, data));
-      long port;
-
-      // Do not report back responses if they were generated from a
-      // command packet
-      if(channel == CONTROL_CHAN)
-        return;
-
-      // Find the port through the owner of the channel
-      if((port = tx_port_index(d_chaninfo_tx[channel].owner)) !=-1 )
-        d_tx[port]->send(s_response_xmit_raw_frame, 
-                         pmt_list2(invocation_handle, status));
-      return;
-    }
-    //--------------- USRP READ ---------------//
-    else if (pmt_eq(event, s_response_usrp_read)) {
-
-      pmt_t status = pmt_nth(1, data);
-
-      if(!pmt_eqv(status, PMT_T)) {
-        std::cerr << "[USRP_SERVER] Error receiving packet\n";
-        return;
-      }
-      else {
-        handle_response_usrp_read(data);
-        return;
-      }
-    }
-
-    goto unhandled;
-  }
-
-  // Checking for defer on all other messages
-  if(d_defer) {
-    if (verbose)
-      std::cout << "[USRP_SERVER] Received msg while deferring (" 
-                << msg->signal() << ")\n";
-    d_defer_queue.push(msg);
-    return;
-  }
-  
-  //--------- CONTROL / STATUS ------------//
-  if (pmt_eq(port_id, d_cs->port_symbol())){
-    
-    //----------- OPEN -----------//
-    if (pmt_eq(event, s_cmd_open)){
-
-      // Reject if already open
-      if(d_opened) {
-        d_cs->send(s_response_open, pmt_list2(invocation_handle, s_err_usrp_already_opened));
-        return;
-      }
-
-      // the parameters are the same to the low level interface, so we just pass 'data' along
-      d_cs_usrp->send(s_cmd_usrp_open, data);
-
-      d_defer = true;
-      
-      return;
-    }
-    //---------- CLOSE -----------//
-    else if (pmt_eq(event, s_cmd_close)){
-      
-      if(!d_opened) { 
-        d_cs->send(s_response_close, pmt_list2(invocation_handle, s_err_usrp_already_closed));
-        return;
-      }
-      
-      d_defer = true;
-      d_cs_usrp->send(s_cmd_usrp_close, pmt_list1(invocation_handle));
-
-      return;
-    }
-    //---------- MAX CAPACITY ----------//
-    else if (pmt_eq(event, s_cmd_max_capacity)) {
-      
-      if(!d_opened) { 
-        d_cs->send(s_response_max_capacity, 
-                   pmt_list3(invocation_handle, s_err_usrp_not_opened, pmt_from_long(0)));
-        return;
-      }
-
-      d_cs->send(s_response_max_capacity, 
-                 pmt_list3(invocation_handle, 
-                           PMT_T, 
-                           pmt_from_long(max_capacity())));
-      return;
-    }
-    //---------- NTX CHAN --------------//
-    else if (pmt_eq(event, s_cmd_ntx_chan)) {
-
-      if(!d_opened) { 
-        d_cs->send(s_response_ntx_chan, 
-                   pmt_list3(invocation_handle, s_err_usrp_not_opened, pmt_from_long(0)));
-        return;
-      }
-
-      d_cs->send(s_response_ntx_chan, 
-                 pmt_list3(invocation_handle, 
-                           PMT_T, 
-                           pmt_from_long(d_ntx_chan)));
-      return;
-    }
-    //---------- NRX CHAN -----------//
-    else if (pmt_eq(event, s_cmd_nrx_chan)) {
-
-      if(!d_opened) { 
-        d_cs->send(s_response_nrx_chan, 
-                   pmt_list3(invocation_handle, s_err_usrp_not_opened, pmt_from_long(0)));
-        return;
-      }
-
-      d_cs->send(s_response_nrx_chan, 
-                 pmt_list3(invocation_handle, 
-                           PMT_T, 
-                           pmt_from_long(d_nrx_chan)));
-      return;
-    }  
-    //--------- ALLOCATION? -----------//
-    else if (pmt_eq(event, s_cmd_current_capacity_allocation)) {
-      
-      if(!d_opened) { 
-        d_cs->send(s_response_current_capacity_allocation, 
-                   pmt_list3(invocation_handle, 
-                             s_err_usrp_not_opened, 
-                             pmt_from_long(0)));
-        return;
-      }
-      
-      d_cs->send(s_response_current_capacity_allocation, 
-                 pmt_list3(invocation_handle, 
-                           PMT_T, 
-                           pmt_from_long(current_capacity_allocation())));
-      return;
-    }
-    goto unhandled;
-  }
-  
-  //-------------- TX ---------------//
-  if ((port = tx_port_index(port_id)) != -1) {
-    
-    //------------ ALLOCATE (TX) ----------------//
-    if (pmt_eq(event, s_cmd_allocate_channel)){
-      
-      if(!d_opened) { 
-        d_tx[port]->send(s_response_allocate_channel, 
-                          pmt_list3(invocation_handle, 
-                                    s_err_usrp_not_opened, 
-                                    pmt_from_long(0)));
-        return;
-      }
-        
-      handle_cmd_allocate_channel(d_tx[port], d_chaninfo_tx, data);
-      return;
-    }
-  
-    //----------- DEALLOCATE (TX) ---------------//
-    if (pmt_eq(event, s_cmd_deallocate_channel)) {
-    
-      if(!d_opened) {
-        d_tx[port]->send(s_response_deallocate_channel, 
-                         pmt_list3(invocation_handle, 
-                                   s_err_usrp_not_opened, 
-                                   pmt_from_long(0)));
-        return;
-      }
-
-      handle_cmd_deallocate_channel(d_tx[port], d_chaninfo_tx, data);
-      return;
-    }
-  
-    //-------------- XMIT RAW FRAME -----------------/
-    if (pmt_eq(event, s_cmd_xmit_raw_frame)){
-
-      if(!d_opened) { 
-        d_tx[port]->send(s_response_xmit_raw_frame, 
-                         pmt_list2(invocation_handle, s_err_usrp_not_opened));
-        return;
-      }
-      
-      handle_cmd_xmit_raw_frame(d_tx[port], d_chaninfo_tx, data);
-      return;
-    }
-    
-    //-------------- CONTROL PACKET -----------------/
-    if (pmt_eq(event, s_cmd_to_control_channel)) {
-      
-      if(!d_opened) { 
-        d_tx[port]->send(s_response_xmit_raw_frame, 
-                         pmt_list2(invocation_handle, s_err_usrp_not_opened));
-        return;
-      }
-      
-      handle_cmd_to_control_channel(d_tx[port], d_chaninfo_tx, data);
-      return;
-
-    }
-
-    goto unhandled;
-  }
-
-  //-------------- RX ---------------//
-  if ((port = rx_port_index(port_id)) != -1) {
-    
-    //------------ ALLOCATE (RX) ----------------//
-    if (pmt_eq(event, s_cmd_allocate_channel)) {
-      
-      if(!d_opened) { 
-        d_rx[port]->send(s_response_allocate_channel, 
-                          pmt_list3(invocation_handle, 
-                                    s_err_usrp_not_opened, 
-                                    pmt_from_long(0)));
-        return;
-      }
-        
-      handle_cmd_allocate_channel(d_rx[port], d_chaninfo_rx, data);
-      return;
-    }
-  
-    //----------- DEALLOCATE (RX) ---------------//
-    if (pmt_eq(event, s_cmd_deallocate_channel)) {
-    
-      if(!d_opened) {
-        d_rx[port]->send(s_response_deallocate_channel, 
-                         pmt_list3(invocation_handle, 
-                                   s_err_usrp_not_opened, 
-                                   pmt_from_long(0)));
-        return;
-      }
-
-      handle_cmd_deallocate_channel(d_rx[port], d_chaninfo_rx, data);
-      return;
-    }
-  
-    //-------------- START RECV ----------------//
-    if (pmt_eq(event, s_cmd_start_recv_raw_samples)) {
-    
-      if(!d_opened) {
-        d_rx[port]->send(s_response_recv_raw_samples,
-                         pmt_list2(invocation_handle, s_err_usrp_not_opened));
-        return;
-      }
-
-      handle_cmd_start_recv_raw_samples(d_rx[port], d_chaninfo_rx, data);
-      return;
-    }
-    
-    //-------------- STOP RECV ----------------//
-    if (pmt_eq(event, s_cmd_stop_recv_raw_samples)) {
-    
-      if(!d_opened) 
-        return;
-
-      // FIX ME : no response for stopping? even if error? (permissions)
-      handle_cmd_stop_recv_raw_samples(d_rx[port], d_chaninfo_rx, data);
-
-      return;
-    }
-
-    goto unhandled;
-  }
-
- unhandled:
-  std::cout << "[USRP_SERVER] unhandled msg: " << msg << std::endl;
-}
-
-/*!
- * \brief Takes a port_symbol() as parameter \p port_id and is used to determine
- * if the port is a TX port, or to find an index in the d_tx vector which stores
- * the port.
- *
- * \returns -1 if \p port_id is not in the d_tx vector (i.e., it's not a TX
- * port), otherwise returns an index in the d_tx vector which stores the port.
- */
-int usrp_server::tx_port_index(pmt_t port_id) {
-
-  for(int i=0; i < (int) d_tx.size(); i++) 
-    if(pmt_eq(d_tx[i]->port_symbol(), port_id))
-      return i;
-
-  return -1;
-}
-
-/*!
- * \brief Takes a port_symbol() as parameter \p port_id and is used to determine
- * if the port is an RX port, or to find an index in the d_rx vector which
- * stores the port.
- *
- * \returns -1 if \p port_id is not in the d_rx vector (i.e., it's not an RX
- * port), otherwise returns an index in the d_rx vector which stores the port.
- */
-int usrp_server::rx_port_index(pmt_t port_id) {
-  
-  for(int i=0; i < (int) d_rx.size(); i++) 
-    if(pmt_eq(d_rx[i]->port_symbol(), port_id))
-      return i;
-
-  return -1;
-}
-
-/*!
- * \brief Determines the current total capacity allocated by all RX and TX
- * channels.
- *
- * \returns the total allocated capacity
- */
-long usrp_server::current_capacity_allocation() {
-  long capacity = 0;
-
-  for(int chan=0; chan < d_ntx_chan; chan++) 
-    capacity += d_chaninfo_tx[chan].assigned_capacity;
-
-  for(int chan=0; chan < d_nrx_chan; chan++)
-    capacity += d_chaninfo_rx[chan].assigned_capacity;
-
-  return capacity;
-}
-    
-
-/*!
- * \brief Called by the handle_message() method if the incoming message to
- * usrp_server is to allocate a channel (cmd-allocate-channel).  The method
- * checks if the requested capacity exists and if so it will reserve it for the
- * caller on the channel that is returned via a response-allocate-channel
- * signal.
- */
-void 
-usrp_server::handle_cmd_allocate_channel(
-                                mb_port_sptr port, 
-                                std::vector<struct channel_info> &chan_info,
-                                pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  long rqstd_capacity = pmt_to_long(pmt_nth(1, data));
-  long chan;
-
-  // Check capacity exists
-  if((D_USB_CAPACITY - current_capacity_allocation()) < rqstd_capacity) {
-
-    // no capacity available
-    port->send(s_response_allocate_channel, 
-               pmt_list3(invocation_handle, 
-                         s_err_requested_capacity_unavailable, 
-                         PMT_NIL));
-    return;
-  }
-
-  // Find a free channel, assign the capacity and respond
-  for(chan=0; chan < (long)chan_info.size(); chan++) {
-
-    if(verbose)
-      std::cout << "[USRP_SERVER] Checking chan: " << chan
-                << " owner " << chan_info[chan].owner
-                << " size " << chan_info.size()
-                << std::endl;
-
-    if(chan_info[chan].owner == PMT_NIL) {
-  
-      chan_info[chan].owner = port->port_symbol();
-      chan_info[chan].assigned_capacity = rqstd_capacity;
-      
-      port->send(s_response_allocate_channel, 
-                 pmt_list3(invocation_handle, 
-                           PMT_T, 
-                           pmt_from_long(chan)));
-
-      if(verbose)
-        std::cout << "[USRP_SERVER] Assigning channel: " << chan 
-                  << " to " << chan_info[chan].owner
-                  << std::endl;
-      return;
-    }
-  
-  }
-
-  if (verbose)
-    std::cout << "[USRP_SERVER] Couldnt find a TX chan\n";
-
-  // no free TX chan found
-  port->send(s_response_allocate_channel, 
-             pmt_list3(invocation_handle, 
-                       s_err_channel_unavailable, 
-                       PMT_NIL));
-  return;
-}
-
-/*!
- * \brief Called by the handle_message() method if the incoming message to
- * usrp_server is to deallocate a channel (cmd-deallocate-channel).  The method
- * ensures that the sender of the signal owns the channel and that the channel
- * number is valid.  A response-deallocate-channel signal is sent back with the
- * result of the deallocation.
- */
-void 
-usrp_server::handle_cmd_deallocate_channel(
-                              mb_port_sptr port, 
-                              std::vector<struct channel_info> &chan_info, 
-                              pmt_t data)
-{
-
-  pmt_t invocation_handle = pmt_nth(0, data); 
-  long channel = pmt_to_long(pmt_nth(1, data));
-
-  // Ensure the channel is valid and the caller owns the port
-  if(!check_valid(port, channel, chan_info,
-                  pmt_list2(s_response_deallocate_channel, invocation_handle)))
-    return;
-  
-  chan_info[channel].assigned_capacity = 0;
-  chan_info[channel].owner = PMT_NIL;
-
-  port->send(s_response_deallocate_channel, 
-             pmt_list2(invocation_handle, 
-                       PMT_T));
-  return;
-}
-
-/*!
- * \brief Called by the handle_message() method if the incoming message to
- * usrp_server is to transmit a frame (cmd-xmit-raw-frame).  The method
- * allocates enough memory to support a burst of packets which contain the frame
- * over the bus of the frame, sets the packet headers, and sends a signal to the
- * lower block for the data (packets) to be written to the bus.  
- *
- * The \p port the command was sent on and the channel info (\p chan_info) of
- * the channel the frame is to be transmitted on are passed to ensure that the
- * caller owns the channel.
- *
- * The \p data parameter is in the format of a cmd-xmit-raw-frame signal.
- *
- * The properties
- */
-void usrp_server::handle_cmd_xmit_raw_frame(
-                              mb_port_sptr port, 
-                              std::vector<struct channel_info> &chan_info, 
-                              pmt_t data) 
-{
-  size_t n_bytes, psize;
-  long max_payload_len = transport_pkt::max_payload();
-
-  pmt_t invocation_handle = pmt_nth(0, data);
-  long channel = pmt_to_long(pmt_nth(1, data));
-  const void *samples = pmt_uniform_vector_elements(pmt_nth(2, data), n_bytes);
-  long timestamp = pmt_to_long(pmt_nth(3, data));
-  pmt_t properties = pmt_nth(4, data);
-  
-  // Ensure the channel is valid and the caller owns the port
-  if(!check_valid(port, channel, chan_info,
-                  pmt_list2(s_response_xmit_raw_frame, invocation_handle)))
-    return;
-
-  // Read information from the properties of the packet
-  bool carrier_sense = false;
-  if(pmt_is_dict(properties)) {
-
-    // Check if carrier sense is enabled for the frame
-    if(pmt_t p_carrier_sense = pmt_dict_ref(properties, 
-                                            pmt_intern("carrier-sense"), 
-                                            PMT_NIL)) {
-      if(pmt_eqv(p_carrier_sense, PMT_T)) 
-        carrier_sense = true;
-    }
-  }
-
-  
-  // Determine the number of packets to allocate contiguous memory for
-  // bursting over the USB and get a pointer to the memory to be used in
-  // building the packets
-  long n_packets = 
-    static_cast<long>(std::ceil(n_bytes / (double)max_payload_len));
-
-  pmt_t v_packets = pmt_make_u8vector(sizeof(transport_pkt) * n_packets, 0);
-
-  transport_pkt *pkts =
-    (transport_pkt *) pmt_u8vector_writable_elements(v_packets, psize);
-
-  for(int n=0; n < n_packets; n++) {
-
-    long payload_len = 
-      std::min((long)(n_bytes-(n*max_payload_len)), (long)max_payload_len);
-  
-    if(n == 0) { // first packet gets start of burst flag and timestamp
-      
-      if(carrier_sense)
-        pkts[n].set_header(pkts[n].FL_START_OF_BURST 
-                           | pkts[n].FL_CARRIER_SENSE, 
-                           channel, 0, payload_len);
-      else
-        pkts[n].set_header(pkts[n].FL_START_OF_BURST, channel, 0, payload_len);
-
-      pkts[n].set_timestamp(timestamp);
-    
-    } else {
-      pkts[n].set_header(0, channel, 0, payload_len);
-      pkts[n].set_timestamp(0xffffffff);
-    }
-
-    memcpy(pkts[n].payload(), 
-           (uint8_t *)samples+(max_payload_len * n), 
-           payload_len);
-  
-  }
-
-
-  pkts[n_packets-1].set_end_of_burst(); // set the last packet's end of burst
-
-  if (verbose && 0)
-    std::cout << "[USRP_SERVER] Received raw frame invocation: " 
-              << invocation_handle << std::endl;
-    
-  // The actual response to the write will be generated by a
-  // s_response_usrp_write since we cannot determine whether to transmit was
-  // successful until we hear from the lower layers.
-  d_cs_usrp->send(s_cmd_usrp_write, 
-                  pmt_list3(invocation_handle, 
-                            pmt_from_long(channel), 
-                            v_packets));
-
-  return;
-}
-
-/*!
- * \brief Called by the handle_message() method to parse incoming control/status
- * signals (cmd-to-control-channel).  
- * 
- * The \p port the command was sent on and the channel info (\p chan_info) of
- * the channel are passed to ensure that the caller owns the channel.
- *
- * The \p data parameter is in the format of a PMT list, where each element
- * follows the format of a control/status signal (i.e. op-ping-fixed).
- *
- * The method will parse all of the C/S commands included in \p data and place
- * the commands in to a lower level packet sent to the control channel.  The
- * method will pack as many commands as possible in t oa single packet, and once
- * it is fill generate as many lower level packets as needed.
- *
- * Anything that needs to be returned to the sender of the signal (i.e. the
- * value of a register) will be generated by the parse_control_pkt() method as
- * the responses to the commands are read back from the USRP.
- */
-void usrp_server::handle_cmd_to_control_channel(
-                            mb_port_sptr port, 
-                            std::vector<struct channel_info> &chan_info, 
-                            pmt_t data) 
-{
-
-  pmt_t invocation_handle = pmt_nth(0, data);
-  pmt_t subpackets = pmt_nth(1, data);
-
-  long n_subpkts = pmt_length(subpackets);
-  long curr_subpkt = 0;
-
-  size_t psize;
-  long payload_len = 0;
-  long channel = CONTROL_CHAN;
-
-  if(verbose)
-    std::cout << "[USRP_SERVER] Handling " << n_subpkts << " commands\n";
-
-  // The design of the following code is optimized for simplicity, not
-  // performance.  To performance optimize this code, the total size in bytes
-  // needed for all of the CS packets is needed to allocate contiguous memory
-  // which contains the USB packets for bursting over the bus.  However to do
-  // this the packets subpackets would need to be parsed twice and their sizes
-  // would need to be determined.
-  //
-  // The approach taken is to keep parsing the subpackets and putting them in to
-  // USB packets.  Once the USB packet is full, a write is sent for it and
-  // another packet is created.
-  //
-  // The subpacket creation methods will return false if the subpacket will not
-  // fit in to the current USB packet.  In these cases a new USB packet is
-  // created and the old is sent.
-  
-  new_packet:
-    // This code needs to become "smart" and only make a new packet when full
-    pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0);
-    transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_packet, psize);
-    payload_len = 0;
-    
-    pkt->set_header(0, channel, 0, payload_len);
-    pkt->set_timestamp(0xffffffff);
-
-  while(curr_subpkt < n_subpkts) {
-
-    pmt_t subp = pmt_nth(curr_subpkt, subpackets);
-    pmt_t subp_cmd = pmt_nth(0, subp);
-    pmt_t subp_data = pmt_nth(1, subp);
-
-    //--------- PING FIXED --------------//
-    if(pmt_eq(subp_cmd, s_op_ping_fixed)) {
-
-      long urid     = pmt_to_long(pmt_nth(0, subp_data));
-      long pingval  = pmt_to_long(pmt_nth(1, subp_data));
-
-      // USRP server sets request ID's to keep track of which application gets
-      // what response back.  To allow a full 6-bits for an RID to the user, we
-      // keep a mapping and replace the RID's as the packets go in and out.  If
-      // there are no RID's available, the command is thrown away silently. 
-      long srid;
-      if((srid = next_rid()) == -1)
-        goto subpkt_bail;
-
-      // We use a vector to store the owner of the ping request and will use it
-      // to send the request on any RX port they own. 
-      d_rids[srid].owner = port->port_symbol();
-      d_rids[srid].user_rid = urid;
-        
-      // Adds a ping after the previous command in the pkt
-      if(!pkt->cs_ping(srid, pingval))
-      {
-        d_cs_usrp->send(s_cmd_usrp_write, 
-                        pmt_list3(invocation_handle, 
-                                  pmt_from_long(channel), 
-                                  v_packet));
-
-        // Return the RID
-        d_rids[srid].owner = PMT_NIL;
-
-        goto new_packet;
-      }
-
-      if(verbose)
-        std::cout << "[USRP_SERVER] Received ping command request"
-                  << " assigning RID " << srid << std::endl;
-
-    }
-  
-    //----------- WRITE REG ---------------//
-    if(pmt_eq(subp_cmd, s_op_write_reg)) {
-      
-      long reg_num = pmt_to_long(pmt_nth(0, subp_data));
-      long val = pmt_to_long(pmt_nth(1, subp_data));
-
-      if(!pkt->cs_write_reg(reg_num, val))
-      {
-        d_cs_usrp->send(s_cmd_usrp_write, 
-                        pmt_list3(invocation_handle, 
-                                  pmt_from_long(channel), 
-                                  v_packet));
-        
-        goto new_packet;
-      }
-      
-      if(verbose)
-        std::cout << "[USRP_SERVER] Received write register request "
-                  << "("
-                  << "Reg: " << reg_num << ", "
-                  << "Val: " << val
-                  << ")\n";
-    }
-    
-    //------- WRITE REG MASKED ----------//
-    if(pmt_eq(subp_cmd, s_op_write_reg_masked)) {
-      
-      long reg_num = pmt_to_long(pmt_nth(0, subp_data));
-      long val = pmt_to_long(pmt_nth(1, subp_data));
-      long mask = pmt_to_long(pmt_nth(2, subp_data));
-
-      if(!pkt->cs_write_reg_masked(reg_num, val, mask))
-      {
-        d_cs_usrp->send(s_cmd_usrp_write, 
-                        pmt_list3(invocation_handle, 
-                                  pmt_from_long(channel), 
-                                  v_packet));
-        
-        goto new_packet;
-      }
-      
-      if(verbose)
-        std::cout << "[USRP_SERVER] Received write register masked request\n";
-    }
-    
-    //------------ READ REG --------------//
-    if(pmt_eq(subp_cmd, s_op_read_reg)) {
-      
-      long urid     = pmt_to_long(pmt_nth(0, subp_data));
-      long reg_num  = pmt_to_long(pmt_nth(1, subp_data));
-
-      long srid;
-      if((srid = next_rid()) == -1)
-        goto subpkt_bail;
-
-      d_rids[srid].owner = port->port_symbol();
-      d_rids[srid].user_rid = urid;
-
-      if(!pkt->cs_read_reg(srid, reg_num))
-      {
-        d_cs_usrp->send(s_cmd_usrp_write, 
-                        pmt_list3(invocation_handle, 
-                                  pmt_from_long(channel), 
-                                  v_packet));
-
-        // Return the rid
-        d_rids[srid].owner = PMT_NIL;
-        
-        goto new_packet;
-      }
-      
-      if(verbose)
-        std::cout << "[USRP_SERVER] Received read register request"
-                  << " assigning RID " << srid << std::endl;
-    }
-    
-    //------------ DELAY --------------//
-    if(pmt_eq(subp_cmd, s_op_delay)) {
-
-      long ticks = pmt_to_long(pmt_nth(0, subp_data));
-
-      if(!pkt->cs_delay(ticks))
-      {
-        d_cs_usrp->send(s_cmd_usrp_write, 
-                        pmt_list3(invocation_handle, 
-                                  pmt_from_long(channel), 
-                                  v_packet));
-        
-        goto new_packet;
-      }
-      
-      if(verbose)
-        std::cout << "[USRP_SERVER] Received delay request of "
-                  << ticks << " ticks\n";
-    }
-
-    //--------- I2C WRITE -----------//
-    // FIXME: could check that byte count does not exceed 2^8 which
-    // is the max length in the subpacket for # of bytes to read.
-    if(pmt_eq(subp_cmd, s_op_i2c_write)) {
-      
-      long i2c_addr = pmt_to_long(pmt_nth(0, subp_data));
-      pmt_t data = pmt_nth(1, subp_data);
-
-      // Get a readable address to the data which also gives us the length
-      size_t data_len;
-      uint8_t *i2c_data = (uint8_t *) pmt_u8vector_writable_elements(data, data_len);
-
-      // Make the USB packet
-      if(!pkt->cs_i2c_write(i2c_addr, i2c_data, data_len))
-      {
-        d_cs_usrp->send(s_cmd_usrp_write, 
-                        pmt_list3(invocation_handle, 
-                                  pmt_from_long(channel), 
-                                  v_packet));
-        
-        goto new_packet;
-      }
-      
-      if(verbose)
-        std::cout << "[USRP_SERVER] Received I2C write\n";
-    }
-  
-    //----------- I2C Read -------------//
-    if(pmt_eq(subp_cmd, s_op_i2c_read)) {
-      
-      long urid       = pmt_to_long(pmt_nth(0, subp_data));
-      long i2c_addr   = pmt_to_long(pmt_nth(1, subp_data));
-      long i2c_bytes  = pmt_to_long(pmt_nth(2, subp_data));
-
-      long srid;
-      if((srid = next_rid()) == -1)
-        goto subpkt_bail;
-      
-      d_rids[srid].owner = port->port_symbol();
-      d_rids[srid].user_rid = urid;
-
-      if(!pkt->cs_i2c_read(srid, i2c_addr, i2c_bytes))
-      {
-        
-        d_cs_usrp->send(s_cmd_usrp_write, 
-                        pmt_list3(invocation_handle, 
-                                  pmt_from_long(channel), 
-                                  v_packet));
-
-        d_rids[srid].owner = PMT_NIL;
-
-        goto new_packet;
-      }
-      
-      if(verbose)
-        std::cout << "[USRP_SERVER] Received I2C read\n";
-    }
-    
-    //--------- SPI WRITE -----------//
-    if(pmt_eq(subp_cmd, s_op_spi_write)) {
-      
-      long enables = pmt_to_long(pmt_nth(0, subp_data));
-      long format = pmt_to_long(pmt_nth(1, subp_data));
-      long opt = pmt_to_long(pmt_nth(2, subp_data));
-      pmt_t data = pmt_nth(3, subp_data);
-
-      // Get a readable address to the data which also gives us the length
-      size_t data_len;
-      uint8_t *spi_data = (uint8_t *) pmt_u8vector_writable_elements(data, data_len);
-
-      // Make the USB packet
-      if(!pkt->cs_spi_write(enables, format, opt, spi_data, data_len))
-      {
-        d_cs_usrp->send(s_cmd_usrp_write, 
-                        pmt_list3(invocation_handle, 
-                                  pmt_from_long(channel), 
-                                  v_packet));
-        
-        goto new_packet;
-      }
-      
-      if(verbose)
-        std::cout << "[USRP_SERVER] Received SPI write\n";
-    }
-    
-    //--------- SPI READ -----------//
-    if(pmt_eq(subp_cmd, s_op_spi_read)) {
-      
-      long urid     = pmt_to_long(pmt_nth(0, subp_data));
-      long enables  = pmt_to_long(pmt_nth(1, subp_data));
-      long format   = pmt_to_long(pmt_nth(2, subp_data));
-      long opt      = pmt_to_long(pmt_nth(3, subp_data));
-      long n_bytes  = pmt_to_long(pmt_nth(4, subp_data));
-      
-      long srid;
-      if((srid = next_rid()) == -1)
-        goto subpkt_bail;
-
-      d_rids[srid].owner = port->port_symbol();
-      d_rids[srid].user_rid = urid;
-
-      // Make the USB packet
-      if(!pkt->cs_spi_read(srid, enables, format, opt, n_bytes))
-      {
-        d_cs_usrp->send(s_cmd_usrp_write, 
-                        pmt_list3(invocation_handle, 
-                                  pmt_from_long(channel), 
-                                  v_packet));
-        
-        // Return the rid
-        d_rids[srid].owner = PMT_NIL;
-
-        goto new_packet;
-      }
-      
-      if(verbose)
-        std::cout << "[USRP_SERVER] Received SPI read\n";
-    }
-
-  subpkt_bail:
-    curr_subpkt++;
-
-  }
-
-
-  // If the current packets length is > 0, we know there are subpackets that
-  // need to be sent out still.
-  if(pkt->payload_len() > 0)
-    d_cs_usrp->send(s_cmd_usrp_write, 
-                    pmt_list3(invocation_handle, 
-                              pmt_from_long(channel), 
-                              v_packet));
-
-  return;
-}
-
-/*!
- * \brief Called by the handle_message() method when the incoming signal is a
- * command to start reading samples from the USRP (cmd-start-recv-raw-samples).  
- *
- * The \p port the command was sent on and the channel info (\p chan_info) of
- * the channel are passed to ensure that the caller owns the channel.
- *
- * The \p data parameter should be in the format of a cmd-start-recv-raw-samples
- * command where the first element in the list is an invocation handle, and the
- * second is the channel the signal generator wants to receive the samples on.
- */
-void
-usrp_server::handle_cmd_start_recv_raw_samples(
-                                  mb_port_sptr port, 
-                                  std::vector<struct channel_info> &chan_info, 
-                                  pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  long channel = pmt_to_long(pmt_nth(1, data));
-
-  // Ensure the channel is valid and the caller owns the port
-  if(!check_valid(port, channel, chan_info,
-                  pmt_list2(s_response_xmit_raw_frame, invocation_handle)))
-    return;
-
-  // Already started receiving samples? (another start before a stop)
-  // Check the RX channel bitmask.
-  if(d_rx_chan_mask & (1 << channel)) {
-    port->send(s_response_recv_raw_samples,
-               pmt_list5(invocation_handle,
-                         s_err_already_receiving,
-                         PMT_NIL,
-                         PMT_NIL,
-                         PMT_NIL));
-    return;
-  }
-
-  // We only need to generate a 'start reading' command down to the
-  // low level interface if no other channel is already reading
-  //
-  // We carry this over the CS interface because the lower level
-  // interface does not care about the channel, we only demux it
-  // at the usrp_server on responses.
-  if(d_rx_chan_mask == 0) {
-    
-    if(verbose)
-      std::cout << "[USRP_SERVER] Sending read request down to start recv\n";
-
-    d_cs_usrp->send(s_cmd_usrp_start_reading, pmt_list1(invocation_handle));
-  }
-
-  d_rx_chan_mask |= 1<<channel;
-  
-  return;
-}
-
-/*!
- * \brief Called by the handle_message() method when the incoming signal is to
- * stop receiving samples from the USRP (cmd-stop-recv-raw-samples).
- *
- * The \p port the command was sent on and the channel info (\p chan_info) of
- * the channel are passed to ensure that the caller owns the channel.
- *
- * The \p data parameter should be in the format of a cmd-stop-recv-raw-samples
- * command where the first element in the list is an invocation handle, and the
- * second is the channel the signal generator wants to stop receiving the
- * samples from.
- */
-void
-usrp_server::handle_cmd_stop_recv_raw_samples(
-                        mb_port_sptr port, 
-                        std::vector<struct channel_info> &chan_info, 
-                        pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  long channel = pmt_to_long(pmt_nth(1, data));
-
-  // FIX ME : we have no responses to send an error...
-  // Ensure the channel is valid and the caller owns the port
-  //if(!check_valid(port, channel, chan_info,
-  //                pmt_list2(s_response_xmit_raw_frame, invocation_handle)))
-  //  return;
-
-  // Remove this hosts bit from the receiver mask
-  d_rx_chan_mask &= ~(1<<channel);
-
-  // We only need to generate a 'start reading' command down to the
-  // low level interface if no other channel is already reading
-  //
-  // We carry this over the CS interface because the lower level
-  // interface does not care about the channel, we only demux it
-  // at the usrp_server on responses.
-  if(d_rx_chan_mask == 0) {
-    
-    if(verbose)
-      std::cout << "[USRP_SERVER] Sending stop reading request down\n";
-
-    d_cs_usrp->send(s_cmd_usrp_stop_reading, pmt_list1(invocation_handle));
-  }
-  
-  return;
-}
-
-/*!
- * \brief Called by the handle_message() method when an incoming signal is
- * generated to USRP server that contains raw samples from the USRP.  This
- * method generates the response-recv-raw-samples signals that are the result of
- * a cmd-start-recv-raw-samples signal.
- *
- * The raw lower-level packet is extracted from \p data, where the format for \p
- * data is a PMT list.  The PMT \p data list should contain an invocation handle
- * as the first element, the status of the lower-level read as the second
- * element, and a uniform vector representation of the packets as the third
- * element.  
- *
- * The packet contains a channel field that the samples are destined to, and the
- * method determines where to send the samples based on this channel since each
- * channel has an associated port which allocated it.
- */
-void
-usrp_server::handle_response_usrp_read(pmt_t data)
-{
-
-  pmt_t invocation_handle = pmt_nth(0, data);
-  pmt_t status = pmt_nth(1, data);
-  pmt_t v_pkt = pmt_nth(2, data);
-
-  size_t n_bytes;
-  size_t ignore;
-
-  if (d_fake_rx) {
-
-    pmt_t pkt = pmt_nth(2, data);
-
-    d_rx[0]->send(s_response_recv_raw_samples,
-                  pmt_list5(PMT_F,
-                            PMT_T,
-                            pkt,
-                            pmt_from_long(0xffff),
-                            PMT_NIL));
-
-    return;
-  }
-
-  // Extract the packet and return appropriately
-  transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, n_bytes);
-
-  // The channel is used to find the port to pass the samples on
-  long channel = pkt->chan();
-  long payload_len = pkt->payload_len();
-  long port;
-
-  // Ignore packets which seem to have incorrect size or size 0
-  if(payload_len > pkt->max_payload() || payload_len == 0)
-    return;
-  
-  // If the packet is a C/S packet, parse it separately
-  if(channel == CONTROL_CHAN) {
-    parse_control_pkt(invocation_handle, pkt);
-    return;
-  }
-
-  if((port = rx_port_index(d_chaninfo_rx[channel].owner)) == -1)
-    return; // Don't know where to send the sample... possibility on abrupt close
-    
-  pmt_t v_samples = pmt_make_u8vector(payload_len, 0);
-  uint8_t *samples = pmt_u8vector_writable_elements(v_samples, ignore);
-  
-  memcpy(samples, pkt->payload(), payload_len);
-
-  // Build a properties dictionary to store things such as the RSSI
-  pmt_t properties =  pmt_make_dict();
-
-  pmt_dict_set(properties,
-               pmt_intern("rssi"),
-               pmt_from_long(pkt->rssi()));
-
-  if(pkt->overrun())
-    pmt_dict_set(properties,
-                 pmt_intern("overrun"),
-                 PMT_T);
-
-  if(pkt->underrun())
-    pmt_dict_set(properties,
-                 pmt_intern("underrun"),
-                 PMT_T);
-
-  d_rx[port]->send(s_response_recv_raw_samples,
-                   pmt_list6(invocation_handle,
-                             status,
-                             v_samples,
-                             pmt_from_long(pkt->timestamp()),
-                             pmt_from_long(channel),
-                             properties));
-  return;
-}
-
-/*!
- * \brief Called by handle_response_usrp_read() when the incoming packet has a
- * channel of CONTROL_CHAN.  This means that the incoming packet contains a
- * response for a command sent to the control channel, which this method will
- * parse.
- *
- * The \p pkt parameter is a pointer to the full packet (transport_pkt) in
- * memory.
- *
- * Given that all commands sent to the control channel that require responses
- * will carry an RID (request ID), the method will use the RID passed back with
- * the response to determine which port the response should be sent on.
- */
-void
-usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt)
-{
-
-  long payload_len = pkt->payload_len();
-  long curr_payload = 0;
-  long port;
-  
-  // We dispatch based on the control packet type, however we can extract the
-  // opcode and the length immediately which is consistent in all responses.
-  //
-  // Since each control packet can have multiple responses, we keep reading the
-  // lengths of each subpacket until we reach the payload length.  
-  while(curr_payload < payload_len) {
-
-    pmt_t sub_packet = pkt->read_subpacket(curr_payload);
-    pmt_t op_symbol = pmt_nth(0, sub_packet);
-
-    int len = pkt->cs_len(curr_payload);
-
-    if(verbose)
-      std::cout << "[USRP_SERVER] Parsing subpacket " 
-                << op_symbol << " ... length " << len << std::endl;
-
-    //----------------- PING RESPONSE ------------------//
-    if(pmt_eq(op_symbol, s_op_ping_fixed_reply)) {
-
-      long srid     = pmt_to_long(pmt_nth(1, sub_packet));
-      pmt_t pingval = pmt_nth(2, sub_packet);
-
-      long urid = d_rids[srid].user_rid;
-      
-      if(verbose)
-        std::cout << "[USRP_SERVER] Found ping response "
-                  << "("
-                  << "URID: " << urid << ", "
-                  << "SRID: " << srid << ", "
-                  << "VAL: " << pingval 
-                  << ")\n";
-      
-      // Do some bounds checking incase of bogus/corrupt responses
-      if(srid > D_MAX_RID)
-        return;
-
-      pmt_t owner = d_rids[srid].owner;
-      
-      // Return the RID
-      d_rids[srid].owner = PMT_NIL;
-
-      // FIXME: should be 1 response for all subpackets here ?
-      if((port = tx_port_index(owner)) != -1)
-        d_tx[port]->send(s_response_from_control_channel,
-                         pmt_list4(invocation_handle,
-                                   PMT_T,
-                                   pmt_list2(s_op_ping_fixed_reply, // subp
-                                             pmt_list2(pmt_from_long(urid), 
-                                                       pingval)),
-                                   pmt_from_long(pkt->timestamp())));
-    }
-    
-    //----------------- READ REG RESPONSE ------------------//
-    else if(pmt_eq(op_symbol, s_op_read_reg_reply)) {
-
-      long srid     = pmt_to_long(pmt_nth(1, sub_packet));
-      pmt_t reg_num = pmt_nth(2, sub_packet);
-      pmt_t reg_val = pmt_nth(3, sub_packet);
-
-      long urid = d_rids[srid].user_rid;
-      
-      if(verbose)
-        std::cout << "[USRP_SERVER] Found read register response "
-                  << "("
-                  << "URID: " << urid << ", "
-                  << "SRID: " << srid << ", "
-                  << "REG: " << reg_num << ", "
-                  << "VAL: " << reg_val 
-                  << ")\n";
-
-      // Do some bounds checking to avoid seg faults
-      if(srid > D_MAX_RID)
-        return;
-      
-      pmt_t owner = d_rids[srid].owner;
-      
-      // Return the RID
-      d_rids[srid].owner = PMT_NIL;
-
-      // FIXME: should be 1 response for all subpackets here ?
-      if((port = tx_port_index(owner)) != -1)
-        d_tx[port]->send(s_response_from_control_channel,
-                         pmt_list4(invocation_handle,
-                                   PMT_T,
-                                   pmt_list2(s_op_read_reg_reply, // subp
-                                             pmt_list3(pmt_from_long(urid), 
-                                                       reg_num, 
-                                                       reg_val)),
-                                   pmt_from_long(pkt->timestamp())));
-    }
-
-    //------------------ I2C READ REPLY -------------------//
-    else if(pmt_eq(op_symbol, s_op_i2c_read_reply)) {
-
-      long srid       = pmt_to_long(pmt_nth(1, sub_packet));
-      pmt_t i2c_addr  = pmt_nth(2, sub_packet);
-      pmt_t i2c_data  = pmt_nth(3, sub_packet);
-
-      long urid = d_rids[srid].user_rid;
-
-      if(verbose)
-        std::cout << "[USRP_SERVER] Found i2c read reply "
-                  << "("
-                  << "URID: " << urid << ", "
-                  << "SRID: " << srid << ", "
-                  << "Addr: " << i2c_addr << ", "
-                  << "Data: " << i2c_data
-                  << ")\n";
-      
-      // Do some bounds checking to avoid seg faults
-      if(srid > D_MAX_RID)
-        return;
-
-      pmt_t owner = d_rids[srid].owner;
-      
-      // Return the RID
-      d_rids[srid].owner = PMT_NIL;
-
-      if((port = tx_port_index(owner)) != -1)
-        d_tx[port]->send(s_response_from_control_channel,
-                         pmt_list4(invocation_handle,
-                                   PMT_T,
-                                   pmt_list2(s_op_i2c_read_reply,
-                                             pmt_list3(pmt_from_long(urid), 
-                                                       i2c_addr,
-                                                       i2c_data)),
-                                   pmt_from_long(pkt->timestamp())));
-    }
-
-    //------------------ SPI READ REPLY -------------------//
-    else if(pmt_eq(op_symbol, s_op_spi_read_reply)) {
-      
-      long srid       = pmt_to_long(pmt_nth(1, sub_packet));
-      pmt_t spi_data  = pmt_nth(2, sub_packet);
-      
-      long urid = d_rids[srid].user_rid;
-
-      if(verbose)
-        std::cout << "[USRP_SERVER] Found SPI read reply "
-                  << "("
-                  << "URID: " << urid << ", "
-                  << "SRID: " << srid << ", "
-                  << "Data: " << spi_data
-                  << ")\n";
-
-      // Bounds check the RID
-      if(srid > D_MAX_RID)
-        return;
-
-      pmt_t owner = d_rids[srid].owner;
-      
-      // Return the RID
-      d_rids[srid].owner = PMT_NIL;
-
-      if((port = tx_port_index(owner)) != -1)
-        d_tx[port]->send(s_response_from_control_channel,
-                         pmt_list4(invocation_handle,
-                                   PMT_T,
-                                   pmt_list2(s_op_spi_read_reply,
-                                             pmt_list2(pmt_from_long(urid), 
-                                                       spi_data)),
-                                   pmt_from_long(pkt->timestamp())));
-    }
-
-    // Each subpacket has an unaccounted for 2 bytes which is the opcode
-    // and the length field
-    curr_payload += len + 2;
-    
-    // All subpackets are 32-bit aligned
-    int align_offset = 4 - (curr_payload % 4);
-
-    if(align_offset != 4)
-      curr_payload += align_offset;
-  }
-}
-
-/*!
- * \brief Used to recall all incoming signals that were deferred when USRP
- * server was in the initialization state.
- */
-void
-usrp_server::recall_defer_queue()
-{
-
-  std::vector<mb_message_sptr> recall;
-
-  while(!d_defer_queue.empty()) {
-    recall.push_back(d_defer_queue.front());
-    d_defer_queue.pop();
-  }
-
-  // Parse the messages that were queued while waiting for an open response
-  for(int i=0; i < (int)recall.size(); i++) 
-    handle_message(recall[i]);
-
-  return;
-}
-
-/*!
- * \brief Commonly called by any method which handles outgoing frames or control
- * packets to the USRP to check if the port on which the signal was sent owns
- * the channel the outgoing packet will be associated with.   This helps ensure
- * that applications do not send data on other application's ports.
- *
- * The \p port parameter is the port symbol that the caller wishes to determine
- * owns the channel specified by \p chan_info.  
- *
- * The \p signal_info parameter is a PMT list containing two elements: the
- * response signal to use if the permissions are invalid, and the invocation
- * handle that was passed.  This allows the method to generate detailed failure
- * responses to signals without having to return some sort of structured
- * information which the caller must then parse and interpret to determine the
- * failure type.
- *
- * \returns true if \p port owns the channel specified by \p chan_info, false
- * otherwise.
- */
-bool
-usrp_server::check_valid(mb_port_sptr port,
-                         long channel,
-                         std::vector<struct channel_info> &chan_info,
-                         pmt_t signal_info)
-{
-
-  pmt_t response_signal = pmt_nth(0, signal_info);
-  pmt_t invocation_handle = pmt_nth(1, signal_info);
-
-  // not a valid channel number?
-  if(channel >= (long)chan_info.size() && channel != CONTROL_CHAN) {
-    port->send(response_signal, 
-               pmt_list2(invocation_handle, 
-                         s_err_channel_invalid));
-
-    if(verbose)
-      std::cout << "[USRP_SERVER] Invalid channel number for event " 
-                << response_signal << std::endl;
-    return false;
-  }
-  
-  // not the owner of the port?
-  if(chan_info[channel].owner != port->port_symbol()) {
-    port->send(response_signal, 
-               pmt_list2(invocation_handle, 
-                         s_err_channel_permission_denied));
-    
-    if(verbose)
-      std::cout << "[USRP_SERVER] Invalid permissions"
-                << " for " << response_signal
-                << " from " << port->port_symbol()
-                << " proper owner is " << chan_info[channel].owner
-                << " on channel " << channel
-                << " invocation " << invocation_handle
-                << std::endl;
-    return false;
-  }
-
-  return true;
-}
-
-/*!
- * \brief Finds the next available RID for internal USRP server use with control
- * and status packets.
- *
- * \returns the next valid RID or -1 if no more RIDs are available.
- */
-long
-usrp_server::next_rid()
-{
-  for(int i = 0; i < D_MAX_RID; i++)
-    if(pmt_eqv(d_rids[i].owner, PMT_NIL))
-      return i;
-
-  if(verbose)
-    std::cout << "[USRP_SERVER] No RIDs left\n";
-  return -1;
-}
-
-/*!
- * \brief Called by handle_message() when USRP server gets a response that the
- * USRP was opened successfully to initialize the registers using the new
- * register read/write control packets.
- */
-void
-usrp_server::initialize_registers()
-{
-  // We use handle_cmd_to_control_channel() to create the register writes using
-  // PMT_NIL as the response port to tell usrp_server not to pass the response
-  // up to any application.
-  if(verbose)
-    std::cout << "[USRP_SERVER] Initializing registers...\n";
-
-  // RX mode to normal (0)
-  set_register(FR_MODE, 0);
-
-  // FPGA debugging?
-  if(d_fpga_debug) {
-    set_register(FR_DEBUG_EN, 1);
-    // FIXME: need to figure out exact register writes to control daughterboard
-    // pins that need to be written to
-  } else {
-    set_register(FR_DEBUG_EN, 0);
-  }
-
-  // Set the transmit sample rate divisor, which is 4-1
-  set_register(FR_TX_SAMPLE_RATE_DIV, 3);
-
-  // Dboard IO buffer and register settings
-  set_register(FR_OE_0, (0xffff << 16) | 0x0000);
-  set_register(FR_IO_0, (0xffff << 16) | 0x0000);
-  set_register(FR_OE_1, (0xffff << 16) | 0x0000);
-  set_register(FR_IO_1, (0xffff << 16) | 0x0000);
-  set_register(FR_OE_2, (0xffff << 16) | 0x0000);
-  set_register(FR_IO_2, (0xffff << 16) | 0x0000);
-  set_register(FR_OE_3, (0xffff << 16) | 0x0000);
-  set_register(FR_IO_3, (0xffff << 16) | 0x0000);
-
-  // zero Tx side Auto Transmit/Receive regs
-  set_register(FR_ATR_MASK_0, 0); 
-  set_register(FR_ATR_TXVAL_0, 0);
-  set_register(FR_ATR_RXVAL_0, 0);
-  set_register(FR_ATR_MASK_1, 0); 
-  set_register(FR_ATR_TXVAL_1, 0);
-  set_register(FR_ATR_RXVAL_1, 0);
-  set_register(FR_ATR_MASK_2, 0);
-  set_register(FR_ATR_TXVAL_2, 0);
-  set_register(FR_ATR_RXVAL_2, 0);
-  set_register(FR_ATR_MASK_3, 0);
-  set_register(FR_ATR_TXVAL_3, 0);
-  set_register(FR_ATR_RXVAL_3, 0);
-
-  // Configure TX mux, this is a hacked value
-  set_register(FR_TX_MUX, 0x00000081);
-
-  // Set the interpolation rate, which is the rate divided by 4, minus 1
-  set_register(FR_INTERP_RATE, (d_interp_tx/4)-1);
-
-  // Apparently this register changes again
-  set_register(FR_TX_MUX, 0x00000981);
-
-  // Set the receive sample rate divisor, which is 2-1
-  set_register(FR_RX_SAMPLE_RATE_DIV, 1);
-
-  // DC offset
-  set_register(FR_DC_OFFSET_CL_EN, 0x0000000f);
-
-  // Reset the DC correction offsets
-  set_register(FR_ADC_OFFSET_0, 0);
-  set_register(FR_ADC_OFFSET_1, 0);
-
-  // Some hard-coded RX configuration
-  set_register(FR_RX_FORMAT, 0x00000300);
-  set_register(FR_RX_MUX, 1);
-
-  // RX decimation rate is divided by two, then subtract 1
-  set_register(FR_DECIM_RATE, (d_decim_rx/2)-1);
-
-  // More hard coding
-  set_register(FR_RX_MUX, 0x000e4e41);
-
-  // Resetting RX registers
-  set_register(FR_RX_PHASE_0, 0);
-  set_register(FR_RX_PHASE_1, 0);
-  set_register(FR_RX_PHASE_2, 0);
-  set_register(FR_RX_PHASE_3, 0);
-  set_register(FR_RX_FREQ_0, 0x28000000);
-  set_register(FR_RX_FREQ_1, 0);
-  set_register(FR_RX_FREQ_2, 0);
-  set_register(FR_RX_FREQ_3, 0);
-
-  // Enable debug bus
-  set_register(FR_DEBUG_EN, 0xf);
-  set_register(FR_OE_0, -1);
-  set_register(FR_OE_1, -1);
-  set_register(FR_OE_2, -1);
-  set_register(FR_OE_3, -1);
-
-  // DEBUGGING
-  //check_register_initialization();
-}
-
-// FIXME: used for debugging to determine if all the registers are actually
-// being set correctly
-void
-usrp_server::check_register_initialization()
-{
-  // RX mode to normal (0)
-  read_register(FR_MODE);
-
-  // FPGA debugging?
-  if(d_fpga_debug) {
-    read_register(FR_DEBUG_EN);
-    // FIXME: need to figure out exact register writes to control daughterboard
-    // pins that need to be written to
-  } else {
-    read_register(FR_DEBUG_EN);
-  }
-
-  // Set the transmit sample rate divisor, which is 4-1
-  read_register(FR_TX_SAMPLE_RATE_DIV);
-
-  // Dboard IO buffer and register settings
-  read_register(FR_OE_0);
-  read_register(FR_IO_0);
-  read_register(FR_OE_1);
-  read_register(FR_IO_1);
-  read_register(FR_OE_2);
-  read_register(FR_IO_2);
-  read_register(FR_OE_3);
-  read_register(FR_IO_3);
-
-  // zero Tx side Auto Transmit/Receive regs
-  read_register(FR_ATR_MASK_0); 
-  read_register(FR_ATR_TXVAL_0);
-  read_register(FR_ATR_RXVAL_0);
-  read_register(FR_ATR_MASK_1); 
-  read_register(FR_ATR_TXVAL_1);
-  read_register(FR_ATR_RXVAL_1);
-  read_register(FR_ATR_MASK_2);
-  read_register(FR_ATR_TXVAL_2);
-  read_register(FR_ATR_RXVAL_2);
-  read_register(FR_ATR_MASK_3);
-  read_register(FR_ATR_TXVAL_3);
-  read_register(FR_ATR_RXVAL_3);
-
-  // Configure TX mux, this is a hacked value
-  read_register(FR_TX_MUX);
-
-  // Set the interpolation rate, which is the rate divided by 4, minus 1
-  read_register(FR_INTERP_RATE);
-
-  // Apparently this register changes again
-  read_register(FR_TX_MUX);
-
-  // Set the receive sample rate divisor, which is 2-1
-  read_register(FR_RX_SAMPLE_RATE_DIV);
-
-  // DC offset
-  read_register(FR_DC_OFFSET_CL_EN);
-
-  // Reset the DC correction offsets
-  read_register(FR_ADC_OFFSET_0);
-  read_register(FR_ADC_OFFSET_1);
-
-  // Some hard-coded RX configuration
-  read_register(FR_RX_FORMAT);
-  read_register(FR_RX_MUX);
-
-  // RX decimation rate is divided by two, then subtract 1
-  read_register(FR_DECIM_RATE);
-
-  // More hard coding
-  read_register(FR_RX_MUX);
-
-  // Resetting RX registers
-  read_register(FR_RX_PHASE_0);
-  read_register(FR_RX_PHASE_1);
-  read_register(FR_RX_PHASE_2);
-  read_register(FR_RX_PHASE_3);
-  read_register(FR_RX_FREQ_0);
-  read_register(FR_RX_FREQ_1);
-  read_register(FR_RX_FREQ_2);
-  read_register(FR_RX_FREQ_3);
-}
-
-/*!
- * \brief Used to generate FPGA register write commands to reset all of the FPGA
- * registers to a value of 0.
- */
-void
-usrp_server::reset_all_registers()
-{
-  for(int i=0; i<64; i++)
-    set_register(i, 0);
-}
-
-/*!
- * \brief Used internally by USRP server to generate a control/status packet
- * which contains a register write.
- *
- * The \p reg parameter is the register number that the value \p val will be
- * written to.
- */
-void
-usrp_server::set_register(long reg, long val)
-{
-  size_t psize;
-  long payload_len = 0;
-
-  pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0);
-  transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_packet, psize);
-  
-  pkt->set_header(0, CONTROL_CHAN, 0, payload_len);
-  pkt->set_timestamp(0xffffffff);
-
-  pkt->cs_write_reg(reg, val);
-
-  d_cs_usrp->send(s_cmd_usrp_write, 
-                  pmt_list3(PMT_NIL, 
-                            pmt_from_long(CONTROL_CHAN), 
-                            v_packet));
-}
-
-/*!
- * \brief Used internally by USRP server to generate a control/status packet
- * which contains a register read.  This is important to use internally so that
- * USRP server can bypass the use of RIDs with register reads, as they are not
- * needed and it would use up the finite number of RIDs available for use for
- * applications to receive responses.
- *
- * The \p reg parameter is the register number that the value should be read
- * from.
- */
-void
-usrp_server::read_register(long reg)
-{
-  size_t psize;
-  long payload_len = 0;
-
-  pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0);
-  transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_packet, psize);
-  
-  pkt->set_header(0, CONTROL_CHAN, 0, payload_len);
-  pkt->set_timestamp(0xffffffff);
-
-  pkt->cs_read_reg(0, reg);
-
-  d_cs_usrp->send(s_cmd_usrp_write, 
-                  pmt_list3(PMT_NIL, 
-                            pmt_from_long(CONTROL_CHAN), 
-                            v_packet));
-}
-
-REGISTER_MBLOCK_CLASS(usrp_server);
diff --git a/usrp/host/lib/inband/usrp_server.h b/usrp/host/lib/inband/usrp_server.h
deleted file mode 100644 (file)
index dd1825d..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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_SERVER_H
-#define INCLUDED_USRP_SERVER_H
-
-#include <mblock/mblock.h>
-#include <vector>
-#include <queue>
-#include <fstream>
-#include <usrp_inband_usb_packet.h>
-
-typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit easy
-
-/*!
- * \brief Implements the lowest-level mblock usb_interface to the USRP
- */
-class usrp_server : public mb_mblock
-{
-public:
-
-  // our ports
-  enum port_types {
-    RX_PORT = 0,
-    TX_PORT = 1
-  };
-  static const int N_PORTS = 4;
-  std::vector<mb_port_sptr> d_tx, d_rx;
-  mb_port_sptr d_cs;
-  mb_port_sptr d_cs_usrp;
-
-  static const int D_USB_CAPACITY = 32 * 1024 * 1024;
-  static const int D_MAX_CHANNELS = 16;
-  long d_ntx_chan;
-  long d_nrx_chan;
-
-  pmt_t d_usrp_dict;
-
-  bool d_fpga_debug;
-  
-  long d_interp_tx;
-  long d_decim_rx;
-
-  // Keep track of the request IDs
-  struct rid_info {
-    pmt_t owner;
-    long user_rid;
-
-    rid_info() {
-      owner = PMT_NIL;
-      user_rid = 0;
-    }
-  };
-
-  static const long D_MAX_RID = 64;
-  std::vector<rid_info> d_rids;
-  
-  struct channel_info {
-    long assigned_capacity;   // the capacity currently assignedby the channel
-    pmt_t owner;              // port ID of the owner of the channel
-
-    channel_info() {
-      assigned_capacity = 0;
-      owner = PMT_NIL;
-    }
-  };
-
-  long d_rx_chan_mask;    // A bitmask representing the channels in the
-                          // receiving state
-
-  std::vector<struct channel_info> d_chaninfo_tx;
-  std::vector<struct channel_info> d_chaninfo_rx;
-
-  std::queue<mb_message_sptr> d_defer_queue;
-
-  bool d_defer;
-  bool d_opened;
-
-  bool d_fake_rx;
-
-public:
-  usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg);
-  ~usrp_server();
-
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
-protected:
-  static int max_capacity() { return D_USB_CAPACITY; }
-
-private:
-  void handle_cmd_allocate_channel(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data);
-  void handle_cmd_deallocate_channel(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data);
-  void handle_cmd_xmit_raw_frame(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data);
-  void handle_cmd_to_control_channel(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data);
-  void handle_cmd_start_recv_raw_samples(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data);
-  void handle_cmd_stop_recv_raw_samples(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data);
-  int rx_port_index(pmt_t port_id);
-  int tx_port_index(pmt_t port_id);
-  long current_capacity_allocation();
-  void recall_defer_queue();
-  void reset_channels();
-  void handle_response_usrp_read(pmt_t data);
-  bool check_valid(mb_port_sptr port, long channel, std::vector<struct channel_info> &chan_info, pmt_t signal_info);
-  void parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt);
-  long next_rid();
-  void initialize_registers();
-  void set_register(long reg, long val);
-  void read_register(long reg);
-  void check_register_initialization();
-  void reset_all_registers();
-};
-
-#endif /* INCLUDED_USRP_SERVER_H */
diff --git a/usrp/host/lib/inband/usrp_server.mbh b/usrp/host/lib/inband/usrp_server.mbh
deleted file mode 100644 (file)
index ed7943f..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-;; -*- scheme -*- ; not really, but tells emacs how to format this
-;;
-;; 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 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.
-;;
-
-;; ----------------------------------------------------------------
-;;              This is an mblock header file
-;;
-;; The format is very much a work-in-progress.
-;; It'll be compiled to C++.
-;; ----------------------------------------------------------------
-
-;; In the outgoing messages described below, invocation-handle is an
-;; identifier provided by the client to tag the method invocation.
-;; The identifier will be returned with the response, to provide the
-;; client with a mechanism to match asynchronous responses with the
-;; commands that generate them.  The value of the invocation-handle is
-;; opaque the the server, and is not required by the server to be
-;; unique.
-;;
-;; In the incoming messages described below, invocation-handle is the
-;; identifier provided by the client in the prompting invocation.  The
-;; identifier is returned with the response, so that the client has a
-;; mechanism to match asynchronous responses with the commands that
-;; generated them.
-;;
-;; status is either #t, indicating success, or a symbol indicating an error.
-;; All symbol's names shall begin with %error-
-
-
-;; ----------------------------------------------------------------
-;; usrp-channel
-;;
-;; The protocol class is defined from the client's point-of-view.
-;; (The client port is unconjugated, the server port is conjugated.)
-
-(define-protocol-class usrp-channel
-
-  (:outgoing
-
-   (cmd-allocate-channel invocation-handle capacity-reservation)
-
-   ;; The cmd-allocate-channel message requests that the server
-   ;; allocates a logical channel in the FPGA for use.
-   ;; capacity-reservation specifies the number of bytes/s of
-   ;; interconnect capacity (USB or ethernet) to reserve for this
-   ;; channel.  (The reservation is just a sanity check, no OS
-   ;; specific mechanism is used.)
-
-   (cmd-deallocate-channel invocation-handle channel)
-
-   ;; The integer channel specifies the channel to deallocate.
-
-   )
-
-  (:incoming
-
-
-   (response-allocate-channel invocation-handle status channel)
-
-   ;; If successful, a channel the specified capacity was allocated.
-   ;; channel, an integer, indicates which channel was allocated.
-
-   (response-deallocate-channel invocation-handle status)
-
-   ;; If successful, the specified channel and associated interconnect
-   ;; capacity were deallocated.
-
-   )
-  )
-
-;; ----------------------------------------------------------------
-;; usrp-low-level-cs
-;;
-;; The protocol class is defined from the client's point-of-view.
-;; (The client port is unconjugated, the server port is conjugated.)
-;;
-;; This defines a low level control and status interface to the usrp.
-;; This will probably be replaced (or at least augmented) with a
-;; higher level interface.  For now, this will allow us to get on
-;; the air.
-;;
-;; The subpackets are lists containing the relevant parameters.  The
-;; server will marshall them appropriately.  Below is a list of
-;; subpackets.  See inband-signaling-usb for details.  The opcodes are
-;; symbols; unless otherwise indicated the remaining parameters are
-;; integers.  rid values are limited to 3-bits.
-;;
-;;   (op-ping-fixed rid ping-value)
-;;   (op-ping-fixed-reply rid ping-value)
-;;   (op-write-reg reg-number reg-value)
-;;   (op-write-reg-masked reg-number reg-value mask-value)
-;;   (op-read-reg rid reg-number)
-;;   (op-read-reg-reply rid reg-number reg-value)
-;;   (op-i2c-write i2c-addr u8-vec)
-;;   (op-i2c-read rid i2c-addr nbytes)
-;;   (op-i2c-read-reply rid i2c-addr u8-vec)
-;;   (op-spi-write enables format opt-header-bytes u8-vec)
-;;   (op-spi-read rid enables format opt-header-bytes nbytes)
-;;   (op-spi-read-reply rid u8-vec)
-;;   (op-delay ticks)
-
-
-(define-protocol-class usrp-low-level-cs
-
-  (:outgoing
-
-   (cmd-to-control-channel invocation-handle list-of-subpackets)
-
-   )
-
-  (:incoming
-
-   (response-from-control-channel invocation-handle status list-of-subpackets timestamp)
-
-   )
-  )
-
-;; ----------------------------------------------------------------
-;; usrp-tx
-;;
-;; The protocol class is defined from the client's point-of-view.
-;; (The client port is unconjugated, the server port is conjugated.)
-
-(define-protocol-class usrp-tx
-  (:include usrp-channel)
-  (:include usrp-low-level-cs)
-
-  (:outgoing
-
-   (cmd-xmit-raw-frame invocation-handle channel samples timestamp properties)
-
-   ;; The argument channel must be an integer.  It specifies the
-   ;; channel on which the frame of samples will be be sent.
-   ;;
-   ;; samples must be a uniform numeric vector.  The contents of the
-   ;; sample vector is treated as opaque and is passed on to the FPGA
-   ;; unmodified.  It is the responsibility of the sender to ensure
-   ;; that the binary format is sensible for the current FPGA
-   ;; configuration.
-   ;;
-   ;; timestamp is a 32-bit integer that specifies the time at which
-   ;; the first sample in samples shall be sent to the D/A converter.
-   ;; The format and interpration of time is specified in the file
-   ;; inband-signaling-usb
-   )
-
-  (:incoming
-
-   (response-xmit-raw-frame invocation-handle status)
-
-   ;; If successful, the samples of the associated frame have been
-   ;; transmitted to the USRP.  This message may be used to implement
-   ;; Tx flow control.  The client could for example implement a
-   ;; policy of never having more than 4 unacknowledged
-   ;; cmd-xmit-raw-frame's outstanding.
-
-   )
-  )
-
-;; ----------------------------------------------------------------
-;; usrp-rx
-;;
-;; The protocol class is defined from the client's point-of-view.
-;; (The client port is unconjugated, the server port is conjugated.)
-
-(define-protocol-class usrp-rx
-  (:include usrp-channel)
-  (:include usrp-low-level-cs)
-
-  (:outgoing
-
-   (cmd-start-recv-raw-samples invocation-handle channel)
-
-   ;; The argument channel must be an integer.  It specifies the
-   ;; channel from which frames of samples will be be received.  The
-   ;; server will return response-recv-raw-samples messages until a
-   ;; cmd-stop-recv-raw-samples message is received.
-
-   (cmd-stop-recv-raw-samples invocation-handle channel)
-
-   ;; The argument channel must be an integer.  There is no reply to
-   ;; this message.
-   
-   )
-
-  (:incoming
-
-   (response-recv-raw-samples invocation-handle status samples timestamp channel properties)
-
-   ;; samples is a uniform numeric vector.  The contents of the sample
-   ;; vector is treated as opaque and is passed from the FPGA
-   ;; unmodified.  It is the responsibility of the receiver to decode
-   ;; the binary format as appropriate for the current FPGA
-   ;; configuration.
-   ;;
-   ;; timestamp is a 32-bit integer that specifies the time at which
-   ;; the first sample in samples was received from the A/D converter.
-   ;; The format and interpretation of time is as specified in the
-   ;; file inband-signaling-usb.
-   ;;
-   ;; properties is a dictionary containing additional (key, value)
-   ;; pairs associated with the reception of these samples.  In
-   ;; particular, the map may contain the Received Signal Strength
-   ;; Indication (RSSI) reported by the front end at the time the
-   ;; first sample was received from the A/D.
-
-   )
-  )
-
-
-;; ----------------------------------------------------------------
-;; usrp-server-cs
-;;
-;; Control and status port for usrp-server
-;;
-;; The protocol class is defined from the client's point-of-view.
-;; (The client port is unconjugated, the server port is conjugated.)
-
-(define-protocol-class usrp-server-cs
-
-  (:outgoing
-   (cmd-open invocation-handle which-usrp)
-   (cmd-close invocation-handle)
-   (cmd-max-capacity invocation-handle)
-   (cmd-ntx-chan invocation-handle)
-   (cmd-nrx-chan invocation-handle)
-   (cmd-current-capacity-allocation invocation-handle)
-   )
-
-  (:incoming
-   (response-open invocation-handle status)
-   (response-close invocation-handle status)
-   (response-max-capacity invocation-handle status capacity)
-   (response-ntx-chan invocation-handle status ntx-chan)
-   (response-nrx-chan invocation-handle status nrx-chan)
-   (response-current-capacity-allocation invocation-handle status capacity)
-   )
-  )
diff --git a/usrp/host/lib/inband/usrp_tx.cc b/usrp/host/lib/inband/usrp_tx.cc
deleted file mode 100644 (file)
index 0d4a846..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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_tx.h>
-#include <iostream>
-#include <usb.h>
-#include <mblock/class_registry.h>
-#include <usrp_inband_usb_packet.h>
-#include <fpga_regs_common.h>
-#include <usrp_standard.h>
-#include <stdio.h>
-
-#include <symbols_usrp_tx_cs.h>
-
-typedef usrp_inband_usb_packet transport_pkt;
-
-static const bool verbose = false;
-
-usrp_tx::usrp_tx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(rt, instance_name, user_arg),
-    d_disk_write(false)
-{
-  d_cs = define_port("cs", "usrp-tx-cs", true, mb_port::EXTERNAL);
-  
-  //d_disk_write=true;
-  
-  if(d_disk_write) {
-    d_ofile.open("tx_data.dat",std::ios::binary|std::ios::out);
-    d_cs_ofile.open("tx_cs.dat",std::ios::binary|std::ios::out);
-  }
-}
-
-usrp_tx::~usrp_tx() 
-{
-  if(d_disk_write) {
-    d_ofile.close();
-    d_cs_ofile.close();
-  }
-}
-
-void 
-usrp_tx::initial_transition()
-{
-  
-}
-
-/*!
- * \brief Handles incoming signals to to the m-block, wihch should only ever be
- * a single message: cmd-usrp-tx-write.
- */
-void
-usrp_tx::handle_message(mb_message_sptr msg)
-{
-  pmt_t event = msg->signal();
-  pmt_t port_id = msg->port_id();
-  pmt_t data = msg->data(); 
-
-  // Theoretically only have 1 message to ever expect, but
-  // want to make sure its at least what we want
-  if(pmt_eq(port_id, d_cs->port_symbol())) {
-    
-    if(pmt_eqv(event, s_cmd_usrp_tx_write))
-      write(data);
-  }
-}
-
-/*!
- * \brief Performs the actual writing of data to the USB bus, called by
- * handle_message() when a cmd-usrp-tx-write signal is received.
- *
- * The \p data parameter is a PMT list which contains three mandatory elements,
- * in the following order: an invocation handle, a channel, and a uniform vector
- * of memory which contains the packets to be written to the bus.
- */
-void
-usrp_tx::write(pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  pmt_t channel = pmt_nth(1, data);
-  pmt_t v_packets = pmt_nth(2, data);
-  d_utx = boost::any_cast<usrp_standard_tx_sptr>(pmt_any_ref(pmt_nth(3, data)));
-
-  size_t n_bytes;
-  bool underrun;  // this will need to go, as it is taken care of in the packet headers
-
-  transport_pkt *pkts = (transport_pkt *) pmt_u8vector_writable_elements(v_packets, n_bytes);
-
-  int ret = d_utx->write (pkts, n_bytes, &underrun);
-  
-  if (0 && underrun)
-    fprintf(stderr, "uU");
-
-  if (ret == (int) n_bytes) {
-    if (verbose)
-      std::cout << "[usrp_server] Write of " << n_bytes << " successful\n";
-    // need to respond with the channel so the USRP server knows who to forward the result of
-    // the write to by looking up the owner of the channel
-    d_cs->send(s_response_usrp_tx_write,
-              pmt_list3(invocation_handle, PMT_T, channel));
-  }
-  else {
-    if (verbose)
-      std::cout << "[usrp_server] Error writing " << n_bytes << " bytes to USB bus\n";
-    d_cs->send(s_response_usrp_tx_write,
-              pmt_list3(invocation_handle, PMT_F, channel));
-  }
-    
-  long n_packets = 
-    static_cast<long>(std::ceil(n_bytes / (double)transport_pkt::max_pkt_size()));
-
-  for(int i=0; i < n_packets; i++) {
-    
-    if(d_disk_write) {
-      if(pkts[i].chan() == CONTROL_CHAN)
-        d_cs_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size());
-      else
-        d_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size());
-
-      d_cs_ofile.flush();
-      d_ofile.flush();
-    }
-  }
-
-
-  return;
-}
-
-REGISTER_MBLOCK_CLASS(usrp_tx);
diff --git a/usrp/host/lib/inband/usrp_tx.h b/usrp/host/lib/inband/usrp_tx.h
deleted file mode 100644 (file)
index d3a6f8b..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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_TX_H
-#define INCLUDED_USRP_TX_H
-
-#include <mblock/mblock.h>
-#include <fstream>
-#include "usrp_standard.h"
-
-/*!
- * \brief Implements the low level usb interface to the USRP
- */
-class usrp_tx : public mb_mblock
-{
-  mb_port_sptr         d_cs;
-  usrp_standard_tx_sptr     d_utx;
-  
-  bool d_disk_write;
-  std::ofstream d_ofile;
-  std::ofstream d_cs_ofile;
-  
- public:
-  usrp_tx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg);
-  ~usrp_tx();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- private:
-  void write(pmt_t data);
-};
-  
-
-#endif /* INCLUDED_USRP_TX_H */
-
diff --git a/usrp/host/lib/inband/usrp_tx_stub.cc b/usrp/host/lib/inband/usrp_tx_stub.cc
deleted file mode 100644 (file)
index c78b1a7..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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 <iostream>
-#include <vector>
-#include <usb.h>
-#include <mblock/class_registry.h>
-#include <usrp_tx_stub.h>
-#include <usrp_inband_usb_packet.h>
-#include <fpga_regs_common.h>
-#include "usrp_standard.h"
-#include <stdio.h>
-#include <fstream>
-#include <usrp_rx_stub.h>
-
-#include <symbols_usrp_tx_cs.h>
-
-typedef usrp_inband_usb_packet transport_pkt;
-
-static const bool verbose = false;
-
-usrp_tx_stub::usrp_tx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(rt, instance_name, user_arg),
-    d_disk_write(false)
-{
-  d_cs = define_port("cs", "usrp-tx-cs", true, mb_port::EXTERNAL);
-  
-  //d_disk_write=true;
-  
-  if(d_disk_write) {
-    d_ofile.open("tx_stub_data.dat",std::ios::binary|std::ios::out);
-    d_cs_ofile.open("tx_stub_cs.dat",std::ios::binary|std::ios::out);
-  }
-}
-
-usrp_tx_stub::~usrp_tx_stub() 
-{
-  if(d_disk_write) {
-    d_ofile.close();
-    d_cs_ofile.close();
-  }
-}
-
-void 
-usrp_tx_stub::initial_transition()
-{
-  
-}
-
-void
-usrp_tx_stub::handle_message(mb_message_sptr msg)
-{
-  pmt_t event = msg->signal();
-  pmt_t port_id = msg->port_id();
-  pmt_t data = msg->data(); 
-
-  // Theoretically only have 1 message to ever expect, but
-  // want to make sure its at least what we want
-  if(pmt_eq(port_id, d_cs->port_symbol())) {
-    
-    if(pmt_eqv(event, s_cmd_usrp_tx_write)) 
-      write(data);
-  }
-}
-
-void
-usrp_tx_stub::write(pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  pmt_t channel = pmt_nth(1, data);
-  pmt_t v_packets = pmt_nth(2, data);
-  d_utx = boost::any_cast<usrp_standard_tx *>(pmt_any_ref(pmt_nth(3, data)));
-
-  size_t n_bytes;
-
-  transport_pkt *pkts = (transport_pkt *) pmt_u8vector_writable_elements(v_packets, n_bytes);
-  long n_packets = static_cast<long>(std::ceil(n_bytes / (double)transport_pkt::max_pkt_size()));
-  
-  // Parse the packets looking for C/S packets and dump them to a disk if
-  // necessary
-  for(long i=0; i<n_packets; i++) {
-
-    if(d_disk_write) {
-      if(pkts[i].chan() == CONTROL_CHAN)
-        d_cs_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size());
-      else
-        d_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size());
-
-      d_cs_ofile.flush();
-      d_ofile.flush();
-    }
-
-    if(pkts[i].chan() == CONTROL_CHAN)
-      parse_cs(invocation_handle, pkts[i]);
-  }
-
-  d_cs->send(s_response_usrp_tx_write,
-       pmt_list3(invocation_handle, PMT_T, channel));
-
-  return;
-}
-
-void
-usrp_tx_stub::parse_cs(pmt_t invocation_handle, transport_pkt pkt)
-{
-  
-  long payload_len = pkt.payload_len();
-  long curr_payload = 0;
-      
-  size_t ignore;
-
-  // There is the possibility that the responses for a single USB packet full of
-  // CS packets will not fit back in a single USB packet, considering some
-  // responses are greater than their commands (read registers).
- new_packet:
-  pmt_t v_pkt = pmt_make_u8vector(sizeof(transport_pkt), 0);
-  
-  transport_pkt *q_pkt =
-    (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, ignore);
-      
-  q_pkt->set_header(0, CONTROL_CHAN, 0, 0);
-  q_pkt->set_timestamp(0xffffffff);
-
-  // We dispatch based on the control packet type, however we can extract the
-  // opcode and the length immediately which is consistent in all responses.
-  //
-  // Since each control packet can have multiple responses, we keep reading the
-  // lengths of each subpacket until we reach the payload length.  
-  while(curr_payload < payload_len) {
-
-    pmt_t sub_packet = pkt.read_subpacket(curr_payload);
-    pmt_t op_symbol = pmt_nth(0, sub_packet);
-
-    int len = pkt.cs_len(curr_payload);
-      
-    if(verbose)
-      std::cout << "[USRP_TX_STUB] Parsing subpacket " 
-                << op_symbol << " ... length " << len << std::endl;
-
-    //----------------- PING FIXED ------------------//
-    if(pmt_eq(op_symbol, s_op_ping_fixed)) {
-
-      long rid = pmt_to_long(pmt_nth(1, sub_packet));
-      long pingval = pmt_to_long(pmt_nth(2, sub_packet));
-
-      // Generate a reply and put it in the queue for the RX stub to read
-      if(!q_pkt->cs_ping_reply(rid, pingval))
-        goto new_packet;
-
-      if(verbose)
-        std::cout << "[USRP_TX_STUB] Generated ping response "
-                  << "("
-                  << "RID: " << rid << ", "
-                  << "VAL: " << pingval 
-                  << ")\n";
-    }
-
-    //----------------- READ REG ------------------//
-    if(pmt_eq(op_symbol, s_op_read_reg)) {
-
-      long rid = pmt_to_long(pmt_nth(1, sub_packet));
-      long reg_num = pmt_to_long(pmt_nth(2, sub_packet));
-      long reg_val = 0xdeef;
-
-      // Generate a reply and put it in the queue for the RX stub to read
-      if(!q_pkt->cs_read_reg_reply(rid, reg_num, reg_val))
-        goto new_packet;
-
-      if(verbose)
-        std::cout << "[USRP_TX_STUB] Generated read register response "
-                  << "("
-                  << "RID: " << rid << ", "
-                  << "REG: " << reg_num << ", "
-                  << "VAL: " << reg_val
-                  << ")\n";
-    }
-    
-    //----------------- DELAY ------------------//
-    if(pmt_eq(op_symbol, s_op_delay)) {
-
-      long ticks = pmt_to_long(pmt_nth(1, sub_packet));
-
-      if(verbose)
-        std::cout << "[USRP_TX_STUB] Received delay command "
-                  << "("
-                  << "Ticks: " << ticks
-                  << ")\n";
-    }
-
-    //----------------- WRITE REG ------------------//
-    if(pmt_eq(op_symbol, s_op_write_reg)) {
-
-      pmt_t reg_num = pmt_nth(1, sub_packet);
-      pmt_t reg_val = pmt_nth(2, sub_packet);
-
-      if(verbose)
-        std::cout << "[USRP_TX_STUB] Received write register command "
-                  << "("
-                  << "RegNum: " << reg_num << ", "
-                  << "Val: " << reg_val
-                  << ")\n";
-    }
-    
-    //----------------- WRITE REG MASK ---------------//
-    if(pmt_eq(op_symbol, s_op_write_reg_masked)) {
-
-      pmt_t reg_num = pmt_nth(1, sub_packet);
-      pmt_t reg_val = pmt_nth(2, sub_packet);
-      pmt_t mask    = pmt_nth(3, sub_packet);
-
-      if(verbose)
-        std::cout << "[USRP_TX_STUB] Received write register command "
-                  << "("
-                  << "RegNum: " << reg_num << ", "
-                  << "Val: " << reg_val << ", "
-                  << "Mask: " << mask
-                  << ")\n";
-    }
-
-    //---------------- I2C WRITE ------------------//
-    if(pmt_eq(op_symbol, s_op_i2c_write)) {
-      pmt_t i2c_addr  = pmt_nth(1, sub_packet);
-      pmt_t i2c_data  = pmt_nth(2, sub_packet);
-
-      if(verbose)
-        std::cout << "[USRP_TX_STUB] Received i2c write command "
-                  << "("
-                  << "Addr: " << i2c_addr << ", "
-                  << "Data: " << i2c_data
-                  << ")\n";
-    }
-
-    //---------------- I2C READ ------------------//
-    if(pmt_eq(op_symbol, s_op_i2c_read)) {
-      long rid       = pmt_to_long(pmt_nth(1, sub_packet));
-      long i2c_addr  = pmt_to_long(pmt_nth(2, sub_packet));
-      long i2c_bytes = pmt_to_long(pmt_nth(3, sub_packet));
-
-      // Create data to place as a response, filled with 0xff
-      size_t ignore;
-      pmt_t i2c_data = pmt_make_u8vector(i2c_bytes, 0xff);
-      uint8_t *w_data = (uint8_t *) pmt_u8vector_writable_elements(i2c_data, ignore);
-
-      // Generate a reply and put it in the queue for the RX stub to read
-      if(!q_pkt->cs_i2c_read_reply(rid, i2c_addr, w_data, i2c_bytes))
-        goto new_packet;
-
-      if(verbose)
-        std::cout << "[USRP_TX_STUB] Received i2c read "
-                  << "("
-                  << "RID: " << rid << ", "
-                  << "Addr: " << i2c_addr << ", "
-                  << "Bytes: " << i2c_bytes
-                  << ")\n";
-    }
-    
-    //---------------- SPI WRITE ------------------//
-    if(pmt_eq(op_symbol, s_op_spi_write)) {
-      long enables  = pmt_to_long(pmt_nth(1, sub_packet));
-      long format   = pmt_to_long(pmt_nth(2, sub_packet));
-      long opt      = pmt_to_long(pmt_nth(3, sub_packet));
-      pmt_t data    = pmt_nth(4, sub_packet);
-
-      if(verbose)
-        std::cout << "[USRP_TX_STUB] Received spi write command "
-                  << "("
-                  << "Enables: " << enables << ", "
-                  << "Format: " << format << ", "
-                  << "Options: " << opt << ", "
-                  << "Data: " << data
-                  << ")\n";
-    }
-
-    //---------------- SPI READ ------------------//
-    if(pmt_eq(op_symbol, s_op_spi_read)) {
-      long rid      = pmt_to_long(pmt_nth(1, sub_packet));
-      long enables  = pmt_to_long(pmt_nth(2, sub_packet));
-      long format   = pmt_to_long(pmt_nth(3, sub_packet));
-      long opt      = pmt_to_long(pmt_nth(4, sub_packet));
-      long n_bytes  = pmt_to_long(pmt_nth(5, sub_packet));
-
-      // Create data to place as a fake response
-      size_t ignore;
-      pmt_t spi_data = pmt_make_u8vector(n_bytes, 0xff);
-      uint8_t *w_data = (uint8_t *) pmt_u8vector_writable_elements(spi_data, ignore);
-
-      // Generate a reply and put it in the queue for the RX stub to read
-      if(!q_pkt->cs_spi_read_reply(rid, w_data, n_bytes))
-        goto new_packet;
-
-      if(verbose)
-        std::cout << "[USRP_TX_STUB] Received spi read command "
-                  << "("
-                  << "RID: " << rid << ", "
-                  << "Enables: " << enables << ", "
-                  << "Format: " << format << ", "
-                  << "Options: " << opt << ", "
-                  << "Bytes: " << n_bytes
-                  << ")\n";
-      
-    }
-
-    // Each subpacket has an unaccounted for 2 bytes which is the opcode
-    // and the length field
-    curr_payload += len + 2;
-
-    // All subpackets are 32-bit aligned
-    int align_offset = 4 - (curr_payload % 4);
-
-    if(align_offset != 4)
-      curr_payload += align_offset;
-
-  }
-
-  // If the packet has data in the payload, it needs queued
-  if(q_pkt->payload_len() > 0)
-    d_cs_queue.push(pmt_list2(invocation_handle, v_pkt));
-
-  return;
-}
-
-REGISTER_MBLOCK_CLASS(usrp_tx_stub);
diff --git a/usrp/host/lib/inband/usrp_tx_stub.h b/usrp/host/lib/inband/usrp_tx_stub.h
deleted file mode 100644 (file)
index b81037a..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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_TX_STUB_H
-#define INCLUDED_USRP_TX_STUB_H
-
-#include <mblock/mblock.h>
-#include <vector>
-#include "usrp_standard.h"
-#include <fstream>
-#include <usrp_inband_usb_packet.h>
-
-typedef usrp_inband_usb_packet transport_pkt;
-
-/*!
- * \brief Implements the low level usb interface to the USRP
- */
-class usrp_tx_stub : public mb_mblock
-{
- public:
-
-  mb_port_sptr d_cs;
-  usrp_standard_tx* d_utx;
-  
-  std::ofstream d_ofile;
-  std::ofstream d_cs_ofile;
-
-  bool d_disk_write;
-
- public:
-  usrp_tx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg);
-  ~usrp_tx_stub();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- private:
-  void write(pmt_t data);
-  void parse_cs(pmt_t invocation_handle, transport_pkt pkt);
-};
-  
-
-#endif /* INCLUDED_USRP_TX_STUB_H */
-
diff --git a/usrp/host/lib/inband/usrp_usb_interface.cc b/usrp/host/lib/inband/usrp_usb_interface.cc
deleted file mode 100644 (file)
index fb7109a..0000000
+++ /dev/null
@@ -1,601 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,2008,2009 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_usb_interface.h>
-
-#include <iostream>
-#include <vector>
-#include <usb.h>
-#include <mblock/class_registry.h>
-#include <usrp_inband_usb_packet.h>
-#include <fpga_regs_common.h>
-#include "usrp_rx.h"
-#include <usrp_rx_stub.h>
-#include "usrp_tx.h"
-#include "usrp_standard.h"
-#include <stdio.h>
-#include <usrp_dbid.h>
-
-typedef usrp_inband_usb_packet transport_pkt;
-
-#include <symbols_usrp_interface_cs.h>
-#include <symbols_usrp_tx_cs.h>
-#include <symbols_usrp_rx_cs.h>
-static pmt_t s_shutdown = pmt_intern("%shutdown");
-
-static const bool verbose = false;
-
-
-/*!
- * \brief Initializes the USB interface m-block.
- *
- * The \p user_arg should be a PMT dictionary which can contain optional
- * arguments for the block, such as the decimatoin and interpolation rate.
- */
-usrp_usb_interface::usrp_usb_interface(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(rt, instance_name, user_arg),
-  d_fake_usrp(false),
-  d_rx_reading(false),
-  d_interp_tx(128),
-  d_decim_rx(128),
-  d_rf_freq(-1),
-  d_rbf("inband_tx_rx.rbf")
-{
-  // Dictionary for arguments to all of the components
-  pmt_t usrp_dict = user_arg;
-  
-  // Default TX/RX interface
-  std::string tx_interface = "usrp_tx";
-  std::string rx_interface = "usrp_rx";
-  
-  if (pmt_is_dict(usrp_dict)) {
-
-    // The 'fake-usrp' key enables the TX and RX stubs if PMT_T
-    if(pmt_t fake_usrp = pmt_dict_ref(usrp_dict, 
-                                      pmt_intern("fake-usrp"), 
-                                      PMT_NIL)) {
-      if(pmt_eqv(fake_usrp, PMT_T)) {
-        tx_interface = "usrp_tx_stub";
-        rx_interface = "usrp_rx_stub";
-        d_fake_usrp=true;
-      }
-    }
-
-    // Read the TX interpolations
-    if(pmt_t interp_tx = pmt_dict_ref(usrp_dict, 
-                                      pmt_intern("interp-tx"), 
-                                      PMT_NIL)) {
-      if(!pmt_eqv(interp_tx, PMT_NIL)) 
-        d_interp_tx = pmt_to_long(interp_tx);
-    }
-    
-    // Read the RX decimation rate
-    if(pmt_t decim_rx = pmt_dict_ref(usrp_dict, 
-                                      pmt_intern("decim-rx"), 
-                                      PMT_NIL)) {
-      if(!pmt_eqv(decim_rx, PMT_NIL)) 
-        d_decim_rx = pmt_to_long(decim_rx);
-    }
-
-    // Read the RBF
-    if(pmt_t rbf = pmt_dict_ref(usrp_dict, 
-                                pmt_intern("rbf"), 
-                                PMT_NIL)) {
-      if(!pmt_eqv(rbf, PMT_NIL)) 
-        d_rbf = pmt_symbol_to_string(rbf);
-    }
-
-    // The RF center frequency
-    if(pmt_t rf_freq = pmt_dict_ref(usrp_dict, 
-                                pmt_intern("rf-freq"), 
-                                PMT_NIL)) {
-      if(!pmt_eqv(rf_freq, PMT_NIL)) 
-        d_rf_freq = pmt_to_double(rf_freq);
-    }
-  }
-  
-  if (verbose) {
-    std::cout << "[USRP_USB_INTERFACE] Setting USRP RBF to " 
-              << d_rbf << std::endl;
-    
-    std::cout << "[USRP_USB_INTERFACE] Setting TX interpolation to " 
-              << d_interp_tx << std::endl;
-          
-    std::cout << "[USRP_USB_INTERFACE] Setting RX interpolation to " 
-              << d_decim_rx << std::endl;
-
-    std::cout << "[USRP_USB_INTERFACE] Using TX interface: " 
-              << tx_interface << "\n";
-
-    std::cout << "[USRP_USB_INTERFACE] Using RX interface: " 
-              << rx_interface << "\n";
-
-  }
-
-  d_cs = define_port("cs", "usrp-interface-cs", true, mb_port::EXTERNAL);      
-  d_rx_cs = define_port("rx_cs", "usrp-rx-cs", false, mb_port::INTERNAL);      
-  d_tx_cs = define_port("tx_cs", "usrp-tx-cs", false, mb_port::INTERNAL);      
-
-  // Connect to TX and RX
-  define_component("tx", tx_interface, usrp_dict);
-  define_component("rx", rx_interface, usrp_dict);
-  connect("self", "rx_cs", "rx", "cs");
-  connect("self", "tx_cs", "tx", "cs");
-  
-  // FIXME: the code should query the FPGA to retrieve the number of channels and such
-  d_ntx_chan = 2;
-  d_nrx_chan = 2;
-}
-
-usrp_usb_interface::~usrp_usb_interface() 
-{ 
-
-}
-
-void 
-usrp_usb_interface::initial_transition()
-{
-
-}
-
-/*!
- * \brief Handles all incoming signals to the block from the lowest m-blocks
- * which read/write to the bus, or the higher m-block which is the USRP server.
- */
-void
-usrp_usb_interface::handle_message(mb_message_sptr msg)
-{
-  pmt_t event = msg->signal();         // the "name" of the message
-  pmt_t port_id = msg->port_id();      // which port it came in on
-  pmt_t data = msg->data();
-  pmt_t invocation_handle;
-
-  if (pmt_eq(event, s_shutdown))       // ignore (for now)
-    return;
-
-  //------------- CONTROL / STATUS -------------//
-  if (pmt_eq(port_id, d_cs->port_symbol())) {  
-
-    //------------ OPEN --------------//
-    if (pmt_eq(event, s_cmd_usrp_open)){
-      handle_cmd_open(data);
-      return;
-    }
-    //----------- CLOSE -------------//
-    else if (pmt_eq(event, s_cmd_usrp_close)) {
-      handle_cmd_close(data);
-      return;
-    }
-    //---------- NTX CHAN ----------//
-    else if (pmt_eq(event, s_cmd_usrp_ntx_chan)) {
-      invocation_handle = pmt_nth(0, data);
-      d_cs->send(s_response_usrp_ntx_chan, 
-                 pmt_list2(invocation_handle, 
-                           pmt_from_long(d_ntx_chan)));
-      return;
-    }
-    //---------- NRX CHAN ----------//
-    else if (pmt_eq(event, s_cmd_usrp_nrx_chan)) {
-      invocation_handle = pmt_nth(0, data);
-      d_cs->send(s_response_usrp_nrx_chan, 
-                 pmt_list2(invocation_handle, 
-                           pmt_from_long(d_nrx_chan)));
-      return;
-    }
-    //------------ WRITE -----------//
-    else if(pmt_eq(event, s_cmd_usrp_write)) {
-      handle_cmd_write(data);
-      return;
-    }
-    //-------- START READING --------//
-    else if(pmt_eq(event, s_cmd_usrp_start_reading)) {
-      handle_cmd_start_reading(data);
-      return;
-    }
-    //-------- STOP READING --------//
-    else if(pmt_eq(event, s_cmd_usrp_stop_reading)) {
-      handle_cmd_stop_reading(data);
-      return;
-    }
-
-    goto unhandled;
-  }
-
-  //---------------- RX ------------------//
-  if (pmt_eq(port_id, d_rx_cs->port_symbol())) {       
-
-    // Relay reads back up
-    if(pmt_eq(event, s_response_usrp_rx_read))  {
-      d_cs->send(s_response_usrp_read, data);
-      return;
-    }
-
-    goto unhandled;
-  }
-  
-  //---------------- TX ------------------//
-  if (pmt_eq(port_id, d_tx_cs->port_symbol())) {       
-
-    if(pmt_eq(event, s_response_usrp_tx_write))  {
-
-      pmt_t invocation_handle = pmt_nth(0, data);
-      pmt_t status = pmt_nth(1, data);
-      pmt_t channel = pmt_nth(2, data);
-
-      d_cs->send(s_response_usrp_write,
-                 pmt_list3(invocation_handle,
-                           status,
-                           channel));
-
-      return;
-    }
-
-    goto unhandled;
-  }
-
- unhandled:
-  std::cout << "[USRP_USB_INTERFACE] unhandled msg: " << msg << std::endl;
-}
-
-/*!
- * \brief Called by the handle_message() method when the incoming signal is to
- * open a USB connection to the USRP (cmd-usrp-open).
- *
- * The \p data parameter is a PMT list, where the elements are an invocation
- * handle and the USRP number.
- */
-void
-usrp_usb_interface::handle_cmd_open(pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  long which_usrp = pmt_to_long(pmt_nth(1, data));
-  pmt_t reply_data;
-  if(d_fake_usrp) {
-    d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T));
-    return;
-  }
-
-  if (verbose)
-    std::cout << "[USRP_USB_INTERFACE] Handling open request for USRP " << which_usrp << "\n";
-
-  // Open up a standard RX and TX for communication with the USRP
-   
-  d_utx = usrp_standard_tx::make(which_usrp,
-                                d_interp_tx,
-                                1,                     // 1 channel
-                                -1,          // mux
-                                4096,        // USB block size
-                                16,          // nblocks for async transfers
-                                d_rbf
-                                );
-  
-  if(d_utx==0) {
-    if (verbose)
-      std::cout << "[USRP_USB_INTERFACE] Failed to open TX\n";
-    reply_data = pmt_list2(invocation_handle, PMT_F);
-    d_cs->send(s_response_usrp_open, reply_data);
-    return;
-  }
-
-  // Perform TX daughterboard tuning
-  double target_freq;
-  unsigned int mux;
-  int tgain, rgain;
-  float input_rate;
-  bool ok;
-  usrp_tune_result r;
-
-  // Cast to usrp_basic and then detect daughterboards
-  d_ub_tx = d_utx;
-  usrp_subdev_spec tspec = pick_tx_subdevice();
-  db_base_sptr tsubdev = d_ub_tx->selected_subdev(tspec);
-
-  // Set the TX mux value
-  mux = d_utx->determine_tx_mux_value(tspec);
-  d_utx->set_mux(mux);
-  
-  // Set the TX gain and determine rate
-  tgain = tsubdev->gain_max();
-  tsubdev->set_gain(tgain);
-  input_rate = d_ub_tx->converter_rate() / d_utx->interp_rate();
-
-  // Perform the actual tuning, if no frequency specified then pick
-  if(d_rf_freq==-1)
-    target_freq = tsubdev->freq_min()+((tsubdev->freq_max()-tsubdev->freq_min())/2.0);
-  else 
-    target_freq = d_rf_freq;
-  ok = d_utx->tune(tsubdev->which(), tsubdev, target_freq, &r);
-  tsubdev->set_enable(true);
-  
-  if(verbose) {
-    printf("TX Subdevice name is %s\n", tsubdev->name().c_str());
-    printf("TX Subdevice freq range: (%g, %g)\n",
-       tsubdev->freq_min(), tsubdev->freq_max());
-    printf("mux: %#08x\n",  mux);
-    printf("target_freq:     %f\n", target_freq);
-    printf("ok:              %s\n", ok ? "true" : "false");
-    printf("gain:            %d\n", tgain);
-    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);
-  }
-
-  if(!ok) {
-    std::cerr << "[USRP_USB_INTERFACE] Failed to set center frequency on TX\n";
-    reply_data = pmt_list2(invocation_handle, PMT_F);
-    d_cs->send(s_response_usrp_open, reply_data);
-    return;
-  }
-
-  d_utx->start();
-
-  if (verbose)
-    std::cout << "[USRP_USB_INTERFACE] Setup TX channel\n";
-
-  d_urx =
-    usrp_standard_rx::make (which_usrp,
-                           d_decim_rx,         
-                           1,                  // nchan
-                           -1,           // mux
-                           0,            // set blank mode to start
-                           4096,         // USB block size
-                           16,           // number of blocks for async transfers
-          d_rbf);
-
-  if(!d_urx) {
-    if (verbose)
-      std::cout << "[usrp_server] Failed to open RX\n";
-    reply_data = pmt_list2(invocation_handle, PMT_F);
-    d_cs->send(s_response_usrp_open, reply_data);
-    return;
-  }
-  
-  // Cast to usrp_basic and then detect daughterboards
-  d_ub_rx = d_urx;
-  usrp_subdev_spec rspec = pick_rx_subdevice();
-  db_base_sptr rsubdev = d_ub_rx->selected_subdev(rspec);
-
-  // Set the RX mux value
-  mux = d_urx->determine_rx_mux_value(rspec);
-  d_urx->set_mux(mux);
-  
-  // Set the RX gain and determine rate
-  rgain = rsubdev->gain_max()/2.0;
-  rsubdev->set_gain(rgain);
-  input_rate = d_ub_rx->converter_rate() / d_urx->decim_rate();
-
-  ok = d_urx->tune(rsubdev->which(), rsubdev, target_freq, &r);
-  rsubdev->set_enable(true);
-  
-  if(verbose) {
-    printf("RX Subdevice name is %s\n", rsubdev->name().c_str());
-    printf("RX Subdevice freq range: (%g, %g)\n",
-       rsubdev->freq_min(), rsubdev->freq_max());
-    printf("mux: %#08x\n",  mux);
-    printf("target_freq:     %f\n", target_freq);
-    printf("ok:              %s\n", ok ? "true" : "false");
-    printf("gain:            %d\n", rgain);
-    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);
-  }
-  
-  if(!ok) {
-    std::cerr << "[USRP_USB_INTERFACE] Failed to set center frequency on RX\n";
-    reply_data = pmt_list2(invocation_handle, PMT_F);
-    d_cs->send(s_response_usrp_open, reply_data);
-    return;
-  }
-
-  if (verbose)
-    std::cout << "[USRP_USB_INTERFACE] Setup RX channel\n";
-    
-//  d_utx->_write_fpga_reg(FR_DEBUG_EN,0xf);
-//  d_utx->_write_oe(0, 0xffff, 0xffff);
-//  d_urx->_write_oe(0, 0xffff, 0xffff);
-//  d_utx->_write_oe(1, 0xffff, 0xffff);
-//  d_urx->_write_oe(1, 0xffff, 0xffff);
-
-  d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T));
-}
-
-/*!
- * \brief Called by the handle_message() method when the incoming signal is to
- * write data to the USB bus (cmd-usrp-write). 
- *
- * The \p data parameter is a PMT list containing 3 mandatory elements in the
- * following order: an invocation handle, channel, and a uniform vector
- * representation of the packets.
- */
-void
-usrp_usb_interface::handle_cmd_write(pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  pmt_t channel = pmt_nth(1, data);
-  pmt_t pkts = pmt_nth(2, data);
-
-  pmt_t tx_handle = pmt_make_any(d_utx);
-
-  d_tx_cs->send(s_cmd_usrp_tx_write, 
-                pmt_list4(invocation_handle, 
-                          channel,
-                          pkts,
-                          tx_handle));
-}
-
-/*!
- * \brief Called by the handle_message() method when the incoming signal is to
- * start reading data from the USB bus (cmd-usrp-start-reading).
- *
- * The \p data parameter is a PMT list with a single element: an invocation
- * handle which can be returned with the response.
- */
-void
-usrp_usb_interface::handle_cmd_start_reading(pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  
-  if(verbose)
-    std::cout << "[USRP_USB_INTERFACE] Starting RX...\n";
-
-  if(!d_fake_usrp)
-    d_urx->start();
-
-  pmt_t rx_handle = pmt_make_any(d_urx);
-
-  d_rx_cs->send(s_cmd_usrp_rx_start_reading, pmt_list2(PMT_NIL, rx_handle));
-
-  d_rx_reading = true;
-
-  return;
-}
-
-/*!
- * \brief Called by the handle_message() method when the incoming signal is to
- * stop reading data from the USB bus (cmd-usrp-stop-reading).
- *
- * The \p data parameter is a PMT list with a single element: an invocation
- * handle which can be returned with the response.
- */
-void
-usrp_usb_interface::handle_cmd_stop_reading(pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  
-  if(!d_fake_usrp) {
-    if(verbose)
-      std::cout << "[USRP_USB_INTERFACE] Stopping RX...\n";
-    usrp_rx_stop = true;
-
-    // Used to allow a read() being called by a lower layer to complete before
-    // stopping, else there can be partial data left on the bus and can generate
-    // errors.
-    while(usrp_rx_stop) {usleep(1);}
-    d_urx->stop();
-  }
-  else {
-    if(verbose)
-      std::cout << "[USRP_USB_INTERFACE] Stopping fake RX...\n";
-    usrp_rx_stop_stub = true;  // extern to communicate with stub to wait
-  }
-
-  d_rx_reading = false;
-
-  return;
-}
-
-/*!
- * \brief Called by the handle_message() method when the incoming signal is to
- * close the USB connection to the USRP.
- *
- * The \p data parameter is a PMT list with a single element: an invocation
- * handle which can be returned with the response.
- */
-void
-usrp_usb_interface::handle_cmd_close(pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-
-  if(d_rx_reading)
-    handle_cmd_stop_reading(PMT_NIL);
-
-  if(d_fake_usrp) {
-    d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T));
-    return;
-  }
-  
-  if (verbose)
-    std::cout << "[USRP_USB_INTERFACE] Handling close request for USRP\n";
-
-  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);
-}
-
-usrp_subdev_spec
-usrp_usb_interface::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_BASIC_RX
-  };
-
-  std::vector<int> candidates(dbids, dbids+(sizeof(dbids)/sizeof(int)));
-  return pick_subdev(d_ub_rx, candidates);
-}
-
-usrp_subdev_spec
-usrp_usb_interface::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(d_ub_tx, candidates);
-}
-
-usrp_subdev_spec
-usrp_usb_interface::pick_subdev(boost::shared_ptr<usrp_basic> d_usrp_basic, std::vector<int> candidates)
-{
-  int dbid0 = d_usrp_basic->selected_subdev(usrp_subdev_spec(0, 0))->dbid();
-  int dbid1 = d_usrp_basic->selected_subdev(usrp_subdev_spec(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!");
-}
-
-
-REGISTER_MBLOCK_CLASS(usrp_usb_interface);
diff --git a/usrp/host/lib/inband/usrp_usb_interface.h b/usrp/host/lib/inband/usrp_usb_interface.h
deleted file mode 100644 (file)
index 4d7750a..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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_USB_INTERFACE_H
-#define INCLUDED_USRP_USB_INTERFACE_H
-
-#include <mblock/mblock.h>
-#include <vector>
-#include "usrp_standard.h"
-
-/*!
- * \brief Implements the low level usb interface to the USRP
- */
-class usrp_usb_interface : public mb_mblock
-{
- public:
-
-  usrp_standard_tx_sptr d_utx;
-  usrp_standard_rx_sptr d_urx;
-
-  boost::shared_ptr<usrp_basic> d_ub_tx;
-  boost::shared_ptr<usrp_basic> d_ub_rx;
-  
-  mb_port_sptr d_cs;
-  mb_port_sptr  d_rx_cs;
-  mb_port_sptr  d_tx_cs;
-  
-  long d_ntx_chan;
-  long d_nrx_chan;
-
-  bool d_fake_usrp;
-
-  bool d_rx_reading;
-
-  long d_interp_tx;
-  long d_decim_rx;
-
-  double d_rf_freq;
-
-  std::string d_rbf;
-
- public:
-  usrp_usb_interface(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg);
-  ~usrp_usb_interface();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-  usrp_subdev_spec pick_rx_subdevice();
-  usrp_subdev_spec pick_tx_subdevice();
-  usrp_subdev_spec pick_subdev(boost::shared_ptr<usrp_basic> d_usrp_basic, std::vector<int> candidates);
-
- private:
-  void handle_cmd_open(pmt_t data);
-  void handle_cmd_close(pmt_t data);
-  void handle_cmd_write(pmt_t data);
-  void handle_cmd_start_reading(pmt_t data);
-  void handle_cmd_stop_reading(pmt_t data);
-};
-  
-
-#endif /* INCLUDED_USRP_USB_INTERFACE_H */
diff --git a/usrp/host/lib/legacy/Makefile.am b/usrp/host/lib/legacy/Makefile.am
deleted file mode 100644 (file)
index e1b1b85..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-#
-#  USRP - Universal Software Radio Peripheral
-# 
-#  Copyright (C) 2003,2004,2006,2007,2008,2009 Free Software Foundation, Inc.
-# 
-#  This program is free software; you can redistribute it and/or modify
-#  it under the terms of the GNU General Public License as published by
-#  the Free Software Foundation; either version 3 of the License, or
-#  (at your option) any later version.
-# 
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-# 
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA
-# 
-
-include $(top_srcdir)/Makefile.common
-
-common_INCLUDES = $(USRP_INCLUDES)
-
-lib_LTLIBRARIES = libusrp.la
-
-libusrp_la_common_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 $(BOOST_LDFLAGS)
-
-libusrp_la_common_LIBADD =             \
-       $(USB_LIBS)                     \
-       $(BOOST_THREAD_LIB)             \
-       ../../misc/libmisc.la
-
-# darwin fusb requires omnithreads
-if FUSB_TECH_darwin
-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) $(BOOST_CPPFLAGS) $(WITH_INCLUDES)
-libusrp_la_LIBADD = $(libusrp_la_common_LIBADD)
-libusrp_la_LDFLAGS = $(libusrp_la_common_LDFLAGS)
-endif
-
-EXTRA_DIST =                           \
-       std_paths.h.in                  \
-       usrp_dbid.dat                   
-
-BUILT_SOURCES =                        \
-       usrp_dbid.h
-
-BUILT_SOURCES += usrp_dbid.cc \
-                usrp_dbid.py
-
-# ----------------------------------------------------------------
-# FUSB_TECH is set at configure time by way of
-#   usrp/config/usrp_fusb_tech.m4.
-#   It indicates which fast usb strategy we should be building.
-#   We currently implement "generic", "darwin", "win32" and "linux"
-
-
-generic_CODE =                                 \
-       fusb_generic.cc                 \
-       fusb_sysconfig_generic.cc
-
-darwin_CODE =                          \
-       fusb_darwin.cc                  \
-       fusb_sysconfig_darwin.cc        \
-       README_OSX                      \
-       circular_buffer.h               \
-       circular_linked_list.h          \
-       darwin_libusb.h                 \
-       mld_threads.h                   
-
-win32_CODE =                           \
-       fusb_win32.cc                   \
-       fusb_sysconfig_win32.cc         
-
-linux_CODE =                           \
-       fusb_linux.cc                   \
-       fusb_sysconfig_linux.cc         
-
-ra_wb_CODE =                           \
-       fusb_ra_wb.cc                   \
-       fusb_sysconfig_ra_wb.cc
-
-
-#
-# include each <foo>_CODE entry here...
-#
-EXTRA_libusrp_la_SOURCES =             \
-       $(generic_CODE)                 \
-       $(darwin_CODE)                  \
-       $(win32_CODE)                   \
-       $(linux_CODE)                   \
-       $(ra_wb_CODE)
-
-
-# work around automake deficiency
-libusrp_la_common_SOURCES =            \
-       fusb.cc                         \
-       md5.c                           \
-       usrp_basic.cc                   \
-       usrp_config.cc                  \
-       usrp_dbid.cc                    \
-       usrp_local_sighandler.cc        \
-       usrp_prims.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
-
-
-
-if FUSB_TECH_generic
-libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(generic_CODE)
-endif
-
-if FUSB_TECH_darwin
-libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(darwin_CODE)
-endif
-
-if FUSB_TECH_win32
-libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(win32_CODE)
-endif
-
-if FUSB_TECH_linux
-libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(linux_CODE)
-endif
-
-if FUSB_TECH_ra_wb
-libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(ra_wb_CODE)
-endif
-
-include_HEADERS =                      \
-       db_base.h                       \
-       db_basic.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_xcvr2450.h                   \
-       usrp_basic.h                    \
-       usrp_bytesex.h                  \
-       usrp_config.h                   \
-       usrp_dbid.h                     \
-       usrp_prims.h                    \
-       usrp_slots.h                    \
-       usrp_standard.h                 \
-       usrp_subdev_spec.h              \
-       usrp_tune_result.h              
-
-noinst_HEADERS =                       \
-       ad9862.h                        \
-       db_base_impl.h                  \
-       db_boards.h                     \
-       db_wbx.h                        \
-       fusb.h                          \
-       fusb_darwin.h                   \
-       fusb_generic.h                  \
-       fusb_linux.h                    \
-       fusb_ra_wb.h                    \
-       fusb_win32.h                    \
-       md5.h                           \
-       rate_to_regval.h                \
-       usrp_local_sighandler.h         
-
-if PYTHON
-usrppython_PYTHON =                    \
-       usrp_dbid.py                    
-
-noinst_PYTHON =                                \
-       gen_usrp_dbid.py                \
-       check_data.py                   \
-       dump_data.py
-
-swiginclude_HEADERS = db_base.i
-endif
-
-# common way for generating sources from templates when using
-# BUILT_SOURCES, using parallel build protection.
-gen_sources = $(BUILT_SOURCES)
-gen_sources_deps = gen_usrp_dbid.py usrp_dbid.dat
-par_gen_command = PYTHONPATH=$(top_srcdir)/usrp/src srcdir=$(srcdir) $(PYTHON) $(srcdir)/gen_usrp_dbid.py $(srcdir)/usrp_dbid.dat
-include $(top_srcdir)/Makefile.par.gen
diff --git a/usrp/host/lib/legacy/README_OSX b/usrp/host/lib/legacy/README_OSX
deleted file mode 100644 (file)
index 37026f2..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-USRP Darwin Fast USB Changes
-Version 0.2 of 2006-04-27
-Michael Dickens <mdickens @at@ nd .dot. edu>
-
-The files included in this archive are:
-
-circular_buffer.h
-circular_linked_list.h
-darwin_libusb.h
-fusb_darwin.cc
-fusb_darwin.h
-mld_threads.h
-
-These files allow GNURadio code for Darwin / MaxOS X to talk to the
-USRP via USB 2.0 at rates up to around 30 Mega-Bytes/sec (MBps), up
-from 4-8 MBps without the changes.
-
-I implemented the buffering myself; there are probably GR buffers
-available which would do the work but as this is "beta" software it's
-a good place to start.  Speed improvements are made by porting
-LIBUSB's non-true async bulk read and write functions into USRP's
-"fusb", and upgrading them to handle -true- async transfers.
-Unfortunately, the easiest way to do this is to spawn a thread or 2 to
-handle the "async" part of the transfers.  This implementation uses
-Darwin's pthreads to do the work for mutexes, conditions, and threads.
-Previous implementations (0.1 and before) used "omni_threads" as
-provided by gnuradio-core, which caused issues with compiling and
-execution ... I'm glad that this is no longer the case.
-
-As far as I have tested, there is no way to improve the throughput to
-32+ MBps without moving into Darwin's "port"s ... a kernel-level data
-transport method with a user/application layer for USB-specific
-functions.  Unfortunately, Apple's documentation for these "port"s is
-minimal; I have learned more from reading the Darwin source code
-< http://darwinsource.opendarwin.org/ > than by reading Apple's
-documents!  This would also require -not- using LIBUSB, of which the
-removal from the rest of the USRP code would be potentially tedious.
-
-If you run into issues either compiling or testing the USRP on
-OSX, please send me a note.
-
-(1) Go through the bootstrap, configure, compile, and install as
-usual (e.g. see < http://www.nd.edu/~mdickens/GNURadio/ > for my
-usual).
-
-(2) from .../usrp/host/apps :  run the scripts
-++++++++++++++++
-./test_usrp_standard_tx
-./test_usrp_standard_rx
-++++++++++++++++
-
-For -all- systems I've tested on thus far, both of these return
-exactly 41 overruns / underruns, and -most- systems start out with a
-stalled pipe.  This stall comes in a usb_control function call to
-LIBUSB; one would have to change the LIBUSB code to handle this issue.
-
-(3) from gr-build/gnuradio-examples/python/usrp :
-++++++++++++++++
-./benchmark_usb.py
-++++++++++++++++
-
-(4) If you get to here, the try doing the FM receiver (gui or not).
-If that sounds correct, then the USB is working.  Yay!
\ No newline at end of file
diff --git a/usrp/host/lib/legacy/ad9862.h b/usrp/host/lib/legacy/ad9862.h
deleted file mode 100644 (file)
index 4375d93..0000000
+++ /dev/null
@@ -1,221 +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.
- */
-
-#ifndef INCLUDED_AD9862_H
-#define INCLUDED_AD9862_H
-
-/*
- * Analog Devices AD9862 registers and some fields
- */
-
-#define BEGIN_AD9862   namespace ad9862 {
-#define        END_AD962       }
-#define        DEF static const int
-
-BEGIN_AD9862;
-
-DEF REG_GENERAL                =  0;
-DEF REG_RX_PWR_DN      =  1;
-DEF    RX_PWR_DN_VREF_DIFF             = (1 << 7);
-DEF    RX_PWR_DN_VREF                  = (1 << 6);
-DEF    RX_PWR_DN_RX_DIGIGAL            = (1 << 5);
-DEF    RX_PWR_DN_RX_B                  = (1 << 4);
-DEF    RX_PWR_DN_RX_A                  = (1 << 3);
-DEF    RX_PWR_DN_BUF_B                 = (1 << 2);
-DEF    RX_PWR_DN_BUF_A                 = (1 << 1);
-DEF    RX_PWR_DN_ALL                   = (1 << 0);
-
-DEF REG_RX_A           =  2;   // bypass input buffer / RxPGA
-DEF REG_RX_B           =  3;   // pypass input buffer / RxPGA
-DEF    RX_X_BYPASS_INPUT_BUFFER        = (1 << 7);
-
-DEF REG_RX_MISC                =  4;
-DEF    RX_MISC_HS_DUTY_CYCLE           = (1 << 2);
-DEF    RX_MISC_SHARED_REF              = (1 << 1);
-DEF    RX_MISC_CLK_DUTY                = (1 << 0);
-
-DEF REG_RX_IF          =  5;
-DEF    RX_IF_THREE_STATE               = (1 << 4);
-DEF    RX_IF_USE_CLKOUT1               = (0 << 3);     
-DEF    RX_IF_USE_CLKOUT2               = (1 << 3);     // aka Rx Retime
-DEF    RX_IF_2S_COMP                   = (1 << 2);
-DEF    RX_IF_INV_RX_SYNC               = (1 << 1);
-DEF    RX_IF_MUX_OUT                   = (1 << 0);
-
-DEF REG_RX_DIGITAL     =  6;
-DEF    RX_DIGITAL_2_CHAN               = (1 << 3);
-DEF    RX_DIGITAL_KEEP_MINUS_VE        = (1 << 2);
-DEF    RX_DIGITAL_HILBERT              = (1 << 1);
-DEF    RX_DIGITAL_DECIMATE             = (1 << 0);
-
-DEF REG_RESERVED_7     =  7;
-
-DEF REG_TX_PWR_DN      =  8;
-DEF    TX_PWR_DN_ALT_TIMING_MODE       = (1 << 5);
-DEF    TX_PWR_DN_TX_OFF_ENABLE         = (1 << 4);
-DEF    TX_PWR_DN_TX_DIGITAL            = (1 << 3);
-DEF    TX_PWR_DN_TX_ANALOG_B           = 0x4;
-DEF    TX_PWR_DN_TX_ANALOG_A           = 0x2;
-DEF    TX_PWR_DN_TX_ANALOG_BOTH        = 0x7;
-
-DEF REG_RESERVED_9     =  9;
-
-DEF REG_TX_A_OFFSET_LO = 10;
-DEF REG_TX_A_OFFSET_HI = 11;
-DEF REG_TX_B_OFFSET_LO = 12;
-DEF REG_TX_B_OFFSET_HI = 13;
-
-DEF REG_TX_A_GAIN      = 14;   // fine trim for matching
-DEF REG_TX_B_GAIN      = 15;   // fine trim for matching
-DEF    TX_X_GAIN_COARSE_FULL           = (3 << 6);
-DEF    TX_X_GAIN_COARSE_1_HALF         = (1 << 6);
-DEF    TX_X_GAIN_COARSE_1_ELEVENTH     = (0 << 6);
-
-DEF REG_TX_PGA         = 16;   // 20 dB continuous gain in 0.1 dB steps
-                               // 0x00 = min gain (-20 dB)
-                               // 0xff = max gain (  0 dB)
-
-DEF REG_TX_MISC                = 17;
-DEF    TX_MISC_SLAVE_ENABLE            = (1 << 1);
-DEF    TX_MISC_TX_PGA_FAST             = (1 << 0);
-
-DEF REG_TX_IF          = 18;
-DEF    TX_IF_USE_CLKOUT2               = (0 << 6);
-DEF    TX_IF_USE_CLKOUT1               = (1 << 6);     // aka Tx Retime
-DEF    TX_IF_I_FIRST                   = (0 << 5);
-DEF    TX_IF_Q_FIRST                   = (1 << 5);
-DEF    TX_IF_INV_TX_SYNC               = (1 << 4);
-DEF    TX_IF_2S_COMP                   = (1 << 3);
-DEF    TX_IF_INVERSE_SAMPLE            = (1 << 2);
-DEF    TX_IF_TWO_EDGES                 = (1 << 1);
-DEF    TX_IF_INTERLEAVED               = (1 << 0);
-
-DEF REG_TX_DIGITAL     = 19;
-DEF    TX_DIGITAL_2_DATA_PATHS         = (1 << 4);
-DEF    TX_DIGITAL_KEEP_NEGATIVE        = (1 << 3);
-DEF    TX_DIGITAL_HILBERT              = (1 << 2);
-DEF    TX_DIGITAL_INTERPOLATE_NONE     = 0x0;
-DEF    TX_DIGITAL_INTERPOLATE_2X       = 0x1;
-DEF    TX_DIGITAL_INTERPOLATE_4X       = 0x2;
-
-DEF REG_TX_MODULATOR   = 20;
-DEF    TX_MODULATOR_NEG_FINE_TUNE      = (1 << 5);
-DEF    TX_MODULATOR_DISABLE_NCO        = (0 << 4);
-DEF    TX_MODULATOR_ENABLE_NCO         = (1 << 4);     // aka Fine Mode
-DEF    TX_MODULATOR_REAL_MIX_MODE      = (1 << 3);
-DEF    TX_MODULATOR_NEG_COARSE_TUNE    = (1 << 2);
-DEF    TX_MODULATOR_COARSE_MODULATION_NONE     = 0x0;
-DEF    TX_MODULATOR_COARSE_MODULATION_F_OVER_4 = 0x1;
-DEF    TX_MODULATOR_COARSE_MODULATION_F_OVER_8 = 0x2;
-DEF    TX_MODULATOR_CM_MASK                    = 0x7;
-
-
-DEF REG_TX_NCO_FTW_7_0 = 21;
-DEF REG_TX_NCO_FTW_15_8        = 22;
-DEF REG_TX_NCO_FTW_23_16= 23;
-
-DEF REG_DLL            = 24;
-DEF    DLL_DISABLE_INTERNAL_XTAL_OSC   = (1 << 6);     // aka Input Clock Ctrl
-DEF    DLL_ADC_DIV2                    = (1 << 5);
-DEF    DLL_MULT_1X                     = (0 << 3);
-DEF    DLL_MULT_2X                     = (1 << 3);
-DEF    DLL_MULT_4X                     = (2 << 3);
-DEF    DLL_PWR_DN                      = (1 << 2);
-// undefined bit                       = (1 << 1);
-DEF    DLL_FAST                        = (1 << 0);
-
-DEF REG_CLKOUT         = 25;
-DEF    CLKOUT2_EQ_DLL                  = (0 << 6);
-DEF    CLKOUT2_EQ_DLL_OVER_2           = (1 << 6);
-DEF    CLKOUT2_EQ_DLL_OVER_4           = (2 << 6);
-DEF    CLKOUT2_EQ_DLL_OVER_8           = (3 << 6);
-DEF    CLKOUT_INVERT_CLKOUT2           = (1 << 5);
-DEF    CLKOUT_DISABLE_CLKOUT2          = (1 << 4);
-// undefined bit                       = (1 << 3);
-// undefined bit                       = (1 << 2);
-DEF    CLKOUT_INVERT_CLKOUT1           = (1 << 1);
-DEF    CLKOUT_DISABLE_CLKOUT1          = (1 << 0);
-
-DEF REG_AUX_ADC_A2_LO  = 26;
-DEF REG_AUX_ADC_A2_HI  = 27;
-DEF REG_AUX_ADC_A1_LO  = 28;
-DEF REG_AUX_ADC_A1_HI  = 29;
-DEF REG_AUX_ADC_B2_LO  = 30;
-DEF REG_AUX_ADC_B2_HI  = 31;
-DEF REG_AUX_ADC_B1_LO  = 32;
-DEF REG_AUX_ADC_B1_HI  = 33;
-
-DEF REG_AUX_ADC_CTRL   = 34;
-DEF    AUX_ADC_CTRL_AUX_SPI            = (1 << 7);
-DEF    AUX_ADC_CTRL_SELBNOTA           = (1 << 6);
-DEF    AUX_ADC_CTRL_REFSEL_B           = (1 << 5);
-DEF    AUX_ADC_CTRL_SELECT_B2          = (0 << 4);
-DEF    AUX_ADC_CTRL_SELECT_B1          = (1 << 4);
-DEF    AUX_ADC_CTRL_START_B            = (1 << 3);
-DEF    AUX_ADC_CTRL_REFSEL_A           = (1 << 2);
-DEF    AUX_ADC_CTRL_SELECT_A2          = (0 << 1);
-DEF    AUX_ADC_CTRL_SELECT_A1          = (1 << 1);
-DEF    AUX_ADC_CTRL_START_A            = (1 << 0);
-
-DEF REG_AUX_ADC_CLK    = 35;
-DEF    AUX_ADC_CLK_CLK_OVER_4          = (1 << 0);
-
-DEF REG_AUX_DAC_A      = 36;
-DEF REG_AUX_DAC_B      = 37;
-DEF REG_AUX_DAC_C      = 38;
-
-DEF REG_AUX_DAC_UPDATE = 39;
-DEF    AUX_DAC_UPDATE_SLAVE_ENABLE     = (1 << 7);
-DEF    AUX_DAC_UPDATE_C                = (1 << 2);
-DEF    AUX_DAC_UPDATE_B                = (1 << 1);
-DEF    AUX_DAC_UPDATE_A                = (1 << 0);
-
-DEF REG_AUX_DAC_PWR_DN = 40;
-DEF    AUX_DAC_PWR_DN_C                = (1 << 2);
-DEF    AUX_DAC_PWR_DN_B                = (1 << 1);
-DEF    AUX_DAC_PWR_DN_A                = (1 << 0);
-
-DEF REG_AUX_DAC_CTRL   = 41;
-DEF    AUX_DAC_CTRL_INV_C              = (1 << 4);
-DEF    AUX_DAC_CTRL_INV_B              = (1 << 2);
-DEF    AUX_DAC_CTRL_INV_A              = (1 << 0);
-
-DEF REG_SIGDELT_LO     = 42;
-DEF REG_SIGDELT_HI     = 43;
-
-// 44 to 48 reserved
-
-DEF REG_ADC_LOW_PWR_LO = 49;
-DEF REG_ADC_LOW_PWR_HI = 50;
-
-// 51 to 62 reserved
-
-DEF REG_CHIP_ID                = 63;
-
-
-END_AD962;
-
-#undef DEF
-#undef BEGIN_AD9862
-#undef END_AD962
-
-#endif /* INCLUDED_AD9862_H */
diff --git a/usrp/host/lib/legacy/check_data.py b/usrp/host/lib/legacy/check_data.py
deleted file mode 100755 (executable)
index 100f0f6..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2003 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
-import struct
-
-fin = sys.stdin
-
-count = 0
-expected = 0
-last_correction = 0
-
-while 1:
-    s = fin.read(2)
-    if not s or len(s) != 2:
-        break
-
-    v, = struct.unpack ('H', s)
-    iv = int(v) & 0xffff
-    # print "%8d  %6d  0x%04x" % (count, iv, iv)
-    if count & 0x1:                     # only counting on the Q channel
-        if (expected & 0xffff) != iv:
-            print "%8d  (%6d) %6d  0x%04x" % (count, count - last_correction, iv, iv)
-            expected = iv               # reset expected sequence
-            last_correction = count
-        expected = (expected + 1) & 0xffff 
-        
-    count += 1
-
-    
-
-
diff --git a/usrp/host/lib/legacy/circular_buffer.h b/usrp/host/lib/legacy/circular_buffer.h
deleted file mode 100644 (file)
index 8898e41..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 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 _CIRCULAR_BUFFER_H_
-#define _CIRCULAR_BUFFER_H_
-
-#include "mld_threads.h"
-#include <stdexcept>
-
-#ifndef DO_DEBUG
-#define DO_DEBUG 0
-#endif
-
-#if DO_DEBUG
-#define DEBUG(X) do{X} while(0);
-#else
-#define DEBUG(X) do{} while(0);
-#endif
-
-template <class T> class circular_buffer
-{
-private:
-// the buffer to use
-  T* d_buffer;
-
-// the following are in Items (type T)
-  UInt32 d_bufLen_I, d_readNdx_I, d_writeNdx_I;
-  UInt32 d_n_avail_write_I, d_n_avail_read_I;
-
-// stuff to control access to class internals
-  mld_mutex_ptr d_internal;
-  mld_condition_ptr d_readBlock, d_writeBlock;
-
-// booleans to decide how to control reading, writing, and aborting
-  bool d_doWriteBlock, d_doFullRead, d_doAbort;
-
-  void delete_mutex_cond () {
-    if (d_internal) {
-      delete d_internal;
-      d_internal = NULL;
-    }
-    if (d_readBlock) {
-      delete d_readBlock;
-      d_readBlock = NULL;
-    }
-    if (d_writeBlock) {
-      delete d_writeBlock;
-      d_writeBlock = NULL;
-    }
-  };
-
-public:
-  circular_buffer (UInt32 bufLen_I,
-                  bool doWriteBlock = true, bool doFullRead = false) {
-    if (bufLen_I == 0)
-      throw std::runtime_error ("circular_buffer(): "
-                               "Number of items to buffer must be > 0.\n");
-    d_bufLen_I = bufLen_I;
-    d_buffer = (T*) new T[d_bufLen_I];
-    d_doWriteBlock = doWriteBlock;
-    d_doFullRead = doFullRead;
-    d_internal = NULL;
-    d_readBlock = d_writeBlock = NULL;
-    reset ();
-    DEBUG (fprintf (stderr, "c_b(): buf len (items) = %ld, "
-                   "doWriteBlock = %s, doFullRead = %s\n", d_bufLen_I,
-                   (d_doWriteBlock ? "true" : "false"),
-                   (d_doFullRead ? "true" : "false")););
-  };
-
-  ~circular_buffer () {
-    delete_mutex_cond ();
-    delete [] d_buffer;
-  };
-
-  inline UInt32 n_avail_write_items () {
-    d_internal->lock ();
-    UInt32 retVal = d_n_avail_write_I;
-    d_internal->unlock ();
-    return (retVal);
-  };
-
-  inline UInt32 n_avail_read_items () {
-    d_internal->lock ();
-    UInt32 retVal = d_n_avail_read_I;
-    d_internal->unlock ();
-    return (retVal);
-  };
-
-  inline UInt32 buffer_length_items () {return (d_bufLen_I);};
-  inline bool do_write_block () {return (d_doWriteBlock);};
-  inline bool do_full_read () {return (d_doFullRead);};
-
-  void reset () {
-    d_doAbort = false;
-    bzero (d_buffer, d_bufLen_I * sizeof (T));
-    d_readNdx_I = d_writeNdx_I = d_n_avail_read_I = 0;
-    d_n_avail_write_I = d_bufLen_I;
-    delete_mutex_cond ();
-    // create a mutex to handle contention of shared resources;
-    // any routine needed access to shared resources uses lock()
-    // before doing anything, then unlock() when finished.
-    d_internal = new mld_mutex ();
-    // link the internal mutex to the read and write conditions;
-    // when wait() is called, the internal mutex will automatically
-    // be unlock()'ed.  Upon return (from a signal() to the condition),
-    // the internal mutex will be lock()'ed.
-    d_readBlock = new mld_condition (d_internal);
-    d_writeBlock = new mld_condition (d_internal);
-  };
-
-/*
- * enqueue: add the given buffer of item-length to the queue,
- *     first-in-first-out (FIFO).
- *
- * inputs:
- *     buf: a pointer to the buffer holding the data
- *
- *     bufLen_I: the buffer length in items (of the instantiated type)
- *
- * returns:
- *    -1: on overflow (write is not blocking, and data is being
- *                     written faster than it is being read)
- *     0: if nothing to do (0 length buffer)
- *     1: if success
- *     2: in the process of aborting, do doing nothing
- *
- * will throw runtime errors if inputs are improper:
- *     buffer pointer is NULL
- *     buffer length is larger than the instantiated buffer length
- */
-
-  int enqueue (T* buf, UInt32 bufLen_I) {
-    DEBUG (fprintf (stderr, "enqueue: buf = %X, bufLen = %ld, #av_wr = %ld, "
-                   "#av_rd = %ld.\n", (unsigned int)buf, bufLen_I,
-                   d_n_avail_write_I, d_n_avail_read_I););
-    if (bufLen_I > d_bufLen_I) {
-      fprintf (stderr, "cannot add buffer longer (%ld"
-              ") than instantiated length (%ld"
-              ").\n", bufLen_I, d_bufLen_I);
-      throw std::runtime_error ("circular_buffer::enqueue()");
-    }
-
-    if (bufLen_I == 0)
-      return (0);
-    if (!buf)
-      throw std::runtime_error ("circular_buffer::enqueue(): "
-                               "input buffer is NULL.\n");
-    d_internal->lock ();
-    if (d_doAbort) {
-      d_internal->unlock ();
-      return (2);
-    }
-    // set the return value to 1: success; change if needed
-    int retval = 1;
-    if (bufLen_I > d_n_avail_write_I) {
-      if (d_doWriteBlock) {
-       while (bufLen_I > d_n_avail_write_I) {
-         DEBUG (fprintf (stderr, "enqueue: #len > #a, waiting.\n"););
-         // wait will automatically unlock() the internal mutex
-         d_writeBlock->wait ();
-         // and lock() it here.
-         if (d_doAbort) {
-           d_internal->unlock ();
-           DEBUG (fprintf (stderr, "enqueue: #len > #a, aborting.\n"););
-           return (2);
-         }
-         DEBUG (fprintf (stderr, "enqueue: #len > #a, done waiting.\n"););
-       }
-      } else {
-       d_n_avail_read_I = d_bufLen_I - bufLen_I;
-       d_n_avail_write_I = bufLen_I;
-       DEBUG (fprintf (stderr, "circular_buffer::enqueue: overflow\n"););
-       retval = -1;
-      }
-    }
-    UInt32 n_now_I = d_bufLen_I - d_writeNdx_I, n_start_I = 0;
-    if (n_now_I > bufLen_I)
-      n_now_I = bufLen_I;
-    else if (n_now_I < bufLen_I)
-      n_start_I = bufLen_I - n_now_I;
-    bcopy (buf, &(d_buffer[d_writeNdx_I]), n_now_I * sizeof (T));
-    if (n_start_I) {
-      bcopy (&(buf[n_now_I]), d_buffer, n_start_I * sizeof (T));
-      d_writeNdx_I = n_start_I;
-    } else
-      d_writeNdx_I += n_now_I;
-    d_n_avail_read_I += bufLen_I;
-    d_n_avail_write_I -= bufLen_I;
-    d_readBlock->signal ();
-    d_internal->unlock ();
-    return (retval);
-  };
-
-/*
- * dequeue: removes from the queue the number of items requested, or
- *     available, into the given buffer on a FIFO basis.
- *
- * inputs:
- *     buf: a pointer to the buffer into which to copy the data
- *
- *     bufLen_I: pointer to the number of items to remove in items
- *         (of the instantiated type)
- *
- * returns:
- *     0: if nothing to do (0 length buffer)
- *     1: if success
- *     2: in the process of aborting, do doing nothing
- *
- * will throw runtime errors if inputs are improper:
- *     buffer pointer is NULL
- *     buffer length pointer is NULL
- *     buffer length is larger than the instantiated buffer length
- */
-
-  int dequeue (T* buf, UInt32* bufLen_I) {
-    DEBUG (fprintf (stderr, "dequeue: buf = %X, *bufLen = %ld, #av_wr = %ld, "
-                   "#av_rd = %ld.\n", (unsigned int)buf, *bufLen_I,
-                   d_n_avail_write_I, d_n_avail_read_I););
-    if (!bufLen_I)
-      throw std::runtime_error ("circular_buffer::dequeue(): "
-                               "input bufLen pointer is NULL.\n");
-    if (!buf)
-      throw std::runtime_error ("circular_buffer::dequeue(): "
-                               "input buffer pointer is NULL.\n");
-    UInt32 l_bufLen_I = *bufLen_I;
-    if (l_bufLen_I == 0)
-      return (0);
-    if (l_bufLen_I > d_bufLen_I) {
-      fprintf (stderr, "cannot remove buffer longer (%ld"
-              ") than instantiated length (%ld"
-              ").\n", l_bufLen_I, d_bufLen_I);
-      throw std::runtime_error ("circular_buffer::dequeue()");
-    }
-
-    d_internal->lock ();
-    if (d_doAbort) {
-      d_internal->unlock ();
-      return (2);
-    }
-    if (d_doFullRead) {
-      while (d_n_avail_read_I < l_bufLen_I) {
-       DEBUG (fprintf (stderr, "dequeue: #a < #len, waiting.\n"););
-       // wait will automatically unlock() the internal mutex
-       d_readBlock->wait ();
-       // and lock() it here.
-       if (d_doAbort) {
-         d_internal->unlock ();
-         DEBUG (fprintf (stderr, "dequeue: #a < #len, aborting.\n"););
-         return (2);
-       }
-       DEBUG (fprintf (stderr, "dequeue: #a < #len, done waiting.\n"););
-     }
-    } else {
-      while (d_n_avail_read_I == 0) {
-       DEBUG (fprintf (stderr, "dequeue: #a == 0, waiting.\n"););
-       // wait will automatically unlock() the internal mutex
-       d_readBlock->wait ();
-       // and lock() it here.
-       if (d_doAbort) {
-         d_internal->unlock ();
-         DEBUG (fprintf (stderr, "dequeue: #a == 0, aborting.\n"););
-         return (2);
-       }
-       DEBUG (fprintf (stderr, "dequeue: #a == 0, done waiting.\n"););
-      }
-    }
-    if (l_bufLen_I > d_n_avail_read_I)
-      l_bufLen_I = d_n_avail_read_I;
-    UInt32 n_now_I = d_bufLen_I - d_readNdx_I, n_start_I = 0;
-    if (n_now_I > l_bufLen_I)
-      n_now_I = l_bufLen_I;
-    else if (n_now_I < l_bufLen_I)
-      n_start_I = l_bufLen_I - n_now_I;
-    bcopy (&(d_buffer[d_readNdx_I]), buf, n_now_I * sizeof (T));
-    if (n_start_I) {
-      bcopy (d_buffer, &(buf[n_now_I]), n_start_I * sizeof (T));
-      d_readNdx_I = n_start_I;
-    } else
-      d_readNdx_I += n_now_I;
-    *bufLen_I = l_bufLen_I;
-    d_n_avail_read_I -= l_bufLen_I;
-    d_n_avail_write_I += l_bufLen_I;
-    d_writeBlock->signal ();
-    d_internal->unlock ();
-    return (1);
-  };
-
-  void abort () {
-    d_internal->lock ();
-    d_doAbort = true;
-    d_writeBlock->signal ();
-    d_readBlock->signal ();
-    d_internal->unlock ();
-  };
-};
-
-#endif /* _CIRCULAR_BUFFER_H_ */
diff --git a/usrp/host/lib/legacy/circular_linked_list.h b/usrp/host/lib/legacy/circular_linked_list.h
deleted file mode 100644 (file)
index e495d60..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 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 _CIRCULAR_LINKED_LIST_H_
-#define _CIRCULAR_LINKED_LIST_H_
-
-#include <mld_threads.h>
-#include <stdexcept>
-
-#define __INLINE__ inline
-
-#ifndef DO_DEBUG
-#define DO_DEBUG 0
-#endif
-
-#if DO_DEBUG
-#define DEBUG(X) do{X} while(0);
-#else
-#define DEBUG(X) do{} while(0);
-#endif
-
-template <class T> class s_both;
-
-template <class T> class s_node
-{
-  typedef s_node<T>* s_node_ptr;
-
-private:
-  T d_object;
-  bool d_available;
-  s_node_ptr d_prev, d_next;
-  s_both<T>* d_both;
-
-public:
-  s_node (T l_object,
-         s_node_ptr l_prev = NULL,
-         s_node_ptr l_next = NULL)
-    : d_object (l_object), d_available (TRUE), d_prev (l_prev),
-    d_next (l_next), d_both (0) {};
-
-  __INLINE__ s_node (s_node_ptr l_prev, s_node_ptr l_next = NULL) {
-    s_node ((T) NULL, l_prev, l_next); };
-  __INLINE__ s_node () { s_node (NULL, NULL, NULL); };
-  __INLINE__ ~s_node () {};
-
-  void remove () {
-    d_prev->next (d_next);
-    d_next->prev (d_prev);
-    d_prev = d_next = this;
-  };
-
-  void insert_before (s_node_ptr l_next) {
-    if (l_next) {
-      s_node_ptr l_prev = l_next->prev ();
-      d_next = l_next;
-      d_prev = l_prev;
-      l_prev->next (this);
-      l_next->prev (this);
-    } else
-      d_next = d_prev = this;
-  };
-
-  void insert_after (s_node_ptr l_prev) {
-    if (l_prev) {
-      s_node_ptr l_next = l_prev->next ();
-      d_prev = l_prev;
-      d_next = l_next;
-      l_next->prev (this);
-      l_prev->next (this);
-    } else
-      d_prev = d_next = this;
-  };
-
-  __INLINE__ T object () { return (d_object); };
-  __INLINE__ void object (T l_object) { d_object = l_object; };
-  __INLINE__ bool available () { return (d_available); };
-  __INLINE__ void set_available () { d_available = TRUE; };
-  __INLINE__ void set_available (bool l_avail) { d_available = l_avail; };
-  __INLINE__ void set_not_available () { d_available = FALSE; };
-  __INLINE__ s_node_ptr next () { return (d_next); };
-  __INLINE__ s_node_ptr prev () { return (d_prev); };
-  __INLINE__ s_both<T>* both () { return (d_both); };
-  __INLINE__ void next (s_node_ptr l_next) { d_next = l_next; };
-  __INLINE__ void prev (s_node_ptr l_prev) { d_prev = l_prev; };
-  __INLINE__ void both (s_both<T>* l_both) { d_both = l_both; };
-};
-
-template <class T> class circular_linked_list {
-  typedef s_node<T>* s_node_ptr;
-
-private:
-  s_node_ptr d_current, d_iterate, d_available, d_inUse;
-  UInt32 d_n_nodes, d_n_used;
-  mld_mutex_ptr d_internal;
-  mld_condition_ptr d_ioBlock;
-
-public:
-  circular_linked_list (UInt32 n_nodes) {
-    if (n_nodes == 0)
-      throw std::runtime_error ("circular_linked_list(): n_nodes == 0");
-
-    d_iterate = NULL;
-    d_n_nodes = n_nodes;
-    d_n_used = 0;
-    s_node_ptr l_prev, l_next;
-    d_inUse = d_current = l_next = l_prev = NULL;
-
-    l_prev = new s_node<T> ();
-    l_prev->set_available ();
-    l_prev->next (l_prev);
-    l_prev->prev (l_prev);
-    if (n_nodes > 1) {
-      l_next = new s_node<T> (l_prev, l_prev);
-      l_next->set_available ();
-      l_next->next (l_prev);
-      l_next->prev (l_prev);
-      l_prev->next (l_next);
-      l_prev->prev (l_next);
-      if (n_nodes > 2) {
-       UInt32 n = n_nodes - 2;
-       while (n-- > 0) {
-         d_current = new s_node<T> (l_prev, l_next);
-         d_current->set_available ();
-         d_current->prev (l_prev);
-         d_current->next (l_next);
-         l_prev->next (d_current);
-         l_next->prev (d_current);
-         l_next = d_current;
-         d_current = NULL;
-       }
-      }
-    }
-    d_available = d_current = l_prev;
-    d_ioBlock = new mld_condition ();
-    d_internal = d_ioBlock->mutex ();
-  };
-
-  ~circular_linked_list () {
-    iterate_start ();
-    s_node_ptr l_node = iterate_next ();
-    while (l_node) {
-      delete l_node;
-      l_node = iterate_next ();
-    }
-    delete d_ioBlock;
-    d_ioBlock = NULL;
-    d_available = d_inUse = d_iterate = d_current = NULL;
-    d_n_used = d_n_nodes = 0;
-  };
-
-  s_node_ptr find_next_available_node () {
-    d_internal->lock ();
-// find an available node
-    s_node_ptr l_node = d_available; 
-    DEBUG (fprintf (stderr, "w "););
-    while (! l_node) {
-      DEBUG (fprintf (stderr, "x\n"););
-      // the ioBlock condition will automatically unlock() d_internal
-      d_ioBlock->wait ();
-      // and lock() is here
-      DEBUG (fprintf (stderr, "y\n"););
-      l_node = d_available;
-    }
-    DEBUG (fprintf (stderr, "::f_n_a_n: #u = %ld, node = %p\n",
-                   num_used(), l_node););
-// remove this one from the current available list
-    if (num_available () == 1) {
-// last one, just set available to NULL
-      d_available = NULL;
-    } else
-      d_available = l_node->next ();
-    l_node->remove ();
-// add is to the inUse list
-    if (! d_inUse)
-      d_inUse = l_node;
-    else
-      l_node->insert_before (d_inUse);
-    d_n_used++;
-    l_node->set_not_available ();
-    d_internal->unlock ();
-    return (l_node);
-  };
-
-  void make_node_available (s_node_ptr l_node) {
-    if (!l_node) return;
-    d_internal->lock ();
-    DEBUG (fprintf (stderr, "::m_n_a: #u = %ld, node = %p\n",
-                   num_used(), l_node););
-// remove this node from the inUse list
-    if (num_used () == 1) {
-// last one, just set inUse to NULL
-      d_inUse = NULL;
-    } else
-      d_inUse = l_node->next ();
-    l_node->remove ();
-// add this node to the available list
-    if (! d_available)
-      d_available = l_node;
-    else
-      l_node->insert_before (d_available);
-    d_n_used--;
-
-    DEBUG (fprintf (stderr, "s%ld ", d_n_used););
-// signal the condition when new data arrives
-    d_ioBlock->signal ();
-    DEBUG (fprintf (stderr, "t "););
-
-// unlock the mutex for thread safety
-    d_internal->unlock ();
-  };
-
-  __INLINE__ void iterate_start () { d_iterate = d_current; };
-
-  s_node_ptr iterate_next () {
-#if 0
-// lock the mutex for thread safety
-    d_internal->lock ();
-#endif
-    s_node_ptr l_this = NULL;
-    if (d_iterate) {
-      l_this = d_iterate;
-      d_iterate = d_iterate->next ();
-      if (d_iterate == d_current)
-       d_iterate = NULL;
-    }
-#if 0
-// unlock the mutex for thread safety
-    d_internal->unlock ();
-#endif
-    return (l_this);
-  };
-
-  __INLINE__ T object () { return (d_current->d_object); };
-  __INLINE__ void object (T l_object) { d_current->d_object = l_object; };
-  __INLINE__ UInt32 num_nodes () { return (d_n_nodes); };
-  __INLINE__ UInt32 num_used () { return (d_n_used); };
-  __INLINE__ void num_used (UInt32 l_n_used) { d_n_used = l_n_used; };
-  __INLINE__ UInt32 num_available () { return (d_n_nodes - d_n_used); };
-  __INLINE__ void num_used_inc (void) {
-    if (d_n_used < d_n_nodes) ++d_n_used;
-  };
-  __INLINE__ void num_used_dec (void) {
-    if (d_n_used != 0) --d_n_used;
-// signal the condition that new data has arrived
-    d_ioBlock->signal ();
-  };
-  __INLINE__ bool in_use () { return (d_n_used != 0); };
-};
-
-template <class T> class s_both
-{
-private:
-  s_node<T>* d_node;
-  void* d_this;
-public:
-  __INLINE__ s_both (s_node<T>* l_node, void* l_this)
-    : d_node (l_node), d_this (l_this) {};
-  __INLINE__ ~s_both () {};
-  __INLINE__ s_node<T>* node () { return (d_node); };
-  __INLINE__ void* This () { return (d_this); };
-  __INLINE__ void set (s_node<T>* l_node, void* l_this) {
-    d_node = l_node; d_this = l_this;};
-};
-
-#endif /* _CIRCULAR_LINKED_LIST_H_ */
diff --git a/usrp/host/lib/legacy/darwin_libusb.h b/usrp/host/lib/legacy/darwin_libusb.h
deleted file mode 100644 (file)
index 063a2e9..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 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.
- */
-
-/*
- * The following code was taken from LIBUSB verion 0.1.10a,
- * and makes the fusb_darwin codes do-able in the current GR
- * programming framework.  Parts and pieces were taken from
- * usbi.h, darwin.c, and error.h .
- *
- * LIBUSB version 0.1.10a is covered by the LGPL, version 2;
- * These codes are used with permission from:
- *   (c) 2000-2003 Johannes Erdfelt <johannes@erdfelt.com>
- *   (c) 2002-2005 Nathan Hjelm <hjelmn@users.sourceforge.net>
- * All rights reserved.
- */
-
-#ifndef __DARWIN_LIBUSB_H__
-#define __DARWIN_LIBUSB_H__
-
-#include <IOKit/IOCFBundle.h>
-#include <IOKit/IOCFPlugIn.h>
-#include <IOKit/usb/IOUSBLib.h>
-#include <IOKit/IOKitLib.h>
-
-extern "C" {
-static char *
-darwin_error_str (int result)
-{
-  switch (result) {
-  case kIOReturnSuccess:
-    return "no error";
-  case kIOReturnNotOpen:
-    return "device not opened for exclusive access";
-  case kIOReturnNoDevice:
-    return "no connection to an IOService";
-  case kIOUSBNoAsyncPortErr:
-    return "no asyc port has been opened for interface";
-  case kIOReturnExclusiveAccess:
-    return "another process has device opened for exclusive access";
-  case kIOUSBPipeStalled:
-    return "pipe is stalled";
-  case kIOReturnError:
-    return "could not establish a connection to Darin kernel";
-  case kIOReturnBadArgument:
-    return "invalid argument";
-  default:
-    return "unknown error";
-  }
-}
-
-/* not a valid errorno outside darwin.c */
-#define LUSBDARWINSTALL (ELAST+1)
-
-static int
-darwin_to_errno (int result)
-{
-  switch (result) {
-  case kIOReturnSuccess:
-    return 0;
-  case kIOReturnNotOpen:
-    return EBADF;
-  case kIOReturnNoDevice:
-  case kIOUSBNoAsyncPortErr:
-    return ENXIO;
-  case kIOReturnExclusiveAccess:
-    return EBUSY;
-  case kIOUSBPipeStalled:
-    return LUSBDARWINSTALL;
-  case kIOReturnBadArgument:
-    return EINVAL;
-  case kIOReturnError:
-  default:
-    return 1;
-  }
-}
-
-typedef enum {
-  USB_ERROR_TYPE_NONE = 0,
-  USB_ERROR_TYPE_STRING,
-  USB_ERROR_TYPE_ERRNO,
-} usb_error_type_t;
-
-extern char usb_error_str[1024];
-extern int usb_error_errno;
-extern usb_error_type_t usb_error_type;
-
-#define USB_ERROR(r, x)                                \
-       do { \
-          usb_error_type = USB_ERROR_TYPE_ERRNO; \
-          usb_error_errno = x; \
-         return r; \
-       } while (0)
-
-#define USB_ERROR_STR(r, x, format, args...)   \
-       do { \
-         usb_error_type = USB_ERROR_TYPE_STRING; \
-         snprintf(usb_error_str, sizeof(usb_error_str) - 1, format, ## args); \
-          if (usb_debug) \
-            fprintf(stderr, "USB error: %s\n", usb_error_str); \
-         return r; \
-       } while (0)
-
-#define USB_ERROR_STR_ORIG(x, format, args...) \
-       do { \
-         usb_error_type = USB_ERROR_TYPE_STRING; \
-         snprintf(usb_error_str, sizeof(usb_error_str) - 1, format, ## args); \
-          if (usb_debug) \
-            fprintf(stderr, "USB error: %s\n", usb_error_str); \
-         return x; \
-       } while (0)
-
-#define USB_ERROR_STR_NO_RET(x, format, args...)       \
-       do { \
-         usb_error_type = USB_ERROR_TYPE_STRING; \
-         snprintf(usb_error_str, sizeof(usb_error_str) - 1, format, ## args); \
-          if (usb_debug) \
-            fprintf(stderr, "USB error: %s\n", usb_error_str); \
-       } while (0)
-
-/* simple function that figures out what pipeRef is associated with an endpoint */
-static int ep_to_pipeRef (darwin_dev_handle *device, int ep)
-{
-  io_return_t ret;
-  UInt8 numep, direction, number;
-  UInt8 dont_care1, dont_care3;
-  UInt16 dont_care2;
-  int i;
-
-  if (usb_debug > 3)
-    fprintf(stderr, "Converting ep address to pipeRef.\n");
-
-  /* retrieve the total number of endpoints on this interface */
-  ret = (*(device->interface))->GetNumEndpoints(device->interface, &numep);
-  if ( ret ) {
-    if ( usb_debug > 3 )
-      fprintf ( stderr, "ep_to_pipeRef: interface is %p\n", device->interface );
-    USB_ERROR_STR_ORIG ( -ret, "ep_to_pipeRef: can't get number of endpoints for interface" );
-  }
-
-  /* iterate through the pipeRefs until we find the correct one */
-  for (i = 1 ; i <= numep ; i++) {
-    ret = (*(device->interface))->GetPipeProperties(device->interface, i, &direction, &number,
-                                                   &dont_care1, &dont_care2, &dont_care3);
-
-    if (ret != kIOReturnSuccess) {
-      fprintf (stderr, "ep_to_pipeRef: an error occurred getting pipe information on pipe %d\n",
-              i );
-      USB_ERROR_STR_ORIG (-darwin_to_errno(ret), "ep_to_pipeRef(GetPipeProperties): %s", darwin_error_str(ret));
-    }
-
-    if (usb_debug > 3)
-      fprintf (stderr, "ep_to_pipeRef: Pipe %i: DIR: %i number: %i\n", i, direction, number);
-
-    /* calculate the endpoint of the pipe and check it versus the requested endpoint */
-    if ( ((direction << 7 & USB_ENDPOINT_DIR_MASK) | (number & USB_ENDPOINT_ADDRESS_MASK)) == ep ) {
-      if (usb_debug > 3)
-       fprintf(stderr, "ep_to_pipeRef: pipeRef for ep address 0x%02x found: 0x%02x\n", ep, i);
-
-      return i;
-    }
-  }
-
-  if (usb_debug > 3)
-    fprintf(stderr, "ep_to_pipeRef: No pipeRef found with endpoint address 0x%02x.\n", ep);
-  
-  /* none of the found pipes match the requested endpoint */
-  return -1;
-}
-
-}
-#endif /* __DARWIN_LIBUSB_H__ */
diff --git a/usrp/host/lib/legacy/db_base.cc b/usrp/host/lib/legacy/db_base.cc
deleted file mode 100644 (file)
index 80c6d46..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-//
-// 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");;
-}
-
-bool
-db_base::set_bw(float bw)
-{
-  // Set baseband bandwidth (board specific)
-  // Should be overriden by boards that implement variable IF filtering (e.g., DBSRX)
-  return false;
-}
-
-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
deleted file mode 100644 (file)
index 3547089..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/* -*- c++ -*- */
-//
-// Copyright 2008 Free Software Foundation, Inc.
-// 
-// This file is part of GNU Radio
-// 
-// GNU Radio is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either 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;
-};
-
-/******************************************************************************/
-
-/*!
- * \brief Abstract base class for all USRP daughterboards
- * \ingroup usrp
- */
-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);
-  virtual bool set_bw(float bw);
-};
-
-
-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
deleted file mode 100644 (file)
index bd5483a..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- c++ -*- */
-//
-// Copyright 2008,2009 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_base.h"
-%}
-
-%include <gr_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);
-  virtual bool set_bw(float bw);
-};
-
-// 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
deleted file mode 100644 (file)
index bb4d95d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with 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
deleted file mode 100644 (file)
index 4bafc93..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-//
-// 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 (d_subdev == 2);
-}
-
-
-
-/******************************************************************************/
-
-
-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
deleted file mode 100644 (file)
index 4dd92b9..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/* -*- c++ -*- */
-//
-// Copyright 2008 Free Software Foundation, Inc.
-// 
-// This file is part of GNU Radio
-// 
-// GNU Radio is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either 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
deleted file mode 100644 (file)
index b537698..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-/* -*- c++ -*- */
-//
-// Copyright 2008 Free Software Foundation, Inc.
-// 
-// This file is part of GNU Radio
-// 
-// GNU Radio is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either 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>
-#include <cstdio>
-
-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)));
-    db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 2)));
-    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)));
-    db.push_back(db_base_sptr(new db_lf_rx(usrp, which_side, 2)));
-    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
deleted file mode 100644 (file)
index 037c460..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- c++ -*- */
-//
-// Copyright 2008 Free Software Foundation, Inc.
-// 
-// This file is part of GNU Radio
-// 
-// GNU Radio is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either 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
deleted file mode 100644 (file)
index 6094f91..0000000
+++ /dev/null
@@ -1,497 +0,0 @@
-//
-// 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>
-#include <cstdio>
-
-
-/*****************************************************************************/
-
-
-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);
-}
-
-bool
-db_dbs_rx::set_bw (float bw)
-{
-  if (bw < 1e6 || bw > 33e6) {
-    fprintf(stderr, "db_dbs_rx::set_bw: bw (=%f) must be between 1e6 and 33e6 inclusive\n", bw);
-    return false;
-  }
-
-  // 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, "db_dbs_rx::set_bw: failed\n");
-    return false;
-  }
-
-  return true;
-}
-
-// 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
deleted file mode 100644 (file)
index 723771f..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- c++ -*- */
-//
-// Copyright 2008 Free Software Foundation, Inc.
-// 
-// This file is part of GNU Radio
-// 
-// GNU Radio is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either 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>
-
-#if 0
-struct bw_t {
-  int m;
-  int fdac;
-  float div;
-};
-#endif
-
-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);
-  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();
-  bool  set_bw(float bw);
-};
-
-#endif
diff --git a/usrp/host/lib/legacy/db_dtt754.cc b/usrp/host/lib/legacy/db_dtt754.cc
deleted file mode 100644 (file)
index 4a6a1a2..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-/* -*- c++ -*- */
-//
-// Copyright 2008 Free Software Foundation, Inc.
-// 
-// This file is part of GNU Radio
-// 
-// GNU Radio is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either 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;
-}
-
-bool
-db_dtt754::set_bw(float bw)
-{
-  /*
-   * Choose the SAW filter bandwidth, either 7MHz or 8MHz)
-   */
-
-  d_bw = bw;
-  set_freq(d_freq);
-
-  return true; // FIXME: propagate set_freq result
-}
-
-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
deleted file mode 100644 (file)
index 0c104ac..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* -*- c++ -*- */
-//
-// Copyright 2008 Free Software Foundation, Inc.
-// 
-// This file is part of GNU Radio
-// 
-// GNU Radio is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either 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();
-  bool 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
deleted file mode 100644 (file)
index cae8b73..0000000
+++ /dev/null
@@ -1,296 +0,0 @@
-/* -*- c++ -*- */
-//
-// Copyright 2008 Free Software Foundation, Inc.
-// 
-// This file is part of GNU Radio
-// 
-// GNU Radio is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either 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;
-}
-
-bool
-db_dtt768::set_bw(float bw)
-{
-  /*
-   * Choose the SAW filter bandwidth, either 7MHz or 8MHz)
-   */
-
-  d_bw = bw;
-  set_freq(d_freq);
-
-  return true; // FIXME: propagate set_freq result
-}
-
-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
deleted file mode 100644 (file)
index dd5a59a..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* -*- c++ -*- */
-//
-// Copyright 2008 Free Software Foundation, Inc.
-// 
-// This file is part of GNU Radio
-// 
-// GNU Radio is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either 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();
-  bool 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
deleted file mode 100644 (file)
index 662d909..0000000
+++ /dev/null
@@ -1,1148 +0,0 @@
-//
-// 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
deleted file mode 100644 (file)
index b9ccfc3..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-/* -*- c++ -*- */
-//
-// Copyright 2008 Free Software Foundation, Inc.
-// 
-// This file is part of GNU Radio
-// 
-// GNU Radio is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either 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
deleted file mode 100644 (file)
index fd996bf..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index aeff532..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index 803ebf8..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-//
-// 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
deleted file mode 100644 (file)
index ed91626..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- c++ -*- */
-//
-// Copyright 2008 Free Software Foundation, Inc.
-// 
-// This file is part of GNU Radio
-// 
-// GNU Radio is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either 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
deleted file mode 100644 (file)
index 4b46383..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with 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
deleted file mode 100644 (file)
index e07abb6..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with 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
deleted file mode 100644 (file)
index 9f1d729..0000000
+++ /dev/null
@@ -1,953 +0,0 @@
-/* -*- c++ -*- */
-//
-// Copyright 2008 Free Software Foundation, Inc.
-// 
-// This file is part of GNU Radio
-// 
-// GNU Radio is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either 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
deleted file mode 100644 (file)
index 3202d36..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/* -*- c++ -*- */
-//
-// Copyright 2008 Free Software Foundation, Inc.
-// 
-// This file is part of GNU Radio
-// 
-// GNU Radio is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either 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
deleted file mode 100644 (file)
index 9ce3168..0000000
+++ /dev/null
@@ -1,791 +0,0 @@
-//
-// Copyright 2008,2009 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>
-#include <boost/thread.hpp>
-#include <boost/weak_ptr.hpp>
-#include <cstdio>
-
-#if 0
-#define LO_OFFSET 4.25e6
-#else
-#define LO_OFFSET 0
-#define NO_LO_OFFSET
-#endif
-
-
-/* ------------------------------------------------------------------------
- *  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.
- */
-
-
-
-// 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 RX_OE_MASK EN|RX_EN|RX_HP
-#define RX_SAFE_IO EN
-
-struct xcvr2450_key {
-  std::string serial_no;
-  int which;
-
-  bool operator==(const xcvr2450_key &x){
-    return x.serial_no ==serial_no && x.which == which;
-  }
-};
-
-class xcvr2450
-{
-private:
-  usrp_basic *d_raw_usrp;
-  int d_which;
-
-  bool d_is_shutdown;
-  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);
-
-public:
-  usrp_basic *usrp(){
-    return d_raw_usrp;
-  }
-
-  xcvr2450(usrp_basic_sptr usrp, int which);
-  ~xcvr2450();
-  void shutdown();
-
-  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);
-
-  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);
-};
-
-
-/*****************************************************************************/
-
-
-xcvr2450::xcvr2450(usrp_basic_sptr _usrp, int which)
-  : d_raw_usrp(_usrp.get()), d_which(which), d_is_shutdown(false)
-{
-  // 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 = 1;    // 0 = 2mA, 1 = 4mA
-  d_ref_div = 1;       // 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  
-  usrp()->common_write_io(C_TX, d_which, TX_SAFE_IO, TX_OE_MASK);
-  usrp()->_common_write_oe(C_TX, d_which, TX_OE_MASK, 0xffff);
-  usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO);
-  usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO);
-  usrp()->common_write_atr_mask(C_TX, d_which, TX_OE_MASK);
-
-  usrp()->common_write_io(C_RX, d_which, RX_SAFE_IO, RX_OE_MASK);
-  usrp()->_common_write_oe(C_RX, d_which, RX_OE_MASK, 0xffff);
-  usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO);
-  usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO);
-  usrp()->common_write_atr_mask(C_RX, d_which, 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");
-  shutdown();
-}
-
-void
-xcvr2450::shutdown()
-{
-  if (!d_is_shutdown){
-    d_is_shutdown = true;
-    usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO);
-    usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO);
-    usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO);
-    usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO);
-  }
-}
-
-
-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)           |
-                     (0<<11)           |
-                     (d_highband<<10)  |
-                     (d_cp_current<<9) |
-                     (d_ref_div<<5)    |
-                     (d_five_gig<<4)   | 5);
-  send_reg(d_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 %X\n", (v&15), 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 = RX_HP;
-  else
-    rx_hp = 0;
-  
-  if(d_tx_ant)
-    tx_antsel = ANTSEL_TX2_RX1;
-  else
-    tx_antsel = ANTSEL_TX1_RX2;
-
-  if(d_rx_ant)
-    rx_antsel = ANTSEL_TX2_RX1;
-  else
-    rx_antsel = ANTSEL_TX1_RX2;
-
-  if(d_five_gig)
-    tx_pa_sel = LB_PA_OFF;
-  else
-    tx_pa_sel = HB_PA_OFF;
-  // Reset GPIO and ATR
-  // FIXME: dont set io, oe, atr mask once basic code stops overriding our settings
-  usrp()->common_write_io(C_TX, d_which, TX_SAFE_IO, TX_OE_MASK);
-  usrp()->_common_write_oe(C_TX, d_which, TX_OE_MASK, 0xffff);
-  usrp()->common_write_atr_txval(C_TX, d_which, tx_pa_sel|tx_antsel|TX_EN|AD9515DIV);
-  usrp()->common_write_atr_rxval(C_TX, d_which, HB_PA_OFF|LB_PA_OFF|rx_antsel|AD9515DIV);
-  usrp()->common_write_atr_mask(C_TX, d_which, TX_OE_MASK);
-
-  usrp()->common_write_io(C_RX, d_which, RX_SAFE_IO, RX_OE_MASK);
-  usrp()->_common_write_oe(C_RX, d_which, RX_OE_MASK, 0xffff);
-  usrp()->common_write_atr_txval(C_RX, d_which, EN|rx_hp);
-  usrp()->common_write_atr_rxval(C_RX, d_which, EN|rx_hp|RX_EN);
-  usrp()->common_write_atr_mask(C_RX, d_which, RX_OE_MASK);
-
-  //printf("GPIO: RXRX=%04X RXTX=%04X TXRX=%04X TXTX=%04X\n",
-  //       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_ad9515_div = 3;
-    scaler = 4.0/5.0;
-  }
-  else {
-    d_five_gig = 0;
-    d_ad9515_div = 3;
-    scaler = 4.0/3.0;
-  }
-
-  if(target_freq > 5.408e9) {
-    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\n",
-  //    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();
-#ifdef NO_LO_OFFSET
-  args.baseband_freq = target_freq;
-#else
-  args.baseband_freq = actual_freq;
-#endif
-
-  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(usrp()->common_read_io(C_RX, d_which) & LOCKDET) {
-    return true;
-  }
-  else {      // Give it a second chance
-    if(usrp()->common_read_io(C_RX, d_which) & 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;
-}
-
-
-/*****************************************************************************/
-
-
-struct xcvr2450_table_entry {
-  xcvr2450_key                         key;
-  boost::weak_ptr<xcvr2450>    value;
-
-  xcvr2450_table_entry(const xcvr2450_key &_key, boost::weak_ptr<xcvr2450> _value)
-    : key(_key), value(_value) {}
-};
-
-typedef std::vector<xcvr2450_table_entry> xcvr2450_table;
-
-static boost::mutex s_table_mutex;
-static xcvr2450_table s_table;
-
-static xcvr2450_sptr
-_get_or_make_xcvr2450(usrp_basic_sptr usrp, int which)
-{
-  xcvr2450_key key = {usrp->serial_number(), which};
-
-  boost::mutex::scoped_lock    guard(s_table_mutex);
-
-  for (xcvr2450_table::iterator p = s_table.begin(); p != s_table.end();){
-    if (p->value.expired())    // weak pointer is now dead
-      p = s_table.erase(p);    // erase it
-    else {
-      if (key == p->key){      // found it
-       return xcvr2450_sptr(p->value);
-      }
-      else                     
-       ++p;                    // keep looking
-    }
-  }
-
-  // We don't have the xcvr2450 we're looking for
-
-  // create a new one and stick it in the table.
-  xcvr2450_sptr r(new xcvr2450(usrp, which));
-  xcvr2450_table_entry t(key, r);
-  s_table.push_back(t);
-
-  return r;
-}
-
-
-/*****************************************************************************/
-
-
-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()
-{
-}
-
-void
-db_xcvr2450_base::shutdown_common()
-{
-  // If the usrp_basic in the xcvr2450 is the same as the usrp_basic
-  // in the daughterboard, shutdown the xcvr now (when only one of Tx
-  // and Rx is open, this is always true).
-
-  if (d_xcvr->usrp() == usrp()){
-    //std::cerr << "db_xcvr2450_base::shutdown_common: same -> shutting down\n";
-    d_xcvr->shutdown();
-  }
-  else {
-    //std::cerr << "db_xcvr2450_base::shutdown_common: different -> ignoring\n";
-  }
-}
-
-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+d_lo_offset);
-}
-
-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)
-{
-  set_lo_offset(LO_OFFSET);
-  //printf("db_xcvr2450_tx::db_xcvr2450_tx\n");
-}
-
-db_xcvr2450_tx::~db_xcvr2450_tx()
-{
-  shutdown();
-}
-
-void
-db_xcvr2450_tx::shutdown()
-{
-  if (!d_is_shutdown){
-    d_is_shutdown = true;
-    shutdown_common();
-  }
-}
-
-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.
-   */
-  set_lo_offset(LO_OFFSET);
-  //printf("db_xcvr2450_rx:d_xcvr_2450_rx\n");
-}
-
-db_xcvr2450_rx::~db_xcvr2450_rx()
-{
-  shutdown();
-}
-
-void
-db_xcvr2450_rx::shutdown()
-{
-  if (!d_is_shutdown){
-    d_is_shutdown = true;
-    shutdown_common();
-  }
-}
-
-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
deleted file mode 100644 (file)
index 1f9dd7c..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* -*- c++ -*- */
-//
-// Copyright 2008,2009 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>
-
-class xcvr2450;
-typedef boost::shared_ptr<xcvr2450> xcvr2450_sptr;
-
-
-/******************************************************************************/
-
-
-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;
-  void shutdown_common();
-};
-
-
-/******************************************************************************/
-
-
-class db_xcvr2450_tx : public db_xcvr2450_base
-{
-protected:
-  void shutdown();
-
-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
-{
-protected:
-  void shutdown();
-
-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/dump_data.py b/usrp/host/lib/legacy/dump_data.py
deleted file mode 100755 (executable)
index 034586d..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2003 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
-import struct
-
-fin = sys.stdin
-
-count = 0
-
-while 1:
-    s = fin.read(2)
-    if not s or len(s) != 2:
-        break
-
-    v, = struct.unpack ('H', s)
-    iv = int(v) & 0xffff
-    print "%8d  %6d  0x%04x" % (count, iv, iv)
-    count += 1
-    
-
-
diff --git a/usrp/host/lib/legacy/fusb.cc b/usrp/host/lib/legacy/fusb.cc
deleted file mode 100644 (file)
index 6e4358f..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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 <fusb.h>
-
-
-// ------------------------------------------------------------------------
-//                          device handle
-// ------------------------------------------------------------------------
-
-fusb_devhandle::fusb_devhandle (usb_dev_handle *udh)
-  : d_udh (udh)
-{
-  // that's it
-};
-
-fusb_devhandle::~fusb_devhandle ()
-{
-  // nop
-}
-
-// ------------------------------------------------------------------------
-//                          end point handle
-// ------------------------------------------------------------------------
-
-fusb_ephandle::fusb_ephandle (int endpoint, bool input_p,
-                             int block_size, int nblocks)
-  : d_endpoint (endpoint), d_input_p (input_p),
-    d_block_size (block_size), d_nblocks (nblocks), d_started (false)
-{
-  // that't it
-}
-
-fusb_ephandle::~fusb_ephandle ()
-{
-  // nop
-}
diff --git a/usrp/host/lib/legacy/fusb.h b/usrp/host/lib/legacy/fusb.h
deleted file mode 100644 (file)
index 769e51c..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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.
- */
-
-// Fast USB interface
-
-#ifndef _FUSB_H_
-#define _FUSB_H_
-
-
-struct  usb_dev_handle;
-class   fusb_ephandle;
-
-/*!
- * \brief abstract usb device handle
- */
-class fusb_devhandle {
-private:
-  // NOT IMPLEMENTED
-  fusb_devhandle (const fusb_devhandle &rhs);            // no copy constructor
-  fusb_devhandle &operator= (const fusb_devhandle &rhs);  // no assignment operator
-
-protected:
-  usb_dev_handle               *d_udh;
-
-public:
-  // CREATORS
-  fusb_devhandle (usb_dev_handle *udh);
-  virtual ~fusb_devhandle ();
-
-  // MANIPULATORS
-  
-  /*!
-   * \brief return an ephandle of the correct subtype
-   */
-  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
-                                       int block_size = 0, int nblocks = 0) = 0;
-  
-  // ACCESSORS
-  usb_dev_handle *get_usb_dev_handle () const { return d_udh; }
-};
-
-
-/*!
- * \brief abstract usb end point handle
- */
-class fusb_ephandle {
-private:
-  // NOT IMPLEMENTED
-  fusb_ephandle (const fusb_ephandle &rhs);            // no copy constructor
-  fusb_ephandle &operator= (const fusb_ephandle &rhs);  // no assignment operator
-
-protected:
-  int                          d_endpoint;
-  bool                         d_input_p;
-  int                          d_block_size;
-  int                          d_nblocks;
-  bool                         d_started;
-
-public:
-  fusb_ephandle (int endpoint, bool input_p,
-                int block_size = 0, int nblocks = 0);
-  virtual ~fusb_ephandle ();
-
-  virtual bool start () = 0;   //!< begin streaming i/o
-  virtual bool stop () = 0;    //!< stop streaming i/o
-
-  /*!
-   * \returns \p nbytes if write was successfully enqueued, else -1.
-   * Will block if no free buffers available.
-   */
-  virtual int write (const void *buffer, int nbytes) = 0;
-
-  /*!
-   * \returns number of bytes read or -1 if error.
-   * number of bytes read will be <= nbytes.
-   * Will block if no input available.
-   */
-  virtual int read (void *buffer, int nbytes) = 0;
-
-  /*
-   * block until all outstanding writes have completed
-   */
-  virtual void wait_for_completion () = 0;
-
-  /*!
-   * \brief returns current block size.
-   */
-  int block_size () { return d_block_size; };
-};
-
-
-/*!
- * \brief factory for creating concrete instances of the appropriate subtype.
- */
-class fusb_sysconfig {
-public:
-  /*!
-   * \brief returns fusb_devhandle or throws if trouble
-   */
-  static fusb_devhandle *make_devhandle (usb_dev_handle *udh);
-
-  /*!
-   * \brief Returns max block size in bytes (hard limit).
-   */
-  static int max_block_size ();
-
-  /*!
-   * \brief Returns default block size in bytes.
-   */
-  static int default_block_size ();
-
-  /*!
-   * \brief Returns the default buffer size in bytes.
-   */
-  static int default_buffer_size ();
-
-};
-
-#endif /* _FUSB_H_ */
diff --git a/usrp/host/lib/legacy/fusb_darwin.cc b/usrp/host/lib/legacy/fusb_darwin.cc
deleted file mode 100644 (file)
index 737387b..0000000
+++ /dev/null
@@ -1,572 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-// tell mld_threads to NOT use omni_threads,
-// but rather Darwin's pthreads
-#define _USE_OMNI_THREADS_
-#define DO_DEBUG 0
-
-#include <usb.h>
-#include "fusb.h"
-#include "fusb_darwin.h"
-#include "darwin_libusb.h"
-
-static const int USB_TIMEOUT = 100;    // in milliseconds
-static const UInt8 NUM_QUEUE_ITEMS = 20;
-
-fusb_devhandle_darwin::fusb_devhandle_darwin (usb_dev_handle* udh)
-  : fusb_devhandle (udh)
-{
-  // that's it
-}
-
-fusb_devhandle_darwin::~fusb_devhandle_darwin ()
-{
-  // nop
-}
-
-fusb_ephandle*
-fusb_devhandle_darwin::make_ephandle (int endpoint, bool input_p,
-                                     int block_size, int nblocks)
-{
-  return new fusb_ephandle_darwin (this, endpoint, input_p,
-                                  block_size, nblocks);
-}
-
-// ----------------------------------------------------------------
-
-fusb_ephandle_darwin::fusb_ephandle_darwin (fusb_devhandle_darwin* dh,
-                                           int endpoint, bool input_p,
-                                           int block_size, int nblocks)
-  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
-    d_devhandle (dh), d_pipeRef (0), d_transferType (0),
-    d_interfaceRef (0),  d_interface (0), d_queue (0),
-    d_buffer (0), d_bufLenBytes (0)
-{
-  d_bufLenBytes = fusb_sysconfig::max_block_size();
-
-// create circular buffer
-  d_buffer = new circular_buffer<char> (NUM_QUEUE_ITEMS * d_bufLenBytes,
-                                       !d_input_p, d_input_p);
-
-// create the queue
-  d_queue = new circular_linked_list <s_buffer_ptr> (NUM_QUEUE_ITEMS);
-  d_queue->iterate_start ();
-  s_node_ptr l_node = d_queue->iterate_next ();
-  while (l_node) {
-    l_node->both (new s_both<s_buffer_ptr> (l_node, this));
-    s_buffer_ptr l_buf = new s_buffer (d_bufLenBytes);
-    l_node->object (l_buf);
-    l_node = d_queue->iterate_next ();
-    l_buf = NULL;
-  }
-
-  d_readRunning = new mld_mutex ();
-  d_runThreadRunning = new mld_mutex ();
-  d_runBlock = new mld_condition ();
-  d_readBlock = new mld_condition ();
-}
-
-fusb_ephandle_darwin::~fusb_ephandle_darwin ()
-{
-  stop ();
-
-  d_queue->iterate_start ();
-  s_node_ptr l_node = d_queue->iterate_next ();
-  while (l_node) {
-    s_both_ptr l_both = l_node->both ();
-    delete l_both;
-    l_both = NULL;
-    l_node->both (NULL);
-    s_buffer_ptr l_buf = l_node->object ();
-    delete l_buf;
-    l_buf = NULL;
-    l_node->object (NULL);
-    l_node = d_queue->iterate_next ();
-  }
-  delete d_queue;
-  d_queue = NULL;
-  delete d_buffer;
-  d_buffer = NULL;
-  delete d_readRunning;
-  d_readRunning = NULL;
-  delete d_runThreadRunning;
-  d_runThreadRunning = NULL;
-  delete d_runBlock;
-  d_runBlock = NULL;
-  delete d_readBlock;
-  d_readBlock = NULL;
-}
-
-bool
-fusb_ephandle_darwin::start ()
-{
-  UInt8  direction, number, interval;
-  UInt16 maxPacketSize;
-
-// reset circular buffer
-  d_buffer->reset ();
-
-// reset the queue
-  d_queue->num_used (0);
-  d_queue->iterate_start ();
-  s_node_ptr l_node = d_queue->iterate_next ();
-  while (l_node) {
-    l_node->both()->set (l_node, this);
-    l_node->object()->reset ();
-    l_node->set_available ();
-    l_node = d_queue->iterate_next ();
-  }
-
-  d_pipeRef = d_transferType = 0;
-
-  usb_dev_handle* dev = d_devhandle->get_usb_dev_handle ();
-  if (! dev)
-    USB_ERROR_STR (false, -ENXIO, "fusb_ephandle_darwin::start: "
-                  "null device");
-
-  darwin_dev_handle* device = (darwin_dev_handle*) dev->impl_info;
-  if (! device)
-    USB_ERROR_STR (false, -ENOENT, "fusb_ephandle_darwin::start: "
-                  "device not initialized");
-
-  if (usb_debug)
-    fprintf (stderr, "fusb_ephandle_darwin::start: "
-            "dev = %p, device = %p\n", dev, device);
-
-  d_interfaceRef = device->interface;
-  if (! d_interfaceRef)
-    USB_ERROR_STR (false, -EACCES, "fusb_ephandle_darwin::start: "
-                  "interface used without being claimed");
-  d_interface = *d_interfaceRef;
-
-// get read or write pipe info (depends on "d_input_p")
-
-  if (usb_debug > 3)
-    fprintf (stderr, "fusb_ephandle_darwin::start "
-            "d_endpoint = %d, d_input_p = %s\n",
-            d_endpoint, d_input_p ? "TRUE" : "FALSE");
-
-  int l_endpoint = (d_input_p ? USB_ENDPOINT_IN : USB_ENDPOINT_OUT);
-  int pipeRef = ep_to_pipeRef (device, d_endpoint | l_endpoint);
-  if (pipeRef < 0)
-    USB_ERROR_STR (false, -EINVAL, "fusb_ephandle_darwin::start "
-                  " invalid pipeRef.\n");
-
-  d_pipeRef = pipeRef;
-  d_interface->GetPipeProperties (d_interfaceRef,
-                                 d_pipeRef,
-                                 &direction,
-                                 &number,
-                                 &d_transferType,
-                                 &maxPacketSize,
-                                 &interval);
-  if (usb_debug == 3)
-    fprintf (stderr, "fusb_ephandle_darwin::start: %s: ep = 0x%02x, "
-            "pipeRef = %d, d_i = %p, d_iR = %p, if_dir = %d, if_# = %d, "
-            "if_int = %d, if_maxPS = %d\n", d_input_p ? "read" : "write",
-            d_endpoint, d_pipeRef, d_interface, d_interfaceRef, direction,
-            number, interval, maxPacketSize);
-
-  // set global start boolean
-  d_started = true;
-
-  // lock the runBlock mutex, before creating the run thread.
-  // this guarantees that we can control execution between these 2 threads
-  d_runBlock->mutex ()->lock ();
-
-  // create the run thread, which allows OSX to process I/O separately
-  d_runThread = new mld_thread (run_thread, this);
-
-  // wait until the run thread (and possibky read thread) are -really-
-  // going; this will unlock the mutex before waiting for a signal ()
-  d_runBlock->wait ();
-
-  if (usb_debug)
-    fprintf (stderr, "fusb_ephandle_darwin::start: %s started.\n",
-            d_input_p ? "read" : "write");
-
-  return (true);
-}
-
-void
-fusb_ephandle_darwin::run_thread (void* arg)
-{
-  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(arg);
-
-  // lock the run thread running mutex; if ::stop() is called, it will
-  // first abort() the pipe then wait for the run thread to finish,
-  // via a lock() on this mutex
-  mld_mutex_ptr l_runThreadRunning = This->d_runThreadRunning;
-  l_runThreadRunning->lock ();
-
-  mld_mutex_ptr l_readRunning = This->d_readRunning;
-  mld_condition_ptr l_readBlock = This->d_readBlock;
-  mld_mutex_ptr l_readBlock_mutex = l_readBlock->mutex ();
-
-  bool l_input_p = This->d_input_p;
-
-  if (usb_debug)
-    fprintf (stderr, "fusb_ephandle_darwin::run_thread: "
-            "starting for %s.\n",
-            l_input_p ? "read" : "write");
-
-  usb_interface_t** l_interfaceRef = This->d_interfaceRef;
-  usb_interface_t* l_interface = This->d_interface;
-  CFRunLoopSourceRef l_cfSource;
-
-// create async run loop
-  l_interface->CreateInterfaceAsyncEventSource (l_interfaceRef, &l_cfSource);
-  CFRunLoopAddSource (CFRunLoopGetCurrent (), l_cfSource,
-                     kCFRunLoopDefaultMode);
-// get run loop reference, to allow other threads to stop
-  This->d_CFRunLoopRef = CFRunLoopGetCurrent ();
-
-  mld_thread_ptr l_rwThread = NULL;
-
-  if (l_input_p) {
-    // lock the readBlock mutex, before creating the read thread.
-    // this guarantees that we can control execution between these 2 threads
-    l_readBlock_mutex->lock ();
-    // create the read thread, which just issues all of the starting
-    // async read commands, then returns
-    l_rwThread = new mld_thread (read_thread, arg);
-    // wait until the the read thread is -really- going; this will
-    // unlock the read block mutex before waiting for a signal ()
-    l_readBlock->wait ();
-  }
-
-  // now signal the run condition to release and finish ::start().
-
-  // lock the runBlock mutex first; this will force waiting until the
-  // ->wait() command is issued in ::start()
-  mld_mutex_ptr l_run_block_mutex = This->d_runBlock->mutex ();
-  l_run_block_mutex->lock ();
-
-  // now that the lock is in place, signal the parent thread that
-  // things are running
-  This->d_runBlock->signal ();
-
-  // release the run_block mutex, just in case
-  l_run_block_mutex->unlock ();
-
-  // run the loop
-  CFRunLoopRun ();
-
-  if (l_input_p) {
-    // wait for read_thread () to finish, if needed
-    l_readRunning->lock ();
-    l_readRunning->unlock ();
-  }
-
-  // remove run loop stuff
-  CFRunLoopRemoveSource (CFRunLoopGetCurrent (),
-                        l_cfSource, kCFRunLoopDefaultMode);
-
-  if (usb_debug)
-    fprintf (stderr, "fusb_ephandle_darwin::run_thread: finished for %s.\n",
-            l_input_p ? "read" : "write");
-
-  // release the run thread running mutex
-  l_runThreadRunning->unlock ();
-}
-
-void
-fusb_ephandle_darwin::read_thread (void* arg)
-{
-  if (usb_debug)
-    fprintf (stderr, "fusb_ephandle_darwin::read_thread: starting.\n");
-
-  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(arg);
-
-  // before doing anything else, lock the read running mutex.  this
-  // mutex does flow control between this thread and the run_thread
-  mld_mutex_ptr l_readRunning = This->d_readRunning;
-  l_readRunning->lock ();
-
-  // signal the read condition from run_thread() to continue
-
-  // lock the readBlock mutex first; this will force waiting until the
-  // ->wait() command is issued in ::run_thread()
-  mld_condition_ptr l_readBlock = This->d_readBlock;
-  mld_mutex_ptr l_read_block_mutex = l_readBlock->mutex ();
-  l_read_block_mutex->lock ();
-
-  // now that the lock is in place, signal the parent thread that
-  // things are running here
-  l_readBlock->signal ();
-
-  // release the run_block mutex, just in case
-  l_read_block_mutex->unlock ();
-
-  // queue up all of the available read requests
-  s_queue_ptr l_queue = This->d_queue;
-  l_queue->iterate_start ();
-  s_node_ptr l_node = l_queue->iterate_next ();
-  while (l_node) {
-    This->read_issue (l_node->both ());
-    l_node = l_queue->iterate_next ();
-  }
-
-  if (usb_debug)
-    fprintf (stderr, "fusb_ephandle_darwin::read_thread: finished.\n");
-
-  // release the read running mutex, to let the parent thread knows
-  // that this thread is finished
-  l_readRunning->unlock ();
-}
-
-void
-fusb_ephandle_darwin::read_issue (s_both_ptr l_both)
-{
-  if ((! l_both) || (! d_started)) {
-    if (usb_debug > 4)
-      fprintf (stderr, "fusb_ephandle_darwin::read_issue: Doing nothing; "
-              "l_both is %X; started is %s\n", (unsigned int) l_both,
-              d_started ? "TRUE" : "FALSE");
-    return;
-  }
-
-// set the node and buffer from the input "both"
-  s_node_ptr l_node = l_both->node ();
-  s_buffer_ptr l_buf = l_node->object ();
-  void* v_buffer = (void*) l_buf->buffer ();
-
-// read up to d_bufLenBytes
-  UInt32 bufLen = d_bufLenBytes;
-  l_buf->n_used (bufLen);
-
-// setup system call result
-  io_return_t result = kIOReturnSuccess;
-
-  if (d_transferType == kUSBInterrupt)
-/* This is an interrupt pipe. We can't specify a timeout. */
-    result = d_interface->ReadPipeAsync
-      (d_interfaceRef, d_pipeRef, v_buffer, bufLen,
-       (IOAsyncCallback1) read_completed, (void*) l_both);
-  else
-    result = d_interface->ReadPipeAsyncTO
-      (d_interfaceRef, d_pipeRef, v_buffer, bufLen, 0, USB_TIMEOUT,
-       (IOAsyncCallback1) read_completed, (void*) l_both);
-
-  if (result != kIOReturnSuccess)
-    USB_ERROR_STR_NO_RET (- darwin_to_errno (result),
-                         "fusb_ephandle_darwin::read_issue "
-                         "(ReadPipeAsync%s): %s",
-                         d_transferType == kUSBInterrupt ? "" : "TO",
-                         darwin_error_str (result));
-  else if (usb_debug > 4)
-    fprintf (stderr, "fusb_ephandle_darwin::read_issue: "
-            "Queued %X (%ld Bytes)\n", (unsigned int) l_both, bufLen);
-}
-
-void
-fusb_ephandle_darwin::read_completed (void* refCon,
-                                     io_return_t result,
-                                     void* io_size)
-{
-  UInt32 l_size = (UInt32) io_size;
-  s_both_ptr l_both = static_cast<s_both_ptr>(refCon);
-  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(l_both->This ());
-  s_node_ptr l_node = l_both->node ();
-  circular_buffer<char>* l_buffer = This->d_buffer;
-  s_buffer_ptr l_buf = l_node->object ();
-  UInt32 l_i_size = l_buf->n_used ();
-
-  if (This->d_started && (l_i_size != l_size))
-    fprintf (stderr, "fusb_ephandle_darwin::read_completed: "
-            "Expected %ld bytes; read %ld.\n",
-            l_i_size, l_size);
-  else if (usb_debug > 4)
-    fprintf (stderr, "fusb_ephandle_darwin::read_completed: "
-            "Read %X (%ld bytes)\n",
-            (unsigned int) l_both, l_size);
-
-// add this read to the transfer buffer
-  if (l_buffer->enqueue (l_buf->buffer (), l_size) == -1) {
-    fputs ("iU", stderr);
-    fflush (stderr);
-  }
-
-// set buffer's # data to 0
-  l_buf->n_used (0);
-
-// issue another read for this "both"
-  This->read_issue (l_both);
-}
-
-int
-fusb_ephandle_darwin::read (void* buffer, int nbytes)
-{
-  UInt32 l_nbytes = (UInt32) nbytes;
-  d_buffer->dequeue ((char*) buffer, &l_nbytes);
-
-  if (usb_debug > 4)
-    fprintf (stderr, "fusb_ephandle_darwin::read: request for %d bytes, %ld bytes retrieved.\n", nbytes, l_nbytes);
-
-  return ((int) l_nbytes);
-}
-
-int
-fusb_ephandle_darwin::write (const void* buffer, int nbytes)
-{
-  UInt32 l_nbytes = (UInt32) nbytes;
-
-  if (! d_started) {
-    if (usb_debug)
-      fprintf (stderr, "fusb_ephandle_darwin::write: Not yet started.\n");
-
-    return (0);
-  }
-
-  while (l_nbytes != 0) {
-// find out how much data to copy; limited to "d_bufLenBytes" per node
-    UInt32 t_nbytes = (l_nbytes > d_bufLenBytes) ? d_bufLenBytes : l_nbytes;
-
-// get next available node to write into;
-// blocks internally if none available
-    s_node_ptr l_node = d_queue->find_next_available_node ();
-
-// copy the input into the node's buffer
-    s_buffer_ptr l_buf = l_node->object ();
-    l_buf->buffer ((char*) buffer, t_nbytes);
-    void* v_buffer = (void*) l_buf->buffer ();
-
-// setup callback parameter & system call return
-    s_both_ptr l_both = l_node->both ();
-    io_return_t result = kIOReturnSuccess;
-
-    if (d_transferType == kUSBInterrupt)
-/* This is an interrupt pipe ... can't specify a timeout. */
-      result = d_interface->WritePipeAsync
-       (d_interfaceRef, d_pipeRef, v_buffer, t_nbytes,
-        (IOAsyncCallback1) write_completed, (void*) l_both);
-    else
-      result = d_interface->WritePipeAsyncTO
-       (d_interfaceRef, d_pipeRef, v_buffer, t_nbytes, 0, USB_TIMEOUT,
-        (IOAsyncCallback1) write_completed, (void*) l_both);
-
-    if (result != kIOReturnSuccess)
-      USB_ERROR_STR (-1, - darwin_to_errno (result),
-                    "fusb_ephandle_darwin::write_thread "
-                    "(WritePipeAsync%s): %s",
-                    d_transferType == kUSBInterrupt ? "" : "TO",
-                    darwin_error_str (result));
-    else if (usb_debug > 4) {
-      fprintf (stderr, "fusb_ephandle_darwin::write_thread: "
-              "Queued %X (%ld Bytes)\n", (unsigned int) l_both, t_nbytes);
-    }
-    l_nbytes -= t_nbytes;
-  }
-
-  return (nbytes);
-}
-
-void
-fusb_ephandle_darwin::write_completed (void* refCon,
-                                      io_return_t result,
-                                      void* io_size)
-{
-  s_both_ptr l_both = static_cast<s_both_ptr>(refCon);
-  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(l_both->This ());
-  UInt32 l_size = (UInt32) io_size;
-  s_node_ptr l_node = l_both->node ();
-  s_queue_ptr l_queue = This->d_queue;
-  s_buffer_ptr l_buf = l_node->object ();
-  UInt32 l_i_size = l_buf->n_used ();
-
-  if (This->d_started && (l_i_size != l_size))
-    fprintf (stderr, "fusb_ephandle_darwin::write_completed: "
-            "Expected %ld bytes written; wrote %ld.\n",
-            l_i_size, l_size);
-  else if (usb_debug > 4)
-    fprintf (stderr, "fusb_ephandle_darwin::write_completed: "
-            "Wrote %X (%ld Bytes)\n", (unsigned int) l_both, l_size);
-
-// set buffer's # data to 0
-  l_buf->n_used (0);
-// make the node available for reuse
-  l_queue->make_node_available (l_node);
-}
-
-void
-fusb_ephandle_darwin::abort ()
-{
-  if (usb_debug)
-    fprintf (stderr, "fusb_ephandle_darwin::abort: starting.\n");
-
-  io_return_t result = d_interface->AbortPipe (d_interfaceRef, d_pipeRef);
-
-  if (result != kIOReturnSuccess)
-    USB_ERROR_STR_NO_RET (- darwin_to_errno (result),
-                         "fusb_ephandle_darwin::abort "
-                         "(AbortPipe): %s", darwin_error_str (result));
-  if (usb_debug)
-    fprintf (stderr, "fusb_ephandle_darwin::abort: finished.\n");
-}
-
-bool
-fusb_ephandle_darwin::stop ()
-{
-  if (! d_started)
-    return (true);
-
-  if (usb_debug)
-    fprintf (stderr, "fusb_ephandle_darwin::stop: stopping %s.\n",
-            d_input_p ? "read" : "write");
-
-  d_started = false;
-
-// abort any pending IO transfers
-  abort ();
-
-// wait for write transfer to finish
-  wait_for_completion ();
-
-// tell IO buffer to abort any waiting conditions
-  d_buffer->abort ();
-
-// stop the run loop
-  CFRunLoopStop (d_CFRunLoopRef);
-
-// wait for the runThread to stop
-  d_runThreadRunning->lock ();
-  d_runThreadRunning->unlock ();
-
-  if (usb_debug)
-    fprintf (stderr, "fusb_ephandle_darwin::stop: %s stopped.\n",
-            d_input_p ? "read" : "write");
-
-  return (true);
-}
-
-void
-fusb_ephandle_darwin::wait_for_completion ()
-{
-  if (d_queue)
-    while (d_queue->in_use ())
-      usleep (1000);
-}
diff --git a/usrp/host/lib/legacy/fusb_darwin.h b/usrp/host/lib/legacy/fusb_darwin.h
deleted file mode 100644 (file)
index bb717b5..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 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 _FUSB_DARWIN_H_
-#define _FUSB_DARWIN_H_
-
-#include <usb.h>
-#include "fusb.h"
-#include <IOKit/IOCFBundle.h>
-#include <IOKit/IOCFPlugIn.h>
-#include <IOKit/usb/IOUSBLib.h>
-#include <IOKit/IOKitLib.h>
-#include "circular_linked_list.h"
-#include "circular_buffer.h"
-
-// for MacOS X 10.4.[0-3]
-#define usb_interface_t IOUSBInterfaceInterface220
-#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID220
-#define InterfaceVersion 220
-
-// for MacOS X 10.3.[0-9] and 10.4.[0-3]
-#define usb_device_t    IOUSBDeviceInterface197
-#define DeviceInterfaceID kIOUSBDeviceInterfaceID197
-#define DeviceVersion 197
-
-extern "C" {
-typedef struct usb_dev_handle {
-  int fd;
-
-  struct usb_bus *bus;
-  struct usb_device *device;
-
-  int config;
-  int interface;
-  int altsetting;
-
-  /* Added by RMT so implementations can store other per-open-device data */
-  void *impl_info;
-} usb_dev_handle;
-
-/* Darwin/OS X impl does not use fd field, instead it uses this */
-typedef struct darwin_dev_handle {
-  usb_device_t** device;
-  usb_interface_t** interface;
-  int open;
-} darwin_dev_handle;
-
-typedef IOReturn io_return_t;
-typedef IOCFPlugInInterface *io_cf_plugin_ref_t;
-
-static int ep_to_pipeRef (darwin_dev_handle* device, int ep);
-extern int usb_debug;
-}
-
-class s_buffer
-{
-private:
-  char* d_buffer;
-  UInt32 d_n_used, d_n_alloc;
-
-public:
-  inline s_buffer (UInt32 n_alloc = 0) {
-    d_n_used = 0;
-    d_n_alloc = n_alloc;
-    if (n_alloc) {
-      d_buffer = (char*) new char [n_alloc];
-    } else {
-      d_buffer = 0;
-    }
-  };
-  inline ~s_buffer () {
-    if (d_n_alloc) {
-      delete [] d_buffer;
-    }
-  };
-  inline UInt32 n_used () { return (d_n_used); };
-  inline void n_used (UInt32 bufLen) {
-    d_n_used = (bufLen > d_n_alloc) ? d_n_alloc : bufLen; };
-  inline UInt32 n_alloc () { return (d_n_alloc); };
-  void buffer (char* l_buffer, UInt32 bufLen) {
-    if (bufLen > d_n_alloc) {
-      fprintf (stderr, "s_buffer::set: Copying only allocated bytes.\n");
-      bufLen = d_n_alloc;
-    }
-    if (!l_buffer) {
-      fprintf (stderr, "s_buffer::set: NULL buffer.\n");
-      return;
-    }
-    bcopy (l_buffer, d_buffer, bufLen);
-    d_n_used = bufLen;
-  };
-  inline char* buffer () { return (d_buffer); };
-  inline void reset () {
-    bzero (d_buffer, d_n_alloc);
-    d_n_used = 0;
-  };
-};
-
-typedef s_buffer* s_buffer_ptr;
-typedef s_node<s_buffer_ptr>* s_node_ptr;
-typedef circular_linked_list<s_buffer_ptr>* s_queue_ptr;
-typedef s_both<s_buffer_ptr>* s_both_ptr;
-
-/*!
- * \brief darwin implementation of fusb_devhandle
- *
- * This is currently identical to the generic implementation
- * and is intended as a starting point for whatever magic is
- * required to make usb fly.
- */
-class fusb_devhandle_darwin : public fusb_devhandle
-{
-public:
-  // CREATORS
-  fusb_devhandle_darwin (usb_dev_handle* udh);
-  virtual ~fusb_devhandle_darwin ();
-
-  // MANIPULATORS
-  virtual fusb_ephandle* make_ephandle (int endpoint, bool input_p,
-                                       int block_size = 0, int nblocks = 0);
-};
-
-/*!
- * \brief darwin implementation of fusb_ephandle
- *
- * This is currently identical to the generic implementation
- * and is intended as a starting point for whatever magic is
- * required to make usb fly.
- */
-class fusb_ephandle_darwin : public fusb_ephandle
-{
-private:
-  fusb_devhandle_darwin* d_devhandle;
-  mld_thread_ptr d_runThread;
-  mld_mutex_ptr d_runThreadRunning;
-
-  CFRunLoopRef d_CFRunLoopRef;
-
-  static void write_completed (void* ret_io_size,
-                              io_return_t result,
-                              void* io_size);
-  static void read_completed (void* ret_io_size,
-                             io_return_t result,
-                             void* io_size);
-  static void run_thread (void* arg);
-  static void read_thread (void* arg);
-
-  void read_issue (s_both_ptr l_both);
-
-public:
-  // variables, for now
-  UInt8 d_pipeRef, d_transferType;
-  usb_interface_t** d_interfaceRef;
-  usb_interface_t* d_interface;
-  s_queue_ptr d_queue;
-  circular_buffer<char>* d_buffer;
-  UInt32 d_bufLenBytes;
-  mld_mutex_ptr d_readRunning;
-  mld_condition_ptr d_runBlock, d_readBlock;
-
-// CREATORS
-
-  fusb_ephandle_darwin (fusb_devhandle_darwin *dh, int endpoint, bool input_p,
-                        int block_size = 0, int nblocks = 0);
-  virtual ~fusb_ephandle_darwin ();
-
-// MANIPULATORS
-
-  virtual bool start ();       //!< begin streaming i/o
-  virtual bool stop ();                //!< stop streaming i/o
-
-  /*!
-   * \returns \p nbytes if write was successfully enqueued, else -1.
-   * Will block if no free buffers available.
-   */
-  virtual int write (const void* buffer, int nbytes);
-
-  /*!
-   * \returns number of bytes read or -1 if error.
-   * number of bytes read will be <= nbytes.
-   * Will block if no input available.
-   */
-  virtual int read (void* buffer, int nbytes);
-
-  /*
-   * abort any pending IO transfers
-   */
-  void abort ();
-
-  /*
-   * block until all outstanding writes have completed
-   */
-  virtual void wait_for_completion ();
-};
-
-#endif /* _FUSB_DARWIN_H_ */
diff --git a/usrp/host/lib/legacy/fusb_generic.cc b/usrp/host/lib/legacy/fusb_generic.cc
deleted file mode 100644 (file)
index 0958716..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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 <fusb_generic.h>
-#include <usb.h>
-
-
-static const int USB_TIMEOUT = 1000;   // in milliseconds
-
-
-fusb_devhandle_generic::fusb_devhandle_generic (usb_dev_handle *udh)
-  : fusb_devhandle (udh)
-{
-  // that's it
-}
-
-fusb_devhandle_generic::~fusb_devhandle_generic ()
-{
-  // nop
-}
-
-fusb_ephandle *
-fusb_devhandle_generic::make_ephandle (int endpoint, bool input_p,
-                                      int block_size, int nblocks)
-{
-  return new fusb_ephandle_generic (this, endpoint, input_p,
-                                   block_size, nblocks);
-}
-
-// ----------------------------------------------------------------
-
-fusb_ephandle_generic::fusb_ephandle_generic (fusb_devhandle_generic *dh,
-                                             int endpoint, bool input_p,
-                                             int block_size, int nblocks)
-  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
-    d_devhandle (dh)
-{
-  // that's it
-}
-
-fusb_ephandle_generic::~fusb_ephandle_generic ()
-{
-  // nop
-}
-
-bool
-fusb_ephandle_generic::start ()
-{
-  d_started = true;
-  return true;
-}
-
-bool
-fusb_ephandle_generic::stop ()
-{
-  d_started = false;
-  return true;
-}
-
-int
-fusb_ephandle_generic::write (const void *buffer, int nbytes)
-{
-  if (!d_started)      // doesn't matter here, but keeps semantics constant
-    return -1;
-  
-  if (d_input_p)
-    return -1;
-  
-  return usb_bulk_write (d_devhandle->get_usb_dev_handle (),
-                        d_endpoint, (char *) buffer, nbytes, USB_TIMEOUT);
-}
-
-int
-fusb_ephandle_generic::read (void *buffer, int nbytes)
-{
-  if (!d_started)      // doesn't matter here, but keeps semantics constant
-    return -1;
-
-  if (!d_input_p)
-    return -1;
-
-  return usb_bulk_read (d_devhandle->get_usb_dev_handle (),
-                       d_endpoint|USB_ENDPOINT_IN, (char *) buffer, nbytes,
-                       USB_TIMEOUT);
-}
diff --git a/usrp/host/lib/legacy/fusb_generic.h b/usrp/host/lib/legacy/fusb_generic.h
deleted file mode 100644 (file)
index b9aef27..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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 _FUSB_GENERIC_H_
-#define _FUSB_GENERIC_H_
-
-#include <fusb.h>
-
-/*!
- * \brief generic implementation of fusb_devhandle using only libusb
- */
-class fusb_devhandle_generic : public fusb_devhandle
-{
-public:
-  // CREATORS
-  fusb_devhandle_generic (usb_dev_handle *udh);
-  virtual ~fusb_devhandle_generic ();
-
-  // MANIPULATORS
-  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
-                                       int block_size = 0, int nblocks = 0);
-};
-
-
-/*!
- * \brief generic implementation of fusb_ephandle using only libusb
- */
-class fusb_ephandle_generic : public fusb_ephandle
-{
-private:
-  fusb_devhandle_generic       *d_devhandle;
-  
-public:
-  // CREATORS
-  fusb_ephandle_generic (fusb_devhandle_generic *dh, int endpoint, bool input_p,
-                        int block_size = 0, int nblocks = 0);
-  virtual ~fusb_ephandle_generic ();
-
-  // MANIPULATORS
-
-  virtual bool start ();       //!< begin streaming i/o
-  virtual bool stop ();                //!< stop streaming i/o
-
-  /*!
-   * \returns \p nbytes if write was successfully enqueued, else -1.
-   * Will block if no free buffers available.
-   */
-  virtual int write (const void *buffer, int nbytes);
-
-  /*!
-   * \returns number of bytes read or -1 if error.
-   * number of bytes read will be <= nbytes.
-   * Will block if no input available.
-   */
-  virtual int read (void *buffer, int nbytes);
-
-  /*
-   * block until all outstanding writes have completed
-   */
-  virtual void wait_for_completion () { };
-};
-
-#endif /* _FUSB_GENERIC_H_ */
-
diff --git a/usrp/host/lib/legacy/fusb_linux.cc b/usrp/host/lib/legacy/fusb_linux.cc
deleted file mode 100644 (file)
index 6c48456..0000000
+++ /dev/null
@@ -1,692 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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 <fusb_linux.h>
-#include <usb.h>               // libusb header
-#include <stdexcept>
-#ifdef HAVE_LINUX_COMPILER_H
-#include <linux/compiler.h>
-#endif
-#include <linux/usbdevice_fs.h>        // interface to kernel portion of user mode usb driver
-#include <sys/ioctl.h>
-#include <assert.h>
-#include <string.h>
-#include <algorithm>
-#include <errno.h>
-#include <string.h>
-#include <cstdio>
-
-#define MINIMIZE_TX_BUFFERING 1                // must be defined to 0 or 1
-
-
-static const int MAX_BLOCK_SIZE = fusb_sysconfig::max_block_size();            // hard limit
-static const int DEFAULT_BLOCK_SIZE = MAX_BLOCK_SIZE;
-static const int DEFAULT_BUFFER_SIZE = 4 * (1L << 20);                         // 4 MB / endpoint
-
-
-// Totally evil and fragile extraction of file descriptor from
-// guts of libusb.  They don't install usbi.h, which is what we'd need
-// to do this nicely.
-//
-// FIXME if everything breaks someday in the future, look here...
-
-static int
-fd_from_usb_dev_handle (usb_dev_handle *udh)
-{
-  return *((int *) udh);
-}
-
-inline static void
-urb_set_ephandle (usbdevfs_urb *urb, fusb_ephandle_linux *handle)
-{
-  urb->usercontext = handle;
-}
-
-inline static fusb_ephandle_linux *
-urb_get_ephandle (usbdevfs_urb *urb)
-{
-  return (fusb_ephandle_linux *) urb->usercontext;
-}
-
-// ------------------------------------------------------------------------
-//                USB request block (urb) allocation
-// ------------------------------------------------------------------------
-
-static usbdevfs_urb *
-alloc_urb (fusb_ephandle_linux *self, int buffer_length, int endpoint,
-          bool input_p, unsigned char *write_buffer)
-{
-  usbdevfs_urb *urb = new usbdevfs_urb;
-  memset (urb, 0, sizeof (*urb));
-
-  urb->buffer_length = buffer_length;
-
-  // We allocate dedicated memory only for input buffers.
-  // For output buffers we reuse the same buffer (the kernel 
-  // copies the data at submital time)
-
-  if (input_p)
-    urb->buffer = new unsigned char [buffer_length];
-  else
-    urb->buffer = write_buffer;
-
-  // init common values
-
-  urb->type = USBDEVFS_URB_TYPE_BULK;
-  urb->endpoint = (endpoint & 0x7f) | (input_p ? 0x80 : 0);
-
-  // USBDEVFS_URB_QUEUE_BULK goes away in linux 2.5, but is needed if
-  // we are using a 2.4 usb-uhci host controller driver.  This is
-  // unlikely since we're almost always going to be plugged into a
-  // high speed host controller (ehci)
-#if 0 && defined (USBDEVFS_URB_QUEUE_BULK)
-  urb->flags = USBDEVFS_URB_QUEUE_BULK;
-#endif
-
-  urb->signr = 0;
-  urb_set_ephandle (urb, self);
-
-  return urb;
-}
-
-static void
-free_urb (usbdevfs_urb *urb)
-{
-  // if this was an input urb, free the buffer
-  if (urb->endpoint & 0x80)
-    delete [] ((unsigned char *) urb->buffer);
-
-  delete urb;
-}
-
-// ------------------------------------------------------------------------
-//                             device handle
-// ------------------------------------------------------------------------
-
-fusb_devhandle_linux::fusb_devhandle_linux (usb_dev_handle *udh)
-  : fusb_devhandle (udh)
-{
-  // that's all
-}
-
-fusb_devhandle_linux::~fusb_devhandle_linux ()
-{
-  // if there are any pending requests, cancel them and free the urbs.
-  
-  std::list<usbdevfs_urb*>::reverse_iterator it;
-
-  for (it = d_pending_rqsts.rbegin (); it != d_pending_rqsts.rend (); it++){
-    _cancel_urb (*it);
-    free_urb (*it);
-  }
-}
-
-fusb_ephandle *
-fusb_devhandle_linux::make_ephandle (int endpoint, bool input_p,
-                                    int block_size, int nblocks)
-{
-  return new fusb_ephandle_linux (this, endpoint, input_p,
-                                 block_size, nblocks);
-}
-
-
-// Attempt to cancel all transactions associated with eph.
-
-void
-fusb_devhandle_linux::_cancel_pending_rqsts (fusb_ephandle_linux *eph)
-{
-  std::list<usbdevfs_urb*>::reverse_iterator it;
-
-  for (it = d_pending_rqsts.rbegin (); it != d_pending_rqsts.rend (); it++){
-    if (urb_get_ephandle (*it) == eph)
-      _cancel_urb (*it);
-  }
-}
-
-void 
-fusb_devhandle_linux::pending_add (usbdevfs_urb *urb)
-{
-  d_pending_rqsts.push_back (urb);
-}
-
-usbdevfs_urb *
-fusb_devhandle_linux::pending_get ()
-{
-  if (d_pending_rqsts.empty ())
-    return 0;
-
-  usbdevfs_urb *urb = d_pending_rqsts.front ();
-  d_pending_rqsts.pop_front ();
-  return urb;
-}
-
-bool
-fusb_devhandle_linux::pending_remove (usbdevfs_urb *urb)
-{
-  std::list<usbdevfs_urb*>::iterator   result = find (d_pending_rqsts.begin (),
-                                                      d_pending_rqsts.end (),
-                                                      urb);
-  if (result == d_pending_rqsts.end ()){
-    fprintf (stderr, "fusb::pending_remove: failed to find urb in pending_rqsts: %p\n", urb);
-    return false;
-  }
-  d_pending_rqsts.erase (result);
-  return true;
-}
-
-/*
- * Submit the urb to the kernel.
- * iff successful, the urb will be placed on the devhandle's pending list.
- */
-bool
-fusb_devhandle_linux::_submit_urb (usbdevfs_urb *urb)
-{
-  int  ret;
-
-  ret = ioctl (fd_from_usb_dev_handle (d_udh), USBDEVFS_SUBMITURB, urb);
-  if (ret < 0){
-    perror ("fusb::_submit_urb");
-    return false;
-  }
-  
-  pending_add (urb);
-  return true;
-}
-
-/*
- * Attempt to cancel the in pending or in-progress urb transaction.
- * Return true iff transaction was sucessfully cancelled.
- *
- * Failure to cancel should not be considered a problem.  This frequently
- * occurs if the transaction has already completed in the kernel but hasn't
- * yet been reaped by the user mode code.
- *
- * urbs which were cancelled have their status field set to -ENOENT when
- * they are reaped.
- */
-bool
-fusb_devhandle_linux::_cancel_urb (usbdevfs_urb *urb)
-{
-  int ret = ioctl (fd_from_usb_dev_handle (d_udh), USBDEVFS_DISCARDURB, urb);
-  if (ret < 0){
-    // perror ("fusb::_cancel_urb");
-    return false;
-  }
-  return true;
-}
-
-/*
- * Check with the kernel and see if any of our outstanding requests
- * have completed.  For each completed transaction, remove it from the
- * devhandle's pending list and append it to the completed list for
- * the corresponding endpoint.
- *
- * If any transactions are reaped return true.
- *
- * If ok_to_block_p is true, then this will block until at least one
- * transaction completes or an unrecoverable error occurs.
- */
-bool
-fusb_devhandle_linux::_reap (bool ok_to_block_p)
-{
-  int          ret;
-  int          nreaped = 0;
-  usbdevfs_urb *urb = 0;
-
-  int  fd = fd_from_usb_dev_handle (d_udh);
-  
-  // try to reap as many as possible without blocking...
-
-  while ((ret = ioctl (fd, USBDEVFS_REAPURBNDELAY, &urb)) == 0){
-    if (urb->status != 0 && urb->status != -ENOENT){
-      fprintf (stderr, "_reap: usb->status = %d, actual_length = %5d\n",
-              urb->status, urb->actual_length);
-    }
-    pending_remove (urb);
-    urb_get_ephandle (urb)->completed_list_add (urb);
-    nreaped++;
-  }
-
-  if (nreaped > 0)             // if we got any, return w/o blocking
-    return true;
-
-  if (!ok_to_block_p)
-    return false;
-  
-  ret = ioctl (fd, USBDEVFS_REAPURB, &urb);
-  if (ret < 0){
-    perror ("fusb::_reap");
-    return false;
-  }
-
-  pending_remove (urb);
-  urb_get_ephandle (urb)->completed_list_add (urb);
-  return true;
-}
-
-void
-fusb_devhandle_linux::_wait_for_completion ()
-{
-  while (!d_pending_rqsts.empty ())
-    if (!_reap(true))
-      break;
-}
-\f// ------------------------------------------------------------------------
-//                          end point handle
-// ------------------------------------------------------------------------
-
-fusb_ephandle_linux::fusb_ephandle_linux (fusb_devhandle_linux *devhandle,
-                                         int endpoint,
-                                         bool input_p,
-                                         int block_size, int nblocks)
-  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
-    d_devhandle (devhandle), 
-    d_write_work_in_progress (0), d_write_buffer (0),
-    d_read_work_in_progress (0), d_read_buffer (0), d_read_buffer_end (0)
-{
-
-  if (d_block_size < 0 || d_block_size > MAX_BLOCK_SIZE)
-    throw std::out_of_range ("fusb_ephandle_linux: block_size");
-
-  if (d_nblocks < 0)
-    throw std::out_of_range ("fusb_ephandle_linux: nblocks");
-
-  if (d_block_size == 0)
-    d_block_size = DEFAULT_BLOCK_SIZE;
-
-  if (d_nblocks == 0)
-    d_nblocks = std::max (1, DEFAULT_BUFFER_SIZE / d_block_size);
-
-  if (!d_input_p)
-    if (!MINIMIZE_TX_BUFFERING)
-      d_write_buffer = new unsigned char [d_block_size];
-
-  if (0)
-    fprintf(stderr, "fusb_ephandle_linux::ctor: d_block_size = %d  d_nblocks = %d\n",
-           d_block_size, d_nblocks);
-
-  // allocate urbs
-
-  for (int i = 0; i < d_nblocks; i++)
-    d_free_list.push_back (alloc_urb (this, d_block_size, d_endpoint,
-                                     d_input_p, d_write_buffer));
-}
-
-fusb_ephandle_linux::~fusb_ephandle_linux ()
-{
-  stop ();
-
-  usbdevfs_urb *urb;
-
-  while ((urb = free_list_get ()) != 0)
-    free_urb (urb);
-
-  while ((urb = completed_list_get ()) != 0)
-    free_urb (urb);
-
-  if (d_write_work_in_progress)
-    free_urb (d_write_work_in_progress);
-
-  delete [] d_write_buffer;
-
-  if (d_read_work_in_progress)
-    free_urb (d_read_work_in_progress);
-}
-
-// ----------------------------------------------------------------
-
-bool
-fusb_ephandle_linux::start ()
-{
-  if (d_started)
-    return true;               // already running
-
-  d_started = true;
-
-  if (d_input_p){              // fire off all the reads
-    usbdevfs_urb *urb;
-
-    int nerrors = 0;
-    while ((urb = free_list_get ()) != 0 && nerrors < d_nblocks){
-      if (!submit_urb (urb))
-       nerrors++;
-    }
-  }
-
-  return true;
-}
-
-//
-// kill all i/o in progress.
-// kill any completed but unprocessed transactions.
-//
-bool
-fusb_ephandle_linux::stop ()
-{
-  if (!d_started)
-    return true;
-
-  if (d_write_work_in_progress){
-    free_list_add (d_write_work_in_progress);
-    d_write_work_in_progress = 0;
-  }
-
-  if (d_read_work_in_progress){
-    free_list_add (d_read_work_in_progress);
-    d_read_work_in_progress = 0;
-    d_read_buffer = 0;
-    d_read_buffer_end = 0;
-  }
-
-  d_devhandle->_cancel_pending_rqsts (this);
-  d_devhandle->_reap (false);
-
-  while (1){
-    usbdevfs_urb *urb;
-    while ((urb = completed_list_get ()) != 0)
-      free_list_add (urb);
-
-    if (d_free_list.size () == (unsigned) d_nblocks)
-      break;
-
-    if (!d_devhandle->_reap(true))
-      break;
-  }
-
-  d_started = false;
-  return true;
-}
-
-// ----------------------------------------------------------------
-//                     routines for writing 
-// ----------------------------------------------------------------
-
-#if (MINIMIZE_TX_BUFFERING)
-
-int 
-fusb_ephandle_linux::write(const void *buffer, int nbytes)
-{
-  if (!d_started)
-    return -1;
-  
-  if (d_input_p)
-    return -1;
-
-  assert(nbytes % 512 == 0);
-
-  unsigned char *src = (unsigned char *) buffer;
-
-  int n = 0;
-  while (n < nbytes){
-
-    usbdevfs_urb *urb = get_write_work_in_progress();
-    if (!urb)
-      return -1;
-    assert(urb->actual_length == 0);
-    int m = std::min(nbytes - n, MAX_BLOCK_SIZE);
-    urb->buffer = src;
-    urb->buffer_length = m;
-
-    n += m;
-    src += m;
-
-    if (!submit_urb(urb))
-      return -1;
-
-    d_write_work_in_progress = 0;
-  }
-
-  return n;
-}
-
-#else
-
-int 
-fusb_ephandle_linux::write (const void *buffer, int nbytes)
-{
-  if (!d_started)
-    return -1;
-  
-  if (d_input_p)
-    return -1;
-
-  unsigned char *src = (unsigned char *) buffer;
-
-  int n = 0;
-  while (n < nbytes){
-
-    usbdevfs_urb *urb = get_write_work_in_progress ();
-    if (!urb)
-      return -1;
-    unsigned char *dst = (unsigned char *) urb->buffer;
-    int m = std::min (nbytes - n, urb->buffer_length - urb->actual_length);
-
-    memcpy (&dst[urb->actual_length], &src[n], m);
-    urb->actual_length += m;
-    n += m;
-
-    if (urb->actual_length == urb->buffer_length){
-      if (!submit_urb (urb))
-       return -1;
-      d_write_work_in_progress = 0;
-    }
-  }
-
-  return n;
-}
-
-#endif
-
-usbdevfs_urb *
-fusb_ephandle_linux::get_write_work_in_progress ()
-{
-  // if we've already got some work in progress, return it
-
-  if (d_write_work_in_progress)
-    return d_write_work_in_progress;
-
-  while (1){
-
-    reap_complete_writes ();
-
-    usbdevfs_urb *urb = free_list_get ();
-
-    if (urb != 0){
-      assert (urb->actual_length == 0);
-      d_write_work_in_progress = urb;
-      return urb;
-    }
-
-    // The free list is empty.  Tell the device handle to reap.
-    // Anything it reaps for us will end up on our completed list.
-
-    if (!d_devhandle->_reap (true))
-      return 0;
-  }
-}
-
-void
-fusb_ephandle_linux::reap_complete_writes ()
-{
-  // take a look at the completed_list and xfer to free list after
-  // checking for errors.
-
-  usbdevfs_urb *urb;
-  
-  while ((urb = completed_list_get ()) != 0){
-
-    // Check for any errors or short writes that were reported in the urb.
-    // The kernel sets status, actual_length and error_count.
-    // error_count is only used for ISO xfers.
-    // status is 0 if successful, else is an errno kind of thing
-
-    if (urb->status != 0){
-      fprintf (stderr, "fusb: (status %d) %s\n", urb->status, strerror (-urb->status));
-    }
-    else if (urb->actual_length != urb->buffer_length){
-      fprintf (stderr, "fusb: short write xfer: %d != %d\n",
-              urb->actual_length, urb->buffer_length);
-    }
-
-    free_list_add (urb);
-  }
-}
-
-void
-fusb_ephandle_linux::wait_for_completion ()
-{
-  d_devhandle->_wait_for_completion ();
-}
-
-// ----------------------------------------------------------------
-//                    routines for reading
-// ----------------------------------------------------------------
-
-int
-fusb_ephandle_linux::read (void *buffer, int nbytes)
-{
-  if (!d_started)
-    return -1;
-  
-  if (!d_input_p)
-    return -1;
-
-  unsigned char *dst = (unsigned char *) buffer;
-
-  int n = 0;
-  while (n < nbytes){
-
-    if (d_read_buffer >= d_read_buffer_end)
-      if (!reload_read_buffer ())
-       return -1;
-
-    int m = std::min (nbytes - n, (int) (d_read_buffer_end - d_read_buffer));
-
-    memcpy (&dst[n], d_read_buffer, m);
-    d_read_buffer += m;
-    n += m;
-  }
-
-  return n;
-}
-
-bool
-fusb_ephandle_linux::reload_read_buffer ()
-{
-  assert (d_read_buffer >= d_read_buffer_end);
-
-  usbdevfs_urb *urb;
-
-  if (d_read_work_in_progress){
-    // We're done with this urb.  Fire off a read to refill it.
-    urb = d_read_work_in_progress;
-    d_read_work_in_progress = 0;
-    d_read_buffer = 0;
-    d_read_buffer_end = 0;
-    urb->actual_length = 0;
-    if (!submit_urb (urb))
-      return false;
-  }
-
-  while (1){
-
-    while ((urb = completed_list_get ()) == 0)
-      if (!d_devhandle->_reap (true))
-       return false;
-
-    // check result of completed read
-
-    if (urb->status != 0){
-      // We've got a problem. Report it and fail.
-      fprintf (stderr, "fusb: (rd status %d) %s\n", urb->status, strerror (-urb->status));
-      urb->actual_length = 0;
-      free_list_add (urb);
-      return false;
-    }
-
-    // we've got a happy urb, full of data...
-
-    d_read_work_in_progress = urb;
-    d_read_buffer = (unsigned char *) urb->buffer;
-    d_read_buffer_end = d_read_buffer + urb->actual_length;
-
-    return true;
-  }
-}
-
-// ----------------------------------------------------------------
-
-void
-fusb_ephandle_linux::free_list_add (usbdevfs_urb *urb)
-{
-  assert (urb_get_ephandle (urb) == this);
-  urb->actual_length = 0;
-  d_free_list.push_back (urb);
-}
-
-usbdevfs_urb *
-fusb_ephandle_linux::free_list_get ()
-{
-  if (d_free_list.empty ())
-    return 0;
-
-  usbdevfs_urb *urb = d_free_list.front ();
-  d_free_list.pop_front ();
-  return urb;
-}
-
-void
-fusb_ephandle_linux::completed_list_add (usbdevfs_urb *urb)
-{
-  assert (urb_get_ephandle (urb) == this);
-  d_completed_list.push_back (urb);
-}
-
-usbdevfs_urb *
-fusb_ephandle_linux::completed_list_get ()
-{
-  if (d_completed_list.empty ())
-    return 0;
-
-  usbdevfs_urb *urb = d_completed_list.front ();
-  d_completed_list.pop_front ();
-  return urb;
-}
-
-/*
- * Submit the urb.  If successful the urb ends up on the devhandle's
- * pending list, otherwise, it's back on our free list.
- */
-bool
-fusb_ephandle_linux::submit_urb (usbdevfs_urb *urb)
-{
-  if (!d_devhandle->_submit_urb (urb)){    // FIXME record the problem somewhere
-    fprintf (stderr, "_submit_urb failed\n");
-    free_list_add (urb);
-    return false;
-  }
-  return true;
-}
diff --git a/usrp/host/lib/legacy/fusb_linux.h b/usrp/host/lib/legacy/fusb_linux.h
deleted file mode 100644 (file)
index 107e1af..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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.
- */
-
-// Fast USB interface
-
-#ifndef _FUSB_LINUX_H_
-#define _FUSB_LINUX_H_
-
-#include <fusb.h>
-#include <list>
-
-struct  usbdevfs_urb;
-class   fusb_ephandle_linux;
-
-/*!
- * \brief linux specific implementation of fusb_devhandle using usbdevice_fs
- */
-class fusb_devhandle_linux : public fusb_devhandle {
-private:
-  std::list<usbdevfs_urb*>      d_pending_rqsts;
-
-  void pending_add (usbdevfs_urb *urb);
-  bool pending_remove (usbdevfs_urb *urb);
-  usbdevfs_urb * pending_get ();
-
-
-public:
-  // CREATORS
-  fusb_devhandle_linux (usb_dev_handle *udh);
-  virtual ~fusb_devhandle_linux ();
-
-  // MANIPULATORS
-  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
-                                       int block_size = 0, int nblocks = 0);
-
-  // internal use only
-  bool _submit_urb (usbdevfs_urb *urb);
-  bool _cancel_urb (usbdevfs_urb *urb);
-  void _cancel_pending_rqsts (fusb_ephandle_linux *eph);
-  bool _reap (bool ok_to_block_p);
-  void _wait_for_completion ();
-};
-
-\f/*!
- * \brief linux specific implementation of fusb_ephandle using usbdevice_fs
- */
-
-class fusb_ephandle_linux : public fusb_ephandle {
-private:
-  fusb_devhandle_linux        *d_devhandle;
-  std::list<usbdevfs_urb*>     d_free_list;
-  std::list<usbdevfs_urb*>     d_completed_list;
-  usbdevfs_urb                *d_write_work_in_progress;
-  unsigned char                       *d_write_buffer;
-  usbdevfs_urb                *d_read_work_in_progress;
-  unsigned char                       *d_read_buffer;
-  unsigned char                       *d_read_buffer_end;
-
-  usbdevfs_urb *get_write_work_in_progress ();
-  void reap_complete_writes ();
-  bool reload_read_buffer ();
-  bool submit_urb (usbdevfs_urb *urb);
-  
-public:
-  fusb_ephandle_linux (fusb_devhandle_linux *dh, int endpoint, bool input_p,
-                      int block_size = 0, int nblocks = 0);
-  virtual ~fusb_ephandle_linux ();
-
-  virtual bool start ();       //!< begin streaming i/o
-  virtual bool stop ();                //!< stop streaming i/o
-
-  /*!
-   * \returns \p nbytes if write was successfully enqueued, else -1.
-   * Will block if no free buffers available.
-   */
-  virtual int write (const void *buffer, int nbytes);
-
-  /*!
-   * \returns number of bytes read or -1 if error.
-   * number of bytes read will be <= nbytes.
-   * Will block if no input available.
-   */
-  virtual int read (void *buffer, int nbytes);
-
-  /*
-   * block until all outstanding writes have completed
-   */
-  virtual void wait_for_completion ();
-
-  // internal use only
-  void free_list_add (usbdevfs_urb *urb);
-  void completed_list_add (usbdevfs_urb *urb);
-  usbdevfs_urb *free_list_get ();              // pop and return head of list or 0
-  usbdevfs_urb *completed_list_get ();         // pop and return head of list or 0
-};
-
-#endif /* _FUSB_LINUX_H_ */
diff --git a/usrp/host/lib/legacy/fusb_ra_wb.cc b/usrp/host/lib/legacy/fusb_ra_wb.cc
deleted file mode 100644 (file)
index 699a34b..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003,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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <fusb_ra_wb.h>
-#include <usb.h>
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include <sys/event.h>
-#include <dev/usb/usb.h>
-
-static const int USB_TIMEOUT = 1000;   // in milliseconds
-
-// the following comment and function is from fusb_linux.cc
-#if 0
-// Totally evil and fragile extraction of file descriptor from
-// guts of libusb.  They don't install usbi.h, which is what we'd need
-// to do this nicely.
-//
-// FIXME if everything breaks someday in the future, look here...
-
-static int
-fd_from_usb_dev_handle (usb_dev_handle *udh)
-{
-  return *((int *) udh);
-}
-#endif
-
-// the control endpoint doesn't actually do us any good so here is a
-// new "fragile extraction"
-static int
-ep_fd_from_usb_dev_handle (usb_dev_handle *udh, int endpoint)
-{
-  struct usb_dev_handle_kludge2 { // see also usrp_prims.cc
-    int                         fd;
-    struct usb_bus     *bus;
-    struct usb_device  *device;
-    int                         config;
-    int                         interface;
-    int                         altsetting;
-    void               *impl_info;
-  };
-  struct bsd_usb_dev_handle_info_kludge {
-    int                         ep_fd[USB_MAX_ENDPOINTS];
-  };
-  struct bsd_usb_dev_handle_info_kludge *info
-      = (struct bsd_usb_dev_handle_info_kludge *)
-           ((struct usb_dev_handle_kludge2 *)udh)->impl_info;
-  return info->ep_fd[UE_GET_ADDR(endpoint)];
-}
-
-
-fusb_devhandle_ra_wb::fusb_devhandle_ra_wb (usb_dev_handle *udh)
-  : fusb_devhandle (udh)
-{
-  // that's it
-}
-
-fusb_devhandle_ra_wb::~fusb_devhandle_ra_wb ()
-{
-  // nop
-}
-
-fusb_ephandle *
-fusb_devhandle_ra_wb::make_ephandle (int endpoint, bool input_p,
-                                    int block_size, int nblocks)
-{
-  return new fusb_ephandle_ra_wb (this, endpoint, input_p,
-                                 block_size, nblocks);
-}
-
-// ----------------------------------------------------------------
-
-fusb_ephandle_ra_wb::fusb_ephandle_ra_wb (fusb_devhandle_ra_wb *dh,
-                                         int endpoint, bool input_p,
-                                         int block_size, int nblocks)
-  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
-    d_devhandle (dh), d_ra_wb_on (false)
-{
-  // that's it 
-}
-
-fusb_ephandle_ra_wb::~fusb_ephandle_ra_wb ()
-{
-  // nop
-}
-
-bool
-fusb_ephandle_ra_wb::start ()
-{
-  d_started = true;
-
-  char buf = '\0';
-  int fd;
-
-  // this is to cause libusb to open the endpoint
-  if (!d_input_p) {
-    write(&buf, 0);
-    fd = ep_fd_from_usb_dev_handle (d_devhandle->get_usb_dev_handle(),
-                                   d_endpoint);
-  }
-  else {
-    read(&buf, 0);
-    fd = ep_fd_from_usb_dev_handle (d_devhandle->get_usb_dev_handle(),
-                                   d_endpoint|USB_ENDPOINT_IN);
-  }
-
-  // enable read ahead/write behind
-  int ret;
-  struct usb_bulk_ra_wb_opt opts;
-  int enable = 1;
-
-  opts.ra_wb_buffer_size = d_block_size*d_nblocks;
-  opts.ra_wb_request_size = d_block_size;
-//  fprintf (stderr, "setting buffer size to %d, request size to %d\n",
-//        opts.ra_wb_buffer_size, opts.ra_wb_request_size);
-  if (!d_input_p) {
-    ret = ioctl (fd, USB_SET_BULK_WB_OPT, &opts);
-    if (ret < 0)
-      fprintf (stderr, "USB_SET_BULK_WB_OPT: %s\n", strerror(errno));
-    else {
-      ret = ioctl (fd, USB_SET_BULK_WB, &enable);
-      if (ret < 0)
-       fprintf (stderr, "USB_SET_BULK_WB: %s\n", strerror(errno));
-      else
-       d_ra_wb_on = true;
-    }
-  }
-  else {
-    ret = ioctl (fd, USB_SET_BULK_RA_OPT, &opts);
-    if (ret < 0)
-      fprintf (stderr, "USB_SET_BULK_RA_OPT: %s\n", strerror(errno));
-    else {
-      ret = ioctl (fd, USB_SET_BULK_RA, &enable);
-      if (ret < 0)
-       fprintf (stderr, "USB_SET_BULK_RA: %s\n", strerror(errno));
-      else
-       d_ra_wb_on = true;
-    }
-  }
-
-  return true;
-}
-
-bool
-fusb_ephandle_ra_wb::stop ()
-{
-  int fd;
-  int ret;
-  int enable = 0;
-  if (d_ra_wb_on) {
-    if (!d_input_p) {
-      fd = ep_fd_from_usb_dev_handle (d_devhandle->get_usb_dev_handle(),
-                                     d_endpoint);
-      ret = ioctl (fd, USB_SET_BULK_WB, &enable);
-      if (ret < 0)
-       fprintf (stderr, "USB_SET_BULK_WB: %s\n", strerror(errno));
-      else
-       d_ra_wb_on = false;
-    }
-    else {
-      fd = ep_fd_from_usb_dev_handle (d_devhandle->get_usb_dev_handle(),
-                                     d_endpoint|USB_ENDPOINT_IN);
-      ret = ioctl (fd, USB_SET_BULK_RA, &enable);
-      if (ret < 0)
-       fprintf (stderr, "USB_SET_BULK_RA: %s\n", strerror(errno));
-      else
-       d_ra_wb_on = false;
-    }
-  }
-
-  d_started = false;
-  return true;
-}
-
-int
-fusb_ephandle_ra_wb::write (const void *buffer, int nbytes)
-{
-  if (!d_started)
-    return -1;
-  
-  if (d_input_p)
-    return -1;
-  
-  return usb_bulk_write (d_devhandle->get_usb_dev_handle (),
-                        d_endpoint, (char *) buffer, nbytes, USB_TIMEOUT);
-}
-
-int
-fusb_ephandle_ra_wb::read (void *buffer, int nbytes)
-{
-  if (!d_started)
-    return -1;
-
-  if (!d_input_p)
-    return -1;
-
-  return usb_bulk_read (d_devhandle->get_usb_dev_handle (),
-                       d_endpoint|USB_ENDPOINT_IN, (char *) buffer, nbytes,
-                       USB_TIMEOUT);
-}
-
-void
-fusb_ephandle_ra_wb::wait_for_completion ()
-{
-  // as the driver is implemented this only makes sense for write 
-  if (d_ra_wb_on && !d_input_p) {
-    int fd = ep_fd_from_usb_dev_handle (d_devhandle->get_usb_dev_handle(),
-                                       d_endpoint);
-    int kq = kqueue();
-    if (kq < 0)
-      return;
-    struct kevent evt;
-    int nevents;
-    EV_SET (&evt, fd, EVFILT_WRITE, EV_ADD | EV_ENABLE, 0, 0, 0/*NULL*/);
-    nevents = kevent (kq, &evt, 1, &evt, 1, NULL);
-    if (nevents < 1) {
-      close(kq);
-      return;
-    }
-    while (!(evt.flags & EV_ERROR) && evt.data < (d_block_size*d_nblocks)) {
-      // it's a busy loop, but that's all I can do at the moment
-      nevents = kevent (kq, NULL, 0, &evt, 1, NULL);
-      // let's see if this improves the test_usrp_standard_tx throughput &
-      // "CPU usage" by looping less frequently
-      struct timeval timeout;
-      timeout.tv_sec = 0;
-      timeout.tv_usec = 1000; // 1 ms
-      select (0, NULL, NULL, NULL, &timeout);
-    }
-    close (kq);
-  }
-}
diff --git a/usrp/host/lib/legacy/fusb_ra_wb.h b/usrp/host/lib/legacy/fusb_ra_wb.h
deleted file mode 100644 (file)
index 233976a..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003,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 _FUSB_RA_WB_H_
-#define _FUSB_RA_WB_H_
-
-#include <fusb.h>
-
-/*!
- * \brief generic implementation of fusb_devhandle using only libusb
- */
-class fusb_devhandle_ra_wb : public fusb_devhandle
-{
-public:
-  // CREATORS
-  fusb_devhandle_ra_wb (usb_dev_handle *udh);
-  virtual ~fusb_devhandle_ra_wb ();
-
-  // MANIPULATORS
-  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
-                                       int block_size = 0, int nblocks = 0);
-};
-
-
-/*!
- * \brief generic implementation of fusb_ephandle using only libusb
- */
-class fusb_ephandle_ra_wb : public fusb_ephandle
-{
-private:
-  fusb_devhandle_ra_wb *d_devhandle;
-  bool d_ra_wb_on;
-  
-public:
-  // CREATORS
-  fusb_ephandle_ra_wb (fusb_devhandle_ra_wb *dh, int endpoint, bool input_p,
-                      int block_size = 0, int nblocks = 0);
-  virtual ~fusb_ephandle_ra_wb ();
-
-  // MANIPULATORS
-
-  virtual bool start ();       //!< begin streaming i/o
-  virtual bool stop ();                //!< stop streaming i/o
-
-  /*!
-   * \returns \p nbytes if write was successfully enqueued, else -1.
-   * Will block if no free buffers available.
-   */
-  virtual int write (const void *buffer, int nbytes);
-
-  /*!
-   * \returns number of bytes read or -1 if error.
-   * number of bytes read will be <= nbytes.
-   * Will block if no input available.
-   */
-  virtual int read (void *buffer, int nbytes);
-
-  /*
-   * block until all outstanding writes have completed
-   */
-  virtual void wait_for_completion ();
-};
-
-#endif /* _FUSB_RA_WB_H_ */
-
diff --git a/usrp/host/lib/legacy/fusb_sysconfig_darwin.cc b/usrp/host/lib/legacy/fusb_sysconfig_darwin.cc
deleted file mode 100644 (file)
index 4d19d12..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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 <fusb.h>
-#include <fusb_darwin.h>
-
-static const int MAX_BLOCK_SIZE = 32 * 1024;           // hard limit
-static const int FUSB_BUFFER_SIZE = 2 * (1L << 20);    // 2 MB
-
-fusb_devhandle *
-fusb_sysconfig::make_devhandle (usb_dev_handle *udh)
-{
-  return new fusb_devhandle_darwin (udh);
-}
-
-int fusb_sysconfig::max_block_size ()
-{
-  return MAX_BLOCK_SIZE;
-}
-
-int fusb_sysconfig::default_block_size ()
-{
-  return fusb_sysconfig::max_block_size ();
-}
-
-int fusb_sysconfig::default_buffer_size ()
-{
-  return FUSB_BUFFER_SIZE;
-}
-
diff --git a/usrp/host/lib/legacy/fusb_sysconfig_generic.cc b/usrp/host/lib/legacy/fusb_sysconfig_generic.cc
deleted file mode 100644 (file)
index 58baba5..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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 <fusb.h>
-#include <fusb_generic.h>
-
-static const int MAX_BLOCK_SIZE = 16 * 1024;           // hard limit
-static const int FUSB_BUFFER_SIZE = 2 * (1L << 20);    // 2 MB
-
-fusb_devhandle *
-fusb_sysconfig::make_devhandle (usb_dev_handle *udh)
-{
-  return new fusb_devhandle_generic (udh);
-}
-       
-int fusb_sysconfig::max_block_size ()
-{
-  return MAX_BLOCK_SIZE;
-}
-
-int fusb_sysconfig::default_block_size ()
-{
-  return fusb_sysconfig::max_block_size ();
-}
-
-int fusb_sysconfig::default_buffer_size ()
-{
-  return FUSB_BUFFER_SIZE;
-}
diff --git a/usrp/host/lib/legacy/fusb_sysconfig_linux.cc b/usrp/host/lib/legacy/fusb_sysconfig_linux.cc
deleted file mode 100644 (file)
index 3c2f593..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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 <fusb.h>
-#include <fusb_linux.h>
-
-static const int MAX_BLOCK_SIZE     =  16 * 1024;      // hard limit
-static const int DEFAULT_BLOCK_SIZE =   4 * 1024;      // fewer kernel memory problems
-static const int FUSB_BUFFER_SIZE   =   1 * (1L << 20); // 1MB
-
-fusb_devhandle *
-fusb_sysconfig::make_devhandle (usb_dev_handle *udh)
-{
-  return new fusb_devhandle_linux (udh);
-}
-
-int fusb_sysconfig::max_block_size ()
-{
-  return MAX_BLOCK_SIZE;
-}
-
-int fusb_sysconfig::default_block_size ()
-{
-  return DEFAULT_BLOCK_SIZE;
-}
-
-int fusb_sysconfig::default_buffer_size ()
-{
-  return FUSB_BUFFER_SIZE;
-}
diff --git a/usrp/host/lib/legacy/fusb_sysconfig_ra_wb.cc b/usrp/host/lib/legacy/fusb_sysconfig_ra_wb.cc
deleted file mode 100644 (file)
index 9da831f..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003,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.
- */
-
-#include <fusb.h>
-#include <fusb_ra_wb.h>
-
-//static const int MAX_BLOCK_SIZE = 16 * 1024;         // hard limit
-// there's no hard limit, even before making any changes to the driver
-// 64k is empirically a pretty good number
-static const int MAX_BLOCK_SIZE = 64 * 1024;
-// there is a limit of 1 MB in the driver for the buffer size
-static const int FUSB_BUFFER_SIZE = 256 * (1L << 10);  // 256 kB
-
-fusb_devhandle *
-fusb_sysconfig::make_devhandle (usb_dev_handle *udh)
-{
-  return new fusb_devhandle_ra_wb (udh);
-}
-       
-int fusb_sysconfig::max_block_size ()
-{
-  return MAX_BLOCK_SIZE;
-}
-
-int fusb_sysconfig::default_block_size ()
-{
-  return fusb_sysconfig::max_block_size ();
-}
-
-int fusb_sysconfig::default_buffer_size ()
-{
-  return FUSB_BUFFER_SIZE;
-}
diff --git a/usrp/host/lib/legacy/fusb_sysconfig_win32.cc b/usrp/host/lib/legacy/fusb_sysconfig_win32.cc
deleted file mode 100644 (file)
index 16eaaa6..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003,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.
- */
-
-#include <fusb.h>
-#include <fusb_win32.h>
-
-static const int MAX_BLOCK_SIZE = 64 * 1024;           // Windows kernel hard limit
-static const int FUSB_BUFFER_SIZE = 2 * (1L << 20);    // 2 MB
-       
-fusb_devhandle *
-fusb_sysconfig::make_devhandle (usb_dev_handle *udh)
-{
-  return new fusb_devhandle_win32 (udh);
-}
-
-int fusb_sysconfig::max_block_size ()
-{
-  return MAX_BLOCK_SIZE;
-}
-
-int fusb_sysconfig::default_block_size ()
-{
-  return fusb_sysconfig::max_block_size ();
-}
-
-int fusb_sysconfig::default_buffer_size ()
-{
-  return FUSB_BUFFER_SIZE;
-}
diff --git a/usrp/host/lib/legacy/fusb_win32.cc b/usrp/host/lib/legacy/fusb_win32.cc
deleted file mode 100644 (file)
index 8900576..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003,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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <fusb_win32.h>
-#include <usb.h>
-#include <assert.h>
-#include <stdexcept>
-#include <string.h>
-
-static const int MAX_BLOCK_SIZE = fusb_sysconfig::max_block_size();
-static const int DEFAULT_BLOCK_SIZE = MAX_BLOCK_SIZE;
-static const int DEFAULT_BUFFER_SIZE = 16 * (1L << 20);                // 16 MB / endpoint
-
-
-static const int USB_TIMEOUT = 1000;   // in milliseconds
-
-
-fusb_devhandle_win32::fusb_devhandle_win32 (usb_dev_handle *udh)
-  : fusb_devhandle (udh)
-{
-  // that's it
-}
-
-fusb_devhandle_win32::~fusb_devhandle_win32 ()
-{
-  // nop
-}
-
-fusb_ephandle *
-fusb_devhandle_win32::make_ephandle (int endpoint, bool input_p,
-                                      int block_size, int nblocks)
-{
-  return new fusb_ephandle_win32 (this, endpoint, input_p,
-                                   block_size, nblocks);
-}
-
-// ----------------------------------------------------------------
-
-fusb_ephandle_win32::fusb_ephandle_win32 (fusb_devhandle_win32 *dh,
-                                             int endpoint, bool input_p,
-                                             int block_size, int nblocks)
-  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
-    d_devhandle (dh), d_input_leftover(0),d_output_short(0)
-{
-  if (d_block_size < 0 || d_block_size > MAX_BLOCK_SIZE)
-    throw std::out_of_range ("fusb_ephandle_win32: block_size");
-
-  if (d_nblocks < 0)
-    throw std::out_of_range ("fusb_ephandle_win32: nblocks");
-
-  if (d_block_size == 0)
-    d_block_size = DEFAULT_BLOCK_SIZE;
-
-  if (d_nblocks == 0)
-    d_nblocks = std::max (1, DEFAULT_BUFFER_SIZE / d_block_size);
-
-  d_buffer = new char [d_block_size*d_nblocks];
-  d_context = new void * [d_nblocks];
-
-  // allocate contexts
-
-  usb_dev_handle *dev = dh->get_usb_dev_handle ();
-  int i;
-
-  if (d_input_p)
-    endpoint |= USB_ENDPOINT_IN;
-
-  for (i=0; i<d_nblocks; i++)
-    usb_bulk_setup_async(dev, &d_context[i], endpoint);
-}
-
-fusb_ephandle_win32::~fusb_ephandle_win32 ()
-{
-  int i;
-
-  stop ();
-
-  for (i=0; i<d_nblocks; i++)
-    usb_free_async(&d_context[i]);
-
-  delete [] d_buffer;
-  delete [] d_context;
-}
-
-bool
-fusb_ephandle_win32::start ()
-{
-  if (d_started)
-    return true;       // already running
-
-  d_started = true;
-
-  d_curr = d_nblocks-1;
-  d_outstanding_write = 0;
-  d_input_leftover =0;
-  d_output_short = 0;
-
-  if (d_input_p){      // fire off all the reads
-    int i;
-
-    for (i=0; i<d_nblocks; i++) {
-      usb_submit_async(d_context[i], (char * ) d_buffer+i*d_block_size,
-                     d_block_size);
-    }
-  }
-
-  return true;
-}
-
-bool
-fusb_ephandle_win32::stop ()
-{
-  if (!d_started)
-    return true;
-
-  if (!d_input_p)
-    wait_for_completion ();
-
-  d_started = false;
-  return true;
-}
-
-int
-fusb_ephandle_win32::write (const void *buffer, int nbytes)
-{
-  int retval=0;
-  char *buf;
-
-  if (!d_started)      // doesn't matter here, but keeps semantics constant
-    return -1;
-
-  if (d_input_p)
-    return -1;
-
-  int bytes_to_write = nbytes;
-  int a=0;
-
-  if (d_output_short != 0) {
-
-       buf = &d_buffer[d_curr*d_block_size + d_block_size - d_output_short];
-       a = std::min(nbytes, d_output_short);
-       memcpy(buf, buffer, a);
-       bytes_to_write -= a;
-       d_output_short -= a;
-
-    if (d_output_short == 0)
-        usb_submit_async(d_context[d_curr],
-                        &d_buffer[d_curr*d_block_size], d_block_size);
-  }
-
-  while (bytes_to_write > 0) {
-    d_curr = (d_curr+1)%d_nblocks;
-    buf = &d_buffer[d_curr*d_block_size];
-
-    if (d_outstanding_write != d_nblocks) {
-      d_outstanding_write++;
-    } else {
-      retval = usb_reap_async(d_context[d_curr], USB_TIMEOUT);
-      if (retval < 0) {
-                 fprintf(stderr, "%s: usb_reap_async: %s\n",
-                         __FUNCTION__, usb_strerror());
-         return retval;
-       }
-    }
-
-    int ncopy = std::min(bytes_to_write, d_block_size);
-    memcpy(buf, (void *) &(((char*)buffer)[a]), ncopy);
-    bytes_to_write -= ncopy;
-    a += ncopy;
-
-    d_output_short = d_block_size - ncopy;
-    if (d_output_short == 0)
-           usb_submit_async(d_context[d_curr], buf, d_block_size);
-  }
-
-  return retval < 0 ? retval : nbytes;
-}
-
-int
-fusb_ephandle_win32::read (void *buffer, int nbytes)
-{
-  int retval=0;
-  char *buf;
-
-  if (!d_started)      // doesn't matter here, but keeps semantics constant
-    return -1;
-
-  if (!d_input_p)
-    return -1;
-
-  int bytes_to_read = nbytes;
-
-  int a=0;
-  if (d_input_leftover != 0) {
-
-       buf = &d_buffer[d_curr*d_block_size + d_block_size - d_input_leftover];
-       a = std::min(nbytes, d_input_leftover);
-       memcpy(buffer, buf, a);
-       bytes_to_read -= a;
-       d_input_leftover -= a;
-
-    if (d_input_leftover == 0)
-        usb_submit_async(d_context[d_curr],
-                        &d_buffer[d_curr*d_block_size], d_block_size);
-  }
-
-  while (bytes_to_read > 0) {
-
-    d_curr = (d_curr+1)%d_nblocks;
-    buf = &d_buffer[d_curr*d_block_size];
-
-    retval = usb_reap_async(d_context[d_curr], USB_TIMEOUT);
-    if (retval < 0)
-         fprintf(stderr, "%s: usb_reap_async: %s\n",
-                         __FUNCTION__, usb_strerror());
-
-    int ncopy = std::min(bytes_to_read, d_block_size);
-    memcpy((void *) &(((char*)buffer)[a]), buf, ncopy);
-    bytes_to_read -= ncopy;
-    a += ncopy;
-
-    d_input_leftover = d_block_size - ncopy;
-    if (d_input_leftover == 0)
-           usb_submit_async(d_context[d_curr], buf, d_block_size);
-  }
-
-  return retval < 0 ? retval : nbytes;
-}
-
-void
-fusb_ephandle_win32::wait_for_completion ()
-{
-  int i;
-
-  for (i=0; i<d_outstanding_write; i++) {
-    int context_num;
-
-    context_num = (d_curr+d_outstanding_write+i+1)%d_nblocks;
-    usb_reap_async(d_context[context_num], USB_TIMEOUT);
-  }
-
-  d_outstanding_write = 0;
-}
diff --git a/usrp/host/lib/legacy/fusb_win32.h b/usrp/host/lib/legacy/fusb_win32.h
deleted file mode 100644 (file)
index 3ad2132..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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 _FUSB_WIN32_H_
-#define _FUSB_WIN32_H_
-
-#include <fusb.h>
-
-/*!
- * \brief win32 implementation of fusb_devhandle using libusb-win32
- */
-class fusb_devhandle_win32 : public fusb_devhandle
-{
-public:
-  // CREATORS
-  fusb_devhandle_win32 (usb_dev_handle *udh);
-  virtual ~fusb_devhandle_win32 ();
-
-  // MANIPULATORS
-  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
-                                       int block_size = 0, int nblocks = 0);
-};
-
-
-/*!
- * \brief win32 implementation of fusb_ephandle using libusb-win32
- */
-class fusb_ephandle_win32 : public fusb_ephandle
-{
-private:
-  fusb_devhandle_win32 *d_devhandle;
-
-  unsigned d_curr;
-  unsigned d_outstanding_write;
-  int d_output_short;
-  int d_input_leftover;
-  void ** d_context;
-  char * d_buffer;
-
-public:
-  // CREATORS
-  fusb_ephandle_win32 (fusb_devhandle_win32 *dh, int endpoint, bool input_p,
-                        int block_size = 0, int nblocks = 0);
-  virtual ~fusb_ephandle_win32 ();
-
-  // MANIPULATORS
-
-  virtual bool start ();       //!< begin streaming i/o
-  virtual bool stop ();                //!< stop streaming i/o
-
-  /*!
-   * \returns \p nbytes if write was successfully enqueued, else -1.
-   * Will block if no free buffers available.
-   */
-  virtual int write (const void *buffer, int nbytes);
-
-  /*!
-   * \returns number of bytes read or -1 if error.
-   * number of bytes read will be <= nbytes.
-   * Will block if no input available.
-   */
-  virtual int read (void *buffer, int nbytes);
-
-  /*
-   * block until all outstanding writes have completed
-   */
-  virtual void wait_for_completion ();
-};
-
-#endif /* _FUSB_WIN32_H_ */
-
diff --git a/usrp/host/lib/legacy/gen_usrp_dbid.py b/usrp/host/lib/legacy/gen_usrp_dbid.py
deleted file mode 100755 (executable)
index bbfdc75..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-import os
-import os.path
-import re
-from optparse import OptionParser
-
-def write_header(f, comment_char):
-    f.write(comment_char); f.write('\n')
-    f.write(comment_char); f.write(' Machine generated by gen_usrp_dbid.py from usrp_dbid.dat\n')
-    f.write(comment_char); f.write(' Do not edit by hand.  All edits will be overwritten.\n')
-    f.write(comment_char); f.write('\n')
-    f.write('\n')
-
-def gen_dbid_py(r):
-    f = open('usrp_dbid.py', 'w')
-    comment_char = '#'
-    write_header(f, comment_char)
-    f.write(comment_char); f.write('\n')
-    f.write(comment_char); f.write(" USRP Daughterboard ID's\n")
-    f.write(comment_char); f.write('\n')
-    f.write('\n')
-    for x in r:
-        f.write('%-16s = %s\n' % (x[1], x[2]))
-
-def gen_dbid_h(r):
-    f = open('usrp_dbid.h', 'w')
-    comment_char = '//'
-    write_header(f, comment_char)
-    f.write(comment_char); f.write('\n')
-    f.write(comment_char); f.write(" USRP Daughterboard ID's\n")
-    f.write(comment_char); f.write('\n')
-    f.write('\n')
-    f.write('#ifndef INCLUDED_USRP_DBID_H\n')
-    f.write('#define INCLUDED_USRP_DBID_H\n')
-    f.write('\n')
-    for x in r:
-        f.write('#define %-25s %s\n' % ('USRP_DBID_' + x[1], x[2]))
-    f.write('\n')
-    f.write('#endif /* INCLUDED_USRP_DBID_H */\n')
-
-def gen_dbid_cc(r):
-    f = open('usrp_dbid.cc', 'w')
-    write_header(f, '//')
-    head = '''/*
- * 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.
- */
-
-#include <usrp_prims.h>
-#include <usrp_dbid.h>
-#include <stdio.h>
-
-#define NELEM(x) sizeof(x)/sizeof(x[0])
-
-static struct {
-  unsigned short       dbid;
-  const char          *name;
-} dbid_map[] = {
-'''
-    
-    tail = '''};
-
-const std::string
-usrp_dbid_to_string (int dbid)
-{
-  if (dbid == -1)
-    return "<none>";
-
-  if (dbid == -2)
-    return "<invalid EEPROM contents>";
-
-  for (unsigned i = 0; i < NELEM (dbid_map); i++)
-    if (dbid == dbid_map[i].dbid)
-      return dbid_map[i].name;
-
-  char tmp[64];
-  snprintf (tmp, sizeof (tmp), "Unknown (0x%04x)", dbid);
-  return tmp;
-}
-'''
-    f.write(head)
-    for x in r:
-        f.write('  { %-27s "%s" },\n' % (
-            'USRP_DBID_' + x[1] + ',', x[0]))
-    f.write(tail)
-
-def gen_all(src_filename):
-    src_file = open(src_filename, 'r')
-    r = []
-    for line in src_file:
-        line = line.strip()
-        line = re.sub(r'\s*#.*$','', line)
-        if len(line) == 0:
-            continue
-        mo = re.match('"([^"]+)"\s*(0x[0-9a-fA-F]+)', line)
-        if mo:
-            str_name = mo.group(1)
-            id_name = str_name.upper().replace(' ', '_')
-            id_val = mo.group(2)
-            r.append((str_name, id_name, id_val))
-            #sys.stdout.write('%-16s\t%-16s\t%s\n' % ('"'+str_name+'"', id_name, id_val))
-
-    gen_dbid_h(r)
-    gen_dbid_py(r)
-    gen_dbid_cc(r)
-    
-
-def main():
-    usage = "usage: %prog [options] usrp_dbid.dat"
-    parser = OptionParser(usage=usage)
-    (options, args) = parser.parse_args()
-    if len(args) != 1:
-        parser.print_help()
-        sys.exit(1)
-
-    gen_all(args[0])
-
-if __name__ == '__main__':
-    main()
diff --git a/usrp/host/lib/legacy/md5.c b/usrp/host/lib/legacy/md5.c
deleted file mode 100644 (file)
index b15ab39..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-/* md5.c - Functions to compute MD5 message digest of files or memory blocks
-   according to the definition of MD5 in RFC 1321 from April 1992.
-   Copyright (C) 1995, 1996, 2001, 2003 Free Software Foundation, Inc.
-   NOTE: The canonical source of this file is maintained with the GNU C
-   Library.  Bugs can be reported to bug-glibc@prep.ai.mit.edu.
-
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 3, or (at your option) any
-   later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 51 Franklin Street, Boston, MA 02110-1301, USA.  */
-
-/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "md5.h"
-
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-// #include "unlocked-io.h"
-
-#ifdef _LIBC
-# include <endian.h>
-# if __BYTE_ORDER == __BIG_ENDIAN
-#  define WORDS_BIGENDIAN 1
-# endif
-/* We need to keep the namespace clean so define the MD5 function
-   protected using leading __ .  */
-# define md5_init_ctx __md5_init_ctx
-# define md5_process_block __md5_process_block
-# define md5_process_bytes __md5_process_bytes
-# define md5_finish_ctx __md5_finish_ctx
-# define md5_read_ctx __md5_read_ctx
-# define md5_stream __md5_stream
-# define md5_buffer __md5_buffer
-#endif
-
-#ifdef WORDS_BIGENDIAN
-# define SWAP(n)                                                       \
-    (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
-#else
-# define SWAP(n) (n)
-#endif
-
-#define BLOCKSIZE 4096
-/* Ensure that BLOCKSIZE is a multiple of 64.  */
-#if BLOCKSIZE % 64 != 0
-/* FIXME-someday (soon?): use #error instead of this kludge.  */
-"invalid BLOCKSIZE"
-#endif
-
-/* This array contains the bytes used to pad the buffer to the next
-   64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
-static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
-
-
-/* Initialize structure containing state of computation.
-   (RFC 1321, 3.3: Step 3)  */
-void
-md5_init_ctx (struct md5_ctx *ctx)
-{
-  ctx->A = 0x67452301;
-  ctx->B = 0xefcdab89;
-  ctx->C = 0x98badcfe;
-  ctx->D = 0x10325476;
-
-  ctx->total[0] = ctx->total[1] = 0;
-  ctx->buflen = 0;
-}
-
-/* Put result from CTX in first 16 bytes following RESBUF.  The result
-   must be in little endian byte order.
-
-   IMPORTANT: On some systems it is required that RESBUF is correctly
-   aligned for a 32 bits value.  */
-void *
-md5_read_ctx (const struct md5_ctx *ctx, void *resbuf)
-{
-  ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
-  ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
-  ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
-  ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
-
-  return resbuf;
-}
-
-/* Process the remaining bytes in the internal buffer and the usual
-   prolog according to the standard and write the result to RESBUF.
-
-   IMPORTANT: On some systems it is required that RESBUF is correctly
-   aligned for a 32 bits value.  */
-void *
-md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
-{
-  /* Take yet unprocessed bytes into account.  */
-  md5_uint32 bytes = ctx->buflen;
-  size_t pad;
-
-  /* Now count remaining bytes.  */
-  ctx->total[0] += bytes;
-  if (ctx->total[0] < bytes)
-    ++ctx->total[1];
-
-  pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
-  memcpy (&ctx->buffer[bytes], fillbuf, pad);
-
-  /* Put the 64-bit file length in *bits* at the end of the buffer.  */
-  *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
-  *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
-                                                       (ctx->total[0] >> 29));
-
-  /* Process last bytes.  */
-  md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
-
-  return md5_read_ctx (ctx, resbuf);
-}
-
-/* Compute MD5 message digest for bytes read from STREAM.  The
-   resulting message digest number will be written into the 16 bytes
-   beginning at RESBLOCK.  */
-int
-md5_stream (FILE *stream, void *resblock)
-{
-  struct md5_ctx ctx;
-  char buffer[BLOCKSIZE + 72];
-  size_t sum;
-
-  /* Initialize the computation context.  */
-  md5_init_ctx (&ctx);
-
-  /* Iterate over full file contents.  */
-  while (1)
-    {
-      /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
-        computation function processes the whole buffer so that with the
-        next round of the loop another block can be read.  */
-      size_t n;
-      sum = 0;
-
-      /* Read block.  Take care for partial reads.  */
-      while (1)
-       {
-         n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
-
-         sum += n;
-
-         if (sum == BLOCKSIZE)
-           break;
-
-         if (n == 0)
-           {
-             /* Check for the error flag IFF N == 0, so that we don't
-                exit the loop after a partial read due to e.g., EAGAIN
-                or EWOULDBLOCK.  */
-             if (ferror (stream))
-               return 1;
-             goto process_partial_block;
-           }
-
-         /* We've read at least one byte, so ignore errors.  But always
-            check for EOF, since feof may be true even though N > 0.
-            Otherwise, we could end up calling fread after EOF.  */
-         if (feof (stream))
-           goto process_partial_block;
-       }
-
-      /* Process buffer with BLOCKSIZE bytes.  Note that
-                       BLOCKSIZE % 64 == 0
-       */
-      md5_process_block (buffer, BLOCKSIZE, &ctx);
-    }
-
- process_partial_block:;
-
-  /* Process any remaining bytes.  */
-  if (sum > 0)
-    md5_process_bytes (buffer, sum, &ctx);
-
-  /* Construct result in desired memory.  */
-  md5_finish_ctx (&ctx, resblock);
-  return 0;
-}
-
-/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
-   result is always in little endian byte order, so that a byte-wise
-   output yields to the wanted ASCII representation of the message
-   digest.  */
-void *
-md5_buffer (const char *buffer, size_t len, void *resblock)
-{
-  struct md5_ctx ctx;
-
-  /* Initialize the computation context.  */
-  md5_init_ctx (&ctx);
-
-  /* Process whole buffer but last len % 64 bytes.  */
-  md5_process_bytes (buffer, len, &ctx);
-
-  /* Put result in desired memory area.  */
-  return md5_finish_ctx (&ctx, resblock);
-}
-
-
-void
-md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
-{
-  /* When we already have some bits in our internal buffer concatenate
-     both inputs first.  */
-  if (ctx->buflen != 0)
-    {
-      size_t left_over = ctx->buflen;
-      size_t add = 128 - left_over > len ? len : 128 - left_over;
-
-      memcpy (&ctx->buffer[left_over], buffer, add);
-      ctx->buflen += add;
-
-      if (ctx->buflen > 64)
-       {
-         md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
-
-         ctx->buflen &= 63;
-         /* The regions in the following copy operation cannot overlap.  */
-         memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
-                 ctx->buflen);
-       }
-
-      buffer = (const char *) buffer + add;
-      len -= add;
-    }
-
-  /* Process available complete blocks.  */
-  if (len >= 64)
-    {
-#if !_STRING_ARCH_unaligned
-/* To check alignment gcc has an appropriate operator.  Other
-   compilers don't.  */
-# if __GNUC__ >= 2
-#  define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0)
-# else
-#  define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0)
-# endif
-      if (UNALIGNED_P (buffer))
-       while (len > 64)
-         {
-           md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
-           buffer = (const char *) buffer + 64;
-           len -= 64;
-         }
-      else
-#endif
-       {
-         md5_process_block (buffer, len & ~63, ctx);
-         buffer = (const char *) buffer + (len & ~63);
-         len &= 63;
-       }
-    }
-
-  /* Move remaining bytes in internal buffer.  */
-  if (len > 0)
-    {
-      size_t left_over = ctx->buflen;
-
-      memcpy (&ctx->buffer[left_over], buffer, len);
-      left_over += len;
-      if (left_over >= 64)
-       {
-         md5_process_block (ctx->buffer, 64, ctx);
-         left_over -= 64;
-         memcpy (ctx->buffer, &ctx->buffer[64], left_over);
-       }
-      ctx->buflen = left_over;
-    }
-}
-
-
-/* These are the four functions used in the four steps of the MD5 algorithm
-   and defined in the RFC 1321.  The first function is a little bit optimized
-   (as found in Colin Plumbs public domain implementation).  */
-/* #define FF(b, c, d) ((b & c) | (~b & d)) */
-#define FF(b, c, d) (d ^ (b & (c ^ d)))
-#define FG(b, c, d) FF (d, b, c)
-#define FH(b, c, d) (b ^ c ^ d)
-#define FI(b, c, d) (c ^ (b | ~d))
-
-/* Process LEN bytes of BUFFER, accumulating context into CTX.
-   It is assumed that LEN % 64 == 0.  */
-
-void
-md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
-{
-  md5_uint32 correct_words[16];
-  const md5_uint32 *words = buffer;
-  size_t nwords = len / sizeof (md5_uint32);
-  const md5_uint32 *endp = words + nwords;
-  md5_uint32 A = ctx->A;
-  md5_uint32 B = ctx->B;
-  md5_uint32 C = ctx->C;
-  md5_uint32 D = ctx->D;
-
-  /* First increment the byte count.  RFC 1321 specifies the possible
-     length of the file up to 2^64 bits.  Here we only compute the
-     number of bytes.  Do a double word increment.  */
-  ctx->total[0] += len;
-  if (ctx->total[0] < len)
-    ++ctx->total[1];
-
-  /* Process all bytes in the buffer with 64 bytes in each round of
-     the loop.  */
-  while (words < endp)
-    {
-      md5_uint32 *cwp = correct_words;
-      md5_uint32 A_save = A;
-      md5_uint32 B_save = B;
-      md5_uint32 C_save = C;
-      md5_uint32 D_save = D;
-
-      /* First round: using the given function, the context and a constant
-        the next context is computed.  Because the algorithms processing
-        unit is a 32-bit word and it is determined to work on words in
-        little endian byte order we perhaps have to change the byte order
-        before the computation.  To reduce the work for the next steps
-        we store the swapped words in the array CORRECT_WORDS.  */
-
-#define OP(a, b, c, d, s, T)                                           \
-      do                                                               \
-        {                                                              \
-         a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;             \
-         ++words;                                                      \
-         a = rol (a, s);                                               \
-         a += b;                                                       \
-        }                                                              \
-      while (0)
-
-      /* Before we start, one word to the strange constants.
-        They are defined in RFC 1321 as
-
-        T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64, or
-        perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}'
-       */
-
-      /* Round 1.  */
-      OP (A, B, C, D,  7, 0xd76aa478);
-      OP (D, A, B, C, 12, 0xe8c7b756);
-      OP (C, D, A, B, 17, 0x242070db);
-      OP (B, C, D, A, 22, 0xc1bdceee);
-      OP (A, B, C, D,  7, 0xf57c0faf);
-      OP (D, A, B, C, 12, 0x4787c62a);
-      OP (C, D, A, B, 17, 0xa8304613);
-      OP (B, C, D, A, 22, 0xfd469501);
-      OP (A, B, C, D,  7, 0x698098d8);
-      OP (D, A, B, C, 12, 0x8b44f7af);
-      OP (C, D, A, B, 17, 0xffff5bb1);
-      OP (B, C, D, A, 22, 0x895cd7be);
-      OP (A, B, C, D,  7, 0x6b901122);
-      OP (D, A, B, C, 12, 0xfd987193);
-      OP (C, D, A, B, 17, 0xa679438e);
-      OP (B, C, D, A, 22, 0x49b40821);
-
-      /* For the second to fourth round we have the possibly swapped words
-        in CORRECT_WORDS.  Redefine the macro to take an additional first
-        argument specifying the function to use.  */
-#undef OP
-#define OP(f, a, b, c, d, k, s, T)                                     \
-      do                                                               \
-       {                                                               \
-         a += f (b, c, d) + correct_words[k] + T;                      \
-         a = rol (a, s);                                               \
-         a += b;                                                       \
-       }                                                               \
-      while (0)
-
-      /* Round 2.  */
-      OP (FG, A, B, C, D,  1,  5, 0xf61e2562);
-      OP (FG, D, A, B, C,  6,  9, 0xc040b340);
-      OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
-      OP (FG, B, C, D, A,  0, 20, 0xe9b6c7aa);
-      OP (FG, A, B, C, D,  5,  5, 0xd62f105d);
-      OP (FG, D, A, B, C, 10,  9, 0x02441453);
-      OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
-      OP (FG, B, C, D, A,  4, 20, 0xe7d3fbc8);
-      OP (FG, A, B, C, D,  9,  5, 0x21e1cde6);
-      OP (FG, D, A, B, C, 14,  9, 0xc33707d6);
-      OP (FG, C, D, A, B,  3, 14, 0xf4d50d87);
-      OP (FG, B, C, D, A,  8, 20, 0x455a14ed);
-      OP (FG, A, B, C, D, 13,  5, 0xa9e3e905);
-      OP (FG, D, A, B, C,  2,  9, 0xfcefa3f8);
-      OP (FG, C, D, A, B,  7, 14, 0x676f02d9);
-      OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
-
-      /* Round 3.  */
-      OP (FH, A, B, C, D,  5,  4, 0xfffa3942);
-      OP (FH, D, A, B, C,  8, 11, 0x8771f681);
-      OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
-      OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
-      OP (FH, A, B, C, D,  1,  4, 0xa4beea44);
-      OP (FH, D, A, B, C,  4, 11, 0x4bdecfa9);
-      OP (FH, C, D, A, B,  7, 16, 0xf6bb4b60);
-      OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
-      OP (FH, A, B, C, D, 13,  4, 0x289b7ec6);
-      OP (FH, D, A, B, C,  0, 11, 0xeaa127fa);
-      OP (FH, C, D, A, B,  3, 16, 0xd4ef3085);
-      OP (FH, B, C, D, A,  6, 23, 0x04881d05);
-      OP (FH, A, B, C, D,  9,  4, 0xd9d4d039);
-      OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
-      OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
-      OP (FH, B, C, D, A,  2, 23, 0xc4ac5665);
-
-      /* Round 4.  */
-      OP (FI, A, B, C, D,  0,  6, 0xf4292244);
-      OP (FI, D, A, B, C,  7, 10, 0x432aff97);
-      OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
-      OP (FI, B, C, D, A,  5, 21, 0xfc93a039);
-      OP (FI, A, B, C, D, 12,  6, 0x655b59c3);
-      OP (FI, D, A, B, C,  3, 10, 0x8f0ccc92);
-      OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
-      OP (FI, B, C, D, A,  1, 21, 0x85845dd1);
-      OP (FI, A, B, C, D,  8,  6, 0x6fa87e4f);
-      OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
-      OP (FI, C, D, A, B,  6, 15, 0xa3014314);
-      OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
-      OP (FI, A, B, C, D,  4,  6, 0xf7537e82);
-      OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
-      OP (FI, C, D, A, B,  2, 15, 0x2ad7d2bb);
-      OP (FI, B, C, D, A,  9, 21, 0xeb86d391);
-
-      /* Add the starting values of the context.  */
-      A += A_save;
-      B += B_save;
-      C += C_save;
-      D += D_save;
-    }
-
-  /* Put checksum in context given as argument.  */
-  ctx->A = A;
-  ctx->B = B;
-  ctx->C = C;
-  ctx->D = D;
-}
diff --git a/usrp/host/lib/legacy/md5.h b/usrp/host/lib/legacy/md5.h
deleted file mode 100644 (file)
index 4a4e790..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/* md5.h - Declaration of functions and data types used for MD5 sum
-   computing library functions.
-   Copyright (C) 1995, 1996, 1999, 2000, 2003 Free Software Foundation, Inc.
-   NOTE: The canonical source of this file is maintained with the GNU C
-   Library.  Bugs can be reported to bug-glibc@prep.ai.mit.edu.
-
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 3, or (at your option) any
-   later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 51 Franklin Street, Boston, MA 02110-1301, USA.  */
-
-#ifndef _MD5_H
-#define _MD5_H 1
-
-#include <stdio.h>
-#include <limits.h>
-
-/* The following contortions are an attempt to use the C preprocessor
-   to determine an unsigned integral type that is 32 bits wide.  An
-   alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
-   doing that would require that the configure script compile and *run*
-   the resulting executable.  Locally running cross-compiled executables
-   is usually not possible.  */
-
-#ifdef _LIBC
-# include <stdint.h>
-typedef uint32_t md5_uint32;
-typedef uintptr_t md5_uintptr;
-#else
-# define UINT_MAX_32_BITS 4294967295U
-
-# if UINT_MAX == UINT_MAX_32_BITS
-   typedef unsigned int md5_uint32;
-# else
-#  if USHRT_MAX == UINT_MAX_32_BITS
-    typedef unsigned short md5_uint32;
-#  else
-#   if ULONG_MAX == UINT_MAX_32_BITS
-     typedef unsigned long md5_uint32;
-#   else
-     /* The following line is intended to evoke an error.
-        Using #error is not portable enough.  */
-     "Cannot determine unsigned 32-bit data type."
-#   endif
-#  endif
-# endif
-/* We have to make a guess about the integer type equivalent in size
-   to pointers which should always be correct.  */
-typedef unsigned long int md5_uintptr;
-#endif
-
-/* Structure to save state of computation between the single steps.  */
-struct md5_ctx
-{
-  md5_uint32 A;
-  md5_uint32 B;
-  md5_uint32 C;
-  md5_uint32 D;
-
-  md5_uint32 total[2];
-  md5_uint32 buflen;
-  char buffer[128];
-};
-
-/*
- * The following three functions are build up the low level used in
- * the functions `md5_stream' and `md5_buffer'.
- */
-
-/* Initialize structure containing state of computation.
-   (RFC 1321, 3.3: Step 3)  */
-extern void md5_init_ctx (struct md5_ctx *ctx);
-
-/* Starting with the result of former calls of this function (or the
-   initialization function update the context for the next LEN bytes
-   starting at BUFFER.
-   It is necessary that LEN is a multiple of 64!!! */
-extern void md5_process_block (const void *buffer, size_t len,
-                              struct md5_ctx *ctx);
-
-/* Starting with the result of former calls of this function (or the
-   initialization function update the context for the next LEN bytes
-   starting at BUFFER.
-   It is NOT required that LEN is a multiple of 64.  */
-extern void md5_process_bytes (const void *buffer, size_t len,
-                              struct md5_ctx *ctx);
-
-/* Process the remaining bytes in the buffer and put result from CTX
-   in first 16 bytes following RESBUF.  The result is always in little
-   endian byte order, so that a byte-wise output yields to the wanted
-   ASCII representation of the message digest.
-
-   IMPORTANT: On some systems it is required that RESBUF be correctly
-   aligned for a 32 bits value.  */
-extern void *md5_finish_ctx (struct md5_ctx *ctx, void *resbuf);
-
-
-/* Put result from CTX in first 16 bytes following RESBUF.  The result is
-   always in little endian byte order, so that a byte-wise output yields
-   to the wanted ASCII representation of the message digest.
-
-   IMPORTANT: On some systems it is required that RESBUF is correctly
-   aligned for a 32 bits value.  */
-extern void *md5_read_ctx (const struct md5_ctx *ctx, void *resbuf);
-
-
-/* Compute MD5 message digest for bytes read from STREAM.  The
-   resulting message digest number will be written into the 16 bytes
-   beginning at RESBLOCK.  */
-extern int md5_stream (FILE *stream, void *resblock);
-
-/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
-   result is always in little endian byte order, so that a byte-wise
-   output yields to the wanted ASCII representation of the message
-   digest.  */
-extern void *md5_buffer (const char *buffer, size_t len, void *resblock);
-
-#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
-
-#endif
diff --git a/usrp/host/lib/legacy/mld_threads.h b/usrp/host/lib/legacy/mld_threads.h
deleted file mode 100644 (file)
index 322f557..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio.
- *
- * Primary Author: Michael Dickens, NCIP Lab, University of Notre Dame
- * 
- * 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_MLD_THREADS_H_
-#define _INCLUDED_MLD_THREADS_H_
-
-/* classes which allow for either pthreads or omni_threads */
-
-#define __macos__
-#ifdef _USE_OMNI_THREADS_
-#include <gnuradio/omnithread.h>
-#else
-#include <pthread.h>
-#endif
-
-#include <stdexcept>
-
-#define __INLINE__ inline
-
-#ifndef DO_DEBUG
-#define DO_DEBUG 0
-#endif
-
-#if DO_DEBUG
-#define DEBUG(X) do{X} while(0);
-#else
-#define DEBUG(X) do{} while(0);
-#endif
-
-class mld_condition_t;
-
-class mld_mutex_t {
-#ifdef _USE_OMNI_THREADS_
-  typedef omni_mutex l_mutex, *l_mutex_ptr;
-#else
-  typedef pthread_mutex_t l_mutex, *l_mutex_ptr;
-#endif
-
-  friend class mld_condition_t;
-
-private:
-  l_mutex_ptr d_mutex;
-
-protected:
-  inline l_mutex_ptr mutex () { return (d_mutex); };
-
-public:
-  __INLINE__ mld_mutex_t () {
-#ifdef _USE_OMNI_THREADS_
-    d_mutex = new omni_mutex ();
-#else
-    d_mutex = (l_mutex_ptr) new l_mutex;
-    int l_ret = pthread_mutex_init (d_mutex, NULL);
-    if (l_ret != 0) {
-      fprintf (stderr, "Error %d creating mutex.\n", l_ret);
-      throw std::runtime_error ("mld_mutex_t::mld_mutex_t()\n");
-    }
-#endif
-  };
-
-  __INLINE__ ~mld_mutex_t () {
-    unlock ();
-#ifndef _USE_OMNI_THREADS_
-    int l_ret = pthread_mutex_destroy (d_mutex);
-    if (l_ret != 0) {
-      fprintf (stderr, "mld_mutex_t::~mld_mutex_t(): "
-              "Error %d destroying mutex.\n", l_ret);
-    }
-#endif
-    delete d_mutex;
-    d_mutex = NULL;
-  };
-
-  __INLINE__ void lock () {
-#ifdef _USE_OMNI_THREADS_
-    d_mutex->lock ();
-#else
-    int l_ret = pthread_mutex_lock (d_mutex);
-    if (l_ret != 0) {
-      fprintf (stderr, "mld_mutex_t::lock(): "
-              "Error %d locking mutex.\n", l_ret);
-    }
-#endif
-  };
-
-  __INLINE__ void unlock () {
-#ifdef _USE_OMNI_THREADS_
-    d_mutex->unlock ();
-#else
-    int l_ret = pthread_mutex_unlock (d_mutex);
-    if (l_ret != 0) {
-      fprintf (stderr, "mld_mutex_t::unlock(): "
-              "Error %d locking mutex.\n", l_ret);
-    }
-#endif
-  };
-
-  __INLINE__ bool trylock () {
-#ifdef _USE_OMNI_THREADS_
-    int l_ret = d_mutex->trylock ();
-#else
-    int l_ret = pthread_mutex_unlock (d_mutex);
-#endif
-    return (l_ret == 0 ? true : false);
-  };
-
-  inline void acquire () { lock(); };
-  inline void release () { unlock(); };
-  inline void wait () { lock(); };
-  inline void post () { unlock(); };
-};
-
-typedef mld_mutex_t mld_mutex, *mld_mutex_ptr;
-
-class mld_condition_t {
-#ifdef _USE_OMNI_THREADS_
-  typedef omni_condition l_condition, *l_condition_ptr;
-#else
-  typedef pthread_cond_t l_condition, *l_condition_ptr;
-#endif
-
-private:
-  l_condition_ptr d_condition;
-  mld_mutex_ptr d_mutex;
-  bool d_i_own_mutex;
-
-public:
-  __INLINE__ mld_condition_t (mld_mutex_ptr mutex = NULL) {
-    if (mutex) {
-      d_i_own_mutex = false;
-      d_mutex = mutex;
-    } else {
-      d_i_own_mutex = true;
-      d_mutex = new mld_mutex ();
-    }
-#ifdef _USE_OMNI_THREADS_
-    d_condition = new omni_condition (d_mutex->mutex ());
-#else
-    d_condition = (l_condition_ptr) new l_condition;
-    int l_ret = pthread_cond_init (d_condition, NULL);
-    if (l_ret != 0) {
-      fprintf (stderr, "Error %d creating condition.\n", l_ret);
-      throw std::runtime_error ("mld_condition_t::mld_condition_t()\n");
-    }
-#endif
-  };
-
-  __INLINE__ ~mld_condition_t () {
-    signal ();
-#ifndef _USE_OMNI_THREADS_
-    int l_ret = pthread_cond_destroy (d_condition);
-    if (l_ret != 0) {
-      fprintf (stderr, "mld_condition_t::mld_condition_t(): "
-              "Error %d destroying condition.\n", l_ret);
-    }
-#endif
-    delete d_condition;
-    d_condition = NULL;
-    if (d_i_own_mutex)
-      delete d_mutex;
-    d_mutex = NULL;
-  };
-
-  __INLINE__ mld_mutex_ptr mutex () {return (d_mutex);};
-
-  __INLINE__ void signal () {
-    DEBUG (fprintf (stderr, "a "););
-
-#ifdef _USE_OMNI_THREADS_
-    d_condition->signal ();
-#else
-    int l_ret = pthread_cond_signal (d_condition);
-    if (l_ret != 0) {
-      fprintf (stderr, "mld_condition_t::signal(): "
-              "Error %d.\n", l_ret);
-    }
-#endif
-    DEBUG (fprintf (stderr, "b "););
-  };
-
-  __INLINE__ void wait () {
-    DEBUG (fprintf (stderr, "c "););
-#ifdef _USE_OMNI_THREADS_
-    d_condition->wait ();
-#else
-    int l_ret = pthread_cond_wait (d_condition, d_mutex->mutex ());
-    if (l_ret != 0) {
-      fprintf (stderr, "mld_condition_t::wait(): "
-              "Error %d.\n", l_ret);
-    }
-#endif
-    DEBUG (fprintf (stderr, "d "););
-  };
-};
-
-typedef mld_condition_t mld_condition, *mld_condition_ptr;
-
-class mld_thread_t {
-#ifdef _USE_OMNI_THREADS_
-  typedef omni_thread l_thread, *l_thread_ptr;
-#else
-  typedef pthread_t l_thread, *l_thread_ptr;
-#endif
-
-private:
-#ifndef _USE_OMNI_THREADS_
-  l_thread d_thread;
-  void (*d_start_routine)(void*);
-  void *d_arg;
-#else
-  l_thread_ptr d_thread;
-#endif
-
-#ifndef _USE_OMNI_THREADS_
-  static void* local_start_routine (void *arg) {
-    mld_thread_t* This = (mld_thread_t*) arg;
-    (*(This->d_start_routine))(This->d_arg);
-    return (NULL);
-  };
-#endif
-
-public:
-  __INLINE__ mld_thread_t (void (*start_routine)(void *), void *arg) {
-#ifdef _USE_OMNI_THREADS_
-    d_thread = new omni_thread (start_routine, arg);
-    d_thread->start ();
-#else
-    d_start_routine = start_routine;
-    d_arg = arg;
-    int l_ret = pthread_create (&d_thread, NULL, local_start_routine, this);
-    if (l_ret != 0) {
-      fprintf (stderr, "Error %d creating thread.\n", l_ret);
-      throw std::runtime_error ("mld_thread_t::mld_thread_t()\n");
-    }
-#endif
-  };
-
-  __INLINE__ ~mld_thread_t () {
-#ifdef _USE_OMNI_THREADS_
-//  delete d_thread;
-    d_thread = NULL;
-#else
-    int l_ret = pthread_detach (d_thread);
-    if (l_ret != 0) {
-      fprintf (stderr, "Error %d detaching thread.\n", l_ret);
-      throw std::runtime_error ("mld_thread_t::~mld_thread_t()\n");
-    }
-#endif
-  };
-};
-
-typedef mld_thread_t mld_thread, *mld_thread_ptr;
-
-#endif /* _INCLUDED_MLD_THREADS_H_ */
diff --git a/usrp/host/lib/legacy/rate_to_regval.h b/usrp/host/lib/legacy/rate_to_regval.h
deleted file mode 100644 (file)
index 1ffdc0f..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-  {   1, 0x00 },
-  {   2, 0x01 },
-  {   3, 0x02 },
-  {   4, 0x11 },
-  {   5, 0x04 },
-  {   6, 0x05 },
-  {   7, 0x06 },
-  {   8, 0x13 },
-  {   9, 0x08 },
-  {  10, 0x09 },
-  {  11, 0x0a },
-  {  12, 0x15 },
-  {  13, 0x0c },
-  {  14, 0x0d },
-  {  15, 0x0e },
-  {  16, 0x33 },
-  {  18, 0x18 },
-  {  20, 0x19 },
-  {  21, 0x26 },
-  {  22, 0x1a },
-  {  24, 0x35 },
-  {  25, 0x44 },
-  {  26, 0x1c },
-  {  27, 0x28 },
-  {  28, 0x1d },
-  {  30, 0x1e },
-  {  32, 0x37 },
-  {  33, 0x2a },
-  {  35, 0x46 },
-  {  36, 0x55 },
-  {  39, 0x2c },
-  {  40, 0x39 },
-  {  42, 0x56 },
-  {  44, 0x3a },
-  {  45, 0x2e },
-  {  48, 0x57 },
-  {  49, 0x66 },
-  {  50, 0x49 },
-  {  52, 0x3c },
-  {  54, 0x58 },
-  {  55, 0x4a },
-  {  56, 0x3d },
-  {  60, 0x59 },
-  {  63, 0x68 },
-  {  64, 0x77 },
-  {  65, 0x4c },
-  {  66, 0x5a },
-  {  70, 0x69 },
-  {  72, 0x5b },
-  {  75, 0x4e },
-  {  77, 0x6a },
-  {  78, 0x5c },
-  {  80, 0x79 },
-  {  81, 0x88 },
-  {  84, 0x5d },
-  {  88, 0x7a },
-  {  90, 0x5e },
-  {  91, 0x6c },
-  {  96, 0x7b },
-  {  98, 0x6d },
-  {  99, 0x8a },
-  { 100, 0x99 },
-  { 104, 0x7c },
-  { 105, 0x6e },
-  { 108, 0x8b },
-  { 110, 0x9a },
-  { 112, 0x7d },
-  { 117, 0x8c },
-  { 120, 0x9b },
-  { 121, 0xaa },
-  { 126, 0x8d },
-  { 128, 0x7f },
-  { 130, 0x9c },
-  { 132, 0xab },
-  { 135, 0x8e },
-  { 140, 0x9d },
-  { 143, 0xac },
-  { 144, 0xbb },
-  { 150, 0x9e },
-  { 154, 0xad },
-  { 156, 0xbc },
-  { 160, 0x9f },
-  { 165, 0xae },
-  { 168, 0xbd },
-  { 169, 0xcc },
-  { 176, 0xaf },
-  { 180, 0xbe },
-  { 182, 0xcd },
-  { 192, 0xbf },
-  { 195, 0xce },
-  { 196, 0xdd },
-  { 208, 0xcf },
-  { 210, 0xde },
-  { 224, 0xdf },
-  { 225, 0xee },
-  { 240, 0xef },
-  { 256, 0xff }
diff --git a/usrp/host/lib/legacy/std_paths.h.in b/usrp/host/lib/legacy/std_paths.h.in
deleted file mode 100644 (file)
index e09499e..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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.
- */
-
-static const char *std_paths[] = {
-  "@prefix@/share/usrp",
-  "/usr/local/share/usrp",
-  0
-};
diff --git a/usrp/host/lib/legacy/usrp_basic.cc b/usrp/host/lib/legacy/usrp_basic.cc
deleted file mode 100644 (file)
index 295c62f..0000000
+++ /dev/null
@@ -1,1552 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003,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_basic.h"
-#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>
-#include <math.h>
-#include <ad9862.h>
-#include <string.h>
-#include <cstdio>
-
-using namespace ad9862;
-
-#define NELEM(x) (sizeof (x) / sizeof (x[0]))
-
-// These set the buffer size used for each end point using the fast
-// usb interface.  The kernel ends up locking down this much memory.
-
-static const int FUSB_BUFFER_SIZE = fusb_sysconfig::default_buffer_size();
-static const int FUSB_BLOCK_SIZE = fusb_sysconfig::max_block_size();
-static const int FUSB_NBLOCKS    = FUSB_BUFFER_SIZE / FUSB_BLOCK_SIZE;
-
-
-static const double POLLING_INTERVAL = 0.1;    // seconds
-
-////////////////////////////////////////////////////////////////
-
-static struct usb_dev_handle *
-open_rx_interface (struct usb_device *dev)
-{
-  struct usb_dev_handle *udh = usrp_open_rx_interface (dev);
-  if (udh == 0){
-    fprintf (stderr, "usrp_basic_rx: can't open rx interface\n");
-    usb_strerror ();
-  }
-  return udh;
-}
-
-static struct usb_dev_handle *
-open_tx_interface (struct usb_device *dev)
-{
-  struct usb_dev_handle *udh = usrp_open_tx_interface (dev);
-  if (udh == 0){
-    fprintf (stderr, "usrp_basic_tx: can't open tx interface\n");
-    usb_strerror ();
-  }
-  return udh;
-}
-
-
-//////////////////////////////////////////////////////////////////
-//
-//                     usrp_basic
-//
-////////////////////////////////////////////////////////////////
-
-
-// Given:
-//   CLKIN = 64 MHz
-//   CLKSEL pin = high 
-//
-// These settings give us:
-//   CLKOUT1 = CLKIN = 64 MHz
-//   CLKOUT2 = CLKIN = 64 MHz
-//   ADC is clocked at  64 MHz
-//   DAC is clocked at 128 MHz
-
-static unsigned char common_regs[] = {
-  REG_GENERAL,         0,
-  REG_DLL,             (DLL_DISABLE_INTERNAL_XTAL_OSC
-                        | DLL_MULT_2X
-                        | DLL_FAST),
-  REG_CLKOUT,          CLKOUT2_EQ_DLL_OVER_2,
-  REG_AUX_ADC_CLK,     AUX_ADC_CLK_CLK_OVER_4
-};
-
-
-usrp_basic::usrp_basic (int which_board, 
-                       struct usb_dev_handle *
-                       open_interface (struct usb_device *dev),
-                       const std::string fpga_filename,
-                       const std::string firmware_filename)
-  : 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_fpga_master_clock_freq(64000000), d_db(2)
-{
-  /*
-   * SWAG: Scientific Wild Ass Guess.
-   *
-   * d_usb_data_rate is used only to determine how often to poll for over- and under-runs.
-   * We defualt it to 1/2  of our best case.  Classes derived from usrp_basic (e.g., 
-   * usrp_standard_tx and usrp_standard_rx) call set_usb_data_rate() to tell us the
-   * actual rate.  This doesn't change our throughput, that's determined by the signal
-   * processing code in the FPGA (which we know nothing about), and the system limits
-   * determined by libusb, fusb_*, and the underlying drivers.
-   */
-  memset (d_fpga_shadows, 0, sizeof (d_fpga_shadows));
-
-  usrp_one_time_init ();
-
-  if (!usrp_load_standard_bits (which_board, false, fpga_filename, firmware_filename))
-    throw std::runtime_error ("usrp_basic/usrp_load_standard_bits");
-
-  struct usb_device *dev = usrp_find_device (which_board);
-  if (dev == 0){
-    fprintf (stderr, "usrp_basic: can't find usrp[%d]\n", which_board);
-    throw std::runtime_error ("usrp_basic/usrp_find_device");
-  }
-
-  if (!(usrp_usrp_p(dev) && usrp_hw_rev(dev) >= 1)){
-    fprintf (stderr, "usrp_basic: sorry, this code only works with USRP revs >= 1\n");
-    throw std::runtime_error ("usrp_basic/bad_rev");
-  }
-
-  if ((d_udh = open_interface (dev)) == 0)
-    throw std::runtime_error ("usrp_basic/open_interface");
-
-  // initialize registers that are common to rx and tx
-
-  if (!usrp_9862_write_many_all (d_udh, common_regs, sizeof (common_regs))){
-    fprintf (stderr, "usrp_basic: failed to init common AD9862 regs\n");
-    throw std::runtime_error ("usrp_basic/init_9862");
-  }
-
-  _write_fpga_reg (FR_MODE, 0);                // ensure we're in normal mode
-  _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 ()
-{
-  return true;         // nop
-}
-
-bool
-usrp_basic::stop ()
-{
-  return true;         // nop
-}
-
-void
-usrp_basic::set_usb_data_rate (int usb_data_rate)
-{
-  d_usb_data_rate = usb_data_rate;
-  d_bytes_per_poll = (int) (usb_data_rate * POLLING_INTERVAL);
-}
-
-bool
-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)
-{
-  return usrp_read_aux_adc (d_udh, slot, which_adc, value);
-}
-
-int
-usrp_basic::_read_aux_adc (int slot, int which_adc)
-{
-  int  value;
-  if (!_read_aux_adc (slot, which_adc, &value))
-    return READ_FAILED;
-
-  return value;
-}
-
-bool
-usrp_basic::write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf)
-{
-  return usrp_eeprom_write (d_udh, i2c_addr, eeprom_offset, buf.data (), buf.size ());
-}
-
-std::string
-usrp_basic::read_eeprom (int i2c_addr, int eeprom_offset, int len)
-{
-  if (len <= 0)
-    return "";
-
-  char buf[len];
-
-  if (!usrp_eeprom_read (d_udh, i2c_addr, eeprom_offset, buf, len))
-    return "";
-
-  return std::string (buf, len);
-}
-
-bool
-usrp_basic::write_i2c (int i2c_addr, const std::string buf)
-{
-  return usrp_i2c_write (d_udh, i2c_addr, buf.data (), buf.size ());
-}
-
-std::string
-usrp_basic::read_i2c (int i2c_addr, int len)
-{
-  if (len <= 0)
-    return "";
-
-  char buf[len];
-
-  if (!usrp_i2c_read (d_udh, i2c_addr, buf, len))
-    return "";
-
-  return std::string (buf, len);
-}
-
-std::string
-usrp_basic::serial_number()
-{
-  return usrp_serial_number(d_udh);
-}
-
-// ----------------------------------------------------------------
-
-bool
-usrp_basic::set_adc_offset (int which_adc, int offset)
-{
-  if (which_adc < 0 || which_adc > 3)
-    return false;
-
-  return _write_fpga_reg (FR_ADC_OFFSET_0 + which_adc, offset);
-}
-
-bool
-usrp_basic::set_dac_offset (int which_dac, int offset, int offset_pin)
-{
-  if (which_dac < 0 || which_dac > 3)
-    return false;
-
-  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;
-
-  if (tx_a){
-    ok =  _write_9862 (which_codec, REG_TX_A_OFFSET_LO, lo);
-    ok &= _write_9862 (which_codec, REG_TX_A_OFFSET_HI, hi);
-  }
-  else {
-    ok =  _write_9862 (which_codec, REG_TX_B_OFFSET_LO, lo);
-    ok &= _write_9862 (which_codec, REG_TX_B_OFFSET_HI, hi);
-  }
-  return ok;
-}
-
-bool
-usrp_basic::set_adc_buffer_bypass (int which_adc, bool bypass)
-{
-  if (which_adc < 0 || which_adc > 3)
-    return false;
-
-  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;
-
-  // If the input buffer is bypassed, we need to power it down too.
-
-  bool ok = _read_9862 (codec, reg, &cur_rx);
-  ok &= _read_9862 (codec, REG_RX_PWR_DN, &cur_pwr_dn);
-  if (!ok)
-    return false;
-
-  if (bypass){
-    cur_rx |= RX_X_BYPASS_INPUT_BUFFER;
-    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_adc & 1) == 0) ? RX_PWR_DN_BUF_A : RX_PWR_DN_BUF_B);
-  }
-
-  ok &= _write_9862 (codec, reg, cur_rx);
-  ok &= _write_9862 (codec, REG_RX_PWR_DN, cur_pwr_dn);
-  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
-usrp_basic::_write_fpga_reg (int regno, int value)
-{
-  if (d_verbose){
-    fprintf (stdout, "_write_fpga_reg(%3d, 0x%08x)\n", regno, value);
-    fflush (stdout);
-  }
-
-  if (regno >= 0 && regno < MAX_REGS)
-    d_fpga_shadows[regno] = value;
-
-  return usrp_write_fpga_reg (d_udh, regno, value);
-}
-
-bool
-usrp_basic::_write_fpga_reg_masked (int regno, int value, int mask)
-{
-  //Only use this for registers who actually use a mask in the verilog firmware, like FR_RX_MASTER_SLAVE
-  //value is a 16 bits value and mask is a 16 bits mask
-  if (d_verbose){
-    fprintf (stdout, "_write_fpga_reg_masked(%3d, 0x%04x,0x%04x)\n", regno, value, mask);
-    fflush (stdout);
-  }
-
-  if (regno >= 0 && regno < MAX_REGS)
-    d_fpga_shadows[regno] = value;
-
-  return usrp_write_fpga_reg (d_udh, regno, (value & 0xffff) | ((mask & 0xffff)<<16));
-}
-
-
-bool
-usrp_basic::_read_fpga_reg (int regno, int *value)
-{
-  return usrp_read_fpga_reg (d_udh, regno, value);
-}
-
-int
-usrp_basic::_read_fpga_reg (int regno)
-{
-  int value;
-  if (!_read_fpga_reg (regno, &value))
-    return READ_FAILED;
-  return value;
-}
-
-bool
-usrp_basic::_write_9862 (int which_codec, int regno, unsigned char value)
-{
-  if (0 && d_verbose){
-    // FIXME really want to enable logging in usrp_prims:usrp_9862_write
-    fprintf(stdout, "_write_9862(codec = %d, regno = %2d, val = 0x%02x)\n", which_codec, regno, value);
-    fflush(stdout);
-  }
-
-  return usrp_9862_write (d_udh, which_codec, regno, value);
-}
-
-
-bool
-usrp_basic::_read_9862 (int which_codec, int regno, unsigned char *value) const
-{
-  return usrp_9862_read (d_udh, which_codec, regno, value);
-}
-
-int
-usrp_basic::_read_9862 (int which_codec, int regno) const
-{
-  unsigned char value;
-  if (!_read_9862 (which_codec, regno, &value))
-    return READ_FAILED;
-  return value;
-}
-
-bool
-usrp_basic::_write_spi (int optional_header, int enables, int format, std::string buf)
-{
-  return usrp_spi_write (d_udh, optional_header, enables, format,
-                        buf.data(), buf.size());
-}
-
-std::string
-usrp_basic::_read_spi (int optional_header, int enables, int format, int len)
-{
-  if (len <= 0)
-    return "";
-  
-  char buf[len];
-
-  if (!usrp_spi_read (d_udh, optional_header, enables, format, buf, len))
-    return "";
-
-  return std::string (buf, len);
-}
-
-
-bool
-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 _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
-//
-////////////////////////////////////////////////////////////////
-
-static unsigned char rx_init_regs[] = {
-  REG_RX_PWR_DN,       0,
-  REG_RX_A,            0,      // minimum gain = 0x00 (max gain = 0x14)
-  REG_RX_B,            0,      // minimum gain = 0x00 (max gain = 0x14)
-  REG_RX_MISC,         (RX_MISC_HS_DUTY_CYCLE | RX_MISC_CLK_DUTY),
-  REG_RX_IF,           (RX_IF_USE_CLKOUT1
-                        | RX_IF_2S_COMP),
-  REG_RX_DIGITAL,      (RX_DIGITAL_2_CHAN)
-};
-
-
-usrp_basic_rx::usrp_basic_rx (int which_board, int fusb_block_size, int fusb_nblocks,
-                             const std::string fpga_filename,
-                             const std::string firmware_filename
-                             )
-  : usrp_basic (which_board, open_rx_interface, fpga_filename, firmware_filename),
-    d_devhandle (0), d_ephandle (0),
-    d_bytes_seen (0), d_first_read (true),
-    d_rx_enable (false)
-{
-  // initialize rx specific registers
-
-  if (!usrp_9862_write_many_all (d_udh, rx_init_regs, sizeof (rx_init_regs))){
-    fprintf (stderr, "usrp_basic_rx: failed to init AD9862 RX regs\n");
-    throw std::runtime_error ("usrp_basic_rx/init_9862");
-  }
-
-  if (0){
-    // FIXME power down 2nd codec rx path
-    usrp_9862_write (d_udh, 1, REG_RX_PWR_DN, 0x1);    // power down everything
-  }
-
-  // Reset the rx path and leave it disabled.
-  set_rx_enable (false);
-  usrp_set_fpga_rx_reset (d_udh, true);
-  usrp_set_fpga_rx_reset (d_udh, false);
-
-  set_fpga_rx_sample_rate_divisor (2); // usually correct
-
-  set_dc_offset_cl_enable(0xf, 0xf);   // enable DC offset removal control loops
-
-  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)
-    throw std::out_of_range ("usrp_basic_rx: invalid fusb_block_size");
-
-  if (fusb_nblocks < 0)
-    throw std::out_of_range ("usrp_basic_rx: invalid fusb_nblocks");
-  
-  if (fusb_block_size == 0)
-    fusb_block_size = fusb_sysconfig::default_block_size();
-
-  if (fusb_nblocks == 0)
-    fusb_nblocks = std::max (1, FUSB_BUFFER_SIZE / fusb_block_size);
-
-  d_devhandle = fusb_sysconfig::make_devhandle (d_udh);
-  d_ephandle = d_devhandle->make_ephandle (USRP_RX_ENDPOINT, true,
-                                          fusb_block_size, fusb_nblocks);
-
-  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[] = {
-  REG_RX_PWR_DN,       0x1                             // power down everything
-};
-
-usrp_basic_rx::~usrp_basic_rx ()
-{
-  if (!set_rx_enable (false)){
-    fprintf (stderr, "usrp_basic_rx: set_fpga_rx_enable failed\n");
-    usb_strerror ();
-  }
-
-  d_ephandle->stop ();
-  delete d_ephandle;
-  delete d_devhandle;
-
-  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();
-}
-
-
-bool
-usrp_basic_rx::start ()
-{
-  if (!usrp_basic::start ())   // invoke parent's method
-    return false;
-
-  // fire off reads before asserting rx_enable
-
-  if (!d_ephandle->start ()){
-    fprintf (stderr, "usrp_basic_rx: failed to start end point streaming");
-    usb_strerror ();
-    return false;
-  }
-
-  if (!set_rx_enable (true)){
-    fprintf (stderr, "usrp_basic_rx: set_rx_enable failed\n");
-    usb_strerror ();
-    return false;
-  }
-  
-  return true;
-}
-
-bool
-usrp_basic_rx::stop ()
-{
-  bool ok = usrp_basic::stop();
-
-  if (!set_rx_enable(false)){
-    fprintf (stderr, "usrp_basic_rx: set_rx_enable(false) failed\n");
-    usb_strerror ();
-    ok = false;
-  }
-
-  if (!d_ephandle->stop()){
-    fprintf (stderr, "usrp_basic_rx: failed to stop end point streaming");
-    usb_strerror ();
-    ok = false;
-  }
-
-  return ok;
-}
-
-usrp_basic_rx *
-usrp_basic_rx::make (int which_board, int fusb_block_size, int fusb_nblocks,
-                    const std::string fpga_filename,
-                    const std::string firmware_filename)
-{
-  usrp_basic_rx *u = 0;
-  
-  try {
-    u = new usrp_basic_rx (which_board, fusb_block_size, fusb_nblocks,
-                          fpga_filename, firmware_filename);
-    return u;
-  }
-  catch (...){
-    delete u;
-    return 0;
-  }
-
-  return u;
-}
-
-bool
-usrp_basic_rx::set_fpga_rx_sample_rate_divisor (unsigned int div)
-{
-  return _write_fpga_reg (FR_RX_SAMPLE_RATE_DIV, div - 1);
-}
-
-
-/*
- * \brief read data from the D/A's via the FPGA.
- * \p len must be a multiple of 512 bytes.
- *
- * \returns the number of bytes read, or -1 on error.
- *
- * If overrun is non-NULL it will be set true iff an RX overrun is detected.
- */
-int
-usrp_basic_rx::read (void *buf, int len, bool *overrun)
-{
-  int  r;
-  
-  if (overrun)
-    *overrun = false;
-  
-  if (len < 0 || (len % 512) != 0){
-    fprintf (stderr, "usrp_basic_rx::read: invalid length = %d\n", len);
-    return -1;
-  }
-
-  r = d_ephandle->read (buf, len);
-  if (r > 0)
-    d_bytes_seen += r;
-
-  /*
-   * In many cases, the FPGA reports an rx overrun right after we
-   * enable the Rx path.  If this is our first read, check for the
-   * overrun to clear the condition, then ignore the result.
-   */
-  if (0 && d_first_read){      // FIXME
-    d_first_read = false;
-    bool bogus_overrun;
-    usrp_check_rx_overrun (d_udh, &bogus_overrun);
-  }
-
-  if (overrun != 0 && d_bytes_seen >= d_bytes_per_poll){
-    d_bytes_seen = 0;
-    if (!usrp_check_rx_overrun (d_udh, overrun)){
-      fprintf (stderr, "usrp_basic_rx: usrp_check_rx_overrun failed\n");
-      usb_strerror ();
-    }
-  }
-    
-  return r;
-}
-
-bool
-usrp_basic_rx::set_rx_enable (bool on)
-{
-  d_rx_enable = on;
-  return usrp_set_fpga_rx_enable (d_udh, on);
-}
-
-// conditional disable, return prev state
-bool
-usrp_basic_rx::disable_rx ()
-{
-  bool enabled = rx_enable ();
-  if (enabled)
-    set_rx_enable (false);
-  return enabled;
-}
-
-// conditional set
-void
-usrp_basic_rx::restore_rx (bool on)
-{
-  if (on != rx_enable ())
-    set_rx_enable (on);
-}
-
-void
-usrp_basic_rx::probe_rx_slots (bool verbose)
-{
-  struct usrp_dboard_eeprom    eeprom;
-  static int slot_id_map[2] = { SLOT_RX_A, SLOT_RX_B };
-  static const char *slot_name[2] = { "RX d'board A", "RX d'board B" };
-
-  for (int i = 0; i < 2; i++){
-    int slot_id = slot_id_map [i];
-    const char *msg = 0;
-    usrp_dbeeprom_status_t s = usrp_read_dboard_eeprom (d_udh, slot_id, &eeprom);
-
-    switch (s){
-    case UDBE_OK:
-      d_dbid[i] = eeprom.id;
-      msg = usrp_dbid_to_string (eeprom.id).c_str ();
-      set_adc_offset (2*i+0, eeprom.offset[0]);
-      set_adc_offset (2*i+1, eeprom.offset[1]);
-      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | eeprom.oe);
-      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
-      break;
-      
-    case UDBE_NO_EEPROM:
-      d_dbid[i] = -1;
-      msg = "<none>";
-      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
-      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
-      break;
-      
-    case UDBE_INVALID_EEPROM:
-      d_dbid[i] = -2;
-      msg = "Invalid EEPROM contents";
-      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
-      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
-      break;
-      
-    case UDBE_BAD_SLOT:
-    default:
-      assert (0);
-    }
-
-    if (verbose){
-      fflush (stdout);
-      fprintf (stderr, "%s: %s\n", slot_name[i], msg);
-    }
-  }
-}
-
-bool
-usrp_basic_rx::set_pga (int which_amp, double gain)
-{
-  return common_set_pga(C_RX, which_amp, gain);
-}
-
-double
-usrp_basic_rx::pga(int which_amp) const
-{
-  return common_pga(C_RX, which_amp);
-}
-
-double
-usrp_basic_rx::pga_min() const
-{
-  return common_pga_min(C_RX);
-}
-
-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::_write_oe (int which_side, int value, int mask)
-{
-  return _common_write_oe(C_RX, which_side, value, mask);
-}
-
-bool
-usrp_basic_rx::write_io (int which_side, int value, int mask)
-{
-  return common_write_io(C_RX, which_side, value, mask);
-}
-
-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_side)
-{
-  return common_read_io(C_RX, which_side);
-}
-
-bool
-usrp_basic_rx::write_refclk(int which_side, int value)
-{
-  return common_write_refclk(C_RX, which_side, value);
-}
-
-bool
-usrp_basic_rx::write_atr_mask(int which_side, int value)
-{
-  return common_write_atr_mask(C_RX, which_side, value);
-}
-
-bool
-usrp_basic_rx::write_atr_txval(int which_side, int value)
-{
-  return common_write_atr_txval(C_RX, which_side, value);
-}
-
-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::write_aux_dac (int which_side, int which_dac, int value)
-{
-  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
-//
-////////////////////////////////////////////////////////////////
-
-
-//
-// DAC input rate 64 MHz interleaved for a total input rate of 128 MHz
-// DAC input is latched on rising edge of CLKOUT2
-// NCO is disabled
-// interpolate 2x
-// coarse modulator disabled
-//
-
-static unsigned char tx_init_regs[] = {
-  REG_TX_PWR_DN,       0,
-  REG_TX_A_OFFSET_LO,  0,
-  REG_TX_A_OFFSET_HI,  0,
-  REG_TX_B_OFFSET_LO,  0,
-  REG_TX_B_OFFSET_HI,  0,
-  REG_TX_A_GAIN,       (TX_X_GAIN_COARSE_FULL | 0),
-  REG_TX_B_GAIN,       (TX_X_GAIN_COARSE_FULL | 0),
-  REG_TX_PGA,          0xff,                   // maximum gain (0 dB)
-  REG_TX_MISC,         0,
-  REG_TX_IF,           (TX_IF_USE_CLKOUT1
-                        | TX_IF_I_FIRST
-                        | TX_IF_INV_TX_SYNC
-                        | TX_IF_2S_COMP
-                        | TX_IF_INTERLEAVED),
-  REG_TX_DIGITAL,      (TX_DIGITAL_2_DATA_PATHS
-                        | TX_DIGITAL_INTERPOLATE_4X),
-  REG_TX_MODULATOR,    (TX_MODULATOR_DISABLE_NCO
-                        | TX_MODULATOR_COARSE_MODULATION_NONE),
-  REG_TX_NCO_FTW_7_0,  0,
-  REG_TX_NCO_FTW_15_8, 0,
-  REG_TX_NCO_FTW_23_16,        0
-};
-
-usrp_basic_tx::usrp_basic_tx (int which_board, int fusb_block_size, int fusb_nblocks,
-                             const std::string fpga_filename,
-                             const std::string firmware_filename)
-  : usrp_basic (which_board, open_tx_interface, fpga_filename, firmware_filename),
-    d_devhandle (0), d_ephandle (0),
-    d_bytes_seen (0), d_first_write (true),
-    d_tx_enable (false)
-{
-  if (!usrp_9862_write_many_all (d_udh, tx_init_regs, sizeof (tx_init_regs))){
-    fprintf (stderr, "usrp_basic_tx: failed to init AD9862 TX regs\n");
-    throw std::runtime_error ("usrp_basic_tx/init_9862");
-  }
-
-  if (0){
-    // FIXME power down 2nd codec tx path
-    usrp_9862_write (d_udh, 1, REG_TX_PWR_DN,
-                    (TX_PWR_DN_TX_DIGITAL
-                     | TX_PWR_DN_TX_ANALOG_BOTH));
-  }
-
-  // Reset the tx path and leave it disabled.
-  set_tx_enable (false);
-  usrp_set_fpga_tx_reset (d_udh, true);
-  usrp_set_fpga_tx_reset (d_udh, false);
-
-  set_fpga_tx_sample_rate_divisor (4); // we're using interp x4
-
-  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)
-    throw std::out_of_range ("usrp_basic_rx: invalid fusb_block_size");
-
-  if (fusb_nblocks < 0)
-    throw std::out_of_range ("usrp_basic_rx: invalid fusb_nblocks");
-  
-  if (fusb_block_size == 0)
-    fusb_block_size = FUSB_BLOCK_SIZE;
-
-  if (fusb_nblocks == 0)
-    fusb_nblocks = std::max (1, FUSB_BUFFER_SIZE / fusb_block_size);
-
-  d_devhandle = fusb_sysconfig::make_devhandle (d_udh);
-  d_ephandle = d_devhandle->make_ephandle (USRP_TX_ENDPOINT, false,
-                                          fusb_block_size, fusb_nblocks);
-
-  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);
-}
-
-
-static unsigned char tx_fini_regs[] = {
-  REG_TX_PWR_DN,       (TX_PWR_DN_TX_DIGITAL
-                        | TX_PWR_DN_TX_ANALOG_BOTH),
-  REG_TX_MODULATOR,    (TX_MODULATOR_DISABLE_NCO
-                        | TX_MODULATOR_COARSE_MODULATION_NONE)
-};
-
-usrp_basic_tx::~usrp_basic_tx ()
-{
-  d_ephandle->stop ();
-  delete d_ephandle;
-  delete d_devhandle;
-
-  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
-usrp_basic_tx::start ()
-{
-  if (!usrp_basic::start ())
-    return false;
-
-  if (!set_tx_enable (true)){
-    fprintf (stderr, "usrp_basic_tx: set_tx_enable failed\n");
-    usb_strerror ();
-    return false;
-  }
-  
-  if (!d_ephandle->start ()){
-    fprintf (stderr, "usrp_basic_tx: failed to start end point streaming");
-    usb_strerror ();
-    return false;
-  }
-
-  return true;
-}
-
-bool
-usrp_basic_tx::stop ()
-{
-  bool ok = usrp_basic::stop ();
-
-  if (!d_ephandle->stop ()){
-    fprintf (stderr, "usrp_basic_tx: failed to stop end point streaming");
-    usb_strerror ();
-    ok = false;
-  }
-
-  if (!set_tx_enable (false)){
-    fprintf (stderr, "usrp_basic_tx: set_tx_enable(false) failed\n");
-    usb_strerror ();
-    ok = false;
-  }
-
-  return ok;
-}
-
-usrp_basic_tx *
-usrp_basic_tx::make (int which_board, int fusb_block_size, int fusb_nblocks,
-                    const std::string fpga_filename,
-                    const std::string firmware_filename)
-{
-  usrp_basic_tx *u = 0;
-  
-  try {
-    u = new usrp_basic_tx (which_board, fusb_block_size, fusb_nblocks,
-                          fpga_filename, firmware_filename);
-    return u;
-  }
-  catch (...){
-    delete u;
-    return 0;
-  }
-
-  return u;
-}
-
-bool
-usrp_basic_tx::set_fpga_tx_sample_rate_divisor (unsigned int div)
-{
-  return _write_fpga_reg (FR_TX_SAMPLE_RATE_DIV, div - 1);
-}
-
-/*!
- * \brief Write data to the A/D's via the FPGA.
- *
- * \p len must be a multiple of 512 bytes.
- * \returns number of bytes written or -1 on error.
- *
- * if \p underrun is non-NULL, it will be set to true iff
- * a transmit underrun condition is detected.
- */
-int
-usrp_basic_tx::write (const void *buf, int len, bool *underrun)
-{
-  int  r;
-  
-  if (underrun)
-    *underrun = false;
-  
-  if (len < 0 || (len % 512) != 0){
-    fprintf (stderr, "usrp_basic_tx::write: invalid length = %d\n", len);
-    return -1;
-  }
-
-  r = d_ephandle->write (buf, len);
-  if (r > 0)
-    d_bytes_seen += r;
-    
-  /*
-   * In many cases, the FPGA reports an tx underrun right after we
-   * enable the Tx path.  If this is our first write, check for the
-   * underrun to clear the condition, then ignore the result.
-   */
-  if (d_first_write && d_bytes_seen >= 4 * FUSB_BLOCK_SIZE){
-    d_first_write = false;
-    bool bogus_underrun;
-    usrp_check_tx_underrun (d_udh, &bogus_underrun);
-  }
-
-  if (underrun != 0 && d_bytes_seen >= d_bytes_per_poll){
-    d_bytes_seen = 0;
-    if (!usrp_check_tx_underrun (d_udh, underrun)){
-      fprintf (stderr, "usrp_basic_tx: usrp_check_tx_underrun failed\n");
-      usb_strerror ();
-    }
-  }
-
-  return r;
-}
-
-void
-usrp_basic_tx::wait_for_completion ()
-{
-  d_ephandle->wait_for_completion ();
-}
-
-bool
-usrp_basic_tx::set_tx_enable (bool on)
-{
-  d_tx_enable = on;
-  // fprintf (stderr, "set_tx_enable %d\n", on);
-  return usrp_set_fpga_tx_enable (d_udh, on);
-}
-
-// conditional disable, return prev state
-bool
-usrp_basic_tx::disable_tx ()
-{
-  bool enabled = tx_enable ();
-  if (enabled)
-    set_tx_enable (false);
-  return enabled;
-}
-
-// conditional set
-void
-usrp_basic_tx::restore_tx (bool on)
-{
-  if (on != tx_enable ())
-    set_tx_enable (on);
-}
-
-void
-usrp_basic_tx::probe_tx_slots (bool verbose)
-{
-  struct usrp_dboard_eeprom    eeprom;
-  static int slot_id_map[2] = { SLOT_TX_A, SLOT_TX_B };
-  static const char *slot_name[2] = { "TX d'board A", "TX d'board B" };
-
-  for (int i = 0; i < 2; i++){
-    int slot_id = slot_id_map [i];
-    const char *msg = 0;
-    usrp_dbeeprom_status_t s = usrp_read_dboard_eeprom (d_udh, slot_id, &eeprom);
-
-    switch (s){
-    case UDBE_OK:
-      d_dbid[i] = eeprom.id;
-      msg = usrp_dbid_to_string (eeprom.id).c_str ();
-      // FIXME, figure out interpretation of dc offset for TX d'boards
-      // offset = (eeprom.offset[1] << 16) | (eeprom.offset[0] & 0xffff);
-      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | eeprom.oe);
-      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
-      break;
-      
-    case UDBE_NO_EEPROM:
-      d_dbid[i] = -1;
-      msg = "<none>";
-      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
-      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
-      break;
-      
-    case UDBE_INVALID_EEPROM:
-      d_dbid[i] = -2;
-      msg = "Invalid EEPROM contents";
-      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
-      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
-      break;
-      
-    case UDBE_BAD_SLOT:
-    default:
-      assert (0);
-    }
-
-    if (verbose){
-      fflush (stdout);
-      fprintf (stderr, "%s: %s\n", slot_name[i], msg);
-    }
-  }
-}
-
-bool
-usrp_basic_tx::set_pga (int which_amp, double gain)
-{
-  return common_set_pga(C_TX, which_amp, gain);
-}
-
-double
-usrp_basic_tx::pga (int which_amp) const
-{
-  return common_pga(C_TX, which_amp);
-}
-
-double
-usrp_basic_tx::pga_min() const
-{
-  return common_pga_min(C_TX);
-}
-
-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::_write_oe (int which_side, int value, int mask)
-{
-  return _common_write_oe(C_TX, which_side, value, mask);
-}
-
-bool
-usrp_basic_tx::write_io (int which_side, int value, int mask)
-{
-  return common_write_io(C_TX, which_side, value, mask);
-}
-
-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_side)
-{
-  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_side, int which_dac, int value)
-{
-  return common_write_aux_dac(C_TX, which_side, which_dac, value);
-}
-
-bool
-usrp_basic_tx::read_aux_adc (int which_side, int which_adc, int *value)
-{
-  return common_read_aux_adc(C_TX, which_side, which_adc, value);
-}
-
-int
-usrp_basic_tx::read_aux_adc (int which_side, int which_adc)
-{
-  return common_read_aux_adc(C_TX, which_side, which_adc);
-}
-
-int
-usrp_basic_tx::block_size () const { return d_ephandle->block_size(); }
-
diff --git a/usrp/host/lib/legacy/usrp_basic.h b/usrp/host/lib/legacy/usrp_basic.h
deleted file mode 100644 (file)
index 86c4863..0000000
+++ /dev/null
@@ -1,991 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003,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.
- */
-
-/*
- * ----------------------------------------------------------------------
- * Mid level interface to the Universal Software Radio Peripheral (Rev 1)
- *
- * These classes implement the basic functionality for talking to the
- * USRP.  They try to be as independent of the signal processing code
- * in FPGA as possible.  They implement access to the low level
- * peripherals on the board, provide a common way for reading and
- * writing registers in the FPGA, and provide the high speed interface
- * to streaming data across the USB.
- *
- * It is expected that subclasses will be derived that provide
- * access to the functionality to a particular FPGA configuration.
- * ----------------------------------------------------------------------
- */
-
-#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 abstract base class for usrp operations
- * \ingroup usrp
- */
-class usrp_basic : boost::noncopyable
-{
-protected:
-  void shutdown_daughterboards();
-
-protected:
-  struct usb_dev_handle        *d_udh;
-  int                   d_usb_data_rate;       // bytes/sec
-  int                   d_bytes_per_poll;      // how often to poll for overruns
-  bool                  d_verbose;
-  long                   d_fpga_master_clock_freq;
-
-  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 = "",
-             const std::string firmware_filename = "");
-
-  /*!
-   * \brief advise usrp_basic of usb data rate (bytes/sec)
-   *
-   * N.B., this doesn't tweak any hardware.  Derived classes
-   * should call this to inform us of the data rate whenever it's
-   * first set or if it changes.
-   *
-   * \param usb_data_rate      bytes/sec
-   */
-  void set_usb_data_rate (int usb_data_rate);
-  
-  /*!
-   * \brief Write auxiliary digital to analog converter.
-   *
-   * \param slot       Which Tx or Rx slot to write.
-   *                   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  [0,3] RX slots must use only 0 and 1.  TX slots must use only 2 and 3.
-   * \param value      [0,4095]
-   * \returns true iff successful
-   */
-  bool _write_aux_dac (int slot, int which_dac, int value);
-
-  /*!
-   * \brief Read auxiliary analog to digital converter.
-   *
-   * \param slot       2-bit slot number. E.g., SLOT_TX_A
-   * \param which_adc  [0,1]
-   * \param value      return 12-bit value [0,4095]
-   * \returns true iff successful
-   */
-  bool _read_aux_adc (int slot, int which_adc, int *value);
-
-  /*!
-   * \brief Read auxiliary analog to digital converter.
-   *
-   * \param slot       2-bit slot number. E.g., SLOT_TX_A
-   * \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);
-
-
-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
-   */
-  long fpga_master_clock_freq () const { return d_fpga_master_clock_freq; }
-
-  /*!
-   * Tell API that the master oscillator on the USRP is operating at a non-standard 
-   * fixed frequency. This is only needed for custom USRP hardware modified to 
-   * operate at a different frequency from the default factory configuration. This
-   * function must be called prior to any other API function.
-   * \param master_clock USRP2 FPGA master clock frequency in Hz (10..64 MHz)
-   */
-  void set_fpga_master_clock_freq (long master_clock) { d_fpga_master_clock_freq = master_clock; }
-
-  /*!
-   * \returns usb data rate in bytes/sec
-   */
-  int usb_data_rate () const { return d_usb_data_rate; }
-
-  void set_verbose (bool on) { d_verbose = on; }
-
-  //! magic value used on alternate register read interfaces
-  static const int READ_FAILED = -99999;
-
-  /*!
-   * \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 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
-   * \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 64 bytes.
-   */
-  std::string read_i2c (int i2c_addr, int len);
-
-  /*!
-   * \brief Set ADC offset correction
-   * \param which_adc  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_adc, int offset);
-
-  /*!
-   * \brief Set DAC offset correction
-   * \param which_dac  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_dac, int offset, int offset_pin);
-
-  /*!
-   * \brief Control ADC input buffer
-   * \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_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.
-   *
-   * \returns non-zero length string iff successful.
-   */
-  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);
-
-
-\f  // ================================================================
-  // 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\f
-  // ----------------------------------------------------------------
-  // 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\f
-
-  // ----------------------------------------------------------------
-  // Low level implementation routines.
-  // You probably shouldn't be using these...
-  //
-
-  bool _set_led (int which_led, bool on);
-
-  /*!
-   * \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
-   * \param value      32-bit value
-   * \returns true iff successful
-   */
-  bool _read_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 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
-   * \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
-   * \param value      8-bit value
-   * \returns true iff successful
-   */
-  bool _read_9862 (int which_codec, int regno, unsigned char *value) const;
-
-  /*!
-   * \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);
-
-  /*!
-   * \brief Start data transfers.
-   * Called in base class to derived class order.
-   */
-  bool start ();
-
-  /*!
-   * \brief Stop data transfers.
-   * Called in base class to derived class order.
-   */
-  bool stop ();
-};
-
-\f/*!
- * \brief class for accessing the receive side of the USRP
- * \ingroup usrp
- */
-class usrp_basic_rx : public usrp_basic 
-{
-private:
-  fusb_devhandle       *d_devhandle;
-  fusb_ephandle                *d_ephandle;
-  int                   d_bytes_seen;          // how many bytes we've seen
-  bool                  d_first_read;
-  bool                  d_rx_enable;
-
-protected:
-  /*!
-   * \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 the rbf file to load
-   * \param firmware_filename name of ihx file to load
-   */
-  usrp_basic_rx (int which_board,
-                int fusb_block_size=0,
-                int fusb_nblocks=0,
-                const std::string fpga_filename = "",
-                const std::string firmware_filename = ""
-                );  // throws if trouble
-
-  bool set_rx_enable (bool on);
-  bool rx_enable () const { return d_rx_enable; }
-
-  bool disable_rx ();          // conditional disable, return prev state
-  void restore_rx (bool on);   // conditional set
-
-  void probe_rx_slots (bool verbose);
-
-public:
-  ~usrp_basic_rx ();
-
-  /*!
-   * \brief invokes constructor, returns instance or 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. 
-   * \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,
-                             int fusb_nblocks=0,
-                             const std::string fpga_filename = "",
-                             const std::string firmware_filename = ""
-                             );
-
-  /*!
-   * \brief tell the fpga the rate rx samples are coming from the A/D's
-   *
-   * div = fpga_master_clock_freq () / sample_rate
-   *
-   * sample_rate is determined by a myriad of registers
-   * in the 9862.  That's why you have to tell us, so
-   * we can tell the fpga.
-   */
-  bool set_fpga_rx_sample_rate_divisor (unsigned int div);
-
-  /*!
-   * \brief read data from the D/A's via the FPGA.
-   * \p len must be a multiple of 512 bytes.
-   *
-   * \returns the number of bytes read, or -1 on error.
-   *
-   * If overrun is non-NULL it will be set true iff an RX overrun is detected.
-   */
-  int read (void *buf, int len, bool *overrun);
-
-
-  //! sampling rate of A/D converter
-  virtual long converter_rate() const { return fpga_master_clock_freq(); } // 64M
-  long adc_rate() const { return converter_rate(); }
-  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);
-
-  int block_size() const;
-
-  // called in base class to derived class order
-  bool start ();
-  bool stop ();
-};
-
-\f/*!
- * \brief class for accessing the transmit side of the USRP
- * \ingroup usrp
- */
-class usrp_basic_tx : public usrp_basic 
-{
-private:
-  fusb_devhandle       *d_devhandle;
-  fusb_ephandle                *d_ephandle;
-  int                   d_bytes_seen;          // how many bytes we've seen
-  bool                  d_first_write;
-  bool                  d_tx_enable;
-
- protected:
-  /*!
-   * \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,
-                int fusb_nblocks=0,
-                const std::string fpga_filename = "",
-                const std::string firmware_filename = ""
-                );             // throws if trouble
-
-  bool set_tx_enable (bool on);
-  bool tx_enable () const { return d_tx_enable; }
-
-  bool disable_tx ();          // conditional disable, return prev state
-  void restore_tx (bool on);   // conditional set
-
-  void probe_tx_slots (bool verbose);
-
-public:
-
-  ~usrp_basic_tx ();
-
-  /*!
-   * \brief invokes constructor, returns instance or 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. 
-   * \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 = ""
-                             );
-
-  /*!
-   * \brief tell the fpga the rate tx samples are going to the D/A's
-   *
-   * div = fpga_master_clock_freq () * 2
-   *
-   * sample_rate is determined by a myriad of registers
-   * in the 9862.  That's why you have to tell us, so
-   * we can tell the fpga.
-   */
-  bool set_fpga_tx_sample_rate_divisor (unsigned int div);
-
-  /*!
-   * \brief Write data to the A/D's via the FPGA.
-   *
-   * \p len must be a multiple of 512 bytes.
-   * \returns number of bytes written or -1 on error.
-   *
-   * if \p underrun is non-NULL, it will be set to true iff
-   * a transmit underrun condition is detected.
-   */
-  int write (const void *buf, int len, bool *underrun);
-
-  /*
-   * Block until all outstanding writes have completed.
-   * This is typically used to assist with benchmarking
-   */
-  void wait_for_completion ();
-
-  //! 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(); }
-  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);
-
-  int block_size() const;
-
-  // called in base class to derived class order
-  bool start ();
-  bool stop ();
-};
-
-#endif
diff --git a/usrp/host/lib/legacy/usrp_bytesex.h b/usrp/host/lib/legacy/usrp_bytesex.h
deleted file mode 100644 (file)
index 331db31..0000000
+++ /dev/null
@@ -1,108 +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.
- */
-#ifndef INCLUDED_USRP_BYTESEX_H
-#define INCLUDED_USRP_BYTESEX_H
-
-/*!
- * \brief routines for convertering between host and usrp byte order
- *
- * Prior to including this file, the user must include "config.h"
- * which will or won't define WORDS_BIGENDIAN based on the
- * result of the AC_C_BIGENDIAN autoconf test.
- */
-
-#ifdef HAVE_BYTESWAP_H
-#include <byteswap.h>
-#else
-
-#warning Using non-portable code (likely wrong other than ILP32).
-
-static inline unsigned short int
-bswap_16 (unsigned short int x)
-{
-  return ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8));
-}
-
-static inline unsigned int
-bswap_32 (unsigned int x)
-{
-  return ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) \
-        | (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24));
-}
-#endif
-
-
-#ifdef WORDS_BIGENDIAN
-
-static inline unsigned int
-host_to_usrp_u32 (unsigned int x)
-{
-  return bswap_32(x);
-}
-
-static inline unsigned int
-usrp_to_host_u32 (unsigned int x)
-{
-  return bswap_32(x);
-}
-
-static inline short int
-host_to_usrp_short (short int x)
-{
-  return bswap_16 (x);
-}
-
-static inline short int
-usrp_to_host_short (short int x)
-{
-  return bswap_16 (x);
-}
-
-#else
-
-static inline unsigned int
-host_to_usrp_u32 (unsigned int x)
-{
-  return x;
-}
-
-static inline unsigned int
-usrp_to_host_u32 (unsigned int x)
-{
-  return x;
-}
-
-static inline short int
-host_to_usrp_short (short int x)
-{
-  return x;
-}
-
-static inline short int
-usrp_to_host_short (unsigned short int x)
-{
-  return x;
-}
-
-#endif
-
-#endif /* INCLUDED_USRP_BYTESEX_H */
diff --git a/usrp/host/lib/legacy/usrp_config.cc b/usrp/host/lib/legacy/usrp_config.cc
deleted file mode 100644 (file)
index fcf207f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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_config.h"
-
-int
-usrp_rx_config_stream_count (unsigned int usrp_rx_config)
-{
-  return 1;
-}
-
-int
-usrp_tx_config_stream_count (unsigned int usrp_tx_config)
-{
-  return 1;
-}
diff --git a/usrp/host/lib/legacy/usrp_config.h b/usrp/host/lib/legacy/usrp_config.h
deleted file mode 100644 (file)
index ee5cb63..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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 _USRP_CONFIG_H_
-#define _USRP_CONFIG_H_
-
-/*
- * ----------------------------------------------------------------
- * USRP Rx configurations.
- *
- * For now this is a placeholder, but will eventually specify the
- * mapping from A/D outputs to DDC inputs (I & Q).
- *
- * What's implemented today is a single DDC that has its I input
- * connected to ADC0 and its Q input connected to ADC1
- * ----------------------------------------------------------------
- */
-
-#define        USRP_RX_CONFIG_DEFAULT  0
-
-/*!
- * given a usrp_rx_config word, return the number of I & Q streams that
- * are interleaved on the USB.
- */
-
-int usrp_rx_config_stream_count (unsigned int usrp_rx_config);
-
-/*
- * USRP Tx configurations.
- *
- * For now this is a placeholder, but will eventually specify the
- * mapping from DUC outputs to D/A inputs.
- *
- * What's implemented today is a single DUC that has its I output
- * connected to DAC0 and its Q output connected to DAC1
- */
-
-#define        USRP_TX_CONFIG_DEFAULT  0
-
-/*!
- * given a usrp_tx_config word, return the number of I & Q streams that
- * are interleaved on the USB.
- */
-
-int usrp_tx_config_stream_count (unsigned int usrp_tx_config);
-
-
-#endif /* _USRP_CONFIG_H_ */
diff --git a/usrp/host/lib/legacy/usrp_dbid.dat b/usrp/host/lib/legacy/usrp_dbid.dat
deleted file mode 100644 (file)
index bd7fd7e..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-#
-# Copyright 2005,2009 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.
-#
-
-# This file is used to generate usrp_dbid.h, usrp_dbid.cc and usrp_dbid.py
-
-"Basic Tx"             0x0000
-"Basic Rx"             0x0001
-"DBS Rx"               0x0002
-"TV Rx"                        0x0003
-
-"Flex 400 Rx"          0x0004
-"Flex 900 Rx"          0x0005
-"Flex 1200 Rx"         0x0006
-"Flex 2400 Rx"         0x0007
-
-"Flex 400 Tx"          0x0008
-"Flex 900 Tx"          0x0009
-"Flex 1200 Tx"         0x000a
-"Flex 2400 Tx"         0x000b
-
-"TV Rx Rev 2"          0x000c
-"DBS Rx ClkMod"                0x000d
-
-"LF Tx"                        0x000e
-"LF Rx"                        0x000f
-
-"Flex 400 Rx MIMO A"   0x0014
-"Flex 900 Rx MIMO A"   0x0015
-"Flex 1200 Rx MIMO A"  0x0016
-"Flex 2400 Rx MIMO A"  0x0017
-
-"Flex 400 Tx MIMO A"   0x0018
-"Flex 900 Tx MIMO A"   0x0019
-"Flex 1200 Tx MIMO A"  0x001a
-"Flex 2400 Tx MIMO A"  0x001b
-
-"Flex 400 Rx MIMO B"   0x0024
-"Flex 900 Rx MIMO B"   0x0025
-"Flex 1200 Rx MIMO B"  0x0026
-"Flex 2400 Rx MIMO B"  0x0027
-
-"Flex 400 Tx MIMO B"   0x0028
-"Flex 900 Tx MIMO B"   0x0029
-"Flex 1200 Tx MIMO B"  0x002a
-"Flex 2400 Tx MIMO B"  0x002b
-
-"Flex 1800 Rx"         0x0030
-"Flex 1800 Tx"         0x0031
-"Flex 1800 Rx MIMO A"  0x0032
-"Flex 1800 Tx MIMO A"  0x0033
-"Flex 1800 Rx MIMO B"  0x0034
-"Flex 1800 Tx MIMO B"  0x0035
-
-"TV Rx Rev 3"          0x0040
-"DTT754"               0x0041
-"DTT768"               0x0042
-
-"WBX LO TX"            0x0050
-"WBX LO RX"            0x0051
-
-"XCVR2450 Tx"          0x0060
-"XCVR2450 Rx"          0x0061
-
-"Experimental Tx"      0xfffe
-"Experimental Rx"      0xffff
diff --git a/usrp/host/lib/legacy/usrp_local_sighandler.cc b/usrp/host/lib/legacy/usrp_local_sighandler.cc
deleted file mode 100644 (file)
index 69cde0b..0000000
+++ /dev/null
@@ -1,191 +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.
- */
-
-/*
- * This is actually the same as gr_local_signhandler, but with a different name.
- * We don't have a common library to put this in, so...
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <usrp_local_sighandler.h>
-#include <stdexcept>
-#include <stdio.h>
-#include <string.h>
-
-usrp_local_sighandler::usrp_local_sighandler (int signum,
-                                             void (*new_handler)(int))
-  : d_signum (signum)
-{
-#ifdef HAVE_SIGACTION
-  struct sigaction new_action;
-  memset (&new_action, 0, sizeof (new_action));
-
-  new_action.sa_handler = new_handler;
-  sigemptyset (&new_action.sa_mask);
-  new_action.sa_flags = 0;
-
-  if (sigaction (d_signum, &new_action, &d_old_action) < 0){
-    perror ("sigaction (install new)");
-    throw std::runtime_error ("sigaction");
-  }
-#endif
-}
-
-usrp_local_sighandler::~usrp_local_sighandler ()
-{
-#ifdef HAVE_SIGACTION
-  if (sigaction (d_signum, &d_old_action, 0) < 0){
-    perror ("sigaction (restore old)");
-    throw std::runtime_error ("sigaction");
-  }
-#endif
-}
-
-void
-usrp_local_sighandler::throw_signal(int signum) throw(usrp_signal)
-{
-  throw usrp_signal (signum);
-}
-
-/*
- * Semi-hideous way to may a signal number into a signal name
- */
-
-#define SIGNAME(x) case x: return #x
-
-std::string
-usrp_signal::name () const
-{
-  char tmp[128];
-
-  switch (signal ()){
-#ifdef SIGHUP
-    SIGNAME (SIGHUP);
-#endif
-#ifdef SIGINT
-    SIGNAME (SIGINT);
-#endif
-#ifdef SIGQUIT
-    SIGNAME (SIGQUIT);
-#endif
-#ifdef SIGILL
-    SIGNAME (SIGILL);
-#endif
-#ifdef SIGTRAP
-    SIGNAME (SIGTRAP);
-#endif
-#ifdef SIGABRT
-    SIGNAME (SIGABRT);
-#endif
-#ifdef SIGBUS
-    SIGNAME (SIGBUS);
-#endif
-#ifdef SIGFPE
-    SIGNAME (SIGFPE);
-#endif
-#ifdef SIGKILL
-    SIGNAME (SIGKILL);
-#endif
-#ifdef SIGUSR1
-    SIGNAME (SIGUSR1);
-#endif
-#ifdef SIGSEGV
-    SIGNAME (SIGSEGV);
-#endif
-#ifdef SIGUSR2
-    SIGNAME (SIGUSR2);
-#endif
-#ifdef SIGPIPE
-    SIGNAME (SIGPIPE);
-#endif
-#ifdef SIGALRM
-    SIGNAME (SIGALRM);
-#endif
-#ifdef SIGTERM
-    SIGNAME (SIGTERM);
-#endif
-#ifdef SIGSTKFLT
-    SIGNAME (SIGSTKFLT);
-#endif
-#ifdef SIGCHLD
-    SIGNAME (SIGCHLD);
-#endif
-#ifdef SIGCONT
-    SIGNAME (SIGCONT);
-#endif
-#ifdef SIGSTOP
-    SIGNAME (SIGSTOP);
-#endif
-#ifdef SIGTSTP
-    SIGNAME (SIGTSTP);
-#endif
-#ifdef SIGTTIN
-    SIGNAME (SIGTTIN);
-#endif
-#ifdef SIGTTOU
-    SIGNAME (SIGTTOU);
-#endif
-#ifdef SIGURG
-    SIGNAME (SIGURG);
-#endif
-#ifdef SIGXCPU
-    SIGNAME (SIGXCPU);
-#endif
-#ifdef SIGXFSZ
-    SIGNAME (SIGXFSZ);
-#endif
-#ifdef SIGVTALRM
-    SIGNAME (SIGVTALRM);
-#endif
-#ifdef SIGPROF
-    SIGNAME (SIGPROF);
-#endif
-#ifdef SIGWINCH
-    SIGNAME (SIGWINCH);
-#endif
-#ifdef SIGIO
-    SIGNAME (SIGIO);
-#endif
-#ifdef SIGPWR
-    SIGNAME (SIGPWR);
-#endif
-#ifdef SIGSYS
-    SIGNAME (SIGSYS);
-#endif
-  default:
-#if defined (HAVE_SNPRINTF)
-#if defined (SIGRTMIN) && defined (SIGRTMAX) 
-    if (signal () >= SIGRTMIN && signal () <= SIGRTMAX){
-      snprintf (tmp, sizeof (tmp), "SIGRTMIN + %d", signal ());
-      return tmp;
-    }
-#endif
-    snprintf (tmp, sizeof (tmp), "SIGNAL %d", signal ());
-    return tmp;
-#else
-    return "Unknown signal";
-#endif
-  }
-}
diff --git a/usrp/host/lib/legacy/usrp_local_sighandler.h b/usrp/host/lib/legacy/usrp_local_sighandler.h
deleted file mode 100644 (file)
index ee33675..0000000
+++ /dev/null
@@ -1,61 +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.
- */
-
-#ifndef INCLUDED_USRP_LOCAL_SIGHANDLER_H
-#define INCLUDED_USRP_LOCAL_SIGHANDLER_H
-
-#include <signal.h>
-#include <string>
-
-/*!
- * \brief Representation of signal.
- */
-class usrp_signal
-{
-  int  d_signum;
-public:
-  usrp_signal (int signum) : d_signum (signum) {}
-  int signal () const { return d_signum; }
-  std::string name () const;
-};
-
-
-/*!
- * \brief Get and set signal handler.
- *
- * Constructor installs new handler, destructor reinstalls
- * original value.
- */
-class usrp_local_sighandler {
-  int                  d_signum;
-#ifdef HAVE_SIGACTION
-  struct sigaction     d_old_action;
-#endif
-public:
-  usrp_local_sighandler (int signum, void (*new_handler)(int));
-  ~usrp_local_sighandler ();
-
-  /* throw usrp_signal (signum) */
-  static void throw_signal (int signum) throw (usrp_signal);
-};
-
-#endif /* INCLUDED_USRP_LOCAL_SIGHANDLER_H */
diff --git a/usrp/host/lib/legacy/usrp_prims.cc b/usrp/host/lib/legacy/usrp_prims.cc
deleted file mode 100644 (file)
index c2f74f5..0000000
+++ /dev/null
@@ -1,1357 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003,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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "usrp_prims.h"
-#include "usrp_commands.h"
-#include "usrp_ids.h"
-#include "usrp_i2c_addr.h"
-#include "fpga_regs_common.h"
-#include "fpga_regs_standard.h"
-#include <usb.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <time.h>              // FIXME should check with autoconf (nanosleep)
-#include <algorithm>
-#include <ad9862.h>
-#include <assert.h>
-
-extern "C" {
-#include "md5.h"
-};
-
-#define VERBOSE 0
-
-using namespace ad9862;
-
-static const int FIRMWARE_HASH_SLOT    = 0;
-static const int FPGA_HASH_SLOT        = 1;
-
-static const int hash_slot_addr[2] = {
-  USRP_HASH_SLOT_0_ADDR,
-  USRP_HASH_SLOT_1_ADDR
-};
-
-static const char *default_firmware_filename = "std.ihx";
-static const char *default_fpga_filename     = "std_2rxhb_2tx.rbf";
-
-#include "std_paths.h"
-#include <stdio.h>
-
-static char *
-find_file (const char *filename, int hw_rev)
-{
-  const char **sp = std_paths;
-  static char path[1000];
-  char *s;
-
-  s = getenv("USRP_PATH");
-  if (s) {
-    snprintf (path, sizeof (path), "%s/rev%d/%s", s, hw_rev, filename);
-    if (access (path, R_OK) == 0)
-      return path;
-  }
-
-  while (*sp){
-    snprintf (path, sizeof (path), "%s/rev%d/%s", *sp, hw_rev, filename);
-    if (access (path, R_OK) == 0)
-      return path;
-    sp++;
-  }
-  return 0;
-}
-
-static const char *
-get_proto_filename(const std::string user_filename, const char *env_var, const char *def)
-{
-  if (user_filename.length() != 0)
-    return user_filename.c_str();
-
-  char *s = getenv(env_var);
-  if (s && *s)
-    return s;
-
-  return def;
-}
-
-
-static void power_down_9862s (struct usb_dev_handle *udh);
-
-void
-usrp_one_time_init ()
-{
-  static bool first = true;
-
-  if (first){
-    first = false;
-    usb_init ();                       // usb library init
-    usb_find_busses ();
-    usb_find_devices ();
-  }
-}
-
-void
-usrp_rescan ()
-{
-  usb_find_busses ();
-  usb_find_devices ();
-}
-
-
-// ----------------------------------------------------------------
-// Danger, big, fragile KLUDGE.  The problem is that we want to be
-// able to get from a usb_dev_handle back to a usb_device, and the
-// right way to do this is buried in a non-installed include file.
-
-static struct usb_device *
-dev_handle_to_dev (usb_dev_handle *udh)
-{
-  struct usb_dev_handle_kludge {
-    int                         fd;
-    struct usb_bus     *bus;
-    struct usb_device  *device;
-  };
-
-  return ((struct usb_dev_handle_kludge *) udh)->device;
-}
-
-// ----------------------------------------------------------------
-
-/*
- * q must be a real USRP, not an FX2.  Return its hardware rev number.
- */
-int
-usrp_hw_rev (struct usb_device *q)
-{
-  return q->descriptor.bcdDevice & 0x00FF;
-}
-
-/*
- * q must be a real USRP, not an FX2.  Return true if it's configured.
- */
-static bool
-_usrp_configured_p (struct usb_device *q)
-{
-  return (q->descriptor.bcdDevice & 0xFF00) != 0;
-}
-
-bool
-usrp_usrp_p (struct usb_device *q)
-{
-  return (q->descriptor.idVendor == USB_VID_FSF
-         && q->descriptor.idProduct == USB_PID_FSF_USRP);
-}
-
-bool
-usrp_fx2_p (struct usb_device *q)
-{
-  return (q->descriptor.idVendor == USB_VID_CYPRESS
-         && q->descriptor.idProduct == USB_PID_CYPRESS_FX2);
-}
-
-bool
-usrp_usrp0_p (struct usb_device *q)
-{
-  return usrp_usrp_p (q) && usrp_hw_rev (q) == 0;
-}
-
-bool
-usrp_usrp1_p (struct usb_device *q)
-{
-  return usrp_usrp_p (q) && usrp_hw_rev (q) == 1;
-}
-
-bool
-usrp_usrp2_p (struct usb_device *q)
-{
-  return usrp_usrp_p (q) && usrp_hw_rev (q) == 2;
-}
-
-
-bool
-usrp_unconfigured_usrp_p (struct usb_device *q)
-{
-  return usrp_usrp_p (q) && !_usrp_configured_p (q);
-}
-
-bool
-usrp_configured_usrp_p (struct usb_device *q)
-{
-  return usrp_usrp_p (q) && _usrp_configured_p (q);
-}
-
-// ----------------------------------------------------------------
-
-struct usb_device *
-usrp_find_device (int nth, bool fx2_ok_p)
-{
-  struct usb_bus *p;
-  struct usb_device *q;
-  int   n_found = 0;
-
-  usrp_one_time_init ();
-  
-  p = usb_get_busses();
-  while (p != NULL){
-    q = p->devices;
-    while (q != NULL){
-      if (usrp_usrp_p (q) || (fx2_ok_p && usrp_fx2_p (q))){
-       if (n_found == nth)     // return this one
-         return q;
-       n_found++;              // keep looking
-      }
-      q = q->next;
-    }
-    p = p->next;
-  }
-  return 0;    // not found
-}
-
-static struct usb_dev_handle *
-usrp_open_interface (struct usb_device *dev, int interface, int altinterface)
-{
-  struct usb_dev_handle *udh = usb_open (dev);
-  if (udh == 0)
-    return 0;
-
-  if (dev != dev_handle_to_dev (udh)){
-    fprintf (stderr, "%s:%d: internal error!\n", __FILE__, __LINE__);
-    abort ();
-  }
-
-#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
-  // There's no get get_configuration function, and with some of the newer kernels
-  // setting the configuration, even if to the same value, hoses any other processes
-  // that have it open.  Hence we opt to not set it at all (We've only
-  // got a single configuration anyway).  This may hose the win32 stuff...
-
-  // Appears to be required for libusb-win32 and Cygwin -- dew 09/20/06
-  if (usb_set_configuration (udh, 1) < 0){
-    /*
-     * Ignore this error.  
-     *
-     * Seems that something changed in drivers/usb/core/devio.c:proc_setconfig such that
-     * it returns -EBUSY if _any_ of the interfaces of a device are open.
-     * We've only got a single configuration, so setting it doesn't even seem
-     * like it should be required.
-     */
-  }
-#endif
-
-  if (usb_claim_interface (udh, interface) < 0){
-    fprintf (stderr, "%s:usb_claim_interface: failed interface %d\n", __FUNCTION__,interface);
-    fprintf (stderr, "%s\n", usb_strerror());
-    usb_close (udh);
-    return 0;
-  }
-
-  if (usb_set_altinterface (udh, altinterface) < 0){
-    fprintf (stderr, "%s:usb_set_alt_interface: failed\n", __FUNCTION__);
-    fprintf (stderr, "%s\n", usb_strerror());
-    usb_release_interface (udh, interface);
-    usb_close (udh);
-    return 0;
-  }
-
-  return udh;
-}
-
-struct usb_dev_handle *
-usrp_open_cmd_interface (struct usb_device *dev)
-{
-  return usrp_open_interface (dev, USRP_CMD_INTERFACE, USRP_CMD_ALTINTERFACE);
-}
-
-struct usb_dev_handle *
-usrp_open_rx_interface (struct usb_device *dev)
-{
-  return usrp_open_interface (dev, USRP_RX_INTERFACE, USRP_RX_ALTINTERFACE);
-}
-
-struct usb_dev_handle *
-usrp_open_tx_interface (struct usb_device *dev)
-{
-  return usrp_open_interface (dev, USRP_TX_INTERFACE, USRP_TX_ALTINTERFACE);
-}
-
-bool
-usrp_close_interface (struct usb_dev_handle *udh)
-{
-  // we're assuming that closing an interface automatically releases it.
-  return usb_close (udh) == 0;
-}
-
-// ----------------------------------------------------------------
-// write internal ram using Cypress vendor extension
-
-static bool
-write_internal_ram (struct usb_dev_handle *udh, unsigned char *buf,
-                   int start_addr, size_t len)
-{
-  int addr;
-  int n;
-  int a;
-  int quanta = MAX_EP0_PKTSIZE;
-
-  for (addr = start_addr; addr < start_addr + (int) len; addr += quanta){
-    n = len + start_addr - addr;
-    if (n > quanta)
-      n = quanta;
-
-    a = usb_control_msg (udh, 0x40, 0xA0,
-                        addr, 0, (char *)(buf + (addr - start_addr)), n, 1000);
-
-    if (a < 0){
-      fprintf(stderr,"write_internal_ram failed: %s\n", usb_strerror());
-      return false;
-    }
-  }
-  return true;
-}
-
-// ----------------------------------------------------------------
-// whack the CPUCS register using the upload RAM vendor extension
-
-static bool
-reset_cpu (struct usb_dev_handle *udh, bool reset_p)
-{
-  unsigned char v;
-
-  if (reset_p)
-    v = 1;             // hold processor in reset
-  else
-    v = 0;             // release reset
-
-  return write_internal_ram (udh, &v, 0xE600, 1);
-}
-
-// ----------------------------------------------------------------
-// Load intel format file into cypress FX2 (8051)
-
-static bool
-_usrp_load_firmware (struct usb_dev_handle *udh, const char *filename,
-                    unsigned char hash[USRP_HASH_SIZE])
-{
-  FILE *f = fopen (filename, "ra");
-  if (f == 0){
-    perror (filename);
-    return false;
-  }
-
-  if (!reset_cpu (udh, true))  // hold CPU in reset while loading firmware
-    goto fail;
-
-  
-  char s[1024];
-  int length;
-  int addr;
-  int type;
-  unsigned char data[256];
-  unsigned char checksum, a;
-  unsigned int b;
-  int i;
-
-  while (!feof(f)){
-    fgets(s, sizeof (s), f); /* we should not use more than 263 bytes normally */
-    if(s[0]!=':'){
-      fprintf(stderr,"%s: invalid line: \"%s\"\n", filename, s);
-      goto fail;
-    }
-    sscanf(s+1, "%02x", &length);
-    sscanf(s+3, "%04x", &addr);
-    sscanf(s+7, "%02x", &type);
-
-    if(type==0){
-
-      a=length+(addr &0xff)+(addr>>8)+type;
-      for(i=0;i<length;i++){
-       sscanf (s+9+i*2,"%02x", &b);
-       data[i]=b;
-       a=a+data[i];
-      }
-
-      sscanf (s+9+length*2,"%02x", &b);
-      checksum=b;
-      if (((a+checksum)&0xff)!=0x00){
-       fprintf (stderr, "  ** Checksum failed: got 0x%02x versus 0x%02x\n", (-a)&0xff, checksum);
-       goto fail;
-      }
-      if (!write_internal_ram (udh, data, addr, length))
-       goto fail;
-    }
-    else if (type == 0x01){      // EOF
-      break;
-    }
-    else if (type == 0x02){
-      fprintf(stderr, "Extended address: whatever I do with it?\n");
-      fprintf (stderr, "%s: invalid line: \"%s\"\n", filename, s);
-      goto fail;
-    }
-  }
-
-  // we jam the hash value into the FX2 memory before letting
-  // the cpu out of reset.  When it comes out of reset it
-  // may renumerate which will invalidate udh.
-
-  if (!usrp_set_hash (udh, FIRMWARE_HASH_SLOT, hash))
-    fprintf (stderr, "usrp: failed to write firmware hash slot\n");
-
-  if (!reset_cpu (udh, false))         // take CPU out of reset
-    goto fail;
-
-  fclose (f);
-  return true;
-
- fail:
-  fclose (f);
-  return false;
-}
-
-// ----------------------------------------------------------------
-// write vendor extension command to USRP
-
-static int
-write_cmd (struct usb_dev_handle *udh,
-          int request, int value, int index,
-          unsigned char *bytes, int len)
-{
-  int  requesttype = (request & 0x80) ? VRT_VENDOR_IN : VRT_VENDOR_OUT;
-
-  int r = usb_control_msg (udh, requesttype, request, value, index,
-                          (char *) bytes, len, 1000);
-  if (r < 0){
-    // we get EPIPE if the firmware stalls the endpoint.
-    if (errno != EPIPE)
-      fprintf (stderr, "usb_control_msg failed: %s\n", usb_strerror ());
-  }
-
-  return r;
-}
-
-// ----------------------------------------------------------------
-// load fpga
-
-static bool
-_usrp_load_fpga (struct usb_dev_handle *udh, const char *filename,
-                unsigned char hash[USRP_HASH_SIZE])
-{
-  bool ok = true;
-
-  FILE *fp = fopen (filename, "rb");
-  if (fp == 0){
-    perror (filename);
-    return false;
-  }
-
-  unsigned char buf[MAX_EP0_PKTSIZE];  // 64 is max size of EP0 packet on FX2
-  int n;
-
-  usrp_set_led (udh, 1, 1);            // led 1 on
-
-
-  // reset FPGA (and on rev1 both AD9862's, thus killing clock)
-  usrp_set_fpga_reset (udh, 1);                // hold fpga in reset
-
-  if (write_cmd (udh, VRQ_FPGA_LOAD, 0, FL_BEGIN, 0, 0) != 0)
-    goto fail;
-  
-  while ((n = fread (buf, 1, sizeof (buf), fp)) > 0){
-    if (write_cmd (udh, VRQ_FPGA_LOAD, 0, FL_XFER, buf, n) != n)
-      goto fail;
-  }
-
-  if (write_cmd (udh, VRQ_FPGA_LOAD, 0, FL_END, 0, 0) != 0)
-    goto fail;
-  
-  fclose (fp);
-
-  if (!usrp_set_hash (udh, FPGA_HASH_SLOT, hash))
-    fprintf (stderr, "usrp: failed to write fpga hash slot\n");
-
-  // On the rev1 USRP, the {tx,rx}_{enable,reset} bits are
-  // controlled over the serial bus, and hence aren't observed until
-  // we've got a good fpga bitstream loaded.
-
-  usrp_set_fpga_reset (udh, 0);                // fpga out of master reset
-
-  // now these commands will work
-  
-  ok &= usrp_set_fpga_tx_enable (udh, 0);
-  ok &= usrp_set_fpga_rx_enable (udh, 0);
-
-  ok &= usrp_set_fpga_tx_reset (udh, 1);       // reset tx and rx paths
-  ok &= usrp_set_fpga_rx_reset (udh, 1);
-  ok &= usrp_set_fpga_tx_reset (udh, 0);       // reset tx and rx paths
-  ok &= usrp_set_fpga_rx_reset (udh, 0);
-
-  if (!ok)
-    fprintf (stderr, "usrp: failed to reset tx and/or rx path\n");
-
-  // Manually reset all regs except master control to zero.
-  // FIXME may want to remove this when we rework FPGA reset strategy.
-  // In the mean while, this gets us reproducible behavior.
-  for (int i = 0; i < FR_USER_0; i++){
-    if (i == FR_MASTER_CTRL)
-      continue;
-    usrp_write_fpga_reg(udh, i, 0);
-  }
-
-  power_down_9862s (udh);              // on the rev1, power these down!
-  usrp_set_led (udh, 1, 0);            // led 1 off
-
-  return true;
-
- fail:
-  power_down_9862s (udh);              // on the rev1, power these down!
-  fclose (fp);
-  return false;
-}
-
-// ----------------------------------------------------------------
-
-bool 
-usrp_set_led (struct usb_dev_handle *udh, int which, bool on)
-{
-  int r = write_cmd (udh, VRQ_SET_LED, on, which, 0, 0);
-
-  return r == 0;
-}
-
-bool
-usrp_set_hash (struct usb_dev_handle *udh, int which,
-              const unsigned char hash[USRP_HASH_SIZE])
-{
-  which &= 1;
-  
-  // we use the Cypress firmware down load command to jam it in.
-  int r = usb_control_msg (udh, 0x40, 0xa0, hash_slot_addr[which], 0,
-                          (char *) hash, USRP_HASH_SIZE, 1000);
-  return r == USRP_HASH_SIZE;
-}
-
-bool
-usrp_get_hash (struct usb_dev_handle *udh, int which, 
-              unsigned char hash[USRP_HASH_SIZE])
-{
-  which &= 1;
-  
-  // we use the Cypress firmware upload command to fetch it.
-  int r = usb_control_msg (udh, 0xc0, 0xa0, hash_slot_addr[which], 0,
-                          (char *) hash, USRP_HASH_SIZE, 1000);
-  return r == USRP_HASH_SIZE;
-}
-
-static bool
-usrp_set_switch (struct usb_dev_handle *udh, int cmd_byte, bool on)
-{
-  return write_cmd (udh, cmd_byte, on, 0, 0, 0) == 0;
-}
-
-
-static bool
-usrp1_fpga_write (struct usb_dev_handle *udh,
-                 int regno, int value)
-{
-  // on the rev1 usrp, we use the generic spi_write interface
-
-  unsigned char buf[4];
-
-  buf[0] = (value >> 24) & 0xff;       // MSB first
-  buf[1] = (value >> 16) & 0xff;
-  buf[2] = (value >>  8) & 0xff;
-  buf[3] = (value >>  0) & 0xff;
-  
-  return usrp_spi_write (udh, 0x00 | (regno & 0x7f),
-                        SPI_ENABLE_FPGA,
-                        SPI_FMT_MSB | SPI_FMT_HDR_1,
-                        buf, sizeof (buf));
-}
-
-static bool
-usrp1_fpga_read (struct usb_dev_handle *udh,
-                int regno, int *value)
-{
-  *value = 0;
-  unsigned char buf[4];
-
-  bool ok = usrp_spi_read (udh, 0x80 | (regno & 0x7f),
-                          SPI_ENABLE_FPGA,
-                          SPI_FMT_MSB | SPI_FMT_HDR_1,
-                          buf, sizeof (buf));
-
-  if (ok)
-    *value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
-
-  return ok;
-}
-
-
-bool
-usrp_write_fpga_reg (struct usb_dev_handle *udh, int reg, int value)
-{
-  switch (usrp_hw_rev (dev_handle_to_dev (udh))){
-  case 0:                      // not supported ;)
-    abort();   
-
-  default:
-    return usrp1_fpga_write (udh, reg, value);
-  }
-}
-
-bool
-usrp_read_fpga_reg (struct usb_dev_handle *udh, int reg, int *value)
-{
-  switch (usrp_hw_rev (dev_handle_to_dev (udh))){
-  case 0:              // not supported ;)
-    abort();
-    
-  default:
-    return usrp1_fpga_read (udh, reg, value);
-  }
-}
-
-bool 
-usrp_set_fpga_reset (struct usb_dev_handle *udh, bool on)
-{
-  return usrp_set_switch (udh, VRQ_FPGA_SET_RESET, on);
-}
-
-bool 
-usrp_set_fpga_tx_enable (struct usb_dev_handle *udh, bool on)
-{
-  return usrp_set_switch (udh, VRQ_FPGA_SET_TX_ENABLE, on);
-}
-
-bool 
-usrp_set_fpga_rx_enable (struct usb_dev_handle *udh, bool on)
-{
-  return usrp_set_switch (udh, VRQ_FPGA_SET_RX_ENABLE, on);
-}
-
-bool 
-usrp_set_fpga_tx_reset (struct usb_dev_handle *udh, bool on)
-{
-  return usrp_set_switch (udh, VRQ_FPGA_SET_TX_RESET, on);
-}
-
-bool 
-usrp_set_fpga_rx_reset (struct usb_dev_handle *udh, bool on)
-{
-  return usrp_set_switch (udh, VRQ_FPGA_SET_RX_RESET, on);
-}
-
-
-// ----------------------------------------------------------------
-// conditional load stuff
-
-static bool
-compute_hash (const char *filename, unsigned char hash[USRP_HASH_SIZE])
-{
-  assert (USRP_HASH_SIZE == 16);
-  memset (hash, 0, USRP_HASH_SIZE);
-
-  FILE *fp = fopen (filename, "rb");
-  if (fp == 0){
-    perror (filename);
-    return false;
-  }
-  int r = md5_stream (fp, hash);
-  fclose (fp);
-  
-  return r == 0;
-}
-
-static usrp_load_status_t
-usrp_conditionally_load_something (struct usb_dev_handle *udh,
-                                  const char *filename,
-                                  bool force,
-                                  int slot,
-                                  bool loader (struct usb_dev_handle *,
-                                               const char *,
-                                               unsigned char [USRP_HASH_SIZE]))
-{
-  unsigned char file_hash[USRP_HASH_SIZE];
-  unsigned char usrp_hash[USRP_HASH_SIZE];
-  
-  if (access (filename, R_OK) != 0){
-    perror (filename);
-    return ULS_ERROR;
-  }
-
-  if (!compute_hash (filename, file_hash))
-    return ULS_ERROR;
-
-  if (!force
-      && usrp_get_hash (udh, slot, usrp_hash)
-      && memcmp (file_hash, usrp_hash, USRP_HASH_SIZE) == 0)
-    return ULS_ALREADY_LOADED;
-
-  bool r = loader (udh, filename, file_hash);
-
-  if (!r)
-    return ULS_ERROR;
-
-  return ULS_OK;
-}
-
-usrp_load_status_t
-usrp_load_firmware (struct usb_dev_handle *udh,
-                   const char *filename,
-                   bool force)
-{
-  return usrp_conditionally_load_something (udh, filename, force,
-                                           FIRMWARE_HASH_SLOT,
-                                           _usrp_load_firmware);
-}
-
-usrp_load_status_t
-usrp_load_fpga (struct usb_dev_handle *udh,
-               const char *filename,
-               bool force)
-{
-  return usrp_conditionally_load_something (udh, filename, force,
-                                           FPGA_HASH_SLOT,
-                                           _usrp_load_fpga);
-}
-
-static usb_dev_handle *
-open_nth_cmd_interface (int nth)
-{
-  struct usb_device *udev = usrp_find_device (nth);
-  if (udev == 0){
-    fprintf (stderr, "usrp: failed to find usrp[%d]\n", nth);
-    return 0;
-  }
-
-  struct usb_dev_handle *udh;
-
-  udh = usrp_open_cmd_interface (udev);
-  if (udh == 0){
-    // FIXME this could be because somebody else has it open.
-    // We should delay and retry...
-    fprintf (stderr, "open_nth_cmd_interface: open_cmd_interface failed\n");
-    usb_strerror ();
-    return 0;
-  }
-
-  return udh;
- }
-
-static bool
-our_nanosleep (const struct timespec *delay)
-{
-  struct timespec      new_delay = *delay;
-  struct timespec      remainder;
-
-  while (1){
-    int r = nanosleep (&new_delay, &remainder);
-    if (r == 0)
-      return true;
-    if (errno == EINTR)
-      new_delay = remainder;
-    else {
-      perror ("nanosleep");
-      return false;
-    }
-  }
-}
-
-static bool
-mdelay (int millisecs)
-{
-  struct timespec      ts;
-  ts.tv_sec = millisecs / 1000;
-  ts.tv_nsec = (millisecs - (1000 * ts.tv_sec)) * 1000000;
-  return our_nanosleep (&ts);
-}
-
-usrp_load_status_t
-usrp_load_firmware_nth (int nth, const char *filename, bool force){
-  struct usb_dev_handle *udh = open_nth_cmd_interface (nth);
-  if (udh == 0)
-    return ULS_ERROR;
-
-  usrp_load_status_t s = usrp_load_firmware (udh, filename, force);
-  usrp_close_interface (udh);
-
-  switch (s){
-
-  case ULS_ALREADY_LOADED:             // nothing changed...
-    return ULS_ALREADY_LOADED;
-    break;
-
-  case ULS_OK:
-    // we loaded firmware successfully.
-
-    // It's highly likely that the board will renumerate (simulate a
-    // disconnect/reconnect sequence), invalidating our current
-    // handle.
-
-    // FIXME.  Turn this into a loop that rescans until we refind ourselves
-    
-    struct timespec    t;      // delay for 1 second
-    t.tv_sec = 2;
-    t.tv_nsec = 0;
-    our_nanosleep (&t);
-
-    usb_find_busses ();                // rescan busses and devices
-    usb_find_devices ();
-
-    return ULS_OK;
-
-  default:
-  case ULS_ERROR:              // some kind of problem
-    return ULS_ERROR;
-  }
-}
-
-static void
-load_status_msg (usrp_load_status_t s, const char *type, const char *filename)
-{
-  char *e = getenv("USRP_VERBOSE");
-  bool verbose = e != 0;
-  
-  switch (s){
-  case ULS_ERROR:
-    fprintf (stderr, "usrp: failed to load %s %s.\n", type, filename);
-    break;
-    
-  case ULS_ALREADY_LOADED:
-    if (verbose)
-      fprintf (stderr, "usrp: %s %s already loaded.\n", type, filename);
-    break;
-
-  case ULS_OK:
-    if (verbose)
-      fprintf (stderr, "usrp: %s %s loaded successfully.\n", type, filename);
-    break;
-  }
-}
-
-bool
-usrp_load_standard_bits (int nth, bool force,
-                        const std::string fpga_filename,
-                        const std::string firmware_filename)
-{
-  usrp_load_status_t   s;
-  const char           *filename;
-  const char           *proto_filename;
-  int hw_rev;
-
-  // first, figure out what hardware rev we're dealing with
-  {
-    struct usb_device *udev = usrp_find_device (nth);
-    if (udev == 0){
-      fprintf (stderr, "usrp: failed to find usrp[%d]\n", nth);
-      return false;
-    }
-    hw_rev = usrp_hw_rev (udev);
-  }
-
-  // start by loading the firmware
-
-  proto_filename = get_proto_filename(firmware_filename, "USRP_FIRMWARE",
-                                     default_firmware_filename);
-  filename = find_file(proto_filename, hw_rev);
-  if (filename == 0){
-    fprintf (stderr, "Can't find firmware: %s\n", proto_filename);
-    return false;
-  }
-
-  s = usrp_load_firmware_nth (nth, filename, force);
-  load_status_msg (s, "firmware", filename);
-
-  if (s == ULS_ERROR)
-    return false;
-
-  // if we actually loaded firmware, we must reload fpga ...
-  if (s == ULS_OK)
-    force = true;
-
-  // now move on to the fpga configuration bitstream
-
-  proto_filename = get_proto_filename(fpga_filename, "USRP_FPGA",
-                                     default_fpga_filename);
-  filename = find_file (proto_filename, hw_rev);
-  if (filename == 0){
-    fprintf (stderr, "Can't find fpga bitstream: %s\n", proto_filename);
-    return false;
-  }
-
-  struct usb_dev_handle *udh = open_nth_cmd_interface (nth);
-  if (udh == 0)
-    return false;
-  
-  s = usrp_load_fpga (udh, filename, force);
-  usrp_close_interface (udh);
-  load_status_msg (s, "fpga bitstream", filename);
-
-  if (s == ULS_ERROR)
-    return false;
-
-  return true;
-}
-
-bool
-_usrp_get_status (struct usb_dev_handle *udh, int which, bool *trouble)
-{
-  unsigned char        status;
-  *trouble = true;
-  
-  if (write_cmd (udh, VRQ_GET_STATUS, 0, which,
-                &status, sizeof (status)) != sizeof (status))
-    return false;
-
-  *trouble = status;
-  return true;
-}
-
-bool
-usrp_check_rx_overrun (struct usb_dev_handle *udh, bool *overrun_p)
-{
-  return _usrp_get_status (udh, GS_RX_OVERRUN, overrun_p);
-}
-
-bool
-usrp_check_tx_underrun (struct usb_dev_handle *udh, bool *underrun_p)
-{
-  return _usrp_get_status (udh, GS_TX_UNDERRUN, underrun_p);
-}
-
-
-bool
-usrp_i2c_write (struct usb_dev_handle *udh, int i2c_addr,
-               const void *buf, int len)
-{
-  if (len < 1 || len > MAX_EP0_PKTSIZE)
-    return false;
-
-  return write_cmd (udh, VRQ_I2C_WRITE, i2c_addr, 0,
-                   (unsigned char *) buf, len) == len;
-}
-
-
-bool
-usrp_i2c_read (struct usb_dev_handle *udh, int i2c_addr,
-              void *buf, int len)
-{
-  if (len < 1 || len > MAX_EP0_PKTSIZE)
-    return false;
-
-  return write_cmd (udh, VRQ_I2C_READ, i2c_addr, 0,
-                   (unsigned char *) buf, len) == len;
-}
-
-bool
-usrp_spi_write (struct usb_dev_handle *udh,
-               int optional_header, int enables, int format,
-               const void *buf, int len)
-{
-  if (len < 0 || len > MAX_EP0_PKTSIZE)
-    return false;
-
-  return write_cmd (udh, VRQ_SPI_WRITE,
-                   optional_header,
-                   ((enables & 0xff) << 8) | (format & 0xff),
-                   (unsigned char *) buf, len) == len;
-}
-
-
-bool
-usrp_spi_read (struct usb_dev_handle *udh,
-              int optional_header, int enables, int format,
-              void *buf, int len)
-{
-  if (len < 0 || len > MAX_EP0_PKTSIZE)
-    return false;
-
-  return write_cmd (udh, VRQ_SPI_READ,
-                   optional_header,
-                   ((enables & 0xff) << 8) | (format & 0xff),
-                   (unsigned char *) buf, len) == len;
-}
-
-bool
-usrp_9862_write (struct usb_dev_handle *udh, int which_codec,
-                int regno, int value)
-{
-  if (0)
-    fprintf (stderr, "usrp_9862_write which = %d, reg = %2d, val = %3d (0x%02x)\n",
-            which_codec, regno, value, value);
-
-  unsigned char buf[1];
-
-  buf[0] = value;
-  
-  return usrp_spi_write (udh, 0x00 | (regno & 0x3f),
-                        which_codec == 0 ? SPI_ENABLE_CODEC_A : SPI_ENABLE_CODEC_B,
-                        SPI_FMT_MSB | SPI_FMT_HDR_1,
-                        buf, 1);
-}
-
-bool
-usrp_9862_read (struct usb_dev_handle *udh, int which_codec,
-               int regno, unsigned char *value)
-{
-  return usrp_spi_read (udh, 0x80 | (regno & 0x3f),
-                       which_codec == 0 ? SPI_ENABLE_CODEC_A : SPI_ENABLE_CODEC_B,
-                       SPI_FMT_MSB | SPI_FMT_HDR_1,
-                       value, 1);
-}
-
-bool
-usrp_9862_write_many (struct usb_dev_handle *udh,
-                     int which_codec,
-                     const unsigned char *buf,
-                     int len)
-{
-  if (len & 0x1)
-    return false;              // must be even
-
-  bool result = true;
-
-  while (len > 0){
-    result &= usrp_9862_write (udh, which_codec, buf[0], buf[1]);
-    len -= 2;
-    buf += 2;
-  }
-
-  return result;
-}
-
-
-bool
-usrp_9862_write_many_all (struct usb_dev_handle *udh,
-                          const unsigned char *buf, int len)
-{
-  // FIXME handle 2/2 and 4/4 versions
-
-  bool result;
-  result  = usrp_9862_write_many (udh, 0, buf, len);
-  result &= usrp_9862_write_many (udh, 1, buf, len);
-  return result;
-}
-
-static void
-power_down_9862s (struct usb_dev_handle *udh)
-{
-  static const unsigned char regs[] = {
-    REG_RX_PWR_DN,     0x01,                   // everything
-    REG_TX_PWR_DN,     0x0f,                   // pwr dn digital and analog_both
-    REG_TX_MODULATOR,  0x00                    // coarse & fine modulators disabled
-  };
-
-  switch (usrp_hw_rev (dev_handle_to_dev (udh))){
-  case 0:
-    break;
-
-  default:
-    usrp_9862_write_many_all (udh, regs, sizeof (regs));
-    break;
-  }
-}
-
-
-
-static const int EEPROM_PAGESIZE = 16;
-
-bool
-usrp_eeprom_write (struct usb_dev_handle *udh, int i2c_addr,
-                  int eeprom_offset, const void *buf, int len)
-{
-  unsigned char cmd[2];
-  const unsigned char *p = (unsigned char *) buf;
-  
-  // The simplest thing that could possibly work:
-  //   all writes are single byte writes.
-  //
-  // We could speed this up using the page write feature,
-  // but we write so infrequently, why bother...
-
-  while (len-- > 0){
-    cmd[0] = eeprom_offset++;
-    cmd[1] = *p++;
-    bool r = usrp_i2c_write (udh, i2c_addr, cmd, sizeof (cmd));
-    mdelay (10);               // delay 10ms worst case write time
-    if (!r)
-      return false;
-  }
-  
-  return true;
-}
-
-bool
-usrp_eeprom_read (struct usb_dev_handle *udh, int i2c_addr,
-                 int eeprom_offset, void *buf, int len)
-{
-  unsigned char *p = (unsigned char *) buf;
-
-  // We setup a random read by first doing a "zero byte write".
-  // Writes carry an address.  Reads use an implicit address.
-
-  unsigned char cmd[1];
-  cmd[0] = eeprom_offset;
-  if (!usrp_i2c_write (udh, i2c_addr, cmd, sizeof (cmd)))
-    return false;
-
-  while (len > 0){
-    int n = std::min (len, MAX_EP0_PKTSIZE);
-    if (!usrp_i2c_read (udh, i2c_addr, p, n))
-      return false;
-    len -= n;
-    p += n;
-  }
-  return true;
-}
-// ----------------------------------------------------------------
-
-static bool
-slot_to_codec (int slot, int *which_codec)
-{
-  *which_codec = 0;
-  
-  switch (slot){
-  case SLOT_TX_A:
-  case SLOT_RX_A:
-    *which_codec = 0;
-    break;
-
-  case SLOT_TX_B:
-  case SLOT_RX_B:
-    *which_codec = 1;
-    break;
-
-  default:
-    fprintf (stderr, "usrp_prims:slot_to_codec: invalid slot = %d\n", slot);
-    return false;
-  }
-  return true;
-}
-
-static bool
-tx_slot_p (int slot)
-{
-  switch (slot){
-  case SLOT_TX_A:
-  case SLOT_TX_B:
-    return true;
-
-  default:
-    return false;
-  }
-}
-
-bool
-usrp_write_aux_dac (struct usb_dev_handle *udh, int slot,
-                   int which_dac, int value)
-{
-  int which_codec;
-  
-  if (!slot_to_codec (slot, &which_codec))
-    return false;
-
-  if (!(0 <= which_dac && which_dac < 4)){
-    fprintf (stderr, "usrp_write_aux_dac: invalid dac = %d\n", which_dac);
-    return false;
-  }
-
-  value &= 0x0fff;     // mask to 12-bits
-  
-  if (which_dac == 3){
-    // dac 3 is really 12-bits.  Use value as is.
-    bool r = true;
-    r &= usrp_9862_write (udh, which_codec, 43, (value >> 4));       // most sig
-    r &= usrp_9862_write (udh, which_codec, 42, (value & 0xf) << 4); // least sig
-    return r;
-  }
-  else {
-    // dac 0, 1, and 2 are really 8 bits.  
-    value = value >> 4;                // shift value appropriately
-    return usrp_9862_write (udh, which_codec, 36 + which_dac, value);
-  }
-}
-
-
-bool
-usrp_read_aux_adc (struct usb_dev_handle *udh, int slot,
-                  int which_adc, int *value)
-{
-  *value = 0;
-  int  which_codec;
-
-  if (!slot_to_codec (slot, &which_codec))
-    return false;
-
-  if (!(0 <= which_codec && which_codec < 2)){
-    fprintf (stderr, "usrp_read_aux_adc: invalid adc = %d\n", which_adc);
-    return false;
-  }
-
-  unsigned char aux_adc_control =
-    AUX_ADC_CTRL_REFSEL_A              // on chip reference
-    | AUX_ADC_CTRL_REFSEL_B;           // on chip reference
-
-  int  rd_reg = 26;    // base address of two regs to read for result
-  
-  // program the ADC mux bits
-  if (tx_slot_p (slot))
-    aux_adc_control |= AUX_ADC_CTRL_SELECT_A2 | AUX_ADC_CTRL_SELECT_B2;
-  else {
-    rd_reg += 2;
-    aux_adc_control |= AUX_ADC_CTRL_SELECT_A1 | AUX_ADC_CTRL_SELECT_B1;
-  }
-  
-  // I'm not sure if we can set the mux and issue a start conversion
-  // in the same cycle, so let's do them one at a time.
-
-  usrp_9862_write (udh, which_codec, 34, aux_adc_control);
-
-  if (which_adc == 0)
-    aux_adc_control |= AUX_ADC_CTRL_START_A;
-  else {
-    rd_reg += 4;
-    aux_adc_control |= AUX_ADC_CTRL_START_B;
-  }
-
-  // start the conversion
-  usrp_9862_write (udh, which_codec, 34, aux_adc_control);
-
-  // read the 10-bit result back
-  unsigned char v_lo = 0;
-  unsigned char v_hi = 0;
-  bool r = usrp_9862_read (udh, which_codec, rd_reg, &v_lo);
-  r &= usrp_9862_read (udh, which_codec, rd_reg + 1, &v_hi);
-
-  if (r)
-    *value = ((v_hi << 2) | ((v_lo >> 6) & 0x3)) << 2; // format as 12-bit
-  
-  return r;
-}
-
-// ----------------------------------------------------------------
-
-static int slot_to_i2c_addr (int slot)
-{
-  switch (slot){
-  case SLOT_TX_A:      return I2C_ADDR_TX_A;
-  case SLOT_RX_A:      return I2C_ADDR_RX_A;
-  case SLOT_TX_B:      return I2C_ADDR_TX_B;
-  case SLOT_RX_B:      return I2C_ADDR_RX_B;
-  default:             return -1;
-  }
-}
-
-static void
-set_chksum (unsigned char *buf)
-{
-  int sum = 0;
-  unsigned int i;
-  for (i = 0; i < DB_EEPROM_CLEN - 1; i++)
-    sum += buf[i];
-  buf[i] = -sum;
-}
-
-static usrp_dbeeprom_status_t
-read_dboard_eeprom (struct usb_dev_handle *udh,
-                   int slot_id, unsigned char *buf)
-{
-  int i2c_addr = slot_to_i2c_addr (slot_id);
-  if (i2c_addr == -1)
-    return UDBE_BAD_SLOT;
-
-  if (!usrp_eeprom_read (udh, i2c_addr, 0, buf, DB_EEPROM_CLEN))
-    return UDBE_NO_EEPROM;
-
-  if (buf[DB_EEPROM_MAGIC] != DB_EEPROM_MAGIC_VALUE)
-    return UDBE_INVALID_EEPROM;
-
-  int sum = 0;
-  for (unsigned int i = 0; i < DB_EEPROM_CLEN; i++)
-    sum += buf[i];
-
-  if ((sum & 0xff) != 0)
-    return UDBE_INVALID_EEPROM;
-
-  return UDBE_OK;
-}
-
-usrp_dbeeprom_status_t
-usrp_read_dboard_eeprom (struct usb_dev_handle *udh,
-                        int slot_id, usrp_dboard_eeprom *eeprom)
-{
-  unsigned char buf[DB_EEPROM_CLEN];
-
-  memset (eeprom, 0, sizeof (*eeprom));
-
-  usrp_dbeeprom_status_t s = read_dboard_eeprom (udh, slot_id, buf);
-  if (s != UDBE_OK)
-    return s;
-
-  eeprom->id = (buf[DB_EEPROM_ID_MSB] << 8) | buf[DB_EEPROM_ID_LSB];
-  eeprom->oe = (buf[DB_EEPROM_OE_MSB] << 8) | buf[DB_EEPROM_OE_LSB];
-  eeprom->offset[0] = (buf[DB_EEPROM_OFFSET_0_MSB] << 8) | buf[DB_EEPROM_OFFSET_0_LSB];
-  eeprom->offset[1] = (buf[DB_EEPROM_OFFSET_1_MSB] << 8) | buf[DB_EEPROM_OFFSET_1_LSB];
-
-  return UDBE_OK;
-}
-
-bool
-usrp_write_dboard_offsets (struct usb_dev_handle *udh, int slot_id,
-                          short offset0, short offset1)
-{
-  unsigned char buf[DB_EEPROM_CLEN];
-
-  usrp_dbeeprom_status_t s = read_dboard_eeprom (udh, slot_id, buf);
-  if (s != UDBE_OK)
-    return false;
-
-  buf[DB_EEPROM_OFFSET_0_LSB] = (offset0 >> 0) & 0xff;
-  buf[DB_EEPROM_OFFSET_0_MSB] = (offset0 >> 8) & 0xff;
-  buf[DB_EEPROM_OFFSET_1_LSB] = (offset1 >> 0) & 0xff;
-  buf[DB_EEPROM_OFFSET_1_MSB] = (offset1 >> 8) & 0xff;
-  set_chksum (buf);
-
-  return usrp_eeprom_write (udh, slot_to_i2c_addr (slot_id),
-                           0, buf, sizeof (buf));
-}
-
-std::string
-usrp_serial_number(struct usb_dev_handle *udh)
-{
-  unsigned char iserial = usb_device(udh)->descriptor.iSerialNumber;
-  if (iserial == 0)
-    return "";
-
-  char buf[1024];
-  if (usb_get_string_simple(udh, iserial, buf, sizeof(buf)) < 0)
-    return "";
-
-  return buf;
-}
diff --git a/usrp/host/lib/legacy/usrp_prims.h b/usrp/host/lib/legacy/usrp_prims.h
deleted file mode 100644 (file)
index aa13474..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003,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.
- */
-
-/*
- * Low level primitives for directly messing with USRP hardware.
- *
- * If you're trying to use the USRP, you'll probably want to take a look
- * at the usrp_rx and usrp_tx classes.  They hide a bunch of low level details
- * and provide high performance streaming i/o.
- *
- * This interface is built on top of libusb, which allegedly works under
- * Linux, *BSD and Mac OS/X.  http://libusb.sourceforge.net
- */
-
-#ifndef _USRP_PRIMS_H_
-#define _USRP_PRIMS_H_
-
-#include <usrp_slots.h>
-#include <string>
-
-static const int USRP_HASH_SIZE = 16;
-
-enum usrp_load_status_t { ULS_ERROR = 0, ULS_OK, ULS_ALREADY_LOADED };
-
-struct usb_dev_handle;
-struct usb_device;
-
-/*!
- * \brief initialize libusb; probe busses and devices.
- * Safe to call more than once.
- */
-void usrp_one_time_init ();
-
-/*
- * force a rescan of the buses and devices
- */
-void usrp_rescan ();
-
-/*!
- * \brief locate Nth (zero based) USRP device in system.
- * Return pointer or 0 if not found.
- *
- * The following kinds of devices are considered USRPs:
- *
- *   unconfigured USRP (no firwmare loaded)
- *   configured USRP (firmware loaded)
- *   unconfigured Cypress FX2 (only if fx2_ok_p is true)
- */
-struct usb_device *usrp_find_device (int nth, bool fx2_ok_p = false);
-
-bool usrp_usrp_p (struct usb_device *q);               //< is this a USRP
-bool usrp_usrp0_p (struct usb_device *q);              //< is this a USRP Rev 0
-bool usrp_usrp1_p (struct usb_device *q);              //< is this a USRP Rev 1
-bool usrp_usrp2_p (struct usb_device *q);              //< is this a USRP Rev 2
-int  usrp_hw_rev (struct usb_device *q);               //< return h/w rev code
-
-bool usrp_fx2_p (struct usb_device *q);                        //< is this an unconfigured Cypress FX2
-
-bool usrp_unconfigured_usrp_p (struct usb_device *q);  //< some kind of unconfigured USRP
-bool usrp_configured_usrp_p (struct usb_device *q);    //< some kind of configured USRP
-
-/*!
- * \brief given a usb_device return an instance of the appropriate usb_dev_handle
- *
- * These routines claim the specified interface and select the
- * correct alternate interface.  (USB nomenclature is totally screwed!)
- *
- * If interface can't be opened, or is already claimed by some other
- * process, 0 is returned.
- */
-struct usb_dev_handle *usrp_open_cmd_interface (struct usb_device *dev);
-struct usb_dev_handle *usrp_open_rx_interface (struct usb_device *dev);
-struct usb_dev_handle *usrp_open_tx_interface (struct usb_device *dev);
-
-/*!
- * \brief close interface.
- */
-bool usrp_close_interface (struct usb_dev_handle *udh);
-
-/*!
- * \brief load intel hex format file into USRP/Cypress FX2 (8051).
- *
- * The filename extension is typically *.ihx
- *
- * Note that loading firmware may cause the device to renumerate.  I.e.,
- * change its configuration, invalidating the current device handle.
- */
-
-usrp_load_status_t 
-usrp_load_firmware (struct usb_dev_handle *udh, const char *filename, bool force);
-
-/*!
- * \brief load intel hex format file into USRP FX2 (8051).
- *
- * The filename extension is typically *.ihx
- *
- * Note that loading firmware may cause the device to renumerate.  I.e.,
- * change its configuration, invalidating the current device handle.
- * If the result is ULS_OK, usrp_load_firmware_nth delays 1 second
- * then rescans the busses and devices.
- */
-usrp_load_status_t
-usrp_load_firmware_nth (int nth, const char *filename, bool force);
-
-/*!
- * \brief load fpga configuration bitstream
- */
-usrp_load_status_t
-usrp_load_fpga (struct usb_dev_handle *udh, const char *filename, bool force);
-
-/*!
- * \brief load the regular firmware and fpga bitstream in the Nth USRP.
- *
- * This is the normal starting point...
- */
-bool usrp_load_standard_bits (int nth, bool force,
-                             const std::string fpga_filename = "",
-                             const std::string firmware_filename = "");
-
-/*!
- * \brief copy the given \p hash into the USRP hash slot \p which.
- * The usrp implements two hash slots, 0 and 1.
- */
-bool usrp_set_hash (struct usb_dev_handle *udh, int which,
-                   const unsigned char hash[USRP_HASH_SIZE]);
-
-/*!
- * \brief retrieve the \p hash from the USRP hash slot \p which.
- * The usrp implements two hash slots, 0 and 1.
- */
-bool usrp_get_hash (struct usb_dev_handle *udh, int which,
-                   unsigned char hash[USRP_HASH_SIZE]);
-
-bool usrp_write_fpga_reg (struct usb_dev_handle *udh, int reg, int value);
-bool usrp_read_fpga_reg (struct usb_dev_handle *udh, int reg, int *value);
-bool usrp_set_fpga_reset (struct usb_dev_handle *udh, bool on);
-bool usrp_set_fpga_tx_enable (struct usb_dev_handle *udh, bool on);
-bool usrp_set_fpga_rx_enable (struct usb_dev_handle *udh, bool on);
-bool usrp_set_fpga_tx_reset (struct usb_dev_handle *udh, bool on);
-bool usrp_set_fpga_rx_reset (struct usb_dev_handle *udh, bool on);
-bool usrp_set_led (struct usb_dev_handle *udh, int which, bool on);
-
-bool usrp_check_rx_overrun (struct usb_dev_handle *udh, bool *overrun_p);
-bool usrp_check_tx_underrun (struct usb_dev_handle *udh, bool *underrun_p);
-
-// i2c_read and i2c_write are limited to a maximum len of 64 bytes.
-
-bool usrp_i2c_write (struct usb_dev_handle *udh, int i2c_addr,
-                    const void *buf, int len);
-
-bool usrp_i2c_read (struct usb_dev_handle *udh, int i2c_addr,
-                   void *buf, int len);
-
-// spi_read and spi_write are limited to a maximum of 64 bytes
-// See usrp_spi_defs.h for more info
-
-bool usrp_spi_write (struct usb_dev_handle *udh,
-                    int optional_header, int enables, int format,
-                    const void *buf, int len);
-
-bool usrp_spi_read (struct usb_dev_handle *udh,
-                    int optional_header, int enables, int format,
-                    void *buf, int len);
-
-
-bool usrp_9862_write (struct usb_dev_handle *udh,
-                     int which_codec,                  // [0,  1]
-                     int regno,                        // [0, 63]
-                     int value);                       // [0, 255]     
-
-bool usrp_9862_read (struct usb_dev_handle *udh,
-                    int which_codec,                   // [0,  1]
-                    int regno,                         // [0, 63]
-                    unsigned char *value);             // [0, 255]
-
-/*!
- * \brief Write multiple 9862 regs at once.
- *
- * \p buf contains alternating register_number, register_value pairs.
- * \p len must be even and is the length of buf in bytes.
- */
-bool usrp_9862_write_many (struct usb_dev_handle *udh, int which_codec,
-                          const unsigned char *buf, int len);
-                          
-
-/*!
- * \brief write specified regs to all 9862's in the system
- */
-bool usrp_9862_write_many_all (struct usb_dev_handle *udh,
-                              const unsigned char *buf, int len);
-                          
-
-// Write 24LC024 / 24LC025 EEPROM on motherboard or daughterboard.
-// Which EEPROM is determined by i2c_addr.  See i2c_addr.h
-
-bool usrp_eeprom_write (struct usb_dev_handle *udh, int i2c_addr,
-                       int eeprom_offset, const void *buf, int len);
-
-
-// Read 24LC024 / 24LC025 EEPROM on motherboard or daughterboard.
-// Which EEPROM is determined by i2c_addr.  See i2c_addr.h
-
-bool usrp_eeprom_read (struct usb_dev_handle *udh, int i2c_addr,
-                      int eeprom_offset, void *buf, int len);
-
-
-// Slot specific i/o routines
-
-/*!
- * \brief write to the specified aux dac.
- *
- * \p slot: which Tx or Rx slot to write.
- *    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
- *
- * \p which_dac: [0,3]  RX slots must use only 0 and 1.
- *                     TX slots must use only 2 and 3.
- *
- * AUX DAC 3 is really the 9862 sigma delta output.
- *
- * \p value to write to aux dac.  All dacs take straight
- * binary values.  Although dacs 0, 1 and 2 are 8-bit and dac 3 is 12-bit,
- * the interface is in terms of 12-bit values [0,4095]
- */
-bool usrp_write_aux_dac (struct usb_dev_handle *uhd, int slot,
-                        int which_dac, int value);
-
-/*!
- * \brief Read the specified aux adc
- *
- * \p slot: which Tx or Rx slot to read aux dac
- * \p which_adc: [0,1]  which of the two adcs to read
- * \p *value: return value, 12-bit straight binary.
- */
-bool usrp_read_aux_adc (struct usb_dev_handle *udh, int slot,
-                       int which_adc, int *value);
-
-
-/*!
- * \brief usrp daughterboard id to name mapping
- */
-const std::string usrp_dbid_to_string (int dbid);
-
-
-enum usrp_dbeeprom_status_t { UDBE_OK, UDBE_BAD_SLOT, UDBE_NO_EEPROM, UDBE_INVALID_EEPROM };
-
-struct usrp_dboard_eeprom {
-  unsigned short       id;             // d'board identifier code
-  unsigned short       oe;             // fpga output enables:
-                                       //   If bit set, i/o pin is an output from FPGA.
-  short                        offset[2];      // ADC/DAC offset correction
-};
-
-/*!
- * \brief Read and return parsed daughterboard eeprom
- */
-usrp_dbeeprom_status_t
-usrp_read_dboard_eeprom (struct usb_dev_handle *udh,
-                        int slot_id, usrp_dboard_eeprom *eeprom);
-
-/*!
- * \brief write ADC/DAC offset calibration constants to d'board eeprom
- */
-bool usrp_write_dboard_offsets (struct usb_dev_handle *udh, int slot_id,
-                               short offset0, short offset1);
-
-/*!
- * \brief return a usrp's serial number.
- *
- * Note that this only works on a configured usrp.
- * \returns non-zero length string iff successful.
- */
-std::string usrp_serial_number(struct usb_dev_handle *udh);
-
-#endif /* _USRP_PRIMS_H_ */
diff --git a/usrp/host/lib/legacy/usrp_slots.h b/usrp/host/lib/legacy/usrp_slots.h
deleted file mode 100644 (file)
index d2c50fc..0000000
+++ /dev/null
@@ -1,33 +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.
- */
-
-#ifndef INCLUDED_USRP_SLOTS_H
-#define INCLUDED_USRP_SLOTS_H
-
-// daughterboard slot numbers used in some calls
-
-static const int SLOT_TX_A = 0;
-static const int SLOT_RX_A = 1;
-static const int SLOT_TX_B = 2;
-static const int SLOT_RX_B = 3;
-
-#endif /* INCLUDED_USRP_SLOTS_H */
diff --git a/usrp/host/lib/legacy/usrp_standard.cc b/usrp/host/lib/legacy/usrp_standard.cc
deleted file mode 100644 (file)
index b810f99..0000000
+++ /dev/null
@@ -1,1167 +0,0 @@
-/* -*- 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.
- */
-
-#include <usrp_standard.h>
-
-#include "usrp_prims.h"
-#include "fpga_regs_common.h"
-#include "fpga_regs_standard.h"
-#include <stdexcept>
-#include <assert.h>
-#include <math.h>
-#include <ad9862.h>
-#include <cstdio>
-
-
-static const int OLD_CAPS_VAL = 0xaa55ff77;
-static const int DEFAULT_CAPS_VAL = ((2 << bmFR_RB_CAPS_NDUC_SHIFT)
-                                    | (2 << bmFR_RB_CAPS_NDDC_SHIFT)
-                                    | bmFR_RB_CAPS_RX_HAS_HALFBAND);
-
-// #define USE_FPGA_TX_CORDIC
-
-
-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() && !db->i_and_q_swapped())           // 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)
-{
-  static const int NBITS = 14;
-  
-  int  v = (int) rint (target_freq / master_freq * pow (2.0, 32.0));
-
-  if (0)
-    v = (v >> (32 - NBITS)) << (32 - NBITS);   // keep only top NBITS
-
-  *actual_freq = v * master_freq / pow (2.0, 32.0);
-
-  if (verbose)
-    fprintf (stderr,
-            "compute_freq_control_word_fpga: target = %g  actual = %g  delta = %g\n",
-            target_freq, *actual_freq, *actual_freq - target_freq);
-
-  return (unsigned int) v;
-}
-
-// The 9862 uses an unsigned 24-bit frequency tuning word and 
-// a separate register to control the sign.
-
-static unsigned int
-compute_freq_control_word_9862 (double master_freq, double target_freq,
-                               double *actual_freq, bool verbose)
-{
-  double sign = 1.0;
-
-  if (target_freq < 0)
-    sign = -1.0;
-
-  int  v = (int) rint (fabs (target_freq) / master_freq * pow (2.0, 24.0));
-  *actual_freq = v * master_freq / pow (2.0, 24.0) * sign;
-
-  if (verbose)
-    fprintf (stderr,
-     "compute_freq_control_word_9862: target = %g  actual = %g  delta = %g  v = %8d\n",
-     target_freq, *actual_freq, *actual_freq - target_freq, v);
-
-  return (unsigned int) v;
-}
-
-// ----------------------------------------------------------------
-
-usrp_standard_common::usrp_standard_common(usrp_basic *parent)
-{
-  // read new FPGA capability register
-  if (!parent->_read_fpga_reg(FR_RB_CAPS, &d_fpga_caps)){
-    fprintf (stderr, "usrp_standard_common: failed to read FPGA cap register.\n");
-    throw std::runtime_error ("usrp_standard_common::ctor");
-  }
-  // If we don't have the cap register, set the value to what it would
-  // have had if we did have one ;)
-  if (d_fpga_caps == OLD_CAPS_VAL)
-    d_fpga_caps = DEFAULT_CAPS_VAL;
-
-  if (0){
-    fprintf(stdout, "has_rx_halfband = %d\n", has_rx_halfband());
-    fprintf(stdout, "nddcs           = %d\n", nddcs());
-    fprintf(stdout, "has_tx_halfband = %d\n", has_tx_halfband());
-    fprintf(stdout, "nducs           = %d\n", nducs());
-  }
-}
-
-bool
-usrp_standard_common::has_rx_halfband() const
-{
-  return (d_fpga_caps & bmFR_RB_CAPS_RX_HAS_HALFBAND) ? true : false;
-}
-
-int
-usrp_standard_common::nddcs() const
-{
-  return (d_fpga_caps & bmFR_RB_CAPS_NDDC_MASK) >> bmFR_RB_CAPS_NDDC_SHIFT;
-}
-
-bool
-usrp_standard_common::has_tx_halfband() const
-{
-  return (d_fpga_caps & bmFR_RB_CAPS_TX_HAS_HALFBAND) ? true : false;
-}
-
-int
-usrp_standard_common::nducs() const
-{
-  return (d_fpga_caps & bmFR_RB_CAPS_NDUC_MASK) >> bmFR_RB_CAPS_NDUC_SHIFT;
-}
-
-// ----------------------------------------------------------------
-
-static int 
-real_rx_mux_value (int mux, int nchan)
-{
-  if (mux != -1)
-    return mux;
-
-  return 0x32103210;
-}
-
-usrp_standard_rx::usrp_standard_rx (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_basic_rx (which_board, fusb_block_size, fusb_nblocks,
-                  fpga_filename, firmware_filename),
-    usrp_standard_common(this),
-    d_nchan (1), d_sw_mux (0x0), d_hw_mux (0x0)
-{
-  if (!set_format(make_format())){
-    fprintf (stderr, "usrp_standard_rx: set_format failed\n");
-    throw std::runtime_error ("usrp_standard_rx::ctor");
-  }
-  if (!set_nchannels (nchan)){
-    fprintf (stderr, "usrp_standard_rx: set_nchannels failed\n");
-    throw std::runtime_error ("usrp_standard_rx::ctor");
-  }
-  if (!set_decim_rate (decim_rate)){
-    fprintf (stderr, "usrp_standard_rx: set_decim_rate failed\n");
-    throw std::runtime_error ("usrp_standard_rx::ctor");
-  }
-  if (!set_mux (real_rx_mux_value (mux, nchan))){
-    fprintf (stderr, "usrp_standard_rx: set_mux failed\n");
-    throw std::runtime_error ("usrp_standard_rx::ctor");
-  }
-  if (!set_fpga_mode (mode)){
-    fprintf (stderr, "usrp_standard_rx: set_fpga_mode failed\n");
-    throw std::runtime_error ("usrp_standard_rx::ctor");
-  }
-
-  for (int i = 0; i < MAX_CHAN; i++){
-    set_rx_freq(i, 0);
-    set_ddc_phase(i, 0);
-  }
-}
-
-usrp_standard_rx::~usrp_standard_rx ()
-{
-  // fprintf(stderr, "\nusrp_standard_rx: dtor\n");
-}
-
-bool
-usrp_standard_rx::start ()
-{
-  if (!usrp_basic_rx::start ())
-    return false;
-
-  // add our code here
-
-  return true;
-}
-
-bool
-usrp_standard_rx::stop ()
-{
-  bool ok = usrp_basic_rx::stop ();
-
-  // add our code here
-
-  return ok;
-}
-
-usrp_standard_rx_sptr
-usrp_standard_rx::make (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
-                       )
-{
-  try {
-    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 (...){
-    return usrp_standard_rx_sptr();
-  }
-}
-
-bool
-usrp_standard_rx::set_decim_rate(unsigned int rate)
-{
-  if (has_rx_halfband()){
-    if ((rate & 0x1) || rate < 4 || rate > 256){
-      fprintf (stderr, "usrp_standard_rx::set_decim_rate: rate must be EVEN and in [4, 256]\n");
-      return false;
-    }
-  }
-  else {
-    if (rate < 4 || rate > 128){
-      fprintf (stderr, "usrp_standard_rx::set_decim_rate: rate must be in [4, 128]\n");
-      return false;
-    }
-  }
-
-  d_decim_rate = rate;
-  set_usb_data_rate ((adc_rate () / rate * nchannels ())
-                    * (2 * sizeof (short)));
-
-  bool s = disable_rx ();
-  int v = has_rx_halfband() ? d_decim_rate/2 - 1 : d_decim_rate - 1;
-  bool ok = _write_fpga_reg (FR_DECIM_RATE, v);
-  restore_rx (s);
-  return ok;
-}
-
-bool usrp_standard_rx::set_nchannels (int nchan)
-{
-  if (!(nchan == 1 || nchan == 2 || nchan == 4))
-    return false;
-
-  if (nchan > nddcs())
-    return false;
-
-  d_nchan = nchan;
-
-  return write_hw_mux_reg ();
-}
-
-
-// map software mux value to hw mux value
-//
-// Software mux value:
-//
-//    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
-// +-------+-------+-------+-------+-------+-------+-------+-------+
-// |   Q3  |   I3  |   Q2  |   I2  |   Q1  |   I1  |   Q0  |   I0  |
-// +-------+-------+-------+-------+-------+-------+-------+-------+
-//
-// Each 4-bit I field is either 0,1,2,3
-// Each 4-bit Q field is either 0,1,2,3 or 0xf (input is const zero)
-// All Q's must be 0xf or none of them may be 0xf
-//
-//
-// Hardware mux value:
-//
-//    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
-// +-----------------------+-------+-------+-------+-------+-+-----+
-// |      must be zero     | Q3| I3| Q2| I2| Q1| I1| Q0| I0|Z| NCH |
-// +-----------------------+-------+-------+-------+-------+-+-----+
-
-
-static bool
-map_sw_mux_to_hw_mux (int sw_mux, int *hw_mux_ptr)
-{
-  // confirm that all I's are either 0,1,2,3 
-
-  for (int i = 0; i < 8; i += 2){
-    int t = (sw_mux >> (4 * i)) & 0xf;
-    if (!(0 <= t && t <= 3))
-      return false;
-  }
-
-  // confirm that all Q's are either 0,1,2,3 or 0xf
-
-  for (int i = 1; i < 8; i += 2){
-    int t = (sw_mux >> (4 * i)) & 0xf;
-    if (!(t == 0xf || (0 <= t && t <= 3)))
-      return false;
-  }
-
-  // confirm that all Q inputs are 0xf (const zero input),
-  // or none of them are 0xf
-
-  int q_and = 1;
-  int q_or =  0;
-
-  for (int i = 0; i < 4; i++){
-    int qx_is_0xf = ((sw_mux >> (8 * i + 4)) & 0xf) == 0xf;
-    q_and &= qx_is_0xf;
-    q_or  |= qx_is_0xf;
-  }
-
-  if (q_and || !q_or){         // OK
-    int hw_mux_value = 0;
-
-    for (int i = 0; i < 8; i++){
-      int t = (sw_mux >> (4 * i)) & 0x3;
-      hw_mux_value |= t << (2 * i + 4);
-    }
-
-    if (q_and)
-      hw_mux_value |= 0x8;     // all Q's zero
-
-    *hw_mux_ptr = hw_mux_value;
-    return true;
-  }
-  else
-    return false;
-}
-
-bool
-usrp_standard_rx::set_mux (int mux)
-{
-  if (!map_sw_mux_to_hw_mux (mux, &d_hw_mux))
-    return false;
-
-  // fprintf (stderr, "sw_mux = 0x%08x  hw_mux = 0x%08x\n", mux, d_hw_mux);
-
-  d_sw_mux = mux;
-  return write_hw_mux_reg ();
-}
-
-bool
-usrp_standard_rx::write_hw_mux_reg ()
-{
-  bool s = disable_rx ();
-  bool ok = _write_fpga_reg (FR_RX_MUX, d_hw_mux | d_nchan);
-  restore_rx (s);
-  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 uses;
-
-  // compute bitmasks of used A/D's
-  
-  if(db[ss.subdev]->is_quadrature())
-    uses = 0x3;               // uses A/D 0 and 1
-  else if (ss.subdev == 0)
-    uses = 0x1;               // uses A/D 0 only
-  else if(ss.subdev == 1)
-    uses = 0x2;               // uses A/D 1 only
-  else
-    uses = 0x0;               // uses no A/D (doesn't exist)
-  
-  if(uses == 0){
-    throw std::runtime_error("Determine RX Mux Error");
-  }
-  
-  bool swap_iq = db[ss.subdev]->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");
-}
-
-int
-usrp_standard_rx::determine_rx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b)
-{
-  std::vector<db_base_sptr> db_a = this->db(ss_a.side);
-  std::vector<db_base_sptr> db_b = this->db(ss_b.side);
-  if (db_a[ss_a.subdev]->is_quadrature() != db_b[ss_b.subdev]->is_quadrature()){
-    throw std::runtime_error("Cannot compute dual mux when mixing quadrature and non-quadrature subdevices");
-  }
-  int mux_a = determine_rx_mux_value(ss_a);
-  int mux_b = determine_rx_mux_value(ss_b);
-  //move the lower byte of the mux b into the second byte of the mux a
-  return ((mux_b & 0xff) << 8) | (mux_a & 0xffff00ff);
-}
-
-bool
-usrp_standard_rx::set_rx_freq (int channel, double freq)
-{
-  if (channel < 0 || channel > MAX_CHAN)
-    return false;
-
-  unsigned int v =
-    compute_freq_control_word_fpga (adc_rate(),
-                                   freq, &d_rx_freq[channel],
-                                   d_verbose);
-
-  return _write_fpga_reg (FR_RX_FREQ_0 + channel, v);
-}
-
-unsigned int
-usrp_standard_rx::decim_rate () const { return d_decim_rate; }
-
-int
-usrp_standard_rx::nchannels () const { return d_nchan; }
-
-int
-usrp_standard_rx::mux () const { return d_sw_mux; }
-
-double 
-usrp_standard_rx::rx_freq (int channel) const
-{
-  if (channel < 0 || channel >= MAX_CHAN)
-    return 0;
-
-  return d_rx_freq[channel];
-}
-
-bool
-usrp_standard_rx::set_fpga_mode (int mode)
-{
-  return _write_fpga_reg (FR_MODE, mode);
-}
-
-bool
-usrp_standard_rx::set_ddc_phase(int channel, int phase)
-{
-  if (channel < 0 || channel >= MAX_CHAN)
-    return false;
-
-  return _write_fpga_reg(FR_RX_PHASE_0 + channel, phase);
-}
-
-
-// To avoid quiet failures, check for things that our code cares about.
-
-static bool
-rx_format_is_valid(unsigned int format)
-{
-  int width =  usrp_standard_rx::format_width(format);
-  int want_q = usrp_standard_rx::format_want_q(format);
-
-  if (!(width == 8 || width == 16))    // FIXME add other widths when valid
-    return false;
-
-  if (!want_q)         // FIXME remove check when the rest of the code can handle I only
-    return false;
-
-  return true;
-}
-
-bool
-usrp_standard_rx::set_format(unsigned int format)
-{
-  if (!rx_format_is_valid(format))
-    return false;
-
-  return _write_fpga_reg(FR_RX_FORMAT, format);
-}
-
-unsigned int
-usrp_standard_rx::format() const
-{
-  return d_fpga_shadows[FR_RX_FORMAT];
-}
-
-// ----------------------------------------------------------------
-
-unsigned int 
-usrp_standard_rx::make_format(int width, int shift, bool want_q, bool bypass_halfband)
-{
-  unsigned int format = 
-    (((width << bmFR_RX_FORMAT_WIDTH_SHIFT) & bmFR_RX_FORMAT_WIDTH_MASK)
-     | ((shift << bmFR_RX_FORMAT_SHIFT_SHIFT) & bmFR_RX_FORMAT_SHIFT_MASK));
-
-  if (want_q)
-    format |= bmFR_RX_FORMAT_WANT_Q;
-  if (bypass_halfband)
-    format |= bmFR_RX_FORMAT_BYPASS_HB;
-
-  return format;
-}
-
-int
-usrp_standard_rx::format_width(unsigned int format)
-{
-  return (format & bmFR_RX_FORMAT_WIDTH_MASK) >> bmFR_RX_FORMAT_WIDTH_SHIFT;
-}
-
-int
-usrp_standard_rx::format_shift(unsigned int format)
-{
-  return (format & bmFR_RX_FORMAT_SHIFT_MASK) >> bmFR_RX_FORMAT_SHIFT_SHIFT;
-}
-
-bool
-usrp_standard_rx::format_want_q(unsigned int format)
-{
-  return (format & bmFR_RX_FORMAT_WANT_Q) != 0;
-}
-
-bool
-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);
-}
-
-
-//////////////////////////////////////////////////////////////////
-
-
-// tx data is timed to CLKOUT1 (64 MHz)
-// interpolate 4x
-// fine modulator enabled
-
-
-static unsigned char tx_regs_use_nco[] = {
-  REG_TX_IF,           (TX_IF_USE_CLKOUT1
-                        | TX_IF_I_FIRST
-                        | TX_IF_2S_COMP
-                        | TX_IF_INTERLEAVED),
-  REG_TX_DIGITAL,      (TX_DIGITAL_2_DATA_PATHS
-                        | TX_DIGITAL_INTERPOLATE_4X)
-};
-
-
-static int
-real_tx_mux_value (int mux, int nchan)
-{
-  if (mux != -1)
-    return mux;
-
-  switch (nchan){
-  case 1:
-    return 0x0098;
-  case 2:
-    return 0xba98;
-  default:
-    assert (0);
-  }
-}
-
-usrp_standard_tx::usrp_standard_tx (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
-                                   )
-  : usrp_basic_tx (which_board, fusb_block_size, fusb_nblocks, fpga_filename, firmware_filename),
-    usrp_standard_common(this),
-    d_sw_mux (0x8), d_hw_mux (0x81)
-{
-  if (!usrp_9862_write_many_all (d_udh, tx_regs_use_nco, sizeof (tx_regs_use_nco))){
-    fprintf (stderr, "usrp_standard_tx: failed to init AD9862 TX regs\n");
-    throw std::runtime_error ("usrp_standard_tx::ctor");
-  }
-  if (!set_nchannels (nchan)){
-    fprintf (stderr, "usrp_standard_tx: set_nchannels failed\n");
-    throw std::runtime_error ("usrp_standard_tx::ctor");
-  }
-  if (!set_interp_rate (interp_rate)){
-    fprintf (stderr, "usrp_standard_tx: set_interp_rate failed\n");
-    throw std::runtime_error ("usrp_standard_tx::ctor");
-  }
-  if (!set_mux (real_tx_mux_value (mux, nchan))){
-    fprintf (stderr, "usrp_standard_tx: set_mux failed\n");
-    throw std::runtime_error ("usrp_standard_tx::ctor");
-  }
-
-  for (int i = 0; i < MAX_CHAN; i++){
-    d_tx_modulator_shadow[i] = (TX_MODULATOR_DISABLE_NCO
-                               | TX_MODULATOR_COARSE_MODULATION_NONE);
-    d_coarse_mod[i] = CM_OFF;
-    set_tx_freq (i, 0);
-  }
-}
-
-usrp_standard_tx::~usrp_standard_tx ()
-{
-  // fprintf(stderr, "\nusrp_standard_tx: dtor\n");
-}
-
-bool
-usrp_standard_tx::start ()
-{
-  if (!usrp_basic_tx::start ())
-    return false;
-
-  // add our code here
-
-  return true;
-}
-
-bool
-usrp_standard_tx::stop ()
-{
-  bool ok = usrp_basic_tx::stop ();
-
-  // add our code here
-
-  return ok;
-}
-
-usrp_standard_tx_sptr
-usrp_standard_tx::make (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
-                       )
-{
-  try {
-    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 (...){
-    return usrp_standard_tx_sptr();
-  }
-}
-
-bool
-usrp_standard_tx::set_interp_rate (unsigned int rate)
-{
-  // fprintf (stderr, "usrp_standard_tx::set_interp_rate\n");
-
-  if ((rate & 0x3) || rate < 4 || rate > 512){
-    fprintf (stderr, "usrp_standard_tx::set_interp_rate: rate must be in [4, 512] and a multiple of 4.\n");
-    return false;
-  }
-
-  d_interp_rate = rate;
-  set_usb_data_rate ((dac_rate () / rate * nchannels ())
-                    * (2 * sizeof (short)));
-
-  // We're using the interp by 4 feature of the 9862 so that we can
-  // use its fine modulator.  Thus, we reduce the FPGA's interpolation rate
-  // by a factor of 4.
-
-  bool s = disable_tx ();
-  bool ok = _write_fpga_reg (FR_INTERP_RATE, d_interp_rate/4 - 1);
-  restore_tx (s);
-  return ok;
-}
-
-bool
-usrp_standard_tx::set_nchannels (int nchan)
-{
-  if (!(nchan == 1 || nchan == 2))
-    return false;
-
-  if (nchan > nducs())
-    return false;
-
-  d_nchan = nchan;
-  return write_hw_mux_reg ();
-}
-
-bool
-usrp_standard_tx::set_mux (int mux)
-{
-  d_sw_mux = mux;
-  d_hw_mux = mux << 4;
-  return write_hw_mux_reg ();
-}
-
-bool
-usrp_standard_tx::write_hw_mux_reg ()
-{
-  bool s = disable_tx ();
-  bool ok = _write_fpga_reg (FR_TX_MUX, d_hw_mux | d_nchan);
-  restore_tx (s);
-  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[ss.subdev]->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];
-  }
-}
-
-int
-usrp_standard_tx::determine_tx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b)
-{
-  if (ss_a.side == ss_b.side && ss_a.subdev == ss_b.subdev){
-    throw std::runtime_error("Cannot compute dual mux, repeated subdevice");
-  }
-  int mux_a = determine_tx_mux_value(ss_a);
-  //Get the mux b:
-  //   DAC0 becomes DAC2
-  //   DAC1 becomes DAC3
-  unsigned int mask[2] = {0x0022, 0x2200};
-  int mux_b = determine_tx_mux_value(ss_b) + mask[ss_b.side];
-  return mux_b | mux_a;
-}
-
-#ifdef USE_FPGA_TX_CORDIC
-
-bool
-usrp_standard_tx::set_tx_freq (int channel, double freq)
-{
-  if (channel < 0 || channel >= MAX_CHAN)
-    return false;
-
-  // This assumes we're running the 4x on-chip interpolator.
-
-  unsigned int v =
-    compute_freq_control_word_fpga (dac_rate () / 4,
-                                   freq, &d_tx_freq[channel],
-                                   d_verbose);
-
-  return _write_fpga_reg (FR_TX_FREQ_0 + channel, v);
-}
-
-
-#else
-
-bool
-usrp_standard_tx::set_tx_freq (int channel, double freq)
-{
-  if (channel < 0 || channel >= MAX_CHAN)
-    return false;
-
-  // split freq into fine and coarse components
-
-  coarse_mod_t cm;
-  double       coarse;
-
-  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_rate () / 4;
-  }
-  else if (freq < -8e6){       // [-24, -8)
-    cm = CM_NEG_FDAC_OVER_8;
-    coarse = -dac_rate () / 8;
-  }
-  else if (freq < 8e6){                // [-8, 8)
-    cm = CM_OFF;
-    coarse = 0;
-  }
-  else if (freq < 24e6){       // [8, 24)
-    cm = CM_POS_FDAC_OVER_8;
-    coarse = dac_rate () / 8;
-  }
-  else if (freq <= 44e6){      // [24, 44]
-    cm = CM_POS_FDAC_OVER_4;
-    coarse = dac_rate () / 4;
-  }
-  else                         // too high
-    return false;
-
-
-  set_coarse_modulator (channel, cm);  // set bits in d_tx_modulator_shadow
-
-  double fine = freq - coarse;
-
-
-  // Compute fine tuning word...
-  // This assumes we're running the 4x on-chip interpolator.
-  // (This is required to use the fine modulator.)
-
-  unsigned int v =
-    compute_freq_control_word_9862 (dac_rate () / 4,
-                                   fine, &d_tx_freq[channel], d_verbose);
-
-  d_tx_freq[channel] += coarse;                // adjust actual
-  
-  unsigned char high, mid, low;
-
-  high = (v >> 16) & 0xff;
-  mid =  (v >>  8) & 0xff;
-  low =  (v >>  0) & 0xff;
-
-  bool ok = true;
-
-  // write the fine tuning word
-  ok &= _write_9862 (channel, REG_TX_NCO_FTW_23_16, high);
-  ok &= _write_9862 (channel, REG_TX_NCO_FTW_15_8,  mid);
-  ok &= _write_9862 (channel, REG_TX_NCO_FTW_7_0,   low);
-
-
-  d_tx_modulator_shadow[channel] |= TX_MODULATOR_ENABLE_NCO;
-
-  if (fine < 0)
-    d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_FINE_TUNE;
-  else
-    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_NEG_FINE_TUNE;
-
-  ok &=_write_9862 (channel, REG_TX_MODULATOR, d_tx_modulator_shadow[channel]);
-
-  return ok;
-}
-#endif
-
-bool
-usrp_standard_tx::set_coarse_modulator (int channel, coarse_mod_t cm)
-{
-  if (channel < 0 || channel >= MAX_CHAN)
-    return false;
-
-  switch (cm){
-  case CM_NEG_FDAC_OVER_4:
-    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
-    d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_4;
-    d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_COARSE_TUNE;
-    break;
-
-  case CM_NEG_FDAC_OVER_8:
-    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
-    d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_8;
-    d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_COARSE_TUNE;
-    break;
-
-  case CM_OFF:
-    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
-    break;
-
-  case CM_POS_FDAC_OVER_8:
-    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
-    d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_8;
-    break;
-
-  case CM_POS_FDAC_OVER_4:
-    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
-    d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_4;
-    break;
-
-  default:
-    return false;
-  }
-
-  d_coarse_mod[channel] = cm;
-  return true;
-}
-
-unsigned int
-usrp_standard_tx::interp_rate () const { return d_interp_rate; }
-
-int
-usrp_standard_tx::nchannels () const { return d_nchan; }
-
-int
-usrp_standard_tx::mux () const { return d_sw_mux; }
-
-double
-usrp_standard_tx::tx_freq (int channel) const
-{
-  if (channel < 0 || channel >= MAX_CHAN)
-    return 0;
-
-  return d_tx_freq[channel];
-}
-
-usrp_standard_tx::coarse_mod_t
-usrp_standard_tx::coarse_modulator (int channel) const
-{
-  if (channel < 0 || channel >= MAX_CHAN)
-    return CM_OFF;
-
-  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
deleted file mode 100644 (file)
index 734fff4..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-/* -*- 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_STANDARD_H
-#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;
-
-/*!
- * \ingroup usrp
- */
-class usrp_standard_common
-{
-  int  d_fpga_caps;            // capability register val
-
-protected:
-  usrp_standard_common(usrp_basic *parent);
-
-public:
-  /*!
-   *\brief does the FPGA implement the final Rx half-band filter?
-   * If it doesn't, the maximum decimation factor with proper gain 
-   * is 1/2 of what it would otherwise be.
-   */
-  bool has_rx_halfband() const;
-
-  /*!
-   * \brief number of digital downconverters implemented in the FPGA
-   * This will be 0, 1, 2 or 4.
-   */
-  int nddcs() const;
-
-  /*!
-   *\brief does the FPGA implement the initial Tx half-band filter?
-   */
-  bool has_tx_halfband() const;
-
-  /*!
-   * \brief number of digital upconverters implemented in the FPGA
-   * 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);
-};
-
-/*!
- * \brief The C++ interface the receive side of the USRP
- * \ingroup usrp
- *
- * This is the recommended interface to USRP receive functionality
- * for applications that use the USRP but not GNU Radio.
- */
-class usrp_standard_rx : public usrp_basic_rx, public usrp_standard_common
-{
- private:
-  static const int     MAX_CHAN = 4;
-  unsigned int         d_decim_rate;
-  int                  d_nchan;
-  int                  d_sw_mux;
-  int                  d_hw_mux;
-  double               d_rx_freq[MAX_CHAN];
-
- protected:
-  usrp_standard_rx (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 = ""
-                   );  // throws if trouble
-
-  bool write_hw_mux_reg ();
-
- public:
-
-  enum {
-    FPGA_MODE_NORMAL     = 0x00,
-    FPGA_MODE_LOOPBACK   = 0x01,
-    FPGA_MODE_COUNTING   = 0x02,
-    FPGA_MODE_COUNTING_32BIT   = 0x04
-  };
-
-  ~usrp_standard_rx ();
-
-  /*!
-   * \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 decim_rate      decimation factor
-   * \param nchan           number of channels
-   * \param mux                     Rx mux setting, \sa set_mux
-   * \param mode            mode
-   * \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 rbf file to load
-   * \param firmware_filename Name of ihx file to load
-   */
-  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].
-   *
-   * The final complex sample rate across the USB is
-   *   adc_freq () / decim_rate () * nchannels ()
-   */
-  bool set_decim_rate  (unsigned int rate);
-
-  /*!
-   * \brief Set number of active channels.  \p nchannels must be 1, 2 or 4.
-   *
-   * The final complex sample rate across the USB is
-   *   adc_freq () / decim_rate () * nchannels ()
-   */
-  bool set_nchannels (int nchannels);
-
-  /*!
-   * \brief Set input mux configuration.
-   *
-   * This determines which ADC (or constant zero) is connected to 
-   * each DDC input.  There are 4 DDCs.  Each has two inputs.
-   *
-   * <pre>
-   * Mux value:
-   *
-   *    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
-   * +-------+-------+-------+-------+-------+-------+-------+-------+
-   * |   Q3  |   I3  |   Q2  |   I2  |   Q1  |   I1  |   Q0  |   I0  |
-   * +-------+-------+-------+-------+-------+-------+-------+-------+
-   *
-   * Each 4-bit I field is either 0,1,2,3
-   * Each 4-bit Q field is either 0,1,2,3 or 0xf (input is const zero)
-   * All Q's must be 0xf or none of them may be 0xf
-   * </pre>
-   */
-  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);
-  int determine_rx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b);
-
-  /*!
-   * \brief set the frequency of the digital down converter.
-   *
-   * \p channel must be in the range [0,3].  \p freq is the center
-   * frequency in Hz.  \p freq may be either negative or postive.
-   * 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 mode
-   */
-  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);
-
-  /*!
-   * \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);
-
-  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] 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;
-  int nchannels () const;
-  int mux () const;
-  unsigned int format () const;
-
-  // called in base class to derived class order
-  bool start ();
-  bool stop ();
-};
-
-// ----------------------------------------------------------------
-
-/*!
- * \brief The C++ interface the transmit side of the USRP
- * \ingroup usrp
- *
- * This is the recommended interface to USRP transmit functionality
- * for applications that use the USRP but not GNU Radio.
- *
- * Uses digital upconverter (coarse & fine modulators) in AD9862...
- */
-class usrp_standard_tx : public usrp_basic_tx, public usrp_standard_common
-{
- public:
-  enum coarse_mod_t {
-    CM_NEG_FDAC_OVER_4,                // -32 MHz
-    CM_NEG_FDAC_OVER_8,                // -16 MHz
-    CM_OFF,
-    CM_POS_FDAC_OVER_8,                // +16 MHz
-    CM_POS_FDAC_OVER_4         // +32 MHz
-  };
-
- protected:
-  static const int     MAX_CHAN = 2;
-  unsigned int         d_interp_rate;
-  int                  d_nchan;
-  int                  d_sw_mux;
-  int                  d_hw_mux;
-  double               d_tx_freq[MAX_CHAN];
-  coarse_mod_t         d_coarse_mod[MAX_CHAN];
-  unsigned char                d_tx_modulator_shadow[MAX_CHAN];
-
-  virtual bool set_coarse_modulator (int channel, coarse_mod_t cm);
-  usrp_standard_tx::coarse_mod_t coarse_modulator (int channel) const;
-
- protected:
-  usrp_standard_tx (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 = ""
-                   );  // throws if trouble
-
-  bool write_hw_mux_reg ();
-
- public:
-  ~usrp_standard_tx ();
-
-  /*!
-   * \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 interp_rate             interpolation factor
-   * \param nchan           number of channels
-   * \param mux                     Tx mux setting, \sa set_mux
-   * \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 rbf file to load
-   * \param firmware_filename Name of ihx file to load
-   */
-  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.
-   *
-   * The final complex sample rate across the USB is
-   *   dac_freq () / interp_rate () * nchannels ()
-   */
-  virtual bool set_interp_rate (unsigned int rate);
-
-  /*!
-   * \brief Set number of active channels.  \p nchannels must be 1 or 2.
-   *
-   * The final complex sample rate across the USB is
-   *   dac_freq () / decim_rate () * nchannels ()
-   */
-  bool set_nchannels  (int nchannels);
-
-  /*!
-   * \brief Set output mux configuration.
-   *
-   * <pre>
-   *     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
-   *  +-------------------------------+-------+-------+-------+-------+
-   *  |                               | DAC3  | DAC2  | DAC1  |  DAC0 |
-   *  +-------------------------------+-------+-------+-------+-------+
-   * 
-   *  There are two interpolators with complex inputs and outputs.
-   *  There are four DACs.
-   * 
-   *  Each 4-bit DACx field specifies the source for the DAC and
-   *  whether or not that DAC is enabled.  Each subfield is coded
-   *  like this: 
-   * 
-   *     3 2 1 0
-   *    +-+-----+
-   *    |E|  N  |
-   *    +-+-----+
-   * 
-   *  Where E is set if the DAC is enabled, and N specifies which
-   *  interpolator output is connected to this DAC.
-   * 
-   *   N   which interp output
-   *  ---  -------------------
-   *   0   chan 0 I
-   *   1   chan 0 Q
-   *   2   chan 1 I
-   *   3   chan 1 Q
-   * </pre>
-   */
-  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);
-  int determine_tx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b);
-
-  /*!
-   * \brief set the frequency of the digital up converter.
-   *
-   * \p channel must be in the range [0,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.
-   */
-  virtual bool set_tx_freq (int channel, double freq);  // chan: [0,1]
-
-  // ACCESSORS
-  unsigned int interp_rate () const;
-  double tx_freq (int channel) const;
-  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] 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 ();
-};
-
-#endif /* INCLUDED_USRP_STANDARD_H */
diff --git a/usrp/host/lib/legacy/usrp_subdev_spec.h b/usrp/host/lib/legacy/usrp_subdev_spec.h
deleted file mode 100644 (file)
index e841ff8..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with 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
deleted file mode 100644 (file)
index 200541a..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with 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/usrp/host/lib/limbo/db_wbx.cc b/usrp/host/lib/limbo/db_wbx.cc
new file mode 100644 (file)
index 0000000..9f1d729
--- /dev/null
@@ -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/limbo/db_wbx.h b/usrp/host/lib/limbo/db_wbx.h
new file mode 100644 (file)
index 0000000..3202d36
--- /dev/null
@@ -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/md5.c b/usrp/host/lib/md5.c
new file mode 100644 (file)
index 0000000..b15ab39
--- /dev/null
@@ -0,0 +1,452 @@
+/* md5.c - Functions to compute MD5 message digest of files or memory blocks
+   according to the definition of MD5 in RFC 1321 from April 1992.
+   Copyright (C) 1995, 1996, 2001, 2003 Free Software Foundation, Inc.
+   NOTE: The canonical source of this file is maintained with the GNU C
+   Library.  Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 3, or (at your option) any
+   later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Boston, MA 02110-1301, USA.  */
+
+/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "md5.h"
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+// #include "unlocked-io.h"
+
+#ifdef _LIBC
+# include <endian.h>
+# if __BYTE_ORDER == __BIG_ENDIAN
+#  define WORDS_BIGENDIAN 1
+# endif
+/* We need to keep the namespace clean so define the MD5 function
+   protected using leading __ .  */
+# define md5_init_ctx __md5_init_ctx
+# define md5_process_block __md5_process_block
+# define md5_process_bytes __md5_process_bytes
+# define md5_finish_ctx __md5_finish_ctx
+# define md5_read_ctx __md5_read_ctx
+# define md5_stream __md5_stream
+# define md5_buffer __md5_buffer
+#endif
+
+#ifdef WORDS_BIGENDIAN
+# define SWAP(n)                                                       \
+    (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
+#else
+# define SWAP(n) (n)
+#endif
+
+#define BLOCKSIZE 4096
+/* Ensure that BLOCKSIZE is a multiple of 64.  */
+#if BLOCKSIZE % 64 != 0
+/* FIXME-someday (soon?): use #error instead of this kludge.  */
+"invalid BLOCKSIZE"
+#endif
+
+/* This array contains the bytes used to pad the buffer to the next
+   64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
+static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
+
+
+/* Initialize structure containing state of computation.
+   (RFC 1321, 3.3: Step 3)  */
+void
+md5_init_ctx (struct md5_ctx *ctx)
+{
+  ctx->A = 0x67452301;
+  ctx->B = 0xefcdab89;
+  ctx->C = 0x98badcfe;
+  ctx->D = 0x10325476;
+
+  ctx->total[0] = ctx->total[1] = 0;
+  ctx->buflen = 0;
+}
+
+/* Put result from CTX in first 16 bytes following RESBUF.  The result
+   must be in little endian byte order.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+void *
+md5_read_ctx (const struct md5_ctx *ctx, void *resbuf)
+{
+  ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
+  ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
+  ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
+  ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
+
+  return resbuf;
+}
+
+/* Process the remaining bytes in the internal buffer and the usual
+   prolog according to the standard and write the result to RESBUF.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+void *
+md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
+{
+  /* Take yet unprocessed bytes into account.  */
+  md5_uint32 bytes = ctx->buflen;
+  size_t pad;
+
+  /* Now count remaining bytes.  */
+  ctx->total[0] += bytes;
+  if (ctx->total[0] < bytes)
+    ++ctx->total[1];
+
+  pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
+  memcpy (&ctx->buffer[bytes], fillbuf, pad);
+
+  /* Put the 64-bit file length in *bits* at the end of the buffer.  */
+  *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
+  *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
+                                                       (ctx->total[0] >> 29));
+
+  /* Process last bytes.  */
+  md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
+
+  return md5_read_ctx (ctx, resbuf);
+}
+
+/* Compute MD5 message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 16 bytes
+   beginning at RESBLOCK.  */
+int
+md5_stream (FILE *stream, void *resblock)
+{
+  struct md5_ctx ctx;
+  char buffer[BLOCKSIZE + 72];
+  size_t sum;
+
+  /* Initialize the computation context.  */
+  md5_init_ctx (&ctx);
+
+  /* Iterate over full file contents.  */
+  while (1)
+    {
+      /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
+        computation function processes the whole buffer so that with the
+        next round of the loop another block can be read.  */
+      size_t n;
+      sum = 0;
+
+      /* Read block.  Take care for partial reads.  */
+      while (1)
+       {
+         n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
+
+         sum += n;
+
+         if (sum == BLOCKSIZE)
+           break;
+
+         if (n == 0)
+           {
+             /* Check for the error flag IFF N == 0, so that we don't
+                exit the loop after a partial read due to e.g., EAGAIN
+                or EWOULDBLOCK.  */
+             if (ferror (stream))
+               return 1;
+             goto process_partial_block;
+           }
+
+         /* We've read at least one byte, so ignore errors.  But always
+            check for EOF, since feof may be true even though N > 0.
+            Otherwise, we could end up calling fread after EOF.  */
+         if (feof (stream))
+           goto process_partial_block;
+       }
+
+      /* Process buffer with BLOCKSIZE bytes.  Note that
+                       BLOCKSIZE % 64 == 0
+       */
+      md5_process_block (buffer, BLOCKSIZE, &ctx);
+    }
+
+ process_partial_block:;
+
+  /* Process any remaining bytes.  */
+  if (sum > 0)
+    md5_process_bytes (buffer, sum, &ctx);
+
+  /* Construct result in desired memory.  */
+  md5_finish_ctx (&ctx, resblock);
+  return 0;
+}
+
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
+   result is always in little endian byte order, so that a byte-wise
+   output yields to the wanted ASCII representation of the message
+   digest.  */
+void *
+md5_buffer (const char *buffer, size_t len, void *resblock)
+{
+  struct md5_ctx ctx;
+
+  /* Initialize the computation context.  */
+  md5_init_ctx (&ctx);
+
+  /* Process whole buffer but last len % 64 bytes.  */
+  md5_process_bytes (buffer, len, &ctx);
+
+  /* Put result in desired memory area.  */
+  return md5_finish_ctx (&ctx, resblock);
+}
+
+
+void
+md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
+{
+  /* When we already have some bits in our internal buffer concatenate
+     both inputs first.  */
+  if (ctx->buflen != 0)
+    {
+      size_t left_over = ctx->buflen;
+      size_t add = 128 - left_over > len ? len : 128 - left_over;
+
+      memcpy (&ctx->buffer[left_over], buffer, add);
+      ctx->buflen += add;
+
+      if (ctx->buflen > 64)
+       {
+         md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
+
+         ctx->buflen &= 63;
+         /* The regions in the following copy operation cannot overlap.  */
+         memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
+                 ctx->buflen);
+       }
+
+      buffer = (const char *) buffer + add;
+      len -= add;
+    }
+
+  /* Process available complete blocks.  */
+  if (len >= 64)
+    {
+#if !_STRING_ARCH_unaligned
+/* To check alignment gcc has an appropriate operator.  Other
+   compilers don't.  */
+# if __GNUC__ >= 2
+#  define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0)
+# else
+#  define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0)
+# endif
+      if (UNALIGNED_P (buffer))
+       while (len > 64)
+         {
+           md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
+           buffer = (const char *) buffer + 64;
+           len -= 64;
+         }
+      else
+#endif
+       {
+         md5_process_block (buffer, len & ~63, ctx);
+         buffer = (const char *) buffer + (len & ~63);
+         len &= 63;
+       }
+    }
+
+  /* Move remaining bytes in internal buffer.  */
+  if (len > 0)
+    {
+      size_t left_over = ctx->buflen;
+
+      memcpy (&ctx->buffer[left_over], buffer, len);
+      left_over += len;
+      if (left_over >= 64)
+       {
+         md5_process_block (ctx->buffer, 64, ctx);
+         left_over -= 64;
+         memcpy (ctx->buffer, &ctx->buffer[64], left_over);
+       }
+      ctx->buflen = left_over;
+    }
+}
+
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+   and defined in the RFC 1321.  The first function is a little bit optimized
+   (as found in Colin Plumbs public domain implementation).  */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF (d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+/* Process LEN bytes of BUFFER, accumulating context into CTX.
+   It is assumed that LEN % 64 == 0.  */
+
+void
+md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
+{
+  md5_uint32 correct_words[16];
+  const md5_uint32 *words = buffer;
+  size_t nwords = len / sizeof (md5_uint32);
+  const md5_uint32 *endp = words + nwords;
+  md5_uint32 A = ctx->A;
+  md5_uint32 B = ctx->B;
+  md5_uint32 C = ctx->C;
+  md5_uint32 D = ctx->D;
+
+  /* First increment the byte count.  RFC 1321 specifies the possible
+     length of the file up to 2^64 bits.  Here we only compute the
+     number of bytes.  Do a double word increment.  */
+  ctx->total[0] += len;
+  if (ctx->total[0] < len)
+    ++ctx->total[1];
+
+  /* Process all bytes in the buffer with 64 bytes in each round of
+     the loop.  */
+  while (words < endp)
+    {
+      md5_uint32 *cwp = correct_words;
+      md5_uint32 A_save = A;
+      md5_uint32 B_save = B;
+      md5_uint32 C_save = C;
+      md5_uint32 D_save = D;
+
+      /* First round: using the given function, the context and a constant
+        the next context is computed.  Because the algorithms processing
+        unit is a 32-bit word and it is determined to work on words in
+        little endian byte order we perhaps have to change the byte order
+        before the computation.  To reduce the work for the next steps
+        we store the swapped words in the array CORRECT_WORDS.  */
+
+#define OP(a, b, c, d, s, T)                                           \
+      do                                                               \
+        {                                                              \
+         a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;             \
+         ++words;                                                      \
+         a = rol (a, s);                                               \
+         a += b;                                                       \
+        }                                                              \
+      while (0)
+
+      /* Before we start, one word to the strange constants.
+        They are defined in RFC 1321 as
+
+        T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64, or
+        perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}'
+       */
+
+      /* Round 1.  */
+      OP (A, B, C, D,  7, 0xd76aa478);
+      OP (D, A, B, C, 12, 0xe8c7b756);
+      OP (C, D, A, B, 17, 0x242070db);
+      OP (B, C, D, A, 22, 0xc1bdceee);
+      OP (A, B, C, D,  7, 0xf57c0faf);
+      OP (D, A, B, C, 12, 0x4787c62a);
+      OP (C, D, A, B, 17, 0xa8304613);
+      OP (B, C, D, A, 22, 0xfd469501);
+      OP (A, B, C, D,  7, 0x698098d8);
+      OP (D, A, B, C, 12, 0x8b44f7af);
+      OP (C, D, A, B, 17, 0xffff5bb1);
+      OP (B, C, D, A, 22, 0x895cd7be);
+      OP (A, B, C, D,  7, 0x6b901122);
+      OP (D, A, B, C, 12, 0xfd987193);
+      OP (C, D, A, B, 17, 0xa679438e);
+      OP (B, C, D, A, 22, 0x49b40821);
+
+      /* For the second to fourth round we have the possibly swapped words
+        in CORRECT_WORDS.  Redefine the macro to take an additional first
+        argument specifying the function to use.  */
+#undef OP
+#define OP(f, a, b, c, d, k, s, T)                                     \
+      do                                                               \
+       {                                                               \
+         a += f (b, c, d) + correct_words[k] + T;                      \
+         a = rol (a, s);                                               \
+         a += b;                                                       \
+       }                                                               \
+      while (0)
+
+      /* Round 2.  */
+      OP (FG, A, B, C, D,  1,  5, 0xf61e2562);
+      OP (FG, D, A, B, C,  6,  9, 0xc040b340);
+      OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
+      OP (FG, B, C, D, A,  0, 20, 0xe9b6c7aa);
+      OP (FG, A, B, C, D,  5,  5, 0xd62f105d);
+      OP (FG, D, A, B, C, 10,  9, 0x02441453);
+      OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
+      OP (FG, B, C, D, A,  4, 20, 0xe7d3fbc8);
+      OP (FG, A, B, C, D,  9,  5, 0x21e1cde6);
+      OP (FG, D, A, B, C, 14,  9, 0xc33707d6);
+      OP (FG, C, D, A, B,  3, 14, 0xf4d50d87);
+      OP (FG, B, C, D, A,  8, 20, 0x455a14ed);
+      OP (FG, A, B, C, D, 13,  5, 0xa9e3e905);
+      OP (FG, D, A, B, C,  2,  9, 0xfcefa3f8);
+      OP (FG, C, D, A, B,  7, 14, 0x676f02d9);
+      OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+      /* Round 3.  */
+      OP (FH, A, B, C, D,  5,  4, 0xfffa3942);
+      OP (FH, D, A, B, C,  8, 11, 0x8771f681);
+      OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
+      OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
+      OP (FH, A, B, C, D,  1,  4, 0xa4beea44);
+      OP (FH, D, A, B, C,  4, 11, 0x4bdecfa9);
+      OP (FH, C, D, A, B,  7, 16, 0xf6bb4b60);
+      OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
+      OP (FH, A, B, C, D, 13,  4, 0x289b7ec6);
+      OP (FH, D, A, B, C,  0, 11, 0xeaa127fa);
+      OP (FH, C, D, A, B,  3, 16, 0xd4ef3085);
+      OP (FH, B, C, D, A,  6, 23, 0x04881d05);
+      OP (FH, A, B, C, D,  9,  4, 0xd9d4d039);
+      OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
+      OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+      OP (FH, B, C, D, A,  2, 23, 0xc4ac5665);
+
+      /* Round 4.  */
+      OP (FI, A, B, C, D,  0,  6, 0xf4292244);
+      OP (FI, D, A, B, C,  7, 10, 0x432aff97);
+      OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
+      OP (FI, B, C, D, A,  5, 21, 0xfc93a039);
+      OP (FI, A, B, C, D, 12,  6, 0x655b59c3);
+      OP (FI, D, A, B, C,  3, 10, 0x8f0ccc92);
+      OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
+      OP (FI, B, C, D, A,  1, 21, 0x85845dd1);
+      OP (FI, A, B, C, D,  8,  6, 0x6fa87e4f);
+      OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+      OP (FI, C, D, A, B,  6, 15, 0xa3014314);
+      OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
+      OP (FI, A, B, C, D,  4,  6, 0xf7537e82);
+      OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
+      OP (FI, C, D, A, B,  2, 15, 0x2ad7d2bb);
+      OP (FI, B, C, D, A,  9, 21, 0xeb86d391);
+
+      /* Add the starting values of the context.  */
+      A += A_save;
+      B += B_save;
+      C += C_save;
+      D += D_save;
+    }
+
+  /* Put checksum in context given as argument.  */
+  ctx->A = A;
+  ctx->B = B;
+  ctx->C = C;
+  ctx->D = D;
+}
diff --git a/usrp/host/lib/md5.h b/usrp/host/lib/md5.h
new file mode 100644 (file)
index 0000000..4a4e790
--- /dev/null
@@ -0,0 +1,129 @@
+/* md5.h - Declaration of functions and data types used for MD5 sum
+   computing library functions.
+   Copyright (C) 1995, 1996, 1999, 2000, 2003 Free Software Foundation, Inc.
+   NOTE: The canonical source of this file is maintained with the GNU C
+   Library.  Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 3, or (at your option) any
+   later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Boston, MA 02110-1301, USA.  */
+
+#ifndef _MD5_H
+#define _MD5_H 1
+
+#include <stdio.h>
+#include <limits.h>
+
+/* The following contortions are an attempt to use the C preprocessor
+   to determine an unsigned integral type that is 32 bits wide.  An
+   alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
+   doing that would require that the configure script compile and *run*
+   the resulting executable.  Locally running cross-compiled executables
+   is usually not possible.  */
+
+#ifdef _LIBC
+# include <stdint.h>
+typedef uint32_t md5_uint32;
+typedef uintptr_t md5_uintptr;
+#else
+# define UINT_MAX_32_BITS 4294967295U
+
+# if UINT_MAX == UINT_MAX_32_BITS
+   typedef unsigned int md5_uint32;
+# else
+#  if USHRT_MAX == UINT_MAX_32_BITS
+    typedef unsigned short md5_uint32;
+#  else
+#   if ULONG_MAX == UINT_MAX_32_BITS
+     typedef unsigned long md5_uint32;
+#   else
+     /* The following line is intended to evoke an error.
+        Using #error is not portable enough.  */
+     "Cannot determine unsigned 32-bit data type."
+#   endif
+#  endif
+# endif
+/* We have to make a guess about the integer type equivalent in size
+   to pointers which should always be correct.  */
+typedef unsigned long int md5_uintptr;
+#endif
+
+/* Structure to save state of computation between the single steps.  */
+struct md5_ctx
+{
+  md5_uint32 A;
+  md5_uint32 B;
+  md5_uint32 C;
+  md5_uint32 D;
+
+  md5_uint32 total[2];
+  md5_uint32 buflen;
+  char buffer[128];
+};
+
+/*
+ * The following three functions are build up the low level used in
+ * the functions `md5_stream' and `md5_buffer'.
+ */
+
+/* Initialize structure containing state of computation.
+   (RFC 1321, 3.3: Step 3)  */
+extern void md5_init_ctx (struct md5_ctx *ctx);
+
+/* Starting with the result of former calls of this function (or the
+   initialization function update the context for the next LEN bytes
+   starting at BUFFER.
+   It is necessary that LEN is a multiple of 64!!! */
+extern void md5_process_block (const void *buffer, size_t len,
+                              struct md5_ctx *ctx);
+
+/* Starting with the result of former calls of this function (or the
+   initialization function update the context for the next LEN bytes
+   starting at BUFFER.
+   It is NOT required that LEN is a multiple of 64.  */
+extern void md5_process_bytes (const void *buffer, size_t len,
+                              struct md5_ctx *ctx);
+
+/* Process the remaining bytes in the buffer and put result from CTX
+   in first 16 bytes following RESBUF.  The result is always in little
+   endian byte order, so that a byte-wise output yields to the wanted
+   ASCII representation of the message digest.
+
+   IMPORTANT: On some systems it is required that RESBUF be correctly
+   aligned for a 32 bits value.  */
+extern void *md5_finish_ctx (struct md5_ctx *ctx, void *resbuf);
+
+
+/* Put result from CTX in first 16 bytes following RESBUF.  The result is
+   always in little endian byte order, so that a byte-wise output yields
+   to the wanted ASCII representation of the message digest.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+extern void *md5_read_ctx (const struct md5_ctx *ctx, void *resbuf);
+
+
+/* Compute MD5 message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 16 bytes
+   beginning at RESBLOCK.  */
+extern int md5_stream (FILE *stream, void *resblock);
+
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
+   result is always in little endian byte order, so that a byte-wise
+   output yields to the wanted ASCII representation of the message
+   digest.  */
+extern void *md5_buffer (const char *buffer, size_t len, void *resblock);
+
+#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
+
+#endif
diff --git a/usrp/host/lib/mld_threads.h b/usrp/host/lib/mld_threads.h
new file mode 100644 (file)
index 0000000..322f557
--- /dev/null
@@ -0,0 +1,275 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio.
+ *
+ * Primary Author: Michael Dickens, NCIP Lab, University of Notre Dame
+ * 
+ * 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_MLD_THREADS_H_
+#define _INCLUDED_MLD_THREADS_H_
+
+/* classes which allow for either pthreads or omni_threads */
+
+#define __macos__
+#ifdef _USE_OMNI_THREADS_
+#include <gnuradio/omnithread.h>
+#else
+#include <pthread.h>
+#endif
+
+#include <stdexcept>
+
+#define __INLINE__ inline
+
+#ifndef DO_DEBUG
+#define DO_DEBUG 0
+#endif
+
+#if DO_DEBUG
+#define DEBUG(X) do{X} while(0);
+#else
+#define DEBUG(X) do{} while(0);
+#endif
+
+class mld_condition_t;
+
+class mld_mutex_t {
+#ifdef _USE_OMNI_THREADS_
+  typedef omni_mutex l_mutex, *l_mutex_ptr;
+#else
+  typedef pthread_mutex_t l_mutex, *l_mutex_ptr;
+#endif
+
+  friend class mld_condition_t;
+
+private:
+  l_mutex_ptr d_mutex;
+
+protected:
+  inline l_mutex_ptr mutex () { return (d_mutex); };
+
+public:
+  __INLINE__ mld_mutex_t () {
+#ifdef _USE_OMNI_THREADS_
+    d_mutex = new omni_mutex ();
+#else
+    d_mutex = (l_mutex_ptr) new l_mutex;
+    int l_ret = pthread_mutex_init (d_mutex, NULL);
+    if (l_ret != 0) {
+      fprintf (stderr, "Error %d creating mutex.\n", l_ret);
+      throw std::runtime_error ("mld_mutex_t::mld_mutex_t()\n");
+    }
+#endif
+  };
+
+  __INLINE__ ~mld_mutex_t () {
+    unlock ();
+#ifndef _USE_OMNI_THREADS_
+    int l_ret = pthread_mutex_destroy (d_mutex);
+    if (l_ret != 0) {
+      fprintf (stderr, "mld_mutex_t::~mld_mutex_t(): "
+              "Error %d destroying mutex.\n", l_ret);
+    }
+#endif
+    delete d_mutex;
+    d_mutex = NULL;
+  };
+
+  __INLINE__ void lock () {
+#ifdef _USE_OMNI_THREADS_
+    d_mutex->lock ();
+#else
+    int l_ret = pthread_mutex_lock (d_mutex);
+    if (l_ret != 0) {
+      fprintf (stderr, "mld_mutex_t::lock(): "
+              "Error %d locking mutex.\n", l_ret);
+    }
+#endif
+  };
+
+  __INLINE__ void unlock () {
+#ifdef _USE_OMNI_THREADS_
+    d_mutex->unlock ();
+#else
+    int l_ret = pthread_mutex_unlock (d_mutex);
+    if (l_ret != 0) {
+      fprintf (stderr, "mld_mutex_t::unlock(): "
+              "Error %d locking mutex.\n", l_ret);
+    }
+#endif
+  };
+
+  __INLINE__ bool trylock () {
+#ifdef _USE_OMNI_THREADS_
+    int l_ret = d_mutex->trylock ();
+#else
+    int l_ret = pthread_mutex_unlock (d_mutex);
+#endif
+    return (l_ret == 0 ? true : false);
+  };
+
+  inline void acquire () { lock(); };
+  inline void release () { unlock(); };
+  inline void wait () { lock(); };
+  inline void post () { unlock(); };
+};
+
+typedef mld_mutex_t mld_mutex, *mld_mutex_ptr;
+
+class mld_condition_t {
+#ifdef _USE_OMNI_THREADS_
+  typedef omni_condition l_condition, *l_condition_ptr;
+#else
+  typedef pthread_cond_t l_condition, *l_condition_ptr;
+#endif
+
+private:
+  l_condition_ptr d_condition;
+  mld_mutex_ptr d_mutex;
+  bool d_i_own_mutex;
+
+public:
+  __INLINE__ mld_condition_t (mld_mutex_ptr mutex = NULL) {
+    if (mutex) {
+      d_i_own_mutex = false;
+      d_mutex = mutex;
+    } else {
+      d_i_own_mutex = true;
+      d_mutex = new mld_mutex ();
+    }
+#ifdef _USE_OMNI_THREADS_
+    d_condition = new omni_condition (d_mutex->mutex ());
+#else
+    d_condition = (l_condition_ptr) new l_condition;
+    int l_ret = pthread_cond_init (d_condition, NULL);
+    if (l_ret != 0) {
+      fprintf (stderr, "Error %d creating condition.\n", l_ret);
+      throw std::runtime_error ("mld_condition_t::mld_condition_t()\n");
+    }
+#endif
+  };
+
+  __INLINE__ ~mld_condition_t () {
+    signal ();
+#ifndef _USE_OMNI_THREADS_
+    int l_ret = pthread_cond_destroy (d_condition);
+    if (l_ret != 0) {
+      fprintf (stderr, "mld_condition_t::mld_condition_t(): "
+              "Error %d destroying condition.\n", l_ret);
+    }
+#endif
+    delete d_condition;
+    d_condition = NULL;
+    if (d_i_own_mutex)
+      delete d_mutex;
+    d_mutex = NULL;
+  };
+
+  __INLINE__ mld_mutex_ptr mutex () {return (d_mutex);};
+
+  __INLINE__ void signal () {
+    DEBUG (fprintf (stderr, "a "););
+
+#ifdef _USE_OMNI_THREADS_
+    d_condition->signal ();
+#else
+    int l_ret = pthread_cond_signal (d_condition);
+    if (l_ret != 0) {
+      fprintf (stderr, "mld_condition_t::signal(): "
+              "Error %d.\n", l_ret);
+    }
+#endif
+    DEBUG (fprintf (stderr, "b "););
+  };
+
+  __INLINE__ void wait () {
+    DEBUG (fprintf (stderr, "c "););
+#ifdef _USE_OMNI_THREADS_
+    d_condition->wait ();
+#else
+    int l_ret = pthread_cond_wait (d_condition, d_mutex->mutex ());
+    if (l_ret != 0) {
+      fprintf (stderr, "mld_condition_t::wait(): "
+              "Error %d.\n", l_ret);
+    }
+#endif
+    DEBUG (fprintf (stderr, "d "););
+  };
+};
+
+typedef mld_condition_t mld_condition, *mld_condition_ptr;
+
+class mld_thread_t {
+#ifdef _USE_OMNI_THREADS_
+  typedef omni_thread l_thread, *l_thread_ptr;
+#else
+  typedef pthread_t l_thread, *l_thread_ptr;
+#endif
+
+private:
+#ifndef _USE_OMNI_THREADS_
+  l_thread d_thread;
+  void (*d_start_routine)(void*);
+  void *d_arg;
+#else
+  l_thread_ptr d_thread;
+#endif
+
+#ifndef _USE_OMNI_THREADS_
+  static void* local_start_routine (void *arg) {
+    mld_thread_t* This = (mld_thread_t*) arg;
+    (*(This->d_start_routine))(This->d_arg);
+    return (NULL);
+  };
+#endif
+
+public:
+  __INLINE__ mld_thread_t (void (*start_routine)(void *), void *arg) {
+#ifdef _USE_OMNI_THREADS_
+    d_thread = new omni_thread (start_routine, arg);
+    d_thread->start ();
+#else
+    d_start_routine = start_routine;
+    d_arg = arg;
+    int l_ret = pthread_create (&d_thread, NULL, local_start_routine, this);
+    if (l_ret != 0) {
+      fprintf (stderr, "Error %d creating thread.\n", l_ret);
+      throw std::runtime_error ("mld_thread_t::mld_thread_t()\n");
+    }
+#endif
+  };
+
+  __INLINE__ ~mld_thread_t () {
+#ifdef _USE_OMNI_THREADS_
+//  delete d_thread;
+    d_thread = NULL;
+#else
+    int l_ret = pthread_detach (d_thread);
+    if (l_ret != 0) {
+      fprintf (stderr, "Error %d detaching thread.\n", l_ret);
+      throw std::runtime_error ("mld_thread_t::~mld_thread_t()\n");
+    }
+#endif
+  };
+};
+
+typedef mld_thread_t mld_thread, *mld_thread_ptr;
+
+#endif /* _INCLUDED_MLD_THREADS_H_ */
diff --git a/usrp/host/lib/rate_to_regval.h b/usrp/host/lib/rate_to_regval.h
new file mode 100644 (file)
index 0000000..1ffdc0f
--- /dev/null
@@ -0,0 +1,97 @@
+  {   1, 0x00 },
+  {   2, 0x01 },
+  {   3, 0x02 },
+  {   4, 0x11 },
+  {   5, 0x04 },
+  {   6, 0x05 },
+  {   7, 0x06 },
+  {   8, 0x13 },
+  {   9, 0x08 },
+  {  10, 0x09 },
+  {  11, 0x0a },
+  {  12, 0x15 },
+  {  13, 0x0c },
+  {  14, 0x0d },
+  {  15, 0x0e },
+  {  16, 0x33 },
+  {  18, 0x18 },
+  {  20, 0x19 },
+  {  21, 0x26 },
+  {  22, 0x1a },
+  {  24, 0x35 },
+  {  25, 0x44 },
+  {  26, 0x1c },
+  {  27, 0x28 },
+  {  28, 0x1d },
+  {  30, 0x1e },
+  {  32, 0x37 },
+  {  33, 0x2a },
+  {  35, 0x46 },
+  {  36, 0x55 },
+  {  39, 0x2c },
+  {  40, 0x39 },
+  {  42, 0x56 },
+  {  44, 0x3a },
+  {  45, 0x2e },
+  {  48, 0x57 },
+  {  49, 0x66 },
+  {  50, 0x49 },
+  {  52, 0x3c },
+  {  54, 0x58 },
+  {  55, 0x4a },
+  {  56, 0x3d },
+  {  60, 0x59 },
+  {  63, 0x68 },
+  {  64, 0x77 },
+  {  65, 0x4c },
+  {  66, 0x5a },
+  {  70, 0x69 },
+  {  72, 0x5b },
+  {  75, 0x4e },
+  {  77, 0x6a },
+  {  78, 0x5c },
+  {  80, 0x79 },
+  {  81, 0x88 },
+  {  84, 0x5d },
+  {  88, 0x7a },
+  {  90, 0x5e },
+  {  91, 0x6c },
+  {  96, 0x7b },
+  {  98, 0x6d },
+  {  99, 0x8a },
+  { 100, 0x99 },
+  { 104, 0x7c },
+  { 105, 0x6e },
+  { 108, 0x8b },
+  { 110, 0x9a },
+  { 112, 0x7d },
+  { 117, 0x8c },
+  { 120, 0x9b },
+  { 121, 0xaa },
+  { 126, 0x8d },
+  { 128, 0x7f },
+  { 130, 0x9c },
+  { 132, 0xab },
+  { 135, 0x8e },
+  { 140, 0x9d },
+  { 143, 0xac },
+  { 144, 0xbb },
+  { 150, 0x9e },
+  { 154, 0xad },
+  { 156, 0xbc },
+  { 160, 0x9f },
+  { 165, 0xae },
+  { 168, 0xbd },
+  { 169, 0xcc },
+  { 176, 0xaf },
+  { 180, 0xbe },
+  { 182, 0xcd },
+  { 192, 0xbf },
+  { 195, 0xce },
+  { 196, 0xdd },
+  { 208, 0xcf },
+  { 210, 0xde },
+  { 224, 0xdf },
+  { 225, 0xee },
+  { 240, 0xef },
+  { 256, 0xff }
diff --git a/usrp/host/lib/std_paths.h.in b/usrp/host/lib/std_paths.h.in
new file mode 100644 (file)
index 0000000..e09499e
--- /dev/null
@@ -0,0 +1,27 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+static const char *std_paths[] = {
+  "@prefix@/share/usrp",
+  "/usr/local/share/usrp",
+  0
+};
diff --git a/usrp/host/lib/usrp_basic.cc b/usrp/host/lib/usrp_basic.cc
new file mode 100644 (file)
index 0000000..4f3df52
--- /dev/null
@@ -0,0 +1,1552 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004,2008,2009 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/usrp_basic.h>
+#include "usrp/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>
+#include <math.h>
+#include <ad9862.h>
+#include <string.h>
+#include <cstdio>
+
+using namespace ad9862;
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+// These set the buffer size used for each end point using the fast
+// usb interface.  The kernel ends up locking down this much memory.
+
+static const int FUSB_BUFFER_SIZE = fusb_sysconfig::default_buffer_size();
+static const int FUSB_BLOCK_SIZE = fusb_sysconfig::max_block_size();
+static const int FUSB_NBLOCKS    = FUSB_BUFFER_SIZE / FUSB_BLOCK_SIZE;
+
+
+static const double POLLING_INTERVAL = 0.1;    // seconds
+
+////////////////////////////////////////////////////////////////
+
+static struct usb_dev_handle *
+open_rx_interface (struct usb_device *dev)
+{
+  struct usb_dev_handle *udh = usrp_open_rx_interface (dev);
+  if (udh == 0){
+    fprintf (stderr, "usrp_basic_rx: can't open rx interface\n");
+    usb_strerror ();
+  }
+  return udh;
+}
+
+static struct usb_dev_handle *
+open_tx_interface (struct usb_device *dev)
+{
+  struct usb_dev_handle *udh = usrp_open_tx_interface (dev);
+  if (udh == 0){
+    fprintf (stderr, "usrp_basic_tx: can't open tx interface\n");
+    usb_strerror ();
+  }
+  return udh;
+}
+
+
+//////////////////////////////////////////////////////////////////
+//
+//                     usrp_basic
+//
+////////////////////////////////////////////////////////////////
+
+
+// Given:
+//   CLKIN = 64 MHz
+//   CLKSEL pin = high 
+//
+// These settings give us:
+//   CLKOUT1 = CLKIN = 64 MHz
+//   CLKOUT2 = CLKIN = 64 MHz
+//   ADC is clocked at  64 MHz
+//   DAC is clocked at 128 MHz
+
+static unsigned char common_regs[] = {
+  REG_GENERAL,         0,
+  REG_DLL,             (DLL_DISABLE_INTERNAL_XTAL_OSC
+                        | DLL_MULT_2X
+                        | DLL_FAST),
+  REG_CLKOUT,          CLKOUT2_EQ_DLL_OVER_2,
+  REG_AUX_ADC_CLK,     AUX_ADC_CLK_CLK_OVER_4
+};
+
+
+usrp_basic::usrp_basic (int which_board, 
+                       struct usb_dev_handle *
+                       open_interface (struct usb_device *dev),
+                       const std::string fpga_filename,
+                       const std::string firmware_filename)
+  : 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_fpga_master_clock_freq(64000000), d_db(2)
+{
+  /*
+   * SWAG: Scientific Wild Ass Guess.
+   *
+   * d_usb_data_rate is used only to determine how often to poll for over- and under-runs.
+   * We defualt it to 1/2  of our best case.  Classes derived from usrp_basic (e.g., 
+   * usrp_standard_tx and usrp_standard_rx) call set_usb_data_rate() to tell us the
+   * actual rate.  This doesn't change our throughput, that's determined by the signal
+   * processing code in the FPGA (which we know nothing about), and the system limits
+   * determined by libusb, fusb_*, and the underlying drivers.
+   */
+  memset (d_fpga_shadows, 0, sizeof (d_fpga_shadows));
+
+  usrp_one_time_init ();
+
+  if (!usrp_load_standard_bits (which_board, false, fpga_filename, firmware_filename))
+    throw std::runtime_error ("usrp_basic/usrp_load_standard_bits");
+
+  struct usb_device *dev = usrp_find_device (which_board);
+  if (dev == 0){
+    fprintf (stderr, "usrp_basic: can't find usrp[%d]\n", which_board);
+    throw std::runtime_error ("usrp_basic/usrp_find_device");
+  }
+
+  if (!(usrp_usrp_p(dev) && usrp_hw_rev(dev) >= 1)){
+    fprintf (stderr, "usrp_basic: sorry, this code only works with USRP revs >= 1\n");
+    throw std::runtime_error ("usrp_basic/bad_rev");
+  }
+
+  if ((d_udh = open_interface (dev)) == 0)
+    throw std::runtime_error ("usrp_basic/open_interface");
+
+  // initialize registers that are common to rx and tx
+
+  if (!usrp_9862_write_many_all (d_udh, common_regs, sizeof (common_regs))){
+    fprintf (stderr, "usrp_basic: failed to init common AD9862 regs\n");
+    throw std::runtime_error ("usrp_basic/init_9862");
+  }
+
+  _write_fpga_reg (FR_MODE, 0);                // ensure we're in normal mode
+  _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 ()
+{
+  return true;         // nop
+}
+
+bool
+usrp_basic::stop ()
+{
+  return true;         // nop
+}
+
+void
+usrp_basic::set_usb_data_rate (int usb_data_rate)
+{
+  d_usb_data_rate = usb_data_rate;
+  d_bytes_per_poll = (int) (usb_data_rate * POLLING_INTERVAL);
+}
+
+bool
+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)
+{
+  return usrp_read_aux_adc (d_udh, slot, which_adc, value);
+}
+
+int
+usrp_basic::_read_aux_adc (int slot, int which_adc)
+{
+  int  value;
+  if (!_read_aux_adc (slot, which_adc, &value))
+    return READ_FAILED;
+
+  return value;
+}
+
+bool
+usrp_basic::write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf)
+{
+  return usrp_eeprom_write (d_udh, i2c_addr, eeprom_offset, buf.data (), buf.size ());
+}
+
+std::string
+usrp_basic::read_eeprom (int i2c_addr, int eeprom_offset, int len)
+{
+  if (len <= 0)
+    return "";
+
+  char buf[len];
+
+  if (!usrp_eeprom_read (d_udh, i2c_addr, eeprom_offset, buf, len))
+    return "";
+
+  return std::string (buf, len);
+}
+
+bool
+usrp_basic::write_i2c (int i2c_addr, const std::string buf)
+{
+  return usrp_i2c_write (d_udh, i2c_addr, buf.data (), buf.size ());
+}
+
+std::string
+usrp_basic::read_i2c (int i2c_addr, int len)
+{
+  if (len <= 0)
+    return "";
+
+  char buf[len];
+
+  if (!usrp_i2c_read (d_udh, i2c_addr, buf, len))
+    return "";
+
+  return std::string (buf, len);
+}
+
+std::string
+usrp_basic::serial_number()
+{
+  return usrp_serial_number(d_udh);
+}
+
+// ----------------------------------------------------------------
+
+bool
+usrp_basic::set_adc_offset (int which_adc, int offset)
+{
+  if (which_adc < 0 || which_adc > 3)
+    return false;
+
+  return _write_fpga_reg (FR_ADC_OFFSET_0 + which_adc, offset);
+}
+
+bool
+usrp_basic::set_dac_offset (int which_dac, int offset, int offset_pin)
+{
+  if (which_dac < 0 || which_dac > 3)
+    return false;
+
+  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;
+
+  if (tx_a){
+    ok =  _write_9862 (which_codec, REG_TX_A_OFFSET_LO, lo);
+    ok &= _write_9862 (which_codec, REG_TX_A_OFFSET_HI, hi);
+  }
+  else {
+    ok =  _write_9862 (which_codec, REG_TX_B_OFFSET_LO, lo);
+    ok &= _write_9862 (which_codec, REG_TX_B_OFFSET_HI, hi);
+  }
+  return ok;
+}
+
+bool
+usrp_basic::set_adc_buffer_bypass (int which_adc, bool bypass)
+{
+  if (which_adc < 0 || which_adc > 3)
+    return false;
+
+  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;
+
+  // If the input buffer is bypassed, we need to power it down too.
+
+  bool ok = _read_9862 (codec, reg, &cur_rx);
+  ok &= _read_9862 (codec, REG_RX_PWR_DN, &cur_pwr_dn);
+  if (!ok)
+    return false;
+
+  if (bypass){
+    cur_rx |= RX_X_BYPASS_INPUT_BUFFER;
+    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_adc & 1) == 0) ? RX_PWR_DN_BUF_A : RX_PWR_DN_BUF_B);
+  }
+
+  ok &= _write_9862 (codec, reg, cur_rx);
+  ok &= _write_9862 (codec, REG_RX_PWR_DN, cur_pwr_dn);
+  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
+usrp_basic::_write_fpga_reg (int regno, int value)
+{
+  if (d_verbose){
+    fprintf (stdout, "_write_fpga_reg(%3d, 0x%08x)\n", regno, value);
+    fflush (stdout);
+  }
+
+  if (regno >= 0 && regno < MAX_REGS)
+    d_fpga_shadows[regno] = value;
+
+  return usrp_write_fpga_reg (d_udh, regno, value);
+}
+
+bool
+usrp_basic::_write_fpga_reg_masked (int regno, int value, int mask)
+{
+  //Only use this for registers who actually use a mask in the verilog firmware, like FR_RX_MASTER_SLAVE
+  //value is a 16 bits value and mask is a 16 bits mask
+  if (d_verbose){
+    fprintf (stdout, "_write_fpga_reg_masked(%3d, 0x%04x,0x%04x)\n", regno, value, mask);
+    fflush (stdout);
+  }
+
+  if (regno >= 0 && regno < MAX_REGS)
+    d_fpga_shadows[regno] = value;
+
+  return usrp_write_fpga_reg (d_udh, regno, (value & 0xffff) | ((mask & 0xffff)<<16));
+}
+
+
+bool
+usrp_basic::_read_fpga_reg (int regno, int *value)
+{
+  return usrp_read_fpga_reg (d_udh, regno, value);
+}
+
+int
+usrp_basic::_read_fpga_reg (int regno)
+{
+  int value;
+  if (!_read_fpga_reg (regno, &value))
+    return READ_FAILED;
+  return value;
+}
+
+bool
+usrp_basic::_write_9862 (int which_codec, int regno, unsigned char value)
+{
+  if (0 && d_verbose){
+    // FIXME really want to enable logging in usrp_prims:usrp_9862_write
+    fprintf(stdout, "_write_9862(codec = %d, regno = %2d, val = 0x%02x)\n", which_codec, regno, value);
+    fflush(stdout);
+  }
+
+  return usrp_9862_write (d_udh, which_codec, regno, value);
+}
+
+
+bool
+usrp_basic::_read_9862 (int which_codec, int regno, unsigned char *value) const
+{
+  return usrp_9862_read (d_udh, which_codec, regno, value);
+}
+
+int
+usrp_basic::_read_9862 (int which_codec, int regno) const
+{
+  unsigned char value;
+  if (!_read_9862 (which_codec, regno, &value))
+    return READ_FAILED;
+  return value;
+}
+
+bool
+usrp_basic::_write_spi (int optional_header, int enables, int format, std::string buf)
+{
+  return usrp_spi_write (d_udh, optional_header, enables, format,
+                        buf.data(), buf.size());
+}
+
+std::string
+usrp_basic::_read_spi (int optional_header, int enables, int format, int len)
+{
+  if (len <= 0)
+    return "";
+  
+  char buf[len];
+
+  if (!usrp_spi_read (d_udh, optional_header, enables, format, buf, len))
+    return "";
+
+  return std::string (buf, len);
+}
+
+
+bool
+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 _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
+//
+////////////////////////////////////////////////////////////////
+
+static unsigned char rx_init_regs[] = {
+  REG_RX_PWR_DN,       0,
+  REG_RX_A,            0,      // minimum gain = 0x00 (max gain = 0x14)
+  REG_RX_B,            0,      // minimum gain = 0x00 (max gain = 0x14)
+  REG_RX_MISC,         (RX_MISC_HS_DUTY_CYCLE | RX_MISC_CLK_DUTY),
+  REG_RX_IF,           (RX_IF_USE_CLKOUT1
+                        | RX_IF_2S_COMP),
+  REG_RX_DIGITAL,      (RX_DIGITAL_2_CHAN)
+};
+
+
+usrp_basic_rx::usrp_basic_rx (int which_board, int fusb_block_size, int fusb_nblocks,
+                             const std::string fpga_filename,
+                             const std::string firmware_filename
+                             )
+  : usrp_basic (which_board, open_rx_interface, fpga_filename, firmware_filename),
+    d_devhandle (0), d_ephandle (0),
+    d_bytes_seen (0), d_first_read (true),
+    d_rx_enable (false)
+{
+  // initialize rx specific registers
+
+  if (!usrp_9862_write_many_all (d_udh, rx_init_regs, sizeof (rx_init_regs))){
+    fprintf (stderr, "usrp_basic_rx: failed to init AD9862 RX regs\n");
+    throw std::runtime_error ("usrp_basic_rx/init_9862");
+  }
+
+  if (0){
+    // FIXME power down 2nd codec rx path
+    usrp_9862_write (d_udh, 1, REG_RX_PWR_DN, 0x1);    // power down everything
+  }
+
+  // Reset the rx path and leave it disabled.
+  set_rx_enable (false);
+  usrp_set_fpga_rx_reset (d_udh, true);
+  usrp_set_fpga_rx_reset (d_udh, false);
+
+  set_fpga_rx_sample_rate_divisor (2); // usually correct
+
+  set_dc_offset_cl_enable(0xf, 0xf);   // enable DC offset removal control loops
+
+  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)
+    throw std::out_of_range ("usrp_basic_rx: invalid fusb_block_size");
+
+  if (fusb_nblocks < 0)
+    throw std::out_of_range ("usrp_basic_rx: invalid fusb_nblocks");
+  
+  if (fusb_block_size == 0)
+    fusb_block_size = fusb_sysconfig::default_block_size();
+
+  if (fusb_nblocks == 0)
+    fusb_nblocks = std::max (1, FUSB_BUFFER_SIZE / fusb_block_size);
+
+  d_devhandle = fusb_sysconfig::make_devhandle (d_udh);
+  d_ephandle = d_devhandle->make_ephandle (USRP_RX_ENDPOINT, true,
+                                          fusb_block_size, fusb_nblocks);
+
+  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[] = {
+  REG_RX_PWR_DN,       0x1                             // power down everything
+};
+
+usrp_basic_rx::~usrp_basic_rx ()
+{
+  if (!set_rx_enable (false)){
+    fprintf (stderr, "usrp_basic_rx: set_fpga_rx_enable failed\n");
+    usb_strerror ();
+  }
+
+  d_ephandle->stop ();
+  delete d_ephandle;
+  delete d_devhandle;
+
+  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();
+}
+
+
+bool
+usrp_basic_rx::start ()
+{
+  if (!usrp_basic::start ())   // invoke parent's method
+    return false;
+
+  // fire off reads before asserting rx_enable
+
+  if (!d_ephandle->start ()){
+    fprintf (stderr, "usrp_basic_rx: failed to start end point streaming");
+    usb_strerror ();
+    return false;
+  }
+
+  if (!set_rx_enable (true)){
+    fprintf (stderr, "usrp_basic_rx: set_rx_enable failed\n");
+    usb_strerror ();
+    return false;
+  }
+  
+  return true;
+}
+
+bool
+usrp_basic_rx::stop ()
+{
+  bool ok = usrp_basic::stop();
+
+  if (!set_rx_enable(false)){
+    fprintf (stderr, "usrp_basic_rx: set_rx_enable(false) failed\n");
+    usb_strerror ();
+    ok = false;
+  }
+
+  if (!d_ephandle->stop()){
+    fprintf (stderr, "usrp_basic_rx: failed to stop end point streaming");
+    usb_strerror ();
+    ok = false;
+  }
+
+  return ok;
+}
+
+usrp_basic_rx *
+usrp_basic_rx::make (int which_board, int fusb_block_size, int fusb_nblocks,
+                    const std::string fpga_filename,
+                    const std::string firmware_filename)
+{
+  usrp_basic_rx *u = 0;
+  
+  try {
+    u = new usrp_basic_rx (which_board, fusb_block_size, fusb_nblocks,
+                          fpga_filename, firmware_filename);
+    return u;
+  }
+  catch (...){
+    delete u;
+    return 0;
+  }
+
+  return u;
+}
+
+bool
+usrp_basic_rx::set_fpga_rx_sample_rate_divisor (unsigned int div)
+{
+  return _write_fpga_reg (FR_RX_SAMPLE_RATE_DIV, div - 1);
+}
+
+
+/*
+ * \brief read data from the D/A's via the FPGA.
+ * \p len must be a multiple of 512 bytes.
+ *
+ * \returns the number of bytes read, or -1 on error.
+ *
+ * If overrun is non-NULL it will be set true iff an RX overrun is detected.
+ */
+int
+usrp_basic_rx::read (void *buf, int len, bool *overrun)
+{
+  int  r;
+  
+  if (overrun)
+    *overrun = false;
+  
+  if (len < 0 || (len % 512) != 0){
+    fprintf (stderr, "usrp_basic_rx::read: invalid length = %d\n", len);
+    return -1;
+  }
+
+  r = d_ephandle->read (buf, len);
+  if (r > 0)
+    d_bytes_seen += r;
+
+  /*
+   * In many cases, the FPGA reports an rx overrun right after we
+   * enable the Rx path.  If this is our first read, check for the
+   * overrun to clear the condition, then ignore the result.
+   */
+  if (0 && d_first_read){      // FIXME
+    d_first_read = false;
+    bool bogus_overrun;
+    usrp_check_rx_overrun (d_udh, &bogus_overrun);
+  }
+
+  if (overrun != 0 && d_bytes_seen >= d_bytes_per_poll){
+    d_bytes_seen = 0;
+    if (!usrp_check_rx_overrun (d_udh, overrun)){
+      fprintf (stderr, "usrp_basic_rx: usrp_check_rx_overrun failed\n");
+      usb_strerror ();
+    }
+  }
+    
+  return r;
+}
+
+bool
+usrp_basic_rx::set_rx_enable (bool on)
+{
+  d_rx_enable = on;
+  return usrp_set_fpga_rx_enable (d_udh, on);
+}
+
+// conditional disable, return prev state
+bool
+usrp_basic_rx::disable_rx ()
+{
+  bool enabled = rx_enable ();
+  if (enabled)
+    set_rx_enable (false);
+  return enabled;
+}
+
+// conditional set
+void
+usrp_basic_rx::restore_rx (bool on)
+{
+  if (on != rx_enable ())
+    set_rx_enable (on);
+}
+
+void
+usrp_basic_rx::probe_rx_slots (bool verbose)
+{
+  struct usrp_dboard_eeprom    eeprom;
+  static int slot_id_map[2] = { SLOT_RX_A, SLOT_RX_B };
+  static const char *slot_name[2] = { "RX d'board A", "RX d'board B" };
+
+  for (int i = 0; i < 2; i++){
+    int slot_id = slot_id_map [i];
+    const char *msg = 0;
+    usrp_dbeeprom_status_t s = usrp_read_dboard_eeprom (d_udh, slot_id, &eeprom);
+
+    switch (s){
+    case UDBE_OK:
+      d_dbid[i] = eeprom.id;
+      msg = usrp_dbid_to_string (eeprom.id).c_str ();
+      set_adc_offset (2*i+0, eeprom.offset[0]);
+      set_adc_offset (2*i+1, eeprom.offset[1]);
+      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | eeprom.oe);
+      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
+      break;
+      
+    case UDBE_NO_EEPROM:
+      d_dbid[i] = -1;
+      msg = "<none>";
+      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
+      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
+      break;
+      
+    case UDBE_INVALID_EEPROM:
+      d_dbid[i] = -2;
+      msg = "Invalid EEPROM contents";
+      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
+      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
+      break;
+      
+    case UDBE_BAD_SLOT:
+    default:
+      assert (0);
+    }
+
+    if (verbose){
+      fflush (stdout);
+      fprintf (stderr, "%s: %s\n", slot_name[i], msg);
+    }
+  }
+}
+
+bool
+usrp_basic_rx::set_pga (int which_amp, double gain)
+{
+  return common_set_pga(C_RX, which_amp, gain);
+}
+
+double
+usrp_basic_rx::pga(int which_amp) const
+{
+  return common_pga(C_RX, which_amp);
+}
+
+double
+usrp_basic_rx::pga_min() const
+{
+  return common_pga_min(C_RX);
+}
+
+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::_write_oe (int which_side, int value, int mask)
+{
+  return _common_write_oe(C_RX, which_side, value, mask);
+}
+
+bool
+usrp_basic_rx::write_io (int which_side, int value, int mask)
+{
+  return common_write_io(C_RX, which_side, value, mask);
+}
+
+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_side)
+{
+  return common_read_io(C_RX, which_side);
+}
+
+bool
+usrp_basic_rx::write_refclk(int which_side, int value)
+{
+  return common_write_refclk(C_RX, which_side, value);
+}
+
+bool
+usrp_basic_rx::write_atr_mask(int which_side, int value)
+{
+  return common_write_atr_mask(C_RX, which_side, value);
+}
+
+bool
+usrp_basic_rx::write_atr_txval(int which_side, int value)
+{
+  return common_write_atr_txval(C_RX, which_side, value);
+}
+
+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::write_aux_dac (int which_side, int which_dac, int value)
+{
+  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
+//
+////////////////////////////////////////////////////////////////
+
+
+//
+// DAC input rate 64 MHz interleaved for a total input rate of 128 MHz
+// DAC input is latched on rising edge of CLKOUT2
+// NCO is disabled
+// interpolate 2x
+// coarse modulator disabled
+//
+
+static unsigned char tx_init_regs[] = {
+  REG_TX_PWR_DN,       0,
+  REG_TX_A_OFFSET_LO,  0,
+  REG_TX_A_OFFSET_HI,  0,
+  REG_TX_B_OFFSET_LO,  0,
+  REG_TX_B_OFFSET_HI,  0,
+  REG_TX_A_GAIN,       (TX_X_GAIN_COARSE_FULL | 0),
+  REG_TX_B_GAIN,       (TX_X_GAIN_COARSE_FULL | 0),
+  REG_TX_PGA,          0xff,                   // maximum gain (0 dB)
+  REG_TX_MISC,         0,
+  REG_TX_IF,           (TX_IF_USE_CLKOUT1
+                        | TX_IF_I_FIRST
+                        | TX_IF_INV_TX_SYNC
+                        | TX_IF_2S_COMP
+                        | TX_IF_INTERLEAVED),
+  REG_TX_DIGITAL,      (TX_DIGITAL_2_DATA_PATHS
+                        | TX_DIGITAL_INTERPOLATE_4X),
+  REG_TX_MODULATOR,    (TX_MODULATOR_DISABLE_NCO
+                        | TX_MODULATOR_COARSE_MODULATION_NONE),
+  REG_TX_NCO_FTW_7_0,  0,
+  REG_TX_NCO_FTW_15_8, 0,
+  REG_TX_NCO_FTW_23_16,        0
+};
+
+usrp_basic_tx::usrp_basic_tx (int which_board, int fusb_block_size, int fusb_nblocks,
+                             const std::string fpga_filename,
+                             const std::string firmware_filename)
+  : usrp_basic (which_board, open_tx_interface, fpga_filename, firmware_filename),
+    d_devhandle (0), d_ephandle (0),
+    d_bytes_seen (0), d_first_write (true),
+    d_tx_enable (false)
+{
+  if (!usrp_9862_write_many_all (d_udh, tx_init_regs, sizeof (tx_init_regs))){
+    fprintf (stderr, "usrp_basic_tx: failed to init AD9862 TX regs\n");
+    throw std::runtime_error ("usrp_basic_tx/init_9862");
+  }
+
+  if (0){
+    // FIXME power down 2nd codec tx path
+    usrp_9862_write (d_udh, 1, REG_TX_PWR_DN,
+                    (TX_PWR_DN_TX_DIGITAL
+                     | TX_PWR_DN_TX_ANALOG_BOTH));
+  }
+
+  // Reset the tx path and leave it disabled.
+  set_tx_enable (false);
+  usrp_set_fpga_tx_reset (d_udh, true);
+  usrp_set_fpga_tx_reset (d_udh, false);
+
+  set_fpga_tx_sample_rate_divisor (4); // we're using interp x4
+
+  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)
+    throw std::out_of_range ("usrp_basic_rx: invalid fusb_block_size");
+
+  if (fusb_nblocks < 0)
+    throw std::out_of_range ("usrp_basic_rx: invalid fusb_nblocks");
+  
+  if (fusb_block_size == 0)
+    fusb_block_size = FUSB_BLOCK_SIZE;
+
+  if (fusb_nblocks == 0)
+    fusb_nblocks = std::max (1, FUSB_BUFFER_SIZE / fusb_block_size);
+
+  d_devhandle = fusb_sysconfig::make_devhandle (d_udh);
+  d_ephandle = d_devhandle->make_ephandle (USRP_TX_ENDPOINT, false,
+                                          fusb_block_size, fusb_nblocks);
+
+  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);
+}
+
+
+static unsigned char tx_fini_regs[] = {
+  REG_TX_PWR_DN,       (TX_PWR_DN_TX_DIGITAL
+                        | TX_PWR_DN_TX_ANALOG_BOTH),
+  REG_TX_MODULATOR,    (TX_MODULATOR_DISABLE_NCO
+                        | TX_MODULATOR_COARSE_MODULATION_NONE)
+};
+
+usrp_basic_tx::~usrp_basic_tx ()
+{
+  d_ephandle->stop ();
+  delete d_ephandle;
+  delete d_devhandle;
+
+  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
+usrp_basic_tx::start ()
+{
+  if (!usrp_basic::start ())
+    return false;
+
+  if (!set_tx_enable (true)){
+    fprintf (stderr, "usrp_basic_tx: set_tx_enable failed\n");
+    usb_strerror ();
+    return false;
+  }
+  
+  if (!d_ephandle->start ()){
+    fprintf (stderr, "usrp_basic_tx: failed to start end point streaming");
+    usb_strerror ();
+    return false;
+  }
+
+  return true;
+}
+
+bool
+usrp_basic_tx::stop ()
+{
+  bool ok = usrp_basic::stop ();
+
+  if (!d_ephandle->stop ()){
+    fprintf (stderr, "usrp_basic_tx: failed to stop end point streaming");
+    usb_strerror ();
+    ok = false;
+  }
+
+  if (!set_tx_enable (false)){
+    fprintf (stderr, "usrp_basic_tx: set_tx_enable(false) failed\n");
+    usb_strerror ();
+    ok = false;
+  }
+
+  return ok;
+}
+
+usrp_basic_tx *
+usrp_basic_tx::make (int which_board, int fusb_block_size, int fusb_nblocks,
+                    const std::string fpga_filename,
+                    const std::string firmware_filename)
+{
+  usrp_basic_tx *u = 0;
+  
+  try {
+    u = new usrp_basic_tx (which_board, fusb_block_size, fusb_nblocks,
+                          fpga_filename, firmware_filename);
+    return u;
+  }
+  catch (...){
+    delete u;
+    return 0;
+  }
+
+  return u;
+}
+
+bool
+usrp_basic_tx::set_fpga_tx_sample_rate_divisor (unsigned int div)
+{
+  return _write_fpga_reg (FR_TX_SAMPLE_RATE_DIV, div - 1);
+}
+
+/*!
+ * \brief Write data to the A/D's via the FPGA.
+ *
+ * \p len must be a multiple of 512 bytes.
+ * \returns number of bytes written or -1 on error.
+ *
+ * if \p underrun is non-NULL, it will be set to true iff
+ * a transmit underrun condition is detected.
+ */
+int
+usrp_basic_tx::write (const void *buf, int len, bool *underrun)
+{
+  int  r;
+  
+  if (underrun)
+    *underrun = false;
+  
+  if (len < 0 || (len % 512) != 0){
+    fprintf (stderr, "usrp_basic_tx::write: invalid length = %d\n", len);
+    return -1;
+  }
+
+  r = d_ephandle->write (buf, len);
+  if (r > 0)
+    d_bytes_seen += r;
+    
+  /*
+   * In many cases, the FPGA reports an tx underrun right after we
+   * enable the Tx path.  If this is our first write, check for the
+   * underrun to clear the condition, then ignore the result.
+   */
+  if (d_first_write && d_bytes_seen >= 4 * FUSB_BLOCK_SIZE){
+    d_first_write = false;
+    bool bogus_underrun;
+    usrp_check_tx_underrun (d_udh, &bogus_underrun);
+  }
+
+  if (underrun != 0 && d_bytes_seen >= d_bytes_per_poll){
+    d_bytes_seen = 0;
+    if (!usrp_check_tx_underrun (d_udh, underrun)){
+      fprintf (stderr, "usrp_basic_tx: usrp_check_tx_underrun failed\n");
+      usb_strerror ();
+    }
+  }
+
+  return r;
+}
+
+void
+usrp_basic_tx::wait_for_completion ()
+{
+  d_ephandle->wait_for_completion ();
+}
+
+bool
+usrp_basic_tx::set_tx_enable (bool on)
+{
+  d_tx_enable = on;
+  // fprintf (stderr, "set_tx_enable %d\n", on);
+  return usrp_set_fpga_tx_enable (d_udh, on);
+}
+
+// conditional disable, return prev state
+bool
+usrp_basic_tx::disable_tx ()
+{
+  bool enabled = tx_enable ();
+  if (enabled)
+    set_tx_enable (false);
+  return enabled;
+}
+
+// conditional set
+void
+usrp_basic_tx::restore_tx (bool on)
+{
+  if (on != tx_enable ())
+    set_tx_enable (on);
+}
+
+void
+usrp_basic_tx::probe_tx_slots (bool verbose)
+{
+  struct usrp_dboard_eeprom    eeprom;
+  static int slot_id_map[2] = { SLOT_TX_A, SLOT_TX_B };
+  static const char *slot_name[2] = { "TX d'board A", "TX d'board B" };
+
+  for (int i = 0; i < 2; i++){
+    int slot_id = slot_id_map [i];
+    const char *msg = 0;
+    usrp_dbeeprom_status_t s = usrp_read_dboard_eeprom (d_udh, slot_id, &eeprom);
+
+    switch (s){
+    case UDBE_OK:
+      d_dbid[i] = eeprom.id;
+      msg = usrp_dbid_to_string (eeprom.id).c_str ();
+      // FIXME, figure out interpretation of dc offset for TX d'boards
+      // offset = (eeprom.offset[1] << 16) | (eeprom.offset[0] & 0xffff);
+      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | eeprom.oe);
+      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
+      break;
+      
+    case UDBE_NO_EEPROM:
+      d_dbid[i] = -1;
+      msg = "<none>";
+      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
+      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
+      break;
+      
+    case UDBE_INVALID_EEPROM:
+      d_dbid[i] = -2;
+      msg = "Invalid EEPROM contents";
+      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
+      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
+      break;
+      
+    case UDBE_BAD_SLOT:
+    default:
+      assert (0);
+    }
+
+    if (verbose){
+      fflush (stdout);
+      fprintf (stderr, "%s: %s\n", slot_name[i], msg);
+    }
+  }
+}
+
+bool
+usrp_basic_tx::set_pga (int which_amp, double gain)
+{
+  return common_set_pga(C_TX, which_amp, gain);
+}
+
+double
+usrp_basic_tx::pga (int which_amp) const
+{
+  return common_pga(C_TX, which_amp);
+}
+
+double
+usrp_basic_tx::pga_min() const
+{
+  return common_pga_min(C_TX);
+}
+
+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::_write_oe (int which_side, int value, int mask)
+{
+  return _common_write_oe(C_TX, which_side, value, mask);
+}
+
+bool
+usrp_basic_tx::write_io (int which_side, int value, int mask)
+{
+  return common_write_io(C_TX, which_side, value, mask);
+}
+
+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_side)
+{
+  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_side, int which_dac, int value)
+{
+  return common_write_aux_dac(C_TX, which_side, which_dac, value);
+}
+
+bool
+usrp_basic_tx::read_aux_adc (int which_side, int which_adc, int *value)
+{
+  return common_read_aux_adc(C_TX, which_side, which_adc, value);
+}
+
+int
+usrp_basic_tx::read_aux_adc (int which_side, int which_adc)
+{
+  return common_read_aux_adc(C_TX, which_side, which_adc);
+}
+
+int
+usrp_basic_tx::block_size () const { return d_ephandle->block_size(); }
+
diff --git a/usrp/host/lib/usrp_config.cc b/usrp/host/lib/usrp_config.cc
new file mode 100644 (file)
index 0000000..fcf207f
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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_config.h"
+
+int
+usrp_rx_config_stream_count (unsigned int usrp_rx_config)
+{
+  return 1;
+}
+
+int
+usrp_tx_config_stream_count (unsigned int usrp_tx_config)
+{
+  return 1;
+}
diff --git a/usrp/host/lib/usrp_config.h b/usrp/host/lib/usrp_config.h
new file mode 100644 (file)
index 0000000..ee5cb63
--- /dev/null
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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 _USRP_CONFIG_H_
+#define _USRP_CONFIG_H_
+
+/*
+ * ----------------------------------------------------------------
+ * USRP Rx configurations.
+ *
+ * For now this is a placeholder, but will eventually specify the
+ * mapping from A/D outputs to DDC inputs (I & Q).
+ *
+ * What's implemented today is a single DDC that has its I input
+ * connected to ADC0 and its Q input connected to ADC1
+ * ----------------------------------------------------------------
+ */
+
+#define        USRP_RX_CONFIG_DEFAULT  0
+
+/*!
+ * given a usrp_rx_config word, return the number of I & Q streams that
+ * are interleaved on the USB.
+ */
+
+int usrp_rx_config_stream_count (unsigned int usrp_rx_config);
+
+/*
+ * USRP Tx configurations.
+ *
+ * For now this is a placeholder, but will eventually specify the
+ * mapping from DUC outputs to D/A inputs.
+ *
+ * What's implemented today is a single DUC that has its I output
+ * connected to DAC0 and its Q output connected to DAC1
+ */
+
+#define        USRP_TX_CONFIG_DEFAULT  0
+
+/*!
+ * given a usrp_tx_config word, return the number of I & Q streams that
+ * are interleaved on the USB.
+ */
+
+int usrp_tx_config_stream_count (unsigned int usrp_tx_config);
+
+
+#endif /* _USRP_CONFIG_H_ */
diff --git a/usrp/host/lib/usrp_dbid.dat b/usrp/host/lib/usrp_dbid.dat
new file mode 100644 (file)
index 0000000..bd7fd7e
--- /dev/null
@@ -0,0 +1,82 @@
+#
+# Copyright 2005,2009 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.
+#
+
+# This file is used to generate usrp_dbid.h, usrp_dbid.cc and usrp_dbid.py
+
+"Basic Tx"             0x0000
+"Basic Rx"             0x0001
+"DBS Rx"               0x0002
+"TV Rx"                        0x0003
+
+"Flex 400 Rx"          0x0004
+"Flex 900 Rx"          0x0005
+"Flex 1200 Rx"         0x0006
+"Flex 2400 Rx"         0x0007
+
+"Flex 400 Tx"          0x0008
+"Flex 900 Tx"          0x0009
+"Flex 1200 Tx"         0x000a
+"Flex 2400 Tx"         0x000b
+
+"TV Rx Rev 2"          0x000c
+"DBS Rx ClkMod"                0x000d
+
+"LF Tx"                        0x000e
+"LF Rx"                        0x000f
+
+"Flex 400 Rx MIMO A"   0x0014
+"Flex 900 Rx MIMO A"   0x0015
+"Flex 1200 Rx MIMO A"  0x0016
+"Flex 2400 Rx MIMO A"  0x0017
+
+"Flex 400 Tx MIMO A"   0x0018
+"Flex 900 Tx MIMO A"   0x0019
+"Flex 1200 Tx MIMO A"  0x001a
+"Flex 2400 Tx MIMO A"  0x001b
+
+"Flex 400 Rx MIMO B"   0x0024
+"Flex 900 Rx MIMO B"   0x0025
+"Flex 1200 Rx MIMO B"  0x0026
+"Flex 2400 Rx MIMO B"  0x0027
+
+"Flex 400 Tx MIMO B"   0x0028
+"Flex 900 Tx MIMO B"   0x0029
+"Flex 1200 Tx MIMO B"  0x002a
+"Flex 2400 Tx MIMO B"  0x002b
+
+"Flex 1800 Rx"         0x0030
+"Flex 1800 Tx"         0x0031
+"Flex 1800 Rx MIMO A"  0x0032
+"Flex 1800 Tx MIMO A"  0x0033
+"Flex 1800 Rx MIMO B"  0x0034
+"Flex 1800 Tx MIMO B"  0x0035
+
+"TV Rx Rev 3"          0x0040
+"DTT754"               0x0041
+"DTT768"               0x0042
+
+"WBX LO TX"            0x0050
+"WBX LO RX"            0x0051
+
+"XCVR2450 Tx"          0x0060
+"XCVR2450 Rx"          0x0061
+
+"Experimental Tx"      0xfffe
+"Experimental Rx"      0xffff
diff --git a/usrp/host/lib/usrp_local_sighandler.cc b/usrp/host/lib/usrp_local_sighandler.cc
new file mode 100644 (file)
index 0000000..5901397
--- /dev/null
@@ -0,0 +1,191 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009 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.
+ */
+
+/*
+ * This is actually the same as gr_local_signhandler, but with a different name.
+ * We don't have a common library to put this in, so...
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp/usrp_local_sighandler.h>
+#include <stdexcept>
+#include <stdio.h>
+#include <string.h>
+
+usrp_local_sighandler::usrp_local_sighandler (int signum,
+                                             void (*new_handler)(int))
+  : d_signum (signum)
+{
+#ifdef HAVE_SIGACTION
+  struct sigaction new_action;
+  memset (&new_action, 0, sizeof (new_action));
+
+  new_action.sa_handler = new_handler;
+  sigemptyset (&new_action.sa_mask);
+  new_action.sa_flags = 0;
+
+  if (sigaction (d_signum, &new_action, &d_old_action) < 0){
+    perror ("sigaction (install new)");
+    throw std::runtime_error ("sigaction");
+  }
+#endif
+}
+
+usrp_local_sighandler::~usrp_local_sighandler ()
+{
+#ifdef HAVE_SIGACTION
+  if (sigaction (d_signum, &d_old_action, 0) < 0){
+    perror ("sigaction (restore old)");
+    throw std::runtime_error ("sigaction");
+  }
+#endif
+}
+
+void
+usrp_local_sighandler::throw_signal(int signum) throw(usrp_signal)
+{
+  throw usrp_signal (signum);
+}
+
+/*
+ * Semi-hideous way to may a signal number into a signal name
+ */
+
+#define SIGNAME(x) case x: return #x
+
+std::string
+usrp_signal::name () const
+{
+  char tmp[128];
+
+  switch (signal ()){
+#ifdef SIGHUP
+    SIGNAME (SIGHUP);
+#endif
+#ifdef SIGINT
+    SIGNAME (SIGINT);
+#endif
+#ifdef SIGQUIT
+    SIGNAME (SIGQUIT);
+#endif
+#ifdef SIGILL
+    SIGNAME (SIGILL);
+#endif
+#ifdef SIGTRAP
+    SIGNAME (SIGTRAP);
+#endif
+#ifdef SIGABRT
+    SIGNAME (SIGABRT);
+#endif
+#ifdef SIGBUS
+    SIGNAME (SIGBUS);
+#endif
+#ifdef SIGFPE
+    SIGNAME (SIGFPE);
+#endif
+#ifdef SIGKILL
+    SIGNAME (SIGKILL);
+#endif
+#ifdef SIGUSR1
+    SIGNAME (SIGUSR1);
+#endif
+#ifdef SIGSEGV
+    SIGNAME (SIGSEGV);
+#endif
+#ifdef SIGUSR2
+    SIGNAME (SIGUSR2);
+#endif
+#ifdef SIGPIPE
+    SIGNAME (SIGPIPE);
+#endif
+#ifdef SIGALRM
+    SIGNAME (SIGALRM);
+#endif
+#ifdef SIGTERM
+    SIGNAME (SIGTERM);
+#endif
+#ifdef SIGSTKFLT
+    SIGNAME (SIGSTKFLT);
+#endif
+#ifdef SIGCHLD
+    SIGNAME (SIGCHLD);
+#endif
+#ifdef SIGCONT
+    SIGNAME (SIGCONT);
+#endif
+#ifdef SIGSTOP
+    SIGNAME (SIGSTOP);
+#endif
+#ifdef SIGTSTP
+    SIGNAME (SIGTSTP);
+#endif
+#ifdef SIGTTIN
+    SIGNAME (SIGTTIN);
+#endif
+#ifdef SIGTTOU
+    SIGNAME (SIGTTOU);
+#endif
+#ifdef SIGURG
+    SIGNAME (SIGURG);
+#endif
+#ifdef SIGXCPU
+    SIGNAME (SIGXCPU);
+#endif
+#ifdef SIGXFSZ
+    SIGNAME (SIGXFSZ);
+#endif
+#ifdef SIGVTALRM
+    SIGNAME (SIGVTALRM);
+#endif
+#ifdef SIGPROF
+    SIGNAME (SIGPROF);
+#endif
+#ifdef SIGWINCH
+    SIGNAME (SIGWINCH);
+#endif
+#ifdef SIGIO
+    SIGNAME (SIGIO);
+#endif
+#ifdef SIGPWR
+    SIGNAME (SIGPWR);
+#endif
+#ifdef SIGSYS
+    SIGNAME (SIGSYS);
+#endif
+  default:
+#if defined (HAVE_SNPRINTF)
+#if defined (SIGRTMIN) && defined (SIGRTMAX) 
+    if (signal () >= SIGRTMIN && signal () <= SIGRTMAX){
+      snprintf (tmp, sizeof (tmp), "SIGRTMIN + %d", signal ());
+      return tmp;
+    }
+#endif
+    snprintf (tmp, sizeof (tmp), "SIGNAL %d", signal ());
+    return tmp;
+#else
+    return "Unknown signal";
+#endif
+  }
+}
diff --git a/usrp/host/lib/usrp_prims.cc b/usrp/host/lib/usrp_prims.cc
new file mode 100644 (file)
index 0000000..3d87d24
--- /dev/null
@@ -0,0 +1,1357 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004,2006,2009 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/usrp_prims.h"
+#include "usrp_commands.h"
+#include "usrp_ids.h"
+#include "usrp_i2c_addr.h"
+#include "fpga_regs_common.h"
+#include "fpga_regs_standard.h"
+#include <usb.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>              // FIXME should check with autoconf (nanosleep)
+#include <algorithm>
+#include <ad9862.h>
+#include <assert.h>
+
+extern "C" {
+#include "md5.h"
+};
+
+#define VERBOSE 0
+
+using namespace ad9862;
+
+static const int FIRMWARE_HASH_SLOT    = 0;
+static const int FPGA_HASH_SLOT        = 1;
+
+static const int hash_slot_addr[2] = {
+  USRP_HASH_SLOT_0_ADDR,
+  USRP_HASH_SLOT_1_ADDR
+};
+
+static const char *default_firmware_filename = "std.ihx";
+static const char *default_fpga_filename     = "std_2rxhb_2tx.rbf";
+
+#include "std_paths.h"
+#include <stdio.h>
+
+static char *
+find_file (const char *filename, int hw_rev)
+{
+  const char **sp = std_paths;
+  static char path[1000];
+  char *s;
+
+  s = getenv("USRP_PATH");
+  if (s) {
+    snprintf (path, sizeof (path), "%s/rev%d/%s", s, hw_rev, filename);
+    if (access (path, R_OK) == 0)
+      return path;
+  }
+
+  while (*sp){
+    snprintf (path, sizeof (path), "%s/rev%d/%s", *sp, hw_rev, filename);
+    if (access (path, R_OK) == 0)
+      return path;
+    sp++;
+  }
+  return 0;
+}
+
+static const char *
+get_proto_filename(const std::string user_filename, const char *env_var, const char *def)
+{
+  if (user_filename.length() != 0)
+    return user_filename.c_str();
+
+  char *s = getenv(env_var);
+  if (s && *s)
+    return s;
+
+  return def;
+}
+
+
+static void power_down_9862s (struct usb_dev_handle *udh);
+
+void
+usrp_one_time_init ()
+{
+  static bool first = true;
+
+  if (first){
+    first = false;
+    usb_init ();                       // usb library init
+    usb_find_busses ();
+    usb_find_devices ();
+  }
+}
+
+void
+usrp_rescan ()
+{
+  usb_find_busses ();
+  usb_find_devices ();
+}
+
+
+// ----------------------------------------------------------------
+// Danger, big, fragile KLUDGE.  The problem is that we want to be
+// able to get from a usb_dev_handle back to a usb_device, and the
+// right way to do this is buried in a non-installed include file.
+
+static struct usb_device *
+dev_handle_to_dev (usb_dev_handle *udh)
+{
+  struct usb_dev_handle_kludge {
+    int                         fd;
+    struct usb_bus     *bus;
+    struct usb_device  *device;
+  };
+
+  return ((struct usb_dev_handle_kludge *) udh)->device;
+}
+
+// ----------------------------------------------------------------
+
+/*
+ * q must be a real USRP, not an FX2.  Return its hardware rev number.
+ */
+int
+usrp_hw_rev (struct usb_device *q)
+{
+  return q->descriptor.bcdDevice & 0x00FF;
+}
+
+/*
+ * q must be a real USRP, not an FX2.  Return true if it's configured.
+ */
+static bool
+_usrp_configured_p (struct usb_device *q)
+{
+  return (q->descriptor.bcdDevice & 0xFF00) != 0;
+}
+
+bool
+usrp_usrp_p (struct usb_device *q)
+{
+  return (q->descriptor.idVendor == USB_VID_FSF
+         && q->descriptor.idProduct == USB_PID_FSF_USRP);
+}
+
+bool
+usrp_fx2_p (struct usb_device *q)
+{
+  return (q->descriptor.idVendor == USB_VID_CYPRESS
+         && q->descriptor.idProduct == USB_PID_CYPRESS_FX2);
+}
+
+bool
+usrp_usrp0_p (struct usb_device *q)
+{
+  return usrp_usrp_p (q) && usrp_hw_rev (q) == 0;
+}
+
+bool
+usrp_usrp1_p (struct usb_device *q)
+{
+  return usrp_usrp_p (q) && usrp_hw_rev (q) == 1;
+}
+
+bool
+usrp_usrp2_p (struct usb_device *q)
+{
+  return usrp_usrp_p (q) && usrp_hw_rev (q) == 2;
+}
+
+
+bool
+usrp_unconfigured_usrp_p (struct usb_device *q)
+{
+  return usrp_usrp_p (q) && !_usrp_configured_p (q);
+}
+
+bool
+usrp_configured_usrp_p (struct usb_device *q)
+{
+  return usrp_usrp_p (q) && _usrp_configured_p (q);
+}
+
+// ----------------------------------------------------------------
+
+struct usb_device *
+usrp_find_device (int nth, bool fx2_ok_p)
+{
+  struct usb_bus *p;
+  struct usb_device *q;
+  int   n_found = 0;
+
+  usrp_one_time_init ();
+  
+  p = usb_get_busses();
+  while (p != NULL){
+    q = p->devices;
+    while (q != NULL){
+      if (usrp_usrp_p (q) || (fx2_ok_p && usrp_fx2_p (q))){
+       if (n_found == nth)     // return this one
+         return q;
+       n_found++;              // keep looking
+      }
+      q = q->next;
+    }
+    p = p->next;
+  }
+  return 0;    // not found
+}
+
+static struct usb_dev_handle *
+usrp_open_interface (struct usb_device *dev, int interface, int altinterface)
+{
+  struct usb_dev_handle *udh = usb_open (dev);
+  if (udh == 0)
+    return 0;
+
+  if (dev != dev_handle_to_dev (udh)){
+    fprintf (stderr, "%s:%d: internal error!\n", __FILE__, __LINE__);
+    abort ();
+  }
+
+#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+  // There's no get get_configuration function, and with some of the newer kernels
+  // setting the configuration, even if to the same value, hoses any other processes
+  // that have it open.  Hence we opt to not set it at all (We've only
+  // got a single configuration anyway).  This may hose the win32 stuff...
+
+  // Appears to be required for libusb-win32 and Cygwin -- dew 09/20/06
+  if (usb_set_configuration (udh, 1) < 0){
+    /*
+     * Ignore this error.  
+     *
+     * Seems that something changed in drivers/usb/core/devio.c:proc_setconfig such that
+     * it returns -EBUSY if _any_ of the interfaces of a device are open.
+     * We've only got a single configuration, so setting it doesn't even seem
+     * like it should be required.
+     */
+  }
+#endif
+
+  if (usb_claim_interface (udh, interface) < 0){
+    fprintf (stderr, "%s:usb_claim_interface: failed interface %d\n", __FUNCTION__,interface);
+    fprintf (stderr, "%s\n", usb_strerror());
+    usb_close (udh);
+    return 0;
+  }
+
+  if (usb_set_altinterface (udh, altinterface) < 0){
+    fprintf (stderr, "%s:usb_set_alt_interface: failed\n", __FUNCTION__);
+    fprintf (stderr, "%s\n", usb_strerror());
+    usb_release_interface (udh, interface);
+    usb_close (udh);
+    return 0;
+  }
+
+  return udh;
+}
+
+struct usb_dev_handle *
+usrp_open_cmd_interface (struct usb_device *dev)
+{
+  return usrp_open_interface (dev, USRP_CMD_INTERFACE, USRP_CMD_ALTINTERFACE);
+}
+
+struct usb_dev_handle *
+usrp_open_rx_interface (struct usb_device *dev)
+{
+  return usrp_open_interface (dev, USRP_RX_INTERFACE, USRP_RX_ALTINTERFACE);
+}
+
+struct usb_dev_handle *
+usrp_open_tx_interface (struct usb_device *dev)
+{
+  return usrp_open_interface (dev, USRP_TX_INTERFACE, USRP_TX_ALTINTERFACE);
+}
+
+bool
+usrp_close_interface (struct usb_dev_handle *udh)
+{
+  // we're assuming that closing an interface automatically releases it.
+  return usb_close (udh) == 0;
+}
+
+// ----------------------------------------------------------------
+// write internal ram using Cypress vendor extension
+
+static bool
+write_internal_ram (struct usb_dev_handle *udh, unsigned char *buf,
+                   int start_addr, size_t len)
+{
+  int addr;
+  int n;
+  int a;
+  int quanta = MAX_EP0_PKTSIZE;
+
+  for (addr = start_addr; addr < start_addr + (int) len; addr += quanta){
+    n = len + start_addr - addr;
+    if (n > quanta)
+      n = quanta;
+
+    a = usb_control_msg (udh, 0x40, 0xA0,
+                        addr, 0, (char *)(buf + (addr - start_addr)), n, 1000);
+
+    if (a < 0){
+      fprintf(stderr,"write_internal_ram failed: %s\n", usb_strerror());
+      return false;
+    }
+  }
+  return true;
+}
+
+// ----------------------------------------------------------------
+// whack the CPUCS register using the upload RAM vendor extension
+
+static bool
+reset_cpu (struct usb_dev_handle *udh, bool reset_p)
+{
+  unsigned char v;
+
+  if (reset_p)
+    v = 1;             // hold processor in reset
+  else
+    v = 0;             // release reset
+
+  return write_internal_ram (udh, &v, 0xE600, 1);
+}
+
+// ----------------------------------------------------------------
+// Load intel format file into cypress FX2 (8051)
+
+static bool
+_usrp_load_firmware (struct usb_dev_handle *udh, const char *filename,
+                    unsigned char hash[USRP_HASH_SIZE])
+{
+  FILE *f = fopen (filename, "ra");
+  if (f == 0){
+    perror (filename);
+    return false;
+  }
+
+  if (!reset_cpu (udh, true))  // hold CPU in reset while loading firmware
+    goto fail;
+
+  
+  char s[1024];
+  int length;
+  int addr;
+  int type;
+  unsigned char data[256];
+  unsigned char checksum, a;
+  unsigned int b;
+  int i;
+
+  while (!feof(f)){
+    fgets(s, sizeof (s), f); /* we should not use more than 263 bytes normally */
+    if(s[0]!=':'){
+      fprintf(stderr,"%s: invalid line: \"%s\"\n", filename, s);
+      goto fail;
+    }
+    sscanf(s+1, "%02x", &length);
+    sscanf(s+3, "%04x", &addr);
+    sscanf(s+7, "%02x", &type);
+
+    if(type==0){
+
+      a=length+(addr &0xff)+(addr>>8)+type;
+      for(i=0;i<length;i++){
+       sscanf (s+9+i*2,"%02x", &b);
+       data[i]=b;
+       a=a+data[i];
+      }
+
+      sscanf (s+9+length*2,"%02x", &b);
+      checksum=b;
+      if (((a+checksum)&0xff)!=0x00){
+       fprintf (stderr, "  ** Checksum failed: got 0x%02x versus 0x%02x\n", (-a)&0xff, checksum);
+       goto fail;
+      }
+      if (!write_internal_ram (udh, data, addr, length))
+       goto fail;
+    }
+    else if (type == 0x01){      // EOF
+      break;
+    }
+    else if (type == 0x02){
+      fprintf(stderr, "Extended address: whatever I do with it?\n");
+      fprintf (stderr, "%s: invalid line: \"%s\"\n", filename, s);
+      goto fail;
+    }
+  }
+
+  // we jam the hash value into the FX2 memory before letting
+  // the cpu out of reset.  When it comes out of reset it
+  // may renumerate which will invalidate udh.
+
+  if (!usrp_set_hash (udh, FIRMWARE_HASH_SLOT, hash))
+    fprintf (stderr, "usrp: failed to write firmware hash slot\n");
+
+  if (!reset_cpu (udh, false))         // take CPU out of reset
+    goto fail;
+
+  fclose (f);
+  return true;
+
+ fail:
+  fclose (f);
+  return false;
+}
+
+// ----------------------------------------------------------------
+// write vendor extension command to USRP
+
+static int
+write_cmd (struct usb_dev_handle *udh,
+          int request, int value, int index,
+          unsigned char *bytes, int len)
+{
+  int  requesttype = (request & 0x80) ? VRT_VENDOR_IN : VRT_VENDOR_OUT;
+
+  int r = usb_control_msg (udh, requesttype, request, value, index,
+                          (char *) bytes, len, 1000);
+  if (r < 0){
+    // we get EPIPE if the firmware stalls the endpoint.
+    if (errno != EPIPE)
+      fprintf (stderr, "usb_control_msg failed: %s\n", usb_strerror ());
+  }
+
+  return r;
+}
+
+// ----------------------------------------------------------------
+// load fpga
+
+static bool
+_usrp_load_fpga (struct usb_dev_handle *udh, const char *filename,
+                unsigned char hash[USRP_HASH_SIZE])
+{
+  bool ok = true;
+
+  FILE *fp = fopen (filename, "rb");
+  if (fp == 0){
+    perror (filename);
+    return false;
+  }
+
+  unsigned char buf[MAX_EP0_PKTSIZE];  // 64 is max size of EP0 packet on FX2
+  int n;
+
+  usrp_set_led (udh, 1, 1);            // led 1 on
+
+
+  // reset FPGA (and on rev1 both AD9862's, thus killing clock)
+  usrp_set_fpga_reset (udh, 1);                // hold fpga in reset
+
+  if (write_cmd (udh, VRQ_FPGA_LOAD, 0, FL_BEGIN, 0, 0) != 0)
+    goto fail;
+  
+  while ((n = fread (buf, 1, sizeof (buf), fp)) > 0){
+    if (write_cmd (udh, VRQ_FPGA_LOAD, 0, FL_XFER, buf, n) != n)
+      goto fail;
+  }
+
+  if (write_cmd (udh, VRQ_FPGA_LOAD, 0, FL_END, 0, 0) != 0)
+    goto fail;
+  
+  fclose (fp);
+
+  if (!usrp_set_hash (udh, FPGA_HASH_SLOT, hash))
+    fprintf (stderr, "usrp: failed to write fpga hash slot\n");
+
+  // On the rev1 USRP, the {tx,rx}_{enable,reset} bits are
+  // controlled over the serial bus, and hence aren't observed until
+  // we've got a good fpga bitstream loaded.
+
+  usrp_set_fpga_reset (udh, 0);                // fpga out of master reset
+
+  // now these commands will work
+  
+  ok &= usrp_set_fpga_tx_enable (udh, 0);
+  ok &= usrp_set_fpga_rx_enable (udh, 0);
+
+  ok &= usrp_set_fpga_tx_reset (udh, 1);       // reset tx and rx paths
+  ok &= usrp_set_fpga_rx_reset (udh, 1);
+  ok &= usrp_set_fpga_tx_reset (udh, 0);       // reset tx and rx paths
+  ok &= usrp_set_fpga_rx_reset (udh, 0);
+
+  if (!ok)
+    fprintf (stderr, "usrp: failed to reset tx and/or rx path\n");
+
+  // Manually reset all regs except master control to zero.
+  // FIXME may want to remove this when we rework FPGA reset strategy.
+  // In the mean while, this gets us reproducible behavior.
+  for (int i = 0; i < FR_USER_0; i++){
+    if (i == FR_MASTER_CTRL)
+      continue;
+    usrp_write_fpga_reg(udh, i, 0);
+  }
+
+  power_down_9862s (udh);              // on the rev1, power these down!
+  usrp_set_led (udh, 1, 0);            // led 1 off
+
+  return true;
+
+ fail:
+  power_down_9862s (udh);              // on the rev1, power these down!
+  fclose (fp);
+  return false;
+}
+
+// ----------------------------------------------------------------
+
+bool 
+usrp_set_led (struct usb_dev_handle *udh, int which, bool on)
+{
+  int r = write_cmd (udh, VRQ_SET_LED, on, which, 0, 0);
+
+  return r == 0;
+}
+
+bool
+usrp_set_hash (struct usb_dev_handle *udh, int which,
+              const unsigned char hash[USRP_HASH_SIZE])
+{
+  which &= 1;
+  
+  // we use the Cypress firmware down load command to jam it in.
+  int r = usb_control_msg (udh, 0x40, 0xa0, hash_slot_addr[which], 0,
+                          (char *) hash, USRP_HASH_SIZE, 1000);
+  return r == USRP_HASH_SIZE;
+}
+
+bool
+usrp_get_hash (struct usb_dev_handle *udh, int which, 
+              unsigned char hash[USRP_HASH_SIZE])
+{
+  which &= 1;
+  
+  // we use the Cypress firmware upload command to fetch it.
+  int r = usb_control_msg (udh, 0xc0, 0xa0, hash_slot_addr[which], 0,
+                          (char *) hash, USRP_HASH_SIZE, 1000);
+  return r == USRP_HASH_SIZE;
+}
+
+static bool
+usrp_set_switch (struct usb_dev_handle *udh, int cmd_byte, bool on)
+{
+  return write_cmd (udh, cmd_byte, on, 0, 0, 0) == 0;
+}
+
+
+static bool
+usrp1_fpga_write (struct usb_dev_handle *udh,
+                 int regno, int value)
+{
+  // on the rev1 usrp, we use the generic spi_write interface
+
+  unsigned char buf[4];
+
+  buf[0] = (value >> 24) & 0xff;       // MSB first
+  buf[1] = (value >> 16) & 0xff;
+  buf[2] = (value >>  8) & 0xff;
+  buf[3] = (value >>  0) & 0xff;
+  
+  return usrp_spi_write (udh, 0x00 | (regno & 0x7f),
+                        SPI_ENABLE_FPGA,
+                        SPI_FMT_MSB | SPI_FMT_HDR_1,
+                        buf, sizeof (buf));
+}
+
+static bool
+usrp1_fpga_read (struct usb_dev_handle *udh,
+                int regno, int *value)
+{
+  *value = 0;
+  unsigned char buf[4];
+
+  bool ok = usrp_spi_read (udh, 0x80 | (regno & 0x7f),
+                          SPI_ENABLE_FPGA,
+                          SPI_FMT_MSB | SPI_FMT_HDR_1,
+                          buf, sizeof (buf));
+
+  if (ok)
+    *value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+
+  return ok;
+}
+
+
+bool
+usrp_write_fpga_reg (struct usb_dev_handle *udh, int reg, int value)
+{
+  switch (usrp_hw_rev (dev_handle_to_dev (udh))){
+  case 0:                      // not supported ;)
+    abort();   
+
+  default:
+    return usrp1_fpga_write (udh, reg, value);
+  }
+}
+
+bool
+usrp_read_fpga_reg (struct usb_dev_handle *udh, int reg, int *value)
+{
+  switch (usrp_hw_rev (dev_handle_to_dev (udh))){
+  case 0:              // not supported ;)
+    abort();
+    
+  default:
+    return usrp1_fpga_read (udh, reg, value);
+  }
+}
+
+bool 
+usrp_set_fpga_reset (struct usb_dev_handle *udh, bool on)
+{
+  return usrp_set_switch (udh, VRQ_FPGA_SET_RESET, on);
+}
+
+bool 
+usrp_set_fpga_tx_enable (struct usb_dev_handle *udh, bool on)
+{
+  return usrp_set_switch (udh, VRQ_FPGA_SET_TX_ENABLE, on);
+}
+
+bool 
+usrp_set_fpga_rx_enable (struct usb_dev_handle *udh, bool on)
+{
+  return usrp_set_switch (udh, VRQ_FPGA_SET_RX_ENABLE, on);
+}
+
+bool 
+usrp_set_fpga_tx_reset (struct usb_dev_handle *udh, bool on)
+{
+  return usrp_set_switch (udh, VRQ_FPGA_SET_TX_RESET, on);
+}
+
+bool 
+usrp_set_fpga_rx_reset (struct usb_dev_handle *udh, bool on)
+{
+  return usrp_set_switch (udh, VRQ_FPGA_SET_RX_RESET, on);
+}
+
+
+// ----------------------------------------------------------------
+// conditional load stuff
+
+static bool
+compute_hash (const char *filename, unsigned char hash[USRP_HASH_SIZE])
+{
+  assert (USRP_HASH_SIZE == 16);
+  memset (hash, 0, USRP_HASH_SIZE);
+
+  FILE *fp = fopen (filename, "rb");
+  if (fp == 0){
+    perror (filename);
+    return false;
+  }
+  int r = md5_stream (fp, hash);
+  fclose (fp);
+  
+  return r == 0;
+}
+
+static usrp_load_status_t
+usrp_conditionally_load_something (struct usb_dev_handle *udh,
+                                  const char *filename,
+                                  bool force,
+                                  int slot,
+                                  bool loader (struct usb_dev_handle *,
+                                               const char *,
+                                               unsigned char [USRP_HASH_SIZE]))
+{
+  unsigned char file_hash[USRP_HASH_SIZE];
+  unsigned char usrp_hash[USRP_HASH_SIZE];
+  
+  if (access (filename, R_OK) != 0){
+    perror (filename);
+    return ULS_ERROR;
+  }
+
+  if (!compute_hash (filename, file_hash))
+    return ULS_ERROR;
+
+  if (!force
+      && usrp_get_hash (udh, slot, usrp_hash)
+      && memcmp (file_hash, usrp_hash, USRP_HASH_SIZE) == 0)
+    return ULS_ALREADY_LOADED;
+
+  bool r = loader (udh, filename, file_hash);
+
+  if (!r)
+    return ULS_ERROR;
+
+  return ULS_OK;
+}
+
+usrp_load_status_t
+usrp_load_firmware (struct usb_dev_handle *udh,
+                   const char *filename,
+                   bool force)
+{
+  return usrp_conditionally_load_something (udh, filename, force,
+                                           FIRMWARE_HASH_SLOT,
+                                           _usrp_load_firmware);
+}
+
+usrp_load_status_t
+usrp_load_fpga (struct usb_dev_handle *udh,
+               const char *filename,
+               bool force)
+{
+  return usrp_conditionally_load_something (udh, filename, force,
+                                           FPGA_HASH_SLOT,
+                                           _usrp_load_fpga);
+}
+
+static usb_dev_handle *
+open_nth_cmd_interface (int nth)
+{
+  struct usb_device *udev = usrp_find_device (nth);
+  if (udev == 0){
+    fprintf (stderr, "usrp: failed to find usrp[%d]\n", nth);
+    return 0;
+  }
+
+  struct usb_dev_handle *udh;
+
+  udh = usrp_open_cmd_interface (udev);
+  if (udh == 0){
+    // FIXME this could be because somebody else has it open.
+    // We should delay and retry...
+    fprintf (stderr, "open_nth_cmd_interface: open_cmd_interface failed\n");
+    usb_strerror ();
+    return 0;
+  }
+
+  return udh;
+ }
+
+static bool
+our_nanosleep (const struct timespec *delay)
+{
+  struct timespec      new_delay = *delay;
+  struct timespec      remainder;
+
+  while (1){
+    int r = nanosleep (&new_delay, &remainder);
+    if (r == 0)
+      return true;
+    if (errno == EINTR)
+      new_delay = remainder;
+    else {
+      perror ("nanosleep");
+      return false;
+    }
+  }
+}
+
+static bool
+mdelay (int millisecs)
+{
+  struct timespec      ts;
+  ts.tv_sec = millisecs / 1000;
+  ts.tv_nsec = (millisecs - (1000 * ts.tv_sec)) * 1000000;
+  return our_nanosleep (&ts);
+}
+
+usrp_load_status_t
+usrp_load_firmware_nth (int nth, const char *filename, bool force){
+  struct usb_dev_handle *udh = open_nth_cmd_interface (nth);
+  if (udh == 0)
+    return ULS_ERROR;
+
+  usrp_load_status_t s = usrp_load_firmware (udh, filename, force);
+  usrp_close_interface (udh);
+
+  switch (s){
+
+  case ULS_ALREADY_LOADED:             // nothing changed...
+    return ULS_ALREADY_LOADED;
+    break;
+
+  case ULS_OK:
+    // we loaded firmware successfully.
+
+    // It's highly likely that the board will renumerate (simulate a
+    // disconnect/reconnect sequence), invalidating our current
+    // handle.
+
+    // FIXME.  Turn this into a loop that rescans until we refind ourselves
+    
+    struct timespec    t;      // delay for 1 second
+    t.tv_sec = 2;
+    t.tv_nsec = 0;
+    our_nanosleep (&t);
+
+    usb_find_busses ();                // rescan busses and devices
+    usb_find_devices ();
+
+    return ULS_OK;
+
+  default:
+  case ULS_ERROR:              // some kind of problem
+    return ULS_ERROR;
+  }
+}
+
+static void
+load_status_msg (usrp_load_status_t s, const char *type, const char *filename)
+{
+  char *e = getenv("USRP_VERBOSE");
+  bool verbose = e != 0;
+  
+  switch (s){
+  case ULS_ERROR:
+    fprintf (stderr, "usrp: failed to load %s %s.\n", type, filename);
+    break;
+    
+  case ULS_ALREADY_LOADED:
+    if (verbose)
+      fprintf (stderr, "usrp: %s %s already loaded.\n", type, filename);
+    break;
+
+  case ULS_OK:
+    if (verbose)
+      fprintf (stderr, "usrp: %s %s loaded successfully.\n", type, filename);
+    break;
+  }
+}
+
+bool
+usrp_load_standard_bits (int nth, bool force,
+                        const std::string fpga_filename,
+                        const std::string firmware_filename)
+{
+  usrp_load_status_t   s;
+  const char           *filename;
+  const char           *proto_filename;
+  int hw_rev;
+
+  // first, figure out what hardware rev we're dealing with
+  {
+    struct usb_device *udev = usrp_find_device (nth);
+    if (udev == 0){
+      fprintf (stderr, "usrp: failed to find usrp[%d]\n", nth);
+      return false;
+    }
+    hw_rev = usrp_hw_rev (udev);
+  }
+
+  // start by loading the firmware
+
+  proto_filename = get_proto_filename(firmware_filename, "USRP_FIRMWARE",
+                                     default_firmware_filename);
+  filename = find_file(proto_filename, hw_rev);
+  if (filename == 0){
+    fprintf (stderr, "Can't find firmware: %s\n", proto_filename);
+    return false;
+  }
+
+  s = usrp_load_firmware_nth (nth, filename, force);
+  load_status_msg (s, "firmware", filename);
+
+  if (s == ULS_ERROR)
+    return false;
+
+  // if we actually loaded firmware, we must reload fpga ...
+  if (s == ULS_OK)
+    force = true;
+
+  // now move on to the fpga configuration bitstream
+
+  proto_filename = get_proto_filename(fpga_filename, "USRP_FPGA",
+                                     default_fpga_filename);
+  filename = find_file (proto_filename, hw_rev);
+  if (filename == 0){
+    fprintf (stderr, "Can't find fpga bitstream: %s\n", proto_filename);
+    return false;
+  }
+
+  struct usb_dev_handle *udh = open_nth_cmd_interface (nth);
+  if (udh == 0)
+    return false;
+  
+  s = usrp_load_fpga (udh, filename, force);
+  usrp_close_interface (udh);
+  load_status_msg (s, "fpga bitstream", filename);
+
+  if (s == ULS_ERROR)
+    return false;
+
+  return true;
+}
+
+bool
+_usrp_get_status (struct usb_dev_handle *udh, int which, bool *trouble)
+{
+  unsigned char        status;
+  *trouble = true;
+  
+  if (write_cmd (udh, VRQ_GET_STATUS, 0, which,
+                &status, sizeof (status)) != sizeof (status))
+    return false;
+
+  *trouble = status;
+  return true;
+}
+
+bool
+usrp_check_rx_overrun (struct usb_dev_handle *udh, bool *overrun_p)
+{
+  return _usrp_get_status (udh, GS_RX_OVERRUN, overrun_p);
+}
+
+bool
+usrp_check_tx_underrun (struct usb_dev_handle *udh, bool *underrun_p)
+{
+  return _usrp_get_status (udh, GS_TX_UNDERRUN, underrun_p);
+}
+
+
+bool
+usrp_i2c_write (struct usb_dev_handle *udh, int i2c_addr,
+               const void *buf, int len)
+{
+  if (len < 1 || len > MAX_EP0_PKTSIZE)
+    return false;
+
+  return write_cmd (udh, VRQ_I2C_WRITE, i2c_addr, 0,
+                   (unsigned char *) buf, len) == len;
+}
+
+
+bool
+usrp_i2c_read (struct usb_dev_handle *udh, int i2c_addr,
+              void *buf, int len)
+{
+  if (len < 1 || len > MAX_EP0_PKTSIZE)
+    return false;
+
+  return write_cmd (udh, VRQ_I2C_READ, i2c_addr, 0,
+                   (unsigned char *) buf, len) == len;
+}
+
+bool
+usrp_spi_write (struct usb_dev_handle *udh,
+               int optional_header, int enables, int format,
+               const void *buf, int len)
+{
+  if (len < 0 || len > MAX_EP0_PKTSIZE)
+    return false;
+
+  return write_cmd (udh, VRQ_SPI_WRITE,
+                   optional_header,
+                   ((enables & 0xff) << 8) | (format & 0xff),
+                   (unsigned char *) buf, len) == len;
+}
+
+
+bool
+usrp_spi_read (struct usb_dev_handle *udh,
+              int optional_header, int enables, int format,
+              void *buf, int len)
+{
+  if (len < 0 || len > MAX_EP0_PKTSIZE)
+    return false;
+
+  return write_cmd (udh, VRQ_SPI_READ,
+                   optional_header,
+                   ((enables & 0xff) << 8) | (format & 0xff),
+                   (unsigned char *) buf, len) == len;
+}
+
+bool
+usrp_9862_write (struct usb_dev_handle *udh, int which_codec,
+                int regno, int value)
+{
+  if (0)
+    fprintf (stderr, "usrp_9862_write which = %d, reg = %2d, val = %3d (0x%02x)\n",
+            which_codec, regno, value, value);
+
+  unsigned char buf[1];
+
+  buf[0] = value;
+  
+  return usrp_spi_write (udh, 0x00 | (regno & 0x3f),
+                        which_codec == 0 ? SPI_ENABLE_CODEC_A : SPI_ENABLE_CODEC_B,
+                        SPI_FMT_MSB | SPI_FMT_HDR_1,
+                        buf, 1);
+}
+
+bool
+usrp_9862_read (struct usb_dev_handle *udh, int which_codec,
+               int regno, unsigned char *value)
+{
+  return usrp_spi_read (udh, 0x80 | (regno & 0x3f),
+                       which_codec == 0 ? SPI_ENABLE_CODEC_A : SPI_ENABLE_CODEC_B,
+                       SPI_FMT_MSB | SPI_FMT_HDR_1,
+                       value, 1);
+}
+
+bool
+usrp_9862_write_many (struct usb_dev_handle *udh,
+                     int which_codec,
+                     const unsigned char *buf,
+                     int len)
+{
+  if (len & 0x1)
+    return false;              // must be even
+
+  bool result = true;
+
+  while (len > 0){
+    result &= usrp_9862_write (udh, which_codec, buf[0], buf[1]);
+    len -= 2;
+    buf += 2;
+  }
+
+  return result;
+}
+
+
+bool
+usrp_9862_write_many_all (struct usb_dev_handle *udh,
+                          const unsigned char *buf, int len)
+{
+  // FIXME handle 2/2 and 4/4 versions
+
+  bool result;
+  result  = usrp_9862_write_many (udh, 0, buf, len);
+  result &= usrp_9862_write_many (udh, 1, buf, len);
+  return result;
+}
+
+static void
+power_down_9862s (struct usb_dev_handle *udh)
+{
+  static const unsigned char regs[] = {
+    REG_RX_PWR_DN,     0x01,                   // everything
+    REG_TX_PWR_DN,     0x0f,                   // pwr dn digital and analog_both
+    REG_TX_MODULATOR,  0x00                    // coarse & fine modulators disabled
+  };
+
+  switch (usrp_hw_rev (dev_handle_to_dev (udh))){
+  case 0:
+    break;
+
+  default:
+    usrp_9862_write_many_all (udh, regs, sizeof (regs));
+    break;
+  }
+}
+
+
+
+static const int EEPROM_PAGESIZE = 16;
+
+bool
+usrp_eeprom_write (struct usb_dev_handle *udh, int i2c_addr,
+                  int eeprom_offset, const void *buf, int len)
+{
+  unsigned char cmd[2];
+  const unsigned char *p = (unsigned char *) buf;
+  
+  // The simplest thing that could possibly work:
+  //   all writes are single byte writes.
+  //
+  // We could speed this up using the page write feature,
+  // but we write so infrequently, why bother...
+
+  while (len-- > 0){
+    cmd[0] = eeprom_offset++;
+    cmd[1] = *p++;
+    bool r = usrp_i2c_write (udh, i2c_addr, cmd, sizeof (cmd));
+    mdelay (10);               // delay 10ms worst case write time
+    if (!r)
+      return false;
+  }
+  
+  return true;
+}
+
+bool
+usrp_eeprom_read (struct usb_dev_handle *udh, int i2c_addr,
+                 int eeprom_offset, void *buf, int len)
+{
+  unsigned char *p = (unsigned char *) buf;
+
+  // We setup a random read by first doing a "zero byte write".
+  // Writes carry an address.  Reads use an implicit address.
+
+  unsigned char cmd[1];
+  cmd[0] = eeprom_offset;
+  if (!usrp_i2c_write (udh, i2c_addr, cmd, sizeof (cmd)))
+    return false;
+
+  while (len > 0){
+    int n = std::min (len, MAX_EP0_PKTSIZE);
+    if (!usrp_i2c_read (udh, i2c_addr, p, n))
+      return false;
+    len -= n;
+    p += n;
+  }
+  return true;
+}
+// ----------------------------------------------------------------
+
+static bool
+slot_to_codec (int slot, int *which_codec)
+{
+  *which_codec = 0;
+  
+  switch (slot){
+  case SLOT_TX_A:
+  case SLOT_RX_A:
+    *which_codec = 0;
+    break;
+
+  case SLOT_TX_B:
+  case SLOT_RX_B:
+    *which_codec = 1;
+    break;
+
+  default:
+    fprintf (stderr, "usrp_prims:slot_to_codec: invalid slot = %d\n", slot);
+    return false;
+  }
+  return true;
+}
+
+static bool
+tx_slot_p (int slot)
+{
+  switch (slot){
+  case SLOT_TX_A:
+  case SLOT_TX_B:
+    return true;
+
+  default:
+    return false;
+  }
+}
+
+bool
+usrp_write_aux_dac (struct usb_dev_handle *udh, int slot,
+                   int which_dac, int value)
+{
+  int which_codec;
+  
+  if (!slot_to_codec (slot, &which_codec))
+    return false;
+
+  if (!(0 <= which_dac && which_dac < 4)){
+    fprintf (stderr, "usrp_write_aux_dac: invalid dac = %d\n", which_dac);
+    return false;
+  }
+
+  value &= 0x0fff;     // mask to 12-bits
+  
+  if (which_dac == 3){
+    // dac 3 is really 12-bits.  Use value as is.
+    bool r = true;
+    r &= usrp_9862_write (udh, which_codec, 43, (value >> 4));       // most sig
+    r &= usrp_9862_write (udh, which_codec, 42, (value & 0xf) << 4); // least sig
+    return r;
+  }
+  else {
+    // dac 0, 1, and 2 are really 8 bits.  
+    value = value >> 4;                // shift value appropriately
+    return usrp_9862_write (udh, which_codec, 36 + which_dac, value);
+  }
+}
+
+
+bool
+usrp_read_aux_adc (struct usb_dev_handle *udh, int slot,
+                  int which_adc, int *value)
+{
+  *value = 0;
+  int  which_codec;
+
+  if (!slot_to_codec (slot, &which_codec))
+    return false;
+
+  if (!(0 <= which_codec && which_codec < 2)){
+    fprintf (stderr, "usrp_read_aux_adc: invalid adc = %d\n", which_adc);
+    return false;
+  }
+
+  unsigned char aux_adc_control =
+    AUX_ADC_CTRL_REFSEL_A              // on chip reference
+    | AUX_ADC_CTRL_REFSEL_B;           // on chip reference
+
+  int  rd_reg = 26;    // base address of two regs to read for result
+  
+  // program the ADC mux bits
+  if (tx_slot_p (slot))
+    aux_adc_control |= AUX_ADC_CTRL_SELECT_A2 | AUX_ADC_CTRL_SELECT_B2;
+  else {
+    rd_reg += 2;
+    aux_adc_control |= AUX_ADC_CTRL_SELECT_A1 | AUX_ADC_CTRL_SELECT_B1;
+  }
+  
+  // I'm not sure if we can set the mux and issue a start conversion
+  // in the same cycle, so let's do them one at a time.
+
+  usrp_9862_write (udh, which_codec, 34, aux_adc_control);
+
+  if (which_adc == 0)
+    aux_adc_control |= AUX_ADC_CTRL_START_A;
+  else {
+    rd_reg += 4;
+    aux_adc_control |= AUX_ADC_CTRL_START_B;
+  }
+
+  // start the conversion
+  usrp_9862_write (udh, which_codec, 34, aux_adc_control);
+
+  // read the 10-bit result back
+  unsigned char v_lo = 0;
+  unsigned char v_hi = 0;
+  bool r = usrp_9862_read (udh, which_codec, rd_reg, &v_lo);
+  r &= usrp_9862_read (udh, which_codec, rd_reg + 1, &v_hi);
+
+  if (r)
+    *value = ((v_hi << 2) | ((v_lo >> 6) & 0x3)) << 2; // format as 12-bit
+  
+  return r;
+}
+
+// ----------------------------------------------------------------
+
+static int slot_to_i2c_addr (int slot)
+{
+  switch (slot){
+  case SLOT_TX_A:      return I2C_ADDR_TX_A;
+  case SLOT_RX_A:      return I2C_ADDR_RX_A;
+  case SLOT_TX_B:      return I2C_ADDR_TX_B;
+  case SLOT_RX_B:      return I2C_ADDR_RX_B;
+  default:             return -1;
+  }
+}
+
+static void
+set_chksum (unsigned char *buf)
+{
+  int sum = 0;
+  unsigned int i;
+  for (i = 0; i < DB_EEPROM_CLEN - 1; i++)
+    sum += buf[i];
+  buf[i] = -sum;
+}
+
+static usrp_dbeeprom_status_t
+read_dboard_eeprom (struct usb_dev_handle *udh,
+                   int slot_id, unsigned char *buf)
+{
+  int i2c_addr = slot_to_i2c_addr (slot_id);
+  if (i2c_addr == -1)
+    return UDBE_BAD_SLOT;
+
+  if (!usrp_eeprom_read (udh, i2c_addr, 0, buf, DB_EEPROM_CLEN))
+    return UDBE_NO_EEPROM;
+
+  if (buf[DB_EEPROM_MAGIC] != DB_EEPROM_MAGIC_VALUE)
+    return UDBE_INVALID_EEPROM;
+
+  int sum = 0;
+  for (unsigned int i = 0; i < DB_EEPROM_CLEN; i++)
+    sum += buf[i];
+
+  if ((sum & 0xff) != 0)
+    return UDBE_INVALID_EEPROM;
+
+  return UDBE_OK;
+}
+
+usrp_dbeeprom_status_t
+usrp_read_dboard_eeprom (struct usb_dev_handle *udh,
+                        int slot_id, usrp_dboard_eeprom *eeprom)
+{
+  unsigned char buf[DB_EEPROM_CLEN];
+
+  memset (eeprom, 0, sizeof (*eeprom));
+
+  usrp_dbeeprom_status_t s = read_dboard_eeprom (udh, slot_id, buf);
+  if (s != UDBE_OK)
+    return s;
+
+  eeprom->id = (buf[DB_EEPROM_ID_MSB] << 8) | buf[DB_EEPROM_ID_LSB];
+  eeprom->oe = (buf[DB_EEPROM_OE_MSB] << 8) | buf[DB_EEPROM_OE_LSB];
+  eeprom->offset[0] = (buf[DB_EEPROM_OFFSET_0_MSB] << 8) | buf[DB_EEPROM_OFFSET_0_LSB];
+  eeprom->offset[1] = (buf[DB_EEPROM_OFFSET_1_MSB] << 8) | buf[DB_EEPROM_OFFSET_1_LSB];
+
+  return UDBE_OK;
+}
+
+bool
+usrp_write_dboard_offsets (struct usb_dev_handle *udh, int slot_id,
+                          short offset0, short offset1)
+{
+  unsigned char buf[DB_EEPROM_CLEN];
+
+  usrp_dbeeprom_status_t s = read_dboard_eeprom (udh, slot_id, buf);
+  if (s != UDBE_OK)
+    return false;
+
+  buf[DB_EEPROM_OFFSET_0_LSB] = (offset0 >> 0) & 0xff;
+  buf[DB_EEPROM_OFFSET_0_MSB] = (offset0 >> 8) & 0xff;
+  buf[DB_EEPROM_OFFSET_1_LSB] = (offset1 >> 0) & 0xff;
+  buf[DB_EEPROM_OFFSET_1_MSB] = (offset1 >> 8) & 0xff;
+  set_chksum (buf);
+
+  return usrp_eeprom_write (udh, slot_to_i2c_addr (slot_id),
+                           0, buf, sizeof (buf));
+}
+
+std::string
+usrp_serial_number(struct usb_dev_handle *udh)
+{
+  unsigned char iserial = usb_device(udh)->descriptor.iSerialNumber;
+  if (iserial == 0)
+    return "";
+
+  char buf[1024];
+  if (usb_get_string_simple(udh, iserial, buf, sizeof(buf)) < 0)
+    return "";
+
+  return buf;
+}
diff --git a/usrp/host/lib/usrp_standard.cc b/usrp/host/lib/usrp_standard.cc
new file mode 100644 (file)
index 0000000..b112dbe
--- /dev/null
@@ -0,0 +1,1167 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2009 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/usrp_standard.h>
+
+#include "usrp/usrp_prims.h"
+#include "fpga_regs_common.h"
+#include "fpga_regs_standard.h"
+#include <stdexcept>
+#include <assert.h>
+#include <math.h>
+#include <ad9862.h>
+#include <cstdio>
+
+
+static const int OLD_CAPS_VAL = 0xaa55ff77;
+static const int DEFAULT_CAPS_VAL = ((2 << bmFR_RB_CAPS_NDUC_SHIFT)
+                                    | (2 << bmFR_RB_CAPS_NDDC_SHIFT)
+                                    | bmFR_RB_CAPS_RX_HAS_HALFBAND);
+
+// #define USE_FPGA_TX_CORDIC
+
+
+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() && !db->i_and_q_swapped())           // 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)
+{
+  static const int NBITS = 14;
+  
+  int  v = (int) rint (target_freq / master_freq * pow (2.0, 32.0));
+
+  if (0)
+    v = (v >> (32 - NBITS)) << (32 - NBITS);   // keep only top NBITS
+
+  *actual_freq = v * master_freq / pow (2.0, 32.0);
+
+  if (verbose)
+    fprintf (stderr,
+            "compute_freq_control_word_fpga: target = %g  actual = %g  delta = %g\n",
+            target_freq, *actual_freq, *actual_freq - target_freq);
+
+  return (unsigned int) v;
+}
+
+// The 9862 uses an unsigned 24-bit frequency tuning word and 
+// a separate register to control the sign.
+
+static unsigned int
+compute_freq_control_word_9862 (double master_freq, double target_freq,
+                               double *actual_freq, bool verbose)
+{
+  double sign = 1.0;
+
+  if (target_freq < 0)
+    sign = -1.0;
+
+  int  v = (int) rint (fabs (target_freq) / master_freq * pow (2.0, 24.0));
+  *actual_freq = v * master_freq / pow (2.0, 24.0) * sign;
+
+  if (verbose)
+    fprintf (stderr,
+     "compute_freq_control_word_9862: target = %g  actual = %g  delta = %g  v = %8d\n",
+     target_freq, *actual_freq, *actual_freq - target_freq, v);
+
+  return (unsigned int) v;
+}
+
+// ----------------------------------------------------------------
+
+usrp_standard_common::usrp_standard_common(usrp_basic *parent)
+{
+  // read new FPGA capability register
+  if (!parent->_read_fpga_reg(FR_RB_CAPS, &d_fpga_caps)){
+    fprintf (stderr, "usrp_standard_common: failed to read FPGA cap register.\n");
+    throw std::runtime_error ("usrp_standard_common::ctor");
+  }
+  // If we don't have the cap register, set the value to what it would
+  // have had if we did have one ;)
+  if (d_fpga_caps == OLD_CAPS_VAL)
+    d_fpga_caps = DEFAULT_CAPS_VAL;
+
+  if (0){
+    fprintf(stdout, "has_rx_halfband = %d\n", has_rx_halfband());
+    fprintf(stdout, "nddcs           = %d\n", nddcs());
+    fprintf(stdout, "has_tx_halfband = %d\n", has_tx_halfband());
+    fprintf(stdout, "nducs           = %d\n", nducs());
+  }
+}
+
+bool
+usrp_standard_common::has_rx_halfband() const
+{
+  return (d_fpga_caps & bmFR_RB_CAPS_RX_HAS_HALFBAND) ? true : false;
+}
+
+int
+usrp_standard_common::nddcs() const
+{
+  return (d_fpga_caps & bmFR_RB_CAPS_NDDC_MASK) >> bmFR_RB_CAPS_NDDC_SHIFT;
+}
+
+bool
+usrp_standard_common::has_tx_halfband() const
+{
+  return (d_fpga_caps & bmFR_RB_CAPS_TX_HAS_HALFBAND) ? true : false;
+}
+
+int
+usrp_standard_common::nducs() const
+{
+  return (d_fpga_caps & bmFR_RB_CAPS_NDUC_MASK) >> bmFR_RB_CAPS_NDUC_SHIFT;
+}
+
+// ----------------------------------------------------------------
+
+static int 
+real_rx_mux_value (int mux, int nchan)
+{
+  if (mux != -1)
+    return mux;
+
+  return 0x32103210;
+}
+
+usrp_standard_rx::usrp_standard_rx (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_basic_rx (which_board, fusb_block_size, fusb_nblocks,
+                  fpga_filename, firmware_filename),
+    usrp_standard_common(this),
+    d_nchan (1), d_sw_mux (0x0), d_hw_mux (0x0)
+{
+  if (!set_format(make_format())){
+    fprintf (stderr, "usrp_standard_rx: set_format failed\n");
+    throw std::runtime_error ("usrp_standard_rx::ctor");
+  }
+  if (!set_nchannels (nchan)){
+    fprintf (stderr, "usrp_standard_rx: set_nchannels failed\n");
+    throw std::runtime_error ("usrp_standard_rx::ctor");
+  }
+  if (!set_decim_rate (decim_rate)){
+    fprintf (stderr, "usrp_standard_rx: set_decim_rate failed\n");
+    throw std::runtime_error ("usrp_standard_rx::ctor");
+  }
+  if (!set_mux (real_rx_mux_value (mux, nchan))){
+    fprintf (stderr, "usrp_standard_rx: set_mux failed\n");
+    throw std::runtime_error ("usrp_standard_rx::ctor");
+  }
+  if (!set_fpga_mode (mode)){
+    fprintf (stderr, "usrp_standard_rx: set_fpga_mode failed\n");
+    throw std::runtime_error ("usrp_standard_rx::ctor");
+  }
+
+  for (int i = 0; i < MAX_CHAN; i++){
+    set_rx_freq(i, 0);
+    set_ddc_phase(i, 0);
+  }
+}
+
+usrp_standard_rx::~usrp_standard_rx ()
+{
+  // fprintf(stderr, "\nusrp_standard_rx: dtor\n");
+}
+
+bool
+usrp_standard_rx::start ()
+{
+  if (!usrp_basic_rx::start ())
+    return false;
+
+  // add our code here
+
+  return true;
+}
+
+bool
+usrp_standard_rx::stop ()
+{
+  bool ok = usrp_basic_rx::stop ();
+
+  // add our code here
+
+  return ok;
+}
+
+usrp_standard_rx_sptr
+usrp_standard_rx::make (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
+                       )
+{
+  try {
+    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 (...){
+    return usrp_standard_rx_sptr();
+  }
+}
+
+bool
+usrp_standard_rx::set_decim_rate(unsigned int rate)
+{
+  if (has_rx_halfband()){
+    if ((rate & 0x1) || rate < 4 || rate > 256){
+      fprintf (stderr, "usrp_standard_rx::set_decim_rate: rate must be EVEN and in [4, 256]\n");
+      return false;
+    }
+  }
+  else {
+    if (rate < 4 || rate > 128){
+      fprintf (stderr, "usrp_standard_rx::set_decim_rate: rate must be in [4, 128]\n");
+      return false;
+    }
+  }
+
+  d_decim_rate = rate;
+  set_usb_data_rate ((adc_rate () / rate * nchannels ())
+                    * (2 * sizeof (short)));
+
+  bool s = disable_rx ();
+  int v = has_rx_halfband() ? d_decim_rate/2 - 1 : d_decim_rate - 1;
+  bool ok = _write_fpga_reg (FR_DECIM_RATE, v);
+  restore_rx (s);
+  return ok;
+}
+
+bool usrp_standard_rx::set_nchannels (int nchan)
+{
+  if (!(nchan == 1 || nchan == 2 || nchan == 4))
+    return false;
+
+  if (nchan > nddcs())
+    return false;
+
+  d_nchan = nchan;
+
+  return write_hw_mux_reg ();
+}
+
+
+// map software mux value to hw mux value
+//
+// Software mux value:
+//
+//    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
+// +-------+-------+-------+-------+-------+-------+-------+-------+
+// |   Q3  |   I3  |   Q2  |   I2  |   Q1  |   I1  |   Q0  |   I0  |
+// +-------+-------+-------+-------+-------+-------+-------+-------+
+//
+// Each 4-bit I field is either 0,1,2,3
+// Each 4-bit Q field is either 0,1,2,3 or 0xf (input is const zero)
+// All Q's must be 0xf or none of them may be 0xf
+//
+//
+// Hardware mux value:
+//
+//    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
+// +-----------------------+-------+-------+-------+-------+-+-----+
+// |      must be zero     | Q3| I3| Q2| I2| Q1| I1| Q0| I0|Z| NCH |
+// +-----------------------+-------+-------+-------+-------+-+-----+
+
+
+static bool
+map_sw_mux_to_hw_mux (int sw_mux, int *hw_mux_ptr)
+{
+  // confirm that all I's are either 0,1,2,3 
+
+  for (int i = 0; i < 8; i += 2){
+    int t = (sw_mux >> (4 * i)) & 0xf;
+    if (!(0 <= t && t <= 3))
+      return false;
+  }
+
+  // confirm that all Q's are either 0,1,2,3 or 0xf
+
+  for (int i = 1; i < 8; i += 2){
+    int t = (sw_mux >> (4 * i)) & 0xf;
+    if (!(t == 0xf || (0 <= t && t <= 3)))
+      return false;
+  }
+
+  // confirm that all Q inputs are 0xf (const zero input),
+  // or none of them are 0xf
+
+  int q_and = 1;
+  int q_or =  0;
+
+  for (int i = 0; i < 4; i++){
+    int qx_is_0xf = ((sw_mux >> (8 * i + 4)) & 0xf) == 0xf;
+    q_and &= qx_is_0xf;
+    q_or  |= qx_is_0xf;
+  }
+
+  if (q_and || !q_or){         // OK
+    int hw_mux_value = 0;
+
+    for (int i = 0; i < 8; i++){
+      int t = (sw_mux >> (4 * i)) & 0x3;
+      hw_mux_value |= t << (2 * i + 4);
+    }
+
+    if (q_and)
+      hw_mux_value |= 0x8;     // all Q's zero
+
+    *hw_mux_ptr = hw_mux_value;
+    return true;
+  }
+  else
+    return false;
+}
+
+bool
+usrp_standard_rx::set_mux (int mux)
+{
+  if (!map_sw_mux_to_hw_mux (mux, &d_hw_mux))
+    return false;
+
+  // fprintf (stderr, "sw_mux = 0x%08x  hw_mux = 0x%08x\n", mux, d_hw_mux);
+
+  d_sw_mux = mux;
+  return write_hw_mux_reg ();
+}
+
+bool
+usrp_standard_rx::write_hw_mux_reg ()
+{
+  bool s = disable_rx ();
+  bool ok = _write_fpga_reg (FR_RX_MUX, d_hw_mux | d_nchan);
+  restore_rx (s);
+  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 uses;
+
+  // compute bitmasks of used A/D's
+  
+  if(db[ss.subdev]->is_quadrature())
+    uses = 0x3;               // uses A/D 0 and 1
+  else if (ss.subdev == 0)
+    uses = 0x1;               // uses A/D 0 only
+  else if(ss.subdev == 1)
+    uses = 0x2;               // uses A/D 1 only
+  else
+    uses = 0x0;               // uses no A/D (doesn't exist)
+  
+  if(uses == 0){
+    throw std::runtime_error("Determine RX Mux Error");
+  }
+  
+  bool swap_iq = db[ss.subdev]->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");
+}
+
+int
+usrp_standard_rx::determine_rx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b)
+{
+  std::vector<db_base_sptr> db_a = this->db(ss_a.side);
+  std::vector<db_base_sptr> db_b = this->db(ss_b.side);
+  if (db_a[ss_a.subdev]->is_quadrature() != db_b[ss_b.subdev]->is_quadrature()){
+    throw std::runtime_error("Cannot compute dual mux when mixing quadrature and non-quadrature subdevices");
+  }
+  int mux_a = determine_rx_mux_value(ss_a);
+  int mux_b = determine_rx_mux_value(ss_b);
+  //move the lower byte of the mux b into the second byte of the mux a
+  return ((mux_b & 0xff) << 8) | (mux_a & 0xffff00ff);
+}
+
+bool
+usrp_standard_rx::set_rx_freq (int channel, double freq)
+{
+  if (channel < 0 || channel > MAX_CHAN)
+    return false;
+
+  unsigned int v =
+    compute_freq_control_word_fpga (adc_rate(),
+                                   freq, &d_rx_freq[channel],
+                                   d_verbose);
+
+  return _write_fpga_reg (FR_RX_FREQ_0 + channel, v);
+}
+
+unsigned int
+usrp_standard_rx::decim_rate () const { return d_decim_rate; }
+
+int
+usrp_standard_rx::nchannels () const { return d_nchan; }
+
+int
+usrp_standard_rx::mux () const { return d_sw_mux; }
+
+double 
+usrp_standard_rx::rx_freq (int channel) const
+{
+  if (channel < 0 || channel >= MAX_CHAN)
+    return 0;
+
+  return d_rx_freq[channel];
+}
+
+bool
+usrp_standard_rx::set_fpga_mode (int mode)
+{
+  return _write_fpga_reg (FR_MODE, mode);
+}
+
+bool
+usrp_standard_rx::set_ddc_phase(int channel, int phase)
+{
+  if (channel < 0 || channel >= MAX_CHAN)
+    return false;
+
+  return _write_fpga_reg(FR_RX_PHASE_0 + channel, phase);
+}
+
+
+// To avoid quiet failures, check for things that our code cares about.
+
+static bool
+rx_format_is_valid(unsigned int format)
+{
+  int width =  usrp_standard_rx::format_width(format);
+  int want_q = usrp_standard_rx::format_want_q(format);
+
+  if (!(width == 8 || width == 16))    // FIXME add other widths when valid
+    return false;
+
+  if (!want_q)         // FIXME remove check when the rest of the code can handle I only
+    return false;
+
+  return true;
+}
+
+bool
+usrp_standard_rx::set_format(unsigned int format)
+{
+  if (!rx_format_is_valid(format))
+    return false;
+
+  return _write_fpga_reg(FR_RX_FORMAT, format);
+}
+
+unsigned int
+usrp_standard_rx::format() const
+{
+  return d_fpga_shadows[FR_RX_FORMAT];
+}
+
+// ----------------------------------------------------------------
+
+unsigned int 
+usrp_standard_rx::make_format(int width, int shift, bool want_q, bool bypass_halfband)
+{
+  unsigned int format = 
+    (((width << bmFR_RX_FORMAT_WIDTH_SHIFT) & bmFR_RX_FORMAT_WIDTH_MASK)
+     | ((shift << bmFR_RX_FORMAT_SHIFT_SHIFT) & bmFR_RX_FORMAT_SHIFT_MASK));
+
+  if (want_q)
+    format |= bmFR_RX_FORMAT_WANT_Q;
+  if (bypass_halfband)
+    format |= bmFR_RX_FORMAT_BYPASS_HB;
+
+  return format;
+}
+
+int
+usrp_standard_rx::format_width(unsigned int format)
+{
+  return (format & bmFR_RX_FORMAT_WIDTH_MASK) >> bmFR_RX_FORMAT_WIDTH_SHIFT;
+}
+
+int
+usrp_standard_rx::format_shift(unsigned int format)
+{
+  return (format & bmFR_RX_FORMAT_SHIFT_MASK) >> bmFR_RX_FORMAT_SHIFT_SHIFT;
+}
+
+bool
+usrp_standard_rx::format_want_q(unsigned int format)
+{
+  return (format & bmFR_RX_FORMAT_WANT_Q) != 0;
+}
+
+bool
+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);
+}
+
+
+//////////////////////////////////////////////////////////////////
+
+
+// tx data is timed to CLKOUT1 (64 MHz)
+// interpolate 4x
+// fine modulator enabled
+
+
+static unsigned char tx_regs_use_nco[] = {
+  REG_TX_IF,           (TX_IF_USE_CLKOUT1
+                        | TX_IF_I_FIRST
+                        | TX_IF_2S_COMP
+                        | TX_IF_INTERLEAVED),
+  REG_TX_DIGITAL,      (TX_DIGITAL_2_DATA_PATHS
+                        | TX_DIGITAL_INTERPOLATE_4X)
+};
+
+
+static int
+real_tx_mux_value (int mux, int nchan)
+{
+  if (mux != -1)
+    return mux;
+
+  switch (nchan){
+  case 1:
+    return 0x0098;
+  case 2:
+    return 0xba98;
+  default:
+    assert (0);
+  }
+}
+
+usrp_standard_tx::usrp_standard_tx (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
+                                   )
+  : usrp_basic_tx (which_board, fusb_block_size, fusb_nblocks, fpga_filename, firmware_filename),
+    usrp_standard_common(this),
+    d_sw_mux (0x8), d_hw_mux (0x81)
+{
+  if (!usrp_9862_write_many_all (d_udh, tx_regs_use_nco, sizeof (tx_regs_use_nco))){
+    fprintf (stderr, "usrp_standard_tx: failed to init AD9862 TX regs\n");
+    throw std::runtime_error ("usrp_standard_tx::ctor");
+  }
+  if (!set_nchannels (nchan)){
+    fprintf (stderr, "usrp_standard_tx: set_nchannels failed\n");
+    throw std::runtime_error ("usrp_standard_tx::ctor");
+  }
+  if (!set_interp_rate (interp_rate)){
+    fprintf (stderr, "usrp_standard_tx: set_interp_rate failed\n");
+    throw std::runtime_error ("usrp_standard_tx::ctor");
+  }
+  if (!set_mux (real_tx_mux_value (mux, nchan))){
+    fprintf (stderr, "usrp_standard_tx: set_mux failed\n");
+    throw std::runtime_error ("usrp_standard_tx::ctor");
+  }
+
+  for (int i = 0; i < MAX_CHAN; i++){
+    d_tx_modulator_shadow[i] = (TX_MODULATOR_DISABLE_NCO
+                               | TX_MODULATOR_COARSE_MODULATION_NONE);
+    d_coarse_mod[i] = CM_OFF;
+    set_tx_freq (i, 0);
+  }
+}
+
+usrp_standard_tx::~usrp_standard_tx ()
+{
+  // fprintf(stderr, "\nusrp_standard_tx: dtor\n");
+}
+
+bool
+usrp_standard_tx::start ()
+{
+  if (!usrp_basic_tx::start ())
+    return false;
+
+  // add our code here
+
+  return true;
+}
+
+bool
+usrp_standard_tx::stop ()
+{
+  bool ok = usrp_basic_tx::stop ();
+
+  // add our code here
+
+  return ok;
+}
+
+usrp_standard_tx_sptr
+usrp_standard_tx::make (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
+                       )
+{
+  try {
+    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 (...){
+    return usrp_standard_tx_sptr();
+  }
+}
+
+bool
+usrp_standard_tx::set_interp_rate (unsigned int rate)
+{
+  // fprintf (stderr, "usrp_standard_tx::set_interp_rate\n");
+
+  if ((rate & 0x3) || rate < 4 || rate > 512){
+    fprintf (stderr, "usrp_standard_tx::set_interp_rate: rate must be in [4, 512] and a multiple of 4.\n");
+    return false;
+  }
+
+  d_interp_rate = rate;
+  set_usb_data_rate ((dac_rate () / rate * nchannels ())
+                    * (2 * sizeof (short)));
+
+  // We're using the interp by 4 feature of the 9862 so that we can
+  // use its fine modulator.  Thus, we reduce the FPGA's interpolation rate
+  // by a factor of 4.
+
+  bool s = disable_tx ();
+  bool ok = _write_fpga_reg (FR_INTERP_RATE, d_interp_rate/4 - 1);
+  restore_tx (s);
+  return ok;
+}
+
+bool
+usrp_standard_tx::set_nchannels (int nchan)
+{
+  if (!(nchan == 1 || nchan == 2))
+    return false;
+
+  if (nchan > nducs())
+    return false;
+
+  d_nchan = nchan;
+  return write_hw_mux_reg ();
+}
+
+bool
+usrp_standard_tx::set_mux (int mux)
+{
+  d_sw_mux = mux;
+  d_hw_mux = mux << 4;
+  return write_hw_mux_reg ();
+}
+
+bool
+usrp_standard_tx::write_hw_mux_reg ()
+{
+  bool s = disable_tx ();
+  bool ok = _write_fpga_reg (FR_TX_MUX, d_hw_mux | d_nchan);
+  restore_tx (s);
+  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[ss.subdev]->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];
+  }
+}
+
+int
+usrp_standard_tx::determine_tx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b)
+{
+  if (ss_a.side == ss_b.side && ss_a.subdev == ss_b.subdev){
+    throw std::runtime_error("Cannot compute dual mux, repeated subdevice");
+  }
+  int mux_a = determine_tx_mux_value(ss_a);
+  //Get the mux b:
+  //   DAC0 becomes DAC2
+  //   DAC1 becomes DAC3
+  unsigned int mask[2] = {0x0022, 0x2200};
+  int mux_b = determine_tx_mux_value(ss_b) + mask[ss_b.side];
+  return mux_b | mux_a;
+}
+
+#ifdef USE_FPGA_TX_CORDIC
+
+bool
+usrp_standard_tx::set_tx_freq (int channel, double freq)
+{
+  if (channel < 0 || channel >= MAX_CHAN)
+    return false;
+
+  // This assumes we're running the 4x on-chip interpolator.
+
+  unsigned int v =
+    compute_freq_control_word_fpga (dac_rate () / 4,
+                                   freq, &d_tx_freq[channel],
+                                   d_verbose);
+
+  return _write_fpga_reg (FR_TX_FREQ_0 + channel, v);
+}
+
+
+#else
+
+bool
+usrp_standard_tx::set_tx_freq (int channel, double freq)
+{
+  if (channel < 0 || channel >= MAX_CHAN)
+    return false;
+
+  // split freq into fine and coarse components
+
+  coarse_mod_t cm;
+  double       coarse;
+
+  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_rate () / 4;
+  }
+  else if (freq < -8e6){       // [-24, -8)
+    cm = CM_NEG_FDAC_OVER_8;
+    coarse = -dac_rate () / 8;
+  }
+  else if (freq < 8e6){                // [-8, 8)
+    cm = CM_OFF;
+    coarse = 0;
+  }
+  else if (freq < 24e6){       // [8, 24)
+    cm = CM_POS_FDAC_OVER_8;
+    coarse = dac_rate () / 8;
+  }
+  else if (freq <= 44e6){      // [24, 44]
+    cm = CM_POS_FDAC_OVER_4;
+    coarse = dac_rate () / 4;
+  }
+  else                         // too high
+    return false;
+
+
+  set_coarse_modulator (channel, cm);  // set bits in d_tx_modulator_shadow
+
+  double fine = freq - coarse;
+
+
+  // Compute fine tuning word...
+  // This assumes we're running the 4x on-chip interpolator.
+  // (This is required to use the fine modulator.)
+
+  unsigned int v =
+    compute_freq_control_word_9862 (dac_rate () / 4,
+                                   fine, &d_tx_freq[channel], d_verbose);
+
+  d_tx_freq[channel] += coarse;                // adjust actual
+  
+  unsigned char high, mid, low;
+
+  high = (v >> 16) & 0xff;
+  mid =  (v >>  8) & 0xff;
+  low =  (v >>  0) & 0xff;
+
+  bool ok = true;
+
+  // write the fine tuning word
+  ok &= _write_9862 (channel, REG_TX_NCO_FTW_23_16, high);
+  ok &= _write_9862 (channel, REG_TX_NCO_FTW_15_8,  mid);
+  ok &= _write_9862 (channel, REG_TX_NCO_FTW_7_0,   low);
+
+
+  d_tx_modulator_shadow[channel] |= TX_MODULATOR_ENABLE_NCO;
+
+  if (fine < 0)
+    d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_FINE_TUNE;
+  else
+    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_NEG_FINE_TUNE;
+
+  ok &=_write_9862 (channel, REG_TX_MODULATOR, d_tx_modulator_shadow[channel]);
+
+  return ok;
+}
+#endif
+
+bool
+usrp_standard_tx::set_coarse_modulator (int channel, coarse_mod_t cm)
+{
+  if (channel < 0 || channel >= MAX_CHAN)
+    return false;
+
+  switch (cm){
+  case CM_NEG_FDAC_OVER_4:
+    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
+    d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_4;
+    d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_COARSE_TUNE;
+    break;
+
+  case CM_NEG_FDAC_OVER_8:
+    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
+    d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_8;
+    d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_COARSE_TUNE;
+    break;
+
+  case CM_OFF:
+    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
+    break;
+
+  case CM_POS_FDAC_OVER_8:
+    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
+    d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_8;
+    break;
+
+  case CM_POS_FDAC_OVER_4:
+    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
+    d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_4;
+    break;
+
+  default:
+    return false;
+  }
+
+  d_coarse_mod[channel] = cm;
+  return true;
+}
+
+unsigned int
+usrp_standard_tx::interp_rate () const { return d_interp_rate; }
+
+int
+usrp_standard_tx::nchannels () const { return d_nchan; }
+
+int
+usrp_standard_tx::mux () const { return d_sw_mux; }
+
+double
+usrp_standard_tx::tx_freq (int channel) const
+{
+  if (channel < 0 || channel >= MAX_CHAN)
+    return 0;
+
+  return d_tx_freq[channel];
+}
+
+usrp_standard_tx::coarse_mod_t
+usrp_standard_tx::coarse_modulator (int channel) const
+{
+  if (channel < 0 || channel >= MAX_CHAN)
+    return CM_OFF;
+
+  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);
+}
index d973c6d78016d4fe827e536422a046edd2c18bc9..78a775cf1b9b55684193f3b1a225a7e1e2c4d9c7 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2003,2004 Free Software Foundation, Inc.
+ * Copyright 2003,2004,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -36,7 +36,7 @@
 
 
 %{
-#include <usrp_prims.h>
+#include <usrp/usrp_prims.h>
 %}
 
 
diff --git a/usrp/limbo/apps-inband/Makefile.am b/usrp/limbo/apps-inband/Makefile.am
new file mode 100644 (file)
index 0000000..0a44d81
--- /dev/null
@@ -0,0 +1,77 @@
+#
+# Copyright 2003,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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+AM_CPPFLAGS =  \
+       $(DEFINES) $(OMNITHREAD_INCLUDES) $(PMT_INCLUDES) $(MBLOCK_INCLUDES) \
+       $(USRP_INCLUDES) $(USRP_INBAND_INCLUDES) $(BOOST_CPPFLAGS) \
+       $(CPPUNIT_INCLUDES) $(WITH_INCLUDES) -I$(top_srcdir)/mblock/src/lib
+
+
+bin_PROGRAMS =                         
+
+noinst_PROGRAMS =                      \
+       test_usrp_inband_ping           \
+       test_usrp_inband_registers      \
+       test_usrp_inband_rx             \
+       test_usrp_inband_2rx            \
+       test_usrp_inband_tx             \
+       test_usrp_inband_2tx            \
+       test_usrp_inband_timestamps     \
+       test_usrp_inband_overrun        \
+       test_usrp_inband_underrun       \
+       read_packets
+
+noinst_HEADERS =                       \
+       ui_nco.h                        \
+       ui_sincos.h     
+
+
+test_usrp_inband_ping_SOURCES  = test_usrp_inband_ping.cc 
+test_usrp_inband_ping_LDADD    = $(USRP_LA) $(USRP_INBAND_LA)
+
+test_usrp_inband_tx_SOURCES    = test_usrp_inband_tx.cc ui_sincos.c
+test_usrp_inband_tx_LDADD      = $(USRP_LA) $(USRP_INBAND_LA)
+
+test_usrp_inband_2tx_SOURCES   = test_usrp_inband_2tx.cc ui_sincos.c
+test_usrp_inband_2tx_LDADD     = $(USRP_LA) $(USRP_INBAND_LA)
+
+test_usrp_inband_timestamps_SOURCES    = test_usrp_inband_timestamps.cc ui_sincos.c
+test_usrp_inband_timestamps_LDADD      = $(USRP_LA) $(USRP_INBAND_LA)
+
+test_usrp_inband_registers_SOURCES     = test_usrp_inband_registers.cc ui_sincos.c
+test_usrp_inband_registers_LDADD       = $(USRP_LA) $(USRP_INBAND_LA)
+
+test_usrp_inband_overrun_SOURCES       = test_usrp_inband_overrun.cc
+test_usrp_inband_overrun_LDADD         = $(USRP_LA) $(USRP_INBAND_LA)
+
+test_usrp_inband_underrun_SOURCES      = test_usrp_inband_underrun.cc
+test_usrp_inband_underrun_LDADD        = $(USRP_LA) $(USRP_INBAND_LA)
+
+test_usrp_inband_rx_SOURCES    = test_usrp_inband_rx.cc ui_sincos.c
+test_usrp_inband_rx_LDADD      = $(USRP_LA) $(USRP_INBAND_LA)
+
+test_usrp_inband_2rx_SOURCES   = test_usrp_inband_2rx.cc ui_sincos.c
+test_usrp_inband_2rx_LDADD     = $(USRP_LA) $(USRP_INBAND_LA)
+
+read_packets_SOURCES = read_packets.cc
+read_packets_LDADD = $(USRP_LA) $(USRP_INBAND_LA)
diff --git a/usrp/limbo/apps-inband/read_packets.cc b/usrp/limbo/apps-inband/read_packets.cc
new file mode 100644 (file)
index 0000000..24a1e88
--- /dev/null
@@ -0,0 +1,109 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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 <iostream>
+#include <usrp_inband_usb_packet.h>
+#include <mblock/class_registry.h>
+#include <vector>
+#include <usrp_usb_interface.h>
+#include <fstream>
+
+typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit easy
+
+int main(int argc, char *argv[]) {
+
+  if(argc !=2) {
+    std::cout << "Usage: ./read_packets <data_file>\n";
+    return -1;
+  }
+
+  std::ifstream infile;
+  std::ofstream outfile;  
+
+  unsigned int pkt_size = transport_pkt::max_pkt_size();
+  unsigned int pkt_num=0;
+
+  transport_pkt *pkt;
+  char pkt_data[pkt_size];          // allocate the number of bytes for a single packet
+
+  pkt = (transport_pkt *)pkt_data;  // makes operations cleaner to read
+
+  // Open the file and read the packets, dumping information
+  infile.open(argv[1], std::ios::binary|std::ios::in);
+  if(!infile.is_open())
+    exit(-1);
+
+  //outfile.open("dump.dat",std::ios::out|std::ios::binary);  
+
+  // read 1 packet in to the memory
+  infile.read(pkt_data, pkt_size);
+
+  while(!infile.eof()) {
+  
+    printf("Packet %u\n", pkt_num);
+
+    if(pkt->start_of_burst())
+      printf("\tstart of burst\n");
+      
+    if(pkt->end_of_burst())
+      printf("\tend of burst\n");
+    
+//    if(pkt->carrier_sense())
+//      printf("\tcarrier sense\n");
+
+    if(pkt->underrun())
+      printf("\tunderrun\n");
+    
+    if(pkt->overrun())
+      printf("\toverrun\n");
+
+    printf("\tchannel: \t0x%x\n", pkt->chan());
+    printf("\ttimestamp: \t0x%x\n", pkt->timestamp());
+    //printf("\ttimestamp: \t%u\n", pkt->timestamp());
+    printf("\tlength: \t%u\n", pkt->payload_len());
+    printf("\trssi: \t%u\n", pkt->rssi());
+
+    printf("\tpayload: \n");
+    for(int i=0; i < pkt->payload_len(); i++)
+    //for(int i=0; i < pkt->max_payload(); i++)
+    {
+      printf("\t%d\t0x%x\n", i, *(pkt->payload()+i));
+      //outfile.write((const char*)(pkt->payload()+i),1);
+      //printf("\t\t0x%x\n", pkt->payload()+i);
+
+    }
+    printf("\n\n");
+
+    pkt_num++;
+  
+    // read 1 packet in to the memory
+    infile.read(pkt_data, pkt_size);
+
+  }
+
+  infile.close();
+  //outfile.close();
+
+}
diff --git a/usrp/limbo/apps-inband/test_usrp_inband_2rx.cc b/usrp/limbo/apps-inband/test_usrp_inband_2rx.cc
new file mode 100644 (file)
index 0000000..c210f19
--- /dev/null
@@ -0,0 +1,371 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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 <mblock/mblock.h>
+#include <mblock/runtime.h>
+#include <mb_runtime_nop.h>            // QA only
+#include <mblock/protocol_class.h>
+#include <mblock/exception.h>
+#include <mblock/msg_queue.h>
+#include <mblock/message.h>
+#include <mb_mblock_impl.h>
+#include <mblock/msg_accepter.h>
+#include <mblock/class_registry.h>
+#include <pmt.h>
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <fstream>
+
+// Include the symbols needed for communication with USRP server
+#include <symbols_usrp_server_cs.h>
+#include <symbols_usrp_channel.h>
+#include <symbols_usrp_low_level_cs.h>
+#include <symbols_usrp_rx.h>
+
+static bool verbose = true;
+
+class test_usrp_rx : public mb_mblock
+{
+  mb_port_sptr         d_rx;
+  mb_port_sptr         d_cs;
+  pmt_t                d_rx_chan0, d_rx_chan1;
+
+  enum state_t {
+    INIT,
+    OPENING_USRP,
+    ALLOCATING_CHANNEL,
+    RECEIVING,
+    CLOSING_CHANNEL,
+    CLOSING_USRP,
+  };
+
+  state_t      d_state;
+
+  std::ofstream d_ofile;
+
+  long d_samples_recvd;
+  long d_samples_to_recv;
+
+ public:
+  test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~test_usrp_rx();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void open_usrp();
+  void close_usrp();
+  void allocate_channel();
+  void send_packets();
+  void enter_receiving();
+  void build_and_send_next_frame();
+  void handle_response_recv_raw_samples(pmt_t invocation_handle);
+  void enter_closing_channel();
+};
+
+test_usrp_rx::test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg),
+    d_rx_chan0(PMT_NIL), d_rx_chan1(PMT_NIL),
+    d_samples_recvd(0),
+    d_samples_to_recv(20e6)
+{ 
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+  
+  // Pass a dictionary to usrp_server which specifies which interface to use, the stub or USRP
+  pmt_t usrp_dict = pmt_make_dict();
+  
+  // To test the application without a USRP
+  bool fake_usrp_p = false;
+  if(fake_usrp_p) {
+    pmt_dict_set(usrp_dict, 
+                 pmt_intern("fake-usrp"),
+                            PMT_T);
+  }
+
+  // Specify the RBF to use
+  pmt_dict_set(usrp_dict,
+               pmt_intern("rbf"),
+               pmt_intern("inband_2rxhb_2tx.rbf"));
+
+  pmt_dict_set(usrp_dict,
+               pmt_intern("decim-rx"),
+               pmt_from_long(64));
+
+  define_component("server", "usrp_server", usrp_dict);
+
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+
+}
+
+test_usrp_rx::~test_usrp_rx()
+{
+}
+
+void
+test_usrp_rx::initial_transition()
+{
+  open_usrp();
+}
+
+void
+test_usrp_rx::handle_message(mb_message_sptr msg)
+{
+  pmt_t        event = msg->signal();
+  pmt_t data = msg->data();
+
+  pmt_t handle = PMT_F;
+  pmt_t status = PMT_F;
+  std::string error_msg;
+  
+  switch(d_state){
+    
+    //----------------------------- OPENING_USRP ----------------------------//
+    // We only expect a response from opening the USRP which should be succesful
+    // or failed.
+    case OPENING_USRP:
+      if (pmt_eq(event, s_response_open)){
+        status = pmt_nth(1, data);
+        if (pmt_eq(status, PMT_T)){
+          allocate_channel();
+          return;
+        }
+        else {
+          error_msg = "failed to open usrp:";
+          goto bail;
+        }
+      }
+      goto unhandled;
+      
+    //----------------------- ALLOCATING CHANNELS --------------------//
+    // Allocate an RX channel to perform the overrun test.
+    case ALLOCATING_CHANNEL:
+      if (pmt_eq(event, s_response_allocate_channel)){
+        status = pmt_nth(1, data);
+        if(pmt_eqv(d_rx_chan0, PMT_NIL))
+          d_rx_chan0 = pmt_nth(2, data);
+        else
+          d_rx_chan1 = pmt_nth(2, data);
+
+        if (pmt_eq(status, PMT_T) && !pmt_eqv(d_rx_chan1, PMT_NIL)){
+          enter_receiving();
+          return;
+        }
+        else if(pmt_eq(status, PMT_F)){
+          error_msg = "failed to allocate channel:";
+          goto bail;
+        }
+        return;
+      }
+      goto unhandled;
+
+    //--------------------------- RECEIVING ------------------------------//
+    // In the receiving state, we receive samples until the specified amount
+    // while counting the number of overruns.
+    case RECEIVING:
+      if (pmt_eq(event, s_response_recv_raw_samples)){
+        status = pmt_nth(1, data);
+
+        if (pmt_eq(status, PMT_T)){
+          handle_response_recv_raw_samples(data);
+          return;
+        }
+        else {
+          error_msg = "bad response-xmit-raw-frame:";
+          goto bail;
+        }
+      }
+      goto unhandled;
+    
+    //------------------------- CLOSING CHANNEL ----------------------------//
+    // Check deallocation response for the RX channel 
+    case CLOSING_CHANNEL:
+      if (pmt_eq(event, s_response_deallocate_channel)){
+        status = pmt_nth(1, data);
+
+        if (pmt_eq(status, PMT_T)){
+          close_usrp();
+          return;
+        }
+        else {
+          error_msg = "failed to deallocate channel:";
+          goto bail;
+        }
+      }
+
+      // Alternately, we ignore all response recv samples while waiting for the
+      // channel to actually close
+      if (pmt_eq(event, s_response_recv_raw_samples))
+        return;
+
+      goto unhandled;
+
+    //--------------------------- CLOSING USRP ------------------------------//
+    // Once we have received a successful USRP close response, we shutdown all
+    // mblocks and exit.
+    case CLOSING_USRP:
+      if (pmt_eq(event, s_response_close)){
+        status = pmt_nth(1, data);
+
+        if (pmt_eq(status, PMT_T)){
+          fflush(stdout);
+          shutdown_all(PMT_T);
+          return;
+        }
+        else {
+          error_msg = "failed to close USRP:";
+          goto bail;
+        }
+      }
+      goto unhandled;
+
+    default:
+      goto unhandled;
+  }
+  return;
+
+ // An error occured, print it, and shutdown all m-blocks
+ bail:
+  std::cerr << error_msg << data
+           << "status = " << status << std::endl;
+  shutdown_all(PMT_F);
+  return;
+
+ // Received an unhandled message for a specific state
+ unhandled:
+  if(verbose && !pmt_eq(event, pmt_intern("%shutdown")))
+    std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
+              << "in state "<< d_state << std::endl;
+}
+
+
+void
+test_usrp_rx::open_usrp()
+{
+  pmt_t which_usrp = pmt_from_long(0);
+
+  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
+  d_state = OPENING_USRP;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_RX] Opening the USRP\n";
+}
+
+void
+test_usrp_rx::close_usrp()
+{
+
+  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
+  d_state = CLOSING_USRP;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_RX] Closing the USRP\n";
+}
+
+void
+test_usrp_rx::allocate_channel()
+{
+  long capacity = (long) 16e6;
+  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
+  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
+  d_state = ALLOCATING_CHANNEL;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_RX] Requesting RX channel allocation\n";
+}
+
+void
+test_usrp_rx::enter_receiving()
+{
+  d_state = RECEIVING;
+
+  d_rx->send(s_cmd_start_recv_raw_samples,
+             pmt_list2(PMT_F,
+                       d_rx_chan0));
+  
+  d_rx->send(s_cmd_start_recv_raw_samples,
+             pmt_list2(PMT_F,
+                       d_rx_chan1));
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_RX] Receiving...\n";
+}
+
+void
+test_usrp_rx::handle_response_recv_raw_samples(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+  pmt_t v_samples = pmt_nth(2, data);
+  pmt_t timestamp = pmt_nth(3, data);
+  pmt_t channel = pmt_nth(4, data);
+  pmt_t properties = pmt_nth(5, data);
+
+  d_samples_recvd += pmt_length(v_samples) / 4;
+
+  // Check for overrun
+  if(!pmt_is_dict(properties)) {
+    std::cout << "[TEST_USRP_INBAND_RX] Recv samples dictionary is improper\n";
+    return;
+  }
+
+  // Check if the number samples we have received meets the test
+  if(d_samples_recvd >= d_samples_to_recv) {
+    d_rx->send(s_cmd_stop_recv_raw_samples, pmt_list2(PMT_NIL, d_rx_chan0));
+    d_rx->send(s_cmd_stop_recv_raw_samples, pmt_list2(PMT_NIL, d_rx_chan1));
+    enter_closing_channel();
+    return;
+  }
+
+}
+
+void
+test_usrp_rx::enter_closing_channel()
+{
+  d_state = CLOSING_CHANNEL;
+
+  d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan0));
+  d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan1));
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_RX] Deallocating RX channel\n";
+}
+
+REGISTER_MBLOCK_CLASS(test_usrp_rx);
+
+
+// ----------------------------------------------------------------
+
+int
+main (int argc, char **argv)
+{
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_NIL;
+
+  rt->run("top", "test_usrp_rx", PMT_F, &result);
+
+}
diff --git a/usrp/limbo/apps-inband/test_usrp_inband_2tx.cc b/usrp/limbo/apps-inband/test_usrp_inband_2tx.cc
new file mode 100644 (file)
index 0000000..11a1a49
--- /dev/null
@@ -0,0 +1,430 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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 <mblock/mblock.h>
+#include <mblock/runtime.h>
+#include <mb_runtime_nop.h>            // QA only
+#include <mblock/protocol_class.h>
+#include <mblock/exception.h>
+#include <mblock/msg_queue.h>
+#include <mblock/message.h>
+#include <mb_mblock_impl.h>
+#include <mblock/msg_accepter.h>
+#include <mblock/class_registry.h>
+#include <pmt.h>
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+
+#include <ui_nco.h>
+#include <symbols_usrp_server_cs.h>
+#include <symbols_usrp_channel.h>
+#include <symbols_usrp_low_level_cs.h>
+#include <symbols_usrp_tx.h>
+
+static bool verbose = true;
+
+class test_usrp_tx : public mb_mblock
+{
+  mb_port_sptr         d_tx;
+  mb_port_sptr         d_cs;
+  pmt_t                d_tx_chan0, d_tx_chan1;
+
+  enum state_t {
+    INIT,
+    OPENING_USRP,
+    ALLOCATING_CHANNEL,
+    TRANSMITTING,
+    CLOSING_CHANNEL,
+    CLOSING_USRP,
+  };
+
+  state_t      d_state;
+  long         d_nsamples_to_send;
+  long         d_nsamples_xmitted;
+  long         d_nframes_xmitted;
+  long         d_samples_per_frame;
+  bool         d_done_sending;
+
+  // for generating sine wave output
+  ui_nco<float,float>  d_nco;
+  double               d_amplitude;
+
+ public:
+  test_usrp_tx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~test_usrp_tx();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void open_usrp();
+  void close_usrp();
+  void allocate_channel();
+  void send_packets();
+  void enter_transmitting();
+  void build_and_send_next_frame();
+  void handle_xmit_response(pmt_t invocation_handle);
+  void enter_closing_channel();
+};
+
+test_usrp_tx::test_usrp_tx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg),
+    d_tx_chan0(PMT_NIL), d_tx_chan1(PMT_NIL),
+    d_state(INIT), d_nsamples_to_send((long) 80e6),
+    d_nsamples_xmitted(0),
+    d_nframes_xmitted(0),
+    d_samples_per_frame((long)(126 * 4)),      // full packet
+    d_done_sending(false),
+    d_amplitude(16384)
+{ 
+  // std::cout << "[TEST_USRP_TX] Initializing...\n";
+  
+  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+  
+  //bool fake_usrp_p = true;
+  bool fake_usrp_p = false;
+
+  // Test the TX side
+
+  pmt_t usrp_dict = pmt_make_dict();
+
+  if(fake_usrp_p) {
+    pmt_dict_set(usrp_dict, 
+                 pmt_intern("fake-usrp"),
+                            PMT_T);
+  }
+  
+  // Specify the RBF to use
+  pmt_dict_set(usrp_dict,
+               pmt_intern("rbf"),
+               pmt_intern("inband_2rxhb_2tx.rbf"));
+
+  // Set TX and RX interpolations
+  pmt_dict_set(usrp_dict,
+               pmt_intern("interp-tx"),
+               pmt_from_long(128));
+
+//  pmt_dict_set(usrp_dict,
+//               pmt_intern("rf-freq"),
+//               pmt_from_long(10e6));
+
+  define_component("server", "usrp_server", usrp_dict);
+
+  connect("self", "tx0", "server", "tx0");
+  connect("self", "cs", "server", "cs");
+
+  // initialize NCO
+  double freq = 100e3;
+  int interp = 32;                         // 32 -> 4MS/s
+  double sample_rate = 128e6 / interp; 
+  d_nco.set_freq(2*M_PI * freq/sample_rate);
+
+  // FIXME need to somehow set the interp rate in the USRP.
+  // for now, we'll have the low-level code hardwire it.
+}
+
+test_usrp_tx::~test_usrp_tx()
+{
+}
+
+void
+test_usrp_tx::initial_transition()
+{
+  open_usrp();
+}
+
+void
+test_usrp_tx::handle_message(mb_message_sptr msg)
+{
+  pmt_t        event = msg->signal();
+  pmt_t data = msg->data();
+
+  pmt_t handle = PMT_F;
+  pmt_t status = PMT_F;
+  std::string error_msg;
+  
+  //std::cout << msg << std::endl;
+
+  switch(d_state){
+  case OPENING_USRP:
+    if (pmt_eq(event, s_response_open)){
+      status = pmt_nth(1, data);
+      if (pmt_eq(status, PMT_T)){
+        allocate_channel();
+        return;
+      }
+      else {
+        error_msg = "failed to open usrp:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+    
+  case ALLOCATING_CHANNEL:
+    if (pmt_eq(event, s_response_allocate_channel)){
+      status = pmt_nth(1, data);
+      if(pmt_eqv(d_tx_chan0, PMT_NIL))
+        d_tx_chan0 = pmt_nth(2, data);
+      else
+        d_tx_chan1 = pmt_nth(2, data);
+
+      if (pmt_eq(status, PMT_T) && !pmt_eqv(d_tx_chan1, PMT_NIL)){
+        enter_transmitting();
+        return;
+      }
+      else if(pmt_eq(status, PMT_F)){
+        error_msg = "failed to allocate channel:";
+        goto bail;
+      }
+      return;
+    }
+    goto unhandled;
+
+  case TRANSMITTING:
+    if (pmt_eq(event, s_response_xmit_raw_frame)){
+      handle = pmt_nth(0, data);
+      status = pmt_nth(1, data);
+
+      if (pmt_eq(status, PMT_T)){
+        handle_xmit_response(handle);
+        return;
+      }
+      else {
+        error_msg = "bad response-xmit-raw-frame:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+
+  case CLOSING_CHANNEL:
+    if (pmt_eq(event, s_response_deallocate_channel)){
+      status = pmt_nth(1, data);
+
+      if (pmt_eq(status, PMT_T)){
+        close_usrp();
+        return;
+      }
+      else {
+        error_msg = "failed to deallocate channel:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+
+  case CLOSING_USRP:
+    if (pmt_eq(event, s_response_close)){
+      status = pmt_nth(1, data);
+
+      if (pmt_eq(status, PMT_T)){
+        shutdown_all(PMT_T);
+        return;
+      }
+      else {
+        error_msg = "failed to close USRP:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+
+  default:
+    goto unhandled;
+  }
+  return;
+
+ bail:
+  std::cerr << error_msg << data
+           << "status = " << status << std::endl;
+  shutdown_all(PMT_F);
+  return;
+
+ unhandled:
+  std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
+           << "in state "<< d_state << std::endl;
+}
+
+
+void
+test_usrp_tx::open_usrp()
+{
+  pmt_t which_usrp = pmt_from_long(0);
+
+  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
+  d_state = OPENING_USRP;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_TX] Opening the USRP\n";
+}
+
+void
+test_usrp_tx::close_usrp()
+{
+  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
+  d_state = CLOSING_USRP;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_TX] Closing the USRP\n";
+}
+
+void
+test_usrp_tx::allocate_channel()
+{
+  long capacity = (long) 16e6;
+
+  // Send two capacity requests, which will allocate us two channels
+  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
+  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
+  d_state = ALLOCATING_CHANNEL;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_TX] Requesting TX channel allocation\n";
+}
+
+void
+test_usrp_tx::enter_transmitting()
+{
+  d_state = TRANSMITTING;
+  d_nsamples_xmitted = 0;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_TX] Transmitting...\n";
+  
+  build_and_send_next_frame(); // fire off 4 to start pipeline
+  build_and_send_next_frame();
+  build_and_send_next_frame();
+  build_and_send_next_frame();
+}
+
+void
+test_usrp_tx::build_and_send_next_frame()
+{
+  // allocate the uniform vector for the samples
+  // FIXME perhaps hold on to this between calls
+
+#if 1
+  long nsamples_this_frame =
+    std::min(d_nsamples_to_send - d_nsamples_xmitted,
+            d_samples_per_frame);
+#else
+  long nsamples_this_frame = d_samples_per_frame;
+#endif
+
+  if (nsamples_this_frame == 0){
+    d_done_sending = true;
+    return;
+  }
+    
+
+  size_t nshorts = 2 * nsamples_this_frame;    // 16-bit I & Q
+  pmt_t uvec = pmt_make_s16vector(nshorts, 0);
+  size_t ignore;
+  int16_t *samples = pmt_s16vector_writable_elements(uvec, ignore);
+
+  // fill in the complex sinusoid
+
+  for (int i = 0; i < nsamples_this_frame; i++){
+
+    if (1){
+      gr_complex s;
+      d_nco.sincos(&s, 1, d_amplitude);
+      // write 16-bit i & q
+      samples[2*i] =   (int16_t) s.real();
+      samples[2*i+1] = (int16_t) s.imag();
+    }
+    else {
+      gr_complex s(d_amplitude, d_amplitude);
+
+      // write 16-bit i & q
+      samples[2*i] =   (int16_t) s.real();
+      samples[2*i+1] = (int16_t) s.imag();
+    }
+  }
+
+  pmt_t tx_properties = pmt_make_dict();
+
+  pmt_t timestamp = pmt_from_long(0xffffffff); // NOW
+  d_tx->send(s_cmd_xmit_raw_frame,
+            pmt_list5(pmt_from_long(d_nframes_xmitted),  // invocation-handle
+                      d_tx_chan0,                        // channel
+                      uvec,                              // the samples
+                      timestamp,
+           tx_properties));
+  
+  // Resend on channel 1
+  d_tx->send(s_cmd_xmit_raw_frame,
+            pmt_list5(pmt_from_long(d_nframes_xmitted),  // invocation-handle
+                      d_tx_chan1,                        // channel
+                      uvec,                              // the samples
+                      timestamp,
+           tx_properties));
+
+  d_nsamples_xmitted += nsamples_this_frame;
+  d_nframes_xmitted++;
+
+  if(verbose && 0)
+    std::cout << "[TEST_USRP_INBAND_TX] Transmitted frame\n";
+}
+
+
+void
+test_usrp_tx::handle_xmit_response(pmt_t handle)
+{
+  if (d_done_sending &&
+      pmt_to_long(handle) == (d_nframes_xmitted - 1)){
+    // We're done sending and have received all responses
+    enter_closing_channel();
+  }
+
+  build_and_send_next_frame();
+}
+
+void
+test_usrp_tx::enter_closing_channel()
+{
+  d_state = CLOSING_CHANNEL;
+  
+  // Deallocate both channels
+  d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan0));
+  d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan1));
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_tX] Deallocating TX channel\n";
+}
+
+REGISTER_MBLOCK_CLASS(test_usrp_tx);
+
+
+// ----------------------------------------------------------------
+
+int
+main (int argc, char **argv)
+{
+  // handle any command line args here
+
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_NIL;
+
+  rt->run("top", "test_usrp_tx", PMT_F, &result);
+}
diff --git a/usrp/limbo/apps-inband/test_usrp_inband_overrun.cc b/usrp/limbo/apps-inband/test_usrp_inband_overrun.cc
new file mode 100644 (file)
index 0000000..cd0fa52
--- /dev/null
@@ -0,0 +1,375 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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 <mblock/mblock.h>
+#include <mblock/runtime.h>
+#include <mblock/protocol_class.h>
+#include <mblock/exception.h>
+#include <mblock/msg_queue.h>
+#include <mblock/message.h>
+#include <mblock/msg_accepter.h>
+#include <mblock/class_registry.h>
+#include <pmt.h>
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <fstream>
+
+// Include the symbols needed for communication with USRP server
+#include <symbols_usrp_server_cs.h>
+#include <symbols_usrp_channel.h>
+#include <symbols_usrp_low_level_cs.h>
+#include <symbols_usrp_rx.h>
+
+static bool verbose = true;
+
+class test_usrp_rx : public mb_mblock
+{
+  mb_port_sptr         d_rx;
+  mb_port_sptr         d_cs;
+  pmt_t                d_rx_chan;      // returned tx channel handle
+
+  enum state_t {
+    INIT,
+    OPENING_USRP,
+    ALLOCATING_CHANNEL,
+    RECEIVING,
+    CLOSING_CHANNEL,
+    CLOSING_USRP,
+  };
+
+  state_t      d_state;
+
+  std::ofstream d_ofile;
+
+  long d_n_overruns;
+
+  long d_samples_recvd;
+  long d_samples_to_recv;
+
+ public:
+  test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~test_usrp_rx();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void open_usrp();
+  void close_usrp();
+  void allocate_channel();
+  void send_packets();
+  void enter_receiving();
+  void build_and_send_next_frame();
+  void handle_response_recv_raw_samples(pmt_t invocation_handle);
+  void enter_closing_channel();
+};
+
+test_usrp_rx::test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg),
+    d_n_overruns(0),
+    d_samples_recvd(0),
+    d_samples_to_recv(10e6)
+{ 
+  
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+  
+  // Pass a dictionary to usrp_server which specifies which interface to use, the stub or USRP
+  pmt_t usrp_dict = pmt_make_dict();
+
+  // Specify the RBF to use
+  pmt_dict_set(usrp_dict,
+               pmt_intern("rbf"),
+               pmt_intern("inband_1rxhb_1tx.rbf"));
+
+  pmt_dict_set(usrp_dict,
+               pmt_intern("decim-rx"),
+               pmt_from_long(128));
+
+  define_component("server", "usrp_server", usrp_dict);
+
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+
+}
+
+test_usrp_rx::~test_usrp_rx()
+{
+}
+
+void
+test_usrp_rx::initial_transition()
+{
+  open_usrp();
+}
+
+void
+test_usrp_rx::handle_message(mb_message_sptr msg)
+{
+  pmt_t        event = msg->signal();
+  pmt_t data = msg->data();
+
+  pmt_t handle = PMT_F;
+  pmt_t status = PMT_F;
+  std::string error_msg;
+  
+  switch(d_state){
+    
+    //----------------------------- OPENING_USRP ----------------------------//
+    // We only expect a response from opening the USRP which should be succesful
+    // or failed.
+    case OPENING_USRP:
+      if (pmt_eq(event, s_response_open)){
+        status = pmt_nth(1, data);
+        if (pmt_eq(status, PMT_T)){
+          allocate_channel();
+          return;
+        }
+        else {
+          error_msg = "failed to open usrp:";
+          goto bail;
+        }
+      }
+      goto unhandled;
+      
+    //----------------------- ALLOCATING CHANNELS --------------------//
+    // Allocate an RX channel to perform the overrun test.
+    case ALLOCATING_CHANNEL:
+      if (pmt_eq(event, s_response_allocate_channel)){
+        status = pmt_nth(1, data);
+        d_rx_chan = pmt_nth(2, data);
+
+        if (pmt_eq(status, PMT_T)){
+          enter_receiving();
+          return;
+        }
+        else {
+          error_msg = "failed to allocate channel:";
+          goto bail;
+        }
+      }
+      goto unhandled;
+
+    //--------------------------- RECEIVING ------------------------------//
+    // In the receiving state, we receive samples until the specified amount
+    // while counting the number of overruns.
+    case RECEIVING:
+      if (pmt_eq(event, s_response_recv_raw_samples)){
+        status = pmt_nth(1, data);
+
+        if (pmt_eq(status, PMT_T)){
+          handle_response_recv_raw_samples(data);
+          return;
+        }
+        else {
+          error_msg = "bad response-xmit-raw-frame:";
+          goto bail;
+        }
+      }
+      goto unhandled;
+    
+    //------------------------- CLOSING CHANNEL ----------------------------//
+    // Check deallocation response for the RX channel 
+    case CLOSING_CHANNEL:
+      if (pmt_eq(event, s_response_deallocate_channel)){
+        status = pmt_nth(1, data);
+
+        if (pmt_eq(status, PMT_T)){
+          close_usrp();
+          return;
+        }
+        else {
+          error_msg = "failed to deallocate channel:";
+          goto bail;
+        }
+      }
+
+      // Alternately, we ignore all response recv samples while waiting for the
+      // channel to actually close
+      if (pmt_eq(event, s_response_recv_raw_samples))
+        return;
+
+      goto unhandled;
+
+    //--------------------------- CLOSING USRP ------------------------------//
+    // Once we have received a successful USRP close response, we shutdown all
+    // mblocks and exit.
+    case CLOSING_USRP:
+      if (pmt_eq(event, s_response_close)){
+        status = pmt_nth(1, data);
+
+        if (pmt_eq(status, PMT_T)){
+          std::cout << "\nOverruns: " << d_n_overruns << std::endl;
+          fflush(stdout);
+          shutdown_all(PMT_T);
+          return;
+        }
+        else {
+          error_msg = "failed to close USRP:";
+          goto bail;
+        }
+      }
+      goto unhandled;
+
+    default:
+      goto unhandled;
+  }
+  return;
+
+ // An error occured, print it, and shutdown all m-blocks
+ bail:
+  std::cerr << error_msg << data
+           << "status = " << status << std::endl;
+  shutdown_all(PMT_F);
+  return;
+
+ // Received an unhandled message for a specific state
+ unhandled:
+  if(verbose && !pmt_eq(event, pmt_intern("%shutdown")))
+    std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
+              << "in state "<< d_state << std::endl;
+}
+
+
+void
+test_usrp_rx::open_usrp()
+{
+  pmt_t which_usrp = pmt_from_long(0);
+
+  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
+  d_state = OPENING_USRP;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_OVERRUN] Opening the USRP\n";
+}
+
+void
+test_usrp_rx::close_usrp()
+{
+  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
+  d_state = CLOSING_USRP;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_OVERRUN] Closing the USRP\n";
+}
+
+void
+test_usrp_rx::allocate_channel()
+{
+  long capacity = (long) 16e6;
+  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
+  d_state = ALLOCATING_CHANNEL;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_OVERRUN] Requesting RX channel allocation\n";
+}
+
+void
+test_usrp_rx::enter_receiving()
+{
+  d_state = RECEIVING;
+
+  d_rx->send(s_cmd_start_recv_raw_samples,
+             pmt_list2(PMT_F,
+                       d_rx_chan));
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_OVERRUN] Receiving...\n";
+}
+
+void
+test_usrp_rx::handle_response_recv_raw_samples(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+  pmt_t v_samples = pmt_nth(2, data);
+  pmt_t timestamp = pmt_nth(3, data);
+  pmt_t channel = pmt_nth(4, data);
+  pmt_t properties = pmt_nth(5, data);
+
+  d_samples_recvd += pmt_length(v_samples) / 4;
+
+  // Check for overrun
+  if(!pmt_is_dict(properties)) {
+    std::cout << "[TEST_USRP_INBAND_OVERRUN] Recv samples dictionary is improper\n";
+    return;
+  }
+
+  if(pmt_t overrun = pmt_dict_ref(properties, 
+                                  pmt_intern("overrun"), 
+                                  PMT_NIL)) {
+    if(pmt_eqv(overrun, PMT_T)) {
+      d_n_overruns++;
+
+      if(verbose && 0)
+        std::cout << "[TEST_USRP_INBAND_OVERRUN] Underrun\n";
+    }
+    else {
+    if(verbose && 0)
+      std::cout << "[TEST_USRP_INBAND_OVERRUN] No overrun\n" << overrun <<std::endl;
+    }
+  } else {
+
+    if(verbose && 0)
+      std::cout << "[TEST_USRP_INBAND_OVERRUN] No overrun\n";
+  }
+
+  // Check if the number samples we have received meets the test
+  if(d_samples_recvd >= d_samples_to_recv) {
+    d_rx->send(s_cmd_stop_recv_raw_samples, pmt_list2(PMT_NIL, d_rx_chan));
+    enter_closing_channel();
+    return;
+  }
+
+}
+
+void
+test_usrp_rx::enter_closing_channel()
+{
+  d_state = CLOSING_CHANNEL;
+  
+  sleep(2);
+  
+  d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan));
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_OVERRUN] Deallocating RX channel\n";
+}
+
+REGISTER_MBLOCK_CLASS(test_usrp_rx);
+
+
+// ----------------------------------------------------------------
+
+int
+main (int argc, char **argv)
+{
+  // handle any command line args here
+
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_NIL;
+
+  rt->run("top", "test_usrp_rx", PMT_F, &result);
+}
diff --git a/usrp/limbo/apps-inband/test_usrp_inband_ping.cc b/usrp/limbo/apps-inband/test_usrp_inband_ping.cc
new file mode 100644 (file)
index 0000000..d779c9a
--- /dev/null
@@ -0,0 +1,374 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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 <mblock/mblock.h>
+#include <mblock/runtime.h>
+#include <mblock/protocol_class.h>
+#include <mblock/exception.h>
+#include <mblock/msg_queue.h>
+#include <mblock/message.h>
+#include <mblock/msg_accepter.h>
+#include <mblock/class_registry.h>
+#include <pmt.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <iostream>
+
+// Include the symbols needed for communication with USRP server
+#include <symbols_usrp_server_cs.h>
+#include <symbols_usrp_channel.h>
+#include <symbols_usrp_low_level_cs.h>
+#include <symbols_usrp_tx.h>
+#include <symbols_usrp_rx.h>
+
+static bool verbose = false;
+
+class test_usrp_inband_ping : public mb_mblock
+{
+
+  mb_port_sptr  d_tx;   // Ports connected to the USRP server
+  mb_port_sptr  d_rx;
+  mb_port_sptr  d_cs;
+
+  pmt_t   d_tx_chan;    // Returned channel from TX allocation
+  pmt_t   d_rx_chan;    // Returned channel from RX allocation
+
+  pmt_t   d_which_usrp; // The USRP to use for the test
+
+  long    d_warm_msgs;  // The number of messages to 'warm' the USRP
+  long    d_warm_recvd; // The number of msgs received in the 'warm' state
+
+  // Keep track of current state
+  enum state_t {
+    INIT,
+    OPENING_USRP,
+    ALLOCATING_CHANNELS,
+    WARMING_USRP,
+    PINGING,
+    CLOSING_CHANNELS,
+    CLOSING_USRP,
+  };
+  state_t d_state;
+
+ public:
+  test_usrp_inband_ping(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~test_usrp_inband_ping();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void opening_usrp();
+  void allocating_channels();
+  void enter_warming_usrp();
+  void enter_pinging();
+  void build_and_send_ping();
+  void closing_channels();
+  void closing_usrp();
+};
+
+
+int
+main (int argc, char **argv)
+{
+  // handle any command line args here
+
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_NIL;
+
+  rt->run("top", "test_usrp_inband_ping", PMT_F, &result);
+}
+
+
+test_usrp_inband_ping::test_usrp_inband_ping(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg),
+  d_tx_chan(PMT_NIL),
+  d_rx_chan(PMT_NIL),
+  d_which_usrp(pmt_from_long(0)),
+  d_state(INIT)
+{
+  
+  // A dictionary is used to pass parameters to the USRP
+  pmt_t usrp_dict = pmt_make_dict();
+
+  // Specify the RBF to use
+  pmt_dict_set(usrp_dict,
+               pmt_intern("rbf"),
+               pmt_intern("fixed1.rbf"));
+
+  // Set TX and RX interpolations
+  pmt_dict_set(usrp_dict,
+               pmt_intern("interp-tx"),
+               pmt_from_long(128));
+
+  pmt_dict_set(usrp_dict,
+               pmt_intern("decim-rx"),
+               pmt_from_long(16));
+  
+  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+
+  // Create an instance of USRP server and connect ports
+  define_component("server", "usrp_server", usrp_dict);
+  connect("self", "tx0", "server", "tx0");
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+
+}
+
+test_usrp_inband_ping::~test_usrp_inband_ping()
+{
+}
+
+void
+test_usrp_inband_ping::initial_transition()
+{
+  opening_usrp();
+}
+
+// Handle message reads all incoming messages from USRP server which will be
+// initialization and ping responses.  We perform actions based on the current
+// state and the event (ie, ping response)
+void
+test_usrp_inband_ping::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();
+  pmt_t data = msg->data();
+  pmt_t port_id = msg->port_id();
+
+  pmt_t handle = PMT_F;
+  pmt_t status = PMT_F;
+  std::string error_msg;
+
+  // Dispatch based on state
+  switch(d_state) {
+
+    //----------------------------- OPENING_USRP ----------------------------//
+    // We only expect a response from opening the USRP which should be succesful
+    // or failed.
+    case OPENING_USRP:
+      
+      if(pmt_eq(event, s_response_open)) {
+
+        status = pmt_nth(1, data);          // failed/succes
+        
+        if(pmt_eq(status, PMT_T)) {
+          allocating_channels();
+          return;
+        }
+        else {
+          error_msg = "failed to open usrp:";
+          goto bail;
+        }
+
+      }
+
+      goto unhandled;   // all other messages not handled in this state
+      
+    
+    //----------------------- ALLOCATING CHANNELS --------------------//
+    // When allocating channels, we need to wait for 2 responses from
+    // USRP server: one for TX and one for RX.  Both are initialized to
+    // NIL so we know to continue to the next state once both are set.
+    case ALLOCATING_CHANNELS:
+
+      // A TX allocation response
+      if(pmt_eq(event, s_response_allocate_channel)
+          && pmt_eq(d_tx->port_symbol(), port_id)) 
+      {
+        status = pmt_nth(1, data);
+        
+        // If successful response, extract the channel
+        if(pmt_eq(status, PMT_T)) {
+          
+          d_tx_chan = pmt_nth(2, data);
+
+          if(verbose)
+            std::cout << "[TEST_USRP_INBAND_PING] Received TX allocation"
+                      << " on channel " << d_tx_chan << std::endl;
+
+          // If the RX has also been allocated already, we can continue
+          if(!pmt_eqv(d_rx_chan, PMT_NIL)) 
+            enter_warming_usrp();
+
+          return;
+        }
+        else {  // TX allocation failed
+          error_msg = "failed to allocate TX channel:";
+          goto bail;
+        }
+      }
+      
+      // A RX allocation response
+      if(pmt_eq(event, s_response_allocate_channel)
+          && pmt_eq(d_rx->port_symbol(), port_id)) 
+      {
+        status = pmt_nth(1, data);
+        
+        // If successful response, extract the channel
+        if(pmt_eq(status, PMT_T)) {
+          
+          d_rx_chan = pmt_nth(2, data);
+
+          if(verbose)
+            std::cout << "[TEST_USRP_INBAND_PING] Received RX allocation"
+                      << " on channel " << d_rx_chan << std::endl;
+
+          // If the TX has also been allocated already, we can continue
+          if(!pmt_eqv(d_tx_chan, PMT_NIL)) 
+            enter_warming_usrp();
+
+          return;
+        }
+        else {  // RX allocation failed
+          error_msg = "failed to allocate RX channel:";
+          goto bail;
+        }
+      }
+
+      goto unhandled;
+
+    //----------------------- WARMING USRP --------------------//
+    // The FX2 seems to need some amount of data to be buffered
+    // before it begins reading.  We use this state to simply
+    // warm up the USRP before benchmarking pings.
+    case WARMING_USRP:
+
+      // We really don't care about the responses from the
+      // control channel in the warming stage, but once we receive
+      // the proper number of responses we switch states.
+      if(pmt_eq(event, s_response_from_control_channel)
+          && pmt_eq(d_rx->port_symbol(), port_id))
+      {
+        d_warm_recvd++;
+
+        if(d_warm_recvd > d_warm_msgs)
+          enter_pinging();
+
+        return;
+      }
+
+      goto unhandled;
+
+    case PINGING:
+      goto unhandled;
+
+    case CLOSING_CHANNELS:
+      goto unhandled;
+
+    case CLOSING_USRP:
+      goto unhandled;
+
+    case INIT:
+      goto unhandled;
+
+  }
+ // An error occured, print it, and shutdown all m-blocks
+ bail:
+  std::cerr << error_msg << data
+           << "status = " << status << std::endl;
+  shutdown_all(PMT_F);
+  return;
+
+ // Received an unhandled message for a specific state
+ unhandled:
+  if(verbose)
+    std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
+              << "in state "<< d_state << std::endl;
+
+}
+
+
+// Sends a command to USRP server to open up a connection to the
+// specified USRP, which is defaulted to USRP 0 on the system
+void
+test_usrp_inband_ping::opening_usrp()
+{
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_PING] Opening USRP " 
+              << d_which_usrp << std::endl;
+
+  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, d_which_usrp));
+  d_state = OPENING_USRP;
+}
+
+// RX and TX channels must be allocated so that the USRP server can
+// properly share bandwidth across multiple USRPs.  No commands will be
+// successful to the USRP through the USRP server on the TX or RX channels until
+// a bandwidth allocation has been received.
+void
+test_usrp_inband_ping::allocating_channels()
+{
+  d_state = ALLOCATING_CHANNELS;
+
+  long capacity = (long) 16e6;
+  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
+  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
+}
+
+// The USRP needs some amount of initial data to pass a buffering point such
+// that it begins to pull and read data from the FX2.  We send an arbitrary
+// amount of data to start the pipeline, which are just pings.
+void
+test_usrp_inband_ping::enter_warming_usrp()
+{
+  d_state = WARMING_USRP;
+
+  for(int i=0; i < d_warm_msgs; i++)
+    build_and_send_ping();
+}
+
+void
+test_usrp_inband_ping::enter_pinging()
+{
+  d_state = PINGING;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_PING] Running ping tests\n";
+
+}
+
+// Pings are sent over the TX channel using the signal 'cmd-to-control-channel'
+// to the USRP server.  Within this message there can be infinite subpackets
+// stored as a list (the second parameter) and sent.  The only subpacket we send
+// is a ping, interpreted by the 'op-ping-fixed' signal.
+void
+test_usrp_inband_ping::build_and_send_ping()
+{
+  
+  d_tx->send(s_cmd_to_control_channel,    // USRP server signal
+             pmt_list2(PMT_NIL,           // invocation handle 
+                       pmt_list1(pmt_list3(s_op_ping_fixed, 
+                                           pmt_from_long(0), 
+                                           pmt_from_long(0)))));
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_PING] Ping!!" << std::endl;
+}
+
+REGISTER_MBLOCK_CLASS(test_usrp_inband_ping);
diff --git a/usrp/limbo/apps-inband/test_usrp_inband_registers.cc b/usrp/limbo/apps-inband/test_usrp_inband_registers.cc
new file mode 100644 (file)
index 0000000..d9bd2db
--- /dev/null
@@ -0,0 +1,435 @@
+/* -*- c++ -*- */
+/*
+ * 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 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 <mblock/mblock.h>
+#include <mblock/runtime.h>
+#include <mblock/protocol_class.h>
+#include <mblock/exception.h>
+#include <mblock/msg_queue.h>
+#include <mblock/message.h>
+//#include <mb_mblock_impl.h>
+#include <mblock/msg_accepter.h>
+#include <mblock/class_registry.h>
+#include <pmt.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <iostream>
+
+// Include the symbols needed for communication with USRP server
+#include <symbols_usrp_server_cs.h>
+#include <symbols_usrp_channel.h>
+#include <symbols_usrp_low_level_cs.h>
+#include <symbols_usrp_tx.h>
+#include <symbols_usrp_rx.h>
+
+static bool verbose = true;
+
+class test_usrp_inband_registers : public mb_mblock
+{
+
+  mb_port_sptr  d_tx;   // Ports connected to the USRP server
+  mb_port_sptr  d_rx;
+  mb_port_sptr  d_cs;
+
+  pmt_t   d_tx_chan;    // Returned channel from TX allocation
+  pmt_t   d_rx_chan;    // Returned channel from RX allocation
+
+  pmt_t   d_which_usrp; // The USRP to use for the test
+
+  long    d_warm_msgs;  // The number of messages to 'warm' the USRP
+  long    d_warm_recvd; // The number of msgs received in the 'warm' state
+
+  // Keep track of current state
+  enum state_t {
+    INIT,
+    OPENING_USRP,
+    ALLOCATING_CHANNELS,
+    WRITE_REGISTER,
+    READ_REGISTER,
+    CLOSING_CHANNELS,
+    CLOSING_USRP,
+  };
+  state_t d_state;
+
+ public:
+  test_usrp_inband_registers(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~test_usrp_inband_registers();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void opening_usrp();
+  void allocating_channels();
+  void write_register();
+  void read_register();
+  void closing_channels();
+  void closing_usrp();
+  void enter_receiving();
+  void build_and_send_ping();
+};
+
+
+int
+main (int argc, char **argv)
+{
+  // handle any command line args here
+
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_NIL;
+
+  rt->run("top", "test_usrp_inband_registers", PMT_F, &result);
+}
+
+
+test_usrp_inband_registers::test_usrp_inband_registers(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg),
+  d_tx_chan(PMT_NIL),
+  d_rx_chan(PMT_NIL),
+  d_which_usrp(pmt_from_long(0)),
+  d_state(INIT)
+{
+  
+  // A dictionary is used to pass parameters to the USRP
+  pmt_t usrp_dict = pmt_make_dict();
+
+  // Specify the RBF to use
+  pmt_dict_set(usrp_dict,
+               pmt_intern("rbf"),
+               pmt_intern("inband_1rxhb_1tx.rbf"));
+
+  // Set TX and RX interpolations
+  pmt_dict_set(usrp_dict,
+               pmt_intern("interp-tx"),
+               pmt_from_long(128));
+
+  pmt_dict_set(usrp_dict,
+               pmt_intern("decim-rx"),
+               pmt_from_long(16));
+  
+  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+
+  // Create an instance of USRP server and connect ports
+  define_component("server", "usrp_server", usrp_dict);
+  connect("self", "tx0", "server", "tx0");
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+
+}
+
+test_usrp_inband_registers::~test_usrp_inband_registers()
+{
+}
+
+void
+test_usrp_inband_registers::initial_transition()
+{
+  opening_usrp();
+}
+
+// Handle message reads all incoming messages from USRP server which will be
+// initialization and ping responses.  We perform actions based on the current
+// state and the event (ie, ping response)
+void
+test_usrp_inband_registers::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();
+  pmt_t data = msg->data();
+  pmt_t port_id = msg->port_id();
+
+  pmt_t handle = PMT_F;
+  pmt_t status = PMT_F;
+  std::string error_msg;
+
+  // Dispatch based on state
+  switch(d_state) {
+
+    //----------------------------- OPENING_USRP ----------------------------//
+    // We only expect a response from opening the USRP which should be succesful
+    // or failed.
+    case OPENING_USRP:
+      
+      if(pmt_eq(event, s_response_open)) {
+
+        status = pmt_nth(1, data);          // failed/succes
+        
+        if(pmt_eq(status, PMT_T)) {
+          allocating_channels();
+          return;
+        }
+        else {
+          error_msg = "failed to open usrp:";
+          goto bail;
+        }
+
+      }
+
+      goto unhandled;   // all other messages not handled in this state
+      
+    
+    //----------------------- ALLOCATING CHANNELS --------------------//
+    // When allocating channels, we need to wait for 2 responses from
+    // USRP server: one for TX and one for RX.  Both are initialized to
+    // NIL so we know to continue to the next state once both are set.
+    case ALLOCATING_CHANNELS:
+
+      // A TX allocation response
+      if(pmt_eq(event, s_response_allocate_channel)
+          && pmt_eq(d_tx->port_symbol(), port_id)) 
+      {
+        status = pmt_nth(1, data);
+        
+        // If successful response, extract the channel
+        if(pmt_eq(status, PMT_T)) {
+          
+          d_tx_chan = pmt_nth(2, data);
+
+          if(verbose)
+            std::cout << "[TEST_USRP_INBAND_PING] Received TX allocation"
+                      << " on channel " << d_tx_chan << std::endl;
+
+          // If the RX has also been allocated already, we can continue
+          if(!pmt_eqv(d_rx_chan, PMT_NIL)) {
+            enter_receiving();
+            write_register();
+          }
+
+          return;
+        }
+        else {  // TX allocation failed
+          error_msg = "failed to allocate TX channel:";
+          goto bail;
+        }
+      }
+      
+      // A RX allocation response
+      if(pmt_eq(event, s_response_allocate_channel)
+          && pmt_eq(d_rx->port_symbol(), port_id)) 
+      {
+        status = pmt_nth(1, data);
+        
+        // If successful response, extract the channel
+        if(pmt_eq(status, PMT_T)) {
+          
+          d_rx_chan = pmt_nth(2, data);
+
+          if(verbose)
+            std::cout << "[TEST_USRP_INBAND_PING] Received RX allocation"
+                      << " on channel " << d_rx_chan << std::endl;
+
+          // If the TX has also been allocated already, we can continue
+          if(!pmt_eqv(d_tx_chan, PMT_NIL)) {
+            enter_receiving();
+            write_register();
+          }
+
+          return;
+        }
+        else {  // RX allocation failed
+          error_msg = "failed to allocate RX channel:";
+          goto bail;
+        }
+      }
+
+      goto unhandled;
+
+    //-------------------------- WRITE REGISTER ----------------------------//
+    // In the write register state, we do not expect to receive any messages
+    // since the write does not directly generate a response until the USRP
+    // responds.
+    case WRITE_REGISTER:
+      goto unhandled;
+
+    //-------------------------- READ REGISTER ----------------------------//
+    // In the read register state, we only expect a read register response back
+    // that has the value we expect to have in it.  We read the response, ensure
+    // that the read was successful and display the register value.
+    case READ_REGISTER:
+
+      if(pmt_eq(event, s_response_from_control_channel)
+          && pmt_eq(d_tx->port_symbol(), port_id))
+      {
+        status = pmt_nth(1, data);
+
+        // If the read was successful, we extract the subpacket information
+        if(pmt_eq(status, PMT_T)) {
+          
+          pmt_t subp = pmt_nth(2, data);      // subpacket should be the read reg reply
+
+          pmt_t subp_sig  = pmt_nth(0, subp);
+          pmt_t subp_data = pmt_nth(1, subp);
+
+          if(!pmt_eqv(subp_sig, s_op_read_reg_reply)) {
+            error_msg = "received improper subpacket when expecting reg reply.";
+            goto bail;
+          }
+
+          pmt_t rid     = pmt_nth(0, subp_data);
+          pmt_t reg_num = pmt_nth(1, subp_data);
+          pmt_t reg_val = pmt_nth(2, subp_data);
+
+          if(verbose)
+            std::cout << "[TEST_USRP_INBAND_REGISTERS] Received read reg reply "
+                      << "("
+                      << "RID: " << rid << ", " 
+                      << "Reg: " << reg_num << ", "
+                      << "Val: " << reg_val
+                      << ")\n";
+          
+          // read_register();  FIX ME STATE TRANSITION
+          return;
+
+        } else {  // bail on unsuccessful write
+          error_msg = "failed to write to register.";
+          goto bail;
+        }
+      }
+      goto unhandled;
+
+    case CLOSING_CHANNELS:
+      goto unhandled;
+
+    case CLOSING_USRP:
+      goto unhandled;
+
+    case INIT:
+      goto unhandled;
+
+  }
+ // An error occured, print it, and shutdown all m-blocks
+ bail:
+  std::cerr << error_msg << data
+           << "status = " << status << std::endl;
+  shutdown_all(PMT_F);
+  return;
+
+ // Received an unhandled message for a specific state
+ unhandled:
+  if(verbose && !pmt_eq(event, s_response_recv_raw_samples))
+    std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
+              << "in state "<< d_state << std::endl;
+
+}
+
+
+// Sends a command to USRP server to open up a connection to the
+// specified USRP, which is defaulted to USRP 0 on the system
+void
+test_usrp_inband_registers::opening_usrp()
+{
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_PING] Opening USRP " 
+              << d_which_usrp << std::endl;
+
+  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, d_which_usrp));
+  d_state = OPENING_USRP;
+}
+
+// RX and TX channels must be allocated so that the USRP server can
+// properly share bandwidth across multiple USRPs.  No commands will be
+// successful to the USRP through the USRP server on the TX or RX channels until
+// a bandwidth allocation has been received.
+void
+test_usrp_inband_registers::allocating_channels()
+{
+  d_state = ALLOCATING_CHANNELS;
+
+  long capacity = (long) 16e6;
+  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
+  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
+}
+
+// After allocating the channels, a write register command will be sent to the
+// USRP.
+void
+test_usrp_inband_registers::write_register()
+{
+  d_state = WRITE_REGISTER;
+
+  long reg = 0;
+
+  d_tx->send(s_cmd_to_control_channel,    // C/S packet
+             pmt_list2(PMT_NIL,           // invoc handle
+                       pmt_list1(
+                            pmt_list2(s_op_write_reg, 
+                                      pmt_list2(
+                                      pmt_from_long(reg), 
+                                      pmt_from_long(0xbeef))))));
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_REGISTERS] Writing 0xbeef to " 
+              << reg << std::endl;
+
+  read_register();  // immediately transition to read the register
+}
+
+// Temporary: for testing pings
+void
+test_usrp_inband_registers::build_and_send_ping()
+{
+  
+  d_tx->send(s_cmd_to_control_channel,
+             pmt_list2(PMT_NIL, pmt_list1(pmt_list2(s_op_ping_fixed,
+                                                    pmt_list2(pmt_from_long(0),
+                                                              pmt_from_long(0))))));
+
+  std::cout << "[TEST_USRP_INBAND_CS] Ping sent" << std::endl;
+}
+
+// After writing to the register, we want to read the value back and ensure that
+// it is the same value that we wrote.
+void
+test_usrp_inband_registers::read_register()
+{
+  d_state = READ_REGISTER;
+
+  long reg = 9;
+
+  d_tx->send(s_cmd_to_control_channel,    // C/S packet
+             pmt_list2(PMT_NIL,           // invoc handle
+                       pmt_list1(
+                            pmt_list2(s_op_read_reg, 
+                                      pmt_list2(
+                                      pmt_from_long(0),   // rid 
+                                      pmt_from_long(reg))))));
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_REGISTERS] Reading from register " 
+              << reg << std::endl;
+}
+
+// Used to enter the receiving state
+void
+test_usrp_inband_registers::enter_receiving()
+{
+  d_rx->send(s_cmd_start_recv_raw_samples,
+             pmt_list2(PMT_F,
+                       d_rx_chan));
+}
+
+REGISTER_MBLOCK_CLASS(test_usrp_inband_registers);
diff --git a/usrp/limbo/apps-inband/test_usrp_inband_rx.cc b/usrp/limbo/apps-inband/test_usrp_inband_rx.cc
new file mode 100644 (file)
index 0000000..4f21e4a
--- /dev/null
@@ -0,0 +1,362 @@
+/* -*- c++ -*- */
+/*
+ * 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 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 <mblock/mblock.h>
+#include <mblock/runtime.h>
+#include <mblock/protocol_class.h>
+#include <mblock/exception.h>
+#include <mblock/msg_queue.h>
+#include <mblock/message.h>
+#include <mblock/msg_accepter.h>
+#include <mblock/class_registry.h>
+#include <pmt.h>
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <fstream>
+
+// Include the symbols needed for communication with USRP server
+#include <symbols_usrp_server_cs.h>
+#include <symbols_usrp_channel.h>
+#include <symbols_usrp_low_level_cs.h>
+#include <symbols_usrp_rx.h>
+
+static bool verbose = true;
+
+class test_usrp_rx : public mb_mblock
+{
+  mb_port_sptr         d_rx;
+  mb_port_sptr         d_cs;
+  pmt_t                d_rx_chan;      // returned tx channel handle
+
+  enum state_t {
+    INIT,
+    OPENING_USRP,
+    ALLOCATING_CHANNEL,
+    RECEIVING,
+    CLOSING_CHANNEL,
+    CLOSING_USRP,
+  };
+
+  state_t      d_state;
+
+  std::ofstream d_ofile;
+
+  long d_samples_recvd;
+  long d_samples_to_recv;
+
+ public:
+  test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~test_usrp_rx();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void open_usrp();
+  void close_usrp();
+  void allocate_channel();
+  void send_packets();
+  void enter_receiving();
+  void build_and_send_next_frame();
+  void handle_response_recv_raw_samples(pmt_t invocation_handle);
+  void enter_closing_channel();
+};
+
+test_usrp_rx::test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg),
+    d_samples_recvd(0),
+    d_samples_to_recv(20e6)
+{ 
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+  
+  // Pass a dictionary to usrp_server which specifies which interface to use, the stub or USRP
+  pmt_t usrp_dict = pmt_make_dict();
+  
+  // To test the application without a USRP
+  bool fake_usrp_p = false;
+  if(fake_usrp_p) {
+    pmt_dict_set(usrp_dict, 
+                 pmt_intern("fake-usrp"),
+                            PMT_T);
+  }
+
+  // Specify the RBF to use
+  pmt_dict_set(usrp_dict,
+               pmt_intern("rbf"),
+               pmt_intern("inband_1rxhb_1tx.rbf"));
+
+  pmt_dict_set(usrp_dict,
+               pmt_intern("decim-rx"),
+               pmt_from_long(64));
+
+//  If unspecified, chooses center frequency from range
+//  pmt_dict_set(usrp_dict,
+//               pmt_intern("rf-freq"),
+//               pmt_from_long(10e6));
+
+  define_component("server", "usrp_server", usrp_dict);
+
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+
+}
+
+test_usrp_rx::~test_usrp_rx()
+{
+}
+
+void
+test_usrp_rx::initial_transition()
+{
+  open_usrp();
+}
+
+void
+test_usrp_rx::handle_message(mb_message_sptr msg)
+{
+  pmt_t        event = msg->signal();
+  pmt_t data = msg->data();
+
+  pmt_t handle = PMT_F;
+  pmt_t status = PMT_F;
+  std::string error_msg;
+  
+  switch(d_state){
+    
+    //----------------------------- OPENING_USRP ----------------------------//
+    // We only expect a response from opening the USRP which should be succesful
+    // or failed.
+    case OPENING_USRP:
+      if (pmt_eq(event, s_response_open)){
+        status = pmt_nth(1, data);
+        if (pmt_eq(status, PMT_T)){
+          allocate_channel();
+          return;
+        }
+        else {
+          error_msg = "failed to open usrp:";
+          goto bail;
+        }
+      }
+      goto unhandled;
+      
+    //----------------------- ALLOCATING CHANNELS --------------------//
+    // Allocate an RX channel to perform the overrun test.
+    case ALLOCATING_CHANNEL:
+      if (pmt_eq(event, s_response_allocate_channel)){
+        status = pmt_nth(1, data);
+        d_rx_chan = pmt_nth(2, data);
+
+        if (pmt_eq(status, PMT_T)){
+          enter_receiving();
+          return;
+        }
+        else {
+          error_msg = "failed to allocate channel:";
+          goto bail;
+        }
+      }
+      goto unhandled;
+
+    //--------------------------- RECEIVING ------------------------------//
+    // In the receiving state, we receive samples until the specified amount
+    // while counting the number of overruns.
+    case RECEIVING:
+      if (pmt_eq(event, s_response_recv_raw_samples)){
+        status = pmt_nth(1, data);
+
+        if (pmt_eq(status, PMT_T)){
+          handle_response_recv_raw_samples(data);
+          return;
+        }
+        else {
+          error_msg = "bad response-xmit-raw-frame:";
+          goto bail;
+        }
+      }
+      goto unhandled;
+    
+    //------------------------- CLOSING CHANNEL ----------------------------//
+    // Check deallocation response for the RX channel 
+    case CLOSING_CHANNEL:
+      if (pmt_eq(event, s_response_deallocate_channel)){
+        status = pmt_nth(1, data);
+
+        if (pmt_eq(status, PMT_T)){
+          close_usrp();
+          return;
+        }
+        else {
+          error_msg = "failed to deallocate channel:";
+          goto bail;
+        }
+      }
+
+      // Alternately, we ignore all response recv samples while waiting for the
+      // channel to actually close
+      if (pmt_eq(event, s_response_recv_raw_samples))
+        return;
+
+      goto unhandled;
+
+    //--------------------------- CLOSING USRP ------------------------------//
+    // Once we have received a successful USRP close response, we shutdown all
+    // mblocks and exit.
+    case CLOSING_USRP:
+      if (pmt_eq(event, s_response_close)){
+        status = pmt_nth(1, data);
+
+        if (pmt_eq(status, PMT_T)){
+          fflush(stdout);
+          shutdown_all(PMT_T);
+          return;
+        }
+        else {
+          error_msg = "failed to close USRP:";
+          goto bail;
+        }
+      }
+      goto unhandled;
+
+    default:
+      goto unhandled;
+  }
+  return;
+
+ // An error occured, print it, and shutdown all m-blocks
+ bail:
+  std::cerr << error_msg << data
+           << "status = " << status << std::endl;
+  shutdown_all(PMT_F);
+  return;
+
+ // Received an unhandled message for a specific state
+ unhandled:
+  if(verbose && !pmt_eq(event, pmt_intern("%shutdown")))
+    std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
+              << "in state "<< d_state << std::endl;
+}
+
+
+void
+test_usrp_rx::open_usrp()
+{
+  pmt_t which_usrp = pmt_from_long(0);
+
+  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
+  d_state = OPENING_USRP;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_RX] Opening the USRP\n";
+}
+
+void
+test_usrp_rx::close_usrp()
+{
+
+  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
+  d_state = CLOSING_USRP;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_RX] Closing the USRP\n";
+}
+
+void
+test_usrp_rx::allocate_channel()
+{
+  long capacity = (long) 16e6;
+  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
+  d_state = ALLOCATING_CHANNEL;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_RX] Requesting RX channel allocation\n";
+}
+
+void
+test_usrp_rx::enter_receiving()
+{
+  d_state = RECEIVING;
+
+  d_rx->send(s_cmd_start_recv_raw_samples,
+             pmt_list2(PMT_F,
+                       d_rx_chan));
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_RX] Receiving...\n";
+}
+
+void
+test_usrp_rx::handle_response_recv_raw_samples(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+  pmt_t v_samples = pmt_nth(2, data);
+  pmt_t timestamp = pmt_nth(3, data);
+  pmt_t channel = pmt_nth(4, data);
+  pmt_t properties = pmt_nth(5, data);
+
+  d_samples_recvd += pmt_length(v_samples) / 4;
+
+  // Check for overrun
+  if(!pmt_is_dict(properties)) {
+    std::cout << "[TEST_USRP_INBAND_RX] Recv samples dictionary is improper\n";
+    return;
+  }
+
+  // Check if the number samples we have received meets the test
+  if(d_samples_recvd >= d_samples_to_recv) {
+    d_rx->send(s_cmd_stop_recv_raw_samples, pmt_list2(PMT_NIL, d_rx_chan));
+    enter_closing_channel();
+    return;
+  }
+
+}
+
+void
+test_usrp_rx::enter_closing_channel()
+{
+  d_state = CLOSING_CHANNEL;
+
+  d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan));
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_RX] Deallocating RX channel\n";
+}
+
+REGISTER_MBLOCK_CLASS(test_usrp_rx);
+
+
+// ----------------------------------------------------------------
+
+int
+main (int argc, char **argv)
+{
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_NIL;
+
+  rt->run("top", "test_usrp_rx", PMT_F, &result);
+
+}
diff --git a/usrp/limbo/apps-inband/test_usrp_inband_timestamps.cc b/usrp/limbo/apps-inband/test_usrp_inband_timestamps.cc
new file mode 100644 (file)
index 0000000..3b874d1
--- /dev/null
@@ -0,0 +1,506 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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 <mblock/mblock.h>
+#include <mblock/runtime.h>
+#include <mblock/protocol_class.h>
+#include <mblock/exception.h>
+#include <mblock/msg_queue.h>
+#include <mblock/message.h>
+#include <mblock/msg_accepter.h>
+#include <mblock/class_registry.h>
+#include <pmt.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <iostream>
+
+#include <ui_nco.h>
+#include <symbols_usrp_server_cs.h>
+#include <symbols_usrp_channel.h>
+#include <symbols_usrp_low_level_cs.h>
+#include <symbols_usrp_tx.h>
+#include <symbols_usrp_rx.h>
+
+#define NBPING  10
+
+static bool verbose = true;
+bool bskip = false;
+long bstep = 10000;
+long bcurr = 0;
+long incr = 0x500;
+long ptime = 0x000;
+
+class test_usrp_inband_timestamps : public mb_mblock
+{
+  mb_port_sptr         d_tx;
+  mb_port_sptr         d_rx;
+  mb_port_sptr         d_cs;
+  pmt_t                d_tx_chan;      // returned tx channel handle
+  pmt_t                d_rx_chan;      // returned tx channel handle
+
+  struct timeval times[NBPING];
+
+  enum state_t {
+    INIT,
+    OPENING_USRP,
+    ALLOCATING_CHANNEL,
+    TRANSMITTING,
+    CLOSING_CHANNEL,
+    CLOSING_USRP,
+  };
+
+  state_t      d_state;
+  long         d_nsamples_to_send;
+  long         d_nsamples_xmitted;
+  long         d_nframes_xmitted;
+  long         d_samples_per_frame;
+  bool         d_done_sending;
+
+  // for generating sine wave output
+  ui_nco<float,float>  d_nco;
+  double               d_amplitude;
+
+ public:
+  test_usrp_inband_timestamps(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~test_usrp_inband_timestamps();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void open_usrp();
+  void close_usrp();
+  void allocate_channel();
+  void send_packets();
+  void enter_receiving();
+  void enter_transmitting();
+  void build_and_send_ping();
+  void build_and_send_next_frame();
+  void handle_xmit_response(pmt_t invocation_handle);
+  void enter_closing_channel();
+};
+
+test_usrp_inband_timestamps::test_usrp_inband_timestamps(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg),
+    d_tx_chan(PMT_NIL),
+    d_rx_chan(PMT_NIL),
+    d_state(INIT), d_nsamples_to_send((long) 40e6),
+    d_nsamples_xmitted(0),
+    d_nframes_xmitted(0),
+    //d_samples_per_frame((long)(126)),
+    d_samples_per_frame((long)(126 * 2)),      // non-full packet
+    //d_samples_per_frame((long)(126 * 3.5)),  // non-full packet
+    //d_samples_per_frame((long)(126 * 4)),    // full packet
+    d_done_sending(false),
+    d_amplitude(16384)
+{ 
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Initializing...\n";
+  
+  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+  
+  bool fake_usrp_p = false;
+
+  // Test the TX side
+
+  pmt_t usrp_dict = pmt_make_dict();
+
+  if(fake_usrp_p) {
+    pmt_dict_set(usrp_dict, 
+                 pmt_intern("fake-usrp"),
+                            PMT_T);
+  }
+
+  // Set TX and RX interpolations
+  pmt_dict_set(usrp_dict,
+               pmt_intern("interp-tx"),
+               pmt_from_long(128));
+
+  pmt_dict_set(usrp_dict,
+               pmt_intern("decim-rx"),
+               pmt_from_long(16));
+
+  // Specify the RBF to use
+  pmt_dict_set(usrp_dict,
+               pmt_intern("rbf"),
+               pmt_intern("inband_1rxhb_1tx.rbf"));
+
+  define_component("server", "usrp_server", usrp_dict);
+
+  connect("self", "tx0", "server", "tx0");
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+
+  // initialize NCO
+  double freq = 100e3;
+  int interp = 32;                         // 32 -> 4MS/s
+  double sample_rate = 128e6 / interp; 
+  d_nco.set_freq(2*M_PI * freq/sample_rate);
+
+}
+
+test_usrp_inband_timestamps::~test_usrp_inband_timestamps()
+{
+}
+
+void
+test_usrp_inband_timestamps::initial_transition()
+{
+  open_usrp();
+}
+
+void
+test_usrp_inband_timestamps::handle_message(mb_message_sptr msg)
+{
+  pmt_t        event = msg->signal();
+  pmt_t data = msg->data();
+  pmt_t port_id = msg->port_id();
+
+  pmt_t handle = PMT_F;
+  pmt_t status = PMT_F;
+  std::string error_msg;
+  
+  //std::cout << msg << std::endl;
+
+  switch(d_state){
+  case OPENING_USRP:
+    if (pmt_eq(event, s_response_open)){
+      status = pmt_nth(1, data);
+      if (pmt_eq(status, PMT_T)){
+        allocate_channel();
+        return;
+      }
+      else {
+        error_msg = "failed to open usrp:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+    
+  case ALLOCATING_CHANNEL:
+    if (pmt_eq(event, s_response_allocate_channel)){
+
+      if(pmt_eq(d_tx->port_symbol(), port_id)) {
+        status = pmt_nth(1, data);
+        d_tx_chan = pmt_nth(2, data);
+
+        if (pmt_eq(status, PMT_T)){
+
+          if(verbose)
+            std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Received allocation for TX\n";
+
+          if(!pmt_eqv(d_rx_chan, PMT_NIL)) {
+            enter_receiving();
+            enter_transmitting();
+          }
+          return;
+        }
+        else {
+          error_msg = "failed to allocate channel:";
+          goto bail;
+        }
+      }
+      
+      if(pmt_eq(d_rx->port_symbol(), port_id)) {
+        status = pmt_nth(1, data);
+        d_rx_chan = pmt_nth(2, data);
+
+        if (pmt_eq(status, PMT_T)){
+
+          if(verbose)
+            std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Received allocation for TX\n";
+          
+          if(!pmt_eqv(d_tx_chan, PMT_NIL)) {
+            enter_receiving();
+            enter_transmitting();
+          }
+          return;
+        }
+        else {
+          error_msg = "failed to allocate channel:";
+          goto bail;
+        }
+      }
+    }
+    goto unhandled;
+
+  case TRANSMITTING:
+    if (pmt_eq(event, s_response_xmit_raw_frame)){
+      handle = pmt_nth(0, data);
+      status = pmt_nth(1, data);
+
+      if (pmt_eq(status, PMT_T)){
+        handle_xmit_response(handle);
+        return;
+      }
+      else {
+        error_msg = "bad response-xmit-raw-frame:";
+        goto bail;
+      }
+    }
+
+    if (pmt_eq(event, s_response_from_control_channel)) {
+      std::cout << "ping response!\n";
+    }
+    goto unhandled;
+
+  case CLOSING_CHANNEL:
+    if (pmt_eq(event, s_response_deallocate_channel)){
+      status = pmt_nth(1, data);
+
+      if (pmt_eq(status, PMT_T)){
+        close_usrp();
+        return;
+      }
+      else {
+        error_msg = "failed to deallocate channel:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+
+  case CLOSING_USRP:
+    if (pmt_eq(event, s_response_close)){
+      status = pmt_nth(1, data);
+
+      if (pmt_eq(status, PMT_T)){
+        shutdown_all(PMT_T);
+        return;
+      }
+      else {
+        error_msg = "failed to close USRP:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+
+  default:
+    goto unhandled;
+  }
+  return;
+
+ bail:
+  std::cerr << error_msg << data
+           << "status = " << status << std::endl;
+  shutdown_all(PMT_F);
+  return;
+
+ unhandled:
+  if(verbose && 0)
+    std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
+              << "in state "<< d_state << std::endl;
+}
+
+
+void
+test_usrp_inband_timestamps::open_usrp()
+{
+  pmt_t which_usrp = pmt_from_long(0);
+
+  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
+  d_state = OPENING_USRP;
+}
+
+void
+test_usrp_inband_timestamps::close_usrp()
+{
+  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
+  d_state = CLOSING_USRP;
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Closing USRP\n";
+}
+
+void
+test_usrp_inband_timestamps::allocate_channel()
+{
+  long capacity = (long) 16e6;
+  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
+  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
+  d_state = ALLOCATING_CHANNEL;
+}
+
+void
+test_usrp_inband_timestamps::enter_receiving()
+{
+  d_rx->send(s_cmd_start_recv_raw_samples,
+             pmt_list2(PMT_F,
+                       d_rx_chan));
+}
+
+void
+test_usrp_inband_timestamps::enter_transmitting()
+{
+  d_state = TRANSMITTING;
+  d_nsamples_xmitted = 0;
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Beginning transmission\n";
+
+  sleep(1);
+
+  build_and_send_next_frame();
+  build_and_send_next_frame();
+  build_and_send_next_frame();
+  build_and_send_next_frame();
+
+}
+
+void
+test_usrp_inband_timestamps::build_and_send_ping()
+{
+  
+  d_tx->send(s_cmd_to_control_channel,
+             pmt_list2(PMT_NIL, pmt_list1(pmt_list2(s_op_ping_fixed,
+                                                    pmt_list2(pmt_from_long(0),
+                                                              pmt_from_long(0))))));
+  if(verbose && 0)
+    std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Ping sent" << std::endl;
+}
+
+void
+test_usrp_inband_timestamps::build_and_send_next_frame()
+{
+  // allocate the uniform vector for the samples
+  // FIXME perhaps hold on to this between calls
+
+#if 0
+  long nsamples_this_frame =
+    std::min(d_nsamples_to_send - d_nsamples_xmitted,
+            d_samples_per_frame);
+#else
+  long nsamples_this_frame = d_samples_per_frame;
+#endif
+
+  if (nsamples_this_frame == 0){
+    d_done_sending = true;
+    return;
+  }
+    
+
+  size_t nshorts = 2 * nsamples_this_frame;    // 16-bit I & Q
+  pmt_t uvec = pmt_make_s16vector(nshorts, 0);
+  size_t ignore;
+  int16_t *samples = pmt_s16vector_writable_elements(uvec, ignore);
+
+  // fill in the complex sinusoid
+
+  for (int i = 0; i < nsamples_this_frame; i++){
+
+    if (1){
+      gr_complex s;
+      d_nco.sincos(&s, 1, d_amplitude);
+      // write 16-bit i & q
+      samples[2*i] =   (int16_t) s.real();
+      samples[2*i+1] = (int16_t) s.imag();
+    }
+    else {
+      gr_complex s(d_amplitude, d_amplitude);
+
+      // write 16-bit i & q
+      samples[2*i] =   (int16_t) s.real();
+      samples[2*i+1] = (int16_t) s.imag();
+    }
+  }
+
+  pmt_t timestamp;
+
+  if(bskip) {
+    timestamp = pmt_from_long(0x0);    // throw away  
+    bcurr++;
+    if(bcurr == bstep) {
+      bskip = false;
+      bcurr = 0;
+    }
+  } else {
+    timestamp = pmt_from_long(0xffffffff);     // NOW
+    timestamp = pmt_from_long(ptime);
+    ptime += incr;
+    bcurr++;
+    if(bcurr == bstep) {
+      //bskip = true;
+      bcurr = 0;
+    }
+  }
+
+  std::cout << bskip << " -- " << bcurr << std::endl;
+
+  d_tx->send(s_cmd_xmit_raw_frame,
+            pmt_list4(pmt_from_long(d_nframes_xmitted),  // invocation-handle
+                      d_tx_chan,                         // channel
+                      uvec,                              // the samples
+                      timestamp));
+
+  d_nsamples_xmitted += nsamples_this_frame;
+  d_nframes_xmitted++;
+
+  if(verbose && 0)
+    std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Transmitted frame\n";
+  
+  //build_and_send_next_frame();
+}
+
+
+void
+test_usrp_inband_timestamps::handle_xmit_response(pmt_t handle)
+{
+  if (d_done_sending &&
+      pmt_to_long(handle) == (d_nframes_xmitted - 1)){
+    // We're done sending and have received all responses
+    enter_closing_channel();
+  }
+
+  build_and_send_next_frame();
+  //build_and_send_ping();
+}
+
+void
+test_usrp_inband_timestamps::enter_closing_channel()
+{
+  d_state = CLOSING_CHANNEL;
+  
+  d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan));
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Closing channel\n";
+}
+
+REGISTER_MBLOCK_CLASS(test_usrp_inband_timestamps);
+
+
+// ----------------------------------------------------------------
+
+int
+main (int argc, char **argv)
+{
+  // handle any command line args here
+
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_NIL;
+
+  rt->run("top", "test_usrp_inband_timestamps", PMT_F, &result);
+}
diff --git a/usrp/limbo/apps-inband/test_usrp_inband_tx.cc b/usrp/limbo/apps-inband/test_usrp_inband_tx.cc
new file mode 100644 (file)
index 0000000..9f294e7
--- /dev/null
@@ -0,0 +1,411 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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 <mblock/mblock.h>
+#include <mblock/runtime.h>
+#include <mblock/protocol_class.h>
+#include <mblock/exception.h>
+#include <mblock/msg_queue.h>
+#include <mblock/message.h>
+#include <mblock/msg_accepter.h>
+#include <mblock/class_registry.h>
+#include <pmt.h>
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+
+#include <ui_nco.h>
+#include <symbols_usrp_server_cs.h>
+#include <symbols_usrp_channel.h>
+#include <symbols_usrp_low_level_cs.h>
+#include <symbols_usrp_tx.h>
+
+static bool verbose = true;
+
+class test_usrp_tx : public mb_mblock
+{
+  mb_port_sptr         d_tx;
+  mb_port_sptr         d_cs;
+  pmt_t                d_tx_chan;      // returned tx channel handle
+
+  enum state_t {
+    INIT,
+    OPENING_USRP,
+    ALLOCATING_CHANNEL,
+    TRANSMITTING,
+    CLOSING_CHANNEL,
+    CLOSING_USRP,
+  };
+
+  state_t      d_state;
+  long         d_nsamples_to_send;
+  long         d_nsamples_xmitted;
+  long         d_nframes_xmitted;
+  long         d_samples_per_frame;
+  bool         d_done_sending;
+
+  // for generating sine wave output
+  ui_nco<float,float>  d_nco;
+  double               d_amplitude;
+
+ public:
+  test_usrp_tx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~test_usrp_tx();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void open_usrp();
+  void close_usrp();
+  void allocate_channel();
+  void send_packets();
+  void enter_transmitting();
+  void build_and_send_next_frame();
+  void handle_xmit_response(pmt_t invocation_handle);
+  void enter_closing_channel();
+};
+
+test_usrp_tx::test_usrp_tx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg),
+    d_state(INIT), d_nsamples_to_send((long) 80e6),
+    d_nsamples_xmitted(0),
+    d_nframes_xmitted(0),
+    d_samples_per_frame((long)(126 * 4)),      // full packet
+    d_done_sending(false),
+    d_amplitude(16384)
+{ 
+  // std::cout << "[TEST_USRP_TX] Initializing...\n";
+  
+  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+  
+  //bool fake_usrp_p = true;
+  bool fake_usrp_p = false;
+
+  // Test the TX side
+
+  pmt_t usrp_dict = pmt_make_dict();
+
+  if(fake_usrp_p) {
+    pmt_dict_set(usrp_dict, 
+                 pmt_intern("fake-usrp"),
+                            PMT_T);
+  }
+  
+  // Specify the RBF to use
+  pmt_dict_set(usrp_dict,
+               pmt_intern("rbf"),
+               pmt_intern("inband_1rxhb_1tx.rbf"));
+
+  // Set TX and RX interpolations
+  pmt_dict_set(usrp_dict,
+               pmt_intern("interp-tx"),
+               pmt_from_long(64));
+
+//  If unspecified, chooses center frequency from range
+//  pmt_dict_set(usrp_dict,
+//               pmt_intern("rf-freq"),
+//               pmt_from_long(10e6));
+
+  define_component("server", "usrp_server", usrp_dict);
+
+  connect("self", "tx0", "server", "tx0");
+  connect("self", "cs", "server", "cs");
+
+  // initialize NCO
+  double freq = 100e3;
+  int interp = 32;                         // 32 -> 4MS/s
+  double sample_rate = 128e6 / interp; 
+  d_nco.set_freq(2*M_PI * freq/sample_rate);
+
+  // FIXME need to somehow set the interp rate in the USRP.
+  // for now, we'll have the low-level code hardwire it.
+}
+
+test_usrp_tx::~test_usrp_tx()
+{
+}
+
+void
+test_usrp_tx::initial_transition()
+{
+  open_usrp();
+}
+
+void
+test_usrp_tx::handle_message(mb_message_sptr msg)
+{
+  pmt_t        event = msg->signal();
+  pmt_t data = msg->data();
+
+  pmt_t handle = PMT_F;
+  pmt_t status = PMT_F;
+  std::string error_msg;
+  
+  //std::cout << msg << std::endl;
+
+  switch(d_state){
+  case OPENING_USRP:
+    if (pmt_eq(event, s_response_open)){
+      status = pmt_nth(1, data);
+      if (pmt_eq(status, PMT_T)){
+        allocate_channel();
+        return;
+      }
+      else {
+        error_msg = "failed to open usrp:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+    
+  case ALLOCATING_CHANNEL:
+    if (pmt_eq(event, s_response_allocate_channel)){
+      status = pmt_nth(1, data);
+      d_tx_chan = pmt_nth(2, data);
+
+      if (pmt_eq(status, PMT_T)){
+        enter_transmitting();
+        return;
+      }
+      else {
+        error_msg = "failed to allocate channel:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+
+  case TRANSMITTING:
+    if (pmt_eq(event, s_response_xmit_raw_frame)){
+      handle = pmt_nth(0, data);
+      status = pmt_nth(1, data);
+
+      if (pmt_eq(status, PMT_T)){
+        handle_xmit_response(handle);
+        return;
+      }
+      else {
+        error_msg = "bad response-xmit-raw-frame:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+
+  case CLOSING_CHANNEL:
+    if (pmt_eq(event, s_response_deallocate_channel)){
+      status = pmt_nth(1, data);
+
+      if (pmt_eq(status, PMT_T)){
+        close_usrp();
+        return;
+      }
+      else {
+        error_msg = "failed to deallocate channel:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+
+  case CLOSING_USRP:
+    if (pmt_eq(event, s_response_close)){
+      status = pmt_nth(1, data);
+
+      if (pmt_eq(status, PMT_T)){
+        shutdown_all(PMT_T);
+        return;
+      }
+      else {
+        error_msg = "failed to close USRP:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+
+  default:
+    goto unhandled;
+  }
+  return;
+
+ bail:
+  std::cerr << error_msg << data
+           << "status = " << status << std::endl;
+  shutdown_all(PMT_F);
+  return;
+
+ unhandled:
+  std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
+           << "in state "<< d_state << std::endl;
+}
+
+
+void
+test_usrp_tx::open_usrp()
+{
+  pmt_t which_usrp = pmt_from_long(0);
+
+  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
+  d_state = OPENING_USRP;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_TX] Opening the USRP\n";
+}
+
+void
+test_usrp_tx::close_usrp()
+{
+  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
+  d_state = CLOSING_USRP;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_TX] Closing the USRP\n";
+}
+
+void
+test_usrp_tx::allocate_channel()
+{
+  long capacity = (long) 16e6;
+  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
+  d_state = ALLOCATING_CHANNEL;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_TX] Requesting TX channel allocation\n";
+}
+
+void
+test_usrp_tx::enter_transmitting()
+{
+  d_state = TRANSMITTING;
+  d_nsamples_xmitted = 0;
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_TX] Transmitting...\n";
+  
+  build_and_send_next_frame(); // fire off 4 to start pipeline
+  build_and_send_next_frame();
+  build_and_send_next_frame();
+  build_and_send_next_frame();
+}
+
+void
+test_usrp_tx::build_and_send_next_frame()
+{
+  // allocate the uniform vector for the samples
+  // FIXME perhaps hold on to this between calls
+
+#if 1
+  long nsamples_this_frame =
+    std::min(d_nsamples_to_send - d_nsamples_xmitted,
+            d_samples_per_frame);
+#else
+  long nsamples_this_frame = d_samples_per_frame;
+#endif
+
+  if (nsamples_this_frame == 0){
+    d_done_sending = true;
+    return;
+  }
+    
+
+  size_t nshorts = 2 * nsamples_this_frame;    // 16-bit I & Q
+  pmt_t uvec = pmt_make_s16vector(nshorts, 0);
+  size_t ignore;
+  int16_t *samples = pmt_s16vector_writable_elements(uvec, ignore);
+
+  // fill in the complex sinusoid
+
+  for (int i = 0; i < nsamples_this_frame; i++){
+
+    if (1){
+      gr_complex s;
+      d_nco.sincos(&s, 1, d_amplitude);
+      // write 16-bit i & q
+      samples[2*i] =   (int16_t) s.real();
+      samples[2*i+1] = (int16_t) s.imag();
+    }
+    else {
+      gr_complex s(d_amplitude, d_amplitude);
+
+      // write 16-bit i & q
+      samples[2*i] =   (int16_t) s.real();
+      samples[2*i+1] = (int16_t) s.imag();
+    }
+  }
+
+  pmt_t tx_properties = pmt_make_dict();
+
+  pmt_t timestamp = pmt_from_long(0xffffffff); // NOW
+  d_tx->send(s_cmd_xmit_raw_frame,
+            pmt_list5(pmt_from_long(d_nframes_xmitted),  // invocation-handle
+                      d_tx_chan,                         // channel
+                      uvec,                              // the samples
+                      timestamp,
+           tx_properties));
+
+  d_nsamples_xmitted += nsamples_this_frame;
+  d_nframes_xmitted++;
+
+  if(verbose && 0)
+    std::cout << "[TEST_USRP_INBAND_TX] Transmitted frame\n";
+}
+
+
+void
+test_usrp_tx::handle_xmit_response(pmt_t handle)
+{
+  if (d_done_sending &&
+      pmt_to_long(handle) == (d_nframes_xmitted - 1)){
+    // We're done sending and have received all responses
+    enter_closing_channel();
+  }
+
+  build_and_send_next_frame();
+}
+
+void
+test_usrp_tx::enter_closing_channel()
+{
+  d_state = CLOSING_CHANNEL;
+  
+  d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan));
+  
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_tX] Deallocating TX channel\n";
+}
+
+REGISTER_MBLOCK_CLASS(test_usrp_tx);
+
+
+// ----------------------------------------------------------------
+
+int
+main (int argc, char **argv)
+{
+  // handle any command line args here
+
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_NIL;
+
+  rt->run("top", "test_usrp_tx", PMT_F, &result);
+}
diff --git a/usrp/limbo/apps-inband/test_usrp_inband_underrun.cc b/usrp/limbo/apps-inband/test_usrp_inband_underrun.cc
new file mode 100644 (file)
index 0000000..11babb0
--- /dev/null
@@ -0,0 +1,674 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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 <mblock/mblock.h>
+#include <mblock/runtime.h>
+#include <mblock/protocol_class.h>
+#include <mblock/exception.h>
+#include <mblock/msg_queue.h>
+#include <mblock/message.h>
+#include <mblock/msg_accepter.h>
+#include <mblock/class_registry.h>
+#include <pmt.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <iostream>
+#include <ui_nco.h>
+
+// Include the symbols needed for communication with USRP server
+#include <symbols_usrp_server_cs.h>
+#include <symbols_usrp_channel.h>
+#include <symbols_usrp_low_level_cs.h>
+#include <symbols_usrp_tx.h>
+#include <symbols_usrp_rx.h>
+
+static bool verbose = true;
+
+class test_usrp_inband_underrun : public mb_mblock
+{
+
+  mb_port_sptr  d_tx;   // Ports connected to the USRP server
+  mb_port_sptr  d_rx;
+  mb_port_sptr  d_cs;
+
+  pmt_t   d_tx_chan;    // Returned channel from TX allocation
+  pmt_t   d_rx_chan;    // Returned channel from RX allocation
+
+  pmt_t   d_which_usrp; // The USRP to use for the test
+
+  long    d_warm_msgs;  // The number of messages to 'warm' the USRP
+  long    d_warm_recvd; // The number of msgs received in the 'warm' state
+
+  // Keep track of current state
+  enum state_t {
+    INIT,
+    OPENING_USRP,
+    ALLOCATING_CHANNELS,
+    WRITE_REGISTER,
+    READ_REGISTER,
+    TRANSMITTING,
+    CLOSING_CHANNELS,
+    CLOSING_USRP,
+  };
+  state_t d_state;
+  
+  long         d_nsamples_to_send;
+  long         d_nsamples_xmitted;
+  long         d_nframes_xmitted;
+  long         d_samples_per_frame;
+  bool         d_done_sending;
+
+  // for generating sine wave output
+  ui_nco<float,float>  d_nco;
+  double               d_amplitude;
+
+  long d_n_underruns;
+
+ public:
+  test_usrp_inband_underrun(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~test_usrp_inband_underrun();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void opening_usrp();
+  void allocating_channels();
+  void write_register();
+  void read_register();
+  void closing_channels();
+  void closing_usrp();
+  void enter_receiving();
+  void enter_transmitting();
+  void build_and_send_ping();
+  void build_and_send_next_frame();
+  void handle_xmit_response(pmt_t handle);
+  void handle_recv_response(pmt_t dict);
+};
+
+
+int
+main (int argc, char **argv)
+{
+  // handle any command line args here
+
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_NIL;
+
+  rt->run("top", "test_usrp_inband_underrun", PMT_F, &result);
+}
+
+
+test_usrp_inband_underrun::test_usrp_inband_underrun(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg),
+  d_tx_chan(PMT_NIL),
+  d_rx_chan(PMT_NIL),
+  d_which_usrp(pmt_from_long(0)),
+  d_state(INIT),
+  d_nsamples_to_send((long) 27e6),
+  d_nsamples_xmitted(0),
+  d_nframes_xmitted(0),
+  d_samples_per_frame(d_nsamples_to_send),     // full packet
+
+  d_done_sending(false),
+  d_amplitude(16384),
+  d_n_underruns(0)
+{
+  
+  // A dictionary is used to pass parameters to the USRP
+  pmt_t usrp_dict = pmt_make_dict();
+
+  // Specify the RBF to use
+  pmt_dict_set(usrp_dict,
+               pmt_intern("rbf"),
+               pmt_intern("inband_1rxhb_1tx.rbf"));
+
+  // Set TX and RX interpolations
+  pmt_dict_set(usrp_dict,
+               pmt_intern("interp-tx"),
+               pmt_from_long(64));
+
+  pmt_dict_set(usrp_dict,
+               pmt_intern("decim-rx"),
+               pmt_from_long(128));
+  
+  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+
+  // Create an instance of USRP server and connect ports
+  define_component("server", "usrp_server", usrp_dict);
+  connect("self", "tx0", "server", "tx0");
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+
+  // initialize NCO
+  double freq = 100e3;
+  int interp = 32;                         // 32 -> 4MS/s
+  double sample_rate = 128e6 / interp; 
+  d_nco.set_freq(2*M_PI * freq/sample_rate);
+}
+
+test_usrp_inband_underrun::~test_usrp_inband_underrun()
+{
+}
+
+void
+test_usrp_inband_underrun::initial_transition()
+{
+  opening_usrp();
+}
+
+// Handle message reads all incoming messages from USRP server which will be
+// initialization and ping responses.  We perform actions based on the current
+// state and the event (ie, ping response)
+void
+test_usrp_inband_underrun::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();
+  pmt_t data = msg->data();
+  pmt_t port_id = msg->port_id();
+
+  pmt_t handle = PMT_F;
+  pmt_t status = PMT_F;
+  pmt_t dict = PMT_NIL;
+  std::string error_msg;
+      
+  // Check the recv sample responses for underruns and count
+  if(pmt_eq(event, s_response_recv_raw_samples)) {
+    handle = pmt_nth(0, data);
+    status = pmt_nth(1, data);
+    dict   = pmt_nth(4, data);
+
+    if(pmt_eq(status, PMT_T)) {
+      handle_recv_response(dict);
+      return;
+    }
+    else {
+      error_msg = "error while receiving samples:";
+      goto bail;
+    }
+  }
+
+
+  // Dispatch based on state
+  switch(d_state) {
+
+    //----------------------------- OPENING_USRP ----------------------------//
+    // We only expect a response from opening the USRP which should be succesful
+    // or failed.
+    case OPENING_USRP:
+      
+      if(pmt_eq(event, s_response_open)) {
+
+        status = pmt_nth(1, data);          // failed/succes
+        
+        if(pmt_eq(status, PMT_T)) {
+          allocating_channels();
+          return;
+        }
+        else {
+          error_msg = "failed to open usrp:";
+          goto bail;
+        }
+
+      }
+
+      goto unhandled;   // all other messages not handled in this state
+      
+    
+    //----------------------- ALLOCATING CHANNELS --------------------//
+    // When allocating channels, we need to wait for 2 responses from
+    // USRP server: one for TX and one for RX.  Both are initialized to
+    // NIL so we know to continue to the next state once both are set.
+    case ALLOCATING_CHANNELS:
+
+      // A TX allocation response
+      if(pmt_eq(event, s_response_allocate_channel)
+          && pmt_eq(d_tx->port_symbol(), port_id)) 
+      {
+        status = pmt_nth(1, data);
+        
+        // If successful response, extract the channel
+        if(pmt_eq(status, PMT_T)) {
+          
+          d_tx_chan = pmt_nth(2, data);
+
+          if(verbose)
+            std::cout << "[TEST_USRP_INBAND_UNDERRUN] Received TX allocation"
+                      << " on channel " << d_tx_chan << std::endl;
+
+          // If the RX has also been allocated already, we can continue
+          if(!pmt_eqv(d_rx_chan, PMT_NIL)) {
+            enter_receiving();
+            enter_transmitting();
+          }
+
+          return;
+        }
+        else {  // TX allocation failed
+          error_msg = "failed to allocate TX channel:";
+          goto bail;
+        }
+      }
+      
+      // A RX allocation response
+      if(pmt_eq(event, s_response_allocate_channel)
+          && pmt_eq(d_rx->port_symbol(), port_id)) 
+      {
+        status = pmt_nth(1, data);
+        
+        // If successful response, extract the channel
+        if(pmt_eq(status, PMT_T)) {
+          
+          d_rx_chan = pmt_nth(2, data);
+
+          if(verbose)
+            std::cout << "[TEST_USRP_INBAND_UNDERRUN] Received RX allocation"
+                      << " on channel " << d_rx_chan << std::endl;
+
+          // If the TX has also been allocated already, we can continue
+          if(!pmt_eqv(d_tx_chan, PMT_NIL)) {
+            enter_receiving();
+            enter_transmitting();
+          }
+
+          return;
+        }
+        else {  // RX allocation failed
+          error_msg = "failed to allocate RX channel:";
+          goto bail;
+        }
+      }
+
+      goto unhandled;
+
+    case WRITE_REGISTER:
+      goto unhandled;
+
+    case READ_REGISTER:
+      goto unhandled;
+
+    //-------------------------- TRANSMITTING ----------------------------//
+    // In the transmit state we count the number of underruns received and
+    // ballpark the number with an expected count (something >1 for starters)
+    case TRANSMITTING:
+      
+      // Check that the transmits are OK
+      if (pmt_eq(event, s_response_xmit_raw_frame)){
+        handle = pmt_nth(0, data);
+        status = pmt_nth(1, data);
+
+        if (pmt_eq(status, PMT_T)){
+          handle_xmit_response(handle);
+          return;
+        }
+        else {
+          error_msg = "bad response-xmit-raw-frame:";
+          goto bail;
+        }
+      }
+
+      goto unhandled;
+
+    //------------------------- CLOSING CHANNELS ----------------------------//
+    // Check deallocation responses, once the TX and RX channels are both
+    // deallocated then we close the USRP.
+    case CLOSING_CHANNELS:
+      
+      if (pmt_eq(event, s_response_deallocate_channel)
+          && pmt_eq(d_tx->port_symbol(), port_id))
+      {
+        status = pmt_nth(1, data);
+
+        // If successful, set the port to NIL
+        if(pmt_eq(status, PMT_T)) {
+          d_tx_chan = PMT_NIL;
+
+          if(verbose)
+            std::cout << "[TEST_USRP_INBAND_UNDERRUN] Received TX deallocation\n";
+
+          // If the RX is also deallocated, we can close the USRP
+          if(pmt_eq(d_rx_chan, PMT_NIL)) 
+            closing_usrp();
+
+          return;
+
+        } else {
+
+          error_msg = "failed to deallocate TX channel:";
+          goto bail;
+
+        }
+      }
+
+      if (pmt_eq(event, s_response_deallocate_channel)
+          && pmt_eq(d_rx->port_symbol(), port_id))
+      {
+        status = pmt_nth(1, data);
+
+        // If successful, set the port to NIL
+        if(pmt_eq(status, PMT_T)) {
+          d_rx_chan = PMT_NIL;
+
+          if(verbose)
+            std::cout << "[TEST_USRP_INBAND_UNDERRUN] Received RX deallocation\n";
+
+          // If the TX is also deallocated, we can close the USRP
+          if(pmt_eq(d_tx_chan, PMT_NIL)) 
+            closing_usrp();
+
+          return;
+
+        } else {
+          
+          error_msg = "failed to deallocate RX channel:";
+          goto bail;
+
+        }
+      }
+
+      goto unhandled;
+
+    //--------------------------- CLOSING USRP ------------------------------//
+    // Once we have received a successful USRP close response, we shutdown all
+    // mblocks and exit.
+    case CLOSING_USRP:
+      
+      if (pmt_eq(event, s_response_close)) {
+        
+        status = pmt_nth(1, data);
+
+        if(pmt_eq(status, PMT_T)) {
+
+          if(verbose)
+            std::cout << "[TEST_USRP_INBAND_UNDERRUN] Successfully closed USRP\n";
+
+          std::cout << "\nUnderruns: " << d_n_underruns << std::endl;
+          fflush(stdout);
+
+          shutdown_all(PMT_T);
+          return;
+
+        } else {
+
+          error_msg = "failed to close USRP:";
+          goto bail;
+        }
+      }
+
+      goto unhandled;
+
+    case INIT:
+      goto unhandled;
+
+  }
+ // An error occured, print it, and shutdown all m-blocks
+ bail:
+  std::cerr << error_msg << data
+           << "status = " << status << std::endl;
+  shutdown_all(PMT_F);
+  return;
+
+ // Received an unhandled message for a specific state
+ unhandled:
+  if(verbose && !pmt_eq(event, pmt_intern("%shutdown")))
+    std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
+              << "in state "<< d_state << std::endl;
+
+}
+
+
+// Sends a command to USRP server to open up a connection to the
+// specified USRP, which is defaulted to USRP 0 on the system
+void
+test_usrp_inband_underrun::opening_usrp()
+{
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_UNDERRUN] Opening USRP " 
+              << d_which_usrp << std::endl;
+
+  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, d_which_usrp));
+  d_state = OPENING_USRP;
+}
+
+// RX and TX channels must be allocated so that the USRP server can
+// properly share bandwidth across multiple USRPs.  No commands will be
+// successful to the USRP through the USRP server on the TX or RX channels until
+// a bandwidth allocation has been received.
+void
+test_usrp_inband_underrun::allocating_channels()
+{
+  d_state = ALLOCATING_CHANNELS;
+
+  long capacity = (long) 16e6;
+  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
+  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
+}
+
+// After allocating the channels, a write register command will be sent to the
+// USRP.
+void
+test_usrp_inband_underrun::write_register()
+{
+  d_state = WRITE_REGISTER;
+
+  long reg = 0;
+
+  d_tx->send(s_cmd_to_control_channel,    // C/S packet
+             pmt_list2(PMT_NIL,           // invoc handle
+                       pmt_list1(
+                            pmt_list2(s_op_write_reg, 
+                                      pmt_list2(
+                                      pmt_from_long(reg), 
+                                      pmt_from_long(0xbeef))))));
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_REGISTERS] Writing 0xbeef to " 
+              << reg << std::endl;
+
+  read_register();  // immediately transition to read the register
+}
+
+// Temporary: for testing pings
+void
+test_usrp_inband_underrun::build_and_send_ping()
+{
+  
+  d_tx->send(s_cmd_to_control_channel,
+             pmt_list2(PMT_NIL, pmt_list1(pmt_list2(s_op_ping_fixed,
+                                                    pmt_list2(pmt_from_long(0),
+                                                              pmt_from_long(0))))));
+
+  std::cout << "[TEST_USRP_INBAND_UNDERRUN] Ping sent" << std::endl;
+}
+
+// After writing to the register, we want to read the value back and ensure that
+// it is the same value that we wrote.
+void
+test_usrp_inband_underrun::read_register()
+{
+  d_state = READ_REGISTER;
+
+  long reg = 9;
+
+  d_tx->send(s_cmd_to_control_channel,    // C/S packet
+             pmt_list2(PMT_NIL,           // invoc handle
+                       pmt_list1(
+                            pmt_list2(s_op_read_reg, 
+                                      pmt_list2(
+                                      pmt_from_long(0),   // rid 
+                                      pmt_from_long(reg))))));
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_UNDERRUN] Reading from register " 
+              << reg << std::endl;
+}
+
+// Used to enter the receiving state
+void
+test_usrp_inband_underrun::enter_receiving()
+{
+  d_rx->send(s_cmd_start_recv_raw_samples,
+             pmt_list2(PMT_F,
+                       d_rx_chan));
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_UNDERRUN] Started RX sample stream\n";
+}
+
+void
+test_usrp_inband_underrun::enter_transmitting()
+{
+  d_state = TRANSMITTING;
+  d_nsamples_xmitted = 0;
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_UNDERRUN] Entering transmit state...\n";
+  
+  build_and_send_next_frame(); // fire off 4 to start pipeline
+  build_and_send_next_frame();
+  build_and_send_next_frame();
+  build_and_send_next_frame();
+}
+
+void
+test_usrp_inband_underrun::build_and_send_next_frame()
+{
+
+  long nsamples_this_frame =
+    std::min(d_nsamples_to_send - d_nsamples_xmitted,
+            d_samples_per_frame);
+
+  if (nsamples_this_frame == 0){
+    d_done_sending = true;
+    return;
+  }
+    
+  size_t nshorts = 2 * nsamples_this_frame;    // 16-bit I & Q
+  pmt_t uvec = pmt_make_s16vector(nshorts, 0);
+  size_t ignore;
+  int16_t *samples = pmt_s16vector_writable_elements(uvec, ignore);
+
+  // fill in the complex sinusoid
+
+  for (int i = 0; i < nsamples_this_frame; i++){
+
+    if (1){
+      gr_complex s;
+      d_nco.sincos(&s, 1, d_amplitude);
+      // write 16-bit i & q
+      samples[2*i] =   (int16_t) s.real();
+      samples[2*i+1] = (int16_t) s.imag();
+    }
+    else {
+      gr_complex s(d_amplitude, d_amplitude);
+
+      // write 16-bit i & q
+      samples[2*i] =   (int16_t) s.real();
+      samples[2*i+1] = (int16_t) s.imag();
+    }
+  }
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_TX] Transmitting frame...\n";
+
+  pmt_t timestamp = pmt_from_long(0xffffffff); // NOW
+  d_tx->send(s_cmd_xmit_raw_frame,
+            pmt_list4(pmt_from_long(d_nframes_xmitted),  // invocation-handle
+                      d_tx_chan,                         // channel
+                      uvec,                              // the samples
+                      timestamp));
+
+  d_nsamples_xmitted += nsamples_this_frame;
+  d_nframes_xmitted++;
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_TX] Transmitted frame\n";
+
+}
+
+void
+test_usrp_inband_underrun::handle_xmit_response(pmt_t handle)
+{
+  if (d_done_sending &&
+    pmt_to_long(handle) == (d_nframes_xmitted - 1)){
+    // We're done sending and have received all responses
+    closing_channels();
+    return;
+  }
+
+  build_and_send_next_frame();
+}
+
+void
+test_usrp_inband_underrun::handle_recv_response(pmt_t dict)
+{
+  if(!pmt_is_dict(dict)) {
+    std::cout << "[TEST_USRP_INBAND_UNDERRUN] Recv samples dictionary is improper\n";
+    return;
+  }
+
+  // Read the TX interpolations
+  if(pmt_t underrun = pmt_dict_ref(dict, 
+                                  pmt_intern("underrun"), 
+                                  PMT_NIL)) {
+    if(pmt_eqv(underrun, PMT_T)) {
+      d_n_underruns++;
+
+      if(verbose && 0)
+        std::cout << "[TEST_USRP_INBAND_UNDERRUN] Underrun\n";
+    }
+    else {
+    if(verbose && 0)
+      std::cout << "[TEST_USRP_INBAND_UNDERRUN] No underrun\n" << underrun <<std::endl;
+    }
+  } else {
+
+    if(verbose && 0)
+      std::cout << "[TEST_USRP_INBAND_UNDERRUN] No underrun\n";
+  }
+  
+}
+
+void
+test_usrp_inband_underrun::closing_channels()
+{
+  d_state = CLOSING_CHANNELS;
+
+  d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan));
+  d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan));
+}
+
+void
+test_usrp_inband_underrun::closing_usrp()
+{
+  d_state = CLOSING_USRP;
+
+  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
+}
+
+REGISTER_MBLOCK_CLASS(test_usrp_inband_underrun);
diff --git a/usrp/limbo/apps-inband/ui_nco.h b/usrp/limbo/apps-inband/ui_nco.h
new file mode 100644 (file)
index 0000000..e6d7814
--- /dev/null
@@ -0,0 +1,202 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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_UI_NCO_H
+#define INCLUDED_UI_NCO_H
+
+
+#include <vector>
+#include <ui_sincos.h>
+#include <cmath>
+
+#include <complex>
+typedef std::complex<float>                    gr_complex;
+
+
+/*!
+ * \brief base class template for Numerically Controlled Oscillator (NCO)
+ */
+
+
+//FIXME  Eventually generalize this to fixed point
+
+template<class o_type, class i_type> 
+class ui_nco {
+public:
+  ui_nco () : phase (0), phase_inc(0) {}
+
+  virtual ~ui_nco () {}
+
+  // radians
+  void set_phase (double angle) {
+    phase = angle;
+  }
+
+  void adjust_phase (double delta_phase) {
+    phase += delta_phase;
+  }
+
+
+  // angle_rate is in radians / step
+  void set_freq (double angle_rate){
+    phase_inc = angle_rate;
+  }
+
+  // angle_rate is a delta in radians / step
+  void adjust_freq (double delta_angle_rate)
+  {
+    phase_inc += delta_angle_rate;
+  }
+
+  // increment current phase angle
+
+  void step () 
+  { 
+    phase += phase_inc; 
+    if (fabs (phase) > M_PI){
+      
+      while (phase > M_PI)
+       phase -= 2*M_PI;
+
+      while (phase < -M_PI)
+       phase += 2*M_PI;
+    }
+  }
+
+  void step (int n)
+  {
+    phase += phase_inc * n;
+    if (fabs (phase) > M_PI){
+      
+      while (phase > M_PI)
+       phase -= 2*M_PI;
+
+      while (phase < -M_PI)
+       phase += 2*M_PI;
+    }
+  }
+
+  // units are radians / step
+  double get_phase () const { return phase; }
+  double get_freq () const { return phase_inc; }
+
+  // compute sin and cos for current phase angle
+  void sincos (float *sinx, float *cosx) const;
+
+  // compute cos or sin for current phase angle
+  float cos () const { return std::cos (phase); }
+  float sin () const { return std::sin (phase); }
+
+  // compute a block at a time
+  void sin (float *output, int noutput_items, double ampl = 1.0);
+  void cos (float *output, int noutput_items, double ampl = 1.0);
+  void sincos (gr_complex *output, int noutput_items, double ampl = 1.0);
+  void sin (short *output, int noutput_items, double ampl = 1.0);
+  void cos (short *output, int noutput_items, double ampl = 1.0);
+  void sin (int *output, int noutput_items, double ampl = 1.0);
+  void cos (int *output, int noutput_items, double ampl = 1.0);
+
+protected:
+  double phase;
+  double phase_inc;
+};
+
+template<class o_type, class i_type> 
+void
+ui_nco<o_type,i_type>::sincos (float *sinx, float *cosx) const
+{
+  ui_sincosf (phase, sinx, cosx);
+}
+
+template<class o_type, class i_type> 
+void
+ui_nco<o_type,i_type>::sin (float *output, int noutput_items, double ampl)
+{
+  for (int i = 0; i < noutput_items; i++){
+    output[i] = (float)(sin () * ampl);
+    step ();
+  }
+}
+
+template<class o_type, class i_type> 
+void
+ui_nco<o_type,i_type>::cos (float *output, int noutput_items, double ampl)
+{
+  for (int i = 0; i < noutput_items; i++){
+    output[i] = (float)(cos () * ampl);
+    step ();
+  }
+}
+
+template<class o_type, class i_type> 
+void
+ui_nco<o_type,i_type>::sin (short *output, int noutput_items, double ampl)
+{
+  for (int i = 0; i < noutput_items; i++){
+    output[i] = (short)(sin() * ampl);
+    step ();
+  }
+}
+
+template<class o_type, class i_type> 
+void
+ui_nco<o_type,i_type>::cos (short *output, int noutput_items, double ampl)
+{
+  for (int i = 0; i < noutput_items; i++){
+    output[i] = (short)(cos () * ampl);
+    step ();
+  }
+}
+
+template<class o_type, class i_type> 
+void
+ui_nco<o_type,i_type>::sin (int *output, int noutput_items, double ampl)
+{
+  for (int i = 0; i < noutput_items; i++){
+    output[i] = (int)(sin () * ampl);
+    step ();
+  }
+}
+
+template<class o_type, class i_type> 
+void
+ui_nco<o_type,i_type>::cos (int *output, int noutput_items, double ampl)
+{
+  for (int i = 0; i < noutput_items; i++){
+    output[i] = (int)(cos () * ampl);
+    step ();
+  }
+}
+
+template<class o_type, class i_type> 
+void
+ui_nco<o_type,i_type>::sincos (gr_complex *output, int noutput_items, double ampl)
+{
+  for (int i = 0; i < noutput_items; i++){
+    float cosx, sinx;
+    sincos (&sinx, &cosx);
+    output[i] = gr_complex(cosx * ampl, sinx * ampl);
+    step ();
+  }
+}
+
+#endif /* INCLUDED_UI_NCO_H */
+
diff --git a/usrp/limbo/apps-inband/ui_sincos.c b/usrp/limbo/apps-inband/ui_sincos.c
new file mode 100644 (file)
index 0000000..27841f0
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- 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
+
+#define _GNU_SOURCE            // ask for GNU extensions if available
+
+#include "ui_sincos.h"
+#include <math.h>
+
+// ----------------------------------------------------------------
+
+#if defined (HAVE_SINCOS)
+
+void
+ui_sincos (double x, double *sinx, double *cosx)
+{
+  sincos (x, sinx, cosx);
+}
+
+#else
+
+void
+ui_sincos (double x, double *sinx, double *cosx)
+{
+  *sinx = sin (x);
+  *cosx = cos (x);
+}
+
+#endif
+
+// ----------------------------------------------------------------
+
+#if defined (HAVE_SINCOSF)
+
+void
+ui_sincosf (float x, float *sinx, float *cosx)
+{
+  sincosf (x, sinx, cosx);
+}
+
+#elif defined (HAVE_SINF) && defined (HAVE_COSF)
+
+void
+ui_sincosf (float x, float *sinx, float *cosx)
+{
+  *sinx = sinf (x);
+  *cosx = cosf (x);
+}
+
+#else
+
+void
+ui_sincosf (float x, float *sinx, float *cosx)
+{
+  *sinx = sin (x);
+  *cosx = cos (x);
+}
+
+#endif
diff --git a/usrp/limbo/apps-inband/ui_sincos.h b/usrp/limbo/apps-inband/ui_sincos.h
new file mode 100644 (file)
index 0000000..d2d6e4b
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,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.
+ */
+
+#ifndef INCLUDED_UI_SINCOS_H
+#define INCLUDED_UI_SINCOS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  
+// compute sine and cosine at the same time
+
+void ui_sincos (double x, double *sin, double *cos);
+void ui_sincosf (float x, float *sin, float *cos);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* INCLUDED_UI_SINCOS_H */
diff --git a/usrp/limbo/inband/Makefile.am b/usrp/limbo/inband/Makefile.am
new file mode 100644 (file)
index 0000000..650a25f
--- /dev/null
@@ -0,0 +1,114 @@
+#
+# Copyright 2007,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.
+#
+
+include $(top_srcdir)/Makefile.common
+
+AM_CPPFLAGS =  \
+       $(DEFINES) $(OMNITHREAD_INCLUDES) $(PMT_INCLUDES) $(MBLOCK_INCLUDES) \
+       $(USRP_INCLUDES) $(BOOST_CPPFLAGS) $(CPPUNIT_INCLUDES) \
+       -I$(srcdir)/../../apps-inband $(WITH_INCLUDES)
+
+TESTS = test_inband
+
+EXTRA_DIST =                           \
+       usrp_server.mbh                 \
+       usrp_interface.mbh 
+
+lib_LTLIBRARIES =                      \
+       libusrp-inband.la               \
+       libusrp-inband-qa.la
+
+# ------------------------------------------------------------------------
+# Build the inband library
+
+BUILT_SOURCES =                                \
+       usrp_server_mbh.cc              \
+       usrp_interface_mbh.cc 
+
+usrp_server_mbh.cc : usrp_server.mbh
+       $(COMPILE_MBH) $(srcdir)/usrp_server.mbh usrp_server_mbh.cc
+
+usrp_interface_mbh.cc : usrp_interface.mbh
+       $(COMPILE_MBH) $(srcdir)/usrp_interface.mbh usrp_interface_mbh.cc
+
+libusrp_inband_la_SOURCES =            \
+       $(BUILT_SOURCES)                \
+       $(srcdir)/../../apps-inband/ui_sincos.c \
+       usrp_inband_usb_packet.cc       \
+       usrp_rx.cc                      \
+       usrp_rx_stub.cc                 \
+       usrp_server.cc                  \
+       usrp_tx.cc                      \
+       usrp_tx_stub.cc                 \
+       usrp_usb_interface.cc           
+
+libusrp_inband_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
+
+libusrp_inband_la_LIBADD =             \
+       $(MBLOCK_LA)                    \
+       $(USRP_LA)                      \
+       -lstdc++
+
+include_HEADERS =                      \
+       usrp_inband_usb_packet.h        \
+       usrp_rx.h                       \
+       usrp_rx_stub.h                  \
+       usrp_server.h                   \
+       usrp_tx.h                       \
+       usrp_tx_stub.h                  \
+       usrp_usb_interface.h
+
+noinst_HEADERS =                       \
+       qa_inband.h                     \
+       qa_inband_packet_prims.h        \
+       qa_inband_usrp_server.h         \
+       symbols_usrp_channel.h          \
+       symbols_usrp_interface_cs.h     \
+       symbols_usrp_low_level_cs.h     \
+       symbols_usrp_rx.h               \
+       symbols_usrp_rx_cs.h            \
+       symbols_usrp_server_cs.h        \
+       symbols_usrp_tx.h               \
+       symbols_usrp_tx_cs.h
+
+# ------------------------------------------------------------------------
+# Build the qa code in its own library
+
+libusrp_inband_qa_la_SOURCES =         \
+       qa_inband.cc                    \
+       qa_inband_packet_prims.cc       \
+       qa_inband_usrp_server.cc
+
+# magic flags
+libusrp_inband_qa_la_LDFLAGS = $(NO_UNDEFINED) -avoid-version
+
+libusrp_inband_qa_la_LIBADD =          \
+       libusrp-inband.la               \
+       $(PMT_LA)                       \
+       $(CPPUNIT_LIBS)                 \
+       -lstdc++
+
+# ------------------------------------------------------------------------
+
+noinst_PROGRAMS =                      \
+       test_inband
+
+test_inband_SOURCES = test_inband.cc
+test_inband_LDADD   = libusrp-inband-qa.la
diff --git a/usrp/limbo/inband/dump_packets.py b/usrp/limbo/inband/dump_packets.py
new file mode 100755 (executable)
index 0000000..2373624
--- /dev/null
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+#
+# 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 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.
+#
+
+import sys
+import struct
+from optparse import OptionParser
+
+from usb_packet import *
+
+def dump_packet(raw_pkt, outfile, dump_payload):
+    pkt = usb_packet(raw_pkt)
+    outfile.write(pkt.decoded_flags())
+    outfile.write(' chan= %2d  len= %3d timestamp= 0x%08x rssi= % 2d  tag= %2d\n' % (
+        pkt.chan(), pkt.payload_len(), pkt.timestamp(), pkt.rssi(), pkt.tag()))
+    if dump_payload:
+        assert pkt.payload_len() % 4 == 0
+        shorts = struct.unpack('<%dh' % (pkt.payload_len() // 2), pkt.payload())
+        for i in range(0, len(shorts), 2):
+            outfile.write('  %6d, %6d\n' % (shorts[i], shorts[i+1]))
+        
+
+def dump_packets(infile, outfile, dump_payload):
+    raw_pkt = infile.read(512)
+    while raw_pkt:
+        if len(raw_pkt) != 512:
+            sys.stderr.write("File length is not a multiple of 512 bytes")
+            raise SystemExit, 1
+
+        dump_packet(raw_pkt, outfile, dump_payload)
+        raw_pkt = infile.read(512)
+
+
+def main():
+    parser = OptionParser()
+    parser.add_option('-p', '--dump-payload', action='store_true', default=False,
+                      help='dump payload in decimal and hex')
+
+    (options, files) = parser.parse_args()
+    if len(files) == 0:
+        dump_packets(sys.stdin, sys.stdout, options.dump_payload)
+    else:
+        for f in files:
+            dump_packets(open(f, "r"), sys.stdout, options.dump_payload)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/usrp/limbo/inband/gen_test_packets.py b/usrp/limbo/inband/gen_test_packets.py
new file mode 100755 (executable)
index 0000000..2ee6463
--- /dev/null
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+
+import random
+import struct
+from pprint import pprint
+from usb_packet import *
+
+MAX_PAYLOAD = 504
+TIME_NOW = 0xffffffff
+
+
+class sequence_generator(object):
+    def __init__(self):
+        self.i = 0
+    
+    def __call__(self):
+        t = self.i
+        self.i += 1
+        return t
+
+def gen_shuffled_lengths():
+    valid_lengths = range(0, MAX_PAYLOAD+1, 4)  # [0, 4, 8, ... 504]
+    random.shuffle(valid_lengths)
+    return valid_lengths
+
+
+class packet_sequence_generator(object):
+    def __init__(self, channel, lengths):
+        self.next = sequence_generator()
+        self.channel = channel
+        self.lengths = lengths
+
+    def __call__(self, output_file):
+        gen_packet(output_file, self.channel, self.next, self.lengths[0])
+        del self.lengths[0]
+
+
+def gen_packet(output_file, channel, content_generator, payload_len):
+    assert (payload_len % 4) == 0
+    payload = []
+    n_iq = payload_len // 4
+    for n in range(n_iq):
+        payload.append(content_generator())  # I
+        payload.append(content_generator())  # Q
+    for n in range(MAX_PAYLOAD // 4 - n_iq):
+        payload.append(0x0000)
+        payload.append(0xffff)
+
+    assert (len(payload) == MAX_PAYLOAD // 2)
+
+    #print "\npayload_len =", payload_len
+    #pprint(payload)
+
+    output_file.write(make_header(FL_START_OF_BURST|FL_END_OF_BURST,
+                                  channel, payload_len, TIME_NOW))
+    output_file.write(struct.pack('<252h', *payload))
+
+
+def gen_all_valid_packet_lengths_1_channel(output_file):
+    lengths = gen_shuffled_lengths()
+    npkts = len(lengths)                # number of packets we'll generator on each stream
+    pkt_gen_0 = packet_sequence_generator(0, lengths)
+    for i in range(npkts):
+        pkt_gen_0(output_file)
+    
+    assert pkt_gen_0.next() == 16002    # 2*sum(1, 2, ..., 126) == 126 * 127
+
+
+def gen_all_valid_packet_lengths_2_channels(output_file):
+    lengths = gen_shuffled_lengths()
+    npkts = len(lengths)                # number of packets we'll generator on each stream
+    pkt_gen_0 = packet_sequence_generator(0, lengths)
+    pkt_gen_1 = packet_sequence_generator(0x1f, gen_shuffled_lengths())
+    pkt_gen = (pkt_gen_0, pkt_gen_1)
+    
+    which_gen = (npkts * [0]) + (npkts * [1])
+    random.shuffle(which_gen)
+    
+    for i in which_gen:
+        pkt_gen[i](output_file)
+    
+    assert pkt_gen_0.next() == 16002    # 2*sum(1, 2, ..., 126) == 126 * 127
+    assert pkt_gen_1.next() == 16002    # 2*sum(1, 2, ..., 126) == 126 * 127
+
+if __name__ == '__main__':
+    random.seed(0)
+    gen_all_valid_packet_lengths_1_channel(open("all_valid_packet_lengths_1_channel.dat", "w"))
+    gen_all_valid_packet_lengths_2_channels(open("all_valid_packet_lengths_2_channels.dat", "w"))
diff --git a/usrp/limbo/inband/qa_inband.cc b/usrp/limbo/inband/qa_inband.cc
new file mode 100644 (file)
index 0000000..6f33a6e
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#include <qa_inband.h>
+#include <qa_inband_packet_prims.h>
+#include <qa_inband_usrp_server.h>
+
+CppUnit::TestSuite *
+qa_inband::suite()
+{
+  CppUnit::TestSuite   *s = new CppUnit::TestSuite("inband");
+
+  s->addTest (qa_inband_packet_prims::suite());
+  s->addTest (qa_inband_usrp_server::suite());
+
+  return s;
+}
diff --git a/usrp/limbo/inband/qa_inband.h b/usrp/limbo/inband/qa_inband.h
new file mode 100644 (file)
index 0000000..ab8f7f2
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * 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 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_QA_INBAND_H
+#define INCLUDED_QA_INBAND_H
+
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the user server
+
+class qa_inband {
+ public:
+  //! return suite of tests for all of usrp server
+  static CppUnit::TestSuite *suite();
+};
+
+#endif /* INCLUDED_QA_INBAND_H */
diff --git a/usrp/limbo/inband/qa_inband_packet_prims.cc b/usrp/limbo/inband/qa_inband_packet_prims.cc
new file mode 100644 (file)
index 0000000..d9bbbec
--- /dev/null
@@ -0,0 +1,162 @@
+/* -*- c++ -*- */
+/*
+ * 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 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 <qa_inband_packet_prims.h>
+#include <cppunit/TestAssert.h>
+#include <stdio.h>
+#include <string.h>
+#include <usrp_inband_usb_packet.h>             // will change on gigabit crossover
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+void
+qa_inband_packet_prims::test_flags()
+{
+  transport_pkt pkt;
+
+  // Test each one of the flags while ensuring no other fields become set in the process
+  pkt.set_header(pkt.FL_START_OF_BURST,0,0,0);
+  CPPUNIT_ASSERT_EQUAL(1, pkt.start_of_burst());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.overrun());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.underrun());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.dropped());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
+
+  pkt.set_header(pkt.FL_END_OF_BURST,0,0,0);
+  CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst());
+  CPPUNIT_ASSERT_EQUAL(1, pkt.end_of_burst());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.overrun());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.underrun());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.dropped());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
+
+  pkt.set_header(pkt.FL_OVERRUN,0,0,0);
+  CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst());
+  CPPUNIT_ASSERT_EQUAL(1, pkt.overrun());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.underrun());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.dropped());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
+
+  pkt.set_header(pkt.FL_UNDERRUN,0,0,0);
+  CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.overrun());
+  CPPUNIT_ASSERT_EQUAL(1, pkt.underrun());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.dropped());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
+
+  pkt.set_header(pkt.FL_DROPPED,0,0,0);
+  CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.overrun());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.underrun());
+  CPPUNIT_ASSERT_EQUAL(1, pkt.dropped());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
+
+  // test of all fields set
+  pkt.set_header(
+    pkt.FL_START_OF_BURST |
+    pkt.FL_END_OF_BURST |
+    pkt.FL_UNDERRUN |
+    pkt.FL_OVERRUN |
+    pkt.FL_DROPPED 
+    ,0,0,0);
+  CPPUNIT_ASSERT_EQUAL(1, pkt.start_of_burst());
+  CPPUNIT_ASSERT_EQUAL(1, pkt.end_of_burst());
+  CPPUNIT_ASSERT_EQUAL(1, pkt.overrun());
+  CPPUNIT_ASSERT_EQUAL(1, pkt.underrun());
+  CPPUNIT_ASSERT_EQUAL(1, pkt.dropped());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
+
+
+}
+//////////////////////////////////////////////////////////////////////
+
+void
+qa_inband_packet_prims::test_fields()
+{
+  transport_pkt pkt;
+  void * payload;
+  
+  // test word0 field exclusiveness
+  //
+  // I want to test max values of each field to ensure field boundaries
+  // but these max values could change based on technology?  The
+  // max payload is returned by a private method so the code is not
+  // technology dependent
+  pkt.set_header(0,16,0,0);
+  CPPUNIT_ASSERT_EQUAL(16, pkt.chan());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
+
+  pkt.set_header(0,0,8,0);
+  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
+  CPPUNIT_ASSERT_EQUAL(8, pkt.tag());
+  CPPUNIT_ASSERT_EQUAL(0,pkt.payload_len());
+
+  pkt.set_header(0,0,0,pkt.max_payload());  
+  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
+  CPPUNIT_ASSERT_EQUAL(pkt.max_payload(), pkt.payload_len());
+
+  // test timestamp, shouldn't have to test other fields since
+  // setting the timestamp only has the ability to affect one word
+  pkt.set_timestamp(54);
+  CPPUNIT_ASSERT_EQUAL(uint32_t(54), pkt.timestamp());
+
+  // test the payload, ensure no other fields overwritten
+  //
+  // is there a better test for this?
+  pkt.set_header(0,0,0,0);
+  payload = malloc(pkt.payload_len());
+  memset(payload, 'f', pkt.payload_len());
+  memcpy(pkt.payload(), payload, pkt.payload_len());
+  CPPUNIT_ASSERT_EQUAL(0, memcmp(pkt.payload(), payload, pkt.payload_len()));
+  CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.overrun());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.underrun());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.dropped());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.chan());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.tag());
+  CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len());
+  free(payload);
+
+}
+//////////////////////////////////////////////////////////////////////
diff --git a/usrp/limbo/inband/qa_inband_packet_prims.h b/usrp/limbo/inband/qa_inband_packet_prims.h
new file mode 100644 (file)
index 0000000..71c0d73
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- c++ -*- */
+/*
+ * 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 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 QA_INBAND_PACKET_PRIMS_H
+#define QA_INBAND_PACKET_PRIMS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_inband_packet_prims : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE(qa_inband_packet_prims);
+  CPPUNIT_TEST(test_flags);
+  CPPUNIT_TEST(test_fields);
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  void test_flags();
+  void test_fields();
+
+};
+
+#endif /* INCLUDED_QA_INBAND_PACKET_PRIMS_H */
diff --git a/usrp/limbo/inband/qa_inband_usrp_server.cc b/usrp/limbo/inband/qa_inband_usrp_server.cc
new file mode 100644 (file)
index 0000000..6049a8a
--- /dev/null
@@ -0,0 +1,1575 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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_inband_usb_packet.h>
+#include <qa_inband_usrp_server.h>
+#include <cppunit/TestAssert.h>
+#include <stdio.h>
+#include <usrp_server.h>
+#include <mblock/mblock.h>
+#include <mblock/runtime.h>
+#include <mblock/protocol_class.h>
+#include <mblock/class_registry.h>
+#include <vector>
+#include <iostream>
+#include <pmt.h>
+
+#include <symbols_usrp_server_cs.h>
+#include <symbols_usrp_tx.h>
+#include <symbols_usrp_rx.h>
+#include <symbols_usrp_channel.h>
+#include <symbols_usrp_low_level_cs.h>
+
+typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit easy
+
+static bool verbose = false;
+
+static pmt_t s_timeout = pmt_intern("%timeout");
+
+// ----------------------------------------------------------------------------------------------
+
+class qa_alloc_top : public mb_mblock
+{
+  mb_port_sptr d_tx;
+  mb_port_sptr d_rx;
+  mb_port_sptr d_cs;
+
+  long d_nmsgs_to_recv;
+  long d_nrecvd;
+
+  long d_max_capacity;
+  long d_ntx_chan, d_nrx_chan;
+
+  long d_nstatus;
+  long d_nstatus_to_recv;
+
+ public:
+  qa_alloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~qa_alloc_top();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void check_message(mb_message_sptr msg);
+  void run_tests();
+};
+
+qa_alloc_top::qa_alloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg)
+{ 
+  d_nrecvd=0;
+  d_nmsgs_to_recv = 6;
+  d_nstatus=0;
+  d_nstatus_to_recv = 50;
+  
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+  // Use the stub with the usrp_server
+  pmt_t usrp_server_dict = pmt_make_dict();
+  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
+
+  // Test the TX side
+  define_component("server", "usrp_server", usrp_server_dict);
+  connect("self", "tx0", "server", "tx0");
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+
+}
+
+qa_alloc_top::~qa_alloc_top(){}
+
+void
+qa_alloc_top::initial_transition()
+{
+  // Allocations should fail before open
+  d_tx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel, 
+                                 s_err_usrp_not_opened), 
+                       pmt_from_long(1)));
+
+  d_rx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel,
+                                 s_err_usrp_not_opened), 
+                       pmt_from_long(1)));
+
+  // Retrieve information about the USRP, then run tests
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open, PMT_T), 
+             pmt_from_long(0)));
+
+  d_cs->send(s_cmd_max_capacity, 
+             pmt_list1(pmt_list2(s_response_max_capacity, PMT_T)));
+  
+  d_cs->send(s_cmd_ntx_chan, 
+             pmt_list1(pmt_list2(s_response_ntx_chan, PMT_T)));
+  
+  d_cs->send(s_cmd_nrx_chan, 
+             pmt_list1(pmt_list2(s_response_nrx_chan,PMT_T)));
+}
+
+void
+qa_alloc_top::run_tests()
+{
+  if(verbose)
+    std::cout << "[qa_alloc_top] Starting tests...\n";
+
+  // should be able to allocate 1 byte
+  d_tx->send(s_cmd_allocate_channel, 
+             pmt_list2(PMT_T, pmt_from_long(1)));
+  
+  // should not be able to allocate max capacity after 100 bytes were allocated
+  d_tx->send(s_cmd_allocate_channel, 
+             pmt_list2(s_err_requested_capacity_unavailable, 
+                       pmt_from_long(d_max_capacity)));  
+  
+  // keep allocating a little more until all of the channels are used and test
+  // the error response we start at 1 since we've already allocated 1 channel
+  for(int i=1; i < d_ntx_chan; i++) {
+
+    if(verbose)
+      std::cout << "[qa_alloc_top] Sent allocation request...\n";
+  
+    d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
+
+    d_nmsgs_to_recv++;
+  }
+
+  // No more channels after allocating all of them is expected
+  d_tx->send(s_cmd_allocate_channel, 
+             pmt_list2(s_err_channel_unavailable, 
+                       pmt_from_long(1)));
+
+  // test out the same on the RX side
+  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
+
+  d_rx->send(s_cmd_allocate_channel, 
+             pmt_list2(s_err_requested_capacity_unavailable, 
+                       pmt_from_long(d_max_capacity)));  
+
+  for(int i=1; i < d_nrx_chan; i++) {
+    
+    d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
+    
+    d_nmsgs_to_recv++;
+  }
+
+  d_rx->send(s_cmd_allocate_channel, 
+             pmt_list2(s_err_channel_unavailable, 
+             pmt_from_long(1)));
+
+  // when all is said and done, there should be d_ntx_chan+d_ntx_chan bytes
+  // allocated
+  d_cs->send(s_cmd_current_capacity_allocation, 
+             pmt_list1(pmt_from_long(d_ntx_chan+d_nrx_chan)));
+}
+
+void
+qa_alloc_top::handle_message(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+
+  if ((pmt_eq(msg->port_id(), d_tx->port_symbol())
+       || pmt_eq(msg->port_id(), d_rx->port_symbol()))
+       && pmt_eq(msg->signal(), s_response_allocate_channel))
+    check_message(msg);
+  
+  if (pmt_eq(msg->port_id(), d_cs->port_symbol())) {
+      
+    if(pmt_eq(msg->signal(), s_response_max_capacity)) {
+      d_max_capacity = pmt_to_long(pmt_nth(2, data));
+      if(verbose)
+        std::cout << "[qa_alloc_top] USRP has max capacity of " 
+                  << d_max_capacity << "\n";
+    }
+    else if(pmt_eq(msg->signal(), s_response_ntx_chan)) {
+      d_ntx_chan = pmt_to_long(pmt_nth(2, data));
+      if(verbose)
+        std::cout << "[qa_alloc_top] USRP tx channels: " 
+                  << d_ntx_chan << "\n";
+    }
+    else if(pmt_eq(msg->signal(), s_response_nrx_chan)) {
+      d_nrx_chan = pmt_to_long(pmt_nth(2, data));
+      if(verbose)
+        std::cout << "[qa_alloc_top] USRP rx channels: " 
+                  << d_nrx_chan << "\n";
+    }
+    else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) {
+      check_message(msg);
+    }
+    
+    d_nstatus++;
+
+    check_message(msg);
+
+    if(d_nstatus==d_nstatus_to_recv)
+      run_tests();
+  }
+}
+
+void
+qa_alloc_top::check_message(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+
+  pmt_t e_event = pmt_nth(0, expected);
+  pmt_t e_status = pmt_nth(1, expected);
+  
+  d_nrecvd++;
+
+
+  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
+    if(verbose)
+      std::cout << "Got: " << status << " Expected: " << e_status << "\n";
+    shutdown_all(PMT_F);
+    return;
+  } else {
+    if(verbose)
+      std::cout << "[qa_alloc_top] Received expected response for message " 
+                << d_nrecvd << " (" << event << ")\n";
+  }
+
+  if(d_nrecvd == d_nmsgs_to_recv)
+    shutdown_all(PMT_T);
+}
+
+REGISTER_MBLOCK_CLASS(qa_alloc_top);
+
+// ----------------------------------------------------------------------------------------------
+
+class qa_dealloc_top : public mb_mblock
+{
+  mb_port_sptr d_tx;
+  mb_port_sptr d_rx;
+  mb_port_sptr d_cs;
+  
+  long d_max_capacity;
+  long d_ntx_chan, d_nrx_chan;
+
+  long d_nstatus;
+  long d_nstatus_to_recv;
+
+  long d_nalloc_to_recv;
+  long d_nalloc_recvd;
+
+  long d_ndealloc_to_recv;
+  long d_ndealloc_recvd;
+
+  std::vector<long> d_tx_chans;
+  std::vector<long> d_rx_chans;
+
+ public:
+  qa_dealloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~qa_dealloc_top();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void check_allocation(mb_message_sptr msg);
+  void check_deallocation(mb_message_sptr msg);
+  void allocate_max();
+  void deallocate_all();
+};
+
+qa_dealloc_top::qa_dealloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg)
+{ 
+  d_ndealloc_recvd=0;
+  d_ndealloc_to_recv = 0;
+  d_nalloc_recvd=0;
+  d_nalloc_to_recv = 0;   // auto-set
+  d_nstatus=0;
+  d_nstatus_to_recv = 4;
+  
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+
+  // Use the stub with the usrp_server
+  pmt_t usrp_server_dict = pmt_make_dict();
+  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
+
+  // Test the TX side
+  define_component("server", "usrp_server", usrp_server_dict);
+  connect("self", "tx0", "server", "tx0");
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+}
+
+qa_dealloc_top::~qa_dealloc_top(){}
+
+void
+qa_dealloc_top::initial_transition()
+{
+
+  if(verbose)
+    std::cout << "[qa_dealloc_top] Initializing...\n";
+
+  // Retrieve information about the USRP, then run tests
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open,PMT_T), 
+             pmt_from_long(0)));
+
+  d_cs->send(s_cmd_max_capacity, 
+             pmt_list1(pmt_list2(s_response_max_capacity,PMT_T)));
+
+  d_cs->send(s_cmd_ntx_chan, 
+             pmt_list1(pmt_list2(s_response_ntx_chan,PMT_T)));
+
+  d_cs->send(s_cmd_nrx_chan, 
+             pmt_list1(pmt_list2(s_response_nrx_chan,PMT_T)));
+}
+
+void
+qa_dealloc_top::allocate_max()
+{
+
+  // Keep allocating until we hit the maximum number of channels
+  for(int i=0; i < d_ntx_chan; i++) {
+    d_tx->send(s_cmd_allocate_channel, 
+               pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T),
+               pmt_from_long(1)));  // 1 byte is good enough
+
+    d_nalloc_to_recv++;
+  }
+
+  for(int i=0; i < d_nrx_chan; i++) {
+    d_rx->send(s_cmd_allocate_channel, 
+               pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T), 
+               pmt_from_long(1)));
+
+    d_nalloc_to_recv++;
+  }
+
+}
+
+void
+qa_dealloc_top::deallocate_all() {
+  
+  // Deallocate all of the channels that were allocated from allocate_max()
+  for(int i=0; i < (int)d_tx_chans.size(); i++) {
+
+    if(verbose)
+      std::cout << "[qa_dealloc_top] Trying to dealloc TX " 
+                << d_tx_chans[i] << std::endl;
+
+    d_tx->send(s_cmd_deallocate_channel, 
+               pmt_list2(pmt_list2(s_response_deallocate_channel,PMT_T), 
+               pmt_from_long(d_tx_chans[i])));
+
+    d_ndealloc_to_recv++;
+  }
+
+  // Deallocate the RX side now
+  for(int i=0; i < (int)d_rx_chans.size(); i++) {
+
+    if(verbose)
+      std::cout << "[qa_dealloc_top] Trying to dealloc RX " 
+                << d_tx_chans[i] << std::endl;
+
+    d_rx->send(s_cmd_deallocate_channel, 
+               pmt_list2(pmt_list2(s_response_deallocate_channel,PMT_T), 
+               pmt_from_long(d_rx_chans[i])));
+
+    d_ndealloc_to_recv++;
+  }
+
+  // Should get permission denied errors trying to re-dealloc the channels, as
+  // we no longer have permission to them after deallocating
+  for(int i=0; i < (int)d_tx_chans.size(); i++) {
+
+    d_tx->send(s_cmd_deallocate_channel, 
+               pmt_list2(pmt_list2(s_response_deallocate_channel,
+                             s_err_channel_permission_denied), 
+                         pmt_from_long(d_tx_chans[i])));
+
+    d_ndealloc_to_recv++;
+  }
+
+  // Same for RX
+  for(int i=0; i < (int)d_rx_chans.size(); i++) {
+
+    d_rx->send(s_cmd_deallocate_channel, 
+               pmt_list2(pmt_list2(s_response_deallocate_channel,
+                             s_err_channel_permission_denied), 
+                         pmt_from_long(d_rx_chans[i])));
+  
+    d_ndealloc_to_recv++;
+  }
+
+  // Try to deallocate a channel that doesn't exist on both sides, the last
+  // element in the vectors is the highest channel number, so we take that plus
+  // 1
+  d_ndealloc_to_recv+=2;
+  d_tx->send(s_cmd_deallocate_channel, 
+             pmt_list2(pmt_list2(s_response_deallocate_channel,
+                                 s_err_channel_invalid), 
+                       pmt_from_long(d_rx_chans.back()+1)));
+
+  d_rx->send(s_cmd_deallocate_channel, 
+             pmt_list2(pmt_list2(s_response_deallocate_channel,
+                                 s_err_channel_invalid), 
+                       pmt_from_long(d_rx_chans.back()+1)));
+
+
+  // The used capacity should be back to 0 now that we've deallocated everything
+  d_cs->send(s_cmd_current_capacity_allocation,
+             pmt_list1(pmt_list2(s_response_current_capacity_allocation,
+                                 PMT_T)));
+}
+
+void
+qa_dealloc_top::handle_message(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+  
+  if(pmt_eq(event, pmt_intern("%shutdown")))
+    return;
+
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+
+  pmt_t e_event = pmt_nth(0, expected);
+  pmt_t e_status = pmt_nth(1, expected);
+
+  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
+    if(verbose)
+      std::cout << "Got: " << status << " Expected: " << e_status << "\n";
+    shutdown_all(PMT_F);
+    return;
+  } else {
+    if(verbose)
+      std::cout << "[qa_alloc_top] Received expected response for message " 
+                << d_ndealloc_recvd
+      << " (" << event << ")\n";
+  }
+
+  if (pmt_eq(msg->port_id(), d_tx->port_symbol())
+       || pmt_eq(msg->port_id(), d_rx->port_symbol())) {
+    
+    if(pmt_eq(msg->signal(), s_response_allocate_channel)) {
+      check_allocation(msg);
+    }
+    
+  }
+  
+  if (pmt_eq(msg->port_id(), d_cs->port_symbol())) {
+      
+    if(pmt_eq(msg->signal(), s_response_max_capacity)) {
+      d_max_capacity = pmt_to_long(pmt_nth(2, data));
+    }
+    else if(pmt_eq(msg->signal(), s_response_ntx_chan)) {
+      d_ntx_chan = pmt_to_long(pmt_nth(2, data));
+    }
+    else if(pmt_eq(msg->signal(), s_response_nrx_chan)) {
+      d_nrx_chan = pmt_to_long(pmt_nth(2, data));
+    }
+    else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) {
+      // the final command is a capacity check which should be 0, then we
+      // shutdown
+      pmt_t expected_result = pmt_from_long(0);
+      pmt_t result = pmt_nth(2, data);
+
+      if(pmt_eqv(expected_result, result)) {
+        shutdown_all(PMT_T);
+        return;
+      } else {
+        shutdown_all(PMT_F);
+        return;
+      }
+    }
+    
+    d_nstatus++;
+
+    if(d_nstatus==d_nstatus_to_recv)
+      allocate_max();
+  }
+}
+
+
+void
+qa_dealloc_top::check_allocation(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+  pmt_t channel = pmt_nth(2, data);
+
+  d_nalloc_recvd++;
+
+  if(!pmt_eqv(status, PMT_T)) {
+    shutdown_all(PMT_F);
+    return;
+  } else {
+    // store all of the allocate channel numbers
+    if(pmt_eq(msg->port_id(), d_tx->port_symbol()))
+      d_tx_chans.push_back(pmt_to_long(channel));
+    if(pmt_eq(msg->port_id(), d_rx->port_symbol()))
+      d_rx_chans.push_back(pmt_to_long(channel));
+  }
+
+  if(d_nalloc_recvd == d_nalloc_to_recv) {
+
+    if(verbose) {
+      std::cout << "[qa_dealloc_top] Allocated TX channels: ";
+      for(int i=0; i < (int)d_tx_chans.size(); i++)
+        std::cout << d_tx_chans[i] << " ";
+
+      std::cout << "\n[qa_dealloc_top] Allocated RX channels: ";
+      for(int i=0; i < (int)d_rx_chans.size(); i++)
+        std::cout << d_rx_chans[i] << " ";
+      std::cout << "\n";
+    }
+
+    deallocate_all();   // once we've allocated all of our channels, try to
+                        // dealloc them
+  }
+}
+
+REGISTER_MBLOCK_CLASS(qa_dealloc_top);
+
+// ----------------------------------------------------------------------------------------------
+
+class qa_open_close_top : public mb_mblock
+{
+  mb_port_sptr d_cs;
+  
+  long d_max_capacity;
+
+  long d_nmsg_to_recv;
+  long d_nmsg_recvd;
+
+ public:
+  qa_open_close_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~qa_open_close_top();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void check_cs(mb_message_sptr msg);
+  void run_tests();
+};
+
+qa_open_close_top::qa_open_close_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg)
+{ 
+
+  d_nmsg_to_recv=7;
+  d_nmsg_recvd=0;
+  
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+
+  // Use the stub with the usrp_server
+  pmt_t usrp_server_dict = pmt_make_dict();
+  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
+
+  // Test the TX side
+  define_component("server", "usrp_server", usrp_server_dict);
+  connect("self", "cs", "server", "cs");
+}
+
+qa_open_close_top::~qa_open_close_top(){}
+
+void
+qa_open_close_top::initial_transition()
+{
+  run_tests();
+}
+
+void
+qa_open_close_top::run_tests()
+{
+  // std::cout << "[qa_open_close_top] Starting tests\n";
+
+  // A close before an open should fail
+  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close, 
+                                              s_err_usrp_already_closed)));
+  
+  // Perform an open, and a second open which should fail
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open,PMT_T), 
+                       pmt_from_long(0)));
+
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open,
+                                 s_err_usrp_already_opened), 
+                       pmt_from_long(0)));
+
+  // A close should now be successful since the interface is open
+  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
+
+  // But, a second close should fail
+  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,
+                                              s_err_usrp_already_closed)));
+  
+  // Just to be thorough, try an open and close again
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open,PMT_T), 
+                       pmt_from_long(0)));
+
+  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
+  
+}
+
+
+void
+qa_open_close_top::handle_message(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+
+  if (pmt_eq(msg->port_id(), d_cs->port_symbol())) {
+      check_cs(msg);
+  }
+
+  d_nmsg_recvd++;
+
+  if(d_nmsg_to_recv == d_nmsg_recvd)
+    shutdown_all(PMT_T);
+}
+
+void
+qa_open_close_top::check_cs(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+
+  pmt_t e_event = pmt_nth(0, expected);
+  pmt_t e_status = pmt_nth(1, expected);
+
+  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
+
+    if(verbose)
+      std::cout << "[qa_open_close_top] FAILED check_cs... Got: " << status
+                << " Expected: " << e_status
+                << " for event " << event << "\n";
+
+    shutdown_all(PMT_F);
+  } else {
+    if(verbose)
+      std::cout << "[qa_open_close_top] Received expected CS response (" 
+                << event << ")\n";
+  }
+
+}
+
+REGISTER_MBLOCK_CLASS(qa_open_close_top);
+
+// ----------------------------------------------------------------------------------------------
+
+class qa_tx_top : public mb_mblock
+{
+  mb_port_sptr d_tx;
+  mb_port_sptr d_rx;
+  mb_port_sptr d_cs;
+  
+  long d_max_capacity;
+  long d_ntx_chan, d_nrx_chan;
+
+  long d_tx_chan;
+  long d_rx_chan;
+
+  long d_nmsg_to_recv;
+  long d_nmsg_recvd;
+
+ public:
+  qa_tx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~qa_tx_top();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void check_allocation(mb_message_sptr msg);
+  void check_deallocation(mb_message_sptr msg);
+  void check_xmit(mb_message_sptr msg);
+  void check_cs(mb_message_sptr msg);
+  void run_tests();
+};
+
+qa_tx_top::qa_tx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg)
+{ 
+
+  d_nmsg_to_recv=10;
+  d_nmsg_recvd=0;
+  
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+
+  // Use the stub with the usrp_server
+  pmt_t usrp_server_dict = pmt_make_dict();
+  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
+
+  // Test the TX side
+  define_component("server", "usrp_server", usrp_server_dict);
+  connect("self", "tx0", "server", "tx0");
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+}
+
+qa_tx_top::~qa_tx_top(){}
+
+void
+qa_tx_top::initial_transition()
+{
+  run_tests();
+}
+
+void
+qa_tx_top::run_tests()
+{
+  if(verbose)
+   std::cout << "[qa_tx_top] Starting tests\n";
+
+  // A transmit before an open should fail
+  d_tx->send(s_cmd_xmit_raw_frame, 
+             pmt_list4(pmt_list2(s_response_xmit_raw_frame, 
+                                 s_err_usrp_not_opened), 
+                       pmt_from_long(0), 
+                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0),
+                       pmt_from_long(0)));
+  
+  // Now open
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open,PMT_T), 
+                       pmt_from_long(0)));
+
+  // Try to transmit on a channel that we have no allocation for
+  d_tx->send(s_cmd_xmit_raw_frame, 
+             pmt_list4(pmt_list2(s_response_xmit_raw_frame,
+                                 s_err_channel_permission_denied), 
+                       pmt_from_long(0), 
+                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0), 
+                       pmt_from_long(0)));
+
+  // Get a channel allocation and send on it, we assume 0 (FIXME) until 'defer'
+  // is implemented for simplicity
+  d_tx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
+                       pmt_from_long(1)));
+
+  d_tx->send(s_cmd_xmit_raw_frame, 
+             pmt_list4(pmt_list2(s_response_xmit_raw_frame, PMT_T), 
+                       pmt_from_long(0), 
+                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0), 
+                       pmt_from_long(0)));
+
+  // Close should be successful
+  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
+
+  // After closing, a new transmit raw frame should fail again
+  d_tx->send(s_cmd_xmit_raw_frame, 
+             pmt_list4(pmt_list2(s_response_xmit_raw_frame, 
+                                 s_err_usrp_not_opened), 
+                       pmt_from_long(0), 
+                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0), 
+                       pmt_from_long(0)));
+
+  // Reopen and retry before getting an allocation, the first xmit should fail,
+  // after we allocate it should work again
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open, PMT_T), 
+                       pmt_from_long(0)));
+
+  d_tx->send(s_cmd_xmit_raw_frame, 
+             pmt_list4(pmt_list2(s_response_xmit_raw_frame,
+                                 s_err_channel_permission_denied), 
+                       pmt_from_long(0), 
+                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0), 
+                       pmt_from_long(0)));
+
+  d_tx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
+                       pmt_from_long(1)));
+
+  d_tx->send(s_cmd_xmit_raw_frame, 
+             pmt_list4(pmt_list2(s_response_xmit_raw_frame,PMT_T), 
+                       pmt_from_long(0), 
+                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0), 
+                       pmt_from_long(0)));
+
+  // A final close which should be successful
+  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
+  
+}
+
+
+void
+qa_tx_top::handle_message(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+  
+  if(pmt_eq(event, pmt_intern("%shutdown")))
+    return;
+
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+
+  pmt_t e_event = pmt_nth(0, expected);
+  pmt_t e_status = pmt_nth(1, expected);
+
+  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
+    if(verbose)
+      std::cout << "[qa_xmit_top] Got: " << status 
+                << " Expected: " << e_status 
+                << "For signal: " << event << "\n";
+    shutdown_all(PMT_F);
+    return;
+  } else {
+    if(verbose)
+      std::cout << "[qa_xmit_top] Received expected response for message " 
+                << d_nmsg_recvd
+      << " (" << event << ")\n";
+  }
+
+  if (pmt_eq(msg->port_id(), d_tx->port_symbol())
+       || pmt_eq(msg->port_id(), d_rx->port_symbol())) {
+    
+    if(pmt_eq(msg->signal(), s_response_allocate_channel)) 
+      check_allocation(msg);
+    
+  }
+  
+  d_nmsg_recvd++;
+
+  if(d_nmsg_to_recv == d_nmsg_recvd){
+    shutdown_all(PMT_T);
+    return;
+  }
+}
+
+void
+qa_tx_top::check_allocation(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+  
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+  pmt_t channel = pmt_nth(2, data);
+
+  if(pmt_eqv(status, PMT_T)) {
+    // store all of the allocate channel numbers
+    if(pmt_eq(msg->port_id(), d_tx->port_symbol()))
+      d_tx_chan = pmt_to_long(channel);
+    if(pmt_eq(msg->port_id(), d_rx->port_symbol()))
+      d_rx_chan = pmt_to_long(channel);
+  }
+}
+
+REGISTER_MBLOCK_CLASS(qa_tx_top);
+
+// ----------------------------------------------------------------------------------------------
+
+class qa_rx_top : public mb_mblock
+{
+  mb_port_sptr d_rx;
+  mb_port_sptr d_cs;
+  
+  long d_max_capacity;
+  long d_ntx_chan, d_nrx_chan;
+
+  long d_rx_chan;
+
+  bool d_got_response_recv;
+
+  mb_time d_t0;
+  double d_delta_t;
+
+ public:
+  qa_rx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~qa_rx_top();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void check_allocation(mb_message_sptr msg);
+  void check_deallocation(mb_message_sptr msg);
+  void check_xmit(mb_message_sptr msg);
+  void check_cs(mb_message_sptr msg);
+  void run_tests();
+};
+
+qa_rx_top::qa_rx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg),
+    d_got_response_recv(false)
+{ 
+
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+
+  // Use the stub with the usrp_server
+  pmt_t usrp_dict = pmt_make_dict();
+  // Set TX and RX interpolations
+  pmt_dict_set(usrp_dict,
+               pmt_intern("decim-rx"),
+               pmt_from_long(128));
+  pmt_dict_set(usrp_dict, pmt_intern("fake-usrp"), PMT_T);
+
+  // Test the TX side
+  define_component("server", "usrp_server", usrp_dict);
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+}
+
+qa_rx_top::~qa_rx_top(){}
+
+void
+qa_rx_top::initial_transition()
+{
+  run_tests();
+}
+
+void
+qa_rx_top::run_tests()
+{
+  if(verbose)
+    std::cout << "[qa_rx_top] Starting tests\n";
+
+  d_cs->send(s_cmd_open, pmt_list2(pmt_list2(s_response_open,PMT_T), pmt_from_long(0)));
+
+  d_rx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T), 
+             pmt_from_long(1)));
+
+  d_rx->send(s_cmd_start_recv_raw_samples, 
+             pmt_list2(PMT_NIL, 
+                       pmt_from_long(0)));
+
+  // Schedule a small timeout in which we expect to have received at least one
+  // packet worth of samples from the stub
+  d_t0 = mb_time::time();
+  schedule_one_shot_timeout(d_t0 + 0.01, PMT_NIL);
+}
+
+
+void
+qa_rx_top::handle_message(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+  
+  if(pmt_eq(event, pmt_intern("%shutdown")))
+    return;
+  
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+
+  // If we get a timeout we shutdown
+  if(pmt_eq(event, s_timeout)) {
+    if(verbose)
+      std::cout << "[qa_rx_top] Got timeout\n";
+    d_rx->send(s_cmd_stop_recv_raw_samples, 
+               pmt_list2(PMT_NIL, 
+                         pmt_from_long(0)));
+
+    d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
+    return;
+  }
+  
+  // For testing RX, an invocation handle is not generated by the stub,
+  // therefore the same approach for testing is not used.  We simply
+  // expect all responses to be true.
+  if(pmt_eq(event, s_response_recv_raw_samples)) {
+    if(pmt_eqv(status, PMT_T)) {
+
+      if(verbose)
+        std::cout << "[qa_rx_top] Received expected response for message " 
+                  << " (" << event << ")\n";
+
+      // All we want is 1 response receive!  Can't guarantee exact numbers
+      d_got_response_recv = true;
+    }
+    else {
+      if(verbose)
+        std::cout << "Got: " << status << " Expected: " << PMT_T << "\n";
+      shutdown_all(PMT_F);
+    }
+    return;
+  }
+
+  pmt_t e_event = pmt_nth(0, expected);
+  pmt_t e_status = pmt_nth(1, expected);
+
+  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
+   if(verbose)
+      std::cout << "Got: " << status << " Expected: " << e_status << "\n";
+    shutdown_all(PMT_F);
+    return;
+  } else {
+    if(verbose)
+      std::cout << "[qa_rx_top] Received expected response for message " 
+                << " (" << event << ")\n";
+  }
+
+  if (pmt_eq(msg->port_id(), d_rx->port_symbol())) {
+    
+    if(pmt_eq(msg->signal(), s_response_allocate_channel)) 
+      check_allocation(msg);
+
+  }
+
+  // We stop when we get a close, we are successful if we
+  // got a response from recv, fail if we never got a recv response
+  if(pmt_eq(msg->signal(), s_response_close)) {
+    
+    if(d_got_response_recv) {
+      shutdown_all(PMT_T);
+      return;
+    }
+    else {
+      shutdown_all(PMT_F);
+      if(verbose)
+        std::cout << "[qa_rx_top] No response message before close\n";
+      return;
+    }
+  }
+}
+
+
+void
+qa_rx_top::check_allocation(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+  
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+  pmt_t channel = pmt_nth(2, data);
+
+  if(pmt_eqv(status, PMT_T)) {
+    // store all of the allocate channel numbers
+    if(pmt_eq(msg->port_id(), d_rx->port_symbol()))
+      d_rx_chan = pmt_to_long(channel);
+  }
+}
+
+REGISTER_MBLOCK_CLASS(qa_rx_top);
+
+// ----------------------------------------------------------------------------------------------
+
+class qa_rid_top : public mb_mblock
+{
+  mb_port_sptr d_tx;
+  mb_port_sptr d_rx;
+  mb_port_sptr d_cs;
+
+  long d_npongs;
+  long d_tcycles;
+  long d_cycles;
+  long d_max_rid;
+  
+  mb_time d_t0;
+  double d_delta_t;
+
+ public:
+  qa_rid_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~qa_rid_top();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void run_tests();
+  void send_max_pings();
+};
+
+qa_rid_top::qa_rid_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg)
+{ 
+  d_npongs = 0;
+  d_tcycles = 3;
+  d_cycles = d_tcycles;
+  d_max_rid = usrp_server::D_MAX_RID;
+  d_delta_t = 0.1;
+
+
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+  // Use the stub with the usrp_server
+  pmt_t usrp_server_dict = pmt_make_dict();
+  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
+
+  // Test the TX side
+  define_component("server", "usrp_server", usrp_server_dict);
+  connect("self", "tx0", "server", "tx0");
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+
+}
+
+qa_rid_top::~qa_rid_top(){}
+
+void
+qa_rid_top::initial_transition()
+{
+  run_tests();
+}
+
+void
+qa_rid_top::run_tests()
+{
+  if(verbose)
+    std::cout << "[qa_rid_top] Starting tests...\n";
+  
+  // Retrieve information about the USRP, then run tests
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open, PMT_T), 
+             pmt_from_long(0)));
+
+  // should be able to allocate 1 byte
+  d_tx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
+                       pmt_from_long(1)));
+  
+  d_rx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
+                       pmt_from_long(1)));
+  
+  // Need to start receiving to read from the USRP to get C/S responses
+  d_rx->send(s_cmd_start_recv_raw_samples, 
+             pmt_list2(PMT_NIL, 
+                       pmt_from_long(0)));
+
+  // Build a subpacket of MAX_RID pings and wait a small amount for all of the
+  // responses and fire off another MAX_RID.  If MAX_RID*2 responses are
+  // received, the RID recycling is working correctly.
+  // Schedule a timer in which we expect to have received all of the responses,
+  // which will send off another MAX_RID worth.
+  send_max_pings();
+  d_t0 = mb_time::time();
+  schedule_one_shot_timeout(d_t0 + d_delta_t, PMT_NIL);
+}
+
+void
+qa_rid_top::send_max_pings()
+{
+  pmt_t ping = pmt_list2(s_op_ping_fixed,
+                         pmt_list2(pmt_from_long(0),
+                                   pmt_from_long(0)));
+
+  pmt_t sub_packets = PMT_NIL;
+
+  for(int i=0; i<d_max_rid; i++) 
+    sub_packets = pmt_list_add(sub_packets, ping);
+
+  d_tx->send(s_cmd_to_control_channel,
+             pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
+                       sub_packets));
+}
+
+void
+qa_rid_top::handle_message(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+
+  // If we get a timeout we ensure we got a maximum RID number of responses.
+  if(pmt_eq(event, s_timeout)) {
+    if(verbose)
+      std::cout << "[qa_rid_top] Got timeout, received so far: " 
+                << d_npongs << "\n";
+
+    d_cycles--;
+    
+    if(d_cycles==0 && d_npongs == d_max_rid*d_tcycles) {
+      shutdown_all(PMT_T);
+    }
+    else if(d_cycles==0) {
+
+      std::cout << "[qa_rid_top] d_npongs: " << d_npongs
+                << " expected: " << d_max_rid*d_tcycles
+                << std::endl;
+
+      shutdown_all(PMT_F);
+    }
+    else {
+      send_max_pings();
+      d_t0 = mb_time::time();
+      schedule_one_shot_timeout(d_t0 + d_delta_t, PMT_NIL);
+    }
+
+  }
+  else if(pmt_eq(event, s_response_from_control_channel))
+  {
+    d_npongs++;
+  }
+
+}
+
+REGISTER_MBLOCK_CLASS(qa_rid_top);
+
+
+// ----------------------------------------------------------------------------------------------
+
+class qa_cs_top : public mb_mblock
+{
+  mb_port_sptr d_tx;
+  mb_port_sptr d_rx;
+  mb_port_sptr d_cs;
+
+  long d_nmsgs_to_recv;
+  long d_nrecvd;
+
+  long d_max_capacity;
+  long d_ntx_chan, d_nrx_chan;
+
+  long d_nstatus;
+  long d_nstatus_to_recv;
+
+ public:
+  qa_cs_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~qa_cs_top();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void check_message(mb_message_sptr msg);
+  void run_tests();
+};
+
+qa_cs_top::qa_cs_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg)
+{ 
+  d_nrecvd=0;
+  d_nmsgs_to_recv = 8;
+  d_nstatus=0;
+  d_nstatus_to_recv = 50;
+  
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+  // Use the stub with the usrp_server
+  pmt_t usrp_server_dict = pmt_make_dict();
+  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
+
+  // Test the TX side
+  define_component("server", "usrp_server", usrp_server_dict);
+  connect("self", "tx0", "server", "tx0");
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+
+}
+
+qa_cs_top::~qa_cs_top(){}
+
+void
+qa_cs_top::initial_transition()
+{
+  run_tests();
+}
+
+void
+qa_cs_top::run_tests()
+{
+  if(verbose)
+    std::cout << "[qa_cs_top] Starting tests...\n";
+  
+  // Retrieve information about the USRP, then run tests
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open, PMT_T), 
+             pmt_from_long(0)));
+
+  // should be able to allocate 1 byte
+  d_tx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
+                       pmt_from_long(1)));
+  
+  d_rx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
+                       pmt_from_long(1)));
+  
+  // Need to start receiving to read from the USRP to get C/S responses
+  d_rx->send(s_cmd_start_recv_raw_samples, 
+             pmt_list2(PMT_NIL, 
+                       pmt_from_long(0)));
+
+  d_tx->send(s_cmd_to_control_channel,
+             pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
+                       pmt_list1(
+                            pmt_list2(s_op_ping_fixed, 
+                                      pmt_list2(pmt_from_long(3), 
+                                      pmt_from_long(0))))));
+  
+  d_tx->send(s_cmd_to_control_channel,
+             pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
+                       pmt_list1(
+                            pmt_list2(s_op_write_reg, 
+                                      pmt_list2(
+                                      pmt_from_long(0x3), 
+                                      pmt_from_long(0x4))))));
+  
+  d_tx->send(s_cmd_to_control_channel,
+             pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
+                       pmt_list1(
+                            pmt_list2(s_op_write_reg_masked, 
+                                      pmt_list3(
+                                      pmt_from_long(0x3), 
+                                      pmt_from_long(0x4),
+                                      pmt_from_long(0x5))))));
+  
+  d_tx->send(s_cmd_to_control_channel,
+             pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
+                       pmt_list1(
+                            pmt_list2(s_op_read_reg, 
+                                      pmt_list2(pmt_from_long(0), 
+                                      pmt_from_long(0x6))))));
+  
+  d_tx->send(s_cmd_to_control_channel,
+             pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
+                       pmt_list1(
+                            pmt_list2(s_op_delay, 
+                                      pmt_list1(pmt_from_long(0x7))))));
+
+  pmt_t subpackets = pmt_list5(
+                        pmt_list2(s_op_ping_fixed, pmt_list2(pmt_from_long(0), pmt_from_long(0))),
+                        pmt_list2(s_op_delay, pmt_list1(pmt_from_long(0x7))),
+                        pmt_list2(s_op_write_reg_masked, pmt_list3(pmt_from_long(3),
+                                                                   pmt_from_long(4),
+                                                                   pmt_from_long(5))),
+                        pmt_list2(s_op_write_reg, pmt_list2(pmt_from_long(3),
+                                                            pmt_from_long(4))),
+                        pmt_list2(s_op_read_reg, pmt_list2(pmt_from_long(0),
+                                                           pmt_from_long(6)))
+                     );
+
+  d_tx->send(s_cmd_to_control_channel, 
+              pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
+                        subpackets));
+
+  pmt_t i2c_data = pmt_make_u8vector(8, 0xff);
+
+  subpackets = pmt_list2(
+                        pmt_list2(s_op_i2c_write, 
+                                  pmt_list2(pmt_from_long(8), i2c_data)),
+                        pmt_list2(s_op_i2c_read,
+                                  pmt_list3(pmt_from_long(0), pmt_from_long(9), pmt_from_long(1)))
+
+                     );
+
+  d_tx->send(s_cmd_to_control_channel, 
+              pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
+                        subpackets));
+  
+}
+
+void
+qa_cs_top::handle_message(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+
+  if ((pmt_eq(msg->port_id(), d_tx->port_symbol())
+       || pmt_eq(msg->port_id(), d_rx->port_symbol()))
+       && pmt_eq(msg->signal(), s_response_allocate_channel))
+    check_message(msg);
+
+  if (pmt_eq(msg->port_id(), d_tx->port_symbol())
+      && pmt_eq(msg->signal(), s_response_from_control_channel))
+    check_message(msg);
+  
+  if (pmt_eq(msg->port_id(), d_cs->port_symbol())) {
+      
+    if(pmt_eq(msg->signal(), s_response_max_capacity)) {
+      d_max_capacity = pmt_to_long(pmt_nth(2, data));
+      if(verbose)
+        std::cout << "[qa_cs_top] USRP has max capacity of " 
+                  << d_max_capacity << "\n";
+    }
+    else if(pmt_eq(msg->signal(), s_response_ntx_chan)) {
+      d_ntx_chan = pmt_to_long(pmt_nth(2, data));
+      if(verbose)
+        std::cout << "[qa_cs_top] USRP tx channels: " 
+                  << d_ntx_chan << "\n";
+    }
+    else if(pmt_eq(msg->signal(), s_response_nrx_chan)) {
+      d_nrx_chan = pmt_to_long(pmt_nth(2, data));
+      if(verbose)
+        std::cout << "[qa_cs_top] USRP rx channels: " 
+                  << d_nrx_chan << "\n";
+    }
+    else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) {
+      check_message(msg);
+    }
+    
+    d_nstatus++;
+
+    check_message(msg);
+
+    if(d_nstatus==d_nstatus_to_recv)
+      run_tests();
+  }
+}
+
+void
+qa_cs_top::check_message(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+
+  pmt_t e_event = pmt_nth(0, expected);
+  pmt_t e_status = pmt_nth(1, expected);
+  
+  d_nrecvd++;
+
+
+  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
+    if(verbose)
+      std::cout << "[qa_cs_top] Got: " << status << " Expected: " << e_status << "\n";
+    shutdown_all(PMT_F);
+    return;
+  } else {
+    if(verbose)
+      std::cout << "[qa_cs_top] Received expected response for message " 
+                << d_nrecvd << " (" << event << ")\n";
+  }
+
+  if(d_nrecvd == d_nmsgs_to_recv)
+    shutdown_all(PMT_T);
+}
+
+REGISTER_MBLOCK_CLASS(qa_cs_top);
+
+// ----------------------------------------------------------------------------------------------
+
+void 
+qa_inband_usrp_server::test_open_close()
+{
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_T;
+
+  // std::cout << "\n\n----------------------------\n";
+  // std::cout << "    RUNNING OPEN/CLOSE TESTS  \n";
+
+  rt->run("top", "qa_open_close_top", PMT_F, &result);
+
+  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
+}
+
+void 
+qa_inband_usrp_server::test_chan_allocation()
+{
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_T;
+
+  // std::cout << "\n\n----------------------------\n";
+  // std::cout << "    RUNNING ALLOCATION TESTS  \n";
+
+  rt->run("qa_alloc_top", "qa_alloc_top", PMT_F, &result);
+  
+  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
+}
+
+void
+qa_inband_usrp_server::test_chan_deallocation()
+{
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_T;
+
+  // std::cout << "\n\n----------------------------\n";
+  // std::cout << "  RUNNING DEALLOCATION TESTS  \n";
+
+  rt->run("qa_dealloc_top", "qa_dealloc_top", PMT_F, &result);
+  
+  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
+}
+
+void
+qa_inband_usrp_server::test_tx()
+{
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_T;
+
+  // std::cout << "\n\n-----------------\n";
+  // std::cout << "  RUNNING TX TESTS  \n";
+
+  rt->run("top", "qa_tx_top", PMT_F, &result);
+  
+  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
+}
+
+void
+qa_inband_usrp_server::test_rx()
+{
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_T;
+
+  // std::cout << "\n\n-----------------\n";
+  // std::cout << "  RUNNING RX TESTS  \n";
+
+  rt->run("top", "qa_rx_top", PMT_F, &result);
+  
+  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
+}
+
+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;
+
+  // std::cout << "\n\n-----------------\n";
+  // std::cout << "  RUNNING CS TESTS  \n";
+
+  rt->run("top", "qa_cs_top", PMT_F, &result);
+  
+  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
+}
+
+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;
+
+  // std::cout << "\n\n-----------------\n";
+  // std::cout << "  RUNNING RID TESTS  \n";
+
+  rt->run("top", "qa_rid_top", PMT_F, &result);
+  
+  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
+}
diff --git a/usrp/limbo/inband/qa_inband_usrp_server.h b/usrp/limbo/inband/qa_inband_usrp_server.h
new file mode 100644 (file)
index 0000000..52a4a0b
--- /dev/null
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * 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 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 QA_INBAND_USRP_SERVER_H
+#define QA_INBAND_USRP_SERVER_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_inband_usrp_server : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE(qa_inband_usrp_server);
+  CPPUNIT_TEST(test_open_close);
+  CPPUNIT_TEST(test_chan_allocation);
+  CPPUNIT_TEST(test_chan_deallocation);
+  CPPUNIT_TEST(test_tx);
+  CPPUNIT_TEST(test_rx);
+  CPPUNIT_TEST(test_cs);
+  CPPUNIT_TEST(test_rid);
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  void test_chan_allocation();
+  void test_chan_deallocation();
+  void test_open_close();
+  void test_tx();
+  void test_rx();
+  void test_cs();
+  void test_rid();
+};
+
+#endif /* INCLUDED_QA_INBAND_USRP_SERVER_H */
diff --git a/usrp/limbo/inband/symbols_usrp_channel.h b/usrp/limbo/inband/symbols_usrp_channel.h
new file mode 100644 (file)
index 0000000..a0114cf
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- c++ -*- */
+/*
+ * 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 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_SYMBOLS_USRP_CHANNEL_H
+#define INCLUDED_SYMBOLS_USRP_CHANNEL_H
+
+#include <pmt.h>
+
+// Outgoing
+static pmt_t s_cmd_allocate_channel = pmt_intern("cmd-allocate-channel");
+static pmt_t s_cmd_deallocate_channel = pmt_intern("cmd-deallocate-channel");
+
+// Incoming
+static pmt_t s_response_allocate_channel = pmt_intern("response-allocate-channel");
+static pmt_t s_response_deallocate_channel = pmt_intern("response-deallocate-channel");
+
+// Errors
+static pmt_t s_err_requested_capacity_unavailable = pmt_intern("err-requested-capacity-unavailable");
+static pmt_t s_err_channel_unavailable = pmt_intern("err-channel-unavailable");
+static pmt_t s_err_channel_invalid = pmt_intern("err-channel-invalid");
+static pmt_t s_err_channel_permission_denied = pmt_intern("err-channel-permission-denied");
+
+#endif /* INCLUDED_SYMBOLS_USRP_CHANNEL_H */
diff --git a/usrp/limbo/inband/symbols_usrp_interface_cs.h b/usrp/limbo/inband/symbols_usrp_interface_cs.h
new file mode 100644 (file)
index 0000000..72c8fcc
--- /dev/null
@@ -0,0 +1,43 @@
+/* -*- c++ -*- */
+/*
+ * 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 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_SYMBOLS_USRP_INTERFACE_CS_H
+#define INCLUDED_SYMBOLS_USRP_INTERFACE_CS_H
+
+#include <pmt.h>
+
+// Outgoing
+static pmt_t s_cmd_usrp_open = pmt_intern("cmd-usrp-open");
+static pmt_t s_cmd_usrp_close = pmt_intern("cmd-usrp-close");
+static pmt_t s_cmd_usrp_ntx_chan = pmt_intern("cmd-usrp-ntx-chan");
+static pmt_t s_cmd_usrp_nrx_chan = pmt_intern("cmd-usrp-nrx-chan");
+static pmt_t s_cmd_usrp_write = pmt_intern("cmd-usrp-write");
+static pmt_t s_cmd_usrp_start_reading = pmt_intern("cmd-usrp-start-reading");
+static pmt_t s_cmd_usrp_stop_reading = pmt_intern("cmd-usrp-stop-reading");
+
+// Incoming
+static pmt_t s_response_usrp_open = pmt_intern("response-usrp-open");
+static pmt_t s_response_usrp_close = pmt_intern("response-usrp-close");
+static pmt_t s_response_usrp_ntx_chan = pmt_intern("response-usrp-ntx-chan");
+static pmt_t s_response_usrp_nrx_chan = pmt_intern("response-usrp-nrx-chan");
+static pmt_t s_response_usrp_write = pmt_intern("response-usrp-write");
+static pmt_t s_response_usrp_read = pmt_intern("response-usrp-read");
+
+#endif /* INCLUDED_SYMBOLS_USRP_INTERFACE_CS_H */
diff --git a/usrp/limbo/inband/symbols_usrp_low_level_cs.h b/usrp/limbo/inband/symbols_usrp_low_level_cs.h
new file mode 100644 (file)
index 0000000..a726060
--- /dev/null
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * 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 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_SYMBOLS_USRP_LOW_LEVEL_CS_H
+#define INCLUDED_SYMBOLS_USRP_LOW_LEVEL_CS_H
+
+#include <pmt.h>
+
+// Outgoing
+static pmt_t s_cmd_to_control_channel = pmt_intern("cmd-to-control-channel");
+
+// Incoming
+static pmt_t s_response_from_control_channel = pmt_intern("response-from-control-channel");
+
+// Subpackets
+static pmt_t s_op_ping_fixed = pmt_intern("op-ping-fixed");
+static pmt_t s_op_ping_fixed_reply = pmt_intern("op-ping-fixed-reply");
+static pmt_t s_op_write_reg = pmt_intern("op-write-reg");
+static pmt_t s_op_write_reg_masked = pmt_intern("op-write-reg-masked");
+static pmt_t s_op_read_reg = pmt_intern("op-read-reg");
+static pmt_t s_op_read_reg_reply = pmt_intern("op-read-reg-reply");
+static pmt_t s_op_i2c_write = pmt_intern("op-i2c-write");
+static pmt_t s_op_i2c_read = pmt_intern("op-i2c-read");
+static pmt_t s_op_i2c_read_reply = pmt_intern("op-i2c-read-reply");
+static pmt_t s_op_spi_write = pmt_intern("op-spi-write");
+static pmt_t s_op_spi_read = pmt_intern("op-spi-read");
+static pmt_t s_op_spi_read_reply = pmt_intern("op-spi-read-reply");
+static pmt_t s_op_delay = pmt_intern("op-delay");
+
+#endif /* INCLUDED_SYMBOLS_USRP_LOW_LEVEL_CS_H */
diff --git a/usrp/limbo/inband/symbols_usrp_rx.h b/usrp/limbo/inband/symbols_usrp_rx.h
new file mode 100644 (file)
index 0000000..07d58a3
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * 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 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_SYMBOLS_USRP_RX_H
+#define INCLUDED_SYMBOLS_USRP_RX_H
+
+#include <pmt.h>
+
+// Outgoing
+static pmt_t s_cmd_start_recv_raw_samples = pmt_intern("cmd-start-recv-raw-samples");
+static pmt_t s_cmd_stop_recv_raw_samples = pmt_intern("cmd-stop-recv-raw-samples");
+
+// Incoming
+static pmt_t s_response_recv_raw_samples = pmt_intern("response-recv-raw-samples");
+
+// Errors
+static pmt_t s_err_already_receiving = pmt_intern("err-already-receiving");
+
+#endif /* INCLUDED_SYMBOLS_USRP_RX_H */
diff --git a/usrp/limbo/inband/symbols_usrp_rx_cs.h b/usrp/limbo/inband/symbols_usrp_rx_cs.h
new file mode 100644 (file)
index 0000000..bf4f033
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * 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 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_SYMBOLS_USRP_RX_CS_H
+#define INCLUDED_SYMBOLS_USRP_RX_CS_H
+
+#include <pmt.h>
+
+// Outgoing
+static pmt_t s_cmd_usrp_rx_start_reading = pmt_intern("cmd-usrp-rx-start-reading");
+
+// Incoming
+static pmt_t s_response_usrp_rx_read = pmt_intern("response-usrp-rx-read");
+
+#endif /* INCLUDED_SYMBOLS_USRP_RX_CS_H */
diff --git a/usrp/limbo/inband/symbols_usrp_server_cs.h b/usrp/limbo/inband/symbols_usrp_server_cs.h
new file mode 100644 (file)
index 0000000..e612e24
--- /dev/null
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * 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 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_SYMBOLS_USRP_SERVER_CS_H
+#define INCLUDED_SYMBOLS_USRP_SERVER_CS_H
+
+#include <pmt.h>
+
+// Outgoing
+static pmt_t s_cmd_open = pmt_intern("cmd-open");
+static pmt_t s_cmd_close = pmt_intern("cmd-close");
+static pmt_t s_cmd_max_capacity  = pmt_intern("cmd-max-capacity");
+static pmt_t s_cmd_ntx_chan  = pmt_intern("cmd-ntx-chan");
+static pmt_t s_cmd_nrx_chan  = pmt_intern("cmd-nrx-chan");
+static pmt_t s_cmd_current_capacity_allocation  = pmt_intern("cmd-current-capacity-allocation");
+
+// Incoming
+static pmt_t s_response_open = pmt_intern("response-open");
+static pmt_t s_response_close = pmt_intern("response-close");
+static pmt_t s_response_max_capacity = pmt_intern("response-max-capacity");
+static pmt_t s_response_ntx_chan = pmt_intern("response-ntx-chan");
+static pmt_t s_response_nrx_chan = pmt_intern("response-nrx-chan");
+static pmt_t s_response_current_capacity_allocation  = pmt_intern("response-current-capacity-allocation");
+
+// Errors
+static pmt_t s_err_usrp_not_opened = pmt_intern("err-usrp-not-opened");
+static pmt_t s_err_usrp_already_opened = pmt_intern("err-usrp-already-opened");
+static pmt_t s_err_usrp_already_closed = pmt_intern("err-usrp-already-closed");
+
+#endif /* INCLUDED_SYMBOLS_USRP_SERVER_CS_H */
diff --git a/usrp/limbo/inband/symbols_usrp_tx.h b/usrp/limbo/inband/symbols_usrp_tx.h
new file mode 100644 (file)
index 0000000..4e58e2c
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * 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 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_SYMBOLS_USRP_TX_H
+#define INCLUDED_SYMBOLS_USRP_TX_H
+
+#include <pmt.h>
+
+// Outgoing
+static pmt_t s_cmd_xmit_raw_frame  = pmt_intern("cmd-xmit-raw-frame");
+
+// Incoming
+static pmt_t s_response_xmit_raw_frame = pmt_intern("response-xmit-raw-frame");
+
+#endif /* INCLUDED_SYMBOLS_USRP_TX_H */
diff --git a/usrp/limbo/inband/symbols_usrp_tx_cs.h b/usrp/limbo/inband/symbols_usrp_tx_cs.h
new file mode 100644 (file)
index 0000000..d02ef1d
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * 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 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_SYMBOLS_USRP_TX_CS_H
+#define INCLUDED_SYMBOLS_USRP_TX_CS_H
+
+#include <pmt.h>
+
+// Outgoing
+static pmt_t s_cmd_usrp_tx_write = pmt_intern("cmd-usrp-tx-write");
+
+// Incoming
+static pmt_t s_response_usrp_tx_write = pmt_intern("response-usrp-tx-write");
+
+#endif /* INCLUDED_SYMBOLS_USRP_TX_CS_H */
diff --git a/usrp/limbo/inband/test_inband.cc b/usrp/limbo/inband/test_inband.cc
new file mode 100644 (file)
index 0000000..77cdca5
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#include <cppunit/TextTestRunner.h>
+#include <qa_inband.h>
+
+int 
+main(int argc, char **argv)
+{
+  
+  CppUnit::TextTestRunner      runner;
+
+  runner.addTest(qa_inband::suite ());
+  
+  bool was_successful = runner.run("", false);
+
+  return was_successful ? 0 : 1;
+}
diff --git a/usrp/limbo/inband/usb_packet.py b/usrp/limbo/inband/usb_packet.py
new file mode 100644 (file)
index 0000000..6dfcf86
--- /dev/null
@@ -0,0 +1,115 @@
+#
+# 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 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.
+#
+
+import struct
+
+
+FL_OVERRUN        = 0x80000000
+FL_UNDERRUN       = 0x40000000
+FL_DROPPED        = 0x20000000
+FL_END_OF_BURST   = 0x10000000
+FL_START_OF_BURST = 0x08000000
+
+FL_ALL_FLAGS      = 0xf8000000
+
+FL_OVERRUN_SHIFT = 31
+FL_UNDERRUN_SHIFT = 30
+FL_DROPPED_SHIFT = 29
+FL_END_OF_BURST_SHIFT = 28
+FL_START_OF_BURST_SHIFT = 27
+  
+RSSI_MASK = 0x3f
+RSSI_SHIFT = 21
+
+CHAN_MASK = 0x1f
+CHAN_SHIFT = 16
+
+TAG_MASK = 0xf
+TAG_SHIFT = 9
+
+PAYLOAD_LEN_MASK = 0x1ff
+PAYLOAD_LEN_SHIFT = 0
+
+def make_header(flags, chan, payload_len, timestamp, rssi=0, tag=0):
+    word0 =  ((flags & FL_ALL_FLAGS)
+              | ((rssi & RSSI_MASK) << RSSI_SHIFT)
+              | ((chan & CHAN_MASK) << CHAN_SHIFT)
+              | ((tag & TAG_MASK) << TAG_SHIFT)
+              | ((payload_len & PAYLOAD_LEN_MASK) << PAYLOAD_LEN_SHIFT))
+    word1 = timestamp
+    return struct.pack('<2I', word0, word1)
+
+
+def _decode(pred, indicator):
+    if pred:
+        return indicator
+    else:
+        return '-'
+
+
+class usb_packet(object):
+    def __init__(self, raw_pkt):
+        assert isinstance(raw_pkt, str) and len(raw_pkt) == 512
+        self._raw_pkt = raw_pkt;
+        (self._word0, self._word1) = struct.unpack('<2I', self._raw_pkt[0:8])
+
+    def timestamp(self):
+        return self._word1
+
+    def rssi(self):
+        return (self._word0 >> RSSI_SHIFT) & RSSI_MASK
+
+    def chan(self):
+        return (self._word0 >> CHAN_SHIFT) & CHAN_MASK
+
+    def tag(self):
+        return (self._word0 >> TAG_SHIFT) & TAG_MASK
+
+    def payload_len(self):
+        return (self._word0 >> PAYLOAD_LEN_SHIFT) & PAYLOAD_LEN_MASK
+
+    def flags(self):
+        return self._word0 & FL_ALL_FLAGS
+
+    def overrun(self):
+        return (self._word0 >> FL_OVERRUN_SHIFT) & 0x1
+
+    def underrun(self):
+        return (self._word0 >> FL_UNDERRUN_SHIFT) & 0x1
+
+    def start_of_burst(self):
+        return (self._word0 >> FL_START_OF_BURST_SHIFT) & 0x1
+
+    def end_of_burst(self):
+        return (self._word0 >> FL_END_OF_BURST_SHIFT) & 0x1
+
+    def dropped(self):
+        return (self._word0 >> FL_DROPPED_SHIFT) & 0x1
+
+    def payload(self):
+        return self._raw_pkt[8:8+self.payload_len()]
+
+    def decoded_flags(self):
+        s = (_decode(self.overrun(), 'O')
+             + _decode(self.underrun(), 'U')
+             + _decode(self.dropped(), 'D')
+             + _decode(self.end_of_burst(), 'E')
+             + _decode(self.start_of_burst(), 'S'))
+        return s
diff --git a/usrp/limbo/inband/usrp_inband_usb_packet.cc b/usrp/limbo/inband/usrp_inband_usb_packet.cc
new file mode 100644 (file)
index 0000000..72bc45c
--- /dev/null
@@ -0,0 +1,793 @@
+/* -*- c++ -*- */
+/*
+ * 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 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_inband_usb_packet.h>
+
+#include <usrp_bytesex.h>
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+/*!
+ * \brief Aligns the packet payload on a 32 bit boundary.  This is essential to
+ * all control/status packets so that the inband FPGA code can parse them
+ * easily.
+ *
+ * \returns true if successful or if the packet was already aligned; false if it
+ * cannot be aligned.
+ */
+bool usrp_inband_usb_packet::align32()
+{
+  int p_len = payload_len();
+
+  int bytes_needed = 4 - (p_len % 4);
+
+  if(bytes_needed == 4)
+    return true;
+
+  // If the room left in the packet is less than the number of bytes
+  // needed, return false to indicate no room to align
+  if((MAX_PAYLOAD - p_len) < bytes_needed)
+    return false;
+    
+  incr_header_len(bytes_needed);
+
+  return true;
+}
+
+/*!
+ * \brief Adds a ping command to the current control packet.
+ *
+ * The \p rid is the rid to be associated with the ping response and \p ping_val
+ * is currently unused.
+ *
+ * \returns true if adding the ping command was successful, false otherwise
+ * (i.e. no space in the current packet).
+ */
+bool usrp_inband_usb_packet::cs_ping(long rid, long ping_val)
+{
+  if(!align32())
+    return false;
+  
+  int p_len = payload_len();
+
+  if((MAX_PAYLOAD - p_len) < (CS_PING_LEN + CS_FIXED_LEN))
+    return false;
+
+  uint32_t ping = ( 
+      ((OP_PING_FIXED & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
+    | ((CS_PING_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
+    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
+    | (ping_val & CS_PINGVAL_MASK)
+
+    );
+
+  uint32_t *payload = (uint32_t *) (d_payload + p_len);
+  *payload = host_to_usrp_u32(ping);
+
+  // Update payload length
+  incr_header_len(CS_FIXED_LEN + CS_PING_LEN);
+
+  return true;
+}
+
+/*!
+ * \brief Adds a ping response to the packet.  This is used by the fake USRP
+ * code to generate fake responses for pings.
+ *
+ * The \p rid is the RID to be associated with the response and \p ping_val is
+ * currently unused.
+ *
+ * \returns true if the ping reply was added successfully, false otherwise.
+ */
+bool usrp_inband_usb_packet::cs_ping_reply(long rid, long ping_val) 
+{
+  if(!align32())
+    return false;
+
+  int p_len = payload_len();
+
+  if((MAX_PAYLOAD - p_len) < (CS_PING_LEN + CS_FIXED_LEN))
+    return false;
+
+  uint32_t ping = ( 
+      ((OP_PING_FIXED_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
+    | ((CS_PING_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
+    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
+    | ((ping_val & CS_PINGVAL_MASK) << CS_PINGVAL_SHIFT)
+
+    );
+
+  uint32_t *payload = (uint32_t *) (d_payload + p_len);
+  *payload = host_to_usrp_u32(ping);
+
+  // Update payload length
+  incr_header_len(CS_FIXED_LEN + CS_PING_LEN);
+
+  return true;
+}
+
+/*!
+ * \brief Adds a write register command to the packet.
+ *
+ * The \p reg_num is the register number for which the value \p val will be
+ * written to.
+ *
+ * \returns true if the command was added to the packet successfully, false
+ * otherwise.
+ */
+bool usrp_inband_usb_packet::cs_write_reg(long reg_num, long val)
+{
+  if(!align32())
+    return false;
+
+  int p_len = payload_len();
+
+  if((MAX_PAYLOAD - p_len) < (CS_WRITEREG_LEN + CS_FIXED_LEN))
+    return false;
+
+  uint32_t word0 = 0;
+
+  // Build the first word which includes the register number
+  word0 = (
+      ((OP_WRITE_REG & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
+    | ((CS_WRITEREG_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
+    | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT)
+  );
+
+  uint32_t *payload = (uint32_t *) (d_payload + p_len);
+  *payload = host_to_usrp_u32(word0);
+
+  // The second word is solely the register value to be written
+  // FIXME: should this be unsigned?
+  payload += 1; 
+  *payload = host_to_usrp_u32((uint32_t) val);
+  
+  // Rebuild the header to update the payload length
+  incr_header_len(CS_FIXED_LEN + CS_WRITEREG_LEN);
+
+  return true;
+}
+
+/*!
+ * \brief Adds a write register masked command to the packet.
+ *
+ * The \p reg_num is the register number for which the value \p val will be
+ * written, masked by \p mask
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
+bool usrp_inband_usb_packet::cs_write_reg_masked(long reg_num, long val, long mask)
+{
+  if(!align32())
+    return false;
+
+  int p_len = payload_len();
+
+  if((MAX_PAYLOAD - p_len) < (CS_WRITEREGMASKED_LEN + CS_FIXED_LEN))
+    return false;
+
+  uint32_t word0 = 0;
+
+  // Build the first word which includes the register number
+  word0 = (
+      ((OP_WRITE_REG_MASKED & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
+    | ((CS_WRITEREGMASKED_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
+    | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT)
+  );
+
+  uint32_t *payload = (uint32_t *) (d_payload + p_len);
+  *payload = host_to_usrp_u32(word0);
+
+  // Skip over the first word and write the register value
+  payload += 1;
+  *payload = host_to_usrp_u32((uint32_t) val);
+
+  // Skip over the register value and write the mask
+  payload += 1;
+  *payload = host_to_usrp_u32((uint32_t) mask);
+  
+  // Rebuild the header to update the payload length
+  incr_header_len(CS_FIXED_LEN + CS_WRITEREGMASKED_LEN);
+
+  return true;
+}
+
+/*!
+ * \brief Adds a read register message to the packet. 
+ *
+ * The \p rid will be the associated RID returned with the response, and \p
+ * reg_num is the register to be read.
+ * 
+ * \returns true if the command was added to the packet, false otherwise.
+ */
+bool usrp_inband_usb_packet::cs_read_reg(long rid, long reg_num)
+{
+  if(!align32())
+    return false;
+
+  int p_len = payload_len();
+
+  if((MAX_PAYLOAD - p_len) < (CS_READREG_LEN + CS_FIXED_LEN))
+    return false;
+
+  uint32_t read_reg = ( 
+      ((OP_READ_REG & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
+    | ((CS_READREG_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
+    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
+    | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT)
+
+    );
+
+  uint32_t *payload = (uint32_t *) (d_payload + p_len);
+  *payload = host_to_usrp_u32(read_reg);
+
+  // Update payload length
+  incr_header_len(CS_FIXED_LEN + CS_READREG_LEN);
+
+  return true;
+}
+
+/*!
+ * \brief Adds a read register reply response to the current packet.  This is
+ * used by the fake USRP code to generate fake register read responses for
+ * testing.
+ *
+ * The \p rid is the associated RID to be included in the response, \p reg_num
+ * is the register the read is coming from, and \p reg_val is the value of the
+ * read.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
+bool usrp_inband_usb_packet::cs_read_reg_reply(long rid, long reg_num, long reg_val)
+{
+  if(!align32())
+    return false;
+
+  int p_len = payload_len();
+
+  if((MAX_PAYLOAD - p_len) < (CS_READREGREPLY_LEN + CS_FIXED_LEN))
+    return false;
+
+  uint32_t word0 = ( 
+      ((OP_READ_REG_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
+    | ((CS_READREGREPLY_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
+    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
+    | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT)
+
+    );
+
+  uint32_t *payload = (uint32_t *) (d_payload + p_len);
+  *payload = host_to_usrp_u32(word0);
+
+  // Hop to the next word and write the reg value
+  payload += 1;
+  *payload = host_to_usrp_u32((uint32_t) reg_val); 
+
+  // Update payload length
+  incr_header_len(CS_FIXED_LEN + CS_READREGREPLY_LEN);
+
+  return true;
+}
+
+/*!
+ * \brief Adds a delay command to the current packet.
+ *
+ * The \p ticks parameter is the number of clock ticks the FPGA should delay
+ * parsing for, which is added to the packet.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
+bool usrp_inband_usb_packet::cs_delay(long ticks)
+{
+  if(!align32())
+    return false;
+
+  int p_len = payload_len();
+
+  if((MAX_PAYLOAD - p_len) < (CS_DELAY_LEN + CS_FIXED_LEN))
+    return false;
+
+  uint32_t delay = ( 
+      ((OP_DELAY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
+    | ((CS_DELAY_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
+    | ((ticks & CS_DELAY_MASK) << CS_DELAY_SHIFT)
+
+    );
+
+  uint32_t *payload = (uint32_t *) (d_payload + p_len);
+  *payload = host_to_usrp_u32(delay);
+
+  // Update payload length
+  incr_header_len(CS_FIXED_LEN + CS_DELAY_LEN);
+
+  return true;
+}
+
+/*!
+ * \brief
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
+bool usrp_inband_usb_packet::cs_i2c_write(long i2c_addr, uint8_t *i2c_data, size_t data_len)
+{
+  if(!align32())
+    return false;
+
+  int p_len = payload_len();
+
+  int i2c_len = data_len + 2;   // 2 bytes between mbz and addr
+
+  if((MAX_PAYLOAD - p_len) < (i2c_len + CS_FIXED_LEN))
+    return false;
+
+  uint32_t word0 = 0;
+
+  word0 = (
+      ((OP_I2C_WRITE & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
+    | ((i2c_len & CS_LEN_MASK) << CS_LEN_SHIFT)
+    | ((i2c_addr & CS_I2CADDR_MASK) << CS_I2CADDR_SHIFT)
+  );
+
+  uint32_t *payload = (uint32_t *) (d_payload + p_len);
+   *payload = host_to_usrp_u32(word0);
+
+   // Jump over the first word and write the data
+   // FIXME: Should the data be changed to usrp byte order?
+   payload += 1;
+   memcpy(payload, i2c_data, data_len);
+
+  // Update payload length
+  incr_header_len(CS_FIXED_LEN + i2c_len);
+
+  return true;
+}
+
+/*!
+ * \brief Adds an I2C read command to the current packet.
+ *
+ * The \p rid is the associated RID to return with the read response, \p
+ * i2c_addr is the address to read from on the I2C bus, and \p n_bytes is the
+ * number of bytes to be read from the bus.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
+bool usrp_inband_usb_packet::cs_i2c_read(long rid, long i2c_addr, long n_bytes)
+{
+  if(!align32())
+    return false;
+
+  int p_len = payload_len();
+
+  if((MAX_PAYLOAD - p_len) < (CS_I2CREAD_LEN + CS_FIXED_LEN))
+    return false;
+
+  uint32_t word0 = 0;
+  
+  word0 = ( 
+      ((OP_I2C_READ & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
+    | ((CS_I2CREAD_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
+    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
+    | ((i2c_addr & CS_I2CADDR_MASK) << CS_I2CADDR_SHIFT)
+    );
+
+  uint32_t *payload = (uint32_t *) (d_payload + p_len);
+  *payload = host_to_usrp_u32(word0);
+
+  // Jump a word and write the number of bytes to read
+  payload += 1;
+  uint32_t word1 = 
+    (n_bytes & CS_I2CREADBYTES_MASK) << CS_I2CREADBYTES_SHIFT;
+  *payload = host_to_usrp_u32(word1);
+
+  // Update payload length
+  incr_header_len(CS_FIXED_LEN + CS_I2CREAD_LEN);
+
+  return true;
+}
+
+/*!
+ * \brief Adds an I2C read reply response to the current packet.  This is used
+ * by the fake USRP code to generate fake I2C responses.
+ *
+ * The \p rid is the RID to be associated with the response, \p i2c_addr is the
+ * address on the I2C bus that the \p i2c_data of \p i2c_data_len was read from.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
+bool usrp_inband_usb_packet::cs_i2c_read_reply(long rid, long i2c_addr, uint8_t *i2c_data, long i2c_data_len)
+{
+  if(!align32())
+    return false;
+
+  int p_len = payload_len();
+
+  int i2c_len = i2c_data_len + 2;
+
+  if((MAX_PAYLOAD - p_len) < (i2c_len + CS_FIXED_LEN)) 
+    return false;
+  
+  uint32_t word0 = 0;
+  
+  word0 = ( 
+      ((OP_I2C_READ_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
+    | ((i2c_len & CS_LEN_MASK) << CS_LEN_SHIFT)
+    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
+    | ((i2c_addr & CS_I2CADDR_MASK) << CS_I2CADDR_SHIFT)
+    );
+
+  uint32_t *payload = (uint32_t *) (d_payload + p_len);
+  *payload = host_to_usrp_u32(word0);
+
+  // Jump a word and write the actual data
+  payload += 1;
+  memcpy(payload, i2c_data, i2c_data_len);
+
+  // Update payload length
+  incr_header_len(CS_FIXED_LEN + i2c_len);
+
+  return true;
+}
+
+/*!
+ * \brief Adds a SPI write command to the current packet.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
+bool usrp_inband_usb_packet::cs_spi_write(long enables, long format, long opt_header_bytes, uint8_t *spi_data, long spi_data_len)
+{
+  if(!align32())
+    return false;
+
+  int p_len = payload_len();
+
+  int spi_len = spi_data_len + 6;
+
+  if((MAX_PAYLOAD - p_len) < (spi_len + CS_FIXED_LEN))
+    return false;
+
+  uint32_t word = 0;
+
+  // First word contains the opcode and length, then mbz
+  word = (
+      ((OP_SPI_WRITE & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
+    | ((spi_len & CS_LEN_MASK) << CS_LEN_SHIFT)
+    );
+  uint32_t *payload = (uint32_t *) (d_payload + p_len);
+  *payload = host_to_usrp_u32(word);
+
+  payload += 1;
+
+  // Second word contains the enables, format, and optional tx bytes
+  word = 0;
+  word = (
+      ((enables & CS_SPIENABLES_MASK) << CS_SPIENABLES_SHIFT)
+    | ((format & CS_SPIFORMAT_MASK) << CS_SPIFORMAT_SHIFT)
+    | ((opt_header_bytes & CS_SPIOPT_MASK) << CS_SPIOPT_SHIFT)
+    );
+  payload = (uint32_t *) (d_payload + p_len);
+  *payload = host_to_usrp_u32(word);
+
+  payload += 1;
+  memcpy(payload, spi_data, spi_data_len);
+
+  // Update payload length
+  incr_header_len(CS_FIXED_LEN + spi_len);
+
+  return true;
+}
+
+/*!
+ * \brief Adds a SPI bus read command to the packet.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
+bool usrp_inband_usb_packet::cs_spi_read(long rid, long enables, long format, long opt_header_bytes, long n_bytes)
+{
+  if(!align32())
+    return false;
+
+  int p_len = payload_len();
+
+  if((MAX_PAYLOAD - p_len) < (CS_SPIREAD_LEN + CS_FIXED_LEN))
+    return false;
+
+  uint32_t word = 0;
+
+  // First word contains the opcode, length, and RID
+  word = (
+      ((OP_SPI_READ & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
+    | ((CS_SPIREAD_LEN & CS_LEN_MASK) << CS_LEN_SHIFT)
+    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
+    );
+  uint32_t *payload = (uint32_t *) (d_payload + p_len);
+  *payload = host_to_usrp_u32(word);
+
+  payload += 1;
+
+  // Second word contains the enables, format, and optional tx bytes
+  word = 0;
+  word = (
+      ((enables & CS_SPIENABLES_MASK) << CS_SPIENABLES_SHIFT)
+    | ((format & CS_SPIFORMAT_MASK) << CS_SPIFORMAT_SHIFT)
+    | ((opt_header_bytes & CS_SPIOPT_MASK) << CS_SPIOPT_SHIFT)
+    );
+  payload = (uint32_t *) (d_payload + p_len);
+  *payload = host_to_usrp_u32(word);
+
+  payload += 1;
+
+  // The third word contains the number of bytes
+  word = 0;
+  word = (
+      ((n_bytes & CS_SPINBYTES_MASK) << CS_SPINBYTES_SHIFT)
+    );
+  payload = (uint32_t *) (d_payload + p_len);
+  *payload = host_to_usrp_u32(word);
+
+  // Update payload length
+  incr_header_len(CS_FIXED_LEN + CS_SPIREAD_LEN);
+
+  return true;
+}
+
+/*!
+ * \brief Adds an SPI read reply to the current packet.  This is used by the
+ * fake USRP code to generate fake responses for SPI reads.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
+bool usrp_inband_usb_packet::cs_spi_read_reply(long rid, uint8_t *spi_data, long spi_data_len)
+{
+  if(!align32())
+    return false;
+
+  int p_len = payload_len();
+
+  int spi_len = spi_data_len + 2;
+
+  if((MAX_PAYLOAD - p_len) < (spi_len + CS_FIXED_LEN))
+    return false;
+
+  uint32_t word = 0;
+
+  // First word contains the opcode, length, and RID
+  word = (
+      ((OP_SPI_READ_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT)
+    | ((spi_len & CS_LEN_MASK) << CS_LEN_SHIFT)
+    | ((rid & CS_RID_MASK) << CS_RID_SHIFT)
+    );
+  uint32_t *payload = (uint32_t *) (d_payload + p_len);
+  *payload = host_to_usrp_u32(word);
+
+  // Jump a word and write the actual data
+  payload += 1;
+  memcpy(payload, spi_data, spi_data_len);
+
+  // Update payload length
+  incr_header_len(CS_FIXED_LEN + spi_len);
+
+  return true;
+}
+
+/*!
+ * \brief Since all control packets contain subpackets which have the length of
+ * the subpacket at a uniform location in the subpacket, this will return the
+ * subpacket length given a byte offset of the start of the subpacket from the beginning of the packet.
+ *
+ * \returns the length of the subpacket
+ */
+int usrp_inband_usb_packet::cs_len(int payload_offset) {
+  uint32_t subpkt = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset)));
+  return (subpkt >> CS_LEN_SHIFT) & CS_LEN_MASK;
+}
+
+/*!
+ * \brief The following method takes an offset within the packet payload to
+ * extract a control/status subpacket and constructs a pmt response which
+ * includes the proper signal and arguments specified by usrp-low-level-cs.  The
+ * USRP server could therefore use this to read subpackets and pass them
+ * responses back up to the application.  It's arguable that only reply packets
+ * should be parsed here, however we parse others for use in debugging or
+ * failure reporting on the transmit side of packets.
+ */
+pmt_t usrp_inband_usb_packet::read_subpacket(int payload_offset) {
+
+  uint32_t subpkt = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset)));
+  uint32_t opcode = (subpkt >> CS_OPCODE_SHIFT) & CS_OPCODE_MASK;
+  uint32_t len = (subpkt >> CS_LEN_SHIFT) & CS_LEN_MASK;
+
+  switch(opcode) {
+    
+    case OP_PING_FIXED_REPLY:
+    {
+      pmt_t rid     = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
+      pmt_t pingval = pmt_from_long((subpkt >> CS_PINGVAL_SHIFT) & CS_PINGVAL_MASK);
+      return pmt_list3(s_op_ping_fixed_reply, rid, pingval);
+    }
+
+    case OP_READ_REG_REPLY:
+    {
+      pmt_t rid     = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
+      pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK);
+
+      // To get the register value we just read the next 32 bits
+      uint32_t val  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4)));
+      pmt_t reg_val = pmt_from_long(val);
+
+      return pmt_list4(s_op_read_reg_reply, rid, reg_num, reg_val);
+    }
+
+    case OP_I2C_READ_REPLY:
+    {
+      pmt_t rid       = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
+      pmt_t i2c_addr  = pmt_from_long((subpkt >> CS_I2CADDR_SHIFT) & CS_I2CADDR_MASK);
+
+      // Make a u8 vector to dump the data from the packet into
+      size_t i2c_data_len;
+      pmt_t i2c_data  = pmt_make_u8vector(len - 2, 0);   // skip rid+mbz+addr = 2 bytes
+      uint8_t *w_data  = 
+          (uint8_t *) pmt_u8vector_writable_elements(i2c_data, i2c_data_len);
+
+      memcpy(w_data, d_payload + payload_offset + 4, i2c_data_len);  // skip first word
+
+      return pmt_list4(s_op_i2c_read_reply, rid, i2c_addr, i2c_data);
+    }
+
+    case OP_SPI_READ_REPLY:
+    {
+      pmt_t rid       = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
+      
+      // Make a u8 vector to dump the data from the packet into
+      size_t spi_data_len;
+      pmt_t spi_data  = pmt_make_u8vector(len - 2, 0);   // skip rid+mbz+addr = 2 bytes
+      uint8_t *w_data  = 
+          (uint8_t *) pmt_u8vector_writable_elements(spi_data, spi_data_len);
+
+      memcpy(w_data, d_payload + payload_offset + 4, spi_data_len);  // skip first word
+
+      return pmt_list3(s_op_spi_read_reply, rid, spi_data);
+    }
+
+    case OP_PING_FIXED:
+    {
+      pmt_t rid     = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
+      pmt_t pingval = pmt_from_long((subpkt >> CS_PINGVAL_SHIFT) & CS_PINGVAL_MASK);
+      return pmt_list3(s_op_ping_fixed, rid, pingval);
+    }
+
+    case OP_WRITE_REG:
+    {
+      pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK);
+
+      // To get the register value we just read the next 32 bits
+      uint32_t val  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4)));
+      pmt_t reg_val = pmt_from_long(val);
+
+      return pmt_list3(s_op_write_reg, reg_num, reg_val);
+    }
+
+    case OP_WRITE_REG_MASKED:
+    {
+      pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK);
+
+      // To get the register value we just read the next 32 bits
+      uint32_t val  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4)));
+      pmt_t reg_val = pmt_from_long(val);
+
+      // The mask is the next 32 bits
+      uint32_t mask  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 8)));
+      pmt_t reg_mask = pmt_from_long(mask);
+
+      return pmt_list4(s_op_write_reg_masked, reg_num, reg_val, reg_mask);
+    }
+
+    case OP_READ_REG:
+    {
+      pmt_t rid     = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
+      pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK);
+
+      return pmt_list3(s_op_read_reg, rid, reg_num);
+    }
+
+    case OP_I2C_WRITE:
+    {
+      pmt_t i2c_addr    = pmt_from_long((subpkt >> CS_I2CADDR_SHIFT) & CS_I2CADDR_MASK);
+
+      // The length includes an extra 2 bytes for storing the mbz and addr
+      pmt_t i2c_data    = pmt_make_u8vector(len-2, 0);
+
+      // Get a writable address to copy the data from the packet
+      size_t ignore;
+      uint8_t *w_data = (uint8_t *) pmt_u8vector_writable_elements(i2c_data, ignore);
+      memcpy(w_data, d_payload + payload_offset + 4, len-2);
+
+      
+      return pmt_list3(s_op_i2c_write, i2c_addr, i2c_data);
+    }
+
+    case OP_I2C_READ:
+    {
+      pmt_t rid       = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
+      pmt_t i2c_addr  = pmt_from_long((subpkt >> CS_I2CADDR_SHIFT) & CS_I2CADDR_MASK);
+      
+      // The number of bytes is in the next word
+      uint32_t bytes  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4)));
+      bytes = (bytes >> CS_I2CREADBYTES_SHIFT) & CS_I2CREADBYTES_MASK;
+      pmt_t i2c_bytes = pmt_from_long(bytes);
+
+      return pmt_list4(s_op_i2c_read, rid, i2c_addr, i2c_bytes);
+    }
+
+    case OP_SPI_WRITE:
+    {
+      // Nothing interesting in the first word, skip to the next
+      uint32_t word  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4)));
+      pmt_t enables   = pmt_from_long((word >> CS_SPIENABLES_SHIFT) & CS_SPIENABLES_MASK);
+      pmt_t format    = pmt_from_long((word >> CS_SPIFORMAT_SHIFT) & CS_SPIFORMAT_MASK);
+      pmt_t opt       = pmt_from_long((word >> CS_SPIOPT_SHIFT) & CS_SPIOPT_MASK);
+
+      // From the next word and on is data
+      size_t spi_data_len;
+      pmt_t spi_data  = pmt_make_u8vector(len - 6, 0);   // skip rid+mbz+addr = 2 bytes
+      uint8_t *w_data  = 
+          (uint8_t *) pmt_u8vector_writable_elements(spi_data, spi_data_len);
+
+      memcpy(w_data, d_payload + payload_offset + 8, spi_data_len);  // skip first 2 words
+
+      return pmt_list5(s_op_spi_write, enables, format, opt, spi_data);
+    }
+
+    case OP_SPI_READ:
+    {
+      // Read the RID from the first word, the rest is mbz
+      pmt_t rid       = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK);
+
+      // Continue at the next word...
+      uint32_t word  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4)));
+      pmt_t enables   = pmt_from_long((word >> CS_SPIENABLES_SHIFT) & CS_SPIENABLES_MASK);
+      pmt_t format    = pmt_from_long((word >> CS_SPIFORMAT_SHIFT) & CS_SPIFORMAT_MASK);
+      pmt_t opt       = pmt_from_long((word >> CS_SPIOPT_SHIFT) & CS_SPIOPT_MASK);
+
+      // The number of bytes is the only thing to read in the next word
+      word  = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 8)));
+      pmt_t n_bytes   = pmt_from_long((word >> CS_SPINBYTES_SHIFT) & CS_SPINBYTES_MASK);
+
+      return pmt_list6(s_op_spi_read, rid, enables, format, opt, n_bytes);
+    }
+
+    case OP_DELAY:
+    {
+      pmt_t ticks = pmt_from_long((subpkt >> CS_DELAY_SHIFT) & CS_DELAY_MASK);
+
+      return pmt_list2(s_op_delay, ticks);
+    }
+    
+    default:
+      return PMT_NIL;
+
+  }
+}
+
diff --git a/usrp/limbo/inband/usrp_inband_usb_packet.h b/usrp/limbo/inband/usrp_inband_usb_packet.h
new file mode 100644 (file)
index 0000000..6f1a3fe
--- /dev/null
@@ -0,0 +1,240 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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_INBAND_USB_PACKET_H_
+#define INCLUDED_USRP_INBAND_USB_PACKET_H_
+
+#include <usrp_bytesex.h>
+#include <mblock/mblock.h>
+#include <pmt.h>
+#include <iostream>
+
+#include <symbols_usrp_low_level_cs.h>
+
+static const int USB_PKT_SIZE = 512;   // bytes
+static const int MAX_PAYLOAD = USB_PKT_SIZE-2*sizeof(uint32_t);
+static const int CONTROL_CHAN = 0x1f;
+
+class usrp_inband_usb_packet {
+  //
+  // keep raw packet in USRP-endian order
+  //
+  uint32_t           d_word0;
+  uint32_t           d_timestamp;
+  unsigned char          d_payload[MAX_PAYLOAD];
+
+public:
+
+  enum opcodes {
+    OP_PING_FIXED         = 0x00,
+    OP_PING_FIXED_REPLY   = 0x01,
+    OP_WRITE_REG          = 0x02,
+    OP_WRITE_REG_MASKED   = 0x03,
+    OP_READ_REG           = 0x04,
+    OP_READ_REG_REPLY     = 0x05,
+    OP_I2C_WRITE          = 0x06,
+    OP_I2C_READ           = 0x07,
+    OP_I2C_READ_REPLY     = 0x08,
+    OP_SPI_WRITE          = 0x09,
+    OP_SPI_READ           = 0x0a,
+    OP_SPI_READ_REPLY     = 0x0b,
+    OP_DELAY              = 0x0c
+  };
+
+  enum flags {
+    FL_OVERRUN        = 0x80000000,
+    FL_UNDERRUN       = 0x40000000,
+    FL_DROPPED        = 0x20000000,
+    FL_START_OF_BURST = 0x10000000,
+    FL_END_OF_BURST   = 0x08000000,
+    FL_CARRIER_SENSE  = 0x04000000,
+
+    FL_ALL_FLAGS      = 0xfc000000
+  };
+
+  static const int FL_OVERRUN_SHIFT = 31;
+  static const int FL_UNDERRUN_SHIFT = 30;
+  static const int FL_DROPPED_SHIFT = 29;
+  static const int FL_END_OF_BURST_SHIFT = 27;
+  static const int FL_START_OF_BURST_SHIFT = 28;
+  
+  static const int RSSI_MASK = 0x3f;
+  static const int RSSI_SHIFT = 21;
+
+  static const int CHAN_MASK = 0x1f;
+  static const int CHAN_SHIFT = 16;
+
+  static const int TAG_MASK = 0xf;
+  static const int TAG_SHIFT = 9;
+
+  static const int PAYLOAD_LEN_MASK = 0x1ff;
+  static const int PAYLOAD_LEN_SHIFT = 0;
+
+  // Fixed size for opcode and length fields
+  static const int CS_FIXED_LEN = 2;
+
+  static const int CS_OPCODE_MASK = 0xff;
+  static const int CS_OPCODE_SHIFT = 24;
+
+  static const int CS_LEN_MASK = 0xff;
+  static const int CS_LEN_SHIFT = 16;
+
+  static const int CS_RID_MASK = 0x3f;
+  static const int CS_RID_SHIFT = 10;
+
+  static const int CS_PING_LEN = 2;
+  static const int CS_PINGVAL_MASK = 0x3ff;
+  static const int CS_PINGVAL_SHIFT = 0;
+
+  static const int CS_WRITEREG_LEN = 6;
+  static const int CS_WRITEREGMASKED_LEN = 10;
+  static const int CS_READREG_LEN = 2;
+  static const int CS_READREGREPLY_LEN = 6;
+  static const int CS_REGNUM_MASK = 0x3ff;
+  static const int CS_REGNUM_SHIFT = 0;
+
+  static const int CS_DELAY_LEN = 2;
+  static const int CS_DELAY_MASK = 0xffff;
+  static const int CS_DELAY_SHIFT = 0;
+
+  static const int CS_I2CADDR_MASK = 0x7f;
+  static const int CS_I2CADDR_SHIFT = 0;
+
+  static const int CS_I2CREAD_LEN = 3;
+  static const int CS_I2CREADBYTES_MASK = 0x7f;
+  static const int CS_I2CREADBYTES_SHIFT = 24;
+
+  static const int CS_SPIOPT_MASK = 0xffff;
+  static const int CS_SPIOPT_SHIFT = 0;
+  static const int CS_SPIFORMAT_MASK = 0xff;
+  static const int CS_SPIFORMAT_SHIFT = 16;
+  static const int CS_SPIENABLES_MASK = 0xff;
+  static const int CS_SPIENABLES_SHIFT = 24;
+  static const int CS_SPIREAD_LEN = 7;
+  static const int CS_SPINBYTES_MASK = 0xff;
+  static const int CS_SPINBYTES_SHIFT = 24;
+
+public:
+  
+  void set_timestamp(uint32_t timestamp){
+    d_timestamp = host_to_usrp_u32(timestamp);
+  }
+
+  void set_end_of_burst() {
+    uint32_t word0 = usrp_to_host_u32(d_word0);
+    word0 |= 1<<FL_END_OF_BURST_SHIFT;
+    d_word0 = host_to_usrp_u32(word0);
+  }
+  
+  void set_header(int flags, int chan, int tag, int payload_len){
+    uint32_t word0 =  ((flags & FL_ALL_FLAGS)
+                       | ((chan & CHAN_MASK) << CHAN_SHIFT)
+                       | ((tag & TAG_MASK) << TAG_SHIFT)
+                       | ((payload_len & PAYLOAD_LEN_MASK) << PAYLOAD_LEN_SHIFT));
+    d_word0 = host_to_usrp_u32(word0);
+  }
+
+  void incr_header_len(int val) {
+    set_header(flags(), chan(), tag(), payload_len() + val);
+  }
+  
+  uint32_t timestamp() const {
+    return usrp_to_host_u32(d_timestamp);
+  }
+
+  int rssi() const {
+    uint32_t word0 = usrp_to_host_u32(d_word0);
+    return (word0 >> RSSI_SHIFT) & RSSI_MASK;
+  }
+
+  int chan() const {
+    uint32_t word0 = usrp_to_host_u32(d_word0);
+    return (word0 >> CHAN_SHIFT) & CHAN_MASK;
+  }
+
+  int tag() const {
+    uint32_t word0 = usrp_to_host_u32(d_word0);
+    return (word0 >> TAG_SHIFT) & TAG_MASK;
+  }
+
+  int payload_len() const {
+    uint32_t word0 = usrp_to_host_u32(d_word0);
+    return (word0 >> PAYLOAD_LEN_SHIFT) & PAYLOAD_LEN_MASK;
+  }
+  
+  int flags() const {
+    return usrp_to_host_u32(d_word0) & FL_ALL_FLAGS;
+  }
+
+  int overrun() const {
+    return (usrp_to_host_u32(d_word0) & FL_OVERRUN) >> FL_OVERRUN_SHIFT;
+  }
+  
+
+  int underrun() const {
+    return (usrp_to_host_u32(d_word0) & FL_UNDERRUN) >> FL_UNDERRUN_SHIFT;
+  }
+
+
+  int start_of_burst() const {
+    return (usrp_to_host_u32(d_word0) & FL_START_OF_BURST) >> FL_START_OF_BURST_SHIFT;
+  }
+
+  int end_of_burst() const {
+    return (usrp_to_host_u32(d_word0) & FL_END_OF_BURST) >> FL_END_OF_BURST_SHIFT;
+  }
+
+  int dropped() const {
+    return (usrp_to_host_u32(d_word0) & FL_DROPPED) >> FL_DROPPED_SHIFT;
+  }
+
+  unsigned char *payload() { 
+    return d_payload; 
+  }
+
+  static int max_payload() {
+    return MAX_PAYLOAD;
+  }
+
+  static int max_pkt_size() {
+    return USB_PKT_SIZE;
+  }
+
+  // C/S methods
+  bool align32();
+  bool cs_ping(long rid, long ping_val);
+  bool cs_ping_reply(long rid, long ping_val);
+  bool cs_write_reg(long reg_num, long val);
+  bool cs_write_reg_masked(long reg_num, long val, long mask);
+  bool cs_read_reg(long rid, long reg_num);
+  bool cs_read_reg_reply(long rid, long reg_num, long reg_val);
+  bool cs_delay(long ticks);
+  bool cs_i2c_write(long i2c_addr, uint8_t *i2c_data, size_t data_len);
+  bool cs_i2c_read(long rid, long i2c_addr, long n_bytes);
+  bool cs_i2c_read_reply(long rid, long i2c_addr, uint8_t *i2c_data, long i2c_data_len);
+  bool cs_spi_write(long enables, long format, long opt_header_bytes, uint8_t *spi_data, long spi_data_len);
+  bool cs_spi_read(long rid, long enables, long format, long opt_header_bytes, long n_bytes);
+  bool cs_spi_read_reply(long rid, uint8_t *spi_data, long spi_data_len);
+  int cs_len(int payload_offset);
+  pmt_t read_subpacket(int payload_offset);
+};
+
+#endif
diff --git a/usrp/limbo/inband/usrp_interface.mbh b/usrp/limbo/inband/usrp_interface.mbh
new file mode 100644 (file)
index 0000000..ad0f78b
--- /dev/null
@@ -0,0 +1,88 @@
+;; -*- scheme -*- ; not really, but tells emacs how to format this
+;;
+;; 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 this program; if not, write to the Free Software Foundation, Inc.,
+;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+;;
+
+;; ----------------------------------------------------------------
+;;              This is an mblock header file
+;;
+;; The format is very much a work-in-progress.
+;; It'll be compiled to C++.
+;; ----------------------------------------------------------------
+
+;; ----------------------------------------------------------------
+;; usrp-interface-cs
+;;
+;; Handles interaction between the usrp_sever and the USB interface
+
+(define-protocol-class usrp-interface-cs
+
+  (:outgoing
+   (cmd-usrp-open invocation-handle which-usrp)
+   (cmd-usrp-close invocation-handle)
+   (cmd-usrp-ntx-chan invocation-handle)
+   (cmd-usrp-nrx-chan invocation-handle)
+   (cmd-usrp-write invocation-handle channel data)
+   (cmd-usrp-start-reading invocation-handle channel)
+   )
+
+  (:incoming
+   (response-usrp-open invocation-handle status)
+   (response-usrp-close invocation-handle status)
+   (response-usrp-ntx-chan invocation-handle ntx-chan)
+   (response-usrp-nrx-chan invocation-handle nrx-chan)
+   (response-usrp-write invocation-handle status channel)
+   (response-usrp-read invocation-handle status data)
+   )
+  )
+
+;; ----------------------------------------------------------------
+;; usrp-tx-cs
+;;
+;; Handles interaction between the USB interface and TX interface
+
+(define-protocol-class usrp-tx-cs
+
+  (:outgoing
+   (cmd-usrp-tx-write invocation-handle channel data tx-handle)
+   )
+
+  (:incoming
+   (response-usrp-tx-write invocation-handle status channel)
+   )
+  )
+
+;; ----------------------------------------------------------------
+;; usrp-rx-cs
+;;
+;; Handles interaction between the USB interface and RX interface
+
+(define-protocol-class usrp-rx-cs
+
+  (:outgoing
+   (cmd-usrp-rx-start-reading invocation-handle rx-handle)
+   (cmd-usrp-rx-stop-reading invocation-handle)
+   )
+
+  (:incoming
+   (response-usrp-rx-read invocation-handle status data)
+
+   ;; There is currently no response to a stop reading
+   )
+  )
diff --git a/usrp/limbo/inband/usrp_rx.cc b/usrp/limbo/inband/usrp_rx.cc
new file mode 100644 (file)
index 0000000..fe9486c
--- /dev/null
@@ -0,0 +1,184 @@
+/* -*- c++ -*- */
+/*
+ * 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 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_rx.h>
+
+#include <usrp_standard.h>
+#include <iostream>
+#include <vector>
+#include <usb.h>
+#include <mblock/class_registry.h>
+#include <usrp_inband_usb_packet.h>
+#include <fpga_regs_common.h>
+#include <stdio.h>
+
+#include <symbols_usrp_rx_cs.h>
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+static const bool verbose = false;
+
+bool usrp_rx_stop;
+
+usrp_rx::usrp_rx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(rt, instance_name, user_arg),
+    d_disk_write(false),
+    d_disk_write_pkt(false)   // if true, writes full packet, else just the payload
+{
+  d_cs = define_port("cs", "usrp-rx-cs", true, mb_port::EXTERNAL);
+  
+  if(d_disk_write) {
+    d_ofile0.open("rx_data_chan0.dat",std::ios::binary|std::ios::out);
+    d_ofile1.open("rx_data_chan1.dat",std::ios::binary|std::ios::out);
+    d_cs_ofile.open("rx_cs.dat",std::ios::binary|std::ios::out);
+  }
+  
+  usrp_rx_stop = false;
+
+}
+
+usrp_rx::~usrp_rx() 
+{
+  if(d_disk_write) {
+    d_ofile0.close();
+    d_ofile1.close();
+    d_cs_ofile.close();
+  }
+}
+
+void 
+usrp_rx::initial_transition()
+{
+  
+}
+
+/*!
+ * \brief Handles incoming signals to to the m-block, wihch should only ever be
+ * a single message: cmd-usrrp-rx-start-reading.  There is no signal to stop
+ * reading as the m-block goes in to a forever loop to read inband packets from
+ * the bus.
+ */
+void
+usrp_rx::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();
+  pmt_t port_id = msg->port_id();
+  pmt_t data = msg->data(); 
+
+  // Theoretically only have 1 message to ever expect, but
+  // want to make sure its at least what we want
+  if(pmt_eq(port_id, d_cs->port_symbol())) {
+    
+    if(pmt_eqv(event, s_cmd_usrp_rx_start_reading))
+      read_and_respond(data);
+  }
+}
+
+/*!
+ * \brief Performs the actual reading of data from the USB bus, called by
+ * handle_message() when a cmd-usrp-rx-start-reading signal is received.  
+ *
+ * The method enters a forever loop where it continues to read data from the bus
+ * and generate read responses to the higher layer.  Currently, shared memory is
+ * used to exit this loop.
+ *
+ * The \p data parameter is a PMT list which contains only a single element, an
+ * invocation handle which will be returned with all read respones.
+ */
+void
+usrp_rx::read_and_respond(pmt_t data)
+{
+  size_t ignore;
+  bool underrun;
+  unsigned int n_read;
+  unsigned int pkt_size = sizeof(transport_pkt);
+
+  pmt_t invocation_handle = pmt_nth(0, data);
+
+  // Need the handle to the RX port to send responses, this is passed
+  // by the USRP interface m-block
+  pmt_t handle = pmt_nth(1, data);
+  d_urx = 
+    boost::any_cast<usrp_standard_rx_sptr>(pmt_any_ref(handle));
+
+  if(verbose)
+    std::cout << "[usrp_rx] Waiting for packets..\n";
+
+  // Read by 512 which is packet size and send them back up
+  while(!usrp_rx_stop) {
+
+    pmt_t v_pkt = pmt_make_u8vector(pkt_size, 0);
+    transport_pkt *pkt = 
+      (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, ignore);
+
+    n_read = d_urx->read(pkt, pkt_size, &underrun);
+
+    if(n_read != pkt_size) {
+      std::cerr << "[usrp_rx] Error reading packet, shutting down\n";
+      d_cs->send(s_response_usrp_rx_read, 
+                 pmt_list3(PMT_NIL, PMT_F, PMT_NIL));
+      return;
+    }
+
+    if(underrun && verbose && 0)
+      std::cout << "[usrp_rx] Underrun\n";
+
+    d_cs->send(s_response_usrp_rx_read, 
+               pmt_list3(PMT_NIL, PMT_T, v_pkt));
+    if(verbose && 0)
+      std::cout << "[usrp_rx] Read 1 packet\n";
+    
+    if(d_disk_write) {
+      if(pkt->chan() == CONTROL_CHAN)
+        d_cs_ofile.write((const char *)pkt, transport_pkt::max_pkt_size());
+      else {
+        if(d_disk_write_pkt) {
+          if(pkt->chan() == 0)
+            d_ofile0.write((const char *)pkt, transport_pkt::max_pkt_size());
+          else if(pkt->chan() == 1)
+            d_ofile1.write((const char *)pkt, transport_pkt::max_pkt_size());
+        } else {
+          if(pkt->chan() == 0)
+            d_ofile0.write((const char *)pkt->payload(), transport_pkt::max_payload());
+          else if(pkt->chan() == 1)
+            d_ofile1.write((const char *)pkt->payload(), transport_pkt::max_payload());
+        }
+      }
+
+      d_cs_ofile.flush();
+      d_ofile0.flush();
+      d_ofile1.flush();
+    }
+  }
+  
+  usrp_rx_stop = false;
+
+  if(verbose) {
+    std::cout << "[USRP_RX] Stopping...\n";
+    fflush(stdout);
+  }
+}
+
+REGISTER_MBLOCK_CLASS(usrp_rx);
diff --git a/usrp/limbo/inband/usrp_rx.h b/usrp/limbo/inband/usrp_rx.h
new file mode 100644 (file)
index 0000000..1006235
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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_RX_H
+#define INCLUDED_USRP_RX_H
+
+#include <mblock/mblock.h>
+#include <fstream>
+#include "usrp_standard.h"
+
+extern bool usrp_rx_stop;   // used to communicate a 'stop' to the RX stub
+
+/*!
+ * \brief Implements the low level usb interface to the USRP
+ */
+class usrp_rx : public mb_mblock
+{
+  mb_port_sptr         d_cs;
+  usrp_standard_rx_sptr     d_urx;
+  
+  bool d_disk_write;
+  bool d_disk_write_pkt;
+  std::ofstream d_ofile0;
+  std::ofstream d_ofile1;
+  std::ofstream d_cs_ofile;
+  
+ public:
+  usrp_rx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg);
+  ~usrp_rx();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ private:
+  void read_and_respond(pmt_t data);
+  void read_data();
+};
+  
+
+#endif /* INCLUDED_USRP_RX_H */
+
diff --git a/usrp/limbo/inband/usrp_rx_stub.cc b/usrp/limbo/inband/usrp_rx_stub.cc
new file mode 100644 (file)
index 0000000..e5c454d
--- /dev/null
@@ -0,0 +1,227 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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_rx_stub.h>
+
+#include <iostream>
+#include <vector>
+#include <usb.h>
+#include <mblock/class_registry.h>
+#include <usrp_inband_usb_packet.h>
+#include <fpga_regs_common.h>
+#include "usrp_standard.h"
+#include <stdio.h>
+#include <string.h>
+#include <ui_nco.h>
+#include <fstream>
+
+#include <symbols_usrp_rx_cs.h>
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+static const bool verbose = false;
+
+bool usrp_rx_stop_stub;
+
+// Used for the fake control packet response code to send the responses back up
+// the RX.  The TX stub dumps responses in to this queue.
+std::queue<pmt_t> d_cs_queue;
+
+usrp_rx_stub::usrp_rx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(rt, instance_name, user_arg),
+    d_samples_per_frame((long)(126)),
+    d_decim_rx(128),
+    d_amplitude(16384),
+    d_disk_write(false)
+{
+
+  // Information about the rates are passed all the way from the app in the form
+  // of a dictionary.  We use this to read the RX decimation rate and compute
+  // the approximate number of MS/s as a form of flow control for the stub.
+  pmt_t usrp_dict = user_arg;
+
+  if (pmt_is_dict(usrp_dict)) {
+    // Read the RX decimation rate
+    if(pmt_t decim_rx = pmt_dict_ref(usrp_dict, 
+                                      pmt_intern("decim-rx"), 
+                                      PMT_NIL)) {
+      if(!pmt_eqv(decim_rx, PMT_NIL)) 
+        d_decim_rx = pmt_to_long(decim_rx);
+    }
+  }
+
+  d_cs = define_port("cs", "usrp-rx-cs", true, mb_port::EXTERNAL);
+  
+  // initialize NCO
+  double freq = 100e3;
+  int interp = 32;                         // 32 -> 4MS/s
+  double sample_rate = 64e6 / interp;  
+  d_nco.set_freq(2*M_PI * freq/sample_rate);
+
+  //d_disk_write = true;
+  
+  if(d_disk_write)
+    d_ofile.open("raw_rx.dat",std::ios::binary|std::ios::out);
+  
+  usrp_rx_stop_stub = false;
+}
+
+usrp_rx_stub::~usrp_rx_stub() 
+{
+  if(d_disk_write)
+    d_ofile.close();
+}
+
+void 
+usrp_rx_stub::initial_transition()
+{
+}
+
+void
+usrp_rx_stub::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();
+  pmt_t port_id = msg->port_id();
+  pmt_t data = msg->data(); 
+
+  if (pmt_eq(msg->signal(), s_timeout)
+      && !pmt_eq(msg->data(), s_done)) {
+  
+    if(!usrp_rx_stop_stub) 
+      read_and_respond();
+    else {  // requested to stop
+      cancel_timeout(msg->metadata());
+      usrp_rx_stop_stub=false;
+      if(verbose)
+        std::cout << "[USRP_RX_STUB] Stopping RX stub\n";
+    }
+
+  }
+
+  // Theoretically only have 1 message to ever expect, but
+  // want to make sure its at least what we want
+  if(pmt_eq(port_id, d_cs->port_symbol())
+      && pmt_eqv(event, s_cmd_usrp_rx_start_reading)) {
+
+    if(verbose)
+      std::cout << "[USRP_RX_STUB] Starting with decim @ " 
+                << d_decim_rx << std::endl;
+    
+      start_packet_timer();
+  }
+}
+
+// Setup a periodic timer which will drive packet generation
+void
+usrp_rx_stub::start_packet_timer()
+{
+  d_t0 = mb_time::time();   // current time
+
+  // Calculate the inter-packet arrival time.  
+  double samples_per_sec = (64.0/(double)d_decim_rx)*1000000.0;
+  double frames_per_sec = samples_per_sec / (double)d_samples_per_frame;
+  double frame_rate = 1.0 / frames_per_sec;
+
+  if(verbose) {
+    std::cout << "[USRP_RX_STUB] Scheduling periodic packet generator\n";
+    std::cout << "\tsamples_per_sec: " << samples_per_sec << std::endl;
+    std::cout << "\tframes_per_sec: " << frames_per_sec << std::endl;
+    std::cout << "\tframe_rate: " << frame_rate << std::endl;
+  }
+
+  schedule_periodic_timeout(d_t0 + frame_rate, mb_time(frame_rate), PMT_T);
+}
+
+void
+usrp_rx_stub::read_and_respond()
+{
+
+  long nsamples_this_frame = d_samples_per_frame;
+
+  size_t nshorts = 2 * nsamples_this_frame;    // 16-bit I & Q
+  long channel = 0;
+  long n_bytes = nshorts*2;
+  pmt_t uvec = pmt_make_s16vector(nshorts, 0);
+  size_t ignore;
+  int16_t *samples = pmt_s16vector_writable_elements(uvec, ignore);
+
+  // fill in the complex sinusoid
+
+  for (int i = 0; i < nsamples_this_frame; i++){
+
+    if (1){
+      gr_complex s;
+      d_nco.sincos(&s, 1, d_amplitude);
+      // write 16-bit i & q
+      samples[2*i] =   (int16_t) s.real();
+      samples[2*i+1] = (int16_t) s.imag();
+    }
+    else {
+      gr_complex s(d_amplitude, d_amplitude);
+
+      // write 16-bit i & q
+      samples[2*i] =   (int16_t) s.real();
+      samples[2*i+1] = (int16_t) s.imag();
+    }
+  }
+  
+  if(d_disk_write)
+    d_ofile.write((const char *)samples, n_bytes);
+
+  pmt_t v_pkt = pmt_make_u8vector(sizeof(transport_pkt), 0);
+  transport_pkt *pkt =
+    (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, ignore);
+
+  pkt->set_header(0, channel, 0, n_bytes);
+  pkt->set_timestamp(0xffffffff);
+  memcpy(pkt->payload(), samples, n_bytes);
+  
+  d_cs->send(s_response_usrp_rx_read, pmt_list3(PMT_NIL, PMT_T, v_pkt));
+
+  // Now lets check the shared CS queue between the TX and RX stub.  Each
+  // element in a queue is a list where the first element is an invocation
+  // handle and the second element is a PMT u8 vect representation of the
+  // CS packet response which can just be passed transparently.
+  while(!d_cs_queue.empty()) {
+    
+    pmt_t cs_pkt = d_cs_queue.front();
+    d_cs_queue.pop();
+
+    pmt_t invocation_handle = pmt_nth(0, cs_pkt);
+    pmt_t v_pkt = pmt_nth(1, cs_pkt);
+
+    d_cs->send(s_response_usrp_rx_read,   
+               pmt_list3(invocation_handle, 
+                         PMT_T, 
+                         v_pkt));  // Take the front CS pkt
+
+    
+    if(verbose)
+      std::cout << "[USRP_RX_STUB] Received CS response from TX stub\n";
+  }
+
+}
+
+REGISTER_MBLOCK_CLASS(usrp_rx_stub);
diff --git a/usrp/limbo/inband/usrp_rx_stub.h b/usrp/limbo/inband/usrp_rx_stub.h
new file mode 100644 (file)
index 0000000..238b456
--- /dev/null
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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_RX_STUB_H
+#define INCLUDED_USRP_RX_STUB_H
+
+#include <mblock/mblock.h>
+#include <vector>
+#include "usrp_standard.h"
+#include <ui_nco.h>
+#include <fstream>
+#include <queue>
+#include <usrp_inband_usb_packet.h>
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+extern bool usrp_rx_stop_stub;   // used to communicate a 'stop' to the RX stub
+extern std::queue<pmt_t> d_cs_queue;
+
+static pmt_t s_timeout = pmt_intern("%timeout");
+static pmt_t s_done = pmt_intern("done");
+
+/*!
+ * \brief Implements the low level usb interface to the USRP
+ */
+class usrp_rx_stub : public mb_mblock
+{
+ public:
+
+  mb_port_sptr d_cs;
+  usrp_standard_rx* d_urx;
+  
+  long         d_samples_per_frame;
+  long    d_decim_rx;
+
+  mb_time d_t0;
+  double d_delta_t;
+  
+  // for generating sine wave output
+  ui_nco<float,float>  d_nco;
+  double               d_amplitude;
+
+  bool d_disk_write;
+
+  std::ofstream d_ofile;
+  
+ public:
+  usrp_rx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg);
+  ~usrp_rx_stub();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ private:
+  void read_and_respond();
+  void read_data();
+  void start_packet_timer();
+};
+  
+
+#endif /* INCLUDED_USRP_RX_H */
+
diff --git a/usrp/limbo/inband/usrp_server.cc b/usrp/limbo/inband/usrp_server.cc
new file mode 100644 (file)
index 0000000..ac26363
--- /dev/null
@@ -0,0 +1,1860 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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_server.h>
+#include <iostream>
+#include <usrp_inband_usb_packet.h>
+#include <mblock/class_registry.h>
+#include <vector>
+#include <usrp_usb_interface.h>
+#include <string.h>
+#include <fpga_regs_common.h>
+#include <fpga_regs_standard.h>
+
+#include <symbols_usrp_server_cs.h>
+#include <symbols_usrp_channel.h>
+#include <symbols_usrp_tx.h>
+#include <symbols_usrp_rx.h>
+#include <symbols_usrp_low_level_cs.h>
+#include <symbols_usrp_interface_cs.h>
+
+static pmt_t s_shutdown = pmt_intern("%shutdown");
+
+typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit easy
+
+const static bool verbose = false;
+
+static std::string
+str(long x)
+{
+  std::ostringstream s;
+  s << x;
+  return s.str();
+}
+
+usrp_server::usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(rt, instance_name, user_arg),
+  d_fpga_debug(false),
+  d_interp_tx(128),     // these should match the lower level defaults (rx also)
+  d_decim_rx(128),
+  d_fake_rx(false)
+{
+  if(verbose)
+    std::cout << "[USRP_SERVER] Initializing...\n";
+
+  // Dictionary for arguments to all of the components
+  d_usrp_dict = user_arg;
+  
+  if (pmt_is_dict(d_usrp_dict)) {
+
+    if(pmt_t fpga_debug = pmt_dict_ref(d_usrp_dict, 
+                                      pmt_intern("fpga-debug"), 
+                                      PMT_NIL)) {
+      if(pmt_eqv(fpga_debug, PMT_T)) 
+        d_fpga_debug=true;
+    }
+    
+    // Read the TX interpolations
+    if(pmt_t interp_tx = pmt_dict_ref(d_usrp_dict, 
+                                      pmt_intern("interp-tx"), 
+                                      PMT_NIL)) {
+      if(!pmt_eqv(interp_tx, PMT_NIL)) 
+        d_interp_tx = pmt_to_long(interp_tx);
+    }
+    
+    // Read the RX decimation rate
+    if(pmt_t decim_rx = pmt_dict_ref(d_usrp_dict, 
+                                      pmt_intern("decim-rx"), 
+                                      PMT_NIL)) {
+      if(!pmt_eqv(decim_rx, PMT_NIL)) 
+        d_decim_rx = pmt_to_long(decim_rx);
+    }
+  }
+  
+  // control & status port
+  d_cs = define_port("cs", "usrp-server-cs", true, mb_port::EXTERNAL); 
+  d_cs_usrp = define_port("cs_usrp", "usrp-interface-cs", false, mb_port::INTERNAL);   
+
+  // ports
+  //
+  // (if/when we do replicated ports, these will be replaced by a
+  //  single replicated port)
+  for(int port=0; port < N_PORTS; port++) {
+
+    d_tx.push_back(define_port("tx"+str(port), 
+                               "usrp-tx", 
+                               true, 
+                               mb_port::EXTERNAL));
+
+    d_rx.push_back(define_port("rx"+str(port), 
+                               "usrp-rx", 
+                               true, 
+                               mb_port::EXTERNAL));
+  }
+
+  define_component("usrp", "usrp_usb_interface", d_usrp_dict);
+  connect("self", "cs_usrp", "usrp", "cs");
+
+  d_defer=false;
+  d_opened=false;
+
+  // FIXME: needs to be returned from open, if we want to use this
+  d_nrx_chan = 2;
+  d_ntx_chan = 2;
+
+  // Initialize capacity on each channel to 0 and to no owner
+  // Also initialize the USRP standard tx/rx pointers to NULL
+  for(int chan=0; chan < d_ntx_chan; chan++)
+    d_chaninfo_tx.push_back(channel_info());
+
+  for(int chan=0; chan < d_nrx_chan; chan++)
+    d_chaninfo_rx.push_back(channel_info());
+
+  d_rx_chan_mask = 0;
+
+  for(int i=0; i < D_MAX_RID; i++) 
+    d_rids.push_back(rid_info());
+
+  //d_fake_rx=true;
+}
+
+/*!
+ * \brief resets the assigned capacity and owners of each RX and TX channel from
+ * allocations.
+ */
+void
+usrp_server::reset_channels()
+{
+
+  for(int chan=0; chan < d_ntx_chan; chan++) {
+    d_chaninfo_tx[chan].assigned_capacity = 0;
+    d_chaninfo_tx[chan].owner = PMT_NIL;
+  }
+
+  for(int chan=0; chan < d_nrx_chan; chan++) {
+    d_chaninfo_rx[chan].assigned_capacity = 0;
+    d_chaninfo_rx[chan].owner = PMT_NIL;
+  }
+
+  d_rx_chan_mask = 0;
+}
+
+usrp_server::~usrp_server()
+{
+}
+
+
+void
+usrp_server::initial_transition()
+{
+  // the initial transition
+}
+
+/*!
+ * \brief Reads all incoming messages to USRP server from the TX, RX, and the CS
+ * ports.  This drives the state of USRP server and dispatches based on the
+ * message.
+ */
+void
+usrp_server::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();         // the "name" of the message
+  pmt_t port_id = msg->port_id();      // which port it came in on
+  pmt_t data = msg->data();
+  pmt_t invocation_handle;
+  pmt_t metadata = msg->metadata();
+  pmt_t status;
+
+  long port;
+
+  if (pmt_eq(event, s_shutdown))       // ignore (for now)
+    return;
+
+  invocation_handle = pmt_nth(0, data);
+
+  if (0){
+    std::cout << "[USRP_SERVER] event: " << event << std::endl;
+    std::cout << "[USRP_SERVER] port_id: " << port_id << std::endl;
+  }
+
+  // It would be nice if this were all table driven, and we could compute our
+  // state transition as f(current_state, port_id, signal)
+  
+  // A message from the USRP CS, which should *only* be responses
+  //
+  // It is important that this set come before checking messages of any other
+  // components.  This is since we always want to listen to the low level USRP
+  // server, even if we aren't initialized we are waiting for responses to
+  // become initialized.  Likewise, after the usrp_server is "closed", we still
+  // want to pass responses back from the low level.
+
+  //---------------- USRP RESPONSE ---------------//
+  if (pmt_eq(port_id, d_cs_usrp->port_symbol())) { 
+    
+    //-------------- USRP OPEN ------------------//
+    if(pmt_eq(event, s_response_usrp_open)) {
+      // pass the response back over the regular CS port
+      pmt_t status = pmt_nth(1, data);
+      d_cs->send(s_response_open, pmt_list2(invocation_handle, status));
+
+      //reset_all_registers();
+      //initialize_registers();
+
+      if(pmt_eqv(status,PMT_T)) {
+        d_opened = true;
+        d_defer = false;
+        recall_defer_queue();
+      }
+
+      return;
+    }
+    //------------- USRP CLOSE -------------------//
+    else if (pmt_eq(event, s_response_usrp_close)) {
+      pmt_t status = pmt_nth(1, data);
+      d_cs->send(s_response_close, pmt_list2(invocation_handle, status));
+
+      if(pmt_eqv(status,PMT_T)) {
+        d_opened = false;
+        d_defer = false;
+        reset_channels();
+        recall_defer_queue();
+      }
+      
+      return;
+    }
+    //--------------- USRP WRITE --------------//
+    else if (pmt_eq(event, s_response_usrp_write)) {
+      
+      pmt_t status = pmt_nth(1, data);
+      long channel = pmt_to_long(pmt_nth(2, data));
+      long port;
+
+      // Do not report back responses if they were generated from a
+      // command packet
+      if(channel == CONTROL_CHAN)
+        return;
+
+      // Find the port through the owner of the channel
+      if((port = tx_port_index(d_chaninfo_tx[channel].owner)) !=-1 )
+        d_tx[port]->send(s_response_xmit_raw_frame, 
+                         pmt_list2(invocation_handle, status));
+      return;
+    }
+    //--------------- USRP READ ---------------//
+    else if (pmt_eq(event, s_response_usrp_read)) {
+
+      pmt_t status = pmt_nth(1, data);
+
+      if(!pmt_eqv(status, PMT_T)) {
+        std::cerr << "[USRP_SERVER] Error receiving packet\n";
+        return;
+      }
+      else {
+        handle_response_usrp_read(data);
+        return;
+      }
+    }
+
+    goto unhandled;
+  }
+
+  // Checking for defer on all other messages
+  if(d_defer) {
+    if (verbose)
+      std::cout << "[USRP_SERVER] Received msg while deferring (" 
+                << msg->signal() << ")\n";
+    d_defer_queue.push(msg);
+    return;
+  }
+  
+  //--------- CONTROL / STATUS ------------//
+  if (pmt_eq(port_id, d_cs->port_symbol())){
+    
+    //----------- OPEN -----------//
+    if (pmt_eq(event, s_cmd_open)){
+
+      // Reject if already open
+      if(d_opened) {
+        d_cs->send(s_response_open, pmt_list2(invocation_handle, s_err_usrp_already_opened));
+        return;
+      }
+
+      // the parameters are the same to the low level interface, so we just pass 'data' along
+      d_cs_usrp->send(s_cmd_usrp_open, data);
+
+      d_defer = true;
+      
+      return;
+    }
+    //---------- CLOSE -----------//
+    else if (pmt_eq(event, s_cmd_close)){
+      
+      if(!d_opened) { 
+        d_cs->send(s_response_close, pmt_list2(invocation_handle, s_err_usrp_already_closed));
+        return;
+      }
+      
+      d_defer = true;
+      d_cs_usrp->send(s_cmd_usrp_close, pmt_list1(invocation_handle));
+
+      return;
+    }
+    //---------- MAX CAPACITY ----------//
+    else if (pmt_eq(event, s_cmd_max_capacity)) {
+      
+      if(!d_opened) { 
+        d_cs->send(s_response_max_capacity, 
+                   pmt_list3(invocation_handle, s_err_usrp_not_opened, pmt_from_long(0)));
+        return;
+      }
+
+      d_cs->send(s_response_max_capacity, 
+                 pmt_list3(invocation_handle, 
+                           PMT_T, 
+                           pmt_from_long(max_capacity())));
+      return;
+    }
+    //---------- NTX CHAN --------------//
+    else if (pmt_eq(event, s_cmd_ntx_chan)) {
+
+      if(!d_opened) { 
+        d_cs->send(s_response_ntx_chan, 
+                   pmt_list3(invocation_handle, s_err_usrp_not_opened, pmt_from_long(0)));
+        return;
+      }
+
+      d_cs->send(s_response_ntx_chan, 
+                 pmt_list3(invocation_handle, 
+                           PMT_T, 
+                           pmt_from_long(d_ntx_chan)));
+      return;
+    }
+    //---------- NRX CHAN -----------//
+    else if (pmt_eq(event, s_cmd_nrx_chan)) {
+
+      if(!d_opened) { 
+        d_cs->send(s_response_nrx_chan, 
+                   pmt_list3(invocation_handle, s_err_usrp_not_opened, pmt_from_long(0)));
+        return;
+      }
+
+      d_cs->send(s_response_nrx_chan, 
+                 pmt_list3(invocation_handle, 
+                           PMT_T, 
+                           pmt_from_long(d_nrx_chan)));
+      return;
+    }  
+    //--------- ALLOCATION? -----------//
+    else if (pmt_eq(event, s_cmd_current_capacity_allocation)) {
+      
+      if(!d_opened) { 
+        d_cs->send(s_response_current_capacity_allocation, 
+                   pmt_list3(invocation_handle, 
+                             s_err_usrp_not_opened, 
+                             pmt_from_long(0)));
+        return;
+      }
+      
+      d_cs->send(s_response_current_capacity_allocation, 
+                 pmt_list3(invocation_handle, 
+                           PMT_T, 
+                           pmt_from_long(current_capacity_allocation())));
+      return;
+    }
+    goto unhandled;
+  }
+  
+  //-------------- TX ---------------//
+  if ((port = tx_port_index(port_id)) != -1) {
+    
+    //------------ ALLOCATE (TX) ----------------//
+    if (pmt_eq(event, s_cmd_allocate_channel)){
+      
+      if(!d_opened) { 
+        d_tx[port]->send(s_response_allocate_channel, 
+                          pmt_list3(invocation_handle, 
+                                    s_err_usrp_not_opened, 
+                                    pmt_from_long(0)));
+        return;
+      }
+        
+      handle_cmd_allocate_channel(d_tx[port], d_chaninfo_tx, data);
+      return;
+    }
+  
+    //----------- DEALLOCATE (TX) ---------------//
+    if (pmt_eq(event, s_cmd_deallocate_channel)) {
+    
+      if(!d_opened) {
+        d_tx[port]->send(s_response_deallocate_channel, 
+                         pmt_list3(invocation_handle, 
+                                   s_err_usrp_not_opened, 
+                                   pmt_from_long(0)));
+        return;
+      }
+
+      handle_cmd_deallocate_channel(d_tx[port], d_chaninfo_tx, data);
+      return;
+    }
+  
+    //-------------- XMIT RAW FRAME -----------------/
+    if (pmt_eq(event, s_cmd_xmit_raw_frame)){
+
+      if(!d_opened) { 
+        d_tx[port]->send(s_response_xmit_raw_frame, 
+                         pmt_list2(invocation_handle, s_err_usrp_not_opened));
+        return;
+      }
+      
+      handle_cmd_xmit_raw_frame(d_tx[port], d_chaninfo_tx, data);
+      return;
+    }
+    
+    //-------------- CONTROL PACKET -----------------/
+    if (pmt_eq(event, s_cmd_to_control_channel)) {
+      
+      if(!d_opened) { 
+        d_tx[port]->send(s_response_xmit_raw_frame, 
+                         pmt_list2(invocation_handle, s_err_usrp_not_opened));
+        return;
+      }
+      
+      handle_cmd_to_control_channel(d_tx[port], d_chaninfo_tx, data);
+      return;
+
+    }
+
+    goto unhandled;
+  }
+
+  //-------------- RX ---------------//
+  if ((port = rx_port_index(port_id)) != -1) {
+    
+    //------------ ALLOCATE (RX) ----------------//
+    if (pmt_eq(event, s_cmd_allocate_channel)) {
+      
+      if(!d_opened) { 
+        d_rx[port]->send(s_response_allocate_channel, 
+                          pmt_list3(invocation_handle, 
+                                    s_err_usrp_not_opened, 
+                                    pmt_from_long(0)));
+        return;
+      }
+        
+      handle_cmd_allocate_channel(d_rx[port], d_chaninfo_rx, data);
+      return;
+    }
+  
+    //----------- DEALLOCATE (RX) ---------------//
+    if (pmt_eq(event, s_cmd_deallocate_channel)) {
+    
+      if(!d_opened) {
+        d_rx[port]->send(s_response_deallocate_channel, 
+                         pmt_list3(invocation_handle, 
+                                   s_err_usrp_not_opened, 
+                                   pmt_from_long(0)));
+        return;
+      }
+
+      handle_cmd_deallocate_channel(d_rx[port], d_chaninfo_rx, data);
+      return;
+    }
+  
+    //-------------- START RECV ----------------//
+    if (pmt_eq(event, s_cmd_start_recv_raw_samples)) {
+    
+      if(!d_opened) {
+        d_rx[port]->send(s_response_recv_raw_samples,
+                         pmt_list2(invocation_handle, s_err_usrp_not_opened));
+        return;
+      }
+
+      handle_cmd_start_recv_raw_samples(d_rx[port], d_chaninfo_rx, data);
+      return;
+    }
+    
+    //-------------- STOP RECV ----------------//
+    if (pmt_eq(event, s_cmd_stop_recv_raw_samples)) {
+    
+      if(!d_opened) 
+        return;
+
+      // FIX ME : no response for stopping? even if error? (permissions)
+      handle_cmd_stop_recv_raw_samples(d_rx[port], d_chaninfo_rx, data);
+
+      return;
+    }
+
+    goto unhandled;
+  }
+
+ unhandled:
+  std::cout << "[USRP_SERVER] unhandled msg: " << msg << std::endl;
+}
+
+/*!
+ * \brief Takes a port_symbol() as parameter \p port_id and is used to determine
+ * if the port is a TX port, or to find an index in the d_tx vector which stores
+ * the port.
+ *
+ * \returns -1 if \p port_id is not in the d_tx vector (i.e., it's not a TX
+ * port), otherwise returns an index in the d_tx vector which stores the port.
+ */
+int usrp_server::tx_port_index(pmt_t port_id) {
+
+  for(int i=0; i < (int) d_tx.size(); i++) 
+    if(pmt_eq(d_tx[i]->port_symbol(), port_id))
+      return i;
+
+  return -1;
+}
+
+/*!
+ * \brief Takes a port_symbol() as parameter \p port_id and is used to determine
+ * if the port is an RX port, or to find an index in the d_rx vector which
+ * stores the port.
+ *
+ * \returns -1 if \p port_id is not in the d_rx vector (i.e., it's not an RX
+ * port), otherwise returns an index in the d_rx vector which stores the port.
+ */
+int usrp_server::rx_port_index(pmt_t port_id) {
+  
+  for(int i=0; i < (int) d_rx.size(); i++) 
+    if(pmt_eq(d_rx[i]->port_symbol(), port_id))
+      return i;
+
+  return -1;
+}
+
+/*!
+ * \brief Determines the current total capacity allocated by all RX and TX
+ * channels.
+ *
+ * \returns the total allocated capacity
+ */
+long usrp_server::current_capacity_allocation() {
+  long capacity = 0;
+
+  for(int chan=0; chan < d_ntx_chan; chan++) 
+    capacity += d_chaninfo_tx[chan].assigned_capacity;
+
+  for(int chan=0; chan < d_nrx_chan; chan++)
+    capacity += d_chaninfo_rx[chan].assigned_capacity;
+
+  return capacity;
+}
+    
+
+/*!
+ * \brief Called by the handle_message() method if the incoming message to
+ * usrp_server is to allocate a channel (cmd-allocate-channel).  The method
+ * checks if the requested capacity exists and if so it will reserve it for the
+ * caller on the channel that is returned via a response-allocate-channel
+ * signal.
+ */
+void 
+usrp_server::handle_cmd_allocate_channel(
+                                mb_port_sptr port, 
+                                std::vector<struct channel_info> &chan_info,
+                                pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  long rqstd_capacity = pmt_to_long(pmt_nth(1, data));
+  long chan;
+
+  // Check capacity exists
+  if((D_USB_CAPACITY - current_capacity_allocation()) < rqstd_capacity) {
+
+    // no capacity available
+    port->send(s_response_allocate_channel, 
+               pmt_list3(invocation_handle, 
+                         s_err_requested_capacity_unavailable, 
+                         PMT_NIL));
+    return;
+  }
+
+  // Find a free channel, assign the capacity and respond
+  for(chan=0; chan < (long)chan_info.size(); chan++) {
+
+    if(verbose)
+      std::cout << "[USRP_SERVER] Checking chan: " << chan
+                << " owner " << chan_info[chan].owner
+                << " size " << chan_info.size()
+                << std::endl;
+
+    if(chan_info[chan].owner == PMT_NIL) {
+  
+      chan_info[chan].owner = port->port_symbol();
+      chan_info[chan].assigned_capacity = rqstd_capacity;
+      
+      port->send(s_response_allocate_channel, 
+                 pmt_list3(invocation_handle, 
+                           PMT_T, 
+                           pmt_from_long(chan)));
+
+      if(verbose)
+        std::cout << "[USRP_SERVER] Assigning channel: " << chan 
+                  << " to " << chan_info[chan].owner
+                  << std::endl;
+      return;
+    }
+  
+  }
+
+  if (verbose)
+    std::cout << "[USRP_SERVER] Couldnt find a TX chan\n";
+
+  // no free TX chan found
+  port->send(s_response_allocate_channel, 
+             pmt_list3(invocation_handle, 
+                       s_err_channel_unavailable, 
+                       PMT_NIL));
+  return;
+}
+
+/*!
+ * \brief Called by the handle_message() method if the incoming message to
+ * usrp_server is to deallocate a channel (cmd-deallocate-channel).  The method
+ * ensures that the sender of the signal owns the channel and that the channel
+ * number is valid.  A response-deallocate-channel signal is sent back with the
+ * result of the deallocation.
+ */
+void 
+usrp_server::handle_cmd_deallocate_channel(
+                              mb_port_sptr port, 
+                              std::vector<struct channel_info> &chan_info, 
+                              pmt_t data)
+{
+
+  pmt_t invocation_handle = pmt_nth(0, data); 
+  long channel = pmt_to_long(pmt_nth(1, data));
+
+  // Ensure the channel is valid and the caller owns the port
+  if(!check_valid(port, channel, chan_info,
+                  pmt_list2(s_response_deallocate_channel, invocation_handle)))
+    return;
+  
+  chan_info[channel].assigned_capacity = 0;
+  chan_info[channel].owner = PMT_NIL;
+
+  port->send(s_response_deallocate_channel, 
+             pmt_list2(invocation_handle, 
+                       PMT_T));
+  return;
+}
+
+/*!
+ * \brief Called by the handle_message() method if the incoming message to
+ * usrp_server is to transmit a frame (cmd-xmit-raw-frame).  The method
+ * allocates enough memory to support a burst of packets which contain the frame
+ * over the bus of the frame, sets the packet headers, and sends a signal to the
+ * lower block for the data (packets) to be written to the bus.  
+ *
+ * The \p port the command was sent on and the channel info (\p chan_info) of
+ * the channel the frame is to be transmitted on are passed to ensure that the
+ * caller owns the channel.
+ *
+ * The \p data parameter is in the format of a cmd-xmit-raw-frame signal.
+ *
+ * The properties
+ */
+void usrp_server::handle_cmd_xmit_raw_frame(
+                              mb_port_sptr port, 
+                              std::vector<struct channel_info> &chan_info, 
+                              pmt_t data) 
+{
+  size_t n_bytes, psize;
+  long max_payload_len = transport_pkt::max_payload();
+
+  pmt_t invocation_handle = pmt_nth(0, data);
+  long channel = pmt_to_long(pmt_nth(1, data));
+  const void *samples = pmt_uniform_vector_elements(pmt_nth(2, data), n_bytes);
+  long timestamp = pmt_to_long(pmt_nth(3, data));
+  pmt_t properties = pmt_nth(4, data);
+  
+  // Ensure the channel is valid and the caller owns the port
+  if(!check_valid(port, channel, chan_info,
+                  pmt_list2(s_response_xmit_raw_frame, invocation_handle)))
+    return;
+
+  // Read information from the properties of the packet
+  bool carrier_sense = false;
+  if(pmt_is_dict(properties)) {
+
+    // Check if carrier sense is enabled for the frame
+    if(pmt_t p_carrier_sense = pmt_dict_ref(properties, 
+                                            pmt_intern("carrier-sense"), 
+                                            PMT_NIL)) {
+      if(pmt_eqv(p_carrier_sense, PMT_T)) 
+        carrier_sense = true;
+    }
+  }
+
+  
+  // Determine the number of packets to allocate contiguous memory for
+  // bursting over the USB and get a pointer to the memory to be used in
+  // building the packets
+  long n_packets = 
+    static_cast<long>(std::ceil(n_bytes / (double)max_payload_len));
+
+  pmt_t v_packets = pmt_make_u8vector(sizeof(transport_pkt) * n_packets, 0);
+
+  transport_pkt *pkts =
+    (transport_pkt *) pmt_u8vector_writable_elements(v_packets, psize);
+
+  for(int n=0; n < n_packets; n++) {
+
+    long payload_len = 
+      std::min((long)(n_bytes-(n*max_payload_len)), (long)max_payload_len);
+  
+    if(n == 0) { // first packet gets start of burst flag and timestamp
+      
+      if(carrier_sense)
+        pkts[n].set_header(pkts[n].FL_START_OF_BURST 
+                           | pkts[n].FL_CARRIER_SENSE, 
+                           channel, 0, payload_len);
+      else
+        pkts[n].set_header(pkts[n].FL_START_OF_BURST, channel, 0, payload_len);
+
+      pkts[n].set_timestamp(timestamp);
+    
+    } else {
+      pkts[n].set_header(0, channel, 0, payload_len);
+      pkts[n].set_timestamp(0xffffffff);
+    }
+
+    memcpy(pkts[n].payload(), 
+           (uint8_t *)samples+(max_payload_len * n), 
+           payload_len);
+  
+  }
+
+
+  pkts[n_packets-1].set_end_of_burst(); // set the last packet's end of burst
+
+  if (verbose && 0)
+    std::cout << "[USRP_SERVER] Received raw frame invocation: " 
+              << invocation_handle << std::endl;
+    
+  // The actual response to the write will be generated by a
+  // s_response_usrp_write since we cannot determine whether to transmit was
+  // successful until we hear from the lower layers.
+  d_cs_usrp->send(s_cmd_usrp_write, 
+                  pmt_list3(invocation_handle, 
+                            pmt_from_long(channel), 
+                            v_packets));
+
+  return;
+}
+
+/*!
+ * \brief Called by the handle_message() method to parse incoming control/status
+ * signals (cmd-to-control-channel).  
+ * 
+ * The \p port the command was sent on and the channel info (\p chan_info) of
+ * the channel are passed to ensure that the caller owns the channel.
+ *
+ * The \p data parameter is in the format of a PMT list, where each element
+ * follows the format of a control/status signal (i.e. op-ping-fixed).
+ *
+ * The method will parse all of the C/S commands included in \p data and place
+ * the commands in to a lower level packet sent to the control channel.  The
+ * method will pack as many commands as possible in t oa single packet, and once
+ * it is fill generate as many lower level packets as needed.
+ *
+ * Anything that needs to be returned to the sender of the signal (i.e. the
+ * value of a register) will be generated by the parse_control_pkt() method as
+ * the responses to the commands are read back from the USRP.
+ */
+void usrp_server::handle_cmd_to_control_channel(
+                            mb_port_sptr port, 
+                            std::vector<struct channel_info> &chan_info, 
+                            pmt_t data) 
+{
+
+  pmt_t invocation_handle = pmt_nth(0, data);
+  pmt_t subpackets = pmt_nth(1, data);
+
+  long n_subpkts = pmt_length(subpackets);
+  long curr_subpkt = 0;
+
+  size_t psize;
+  long payload_len = 0;
+  long channel = CONTROL_CHAN;
+
+  if(verbose)
+    std::cout << "[USRP_SERVER] Handling " << n_subpkts << " commands\n";
+
+  // The design of the following code is optimized for simplicity, not
+  // performance.  To performance optimize this code, the total size in bytes
+  // needed for all of the CS packets is needed to allocate contiguous memory
+  // which contains the USB packets for bursting over the bus.  However to do
+  // this the packets subpackets would need to be parsed twice and their sizes
+  // would need to be determined.
+  //
+  // The approach taken is to keep parsing the subpackets and putting them in to
+  // USB packets.  Once the USB packet is full, a write is sent for it and
+  // another packet is created.
+  //
+  // The subpacket creation methods will return false if the subpacket will not
+  // fit in to the current USB packet.  In these cases a new USB packet is
+  // created and the old is sent.
+  
+  new_packet:
+    // This code needs to become "smart" and only make a new packet when full
+    pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0);
+    transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_packet, psize);
+    payload_len = 0;
+    
+    pkt->set_header(0, channel, 0, payload_len);
+    pkt->set_timestamp(0xffffffff);
+
+  while(curr_subpkt < n_subpkts) {
+
+    pmt_t subp = pmt_nth(curr_subpkt, subpackets);
+    pmt_t subp_cmd = pmt_nth(0, subp);
+    pmt_t subp_data = pmt_nth(1, subp);
+
+    //--------- PING FIXED --------------//
+    if(pmt_eq(subp_cmd, s_op_ping_fixed)) {
+
+      long urid     = pmt_to_long(pmt_nth(0, subp_data));
+      long pingval  = pmt_to_long(pmt_nth(1, subp_data));
+
+      // USRP server sets request ID's to keep track of which application gets
+      // what response back.  To allow a full 6-bits for an RID to the user, we
+      // keep a mapping and replace the RID's as the packets go in and out.  If
+      // there are no RID's available, the command is thrown away silently. 
+      long srid;
+      if((srid = next_rid()) == -1)
+        goto subpkt_bail;
+
+      // We use a vector to store the owner of the ping request and will use it
+      // to send the request on any RX port they own. 
+      d_rids[srid].owner = port->port_symbol();
+      d_rids[srid].user_rid = urid;
+        
+      // Adds a ping after the previous command in the pkt
+      if(!pkt->cs_ping(srid, pingval))
+      {
+        d_cs_usrp->send(s_cmd_usrp_write, 
+                        pmt_list3(invocation_handle, 
+                                  pmt_from_long(channel), 
+                                  v_packet));
+
+        // Return the RID
+        d_rids[srid].owner = PMT_NIL;
+
+        goto new_packet;
+      }
+
+      if(verbose)
+        std::cout << "[USRP_SERVER] Received ping command request"
+                  << " assigning RID " << srid << std::endl;
+
+    }
+  
+    //----------- WRITE REG ---------------//
+    if(pmt_eq(subp_cmd, s_op_write_reg)) {
+      
+      long reg_num = pmt_to_long(pmt_nth(0, subp_data));
+      long val = pmt_to_long(pmt_nth(1, subp_data));
+
+      if(!pkt->cs_write_reg(reg_num, val))
+      {
+        d_cs_usrp->send(s_cmd_usrp_write, 
+                        pmt_list3(invocation_handle, 
+                                  pmt_from_long(channel), 
+                                  v_packet));
+        
+        goto new_packet;
+      }
+      
+      if(verbose)
+        std::cout << "[USRP_SERVER] Received write register request "
+                  << "("
+                  << "Reg: " << reg_num << ", "
+                  << "Val: " << val
+                  << ")\n";
+    }
+    
+    //------- WRITE REG MASKED ----------//
+    if(pmt_eq(subp_cmd, s_op_write_reg_masked)) {
+      
+      long reg_num = pmt_to_long(pmt_nth(0, subp_data));
+      long val = pmt_to_long(pmt_nth(1, subp_data));
+      long mask = pmt_to_long(pmt_nth(2, subp_data));
+
+      if(!pkt->cs_write_reg_masked(reg_num, val, mask))
+      {
+        d_cs_usrp->send(s_cmd_usrp_write, 
+                        pmt_list3(invocation_handle, 
+                                  pmt_from_long(channel), 
+                                  v_packet));
+        
+        goto new_packet;
+      }
+      
+      if(verbose)
+        std::cout << "[USRP_SERVER] Received write register masked request\n";
+    }
+    
+    //------------ READ REG --------------//
+    if(pmt_eq(subp_cmd, s_op_read_reg)) {
+      
+      long urid     = pmt_to_long(pmt_nth(0, subp_data));
+      long reg_num  = pmt_to_long(pmt_nth(1, subp_data));
+
+      long srid;
+      if((srid = next_rid()) == -1)
+        goto subpkt_bail;
+
+      d_rids[srid].owner = port->port_symbol();
+      d_rids[srid].user_rid = urid;
+
+      if(!pkt->cs_read_reg(srid, reg_num))
+      {
+        d_cs_usrp->send(s_cmd_usrp_write, 
+                        pmt_list3(invocation_handle, 
+                                  pmt_from_long(channel), 
+                                  v_packet));
+
+        // Return the rid
+        d_rids[srid].owner = PMT_NIL;
+        
+        goto new_packet;
+      }
+      
+      if(verbose)
+        std::cout << "[USRP_SERVER] Received read register request"
+                  << " assigning RID " << srid << std::endl;
+    }
+    
+    //------------ DELAY --------------//
+    if(pmt_eq(subp_cmd, s_op_delay)) {
+
+      long ticks = pmt_to_long(pmt_nth(0, subp_data));
+
+      if(!pkt->cs_delay(ticks))
+      {
+        d_cs_usrp->send(s_cmd_usrp_write, 
+                        pmt_list3(invocation_handle, 
+                                  pmt_from_long(channel), 
+                                  v_packet));
+        
+        goto new_packet;
+      }
+      
+      if(verbose)
+        std::cout << "[USRP_SERVER] Received delay request of "
+                  << ticks << " ticks\n";
+    }
+
+    //--------- I2C WRITE -----------//
+    // FIXME: could check that byte count does not exceed 2^8 which
+    // is the max length in the subpacket for # of bytes to read.
+    if(pmt_eq(subp_cmd, s_op_i2c_write)) {
+      
+      long i2c_addr = pmt_to_long(pmt_nth(0, subp_data));
+      pmt_t data = pmt_nth(1, subp_data);
+
+      // Get a readable address to the data which also gives us the length
+      size_t data_len;
+      uint8_t *i2c_data = (uint8_t *) pmt_u8vector_writable_elements(data, data_len);
+
+      // Make the USB packet
+      if(!pkt->cs_i2c_write(i2c_addr, i2c_data, data_len))
+      {
+        d_cs_usrp->send(s_cmd_usrp_write, 
+                        pmt_list3(invocation_handle, 
+                                  pmt_from_long(channel), 
+                                  v_packet));
+        
+        goto new_packet;
+      }
+      
+      if(verbose)
+        std::cout << "[USRP_SERVER] Received I2C write\n";
+    }
+  
+    //----------- I2C Read -------------//
+    if(pmt_eq(subp_cmd, s_op_i2c_read)) {
+      
+      long urid       = pmt_to_long(pmt_nth(0, subp_data));
+      long i2c_addr   = pmt_to_long(pmt_nth(1, subp_data));
+      long i2c_bytes  = pmt_to_long(pmt_nth(2, subp_data));
+
+      long srid;
+      if((srid = next_rid()) == -1)
+        goto subpkt_bail;
+      
+      d_rids[srid].owner = port->port_symbol();
+      d_rids[srid].user_rid = urid;
+
+      if(!pkt->cs_i2c_read(srid, i2c_addr, i2c_bytes))
+      {
+        
+        d_cs_usrp->send(s_cmd_usrp_write, 
+                        pmt_list3(invocation_handle, 
+                                  pmt_from_long(channel), 
+                                  v_packet));
+
+        d_rids[srid].owner = PMT_NIL;
+
+        goto new_packet;
+      }
+      
+      if(verbose)
+        std::cout << "[USRP_SERVER] Received I2C read\n";
+    }
+    
+    //--------- SPI WRITE -----------//
+    if(pmt_eq(subp_cmd, s_op_spi_write)) {
+      
+      long enables = pmt_to_long(pmt_nth(0, subp_data));
+      long format = pmt_to_long(pmt_nth(1, subp_data));
+      long opt = pmt_to_long(pmt_nth(2, subp_data));
+      pmt_t data = pmt_nth(3, subp_data);
+
+      // Get a readable address to the data which also gives us the length
+      size_t data_len;
+      uint8_t *spi_data = (uint8_t *) pmt_u8vector_writable_elements(data, data_len);
+
+      // Make the USB packet
+      if(!pkt->cs_spi_write(enables, format, opt, spi_data, data_len))
+      {
+        d_cs_usrp->send(s_cmd_usrp_write, 
+                        pmt_list3(invocation_handle, 
+                                  pmt_from_long(channel), 
+                                  v_packet));
+        
+        goto new_packet;
+      }
+      
+      if(verbose)
+        std::cout << "[USRP_SERVER] Received SPI write\n";
+    }
+    
+    //--------- SPI READ -----------//
+    if(pmt_eq(subp_cmd, s_op_spi_read)) {
+      
+      long urid     = pmt_to_long(pmt_nth(0, subp_data));
+      long enables  = pmt_to_long(pmt_nth(1, subp_data));
+      long format   = pmt_to_long(pmt_nth(2, subp_data));
+      long opt      = pmt_to_long(pmt_nth(3, subp_data));
+      long n_bytes  = pmt_to_long(pmt_nth(4, subp_data));
+      
+      long srid;
+      if((srid = next_rid()) == -1)
+        goto subpkt_bail;
+
+      d_rids[srid].owner = port->port_symbol();
+      d_rids[srid].user_rid = urid;
+
+      // Make the USB packet
+      if(!pkt->cs_spi_read(srid, enables, format, opt, n_bytes))
+      {
+        d_cs_usrp->send(s_cmd_usrp_write, 
+                        pmt_list3(invocation_handle, 
+                                  pmt_from_long(channel), 
+                                  v_packet));
+        
+        // Return the rid
+        d_rids[srid].owner = PMT_NIL;
+
+        goto new_packet;
+      }
+      
+      if(verbose)
+        std::cout << "[USRP_SERVER] Received SPI read\n";
+    }
+
+  subpkt_bail:
+    curr_subpkt++;
+
+  }
+
+
+  // If the current packets length is > 0, we know there are subpackets that
+  // need to be sent out still.
+  if(pkt->payload_len() > 0)
+    d_cs_usrp->send(s_cmd_usrp_write, 
+                    pmt_list3(invocation_handle, 
+                              pmt_from_long(channel), 
+                              v_packet));
+
+  return;
+}
+
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is a
+ * command to start reading samples from the USRP (cmd-start-recv-raw-samples).  
+ *
+ * The \p port the command was sent on and the channel info (\p chan_info) of
+ * the channel are passed to ensure that the caller owns the channel.
+ *
+ * The \p data parameter should be in the format of a cmd-start-recv-raw-samples
+ * command where the first element in the list is an invocation handle, and the
+ * second is the channel the signal generator wants to receive the samples on.
+ */
+void
+usrp_server::handle_cmd_start_recv_raw_samples(
+                                  mb_port_sptr port, 
+                                  std::vector<struct channel_info> &chan_info, 
+                                  pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  long channel = pmt_to_long(pmt_nth(1, data));
+
+  // Ensure the channel is valid and the caller owns the port
+  if(!check_valid(port, channel, chan_info,
+                  pmt_list2(s_response_xmit_raw_frame, invocation_handle)))
+    return;
+
+  // Already started receiving samples? (another start before a stop)
+  // Check the RX channel bitmask.
+  if(d_rx_chan_mask & (1 << channel)) {
+    port->send(s_response_recv_raw_samples,
+               pmt_list5(invocation_handle,
+                         s_err_already_receiving,
+                         PMT_NIL,
+                         PMT_NIL,
+                         PMT_NIL));
+    return;
+  }
+
+  // We only need to generate a 'start reading' command down to the
+  // low level interface if no other channel is already reading
+  //
+  // We carry this over the CS interface because the lower level
+  // interface does not care about the channel, we only demux it
+  // at the usrp_server on responses.
+  if(d_rx_chan_mask == 0) {
+    
+    if(verbose)
+      std::cout << "[USRP_SERVER] Sending read request down to start recv\n";
+
+    d_cs_usrp->send(s_cmd_usrp_start_reading, pmt_list1(invocation_handle));
+  }
+
+  d_rx_chan_mask |= 1<<channel;
+  
+  return;
+}
+
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is to
+ * stop receiving samples from the USRP (cmd-stop-recv-raw-samples).
+ *
+ * The \p port the command was sent on and the channel info (\p chan_info) of
+ * the channel are passed to ensure that the caller owns the channel.
+ *
+ * The \p data parameter should be in the format of a cmd-stop-recv-raw-samples
+ * command where the first element in the list is an invocation handle, and the
+ * second is the channel the signal generator wants to stop receiving the
+ * samples from.
+ */
+void
+usrp_server::handle_cmd_stop_recv_raw_samples(
+                        mb_port_sptr port, 
+                        std::vector<struct channel_info> &chan_info, 
+                        pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  long channel = pmt_to_long(pmt_nth(1, data));
+
+  // FIX ME : we have no responses to send an error...
+  // Ensure the channel is valid and the caller owns the port
+  //if(!check_valid(port, channel, chan_info,
+  //                pmt_list2(s_response_xmit_raw_frame, invocation_handle)))
+  //  return;
+
+  // Remove this hosts bit from the receiver mask
+  d_rx_chan_mask &= ~(1<<channel);
+
+  // We only need to generate a 'start reading' command down to the
+  // low level interface if no other channel is already reading
+  //
+  // We carry this over the CS interface because the lower level
+  // interface does not care about the channel, we only demux it
+  // at the usrp_server on responses.
+  if(d_rx_chan_mask == 0) {
+    
+    if(verbose)
+      std::cout << "[USRP_SERVER] Sending stop reading request down\n";
+
+    d_cs_usrp->send(s_cmd_usrp_stop_reading, pmt_list1(invocation_handle));
+  }
+  
+  return;
+}
+
+/*!
+ * \brief Called by the handle_message() method when an incoming signal is
+ * generated to USRP server that contains raw samples from the USRP.  This
+ * method generates the response-recv-raw-samples signals that are the result of
+ * a cmd-start-recv-raw-samples signal.
+ *
+ * The raw lower-level packet is extracted from \p data, where the format for \p
+ * data is a PMT list.  The PMT \p data list should contain an invocation handle
+ * as the first element, the status of the lower-level read as the second
+ * element, and a uniform vector representation of the packets as the third
+ * element.  
+ *
+ * The packet contains a channel field that the samples are destined to, and the
+ * method determines where to send the samples based on this channel since each
+ * channel has an associated port which allocated it.
+ */
+void
+usrp_server::handle_response_usrp_read(pmt_t data)
+{
+
+  pmt_t invocation_handle = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+  pmt_t v_pkt = pmt_nth(2, data);
+
+  size_t n_bytes;
+  size_t ignore;
+
+  if (d_fake_rx) {
+
+    pmt_t pkt = pmt_nth(2, data);
+
+    d_rx[0]->send(s_response_recv_raw_samples,
+                  pmt_list5(PMT_F,
+                            PMT_T,
+                            pkt,
+                            pmt_from_long(0xffff),
+                            PMT_NIL));
+
+    return;
+  }
+
+  // Extract the packet and return appropriately
+  transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, n_bytes);
+
+  // The channel is used to find the port to pass the samples on
+  long channel = pkt->chan();
+  long payload_len = pkt->payload_len();
+  long port;
+
+  // Ignore packets which seem to have incorrect size or size 0
+  if(payload_len > pkt->max_payload() || payload_len == 0)
+    return;
+  
+  // If the packet is a C/S packet, parse it separately
+  if(channel == CONTROL_CHAN) {
+    parse_control_pkt(invocation_handle, pkt);
+    return;
+  }
+
+  if((port = rx_port_index(d_chaninfo_rx[channel].owner)) == -1)
+    return; // Don't know where to send the sample... possibility on abrupt close
+    
+  pmt_t v_samples = pmt_make_u8vector(payload_len, 0);
+  uint8_t *samples = pmt_u8vector_writable_elements(v_samples, ignore);
+  
+  memcpy(samples, pkt->payload(), payload_len);
+
+  // Build a properties dictionary to store things such as the RSSI
+  pmt_t properties =  pmt_make_dict();
+
+  pmt_dict_set(properties,
+               pmt_intern("rssi"),
+               pmt_from_long(pkt->rssi()));
+
+  if(pkt->overrun())
+    pmt_dict_set(properties,
+                 pmt_intern("overrun"),
+                 PMT_T);
+
+  if(pkt->underrun())
+    pmt_dict_set(properties,
+                 pmt_intern("underrun"),
+                 PMT_T);
+
+  d_rx[port]->send(s_response_recv_raw_samples,
+                   pmt_list6(invocation_handle,
+                             status,
+                             v_samples,
+                             pmt_from_long(pkt->timestamp()),
+                             pmt_from_long(channel),
+                             properties));
+  return;
+}
+
+/*!
+ * \brief Called by handle_response_usrp_read() when the incoming packet has a
+ * channel of CONTROL_CHAN.  This means that the incoming packet contains a
+ * response for a command sent to the control channel, which this method will
+ * parse.
+ *
+ * The \p pkt parameter is a pointer to the full packet (transport_pkt) in
+ * memory.
+ *
+ * Given that all commands sent to the control channel that require responses
+ * will carry an RID (request ID), the method will use the RID passed back with
+ * the response to determine which port the response should be sent on.
+ */
+void
+usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt)
+{
+
+  long payload_len = pkt->payload_len();
+  long curr_payload = 0;
+  long port;
+  
+  // We dispatch based on the control packet type, however we can extract the
+  // opcode and the length immediately which is consistent in all responses.
+  //
+  // Since each control packet can have multiple responses, we keep reading the
+  // lengths of each subpacket until we reach the payload length.  
+  while(curr_payload < payload_len) {
+
+    pmt_t sub_packet = pkt->read_subpacket(curr_payload);
+    pmt_t op_symbol = pmt_nth(0, sub_packet);
+
+    int len = pkt->cs_len(curr_payload);
+
+    if(verbose)
+      std::cout << "[USRP_SERVER] Parsing subpacket " 
+                << op_symbol << " ... length " << len << std::endl;
+
+    //----------------- PING RESPONSE ------------------//
+    if(pmt_eq(op_symbol, s_op_ping_fixed_reply)) {
+
+      long srid     = pmt_to_long(pmt_nth(1, sub_packet));
+      pmt_t pingval = pmt_nth(2, sub_packet);
+
+      long urid = d_rids[srid].user_rid;
+      
+      if(verbose)
+        std::cout << "[USRP_SERVER] Found ping response "
+                  << "("
+                  << "URID: " << urid << ", "
+                  << "SRID: " << srid << ", "
+                  << "VAL: " << pingval 
+                  << ")\n";
+      
+      // Do some bounds checking incase of bogus/corrupt responses
+      if(srid > D_MAX_RID)
+        return;
+
+      pmt_t owner = d_rids[srid].owner;
+      
+      // Return the RID
+      d_rids[srid].owner = PMT_NIL;
+
+      // FIXME: should be 1 response for all subpackets here ?
+      if((port = tx_port_index(owner)) != -1)
+        d_tx[port]->send(s_response_from_control_channel,
+                         pmt_list4(invocation_handle,
+                                   PMT_T,
+                                   pmt_list2(s_op_ping_fixed_reply, // subp
+                                             pmt_list2(pmt_from_long(urid), 
+                                                       pingval)),
+                                   pmt_from_long(pkt->timestamp())));
+    }
+    
+    //----------------- READ REG RESPONSE ------------------//
+    else if(pmt_eq(op_symbol, s_op_read_reg_reply)) {
+
+      long srid     = pmt_to_long(pmt_nth(1, sub_packet));
+      pmt_t reg_num = pmt_nth(2, sub_packet);
+      pmt_t reg_val = pmt_nth(3, sub_packet);
+
+      long urid = d_rids[srid].user_rid;
+      
+      if(verbose)
+        std::cout << "[USRP_SERVER] Found read register response "
+                  << "("
+                  << "URID: " << urid << ", "
+                  << "SRID: " << srid << ", "
+                  << "REG: " << reg_num << ", "
+                  << "VAL: " << reg_val 
+                  << ")\n";
+
+      // Do some bounds checking to avoid seg faults
+      if(srid > D_MAX_RID)
+        return;
+      
+      pmt_t owner = d_rids[srid].owner;
+      
+      // Return the RID
+      d_rids[srid].owner = PMT_NIL;
+
+      // FIXME: should be 1 response for all subpackets here ?
+      if((port = tx_port_index(owner)) != -1)
+        d_tx[port]->send(s_response_from_control_channel,
+                         pmt_list4(invocation_handle,
+                                   PMT_T,
+                                   pmt_list2(s_op_read_reg_reply, // subp
+                                             pmt_list3(pmt_from_long(urid), 
+                                                       reg_num, 
+                                                       reg_val)),
+                                   pmt_from_long(pkt->timestamp())));
+    }
+
+    //------------------ I2C READ REPLY -------------------//
+    else if(pmt_eq(op_symbol, s_op_i2c_read_reply)) {
+
+      long srid       = pmt_to_long(pmt_nth(1, sub_packet));
+      pmt_t i2c_addr  = pmt_nth(2, sub_packet);
+      pmt_t i2c_data  = pmt_nth(3, sub_packet);
+
+      long urid = d_rids[srid].user_rid;
+
+      if(verbose)
+        std::cout << "[USRP_SERVER] Found i2c read reply "
+                  << "("
+                  << "URID: " << urid << ", "
+                  << "SRID: " << srid << ", "
+                  << "Addr: " << i2c_addr << ", "
+                  << "Data: " << i2c_data
+                  << ")\n";
+      
+      // Do some bounds checking to avoid seg faults
+      if(srid > D_MAX_RID)
+        return;
+
+      pmt_t owner = d_rids[srid].owner;
+      
+      // Return the RID
+      d_rids[srid].owner = PMT_NIL;
+
+      if((port = tx_port_index(owner)) != -1)
+        d_tx[port]->send(s_response_from_control_channel,
+                         pmt_list4(invocation_handle,
+                                   PMT_T,
+                                   pmt_list2(s_op_i2c_read_reply,
+                                             pmt_list3(pmt_from_long(urid), 
+                                                       i2c_addr,
+                                                       i2c_data)),
+                                   pmt_from_long(pkt->timestamp())));
+    }
+
+    //------------------ SPI READ REPLY -------------------//
+    else if(pmt_eq(op_symbol, s_op_spi_read_reply)) {
+      
+      long srid       = pmt_to_long(pmt_nth(1, sub_packet));
+      pmt_t spi_data  = pmt_nth(2, sub_packet);
+      
+      long urid = d_rids[srid].user_rid;
+
+      if(verbose)
+        std::cout << "[USRP_SERVER] Found SPI read reply "
+                  << "("
+                  << "URID: " << urid << ", "
+                  << "SRID: " << srid << ", "
+                  << "Data: " << spi_data
+                  << ")\n";
+
+      // Bounds check the RID
+      if(srid > D_MAX_RID)
+        return;
+
+      pmt_t owner = d_rids[srid].owner;
+      
+      // Return the RID
+      d_rids[srid].owner = PMT_NIL;
+
+      if((port = tx_port_index(owner)) != -1)
+        d_tx[port]->send(s_response_from_control_channel,
+                         pmt_list4(invocation_handle,
+                                   PMT_T,
+                                   pmt_list2(s_op_spi_read_reply,
+                                             pmt_list2(pmt_from_long(urid), 
+                                                       spi_data)),
+                                   pmt_from_long(pkt->timestamp())));
+    }
+
+    // Each subpacket has an unaccounted for 2 bytes which is the opcode
+    // and the length field
+    curr_payload += len + 2;
+    
+    // All subpackets are 32-bit aligned
+    int align_offset = 4 - (curr_payload % 4);
+
+    if(align_offset != 4)
+      curr_payload += align_offset;
+  }
+}
+
+/*!
+ * \brief Used to recall all incoming signals that were deferred when USRP
+ * server was in the initialization state.
+ */
+void
+usrp_server::recall_defer_queue()
+{
+
+  std::vector<mb_message_sptr> recall;
+
+  while(!d_defer_queue.empty()) {
+    recall.push_back(d_defer_queue.front());
+    d_defer_queue.pop();
+  }
+
+  // Parse the messages that were queued while waiting for an open response
+  for(int i=0; i < (int)recall.size(); i++) 
+    handle_message(recall[i]);
+
+  return;
+}
+
+/*!
+ * \brief Commonly called by any method which handles outgoing frames or control
+ * packets to the USRP to check if the port on which the signal was sent owns
+ * the channel the outgoing packet will be associated with.   This helps ensure
+ * that applications do not send data on other application's ports.
+ *
+ * The \p port parameter is the port symbol that the caller wishes to determine
+ * owns the channel specified by \p chan_info.  
+ *
+ * The \p signal_info parameter is a PMT list containing two elements: the
+ * response signal to use if the permissions are invalid, and the invocation
+ * handle that was passed.  This allows the method to generate detailed failure
+ * responses to signals without having to return some sort of structured
+ * information which the caller must then parse and interpret to determine the
+ * failure type.
+ *
+ * \returns true if \p port owns the channel specified by \p chan_info, false
+ * otherwise.
+ */
+bool
+usrp_server::check_valid(mb_port_sptr port,
+                         long channel,
+                         std::vector<struct channel_info> &chan_info,
+                         pmt_t signal_info)
+{
+
+  pmt_t response_signal = pmt_nth(0, signal_info);
+  pmt_t invocation_handle = pmt_nth(1, signal_info);
+
+  // not a valid channel number?
+  if(channel >= (long)chan_info.size() && channel != CONTROL_CHAN) {
+    port->send(response_signal, 
+               pmt_list2(invocation_handle, 
+                         s_err_channel_invalid));
+
+    if(verbose)
+      std::cout << "[USRP_SERVER] Invalid channel number for event " 
+                << response_signal << std::endl;
+    return false;
+  }
+  
+  // not the owner of the port?
+  if(chan_info[channel].owner != port->port_symbol()) {
+    port->send(response_signal, 
+               pmt_list2(invocation_handle, 
+                         s_err_channel_permission_denied));
+    
+    if(verbose)
+      std::cout << "[USRP_SERVER] Invalid permissions"
+                << " for " << response_signal
+                << " from " << port->port_symbol()
+                << " proper owner is " << chan_info[channel].owner
+                << " on channel " << channel
+                << " invocation " << invocation_handle
+                << std::endl;
+    return false;
+  }
+
+  return true;
+}
+
+/*!
+ * \brief Finds the next available RID for internal USRP server use with control
+ * and status packets.
+ *
+ * \returns the next valid RID or -1 if no more RIDs are available.
+ */
+long
+usrp_server::next_rid()
+{
+  for(int i = 0; i < D_MAX_RID; i++)
+    if(pmt_eqv(d_rids[i].owner, PMT_NIL))
+      return i;
+
+  if(verbose)
+    std::cout << "[USRP_SERVER] No RIDs left\n";
+  return -1;
+}
+
+/*!
+ * \brief Called by handle_message() when USRP server gets a response that the
+ * USRP was opened successfully to initialize the registers using the new
+ * register read/write control packets.
+ */
+void
+usrp_server::initialize_registers()
+{
+  // We use handle_cmd_to_control_channel() to create the register writes using
+  // PMT_NIL as the response port to tell usrp_server not to pass the response
+  // up to any application.
+  if(verbose)
+    std::cout << "[USRP_SERVER] Initializing registers...\n";
+
+  // RX mode to normal (0)
+  set_register(FR_MODE, 0);
+
+  // FPGA debugging?
+  if(d_fpga_debug) {
+    set_register(FR_DEBUG_EN, 1);
+    // FIXME: need to figure out exact register writes to control daughterboard
+    // pins that need to be written to
+  } else {
+    set_register(FR_DEBUG_EN, 0);
+  }
+
+  // Set the transmit sample rate divisor, which is 4-1
+  set_register(FR_TX_SAMPLE_RATE_DIV, 3);
+
+  // Dboard IO buffer and register settings
+  set_register(FR_OE_0, (0xffff << 16) | 0x0000);
+  set_register(FR_IO_0, (0xffff << 16) | 0x0000);
+  set_register(FR_OE_1, (0xffff << 16) | 0x0000);
+  set_register(FR_IO_1, (0xffff << 16) | 0x0000);
+  set_register(FR_OE_2, (0xffff << 16) | 0x0000);
+  set_register(FR_IO_2, (0xffff << 16) | 0x0000);
+  set_register(FR_OE_3, (0xffff << 16) | 0x0000);
+  set_register(FR_IO_3, (0xffff << 16) | 0x0000);
+
+  // zero Tx side Auto Transmit/Receive regs
+  set_register(FR_ATR_MASK_0, 0); 
+  set_register(FR_ATR_TXVAL_0, 0);
+  set_register(FR_ATR_RXVAL_0, 0);
+  set_register(FR_ATR_MASK_1, 0); 
+  set_register(FR_ATR_TXVAL_1, 0);
+  set_register(FR_ATR_RXVAL_1, 0);
+  set_register(FR_ATR_MASK_2, 0);
+  set_register(FR_ATR_TXVAL_2, 0);
+  set_register(FR_ATR_RXVAL_2, 0);
+  set_register(FR_ATR_MASK_3, 0);
+  set_register(FR_ATR_TXVAL_3, 0);
+  set_register(FR_ATR_RXVAL_3, 0);
+
+  // Configure TX mux, this is a hacked value
+  set_register(FR_TX_MUX, 0x00000081);
+
+  // Set the interpolation rate, which is the rate divided by 4, minus 1
+  set_register(FR_INTERP_RATE, (d_interp_tx/4)-1);
+
+  // Apparently this register changes again
+  set_register(FR_TX_MUX, 0x00000981);
+
+  // Set the receive sample rate divisor, which is 2-1
+  set_register(FR_RX_SAMPLE_RATE_DIV, 1);
+
+  // DC offset
+  set_register(FR_DC_OFFSET_CL_EN, 0x0000000f);
+
+  // Reset the DC correction offsets
+  set_register(FR_ADC_OFFSET_0, 0);
+  set_register(FR_ADC_OFFSET_1, 0);
+
+  // Some hard-coded RX configuration
+  set_register(FR_RX_FORMAT, 0x00000300);
+  set_register(FR_RX_MUX, 1);
+
+  // RX decimation rate is divided by two, then subtract 1
+  set_register(FR_DECIM_RATE, (d_decim_rx/2)-1);
+
+  // More hard coding
+  set_register(FR_RX_MUX, 0x000e4e41);
+
+  // Resetting RX registers
+  set_register(FR_RX_PHASE_0, 0);
+  set_register(FR_RX_PHASE_1, 0);
+  set_register(FR_RX_PHASE_2, 0);
+  set_register(FR_RX_PHASE_3, 0);
+  set_register(FR_RX_FREQ_0, 0x28000000);
+  set_register(FR_RX_FREQ_1, 0);
+  set_register(FR_RX_FREQ_2, 0);
+  set_register(FR_RX_FREQ_3, 0);
+
+  // Enable debug bus
+  set_register(FR_DEBUG_EN, 0xf);
+  set_register(FR_OE_0, -1);
+  set_register(FR_OE_1, -1);
+  set_register(FR_OE_2, -1);
+  set_register(FR_OE_3, -1);
+
+  // DEBUGGING
+  //check_register_initialization();
+}
+
+// FIXME: used for debugging to determine if all the registers are actually
+// being set correctly
+void
+usrp_server::check_register_initialization()
+{
+  // RX mode to normal (0)
+  read_register(FR_MODE);
+
+  // FPGA debugging?
+  if(d_fpga_debug) {
+    read_register(FR_DEBUG_EN);
+    // FIXME: need to figure out exact register writes to control daughterboard
+    // pins that need to be written to
+  } else {
+    read_register(FR_DEBUG_EN);
+  }
+
+  // Set the transmit sample rate divisor, which is 4-1
+  read_register(FR_TX_SAMPLE_RATE_DIV);
+
+  // Dboard IO buffer and register settings
+  read_register(FR_OE_0);
+  read_register(FR_IO_0);
+  read_register(FR_OE_1);
+  read_register(FR_IO_1);
+  read_register(FR_OE_2);
+  read_register(FR_IO_2);
+  read_register(FR_OE_3);
+  read_register(FR_IO_3);
+
+  // zero Tx side Auto Transmit/Receive regs
+  read_register(FR_ATR_MASK_0); 
+  read_register(FR_ATR_TXVAL_0);
+  read_register(FR_ATR_RXVAL_0);
+  read_register(FR_ATR_MASK_1); 
+  read_register(FR_ATR_TXVAL_1);
+  read_register(FR_ATR_RXVAL_1);
+  read_register(FR_ATR_MASK_2);
+  read_register(FR_ATR_TXVAL_2);
+  read_register(FR_ATR_RXVAL_2);
+  read_register(FR_ATR_MASK_3);
+  read_register(FR_ATR_TXVAL_3);
+  read_register(FR_ATR_RXVAL_3);
+
+  // Configure TX mux, this is a hacked value
+  read_register(FR_TX_MUX);
+
+  // Set the interpolation rate, which is the rate divided by 4, minus 1
+  read_register(FR_INTERP_RATE);
+
+  // Apparently this register changes again
+  read_register(FR_TX_MUX);
+
+  // Set the receive sample rate divisor, which is 2-1
+  read_register(FR_RX_SAMPLE_RATE_DIV);
+
+  // DC offset
+  read_register(FR_DC_OFFSET_CL_EN);
+
+  // Reset the DC correction offsets
+  read_register(FR_ADC_OFFSET_0);
+  read_register(FR_ADC_OFFSET_1);
+
+  // Some hard-coded RX configuration
+  read_register(FR_RX_FORMAT);
+  read_register(FR_RX_MUX);
+
+  // RX decimation rate is divided by two, then subtract 1
+  read_register(FR_DECIM_RATE);
+
+  // More hard coding
+  read_register(FR_RX_MUX);
+
+  // Resetting RX registers
+  read_register(FR_RX_PHASE_0);
+  read_register(FR_RX_PHASE_1);
+  read_register(FR_RX_PHASE_2);
+  read_register(FR_RX_PHASE_3);
+  read_register(FR_RX_FREQ_0);
+  read_register(FR_RX_FREQ_1);
+  read_register(FR_RX_FREQ_2);
+  read_register(FR_RX_FREQ_3);
+}
+
+/*!
+ * \brief Used to generate FPGA register write commands to reset all of the FPGA
+ * registers to a value of 0.
+ */
+void
+usrp_server::reset_all_registers()
+{
+  for(int i=0; i<64; i++)
+    set_register(i, 0);
+}
+
+/*!
+ * \brief Used internally by USRP server to generate a control/status packet
+ * which contains a register write.
+ *
+ * The \p reg parameter is the register number that the value \p val will be
+ * written to.
+ */
+void
+usrp_server::set_register(long reg, long val)
+{
+  size_t psize;
+  long payload_len = 0;
+
+  pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0);
+  transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_packet, psize);
+  
+  pkt->set_header(0, CONTROL_CHAN, 0, payload_len);
+  pkt->set_timestamp(0xffffffff);
+
+  pkt->cs_write_reg(reg, val);
+
+  d_cs_usrp->send(s_cmd_usrp_write, 
+                  pmt_list3(PMT_NIL, 
+                            pmt_from_long(CONTROL_CHAN), 
+                            v_packet));
+}
+
+/*!
+ * \brief Used internally by USRP server to generate a control/status packet
+ * which contains a register read.  This is important to use internally so that
+ * USRP server can bypass the use of RIDs with register reads, as they are not
+ * needed and it would use up the finite number of RIDs available for use for
+ * applications to receive responses.
+ *
+ * The \p reg parameter is the register number that the value should be read
+ * from.
+ */
+void
+usrp_server::read_register(long reg)
+{
+  size_t psize;
+  long payload_len = 0;
+
+  pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0);
+  transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_packet, psize);
+  
+  pkt->set_header(0, CONTROL_CHAN, 0, payload_len);
+  pkt->set_timestamp(0xffffffff);
+
+  pkt->cs_read_reg(0, reg);
+
+  d_cs_usrp->send(s_cmd_usrp_write, 
+                  pmt_list3(PMT_NIL, 
+                            pmt_from_long(CONTROL_CHAN), 
+                            v_packet));
+}
+
+REGISTER_MBLOCK_CLASS(usrp_server);
diff --git a/usrp/limbo/inband/usrp_server.h b/usrp/limbo/inband/usrp_server.h
new file mode 100644 (file)
index 0000000..dd1825d
--- /dev/null
@@ -0,0 +1,131 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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_SERVER_H
+#define INCLUDED_USRP_SERVER_H
+
+#include <mblock/mblock.h>
+#include <vector>
+#include <queue>
+#include <fstream>
+#include <usrp_inband_usb_packet.h>
+
+typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit easy
+
+/*!
+ * \brief Implements the lowest-level mblock usb_interface to the USRP
+ */
+class usrp_server : public mb_mblock
+{
+public:
+
+  // our ports
+  enum port_types {
+    RX_PORT = 0,
+    TX_PORT = 1
+  };
+  static const int N_PORTS = 4;
+  std::vector<mb_port_sptr> d_tx, d_rx;
+  mb_port_sptr d_cs;
+  mb_port_sptr d_cs_usrp;
+
+  static const int D_USB_CAPACITY = 32 * 1024 * 1024;
+  static const int D_MAX_CHANNELS = 16;
+  long d_ntx_chan;
+  long d_nrx_chan;
+
+  pmt_t d_usrp_dict;
+
+  bool d_fpga_debug;
+  
+  long d_interp_tx;
+  long d_decim_rx;
+
+  // Keep track of the request IDs
+  struct rid_info {
+    pmt_t owner;
+    long user_rid;
+
+    rid_info() {
+      owner = PMT_NIL;
+      user_rid = 0;
+    }
+  };
+
+  static const long D_MAX_RID = 64;
+  std::vector<rid_info> d_rids;
+  
+  struct channel_info {
+    long assigned_capacity;   // the capacity currently assignedby the channel
+    pmt_t owner;              // port ID of the owner of the channel
+
+    channel_info() {
+      assigned_capacity = 0;
+      owner = PMT_NIL;
+    }
+  };
+
+  long d_rx_chan_mask;    // A bitmask representing the channels in the
+                          // receiving state
+
+  std::vector<struct channel_info> d_chaninfo_tx;
+  std::vector<struct channel_info> d_chaninfo_rx;
+
+  std::queue<mb_message_sptr> d_defer_queue;
+
+  bool d_defer;
+  bool d_opened;
+
+  bool d_fake_rx;
+
+public:
+  usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg);
+  ~usrp_server();
+
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+protected:
+  static int max_capacity() { return D_USB_CAPACITY; }
+
+private:
+  void handle_cmd_allocate_channel(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data);
+  void handle_cmd_deallocate_channel(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data);
+  void handle_cmd_xmit_raw_frame(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data);
+  void handle_cmd_to_control_channel(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data);
+  void handle_cmd_start_recv_raw_samples(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data);
+  void handle_cmd_stop_recv_raw_samples(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data);
+  int rx_port_index(pmt_t port_id);
+  int tx_port_index(pmt_t port_id);
+  long current_capacity_allocation();
+  void recall_defer_queue();
+  void reset_channels();
+  void handle_response_usrp_read(pmt_t data);
+  bool check_valid(mb_port_sptr port, long channel, std::vector<struct channel_info> &chan_info, pmt_t signal_info);
+  void parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt);
+  long next_rid();
+  void initialize_registers();
+  void set_register(long reg, long val);
+  void read_register(long reg);
+  void check_register_initialization();
+  void reset_all_registers();
+};
+
+#endif /* INCLUDED_USRP_SERVER_H */
diff --git a/usrp/limbo/inband/usrp_server.mbh b/usrp/limbo/inband/usrp_server.mbh
new file mode 100644 (file)
index 0000000..ed7943f
--- /dev/null
@@ -0,0 +1,255 @@
+;; -*- scheme -*- ; not really, but tells emacs how to format this
+;;
+;; 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 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.
+;;
+
+;; ----------------------------------------------------------------
+;;              This is an mblock header file
+;;
+;; The format is very much a work-in-progress.
+;; It'll be compiled to C++.
+;; ----------------------------------------------------------------
+
+;; In the outgoing messages described below, invocation-handle is an
+;; identifier provided by the client to tag the method invocation.
+;; The identifier will be returned with the response, to provide the
+;; client with a mechanism to match asynchronous responses with the
+;; commands that generate them.  The value of the invocation-handle is
+;; opaque the the server, and is not required by the server to be
+;; unique.
+;;
+;; In the incoming messages described below, invocation-handle is the
+;; identifier provided by the client in the prompting invocation.  The
+;; identifier is returned with the response, so that the client has a
+;; mechanism to match asynchronous responses with the commands that
+;; generated them.
+;;
+;; status is either #t, indicating success, or a symbol indicating an error.
+;; All symbol's names shall begin with %error-
+
+
+;; ----------------------------------------------------------------
+;; usrp-channel
+;;
+;; The protocol class is defined from the client's point-of-view.
+;; (The client port is unconjugated, the server port is conjugated.)
+
+(define-protocol-class usrp-channel
+
+  (:outgoing
+
+   (cmd-allocate-channel invocation-handle capacity-reservation)
+
+   ;; The cmd-allocate-channel message requests that the server
+   ;; allocates a logical channel in the FPGA for use.
+   ;; capacity-reservation specifies the number of bytes/s of
+   ;; interconnect capacity (USB or ethernet) to reserve for this
+   ;; channel.  (The reservation is just a sanity check, no OS
+   ;; specific mechanism is used.)
+
+   (cmd-deallocate-channel invocation-handle channel)
+
+   ;; The integer channel specifies the channel to deallocate.
+
+   )
+
+  (:incoming
+
+
+   (response-allocate-channel invocation-handle status channel)
+
+   ;; If successful, a channel the specified capacity was allocated.
+   ;; channel, an integer, indicates which channel was allocated.
+
+   (response-deallocate-channel invocation-handle status)
+
+   ;; If successful, the specified channel and associated interconnect
+   ;; capacity were deallocated.
+
+   )
+  )
+
+;; ----------------------------------------------------------------
+;; usrp-low-level-cs
+;;
+;; The protocol class is defined from the client's point-of-view.
+;; (The client port is unconjugated, the server port is conjugated.)
+;;
+;; This defines a low level control and status interface to the usrp.
+;; This will probably be replaced (or at least augmented) with a
+;; higher level interface.  For now, this will allow us to get on
+;; the air.
+;;
+;; The subpackets are lists containing the relevant parameters.  The
+;; server will marshall them appropriately.  Below is a list of
+;; subpackets.  See inband-signaling-usb for details.  The opcodes are
+;; symbols; unless otherwise indicated the remaining parameters are
+;; integers.  rid values are limited to 3-bits.
+;;
+;;   (op-ping-fixed rid ping-value)
+;;   (op-ping-fixed-reply rid ping-value)
+;;   (op-write-reg reg-number reg-value)
+;;   (op-write-reg-masked reg-number reg-value mask-value)
+;;   (op-read-reg rid reg-number)
+;;   (op-read-reg-reply rid reg-number reg-value)
+;;   (op-i2c-write i2c-addr u8-vec)
+;;   (op-i2c-read rid i2c-addr nbytes)
+;;   (op-i2c-read-reply rid i2c-addr u8-vec)
+;;   (op-spi-write enables format opt-header-bytes u8-vec)
+;;   (op-spi-read rid enables format opt-header-bytes nbytes)
+;;   (op-spi-read-reply rid u8-vec)
+;;   (op-delay ticks)
+
+
+(define-protocol-class usrp-low-level-cs
+
+  (:outgoing
+
+   (cmd-to-control-channel invocation-handle list-of-subpackets)
+
+   )
+
+  (:incoming
+
+   (response-from-control-channel invocation-handle status list-of-subpackets timestamp)
+
+   )
+  )
+
+;; ----------------------------------------------------------------
+;; usrp-tx
+;;
+;; The protocol class is defined from the client's point-of-view.
+;; (The client port is unconjugated, the server port is conjugated.)
+
+(define-protocol-class usrp-tx
+  (:include usrp-channel)
+  (:include usrp-low-level-cs)
+
+  (:outgoing
+
+   (cmd-xmit-raw-frame invocation-handle channel samples timestamp properties)
+
+   ;; The argument channel must be an integer.  It specifies the
+   ;; channel on which the frame of samples will be be sent.
+   ;;
+   ;; samples must be a uniform numeric vector.  The contents of the
+   ;; sample vector is treated as opaque and is passed on to the FPGA
+   ;; unmodified.  It is the responsibility of the sender to ensure
+   ;; that the binary format is sensible for the current FPGA
+   ;; configuration.
+   ;;
+   ;; timestamp is a 32-bit integer that specifies the time at which
+   ;; the first sample in samples shall be sent to the D/A converter.
+   ;; The format and interpration of time is specified in the file
+   ;; inband-signaling-usb
+   )
+
+  (:incoming
+
+   (response-xmit-raw-frame invocation-handle status)
+
+   ;; If successful, the samples of the associated frame have been
+   ;; transmitted to the USRP.  This message may be used to implement
+   ;; Tx flow control.  The client could for example implement a
+   ;; policy of never having more than 4 unacknowledged
+   ;; cmd-xmit-raw-frame's outstanding.
+
+   )
+  )
+
+;; ----------------------------------------------------------------
+;; usrp-rx
+;;
+;; The protocol class is defined from the client's point-of-view.
+;; (The client port is unconjugated, the server port is conjugated.)
+
+(define-protocol-class usrp-rx
+  (:include usrp-channel)
+  (:include usrp-low-level-cs)
+
+  (:outgoing
+
+   (cmd-start-recv-raw-samples invocation-handle channel)
+
+   ;; The argument channel must be an integer.  It specifies the
+   ;; channel from which frames of samples will be be received.  The
+   ;; server will return response-recv-raw-samples messages until a
+   ;; cmd-stop-recv-raw-samples message is received.
+
+   (cmd-stop-recv-raw-samples invocation-handle channel)
+
+   ;; The argument channel must be an integer.  There is no reply to
+   ;; this message.
+   
+   )
+
+  (:incoming
+
+   (response-recv-raw-samples invocation-handle status samples timestamp channel properties)
+
+   ;; samples is a uniform numeric vector.  The contents of the sample
+   ;; vector is treated as opaque and is passed from the FPGA
+   ;; unmodified.  It is the responsibility of the receiver to decode
+   ;; the binary format as appropriate for the current FPGA
+   ;; configuration.
+   ;;
+   ;; timestamp is a 32-bit integer that specifies the time at which
+   ;; the first sample in samples was received from the A/D converter.
+   ;; The format and interpretation of time is as specified in the
+   ;; file inband-signaling-usb.
+   ;;
+   ;; properties is a dictionary containing additional (key, value)
+   ;; pairs associated with the reception of these samples.  In
+   ;; particular, the map may contain the Received Signal Strength
+   ;; Indication (RSSI) reported by the front end at the time the
+   ;; first sample was received from the A/D.
+
+   )
+  )
+
+
+;; ----------------------------------------------------------------
+;; usrp-server-cs
+;;
+;; Control and status port for usrp-server
+;;
+;; The protocol class is defined from the client's point-of-view.
+;; (The client port is unconjugated, the server port is conjugated.)
+
+(define-protocol-class usrp-server-cs
+
+  (:outgoing
+   (cmd-open invocation-handle which-usrp)
+   (cmd-close invocation-handle)
+   (cmd-max-capacity invocation-handle)
+   (cmd-ntx-chan invocation-handle)
+   (cmd-nrx-chan invocation-handle)
+   (cmd-current-capacity-allocation invocation-handle)
+   )
+
+  (:incoming
+   (response-open invocation-handle status)
+   (response-close invocation-handle status)
+   (response-max-capacity invocation-handle status capacity)
+   (response-ntx-chan invocation-handle status ntx-chan)
+   (response-nrx-chan invocation-handle status nrx-chan)
+   (response-current-capacity-allocation invocation-handle status capacity)
+   )
+  )
diff --git a/usrp/limbo/inband/usrp_tx.cc b/usrp/limbo/inband/usrp_tx.cc
new file mode 100644 (file)
index 0000000..0d4a846
--- /dev/null
@@ -0,0 +1,150 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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_tx.h>
+#include <iostream>
+#include <usb.h>
+#include <mblock/class_registry.h>
+#include <usrp_inband_usb_packet.h>
+#include <fpga_regs_common.h>
+#include <usrp_standard.h>
+#include <stdio.h>
+
+#include <symbols_usrp_tx_cs.h>
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+static const bool verbose = false;
+
+usrp_tx::usrp_tx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(rt, instance_name, user_arg),
+    d_disk_write(false)
+{
+  d_cs = define_port("cs", "usrp-tx-cs", true, mb_port::EXTERNAL);
+  
+  //d_disk_write=true;
+  
+  if(d_disk_write) {
+    d_ofile.open("tx_data.dat",std::ios::binary|std::ios::out);
+    d_cs_ofile.open("tx_cs.dat",std::ios::binary|std::ios::out);
+  }
+}
+
+usrp_tx::~usrp_tx() 
+{
+  if(d_disk_write) {
+    d_ofile.close();
+    d_cs_ofile.close();
+  }
+}
+
+void 
+usrp_tx::initial_transition()
+{
+  
+}
+
+/*!
+ * \brief Handles incoming signals to to the m-block, wihch should only ever be
+ * a single message: cmd-usrp-tx-write.
+ */
+void
+usrp_tx::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();
+  pmt_t port_id = msg->port_id();
+  pmt_t data = msg->data(); 
+
+  // Theoretically only have 1 message to ever expect, but
+  // want to make sure its at least what we want
+  if(pmt_eq(port_id, d_cs->port_symbol())) {
+    
+    if(pmt_eqv(event, s_cmd_usrp_tx_write))
+      write(data);
+  }
+}
+
+/*!
+ * \brief Performs the actual writing of data to the USB bus, called by
+ * handle_message() when a cmd-usrp-tx-write signal is received.
+ *
+ * The \p data parameter is a PMT list which contains three mandatory elements,
+ * in the following order: an invocation handle, a channel, and a uniform vector
+ * of memory which contains the packets to be written to the bus.
+ */
+void
+usrp_tx::write(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  pmt_t channel = pmt_nth(1, data);
+  pmt_t v_packets = pmt_nth(2, data);
+  d_utx = boost::any_cast<usrp_standard_tx_sptr>(pmt_any_ref(pmt_nth(3, data)));
+
+  size_t n_bytes;
+  bool underrun;  // this will need to go, as it is taken care of in the packet headers
+
+  transport_pkt *pkts = (transport_pkt *) pmt_u8vector_writable_elements(v_packets, n_bytes);
+
+  int ret = d_utx->write (pkts, n_bytes, &underrun);
+  
+  if (0 && underrun)
+    fprintf(stderr, "uU");
+
+  if (ret == (int) n_bytes) {
+    if (verbose)
+      std::cout << "[usrp_server] Write of " << n_bytes << " successful\n";
+    // need to respond with the channel so the USRP server knows who to forward the result of
+    // the write to by looking up the owner of the channel
+    d_cs->send(s_response_usrp_tx_write,
+              pmt_list3(invocation_handle, PMT_T, channel));
+  }
+  else {
+    if (verbose)
+      std::cout << "[usrp_server] Error writing " << n_bytes << " bytes to USB bus\n";
+    d_cs->send(s_response_usrp_tx_write,
+              pmt_list3(invocation_handle, PMT_F, channel));
+  }
+    
+  long n_packets = 
+    static_cast<long>(std::ceil(n_bytes / (double)transport_pkt::max_pkt_size()));
+
+  for(int i=0; i < n_packets; i++) {
+    
+    if(d_disk_write) {
+      if(pkts[i].chan() == CONTROL_CHAN)
+        d_cs_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size());
+      else
+        d_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size());
+
+      d_cs_ofile.flush();
+      d_ofile.flush();
+    }
+  }
+
+
+  return;
+}
+
+REGISTER_MBLOCK_CLASS(usrp_tx);
diff --git a/usrp/limbo/inband/usrp_tx.h b/usrp/limbo/inband/usrp_tx.h
new file mode 100644 (file)
index 0000000..d3a6f8b
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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_TX_H
+#define INCLUDED_USRP_TX_H
+
+#include <mblock/mblock.h>
+#include <fstream>
+#include "usrp_standard.h"
+
+/*!
+ * \brief Implements the low level usb interface to the USRP
+ */
+class usrp_tx : public mb_mblock
+{
+  mb_port_sptr         d_cs;
+  usrp_standard_tx_sptr     d_utx;
+  
+  bool d_disk_write;
+  std::ofstream d_ofile;
+  std::ofstream d_cs_ofile;
+  
+ public:
+  usrp_tx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg);
+  ~usrp_tx();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ private:
+  void write(pmt_t data);
+};
+  
+
+#endif /* INCLUDED_USRP_TX_H */
+
diff --git a/usrp/limbo/inband/usrp_tx_stub.cc b/usrp/limbo/inband/usrp_tx_stub.cc
new file mode 100644 (file)
index 0000000..c78b1a7
--- /dev/null
@@ -0,0 +1,344 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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 <iostream>
+#include <vector>
+#include <usb.h>
+#include <mblock/class_registry.h>
+#include <usrp_tx_stub.h>
+#include <usrp_inband_usb_packet.h>
+#include <fpga_regs_common.h>
+#include "usrp_standard.h"
+#include <stdio.h>
+#include <fstream>
+#include <usrp_rx_stub.h>
+
+#include <symbols_usrp_tx_cs.h>
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+static const bool verbose = false;
+
+usrp_tx_stub::usrp_tx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(rt, instance_name, user_arg),
+    d_disk_write(false)
+{
+  d_cs = define_port("cs", "usrp-tx-cs", true, mb_port::EXTERNAL);
+  
+  //d_disk_write=true;
+  
+  if(d_disk_write) {
+    d_ofile.open("tx_stub_data.dat",std::ios::binary|std::ios::out);
+    d_cs_ofile.open("tx_stub_cs.dat",std::ios::binary|std::ios::out);
+  }
+}
+
+usrp_tx_stub::~usrp_tx_stub() 
+{
+  if(d_disk_write) {
+    d_ofile.close();
+    d_cs_ofile.close();
+  }
+}
+
+void 
+usrp_tx_stub::initial_transition()
+{
+  
+}
+
+void
+usrp_tx_stub::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();
+  pmt_t port_id = msg->port_id();
+  pmt_t data = msg->data(); 
+
+  // Theoretically only have 1 message to ever expect, but
+  // want to make sure its at least what we want
+  if(pmt_eq(port_id, d_cs->port_symbol())) {
+    
+    if(pmt_eqv(event, s_cmd_usrp_tx_write)) 
+      write(data);
+  }
+}
+
+void
+usrp_tx_stub::write(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  pmt_t channel = pmt_nth(1, data);
+  pmt_t v_packets = pmt_nth(2, data);
+  d_utx = boost::any_cast<usrp_standard_tx *>(pmt_any_ref(pmt_nth(3, data)));
+
+  size_t n_bytes;
+
+  transport_pkt *pkts = (transport_pkt *) pmt_u8vector_writable_elements(v_packets, n_bytes);
+  long n_packets = static_cast<long>(std::ceil(n_bytes / (double)transport_pkt::max_pkt_size()));
+  
+  // Parse the packets looking for C/S packets and dump them to a disk if
+  // necessary
+  for(long i=0; i<n_packets; i++) {
+
+    if(d_disk_write) {
+      if(pkts[i].chan() == CONTROL_CHAN)
+        d_cs_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size());
+      else
+        d_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size());
+
+      d_cs_ofile.flush();
+      d_ofile.flush();
+    }
+
+    if(pkts[i].chan() == CONTROL_CHAN)
+      parse_cs(invocation_handle, pkts[i]);
+  }
+
+  d_cs->send(s_response_usrp_tx_write,
+       pmt_list3(invocation_handle, PMT_T, channel));
+
+  return;
+}
+
+void
+usrp_tx_stub::parse_cs(pmt_t invocation_handle, transport_pkt pkt)
+{
+  
+  long payload_len = pkt.payload_len();
+  long curr_payload = 0;
+      
+  size_t ignore;
+
+  // There is the possibility that the responses for a single USB packet full of
+  // CS packets will not fit back in a single USB packet, considering some
+  // responses are greater than their commands (read registers).
+ new_packet:
+  pmt_t v_pkt = pmt_make_u8vector(sizeof(transport_pkt), 0);
+  
+  transport_pkt *q_pkt =
+    (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, ignore);
+      
+  q_pkt->set_header(0, CONTROL_CHAN, 0, 0);
+  q_pkt->set_timestamp(0xffffffff);
+
+  // We dispatch based on the control packet type, however we can extract the
+  // opcode and the length immediately which is consistent in all responses.
+  //
+  // Since each control packet can have multiple responses, we keep reading the
+  // lengths of each subpacket until we reach the payload length.  
+  while(curr_payload < payload_len) {
+
+    pmt_t sub_packet = pkt.read_subpacket(curr_payload);
+    pmt_t op_symbol = pmt_nth(0, sub_packet);
+
+    int len = pkt.cs_len(curr_payload);
+      
+    if(verbose)
+      std::cout << "[USRP_TX_STUB] Parsing subpacket " 
+                << op_symbol << " ... length " << len << std::endl;
+
+    //----------------- PING FIXED ------------------//
+    if(pmt_eq(op_symbol, s_op_ping_fixed)) {
+
+      long rid = pmt_to_long(pmt_nth(1, sub_packet));
+      long pingval = pmt_to_long(pmt_nth(2, sub_packet));
+
+      // Generate a reply and put it in the queue for the RX stub to read
+      if(!q_pkt->cs_ping_reply(rid, pingval))
+        goto new_packet;
+
+      if(verbose)
+        std::cout << "[USRP_TX_STUB] Generated ping response "
+                  << "("
+                  << "RID: " << rid << ", "
+                  << "VAL: " << pingval 
+                  << ")\n";
+    }
+
+    //----------------- READ REG ------------------//
+    if(pmt_eq(op_symbol, s_op_read_reg)) {
+
+      long rid = pmt_to_long(pmt_nth(1, sub_packet));
+      long reg_num = pmt_to_long(pmt_nth(2, sub_packet));
+      long reg_val = 0xdeef;
+
+      // Generate a reply and put it in the queue for the RX stub to read
+      if(!q_pkt->cs_read_reg_reply(rid, reg_num, reg_val))
+        goto new_packet;
+
+      if(verbose)
+        std::cout << "[USRP_TX_STUB] Generated read register response "
+                  << "("
+                  << "RID: " << rid << ", "
+                  << "REG: " << reg_num << ", "
+                  << "VAL: " << reg_val
+                  << ")\n";
+    }
+    
+    //----------------- DELAY ------------------//
+    if(pmt_eq(op_symbol, s_op_delay)) {
+
+      long ticks = pmt_to_long(pmt_nth(1, sub_packet));
+
+      if(verbose)
+        std::cout << "[USRP_TX_STUB] Received delay command "
+                  << "("
+                  << "Ticks: " << ticks
+                  << ")\n";
+    }
+
+    //----------------- WRITE REG ------------------//
+    if(pmt_eq(op_symbol, s_op_write_reg)) {
+
+      pmt_t reg_num = pmt_nth(1, sub_packet);
+      pmt_t reg_val = pmt_nth(2, sub_packet);
+
+      if(verbose)
+        std::cout << "[USRP_TX_STUB] Received write register command "
+                  << "("
+                  << "RegNum: " << reg_num << ", "
+                  << "Val: " << reg_val
+                  << ")\n";
+    }
+    
+    //----------------- WRITE REG MASK ---------------//
+    if(pmt_eq(op_symbol, s_op_write_reg_masked)) {
+
+      pmt_t reg_num = pmt_nth(1, sub_packet);
+      pmt_t reg_val = pmt_nth(2, sub_packet);
+      pmt_t mask    = pmt_nth(3, sub_packet);
+
+      if(verbose)
+        std::cout << "[USRP_TX_STUB] Received write register command "
+                  << "("
+                  << "RegNum: " << reg_num << ", "
+                  << "Val: " << reg_val << ", "
+                  << "Mask: " << mask
+                  << ")\n";
+    }
+
+    //---------------- I2C WRITE ------------------//
+    if(pmt_eq(op_symbol, s_op_i2c_write)) {
+      pmt_t i2c_addr  = pmt_nth(1, sub_packet);
+      pmt_t i2c_data  = pmt_nth(2, sub_packet);
+
+      if(verbose)
+        std::cout << "[USRP_TX_STUB] Received i2c write command "
+                  << "("
+                  << "Addr: " << i2c_addr << ", "
+                  << "Data: " << i2c_data
+                  << ")\n";
+    }
+
+    //---------------- I2C READ ------------------//
+    if(pmt_eq(op_symbol, s_op_i2c_read)) {
+      long rid       = pmt_to_long(pmt_nth(1, sub_packet));
+      long i2c_addr  = pmt_to_long(pmt_nth(2, sub_packet));
+      long i2c_bytes = pmt_to_long(pmt_nth(3, sub_packet));
+
+      // Create data to place as a response, filled with 0xff
+      size_t ignore;
+      pmt_t i2c_data = pmt_make_u8vector(i2c_bytes, 0xff);
+      uint8_t *w_data = (uint8_t *) pmt_u8vector_writable_elements(i2c_data, ignore);
+
+      // Generate a reply and put it in the queue for the RX stub to read
+      if(!q_pkt->cs_i2c_read_reply(rid, i2c_addr, w_data, i2c_bytes))
+        goto new_packet;
+
+      if(verbose)
+        std::cout << "[USRP_TX_STUB] Received i2c read "
+                  << "("
+                  << "RID: " << rid << ", "
+                  << "Addr: " << i2c_addr << ", "
+                  << "Bytes: " << i2c_bytes
+                  << ")\n";
+    }
+    
+    //---------------- SPI WRITE ------------------//
+    if(pmt_eq(op_symbol, s_op_spi_write)) {
+      long enables  = pmt_to_long(pmt_nth(1, sub_packet));
+      long format   = pmt_to_long(pmt_nth(2, sub_packet));
+      long opt      = pmt_to_long(pmt_nth(3, sub_packet));
+      pmt_t data    = pmt_nth(4, sub_packet);
+
+      if(verbose)
+        std::cout << "[USRP_TX_STUB] Received spi write command "
+                  << "("
+                  << "Enables: " << enables << ", "
+                  << "Format: " << format << ", "
+                  << "Options: " << opt << ", "
+                  << "Data: " << data
+                  << ")\n";
+    }
+
+    //---------------- SPI READ ------------------//
+    if(pmt_eq(op_symbol, s_op_spi_read)) {
+      long rid      = pmt_to_long(pmt_nth(1, sub_packet));
+      long enables  = pmt_to_long(pmt_nth(2, sub_packet));
+      long format   = pmt_to_long(pmt_nth(3, sub_packet));
+      long opt      = pmt_to_long(pmt_nth(4, sub_packet));
+      long n_bytes  = pmt_to_long(pmt_nth(5, sub_packet));
+
+      // Create data to place as a fake response
+      size_t ignore;
+      pmt_t spi_data = pmt_make_u8vector(n_bytes, 0xff);
+      uint8_t *w_data = (uint8_t *) pmt_u8vector_writable_elements(spi_data, ignore);
+
+      // Generate a reply and put it in the queue for the RX stub to read
+      if(!q_pkt->cs_spi_read_reply(rid, w_data, n_bytes))
+        goto new_packet;
+
+      if(verbose)
+        std::cout << "[USRP_TX_STUB] Received spi read command "
+                  << "("
+                  << "RID: " << rid << ", "
+                  << "Enables: " << enables << ", "
+                  << "Format: " << format << ", "
+                  << "Options: " << opt << ", "
+                  << "Bytes: " << n_bytes
+                  << ")\n";
+      
+    }
+
+    // Each subpacket has an unaccounted for 2 bytes which is the opcode
+    // and the length field
+    curr_payload += len + 2;
+
+    // All subpackets are 32-bit aligned
+    int align_offset = 4 - (curr_payload % 4);
+
+    if(align_offset != 4)
+      curr_payload += align_offset;
+
+  }
+
+  // If the packet has data in the payload, it needs queued
+  if(q_pkt->payload_len() > 0)
+    d_cs_queue.push(pmt_list2(invocation_handle, v_pkt));
+
+  return;
+}
+
+REGISTER_MBLOCK_CLASS(usrp_tx_stub);
diff --git a/usrp/limbo/inband/usrp_tx_stub.h b/usrp/limbo/inband/usrp_tx_stub.h
new file mode 100644 (file)
index 0000000..b81037a
--- /dev/null
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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_TX_STUB_H
+#define INCLUDED_USRP_TX_STUB_H
+
+#include <mblock/mblock.h>
+#include <vector>
+#include "usrp_standard.h"
+#include <fstream>
+#include <usrp_inband_usb_packet.h>
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+/*!
+ * \brief Implements the low level usb interface to the USRP
+ */
+class usrp_tx_stub : public mb_mblock
+{
+ public:
+
+  mb_port_sptr d_cs;
+  usrp_standard_tx* d_utx;
+  
+  std::ofstream d_ofile;
+  std::ofstream d_cs_ofile;
+
+  bool d_disk_write;
+
+ public:
+  usrp_tx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg);
+  ~usrp_tx_stub();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ private:
+  void write(pmt_t data);
+  void parse_cs(pmt_t invocation_handle, transport_pkt pkt);
+};
+  
+
+#endif /* INCLUDED_USRP_TX_STUB_H */
+
diff --git a/usrp/limbo/inband/usrp_usb_interface.cc b/usrp/limbo/inband/usrp_usb_interface.cc
new file mode 100644 (file)
index 0000000..fb7109a
--- /dev/null
@@ -0,0 +1,601 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008,2009 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_usb_interface.h>
+
+#include <iostream>
+#include <vector>
+#include <usb.h>
+#include <mblock/class_registry.h>
+#include <usrp_inband_usb_packet.h>
+#include <fpga_regs_common.h>
+#include "usrp_rx.h"
+#include <usrp_rx_stub.h>
+#include "usrp_tx.h"
+#include "usrp_standard.h"
+#include <stdio.h>
+#include <usrp_dbid.h>
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+#include <symbols_usrp_interface_cs.h>
+#include <symbols_usrp_tx_cs.h>
+#include <symbols_usrp_rx_cs.h>
+static pmt_t s_shutdown = pmt_intern("%shutdown");
+
+static const bool verbose = false;
+
+
+/*!
+ * \brief Initializes the USB interface m-block.
+ *
+ * The \p user_arg should be a PMT dictionary which can contain optional
+ * arguments for the block, such as the decimatoin and interpolation rate.
+ */
+usrp_usb_interface::usrp_usb_interface(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(rt, instance_name, user_arg),
+  d_fake_usrp(false),
+  d_rx_reading(false),
+  d_interp_tx(128),
+  d_decim_rx(128),
+  d_rf_freq(-1),
+  d_rbf("inband_tx_rx.rbf")
+{
+  // Dictionary for arguments to all of the components
+  pmt_t usrp_dict = user_arg;
+  
+  // Default TX/RX interface
+  std::string tx_interface = "usrp_tx";
+  std::string rx_interface = "usrp_rx";
+  
+  if (pmt_is_dict(usrp_dict)) {
+
+    // The 'fake-usrp' key enables the TX and RX stubs if PMT_T
+    if(pmt_t fake_usrp = pmt_dict_ref(usrp_dict, 
+                                      pmt_intern("fake-usrp"), 
+                                      PMT_NIL)) {
+      if(pmt_eqv(fake_usrp, PMT_T)) {
+        tx_interface = "usrp_tx_stub";
+        rx_interface = "usrp_rx_stub";
+        d_fake_usrp=true;
+      }
+    }
+
+    // Read the TX interpolations
+    if(pmt_t interp_tx = pmt_dict_ref(usrp_dict, 
+                                      pmt_intern("interp-tx"), 
+                                      PMT_NIL)) {
+      if(!pmt_eqv(interp_tx, PMT_NIL)) 
+        d_interp_tx = pmt_to_long(interp_tx);
+    }
+    
+    // Read the RX decimation rate
+    if(pmt_t decim_rx = pmt_dict_ref(usrp_dict, 
+                                      pmt_intern("decim-rx"), 
+                                      PMT_NIL)) {
+      if(!pmt_eqv(decim_rx, PMT_NIL)) 
+        d_decim_rx = pmt_to_long(decim_rx);
+    }
+
+    // Read the RBF
+    if(pmt_t rbf = pmt_dict_ref(usrp_dict, 
+                                pmt_intern("rbf"), 
+                                PMT_NIL)) {
+      if(!pmt_eqv(rbf, PMT_NIL)) 
+        d_rbf = pmt_symbol_to_string(rbf);
+    }
+
+    // The RF center frequency
+    if(pmt_t rf_freq = pmt_dict_ref(usrp_dict, 
+                                pmt_intern("rf-freq"), 
+                                PMT_NIL)) {
+      if(!pmt_eqv(rf_freq, PMT_NIL)) 
+        d_rf_freq = pmt_to_double(rf_freq);
+    }
+  }
+  
+  if (verbose) {
+    std::cout << "[USRP_USB_INTERFACE] Setting USRP RBF to " 
+              << d_rbf << std::endl;
+    
+    std::cout << "[USRP_USB_INTERFACE] Setting TX interpolation to " 
+              << d_interp_tx << std::endl;
+          
+    std::cout << "[USRP_USB_INTERFACE] Setting RX interpolation to " 
+              << d_decim_rx << std::endl;
+
+    std::cout << "[USRP_USB_INTERFACE] Using TX interface: " 
+              << tx_interface << "\n";
+
+    std::cout << "[USRP_USB_INTERFACE] Using RX interface: " 
+              << rx_interface << "\n";
+
+  }
+
+  d_cs = define_port("cs", "usrp-interface-cs", true, mb_port::EXTERNAL);      
+  d_rx_cs = define_port("rx_cs", "usrp-rx-cs", false, mb_port::INTERNAL);      
+  d_tx_cs = define_port("tx_cs", "usrp-tx-cs", false, mb_port::INTERNAL);      
+
+  // Connect to TX and RX
+  define_component("tx", tx_interface, usrp_dict);
+  define_component("rx", rx_interface, usrp_dict);
+  connect("self", "rx_cs", "rx", "cs");
+  connect("self", "tx_cs", "tx", "cs");
+  
+  // FIXME: the code should query the FPGA to retrieve the number of channels and such
+  d_ntx_chan = 2;
+  d_nrx_chan = 2;
+}
+
+usrp_usb_interface::~usrp_usb_interface() 
+{ 
+
+}
+
+void 
+usrp_usb_interface::initial_transition()
+{
+
+}
+
+/*!
+ * \brief Handles all incoming signals to the block from the lowest m-blocks
+ * which read/write to the bus, or the higher m-block which is the USRP server.
+ */
+void
+usrp_usb_interface::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();         // the "name" of the message
+  pmt_t port_id = msg->port_id();      // which port it came in on
+  pmt_t data = msg->data();
+  pmt_t invocation_handle;
+
+  if (pmt_eq(event, s_shutdown))       // ignore (for now)
+    return;
+
+  //------------- CONTROL / STATUS -------------//
+  if (pmt_eq(port_id, d_cs->port_symbol())) {  
+
+    //------------ OPEN --------------//
+    if (pmt_eq(event, s_cmd_usrp_open)){
+      handle_cmd_open(data);
+      return;
+    }
+    //----------- CLOSE -------------//
+    else if (pmt_eq(event, s_cmd_usrp_close)) {
+      handle_cmd_close(data);
+      return;
+    }
+    //---------- NTX CHAN ----------//
+    else if (pmt_eq(event, s_cmd_usrp_ntx_chan)) {
+      invocation_handle = pmt_nth(0, data);
+      d_cs->send(s_response_usrp_ntx_chan, 
+                 pmt_list2(invocation_handle, 
+                           pmt_from_long(d_ntx_chan)));
+      return;
+    }
+    //---------- NRX CHAN ----------//
+    else if (pmt_eq(event, s_cmd_usrp_nrx_chan)) {
+      invocation_handle = pmt_nth(0, data);
+      d_cs->send(s_response_usrp_nrx_chan, 
+                 pmt_list2(invocation_handle, 
+                           pmt_from_long(d_nrx_chan)));
+      return;
+    }
+    //------------ WRITE -----------//
+    else if(pmt_eq(event, s_cmd_usrp_write)) {
+      handle_cmd_write(data);
+      return;
+    }
+    //-------- START READING --------//
+    else if(pmt_eq(event, s_cmd_usrp_start_reading)) {
+      handle_cmd_start_reading(data);
+      return;
+    }
+    //-------- STOP READING --------//
+    else if(pmt_eq(event, s_cmd_usrp_stop_reading)) {
+      handle_cmd_stop_reading(data);
+      return;
+    }
+
+    goto unhandled;
+  }
+
+  //---------------- RX ------------------//
+  if (pmt_eq(port_id, d_rx_cs->port_symbol())) {       
+
+    // Relay reads back up
+    if(pmt_eq(event, s_response_usrp_rx_read))  {
+      d_cs->send(s_response_usrp_read, data);
+      return;
+    }
+
+    goto unhandled;
+  }
+  
+  //---------------- TX ------------------//
+  if (pmt_eq(port_id, d_tx_cs->port_symbol())) {       
+
+    if(pmt_eq(event, s_response_usrp_tx_write))  {
+
+      pmt_t invocation_handle = pmt_nth(0, data);
+      pmt_t status = pmt_nth(1, data);
+      pmt_t channel = pmt_nth(2, data);
+
+      d_cs->send(s_response_usrp_write,
+                 pmt_list3(invocation_handle,
+                           status,
+                           channel));
+
+      return;
+    }
+
+    goto unhandled;
+  }
+
+ unhandled:
+  std::cout << "[USRP_USB_INTERFACE] unhandled msg: " << msg << std::endl;
+}
+
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is to
+ * open a USB connection to the USRP (cmd-usrp-open).
+ *
+ * The \p data parameter is a PMT list, where the elements are an invocation
+ * handle and the USRP number.
+ */
+void
+usrp_usb_interface::handle_cmd_open(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  long which_usrp = pmt_to_long(pmt_nth(1, data));
+  pmt_t reply_data;
+  if(d_fake_usrp) {
+    d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T));
+    return;
+  }
+
+  if (verbose)
+    std::cout << "[USRP_USB_INTERFACE] Handling open request for USRP " << which_usrp << "\n";
+
+  // Open up a standard RX and TX for communication with the USRP
+   
+  d_utx = usrp_standard_tx::make(which_usrp,
+                                d_interp_tx,
+                                1,                     // 1 channel
+                                -1,          // mux
+                                4096,        // USB block size
+                                16,          // nblocks for async transfers
+                                d_rbf
+                                );
+  
+  if(d_utx==0) {
+    if (verbose)
+      std::cout << "[USRP_USB_INTERFACE] Failed to open TX\n";
+    reply_data = pmt_list2(invocation_handle, PMT_F);
+    d_cs->send(s_response_usrp_open, reply_data);
+    return;
+  }
+
+  // Perform TX daughterboard tuning
+  double target_freq;
+  unsigned int mux;
+  int tgain, rgain;
+  float input_rate;
+  bool ok;
+  usrp_tune_result r;
+
+  // Cast to usrp_basic and then detect daughterboards
+  d_ub_tx = d_utx;
+  usrp_subdev_spec tspec = pick_tx_subdevice();
+  db_base_sptr tsubdev = d_ub_tx->selected_subdev(tspec);
+
+  // Set the TX mux value
+  mux = d_utx->determine_tx_mux_value(tspec);
+  d_utx->set_mux(mux);
+  
+  // Set the TX gain and determine rate
+  tgain = tsubdev->gain_max();
+  tsubdev->set_gain(tgain);
+  input_rate = d_ub_tx->converter_rate() / d_utx->interp_rate();
+
+  // Perform the actual tuning, if no frequency specified then pick
+  if(d_rf_freq==-1)
+    target_freq = tsubdev->freq_min()+((tsubdev->freq_max()-tsubdev->freq_min())/2.0);
+  else 
+    target_freq = d_rf_freq;
+  ok = d_utx->tune(tsubdev->which(), tsubdev, target_freq, &r);
+  tsubdev->set_enable(true);
+  
+  if(verbose) {
+    printf("TX Subdevice name is %s\n", tsubdev->name().c_str());
+    printf("TX Subdevice freq range: (%g, %g)\n",
+       tsubdev->freq_min(), tsubdev->freq_max());
+    printf("mux: %#08x\n",  mux);
+    printf("target_freq:     %f\n", target_freq);
+    printf("ok:              %s\n", ok ? "true" : "false");
+    printf("gain:            %d\n", tgain);
+    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);
+  }
+
+  if(!ok) {
+    std::cerr << "[USRP_USB_INTERFACE] Failed to set center frequency on TX\n";
+    reply_data = pmt_list2(invocation_handle, PMT_F);
+    d_cs->send(s_response_usrp_open, reply_data);
+    return;
+  }
+
+  d_utx->start();
+
+  if (verbose)
+    std::cout << "[USRP_USB_INTERFACE] Setup TX channel\n";
+
+  d_urx =
+    usrp_standard_rx::make (which_usrp,
+                           d_decim_rx,         
+                           1,                  // nchan
+                           -1,           // mux
+                           0,            // set blank mode to start
+                           4096,         // USB block size
+                           16,           // number of blocks for async transfers
+          d_rbf);
+
+  if(!d_urx) {
+    if (verbose)
+      std::cout << "[usrp_server] Failed to open RX\n";
+    reply_data = pmt_list2(invocation_handle, PMT_F);
+    d_cs->send(s_response_usrp_open, reply_data);
+    return;
+  }
+  
+  // Cast to usrp_basic and then detect daughterboards
+  d_ub_rx = d_urx;
+  usrp_subdev_spec rspec = pick_rx_subdevice();
+  db_base_sptr rsubdev = d_ub_rx->selected_subdev(rspec);
+
+  // Set the RX mux value
+  mux = d_urx->determine_rx_mux_value(rspec);
+  d_urx->set_mux(mux);
+  
+  // Set the RX gain and determine rate
+  rgain = rsubdev->gain_max()/2.0;
+  rsubdev->set_gain(rgain);
+  input_rate = d_ub_rx->converter_rate() / d_urx->decim_rate();
+
+  ok = d_urx->tune(rsubdev->which(), rsubdev, target_freq, &r);
+  rsubdev->set_enable(true);
+  
+  if(verbose) {
+    printf("RX Subdevice name is %s\n", rsubdev->name().c_str());
+    printf("RX Subdevice freq range: (%g, %g)\n",
+       rsubdev->freq_min(), rsubdev->freq_max());
+    printf("mux: %#08x\n",  mux);
+    printf("target_freq:     %f\n", target_freq);
+    printf("ok:              %s\n", ok ? "true" : "false");
+    printf("gain:            %d\n", rgain);
+    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);
+  }
+  
+  if(!ok) {
+    std::cerr << "[USRP_USB_INTERFACE] Failed to set center frequency on RX\n";
+    reply_data = pmt_list2(invocation_handle, PMT_F);
+    d_cs->send(s_response_usrp_open, reply_data);
+    return;
+  }
+
+  if (verbose)
+    std::cout << "[USRP_USB_INTERFACE] Setup RX channel\n";
+    
+//  d_utx->_write_fpga_reg(FR_DEBUG_EN,0xf);
+//  d_utx->_write_oe(0, 0xffff, 0xffff);
+//  d_urx->_write_oe(0, 0xffff, 0xffff);
+//  d_utx->_write_oe(1, 0xffff, 0xffff);
+//  d_urx->_write_oe(1, 0xffff, 0xffff);
+
+  d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T));
+}
+
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is to
+ * write data to the USB bus (cmd-usrp-write). 
+ *
+ * The \p data parameter is a PMT list containing 3 mandatory elements in the
+ * following order: an invocation handle, channel, and a uniform vector
+ * representation of the packets.
+ */
+void
+usrp_usb_interface::handle_cmd_write(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  pmt_t channel = pmt_nth(1, data);
+  pmt_t pkts = pmt_nth(2, data);
+
+  pmt_t tx_handle = pmt_make_any(d_utx);
+
+  d_tx_cs->send(s_cmd_usrp_tx_write, 
+                pmt_list4(invocation_handle, 
+                          channel,
+                          pkts,
+                          tx_handle));
+}
+
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is to
+ * start reading data from the USB bus (cmd-usrp-start-reading).
+ *
+ * The \p data parameter is a PMT list with a single element: an invocation
+ * handle which can be returned with the response.
+ */
+void
+usrp_usb_interface::handle_cmd_start_reading(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  
+  if(verbose)
+    std::cout << "[USRP_USB_INTERFACE] Starting RX...\n";
+
+  if(!d_fake_usrp)
+    d_urx->start();
+
+  pmt_t rx_handle = pmt_make_any(d_urx);
+
+  d_rx_cs->send(s_cmd_usrp_rx_start_reading, pmt_list2(PMT_NIL, rx_handle));
+
+  d_rx_reading = true;
+
+  return;
+}
+
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is to
+ * stop reading data from the USB bus (cmd-usrp-stop-reading).
+ *
+ * The \p data parameter is a PMT list with a single element: an invocation
+ * handle which can be returned with the response.
+ */
+void
+usrp_usb_interface::handle_cmd_stop_reading(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  
+  if(!d_fake_usrp) {
+    if(verbose)
+      std::cout << "[USRP_USB_INTERFACE] Stopping RX...\n";
+    usrp_rx_stop = true;
+
+    // Used to allow a read() being called by a lower layer to complete before
+    // stopping, else there can be partial data left on the bus and can generate
+    // errors.
+    while(usrp_rx_stop) {usleep(1);}
+    d_urx->stop();
+  }
+  else {
+    if(verbose)
+      std::cout << "[USRP_USB_INTERFACE] Stopping fake RX...\n";
+    usrp_rx_stop_stub = true;  // extern to communicate with stub to wait
+  }
+
+  d_rx_reading = false;
+
+  return;
+}
+
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is to
+ * close the USB connection to the USRP.
+ *
+ * The \p data parameter is a PMT list with a single element: an invocation
+ * handle which can be returned with the response.
+ */
+void
+usrp_usb_interface::handle_cmd_close(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+
+  if(d_rx_reading)
+    handle_cmd_stop_reading(PMT_NIL);
+
+  if(d_fake_usrp) {
+    d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T));
+    return;
+  }
+  
+  if (verbose)
+    std::cout << "[USRP_USB_INTERFACE] Handling close request for USRP\n";
+
+  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);
+}
+
+usrp_subdev_spec
+usrp_usb_interface::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_BASIC_RX
+  };
+
+  std::vector<int> candidates(dbids, dbids+(sizeof(dbids)/sizeof(int)));
+  return pick_subdev(d_ub_rx, candidates);
+}
+
+usrp_subdev_spec
+usrp_usb_interface::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(d_ub_tx, candidates);
+}
+
+usrp_subdev_spec
+usrp_usb_interface::pick_subdev(boost::shared_ptr<usrp_basic> d_usrp_basic, std::vector<int> candidates)
+{
+  int dbid0 = d_usrp_basic->selected_subdev(usrp_subdev_spec(0, 0))->dbid();
+  int dbid1 = d_usrp_basic->selected_subdev(usrp_subdev_spec(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!");
+}
+
+
+REGISTER_MBLOCK_CLASS(usrp_usb_interface);
diff --git a/usrp/limbo/inband/usrp_usb_interface.h b/usrp/limbo/inband/usrp_usb_interface.h
new file mode 100644 (file)
index 0000000..4d7750a
--- /dev/null
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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_USB_INTERFACE_H
+#define INCLUDED_USRP_USB_INTERFACE_H
+
+#include <mblock/mblock.h>
+#include <vector>
+#include "usrp_standard.h"
+
+/*!
+ * \brief Implements the low level usb interface to the USRP
+ */
+class usrp_usb_interface : public mb_mblock
+{
+ public:
+
+  usrp_standard_tx_sptr d_utx;
+  usrp_standard_rx_sptr d_urx;
+
+  boost::shared_ptr<usrp_basic> d_ub_tx;
+  boost::shared_ptr<usrp_basic> d_ub_rx;
+  
+  mb_port_sptr d_cs;
+  mb_port_sptr  d_rx_cs;
+  mb_port_sptr  d_tx_cs;
+  
+  long d_ntx_chan;
+  long d_nrx_chan;
+
+  bool d_fake_usrp;
+
+  bool d_rx_reading;
+
+  long d_interp_tx;
+  long d_decim_rx;
+
+  double d_rf_freq;
+
+  std::string d_rbf;
+
+ public:
+  usrp_usb_interface(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg);
+  ~usrp_usb_interface();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+  usrp_subdev_spec pick_rx_subdevice();
+  usrp_subdev_spec pick_tx_subdevice();
+  usrp_subdev_spec pick_subdev(boost::shared_ptr<usrp_basic> d_usrp_basic, std::vector<int> candidates);
+
+ private:
+  void handle_cmd_open(pmt_t data);
+  void handle_cmd_close(pmt_t data);
+  void handle_cmd_write(pmt_t data);
+  void handle_cmd_start_reading(pmt_t data);
+  void handle_cmd_stop_reading(pmt_t data);
+};
+  
+
+#endif /* INCLUDED_USRP_USB_INTERFACE_H */
diff --git a/usrp/usrp-inband.pc.in b/usrp/usrp-inband.pc.in
deleted file mode 100644 (file)
index 57e2746..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: usrp-inband
-Description: USRP C++ Interface with in-band signaling
-Requires: usrp pmt mblock
-Version: @VERSION@
-Libs: -L${libdir} -lusrp-inband
-Cflags: -I${includedir}