summaryrefslogtreecommitdiff
path: root/gr-digital/include/digital/mpsk_receiver_cc.h
blob: 14094e25b7924730d14d621eff5bb180bbaaf2ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/* -*- c++ -*- */
/*
 * Copyright 2004,2007,2011,2012 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_MPSK_RECEIVER_CC_H
#define	INCLUDED_DIGITAL_MPSK_RECEIVER_CC_H

#include <digital/api.h>
#include <gr_block.h>

namespace gr {
  namespace digital {

    /*!
     * \brief This block takes care of receiving M-PSK modulated
     * signals through phase, frequency, and symbol synchronization.
     * \ingroup sync_blk
     * \ingroup demod_blk
     * \ingroup digital
     *
     * This block takes care of receiving M-PSK modulated signals
     * through phase, frequency, and symbol synchronization. It
     * performs carrier frequency and phase locking as well as symbol
     * timing recovery.  It works with (D)BPSK, (D)QPSK, and (D)8PSK
     * as tested currently. It should also work for OQPSK and PI/4
     * DQPSK.
     *
     * The phase and frequency synchronization are based on a Costas
     * loop that finds the error of the incoming signal point compared
     * to its nearest constellation point. The frequency and phase of
     * the NCO are updated according to this error. There are
     * optimized phase error detectors for BPSK and QPSK, but 8PSK is
     * done using a brute-force computation of the constellation
     * points to find the minimum.
     *
     * The symbol synchronization is done using a modified Mueller and
     * Muller circuit from the paper:
     *
     * "G. R. Danesfahani, T. G. Jeans, "Optimisation of modified Mueller
     * and Muller algorithm," Electronics Letters, Vol. 31, no. 13, 22
     * June 1995, pp. 1032 - 1033."
     *
     * This circuit interpolates the downconverted sample (using the
     * NCO developed by the Costas loop) every mu samples, then it
     * finds the sampling error based on this and the past symbols and
     * the decision made on the samples. Like the phase error
     * detector, there are optimized decision algorithms for BPSK and
     * QPKS, but 8PSK uses another brute force computation against all
     * possible symbols. The modifications to the M&M used here reduce
     * self-noise.
     *
     */
    class DIGITAL_API mpsk_receiver_cc : virtual public gr_block
    {
    public:
      // gr::digital::mpsk_receiver_cc::sptr
      typedef boost::shared_ptr<mpsk_receiver_cc> sptr;

      /*!
       * \brief Buil M-PSK receiver block.
       *
       * \param M	    modulation order of the M-PSK modulation
       * \param theta	    any constant phase rotation from the real axis of the constellation
       * \param loop_bw	    Loop bandwidth to set gains of phase/freq tracking loop
       * \param fmin        minimum normalized frequency value the loop can achieve
       * \param fmax        maximum normalized frequency value the loop can achieve
       * \param mu          initial parameter for the interpolator [0,1]
       * \param gain_mu     gain parameter of the M&M error signal to adjust mu (~0.05)
       * \param omega       initial value for the number of symbols between samples (~number of samples/symbol)
       * \param gain_omega  gain parameter to adjust omega based on the error (~omega^2/4)
       * \param omega_rel   sets the maximum (omega*(1+omega_rel)) and minimum (omega*(1+omega_rel)) omega (~0.005)
       *
       * The constructor also chooses which phase detector and
       * decision maker to use in the work loop based on the value of
       * M.
       */
      static sptr make(unsigned int M, float theta, 
		       float loop_bw,
		       float fmin, float fmax,
		       float mu, float gain_mu, 
		       float omega, float gain_omega, float omega_rel);
      
      //! Returns the modulation order (M) currently set
      virtual float modulation_order() const = 0;

      //! Returns current value of theta
      virtual float theta() const = 0;

      //! Returns current value of mu
      virtual float mu() const = 0;

      //! Returns current value of omega
      virtual float omega() const = 0;

      //! Returns mu gain factor
      virtual float gain_mu() const = 0;

      //! Returns omega gain factor
      virtual float gain_omega() const = 0;

      //! Returns the relative omega limit
      virtual float gain_omega_rel() const = 0;

      //! Sets the modulation order (M) currently
      virtual void set_modulation_order(unsigned int M) = 0;

      //! Sets value of theta
      virtual void set_theta(float theta) = 0;

      //! Sets value of mu
      virtual void set_mu(float mu) = 0;
  
      //! Sets value of omega and its min and max values 
      virtual void set_omega(float omega) = 0;

      //! Sets value for mu gain factor
      virtual void set_gain_mu(float gain_mu) = 0;

      //! Sets value for omega gain factor
      virtual void set_gain_omega(float gain_omega) = 0;

      //! Sets the relative omega limit and resets omega min/max values
      virtual void set_gain_omega_rel(float omega_rel) = 0;
    };

  } /* namespace digital */
} /* namespace gr */

#endif /* INCLUDED_DIGITAL_MPSK_RECEIVER_CC_H */