TX block
parent
6f8451c901
commit
fbed8ca129
39
README.md
39
README.md
|
|
@ -36,44 +36,11 @@ to solve any issue related to ``ImportError: libgnuradio-m17.so.1.0.0: cannot op
|
|||
|
||||
When running the flowgraph found in ``examples`` with ``gnuradio-companion ../examples/m17_streamer.grc``
|
||||
|
||||
<img src="examples/m17_streamer.png">
|
||||
<img src="examples/m17_loopback.png">
|
||||
|
||||
the output should be
|
||||
See <a href="examples/README.md">examples/README.md</a> for the expected output and unit testing examples.
|
||||
|
||||
```
|
||||
Generating: '.../M17_Implementations/SP5WWP/gr-m17/examples/m17_streamer.py'
|
||||
|
||||
Executing: /usr/bin/python3 -u .../M17_Implementations/SP5WWP/gr-m17/examples/m17_streamer.py
|
||||
|
||||
new meta: helloworld
|
||||
new SRC ID: 1 2 3 4 5 6
|
||||
new DST ID: 255 255 255 255 255 255
|
||||
New sampling rate: 8800.000000
|
||||
new type: 0 0
|
||||
got_lsf=1
|
||||
LSF
|
||||
DST: #BCAST SRC: FPR-4U3F TYPE: 0000 META: 68656C6C6F776F726C6400000000 LSF_CRC_OK
|
||||
FN: 0000 PLD: 00000000000000000000000000000000
|
||||
FN: 0001 PLD: 00000000000000000000000000000000
|
||||
FN: 0002 PLD: 00000000000000000000000000000000
|
||||
FN: 0003 PLD: 00000000000000000000000000000000
|
||||
FN: 0004 PLD: 00000000000000000000000000000000
|
||||
DST: #BCAST SRC: FPR-4U3F TYPE: 0000 META: 68656C6C6F776F726C6400000000 LSF_CRC_OK
|
||||
FN: 0005 PLD: 00000000000000000000000000000000
|
||||
FN: 0006 PLD: 00000000000000000000000000000000
|
||||
FN: 0007 PLD: 00000000000000000000000000000000
|
||||
FN: 0008 PLD: 00000000000000000000000000000000
|
||||
FN: 0009 PLD: 00000000000000000000000000000000
|
||||
FN: 000A PLD: 00000000000000000000000000000000
|
||||
DST: #BCAST SRC: FPR-4U3F TYPE: 0000 META: 68656C6C6F776F726C6400000000 LSF_CRC_OK
|
||||
FN: 000B PLD: 00000000000000000000000000000000
|
||||
FN: 000C PLD: 00000000000000000000000000000000
|
||||
FN: 000D PLD: 00000000000000000000000000000000
|
||||
FN: 000E PLD: 00000000000000000000000000000000
|
||||
FN: 000F PLD: 00000000000000000000000000000000
|
||||
```
|
||||
|
||||
Notice that due to the verbose output of gr-m17 and the slow console of GNU Radio Companion, I
|
||||
Notice that due to the verbose output of ``gr-m17`` and the slow console of GNU Radio Companion, I
|
||||
would strongly advise generating the Python script from GNU Radio Companion and then execute
|
||||
``python3 m17_streamer.py`` from a terminal to avoid waiting for a long time for GNU Radio
|
||||
Companion to flush all messages.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
### m17_rx.grc
|
||||
|
||||
<img src="m17_rx.png">
|
||||
|
||||
This receiver testing example relies on ``../M17_Implementations/SP5WWP/m17-coder/m17-coder-sym``
|
||||
to broadcast a signal. Following this unit testing example, run this flowchart along with
|
||||
```
|
||||
|
|
@ -26,17 +28,56 @@ DST: ALL SRC: AB1CDE TYPE: 0005 META: 0000000000000000000000000000 LSF_
|
|||
It would be wise to execute from a terminal rather than the GNU Radio Companion graphical interface
|
||||
to avoid flooding the console.
|
||||
|
||||
### m17_tx.grc
|
||||
|
||||
<img src="m17_tx.png">
|
||||
|
||||
This transmitter testing example relies on ``../M17_Implementations/SP5WWP/m17-decoder/m17-decoder-sym``
|
||||
to decode a signal. Following this unit testing example, run this flowchart along with
|
||||
```
|
||||
mkfifo /tmp/fifo1
|
||||
mkfifo /tmp/fifo2
|
||||
../M17_Implementations/SP5WWP/m17-decoder/m17-decoder-sym < /tmp/fifo2
|
||||
```
|
||||
|
||||
and the output of ``python3 ./m17_tx.py`` should be
|
||||
```
|
||||
DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK
|
||||
FN: 0018 PLD: 01020304050600000000000000000000 e=0.0
|
||||
FN: 0019 PLD: 01020304050600000000000000000000 e=0.0
|
||||
FN: 001A PLD: 01020304050600000000000000000000 e=0.0
|
||||
FN: 001B PLD: 01020304050600000000000000000000 e=0.0
|
||||
FN: 001C PLD: 01020304050600000000000000000000 e=0.0
|
||||
FN: 001D PLD: 01020304050600000000000000000000 e=0.0
|
||||
DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK
|
||||
FN: 001E PLD: 01020304050600000000000000000000 e=0.0
|
||||
```
|
||||
|
||||
### m17_streamer.grc
|
||||
|
||||
Loopback demo with TX and RX both in GNU Radio.
|
||||
|
||||
<img src="m17_loopback.png">
|
||||
|
||||
The output should be
|
||||
|
||||
```
|
||||
DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK
|
||||
DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK
|
||||
DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK
|
||||
DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK
|
||||
DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK
|
||||
DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK
|
||||
```
|
||||
|
||||
## TO BE DEBUGGED AND VALIDATED
|
||||
|
||||
### transmitterPLUTOSDR.grc
|
||||
M17 transmitter with ADALM Pluto SDR.
|
||||
|
||||
### receiverRTLSDR.grc
|
||||
M17 receiver with RTL SDR. Automatic Frequency Correction can be enabled as an option.
|
||||
|
||||
### m17_streamer.grc
|
||||
Old loopback demo.
|
||||
|
||||
<img src="m17_loopback.png">
|
||||
|
||||
### m17_loopback_noisychannel.grc
|
||||
Loopback demo with the addition of noise, no modulation/no channnel.
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 174 KiB |
|
|
@ -0,0 +1,215 @@
|
|||
options:
|
||||
parameters:
|
||||
author: Wojciech SP5WWP
|
||||
catch_exceptions: 'True'
|
||||
category: '[GRC Hier Blocks]'
|
||||
cmake_opt: ''
|
||||
comment: ''
|
||||
copyright: M17 Project, Jan 2024
|
||||
description: ''
|
||||
gen_cmake: 'On'
|
||||
gen_linking: dynamic
|
||||
generate_options: qt_gui
|
||||
hier_block_src_path: '.:'
|
||||
id: m17_tx
|
||||
max_nouts: '0'
|
||||
output_language: python
|
||||
placement: (0,0)
|
||||
qt_qss_theme: ''
|
||||
realtime_scheduling: ''
|
||||
run: 'True'
|
||||
run_command: '{python} -u {filename}'
|
||||
run_options: prompt
|
||||
sizing_mode: fixed
|
||||
thread_safe_setters: ''
|
||||
title: M17 loopback demo
|
||||
window_size: (1000,1000)
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [8, 4.0]
|
||||
rotation: 0
|
||||
state: enabled
|
||||
|
||||
blocks:
|
||||
- name: dst_str
|
||||
id: variable_qtgui_entry
|
||||
parameters:
|
||||
comment: ''
|
||||
entry_signal: editingFinished
|
||||
gui_hint: ''
|
||||
label: DST
|
||||
type: string
|
||||
value: AB2CDE
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [568, 12.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: meta_str
|
||||
id: variable_qtgui_entry
|
||||
parameters:
|
||||
comment: ''
|
||||
entry_signal: editingFinished
|
||||
gui_hint: ''
|
||||
label: META
|
||||
type: string
|
||||
value: Hello!
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [288, 12.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: samp_rate
|
||||
id: variable
|
||||
parameters:
|
||||
comment: ''
|
||||
value: '4800'
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [192, 12.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: src_str
|
||||
id: variable_qtgui_entry
|
||||
parameters:
|
||||
comment: ''
|
||||
entry_signal: editingFinished
|
||||
gui_hint: ''
|
||||
label: SRC
|
||||
type: string
|
||||
value: AB1CDE
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [424, 12.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: type_val
|
||||
id: variable_qtgui_entry
|
||||
parameters:
|
||||
comment: ''
|
||||
entry_signal: editingFinished
|
||||
gui_hint: ''
|
||||
label: TYPE
|
||||
type: int
|
||||
value: '5'
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [712, 12.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: blocks_file_sink_0
|
||||
id: blocks_file_sink
|
||||
parameters:
|
||||
affinity: ''
|
||||
alias: ''
|
||||
append: 'False'
|
||||
comment: '/tmp/fifo2 was created with
|
||||
|
||||
mkfifo /tmp/fifo2'
|
||||
file: /tmp/fifo2
|
||||
type: float
|
||||
unbuffered: 'False'
|
||||
vlen: '1'
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [752, 144.0]
|
||||
rotation: 0
|
||||
state: enabled
|
||||
- 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
|
||||
type: float
|
||||
vlen: '1'
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [536, 152.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: blocks_vector_source_x_0_2
|
||||
id: blocks_vector_source_x
|
||||
parameters:
|
||||
affinity: ''
|
||||
alias: ''
|
||||
comment: ''
|
||||
maxoutbuf: '0'
|
||||
minoutbuf: '0'
|
||||
repeat: 'True'
|
||||
tags: '[]'
|
||||
type: byte
|
||||
vector: (0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00)
|
||||
vlen: '1'
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [16, 144.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: m17_m17_coder_0
|
||||
id: m17_m17_coder
|
||||
parameters:
|
||||
affinity: ''
|
||||
alias: ''
|
||||
comment: ''
|
||||
debug: 'False'
|
||||
dst_id: dst_str
|
||||
maxoutbuf: '0'
|
||||
meta: meta_str
|
||||
minoutbuf: '0'
|
||||
src_id: src_str
|
||||
type: type_val
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [320, 128.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: note_0_2
|
||||
id: note
|
||||
parameters:
|
||||
alias: ''
|
||||
comment: ''
|
||||
note: DATA
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [200, 88.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
|
||||
connections:
|
||||
- [blocks_throttle2_0, '0', blocks_file_sink_0, '0']
|
||||
- [blocks_vector_source_x_0_2, '0', m17_m17_coder_0, '0']
|
||||
- [m17_m17_coder_0, '0', blocks_throttle2_0, '0']
|
||||
|
||||
metadata:
|
||||
file_format: 1
|
||||
grc_version: 3.10.10.0
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
|
|
@ -138,6 +138,8 @@ void m17_coder_impl::set_type(short type)
|
|||
|
||||
int countin=0;
|
||||
uint32_t countout=0;
|
||||
float frame_buff_tmp[192];
|
||||
uint32_t frame_buff_count_tmp;
|
||||
|
||||
uint8_t enc_bits[SYM_PER_PLD*2]; //type-2 bits, unpacked
|
||||
uint8_t rf_bits[SYM_PER_PLD*2]; //type-4 bits, unpacked
|
||||
|
|
@ -149,120 +151,30 @@ void m17_coder_impl::set_type(short type)
|
|||
|
||||
while (countout<(uint32_t)noutput_items) {
|
||||
if (countin+16<=noutput_items)
|
||||
{if(_got_lsf) //stream frames
|
||||
{for (int i=0;i<16;i++) {data[i]=in[countin];countin++;}
|
||||
if(_got_lsf) //stream frames
|
||||
{
|
||||
//we could discard the data we already have
|
||||
for (int i=0;i<16;i++) {data[i]=in[countin];countin++;}
|
||||
|
||||
//send stream frame syncword
|
||||
send_syncword(out,&countout,SYNC_STR);
|
||||
|
||||
//derive the LICH_CNT from the Frame Number
|
||||
lich_cnt=_fn%6;
|
||||
|
||||
//extract LICH from the whole LSF
|
||||
switch(lich_cnt)
|
||||
{
|
||||
case 0:
|
||||
lich[0]=lsf.dst[0];
|
||||
lich[1]=lsf.dst[1];
|
||||
lich[2]=lsf.dst[2];
|
||||
lich[3]=lsf.dst[3];
|
||||
lich[4]=lsf.dst[4];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
lich[0]=lsf.dst[5];
|
||||
lich[1]=lsf.src[0];
|
||||
lich[2]=lsf.src[1];
|
||||
lich[3]=lsf.src[2];
|
||||
lich[4]=lsf.src[3];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
lich[0]=lsf.src[4];
|
||||
lich[1]=lsf.src[5];
|
||||
lich[2]=lsf.type[0];
|
||||
lich[3]=lsf.type[1];
|
||||
lich[4]=lsf.meta[0];
|
||||
break;
|
||||
|
||||
case 3:
|
||||
lich[0]=lsf.meta[1];
|
||||
lich[1]=lsf.meta[2];
|
||||
lich[2]=lsf.meta[3];
|
||||
lich[3]=lsf.meta[4];
|
||||
lich[4]=lsf.meta[5];
|
||||
break;
|
||||
|
||||
case 4:
|
||||
lich[0]=lsf.meta[6];
|
||||
lich[1]=lsf.meta[7];
|
||||
lich[2]=lsf.meta[8];
|
||||
lich[3]=lsf.meta[9];
|
||||
lich[4]=lsf.meta[10];
|
||||
break;
|
||||
|
||||
case 5:
|
||||
lich[0]=lsf.meta[11];
|
||||
lich[1]=lsf.meta[12];
|
||||
lich[2]=lsf.meta[13];
|
||||
lich[3]=lsf.crc[0];
|
||||
lich[4]=lsf.crc[1];
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
break;
|
||||
}
|
||||
lich[5]=lich_cnt<<5;
|
||||
extract_LICH(lich, lich_cnt, &lsf);
|
||||
|
||||
//encode the LICH
|
||||
uint32_t val;
|
||||
|
||||
val=golay24_encode((lich[0]<<4)|(lich[1]>>4));
|
||||
lich_encoded[0]=(val>>16)&0xFF;
|
||||
lich_encoded[1]=(val>>8)&0xFF;
|
||||
lich_encoded[2]=(val>>0)&0xFF;
|
||||
val=golay24_encode(((lich[1]&0x0F)<<8)|lich[2]);
|
||||
lich_encoded[3]=(val>>16)&0xFF;
|
||||
lich_encoded[4]=(val>>8)&0xFF;
|
||||
lich_encoded[5]=(val>>0)&0xFF;
|
||||
val=golay24_encode((lich[3]<<4)|(lich[4]>>4));
|
||||
lich_encoded[6]=(val>>16)&0xFF;
|
||||
lich_encoded[7]=(val>>8)&0xFF;
|
||||
lich_encoded[8]=(val>>0)&0xFF;
|
||||
val=golay24_encode(((lich[4]&0x0F)<<8)|lich[5]);
|
||||
lich_encoded[9]=(val>>16)&0xFF;
|
||||
lich_encoded[10]=(val>>8)&0xFF;
|
||||
lich_encoded[11]=(val>>0)&0xFF;
|
||||
encode_LICH(lich_encoded, lich);
|
||||
|
||||
//unpack LICH (12 bytes)
|
||||
memset(enc_bits, 0, SYM_PER_PLD*2);
|
||||
for(uint8_t i=0; i<12; i++)
|
||||
{
|
||||
for(uint8_t j=0; j<8; j++)
|
||||
enc_bits[i*8+j]=(lich_encoded[i]>>(7-j))&1;
|
||||
}
|
||||
unpack_LICH(enc_bits, lich_encoded);
|
||||
|
||||
//encode the rest of the frame
|
||||
//encode the rest of the frame (starting at bit 96 - 0..95 are filled with LICH)
|
||||
// conv_encode_stream_frame(&enc_bits[96], data, finished ? (_fn | 0x8000) : _fn); JMF review
|
||||
conv_encode_stream_frame(&enc_bits[96], data, _fn);
|
||||
|
||||
//reorder bits
|
||||
for(uint16_t i=0; i<SYM_PER_PLD*2; i++)
|
||||
rf_bits[i]=enc_bits[intrl_seq[i]];
|
||||
reorder_bits(rf_bits, enc_bits);
|
||||
|
||||
//randomize
|
||||
for(uint16_t i=0; i<SYM_PER_PLD*2; i++)
|
||||
{
|
||||
if((rand_seq[i/8]>>(7-(i%8)))&1) //flip bit if '1'
|
||||
{
|
||||
if(rf_bits[i])
|
||||
rf_bits[i]=0;
|
||||
else
|
||||
rf_bits[i]=1;
|
||||
}
|
||||
}
|
||||
randomize_bits(rf_bits);
|
||||
|
||||
//send dummy symbols (debug)
|
||||
/*float s=0.0;
|
||||
|
|
@ -288,51 +200,41 @@ void m17_coder_impl::set_type(short type)
|
|||
}
|
||||
else //LSF
|
||||
{
|
||||
// for (int i=0;i<6;i++) {lsf.dst[i]=in[countin];countin++;}
|
||||
// for (int i=0;i<6;i++) {lsf.src[i]=in[countin];countin++;}
|
||||
// for (int i=0;i<2;i++) {lsf.type[i]=in[countin];countin++;}
|
||||
// for (int i=0;i<14;i++) {lsf.meta[i]=in[countin];countin++;}
|
||||
for (int i=0;i<16;i++) {data[i]=in[countin];countin++;}
|
||||
|
||||
//calculate LSF CRC
|
||||
// uint16_t ccrc=LSF_CRC(&lsf);
|
||||
// lsf.crc[0]=ccrc>>8;
|
||||
// lsf.crc[1]=ccrc&0xFF;
|
||||
|
||||
_got_lsf=1;
|
||||
// printf("got_lsf=1\n");
|
||||
|
||||
//send out the preamble and LSF
|
||||
send_preamble(frame_buff_tmp, &frame_buff_count_tmp, 0); //0 - LSF preamble, as opposed to 1 - BERT preamble
|
||||
for(uint16_t i=0; i<SYM_PER_FRA; i++) //40ms * 4800 - 8 (syncword)
|
||||
{
|
||||
out[countout]=frame_buff_tmp[i];
|
||||
countout++;
|
||||
}
|
||||
|
||||
//send LSF syncword
|
||||
send_syncword(frame_buff_tmp,&frame_buff_count_tmp,SYNC_LSF);
|
||||
for(uint16_t i=0; i<SYM_PER_SWD; i++) //40ms * 4800 - 8 (syncword)
|
||||
{
|
||||
out[countout]=frame_buff_tmp[i];
|
||||
countout++;
|
||||
}
|
||||
|
||||
//encode LSF data
|
||||
conv_encode_LSF(enc_bits, &lsf);
|
||||
|
||||
//send out the preamble and LSF
|
||||
//send_Preamble(0,out,&countout); //0 - LSF preamble, as opposed to 1 - BERT preamble
|
||||
send_preamble(out, &countout, 0);
|
||||
|
||||
//send LSF syncword
|
||||
send_syncword(out,&countout,SYNC_LSF);
|
||||
|
||||
//reorder bits
|
||||
for(uint16_t i=0; i<SYM_PER_PLD*2; i++)
|
||||
rf_bits[i]=enc_bits[intrl_seq[i]];
|
||||
reorder_bits(rf_bits, enc_bits);
|
||||
|
||||
//randomize
|
||||
for(uint16_t i=0; i<SYM_PER_PLD*2; i++)
|
||||
{
|
||||
if((rand_seq[i/8]>>(7-(i%8)))&1) //flip bit if '1'
|
||||
{
|
||||
if(rf_bits[i])
|
||||
rf_bits[i]=0;
|
||||
else
|
||||
rf_bits[i]=1;
|
||||
}
|
||||
}
|
||||
randomize_bits(rf_bits);
|
||||
|
||||
float s;
|
||||
//send LSF data
|
||||
send_data(frame_buff_tmp, &frame_buff_count_tmp, rf_bits);
|
||||
|
||||
for(uint16_t i=0; i<SYM_PER_PLD; i++) //40ms * 4800 - 8 (syncword)
|
||||
{
|
||||
s=symbol_map[rf_bits[2*i]*2+rf_bits[2*i+1]];
|
||||
out[countout]=s;
|
||||
out[countout]=frame_buff_tmp[i];
|
||||
countout++;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue