summaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-03-30 13:32:52 +0000
committerJosh Blum <josh@joshknows.com>2010-03-30 13:32:52 +0000
commitf94fa1e464c9e2a87274c991dc6461f7f4c956d8 (patch)
tree1b88020a0dece1ae509cf3fb219b7cce487dc198 /host/lib/usrp
parent29e88b3478aad89ff76363029395200a8601e667 (diff)
parent281307833c8275031bd2469e6aef3f472490749a (diff)
downloaduhd-f94fa1e464c9e2a87274c991dc6461f7f4c956d8.tar.gz
uhd-f94fa1e464c9e2a87274c991dc6461f7f4c956d8.tar.bz2
uhd-f94fa1e464c9e2a87274c991dc6461f7f4c956d8.zip
Merge branch 'master' of git@ettus.sourcerepo.com:ettus/uhd into usrp_e
Conflicts: host/include/uhd/usrp/dboard_id.hpp host/lib/usrp/usrp2/usrp2_impl.cpp
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/dboard/basic.cpp35
-rw-r--r--host/lib/usrp/dboard_base.cpp16
-rw-r--r--host/lib/usrp/dboard_manager.cpp23
-rw-r--r--host/lib/usrp/usrp1e/usrp1e_none.cpp2
-rw-r--r--host/lib/usrp/usrp2/dboard_impl.cpp3
-rw-r--r--host/lib/usrp/usrp2/dboard_interface.cpp2
-rw-r--r--host/lib/usrp/usrp2/dsp_impl.cpp68
-rw-r--r--host/lib/usrp/usrp2/fw_common.h16
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp121
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp88
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp29
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp24
12 files changed, 220 insertions, 207 deletions
diff --git a/host/lib/usrp/dboard/basic.cpp b/host/lib/usrp/dboard/basic.cpp
index 82485ae6a..2f29c8e0c 100644
--- a/host/lib/usrp/dboard/basic.cpp
+++ b/host/lib/usrp/dboard/basic.cpp
@@ -15,9 +15,10 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#include <uhd/utils.hpp>
#include <uhd/props.hpp>
-#include <uhd/types.hpp>
+#include <uhd/types/ranges.hpp>
+#include <uhd/utils/assert.hpp>
+#include <uhd/utils/static.hpp>
#include <uhd/usrp/dboard_base.hpp>
#include <uhd/usrp/dboard_manager.hpp>
#include <boost/assign/list_of.hpp>
@@ -33,26 +34,26 @@ using namespace boost::assign;
**********************************************************************/
class basic_rx : public rx_dboard_base{
public:
- basic_rx(ctor_args_t const& args, freq_t max_freq);
+ basic_rx(ctor_args_t const& args, double max_freq);
~basic_rx(void);
void rx_get(const wax::obj &key, wax::obj &val);
void rx_set(const wax::obj &key, const wax::obj &val);
private:
- freq_t _max_freq;
+ double _max_freq;
};
class basic_tx : public tx_dboard_base{
public:
- basic_tx(ctor_args_t const& args, freq_t max_freq);
+ basic_tx(ctor_args_t const& args, double max_freq);
~basic_tx(void);
void tx_get(const wax::obj &key, wax::obj &val);
void tx_set(const wax::obj &key, const wax::obj &val);
private:
- freq_t _max_freq;
+ double _max_freq;
};
/***********************************************************************
@@ -74,17 +75,17 @@ static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t const& args){
return dboard_base::sptr(new basic_tx(args, 32e6));
}
-STATIC_BLOCK(reg_dboards){
- dboard_manager::register_dboard(0x0000, &make_basic_tx, "Basic TX", list_of(""));
+UHD_STATIC_BLOCK(reg_dboards){
+ dboard_manager::register_dboard(0x0000, &make_basic_tx, "Basic TX");
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(0x000e, &make_lf_tx, "LF TX");
dboard_manager::register_dboard(0x000f, &make_lf_rx, "LF RX", list_of("ab")("a")("b"));
}
/***********************************************************************
* Basic and LF RX dboard
**********************************************************************/
-basic_rx::basic_rx(ctor_args_t const& args, freq_t max_freq) : rx_dboard_base(args){
+basic_rx::basic_rx(ctor_args_t const& args, double max_freq) : rx_dboard_base(args){
_max_freq = max_freq;
// set the gpios to safe values (all inputs)
get_interface()->set_gpio_ddr(dboard_interface::GPIO_RX_BANK, 0x0000, 0xffff);
@@ -112,7 +113,7 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){
return;
case SUBDEV_PROP_GAIN:
- val = gain_t(0);
+ val = float(0);
return;
case SUBDEV_PROP_GAIN_RANGE:
@@ -124,7 +125,7 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){
return;
case SUBDEV_PROP_FREQ:
- val = freq_t(0);
+ val = double(0);
return;
case SUBDEV_PROP_FREQ_RANGE:
@@ -163,7 +164,7 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){
switch(key.as<subdev_prop_t>()){
case SUBDEV_PROP_GAIN:
- ASSERT_THROW(val.as<gain_t>() == gain_t(0));
+ ASSERT_THROW(val.as<float>() == float(0));
return;
case SUBDEV_PROP_ANTENNA:
@@ -195,7 +196,7 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){
/***********************************************************************
* Basic and LF TX dboard
**********************************************************************/
-basic_tx::basic_tx(ctor_args_t const& args, freq_t max_freq) : tx_dboard_base(args){
+basic_tx::basic_tx(ctor_args_t const& args, double max_freq) : tx_dboard_base(args){
_max_freq = max_freq;
// set the gpios to safe values (all inputs)
get_interface()->set_gpio_ddr(dboard_interface::GPIO_TX_BANK, 0x0000, 0xffff);
@@ -220,7 +221,7 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){
return;
case SUBDEV_PROP_GAIN:
- val = gain_t(0);
+ val = float(0);
return;
case SUBDEV_PROP_GAIN_RANGE:
@@ -232,7 +233,7 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){
return;
case SUBDEV_PROP_FREQ:
- val = freq_t(0);
+ val = double(0);
return;
case SUBDEV_PROP_FREQ_RANGE:
@@ -271,7 +272,7 @@ void basic_tx::tx_set(const wax::obj &key_, const wax::obj &val){
switch(key.as<subdev_prop_t>()){
case SUBDEV_PROP_GAIN:
- ASSERT_THROW(val.as<gain_t>() == gain_t(0));
+ ASSERT_THROW(val.as<float>() == float(0));
return;
case SUBDEV_PROP_ANTENNA:
diff --git a/host/lib/usrp/dboard_base.cpp b/host/lib/usrp/dboard_base.cpp
index 6dd41cfd8..09d3bbfd4 100644
--- a/host/lib/usrp/dboard_base.cpp
+++ b/host/lib/usrp/dboard_base.cpp
@@ -52,15 +52,15 @@ dboard_id_t dboard_base::get_tx_id(void){
* xcvr dboard dboard_base class
**********************************************************************/
xcvr_dboard_base::xcvr_dboard_base(ctor_args_t const& args) : dboard_base(args){
- if (get_rx_id() == ID_NONE){
+ if (get_rx_id() == dboard_id::NONE){
throw std::runtime_error(str(boost::format(
"cannot create xcvr board when the rx id is \"%s\""
- ) % dboard_id::to_string(ID_NONE)));
+ ) % dboard_id::to_string(dboard_id::NONE)));
}
- if (get_tx_id() == ID_NONE){
+ if (get_tx_id() == dboard_id::NONE){
throw std::runtime_error(str(boost::format(
"cannot create xcvr board when the tx id is \"%s\""
- ) % dboard_id::to_string(ID_NONE)));
+ ) % dboard_id::to_string(dboard_id::NONE)));
}
}
@@ -72,11 +72,11 @@ xcvr_dboard_base::~xcvr_dboard_base(void){
* rx dboard dboard_base class
**********************************************************************/
rx_dboard_base::rx_dboard_base(ctor_args_t const& args) : dboard_base(args){
- if (get_tx_id() != ID_NONE){
+ if (get_tx_id() != dboard_id::NONE){
throw std::runtime_error(str(boost::format(
"cannot create rx board when the tx id is \"%s\""
" -> expected a tx id of \"%s\""
- ) % dboard_id::to_string(get_tx_id()) % dboard_id::to_string(ID_NONE)));
+ ) % dboard_id::to_string(get_tx_id()) % dboard_id::to_string(dboard_id::NONE)));
}
}
@@ -96,11 +96,11 @@ void rx_dboard_base::tx_set(const wax::obj &, const wax::obj &){
* tx dboard dboard_base class
**********************************************************************/
tx_dboard_base::tx_dboard_base(ctor_args_t const& args) : dboard_base(args){
- if (get_rx_id() != ID_NONE){
+ if (get_rx_id() != dboard_id::NONE){
throw std::runtime_error(str(boost::format(
"cannot create tx board when the rx id is \"%s\""
" -> expected a rx id of \"%s\""
- ) % dboard_id::to_string(get_rx_id()) % dboard_id::to_string(ID_NONE)));
+ ) % dboard_id::to_string(get_rx_id()) % dboard_id::to_string(dboard_id::NONE)));
}
}
diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp
index 6ca15e98c..424626023 100644
--- a/host/lib/usrp/dboard_manager.cpp
+++ b/host/lib/usrp/dboard_manager.cpp
@@ -16,9 +16,10 @@
//
#include <uhd/usrp/dboard_manager.hpp>
-#include <uhd/gain_handler.hpp>
-#include <uhd/utils.hpp>
-#include <uhd/dict.hpp>
+#include <uhd/utils/gain_handler.hpp>
+#include <uhd/utils/static.hpp>
+#include <uhd/utils/assert.hpp>
+#include <uhd/types/dict.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/format.hpp>
#include <boost/bind.hpp>
@@ -35,7 +36,7 @@ typedef boost::tuple<dboard_manager::dboard_ctor_t, std::string, prop_names_t> a
//map a dboard id to a dboard constructor
typedef uhd::dict<dboard_id_t, args_t> id_to_args_map_t;
-STATIC_INSTANCE(id_to_args_map_t, get_id_to_args_map)
+UHD_SINGLETON_FCN(id_to_args_map_t, get_id_to_args_map)
void dboard_manager::register_dboard(
dboard_id_t dboard_id,
@@ -163,12 +164,12 @@ static args_t get_dboard_args(
std::string const& xx_type
){
//special case, its rx and the none id (0xffff)
- if (xx_type == "rx" and dboard_id == ID_NONE){
+ if (xx_type == "rx" and dboard_id == dboard_id::NONE){
return get_dboard_args(0x0001, xx_type);
}
//special case, its tx and the none id (0xffff)
- if (xx_type == "tx" and dboard_id == ID_NONE){
+ if (xx_type == "tx" and dboard_id == dboard_id::NONE){
return get_dboard_args(0x0000, xx_type);
}
@@ -203,7 +204,7 @@ dboard_manager_impl::dboard_manager_impl(
//make xcvr subdevs (make one subdev for both rx and tx dboards)
if (rx_dboard_ctor == tx_dboard_ctor){
ASSERT_THROW(rx_subdevs == tx_subdevs);
- BOOST_FOREACH(std::string subdev, rx_subdevs){
+ BOOST_FOREACH(const std::string &subdev, rx_subdevs){
dboard_base::sptr xcvr_dboard = rx_dboard_ctor(
dboard_base::ctor_args_t(subdev, interface, rx_dboard_id, tx_dboard_id)
);
@@ -221,9 +222,9 @@ dboard_manager_impl::dboard_manager_impl(
//make tx and rx subdevs (separate subdevs for rx and tx dboards)
else{
//make the rx subdevs
- BOOST_FOREACH(std::string subdev, rx_subdevs){
+ BOOST_FOREACH(const std::string &subdev, rx_subdevs){
dboard_base::sptr rx_dboard = rx_dboard_ctor(
- dboard_base::ctor_args_t(subdev, interface, rx_dboard_id, ID_NONE)
+ dboard_base::ctor_args_t(subdev, interface, rx_dboard_id, dboard_id::NONE)
);
//create a rx proxy for this rx board
_rx_dboards[subdev] = subdev_proxy::sptr(
@@ -231,9 +232,9 @@ dboard_manager_impl::dboard_manager_impl(
);
}
//make the tx subdevs
- BOOST_FOREACH(std::string subdev, tx_subdevs){
+ BOOST_FOREACH(const std::string &subdev, tx_subdevs){
dboard_base::sptr tx_dboard = tx_dboard_ctor(
- dboard_base::ctor_args_t(subdev, interface, ID_NONE, tx_dboard_id)
+ dboard_base::ctor_args_t(subdev, interface, dboard_id::NONE, tx_dboard_id)
);
//create a tx proxy for this tx board
_tx_dboards[subdev] = subdev_proxy::sptr(
diff --git a/host/lib/usrp/usrp1e/usrp1e_none.cpp b/host/lib/usrp/usrp1e/usrp1e_none.cpp
index ac0b12a75..94243523d 100644
--- a/host/lib/usrp/usrp1e/usrp1e_none.cpp
+++ b/host/lib/usrp/usrp1e/usrp1e_none.cpp
@@ -25,7 +25,7 @@ using namespace uhd::usrp;
* when the required kernel module headers are not present.
*/
-device_addrs_t usrp1e::discover(const device_addr_t &){
+device_addrs_t usrp1e::find(const device_addr_t &){
return device_addrs_t(); //return empty list
}
diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp
index 66e02d469..fd72aeaa4 100644
--- a/host/lib/usrp/usrp2/dboard_impl.cpp
+++ b/host/lib/usrp/usrp2/dboard_impl.cpp
@@ -15,7 +15,8 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#include <uhd/utils.hpp>
+#include <uhd/utils/assert.hpp>
+#include <uhd/types/clock_config.hpp>
#include <boost/format.hpp>
#include "usrp2_impl.hpp"
diff --git a/host/lib/usrp/usrp2/dboard_interface.cpp b/host/lib/usrp/usrp2/dboard_interface.cpp
index d20465147..8fc7864b0 100644
--- a/host/lib/usrp/usrp2/dboard_interface.cpp
+++ b/host/lib/usrp/usrp2/dboard_interface.cpp
@@ -15,7 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#include <uhd/utils.hpp>
+#include <uhd/utils/assert.hpp>
#include "usrp2_impl.hpp"
using namespace uhd::usrp;
diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp
index 34cce0afb..0d43fac0e 100644
--- a/host/lib/usrp/usrp2/dsp_impl.cpp
+++ b/host/lib/usrp/usrp2/dsp_impl.cpp
@@ -15,7 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#include <uhd/utils.hpp>
+#include <uhd/utils/assert.hpp>
#include <boost/format.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/math/special_functions/round.hpp>
@@ -35,7 +35,7 @@ template <class T> T log2(T num){
/***********************************************************************
* DDC Helper Methods
**********************************************************************/
-static boost::uint32_t calculate_freq_word_and_update_actual_freq(freq_t &freq, freq_t clock_freq){
+static boost::uint32_t calculate_freq_word_and_update_actual_freq(double &freq, double clock_freq){
double scale_factor = std::pow(2.0, 32);
//calculate the freq register word
@@ -63,9 +63,8 @@ void usrp2_impl::init_ddc_config(void){
_ddc_freq = 0;
update_ddc_config();
- _ddc_stream_at = time_spec_t();
- _ddc_enabled = false;
- update_ddc_enabled();
+ //initial command that kills streaming (in case if was left on)
+ //issue_ddc_stream_cmd(TODO)
}
void usrp2_impl::update_ddc_config(void){
@@ -86,21 +85,19 @@ void usrp2_impl::update_ddc_config(void){
ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_TOTALLY_SETUP_THE_DDC_DUDE);
}
-void usrp2_impl::update_ddc_enabled(void){
+void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){
//setup the out data
usrp2_ctrl_data_t out_data;
- out_data.id = htonl(USRP2_CTRL_ID_CONFIGURE_STREAMING_FOR_ME_BRO);
- out_data.data.streaming.enabled = (_ddc_enabled)? 1 : 0;
- out_data.data.streaming.secs = htonl(_ddc_stream_at.secs);
- out_data.data.streaming.ticks = htonl(_ddc_stream_at.ticks);
- out_data.data.streaming.samples = htonl(_max_rx_samples_per_packet);
+ out_data.id = htonl(USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO);
+ out_data.data.stream_cmd.now = (stream_cmd.stream_now)? 1 : 0;
+ out_data.data.stream_cmd.continuous = (stream_cmd.continuous)? 1 : 0;
+ out_data.data.stream_cmd.secs = htonl(stream_cmd.time_spec.secs);
+ out_data.data.stream_cmd.ticks = htonl(stream_cmd.time_spec.ticks);
+ out_data.data.stream_cmd.num_samps = htonl(stream_cmd.num_samps);
//send and recv
usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data);
- ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_CONFIGURED_THAT_STREAMING_DUDE);
-
- //clear the stream at time spec (it must be set for the next round of enable/disable)
- _ddc_stream_at = time_spec_t();
+ ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE);
}
/***********************************************************************
@@ -116,12 +113,12 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){
case DSP_PROP_OTHERS:{
prop_names_t others = boost::assign::list_of
- ("rate")
+ ("if_rate")
+ ("bb_rate")
("decim")
("decims")
("freq")
- ("enabled")
- ("stream_at")
+ ("stream_cmd")
;
val = others;
}
@@ -131,10 +128,14 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){
//handle string-based properties specific to this dsp
std::string key_name = key.as<std::string>();
- if (key_name == "rate"){
+ if (key_name == "if_rate"){
val = get_master_clock_freq();
return;
}
+ else if (key_name == "bb_rate"){
+ val = get_master_clock_freq()/_ddc_decim;
+ return;
+ }
else if (key_name == "decim"){
val = _ddc_decim;
return;
@@ -147,10 +148,6 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){
val = _ddc_freq;
return;
}
- else if (key_name == "enabled"){
- val = _ddc_enabled;
- return;
- }
throw std::invalid_argument(str(
boost::format("error getting: unknown key with name %s") % key_name
@@ -171,23 +168,15 @@ void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val){
return;
}
else if (key_name == "freq"){
- freq_t new_freq = val.as<freq_t>();
+ double new_freq = val.as<double>();
ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0);
ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0);
_ddc_freq = new_freq; //shadow
update_ddc_config();
return;
}
- else if (key_name == "enabled"){
- bool new_enabled = val.as<bool>();
- _ddc_enabled = new_enabled; //shadow
- update_ddc_enabled();
- return;
- }
- else if (key_name == "stream_at"){
- time_spec_t new_stream_at = val.as<time_spec_t>();
- _ddc_stream_at = new_stream_at; //shadow
- //update_ddc_enabled(); //dont update from here
+ else if (key_name == "stream_cmd"){
+ issue_ddc_stream_cmd(val.as<stream_cmd_t>());
return;
}
@@ -250,7 +239,8 @@ void usrp2_impl::duc_get(const wax::obj &key, wax::obj &val){
case DSP_PROP_OTHERS:{
prop_names_t others = boost::assign::list_of
- ("rate")
+ ("if_rate")
+ ("bb_rate")
("interp")
("interps")
("freq")
@@ -263,10 +253,14 @@ void usrp2_impl::duc_get(const wax::obj &key, wax::obj &val){
//handle string-based properties specific to this dsp
std::string key_name = key.as<std::string>();
- if (key_name == "rate"){
+ if (key_name == "if_rate"){
val = get_master_clock_freq();
return;
}
+ else if (key_name == "bb_rate"){
+ val = get_master_clock_freq()/_duc_interp;
+ return;
+ }
else if (key_name == "interp"){
val = _duc_interp;
return;
@@ -299,7 +293,7 @@ void usrp2_impl::duc_set(const wax::obj &key, const wax::obj &val){
return;
}
else if (key_name == "freq"){
- freq_t new_freq = val.as<freq_t>();
+ double new_freq = val.as<double>();
ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0);
ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0);
_duc_freq = new_freq; //shadow
diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h
index 7fcae6fb2..30fee6c32 100644
--- a/host/lib/usrp/usrp2/fw_common.h
+++ b/host/lib/usrp/usrp2/fw_common.h
@@ -32,6 +32,9 @@ extern "C" {
#define _SINS_
#endif
+//used to differentiate control packets over data port
+#define USRP2_INVALID_VRT_HEADER 0
+
// size of the vrt header and trailer to the host
#define USRP2_HOST_RX_VRT_HEADER_WORDS32 5
#define USRP2_HOST_RX_VRT_TRAILER_WORDS32 1 //FIXME fpga sets wrong header size when no trailer present
@@ -90,8 +93,8 @@ typedef enum{
USRP2_CTRL_ID_SETUP_THIS_DDC_FOR_ME_BRO,
USRP2_CTRL_ID_TOTALLY_SETUP_THE_DDC_DUDE,
- USRP2_CTRL_ID_CONFIGURE_STREAMING_FOR_ME_BRO,
- USRP2_CTRL_ID_CONFIGURED_THAT_STREAMING_DUDE,
+ USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO,
+ USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE,
USRP2_CTRL_ID_SETUP_THIS_DUC_FOR_ME_BRO,
USRP2_CTRL_ID_TOTALLY_SETUP_THE_DUC_DUDE,
@@ -186,12 +189,13 @@ typedef struct{
_SINS_ uint32_t scale_iq;
} ddc_args;
struct {
- _SINS_ uint8_t enabled;
- _SINS_ uint8_t _pad[3];
+ _SINS_ uint8_t now; //stream now?
+ _SINS_ uint8_t continuous; //auto-reload commmands?
+ _SINS_ uint8_t _pad[2];
_SINS_ uint32_t secs;
_SINS_ uint32_t ticks;
- _SINS_ uint32_t samples;
- } streaming;
+ _SINS_ uint32_t num_samps;
+ } stream_cmd;
struct {
_SINS_ uint32_t freq_word;
_SINS_ uint32_t interp;
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index dc8eea243..c87884ebb 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -16,7 +16,6 @@
//
#include <complex>
-#include <algorithm>
#include <boost/format.hpp>
#include "usrp2_impl.hpp"
@@ -42,20 +41,22 @@ 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
- boost::uint32_t zero_data = 0;
- _data_transport->send(asio::buffer(&zero_data, sizeof(zero_data)));
+ //and the maximum number of lines (32 bit words) per packet
+ boost::uint32_t data[2] = {
+ htonl(USRP2_INVALID_VRT_HEADER),
+ htonl(_max_rx_samples_per_packet)
+ };
+ _data_transport->send(asio::buffer(&data, sizeof(data)));
}
-#define unrolled_loop(__i, __len, __inst) {\
+#define unrolled_loop(__inst, __len){ \
size_t __i = 0; \
- while(__i < (__len & ~0x7)){ \
- __inst; __i++; __inst; __i++; \
- __inst; __i++; __inst; __i++; \
- __inst; __i++; __inst; __i++; \
- __inst; __i++; __inst; __i++; \
+ for(; __i < (__len & ~0x3); __i+= 4){ \
+ __inst(__i+0); __inst(__i+1); \
+ __inst(__i+2); __inst(__i+3); \
} \
- while(__i < __len){ \
- __inst; __i++;\
+ for(; __i < __len; __i++){ \
+ __inst(__i); \
} \
}
@@ -71,11 +72,12 @@ static inline void host_floats_to_usrp2_items(
const fc32_t *host_floats,
size_t num_samps
){
- unrolled_loop(i, num_samps,{
- 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));
- });
+ #define host_floats_to_usrp2_items_i(i){ \
+ 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)); \
+ }
+ unrolled_loop(host_floats_to_usrp2_items_i, num_samps);
}
static inline void usrp2_items_to_host_floats(
@@ -83,12 +85,13 @@ static inline void usrp2_items_to_host_floats(
const boost::uint32_t *usrp2_items,
size_t num_samps
){
- unrolled_loop(i, num_samps,{
- 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));
- });
+ #define usrp2_items_to_host_floats_i(i){ \
+ 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)); \
+ }
+ unrolled_loop(usrp2_items_to_host_floats_i, num_samps);
}
static inline void host_items_to_usrp2_items(
@@ -96,11 +99,12 @@ static inline void host_items_to_usrp2_items(
const boost::uint32_t *host_items,
size_t num_samps
){
+ #define host_items_to_usrp2_items_i(i) usrp2_items[i] = htonl(host_items[i])
if (is_big_endian){
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]));
+ unrolled_loop(host_items_to_usrp2_items_i, num_samps);
}
}
@@ -109,11 +113,12 @@ static inline void usrp2_items_to_host_items(
const boost::uint32_t *usrp2_items,
size_t num_samps
){
+ #define usrp2_items_to_host_items_i(i) host_items[i] = ntohl(usrp2_items[i])
if (is_big_endian){
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]));
+ unrolled_loop(usrp2_items_to_host_items_i, num_samps);
}
}
@@ -167,46 +172,43 @@ void usrp2_impl::recv_raw(rx_metadata_t &metadata){
size_t usrp2_impl::send(
const asio::const_buffer &buff,
const tx_metadata_t &metadata,
- const std::string &type
+ const io_type_t &io_type
){
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
- //and copy the samples into the send buffer
- if (type == "32fc"){
- num_samps = std::min(asio::buffer_size(buff)/sizeof(fc32_t), num_samps);
- host_floats_to_usrp2_items(items, asio::buffer_cast<const fc32_t*>(buff), num_samps);
- }
- 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 boost::uint32_t*>(buff), num_samps);
- }
- else{
- throw std::runtime_error(str(boost::format("usrp2 send: cannot handle type \"%s\"") % type));
- }
+ size_t num_samps = std::min(
+ asio::buffer_size(buff)/io_type.size,
+ size_t(_max_tx_samples_per_packet)
+ );
- 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]++;
//pack metadata into a vrt header
vrt::pack(
metadata, //input
- vrt_hdr, //output
+ tx_mem, //output
num_header_words32, //output
num_samps, //input
num_packet_words32, //output
packet_count //input
);
- //copy in the vrt header (yes we left space)
- items -= num_header_words32;
- std::memcpy(items, vrt_hdr, num_header_words32*sizeof(boost::uint32_t));
+ boost::uint32_t *items = tx_mem + num_header_words32; //offset for data
+
+ //copy the samples into the send buffer
+ switch(io_type.tid){
+ case io_type_t::COMPLEX_FLOAT32:
+ host_floats_to_usrp2_items(items, asio::buffer_cast<const fc32_t*>(buff), num_samps);
+ break;
+ case io_type_t::COMPLEX_INT16:
+ host_items_to_usrp2_items(items, asio::buffer_cast<const boost::uint32_t*>(buff), num_samps);
+ break;
+ default:
+ throw std::runtime_error(str(boost::format("usrp2 send: cannot handle type \"%c\"") % io_type.tid));
+ }
//send and return number of samples
- _data_transport->send(asio::buffer(items, num_packet_words32*sizeof(boost::uint32_t)));
+ _data_transport->send(asio::buffer(tx_mem, num_packet_words32*sizeof(boost::uint32_t)));
return num_samps;
}
@@ -216,7 +218,7 @@ size_t usrp2_impl::send(
size_t usrp2_impl::recv(
const asio::mutable_buffer &buff,
rx_metadata_t &metadata,
- const std::string &type
+ const io_type_t &io_type
){
//perform a receive if no rx data is waiting to be copied
if (asio::buffer_size(_rx_copy_buff) == 0){
@@ -232,21 +234,22 @@ 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(boost::uint32_t);
+ size_t num_samps = std::min(
+ asio::buffer_size(buff)/io_type.size,
+ 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
- if (type == "32fc"){
- num_samps = std::min(asio::buffer_size(buff)/sizeof(fc32_t), num_samps);
+ //copy the samples from the recv buffer
+ switch(io_type.tid){
+ case io_type_t::COMPLEX_FLOAT32:
usrp2_items_to_host_floats(asio::buffer_cast<fc32_t*>(buff), items, num_samps);
- }
- else if (type == "16sc"){
- num_samps = std::min(asio::buffer_size(buff)/sizeof(sc16_t), num_samps);
+ break;
+ case io_type_t::COMPLEX_INT16:
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));
+ break;
+ default:
+ throw std::runtime_error(str(boost::format("usrp2 recv: cannot handle type \"%c\"") % io_type.tid));
}
//update the rx copy buffer to reflect the bytes copied
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index cbca8eec7..35dfd6287 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -15,7 +15,8 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#include <uhd/utils.hpp>
+#include <uhd/utils/assert.hpp>
+#include <uhd/types/mac_addr.hpp>
#include "usrp2_impl.hpp"
using namespace uhd;
@@ -35,27 +36,10 @@ void usrp2_impl::mboard_init(void){
}
void usrp2_impl::init_clock_config(void){
- //init the ref source clock config
- _ref_source_dict = boost::assign::map_list_of
- ("int", USRP2_REF_SOURCE_INT)
- ("sma", USRP2_REF_SOURCE_SMA)
- ("mimo", USRP2_REF_SOURCE_MIMO)
- ;
- _clock_config.ref_source = "int";
-
- //init the pps source clock config
- _pps_source_dict = boost::assign::map_list_of
- ("sma", USRP2_PPS_SOURCE_SMA)
- ("mimo", USRP2_PPS_SOURCE_MIMO)
- ;
- _clock_config.pps_source = "sma";
-
- //init the pps polarity clock config
- _pps_polarity_dict = boost::assign::map_list_of
- (clock_config_t::POLARITY_POS, USRP2_PPS_POLARITY_POS)
- (clock_config_t::POLARITY_NEG, USRP2_PPS_POLARITY_NEG)
- ;
- _clock_config.pps_polarity = clock_config_t::POLARITY_NEG;
+ //setup the clock configuration settings
+ _clock_config.ref_source = clock_config_t::REF_INT;
+ _clock_config.pps_source = clock_config_t::PPS_SMA;
+ _clock_config.pps_polarity = clock_config_t::PPS_NEG;
//update the clock config (sends a control packet)
update_clock_config();
@@ -65,9 +49,35 @@ void usrp2_impl::update_clock_config(void){
//setup the out data
usrp2_ctrl_data_t out_data;
out_data.id = htonl(USRP2_CTRL_ID_HERES_A_NEW_CLOCK_CONFIG_BRO);
- out_data.data.clock_config.ref_source = _ref_source_dict [_clock_config.ref_source];
- out_data.data.clock_config.pps_source = _pps_source_dict [_clock_config.pps_source];
- out_data.data.clock_config.pps_polarity = _pps_polarity_dict[_clock_config.pps_polarity];
+
+ //translate ref source enums
+ switch(_clock_config.ref_source){
+ case clock_config_t::REF_INT:
+ out_data.data.clock_config.ref_source = USRP2_REF_SOURCE_INT; break;
+ case clock_config_t::REF_SMA:
+ out_data.data.clock_config.ref_source = USRP2_REF_SOURCE_SMA; break;
+ case clock_config_t::REF_MIMO:
+ out_data.data.clock_config.ref_source = USRP2_REF_SOURCE_MIMO; break;
+ default: throw std::runtime_error("usrp2: unhandled clock configuration ref source");
+ }
+
+ //translate pps source enums
+ switch(_clock_config.pps_source){
+ case clock_config_t::PPS_SMA:
+ out_data.data.clock_config.pps_source = USRP2_PPS_SOURCE_SMA; break;
+ case clock_config_t::PPS_MIMO:
+ out_data.data.clock_config.pps_source = USRP2_PPS_SOURCE_MIMO; break;
+ default: throw std::runtime_error("usrp2: unhandled clock configuration pps source");
+ }
+
+ //translate pps polarity enums
+ switch(_clock_config.pps_polarity){
+ case clock_config_t::PPS_POS:
+ out_data.data.clock_config.pps_source = USRP2_PPS_POLARITY_POS; break;
+ case clock_config_t::PPS_NEG:
+ out_data.data.clock_config.pps_source = USRP2_PPS_POLARITY_NEG; break;
+ default: throw std::runtime_error("usrp2: unhandled clock configuration pps polarity");
+ }
//send and recv
usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data);
@@ -106,7 +116,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){
ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_THIS_IS_MY_MAC_ADDR_DUDE);
//extract the address
- val = reinterpret_cast<mac_addr_t*>(in_data.data.mac_addr)->to_string();
+ val = mac_addr_t::from_bytes(in_data.data.mac_addr).to_string();
return;
}
@@ -159,7 +169,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){
return;
case MBOARD_PROP_CLOCK_RATE:
- val = freq_t(get_master_clock_freq());
+ val = double(get_master_clock_freq());
return;
case MBOARD_PROP_RX_DSP:
@@ -184,14 +194,6 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){
val = _clock_config;
return;
- case MBOARD_PROP_PPS_SOURCE_NAMES:
- val = prop_names_t(_pps_source_dict.get_keys());
- return;
-
- case MBOARD_PROP_REF_SOURCE_NAMES:
- val = prop_names_t(_ref_source_dict.get_keys());
- return;
-
case MBOARD_PROP_TIME_NOW:
case MBOARD_PROP_TIME_NEXT_PPS:
throw std::runtime_error("Error: trying to get write-only property on usrp2 mboard");
@@ -209,8 +211,8 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){
//setup the out data
usrp2_ctrl_data_t out_data;
out_data.id = htonl(USRP2_CTRL_ID_HERE_IS_A_NEW_MAC_ADDR_BRO);
- mac_addr_t mac_addr(val.as<std::string>());
- std::memcpy(out_data.data.mac_addr, &mac_addr, sizeof(mac_addr_t));
+ mac_addr_t mac_addr = mac_addr_t::from_string(val.as<std::string>());
+ std::copy(mac_addr.to_bytes(), mac_addr.to_bytes()+mac_addr_t::hlen, out_data.data.mac_addr);
//send and recv
usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data);
@@ -234,13 +236,9 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){
//handle the get request conditioned on the key
switch(key.as<mboard_prop_t>()){
- case MBOARD_PROP_CLOCK_CONFIG:{
- clock_config_t clock_config = val.as<clock_config_t>();
- assert_has(_pps_source_dict.get_keys(), clock_config.pps_source, "usrp2 pps source");
- assert_has(_ref_source_dict.get_keys(), clock_config.ref_source, "usrp2 ref source");
- _clock_config = clock_config; //shadow
- update_clock_config();
- }
+ case MBOARD_PROP_CLOCK_CONFIG:
+ _clock_config = val.as<clock_config_t>();
+ update_clock_config();
return;
case MBOARD_PROP_TIME_NOW:{
@@ -264,8 +262,6 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){
case MBOARD_PROP_RX_DBOARD_NAMES:
case MBOARD_PROP_TX_DBOARD:
case MBOARD_PROP_TX_DBOARD_NAMES:
- case MBOARD_PROP_PPS_SOURCE_NAMES:
- case MBOARD_PROP_REF_SOURCE_NAMES:
throw std::runtime_error("Error: trying to set read-only property on usrp2 mboard");
}
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index 85d73e83a..67fbdf8d2 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -15,9 +15,12 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
+#include <uhd/transport/if_addrs.hpp>
+#include <uhd/utils/assert.hpp>
+#include <uhd/utils/static.hpp>
#include <boost/format.hpp>
+#include <boost/foreach.hpp>
#include <boost/bind.hpp>
-#include <uhd/utils.hpp>
#include <iostream>
#include "usrp2_impl.hpp"
@@ -27,16 +30,33 @@ using namespace uhd::transport;
namespace asio = boost::asio;
STATIC_BLOCK(register_usrp2_device){
- device::register_device(&usrp2::discover, &usrp2::make);
+ device::register_device(&usrp2::find, &usrp2::make);
}
/***********************************************************************
* Discovery over the udp transport
**********************************************************************/
-uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){
+uhd::device_addrs_t usrp2::find(const device_addr_t &hint){
device_addrs_t usrp2_addrs;
- if (not hint.has_key("addr")) return usrp2_addrs;
+ //if no address was specified, send a broadcast on each interface
+ if (not hint.has_key("addr")){
+ BOOST_FOREACH(const if_addrs_t &if_addrs, get_if_addrs()){
+ //avoid the loopback device
+ if (if_addrs.inet == asio::ip::address_v4::loopback().to_string()) continue;
+
+ //create a new hint with this broadcast address
+ device_addr_t new_hint = hint;
+ new_hint["addr"] = if_addrs.bcast;
+
+ //call discover with the new hint and append results
+ device_addrs_t new_usrp2_addrs = usrp2::find(new_hint);
+ usrp2_addrs.insert(usrp2_addrs.begin(),
+ new_usrp2_addrs.begin(), new_usrp2_addrs.end()
+ );
+ }
+ return usrp2_addrs;
+ }
//create a udp transport to communicate
//TODO if an addr is not provided, search all interfaces?
@@ -63,7 +83,6 @@ uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){
boost::asio::ip::address_v4 ip_addr(ntohl(ctrl_data_in.data.ip_addr));
device_addr_t new_addr;
new_addr["name"] = "USRP2";
- new_addr["transport"] = "udp";
new_addr["addr"] = ip_addr.to_string();
usrp2_addrs.push_back(new_addr);
//dont break here, it will exit the while loop
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index 55ac0b192..3468a0cf1 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -19,9 +19,10 @@
#define INCLUDED_USRP2_IMPL_HPP
#include <uhd/usrp/usrp2.hpp>
-#include <uhd/dict.hpp>
-#include <uhd/types.hpp>
-#include <uhd/time_spec.hpp>
+#include <uhd/types/dict.hpp>
+#include <uhd/types/stream_cmd.hpp>
+#include <uhd/types/clock_config.hpp>
+#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
@@ -105,8 +106,8 @@ public:
double get_master_clock_freq(void);
//the io interface
- size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const std::string &);
- size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const std::string &);
+ size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const uhd::io_type_t &);
+ size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const uhd::io_type_t &);
private:
//device properties interface
@@ -146,11 +147,6 @@ private:
void update_clock_config(void);
void set_time_spec(const uhd::time_spec_t &time_spec, bool now);
- //mappings from clock config strings to over the wire enums
- uhd::dict<std::string, usrp2_ref_source_t> _ref_source_dict;
- uhd::dict<std::string, usrp2_pps_source_t> _pps_source_dict;
- uhd::dict<uhd::clock_config_t::polarity_t, usrp2_pps_polarity_t> _pps_polarity_dict;
-
//rx and tx dboard methods and objects
uhd::usrp::dboard_manager::sptr _dboard_manager;
void dboard_init(void);
@@ -177,16 +173,14 @@ private:
//methods and shadows for the ddc dsp
std::vector<size_t> _allowed_decim_and_interp_rates;
size_t _ddc_decim;
- uhd::freq_t _ddc_freq;
- bool _ddc_enabled;
- uhd::time_spec_t _ddc_stream_at;
+ double _ddc_freq;
void init_ddc_config(void);
void update_ddc_config(void);
- void update_ddc_enabled(void);
+ void issue_ddc_stream_cmd(const uhd::stream_cmd_t &stream_cmd);
//methods and shadows for the duc dsp
size_t _duc_interp;
- uhd::freq_t _duc_freq;
+ double _duc_freq;
void init_duc_config(void);
void update_duc_config(void);