diff options
Diffstat (limited to 'host')
| -rw-r--r-- | host/lib/usrp/usrp2/dboard_iface.cpp | 48 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp | 48 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 33 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.hpp | 12 | 
4 files changed, 76 insertions, 65 deletions
| diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp index bc510c8a1..edd9ef242 100644 --- a/host/lib/usrp/usrp2/dboard_iface.cpp +++ b/host/lib/usrp/usrp2/dboard_iface.cpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@  //  #include "gpio_core_200.hpp" -#include "usrp2_iface.hpp" +#include <uhd/types/serial.hpp>  #include "clock_ctrl.hpp"  #include "usrp2_regs.hpp" //wishbone address constants  #include <uhd/usrp/dboard_iface.hpp> @@ -35,7 +35,12 @@ using namespace boost::assign;  class usrp2_dboard_iface : public dboard_iface{  public: -    usrp2_dboard_iface(usrp2_iface::sptr iface, usrp2_clock_ctrl::sptr clock_ctrl); +    usrp2_dboard_iface( +        wb_iface::sptr wb_iface, +        uhd::i2c_iface::sptr i2c_iface, +        uhd::spi_iface::sptr spi_iface, +        usrp2_clock_ctrl::sptr clock_ctrl +    );      ~usrp2_dboard_iface(void);      special_props_t get_special_props(void){ @@ -79,7 +84,8 @@ public:      );  private: -    usrp2_iface::sptr _iface; +    uhd::i2c_iface::sptr _i2c_iface; +    uhd::spi_iface::sptr _spi_iface;      usrp2_clock_ctrl::sptr _clock_ctrl;      gpio_core_200::sptr _gpio; @@ -92,22 +98,28 @@ private:   * Make Function   **********************************************************************/  dboard_iface::sptr make_usrp2_dboard_iface( -    usrp2_iface::sptr iface, +    wb_iface::sptr wb_iface, +    uhd::i2c_iface::sptr i2c_iface, +    uhd::spi_iface::sptr spi_iface,      usrp2_clock_ctrl::sptr clock_ctrl  ){ -    return dboard_iface::sptr(new usrp2_dboard_iface(iface, clock_ctrl)); +    return dboard_iface::sptr(new usrp2_dboard_iface(wb_iface, i2c_iface, spi_iface, clock_ctrl));  }  /***********************************************************************   * Structors   **********************************************************************/  usrp2_dboard_iface::usrp2_dboard_iface( -    usrp2_iface::sptr iface, +    wb_iface::sptr wb_iface, +    uhd::i2c_iface::sptr i2c_iface, +    uhd::spi_iface::sptr spi_iface,      usrp2_clock_ctrl::sptr clock_ctrl -){ -    _iface = iface; -    _clock_ctrl = clock_ctrl; -    _gpio = gpio_core_200::make(_iface, U2_REG_SR_ADDR(SR_GPIO), U2_REG_GPIO_RB); +): +    _i2c_iface(i2c_iface), +    _spi_iface(spi_iface), +    _clock_ctrl(clock_ctrl) +{ +    _gpio = gpio_core_200::make(wb_iface, U2_REG_SR_ADDR(SR_GPIO), U2_REG_GPIO_RB);      //reset the aux dacs      _dac_regs[UNIT_RX] = ad5623_regs_t(); @@ -202,7 +214,7 @@ void usrp2_dboard_iface::write_spi(      boost::uint32_t data,      size_t num_bits  ){ -    _iface->write_spi(unit_to_spi_dev[unit], config, data, num_bits); +    _spi_iface->write_spi(unit_to_spi_dev[unit], config, data, num_bits);  }  boost::uint32_t usrp2_dboard_iface::read_write_spi( @@ -211,18 +223,18 @@ boost::uint32_t usrp2_dboard_iface::read_write_spi(      boost::uint32_t data,      size_t num_bits  ){ -    return _iface->read_spi(unit_to_spi_dev[unit], config, data, num_bits); +    return _spi_iface->read_spi(unit_to_spi_dev[unit], config, data, num_bits);  }  /***********************************************************************   * I2C   **********************************************************************/  void usrp2_dboard_iface::write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ -    return _iface->write_i2c(addr, bytes); +    return _i2c_iface->write_i2c(addr, bytes);  }  byte_vector_t usrp2_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes){ -    return _iface->read_i2c(addr, num_bytes); +    return _i2c_iface->read_i2c(addr, num_bytes);  }  /*********************************************************************** @@ -233,7 +245,7 @@ void usrp2_dboard_iface::_write_aux_dac(unit_t unit){          (UNIT_RX, SPI_SS_RX_DAC)          (UNIT_TX, SPI_SS_TX_DAC)      ; -    _iface->write_spi( +    _spi_iface->write_spi(          unit_to_spi_dac[unit], spi_config_t::EDGE_FALL,           _dac_regs[unit].get_reg(), 24      ); @@ -281,11 +293,11 @@ double usrp2_dboard_iface::read_aux_adc(unit_t unit, aux_adc_t which){      } ad7922_regs.chn = ad7922_regs.mod; //normal mode: mod == chn      //write and read spi -    _iface->write_spi( +    _spi_iface->write_spi(          unit_to_spi_adc[unit], config,          ad7922_regs.get_reg(), 16      ); -    ad7922_regs.set_reg(boost::uint16_t(_iface->read_spi( +    ad7922_regs.set_reg(boost::uint16_t(_spi_iface->read_spi(          unit_to_spi_adc[unit], config,          ad7922_regs.get_reg(), 16      ))); diff --git a/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp b/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp index 4691fa887..e19e7d5e7 100644 --- a/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp +++ b/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp @@ -15,6 +15,7 @@  // along with this program.  If not, see <http://www.gnu.org/licenses/>.  // +#include "usrp2_regs.hpp"  #include <uhd/exception.hpp>  #include <uhd/utils/msg.hpp>  #include <uhd/transport/vrt_if_packet.hpp> @@ -27,24 +28,25 @@ using namespace uhd::transport;  static const size_t POKE32_CMD = (1 << 8);  static const size_t PEEK32_CMD = 0;  static const double ACK_TIMEOUT = 0.5; +static const boost::uint32_t MAX_SEQS_OUT = 16;  class usrp2_fifo_ctrl_impl : public usrp2_fifo_ctrl{  public:      usrp2_fifo_ctrl_impl(zero_copy_if::sptr xport):          _xport(xport), -        _seq(0) +        _seq(0), _last_seq_ack(0)      { -        //NOP +        while (_xport->get_recv_buff(0.0)){} //flush      }      UHD_INLINE void send_pkt(wb_addr_type addr, boost::uint32_t data, int cmd){          managed_send_buffer::sptr buff = _xport->get_send_buff(0.0);          if (not buff){ -            throw uhd::runtime_error("peek32/poke32 in fifo ctrl timed out getting a send buffer"); +            throw uhd::runtime_error("fifo ctrl timed out getting a send buffer");          }          boost::uint32_t *trans = buff->cast<boost::uint32_t *>(); -        trans[0] = htonl(_seq++); +        trans[0] = htonl(++_seq);          boost::uint32_t *pkt = trans + 1;          //load packet info @@ -61,10 +63,10 @@ public:          packet_info.has_tsf = false;          packet_info.has_tlr = false; -        //load header with offset 1 +        //load header          vrt::if_hdr_pack_be(pkt, packet_info); -        //load payload with offset 1 +        //load payload          const boost::uint32_t ctrl_word = (addr & 0xff) | cmd | (_seq << 16);          pkt[packet_info.num_header_words32+0] = htonl(ctrl_word);          pkt[packet_info.num_header_words32+1] = htonl(data); @@ -76,40 +78,37 @@ public:      void poke32(wb_addr_type addr, boost::uint32_t data){          boost::mutex::scoped_lock lock(_mutex); -        while (_xport->get_recv_buff(0.0)){} //flush - -        this->send_pkt(addr, data, POKE32_CMD); +        this->send_pkt((addr - SETTING_REGS_BASE)/4, data, POKE32_CMD); -        { -            managed_recv_buffer::sptr buff = _xport->get_recv_buff(ACK_TIMEOUT); -            if (not buff){ -                throw uhd::runtime_error("poke32 in fifo ctrl timed out getting a recv buffer"); -            } -            const boost::uint32_t *pkt = buff->cast<const boost::uint32_t *>(); -            vrt::if_packet_info_t packet_info; -            packet_info.num_packet_words32 = buff->size()/sizeof(boost::uint32_t); -            vrt::if_hdr_unpack_be(pkt, packet_info); -        } +        this->wait_for_ack(boost::int16_t(_seq-MAX_SEQS_OUT));      }      boost::uint32_t peek32(wb_addr_type addr){          boost::mutex::scoped_lock lock(_mutex); -        while (_xport->get_recv_buff(0.0)){} //flush +        this->send_pkt((addr - READBACK_BASE)/4, 0, PEEK32_CMD); -        this->send_pkt(addr >> 2, 0, PEEK32_CMD); +        return this->wait_for_ack(boost::int16_t(_seq)); +    } + +    boost::uint32_t wait_for_ack(const boost::int16_t seq_to_ack){ -        { +        while (_last_seq_ack < seq_to_ack){              managed_recv_buffer::sptr buff = _xport->get_recv_buff(ACK_TIMEOUT);              if (not buff){ -                throw uhd::runtime_error("peek32 in fifo ctrl timed out getting a recv buffer"); +                throw uhd::runtime_error("fifo ctrl timed out looking for acks");              }              const boost::uint32_t *pkt = buff->cast<const boost::uint32_t *>();              vrt::if_packet_info_t packet_info;              packet_info.num_packet_words32 = buff->size()/sizeof(boost::uint32_t);              vrt::if_hdr_unpack_be(pkt, packet_info); -            return ntohl(pkt[packet_info.num_header_words32+1]); +            _last_seq_ack = ntohl(pkt[packet_info.num_header_words32+0]) >> 16; +            if (_last_seq_ack == seq_to_ack){ +                return ntohl(pkt[packet_info.num_header_words32+1]); +            }          } + +        return 0;      }      void poke16(wb_addr_type, boost::uint16_t){ @@ -124,6 +123,7 @@ private:      zero_copy_if::sptr _xport;      boost::mutex _mutex;      boost::uint32_t _seq; +    boost::uint16_t _last_seq_ack;  }; diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 5e873f741..59cf65828 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -462,10 +462,10 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){          // create frontend control objects          ////////////////////////////////////////////////////////////////          _mbc[mb].rx_fe = rx_frontend_core_200::make( -            _mbc[mb].iface, U2_REG_SR_ADDR(SR_RX_FRONT) +            _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_RX_FRONT)          );          _mbc[mb].tx_fe = tx_frontend_core_200::make( -            _mbc[mb].iface, U2_REG_SR_ADDR(SR_TX_FRONT) +            _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_TX_FRONT)          );          _tree->create<subdev_spec_t>(mb_path / "rx_subdev_spec") @@ -496,10 +496,10 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){          // create rx dsp control objects          ////////////////////////////////////////////////////////////////          _mbc[mb].rx_dsps.push_back(rx_dsp_core_200::make( -            _mbc[mb].iface, U2_REG_SR_ADDR(SR_RX_DSP0), U2_REG_SR_ADDR(SR_RX_CTRL0), USRP2_RX_SID_BASE + 0, true +            _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_RX_DSP0), U2_REG_SR_ADDR(SR_RX_CTRL0), USRP2_RX_SID_BASE + 0, true          ));          _mbc[mb].rx_dsps.push_back(rx_dsp_core_200::make( -            _mbc[mb].iface, U2_REG_SR_ADDR(SR_RX_DSP1), U2_REG_SR_ADDR(SR_RX_CTRL1), USRP2_RX_SID_BASE + 1, true +            _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_RX_DSP1), U2_REG_SR_ADDR(SR_RX_CTRL1), USRP2_RX_SID_BASE + 1, true          ));          for (size_t dspno = 0; dspno < _mbc[mb].rx_dsps.size(); dspno++){              _mbc[mb].rx_dsps[dspno]->set_link_rate(USRP2_LINK_RATE_BPS); @@ -524,7 +524,7 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){          // create tx dsp control objects          ////////////////////////////////////////////////////////////////          _mbc[mb].tx_dsp = tx_dsp_core_200::make( -            _mbc[mb].iface, U2_REG_SR_ADDR(SR_TX_DSP), U2_REG_SR_ADDR(SR_TX_CTRL), USRP2_TX_ASYNC_SID +            _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_TX_DSP), U2_REG_SR_ADDR(SR_TX_CTRL), USRP2_TX_ASYNC_SID          );          _mbc[mb].tx_dsp->set_link_rate(USRP2_LINK_RATE_BPS);          _tree->access<double>(mb_path / "tick_rate") @@ -558,8 +558,9 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){          time64_rb_bases.rb_hi_pps = U2_REG_TIME64_HI_RB_PPS;          time64_rb_bases.rb_lo_pps = U2_REG_TIME64_LO_RB_PPS;          _mbc[mb].time64 = time64_core_200::make( -            _mbc[mb].iface, U2_REG_SR_ADDR(SR_TIME64), time64_rb_bases, mimo_clock_sync_delay_cycles +            _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_TIME64), time64_rb_bases, mimo_clock_sync_delay_cycles          ); +        //_mbc[mb].fifo_ctrl->poke32(0x7, 0x1234);          _tree->access<double>(mb_path / "tick_rate")              .subscribe(boost::bind(&time64_core_200::set_tick_rate, _mbc[mb].time64, _1));          _tree->create<time_spec_t>(mb_path / "time/now") @@ -582,7 +583,7 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){          ////////////////////////////////////////////////////////////////////          // create user-defined control objects          //////////////////////////////////////////////////////////////////// -        _mbc[mb].user = user_settings_core_200::make(_mbc[mb].iface, U2_REG_SR_ADDR(SR_USER_REGS)); +        _mbc[mb].user = user_settings_core_200::make(_mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_USER_REGS));          _tree->create<user_settings_core_200::user_reg_t>(mb_path / "user/regs")              .subscribe(boost::bind(&user_settings_core_200::set_reg, _mbc[mb].user, _1)); @@ -608,7 +609,7 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){              .subscribe(boost::bind(&usrp2_impl::set_db_eeprom, this, mb, "gdb", _1));          //create a new dboard interface and manager -        _mbc[mb].dboard_iface = make_usrp2_dboard_iface(_mbc[mb].iface, _mbc[mb].clock); +        _mbc[mb].dboard_iface = make_usrp2_dboard_iface(_mbc[mb].fifo_ctrl, _mbc[mb].iface, _mbc[mb].iface, _mbc[mb].clock);          _tree->create<dboard_iface::sptr>(mb_path / "dboards/A/iface").set(_mbc[mb].dboard_iface);          _mbc[mb].dboard_manager = dboard_manager::make(              rx_db_eeprom.id, tx_db_eeprom.id, gdb_eeprom.id, @@ -678,12 +679,12 @@ void usrp2_impl::set_db_eeprom(const std::string &mb, const std::string &type, c  }  sensor_value_t usrp2_impl::get_mimo_locked(const std::string &mb){ -    const bool lock = (_mbc[mb].iface->peek32(U2_REG_IRQ_RB) & (1<<10)) != 0; +    const bool lock = (_mbc[mb].fifo_ctrl->peek32(U2_REG_IRQ_RB) & (1<<10)) != 0;      return sensor_value_t("MIMO", lock, "locked", "unlocked");  }  sensor_value_t usrp2_impl::get_ref_locked(const std::string &mb){ -    const bool lock = (_mbc[mb].iface->peek32(U2_REG_IRQ_RB) & (1<<11)) != 0; +    const bool lock = (_mbc[mb].fifo_ctrl->peek32(U2_REG_IRQ_RB) & (1<<11)) != 0;      return sensor_value_t("Ref", lock, "locked", "unlocked");  } @@ -728,18 +729,18 @@ void usrp2_impl::update_clock_source(const std::string &mb, const std::string &s      case usrp2_iface::USRP_N210:      case usrp2_iface::USRP_N200_R4:      case usrp2_iface::USRP_N210_R4: -        if (source == "internal")       _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x12); -        else if (source == "external")  _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C); -        else if (source == "mimo")      _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15); +        if (source == "internal")       _mbc[mb].fifo_ctrl->poke32(U2_REG_MISC_CTRL_CLOCK, 0x12); +        else if (source == "external")  _mbc[mb].fifo_ctrl->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C); +        else if (source == "mimo")      _mbc[mb].fifo_ctrl->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15);          else throw uhd::value_error("unhandled clock configuration reference source: " + source);          _mbc[mb].clock->enable_external_ref(true); //USRP2P has an internal 10MHz TCXO          break;      case usrp2_iface::USRP2_REV3:      case usrp2_iface::USRP2_REV4: -        if (source == "internal")       _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x10); -        else if (source == "external")  _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C); -        else if (source == "mimo")      _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15); +        if (source == "internal")       _mbc[mb].fifo_ctrl->poke32(U2_REG_MISC_CTRL_CLOCK, 0x10); +        else if (source == "external")  _mbc[mb].fifo_ctrl->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C); +        else if (source == "mimo")      _mbc[mb].fifo_ctrl->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15);          else throw uhd::value_error("unhandled clock configuration reference source: " + source);          _mbc[mb].clock->enable_external_ref(source != "internal");          break; diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 291208eff..3d2fbf14f 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -18,6 +18,7 @@  #ifndef INCLUDED_USRP2_IMPL_HPP  #define INCLUDED_USRP2_IMPL_HPP +#include "gpio_core_200.hpp"  #include "usrp2_iface.hpp"  #include "usrp2_fifo_ctrl.hpp"  #include "clock_ctrl.hpp" @@ -53,14 +54,11 @@ static const size_t USRP2_SRAM_BYTES = size_t(1 << 20);  static const boost::uint32_t USRP2_TX_ASYNC_SID = 2;  static const boost::uint32_t USRP2_RX_SID_BASE = 3; -/*! - * Make a usrp2 dboard interface. - * \param iface the usrp2 interface object - * \param clk_ctrl the clock control object - * \return a sptr to a new dboard interface - */ +//! Make a usrp2 dboard interface.  uhd::usrp::dboard_iface::sptr make_usrp2_dboard_iface( -    usrp2_iface::sptr iface, +    wb_iface::sptr wb_iface, +    uhd::i2c_iface::sptr i2c_iface, +    uhd::spi_iface::sptr spi_iface,      usrp2_clock_ctrl::sptr clk_ctrl  ); | 
