From 905f5b3b249a60401e181856ac6b3f2cae88d166 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 30 Jun 2010 16:21:46 -0700 Subject: usrp2: split mboard impl into its own class, usrp2 device can instantiate N mboard impls for mimo setup (works with 1 for now) --- host/lib/usrp/usrp2/mboard_impl.cpp | 78 +++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 12 deletions(-) (limited to 'host/lib/usrp/usrp2/mboard_impl.cpp') diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 2c900b328..903d5da86 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -29,17 +29,71 @@ using namespace uhd; using namespace uhd::usrp; +/*********************************************************************** + * Structors + **********************************************************************/ +usrp2_mboard_impl::usrp2_mboard_impl( + size_t index, transport::udp_simple::sptr ctrl_transport +): + _index(index) +{ + //make a new interface for usrp2 stuff + _iface = usrp2_iface::make(ctrl_transport); + _clock_ctrl = usrp2_clock_ctrl::make(_iface); + _codec_ctrl = usrp2_codec_ctrl::make(_iface); + _serdes_ctrl = usrp2_serdes_ctrl::make(_iface); + + //TODO move to dsp impl... + //load the allowed decim/interp rates + //_USRP2_RATES = range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4) + _allowed_decim_and_interp_rates.clear(); + for (size_t i = 4; i <= 128; i+=1){ + _allowed_decim_and_interp_rates.push_back(i); + } + for (size_t i = 130; i <= 256; i+=2){ + _allowed_decim_and_interp_rates.push_back(i); + } + for (size_t i = 260; i <= 512; i+=4){ + _allowed_decim_and_interp_rates.push_back(i); + } + + //init the ddc + init_ddc_config(); + + //init the duc + init_duc_config(); + + //initialize the clock configuration + init_clock_config(); + + //init the tx and rx dboards (do last) + dboard_init(); +} + +usrp2_mboard_impl::~usrp2_mboard_impl(void){ + /* NOP */ +} + /*********************************************************************** * Helper Methods **********************************************************************/ -void usrp2_impl::mboard_init(void){ - _mboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp2_impl::mboard_get, this, _1, _2), - boost::bind(&usrp2_impl::mboard_set, this, _1, _2) +void usrp2_mboard_impl::setup_vrt_recv_regs(size_t num_samps){ + _max_recv_samps_per_packet = num_samps; + + _iface->poke32(U2_REG_RX_CTRL_NSAMPS_PER_PKT, _max_recv_samps_per_packet); + _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 + | (0x1 << 28) //if data with stream id + | (0x1 << 26) //has trailer + | (0x3 << 22) //integer time other + | (0x1 << 20) //fractional time sample count ); + _iface->poke32(U2_REG_RX_CTRL_VRT_STREAM_ID, 0); + _iface->poke32(U2_REG_RX_CTRL_VRT_TRAILER, 0); } -void usrp2_impl::init_clock_config(void){ +void usrp2_mboard_impl::init_clock_config(void){ //setup the clock configuration settings _clock_config.ref_source = clock_config_t::REF_INT; _clock_config.pps_source = clock_config_t::PPS_SMA; @@ -49,7 +103,7 @@ void usrp2_impl::init_clock_config(void){ update_clock_config(); } -void usrp2_impl::update_clock_config(void){ +void usrp2_mboard_impl::update_clock_config(void){ boost::uint32_t pps_flags = 0; //translate pps source enums @@ -82,7 +136,7 @@ void usrp2_impl::update_clock_config(void){ _clock_ctrl->enable_external_ref(use_external); } -void usrp2_impl::set_time_spec(const time_spec_t &time_spec, bool now){ +void usrp2_mboard_impl::set_time_spec(const time_spec_t &time_spec, bool now){ //set the ticks _iface->poke32(U2_REG_TIME64_TICKS, time_spec.get_tick_count(get_master_clock_freq())); @@ -94,7 +148,7 @@ void usrp2_impl::set_time_spec(const time_spec_t &time_spec, bool now){ _iface->poke32(U2_REG_TIME64_SECS, boost::uint32_t(time_spec.get_full_secs())); } -void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ +void usrp2_mboard_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ UHD_ASSERT_THROW(stream_cmd.num_samps <= U2_REG_RX_CTRL_MAX_SAMPS_PER_CMD); //setup the mode to instruction flags @@ -113,7 +167,7 @@ void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ //issue the stream command _iface->poke32(U2_REG_RX_CTRL_STREAM_CMD, U2_REG_RX_CTRL_MAKE_CMD( - (inst_samps)? stream_cmd.num_samps : ((inst_chain)? get_max_recv_samps_per_packet() : 1), + (inst_samps)? stream_cmd.num_samps : ((inst_chain)? _max_recv_samps_per_packet : 1), (stream_cmd.stream_now)? 1 : 0, (inst_chain)? 1 : 0, (inst_reload)? 1 : 0 @@ -125,7 +179,7 @@ void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ /*********************************************************************** * MBoard Get Properties **********************************************************************/ -void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ +void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){ wax::obj key; std::string name; boost::tie(key, name) = extract_named_prop(key_); @@ -148,7 +202,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ //handle the get request conditioned on the key switch(key.as()){ case MBOARD_PROP_NAME: - val = std::string("usrp2 mboard"); + val = str(boost::format("usrp2 mboard %d") % _index); return; case MBOARD_PROP_OTHERS:{ @@ -207,7 +261,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * MBoard Set Properties **********************************************************************/ -void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){ +void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){ //handle the other props if (key.type() == typeid(std::string)){ if (key.as() == "mac-addr"){ -- cgit v1.2.3 From 158bf440d2884b981a86121990be16decedaa733 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 30 Jun 2010 17:34:35 -0700 Subject: usrp2: moved calculations for max packet size and otw types into shared object between device and mboards --- host/lib/usrp/usrp2/io_impl.cpp | 35 +++++---------- host/lib/usrp/usrp2/mboard_impl.cpp | 38 ++++++++-------- host/lib/usrp/usrp2/usrp2_impl.cpp | 2 +- host/lib/usrp/usrp2/usrp2_impl.hpp | 86 +++++++++++++++++++++++++------------ 4 files changed, 88 insertions(+), 73 deletions(-) (limited to 'host/lib/usrp/usrp2/mboard_impl.cpp') diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 8b1864e2d..0c92c33b2 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -95,16 +95,6 @@ void usrp2_impl::io_impl::recv_pirate_loop(zero_copy_if::sptr zc_if, size_t inde * Helper Functions **********************************************************************/ void usrp2_impl::io_init(void){ - //setup rx otw type - _rx_otw_type.width = 16; - _rx_otw_type.shift = 0; - _rx_otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN; - - //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 for(size_t i = 0; i < _data_transports.size(); i++){ managed_send_buffer::sptr send_buff = _data_transports[i]->get_send_buff(); @@ -113,11 +103,6 @@ void usrp2_impl::io_init(void){ send_buff->commit(sizeof(data)); } - //setup VRT RX DSP regs - for(size_t i = 0; i < _mboards.size(); i++){ - _mboards[i]->setup_vrt_recv_regs(get_max_recv_samps_per_packet()); - } - std::cout << "RX samples per packet: " << get_max_recv_samps_per_packet() << std::endl; std::cout << "TX samples per packet: " << get_max_send_samps_per_packet() << std::endl; @@ -147,11 +132,11 @@ size_t usrp2_impl::send( send_mode_t send_mode ){ return vrt_packet_handler::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, _tx_otw_type, //input and output types to convert - get_master_clock_freq(), //master clock tick rate + _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 + _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), get_max_send_samps_per_packet() @@ -169,11 +154,11 @@ size_t usrp2_impl::recv( recv_mode_t recv_mode ){ return vrt_packet_handler::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, _rx_otw_type, //input and output types to convert - get_master_clock_freq(), //master clock tick rate + _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 + _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, _1) ); diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 903d5da86..28a346be7 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -33,9 +33,12 @@ using namespace uhd::usrp; * Structors **********************************************************************/ usrp2_mboard_impl::usrp2_mboard_impl( - size_t index, transport::udp_simple::sptr ctrl_transport + size_t index, + transport::udp_simple::sptr ctrl_transport, + const usrp2_io_helper &io_helper ): - _index(index) + _index(index), + _io_helper(io_helper) { //make a new interface for usrp2 stuff _iface = usrp2_iface::make(ctrl_transport); @@ -57,6 +60,19 @@ usrp2_mboard_impl::usrp2_mboard_impl( _allowed_decim_and_interp_rates.push_back(i); } + //setup the vrt rx registers + _iface->poke32(U2_REG_RX_CTRL_NSAMPS_PER_PKT, _io_helper.get_max_recv_samps_per_packet()); + _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 + | (0x1 << 28) //if data with stream id + | (0x1 << 26) //has trailer + | (0x3 << 22) //integer time other + | (0x1 << 20) //fractional time sample count + ); + _iface->poke32(U2_REG_RX_CTRL_VRT_STREAM_ID, 0); + _iface->poke32(U2_REG_RX_CTRL_VRT_TRAILER, 0); + //init the ddc init_ddc_config(); @@ -77,22 +93,6 @@ usrp2_mboard_impl::~usrp2_mboard_impl(void){ /*********************************************************************** * Helper Methods **********************************************************************/ -void usrp2_mboard_impl::setup_vrt_recv_regs(size_t num_samps){ - _max_recv_samps_per_packet = num_samps; - - _iface->poke32(U2_REG_RX_CTRL_NSAMPS_PER_PKT, _max_recv_samps_per_packet); - _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 - | (0x1 << 28) //if data with stream id - | (0x1 << 26) //has trailer - | (0x3 << 22) //integer time other - | (0x1 << 20) //fractional time sample count - ); - _iface->poke32(U2_REG_RX_CTRL_VRT_STREAM_ID, 0); - _iface->poke32(U2_REG_RX_CTRL_VRT_TRAILER, 0); -} - void usrp2_mboard_impl::init_clock_config(void){ //setup the clock configuration settings _clock_config.ref_source = clock_config_t::REF_INT; @@ -167,7 +167,7 @@ void usrp2_mboard_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ //issue the stream command _iface->poke32(U2_REG_RX_CTRL_STREAM_CMD, U2_REG_RX_CTRL_MAKE_CMD( - (inst_samps)? stream_cmd.num_samps : ((inst_chain)? _max_recv_samps_per_packet : 1), + (inst_samps)? stream_cmd.num_samps : ((inst_chain)? _io_helper.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 af496bf69..436146a48 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -173,7 +173,7 @@ usrp2_impl::usrp2_impl( //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]) + new usrp2_mboard_impl(i, ctrl_transports[i], _io_helper) )); //use an empty name when there is only one mboard std::string name = (ctrl_transports.size() > 1)? boost::lexical_cast(i) : ""; diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index ccda5e3d8..719cf3f16 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -69,6 +69,55 @@ private: void set(const wax::obj &key, const wax::obj &val){return _set(key, val);} }; +/*! + * 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 = + USRP2_UDP_BYTES - + 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_bytes_per_packet = + USRP2_UDP_BYTES - + 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. @@ -79,23 +128,21 @@ public: typedef boost::shared_ptr sptr; //structors - usrp2_mboard_impl(size_t index, uhd::transport::udp_simple::sptr); + usrp2_mboard_impl(size_t index, uhd::transport::udp_simple::sptr, const usrp2_io_helper &); ~usrp2_mboard_impl(void); - void setup_vrt_recv_regs(size_t num_samps); - inline double get_master_clock_freq(void){ return _clock_ctrl->get_master_clock_rate(); } +private: + size_t _index; + const usrp2_io_helper &_io_helper; + //properties for this mboard void get(const wax::obj &, wax::obj &); void set(const wax::obj &, const wax::obj &); -private: - size_t _index; - size_t _max_recv_samps_per_packet; - //interfaces usrp2_iface::sptr _iface; usrp2_clock_ctrl::sptr _clock_ctrl; @@ -172,7 +219,7 @@ public: //the io interface size_t get_max_send_samps_per_packet(void) const{ - return _max_tx_bytes_per_packet/_tx_otw_type.get_sample_size(); + return _io_helper.get_max_send_samps_per_packet(); } size_t send( const std::vector &, size_t, @@ -181,7 +228,7 @@ public: 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(); + return _io_helper.get_max_recv_samps_per_packet(); } size_t recv( const std::vector &, size_t, @@ -191,10 +238,6 @@ public: ); private: - inline double get_master_clock_freq(void){ - return _mboards.front()->get_master_clock_freq(); - } - //device properties interface void get(const wax::obj &, wax::obj &); void set(const wax::obj &, const wax::obj &); @@ -203,22 +246,9 @@ private: std::vector _mboards; uhd::dict _mboard_dict; - /******************************************************************* - * Deal with the rx and tx packet sizes - ******************************************************************/ - static const size_t _max_rx_bytes_per_packet = - USRP2_UDP_BYTES - - 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_bytes_per_packet = - USRP2_UDP_BYTES - - 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 - ; - + //io impl methods and members std::vector _data_transports; - uhd::otw_type_t _rx_otw_type, _tx_otw_type; + const usrp2_io_helper _io_helper; UHD_PIMPL_DECL(io_impl) _io_impl; void io_init(void); }; -- cgit v1.2.3 From 5e14653f241070791d46893e68e341357e040add Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sun, 4 Jul 2010 19:13:59 -0700 Subject: usrp2: bug fix for readback registers added readback for time64 fixed bug for fragment flag in vrt packet handler --- host/include/uhd/transport/zero_copy.hpp | 8 ++++---- host/include/uhd/usrp/mboard_props.hpp | 2 +- host/lib/transport/vrt_packet_handler.hpp | 18 +++++++++--------- host/lib/usrp/usrp2/fw_common.h | 2 +- host/lib/usrp/usrp2/mboard_impl.cpp | 10 ++++++++++ host/lib/usrp/usrp2/usrp2_regs.hpp | 10 ++++++---- 6 files changed, 31 insertions(+), 19 deletions(-) (limited to 'host/lib/usrp/usrp2/mboard_impl.cpp') diff --git a/host/include/uhd/transport/zero_copy.hpp b/host/include/uhd/transport/zero_copy.hpp index 2815e3189..da10bfbe2 100644 --- a/host/include/uhd/transport/zero_copy.hpp +++ b/host/include/uhd/transport/zero_copy.hpp @@ -47,7 +47,7 @@ namespace uhd{ namespace transport{ * Get the size of the underlying buffer. * \return the number of bytes */ - size_t size(void) const{ + inline size_t size(void) const{ return boost::asio::buffer_size(this->get()); } @@ -55,7 +55,7 @@ namespace uhd{ namespace transport{ * Get a pointer to the underlying buffer. * \return a pointer into memory */ - template T cast(void) const{ + template inline T cast(void) const{ return boost::asio::buffer_cast(this->get()); } @@ -89,7 +89,7 @@ namespace uhd{ namespace transport{ * Get the size of the underlying buffer. * \return the number of bytes */ - size_t size(void) const{ + inline size_t size(void) const{ return boost::asio::buffer_size(this->get()); } @@ -97,7 +97,7 @@ namespace uhd{ namespace transport{ * Get a pointer to the underlying buffer. * \return a pointer into memory */ - template T cast(void) const{ + template inline T cast(void) const{ return boost::asio::buffer_cast(this->get()); } diff --git a/host/include/uhd/usrp/mboard_props.hpp b/host/include/uhd/usrp/mboard_props.hpp index 7ff454472..a432ce50c 100644 --- a/host/include/uhd/usrp/mboard_props.hpp +++ b/host/include/uhd/usrp/mboard_props.hpp @@ -40,7 +40,7 @@ namespace uhd{ namespace usrp{ MBOARD_PROP_TX_DBOARD = 'v', //ro, wax::obj MBOARD_PROP_TX_DBOARD_NAMES = 'V', //ro, prop_names_t MBOARD_PROP_CLOCK_CONFIG = 'C', //rw, clock_config_t - MBOARD_PROP_TIME_NOW = 't', //wo, time_spec_t + MBOARD_PROP_TIME_NOW = 't', //rw, time_spec_t MBOARD_PROP_TIME_NEXT_PPS = 'T', //wo, time_spec_t MBOARD_PROP_STREAM_CMD = 's' //wo, stream_cmd_t }; diff --git a/host/lib/transport/vrt_packet_handler.hpp b/host/lib/transport/vrt_packet_handler.hpp index 42cbb7e5a..177239509 100644 --- a/host/lib/transport/vrt_packet_handler.hpp +++ b/host/lib/transport/vrt_packet_handler.hpp @@ -151,20 +151,15 @@ namespace vrt_packet_handler{ //extract the number of samples available to copy size_t bytes_per_item = otw_type.get_sample_size(); size_t bytes_available = state.size_of_copy_buffs; - size_t num_samps = std::min(total_samps, bytes_available/bytes_per_item); - size_t bytes_to_copy = num_samps*bytes_per_item; - - //setup the fragment flags and offset - metadata.more_fragments = total_samps < num_samps; - metadata.fragment_offset = state.fragment_offset_in_samps; - state.fragment_offset_in_samps += num_samps; //set for next call + size_t nsamps_to_copy = std::min(total_samps, bytes_available/bytes_per_item); + size_t bytes_to_copy = nsamps_to_copy*bytes_per_item; for (size_t i = 0; i < state.width; i++){ //copy-convert the samples from the recv buffer uhd::transport::convert_otw_type_to_io_type( state.copy_buffs[i], otw_type, reinterpret_cast(buffs[i]) + offset_bytes, - io_type, num_samps + io_type, nsamps_to_copy ); //update the rx copy buffer to reflect the bytes copied @@ -173,7 +168,12 @@ namespace vrt_packet_handler{ //update the copy buffer's availability state.size_of_copy_buffs -= bytes_to_copy; - return num_samps; + //setup the fragment flags and offset + metadata.more_fragments = state.size_of_copy_buffs != 0; + metadata.fragment_offset = state.fragment_offset_in_samps; + state.fragment_offset_in_samps += nsamps_to_copy; //set for next call + + return nsamps_to_copy; } /******************************************************************* diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index 242d268ec..12daa6286 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -38,7 +38,7 @@ extern "C" { //defines the protocol version in this shared header //increment this value when the protocol is changed -#define USRP2_PROTO_VERSION 4 +#define USRP2_PROTO_VERSION 5 //used to differentiate control packets over data port #define USRP2_INVALID_VRT_HEADER 0 diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 28a346be7..36ac6275f 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -25,6 +25,7 @@ #include #include #include +#include using namespace uhd; using namespace uhd::usrp; @@ -72,6 +73,7 @@ usrp2_mboard_impl::usrp2_mboard_impl( ); _iface->poke32(U2_REG_RX_CTRL_VRT_STREAM_ID, 0); _iface->poke32(U2_REG_RX_CTRL_VRT_TRAILER, 0); + _iface->poke32(U2_REG_TIME64_TPS, size_t(get_master_clock_freq())); //init the ddc init_ddc_config(); @@ -254,6 +256,14 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){ val = _clock_config; return; + case MBOARD_PROP_TIME_NOW: + val = time_spec_t( + _iface->peek32(U2_REG_TIME64_SECS_RB), + _iface->peek32(U2_REG_TIME64_TICKS_RB), + get_master_clock_freq() + ); + return; + default: UHD_THROW_PROP_GET_ERROR(); } } diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index 589fa71a3..c859d3603 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.hpp @@ -18,8 +18,6 @@ #ifndef INCLUDED_USRP2_REGS_HPP #define INCLUDED_USRP2_REGS_HPP -#include - //////////////////////////////////////////////////// // Settings Bus, Slave #7, Not Byte Addressable! // @@ -46,7 +44,7 @@ #define SR_SIMTIMER 198 #define SR_LAST 255 -#define _SR_ADDR(sr) (MISC_OUTPUT_BASE + (sr) * sizeof(boost::uint32_t)) +#define _SR_ADDR(sr) ((MISC_OUTPUT_BASE) + (4*(sr))) ///////////////////////////////////////////////// // SPI Slave Constants @@ -104,7 +102,11 @@ #define U2_REG_TIME64_SECS _SR_ADDR(SR_TIME64 + 0) // value to set absolute secs to on next PPS #define U2_REG_TIME64_TICKS _SR_ADDR(SR_TIME64 + 1) // value to set absolute ticks to on next PPS #define U2_REG_TIME64_FLAGS _SR_ADDR(SR_TIME64 + 2) // flags - see chart above -#define U2_REG_TIME64_IMM _SR_ADDR(SR_TIME64 + 3) // set immediate (0=latch on next pps, 1=latch immediate, default=0) +#define U2_REG_TIME64_IMM _SR_ADDR(SR_TIME64 + 3) // set immediate (0=latch on next pps, 1=latch immediate, default=0) +#define U2_REG_TIME64_TPS _SR_ADDR(SR_TIME64 + 4) // the ticks per second rollover count + +#define U2_REG_TIME64_SECS_RB (0xCC00 + 4*10) +#define U2_REG_TIME64_TICKS_RB (0xCC00 + 4*11) //pps flags (see above) #define U2_FLAG_TIME64_PPS_NEGEDGE (0 << 0) -- cgit v1.2.3 From a95eaac42f6cc85fd2ad3f32dc29eeab38ef5194 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 5 Jul 2010 19:12:01 -0700 Subject: usrp2: Added a peek64 to read pairs of 32 bit numbers such as time64 also added a templated host to/from network conversion in byteswap.hpp (didnt use it though) --- firmware/microblaze/apps/txrx_uhd.c | 8 ++++++++ host/include/uhd/utils/byteswap.hpp | 27 +++++++++++++++++++++++++++ host/lib/usrp/usrp2/fw_common.h | 4 +++- host/lib/usrp/usrp2/mboard_impl.cpp | 14 ++++++++------ host/lib/usrp/usrp2/usrp2_iface.cpp | 24 +++++++++++++++++++----- host/lib/usrp/usrp2/usrp2_iface.hpp | 10 ++++++++++ 6 files changed, 75 insertions(+), 12 deletions(-) (limited to 'host/lib/usrp/usrp2/mboard_impl.cpp') diff --git a/firmware/microblaze/apps/txrx_uhd.c b/firmware/microblaze/apps/txrx_uhd.c index 21803b199..99c149d45 100644 --- a/firmware/microblaze/apps/txrx_uhd.c +++ b/firmware/microblaze/apps/txrx_uhd.c @@ -269,6 +269,10 @@ void handle_udp_ctrl_packet( printf("error! tried to poke into 0x%x\n", ctrl_data_in->data.poke_args.addr); } else switch(ctrl_data_in->data.poke_args.num_bytes){ + case sizeof(uint64_t): + *((uint32_t *) ctrl_data_in->data.poke_args.addrhi) = (uint32_t)ctrl_data_in->data.poke_args.datahi; + //continue to uint32_t for low addr: + case sizeof(uint32_t): *((uint32_t *) ctrl_data_in->data.poke_args.addr) = (uint32_t)ctrl_data_in->data.poke_args.data; break; @@ -287,6 +291,10 @@ void handle_udp_ctrl_packet( case USRP2_CTRL_ID_PEEK_AT_THIS_REGISTER_FOR_ME_BRO: switch(ctrl_data_in->data.poke_args.num_bytes){ + case sizeof(uint64_t): + ctrl_data_out.data.poke_args.datahi = *((uint32_t *) ctrl_data_in->data.poke_args.addrhi); + //continue to uint32_t for low addr: + case sizeof(uint32_t): ctrl_data_out.data.poke_args.data = *((uint32_t *) ctrl_data_in->data.poke_args.addr); break; diff --git a/host/include/uhd/utils/byteswap.hpp b/host/include/uhd/utils/byteswap.hpp index dd5dcbc09..26d60c2ab 100644 --- a/host/include/uhd/utils/byteswap.hpp +++ b/host/include/uhd/utils/byteswap.hpp @@ -37,6 +37,12 @@ namespace uhd{ //! perform a byteswap on a 64 bit integer boost::uint64_t byteswap(boost::uint64_t); + //! network to host: short, long, or long-long + template T ntohx(T); + + //! host to network: short, long, or long-long + template T htonx(T); + } //namespace uhd /*********************************************************************** @@ -117,4 +123,25 @@ namespace uhd{ #endif +/*********************************************************************** + * Define the templated network to/from host conversions + **********************************************************************/ +#include + +template UHD_INLINE T uhd::ntohx(T num){ + #ifdef BOOST_BIG_ENDIAN + return num; + #else + return uhd::byteswap(num); + #endif +} + +template UHD_INLINE T uhd::htonx(T num){ + #ifdef BOOST_BIG_ENDIAN + return num; + #else + return uhd::byteswap(num); + #endif +} + #endif /* INCLUDED_UHD_UTILS_BYTESWAP_HPP */ diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index 12daa6286..4c66aa41e 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -111,7 +111,9 @@ typedef struct{ struct { _SINS_ uint32_t addr; _SINS_ uint32_t data; - _SINS_ uint8_t num_bytes; //1, 2, 4 + _SINS_ uint32_t addrhi; + _SINS_ uint32_t datahi; + _SINS_ uint8_t num_bytes; //1, 2, 4, 8 } poke_args; } data; } usrp2_ctrl_data_t; diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 36ac6275f..952954286 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -256,12 +256,14 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){ val = _clock_config; return; - case MBOARD_PROP_TIME_NOW: - val = time_spec_t( - _iface->peek32(U2_REG_TIME64_SECS_RB), - _iface->peek32(U2_REG_TIME64_TICKS_RB), - get_master_clock_freq() - ); + case MBOARD_PROP_TIME_NOW:{ + usrp2_iface::pair64 time64( + _iface->peek64(U2_REG_TIME64_SECS_RB, U2_REG_TIME64_TICKS_RB) + ); + val = time_spec_t( + time64.first, time64.second, get_master_clock_freq() + ); + } return; default: UHD_THROW_PROP_GET_ERROR(); diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index 66a1a57f6..faf4a5c7e 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -59,6 +59,20 @@ public: return this->peek(addr); } + pair64 peek64(boost::uint32_t addrlo, boost::uint32_t addrhi){ + //setup the out data + usrp2_ctrl_data_t out_data; + out_data.id = htonl(USRP2_CTRL_ID_PEEK_AT_THIS_REGISTER_FOR_ME_BRO); + out_data.data.poke_args.addr = htonl(addrlo); + out_data.data.poke_args.addrhi = htonl(addrhi); + out_data.data.poke_args.num_bytes = sizeof(boost::uint64_t); + + //send and recv + usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data); + UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_WOAH_I_DEFINITELY_PEEKED_IT_DUDE); + return pair64(ntohl(in_data.data.poke_args.data), ntohl(in_data.data.poke_args.datahi)); + } + /*********************************************************************** * SPI **********************************************************************/ @@ -86,7 +100,7 @@ public: //send and recv usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data); - UHD_ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE); + UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE); return ntohl(in_data.data.spi_args.data); } @@ -109,7 +123,7 @@ public: //send and recv usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data); - UHD_ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE); + UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE); } byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes){ @@ -124,7 +138,7 @@ public: //send and recv usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data); - UHD_ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE); + UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE); UHD_ASSERT_THROW(in_data.data.i2c_args.addr = num_bytes); //copy out the data @@ -187,7 +201,7 @@ private: //send and recv usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data); - UHD_ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_OMG_POKED_REGISTER_SO_BAD_DUDE); + UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_OMG_POKED_REGISTER_SO_BAD_DUDE); } template T peek(boost::uint32_t addr){ @@ -199,7 +213,7 @@ private: //send and recv usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data); - UHD_ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_WOAH_I_DEFINITELY_PEEKED_IT_DUDE); + UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_WOAH_I_DEFINITELY_PEEKED_IT_DUDE); return T(ntohl(in_data.data.poke_args.data)); } diff --git a/host/lib/usrp/usrp2/usrp2_iface.hpp b/host/lib/usrp/usrp2/usrp2_iface.hpp index 7b2a3a89d..9cc32104e 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.hpp +++ b/host/lib/usrp/usrp2/usrp2_iface.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "fw_common.h" //////////////////////////////////////////////////////////////////////// @@ -49,6 +50,7 @@ class usrp2_iface : public uhd::i2c_iface, boost::noncopyable{ public: typedef boost::shared_ptr sptr; + typedef std::pair pair64; /*! * Make a new usrp2 interface with the control transport. @@ -64,6 +66,14 @@ public: */ virtual usrp2_ctrl_data_t ctrl_send_and_recv(const usrp2_ctrl_data_t &data) = 0; + /*! + * Read a dual register (64 bits) + * \param addrlo the address for the low-32 bits + * \param addrhi the address for the high-32 bits + * \return a pair of 32 bit integers lo, hi + */ + virtual pair64 peek64(boost::uint32_t addrlo, boost::uint32_t addrhi) = 0; + /*! * Write a register (32 bits) * \param addr the address -- cgit v1.2.3