summaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-02-19 10:30:50 -0800
committerJosh Blum <josh@joshknows.com>2011-02-19 10:30:50 -0800
commite558283f9ff2550d164d868c8e66a5561c781474 (patch)
treebb18d025134e772dff40e459dd6a5a41c0b23b8f /host/lib/usrp
parentb1313c9f65ea89c3aa9707538af027da337dcba8 (diff)
downloaduhd-e558283f9ff2550d164d868c8e66a5561c781474.tar.gz
uhd-e558283f9ff2550d164d868c8e66a5561c781474.tar.bz2
uhd-e558283f9ff2550d164d868c8e66a5561c781474.zip
usrp2: lot of work on dual dsp, grep for TODOs before continuing
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/usrp2/dsp_impl.cpp4
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp71
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp98
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp82
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp36
5 files changed, 150 insertions, 141 deletions
diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp
index ef9b5064c..cdd559e94 100644
--- a/host/lib/usrp/usrp2/dsp_impl.cpp
+++ b/host/lib/usrp/usrp2/dsp_impl.cpp
@@ -40,7 +40,7 @@ struct usrp2_mboard_impl::dsp_impl{
uhd::dict<size_t, bool> continuous_streaming;
};
-void usrp2_mboard_impl::dsp_init(size_t recv_samps_per_packet){
+void usrp2_mboard_impl::dsp_init(void){
//create new dsp impl
_dsp_impl = UHD_PIMPL_MAKE(dsp_impl, ());
@@ -69,7 +69,7 @@ void usrp2_mboard_impl::dsp_init(size_t recv_samps_per_packet){
//setup the rx control registers
_iface->poke32(_iface->regs.rx_ctrl[i].clear_overrun, 1); //reset
- _iface->poke32(_iface->regs.rx_ctrl[i].nsamps_per_pkt, recv_samps_per_packet);
+ _iface->poke32(_iface->regs.rx_ctrl[i].nsamps_per_pkt, _device.get_max_recv_samps_per_packet());
_iface->poke32(_iface->regs.rx_ctrl[i].nchannels, 1);
_iface->poke32(_iface->regs.rx_ctrl[i].vrt_header, 0
| (0x1 << 28) //if data with stream id
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index 816f1859a..179c2401d 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -18,6 +18,7 @@
#include "../../transport/vrt_packet_handler.hpp"
#include "usrp2_impl.hpp"
#include "usrp2_regs.hpp"
+#include <uhd/usrp/mboard_props.hpp>
#include <uhd/utils/byteswap.hpp>
#include <uhd/utils/thread_priority.hpp>
#include <uhd/transport/bounded_buffer.hpp>
@@ -119,16 +120,16 @@ private:
**********************************************************************/
struct usrp2_impl::io_impl{
- io_impl(size_t send_frame_size, const std::vector<zero_copy_if::sptr> &xports):
- xports(xports),
+ io_impl(size_t num_mboards, size_t send_frame_size):
+ //the assumption is that all data transports should be identical
get_recv_buffs_fcn(boost::bind(&usrp2_impl::io_impl::get_recv_buffs, this, _1)),
get_send_buffs_fcn(boost::bind(&usrp2_impl::io_impl::get_send_buffs, this, _1)),
- packet_handler_recv_state(xports.size()),
- packet_handler_send_state(xports.size()),
+ packet_handler_recv_state(num_mboards*usrp2_mboard_impl::NUM_RX_DSPS), //max chans
+ packet_handler_send_state(num_mboards*usrp2_mboard_impl::NUM_RX_DSPS), //max chans
async_msg_fifo(100/*messages deep*/)
{
- for (size_t i = 0; i < xports.size(); i++){
- fc_mons.push_back(flow_control_monitor::sptr(
+ for (size_t i = 0; i < num_mboards; i++){ //only one monitor per mboard (only 1 tx dsp so far)
+ fc_mons.push_back(flow_control_monitor::sptr( //OMG TODO this will not be mapped right when a tx is disabled
new flow_control_monitor(usrp2_impl::sram_bytes/send_frame_size)
));
//init empty packet infos
@@ -149,7 +150,7 @@ struct usrp2_impl::io_impl{
}
bool get_send_buffs(vrt_packet_handler::managed_send_buffs_t &buffs){
- UHD_ASSERT_THROW(xports.size() == buffs.size());
+ UHD_ASSERT_THROW(send_xports.size() == buffs.size());
//calculate the flow control word
const boost::uint32_t fc_word32 = packet_handler_send_state.next_packet_seq;
@@ -157,7 +158,7 @@ struct usrp2_impl::io_impl{
//grab a managed buffer for each index
for (size_t i = 0; i < buffs.size(); i++){
if (not fc_mons[i]->check_fc_condition(fc_word32, send_timeout)) return false;
- buffs[i] = xports[i]->get_send_buff(send_timeout);
+ buffs[i] = send_xports[i]->get_send_buff(send_timeout);
if (not buffs[i].get()) return false;
buffs[i]->cast<boost::uint32_t *>()[0] = uhd::htonx(fc_word32);
}
@@ -166,7 +167,8 @@ struct usrp2_impl::io_impl{
bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs);
- const std::vector<zero_copy_if::sptr> &xports;
+ //vector of send and recv xports to be mapped to channels
+ std::vector<zero_copy_if::sptr> recv_xports, send_xports;
//timeouts set on calls to recv/send (passed into get buffs methods)
double recv_timeout, send_timeout;
@@ -186,7 +188,7 @@ struct usrp2_impl::io_impl{
vrt_packet_handler::send_state packet_handler_send_state;
//methods and variables for the pirate crew
- void recv_pirate_loop(zero_copy_if::sptr, usrp2_mboard_impl::sptr, size_t);
+ void recv_pirate_loop(usrp2_mboard_impl::sptr, size_t);
boost::thread_group recv_pirate_crew;
bool recv_pirate_crew_raiding;
bounded_buffer<async_metadata_t> async_msg_fifo;
@@ -200,9 +202,7 @@ struct usrp2_impl::io_impl{
* - put async message packets into queue
**********************************************************************/
void usrp2_impl::io_impl::recv_pirate_loop(
- zero_copy_if::sptr zc_if_err0,
- usrp2_mboard_impl::sptr mboard,
- size_t index
+ usrp2_mboard_impl::sptr mboard, size_t index
){
set_thread_priority_safe();
recv_pirate_crew_raiding = true;
@@ -210,7 +210,7 @@ void usrp2_impl::io_impl::recv_pirate_loop(
spawn_mutex.unlock();
while(recv_pirate_crew_raiding){
- managed_recv_buffer::sptr buff = zc_if_err0->get_recv_buff();
+ managed_recv_buffer::sptr buff = mboard->err_xports[0]->get_recv_buff();
if (not buff.get()) continue; //ignore timeout/error buffers
try{
@@ -258,27 +258,46 @@ void usrp2_impl::io_impl::recv_pirate_loop(
**********************************************************************/
void usrp2_impl::io_init(void){
- //the assumption is that all data transports should be identical
- const size_t send_frame_size = _data_transports.front()->get_send_frame_size();
-
//create new io impl
- _io_impl = UHD_PIMPL_MAKE(io_impl, (send_frame_size, _data_transports));
+ _io_impl = UHD_PIMPL_MAKE(io_impl, (_mboards.size(), this->send_frame_size));
//create a new pirate thread for each zc if (yarr!!)
- for (size_t i = 0; i < _err0_transports.size(); i++){
+ for (size_t i = 0; i < _mboards.size(); i++){
//lock the unlocked mutex (non-blocking)
_io_impl->spawn_mutex.lock();
//spawn a new pirate to plunder the recv booty
_io_impl->recv_pirate_crew.create_thread(boost::bind(
&usrp2_impl::io_impl::recv_pirate_loop,
- _io_impl.get(), _err0_transports.at(i),
- _mboards.at(i), i
+ _io_impl.get(), _mboards.at(i), i
));
//block here until the spawned thread unlocks
_io_impl->spawn_mutex.lock();
//exit loop iteration in an unlocked condition
_io_impl->spawn_mutex.unlock();
}
+
+ //update mapping here since it didnt b4 when io init not called first
+ update_xport_channel_mapping();
+}
+
+void usrp2_impl::update_xport_channel_mapping(void){
+ if (_io_impl.get() == NULL) return; //not inited yet
+
+ _io_impl->recv_xports.clear();
+ _io_impl->send_xports.clear();
+ BOOST_FOREACH(usrp2_mboard_impl::sptr mboard, _mboards){
+
+ subdev_spec_t rx_subdev_spec = mboard->get_link()[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>();
+ for (size_t j = 0; j < rx_subdev_spec.size(); j++){
+ _io_impl->recv_xports.push_back(mboard->dsp_xports.at(j));
+ }
+
+ subdev_spec_t tx_subdev_spec = mboard->get_link()[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>();
+ for (size_t j = 0; j < tx_subdev_spec.size(); j++){
+ _io_impl->send_xports.push_back(mboard->dsp_xports.at(j));
+ }
+
+ }
}
/***********************************************************************
@@ -300,7 +319,7 @@ size_t usrp2_impl::get_max_send_samps_per_packet(void) const{
+ vrt_send_header_offset_words32*sizeof(boost::uint32_t)
- sizeof(vrt::if_packet_info_t().cid) //no class id ever used
;
- const size_t bpp = _data_transports.front()->get_send_frame_size() - hdr_size;
+ const size_t bpp = this->send_frame_size - hdr_size;
return bpp/_tx_otw_type.get_sample_size();
}
@@ -383,7 +402,7 @@ UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs(
vrt_packet_handler::managed_recv_buffs_t &buffs
){
if (buffs.size() == 1){
- buffs[0] = xports[0]->get_recv_buff(recv_timeout);
+ buffs[0] = recv_xports[0]->get_recv_buff(recv_timeout);
if (buffs[0].get() == NULL) return false;
bool clear, msg; time_spec_t time; //unused variables
//call extract_packet_info to handle printing the overflows
@@ -404,7 +423,7 @@ UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs(
//do an initial pop to load an initial sequence id
size_t index = indexes_to_do.front();
- buff_tmp = xports[index]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time()));
+ buff_tmp = recv_xports[index]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time()));
if (buff_tmp.get() == NULL) return false;
extract_packet_info(buff_tmp, this->prev_infos[index], expected_time, clear, msg);
if (clear) goto got_clear;
@@ -417,7 +436,7 @@ UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs(
//pop an element off for this index
index = indexes_to_do.front();
- buff_tmp = xports[index]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time()));
+ buff_tmp = recv_xports[index]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time()));
if (buff_tmp.get() == NULL) return false;
time_spec_t this_time;
extract_packet_info(buff_tmp, this->prev_infos[index], this_time, clear, msg);
@@ -458,7 +477,7 @@ size_t usrp2_impl::get_max_recv_samps_per_packet(void) const{
+ sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer
- sizeof(vrt::if_packet_info_t().cid) //no class id ever used
;
- const size_t bpp = _data_transports.front()->get_recv_frame_size() - hdr_size;
+ const size_t bpp = this->recv_frame_size - hdr_size;
return bpp/_rx_otw_type.get_sample_size();
}
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index d95ad4a7a..8db295042 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -21,6 +21,7 @@
#include <uhd/usrp/misc_utils.hpp>
#include <uhd/usrp/dsp_utils.hpp>
#include <uhd/usrp/mboard_props.hpp>
+#include <uhd/utils/byteswap.hpp>
#include <uhd/utils/assert.hpp>
#include <uhd/utils/algorithm.hpp>
#include <boost/bind.hpp>
@@ -32,21 +33,72 @@ static const size_t mimo_clock_sync_delay_cycles = 137;
using namespace uhd;
using namespace uhd::usrp;
+using namespace uhd::transport;
+
+/***********************************************************************
+ * Helpers
+ **********************************************************************/
+static void init_xport(zero_copy_if::sptr xport){
+ //Send a small data packet so the usrp2 knows the udp source port.
+ //This setup must happen before further initialization occurs
+ //or the async update packets will cause ICMP destination unreachable.
+ static const boost::uint32_t data[2] = {
+ uhd::htonx(boost::uint32_t(0 /* don't care seq num */)),
+ uhd::htonx(boost::uint32_t(USRP2_INVALID_VRT_HEADER))
+ };
+
+ transport::managed_send_buffer::sptr send_buff = xport->get_send_buff();
+ std::memcpy(send_buff->cast<void*>(), &data, sizeof(data));
+ send_buff->commit(sizeof(data));
+}
/***********************************************************************
* Structors
**********************************************************************/
usrp2_mboard_impl::usrp2_mboard_impl(
- size_t index,
- transport::udp_simple::sptr ctrl_transport,
- transport::zero_copy_if::sptr data_transport,
- transport::zero_copy_if::sptr err0_transport,
- const device_addr_t &device_args,
- size_t recv_samps_per_packet
+ const device_addr_t &device_addr, //global args passed into make
+ const device_addr_t &device_args, //separated mboard specific args
+ size_t index, usrp2_impl &device
):
- _index(index),
- _iface(usrp2_iface::make(ctrl_transport))
+ _index(index), _device(device),
+ _iface(usrp2_iface::make(udp_simple::make_connected(
+ device_addr["addr"], boost::lexical_cast<std::string>(USRP2_UDP_CTRL_PORT)
+ )))
{
+
+ //setup the dsp transport hints (default to a large recv buff)
+ device_addr_t dsp_xport_hints = device_addr;
+ if (not dsp_xport_hints.has_key("recv_buff_size")){
+ //only enable on platforms that are happy with the large buffer resize
+ #if defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)
+ //set to half-a-second of buffering at max rate
+ dsp_xport_hints["recv_buff_size"] = "50e6";
+ #endif /*defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)*/
+ }
+
+ //construct transports for dsp and async errors
+ std::cout << "Making transport for DSP0..." << std::endl;
+ dsp_xports.push_back(udp_zero_copy::make(
+ device_addr["addr"], boost::lexical_cast<std::string>(USRP2_UDP_DSP0_PORT), dsp_xport_hints
+ ));
+ init_xport(dsp_xports.back());
+
+ std::cout << "Making transport for DSP1..." << std::endl;
+ dsp_xports.push_back(udp_zero_copy::make(
+ device_addr["addr"], boost::lexical_cast<std::string>(USRP2_UDP_DSP1_PORT), dsp_xport_hints
+ ));
+ init_xport(dsp_xports.back());
+
+ std::cout << "Making transport for ERR0..." << std::endl;
+ err_xports.push_back(udp_zero_copy::make(
+ device_addr["addr"], boost::lexical_cast<std::string>(USRP2_UDP_ERR0_PORT), device_addr_t()
+ ));
+ init_xport(err_xports.back());
+
+ //set the frame sizes (assume homogeneous)
+ device.recv_frame_size = dsp_xports.front()->get_recv_frame_size();
+ device.send_frame_size = dsp_xports.front()->get_send_frame_size();
+
//contruct the interfaces to mboard perifs
_clock_ctrl = usrp2_clock_ctrl::make(_iface);
_codec_ctrl = usrp2_codec_ctrl::make(_iface);
@@ -57,7 +109,7 @@ usrp2_mboard_impl::usrp2_mboard_impl(
//if(_gps_ctrl->gps_detected()) std::cout << "GPS time: " << _gps_ctrl->get_time() << std::endl;
//init the dsp stuff (before setting update packets)
- dsp_init(recv_samps_per_packet);
+ dsp_init();
//setting the cycles per update (disabled by default)
const double ups_per_sec = device_args.cast<double>("ups_per_sec", 0.0);
@@ -69,7 +121,7 @@ usrp2_mboard_impl::usrp2_mboard_impl(
//setting the packets per update (enabled by default)
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());
+ const size_t packets_per_up = size_t(usrp2_impl::sram_bytes/ups_per_fifo/dsp_xports[0]->get_send_frame_size());
_iface->poke32(_iface->regs.tx_ctrl_packets_per_up, U2_FLAG_TX_CTRL_UP_ENB | packets_per_up);
}
@@ -106,14 +158,14 @@ usrp2_mboard_impl::usrp2_mboard_impl(
(*this)[MBOARD_PROP_TX_SUBDEV_SPEC] = subdev_spec_t();
//This is a hack/fix for the lingering packet problem.
- /*
stream_cmd_t stream_cmd(stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
- stream_cmd.num_samps = 1;
- this->issue_ddc_stream_cmd(stream_cmd);
- data_transport->get_recv_buff().get(); //recv with timeout for lingering
- data_transport->get_recv_buff().get(); //recv with timeout for expected
- _iface->poke32(_iface->regs.rx_ctrl[0].clear_overrun, 1); //resets sequence
- */
+ for (size_t i = 0; i < NUM_RX_DSPS; i++){
+ stream_cmd.num_samps = 1;
+ this->issue_ddc_stream_cmd(stream_cmd, i);
+ dsp_xports[i]->get_recv_buff().get(); //recv with timeout for lingering
+ dsp_xports[i]->get_recv_buff().get(); //recv with timeout for expected
+ _iface->poke32(_iface->regs.rx_ctrl[i].clear_overrun, 1); //resets sequence
+ }
}
usrp2_mboard_impl::~usrp2_mboard_impl(void){
@@ -336,17 +388,21 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){
_dboard_manager->get_rx_subdev(_rx_subdev_spec[i].sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()
));
}
+ _device.update_xport_channel_mapping();
return;
case MBOARD_PROP_TX_SUBDEV_SPEC:
_tx_subdev_spec = val.as<subdev_spec_t>();
verify_tx_subdev_spec(_tx_subdev_spec, this->get_link());
//sanity check
- UHD_ASSERT_THROW(_tx_subdev_spec.size() == 1);
+ UHD_ASSERT_THROW(_tx_subdev_spec.size() <= NUM_TX_DSPS);
//set the mux
- _iface->poke32(_iface->regs.dsp_tx_mux, dsp_type1::calc_tx_mux_word(
- _dboard_manager->get_tx_subdev(_tx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()
- ));
+ for (size_t i = 0; i < _rx_subdev_spec.size(); i++){
+ _iface->poke32(_iface->regs.dsp_tx_mux, dsp_type1::calc_tx_mux_word(
+ _dboard_manager->get_tx_subdev(_tx_subdev_spec[i].sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()
+ ));
+ }
+ _device.update_xport_channel_mapping();
return;
case MBOARD_PROP_EEPROM_MAP:
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index 78eda4f62..4ff56eb5b 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -42,9 +42,6 @@ namespace asio = boost::asio;
/***********************************************************************
* Helper Functions
**********************************************************************/
-template <class T> std::string num2str(T num){
- return boost::lexical_cast<std::string>(num);
-}
//! separate indexed device addresses into a vector of device addresses
device_addrs_t sep_indexed_dev_addrs(const device_addr_t &dev_addr){
@@ -168,9 +165,9 @@ static device_addrs_t usrp2_find(const device_addr_t &hint_){
//This operation can throw due to compatibility mismatch.
//In this case, the discovered device will be ignored.
try{
- mboard_eeprom_t mb_eeprom = usrp2_iface::make(
- udp_simple::make_connected(new_addr["addr"], num2str(USRP2_UDP_CTRL_PORT))
- )->mb_eeprom;
+ mboard_eeprom_t mb_eeprom = usrp2_iface::make(udp_simple::make_connected(
+ new_addr["addr"], boost::lexical_cast<std::string>(USRP2_UDP_CTRL_PORT)
+ ))->mb_eeprom;
new_addr["name"] = mb_eeprom["name"];
new_addr["serial"] = mb_eeprom["serial"];
if (
@@ -199,56 +196,7 @@ static device_addrs_t usrp2_find(const device_addr_t &hint_){
* Make
**********************************************************************/
static device::sptr usrp2_make(const device_addr_t &device_addr){
-
- //setup the dsp transport hints (default to a large recv buff)
- device_addr_t dsp_xport_hints = device_addr;
- if (not dsp_xport_hints.has_key("recv_buff_size")){
- //only enable on platforms that are happy with the large buffer resize
- #if defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)
- //set to half-a-second of buffering at max rate
- dsp_xport_hints["recv_buff_size"] = "50e6";
- #endif /*defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)*/
- }
-
- //create a ctrl and data transport for each address
- std::vector<udp_simple::sptr> ctrl_transports;
- std::vector<zero_copy_if::sptr> data_transports;
- std::vector<zero_copy_if::sptr> err0_transports;
- const device_addrs_t device_addrs = sep_indexed_dev_addrs(device_addr);
-
- //Send a small data packet so the usrp2 knows the udp source port.
- //This setup must happen before further initialization occurs
- //or the async update packets will cause ICMP destination unreachable.
- transport::managed_send_buffer::sptr send_buff;
- static const boost::uint32_t data[2] = {
- uhd::htonx(boost::uint32_t(0 /* don't care seq num */)),
- uhd::htonx(boost::uint32_t(USRP2_INVALID_VRT_HEADER))
- };
-
- 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)
- ));
-
- data_transports.push_back(udp_zero_copy::make(
- dev_addr_i["addr"], num2str(USRP2_UDP_DSP0_PORT), dsp_xport_hints
- ));
- send_buff = data_transports.back()->get_send_buff();
- std::memcpy(send_buff->cast<void*>(), &data, sizeof(data));
- send_buff->commit(sizeof(data));
-
- err0_transports.push_back(udp_zero_copy::make(
- dev_addr_i["addr"], num2str(USRP2_UDP_ERR0_PORT), device_addr_t()
- ));
- send_buff = err0_transports.back()->get_send_buff();
- std::memcpy(send_buff->cast<void*>(), &data, sizeof(data));
- send_buff->commit(sizeof(data));
- }
-
- //create the usrp2 implementation guts
- return device::sptr(new usrp2_impl(
- ctrl_transports, data_transports, err0_transports, device_addrs
- ));
+ return device::sptr(new usrp2_impl(device_addr));
}
UHD_STATIC_BLOCK(register_usrp2_device){
@@ -258,15 +206,9 @@ UHD_STATIC_BLOCK(register_usrp2_device){
/***********************************************************************
* Structors
**********************************************************************/
-usrp2_impl::usrp2_impl(
- std::vector<udp_simple::sptr> ctrl_transports,
- std::vector<zero_copy_if::sptr> data_transports,
- std::vector<zero_copy_if::sptr> err0_transports,
- const device_addrs_t &device_args
-):
- _data_transports(data_transports),
- _err0_transports(err0_transports)
-{
+usrp2_impl::usrp2_impl(const device_addr_t &device_addr){
+ device_addrs_t device_args = sep_indexed_dev_addrs(device_addr);
+
//setup rx otw type
_rx_otw_type.width = 16;
_rx_otw_type.shift = 0;
@@ -281,13 +223,11 @@ usrp2_impl::usrp2_impl(
//create a new mboard handler for each control transport
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],
- err0_transports[i], device_args[i],
- this->get_max_recv_samps_per_packet()
- )));
+ _mboards.push_back(usrp2_mboard_impl::sptr(
+ new usrp2_mboard_impl(device_addr, device_args[i], i, *this)
+ ));
//use an empty name when there is only one mboard
- std::string name = (ctrl_transports.size() > 1)? boost::lexical_cast<std::string>(i) : "";
+ std::string name = (device_args.size() > 1)? boost::lexical_cast<std::string>(i) : "";
_mboard_dict[name] = _mboards.back();
}
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index cb049f876..4f68b630e 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -71,6 +71,8 @@ private:
void set(const wax::obj &key, const wax::obj &val){return _set(key, val);}
};
+class usrp2_impl;
+
/*!
* USRP2 mboard implementation guts:
* The implementation details are encapsulated here.
@@ -85,12 +87,9 @@ public:
//structors
usrp2_mboard_impl(
- size_t index,
- uhd::transport::udp_simple::sptr,
- uhd::transport::zero_copy_if::sptr,
- uhd::transport::zero_copy_if::sptr,
+ const uhd::device_addr_t &device_addr,
const uhd::device_addr_t &device_args,
- size_t recv_samps_per_packet
+ size_t index, usrp2_impl &device
);
~usrp2_mboard_impl(void);
@@ -100,8 +99,12 @@ public:
void handle_overflow(size_t);
+ std::vector<uhd::transport::zero_copy_if::sptr> dsp_xports;
+ std::vector<uhd::transport::zero_copy_if::sptr> err_xports;
+
private:
size_t _index;
+ usrp2_impl &_device;
bool _mimo_clocking_mode_is_master;
//interfaces
@@ -151,7 +154,7 @@ private:
//methods and shadows for the dsps
UHD_PIMPL_DECL(dsp_impl) _dsp_impl;
- void dsp_init(size_t recv_samps_per_packet);
+ void dsp_init(void);
void issue_ddc_stream_cmd(const uhd::stream_cmd_t &, size_t);
//properties interface for ddc
@@ -177,19 +180,7 @@ public:
static const boost::uint32_t RECV_SID = 1;
static const boost::uint32_t ASYNC_SID = 2;
- /*!
- * Create a new usrp2 impl base.
- * \param ctrl_transports the udp transports for control
- * \param data_transports the udp transports for data
- * \param err0_transports the udp transports for error
- * \param device_args optional misc device parameters
- */
- usrp2_impl(
- std::vector<uhd::transport::udp_simple::sptr> ctrl_transports,
- std::vector<uhd::transport::zero_copy_if::sptr> data_transports,
- std::vector<uhd::transport::zero_copy_if::sptr> err0_transports,
- const uhd::device_addrs_t &device_args
- );
+ usrp2_impl(const uhd::device_addr_t &);
~usrp2_impl(void);
@@ -208,6 +199,11 @@ public:
size_t get_max_recv_samps_per_packet(void) const;
bool recv_async_msg(uhd::async_metadata_t &, double);
+ void update_xport_channel_mapping(void);
+
+ //public frame sizes, set by mboard, used by io impl
+ size_t recv_frame_size, send_frame_size;
+
private:
//device properties interface
void get(const wax::obj &, wax::obj &);
@@ -218,8 +214,6 @@ private:
uhd::dict<std::string, usrp2_mboard_impl::sptr> _mboard_dict;
//io impl methods and members
- std::vector<uhd::transport::zero_copy_if::sptr> _data_transports;
- std::vector<uhd::transport::zero_copy_if::sptr> _err0_transports;
uhd::otw_type_t _rx_otw_type, _tx_otw_type;
UHD_PIMPL_DECL(io_impl) _io_impl;
void io_init(void);