From 5fe5b0e578dea308b16c4cd5a9bb500667e47681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Izzo?= Date: Fri, 13 May 2022 12:05:13 +0200 Subject: [PATCH] Refactor M17 logging Refactored logging functions to enable in-system logging on Module17 and MDx radios. TG-81 --- .../include/protocols/M17/M17Demodulator.h | 20 ++++ openrtx/src/protocols/M17/M17Demodulator.cpp | 112 ++++++++---------- scripts/plot_m17_demod_csv.py | 11 +- 3 files changed, 73 insertions(+), 70 deletions(-) diff --git a/openrtx/include/protocols/M17/M17Demodulator.h b/openrtx/include/protocols/M17/M17Demodulator.h index 5f5a883e..17beddbb 100644 --- a/openrtx/include/protocols/M17/M17Demodulator.h +++ b/openrtx/include/protocols/M17/M17Demodulator.h @@ -34,6 +34,7 @@ #include #include #include +#include #include "M17Datatypes.h" namespace M17 @@ -135,6 +136,17 @@ private: uint8_t lsf_syncword_bytes[2] = {0x55, 0xf7}; uint8_t stream_syncword_bytes[2] = {0xff, 0x5d}; + typedef struct { + int16_t sample; + int32_t conv; + float conv_th; + int32_t sample_index; + float qnt_pos_avg; + float qnt_neg_avg; + int32_t symbol; + int32_t frame_index; + } demod_log; + /* * Buffers */ @@ -150,6 +162,9 @@ private: bool newFrame; ///< A new frame has been fully decoded. int16_t basebandBridge[M17_BRIDGE_SIZE] = { 0 }; ///< Bridge buffer uint16_t phase; ///< Phase of the signal w.r.t. sampling +#ifdef PLATFORM_LINUX + FILE *csv_log; ///< Used under Linux to hold the log file +#endif /* * State variables @@ -241,6 +256,11 @@ private: */ uint8_t hammingDistance(uint8_t x, uint8_t y); + /** + * Append a sample to the log + */ + void appendLog(demod_log *log); + }; } /* M17 */ diff --git a/openrtx/src/protocols/M17/M17Demodulator.cpp b/openrtx/src/protocols/M17/M17Demodulator.cpp index 1ec58034..9a25f39c 100644 --- a/openrtx/src/protocols/M17/M17Demodulator.cpp +++ b/openrtx/src/protocols/M17/M17Demodulator.cpp @@ -67,11 +67,10 @@ void M17Demodulator::init() locked = false; newFrame = false; - #ifdef PLATFORM_LINUX - FILE *csv_log = fopen("demod_log.csv", "w"); - fprintf(csv_log, "Signal,Convolution,Threshold,Offset,Sample,Max,Min,Symbol,I\n"); - fclose(csv_log); - #endif // PLATFORM_MOD17 +#ifdef PLATFORM_LINUX + csv_log = fopen("demod_log.csv", "w"); + fprintf(csv_log, "Sample,Convolution,Threshold,Index,Max,Min,Symbol,I\n"); +#endif // PLATFORM_MOD17 } void M17Demodulator::terminate() @@ -81,6 +80,9 @@ void M17Demodulator::terminate() delete activeFrame; delete[] rawFrame; delete idleFrame; +#ifdef PLATFORM_LINUX + fclose(csv_log); +#endif } void M17Demodulator::startBasebandSampling() @@ -196,9 +198,6 @@ int32_t M17Demodulator::convolution(int32_t offset, sync_t M17Demodulator::nextFrameSync(int32_t offset) { - #ifdef PLATFORM_LINUX - FILE *csv_log = fopen("demod_log.csv", "a"); - #endif sync_t syncword = { -1, false }; // Find peaks in the correlation between the baseband and the frame syncword @@ -211,21 +210,14 @@ sync_t M17Demodulator::nextFrameSync(int32_t offset) int32_t conv = convolution(i, stream_syncword, M17_SYNCWORD_SYMBOLS); updateCorrelationStats(conv); - #ifdef PLATFORM_LINUX - int16_t sample = 0; - if (i < 0) // When we are at negative offsets use bridge buffer - sample = basebandBridge[M17_BRIDGE_SIZE + i]; - else // Otherwise use regular data buffer - sample = baseband.data[i]; - - fprintf(csv_log, "%" PRId16 ",%d,%f,%d,%" PRId16 ",%f,%f,%d,%d\n", - sample, - conv / 10, - CONV_THRESHOLD_FACTOR * getCorrelationStddev() / 10, - i, - 0,0.0,0.0,0,0); - fflush(csv_log); - #endif + // Log syncword search + demod_log log = { + (i < 0) ? basebandBridge[M17_BRIDGE_SIZE + i] : baseband.data[i], + conv, + CONV_THRESHOLD_FACTOR * getCorrelationStddev(), + i, + 0.0,0.0,0,0}; + appendLog(&log); // Positive correlation peak -> frame syncword if (conv > (getCorrelationStddev() * CONV_THRESHOLD_FACTOR)) @@ -241,9 +233,6 @@ sync_t M17Demodulator::nextFrameSync(int32_t offset) } } - #ifdef PLATFORM_LINUX - fclose(csv_log); - #endif return syncword; } @@ -281,6 +270,25 @@ uint8_t M17Demodulator::hammingDistance(uint8_t x, uint8_t y) return __builtin_popcount(x ^ y); } +#ifdef PLATFORM_LINUX +void M17Demodulator::appendLog(demod_log *log) { + fprintf(csv_log, "%" PRId16 ",%d,%f,%d,%f,%f,%d,%d\n", + log->sample, + log->conv, + log->conv_th, + log->sample_index, + log->qnt_pos_avg, + log->qnt_neg_avg, + log->symbol, + log->frame_index); + fflush(csv_log); +} +#else +void M17Demodulator::appendLog(demod_log *log) { + // TODO: Add log to circular queue +} +#endif + bool M17Demodulator::update() { M17::sync_t syncword = { 0, false }; @@ -293,10 +301,6 @@ bool M17Demodulator::update() // Apply DC removal filter dsp_dcRemoval(&dsp_state, baseband.data, baseband.len); - #ifdef PLATFORM_LINUX - FILE *csv_log = fopen("demod_log.csv", "a"); - #endif - if(baseband.data != NULL) { // Apply RRC on the baseband buffer @@ -336,38 +340,22 @@ bool M17Demodulator::update() updateQuantizationStats(symbol_index); int8_t symbol = quantize(symbol_index); - #ifdef PLATFORM_LINUX - for (int i = 0; i < 2; i++) + // Log quantization + for (int i = -2; i <= 2; i++) { - if ((symbol_index - 2 + i) >= 0) - fprintf(csv_log, "%" PRId16 ",%d,%f,%d,%" PRId16 ",%f,%f,%d,%d\n", - 0,0,0.0,symbol_index - 2 + i, - baseband.data[symbol_index - 2 + i], - qnt_pos_avg / 2.1, - qnt_neg_avg / 2.1, - 0, - frame_index); + if ((symbol_index + i) >= 0 && + (symbol_index + i) < static_cast (baseband.len)) + { + demod_log log = { + baseband.data[symbol_index + i], + 0,0.0,symbol_index + i, + qnt_pos_avg / 2.1f, + qnt_neg_avg / 2.1f, + symbol, + frame_index}; + appendLog(&log); + } } - fprintf(csv_log, "%" PRId16 ",%d,%f,%d,%" PRId16 ",%f,%f,%d,%d\n", - 0,0,0.0,symbol_index, - baseband.data[symbol_index], - qnt_pos_avg / 2.1, - qnt_neg_avg / 2.1, - symbol * 666, - frame_index); - for (int i = 0; i < 2; i++) - { - if ((symbol_index + i + 1) < static_cast (baseband.len)) - fprintf(csv_log, "%" PRId16 ",%d,%f,%d,%" PRId16 ",%f,%f,%d,%d\n", - 0,0,0.0,symbol_index + i + 1, - baseband.data[symbol_index + i + 1], - qnt_pos_avg / 2.1, - qnt_neg_avg / 2.1, - 0, - frame_index); - } - fflush(csv_log); - #endif setSymbol(*activeFrame, frame_index, symbol); decoded_syms++; @@ -426,9 +414,5 @@ bool M17Demodulator::update() } } - #ifdef PLATFORM_LINUX - fclose(csv_log); - #endif - return newFrame; } diff --git a/scripts/plot_m17_demod_csv.py b/scripts/plot_m17_demod_csv.py index 8f60e350..22fdda4a 100755 --- a/scripts/plot_m17_demod_csv.py +++ b/scripts/plot_m17_demod_csv.py @@ -7,14 +7,13 @@ 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.Signal) -plt.plot(df.index, df.Convolution) -plt.plot(df.index, df.Threshold) -plt.plot(df.index, df.Threshold * -1) -plt.plot(df.index, df.Offset) 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) +plt.plot(df.index, df.Symbol * 4000) plt.plot(df.index, df.I) plt.show()