diff options
Diffstat (limited to 'host/lib')
| -rw-r--r-- | host/lib/usrp/common/ad9361_ctrl.cpp | 54 | ||||
| -rw-r--r-- | host/lib/usrp/common/ad9361_ctrl.hpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/common/ad9361_driver/ad9361_device.cpp | 10 | ||||
| -rw-r--r-- | host/lib/usrp/common/ad9361_driver/ad9361_device.h | 3 | ||||
| -rw-r--r-- | host/lib/usrp/e300/e300_remote_codec_ctrl.cpp | 3 | 
5 files changed, 68 insertions, 10 deletions
diff --git a/host/lib/usrp/common/ad9361_ctrl.cpp b/host/lib/usrp/common/ad9361_ctrl.cpp index 54f0fcdbf..654311424 100644 --- a/host/lib/usrp/common/ad9361_ctrl.cpp +++ b/host/lib/usrp/common/ad9361_ctrl.cpp @@ -93,18 +93,30 @@ class ad9361_ctrl_impl : public ad9361_ctrl  {  public:      ad9361_ctrl_impl(ad9361_params::sptr client_settings, ad9361_io::sptr io_iface): -        _device(client_settings, io_iface) +        _device(client_settings, io_iface), _safe_spi(io_iface), _timed_spi(io_iface)      {          _device.initialize();      } +    void set_timed_spi(uhd::spi_iface::sptr spi_iface, boost::uint32_t slave_num) +    { +        _timed_spi = boost::make_shared<ad9361_io_spi>(spi_iface, slave_num); +        _use_timed_spi(); +    } + +    void set_safe_spi(uhd::spi_iface::sptr spi_iface, boost::uint32_t slave_num) +    { +        _safe_spi = boost::make_shared<ad9361_io_spi>(spi_iface, slave_num); +    } +      double set_gain(const std::string &which, const double value)      {          boost::lock_guard<boost::mutex> lock(_mutex);          ad9361_device_t::direction_t direction = _get_direction_from_antenna(which);          ad9361_device_t::chain_t chain =_get_chain_from_antenna(which); -        return _device.set_gain(direction, chain, value); +        double return_val = _device.set_gain(direction, chain, value); +        return return_val;      }      void set_agc(const std::string &which, bool enable) @@ -112,7 +124,7 @@ public:          boost::lock_guard<boost::mutex> lock(_mutex);          ad9361_device_t::chain_t chain =_get_chain_from_antenna(which); -         _device.set_agc(chain, enable); +        _device.set_agc(chain, enable);      }      void set_agc_mode(const std::string &which, const std::string &mode) @@ -133,6 +145,9 @@ public:      {          boost::lock_guard<boost::mutex> lock(_mutex); +        // Changing clock rate will disrupt AD9361's sample clock +        _use_safe_spi(); +          //clip to known bounds          const meta_range_t clock_rate_range = ad9361_ctrl::get_clock_rate_range();          const double clipped_rate = clock_rate_range.clip(rate); @@ -144,7 +159,11 @@ public:              ) % (rate/1e6) % (clipped_rate/1e6) << std::endl;          } -        return _device.set_clock_rate(clipped_rate); +        double return_rate = _device.set_clock_rate(clipped_rate); + +        _use_timed_spi(); + +        return return_rate;      }      //! set which RX and TX chains/antennas are active @@ -152,7 +171,11 @@ public:      {          boost::lock_guard<boost::mutex> lock(_mutex); +        // If both RX chains are disabled then the AD9361's sample clock is disabled +        _use_safe_spi();          _device.set_active_chains(tx1, tx2, rx1, rx2); +        _use_timed_spi(); +      }      //! tune the given frontend, return the exact value @@ -166,7 +189,8 @@ public:          const double value = ad9361_ctrl::get_rf_freq_range().clip(clipped_freq);          ad9361_device_t::direction_t direction = _get_direction_from_antenna(which); -        return _device.tune(direction, value); +        double return_val = _device.tune(direction, value); +        return return_val;      }      //! get the current frequency for the given frontend @@ -283,16 +307,28 @@ private:          return ad9361_device_t::CHAIN_1;      } -    ad9361_device_t _device; -    boost::mutex    _mutex; +    void _use_safe_spi() { +        _device.set_io_iface(_safe_spi); +    } + +    void _use_timed_spi() { +        _device.set_io_iface(_timed_spi); +    } + +    ad9361_device_t         _device; +    ad9361_io::sptr         _safe_spi;      // SPI core that uses an always available clock +    ad9361_io::sptr         _timed_spi;     // SPI core that has a dependency on the AD9361's sample clock (i.e. radio clk) +    boost::mutex            _mutex;  };  //----------------------------------------------------------------------  // Make an instance of the AD9361 Control interface  //----------------------------------------------------------------------  ad9361_ctrl::sptr ad9361_ctrl::make_spi( -    ad9361_params::sptr client_settings, uhd::spi_iface::sptr spi_iface, boost::uint32_t slave_num) -{ +    ad9361_params::sptr client_settings, +    uhd::spi_iface::sptr spi_iface, +    boost::uint32_t slave_num +) {      boost::shared_ptr<ad9361_io_spi> spi_io_iface = boost::make_shared<ad9361_io_spi>(spi_iface, slave_num);      return sptr(new ad9361_ctrl_impl(client_settings, spi_io_iface));  } diff --git a/host/lib/usrp/common/ad9361_ctrl.hpp b/host/lib/usrp/common/ad9361_ctrl.hpp index 8cd75d539..5770c3ec4 100644 --- a/host/lib/usrp/common/ad9361_ctrl.hpp +++ b/host/lib/usrp/common/ad9361_ctrl.hpp @@ -56,7 +56,13 @@ public:      //! make a new codec control object      static sptr make_spi( -        ad9361_params::sptr client_settings, uhd::spi_iface::sptr spi_iface, boost::uint32_t slave_num); +        ad9361_params::sptr client_settings, +        uhd::spi_iface::sptr spi_iface, +        boost::uint32_t slave_num +    ); + +    virtual void set_timed_spi(uhd::spi_iface::sptr spi_iface, boost::uint32_t slave_num) = 0; +    virtual void set_safe_spi(uhd::spi_iface::sptr spi_iface, boost::uint32_t slave_num) = 0;      //! Get a list of gain names for RX or TX      static std::vector<std::string> get_gain_names(const std::string &/*which*/) diff --git a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp index bb25379c0..095017bb6 100644 --- a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp +++ b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp @@ -1565,6 +1565,12 @@ void ad9361_device_t::initialize()      _io_iface->poke8(0x000, 0x00);      boost::this_thread::sleep(boost::posix_time::milliseconds(20)); +    /* Check device ID to make sure iface works */ +    boost::uint32_t device_id = (_io_iface->peek8(0x037) & 0x8); +    if (device_id != 0x8) { +        throw uhd::runtime_error(str(boost::format("[ad9361_device_t::initialize] Device ID readback failure. Expected: 0x8, Received: 0x%x") % device_id)); +    } +      /* There is not a WAT big enough for this. */      _io_iface->poke8(0x3df, 0x01); @@ -1774,6 +1780,10 @@ void ad9361_device_t::initialize()      _io_iface->poke8(0x014, 0x21);  } +void ad9361_device_t::set_io_iface(ad9361_io::sptr io_iface) +{ +    _io_iface = io_iface; +}  /* This function sets the RX / TX rate between AD9361 and the FPGA, and   * thus determines the interpolation / decimation required in the FPGA to diff --git a/host/lib/usrp/common/ad9361_driver/ad9361_device.h b/host/lib/usrp/common/ad9361_driver/ad9361_device.h index 73b1d9a35..d0e8a7e39 100644 --- a/host/lib/usrp/common/ad9361_driver/ad9361_device.h +++ b/host/lib/usrp/common/ad9361_driver/ad9361_device.h @@ -75,6 +75,9 @@ public:      /* Initialize the AD9361 codec. */      void initialize(); +    /* Set SPI interface */ +    void set_io_iface(ad9361_io::sptr io_iface); +      /* This function sets the RX / TX rate between AD9361 and the FPGA, and       * thus determines the interpolation / decimation required in the FPGA to       * achieve the user's requested rate. diff --git a/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp b/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp index 17a564f21..cb2583b1b 100644 --- a/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp +++ b/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp @@ -36,6 +36,9 @@ public:      {      } +    void set_timed_spi(uhd::spi_iface::sptr spi_iface, boost::uint32_t slave_num) {}; +    void set_safe_spi(uhd::spi_iface::sptr spi_iface, boost::uint32_t slave_num) {}; +      double set_gain(const std::string &which, const double value)      {          _clear();  | 
