Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lorawan tx support #101

Merged
merged 4 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions examples/tx_rx_functionality_check.grc
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ blocks:
id: variable
parameters:
comment: ''
value: '0'
value: '1'
states:
bus_sink: false
bus_source: false
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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']
Expand Down
10 changes: 5 additions & 5 deletions examples/tx_rx_functionality_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)))

Expand All @@ -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))
Expand Down Expand Up @@ -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):
Expand Down
2 changes: 2 additions & 0 deletions examples/tx_rx_hier_functionality_check.grc
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ blocks:
samp_rate: '500000'
sf: '7'
soft_decoding: 'True'
sync_word: '[0x12]'
states:
bus_sink: false
bus_source: false
Expand Down Expand Up @@ -303,6 +304,7 @@ blocks:
minoutbuf: '0'
samp_rate: '500000'
sf: '7'
sync_word: '[0x12]'
states:
bus_sink: false
bus_source: false
Expand Down
4 changes: 2 additions & 2 deletions examples/tx_rx_hier_functionality_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
7 changes: 6 additions & 1 deletion grc/lora_sdr_lora_rx.block.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()}

Expand All @@ -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
Expand Down
8 changes: 7 additions & 1 deletion grc/lora_sdr_lora_tx.block.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 })
Expand All @@ -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
Expand Down
2 changes: 0 additions & 2 deletions grc/lora_sdr_modulate.block.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
6 changes: 5 additions & 1 deletion grc/lora_sdr_whitening.block.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -40,6 +40,9 @@ 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
optional: True
outputs:
- domain: stream
dtype: byte
Expand All @@ -60,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

Expand Down
1 change: 0 additions & 1 deletion include/gnuradio/lora_sdr/modulate.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ namespace gr {
{
public:
typedef std::shared_ptr<modulate> sptr;
virtual void set_sf(uint8_t sf)=0;

/*!
* \brief Return a shared_ptr to a new instance of lora_sdr::modulate.
Expand Down
9 changes: 8 additions & 1 deletion lib/add_crc_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,16 @@ 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"));
if(tags.size() > 0)
{
tags[0].offset = nitems_written(0);

if (nitems_to_process) add_item_tag(0, tags[0]);
}

m_cnt = 0;
}
Expand Down
15 changes: 14 additions & 1 deletion lib/gray_demap_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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<tag_t> 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<int>(m_sf) <<std::endl;
}
}
for(int i=0;i<noutput_items;i++){
#ifdef GRLORA_DEBUG
std::cout<<std::hex<<"0x"<<in[i]<<" --> ";
Expand Down
1 change: 1 addition & 0 deletions lib/gray_demap_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
18 changes: 18 additions & 0 deletions lib/hamming_enc_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,24 @@ namespace gr

// read tags
std::vector<tag_t> 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<int>(m_cr) <<std::endl;
}
if (new_sf != m_sf) {
m_sf = new_sf;
// std::cout<<"New sf Hamming "<< static_cast<int>(m_sf) <<std::endl;
}
}


get_tags_in_window(tags, 0, 0, noutput_items, pmt::string_to_symbol("frame_len"));
if (tags.size())
{
Expand Down
24 changes: 20 additions & 4 deletions lib/header_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ namespace gr
m_header.resize(5);

set_tag_propagation_policy(TPP_DONT);
m_tags.resize(2);
m_tags.resize(3);
m_cnt_header_nibbles = 0;
m_has_config_tag = false;
}

void header_impl::set_cr(uint8_t cr){
Expand Down Expand Up @@ -76,7 +77,7 @@ namespace gr
nitems_to_process = std::min(tags[0].offset - nitems_read(0), (uint64_t)noutput_items);
else
{
if (tags.size() >= 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);
Expand All @@ -90,6 +91,19 @@ namespace gr
m_cnt_nibbles = 0;

m_tags[1] = tags[0];
get_tags_in_window(tags, 0, 0, 1, pmt::string_to_symbol("configuration"));
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;
}
}
}

Expand Down Expand Up @@ -120,6 +134,8 @@ namespace gr
//add tag
add_item_tag(0, m_tags[0]);
add_item_tag(0, m_tags[1]);
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++)
Expand All @@ -141,15 +157,15 @@ namespace gr
{
add_item_tag(0, m_tags[0]);
add_item_tag(0, m_tags[1]);
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++)
{
out[i] = in[i - out_offset];
m_cnt_nibbles++;
m_cnt_header_nibbles = 0;
}


consume_each(nitems_to_process - out_offset);
return nitems_to_process;
}
Expand Down
Loading
Loading