From 3c9a63f1d148592df2b715496c67ccbc2939ad0d Mon Sep 17 00:00:00 2001 From: Pieter Robyns Date: Thu, 17 May 2018 16:21:00 +0200 Subject: [PATCH] Prototype finished: can receive message using RN2483 --- lib/encoder_impl.cc | 60 ++++++++++++++++++++++++++++++++------------- lib/encoder_impl.h | 2 ++ 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/lib/encoder_impl.cc b/lib/encoder_impl.cc index 30d2b20..39b0eb2 100644 --- a/lib/encoder_impl.cc +++ b/lib/encoder_impl.cc @@ -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 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 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& 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 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]); } } diff --git a/lib/encoder_impl.h b/lib/encoder_impl.h index ab2ab3f..2fd53b9 100644 --- a/lib/encoder_impl.h +++ b/lib/encoder_impl.h @@ -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 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