From 2c96e006b05eecbd25412de3d3efce60266bc800 Mon Sep 17 00:00:00 2001 From: Christoph Mayer Date: Tue, 5 Nov 2019 21:24:51 +0100 Subject: [PATCH] added a OQPSK demodulator --- grc/CMakeLists.txt | 1 + grc/digitalhf_oqpsk_demodulator.xml | 40 +++++++ include/digitalhf/CMakeLists.txt | 1 + include/digitalhf/oqpsk_demodulator.h | 60 ++++++++++ lib/CMakeLists.txt | 1 + lib/oqpsk_demodulator_impl.cc | 152 ++++++++++++++++++++++++++ lib/oqpsk_demodulator_impl.h | 72 ++++++++++++ swig/digitalhf_swig.i | 4 + 8 files changed, 331 insertions(+) create mode 100644 grc/digitalhf_oqpsk_demodulator.xml create mode 100644 include/digitalhf/oqpsk_demodulator.h create mode 100644 lib/oqpsk_demodulator_impl.cc create mode 100644 lib/oqpsk_demodulator_impl.h diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index a37bd91..3e6f8b8 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -22,5 +22,6 @@ install(FILES digitalhf_physical_layer_driver.xml digitalhf_doppler_correction_cc.xml digitalhf_cis_12_channelizer.xml + digitalhf_oqpsk_demodulator.xml digitalhf_msg_proxy.xml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/digitalhf_oqpsk_demodulator.xml b/grc/digitalhf_oqpsk_demodulator.xml new file mode 100644 index 0000000..2aabc04 --- /dev/null +++ b/grc/digitalhf_oqpsk_demodulator.xml @@ -0,0 +1,40 @@ + + + oqpsk_demodulator + digitalhf_oqpsk_demodulator + [digitalhf] + import digitalhf + digitalhf.oqpsk_demodulator($fs, $fd, $loop_bw, $df) + + fs (Hz) + fs + float + + + fd (Hz) + fd + float + + + loop_bw + loop_bw + float + + + df (Hz) + df + float + + + in + complex + + + soft_dec_x + float + + + soft_dec_y + float + + diff --git a/include/digitalhf/CMakeLists.txt b/include/digitalhf/CMakeLists.txt index 18d04e0..b182aaa 100644 --- a/include/digitalhf/CMakeLists.txt +++ b/include/digitalhf/CMakeLists.txt @@ -29,6 +29,7 @@ install(FILES viterbi29.h viterbi39.h viterbi48.h + oqpsk_demodulator.h vector_pll_cc.h DESTINATION include/digitalhf ) diff --git a/include/digitalhf/oqpsk_demodulator.h b/include/digitalhf/oqpsk_demodulator.h new file mode 100644 index 0000000..0278846 --- /dev/null +++ b/include/digitalhf/oqpsk_demodulator.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2019 hcab14@gmail.com. + * + * This 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. + * + * This software 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_DIGITALHF_OQPSK_DEMODULATOR_H +#define INCLUDED_DIGITALHF_OQPSK_DEMODULATOR_H + +#include +#include + +namespace gr { +namespace digitalhf { + +/*! + * \brief <+description of block+> + * \ingroup digitalhf + * + */ +class DIGITALHF_API oqpsk_demodulator : virtual public gr::block +{ + public: + typedef boost::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of digitalhf::oqpsk_demodulator. + * + * To avoid accidental use of raw pointers, digitalhf::oqpsk_demodulator's + * constructor is in a private implementation + * class. digitalhf::oqpsk_demodulator::make is the public interface for + * creating new instances. + */ + static sptr make(float fs=240e3, + float fd=48e3, + float loop_bw=3.1415/100.0f, + float df=20.0f); + +}; + +} // namespace digitalhf +} // namespace gr + +#endif /* INCLUDED_DIGITALHF_OQPSK_DEMODULATOR_H */ + diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 14ab2fc..0e840c0 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -32,6 +32,7 @@ list(APPEND digitalhf_sources viterbi29_impl.cc viterbi39_impl.cc viterbi48_impl.cc + oqpsk_demodulator_impl.cc vector_pll_cc_impl.cc vector_early_late_cc_impl.cc lms.cc diff --git a/lib/oqpsk_demodulator_impl.cc b/lib/oqpsk_demodulator_impl.cc new file mode 100644 index 0000000..9318789 --- /dev/null +++ b/lib/oqpsk_demodulator_impl.cc @@ -0,0 +1,152 @@ +/* -*- c++ -*- */ +/* + * Copyright 2019 hcab14@gmail.com. + * + * This 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. + * + * This software 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include "oqpsk_demodulator_impl.h" + +namespace gr { +namespace digitalhf { + +my_control_loop::~my_control_loop() { +} + +void +my_control_loop::phase_wrap(float x) +{ + // d_phase = fmodf(d_phase, x); + while (d_phase > x) + d_phase -= x; + while (d_phase < -x) + d_phase += x; +} + +oqpsk_demodulator::sptr +oqpsk_demodulator::make(float fs, + float fd, + float loop_bw, + float df) +{ + return gnuradio::get_initial_sptr + (new oqpsk_demodulator_impl(fs, fd, loop_bw, df)); +} + +/* + * The private constructor + */ +oqpsk_demodulator_impl::oqpsk_demodulator_impl(float fs, + float fd, + float loop_bw, + float df) + : gr::block("oqpsk_demodulator", + gr::io_signature::make(1, 1, sizeof(gr_complex)), + gr::io_signature::make(2, 2, sizeof(float))) + , _pll_plus (loop_bw, + (+0.5f*fd + df)/fs*2*M_PI, + (+0.5f*fd - df)/fs*2*M_PI) + , _pll_minus(loop_bw, + (-0.5f*fd + df)/fs*2*M_PI, + (-0.5f*fd - df)/fs*2*M_PI) + , _soft_dec_x(0.0f) + , _soft_dec_y(0.0f) + , _soft_dec_x_last(0.0f) + , _soft_dec_y_last(0.0f) + , _code_cos_last(0.0f) + , _code_sin_last(0.0f) +{ + GR_LOG_DECLARE_LOGPTR(d_logger); + GR_LOG_ASSIGN_LOGPTR(d_logger, "oqpsk_demodulator"); +} + +oqpsk_demodulator_impl::~oqpsk_demodulator_impl() +{ +} + +int +oqpsk_demodulator_impl::general_work(int noutput_items, + gr_vector_int& ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + gr::thread::scoped_lock lock(d_setlock); + gr_complex const* in = static_cast(input_items[0]); + float* out_x = static_cast(output_items[0]); + float* out_y = static_cast(output_items[1]); + + int nout = 0; + int i = 0; + for (; i + +#include + +namespace gr { +namespace digitalhf { + +class my_control_loop : public blocks::control_loop { +public: + my_control_loop(float loop_bw, float max_freq, float min_freq) + : blocks::control_loop(loop_bw, max_freq, min_freq) {} + virtual ~my_control_loop(); + + virtual void phase_wrap(float x); +protected: +} ; + +class oqpsk_demodulator_impl : public oqpsk_demodulator +{ +private: + my_control_loop _pll_plus; + my_control_loop _pll_minus; + + float _soft_dec_x; + float _soft_dec_y; + float _soft_dec_x_last; + float _soft_dec_y_last; + float _code_cos_last; + float _code_sin_last; +public: + oqpsk_demodulator_impl(float fs, + float fd, + float loop_bw, + float df); + virtual ~oqpsk_demodulator_impl(); + + int general_work(int noutput_items, + gr_vector_int& ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + +protected: + +}; + +} // namespace digitalhf +} // namespace gr + +#endif /* INCLUDED_DIGITALHF_OQPSK_DEMODULATOR_IMPL_H */ diff --git a/swig/digitalhf_swig.i b/swig/digitalhf_swig.i index b274719..ce6e67f 100644 --- a/swig/digitalhf_swig.i +++ b/swig/digitalhf_swig.i @@ -10,6 +10,7 @@ %{ #include "digitalhf/adaptive_dfe.h" #include "digitalhf/doppler_correction_cc.h" +#include "digitalhf/oqpsk_demodulator.h" #include "digitalhf/viterbi27.h" #include "digitalhf/viterbi29.h" #include "digitalhf/viterbi39.h" @@ -27,6 +28,9 @@ GR_SWIG_BLOCK_MAGIC2(digitalhf, doppler_correction_cc); %include "digitalhf/vector_pll_cc.h" GR_SWIG_BLOCK_MAGIC2(digitalhf, vector_pll_cc); +%include "digitalhf/oqpsk_demodulator.h" +GR_SWIG_BLOCK_MAGIC2(digitalhf, oqpsk_demodulator); + %include "digitalhf/vector_early_late_cc.h" GR_SWIG_BLOCK_MAGIC2(digitalhf, vector_early_late_cc);