diff options
author | Josh Blum <josh@joshknows.com> | 2010-12-13 23:39:28 -0800 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2010-12-13 23:39:28 -0800 |
commit | 4d9b9ae7e9fe36bf7c1e2e60a37845e9cc4ecee3 (patch) | |
tree | 4a05c76b1580a02c53f0ba75e8a999f5fb16a792 | |
parent | 5952f5bb6b3411c36633c4327b0c265991bf791a (diff) | |
download | uhd-4d9b9ae7e9fe36bf7c1e2e60a37845e9cc4ecee3.tar.gz uhd-4d9b9ae7e9fe36bf7c1e2e60a37845e9cc4ecee3.tar.bz2 uhd-4d9b9ae7e9fe36bf7c1e2e60a37845e9cc4ecee3.zip |
usrp2: added mimo_mode address arg and documented it
-rw-r--r-- | host/docs/usrp2.rst | 57 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 24 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 14 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.hpp | 7 |
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); |