/* -*- c++ -*- */
/*
- * Copyright 2003,2004 Free Software Foundation, Inc.
- *
+ * 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 2, or (at your option)
+ * the Free Software Foundation; either version 3, or (at your option)
* any later version.
- *
+ *
* GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR 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,
#include "config.h"
#endif
-#include "usrp_basic.h"
-#include "usrp_prims.h"
+#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 <usb.h>
+#include "db_boards.h"
#include <stdexcept>
#include <assert.h>
#include <math.h>
#include <ad9862.h>
+#include <string.h>
+#include <cstdio>
using namespace ad9862;
////////////////////////////////////////////////////////////////
-static struct usb_dev_handle *
-open_rx_interface (struct usb_device *dev)
+static libusb_device_handle *
+open_rx_interface (libusb_device *dev)
{
- struct usb_dev_handle *udh = usrp_open_rx_interface (dev);
+ libusb_device_handle *udh = usrp_open_rx_interface (dev);
if (udh == 0){
fprintf (stderr, "usrp_basic_rx: can't open rx interface\n");
- usb_strerror ();
}
return udh;
}
-static struct usb_dev_handle *
-open_tx_interface (struct usb_device *dev)
+static libusb_device_handle *
+open_tx_interface (libusb_device *dev)
{
- struct usb_dev_handle *udh = usrp_open_tx_interface (dev);
+ libusb_device_handle *udh = usrp_open_tx_interface (dev);
if (udh == 0){
fprintf (stderr, "usrp_basic_tx: can't open tx interface\n");
- usb_strerror ();
}
return udh;
}
-
//////////////////////////////////////////////////////////////////
//
// usrp_basic
//
////////////////////////////////////////////////////////////////
-
// Given:
// CLKIN = 64 MHz
-// CLKSEL pin = high
+// CLKSEL pin = high
//
// These settings give us:
// CLKOUT1 = CLKIN = 64 MHz
REG_AUX_ADC_CLK, AUX_ADC_CLK_CLK_OVER_4
};
-
-usrp_basic::usrp_basic (int which_board,
- struct usb_dev_handle *
- open_interface (struct usb_device *dev),
+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_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_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.
+ * 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 ();
+ usrp_one_time_init (&d_ctx);
- if (!usrp_load_standard_bits (which_board, false, fpga_filename, firmware_filename))
+ if (!usrp_load_standard_bits (which_board, false, fpga_filename,
+ firmware_filename, d_ctx))
throw std::runtime_error ("usrp_basic/usrp_load_standard_bits");
- struct usb_device *dev = usrp_find_device (which_board);
+ 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");
// initialize registers that are common to rx and tx
- if (!usrp_9862_write_many_all (d_udh, common_regs, sizeof (common_regs))){
+ 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)
- usb_close (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
}
bool
-usrp_basic::write_aux_dac (int slot, int which_dac, int value)
+usrp_basic::_write_aux_dac (int slot, int which_dac, int value)
{
return usrp_write_aux_dac (d_udh, slot, which_dac, value);
}
bool
-usrp_basic::read_aux_adc (int slot, int which_adc, int *value)
+usrp_basic::_read_aux_adc (int slot, int which_adc, int *value)
{
return usrp_read_aux_adc (d_udh, slot, which_adc, value);
}
int
-usrp_basic::read_aux_adc (int slot, int which_adc)
+usrp_basic::_read_aux_adc (int slot, int which_adc)
{
int value;
- if (!read_aux_adc (slot, which_adc, &value))
+ if (!_read_aux_adc (slot, which_adc, &value))
return READ_FAILED;
return value;
// ----------------------------------------------------------------
bool
-usrp_basic::set_adc_offset (int which, int offset)
+usrp_basic::set_adc_offset (int which_adc, int offset)
{
- if (which < 0 || which > 3)
+ if (which_adc < 0 || which_adc > 3)
return false;
- return _write_fpga_reg (FR_ADC_OFFSET_0 + which, offset);
+ return _write_fpga_reg (FR_ADC_OFFSET_0 + which_adc, offset);
}
bool
-usrp_basic::set_dac_offset (int which, int offset, int offset_pin)
+usrp_basic::set_dac_offset (int which_dac, int offset, int offset_pin)
{
- if (which < 0 || which > 3)
+ if (which_dac < 0 || which_dac > 3)
return false;
- int which_codec = which >> 1;
- int tx_a = (which & 0x1) == 0;
+ int which_codec = which_dac >> 1;
+ int tx_a = (which_dac & 0x1) == 0;
int lo = ((offset & 0x3) << 6) | (offset_pin & 0x1);
int hi = (offset >> 2);
bool ok;
}
bool
-usrp_basic::set_adc_buffer_bypass (int which, bool bypass)
+usrp_basic::set_adc_buffer_bypass (int which_adc, bool bypass)
{
- if (which < 0 || which > 3)
+ if (which_adc < 0 || which_adc > 3)
return false;
- int codec = which >> 1;
- int reg = (which & 1) == 0 ? REG_RX_A : REG_RX_B;
+ int codec = which_adc >> 1;
+ int reg = (which_adc & 1) == 0 ? REG_RX_A : REG_RX_B;
unsigned char cur_rx;
unsigned char cur_pwr_dn;
if (bypass){
cur_rx |= RX_X_BYPASS_INPUT_BUFFER;
- cur_pwr_dn |= ((which & 1) == 0) ? RX_PWR_DN_BUF_A : RX_PWR_DN_BUF_B;
+ cur_pwr_dn |= ((which_adc & 1) == 0) ? RX_PWR_DN_BUF_A : RX_PWR_DN_BUF_B;
}
else {
cur_rx &= ~RX_X_BYPASS_INPUT_BUFFER;
- cur_pwr_dn &= ~(((which & 1) == 0) ? RX_PWR_DN_BUF_A : RX_PWR_DN_BUF_B);
+ cur_pwr_dn &= ~(((which_adc & 1) == 0) ? RX_PWR_DN_BUF_A : RX_PWR_DN_BUF_B);
}
ok &= _write_9862 (codec, reg, cur_rx);
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
{
if (len <= 0)
return "";
-
+
char buf[len];
if (!usrp_spi_read (d_udh, optional_header, enables, format, buf, len))
bool
-usrp_basic::_set_led (int which, bool on)
+usrp_basic::_set_led (int which_led, bool on)
+{
+ return usrp_set_led (d_udh, which_led, on);
+}
+
+bool
+usrp_basic::write_atr_tx_delay(int value)
+{
+ return _write_fpga_reg(FR_ATR_TX_DELAY, value);
+}
+
+bool
+usrp_basic::write_atr_rx_delay(int value)
{
- return usrp_set_led (d_udh, which, on);
+ 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
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)
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;
+ 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_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_fpga_reg(FR_ATR_MASK_1, 0); // zero Rx side Auto Transmit/Receive regs
- _write_fpga_reg(FR_ATR_TXVAL_1, 0);
- _write_fpga_reg(FR_ATR_RXVAL_1, 0);
- _write_fpga_reg(FR_ATR_MASK_3, 0);
- _write_fpga_reg(FR_ATR_TXVAL_3, 0);
- _write_fpga_reg(FR_ATR_RXVAL_3, 0);
+ write_atr_mask(0, 0); // zero Rx A Auto Transmit/Receive regs
+ write_atr_txval(0, 0);
+ write_atr_rxval(0, 0);
+ write_atr_mask(1, 0); // zero Rx B Auto Transmit/Receive regs
+ write_atr_txval(1, 0);
+ write_atr_rxval(1, 0);
}
static unsigned char rx_fini_regs[] = {
{
if (!set_rx_enable (false)){
fprintf (stderr, "usrp_basic_rx: set_fpga_rx_enable failed\n");
- usb_strerror ();
}
d_ephandle->stop ();
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();
}
if (!d_ephandle->start ()){
fprintf (stderr, "usrp_basic_rx: failed to start end point streaming");
- usb_strerror ();
return false;
}
if (!set_rx_enable (true)){
fprintf (stderr, "usrp_basic_rx: set_rx_enable failed\n");
- usb_strerror ();
return false;
}
-
+
return true;
}
{
bool ok = usrp_basic::stop();
- if (!d_ephandle->stop()){
- fprintf (stderr, "usrp_basic_rx: failed to stop end point streaming");
- usb_strerror ();
- ok = false;
- }
if (!set_rx_enable(false)){
fprintf (stderr, "usrp_basic_rx: set_rx_enable(false) failed\n");
- usb_strerror ();
ok = false;
}
- return false;
+
+ if (!d_ephandle->stop()){
+ fprintf (stderr, "usrp_basic_rx: failed to stop end point streaming");
+ ok = false;
+ }
+
+ return ok;
}
usrp_basic_rx *
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);
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;
d_bytes_seen = 0;
if (!usrp_check_rx_overrun (d_udh, overrun)){
fprintf (stderr, "usrp_basic_rx: usrp_check_rx_overrun failed\n");
- usb_strerror ();
}
}
-
+
return r;
}
set_rx_enable (on);
}
-bool
-usrp_basic_rx::set_pga (int which, double gain)
-{
- if (which < 0 || which > 3)
- return false;
-
- gain = std::max (pga_min (), gain);
- gain = std::min (pga_max (), gain);
-
- int codec = which >> 1;
- int reg = (which & 1) == 0 ? REG_RX_A : REG_RX_B;
-
- // read current value to get input buffer bypass flag.
- unsigned char cur_rx;
- if (!_read_9862 (codec, reg, &cur_rx))
- return false;
-
- int int_gain = (int) rint ((gain - pga_min ()) / pga_db_per_step());
-
- cur_rx = (cur_rx & RX_X_BYPASS_INPUT_BUFFER) | (int_gain & 0x7f);
- return _write_9862 (codec, reg, cur_rx);
-}
-
-double
-usrp_basic_rx::pga (int which) const
-{
- if (which < 0 || which > 3)
- return READ_FAILED;
-
- int codec = which >> 1;
- int reg = (which & 1) == 0 ? REG_RX_A : REG_RX_B;
- unsigned char v;
- bool ok = _read_9862 (codec, reg, &v);
- if (!ok)
- return READ_FAILED;
-
- return (pga_db_per_step() * (v & 0x1f)) + pga_min();
-}
-
-static int
-slot_id_to_oe_reg (int slot_id)
-{
- static int reg[4] = { FR_OE_0, FR_OE_1, FR_OE_2, FR_OE_3 };
- assert (0 <= slot_id && slot_id < 4);
- return reg[slot_id];
-}
-
-static int
-slot_id_to_io_reg (int slot_id)
-{
- static int reg[4] = { FR_IO_0, FR_IO_1, FR_IO_2, FR_IO_3 };
- assert (0 <= slot_id && slot_id < 4);
- return reg[slot_id];
-}
-
void
usrp_basic_rx::probe_rx_slots (bool verbose)
{
_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);
}
bool
-usrp_basic_rx::_write_oe (int which_dboard, int value, int mask)
+usrp_basic_rx::set_pga (int which_amp, double gain)
{
- if (! (0 <= which_dboard && which_dboard <= 1))
- return false;
+ return common_set_pga(C_RX, which_amp, gain);
+}
- return _write_fpga_reg (slot_id_to_oe_reg (dboard_to_slot (which_dboard)),
- (mask << 16) | (value & 0xffff));
+double
+usrp_basic_rx::pga(int which_amp) const
+{
+ return common_pga(C_RX, which_amp);
}
-bool
-usrp_basic_rx::write_io (int which_dboard, int value, int mask)
+double
+usrp_basic_rx::pga_min() const
{
- if (! (0 <= which_dboard && which_dboard <= 1))
- return false;
+ return common_pga_min(C_RX);
+}
+
+double
+usrp_basic_rx::pga_max() const
+{
+ return common_pga_max(C_RX);
+}
- return _write_fpga_reg (slot_id_to_io_reg (dboard_to_slot (which_dboard)),
- (mask << 16) | (value & 0xffff));
+double
+usrp_basic_rx::pga_db_per_step() const
+{
+ return common_pga_db_per_step(C_RX);
}
bool
-usrp_basic_rx::read_io (int which_dboard, int *value)
+usrp_basic_rx::_write_oe (int which_side, int value, int mask)
{
- if (! (0 <= which_dboard && which_dboard <= 1))
- return false;
+ return _common_write_oe(C_RX, which_side, value, mask);
+}
- int t;
- int reg = which_dboard + 1; // FIXME, *very* magic number (fix in serial_io.v)
- bool ok = _read_fpga_reg (reg, &t);
- if (!ok)
- return false;
+bool
+usrp_basic_rx::write_io (int which_side, int value, int mask)
+{
+ return common_write_io(C_RX, which_side, value, mask);
+}
- *value = (t >> 16) & 0xffff; // FIXME, more magic
- return true;
+bool
+usrp_basic_rx::read_io (int which_side, int *value)
+{
+ return common_read_io(C_RX, which_side, value);
}
int
-usrp_basic_rx::read_io (int which_dboard)
+usrp_basic_rx::read_io (int which_side)
{
- int value;
- if (!read_io (which_dboard, &value))
- return READ_FAILED;
- return value;
+ return common_read_io(C_RX, which_side);
}
bool
-usrp_basic_rx::write_aux_dac (int which_dboard, int which_dac, int value)
+usrp_basic_rx::write_refclk(int which_side, int value)
{
- return usrp_basic::write_aux_dac (dboard_to_slot (which_dboard),
- which_dac, value);
+ return common_write_refclk(C_RX, which_side, value);
}
bool
-usrp_basic_rx::read_aux_adc (int which_dboard, int which_adc, int *value)
+usrp_basic_rx::write_atr_mask(int which_side, int value)
{
- return usrp_basic::read_aux_adc (dboard_to_slot (which_dboard),
- which_adc, value);
+ return common_write_atr_mask(C_RX, which_side, value);
}
-int
-usrp_basic_rx::read_aux_adc (int which_dboard, int which_adc)
+bool
+usrp_basic_rx::write_atr_txval(int which_side, int value)
{
- return usrp_basic::read_aux_adc (dboard_to_slot (which_dboard), which_adc);
+ return common_write_atr_txval(C_RX, which_side, value);
}
-int
-usrp_basic_rx::block_size () const { return d_ephandle->block_size(); }
+bool
+usrp_basic_rx::write_atr_rxval(int which_side, int value)
+{
+ return common_write_atr_rxval(C_RX, which_side, value);
+}
bool
-usrp_basic_rx::set_dc_offset_cl_enable(int bits, int mask)
+usrp_basic_rx::write_aux_dac (int which_side, int which_dac, int value)
{
- return _write_fpga_reg(FR_DC_OFFSET_CL_EN,
- (d_fpga_shadows[FR_DC_OFFSET_CL_EN] & ~mask) | (bits & mask));
+ return common_write_aux_dac(C_RX, which_side, which_dac, value);
+}
+
+bool
+usrp_basic_rx::read_aux_adc (int which_side, int which_adc, int *value)
+{
+ return common_read_aux_adc(C_RX, which_side, which_adc, value);
}
+int
+usrp_basic_rx::read_aux_adc (int which_side, int which_adc)
+{
+ return common_read_aux_adc(C_RX, which_side, which_adc);
+}
+
+int
+usrp_basic_rx::block_size () const { return d_ephandle->block_size(); }
+
////////////////////////////////////////////////////////////////
//
// usrp_basic_tx
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)
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_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_fpga_reg(FR_ATR_MASK_0, 0); // zero Tx side Auto Transmit/Receive regs
- _write_fpga_reg(FR_ATR_TXVAL_0, 0);
- _write_fpga_reg(FR_ATR_RXVAL_0, 0);
- _write_fpga_reg(FR_ATR_MASK_2, 0);
- _write_fpga_reg(FR_ATR_TXVAL_2, 0);
- _write_fpga_reg(FR_ATR_RXVAL_2, 0);
+ write_atr_mask(0, 0); // zero Tx A Auto Transmit/Receive regs
+ write_atr_txval(0, 0);
+ write_atr_rxval(0, 0);
+ write_atr_mask(1, 0); // zero Tx B Auto Transmit/Receive regs
+ write_atr_txval(1, 0);
+ write_atr_rxval(1, 0);
}
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
if (!set_tx_enable (true)){
fprintf (stderr, "usrp_basic_tx: set_tx_enable failed\n");
- usb_strerror ();
return false;
}
-
+
if (!d_ephandle->start ()){
fprintf (stderr, "usrp_basic_tx: failed to start end point streaming");
- usb_strerror ();
return false;
}
{
bool ok = usrp_basic::stop ();
- if (!set_tx_enable (false)){
- fprintf (stderr, "usrp_basic_tx: set_tx_enable(false) failed\n");
- usb_strerror ();
- ok = false;
- }
if (!d_ephandle->stop ()){
fprintf (stderr, "usrp_basic_tx: failed to stop end point streaming");
- usb_strerror ();
ok = false;
}
+
+ if (!set_tx_enable (false)){
+ fprintf (stderr, "usrp_basic_tx: set_tx_enable(false) failed\n");
+ ok = false;
+ }
+
return ok;
}
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);
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
d_bytes_seen = 0;
if (!usrp_check_tx_underrun (d_udh, underrun)){
fprintf (stderr, "usrp_basic_tx: usrp_check_tx_underrun failed\n");
- usb_strerror ();
}
}
set_tx_enable (on);
}
-bool
-usrp_basic_tx::set_pga (int which, double gain)
-{
- if (which < 0 || which > 3)
- return false;
-
- gain = std::max (pga_min (), gain);
- gain = std::min (pga_max (), gain);
-
- int codec = which >> 1; // 0 and 1 are same, as are 2 and 3
-
- int int_gain = (int) rint ((gain - pga_min ()) / pga_db_per_step());
-
- return _write_9862 (codec, REG_TX_PGA, int_gain);
-}
-
-double
-usrp_basic_tx::pga (int which) const
-{
- if (which < 0 || which > 3)
- return READ_FAILED;
-
- int codec = which >> 1;
- unsigned char v;
- bool ok = _read_9862 (codec, REG_TX_PGA, &v);
- if (!ok)
- return READ_FAILED;
-
- return (pga_db_per_step() * v) + pga_min();
-}
-
void
usrp_basic_tx::probe_tx_slots (bool verbose)
{
_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);
}
bool
-usrp_basic_tx::_write_oe (int which_dboard, int value, int mask)
+usrp_basic_tx::set_pga (int which_amp, double gain)
{
- if (! (0 <= which_dboard && which_dboard <= 1))
- return false;
+ return common_set_pga(C_TX, which_amp, gain);
+}
- return _write_fpga_reg (slot_id_to_oe_reg (dboard_to_slot (which_dboard)),
- (mask << 16) | (value & 0xffff));
+double
+usrp_basic_tx::pga (int which_amp) const
+{
+ return common_pga(C_TX, which_amp);
}
-bool
-usrp_basic_tx::write_io (int which_dboard, int value, int mask)
+double
+usrp_basic_tx::pga_min() const
{
- if (! (0 <= which_dboard && which_dboard <= 1))
- return false;
+ return common_pga_min(C_TX);
+}
- return _write_fpga_reg (slot_id_to_io_reg (dboard_to_slot (which_dboard)),
- (mask << 16) | (value & 0xffff));
+double
+usrp_basic_tx::pga_max() const
+{
+ return common_pga_max(C_TX);
+}
+
+double
+usrp_basic_tx::pga_db_per_step() const
+{
+ return common_pga_db_per_step(C_TX);
}
bool
-usrp_basic_tx::read_io (int which_dboard, int *value)
+usrp_basic_tx::_write_oe (int which_side, int value, int mask)
{
- if (! (0 <= which_dboard && which_dboard <= 1))
- return false;
+ return _common_write_oe(C_TX, which_side, value, mask);
+}
- int t;
- int reg = which_dboard + 1; // FIXME, *very* magic number (fix in serial_io.v)
- bool ok = _read_fpga_reg (reg, &t);
- if (!ok)
- return false;
+bool
+usrp_basic_tx::write_io (int which_side, int value, int mask)
+{
+ return common_write_io(C_TX, which_side, value, mask);
+}
- *value = t & 0xffff; // FIXME, more magic
- return true;
+bool
+usrp_basic_tx::read_io (int which_side, int *value)
+{
+ return common_read_io(C_TX, which_side, value);
}
int
-usrp_basic_tx::read_io (int which_dboard)
+usrp_basic_tx::read_io (int which_side)
{
- int value;
- if (!read_io (which_dboard, &value))
- return READ_FAILED;
- return value;
+ return common_read_io(C_TX, which_side);
+}
+
+bool
+usrp_basic_tx::write_refclk(int which_side, int value)
+{
+ return common_write_refclk(C_TX, which_side, value);
+}
+
+bool
+usrp_basic_tx::write_atr_mask(int which_side, int value)
+{
+ return common_write_atr_mask(C_TX, which_side, value);
+}
+
+bool
+usrp_basic_tx::write_atr_txval(int which_side, int value)
+{
+ return common_write_atr_txval(C_TX, which_side, value);
+}
+
+bool
+usrp_basic_tx::write_atr_rxval(int which_side, int value)
+{
+ return common_write_atr_rxval(C_TX, which_side, value);
}
bool
-usrp_basic_tx::write_aux_dac (int which_dboard, int which_dac, int value)
+usrp_basic_tx::write_aux_dac (int which_side, int which_dac, int value)
{
- return usrp_basic::write_aux_dac (dboard_to_slot (which_dboard),
- which_dac, value);
+ return common_write_aux_dac(C_TX, which_side, which_dac, value);
}
bool
-usrp_basic_tx::read_aux_adc (int which_dboard, int which_adc, int *value)
+usrp_basic_tx::read_aux_adc (int which_side, int which_adc, int *value)
{
- return usrp_basic::read_aux_adc (dboard_to_slot (which_dboard),
- which_adc, value);
+ return common_read_aux_adc(C_TX, which_side, which_adc, value);
}
int
-usrp_basic_tx::read_aux_adc (int which_dboard, int which_adc)
+usrp_basic_tx::read_aux_adc (int which_side, int which_adc)
{
- return usrp_basic::read_aux_adc (dboard_to_slot (which_dboard), which_adc);
+ return common_read_aux_adc(C_TX, which_side, which_adc);
}
int