aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2015-07-03 13:47:53 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2015-12-18 09:01:08 +0100
commit4bf59cbe53a889a9b45dfb313e4afaab75b578d5 (patch)
treea79ff9434fa0226127d8ff1f43e8880f91938534
parent0efe90f8881d89008f56b920aa24e329d1d589ad (diff)
downloaduhd-4bf59cbe53a889a9b45dfb313e4afaab75b578d5.tar.gz
uhd-4bf59cbe53a889a9b45dfb313e4afaab75b578d5.tar.bz2
uhd-4bf59cbe53a889a9b45dfb313e4afaab75b578d5.zip
Use TIM-TOS instead of NAV-SOL to determine time lock
-rw-r--r--host/lib/usrp/b200/b200_impl.cpp6
-rw-r--r--host/lib/usrp/gps_ctrl.cpp140
2 files changed, 85 insertions, 61 deletions
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
index 3da402f13..ad357ff6a 100644
--- a/host/lib/usrp/b200/b200_impl.cpp
+++ b/host/lib/usrp/b200/b200_impl.cpp
@@ -719,9 +719,9 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s
_tree->access<std::string>(mb_path / "clock_source" / "value").set("gpsdo");
if (not _gps->gps_detected_lea_m8f()) {
- UHD_MSG(status) << "Initializing time to the internal GPSDO" << std::endl;
- const time_t tp = time_t(_gps->get_sensor("gps_time").to_int()+1);
- _tree->access<time_spec_t>(mb_path / "time" / "pps").set(time_spec_t(tp));
+ UHD_MSG(status) << "Initializing time to the internal GPSDO" << std::endl;
+ const time_t tp = time_t(_gps->get_sensor("gps_time").to_int()+1);
+ _tree->access<time_spec_t>(mb_path / "time" / "pps").set(time_spec_t(tp));
}
}
diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp
index 5f45e7298..8a7b79ba6 100644
--- a/host/lib/usrp/gps_ctrl.cpp
+++ b/host/lib/usrp/gps_ctrl.cpp
@@ -255,12 +255,10 @@ private:
return std::string();
}
else if (gps_detected() && gps_type == GPS_TYPE_LEA_M8F) {
- const std::list<std::string> list = boost::assign::list_of("GNGGA")("GNRMC")("FIXTYPE");
+ const std::list<std::string> list = boost::assign::list_of("GNGGA")("GNRMC")("TIMELOCK");
// Concatenate all incoming data into the deque
- for (std::string msg = _recv();
- msg.length() > 0 && gps_parser.size() < (2*115200);
- msg = _recv())
+ for (std::string msg = _recv(); msg.length() > 0; msg = _recv())
{
gps_parser.push_data(msg.begin(), msg.end());
}
@@ -272,48 +270,63 @@ private:
for (std::string msg = gps_parser.get_next_message(); not msg.empty(); msg = gps_parser.get_next_message())
{
/*
- std::stringstream ss;
- ss << "Got message ";
- for (size_t m = 0; m < msg.size(); m++) {
- ss << std::hex << (unsigned int)(unsigned char)msg[m] << " " << std::dec;
+ if (msg[0] != '$') {
+ std::stringstream ss;
+ ss << "Got message ";
+ for (size_t m = 0; m < msg.size(); m++) {
+ ss << std::hex << (unsigned int)(unsigned char)msg[m] << " " << std::dec;
+ }
+ UHD_MSG(warning) << ss.str() << ":" << std::endl;
}
- UHD_MSG(warning) << ss.str() << ":" << std::endl << msg << std::endl;
- */
-
- // Get UBX-NAV-SOL
- const uint8_t nav_sol_head[4] = {0xb5, 0x62, 0x01, 0x06};
- const std::string nav_sol_head_str(reinterpret_cast<const char *>(nav_sol_head), 4);
- if (msg.find(nav_sol_head_str) == 0 and msg.length() == 52 + 8) {
- uint8_t gpsFix = msg[6 + 10]; // header size == 6, field offset == 10
-
- std::string fixtype;
+ // */
- if (gpsFix == 0) {
- fixtype = "no fix";
- }
- else if (gpsFix == 1) {
- fixtype = "dead reckoning";
- }
- else if (gpsFix == 2) {
- fixtype = "2d fix";
- }
- else if (gpsFix == 3) {
- fixtype = "3d fix";
- }
- else if (gpsFix == 4) {
- fixtype = "combined fix";
- }
- else if (gpsFix == 5) {
- fixtype = "time-only fix";
- }
+ const uint8_t tim_tos_head[4] = {0xb5, 0x62, 0x0D, 0x12};
+ const std::string tim_tos_head_str(reinterpret_cast<const char *>(tim_tos_head), 4);
- if (not fixtype.empty()) {
- msgs["FIXTYPE"] = fixtype;
- }
- }
- else if (msg[0] == '$') {
+ // Try to get NMEA first
+ if (msg[0] == '$') {
msgs[msg.substr(1,5)] = msg;
}
+ else if (msg.find(tim_tos_head_str) == 0 and msg.length() == 56 + 8) {
+ // header size == 6, field offset == 4, 32-bit field
+ uint8_t flags1 = msg[6 + 4];
+ uint8_t flags2 = msg[6 + 5];
+ uint8_t flags3 = msg[6 + 5];
+ uint8_t flags4 = msg[6 + 5];
+
+ uint32_t flags = flags1 | (flags2 << 8) | (flags3 << 16) | (flags4 << 24);
+ /* bits in flags are:
+ leapNow 0
+ leapSoon 1
+ leapPositive 2
+ timeInLimit 3
+ intOscInLimit 4
+ extOscInLimit 5
+ gnssTimeValid 6
+ UTCTimeValid 7
+ DiscSrc 10
+ raim 11
+ cohPulse 12
+ lockedPulse 13
+ */
+
+ bool lockedPulse = (flags & (1 << 13));
+ bool timeInLimit = (flags & (1 << 3));
+ bool intOscInLimit = (flags & (1 << 4));
+
+ if (lockedPulse and timeInLimit and intOscInLimit) {
+ msgs["TIMELOCK"] = "TIME LOCKED";
+ }
+ else {
+ std::stringstream ss;
+ ss <<
+ (lockedPulse ? "" : "no" ) << "lockedPulse " <<
+ (timeInLimit ? "" : "no" ) << "timeInLimit " <<
+ (intOscInLimit ? "" : "no" ) << "intOscInLimit ";
+
+ msgs["TIMELOCK"] = ss.str();
+ }
+ }
else if (msg[0] == '\xb5' and msg[1] == '\x62') { /* Ignore unsupported UBX message */ }
else {
std::stringstream ss;
@@ -428,7 +441,7 @@ public:
("gps_time")
("gps_locked")
("gps_servo")
- ("gps_fixtype");
+ ("gps_timelock");
return ret;
}
@@ -437,7 +450,7 @@ public:
or key == "gps_gprmc"
or key == "gps_gngga"
or key == "gps_gnrmc"
- or key == "gps_fixtype" ) {
+ or key == "gps_timelock" ) {
return sensor_value_t(
boost::to_upper_copy(key),
get_cached_sensor(boost::to_upper_copy(key.substr(4,8)), GPS_NMEA_NORMAL_FRESHNESS, false, false),
@@ -478,9 +491,16 @@ private:
}
void init_lea_m8f(void) {
- // Enable the UBX-NAV-SOL and the $GNRMC messages
- const uint8_t en_nav_sol[11] = {0xb5, 0x62, 0x06, 0x01, 0x03, 0x00, 0x01, 0x06, 0x01, 0x12, 0x4f};
- _send(std::string(reinterpret_cast<const char *>(en_nav_sol), sizeof(en_nav_sol)));
+ // Send a GNSS-only hotstart to make sure we're not in holdover right now
+ const uint8_t cfg_rst_hotstart[12] = {0xb5, 0x62, 0x06, 0x04, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x68};
+ _send(std::string(reinterpret_cast<const char *>(cfg_rst_hotstart), sizeof(cfg_rst_hotstart)));
+
+ // Give time to module to reboot
+ sleep(milliseconds(2000));
+
+ // Enable the UBX-TIM-TOS and the $GNRMC messages
+ const uint8_t en_tim_tos[11] = {0xb5, 0x62, 0x06, 0x01, 0x03, 0x00, 0x0d, 0x12, 0x01, 0x2a, 0x8b};
+ _send(std::string(reinterpret_cast<const char *>(en_tim_tos), sizeof(en_tim_tos)));
const uint8_t en_gnrmc[11] = {0xb5, 0x62, 0x06, 0x01, 0x03, 0x00, 0xf0, 0x04, 0x01, 0xff, 0x18};
_send(std::string(reinterpret_cast<const char *>(en_gnrmc), sizeof(en_gnrmc)));
@@ -522,9 +542,11 @@ private:
ptime get_time(void) {
_flush();
int error_cnt = 0;
+ const int GPS_TIMEVALID_TIMEOUT_MS = 60000;
ptime gps_time;
- while(error_cnt < 2) {
- try {
+ const boost::system_time valid_time_timeout = boost::get_system_time() + milliseconds(GPS_TIMEVALID_TIMEOUT_MS);
+ try {
+ while(boost::get_system_time() < valid_time_timeout) {
std::string reply;
if (gps_type == GPS_TYPE_LEA_M8F) {
reply = get_nmea("GNRMC");
@@ -536,8 +558,9 @@ private:
std::string datestr = get_token(reply, 9);
std::string timestr = get_token(reply, 1);
- if(datestr.size() == 0 or timestr.size() == 0) {
- throw uhd::value_error(str(boost::format("Invalid response \"%s\"") % reply));
+ if (datestr.size() == 0 or timestr.size() == 0) {
+ error_cnt++;
+ continue;
}
//just trust me on this one
@@ -550,14 +573,15 @@ private:
+ minutes(boost::lexical_cast<int>(timestr.substr(2, 2)))
+ seconds(boost::lexical_cast<int>(timestr.substr(4, 2)))
);
+ UHD_MSG(warning) << "get_time ok: " << error_cnt << std::endl;
return gps_time;
- } catch(std::exception &e) {
- UHD_MSG(warning) << "get_time: " << e.what() << std::endl;
- _flush();
- error_cnt++;
}
+ } catch(std::exception &e) {
+ UHD_MSG(error) << "get_time: " << e.what() << std::endl;
+ _flush();
}
+ UHD_MSG(warning) << "get_time err: " << error_cnt << std::endl;
throw uhd::value_error("Timeout after no valid message found");
return gps_time; //keep gcc from complaining
@@ -581,9 +605,9 @@ private:
try {
std::string reply;
if (gps_type == GPS_TYPE_LEA_M8F) {
- reply = get_cached_sensor("FIXTYPE", GPS_LOCK_FRESHNESS, false, false);
- UHD_MSG(warning) << "FIXTYPE is " << reply << std::endl;
- return reply == "3d fix";
+ reply = get_cached_sensor("TIMELOCK", GPS_LOCK_FRESHNESS, false, false);
+ UHD_MSG(warning) << "TIMELOCK is " << reply << std::endl;
+ return reply == "locked";
}
else {
reply = get_cached_sensor("GPGGA", GPS_LOCK_FRESHNESS, false, false);
@@ -650,7 +674,7 @@ private:
static const int GPS_NMEA_LOW_FRESHNESS = 2500;
static const int GPS_NMEA_NORMAL_FRESHNESS = 1000;
static const int GPS_SERVO_FRESHNESS = 2500;
- static const int GPS_LOCK_FRESHNESS = 2500;
+ static const int GPS_LOCK_FRESHNESS = 200;
static const int GPS_TIMEOUT_DELAY_MS = 200;
static const int GPSDO_COMMAND_DELAY_MS = 200;
};