diff --git a/examples/cdc_phy_loopback.grc b/examples/cdc_phy_loopback.grc new file mode 100644 index 0000000000000000000000000000000000000000..756e3324b0bf2a7ec0f8e51c1039f6c220c02ec1 --- /dev/null +++ b/examples/cdc_phy_loopback.grc @@ -0,0 +1,612 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: University of Melbourne + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: cdc_phy_loopback + 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: CDC PHY Loopback + window_size: (1000,1000) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: amp_gain + id: variable_qtgui_range + parameters: + comment: '' + gui_hint: '' + label: Amp Gain + min_len: '200' + orient: QtCore.Qt.Horizontal + rangeType: float + start: '-3' + step: '0.1' + stop: '3' + value: '0.0' + widget: counter_slider + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [288, 316.0] + rotation: 0 + state: true +- name: excess_bw + id: variable + parameters: + comment: '' + value: '0.35' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [256, 12.0] + rotation: 0 + state: enabled +- name: phase_rot + id: variable_qtgui_range + parameters: + comment: '' + gui_hint: '' + label: Phase Rot + min_len: '200' + orient: QtCore.Qt.Horizontal + rangeType: float + start: -np.pi + step: 2*np.pi/200 + stop: np.pi + value: np.pi/4 + widget: counter_slider + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [400, 316.0] + rotation: 0 + state: true +- name: sps + id: variable + parameters: + comment: '' + value: '2' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [184, 12.0] + rotation: 0 + state: enabled +- name: blocks_message_debug_0 + id: blocks_message_debug + parameters: + affinity: '' + alias: '' + comment: '' + en_uvec: 'True' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [856, 8.0] + rotation: 0 + state: true +- name: blocks_message_strobe_1 + id: blocks_message_strobe + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + msg: pmt.intern("TEST") + period: '500' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [352, 116.0] + rotation: 180 + state: true +- name: channels_channel_model_0 + id: channels_channel_model + parameters: + affinity: '' + alias: '' + block_tags: 'False' + comment: '' + epsilon: '1.001' + freq_offset: '0.0' + maxoutbuf: '0' + minoutbuf: '0' + noise_voltage: '0.0' + seed: '0' + taps: np.exp(1j*phase_rot)*10**(amp_gain) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [304, 188.0] + rotation: 0 + state: true +- name: import_0 + id: import + parameters: + alias: '' + comment: '' + imports: import numpy as np + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [288, 444.0] + rotation: 0 + state: true +- name: pdu_random_pdu_0 + id: pdu_random_pdu + parameters: + affinity: '' + alias: '' + comment: '' + length_modulo: '2' + mask: '0xFF' + maxoutbuf: '0' + maxsize: '64' + minoutbuf: '0' + minsize: '64' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [80, 100.0] + rotation: 180 + state: true +- name: phy_rx_0 + id: phy_rx + parameters: + affinity: '' + alias: '' + comment: '' + excess_bw: '0.350' + maxoutbuf: '0' + minoutbuf: '0' + sps: '2' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [552, 152.0] + rotation: 0 + state: true +- name: phy_tx_0 + id: phy_tx + parameters: + affinity: '' + alias: '' + comment: '' + excess_bw: '0.350' + maxoutbuf: '0' + minoutbuf: '0' + phasing: '20' + sps: '2' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [80, 232.0] + rotation: 0 + state: true +- name: qtgui_const_sink_x_0 + id: qtgui_const_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: '"blue"' + color10: '"red"' + color2: '"red"' + color3: '"red"' + color4: '"red"' + color5: '"red"' + color6: '"red"' + color7: '"red"' + color8: '"red"' + color9: '"red"' + comment: '' + grid: 'False' + gui_hint: '' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: '0' + marker10: '0' + marker2: '0' + marker3: '0' + marker4: '0' + marker5: '0' + marker6: '0' + marker7: '0' + marker8: '0' + marker9: '0' + name: '"Symbol Sync"' + nconnections: '1' + size: '256' + style1: '0' + style10: '0' + style2: '0' + style3: '0' + style4: '0' + style5: '0' + style6: '0' + style7: '0' + style8: '0' + style9: '0' + tr_chan: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_TAG + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '"corr_est"' + type: complex + update_time: '0.10' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + xmax: '2' + xmin: '-2' + ymax: '2' + ymin: '-2' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [800, 116.0] + rotation: 0 + state: enabled +- name: qtgui_const_sink_x_0_0 + id: qtgui_const_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: '"blue"' + color10: '"red"' + color2: '"red"' + color3: '"red"' + color4: '"red"' + color5: '"red"' + color6: '"red"' + color7: '"red"' + color8: '"red"' + color9: '"red"' + comment: '' + grid: 'False' + gui_hint: '' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: '0' + marker10: '0' + marker2: '0' + marker3: '0' + marker4: '0' + marker5: '0' + marker6: '0' + marker7: '0' + marker8: '0' + marker9: '0' + name: '"Costas Loop"' + nconnections: '1' + size: '256' + style1: '0' + style10: '0' + style2: '0' + style3: '0' + style4: '0' + style5: '0' + style6: '0' + style7: '0' + style8: '0' + style9: '0' + tr_chan: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_TAG + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '"corr_est"' + type: complex + update_time: '0.10' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + xmax: '2' + xmin: '-2' + ymax: '2' + ymin: '-2' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [800, 196.0] + rotation: 0 + state: enabled +- name: qtgui_time_sink_x_0 + id: qtgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: blue + color10: dark blue + color2: red + color3: green + color4: black + color5: cyan + color6: magenta + color7: yellow + color8: dark red + color9: dark green + comment: '' + ctrlpanel: 'False' + entags: 'True' + grid: 'False' + gui_hint: '' + label1: Signal 1 + label10: Signal 10 + label2: Signal 2 + label3: Signal 3 + label4: Signal 4 + label5: Signal 5 + label6: Signal 6 + label7: Signal 7 + label8: Signal 8 + label9: Signal 9 + legend: 'True' + marker1: '-1' + marker10: '-1' + marker2: '-1' + marker3: '-1' + marker4: '-1' + marker5: '-1' + marker6: '-1' + marker7: '-1' + marker8: '-1' + marker9: '-1' + name: '"Preamble"' + nconnections: '1' + size: '256' + srate: '1' + stemplot: 'False' + style1: '1' + style10: '1' + style2: '1' + style3: '1' + style4: '1' + style5: '1' + style6: '1' + style7: '1' + style8: '1' + style9: '1' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_TAG + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '"corr_est"' + type: float + update_time: '0.10' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + ylabel: Amplitude + ymax: '1.5' + ymin: '0' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [832, 276.0] + rotation: 0 + state: enabled +- name: qtgui_time_sink_x_1 + id: qtgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: blue + color10: dark blue + color2: red + color3: green + color4: black + color5: cyan + color6: magenta + color7: yellow + color8: dark red + color9: dark green + comment: '' + ctrlpanel: 'False' + entags: 'True' + grid: 'False' + gui_hint: '' + label1: Signal 1 + label10: Signal 10 + label2: Signal 2 + label3: Signal 3 + label4: Signal 4 + label5: Signal 5 + label6: Signal 6 + label7: Signal 7 + label8: Signal 8 + label9: Signal 9 + legend: 'True' + marker1: '-1' + marker10: '-1' + marker2: '-1' + marker3: '-1' + marker4: '-1' + marker5: '-1' + marker6: '-1' + marker7: '-1' + marker8: '-1' + marker9: '-1' + name: '"AGC"' + nconnections: '1' + size: '1024' + srate: '1' + stemplot: 'False' + style1: '1' + style10: '1' + style2: '1' + style3: '1' + style4: '1' + style5: '1' + style6: '1' + style7: '1' + style8: '1' + style9: '1' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_TAG + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '"corr_est"' + type: complex + update_time: '0.10' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + ylabel: Amplitude + ymax: '2' + ymin: '-2' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [816, 372.0] + rotation: 0 + state: true + +connections: +- [blocks_message_strobe_1, strobe, pdu_random_pdu_0, generate] +- [channels_channel_model_0, '0', phy_rx_0, '0'] +- [pdu_random_pdu_0, pdus, phy_tx_0, sdu] +- [phy_rx_0, '0', qtgui_const_sink_x_0, '0'] +- [phy_rx_0, '1', qtgui_const_sink_x_0_0, '0'] +- [phy_rx_0, '3', qtgui_time_sink_x_0, '0'] +- [phy_rx_0, '4', qtgui_time_sink_x_1, '0'] +- [phy_rx_0, pdu, blocks_message_debug_0, print] +- [phy_tx_0, '0', channels_channel_model_0, '0'] + +metadata: + file_format: 1 diff --git a/examples/cdc_phy_rx.grc b/examples/cdc_phy_rx.grc new file mode 100644 index 0000000000000000000000000000000000000000..65862b8ca694db4f7575b34c0e0c7b245ba6fba9 --- /dev/null +++ b/examples/cdc_phy_rx.grc @@ -0,0 +1,561 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[CDC]' + cmake_opt: '' + comment: '' + copyright: University of Melbourne + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: hb + hier_block_src_path: '.:' + id: cdc_phy_rx_mod + 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: CDC PHY Rx (Mod) + window_size: (1000,1000) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: constel + id: variable_constellation + parameters: + comment: '' + const_points: '[-1-1j, -1+1j, 1+1j, 1-1j]' + dims: '1' + normalization: digital.constellation.AMPLITUDE_NORMALIZATION + precision: '8' + rot_sym: '4' + soft_dec_lut: None + sym_map: '[0, 1, 3, 2]' + type: bpsk + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [200, 420.0] + rotation: 0 + state: true +- name: modulated_sync_word + id: variable + parameters: + comment: '' + value: np.array([ 6.3415498e-01+0.j, -8.2522854e-02+0.j, -6.7432624e-01+0.j, 2.1960361e-02+0.j, 6.6994393e-01+0.j, 2.7926212e-02+0.j, + -6.2773204e-01+0.j, -1.6468078e-01+0.j, 5.7718420e-01+0.j, 7.2756535e-01+0.j, 4.6373290e-01+0.j, 2.3871353e-02+0.j, + -4.8910391e-01+0.j, -7.3612314e-01+0.j, -4.8162562e-01+0.j, 1.2282493e-02+0.j, 4.6576929e-01+0.j, 7.3573601e-01+0.j, + 5.4807413e-01+0.j, -1.3198391e-01+0.j, -5.6807721e-01+0.j, -1.1599341e-01+0.j, 6.0297143e-01+0.j, 6.1259979e-01+0.j, + 3.7387580e-01+0.j, 6.1534089e-01+0.j, 6.1044985e-01+0.j, -1.3032347e-01+0.j, + -5.7351917e-01+0.j, -1.1359498e-01+0.j, 5.1318854e-01+0.j, 7.6605660e-01+0.j, 5.5351597e-01+0.j, + -1.7184576e-01+0.j, -6.0304552e-01+0.j, -5.2386895e-09+0.j, 6.0304564e-01+0.j, 1.7458701e-01+0.j, + -5.4603779e-01+0.j, -7.7764541e-01+0.j, -5.1115209e-01+0.j, 1.2587748e-01+0.j, + 5.5562639e-01+0.j, 1.4426640e-01+0.j, -5.5147964e-01+0.j, -7.4326605e-01+0.j, + -4.9114031e-01+0.j, 2.7579335e-02+0.j, 5.3652304e-01+0.j, 5.9185678e-01+0.j, 4.3005973e-01+0.j, + 5.5639654e-01+0.j, 5.7140875e-01+0.j, 1.4330061e-02+0.j, -5.7344508e-01+0.j, + -5.8026785e-01+0.j, -4.0265229e-01+0.j, -6.0784715e-01+0.j, -6.1882788e-01+0.j, 1.3541880e-01+0.j, + 6.3996756e-01+0.j, -1.1588858e-02+0.j, -6.3045293e-01+0.j, -1.2313626e-01+0.j, 5.9345692e-01+0.j, 6.3337904e-01+0.j, + 4.5958614e-01+0.j, 4.4280154e-01+0.j, 4.8155165e-01+0.j, 6.0579962e-01+0.j, 5.2610868e-01+0.j, 2.5531810e-02+0.j, + -4.9454585e-01+0.j, -7.3372471e-01+0.j, -5.7140863e-01+0.j, 1.6025695e-01+0.j, 6.3045293e-01+0.j, + -2.2790564e-02+0.j, -6.5453744e-01+0.j, -4.3920707e-02+0.j, 6.6330218e-01+0.j, + 1.3472509e-01+0.j, -6.3582081e-01+0.j, -5.8741081e-01+0.j, -4.1216698e-01+0.j, + -5.9255040e-01+0.j, -5.4807413e-01+0.j, -1.3942933e-02+0.j, 5.0699669e-01+0.j, 7.0545167e-01+0.j, + 5.1991683e-01+0.j, -3.5073120e-02+0.j, -5.2814502e-01+0.j, -5.9695208e-01+0.j, + -4.9650821e-01+0.j, -4.3669510e-01+0.j, -4.6910083e-01+0.j, -6.3407266e-01+0.j, + -5.7760048e-01+0.j, 9.9652052e-02+0.j, 5.9685379e-01+0.j, 1.1398210e-01+0.j, + -5.7963693e-01+0.j, -6.4087272e-01+0.j, -4.3625149e-01+0.j, -4.7107458e-01+0.j, + -5.4392737e-01+0.j, -4.6153325e-01+0.j, -4.5958611e-01+0.j, -6.1738855e-01+0.j, + -5.3855950e-01+0.j, 2.7412227e-03+0.j, 5.4603767e-01+0.j, 6.0305846e-01+0.j, + 4.5414424e-01+0.j, 4.7992218e-01+0.j, 5.0904173e-01+0.j, 4.9728334e-01+0.j, 5.1278079e-01+0.j, 4.7549835e-01+0.j, + 4.5890158e-01+0.j, 6.0340530e-01+0.j, 5.3810960e-01+0.j, 1.3112724e-02+0.j, + -5.2549899e-01+0.j, -6.6004950e-01+0.j, -4.8329139e-01+0.j, -2.2242454e-01+0.j], + dtype=np.complex64) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [160, 156.0] + rotation: 0 + state: true +- name: nfilts + id: variable + parameters: + comment: '' + value: '32' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [672, 20.0] + rotation: 0 + state: true +- name: rrc_taps + id: variable_rrc_filter_taps + parameters: + alpha: excess_bw + comment: '' + gain: nfilts + ntaps: 11*sps*nfilts + samp_rate: sps*nfilts + sym_rate: '1.0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [744, 20.0] + rotation: 0 + state: true +- name: blocks_multiply_by_tag_value_cc_0 + id: blocks_multiply_by_tag_value_cc + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + tagname: amp_est + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [392, 212.0] + rotation: 0 + state: true +- name: blocks_repack_bits_bb_0 + id: blocks_repack_bits_bb + parameters: + affinity: '' + alias: '' + align_output: 'True' + comment: '' + endianness: gr.GR_MSB_FIRST + k: constel.bits_per_symbol() + l: '8' + len_tag_key: '"packet_len"' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [720, 364.0] + rotation: 0 + state: true +- name: cdc_preamble_detect_cc_0 + id: cdc_preamble_detect_cc + parameters: + affinity: '' + alias: '' + comment: '' + mark_delay: '0' + maxoutbuf: '0' + minoutbuf: '0' + sequence: modulated_sync_word + threshold: '0.5' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [152, 220.0] + rotation: 0 + state: true +- name: digital_additive_scrambler_bb_0 + id: digital_additive_scrambler_bb + parameters: + affinity: '' + alias: '' + bits_per_byte: '8' + comment: '' + count: '0' + len: '7' + mask: '0x8A' + maxoutbuf: '0' + minoutbuf: '0' + reset_tag_key: '"packet_len"' + seed: '0x7F' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [192, 492.0] + rotation: 0 + state: true +- name: digital_constellation_decoder_cb_0 + id: digital_constellation_decoder_cb + parameters: + affinity: '' + alias: '' + comment: '' + constellation: constel + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [200, 372.0] + rotation: 0 + state: true +- name: digital_correlate_access_code_xx_ts_0 + id: digital_correlate_access_code_xx_ts + parameters: + access_code: digital.packet_utils.default_access_code + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + tagname: packet_len + threshold: '3' + type: byte + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [432, 356.0] + rotation: 0 + state: true +- name: digital_costas_loop_cc_0 + id: digital_costas_loop_cc + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + order: constel.arity() + use_snr: 'False' + w: '0.035' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1024, 144.0] + rotation: 0 + state: true +- name: digital_crc32_async_bb_0 + id: digital_crc32_async_bb + parameters: + affinity: '' + alias: '' + check: 'True' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [632, 532.0] + rotation: 0 + state: true +- name: digital_symbol_sync_xx_0 + id: digital_symbol_sync_xx + parameters: + affinity: '' + alias: '' + comment: '' + constellation: digital.constellation_bpsk().base() + damping: '1.0' + loop_bw: 0.045/2 + max_dev: '1.5' + maxoutbuf: '0' + minoutbuf: '0' + nfilters: nfilts + osps: '1' + pfb_mf_taps: rrc_taps + resamp_type: digital.IR_PFB_MF + sps: sps + ted_gain: '1.0' + ted_type: digital.TED_EARLY_LATE + type: cc + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [624, 148.0] + rotation: 0 + state: true +- name: excess_bw + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: Excess Bw + short_id: '' + type: eng_float + value: '0.350' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [336, 12.0] + rotation: 0 + state: true +- name: import_0 + id: import + parameters: + alias: '' + comment: '' + imports: import numpy as np + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [80, 156.0] + rotation: 0 + state: true +- name: pad_sink_0 + id: pad_sink + parameters: + affinity: '' + alias: '' + comment: '' + label: pdu + num_streams: '1' + optional: 'True' + type: message + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [792, 532.0] + rotation: 0 + state: true +- name: pad_sink_1 + id: pad_sink + parameters: + affinity: '' + alias: '' + comment: '' + label: timing + num_streams: '1' + optional: 'True' + type: complex + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1024, 276.0] + rotation: 0 + state: true +- name: pad_sink_1_0 + id: pad_sink + parameters: + affinity: '' + alias: '' + comment: '' + label: symbols + num_streams: '1' + optional: 'True' + type: complex + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1280, 188.0] + rotation: 0 + state: true +- name: pad_sink_1_1 + id: pad_sink + parameters: + affinity: '' + alias: '' + comment: '' + label: packet + num_streams: '1' + optional: 'True' + type: byte + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [400, 580.0] + rotation: 0 + state: true +- name: pad_sink_1_2 + id: pad_sink + parameters: + affinity: '' + alias: '' + comment: '' + label: corr + num_streams: '1' + optional: 'True' + type: float + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [264, 300.0] + rotation: 180 + state: true +- name: pad_sink_1_3 + id: pad_sink + parameters: + affinity: '' + alias: '' + comment: '' + label: agc + num_streams: '1' + optional: 'True' + type: complex + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [472, 276.0] + rotation: 180 + state: true +- name: pad_source_0 + id: pad_source + parameters: + affinity: '' + alias: '' + comment: '' + label: iq + maxoutbuf: '0' + minoutbuf: '0' + num_streams: '1' + optional: 'False' + type: complex + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [16, 236.0] + rotation: 0 + state: true +- name: pdu_tagged_stream_to_pdu_0 + id: pdu_tagged_stream_to_pdu + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + tag: packet_len + type: byte + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [400, 532.0] + rotation: 0 + state: true +- name: sps + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: Samps per Symb + short_id: '' + type: intx + value: '2' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [192, 12.0] + rotation: 0 + state: true +- name: virtual_sink_0 + id: virtual_sink + parameters: + alias: '' + comment: '' + stream_id: symbols + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1280, 140.0] + rotation: 0 + state: true +- name: virtual_sink_0_0 + id: virtual_sink + parameters: + alias: '' + comment: '' + stream_id: bytes + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [928, 372.0] + rotation: 0 + state: true +- name: virtual_source_0 + id: virtual_source + parameters: + alias: '' + comment: '' + stream_id: symbols + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [16, 372.0] + rotation: 0 + state: true +- name: virtual_source_0_0 + id: virtual_source + parameters: + alias: '' + comment: '' + stream_id: bytes + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [16, 532.0] + rotation: 0 + state: true + +connections: +- [blocks_multiply_by_tag_value_cc_0, '0', digital_symbol_sync_xx_0, '0'] +- [blocks_multiply_by_tag_value_cc_0, '0', pad_sink_1_3, '0'] +- [blocks_repack_bits_bb_0, '0', virtual_sink_0_0, '0'] +- [cdc_preamble_detect_cc_0, '0', blocks_multiply_by_tag_value_cc_0, '0'] +- [cdc_preamble_detect_cc_0, '1', pad_sink_1_2, '0'] +- [digital_additive_scrambler_bb_0, '0', pad_sink_1_1, '0'] +- [digital_additive_scrambler_bb_0, '0', pdu_tagged_stream_to_pdu_0, '0'] +- [digital_constellation_decoder_cb_0, '0', digital_correlate_access_code_xx_ts_0, + '0'] +- [digital_correlate_access_code_xx_ts_0, '0', blocks_repack_bits_bb_0, '0'] +- [digital_costas_loop_cc_0, '0', pad_sink_1_0, '0'] +- [digital_costas_loop_cc_0, '0', virtual_sink_0, '0'] +- [digital_crc32_async_bb_0, out, pad_sink_0, in] +- [digital_symbol_sync_xx_0, '0', digital_costas_loop_cc_0, '0'] +- [digital_symbol_sync_xx_0, '0', pad_sink_1, '0'] +- [pad_source_0, '0', cdc_preamble_detect_cc_0, '0'] +- [pdu_tagged_stream_to_pdu_0, pdus, digital_crc32_async_bb_0, in] +- [virtual_source_0, '0', digital_constellation_decoder_cb_0, '0'] +- [virtual_source_0_0, '0', digital_additive_scrambler_bb_0, '0'] + +metadata: + file_format: 1 diff --git a/examples/cdc_phy_tx.grc b/examples/cdc_phy_tx.grc new file mode 100644 index 0000000000000000000000000000000000000000..bd2e60bb1a514d3014cc0feec19def028e15bbbd --- /dev/null +++ b/examples/cdc_phy_tx.grc @@ -0,0 +1,453 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[CDC]' + cmake_opt: '' + comment: '' + copyright: University of Melbourne + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: hb + hier_block_src_path: '.:' + id: cdc_phy_tx_mod + 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: CDC PHY Tx (Mod) + window_size: (1000,1000) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: access_code + id: variable + parameters: + comment: '' + value: digital.packet_utils.default_access_code + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [768, 12.0] + rotation: 0 + state: true +- name: constel + id: variable_constellation + parameters: + comment: '' + const_points: '[-1-1j, -1+1j, 1+1j, 1-1j]' + dims: '1' + normalization: digital.constellation.AMPLITUDE_NORMALIZATION + precision: '8' + rot_sym: '4' + soft_dec_lut: None + sym_map: '[0, 1, 3, 2]' + type: bpsk + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [192, 388.0] + rotation: 0 + state: true +- name: header_format + id: variable + parameters: + comment: '' + value: digital.header_format_default(access_code, 0, constel.bits_per_symbol()) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [952, 12.0] + rotation: 0 + state: true +- name: num_taps + id: variable + parameters: + comment: '' + value: 11*sps + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1024, 404.0] + rotation: 0 + state: true +- name: blocks_repack_bits_bb_0 + id: blocks_repack_bits_bb + parameters: + affinity: '' + alias: '' + align_output: 'False' + comment: '' + endianness: gr.GR_MSB_FIRST + k: '8' + l: constel.bits_per_symbol() + len_tag_key: '"packet_len"' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [192, 316.0] + rotation: 0 + state: true +- name: blocks_tagged_stream_mux_0 + id: blocks_tagged_stream_mux + parameters: + affinity: '' + alias: '' + comment: '' + lengthtagname: packet_len + maxoutbuf: '0' + minoutbuf: '0' + ninputs: '2' + tag_preserve_head_pos: '0' + type: byte + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1016, 128.0] + rotation: 0 + state: true +- name: cdc_tag_tx_burst_cc_0 + id: cdc_tag_tx_burst_cc + parameters: + affinity: '' + alias: '' + comment: '' + lengthtagname: packet_len + maxoutbuf: '0' + minoutbuf: '0' + scalar: sps + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1168, 308.0] + rotation: 0 + state: true +- name: digital_additive_scrambler_bb_0 + id: digital_additive_scrambler_bb + parameters: + affinity: '' + alias: '' + bits_per_byte: '8' + comment: '' + count: '0' + len: '7' + mask: '0x8A' + maxoutbuf: '0' + minoutbuf: '0' + reset_tag_key: '"packet_len"' + seed: '0x7F' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [568, 124.0] + rotation: 0 + state: true +- name: digital_burst_shaper_xx_0 + id: digital_burst_shaper_xx + parameters: + affinity: '' + alias: '' + comment: '' + insert_phasing: 'True' + length_tag_name: '"packet_len"' + maxoutbuf: '0' + minoutbuf: '0' + post_padding: num_taps//2 + pre_padding: '0' + type: complex + window: firdes.window(window.WIN_HANN, phasing, 0) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [696, 284.0] + rotation: 0 + state: true +- name: digital_chunks_to_symbols_xx_0 + id: digital_chunks_to_symbols_xx + parameters: + affinity: '' + alias: '' + comment: '' + dimension: '1' + in_type: byte + maxoutbuf: '0' + minoutbuf: '0' + num_ports: '1' + out_type: complex + symbol_table: constel.points() + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [496, 304.0] + rotation: 0 + state: true +- name: digital_crc32_async_bb_0 + id: digital_crc32_async_bb + parameters: + affinity: '' + alias: '' + check: 'False' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [152, 164.0] + rotation: 0 + state: true +- name: digital_protocol_formatter_bb_0 + id: digital_protocol_formatter_bb + parameters: + affinity: '' + alias: '' + comment: '' + format: header_format + len_tag_key: '"packet_len"' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [768, 116.0] + rotation: 0 + state: true +- name: excess_bw + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: Excess Bw + short_id: '' + type: eng_float + value: '0.350' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [336, 12.0] + rotation: 0 + state: true +- name: pad_sink_0 + id: pad_sink + parameters: + affinity: '' + alias: '' + comment: '' + label: iq + num_streams: '1' + optional: 'False' + type: complex + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1400, 316.0] + rotation: 0 + state: true +- name: pad_sink_1 + id: pad_sink + parameters: + affinity: '' + alias: '' + comment: '' + label: burst + num_streams: '1' + optional: 'True' + type: complex + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [936, 404.0] + rotation: 0 + state: true +- name: pad_sink_1_0 + id: pad_sink + parameters: + affinity: '' + alias: '' + comment: '' + label: symbols + num_streams: '1' + optional: 'True' + type: complex + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [696, 396.0] + rotation: 0 + state: true +- name: pad_source_0 + id: pad_source + parameters: + affinity: '' + alias: '' + comment: '' + label: sdu + maxoutbuf: '0' + minoutbuf: '0' + num_streams: '1' + optional: 'True' + type: message + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [16, 164.0] + rotation: 0 + state: true +- name: pdu_pdu_to_tagged_stream_0 + id: pdu_pdu_to_tagged_stream + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + tag: packet_len + type: byte + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [344, 164.0] + rotation: 0 + state: true +- name: phasing + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: Phasing Symbols + short_id: '' + type: intx + value: '20' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [448, 12.0] + rotation: 0 + state: true +- name: root_raised_cosine_filter_0 + id: root_raised_cosine_filter + parameters: + affinity: '' + alias: '' + alpha: excess_bw + comment: '' + decim: '1' + gain: '1.0' + interp: sps + maxoutbuf: '0' + minoutbuf: '0' + ntaps: num_taps + samp_rate: sps + sym_rate: '1.0' + type: interp_fir_filter_ccf + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [936, 276.0] + rotation: 0 + state: true +- name: sps + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: Samps per Symb + short_id: '' + type: intx + value: '2' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [192, 12.0] + rotation: 0 + state: true +- name: virtual_sink_0 + id: virtual_sink + parameters: + alias: '' + comment: '' + stream_id: tx_bytes + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1248, 140.0] + rotation: 0 + state: true +- name: virtual_source_0 + id: virtual_source + parameters: + alias: '' + comment: '' + stream_id: tx_bytes + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [16, 324.0] + rotation: 0 + state: true + +connections: +- [blocks_repack_bits_bb_0, '0', digital_chunks_to_symbols_xx_0, '0'] +- [blocks_tagged_stream_mux_0, '0', virtual_sink_0, '0'] +- [cdc_tag_tx_burst_cc_0, '0', pad_sink_0, '0'] +- [digital_additive_scrambler_bb_0, '0', blocks_tagged_stream_mux_0, '1'] +- [digital_additive_scrambler_bb_0, '0', digital_protocol_formatter_bb_0, '0'] +- [digital_burst_shaper_xx_0, '0', pad_sink_1, '0'] +- [digital_burst_shaper_xx_0, '0', root_raised_cosine_filter_0, '0'] +- [digital_chunks_to_symbols_xx_0, '0', digital_burst_shaper_xx_0, '0'] +- [digital_chunks_to_symbols_xx_0, '0', pad_sink_1_0, '0'] +- [digital_crc32_async_bb_0, out, pdu_pdu_to_tagged_stream_0, pdus] +- [digital_protocol_formatter_bb_0, '0', blocks_tagged_stream_mux_0, '0'] +- [pad_source_0, out, digital_crc32_async_bb_0, in] +- [pdu_pdu_to_tagged_stream_0, '0', digital_additive_scrambler_bb_0, '0'] +- [root_raised_cosine_filter_0, '0', cdc_tag_tx_burst_cc_0, '0'] +- [virtual_source_0, '0', blocks_repack_bits_bb_0, '0'] + +metadata: + file_format: 1 diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index 49a597df0d6617ad013021f3f8579a993c6aa5bf..31c18d1e357264535f1c633bdfce9b43ef1b4b9d 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -5,7 +5,9 @@ # # SPDX-License-Identifier: GPL-3.0-or-later # - install(FILES - DESTINATION share/gnuradio/grc/blocks + cdc_tag_tx_burst_cc.block.yml + cdc_preamble_detect_cc.block.yml + cdc_phy_tx.block.yml + cdc_phy_rx.block.yml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/cdc_phy_rx.block.yml b/grc/cdc_phy_rx.block.yml new file mode 100644 index 0000000000000000000000000000000000000000..6a806a2eae53e1a6f9c207f6660fbdc4b650541b --- /dev/null +++ b/grc/cdc_phy_rx.block.yml @@ -0,0 +1,58 @@ +id: phy_rx +label: CDC PHY Rx +category: '[CDC]' + +parameters: +- id: excess_bw + label: Excess Bw + dtype: real + default: '0.350' + hide: none +- id: sps + label: Samps per Symb + dtype: int + default: '2' + hide: none + +inputs: +- label: iq + dtype: complex + vlen: 1 + +outputs: +- label: pdu + domain: message + dtype: message + optional: true +- label: timing + dtype: complex + vlen: 1 + optional: true +- label: symbols + dtype: complex + vlen: 1 + optional: true +- label: packet + dtype: byte + vlen: 1 + optional: true +- label: corr + dtype: float + vlen: 1 + optional: true +- label: agc + dtype: complex + vlen: 1 + optional: true + +templates: + imports: 'from phy_rx import phy_rx # grc-generated hier_block' + make: "phy_rx(\n excess_bw=${ excess_bw },\n sps=${ sps },\n)" + callbacks: + - set_excess_bw(${ excess_bw }) + - set_sps(${ sps }) + +documentation: /home/gjbradford/code/gnuradio/gr/gr-cdc/examples/phy_rx.py +grc_source: /home/gjbradford/code/gnuradio/gr/gr-cdc/examples/cdc_phy_rx.grc + +file_format: 1 diff --git a/grc/cdc_phy_tx.block.yml b/grc/cdc_phy_tx.block.yml new file mode 100644 index 0000000000000000000000000000000000000000..8f58df9553bab0f5a5fe52ba329ef5577c55e5e6 --- /dev/null +++ b/grc/cdc_phy_tx.block.yml @@ -0,0 +1,53 @@ +id: phy_tx +label: CDC PHY Tx +category: '[CDC]' + +parameters: +- id: excess_bw + label: Excess Bw + dtype: real + default: '0.350' + hide: none +- id: phasing + label: Phasing Symbols + dtype: int + default: '20' + hide: none +- id: sps + label: Samps per Symb + dtype: int + default: '2' + hide: none + +inputs: +- label: sdu + domain: message + dtype: message + optional: true + +outputs: +- label: iq + dtype: complex + vlen: 1 +- label: burst + dtype: complex + vlen: 1 + optional: true +- label: symbols + dtype: complex + vlen: 1 + optional: true + +templates: + imports: 'from phy_tx import phy_tx # grc-generated hier_block' + make: "phy_tx(\n excess_bw=${ excess_bw },\n phasing=${ phasing },\n \ + \ sps=${ sps },\n)" + callbacks: + - set_excess_bw(${ excess_bw }) + - set_phasing(${ phasing }) + - set_sps(${ sps }) + +documentation: /home/gjbradford/code/gnuradio/gr/gr-cdc/examples/phy_tx.py +grc_source: /home/gjbradford/code/gnuradio/gr/gr-cdc/examples/cdc_phy_tx.grc + +file_format: 1 diff --git a/grc/cdc_preamble_detect_cc.block.yml b/grc/cdc_preamble_detect_cc.block.yml new file mode 100644 index 0000000000000000000000000000000000000000..b56910479e0b5d38dc0aa63e40d799b71aa8254c --- /dev/null +++ b/grc/cdc_preamble_detect_cc.block.yml @@ -0,0 +1,35 @@ +id: cdc_preamble_detect_cc +label: Preamble Detect +category: '[CDC]' + +templates: + imports: from gnuradio import cdc + make: cdc.preamble_detect_cc(${sequence}, ${threshold}, ${mark_delay}) + +parameters: +- id: sequence + label: Sequence + dtype: complex_vector +- id: threshold + label: Threshold + default: '0.5' + dtype: float +- id: mark_delay + label: Mark delay + default: '0' + dtype: int + +inputs: +- label: in + domain: stream + dtype: complex + +outputs: +- label: out + domain: stream + dtype: complex +- label: out + domain: stream + dtype: float + +file_format: 1 diff --git a/grc/cdc_tag_tx_burst_cc.block.yml b/grc/cdc_tag_tx_burst_cc.block.yml new file mode 100644 index 0000000000000000000000000000000000000000..9e48dbe21bbf19477d7705a036b597b37a4936d3 --- /dev/null +++ b/grc/cdc_tag_tx_burst_cc.block.yml @@ -0,0 +1,29 @@ +id: cdc_tag_tx_burst_cc +label: Tag Tx Burst +category: '[CDC]' + +templates: + imports: from gnuradio import cdc + make: cdc.tag_tx_burst_cc(${lengthtagname}, ${scalar}) + +parameters: +- id: lengthtagname + label: Length tag name + dtype: string + default: 'packet_len' +- id: scalar + label: Scalar + dtype: int + default: + +inputs: +- label: in + domain: stream + dtype: complex + +outputs: +- label: out + domain: stream + dtype: complex + +file_format: 1 diff --git a/include/gnuradio/cdc/CMakeLists.txt b/include/gnuradio/cdc/CMakeLists.txt index 864df4f841a39a4a1ef6051922c69d8a9a967f94..75345f8917ac7f03559dc9a6e7902775d0c975de 100644 --- a/include/gnuradio/cdc/CMakeLists.txt +++ b/include/gnuradio/cdc/CMakeLists.txt @@ -11,5 +11,6 @@ ######################################################################## install(FILES api.h - DESTINATION include/gnuradio/cdc + tag_tx_burst_cc.h + preamble_detect_cc.h DESTINATION include/gnuradio/cdc ) diff --git a/include/gnuradio/cdc/preamble_detect_cc.h b/include/gnuradio/cdc/preamble_detect_cc.h new file mode 100644 index 0000000000000000000000000000000000000000..6e9cda4b6831d59d8c839ffe15c06f18731b0c76 --- /dev/null +++ b/include/gnuradio/cdc/preamble_detect_cc.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- */ +/* + * Copyright 2023 University of Melbourne. + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#ifndef INCLUDED_CDC_PREAMBLE_DETECT_CC_H +#define INCLUDED_CDC_PREAMBLE_DETECT_CC_H + +#include <gnuradio/cdc/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { +namespace cdc { + +/*! + * \brief <+description of block+> + * \ingroup cdc + * + */ +class CDC_API preamble_detect_cc : virtual public gr::sync_block { +public: + typedef std::shared_ptr<preamble_detect_cc> sptr; + + static sptr make(const std::vector<gr_complex>& sequence, + float threshold = 0.5, + unsigned int mark_delay = 0); + + virtual std::vector<gr_complex> sequence() const = 0; + virtual void set_sequence(const std::vector<gr_complex>& sequence) = 0; + + virtual float threshold() const = 0; + virtual void set_threshold(float threshold) = 0; + + virtual unsigned int mark_delay(void) const = 0; + virtual void set_mark_delay(unsigned int mark_delay) = 0; +}; + +} // namespace cdc +} // namespace gr + +#endif /* INCLUDED_CDC_PREAMBLE_DETECT_CC_H */ diff --git a/include/gnuradio/cdc/tag_tx_burst_cc.h b/include/gnuradio/cdc/tag_tx_burst_cc.h new file mode 100644 index 0000000000000000000000000000000000000000..c5499f382491984435d5d21c43e6f61d1a18dd97 --- /dev/null +++ b/include/gnuradio/cdc/tag_tx_burst_cc.h @@ -0,0 +1,34 @@ +/* -*- c++ -*- */ +/* + * Copyright 2023 University of Melbourne. + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#ifndef INCLUDED_CDC_TAG_TX_BURST_CC_H +#define INCLUDED_CDC_TAG_TX_BURST_CC_H + +#include <gnuradio/cdc/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { +namespace cdc { + +/*! + * \brief <+description of block+> + * \ingroup cdc + * + */ +class CDC_API tag_tx_burst_cc : virtual public gr::sync_block +{ +public: + typedef std::shared_ptr<tag_tx_burst_cc> sptr; + + static sptr make(const std::string &lengthtagname, + int scalar); +}; + +} // namespace cdc +} // namespace gr + +#endif /* INCLUDED_CDC_TAG_TX_BURST_CC_H */ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 77cfc1ecf2430bb3ca79afb3ed5d82d6609beba3..3028ecff7ded67488521408cb7b003b4d0f90a33 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -12,6 +12,8 @@ include(GrPlatform) #define LIB_SUFFIX list(APPEND cdc_sources + tag_tx_burst_cc_impl.cc + preamble_detect_cc_impl.cc ) set(cdc_sources "${cdc_sources}" PARENT_SCOPE) @@ -21,7 +23,7 @@ if(NOT cdc_sources) endif(NOT cdc_sources) add_library(gnuradio-cdc SHARED ${cdc_sources}) -target_link_libraries(gnuradio-cdc gnuradio::gnuradio-runtime) +target_link_libraries(gnuradio-cdc gnuradio::gnuradio-runtime gnuradio-filter) target_include_directories(gnuradio-cdc PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include> PUBLIC $<INSTALL_INTERFACE:include> diff --git a/lib/preamble_detect_cc_impl.cc b/lib/preamble_detect_cc_impl.cc new file mode 100644 index 0000000000000000000000000000000000000000..d00f47e63cc83e8966ae1128c8868748016bf536 --- /dev/null +++ b/lib/preamble_detect_cc_impl.cc @@ -0,0 +1,207 @@ +/* -*- c++ -*- */ +/* + * Copyright 2023 University of Melbourne. + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "preamble_detect_cc_impl.h" +#include <gnuradio/io_signature.h> +#include <gnuradio/math.h> + + +namespace gr { +namespace cdc { + +preamble_detect_cc::sptr preamble_detect_cc::make(const std::vector<gr_complex>& sequence, + float threshold, + unsigned int mark_delay) +{ + return gnuradio::make_block_sptr<preamble_detect_cc_impl>( + sequence, threshold, mark_delay); +} + +preamble_detect_cc_impl::preamble_detect_cc_impl(const std::vector<gr_complex>& sequence, + float threshold, + unsigned int mark_delay) + : gr::sync_block("preamble_detect_cc", + gr::io_signature::make(1, 1, sizeof(gr_complex)), + gr::io_signature::make2(1, 2, sizeof(gr_complex), sizeof(float))), + d_src_id(pmt::intern(alias())), + d_sequence(sequence.size()), + d_threshold(threshold), + d_mark_delay(mark_delay), + d_filter(1, sequence), + d_corr(s_nitems), + d_corr_mag(s_nitems), + d_y_mag(s_nitems + sequence.size()), + d_y_accum(0.0), + d_skip(0) +{ + set_max_noutput_items(s_nitems); + set_sequence(sequence); +} + +preamble_detect_cc_impl::~preamble_detect_cc_impl() {} + +std::vector<gr_complex> preamble_detect_cc_impl::sequence() const +{ + return d_sequence; +} + +void preamble_detect_cc_impl::set_sequence(const std::vector<gr_complex>& sequence) +{ + gr::thread::scoped_lock lock(d_setlock); + + d_sequence = sequence; + + // create time-reversed conjugate of training sequence for filtering + std::vector<gr_complex> taps(sequence.size()); + std::reverse_copy(sequence.begin(), sequence.end(), taps.begin()); + d_scale = 0.0; + for (size_t i = 0; i < taps.size(); i++) { + taps[i] = std::conj(taps[i]); + d_scale += std::norm(taps[i]); + } + d_scale = 1.0 / sqrt(d_scale); + for (size_t i = 0; i < taps.size(); i++) { + taps[i] *= d_scale; + } + + // set taps and block output multiple to FFT kernel's internal nsamples + const int nsamples = d_filter.set_taps(taps); + set_output_multiple(nsamples); + + // keep a history of the length of the sync word to delay for tagging + set_history(d_sequence.size()); + declare_sample_delay(0, sequence.size()); + declare_sample_delay(1, 0); +} + +float preamble_detect_cc_impl::threshold() const +{ + return d_threshold; +} + +void preamble_detect_cc_impl::set_threshold(float threshold) +{ + gr::thread::scoped_lock lock(d_setlock); + d_threshold = threshold; +} + +unsigned int preamble_detect_cc_impl::mark_delay() const +{ + return d_mark_delay; +} + +void preamble_detect_cc_impl::set_mark_delay(unsigned int mark_delay) +{ + gr::thread::scoped_lock lock(d_setlock); + d_mark_delay = mark_delay; +} + +int preamble_detect_cc_impl::work(int noutput_items, + gr_vector_const_void_star& input_items, + gr_vector_void_star& output_items) +{ + auto in = static_cast<const gr_complex*>(input_items[0]); + auto out = static_cast<gr_complex*>(output_items[0]); + + float* corr_mag; + if (output_items.size() > 1) { + corr_mag = static_cast<float*>(output_items[1]); + } else { + corr_mag = d_corr_mag.data(); + } + + unsigned int hist_len = history() - 1; + + float threshold; + { + gr::thread::scoped_lock lock(d_setlock); + threshold = d_threshold; + } + + // correlate input samples with training sequence + d_filter.filter(noutput_items, &in[hist_len], d_corr.data()); + + // calculate squared magnitude of correlation result + volk_32fc_magnitude_squared_32f(corr_mag, d_corr.data(), noutput_items); + + // calculate squared magnitued of input samples for normalization + volk_32fc_magnitude_squared_32f(d_y_mag.data(), in, noutput_items + hist_len); + + // initialize moving average filter + d_y_accum = 0; + for (int i = 0; i < hist_len; i++) { + d_y_accum += d_y_mag[i]; + } + + // search for correlation peaks above threshold + for (int i = 0; i < noutput_items; i++) { + // add sample to moving average + d_y_accum += d_y_mag[hist_len + i]; + + // normalize cross-correlation + corr_mag[i] /= d_y_accum; + + // drop oldest sample from moving average + d_y_accum -= d_y_mag[i]; + + if (d_skip > 0) { + d_skip--; + continue; + } + + if (corr_mag[i] > threshold) { + // single-tap (inverse) channel estimate + gr_complex chan_est = d_corr[i] * d_scale; + double amp_est = 1.0 / std::abs(chan_est); + double phase_est = std::arg(chan_est); + + // time phase estimate - center-of-mass (3 samples) + float m1 = corr_mag[i-1]; + float m2 = corr_mag[i+0]; + float m3 = corr_mag[i+1] / (d_y_accum + d_y_mag[hist_len+i+1]); + double nom = m1 + 2*m2 + 3*m3; + double den = m1 + m2 + m3; + double time_est = (nom/den) - 2.0; + + // tag output + int offset = nitems_written(0) + i; + for (unsigned int ch = 0; ch < output_items.size(); ch++) { + add_item_tag(ch, offset, + pmt::intern("corr_start"), + pmt::from_double(corr_mag[i]), + d_src_id); + add_item_tag(ch, offset + d_mark_delay, + pmt::intern("corr_est"), + pmt::from_double(corr_mag[i]), + d_src_id); + add_item_tag(ch, offset + d_mark_delay, + pmt::intern("amp_est"), + pmt::from_complex(amp_est), + d_src_id); + add_item_tag(ch, offset + d_mark_delay, + pmt::intern("phase_est"), // reset Costas Loop to zero phase + pmt::from_double(phase_est), + d_src_id); + add_item_tag(ch, offset + d_mark_delay, + pmt::intern("time_est"), + pmt::from_double(time_est), + d_src_id); + } + + // skip remaining symbols in sequence + d_skip = d_sequence.size() - 1; + } + } + + // pass through input samples but with delay of history() + memcpy(out, &in[0], sizeof(gr_complex)*noutput_items); + + return noutput_items; +} + +} /* namespace cdc */ +} /* namespace gr */ diff --git a/lib/preamble_detect_cc_impl.h b/lib/preamble_detect_cc_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..9177a346802d20d8409cbc78287a6034b6c4727e --- /dev/null +++ b/lib/preamble_detect_cc_impl.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2023 University of Melbourne. + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#ifndef INCLUDED_CDC_PREAMBLE_DETECT_CC_IMPL_H +#define INCLUDED_CDC_PREAMBLE_DETECT_CC_IMPL_H + +#include <gnuradio/cdc/preamble_detect_cc.h> +#include <gnuradio/filter/fft_filter.h> + +using namespace gr::filter; + +namespace gr { +namespace cdc { + +class preamble_detect_cc_impl : public preamble_detect_cc { +private: + pmt::pmt_t d_src_id; + + std::vector<gr_complex> d_sequence; + float d_threshold; + unsigned int d_mark_delay; + + kernel::fft_filter_ccc d_filter; + volk::vector<gr_complex> d_corr; + volk::vector<float> d_corr_mag; + volk::vector<float> d_y_mag; + float d_scale; + float d_y_accum; + int d_skip; + + static constexpr int s_nitems = 24*1024; + +public: + preamble_detect_cc_impl(const std::vector<gr_complex> &sequence, + float threshold, + unsigned int mark_delay); + ~preamble_detect_cc_impl() override; + + std::vector<gr_complex> sequence() const override; + void set_sequence(const std::vector<gr_complex>& sequence) override; + + float threshold() const override; + void set_threshold(float threshold) override; + + unsigned int mark_delay() const override; + void set_mark_delay(unsigned int mark_delay) override; + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +} // namespace cdc +} // namespace gr + +#endif /* INCLUDED_CDC_PREAMBLE_DETECT_CC_IMPL_H */ diff --git a/lib/tag_tx_burst_cc_impl.cc b/lib/tag_tx_burst_cc_impl.cc new file mode 100644 index 0000000000000000000000000000000000000000..d1f36abf32e2b06d691389ffc4d7359a89be3f84 --- /dev/null +++ b/lib/tag_tx_burst_cc_impl.cc @@ -0,0 +1,88 @@ +/* -*- c++ -*- */ +/* + * Copyright 2023 University of Melbourne. + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "tag_tx_burst_cc_impl.h" +#include <gnuradio/io_signature.h> + +namespace gr { +namespace cdc { + +tag_tx_burst_cc::sptr tag_tx_burst_cc::make(const std::string &lengthtagname, + int scalar) +{ + return gnuradio::make_block_sptr<tag_tx_burst_cc_impl>( + lengthtagname, scalar); +} + +tag_tx_burst_cc_impl::tag_tx_burst_cc_impl(const std::string &lengthtagname, + int scalar) + : gr::sync_block( + "tag_tx_burst_cc", + gr::io_signature::make(1, 1, sizeof(gr_complex)), + gr::io_signature::make(1, 1, sizeof(gr_complex))), + d_lengthtag(pmt::mp(lengthtagname)), + d_scalar(scalar), + d_eob_offset(0) +{ + set_tag_propagation_policy(TPP_DONT); +} + +tag_tx_burst_cc_impl::~tag_tx_burst_cc_impl() {} + +int tag_tx_burst_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + auto in = static_cast<const gr_complex *>(input_items[0]); + auto out = static_cast<gr_complex *>(output_items[0]); + + // copy input samples to output port + memcpy(out, in, noutput_items*sizeof(gr_complex)); + + // update length tag and add SOB and EOB tags + uint64_t offset = nitems_read(0); + uint64_t nend = nitems_read(0) + noutput_items; + while (offset < nend) { + if (d_eob_offset > 0) { + if (d_eob_offset < nend) { + offset = d_eob_offset; + d_eob_offset = 0; + + add_item_tag(0, + offset, + pmt::mp("tx_eob"), + pmt::PMT_NIL); + } else { + offset = nend; + } + } else { + // get tags in remaining window + std::vector<tag_t> tags; + get_tags_in_range(tags, 0, offset, nend, d_lengthtag); + + if (!tags.empty()) { + long value = d_scalar * pmt::to_long(tags[0].value); + add_item_tag(0, + tags[0].offset, + d_lengthtag, + pmt::from_long(value), + tags[0].srcid); + add_item_tag(0, + tags[0].offset, + pmt::mp("tx_sob"), + pmt::PMT_NIL); + d_eob_offset = tags[0].offset + value - 1; + } else { + offset = nend; + } + } + } + + return noutput_items; +} + +} /* namespace cdc */ +} /* namespace gr */ diff --git a/lib/tag_tx_burst_cc_impl.h b/lib/tag_tx_burst_cc_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..f732351e8f78a54227febffb6675bf49c25e8b9b --- /dev/null +++ b/lib/tag_tx_burst_cc_impl.h @@ -0,0 +1,35 @@ +/* -*- c++ -*- */ +/* + * Copyright 2023 University of Melbourne. + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#ifndef INCLUDED_CDC_TAG_TX_BURST_CC_IMPL_H +#define INCLUDED_CDC_TAG_TX_BURST_CC_IMPL_H + +#include <gnuradio/cdc/tag_tx_burst_cc.h> + +namespace gr { +namespace cdc { + +class tag_tx_burst_cc_impl : public tag_tx_burst_cc { +private: + const pmt::pmt_t d_lengthtag; + int d_scalar; + uint64_t d_eob_offset; + +public: + tag_tx_burst_cc_impl(const std::string& lengthtagname, + int scalar); + ~tag_tx_burst_cc_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) override; +}; + +} // namespace cdc +} // namespace gr + +#endif /* INCLUDED_CDC_TAG_TX_BURST_CC_IMPL_H */ diff --git a/python/cdc/CMakeLists.txt b/python/cdc/CMakeLists.txt index b7f3145e17e21d04627ac2200752fde58dcede40..858f625febe43e72d51576319034926b81a96f17 100644 --- a/python/cdc/CMakeLists.txt +++ b/python/cdc/CMakeLists.txt @@ -22,7 +22,8 @@ add_subdirectory(bindings) GR_PYTHON_INSTALL( FILES __init__.py - DESTINATION ${GR_PYTHON_DIR}/gnuradio/cdc + phy_tx.py + phy_rx.py DESTINATION ${GR_PYTHON_DIR}/gnuradio/cdc ) ######################################################################## diff --git a/python/cdc/__init__.py b/python/cdc/__init__.py index 8271f599c3eb6962efb61429f50b6ec2d303a42b..e08c076c382109aba61b8d1778862ae8fddf1397 100644 --- a/python/cdc/__init__.py +++ b/python/cdc/__init__.py @@ -20,4 +20,7 @@ except ModuleNotFoundError: pass # import any pure python here +from .phy_tx import phy_tx +from .phy_rx import phy_rx + # diff --git a/python/cdc/bindings/CMakeLists.txt b/python/cdc/bindings/CMakeLists.txt index 607a20f93ea348f644015e0dacb7dad7ae5ad34a..e223334924bf41f77e13caff1689de334c9f6e38 100644 --- a/python/cdc/bindings/CMakeLists.txt +++ b/python/cdc/bindings/CMakeLists.txt @@ -29,7 +29,8 @@ include(GrPybind) ######################################################################## list(APPEND cdc_python_files - python_bindings.cc) + tag_tx_burst_cc_python.cc + preamble_detect_cc_python.cc python_bindings.cc) GR_PYBIND_MAKE_OOT(cdc ../../.. diff --git a/python/cdc/bindings/docstrings/preamble_detect_cc_pydoc_template.h b/python/cdc/bindings/docstrings/preamble_detect_cc_pydoc_template.h new file mode 100644 index 0000000000000000000000000000000000000000..3043d288b645334e239dce566ede68c6a7bad199 --- /dev/null +++ b/python/cdc/bindings/docstrings/preamble_detect_cc_pydoc_template.h @@ -0,0 +1,48 @@ +/* + * Copyright 2023 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,cdc, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_cdc_preamble_detect_cc = R"doc()doc"; + + + static const char *__doc_gr_cdc_preamble_detect_cc_preamble_detect_cc_0 = R"doc()doc"; + + + static const char *__doc_gr_cdc_preamble_detect_cc_preamble_detect_cc_1 = R"doc()doc"; + + + static const char *__doc_gr_cdc_preamble_detect_cc_make = R"doc()doc"; + + + static const char *__doc_gr_cdc_preamble_detect_cc_sequence = R"doc()doc"; + + + static const char *__doc_gr_cdc_preamble_detect_cc_set_sequence = R"doc()doc"; + + + static const char *__doc_gr_cdc_preamble_detect_cc_threshold = R"doc()doc"; + + + static const char *__doc_gr_cdc_preamble_detect_cc_set_threshold = R"doc()doc"; + + + static const char *__doc_gr_cdc_preamble_detect_cc_mark_delay = R"doc()doc"; + + + static const char *__doc_gr_cdc_preamble_detect_cc_set_mark_delay = R"doc()doc"; + + diff --git a/python/cdc/bindings/docstrings/tag_tx_burst_cc_pydoc_template.h b/python/cdc/bindings/docstrings/tag_tx_burst_cc_pydoc_template.h new file mode 100644 index 0000000000000000000000000000000000000000..3da5e6f317dac9b85af6bf9fce052b7fc28ffe3b --- /dev/null +++ b/python/cdc/bindings/docstrings/tag_tx_burst_cc_pydoc_template.h @@ -0,0 +1,27 @@ +/* + * Copyright 2023 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,cdc, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_cdc_tag_tx_burst_cc = R"doc()doc"; + + + static const char *__doc_gr_cdc_tag_tx_burst_cc_tag_tx_burst_cc = R"doc()doc"; + + + static const char *__doc_gr_cdc_tag_tx_burst_cc_make = R"doc()doc"; + + diff --git a/python/cdc/bindings/preamble_detect_cc_python.cc b/python/cdc/bindings/preamble_detect_cc_python.cc new file mode 100644 index 0000000000000000000000000000000000000000..d468c2cec8d00d56dde29a2b18d495a90082e614 --- /dev/null +++ b/python/cdc/bindings/preamble_detect_cc_python.cc @@ -0,0 +1,101 @@ +/* + * Copyright 2023 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/***********************************************************************************/ +/* This file is automatically generated using bindtool and can be manually edited */ +/* The following lines can be configured to regenerate this file during cmake */ +/* If manual edits are made, the following tags should be modified accordingly. */ +/* BINDTOOL_GEN_AUTOMATIC(0) */ +/* BINDTOOL_USE_PYGCCXML(0) */ +/* BINDTOOL_HEADER_FILE(preamble_detect_cc.h) */ +/* BINDTOOL_HEADER_FILE_HASH(a9266ae8920e7062dd71159aa9a81dbd) */ +/***********************************************************************************/ + +#include <pybind11/complex.h> +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> + +namespace py = pybind11; + +#include <gnuradio/cdc/preamble_detect_cc.h> +// pydoc.h is automatically generated in the build directory +#include <preamble_detect_cc_pydoc.h> + +void bind_preamble_detect_cc(py::module& m) +{ + + using preamble_detect_cc = ::gr::cdc::preamble_detect_cc; + + + py::class_<preamble_detect_cc, gr::sync_block, gr::block, gr::basic_block, + std::shared_ptr<preamble_detect_cc>>(m, "preamble_detect_cc", D(preamble_detect_cc)) + + .def(py::init(&preamble_detect_cc::make), + py::arg("sequence"), + py::arg("threshold") = 0.5, + py::arg("mark_delay") = 0, + D(preamble_detect_cc,make) + ) + + + + + + + .def("sequence",&preamble_detect_cc::sequence, + D(preamble_detect_cc,sequence) + ) + + + + .def("set_sequence",&preamble_detect_cc::set_sequence, + py::arg("sequence"), + D(preamble_detect_cc,set_sequence) + ) + + + + .def("threshold",&preamble_detect_cc::threshold, + D(preamble_detect_cc,threshold) + ) + + + + .def("set_threshold",&preamble_detect_cc::set_threshold, + py::arg("threshold"), + D(preamble_detect_cc,set_threshold) + ) + + + + .def("mark_delay",&preamble_detect_cc::mark_delay, + D(preamble_detect_cc,mark_delay) + ) + + + + .def("set_mark_delay",&preamble_detect_cc::set_mark_delay, + py::arg("mark_delay"), + D(preamble_detect_cc,set_mark_delay) + ) + + ; + + + + +} + + + + + + + + diff --git a/python/cdc/bindings/python_bindings.cc b/python/cdc/bindings/python_bindings.cc index 3e8d87ca128146499ffa16fa9eedd83766ee7579..914900bfbe15652e06bbcb6ee32c960f36b652c6 100644 --- a/python/cdc/bindings/python_bindings.cc +++ b/python/cdc/bindings/python_bindings.cc @@ -21,6 +21,8 @@ namespace py = pybind11; // Please do not delete /**************************************/ // BINDING_FUNCTION_PROTOTYPES( + void bind_tag_tx_burst_cc(py::module& m); + void bind_preamble_detect_cc(py::module& m); // ) END BINDING_FUNCTION_PROTOTYPES @@ -49,5 +51,7 @@ PYBIND11_MODULE(cdc_python, m) // Please do not delete /**************************************/ // BINDING_FUNCTION_CALLS( + bind_tag_tx_burst_cc(m); + bind_preamble_detect_cc(m); // ) END BINDING_FUNCTION_CALLS -} +} \ No newline at end of file diff --git a/python/cdc/bindings/tag_tx_burst_cc_python.cc b/python/cdc/bindings/tag_tx_burst_cc_python.cc new file mode 100644 index 0000000000000000000000000000000000000000..cef6787f14026ab93cb336ad14b36a3dfddc778c --- /dev/null +++ b/python/cdc/bindings/tag_tx_burst_cc_python.cc @@ -0,0 +1,61 @@ +/* + * Copyright 2023 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/***********************************************************************************/ +/* This file is automatically generated using bindtool and can be manually edited */ +/* The following lines can be configured to regenerate this file during cmake */ +/* If manual edits are made, the following tags should be modified accordingly. */ +/* BINDTOOL_GEN_AUTOMATIC(0) */ +/* BINDTOOL_USE_PYGCCXML(0) */ +/* BINDTOOL_HEADER_FILE(tag_tx_burst_cc.h) */ +/* BINDTOOL_HEADER_FILE_HASH(82ed4da9bc2a218e814737e1f7643ca7) */ +/***********************************************************************************/ + +#include <pybind11/complex.h> +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> + +namespace py = pybind11; + +#include <gnuradio/cdc/tag_tx_burst_cc.h> +// pydoc.h is automatically generated in the build directory +#include <tag_tx_burst_cc_pydoc.h> + +void bind_tag_tx_burst_cc(py::module& m) +{ + + using tag_tx_burst_cc = ::gr::cdc::tag_tx_burst_cc; + + + py::class_<tag_tx_burst_cc, gr::sync_block, gr::block, gr::basic_block, + std::shared_ptr<tag_tx_burst_cc>>(m, "tag_tx_burst_cc", D(tag_tx_burst_cc)) + + .def(py::init(&tag_tx_burst_cc::make), + py::arg("lengthtagname"), + py::arg("scalar"), + D(tag_tx_burst_cc,make) + ) + + + + + ; + + + + +} + + + + + + + + diff --git a/python/cdc/phy_rx.py b/python/cdc/phy_rx.py new file mode 100644 index 0000000000000000000000000000000000000000..7d08049e426b4d01fc6baf058e7734b0b39d93c6 --- /dev/null +++ b/python/cdc/phy_rx.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- + +# +# SPDX-License-Identifier: GPL-3.0 +# +# GNU Radio Python Flow Graph +# Title: CDC PHY Rx +# Copyright: University of Melbourne +# GNU Radio version: 3.10.1.1 + +from gnuradio import blocks +from gnuradio import cdc +from gnuradio import digital +from gnuradio import filter +from gnuradio import gr +from gnuradio.filter import firdes +from gnuradio.fft import window +import sys +import signal +from gnuradio import gr, pdu +import numpy as np + + + + + + + +class phy_rx(gr.hier_block2): + def __init__(self, excess_bw=0.350, sps=2): + gr.hier_block2.__init__( + self, "CDC PHY Rx", + gr.io_signature(1, 1, gr.sizeof_gr_complex*1), + gr.io_signature.makev(5, 5, [gr.sizeof_gr_complex*1, gr.sizeof_gr_complex*1, gr.sizeof_char*1, gr.sizeof_float*1, gr.sizeof_gr_complex*1]), + ) + self.message_port_register_hier_out("pdu") + + ################################################## + # Parameters + ################################################## + self.excess_bw = excess_bw + self.sps = sps + + ################################################## + # Variables + ################################################## + self.nfilts = nfilts = 32 + self.rrc_taps = rrc_taps = firdes.root_raised_cosine(nfilts, sps*nfilts,1.0, excess_bw, 11*sps*nfilts) + self.modulated_sync_word = modulated_sync_word = np.array([ 6.3415498e-01+0.j, -8.2522854e-02+0.j, -6.7432624e-01+0.j, 2.1960361e-02+0.j, 6.6994393e-01+0.j, 2.7926212e-02+0.j, -6.2773204e-01+0.j, -1.6468078e-01+0.j, 5.7718420e-01+0.j, 7.2756535e-01+0.j, 4.6373290e-01+0.j, 2.3871353e-02+0.j, -4.8910391e-01+0.j, -7.3612314e-01+0.j, -4.8162562e-01+0.j, 1.2282493e-02+0.j, 4.6576929e-01+0.j, 7.3573601e-01+0.j, 5.4807413e-01+0.j, -1.3198391e-01+0.j, -5.6807721e-01+0.j, -1.1599341e-01+0.j, 6.0297143e-01+0.j, 6.1259979e-01+0.j, 3.7387580e-01+0.j, 6.1534089e-01+0.j, 6.1044985e-01+0.j, -1.3032347e-01+0.j, -5.7351917e-01+0.j, -1.1359498e-01+0.j, 5.1318854e-01+0.j, 7.6605660e-01+0.j, 5.5351597e-01+0.j, -1.7184576e-01+0.j, -6.0304552e-01+0.j, -5.2386895e-09+0.j, 6.0304564e-01+0.j, 1.7458701e-01+0.j, -5.4603779e-01+0.j, -7.7764541e-01+0.j, -5.1115209e-01+0.j, 1.2587748e-01+0.j, 5.5562639e-01+0.j, 1.4426640e-01+0.j, -5.5147964e-01+0.j, -7.4326605e-01+0.j, -4.9114031e-01+0.j, 2.7579335e-02+0.j, 5.3652304e-01+0.j, 5.9185678e-01+0.j, 4.3005973e-01+0.j, 5.5639654e-01+0.j, 5.7140875e-01+0.j, 1.4330061e-02+0.j, -5.7344508e-01+0.j, -5.8026785e-01+0.j, -4.0265229e-01+0.j, -6.0784715e-01+0.j, -6.1882788e-01+0.j, 1.3541880e-01+0.j, 6.3996756e-01+0.j, -1.1588858e-02+0.j, -6.3045293e-01+0.j, -1.2313626e-01+0.j, 5.9345692e-01+0.j, 6.3337904e-01+0.j, 4.5958614e-01+0.j, 4.4280154e-01+0.j, 4.8155165e-01+0.j, 6.0579962e-01+0.j, 5.2610868e-01+0.j, 2.5531810e-02+0.j, -4.9454585e-01+0.j, -7.3372471e-01+0.j, -5.7140863e-01+0.j, 1.6025695e-01+0.j, 6.3045293e-01+0.j, -2.2790564e-02+0.j, -6.5453744e-01+0.j, -4.3920707e-02+0.j, 6.6330218e-01+0.j, 1.3472509e-01+0.j, -6.3582081e-01+0.j, -5.8741081e-01+0.j, -4.1216698e-01+0.j, -5.9255040e-01+0.j, -5.4807413e-01+0.j, -1.3942933e-02+0.j, 5.0699669e-01+0.j, 7.0545167e-01+0.j, 5.1991683e-01+0.j, -3.5073120e-02+0.j, -5.2814502e-01+0.j, -5.9695208e-01+0.j, -4.9650821e-01+0.j, -4.3669510e-01+0.j, -4.6910083e-01+0.j, -6.3407266e-01+0.j, -5.7760048e-01+0.j, 9.9652052e-02+0.j, 5.9685379e-01+0.j, 1.1398210e-01+0.j, -5.7963693e-01+0.j, -6.4087272e-01+0.j, -4.3625149e-01+0.j, -4.7107458e-01+0.j, -5.4392737e-01+0.j, -4.6153325e-01+0.j, -4.5958611e-01+0.j, -6.1738855e-01+0.j, -5.3855950e-01+0.j, 2.7412227e-03+0.j, 5.4603767e-01+0.j, 6.0305846e-01+0.j, 4.5414424e-01+0.j, 4.7992218e-01+0.j, 5.0904173e-01+0.j, 4.9728334e-01+0.j, 5.1278079e-01+0.j, 4.7549835e-01+0.j, 4.5890158e-01+0.j, 6.0340530e-01+0.j, 5.3810960e-01+0.j, 1.3112724e-02+0.j, -5.2549899e-01+0.j, -6.6004950e-01+0.j, -4.8329139e-01+0.j, -2.2242454e-01+0.j], dtype=np.complex64) + self.constel = constel = digital.constellation_bpsk().base() + + ################################################## + # Blocks + ################################################## + self.pdu_tagged_stream_to_pdu_0 = pdu.tagged_stream_to_pdu(gr.types.byte_t, 'packet_len') + self.digital_symbol_sync_xx_0 = digital.symbol_sync_cc( + digital.TED_EARLY_LATE, + sps, + 0.045/2, + 1.0, + 1.0, + 1.5, + 1, + digital.constellation_bpsk().base(), + digital.IR_PFB_MF, + nfilts, + rrc_taps) + self.digital_crc32_async_bb_0 = digital.crc32_async_bb(True) + self.digital_costas_loop_cc_0 = digital.costas_loop_cc(0.035, constel.arity(), False) + self.digital_correlate_access_code_xx_ts_0 = digital.correlate_access_code_bb_ts(digital.packet_utils.default_access_code, + 3, 'packet_len') + self.digital_constellation_decoder_cb_0 = digital.constellation_decoder_cb(constel) + self.digital_additive_scrambler_bb_0 = digital.additive_scrambler_bb(0x8A, 0x7F, 7, count=0, bits_per_byte=8, reset_tag_key="packet_len") + self.cdc_preamble_detect_cc_0 = cdc.preamble_detect_cc(modulated_sync_word, 0.5, 0) + self.blocks_repack_bits_bb_0 = blocks.repack_bits_bb(constel.bits_per_symbol(), 8, "packet_len", True, gr.GR_MSB_FIRST) + self.blocks_multiply_by_tag_value_cc_0 = blocks.multiply_by_tag_value_cc('amp_est', 1) + + + ################################################## + # Connections + ################################################## + self.msg_connect((self.digital_crc32_async_bb_0, 'out'), (self, 'pdu')) + self.msg_connect((self.pdu_tagged_stream_to_pdu_0, 'pdus'), (self.digital_crc32_async_bb_0, 'in')) + self.connect((self.blocks_multiply_by_tag_value_cc_0, 0), (self.digital_symbol_sync_xx_0, 0)) + self.connect((self.blocks_multiply_by_tag_value_cc_0, 0), (self, 4)) + self.connect((self.blocks_repack_bits_bb_0, 0), (self.digital_additive_scrambler_bb_0, 0)) + self.connect((self.cdc_preamble_detect_cc_0, 0), (self.blocks_multiply_by_tag_value_cc_0, 0)) + self.connect((self.cdc_preamble_detect_cc_0, 1), (self, 3)) + self.connect((self.digital_additive_scrambler_bb_0, 0), (self, 2)) + self.connect((self.digital_additive_scrambler_bb_0, 0), (self.pdu_tagged_stream_to_pdu_0, 0)) + self.connect((self.digital_constellation_decoder_cb_0, 0), (self.digital_correlate_access_code_xx_ts_0, 0)) + self.connect((self.digital_correlate_access_code_xx_ts_0, 0), (self.blocks_repack_bits_bb_0, 0)) + self.connect((self.digital_costas_loop_cc_0, 0), (self.digital_constellation_decoder_cb_0, 0)) + self.connect((self.digital_costas_loop_cc_0, 0), (self, 1)) + self.connect((self.digital_symbol_sync_xx_0, 0), (self.digital_costas_loop_cc_0, 0)) + self.connect((self.digital_symbol_sync_xx_0, 0), (self, 0)) + self.connect((self, 0), (self.cdc_preamble_detect_cc_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, self.sps*self.nfilts, 1.0, self.excess_bw, 11*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, self.sps*self.nfilts, 1.0, self.excess_bw, 11*self.sps*self.nfilts)) + + 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, self.sps*self.nfilts, 1.0, self.excess_bw, 11*self.sps*self.nfilts)) + + def get_rrc_taps(self): + return self.rrc_taps + + def set_rrc_taps(self, rrc_taps): + self.rrc_taps = rrc_taps + + def get_modulated_sync_word(self): + return self.modulated_sync_word + + def set_modulated_sync_word(self, modulated_sync_word): + self.modulated_sync_word = modulated_sync_word + + def get_constel(self): + return self.constel + + def set_constel(self, constel): + self.constel = constel + diff --git a/python/cdc/phy_tx.py b/python/cdc/phy_tx.py new file mode 100644 index 0000000000000000000000000000000000000000..dbcbb99fc82cfc9158aa65267c855406482aea36 --- /dev/null +++ b/python/cdc/phy_tx.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- + +# +# SPDX-License-Identifier: GPL-3.0 +# +# GNU Radio Python Flow Graph +# Title: CDC PHY Tx +# Copyright: University of Melbourne +# GNU Radio version: 3.10.1.1 + +from gnuradio import blocks +from gnuradio import cdc +from gnuradio import digital +from gnuradio import filter +from gnuradio.filter import firdes +from gnuradio import gr +from gnuradio.fft import window +import sys +import signal +from gnuradio import gr, pdu + + + + + + + +class phy_tx(gr.hier_block2): + def __init__(self, excess_bw=0.350, phasing=20, sps=2): + gr.hier_block2.__init__( + self, "CDC 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("sdu") + + ################################################## + # Parameters + ################################################## + self.excess_bw = excess_bw + self.phasing = phasing + self.sps = sps + + ################################################## + # Variables + ################################################## + self.constel = constel = digital.constellation_bpsk().base() + self.access_code = access_code = digital.packet_utils.default_access_code + self.num_taps = num_taps = 11*sps + self.header_format = header_format = digital.header_format_default(access_code, 0, constel.bits_per_symbol()) + + ################################################## + # Blocks + ################################################## + self.root_raised_cosine_filter_0 = filter.interp_fir_filter_ccf( + sps, + firdes.root_raised_cosine( + 1.0, + sps, + 1.0, + excess_bw, + num_taps)) + self.pdu_pdu_to_tagged_stream_0 = pdu.pdu_to_tagged_stream(gr.types.byte_t, 'packet_len') + self.digital_protocol_formatter_bb_0 = digital.protocol_formatter_bb(header_format, "packet_len") + self.digital_crc32_async_bb_0 = digital.crc32_async_bb(False) + self.digital_chunks_to_symbols_xx_0 = digital.chunks_to_symbols_bc(constel.points(), 1) + self.digital_burst_shaper_xx_0 = digital.burst_shaper_cc(firdes.window(window.WIN_HANN, phasing, 0), 0, num_taps//2, True, "packet_len") + self.digital_additive_scrambler_bb_0 = digital.additive_scrambler_bb(0x8A, 0x7F, 7, count=0, bits_per_byte=8, reset_tag_key="packet_len") + self.cdc_tag_tx_burst_cc_0 = cdc.tag_tx_burst_cc('packet_len', sps) + self.blocks_tagged_stream_mux_0 = blocks.tagged_stream_mux(gr.sizeof_char*1, 'packet_len', 0) + self.blocks_repack_bits_bb_0 = blocks.repack_bits_bb(8, constel.bits_per_symbol(), "packet_len", False, gr.GR_MSB_FIRST) + + + ################################################## + # Connections + ################################################## + self.msg_connect((self.digital_crc32_async_bb_0, 'out'), (self.pdu_pdu_to_tagged_stream_0, 'pdus')) + self.msg_connect((self, 'sdu'), (self.digital_crc32_async_bb_0, 'in')) + self.connect((self.blocks_repack_bits_bb_0, 0), (self.digital_chunks_to_symbols_xx_0, 0)) + self.connect((self.blocks_tagged_stream_mux_0, 0), (self.blocks_repack_bits_bb_0, 0)) + self.connect((self.cdc_tag_tx_burst_cc_0, 0), (self, 0)) + self.connect((self.digital_additive_scrambler_bb_0, 0), (self.blocks_tagged_stream_mux_0, 1)) + self.connect((self.digital_additive_scrambler_bb_0, 0), (self.digital_protocol_formatter_bb_0, 0)) + self.connect((self.digital_burst_shaper_xx_0, 0), (self, 1)) + self.connect((self.digital_burst_shaper_xx_0, 0), (self.root_raised_cosine_filter_0, 0)) + self.connect((self.digital_chunks_to_symbols_xx_0, 0), (self.digital_burst_shaper_xx_0, 0)) + self.connect((self.digital_chunks_to_symbols_xx_0, 0), (self, 2)) + self.connect((self.digital_protocol_formatter_bb_0, 0), (self.blocks_tagged_stream_mux_0, 0)) + self.connect((self.pdu_pdu_to_tagged_stream_0, 0), (self.digital_additive_scrambler_bb_0, 0)) + self.connect((self.root_raised_cosine_filter_0, 0), (self.cdc_tag_tx_burst_cc_0, 0)) + + + def get_excess_bw(self): + return self.excess_bw + + def set_excess_bw(self, excess_bw): + self.excess_bw = excess_bw + self.root_raised_cosine_filter_0.set_taps(firdes.root_raised_cosine(1.0, self.sps, 1.0, self.excess_bw, self.num_taps)) + + def get_phasing(self): + return self.phasing + + def set_phasing(self, phasing): + self.phasing = phasing + + def get_sps(self): + return self.sps + + def set_sps(self, sps): + self.sps = sps + self.set_num_taps(11*self.sps) + self.root_raised_cosine_filter_0.set_taps(firdes.root_raised_cosine(1.0, self.sps, 1.0, self.excess_bw, self.num_taps)) + + def get_constel(self): + return self.constel + + def set_constel(self, constel): + self.constel = constel + + def get_access_code(self): + return self.access_code + + def set_access_code(self, access_code): + self.access_code = access_code + self.set_header_format(digital.header_format_default(self.access_code, 0, constel.bits_per_symbol())) + + def get_num_taps(self): + return self.num_taps + + def set_num_taps(self, num_taps): + self.num_taps = num_taps + self.root_raised_cosine_filter_0.set_taps(firdes.root_raised_cosine(1.0, self.sps, 1.0, self.excess_bw, self.num_taps)) + + def get_header_format(self): + return self.header_format + + def set_header_format(self, header_format): + self.header_format = header_format +