From ca43e1515f42c9ab6efa485d561f5f85048807a7 Mon Sep 17 00:00:00 2001 From: Glenn Bradford <glenn.bradford@unimelb.edu.au> Date: Fri, 1 Apr 2022 19:14:20 +1100 Subject: [PATCH] add cdc packet mac tx --- examples/cdc_packet_hw_loopback.grc | 88 ++++++++++++++---------- examples/cdc_packet_tx.grc | 98 +++++++++++++++------------ grc/CMakeLists.txt | 1 + grc/elen90089_packet_mac_tx.block.yml | 37 ++++++++++ python/CMakeLists.txt | 1 + python/__init__.py | 1 + python/packet_mac_tx.py | 90 ++++++++++++++++++++++++ 7 files changed, 237 insertions(+), 79 deletions(-) create mode 100644 grc/elen90089_packet_mac_tx.block.yml create mode 100644 python/packet_mac_tx.py diff --git a/examples/cdc_packet_hw_loopback.grc b/examples/cdc_packet_hw_loopback.grc index 4a76a62..44b6d6f 100644 --- a/examples/cdc_packet_hw_loopback.grc +++ b/examples/cdc_packet_hw_loopback.grc @@ -63,6 +63,30 @@ blocks: coordinate: [8, 108.0] rotation: 0 state: true +- name: default_freq + id: variable + parameters: + comment: '' + value: 920e6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [456, 12.0] + rotation: 0 + state: enabled +- name: default_tx_gain + id: variable + parameters: + comment: '' + value: '20' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [440, 76.0] + rotation: 0 + state: enabled - name: rf_freq id: variable_qtgui_range parameters: @@ -75,13 +99,13 @@ blocks: start: 70e6 step: 1e3 stop: 6e9 - value: 920e6 + value: default_freq widget: counter states: bus_sink: false bus_source: false bus_structure: null - coordinate: [456, 12.0] + coordinate: [560, 12.0] rotation: 0 state: true - name: rx_gain @@ -102,7 +126,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [704, 12.0] + coordinate: [808, 12.0] rotation: 0 state: true - name: samp_rate @@ -153,13 +177,13 @@ blocks: start: '-10' step: '1' stop: '50' - value: '20' + value: default_tx_gain widget: counter_slider states: bus_sink: false bus_source: false bus_structure: null - coordinate: [584, 12.0] + coordinate: [688, 12.0] rotation: 0 state: true - name: bladeRF_sink_0 @@ -176,8 +200,8 @@ blocks: device_id: '0' fpga_image: '' fpga_reload: 'False' - freq: rf_freq - gain0: tx_gain + freq: default_freq + gain0: default_tx_gain gain1: '10' if_gain0: '0' if_gain1: '20' @@ -208,7 +232,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [608, 244.0] + coordinate: [880, 148.0] rotation: 0 state: enabled - name: bladeRF_source_0 @@ -222,7 +246,7 @@ blocks: comment: '' dac: '10000' dc_calibration: LPF_TUNING - dc_offset_mode0: '0' + dc_offset_mode0: '2' dc_offset_mode1: '0' device_id: '0' fpga_image: '' @@ -235,7 +259,7 @@ blocks: if_gain0: '0' if_gain1: '20' in_clk: ONBOARD - iq_balance_mode0: '0' + iq_balance_mode0: '2' iq_balance_mode1: '0' lpf_mode: disabled maxoutbuf: '0' @@ -262,7 +286,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [888, 244.0] + coordinate: [304, 356.0] rotation: 0 state: enabled - name: blocks_message_strobe_0 @@ -279,7 +303,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [784, 164.0] + coordinate: [592, 172.0] rotation: 180 state: true - name: blocks_random_pdu_0 @@ -298,36 +322,26 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [488, 148.0] + coordinate: [280, 156.0] rotation: 180 state: true -- name: epy_block_0 - id: epy_block +- name: elen90089_packet_mac_tx_0 + id: elen90089_packet_mac_tx parameters: - _source_code: "import numpy as np\nfrom gnuradio import gr\nimport pmt\n\n\nclass\ - \ add_payload_bps(gr.sync_block):\n\n def __init__(self, bps=1):\n \ - \ gr.sync_block.__init__(\n self,\n name='Add Payload\ - \ BPS', # will show up in GRC\n in_sig=None,\n out_sig=None\n\ - \ )\n self.bps = bps\n self.message_port_register_in(pmt.intern('in'))\n\ - \ self.message_port_register_out(pmt.intern('out'))\n self.set_msg_handler(pmt.intern('in'),\ - \ self.msg_handler)\n\n def msg_handler(self, msg):\n info = pmt.make_dict()\n\ - \ info = pmt.dict_add(info, pmt.intern('bps'), pmt.from_long(self.bps))\n\ - \ pdu = pmt.cons(info, pmt.cdr(msg))\n self.message_port_pub(pmt.intern('out'),\ - \ pdu)\n" affinity: '' alias: '' bps: bps_payload comment: '' + freq: rf_freq + gain: tx_gain maxoutbuf: '0' minoutbuf: '0' states: - _io_cache: ('Add Payload BPS', 'add_payload_bps', [('bps', '1')], [('in', 'message', - 1)], [('out', 'message', 1)], '', ['bps']) bus_sink: false bus_source: false bus_structure: null - coordinate: [280, 172.0] - rotation: 180 + coordinate: [312, 260.0] + rotation: 0 state: true - name: packet_phy_tx_0 id: packet_phy_tx @@ -343,9 +357,9 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [280, 360.0] + coordinate: [584, 264.0] rotation: 0 - state: true + state: enabled - name: qtgui_time_sink_x_0 id: qtgui_time_sink_x parameters: @@ -440,9 +454,9 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [608, 484.0] + coordinate: [880, 388.0] rotation: 0 - state: true + state: enabled - name: qtgui_time_sink_x_0_0 id: qtgui_time_sink_x parameters: @@ -498,7 +512,7 @@ blocks: marker9: '-1' name: '"Received Waveform"' nconnections: '1' - size: '512' + size: '1024' srate: '1' stemplot: 'False' style1: '1' @@ -537,15 +551,15 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1120, 316.0] + coordinate: [544, 428.0] rotation: 0 state: enabled connections: - [bladeRF_source_0, '0', qtgui_time_sink_x_0_0, '0'] - [blocks_message_strobe_0, strobe, blocks_random_pdu_0, generate] -- [blocks_random_pdu_0, pdus, epy_block_0, in] -- [epy_block_0, out, packet_phy_tx_0, phy_sdu] +- [blocks_random_pdu_0, pdus, elen90089_packet_mac_tx_0, mac_sdu] +- [elen90089_packet_mac_tx_0, mac_pdu, packet_phy_tx_0, phy_sdu] - [packet_phy_tx_0, '0', bladeRF_sink_0, '0'] - [packet_phy_tx_0, '0', qtgui_time_sink_x_0, '0'] diff --git a/examples/cdc_packet_tx.grc b/examples/cdc_packet_tx.grc index 39fac7f..0e83b5e 100644 --- a/examples/cdc_packet_tx.grc +++ b/examples/cdc_packet_tx.grc @@ -63,27 +63,30 @@ blocks: coordinate: [8, 108.0] rotation: 0 state: true -- name: rf_freq - id: variable_qtgui_range +- name: default_tx_freq + id: variable parameters: comment: '' - gui_hint: 0, 0, 1, 1 - label: RF Frequency - min_len: '200' - orient: QtCore.Qt.Horizontal - rangeType: float - start: 70e6 - step: 1e3 - stop: 6e9 value: 920e6 - widget: counter_slider states: bus_sink: false bus_source: false bus_structure: null - coordinate: [456, 12.0] + coordinate: [448, 12.0] rotation: 0 - state: true + state: enabled +- name: default_tx_gain + id: variable + parameters: + comment: '' + value: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [448, 76.0] + rotation: 0 + state: enabled - name: samp_rate id: variable parameters: @@ -120,6 +123,27 @@ blocks: coordinate: [184, 12.0] rotation: 0 state: enabled +- name: tx_freq + id: variable_qtgui_range + parameters: + comment: '' + gui_hint: 0, 0, 1, 1 + label: Tx Frequency + min_len: '200' + orient: QtCore.Qt.Horizontal + rangeType: float + start: 70e6 + step: 1e3 + stop: 6e9 + value: default_tx_freq + widget: counter_slider + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [568, 12.0] + rotation: 0 + state: true - name: tx_gain id: variable_qtgui_range parameters: @@ -132,13 +156,13 @@ blocks: start: '-10' step: '1' stop: '50' - value: '0' + value: default_tx_gain widget: counter_slider states: bus_sink: false bus_source: false bus_structure: null - coordinate: [584, 12.0] + coordinate: [696, 12.0] rotation: 0 state: true - name: bladeRF_sink_0 @@ -155,8 +179,8 @@ blocks: device_id: '0' fpga_image: '' fpga_reload: 'False' - freq: rf_freq - gain0: tx_gain + freq: default_tx_freq + gain0: default_tx_gain gain1: '10' if_gain0: '0' if_gain1: '20' @@ -187,7 +211,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [712, 340.0] + coordinate: [912, 332.0] rotation: 0 state: disabled - name: blocks_message_strobe_0 @@ -204,7 +228,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [776, 164.0] + coordinate: [560, 164.0] rotation: 180 state: true - name: blocks_random_pdu_0 @@ -223,7 +247,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [480, 148.0] + coordinate: [256, 148.0] rotation: 180 state: true - name: blocks_throttle_0 @@ -242,36 +266,26 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [528, 268.0] + coordinate: [800, 260.0] rotation: 0 state: true -- name: epy_block_0 - id: epy_block +- name: elen90089_packet_mac_tx_0 + id: elen90089_packet_mac_tx parameters: - _source_code: "import numpy as np\nfrom gnuradio import gr\nimport pmt\n\n\nclass\ - \ add_payload_bps(gr.sync_block):\n\n def __init__(self, bps=1):\n \ - \ gr.sync_block.__init__(\n self,\n name='Add Payload\ - \ BPS', # will show up in GRC\n in_sig=None,\n out_sig=None\n\ - \ )\n self.bps = bps\n self.message_port_register_in(pmt.intern('in'))\n\ - \ self.message_port_register_out(pmt.intern('out'))\n self.set_msg_handler(pmt.intern('in'),\ - \ self.msg_handler)\n\n def msg_handler(self, msg):\n info = pmt.make_dict()\n\ - \ info = pmt.dict_add(info, pmt.intern('bps'), pmt.from_long(self.bps))\n\ - \ pdu = pmt.cons(info, pmt.cdr(msg))\n self.message_port_pub(pmt.intern('out'),\ - \ pdu)\n" affinity: '' alias: '' bps: bps_payload comment: '' + freq: tx_freq + gain: tx_gain maxoutbuf: '0' minoutbuf: '0' states: - _io_cache: ('Add Payload BPS', 'add_payload_bps', [('bps', '1')], [('in', 'message', - 1)], [('out', 'message', 1)], '', ['bps']) bus_sink: false bus_source: false bus_structure: null - coordinate: [280, 172.0] - rotation: 180 + coordinate: [288, 260.0] + rotation: 0 state: true - name: packet_phy_tx_0 id: packet_phy_tx @@ -287,7 +301,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [280, 272.0] + coordinate: [560, 264.0] rotation: 0 state: true - name: qtgui_const_sink_x_0 @@ -379,7 +393,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [240, 356.0] + coordinate: [520, 340.0] rotation: 180 state: enabled - name: qtgui_time_sink_x_0 @@ -476,15 +490,15 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [712, 244.0] + coordinate: [968, 236.0] rotation: 0 state: true connections: - [blocks_message_strobe_0, strobe, blocks_random_pdu_0, generate] -- [blocks_random_pdu_0, pdus, epy_block_0, in] +- [blocks_random_pdu_0, pdus, elen90089_packet_mac_tx_0, mac_sdu] - [blocks_throttle_0, '0', qtgui_time_sink_x_0, '0'] -- [epy_block_0, out, packet_phy_tx_0, phy_sdu] +- [elen90089_packet_mac_tx_0, mac_pdu, packet_phy_tx_0, phy_sdu] - [packet_phy_tx_0, '0', bladeRF_sink_0, '0'] - [packet_phy_tx_0, '0', blocks_throttle_0, '0'] - [packet_phy_tx_0, '1', qtgui_const_sink_x_0, '0'] diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index 690c145..12c160e 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -11,5 +11,6 @@ install(FILES elen90089_moe_symbol_sync_cc.block.yml elen90089_symbol_mapper_c.block.yml elen90089_header_format_cdc.block.yml + elen90089_packet_mac_tx.block.yml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/elen90089_packet_mac_tx.block.yml b/grc/elen90089_packet_mac_tx.block.yml new file mode 100644 index 0000000..5526a79 --- /dev/null +++ b/grc/elen90089_packet_mac_tx.block.yml @@ -0,0 +1,37 @@ +id: elen90089_packet_mac_tx +label: CDC Packet MAC Tx +category: '[elen90089]' + +templates: + imports: import elen90089 + make: elen90089.packet_mac_tx(${bps}, ${freq}, ${gain}) + callbacks: + - set_bps(${bps}) + - set_freq(${freq}) + - set_gain(${gain}) + +parameters: +- id: bps + label: Payload BPS + dtype: int + default: 1 +- id: freq + label: Tx Frequency + dtype: raw + default: None +- id: gain + label: Tx Gain + dtype: raw + default: None + +inputs: +- label: mac_sdu + domain: message + optional: True + +outputs: +- label: mac_pdu + domain: message + optional: True + +file_format: 1 diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index a984ec1..3b89790 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -22,6 +22,7 @@ add_subdirectory(bindings) GR_PYTHON_INSTALL( FILES __init__.py + packet_mac_tx.py DESTINATION ${GR_PYTHON_DIR}/elen90089 ) diff --git a/python/__init__.py b/python/__init__.py index 76186ec..d997af0 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -20,4 +20,5 @@ except ModuleNotFoundError: pass # import any pure python here +from .packet_mac_tx import packet_mac_tx # diff --git a/python/packet_mac_tx.py b/python/packet_mac_tx.py new file mode 100644 index 0000000..7f31aa0 --- /dev/null +++ b/python/packet_mac_tx.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2022 University of Melbourne. +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +import numpy as np +from gnuradio import gr +import pmt + + +class packet_mac_tx(gr.sync_block): + """CDC Packet MAC Transmitter.""" + def __init__(self, bps=1, freq=None, gain=None): + gr.sync_block.__init__( + self, + name="CDC Packet MAC Tx", + in_sig=None, + out_sig=None) + + # PHY configuration parameters + self.bps = bps + self.freq = freq + self.gain = gain + + # create message ports + self.message_port_register_in(pmt.intern('mac_sdu')) + self.message_port_register_out(pmt.intern('mac_pdu')) + self.set_msg_handler(pmt.intern('mac_sdu'), self.handle_sdu) + + def set_bps(self, bps): + self.bps = int(bps) + + def set_freq(self, freq): + self.freq = float(freq) + + def set_gain(self, gain): + self.gain = float(gain) + + def handle_sdu(self, sdu): + """Handle SDU received from layer 3.""" + + # add MAC header + data = pmt.to_python(pmt.cdr(sdu)) + header = self.create_header() + payload = np.concatenate([header, data]) + + # create phy configuration + phy_config = self.create_phy_config() + + # send PDU to PHY + pdu = pmt.cons(phy_config, pmt.to_pmt(payload)) + self.message_port_pub(pmt.intern('mac_pdu'), pdu) + + def create_header(self): + """Create MAC header.""" + header = np.array([], dtype=np.uint8) + return header + + def create_phy_config(self): + """Create PHY configuration dictionary.""" + # Tx commands to bladeRF + tx_cmd = pmt.make_dict() + has_cmd = False + if self.freq is not None: + tx_cmd = pmt.dict_add(tx_cmd, + pmt.intern('freq'), + pmt.from_double(self.freq)) + self.freq = None + has_cmd = True + if self.gain is not None: + tx_cmd = pmt.dict_add(tx_cmd, + pmt.intern('gain'), + pmt.from_double(self.gain)) + self.gain = None + has_cmd = True + + # create config + config = pmt.make_dict() + config = pmt.dict_add(config, + pmt.intern('bps'), + pmt.from_long(self.bps)) + if has_cmd: + config = pmt.dict_add(config, + pmt.intern('tx_command'), + tx_cmd) + + return config -- GitLab