From d93c2f8b14cbfb0b33b559a394db8add8ea86554 Mon Sep 17 00:00:00 2001 From: John Greb Date: Wed, 14 Jan 2015 00:48:48 +0000 Subject: [PATCH] Reverse SFFT for headers. --- plugins/channel/lora/lorademod.cpp | 24 +++++++++++++++++------- plugins/channel/lora/lorademod.h | 5 +++-- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/plugins/channel/lora/lorademod.cpp b/plugins/channel/lora/lorademod.cpp index 53d369536..5c869d5b2 100644 --- a/plugins/channel/lora/lorademod.cpp +++ b/plugins/channel/lora/lorademod.cpp @@ -40,12 +40,15 @@ LoRaDemod::LoRaDemod(SampleSink* sampleSink) : m_count = 0; loraFilter = new sfft(LORA_SFFT_LEN); + negaFilter = new sfft(LORA_SFFT_LEN); } LoRaDemod::~LoRaDemod() { if (loraFilter) delete loraFilter; + if (negaFilter) + delete negaFilter; } void LoRaDemod::configure(MessageQueue* messageQueue, Real Bandwidth) @@ -54,22 +57,29 @@ void LoRaDemod::configure(MessageQueue* messageQueue, Real Bandwidth) cmd->submit(messageQueue, this); } -// Detecting the header needs an sfft with the opposite rotation -int LoRaDemod::detect(Complex c) + +int LoRaDemod::detect(Complex c, Complex a) { int i; float peak; float mag[LORA_SFFT_LEN]; + float rev[LORA_SFFT_LEN]; - loraFilter->run(c); + loraFilter->run(c * a); + negaFilter->run(c * conj(a)); if (++m_count & 31) return m_result; // process spectrum every 32 samples loraFilter->fetch(mag); + negaFilter->fetch(rev); peak = 0.0f; m_result = 0; for (i = 0; i < LORA_SFFT_LEN; i++) { + if (rev[i]/3 > peak) { + peak = rev[i]/3; + m_result = i; + } if (mag[i] > peak) { peak = mag[i]; m_result = i; @@ -92,11 +102,11 @@ void LoRaDemod::feed(SampleVector::const_iterator begin, SampleVector::const_ite m_chirp = (m_chirp + 1) & (SPREADFACTOR - 1); m_angle = (m_angle + m_chirp) & (SPREADFACTOR - 1); Complex cangle(cos(M_PI*2*m_angle/SPREADFACTOR),-sin(M_PI*2*m_angle/SPREADFACTOR)); - newangle = detect(ci * cangle); + newangle = detect(ci, cangle); - m_bin = (m_bin + newangle) & (LORA_SFFT_LEN - 1); - Complex nangle(cos(M_PI*2*m_bin/LORA_SFFT_LEN),sin(M_PI*2*m_bin/LORA_SFFT_LEN)); - m_sampleBuffer.push_back(Sample(nangle.real() * 500, nangle.imag() * 500)); + m_bin = (m_bin + newangle) & (2*LORA_SFFT_LEN - 1); + Complex nangle(cos(M_PI*m_bin/LORA_SFFT_LEN),sin(M_PI*m_bin/LORA_SFFT_LEN)); + m_sampleBuffer.push_back(Sample(nangle.real() * 100, nangle.imag() * 100)); m_sampleDistanceRemain += (Real)m_sampleRate / m_Bandwidth; } } diff --git a/plugins/channel/lora/lorademod.h b/plugins/channel/lora/lorademod.h index 9e2ef443d..33da4ada3 100644 --- a/plugins/channel/lora/lorademod.h +++ b/plugins/channel/lora/lorademod.h @@ -27,7 +27,7 @@ #define SPREADFACTOR (1<<8) -/* It takes a lot of CPU to run the sliding FFT */ +/* Chosen for number of bins, not symbol length */ #define LORA_SFFT_LEN (128) class LoRaDemod : public SampleSink { @@ -38,7 +38,7 @@ public: void configure(MessageQueue* messageQueue, Real Bandwidth); void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool pO); - int detect(Complex c); + int detect(Complex sample, Complex angle); void start(); void stop(); bool handleMessage(Message* cmd); @@ -75,6 +75,7 @@ private: int m_count; sfft* loraFilter; + sfft* negaFilter; NCO m_nco; Interpolator m_interpolator;