| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
 | 
					
						
							|  |  |  | // written by Christian Daniel                                                   //
 | 
					
						
							|  |  |  | // (c) 2015 John Greb
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is free software; you can redistribute it and/or modify          //
 | 
					
						
							|  |  |  | // it under the terms of the GNU General Public License as published by          //
 | 
					
						
							|  |  |  | // the Free Software Foundation as version 3 of the License, or                  //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful,               //
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
					
						
							|  |  |  | // GNU General Public License V3 for more details.                               //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU General Public License             //
 | 
					
						
							|  |  |  | // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QTime>
 | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | #include <QDebug>
 | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include "lorademod.h"
 | 
					
						
							| 
									
										
										
										
											2015-08-19 22:12:52 +02:00
										 |  |  | #include "dsp/channelizer.h"
 | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 00:53:00 +00:00
										 |  |  | #include "lorabits.h"
 | 
					
						
							| 
									
										
										
										
											2015-01-15 10:57:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | MESSAGE_CLASS_DEFINITION(LoRaDemod::MsgConfigureLoRaDemod, Message) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LoRaDemod::LoRaDemod(SampleSink* sampleSink) : | 
					
						
							| 
									
										
										
										
											2015-08-24 23:23:45 +02:00
										 |  |  | 	m_sampleSink(sampleSink), | 
					
						
							|  |  |  | 	m_settingsMutex(QMutex::Recursive) | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-08-12 09:03:02 +02:00
										 |  |  | 	setObjectName("LoRaDemod"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | 	m_Bandwidth = 7813; | 
					
						
							|  |  |  | 	m_sampleRate = 96000; | 
					
						
							|  |  |  | 	m_frequency = 0; | 
					
						
							|  |  |  | 	m_nco.setFreq(m_frequency, m_sampleRate); | 
					
						
							| 
									
										
										
										
											2015-01-11 12:27:11 +00:00
										 |  |  | 	m_interpolator.create(16, m_sampleRate, m_Bandwidth/1.9); | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | 	m_sampleDistanceRemain = (Real)m_sampleRate / m_Bandwidth; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-11 12:27:11 +00:00
										 |  |  | 	m_chirp = 0; | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | 	m_angle = 0; | 
					
						
							| 
									
										
										
										
											2015-01-12 19:59:45 +00:00
										 |  |  | 	m_bin = 0; | 
					
						
							| 
									
										
										
										
											2015-01-13 19:14:36 +00:00
										 |  |  | 	m_result = 0; | 
					
						
							|  |  |  | 	m_count = 0; | 
					
						
							| 
									
										
										
										
											2015-01-17 15:59:44 +00:00
										 |  |  | 	m_header = 0; | 
					
						
							| 
									
										
										
										
											2015-01-22 22:30:55 +00:00
										 |  |  | 	m_time = 0; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	m_tune = 0; | 
					
						
							| 
									
										
										
										
											2015-01-11 19:30:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	loraFilter = new sfft(LORA_SFFT_LEN); | 
					
						
							| 
									
										
										
										
											2015-01-14 00:48:48 +00:00
										 |  |  | 	negaFilter = new sfft(LORA_SFFT_LEN); | 
					
						
							| 
									
										
										
										
											2015-01-15 10:57:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 00:53:00 +00:00
										 |  |  | 	mov = new float[4*LORA_SFFT_LEN]; | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | 	history = new short[1024]; | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 	finetune = new short[16]; | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LoRaDemod::~LoRaDemod() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-01-11 19:30:48 +00:00
										 |  |  | 	if (loraFilter) | 
					
						
							|  |  |  | 		delete loraFilter; | 
					
						
							| 
									
										
										
										
											2015-01-14 00:48:48 +00:00
										 |  |  | 	if (negaFilter) | 
					
						
							|  |  |  | 		delete negaFilter; | 
					
						
							| 
									
										
										
										
											2015-01-21 00:53:00 +00:00
										 |  |  | 	if (mov) | 
					
						
							|  |  |  | 		delete [] mov; | 
					
						
							| 
									
										
										
										
											2015-01-22 22:30:55 +00:00
										 |  |  | 	if (history) | 
					
						
							|  |  |  | 		delete [] history; | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 	if (finetune) | 
					
						
							|  |  |  | 		delete [] finetune; | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LoRaDemod::configure(MessageQueue* messageQueue, Real Bandwidth) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Message* cmd = MsgConfigureLoRaDemod::create(Bandwidth); | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	messageQueue->push(cmd); | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | void LoRaDemod::dumpRaw() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 	short bin, j, max; | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | 	char text[256]; | 
					
						
							| 
									
										
										
										
											2015-02-09 23:54:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	max = m_time / 4 - 3; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-13 18:16:22 +00:00
										 |  |  | 	if (max > 140) | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-02-13 18:16:22 +00:00
										 |  |  | 		max = 140; // about 2 symbols to each char
 | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-09 23:54:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	for ( j=0; j < max; j++) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-02-13 18:16:22 +00:00
										 |  |  | 		bin = (history[(j + 1)  * 4] + m_tune ) & (LORA_SFFT_LEN - 1); | 
					
						
							| 
									
										
										
										
											2015-01-31 23:41:06 +00:00
										 |  |  | 		text[j] = toGray(bin >> 1); | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 09:37:08 +00:00
										 |  |  | 	prng6(text, max); | 
					
						
							| 
									
										
										
										
											2015-02-13 18:16:22 +00:00
										 |  |  | 	// First block is always 8 symbols
 | 
					
						
							|  |  |  | 	interleave6(text, 6); | 
					
						
							|  |  |  | 	interleave6(&text[8], max); | 
					
						
							|  |  |  | 	hamming6(text, 6); | 
					
						
							|  |  |  | 	hamming6(&text[8], max); | 
					
						
							| 
									
										
										
										
											2015-02-09 23:54:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	for ( j=0; j < max / 2; j++) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-02-13 18:16:22 +00:00
										 |  |  | 		text[j] = (text[j * 2 + 1] << 4) | (0xf & text[j * 2 + 0]); | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-09 23:54:51 +00:00
										 |  |  | 		if ((text[j] < 32 )||( text[j] > 126)) | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2015-02-09 23:54:51 +00:00
										 |  |  | 			text[j] = 0x5f; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-02-07 10:03:51 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-13 18:16:22 +00:00
										 |  |  | 	text[3] = text[2]; | 
					
						
							|  |  |  | 	text[2] = text[1]; | 
					
						
							|  |  |  | 	text[1] = text[0]; | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 	text[j] = 0; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-13 18:16:22 +00:00
										 |  |  | 	printf("%s\n", &text[1]); | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-22 22:30:55 +00:00
										 |  |  | short LoRaDemod::synch(short bin) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 	short i, j; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (bin < 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | 		if (m_time > 70) | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | 			dumpRaw(); | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-22 22:30:55 +00:00
										 |  |  | 		m_time = 0; | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2015-01-22 22:30:55 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 	history[m_time] = bin; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-22 22:30:55 +00:00
										 |  |  | 	if (m_time > 12) | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 		if (bin == history[m_time - 6]) | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			if (bin == history[m_time - 12]) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | 				m_tune = LORA_SFFT_LEN - bin; | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 				j = 0; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 				for (i=0; i<12; i++) | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 					j += finetune[15 & (m_time - i)]; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 				if (j < 0) | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 					m_tune += 1; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 				m_tune &= (LORA_SFFT_LEN - 1); | 
					
						
							|  |  |  | 				m_time = 0; | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | 				return -1; | 
					
						
							| 
									
										
										
										
											2015-01-22 22:30:55 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-22 22:30:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	m_time++; | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | 	m_time &= 1023; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | 	if (m_time & 3) | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | 	return (bin + m_tune) & (LORA_SFFT_LEN - 1); | 
					
						
							| 
									
										
										
										
											2015-01-22 22:30:55 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-01-14 00:48:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 00:53:00 +00:00
										 |  |  | int LoRaDemod::detect(Complex c, Complex a) | 
					
						
							| 
									
										
										
										
											2015-01-12 19:59:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 	int p, q; | 
					
						
							| 
									
										
										
										
											2015-01-22 22:30:55 +00:00
										 |  |  | 	short i, result, negresult, movpoint; | 
					
						
							| 
									
										
										
										
											2015-01-21 00:53:00 +00:00
										 |  |  | 	float peak, negpeak, tfloat; | 
					
						
							| 
									
										
										
										
											2015-01-13 19:14:36 +00:00
										 |  |  | 	float mag[LORA_SFFT_LEN]; | 
					
						
							| 
									
										
										
										
											2015-01-14 00:48:48 +00:00
										 |  |  | 	float rev[LORA_SFFT_LEN]; | 
					
						
							| 
									
										
										
										
											2015-01-13 19:14:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-14 00:48:48 +00:00
										 |  |  | 	loraFilter->run(c * a); | 
					
						
							|  |  |  | 	negaFilter->run(c * conj(a)); | 
					
						
							| 
									
										
										
										
											2015-01-21 00:53:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// process spectrum twice in FFTLEN
 | 
					
						
							|  |  |  | 	if (++m_count & ((1 << DATA_BITS) - 1)) | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-01-13 19:14:36 +00:00
										 |  |  | 		return m_result; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 00:53:00 +00:00
										 |  |  | 	movpoint = 3 & (m_count >> DATA_BITS); | 
					
						
							| 
									
										
										
										
											2015-01-13 19:14:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	loraFilter->fetch(mag); | 
					
						
							| 
									
										
										
										
											2015-01-14 00:48:48 +00:00
										 |  |  | 	negaFilter->fetch(rev); | 
					
						
							| 
									
										
										
										
											2015-01-17 15:59:44 +00:00
										 |  |  | 	peak = negpeak = 0.0f; | 
					
						
							|  |  |  | 	result = negresult = 0; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < LORA_SFFT_LEN; i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (rev[i] > negpeak) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2015-01-17 15:59:44 +00:00
										 |  |  | 			negpeak = rev[i]; | 
					
						
							|  |  |  | 			negresult = i; | 
					
						
							| 
									
										
										
										
											2015-01-14 00:48:48 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 00:53:00 +00:00
										 |  |  | 		tfloat = mov[i] + mov[LORA_SFFT_LEN + i] +mov[2 * LORA_SFFT_LEN + i] | 
					
						
							|  |  |  | 				+ mov[3 * LORA_SFFT_LEN + i] + mag[i]; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (tfloat > peak) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2015-01-21 00:53:00 +00:00
										 |  |  | 			peak = tfloat; | 
					
						
							| 
									
										
										
										
											2015-01-17 15:59:44 +00:00
										 |  |  | 			result = i; | 
					
						
							| 
									
										
										
										
											2015-01-12 19:59:45 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 00:53:00 +00:00
										 |  |  | 		mov[movpoint * LORA_SFFT_LEN + i] = mag[i]; | 
					
						
							| 
									
										
										
										
											2015-01-12 19:59:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	p = (result - 1 + LORA_SFFT_LEN) & (LORA_SFFT_LEN -1); | 
					
						
							|  |  |  | 	q = (result + 1) & (LORA_SFFT_LEN -1); | 
					
						
							|  |  |  | 	finetune[15 & m_time] = (mag[p] > mag[q]) ? -1 : 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 09:37:08 +00:00
										 |  |  | 	if (peak < negpeak * LORA_SQUELCH) | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 		result = -1; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 00:02:49 +00:00
										 |  |  | 	result = synch(result); | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | 	if (result >= 0) | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-01-25 17:27:20 +00:00
										 |  |  | 		m_result = result; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-13 19:14:36 +00:00
										 |  |  | 	return m_result; | 
					
						
							| 
									
										
										
										
											2015-01-12 19:59:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 08:24:23 +02:00
										 |  |  | void LoRaDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool pO) | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-01-12 19:59:45 +00:00
										 |  |  | 	int newangle; | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | 	Complex ci; | 
					
						
							| 
									
										
										
										
											2015-01-12 19:59:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | 	m_sampleBuffer.clear(); | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-24 23:23:45 +02:00
										 |  |  | 	m_settingsMutex.lock(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	for(SampleVector::const_iterator it = begin; it < end; ++it) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-10-09 03:59:28 +02:00
										 |  |  | 		Complex c(it->real() / 32768.0f, it->imag() / 32768.0f); | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | 		c *= m_nco.nextIQ(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 		if(m_interpolator.interpolate(&m_sampleDistanceRemain, c, &ci)) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2015-01-11 12:27:11 +00:00
										 |  |  | 			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)); | 
					
						
							| 
									
										
										
										
											2015-01-14 00:48:48 +00:00
										 |  |  | 			newangle = detect(ci, cangle); | 
					
						
							| 
									
										
										
										
											2015-01-12 19:59:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-15 10:57:05 +00:00
										 |  |  | 			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)); | 
					
						
							| 
									
										
										
										
											2015-01-14 00:48:48 +00:00
										 |  |  | 			m_sampleBuffer.push_back(Sample(nangle.real() * 100, nangle.imag() * 100)); | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | 			m_sampleDistanceRemain += (Real)m_sampleRate / m_Bandwidth; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(m_sampleSink != 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-01-15 10:57:05 +00:00
										 |  |  | 		m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), false); | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-24 23:23:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	m_settingsMutex.unlock(); | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LoRaDemod::start() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LoRaDemod::stop() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | bool LoRaDemod::handleMessage(const Message& cmd) | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	qDebug() << "LoRaDemod::handleMessage"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-19 22:12:52 +02:00
										 |  |  | 	if (Channelizer::MsgChannelizerNotification::match(cmd)) | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-08-19 22:12:52 +02:00
										 |  |  | 		Channelizer::MsgChannelizerNotification& notif = (Channelizer::MsgChannelizerNotification&) cmd; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-24 23:23:45 +02:00
										 |  |  | 		m_settingsMutex.lock(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 		m_sampleRate = notif.getSampleRate(); | 
					
						
							|  |  |  | 		m_nco.setFreq(-notif.getFrequencyOffset(), m_sampleRate); | 
					
						
							| 
									
										
										
										
											2015-01-11 12:27:11 +00:00
										 |  |  | 		m_interpolator.create(16, m_sampleRate, m_Bandwidth/1.9); | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | 		m_sampleDistanceRemain = m_sampleRate / m_Bandwidth; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-24 23:23:45 +02:00
										 |  |  | 		m_settingsMutex.unlock(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-19 22:12:52 +02:00
										 |  |  | 		qDebug() << "LoRaDemod::handleMessage: MsgChannelizerNotification: m_sampleRate: " << m_sampleRate | 
					
						
							|  |  |  | 				<< " frequencyOffset: " << notif.getFrequencyOffset(); | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | 		return true; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else if (MsgConfigureLoRaDemod::match(cmd)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		MsgConfigureLoRaDemod& cfg = (MsgConfigureLoRaDemod&) cmd; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-24 23:23:45 +02:00
										 |  |  | 		m_settingsMutex.lock(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 		m_Bandwidth = cfg.getBandwidth(); | 
					
						
							| 
									
										
										
										
											2015-01-11 12:27:11 +00:00
										 |  |  | 		m_interpolator.create(16, m_sampleRate, m_Bandwidth/1.9); | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-24 23:23:45 +02:00
										 |  |  | 		m_settingsMutex.unlock(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 		qDebug() << " MsgConfigureLoRaDemod: m_Bandwidth: " << m_Bandwidth; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | 		return true; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if(m_sampleSink != 0) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | 			 return m_sampleSink->handleMessage(cmd); | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | 			return false; | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-01-11 00:12:58 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } |