diff --git a/examples/cdc_packet_tx.grc b/examples/cdc_packet_tx.grc index 0e83b5edb54305cd88f568ef5b0727669fe81d6f..01a653bd08bc5944b7910958a9285989cb2d8f31 100644 --- a/examples/cdc_packet_tx.grc +++ b/examples/cdc_packet_tx.grc @@ -296,12 +296,16 @@ blocks: excess_bw: '0.35' maxoutbuf: '0' minoutbuf: '0' + show_burst: 'False' + show_header: 'False' + show_postcrc: 'False' + show_symbols: 'True' sps: '2' states: bus_sink: false bus_source: false bus_structure: null - coordinate: [560, 264.0] + coordinate: [560, 268.0] rotation: 0 state: true - name: qtgui_const_sink_x_0 @@ -490,7 +494,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [968, 236.0] + coordinate: [1000, 236.0] rotation: 0 state: true diff --git a/examples/packet_phy_tx.grc b/examples/packet_phy_tx.grc index 204c1dfceb6f1e008faa8a5ff01599961e6ce30e..7d6128ccbb351093c0398bc2f85f9863e2c3870b 100644 --- a/examples/packet_phy_tx.grc +++ b/examples/packet_phy_tx.grc @@ -11,7 +11,7 @@ options: gen_linking: dynamic generate_options: hb hier_block_src_path: '.:' - id: packet_phy_tx + id: packet_phy_tx_grc max_nouts: '0' output_language: python placement: (0,0) @@ -22,7 +22,7 @@ options: run_options: prompt sizing_mode: fixed thread_safe_setters: '' - title: CDC Packet PHY TX + title: CDC Packet PHY TX (GRC) window_size: (1000,1000) states: bus_sink: false @@ -296,7 +296,7 @@ blocks: bus_structure: null coordinate: [392, 124.0] rotation: 0 - state: disabled + state: enabled - name: pad_sink_1_0 id: pad_sink parameters: @@ -314,7 +314,7 @@ blocks: bus_structure: null coordinate: [712, 116.0] rotation: 0 - state: disabled + state: enabled - name: pad_sink_2 id: pad_sink parameters: @@ -350,7 +350,7 @@ blocks: bus_structure: null coordinate: [488, 388.0] rotation: 0 - state: disabled + state: enabled - name: pad_source_0 id: pad_source parameters: diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index 12c160e81ec234c1dcf239618ff7dd0babb5eb30..7bd50626ef9ac1668c7b5c76b8132e59618f230f 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -11,6 +11,7 @@ install(FILES elen90089_moe_symbol_sync_cc.block.yml elen90089_symbol_mapper_c.block.yml elen90089_header_format_cdc.block.yml + elen90089_packet_phy_tx.block.yml elen90089_packet_mac_tx.block.yml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/elen90089_packet_phy_tx.block.yml b/grc/elen90089_packet_phy_tx.block.yml new file mode 100644 index 0000000000000000000000000000000000000000..984f735aaf658221515d0f1c410f30222a78f20d --- /dev/null +++ b/grc/elen90089_packet_phy_tx.block.yml @@ -0,0 +1,85 @@ +id: packet_phy_tx +label: CDC Packet PHY TX +category: '[elen90089]' + +parameters: +- id: excess_bw + label: Excess BW + dtype: real + default: '0.35' + hide: none +- id: sps + label: Samps per symb + dtype: int + default: '2' + hide: none + +- id: show_postcrc + category: Debug + label: Show Post CRC + dtype: enum + default: False + options: ['False', 'True'] + hide: part +- id: show_header + category: Debug + label: Show Header + dtype: enum + default: False + options: ['False', 'True'] + hide: part +- id: show_symbols + category: Debug + label: Show Symbols + dtype: enum + default: False + options: ['False', 'True'] + hide: part +- id: show_burst + category: Debug + label: Show Burst + dtype: enum + default: False + options: ['False', 'True'] + hide: part + +inputs: +- label: phy_sdu + domain: message + dtype: message + +outputs: +- label: iq + dtype: complex + vlen: 1 +- label: postcrc + domain: message + dtype: message + optional: true + hide: ${ show_postcrc == 'False' } +- label: header + domain: message + dtype: message + optional: true + hide: ${ show_header == 'False' } +- label: symbols + dtype: complex + vlen: 1 + optional: true + hide: ${ show_symbols == 'False' } +- label: burst + dtype: complex + vlen: 1 + optional: true + hide: ${ show_burst == 'False' } + +templates: + imports: 'from elen90089 import packet_phy_tx' + make: "packet_phy_tx(excess_bw=${ excess_bw }, sps=${ sps },)" + callbacks: + - set_excess_bw(${ excess_bw }) + - set_sps(${ sps }) + +#documentation: + +file_format: 1 diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 3b89790c61fe55ef4bec04b1833ee653eb493572..eb5106e643b31c808e9bdee3704037c6cb311451 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -22,6 +22,7 @@ add_subdirectory(bindings) GR_PYTHON_INSTALL( FILES __init__.py + packet_phy_tx.py packet_mac_tx.py DESTINATION ${GR_PYTHON_DIR}/elen90089 ) diff --git a/python/__init__.py b/python/__init__.py index d997af05f5d3e93aeddd2bcdb23193d36d18e18f..f7264423aa043081b2bd81ef0177f446a19fca92 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -20,5 +20,6 @@ except ModuleNotFoundError: pass # import any pure python here +from .packet_phy_tx import packet_phy_tx from .packet_mac_tx import packet_mac_tx # diff --git a/python/packet_phy_tx.py b/python/packet_phy_tx.py new file mode 100644 index 0000000000000000000000000000000000000000..ce7df6e730826b0eb1abdd6cc085aecd68ff1582 --- /dev/null +++ b/python/packet_phy_tx.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- + +# +# SPDX-License-Identifier: GPL-3.0 +# +# GNU Radio Python Flow Graph +# Title: CDC Packet PHY TX +# Copyright: University of Melbourne +# GNU Radio version: 3.9.5.0 + +from gnuradio import blocks +from gnuradio import digital +from gnuradio import fec +from gnuradio import gr +from gnuradio.filter import firdes +from gnuradio.fft import window +import sys +import signal +from gnuradio.filter import pfb +import elen90089 + + +class packet_phy_tx(gr.hier_block2): + def __init__(self, excess_bw=0.35, sps=2): + gr.hier_block2.__init__( + self, "CDC Packet PHY TX", + gr.io_signature(0, 0, 0), + gr.io_signature.makev(3, 3, [gr.sizeof_gr_complex*1, + gr.sizeof_gr_complex*1, + gr.sizeof_gr_complex*1]), + ) + self.message_port_register_hier_in("phy_sdu") + self.message_port_register_hier_out("postcrc") + self.message_port_register_hier_out("header") + + ################################################## + # Parameters + ################################################## + self.excess_bw = excess_bw + self.sps = sps + + ################################################## + # Variables + ################################################## + self.nfilts = nfilts = 32 + self.rrc_taps = rrc_taps = firdes.root_raised_cosine(nfilts/2, nfilts,1.0, excess_bw, 5*sps*nfilts) + self.taps_per_filt = taps_per_filt = len(rrc_taps)/nfilts + self.header_format_cdc_0 = header_format_cdc_0 = elen90089.header_format_cdc(digital.packet_utils.default_access_code, 3, 1) + self.hdr_encoder = hdr_encoder = fec.dummy_encoder_make(1500) + self.filt_delay = filt_delay = int(1+(taps_per_filt-1)//2) + + ################################################## + # Blocks + ################################################## + self.pfb_arb_resampler_xxx_0_0 = pfb.arb_resampler_ccf( + sps, + taps=rrc_taps, + flt_size=nfilts) + self.pfb_arb_resampler_xxx_0_0.declare_sample_delay(filt_delay) + self.fec_async_encoder_0_0 = fec.async_encoder(hdr_encoder, True, False, False, 1500) + self.elen90089_symbol_mapper_c_0 = elen90089.symbol_mapper_c(elen90089.symbol_mapper_c.constel.CONSTEL_BPSK, 'packet_len') + self.digital_protocol_formatter_async_0 = digital.protocol_formatter_async(header_format_cdc_0) + self.digital_crc32_async_bb_1 = digital.crc32_async_bb(False) + self.digital_burst_shaper_xx_0 = digital.burst_shaper_cc(firdes.window(window.WIN_HANN, 20, 0), 0, filt_delay, True, 'packet_len') + self.blocks_tagged_stream_multiply_length_0 = blocks.tagged_stream_multiply_length(gr.sizeof_gr_complex*1, 'packet_len', sps) + + + ################################################## + # Connections + ################################################## + self.msg_connect((self.digital_crc32_async_bb_1, 'out'), (self.digital_protocol_formatter_async_0, 'in')) + self.msg_connect((self.digital_crc32_async_bb_1, 'out'), (self, 'postcrc')) + self.msg_connect((self.digital_protocol_formatter_async_0, 'payload'), (self.elen90089_symbol_mapper_c_0, 'pld')) + self.msg_connect((self.digital_protocol_formatter_async_0, 'header'), (self.fec_async_encoder_0_0, 'in')) + self.msg_connect((self.digital_protocol_formatter_async_0, 'header'), (self, 'header')) + self.msg_connect((self.fec_async_encoder_0_0, 'out'), (self.elen90089_symbol_mapper_c_0, 'hdr')) + self.msg_connect((self, 'phy_sdu'), (self.digital_crc32_async_bb_1, 'in')) + self.connect((self.blocks_tagged_stream_multiply_length_0, 0), (self, 0)) + self.connect((self.digital_burst_shaper_xx_0, 0), (self, 2)) + self.connect((self.digital_burst_shaper_xx_0, 0), (self.pfb_arb_resampler_xxx_0_0, 0)) + self.connect((self.elen90089_symbol_mapper_c_0, 0), (self.digital_burst_shaper_xx_0, 0)) + self.connect((self.elen90089_symbol_mapper_c_0, 0), (self, 1)) + self.connect((self.pfb_arb_resampler_xxx_0_0, 0), (self.blocks_tagged_stream_multiply_length_0, 0)) + + + def get_excess_bw(self): + return self.excess_bw + + def set_excess_bw(self, excess_bw): + self.excess_bw = excess_bw + self.set_rrc_taps(firdes.root_raised_cosine(self.nfilts/2, self.nfilts, 1.0, self.excess_bw, 5*self.sps*self.nfilts)) + + def get_sps(self): + return self.sps + + def set_sps(self, sps): + self.sps = sps + self.set_rrc_taps(firdes.root_raised_cosine(self.nfilts/2, self.nfilts, 1.0, self.excess_bw, 5*self.sps*self.nfilts)) + self.blocks_tagged_stream_multiply_length_0.set_scalar(self.sps) + self.pfb_arb_resampler_xxx_0_0.set_rate(self.sps) + + def get_nfilts(self): + return self.nfilts + + def set_nfilts(self, nfilts): + self.nfilts = nfilts + self.set_rrc_taps(firdes.root_raised_cosine(self.nfilts/2, self.nfilts, 1.0, self.excess_bw, 5*self.sps*self.nfilts)) + self.set_taps_per_filt(len(self.rrc_taps)/self.nfilts) + + def get_rrc_taps(self): + return self.rrc_taps + + def set_rrc_taps(self, rrc_taps): + self.rrc_taps = rrc_taps + self.set_taps_per_filt(len(self.rrc_taps)/self.nfilts) + self.pfb_arb_resampler_xxx_0_0.set_taps(self.rrc_taps) + + def get_taps_per_filt(self): + return self.taps_per_filt + + def set_taps_per_filt(self, taps_per_filt): + self.taps_per_filt = taps_per_filt + self.set_filt_delay(int(1+(self.taps_per_filt-1)//2)) + + def get_header_format_cdc_0(self): + return self.header_format_cdc_0 + + def set_header_format_cdc_0(self, header_format_cdc_0): + self.header_format_cdc_0 = header_format_cdc_0 + + def get_hdr_encoder(self): + return self.hdr_encoder + + def set_hdr_encoder(self, hdr_encoder): + self.hdr_encoder = hdr_encoder + + def get_filt_delay(self): + return self.filt_delay + + def set_filt_delay(self, filt_delay): + self.filt_delay = filt_delay +