From 685095418bc8fd27dcd0b1d73ad1741114aeda6a Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 14 Sep 2014 00:08:53 +0200 Subject: SFN: carry FCT along with timestamps This is the first step to fix issue #6. The goal is to enable the OutputUHD to check for FCT consistency. Once it can do that, it will also be able to reset the UHD streamer if necessary. --- src/TimestampDecoder.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src/TimestampDecoder.cpp') diff --git a/src/TimestampDecoder.cpp b/src/TimestampDecoder.cpp index d6c627f..1bb4dd2 100644 --- a/src/TimestampDecoder.cpp +++ b/src/TimestampDecoder.cpp @@ -2,8 +2,10 @@ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Includes modifications for which no copyright is claimed - 2012, Matthias P. Braendli, matthias.braendli@mpb.li + Copyright (C) 2014 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://opendigitalradio.org */ /* This file is part of ODR-DabMod. @@ -45,6 +47,7 @@ void TimestampDecoder::calculateTimestamp(struct frame_timestamp& ts) ts_queued->timestamp_valid = full_timestamp_received_mnsc; ts_queued->timestamp_sec = time_secs; ts_queued->timestamp_pps_offset = time_pps; + ts_queued->fct = latestFCT; ts_queued->timestamp_refresh = offset_changed; offset_changed = false; @@ -65,6 +68,7 @@ void TimestampDecoder::calculateTimestamp(struct frame_timestamp& ts) ts.timestamp_sec = 0; ts.timestamp_pps_offset = 0; ts.timestamp_refresh = false; + ts.fct = 0; } else { //fprintf(stderr, ". %zu ", queue_timestamps.size()); @@ -179,13 +183,17 @@ void TimestampDecoder::updateTimestampPPS(double pps) } time_pps = pps; - } -void TimestampDecoder::updateTimestampEti(int framephase, uint16_t mnsc, double pps) +void TimestampDecoder::updateTimestampEti( + int framephase, + uint16_t mnsc, + double pps, + uint32_t fct) { updateTimestampPPS(pps); pushMNSCData(framephase, mnsc); + latestFCT = fct; } -- cgit v1.2.3 From 11295eabfdb514b43918b8ac45945d36f81f4bd7 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 26 Sep 2014 11:23:53 +0200 Subject: Interrupt UHD when FCT value is not contiguous --- src/EtiReader.cpp | 6 ++++-- src/OutputUHD.cpp | 35 ++++++++++++++++------------------- src/TimestampDecoder.cpp | 20 ++++++++++++++------ 3 files changed, 34 insertions(+), 27 deletions(-) (limited to 'src/TimestampDecoder.cpp') diff --git a/src/EtiReader.cpp b/src/EtiReader.cpp index f7376cc..fe54f55 100644 --- a/src/EtiReader.cpp +++ b/src/EtiReader.cpp @@ -297,11 +297,13 @@ bool EtiReader::sourceContainsTimestamp() double EtiReader::getPPSOffset() { - if (!sourceContainsTimestamp()) + if (!sourceContainsTimestamp()) { + //fprintf(stderr, "****** SOURCE NO TS\n"); return 0.0; + } uint32_t timestamp = ntohl(eti_tist.TIST) & 0xFFFFFF; - //fprintf(stderr, "TIST 0x%x\n", timestamp); + //fprintf(stderr, "****** TIST 0x%x\n", timestamp); double pps = timestamp / 16384000.0; // seconds return pps; diff --git a/src/OutputUHD.cpp b/src/OutputUHD.cpp index 927d2e6..3d8eea6 100644 --- a/src/OutputUHD.cpp +++ b/src/OutputUHD.cpp @@ -346,7 +346,10 @@ void UHDWorker::process() md.start_of_burst = false; md.end_of_burst = false; + int expected_next_fct = -1; + while (running) { + bool fct_discontinuity = false; md.has_time_spec = false; md.time_spec = uhd::time_spec_t(0.0); num_acc_samps = 0; @@ -376,19 +379,20 @@ void UHDWorker::process() sizeIn = uwd->bufsize / sizeof(complexf); -#if FAKE_UHD + /* Verify that the FCT value is correct. If we miss one transmission + * frame we must interrupt UHD and resync to the timestamps + */ if (expected_next_fct != -1) { - if (expected_next_fct != frame->ts.fct) { + if (expected_next_fct != (int)frame->ts.fct) { uwd->logger->level(warn) << "OutputUHD: Incorrect expect fct " << frame->ts.fct; - // TODO here we should disrupt the UHD streamer so that - // it resyncs to the correct timestamps + fct_discontinuity = true; } } expected_next_fct = (frame->ts.fct + uwd->fct_increment) % 250; -#else + // Check for ref_lock if (uwd->check_refclk_loss) { @@ -482,7 +486,6 @@ void UHDWorker::process() goto loopend; } } -#endif PDEBUG("UHDWorker::process:max_num_samps: %zu.\n", usrp_max_num_samps); @@ -492,8 +495,13 @@ void UHDWorker::process() //ensure the the last packet has EOB set if the timestamps has been //refreshed and need to be reconsidered. - md.end_of_burst = (frame->ts.timestamp_refresh && - (samps_to_send <= usrp_max_num_samps)); + //Also, if we saw that the FCT did not increment as expected, which + //could be due to a lost incoming packet. + md.end_of_burst = ( + uwd->sourceContainsTimestamp && + (frame->ts.timestamp_refresh || fct_discontinuity) && + samps_to_send <= usrp_max_num_samps ); + #if FAKE_UHD // This is probably very approximate @@ -586,17 +594,6 @@ void UHDWorker::process() } } #endif - - /* - bool got_async_burst_ack = false; - //loop through all messages for the ACK packet (may have underflow messages in queue) - while (not got_async_burst_ack and uwd->myUsrp->get_device()->recv_async_msg(async_md, 0.2)){ - got_async_burst_ack = (async_md.event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK); - } - //std::cerr << (got_async_burst_ack? "success" : "fail") << std::endl; - // */ - - } last_pps = pps_offset; diff --git a/src/TimestampDecoder.cpp b/src/TimestampDecoder.cpp index 1bb4dd2..96c84c0 100644 --- a/src/TimestampDecoder.cpp +++ b/src/TimestampDecoder.cpp @@ -35,7 +35,7 @@ #include "Eti.h" #include "Log.h" -//#define MDEBUG(fmt, args...) fprintf (LOG, fmt , ## args) +//#define MDEBUG(fmt, args...) fprintf (LOG, "*****" fmt , ## args) #define MDEBUG(fmt, args...) PDEBUG(fmt, ## args) @@ -52,6 +52,7 @@ void TimestampDecoder::calculateTimestamp(struct frame_timestamp& ts) ts_queued->timestamp_refresh = offset_changed; offset_changed = false; + MDEBUG("time_secs=%d, time_pps=%f\n", time_secs, time_pps); *ts_queued += timestamp_offset; queue_timestamps.push(ts_queued); @@ -90,7 +91,7 @@ void TimestampDecoder::calculateTimestamp(struct frame_timestamp& ts) delete ts_queued; } - PDEBUG("Timestamp queue size %zu, delay_calc %u\n", + MDEBUG("Timestamp queue size %zu, delay_calc %u\n", queue_timestamps.size(), modconfig.delay_calculation_pipeline_stages); @@ -157,13 +158,14 @@ void TimestampDecoder::pushMNSCData(int framephase, uint16_t mnsc) void TimestampDecoder::updateTimestampSeconds(uint32_t secs) { - MDEBUG("TimestampDecoder::updateTimestampSeconds(%d)\n", secs); if (inhibit_second_update > 0) { + MDEBUG("TimestampDecoder::updateTimestampSeconds(%d) inhibit\n", secs); inhibit_second_update--; } else { + MDEBUG("TimestampDecoder::updateTimestampSeconds(%d) apply\n", secs); time_secs = secs; } } @@ -229,13 +231,16 @@ bool TimestampDecoder::updateModulatorOffset() } catch (bad_lexical_cast& e) { - myLogger.level(error) << "Error parsing timestamp offset from file '" << modconfig.offset_filename << "'"; + myLogger.level(error) << + "Error parsing timestamp offset from file '" << + modconfig.offset_filename << "'"; r = false; } } else { - myLogger.level(error) << "Error reading from timestamp offset file: eof reached\n"; + myLogger.level(error) << + "Error reading from timestamp offset file: eof reached\n"; r = false; } filestream.close(); @@ -252,7 +257,9 @@ bool TimestampDecoder::updateModulatorOffset() if (timestamp_offset != newoffset) { timestamp_offset = newoffset; - myLogger.level(info) << "TimestampDecoder::updateTimestampOffset: new offset is " << timestamp_offset; + myLogger.level(info) << + "TimestampDecoder::updateTimestampOffset: new offset is " << + timestamp_offset; offset_changed = true; } @@ -264,3 +271,4 @@ bool TimestampDecoder::updateModulatorOffset() return false; } } + -- cgit v1.2.3