summaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-10-07 10:11:32 -0700
committerJosh Blum <josh@joshknows.com>2010-10-07 10:11:32 -0700
commit86b021e48031f2bc6e99c7c5d2d626ea149dec70 (patch)
treec107d3d7fb0f34da17085c06e81aa96258c38746 /host/lib/usrp
parentd5a0960455560e9f6077aa45d52aa01c469769dd (diff)
parentb40ace72dd1b940fc0ce6e4a5e06346439dd5625 (diff)
downloaduhd-86b021e48031f2bc6e99c7c5d2d626ea149dec70.tar.gz
uhd-86b021e48031f2bc6e99c7c5d2d626ea149dec70.tar.bz2
uhd-86b021e48031f2bc6e99c7c5d2d626ea149dec70.zip
Merge branch 'next' into usrp_e_mmap_b2
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/usrp1/io_impl.cpp169
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.cpp48
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.hpp10
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp4
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp8
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp40
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp75
7 files changed, 161 insertions, 193 deletions
diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp
index 676b1536a..0a16f7a43 100644
--- a/host/lib/usrp/usrp1/io_impl.cpp
+++ b/host/lib/usrp/usrp1/io_impl.cpp
@@ -33,6 +33,28 @@ using namespace uhd::usrp;
using namespace uhd::transport;
namespace asio = boost::asio;
+static const size_t alignment_padding = 512;
+
+/***********************************************************************
+ * Helper struct to associate an offset with a buffer
+ **********************************************************************/
+class offset_send_buffer{
+public:
+ typedef boost::shared_ptr<offset_send_buffer> sptr;
+
+ static sptr make(managed_send_buffer::sptr buff, size_t offset = 0){
+ return sptr(new offset_send_buffer(buff, offset));
+ }
+
+ //member variables
+ managed_send_buffer::sptr buff;
+ size_t offset; /* in bytes */
+
+private:
+ offset_send_buffer(managed_send_buffer::sptr buff, size_t offset):
+ buff(buff), offset(offset){/* NOP */}
+};
+
/***********************************************************************
* IO Implementation Details
**********************************************************************/
@@ -41,8 +63,7 @@ struct usrp1_impl::io_impl{
data_transport(data_transport),
underflow_poll_samp_count(0),
overflow_poll_samp_count(0),
- send_buff(data_transport->get_send_buff()),
- num_bytes_committed(0)
+ curr_buff(offset_send_buffer::make(data_transport->get_send_buff()))
{
/* NOP */
}
@@ -62,98 +83,88 @@ struct usrp1_impl::io_impl{
size_t overflow_poll_samp_count;
//wrapper around the actual send buffer interface
- //all of this to ensure only full buffers are committed
- managed_send_buffer::sptr send_buff;
- size_t num_bytes_committed;
- double send_timeout;
- boost::uint8_t pseudo_buff[BYTES_PER_PACKET];
- void phony_commit_pseudo_buff(size_t num_bytes);
- void phony_commit_send_buff(size_t num_bytes);
- void commit_send_buff(void);
+ //all of this to ensure only aligned lengths are committed
+ //NOTE: you must commit before getting a new buffer
+ //since the vrt packet handler obeys this, we are ok
+ offset_send_buffer::sptr curr_buff;
+ void commit_send_buff(offset_send_buffer::sptr, offset_send_buffer::sptr, size_t);
void flush_send_buff(void);
bool get_send_buffs(vrt_packet_handler::managed_send_buffs_t &, double);
-
- //helpers to get at the send buffer + offset
- inline void *get_send_mem_ptr(void){
- return send_buff->cast<boost::uint8_t *>() + num_bytes_committed;
- }
- inline size_t get_send_mem_size(void){
- return send_buff->size() - num_bytes_committed;
- }
};
/*!
- * Accept a commit of num bytes to the pseudo buffer.
- * Memcpy the entire contents of pseudo buffer into send buffers.
- *
- * Under most conditions:
- * The first loop iteration will fill the remainder of the send buffer.
- * The second loop iteration will empty the pseudo buffer remainder.
+ * Perform an actual commit on the send buffer:
+ * Copy the remainder of alignment to the next buffer.
+ * Commit the current buffer at multiples of alignment.
*/
-void usrp1_impl::io_impl::phony_commit_pseudo_buff(size_t num_bytes){
- size_t bytes_to_copy = num_bytes, bytes_copied = 0;
- while(bytes_to_copy){
- size_t bytes_copied_here = std::min(bytes_to_copy, get_send_mem_size());
- std::memcpy(get_send_mem_ptr(), pseudo_buff + bytes_copied, bytes_copied_here);
- phony_commit_send_buff(bytes_copied_here);
- bytes_to_copy -= bytes_copied_here;
- bytes_copied += bytes_copied_here;
- }
-}
+void usrp1_impl::io_impl::commit_send_buff(
+ offset_send_buffer::sptr curr,
+ offset_send_buffer::sptr next,
+ size_t num_bytes
+){
+ //total number of bytes now in the current buffer
+ size_t bytes_in_curr_buffer = curr->offset + num_bytes;
-/*!
- * Accept a commit of num bytes to the send buffer.
- * Conditionally commit the send buffer if full.
- */
-void usrp1_impl::io_impl::phony_commit_send_buff(size_t num_bytes){
- num_bytes_committed += num_bytes;
- if (num_bytes_committed != send_buff->size()) return;
- commit_send_buff();
+ //calculate how many to commit and remainder
+ size_t num_bytes_remaining = bytes_in_curr_buffer % alignment_padding;
+ size_t num_bytes_to_commit = bytes_in_curr_buffer - num_bytes_remaining;
+
+ //copy the remainder into the next buffer
+ std::memcpy(
+ next->buff->cast<char *>() + next->offset,
+ curr->buff->cast<char *>() + num_bytes_to_commit,
+ num_bytes_remaining
+ );
+
+ //update the offset into the next buffer
+ next->offset += num_bytes_remaining;
+
+ //commit the current buffer
+ curr->buff->commit(num_bytes_to_commit);
}
/*!
- * Flush the send buffer:
- * Zero-pad the send buffer to the nearest 512 byte boundary and commit.
+ * Flush the current buffer by padding out to alignment and committing.
*/
void usrp1_impl::io_impl::flush_send_buff(void){
- size_t bytes_to_pad = (-1*num_bytes_committed)%512;
- std::memset(get_send_mem_ptr(), 0, bytes_to_pad);
- num_bytes_committed += bytes_to_pad;
- commit_send_buff();
+ //calculate the number of bytes to alignment
+ size_t bytes_to_pad = (-1*curr_buff->offset)%alignment_padding;
+
+ //get the buffer, clear, and commit (really current buffer)
+ vrt_packet_handler::managed_send_buffs_t buffs(1);
+ if (this->get_send_buffs(buffs, 0.1)){
+ std::memset(buffs[0]->cast<void *>(), 0, bytes_to_pad);
+ buffs[0]->commit(bytes_to_pad);
+ }
}
/*!
- * Perform an actual commit on the send buffer:
- * Commit the contents of the send buffer and request a new buffer.
+ * Get a managed send buffer with the alignment padding:
+ * Always grab the next send buffer so we can timeout here.
*/
-void usrp1_impl::io_impl::commit_send_buff(void){
- send_buff->commit(num_bytes_committed);
- send_buff = data_transport->get_send_buff(send_timeout);
- num_bytes_committed = 0;
-}
-
bool usrp1_impl::io_impl::get_send_buffs(
vrt_packet_handler::managed_send_buffs_t &buffs, double timeout
){
- send_timeout = timeout;
UHD_ASSERT_THROW(buffs.size() == 1);
- //not enough bytes free -> use the pseudo buffer
- if (get_send_mem_size() < BYTES_PER_PACKET){
- buffs[0] = managed_send_buffer::make_safe(
- boost::asio::buffer(pseudo_buff),
- boost::bind(&usrp1_impl::io_impl::phony_commit_pseudo_buff, this, _1)
- );
- }
- //otherwise use the send buffer offset by the bytes written
- else{
- buffs[0] = managed_send_buffer::make_safe(
- boost::asio::buffer(get_send_mem_ptr(), get_send_mem_size()),
- boost::bind(&usrp1_impl::io_impl::phony_commit_send_buff, this, _1)
- );
- }
+ //try to get a new managed buffer with timeout
+ offset_send_buffer::sptr next_buff(offset_send_buffer::make(data_transport->get_send_buff(timeout)));
+ if (not next_buff->buff.get()) return false; /* propagate timeout here */
- return buffs[0].get() != NULL;
+ //calculate the buffer pointer and size given the offset
+ //references to the buffers are held in the bound function
+ buffs[0] = managed_send_buffer::make_safe(
+ boost::asio::buffer(
+ curr_buff->buff->cast<char *>() + curr_buff->offset,
+ curr_buff->buff->size() - curr_buff->offset
+ ),
+ boost::bind(&usrp1_impl::io_impl::commit_send_buff, this, curr_buff, next_buff, _1)
+ );
+
+ //store the next buffer for the next call
+ curr_buff = next_buff;
+
+ return true;
}
/***********************************************************************
@@ -182,6 +193,13 @@ static void usrp1_bs_vrt_packer(
if_packet_info.num_packet_words32 = if_packet_info.num_payload_words32;
}
+size_t usrp1_impl::get_max_send_samps_per_packet(void) const {
+ return (_data_transport->get_send_frame_size() - alignment_padding)
+ / _tx_otw_type.get_sample_size()
+ / _tx_subdev_spec.size()
+ ;
+}
+
size_t usrp1_impl::send(
const std::vector<const void *> &buffs, size_t num_samps,
const tx_metadata_t &metadata, const io_type_t &io_type,
@@ -249,6 +267,13 @@ static bool get_recv_buffs(
return buffs[0].get() != NULL;
}
+size_t usrp1_impl::get_max_recv_samps_per_packet(void) const {
+ return _data_transport->get_recv_frame_size()
+ / _rx_otw_type.get_sample_size()
+ / _rx_subdev_spec.size()
+ ;
+}
+
size_t usrp1_impl::recv(
const std::vector<void *> &buffs, size_t num_samps,
rx_metadata_t &metadata, const io_type_t &io_type,
diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp
index 6ebd6bb09..276ca86f6 100644
--- a/host/lib/usrp/usrp1/usrp1_impl.cpp
+++ b/host/lib/usrp/usrp1/usrp1_impl.cpp
@@ -106,17 +106,8 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)
/***********************************************************************
* Make
**********************************************************************/
-template<typename output_type> static output_type cast_from_dev_addr(
- const device_addr_t &device_addr,
- const std::string &key,
- output_type def_val
-){
- return (device_addr.has_key(key))?
- boost::lexical_cast<output_type>(device_addr[key]) : def_val;
-}
+static device::sptr usrp1_make(const device_addr_t &device_addr){
-static device::sptr usrp1_make(const device_addr_t &device_addr)
-{
//extract the FPGA path for the USRP1
std::string usrp1_fpga_image = find_image_path(
device_addr.has_key("fpga")? device_addr["fpga"] : "usrp1_fpga.rbf"
@@ -127,29 +118,26 @@ static device::sptr usrp1_make(const device_addr_t &device_addr)
std::vector<usb_device_handle::sptr> device_list =
usb_device_handle::get_device_list(USRP1_VENDOR_ID, USRP1_PRODUCT_ID);
- //create data and control transports
- usb_zero_copy::sptr data_transport;
- usrp_ctrl::sptr usrp_ctrl;
-
-
- BOOST_FOREACH(usb_device_handle::sptr handle, device_list) {
- if (handle->get_serial() == device_addr["serial"]) {
- usb_control::sptr ctrl_transport = usb_control::make(handle);
- usrp_ctrl = usrp_ctrl::make(ctrl_transport);
- usrp_ctrl->usrp_load_fpga(usrp1_fpga_image);
-
- data_transport = usb_zero_copy::make(
- handle, // identifier
- 6, // IN endpoint
- 2, // OUT endpoint
- size_t(cast_from_dev_addr<double>(device_addr, "recv_xfer_size", 0)),
- size_t(cast_from_dev_addr<double>(device_addr, "recv_num_xfers", 0)),
- size_t(cast_from_dev_addr<double>(device_addr, "send_xfer_size", 0)),
- size_t(cast_from_dev_addr<double>(device_addr, "send_num_xfers", 0))
- );
+ //locate the matching handle in the device list
+ usb_device_handle::sptr handle;
+ BOOST_FOREACH(usb_device_handle::sptr dev_handle, device_list) {
+ if (dev_handle->get_serial() == device_addr["serial"]){
+ handle = dev_handle;
break;
}
}
+ UHD_ASSERT_THROW(handle.get() != NULL); //better be found
+
+ //create control objects and a data transport
+ usb_control::sptr ctrl_transport = usb_control::make(handle);
+ usrp_ctrl::sptr usrp_ctrl = usrp_ctrl::make(ctrl_transport);
+ usrp_ctrl->usrp_load_fpga(usrp1_fpga_image);
+ usb_zero_copy::sptr data_transport = usb_zero_copy::make(
+ handle, // identifier
+ 6, // IN endpoint
+ 2, // OUT endpoint
+ device_addr // param hints
+ );
//create the usrp1 implementation guts
return device::sptr(new usrp1_impl(data_transport, usrp_ctrl));
diff --git a/host/lib/usrp/usrp1/usrp1_impl.hpp b/host/lib/usrp/usrp1/usrp1_impl.hpp
index f2c464610..ff4d40762 100644
--- a/host/lib/usrp/usrp1/usrp1_impl.hpp
+++ b/host/lib/usrp/usrp1/usrp1_impl.hpp
@@ -90,15 +90,9 @@ public:
const uhd::io_type_t &,
recv_mode_t, double);
- static const size_t BYTES_PER_PACKET = 512*4; //under the transfer size
+ size_t get_max_send_samps_per_packet(void) const;
- size_t get_max_send_samps_per_packet(void) const {
- return BYTES_PER_PACKET/_tx_otw_type.get_sample_size()/_tx_subdev_spec.size();
- }
-
- size_t get_max_recv_samps_per_packet(void) const {
- return BYTES_PER_PACKET/_rx_otw_type.get_sample_size()/_rx_subdev_spec.size();
- }
+ size_t get_max_recv_samps_per_packet(void) const;
bool recv_async_msg(uhd::async_metadata_t &, double);
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index 33cec3cbc..07eda08c3 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -206,7 +206,7 @@ size_t usrp2_impl::send(
_io_impl->packet_handler_send_state, //last state of the send handler
buffs, num_samps, //buffer to fill
metadata, send_mode, //samples metadata
- io_type, _io_helper.get_tx_otw_type(), //input and output types to convert
+ io_type, _tx_otw_type, //input and output types to convert
_mboards.front()->get_master_clock_freq(), //master clock tick rate
uhd::transport::vrt::if_hdr_pack_be,
boost::bind(&get_send_buffs, _data_transports, _1, timeout),
@@ -226,7 +226,7 @@ size_t usrp2_impl::recv(
_io_impl->packet_handler_recv_state, //last state of the recv handler
buffs, num_samps, //buffer to fill
metadata, recv_mode, //samples metadata
- io_type, _io_helper.get_rx_otw_type(), //input and output types to convert
+ io_type, _rx_otw_type, //input and output types to convert
_mboards.front()->get_master_clock_freq(), //master clock tick rate
uhd::transport::vrt::if_hdr_unpack_be,
boost::bind(&usrp2_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout)
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index 0b9f8ee83..a0e6adfad 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -38,10 +38,10 @@ using namespace uhd::usrp;
usrp2_mboard_impl::usrp2_mboard_impl(
size_t index,
transport::udp_simple::sptr ctrl_transport,
- const usrp2_io_helper &io_helper
+ size_t recv_frame_size
):
_index(index),
- _io_helper(io_helper)
+ _recv_frame_size(recv_frame_size)
{
//make a new interface for usrp2 stuff
_iface = usrp2_iface::make(ctrl_transport);
@@ -75,7 +75,7 @@ usrp2_mboard_impl::usrp2_mboard_impl(
this->issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
//init the rx control registers
- _iface->poke32(U2_REG_RX_CTRL_NSAMPS_PER_PKT, _io_helper.get_max_recv_samps_per_packet());
+ _iface->poke32(U2_REG_RX_CTRL_NSAMPS_PER_PKT, _recv_frame_size);
_iface->poke32(U2_REG_RX_CTRL_NCHANNELS, 1);
_iface->poke32(U2_REG_RX_CTRL_CLEAR_OVERRUN, 1); //reset
_iface->poke32(U2_REG_RX_CTRL_VRT_HEADER, 0
@@ -178,7 +178,7 @@ void usrp2_mboard_impl::set_time_spec(const time_spec_t &time_spec, bool now){
void usrp2_mboard_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){
_iface->poke32(U2_REG_RX_CTRL_STREAM_CMD, dsp_type1::calc_stream_cmd_word(
- stream_cmd, _io_helper.get_max_recv_samps_per_packet()
+ stream_cmd, _recv_frame_size
));
_iface->poke32(U2_REG_RX_CTRL_TIME_SECS, boost::uint32_t(stream_cmd.time_spec.get_full_secs()));
_iface->poke32(U2_REG_RX_CTRL_TIME_TICKS, stream_cmd.time_spec.get_tick_count(get_master_clock_freq()));
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index 568c87a22..a680708ad 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -124,26 +124,7 @@ static uhd::device_addrs_t usrp2_find(const device_addr_t &hint){
/***********************************************************************
* Make
**********************************************************************/
-template <typename out_type, typename in_type>
-out_type lexical_cast(const in_type &in){
- try{
- return boost::lexical_cast<out_type>(in);
- }catch(...){
- throw std::runtime_error(str(boost::format(
- "failed to cast \"%s\" to type \"%s\""
- ) % boost::lexical_cast<std::string>(in) % typeid(out_type).name()));
- }
-}
-
static device::sptr usrp2_make(const device_addr_t &device_addr){
- //extract the receive and send buffer sizes
- size_t recv_buff_size = 0, send_buff_size= 0 ;
- if (device_addr.has_key("recv_buff_size")){
- recv_buff_size = size_t(lexical_cast<double>(device_addr["recv_buff_size"]));
- }
- if (device_addr.has_key("send_buff_size")){
- send_buff_size = size_t(lexical_cast<double>(device_addr["send_buff_size"]));
- }
//create a ctrl and data transport for each address
std::vector<udp_simple::sptr> ctrl_transports;
@@ -154,8 +135,7 @@ static device::sptr usrp2_make(const device_addr_t &device_addr){
addr, num2str(USRP2_UDP_CTRL_PORT)
));
data_transports.push_back(udp_zero_copy::make(
- addr, num2str(USRP2_UDP_DATA_PORT),
- recv_buff_size, send_buff_size
+ addr, num2str(USRP2_UDP_DATA_PORT), device_addr
));
}
@@ -178,11 +158,23 @@ usrp2_impl::usrp2_impl(
):
_data_transports(data_transports)
{
+ //setup rx otw type
+ _rx_otw_type.width = 16;
+ _rx_otw_type.shift = 0;
+ _rx_otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
+
+ //setup tx otw type
+ _tx_otw_type.width = 16;
+ _tx_otw_type.shift = 0;
+ _tx_otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
+
+ //!!!!! 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++){
- _mboards.push_back(usrp2_mboard_impl::sptr(
- new usrp2_mboard_impl(i, ctrl_transports[i], _io_helper)
- ));
+ _mboards.push_back(usrp2_mboard_impl::sptr(new usrp2_mboard_impl(
+ i, ctrl_transports[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) : "";
_mboard_dict[name] = _mboards.back();
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index e8763b284..e12c4d6d4 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -72,54 +72,6 @@ private:
};
/*!
- * The io helper class encapculates the max packet sizes and otw types.
- * The otw types are read-only for now, this will be reimplemented
- * when it becomes possible to change the otw type in the usrp2.
- */
-class usrp2_io_helper{
-public:
- usrp2_io_helper(void){
- //setup rx otw type
- _rx_otw_type.width = 16;
- _rx_otw_type.shift = 0;
- _rx_otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
-
- //setup tx otw type
- _tx_otw_type.width = 16;
- _tx_otw_type.shift = 0;
- _tx_otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
- }
-
- inline size_t get_max_send_samps_per_packet(void) const{
- return _max_tx_bytes_per_packet/_tx_otw_type.get_sample_size();
- }
-
- inline size_t get_max_recv_samps_per_packet(void) const{
- return _max_rx_bytes_per_packet/_rx_otw_type.get_sample_size();
- }
-
- inline const uhd::otw_type_t &get_rx_otw_type(void) const{
- return _rx_otw_type;
- }
-
- inline const uhd::otw_type_t &get_tx_otw_type(void) const{
- return _tx_otw_type;
- }
-
-private:
- uhd::otw_type_t _rx_otw_type, _tx_otw_type;
- static const size_t _max_rx_bytes_per_packet = uhd::transport::udp_simple::mtu
- - uhd::transport::vrt::max_if_hdr_words32*sizeof(boost::uint32_t)
- - sizeof(uhd::transport::vrt::if_packet_info_t().tlr) //forced to have trailer
- + sizeof(uhd::transport::vrt::if_packet_info_t().cid) //no class id ever used
- ;
- static const size_t _max_tx_bytes_per_packet = uhd::transport::udp_simple::mtu
- - uhd::transport::vrt::max_if_hdr_words32*sizeof(boost::uint32_t)
- + sizeof(uhd::transport::vrt::if_packet_info_t().cid) //no class id ever used
- ;
-};
-
-/*!
* USRP2 mboard implementation guts:
* The implementation details are encapsulated here.
* Handles properties on the mboard, dboard, dsps...
@@ -129,7 +81,11 @@ public:
typedef boost::shared_ptr<usrp2_mboard_impl> sptr;
//structors
- usrp2_mboard_impl(size_t index, uhd::transport::udp_simple::sptr, const usrp2_io_helper &);
+ usrp2_mboard_impl(
+ size_t index,
+ uhd::transport::udp_simple::sptr,
+ size_t recv_frame_size
+ );
~usrp2_mboard_impl(void);
inline double get_master_clock_freq(void){
@@ -139,7 +95,7 @@ public:
private:
size_t _index;
int _rev_hi, _rev_lo;
- const usrp2_io_helper &_io_helper;
+ const size_t _recv_frame_size;
//properties for this mboard
void get(const wax::obj &, wax::obj &);
@@ -229,7 +185,8 @@ public:
//the io interface
size_t get_max_send_samps_per_packet(void) const{
- return _io_helper.get_max_send_samps_per_packet();
+ const size_t bytes_per_packet = _data_transports.front()->get_send_frame_size() - _max_tx_header_bytes;
+ return bytes_per_packet/_tx_otw_type.get_sample_size();
}
size_t send(
const std::vector<const void *> &, size_t,
@@ -237,7 +194,8 @@ public:
uhd::device::send_mode_t, double
);
size_t get_max_recv_samps_per_packet(void) const{
- return _io_helper.get_max_recv_samps_per_packet();
+ const size_t bytes_per_packet = _data_transports.front()->get_recv_frame_size() - _max_rx_header_bytes;
+ return bytes_per_packet/_rx_otw_type.get_sample_size();
}
size_t recv(
const std::vector<void *> &, size_t,
@@ -257,9 +215,20 @@ private:
//io impl methods and members
std::vector<uhd::transport::udp_zero_copy::sptr> _data_transports;
- const usrp2_io_helper _io_helper;
UHD_PIMPL_DECL(io_impl) _io_impl;
void io_init(void);
+
+ //over-the-wire structs and constants
+ uhd::otw_type_t _rx_otw_type, _tx_otw_type;
+ static const size_t _max_rx_header_bytes = 0
+ + uhd::transport::vrt::max_if_hdr_words32*sizeof(boost::uint32_t)
+ + sizeof(uhd::transport::vrt::if_packet_info_t().tlr) //forced to have trailer
+ - sizeof(uhd::transport::vrt::if_packet_info_t().cid) //no class id ever used
+ ;
+ static const size_t _max_tx_header_bytes = 0
+ + uhd::transport::vrt::max_if_hdr_words32*sizeof(boost::uint32_t)
+ - sizeof(uhd::transport::vrt::if_packet_info_t().cid) //no class id ever used
+ ;
};
#endif /* INCLUDED_USRP2_IMPL_HPP */