diff options
Diffstat (limited to 'host/lib/usrp/x300')
-rw-r--r-- | host/lib/usrp/x300/x300_clock_ctrl.cpp | 11 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_impl.cpp | 67 |
2 files changed, 36 insertions, 42 deletions
diff --git a/host/lib/usrp/x300/x300_clock_ctrl.cpp b/host/lib/usrp/x300/x300_clock_ctrl.cpp index a8b30a0ab..daae5df9b 100644 --- a/host/lib/usrp/x300/x300_clock_ctrl.cpp +++ b/host/lib/usrp/x300/x300_clock_ctrl.cpp @@ -283,6 +283,7 @@ void set_master_clock_rate(double clock_rate) { _lmk04816_regs.CLKout0_1_PD = lmk04816_regs_t::CLKOUT0_1_PD_POWER_UP; this->write_regs(0); _lmk04816_regs.CLKout0_1_DIV = vco_div; + _lmk04816_regs.CLKout0_ADLY_SEL = lmk04816_regs_t::CLKOUT0_ADLY_SEL_D_EV_X; this->write_regs(0); // Register 1 @@ -294,6 +295,8 @@ void set_master_clock_rate(double clock_rate) { // Register 3 _lmk04816_regs.CLKout6_7_DIV = vco_div; _lmk04816_regs.CLKout6_7_OSCin_Sel = lmk04816_regs_t::CLKOUT6_7_OSCIN_SEL_VCO; + _lmk04816_regs.CLKout6_ADLY_SEL = lmk04816_regs_t::CLKOUT6_ADLY_SEL_D_EV_X; + _lmk04816_regs.CLKout7_ADLY_SEL = lmk04816_regs_t::CLKOUT7_ADLY_SEL_D_EV_X; // Register 4 _lmk04816_regs.CLKout8_9_DIV = vco_div; // Register 5 @@ -305,12 +308,20 @@ void set_master_clock_rate(double clock_rate) { _lmk04816_regs.CLKout1_TYPE = lmk04816_regs_t::CLKOUT1_TYPE_P_DOWN; //CPRI feedback clock, use LVDS _lmk04816_regs.CLKout2_TYPE = lmk04816_regs_t::CLKOUT2_TYPE_LVPECL_700MVPP; //DB_0_RX _lmk04816_regs.CLKout3_TYPE = lmk04816_regs_t::CLKOUT3_TYPE_LVPECL_700MVPP; //DB_1_RX + // Analog delay of 1075ps (maximum) to synchronize the radio clock with the source synchronous ADC clocks. + // This delay may need to vary due to temperature. Tested and verified at room temperature only. + _lmk04816_regs.CLKout0_1_ADLY = 0x17; + // Register 7 _lmk04816_regs.CLKout4_TYPE = lmk04816_regs_t::CLKOUT4_TYPE_LVPECL_700MVPP; //DB_1_TX _lmk04816_regs.CLKout5_TYPE = lmk04816_regs_t::CLKOUT5_TYPE_LVPECL_700MVPP; //DB_0_TX _lmk04816_regs.CLKout6_TYPE = lmk04816_regs_t::CLKOUT6_TYPE_LVPECL_700MVPP; //DB0_DAC _lmk04816_regs.CLKout7_TYPE = lmk04816_regs_t::CLKOUT7_TYPE_LVPECL_700MVPP; //DB1_DAC _lmk04816_regs.CLKout8_TYPE = lmk04816_regs_t::CLKOUT8_TYPE_LVPECL_700MVPP; //DB0_ADC + // Analog delay of 1075ps (maximum) to synchronize the DAC reference clocks with the source synchronous DAC clocks. + // This delay may need to vary due to temperature. Tested and verified at room temperature only. + _lmk04816_regs.CLKout6_7_ADLY = 0x17; + // Register 8 _lmk04816_regs.CLKout9_TYPE = lmk04816_regs_t::CLKOUT9_TYPE_LVPECL_700MVPP; //DB1_ADC _lmk04816_regs.CLKout10_TYPE = lmk04816_regs_t::CLKOUT10_TYPE_LVDS; //REF_CLKOUT diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index 3561bc2f1..1b651065d 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -809,45 +809,32 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) _tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(tx_fe_spec); UHD_MSG(status) << "Initializing clock and PPS references..." << std::endl; - try { - //First, try external source - _tree->access<std::string>(mb_path / "clock_source" / "value").set("external"); - wait_for_ref_locked(mb.zpu_ctrl, 1.0); - _tree->access<std::string>(mb_path / "time_source" / "value").set("external"); - UHD_MSG(status) << "References initialized to external sources" << std::endl; - } catch (uhd::exception::runtime_error &e) { - //No external source detected - set to the GPSDO if installed - if (mb.gps and mb.gps->gps_detected()) - { - _tree->access<std::string>(mb_path / "clock_source" / "value").set("gpsdo"); - try { - wait_for_ref_locked(mb.zpu_ctrl, 1.0); - } catch (uhd::exception::runtime_error &e) { - UHD_MSG(warning) << "Clock reference failed to lock to GPSDO during device initialization. " << - "Check for the lock before operation or ignore this warning if using another clock source." << std::endl; - } - _tree->access<std::string>(mb_path / "time_source" / "value").set("gpsdo"); - UHD_MSG(status) << "References initialized to GPSDO sources" << std::endl; - UHD_MSG(status) << "Initializing time to the GPSDO time" << std::endl; - const time_t tp = time_t(mb.gps->get_sensor("gps_time").to_int()+1); - _tree->access<time_spec_t>(mb_path / "time" / "pps").set(time_spec_t(tp)); - - //wait for next PPS edge (timeout after 1 second) - time_spec_t pps_time = _tree->access<time_spec_t>(mb_path / "time" / "pps").get(); - for (size_t i = 0; i < 10 && _tree->access<time_spec_t>(mb_path / "time" / "pps").get() == pps_time; i++) - boost::this_thread::sleep(boost::posix_time::milliseconds(100)); - } else { - _tree->access<std::string>(mb_path / "clock_source" / "value").set("internal"); - try { - wait_for_ref_locked(mb.zpu_ctrl, 1.0); - } catch (uhd::exception::runtime_error &e) { - // Ignore for now - It can sometimes take longer than 1 second to lock and that is OK. - //UHD_MSG(warning) << "Clock reference failed to lock to internal source during device initialization. " << - // "Check for the lock before operation or ignore this warning if using another clock source." << std::endl; - } - _tree->access<std::string>(mb_path / "time_source" / "value").set("internal"); - UHD_MSG(status) << "References initialized to internal sources" << std::endl; + //Set to the GPSDO if installed + if (mb.gps and mb.gps->gps_detected()) + { + _tree->access<std::string>(mb_path / "clock_source" / "value").set("gpsdo"); + try { + wait_for_ref_locked(mb.zpu_ctrl, 1.0); + } catch (uhd::exception::runtime_error &e) { + UHD_MSG(warning) << "Clock reference failed to lock to GPSDO during device initialization. " << + "Check for the lock before operation or ignore this warning if using another clock source." << std::endl; + } + _tree->access<std::string>(mb_path / "time_source" / "value").set("gpsdo"); + UHD_MSG(status) << "References initialized to GPSDO sources" << std::endl; + UHD_MSG(status) << "Initializing time to the GPSDO time" << std::endl; + const time_t tp = time_t(mb.gps->get_sensor("gps_time").to_int()+1); + _tree->access<time_spec_t>(mb_path / "time" / "pps").set(time_spec_t(tp)); + } else { + _tree->access<std::string>(mb_path / "clock_source" / "value").set("internal"); + try { + wait_for_ref_locked(mb.zpu_ctrl, 1.0); + } catch (uhd::exception::runtime_error &e) { + // Ignore for now - It can sometimes take longer than 1 second to lock and that is OK. + //UHD_MSG(warning) << "Clock reference failed to lock to internal source during device initialization. " << + // "Check for the lock before operation or ignore this warning if using another clock source." << std::endl; } + _tree->access<std::string>(mb_path / "time_source" / "value").set("internal"); + UHD_MSG(status) << "References initialized to internal sources" << std::endl; } } @@ -1395,10 +1382,6 @@ void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &sou this->update_clock_control(mb); - //reset the clock control - //without this, the lock time is long and can be as much as 30 seconds - mb.clock->reset_clocks(); - /* FIXME: implement when we know the correct timeouts * //wait for lock * double timeout = 1.0; |