kopia lustrzana https://github.com/rpp0/gr-lora
Prototype finished: can receive message using RN2483
rodzic
1d971aa458
commit
3c9a63f1d1
|
@ -50,12 +50,13 @@ namespace gr {
|
|||
set_output_multiple(pow(2,16));
|
||||
|
||||
// Initialize variables
|
||||
d_osr = 4;
|
||||
d_osr = 8;
|
||||
d_samples_per_second = 125000*d_osr;
|
||||
d_num_preamble_symbols = 8;
|
||||
d_bw = 125000;
|
||||
d_explicit = true;
|
||||
d_reduced_rate = false;
|
||||
d_chirp_phi0 = -M_PI;
|
||||
|
||||
d_dt = 1.0f / d_samples_per_second;
|
||||
d_sample_buffer.reserve(d_samples_per_second); // Allocate for one second of samples
|
||||
|
@ -64,20 +65,20 @@ namespace gr {
|
|||
fec_scheme fs = LIQUID_FEC_HAMMING84;
|
||||
d_h48_fec = fec_create(fs, NULL);
|
||||
|
||||
// Setup chirp lookup tables
|
||||
// Setup chirp lookup tables TODO unused now
|
||||
for(uint8_t sf = 6; sf <= 12; sf++) {
|
||||
const uint32_t chips_per_symbol = pow(2, sf);
|
||||
const double symbols_per_second = (double)d_bw / chips_per_symbol;
|
||||
const double samples_per_symbol = d_samples_per_second / symbols_per_second;
|
||||
const double T = -0.5 * d_bw * symbols_per_second;
|
||||
const double f0 = (d_bw / 2.0);
|
||||
const double T = 0.5 * d_bw * symbols_per_second;
|
||||
const double f0 = -(d_bw / 2.0);
|
||||
const double pre_dir = 2.0 * M_PI;
|
||||
double t;
|
||||
|
||||
std::vector<gr_complex> chirp(samples_per_symbol*2);
|
||||
for (uint32_t i = 0u; i < samples_per_symbol; i++) {
|
||||
t = d_dt * i;
|
||||
gr_complex sample = gr_expj(pre_dir * t * (f0 + T * t) * -1.0f);
|
||||
gr_complex sample = gr_expj(pre_dir * t * (f0 + T * t));
|
||||
chirp[i] = sample;
|
||||
chirp[i+samples_per_symbol] = sample;
|
||||
}
|
||||
|
@ -88,6 +89,36 @@ namespace gr {
|
|||
}
|
||||
}
|
||||
|
||||
void encoder_impl::transmit_chirp(bool up, uint8_t sf, uint16_t symbol, bool quarter = false) {
|
||||
const uint32_t chips_per_symbol = pow(2, sf);
|
||||
const double symbols_per_second = (double)d_bw / chips_per_symbol;
|
||||
const uint32_t samples_per_symbol = d_samples_per_second / symbols_per_second;
|
||||
const double T = 0.5 * d_bw * symbols_per_second;
|
||||
const double f0 = -(d_bw / 2.0);
|
||||
double pre_dir = 2.0 * M_PI;
|
||||
double t;
|
||||
|
||||
if(!up)
|
||||
pre_dir *= -1;
|
||||
|
||||
std::vector<gr_complex> chirp(samples_per_symbol);
|
||||
double phase = 0;
|
||||
for (uint32_t i = 0u; i < samples_per_symbol; i++) {
|
||||
t = d_dt * ((i + (d_osr * symbol)) % samples_per_symbol);
|
||||
phase = d_chirp_phi0 + (pre_dir * t * (f0 + T * t));
|
||||
chirp[i] = gr_expj(phase);
|
||||
}
|
||||
|
||||
// Add chirp to buffer
|
||||
if(quarter)
|
||||
d_sample_buffer.insert(d_sample_buffer.end(), chirp.begin(), chirp.begin() + chirp.size() / 4);
|
||||
else
|
||||
d_sample_buffer.insert(d_sample_buffer.end(), chirp.begin(), chirp.end());
|
||||
|
||||
// Set phase
|
||||
d_chirp_phi0 = phase;
|
||||
}
|
||||
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
|
@ -222,28 +253,23 @@ namespace gr {
|
|||
uint32_t num_symbols = num_bytes * ((4.0+conf.phy.cr) / conf.tap.channel.sf) + 0.5;
|
||||
uint32_t encoded_offset = 0;
|
||||
uint32_t packet_offset = 0;
|
||||
std::vector<gr_complex>& upchirp = d_chirps[conf.tap.channel.sf];
|
||||
|
||||
// Add preamble symbols to queue
|
||||
for(uint32_t i = 0; i < d_num_preamble_symbols; i++) {
|
||||
d_sample_buffer.insert(d_sample_buffer.end(), upchirp.begin(), upchirp.begin() + (upchirp.size() / 2));
|
||||
transmit_chirp(true, conf.tap.channel.sf, 0);
|
||||
}
|
||||
|
||||
// Add sync words to queue
|
||||
uint8_t sync_word = 0x12;
|
||||
uint32_t sync_offset_1 = ((sync_word & 0xf0) >> 4) * pow(2, conf.tap.channel.sf) * d_osr / 32;
|
||||
uint32_t sync_offset_2 = (sync_word & 0x0f) * pow(2, conf.tap.channel.sf) * d_osr / 32;
|
||||
d_sample_buffer.insert(d_sample_buffer.end(), upchirp.begin()+sync_offset_1, upchirp.begin()+sync_offset_1 + (upchirp.size() / 2));
|
||||
d_sample_buffer.insert(d_sample_buffer.end(), upchirp.begin()+sync_offset_2, upchirp.begin()+sync_offset_2 + (upchirp.size() / 2));
|
||||
transmit_chirp(true, conf.tap.channel.sf, sync_offset_1);
|
||||
transmit_chirp(true, conf.tap.channel.sf, sync_offset_2);
|
||||
|
||||
// Add SFD to queue
|
||||
std::vector<gr_complex> downchirp(upchirp.size() / 2);
|
||||
for(uint32_t i = 0; i < downchirp.size(); i++) {
|
||||
downchirp[i] = std::conj(upchirp[i]);
|
||||
}
|
||||
d_sample_buffer.insert(d_sample_buffer.end(), downchirp.begin(), downchirp.end());
|
||||
d_sample_buffer.insert(d_sample_buffer.end(), downchirp.begin(), downchirp.end());
|
||||
d_sample_buffer.insert(d_sample_buffer.end(), downchirp.begin(), downchirp.begin() + downchirp.size() / 4.0);
|
||||
transmit_chirp(false, conf.tap.channel.sf, 0);
|
||||
transmit_chirp(false, conf.tap.channel.sf, 0);
|
||||
transmit_chirp(false, conf.tap.channel.sf, 0, true);
|
||||
|
||||
// If explicit header, add one block (= SF codewords) to queue in reduced rate mode (and always 4/8)
|
||||
if(d_explicit) {
|
||||
|
@ -284,7 +310,7 @@ namespace gr {
|
|||
|
||||
// Transmission
|
||||
for(uint32_t i = 0; i < num_symbols; i++) {
|
||||
d_sample_buffer.insert(d_sample_buffer.end(), upchirp.begin() + (symbols[i]*d_osr), upchirp.begin() + (symbols[i]*d_osr) + (upchirp.size() / 2));
|
||||
transmit_chirp(true, conf.tap.channel.sf, symbols[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ namespace gr {
|
|||
double d_dt;
|
||||
uint8_t d_osr;
|
||||
uint16_t d_num_preamble_symbols;
|
||||
double d_chirp_phi0;
|
||||
std::vector<gr_complex> d_sample_buffer;
|
||||
|
||||
public:
|
||||
|
@ -55,6 +56,7 @@ namespace gr {
|
|||
void shuffle(uint8_t *data, uint32_t data_len, const uint8_t *shuffle_pattern);
|
||||
uint32_t interleave_block(uint16_t *symbols, uint8_t* data, uint8_t sf, uint8_t cr, bool reduced_rate);
|
||||
void nibble_swap(uint8_t* encoded, uint32_t length);
|
||||
void transmit_chirp(bool up, uint8_t sf, uint16_t symbol, bool quarter);
|
||||
};
|
||||
|
||||
} // namespace lora
|
||||
|
|
Ładowanie…
Reference in New Issue