diff options
| -rw-r--r-- | CHANGELOG | 15 | ||||
| -rwxr-xr-x | firmware/usrp3/x300/x300_aurora_bist.py | 108 | ||||
| -rw-r--r-- | firmware/usrp3/x300/x300_defs.h | 2 | ||||
| -rw-r--r-- | host/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | host/cmake/debian/changelog | 18 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_ubx.cpp | 45 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_fw_common.h | 4 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_impl.cpp | 2 | 
8 files changed, 175 insertions, 23 deletions
| @@ -22,6 +22,21 @@ Change Log for Releases  - Added more aggressive optimization strategies for FPGA builds  - Xilinx IP tool upgrade scripts cleaned up +## 003.009.005 +- B200: Update DSPs after changing tick rate +- X300: Added option to disable ADC self test, prevent DAC from +  underrunning +- UBX: Fixed noise issues, reduced power consumption/heat, added codes for +  upcoming board revisions, force RX LNAs on (reduces rx settling time) +- WBX: Fixed rev2 and rev3 boards on X300 +- Utils/Examples: Cleaned up query_gpsdo_sensors, test_dboard_coercion, +- Manual: Minor fixes and updates +- CMake: Fix lib64 detection, better platform detection, Doxygen may use shorter +  filenames +- Octoclock: GPSDO-related fixes, sequence number consistency fixes, UART +  fixes (off-by-one errors). uhd_usrp_probe will pick up an OC now, +  added Wireshark dissector for OC packets +  ## 003.009.004  - GPIO control: Fix address mismatch for RX and full duplex.    This fixes full-duplex mode for most devices. diff --git a/firmware/usrp3/x300/x300_aurora_bist.py b/firmware/usrp3/x300/x300_aurora_bist.py index 225cd030b..f5e119b66 100755 --- a/firmware/usrp3/x300/x300_aurora_bist.py +++ b/firmware/usrp3/x300/x300_aurora_bist.py @@ -1,6 +1,3 @@ -from __future__ import print_function -from builtins import str -from builtins import range  #!/usr/bin/env python  #  # Copyright 2016 Ettus Research LLC @@ -19,12 +16,17 @@ from builtins import range  # along with this program.  If not, see <http://www.gnu.org/licenses/>.  # +from __future__ import print_function +from builtins import str +from builtins import range +  import x300_debug  import argparse  import time  import datetime  import math  import tqdm +import numpy  ########################################################################  # constants @@ -86,9 +88,9 @@ def get_rate_setting(rate):              return (div-1, 8e-6 * BUS_CLK_RATE * (1.0 - 1.0/(div-1)))      return (0, 8e-6 * BUS_CLK_RATE) -def run_loopback_bist(ctrls, duration, xxx_todo_changeme): -    (rate_sett, rate) = xxx_todo_changeme -    print('[INFO] Running Loopback BIST at %.0fMB/s for %.0fs...'%(rate,duration)) +def run_ber_loopback_bist(ctrls, duration, rate_tuple): +    (rate_sett, rate) = rate_tuple +    print('[INFO] Running BER Loopback BIST at %.0fMB/s for %.0fs...'%(rate,duration))      # Determine offsets      (mst_port, link_up) = get_aurora_info(ctrls['master'])      MST_MAC_REG_BASE = SFP0_MAC_REG_BASE if (mst_port == 0) else SFP1_MAC_REG_BASE @@ -165,6 +167,93 @@ def run_loopback_bist(ctrls, duration, xxx_todo_changeme):      if 'slave' in ctrls:          ctrls['slave'].poke(SLA_MAC_REG_BASE + MAC_REG_CTRL, 0) +def run_latency_loopback_bist(ctrls, duration, rate_tuple): +    (rate_sett, rate) = rate_tuple +    print('[INFO] Running Latency Loopback BIST at %.0fMB/s for %.0fs...'%(rate,duration)) +    # Determine offsets +    (mst_port, link_up) = get_aurora_info(ctrls['master']) +    MST_MAC_REG_BASE = SFP0_MAC_REG_BASE if (mst_port == 0) else SFP1_MAC_REG_BASE +    if 'slave' in ctrls: +        (sla_port, link_up) = get_aurora_info(ctrls['slave']) +        SLA_MAC_REG_BASE = SFP0_MAC_REG_BASE if (sla_port == 0) else SFP1_MAC_REG_BASE +    # Reset both PHYS +    ctrls['master'].poke(MST_MAC_REG_BASE + MAC_REG_CTRL, MAC_CTRL_PHY_RESET) +    ctrls['master'].poke(MST_MAC_REG_BASE + MAC_REG_CTRL, 0) +    if 'slave' in ctrls: +        ctrls['slave'].poke(SLA_MAC_REG_BASE + MAC_REG_CTRL, MAC_CTRL_PHY_RESET) +        ctrls['slave'].poke(SLA_MAC_REG_BASE + MAC_REG_CTRL, 0) +    time.sleep(1.5) + +    # Put the slave in loopback mode and the master in BIST mode +    if 'slave' in ctrls: +        ctrls['slave'].poke(SLA_MAC_REG_BASE + MAC_REG_CTRL, MAC_CTRL_BIST_LOOPBACK_EN) +    if rate_sett == 0: +        master_ctrl = MAC_CTRL_BIST_GEN_EN|MAC_CTRL_BIST_CHECKER_EN +    else: +        master_ctrl = ((rate_sett - 1) << MAC_CTRL_BIST_RATE_OFFSET)|MAC_CTRL_BIST_GEN_EN|MAC_CTRL_BIST_CHECKER_EN + +    start_time = datetime.datetime.now() +    latencies = [] +    mst_lock_errors = 0 +    mst_hard_errors = 0 +    mst_overruns = 0 +    try: +        for i in tqdm.tqdm(list(range(duration*10)), desc='[INFO] Progress'): +            ctrls['master'].poke(MST_MAC_REG_BASE + MAC_REG_CTRL, master_ctrl) +            # Wait and check if BIST locked +            time.sleep(0.05) +            mst_status = ctrls['master'].peek(MST_MAC_REG_BASE + MAC_REG_STATUS) +            if (not (mst_status & MAC_STATUS_BIST_LOCKED_MSK)): +                mst_lock_errors += 1 +            # Turn off the BIST generator +            ctrls['master'].poke(MST_MAC_REG_BASE + MAC_REG_CTRL, MAC_CTRL_BIST_CHECKER_EN) +            # Validate status and no overruns +            mst_status = ctrls['master'].peek(MST_MAC_REG_BASE + MAC_REG_STATUS) +            mst_overruns += ctrls['master'].peek(MST_MAC_REG_BASE + MAC_REG_OVERRUNS) +            if (mst_status & MAC_STATUS_HARD_ERR_MSK): +                mst_hard_errors += 1 +            time.sleep(0.05) +            ctrls['master'].poke(MST_MAC_REG_BASE + MAC_REG_CTRL, 0) +            # Compure latency +            mst_latency_cyc = 16.0*((mst_status & MAC_STATUS_BIST_LATENCY_MSK) >> MAC_STATUS_BIST_LATENCY_OFFSET) +            mst_latency_us = 1e6*mst_latency_cyc/AURORA_CLK_RATE +            latencies.append(mst_latency_us) +    except KeyboardInterrupt: +        print('[WARNING] Operation cancelled by user.') +    stop_time = datetime.datetime.now() +    # Report +    if (mst_lock_errors > 0): +        print('[ERROR] BIST engine did not lock onto a PRBS word %d times!'%(mst_lock_errors)) +    if (mst_hard_errors > 0): +        print('[ERROR] There were %d hard errors in master PHY'%(mst_hard_errors)) +    if (mst_overruns > 0): +        print('[ERROR] There were %d buffer overruns in master PHY'%(mst_overruns)) + +    print('[INFO] BIST Complete!') +    print('- Elapsed Time               = ' + str(stop_time - start_time)) +    print('- Roundtrip Latency Mean     = %.2fus'%(numpy.mean(latencies))) +    print('- Roundtrip Latency Stdev    = %.2fus'%(numpy.std(latencies))) +    # Turn off BIST loopback     +    time.sleep(0.5) +    if 'slave' in ctrls: +        ctrls['slave'].poke(SLA_MAC_REG_BASE + MAC_REG_CTRL, 0) +    if 'slave' in ctrls: +        sla_status = ctrls['slave'].peek(SLA_MAC_REG_BASE + MAC_REG_STATUS) +        sla_overruns = ctrls['slave'].peek(SLA_MAC_REG_BASE + MAC_REG_OVERRUNS) +        if (sla_status & MAC_STATUS_HARD_ERR_MSK): +            print('[ERROR] Hard errors in slave PHY') +        if (sla_overruns > 0): +            print('[ERROR] Buffer overruns in slave PHY') +    # Drain and Cleanup +    print('[INFO] Cleaning up...') +    ctrls['master'].poke(MST_MAC_REG_BASE + MAC_REG_CTRL, MAC_CTRL_BIST_CHECKER_EN) +    if 'slave' in ctrls: +        ctrls['slave'].poke(SLA_MAC_REG_BASE + MAC_REG_CTRL, MAC_CTRL_BIST_CHECKER_EN) +    time.sleep(0.5) +    ctrls['master'].poke(MST_MAC_REG_BASE + MAC_REG_CTRL, 0) +    if 'slave' in ctrls: +        ctrls['slave'].poke(SLA_MAC_REG_BASE + MAC_REG_CTRL, 0) +  ########################################################################  # command line options  ######################################################################## @@ -172,6 +261,7 @@ def get_options():      parser = argparse.ArgumentParser(description='Controller for the USRP X3X0 Aurora BIST Engine')      parser.add_argument('--master', type=str, default=None, required=True, help='IP Address of master USRP-X3X0 device')      parser.add_argument('--slave', type=str, default=None, help='IP Address of slave USRP-X3X0 device') +    parser.add_argument('--test', type=str, default='ber', choices=['ber', 'latency'], help='Type of test to run')      parser.add_argument('--duration', type=int, default=10, help='Duration of test in seconds')      parser.add_argument('--rate', type=int, default=1245, help='BIST throughput in MB/s')      return parser.parse_args() @@ -210,4 +300,8 @@ if __name__=='__main__':          exit(1)      # Run BIST -    run_loopback_bist(ctrls, options.duration, get_rate_setting(options.rate)) +    if options.test == 'ber': +        run_ber_loopback_bist(ctrls, options.duration, get_rate_setting(options.rate)) +    else: +        run_latency_loopback_bist(ctrls, options.duration, get_rate_setting(options.rate)) + diff --git a/firmware/usrp3/x300/x300_defs.h b/firmware/usrp3/x300/x300_defs.h index efd44b49d..e9e9f34fa 100644 --- a/firmware/usrp3/x300/x300_defs.h +++ b/firmware/usrp3/x300/x300_defs.h @@ -4,7 +4,7 @@  #ifndef INCLUDED_X300_DEFS_H  #define INCLUDED_X300_DEFS_H -#define CPU_CLOCK 166666667 +#define CPU_CLOCK  83333333  #define MAIN_RAM_BASE 0x0000  #define PKT_RAM0_BASE 0x8000  #define SFP0_MAC_BASE 0xC000 diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index 643857708..4d1654c21 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -332,8 +332,8 @@ UHD_INSTALL(FILES  #{{{IMG_SECTION  # This section is written automatically by /images/create_imgs_package.py  # Any manual changes in here will be overwritten. -SET(UHD_IMAGES_MD5SUM "26473d4f18d2c9a207062e107bda1d11") -SET(UHD_IMAGES_DOWNLOAD_SRC "uhd-images_003.010.000.000-release.zip") +SET(UHD_IMAGES_MD5SUM "4f4a6c229f5a3906dc63533d3a505feb") +SET(UHD_IMAGES_DOWNLOAD_SRC "uhd-images_003.010.000.000-36-g967897e0.zip")  #}}}  ######################################################################## diff --git a/host/cmake/debian/changelog b/host/cmake/debian/changelog index 48732ca38..f38aab406 100644 --- a/host/cmake/debian/changelog +++ b/host/cmake/debian/changelog @@ -22,6 +22,24 @@ uhd (3.10.0.0-0ubuntu1) trusty; urgency=low   -- Ettus Research <packages@ettus.com>  Thu, 11 Aug 2016 04:48:49 -0800 +uhd (3.9.5-0ubuntu1) trusty; urgency=low + +  - B200: Update DSPs after changing tick rate +  - X300: Added option to disable ADC self test, prevent DAC from +    underrunning +  - UBX: Fixed noise issues, reduced power consumption/heat, added codes for +    upcoming board revisions, force RX LNAs on (reduces rx settling time) +  - WBX: Fixed rev2 and rev3 boards on X300 +  - Utils/Examples: Cleaned up query_gpsdo_sensors, test_dboard_coercion, +  - Manual: Minor fixes and updates +  - CMake: Fix lib64 detection, better platform detection, Doxygen may use shorter +    filenames +  - Octoclock: GPSDO-related fixes, sequence number consistency fixes, UART +    fixes (off-by-one errors). uhd_usrp_probe will pick up an OC now, +    added Wireshark dissector for OC packets + + -- Ettus Research <packages@ettus.com>  Mon, 22 Aug 2016 02:36:40 -0800 +  uhd (3.9.4-0ubuntu1) trusty; urgency=low    - GPIO control: Fix address mismatch for RX and full duplex. diff --git a/host/lib/usrp/dboard/db_ubx.cpp b/host/lib/usrp/dboard/db_ubx.cpp index be3bdd17d..7416de735 100644 --- a/host/lib/usrp/dboard/db_ubx.cpp +++ b/host/lib/usrp/dboard/db_ubx.cpp @@ -154,6 +154,12 @@ static const dboard_id_t UBX_V1_40MHZ_TX_ID(0x77);  static const dboard_id_t UBX_V1_40MHZ_RX_ID(0x78);  static const dboard_id_t UBX_V1_160MHZ_TX_ID(0x79);  static const dboard_id_t UBX_V1_160MHZ_RX_ID(0x7A); +static const dboard_id_t UBX_V2_40MHZ_TX_ID(0x7B); +static const dboard_id_t UBX_V2_40MHZ_RX_ID(0x7C); +static const dboard_id_t UBX_V2_160MHZ_TX_ID(0x7D); +static const dboard_id_t UBX_V2_160MHZ_RX_ID(0x7E); +static const dboard_id_t UBX_LP_160MHZ_TX_ID(0x0200); +static const dboard_id_t UBX_LP_160MHZ_RX_ID(0x0201);  static const freq_range_t ubx_freq_range(10e6, 6.0e9);  static const gain_range_t ubx_tx_gain_range(0, 31.5, double(0.5));  static const gain_range_t ubx_rx_gain_range(0, 31.5, double(0.5)); @@ -221,19 +227,34 @@ public:          _iface = get_iface();          dboard_id_t rx_id = get_rx_id();          dboard_id_t tx_id = get_tx_id(); -        if (rx_id == UBX_PROTO_V3_RX_ID and tx_id == UBX_PROTO_V3_TX_ID) +        if (rx_id == UBX_PROTO_V3_RX_ID and tx_id == UBX_PROTO_V3_TX_ID) {              _rev = 0; -        else if (rx_id == UBX_PROTO_V4_RX_ID and tx_id == UBX_PROTO_V4_TX_ID) +        } +        else if (rx_id == UBX_PROTO_V4_RX_ID and tx_id == UBX_PROTO_V4_TX_ID) {              _rev = 1; -        else if (rx_id == UBX_V1_40MHZ_RX_ID and tx_id == UBX_V1_40MHZ_TX_ID) +        } +        else if (rx_id == UBX_V1_40MHZ_RX_ID and tx_id == UBX_V1_40MHZ_TX_ID) {              _rev = 1; -        else if (rx_id == UBX_V1_160MHZ_RX_ID and tx_id == UBX_V1_160MHZ_TX_ID) -        { +        } +        else if (rx_id == UBX_V2_40MHZ_RX_ID and tx_id == UBX_V2_40MHZ_TX_ID) { +            _rev = 2; +        } +        else if (rx_id == UBX_V1_160MHZ_RX_ID and tx_id == UBX_V1_160MHZ_TX_ID) {              bw = 160e6;              _rev = 1;          } -        else +        else if (rx_id == UBX_V2_160MHZ_RX_ID and tx_id == UBX_V2_160MHZ_TX_ID) { +            bw = 160e6; +            _rev = 2; +        } +        else if (rx_id == UBX_LP_160MHZ_RX_ID and tx_id == UBX_LP_160MHZ_TX_ID) { +            // The LP version behaves and looks like a regular UBX-160 v2 +            bw = 160e6; +            _rev = 2; +        } +        else {              UHD_THROW_INVALID_CODE_PATH(); +        }          switch(_rev)          { @@ -243,6 +264,7 @@ public:              pfd_freq_max = 25e6;              break;          case 1: +        case 2:              for (size_t i = 0; i < sizeof(ubx_v1_gpio_info) / sizeof(ubx_gpio_field_info_t); i++)                  _gpio_map[ubx_v1_gpio_info[i].id] = ubx_v1_gpio_info[i];              pfd_freq_max = 50e6; @@ -355,7 +377,7 @@ public:                  lo->set_ld_pin_mode(max287x_iface::LD_PIN_MODE_DLD);              }          } -        else if (_rev == 1) +        else if (_rev == 1 or _rev == 2)          {              _txlo1 = max287x_iface::make<max2871>(boost::bind(&ubx_xcvr::write_spi_regs, this, TXLO1, _1));              _txlo2 = max287x_iface::make<max2871>(boost::bind(&ubx_xcvr::write_spi_regs, this, TXLO2, _1)); @@ -1242,8 +1264,11 @@ static dboard_base::sptr make_ubx(dboard_base::ctor_args_t args)  UHD_STATIC_BLOCK(reg_ubx_dboards)  { -    dboard_manager::register_dboard(UBX_PROTO_V3_RX_ID, UBX_PROTO_V3_TX_ID, &make_ubx, "UBX v0.3"); -    dboard_manager::register_dboard(UBX_PROTO_V4_RX_ID, UBX_PROTO_V4_TX_ID, &make_ubx, "UBX v0.4"); -    dboard_manager::register_dboard(UBX_V1_40MHZ_RX_ID, UBX_V1_40MHZ_TX_ID, &make_ubx, "UBX-40 v1"); +    dboard_manager::register_dboard(UBX_PROTO_V3_RX_ID,  UBX_PROTO_V3_TX_ID,  &make_ubx, "UBX v0.3"); +    dboard_manager::register_dboard(UBX_PROTO_V4_RX_ID,  UBX_PROTO_V4_TX_ID,  &make_ubx, "UBX v0.4"); +    dboard_manager::register_dboard(UBX_V1_40MHZ_RX_ID,  UBX_V1_40MHZ_TX_ID,  &make_ubx, "UBX-40 v1");      dboard_manager::register_dboard(UBX_V1_160MHZ_RX_ID, UBX_V1_160MHZ_TX_ID, &make_ubx, "UBX-160 v1"); +    dboard_manager::register_dboard(UBX_V2_40MHZ_RX_ID,  UBX_V2_40MHZ_TX_ID,  &make_ubx, "UBX-40 v2"); +    dboard_manager::register_dboard(UBX_V2_160MHZ_RX_ID, UBX_V2_160MHZ_TX_ID, &make_ubx, "UBX-160 v2"); +    dboard_manager::register_dboard(UBX_LP_160MHZ_RX_ID, UBX_LP_160MHZ_TX_ID, &make_ubx, "UBX-160-LP");  } diff --git a/host/lib/usrp/x300/x300_fw_common.h b/host/lib/usrp/x300/x300_fw_common.h index e05cd9ec7..aae0f769c 100644 --- a/host/lib/usrp/x300/x300_fw_common.h +++ b/host/lib/usrp/x300/x300_fw_common.h @@ -31,9 +31,9 @@ extern "C" {  #define X300_REVISION_COMPAT 7  #define X300_REVISION_MIN    2 -#define X300_FW_COMPAT_MAJOR 4 +#define X300_FW_COMPAT_MAJOR 5  #define X300_FW_COMPAT_MINOR 0 -#define X300_FPGA_COMPAT_MAJOR 0x20 +#define X300_FPGA_COMPAT_MAJOR 0x21  //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 6ebe30739..5f47c35ed 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -694,7 +694,7 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)      mb.zpu_spi = spi_core_3000::make(mb.zpu_ctrl, SR_ADDR(SET0_BASE, ZPU_SR_SPI),              SR_ADDR(SET0_BASE, ZPU_RB_SPI));      mb.zpu_i2c = i2c_core_100_wb32::make(mb.zpu_ctrl, I2C1_BASE); -    mb.zpu_i2c->set_clock_rate(X300_BUS_CLOCK_RATE); +    mb.zpu_i2c->set_clock_rate(X300_BUS_CLOCK_RATE/2);      ////////////////////////////////////////////////////////////////////      // print network routes mapping | 
