uhd: reset sample clock when time goes non-monotonic

With UHD b4fc0d61bb6cbd1a5614745bab9aeb0abc22cb6f

Sample clock will reset to zero after an overrun. Earlier
versions may hang the FPGA, which is non-recoverable,
requiring a manual image reload or reboot.

If reset to zero, attempt to kick the sample clock to the
last properly received timestamp value. At this point,
there will be a timing continuity jump, which will drop
connections, but transmit and receive chains should be
aligned allowing for re-establishment.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>

git-svn-id: http://wush.net/svn/range/software/public/openbts/trunk@2645 19bc5d8c-e614-43d4-8b26-e1612bc8e597
diff --git a/Transceiver52M/UHDDevice.cpp b/Transceiver52M/UHDDevice.cpp
index f28c175..b6b85c6 100644
--- a/Transceiver52M/UHDDevice.cpp
+++ b/Transceiver52M/UHDDevice.cpp
@@ -205,6 +205,7 @@
 
 	void init_gains();
 	void set_ref_clk(bool ext_clk);
+	void reset_clk(uhd::time_spec_t ts);
 	double set_rates(double rate);
 	bool flush_recv(size_t num_pkts);
 
@@ -386,6 +387,15 @@
 	return true;
 }
 
+void uhd_device::reset_clk(uhd::time_spec_t ts)
+{
+	double time;
+
+	usrp_dev->set_time_now(uhd::time_spec_t(ts));
+	time = usrp_dev->get_time_now().get_real_secs();
+	LOG(INFO) << "Reset USRP clock to " << time << " seconds";
+}
+
 bool uhd_device::start()
 {
 	LOG(INFO) << "Starting USRP...";
@@ -504,8 +514,10 @@
 		}
 
 		// Other metadata timing checks
-		if (check_rx_md_err(metadata, prev_ts) < 0)
+		if (check_rx_md_err(metadata, prev_ts) < 0) {
+			reset_clk(prev_ts);
 			return 0;
+		}
 
 		ts = metadata.time_spec;
 		LOG(DEEPDEBUG) << "Received timestamp = " << ts.get_real_secs();