diff options
Diffstat (limited to 'usrp/host/lib')
68 files changed, 0 insertions, 18249 deletions
diff --git a/usrp/host/lib/.gitignore b/usrp/host/lib/.gitignore deleted file mode 100644 index e0e4208db..000000000 --- a/usrp/host/lib/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -/Makefile -/Makefile.in -/.la -/.lo -/.deps -/.libs -/*.la -/*.lo -/test_fusb -/std_paths.h -/usrp_dbid.py -/usrp_dbid.h -/usrp_dbid.cc -/stamp-* diff --git a/usrp/host/lib/Makefile.am b/usrp/host/lib/Makefile.am deleted file mode 100644 index 96ab55821..000000000 --- a/usrp/host/lib/Makefile.am +++ /dev/null @@ -1,194 +0,0 @@ -# -# USRP - Universal Software Radio Peripheral -# -# Copyright (C) 2003,2004,2006,2007,2008,2009,2010 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# 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) $(USB_INCLUDES) - -lib_LTLIBRARIES = libusrp.la - -libusrp_la_common_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS) $(BOOST_LDFLAGS) - -libusrp_la_common_LIBADD = \ - $(USB_LIBS) \ - $(BOOST_THREAD_LIB) \ - ../misc/libmisc.la - -# darwin fusb requires gruel (for threading) -if FUSB_TECH_darwin -AM_CPPFLAGS = $(GRUEL_INCLUDES) $(common_INCLUDES) $(BOOST_CPPFLAGS) $(WITH_INCLUDES) -libusrp_la_LIBADD = $(libusrp_la_common_LIBADD) $(GRUEL_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 \ - usrp_prims_libusb0.cc - -darwin_CODE = \ - fusb_darwin.cc \ - fusb_sysconfig_darwin.cc \ - README_OSX \ - circular_buffer.h \ - circular_linked_list.h \ - darwin_libusb.h \ - usrp_prims_libusb0.cc - - -win32_CODE = \ - fusb_win32.cc \ - fusb_sysconfig_win32.cc \ - usrp_prims_libusb0.cc - - -linux_CODE = \ - fusb_linux.cc \ - fusb_sysconfig_linux.cc \ - usrp_prims_libusb0.cc - -ra_wb_CODE = \ - fusb_ra_wb.cc \ - fusb_sysconfig_ra_wb.cc \ - usrp_prims_libusb0.cc - -libusb1_CODE = \ - fusb_libusb1.cc \ - fusb_sysconfig_libusb1.cc \ - usrp_prims_libusb1.cc - -# -# include each <foo>_CODE entry here... -# -EXTRA_libusrp_la_SOURCES = \ - $(generic_CODE) \ - $(darwin_CODE) \ - $(win32_CODE) \ - $(linux_CODE) \ - $(ra_wb_CODE) \ - $(libusb1_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_common.cc \ - usrp_standard.cc \ - db_wbxng_adf4350.cc \ - db_wbxng_adf4350_regs.cc \ - db_boards.cc \ - db_base.cc \ - db_basic.cc \ - db_bitshark_rx.cc \ - db_tv_rx.cc \ - db_tv_rx_mimo.cc \ - db_flexrf.cc \ - db_flexrf_mimo.cc \ - db_dbs_rx.cc \ - db_wbxng.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 - -if FUSB_TECH_libusb1 -libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(libusb1_CODE) -endif - - -noinst_HEADERS = \ - ad9862.h \ - db_base_impl.h \ - db_boards.h \ - db_util.h \ - db_wbxng_adf4350.h \ - db_wbxng_adf4350_regs.h \ - fusb.h \ - fusb_darwin.h \ - fusb_generic.h \ - fusb_linux.h \ - fusb_libusb1.h \ - fusb_ra_wb.h \ - fusb_win32.h \ - md5.h \ - rate_to_regval.h \ - usrp_config.h \ - usrp_primsi.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 deleted file mode 100644 index 37026f25a..000000000 --- a/usrp/host/lib/README_OSX +++ /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/ad9862.h b/usrp/host/lib/ad9862.h deleted file mode 100644 index 4375d93d8..000000000 --- a/usrp/host/lib/ad9862.h +++ /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/check_data.py b/usrp/host/lib/check_data.py deleted file mode 100755 index 100f0f6dd..000000000 --- a/usrp/host/lib/check_data.py +++ /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/circular_buffer.h b/usrp/host/lib/circular_buffer.h deleted file mode 100644 index 48758bf87..000000000 --- a/usrp/host/lib/circular_buffer.h +++ /dev/null @@ -1,315 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006,2009,2010 Free Software Foundation, Inc. - * - * This file is part of GNU Radio. - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _CIRCULAR_BUFFER_H_ -#define _CIRCULAR_BUFFER_H_ - -#include <gruel/thread.h> -#include <iostream> -#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) - size_t d_bufLen_I, d_readNdx_I, d_writeNdx_I; - size_t d_n_avail_write_I, d_n_avail_read_I; - -// stuff to control access to class internals - gruel::mutex* d_internal; - gruel::condition_variable* d_readBlock; - gruel::condition_variable* 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 (size_t 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 (std::cerr << "c_b(): buf len (items) = " << d_bufLen_ - << ", doWriteBlock = " << (d_doWriteBlock ? "true" : "false") - << ", doFullRead = " << (d_doFullRead ? "true" : "false") - << std::endl); - }; - - ~circular_buffer () { - delete_mutex_cond (); - delete [] d_buffer; - }; - - inline size_t n_avail_write_items () { - gruel::scoped_lock l (*d_internal); - size_t retVal = d_n_avail_write_I; - return (retVal); - }; - - inline size_t n_avail_read_items () { - gruel::scoped_lock l (*d_internal); - size_t retVal = d_n_avail_read_I; - return (retVal); - }; - - inline size_t 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 gruel::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 notify_one() to the condition), - // the internal mutex will be lock()'ed. - d_readBlock = new gruel::condition_variable (); - d_writeBlock = new gruel::condition_variable (); - }; - -/* - * 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, size_t bufLen_I) { - DEBUG (std::cerr << "enqueue: buf = " << (void*) buf - << ", bufLen = " << bufLen_I - << ", #av_wr = " << d_n_avail_write_I - << ", #av_rd = " << d_n_avail_read_I << std::endl); - if (bufLen_I > d_bufLen_I) { - std::cerr << "ERROR: cannot add buffer longer (" - << bufLen_I << ") than instantiated length (" - << d_bufLen_I << ")." << std::endl; - 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"); - gruel::scoped_lock l (*d_internal); - if (d_doAbort) { - 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 (std::cerr << "enqueue: #len > #a, waiting." << std::endl); - // wait; will automatically unlock() the internal mutex via - // the scoped lock - d_writeBlock->wait (l); - // and auto re-lock() it here. - if (d_doAbort) { - DEBUG (std::cerr << "enqueue: #len > #a, aborting." << std::endl); - return (2); - } - DEBUG (std::cerr << "enqueue: #len > #a, done waiting." << std::endl); - } - } else { - d_n_avail_read_I = d_bufLen_I - bufLen_I; - d_n_avail_write_I = bufLen_I; - DEBUG (std::cerr << "circular_buffer::enqueue: overflow" << std::endl); - retval = -1; - } - } - size_t 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->notify_one (); - 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, size_t* bufLen_I) { - DEBUG (std::cerr << "dequeue: buf = " << ((void*) buf) - << ", *bufLen = " << (*bufLen_I) - << ", #av_wr = " << d_n_avail_write_I - << ", #av_rd = " << d_n_avail_read_I << std::endl); - 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"); - size_t l_bufLen_I = *bufLen_I; - if (l_bufLen_I == 0) - return (0); - if (l_bufLen_I > d_bufLen_I) { - std::cerr << "ERROR: cannot remove buffer longer (" - << l_bufLen_I << ") than instantiated length (" - << d_bufLen_I << ")." << std::endl; - throw std::runtime_error ("circular_buffer::dequeue()"); - } - - gruel::scoped_lock l (*d_internal); - if (d_doAbort) { - return (2); - } - if (d_doFullRead) { - while (d_n_avail_read_I < l_bufLen_I) { - DEBUG (std::cerr << "dequeue: #a < #len, waiting." << std::endl); - // wait; will automatically unlock() the internal mutex via - // the scoped lock - d_readBlock->wait (l); - // and re-lock() it here. - if (d_doAbort) { - DEBUG (std::cerr << "dequeue: #a < #len, aborting." << std::endl); - return (2); - } - DEBUG (std::cerr << "dequeue: #a < #len, done waiting." << std::endl); - } - } else { - while (d_n_avail_read_I == 0) { - DEBUG (std::cerr << "dequeue: #a == 0, waiting." << std::endl); - // wait; will automatically unlock() the internal mutex via - // the scoped lock - d_readBlock->wait (l); - // and re-lock() it here. - if (d_doAbort) { - DEBUG (std::cerr << "dequeue: #a == 0, aborting." << std::endl); - return (2); - } - DEBUG (std::cerr << "dequeue: #a == 0, done waiting." << std::endl); - } - } - if (l_bufLen_I > d_n_avail_read_I) - l_bufLen_I = d_n_avail_read_I; - size_t 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->notify_one (); - return (1); - }; - - void abort () { - gruel::scoped_lock l (*d_internal); - d_doAbort = true; - d_writeBlock->notify_one (); - d_readBlock->notify_one (); - }; -}; - -#endif /* _CIRCULAR_BUFFER_H_ */ diff --git a/usrp/host/lib/circular_linked_list.h b/usrp/host/lib/circular_linked_list.h deleted file mode 100644 index bbed5e49b..000000000 --- a/usrp/host/lib/circular_linked_list.h +++ /dev/null @@ -1,278 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006,2009,2010 Free Software Foundation, Inc. - * - * This file is part of GNU Radio. - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _CIRCULAR_LINKED_LIST_H_ -#define _CIRCULAR_LINKED_LIST_H_ - -#include <gruel/thread.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; - size_t d_n_nodes, d_n_used; - gruel::mutex* d_internal; - gruel::condition_variable* d_ioBlock; - -public: - circular_linked_list (size_t 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) { - size_t 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 gruel::condition_variable (); - d_internal = new gruel::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; - delete d_internal; - d_internal = NULL; - d_available = d_inUse = d_iterate = d_current = NULL; - d_n_used = d_n_nodes = 0; - }; - - s_node_ptr find_next_available_node () { - gruel::scoped_lock l (*d_internal); -// find an available node - s_node_ptr l_node = d_available; - DEBUG (std::cerr << "w "); - while (! l_node) { - DEBUG (std::cerr << "x" << std::endl); - // the ioBlock condition will automatically unlock() d_internal - d_ioBlock->wait (l); - // and lock() is here - DEBUG (std::cerr << "y" << std::endl); - l_node = d_available; - } - DEBUG (std::cerr << "::f_n_a_n: #u = " << num_used() - << ", node = " << l_node << std::endl); -// 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 (); - return (l_node); - }; - - void make_node_available (s_node_ptr l_node) { - if (!l_node) return; - gruel::scoped_lock l (*d_internal); - DEBUG (std::cerr << "::m_n_a: #u = " << num_used() - << ", node = " << l_node << std::endl); -// 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 (std::cerr << "s" << d_n_used); -// signal the condition when new data arrives - d_ioBlock->notify_one (); - DEBUG (std::cerr << "t "); - }; - - __INLINE__ void iterate_start () { d_iterate = d_current; }; - - s_node_ptr iterate_next () { -#if 0 -// lock the mutex for thread safety - gruel::scoped_lock l (*d_internal); -#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; - } - return (l_this); - }; - - __INLINE__ T object () { return (d_current->d_object); }; - __INLINE__ void object (T l_object) { d_current->d_object = l_object; }; - __INLINE__ size_t num_nodes () { return (d_n_nodes); }; - __INLINE__ size_t num_used () { return (d_n_used); }; - __INLINE__ void num_used (size_t l_n_used) { d_n_used = l_n_used; }; - __INLINE__ size_t 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->notify_one (); - }; - __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 deleted file mode 100644 index 8446f044e..000000000 --- a/usrp/host/lib/darwin_libusb.h +++ /dev/null @@ -1,227 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 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. - */ - -/* - * 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 const char* darwin_error_strings[] = { - "no error", - "device not opened for exclusive access", - "no connection to an IOService", - "no asyc port has been opened for interface", - "another process has device opened for exclusive access", - "pipe is stalled", - "could not establish a connection to Darin kernel", - "invalid argument", - "unknown error" -}; - -static const char * -darwin_error_str (int result) -{ - switch (result) { - case kIOReturnSuccess: - return (darwin_error_strings[0]); - case kIOReturnNotOpen: - return (darwin_error_strings[1]); - case kIOReturnNoDevice: - return (darwin_error_strings[2]); - case kIOUSBNoAsyncPortErr: - return (darwin_error_strings[3]); - case kIOReturnExclusiveAccess: - return (darwin_error_strings[4]); - case kIOUSBPipeStalled: - return (darwin_error_strings[5]); - case kIOReturnError: - return (darwin_error_strings[6]); - case kIOReturnBadArgument: - return (darwin_error_strings[7]); - default: - return (darwin_error_strings[8]); - } -} - -/* 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) { \ - std::cerr << "USB error: " << usb_error_str << std::cerr; \ - } \ - 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) { \ - std::cerr << "USB error: " << usb_error_str << std::endl; \ - } \ - 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) { \ - std::cerr << "USB error: " << usb_error_str << std::endl; \ - } \ - } 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) { - std::cerr << "Converting ep address to pipeRef." << std::endl; - } - - /* retrieve the total number of endpoints on this interface */ - ret = (*(device->interface))->GetNumEndpoints(device->interface, &numep); - if ( ret ) { - if ( usb_debug > 3 ) { - std::cerr << "ep_to_pipeRef: interface is " - << device->interface << std::endl; - } - 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) { - std::cerr << "ep_to_pipeRef: an error occurred getting " - << "pipe information on pipe " << i << std::endl; - - USB_ERROR_STR_ORIG (-darwin_to_errno(ret), - "ep_to_pipeRef(GetPipeProperties): %s", - darwin_error_str(ret)); - } - - if (usb_debug > 3) { - std::cerr << "ep_to_pipeRef: Pipe " << i << ": DIR: " - << direction << " number: " << number << std::endl; - } - - /* 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) { - std::cerr << "ep_to_pipeRef: pipeRef for ep address " - << ep << " found: " << i << std::endl; - } - return (i); - } - } - - if (usb_debug > 3) { - std::cerr << "ep_to_pipeRef: No pipeRef found with endpoint address " - << ep << std::endl; - } - - /* 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 deleted file mode 100644 index b4fb45c51..000000000 --- a/usrp/host/lib/db_base.cc +++ /dev/null @@ -1,256 +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. -// - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#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("_refclk_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 deleted file mode 100644 index 9d5ca4370..000000000 --- a/usrp/host/lib/db_base_impl.h +++ /dev/null @@ -1,33 +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 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 deleted file mode 100644 index 1694d6a3f..000000000 --- a/usrp/host/lib/db_basic.cc +++ /dev/null @@ -1,266 +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. - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#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_bitshark_rx.cc b/usrp/host/lib/db_bitshark_rx.cc deleted file mode 100644 index 5368866d8..000000000 --- a/usrp/host/lib/db_bitshark_rx.cc +++ /dev/null @@ -1,417 +0,0 @@ -// -// Copyright 2010 Free Software Foundation, Inc. -// -// This file is part of GNU Radio -// -// GNU Radio is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either 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. - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <usrp/db_bitshark_rx.h> -#include <db_base_impl.h> -#include <cmath> -#include <cstdio> -#include <string.h> -#include <stdint.h> - -/* Note: Thie general structure of this file is based on the db_dbsrx.cc - codebase for the dbsrx daughterboard. */ - -/* The following defines specify the address map provided by the - Bitshark card. These registers are all accessed over I2C. */ -#define RF_CENTER_FREQ_REG 0x00 -#define RF_CHAN_FILTER_BW_REG 0x01 -#define RF_GAIN_REG 0x02 -#define BB_GAIN_REG 0x03 -#define ADF4350_REG 0x10 -#define SKY73202_REG 0x11 -#define CLOCK_SCHEME_REG 0x20 - -/* The following table lists the registers provided by the BURX board that - are accessible over I2C: - -------------------------------------------------------- - |RegAddr: 0x00-RF Center Freq register | - |4-bytes 0x00| - |4-byte unsigned RF center freq (in KHz)| - |RegAddr: 0x01-RF channel filter bandwidth register | - |4-bytes 0x00| - |4-byte unsigned RF channel filter bw (in KHz)| - |RegAddr: 0x02-RF gain register | - |7-bytes 0x00| - |1-byte signed RF gain (in dB)| - |RegAddr: 0x03-Baseband gain register | - |4-bytes 0x00| - |4-byte signed baseband filter gain (in dB)| - |RegAddr: 0x10-ADF4350 register | - |4-bytes 0x00| - |4-byte ADF4350 register value (actual ADF4350 reg addr embedded - within 4-byte value)| - |RegAddr: 0x11-SKY73202 register | - |5-bytes 0x00| - |1-byte reg 0 of SKY73202 | - |1-byte reg 1 of SKY73202 | - |1-byte reg 2 of SKY73202 | - |RegAddr: 0x20-Clock Scheme | - |3-bytes 0x00| - |1-byte indicating clocking scheme: - -0x00 -> BURX local TCXO off, BURX accepts ref clock from - USRP (freq of USRP's ref clock specified in bytes 2-5) - -0x01 -> BURX local TCXO on, BURX uses its local TCXO as its ref - clock, TCXO signal output for use by USRP | - |4-byte USRP ref clock freq in hz (only needed if byte 1 set to 0x00) | - - --------------------------------------------------------------------------- - - As an example, lets say the client wants to set an RF center freq of - 1000 MHz. In KHz, this translates to 1000000 (resolution is only down to - steps of 1 KHz), which is 0x000F4240 in hex. So the complete 9-byte I2C - sequence that the client should send is as follows: - byte 0: 0x00-register 0x00 is the target of the write operation - bytes 1-4: 0x00 (padding) - byte 5: 0x40 (LSB of the 1000000 KHz value, in hex) - byte 6: 0x42 - byte 7: 0x0F - byte 8: 0x00 (MSB of the 1000000 KHz value, in hex) - - If using the usrper cmd-line application on a PC, this sequence would - be sent as follows (assuming that the BURX is in slot A): - - # usrper i2c_write 0x47 000000000040420F00 - - How about another example...lets say the client wants to setup the clock - scheme to use scheme #1 where the 26 MHz TCXO on the BURX board is enabled, - and is provided to the USRP. 26 MHz (i.e. 26 million), in hex, is 0x18CBA80. - So the complete 9-byte I2C sequence that the client should send is as follows: - byte 0: 0x20-register 0x20 is the target of the write operation - bytes 1-3: 0x00 (padding) - byte 4: 0x01 (indicating that clock scheme #1 is wanted) - byte 5: 0x80 (LSB of the BURX ref clk freq) - byte 6: 0xBA - byte 7: 0x8C - byte 8: 0x01 (MSB of the BURX ref clk freq) - - To enable the BURX local ref clk, which will also make it available on the - on-board U.FL connector as a source for the USRP, a user can also use - the usrper cmd-line application on a PC. The following sequence would - be sent (assuming that the BURX is in slot A): - - # usrper i2c_write 0x47 200000000180BA8C01 - -*/ - -#define NUM_BYTES_IN_I2C_CMD 9 - -/*****************************************************************************/ - -db_bitshark_rx::db_bitshark_rx(usrp_basic_sptr _usrp, int which) - : db_base(_usrp, which) -{ - // Control Bitshark receiver USRP daughterboard. - // - // @param usrp: instance of usrp.source_c - // @param which: which side: 0, 1 corresponding to RX_A or RX_B respectively - - // turn off all outputs - usrp()->_write_oe(d_which, 0, 0xffff); - - if (which == 0) - { - d_i2c_addr = 0x47; - } - else - { - d_i2c_addr = 0x45; - } - - // initialize gain - set_gain((gain_min() + gain_max()) / 2.0); - - // by default, assume we're using the USRPs clock as the ref clk, - // so setup the clock scheme and frequency. If the user wants - // to use the Bitshark's TCXO, the clock scheme should be set - // to 1, the freq should be set to 26000000, and a top-level - // 'make' and 'make install' needs to be executed. In addition, - // a U.FL to SMA cable needs to connect J6 on the Bitshark to - // the external clk input on the USRP - set_clock_scheme(0,64000000); - - set_bw(8e6); // Default IF bandwidth to match USRP1 max host bandwidth - - bypass_adc_buffers(true); -} - -db_bitshark_rx::~db_bitshark_rx() -{ - shutdown(); -} - -/************ Private Functions **********************/ - -void -db_bitshark_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); - } -} - -/************ Public Functions **********************/ -void -db_bitshark_rx::shutdown() -{ - if (!d_is_shutdown) - { - d_is_shutdown = true; - } -} - -bool -db_bitshark_rx::set_bw (float bw) -{ - std::vector<int> args(NUM_BYTES_IN_I2C_CMD,0); - uint16_t rf_bw_in_khz = (uint16_t)(bw/1000.0); - char val[4]; - bool result = false; - uint8_t try_count = 0; - - memset(val,0x00,4); - if (rf_bw_in_khz < 660 || rf_bw_in_khz > 56000) - { - fprintf(stderr, "db_bitshark_rx::set_bw: bw (=%d) must be between 660 KHz and 56 MHz inclusive\n", rf_bw_in_khz); - return false; - } - //fprintf(stdout,"Setting bw: requested bw in khz is %d\r\n",rf_bw_in_khz); - memcpy(val,&rf_bw_in_khz,4); - args[0] = RF_CHAN_FILTER_BW_REG; - args[5] = val[0]; - args[6] = val[1]; - args[7] = val[2]; - args[8] = val[3]; - while ((result != true) && (try_count < 3)) - { - result=usrp()->write_i2c (d_i2c_addr, int_seq_to_str (args)); - try_count++; - } - - if (result == false) - { - fprintf(stderr, "db_bitshark_rx:set_bw: giving up after 3 tries without success\n"); - } - - return result; -} - -/* The gain referenced below is RF gain only. There are two independent - gain settings at RF: a digital step attenuator (providing 0, -6, -12, and - -18 dB of attenuation), and a second LNA (LNA2) that provides ~25 dB of - gain (roughly...it actually depends on the RF freq). So combining these - two stages can provide an overall gain range from 0 (which is mapped - to -18 dB on the step attenuator + LNA2 turned off) to 42 (which is - mapped to 0 dB on the step attenuator + LNA2 turned on). - - There could be better ways to map these, but this is sufficient for - now. */ -float -db_bitshark_rx::gain_min() -{ - return 0; -} - -float -db_bitshark_rx::gain_max() -{ - return 42; -} - -float -db_bitshark_rx::gain_db_per_step() -{ - return 6; -} - -bool -db_bitshark_rx::set_gain(float gain) -{ - // Set the gain. - // - // @param gain: RF gain in decibels, range of 0-42 - // @returns True/False - - std::vector<int> args(NUM_BYTES_IN_I2C_CMD,0); - bool result = false; - uint8_t try_count = 0; - - if (gain < gain_min() || gain > gain_max()) - { - fprintf(stderr,"db_bitshark_rx::set_gain: gain (=%f) must be between %f and %f inclusive\n", gain,gain_min(),gain_max()); - return false; - } - //fprintf(stdout,"db_bitshark_rx::set_gain: requested gain of %f\r\n",gain); - args[0] = RF_GAIN_REG; - args[5] = (int)gain; - - while ((result != true) && (try_count < 3)) - { - result=usrp()->write_i2c (d_i2c_addr, int_seq_to_str (args)); - try_count++; - } - - if (result == false) - { - fprintf(stderr, "db_bitshark_rx:set_gain: giving up after 3 tries without success\n"); - } - - return result; -} - - -bool -db_bitshark_rx::set_clock_scheme(uint8_t clock_scheme, uint32_t ref_clk_freq) -{ - // Set the clock scheme for determining how the BURX - // dboard receives its clock. Note: Ideally, the constructor for the - // BURX board could simply call this method to set how it wants the - // clock scheme configured. However, depending on the application - // using the daughterboard, the constructor may run _after_ some - // other portion of the application needs the FPGA. And if the - // the clock source for the FPGA was the BURX's 26 MHz TCXO, we're in - // a chicken-before-the-egg dilemna. So the solution is to leave - // this function here for reference in case an app wants to use it, - // and also give the user the ability to set the clock scheme through - // the usrper cmd-line application (see example at the top of this - // file). - // - // @param clock_scheme - // @param ref_clk_freq in Hz - // @returns True/False - - std::vector<int> args(NUM_BYTES_IN_I2C_CMD,0); - bool result = false; - uint8_t try_count = 0; - char val[4]; - - if (clock_scheme > 1) - { - fprintf(stderr,"db_bitshark_rx::set_clock_scheme: invalid scheme %d\n",clock_scheme); - return false; - } - //fprintf(stdout,"db_bitshark_rx::set_clock_scheme: requested clock schem of %d with freq %d Hz \n",clock_scheme,ref_clk_freq); - memcpy(val,&ref_clk_freq,4); - args[0] = CLOCK_SCHEME_REG; - args[4] = (int)clock_scheme; - args[5] = val[0]; - args[6] = val[1]; - args[7] = val[2]; - args[8] = val[3]; - - while ((result != true) && (try_count < 3)) - { - result=usrp()->write_i2c (d_i2c_addr, int_seq_to_str (args)); - try_count++; - } - - if (result == false) - { - fprintf(stderr, "db_bitshark_rx:set_clock_scheme: giving up after 3 tries without success\n"); - } - return result; -} - -double -db_bitshark_rx::freq_min() -{ - return 300e6; -} - -double -db_bitshark_rx::freq_max() -{ - return 4e9; -} - -struct freq_result_t -db_bitshark_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. - - std::vector<int> args(NUM_BYTES_IN_I2C_CMD,0); - std::vector<int> bytes(2); - char val[4]; - freq_result_t act_freq = {false, 0}; - uint32_t freq_in_khz = (uint32_t)(freq/1000.0); - bool result = false; - uint8_t try_count = 0; - - memset(val,0x00,4); - if(!(freq>=freq_min() && freq<=freq_max())) - { - return act_freq; - } - - //fprintf(stdout,"db_bitshark_rx::set_freq: requested freq is %d KHz\n",freq_in_khz); - memcpy(val,&freq_in_khz,4); - args[0] = RF_CENTER_FREQ_REG; - args[5] = val[0]; - args[6] = val[1]; - args[7] = val[2]; - args[8] = val[3]; - - while ((result != true) && (try_count < 3)) - { - result=usrp()->write_i2c (d_i2c_addr, int_seq_to_str (args)); - try_count++; - } - - if (result == false) - { - fprintf(stderr, "db_bitshark_rx:set_freq: giving up after 3 tries without success\n"); - } - - act_freq.ok = result; - act_freq.baseband_freq = (double)freq; - return act_freq; -} - -bool -db_bitshark_rx::is_quadrature() -{ - // Return True if this board requires both I & Q analog channels. - return true; -} - -bool -db_bitshark_rx::i_and_q_swapped() -{ - // Returns True since our I and Q channels are swapped - return true; -} diff --git a/usrp/host/lib/db_boards.cc b/usrp/host/lib/db_boards.cc deleted file mode 100644 index 9324d58ee..000000000 --- a/usrp/host/lib/db_boards.cc +++ /dev/null @@ -1,244 +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. -// - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <db_boards.h> -#include <usrp/usrp_dbid.h> -#include <usrp/db_basic.h> -#include <usrp/db_tv_rx.h> -#include <usrp/db_tv_rx_mimo.h> -#include <usrp/db_dbs_rx.h> -#include <usrp/db_flexrf.h> -#include <usrp/db_flexrf_mimo.h> -#include <usrp/db_wbxng.h> -#include <usrp/db_xcvr2450.h> -#include <usrp/db_dtt754.h> -#include <usrp/db_dtt768.h> -#include <usrp/db_bitshark_rx.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_TV_RX_MIMO): - db.push_back(db_base_sptr(new db_tv_rx_mimo(usrp, which_side, 43.75e6, 5.75e6))); - break; - case(USRP_DBID_TV_RX_REV_2_MIMO): - db.push_back(db_base_sptr(new db_tv_rx_mimo(usrp, which_side, 44e6, 20e6))); - break; - case(USRP_DBID_TV_RX_REV_3_MIMO): - db.push_back(db_base_sptr(new db_tv_rx_mimo(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_WBX_NG_TX): - db.push_back(db_base_sptr(new db_wbxng_tx(usrp, which_side))); - break; - case(USRP_DBID_WBX_NG_RX): - db.push_back(db_base_sptr(new db_wbxng_rx(usrp, which_side))); - break; - - 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(USRP_DBID_BITSHARK_RX): - db.push_back(db_base_sptr(new db_bitshark_rx(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 deleted file mode 100644 index 136091c53..000000000 --- a/usrp/host/lib/db_boards.h +++ /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 <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 deleted file mode 100644 index 7fe8c4951..000000000 --- a/usrp/host/lib/db_dbs_rx.cc +++ /dev/null @@ -1,501 +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. - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#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 deleted file mode 100644 index 9ced705e4..000000000 --- a/usrp/host/lib/db_dtt754.cc +++ /dev/null @@ -1,327 +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. - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#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 deleted file mode 100644 index 0dfe1a8f3..000000000 --- a/usrp/host/lib/db_dtt768.cc +++ /dev/null @@ -1,300 +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. - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#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 deleted file mode 100644 index ddd87012d..000000000 --- a/usrp/host/lib/db_flexrf.cc +++ /dev/null @@ -1,1247 +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. - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <usrp/db_flexrf.h> -#include <db_base_impl.h> -#ifdef HAVE_TIME_H -#include <ctime> -#endif - -// 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(); -} - -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; - } -} - -//---------------------------------------------------------------------- - -_2200_common::_2200_common() - : _AD4360_common() -{ - // Band-specific R-Register Values - d_R_DIV = 16; // bits 15:2 - - // Band-specific C-Register values - d_P = 1; // bits 23,22 Div by 16/17 - d_CP2 = 7; // bits 19:17 - d_CP1 = 7; // bits 16:14 - - // Band specifc N-Register Values - d_DIVSEL = 0; // bit 23 - d_DIV2 = 0; // bit 22 - d_CPGAIN = 0; // bit 21 - d_freq_mult = 1; -} - -double -_2200_common::freq_min() -{ - return 2000e6; -} - -double -_2200_common::freq_max() -{ - return 2400e6; -} - -//---------------------------------------------------------------------- - -_2400_common::_2400_common() - : _AD4360_common() -{ - // 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 2900e6; -} - -//---------------------------------------------------------------------- - -_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 1450e6; -} - -//------------------------------------------------------------------------- - -_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 1500e6; -} - -double -_1800_common::freq_max() -{ - return 2100e6; -} - -//------------------------------------------------------------------------- - -_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 750e6; -} - -double -_900_common::freq_max() -{ - return 1050e6; -} - -//------------------------------------------------------------------------- - -_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_2200_tx::db_flexrf_2200_tx(usrp_basic_sptr usrp, int which) - : flexrf_base_tx(usrp, which) -{ - d_common = new _2200_common(); -} - -db_flexrf_2200_tx::~db_flexrf_2200_tx() -{ -} - -bool -db_flexrf_2200_tx::_compute_regs(double freq, int &retR, int &retcontrol, - int &retN, double &retfreq) -{ - return d_common->_compute_regs(_refclk_freq(), freq, retR, - retcontrol, retN, retfreq); -} - - - -db_flexrf_2200_rx::db_flexrf_2200_rx(usrp_basic_sptr usrp, int which) - : flexrf_base_rx(usrp, which) -{ - d_common = new _2200_common(); - set_gain((gain_min() + gain_max()) / 2.0); // initialize gain -} - -db_flexrf_2200_rx::~db_flexrf_2200_rx() -{ -} - -float -db_flexrf_2200_rx::gain_min() -{ - return usrp()->pga_min(); -} - -float -db_flexrf_2200_rx::gain_max() -{ - return usrp()->pga_max()+70; -} - -float -db_flexrf_2200_rx::gain_db_per_step() -{ - return 0.05; -} - - -bool -db_flexrf_2200_rx::i_and_q_swapped() -{ - return true; -} - -bool -db_flexrf_2200_rx::_compute_regs(double freq, int &retR, int &retcontrol, - int &retN, double &retfreq) -{ - return d_common->_compute_regs(_refclk_freq(), freq, retR, - retcontrol, retN, retfreq); -} - -//------------------------------------------------------------ - -db_flexrf_2400_tx::db_flexrf_2400_tx(usrp_basic_sptr usrp, int which) - : flexrf_base_tx(usrp, which) -{ - 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 deleted file mode 100644 index 29bbbd58f..000000000 --- a/usrp/host/lib/db_flexrf_mimo.cc +++ /dev/null @@ -1,280 +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 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/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 deleted file mode 100644 index 1822479e1..000000000 --- a/usrp/host/lib/db_tv_rx.cc +++ /dev/null @@ -1,278 +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. - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#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_tv_rx_mimo.cc b/usrp/host/lib/db_tv_rx_mimo.cc deleted file mode 100644 index 0964c5d8b..000000000 --- a/usrp/host/lib/db_tv_rx_mimo.cc +++ /dev/null @@ -1,39 +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. - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <usrp/db_tv_rx_mimo.h> - -db_tv_rx_mimo::db_tv_rx_mimo(usrp_basic_sptr usrp, int which, - double first_IF, double second_IF) - : db_tv_rx(usrp, which,first_IF,second_IF) -{ - _enable_refclk(true);//enable FPGA refclock output on gpio 0 -} - -int -db_tv_rx_mimo::_refclk_divisor() -{ - return 16;// 64/16=> 4 Mhz refclock -} - diff --git a/usrp/host/lib/db_util.cc b/usrp/host/lib/db_util.cc deleted file mode 100644 index 4b46383bb..000000000 --- a/usrp/host/lib/db_util.cc +++ /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/db_util.h b/usrp/host/lib/db_util.h deleted file mode 100644 index e07abb608..000000000 --- a/usrp/host/lib/db_util.h +++ /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/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc deleted file mode 100644 index 4d17c72d1..000000000 --- a/usrp/host/lib/db_wbxng.cc +++ /dev/null @@ -1,538 +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. - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <usrp/db_wbxng.h> -#include "db_wbxng_adf4350.h" -#include <db_base_impl.h> -#include <stdio.h> -#ifdef HAVE_TIME_H -#include <ctime> -#endif - -// d'board i/o pin defs -// Tx and Rx have shared defs, but different i/o regs -#define ENABLE_5 (1 << 7) // enables 5.0V power supply -#define ENABLE_33 (1 << 6) // enables 3.3V supply -//#define RX_TXN (1 << 15) // Tx only: T/R antenna switch for TX/RX port -//#define RX2_RX1N (1 << 15) // Rx only: antenna switch between RX2 and TX/RX port -#define RX_TXN ((1 << 5)|(1 << 15)) // Tx only: T/R antenna switch for TX/RX port -#define RX2_RX1N ((1 << 5)|(1 << 15)) // Rx only: antenna switch between RX2 and TX/RX port -#define RXBB_EN (1 << 4) -#define TXMOD_EN (1 << 4) -#define PLL_CE (1 << 3) -#define PLL_PDBRF (1 << 2) -#define PLL_MUXOUT (1 << 1) -#define PLL_LOCK_DETECT (1 << 0) - -// RX Attenuator constants -#define ATTN_SHIFT 8 -#define ATTN_MASK (63 << ATTN_SHIFT) - -wbxng_base::wbxng_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 - */ - - usrp()->_write_oe(d_which, 0, 0xffff); // turn off all outputs - - d_first = true; - d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0; - - _enable_refclk(false); // disable refclk - - set_auto_tr(false); -} - -wbxng_base::~wbxng_base() -{ -} - -int -wbxng_base::_refclk_divisor() -{ - return 1; -} - -struct freq_result_t -wbxng_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. - */ - - // clamp freq - freq_t int_freq = freq_t(std::max(freq_min(), std::min(freq, freq_max()))); - - bool ok = d_common->_set_freq(int_freq*2, _refclk_freq()); - - _write_spi(d_common->compute_register(5)); - _write_spi(d_common->compute_register(4)); - _write_spi(d_common->compute_register(3)); - /* load involved registers */ - _write_spi(d_common->compute_register(2)); - _write_spi(d_common->compute_register(1)); - _write_spi(d_common->compute_register(0)); - - double freq_result = (double) d_common->_get_freq(_refclk_freq())/2.0; - - //ok &= _get_locked(); - struct freq_result_t args = {ok, freq_result}; - - /* Wait before reading Lock Detect*/ - timespec t; - t.tv_sec = 0; - t.tv_nsec = 10000000; - nanosleep(&t, NULL); - - //fprintf(stderr,"Setting WBXNG frequency, requested %d, obtained %f, lock_detect %d\n", - // int_freq, freq_result, d_common->_get_locked()); - - // FIXME - // 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; - - return args; -} - -bool -wbxng_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 -wbxng_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 -wbxng_base::freq_min() -{ - return (double) d_common->_get_min_freq()/2.0; -} - -double -wbxng_base::freq_max() -{ - return (double) d_common->_get_max_freq()/2.0; -} - -bool -wbxng_base::_get_locked(void) -{ - return usrp()->read_io(d_which) & PLL_LOCK_DETECT; -} - -void -wbxng_base::_write_spi(std::string data) -{ - usrp()->_write_spi(0, d_spi_enable, d_spi_format, data); -} - -// ---------------------------------------------------------------- - -db_wbxng_tx::db_wbxng_tx(usrp_basic_sptr _usrp, int which) - : wbxng_base(_usrp, which) -{ - /* - @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; - } - - d_common = boost::shared_ptr<adf4350> (new adf4350()); - - /* Initialize the registers. */ - _write_spi(d_common->compute_register(5)); - _write_spi(d_common->compute_register(4)); - _write_spi(d_common->compute_register(3)); - _write_spi(d_common->compute_register(2)); - _write_spi(d_common->compute_register(1)); - _write_spi(d_common->compute_register(0)); - - // power up the transmit side, but don't enable the mixer - usrp()->_write_oe(d_which,(PLL_CE|PLL_PDBRF|RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5), (PLL_CE|PLL_PDBRF|RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5)); - usrp()->write_io(d_which, (PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_CE|PLL_PDBRF|RX_TXN|ENABLE_33|ENABLE_5)); - //set_lo_offset(4e6); - - // Disable VCO/PLL - //d_common->_enable(true); - usrp()->write_io(d_which, (PLL_PDBRF), (PLL_PDBRF)); - - set_gain(gain_min()); // initialize gain -} - -db_wbxng_tx::~db_wbxng_tx() -{ - shutdown(); -} - -void -db_wbxng_tx::shutdown() -{ - // fprintf(stderr, "db_wbxng_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 - - // Disable VCO/PLL - //d_common->_enable(false); - usrp()->write_io(d_which, 0, (PLL_PDBRF)); - - // Power down and leave the T/R switch in the R position - usrp()->write_io(d_which, (RX_TXN), (PLL_CE|PLL_PDBRF|RX_TXN|ENABLE_33|ENABLE_5)); - - /* - _write_control(_compute_control_reg()); - */ - _enable_refclk(false); // turn off refclk - set_auto_tr(false); - } -} - -bool -db_wbxng_tx::set_auto_tr(bool on) -{ - bool ok = true; - if(on) { - ok &= set_atr_mask (RX_TXN | TXMOD_EN); - ok &= set_atr_txval(0 | TXMOD_EN); - ok &= set_atr_rxval(RX_TXN); - } - else { - ok &= set_atr_mask (0); - ok &= set_atr_txval(0); - ok &= set_atr_rxval(0); - } - return ok; -} - -bool -db_wbxng_tx::set_enable(bool on) -{ - /* - Enable transmitter if on is true - */ - - int v; - int mask = RX_TXN | TXMOD_EN; - if(on) { - v = TXMOD_EN; - // Enable VCO/PLL - //d_common->_enable(true); - } - else { - v = RX_TXN; - // Disable VCO/PLL - //d_common->_enable(false); - } - return usrp()->write_io(d_which, v, mask); -} - -float -db_wbxng_tx::gain_min() -{ - return 0.0; -} - -float -db_wbxng_tx::gain_max() -{ - return 25.0; -} - -float -db_wbxng_tx::gain_db_per_step() -{ - return gain_max()/(1+(1.4-0.5)*4096/3.3); -} - -bool -db_wbxng_tx::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(); - float mingain = gain_min(); - pga_gain = 0; - agc_gain = gain; - - V_maxgain = 0.5; - V_mingain = 1.4; - V_fullscale = 3.3; - dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale; - - //fprintf(stderr, "TXGAIN: %f dB, Dac Code: %d, Voltage: %f\n", gain, int(dac_value), float((dac_value/4096.0)*V_fullscale)); - assert(dac_value>=0 && dac_value<4096); - - return (usrp()->write_aux_dac(d_which, 0, int(dac_value)) - && _set_pga(usrp()->pga_max())); - -} - - -/**************************************************************************/ - - -db_wbxng_rx::db_wbxng_rx(usrp_basic_sptr _usrp, int which) - : wbxng_base(_usrp, which) -{ - /* - @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; - } - - d_common = boost::shared_ptr<adf4350> (new adf4350()); - - /* Initialize the registers. */ - _write_spi(d_common->compute_register(5)); - _write_spi(d_common->compute_register(4)); - _write_spi(d_common->compute_register(3)); - _write_spi(d_common->compute_register(2)); - _write_spi(d_common->compute_register(1)); - _write_spi(d_common->compute_register(0)); - - usrp()->_write_oe(d_which, (PLL_CE|PLL_PDBRF|RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5), (PLL_CE|PLL_PDBRF|RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5)); - usrp()->write_io(d_which, (PLL_CE|RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5), (PLL_CE|PLL_PDBRF|RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5)); - //fprintf(stderr,"Setting WBXNG RXBB on"); - - // Enable VCO/PLL - //d_common->_enable(true); - usrp()->write_io(d_which, (PLL_PDBRF), (PLL_PDBRF)); - - // set up for RX on TX/RX port - select_rx_antenna("TX/RX"); - - bypass_adc_buffers(true); - - /* - set_lo_offset(-4e6); - */ - - set_gain(gain_min()); // initialize gain -} - -db_wbxng_rx::~db_wbxng_rx() -{ - shutdown(); -} - -void -db_wbxng_rx::shutdown() -{ - // fprintf(stderr, "db_wbxng_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 VCO/PLL - //d_common->_enable(false); - usrp()->write_io(d_which, 0, (PLL_PDBRF)); - - // fprintf(stderr, "db_wbxng_rx::shutdown before _write_control\n"); - //_write_control(_compute_control_reg()); - - // fprintf(stderr, "db_wbxng_rx::shutdown before _enable_refclk\n"); - _enable_refclk(false); // turn off refclk - - // fprintf(stderr, "db_wbxng_rx::shutdown before set_auto_tr\n"); - set_auto_tr(false); - - // Power down - usrp()->write_io(d_which, 0, (PLL_CE|PLL_PDBRF|RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5)); - - // fprintf(stderr, "db_wbxng_rx::shutdown after set_auto_tr\n"); - } -} - -bool -db_wbxng_rx::set_auto_tr(bool on) -{ - bool ok = true; - if(on) { - ok &= set_atr_mask (RXBB_EN|RX2_RX1N); - ok &= set_atr_txval( 0|RX2_RX1N); - ok &= set_atr_rxval(RXBB_EN| 0); - } - else { - ok &= set_atr_mask (0); - ok &= set_atr_txval(0); - ok &= set_atr_rxval(0); - } - return true; -} - -bool -db_wbxng_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; - } - return true; -} - -bool -db_wbxng_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 { - return false; - } - - return true; -} - -bool -db_wbxng_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 maxgain = gain_max() - usrp()->pga_max(); - if(gain > maxgain) { - pga_gain = gain-maxgain; - assert(pga_gain <= usrp()->pga_max()); - agc_gain = maxgain; - } - else { - pga_gain = 0; - agc_gain = gain; - } - - return _set_attn(maxgain-agc_gain) && _set_pga(int(pga_gain)); -} - -bool -db_wbxng_rx::_set_attn(float attn) -{ - int attn_code = int(floor(attn/0.5)); - unsigned int iobits = (~attn_code) << ATTN_SHIFT; - //fprintf(stderr, "Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x \n", attn, attn_code, iobits & ATTN_MASK, ATTN_MASK); - return usrp()->write_io(d_which, iobits, ATTN_MASK); -} - -float -db_wbxng_rx::gain_min() -{ - return usrp()->pga_min(); -} - -float -db_wbxng_rx::gain_max() -{ - return usrp()->pga_max()+30.5; -} - -float -db_wbxng_rx::gain_db_per_step() -{ - return 0.05; -} - -bool -db_wbxng_rx::i_and_q_swapped() -{ - return false; -} diff --git a/usrp/host/lib/db_wbxng_adf4350.cc b/usrp/host/lib/db_wbxng_adf4350.cc deleted file mode 100644 index f1ab63d82..000000000 --- a/usrp/host/lib/db_wbxng_adf4350.cc +++ /dev/null @@ -1,148 +0,0 @@ -// -// 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 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. - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "db_wbxng_adf4350.h" -#include <db_base_impl.h> -#include <stdio.h> - -#define FREQ_C(freq) uint64_t(freq) -#define DIV_ROUND(num, denom) (((num) + ((denom)/2))/(denom)) -#define MIN_INT_DIV uint16_t(23) /* minimum int divider, prescaler 4/5 only */ -#define MAX_RF_DIV uint8_t(16) /* max rf divider, divides rf output */ -#define MIN_VCO_FREQ FREQ_C(2.2e9) /* minimum vco freq */ -#define MAX_VCO_FREQ FREQ_C(4.4e9) /* minimum vco freq */ -#define MAX_FREQ DIV_ROUND(MAX_VCO_FREQ, 1) /* upper bound freq (rf div = 1) */ -#define MIN_FREQ DIV_ROUND(MIN_VCO_FREQ, MAX_RF_DIV) /* calculated lower bound freq */ - -#define CE_PIN (1 << 3) -#define PDB_RF_PIN (1 << 2) -#define MUX_PIN (1 << 1) -#define LD_PIN (1 << 0) - -adf4350::adf4350() -{ - d_regs = new adf4350_regs(); -} - -adf4350::~adf4350() -{ - delete d_regs; -} - -std::string -adf4350::compute_register(uint8_t addr) -{ - uint32_t data = d_regs->compute_register(addr); - - data |= addr; - - // create std::string from data here - char s[4]; - s[0] = (char)((data >> 24) & 0xff); - s[1] = (char)((data >> 16) & 0xff); - s[2] = (char)((data >> 8) & 0xff); - s[3] = (char)(data & 0xff); - return std::string(s, 4); -} - -freq_t -adf4350::_get_max_freq(void) -{ - return MAX_FREQ; -} - -freq_t -adf4350::_get_min_freq(void) -{ - return MIN_FREQ; -} - -bool -adf4350::_set_freq(freq_t freq, freq_t refclock_freq) -{ - /* Set the frequency by setting int, frac, mod, r, div */ - if (freq > MAX_FREQ || freq < MIN_FREQ) return false; - int min_int_div = 23; - d_regs->d_prescaler = 0; - if (freq > FREQ_C(3e9)) { - min_int_div = 75; - d_regs->d_prescaler = 1; - } - /* Ramp up the RF divider until the VCO is within range. */ - d_regs->d_divider_select = 0; - while (freq < MIN_VCO_FREQ){ - freq <<= 1; //double the freq - d_regs->d_divider_select++; //double the divider - } - /* Ramp up the R divider until the N divider is at least the minimum. */ - //d_regs->d_10_bit_r_counter = refclock_freq*MIN_INT_DIV/freq; - d_regs->d_10_bit_r_counter = 2; - uint64_t n_mod; - do{ - d_regs->d_10_bit_r_counter++; - n_mod = freq; - n_mod *= d_regs->d_10_bit_r_counter; - n_mod *= d_regs->d_mod; - n_mod /= refclock_freq; - /* calculate int and frac */ - d_regs->d_int = n_mod/d_regs->d_mod; - d_regs->d_frac = (n_mod - (freq_t)d_regs->d_int*d_regs->d_mod) & uint16_t(0xfff); - /* - fprintf(stderr, - "VCO %lu KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n", - freq, d_regs->d_int, d_regs->d_frac, - d_regs->d_mod, d_regs->d_10_bit_r_counter, (1 << d_regs->d_divider_select) - ); - */ - }while(d_regs->d_int < min_int_div); - /* calculate the band select so PFD is under 125 KHz */ - d_regs->d_8_bit_band_select_clock_divider_value = \ - refclock_freq/(FREQ_C(30e3)*d_regs->d_10_bit_r_counter) + 1; - /* - fprintf(stderr, "Band Selection: Div %u, Freq %lu\n", - d_regs->d_8_bit_band_select_clock_divider_value, - refclock_freq/(d_regs->d_8_bit_band_select_clock_divider_value * d_regs->d_10_bit_r_counter) + 1 - ); - */ - return true; -} - -freq_t -adf4350::_get_freq(freq_t refclock_freq) -{ - /* Calculate the freq from int, frac, mod, ref, r, div: - * freq = (int + frac/mod) * (ref/r) - * Keep precision by doing multiplies first: - * freq = (((((((int)*mod) + frac)*ref)/mod)/r)/div) - */ - uint64_t freq; - freq = d_regs->d_int; - freq *= d_regs->d_mod; - freq += d_regs->d_frac; - freq *= refclock_freq; - freq /= d_regs->d_mod; - freq /= d_regs->d_10_bit_r_counter; - freq /= (1 << d_regs->d_divider_select); - return freq; -} diff --git a/usrp/host/lib/db_wbxng_adf4350.h b/usrp/host/lib/db_wbxng_adf4350.h deleted file mode 100644 index ce8cbf4b1..000000000 --- a/usrp/host/lib/db_wbxng_adf4350.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// 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 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_ADF4350_H -#define INCLUDED_ADF4350_H - -#include "db_wbxng_adf4350_regs.h" -#include <usrp/db_base.h> -#include <stdint.h> - -typedef uint64_t freq_t; -class adf4350_regs; - -class adf4350 -{ -public: - adf4350(); - ~adf4350(); - void _update(); - std::string compute_register(uint8_t addr); - bool _set_freq(freq_t freq, freq_t refclock_freq); - freq_t _get_freq(freq_t refclock_freq); - freq_t _get_max_freq(); - freq_t _get_min_freq(); - -protected: - adf4350_regs *d_regs; -}; - -#endif /* INCLUDED_ADF4350_H */ diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.cc b/usrp/host/lib/db_wbxng_adf4350_regs.cc deleted file mode 100644 index c9707c3c6..000000000 --- a/usrp/host/lib/db_wbxng_adf4350_regs.cc +++ /dev/null @@ -1,136 +0,0 @@ -// -// 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 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_wbxng_adf4350_regs.h" -#include "db_wbxng_adf4350.h" - -//#include "cal_div.h" - -/* reg 0 */ -/* reg 1 */ -const uint16_t adf4350_regs::s_phase = 0; -/* reg 2 */ -const uint8_t adf4350_regs::s_low_noise_and_low_spur_modes = 3; -const uint8_t adf4350_regs::s_muxout = 6; -const uint8_t adf4350_regs::s_reference_doubler = 0; -const uint8_t adf4350_regs::s_rdiv2 = 0; -const uint8_t adf4350_regs::s_double_buff = 0; -const uint8_t adf4350_regs::s_charge_pump_setting = 5; -const uint8_t adf4350_regs::s_ldf = 0; -const uint8_t adf4350_regs::s_ldp = 0; -const uint8_t adf4350_regs::s_pd_polarity = 1; -const uint8_t adf4350_regs::s_power_down = 0; -const uint8_t adf4350_regs::s_cp_three_state = 0; -const uint8_t adf4350_regs::s_counter_reset = 0; -/* reg 3 */ -const uint8_t adf4350_regs::s_csr = 0; -const uint8_t adf4350_regs::s_clk_div_mode = 0; -const uint16_t adf4350_regs::s_12_bit_clock_divider_value = 0; -/* reg 4 */ -const uint8_t adf4350_regs::s_feedback_select = 1; -const uint8_t adf4350_regs::s_vco_power_down = 0; -const uint8_t adf4350_regs::s_mtld = 0; -const uint8_t adf4350_regs::s_aux_output_select = 1; -const uint8_t adf4350_regs::s_aux_output_enable = 0; -const uint8_t adf4350_regs::s_aux_output_power = 0; -const uint8_t adf4350_regs::s_rf_output_enable = 1; -const uint8_t adf4350_regs::s_output_power = 3; -/* reg 5 */ -const uint8_t adf4350_regs::s_ld_pin_mode = 1; - -adf4350_regs::adf4350_regs(){ - - /* reg 0 */ - d_int = uint16_t(100); - d_frac = 0; - /* reg 1 */ - d_prescaler = uint8_t(0); - d_mod = uint16_t(0xfff); /* max fractional accuracy */ - /* reg 2 */ - d_10_bit_r_counter = uint16_t(2); - /* reg 3 */ - /* reg 4 */ - d_divider_select = 0; - d_8_bit_band_select_clock_divider_value = 0; - /* reg 5 */ -} - -adf4350_regs::~adf4350_regs(void){ -} - -uint32_t -adf4350_regs::_reg_shift(uint32_t data, uint32_t shift){ - return data << shift; -} - -uint32_t -adf4350_regs::compute_register(uint8_t addr){ - uint32_t data = 0; - switch (addr){ - case 0: data = ( - _reg_shift(d_int, 15) | - _reg_shift(d_frac, 3)); - break; - case 1: data = ( - _reg_shift(d_prescaler, 27) | - _reg_shift(s_phase, 15) | - _reg_shift(d_mod, 3)); - break; - case 2: data = ( - _reg_shift(s_low_noise_and_low_spur_modes, 29) | - _reg_shift(s_muxout, 26) | - _reg_shift(s_reference_doubler, 25) | - _reg_shift(s_rdiv2, 24) | - _reg_shift(d_10_bit_r_counter, 14) | - _reg_shift(s_double_buff, 13) | - _reg_shift(s_charge_pump_setting, 9) | - _reg_shift(s_ldf, 8) | - _reg_shift(s_ldp, 7) | - _reg_shift(s_pd_polarity, 6) | - _reg_shift(s_power_down, 5) | - _reg_shift(s_cp_three_state, 4) | - _reg_shift(s_counter_reset, 3)); - break; - case 3: data = ( - _reg_shift(s_csr, 18) | - _reg_shift(s_clk_div_mode, 15) | - _reg_shift(s_12_bit_clock_divider_value, 3)); - break; - case 4: data = ( - _reg_shift(s_feedback_select, 23) | - _reg_shift(d_divider_select, 20) | - _reg_shift(d_8_bit_band_select_clock_divider_value, 12) | - _reg_shift(s_vco_power_down, 11) | - _reg_shift(s_mtld, 10) | - _reg_shift(s_aux_output_select, 9) | - _reg_shift(s_aux_output_enable, 8) | - _reg_shift(s_aux_output_power, 6) | - _reg_shift(s_rf_output_enable, 5) | - _reg_shift(s_output_power, 3)); - break; - case 5: data = ( - _reg_shift(s_ld_pin_mode, 22)); - break; - default: return data; - } - /* return the data to write out to spi */ - return data; -} - diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.h b/usrp/host/lib/db_wbxng_adf4350_regs.h deleted file mode 100644 index 33a548e85..000000000 --- a/usrp/host/lib/db_wbxng_adf4350_regs.h +++ /dev/null @@ -1,83 +0,0 @@ -// -// 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 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 ADF4350_REGS_H -#define ADF4350_REGS_H - -#include <usrp/db_base.h> -#include <stdint.h> - -class adf4350; - -class adf4350_regs -{ -public: - adf4350_regs(); - ~adf4350_regs(); - - uint32_t _reg_shift(uint32_t data, uint32_t shift); - uint32_t compute_register(uint8_t addr); - - /* reg 0 */ - uint16_t d_int; - uint16_t d_frac; - /* reg 1 */ - uint8_t d_prescaler; - static const uint16_t s_phase; - uint16_t d_mod; - /* reg 2 */ - static const uint8_t s_low_noise_and_low_spur_modes; - static const uint8_t s_muxout; - static const uint8_t s_reference_doubler; - static const uint8_t s_rdiv2; - uint16_t d_10_bit_r_counter; - static const uint8_t s_double_buff; - static const uint8_t s_charge_pump_setting; - static const uint8_t s_ldf; - static const uint8_t s_ldp; - static const uint8_t s_pd_polarity; - static const uint8_t s_power_down; - static const uint8_t s_cp_three_state; - static const uint8_t s_counter_reset; - /* reg 3 */ - static const uint8_t s_csr; - static const uint8_t s_clk_div_mode; - static const uint16_t s_12_bit_clock_divider_value; - /* reg 4 */ - static const uint8_t s_feedback_select; - uint8_t d_divider_select; - uint8_t d_8_bit_band_select_clock_divider_value; - static const uint8_t s_vco_power_down; - static const uint8_t s_mtld; - static const uint8_t s_aux_output_select; - static const uint8_t s_aux_output_enable; - static const uint8_t s_aux_output_power; - static const uint8_t s_rf_output_enable; - static const uint8_t s_output_power; - /* reg 5 */ - static const uint8_t s_ld_pin_mode; - -protected: - usrp_basic_sptr d_usrp; - int d_spi_enable; - int d_spi_format; -}; - -#endif /* ADF4350_REGS_H */ diff --git a/usrp/host/lib/db_xcvr2450.cc b/usrp/host/lib/db_xcvr2450.cc deleted file mode 100644 index ce9d1f4e8..000000000 --- a/usrp/host/lib/db_xcvr2450.cc +++ /dev/null @@ -1,795 +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. - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#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<<9) | - (d_rxlpf_bw<<7) | - (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 deleted file mode 100755 index 034586d8a..000000000 --- a/usrp/host/lib/dump_data.py +++ /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/fusb.cc b/usrp/host/lib/fusb.cc deleted file mode 100644 index 2a597b67c..000000000 --- a/usrp/host/lib/fusb.cc +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2003,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 <fusb.h> - -// ------------------------------------------------------------------------ -// device handle -// ------------------------------------------------------------------------ - -fusb_devhandle::fusb_devhandle (libusb_device_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 deleted file mode 100644 index 538ae1ae0..000000000 --- a/usrp/host/lib/fusb.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -*- c++ -*- */ -/* - * 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 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_H_ -#define _FUSB_H_ - -#include <usrp/libusb_types.h> - -struct libusb_context; -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: - libusb_device_handle *d_udh; - -public: - // CREATORS - fusb_devhandle (libusb_device_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 - libusb_device_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 (libusb_device_handle *udh, - libusb_context *ctx = 0); - - /*! - * \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 deleted file mode 100644 index d2966c115..000000000 --- a/usrp/host/lib/fusb_darwin.cc +++ /dev/null @@ -1,582 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006,2009,2010 Free Software Foundation, Inc. - * - * This file is part of GNU Radio. - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define DO_DEBUG 0 - -#include <usb.h> -#include "fusb.h" -#include "fusb_darwin.h" -#include "darwin_libusb.h" -#include <iostream> - -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 gruel::mutex (); - d_runThreadRunning = new gruel::mutex (); - d_runBlock = new gruel::condition_variable (); - d_readBlock = new gruel::condition_variable (); - d_runBlock_mutex = new gruel::mutex (); - d_readBlock_mutex = new gruel::mutex (); -} - -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_mutex; - d_runBlock_mutex = NULL; - delete d_readBlock_mutex; - d_readBlock_mutex = 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) { - std::cerr << "fusb_ephandle_darwin::start: dev = " << - (void*) dev << ", device = " << (void*) device << std::endl; - } - - 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) { - std::cerr << "fusb_ephandle_darwin::start d_endpoint = " << d_endpoint - << ", d_input_p = " << (d_input_p ? "TRUE" : "FALSE") << std::endl; - } - - 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) { - std::cerr << "fusb_ephandle_darwin::start: " << (d_input_p ? "read" : "write") - << ": ep = " << d_endpoint << ", pipeRef = " << d_pipeRef << "interface = " - << d_interface << ", interfaceRef = " << d_interfaceRef - << ", if_direction = " << direction << ", if_# = " << number - << ", if_interval = " << interval << ", if_maxPacketSize = " - << maxPacketSize << std::endl; - } - - // 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 - gruel::scoped_lock l (*d_runBlock_mutex); - - // create the run thread, which allows OSX to process I/O separately - d_runThread = new gruel::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 (l); - - if (usb_debug) { - std::cerr << "fusb_ephandle_darwin::start: " << (d_input_p ? "read" : "write") - << " started." << std::endl; - } - - 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 - gruel::mutex* l_runThreadRunning = This->d_runThreadRunning; - gruel::scoped_lock l0 (*l_runThreadRunning); - - gruel::mutex* l_readRunning = This->d_readRunning; - gruel::condition_variable* l_readBlock = This->d_readBlock; - gruel::mutex* l_readBlock_mutex = This->d_readBlock_mutex; - - bool l_input_p = This->d_input_p; - - if (usb_debug) { - std::cerr << "fusb_ephandle_darwin::run_thread: starting for " - << (l_input_p ? "read" : "write") << "." << std::endl; - } - - 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 (); - - gruel::thread* 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 - gruel::scoped_lock l1 (*l_readBlock_mutex); - // create the read thread, which just issues all of the starting - // async read commands, then returns - l_rwThread = new gruel::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 (l1); - } - - { - // 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() - gruel::mutex* l_run_block_mutex = This->d_runBlock_mutex; - gruel::scoped_lock l2 (*l_run_block_mutex); - - // now that the lock is in place, signal the parent thread that - // things are running - This->d_runBlock->notify_one (); - } - - // run the loop - CFRunLoopRun (); - - if (l_input_p) { - // wait for read_thread () to finish, if needed - gruel::scoped_lock l3 (*l_readRunning); - } - - // remove run loop stuff - CFRunLoopRemoveSource (CFRunLoopGetCurrent (), - l_cfSource, kCFRunLoopDefaultMode); - - if (usb_debug) { - std::cerr << "fusb_ephandle_darwin::run_thread: finished for " - << (l_input_p ? "read" : "write") << "." << std::endl; - } -} - -void -fusb_ephandle_darwin::read_thread (void* arg) -{ - if (usb_debug) { - std::cerr << "fusb_ephandle_darwin::read_thread: starting." << std::endl; - } - - 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 - gruel::mutex* l_readRunning = This->d_readRunning; - gruel::scoped_lock l0 (*l_readRunning); - - // 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() - gruel::condition_variable* l_readBlock = This->d_readBlock; - gruel::mutex* l_read_block_mutex = This->d_readBlock_mutex; - - { - gruel::scoped_lock l1 (*l_read_block_mutex); - - // now that the lock is in place, signal the parent thread that - // things are running here - l_readBlock->notify_one (); - } - - // 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) { - std::cerr << "fusb_ephandle_darwin::read_thread: finished." << std::endl; - } -} - -void -fusb_ephandle_darwin::read_issue (s_both_ptr l_both) -{ - if ((! l_both) || (! d_started)) { - if (usb_debug > 4) { - std::cerr << "fusb_ephandle_darwin::read_issue: Doing nothing; " - << "l_both is " << (void*) l_both << "; started is " - << (d_started ? "TRUE" : "FALSE") << std::endl; - } - 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 - size_t 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) { - std::cerr << "fusb_ephandle_darwin::read_issue: Queued " << (void*) l_both - << " (" << bufLen << " Bytes)" << std::endl; - } -} - -void -fusb_ephandle_darwin::read_completed (void* refCon, - io_return_t result, - void* io_size) -{ - size_t l_size = (size_t) 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 (); - size_t l_i_size = l_buf->n_used (); - - if (This->d_started && (l_i_size != l_size)) { - std::cerr << "fusb_ephandle_darwin::read_completed: Expected " << l_i_size - << " bytes; read " << l_size << "." << std::endl; - } else if (usb_debug > 4) { - std::cerr << "fusb_ephandle_darwin::read_completed: Read " << (void*) l_both - << " (" << l_size << " bytes)" << std::endl; - } - -// add this read to the transfer buffer, and check for overflow -// -> data is being enqueued faster than it can be dequeued - if (l_buffer->enqueue (l_buf->buffer (), l_size) == -1) { -// print out that there's an overflow - fputs ("uO", 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) -{ - size_t l_nbytes = (size_t) nbytes; - d_buffer->dequeue ((char*) buffer, &l_nbytes); - - if (usb_debug > 4) { - std::cerr << "fusb_ephandle_darwin::read: request for " << nbytes - << " bytes, " << l_nbytes << " bytes retrieved." << std::endl; - } - - return ((int) l_nbytes); -} - -int -fusb_ephandle_darwin::write (const void* buffer, int nbytes) -{ - size_t l_nbytes = (size_t) nbytes; - - if (! d_started) { - if (usb_debug) { - std::cerr << "fusb_ephandle_darwin::write: Not yet started." << std::endl; - } - return (0); - } - - while (l_nbytes != 0) { -// find out how much data to copy; limited to "d_bufLenBytes" per node - size_t 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) { - std::cerr << "fusb_ephandle_darwin::write_thread: Queued " << (void*) l_both - << " (" << t_nbytes << " Bytes)" << std::endl; - } - 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 ()); - size_t l_size = (size_t) 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 (); - size_t l_i_size = l_buf->n_used (); - - if (This->d_started && (l_i_size != l_size)) { - std::cerr << "fusb_ephandle_darwin::write_completed: Expected " << l_i_size - << " bytes written; wrote " << l_size << "." << std::endl; - } else if (usb_debug > 4) { - std::cerr << "fusb_ephandle_darwin::write_completed: Wrote " << (void*) l_both - << " (" << l_size << " Bytes)" << std::endl; - } - -// 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) { - std::cerr << "fusb_ephandle_darwin::abort: starting." << std::endl; - } - - 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) { - std::cerr << "fusb_ephandle_darwin::abort: finished." << std::endl; - } -} - -bool -fusb_ephandle_darwin::stop () -{ - if (! d_started) - return (true); - - if (usb_debug) { - std::cerr << "fusb_ephandle_darwin::stop: stopping " - << (d_input_p ? "read" : "write") << "." << std::endl; - } - - 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 - gruel::scoped_lock l (*d_runThreadRunning); - - if (usb_debug) { - std::cerr << "fusb_ephandle_darwin::stop: " << (d_input_p ? "read" : "write") - << " stopped." << std::endl; - } - - 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 deleted file mode 100644 index 4d18177be..000000000 --- a/usrp/host/lib/fusb_darwin.h +++ /dev/null @@ -1,218 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006,2009,2010 Free Software Foundation, Inc. - * - * This file is part of GNU Radio. - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#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; - size_t d_n_used, d_n_alloc; - -public: - inline s_buffer (size_t 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 size_t n_used () { return (d_n_used); }; - inline void n_used (size_t bufLen) { - d_n_used = (bufLen > d_n_alloc) ? d_n_alloc : bufLen; }; - inline size_t n_alloc () { return (d_n_alloc); }; - void buffer (char* l_buffer, size_t bufLen) { - if (bufLen > d_n_alloc) { - std::cerr << "s_buffer::set: Copying only allocated bytes." << std::endl; - bufLen = d_n_alloc; - } - if (!l_buffer) { - std::cerr << "s_buffer::set: NULL buffer." << std::endl; - 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; - gruel::thread* d_runThread; - gruel::mutex* 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; - size_t d_bufLenBytes; - gruel::mutex* d_readRunning; - gruel::mutex* d_runBlock_mutex; - gruel::mutex* d_readBlock_mutex; - gruel::condition_variable* d_runBlock; - gruel::condition_variable* 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 deleted file mode 100644 index 0958716d9..000000000 --- a/usrp/host/lib/fusb_generic.cc +++ /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/fusb_generic.h b/usrp/host/lib/fusb_generic.h deleted file mode 100644 index b9aef2737..000000000 --- a/usrp/host/lib/fusb_generic.h +++ /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/fusb_libusb1.cc b/usrp/host/lib/fusb_libusb1.cc deleted file mode 100644 index 770708451..000000000 --- a/usrp/host/lib/fusb_libusb1.cc +++ /dev/null @@ -1,702 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2003,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 <fusb_libusb1.h> -#include <fusb.h> -#include <libusb-1.0/libusb.h> -#include <stdexcept> -#include <cstdio> -#include <assert.h> -#include <string.h> -#include <algorithm> -#include <errno.h> -#include <string.h> - -#define MINIMIZE_TX_BUFFERING true - -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 = 4 * (1L << 20); // 4 MB endpoint -static const int LIBUSB_TIMEOUT = 0; // no timeout - -inline static fusb_ephandle_libusb1 * -lut_get_ephandle (libusb_transfer *lut) -{ - return (fusb_ephandle_libusb1 *) lut->user_data; -} - -// ------------------------------------------------------------------------ -// libusb_transfer allocation, deallocation, and callback -// ------------------------------------------------------------------------ - -static void -free_lut (libusb_transfer *lut) -{ - - // if this was an input transfer, free the buffer - if (lut->endpoint & 0x80) - delete [] ((unsigned char *) lut->buffer); - - libusb_free_transfer(lut); - -} - -/* - * The callback means the libusb_transfer is completed whether sent, cancelled, - * or failed. Move the libusb_transfer from the pending list to the - * completed list. If the cancel is from the destructor then free the - * transfer instead; normally this won't happen since all endpoints should be - * destroyed first leaving the pending list empty. - */ - -static void -generic_callback(struct libusb_transfer *lut) -{ - - // Fish out devhandle from endpoint - fusb_devhandle_libusb1* dev_handle = - lut_get_ephandle(lut)->get_fusb_devhandle_libusb1(); - - dev_handle->pending_remove(lut); - - if (lut->status == LIBUSB_TRANSFER_CANCELLED && dev_handle->_teardown() == 1) - { - free_lut (lut); - return; - } - - lut_get_ephandle(lut)->completed_list_add(lut); - -} - -static libusb_transfer* -alloc_lut (fusb_ephandle_libusb1 *self, int buffer_length, int endpoint, - bool input_p, unsigned char *write_buffer, - fusb_devhandle_libusb1 *dh) -{ - - struct libusb_transfer* lut = libusb_alloc_transfer(0); - - endpoint = (endpoint & 0x7f) | (input_p ? 0x80 : 0); - - if (input_p) - write_buffer = new unsigned char [buffer_length]; - - // We need the base class libusb_device_handle - libusb_device_handle *dev_handle = dh->get_usb_dev_handle(); - - // Load the libusb_transfer for bulk transfer - libusb_fill_bulk_transfer (lut, // transfer - dev_handle, // dev_handle - endpoint, // endpoint - write_buffer, // buffer - buffer_length, // length - generic_callback, // callback - self, // user_data - LIBUSB_TIMEOUT); // timeout - - return lut; -} - -// ------------------------------------------------------------------------ -// device handle -// ------------------------------------------------------------------------ - -fusb_devhandle_libusb1::fusb_devhandle_libusb1 (libusb_device_handle *udh, - libusb_context *ctx) - : fusb_devhandle (udh), d_ctx (ctx), d_teardown (false) -{ - // that's it -} - -fusb_devhandle_libusb1::~fusb_devhandle_libusb1 () -{ - d_teardown = true; - - std::list<libusb_transfer*>::reverse_iterator it; - - // After cancellation the libusb_transfer is still active so delay freeing - // transfer until callback occurs. In most cases the pending list should - // already be empty by the time this destructor is called. - - for (it = d_pending_rqsts.rbegin (); it != d_pending_rqsts.rend (); it++) { - _cancel_lut (*it); - } - - // Wait for pending list to empty - _wait_for_completion (); - -} - -fusb_ephandle* -fusb_devhandle_libusb1::make_ephandle (int endpoint, bool input_p, - int block_size, int nblocks) -{ - return new fusb_ephandle_libusb1 (this, endpoint, input_p, - block_size, nblocks); -} - -/* - * devhandle list manipulators - */ - -void -fusb_devhandle_libusb1::pending_add (libusb_transfer *lut) -{ - d_pending_rqsts.push_back (lut); -} - - -/* - * Attempt to cancel all transations associated with eph - */ - -void -fusb_devhandle_libusb1::_cancel_pending_rqsts (fusb_ephandle_libusb1 *eph) -{ - std::list<libusb_transfer*>::reverse_iterator it; - - for (it = d_pending_rqsts.rbegin (); it != d_pending_rqsts.rend (); it++){ - if (lut_get_ephandle (*it) == eph) - _cancel_lut (*it); - } -} - -/* - * Pull from the pending list - */ - -libusb_transfer * -fusb_devhandle_libusb1::pending_get () -{ - if (d_pending_rqsts.empty ()) - return 0; - - libusb_transfer *lut = d_pending_rqsts.front (); - d_pending_rqsts.pop_front (); - return lut; -} - -/* - * Match libusb_tranfer with the pending list and erase - * Return true if found, false otherwise - */ - -bool -fusb_devhandle_libusb1::pending_remove (libusb_transfer *lut) -{ - std::list<libusb_transfer*>::iterator result; - result = find (d_pending_rqsts.begin (), d_pending_rqsts.end (), lut); - - if (result == d_pending_rqsts.end ()) { - fprintf (stderr, "fusb::pending_remove: failed to find lut in pending_rqsts: %p\n", lut); - - return false; - } - d_pending_rqsts.erase (result); - return true; -} - -/* - * Submit the libusb_transfer to libusb - * iff successful, the transfer will be placed on the devhandle pending list. - */ - -bool -fusb_devhandle_libusb1::_submit_lut (libusb_transfer *lut) -{ - - int ret = libusb_submit_transfer (lut); - if (ret < 0) { - fprintf(stderr, "fusb::_submit_lut %d", ret); - return false; - } - - pending_add(lut); - return true; - -} - -/* - * Attempt to cancel any pending libusb_transfer transactions. - * Return true in the absence of errors, which does not mean that the transfer - * is cancelled. Cancellation can be checked after the callback is fired off - * by libusb. - */ - -bool -fusb_devhandle_libusb1::_cancel_lut (libusb_transfer *lut) -{ - - int ret = libusb_cancel_transfer (lut); - if (ret < 0) { - fprintf (stderr, "fusb::_cancel_lut"); - return false; - } - return true; - -} - -/* - * Reimplementing _reap for context use and compatibiliy with libusb-0.12. - * - * Returns false on timeout or error, true if an event was handled - * - * If ok_to_block_p is false then handle already pending events and return - * immediately. - * - * If ok_to_block_p is true then call libusb_handle_events_timeout with default - * timeout value of 2 seconds, which waits and returns on event arrival or - * timeout. - */ - -bool -fusb_devhandle_libusb1::_reap (bool ok_to_block_p) -{ - int ret; - struct timeval tv; - - // Save pending size - int pnd_size = d_pending_rqsts.size(); - - if (ok_to_block_p) { - tv.tv_sec = 2; - tv.tv_usec = 0; - } - else { - tv.tv_sec = 0; - tv.tv_usec = 0; - } - - if ((ret = libusb_handle_events_timeout(d_ctx, &tv)) < 0) { - fprintf (stderr, "fusb::_reap libusb_handle_events() %i\n", ret); - return false; - } - - // Check that a pending transfer was removed - if (pnd_size > d_pending_rqsts.size()) - return true; - else { - return false; - } -} - -void -fusb_devhandle_libusb1::_wait_for_completion () -{ - - while (!d_pending_rqsts.empty ()) - if (!_reap(true)) - break; - -} - -// ------------------------------------------------------------------------ -// endpoint handle -// ------------------------------------------------------------------------ - -fusb_ephandle_libusb1::fusb_ephandle_libusb1 (fusb_devhandle_libusb1 *dh, - int endpoint, bool input_p, - int block_size, int nblocks) - : fusb_ephandle (endpoint, input_p, block_size, nblocks), - d_devhandle (dh), - 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_libusb1: block_size"); - - if (d_nblocks < 0) - throw std::out_of_range ("fusb_ephandle_libusb1: 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_libusb1::ctor: d_block_size = %d d_nblocks = %d\n", - d_block_size, d_nblocks); - - // allocate libusb_transfers - for (int i = 0; i < d_nblocks; i++) - d_free_list.push_back (alloc_lut (this, d_block_size, d_endpoint, - d_input_p, d_write_buffer, d_devhandle)); -} - -fusb_ephandle_libusb1::~fusb_ephandle_libusb1 () -{ - - stop (); - - libusb_transfer *lut; - - while ((lut = free_list_get ()) != 0) - free_lut (lut); - - while ((lut = completed_list_get ()) != 0) - free_lut (lut); - - if (d_write_work_in_progress) - free_lut (d_write_work_in_progress); - - delete [] d_write_buffer; - - if (d_read_work_in_progress) - free_lut (d_read_work_in_progress); - -} - -bool -fusb_ephandle_libusb1::start () -{ - if (d_started) - return true; - - d_started = true; - - if (d_input_p) { - libusb_transfer *lut; - - int nerrors = 0; - while ((lut = free_list_get ()) !=0 && nerrors < d_nblocks) { - if (!submit_lut (lut)) - nerrors++; - } - } - - return true; - -} - -/* - * Cancel all transfers in progress or pending and return to initial state - */ - -bool -fusb_ephandle_libusb1::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) { - libusb_transfer *lut; - while ((lut = completed_list_get ()) != 0) - free_list_add (lut); - - 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_libusb1::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; - - assert(nbytes % 512 == 0); - - unsigned char *src = (unsigned char *) buffer; - - int n = 0; - while (n < nbytes){ - - struct libusb_transfer *lut = get_write_work_in_progress(); - if (!lut) - return -1; - assert(lut->actual_length == 0); - int m = std::min(nbytes - n, MAX_BLOCK_SIZE); - lut->buffer = src; - lut->length = m; - - n += m; - src += m; - - if (!submit_lut(lut)) - return -1; - - d_write_work_in_progress = 0; - } - - return n; -} - -#else - -int -fusb_ephandle_libusb1::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){ - - libusb_transfer *lut = get_write_work_in_progress (); - if (!lut) - return -1; - unsigned char *dst = (unsigned char *) lut->buffer; - int m = std::min (nbytes - n, lut->length - lut->actual_length); - - memcpy (&dst[lut->actual_length], &src[n], m); - lut->actual_length += m; - n += m; - - if (lut->actual_length == lut->length){ - if (!submit_lut (lut)) - return -1; - d_write_work_in_progress = 0; - } - } - - return n; -} - -#endif - -struct libusb_transfer * -fusb_ephandle_libusb1::get_write_work_in_progress () -{ - if (d_write_work_in_progress) - return d_write_work_in_progress; - - while (1) { - - reap_complete_writes (); - - struct libusb_transfer *lut = free_list_get (); - - if (lut != 0){ - assert (lut->actual_length == 0); - d_write_work_in_progress = lut; - return lut; - } - - if (!d_devhandle->_reap (true)) - return 0; - } -} - -void -fusb_ephandle_libusb1::reap_complete_writes () -{ - // take a look at the completed list and xfer to free list after - // checking for errors. - - libusb_transfer *lut; - - while ((lut = completed_list_get ()) != 0) { - - // Check for any errors or short writes that were reporetd in the transfer. - // libusb1 sets status, actual_length. - - if (lut->status != LIBUSB_TRANSFER_COMPLETED) { - fprintf (stderr, "fusb: (status %d) \n", lut->status ); - } - else if (lut->actual_length != lut->length){ - fprintf (stderr, "fusb: short write xfer: %d != %d\n", - lut->actual_length, lut->length); - } - - free_list_add (lut); - } -} - -void -fusb_ephandle_libusb1::wait_for_completion () -{ - d_devhandle->_wait_for_completion (); -} - -// ------------------------------------------------------------------------ -// routines for reading -// ------------------------------------------------------------------------ - -int -fusb_ephandle_libusb1::read (void *buffer, int nbytes) -{ - if (!d_started) // doesn't matter here, but keeps semantics constant - 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_libusb1::reload_read_buffer () -{ - assert (d_read_buffer >= d_read_buffer_end); - - libusb_transfer *lut; - - if (d_read_work_in_progress) { - lut = d_read_work_in_progress; - d_read_work_in_progress = 0; - d_read_buffer = 0; - d_read_buffer_end = 0; - lut->actual_length = 0; - if (!submit_lut (lut)) - return false; - } - - while (1) { - - while ((lut = completed_list_get ()) == 0 ) - if (!d_devhandle->_reap(true)) - return false; - - if (lut->status != LIBUSB_TRANSFER_COMPLETED) { - fprintf (stderr, "fust: (rd status %d) %s\n", lut->status, - strerror (-lut->status)); - lut->actual_length = 0; - free_list_add (lut); - return false; - } - - d_read_work_in_progress = lut; - d_read_buffer = (unsigned char *) lut->buffer; - d_read_buffer_end = d_read_buffer + lut->actual_length; - - return true; - } -} - - -/* - * ephandle list manipulation - */ - - -void -fusb_ephandle_libusb1::free_list_add (libusb_transfer *lut) -{ - assert (lut_get_ephandle (lut) == this); - lut->actual_length = 0; - d_free_list.push_back (lut); -} - -libusb_transfer * -fusb_ephandle_libusb1::free_list_get () -{ - if (d_free_list.empty ()) - return 0; - - libusb_transfer *lut = d_free_list.front (); - d_free_list.pop_front (); - return lut; -} - -void -fusb_ephandle_libusb1::completed_list_add (libusb_transfer *lut) -{ - assert (lut_get_ephandle (lut) == this); - d_completed_list.push_back (lut); -} - -libusb_transfer * -fusb_ephandle_libusb1::completed_list_get () -{ - if (d_completed_list.empty ()) - return 0; - - libusb_transfer *lut = d_completed_list.front (); - d_completed_list.pop_front (); - return lut; -} - -bool -fusb_ephandle_libusb1::submit_lut (libusb_transfer *lut) -{ - if (!d_devhandle->_submit_lut (lut)) { - fprintf (stderr, "_submit_lut failed\n"); - free_list_add (lut); - return false; - } - return true; -} diff --git a/usrp/host/lib/fusb_libusb1.h b/usrp/host/lib/fusb_libusb1.h deleted file mode 100644 index c0e3736bd..000000000 --- a/usrp/host/lib/fusb_libusb1.h +++ /dev/null @@ -1,131 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2003,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 _FUSB_LIBUSB1_H_ -#define _FUSB_LIBUSB1_H_ - -#include <fusb.h> -#include <list> - -struct libusb_transfer; -struct libusb_context; - -class fusb_ephandle_libusb1; - -/*! - * \brief libusb1 implementation of fusb_devhandle - */ -class fusb_devhandle_libusb1 : public fusb_devhandle -{ -private: - std::list<libusb_transfer*> d_pending_rqsts; - libusb_context *d_ctx; - - void pending_add (struct libusb_transfer *lut); - struct libusb_transfer * pending_get (); - - bool d_teardown; - -public: - // CREATORS - fusb_devhandle_libusb1 (libusb_device_handle *udh, libusb_context *ctx); - virtual ~fusb_devhandle_libusb1 (); - - // MANIPULATORS - virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p, - int block_size = 0, int nblocks = 0); - // internal use only - bool _submit_lut (libusb_transfer *); - bool _cancel_lut (libusb_transfer *); - void _cancel_pending_rqsts (fusb_ephandle_libusb1 *eph); - bool _reap (bool ok_to_block_p); - void _wait_for_completion (); - - // accessors to work from callback context - bool pending_remove (struct libusb_transfer *lut); - inline bool _teardown() { return d_teardown; } - -}; - - -/*! - * \brief libusb1 implementation of fusb_ephandle - */ -class fusb_ephandle_libusb1 : public fusb_ephandle -{ -private: - fusb_devhandle_libusb1 *d_devhandle; - std::list<libusb_transfer*> d_free_list; - std::list<libusb_transfer*> d_completed_list; - libusb_transfer *d_write_work_in_progress; - unsigned char *d_write_buffer; - libusb_transfer *d_read_work_in_progress; - unsigned char *d_read_buffer; - unsigned char *d_read_buffer_end; - - libusb_transfer *get_write_work_in_progress (); - void reap_complete_writes (); - bool reload_read_buffer (); - bool submit_lut (libusb_transfer *lut); - -public: - // CREATORS - fusb_ephandle_libusb1 (fusb_devhandle_libusb1 *dh, int endpoint, bool input_p, - int block_size = 0, int nblocks = 0); - virtual ~fusb_ephandle_libusb1 (); - - // 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 (); - - void free_list_add (struct libusb_transfer *lut); - void completed_list_add (struct libusb_transfer *lut); - struct libusb_transfer *free_list_get (); - struct libusb_transfer *completed_list_get (); - - // accessor to work from callback context - fusb_devhandle_libusb1* get_fusb_devhandle_libusb1 () const { - return d_devhandle; - } -}; - -#endif /* _FUSB_LINUX1_H_ */ - diff --git a/usrp/host/lib/fusb_linux.cc b/usrp/host/lib/fusb_linux.cc deleted file mode 100644 index 6c484569f..000000000 --- a/usrp/host/lib/fusb_linux.cc +++ /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; -} -// ------------------------------------------------------------------------ -// 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 deleted file mode 100644 index 107e1af70..000000000 --- a/usrp/host/lib/fusb_linux.h +++ /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 (); -}; - -/*! - * \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 deleted file mode 100644 index 699a34b39..000000000 --- a/usrp/host/lib/fusb_ra_wb.cc +++ /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/fusb_ra_wb.h b/usrp/host/lib/fusb_ra_wb.h deleted file mode 100644 index 233976abe..000000000 --- a/usrp/host/lib/fusb_ra_wb.h +++ /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/fusb_sysconfig_darwin.cc b/usrp/host/lib/fusb_sysconfig_darwin.cc deleted file mode 100644 index 68dd64815..000000000 --- a/usrp/host/lib/fusb_sysconfig_darwin.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2003,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 <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, libusb_context *ctx) -{ - 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 deleted file mode 100644 index e0986510c..000000000 --- a/usrp/host/lib/fusb_sysconfig_generic.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2003,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 <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, libusb_context *ctx) -{ - 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_libusb1.cc b/usrp/host/lib/fusb_sysconfig_libusb1.cc deleted file mode 100644 index 46daf561a..000000000 --- a/usrp/host/lib/fusb_sysconfig_libusb1.cc +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2003,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 <fusb.h> -#include <fusb_libusb1.h> - -static const int MAX_BLOCK_SIZE = 16 * 1024; // hard limit -static const int DEFAULT_BLOCK_SIZE = 4 * 1024; -static const int FUSB_BUFFER_SIZE = 1 * (1L << 20); // 1 MB - -struct libusb_context; - -fusb_devhandle * -fusb_sysconfig::make_devhandle (libusb_device_handle *udh, libusb_context *ctx) -{ - return new fusb_devhandle_libusb1 (udh, ctx); -} - -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_linux.cc b/usrp/host/lib/fusb_sysconfig_linux.cc deleted file mode 100644 index e33b90ba4..000000000 --- a/usrp/host/lib/fusb_sysconfig_linux.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2003,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 <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, libusb_context *ctx) -{ - 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 deleted file mode 100644 index c527e3099..000000000 --- a/usrp/host/lib/fusb_sysconfig_ra_wb.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2003,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. - */ - -#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, libusb_context *ctx) -{ - 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 deleted file mode 100644 index fb4be8829..000000000 --- a/usrp/host/lib/fusb_sysconfig_win32.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2003,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 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, libusb_context *ctx) -{ - 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 deleted file mode 100644 index 8c218534b..000000000 --- a/usrp/host/lib/fusb_win32.cc +++ /dev/null @@ -1,267 +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> -#include <cstdio> - -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 deleted file mode 100644 index 3ad2132f4..000000000 --- a/usrp/host/lib/fusb_win32.h +++ /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/gen-ratios b/usrp/host/lib/gen-ratios deleted file mode 100755 index 2250090d7..000000000 --- a/usrp/host/lib/gen-ratios +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python -# -*- python -*- - -def how_good (x): - pof2 = [1,2,4,8,16] - if x in pof2: - return 0 - if x in map (lambda x: x+1, pof2): - return -10 - if x in map (lambda x: x-1, pof2): - return -5 - return -2 - - -def better (v1, v2): - return abs ((v1 & 0xf) - ((v1 >> 4) & 0xf)) < abs ((v2 & 0xf) - ((v2 >> 4) & 0xf)) - - -def foo (): - result = {} - for i in range (1,17): - for j in range (1,17): - i_goodness = how_good (i) - j_goodness = how_good (j) - goodness = i_goodness + j_goodness - v = ((i - 1) << 4) | (j - 1) - - key = i * j - prev = result.get (key, None) - # print "i=%3d j=%3d key=%3d good=%3d v=0x%02x prev=%s" % (i, j, key, goodness, v, prev) - - if not prev: - result[key] = (goodness, v) - elif goodness > prev[0]: - result[key] = (goodness, v) - elif goodness == prev[0] and better(v, prev[1]): - result[key] = (goodness, v) - - r = result.items () - r.sort () - for k, d in r: - print "(%3d, 0x%02x)" % (k, d[1]) - - - -foo () - - diff --git a/usrp/host/lib/gen_usrp_dbid.py b/usrp/host/lib/gen_usrp_dbid.py deleted file mode 100755 index c7d3770c1..000000000 --- a/usrp/host/lib/gen_usrp_dbid.py +++ /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('../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/limbo/db_wbx.cc b/usrp/host/lib/limbo/db_wbx.cc deleted file mode 100644 index 9f1d72939..000000000 --- a/usrp/host/lib/limbo/db_wbx.cc +++ /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/limbo/db_wbx.h b/usrp/host/lib/limbo/db_wbx.h deleted file mode 100644 index 3202d368c..000000000 --- a/usrp/host/lib/limbo/db_wbx.h +++ /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/md5.c b/usrp/host/lib/md5.c deleted file mode 100644 index b15ab390f..000000000 --- a/usrp/host/lib/md5.c +++ /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/md5.h b/usrp/host/lib/md5.h deleted file mode 100644 index 4a4e790c1..000000000 --- a/usrp/host/lib/md5.h +++ /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/rate_to_regval.h b/usrp/host/lib/rate_to_regval.h deleted file mode 100644 index 1ffdc0f69..000000000 --- a/usrp/host/lib/rate_to_regval.h +++ /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/std_paths.h.in b/usrp/host/lib/std_paths.h.in deleted file mode 100644 index e09499e0b..000000000 --- a/usrp/host/lib/std_paths.h.in +++ /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/usrp_basic.cc b/usrp/host/lib/usrp_basic.cc deleted file mode 100644 index 5b2f7ff71..000000000 --- a/usrp/host/lib/usrp_basic.cc +++ /dev/null @@ -1,1538 +0,0 @@ -/* -*- 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 <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 libusb_device_handle * -open_rx_interface (libusb_device *dev) -{ - libusb_device_handle *udh = usrp_open_rx_interface (dev); - if (udh == 0){ - fprintf (stderr, "usrp_basic_rx: can't open rx interface\n"); - } - return udh; -} - -static libusb_device_handle * -open_tx_interface (libusb_device *dev) -{ - libusb_device_handle *udh = usrp_open_tx_interface (dev); - if (udh == 0){ - fprintf (stderr, "usrp_basic_tx: can't open tx interface\n"); - } - 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, - libusb_device_handle * - open_interface (libusb_device *dev), - const std::string fpga_filename, - const std::string firmware_filename) - : d_udh (0), d_ctx (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 (&d_ctx); - - if (!usrp_load_standard_bits (which_board, false, fpga_filename, - firmware_filename, d_ctx)) - throw std::runtime_error ("usrp_basic/usrp_load_standard_bits"); - - libusb_device *dev = usrp_find_device (which_board, false, d_ctx); - 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 - -} - -usrp_basic::~usrp_basic () -{ - d_db.resize(0); // forget db shared ptrs - - if (d_udh) - usrp_close_interface (d_udh); - - usrp_deinit (d_ctx); -} - -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(); -} - -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_ctx); - 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"); - } - - 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"); - return false; - } - - if (!set_rx_enable (true)){ - fprintf (stderr, "usrp_basic_rx: set_rx_enable failed\n"); - 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"); - ok = false; - } - - if (!d_ephandle->stop()){ - fprintf (stderr, "usrp_basic_rx: failed to stop end point streaming"); - 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"); - } - } - - 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_ctx); - 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"); - return false; - } - - if (!d_ephandle->start ()){ - fprintf (stderr, "usrp_basic_tx: failed to start end point streaming"); - 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"); - ok = false; - } - - if (!set_tx_enable (false)){ - fprintf (stderr, "usrp_basic_tx: set_tx_enable(false) failed\n"); - 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"); - } - } - - 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 deleted file mode 100644 index fcf207f68..000000000 --- a/usrp/host/lib/usrp_config.cc +++ /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/usrp_config.h b/usrp/host/lib/usrp_config.h deleted file mode 100644 index ee5cb63bd..000000000 --- a/usrp/host/lib/usrp_config.h +++ /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/usrp_dbid.dat b/usrp/host/lib/usrp_dbid.dat deleted file mode 100644 index 2548d737e..000000000 --- a/usrp/host/lib/usrp_dbid.dat +++ /dev/null @@ -1,93 +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 2200 Rx MIMO B" 0x002c -"Flex 2200 Tx MIMO B" 0x002d - -"Flex 1800 Rx" 0x0030 -"Flex 1800 Tx" 0x0031 -"Flex 1800 Rx MIMO A" 0x0032 -"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 -"TV Rx MIMO" 0x0043 -"TV Rx Rev 2 MIMO" 0x0044 -"TV Rx Rev 3 MIMO" 0x0045 - -"WBX LO TX" 0x0050 -"WBX LO RX" 0x0051 - -"WBX NG TX" 0x0052 -"WBX NG RX" 0x0053 - -"XCVR2450 Tx" 0x0060 -"XCVR2450 Rx" 0x0061 - -"Bitshark Rx" 0x0070 - -"Experimental Tx" 0xfffe -"Experimental Rx" 0xffff diff --git a/usrp/host/lib/usrp_local_sighandler.cc b/usrp/host/lib/usrp_local_sighandler.cc deleted file mode 100644 index 59013972e..000000000 --- a/usrp/host/lib/usrp_local_sighandler.cc +++ /dev/null @@ -1,191 +0,0 @@ -/* -*- 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_common.cc b/usrp/host/lib/usrp_prims_common.cc deleted file mode 100644 index 20a55653c..000000000 --- a/usrp/host/lib/usrp_prims_common.cc +++ /dev/null @@ -1,1241 +0,0 @@ -/* -*- 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_primsi.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 <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> -#include "std_paths.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"; - -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 (libusb_device_handle *udh); - - -// ---------------------------------------------------------------- - -/* - * q must be a real USRP, not an FX2. Return its hardware rev number. - */ - -int -usrp_hw_rev (libusb_device *q) -{ - libusb_device_descriptor desc = _get_usb_device_descriptor(q); - return desc.bcdDevice & 0x00FF; -} - -/* - * q must be a real USRP, not an FX2. Return true if it's configured. - */ -static bool -_usrp_configured_p (libusb_device *q) -{ - libusb_device_descriptor desc = _get_usb_device_descriptor(q); - return (desc.bcdDevice & 0xFF00) != 0; -} - -bool -usrp_usrp_p (libusb_device *q) -{ - libusb_device_descriptor desc = _get_usb_device_descriptor(q); - return (desc.idVendor == USB_VID_FSF - && desc.idProduct == USB_PID_FSF_USRP); -} - -bool -usrp_fx2_p (libusb_device *q) -{ - libusb_device_descriptor desc = _get_usb_device_descriptor(q); - return (desc.idVendor == USB_VID_CYPRESS - && desc.idProduct == USB_PID_CYPRESS_FX2); -} - -bool -usrp_usrp0_p (libusb_device *q) -{ - return usrp_usrp_p (q) && usrp_hw_rev (q) == 0; -} - -bool -usrp_usrp1_p (libusb_device *q) -{ - return usrp_usrp_p (q) && usrp_hw_rev (q) == 1; -} - -bool -usrp_usrp2_p (libusb_device *q) -{ - return usrp_usrp_p (q) && usrp_hw_rev (q) == 2; -} - - -bool -usrp_unconfigured_usrp_p (libusb_device *q) -{ - return usrp_usrp_p (q) && !_usrp_configured_p (q); -} - -bool -usrp_configured_usrp_p (libusb_device *q) -{ - return usrp_usrp_p (q) && _usrp_configured_p (q); -} - - -// ---------------------------------------------------------------- - - -libusb_device_handle * -usrp_open_cmd_interface (libusb_device *dev) -{ - return usrp_open_interface (dev, USRP_CMD_INTERFACE, USRP_CMD_ALTINTERFACE); -} - -libusb_device_handle * -usrp_open_rx_interface (libusb_device *dev) -{ - return usrp_open_interface (dev, USRP_RX_INTERFACE, USRP_RX_ALTINTERFACE); -} - -libusb_device_handle * -usrp_open_tx_interface (libusb_device *dev) -{ - return usrp_open_interface (dev, USRP_TX_INTERFACE, USRP_TX_ALTINTERFACE); -} - - -// ---------------------------------------------------------------- -// write internal ram using Cypress vendor extension - -static bool -write_internal_ram (libusb_device_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_transfer (udh, 0x40, 0xA0, addr, 0, - (unsigned char*)(buf + (addr - start_addr)), n, 1000); - - if (a < 0){ - fprintf(stderr,"write_internal_ram failed\n"); - return false; - } - } - return true; -} - - -// ---------------------------------------------------------------- -// whack the CPUCS register using the upload RAM vendor extension - -static bool -reset_cpu (libusb_device_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 (libusb_device_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; -} - -// ---------------------------------------------------------------- -// load fpga - -static bool -_usrp_load_fpga (libusb_device_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 (libusb_device_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 (libusb_device_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_transfer (udh, 0x40, 0xa0, hash_slot_addr[which], 0, - (unsigned char *) hash, USRP_HASH_SIZE, 1000); - - if (r < 0) - fprintf (stderr, "usrp: failed to set hash\n"); - - return r == USRP_HASH_SIZE; -} - -bool -usrp_get_hash (libusb_device_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_transfer (udh, 0xc0, 0xa0, hash_slot_addr[which], 0, - (unsigned char *) hash, USRP_HASH_SIZE, 1000); - - if (r < 0) - fprintf (stderr, "usrp: failed to get hash\n"); - - return r == USRP_HASH_SIZE; -} - - - -static bool -usrp_set_switch (libusb_device_handle *udh, int cmd_byte, bool on) -{ - return write_cmd (udh, cmd_byte, on, 0, 0, 0) == 0; -} - -static bool -usrp1_fpga_write (libusb_device_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 (libusb_device_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 (libusb_device_handle *udh, int reg, int value) -{ - switch (usrp_hw_rev (_get_usb_device (udh))){ - case 0: // not supported ;) - abort(); - - default: - return usrp1_fpga_write (udh, reg, value); - } -} - -bool -usrp_read_fpga_reg (libusb_device_handle *udh, int reg, int *value) -{ - switch (usrp_hw_rev (_get_usb_device (udh))){ - case 0: // not supported ;) - abort(); - - default: - return usrp1_fpga_read (udh, reg, value); - } -} - -bool -usrp_set_fpga_reset (libusb_device_handle *udh, bool on) -{ - return usrp_set_switch (udh, VRQ_FPGA_SET_RESET, on); -} - -bool -usrp_set_fpga_tx_enable (libusb_device_handle *udh, bool on) -{ - return usrp_set_switch (udh, VRQ_FPGA_SET_TX_ENABLE, on); -} - -bool -usrp_set_fpga_rx_enable (libusb_device_handle *udh, bool on) -{ - return usrp_set_switch (udh, VRQ_FPGA_SET_RX_ENABLE, on); -} - -bool -usrp_set_fpga_tx_reset (libusb_device_handle *udh, bool on) -{ - return usrp_set_switch (udh, VRQ_FPGA_SET_TX_RESET, on); -} - -bool -usrp_set_fpga_rx_reset (libusb_device_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 (libusb_device_handle *udh, - const char *filename, - bool force, - int slot, - bool loader (libusb_device_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 (libusb_device_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 (libusb_device_handle *udh, - const char *filename, - bool force) -{ - return usrp_conditionally_load_something (udh, filename, force, - FPGA_HASH_SLOT, - _usrp_load_fpga); -} - -static libusb_device_handle * -open_nth_cmd_interface (int nth, libusb_context *ctx) -{ - - libusb_device *udev = usrp_find_device (nth, false, ctx); - if (udev == 0){ - fprintf (stderr, "usrp: failed to find usrp[%d]\n", nth); - return 0; - } - - libusb_device_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"); - 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, libusb_context *ctx) -{ - libusb_device_handle *udh = open_nth_cmd_interface (nth, ctx); - 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 2 second - t.tv_sec = 2; - t.tv_nsec = 0; - our_nanosleep (&t); - - usrp_rescan (); - - 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, - libusb_context *ctx) -{ - 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 - { - libusb_device *udev = usrp_find_device (nth, false, ctx); - 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, ctx); - 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; - } - libusb_device_handle *udh = open_nth_cmd_interface (nth, ctx); - 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 (libusb_device_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 (libusb_device_handle *udh, bool *overrun_p) -{ - return _usrp_get_status (udh, GS_RX_OVERRUN, overrun_p); -} - -bool -usrp_check_tx_underrun (libusb_device_handle *udh, bool *underrun_p) -{ - return _usrp_get_status (udh, GS_TX_UNDERRUN, underrun_p); -} - - -bool -usrp_i2c_write (libusb_device_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 (libusb_device_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 (libusb_device_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 (libusb_device_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 (libusb_device_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 (libusb_device_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 (libusb_device_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 (libusb_device_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 (libusb_device_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 (_get_usb_device (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 (libusb_device_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 (libusb_device_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 (libusb_device_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 (libusb_device_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 (libusb_device_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 (libusb_device_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 (libusb_device_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(libusb_device_handle *udh) -{ - libusb_device_descriptor desc = - _get_usb_device_descriptor (_get_usb_device (udh)); - - unsigned char iserial = desc.iSerialNumber; - if (iserial == 0) - return ""; - - unsigned char buf[1024]; - if (_get_usb_string_descriptor (udh, iserial, buf, sizeof(buf)) < 0) - return ""; - - return (char*) buf; -} - - - - diff --git a/usrp/host/lib/usrp_prims_libusb0.cc b/usrp/host/lib/usrp_prims_libusb0.cc deleted file mode 100644 index 4fbfabea9..000000000 --- a/usrp/host/lib/usrp_prims_libusb0.cc +++ /dev/null @@ -1,230 +0,0 @@ -/* -*- 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_primsi.h" -#include "usrp_commands.h" -#include <usb.h> -#include <errno.h> -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <ad9862.h> -#include <assert.h> - -extern "C" { -#include "md5.h" -}; - -using namespace ad9862; - -/* - * libusb 0.12 / 1.0 compatibility - */ - -struct usb_device * -_get_usb_device (struct usb_dev_handle *udh) -{ - return usb_device (udh); -} - -struct usb_device_descriptor -_get_usb_device_descriptor (struct usb_device *q) -{ - return q->descriptor; -} - -int -_get_usb_string_descriptor (struct usb_dev_handle *udh, int index, - unsigned char* data, int length) -{ - int ret; - ret = usb_get_string_simple (udh, index, (char*) data, length); - - if (ret < 0) { - fprintf (stderr, "usrp: usb_get_string_descriptor failed: %s\n", - usb_strerror()); - } - - return ret; -} - -int -_usb_control_transfer (struct usb_dev_handle *udh, int request_type, - int request, int value, int index, - unsigned char *data, int length, unsigned int timeout) -{ - int ret; - - ret = usb_control_msg (udh, request_type,request, value, index, - (char*) data, length, (int) timeout); - if (ret < 0) - fprintf (stderr, "usrp: usb_control_msg failed: %s\n", usb_strerror()); - - return ret; -} - - -// ---------------------------------------------------------------- - - -void -usrp_one_time_init (libusb_context **ctx) -{ - static bool first = true; - - if (first) { - first = false; - usb_init (); // usb library init - usb_find_busses (); - usb_find_devices (); - } -} - -void -usrp_deinit (libusb_context *ctx) -{ - // nop -} - -void -usrp_rescan () -{ - usb_find_busses (); - usb_find_devices (); -} - - -// ---------------------------------------------------------------- - - -struct usb_device * -usrp_find_device (int nth, bool fx2_ok_p, libusb_context *ctx) -{ - 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 -} - -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 != usb_device (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; -} - -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 vendor extension command to USRP - - -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 ()); - fprintf (stderr, "write_cmd failed\n"); - } - } - - return r; -} - diff --git a/usrp/host/lib/usrp_prims_libusb1.cc b/usrp/host/lib/usrp_prims_libusb1.cc deleted file mode 100644 index 5dfe416e1..000000000 --- a/usrp/host/lib/usrp_prims_libusb1.cc +++ /dev/null @@ -1,276 +0,0 @@ -/* -*- 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_primsi.h" -#include "usrp_commands.h" -#include <libusb-1.0/libusb.h> -#include <errno.h> -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <ad9862.h> -#include <assert.h> - -extern "C" { -#include "md5.h" -}; - -using namespace ad9862; - -static const int LIBUSB1_DEBUG = 0; - -/* - * libusb 0.12 / 1.0 compatibility - */ - -static const char * -_get_usb_error_str (int usb_err) -{ - switch (usb_err) { - case LIBUSB_SUCCESS: - return "Success (no error)"; - case LIBUSB_ERROR_IO: - return "Input/output error"; - case LIBUSB_ERROR_INVALID_PARAM: - return "Invalid parameter"; - case LIBUSB_ERROR_ACCESS: - return "Access denied (insufficient permissions)"; - case LIBUSB_ERROR_NO_DEVICE: - return "No such device (it may have been disconnected)"; - case LIBUSB_ERROR_NOT_FOUND: - return "Entity not found"; - case LIBUSB_ERROR_BUSY: - return "Resource busy"; - case LIBUSB_ERROR_TIMEOUT: - return "Operation timed out"; - case LIBUSB_ERROR_OVERFLOW: - return "Overflow"; - case LIBUSB_ERROR_PIPE: - return "Pipe error"; - case LIBUSB_ERROR_INTERRUPTED: - return "System call interrupted (perhaps due to signal)"; - case LIBUSB_ERROR_NO_MEM: - return "Insufficient memory"; - case LIBUSB_ERROR_NOT_SUPPORTED: - return "Operation not supported or unimplemented on this platform"; - case LIBUSB_ERROR_OTHER: - return "Unknown error"; - } - - return "Unknown error"; -} - -struct libusb_device * -_get_usb_device (struct libusb_device_handle *udh) -{ - return libusb_get_device (udh); -} - -struct libusb_device_descriptor -_get_usb_device_descriptor(struct libusb_device *q) -{ - int ret; - struct libusb_device_descriptor desc; - - ret = libusb_get_device_descriptor(q, &desc); - - if (ret < 0) { - fprintf (stderr, "usrp: libusb_get_device_descriptor failed: %s\n", - _get_usb_error_str(ret)); - } - return desc; -} - -int -_get_usb_string_descriptor (struct libusb_device_handle *udh, int index, - unsigned char* data, int length) -{ - int ret; - ret = libusb_get_string_descriptor_ascii (udh, (uint8_t) index, data, length); - - if (ret < 0) { - fprintf (stderr, "usrp: libusb_get_string_descriptor_ascii failed: %s\n", - _get_usb_error_str(ret)); - } - return ret; -} - -int -_usb_control_transfer (struct libusb_device_handle *udh, int request_type, - int request, int value, int index, - unsigned char *data, int length, unsigned int timeout) -{ - int ret; - ret = libusb_control_transfer (udh, request_type, request, value, index, - data, length, timeout); - if (ret < 0) { - fprintf (stderr, "usrp: libusb_control_transfer failed: %s\n", - _get_usb_error_str(ret)); - } - return ret; -} - - -// ---------------------------------------------------------------- - - -void -usrp_one_time_init (libusb_context **ctx) -{ - int ret; - - if ((ret = libusb_init (ctx)) < 0) - fprintf (stderr, "usrp: libusb_init failed: %s\n", _get_usb_error_str(ret)); - - // Enable debug verbosity if requested. This will only work if the debug - // option is compiled into libusb and may produce a generous amount of output - // on stdout. If debug output is not compiled into libusb, this call does - // nothing. - if (LIBUSB1_DEBUG) - libusb_set_debug(*ctx, 3); -} - -void -usrp_deinit (struct libusb_context *ctx) -{ - // Each object _should_ be running in its own context. If running in default - // context then leave the instance open as it may be shared. - if (ctx != NULL) - libusb_exit (ctx); -} - -void -usrp_rescan () -{ - // nop -} - -struct libusb_device * -usrp_find_device (int nth, bool fx2_ok_p, libusb_context *ctx) -{ - libusb_device **list; - - struct libusb_device *q; - int n_found = 0; - - // Make sure not operating on default context. There are cases where operating - // with a single global (NULL) context may be preferable, so this check can be - // skipped if you know what you're doing. - assert (ctx != NULL); - - size_t cnt = libusb_get_device_list(ctx, &list); - size_t i = 0; - - if (cnt < 0) - fprintf(stderr, "usrp: libusb_get_device_list failed: %s\n", - _get_usb_error_str(cnt)); - - for (i = 0; i < cnt; i++) { - q = list[i]; - 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 - } - } - - // The list needs to be freed. Right now just release it if nothing is found. - libusb_free_device_list(list, 1); - - return 0; // not found -} - -struct libusb_device_handle * -usrp_open_interface (libusb_device *dev, int interface, int altinterface) -{ - libusb_device_handle *udh; - int ret; - - if (libusb_open (dev, &udh) < 0) - return 0; - - if (dev != libusb_get_device (udh)){ - fprintf (stderr, "%s:%d: internal error!\n", __FILE__, __LINE__); - abort (); - } - - if ((ret = libusb_claim_interface (udh, interface)) < 0) { - fprintf (stderr, "%s:usb_claim_interface: failed interface %d\n", - __FUNCTION__, interface); - fprintf (stderr, "%s\n", _get_usb_error_str(ret)); - libusb_close (udh); - return 0; - } - - if ((ret = libusb_set_interface_alt_setting (udh, interface, - altinterface)) < 0) { - fprintf (stderr, "%s:usb_set_alt_interface: failed\n", __FUNCTION__); - fprintf (stderr, "%s\n", _get_usb_error_str(ret)); - libusb_release_interface (udh, interface); - libusb_close (udh); - return 0; - } - - return udh; -} - -bool -usrp_close_interface (libusb_device_handle *udh) -{ - // returns void - libusb_close(udh); - return 0; -} - - -// ---------------------------------------------------------------- -// write vendor extension command to USRP - - -int -write_cmd (struct libusb_device_handle *udh, - int request, int value, int index, - unsigned char *bytes, int len) -{ - int requesttype = (request & 0x80) ? VRT_VENDOR_IN : VRT_VENDOR_OUT; - - int ret = libusb_control_transfer(udh, requesttype, request, value, index, - bytes, len, 1000); - - if (ret < 0) { - // we get EPIPE if the firmware stalls the endpoint. - if (ret != LIBUSB_ERROR_PIPE) { - fprintf (stderr, "usrp: libusb_control_transfer failed: %s\n", - _get_usb_error_str(ret)); - fprintf (stderr, "usrp: write_cmd failed\n"); - } - } - - return ret; -} - diff --git a/usrp/host/lib/usrp_primsi.h b/usrp/host/lib/usrp_primsi.h deleted file mode 100644 index b1cf7263a..000000000 --- a/usrp/host/lib/usrp_primsi.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2003,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. - */ - -/* - * Internal usrp_prims header file - */ - -#ifndef _USRP_PRIMSI_H_ -#define _USRP_PRIMSI_H_ - -#include "usrp/usrp_prims.h" - -/* - * Internal functions - */ - -libusb_device_handle * -usrp_open_interface(libusb_device *dev, int interface, int altinterface); - -int write_cmd (libusb_device_handle *udh, int request, int value, int index, - unsigned char *bytes, int len); - -/* - * Compatibility functions - */ - -libusb_device *_get_usb_device (libusb_device_handle *udh); - -libusb_device_descriptor _get_usb_device_descriptor (libusb_device *q); - -int _get_usb_string_descriptor (libusb_device_handle *udh, int index, - unsigned char* data, int length); - -int _usb_control_transfer (libusb_device_handle *udh, int request_type, - int request, int value, int index, - unsigned char *data, int length, - unsigned int timeout); - -#endif /* _USRP_PRIMSI_H_ */ - diff --git a/usrp/host/lib/usrp_standard.cc b/usrp/host/lib/usrp_standard.cc deleted file mode 100644 index fe5afabdb..000000000 --- a/usrp/host/lib/usrp_standard.cc +++ /dev/null @@ -1,1175 +0,0 @@ -/* -*- 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#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; - - double coarse_freq_1 = dac_rate () / 8; // First coarse frequency - double coarse_freq_2 = dac_rate () / 4; // Second coarse frequency - double coarse_limit_1 = coarse_freq_1 / 2; // Midpoint of [0 , freq1] range - double coarse_limit_2 = (coarse_freq_1 + coarse_freq_2) / 2; // Midpoint of [freq1 , freq2] range - double high_limit = (double)44e6/128e6*dac_rate (); // Highest meaningful frequency - - if (freq < -high_limit) // too low - return false; - else if (freq < -coarse_limit_2){ // For 64MHz: [-44, -24) - cm = CM_NEG_FDAC_OVER_4; - coarse = -coarse_freq_2; - } - else if (freq < -coarse_limit_1){ // For 64MHz: [-24, -8) - cm = CM_NEG_FDAC_OVER_8; - coarse = -coarse_freq_1; - } - else if (freq < coarse_limit_1){ // For 64MHz: [-8, 8) - cm = CM_OFF; - coarse = 0; - } - else if (freq < coarse_limit_2){ // For 64MHz: [8, 24) - cm = CM_POS_FDAC_OVER_8; - coarse = coarse_freq_1; - } - else if (freq <= high_limit){ // For 64MHz: [24, 44] - cm = CM_POS_FDAC_OVER_4; - coarse = coarse_freq_2; - } - 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); -} |