diff --git a/openrtx/src/protocols/M17/M17Demodulator.cpp b/openrtx/src/protocols/M17/M17Demodulator.cpp index 49e747c9..3592f719 100644 --- a/openrtx/src/protocols/M17/M17Demodulator.cpp +++ b/openrtx/src/protocols/M17/M17Demodulator.cpp @@ -27,30 +27,31 @@ #include #include #include -#include -#include -#ifndef PLATFORM_LINUX -#include -#endif using namespace M17; #ifdef ENABLE_DEMOD_LOG +#include #include +#ifndef PLATFORM_LINUX +#include +#endif typedef struct { int16_t sample; int32_t conv; - float conv_th; + float conv_th; int32_t sample_index; - float qnt_pos_avg; - float qnt_neg_avg; + float qnt_pos_avg; + float qnt_neg_avg; int32_t symbol; int32_t frame_index; + uint8_t flags; + uint8_t _empty; } -log_entry_t; +__attribute__((packed)) log_entry_t; #ifdef PLATFORM_LINUX #define LOG_QUEUE 160000 @@ -63,7 +64,7 @@ static std::atomic_bool dumpData; static bool logRunning; static bool trigEnable; static bool triggered; -static uint8_t trigCnt; +static uint32_t trigCnt; static pthread_t logThread; static void *logFunc(void *arg) @@ -72,7 +73,7 @@ static void *logFunc(void *arg) #ifdef PLATFORM_LINUX FILE *csv_log = fopen("demod_log.csv", "w"); - fprintf(csv_log, "Sample,Convolution,Threshold,Index,Max,Min,Symbol,I\n"); + fprintf(csv_log, "Sample,Convolution,Threshold,Index,Max,Min,Symbol,I,Flags\n"); #endif uint8_t emptyCtr = 0; @@ -87,14 +88,14 @@ static void *logFunc(void *arg) memset(&entry, 0x00, sizeof(log_entry_t)); if(logBuf.pop(entry, false) == false) emptyCtr++; - if(emptyCtr >= 4) + if(emptyCtr >= 100) { dumpData = false; emptyCtr = 0; } #ifdef PLATFORM_LINUX - fprintf(csv_log, "%" PRId16 ",%d,%f,%d,%f,%f,%d,%d\n", + fprintf(csv_log, "%" PRId16 ",%d,%f,%d,%f,%f,%d,%d,%d\n", entry.sample, entry.conv, entry.conv_th, @@ -102,7 +103,8 @@ static void *logFunc(void *arg) entry.qnt_pos_avg, entry.qnt_neg_avg, entry.symbol, - entry.frame_index); + entry.frame_index + entry.flags); fflush(csv_log); #else vcom_writeBlock(&entry, sizeof(log_entry_t)); @@ -122,14 +124,14 @@ static inline void pushLog(const log_entry_t& e) /* * 1) do not push data to log while dump is in progress * 2) if triggered, increase the counter - * 3) log twenty entries after the trigger and then start dump + * 3) fill half of the buffer with entries after the trigger, then start dump * 4) if buffer is full, erase the oldest element * 5) push data without blocking */ if(dumpData) return; if(triggered) trigCnt++; - if(trigCnt >= 20) + if(trigCnt >= LOG_QUEUE/2) { dumpData = true; triggered = false; @@ -309,15 +311,16 @@ sync_t M17Demodulator::nextFrameSync(int32_t offset) updateCorrelationStats(conv); #ifdef ENABLE_DEMOD_LOG - // Log syncword search - log_entry_t log = - { - (i < 0) ? basebandBridge[M17_BRIDGE_SIZE + i] : baseband.data[i], - conv, - CONV_THRESHOLD_FACTOR * getCorrelationStddev(), - i, - 0.0,0.0,0,0 - }; + log_entry_t log; + log.sample = (i < 0) ? basebandBridge[M17_BRIDGE_SIZE + i] : baseband.data[i]; + log.conv = conv; + log.conv_th = CONV_THRESHOLD_FACTOR * getCorrelationStddev(); + log.sample_index = i; + log.qnt_pos_avg = 0.0; + log.qnt_neg_avg = 0.0; + log.symbol = 0; + log.frame_index = 0; + log.flags = 1; pushLog(log); #endif @@ -378,24 +381,27 @@ int32_t M17Demodulator::syncwordSweep(int32_t offset) int32_t conv = convolution(offset + i, stream_syncword, M17_SYNCWORD_SYMBOLS); -#ifdef ENABLE_DEMOD_LOG - int16_t sample; - if (offset + i < 0) - sample = basebandBridge[M17_BRIDGE_SIZE + offset + i]; - else - sample = baseband.data[offset + i]; - log_entry_t log; - log = - { - sample, - conv, - 0.0, - offset + i, - 0.0,0.0,0,0 - }; + #ifdef ENABLE_DEMOD_LOG + int16_t sample; + if (offset + i < 0) + sample = basebandBridge[M17_BRIDGE_SIZE + offset + i]; + else + sample = baseband.data[offset + i]; + + log_entry_t log; + log.sample = sample; + log.conv = conv; + log.conv_th = 0.0; + log.sample_index = offset + i; + log.qnt_pos_avg = 0.0; + log.qnt_neg_avg = 0.0; + log.symbol = 0; + log.frame_index = 0; + log.flags = 2; pushLog(log); -#endif + #endif + if (conv > max_conv) { max_conv = conv; @@ -464,22 +470,23 @@ bool M17Demodulator::update() if ((symbol_index + i) >= 0 && (symbol_index + i) < static_cast (baseband.len)) { - log_entry_t log = - { - baseband.data[symbol_index + i], - phase,0.0,symbol_index + i, - qnt_pos_avg / 1.5f, - qnt_neg_avg / 1.5f, - symbol, - frame_index - }; + log_entry_t log; + log.sample = baseband.data[symbol_index + i]; + log.conv = 0; + log.conv_th = 0.0; + log.sample_index = symbol_index + i; + log.qnt_pos_avg = qnt_pos_avg / 1.5f; + log.qnt_neg_avg = qnt_neg_avg / 1.5f; + log.symbol = symbol; + log.frame_index = frame_index; + log.flags = 3; pushLog(log); } } #endif - setSymbol(*activeFrame, frame_index, symbol); + setSymbol(*activeFrame, frame_index, symbol); decoded_syms++; frame_index++; @@ -503,24 +510,27 @@ bool M17Demodulator::update() locked = false; std::swap(activeFrame, idleFrame); frame_index = 0; - newFrame = true; + newFrame = true; phase = 0; #ifdef ENABLE_DEMOD_LOG - // Trigger a data dump when lock is lost. + // Pre-arm the log trigger. + trigEnable = true; + #endif + + } + // Correct syncword found + else + { + #ifdef ENABLE_DEMOD_LOG + // Trigger a data dump when lock is re-acquired. if((dumpData == false) && (trigEnable == true)) { trigEnable = false; triggered = true; } #endif - } - // Correct syncword found - else - { - #ifdef ENABLE_DEMOD_LOG - trigEnable = true; - #endif + locked = true; } } diff --git a/openrtx/src/rtx/OpMode_M17.cpp b/openrtx/src/rtx/OpMode_M17.cpp index daef330a..e6b6ab07 100644 --- a/openrtx/src/rtx/OpMode_M17.cpp +++ b/openrtx/src/rtx/OpMode_M17.cpp @@ -77,10 +77,8 @@ void OpMode_M17::update(rtxStatus_t *const status, const bool newCfg) if(type == M17FrameType::STREAM) { M17StreamFrame sf = decoder.getStreamFrame(); - #ifndef ENABLE_DEMOD_LOG codec_pushFrame(sf.payload().data(), false); codec_pushFrame(sf.payload().data() + 8, false); - #endif } } } @@ -91,9 +89,7 @@ void OpMode_M17::update(rtxStatus_t *const status, const bool newCfg) audio_disableMic(); audio_enableAmp(); codec_stop(); - #ifndef ENABLE_DEMOD_LOG codec_startDecode(SINK_SPK); - #endif decoder.reset(); demodulator.startBasebandSampling(); diff --git a/scripts/get_demod_log.c b/scripts/get_demod_log.c index 5d8499b1..7edfd795 100644 --- a/scripts/get_demod_log.c +++ b/scripts/get_demod_log.c @@ -69,14 +69,16 @@ typedef struct { int16_t sample; int32_t conv; - float conv_th; + float conv_th; int32_t sample_index; - float qnt_pos_avg; - float qnt_neg_avg; + float qnt_pos_avg; + float qnt_neg_avg; int32_t symbol; int32_t frame_index; + uint8_t flags; + uint8_t _empty; } -log_entry_t; +__attribute__((packed)) log_entry_t; int main() { //char *portname = "/dev/ttyACM0"; @@ -92,11 +94,11 @@ int main() { set_blocking (fd, 0); // set no blocking log_entry_t log = { 0 }; FILE *csv_log = fopen("serial_demod_log.csv", "w"); - fprintf(csv_log, "Sample,Convolution,Threshold,Index,Max,Min,Symbol,I\n"); + fprintf(csv_log, "Sample,Convolution,Threshold,Index,Max,Min,Symbol,I,Flags\n"); while(true) { read(fd, &log, sizeof(log)); - fprintf(csv_log, "%" PRId16 ",%d,%f,%d,%f,%f,%d,%d\n", + fprintf(csv_log, "%" PRId16 ",%d,%f,%d,%f,%f,%d,%d,%d\n", log.sample, log.conv, log.conv_th, @@ -104,7 +106,8 @@ int main() { log.qnt_pos_avg, log.qnt_neg_avg, log.symbol, - log.frame_index); + log.frame_index, + log.flags); fflush(csv_log); } fclose(csv_log); diff --git a/scripts/plot_m17_demod_csv.py b/scripts/plot_m17_demod_csv.py index 70549f61..0b3fb7f0 100755 --- a/scripts/plot_m17_demod_csv.py +++ b/scripts/plot_m17_demod_csv.py @@ -7,13 +7,17 @@ from sys import argv plt.rcParams["figure.autolayout"] = True df = pd.read_csv(argv[1]) print("Contents in csv file:\n", df) -plt.plot(df.index, df.Sample) -plt.plot(df.index, df.Convolution / 10) -plt.plot(df.index, df.Threshold / 10) -plt.plot(df.index, df.Threshold * -1 / 10) -plt.plot(df.index, df.Index) -plt.plot(df.index, df.Max) -plt.plot(df.index, df.Min) -plt.plot(df.index, df.Symbol * 10) -plt.plot(df.index, df.I) +plt.plot(df.index, df.Sample, label="Sample") +plt.plot(df.index, df.Convolution / 10, label="Conv") +plt.plot(df.index, df.Threshold / 10, label="Conv. Th+") +plt.plot(df.index, df.Threshold * -1 / 10, label="Conv. Th-") +plt.plot(df.index, df.Index, label="Index") +plt.plot(df.index, df.Max, label="Qnt. avg. +") +plt.plot(df.index, df.Min, label="Qnt. avg. -") +plt.plot(df.index, df.Symbol * 10, label="Symbol") +plt.plot(df.index, df.I, label="I") +plt.plot(df.index, df.Flags * 100, label="Flags") +plt.grid(True) +plt.legend(loc="upper left") +plt.suptitle(argv[1]) plt.show()