diff options
Diffstat (limited to 'host/lib/usrp/usrp2')
| -rw-r--r-- | host/lib/usrp/usrp2/CMakeLists.txt | 29 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/dboard_iface.cpp | 57 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/dsp_impl.cpp | 24 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/io_impl.cpp | 3 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 32 | 
5 files changed, 85 insertions, 60 deletions
| diff --git a/host/lib/usrp/usrp2/CMakeLists.txt b/host/lib/usrp/usrp2/CMakeLists.txt new file mode 100644 index 000000000..f9907e21e --- /dev/null +++ b/host/lib/usrp/usrp2/CMakeLists.txt @@ -0,0 +1,29 @@ +# +# Copyright 2010 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 <http://www.gnu.org/licenses/>. +# + +#This file will be included by cmake, use absolute paths! + +LIBUHD_APPEND_SOURCES( +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/clock_control.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_impl.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_iface.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dsp_impl.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/io_impl.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/mboard_impl.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_iface.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_impl.cpp +) diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp index 74d80163c..372a5af07 100644 --- a/host/lib/usrp/usrp2/dboard_iface.cpp +++ b/host/lib/usrp/usrp2/dboard_iface.cpp @@ -29,6 +29,7 @@  using namespace uhd;  using namespace uhd::usrp; +using namespace boost::assign;  class usrp2_dboard_iface : public dboard_iface{  public: @@ -122,49 +123,42 @@ double usrp2_dboard_iface::get_clock_rate(unit_t){  void usrp2_dboard_iface::set_clock_enabled(unit_t unit, bool enb){      switch(unit){ -    case UNIT_RX: -        _clk_ctrl->enable_rx_dboard_clock(enb); -        return; -    case UNIT_TX: -        _clk_ctrl->enable_tx_dboard_clock(enb); -        return; +    case UNIT_RX: _clk_ctrl->enable_rx_dboard_clock(enb); return; +    case UNIT_TX: _clk_ctrl->enable_tx_dboard_clock(enb); return;      }  }  /***********************************************************************   * GPIO   **********************************************************************/ -static int unit_to_shift(dboard_iface::unit_t unit){ -    switch(unit){ -    case dboard_iface::UNIT_RX: return 0; -    case dboard_iface::UNIT_TX: return 16; -    } -    throw std::runtime_error("unknown unit type"); -} +static const uhd::dict<dboard_iface::unit_t, int> unit_to_shift = map_list_of +    (dboard_iface::UNIT_RX, 0) +    (dboard_iface::UNIT_TX, 16) +;  void usrp2_dboard_iface::set_gpio_ddr(unit_t unit, boost::uint16_t value){      _ddr_shadow = \ -        (_ddr_shadow & ~(0xffff << unit_to_shift(unit))) | -        (boost::uint32_t(value) << unit_to_shift(unit)); +        (_ddr_shadow & ~(0xffff << unit_to_shift[unit])) | +        (boost::uint32_t(value) << unit_to_shift[unit]);      _iface->poke32(FR_GPIO_DDR, _ddr_shadow);  }  boost::uint16_t usrp2_dboard_iface::read_gpio(unit_t unit){ -    return boost::uint16_t(_iface->peek32(FR_GPIO_IO) >> unit_to_shift(unit)); +    return boost::uint16_t(_iface->peek32(FR_GPIO_IO) >> unit_to_shift[unit]);  }  void usrp2_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t value){      //define mapping of unit to atr regs to register address      static const uhd::dict<          unit_t, uhd::dict<atr_reg_t, boost::uint32_t> -    > unit_to_atr_to_addr = boost::assign::map_list_of -        (UNIT_RX, boost::assign::map_list_of +    > unit_to_atr_to_addr = map_list_of +        (UNIT_RX, map_list_of              (ATR_REG_IDLE,        FR_ATR_IDLE_RXSIDE)              (ATR_REG_TX_ONLY,     FR_ATR_INTX_RXSIDE)              (ATR_REG_RX_ONLY,     FR_ATR_INRX_RXSIDE)              (ATR_REG_FULL_DUPLEX, FR_ATR_FULL_RXSIDE)          ) -        (UNIT_TX, boost::assign::map_list_of +        (UNIT_TX, map_list_of              (ATR_REG_IDLE,        FR_ATR_IDLE_TXSIDE)              (ATR_REG_TX_ONLY,     FR_ATR_INTX_TXSIDE)              (ATR_REG_RX_ONLY,     FR_ATR_INRX_TXSIDE) @@ -177,19 +171,10 @@ void usrp2_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t  /***********************************************************************   * SPI   **********************************************************************/ -/*! - * Static function to convert a unit type enum - * to an over-the-wire value for the spi device. - * \param unit the dboard interface unit type enum - * \return an over the wire representation - */ -static boost::uint8_t unit_to_otw_spi_dev(dboard_iface::unit_t unit){ -    switch(unit){ -    case dboard_iface::UNIT_TX: return SPI_SS_TX_DB; -    case dboard_iface::UNIT_RX: return SPI_SS_RX_DB; -    } -    throw std::invalid_argument("unknown unit type"); -} +static const uhd::dict<dboard_iface::unit_t, int> unit_to_spi_dev = map_list_of +    (dboard_iface::UNIT_TX, SPI_SS_TX_DB) +    (dboard_iface::UNIT_RX, SPI_SS_RX_DB) +;  void usrp2_dboard_iface::write_spi(      unit_t unit, @@ -197,7 +182,7 @@ void usrp2_dboard_iface::write_spi(      boost::uint32_t data,      size_t num_bits  ){ -    _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, false /*no rb*/); +    _iface->transact_spi(unit_to_spi_dev[unit], config, data, num_bits, false /*no rb*/);  }  boost::uint32_t usrp2_dboard_iface::read_write_spi( @@ -206,7 +191,7 @@ boost::uint32_t usrp2_dboard_iface::read_write_spi(      boost::uint32_t data,      size_t num_bits  ){ -    return _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, true /*rb*/); +    return _iface->transact_spi(unit_to_spi_dev[unit], config, data, num_bits, true /*rb*/);  }  /*********************************************************************** @@ -224,7 +209,7 @@ byte_vector_t usrp2_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes   * Aux DAX/ADC   **********************************************************************/  void usrp2_dboard_iface::_write_aux_dac(unit_t unit){ -    static const uhd::dict<unit_t, int> unit_to_spi_dac = boost::assign::map_list_of +    static const uhd::dict<unit_t, int> unit_to_spi_dac = map_list_of          (UNIT_RX, SPI_SS_RX_DAC)          (UNIT_TX, SPI_SS_TX_DAC)      ; @@ -248,7 +233,7 @@ void usrp2_dboard_iface::write_aux_dac(unit_t unit, int which, float value){  }  float usrp2_dboard_iface::read_aux_adc(unit_t unit, int which){ -    static const uhd::dict<unit_t, int> unit_to_spi_adc = boost::assign::map_list_of +    static const uhd::dict<unit_t, int> unit_to_spi_adc = map_list_of          (UNIT_RX, SPI_SS_RX_ADC)          (UNIT_TX, SPI_SS_TX_ADC)      ; diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index bd61ac376..195a9bc53 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -52,6 +52,23 @@ static boost::uint32_t calculate_freq_word_and_update_actual_freq(double &freq,      return freq_word;  } +// Check if requested decim/interp rate is: +//      multiple of 4, enable two halfband filters +//      multiple of 2, enable one halfband filter +//      handle remainder in CIC +static boost::uint32_t calculate_cic_word(size_t rate){ +    int hb0 = 0, hb1 = 0; +    if (not (rate & 0x1)){ +        hb0 = 1; +        rate /= 2; +    } +    if (not (rate & 0x1)){ +        hb1 = 1; +        rate /= 2; +    } +    return (hb1 << 9) | (hb0 << 8) | (rate & 0xff); +} +  static boost::uint32_t calculate_iq_scale_word(boost::int16_t i, boost::int16_t q){      return (boost::uint16_t(i) << 16) | (boost::uint16_t(q) << 0);  } @@ -81,7 +98,7 @@ void usrp2_impl::init_ddc_config(void){  void usrp2_impl::update_ddc_config(void){      //set the decimation -    _iface->poke32(FR_DSP_RX_DECIM_RATE, _ddc_decim); +    _iface->poke32(FR_DSP_RX_DECIM_RATE, calculate_cic_word(_ddc_decim));      //set the scaling      static const boost::int16_t default_rx_scale_iq = 1024; @@ -160,15 +177,14 @@ void usrp2_impl::init_duc_config(void){  void usrp2_impl::update_duc_config(void){      // Calculate CIC interpolation (i.e., without halfband interpolators) -    size_t tmp_interp = _duc_interp; -    while(tmp_interp > 128) tmp_interp /= 2; +    size_t tmp_interp = calculate_cic_word(_duc_interp) & 0xff;      // Calculate closest multiplier constant to reverse gain absent scale multipliers      double interp_cubed = std::pow(double(tmp_interp), 3);      boost::int16_t scale = rint((4096*std::pow(2, ceil(log2(interp_cubed))))/(1.65*interp_cubed));      //set the interpolation -    _iface->poke32(FR_DSP_TX_INTERP_RATE, _ddc_decim); +    _iface->poke32(FR_DSP_TX_INTERP_RATE, calculate_cic_word(_duc_interp));      //set the scaling      _iface->poke32(FR_DSP_TX_SCALE_IQ, calculate_iq_scale_word(scale, scale)); diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index a2e99c824..7c9d003ce 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -39,6 +39,9 @@ void usrp2_impl::io_init(void){      //initially empty copy buffer      _rx_copy_buff = asio::buffer("", 0); +    //init the expected rx seq number +    _rx_stream_id_to_packet_seq[0] = 0; +      //send a small data packet so the usrp2 knows the udp source port      managed_send_buffer::sptr send_buff = _data_transport->get_send_buff();      boost::uint32_t data = htonl(USRP2_INVALID_VRT_HEADER); diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 2b974fb9b..1dde8c054 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -113,31 +113,23 @@ device::sptr usrp2::make(const device_addr_t &device_addr){          device_addr["addr"], num2str(USRP2_UDP_CTRL_PORT)      ); -    //create a data transport -    udp_zero_copy::sptr data_transport = udp_zero_copy::make( -        device_addr["addr"], num2str(USRP2_UDP_DATA_PORT) -    ); - -    //resize the recv data transport buffers +    //extract the receive and send buffer sizes +    size_t recv_buff_size = 0, send_buff_size= 0 ;      if (device_addr.has_key("recv_buff_size")){ -        size_t num_byes = size_t(boost::lexical_cast<double>(device_addr["recv_buff_size"])); -        size_t actual_bytes = data_transport->resize_recv_buff_size(num_byes); -        if (num_byes != actual_bytes) std::cout << boost::format( -            "Target recv buffer size: %d\n" -            "Actual recv byffer size: %d" -        ) % num_byes % actual_bytes << std::endl; +        recv_buff_size = size_t(boost::lexical_cast<double>(device_addr["recv_buff_size"]));      } - -    //resize the send data transport buffers      if (device_addr.has_key("send_buff_size")){ -        size_t num_byes = size_t(boost::lexical_cast<double>(device_addr["send_buff_size"])); -        size_t actual_bytes = data_transport->resize_send_buff_size(num_byes); -        if (num_byes != actual_bytes) std::cout << boost::format( -            "Target send buffer size: %d\n" -            "Actual send byffer size: %d" -        ) % num_byes % actual_bytes << std::endl; +        send_buff_size = size_t(boost::lexical_cast<double>(device_addr["send_buff_size"]));      } +    //create a data transport +    udp_zero_copy::sptr data_transport = udp_zero_copy::make( +        device_addr["addr"], +        num2str(USRP2_UDP_DATA_PORT), +        recv_buff_size, +        send_buff_size +    ); +      //create the usrp2 implementation guts      return device::sptr(          new usrp2_impl(ctrl_transport, data_transport) | 
