aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/usrp2/clock_ctrl.cpp8
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp162
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp2
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp8
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp50
5 files changed, 70 insertions, 160 deletions
diff --git a/host/lib/usrp/usrp2/clock_ctrl.cpp b/host/lib/usrp/usrp2/clock_ctrl.cpp
index db8d8a886..4c5207203 100644
--- a/host/lib/usrp/usrp2/clock_ctrl.cpp
+++ b/host/lib/usrp/usrp2/clock_ctrl.cpp
@@ -79,7 +79,9 @@ public:
_ad9510_regs.power_down_lvds_cmos_out7 = enb? 0 : 1;
_ad9510_regs.lvds_cmos_select_out7 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT7_CMOS;
_ad9510_regs.output_level_lvds_out7 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT7_1_75MA;
+ _ad9510_regs.bypass_divider_out7 = 1;
this->write_reg(0x43);
+ this->write_reg(0x57);
this->update_regs();
}
@@ -88,7 +90,9 @@ public:
_ad9510_regs.power_down_lvds_cmos_out6 = enb? 0 : 1;
_ad9510_regs.lvds_cmos_select_out6 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT6_CMOS;
_ad9510_regs.output_level_lvds_out6 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT6_1_75MA;
+ _ad9510_regs.bypass_divider_out6 = 1;
this->write_reg(0x42);
+ this->write_reg(0x55);
this->update_regs();
}
@@ -130,7 +134,9 @@ private:
ad9510_regs_t::POWER_DOWN_LVPECL_OUT3_NORMAL :
ad9510_regs_t::POWER_DOWN_LVPECL_OUT3_SAFE_PD;
_ad9510_regs.output_level_lvpecl_out3 = ad9510_regs_t::OUTPUT_LEVEL_LVPECL_OUT3_810MV;
+ _ad9510_regs.bypass_divider_out3 = 1;
this->write_reg(0x3F);
+ this->write_reg(0x4F);
this->update_regs();
}
@@ -139,7 +145,9 @@ private:
_ad9510_regs.power_down_lvds_cmos_out4 = enb? 0 : 1;
_ad9510_regs.lvds_cmos_select_out4 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT4_LVDS;
_ad9510_regs.output_level_lvds_out4 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT4_1_75MA;
+ _ad9510_regs.bypass_divider_out4 = 1;
this->write_reg(0x40);
+ this->write_reg(0x51);
this->update_regs();
}
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index 7c9d003ce..b6ab919e7 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -31,16 +31,15 @@ namespace asio = boost::asio;
* Helper Functions
**********************************************************************/
void usrp2_impl::io_init(void){
- //setup otw type
- _otw_type.width = 16;
- _otw_type.shift = 0;
- _otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN;
+ //setup rx otw type
+ _rx_otw_type.width = 16;
+ _rx_otw_type.shift = 0;
+ _rx_otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN;
- //initially empty copy buffer
- _rx_copy_buff = asio::buffer("", 0);
-
- //init the expected rx seq number
- _rx_stream_id_to_packet_seq[0] = 0;
+ //setup tx otw type
+ _tx_otw_type.width = 16;
+ _tx_otw_type.shift = 0;
+ _tx_otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN;
//send a small data packet so the usrp2 knows the udp source port
managed_send_buffer::sptr send_buff = _data_transport->get_send_buff();
@@ -49,7 +48,8 @@ void usrp2_impl::io_init(void){
send_buff->done(sizeof(data));
//setup RX DSP regs
- _iface->poke32(FR_RX_CTRL_NSAMPS_PER_PKT, _max_rx_samples_per_packet);
+ std::cout << "RX samples per packet: " << get_max_recv_samps_per_packet() << std::endl;
+ _iface->poke32(FR_RX_CTRL_NSAMPS_PER_PKT, get_max_recv_samps_per_packet());
_iface->poke32(FR_RX_CTRL_NCHANNELS, 1);
_iface->poke32(FR_RX_CTRL_CLEAR_OVERRUN, 1); //reset
_iface->poke32(FR_RX_CTRL_VRT_HEADER, 0
@@ -63,98 +63,22 @@ void usrp2_impl::io_init(void){
}
/***********************************************************************
- * Receive Raw Data
- **********************************************************************/
-void usrp2_impl::recv_raw(rx_metadata_t &metadata){
- //do a receive
- _rx_smart_buff = _data_transport->get_recv_buff();
-
- //unpack the vrt header
- size_t num_packet_words32 = _rx_smart_buff->size()/sizeof(boost::uint32_t);
- if (num_packet_words32 == 0){
- _rx_copy_buff = boost::asio::buffer("", 0);
- return; //must exit here after setting the buffer
- }
- const boost::uint32_t *vrt_hdr = _rx_smart_buff->cast<const boost::uint32_t *>();
- size_t num_header_words32_out, num_payload_words32_out, packet_count_out;
- try{
- vrt::unpack(
- metadata, //output
- vrt_hdr, //input
- num_header_words32_out, //output
- num_payload_words32_out, //output
- num_packet_words32, //input
- packet_count_out, //output
- get_master_clock_freq()
- );
- }catch(const std::exception &e){
- std::cerr << "bad vrt header: " << e.what() << std::endl;
- _rx_copy_buff = boost::asio::buffer("", 0);
- return; //must exit here after setting the buffer
- }
-
- //handle the packet count / sequence number
- size_t expected_packet_count = _rx_stream_id_to_packet_seq[metadata.stream_id];
- if (packet_count_out != expected_packet_count){
- std::cerr << "S" << (packet_count_out - expected_packet_count)%16;
- }
- _rx_stream_id_to_packet_seq[metadata.stream_id] = (packet_count_out+1)%16;
-
- //setup the rx buffer to point to the data
- _rx_copy_buff = asio::buffer(
- vrt_hdr + num_header_words32_out,
- num_payload_words32_out*sizeof(boost::uint32_t)
- );
-}
-
-/***********************************************************************
* Send Data
**********************************************************************/
size_t usrp2_impl::send(
const asio::const_buffer &buff,
- const tx_metadata_t &metadata_,
- const io_type_t &io_type
+ const tx_metadata_t &metadata,
+ const io_type_t &io_type,
+ send_mode_t send_mode
){
- tx_metadata_t metadata = metadata_; //rw copy to change later
-
- transport::managed_send_buffer::sptr send_buff = _data_transport->get_send_buff();
- boost::uint32_t *tx_mem = send_buff->cast<boost::uint32_t *>();
- size_t num_samps = std::min(std::min(
- asio::buffer_size(buff)/io_type.size,
- size_t(_max_tx_samples_per_packet)),
- send_buff->size()/io_type.size
+ return vrt_packet_handler::send(
+ _packet_handler_send_state, //last state of the send handler
+ buff, metadata, send_mode, //buffer to empty and samples metadata
+ io_type, _tx_otw_type, //input and output types to convert
+ get_master_clock_freq(), //master clock tick rate
+ _data_transport, //zero copy interface
+ get_max_send_samps_per_packet()
);
-
- //kill the end of burst flag if this is a fragment
- if (asio::buffer_size(buff)/io_type.size < num_samps)
- metadata.end_of_burst = false;
-
- size_t num_header_words32, num_packet_words32;
- size_t packet_count = _tx_stream_id_to_packet_seq[metadata.stream_id]++;
-
- //pack metadata into a vrt header
- vrt::pack(
- metadata, //input
- tx_mem, //output
- num_header_words32, //output
- num_samps, //input
- num_packet_words32, //output
- packet_count, //input
- get_master_clock_freq()
- );
-
- boost::uint32_t *items = tx_mem + num_header_words32; //offset for data
-
- //copy-convert the samples into the send buffer
- convert_io_type_to_otw_type(
- asio::buffer_cast<const void*>(buff), io_type,
- (void*)items, _otw_type,
- num_samps
- );
-
- //send and return number of samples
- send_buff->done(num_packet_words32*sizeof(boost::uint32_t));
- return num_samps;
}
/***********************************************************************
@@ -163,44 +87,14 @@ size_t usrp2_impl::send(
size_t usrp2_impl::recv(
const asio::mutable_buffer &buff,
rx_metadata_t &metadata,
- const io_type_t &io_type
+ const io_type_t &io_type,
+ recv_mode_t recv_mode
){
- //perform a receive if no rx data is waiting to be copied
- if (asio::buffer_size(_rx_copy_buff) == 0){
- _fragment_offset_in_samps = 0;
- recv_raw(metadata);
- }
- //otherwise flag the metadata to show that is is a fragment
- else{
- metadata = rx_metadata_t();
- }
-
- //extract the number of samples available to copy
- //and a pointer into the usrp2 received items memory
- size_t bytes_to_copy = asio::buffer_size(_rx_copy_buff);
- if (bytes_to_copy == 0) return 0; //nothing to receive
- size_t num_samps = std::min(
- asio::buffer_size(buff)/io_type.size,
- bytes_to_copy/sizeof(boost::uint32_t)
+ return vrt_packet_handler::recv(
+ _packet_handler_recv_state, //last state of the recv handler
+ buff, metadata, recv_mode, //buffer to fill and samples metadata
+ io_type, _rx_otw_type, //input and output types to convert
+ get_master_clock_freq(), //master clock tick rate
+ _data_transport //zero copy interface
);
- const boost::uint32_t *items = asio::buffer_cast<const boost::uint32_t*>(_rx_copy_buff);
-
- //setup the fragment flags and offset
- metadata.more_fragments = asio::buffer_size(buff)/io_type.size < num_samps;
- metadata.fragment_offset = _fragment_offset_in_samps;
- _fragment_offset_in_samps += num_samps; //set for next time
-
- //copy-convert the samples from the recv buffer
- convert_otw_type_to_io_type(
- (const void*)items, _otw_type,
- asio::buffer_cast<void*>(buff), io_type,
- num_samps
- );
-
- //update the rx copy buffer to reflect the bytes copied
- _rx_copy_buff = asio::buffer(
- items + num_samps, bytes_to_copy - num_samps*sizeof(boost::uint32_t)
- );
-
- return num_samps;
}
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index 9ae68d158..f17efd88e 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -111,7 +111,7 @@ void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){
//issue the stream command
_iface->poke32(FR_RX_CTRL_STREAM_CMD, FR_RX_CTRL_MAKE_CMD(
- (inst_samps)? stream_cmd.num_samps : ((inst_chain)? _max_rx_samples_per_packet : 1),
+ (inst_samps)? stream_cmd.num_samps : ((inst_chain)? get_max_recv_samps_per_packet() : 1),
(stream_cmd.stream_now)? 1 : 0,
(inst_chain)? 1 : 0,
(inst_reload)? 1 : 0
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index 2b7bdeea2..af3ec216a 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -210,14 +210,6 @@ void usrp2_impl::get(const wax::obj &key_, wax::obj &val){
val = prop_names_t(1, "");
return;
- case DEVICE_PROP_MAX_RX_SAMPLES:
- val = size_t(_max_rx_samples_per_packet);
- return;
-
- case DEVICE_PROP_MAX_TX_SAMPLES:
- val = size_t(_max_tx_samples_per_packet);
- return;
-
default: UHD_THROW_PROP_GET_ERROR();
}
}
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index c5b6af810..afea9683c 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -33,6 +33,7 @@
#include <uhd/transport/vrt.hpp>
#include <uhd/transport/udp_zero_copy.hpp>
#include <uhd/usrp/dboard_manager.hpp>
+#include "../../transport/vrt_packet_handler.hpp"
/*!
* Make a usrp2 dboard interface.
@@ -103,8 +104,24 @@ public:
~usrp2_impl(void);
//the io interface
- size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const uhd::io_type_t &);
- size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const uhd::io_type_t &);
+ size_t get_max_send_samps_per_packet(void) const{
+ return _max_tx_bytes_per_packet/_tx_otw_type.get_sample_size();
+ }
+ size_t send(
+ const boost::asio::const_buffer &,
+ const uhd::tx_metadata_t &,
+ const uhd::io_type_t &,
+ uhd::device::send_mode_t
+ );
+ size_t get_max_recv_samps_per_packet(void) const{
+ return _max_rx_bytes_per_packet/_rx_otw_type.get_sample_size();
+ }
+ size_t recv(
+ const boost::asio::mutable_buffer &,
+ uhd::rx_metadata_t &,
+ const uhd::io_type_t &,
+ uhd::device::recv_mode_t
+ );
private:
double get_master_clock_freq(void){
@@ -121,25 +138,24 @@ private:
codec_ctrl::sptr _codec_ctrl;
serdes_ctrl::sptr _serdes_ctrl;
- //the raw io interface (samples are in the usrp2 native format)
- void recv_raw(uhd::rx_metadata_t &);
- uhd::dict<boost::uint32_t, size_t> _tx_stream_id_to_packet_seq;
- uhd::dict<boost::uint32_t, size_t> _rx_stream_id_to_packet_seq;
+ /*******************************************************************
+ * Deal with the rx and tx packet sizes
+ ******************************************************************/
static const size_t _mtu = 1500; //FIXME we have no idea
static const size_t _hdrs = (2 + 14 + 20 + 8); //size of headers (pad, eth, ip, udp)
- static const size_t _max_rx_samples_per_packet =
- (_mtu - _hdrs)/sizeof(boost::uint32_t) -
- USRP2_HOST_RX_VRT_HEADER_WORDS32 -
- USRP2_HOST_RX_VRT_TRAILER_WORDS32
+ static const size_t _max_rx_bytes_per_packet =
+ _mtu - _hdrs -
+ USRP2_HOST_RX_VRT_HEADER_WORDS32*sizeof(boost::uint32_t) -
+ USRP2_HOST_RX_VRT_TRAILER_WORDS32*sizeof(boost::uint32_t)
;
- static const size_t _max_tx_samples_per_packet =
- (_mtu - _hdrs)/sizeof(boost::uint32_t) -
- uhd::transport::vrt::max_header_words32
+ static const size_t _max_tx_bytes_per_packet =
+ _mtu - _hdrs -
+ uhd::transport::vrt::max_header_words32*sizeof(boost::uint32_t)
;
- uhd::transport::managed_recv_buffer::sptr _rx_smart_buff;
- boost::asio::const_buffer _rx_copy_buff;
- size_t _fragment_offset_in_samps;
- uhd::otw_type_t _otw_type;
+
+ vrt_packet_handler::recv_state _packet_handler_recv_state;
+ vrt_packet_handler::send_state _packet_handler_send_state;
+ uhd::otw_type_t _rx_otw_type, _tx_otw_type;
void io_init(void);
//udp transports for control and data