From 265db795c26cf9609f8f1288484f85788cbf7b3d Mon Sep 17 00:00:00 2001 From: Ashish Chaudhari Date: Thu, 6 Nov 2014 14:21:39 -0800 Subject: x300: Cleaned up DAC ctrl and clock init logic - DAC: Squashed configuration into 2 main operations: reset and reset_and_resync - DAC: Put in sleep mode during configuration - DAC: Synchronize only if streaming to more than one DAC - DAC: Use falling edge sync mode - DAC: Fixed power up/down settings - DAC: Frontend sync failure is fatal - Clocks: Refactored clock source change logic - Clocks: Cleaned up init and lock-check sequence --- host/lib/usrp/x300/x300_impl.cpp | 273 ++++++++++++++++++++++----------------- 1 file changed, 151 insertions(+), 122 deletions(-) (limited to 'host/lib/usrp/x300/x300_impl.cpp') diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index b4286ee79..5520cc82e 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -372,6 +372,7 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) { const fs_path mb_path = "/mboards/"+boost::lexical_cast(mb_i); mboard_members_t &mb = _mb[mb_i]; + mb.initialization_done = false; mb.addr = dev_addr.has_key("resource") ? dev_addr["resource"] : dev_addr["addr"]; mb.xport_path = dev_addr.has_key("resource") ? "nirio" : "eth"; @@ -621,32 +622,18 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) mb.hw_rev = X300_REV("D"); } - //Initialize clock control with internal references and GPSDO power on. - mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_INTERNAL; - mb.clock_control_regs_pps_select = ZPU_SR_CLOCK_CTRL_PPS_SRC_INTERNAL; - mb.clock_control_regs_pps_out_enb = 0; - mb.clock_control_regs_tcxo_enb = 1; - mb.clock_control_regs_gpsdo_pwr = 1; - this->update_clock_control(mb); - - //Create clock control + //Create clock control. NOTE: This does not configure the LMK yet. + initialize_clock_control(mb); mb.clock = x300_clock_ctrl::make(mb.zpu_spi, 1 /*slaveno*/, mb.hw_rev, dev_addr.cast("master_clock_rate", X300_DEFAULT_TICK_RATE), dev_addr.cast("system_ref_rate", X300_DEFAULT_SYSREF_RATE)); - //wait for reference clock to lock - if(mb.hw_rev > 4) - { - try { - //FIXME: Need to verify timeout value to make sure lock can be achieved in < 1.0 seconds - wait_for_ref_locked(mb.zpu_ctrl, 1.0); - } catch (uhd::runtime_error &e) { - //Silently fail for now, but fix after we have the correct timeout value - //UHD_MSG(warning) << "Clock failed to lock to internal source during initialization." << std::endl; - } - } + //Initialize clock source to use internal reference and generate + //a valid radio clock. This may change after configuration is done. + //This will configure the LMK and wait for lock + update_clock_source(mb, "internal"); //////////////////////////////////////////////////////////////////// // create clock properties @@ -750,7 +737,6 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) _tree->create(mb_path / "clock_source" / "value") .set("internal") .subscribe(boost::bind(&x300_impl::update_clock_source, this, boost::ref(mb), _1)) - .subscribe(boost::bind(&x300_impl::reset_clocks, this, boost::ref(mb))) .subscribe(boost::bind(&x300_impl::reset_radios, this, boost::ref(mb))); static const std::vector clock_source_options = boost::assign::list_of("internal")("external")("gpsdo"); @@ -769,6 +755,22 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) _tree->create(mb_path / "clock_source" / "output") .subscribe(boost::bind(&x300_clock_ctrl::set_ref_out, mb.clock, _1)); + //////////////////////////////////////////////////////////////////// + // initialize clock and time sources + //////////////////////////////////////////////////////////////////// + if (mb.gps and mb.gps->gps_detected()) + { + UHD_MSG(status) << "Initializing clock and time using GPSDO... " << std::flush; + _tree->access(mb_path / "clock_source" / "value").set("gpsdo"); + _tree->access(mb_path / "time_source" / "value").set("gpsdo"); + const time_t tp = time_t(mb.gps->get_sensor("gps_time").to_int() + 1); + _tree->access(mb_path / "time" / "pps").set(time_spec_t(tp)); + } else { + UHD_MSG(status) << "Initializing clock and time using internal sources... " << std::flush; + _tree->access(mb_path / "clock_source" / "value").set("internal"); + _tree->access(mb_path / "time_source" / "value").set("internal"); + } + UHD_MSG(status) << "done" << std::endl; //////////////////////////////////////////////////////////////////// // create frontend mapping @@ -811,25 +813,7 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) _tree->access(mb_path / "rx_subdev_spec").set(rx_fe_spec); _tree->access(mb_path / "tx_subdev_spec").set(tx_fe_spec); - UHD_MSG(status) << "Initializing clock and PPS references..." << std::endl; - //Set to the GPSDO if installed - if (mb.gps and mb.gps->gps_detected()) - { - _tree->access(mb_path / "clock_source" / "value").set("gpsdo"); - try { - wait_for_ref_locked(mb.zpu_ctrl, 1.0); - } catch (uhd::exception::runtime_error &e) { - UHD_MSG(warning) << "Clock reference failed to lock to GPSDO during device initialization. " << - "Check for the lock before operation or ignore this warning if using another clock source." << std::endl; - } - _tree->access(mb_path / "time_source" / "value").set("gpsdo"); - UHD_MSG(status) << "References initialized to GPSDO sources" << std::endl; - UHD_MSG(status) << "Initializing time to the GPSDO time" << std::endl; - const time_t tp = time_t(mb.gps->get_sensor("gps_time").to_int()+1); - _tree->access(mb_path / "time" / "pps").set(time_spec_t(tp)); - } else { - UHD_MSG(status) << "References initialized to internal sources" << std::endl; - } + mb.initialization_done = true; } x300_impl::~x300_impl(void) @@ -916,14 +900,6 @@ void x300_impl::setup_radio(const size_t mb_i, const std::string &slot_name) } perif.adc->set_test_word("normal", "normal"); - //////////////////////////////////////////////////////////////// - // Sync DAC's for MIMO - //////////////////////////////////////////////////////////////// - UHD_MSG(status) << "Sync DAC's." << std::endl; - perif.dac->arm_dac_sync(); // Put DAC into data Sync mode - perif.ctrl->poke32(TOREG(SR_DACSYNC), 0x1); // Arm FRAMEP/N sync pulse - - //////////////////////////////////////////////////////////////// // create codec control objects //////////////////////////////////////////////////////////////// @@ -960,8 +936,6 @@ void x300_impl::setup_radio(const size_t mb_i, const std::string &slot_name) .subscribe(boost::bind(&tx_frontend_core_200::set_iq_balance, perif.tx_fe, _1)) .set(std::complex(0.0, 0.0)); - - //////////////////////////////////////////////////////////////////// // create rx dsp control objects //////////////////////////////////////////////////////////////////// @@ -1200,10 +1174,10 @@ x300_impl::both_xports_t x300_impl::make_transport( << std::endl; } - size_t system_max_send_frame_size = (size_t) _max_frame_sizes.send_frame_size; - size_t system_max_recv_frame_size = (size_t) _max_frame_sizes.recv_frame_size; + size_t system_max_send_frame_size = (size_t) _max_frame_sizes.send_frame_size; + size_t system_max_recv_frame_size = (size_t) _max_frame_sizes.recv_frame_size; - // Make sure frame sizes do not exceed the max available value supported by UHD + // Make sure frame sizes do not exceed the max available value supported by UHD default_buff_args.send_frame_size = (prefix == X300_RADIO_DEST_PREFIX_TX) ? std::min(system_max_send_frame_size, X300_10GE_DATA_FRAME_MAX_SIZE) @@ -1346,11 +1320,9 @@ void x300_impl::register_loopback_self_test(wb_iface::sptr iface) UHD_MSG(status) << ((test_fail)? " fail" : "pass") << std::endl; } -void x300_impl::set_time_source_out(mboard_members_t &mb, const bool enb) -{ - mb.clock_control_regs_pps_out_enb = enb? 1 : 0; - this->update_clock_control(mb); -} +/*********************************************************************** + * clock and time control logic + **********************************************************************/ void x300_impl::update_clock_control(mboard_members_t &mb) { @@ -1363,79 +1335,71 @@ void x300_impl::update_clock_control(mboard_members_t &mb) mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_CLOCK_CTRL), reg); } -void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &source) +void x300_impl::initialize_clock_control(mboard_members_t &mb) { - mb.clock_control_regs_clock_source = 0; - mb.clock_control_regs_tcxo_enb = 0; - if (source == "internal") { - mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_INTERNAL; - mb.clock_control_regs_tcxo_enb = 1; - } else if (source == "external") { - mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_EXTERNAL; - } else if (source == "gpsdo") { - mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_GPSDO; - } else { - throw uhd::key_error("update_clock_source: unknown source: " + source); - } - + //Initialize clock control register soft copies + mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_INTERNAL; + mb.clock_control_regs_pps_select = ZPU_SR_CLOCK_CTRL_PPS_SRC_INTERNAL; + mb.clock_control_regs_pps_out_enb = 0; + mb.clock_control_regs_tcxo_enb = 1; + mb.clock_control_regs_gpsdo_pwr = 1; //GPSDO power always ON this->update_clock_control(mb); - - /* FIXME: implement when we know the correct timeouts - * //wait for lock - * double timeout = 1.0; - * try { - * if (mb.hw_rev > 4) - * wait_for_ref_locked(mb.zpu_ctrl, timeout); - * } catch (uhd::runtime_error &e) { - * //failed to lock on reference - * throw uhd::runtime_error((boost::format("Clock failed to lock to %s source.") % source).str()); - * } - */ } -void x300_impl::reset_clocks(mboard_members_t &mb) +void x300_impl::set_time_source_out(mboard_members_t &mb, const bool enb) { - mb.clock->reset_clocks(); - - if (mb.hw_rev > 4) - { - try { - wait_for_ref_locked(mb.zpu_ctrl, 30.0); - } catch (uhd::runtime_error &e) { - //failed to lock on reference - throw uhd::runtime_error((boost::format("PLL failed to lock to reference clock.")).str()); - } - } + mb.clock_control_regs_pps_out_enb = enb? 1 : 0; + this->update_clock_control(mb); } -void x300_impl::reset_radios(mboard_members_t &mb) +void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &source) { - // reset ADCs and DACs - BOOST_FOREACH (radio_perifs_t& perif, mb.radio_perifs) - { - perif.adc->reset(); - perif.dac->reset(); - } + //Optimize for the case when the current source is internal and we are trying + //to set it to internal. This is the only case where we are guaranteed that + //the clock has not gone away so we can skip setting the MUX and reseting the LMK. + if (not (mb.current_refclk_src == "internal" and source == "internal")) { + //Update the clock MUX on the motherboard to select the requested source + mb.clock_control_regs_clock_source = 0; + mb.clock_control_regs_tcxo_enb = 0; + if (source == "internal") { + mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_INTERNAL; + mb.clock_control_regs_tcxo_enb = 1; + } else if (source == "external") { + mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_EXTERNAL; + } else if (source == "gpsdo") { + mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_GPSDO; + } else { + throw uhd::key_error("update_clock_source: unknown source: " + source); + } + this->update_clock_control(mb); - // check PLL locks - BOOST_FOREACH (radio_perifs_t& perif, mb.radio_perifs) - { - perif.dac->check_pll(); + //Reset the LMK to make sure it re-locks to the new reference + mb.clock->reset_clocks(); } - // Sync DACs - BOOST_FOREACH (radio_perifs_t& perif, mb.radio_perifs) - { - perif.dac->arm_dac_sync(); - } - BOOST_FOREACH (radio_perifs_t& perif, mb.radio_perifs) - { - perif.dac->check_dac_sync(); - // Arm FRAMEP/N sync pulse - // TODO: Investigate timing of the sync frame pulse. - perif.ctrl->poke32(TOREG(SR_DACSYNC), 0x1); - perif.dac->check_frontend_sync(); + //Wait for the LMK to lock (always, as a sanity check that the clock is useable) + //* Currently the LMK can take as long as 30 seconds to lock to a reference but we don't + //* want to wait that long during initialization. + //TODO: Need to verify timeout and settings to make sure lock can be achieved in < 1.0 seconds + double timeout = mb.initialization_done ? 30.0 : 1.0; + + //The programming code in x300_clock_ctrl is not compatible with revs <= 4 and may + //lead to locking issues. So, disable the ref-locked check for older (unsupported) boards. + if (mb.hw_rev > 4) { + if (not wait_for_ref_locked(mb.zpu_ctrl, timeout)) { + //failed to lock on reference + if (mb.initialization_done) { + throw uhd::runtime_error((boost::format("Reference Clock failed to lock to %s source.") % source).str()); + } else { + //TODO: Re-enable this warning when we figure out a reliable lock time + //UHD_MSG(warning) << "Reference clock failed to lock to " + source + " during device initialization. " << + // "Check for the lock before operation or ignore this warning if using another clock source." << std::endl; + } + } } + + //Update cache value + mb.current_refclk_src = source; } void x300_impl::update_time_source(mboard_members_t &mb, const std::string &source) @@ -1460,18 +1424,18 @@ void x300_impl::update_time_source(mboard_members_t &mb, const std::string &sour } } -void x300_impl::wait_for_ref_locked(wb_iface::sptr ctrl, double timeout) +bool x300_impl::wait_for_ref_locked(wb_iface::sptr ctrl, double timeout) { boost::system_time timeout_time = boost::get_system_time() + boost::posix_time::milliseconds(timeout * 1000.0); do { if (get_ref_locked(ctrl).to_bool()) - return; + return true; boost::this_thread::sleep(boost::posix_time::milliseconds(1)); } while (boost::get_system_time() < timeout_time); //failed to lock on reference - throw uhd::runtime_error("The reference clock failed to lock."); + return false; } sensor_value_t x300_impl::get_ref_locked(wb_iface::sptr ctrl) @@ -1496,6 +1460,67 @@ bool x300_impl::is_pps_present(wb_iface::sptr ctrl) return false; } +/*********************************************************************** + * reset and synchronization logic + **********************************************************************/ + +void x300_impl::reset_radios(mboard_members_t &mb) +{ + // Reset ADCs and DACs + BOOST_FOREACH (radio_perifs_t& perif, mb.radio_perifs) + { + perif.adc->reset(); + perif.dac->reset(); + } +} + +void x300_impl::synchronize_dacs(const std::vector& radios) +{ + if (radios.size() < 2) return; //Nothing to synchronize + + //**PRECONDITION** + //This function assumes that all the VITA times in "radios" are synchronized + //to a common reference. Currently, this function is called in get_tx_stream + //which also has the same precondition. + + //Reinitialize and resync all DACs + for (size_t i = 0; i < radios.size(); i++) { + radios[i]->dac->reset_and_resync(); + } + + //Get a rough estimate of the cumulative command latency + boost::posix_time::ptime t_start = boost::posix_time::microsec_clock::local_time(); + for (size_t i = 0; i < radios.size(); i++) { + radios[i]->ctrl->peek64(RB64_TIME_NOW); //Discard value. We are just timing the call + } + boost::posix_time::time_duration t_elapsed = + boost::posix_time::microsec_clock::local_time() - t_start; + + //Add 100% of headroom + uncertaintly to the command time + boost::uint64_t t_sync_us = (t_elapsed.total_microseconds() * 2) + 13000 /*Scheduler latency*/; + + //Pick radios[0] as the time reference. + uhd::time_spec_t sync_time = + radios[0]->time64->get_time_now() + uhd::time_spec_t(((double)t_sync_us)/1e6); + + //Send the sync command + for (size_t i = 0; i < radios.size(); i++) { + radios[i]->ctrl->set_time(sync_time); + radios[i]->ctrl->poke32(TOREG(SR_DACSYNC), 0x1); //Arm FRAMEP/N sync pulse + radios[i]->ctrl->set_time(uhd::time_spec_t(0.0)); //Clear command time + } + + //Wait and check status + boost::this_thread::sleep(boost::posix_time::microseconds(t_sync_us)); + for (size_t i = 0; i < radios.size(); i++) { + radios[i]->dac->verify_sync(); + } +} + +/*********************************************************************** + * eeprom + **********************************************************************/ + void x300_impl::set_db_eeprom(i2c_iface::sptr i2c, const size_t addr, const uhd::usrp::dboard_eeprom_t &db_eeprom) { db_eeprom.store(*i2c, addr); @@ -1507,6 +1532,10 @@ void x300_impl::set_mb_eeprom(i2c_iface::sptr i2c, const mboard_eeprom_t &mb_eep mb_eeprom.commit(*eeprom16, "X300"); } +/*********************************************************************** + * front-panel GPIO + **********************************************************************/ + boost::uint32_t x300_impl::get_fp_gpio(gpio_core_200::sptr gpio, const std::string &) { return boost::uint32_t(gpio->read_gpio(dboard_iface::UNIT_RX)); -- cgit v1.2.3 From beabf3d302a98a0a1e28ae8cc4d338f0bd13db6e Mon Sep 17 00:00:00 2001 From: Ben Hilburn Date: Mon, 3 Nov 2014 17:05:26 -0800 Subject: uhd: replaced the `images_error` with a generic utility error - Deleted images.*, moved functionality to paths.* - Applies for all devices that check FPGA or FW compat numbers - Adds generic utility search tool --- host/include/uhd/utils/CMakeLists.txt | 1 - host/include/uhd/utils/images.hpp | 53 ----------------------- host/include/uhd/utils/paths.hpp | 25 +++++++++++ host/lib/usrp/b100/b100_impl.cpp | 10 ++--- host/lib/usrp/b100/b100_impl.hpp | 2 +- host/lib/usrp/b200/b200_impl.cpp | 15 +++---- host/lib/usrp/b200/b200_impl.hpp | 6 +-- host/lib/usrp/e100/e100_impl.cpp | 4 +- host/lib/usrp/e300/e300_impl.cpp | 4 +- host/lib/usrp/e300/e300_network.cpp | 2 +- host/lib/usrp/usrp1/usrp1_impl.cpp | 4 +- host/lib/usrp/usrp2/usrp2_iface.cpp | 8 ++-- host/lib/usrp/x300/x300_impl.cpp | 14 +++--- host/lib/usrp_clock/octoclock/octoclock_impl.cpp | 6 +-- host/lib/utils/CMakeLists.txt | 1 - host/lib/utils/images.cpp | 54 ------------------------ host/lib/utils/paths.cpp | 37 ++++++++++++++-- host/utils/b2xx_fx3_utils.cpp | 2 +- host/utils/octoclock_firmware_burner.cpp | 2 +- host/utils/usrp_n2xx_simple_net_burner.cpp | 2 +- host/utils/usrp_x3xx_fpga_burner.cpp | 2 +- 21 files changed, 99 insertions(+), 155 deletions(-) delete mode 100644 host/include/uhd/utils/images.hpp delete mode 100644 host/lib/utils/images.cpp (limited to 'host/lib/usrp/x300/x300_impl.cpp') diff --git a/host/include/uhd/utils/CMakeLists.txt b/host/include/uhd/utils/CMakeLists.txt index c308c9cde..05f6892d2 100644 --- a/host/include/uhd/utils/CMakeLists.txt +++ b/host/include/uhd/utils/CMakeLists.txt @@ -25,7 +25,6 @@ UHD_INSTALL(FILES cast.hpp csv.hpp gain_group.hpp - images.hpp log.hpp math.hpp msg.hpp diff --git a/host/include/uhd/utils/images.hpp b/host/include/uhd/utils/images.hpp deleted file mode 100644 index a0934fb08..000000000 --- a/host/include/uhd/utils/images.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// -// 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 -// 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_UHD_UTILS_IMAGES_HPP -#define INCLUDED_UHD_UTILS_IMAGES_HPP - -#include -#include - -namespace uhd{ - - /*! - * Search for an image in the system image paths: - * Search compiled-in paths and environment variable paths - * for a specific image file with the provided file name. - * \param image_name the name of the file - * \return the full system path to the file - * \throw exception if the image was not found - */ - UHD_API std::string find_image_path(const std::string &image_name); - - /*! - * Search for the location of the UHD Images Downloader script. - * \return the full system path to uhd_images_downloader.py - */ - - UHD_API std::string find_images_downloader(void); - - /*! - * Return the error string for recommending using the UHD Images Downloader. - * String depends on OS. - * \return the message suggesting the use of uhd_images_downloader.py - */ - - UHD_API std::string print_images_error(void); - -} //namespace uhd - -#endif /* INCLUDED_UHD_UTILS_IMAGES_HPP */ diff --git a/host/include/uhd/utils/paths.hpp b/host/include/uhd/utils/paths.hpp index e0f455e92..c1f32ba61 100644 --- a/host/include/uhd/utils/paths.hpp +++ b/host/include/uhd/utils/paths.hpp @@ -32,6 +32,31 @@ namespace uhd{ //! Get a string representing the system's pkg directory UHD_API std::string get_pkg_path(void); + /*! + * Search for an image in the system image paths: + * Search compiled-in paths and environment variable paths + * for a specific image file with the provided file name. + * \param image_name the name of the file + * \return the full system path to the file + * \throw exception if the image was not found + */ + UHD_API std::string find_image_path(const std::string &image_name); + + /*! + * Search for the location of a particular UHD utility. + * The utility must be installed in the `uhd/utils` directory. + * \param the name of the utility to search for + * \return the full system path to @param + */ + UHD_API std::string find_utility(std::string name); + + /*! + * Return an error string recommending the user run the utility. + * The error string will include the full path to the utility to run. + * \return the message suggesting the use of the named utility. + */ + UHD_API std::string print_utility_error(std::string name); + } //namespace uhd #endif /* INCLUDED_UHD_UTILS_PATHS_HPP */ diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index 24a87a3c8..c4279913c 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -82,7 +82,7 @@ static device_addrs_t b100_find(const device_addr_t &hint) b100_fw_image = find_image_path(hint.get("fw", B100_FW_FILE_NAME)); } catch(...){ - UHD_MSG(warning) << boost::format("Could not locate B100 firmware. %s\n") % print_images_error(); + UHD_MSG(warning) << boost::format("Could not locate B100 firmware. %s\n") % print_utility_error("uhd_images_downloader.py"); return b100_addrs; } UHD_LOG << "the firmware image: " << b100_fw_image << std::endl; @@ -532,10 +532,10 @@ void b100_impl::check_fw_compat(void){ ); if (fw_compat_num != B100_FW_COMPAT_NUM){ throw uhd::runtime_error(str(boost::format( - "Expected firmware compatibility number 0x%x, but got 0x%x:\n" + "Expected firmware compatibility number %d, but got %d:\n" "The firmware build is not compatible with the host code build.\n" "%s" - ) % B100_FW_COMPAT_NUM % fw_compat_num % print_images_error())); + ) % int(B100_FW_COMPAT_NUM) % fw_compat_num % print_utility_error("uhd_images_downloader.py"))); } _tree->create("/mboards/0/fw_version").set(str(boost::format("%u.0") % fw_compat_num)); } @@ -552,7 +552,7 @@ void b100_impl::check_fpga_compat(void){ "Expected FPGA compatibility number %d, but got %d:\n" "The FPGA build is not compatible with the host code build." "%s" - ) % int(B100_FPGA_COMPAT_NUM) % fpga_major % print_images_error())); + ) % int(B100_FPGA_COMPAT_NUM) % fpga_major % print_utility_error("uhd_images_downloader.py"))); } _tree->create("/mboards/0/fpga_version").set(str(boost::format("%u.%u") % fpga_major % fpga_minor)); } diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp index 59ea2202e..dbca543be 100644 --- a/host/lib/usrp/b100/b100_impl.hpp +++ b/host/lib/usrp/b100/b100_impl.hpp @@ -46,7 +46,7 @@ static const double B100_LINK_RATE_BPS = 256e6/5; //pratical link rate (< 480 Mbps) static const std::string B100_FW_FILE_NAME = "usrp_b100_fw.ihx"; static const std::string B100_FPGA_FILE_NAME = "usrp_b100_fpga.bin"; -static const boost::uint16_t B100_FW_COMPAT_NUM = 0x04; +static const boost::uint16_t B100_FW_COMPAT_NUM = 4; static const boost::uint16_t B100_FPGA_COMPAT_NUM = 11; static const boost::uint32_t B100_RX_SID_BASE = 30; static const boost::uint32_t B100_TX_ASYNC_SID = 10; diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp index 6d1172c98..b3c190c50 100644 --- a/host/lib/usrp/b200/b200_impl.cpp +++ b/host/lib/usrp/b200/b200_impl.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -115,7 +115,7 @@ static device_addrs_t b200_find(const device_addr_t &hint) UHD_MSG(warning) << boost::format( "Could not locate B200 firmware.\n" "Please install the images package. %s\n" - ) % print_images_error(); + ) % print_utility_error("uhd_images_downloader.py"); return b200_addrs; } UHD_LOG << "the firmware image: " << b200_fw_image << std::endl; @@ -791,11 +791,11 @@ void b200_impl::check_fw_compat(void) if (compat_major != B200_FW_COMPAT_NUM_MAJOR){ throw uhd::runtime_error(str(boost::format( - "Expected firmware compatibility number 0x%x, but got 0x%x.%x:\n" + "Expected firmware compatibility number %d.%d, but got %d.%d:\n" "The firmware build is not compatible with the host code build.\n" "%s" - ) % int(B200_FW_COMPAT_NUM_MAJOR) % compat_major % compat_minor - % print_images_error())); + ) % int(B200_FW_COMPAT_NUM_MAJOR) % int(B200_FW_COMPAT_NUM_MINOR) + % compat_major % compat_minor % print_utility_error("uhd_images_downloader.py"))); } _tree->create("/mboards/0/fw_version").set(str(boost::format("%u.%u") % compat_major % compat_minor)); @@ -812,11 +812,10 @@ void b200_impl::check_fpga_compat(void) if (compat_major != B200_FPGA_COMPAT_NUM){ throw uhd::runtime_error(str(boost::format( - "Expected FPGA compatibility number 0x%x, but got 0x%x.%x:\n" + "Expected FPGA compatibility number %d, but got %d:\n" "The FPGA build is not compatible with the host code build.\n" "%s" - ) % int(B200_FPGA_COMPAT_NUM) % compat_major % compat_minor - % print_images_error())); + ) % int(B200_FPGA_COMPAT_NUM) % compat_major % print_utility_error("uhd_images_downloader.py"))); } _tree->create("/mboards/0/fpga_version").set(str(boost::format("%u.%u") % compat_major % compat_minor)); diff --git a/host/lib/usrp/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp index 22e962bd5..71592f60b 100644 --- a/host/lib/usrp/b200/b200_impl.hpp +++ b/host/lib/usrp/b200/b200_impl.hpp @@ -45,9 +45,9 @@ #include #include #include "recv_packet_demuxer_3000.hpp" -static const boost::uint8_t B200_FW_COMPAT_NUM_MAJOR = 0x07; -static const boost::uint8_t B200_FW_COMPAT_NUM_MINOR = 0x00; -static const boost::uint16_t B200_FPGA_COMPAT_NUM = 0x04; +static const boost::uint8_t B200_FW_COMPAT_NUM_MAJOR = 7; +static const boost::uint8_t B200_FW_COMPAT_NUM_MINOR = 0; +static const boost::uint16_t B200_FPGA_COMPAT_NUM = 4; static const double B200_BUS_CLOCK_RATE = 100e6; static const double B200_DEFAULT_TICK_RATE = 32e6; static const double B200_DEFAULT_FREQ = 100e6; // Hz diff --git a/host/lib/usrp/e100/e100_impl.cpp b/host/lib/usrp/e100/e100_impl.cpp index 8b4f2316c..ac419e0e0 100644 --- a/host/lib/usrp/e100/e100_impl.cpp +++ b/host/lib/usrp/e100/e100_impl.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -132,7 +132,7 @@ e100_impl::e100_impl(const uhd::device_addr_t &device_addr){ e100_fpga_image = find_image_path(device_addr.get("fpga", default_fpga_file_name)); } catch(...){ - UHD_MSG(error) << boost::format("Could not find FPGA image. %s\n") % print_images_error(); + UHD_MSG(error) << boost::format("Could not find FPGA image. %s\n") % print_utility_error("uhd_images_downloader.py"); throw; } e100_load_fpga(e100_fpga_image); diff --git a/host/lib/usrp/e300/e300_impl.cpp b/host/lib/usrp/e300/e300_impl.cpp index e42ac390e..8807a56e4 100644 --- a/host/lib/usrp/e300/e300_impl.cpp +++ b/host/lib/usrp/e300/e300_impl.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -397,7 +397,7 @@ e300_impl::e300_impl(const uhd::device_addr_t &device_addr) "%s" ) % fpga::COMPAT_MAJOR % _get_version(FPGA_MAJOR) % _get_version(FPGA_MINOR) - % print_images_error())); + % print_utility_error("uhd_images_downloader.py"))); } //////////////////////////////////////////////////////////////////// diff --git a/host/lib/usrp/e300/e300_network.cpp b/host/lib/usrp/e300/e300_network.cpp index 883ff0c4f..59e1eec86 100644 --- a/host/lib/usrp/e300/e300_network.cpp +++ b/host/lib/usrp/e300/e300_network.cpp @@ -33,7 +33,7 @@ #include #include -#include +#include #include #include diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp index 709092e42..dbd5408e8 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.cpp +++ b/host/lib/usrp/usrp1/usrp1_impl.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -85,7 +85,7 @@ static device_addrs_t usrp1_find(const device_addr_t &hint) usrp1_fw_image = find_image_path(hint.get("fw", "usrp1_fw.ihx")); } catch(...){ - UHD_MSG(warning) << boost::format("Could not locate USRP1 firmware. %s") % print_images_error(); + UHD_MSG(warning) << boost::format("Could not locate USRP1 firmware. %s") % print_utility_error("uhd_images_downloader.py"); } UHD_LOG << "USRP1 firmware image: " << usrp1_fw_image << std::endl; diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index b2085807f..65cf90a17 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -375,7 +375,7 @@ public: fpga_image_path = uhd::find_image_path(fpga_image); } catch(const std::exception &){ - return str(boost::format("Could not find %s and %s in your images path!\n%s") % fw_image % fpga_image % print_images_error()); + return str(boost::format("Could not find %s and %s in your images path!\n%s") % fw_image % fpga_image % print_utility_error("uhd_images_downloader.py")); } //escape char for multi-line cmd + newline + indent? @@ -389,13 +389,13 @@ public: if (this->get_rev() == USRP2_REV3 or this->get_rev() == USRP2_REV4){ const std::string card_burner = (fs::path(uhd::get_pkg_path()) / UHD_LIB_DIR / "uhd" / "utils" / "usrp2_card_burner.py").string(); const std::string card_burner_cmd = str(boost::format("\"%s%s\" %s--fpga=\"%s\" %s--fw=\"%s\"") % sudo % card_burner % ml % fpga_image_path % ml % fw_image_path); - return str(boost::format("%s\n%s") % print_images_error() % card_burner_cmd); + return str(boost::format("%s\n%s") % print_utility_error("uhd_images_downloader.py") % card_burner_cmd); } else{ const std::string addr = _ctrl_transport->get_recv_addr(); const std::string net_burner_path = (fs::path(uhd::get_pkg_path()) / UHD_LIB_DIR / "uhd" / "utils" / "usrp_n2xx_simple_net_burner").string(); const std::string net_burner_cmd = str(boost::format("\"%s\" %s--addr=\"%s\"") % net_burner_path % ml % addr); - return str(boost::format("%s\n%s") % print_images_error() % net_burner_cmd); + return str(boost::format("%s\n%s") % print_utility_error("uhd_images_downloader.py") % net_burner_cmd); } } diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index a879ae02d..8d255097d 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -24,7 +24,7 @@ #include "apply_corrections.hpp" #include #include -#include +#include #include #include #include @@ -171,7 +171,7 @@ static device_addrs_t x300_find_pcie(const device_addr_t &hint, bool explicit_qu default: continue; } - + niriok_proxy::sptr kernel_proxy = niriok_proxy::make_and_open(dev_info.interface_path); //Attempt to read the name from the EEPROM and perform filtering. @@ -1670,11 +1670,11 @@ void x300_impl::check_fw_compat(const fs_path &mb_path, wb_iface::sptr iface) if (compat_major != X300_FW_COMPAT_MAJOR) { throw uhd::runtime_error(str(boost::format( - "Expected firmware compatibility number 0x%x, but got 0x%x.%x:\n" + "Expected firmware compatibility number %d.%d, but got %d.%d:\n" "The firmware build is not compatible with the host code build.\n" "%s" - ) % int(X300_FW_COMPAT_MAJOR) % compat_major % compat_minor - % print_images_error())); + ) % int(X300_FW_COMPAT_MAJOR) % int(X300_FW_COMPAT_MINOR) + % compat_major % compat_minor % print_utility_error("uhd_images_downloader.py"))); } _tree->create(mb_path / "fw_version").set(str(boost::format("%u.%u") % compat_major % compat_minor)); @@ -1694,11 +1694,11 @@ void x300_impl::check_fpga_compat(const fs_path &mb_path, wb_iface::sptr iface) "Download 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 X3xx device using the burner utility. \n\n" + "USRP X3xx device using the burner utility. %s\n\n" "For more information, refer to the UHD manual:\n\n" " http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_flash" ) % int(X300_FPGA_COMPAT_MAJOR) % compat_major - % print_images_error())); + % print_utility_error("uhd_images_downloader.py") % print_utility_error("usrp_x3xx_fpga_burner"))); } _tree->create(mb_path / "fpga_version").set(str(boost::format("%u.%u") % compat_major % compat_minor)); diff --git a/host/lib/usrp_clock/octoclock/octoclock_impl.cpp b/host/lib/usrp_clock/octoclock/octoclock_impl.cpp index 8c207dd9f..d55fab10e 100644 --- a/host/lib/usrp_clock/octoclock/octoclock_impl.cpp +++ b/host/lib/usrp_clock/octoclock/octoclock_impl.cpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include @@ -420,7 +420,7 @@ std::string octoclock_impl::_get_images_help_message(const std::string &addr){ catch(const std::exception &e){ return str(boost::format("Could not find %s in your images path.\n%s") % image_name - % uhd::print_images_error()); + % uhd::print_utility_error("uhd_images_downloader.py")); } //Get escape character @@ -433,5 +433,5 @@ std::string octoclock_impl::_get_images_help_message(const std::string &addr){ //Get burner command const std::string burner_path = (fs::path(uhd::get_pkg_path()) / "bin" / "octoclock_firmware_burner").string(); const std::string burner_cmd = str(boost::format("%s %s--addr=\"%s\"") % burner_path % ml % addr); - return str(boost::format("%s\n%s") % uhd::print_images_error() % burner_cmd); + return str(boost::format("%s\n%s") % uhd::print_utility_error("uhd_images_downloader.py") % burner_cmd); } diff --git a/host/lib/utils/CMakeLists.txt b/host/lib/utils/CMakeLists.txt index 106e2b650..369920ac1 100644 --- a/host/lib/utils/CMakeLists.txt +++ b/host/lib/utils/CMakeLists.txt @@ -132,7 +132,6 @@ SET_SOURCE_FILES_PROPERTIES( LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/csv.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gain_group.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/images.cpp ${CMAKE_CURRENT_SOURCE_DIR}/load_modules.cpp ${CMAKE_CURRENT_SOURCE_DIR}/log.cpp ${CMAKE_CURRENT_SOURCE_DIR}/msg.cpp diff --git a/host/lib/utils/images.cpp b/host/lib/utils/images.cpp deleted file mode 100644 index 1ba2f81e6..000000000 --- a/host/lib/utils/images.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// 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 -// 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 . -// - -#include -#include -#include -#include -#include -#include -#include - -namespace fs = boost::filesystem; - -std::vector get_image_paths(void); //defined in paths.cpp - -/*********************************************************************** - * Find an image in the image paths - **********************************************************************/ -std::string uhd::find_image_path(const std::string &image_name){ - if (fs::exists(image_name)){ - return fs::system_complete(image_name).string(); - } - BOOST_FOREACH(const fs::path &path, get_image_paths()){ - fs::path image_path = path / image_name; - if (fs::exists(image_path)) return image_path.string(); - } - throw uhd::io_error("Could not find path for image: " + image_name + "\n\n" + uhd::print_images_error()); -} - -std::string uhd::find_images_downloader(void){ - return fs::path(fs::path(uhd::get_pkg_path()) / UHD_LIB_DIR / "uhd" / "utils" / "uhd_images_downloader.py").string(); -} - -std::string uhd::print_images_error(void){ - #ifdef UHD_PLATFORM_WIN32 - return "As an Administrator, please run:\n\n\"" + find_images_downloader() + "\""; - #else - return "Please run:\n\nsudo \"" + find_images_downloader() + "\""; - #endif -} diff --git a/host/lib/utils/paths.cpp b/host/lib/utils/paths.cpp index 3e2bea1c6..282ebb566 100644 --- a/host/lib/utils/paths.cpp +++ b/host/lib/utils/paths.cpp @@ -17,15 +17,19 @@ #include #include -#include + +#include +#include #include #include -#include +#include + +#include //P_tmpdir #include +#include #include #include -#include //getenv -#include //P_tmpdir + #ifdef BOOST_MSVC #define USE_GET_TEMP_PATH #include //GetTempPath @@ -136,3 +140,28 @@ std::string uhd::get_app_path(void){ return uhd::get_tmp_path(); } + +std::string uhd::find_image_path(const std::string &image_name){ + if (fs::exists(image_name)){ + return fs::system_complete(image_name).string(); + } + BOOST_FOREACH(const fs::path &path, get_image_paths()){ + fs::path image_path = path / image_name; + if (fs::exists(image_path)) return image_path.string(); + } + throw uhd::io_error("Could not find path for image: " + image_name + + "\n\n" + uhd::print_utility_error("uhd_images_downloader.py")); +} + +std::string uhd::find_utility(std::string name) { + return fs::path(fs::path(uhd::get_pkg_path()) / UHD_LIB_DIR / "uhd" / "utils" / name) + .string(); +} + +std::string uhd::print_utility_error(std::string name){ + #ifdef UHD_PLATFORM_WIN32 + return "As an Administrator, please run:\n\n\"" + find_utility(name) + "\""; + #else + return "Please run:\n\n \"" + find_utility(name) + "\""; + #endif +} diff --git a/host/utils/b2xx_fx3_utils.cpp b/host/utils/b2xx_fx3_utils.cpp index 0cab6618d..8b64be63e 100644 --- a/host/utils/b2xx_fx3_utils.cpp +++ b/host/utils/b2xx_fx3_utils.cpp @@ -39,7 +39,7 @@ #include #include #include -#include +#include namespace po = boost::program_options; namespace fs = boost::filesystem; diff --git a/host/utils/octoclock_firmware_burner.cpp b/host/utils/octoclock_firmware_burner.cpp index 9551ddd20..0a48caabd 100644 --- a/host/utils/octoclock_firmware_burner.cpp +++ b/host/utils/octoclock_firmware_burner.cpp @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include diff --git a/host/utils/usrp_n2xx_simple_net_burner.cpp b/host/utils/usrp_n2xx_simple_net_burner.cpp index dc83b6fdf..b06e67bb2 100644 --- a/host/utils/usrp_n2xx_simple_net_burner.cpp +++ b/host/utils/usrp_n2xx_simple_net_burner.cpp @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/host/utils/usrp_x3xx_fpga_burner.cpp b/host/utils/usrp_x3xx_fpga_burner.cpp index b849cfb92..abd5815e8 100644 --- a/host/utils/usrp_x3xx_fpga_burner.cpp +++ b/host/utils/usrp_x3xx_fpga_burner.cpp @@ -45,7 +45,7 @@ #include #include #include -#include +#include #include #include -- cgit v1.2.3 From 12d91d67187e72c189c42970f3bc1323c1977a4a Mon Sep 17 00:00:00 2001 From: Ashish Chaudhari Date: Fri, 5 Dec 2014 09:21:06 -0800 Subject: x300: Fixed minor issues in X300 clk code - Bugfix for #638 - get_ref_locked will check lock status one last time before giving up --- host/lib/usrp/x300/x300_impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host/lib/usrp/x300/x300_impl.cpp') diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index 8d255097d..c7980c997 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -1434,8 +1434,8 @@ bool x300_impl::wait_for_ref_locked(wb_iface::sptr ctrl, double timeout) boost::this_thread::sleep(boost::posix_time::milliseconds(1)); } while (boost::get_system_time() < timeout_time); - //failed to lock on reference - return false; + //Check one last time + return get_ref_locked(ctrl).to_bool(); } sensor_value_t x300_impl::get_ref_locked(wb_iface::sptr ctrl) -- cgit v1.2.3 From 2ce97f6c05f607846eb11e9799b5d5045049e747 Mon Sep 17 00:00:00 2001 From: Brooks Date: Fri, 19 Dec 2014 10:51:05 -0600 Subject: x300: support new 120 MHz bandwidth versions of the NI-branded X310s --- host/lib/transport/nirio/rpc/rpc_client.cpp | 2 +- host/lib/usrp/x300/x300_impl.cpp | 46 +++++---- host/lib/usrp/x300/x300_regs.hpp | 140 +++++++++++++++------------- 3 files changed, 103 insertions(+), 85 deletions(-) (limited to 'host/lib/usrp/x300/x300_impl.cpp') diff --git a/host/lib/transport/nirio/rpc/rpc_client.cpp b/host/lib/transport/nirio/rpc/rpc_client.cpp index cf8e9c1a9..48f47cfae 100644 --- a/host/lib/transport/nirio/rpc/rpc_client.cpp +++ b/host/lib/transport/nirio/rpc/rpc_client.cpp @@ -52,7 +52,7 @@ rpc_client::rpc_client ( //- address_configured: Only return addresses if a non-loopback address is configured for the system. //- numeric_host: No name resolution should be attempted for host //- numeric_service: No name resolution should be attempted for service - tcp::resolver::query::flags query_flags; + tcp::resolver::query::flags query_flags = tcp::resolver::query::passive; tcp::resolver::query query(tcp::v4(), server, port, query_flags); tcp::resolver::iterator iterator = resolver.resolve(query); diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index c7980c997..95ac3af38 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -41,7 +41,7 @@ #define NIUSRPRIO_DEFAULT_RPC_PORT "5444" -#define X300_REV(x) (x - "A" + 1) +#define X300_REV(x) ((x) - "A" + 1) using namespace uhd; using namespace uhd::usrp; @@ -1722,14 +1722,20 @@ x300_impl::x300_mboard_t x300_impl::get_mb_type_from_pcie(const std::string& res case X300_USRP_PCIE_SSID: mb_type = USRP_X300_MB; break; case X310_USRP_PCIE_SSID: - case X310_2940R_PCIE_SSID: - case X310_2942R_PCIE_SSID: - case X310_2943R_PCIE_SSID: - case X310_2944R_PCIE_SSID: - case X310_2950R_PCIE_SSID: - case X310_2952R_PCIE_SSID: - case X310_2953R_PCIE_SSID: - case X310_2954R_PCIE_SSID: + case X310_2940R_40MHz_PCIE_SSID: + case X310_2940R_120MHz_PCIE_SSID: + case X310_2942R_40MHz_PCIE_SSID: + case X310_2942R_120MHz_PCIE_SSID: + case X310_2943R_40MHz_PCIE_SSID: + case X310_2943R_120MHz_PCIE_SSID: + case X310_2944R_40MHz_PCIE_SSID: + case X310_2950R_40MHz_PCIE_SSID: + case X310_2950R_120MHz_PCIE_SSID: + case X310_2952R_40MHz_PCIE_SSID: + case X310_2952R_120MHz_PCIE_SSID: + case X310_2953R_40MHz_PCIE_SSID: + case X310_2953R_120MHz_PCIE_SSID: + case X310_2954R_40MHz_PCIE_SSID: mb_type = USRP_X310_MB; break; default: mb_type = UNKNOWN; break; @@ -1757,14 +1763,20 @@ x300_impl::x300_mboard_t x300_impl::get_mb_type_from_eeprom(const uhd::usrp::mbo case X300_USRP_PCIE_SSID: mb_type = USRP_X300_MB; break; case X310_USRP_PCIE_SSID: - case X310_2940R_PCIE_SSID: - case X310_2942R_PCIE_SSID: - case X310_2943R_PCIE_SSID: - case X310_2944R_PCIE_SSID: - case X310_2950R_PCIE_SSID: - case X310_2952R_PCIE_SSID: - case X310_2953R_PCIE_SSID: - case X310_2954R_PCIE_SSID: + case X310_2940R_40MHz_PCIE_SSID: + case X310_2940R_120MHz_PCIE_SSID: + case X310_2942R_40MHz_PCIE_SSID: + case X310_2942R_120MHz_PCIE_SSID: + case X310_2943R_40MHz_PCIE_SSID: + case X310_2943R_120MHz_PCIE_SSID: + case X310_2944R_40MHz_PCIE_SSID: + case X310_2950R_40MHz_PCIE_SSID: + case X310_2950R_120MHz_PCIE_SSID: + case X310_2952R_40MHz_PCIE_SSID: + case X310_2952R_120MHz_PCIE_SSID: + case X310_2953R_40MHz_PCIE_SSID: + case X310_2953R_120MHz_PCIE_SSID: + case X310_2954R_40MHz_PCIE_SSID: mb_type = USRP_X310_MB; break; default: UHD_MSG(warning) << "X300 unknown product code in EEPROM: " << product_num << std::endl; diff --git a/host/lib/usrp/x300/x300_regs.hpp b/host/lib/usrp/x300/x300_regs.hpp index f920b5ae2..68f438b7f 100644 --- a/host/lib/usrp/x300/x300_regs.hpp +++ b/host/lib/usrp/x300/x300_regs.hpp @@ -25,40 +25,40 @@ #define localparam static const int -localparam SR_DACSYNC = 5; -localparam SR_LOOPBACK = 6; -localparam SR_TEST = 7; -localparam SR_SPI = 8; -localparam SR_GPIO = 16; -localparam SR_MISC_OUTS = 24; -localparam SR_READBACK = 32; -localparam SR_TX_CTRL = 64; -localparam SR_RX_CTRL = 96; -localparam SR_TIME = 128; -localparam SR_RX_DSP = 144; -localparam SR_TX_DSP = 184; -localparam SR_LEDS = 195; -localparam SR_FP_GPIO = 200; -localparam SR_RX_FRONT = 208; -localparam SR_TX_FRONT = 216; - -localparam RB32_GPIO = 0; -localparam RB32_SPI = 4; -localparam RB64_TIME_NOW = 8; -localparam RB64_TIME_PPS = 16; -localparam RB32_TEST = 24; -localparam RB32_RX = 28; -localparam RB32_FP_GPIO = 32; - -localparam BL_ADDRESS = 0; -localparam BL_DATA = 1; +localparam SR_DACSYNC = 5; +localparam SR_LOOPBACK = 6; +localparam SR_TEST = 7; +localparam SR_SPI = 8; +localparam SR_GPIO = 16; +localparam SR_MISC_OUTS = 24; +localparam SR_READBACK = 32; +localparam SR_TX_CTRL = 64; +localparam SR_RX_CTRL = 96; +localparam SR_TIME = 128; +localparam SR_RX_DSP = 144; +localparam SR_TX_DSP = 184; +localparam SR_LEDS = 196; +localparam SR_FP_GPIO = 200; +localparam SR_RX_FRONT = 208; +localparam SR_TX_FRONT = 216; + +localparam RB32_GPIO = 0; +localparam RB32_SPI = 4; +localparam RB64_TIME_NOW = 8; +localparam RB64_TIME_PPS = 16; +localparam RB32_TEST = 24; +localparam RB32_RX = 28; +localparam RB32_FP_GPIO = 32; + +localparam BL_ADDRESS = 0; +localparam BL_DATA = 1; //wishbone settings map - relevant to host code -#define SET0_BASE 0xa000 -#define SETXB_BASE 0xb000 -#define BOOT_LDR_BASE 0xFA00 -#define I2C0_BASE 0xfe00 -#define I2C1_BASE 0xff00 +#define SET0_BASE 0xa000 +#define SETXB_BASE 0xb000 +#define BOOT_LDR_BASE 0xfa00 +#define I2C0_BASE 0xfe00 +#define I2C1_BASE 0xff00 #define SR_ADDR(base, offset) ((base) + (offset)*4) localparam ZPU_SR_LEDS = 00; @@ -70,56 +70,62 @@ localparam ZPU_SR_ETHINT0 = 40; localparam ZPU_SR_ETHINT1 = 56; //clock controls -#define ZPU_SR_CLOCK_CTRL_CLK_SRC_EXTERNAL 0x00 -#define ZPU_SR_CLOCK_CTRL_CLK_SRC_INTERNAL 0x02 -#define ZPU_SR_CLOCK_CTRL_CLK_SRC_GPSDO 0x03 -#define ZPU_SR_CLOCK_CTRL_PPS_SRC_EXTERNAL 0x00 -#define ZPU_SR_CLOCK_CTRL_PPS_SRC_INTERNAL 0x02 -#define ZPU_SR_CLOCK_CTRL_PPS_SRC_GPSDO 0x03 - -localparam ZPU_RB_SPI = 2; +#define ZPU_SR_CLOCK_CTRL_CLK_SRC_EXTERNAL 0x00 +#define ZPU_SR_CLOCK_CTRL_CLK_SRC_INTERNAL 0x02 +#define ZPU_SR_CLOCK_CTRL_CLK_SRC_GPSDO 0x03 +#define ZPU_SR_CLOCK_CTRL_PPS_SRC_EXTERNAL 0x00 +#define ZPU_SR_CLOCK_CTRL_PPS_SRC_INTERNAL 0x02 +#define ZPU_SR_CLOCK_CTRL_PPS_SRC_GPSDO 0x03 + +localparam ZPU_RB_SPI = 2; localparam ZPU_RB_CLK_STATUS = 3; localparam ZPU_RB_COMPAT_NUM = 6; localparam ZPU_RB_ETH_TYPE0 = 4; localparam ZPU_RB_ETH_TYPE1 = 5; //clock status -#define ZPU_RB_CLK_STATUS_LMK_STATUS (0x3 << 0) -#define ZPU_RB_CLK_STATUS_LMK_LOCK (0x1 << 2) -#define ZPU_RB_CLK_STATUS_LMK_HOLDOVER (0x1 << 3) -#define ZPU_RB_CLK_STATUS_PPS_DETECT (0x1 << 4) +#define ZPU_RB_CLK_STATUS_LMK_STATUS (0x3 << 0) +#define ZPU_RB_CLK_STATUS_LMK_LOCK (0x1 << 2) +#define ZPU_RB_CLK_STATUS_LMK_HOLDOVER (0x1 << 3) +#define ZPU_RB_CLK_STATUS_PPS_DETECT (0x1 << 4) //spi slaves on radio -#define DB_DAC_SEN (1 << 7) -#define DB_ADC_SEN (1 << 6) +#define DB_DAC_SEN (1 << 7) +#define DB_ADC_SEN (1 << 6) #define DB_RX_LSADC_SEN (1 << 5) #define DB_RX_LSDAC_SEN (1 << 4) #define DB_TX_LSADC_SEN (1 << 3) #define DB_TX_LSDAC_SEN (1 << 2) -#define DB_RX_SEN (1 << 1) -#define DB_TX_SEN (1 << 0) +#define DB_RX_SEN (1 << 1) +#define DB_TX_SEN (1 << 0) //------------------------------------------------------------------- // PCIe Registers //------------------------------------------------------------------- -static const uint32_t X300_PCIE_VID = 0x1093; -static const uint32_t X300_PCIE_PID = 0xC4C4; -static const uint32_t X300_USRP_PCIE_SSID = 0x7736; -static const uint32_t X310_USRP_PCIE_SSID = 0x76CA; -static const uint32_t X310_2940R_PCIE_SSID = 0x772B; -static const uint32_t X310_2942R_PCIE_SSID = 0x772C; -static const uint32_t X310_2943R_PCIE_SSID = 0x772D; -static const uint32_t X310_2944R_PCIE_SSID = 0x772E; -static const uint32_t X310_2950R_PCIE_SSID = 0x772F; -static const uint32_t X310_2952R_PCIE_SSID = 0x7730; -static const uint32_t X310_2953R_PCIE_SSID = 0x7731; -static const uint32_t X310_2954R_PCIE_SSID = 0x7732; +static const uint32_t X300_PCIE_VID = 0x1093; +static const uint32_t X300_PCIE_PID = 0xC4C4; +static const uint32_t X300_USRP_PCIE_SSID = 0x7736; +static const uint32_t X310_USRP_PCIE_SSID = 0x76CA; +static const uint32_t X310_2940R_40MHz_PCIE_SSID = 0x772B; +static const uint32_t X310_2940R_120MHz_PCIE_SSID = 0x77FB; +static const uint32_t X310_2942R_40MHz_PCIE_SSID = 0x772C; +static const uint32_t X310_2942R_120MHz_PCIE_SSID = 0x77FC; +static const uint32_t X310_2943R_40MHz_PCIE_SSID = 0x772D; +static const uint32_t X310_2943R_120MHz_PCIE_SSID = 0x77FD; +static const uint32_t X310_2944R_40MHz_PCIE_SSID = 0x772E; +static const uint32_t X310_2950R_40MHz_PCIE_SSID = 0x772F; +static const uint32_t X310_2950R_120MHz_PCIE_SSID = 0x77FE; +static const uint32_t X310_2952R_40MHz_PCIE_SSID = 0x7730; +static const uint32_t X310_2952R_120MHz_PCIE_SSID = 0x77FF; +static const uint32_t X310_2953R_40MHz_PCIE_SSID = 0x7731; +static const uint32_t X310_2953R_120MHz_PCIE_SSID = 0x7800; +static const uint32_t X310_2954R_40MHz_PCIE_SSID = 0x7732; static const uint32_t FPGA_X3xx_SIG_VALUE = 0x58333030; static const uint32_t PCIE_FPGA_ADDR_BASE = 0xC0000; -#define PCIE_FPGA_REG(X) (PCIE_FPGA_ADDR_BASE + X) +#define PCIE_FPGA_REG(X) (PCIE_FPGA_ADDR_BASE + (X)) static const uint32_t FPGA_PCIE_SIG_REG = PCIE_FPGA_REG(0x0000); static const uint32_t FPGA_CNTR_LO_REG = PCIE_FPGA_REG(0x0004); @@ -140,8 +146,8 @@ static const uint32_t DMA_FRAME_SIZE_REG = 0x4; static const uint32_t DMA_SAMPLE_COUNT_REG = 0x8; static const uint32_t DMA_PKT_COUNT_REG = 0xC; -#define PCIE_TX_DMA_REG(REG, CHAN) (PCIE_TX_DMA_REG_BASE + (CHAN*DMA_REG_GRP_SIZE) + REG) -#define PCIE_RX_DMA_REG(REG, CHAN) (PCIE_RX_DMA_REG_BASE + (CHAN*DMA_REG_GRP_SIZE) + REG) +#define PCIE_TX_DMA_REG(REG, CHAN) (PCIE_TX_DMA_REG_BASE + ((CHAN)*DMA_REG_GRP_SIZE) + (REG)) +#define PCIE_RX_DMA_REG(REG, CHAN) (PCIE_RX_DMA_REG_BASE + ((CHAN)*DMA_REG_GRP_SIZE) + (REG)) static const uint32_t DMA_CTRL_DISABLED = 0x00000000; static const uint32_t DMA_CTRL_ENABLED = 0x00000002; @@ -154,15 +160,15 @@ static const uint32_t DMA_STATUS_ERROR = 0x00000001; static const uint32_t DMA_STATUS_BUSY = 0x00000002; static const uint32_t PCIE_ROUTER_REG_BASE = PCIE_FPGA_REG(0x0500); -#define PCIE_ROUTER_REG(X) (PCIE_ROUTER_REG_BASE + X) +#define PCIE_ROUTER_REG(X) (PCIE_ROUTER_REG_BASE + (X)) static const uint32_t PCIE_ZPU_DATA_BASE = 0x30000; static const uint32_t PCIE_ZPU_READ_BASE = 0x20000; //Trig and Status share the same base static const uint32_t PCIE_ZPU_STATUS_BASE = 0x20000; -#define PCIE_ZPU_DATA_REG(X) (PCIE_FPGA_REG(PCIE_ZPU_DATA_BASE) + X) -#define PCIE_ZPU_READ_REG(X) (PCIE_FPGA_REG(PCIE_ZPU_READ_BASE) + X) -#define PCIE_ZPU_STATUS_REG(X) (PCIE_FPGA_REG(PCIE_ZPU_STATUS_BASE) + X) +#define PCIE_ZPU_DATA_REG(X) (PCIE_FPGA_REG(PCIE_ZPU_DATA_BASE) + (X)) +#define PCIE_ZPU_READ_REG(X) (PCIE_FPGA_REG(PCIE_ZPU_READ_BASE) + (X)) +#define PCIE_ZPU_STATUS_REG(X) (PCIE_FPGA_REG(PCIE_ZPU_STATUS_BASE) + (X)) static const uint32_t PCIE_ZPU_READ_START = 0x0; static const uint32_t PCIE_ZPU_READ_CLOBBER = 0x80000000; -- cgit v1.2.3 From d9241b78d32402093c37ab7ce2f4336699219ed4 Mon Sep 17 00:00:00 2001 From: Ian Buckley Date: Mon, 9 Mar 2015 11:20:56 -0700 Subject: B200: UHD support for FPGPIO connector on REV6+ boards. - GPIO on UART connector all board Revs - Consolidated fpgpio_bitbang into fpgpio example and renamed it gpio - Changed FP_GPIO readback address to match X300 --- host/examples/CMakeLists.txt | 2 +- host/examples/fpgpio.cpp | 418 ------------------------------ host/examples/gpio.cpp | 462 ++++++++++++++++++++++++++++++++++ host/lib/usrp/b200/b200_impl.cpp | 35 ++- host/lib/usrp/b200/b200_impl.hpp | 7 +- host/lib/usrp/b200/b200_regs.hpp | 2 + host/lib/usrp/cores/gpio_core_200.hpp | 9 +- host/lib/usrp/e300/e300_impl.cpp | 34 +-- host/lib/usrp/e300/e300_impl.hpp | 6 +- host/lib/usrp/x300/x300_impl.cpp | 35 +-- host/lib/usrp/x300/x300_impl.hpp | 6 +- 11 files changed, 555 insertions(+), 461 deletions(-) delete mode 100644 host/examples/fpgpio.cpp create mode 100644 host/examples/gpio.cpp (limited to 'host/lib/usrp/x300/x300_impl.cpp') diff --git a/host/examples/CMakeLists.txt b/host/examples/CMakeLists.txt index 598e42302..92947d86c 100644 --- a/host/examples/CMakeLists.txt +++ b/host/examples/CMakeLists.txt @@ -35,7 +35,7 @@ SET(example_sources tx_waveforms.cpp txrx_loopback_to_file.cpp latency_test.cpp - fpgpio.cpp + gpio.cpp ) IF(ENABLE_OCTOCLOCK) diff --git a/host/examples/fpgpio.cpp b/host/examples/fpgpio.cpp deleted file mode 100644 index c57893669..000000000 --- a/host/examples/fpgpio.cpp +++ /dev/null @@ -1,418 +0,0 @@ -// -// Copyright 2014 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 . -// - -// Example for front panel GPIO. -// Bits are set as follows: -// FPGPIO[0] = ATR output 1 at idle -// FPGPIO[1] = ATR output 1 during RX -// FPGPIO[2] = ATR output 1 during TX -// FPGPIO[3] = ATR output 1 during full duplex -// FPGPIO[4] = output -// FPGPIO[5] = input -// FPGPIO[6] = input (X series only) -// FPGPIO[7] = input (X series only) -// FPGPIO[8] = input (X series only) -// FPGPIO[9] = input (X series only) -// FPGPIO[10] = input (X series only) -// The example cycles through idle, TX, RX, and full duplex, spending 2 seconds for each. -// Outputs can be physically looped back to inputs for verification testing. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const std::string FPGPIO_DEFAULT_CPU_FORMAT = "fc32"; -static const std::string FPGPIO_DEFAULT_OTW_FORMAT = "sc16"; -static const double FPGPIO_DEFAULT_RX_RATE = 500e3; -static const double FPGPIO_DEFAULT_TX_RATE = 500e3; -static const double FPGPIO_DEFAULT_DWELL_TIME = 2.0; -static const std::string FPGPIO_DEFAULT_GPIO = "FP0"; -static const size_t FPGPIO_DEFAULT_NUM_BITS = 11; - -static UHD_INLINE boost::uint32_t FPGPIO_BIT(const size_t x) -{ - return (1 << x); -} - -namespace po = boost::program_options; - -static bool stop_signal_called = false; -void sig_int_handler(int){stop_signal_called = true;} - -std::string to_bit_string(boost::uint32_t val, const size_t num_bits) -{ - std::string out; - for (int i = num_bits - 1; i >= 0; i--) - { - std::string bit = ((val >> i) & 1) ? "1" : "0"; - out += " "; - out += bit; - } - return out; -} - -void output_reg_values( - const std::string bank, - const uhd::usrp::multi_usrp::sptr &usrp, - const size_t num_bits) -{ - std::cout << (boost::format("Bit ")); - for (int i = num_bits - 1; i >= 0; i--) - std::cout << (boost::format(" %s%d") % (i < 10 ? " " : "") % i); - std::cout << std::endl; - std::cout << "CTRL: " << to_bit_string( - boost::uint32_t(usrp->get_gpio_attr(bank, std::string("CTRL"))), - num_bits) - << std::endl; - - std::cout << "DDR: " << to_bit_string( - boost::uint32_t(usrp->get_gpio_attr(bank, std::string("DDR"))), - num_bits) - << std::endl; - - std::cout << "ATR_0X: " << to_bit_string( - boost::uint32_t(usrp->get_gpio_attr(bank, std::string("ATR_0X"))), - num_bits) - << std::endl; - - std::cout << "ATR_RX: " << to_bit_string( - boost::uint32_t(usrp->get_gpio_attr(bank, std::string("ATR_RX"))), - num_bits) - << std::endl; - - std::cout << "ATR_TX: " << to_bit_string( - boost::uint32_t(usrp->get_gpio_attr(bank, std::string("ATR_TX"))), - num_bits) - << std::endl; - - std::cout << "ATR_XX: " << to_bit_string( - boost::uint32_t(usrp->get_gpio_attr(bank, std::string("ATR_XX"))), - num_bits) - << std::endl; - - std::cout << "OUT: " << to_bit_string( - boost::uint32_t(usrp->get_gpio_attr(bank, std::string("OUT"))), - num_bits) - << std::endl; - - std::cout << "READBACK: " << to_bit_string( - boost::uint32_t(usrp->get_gpio_attr(bank, std::string("READBACK"))), - num_bits) - << std::endl; -} - -int UHD_SAFE_MAIN(int argc, char *argv[]) -{ - uhd::set_thread_priority_safe(); - - //variables to be set by po - std::string args; - std::string cpu, otw; - double rx_rate, tx_rate, dwell; - std::string fpgpio; - size_t num_bits; - - //setup the program options - po::options_description desc("Allowed options"); - desc.add_options() - ("help", "help message") - ("args", po::value(&args)->default_value(""), "multi uhd device address args") - ("repeat", "repeat loop until Ctrl-C is pressed") - ("cpu", po::value(&cpu)->default_value(FPGPIO_DEFAULT_CPU_FORMAT), "cpu data format") - ("otw", po::value(&otw)->default_value(FPGPIO_DEFAULT_OTW_FORMAT), "over the wire data format") - ("rx_rate", po::value(&rx_rate)->default_value(FPGPIO_DEFAULT_RX_RATE), "rx sample rate") - ("tx_rate", po::value(&tx_rate)->default_value(FPGPIO_DEFAULT_TX_RATE), "tx sample rate") - ("dwell", po::value(&dwell)->default_value(FPGPIO_DEFAULT_DWELL_TIME), "dwell time in seconds for each test case") - ("gpio", po::value(&fpgpio)->default_value(FPGPIO_DEFAULT_GPIO), "name of gpio bank") - ("bits", po::value(&num_bits)->default_value(FPGPIO_DEFAULT_NUM_BITS), "number of bits in gpio bank") - ; - po::variables_map vm; - po::store(po::parse_command_line(argc, argv, desc), vm); - po::notify(vm); - - //print the help message - if (vm.count("help")){ - std::cout << boost::format("Front Panel GPIO %s") % desc << std::endl; - return ~0; - } - - //create a usrp device - std::cout << std::endl; - std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; - uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); - std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; - - //print out initial unconfigured state of FP GPIO - std::cout << "Unconfigured GPIO values:" << std::endl; - output_reg_values(fpgpio, usrp, num_bits); - - //configure GPIO registers - boost::uint32_t ctrl = 0; // default all as manual - boost::uint32_t ddr = 0; // default all as input - boost::uint32_t atr_idle = 0; - boost::uint32_t atr_rx = 0; - boost::uint32_t atr_tx = 0; - boost::uint32_t atr_duplex = 0; - boost::uint32_t mask = 0x7ff; - - //set up FPGPIO outputs: - //FPGPIO[0] = ATR output 1 at idle - ctrl |= FPGPIO_BIT(0); - atr_idle |= FPGPIO_BIT(0); - ddr |= FPGPIO_BIT(0); - - //FPGPIO[1] = ATR output 1 during RX - ctrl |= FPGPIO_BIT(1); - ddr |= FPGPIO_BIT(1); - atr_rx |= FPGPIO_BIT(1); - - //FPGPIO[2] = ATR output 1 during TX - ctrl |= FPGPIO_BIT(2); - ddr |= FPGPIO_BIT(2); - atr_tx |= FPGPIO_BIT(2); - - //FPGPIO[3] = ATR output 1 during full duplex - ctrl |= FPGPIO_BIT(3); - ddr |= FPGPIO_BIT(3); - atr_duplex |= FPGPIO_BIT(3); - - //FPGPIO[4] = output - ddr |= FPGPIO_BIT(4); - - //set data direction register (DDR) - usrp->set_gpio_attr(fpgpio, std::string("DDR"), ddr, mask); - - //set ATR registers - usrp->set_gpio_attr(fpgpio, std::string("ATR_0X"), atr_idle, mask); - usrp->set_gpio_attr(fpgpio, std::string("ATR_RX"), atr_rx, mask); - usrp->set_gpio_attr(fpgpio, std::string("ATR_TX"), atr_tx, mask); - usrp->set_gpio_attr(fpgpio, std::string("ATR_XX"), atr_duplex, mask); - - //set control register - usrp->set_gpio_attr(fpgpio, std::string("CTRL"), ctrl, mask); - - //print out initial state of FP GPIO - std::cout << "\nConfigured GPIO values:" << std::endl; - output_reg_values(fpgpio, usrp, num_bits); - std::cout << std::endl; - - //set up streams - uhd::stream_args_t rx_args(cpu, otw); - uhd::stream_args_t tx_args(cpu, otw); - uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(rx_args); - uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(tx_args); - uhd::stream_cmd_t rx_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); - rx_cmd.stream_now = true; - usrp->set_rx_rate(rx_rate); - usrp->set_tx_rate(tx_rate); - - //set up buffers for tx and rx - const size_t max_samps_per_packet = rx_stream->get_max_num_samps(); - const size_t nsamps_per_buff = max_samps_per_packet; - std::vector rx_buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(cpu)); - std::vector tx_buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(cpu)); - std::vector rx_buffs, tx_buffs; - for (size_t ch = 0; ch < rx_stream->get_num_channels(); ch++) - rx_buffs.push_back(&rx_buff.front()); //same buffer for each channel - for (size_t ch = 0; ch < tx_stream->get_num_channels(); ch++) - tx_buffs.push_back(&tx_buff.front()); //same buffer for each channel - - uhd::rx_metadata_t rx_md; - uhd::tx_metadata_t tx_md; - tx_md.has_time_spec = false; - tx_md.start_of_burst = true; - uhd::time_spec_t stop_time; - double timeout = 0.01; - uhd::time_spec_t dwell_time(dwell); - int loop = 0; - boost::uint32_t rb, expected; - - //register singal handler - std::signal(SIGINT, &sig_int_handler); - - //Test the mask - only need to test once with no dwell time - std::cout << "\nTesting mask..." << std::flush; - //send a value of all 1's to the DDR with a mask for only bit 10 - usrp->set_gpio_attr(fpgpio, std::string("DDR"), ~0, FPGPIO_BIT(10)); - //bit 10 should now be 1, but all the other bits should be unchanged - rb = usrp->get_gpio_attr(fpgpio, std::string("DDR")) & mask; - expected = ddr | FPGPIO_BIT(10); - if (rb == expected) - std::cout << "pass" << std::endl; - else - std::cout << "fail" << std::endl; - std::cout << std::endl; - output_reg_values(fpgpio, usrp, num_bits); - usrp->set_gpio_attr(fpgpio, std::string("DDR"), ddr, mask); - - while (not stop_signal_called) - { - int failures = 0; - - if (vm.count("repeat")) - std::cout << "Press Ctrl + C to quit..." << std::endl; - - // test user controlled GPIO and ATR idle by setting bit 4 high for 1 second - std::cout << "\nTesting user controlled GPIO and ATR idle output..." << std::flush; - usrp->set_gpio_attr(fpgpio, "OUT", 1 << 4, 1 << 4); - stop_time = usrp->get_time_now() + dwell_time; - while (not stop_signal_called and usrp->get_time_now() < stop_time) - { - boost::this_thread::sleep(boost::posix_time::milliseconds(100)); - } - rb = usrp->get_gpio_attr(fpgpio, "READBACK"); - expected = FPGPIO_BIT(4) | FPGPIO_BIT(0); - if ((rb & expected) != expected) - { - ++failures; - std::cout << "fail" << std::endl; - if ((rb & FPGPIO_BIT(0)) == 0) - std::cout << "Bit 0 should be set, but is not" << std::endl; - if ((rb & FPGPIO_BIT(4)) == 0) - std::cout << "Bit 4 should be set, but is not" << std::endl; - } else { - std::cout << "pass" << std::endl; - } - std::cout << std::endl; - output_reg_values(fpgpio, usrp, num_bits); - usrp->set_gpio_attr(fpgpio, "OUT", 0, FPGPIO_BIT(4)); - if (stop_signal_called) - break; - - // test ATR RX by receiving for 1 second - std::cout << "\nTesting ATR RX output..." << std::flush; - rx_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; - rx_stream->issue_stream_cmd(rx_cmd); - stop_time = usrp->get_time_now() + dwell_time; - while (not stop_signal_called and usrp->get_time_now() < stop_time) - { - try { - rx_stream->recv(rx_buffs, nsamps_per_buff, rx_md, timeout); - } catch(...){} - } - rb = usrp->get_gpio_attr(fpgpio, "READBACK"); - expected = FPGPIO_BIT(1); - if ((rb & expected) != expected) - { - ++failures; - std::cout << "fail" << std::endl; - std::cout << "Bit 1 should be set, but is not" << std::endl; - } else { - std::cout << "pass" << std::endl; - } - std::cout << std::endl; - output_reg_values(fpgpio, usrp, num_bits); - rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); - //clear out any data left in the rx stream - try { - rx_stream->recv(rx_buffs, nsamps_per_buff, rx_md, timeout); - } catch(...){} - if (stop_signal_called) - break; - - // test ATR TX by transmitting for 1 second - std::cout << "\nTesting ATR TX output..." << std::flush; - stop_time = usrp->get_time_now() + dwell_time; - tx_md.start_of_burst = true; - tx_md.end_of_burst = false; - while (not stop_signal_called and usrp->get_time_now() < stop_time) - { - try { - tx_stream->send(tx_buffs, nsamps_per_buff, tx_md, timeout); - tx_md.start_of_burst = false; - } catch(...){} - } - rb = usrp->get_gpio_attr(fpgpio, "READBACK"); - expected = FPGPIO_BIT(2); - if ((rb & expected) != expected) - { - ++failures; - std::cout << "fail" << std::endl; - std::cout << "Bit 2 should be set, but is not" << std::endl; - } else { - std::cout << "pass" << std::endl; - } - std::cout << std::endl; - output_reg_values(fpgpio, usrp, num_bits); - tx_md.end_of_burst = true; - try { - tx_stream->send(tx_buffs, nsamps_per_buff, tx_md, timeout); - } catch(...){} - if (stop_signal_called) - break; - - // test ATR RX by transmitting and receiving for 1 second - std::cout << "\nTesting ATR full duplex output..." << std::flush; - rx_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; - rx_stream->issue_stream_cmd(rx_cmd); - tx_md.start_of_burst = true; - tx_md.end_of_burst = false; - stop_time = usrp->get_time_now() + dwell_time; - while (not stop_signal_called and usrp->get_time_now() < stop_time) - { - try { - tx_stream->send(rx_buffs, nsamps_per_buff, tx_md, timeout); - tx_md.start_of_burst = false; - rx_stream->recv(tx_buffs, nsamps_per_buff, rx_md, timeout); - } catch(...){} - } - rb = usrp->get_gpio_attr(fpgpio, "READBACK"); - expected = FPGPIO_BIT(3); - if ((rb & expected) != expected) - { - ++failures; - std::cout << "fail" << std::endl; - std::cout << "Bit 3 should be set, but is not" << std::endl; - } else { - std::cout << "pass" << std::endl; - } - std::cout << std::endl; - output_reg_values(fpgpio, usrp, num_bits); - rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); - tx_md.end_of_burst = true; - try { - tx_stream->send(tx_buffs, nsamps_per_buff, tx_md, timeout); - } catch(...){} - //clear out any data left in the rx stream - try { - rx_stream->recv(rx_buffs, nsamps_per_buff, rx_md, timeout); - } catch(...){} - - std::cout << std::endl; - if (failures) - std::cout << failures << " tests failed" << std::endl; - else - std::cout << "All tests passed!" << std::endl; - - if (!vm.count("repeat")) - break; - - std::cout << (boost::format("\nLoop %d completed") % ++loop) << std::endl; - } - - //finished - std::cout << std::endl << "Done!" << std::endl << std::endl; - - return EXIT_SUCCESS; -} diff --git a/host/examples/gpio.cpp b/host/examples/gpio.cpp new file mode 100644 index 000000000..b0d15f35a --- /dev/null +++ b/host/examples/gpio.cpp @@ -0,0 +1,462 @@ +// +// Copyright 2014-15 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 . +// + +// Example for GPIO testing and bit banging. +// +// This example was originally designed to test the 11 bit wide front panel +// GPIO on the X300 series and has since been adapted to work with any GPIO +// bank on any USRP and provide optional bit banging. Please excuse the +// clutter. Also, there is no current way to detect the width of the +// specified GPIO bank, so the user must specify the width with the --bits +// flag if more than 11 bits. +// +// GPIO Testing: +// For testing, GPIO bits are set as follows: +// GPIO[0] = ATR output 1 at idle +// GPIO[1] = ATR output 1 during RX +// GPIO[2] = ATR output 1 during TX +// GPIO[3] = ATR output 1 during full duplex +// GPIO[4] = output +// GPIO[n:5] = input (all other pins) +// The testing cycles through idle, TX, RX, and full duplex, dwelling on each +// test case (default 2 seconds), and then comparing the readback register with +// the expected values of the outputs for verification. The values of all GPIO +// registers are displayed at the end of each test case. Outputs can be +// physically looped back to inputs to manually verify the inputs. +// +// GPIO Bit Banging: +// GPIO banks have the standard registers of DDR for data direction and OUT +// for output values. Users can bit bang the GPIO bits by using this example +// with the --bitbang flag and specifying the --ddr and --out flags to set the +// values of the corresponding registers. The READBACK register is +// continuously read for the duration of the dwell time (default 2 seconds) so +// users can monitor changes on the inputs. +// +// Automatic Transmit/Receive (ATR): +// In addition to the standard DDR and OUT registers, the GPIO banks also +// have ATR (Automatic Transmit/Receive) control registers that allow the +// GPIO pins to be automatically set to specific values when the USRP is +// idle, transmitting, receiving, or operating in full duplex mode. The +// description of these registers is below: +// CTRL - Control (0=manual, 1=ATR) +// ATR_0X - Values to be set when idle +// ATR_RX - Output values to be set when receiving +// ATR_TX - Output values to be set when transmitting +// ATR_XX - Output values to be set when operating in full duplex +// This code below contains examples of setting all these registers. On +// devices with multiple radios, the ATR for the front panel GPIO is driven +// by the state of the first radio (0 or A). +// +// The UHD API +// The multi_usrp::set_gpio_attr() method is the UHD API for configuring and +// controlling the GPIO banks. The parameters to the method are: +// bank - the name of the GPIO bank (typically "FP0" for front panel GPIO, +// "TX" for TX daughter card GPIO, or +// "RX" for RX daughter card GPIO) +// attr - attribute (register) to change ("DDR", "OUT", "CTRL", "ATR_0X", +// "ATR_RX", "ATR_TX", "ATR_XX") +// value - the value to be set +// mask - a mask indicating which bits in the specified attribute register are +// to be changed (default is all bits). + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const std::string GPIO_DEFAULT_CPU_FORMAT = "fc32"; +static const std::string GPIO_DEFAULT_OTW_FORMAT = "sc16"; +static const double GPIO_DEFAULT_RX_RATE = 500e3; +static const double GPIO_DEFAULT_TX_RATE = 500e3; +static const double GPIO_DEFAULT_DWELL_TIME = 2.0; +static const std::string GPIO_DEFAULT_GPIO = "FP0"; +static const size_t GPIO_DEFAULT_NUM_BITS = 11; +static const std::string GPIO_DEFAULT_CTRL = "0x0"; // all as user controlled +static const std::string GPIO_DEFAULT_DDR = "0x0"; // all as inputs +static const std::string GPIO_DEFAULT_OUT = "0x0"; + +static UHD_INLINE boost::uint32_t GPIO_BIT(const size_t x) +{ + return (1 << x); +} + +namespace po = boost::program_options; + +static bool stop_signal_called = false; +void sig_int_handler(int){stop_signal_called = true;} + +std::string to_bit_string(boost::uint32_t val, const size_t num_bits) +{ + std::string out; + for (int i = num_bits - 1; i >= 0; i--) + { + std::string bit = ((val >> i) & 1) ? "1" : "0"; + out += " "; + out += bit; + } + return out; +} + +void output_reg_values( + const std::string bank, + const uhd::usrp::multi_usrp::sptr &usrp, + const size_t num_bits) +{ + std::vector attrs = boost::assign::list_of("CTRL")("DDR")("ATR_0X")("ATR_RX")("ATR_TX")("ATR_XX")("OUT")("READBACK"); + std::cout << (boost::format("%10s ") % "Bit"); + for (int i = num_bits - 1; i >= 0; i--) + std::cout << (boost::format(" %2d") % i); + std::cout << std::endl; + BOOST_FOREACH(std::string &attr, attrs) + { + std::cout << (boost::format("%10s:%s") + % attr % to_bit_string(boost::uint32_t(usrp->get_gpio_attr(bank, attr)), num_bits)) + << std::endl; + } +} + +int UHD_SAFE_MAIN(int argc, char *argv[]) +{ + uhd::set_thread_priority_safe(); + + //variables to be set by po + std::string args; + std::string cpu, otw; + double rx_rate, tx_rate, dwell; + std::string gpio; + size_t num_bits; + std::string ctrl_str; + std::string ddr_str; + std::string out_str; + + //setup the program options + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("args", po::value(&args)->default_value(""), "multi uhd device address args") + ("repeat", "repeat loop until Ctrl-C is pressed") + ("cpu", po::value(&cpu)->default_value(GPIO_DEFAULT_CPU_FORMAT), "cpu data format") + ("otw", po::value(&otw)->default_value(GPIO_DEFAULT_OTW_FORMAT), "over the wire data format") + ("rx_rate", po::value(&rx_rate)->default_value(GPIO_DEFAULT_RX_RATE), "rx sample rate") + ("tx_rate", po::value(&tx_rate)->default_value(GPIO_DEFAULT_TX_RATE), "tx sample rate") + ("dwell", po::value(&dwell)->default_value(GPIO_DEFAULT_DWELL_TIME), "dwell time in seconds for each test case") + ("bank", po::value(&gpio)->default_value(GPIO_DEFAULT_GPIO), "name of gpio bank") + ("bits", po::value(&num_bits)->default_value(GPIO_DEFAULT_NUM_BITS), "number of bits in gpio bank") + ("bitbang", "single test case where user sets values for CTRL, DDR, and OUT registers") + ("ddr", po::value(&ddr_str)->default_value(GPIO_DEFAULT_DDR), "GPIO DDR reg value") + ("out", po::value(&out_str)->default_value(GPIO_DEFAULT_OUT), "GPIO OUT reg value") + ; + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help")){ + std::cout << boost::format("gpio %s") % desc << std::endl; + return ~0; + } + + //create a usrp device + std::cout << std::endl; + std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; + uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); + std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; + + //print out initial unconfigured state of FP GPIO + std::cout << "Initial GPIO values:" << std::endl; + output_reg_values(gpio, usrp, num_bits); + + //configure GPIO registers + boost::uint32_t ddr = strtoul(ddr_str.c_str(), NULL, 0); + boost::uint32_t out = strtoul(out_str.c_str(), NULL, 0); + boost::uint32_t ctrl = 0; + boost::uint32_t atr_idle = 0; + boost::uint32_t atr_rx = 0; + boost::uint32_t atr_tx = 0; + boost::uint32_t atr_duplex = 0; + boost::uint32_t mask = (1 << num_bits) - 1; + + if (!vm.count("bitbang")) + { + //set up GPIO outputs: + //GPIO[0] = ATR output 1 at idle + ctrl |= GPIO_BIT(0); + atr_idle |= GPIO_BIT(0); + ddr |= GPIO_BIT(0); + + //GPIO[1] = ATR output 1 during RX + ctrl |= GPIO_BIT(1); + ddr |= GPIO_BIT(1); + atr_rx |= GPIO_BIT(1); + + //GPIO[2] = ATR output 1 during TX + ctrl |= GPIO_BIT(2); + ddr |= GPIO_BIT(2); + atr_tx |= GPIO_BIT(2); + + //GPIO[3] = ATR output 1 during full duplex + ctrl |= GPIO_BIT(3); + ddr |= GPIO_BIT(3); + atr_duplex |= GPIO_BIT(3); + + //GPIO[4] = output + ddr |= GPIO_BIT(4); + } + + //set data direction register (DDR) + usrp->set_gpio_attr(gpio, "DDR", ddr, mask); + + //set output values (OUT) + usrp->set_gpio_attr(gpio, "OUT", out, mask); + + //set ATR registers + usrp->set_gpio_attr(gpio, "ATR_0X", atr_idle, mask); + usrp->set_gpio_attr(gpio, "ATR_RX", atr_rx, mask); + usrp->set_gpio_attr(gpio, "ATR_TX", atr_tx, mask); + usrp->set_gpio_attr(gpio, "ATR_XX", atr_duplex, mask); + + //set control register + usrp->set_gpio_attr(gpio, "CTRL", ctrl, mask); + + //print out initial state of FP GPIO + std::cout << "\nConfigured GPIO values:" << std::endl; + output_reg_values(gpio, usrp, num_bits); + std::cout << std::endl; + + //set up streams + uhd::stream_args_t rx_args(cpu, otw); + uhd::stream_args_t tx_args(cpu, otw); + uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(rx_args); + uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(tx_args); + uhd::stream_cmd_t rx_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); + rx_cmd.stream_now = true; + usrp->set_rx_rate(rx_rate); + usrp->set_tx_rate(tx_rate); + + //set up buffers for tx and rx + const size_t max_samps_per_packet = rx_stream->get_max_num_samps(); + const size_t nsamps_per_buff = max_samps_per_packet; + std::vector rx_buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(cpu)); + std::vector tx_buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(cpu)); + std::vector rx_buffs, tx_buffs; + for (size_t ch = 0; ch < rx_stream->get_num_channels(); ch++) + rx_buffs.push_back(&rx_buff.front()); //same buffer for each channel + for (size_t ch = 0; ch < tx_stream->get_num_channels(); ch++) + tx_buffs.push_back(&tx_buff.front()); //same buffer for each channel + + uhd::rx_metadata_t rx_md; + uhd::tx_metadata_t tx_md; + tx_md.has_time_spec = false; + tx_md.start_of_burst = true; + uhd::time_spec_t stop_time; + double timeout = 0.01; + uhd::time_spec_t dwell_time(dwell); + int loop = 0; + boost::uint32_t rb, expected; + + //register signal handler + std::signal(SIGINT, &sig_int_handler); + + if (!vm.count("bitbang")) + { + // Test the mask parameter of the multi_usrp::set_gpio_attr API + // We only need to test once with no dwell time + std::cout << "\nTesting mask..." << std::flush; + //send a value of all 1's to the DDR with a mask for only upper most bit + usrp->set_gpio_attr(gpio, "DDR", ~0, GPIO_BIT(num_bits - 1)); + //upper most bit should now be 1, but all the other bits should be unchanged + rb = usrp->get_gpio_attr(gpio, "DDR") & mask; + expected = ddr | GPIO_BIT(num_bits - 1); + if (rb == expected) + std::cout << "pass:" << std::endl; + else + std::cout << "fail:" << std::endl; + output_reg_values(gpio, usrp, num_bits); + //restore DDR value + usrp->set_gpio_attr(gpio, "DDR", ddr, mask); + } + + while (not stop_signal_called) + { + int failures = 0; + + if (vm.count("repeat")) + std::cout << "Press Ctrl + C to quit..." << std::endl; + + if (vm.count("bitbang")) + { + // dwell and continuously read back GPIO values + stop_time = usrp->get_time_now() + dwell_time; + while (not stop_signal_called and usrp->get_time_now() < stop_time) + { + rb = usrp->get_gpio_attr(gpio, "READBACK"); + std::cout << "\rREADBACK: " << to_bit_string(rb, num_bits); + boost::this_thread::sleep(boost::posix_time::milliseconds(10)); + } + std::cout << std::endl; + } + else + { + // test user controlled GPIO and ATR idle by setting bit 4 high for 1 second + std::cout << "\nTesting user controlled GPIO and ATR idle output..." << std::flush; + usrp->set_gpio_attr(gpio, "OUT", 1 << 4, 1 << 4); + stop_time = usrp->get_time_now() + dwell_time; + while (not stop_signal_called and usrp->get_time_now() < stop_time) + { + boost::this_thread::sleep(boost::posix_time::milliseconds(100)); + } + rb = usrp->get_gpio_attr(gpio, "READBACK"); + expected = GPIO_BIT(4) | GPIO_BIT(0); + if ((rb & expected) != expected) + { + ++failures; + std::cout << "fail:" << std::endl; + if ((rb & GPIO_BIT(0)) == 0) + std::cout << "Bit 0 should be set, but is not" << std::endl; + if ((rb & GPIO_BIT(4)) == 0) + std::cout << "Bit 4 should be set, but is not" << std::endl; + } else { + std::cout << "pass:" << std::endl; + } + output_reg_values(gpio, usrp, num_bits); + usrp->set_gpio_attr(gpio, "OUT", 0, GPIO_BIT(4)); + if (stop_signal_called) + break; + + // test ATR RX by receiving for 1 second + std::cout << "\nTesting ATR RX output..." << std::flush; + rx_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; + rx_stream->issue_stream_cmd(rx_cmd); + stop_time = usrp->get_time_now() + dwell_time; + while (not stop_signal_called and usrp->get_time_now() < stop_time) + { + try { + rx_stream->recv(rx_buffs, nsamps_per_buff, rx_md, timeout); + } catch(...){} + } + rb = usrp->get_gpio_attr(gpio, "READBACK"); + expected = GPIO_BIT(1); + if ((rb & expected) != expected) + { + ++failures; + std::cout << "fail:" << std::endl; + std::cout << "Bit 1 should be set, but is not" << std::endl; + } else { + std::cout << "pass:" << std::endl; + } + output_reg_values(gpio, usrp, num_bits); + rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); + //clear out any data left in the rx stream + try { + rx_stream->recv(rx_buffs, nsamps_per_buff, rx_md, timeout); + } catch(...){} + if (stop_signal_called) + break; + + // test ATR TX by transmitting for 1 second + std::cout << "\nTesting ATR TX output..." << std::flush; + stop_time = usrp->get_time_now() + dwell_time; + tx_md.start_of_burst = true; + tx_md.end_of_burst = false; + while (not stop_signal_called and usrp->get_time_now() < stop_time) + { + try { + tx_stream->send(tx_buffs, nsamps_per_buff, tx_md, timeout); + tx_md.start_of_burst = false; + } catch(...){} + } + rb = usrp->get_gpio_attr(gpio, "READBACK"); + expected = GPIO_BIT(2); + if ((rb & expected) != expected) + { + ++failures; + std::cout << "fail:" << std::endl; + std::cout << "Bit 2 should be set, but is not" << std::endl; + } else { + std::cout << "pass:" << std::endl; + } + output_reg_values(gpio, usrp, num_bits); + tx_md.end_of_burst = true; + try { + tx_stream->send(tx_buffs, nsamps_per_buff, tx_md, timeout); + } catch(...){} + if (stop_signal_called) + break; + + // test ATR RX by transmitting and receiving for 1 second + std::cout << "\nTesting ATR full duplex output..." << std::flush; + rx_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; + rx_stream->issue_stream_cmd(rx_cmd); + tx_md.start_of_burst = true; + tx_md.end_of_burst = false; + stop_time = usrp->get_time_now() + dwell_time; + while (not stop_signal_called and usrp->get_time_now() < stop_time) + { + try { + tx_stream->send(rx_buffs, nsamps_per_buff, tx_md, timeout); + tx_md.start_of_burst = false; + rx_stream->recv(tx_buffs, nsamps_per_buff, rx_md, timeout); + } catch(...){} + } + rb = usrp->get_gpio_attr(gpio, "READBACK"); + expected = GPIO_BIT(3); + if ((rb & expected) != expected) + { + ++failures; + std::cout << "fail:" << std::endl; + std::cout << "Bit 3 should be set, but is not" << std::endl; + } else { + std::cout << "pass:" << std::endl; + } + output_reg_values(gpio, usrp, num_bits); + rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); + tx_md.end_of_burst = true; + try { + tx_stream->send(tx_buffs, nsamps_per_buff, tx_md, timeout); + } catch(...){} + //clear out any data left in the rx stream + try { + rx_stream->recv(rx_buffs, nsamps_per_buff, rx_md, timeout); + } catch(...){} + + std::cout << std::endl; + if (failures) + std::cout << failures << " tests failed" << std::endl; + else + std::cout << "All tests passed!" << std::endl; + } + + if (!vm.count("repeat")) + break; + + if (not stop_signal_called) + std::cout << (boost::format("\nLoop %d completed") % ++loop) << std::endl; + } + + //finished + std::cout << std::endl << "Done!" << std::endl << std::endl; + + return EXIT_SUCCESS; +} diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp index 663696926..89af6a6e1 100644 --- a/host/lib/usrp/b200/b200_impl.cpp +++ b/host/lib/usrp/b200/b200_impl.cpp @@ -1,5 +1,5 @@ // -// Copyright 2012-2014 Ettus Research LLC +// Copyright 2012-2015 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 @@ -528,6 +528,19 @@ b200_impl::b200_impl(const device_addr_t &device_addr) static const std::vector clock_sources = boost::assign::list_of("internal")("external")("gpsdo"); _tree->create >(mb_path / "clock_source" / "options").set(clock_sources); + //////////////////////////////////////////////////////////////////// + // front panel gpio + //////////////////////////////////////////////////////////////////// + _radio_perifs[0].fp_gpio = gpio_core_200::make(_radio_perifs[0].ctrl, TOREG(SR_FP_GPIO), RB32_FP_GPIO); + BOOST_FOREACH(const gpio_attr_map_t::value_type attr, gpio_attr_map) + { + _tree->create(mb_path / "gpio" / "FP0" / attr.second) + .set(0) + .subscribe(boost::bind(&b200_impl::set_fp_gpio, this, _radio_perifs[0].fp_gpio, attr.first, _1)); + } + _tree->create(mb_path / "gpio" / "FP0" / "READBACK") + .publish(boost::bind(&b200_impl::get_fp_gpio, this, _radio_perifs[0].fp_gpio)); + //////////////////////////////////////////////////////////////////// // dboard eeproms but not really //////////////////////////////////////////////////////////////////// @@ -902,6 +915,26 @@ void b200_impl::set_mb_eeprom(const uhd::usrp::mboard_eeprom_t &mb_eeprom) } +boost::uint32_t b200_impl::get_fp_gpio(gpio_core_200::sptr gpio) +{ + return boost::uint32_t(gpio->read_gpio(dboard_iface::UNIT_RX)); +} + +void b200_impl::set_fp_gpio(gpio_core_200::sptr gpio, const gpio_attr_t attr, const boost::uint32_t value) +{ + switch (attr) + { + case CTRL: return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value); + case DDR: return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value); + case OUT: return gpio->set_gpio_out(dboard_iface::UNIT_RX, value); + case ATR_0X: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value); + case ATR_RX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value); + case ATR_TX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value); + case ATR_XX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value); + default: UHD_THROW_INVALID_CODE_PATH(); + } +} + /*********************************************************************** * Reference time and clock **********************************************************************/ diff --git a/host/lib/usrp/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp index 64d7aa7d0..cff767b4b 100644 --- a/host/lib/usrp/b200/b200_impl.hpp +++ b/host/lib/usrp/b200/b200_impl.hpp @@ -1,5 +1,5 @@ // -// Copyright 2012-2013 Ettus Research LLC +// Copyright 2012-2015 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 @@ -156,6 +156,7 @@ private: { radio_ctrl_core_3000::sptr ctrl; gpio_core_200_32wo::sptr atr; + gpio_core_200::sptr fp_gpio; time_core_3000::sptr time64; rx_vita_core_3000::sptr framer; rx_dsp_core_3000::sptr ddc; @@ -194,6 +195,9 @@ private: void update_enables(void); void update_atrs(void); + boost::uint32_t get_fp_gpio(gpio_core_200::sptr); + void set_fp_gpio(gpio_core_200::sptr, const gpio_attr_t, const boost::uint32_t); + double _tick_rate; double get_tick_rate(void){return _tick_rate;} double set_tick_rate(const double rate); @@ -245,6 +249,7 @@ private: //! Coercer, attached to the "rate/value" property on the rx dsps. double coerce_rx_samp_rate(rx_dsp_core_3000::sptr, size_t, const double); void update_rx_samp_rate(const size_t, const double); + //! Coercer, attached to the "rate/value" property on the tx dsps. double coerce_tx_samp_rate(tx_dsp_core_3000::sptr, size_t, const double); void update_tx_samp_rate(const size_t, const double); diff --git a/host/lib/usrp/b200/b200_regs.hpp b/host/lib/usrp/b200/b200_regs.hpp index 900651f94..8f2dd03f3 100644 --- a/host/lib/usrp/b200/b200_regs.hpp +++ b/host/lib/usrp/b200/b200_regs.hpp @@ -46,11 +46,13 @@ localparam SR_TX_DSP = 184; localparam SR_TIME = 128; localparam SR_RX_FMT = 136; localparam SR_TX_FMT = 138; +localparam SR_FP_GPIO = 200; localparam RB32_TEST = 0; localparam RB64_TIME_NOW = 8; localparam RB64_TIME_PPS = 16; localparam RB64_CODEC_READBACK = 24; +localparam RB32_FP_GPIO = 32; //pll constants static const int AD9361_SLAVENO = (1 << 0); diff --git a/host/lib/usrp/cores/gpio_core_200.hpp b/host/lib/usrp/cores/gpio_core_200.hpp index 164437f40..a76cced01 100644 --- a/host/lib/usrp/cores/gpio_core_200.hpp +++ b/host/lib/usrp/cores/gpio_core_200.hpp @@ -1,5 +1,5 @@ // -// Copyright 2011,2014 Ettus Research LLC +// Copyright 2011,2014,2015 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,10 +20,17 @@ #include #include +#include #include #include #include #include +#include + +typedef enum{CTRL,DDR,OUT,ATR_0X,ATR_RX,ATR_TX,ATR_XX} gpio_attr_t; +typedef std::map gpio_attr_map_t; +static const gpio_attr_map_t gpio_attr_map = + boost::assign::map_list_of(CTRL,"CTRL")(DDR,"DDR")(OUT,"OUT")(ATR_0X,"ATR_0X")(ATR_RX,"ATR_RX")(ATR_TX,"ATR_TX")(ATR_XX,"ATR_XX"); class gpio_core_200 : boost::noncopyable{ public: diff --git a/host/lib/usrp/e300/e300_impl.cpp b/host/lib/usrp/e300/e300_impl.cpp index ce94147e8..ac92f9a12 100644 --- a/host/lib/usrp/e300/e300_impl.cpp +++ b/host/lib/usrp/e300/e300_impl.cpp @@ -469,15 +469,14 @@ e300_impl::e300_impl(const uhd::device_addr_t &device_addr) // internal gpios //////////////////////////////////////////////////////////////////// gpio_core_200::sptr fp_gpio = gpio_core_200::make(_radio_perifs[0].ctrl, TOREG(SR_FP_GPIO), RB32_FP_GPIO); - const std::vector gpio_attrs = boost::assign::list_of("CTRL")("DDR")("OUT")("ATR_0X")("ATR_RX")("ATR_TX")("ATR_XX"); - BOOST_FOREACH(const std::string &attr, gpio_attrs) + BOOST_FOREACH(const gpio_attr_map_t::value_type attr, gpio_attr_map) { - _tree->create(mb_path / "gpio" / "INT0" / attr) - .subscribe(boost::bind(&e300_impl::_set_internal_gpio, this, fp_gpio, attr, _1)) + _tree->create(mb_path / "gpio" / "INT0" / attr.second) + .subscribe(boost::bind(&e300_impl::_set_internal_gpio, this, fp_gpio, attr.first, _1)) .set(0); } _tree->create(mb_path / "gpio" / "INT0" / "READBACK") - .publish(boost::bind(&e300_impl::_get_internal_gpio, this, fp_gpio, "READBACK")); + .publish(boost::bind(&e300_impl::_get_internal_gpio, this, fp_gpio)); //////////////////////////////////////////////////////////////////// @@ -576,32 +575,35 @@ e300_impl::e300_impl(const uhd::device_addr_t &device_addr) _tree->access(mb_path / "tx_subdev_spec").set(tx_spec); } -boost::uint8_t e300_impl::_get_internal_gpio( - gpio_core_200::sptr gpio, - const std::string &) +boost::uint8_t e300_impl::_get_internal_gpio(gpio_core_200::sptr gpio) { return boost::uint32_t(gpio->read_gpio(dboard_iface::UNIT_RX)); } void e300_impl::_set_internal_gpio( gpio_core_200::sptr gpio, - const std::string &attr, + const gpio_attr_t attr, const boost::uint32_t value) { - if (attr == "CTRL") + switch (attr) + { + case CTRL: return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value); - else if (attr == "DDR") + case DDR: return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value); - else if (attr == "OUT") + case OUT: return gpio->set_gpio_out(dboard_iface::UNIT_RX, value); - else if (attr == "ATR_0X") + case ATR_0X: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value); - else if (attr == "ATR_RX") + case ATR_RX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value); - else if (attr == "ATR_TX") + case ATR_TX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value); - else if (attr == "ATR_XX") + case ATR_XX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value); + default: + UHD_THROW_INVALID_CODE_PATH(); + } } uhd::sensor_value_t e300_impl::_get_fe_pll_lock(const bool is_tx) diff --git a/host/lib/usrp/e300/e300_impl.hpp b/host/lib/usrp/e300/e300_impl.hpp index c7d683f58..21aef215d 100644 --- a/host/lib/usrp/e300/e300_impl.hpp +++ b/host/lib/usrp/e300/e300_impl.hpp @@ -264,13 +264,11 @@ private: // methods uhd::sensor_value_t _get_fe_pll_lock(const bool is_tx); // internal gpios - boost::uint8_t _get_internal_gpio( - gpio_core_200::sptr, - const std::string &); + boost::uint8_t _get_internal_gpio(gpio_core_200::sptr); void _set_internal_gpio( gpio_core_200::sptr gpio, - const std::string &attr, + const gpio_attr_t attr, const boost::uint32_t value); private: // members diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index bf676b661..a82be543d 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -1,5 +1,5 @@ // -// Copyright 2013-2014 Ettus Research LLC +// Copyright 2013-2015 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 @@ -695,15 +695,14 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) // front panel gpio //////////////////////////////////////////////////////////////////// mb.fp_gpio = gpio_core_200::make(mb.radio_perifs[0].ctrl, TOREG(SR_FP_GPIO), RB32_FP_GPIO); - const std::vector GPIO_ATTRS = boost::assign::list_of("CTRL")("DDR")("OUT")("ATR_0X")("ATR_RX")("ATR_TX")("ATR_XX"); - BOOST_FOREACH(const std::string &attr, GPIO_ATTRS) + BOOST_FOREACH(const gpio_attr_map_t::value_type attr, gpio_attr_map) { - _tree->create(mb_path / "gpio" / "FP0" / attr) + _tree->create(mb_path / "gpio" / "FP0" / attr.second) .set(0) - .subscribe(boost::bind(&x300_impl::set_fp_gpio, this, mb.fp_gpio, attr, _1)); + .subscribe(boost::bind(&x300_impl::set_fp_gpio, this, mb.fp_gpio, attr.first, _1)); } _tree->create(mb_path / "gpio" / "FP0" / "READBACK") - .publish(boost::bind(&x300_impl::get_fp_gpio, this, mb.fp_gpio, "READBACK")); + .publish(boost::bind(&x300_impl::get_fp_gpio, this, mb.fp_gpio)); //////////////////////////////////////////////////////////////////// // register the time keepers - only one can be the highlander @@ -1353,7 +1352,7 @@ void x300_impl::set_time_source_out(mboard_members_t &mb, const bool enb) void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &source) { //Optimize for the case when the current source is internal and we are trying - //to set it to internal. This is the only case where we are guaranteed that + //to set it to internal. This is the only case where we are guaranteed that //the clock has not gone away so we can skip setting the MUX and reseting the LMK. if (not (mb.current_refclk_src == "internal" and source == "internal")) { //Update the clock MUX on the motherboard to select the requested source @@ -1534,20 +1533,24 @@ void x300_impl::set_mb_eeprom(i2c_iface::sptr i2c, const mboard_eeprom_t &mb_eep * front-panel GPIO **********************************************************************/ -boost::uint32_t x300_impl::get_fp_gpio(gpio_core_200::sptr gpio, const std::string &) +boost::uint32_t x300_impl::get_fp_gpio(gpio_core_200::sptr gpio) { return boost::uint32_t(gpio->read_gpio(dboard_iface::UNIT_RX)); } -void x300_impl::set_fp_gpio(gpio_core_200::sptr gpio, const std::string &attr, const boost::uint32_t value) +void x300_impl::set_fp_gpio(gpio_core_200::sptr gpio, const gpio_attr_t attr, const boost::uint32_t value) { - if (attr == "CTRL") return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value); - if (attr == "DDR") return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value); - if (attr == "OUT") return gpio->set_gpio_out(dboard_iface::UNIT_RX, value); - if (attr == "ATR_0X") return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value); - if (attr == "ATR_RX") return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value); - if (attr == "ATR_TX") return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value); - if (attr == "ATR_XX") return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value); + switch (attr) + { + case CTRL: return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value); + case DDR: return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value); + case OUT: return gpio->set_gpio_out(dboard_iface::UNIT_RX, value); + case ATR_0X: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value); + case ATR_RX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value); + case ATR_TX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value); + case ATR_XX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value); + default: UHD_THROW_INVALID_CODE_PATH(); + } } /*********************************************************************** diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp index 70c5dccb4..9ad060c85 100644 --- a/host/lib/usrp/x300/x300_impl.hpp +++ b/host/lib/usrp/x300/x300_impl.hpp @@ -1,5 +1,5 @@ // -// Copyright 2013-2014 Ettus Research LLC +// Copyright 2013-2015 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 @@ -360,8 +360,8 @@ private: void check_fpga_compat(const uhd::fs_path &mb_path, uhd::wb_iface::sptr iface); void update_atr_leds(gpio_core_200_32wo::sptr, const std::string &ant); - boost::uint32_t get_fp_gpio(gpio_core_200::sptr, const std::string &); - void set_fp_gpio(gpio_core_200::sptr, const std::string &, const boost::uint32_t); + boost::uint32_t get_fp_gpio(gpio_core_200::sptr); + void set_fp_gpio(gpio_core_200::sptr, const gpio_attr_t, const boost::uint32_t); //**PRECONDITION** //This function assumes that all the VITA times in "radios" are synchronized -- cgit v1.2.3 From 08467564116f4b948620e831bfd4b5426a43611c Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Wed, 11 Mar 2015 14:33:57 -0700 Subject: gpio: Renamed enums to avoid clash with generic, compiler-provided names --- host/lib/usrp/b200/b200_impl.cpp | 14 +++++++------- host/lib/usrp/cores/gpio_core_200.hpp | 21 +++++++++++++++++++-- host/lib/usrp/e300/e300_impl.cpp | 14 +++++++------- host/lib/usrp/x300/x300_impl.cpp | 14 +++++++------- 4 files changed, 40 insertions(+), 23 deletions(-) (limited to 'host/lib/usrp/x300/x300_impl.cpp') diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp index b1ab6ea7d..c22eb86bc 100644 --- a/host/lib/usrp/b200/b200_impl.cpp +++ b/host/lib/usrp/b200/b200_impl.cpp @@ -925,13 +925,13 @@ void b200_impl::set_fp_gpio(gpio_core_200::sptr gpio, const gpio_attr_t attr, co { switch (attr) { - case CTRL: return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value); - case DDR: return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value); - case OUT: return gpio->set_gpio_out(dboard_iface::UNIT_RX, value); - case ATR_0X: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value); - case ATR_RX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value); - case ATR_TX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value); - case ATR_XX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value); + case GPIO_CTRL: return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value); + case GPIO_DDR: return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value); + case GPIO_OUT: return gpio->set_gpio_out(dboard_iface::UNIT_RX, value); + case GPIO_ATR_0X: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value); + case GPIO_ATR_RX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value); + case GPIO_ATR_TX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value); + case GPIO_ATR_XX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value); default: UHD_THROW_INVALID_CODE_PATH(); } } diff --git a/host/lib/usrp/cores/gpio_core_200.hpp b/host/lib/usrp/cores/gpio_core_200.hpp index a76cced01..e22834fd9 100644 --- a/host/lib/usrp/cores/gpio_core_200.hpp +++ b/host/lib/usrp/cores/gpio_core_200.hpp @@ -27,10 +27,27 @@ #include #include -typedef enum{CTRL,DDR,OUT,ATR_0X,ATR_RX,ATR_TX,ATR_XX} gpio_attr_t; +typedef enum { + GPIO_CTRL, + GPIO_DDR, + GPIO_OUT, + GPIO_ATR_0X, + GPIO_ATR_RX, + GPIO_ATR_TX, + GPIO_ATR_XX +} gpio_attr_t; + typedef std::map gpio_attr_map_t; static const gpio_attr_map_t gpio_attr_map = - boost::assign::map_list_of(CTRL,"CTRL")(DDR,"DDR")(OUT,"OUT")(ATR_0X,"ATR_0X")(ATR_RX,"ATR_RX")(ATR_TX,"ATR_TX")(ATR_XX,"ATR_XX"); + boost::assign::map_list_of + (GPIO_CTRL, "CTRL") + (GPIO_DDR, "DDR") + (GPIO_OUT, "OUT") + (GPIO_ATR_0X, "ATR_0X") + (GPIO_ATR_RX, "ATR_RX") + (GPIO_ATR_TX, "ATR_TX") + (GPIO_ATR_XX, "ATR_XX") +; class gpio_core_200 : boost::noncopyable{ public: diff --git a/host/lib/usrp/e300/e300_impl.cpp b/host/lib/usrp/e300/e300_impl.cpp index ac92f9a12..8be3e47c9 100644 --- a/host/lib/usrp/e300/e300_impl.cpp +++ b/host/lib/usrp/e300/e300_impl.cpp @@ -587,19 +587,19 @@ void e300_impl::_set_internal_gpio( { switch (attr) { - case CTRL: + case GPIO_CTRL: return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value); - case DDR: + case GPIO_DDR: return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value); - case OUT: + case GPIO_OUT: return gpio->set_gpio_out(dboard_iface::UNIT_RX, value); - case ATR_0X: + case GPIO_ATR_0X: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value); - case ATR_RX: + case GPIO_ATR_RX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value); - case ATR_TX: + case GPIO_ATR_TX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value); - case ATR_XX: + case GPIO_ATR_XX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value); default: UHD_THROW_INVALID_CODE_PATH(); diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index a82be543d..d9b27b6b4 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -1542,13 +1542,13 @@ void x300_impl::set_fp_gpio(gpio_core_200::sptr gpio, const gpio_attr_t attr, co { switch (attr) { - case CTRL: return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value); - case DDR: return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value); - case OUT: return gpio->set_gpio_out(dboard_iface::UNIT_RX, value); - case ATR_0X: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value); - case ATR_RX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value); - case ATR_TX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value); - case ATR_XX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value); + case GPIO_CTRL: return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value); + case GPIO_DDR: return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value); + case GPIO_OUT: return gpio->set_gpio_out(dboard_iface::UNIT_RX, value); + case GPIO_ATR_0X: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value); + case GPIO_ATR_RX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value); + case GPIO_ATR_TX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value); + case GPIO_ATR_XX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value); default: UHD_THROW_INVALID_CODE_PATH(); } } -- cgit v1.2.3