diff options
Diffstat (limited to 'host/lib/usrp/x300/x300_impl.cpp')
-rw-r--r-- | host/lib/usrp/x300/x300_impl.cpp | 116 |
1 files changed, 70 insertions, 46 deletions
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index 1e424414e..0483ecf11 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -47,23 +47,38 @@ using namespace uhd; using namespace uhd::usrp; using namespace uhd::transport; using namespace uhd::niusrprio; +using namespace uhd::usrp::gpio_atr; using namespace uhd::usrp::x300; namespace asio = boost::asio; -/*********************************************************************** - * Discovery over the udp and pcie transport - **********************************************************************/ +static bool has_dram_buff(wb_iface::sptr zpu_ctrl) { + bool dramR0 = dma_fifo_core_3000::check( + zpu_ctrl, SR_ADDR(SET0_BASE, ZPU_SR_DRAM_FIFO0), SR_ADDR(SET0_BASE, ZPU_RB_DRAM_FIFO0)); + bool dramR1 = dma_fifo_core_3000::check( + zpu_ctrl, SR_ADDR(SET0_BASE, ZPU_SR_DRAM_FIFO1), SR_ADDR(SET0_BASE, ZPU_RB_DRAM_FIFO1)); + return (dramR0 and dramR1); +} + static std::string get_fpga_option(wb_iface::sptr zpu_ctrl) { - //1G = {0:1G, 1:1G} w/ DRAM, HG = {0:1G, 1:10G} w/ DRAM, XG = {0:10G, 1:10G} w/ DRAM - //HGS = {0:1G, 1:10G} w/ SRAM, XGS = {0:10G, 1:10G} w/ SRAM + //Possible options: + //1G = {0:1G, 1:1G} w/ DRAM, HG = {0:1G, 1:10G} w/ DRAM, XG = {0:10G, 1:10G} w/ DRAM + //1GS = {0:1G, 1:1G} w/ SRAM, HGS = {0:1G, 1:10G} w/ SRAM, XGS = {0:10G, 1:10G} w/ SRAM - //In the default configuration, UHD does not support the HG and XG images so - //they are never autodetected. + std::string option; bool eth0XG = (zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_ETH_TYPE0)) == 0x1); bool eth1XG = (zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_ETH_TYPE1)) == 0x1); - return (eth0XG && eth1XG) ? "XGS" : (eth1XG ? "HGS" : "1G"); + option = (eth0XG && eth1XG) ? "XG" : (eth1XG ? "HG" : "1G"); + + if (not has_dram_buff(zpu_ctrl)) { + option += "S"; + } + return option; } +/*********************************************************************** + * Discovery over the udp and pcie transport + **********************************************************************/ + //@TODO: Refactor the find functions to collapse common code for ethernet and PCIe static device_addrs_t x300_find_with_addr(const device_addr_t &hint) { @@ -729,6 +744,36 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) } //////////////////////////////////////////////////////////////////// + // DRAM FIFO initialization + //////////////////////////////////////////////////////////////////// + mb.has_dram_buff = has_dram_buff(mb.zpu_ctrl); + if (mb.has_dram_buff) { + for (size_t i = 0; i < mboard_members_t::NUM_RADIOS; i++) { + static const size_t NUM_REGS = 8; + mb.dram_buff_ctrl[i] = dma_fifo_core_3000::make( + mb.zpu_ctrl, + SR_ADDR(SET0_BASE, ZPU_SR_DRAM_FIFO0+(i*NUM_REGS)), + SR_ADDR(SET0_BASE, ZPU_RB_DRAM_FIFO0+i)); + mb.dram_buff_ctrl[i]->resize(X300_DRAM_FIFO_SIZE * i, X300_DRAM_FIFO_SIZE); + + if (mb.dram_buff_ctrl[i]->ext_bist_supported()) { + UHD_MSG(status) << boost::format("Running BIST for DRAM FIFO %d... ") % i; + boost::uint32_t bisterr = mb.dram_buff_ctrl[i]->run_bist(); + if (bisterr != 0) { + throw uhd::runtime_error(str(boost::format("DRAM FIFO BIST failed! (code: %d)\n") % bisterr)); + } else { + double throughput = mb.dram_buff_ctrl[i]->get_bist_throughput(X300_BUS_CLOCK_RATE); + UHD_MSG(status) << (boost::format("pass (Throughput: %.1fMB/s)") % (throughput/1e6)) << std::endl; + } + } else { + if (mb.dram_buff_ctrl[i]->run_bist() != 0) { + throw uhd::runtime_error(str(boost::format("DRAM FIFO %d BIST failed!\n") % i)); + } + } + } + } + + //////////////////////////////////////////////////////////////////// // setup radios //////////////////////////////////////////////////////////////////// this->setup_radio(mb_i, "A", dev_addr); @@ -749,15 +794,15 @@ 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, radio::sr_addr(radio::FP_GPIO), radio::RB32_FP_GPIO); + mb.fp_gpio = gpio_atr_3000::make(mb.radio_perifs[0].ctrl, radio::sr_addr(radio::FP_GPIO), radio::RB32_FP_GPIO); BOOST_FOREACH(const gpio_attr_map_t::value_type attr, gpio_attr_map) { _tree->create<boost::uint32_t>(mb_path / "gpio" / "FP0" / attr.second) .set(0) - .subscribe(boost::bind(&x300_impl::set_fp_gpio, this, mb.fp_gpio, attr.first, _1)); + .subscribe(boost::bind(&gpio_atr_3000::set_gpio_attr, mb.fp_gpio, attr.first, _1)); } _tree->create<boost::uint32_t>(mb_path / "gpio" / "FP0" / "READBACK") - .publish(boost::bind(&x300_impl::get_fp_gpio, this, mb.fp_gpio)); + .publish(boost::bind(&gpio_atr_3000::read_gpio, mb.fp_gpio)); //////////////////////////////////////////////////////////////////// // register the time keepers - only one can be the highlander @@ -930,7 +975,8 @@ void x300_impl::setup_radio(const size_t mb_i, const std::string &slot_name, con perif.spi = spi_core_3000::make(perif.ctrl, radio::sr_addr(radio::SPI), radio::RB32_SPI); perif.adc = x300_adc_ctrl::make(perif.spi, DB_ADC_SEN); perif.dac = x300_dac_ctrl::make(perif.spi, DB_DAC_SEN, mb.clock->get_master_clock_rate()); - perif.leds = gpio_core_200_32wo::make(perif.ctrl, radio::sr_addr(radio::LEDS)); + perif.leds = gpio_atr_3000::make_write_only(perif.ctrl, radio::sr_addr(radio::LEDS)); + perif.leds->set_atr_mode(MODE_ATR, 0xFFFFFFFF); perif.rx_fe = rx_frontend_core_200::make(perif.ctrl, radio::sr_addr(radio::RX_FRONT)); perif.rx_fe->set_dc_offset(rx_frontend_core_200::DEFAULT_DC_OFFSET_VALUE); perif.rx_fe->set_dc_offset_auto(rx_frontend_core_200::DEFAULT_DC_OFFSET_ENABLE); @@ -940,7 +986,10 @@ void x300_impl::setup_radio(const size_t mb_i, const std::string &slot_name, con perif.framer = rx_vita_core_3000::make(perif.ctrl, radio::sr_addr(radio::RX_CTRL)); perif.ddc = rx_dsp_core_3000::make(perif.ctrl, radio::sr_addr(radio::RX_DSP)); perif.ddc->set_link_rate(10e9/8); //whatever - perif.deframer = tx_vita_core_3000::make(perif.ctrl, radio::sr_addr(radio::TX_CTRL)); + //The DRAM FIFO is treated as in internal radio FIFO for flow control purposes + tx_vita_core_3000::fc_monitor_loc fc_loc = + mb.has_dram_buff ? tx_vita_core_3000::FC_PRE_FIFO : tx_vita_core_3000::FC_PRE_RADIO; + perif.deframer = tx_vita_core_3000::make(perif.ctrl, radio::sr_addr(radio::TX_CTRL), fc_loc); perif.duc = tx_dsp_core_3000::make(perif.ctrl, radio::sr_addr(radio::TX_DSP)); perif.duc->set_link_rate(10e9/8); //whatever @@ -1014,7 +1063,7 @@ void x300_impl::setup_radio(const size_t mb_i, const std::string &slot_name, con //create a new dboard interface x300_dboard_iface_config_t db_config; - db_config.gpio = gpio_core_200::make(perif.ctrl, radio::sr_addr(radio::GPIO), radio::RB32_GPIO); + db_config.gpio = db_gpio_atr_3000::make(perif.ctrl, radio::sr_addr(radio::GPIO), radio::RB32_GPIO); db_config.spi = perif.spi; db_config.rx_spi_slaveno = DB_RX_SEN; db_config.tx_spi_slaveno = DB_TX_SEN; @@ -1143,7 +1192,7 @@ x300_impl::both_xports_t x300_impl::make_transport( * connection type.*/ size_t eth_data_rec_frame_size = 0; - if (mb.loaded_fpga_image == "HGS") { + if (mb.loaded_fpga_image.substr(0,2) == "HG") { if (mb.router_dst_here == X300_XB_DST_E0) { eth_data_rec_frame_size = X300_1GE_DATA_FRAME_MAX_SIZE; _tree->access<double>("/mboards/"+boost::lexical_cast<std::string>(mb_index) / "link_max_rate").set(X300_MAX_RATE_1GIGE); @@ -1151,7 +1200,7 @@ x300_impl::both_xports_t x300_impl::make_transport( eth_data_rec_frame_size = X300_10GE_DATA_FRAME_MAX_SIZE; _tree->access<double>("/mboards/"+boost::lexical_cast<std::string>(mb_index) / "link_max_rate").set(X300_MAX_RATE_10GIGE); } - } else if (mb.loaded_fpga_image == "XGS") { + } else if (mb.loaded_fpga_image.substr(0,2) == "XG") { eth_data_rec_frame_size = X300_10GE_DATA_FRAME_MAX_SIZE; _tree->access<double>("/mboards/"+boost::lexical_cast<std::string>(mb_index) / "link_max_rate").set(X300_MAX_RATE_10GIGE); } @@ -1295,16 +1344,16 @@ boost::uint32_t x300_impl::allocate_sid(mboard_members_t &mb, const sid_config_t return sid; } -void x300_impl::update_atr_leds(gpio_core_200_32wo::sptr leds, const std::string &rx_ant) +void x300_impl::update_atr_leds(gpio_atr_3000::sptr leds, const std::string &rx_ant) { const bool is_txrx = (rx_ant == "TX/RX"); const int rx_led = (1 << 2); const int tx_led = (1 << 1); const int txrx_led = (1 << 0); - leds->set_atr_reg(dboard_iface::ATR_REG_IDLE, 0); - leds->set_atr_reg(dboard_iface::ATR_REG_RX_ONLY, is_txrx? txrx_led : rx_led); - leds->set_atr_reg(dboard_iface::ATR_REG_TX_ONLY, tx_led); - leds->set_atr_reg(dboard_iface::ATR_REG_FULL_DUPLEX, rx_led | tx_led); + leds->set_atr_reg(ATR_REG_IDLE, 0); + leds->set_atr_reg(ATR_REG_RX_ONLY, is_txrx? txrx_led : rx_led); + leds->set_atr_reg(ATR_REG_TX_ONLY, tx_led); + leds->set_atr_reg(ATR_REG_FULL_DUPLEX, rx_led | tx_led); } void x300_impl::set_tick_rate(mboard_members_t &mb, const double rate) @@ -1314,7 +1363,6 @@ void x300_impl::set_tick_rate(mboard_members_t &mb, const double rate) perif.time64->set_tick_rate(rate); perif.framer->set_tick_rate(rate); perif.ddc->set_tick_rate(rate); - perif.deframer->set_tick_rate(rate); perif.duc->set_tick_rate(rate); } } @@ -1509,30 +1557,6 @@ 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) -{ - return boost::uint32_t(gpio->read_gpio(dboard_iface::UNIT_RX)); -} - -void x300_impl::set_fp_gpio(gpio_core_200::sptr gpio, const gpio_attr_t attr, const boost::uint32_t value) -{ - switch (attr) - { - 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(); - } -} - -/*********************************************************************** * claimer logic **********************************************************************/ |