diff options
| -rw-r--r-- | firmware/usrp3/x300/x300_main.c | 37 | ||||
| -rw-r--r-- | host/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | host/cmake/debian/changelog | 23 | ||||
| -rw-r--r-- | host/docs/usrp_e3x0.dox | 1 | ||||
| -rw-r--r-- | host/lib/experts/expert_container.cpp | 4 | ||||
| -rwxr-xr-x | host/lib/ic_reg_maps/gen_adf5355_regs.py | 8 | ||||
| -rw-r--r-- | host/lib/usrp/common/adf5355.cpp | 45 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/device3/device3_io_impl.cpp | 1 | ||||
| -rw-r--r-- | host/lib/usrp/gps_ctrl.cpp | 10 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_fw_uart.cpp | 33 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_impl.cpp | 31 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_impl.hpp | 5 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_radio_ctrl_impl.cpp | 11 | ||||
| -rw-r--r-- | host/utils/query_gpsdo_sensors.cpp | 99 | 
15 files changed, 184 insertions, 130 deletions
diff --git a/firmware/usrp3/x300/x300_main.c b/firmware/usrp3/x300/x300_main.c index c5e4fc88a..459f7b0b1 100644 --- a/firmware/usrp3/x300/x300_main.c +++ b/firmware/usrp3/x300/x300_main.c @@ -217,30 +217,28 @@ void handle_udp_mtu_detect(  /***********************************************************************   * Deal with host claims and claim timeout   **********************************************************************/ -static void handle_claim(void) +static void handle_claim(uint32_t ticks_now)  { +    static const uint32_t CLAIM_TIMEOUT = 2*CPU_CLOCK;      // 2 seconds +    static uint32_t ticks_last_claim = 0;      static uint32_t last_time = 0; -    static size_t timeout = 0; -    //time is 0 if the claim was forfeit -    if (shmem[X300_FW_SHMEM_CLAIM_TIME] == 0) +    // Claim status can only change if the claim is active or the claim is renewed. +    if (shmem[X300_FW_SHMEM_CLAIM_STATUS] != 0 && +            (shmem[X300_FW_SHMEM_CLAIM_TIME] == 0 || +            ticks_now - ticks_last_claim > CLAIM_TIMEOUT))      { -        shmem[X300_FW_SHMEM_CLAIM_STATUS] = 0; +            // the claim was released or timed out +            shmem[X300_FW_SHMEM_CLAIM_STATUS] = 0; +            last_time = shmem[X300_FW_SHMEM_CLAIM_TIME];      } -    //if the time changes, reset timeout      else if (last_time != shmem[X300_FW_SHMEM_CLAIM_TIME])      { +        // claim was renewed          shmem[X300_FW_SHMEM_CLAIM_STATUS] = 1; -        timeout = 0; +        last_time = shmem[X300_FW_SHMEM_CLAIM_TIME]; +        ticks_last_claim = ticks_now;      } -    //otherwise increment for timeout -    else timeout++; - -    //always stash the last seen time -    last_time = shmem[X300_FW_SHMEM_CLAIM_TIME]; - -    //the claim has timed out after 2 seconds -    if (timeout > 200) shmem[X300_FW_SHMEM_CLAIM_STATUS] = 0;  }  /*********************************************************************** @@ -419,8 +417,14 @@ int main(void)      while(true)      { -        //jobs that happen once every 10ms          const uint32_t ticks_now = wb_peek32(SR_ADDR(RB0_BASE, RB_COUNTER)); + +        // handle the claim every time because any packet processed could +        // have claimed or released the device and we want the claim status +        // to be updated immediately to make it atomic from the host perspective +        handle_claim(ticks_now); + +        //jobs that happen once every 10ms          const uint32_t ticks_passed = ticks_now - last_cronjob;          static const uint32_t tick_delta = CPU_CLOCK/100;          if (ticks_passed > tick_delta) @@ -428,7 +432,6 @@ int main(void)              poll_sfpp_status(0); // Every so often poll XGE Phy to look for SFP+ hotplug events.              poll_sfpp_status(1); // Every so often poll XGE Phy to look for SFP+ hotplug events.              //handle_link_state(); //deal with router table update -            handle_claim(); //deal with the host claim register              update_leds(); //run the link and activity leds              garp(); //send periodic garps              last_cronjob = ticks_now; diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index 40c92b856..a7274a451 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -357,8 +357,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 "9641027408a4bbd478ad221d3dae1cfd") -SET(UHD_IMAGES_DOWNLOAD_SRC "uhd-images_003.010.001.001-rc1.zip") +SET(UHD_IMAGES_MD5SUM "e5ac0830665a6c77a46ba0ae32f9fa11") +SET(UHD_IMAGES_DOWNLOAD_SRC "uhd-images_003.010.001.001-release.zip")  #}}}  ######################################################################## diff --git a/host/cmake/debian/changelog b/host/cmake/debian/changelog index 94ee3885a..5dea31b00 100644 --- a/host/cmake/debian/changelog +++ b/host/cmake/debian/changelog @@ -1,3 +1,26 @@ +uhd (3.10.1.1-0ubuntu1) trusty; urgency=low + +  - Docs: The protocol for Gen-3 devices is now consistently referred to as CHDR. +  - X300: Fixed EEPROM corruption bug (happened when two processes would access +    find routines on the same device at the same time). Improved initialization +    time. CE clock is now 214 MHz. Fixed channel list generation. Find routines +    now more lenient in case one devices fails (others can still be found then). +    Improve PCIe behaviour. Fix timed commands for non-TwinRX dboards. Improve +    AXI Interconnect (faster, improved build timing). +  - N230: Use second_addr (like X300). +  - C API: Added UHD_VERSION macro. Fixed online rate change. +  - Utils: Minor fixes to uhd_images_downloader. +  - Build/CMake: Fixed some Py3k build issues. Fixed many compiler warnings. Allow +    to specify package names. +  - RFNoC: Fixed sampling rate mismatch error. Noc-Shell uses a non-cascaded 2-clk +    FIFO. Increase default FIFO sizes on DUC and DDC blocks. +  - UBX: Force on RX driver to eliminate transient. +  - Transport code: Fixed memory leak. +  - FPGA repository: Merged usrp3_rfnoc and usrp3 directories again. Cleaned up +    superfluous files. Clean separation between Gen-3 and other devices in usrp3. + + -- Ettus Research <packages@ettus.com>  Thu, 26 Jan 2017 04:15:56 -0800 +  uhd (3.10.1.0-0ubuntu1) trusty; urgency=low    - Fixed multiple compiler warnings diff --git a/host/docs/usrp_e3x0.dox b/host/docs/usrp_e3x0.dox index 470f6a26b..929b9f635 100644 --- a/host/docs/usrp_e3x0.dox +++ b/host/docs/usrp_e3x0.dox @@ -18,7 +18,6 @@  - FPGA Capabilities:          - 2 RX DDC chains in FPGA          - 2 TX DUC chain in FPGA -	- Timed commands in FPGA  	- Timed sampling in FPGA  	- 16-bit fixed point sample mode (sc16) diff --git a/host/lib/experts/expert_container.cpp b/host/lib/experts/expert_container.cpp index b9c78f9f5..853e3e4b7 100644 --- a/host/lib/experts/expert_container.cpp +++ b/host/lib/experts/expert_container.cpp @@ -100,7 +100,7 @@ public:      {          boost::lock_guard<boost::recursive_mutex> resolve_lock(_resolve_mutex);          boost::lock_guard<boost::mutex> lock(_mutex); -        EX_LOG(0, str(boost::format("resolve_from(%s)") % node_name)); +        EX_LOG(0, "resolve_from (overridden to resolve_all)");          // Do a full resolve of the graph          // Not optimizing the traversal using node_name to reduce experts complexity          _resolve_helper("", "", false); @@ -110,7 +110,7 @@ public:      {          boost::lock_guard<boost::recursive_mutex> resolve_lock(_resolve_mutex);          boost::lock_guard<boost::mutex> lock(_mutex); -        EX_LOG(0, str(boost::format("resolve_to(%s)") % node_name)); +        EX_LOG(0, "resolve_to (overridden to resolve_all)");          // Do a full resolve of the graph          // Not optimizing the traversal using node_name to reduce experts complexity          _resolve_helper("", "", false); diff --git a/host/lib/ic_reg_maps/gen_adf5355_regs.py b/host/lib/ic_reg_maps/gen_adf5355_regs.py index 9644f2e53..a69f126cc 100755 --- a/host/lib/ic_reg_maps/gen_adf5355_regs.py +++ b/host/lib/ic_reg_maps/gen_adf5355_regs.py @@ -26,7 +26,7 @@ REGS_TMPL="""\  ########################################################################  int_16_bit              0[4:19]     0  prescaler               0[20]       0       4_5, 8_9 -autocal_en              0[21]       0       disabled, enabled +autocal_en              0[21]       1       disabled, enabled  reg0_reserved0          0[22:31]    0x000  ########################################################################  ## address 1 @@ -53,13 +53,13 @@ counter_reset           4[4]        0       disabled, enabled  cp_three_state          4[5]        0       disabled, enabled  power_down              4[6]        0       disabled, enabled  pd_polarity             4[7]        1       negative, positive -mux_logic               4[8]        0       1_8V, 3_3V +mux_logic               4[8]        1       1_8V, 3_3V  ref_mode                4[9]        0       single, diff  <% current_setting_enums = ', '.join(map(lambda x: '_'.join(("%0.2fma"%(round(x*31.27 + 31.27)/100)).split('.')), range(0,16))) %>\  charge_pump_current     4[10:13]    0       ${current_setting_enums}  double_buff_div         4[14]       0       disabled, enabled  r_counter_10_bit        4[15:24]    0 -reference_divide_by_2   4[25]       1       disabled, enabled +reference_divide_by_2   4[25]       0       disabled, enabled  reference_doubler       4[26]       0       disabled, enabled  muxout                  4[27:29]    1       3state, dvdd, dgnd, rdiv, ndiv, analog_ld, dld, reserved  reg4_reserved0          4[30:31]    0 @@ -91,7 +91,7 @@ frac_n_ld_precision     7[5:6]      0       5ns, 6ns, 8ns, 12ns  loss_of_lock_mode       7[7]        0       disabled, enabled  ld_cyc_count            7[8:9]      0       1024, 2048, 4096, 8192  reg7_reserved0          7[10:24]    0x0 -le_sync                 7[25]       0       disabled, le_synced_to_refin +le_sync                 7[25]       1       disabled, le_synced_to_refin  reg7_reserved1          7[26:31]    0x4  ########################################################################  ## address 8 diff --git a/host/lib/usrp/common/adf5355.cpp b/host/lib/usrp/common/adf5355.cpp index ee9d1d1d9..e3fd66bc2 100644 --- a/host/lib/usrp/common/adf5355.cpp +++ b/host/lib/usrp/common/adf5355.cpp @@ -62,43 +62,14 @@ public:          _pfd_freq(0.0),          _fb_after_divider(false)      { -        _regs.counter_reset = adf5355_regs_t::COUNTER_RESET_DISABLED; -        _regs.cp_three_state = adf5355_regs_t::CP_THREE_STATE_DISABLED; -        _regs.power_down = adf5355_regs_t::POWER_DOWN_DISABLED; -        _regs.pd_polarity = adf5355_regs_t::PD_POLARITY_POSITIVE; -        _regs.mux_logic = adf5355_regs_t::MUX_LOGIC_3_3V; -        _regs.ref_mode = adf5355_regs_t::REF_MODE_SINGLE; -        _regs.muxout = adf5355_regs_t::MUXOUT_DLD; -        _regs.double_buff_div = adf5355_regs_t::DOUBLE_BUFF_DIV_DISABLED; - -        _regs.rf_out_a_enabled = adf5355_regs_t::RF_OUT_A_ENABLED_ENABLED; -        _regs.rf_out_b_enabled = adf5355_regs_t::RF_OUT_B_ENABLED_DISABLED; -        _regs.mute_till_lock_detect = adf5355_regs_t::MUTE_TILL_LOCK_DETECT_MUTE_DISABLED; -        _regs.ld_mode = adf5355_regs_t::LD_MODE_FRAC_N; -        _regs.frac_n_ld_precision = adf5355_regs_t::FRAC_N_LD_PRECISION_5NS; -        _regs.ld_cyc_count = adf5355_regs_t::LD_CYC_COUNT_1024; -        _regs.le_sync = adf5355_regs_t::LE_SYNC_LE_SYNCED_TO_REFIN; -        _regs.phase_resync = adf5355_regs_t::PHASE_RESYNC_DISABLED; -        _regs.reference_divide_by_2 = adf5355_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED; -        _regs.reference_doubler = adf5355_regs_t::REFERENCE_DOUBLER_DISABLED; -        _regs.autocal_en = adf5355_regs_t::AUTOCAL_EN_ENABLED; -        _regs.prescaler = adf5355_regs_t::PRESCALER_4_5; +        // TODO This is a hardware specific value, but can be made the default in the ic_reg_map          _regs.charge_pump_current = adf5355_regs_t::CHARGE_PUMP_CURRENT_0_94MA; -        _regs.gated_bleed = adf5355_regs_t::GATED_BLEED_DISABLED; -        _regs.negative_bleed = adf5355_regs_t::NEGATIVE_BLEED_ENABLED; -        _regs.feedback_select = adf5355_regs_t::FEEDBACK_SELECT_FUNDAMENTAL; -        _regs.output_power = adf5355_regs_t::OUTPUT_POWER_5DBM; +        // TODO cleanup these magic numbers          _regs.cp_bleed_current = 2;          _regs.r_counter_10_bit = 8; - -        _regs.ld_cyc_count = adf5355_regs_t::LD_CYC_COUNT_1024; -        _regs.loss_of_lock_mode = adf5355_regs_t::LOSS_OF_LOCK_MODE_DISABLED; -        _regs.frac_n_ld_precision = adf5355_regs_t::FRAC_N_LD_PRECISION_5NS; -        _regs.ld_mode = adf5355_regs_t::LD_MODE_FRAC_N; -          _regs.vco_band_div = 3;          _regs.timeout = 11;          _regs.auto_level_timeout = 30; @@ -108,6 +79,14 @@ public:          _regs.adc_conversion = adf5355_regs_t::ADC_CONVERSION_ENABLED;          _regs.adc_enable = adf5355_regs_t::ADC_ENABLE_ENABLED; + +        // TODO Needs to be enabled for phase resync +        _regs.phase_resync = adf5355_regs_t::PHASE_RESYNC_DISABLED; + +        // TODO Default should be divided, but there seems to be a bug preventing that. Needs rechecking +        _regs.feedback_select = adf5355_regs_t::FEEDBACK_SELECT_FUNDAMENTAL; +         +        // TODO 0 is an invalid value for this field. Setting to 1 seemed to break phase sync, needs retesting.          _regs.phase_resync_clk_div = 0;      } @@ -193,7 +172,9 @@ public:          //-----------------------------------------------------------          //Phase resync -        _regs.phase_resync = adf5355_regs_t::PHASE_RESYNC_DISABLED; // Disabled during development +        // TODO Renable here, in initialization, or through separate set_phase_resync(bool enable) function +        _regs.phase_resync = adf5355_regs_t::PHASE_RESYNC_DISABLED; +          _regs.phase_adjust = adf5355_regs_t::PHASE_ADJUST_DISABLED;          _regs.sd_load_reset = adf5355_regs_t::SD_LOAD_RESET_ON_REG0_UPDATE;          _regs.phase_resync_clk_div = static_cast<uint16_t>( diff --git a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp index dfbea9917..346f39589 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp @@ -106,6 +106,8 @@ public:              _config_lo2_route(i==0?LO_CONFIG_CH1:LO_CONFIG_CH2);              _lo1_iface[i]->set_output_power(adf5355_iface::OUTPUT_POWER_5DBM);              _lo1_iface[i]->set_reference_freq(TWINRX_DESIRED_REFERENCE_FREQ); +            // Divided feedback did not appear to be correctly implemented during bringup. Necessary for phase resync +//            _lo1_iface[i]->set_feedback_select(adf5355_iface::FB_SEL_DIVIDED);              _lo1_iface[i]->set_muxout_mode(adf5355_iface::MUXOUT_DLD);              _lo1_iface[i]->set_frequency(3e9, 1.0e3);              _lo2_iface[i]->set_feedback_select(adf435x_iface::FB_SEL_DIVIDED); diff --git a/host/lib/usrp/device3/device3_io_impl.cpp b/host/lib/usrp/device3/device3_io_impl.cpp index bb98b1031..2f2e778c9 100644 --- a/host/lib/usrp/device3/device3_io_impl.cpp +++ b/host/lib/usrp/device3/device3_io_impl.cpp @@ -808,6 +808,7 @@ tx_streamer::sptr device3_impl::get_tx_stream(const uhd::stream_args_t &args_)                  )          ); +        blk_ctrl->sr_write(uhd::rfnoc::SR_CLEAR_RX_FC, 0xc1ea12, block_port);          blk_ctrl->sr_write(uhd::rfnoc::SR_RESP_IN_DST_SID, xport.recv_sid.get_dst(), block_port);          UHD_STREAMER_LOG() << "[TX Streamer] resp_in_dst_sid == " << boost::format("0x%04X") % xport.recv_sid.get_dst() << std::endl; diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp index 28f5a28cd..f4a42af34 100644 --- a/host/lib/usrp/gps_ctrl.cpp +++ b/host/lib/usrp/gps_ctrl.cpp @@ -92,7 +92,7 @@ private:                      sentences[which].get<2>() = true;                  }              } catch(std::exception &e) { -                UHD_MSG(warning) << "get_sentence: " << e.what(); +                UHD_LOGV(often) << "get_sentence: " << e.what();              }              if (not sentence.empty() or now > exit_time) @@ -134,7 +134,7 @@ private:      }    void update_cache() { -    if(not gps_detected() or (_gps_type != GPS_TYPE_INTERNAL_GPSDO)) { +    if(not gps_detected()) {          return;      } @@ -352,11 +352,11 @@ private:              return gps_time;          } catch(std::exception &e) { -            UHD_MSG(warning) << "get_time: " << e.what(); +            UHD_LOGV(often) << "get_time: " << e.what();              error_cnt++;          }      } -    throw uhd::value_error("Timeout after no valid message found"); +    throw uhd::value_error("get_time: Timeout after no valid message found");      return gps_time; //keep gcc from complaining    } @@ -379,7 +379,7 @@ private:              else                  return (get_token(reply, 6) != "0");          } catch(std::exception &e) { -            UHD_MSG(warning) << "locked: " << e.what(); +            UHD_LOGV(often) << "locked: " << e.what();              error_cnt++;          }      } diff --git a/host/lib/usrp/x300/x300_fw_uart.cpp b/host/lib/usrp/x300/x300_fw_uart.cpp index 6e7425c4d..a2cbcc908 100644 --- a/host/lib/usrp/x300/x300_fw_uart.cpp +++ b/host/lib/usrp/x300/x300_fw_uart.cpp @@ -76,8 +76,9 @@ struct x300_uart_iface : uart_iface          if (rxoffset == _last_device_rxoffset)              return -1; +        int ret = static_cast<int>(_rxcache[((rxoffset)/4) % poolsize] >> ((rxoffset%4)*8) & 0xFF);          rxoffset++; -        return static_cast<int>(_rxcache[(rxoffset/4) % poolsize] >> ((rxoffset%4)*8) & 0xFF); +        return ret;      }      void update_cache(void) @@ -91,30 +92,42 @@ struct x300_uart_iface : uart_iface              {                  // all the data is new - reload the entire cache                  for (uint32_t i = 0; i < poolsize; i++) +                {                      _rxcache[i] = _iface->peek32(SR_ADDR(rxpool, i)); +                } + +                // set the head to the same character as the current device +                // offset (tail) one loop earlier +                rxoffset = device_rxoffset - (poolsize*4); + +                // set the tail to the current device offset +                _last_device_rxoffset = device_rxoffset; -                // set rxoffset to the end of the first string -                rxoffset = device_rxoffset - (poolsize*4) + 1; -                while (static_cast<char>((_rxcache[(rxoffset/4) % poolsize] >> ((rxoffset%4)*8) & 0xFF)) != '\n') -                    ++rxoffset; +                // the string at the head is a partial, so skip it +                for (int c = getchar(); c != '\n' and c != -1; c = getchar()) {} -                // clear the partial string in the buffer; +                // clear the partial string in the buffer, if any                  _rxbuff.clear();              }              else if (rxoffset == _last_device_rxoffset)              {                  // new data was added - refresh the portion of the cache that was updated -                for (uint32_t i = ((_last_device_rxoffset+1)/4) % poolsize; i != (((device_rxoffset)/4)+1) % poolsize; i = (i+1) % poolsize) +                for (uint32_t i = (_last_device_rxoffset/4) % poolsize; +                        i != ((device_rxoffset/4)+1) % poolsize; +                        i = (i+1) % poolsize)                  {                      _rxcache[i] = _iface->peek32(SR_ADDR(rxpool, i));                  } -            } else { + +                // set the tail to the current device offset +                _last_device_rxoffset = device_rxoffset; +            } +            else +            {                  // there is new data, but we aren't done with what we have - check back later                  break;              } -            _last_device_rxoffset = device_rxoffset; -              // check again to see if anything changed while we were updating the cache              device_rxoffset = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_RX_INDEX));              delta = device_rxoffset - rxoffset; diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index 8164c79b6..aa54c2228 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -1529,13 +1529,32 @@ void x300_impl::claimer_loop(wb_iface::sptr iface)  x300_impl::claim_status_t x300_impl::claim_status(wb_iface::sptr iface)  { -    //If timed out, then device is definitely unclaimed -    if (iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_STATUS)) == 0) -        return UNCLAIMED; +    claim_status_t claim_status = CLAIMED_BY_OTHER; // Default to most restrictive +    boost::system_time timeout_time = boost::get_system_time() + boost::posix_time::seconds(1); +    while (boost::get_system_time() < timeout_time) +    { +        //If timed out, then device is definitely unclaimed +        if (iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_STATUS)) == 0) +        { +            claim_status = UNCLAIMED; +            break; +        } -    //otherwise check claim src to determine if another thread with the same src has claimed the device -    uint32_t hash = iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_SRC)); -    return (hash == get_process_hash() ? CLAIMED_BY_US : CLAIMED_BY_OTHER); +        //otherwise check claim src to determine if another thread with the same src has claimed the device +        uint32_t hash = iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_SRC)); +        if (hash == 0) +        { +            // A non-zero claim status and an empty hash means the claim might +            // be in the process of being released.  This is possible because +            // older firmware takes a long time to update the status.  Wait and +            // check status again. +            boost::this_thread::sleep(boost::posix_time::milliseconds(5)); +            continue; +        } +        claim_status = (hash == get_process_hash() ? CLAIMED_BY_US : CLAIMED_BY_OTHER); +        break; +    } +    return claim_status;  }  void x300_impl::claim(wb_iface::sptr iface) diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp index 55b055d44..d082ab76a 100644 --- a/host/lib/usrp/x300/x300_impl.hpp +++ b/host/lib/usrp/x300/x300_impl.hpp @@ -54,10 +54,7 @@ static const size_t X300_RX_SW_BUFF_SIZE_ETH_MACOS  = 0x100000; //1Mib  //where an element is 8 bytes. For best throughput ensure that the data frame fits in these buffers.  //Also ensure that the kernel has enough frames to hold buffered TX and RX data  static const size_t X300_PCIE_RX_DATA_FRAME_SIZE    = 8184;     //bytes -//static const size_t X300_PCIE_TX_DATA_FRAME_SIZE    = 8192;     //bytes -// This is a temporary solution: We're throttling PCIe MTU to avoid -// underruns on Tx. Once we solve it on the FPGA side, need revert this commit. -static const size_t X300_PCIE_TX_DATA_FRAME_SIZE    = 3000;     //bytes +static const size_t X300_PCIE_TX_DATA_FRAME_SIZE    = 8184;     //bytes  static const size_t X300_PCIE_DATA_NUM_FRAMES       = 2048;  static const size_t X300_PCIE_MSG_FRAME_SIZE        = 256;      //bytes  static const size_t X300_PCIE_MSG_NUM_FRAMES        = 64; diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp index f4ad0d035..9bf61f998 100644 --- a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp +++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp @@ -126,8 +126,7 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(x300_radio_ctrl)          // Bind the daughterboard command time to the motherboard level property          //////////////////////////////////////////////////////////////// -        if (_tree->exists(fs_path("time") / "cmd") and -                _tree->exists(fs_path("dboards" / _radio_slot /  "rx_frontends" / _rx_fe_map.at(i).db_fe_name / "time" / "cmd"))) { +        if (_tree->exists(fs_path("time") / "cmd")) {              _tree->access<time_spec_t>(fs_path("time") / "cmd")                  .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::set_fe_cmd_time, this, _1, i));          } @@ -180,9 +179,11 @@ double x300_radio_ctrl_impl::set_rate(double rate)  void x300_radio_ctrl_impl::set_fe_cmd_time(const time_spec_t &time, const size_t chan)  { -    _tree->access<time_spec_t>( -            fs_path("dboards" / _radio_slot /  "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd") -    ).set(time); +    if (_tree->exists(fs_path("dboards" / _radio_slot /  "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd"))) { +        _tree->access<time_spec_t>( +                fs_path("dboards" / _radio_slot /  "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd") +        ).set(time); +    }  }  void x300_radio_ctrl_impl::set_tx_antenna(const std::string &ant, const size_t chan) diff --git a/host/utils/query_gpsdo_sensors.cpp b/host/utils/query_gpsdo_sensors.cpp index 7420e62e9..6c2ec0bd1 100644 --- a/host/utils/query_gpsdo_sensors.cpp +++ b/host/utils/query_gpsdo_sensors.cpp @@ -120,67 +120,83 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){        return EXIT_FAILURE;    } -  // Explicitly set time source to gpsdo -  boost::this_thread::sleep(boost::posix_time::seconds(1)); +  std::cout << "\nSetting the reference clock source to \"gpsdo\"...\n";    try { -      usrp->set_time_source("gpsdo"); +      usrp->set_clock_source("gpsdo");    } catch (uhd::value_error &e) { -      std::cout << "could not set the time source to \"gpsdo\"; error was:" <<std::endl; +      std::cout << "could not set the clock source to \"gpsdo\"; error was:" <<std::endl;        std::cout << e.what() << std::endl;        std::cout << "trying \"external\"..." <<std::endl; -      try { -          usrp->set_time_source("external"); +      try{ +          usrp->set_clock_source("external");        } catch (uhd::value_error&) {            std::cout << "\"external\" failed, too." << std::endl;        }    } -  std::cout<< std::endl << "Time source is now " << usrp->get_time_source(0) << std::endl; +  std::cout<< std::endl << "Clock source is now " << usrp->get_clock_source(0) << std::endl; -  //Check for GPS lock -  uhd::sensor_value_t gps_locked = usrp->get_mboard_sensor("gps_locked",0); -  if(not gps_locked.to_bool()) { -      std::cout << boost::format("\nGPS does not have lock. Wait a few minutes and try again.\n"); -      std::cout << boost::format("NMEA strings and device time may not be accurate until lock is achieved.\n\n"); +  //Check for 10 MHz lock +  if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()) { +      uhd::sensor_value_t ref_locked = usrp->get_mboard_sensor("ref_locked",0); +      for (size_t i = 0; not ref_locked.to_bool() and i < 100; i++) { +          boost::this_thread::sleep(boost::posix_time::milliseconds(100)); +          ref_locked = usrp->get_mboard_sensor("ref_locked",0); +      } +      if(not ref_locked.to_bool()) { +          std::cout << boost::format("USRP NOT Locked to GPSDO 10 MHz Reference.\n"); +          std::cout << boost::format("Double check installation instructions (N2X0/E1X0 only): https://www.ettus.com/content/files/gpsdo-kit_4.pdf\n\n"); +          return EXIT_FAILURE; +      } else { +          std::cout << boost::format("USRP Locked to GPSDO 10 MHz Reference.\n"); +      }    } else { -      std::cout << boost::format("GPS Locked"); +      std::cout << boost::format("ref_locked sensor not present on this board.\n");    } -  std::cout << "\nSetting the reference clock source to \"gpsdo\"...\n"; +  // Explicitly set time source to gpsdo    try { -      usrp->set_clock_source("gpsdo"); +      usrp->set_time_source("gpsdo");    } catch (uhd::value_error &e) { -      std::cout << "could not set the clock source to \"gpsdo\"; error was:" <<std::endl; +      std::cout << "could not set the time source to \"gpsdo\"; error was:" <<std::endl;        std::cout << e.what() << std::endl;        std::cout << "trying \"external\"..." <<std::endl; -      try{ -          usrp->set_clock_source("external"); +      try { +          usrp->set_time_source("external");        } catch (uhd::value_error&) {            std::cout << "\"external\" failed, too." << std::endl;        }    } -  std::cout<< std::endl << "Clock source is now " << usrp->get_clock_source(0) << std::endl; +  std::cout << std::endl << "Time source is now " << usrp->get_time_source(0) << std::endl;    print_notes(); +  // The TCXO has a long warm up time, so wait up to 30 seconds for sensor data to show up +  std::cout << "Waiting for the GPSDO to warm up..." << std::endl; +  for (size_t i = 0; i < 300; i++) { +      try { +          usrp->get_mboard_sensor("gps_locked",0); +          break; +      } catch (std::exception &) {} +      boost::this_thread::sleep(boost::posix_time::milliseconds(100)); +  } +  try { +      usrp->get_mboard_sensor("gps_locked",0); +  } catch (std::exception &) { +      std::cout << "No response from GPSDO in 30 seconds" << std::endl; +      return EXIT_FAILURE; +  } +  std::cout << "The GPSDO is warmed up and talking." << std::endl; -  //Check for 10 MHz lock -  if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()) { -      uhd::sensor_value_t gps_locked = usrp->get_mboard_sensor("ref_locked",0); -      if(not gps_locked.to_bool()) { -          std::cout << boost::format("USRP NOT Locked to GPSDO 10 MHz Reference.\n"); -          std::cout << boost::format("Double check installation instructions (N2X0/E1X0 only): https://www.ettus.com/content/files/gpsdo-kit_4.pdf\n\n"); -          std::cout << boost::format("Locking the internal reference to the GPSDO might take a second to reach stability. Retrying in 10 s...\n\n"); -          boost::this_thread::sleep(boost::posix_time::seconds(10)); -      } -      if(usrp->get_mboard_sensor("ref_locked",0).to_bool()) { -          std::cout << boost::format("USRP Locked to GPSDO 10 MHz Reference.\n"); -      } +  //Check for GPS lock +  uhd::sensor_value_t gps_locked = usrp->get_mboard_sensor("gps_locked",0);; +  if(not gps_locked.to_bool()) { +      std::cout << boost::format("\nGPS does not have lock. Wait a few minutes and try again.\n"); +      std::cout << boost::format("NMEA strings and device time may not be accurate until lock is achieved.\n\n");    } else { -      std::cout << boost::format("ref_locked sensor not present on this board.\n"); +      std::cout << boost::format("GPS Locked");    }    //Check PPS and compare UHD device time to GPS time -  boost::this_thread::sleep(boost::posix_time::seconds(1));    uhd::sensor_value_t gps_time = usrp->get_mboard_sensor("gps_time");    uhd::time_spec_t last_pps_time = usrp->get_time_last_pps(); @@ -189,13 +205,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){    long long pps_seconds = last_pps_time.to_ticks(1.0);    if(pps_seconds != gps_seconds) { -      std::cout << boost::format("\nGPS and UHD Device time are NOT aligned;\nlast_pps: %ld vs gps: %ld. Trying to set the device time to GPS time...") -                % pps_seconds % gps_seconds +      std::cout << "\nTrying to align the device time to GPS time..."                  << std::endl; -      //full next after next second -      uhd::time_spec_t next_pps_time(gps_seconds + 2.0); -      //instruct the USRP to wait for the next PPS edge, then set the new time on the following PPS -      usrp->set_time_unknown_pps(next_pps_time); +      //set the device time to the GPS time +      //getting the GPS time returns just after the PPS edge, so just add a +      //second and set the device time at the next PPS edge +      usrp->set_time_next_pps(uhd::time_spec_t(gps_time.to_int() + 1.0));        //allow some time to make sure the PPS has come…        boost::this_thread::sleep(boost::posix_time::milliseconds(1100));        //…then ask @@ -203,14 +218,14 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){        pps_seconds = usrp->get_time_last_pps().to_ticks(1.0);    } -  std::cout << boost::format("last_pps: %ld vs gps: %ld.") -            % pps_seconds % gps_seconds -            << std::endl;    if (pps_seconds == gps_seconds) {        std::cout << boost::format("GPS and UHD Device time are aligned.\n");    } else {        std::cout << boost::format("Could not align UHD Device time to GPS time. Giving up.\n");    } +  std::cout << boost::format("last_pps: %ld vs gps: %ld.") +            % pps_seconds % gps_seconds +            << std::endl;    //print NMEA strings    try {  | 
