diff options
Diffstat (limited to 'host/lib/usrp')
| -rw-r--r-- | host/lib/usrp/usrp2/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/clock_ctrl.cpp | 105 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/codec_ctrl.cpp | 32 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/dboard_iface.cpp | 26 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/dboard_impl.cpp | 12 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/dsp_impl.cpp | 12 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/fw_common.h | 16 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 60 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/serdes_ctrl.cpp | 4 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_clk_regs.hpp | 63 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_iface.cpp | 13 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_iface.hpp | 37 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_regs.cpp | 97 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_regs.hpp | 170 | 
14 files changed, 463 insertions, 185 deletions
diff --git a/host/lib/usrp/usrp2/CMakeLists.txt b/host/lib/usrp/usrp2/CMakeLists.txt index 99d0b8bdd..1da8f4419 100644 --- a/host/lib/usrp/usrp2/CMakeLists.txt +++ b/host/lib/usrp/usrp2/CMakeLists.txt @@ -34,4 +34,5 @@ LIBUHD_APPEND_SOURCES(      ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_impl.cpp      ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_impl.hpp      ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_regs.hpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_regs.cpp  ) diff --git a/host/lib/usrp/usrp2/clock_ctrl.cpp b/host/lib/usrp/usrp2/clock_ctrl.cpp index b9be037c0..5ed8ec079 100644 --- a/host/lib/usrp/usrp2/clock_ctrl.cpp +++ b/host/lib/usrp/usrp2/clock_ctrl.cpp @@ -18,6 +18,7 @@  #include "clock_ctrl.hpp"  #include "ad9510_regs.hpp"  #include "usrp2_regs.hpp" //spi slave constants +#include "usrp2_clk_regs.hpp"  #include <uhd/utils/assert.hpp>  #include <boost/cstdint.hpp> @@ -29,10 +30,12 @@ using namespace uhd;  class usrp2_clock_ctrl_impl : public usrp2_clock_ctrl{  public:      usrp2_clock_ctrl_impl(usrp2_iface::sptr iface){ -        _iface = iface; +        _iface = iface; //_iface has get_hw_rev(), which lets us know if it's a USRP2+ (>=0x80) or USRP2 (<0x80). + +        clk_regs = usrp2_clk_regs_t(_iface->get_hw_rev());          _ad9510_regs.cp_current_setting = ad9510_regs_t::CP_CURRENT_SETTING_3_0MA; -        this->write_reg(0x09); +        this->write_reg(clk_regs.pll_3);          // Setup the clock registers to 100MHz:          //  This was already done by the firmware (or the host couldnt communicate). @@ -42,20 +45,20 @@ public:          _ad9510_regs.pll_power_down = ad9510_regs_t::PLL_POWER_DOWN_NORMAL;          _ad9510_regs.prescaler_value = ad9510_regs_t::PRESCALER_VALUE_DIV2; -        this->write_reg(0x0A); +        this->write_reg(clk_regs.pll_4);          _ad9510_regs.acounter = 0; -        this->write_reg(0x04); +        this->write_reg(clk_regs.acounter);          _ad9510_regs.bcounter_msb = 0;          _ad9510_regs.bcounter_lsb = 5; -        this->write_reg(0x05); -        this->write_reg(0x06); +        this->write_reg(clk_regs.bcounter_msb); +        this->write_reg(clk_regs.bcounter_lsb);          _ad9510_regs.ref_counter_msb = 0;          _ad9510_regs.ref_counter_lsb = 1; // r divider = 1 -        this->write_reg(0x0B); -        this->write_reg(0x0C); +        this->write_reg(clk_regs.ref_counter_msb); +        this->write_reg(clk_regs.ref_counter_lsb);          /* regs will be updated in commands below */ @@ -76,11 +79,12 @@ public:      }      //uses output clock 7 (cmos) +    //this clock is the same between USRP2 and USRP2+ and so this fn does not get a switch statement      void enable_rx_dboard_clock(bool enb){          _ad9510_regs.power_down_lvds_cmos_out7 = enb? 0 : 1;          _ad9510_regs.lvds_cmos_select_out7 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT7_CMOS;          _ad9510_regs.output_level_lvds_out7 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT7_1_75MA; -        this->write_reg(0x43); +        this->write_reg(clk_regs.output(clk_regs.rx_db));          this->update_regs();      } @@ -96,8 +100,8 @@ public:          _ad9510_regs.divider_low_cycles_out7 = low - 1;          _ad9510_regs.divider_high_cycles_out7 = high - 1;          //write the registers -        this->write_reg(0x56); -        this->write_reg(0x57); +        this->write_reg(clk_regs.div_lo(clk_regs.rx_db)); +        this->write_reg(clk_regs.div_hi(clk_regs.rx_db));          this->update_regs();      } @@ -107,29 +111,50 @@ public:          return rates;      } -    //uses output clock 6 (cmos) +    //uses output clock 6 (cmos) on USRP2 and output clock 5 (cmos) on USRP2+      void enable_tx_dboard_clock(bool enb){ -        _ad9510_regs.power_down_lvds_cmos_out6 = enb? 0 : 1; -        _ad9510_regs.lvds_cmos_select_out6 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT6_CMOS; -        _ad9510_regs.output_level_lvds_out6 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT6_1_75MA; -        this->write_reg(0x42); +        switch(clk_regs.tx_db) { +        case 5: //USRP2+ +          _ad9510_regs.power_down_lvds_cmos_out5 = enb? 0 : 1; +          _ad9510_regs.lvds_cmos_select_out5 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT5_CMOS; +          _ad9510_regs.output_level_lvds_out5 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT5_1_75MA; +          break; +        case 6: //USRP2 +          _ad9510_regs.power_down_lvds_cmos_out6 = enb? 0 : 1; +          _ad9510_regs.lvds_cmos_select_out6 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT6_CMOS; +          _ad9510_regs.output_level_lvds_out6 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT6_1_75MA; +          break; +        } + +        this->write_reg(clk_regs.output(clk_regs.tx_db));          this->update_regs();      }      void set_rate_tx_dboard_clock(double rate){          assert_has(get_rates_tx_dboard_clock(), rate, "tx dboard clock rate");          size_t divider = size_t(rate/get_master_clock_rate()); -        //bypass when the divider ratio is one -        _ad9510_regs.bypass_divider_out6 = (divider == 1)? 1 : 0;          //calculate the low and high dividers          size_t high = divider/2;          size_t low = divider - high; -        //set the registers (divider - 1) -        _ad9510_regs.divider_low_cycles_out6 = low - 1; -        _ad9510_regs.divider_high_cycles_out6 = high - 1; + +        switch(clk_regs.tx_db) { +        case 5: //USRP2+ +          _ad9510_regs.bypass_divider_out5 = (divider == 1)? 1 : 0; +          _ad9510_regs.divider_low_cycles_out5 = low - 1; +          _ad9510_regs.divider_high_cycles_out5 = high - 1; +          break; +        case 6: //USRP2 +          //bypass when the divider ratio is one +          _ad9510_regs.bypass_divider_out6 = (divider == 1)? 1 : 0; +          //set the registers (divider - 1) +          _ad9510_regs.divider_low_cycles_out6 = low - 1; +          _ad9510_regs.divider_high_cycles_out6 = high - 1; +          break; +        } +          //write the registers -        this->write_reg(0x54); -        this->write_reg(0x55); +        this->write_reg(clk_regs.div_hi(clk_regs.tx_db)); +        this->write_reg(clk_regs.div_lo(clk_regs.tx_db));          this->update_regs();      } @@ -147,7 +172,7 @@ public:              ad9510_regs_t::CHARGE_PUMP_MODE_3STATE ;          _ad9510_regs.pll_mux_control = ad9510_regs_t::PLL_MUX_CONTROL_DLD_HIGH;          _ad9510_regs.pfd_polarity = ad9510_regs_t::PFD_POLARITY_POS; -        this->write_reg(0x08); +        this->write_reg(clk_regs.pll_2);          this->update_regs();      } @@ -170,32 +195,44 @@ private:       */      void update_regs(void){          _ad9510_regs.update_registers = 1; -        this->write_reg(0x5a); +        this->write_reg(clk_regs.update);      }      //uses output clock 3 (pecl) +    //this is the same between USRP2 and USRP2+ and doesn't get a switch statement      void enable_dac_clock(bool enb){          _ad9510_regs.power_down_lvpecl_out3 = (enb)?              ad9510_regs_t::POWER_DOWN_LVPECL_OUT3_NORMAL :              ad9510_regs_t::POWER_DOWN_LVPECL_OUT3_SAFE_PD;          _ad9510_regs.output_level_lvpecl_out3 = ad9510_regs_t::OUTPUT_LEVEL_LVPECL_OUT3_810MV;          _ad9510_regs.bypass_divider_out3 = 1; -        this->write_reg(0x3F); -        this->write_reg(0x4F); +        this->write_reg(clk_regs.output(clk_regs.dac)); +        this->write_reg(clk_regs.div_hi(clk_regs.dac));          this->update_regs();      } -    //uses output clock 4 (lvds) +    //uses output clock 4 (lvds) on USRP2 and output clock 2 (lvpecl) on USRP2+      void enable_adc_clock(bool enb){ -        _ad9510_regs.power_down_lvds_cmos_out4 = enb? 0 : 1; -        _ad9510_regs.lvds_cmos_select_out4 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT4_LVDS; -        _ad9510_regs.output_level_lvds_out4 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT4_1_75MA; -        _ad9510_regs.bypass_divider_out4 = 1; -        this->write_reg(0x40); -        this->write_reg(0x51); +        switch(clk_regs.adc) { +        case 2: +          _ad9510_regs.power_down_lvpecl_out2 = enb? ad9510_regs_t::POWER_DOWN_LVPECL_OUT2_NORMAL : ad9510_regs_t::POWER_DOWN_LVPECL_OUT2_SAFE_PD; +          _ad9510_regs.output_level_lvpecl_out2 = ad9510_regs_t::OUTPUT_LEVEL_LVPECL_OUT2_500MV; +          _ad9510_regs.bypass_divider_out2 = 1; +          break; +        case 4: +          _ad9510_regs.power_down_lvds_cmos_out4 = enb? 0 : 1; +          _ad9510_regs.lvds_cmos_select_out4 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT4_LVDS; +          _ad9510_regs.output_level_lvds_out4 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT4_1_75MA; +          _ad9510_regs.bypass_divider_out4 = 1; +          break; +        } + +        this->write_reg(clk_regs.output(clk_regs.adc)); +        this->write_reg(clk_regs.div_hi(clk_regs.adc));          this->update_regs();      } +    usrp2_clk_regs_t clk_regs;      usrp2_iface::sptr _iface;      ad9510_regs_t _ad9510_regs;  }; diff --git a/host/lib/usrp/usrp2/codec_ctrl.cpp b/host/lib/usrp/usrp2/codec_ctrl.cpp index 32cc13ded..107894d2a 100644 --- a/host/lib/usrp/usrp2/codec_ctrl.cpp +++ b/host/lib/usrp/usrp2/codec_ctrl.cpp @@ -17,6 +17,7 @@  #include "codec_ctrl.hpp"  #include "ad9777_regs.hpp" +#include "ads62p44_regs.hpp"  #include "usrp2_regs.hpp"  #include <boost/cstdint.hpp>  #include <boost/foreach.hpp> @@ -57,7 +58,16 @@ public:          }          //power-up adc -        _iface->poke32(U2_REG_MISC_CTRL_ADC, U2_FLAG_MISC_CTRL_ADC_ON); +        if(_iface->get_hw_rev() < USRP2P_FIRST_HW_REV) { //if we're on a USRP2 +          _iface->poke32(_iface->regs.misc_ctrl_adc, U2_FLAG_MISC_CTRL_ADC_ON); +        } else { //we're on a USRP2+ +          _ads62p44_regs.reset = 1; +          this->send_ads62p44_reg(0x00); //issue a reset to the ADC +          //everything else should be pretty much default, i think +//          _ads62p44_regs.decimation = DECIMATION_DECIMATE_1; +           + +        }      }      ~usrp2_codec_ctrl_impl(void){ @@ -66,11 +76,21 @@ public:          this->send_ad9777_reg(0);          //power-down adc -        _iface->poke32(U2_REG_MISC_CTRL_ADC, U2_FLAG_MISC_CTRL_ADC_OFF); +        if(_iface->get_hw_rev() < USRP2P_FIRST_HW_REV) { //if we're on a USRP2 +          _iface->poke32(_iface->regs.misc_ctrl_adc, U2_FLAG_MISC_CTRL_ADC_OFF); +        } else { //we're on a USRP2+ +//          _ads62p44_regs.reset = 1; +//          this->send_ads62p44_reg(0x00); //issue a reset to the ADC +          //everything else should be pretty much default, i think +//          _ads62p44_regs.decimation = DECIMATION_DECIMATE_1; +           + +        }      }  private:      ad9777_regs_t _ad9777_regs; +    ads62p44_regs_t _ads62p44_regs;      usrp2_iface::sptr _iface;      void send_ad9777_reg(boost::uint8_t addr){ @@ -81,6 +101,14 @@ private:              reg, 16, false /*no rb*/          );      } + +    void send_ads62p44_reg(boost::uint8_t addr) { +        boost::uint16_t reg = _ads62p44_regs.get_write_reg(addr); +        _iface->transact_spi( +            SPI_SS_ADS62P44, spi_config_t::EDGE_RISE, +            reg, 16, false /*no rb*/ +        ); +    }  };  /*********************************************************************** diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp index 6f2fb9396..5c81856bb 100644 --- a/host/lib/usrp/usrp2/dboard_iface.cpp +++ b/host/lib/usrp/usrp2/dboard_iface.cpp @@ -168,8 +168,8 @@ void usrp2_dboard_iface::set_pin_ctrl(unit_t unit, boost::uint16_t value){      //write the selection mux value to register      switch(unit){ -    case UNIT_RX: _iface->poke32(U2_REG_GPIO_RX_SEL, new_sels); return; -    case UNIT_TX: _iface->poke32(U2_REG_GPIO_TX_SEL, new_sels); return; +    case UNIT_RX: _iface->poke32(_iface->regs.gpio_rx_sel, new_sels); return; +    case UNIT_TX: _iface->poke32(_iface->regs.gpio_tx_sel, new_sels); return;      }  } @@ -177,18 +177,18 @@ 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]); -    _iface->poke32(U2_REG_GPIO_DDR, _ddr_shadow); +    _iface->poke32(_iface->regs.gpio_ddr, _ddr_shadow);  }  void usrp2_dboard_iface::write_gpio(unit_t unit, boost::uint16_t value){      _gpio_shadow = \          (_gpio_shadow & ~(0xffff << unit_to_shift[unit])) |          (boost::uint32_t(value) << unit_to_shift[unit]); -    _iface->poke32(U2_REG_GPIO_IO, _gpio_shadow); +    _iface->poke32(_iface->regs.gpio_io, _gpio_shadow);  }  boost::uint16_t usrp2_dboard_iface::read_gpio(unit_t unit){ -    return boost::uint16_t(_iface->peek32(U2_REG_GPIO_IO) >> unit_to_shift[unit]); +    return boost::uint16_t(_iface->peek32(_iface->regs.gpio_io) >> unit_to_shift[unit]);  }  void usrp2_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t value){ @@ -197,16 +197,16 @@ void usrp2_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t          unit_t, uhd::dict<atr_reg_t, boost::uint32_t>      > unit_to_atr_to_addr = map_list_of          (UNIT_RX, map_list_of -            (ATR_REG_IDLE,        U2_REG_ATR_IDLE_RXSIDE) -            (ATR_REG_TX_ONLY,     U2_REG_ATR_INTX_RXSIDE) -            (ATR_REG_RX_ONLY,     U2_REG_ATR_INRX_RXSIDE) -            (ATR_REG_FULL_DUPLEX, U2_REG_ATR_FULL_RXSIDE) +            (ATR_REG_IDLE,        _iface->regs.atr_idle_rxside) +            (ATR_REG_TX_ONLY,     _iface->regs.atr_intx_rxside) +            (ATR_REG_RX_ONLY,     _iface->regs.atr_inrx_rxside) +            (ATR_REG_FULL_DUPLEX, _iface->regs.atr_full_rxside)          )          (UNIT_TX, map_list_of -            (ATR_REG_IDLE,        U2_REG_ATR_IDLE_TXSIDE) -            (ATR_REG_TX_ONLY,     U2_REG_ATR_INTX_TXSIDE) -            (ATR_REG_RX_ONLY,     U2_REG_ATR_INRX_TXSIDE) -            (ATR_REG_FULL_DUPLEX, U2_REG_ATR_FULL_TXSIDE) +            (ATR_REG_IDLE,        _iface->regs.atr_idle_txside) +            (ATR_REG_TX_ONLY,     _iface->regs.atr_intx_txside) +            (ATR_REG_RX_ONLY,     _iface->regs.atr_inrx_txside) +            (ATR_REG_FULL_DUPLEX, _iface->regs.atr_full_txside)          )      ;      _iface->poke16(unit_to_atr_to_addr[unit][atr], value); diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index 8942f9d31..07e36a21b 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -35,8 +35,8 @@ using namespace uhd::usrp;   **********************************************************************/  void usrp2_mboard_impl::dboard_init(void){      //read the dboard eeprom to extract the dboard ids -    _rx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_RX_DB, 0, dboard_eeprom_t::num_bytes())); -    _tx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_TX_DB, 0, dboard_eeprom_t::num_bytes())); +    _rx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(USRP2_I2C_ADDR_RX_DB, 0, dboard_eeprom_t::num_bytes())); +    _tx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(USRP2_I2C_ADDR_TX_DB, 0, dboard_eeprom_t::num_bytes()));      //create a new dboard interface and manager      _dboard_iface = make_usrp2_dboard_iface(_iface, _clock_ctrl); @@ -103,7 +103,7 @@ void usrp2_mboard_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){              UHD_ASSERT_THROW(_rx_subdevs_in_use.size() == 1);              wax::obj rx_subdev = _dboard_manager->get_rx_subdev(_rx_subdevs_in_use.at(0));              std::cout << "Using: " << rx_subdev[SUBDEV_PROP_NAME].as<std::string>() << std::endl; -            _iface->poke32(U2_REG_DSP_RX_MUX, dsp_type1::calc_rx_mux_word( +            _iface->poke32(_iface->regs.dsp_rx_mux, dsp_type1::calc_rx_mux_word(                  rx_subdev[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()              ));          } @@ -111,7 +111,7 @@ void usrp2_mboard_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){      case DBOARD_PROP_DBOARD_ID:          _rx_db_eeprom.id = val.as<dboard_id_t>(); -        _iface->write_eeprom(I2C_ADDR_RX_DB, 0, _rx_db_eeprom.get_eeprom_bytes()); +        _iface->write_eeprom(USRP2_I2C_ADDR_RX_DB, 0, _rx_db_eeprom.get_eeprom_bytes());          return;      default: UHD_THROW_PROP_SET_ERROR(); @@ -162,7 +162,7 @@ void usrp2_mboard_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){              UHD_ASSERT_THROW(_tx_subdevs_in_use.size() == 1);              wax::obj tx_subdev = _dboard_manager->get_tx_subdev(_tx_subdevs_in_use.at(0));              std::cout << "Using: " << tx_subdev[SUBDEV_PROP_NAME].as<std::string>() << std::endl; -            _iface->poke32(U2_REG_DSP_TX_MUX, dsp_type1::calc_tx_mux_word( +            _iface->poke32(_iface->regs.dsp_tx_mux, dsp_type1::calc_tx_mux_word(                  tx_subdev[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()              ));          } @@ -170,7 +170,7 @@ void usrp2_mboard_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){      case DBOARD_PROP_DBOARD_ID:          _tx_db_eeprom.id = val.as<dboard_id_t>(); -        _iface->write_eeprom(I2C_ADDR_TX_DB, 0, _tx_db_eeprom.get_eeprom_bytes()); +        _iface->write_eeprom(USRP2_I2C_ADDR_TX_DB, 0, _tx_db_eeprom.get_eeprom_bytes());          return;      default: UHD_THROW_PROP_SET_ERROR(); diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index 7d9cdc441..936b1f7a2 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -86,7 +86,7 @@ void usrp2_mboard_impl::ddc_set(const wax::obj &key, const wax::obj &val){      case DSP_PROP_FREQ_SHIFT:{              double new_freq = val.as<double>(); -            _iface->poke32(U2_REG_DSP_RX_FREQ, +            _iface->poke32(_iface->regs.dsp_rx_freq,                  dsp_type1::calc_cordic_word_and_update(new_freq, get_master_clock_freq())              );              _ddc_freq = new_freq; //shadow @@ -98,11 +98,11 @@ void usrp2_mboard_impl::ddc_set(const wax::obj &key, const wax::obj &val){              _ddc_decim = pick_closest_rate(extact_rate, _allowed_decim_and_interp_rates);              //set the decimation -            _iface->poke32(U2_REG_DSP_RX_DECIM_RATE, dsp_type1::calc_cic_filter_word(_ddc_decim)); +            _iface->poke32(_iface->regs.dsp_rx_decim_rate, dsp_type1::calc_cic_filter_word(_ddc_decim));              //set the scaling              static const boost::int16_t default_rx_scale_iq = 1024; -            _iface->poke32(U2_REG_DSP_RX_SCALE_IQ, +            _iface->poke32(_iface->regs.dsp_rx_scale_iq,                  dsp_type1::calc_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq)              );          } @@ -161,7 +161,7 @@ void usrp2_mboard_impl::duc_set(const wax::obj &key, const wax::obj &val){      case DSP_PROP_FREQ_SHIFT:{              double new_freq = val.as<double>(); -            _iface->poke32(U2_REG_DSP_TX_FREQ, +            _iface->poke32(_iface->regs.dsp_tx_freq,                  dsp_type1::calc_cordic_word_and_update(new_freq, get_master_clock_freq())              );              _duc_freq = new_freq; //shadow @@ -173,10 +173,10 @@ void usrp2_mboard_impl::duc_set(const wax::obj &key, const wax::obj &val){              _duc_interp = pick_closest_rate(extact_rate, _allowed_decim_and_interp_rates);              //set the interpolation -            _iface->poke32(U2_REG_DSP_TX_INTERP_RATE, dsp_type1::calc_cic_filter_word(_duc_interp)); +            _iface->poke32(_iface->regs.dsp_tx_interp_rate, dsp_type1::calc_cic_filter_word(_duc_interp));              //set the scaling -            _iface->poke32(U2_REG_DSP_TX_SCALE_IQ, dsp_type1::calc_iq_scale_word(_duc_interp)); +            _iface->poke32(_iface->regs.dsp_tx_scale_iq, dsp_type1::calc_iq_scale_word(_duc_interp));          }          return; diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index fd728e393..c4dabf5bc 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -44,6 +44,22 @@ extern "C" {  #define USRP2_UDP_CTRL_PORT 49152  #define USRP2_UDP_DATA_PORT 49153 +//////////////////////////////////////////////////////////////////////// +// I2C addresses +//////////////////////////////////////////////////////////////////////// +#define USRP2_I2C_DEV_EEPROM  0x50 // 24LC02[45]:  7-bits 1010xxx +#define	USRP2_I2C_ADDR_MBOARD (USRP2_I2C_DEV_EEPROM | 0x0) +#define	USRP2_I2C_ADDR_TX_DB  (USRP2_I2C_DEV_EEPROM | 0x4) +#define	USRP2_I2C_ADDR_RX_DB  (USRP2_I2C_DEV_EEPROM | 0x5) + +//////////////////////////////////////////////////////////////////////// +// EEPROM Layout +//////////////////////////////////////////////////////////////////////// +#define USRP2_EE_MBOARD_REV_LSB  0x00 //1 byte +#define USRP2_EE_MBOARD_REV_MSB  0x01 //1 byte +#define USRP2_EE_MBOARD_MAC_ADDR 0x02 //6 bytes +#define USRP2_EE_MBOARD_IP_ADDR  0x0C //uint32, big-endian +  typedef enum{      USRP2_CTRL_ID_HUH_WHAT = ' ',      //USRP2_CTRL_ID_FOR_SURE, //TODO error condition enums diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index b3b03c11c..133e6f989 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -45,8 +45,11 @@ usrp2_mboard_impl::usrp2_mboard_impl(      _iface = usrp2_iface::make(ctrl_transport);      //extract the mboard rev numbers -    _rev_lo = _iface->read_eeprom(I2C_ADDR_MBOARD, EE_MBOARD_REV_LSB, 1).at(0); -    _rev_hi = _iface->read_eeprom(I2C_ADDR_MBOARD, EE_MBOARD_REV_MSB, 1).at(0); +    _rev_lo = _iface->read_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_REV_LSB, 1).at(0); +    _rev_hi = _iface->read_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_REV_MSB, 1).at(0); + +    //set the device revision (USRP2 or USRP2+) based on the above +    _iface->set_hw_rev((_rev_hi << 8) | _rev_lo);      //contruct the interfaces to mboard perifs      _clock_ctrl = usrp2_clock_ctrl::make(_iface); @@ -67,24 +70,25 @@ usrp2_mboard_impl::usrp2_mboard_impl(          _allowed_decim_and_interp_rates.push_back(i);      } -    //init the rx control registers -    _iface->poke32(U2_REG_RX_CTRL_NSAMPS_PER_PKT, _io_helper.get_max_recv_samps_per_packet()); -    _iface->poke32(U2_REG_RX_CTRL_NCHANNELS, 1); -    _iface->poke32(U2_REG_RX_CTRL_CLEAR_OVERRUN, 1); //reset -    _iface->poke32(U2_REG_RX_CTRL_VRT_HEADER, 0 +    //setup the vrt rx registers +    _iface->poke32(_iface->regs.rx_ctrl_nsamps_per_pkt, _io_helper.get_max_recv_samps_per_packet()); +    _iface->poke32(_iface->regs.rx_ctrl_nchannels, 1); +    _iface->poke32(_iface->regs.rx_ctrl_clear_overrun, 1); //reset +    _iface->poke32(_iface->regs.rx_ctrl_vrt_header, 0 +          | (0x1 << 28) //if data with stream id          | (0x1 << 26) //has trailer          | (0x3 << 22) //integer time other          | (0x1 << 20) //fractional time sample count      ); -    _iface->poke32(U2_REG_RX_CTRL_VRT_STREAM_ID, 0); -    _iface->poke32(U2_REG_RX_CTRL_VRT_TRAILER, 0); -    _iface->poke32(U2_REG_TIME64_TPS, size_t(get_master_clock_freq())); +    _iface->poke32(_iface->regs.rx_ctrl_vrt_stream_id, 0); +    _iface->poke32(_iface->regs.rx_ctrl_vrt_trailer, 0); +    _iface->poke32(_iface->regs.time64_tps, size_t(get_master_clock_freq()));      //init the tx control registers -    _iface->poke32(U2_REG_TX_CTRL_NUM_CHAN, 0);    //1 channel -    _iface->poke32(U2_REG_TX_CTRL_CLEAR_STATE, 1); //reset -    _iface->poke32(U2_REG_TX_CTRL_REPORT_SID, 1);  //sid 1 (different from rx) +    _iface->poke32(_iface->regs.tx_ctrl_num_chan, 0);    //1 channel +    _iface->poke32(_iface->regs.tx_ctrl_clear_state, 1); //reset +    _iface->poke32(_iface->regs.tx_ctrl_report_sid, 1);  //sid 1 (different from rx)      //init the ddc      init_ddc_config(); @@ -134,13 +138,13 @@ void usrp2_mboard_impl::update_clock_config(void){      }      //set the pps flags -    _iface->poke32(U2_REG_TIME64_FLAGS, pps_flags); +    _iface->poke32(_iface->regs.time64_flags, pps_flags);      //clock source ref 10mhz      switch(_clock_config.ref_source){ -    case clock_config_t::REF_INT : _iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x10); break; -    case clock_config_t::REF_SMA : _iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C); break; -    case clock_config_t::REF_MIMO: _iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15); break; +    case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x10); break; +    case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break; +    case clock_config_t::REF_MIMO: _iface->poke32(_iface->regs.misc_ctrl_clock, 0x15); break;      default: throw std::runtime_error("usrp2: unhandled clock configuration reference source");      } @@ -151,22 +155,22 @@ void usrp2_mboard_impl::update_clock_config(void){  void usrp2_mboard_impl::set_time_spec(const time_spec_t &time_spec, bool now){      //set the ticks -    _iface->poke32(U2_REG_TIME64_TICKS, time_spec.get_tick_count(get_master_clock_freq())); +    _iface->poke32(_iface->regs.time64_ticks, time_spec.get_tick_count(get_master_clock_freq()));      //set the flags register      boost::uint32_t imm_flags = (now)? U2_FLAG_TIME64_LATCH_NOW : U2_FLAG_TIME64_LATCH_NEXT_PPS; -    _iface->poke32(U2_REG_TIME64_IMM, imm_flags); +    _iface->poke32(_iface->regs.time64_imm, imm_flags);      //set the seconds (latches in all 3 registers) -    _iface->poke32(U2_REG_TIME64_SECS, boost::uint32_t(time_spec.get_full_secs())); +    _iface->poke32(_iface->regs.time64_secs, boost::uint32_t(time_spec.get_full_secs()));  }  void usrp2_mboard_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ -    _iface->poke32(U2_REG_RX_CTRL_STREAM_CMD, dsp_type1::calc_stream_cmd_word( +    _iface->poke32(_iface->regs.rx_ctrl_stream_cmd, dsp_type1::calc_stream_cmd_word(          stream_cmd, _io_helper.get_max_recv_samps_per_packet()      )); -    _iface->poke32(U2_REG_RX_CTRL_TIME_SECS,  boost::uint32_t(stream_cmd.time_spec.get_full_secs())); -    _iface->poke32(U2_REG_RX_CTRL_TIME_TICKS, stream_cmd.time_spec.get_tick_count(get_master_clock_freq())); +    _iface->poke32(_iface->regs.rx_ctrl_time_secs,  boost::uint32_t(stream_cmd.time_spec.get_full_secs())); +    _iface->poke32(_iface->regs.rx_ctrl_time_ticks, stream_cmd.time_spec.get_tick_count(get_master_clock_freq()));  }  /*********************************************************************** @@ -179,14 +183,14 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){      //handle the other props      if (key.type() == typeid(std::string)){          if (key.as<std::string>() == "mac-addr"){ -            byte_vector_t bytes = _iface->read_eeprom(I2C_ADDR_MBOARD, EE_MBOARD_MAC_ADDR, 6); +            byte_vector_t bytes = _iface->read_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_MAC_ADDR, 6);              val = mac_addr_t::from_bytes(bytes).to_string();              return;          }          if (key.as<std::string>() == "ip-addr"){              boost::asio::ip::address_v4::bytes_type bytes; -            std::copy(_iface->read_eeprom(I2C_ADDR_MBOARD, EE_MBOARD_IP_ADDR, 4), bytes); +            std::copy(_iface->read_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, 4), bytes);              val = boost::asio::ip::address_v4(bytes).to_string();              return;          } @@ -249,7 +253,7 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){      case MBOARD_PROP_TIME_NOW:{              usrp2_iface::pair64 time64( -                _iface->peek64(U2_REG_TIME64_SECS_RB, U2_REG_TIME64_TICKS_RB) +                _iface->peek64(_iface->regs.time64_secs_rb, _iface->regs.time64_ticks_rb)              );              val = time_spec_t(                  time64.first, time64.second, get_master_clock_freq() @@ -269,14 +273,14 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){      if (key.type() == typeid(std::string)){          if (key.as<std::string>() == "mac-addr"){              byte_vector_t bytes = mac_addr_t::from_string(val.as<std::string>()).to_bytes(); -            _iface->write_eeprom(I2C_ADDR_MBOARD, EE_MBOARD_MAC_ADDR, bytes); +            _iface->write_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_MAC_ADDR, bytes);              return;          }          if (key.as<std::string>() == "ip-addr"){              byte_vector_t bytes(4);              std::copy(boost::asio::ip::address_v4::from_string(val.as<std::string>()).to_bytes(), bytes); -            _iface->write_eeprom(I2C_ADDR_MBOARD, EE_MBOARD_IP_ADDR, bytes); +            _iface->write_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, bytes);              return;          }      } diff --git a/host/lib/usrp/usrp2/serdes_ctrl.cpp b/host/lib/usrp/usrp2/serdes_ctrl.cpp index e83dceb96..1cda22f45 100644 --- a/host/lib/usrp/usrp2/serdes_ctrl.cpp +++ b/host/lib/usrp/usrp2/serdes_ctrl.cpp @@ -27,11 +27,11 @@ class usrp2_serdes_ctrl_impl : public usrp2_serdes_ctrl{  public:      usrp2_serdes_ctrl_impl(usrp2_iface::sptr iface){          _iface = iface; -        _iface->poke32(U2_REG_MISC_CTRL_SERDES, U2_FLAG_MISC_CTRL_SERDES_ENABLE | U2_FLAG_MISC_CTRL_SERDES_RXEN); +        _iface->poke32(_iface->regs.misc_ctrl_serdes, U2_FLAG_MISC_CTRL_SERDES_ENABLE | U2_FLAG_MISC_CTRL_SERDES_RXEN);      }      ~usrp2_serdes_ctrl_impl(void){ -        _iface->poke32(U2_REG_MISC_CTRL_SERDES, 0); //power-down +        _iface->poke32(_iface->regs.misc_ctrl_serdes, 0); //power-down      }  private: diff --git a/host/lib/usrp/usrp2/usrp2_clk_regs.hpp b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp new file mode 100644 index 000000000..d057fb342 --- /dev/null +++ b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp @@ -0,0 +1,63 @@ +// +// 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/>. +// + +#ifndef INCLUDED_USRP2_CLK_REGS_HPP +#define INCLUDED_USRP2_CLK_REGS_HPP + +#include "usrp2_regs.hpp" + +class usrp2_clk_regs_t { +public: +  usrp2_clk_regs_t(void) { ; } +  usrp2_clk_regs_t(int hw_rev) {    +    test = 0; +    fpga = 1; +    adc = (hw_rev>=USRP2P_FIRST_HW_REV) ? 2 : 4; +    dac = 3; +    serdes = (hw_rev>=USRP2P_FIRST_HW_REV) ? 4 : 2; //only used by usrp2+ +    tx_db = (hw_rev>=USRP2P_FIRST_HW_REV) ? 5 : 6; +    exp = (hw_rev>=USRP2P_FIRST_HW_REV) ? 6 : 5; +    rx_db = 7; +  } + +  static int output(int clknum) { return 0x3C + clknum; } +  static int div_lo(int clknum) { return 0x48 + 2 * clknum; } +  static int div_hi(int clknum) { return 0x49 + 2 * clknum; } + +  const static int acounter = 0x04; +  const static int bcounter_msb = 0x05; +  const static int bcounter_lsb = 0x06; +  const static int pll_1 = 0x07; +  const static int pll_2 = 0x08; +  const static int pll_3 = 0x09; +  const static int pll_4 = 0x0A; +  const static int ref_counter_msb = 0x0B; +  const static int ref_counter_lsb = 0x0C; +  const static int pll_5 = 0x0D; +  const static int update = 0x5A; + +  int test; +  int fpga; +  int adc; +  int dac; +  int serdes; +  int exp; +  int tx_db; +  int rx_db; +}; + +#endif //INCLUDED_USRP2_CLK_REGS_HPP diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index a21157d76..17ba75d85 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -193,6 +193,19 @@ public:          throw std::runtime_error("usrp2 no control response");      } + /*********************************************************************** +  * Get/set hardware revision +  **********************************************************************/ +    void set_hw_rev(int rev) { +        hw_rev = rev; +        regs = usrp2_get_regs(rev); //might be a better place to do this +    } +  +    int get_hw_rev(void) { +        return hw_rev; +    } + +  private:      //this lovely lady makes it all possible      udp_simple::sptr _ctrl_transport; diff --git a/host/lib/usrp/usrp2/usrp2_iface.hpp b/host/lib/usrp/usrp2/usrp2_iface.hpp index 9cc32104e..b9f5f0fb8 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.hpp +++ b/host/lib/usrp/usrp2/usrp2_iface.hpp @@ -25,22 +25,7 @@  #include <boost/cstdint.hpp>  #include <utility>  #include "fw_common.h" - -//////////////////////////////////////////////////////////////////////// -// I2C addresses -//////////////////////////////////////////////////////////////////////// -#define I2C_DEV_EEPROM  0x50 // 24LC02[45]:  7-bits 1010xxx -#define	I2C_ADDR_MBOARD (I2C_DEV_EEPROM | 0x0) -#define	I2C_ADDR_TX_DB  (I2C_DEV_EEPROM | 0x4) -#define	I2C_ADDR_RX_DB  (I2C_DEV_EEPROM | 0x5) - -//////////////////////////////////////////////////////////////////////// -// EEPROM Layout -//////////////////////////////////////////////////////////////////////// -#define EE_MBOARD_REV_LSB  0x00 //1 byte -#define EE_MBOARD_REV_MSB  0x01 //1 byte -#define EE_MBOARD_MAC_ADDR 0x02 //6 bytes -#define EE_MBOARD_IP_ADDR  0x0C //uint32, big-endian +#include "usrp2_regs.hpp"  /*!   * The usrp2 interface class: @@ -118,6 +103,26 @@ public:          size_t num_bits,          bool readback      ) = 0; + +    /*! +     * Set the hardware revision number. Also selects the proper register set for the device. +     * \param rev the 16-bit revision +     */ +    virtual void set_hw_rev(int rev) = 0; + +    /*! Return the hardware revision number +     * \return hardware revision +     */ +    virtual int get_hw_rev(void) = 0; + +    /*! +     * Register map selected from USRP2/USRP2+. +     */ +    usrp2_regs_t regs; +    /*! +     * Hardware revision as returned by the device. +     */ +    int hw_rev;  };  #endif /* INCLUDED_USRP2_IFACE_HPP */ diff --git a/host/lib/usrp/usrp2/usrp2_regs.cpp b/host/lib/usrp/usrp2/usrp2_regs.cpp new file mode 100644 index 000000000..e40407f99 --- /dev/null +++ b/host/lib/usrp/usrp2/usrp2_regs.cpp @@ -0,0 +1,97 @@ +// +// 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/>. +// + +#include "usrp2_regs.hpp" + +int sr_addr(int misc_output_base, int sr) { +	return misc_output_base + 4 * sr; +} + +usrp2_regs_t usrp2_get_regs(int hw_rev) { + +  //how about you just make this dependent on hw_rev instead of doing the init before main, and give up the const globals, since the application won't ever need both. +  const int misc_output_base = (hw_rev>=USRP2P_FIRST_HW_REV) ? USRP2P_MISC_OUTPUT_BASE : USRP2_MISC_OUTPUT_BASE, +            gpio_base        = (hw_rev>=USRP2P_FIRST_HW_REV) ? USRP2P_GPIO_BASE        : USRP2_GPIO_BASE, +            atr_base         = (hw_rev>=USRP2P_FIRST_HW_REV) ? USRP2P_ATR_BASE         : USRP2_ATR_BASE, +            bp_base          = (hw_rev>=USRP2P_FIRST_HW_REV) ? USRP2P_BP_STATUS_BASE   : USRP2_BP_STATUS_BASE; + +  usrp2_regs_t x; +  x.sr_misc = 0; +  x.sr_tx_prot_eng = 32; +	x.sr_rx_prot_eng = 48; +  x.sr_buffer_pool_ctrl = 64; +  x.sr_udp_sm = 96; +  x.sr_tx_dsp = 208; +  x.sr_tx_ctrl = 224; +  x.sr_rx_dsp = 160; +  x.sr_rx_ctrl = 176; +  x.sr_time64 = 192; +  x.sr_simtimer = 198; +  x.sr_last = 255; +  x.misc_ctrl_clock = sr_addr(misc_output_base, 0); +  x.misc_ctrl_serdes = sr_addr(misc_output_base, 1); +  x.misc_ctrl_adc = sr_addr(misc_output_base, 2); +  x.misc_ctrl_leds = sr_addr(misc_output_base, 3); +  x.misc_ctrl_phy = sr_addr(misc_output_base, 4); +  x.misc_ctrl_dbg_mux = sr_addr(misc_output_base, 5); +  x.misc_ctrl_ram_page = sr_addr(misc_output_base, 6); +  x.misc_ctrl_flush_icache = sr_addr(misc_output_base, 7); +  x.misc_ctrl_led_src = sr_addr(misc_output_base, 8); +  x.time64_secs = sr_addr(misc_output_base, x.sr_time64 + 0); +  x.time64_ticks = sr_addr(misc_output_base, x.sr_time64 + 1); +  x.time64_flags = sr_addr(misc_output_base, x.sr_time64 + 2); +  x.time64_imm = sr_addr(misc_output_base, x.sr_time64 + 3); +  x.time64_tps = sr_addr(misc_output_base, x.sr_time64 + 4); +  x.time64_secs_rb = bp_base + 4*10; +  x.time64_ticks_rb = bp_base + 4*11; +  x.dsp_tx_freq = sr_addr(misc_output_base, x.sr_tx_dsp + 0); +  x.dsp_tx_scale_iq = sr_addr(misc_output_base, x.sr_tx_dsp + 1); +  x.dsp_tx_interp_rate = sr_addr(misc_output_base, x.sr_tx_dsp + 2); +  x.dsp_tx_mux = sr_addr(misc_output_base, x.sr_tx_dsp + 4); +  x.dsp_rx_freq = sr_addr(misc_output_base, x.sr_rx_dsp + 0); +  x.dsp_rx_scale_iq = sr_addr(misc_output_base, x.sr_rx_dsp + 1); +  x.dsp_rx_decim_rate = sr_addr(misc_output_base, x.sr_rx_dsp + 2); +  x.dsp_rx_dcoffset_i = sr_addr(misc_output_base, x.sr_rx_dsp + 3); +  x.dsp_rx_dcoffset_q = sr_addr(misc_output_base, x.sr_rx_dsp + 4); +  x.dsp_rx_mux = sr_addr(misc_output_base, x.sr_rx_dsp + 5); +  x.gpio_io = gpio_base + 0; +  x.gpio_ddr = gpio_base + 4; +  x.gpio_tx_sel = gpio_base + 8; +  x.gpio_rx_sel = gpio_base + 12; +  x.atr_idle_txside = atr_base + 0; +  x.atr_idle_rxside = atr_base + 2; +  x.atr_intx_txside = atr_base + 4; +  x.atr_intx_rxside = atr_base + 6; +  x.atr_inrx_txside = atr_base + 8; +  x.atr_inrx_rxside = atr_base + 10; +  x.atr_full_txside = atr_base + 12; +  x.atr_full_rxside = atr_base + 14; +  x.rx_ctrl_stream_cmd = sr_addr(misc_output_base, x.sr_rx_ctrl + 0); +  x.rx_ctrl_time_secs = sr_addr(misc_output_base, x.sr_rx_ctrl + 1); +  x.rx_ctrl_time_ticks = sr_addr(misc_output_base, x.sr_rx_ctrl + 2); +  x.rx_ctrl_clear_overrun = sr_addr(misc_output_base, x.sr_rx_ctrl + 3); +  x.rx_ctrl_vrt_header = sr_addr(misc_output_base, x.sr_rx_ctrl + 4); +  x.rx_ctrl_vrt_stream_id = sr_addr(misc_output_base, x.sr_rx_ctrl + 5); +  x.rx_ctrl_vrt_trailer = sr_addr(misc_output_base, x.sr_rx_ctrl + 6); +  x.rx_ctrl_nsamps_per_pkt = sr_addr(misc_output_base, x.sr_rx_ctrl + 7); +  x.rx_ctrl_nchannels = sr_addr(misc_output_base, x.sr_rx_ctrl + 8); +  x.tx_ctrl_num_chan = sr_addr(misc_output_base, x.sr_tx_ctrl + 0); +  x.tx_ctrl_clear_state = sr_addr(misc_output_base, x.sr_tx_ctrl + 1); +  x.tx_ctrl_report_sid = sr_addr(misc_output_base, x.sr_tx_ctrl + 2); + +  return x; +} diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index aa8bd860f..8dbd6c4b4 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.hpp @@ -18,6 +18,91 @@  #ifndef INCLUDED_USRP2_REGS_HPP  #define INCLUDED_USRP2_REGS_HPP +//these are used to set the  + +#define USRP2_MISC_OUTPUT_BASE  0xD400 +#define USRP2_GPIO_BASE         0xC800 +#define USRP2_ATR_BASE          0xE400 +#define USRP2_BP_STATUS_BASE    0xCC00 + +#define USRP2P_MISC_OUTPUT_BASE 0x2000 +#define USRP2P_GPIO_BASE        0x3200 +#define USRP2P_ATR_BASE         0x3800 +#define USRP2P_BP_STATUS_BASE   0x3300 + +#define USRP2P_FIRST_HW_REV     0x0A00 + +typedef struct { +	int sr_misc; +	int sr_tx_prot_eng; +	int sr_rx_prot_eng; +	int sr_buffer_pool_ctrl; +	int sr_udp_sm; +	int sr_tx_dsp; +	int sr_tx_ctrl; +	int sr_rx_dsp; +	int sr_rx_ctrl; +	int sr_time64; +	int sr_simtimer; +	int sr_last; +	int misc_ctrl_clock; +	int misc_ctrl_serdes; +	int misc_ctrl_adc; +	int misc_ctrl_leds; +	int misc_ctrl_phy; +	int misc_ctrl_dbg_mux; +	int misc_ctrl_ram_page; +	int misc_ctrl_flush_icache; +	int misc_ctrl_led_src; +	int time64_secs; // value to set absolute secs to on next PPS +	int time64_ticks; // value to set absolute ticks to on next PPS +	int time64_flags; // flags -- see chart below +	int time64_imm; // set immediate (0=latch on next pps, 1=latch immediate, default=0) +	int time64_tps; // ticks per second rollover count +	int time64_secs_rb; +	int time64_ticks_rb; +	int dsp_tx_freq; +	int dsp_tx_scale_iq; +	int dsp_tx_interp_rate; +  int dsp_tx_mux; +	int dsp_rx_freq; +	int dsp_rx_scale_iq; +	int dsp_rx_decim_rate; +	int dsp_rx_dcoffset_i; +	int dsp_rx_dcoffset_q; +	int dsp_rx_mux; +	int gpio_base; +	int gpio_io; +	int gpio_ddr; +	int gpio_tx_sel; +	int gpio_rx_sel; +	int atr_base; +	int atr_idle_txside; +	int atr_idle_rxside; +	int atr_intx_txside; +	int atr_intx_rxside; +	int atr_inrx_txside; +	int atr_inrx_rxside; +	int atr_full_txside; +	int atr_full_rxside; +	int rx_ctrl_stream_cmd; +	int rx_ctrl_time_secs; +	int rx_ctrl_time_ticks; +	int rx_ctrl_clear_overrun; +	int rx_ctrl_vrt_header; +	int rx_ctrl_vrt_stream_id; +  int rx_ctrl_vrt_trailer; +	int rx_ctrl_nsamps_per_pkt; +	int rx_ctrl_nchannels; +  int tx_ctrl_num_chan; +  int tx_ctrl_clear_state; +  int tx_ctrl_report_sid; +} usrp2_regs_t; + +extern const usrp2_regs_t usrp2_regs; //the register definitions, set in usrp2_regs.cpp and usrp2p_regs.cpp + +usrp2_regs_t usrp2_get_regs(int hw_rev); +  ////////////////////////////////////////////////////  // Settings Bus, Slave #7, Not Byte Addressable!  // @@ -25,27 +110,12 @@  // 1KB of address space (== 256 32-bit write-only regs) -#define MISC_OUTPUT_BASE        0xD400 +//#define MISC_OUTPUT_BASE        0xD400  //#define TX_PROTOCOL_ENGINE_BASE 0xD480  //#define RX_PROTOCOL_ENGINE_BASE 0xD4C0  //#define BUFFER_POOL_CTRL_BASE   0xD500  //#define LAST_SETTING_REG        0xD7FC  // last valid setting register -#define SR_MISC 0 -#define SR_TX_PROT_ENG 32 -#define SR_RX_PROT_ENG 48 -#define SR_BUFFER_POOL_CTRL 64 -#define SR_UDP_SM 96 -#define SR_TX_DSP 208 -#define SR_TX_CTRL 224 -#define SR_RX_DSP 160 -#define SR_RX_CTRL 176 -#define SR_TIME64 192 -#define SR_SIMTIMER 198 -#define SR_LAST 255 - -#define _SR_ADDR(sr)    ((MISC_OUTPUT_BASE) + (4*(sr))) -  /////////////////////////////////////////////////  // SPI Slave Constants  //////////////////////////////////////////////// @@ -58,20 +128,11 @@  #define SPI_SS_TX_DAC   32  #define SPI_SS_TX_ADC   64  #define SPI_SS_TX_DB   128 +#define SPI_SS_ADS62P44 256 //for usrp2p  /////////////////////////////////////////////////  // Misc Control  //////////////////////////////////////////////// -#define U2_REG_MISC_CTRL_CLOCK           _SR_ADDR(0) -#define U2_REG_MISC_CTRL_SERDES          _SR_ADDR(1) -#define U2_REG_MISC_CTRL_ADC             _SR_ADDR(2) -#define U2_REG_MISC_CTRL_LEDS            _SR_ADDR(3) -#define U2_REG_MISC_CTRL_PHY             _SR_ADDR(4) // LSB is reset line to eth phy -#define U2_REG_MISC_CTRL_DBG_MUX         _SR_ADDR(5) -#define U2_REG_MISC_CTRL_RAM_PAGE        _SR_ADDR(6) // FIXME should go somewhere else... -#define U2_REG_MISC_CTRL_FLUSH_ICACHE    _SR_ADDR(7) // Flush the icache -#define U2_REG_MISC_CTRL_LED_SRC         _SR_ADDR(8) // HW or SW control for LEDs -  #define U2_FLAG_MISC_CTRL_SERDES_ENABLE 8  #define U2_FLAG_MISC_CTRL_SERDES_PRBSEN 4  #define U2_FLAG_MISC_CTRL_SERDES_LOOPEN 2 @@ -99,14 +160,6 @@     *     * </pre>     */ -#define U2_REG_TIME64_SECS  _SR_ADDR(SR_TIME64 + 0)  // value to set absolute secs to on next PPS -#define U2_REG_TIME64_TICKS _SR_ADDR(SR_TIME64 + 1)  // value to set absolute ticks to on next PPS -#define U2_REG_TIME64_FLAGS _SR_ADDR(SR_TIME64 + 2)  // flags - see chart above -#define U2_REG_TIME64_IMM   _SR_ADDR(SR_TIME64 + 3)  // set immediate (0=latch on next pps, 1=latch immediate, default=0) -#define U2_REG_TIME64_TPS   _SR_ADDR(SR_TIME64 + 4)  // the ticks per second rollover count - -#define U2_REG_TIME64_SECS_RB  (0xCC00 + 4*10) -#define U2_REG_TIME64_TICKS_RB (0xCC00 + 4*11)  //pps flags (see above)  #define U2_FLAG_TIME64_PPS_NEGEDGE (0 << 0) @@ -120,9 +173,6 @@  /////////////////////////////////////////////////  // DSP TX Regs  //////////////////////////////////////////////// -#define U2_REG_DSP_TX_FREQ         _SR_ADDR(SR_TX_DSP + 0) -#define U2_REG_DSP_TX_SCALE_IQ     _SR_ADDR(SR_TX_DSP + 1) // {scale_i,scale_q} -#define U2_REG_DSP_TX_INTERP_RATE  _SR_ADDR(SR_TX_DSP + 2)    /*!     * \brief output mux configuration. @@ -158,17 +208,11 @@     * The default value is 0x10     * </pre>     */ -#define U2_REG_DSP_TX_MUX  _SR_ADDR(SR_TX_DSP + 4)  /////////////////////////////////////////////////  // DSP RX Regs  //////////////////////////////////////////////// -#define U2_REG_DSP_RX_FREQ         _SR_ADDR(SR_RX_DSP + 0) -#define U2_REG_DSP_RX_SCALE_IQ     _SR_ADDR(SR_RX_DSP + 1) // {scale_i,scale_q} -#define U2_REG_DSP_RX_DECIM_RATE   _SR_ADDR(SR_RX_DSP + 2) -#define U2_REG_DSP_RX_DCOFFSET_I   _SR_ADDR(SR_RX_DSP + 3) // Bit 31 high sets fixed offset mode, using lower 14 bits, -                                                       // otherwise it is automatic  -#define U2_REG_DSP_RX_DCOFFSET_Q   _SR_ADDR(SR_RX_DSP + 4) // Bit 31 high sets fixed offset mode, using lower 14 bits +    /*!     * \brief input mux configuration.     * @@ -190,20 +234,10 @@     * The default value is 0x4     * </pre>     */ -#define U2_REG_DSP_RX_MUX  _SR_ADDR(SR_RX_DSP + 5)         // called adc_mux in dsp_core_rx.v  ////////////////////////////////////////////////  // GPIO, Slave 4  //////////////////////////////////////////////// -// -// These go to the daughterboard i/o pins -// -#define U2_REG_GPIO_BASE 0xC800 - -#define U2_REG_GPIO_IO         U2_REG_GPIO_BASE + 0  // 32 bits, gpio io pins (tx high 16 bits, rx low 16 bits) -#define U2_REG_GPIO_DDR        U2_REG_GPIO_BASE + 4  // 32 bits, gpio ddr, 1 means output (tx high 16 bits, rx low 16 bits) -#define U2_REG_GPIO_TX_SEL     U2_REG_GPIO_BASE + 8  // 16 2-bit fields select which source goes to TX DB -#define U2_REG_GPIO_RX_SEL     U2_REG_GPIO_BASE + 12 // 16 2-bit fields select which source goes to RX DB  // each 2-bit sel field is layed out this way  #define U2_FLAG_GPIO_SEL_GPIO      0 // if pin is an output, set by GPIO register @@ -214,38 +248,18 @@  ///////////////////////////////////////////////////  // ATR Controller, Slave 11  //////////////////////////////////////////////// -#define U2_REG_ATR_BASE  0xE400 -#define U2_REG_ATR_IDLE_TXSIDE  U2_REG_ATR_BASE + 0 -#define U2_REG_ATR_IDLE_RXSIDE  U2_REG_ATR_BASE + 2 -#define U2_REG_ATR_INTX_TXSIDE  U2_REG_ATR_BASE + 4 -#define U2_REG_ATR_INTX_RXSIDE  U2_REG_ATR_BASE + 6 -#define U2_REG_ATR_INRX_TXSIDE  U2_REG_ATR_BASE + 8 -#define U2_REG_ATR_INRX_RXSIDE  U2_REG_ATR_BASE + 10 -#define U2_REG_ATR_FULL_TXSIDE  U2_REG_ATR_BASE + 12 -#define U2_REG_ATR_FULL_RXSIDE  U2_REG_ATR_BASE + 14  ///////////////////////////////////////////////////  // RX CTRL regs  /////////////////////////////////////////////////// -// The following 3 are logically a single command register. -// They are clocked into the underlying fifo when time_ticks is written. -#define U2_REG_RX_CTRL_STREAM_CMD        _SR_ADDR(SR_RX_CTRL + 0) // {now, chain, num_samples(30) -#define U2_REG_RX_CTRL_TIME_SECS         _SR_ADDR(SR_RX_CTRL + 1) -#define U2_REG_RX_CTRL_TIME_TICKS        _SR_ADDR(SR_RX_CTRL + 2) - -#define U2_REG_RX_CTRL_CLEAR_OVERRUN     _SR_ADDR(SR_RX_CTRL + 3) // write anything to clear overrun -#define U2_REG_RX_CTRL_VRT_HEADER        _SR_ADDR(SR_RX_CTRL + 4) // word 0 of packet.  FPGA fills in packet counter -#define U2_REG_RX_CTRL_VRT_STREAM_ID     _SR_ADDR(SR_RX_CTRL + 5) // word 1 of packet. -#define U2_REG_RX_CTRL_VRT_TRAILER       _SR_ADDR(SR_RX_CTRL + 6) -#define U2_REG_RX_CTRL_NSAMPS_PER_PKT    _SR_ADDR(SR_RX_CTRL + 7) -#define U2_REG_RX_CTRL_NCHANNELS         _SR_ADDR(SR_RX_CTRL + 8) // 1 in basic case, up to 4 for vector sources +  ///////////////////////////////////////////////////  // TX CTRL regs  /////////////////////////////////////////////////// -#define U2_REG_TX_CTRL_NUM_CHAN          _SR_ADDR(SR_TX_CTRL + 0) -#define U2_REG_TX_CTRL_CLEAR_STATE       _SR_ADDR(SR_TX_CTRL + 1) -#define U2_REG_TX_CTRL_REPORT_SID        _SR_ADDR(SR_TX_CTRL + 2) +//#define U2_REG_TX_CTRL_NUM_CHAN          _SR_ADDR(SR_TX_CTRL + 0) +//#define U2_REG_TX_CTRL_CLEAR_STATE       _SR_ADDR(SR_TX_CTRL + 1) +//#define U2_REG_TX_CTRL_REPORT_SID        _SR_ADDR(SR_TX_CTRL + 2)  #endif /* INCLUDED_USRP2_REGS_HPP */  | 
