Refactor M17 logging

Refactored logging functions to enable in-system logging on Module17 and
MDx radios.

TG-81
This commit is contained in:
Niccolò Izzo 2022-05-13 12:05:13 +02:00 committed by Silvano Seva
parent 361308be16
commit 5fe5b0e578
3 changed files with 73 additions and 70 deletions

View File

@ -34,6 +34,7 @@
#include <hwconfig.h> #include <hwconfig.h>
#include <dsp.h> #include <dsp.h>
#include <deque> #include <deque>
#include <stdio.h>
#include "M17Datatypes.h" #include "M17Datatypes.h"
namespace M17 namespace M17
@ -135,6 +136,17 @@ private:
uint8_t lsf_syncword_bytes[2] = {0x55, 0xf7}; uint8_t lsf_syncword_bytes[2] = {0x55, 0xf7};
uint8_t stream_syncword_bytes[2] = {0xff, 0x5d}; 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 * Buffers
*/ */
@ -150,6 +162,9 @@ private:
bool newFrame; ///< A new frame has been fully decoded. bool newFrame; ///< A new frame has been fully decoded.
int16_t basebandBridge[M17_BRIDGE_SIZE] = { 0 }; ///< Bridge buffer int16_t basebandBridge[M17_BRIDGE_SIZE] = { 0 }; ///< Bridge buffer
uint16_t phase; ///< Phase of the signal w.r.t. sampling 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 * State variables
@ -241,6 +256,11 @@ private:
*/ */
uint8_t hammingDistance(uint8_t x, uint8_t y); uint8_t hammingDistance(uint8_t x, uint8_t y);
/**
* Append a sample to the log
*/
void appendLog(demod_log *log);
}; };
} /* M17 */ } /* M17 */

View File

@ -67,11 +67,10 @@ void M17Demodulator::init()
locked = false; locked = false;
newFrame = false; newFrame = false;
#ifdef PLATFORM_LINUX #ifdef PLATFORM_LINUX
FILE *csv_log = fopen("demod_log.csv", "w"); csv_log = fopen("demod_log.csv", "w");
fprintf(csv_log, "Signal,Convolution,Threshold,Offset,Sample,Max,Min,Symbol,I\n"); fprintf(csv_log, "Sample,Convolution,Threshold,Index,Max,Min,Symbol,I\n");
fclose(csv_log); #endif // PLATFORM_MOD17
#endif // PLATFORM_MOD17
} }
void M17Demodulator::terminate() void M17Demodulator::terminate()
@ -81,6 +80,9 @@ void M17Demodulator::terminate()
delete activeFrame; delete activeFrame;
delete[] rawFrame; delete[] rawFrame;
delete idleFrame; delete idleFrame;
#ifdef PLATFORM_LINUX
fclose(csv_log);
#endif
} }
void M17Demodulator::startBasebandSampling() void M17Demodulator::startBasebandSampling()
@ -196,9 +198,6 @@ int32_t M17Demodulator::convolution(int32_t offset,
sync_t M17Demodulator::nextFrameSync(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 }; sync_t syncword = { -1, false };
// Find peaks in the correlation between the baseband and the frame syncword // 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); int32_t conv = convolution(i, stream_syncword, M17_SYNCWORD_SYMBOLS);
updateCorrelationStats(conv); updateCorrelationStats(conv);
#ifdef PLATFORM_LINUX // Log syncword search
int16_t sample = 0; demod_log log = {
if (i < 0) // When we are at negative offsets use bridge buffer (i < 0) ? basebandBridge[M17_BRIDGE_SIZE + i] : baseband.data[i],
sample = basebandBridge[M17_BRIDGE_SIZE + i]; conv,
else // Otherwise use regular data buffer CONV_THRESHOLD_FACTOR * getCorrelationStddev(),
sample = baseband.data[i]; i,
0.0,0.0,0,0};
fprintf(csv_log, "%" PRId16 ",%d,%f,%d,%" PRId16 ",%f,%f,%d,%d\n", appendLog(&log);
sample,
conv / 10,
CONV_THRESHOLD_FACTOR * getCorrelationStddev() / 10,
i,
0,0.0,0.0,0,0);
fflush(csv_log);
#endif
// Positive correlation peak -> frame syncword // Positive correlation peak -> frame syncword
if (conv > (getCorrelationStddev() * CONV_THRESHOLD_FACTOR)) 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; return syncword;
} }
@ -281,6 +270,25 @@ uint8_t M17Demodulator::hammingDistance(uint8_t x, uint8_t y)
return __builtin_popcount(x ^ 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() bool M17Demodulator::update()
{ {
M17::sync_t syncword = { 0, false }; M17::sync_t syncword = { 0, false };
@ -293,10 +301,6 @@ bool M17Demodulator::update()
// Apply DC removal filter // Apply DC removal filter
dsp_dcRemoval(&dsp_state, baseband.data, baseband.len); dsp_dcRemoval(&dsp_state, baseband.data, baseband.len);
#ifdef PLATFORM_LINUX
FILE *csv_log = fopen("demod_log.csv", "a");
#endif
if(baseband.data != NULL) if(baseband.data != NULL)
{ {
// Apply RRC on the baseband buffer // Apply RRC on the baseband buffer
@ -336,38 +340,22 @@ bool M17Demodulator::update()
updateQuantizationStats(symbol_index); updateQuantizationStats(symbol_index);
int8_t symbol = quantize(symbol_index); int8_t symbol = quantize(symbol_index);
#ifdef PLATFORM_LINUX // Log quantization
for (int i = 0; i < 2; i++) for (int i = -2; i <= 2; i++)
{ {
if ((symbol_index - 2 + i) >= 0) if ((symbol_index + i) >= 0 &&
fprintf(csv_log, "%" PRId16 ",%d,%f,%d,%" PRId16 ",%f,%f,%d,%d\n", (symbol_index + i) < static_cast<int32_t> (baseband.len))
0,0,0.0,symbol_index - 2 + i, {
baseband.data[symbol_index - 2 + i], demod_log log = {
qnt_pos_avg / 2.1, baseband.data[symbol_index + i],
qnt_neg_avg / 2.1, 0,0.0,symbol_index + i,
0, qnt_pos_avg / 2.1f,
frame_index); 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<int32_t> (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<M17_FRAME_BYTES>(*activeFrame, frame_index, symbol); setSymbol<M17_FRAME_BYTES>(*activeFrame, frame_index, symbol);
decoded_syms++; decoded_syms++;
@ -426,9 +414,5 @@ bool M17Demodulator::update()
} }
} }
#ifdef PLATFORM_LINUX
fclose(csv_log);
#endif
return newFrame; return newFrame;
} }

View File

@ -7,14 +7,13 @@ from sys import argv
plt.rcParams["figure.autolayout"] = True plt.rcParams["figure.autolayout"] = True
df = pd.read_csv(argv[1]) df = pd.read_csv(argv[1])
print("Contents in csv file:\n", df) 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.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.Max)
plt.plot(df.index, df.Min) 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.plot(df.index, df.I)
plt.show() plt.show()