python/trx: fork RadioInterfaceUHD from RadioInterface

Change-Id: I1644a3f6b8da0d5f2a1a133058269e5383948fda
This commit is contained in:
Vadim Yanitskiy 2019-01-19 11:55:01 +07:00 committed by Piotr Krysik
parent 8072d3acd8
commit 6ee957f904
5 changed files with 97 additions and 36 deletions

View File

@ -29,6 +29,7 @@ from argparse import ArgumentParser
from argparse import ArgumentTypeError from argparse import ArgumentTypeError
from gnuradio import eng_notation from gnuradio import eng_notation
from grgsm.trx import RadioInterfaceUHD
from grgsm.trx import RadioInterface from grgsm.trx import RadioInterface
from grgsm.trx import Transceiver from grgsm.trx import Transceiver
@ -58,7 +59,7 @@ class Application:
signal.signal(signal.SIGINT, self.sig_handler) signal.signal(signal.SIGINT, self.sig_handler)
# Init Radio interface # Init Radio interface
self.radio = RadioInterface(self.phy_args, self.phy_sample_rate, self.radio = RadioInterfaceUHD(self.phy_args, self.phy_sample_rate,
self.phy_rx_gain, self.phy_tx_gain, self.phy_ppm, self.phy_rx_gain, self.phy_tx_gain, self.phy_ppm,
self.phy_rx_antenna, self.phy_tx_antenna, self.phy_rx_antenna, self.phy_tx_antenna,
self.phy_freq_offset, self.bind_addr, self.phy_freq_offset, self.bind_addr,

View File

@ -24,6 +24,7 @@ GR_PYTHON_INSTALL(
ctrl_if.py ctrl_if.py
ctrl_if_bb.py ctrl_if_bb.py
radio_if.py radio_if.py
radio_if_uhd.py
radio_if_grc.py radio_if_grc.py
transceiver.py transceiver.py
dict_toggle_sign.py dict_toggle_sign.py

View File

@ -25,6 +25,7 @@ from ctrl_if import CTRLInterface
from ctrl_if_bb import CTRLInterfaceBB from ctrl_if_bb import CTRLInterfaceBB
from radio_if_grc import RadioInterfaceGRC from radio_if_grc import RadioInterfaceGRC
from radio_if import RadioInterface from radio_if import RadioInterface
from radio_if import RadioInterfaceUHD
from transceiver import Transceiver from transceiver import Transceiver
from dict_toggle_sign import dict_toggle_sign from dict_toggle_sign import dict_toggle_sign

View File

@ -2,7 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# GR-GSM based transceiver # GR-GSM based transceiver
# Follow graph implementation # Generic (device independent) flow-graph implementation
# #
# (C) 2016-2019 by Vadim Yanitskiy <axilirator@gmail.com> # (C) 2016-2019 by Vadim Yanitskiy <axilirator@gmail.com>
# (C) 2017 by Piotr Krysik <ptrkrysik@gmail.com> # (C) 2017 by Piotr Krysik <ptrkrysik@gmail.com>
@ -33,7 +33,6 @@ from math import pi
from gnuradio import eng_notation from gnuradio import eng_notation
from gnuradio import digital from gnuradio import digital
from gnuradio import blocks from gnuradio import blocks
from gnuradio import uhd
from gnuradio import gr from gnuradio import gr
from gnuradio import filter from gnuradio import filter
@ -57,11 +56,6 @@ class RadioInterface(gr.top_block):
GSM_SYM_RATE = (1.0 / GSM_SYM_PERIOD_uS) * 1e6 GSM_SYM_RATE = (1.0 / GSM_SYM_PERIOD_uS) * 1e6
SAMPLE_RATE = GSM_SYM_RATE * osr SAMPLE_RATE = GSM_SYM_RATE * osr
# FIXME: shall be measured (automatically?) for
# particular device and particular clock rate.
# The current value is measured for USRP B2X0 at 26e6.
delay_correction = (285.616 + 2 * GSM_SYM_PERIOD_uS) * 1e-6
# Dummy freq. value that is used during initialization # Dummy freq. value that is used during initialization
# basically, the DL freq. of ARFCN 0 # basically, the DL freq. of ARFCN 0
DUMMY_FREQ = 935e6 DUMMY_FREQ = 935e6
@ -83,6 +77,10 @@ class RadioInterface(gr.top_block):
self.ppm = phy_ppm self.ppm = phy_ppm
self.freq_offset = phy_freq_offset self.freq_offset = phy_freq_offset
self.phy_args = phy_args
self.rx_antenna = phy_rx_antenna
self.tx_antenna = phy_tx_antenna
gr.top_block.__init__(self, "GR-GSM TRX") gr.top_block.__init__(self, "GR-GSM TRX")
# TRX Burst Interface # TRX Burst Interface
@ -91,15 +89,7 @@ class RadioInterface(gr.top_block):
str(trx_base_port)) str(trx_base_port))
# RX path definition # RX path definition
self.phy_src = uhd.usrp_source(phy_args, self.phy_init_source()
uhd.stream_args(cpu_format="fc32",
channels=range(1)))
self.phy_src.set_clock_rate(26e6, uhd.ALL_MBOARDS)
self.phy_src.set_antenna(phy_rx_antenna, 0)
self.phy_src.set_samp_rate(phy_sample_rate)
self.phy_src.set_bandwidth(650e3, 0)
self.phy_src.set_gain(phy_rx_gain)
self.msg_to_tag_src = grgsm.msg_to_tag() self.msg_to_tag_src = grgsm.msg_to_tag()
@ -115,7 +105,7 @@ class RadioInterface(gr.top_block):
# Connections # Connections
self.connect( self.connect(
(self.phy_src, 0), (self._phy_src, 0),
(self.msg_to_tag_src, 0)) (self.msg_to_tag_src, 0))
self.connect( self.connect(
@ -140,18 +130,11 @@ class RadioInterface(gr.top_block):
# TX Path Definition # TX Path Definition
self.phy_sink = uhd.usrp_sink(phy_args, self.phy_init_sink()
uhd.stream_args(cpu_format="fc32",
channels=range(1)), "packet_len")
self.phy_sink.set_clock_rate(26e6, uhd.ALL_MBOARDS)
self.phy_sink.set_antenna(phy_tx_antenna, 0)
self.phy_sink.set_samp_rate(phy_sample_rate)
self.phy_sink.set_gain(self.tx_gain)
self.tx_time_setter = grgsm.txtime_setter( self.tx_time_setter = grgsm.txtime_setter(
0xffffffff, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0,
self.delay_correction + self.GSM_UL_DL_SHIFT_uS * 1e-6) self.phy_proc_delay + self.GSM_UL_DL_SHIFT_uS * 1e-6)
self.tx_burst_proc = grgsm.preprocess_tx_burst() self.tx_burst_proc = grgsm.preprocess_tx_burst()
@ -200,7 +183,7 @@ class RadioInterface(gr.top_block):
self.connect( self.connect(
(self.rotator_sink, 0), (self.rotator_sink, 0),
(self.phy_sink, 0)) (self._phy_sink, 0))
# RX & TX synchronization # RX & TX synchronization
@ -245,11 +228,11 @@ class RadioInterface(gr.top_block):
(self.dict_toggle_sign, 'dict_out'), (self.dict_toggle_sign, 'dict_out'),
(self.msg_to_tag_sink, 'msg')) (self.msg_to_tag_sink, 'msg'))
def phy_init_source(self):
raise NotImplementedError
# Some UHD devices (such as UmTRX) do start the clock def phy_init_sink(self):
# not from 0, so it's required to reset it manually. raise NotImplementedError
# Resetting UHD source will also affect the sink.
self.phy_src.set_time_now(uhd.time_spec(0.0))
def shutdown(self): def shutdown(self):
print("[i] Shutdown Radio interface") print("[i] Shutdown Radio interface")
@ -281,9 +264,10 @@ class RadioInterface(gr.top_block):
print("[#] Shifting RX freq. to %s (offset is %s)" print("[#] Shifting RX freq. to %s (offset is %s)"
% (eng_notation.num_to_str(fc), % (eng_notation.num_to_str(fc),
eng_notation.num_to_str(self.freq_offset))) eng_notation.num_to_str(self.freq_offset)))
self.phy_src.set_center_freq(fc, 0)
self.rotator_src.set_phase_inc(self.calc_phase_inc(fc)) self.rotator_src.set_phase_inc(self.calc_phase_inc(fc))
self.gsm_clck_ctrl.set_fc(fc) self.gsm_clck_ctrl.set_fc(fc)
self.phy_set_rx_freq(fc)
self.rx_freq = fc self.rx_freq = fc
def set_tx_freq(self, fc): def set_tx_freq(self, fc):
@ -292,16 +276,17 @@ class RadioInterface(gr.top_block):
print("[#] Shifting TX freq. to %s (offset is %s)" print("[#] Shifting TX freq. to %s (offset is %s)"
% (eng_notation.num_to_str(fc), % (eng_notation.num_to_str(fc),
eng_notation.num_to_str(self.freq_offset))) eng_notation.num_to_str(self.freq_offset)))
self.phy_sink.set_center_freq(fc, 0)
self.rotator_sink.set_phase_inc(-self.calc_phase_inc(fc)) self.rotator_sink.set_phase_inc(-self.calc_phase_inc(fc))
self.phy_set_tx_freq(fc)
self.tx_freq = fc self.tx_freq = fc
def set_rx_gain(self, gain): def set_rx_gain(self, gain):
self.phy_src.set_gain(gain, 0) self.phy_set_rx_gain(gain)
self.rx_gain = gain self.rx_gain = gain
def set_tx_gain(self, gain): def set_tx_gain(self, gain):
self.phy_sink.set_gain(gain, 0) self.phy_set_tx_gain(gain)
self.tx_gain = gain self.tx_gain = gain
def set_slot(self, slot, config): def set_slot(self, slot, config):

View File

@ -0,0 +1,73 @@
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# GR-GSM based transceiver
# Radio interface for UHD devices
#
# (C) 2019 by Vadim Yanitskiy <axilirator@gmail.com>
#
# All Rights Reserved
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
from gnuradio import uhd
from radio_if import RadioInterface
class RadioInterfaceUHD(RadioInterface):
@property
def phy_proc_delay(self):
# FIXME: shall be measured (automatically?) for
# particular device and particular clock rate.
# The current value is measured for USRP B2X0 at 26e6.
return (285.616 + 2 * self.GSM_SYM_PERIOD_uS) * 1e-6
def phy_init_source(self):
self._phy_src = uhd.usrp_source(self.phy_args,
uhd.stream_args(cpu_format = "fc32",
channels = range(1)))
self._phy_src.set_clock_rate(26e6, uhd.ALL_MBOARDS)
self._phy_src.set_antenna(self.rx_antenna, 0)
self._phy_src.set_samp_rate(self.sample_rate)
self._phy_src.set_bandwidth(650e3, 0)
self._phy_src.set_gain(self.rx_gain)
# Some UHD devices (such as UmTRX) do start the clock
# not from 0, so it's required to reset it manually.
# Resetting UHD source will also affect the sink.
self._phy_src.set_time_now(uhd.time_spec(0.0))
def phy_init_sink(self):
self._phy_sink = uhd.usrp_sink(self.phy_args,
uhd.stream_args(cpu_format = "fc32",
channels = range(1)), "packet_len")
self._phy_sink.set_clock_rate(26e6, uhd.ALL_MBOARDS)
self._phy_sink.set_antenna(self.tx_antenna, 0)
self._phy_sink.set_samp_rate(self.sample_rate)
self._phy_sink.set_gain(self.tx_gain)
def phy_set_rx_freq(self, freq):
self._phy_src.set_center_freq(freq, 0)
def phy_set_tx_freq(self, freq):
self._phy_sink.set_center_freq(freq, 0)
def phy_set_rx_gain(self, gain):
self._phy_src.set_gain(gain, 0)
def phy_set_tx_gain(self, gain):
self._phy_sink.set_gain(gain, 0)