aboutsummaryrefslogtreecommitdiffstats
path: root/src/output/USRPTime.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/output/USRPTime.cpp')
-rw-r--r--src/output/USRPTime.cpp183
1 files changed, 98 insertions, 85 deletions
diff --git a/src/output/USRPTime.cpp b/src/output/USRPTime.cpp
index 39b0e5a..232fa58 100644
--- a/src/output/USRPTime.cpp
+++ b/src/output/USRPTime.cpp
@@ -39,64 +39,6 @@ namespace Output {
using namespace std;
-
-// Check function for GPS TIMELOCK sensor from the ODR LEA-M8F board GPSDO
-static bool check_gps_timelock(uhd::usrp::multi_usrp::sptr& usrp)
-{
- try {
- const string sensor_value =
- usrp->get_mboard_sensor("gps_timelock", 0).to_pp_string();
-
- if (sensor_value.find("TIME LOCKED") == string::npos) {
-
- const string gngga =
- usrp->get_mboard_sensor("gps_gngga", 0).to_pp_string();
-
- std::stringstream ss(gngga);
- std::string item;
- std::vector<std::string> elems;
- while (std::getline(ss, item, ',')) {
- elems.push_back(item);
- }
-
- const auto num_svs = (elems.size() >= 7) ? elems[7] : "?";
-
- etiLog.level(info) << "OutputUHD: " << num_svs << " SVs,"
- " gps_timelock " << sensor_value;
- return false;
- }
-
- return true;
- }
- catch (const uhd::exception &e) {
- etiLog.level(warn) << "OutputUHD: no gps_timelock sensor: " <<
- e.what();
- return false;
- }
-}
-
-// Check function for GPS LOCKED sensor from the Ettus GPSDO
-static bool check_gps_locked(uhd::usrp::multi_usrp::sptr& usrp)
-{
- try {
- const uhd::sensor_value_t sensor_value(
- usrp->get_mboard_sensor("gps_locked", 0));
- if (not sensor_value.to_bool()) {
- etiLog.level(warn) << "OutputUHD: gps_locked " <<
- sensor_value.to_pp_string();
- return false;
- }
-
- return true;
- }
- catch (const uhd::exception &e) {
- etiLog.level(warn) << "OutputUHD: no gps_locked sensor" <<
- e.what();
- return false;
- }
-}
-
-
USRPTime::USRPTime(
uhd::usrp::multi_usrp::sptr usrp,
SDRDeviceConfig& conf) :
@@ -104,26 +46,6 @@ USRPTime::USRPTime(
m_conf(conf),
time_last_check(timepoint_t::clock::now())
{
-
- if (m_conf.pps_src == "gpsdo") {
- using namespace std::chrono;
- auto now = system_clock::now();
- auto expiry = now + seconds(m_conf.maxGPSHoldoverTime);
- auto checkfunc = gpsdo_is_ettus() ? check_gps_locked : check_gps_timelock;
- while (now < expiry) {
- if (checkfunc(m_usrp)) {
- break;
- }
-
- now = system_clock::now();
- this_thread::sleep_for(seconds(2));
- }
-
- if (not checkfunc(m_usrp)) {
- throw runtime_error("GPSDO did not lock during startup");
- }
- }
-
if (m_conf.pps_src == "none") {
if (m_conf.enableSync) {
etiLog.level(warn) <<
@@ -133,8 +55,18 @@ USRPTime::USRPTime(
set_usrp_time_from_localtime();
}
- else if (m_conf.pps_src == "pps" or m_conf.pps_src == "gpsdo") {
- set_usrp_time_from_pps();
+ else if (m_conf.pps_src == "pps") {
+ // let verify_time handle time setup
+ }
+ else if (m_conf.pps_src == "gpsdo") {
+ if (gpsdo_is_ettus() ? check_gps_locked() : check_gps_timelock()) {
+ set_usrp_time_from_pps();
+ gps_state = gps_state_e::monitor_fix;
+ num_checks_without_gps_fix = 0;
+ }
+ else {
+ // let verify_time handle time setup
+ }
}
else {
throw std::runtime_error("USRPTime not implemented yet: " +
@@ -193,6 +125,11 @@ bool USRPTime::verify_time()
throw logic_error("End of USRPTime::verify_time() reached");
}
+gnss_stats_t USRPTime::get_gnss_stats(void) const
+{
+ return gnss_stats;
+}
+
void USRPTime::check_gps()
{
timepoint_t time_now = timepoint_t::clock::now();
@@ -224,11 +161,11 @@ void USRPTime::check_gps()
// time, it has to be done in a separate thread.
if (gpsdo_is_ettus()) {
gps_fix_future = std::async(std::launch::async,
- std::bind(check_gps_locked, m_usrp) );
+ std::bind(&USRPTime::check_gps_locked, this) );
}
else {
gps_fix_future = std::async(std::launch::async,
- std::bind(check_gps_timelock, m_usrp) );
+ std::bind(&USRPTime::check_gps_timelock, this) );
}
}
}
@@ -239,11 +176,15 @@ bool USRPTime::gpsfix_needs_check() const
if (m_conf.refclk_src == "internal") {
return false;
}
- else if (m_conf.refclk_src == "gpsdo") {
+ else if (gps_state == gps_state_e::monitor_fix and
+ (m_conf.refclk_src == "gpsdo" or
+ m_conf.refclk_src == "gpsdo-ettus")) {
return (m_conf.maxGPSHoldoverTime != 0);
}
- else if (m_conf.refclk_src == "gpsdo-ettus") {
- return (m_conf.maxGPSHoldoverTime != 0);
+ else if (gps_state == gps_state_e::bootup and
+ (m_conf.refclk_src == "gpsdo" or
+ m_conf.refclk_src == "gpsdo-ettus")) {
+ return true;
}
else {
return false;
@@ -308,6 +249,78 @@ void USRPTime::set_usrp_time_from_pps()
}
}
+
+// Check functionality of GPS sensors applicable to the ODR LEA-M8F board GPSDO
+bool USRPTime::check_gps_timelock()
+{
+ bool locked = false;
+
+ try {
+ const string sensor_value =
+ m_usrp->get_mboard_sensor("gps_timelock", 0).to_pp_string();
+
+ const string gngga =
+ m_usrp->get_mboard_sensor("gps_gngga", 0).to_pp_string();
+
+ std::stringstream ss(gngga);
+ std::string item;
+ std::vector<std::string> elems;
+ while (std::getline(ss, item, ',')) {
+ elems.push_back(item);
+ }
+
+ const auto num_svs = (elems.size() > 7) ? elems[7] : "0";
+ gnss_stats.num_sv = std::stoi(num_svs);
+
+ locked = (sensor_value.find("TIME LOCKED") != string::npos);
+ }
+ catch (const uhd::exception &e) {
+ etiLog.level(warn) << "OutputUHD: no gps_timelock sensor: " <<
+ e.what();
+ }
+
+ // LEA-M8F-patched UHD 3.12.0 has this additional sensor, that can
+ // be used to distinguish holdover operation. Previous versions
+ // did a config reset at startup to ensure we would not startup while
+ // in holdover.
+ try {
+ const string disc_src =
+ m_usrp->get_mboard_sensor("gps_discsrc", 0).to_pp_string();
+
+ locked &= (disc_src.find("gnss") != string::npos);
+ }
+ catch (const uhd::exception &e) {
+ etiLog.level(warn) << "OutputUHD: no gps_timelock sensor: " <<
+ e.what();
+ }
+
+ gnss_stats.holdover = not locked;
+
+ return locked;
+}
+
+// Check function for GPS LOCKED sensor from the Ettus GPSDO
+bool USRPTime::check_gps_locked()
+{
+ try {
+ const uhd::sensor_value_t sensor_value(
+ m_usrp->get_mboard_sensor("gps_locked", 0));
+ if (not sensor_value.to_bool()) {
+ etiLog.level(warn) << "OutputUHD: gps_locked " <<
+ sensor_value.to_pp_string();
+ return false;
+ }
+
+ return true;
+ }
+ catch (const uhd::exception &e) {
+ etiLog.level(warn) << "OutputUHD: no gps_locked sensor" <<
+ e.what();
+ return false;
+ }
+}
+
+
} // namespace Output
#endif // HAVE_OUTPUT_UHD