summaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/dboard/basic.cpp14
-rw-r--r--host/lib/usrp/dboard_manager.cpp4
-rw-r--r--host/lib/usrp/usrp2/dboard_impl.cpp82
-rw-r--r--host/lib/usrp/usrp2/dboard_interface.cpp59
-rw-r--r--host/lib/usrp/usrp2/dboard_interface.hpp63
-rw-r--r--host/lib/usrp/usrp2/dsp_impl.cpp23
-rw-r--r--host/lib/usrp/usrp2/fw_common.h104
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp67
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp22
9 files changed, 250 insertions, 188 deletions
diff --git a/host/lib/usrp/dboard/basic.cpp b/host/lib/usrp/dboard/basic.cpp
index 095b77ce1..02b391244 100644
--- a/host/lib/usrp/dboard/basic.cpp
+++ b/host/lib/usrp/dboard/basic.cpp
@@ -75,9 +75,9 @@ static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t const& args){
STATIC_BLOCK(reg_dboards){
dboard_manager::register_dboard(0x0000, &make_basic_tx, "Basic TX", list_of(""));
- dboard_manager::register_dboard(0x0001, &make_basic_rx, "Basic RX", list_of("a")("b")("ab"));
+ dboard_manager::register_dboard(0x0001, &make_basic_rx, "Basic RX", list_of("ab")("a")("b"));
dboard_manager::register_dboard(0x000e, &make_lf_tx, "LF TX", list_of(""));
- dboard_manager::register_dboard(0x000f, &make_lf_rx, "LF RX", list_of("a")("b")("ab"));
+ dboard_manager::register_dboard(0x000f, &make_lf_rx, "LF RX", list_of("ab")("a")("b"));
}
/***********************************************************************
@@ -100,7 +100,7 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){
//handle the get request conditioned on the key
switch(key.as<subdev_prop_t>()){
case SUBDEV_PROP_NAME:
- val = std::string(str(boost::format("%s:%s")
+ val = std::string(str(boost::format("%s - %s")
% dboard_id::to_string(get_rx_id())
% get_subdev_name()
));
@@ -172,11 +172,13 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){
case SUBDEV_PROP_ENABLED:
return; // it wont do you much good, but you can set it
+ case SUBDEV_PROP_FREQ:
+ return; // it wont do you much good, but you can set it
+
case SUBDEV_PROP_NAME:
case SUBDEV_PROP_OTHERS:
case SUBDEV_PROP_GAIN_RANGE:
case SUBDEV_PROP_GAIN_NAMES:
- case SUBDEV_PROP_FREQ:
case SUBDEV_PROP_FREQ_RANGE:
case SUBDEV_PROP_ANTENNA_NAMES:
case SUBDEV_PROP_QUADRATURE:
@@ -278,11 +280,13 @@ void basic_tx::tx_set(const wax::obj &key_, const wax::obj &val){
case SUBDEV_PROP_ENABLED:
return; // it wont do you much good, but you can set it
+ case SUBDEV_PROP_FREQ:
+ return; // it wont do you much good, but you can set it
+
case SUBDEV_PROP_NAME:
case SUBDEV_PROP_OTHERS:
case SUBDEV_PROP_GAIN_RANGE:
case SUBDEV_PROP_GAIN_NAMES:
- case SUBDEV_PROP_FREQ:
case SUBDEV_PROP_FREQ_RANGE:
case SUBDEV_PROP_ANTENNA_NAMES:
case SUBDEV_PROP_QUADRATURE:
diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp
index eeabbda99..6ca15e98c 100644
--- a/host/lib/usrp/dboard_manager.cpp
+++ b/host/lib/usrp/dboard_manager.cpp
@@ -46,7 +46,7 @@ void dboard_manager::register_dboard(
//std::cout << "registering: " << name << std::endl;
if (get_id_to_args_map().has_key(dboard_id)){
throw std::runtime_error(str(boost::format(
- "The dboard id 0x%.4x is already registered to %s."
+ "The dboard id 0x%04x is already registered to %s."
) % dboard_id % dboard_id::to_string(dboard_id)));
}
get_id_to_args_map()[dboard_id] = args_t(dboard_ctor, name, subdev_names);
@@ -54,7 +54,7 @@ void dboard_manager::register_dboard(
std::string dboard_id::to_string(const dboard_id_t &id){
std::string name = (get_id_to_args_map().has_key(id))? get_id_to_args_map()[id].get<1>() : "unknown";
- return str(boost::format("%s (0x%.4x)") % name % id);
+ return str(boost::format("%s (0x%04x)") % name % id);
}
/***********************************************************************
diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp
index 6d957436e..60622ca47 100644
--- a/host/lib/usrp/usrp2/dboard_impl.cpp
+++ b/host/lib/usrp/usrp2/dboard_impl.cpp
@@ -18,7 +18,6 @@
#include <uhd/utils.hpp>
#include <boost/format.hpp>
#include "usrp2_impl.hpp"
-#include "dboard_interface.hpp"
using namespace uhd;
using namespace uhd::usrp;
@@ -32,23 +31,16 @@ void usrp2_impl::dboard_init(void){
out_data.id = htonl(USRP2_CTRL_ID_GIVE_ME_YOUR_DBOARD_IDS_BRO);
usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data);
ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_THESE_ARE_MY_DBOARD_IDS_DUDE);
- std::cout << boost::format("rx id 0x%.2x, tx id 0x%.2x")
- % ntohs(in_data.data.dboard_ids.rx_id)
- % ntohs(in_data.data.dboard_ids.tx_id) << std::endl;
- //extract the dboard ids an convert them to enums
- dboard_id_t rx_dboard_id = static_cast<dboard_id_t>(
- ntohs(in_data.data.dboard_ids.rx_id)
- );
- dboard_id_t tx_dboard_id = static_cast<dboard_id_t>(
- ntohs(in_data.data.dboard_ids.tx_id)
- );
+ //extract the dboard ids an convert them
+ dboard_id_t rx_dboard_id = ntohs(in_data.data.dboard_ids.rx_id);
+ dboard_id_t tx_dboard_id = ntohs(in_data.data.dboard_ids.tx_id);
//create a new dboard interface and manager
dboard_interface::sptr _dboard_interface(
- new usrp2_dboard_interface(this)
+ make_usrp2_dboard_interface(this)
);
- dboard_manager::sptr _dboard_manager = dboard_manager::make(
+ _dboard_manager = dboard_manager::make(
rx_dboard_id, tx_dboard_id, _dboard_interface
);
@@ -61,6 +53,46 @@ void usrp2_impl::dboard_init(void){
boost::bind(&usrp2_impl::tx_dboard_get, this, _1, _2),
boost::bind(&usrp2_impl::tx_dboard_set, this, _1, _2)
);
+
+ //init the subdevs in use (use the first subdevice)
+ _rx_subdevs_in_use = prop_names_t(1, _dboard_manager->get_rx_subdev_names().at(0));
+ _tx_subdevs_in_use = prop_names_t(1, _dboard_manager->get_tx_subdev_names().at(0));
+ update_mux_config();
+}
+
+void usrp2_impl::update_mux_config(void){
+ //calculate the rx mux
+ boost::uint32_t rx_mux = 0;
+ ASSERT_THROW(_rx_subdevs_in_use.size() == 1);
+ wax::obj rx_subdev = _dboard_manager->get_rx_subdev(_rx_subdevs_in_use.at(0));
+ std::cout << "Using: " << rx_subdev[SUBDEV_PROP_NAME].as<std::string>() << std::endl;
+ if (rx_subdev[SUBDEV_PROP_QUADRATURE].as<bool>()){
+ rx_mux = (0x01 << 2) | (0x00 << 0); //Q=ADC1, I=ADC0
+ }else{
+ rx_mux = 0x00; //ADC0
+ }
+ if (rx_subdev[SUBDEV_PROP_IQ_SWAPPED].as<bool>()){
+ rx_mux = (((rx_mux >> 0) & 0x3) << 2) | (((rx_mux >> 2) & 0x3) << 0);
+ }
+
+ //calculate the tx mux
+ boost::uint32_t tx_mux = 0x10;
+ ASSERT_THROW(_tx_subdevs_in_use.size() == 1);
+ wax::obj tx_subdev = _dboard_manager->get_tx_subdev(_tx_subdevs_in_use.at(0));
+ std::cout << "Using: " << tx_subdev[SUBDEV_PROP_NAME].as<std::string>() << std::endl;
+ if (tx_subdev[SUBDEV_PROP_IQ_SWAPPED].as<bool>()){
+ tx_mux = (((tx_mux >> 0) & 0x1) << 1) | (((tx_mux >> 1) & 0x1) << 0);
+ }
+
+ //setup the out data
+ usrp2_ctrl_data_t out_data;
+ out_data.id = htonl(USRP2_CTRL_ID_UPDATE_THOSE_MUX_SETTINGS_BRO);
+ out_data.data.mux_args.rx_mux = htonl(rx_mux);
+ out_data.data.mux_args.tx_mux = htonl(tx_mux);
+
+ //send and recv
+ usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data);
+ ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_UPDATED_THE_MUX_SETTINGS_DUDE);
}
/***********************************************************************
@@ -84,12 +116,22 @@ void usrp2_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){
val = _dboard_manager->get_rx_subdev_names();
return;
+ case DBOARD_PROP_USED_SUBDEVS:
+ val = _rx_subdevs_in_use;
+ return;
+
//case DBOARD_PROP_CODEC:
// throw std::runtime_error("unhandled prop in usrp2 dboard");
}
}
-void usrp2_impl::rx_dboard_set(const wax::obj &, const wax::obj &){
+void usrp2_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){
+ if (key.as<dboard_prop_t>() == DBOARD_PROP_USED_SUBDEVS){
+ _rx_subdevs_in_use = val.as<prop_names_t>();
+ update_mux_config(); //if the val is bad, this will throw
+ return;
+ }
+
throw std::runtime_error("Cannot set on usrp2 dboard");
}
@@ -114,11 +156,21 @@ void usrp2_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){
val = _dboard_manager->get_tx_subdev_names();
return;
+ case DBOARD_PROP_USED_SUBDEVS:
+ val = _tx_subdevs_in_use;
+ return;
+
//case DBOARD_PROP_CODEC:
// throw std::runtime_error("unhandled prop in usrp2 dboard");
}
}
-void usrp2_impl::tx_dboard_set(const wax::obj &, const wax::obj &){
+void usrp2_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){
+ if (key.as<dboard_prop_t>() == DBOARD_PROP_USED_SUBDEVS){
+ _tx_subdevs_in_use = val.as<prop_names_t>();
+ update_mux_config(); //if the val is bad, this will throw
+ return;
+ }
+
throw std::runtime_error("Cannot set on usrp2 dboard");
}
diff --git a/host/lib/usrp/usrp2/dboard_interface.cpp b/host/lib/usrp/usrp2/dboard_interface.cpp
index f12b101f3..d20465147 100644
--- a/host/lib/usrp/usrp2/dboard_interface.cpp
+++ b/host/lib/usrp/usrp2/dboard_interface.cpp
@@ -16,11 +16,48 @@
//
#include <uhd/utils.hpp>
-#include "dboard_interface.hpp"
#include "usrp2_impl.hpp"
using namespace uhd::usrp;
+class usrp2_dboard_interface : public dboard_interface{
+public:
+ usrp2_dboard_interface(usrp2_impl *impl);
+ ~usrp2_dboard_interface(void);
+
+ void write_aux_dac(unit_type_t, int, int);
+ int read_aux_adc(unit_type_t, int);
+
+ void set_atr_reg(gpio_bank_t, boost::uint16_t, boost::uint16_t, boost::uint16_t);
+ void set_gpio_ddr(gpio_bank_t, boost::uint16_t, boost::uint16_t);
+ void write_gpio(gpio_bank_t, boost::uint16_t, boost::uint16_t);
+ boost::uint16_t read_gpio(gpio_bank_t);
+
+ void write_i2c(int, const byte_vector_t &);
+ byte_vector_t read_i2c(int, size_t);
+
+ double get_rx_clock_rate(void);
+ double get_tx_clock_rate(void);
+
+private:
+ byte_vector_t transact_spi(
+ spi_dev_t dev,
+ spi_latch_t latch,
+ spi_push_t push,
+ const byte_vector_t &buf,
+ bool readback
+ );
+
+ usrp2_impl *_impl;
+};
+
+/***********************************************************************
+ * Make Function
+ **********************************************************************/
+dboard_interface::sptr make_usrp2_dboard_interface(usrp2_impl *impl){
+ return dboard_interface::sptr(new usrp2_dboard_interface(impl));
+}
+
/***********************************************************************
* Structors
**********************************************************************/
@@ -52,7 +89,7 @@ double usrp2_dboard_interface::get_tx_clock_rate(void){
* \param bank the dboard interface gpio bank enum
* \return an over the wire representation
*/
-static uint8_t gpio_bank_to_otw(dboard_interface::gpio_bank_t bank){
+static boost::uint8_t gpio_bank_to_otw(dboard_interface::gpio_bank_t bank){
switch(bank){
case uhd::usrp::dboard_interface::GPIO_TX_BANK: return USRP2_DIR_TX;
case uhd::usrp::dboard_interface::GPIO_RX_BANK: return USRP2_DIR_RX;
@@ -60,7 +97,7 @@ static uint8_t gpio_bank_to_otw(dboard_interface::gpio_bank_t bank){
throw std::invalid_argument("unknown gpio bank type");
}
-void usrp2_dboard_interface::set_gpio_ddr(gpio_bank_t bank, uint16_t value, uint16_t mask){
+void usrp2_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){
//setup the out data
usrp2_ctrl_data_t out_data;
out_data.id = htonl(USRP2_CTRL_ID_USE_THESE_GPIO_DDR_SETTINGS_BRO);
@@ -73,7 +110,7 @@ void usrp2_dboard_interface::set_gpio_ddr(gpio_bank_t bank, uint16_t value, uint
ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_GOT_THE_GPIO_DDR_SETTINGS_DUDE);
}
-void usrp2_dboard_interface::write_gpio(gpio_bank_t bank, uint16_t value, uint16_t mask){
+void usrp2_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){
//setup the out data
usrp2_ctrl_data_t out_data;
out_data.id = htonl(USRP2_CTRL_ID_SET_YOUR_GPIO_PIN_OUTS_BRO);
@@ -86,7 +123,7 @@ void usrp2_dboard_interface::write_gpio(gpio_bank_t bank, uint16_t value, uint16
ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_I_SET_THE_GPIO_PIN_OUTS_DUDE);
}
-uint16_t usrp2_dboard_interface::read_gpio(gpio_bank_t bank){
+boost::uint16_t usrp2_dboard_interface::read_gpio(gpio_bank_t bank){
//setup the out data
usrp2_ctrl_data_t out_data;
out_data.id = htonl(USRP2_CTRL_ID_GIVE_ME_YOUR_GPIO_PIN_VALS_BRO);
@@ -98,7 +135,7 @@ uint16_t usrp2_dboard_interface::read_gpio(gpio_bank_t bank){
return ntohs(in_data.data.gpio_config.value);
}
-void usrp2_dboard_interface::set_atr_reg(gpio_bank_t bank, uint16_t tx_value, uint16_t rx_value, uint16_t mask){
+void usrp2_dboard_interface::set_atr_reg(gpio_bank_t bank, boost::uint16_t tx_value, boost::uint16_t rx_value, boost::uint16_t mask){
//setup the out data
usrp2_ctrl_data_t out_data;
out_data.id = htonl(USRP2_CTRL_ID_USE_THESE_ATR_SETTINGS_BRO);
@@ -121,7 +158,7 @@ void usrp2_dboard_interface::set_atr_reg(gpio_bank_t bank, uint16_t tx_value, ui
* \param dev the dboard interface spi dev enum
* \return an over the wire representation
*/
-static uint8_t spi_dev_to_otw(dboard_interface::spi_dev_t dev){
+static boost::uint8_t spi_dev_to_otw(dboard_interface::spi_dev_t dev){
switch(dev){
case uhd::usrp::dboard_interface::SPI_TX_DEV: return USRP2_DIR_TX;
case uhd::usrp::dboard_interface::SPI_RX_DEV: return USRP2_DIR_RX;
@@ -135,7 +172,7 @@ static uint8_t spi_dev_to_otw(dboard_interface::spi_dev_t dev){
* \param latch the dboard interface spi latch enum
* \return an over the wire representation
*/
-static uint8_t spi_latch_to_otw(dboard_interface::spi_latch_t latch){
+static boost::uint8_t spi_latch_to_otw(dboard_interface::spi_latch_t latch){
switch(latch){
case uhd::usrp::dboard_interface::SPI_LATCH_RISE: return USRP2_CLK_EDGE_RISE;
case uhd::usrp::dboard_interface::SPI_LATCH_FALL: return USRP2_CLK_EDGE_FALL;
@@ -149,7 +186,7 @@ static uint8_t spi_latch_to_otw(dboard_interface::spi_latch_t latch){
* \param push the dboard interface spi push enum
* \return an over the wire representation
*/
-static uint8_t spi_push_to_otw(dboard_interface::spi_push_t push){
+static boost::uint8_t spi_push_to_otw(dboard_interface::spi_push_t push){
switch(push){
case uhd::usrp::dboard_interface::SPI_PUSH_RISE: return USRP2_CLK_EDGE_RISE;
case uhd::usrp::dboard_interface::SPI_PUSH_FALL: return USRP2_CLK_EDGE_FALL;
@@ -249,7 +286,7 @@ dboard_interface::byte_vector_t usrp2_dboard_interface::read_i2c(int i2c_addr, s
* \param unit the dboard interface unit type enum
* \return an over the wire representation
*/
-static uint8_t spi_dev_to_otw(dboard_interface::unit_type_t unit){
+static boost::uint8_t spi_dev_to_otw(dboard_interface::unit_type_t unit){
switch(unit){
case uhd::usrp::dboard_interface::UNIT_TYPE_TX: return USRP2_DIR_TX;
case uhd::usrp::dboard_interface::UNIT_TYPE_RX: return USRP2_DIR_RX;
@@ -263,7 +300,7 @@ void usrp2_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, i
out_data.id = htonl(USRP2_CTRL_ID_WRITE_THIS_TO_THE_AUX_DAC_BRO);
out_data.data.aux_args.dir = spi_dev_to_otw(unit);
out_data.data.aux_args.which = which;
- out_data.data.aux_args.dir = htonl(value);
+ out_data.data.aux_args.value = htonl(value);
//send and recv
usrp2_ctrl_data_t in_data = _impl->ctrl_send_and_recv(out_data);
diff --git a/host/lib/usrp/usrp2/dboard_interface.hpp b/host/lib/usrp/usrp2/dboard_interface.hpp
deleted file mode 100644
index a06359e5e..000000000
--- a/host/lib/usrp/usrp2/dboard_interface.hpp
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// Copyright 2010 Ettus Research LLC
-//
-// 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, see <http://www.gnu.org/licenses/>.
-//
-
-#include <uhd/usrp/dboard_interface.hpp>
-
-#ifndef INCLUDED_DBOARD_INTERFACE_HPP
-#define INCLUDED_DBOARD_INTERFACE_HPP
-
-class usrp2_impl; //dummy class declaration
-
-class usrp2_dboard_interface : public uhd::usrp::dboard_interface{
-public:
- usrp2_dboard_interface(usrp2_impl *impl);
-
- ~usrp2_dboard_interface(void);
-
- void write_aux_dac(unit_type_t, int, int);
-
- int read_aux_adc(unit_type_t, int);
-
- void set_atr_reg(gpio_bank_t, uint16_t, uint16_t, uint16_t);
-
- void set_gpio_ddr(gpio_bank_t, uint16_t, uint16_t);
-
- void write_gpio(gpio_bank_t, uint16_t, uint16_t);
-
- uint16_t read_gpio(gpio_bank_t);
-
- void write_i2c(int, const byte_vector_t &);
-
- byte_vector_t read_i2c(int, size_t);
-
- double get_rx_clock_rate(void);
-
- double get_tx_clock_rate(void);
-
-private:
- byte_vector_t transact_spi(
- spi_dev_t dev,
- spi_latch_t latch,
- spi_push_t push,
- const byte_vector_t &buf,
- bool readback
- );
-
- usrp2_impl *_impl;
-};
-
-#endif /* INCLUDED_DBOARD_INTERFACE_HPP */
diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp
index 7520c1757..54ed45e41 100644
--- a/host/lib/usrp/usrp2/dsp_impl.cpp
+++ b/host/lib/usrp/usrp2/dsp_impl.cpp
@@ -18,6 +18,7 @@
#include <uhd/utils.hpp>
#include <boost/format.hpp>
#include <boost/assign/list_of.hpp>
+#include <boost/math/special_functions/round.hpp>
#include "usrp2_impl.hpp"
using namespace uhd;
@@ -25,14 +26,20 @@ using namespace uhd;
static const size_t default_decim = 16;
static const size_t default_interp = 16;
+#define rint boost::math::iround
+
+template <class T> T log2(T num){
+ return std::log(num)/std::log(T(2));
+}
+
/***********************************************************************
* DDC Helper Methods
**********************************************************************/
-static uint32_t calculate_freq_word_and_update_actual_freq(freq_t &freq, freq_t clock_freq){
- double scale_factor = pow(2.0, 32);
+static boost::uint32_t calculate_freq_word_and_update_actual_freq(freq_t &freq, freq_t clock_freq){
+ double scale_factor = std::pow(2.0, 32);
//calculate the freq register word
- uint32_t freq_word = rint((freq / clock_freq) * scale_factor);
+ boost::uint32_t freq_word = rint((freq / clock_freq) * scale_factor);
//update the actual frequency
freq = (double(freq_word) / scale_factor) * clock_freq;
@@ -40,8 +47,8 @@ static uint32_t calculate_freq_word_and_update_actual_freq(freq_t &freq, freq_t
return freq_word;
}
-static uint32_t calculate_iq_scale_word(int16_t i, int16_t q){
- return (uint16_t(i) << 16) | (uint16_t(q) << 0);
+static boost::uint32_t calculate_iq_scale_word(boost::int16_t i, boost::int16_t q){
+ return (boost::uint16_t(i) << 16) | (boost::uint16_t(q) << 0);
}
void usrp2_impl::init_ddc_config(void){
@@ -69,7 +76,7 @@ void usrp2_impl::update_ddc_config(void){
calculate_freq_word_and_update_actual_freq(_ddc_freq, get_master_clock_freq())
);
out_data.data.ddc_args.decim = htonl(_ddc_decim);
- static const uint32_t default_rx_scale_iq = 1024;
+ static const boost::int16_t default_rx_scale_iq = 1024;
out_data.data.ddc_args.scale_iq = htonl(
calculate_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq)
);
@@ -211,8 +218,8 @@ void usrp2_impl::update_duc_config(void){
while(tmp_interp > 128) tmp_interp /= 2;
// Calculate closest multiplier constant to reverse gain absent scale multipliers
- size_t interp_cubed = pow(tmp_interp, 3);
- size_t scale = rint((4096*pow(2, ceil(log2(interp_cubed))))/(1.65*interp_cubed));
+ double interp_cubed = std::pow(double(tmp_interp), 3);
+ boost::int16_t scale = rint((4096*std::pow(2, ceil(log2(interp_cubed))))/(1.65*interp_cubed));
//setup the out data
usrp2_ctrl_data_t out_data;
diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h
index 10c1ef8cf..7fcae6fb2 100644
--- a/host/lib/usrp/usrp2/fw_common.h
+++ b/host/lib/usrp/usrp2/fw_common.h
@@ -24,7 +24,12 @@
* Therefore, this header may only contain valid C code.
*/
#ifdef __cplusplus
+#include <boost/cstdint.hpp>
+#define _SINS_ boost:://stdint namespace when in c++
extern "C" {
+#else
+#include <stdint.h>
+#define _SINS_
#endif
// size of the vrt header and trailer to the host
@@ -94,6 +99,9 @@ typedef enum{
USRP2_CTRL_ID_GOT_A_NEW_TIME_FOR_YOU_BRO,
USRP2_CTRL_ID_SWEET_I_GOT_THAT_TIME_DUDE,
+ USRP2_CTRL_ID_UPDATE_THOSE_MUX_SETTINGS_BRO,
+ USRP2_CTRL_ID_UPDATED_THE_MUX_SETTINGS_DUDE,
+
USRP2_CTRL_ID_PEACE_OUT
} usrp2_ctrl_id_t;
@@ -125,75 +133,79 @@ typedef enum{
} usrp2_clk_edge_t;
typedef struct{
- uint32_t id;
- uint32_t seq;
+ _SINS_ uint32_t id;
+ _SINS_ uint32_t seq;
union{
- uint32_t ip_addr;
- uint8_t mac_addr[6];
+ _SINS_ uint32_t ip_addr;
+ _SINS_ uint8_t mac_addr[6];
struct {
- uint16_t rx_id;
- uint16_t tx_id;
+ _SINS_ uint16_t rx_id;
+ _SINS_ uint16_t tx_id;
} dboard_ids;
struct {
- uint8_t pps_source;
- uint8_t pps_polarity;
- uint8_t ref_source;
- uint8_t _pad;
+ _SINS_ uint8_t pps_source;
+ _SINS_ uint8_t pps_polarity;
+ _SINS_ uint8_t ref_source;
+ _SINS_ uint8_t _pad;
} clock_config;
struct {
- uint8_t bank;
- uint8_t _pad[3];
- uint16_t value;
- uint16_t mask;
+ _SINS_ uint8_t bank;
+ _SINS_ uint8_t _pad[3];
+ _SINS_ uint16_t value;
+ _SINS_ uint16_t mask;
} gpio_config;
struct {
- uint8_t bank;
- uint8_t _pad[3];
- uint16_t tx_value;
- uint16_t rx_value;
- uint16_t mask;
+ _SINS_ uint8_t bank;
+ _SINS_ uint8_t _pad[3];
+ _SINS_ uint16_t tx_value;
+ _SINS_ uint16_t rx_value;
+ _SINS_ uint16_t mask;
} atr_config;
struct {
- uint8_t dev;
- uint8_t latch;
- uint8_t push;
- uint8_t readback;
- uint8_t bytes;
- uint8_t data[sizeof(uint32_t)];
+ _SINS_ uint8_t dev;
+ _SINS_ uint8_t latch;
+ _SINS_ uint8_t push;
+ _SINS_ uint8_t readback;
+ _SINS_ uint8_t bytes;
+ _SINS_ uint8_t data[sizeof(_SINS_ uint32_t)];
} spi_args;
struct {
- uint8_t addr;
- uint8_t bytes;
- uint8_t data[sizeof(uint32_t)];
+ _SINS_ uint8_t addr;
+ _SINS_ uint8_t bytes;
+ _SINS_ uint8_t data[sizeof(_SINS_ uint32_t)];
} i2c_args;
struct {
- uint8_t dir;
- uint8_t which;
- uint8_t _pad[2];
- uint32_t value;
+ _SINS_ uint8_t dir;
+ _SINS_ uint8_t which;
+ _SINS_ uint8_t _pad[2];
+ _SINS_ uint32_t value;
} aux_args;
struct {
- uint32_t freq_word;
- uint32_t decim;
- uint32_t scale_iq;
+ _SINS_ uint32_t freq_word;
+ _SINS_ uint32_t decim;
+ _SINS_ uint32_t scale_iq;
} ddc_args;
struct {
- uint8_t enabled;
- uint8_t _pad[3];
- uint32_t secs;
- uint32_t ticks;
- uint32_t samples;
+ _SINS_ uint8_t enabled;
+ _SINS_ uint8_t _pad[3];
+ _SINS_ uint32_t secs;
+ _SINS_ uint32_t ticks;
+ _SINS_ uint32_t samples;
} streaming;
struct {
- uint32_t freq_word;
- uint32_t interp;
- uint32_t scale_iq;
+ _SINS_ uint32_t freq_word;
+ _SINS_ uint32_t interp;
+ _SINS_ uint32_t scale_iq;
} duc_args;
struct {
- uint32_t secs;
- uint32_t ticks;
- uint8_t now;
+ _SINS_ uint32_t secs;
+ _SINS_ uint32_t ticks;
+ _SINS_ uint8_t now;
} time_args;
+ struct {
+ _SINS_ uint32_t rx_mux;
+ _SINS_ uint32_t tx_mux;
+ } mux_args;
} data;
} usrp2_ctrl_data_t;
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index cc7746720..dc8eea243 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -16,6 +16,7 @@
//
#include <complex>
+#include <algorithm>
#include <boost/format.hpp>
#include "usrp2_impl.hpp"
@@ -27,11 +28,11 @@ namespace asio = boost::asio;
/***********************************************************************
* Constants
**********************************************************************/
-typedef std::complex<float> fc32_t;
-typedef std::complex<int16_t> sc16_t;
+typedef std::complex<float> fc32_t;
+typedef std::complex<boost::int16_t> sc16_t;
-static const float shorts_per_float = pow(2.0, 15);
-static const float floats_per_short = 1.0/shorts_per_float;
+static const float shorts_per_float = float(1 << 15);
+static const float floats_per_short = float(1.0/shorts_per_float);
/***********************************************************************
* Helper Functions
@@ -41,7 +42,7 @@ void usrp2_impl::io_init(void){
_rx_copy_buff = asio::buffer("", 0);
//send a small data packet so the usrp2 knows the udp source port
- uint32_t zero_data = 0;
+ boost::uint32_t zero_data = 0;
_data_transport->send(asio::buffer(&zero_data, sizeof(zero_data)));
}
@@ -66,37 +67,37 @@ static const bool is_big_endian = false;
#endif
static inline void host_floats_to_usrp2_items(
- uint32_t *usrp2_items,
+ boost::uint32_t *usrp2_items,
const fc32_t *host_floats,
size_t num_samps
){
unrolled_loop(i, num_samps,{
- uint16_t real = host_floats[i].real()*shorts_per_float;
- uint16_t imag = host_floats[i].imag()*shorts_per_float;
+ boost::uint16_t real = boost::int16_t(host_floats[i].real()*shorts_per_float);
+ boost::uint16_t imag = boost::int16_t(host_floats[i].imag()*shorts_per_float);
usrp2_items[i] = htonl((real << 16) | (imag << 0));
});
}
static inline void usrp2_items_to_host_floats(
fc32_t *host_floats,
- const uint32_t *usrp2_items,
+ const boost::uint32_t *usrp2_items,
size_t num_samps
){
unrolled_loop(i, num_samps,{
- uint32_t item = ntohl(usrp2_items[i]);
- int16_t real = item >> 16;
- int16_t imag = item >> 0;
- host_floats[i] = fc32_t(real*floats_per_short, imag*floats_per_short);
+ boost::uint32_t item = ntohl(usrp2_items[i]);
+ boost::int16_t real = boost::uint16_t(item >> 16);
+ boost::int16_t imag = boost::uint16_t(item >> 0);
+ host_floats[i] = fc32_t(float(real*floats_per_short), float(imag*floats_per_short));
});
}
static inline void host_items_to_usrp2_items(
- uint32_t *usrp2_items,
- const uint32_t *host_items,
+ boost::uint32_t *usrp2_items,
+ const boost::uint32_t *host_items,
size_t num_samps
){
if (is_big_endian){
- std::memcpy(usrp2_items, host_items, num_samps*sizeof(uint32_t));
+ std::memcpy(usrp2_items, host_items, num_samps*sizeof(boost::uint32_t));
}
else{
unrolled_loop(i, num_samps, usrp2_items[i] = htonl(host_items[i]));
@@ -104,12 +105,12 @@ static inline void host_items_to_usrp2_items(
}
static inline void usrp2_items_to_host_items(
- uint32_t *host_items,
- const uint32_t *usrp2_items,
+ boost::uint32_t *host_items,
+ const boost::uint32_t *usrp2_items,
size_t num_samps
){
if (is_big_endian){
- std::memcpy(host_items, usrp2_items, num_samps*sizeof(uint32_t));
+ std::memcpy(host_items, usrp2_items, num_samps*sizeof(boost::uint32_t));
}
else{
unrolled_loop(i, num_samps, host_items[i] = ntohl(usrp2_items[i]));
@@ -124,12 +125,12 @@ void usrp2_impl::recv_raw(rx_metadata_t &metadata){
_rx_smart_buff = _data_transport->recv();
//unpack the vrt header
- size_t num_packet_words32 = asio::buffer_size(_rx_smart_buff->get())/sizeof(uint32_t);
+ size_t num_packet_words32 = asio::buffer_size(_rx_smart_buff->get())/sizeof(boost::uint32_t);
if (num_packet_words32 == 0){
_rx_copy_buff = boost::asio::buffer("", 0);
return; //must exit here after setting the buffer
}
- const uint32_t *vrt_hdr = asio::buffer_cast<const uint32_t *>(_rx_smart_buff->get());
+ const boost::uint32_t *vrt_hdr = asio::buffer_cast<const boost::uint32_t *>(_rx_smart_buff->get());
size_t num_header_words32_out, num_payload_words32_out, packet_count_out;
try{
vrt::unpack(
@@ -149,14 +150,14 @@ void usrp2_impl::recv_raw(rx_metadata_t &metadata){
//handle the packet count / sequence number
size_t expected_packet_count = _rx_stream_id_to_packet_seq[metadata.stream_id];
if (packet_count_out != expected_packet_count){
- std::cerr << "bad packet count: " << packet_count_out << std::endl;
+ std::cerr << "S" << (packet_count_out - expected_packet_count)%16;
}
_rx_stream_id_to_packet_seq[metadata.stream_id] = (packet_count_out+1)%16;
//setup the rx buffer to point to the data
_rx_copy_buff = asio::buffer(
vrt_hdr + num_header_words32_out,
- num_payload_words32_out*sizeof(uint32_t)
+ num_payload_words32_out*sizeof(boost::uint32_t)
);
}
@@ -168,8 +169,8 @@ size_t usrp2_impl::send(
const tx_metadata_t &metadata,
const std::string &type
){
- uint32_t tx_mem[_mtu/sizeof(uint32_t)];
- uint32_t *items = tx_mem + vrt::max_header_words32; //offset for data
+ boost::uint32_t tx_mem[_mtu/sizeof(boost::uint32_t)];
+ boost::uint32_t *items = tx_mem + vrt::max_header_words32; //offset for data
size_t num_samps = _max_tx_samples_per_packet;
//calculate the number of samples to be copied
@@ -180,13 +181,13 @@ size_t usrp2_impl::send(
}
else if (type == "16sc"){
num_samps = std::min(asio::buffer_size(buff)/sizeof(sc16_t), num_samps);
- host_items_to_usrp2_items(items, asio::buffer_cast<const uint32_t*>(buff), num_samps);
+ host_items_to_usrp2_items(items, asio::buffer_cast<const boost::uint32_t*>(buff), num_samps);
}
else{
throw std::runtime_error(str(boost::format("usrp2 send: cannot handle type \"%s\"") % type));
}
- uint32_t vrt_hdr[vrt::max_header_words32];
+ boost::uint32_t vrt_hdr[vrt::max_header_words32];
size_t num_header_words32, num_packet_words32;
size_t packet_count = _tx_stream_id_to_packet_seq[metadata.stream_id]++;
@@ -202,10 +203,10 @@ size_t usrp2_impl::send(
//copy in the vrt header (yes we left space)
items -= num_header_words32;
- std::memcpy(items, vrt_hdr, num_header_words32*sizeof(uint32_t));
+ std::memcpy(items, vrt_hdr, num_header_words32*sizeof(boost::uint32_t));
//send and return number of samples
- _data_transport->send(asio::buffer(items, num_packet_words32*sizeof(uint32_t)));
+ _data_transport->send(asio::buffer(items, num_packet_words32*sizeof(boost::uint32_t)));
return num_samps;
}
@@ -231,8 +232,8 @@ size_t usrp2_impl::recv(
//and a pointer into the usrp2 received items memory
size_t bytes_to_copy = asio::buffer_size(_rx_copy_buff);
if (bytes_to_copy == 0) return 0; //nothing to receive
- size_t num_samps = bytes_to_copy/sizeof(uint32_t);
- const uint32_t *items = asio::buffer_cast<const uint32_t*>(_rx_copy_buff);
+ size_t num_samps = bytes_to_copy/sizeof(boost::uint32_t);
+ const boost::uint32_t *items = asio::buffer_cast<const boost::uint32_t*>(_rx_copy_buff);
//calculate the number of samples to be copied
//and copy the samples from the recv buffer
@@ -242,7 +243,7 @@ size_t usrp2_impl::recv(
}
else if (type == "16sc"){
num_samps = std::min(asio::buffer_size(buff)/sizeof(sc16_t), num_samps);
- usrp2_items_to_host_items(asio::buffer_cast<uint32_t*>(buff), items, num_samps);
+ usrp2_items_to_host_items(asio::buffer_cast<boost::uint32_t*>(buff), items, num_samps);
}
else{
throw std::runtime_error(str(boost::format("usrp2 recv: cannot handle type \"%s\"") % type));
@@ -250,7 +251,7 @@ size_t usrp2_impl::recv(
//update the rx copy buffer to reflect the bytes copied
_rx_copy_buff = asio::buffer(
- items + num_samps, bytes_to_copy - num_samps*sizeof(uint32_t)
+ items + num_samps, bytes_to_copy - num_samps*sizeof(boost::uint32_t)
);
return num_samps;
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index fc713c2bf..765c523fe 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -31,6 +31,15 @@
#ifndef INCLUDED_USRP2_IMPL_HPP
#define INCLUDED_USRP2_IMPL_HPP
+class usrp2_impl; //dummy class declaration
+
+/*!
+ * Make a usrp2 dboard interface.
+ * \param impl a pointer to the usrp2 impl object
+ * \return a sptr to a new dboard interface
+ */
+uhd::usrp::dboard_interface::sptr make_usrp2_dboard_interface(usrp2_impl *impl);
+
/*!
* Simple wax obj proxy class:
* Provides a wax obj interface for a set and a get function.
@@ -106,17 +115,17 @@ public:
private:
//the raw io interface (samples are in the usrp2 native format)
void recv_raw(uhd::rx_metadata_t &);
- uhd::dict<uint32_t, size_t> _tx_stream_id_to_packet_seq;
- uhd::dict<uint32_t, size_t> _rx_stream_id_to_packet_seq;
+ uhd::dict<boost::uint32_t, size_t> _tx_stream_id_to_packet_seq;
+ uhd::dict<boost::uint32_t, size_t> _rx_stream_id_to_packet_seq;
static const size_t _mtu = 1500; //FIXME we have no idea
static const size_t _hdrs = (2 + 14 + 20 + 8); //size of headers (pad, eth, ip, udp)
static const size_t _max_rx_samples_per_packet =
- (_mtu - _hdrs)/sizeof(uint32_t) -
+ (_mtu - _hdrs)/sizeof(boost::uint32_t) -
USRP2_HOST_RX_VRT_HEADER_WORDS32 -
USRP2_HOST_RX_VRT_TRAILER_WORDS32
;
static const size_t _max_tx_samples_per_packet =
- (_mtu - _hdrs)/sizeof(uint32_t) -
+ (_mtu - _hdrs)/sizeof(boost::uint32_t) -
uhd::transport::vrt::max_header_words32
;
uhd::transport::smart_buffer::sptr _rx_smart_buff;
@@ -128,7 +137,7 @@ private:
uhd::transport::udp_zero_copy::sptr _data_transport;
//private vars for dealing with send/recv control
- uint32_t _ctrl_seq_num;
+ boost::uint32_t _ctrl_seq_num;
boost::mutex _ctrl_mutex;
//methods and shadows for clock configuration
@@ -156,11 +165,14 @@ private:
void rx_dboard_get(const wax::obj &, wax::obj &);
void rx_dboard_set(const wax::obj &, const wax::obj &);
uhd::dict<std::string, wax_obj_proxy> _rx_dboards;
+ uhd::prop_names_t _rx_subdevs_in_use;
//properties interface for tx dboard
void tx_dboard_get(const wax::obj &, wax::obj &);
void tx_dboard_set(const wax::obj &, const wax::obj &);
uhd::dict<std::string, wax_obj_proxy> _tx_dboards;
+ uhd::prop_names_t _tx_subdevs_in_use;
+ void update_mux_config(void);
//methods and shadows for the ddc dsp
std::vector<size_t> _allowed_decim_and_interp_rates;