summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/include/uhd/types/metadata.hpp15
-rw-r--r--host/lib/usrp/b100/io_impl.cpp26
-rw-r--r--host/lib/usrp/common/async_packet_handler.hpp71
-rw-r--r--host/lib/usrp/e100/io_impl.cpp18
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp18
5 files changed, 100 insertions, 48 deletions
diff --git a/host/include/uhd/types/metadata.hpp b/host/include/uhd/types/metadata.hpp
index 269c77c7c..788999900 100644
--- a/host/include/uhd/types/metadata.hpp
+++ b/host/include/uhd/types/metadata.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
#include <uhd/config.hpp>
#include <uhd/types/time_spec.hpp>
+#include <boost/cstdint.hpp>
namespace uhd{
@@ -140,13 +141,21 @@ namespace uhd{
EVENT_CODE_UNDERFLOW = 0x2,
//! Packet loss between host and device.
EVENT_CODE_SEQ_ERROR = 0x4,
- //! Packet had time that was late (or too early).
+ //! Packet had time that was late.
EVENT_CODE_TIME_ERROR = 0x8,
//! Underflow occurred inside a packet.
EVENT_CODE_UNDERFLOW_IN_PACKET = 0x10,
//! Packet loss within a burst.
- EVENT_CODE_SEQ_ERROR_IN_BURST = 0x20
+ EVENT_CODE_SEQ_ERROR_IN_BURST = 0x20,
+ //! Some kind of custom user payload
+ EVENT_CODE_USER_PAYLOAD = 0x40
} event_code;
+
+ /*!
+ * A special payload populated by custom FPGA fabric.
+ */
+ boost::uint32_t user_payload[4];
+
};
} //namespace uhd
diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp
index 6f8d3fb52..674380cca 100644
--- a/host/lib/usrp/b100/io_impl.cpp
+++ b/host/lib/usrp/b100/io_impl.cpp
@@ -17,6 +17,7 @@
#include "recv_packet_demuxer.hpp"
#include "validate_subdev_spec.hpp"
+#include "async_packet_handler.hpp"
#include "../../transport/super_recv_packet_handler.hpp"
#include "../../transport/super_send_packet_handler.hpp"
#include "usrp_commands.h"
@@ -47,6 +48,7 @@ struct b100_impl::io_impl{
zero_copy_if::sptr data_transport;
bounded_buffer<async_metadata_t> async_msg_fifo;
recv_packet_demuxer::sptr demuxer;
+ double tick_rate;
};
/***********************************************************************
@@ -81,24 +83,16 @@ void b100_impl::handle_async_message(managed_recv_buffer::sptr rbuf){
}
if (if_packet_info.sid == B100_TX_ASYNC_SID and if_packet_info.packet_type != vrt::if_packet_info_t::PACKET_TYPE_DATA){
+
//fill in the async metadata
async_metadata_t metadata;
- metadata.channel = 0;
- metadata.has_time_spec = if_packet_info.has_tsf;
- metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, _clock_ctrl->get_fpga_clock_rate());
- metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(vrt_hdr, if_packet_info));
+ load_metadata_from_buff(uhd::wtohx<boost::uint32_t>, metadata, if_packet_info, vrt_hdr, _io_impl->tick_rate);
+
+ //push the message onto the queue
_io_impl->async_msg_fifo.push_with_pop_on_full(metadata);
- if (metadata.event_code &
- ( async_metadata_t::EVENT_CODE_UNDERFLOW
- | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET)
- ) UHD_MSG(fastpath) << "U";
- else if (metadata.event_code &
- ( async_metadata_t::EVENT_CODE_SEQ_ERROR
- | async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST)
- ) UHD_MSG(fastpath) << "S";
- else if (metadata.event_code &
- async_metadata_t::EVENT_CODE_TIME_ERROR
- ) UHD_MSG(fastpath) << "L";
+
+ //print some fastpath messages
+ standard_async_msg_prints(metadata);
}
else UHD_MSG(error) << "Unknown async packet" << std::endl;
}
@@ -117,6 +111,8 @@ void b100_impl::update_rates(void){
}
void b100_impl::update_tick_rate(const double rate){
+ _io_impl->tick_rate = rate;
+
//update the tick rate on all existing streamers -> thread safe
for (size_t i = 0; i < _rx_streamers.size(); i++){
boost::shared_ptr<sph::recv_packet_streamer> my_streamer =
diff --git a/host/lib/usrp/common/async_packet_handler.hpp b/host/lib/usrp/common/async_packet_handler.hpp
new file mode 100644
index 000000000..fef03483f
--- /dev/null
+++ b/host/lib/usrp/common/async_packet_handler.hpp
@@ -0,0 +1,71 @@
+//
+// Copyright 2012 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_LIBUHD_USRP_COMMON_ASYNC_PACKET_HANDLER_HPP
+#define INCLUDED_LIBUHD_USRP_COMMON_ASYNC_PACKET_HANDLER_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/transport/vrt_if_packet.hpp>
+#include <uhd/types/metadata.hpp>
+#include <uhd/utils/byteswap.hpp>
+#include <uhd/utils/msg.hpp>
+
+namespace uhd{ namespace usrp{
+
+ template <typename to_host_type>
+ void load_metadata_from_buff(
+ const to_host_type &to_host,
+ async_metadata_t &metadata,
+ const transport::vrt::if_packet_info_t &if_packet_info,
+ const boost::uint32_t *vrt_hdr,
+ const double tick_rate,
+ const size_t channel = 0
+ ){
+ const boost::uint32_t *payload = vrt_hdr + if_packet_info.num_header_words32;
+
+ //load into metadata
+ metadata.channel = channel;
+ metadata.has_time_spec = if_packet_info.has_tsf;
+ metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, tick_rate);
+ metadata.event_code = async_metadata_t::event_code_t(to_host(payload[0]) & 0xff);
+
+ //load user payload
+ for (size_t i = 1; i < if_packet_info.num_payload_words32; i++){
+ if (i-1 == 4) break; //limit of 4 words32
+ metadata.user_payload[i-1] = to_host(payload[i]);
+ }
+ }
+
+ UHD_INLINE void standard_async_msg_prints(const async_metadata_t &metadata)
+ {
+ if (metadata.event_code &
+ ( async_metadata_t::EVENT_CODE_UNDERFLOW
+ | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET)
+ ) UHD_MSG(fastpath) << "U";
+ else if (metadata.event_code &
+ ( async_metadata_t::EVENT_CODE_SEQ_ERROR
+ | async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST)
+ ) UHD_MSG(fastpath) << "S";
+ else if (metadata.event_code &
+ async_metadata_t::EVENT_CODE_TIME_ERROR
+ ) UHD_MSG(fastpath) << "L";
+ }
+
+
+}} //namespace uhd::usrp
+
+#endif /* INCLUDED_LIBUHD_USRP_COMMON_ASYNC_PACKET_HANDLER_HPP */
diff --git a/host/lib/usrp/e100/io_impl.cpp b/host/lib/usrp/e100/io_impl.cpp
index b090e45c7..e9608125f 100644
--- a/host/lib/usrp/e100/io_impl.cpp
+++ b/host/lib/usrp/e100/io_impl.cpp
@@ -17,6 +17,7 @@
#include "recv_packet_demuxer.hpp"
#include "validate_subdev_spec.hpp"
+#include "async_packet_handler.hpp"
#include "../../transport/super_recv_packet_handler.hpp"
#include "../../transport/super_send_packet_handler.hpp"
#include <linux/usrp_e.h> //ioctl structures and constants
@@ -123,26 +124,13 @@ void e100_impl::io_impl::handle_irq(void){
//fill in the async metadata
async_metadata_t metadata;
- metadata.channel = 0;
- metadata.has_time_spec = if_packet_info.has_tsf;
- metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, tick_rate);
- metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(data.buf, if_packet_info));
+ load_metadata_from_buff(uhd::wtohx<boost::uint32_t>, metadata, if_packet_info, data.buf, tick_rate);
//push the message onto the queue
async_msg_fifo.push_with_pop_on_full(metadata);
//print some fastpath messages
- if (metadata.event_code &
- ( async_metadata_t::EVENT_CODE_UNDERFLOW
- | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET)
- ) UHD_MSG(fastpath) << "U";
- else if (metadata.event_code &
- ( async_metadata_t::EVENT_CODE_SEQ_ERROR
- | async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST)
- ) UHD_MSG(fastpath) << "S";
- else if (metadata.event_code &
- async_metadata_t::EVENT_CODE_TIME_ERROR
- ) UHD_MSG(fastpath) << "L";
+ standard_async_msg_prints(metadata);
}
//prepare for the next round
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index 221b747cb..d32ffb62c 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -16,6 +16,7 @@
//
#include "validate_subdev_spec.hpp"
+#include "async_packet_handler.hpp"
#include "../../transport/super_recv_packet_handler.hpp"
#include "../../transport/super_send_packet_handler.hpp"
#include "usrp2_impl.hpp"
@@ -202,10 +203,7 @@ void usrp2_impl::io_impl::recv_pirate_loop(
//fill in the async metadata
async_metadata_t metadata;
- metadata.channel = index;
- metadata.has_time_spec = if_packet_info.has_tsf;
- metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, tick_rate);
- metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(vrt_hdr, if_packet_info));
+ load_metadata_from_buff(uhd::ntohx<boost::uint32_t>, metadata, if_packet_info, vrt_hdr, tick_rate, index);
//catch the flow control packets and react
if (metadata.event_code == 0){
@@ -216,17 +214,7 @@ void usrp2_impl::io_impl::recv_pirate_loop(
//else UHD_MSG(often) << "metadata.event_code " << metadata.event_code << std::endl;
async_msg_fifo.push_with_pop_on_full(metadata);
- if (metadata.event_code &
- ( async_metadata_t::EVENT_CODE_UNDERFLOW
- | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET)
- ) UHD_MSG(fastpath) << "U";
- else if (metadata.event_code &
- ( async_metadata_t::EVENT_CODE_SEQ_ERROR
- | async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST)
- ) UHD_MSG(fastpath) << "S";
- else if (metadata.event_code &
- async_metadata_t::EVENT_CODE_TIME_ERROR
- ) UHD_MSG(fastpath) << "L";
+ standard_async_msg_prints(metadata);
}
else{
//TODO unknown received packet, may want to print error...