diff options
Diffstat (limited to 'host/lib/usrp')
-rw-r--r-- | host/lib/usrp/usrp2/clock_ctrl.cpp | 8 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/io_impl.cpp | 162 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 2 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 8 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.hpp | 50 |
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 |