From d899cadebc18d9adbc7371cc550c7df1dc4b653d Mon Sep 17 00:00:00 2001 From: tapparelj Date: Tue, 9 Jul 2024 15:50:01 +0200 Subject: [PATCH 1/4] add tags for lorawan support --- grc/lora_sdr_whitening.block.yml | 4 ++- lib/add_crc_impl.cc | 5 +++ lib/gray_demap_impl.cc | 15 +++++++- lib/gray_demap_impl.h | 1 + lib/hamming_enc_impl.cc | 18 ++++++++++ lib/header_impl.cc | 17 ++++++--- lib/interleaver_impl.cc | 55 ++++++++++++++++++++++++---- lib/interleaver_impl.h | 5 ++- lib/modulate_impl.cc | 62 ++++++++++++++++++++++---------- lib/modulate_impl.h | 4 ++- lib/whitening_impl.cc | 20 +++++++++-- lib/whitening_impl.h | 4 ++- 12 files changed, 174 insertions(+), 36 deletions(-) diff --git a/grc/lora_sdr_whitening.block.yml b/grc/lora_sdr_whitening.block.yml index a4c2373e..d7836cfb 100644 --- a/grc/lora_sdr_whitening.block.yml +++ b/grc/lora_sdr_whitening.block.yml @@ -29,7 +29,7 @@ parameters: label: is_hex dtype: bool default: false - hide: ${ ( 'none' if (str(source_type) == "file_source" and use_length_tag == 'False') else 'all') } + hide: part inputs: - domain: stream @@ -40,6 +40,8 @@ inputs: id: msg optional: ${ ( False if str(source_type) == "message_strobe" else True) } hide: ${ ( False if str(source_type) == "message_strobe" else True) } +- label: dict + domain: message outputs: - domain: stream dtype: byte diff --git a/lib/add_crc_impl.cc b/lib/add_crc_impl.cc index d74bc0de..caafbc5c 100644 --- a/lib/add_crc_impl.cc +++ b/lib/add_crc_impl.cc @@ -100,6 +100,11 @@ namespace gr m_frame_len = pmt::to_long(tags[0].value); tags[0].offset = nitems_written(0); tags[0].value = pmt::from_long(m_frame_len + (m_has_crc ? 4 : 0)); + if (nitems_to_process) + add_item_tag(0, tags[0]); + + get_tags_in_window(tags, 0, 0, ninput_items[0], pmt::string_to_symbol("configuration")); + tags[0].offset = nitems_written(0); if (nitems_to_process) add_item_tag(0, tags[0]); diff --git a/lib/gray_demap_impl.cc b/lib/gray_demap_impl.cc index c60f40e6..b11cd712 100644 --- a/lib/gray_demap_impl.cc +++ b/lib/gray_demap_impl.cc @@ -25,7 +25,7 @@ namespace gr { gr::io_signature::make(1, 1, sizeof(uint32_t)), gr::io_signature::make(1, 1, sizeof(uint32_t))) { - m_sf=sf; + m_sf = sf; set_tag_propagation_policy(TPP_ONE_TO_ONE); } @@ -46,6 +46,19 @@ namespace gr { { const uint32_t *in = (const uint32_t *) input_items[0]; uint32_t *out = (uint32_t *) output_items[0]; + + std::vector tags; + + get_tags_in_window(tags, 0, 0, noutput_items, pmt::string_to_symbol("configuration")); + if (tags.size() > 0) { + //Update cr and sf + pmt::pmt_t err_sf = pmt::string_to_symbol("error"); + int new_sf = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("sf"), err_sf)); + if (new_sf != m_sf) { + m_sf = new_sf; + // std::cout<<"New sf gray demap "<< static_cast(m_sf) < "; diff --git a/lib/gray_demap_impl.h b/lib/gray_demap_impl.h index fb693fdf..1e4679ad 100644 --- a/lib/gray_demap_impl.h +++ b/lib/gray_demap_impl.h @@ -16,6 +16,7 @@ namespace gr { gray_demap_impl(uint8_t sf); ~gray_demap_impl(); void set_sf(uint8_t sf); + void frame_info_handler(pmt::pmt_t frame_info); int work( int noutput_items, diff --git a/lib/hamming_enc_impl.cc b/lib/hamming_enc_impl.cc index 6c5bc5b9..760cd6f1 100644 --- a/lib/hamming_enc_impl.cc +++ b/lib/hamming_enc_impl.cc @@ -63,6 +63,24 @@ namespace gr // read tags std::vector tags; + get_tags_in_window(tags, 0, 0, noutput_items, pmt::string_to_symbol("configuration")); + + if (tags.size() > 0) { + // Update cr and sf + pmt::pmt_t err = pmt::string_to_symbol("error"); + int new_cr = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("cr"), err)); + int new_sf = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("sf"), err)); + if (new_cr != m_cr) { + m_cr = new_cr; + // std::cout<<"New cr Hamming "<< static_cast(m_cr) <(m_sf) <= 2) + if (tags.size() >= 2) //2 nitems_to_process = std::min(tags[1].offset - tags[0].offset, (uint64_t)noutput_items); m_payload_len = int(pmt::to_long(tags[0].value) / 2); @@ -90,6 +90,15 @@ namespace gr m_cnt_nibbles = 0; m_tags[1] = tags[0]; + get_tags_in_window(tags, 0, 0, 1, pmt::string_to_symbol("configuration")); + tags[0].offset = nitems_written(0); + m_tags[2] = tags[0]; + + pmt::pmt_t err = pmt::string_to_symbol("error"); + int new_cr = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("cr"), err)); + if (new_cr != m_cr) { + m_cr = new_cr; + } } } @@ -120,6 +129,7 @@ namespace gr //add tag add_item_tag(0, m_tags[0]); add_item_tag(0, m_tags[1]); + add_item_tag(0, m_tags[2]); } for (int i = 0; i < nitems_to_process; i++) @@ -141,6 +151,7 @@ namespace gr { add_item_tag(0, m_tags[0]); add_item_tag(0, m_tags[1]); + add_item_tag(0, m_tags[2]); } for (int i = out_offset; i < nitems_to_process; i++) { @@ -148,8 +159,6 @@ namespace gr m_cnt_nibbles++; m_cnt_header_nibbles = 0; } - - consume_each(nitems_to_process - out_offset); return nitems_to_process; } diff --git a/lib/interleaver_impl.cc b/lib/interleaver_impl.cc index 354f2d80..a992d28c 100644 --- a/lib/interleaver_impl.cc +++ b/lib/interleaver_impl.cc @@ -28,11 +28,14 @@ namespace gr m_sf = sf; m_cr = cr; m_bw = bw; - if (ldro == AUTO) + if (ldro == AUTO){ m_ldro = (float)(1u< LDRO_MAX_DURATION_MS; + } else + { m_ldro = ldro; - + } + ldro_pass = ldro; cw_cnt = 0; set_tag_propagation_policy(TPP_DONT); @@ -63,6 +66,29 @@ namespace gr ninput_items_required[0] = 1; } + void interleaver_impl::update_var(int new_cr, int new_sf, int new_bw, bool ldro_pass) + { + if (new_cr != m_cr) { + m_cr = new_cr; + // std::cout<<"New cr Interleaver "<< static_cast(m_cr) <(m_sf) <(m_bw) < LDRO_MAX_DURATION_MS; + m_ldro = (float)(1u< LDRO_MAX_DURATION_MS; + } + else { + m_ldro = ldro_pass; + } + } + int interleaver_impl::general_work(int noutput_items, gr_vector_int &ninput_items, @@ -87,8 +113,22 @@ namespace gr } cw_cnt = 0; m_frame_len = pmt::to_long(tags[0].value); - tags[0].value = pmt::from_long(8 + std::max((int)std::ceil((double)(m_frame_len - m_sf + 2) / (m_sf-2*m_ldro)) * (m_cr + 4), 0)); //get number of items in frame - tags[0].offset = nitems_written(0); + m_framelen_tag = tags[0]; + get_tags_in_window(tags, 0, 0, 1, pmt::string_to_symbol("configuration")); + m_config_tag = tags[0]; + m_config_tag.offset = nitems_written(0); + + pmt::pmt_t err_cr = pmt::string_to_symbol("error"); + pmt::pmt_t err_sf = pmt::string_to_symbol("error"); + pmt::pmt_t err_bw = pmt::string_to_symbol("error"); + int new_cr = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("cr"), err_cr)); + int new_sf = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("sf"), err_sf)); + int new_bw = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("bw"), err_bw)); + update_var(new_cr, new_sf, new_bw, ldro_pass); + // std::cout<<"update tag"<(m_sf) <= sf_app || cw_cnt + nitems_to_process == (uint32_t)m_frame_len) { //propagate tag - if(!cw_cnt) - add_item_tag(0, tags[0]); - + if(!cw_cnt){ + add_item_tag(0, m_framelen_tag); + add_item_tag(0, m_config_tag); + } //Create the empty matrices std::vector> cw_bin(sf_app); std::vector init_bit(m_sf, 0); diff --git a/lib/interleaver_impl.h b/lib/interleaver_impl.h index f02bb801..1a3c2310 100644 --- a/lib/interleaver_impl.h +++ b/lib/interleaver_impl.h @@ -17,6 +17,9 @@ namespace gr { int m_frame_len; ///(m_sf) <(m_bw) <(m_bw) < sync_words, uint32_t frame_zero_padd, uint16_t preamb_len); @@ -50,7 +52,7 @@ namespace gr { // Where all the action really happens void forecast (int noutput_items, gr_vector_int &ninput_items_required); - + void update_var(int new_sf, int new_bw); int general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, diff --git a/lib/whitening_impl.cc b/lib/whitening_impl.cc index 24711654..5dc87900 100644 --- a/lib/whitening_impl.cc +++ b/lib/whitening_impl.cc @@ -34,9 +34,13 @@ namespace gr m_is_hex = use_length_tag?false:is_hex;// cant use length tag if input is given as a string of hex values m_tag_offset = 1; + message_port_register_in(pmt::mp("dict")); + set_msg_handler(pmt::mp("dict"), [this](pmt::pmt_t dict) + { this->frame_info_handler(dict); }); + message_port_register_in(pmt::mp("msg")); set_msg_handler(pmt::mp("msg"), [this](pmt::pmt_t msg) - { this->msg_handler(msg); }); + { this->msg_handler(msg); }); } /* @@ -53,13 +57,25 @@ namespace gr // payload_str.push_back(random_string(rand()%253+2)); // payload_str.push_back(rand()%2?"12345":"abcdefghijklmnop"); payload_str.push_back(pmt::symbol_to_string(message)); - // std::copy(payload_str.begin(), payload_str.end(), std::back_inserter(m_payload)); + } + void whitening_impl::frame_info_handler(pmt::pmt_t frame_info) + { + // std::cout<<" info "< lock(m_payload_mutex); // check if input file is used uint8_t *in; if (input_items.size()) diff --git a/lib/whitening_impl.h b/lib/whitening_impl.h index db172720..9f3d6f3a 100644 --- a/lib/whitening_impl.h +++ b/lib/whitening_impl.h @@ -22,8 +22,10 @@ namespace gr std::string m_length_tag_name; ///< name/key of the length tag int m_input_byte_cnt; ///< number of bytes from the input already processed uint64_t m_tag_offset; ///< offset of the length tag - + void msg_handler(pmt::pmt_t message); + void frame_info_handler(pmt::pmt_t frame_info); + public: whitening_impl(bool is_hex, bool use_length_tag, char separator, std::string length_tag_name); From caad32deb0e454db8fe8b872605c0087b4355151 Mon Sep 17 00:00:00 2001 From: tapparelj Date: Tue, 9 Jul 2024 17:20:39 +0200 Subject: [PATCH 2/4] fixed optional configuration tags --- examples/tx_rx_functionality_check.grc | 24 +++++++------- examples/tx_rx_functionality_check.py | 10 +++--- grc/lora_sdr_modulate.block.yml | 2 -- grc/lora_sdr_whitening.block.yml | 2 ++ include/gnuradio/lora_sdr/modulate.h | 1 - lib/add_crc_impl.cc | 8 +++-- lib/header_impl.cc | 25 +++++++++------ lib/header_impl.h | 2 ++ lib/interleaver_impl.cc | 31 ++++++++++++------- lib/interleaver_impl.h | 1 + lib/modulate_impl.cc | 19 +++++++----- .../docstrings/modulate_pydoc_template.h | 8 ++--- python/lora_sdr/bindings/modulate_python.cc | 6 ++-- 13 files changed, 79 insertions(+), 60 deletions(-) diff --git a/examples/tx_rx_functionality_check.grc b/examples/tx_rx_functionality_check.grc index a2059c8a..136e5315 100644 --- a/examples/tx_rx_functionality_check.grc +++ b/examples/tx_rx_functionality_check.grc @@ -85,7 +85,7 @@ blocks: id: variable parameters: comment: '' - value: '0' + value: '1' states: bus_sink: false bus_source: false @@ -206,7 +206,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1448, 240.0] + coordinate: [1448, 236.0] rotation: 0 state: true - name: blocks_message_strobe_0_0 @@ -223,26 +223,28 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [120, 228.0] + coordinate: [128, 212.0] rotation: 0 state: enabled -- name: blocks_throttle_0 - id: blocks_throttle +- name: blocks_throttle2_0 + id: blocks_throttle2 parameters: affinity: '' alias: '' comment: '' ignoretag: 'True' + limit: auto + maximum: '0.1' maxoutbuf: '0' minoutbuf: '0' - samples_per_second: samp_rate*10 + samples_per_second: samp_rate type: complex vlen: '1' states: bus_sink: false bus_source: false bus_structure: null - coordinate: [1584, 244.0] + coordinate: [1600, 228.0] rotation: 0 state: enabled - name: channels_channel_model_0 @@ -527,7 +529,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [152, 172.0] + coordinate: [160, 156.0] rotation: 180 state: enabled - name: lora_sdr_whitening_0 @@ -547,15 +549,15 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [392, 236.0] + coordinate: [392, 224.0] rotation: 0 state: true connections: -- [blocks_delay_0, '0', blocks_throttle_0, '0'] +- [blocks_delay_0, '0', blocks_throttle2_0, '0'] - [blocks_message_strobe_0_0, strobe, lora_sdr_payload_id_inc_0, msg_in] - [blocks_message_strobe_0_0, strobe, lora_sdr_whitening_0, msg] -- [blocks_throttle_0, '0', channels_channel_model_0, '0'] +- [blocks_throttle2_0, '0', channels_channel_model_0, '0'] - [channels_channel_model_0, '0', lora_sdr_frame_sync_0, '0'] - [lora_sdr_add_crc_0, '0', lora_sdr_hamming_enc_0, '0'] - [lora_sdr_deinterleaver_0, '0', lora_sdr_hamming_dec_0, '0'] diff --git a/examples/tx_rx_functionality_check.py b/examples/tx_rx_functionality_check.py index 8e22af53..ae753c9a 100755 --- a/examples/tx_rx_functionality_check.py +++ b/examples/tx_rx_functionality_check.py @@ -42,7 +42,7 @@ def __init__(self): self.pay_len = pay_len = 255 self.impl_head = impl_head = False self.has_crc = has_crc = True - self.cr = cr = 0 + self.cr = cr = 1 self.clk_offset = clk_offset = 0 self.center_freq = center_freq = 868.1e6 self.SNRdB = SNRdB = -5 @@ -76,7 +76,7 @@ def __init__(self): noise_seed=0, block_tags=True) self.channels_channel_model_0.set_min_output_buffer((int((2**sf+2)*samp_rate/bw))) - self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, (samp_rate*10),True) + self.blocks_throttle2_0 = blocks.throttle( gr.sizeof_gr_complex*1, samp_rate, True, 0 if "auto" == "auto" else max( int(float(0.1) * samp_rate) if "auto" == "time" else int(0.1), 1) ) self.blocks_message_strobe_0_0 = blocks.message_strobe(pmt.intern("Hello world: 0"), 2000) self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, (int(2**sf*samp_rate/bw*10.1))) @@ -88,8 +88,8 @@ def __init__(self): self.msg_connect((self.blocks_message_strobe_0_0, 'strobe'), (self.lora_sdr_whitening_0, 'msg')) self.msg_connect((self.lora_sdr_header_decoder_0, 'frame_info'), (self.lora_sdr_frame_sync_0, 'frame_info')) self.msg_connect((self.lora_sdr_payload_id_inc_0, 'msg_out'), (self.blocks_message_strobe_0_0, 'set_msg')) - self.connect((self.blocks_delay_0, 0), (self.blocks_throttle_0, 0)) - self.connect((self.blocks_throttle_0, 0), (self.channels_channel_model_0, 0)) + self.connect((self.blocks_delay_0, 0), (self.blocks_throttle2_0, 0)) + self.connect((self.blocks_throttle2_0, 0), (self.channels_channel_model_0, 0)) self.connect((self.channels_channel_model_0, 0), (self.lora_sdr_frame_sync_0, 0)) self.connect((self.lora_sdr_add_crc_0, 0), (self.lora_sdr_hamming_enc_0, 0)) self.connect((self.lora_sdr_deinterleaver_0, 0), (self.lora_sdr_hamming_dec_0, 0)) @@ -144,7 +144,7 @@ def get_samp_rate(self): def set_samp_rate(self, samp_rate): self.samp_rate = samp_rate self.blocks_delay_0.set_dly(int((int(2**self.sf*self.samp_rate/self.bw*10.1)))) - self.blocks_throttle_0.set_sample_rate((self.samp_rate*10)) + self.blocks_throttle2_0.set_sample_rate(self.samp_rate) self.channels_channel_model_0.set_frequency_offset((self.center_freq*self.clk_offset*1e-6/self.samp_rate)) def get_preamb_len(self): diff --git a/grc/lora_sdr_modulate.block.yml b/grc/lora_sdr_modulate.block.yml index c5c4eac0..8aab8066 100644 --- a/grc/lora_sdr_modulate.block.yml +++ b/grc/lora_sdr_modulate.block.yml @@ -42,8 +42,6 @@ outputs: templates: imports: import gnuradio.lora_sdr as lora_sdr make: lora_sdr.modulate(${sf}, ${samp_rate}, ${bw}, ${sync_words}, ${frame_zero_padd},${preamb_len}) - callbacks: - - set_sf(${sf}) asserts: - ${ (samp_rate/bw).is_integer()} - ${frame_zero_padd>=0} diff --git a/grc/lora_sdr_whitening.block.yml b/grc/lora_sdr_whitening.block.yml index d7836cfb..bef4b6fb 100644 --- a/grc/lora_sdr_whitening.block.yml +++ b/grc/lora_sdr_whitening.block.yml @@ -42,6 +42,7 @@ inputs: hide: ${ ( False if str(source_type) == "message_strobe" else True) } - label: dict domain: message + optional: True outputs: - domain: stream dtype: byte @@ -62,6 +63,7 @@ documentation: |- msg: the payload as a PMT message string or in: a file source with payloads separated by separator. + dict: a dictionary to set parameters such as sf, bw, cr Output: out: Stream of whitened payload nibbles diff --git a/include/gnuradio/lora_sdr/modulate.h b/include/gnuradio/lora_sdr/modulate.h index d9f958c5..b3a2ac6e 100644 --- a/include/gnuradio/lora_sdr/modulate.h +++ b/include/gnuradio/lora_sdr/modulate.h @@ -37,7 +37,6 @@ namespace gr { { public: typedef std::shared_ptr sptr; - virtual void set_sf(uint8_t sf)=0; /*! * \brief Return a shared_ptr to a new instance of lora_sdr::modulate. diff --git a/lib/add_crc_impl.cc b/lib/add_crc_impl.cc index caafbc5c..565dcc99 100644 --- a/lib/add_crc_impl.cc +++ b/lib/add_crc_impl.cc @@ -104,10 +104,12 @@ namespace gr add_item_tag(0, tags[0]); get_tags_in_window(tags, 0, 0, ninput_items[0], pmt::string_to_symbol("configuration")); - tags[0].offset = nitems_written(0); + if(tags.size() > 0) + { + tags[0].offset = nitems_written(0); - if (nitems_to_process) - add_item_tag(0, tags[0]); + if (nitems_to_process) add_item_tag(0, tags[0]); + } m_cnt = 0; } diff --git a/lib/header_impl.cc b/lib/header_impl.cc index e97d441c..c51cb0ce 100644 --- a/lib/header_impl.cc +++ b/lib/header_impl.cc @@ -33,6 +33,7 @@ namespace gr set_tag_propagation_policy(TPP_DONT); m_tags.resize(3); m_cnt_header_nibbles = 0; + m_has_config_tag = false; } void header_impl::set_cr(uint8_t cr){ @@ -91,13 +92,17 @@ namespace gr m_tags[1] = tags[0]; get_tags_in_window(tags, 0, 0, 1, pmt::string_to_symbol("configuration")); - tags[0].offset = nitems_written(0); - m_tags[2] = tags[0]; - - pmt::pmt_t err = pmt::string_to_symbol("error"); - int new_cr = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("cr"), err)); - if (new_cr != m_cr) { - m_cr = new_cr; + if(tags.size() > 0) + { + tags[0].offset = nitems_written(0); + m_tags[2] = tags[0]; + + pmt::pmt_t err = pmt::string_to_symbol("error"); + int new_cr = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("cr"), err)); + if (new_cr != m_cr) { + m_cr = new_cr; + } + m_has_config_tag = true; } } } @@ -129,7 +134,8 @@ namespace gr //add tag add_item_tag(0, m_tags[0]); add_item_tag(0, m_tags[1]); - add_item_tag(0, m_tags[2]); + if(m_has_config_tag) add_item_tag(0, m_tags[2]); + m_has_config_tag = false; } for (int i = 0; i < nitems_to_process; i++) @@ -151,7 +157,8 @@ namespace gr { add_item_tag(0, m_tags[0]); add_item_tag(0, m_tags[1]); - add_item_tag(0, m_tags[2]); + if(m_has_config_tag) add_item_tag(0, m_tags[2]); + m_has_config_tag = false; } for (int i = out_offset; i < nitems_to_process; i++) { diff --git a/lib/header_impl.h b/lib/header_impl.h index 188f7820..44acfe93 100644 --- a/lib/header_impl.h +++ b/lib/header_impl.h @@ -17,6 +17,8 @@ namespace gr { unsigned int m_cnt_header_nibbles; ///< count the number of explicit header nibbles output std::vector m_header; ///< contain the header to prepend + bool m_has_config_tag; /// m_tags; void msg_handler(pmt::pmt_t message); diff --git a/lib/interleaver_impl.cc b/lib/interleaver_impl.cc index a992d28c..098ae127 100644 --- a/lib/interleaver_impl.cc +++ b/lib/interleaver_impl.cc @@ -39,6 +39,7 @@ namespace gr cw_cnt = 0; set_tag_propagation_policy(TPP_DONT); + m_has_config_tag = false; } void interleaver_impl::set_cr(uint8_t cr){ @@ -115,16 +116,20 @@ namespace gr m_frame_len = pmt::to_long(tags[0].value); m_framelen_tag = tags[0]; get_tags_in_window(tags, 0, 0, 1, pmt::string_to_symbol("configuration")); - m_config_tag = tags[0]; - m_config_tag.offset = nitems_written(0); - - pmt::pmt_t err_cr = pmt::string_to_symbol("error"); - pmt::pmt_t err_sf = pmt::string_to_symbol("error"); - pmt::pmt_t err_bw = pmt::string_to_symbol("error"); - int new_cr = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("cr"), err_cr)); - int new_sf = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("sf"), err_sf)); - int new_bw = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("bw"), err_bw)); - update_var(new_cr, new_sf, new_bw, ldro_pass); + if(tags.size()>0) + { + m_has_config_tag = true; + m_config_tag = tags[0]; + m_config_tag.offset = nitems_written(0); + + pmt::pmt_t err_cr = pmt::string_to_symbol("error"); + pmt::pmt_t err_sf = pmt::string_to_symbol("error"); + pmt::pmt_t err_bw = pmt::string_to_symbol("error"); + int new_cr = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("cr"), err_cr)); + int new_sf = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("sf"), err_sf)); + int new_bw = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("bw"), err_bw)); + update_var(new_cr, new_sf, new_bw, ldro_pass); + } // std::cout<<"update tag"<(m_sf) <> cw_bin(sf_app); diff --git a/lib/interleaver_impl.h b/lib/interleaver_impl.h index 1a3c2310..4c316dec 100644 --- a/lib/interleaver_impl.h +++ b/lib/interleaver_impl.h @@ -20,6 +20,7 @@ namespace gr { bool ldro_pass; tag_t m_config_tag; tag_t m_framelen_tag; + bool m_has_config_tag; ///0) + { + m_config_tag = tags[0]; + m_config_tag.offset = nitems_written(0); - pmt::pmt_t err_sf = pmt::string_to_symbol("error"); - pmt::pmt_t err_bw = pmt::string_to_symbol("error"); - int new_sf = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("sf"), err_sf)); - int new_bw = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("bw"), err_bw)); - update_var(new_sf, new_bw); + pmt::pmt_t err_sf = pmt::string_to_symbol("error"); + pmt::pmt_t err_bw = pmt::string_to_symbol("error"); + int new_sf = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("sf"), err_sf)); + int new_bw = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("bw"), err_bw)); + update_var(new_sf, new_bw); - add_item_tag(0, m_config_tag); + add_item_tag(0, m_config_tag); + } m_framelen_tag.offset = nitems_written(0); diff --git a/python/lora_sdr/bindings/docstrings/modulate_pydoc_template.h b/python/lora_sdr/bindings/docstrings/modulate_pydoc_template.h index 266b434d..dcb5436c 100644 --- a/python/lora_sdr/bindings/docstrings/modulate_pydoc_template.h +++ b/python/lora_sdr/bindings/docstrings/modulate_pydoc_template.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 Free Software Foundation, Inc. + * Copyright 2024 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -16,10 +16,6 @@ static const char *__doc_gr_lora_sdr_modulate = R"doc()doc"; -static const char *__doc_gr_lora_sdr_modulate_modulate_0 = R"doc()doc"; - -static const char *__doc_gr_lora_sdr_modulate_modulate_1 = R"doc()doc"; - -static const char *__doc_gr_lora_sdr_modulate_set_sf = R"doc()doc"; +static const char *__doc_gr_lora_sdr_modulate_modulate = R"doc()doc"; static const char *__doc_gr_lora_sdr_modulate_make = R"doc()doc"; diff --git a/python/lora_sdr/bindings/modulate_python.cc b/python/lora_sdr/bindings/modulate_python.cc index 281d6e40..ba428587 100644 --- a/python/lora_sdr/bindings/modulate_python.cc +++ b/python/lora_sdr/bindings/modulate_python.cc @@ -1,5 +1,5 @@ /* - * Copyright 2022 Free Software Foundation, Inc. + * Copyright 2024 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -16,7 +16,7 @@ /* BINDTOOL_GEN_AUTOMATIC(0) */ /* BINDTOOL_USE_PYGCCXML(0) */ /* BINDTOOL_HEADER_FILE(modulate.h) */ -/* BINDTOOL_HEADER_FILE_HASH(2d53e07518d5fe3cb922e161a563407a) */ +/* BINDTOOL_HEADER_FILE_HASH(2f4e1101c5eabd18418839d5e0ac6b19) */ /***********************************************************************************/ #include @@ -40,7 +40,5 @@ void bind_modulate(py::module &m) { py::arg("bw"), py::arg("sync_words"), py::arg("inter_frame_padd"), py::arg("preamble_len"), D(modulate, make)) - .def("set_sf", &modulate::set_sf, py::arg("sf"), D(modulate, set_sf)) - ; } From cd6ace0e98d98b54255de2efd76e865a737f869a Mon Sep 17 00:00:00 2001 From: tapparelj Date: Tue, 9 Jul 2024 17:31:55 +0200 Subject: [PATCH 3/4] add sync word to hier block --- examples/tx_rx_hier_functionality_check.grc | 2 ++ examples/tx_rx_hier_functionality_check.py | 4 ++-- grc/lora_sdr_lora_rx.block.yml | 7 ++++++- grc/lora_sdr_lora_tx.block.yml | 8 +++++++- python/lora_sdr/lora_sdr_lora_tx.py | 5 +++-- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/examples/tx_rx_hier_functionality_check.grc b/examples/tx_rx_hier_functionality_check.grc index 89a6bc41..f38c0094 100644 --- a/examples/tx_rx_hier_functionality_check.grc +++ b/examples/tx_rx_hier_functionality_check.grc @@ -264,6 +264,7 @@ blocks: samp_rate: '500000' sf: '7' soft_decoding: 'True' + sync_word: '[0x12]' states: bus_sink: false bus_source: false @@ -303,6 +304,7 @@ blocks: minoutbuf: '0' samp_rate: '500000' sf: '7' + sync_word: '[0x12]' states: bus_sink: false bus_source: false diff --git a/examples/tx_rx_hier_functionality_check.py b/examples/tx_rx_hier_functionality_check.py index 9c2437d1..cf703696 100755 --- a/examples/tx_rx_hier_functionality_check.py +++ b/examples/tx_rx_hier_functionality_check.py @@ -58,9 +58,9 @@ def __init__(self): impl_head=False, samp_rate=500000, sf=7, - ldro_mode=2,frame_zero_padd=1280 ) + ldro_mode=2,frame_zero_padd=1280,sync_word=[0x12] ) self.lora_sdr_payload_id_inc_0 = lora_sdr.payload_id_inc(':') - self.lora_rx_0 = lora_sdr.lora_sdr_lora_rx( bw=125000, cr=1, has_crc=True, impl_head=False, pay_len=255, samp_rate=500000, sf=7, soft_decoding=True, ldro_mode=2, print_rx=[True,True]) + self.lora_rx_0 = lora_sdr.lora_sdr_lora_rx( bw=125000, cr=1, has_crc=True, impl_head=False, pay_len=255, samp_rate=500000, sf=7, sync_word=[0x12], soft_decoding=True, ldro_mode=2, print_rx=[True,True]) self.channels_channel_model_0 = channels.channel_model( noise_voltage=(10**(-SNRdB/20)), frequency_offset=(center_freq*clk_offset*1e-6/samp_rate), diff --git a/grc/lora_sdr_lora_rx.block.yml b/grc/lora_sdr_lora_rx.block.yml index ca410a49..af54bc7c 100644 --- a/grc/lora_sdr_lora_rx.block.yml +++ b/grc/lora_sdr_lora_rx.block.yml @@ -57,6 +57,10 @@ parameters: options: ['0','1','2'] option_labels: ['Disable','Enable','Auto'] default: '2' +- id: sync_word + label: Sync word + hide: part + default: '[0x12]' - id: print_rx label: Print info dtype: enum @@ -84,7 +88,7 @@ templates: imports: 'import gnuradio.lora_sdr as lora_sdr' make: "lora_sdr.lora_sdr_lora_rx( bw=${ bw }, cr=${ cr }, has_crc=${ has_crc}, impl_head=${ impl_head }, pay_len=${ pay_len }, samp_rate=${samp_rate }, - sf=${ sf }, soft_decoding=${ soft_decoding }, ldro_mode=${ldro}, print_rx=${print_rx})" + sf=${ sf }, sync_word=${sync_word}, soft_decoding=${ soft_decoding }, ldro_mode=${ldro}, print_rx=${print_rx})" asserts: - ${ (samp_rate/bw).is_integer()} @@ -101,6 +105,7 @@ documentation: |- - CRC presence: Payload contains a CRC (only for implicit mode) - Payload length: Length of the payload in bytes (only for implicit mode) - Use soft-decision decoding: Use soft-decision decoding + - Sync word: Sync word to use (default 0x12 for private networks and 0x34 for LoRaWAN). Can be given as [0x12] (or directly the two modulated values [8,16]) - Print info: Print received payload/header in the terminal Inputs: - in: Stream of complex samples diff --git a/grc/lora_sdr_lora_tx.block.yml b/grc/lora_sdr_lora_tx.block.yml index d5fbb30f..94db8e26 100644 --- a/grc/lora_sdr_lora_tx.block.yml +++ b/grc/lora_sdr_lora_tx.block.yml @@ -46,6 +46,10 @@ parameters: options: ['0','1','2'] option_labels: ['Disable','Enable','Auto'] default: '2' +- id: sync_word + label: Sync word + hide: part + default: '[0x12]' - id: frame_zero_padd label: Frame zero padding hide: part @@ -63,7 +67,7 @@ templates: imports: 'import gnuradio.lora_sdr as lora_sdr' make: "lora_sdr.lora_sdr_lora_tx(\n bw=${ bw },\n cr=${ cr },\n has_crc=${ has_crc\ \ },\n impl_head=${ impl_head },\n samp_rate=${ samp_rate },\n sf=${\ - \ sf },\n ldro_mode=${ldro},frame_zero_padd=${frame_zero_padd} )" + \ sf },\n ldro_mode=${ldro},frame_zero_padd=${frame_zero_padd},sync_word=${sync_word} )" callbacks: - set_cr(${ cr }) - set_sf(${ sf }) @@ -82,7 +86,9 @@ documentation: |- - Coding rate: coding rate to use - CRC presence: Payload contains a CRC - LDRO: usage of low data rate optimisation mode (Auto will enable this mode when symbol period exceed 16ms) + - Sync word: Sync word to use (default 0x12 for private networks and 0x34 for LoRaWAN). Can be given as [0x12] (or directly the two modulated values [8,16]) - Frame zero padding: number of null samples padded after each frame + Inputs: - in: Message of the payload to transmitt Outputs diff --git a/python/lora_sdr/lora_sdr_lora_tx.py b/python/lora_sdr/lora_sdr_lora_tx.py index bb7a8f36..c238accf 100644 --- a/python/lora_sdr/lora_sdr_lora_tx.py +++ b/python/lora_sdr/lora_sdr_lora_tx.py @@ -16,7 +16,7 @@ from . import lora_sdr_python as lora_sdr class lora_sdr_lora_tx(gr.hier_block2): - def __init__(self, bw=125000, cr=1, has_crc=True, impl_head=False, samp_rate=250000, sf=7, ldro_mode=2, frame_zero_padd=2**7, ): + def __init__(self, bw=125000, cr=1, has_crc=True, impl_head=False, samp_rate=250000, sf=7, ldro_mode=2, frame_zero_padd=2**7, sync_word=[0x12] ): gr.hier_block2.__init__( self, "lora_sdr_lora_tx", gr.io_signature(0, 0, 0), @@ -34,12 +34,13 @@ def __init__(self, bw=125000, cr=1, has_crc=True, impl_head=False, samp_rate=250 self.samp_rate = samp_rate self.sf = sf self.frame_zero_padd = frame_zero_padd + self.sync_word = sync_word ################################################## # Blocks ################################################## self.lora_sdr_whitening_0 = lora_sdr.whitening(False,False,',','packet_len') - self.lora_sdr_modulate_0 = lora_sdr.modulate(sf, samp_rate, bw, [8,16],frame_zero_padd,8) + self.lora_sdr_modulate_0 = lora_sdr.modulate(sf, samp_rate, bw, sync_word,frame_zero_padd,8) self.lora_sdr_interleaver_0 = lora_sdr.interleaver(cr, sf, ldro_mode, bw) self.lora_sdr_header_0 = lora_sdr.header(impl_head, has_crc, cr) self.lora_sdr_hamming_enc_0 = lora_sdr.hamming_enc(cr, sf) From 9f1a7991bc6636554606313d0b57c617fa5cd378 Mon Sep 17 00:00:00 2001 From: tapparelj Date: Wed, 17 Jul 2024 13:02:19 +0200 Subject: [PATCH 4/4] Fix low datarate optimisation mode update --- lib/interleaver_impl.cc | 17 ++++++++++++----- lib/interleaver_impl.h | 4 ++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/interleaver_impl.cc b/lib/interleaver_impl.cc index 098ae127..7772c11d 100644 --- a/lib/interleaver_impl.cc +++ b/lib/interleaver_impl.cc @@ -28,6 +28,7 @@ namespace gr m_sf = sf; m_cr = cr; m_bw = bw; + m_ldro_mode = ldro; if (ldro == AUTO){ m_ldro = (float)(1u< LDRO_MAX_DURATION_MS; } @@ -35,7 +36,6 @@ namespace gr { m_ldro = ldro; } - ldro_pass = ldro; cw_cnt = 0; set_tag_propagation_policy(TPP_DONT); @@ -48,6 +48,13 @@ namespace gr void interleaver_impl::set_sf(uint8_t sf){ m_sf = sf; + if (m_ldro_mode == AUTO){ + //m_ldro = (float)(1u< LDRO_MAX_DURATION_MS; + m_ldro = (float)(1u< LDRO_MAX_DURATION_MS; + } + else { + m_ldro = m_ldro_mode; + } } uint8_t interleaver_impl::get_cr(){ @@ -67,7 +74,7 @@ namespace gr ninput_items_required[0] = 1; } - void interleaver_impl::update_var(int new_cr, int new_sf, int new_bw, bool ldro_pass) + void interleaver_impl::update_var(int new_cr, int new_sf, int new_bw) { if (new_cr != m_cr) { m_cr = new_cr; @@ -81,12 +88,12 @@ namespace gr m_bw = new_bw; // std::cout<<"New bw Interleaver "<< static_cast(m_bw) < LDRO_MAX_DURATION_MS; m_ldro = (float)(1u< LDRO_MAX_DURATION_MS; } else { - m_ldro = ldro_pass; + m_ldro = m_ldro_mode; } } @@ -128,7 +135,7 @@ namespace gr int new_cr = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("cr"), err_cr)); int new_sf = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("sf"), err_sf)); int new_bw = pmt::to_long(pmt::dict_ref(tags[0].value, pmt::string_to_symbol("bw"), err_bw)); - update_var(new_cr, new_sf, new_bw, ldro_pass); + update_var(new_cr, new_sf, new_bw); } // std::cout<<"update tag"<(m_sf) <