From 0982673af1e91b91c4b983f0f423277e09089e7e Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Fri, 15 Jul 2016 13:14:24 +0200 Subject: New clock offset corrector and clock offset control --- grc/gsm_block_tree.xml | 1 + grc/misc_utils/CMakeLists.txt | 1 + .../gsm_clock_offset_corrector_tagged.xml | 50 ++ grc/receiver/gsm_clock_offset_control.xml | 11 +- .../misc_utils/gsm_clock_offset_corrector_new.grc | 494 +++++++++++++++++ .../gsm_clock_offset_corrector_tagged.grc | 606 +++++++++++++++++++++ include/grgsm/receiver/clock_offset_control.h | 5 +- lib/receiver/clock_offset_control_impl.cc | 106 ++-- lib/receiver/clock_offset_control_impl.h | 7 +- python/CMakeLists.txt | 4 +- python/__init__.py | 1 + python/misc_utils/clock_offset_corrector_tagged.py | 81 +++ 12 files changed, 1315 insertions(+), 52 deletions(-) create mode 100644 grc/misc_utils/gsm_clock_offset_corrector_tagged.xml create mode 100644 hier_blocks/misc_utils/gsm_clock_offset_corrector_new.grc create mode 100644 hier_blocks/misc_utils/gsm_clock_offset_corrector_tagged.grc create mode 100644 python/misc_utils/clock_offset_corrector_tagged.py diff --git a/grc/gsm_block_tree.xml b/grc/gsm_block_tree.xml index 1dd81b7..99628d6 100644 --- a/grc/gsm_block_tree.xml +++ b/grc/gsm_block_tree.xml @@ -62,6 +62,7 @@ gsm_controlled_fractional_resampler_cc gsm_message_printer gsm_clock_offset_corrector + gsm_clock_offset_corrector_tagged gsm_tmsi_dumper diff --git a/grc/misc_utils/CMakeLists.txt b/grc/misc_utils/CMakeLists.txt index d042beb..a64d2eb 100644 --- a/grc/misc_utils/CMakeLists.txt +++ b/grc/misc_utils/CMakeLists.txt @@ -25,6 +25,7 @@ install(FILES gsm_message_printer.xml gsm_bursts_printer.xml gsm_clock_offset_corrector.xml + gsm_clock_offset_corrector_tagged.xml gsm_tmsi_dumper.xml gsm_burst_file_sink.xml gsm_burst_file_source.xml diff --git a/grc/misc_utils/gsm_clock_offset_corrector_tagged.xml b/grc/misc_utils/gsm_clock_offset_corrector_tagged.xml new file mode 100644 index 0000000..4f91b4b --- /dev/null +++ b/grc/misc_utils/gsm_clock_offset_corrector_tagged.xml @@ -0,0 +1,50 @@ + + Clock Offset Corrector Tagged + gsm_clock_offset_corrector_tagged + from clock_offset_corrector_tagged import clock_offset_corrector_tagged # grc-generated hier_block + grgsm.clock_offset_corrector_tagged( + fc=$fc, + ppm=$ppm, + samp_rate_in=$samp_rate_in, +) + set_fc($fc) + set_ppm($ppm) + set_samp_rate_in($samp_rate_in) + + fc + fc + fc + float + + + ppm + ppm + ppm + float + + + samp_rate_in + samp_rate_in + samp_rate_in + float + + + ctrl + message + 1 + + + in + complex + 1 + + + out + complex + 1 + + Piotr Krysik +Clock offset corrector with blocks that use tags to switch offsets + + gr-gsm/hier_blocks/misc_utils/gsm_clock_offset_corrector_tagged.grc + diff --git a/grc/receiver/gsm_clock_offset_control.xml b/grc/receiver/gsm_clock_offset_control.xml index 2d55e4f..704d2f3 100644 --- a/grc/receiver/gsm_clock_offset_control.xml +++ b/grc/receiver/gsm_clock_offset_control.xml @@ -3,7 +3,7 @@ GSM Clock Offset Control gsm_clock_offset_control import grgsm - grgsm.clock_offset_control($fc) + grgsm.clock_offset_control($fc, $samp_rate) fc @@ -12,13 +12,20 @@ float + + samp_rate + samp_rate + samp_rate + float + + measurements message - ppm + ctrl message 1 diff --git a/hier_blocks/misc_utils/gsm_clock_offset_corrector_new.grc b/hier_blocks/misc_utils/gsm_clock_offset_corrector_new.grc new file mode 100644 index 0000000..390fce6 --- /dev/null +++ b/hier_blocks/misc_utils/gsm_clock_offset_corrector_new.grc @@ -0,0 +1,494 @@ + + + + Thu Nov 6 10:22:20 2014 + + options + + author + Piotr Krysik + + + window_size + 2280, 1024 + + + category + GSM + + + comment + + + + description + + + + _enabled + True + + + _coordinate + (10, 10) + + + _rotation + 0 + + + generate_options + hb + + + hier_block_src_path + .: + + + id + clock_offset_corrector_new + + + max_nouts + 0 + + + qt_qss_theme + + + + realtime_scheduling + + + + run_command + {python} -u {filename} + + + run_options + prompt + + + run + True + + + thread_safe_setters + + + + title + Clock offset corrector + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (736, 19) + + + _rotation + 0 + + + id + samp_rate_out + + + value + samp_rate_in + + + + pad_source + + comment + + + + _enabled + True + + + _coordinate + (32, 244) + + + _rotation + 0 + + + id + ctrl_in + + + label + ctrl_in + + + num_streams + 1 + + + optional + True + + + type + message + + + vlen + 1 + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (274, 19) + + + _rotation + 0 + + + id + fc + + + label + fc + + + short_id + + + + type + eng_float + + + value + 936.6e6 + + + + grgsm_msg_to_tag + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (192, 193) + + + _rotation + 0 + + + id + grgsm_msg_to_tag_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + + import + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (11, 125) + + + _rotation + 0 + + + id + math_imp + + + import + import math + + + + pad_sink + + comment + + + + _enabled + True + + + _coordinate + (1168, 204) + + + _rotation + 0 + + + id + pad_sink_1 + + + type + complex + + + label + out + + + num_streams + 1 + + + optional + False + + + vlen + 1 + + + + pad_source + + comment + + + + _enabled + True + + + _coordinate + (32, 188) + + + _rotation + 0 + + + id + pad_source_0 + + + label + in + + + num_streams + 1 + + + optional + False + + + type + complex + + + vlen + 1 + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (496, 19) + + + _rotation + 0 + + + id + ppm + + + label + ppm + + + short_id + + + + type + eng_float + + + value + 0 + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (368, 19) + + + _rotation + 0 + + + id + samp_rate_in + + + label + samp_rate_in + + + short_id + + + + type + eng_float + + + value + 1625000.0/6.0*4.0 + + + + parameter + + alias + + + + comment + + + + _enabled + False + + + _coordinate + (592, 20) + + + _rotation + 0 + + + id + samp_rate_out + + + label + samp_rate_out + + + short_id + + + + type + eng_float + + + value + 1625000.0/6.0*4.0 + + + + ctrl_in + grgsm_msg_to_tag_0 + out + msg + + + pad_source_0 + grgsm_msg_to_tag_0 + 0 + 0 + + diff --git a/hier_blocks/misc_utils/gsm_clock_offset_corrector_tagged.grc b/hier_blocks/misc_utils/gsm_clock_offset_corrector_tagged.grc new file mode 100644 index 0000000..61d8db7 --- /dev/null +++ b/hier_blocks/misc_utils/gsm_clock_offset_corrector_tagged.grc @@ -0,0 +1,606 @@ + + + + Thu Nov 6 10:22:20 2014 + + options + + author + Piotr Krysik + + + window_size + 2280, 1024 + + + category + GSM + + + comment + + + + description + Clock offset corrector with blocks that use tags to switch offsets + + + _enabled + True + + + _coordinate + (10, 10) + + + _rotation + 0 + + + generate_options + hb + + + hier_block_src_path + .: + + + id + clock_offset_corrector_tagged + + + max_nouts + 0 + + + qt_qss_theme + + + + realtime_scheduling + + + + run_command + {python} -u {filename} + + + run_options + prompt + + + run + True + + + thread_safe_setters + + + + title + Clock offset corrector tagged + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (736, 19) + + + _rotation + 0 + + + id + samp_rate_out + + + value + samp_rate_in + + + + pad_source + + comment + + + + _enabled + True + + + _coordinate + (32, 244) + + + _rotation + 0 + + + id + ctrl + + + label + ctrl + + + num_streams + 1 + + + optional + True + + + type + message + + + vlen + 1 + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (274, 19) + + + _rotation + 0 + + + id + fc + + + label + fc + + + short_id + + + + type + eng_float + + + value + 936.6e6 + + + + grgsm_controlled_fractional_resampler_cc + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + _coordinate + (328, 197) + + + _rotation + 0 + + + id + grgsm_controlled_fractional_resampler_cc_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + phase_shift + 0 + + + resamp_ratio + 1.0 + + + + grgsm_msg_to_tag + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (192, 193) + + + _rotation + 0 + + + id + grgsm_msg_to_tag_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + + gsm_controlled_rotator_cc + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (608, 209) + + + _rotation + 0 + + + id + gsm_controlled_rotator_cc_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + phase_inc + ppm/1.0e6*2*math.pi*fc/samp_rate_in + + + samp_rate + samp_rate_out + + + + import + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (11, 125) + + + _rotation + 0 + + + id + math_imp + + + import + import math + + + + pad_sink + + comment + + + + _enabled + True + + + _coordinate + (784, 220) + + + _rotation + 0 + + + id + pad_sink_1 + + + type + complex + + + label + out + + + num_streams + 1 + + + optional + False + + + vlen + 1 + + + + pad_source + + comment + + + + _enabled + True + + + _coordinate + (32, 188) + + + _rotation + 0 + + + id + pad_source_0 + + + label + in + + + num_streams + 1 + + + optional + False + + + type + complex + + + vlen + 1 + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (496, 19) + + + _rotation + 0 + + + id + ppm + + + label + ppm + + + short_id + + + + type + eng_float + + + value + 0 + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (368, 19) + + + _rotation + 0 + + + id + samp_rate_in + + + label + samp_rate_in + + + short_id + + + + type + eng_float + + + value + 1625000.0/6.0*4.0 + + + + parameter + + alias + + + + comment + + + + _enabled + False + + + _coordinate + (592, 20) + + + _rotation + 0 + + + id + samp_rate_out + + + label + samp_rate_out + + + short_id + + + + type + eng_float + + + value + 1625000.0/6.0*4.0 + + + + ctrl + grgsm_msg_to_tag_0 + out + msg + + + grgsm_controlled_fractional_resampler_cc_0 + gsm_controlled_rotator_cc_0 + 0 + 0 + + + grgsm_msg_to_tag_0 + grgsm_controlled_fractional_resampler_cc_0 + 0 + 0 + + + gsm_controlled_rotator_cc_0 + pad_sink_1 + 0 + 0 + + + pad_source_0 + grgsm_msg_to_tag_0 + 0 + 0 + + diff --git a/include/grgsm/receiver/clock_offset_control.h b/include/grgsm/receiver/clock_offset_control.h index 9a96d9c..ef750d1 100644 --- a/include/grgsm/receiver/clock_offset_control.h +++ b/include/grgsm/receiver/clock_offset_control.h @@ -49,8 +49,9 @@ namespace gr { * class. gsm::clock_offset_control::make is the public interface for * creating new instances. */ - static sptr make(float fc); - virtual void set_fc(float fc) = 0; + static sptr make(float fc, float samp_rate); + virtual void set_fc(float fc) = 0; + virtual void set_samp_rate(float samp_rate) = 0; }; } // namespace gsm diff --git a/lib/receiver/clock_offset_control_impl.cc b/lib/receiver/clock_offset_control_impl.cc index 43a9b8e..b3a7934 100644 --- a/lib/receiver/clock_offset_control_impl.cc +++ b/lib/receiver/clock_offset_control_impl.cc @@ -33,17 +33,17 @@ namespace gr namespace gsm { clock_offset_control::sptr -clock_offset_control::make(float fc) +clock_offset_control::make(float fc, float samp_rate) { return gnuradio::get_initial_sptr - (new clock_offset_control_impl(fc)); + (new clock_offset_control_impl(fc, samp_rate)); } /* * The private constructor */ -clock_offset_control_impl::clock_offset_control_impl(float fc) +clock_offset_control_impl::clock_offset_control_impl(float fc, float samp_rate) : gr::block("clock_offset_control", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) @@ -51,9 +51,10 @@ clock_offset_control_impl::clock_offset_control_impl(float fc) { message_port_register_in(pmt::mp("measurements")); set_msg_handler(pmt::mp("measurements"), boost::bind(&clock_offset_control_impl::process_measurement, this, _1)); - message_port_register_out(pmt::mp("ppm")); + message_port_register_out(pmt::mp("ctrl")); set_fc(fc); + set_samp_rate(samp_rate); d_alfa = 0.3; d_ppm_estimate = -1e6; d_last_ppm_estimate = -1e6; @@ -77,6 +78,11 @@ void clock_offset_control_impl::set_fc(float fc) d_fc = fc; } +void clock_offset_control_impl::set_samp_rate(float samp_rate) +{ + d_samp_rate = samp_rate; +} + void clock_offset_control_impl::process_measurement(pmt::pmt_t msg) { if(pmt::is_tuple(msg)) @@ -103,66 +109,76 @@ void clock_offset_control_impl::process_measurement(pmt::pmt_t msg) float ppm = -freq_offset/d_fc*1.0e6; std::string state = pmt::symbol_to_string(pmt::tuple_ref(msg,2)); d_last_state = state; - if(std::abs(ppm) > 100.0) //safeguard against flawed measurements + if(std::abs(ppm) < 100.0) //safeguard against flawed measurements { - ppm=0; - reset(); - } - if(state == "fcch_search") - { - pmt::pmt_t msg_ppm = pmt::from_double(ppm); - message_port_pub(pmt::intern("ppm"), msg_ppm); - d_last_fcch_time = d_current_time; - } - else - if (state == "synchronized") - { - d_last_fcch_time = d_current_time; - if(d_first_measurement) + if(state == "fcch_search") { - d_ppm_estimate = ppm; - d_first_measurement = false; - } - else + send_ctrl_messages(ppm); + d_last_fcch_time = d_current_time; + } + else + if (state == "synchronized") { - d_ppm_estimate = (1-d_alfa)*d_ppm_estimate+d_alfa*ppm; - } - - if(d_counter == 5) - { - d_counter = 0; - if(std::abs(d_last_ppm_estimate-d_ppm_estimate) > 0.1) + d_last_fcch_time = d_current_time; + if(d_first_measurement) + { + d_ppm_estimate = ppm; + d_first_measurement = false; + } + else { - pmt::pmt_t msg_ppm = pmt::from_double(ppm); - message_port_pub(pmt::intern("ppm"), msg_ppm); - d_last_ppm_estimate = d_ppm_estimate; + d_ppm_estimate = (1-d_alfa)*d_ppm_estimate+d_alfa*ppm; + } + + if(d_counter == 5) + { + d_counter = 0; + if(std::abs(d_last_ppm_estimate-d_ppm_estimate) > 0.1) + { +// pmt::pmt_t msg_ppm = pmt::from_double(ppm); +// message_port_pub(pmt::intern("ppm"), msg_ppm); + send_ctrl_messages(ppm); + d_last_ppm_estimate = d_ppm_estimate; + } + } + else + { + d_counter=d_counter+1; } } else + if(state == "sync_loss") { - d_counter=d_counter+1; + reset(); +// pmt::pmt_t msg_ppm = pmt::from_double(0.0); +// message_port_pub(pmt::intern("ppm"), msg_ppm); + send_ctrl_messages(0); } - } - else - if(state == "sync_loss") - { - reset(); - pmt::pmt_t msg_ppm = pmt::from_double(0.0); - message_port_pub(pmt::intern("ppm"), msg_ppm); - } + } } } } +void clock_offset_control_impl::send_ctrl_messages(float ppm) +{ +// pmt::pmt_t msg_ppm = pmt::from_double(ppm); +// message_port_pub(pmt::intern("ctrl"), msg_ppm); +// d_last_fcch_time = d_current_time; + + pmt::pmt_t msg_set_phase_inc = pmt::cons(pmt::intern("set_phase_inc"), pmt::from_double(2*M_PI*d_fc/d_samp_rate*ppm/1.0e6)); + message_port_pub(pmt::intern("ctrl"), msg_set_phase_inc); + + pmt::pmt_t msg_set_resamp_ratio = pmt::cons(pmt::intern("set_resamp_ratio"), pmt::from_double(1+ppm/1.0e6)); + message_port_pub(pmt::intern("ctrl"), msg_set_resamp_ratio); +} + void clock_offset_control_impl::timed_reset() { reset(); - pmt::pmt_t msg_ppm = pmt::from_double(0.0); - message_port_pub(pmt::intern("ppm"), msg_ppm); + send_ctrl_messages(0); } - void clock_offset_control_impl::reset() { d_ppm_estimate = -1e6; diff --git a/lib/receiver/clock_offset_control_impl.h b/lib/receiver/clock_offset_control_impl.h index 3c11a6f..cc0ea3d 100644 --- a/lib/receiver/clock_offset_control_impl.h +++ b/lib/receiver/clock_offset_control_impl.h @@ -32,9 +32,10 @@ namespace gr { { private: float d_fc; + float d_samp_rate; float d_alfa; float d_ppm_estimate; - float d_last_ppm_estimate; + float d_last_ppm_estimate; bool d_first_measurement; int d_counter; std::string d_last_state; @@ -43,13 +44,15 @@ namespace gr { bool d_first_time; void process_measurement(pmt::pmt_t msg); + void send_ctrl_messages(float ppm); void timed_reset(); void reset(); public: - clock_offset_control_impl(float fc); + clock_offset_control_impl(float fc, float samp_rate); ~clock_offset_control_impl(); virtual void set_fc(float fc); + virtual void set_samp_rate(float samp_rate); }; } // namespace gsm } // namespace gr diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index aa77ff1..a9c4599 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -41,7 +41,8 @@ GR_PYTHON_INSTALL( receiver/fcch_detector.py receiver/chirpz.py misc_utils/arfcn.py - misc_utils/clock_offset_corrector.py + misc_utils/clock_offset_corrector.py + misc_utils/clock_offset_corrector_tagged.py misc_utils/hier_block.py DESTINATION ${GR_PYTHON_DIR}/grgsm ) @@ -63,3 +64,4 @@ GR_ADD_TEST(qa_burst_fnr_filter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR} 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) GR_ADD_TEST(qa_msg_to_tag ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_msg_to_tag.py) +GR_ADD_TEST(qa_controlled_fractional_resampler_cc ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_controlled_fractional_resampler_cc.py) diff --git a/python/__init__.py b/python/__init__.py index dfa7a0e..2e35f6c 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -51,6 +51,7 @@ from fcch_burst_tagger import fcch_burst_tagger from sch_detector import sch_detector from fcch_detector import fcch_detector from clock_offset_corrector import clock_offset_corrector +from clock_offset_corrector_tagged import clock_offset_corrector_tagged from gsm_input import gsm_input from gsm_wideband_input import gsm_wideband_input from gsm_bcch_ccch_demapper import gsm_bcch_ccch_demapper diff --git a/python/misc_utils/clock_offset_corrector_tagged.py b/python/misc_utils/clock_offset_corrector_tagged.py new file mode 100644 index 0000000..5d198b0 --- /dev/null +++ b/python/misc_utils/clock_offset_corrector_tagged.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +################################################## +# GNU Radio Python Flow Graph +# Title: Clock offset corrector +# Author: Piotr Krysik +# Description: Clock offset corrector with blocks that use tags to switch offsets +# Generated: Fri Jul 15 10:09:22 2016 +################################################## + +from gnuradio import gr +from gnuradio.filter import firdes +import grgsm +import math + + +class clock_offset_corrector_tagged(grgsm.hier_block): + + def __init__(self, fc=936.6e6, ppm=0, samp_rate_in=1625000.0/6.0*4.0): + gr.hier_block2.__init__( + self, "Clock offset corrector tagged", + gr.io_signature(1, 1, gr.sizeof_gr_complex*1), + gr.io_signature(1, 1, gr.sizeof_gr_complex*1), + ) + self.message_port_register_hier_in("ctrl") + + ################################################## + # Parameters + ################################################## + self.fc = fc + self.ppm = ppm + self.samp_rate_in = samp_rate_in + + ################################################## + # Variables + ################################################## + self.samp_rate_out = samp_rate_out = samp_rate_in + + ################################################## + # Blocks + ################################################## + self.gsm_controlled_rotator_cc_0 = grgsm.controlled_rotator_cc(ppm/1.0e6*2*math.pi*fc/samp_rate_in,samp_rate_out) + self.grgsm_msg_to_tag_0 = grgsm.msg_to_tag() + self.grgsm_controlled_fractional_resampler_cc_0 = grgsm.controlled_fractional_resampler_cc(0, 1.0) + + ################################################## + # Connections + ################################################## + self.msg_connect((self, 'ctrl'), (self.grgsm_msg_to_tag_0, 'msg')) + self.connect((self.grgsm_controlled_fractional_resampler_cc_0, 0), (self.gsm_controlled_rotator_cc_0, 0)) + self.connect((self.grgsm_msg_to_tag_0, 0), (self.grgsm_controlled_fractional_resampler_cc_0, 0)) + self.connect((self.gsm_controlled_rotator_cc_0, 0), (self, 0)) + self.connect((self, 0), (self.grgsm_msg_to_tag_0, 0)) + + def get_fc(self): + return self.fc + + def set_fc(self, fc): + self.fc = fc + self.gsm_controlled_rotator_cc_0.set_phase_inc(self.ppm/1.0e6*2*math.pi*self.fc/self.samp_rate_in) + + def get_ppm(self): + return self.ppm + + def set_ppm(self, ppm): + self.ppm = ppm + self.gsm_controlled_rotator_cc_0.set_phase_inc(self.ppm/1.0e6*2*math.pi*self.fc/self.samp_rate_in) + + def get_samp_rate_in(self): + return self.samp_rate_in + + def set_samp_rate_in(self, samp_rate_in): + self.samp_rate_in = samp_rate_in + self.set_samp_rate_out(self.samp_rate_in) + self.gsm_controlled_rotator_cc_0.set_phase_inc(self.ppm/1.0e6*2*math.pi*self.fc/self.samp_rate_in) + + def get_samp_rate_out(self): + return self.samp_rate_out + + def set_samp_rate_out(self, samp_rate_out): + self.samp_rate_out = samp_rate_out + self.gsm_controlled_rotator_cc_0.set_samp_rate(self.samp_rate_out) -- cgit v1.2.3