diff options
Diffstat (limited to 'host/lib')
| -rw-r--r-- | host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp | 15 | ||||
| -rw-r--r-- | host/lib/usrp/common/usrp3_fw_ctrl_iface.hpp | 9 | ||||
| -rw-r--r-- | host/lib/usrp/n230/n230_image_loader.cpp | 36 | ||||
| -rw-r--r-- | host/lib/usrp/n230/n230_impl.cpp | 69 | ||||
| -rw-r--r-- | host/lib/usrp/n230/n230_resource_manager.cpp | 30 | ||||
| -rw-r--r-- | host/lib/usrp/n230/n230_resource_manager.hpp | 1 | 
6 files changed, 111 insertions, 49 deletions
| diff --git a/host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp b/host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp index aefd84882..ef541e37f 100644 --- a/host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp +++ b/host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp @@ -32,9 +32,10 @@ namespace uhd { namespace usrp { namespace usrp3 {  //----------------------------------------------------------  uhd::wb_iface::sptr usrp3_fw_ctrl_iface::make(      uhd::transport::udp_simple::sptr udp_xport, -    boost::uint16_t product_id) +    const boost::uint16_t product_id, +    const bool verbose)  { -    return wb_iface::sptr(new usrp3_fw_ctrl_iface(udp_xport, product_id)); +    return wb_iface::sptr(new usrp3_fw_ctrl_iface(udp_xport, product_id, verbose));  }  //---------------------------------------------------------- @@ -43,8 +44,10 @@ uhd::wb_iface::sptr usrp3_fw_ctrl_iface::make(  usrp3_fw_ctrl_iface::usrp3_fw_ctrl_iface(      uhd::transport::udp_simple::sptr udp_xport, -    boost::uint16_t product_id) : -    _product_id(product_id), _udp_xport(udp_xport), _seq_num(0) +    const boost::uint16_t product_id, +    const bool verbose) : +    _product_id(product_id), _verbose(verbose), _udp_xport(udp_xport), +    _seq_num(0)  {      flush();      peek32(0); @@ -72,7 +75,7 @@ void usrp3_fw_ctrl_iface::poke32(const wb_addr_type addr, const boost::uint32_t          } catch(const std::exception &ex) {              const std::string error_msg = str(boost::format(                  "udp fw poke32 failure #%u\n%s") % i % ex.what()); -            UHD_MSG(warning) << error_msg << std::endl; +            if (_verbose) UHD_MSG(warning) << error_msg << std::endl;              if (i == NUM_RETRIES) throw uhd::io_error(error_msg);          }      } @@ -88,7 +91,7 @@ boost::uint32_t usrp3_fw_ctrl_iface::peek32(const wb_addr_type addr)          } catch(const std::exception &ex) {              const std::string error_msg = str(boost::format(                  "udp fw peek32 failure #%u\n%s") % i % ex.what()); -            UHD_MSG(warning) << error_msg << std::endl; +            if (_verbose) UHD_MSG(warning) << error_msg << std::endl;              if (i == NUM_RETRIES) throw uhd::io_error(error_msg);          }      } diff --git a/host/lib/usrp/common/usrp3_fw_ctrl_iface.hpp b/host/lib/usrp/common/usrp3_fw_ctrl_iface.hpp index 3617f3083..33286861b 100644 --- a/host/lib/usrp/common/usrp3_fw_ctrl_iface.hpp +++ b/host/lib/usrp/common/usrp3_fw_ctrl_iface.hpp @@ -30,7 +30,8 @@ class usrp3_fw_ctrl_iface : public uhd::wb_iface  public:      usrp3_fw_ctrl_iface(          uhd::transport::udp_simple::sptr udp_xport, -        boost::uint16_t product_id); +        const boost::uint16_t product_id, +        const bool verbose);      virtual ~usrp3_fw_ctrl_iface();      // -- uhd::wb_iface -- @@ -40,7 +41,8 @@ public:      static uhd::wb_iface::sptr make(          uhd::transport::udp_simple::sptr udp_xport, -        boost::uint16_t product_id); +        const boost::uint16_t product_id, +        const bool verbose = true);      // -- uhd::wb_iface --      static std::vector<std::string> discover_devices( @@ -56,7 +58,8 @@ private:      boost::uint32_t _peek32(const wb_addr_type addr);      void _flush(void); -    boost::uint16_t                     _product_id; +    const boost::uint16_t               _product_id; +    const bool                          _verbose;      uhd::transport::udp_simple::sptr    _udp_xport;      boost::uint32_t                     _seq_num;      boost::mutex                        _mutex; diff --git a/host/lib/usrp/n230/n230_image_loader.cpp b/host/lib/usrp/n230/n230_image_loader.cpp index f8a6ba092..9dd4a252d 100644 --- a/host/lib/usrp/n230/n230_image_loader.cpp +++ b/host/lib/usrp/n230/n230_image_loader.cpp @@ -21,10 +21,11 @@  #include <uhd/exception.hpp>  #include <uhd/utils/static.hpp>  #include <uhd/utils/byteswap.hpp> +#include <uhd/utils/paths.hpp>  #include <uhd/transport/udp_simple.hpp>  #include <boost/algorithm/string.hpp>  #include <boost/filesystem.hpp> - +#include <boost/format.hpp>  #include "n230_fw_host_iface.h"  #include "n230_impl.hpp" @@ -129,11 +130,27 @@ static bool n230_image_loader(const image_loader::image_loader_args_t &loader_ar      device_addr_t dev = devs[0];      // Sanity check the specified bitfile -    if (not boost::filesystem::exists(loader_args.fpga_path)) { -        throw uhd::runtime_error(str(boost::format("The file \"%s\" does not exist.") % loader_args.fpga_path)); +    std::string fpga_img_path = loader_args.fpga_path; +    bool fpga_path_specified = !loader_args.fpga_path.empty(); +    if (not fpga_path_specified) { +        fpga_img_path = ( +            fs::path(uhd::get_pkg_path()) / "share" / "uhd" / "images" / "usrp_n230_fpga.bit" +        ).string(); +    } + +    if (not boost::filesystem::exists(fpga_img_path)) { +        if (fpga_path_specified) { +            throw uhd::runtime_error(str(boost::format("The file \"%s\" does not exist.") % fpga_img_path)); +        } else { +            throw uhd::runtime_error(str(boost::format( +                "Could not find the default FPGA image: %s.\n" +                "Either specify the --fpga-path argument or download the latest prebuilt images:\n" +                "%s\n") +            % fpga_img_path % print_utility_error("uhd_images_downloader.py"))); +        }      }      xil_bitfile_hdr_t hdr; -    _parse_bitfile_header(loader_args.fpga_path, hdr); +    _parse_bitfile_header(fpga_img_path, hdr);      // Create a UDP communication link      udp_simple::sptr udp_xport = @@ -142,11 +159,11 @@ static bool n230_image_loader(const image_loader::image_loader_args_t &loader_ar      if (hdr.valid and hdr.product == "n230") {          if (hdr.userid != 0x5AFE0000) {              std::cout << boost::format("Unit: USRP N230 (%s, %s)\n-- FPGA Image: %s\n") -                         % dev["addr"] % dev["serial"] % loader_args.fpga_path; +                         % dev["addr"] % dev["serial"] % fpga_img_path;              // Write image -            std::ifstream image(loader_args.fpga_path.c_str(), std::ios::binary); -            size_t image_size = boost::filesystem::file_size(loader_args.fpga_path); +            std::ifstream image(fpga_img_path.c_str(), std::ios::binary); +            size_t image_size = boost::filesystem::file_size(fpga_img_path);              static const size_t SECTOR_SIZE = 65536;              static const size_t IMAGE_BASE  = 0x400000; @@ -171,14 +188,15 @@ static bool n230_image_loader(const image_loader::image_loader_args_t &loader_ar                               % (int(double(bytes_written) / double(image_size) * 100.0))                           << std::flush;              } -            std::cout << std::endl << "Image loaded successfully." << std::endl; +            std::cout << std::endl << "FPGA image loaded successfully." << std::endl; +            std::cout << std::endl << "Power-cycle the device to run the image." << std::endl;              return true;          } else {              throw uhd::runtime_error("This utility cannot burn a failsafe image!");          }      } else {          throw uhd::runtime_error(str(boost::format("The file at path \"%s\" is not a valid USRP N230 FPGA image.") -                                     % loader_args.fpga_path)); +                                     % fpga_img_path));      }  } diff --git a/host/lib/usrp/n230/n230_impl.cpp b/host/lib/usrp/n230/n230_impl.cpp index ab7fa6fe6..b005182cf 100644 --- a/host/lib/usrp/n230/n230_impl.cpp +++ b/host/lib/usrp/n230/n230_impl.cpp @@ -130,30 +130,47 @@ uhd::device_addrs_t n230_impl::n230_find(const uhd::device_addr_t &multi_dev_hin          //we may not be able to communicate directly (non-broadcast).          udp_simple::sptr ctrl_xport = udp_simple::make_connected(new_addr["addr"], BOOST_STRINGIZE(N230_FW_COMMS_UDP_PORT)); -        usrp3::usrp3_fw_ctrl_iface::sptr fw_ctrl = usrp3::usrp3_fw_ctrl_iface::make(ctrl_xport, N230_FW_PRODUCT_ID); -        uint32_t compat_reg_addr = fw::reg_addr(fw::WB_SBRB_BASE, fw::RB_ZPU_COMPAT); -        if (fw::get_prod_num(fw_ctrl->peek32(compat_reg_addr)) == fw::PRODUCT_NUM) { -            if (!n230_resource_manager::is_device_claimed(fw_ctrl)) { -                //Not claimed by another process or host -                try { -                    //Try to read the EEPROM to get the name and serial -                    n230_eeprom_manager eeprom_mgr(new_addr["addr"]); -                    const mboard_eeprom_t& eeprom = eeprom_mgr.get_mb_eeprom(); -                    new_addr["name"] = eeprom["name"]; -                    new_addr["serial"] = eeprom["serial"]; -                } -                catch(const std::exception &) -                { -                    //set these values as empty string so the device may still be found -                    //and the filter's below can still operate on the discovered device -                    new_addr["name"] = ""; -                    new_addr["serial"] = ""; -                } -                //filter the discovered device below by matching optional keys -                if ((not hint.has_key("name")    or hint["name"]    == new_addr["name"]) and -                    (not hint.has_key("serial")  or hint["serial"]  == new_addr["serial"])) -                { -                    n230_addrs.push_back(new_addr); +        //Corner case: If two devices have the same IP but different MAC +        //addresses and are used back-to-back it takes a while for ARP tables +        //on the host to update in which period brodcasts will respond but +        //connected communication can fail. Retry the following call to allow +        //the stack to update +        size_t first_conn_retries = 10; +        usrp3::usrp3_fw_ctrl_iface::sptr fw_ctrl; +        while (first_conn_retries > 0) { +            try { +                fw_ctrl = usrp3::usrp3_fw_ctrl_iface::make(ctrl_xport, N230_FW_PRODUCT_ID, false /*verbose*/); +                break; +            } catch (uhd::io_error& ex) { +                boost::this_thread::sleep(boost::posix_time::milliseconds(500)); +                first_conn_retries--; +            } +        } +        if (first_conn_retries > 0) { +            uint32_t compat_reg = fw_ctrl->peek32(fw::reg_addr(fw::WB_SBRB_BASE, fw::RB_ZPU_COMPAT)); +            if (fw::get_prod_num(compat_reg) == fw::PRODUCT_NUM) { +                if (!n230_resource_manager::is_device_claimed(fw_ctrl)) { +                    //Not claimed by another process or host +                    try { +                        //Try to read the EEPROM to get the name and serial +                        n230_eeprom_manager eeprom_mgr(new_addr["addr"]); +                        const mboard_eeprom_t& eeprom = eeprom_mgr.get_mb_eeprom(); +                        new_addr["name"] = eeprom["name"]; +                        new_addr["serial"] = eeprom["serial"]; +                    } +                    catch(const std::exception &) +                    { +                        //set these values as empty string so the device may still be found +                        //and the filter's below can still operate on the discovered device +                        new_addr["name"] = ""; +                        new_addr["serial"] = ""; +                    } +                    //filter the discovered device below by matching optional keys +                    if ((not hint.has_key("name")    or hint["name"]    == new_addr["name"]) and +                        (not hint.has_key("serial")  or hint["serial"]  == new_addr["serial"])) +                    { +                        n230_addrs.push_back(new_addr); +                    }                  }              }          } @@ -204,10 +221,6 @@ n230_impl::n230_impl(const uhd::device_addr_t& dev_addr)              throw uhd::runtime_error(str(boost::format(                  "Hardware is too new for this software. Please upgrade to a driver that supports hardware revision %d.")                  % hw_rev)); -        } else if (hw_rev < N230_HW_REVISION_MIN) { //Compare min against the revision (and not compat) to give us more leeway for partial support for a compat -            throw uhd::runtime_error(str(boost::format( -                "Software is too new for this hardware. Please downgrade to a driver that supports hardware revision %d.") -                % hw_rev));          }      } diff --git a/host/lib/usrp/n230/n230_resource_manager.cpp b/host/lib/usrp/n230/n230_resource_manager.cpp index 4db494302..f13dd0b33 100644 --- a/host/lib/usrp/n230/n230_resource_manager.cpp +++ b/host/lib/usrp/n230/n230_resource_manager.cpp @@ -84,6 +84,7 @@ n230_resource_manager::n230_resource_manager(      UHD_MSG(status) << "Setup basic communication...\n";      //Discover ethernet interfaces +    bool dual_eth_expected = (ip_addrs.size() > 1);      BOOST_FOREACH(const std::string& addr, ip_addrs) {          n230_eth_conn_t conn_iface;          conn_iface.ip_addr = addr; @@ -100,7 +101,15 @@ n230_resource_manager::n230_resource_manager(          switch (iface_id) {              case N230_ETH0_IFACE_ID: conn_iface.type = ETH0; break;              case N230_ETH1_IFACE_ID: conn_iface.type = ETH1; break; -            default: throw uhd::runtime_error("N230 Initialization Error: Could not detect ethernet port number.)"); +            default: { +                if (dual_eth_expected) { +                    throw uhd::runtime_error("N230 Initialization Error: Could not detect ethernet port number."); +                } else { +                    //For backwards compatibility, if only one port is specified, assume that a detection +                    //failure means that the device does not support dual-ethernet behavior. +                    conn_iface.type = ETH0; break; +                } +            }          }          _eth_conns.push_back(conn_iface);      } @@ -488,6 +497,21 @@ bool n230_resource_manager::_radio_data_loopback_self_test(wb_iface::sptr iface)      return !test_fail;  } +std::string n230_resource_manager::_get_fpga_upgrade_msg() { +    std::string img_loader_path = +        (fs::path(uhd::get_pkg_path()) / "bin" / "uhd_image_loader").string(); + +    return str(boost::format( +            "\nDownload the appropriate FPGA images for this version of UHD.\n" +            "%s\n\n" +            "Then burn a new image to the on-board flash storage of your\n" +            "USRP N230 device using the image loader utility. Use this command:\n" +            "\n \"%s\" --args=\"type=n230,addr=%s\"\n") +        % print_utility_error("uhd_images_downloader.py") +        % img_loader_path % _get_conn(PRI_ETH).ip_addr); + +} +  void n230_resource_manager::_check_fw_compat()  {      boost::uint32_t compat_num = _fw_ctrl->peek32(N230_FW_HOST_SHMEM_OFFSET(fw_compat_num)); @@ -503,7 +527,7 @@ void n230_resource_manager::_check_fw_compat()              ) % static_cast<boost::uint32_t>(N230_FW_COMPAT_NUM_MAJOR)                % static_cast<boost::uint32_t>(_fw_version.compat_major)                % static_cast<boost::uint32_t>(_fw_version.compat_minor) -              % print_utility_error("uhd_images_downloader.py"))); +              % _get_fpga_upgrade_msg()));      }  } @@ -538,7 +562,7 @@ void n230_resource_manager::_check_fpga_compat()              ) % static_cast<boost::uint32_t>(fpga::RB_N230_COMPAT_MAJOR)                % static_cast<boost::uint32_t>(_fpga_version.compat_major)                % static_cast<boost::uint32_t>(_fpga_version.compat_minor) -              % print_utility_error("uhd_images_downloader.py"))); +              % _get_fpga_upgrade_msg()));      }  } diff --git a/host/lib/usrp/n230/n230_resource_manager.hpp b/host/lib/usrp/n230/n230_resource_manager.hpp index 3a0b13329..0a1178bd2 100644 --- a/host/lib/usrp/n230/n230_resource_manager.hpp +++ b/host/lib/usrp/n230/n230_resource_manager.hpp @@ -240,6 +240,7 @@ private:      void _initialize_radio(size_t instance); +    std::string _get_fpga_upgrade_msg();      void _check_fw_compat();      void _check_fpga_compat(); | 
