summaryrefslogtreecommitdiff
path: root/gr-digital/lib/symbol_sync_ff_impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'gr-digital/lib/symbol_sync_ff_impl.h')
-rw-r--r--gr-digital/lib/symbol_sync_ff_impl.h153
1 files changed, 153 insertions, 0 deletions
diff --git a/gr-digital/lib/symbol_sync_ff_impl.h b/gr-digital/lib/symbol_sync_ff_impl.h
new file mode 100644
index 0000000000..f4bd6658b3
--- /dev/null
+++ b/gr-digital/lib/symbol_sync_ff_impl.h
@@ -0,0 +1,153 @@
+/* -*- c++ -*- */
+/*
+ * Copyright (C) 2017 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DIGITAL_SYMBOL_SYNC_FF_IMPL_H
+#define INCLUDED_DIGITAL_SYMBOL_SYNC_FF_IMPL_H
+
+#include <gnuradio/digital/symbol_sync_ff.h>
+#include "clock_tracking_loop.h"
+#include "timing_error_detector.h"
+#include "interpolating_resampler.h"
+
+namespace gr {
+ namespace digital {
+
+ class symbol_sync_ff_impl : public symbol_sync_ff
+ {
+ public:
+ symbol_sync_ff_impl(enum ted_type detector_type,
+ float sps,
+ float loop_bw,
+ float damping_factor,
+ float max_deviation,
+ int osps,
+ constellation_sptr slicer,
+ ir_type interp_type,
+ int n_filters,
+ const std::vector<float> &taps);
+ ~symbol_sync_ff_impl();
+
+ void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ // Symbol Clock Tracking and Estimation
+ float loop_bandwidth() const { return d_clock->get_loop_bandwidth(); }
+ float damping_factor() const { return d_clock->get_damping_factor(); }
+ float alpha() const { return d_clock->get_alpha(); }
+ float beta() const { return d_clock->get_beta(); }
+
+ void set_loop_bandwidth (float omega_n_norm) {
+ d_clock->set_loop_bandwidth(omega_n_norm);
+ }
+ void set_damping_factor (float zeta) {
+ d_clock->set_damping_factor(zeta);
+ }
+ void set_alpha (float alpha) { d_clock->set_alpha(alpha); }
+ void set_beta (float beta) { d_clock->set_beta(beta); }
+
+ private:
+ // Timing Error Detector
+ timing_error_detector *d_ted;
+
+ // Symbol Clock Tracking and Estimation
+ clock_tracking_loop *d_clock;
+
+ // Interpolator and Interpolator Positioning and Alignment
+ interpolating_resampler_fff *d_interp;
+
+ // Block Internal Clocks
+ // 4 clocks that run synchronously, aligned to the Symbol Clock:
+ // Interpolator Clock (always highest rate)
+ // Timing Error Detector Input Clock
+ // Output Sample Clock
+ // Symbol Clock (always lowest rate)
+ int d_interp_clock;
+ float d_inst_interp_period;
+
+ float d_interps_per_ted_input;
+ int d_interps_per_ted_input_n;
+ bool d_ted_input_clock;
+
+ int d_interps_per_output_sample_n;
+ bool d_output_sample_clock;
+ float d_inst_output_period;
+
+ float d_interps_per_symbol;
+ int d_interps_per_symbol_n;
+ bool d_symbol_clock;
+ float d_inst_clock_period;
+ float d_avg_clock_period;
+
+ // Block output
+ float d_osps;
+ int d_osps_n;
+
+ // Tag Propagation and Symbol Clock Tracking Reset/Resync
+ uint64_t d_filter_delay; // interpolator filter delay
+ std::vector<tag_t> d_tags;
+ std::vector<tag_t> d_new_tags;
+ pmt::pmt_t d_time_est_key;
+ pmt::pmt_t d_clock_est_key;
+
+ // Optional Diagnostic Outputs
+ int d_noutputs;
+ float *d_out_error;
+ float *d_out_instantaneous_clock_period;
+ float *d_out_average_clock_period;
+
+ // Block Internal Clocks
+ void update_internal_clock_outputs();
+ void advance_internal_clocks();
+ void revert_internal_clocks();
+ void sync_reset_internal_clocks();
+ bool ted_input_clock() { return d_ted_input_clock; }
+ bool output_sample_clock() { return d_output_sample_clock; }
+ bool symbol_clock() { return d_symbol_clock; }
+
+ // Tag Propagation and Clock Tracking Reset/Resync
+ void collect_tags(uint64_t nitems_rd, int count);
+ bool find_sync_tag(uint64_t nitems_rd, int iidx,
+ int distance,
+ uint64_t &tag_offset,
+ float &timing_offset,
+ float &clock_period);
+ void propagate_tags(uint64_t nitems_rd, int iidx,
+ float iidx_fraction,
+ float inst_output_period,
+ uint64_t nitems_wr, int oidx);
+ void save_expiring_tags(uint64_t nitems_rd, int consumed);
+
+ // Optional Diagnostic Outputs
+ void setup_optional_outputs(gr_vector_void_star &output_items);
+ void emit_optional_output(int oidx,
+ float error,
+ float inst_clock_period,
+ float avg_clock_period);
+ };
+
+ } /* namespace digital */
+} /* namespace gr */
+
+#endif /* INCLUDED_DIGITAL_SYMBOL_SYNC_FF_IMPL_H */