aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/docs/usrp2.rst57
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp24
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp14
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp7
4 files changed, 82 insertions, 20 deletions
diff --git a/host/docs/usrp2.rst b/host/docs/usrp2.rst
index 04622b9ce..3031a0075 100644
--- a/host/docs/usrp2.rst
+++ b/host/docs/usrp2.rst
@@ -209,19 +209,66 @@ Example device address string representation for 2 USRP2s with IPv4 addresses 19
addr0=192.168.10.2, addr1=192.168.20.2
+------------------------------------------------------------------------
+Using the MIMO Cable
+------------------------------------------------------------------------
+The MIMO cable allows two USRP devices to share reference clocks,
+time synchronization, and the ethernet interface.
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-MIMO cable configuration
+Shared ethernet mode
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Using the MIMO cable, two USRP devices can be grouped together in a multi-device configuration.
-Only one device in the configuration can be attached to the ethernet.
+In shared ethernet mode,
+only one device in the configuration can be attached to the ethernet.
This device will be referred to as the master, and the other device, the slave.
* The master provides reference clock and time synchronization to the slave.
* All data passing between the host and the slave is routed over the MIMO cable.
-* Both master and slave must have different IPv4 addresses but in the same subnet.
+* Both master and slave must have different IPv4 addresses in the same subnet.
+* The master and slave may be used individually or in a multi-device configuration.
+* External clocking is optional, and should only be supplied to the master device.
+* The role of slave and master may be switched with the "mimo_mode" device address (see dual ethernet mode).
+
+Example device address string representation for 2 USRP2s with IPv4 addresses 192.168.10.2 (master) and 192.168.10.3 (slave)
+::
+
+ -- Multi-device example --
+
+ addr0=192.168.10.2, addr1=192.168.10.3
+
+ -- Two single devices example --
+
+ addr=192.168.10.2
+
+ addr=192.168.10.3
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Dual ethernet mode
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+In dual ethernet mode,
+both devices in the configuration must be attached to the ethernet.
+One of the devices in the configuration will be configured to provide synchronization.
+This device will be referred to as the master, and the other device, the slave.
+
+* The master provides reference clock and time synchronization to the slave.
+* The devices require the special device address argument "mimo_mode" set.
+* Both master and slave must have different IPv4 addresses in different subnets.
* The master and slave may be used individually or in a multi-device configuration.
* External clocking is optional, and should only be supplied to the master device.
+Example device address string representation for 2 USRP2s with IPv4 addresses 192.168.10.2 (master) and 192.168.20.2 (slave)
+::
+
+ -- Multi-device example --
+
+ addr0=192.168.10.2, mimo_mode0=master, addr1=192.168.20.2, mimo_mode1=slave
+
+ -- Two single devices example --
+
+ addr=192.168.10.2, mimo_mode=master
+
+ addr=192.168.20.2, mimo_mode=slave
+
------------------------------------------------------------------------
Hardware setup notes
------------------------------------------------------------------------
@@ -233,7 +280,7 @@ The LEDs on the front panel can be useful in debugging hardware and software iss
The LEDs reveal the following about the state of the device:
* **LED A:** transmitting
-* **LED B:** serdes link
+* **LED B:** mimo cable link
* **LED C:** receiving
* **LED D:** firmware loaded
* **LED E:** reference lock
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index ac447d209..b8ebd6030 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -42,8 +42,8 @@ usrp2_mboard_impl::usrp2_mboard_impl(
size_t index,
transport::udp_simple::sptr ctrl_transport,
transport::zero_copy_if::sptr data_transport,
- size_t recv_samps_per_packet,
- const device_addr_t &flow_control_hints
+ const device_addr_t &device_args,
+ size_t recv_samps_per_packet
):
_index(index),
_iface(usrp2_iface::make(ctrl_transport))
@@ -101,14 +101,14 @@ usrp2_mboard_impl::usrp2_mboard_impl(
_iface->poke32(_iface->regs.tx_ctrl_policy, U2_FLAG_TX_CTRL_POLICY_NEXT_PACKET);
//setting the cycles per update (disabled by default)
- const double ups_per_sec = flow_control_hints.cast<double>("ups_per_sec", 0.0);
+ const double ups_per_sec = device_args.cast<double>("ups_per_sec", 0.0);
if (ups_per_sec > 0.0){
const size_t cycles_per_up = size_t(_clock_ctrl->get_master_clock_rate()/ups_per_sec);
_iface->poke32(_iface->regs.tx_ctrl_cycles_per_up, U2_FLAG_TX_CTRL_UP_ENB | cycles_per_up);
}
//setting the packets per update (enabled by default)
- const double ups_per_fifo = flow_control_hints.cast<double>("ups_per_fifo", 8.0);
+ const double ups_per_fifo = device_args.cast<double>("ups_per_fifo", 8.0);
if (ups_per_fifo > 0.0){
const size_t packets_per_up = size_t(usrp2_impl::sram_bytes/ups_per_fifo/data_transport->get_send_frame_size());
_iface->poke32(_iface->regs.tx_ctrl_packets_per_up, U2_FLAG_TX_CTRL_UP_ENB | packets_per_up);
@@ -121,6 +121,20 @@ usrp2_mboard_impl::usrp2_mboard_impl(
init_duc_config();
//initialize the clock configuration
+ if (device_args.has_key("mimo_mode")){
+ if (device_args["mimo_mode"] == "master"){
+ _mimo_clocking_mode_is_master = true;
+ }
+ else if (device_args["mimo_mode"] == "slave"){
+ _mimo_clocking_mode_is_master = false;
+ }
+ else throw std::runtime_error(
+ "mimo_mode must be set to master or slave"
+ );
+ }
+ else {
+ _mimo_clocking_mode_is_master = bool(_iface->peek32(_iface->regs.status) & (1 << 8));
+ }
init_clock_config();
//init the codec before the dboard
@@ -200,7 +214,7 @@ void usrp2_mboard_impl::update_clock_config(void){
// - Masters always drive the clock over serdes.
// - Slaves always lock to this serdes clock.
// - Slaves lock their time over the serdes.
- if (_iface->peek32(_iface->regs.status) & (1 << 8)){
+ if (_mimo_clocking_mode_is_master){
_clock_ctrl->enable_mimo_clock_out(true);
switch(_iface->get_rev()){
case usrp2_iface::USRP_N200:
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index c3bbe4d65..133c39a35 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -201,8 +201,9 @@ sep_indexed_dev_addrs(device_addr);
//create a ctrl and data transport for each address
std::vector<udp_simple::sptr> ctrl_transports;
std::vector<zero_copy_if::sptr> data_transports;
+ const device_addrs_t device_addrs = sep_indexed_dev_addrs(device_addr);
- BOOST_FOREACH(const device_addr_t &dev_addr_i, sep_indexed_dev_addrs(device_addr)){
+ BOOST_FOREACH(const device_addr_t &dev_addr_i, device_addrs){
ctrl_transports.push_back(udp_simple::make_connected(
dev_addr_i["addr"], num2str(USRP2_UDP_CTRL_PORT)
));
@@ -213,7 +214,7 @@ sep_indexed_dev_addrs(device_addr);
//create the usrp2 implementation guts
return device::sptr(
- new usrp2_impl(ctrl_transports, data_transports, device_addr)
+ new usrp2_impl(ctrl_transports, data_transports, device_addrs)
);
}
@@ -227,7 +228,7 @@ UHD_STATIC_BLOCK(register_usrp2_device){
usrp2_impl::usrp2_impl(
std::vector<udp_simple::sptr> ctrl_transports,
std::vector<zero_copy_if::sptr> data_transports,
- const device_addr_t &flow_control_hints
+ const device_addrs_t &device_args
):
_data_transports(data_transports)
{
@@ -244,11 +245,10 @@ usrp2_impl::usrp2_impl(
//!!!!! set the otw type here before continuing, its used below
//create a new mboard handler for each control transport
- for(size_t i = 0; i < ctrl_transports.size(); i++){
+ for(size_t i = 0; i < device_args.size(); i++){
_mboards.push_back(usrp2_mboard_impl::sptr(new usrp2_mboard_impl(
- i, ctrl_transports[i], data_transports[i],
- this->get_max_recv_samps_per_packet(),
- flow_control_hints
+ i, ctrl_transports[i], data_transports[i], device_args[i],
+ this->get_max_recv_samps_per_packet()
)));
//use an empty name when there is only one mboard
std::string name = (ctrl_transports.size() > 1)? boost::lexical_cast<std::string>(i) : "";
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index d0bc175ca..85c00b079 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -85,8 +85,8 @@ public:
size_t index,
uhd::transport::udp_simple::sptr,
uhd::transport::zero_copy_if::sptr,
- size_t recv_samps_per_packet,
- const uhd::device_addr_t &flow_control_hints
+ const uhd::device_addr_t &device_args,
+ size_t recv_samps_per_packet
);
~usrp2_mboard_impl(void);
@@ -99,6 +99,7 @@ public:
private:
size_t _index;
bool _continuous_streaming;
+ bool _mimo_clocking_mode_is_master;
//interfaces
usrp2_iface::sptr _iface;
@@ -190,7 +191,7 @@ public:
usrp2_impl(
std::vector<uhd::transport::udp_simple::sptr> ctrl_transports,
std::vector<uhd::transport::zero_copy_if::sptr> data_transports,
- const uhd::device_addr_t &flow_control_hints
+ const uhd::device_addrs_t &device_args
);
~usrp2_impl(void);