diff options
Diffstat (limited to 'host/lib/usrp/x300')
-rw-r--r-- | host/lib/usrp/x300/CMakeLists.txt | 2 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_fw_common.h | 2 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_impl.cpp | 116 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_impl.hpp | 24 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_io_impl.cpp | 10 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_regs.hpp | 6 |
6 files changed, 97 insertions, 63 deletions
diff --git a/host/lib/usrp/x300/CMakeLists.txt b/host/lib/usrp/x300/CMakeLists.txt index 3d6348eec..f8b129f89 100644 --- a/host/lib/usrp/x300/CMakeLists.txt +++ b/host/lib/usrp/x300/CMakeLists.txt @@ -22,8 +22,6 @@ ######################################################################## # Conditionally configure the X300 support ######################################################################## -LIBUHD_REGISTER_COMPONENT("X300" ENABLE_X300 ON "ENABLE_LIBUHD" OFF OFF) - IF(ENABLE_X300) LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/x300_impl.cpp diff --git a/host/lib/usrp/x300/x300_fw_common.h b/host/lib/usrp/x300/x300_fw_common.h index 549fc9dfa..6039ee376 100644 --- a/host/lib/usrp/x300/x300_fw_common.h +++ b/host/lib/usrp/x300/x300_fw_common.h @@ -33,7 +33,7 @@ extern "C" { #define X300_REVISION_MIN 2 #define X300_FW_COMPAT_MAJOR 4 #define X300_FW_COMPAT_MINOR 0 -#define X300_FPGA_COMPAT_MAJOR 19 +#define X300_FPGA_COMPAT_MAJOR 20 //shared memory sections - in between the stack and the program space #define X300_FW_SHMEM_BASE 0x6000 diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index ebb9bf3a6..37461e2e5 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); } } @@ -1517,30 +1565,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 **********************************************************************/ diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp index 67afa77ee..4de0344bf 100644 --- a/host/lib/usrp/x300/x300_impl.hpp +++ b/host/lib/usrp/x300/x300_impl.hpp @@ -41,7 +41,8 @@ #include "radio_ctrl_core_3000.hpp" #include "rx_frontend_core_200.hpp" #include "tx_frontend_core_200.hpp" -#include "gpio_core_200.hpp" +#include "gpio_atr_3000.hpp" +#include "dma_fifo_core_3000.hpp" #include <boost/weak_ptr.hpp> #include <uhd/usrp/gps_ctrl.hpp> #include <uhd/usrp/mboard_eeprom.hpp> @@ -56,8 +57,11 @@ static const std::string X300_FW_FILE_NAME = "usrp_x300_fw.bin"; static const double X300_DEFAULT_TICK_RATE = 200e6; //Hz static const double X300_BUS_CLOCK_RATE = 166.666667e6; //Hz -static const size_t X300_TX_HW_BUFF_SIZE = 520*1024; //512K SRAM buffer + 8K 2Clk FIFO -static const size_t X300_TX_FC_RESPONSE_FREQ = 8; //per flow-control window +static const size_t X300_TX_HW_BUFF_SIZE_SRAM = 520*1024; //512K SRAM buffer + 8K 2Clk FIFO +static const size_t X300_TX_FC_RESPONSE_FREQ_SRAM = 8; //per flow-control window +static const size_t X300_TX_HW_BUFF_SIZE_DRAM = 128*1024; +static const size_t X300_TX_FC_RESPONSE_FREQ_DRAM = 32; +static const boost::uint32_t X300_DRAM_FIFO_SIZE = 32*1024*1024; static const size_t X300_RX_SW_BUFF_SIZE_ETH = 0x2000000;//32MiB For an ~8k frame size any size >32MiB is just wasted buffer space static const size_t X300_RX_SW_BUFF_SIZE_ETH_MACOS = 0x100000; //1Mib @@ -123,7 +127,7 @@ enum struct x300_dboard_iface_config_t { - gpio_core_200::sptr gpio; + uhd::usrp::gpio_atr::db_gpio_atr_3000::sptr gpio; spi_core_3000::sptr spi; size_t rx_spi_slaveno; size_t tx_spi_slaveno; @@ -185,7 +189,7 @@ private: rx_dsp_core_3000::sptr ddc; tx_vita_core_3000::sptr deframer; tx_dsp_core_3000::sptr duc; - gpio_core_200_32wo::sptr leds; + uhd::usrp::gpio_atr::gpio_atr_3000::sptr leds; rx_frontend_core_200::sptr rx_fe; tx_frontend_core_200::sptr tx_fe; //Registers @@ -226,10 +230,14 @@ private: return slot_name == "A" ? 0 : 1; } + bool has_dram_buff; + dma_fifo_core_3000::sptr dram_buff_ctrl[NUM_RADIOS]; + + //other perifs on mboard x300_clock_ctrl::sptr clock; uhd::gps_ctrl::sptr gps; - gpio_core_200::sptr fp_gpio; + uhd::usrp::gpio_atr::gpio_atr_3000::sptr fp_gpio; uhd::usrp::x300::fw_regmap_t::sptr fw_regmap; @@ -366,9 +374,7 @@ private: void check_fw_compat(const uhd::fs_path &mb_path, uhd::wb_iface::sptr iface); void check_fpga_compat(const uhd::fs_path &mb_path, const mboard_members_t &members); - void update_atr_leds(gpio_core_200_32wo::sptr, const std::string &ant); - boost::uint32_t get_fp_gpio(gpio_core_200::sptr); - void set_fp_gpio(gpio_core_200::sptr, const gpio_attr_t, const boost::uint32_t); + void update_atr_leds(uhd::usrp::gpio_atr::gpio_atr_3000::sptr, const std::string &ant); void self_cal_adc_capture_delay(mboard_members_t& mb, const size_t radio_i, bool print_status = false); double self_cal_adc_xfer_delay(mboard_members_t& mb, bool apply_delay = false); diff --git a/host/lib/usrp/x300/x300_io_impl.cpp b/host/lib/usrp/x300/x300_io_impl.cpp index e3515af0c..1356daec5 100644 --- a/host/lib/usrp/x300/x300_io_impl.cpp +++ b/host/lib/usrp/x300/x300_io_impl.cpp @@ -216,9 +216,10 @@ struct x300_tx_fc_guts_t * FC credit we have is C = F + M - N (i.e. we can send C more packets * before getting another ack). */ -static size_t get_tx_flow_control_window(size_t frame_size, const device_addr_t& tx_args) +static size_t get_tx_flow_control_window(size_t frame_size, const bool dram_buff, const device_addr_t& tx_args) { - double hw_buff_size = tx_args.cast<double>("send_buff_size", X300_TX_HW_BUFF_SIZE); + double default_buff_size = dram_buff ? X300_TX_HW_BUFF_SIZE_DRAM : X300_TX_HW_BUFF_SIZE_SRAM; + double hw_buff_size = tx_args.cast<double>("send_buff_size", default_buff_size); size_t window_in_pkts = (static_cast<size_t>(hw_buff_size) / frame_size); if (window_in_pkts == 0) { throw uhd::value_error("send_buff_size must be larger than the send_frame_size."); @@ -580,8 +581,9 @@ tx_streamer::sptr x300_impl::get_tx_stream(const uhd::stream_args_t &args_) perif.duc->setup(args); //flow control setup - size_t fc_window = get_tx_flow_control_window(xport.send->get_send_frame_size(), device_addr); //In packets - const size_t fc_handle_window = std::max<size_t>(1, fc_window/X300_TX_FC_RESPONSE_FREQ); + size_t fc_window = get_tx_flow_control_window(xport.send->get_send_frame_size(), mb.has_dram_buff, device_addr); //In packets + const size_t fc_handle_window = std::max<size_t>(1, + fc_window/ (mb.has_dram_buff ? X300_TX_FC_RESPONSE_FREQ_DRAM : X300_TX_FC_RESPONSE_FREQ_SRAM)); UHD_LOG << "TX Flow Control Window = " << fc_window << ", TX Flow Control Handler Window = " << fc_handle_window << std::endl; diff --git a/host/lib/usrp/x300/x300_regs.hpp b/host/lib/usrp/x300/x300_regs.hpp index 3e0966c83..de3a3161a 100644 --- a/host/lib/usrp/x300/x300_regs.hpp +++ b/host/lib/usrp/x300/x300_regs.hpp @@ -42,7 +42,7 @@ static const uint32_t TIME = 128; static const uint32_t RX_DSP = 144; static const uint32_t TX_DSP = 184; static const uint32_t LEDS = 195; -static const uint32_t FP_GPIO = 200; +static const uint32_t FP_GPIO = 201; static const uint32_t RX_FRONT = 208; static const uint32_t TX_FRONT = 216; @@ -77,6 +77,8 @@ localparam ZPU_SR_XB_LOCAL = 03; localparam ZPU_SR_SPI = 32; localparam ZPU_SR_ETHINT0 = 40; localparam ZPU_SR_ETHINT1 = 56; +localparam ZPU_SR_DRAM_FIFO0 = 72; +localparam ZPU_SR_DRAM_FIFO1 = 80; //reset bits #define ZPU_SR_SW_RST_ETH_PHY (1<<0) @@ -89,6 +91,8 @@ localparam ZPU_RB_CLK_STATUS = 3; localparam ZPU_RB_COMPAT_NUM = 6; localparam ZPU_RB_ETH_TYPE0 = 4; localparam ZPU_RB_ETH_TYPE1 = 5; +localparam ZPU_RB_DRAM_FIFO0 = 10; +localparam ZPU_RB_DRAM_FIFO1 = 11; //spi slaves on radio #define DB_DAC_SEN (1 << 7) |