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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
|
/* -*- c++ -*- */
/*
* Copyright 2011 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_CONSTELLATION_RECEIVER_CB_H
#define INCLUDED_DIGITAL_CONSTELLATION_RECEIVER_CB_H
#include <digital_api.h>
#include <gr_block.h>
#include <digital_constellation.h>
#include <gr_complex.h>
#include <math.h>
#include <fstream>
class digital_constellation_receiver_cb;
typedef boost::shared_ptr<digital_constellation_receiver_cb> digital_constellation_receiver_cb_sptr;
// public constructor
DIGITAL_API digital_constellation_receiver_cb_sptr
digital_make_constellation_receiver_cb (digital_constellation_sptr constellation,
float loop_bw, float fmin, float fmax);
/*!
* \brief This block takes care of receiving generic modulated signals through phase, frequency, and symbol
* synchronization.
* \ingroup sync_blk
* \ingroup demod_blk
*
* This block takes care of receiving generic modulated signals through phase, frequency, and symbol
* synchronization. It performs carrier frequency and phase locking as well as symbol timing recovery.
*
* 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.
*
* 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 digital_constellation_receiver_cb : public gr_block
{
public:
int general_work (int noutput_items,
gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
/*******************************************************************
SET FUNCTIONS
*******************************************************************/
/*!
* \brief Set the loop bandwidth
*
* Set the loop filter's bandwidth to \p bw. This should be between
* 2*pi/200 and 2*pi/100 (in rads/samp). It must also be a positive
* number.
*
* When a new damping factor is set, the gains, alpha and beta, of the loop
* are recalculated by a call to update_gains().
*
* \param bw (float) new bandwidth
*
*/
void set_loop_bandwidth(float bw);
/*!
* \brief Set the loop damping factor
*
* Set the loop filter's damping factor to \p df. The damping factor
* should be sqrt(2)/2.0 for critically damped systems.
* Set it to anything else only if you know what you are doing. It must
* be a number between 0 and 1.
*
* When a new damping factor is set, the gains, alpha and beta, of the loop
* are recalculated by a call to update_gains().
*
* \param df (float) new damping factor
*
*/
void set_damping_factor(float df);
/*!
* \brief Set the loop gain alpha
*
* Set's the loop filter's alpha gain parameter.
*
* This value should really only be set by adjusting the loop bandwidth
* and damping factor.
*
* \param alpha (float) new alpha gain
*
*/
void set_alpha(float alpha);
/*!
* \brief Set the loop gain beta
*
* Set's the loop filter's beta gain parameter.
*
* This value should really only be set by adjusting the loop bandwidth
* and damping factor.
*
* \param beta (float) new beta gain
*
*/
void set_beta(float beta);
/*!
* \brief Set the phase/freq recovery loop's frequency.
*
* Set's the phase/freq recovery loop's frequency. While this is normally
* updated by the inner loop of the algorithm, it could be useful to
* manually initialize, set, or reset this under certain circumstances.
*
* \param freq (float) new frequency
*
*/
void set_frequency(float freq);
/*!
* \brief Set the phase/freq recovery loop's phase.
*
* Set's the phase/freq recovery loop's phase. While this is normally
* updated by the inner loop of the algorithm, it could be useful to
* manually initialize, set, or reset this under certain circumstances.
*
* \param phase (float) new phase
*
*/
void set_phase(float phase);
/*******************************************************************
GET FUNCTIONS
*******************************************************************/
/*!
* \brief Returns the loop bandwidth
*/
float get_loop_bandwidth() const;
/*!
* \brief Returns the loop damping factor
*/
float get_damping_factor() const;
/*!
* \brief Returns the loop gain alpha
*/
float get_alpha() const;
/*!
* \brief Returns the loop gain beta
*/
float get_beta() const;
/*!
* \brief Get the phase/freq recovery loop's frequency estimate
*/
float get_frequency() const;
/*!
* \brief Get the phase/freq loop's phase estimate
*/
float get_phase() const;
protected:
/*!
* \brief Constructor to synchronize incoming M-PSK symbols
*
* \param constellation constellation of points for generic modulation
* \param alpha gain parameter to adjust the phase in the Costas loop (~0.01)
* \param beta gain parameter to adjust the frequency in the Costas loop (~alpha^2/4)
* \param fmin minimum normalized frequency value the loop can achieve
* \param fmax maximum normalized frequency value the loop can achieve
*
* The constructor also chooses which phase detector and decision maker to use in the
* work loop based on the value of M.
*/
digital_constellation_receiver_cb (digital_constellation_sptr constellation,
float loop_bw, float fmin, float fmax);
void phase_error_tracking(float phase_error);
private:
unsigned int d_M;
// Members related to carrier and phase tracking
float d_freq, d_max_freq, d_min_freq;
float d_phase;
float d_loop_bw;
float d_damping;
float d_alpha;
float d_beta;
digital_constellation_sptr d_constellation;
unsigned int d_current_const_point;
//! delay line length.
static const unsigned int DLLEN = 8;
//! delay line plus some length for overflow protection
gr_complex d_dl[2*DLLEN] __attribute__ ((aligned(8)));
//! index to delay line
unsigned int d_dl_idx;
/*! \brief update the system gains from the loop bandwidth and damping factor
*
* This function updates the system gains based on the loop
* bandwidth and damping factor of the system.
* These two factors can be set separately through their own
* set functions.
*/
void update_gains();
friend DIGITAL_API digital_constellation_receiver_cb_sptr
digital_make_constellation_receiver_cb (digital_constellation_sptr constell,
float loop_bw, float fmin, float fmax);
};
#endif
|