kopia lustrzana https://github.com/rpp0/gr-lora
Some progress on different SFs and CRs
rodzic
90486a0ed0
commit
380be3e20d
|
@ -18,6 +18,5 @@
|
||||||
# Boston, MA 02110-1301, USA.
|
# Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
install(FILES
|
install(FILES
|
||||||
lora_decoder.xml
|
|
||||||
lora_receiver.xml DESTINATION share/gnuradio/grc/blocks
|
lora_receiver.xml DESTINATION share/gnuradio/grc/blocks
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<block>
|
|
||||||
<name>LoRa Decoder</name>
|
|
||||||
<key>lora_decoder</key>
|
|
||||||
<category>lora</category>
|
|
||||||
<import>import lora</import>
|
|
||||||
<make>lora.lora_decoder()</make>
|
|
||||||
|
|
||||||
<sink>
|
|
||||||
<name>in</name>
|
|
||||||
<type>float</type>
|
|
||||||
</sink>
|
|
||||||
|
|
||||||
<sink>
|
|
||||||
<name>in</name>
|
|
||||||
<type>complex</type>
|
|
||||||
</sink>
|
|
||||||
|
|
||||||
<source>
|
|
||||||
<name>out</name>
|
|
||||||
<type>float</type>
|
|
||||||
<optional>1</optional>
|
|
||||||
</source>
|
|
||||||
|
|
||||||
<source>
|
|
||||||
<name>out</name>
|
|
||||||
<type>float</type>
|
|
||||||
<optional>1</optional>
|
|
||||||
</source>
|
|
||||||
</block>
|
|
|
@ -4,13 +4,13 @@
|
||||||
<key>lora_lora_receiver</key>
|
<key>lora_lora_receiver</key>
|
||||||
<category>lora</category>
|
<category>lora</category>
|
||||||
<import>import lora</import>
|
<import>import lora</import>
|
||||||
<make>lora.lora_receiver($in_samp_rate, $freq, $offset, $finetune, $realtime)</make>
|
<make>lora.lora_receiver($in_samp_rate, $freq, $offset, $sf, $realtime)</make>
|
||||||
|
|
||||||
<callback>set_finetune($finetune)</callback>
|
<callback>set_sf($sf)</callback>
|
||||||
<callback>set_offset($offset)</callback>
|
<callback>set_offset($offset)</callback>
|
||||||
<param>
|
<param>
|
||||||
<name>Finetune</name>
|
<name>Spreading factor</name>
|
||||||
<key>finetune</key>
|
<key>sf</key>
|
||||||
<type>int</type>
|
<type>int</type>
|
||||||
</param>
|
</param>
|
||||||
|
|
||||||
|
|
|
@ -703,9 +703,9 @@ namespace gr {
|
||||||
* class. lora::decoder::make is the public interface for
|
* class. lora::decoder::make is the public interface for
|
||||||
* creating new instances.
|
* creating new instances.
|
||||||
*/
|
*/
|
||||||
static sptr make(int finetune);
|
static sptr make(int sf);
|
||||||
|
|
||||||
virtual void set_finetune(int32_t finetune) = 0;
|
virtual void set_sf(uint8_t sf) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lora
|
} // namespace lora
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
#include "tables.h"
|
#include "tables.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
#define CORRELATION_SEARCH_RANGE 1024
|
|
||||||
#define DELAY_AFTER_SYNC 262
|
|
||||||
//#define NO_TMP_WRITES 1
|
//#define NO_TMP_WRITES 1
|
||||||
//#define CFO_CORRECT 1
|
//#define CFO_CORRECT 1
|
||||||
|
|
||||||
|
@ -39,34 +37,35 @@ namespace gr {
|
||||||
namespace lora {
|
namespace lora {
|
||||||
|
|
||||||
decoder::sptr
|
decoder::sptr
|
||||||
decoder::make(int finetune) {
|
decoder::make(int sf) {
|
||||||
return gnuradio::get_initial_sptr
|
return gnuradio::get_initial_sptr
|
||||||
(new decoder_impl(finetune));
|
(new decoder_impl(sf));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The private constructor
|
* The private constructor
|
||||||
*/
|
*/
|
||||||
decoder_impl::decoder_impl(int finetune) : gr::sync_block("decoder",
|
decoder_impl::decoder_impl(int sf) : gr::sync_block("decoder",
|
||||||
gr::io_signature::make(1, -1, sizeof(gr_complex)),
|
gr::io_signature::make(1, -1, sizeof(gr_complex)),
|
||||||
gr::io_signature::make(0, 2, sizeof(float))) {
|
gr::io_signature::make(0, 2, sizeof(float))) {
|
||||||
d_state = DETECT;
|
d_state = DETECT;
|
||||||
|
|
||||||
d_debug_samples.open("/tmp/grlora_debug", std::ios::out | std::ios::binary);
|
d_debug_samples.open("/tmp/grlora_debug", std::ios::out | std::ios::binary);
|
||||||
d_debug.open("/tmp/grlora_debug_txt", std::ios::out);
|
d_debug.open("/tmp/grlora_debug_txt", std::ios::out);
|
||||||
d_sf = 7; // Only affects PHY send
|
d_sf = sf; // Only affects PHY send
|
||||||
d_bw = 125000;
|
d_bw = 125000;
|
||||||
d_cr = 4;
|
d_cr = 4;
|
||||||
d_bits_per_second = (double)d_sf * 1.0f / (pow(2.0f, d_sf) / d_bw);
|
d_bits_per_second = (double)d_sf * (4.0f/4.0f+d_cr) / (pow(2.0f, d_sf) / d_bw);
|
||||||
d_samples_per_second = 1000000;
|
d_samples_per_second = 1000000;
|
||||||
d_symbols_per_second = (double)d_bw / pow(2.0f, d_sf);
|
d_symbols_per_second = (double)d_bw / pow(2.0f, d_sf);
|
||||||
d_bits_per_symbol = (uint32_t)(d_bits_per_second / d_symbols_per_second);
|
d_bits_per_symbol = (uint32_t)(d_bits_per_second / d_symbols_per_second);
|
||||||
d_samples_per_symbol = (uint32_t)(d_samples_per_second / d_symbols_per_second);
|
d_samples_per_symbol = (uint32_t)(d_samples_per_second / d_symbols_per_second);
|
||||||
|
d_delay_after_sync = d_samples_per_symbol / 4; //262;
|
||||||
|
d_delay_after_sync += (uint32_t)d_delay_after_sync * 2.4f / 100.0f;
|
||||||
|
d_corr_decim_factor = 8; // samples_per_symbol / corr_decim_factor = correlation window. Also serves as preamble decimation factor
|
||||||
d_number_of_bins = (uint32_t)pow(2, d_sf);
|
d_number_of_bins = (uint32_t)pow(2, d_sf);
|
||||||
d_number_of_bins_hdr = d_number_of_bins / 4;
|
d_number_of_bins_hdr = d_number_of_bins / 4;
|
||||||
d_compression = 8;
|
|
||||||
d_payload_symbols = 0;
|
d_payload_symbols = 0;
|
||||||
d_finetune = finetune;
|
|
||||||
d_cfo_estimation = 0.0f;
|
d_cfo_estimation = 0.0f;
|
||||||
d_cfo_step = 0;
|
d_cfo_step = 0;
|
||||||
d_dt = 1.0f / d_samples_per_second;
|
d_dt = 1.0f / d_samples_per_second;
|
||||||
|
@ -287,18 +286,18 @@ namespace gr {
|
||||||
float samples_ifreq[window];
|
float samples_ifreq[window];
|
||||||
|
|
||||||
instantaneous_frequency(samples, samples_ifreq, window);
|
instantaneous_frequency(samples, samples_ifreq, window);
|
||||||
return sliding_norm_cross_correlate(samples_ifreq, &d_upchirp_ifreq[0], window, 128, index);
|
return sliding_norm_cross_correlate(samples_ifreq, &d_upchirp_ifreq[0], window, d_samples_per_symbol / d_corr_decim_factor, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int decoder_impl::get_shift_fft(gr_complex* samples) {
|
unsigned int decoder_impl::get_shift_fft(gr_complex* samples) {
|
||||||
float fft_mag[d_number_of_bins];
|
float fft_mag[d_number_of_bins];
|
||||||
gr_complex mult_hf[d_samples_per_symbol];
|
gr_complex mult_hf[d_samples_per_symbol];
|
||||||
|
|
||||||
/*#ifdef CFO_CORRECT
|
#ifdef CFO_CORRECT
|
||||||
determine_cfo(&samples[0]);
|
determine_cfo(&samples[0]);
|
||||||
std::cout << "CFO: " << d_cfo_estimation << std::endl;
|
d_debug << "CFO: " << d_cfo_estimation << std::endl;
|
||||||
correct_cfo(&samples[0], d_samples_per_symbol);
|
correct_cfo(&samples[0], d_samples_per_symbol);
|
||||||
#endif*/
|
#endif
|
||||||
|
|
||||||
samples_to_file("/tmp/data", &samples[0], d_samples_per_symbol, sizeof(gr_complex));
|
samples_to_file("/tmp/data", &samples[0], d_samples_per_symbol, sizeof(gr_complex));
|
||||||
|
|
||||||
|
@ -386,17 +385,15 @@ namespace gr {
|
||||||
|
|
||||||
// Decode (actually gray encode) the bin to get the symbol value
|
// Decode (actually gray encode) the bin to get the symbol value
|
||||||
unsigned int word = gray_encode(bin_idx);
|
unsigned int word = gray_encode(bin_idx);
|
||||||
d_debug << bin_idx << " " << to_bin(word, is_header ? 5 : 7) << " ! " << bin_idx_test << std::endl;
|
d_debug << to_bin(word, is_header ? d_sf-2 : d_sf) << " " << bin_idx << std::endl;
|
||||||
d_words.push_back(word);
|
d_words.push_back(word);
|
||||||
|
|
||||||
// Look for 4+cr symbols and stop
|
// Look for 4+cr symbols and stop
|
||||||
if(d_words.size() == (4 + d_cr)) {
|
if(d_words.size() == (4 + d_cr)) {
|
||||||
// Deinterleave
|
// Deinterleave
|
||||||
if(is_header) {
|
if(is_header) {
|
||||||
//print_vector(d_words, "M", d_sf - 2);
|
|
||||||
deinterleave(d_sf - 2);
|
deinterleave(d_sf - 2);
|
||||||
} else {
|
} else {
|
||||||
//print_vector(d_words, "M", d_sf);
|
|
||||||
deinterleave(d_sf);
|
deinterleave(d_sf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,6 +470,8 @@ namespace gr {
|
||||||
|
|
||||||
if(!is_header)
|
if(!is_header)
|
||||||
std::cout << result.str() << std::endl;
|
std::cout << result.str() << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << result.str();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -513,9 +512,22 @@ namespace gr {
|
||||||
}
|
}
|
||||||
|
|
||||||
void decoder_impl::hamming_decode(uint8_t* out_data) {
|
void decoder_impl::hamming_decode(uint8_t* out_data) {
|
||||||
unsigned int n = ceil(d_words_dewhitened.size() * 4.0 / 8.0);
|
unsigned int n = ceil(d_words_dewhitened.size() * 4.0f / (4.0f + d_cr));
|
||||||
fec_scheme fs = LIQUID_FEC_HAMMING84;
|
fec_scheme fs = LIQUID_FEC_HAMMING84;
|
||||||
|
|
||||||
|
if(d_cr == 4)
|
||||||
|
fs = LIQUID_FEC_HAMMING84;
|
||||||
|
else if(d_cr == 3)
|
||||||
|
fs = LIQUID_FEC_HAMMING74;
|
||||||
|
else if(d_cr == 2)
|
||||||
|
fs = LIQUID_FEC_HAMMING128;
|
||||||
|
else if(d_cr == 1) { // TODO: Temporary, since Liquid doesn't support 4/5 Hamming so we need to implement it ourselves / extend Liquid.
|
||||||
|
uint8_t indices[4] = {1, 2, 3, 5};
|
||||||
|
fec_extract_data_only(&d_words_dewhitened[0], d_words_dewhitened.size(), indices, 4, out_data);
|
||||||
|
d_words_dewhitened.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int k = fec_get_enc_msg_length(fs, n);
|
unsigned int k = fec_get_enc_msg_length(fs, n);
|
||||||
fec hamming = fec_create(fs, NULL);
|
fec hamming = fec_create(fs, NULL);
|
||||||
|
|
||||||
|
@ -548,10 +560,10 @@ namespace gr {
|
||||||
}
|
}
|
||||||
|
|
||||||
float sum = 0.0f;
|
float sum = 0.0f;
|
||||||
for(int i = 0; i < d_samples_per_symbol; i++) {
|
for(int i = 0; i < d_samples_per_symbol-1; i++) {
|
||||||
sum += instantaneous_freq[i];
|
sum += instantaneous_freq[i];
|
||||||
}
|
}
|
||||||
sum /= d_samples_per_symbol;
|
sum /= d_samples_per_symbol-1;
|
||||||
|
|
||||||
d_cfo_estimation = sum;
|
d_cfo_estimation = sum;
|
||||||
|
|
||||||
|
@ -575,26 +587,32 @@ namespace gr {
|
||||||
}
|
}
|
||||||
|
|
||||||
int decoder_impl::find_preamble_start_fast(gr_complex* samples, uint32_t len) {
|
int decoder_impl::find_preamble_start_fast(gr_complex* samples, uint32_t len) {
|
||||||
int decimation = d_decim_factor; // TODO: Replace with d_decimation
|
int decimation = d_corr_decim_factor;
|
||||||
int decim_size = d_samples_per_symbol / decimation;
|
int decim_size = d_samples_per_symbol / decimation;
|
||||||
float decim[decim_size];
|
float decim[decimation];
|
||||||
float gradient[decim_size];
|
float gradient[decimation];
|
||||||
|
uint32_t rising = 0;
|
||||||
|
uint32_t rising_required = 2;
|
||||||
|
|
||||||
|
gradient[0] = 0.0f;
|
||||||
|
|
||||||
|
|
||||||
for(int i = 0; i < decim_size; i++) {
|
for(int i = 0; i < decimation; i++) {
|
||||||
float s[2] = {
|
float s[2] = {
|
||||||
arg(samples[i*decimation]),
|
arg(samples[i*decim_size]),
|
||||||
arg(samples[(i+1)*decimation])
|
arg(samples[(i+1)*decim_size])
|
||||||
};
|
};
|
||||||
liquid_unwrap_phase(s, 2);
|
liquid_unwrap_phase(s, 2);
|
||||||
|
|
||||||
decim[i] = (s[1] - s[0]) / (2.0f * M_PI) * d_samples_per_second;
|
decim[i] = (s[1] - s[0]) / (2.0f * M_PI) * d_samples_per_second;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 1; i < decim_size; i++) {
|
for(int i = 1; i < decimation; i++) {
|
||||||
gradient[i] = decim[i] - decim[i-1];
|
gradient[i] = decim[i] - decim[i-1];
|
||||||
if(gradient[i] <= -20000) {
|
if(gradient[i] > gradient[i-1])
|
||||||
return i*decimation;
|
rising++;
|
||||||
|
if(rising >= rising_required && gradient[i] <= -20000) { // TODO: Make this a bit more logical, e.g. d_bw / decimation * 2 -> 2 steps down
|
||||||
|
return i*decim_size;
|
||||||
}
|
}
|
||||||
//d_debug << "G:" << gradient[i] << std::endl;
|
//d_debug << "G:" << gradient[i] << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -602,6 +620,31 @@ namespace gr {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t decoder_impl::lookup_cr(uint8_t bytevalue) {
|
||||||
|
switch (bytevalue & 0x0f) {
|
||||||
|
case 0x0a: {
|
||||||
|
return 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x0b: {
|
||||||
|
return 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x0c: {
|
||||||
|
return 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x08: {
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int decoder_impl::work(int noutput_items,
|
int decoder_impl::work(int noutput_items,
|
||||||
gr_vector_const_void_star &input_items,
|
gr_vector_const_void_star &input_items,
|
||||||
gr_vector_void_star &output_items) {
|
gr_vector_void_star &output_items) {
|
||||||
|
@ -635,9 +678,10 @@ namespace gr {
|
||||||
if(c > 0.8f) {
|
if(c > 0.8f) {
|
||||||
d_debug << "SYNC: " << c << std::endl;
|
d_debug << "SYNC: " << c << std::endl;
|
||||||
// Debug stuff
|
// Debug stuff
|
||||||
samples_to_file("/tmp/sync", &input[0], CORRELATION_SEARCH_RANGE, sizeof(gr_complex));
|
samples_to_file("/tmp/sync", &input[0], d_samples_per_symbol, sizeof(gr_complex));
|
||||||
|
|
||||||
d_state = PAUSE;
|
d_state = PAUSE;
|
||||||
|
d_cr = 4;
|
||||||
consume_each(d_samples_per_symbol);
|
consume_each(d_samples_per_symbol);
|
||||||
} else {
|
} else {
|
||||||
d_corr_fails++;
|
d_corr_fails++;
|
||||||
|
@ -651,8 +695,8 @@ namespace gr {
|
||||||
case PAUSE: {
|
case PAUSE: {
|
||||||
d_state = DECODE_HEADER;
|
d_state = DECODE_HEADER;
|
||||||
|
|
||||||
samples_debug(input, d_samples_per_symbol + DELAY_AFTER_SYNC);
|
samples_debug(input, d_samples_per_symbol + d_delay_after_sync);
|
||||||
consume_each(d_samples_per_symbol + DELAY_AFTER_SYNC);
|
consume_each(d_samples_per_symbol + d_delay_after_sync);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DECODE_HEADER: {
|
case DECODE_HEADER: {
|
||||||
|
@ -663,7 +707,7 @@ namespace gr {
|
||||||
|
|
||||||
nibble_reverse(decoded, 1); // TODO: Why?
|
nibble_reverse(decoded, 1); // TODO: Why?
|
||||||
d_payload_length = decoded[0];
|
d_payload_length = decoded[0];
|
||||||
d_cr = 4; // TODO: Get from header instead of hardcode
|
d_cr = lookup_cr(decoded[2]);
|
||||||
|
|
||||||
int symbols_per_block = d_cr + 4;
|
int symbols_per_block = d_cr + 4;
|
||||||
int bits_needed = ((d_payload_length * 8) + 16) * (symbols_per_block / 4);
|
int bits_needed = ((d_payload_length * 8) + 16) * (symbols_per_block / 4);
|
||||||
|
@ -710,8 +754,9 @@ namespace gr {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decoder_impl::set_finetune(int32_t finetune) {
|
void decoder_impl::set_sf(uint8_t sf) {
|
||||||
d_finetune = finetune;
|
if(sf >= 7 && sf <= 13)
|
||||||
|
d_sf = sf;
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace lora */
|
} /* namespace lora */
|
||||||
|
|
|
@ -51,11 +51,11 @@ namespace gr {
|
||||||
std::vector<float> d_upchirp_ifreq;
|
std::vector<float> d_upchirp_ifreq;
|
||||||
std::vector<gr_complex> d_fft;
|
std::vector<gr_complex> d_fft;
|
||||||
std::vector<gr_complex> d_mult;
|
std::vector<gr_complex> d_mult;
|
||||||
int32_t d_finetune;
|
|
||||||
uint8_t d_sf;
|
uint8_t d_sf;
|
||||||
uint32_t d_bw;
|
uint32_t d_bw;
|
||||||
uint8_t d_cr;
|
uint8_t d_cr;
|
||||||
double d_bits_per_second;
|
double d_bits_per_second;
|
||||||
|
uint32_t d_delay_after_sync;
|
||||||
uint32_t d_samples_per_second;
|
uint32_t d_samples_per_second;
|
||||||
double d_symbols_per_second;
|
double d_symbols_per_second;
|
||||||
uint32_t d_bits_per_symbol;
|
uint32_t d_bits_per_symbol;
|
||||||
|
@ -75,6 +75,7 @@ namespace gr {
|
||||||
std::ofstream d_debug;
|
std::ofstream d_debug;
|
||||||
fftplan d_q;
|
fftplan d_q;
|
||||||
float d_decim_h[DECIMATOR_FILTER_SIZE];
|
float d_decim_h[DECIMATOR_FILTER_SIZE];
|
||||||
|
uint32_t d_corr_decim_factor;
|
||||||
int d_decim_factor;
|
int d_decim_factor;
|
||||||
firdecim_crcf d_decim;
|
firdecim_crcf d_decim;
|
||||||
float d_cfo_estimation;
|
float d_cfo_estimation;
|
||||||
|
@ -106,6 +107,7 @@ namespace gr {
|
||||||
float stddev(const float *values, int len, float mean);
|
float stddev(const float *values, int len, float mean);
|
||||||
inline void instantaneous_phase(const gr_complex* in_samples, float* out_iphase, uint32_t window);
|
inline void instantaneous_phase(const gr_complex* in_samples, float* out_iphase, uint32_t window);
|
||||||
void instantaneous_frequency(const gr_complex* in_samples, float* out_ifreq, uint32_t window);
|
void instantaneous_frequency(const gr_complex* in_samples, float* out_ifreq, uint32_t window);
|
||||||
|
uint8_t lookup_cr(uint8_t bytevalue);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -118,7 +120,7 @@ namespace gr {
|
||||||
gr_vector_void_star &output_items);
|
gr_vector_void_star &output_items);
|
||||||
|
|
||||||
// GRC interfaces
|
// GRC interfaces
|
||||||
virtual void set_finetune(int32_t finetune);
|
virtual void set_sf(uint8_t sf);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lora
|
} // namespace lora
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
namespace gr {
|
namespace gr {
|
||||||
namespace lora {
|
namespace lora {
|
||||||
const uint8_t prng_header[] = {
|
const uint8_t prng_header[] = {
|
||||||
0x22, 0x11, 0x0, 0x0, 0x0
|
0x22, 0x11, 0x00, 0x00, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t prng_payload[] = {
|
const uint8_t prng_payload[] = {
|
||||||
|
|
|
@ -47,6 +47,18 @@ namespace gr {
|
||||||
return (((count+1) % 2) == 0);
|
return (((count+1) % 2) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fec_extract_data_only(uint8_t* in_data, uint32_t len, uint8_t* indices, uint8_t n, uint8_t* out_data) {
|
||||||
|
for(uint32_t i = 0; i < len; i++) {
|
||||||
|
uint8_t d = 0;
|
||||||
|
for(uint32_t j = 0; j < n; j++) {
|
||||||
|
uint8_t power = pow(2, indices[j]);
|
||||||
|
if((in_data[i] & power) > 0) {
|
||||||
|
d += power;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out_data[i] = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,15 +30,15 @@ class lora_receiver(gr.hier_block2):
|
||||||
"""
|
"""
|
||||||
docstring for block lora_receiver
|
docstring for block lora_receiver
|
||||||
"""
|
"""
|
||||||
def __init__(self, in_samp_rate, freq, offset, finetune, realtime):
|
def __init__(self, in_samp_rate, freq, offset, sf, realtime):
|
||||||
gr.hier_block2.__init__(self,
|
gr.hier_block2.__init__(self,
|
||||||
"lora_receiver", # Min, Max, gr.sizeof_<type>
|
"lora_receiver", # Min, Max, gr.sizeof_<type>
|
||||||
gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
|
gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
|
||||||
gr.io_signature(0, 0, 0)) # Output signature
|
gr.io_signature(0, 0, 0)) # Output signature
|
||||||
|
|
||||||
# Parameters
|
# Parameters
|
||||||
self.finetune = finetune
|
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
|
self.sf = sf
|
||||||
self.in_samp_rate = in_samp_rate
|
self.in_samp_rate = in_samp_rate
|
||||||
self.realtime = realtime
|
self.realtime = realtime
|
||||||
bw = 125000
|
bw = 125000
|
||||||
|
@ -47,7 +47,7 @@ class lora_receiver(gr.hier_block2):
|
||||||
null1 = null_sink(gr.sizeof_float)
|
null1 = null_sink(gr.sizeof_float)
|
||||||
null2 = null_sink(gr.sizeof_float)
|
null2 = null_sink(gr.sizeof_float)
|
||||||
if realtime:
|
if realtime:
|
||||||
self.c_decoder = lora.decoder(finetune)
|
self.c_decoder = lora.decoder(sf)
|
||||||
out_samp_rate = 1000000
|
out_samp_rate = 1000000
|
||||||
else:
|
else:
|
||||||
decoder = lora_decoder()
|
decoder = lora_decoder()
|
||||||
|
@ -73,13 +73,13 @@ class lora_receiver(gr.hier_block2):
|
||||||
self.connect((decoder, 0), (null1, 0))
|
self.connect((decoder, 0), (null1, 0))
|
||||||
self.connect((decoder, 1), (null2, 0))
|
self.connect((decoder, 1), (null2, 0))
|
||||||
|
|
||||||
def get_finetune(self):
|
def set_sf(self):
|
||||||
return self.finetune
|
return self.sf
|
||||||
|
|
||||||
def set_finetune(self, finetune):
|
def set_sf(self, sf):
|
||||||
self.finetune = finetune
|
self.sf = sf
|
||||||
if self.realtime:
|
if self.realtime:
|
||||||
self.c_decoder.set_finetune(self.finetune)
|
self.c_decoder.set_sf(self.sf)
|
||||||
|
|
||||||
def get_offset(self):
|
def get_offset(self):
|
||||||
return self.offset
|
return self.offset
|
||||||
|
|
Ładowanie…
Reference in New Issue