summaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/usrp1
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-09-30 15:03:04 -0700
committerJosh Blum <josh@joshknows.com>2010-09-30 15:03:04 -0700
commitccb7adcb150ae481ce08d4e0fa32641b5aec4e6e (patch)
tree111e27a507d711f890f99ea47c57f25757482e03 /host/lib/usrp/usrp1
parent507283b3d43d653bf7ff1b2aa04f3d642297c9b1 (diff)
parent790a5ac665144180cde712d46b799a115bb74e46 (diff)
downloaduhd-ccb7adcb150ae481ce08d4e0fa32641b5aec4e6e.tar.gz
uhd-ccb7adcb150ae481ce08d4e0fa32641b5aec4e6e.tar.bz2
uhd-ccb7adcb150ae481ce08d4e0fa32641b5aec4e6e.zip
Merge branch 'master' into usrp_e_next
Diffstat (limited to 'host/lib/usrp/usrp1')
-rw-r--r--host/lib/usrp/usrp1/codec_ctrl.cpp14
-rw-r--r--host/lib/usrp/usrp1/codec_ctrl.hpp3
-rw-r--r--host/lib/usrp/usrp1/dboard_iface.cpp11
-rw-r--r--host/lib/usrp/usrp1/io_impl.cpp8
-rw-r--r--host/lib/usrp/usrp1/usrp1_ctrl.cpp16
-rw-r--r--host/lib/usrp/usrp1/usrp1_iface.cpp16
-rw-r--r--host/lib/usrp/usrp1/usrp1_iface.hpp14
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.cpp46
8 files changed, 76 insertions, 52 deletions
diff --git a/host/lib/usrp/usrp1/codec_ctrl.cpp b/host/lib/usrp/usrp1/codec_ctrl.cpp
index ad16f6b3a..4aa730573 100644
--- a/host/lib/usrp/usrp1/codec_ctrl.cpp
+++ b/host/lib/usrp/usrp1/codec_ctrl.cpp
@@ -61,6 +61,9 @@ public:
float get_tx_pga_gain(void);
void set_rx_pga_gain(float, char);
float get_rx_pga_gain(char);
+
+ //rx adc buffer control
+ void bypass_adc_buffers(bool bypass);
private:
usrp1_iface::sptr _iface;
@@ -419,6 +422,17 @@ void usrp1_codec_ctrl_impl::set_duc_freq(double freq)
}
/***********************************************************************
+ * Codec Control ADC buffer bypass
+ * Disable this for AC-coupled daughterboards (TVRX)
+ * By default it is initialized TRUE.
+ **********************************************************************/
+void usrp1_codec_ctrl_impl::bypass_adc_buffers(bool bypass) {
+ _ad9862_regs.byp_buffer_a = bypass;
+ _ad9862_regs.byp_buffer_b = bypass;
+ this->send_reg(2);
+}
+
+/***********************************************************************
* Codec Control Make
**********************************************************************/
usrp1_codec_ctrl::sptr usrp1_codec_ctrl::make(usrp1_iface::sptr iface,
diff --git a/host/lib/usrp/usrp1/codec_ctrl.hpp b/host/lib/usrp/usrp1/codec_ctrl.hpp
index 259d10ef4..e2e8a010d 100644
--- a/host/lib/usrp/usrp1/codec_ctrl.hpp
+++ b/host/lib/usrp/usrp1/codec_ctrl.hpp
@@ -92,6 +92,9 @@ public:
//! Set the TX modulator frequency
virtual void set_duc_freq(double freq) = 0;
+
+ //! Enable or disable ADC buffer bypass
+ virtual void bypass_adc_buffers(bool bypass) = 0;
};
#endif /* INCLUDED_USRP1_CODEC_CTRL_HPP */
diff --git a/host/lib/usrp/usrp1/dboard_iface.cpp b/host/lib/usrp/usrp1/dboard_iface.cpp
index 4791b55ce..1ac15a46a 100644
--- a/host/lib/usrp/usrp1/dboard_iface.cpp
+++ b/host/lib/usrp/usrp1/dboard_iface.cpp
@@ -32,6 +32,8 @@ using namespace uhd;
using namespace uhd::usrp;
using namespace boost::assign;
+static const dboard_id_t tvrx_id(0x0040);
+
class usrp1_dboard_iface : public dboard_iface {
public:
@@ -51,6 +53,10 @@ public:
//init the clock rate shadows
this->set_clock_rate(UNIT_RX, this->get_clock_rates(UNIT_RX).front());
this->set_clock_rate(UNIT_TX, this->get_clock_rates(UNIT_TX).front());
+
+ //yes this is evil but it's necessary for TVRX to work on USRP1
+ if(_rx_dboard_id == tvrx_id) _codec->bypass_adc_buffers(false);
+ //else _codec->bypass_adc_buffers(false); //don't think this is necessary
}
~usrp1_dboard_iface()
@@ -93,6 +99,7 @@ public:
std::vector<double> get_clock_rates(unit_t);
double get_clock_rate(unit_t);
void set_clock_enabled(unit_t, bool);
+ double get_codec_rate(unit_t);
private:
usrp1_iface::sptr _iface;
@@ -170,6 +177,10 @@ void usrp1_dboard_iface::set_clock_enabled(unit_t, bool)
//TODO we can only enable for special case anyway...
}
+double usrp1_dboard_iface::get_codec_rate(unit_t){
+ return _clock->get_master_clock_freq();
+}
+
/***********************************************************************
* GPIO
**********************************************************************/
diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp
index 73974f2d6..aee760a83 100644
--- a/host/lib/usrp/usrp1/io_impl.cpp
+++ b/host/lib/usrp/usrp1/io_impl.cpp
@@ -272,18 +272,18 @@ static void usrp1_bs_vrt_unpacker(
}
static bool get_recv_buffs(
- zero_copy_if::sptr zc_if,
+ zero_copy_if::sptr zc_if, size_t timeout_ms,
vrt_packet_handler::managed_recv_buffs_t &buffs
){
UHD_ASSERT_THROW(buffs.size() == 1);
- buffs[0] = zc_if->get_recv_buff();
+ buffs[0] = zc_if->get_recv_buff(timeout_ms);
return buffs[0].get() != NULL;
}
size_t usrp1_impl::recv(
const std::vector<void *> &buffs, size_t num_samps,
rx_metadata_t &metadata, const io_type_t &io_type,
- recv_mode_t recv_mode, size_t /*timeout_ms TODO*/
+ recv_mode_t recv_mode, size_t timeout_ms
){
size_t num_samps_recvd = vrt_packet_handler::recv(
_io_impl->packet_handler_recv_state, //last state of the recv handler
@@ -292,7 +292,7 @@ size_t usrp1_impl::recv(
io_type, _rx_otw_type, //input and output types to convert
_clock_ctrl->get_master_clock_freq(), //master clock tick rate
&usrp1_bs_vrt_unpacker,
- boost::bind(&get_recv_buffs, _data_transport, _1),
+ boost::bind(&get_recv_buffs, _data_transport, timeout_ms, _1),
&vrt_packet_handler::handle_overflow_nop,
0, //vrt header offset
_rx_subdev_spec.size() //num channels
diff --git a/host/lib/usrp/usrp1/usrp1_ctrl.cpp b/host/lib/usrp/usrp1/usrp1_ctrl.cpp
index 1dc6e6e25..5043aed7d 100644
--- a/host/lib/usrp/usrp1/usrp1_ctrl.cpp
+++ b/host/lib/usrp/usrp1/usrp1_ctrl.cpp
@@ -38,6 +38,8 @@ enum firmware_code {
#define FX2_FIRMWARE_LOAD 0xa0
+static const bool load_img_msg = true;
+
/***********************************************************************
* Helper Functions
**********************************************************************/
@@ -178,6 +180,7 @@ public:
unsigned char reset_n = 0;
//hit the reset line
+ if (load_img_msg) std::cout << "Loading firmware image: " << filestring << "..." << std::flush;
usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0,
&reset_y, 1);
@@ -206,14 +209,14 @@ public:
}
//type 0x01 is end
else if (type == 0x01) {
+ usrp_set_firmware_hash(hash); //set hash before reset
usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0,
&reset_n, 1);
- usrp_set_firmware_hash(hash);
file.close();
//wait for things to settle
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
-
+ if (load_img_msg) std::cout << " done" << std::endl;
return USRP_FIRMWARE_LOAD_SUCCESS;
}
//type anything else is unhandled
@@ -249,6 +252,7 @@ public:
unsigned char buf[ep0_size];
int ret;
+ if (load_img_msg) std::cout << "Loading FPGA image: " << filestring << "..." << std::flush;
std::ifstream file;
file.open(filename, std::ios::in | std::ios::binary);
if (not file.good()) {
@@ -263,11 +267,12 @@ public:
return -1;
}
- ssize_t n;
- while ((n = file.readsome((char *)buf, sizeof(buf))) > 0) {
+ while (not file.eof()) {
+ file.read((char *)buf, sizeof(buf));
+ size_t n = file.gcount();
ret = usrp_control_write(VRQ_FPGA_LOAD, 0, FL_XFER,
buf, n);
- if (ret != n) {
+ if (ret < 0 or size_t(ret) != n) {
std::cerr << "fpga load error " << ret << std::endl;
file.close();
return -1;
@@ -282,6 +287,7 @@ public:
usrp_set_fpga_hash(hash);
file.close();
+ if (load_img_msg) std::cout << " done" << std::endl;
return 0;
}
diff --git a/host/lib/usrp/usrp1/usrp1_iface.cpp b/host/lib/usrp/usrp1/usrp1_iface.cpp
index 5fd3987d5..64ced2905 100644
--- a/host/lib/usrp/usrp1/usrp1_iface.cpp
+++ b/host/lib/usrp/usrp1/usrp1_iface.cpp
@@ -49,7 +49,7 @@ public:
******************************************************************/
void poke32(boost::uint32_t addr, boost::uint32_t value)
{
- boost::uint32_t swapped = byteswap(value);
+ boost::uint32_t swapped = uhd::htonx(value);
if (iface_debug) {
std::cout.fill('0');
@@ -72,12 +72,6 @@ public:
std::cerr << "USRP: failed memory write: " << ret << std::endl;
}
- void poke16(boost::uint32_t, boost::uint16_t)
- {
- //fpga only handles 32 bit writes
- std::cerr << "USRP: unsupported operation: poke16()" << std::endl;
- }
-
boost::uint32_t peek32(boost::uint32_t addr)
{
boost::uint32_t value_out;
@@ -95,13 +89,7 @@ public:
if (ret < 0)
std::cerr << "USRP: failed memory read: " << ret << std::endl;
- return byteswap(value_out);
- }
-
- boost::uint16_t peek16(boost::uint32_t addr)
- {
- boost::uint32_t val = peek32(addr);
- return boost::uint16_t(val & 0xff);
+ return uhd::ntohx(value_out);
}
/*******************************************************************
diff --git a/host/lib/usrp/usrp1/usrp1_iface.hpp b/host/lib/usrp/usrp1/usrp1_iface.hpp
index 9a3fdd6bc..3f608584a 100644
--- a/host/lib/usrp/usrp1/usrp1_iface.hpp
+++ b/host/lib/usrp/usrp1/usrp1_iface.hpp
@@ -54,20 +54,6 @@ public:
virtual boost::uint32_t peek32(boost::uint32_t addr) = 0;
/*!
- * Write a register (16 bits)
- * \param addr the address
- * \param data the 16bit data
- */
- virtual void poke16(boost::uint32_t addr, boost::uint16_t data) = 0;
-
- /*!
- * read a register (16 bits)
- * \param addr the address
- * \return the 16bit data
- */
- virtual boost::uint16_t peek16(boost::uint32_t addr) = 0;
-
- /*!
* Perform an spi transaction.
* \param which_slave the slave device number
* \param config spi config args
diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp
index 627180b11..793e3027d 100644
--- a/host/lib/usrp/usrp1/usrp1_impl.cpp
+++ b/host/lib/usrp/usrp1/usrp1_impl.cpp
@@ -30,6 +30,7 @@
#include <boost/assign/list_of.hpp>
#include <boost/filesystem.hpp>
#include <boost/thread/thread.hpp>
+#include <boost/lexical_cast.hpp>
#include <iostream>
using namespace uhd;
@@ -74,14 +75,14 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)
boost::uint16_t vid = hint.has_key("uninit") ? FX2_VENDOR_ID : USRP1_VENDOR_ID;
boost::uint16_t pid = hint.has_key("uninit") ? FX2_PRODUCT_ID : USRP1_PRODUCT_ID;
- //see what we got on the USB bus
- std::vector<usb_device_handle::sptr> device_list =
- usb_device_handle::get_device_list(vid, pid);
-
- if(device_list.size() == 0) return usrp1_addrs; //return nothing if no USRPs found
+ // Important note:
+ // The get device list calls are nested inside the for loop.
+ // This allows the usb guts to decontruct when not in use,
+ // so that re-enumeration after fw load can occur successfully.
+ // This requirement is a courtesy of libusb1.0 on windows.
//find the usrps and load firmware
- BOOST_FOREACH(usb_device_handle::sptr handle, device_list) {
+ BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {
usb_control::sptr ctrl_transport = usb_control::make(handle);
usrp_ctrl::sptr usrp_ctrl = usrp_ctrl::make(ctrl_transport);
usrp_ctrl->usrp_load_firmware(usrp1_fw_image);
@@ -90,13 +91,15 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)
//get descriptors again with serial number, but using the initialized VID/PID now since we have firmware
vid = USRP1_VENDOR_ID;
pid = USRP1_PRODUCT_ID;
- device_list = usb_device_handle::get_device_list(vid, pid);
- BOOST_FOREACH(usb_device_handle::sptr handle, device_list) {
+ BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {
device_addr_t new_addr;
new_addr["type"] = "usrp1";
new_addr["serial"] = handle->get_serial();
- usrp1_addrs.push_back(new_addr);
+ //this is a found usrp1 when a hint serial is not specified or it matches
+ if (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]){
+ usrp1_addrs.push_back(new_addr);
+ }
}
return usrp1_addrs;
@@ -105,6 +108,15 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)
/***********************************************************************
* Make
**********************************************************************/
+template<typename output_type> static output_type cast_from_dev_addr(
+ const device_addr_t &device_addr,
+ const std::string &key,
+ output_type def_val
+){
+ return (device_addr.has_key(key))?
+ boost::lexical_cast<output_type>(device_addr[key]) : def_val;
+}
+
static device::sptr usrp1_make(const device_addr_t &device_addr)
{
//extract the FPGA path for the USRP1
@@ -128,11 +140,15 @@ static device::sptr usrp1_make(const device_addr_t &device_addr)
usrp_ctrl = usrp_ctrl::make(ctrl_transport);
usrp_ctrl->usrp_load_fpga(usrp1_fpga_image);
- data_transport = usb_zero_copy::make(handle, // identifier
- 6, // IN endpoint
- 2, // OUT endpoint
- 2 * (1 << 20), // buffer size
- 16384); // transfer size
+ data_transport = usb_zero_copy::make(
+ handle, // identifier
+ 6, // IN endpoint
+ 2, // OUT endpoint
+ size_t(cast_from_dev_addr<double>(device_addr, "recv_xfer_size", 0)),
+ size_t(cast_from_dev_addr<double>(device_addr, "recv_num_xfers", 0)),
+ size_t(cast_from_dev_addr<double>(device_addr, "send_xfer_size", 0)),
+ size_t(cast_from_dev_addr<double>(device_addr, "send_num_xfers", 0))
+ );
break;
}
}
@@ -171,7 +187,7 @@ usrp1_impl::usrp1_impl(uhd::transport::usb_zero_copy::sptr data_transport,
//initialize the mboard
mboard_init();
- //initialize the dboards
+ //initialize the dboards
dboard_init();
//initialize the dsps