From 8442ea5e2cfec89db6e58736a969da2842734631 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 9 Feb 2012 19:02:43 -0800 Subject: b100/usrp1: various tweaks for compiler warns and valgrind --- host/lib/usrp/common/fx2_ctrl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host/lib/usrp/common') diff --git a/host/lib/usrp/common/fx2_ctrl.cpp b/host/lib/usrp/common/fx2_ctrl.cpp index 3c6df7079..baf8f5e68 100644 --- a/host/lib/usrp/common/fx2_ctrl.cpp +++ b/host/lib/usrp/common/fx2_ctrl.cpp @@ -419,7 +419,7 @@ public: { UHD_ASSERT_THROW(bytes.size() < max_i2c_data_bytes); - unsigned char buff[max_i2c_data_bytes]; + unsigned char buff[max_i2c_data_bytes] = {}; std::copy(bytes.begin(), bytes.end(), buff); int ret = this->usrp_i2c_write(addr & 0xff, @@ -434,7 +434,7 @@ public: { UHD_ASSERT_THROW(num_bytes < max_i2c_data_bytes); - unsigned char buff[max_i2c_data_bytes]; + unsigned char buff[max_i2c_data_bytes] = {}; int ret = this->usrp_i2c_read(addr & 0xff, buff, num_bytes); -- cgit v1.2.3 From 8bd255c5f6ed586603727ffaa56d1eeb325458af Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 14 Feb 2012 12:03:52 -0800 Subject: b100: added transport flushes and moved around reset code --- host/lib/usrp/b100/b100_impl.cpp | 15 ++++----------- host/lib/usrp/b100/b100_impl.hpp | 2 -- host/lib/usrp/common/fx2_ctrl.hpp | 3 +++ 3 files changed, 7 insertions(+), 13 deletions(-) (limited to 'host/lib/usrp/common') diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index 4c9f93249..af10590ac 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -181,9 +181,9 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ //load FPGA image, gpif is disabled while loading this->enable_gpif(false); _fx2_ctrl->usrp_load_fpga(b100_fpga_image); + _fx2_ctrl->usrp_fpga_reset(false); //active low reset + _fx2_ctrl->usrp_fpga_reset(true); this->enable_gpif(true); - this->set_reset_fpga(1); - this->set_reset_fpga(0); //create the control transport device_addr_t ctrl_xport_args; @@ -198,12 +198,12 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ 3, 4, //interface, endpoint ctrl_xport_args ); + while (_ctrl_transport->get_recv_buff(0.0)){} //flush ctrl xport //////////////////////////////////////////////////////////////////// // Initialize FPGA wishbone communication //////////////////////////////////////////////////////////////////// _fpga_ctrl = b100_ctrl::make(_ctrl_transport); - this->reset_gpif(6); //always reset first to ensure communication _fpga_ctrl->poke32(B100_REG_GLOBAL_RESET, 0); //global fpga reset this->check_fpga_compat(); //check after reset and making control @@ -234,6 +234,7 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ ), B100_MAX_PKT_BYTE_LIMIT ); + while (_data_transport->get_recv_buff(0.0)){} //flush data xport //////////////////////////////////////////////////////////////////// // Initialize the properties tree @@ -515,10 +516,6 @@ void b100_impl::update_clock_source(const std::string &source){ } ////////////////// some GPIF preparation related stuff ///////////////// -void b100_impl::reset_gpif(const boost::uint16_t ep) { - _fx2_ctrl->usrp_control_write(VRQ_RESET_GPIF, ep, ep, 0, 0); -} - void b100_impl::enable_gpif(const bool en) { _fx2_ctrl->usrp_control_write(VRQ_ENABLE_GPIF, en ? 1 : 0, 0, 0, 0); } @@ -527,10 +524,6 @@ void b100_impl::clear_fpga_fifo(void) { _fx2_ctrl->usrp_control_write(VRQ_CLEAR_FPGA_FIFO, 0, 0, 0, 0); } -void b100_impl::set_reset_fpga(const bool en) { - _fx2_ctrl->usrp_control_write(VRQ_FPGA_SET_RESET, en ? 0 : 1, 0, 0, 0); -} - sensor_value_t b100_impl::get_ref_locked(void){ const bool lock = _clock_ctrl->get_locked(); return sensor_value_t("Ref", lock, "locked", "unlocked"); diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp index b71b65562..eab9c750b 100644 --- a/host/lib/usrp/b100/b100_impl.hpp +++ b/host/lib/usrp/b100/b100_impl.hpp @@ -123,10 +123,8 @@ private: void update_rx_subdev_spec(const uhd::usrp::subdev_spec_t &); void update_tx_subdev_spec(const uhd::usrp::subdev_spec_t &); void update_clock_source(const std::string &); - void reset_gpif(const boost::uint16_t); void enable_gpif(const bool); void clear_fpga_fifo(void); - void set_reset_fpga(const bool en); void handle_async_message(uhd::transport::managed_recv_buffer::sptr); uhd::sensor_value_t get_ref_locked(void); void set_rx_fe_corrections(const double); diff --git a/host/lib/usrp/common/fx2_ctrl.hpp b/host/lib/usrp/common/fx2_ctrl.hpp index 691d64275..5e28e8081 100644 --- a/host/lib/usrp/common/fx2_ctrl.hpp +++ b/host/lib/usrp/common/fx2_ctrl.hpp @@ -116,6 +116,9 @@ public: //! enable/disable the tx path virtual void usrp_tx_enable(bool on) = 0; + + //! reset the fpga + virtual void usrp_fpga_reset(bool on) = 0; }; }} //namespace uhd::usrp -- cgit v1.2.3 From 1463a78fd2ebac1985182dede9c3ec1af11a3799 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 14 Feb 2012 15:01:15 -0800 Subject: b100: reset/reenumerate fx2 for bad endpoint state Determine state of control endpoint, re-enumerate to put in a known state, rerun some initialization code. --- host/lib/usrp/b100/b100_impl.cpp | 19 +++++++++++++++++++ host/lib/usrp/common/fx2_ctrl.cpp | 9 +++++++++ host/lib/usrp/common/fx2_ctrl.hpp | 3 +++ 3 files changed, 31 insertions(+) (limited to 'host/lib/usrp/common') diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index af10590ac..8b55494c5 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -150,6 +150,10 @@ UHD_STATIC_BLOCK(register_b100_device){ * Structors **********************************************************************/ b100_impl::b100_impl(const device_addr_t &device_addr){ + size_t initialization_count = 0; + b100_impl_constructor_begin: + initialization_count++; + _tree = property_tree::make(); //extract the FPGA path for the B100 @@ -205,6 +209,21 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ //////////////////////////////////////////////////////////////////// _fpga_ctrl = b100_ctrl::make(_ctrl_transport); _fpga_ctrl->poke32(B100_REG_GLOBAL_RESET, 0); //global fpga reset + //perform a test peek operation + try{ + _fpga_ctrl->peek32(0); + } + //try reset once in the case of failure + catch(const uhd::exception &e){ + if (initialization_count > 1) throw; + UHD_MSG(warning) << + "The control endpoint was left in a bad state.\n" + "Attempting endpoint re-enumeration...\n" << std::endl; + _fpga_ctrl.reset(); + _ctrl_transport.reset(); + _fx2_ctrl->usrp_fx2_reset(); + goto b100_impl_constructor_begin; + } this->check_fpga_compat(); //check after reset and making control //////////////////////////////////////////////////////////////////// diff --git a/host/lib/usrp/common/fx2_ctrl.cpp b/host/lib/usrp/common/fx2_ctrl.cpp index baf8f5e68..7b8920eb1 100644 --- a/host/lib/usrp/common/fx2_ctrl.cpp +++ b/host/lib/usrp/common/fx2_ctrl.cpp @@ -139,6 +139,15 @@ public: _ctrl_transport = ctrl_transport; } + void usrp_fx2_reset(void){ + unsigned char reset_y = 1; + unsigned char reset_n = 0; + usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, &reset_y, 1); + usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, &reset_n, 1); + //wait for things to settle + boost::this_thread::sleep(boost::posix_time::milliseconds(2000)); + } + void usrp_load_firmware(std::string filestring, bool force) { const char *filename = filestring.c_str(); diff --git a/host/lib/usrp/common/fx2_ctrl.hpp b/host/lib/usrp/common/fx2_ctrl.hpp index 5e28e8081..f2e060862 100644 --- a/host/lib/usrp/common/fx2_ctrl.hpp +++ b/host/lib/usrp/common/fx2_ctrl.hpp @@ -39,6 +39,9 @@ public: //! Call init after the fpga is loaded virtual void usrp_init(void) = 0; + //! For emergency situations + virtual void usrp_fx2_reset(void) = 0; + /*! * Load firmware in Intel HEX Format onto device * \param filename name of firmware file -- cgit v1.2.3 From 3060006b35859c8766e00d3b234b51a19aa8595f Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 14 Feb 2012 18:26:03 -0800 Subject: uhd: added async md user payload and common utils --- host/include/uhd/types/metadata.hpp | 15 ++++-- host/lib/usrp/b100/io_impl.cpp | 26 +++++----- host/lib/usrp/common/async_packet_handler.hpp | 71 +++++++++++++++++++++++++++ host/lib/usrp/e100/io_impl.cpp | 18 ++----- host/lib/usrp/usrp2/io_impl.cpp | 18 ++----- 5 files changed, 100 insertions(+), 48 deletions(-) create mode 100644 host/lib/usrp/common/async_packet_handler.hpp (limited to 'host/lib/usrp/common') 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 #include +#include 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_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, 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 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 . +// + +#ifndef INCLUDED_LIBUHD_USRP_COMMON_ASYNC_PACKET_HANDLER_HPP +#define INCLUDED_LIBUHD_USRP_COMMON_ASYNC_PACKET_HANDLER_HPP + +#include +#include +#include +#include +#include + +namespace uhd{ namespace usrp{ + + template + 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 //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, 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, 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... -- cgit v1.2.3