diff options
author | rpp <red@nostack.net> | 2015-10-01 10:44:34 +0200 |
---|---|---|
committer | rpp <red@nostack.net> | 2015-10-05 09:57:03 +0200 |
commit | a49a4d2b966878654c4239f27516efb59ffe1845 (patch) | |
tree | 0f0b936f5e1af8cefd9861a0544e7ea0f4a07d23 /python | |
parent | 06ecb02d5e26b79d6ce4c03eb7c09670df792fc8 (diff) |
Implemented multiband channelizer as gr-gsm block.
Diffstat (limited to 'python')
-rw-r--r-- | python/CMakeLists.txt | 4 | ||||
-rw-r--r-- | python/__init__.py | 1 | ||||
-rw-r--r-- | python/receiver/gsm_wideband_input.py | 115 |
3 files changed, 118 insertions, 2 deletions
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 78cc646..f68100a 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -32,9 +32,10 @@ GR_PYTHON_INSTALL( FILES __init__.py receiver/gsm_input.py + receiver/gsm_wideband_input.py receiver/fcch_burst_tagger.py receiver/sch_detector.py - receiver/fcch_detector.py + receiver/fcch_detector.py receiver/chirpz.py misc_utils/arfcn.py misc_utils/clock_offset_corrector.py DESTINATION ${GR_PYTHON_DIR}/grgsm @@ -57,4 +58,3 @@ GR_ADD_TEST(qa_burst_sdcch_subslot_filter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_S GR_ADD_TEST(qa_burst_fnr_filter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_fnr_filter.py) GR_ADD_TEST(qa_dummy_burst_filter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_dummy_burst_filter.py) GR_ADD_TEST(qa_arfcn ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_arfcn.py) - diff --git a/python/__init__.py b/python/__init__.py index 31c0bc5..0c50bdb 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -51,6 +51,7 @@ from sch_detector import sch_detector from fcch_detector import fcch_detector from clock_offset_corrector import clock_offset_corrector from gsm_input import gsm_input +from gsm_wideband_input import gsm_wideband_input import arfcn diff --git a/python/receiver/gsm_wideband_input.py b/python/receiver/gsm_wideband_input.py new file mode 100644 index 0000000..d1f704b --- /dev/null +++ b/python/receiver/gsm_wideband_input.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python +################################################## +# Gnuradio Python Flow Graph +# Title: GSM wideband input adaptor +# Author: Piotr Krysik +# Co-author: Pieter Robyns +# Description: Adaptor of input stream for the GSM receiver. Contains frequency ofset corrector doing also resampling to integer multiplies of GSM sample rate and LP filter filtering GSM channel. +################################################## + +from gnuradio import filter +from gnuradio import gr +from gnuradio import eng_notation +from gnuradio.filter import firdes +import grgsm.arfcn as arfcn +import grgsm + +class gsm_wideband_input(gr.hier_block2): + def __init__(self, ppm=0, osr=4, fc=925.2e6, samp_rate_in=20e6, ca=[]): + self.num_streams = len(ca) + gr.hier_block2.__init__( + self, "GSM wideband input adaptor", + gr.io_signature(1, 1, gr.sizeof_gr_complex*1), + gr.io_signature(self.num_streams, self.num_streams, gr.sizeof_gr_complex*1), + ) + + ################################################## + # Parameters + ################################################## + self.ppm = ppm + self.osr = osr + self.fc = fc + self.samp_rate_in = samp_rate_in + self.ca = ca + self.blocks_fir_filters = {} + self.blocks_resamplers = {} + self.blocks_ocs = {} + self.band = 'E-GSM' # TODO make selectable + band = 'E-GSM' + + ################################################## + # Variables + ################################################## + self.samp_rate_out = samp_rate_out = 1625000.0/6.0*osr + #self.samp_rate_out = samp_rate_out = 1000000 + + ################################################## + # Blocks + ################################################## + self.ppm_in = None + self.message_port_register_hier_out("ppm_in") + #self.lpf = firdes.low_pass(1, samp_rate_out, 125e3, 5e3, firdes.WIN_HAMMING, 6.76) + self.lpf = firdes.low_pass(1, samp_rate_in, 125e3, 75e3, firdes.WIN_HAMMING, 6.76) + self.gsm_clock_offset_corrector_0 = grgsm.clock_offset_corrector( + fc=fc, + ppm=ppm, + samp_rate_in=samp_rate_in, + ) + + c0_arfcn = arfcn.downlink2arfcn(fc, band) + print("Extracting channels %s, given that the center frequency is at ARFCN %d (%s)" % (str(ca), c0_arfcn, eng_notation.num_to_str(fc))) + + self.connect((self, 0), (self.gsm_clock_offset_corrector_0, 0)) + + + output_port = 0 + for channel in ca: + channel_freq = arfcn.arfcn2downlink(channel, band) + if channel_freq is None: + print("Warning: invalid ARFCN %d for band %s" % (channel, band)) + continue + freq_diff = channel_freq - fc + print("ARFCN %d is at C0 %+d KHz" % (channel, int(freq_diff / 1000.0))) + + #self.blocks_ocs[channel] = grgsm.clock_offset_corrector(fc=fc, ppm=ppm, samp_rate_in=samp_rate_in) + self.blocks_resamplers[channel] = filter.fractional_resampler_cc(0, samp_rate_in/samp_rate_out) + self.blocks_fir_filters[channel] = filter.freq_xlating_fir_filter_ccc(1, (self.lpf), freq_diff, samp_rate_in) + self.connect((self.gsm_clock_offset_corrector_0, 0), (self.blocks_fir_filters[channel], 0)) + self.connect((self.blocks_fir_filters[channel], 0), (self.blocks_resamplers[channel], 0)) + self.connect((self.blocks_resamplers[channel], 0), (self, output_port)) + output_port += 1 + + + """" + output_port = 0 + for channel in ca: + channel_freq = arfcn.arfcn2downlink(channel, band) + if channel_freq is None: + print("Warning: invalid ARFCN %d for band %s" % (channel, band)) + continue + freq_diff = channel_freq - fc + print("ARFCN %d is at C0 %+d KHz" % (channel, int(freq_diff / 1000.0))) + self.blocks_fir_filters[channel] = filter.freq_xlating_fir_filter_ccc(20, (firdes.low_pass(1, samp_rate_in, 300000, 100000)), freq_diff, samp_rate_in) + self.connect((self, 0), (self.blocks_fir_filters[channel], 0)) + self.connect((self.blocks_fir_filters[channel], 0), (self, output_port)) + output_port += 1 + """ + + ################################################## + # Asynch Message Connections + ################################################## + self.msg_connect(self, "ppm_in", self.gsm_clock_offset_corrector_0, "ppm_in") + + def get_ppm(self): + return self.ppm + + def set_ppm(self, ppm): + self.ppm = ppm + self.gsm_clock_offset_corrector_0.set_ppm(self.ppm) + + def get_fc(self): + return self.fc + + def set_fc(self, fc): + self.fc = fc + self.gsm_clock_offset_corrector_0.set_fc(self.fc) |