From 42a54a01a037451c5a32f9b02a8c7519d466a09c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 9 Oct 2025 16:38:38 +0200 Subject: [PATCH] USRP: move time/clock source setting to later Doing this before using set_master_clock_rate() on the B200 seems to invalidate synchronization setting. [HW] USRP clock set to 1759836386.000000 sec [...] [HW] current pps at 3.286750, starting streaming at 4.286750 In other words, the current time setting was reset. With this change now, we see [HW] USRP clock set to 1759929873.000000 sec [...] [HW] current pps at 1759929873.000000, starting streaming at 1759929874.000000 This is because changing clock sources (I assume setting the master clock rate impacts the clock) can result in changing the time. From the documentation of [1]: > Note: When changing clock sources, a previously set time will most > likely be lost. It is recommended to set the time after changing the > clock source. Otherwise, an unexpected time may line up with future PPS > edges. [1] https://files.ettus.com/manual/classuhd_1_1usrp_1_1multi__usrp.html#a99254abfa5259b70a020e667eee619b9 --- radio/USRP/usrp_lib.cpp | 139 ++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 75 deletions(-) diff --git a/radio/USRP/usrp_lib.cpp b/radio/USRP/usrp_lib.cpp index 6dde70b2eb..79c58b59f4 100644 --- a/radio/USRP/usrp_lib.cpp +++ b/radio/USRP/usrp_lib.cpp @@ -1161,79 +1161,6 @@ extern "C" { s->usrp = uhd::usrp::multi_usrp::make(args); - if (args.find("clock_source")==std::string::npos) { - if (openair0_cfg[0].clock_source == internal) { - s->usrp->set_clock_source("internal"); - LOG_I(HW,"Setting clock source to internal\n"); - } - else if (openair0_cfg[0].clock_source == external ) { - s->usrp->set_clock_source("external"); - LOG_I(HW,"Setting clock source to external\n"); - } - else if (openair0_cfg[0].clock_source==gpsdo) { - s->usrp->set_clock_source("gpsdo"); - LOG_I(HW,"Setting clock source to gpsdo\n"); - } - else { - LOG_W(HW,"Clock source set neither in usrp_args nor on command line, using default!\n"); - } - } - else { - if (openair0_cfg[0].clock_source != unset) { - LOG_W(HW,"Clock source set in both usrp_args and in clock_source, ingnoring the latter!\n"); - } - } - - if (args.find("time_source")==std::string::npos) { - if (openair0_cfg[0].time_source == internal) { - s->usrp->set_time_source("internal"); - LOG_I(HW,"Setting time source to internal\n"); - } - else if (openair0_cfg[0].time_source == external ) { - s->usrp->set_time_source("external"); - LOG_I(HW,"Setting time source to external\n"); - } - else if (openair0_cfg[0].time_source==gpsdo) { - s->usrp->set_time_source("gpsdo"); - LOG_I(HW,"Setting time source to gpsdo\n"); - } - else { - LOG_W(HW,"Time source set neither in usrp_args nor on command line, using default!\n"); - } - } - else { - if (openair0_cfg[0].time_source != unset) { - LOG_W(HW, "Time source set in both usrp_args and in openair0_cfg[0].time_source, ignoring the latter!\n"); - } - } - - - if (s->usrp->get_clock_source(0) == "gpsdo") { - s->use_gps = 1; - - if (sync_to_gps(device)==EXIT_SUCCESS) { - LOG_I(HW,"USRP synced with GPS!\n"); - } else { - LOG_I(HW,"USRP fails to sync with GPS. Exiting.\n"); - exit(EXIT_FAILURE); - } - } else { - if (s->usrp->get_time_source(0) == "external") { - usrp_sync_pps(s); - } else { - s->usrp->set_time_next_pps(uhd::time_spec_t(0.0)); - } - - if (s->usrp->get_clock_source(0) == "external") { - if (check_ref_locked(s,0)) { - LOG_I(HW,"USRP locked to external reference!\n"); - } else { - LOG_I(HW,"Failed to lock to external reference. Exiting.\n"); - exit(EXIT_FAILURE); - } - } - } - if (device->type==USRP_X300_DEV) { openair0_cfg[0].rx_gain_calib_table = calib_table_x310; std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; @@ -1470,8 +1397,70 @@ extern "C" { } } - //s->usrp->set_clock_source("external"); - //s->usrp->set_time_source("external"); + if (args.find("clock_source") == std::string::npos) { + if (openair0_cfg[0].clock_source == internal) { + s->usrp->set_clock_source("internal"); + LOG_I(HW, "Setting clock source to internal\n"); + } else if (openair0_cfg[0].clock_source == external) { + s->usrp->set_clock_source("external"); + LOG_I(HW, "Setting clock source to external\n"); + } else if (openair0_cfg[0].clock_source == gpsdo) { + s->usrp->set_clock_source("gpsdo"); + LOG_I(HW, "Setting clock source to gpsdo\n"); + } else { + LOG_W(HW, "Clock source set neither in usrp_args nor on command line, using default!\n"); + } + } else { + if (openair0_cfg[0].clock_source != unset) { + LOG_W(HW, "Clock source set in both usrp_args and in clock_source, ingnoring the latter!\n"); + } + } + + if (args.find("time_source") == std::string::npos) { + if (openair0_cfg[0].time_source == internal) { + s->usrp->set_time_source("internal"); + LOG_I(HW, "Setting time source to internal\n"); + } else if (openair0_cfg[0].time_source == external) { + s->usrp->set_time_source("external"); + LOG_I(HW, "Setting time source to external\n"); + } else if (openair0_cfg[0].time_source == gpsdo) { + s->usrp->set_time_source("gpsdo"); + LOG_I(HW, "Setting time source to gpsdo\n"); + } else { + LOG_W(HW, "Time source set neither in usrp_args nor on command line, using default!\n"); + } + } else { + if (openair0_cfg[0].time_source != unset) { + LOG_W(HW, "Time source set in both usrp_args and in openair0_cfg[0].time_source, ignoring the latter!\n"); + } + } + + if (s->usrp->get_clock_source(0) == "gpsdo") { + s->use_gps = 1; + + if (sync_to_gps(device) == EXIT_SUCCESS) { + LOG_I(HW, "USRP synced with GPS!\n"); + } else { + LOG_I(HW, "USRP fails to sync with GPS. Exiting.\n"); + exit(EXIT_FAILURE); + } + } else { + if (s->usrp->get_time_source(0) == "external") { + usrp_sync_pps(s); + } else { + s->usrp->set_time_next_pps(uhd::time_spec_t(0.0)); + } + + if (s->usrp->get_clock_source(0) == "external") { + if (check_ref_locked(s, 0)) { + LOG_I(HW, "USRP locked to external reference!\n"); + } else { + LOG_I(HW, "Failed to lock to external reference. Exiting.\n"); + exit(EXIT_FAILURE); + } + } + } + // display USRP settings LOG_I(HW,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6); LOG_I(HW,"Actual clock source %s...\n",s->usrp->get_clock_source(0).c_str());