diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2014-09-14 00:08:53 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2014-09-14 00:08:53 +0200 |
commit | 685095418bc8fd27dcd0b1d73ad1741114aeda6a (patch) | |
tree | 5d959800a98b294cdc08278c8eaf181730190e07 /src | |
parent | 0b7bc4a405ea4d6f24fade9420e9919420c64d8e (diff) | |
download | dabmod-685095418bc8fd27dcd0b1d73ad1741114aeda6a.tar.gz dabmod-685095418bc8fd27dcd0b1d73ad1741114aeda6a.tar.bz2 dabmod-685095418bc8fd27dcd0b1d73ad1741114aeda6a.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/EtiReader.cpp | 19 | ||||
-rw-r--r-- | src/EtiReader.h | 9 | ||||
-rw-r--r-- | src/InputZeroMQReader.cpp | 4 | ||||
-rw-r--r-- | src/OutputUHD.cpp | 56 | ||||
-rw-r--r-- | src/OutputUHD.h | 14 | ||||
-rw-r--r-- | src/TimestampDecoder.cpp | 16 | ||||
-rw-r--r-- | src/TimestampDecoder.h | 22 |
7 files changed, 100 insertions, 40 deletions
diff --git a/src/EtiReader.cpp b/src/EtiReader.cpp index b61481c..f7376cc 100644 --- a/src/EtiReader.cpp +++ b/src/EtiReader.cpp @@ -2,8 +2,10 @@ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 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. @@ -269,18 +271,17 @@ int EtiReader::process(Buffer* dataIn) } break; default: - // throw std::runtime_error("Invalid state!"); + // throw std::runtime_error("Invalid state!"); PDEBUG("Invalid state (%i)!", state); input_size = 0; } } - + // Update timestamps myTimestampDecoder.updateTimestampEti(eti_fc.FP & 0x3, - eti_eoh.MNSC, - getPPSOffset()); + eti_eoh.MNSC, getPPSOffset(), eti_fc.FCT); - if (getFCT() % 125 == 0) //every 3 seconds is fine enough + if (eti_fc.FCT % 125 == 0) //every 3 seconds is fine enough { myTimestampDecoder.updateModulatorOffset(); } @@ -306,7 +307,3 @@ double EtiReader::getPPSOffset() return pps; } -uint32_t EtiReader::getFCT() -{ - return eti_fc.FCT; -} diff --git a/src/EtiReader.h b/src/EtiReader.h index be12075..209b208 100644 --- a/src/EtiReader.h +++ b/src/EtiReader.h @@ -2,8 +2,10 @@ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 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. @@ -60,9 +62,6 @@ public: myTimestampDecoder.calculateTimestamp(ts); } - /* Return the frame counter */ - uint32_t getFCT(); - /* Returns true if we have valid time stamps in the ETI*/ bool sourceContainsTimestamp(); diff --git a/src/InputZeroMQReader.cpp b/src/InputZeroMQReader.cpp index cf3f7aa..cfb56b2 100644 --- a/src/InputZeroMQReader.cpp +++ b/src/InputZeroMQReader.cpp @@ -3,8 +3,10 @@ Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyrigth (C) 2013, 2014 + Copyright (C) 2013, 2014 Matthias P. Braendli, matthias.braendli@mpb.li + + http://opendigitalradio.org */ /* This file is part of ODR-DabMod. diff --git a/src/OutputUHD.cpp b/src/OutputUHD.cpp index b44cd3f..927d2e6 100644 --- a/src/OutputUHD.cpp +++ b/src/OutputUHD.cpp @@ -58,6 +58,9 @@ OutputUHD::OutputUHD( { myMuting = 0; // is remote-controllable +#if FAKE_UHD + MDEBUG("OutputUHD:Using fake UHD output"); +#else std::stringstream device; device << myConf.device; @@ -198,6 +201,7 @@ OutputUHD::OutputUHD( // preparing output thread worker data uwd.myUsrp = myUsrp; +#endif uwd.frame0.ts.timestamp_valid = false; uwd.frame1.ts.timestamp_valid = false; @@ -257,7 +261,15 @@ int OutputUHD::process(Buffer* dataIn, Buffer* dataOut) myEtiReader->calculateTimestamp(ts); uwd.frame0.ts = ts; - uwd.frame0.fct = myEtiReader->getFCT(); + + switch (myEtiReader->getMode()) { + case 1: uwd.fct_increment = 4; break; + case 2: + case 3: uwd.fct_increment = 1; break; + case 4: uwd.fct_increment = 2; break; + default: break; + } + activebuffer = 1; @@ -287,13 +299,11 @@ int OutputUHD::process(Buffer* dataIn, Buffer* dataOut) memcpy(uwd.frame0.buf, dataIn->getData(), uwd.bufsize); uwd.frame0.ts = ts; - uwd.frame0.fct = myEtiReader->getFCT(); } else if (activebuffer == 1) { memcpy(uwd.frame1.buf, dataIn->getData(), uwd.bufsize); uwd.frame1.ts = ts; - uwd.frame1.fct = myEtiReader->getFCT(); } activebuffer = (activebuffer + 1) % 2; @@ -322,9 +332,13 @@ void UHDWorker::process() // Transmit timeout const double timeout = 0.2; +#if FAKE_UHD == 0 uhd::stream_args_t stream_args("fc32"); //complex floats uhd::tx_streamer::sptr myTxStream = uwd->myUsrp->get_tx_stream(stream_args); size_t usrp_max_num_samps = myTxStream->get_max_num_samps(); +#else + size_t usrp_max_num_samps = 2048; // arbitrarily chosen +#endif const complexf* in; @@ -362,6 +376,19 @@ void UHDWorker::process() sizeIn = uwd->bufsize / sizeof(complexf); +#if FAKE_UHD + if (expected_next_fct != -1) { + if (expected_next_fct != 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 + } + } + + expected_next_fct = (frame->ts.fct + uwd->fct_increment) % 250; +#else // Check for ref_lock if (uwd->check_refclk_loss) { @@ -392,7 +419,7 @@ void UHDWorker::process() * MNSC. We sleep through the frame. */ uwd->logger->level(info) << - "OutputUHD: Throwing sample " << frame->fct << + "OutputUHD: Throwing sample " << frame->ts.fct << " away: incomplete timestamp " << tx_second << " + " << pps_offset; usleep(20000); //TODO should this be TM-dependant ? @@ -408,7 +435,7 @@ void UHDWorker::process() "OutputUHD: Timestamp in the past! offset: " << md.time_spec.get_real_secs() - usrp_time << " (" << usrp_time << ")" - " frame " << frame->fct << + " frame " << frame->ts.fct << ", tx_second " << tx_second << ", pps " << pps_offset; goto loopend; //skip the frame @@ -433,7 +460,7 @@ void UHDWorker::process() "OutputUHD (usrp time: %f): frame %d;" " tx_second %zu; pps %.9f\n", usrp_time, - frame->fct, tx_second, pps_offset); + frame->ts.fct, tx_second, pps_offset); } } @@ -444,20 +471,21 @@ void UHDWorker::process() if (uwd->muting) { uwd->logger->log(info, "OutputUHD: Muting sample %d requested\n", - frame->fct); + frame->ts.fct); } else { uwd->logger->log(info, "OutputUHD: Muting sample %d : no timestamp\n", - frame->fct); + frame->ts.fct); } usleep(20000); goto loopend; } } +#endif PDEBUG("UHDWorker::process:max_num_samps: %zu.\n", - myTxStream->get_max_num_samps()); + usrp_max_num_samps); while (running && !uwd->muting && (num_acc_samps < sizeIn)) { size_t samps_to_send = std::min(sizeIn - num_acc_samps, usrp_max_num_samps); @@ -467,10 +495,16 @@ void UHDWorker::process() md.end_of_burst = (frame->ts.timestamp_refresh && (samps_to_send <= usrp_max_num_samps)); +#if FAKE_UHD + // This is probably very approximate + usleep( (1000000 / uwd->sampleRate) * samps_to_send); + size_t num_tx_samps = samps_to_send; +#else //send a single packet size_t num_tx_samps = myTxStream->send( &in[num_acc_samps], samps_to_send, md, timeout); +#endif num_acc_samps += num_tx_samps; @@ -515,6 +549,7 @@ void UHDWorker::process() #endif } +#if FAKE_UHD == 0 uhd::async_metadata_t async_md; if (uwd->myUsrp->get_device()->recv_async_msg(async_md, 0)) { const char* uhd_async_message = ""; @@ -545,11 +580,12 @@ void UHDWorker::process() if (failure) { uwd->logger->level(alert) << "Near frame " << - frame->fct << ": Received Async UHD Message '" << + frame->ts.fct << ": Received Async UHD Message '" << uhd_async_message << "'"; } } +#endif /* bool got_async_burst_ack = false; diff --git a/src/OutputUHD.h b/src/OutputUHD.h index 69e5b20..3a047bf 100644 --- a/src/OutputUHD.h +++ b/src/OutputUHD.h @@ -36,6 +36,8 @@ DESCRIPTION: #ifndef OUTPUT_UHD_H #define OUTPUT_UHD_H +#define FAKE_UHD 0 + #ifdef HAVE_CONFIG_H # include <config.h> #endif @@ -77,15 +79,14 @@ struct UHDWorkerFrameData { // Full timestamp struct frame_timestamp ts; - - // Frame counter - uint32_t fct; }; enum refclk_lock_loss_behaviour_t { CRASH, IGNORE }; struct UHDWorkerData { +#if FAKE_UHD == 0 uhd::usrp::multi_usrp::sptr myUsrp; +#endif unsigned sampleRate; // Double buffering between the two threads @@ -117,7 +118,12 @@ struct UHDWorkerData { // The common logger Logger* logger; -}; + + // What transmission mode we're using defines by how + // much the FCT should increment for each + // transmission frame. + int fct_increment; +}; class UHDWorker { 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; } diff --git a/src/TimestampDecoder.h b/src/TimestampDecoder.h index 52290ac..0c393e4 100644 --- a/src/TimestampDecoder.h +++ b/src/TimestampDecoder.h @@ -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. @@ -52,6 +54,9 @@ struct modulator_offset_config struct frame_timestamp { + // Which frame count does this timestamp apply to + uint32_t fct; + uint32_t timestamp_sec; double timestamp_pps_offset; bool timestamp_valid; @@ -64,6 +69,7 @@ struct frame_timestamp this->timestamp_pps_offset = rhs.timestamp_pps_offset; this->timestamp_valid = rhs.timestamp_valid; this->timestamp_refresh = rhs.timestamp_refresh; + this->fct = rhs.fct; } return *this; @@ -104,7 +110,7 @@ struct frame_timestamp /* This module decodes MNSC time information */ class TimestampDecoder { - public: + public: TimestampDecoder( struct modulator_offset_config& config, Logger& logger): @@ -113,6 +119,7 @@ class TimestampDecoder inhibit_second_update = 0; time_pps = 0.0; time_secs = 0; + latestFCT = 0; enableDecode = false; full_timestamp_received_mnsc = false; gmtime_r(0, &temp_time); @@ -129,7 +136,11 @@ class TimestampDecoder void calculateTimestamp(struct frame_timestamp& ts); /* Update timestamp data from data in ETI */ - void updateTimestampEti(int framephase, uint16_t mnsc, double pps); + void updateTimestampEti( + int framephase, + uint16_t mnsc, + double pps, + uint32_t fct); /* Update the modulator timestamp offset according to the modconf */ @@ -147,7 +158,7 @@ class TimestampDecoder * the timestamp */ void updateTimestampPPS(double pps); - + /* Update the timestamp when a full set of MNSC data is * known. This function can be called at most every four * frames when the data is transferred using the MNSC. @@ -156,6 +167,7 @@ class TimestampDecoder struct tm temp_time; uint32_t time_secs; + uint32_t latestFCT; double time_pps; double timestamp_offset; int inhibit_second_update; |