kopia lustrzana https://github.com/rpp0/gr-lora
Experimental support for custom bandwidths
rodzic
e8303b9413
commit
a687cce7c5
|
@ -1,28 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<block>
|
|
||||||
<name>channelizer</name>
|
|
||||||
<key>lora_channelizer</key>
|
|
||||||
<category></category>
|
|
||||||
<import>import lora</import>
|
|
||||||
<make>lora.channelizer($in_samp_rate, $out_samp_rate, $center_freq, $channel_list)</make>
|
|
||||||
|
|
||||||
<!-- Make one 'sink' node per input. Sub-nodes:
|
|
||||||
* name (an identifier for the GUI)
|
|
||||||
* type
|
|
||||||
* vlen
|
|
||||||
* optional (set to 1 for optional inputs) -->
|
|
||||||
<sink>
|
|
||||||
<name>in</name>
|
|
||||||
<type>complex</type>
|
|
||||||
</sink>
|
|
||||||
|
|
||||||
<!-- Make one 'source' node per output. Sub-nodes:
|
|
||||||
* name (an identifier for the GUI)
|
|
||||||
* type
|
|
||||||
* vlen
|
|
||||||
* optional (set to 1 for optional inputs) -->
|
|
||||||
<source>
|
|
||||||
<name>out</name>
|
|
||||||
<type>complex</type>
|
|
||||||
</source>
|
|
||||||
</block>
|
|
|
@ -4,15 +4,14 @@
|
||||||
<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, $center_freq, $channel_list, $sf, $out_samp_rate, $implicit, $cr, $crc, $reduced_rate, $conj)</make>
|
<make>lora.lora_receiver($samp_rate, $center_freq, $channel_list, $bandwidth, $sf, $implicit, $cr, $crc, $reduced_rate, $conj, $decimation, $disable_channelization, $disable_drift_correction)</make>
|
||||||
|
|
||||||
<callback>set_center_freq($freq)</callback>
|
<callback>set_center_freq($freq)</callback>
|
||||||
<callback>set_sf($sf)</callback>
|
<callback>set_sf($sf)</callback>
|
||||||
<callback>set_out_samp_rate($out_samp_rate)</callback>
|
|
||||||
|
|
||||||
<param>
|
<param>
|
||||||
<name>Sample rate</name>
|
<name>Sample rate</name>
|
||||||
<key>in_samp_rate</key>
|
<key>samp_rate</key>
|
||||||
<value>1e6</value>
|
<value>1e6</value>
|
||||||
<type>float</type>
|
<type>float</type>
|
||||||
</param>
|
</param>
|
||||||
|
@ -29,6 +28,14 @@
|
||||||
<key>channel_list</key>
|
<key>channel_list</key>
|
||||||
<value>[868.1e6]</value>
|
<value>[868.1e6]</value>
|
||||||
<type>float_vector</type>
|
<type>float_vector</type>
|
||||||
|
<hide>$disable_channelization.hide_channels</hide>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>Bandwidth</name>
|
||||||
|
<key>bandwidth</key>
|
||||||
|
<value>125000</value>
|
||||||
|
<type>int</type>
|
||||||
</param>
|
</param>
|
||||||
|
|
||||||
<param>
|
<param>
|
||||||
|
@ -115,10 +122,35 @@
|
||||||
</param>
|
</param>
|
||||||
|
|
||||||
<param>
|
<param>
|
||||||
<name>Output sample rate</name>
|
<name>Decimation</name>
|
||||||
<key>out_samp_rate</key>
|
<key>decimation</key>
|
||||||
<value>1000000</value>
|
<value>1</value>
|
||||||
<type>float</type>
|
<type>int</type>
|
||||||
|
<hide>part</hide>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>Disable channelization</name>
|
||||||
|
<key>disable_channelization</key>
|
||||||
|
<type>enum</type>
|
||||||
|
<hide>part</hide>
|
||||||
|
<option>
|
||||||
|
<name>No</name>
|
||||||
|
<key>False</key>
|
||||||
|
<opt>hide_channels:</opt>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>Yes</name>
|
||||||
|
<key>True</key>
|
||||||
|
<opt>hide_channels:all</opt>
|
||||||
|
</option>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>Disable drift correction</name>
|
||||||
|
<key>disable_drift_correction</key>
|
||||||
|
<value>False</value>
|
||||||
|
<type>bool</type>
|
||||||
<hide>part</hide>
|
<hide>part</hide>
|
||||||
</param>
|
</param>
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace gr {
|
||||||
* class. lora::channelizer::make is the public interface for
|
* class. lora::channelizer::make is the public interface for
|
||||||
* creating new instances.
|
* creating new instances.
|
||||||
*/
|
*/
|
||||||
static sptr make(float in_samp_rate, float out_samp_rate, float center_freq, std::vector<float> channel_list);
|
static sptr make(float samp_rate, float center_freq, std::vector<float> channel_list, uint32_t bandwidth, uint32_t decimation);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lora
|
} // namespace lora
|
||||||
|
|
|
@ -702,7 +702,7 @@ 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(float samp_rate, int sf, bool implicit, uint8_t cr, bool crc, bool reduced_rate);
|
static sptr make(float samp_rate, uint32_t bandwidth, uint8_t sf, bool implicit, uint8_t cr, bool crc, bool reduced_rate, bool disable_drift_correction);
|
||||||
|
|
||||||
virtual void set_sf(uint8_t sf) = 0;
|
virtual void set_sf(uint8_t sf) = 0;
|
||||||
virtual void set_samp_rate(float samp_rate) = 0;
|
virtual void set_samp_rate(float samp_rate) = 0;
|
||||||
|
|
|
@ -29,32 +29,31 @@ namespace gr {
|
||||||
namespace lora {
|
namespace lora {
|
||||||
|
|
||||||
channelizer::sptr
|
channelizer::sptr
|
||||||
channelizer::make(float in_samp_rate, float out_samp_rate, float center_freq, std::vector<float> channel_list) {
|
channelizer::make(float samp_rate, float center_freq, std::vector<float> channel_list, uint32_t bandwidth, uint32_t decimation) {
|
||||||
return gnuradio::get_initial_sptr
|
return gnuradio::get_initial_sptr
|
||||||
(new channelizer_impl(in_samp_rate, out_samp_rate, center_freq, channel_list));
|
(new channelizer_impl(samp_rate, center_freq, channel_list, bandwidth, decimation));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The private constructor
|
* The private constructor
|
||||||
*/
|
*/
|
||||||
channelizer_impl::channelizer_impl(float in_samp_rate, float out_samp_rate, float center_freq, std::vector<float> channel_list)
|
channelizer_impl::channelizer_impl(float samp_rate, float center_freq, std::vector<float> channel_list, uint32_t bandwidth, uint32_t decimation)
|
||||||
: gr::hier_block2("channelizer",
|
: gr::hier_block2("channelizer",
|
||||||
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
||||||
gr::io_signature::make(channel_list.size(), channel_list.size(), sizeof(gr_complex))),
|
gr::io_signature::make(channel_list.size(), channel_list.size(), sizeof(gr_complex))),
|
||||||
d_cfo(0.0)
|
d_cfo(0.0)
|
||||||
{
|
{
|
||||||
d_lpf = gr::filter::firdes::low_pass(1.0, out_samp_rate, 62500+15000, 10000, gr::filter::firdes::WIN_HAMMING, 6.67);
|
d_lpf = gr::filter::firdes::low_pass(1.0, samp_rate, (bandwidth/2)+15000, 10000, gr::filter::firdes::WIN_HAMMING, 6.67);
|
||||||
d_freq_offset = channel_list[0] - center_freq;
|
d_freq_offset = channel_list[0] - center_freq;
|
||||||
d_xlating_fir_filter = gr::filter::freq_xlating_fir_filter_ccf::make(1, d_lpf, d_freq_offset, out_samp_rate);
|
d_xlating_fir_filter = gr::filter::freq_xlating_fir_filter_ccf::make(decimation, d_lpf, d_freq_offset, samp_rate);
|
||||||
d_controller = gr::lora::controller::make((void*)this);
|
d_controller = gr::lora::controller::make((void*)this);
|
||||||
d_resampler = gr::filter::fractional_resampler_cc::make(0, (float)in_samp_rate / (float)out_samp_rate);
|
//d_resampler = gr::filter::fractional_resampler_cc::make(0, (float)in_samp_rate / (float)out_samp_rate);
|
||||||
//self.delay = delay(gr.sizeof_gr_complex, int((len(lpf)-1) / 2.0))
|
//self.delay = delay(gr.sizeof_gr_complex, int((len(lpf)-1) / 2.0))
|
||||||
|
|
||||||
//Create message ports
|
//Create message ports
|
||||||
message_port_register_hier_in(pmt::intern("control"));
|
message_port_register_hier_in(pmt::intern("control"));
|
||||||
|
|
||||||
connect(self(), 0, d_resampler, 0);
|
connect(self(), 0, d_xlating_fir_filter, 0);
|
||||||
connect(d_resampler, 0, d_xlating_fir_filter, 0);
|
|
||||||
connect(d_xlating_fir_filter, 0, self(), 0);
|
connect(d_xlating_fir_filter, 0, self(), 0);
|
||||||
|
|
||||||
msg_connect(self(), pmt::intern("control"), d_controller, pmt::intern("control"));
|
msg_connect(self(), pmt::intern("control"), d_controller, pmt::intern("control"));
|
||||||
|
|
|
@ -33,14 +33,14 @@ namespace gr {
|
||||||
class channelizer_impl : public channelizer {
|
class channelizer_impl : public channelizer {
|
||||||
private:
|
private:
|
||||||
gr::filter::freq_xlating_fir_filter_ccf::sptr d_xlating_fir_filter;
|
gr::filter::freq_xlating_fir_filter_ccf::sptr d_xlating_fir_filter;
|
||||||
gr::filter::fractional_resampler_cc::sptr d_resampler;
|
//gr::filter::fractional_resampler_cc::sptr d_resampler;
|
||||||
std::vector<float> d_lpf;
|
std::vector<float> d_lpf;
|
||||||
float d_cfo;
|
float d_cfo;
|
||||||
uint32_t d_freq_offset;
|
uint32_t d_freq_offset;
|
||||||
gr::lora::controller::sptr d_controller;
|
gr::lora::controller::sptr d_controller;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
channelizer_impl(float in_samp_rate, float out_samp_rate, float center_freq, std::vector<float> channel_list);
|
channelizer_impl(float samp_rate, float center_freq, std::vector<float> channel_list, uint32_t bandwidth, uint32_t decimation);
|
||||||
~channelizer_impl();
|
~channelizer_impl();
|
||||||
void apply_cfo(float cfo);
|
void apply_cfo(float cfo);
|
||||||
|
|
||||||
|
|
|
@ -37,15 +37,15 @@
|
||||||
namespace gr {
|
namespace gr {
|
||||||
namespace lora {
|
namespace lora {
|
||||||
|
|
||||||
decoder::sptr decoder::make(float samp_rate, int sf, bool implicit, uint8_t cr, bool crc, bool reduced_rate) {
|
decoder::sptr decoder::make(float samp_rate, uint32_t bandwidth, uint8_t sf, bool implicit, uint8_t cr, bool crc, bool reduced_rate, bool disable_drift_correction) {
|
||||||
return gnuradio::get_initial_sptr
|
return gnuradio::get_initial_sptr
|
||||||
(new decoder_impl(samp_rate, sf, implicit, cr, crc, reduced_rate));
|
(new decoder_impl(samp_rate, bandwidth, sf, implicit, cr, crc, reduced_rate, disable_drift_correction));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The private constructor
|
* The private constructor
|
||||||
*/
|
*/
|
||||||
decoder_impl::decoder_impl(float samp_rate, uint8_t sf, bool implicit, uint8_t cr, bool crc, bool reduced_rate)
|
decoder_impl::decoder_impl(float samp_rate, uint32_t bandwidth, uint8_t sf, bool implicit, uint8_t cr, bool crc, bool reduced_rate, bool disable_drift_correction)
|
||||||
: gr::sync_block("decoder",
|
: 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, 0, 0)),
|
gr::io_signature::make(0, 0, 0)),
|
||||||
|
@ -65,7 +65,7 @@ namespace gr {
|
||||||
d_dbg.attach();
|
d_dbg.attach();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
d_bw = 125000u;
|
d_bw = bandwidth;
|
||||||
d_implicit = implicit;
|
d_implicit = implicit;
|
||||||
d_reduced_rate = reduced_rate;
|
d_reduced_rate = reduced_rate;
|
||||||
d_phdr.cr = cr;
|
d_phdr.cr = cr;
|
||||||
|
@ -87,12 +87,16 @@ namespace gr {
|
||||||
d_energy_threshold = 0.0f;
|
d_energy_threshold = 0.0f;
|
||||||
d_whitening_sequence = gr::lora::prng_payload;
|
d_whitening_sequence = gr::lora::prng_payload;
|
||||||
d_fine_sync = 0;
|
d_fine_sync = 0;
|
||||||
|
d_enable_fine_sync = !disable_drift_correction;
|
||||||
set_output_multiple(2 * d_samples_per_symbol);
|
set_output_multiple(2 * d_samples_per_symbol);
|
||||||
|
|
||||||
std::cout << "Bits (nominal) per symbol: \t" << d_bits_per_symbol << std::endl;
|
std::cout << "Bits (nominal) per symbol: \t" << d_bits_per_symbol << std::endl;
|
||||||
std::cout << "Bins per symbol: \t" << d_number_of_bins << std::endl;
|
std::cout << "Bins per symbol: \t" << d_number_of_bins << std::endl;
|
||||||
std::cout << "Samples per symbol: \t" << d_samples_per_symbol << std::endl;
|
std::cout << "Samples per symbol: \t" << d_samples_per_symbol << std::endl;
|
||||||
std::cout << "Decimation: \t\t" << d_decim_factor << std::endl;
|
std::cout << "Decimation: \t\t" << d_decim_factor << std::endl;
|
||||||
|
if(!d_enable_fine_sync) {
|
||||||
|
std::cout << "Warning: clock drift correction disabled" << std::endl;
|
||||||
|
}
|
||||||
if(d_implicit) {
|
if(d_implicit) {
|
||||||
std::cout << "CR: \t\t" << (int)d_phdr.cr << std::endl;
|
std::cout << "CR: \t\t" << (int)d_phdr.cr << std::endl;
|
||||||
std::cout << "CRC: \t\t" << (int)d_phdr.has_mac_crc << std::endl;
|
std::cout << "CRC: \t\t" << (int)d_phdr.has_mac_crc << std::endl;
|
||||||
|
@ -481,7 +485,8 @@ namespace gr {
|
||||||
|
|
||||||
uint32_t bin_idx = max_frequency_gradient_idx(samples);
|
uint32_t bin_idx = max_frequency_gradient_idx(samples);
|
||||||
//uint32_t bin_idx = get_shift_fft(samples);
|
//uint32_t bin_idx = get_shift_fft(samples);
|
||||||
fine_sync(samples, bin_idx, std::max(d_decim_factor / 4u, 2u));
|
if(d_enable_fine_sync)
|
||||||
|
fine_sync(samples, bin_idx, std::max(d_decim_factor / 4u, 2u));
|
||||||
|
|
||||||
// DBGR_INTERMEDIATE_TIME_MEASUREMENT();
|
// DBGR_INTERMEDIATE_TIME_MEASUREMENT();
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,8 @@ namespace gr {
|
||||||
uint32_t d_decim_factor; ///< The number of samples (data points) in each bin.
|
uint32_t d_decim_factor; ///< The number of samples (data points) in each bin.
|
||||||
float d_cfo_estimation; ///< An estimation for the current Center Frequency Offset.
|
float d_cfo_estimation; ///< An estimation for the current Center Frequency Offset.
|
||||||
double d_dt; ///< Indicates how fast the frequency changes in a symbol (chirp).
|
double d_dt; ///< Indicates how fast the frequency changes in a symbol (chirp).
|
||||||
int32_t d_fine_sync;
|
bool d_enable_fine_sync; ///< Enable drift correction
|
||||||
|
int32_t d_fine_sync; ///< Amount of drift correction to apply for next symbol
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief TODO
|
* \brief TODO
|
||||||
|
@ -415,7 +416,7 @@ namespace gr {
|
||||||
* \param sf
|
* \param sf
|
||||||
* The expected spreqding factor.
|
* The expected spreqding factor.
|
||||||
*/
|
*/
|
||||||
decoder_impl(float samp_rate, uint8_t sf, bool implicit, uint8_t cr, bool crc, bool reduced_rate);
|
decoder_impl(float samp_rate, uint32_t bandwidth, uint8_t sf, bool implicit, uint8_t cr, bool crc, bool reduced_rate, bool disable_drift_correction);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default destructor.
|
* Default destructor.
|
||||||
|
|
|
@ -27,37 +27,52 @@ class lora_receiver(gr.hier_block2):
|
||||||
"""
|
"""
|
||||||
docstring for block lora_receiver
|
docstring for block lora_receiver
|
||||||
"""
|
"""
|
||||||
def __init__(self, in_samp_rate, center_freq, channel_list, sf, out_samp_rate, implicit, cr, crc, reduced_rate=False, conj=False):
|
def __init__(self, samp_rate, center_freq, channel_list, bandwidth, sf, implicit, cr, crc, reduced_rate=False, conj=False, decimation=1, disable_channelization=False, disable_drift_correction=False):
|
||||||
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.in_samp_rate = in_samp_rate
|
self.samp_rate = samp_rate
|
||||||
self.center_freq = center_freq
|
self.center_freq = center_freq
|
||||||
self.sf = sf
|
|
||||||
self.out_samp_rate = out_samp_rate
|
|
||||||
self.channel_list = channel_list
|
self.channel_list = channel_list
|
||||||
|
self.bandwidth = bandwidth
|
||||||
|
self.sf = sf
|
||||||
|
self.implicit = implicit
|
||||||
|
self.cr = cr
|
||||||
|
self.crc = crc
|
||||||
|
self.decimation = decimation
|
||||||
self.conj = conj
|
self.conj = conj
|
||||||
|
self.disable_channelization = disable_channelization
|
||||||
|
self.disable_drift_correction = disable_drift_correction
|
||||||
|
|
||||||
# Define blocks
|
# Define blocks
|
||||||
self.block_conj = gnuradio.blocks.conjugate_cc()
|
self.block_conj = gnuradio.blocks.conjugate_cc()
|
||||||
self.channelizer = lora.channelizer(in_samp_rate, out_samp_rate, center_freq, channel_list)
|
self.channelizer = lora.channelizer(samp_rate, center_freq, channel_list, bandwidth, decimation)
|
||||||
self.decoder = lora.decoder(out_samp_rate, sf, implicit, cr, crc, reduced_rate)
|
self.decoder = lora.decoder(samp_rate / decimation, bandwidth, sf, implicit, cr, crc, reduced_rate, disable_drift_correction)
|
||||||
|
|
||||||
# Messages
|
# Messages
|
||||||
self.message_port_register_hier_out('frames')
|
self.message_port_register_hier_out('frames')
|
||||||
|
|
||||||
# Connect blocks
|
# Connect blocks
|
||||||
self.connect((self, 0), (self.channelizer, 0))
|
if self.disable_channelization:
|
||||||
if self.conj:
|
self.resampler = gnuradio.filter.fractional_resampler_cc(0, float(decimation))
|
||||||
self.connect((self.channelizer, 0), (self.block_conj, 0))
|
self.connect((self, 0), (self.resampler, 0))
|
||||||
self.connect((self.block_conj, 0), (self.decoder, 0))
|
self._connect_conj_block_if_enabled(self.resampler, self.decoder)
|
||||||
else:
|
else:
|
||||||
self.connect((self.channelizer, 0), (self.decoder, 0))
|
self.connect((self, 0), (self.channelizer, 0))
|
||||||
|
self._connect_conj_block_if_enabled(self.channelizer, self.decoder)
|
||||||
|
self.msg_connect((self.decoder, 'control'), (self.channelizer, 'control'))
|
||||||
|
|
||||||
self.msg_connect((self.decoder, 'frames'), (self, 'frames'))
|
self.msg_connect((self.decoder, 'frames'), (self, 'frames'))
|
||||||
self.msg_connect((self.decoder, 'control'), (self.channelizer, 'control'))
|
|
||||||
|
def _connect_conj_block_if_enabled(self, source, dest):
|
||||||
|
if self.conj:
|
||||||
|
self.connect((source, 0), (self.block_conj, 0))
|
||||||
|
self.connect((self.block_conj, 0), (dest, 0))
|
||||||
|
else:
|
||||||
|
self.connect((source, 0), (dest, 0))
|
||||||
|
|
||||||
def get_sf(self):
|
def get_sf(self):
|
||||||
return self.sf
|
return self.sf
|
||||||
|
|
Ładowanie…
Reference in New Issue