diff options
author | Tom | 2010-02-01 19:21:54 -0500 |
---|---|---|
committer | Tom | 2010-02-01 19:21:54 -0500 |
commit | 4640708a2cb9740c41f0e27a6ce865a85473a4a0 (patch) | |
tree | f95c41a7c24ef25c5be1b23893f06de5cb14818b /gnuradio-core/src/python | |
parent | 824aa242f143a088f04031840bc36ed54de74005 (diff) | |
parent | 3bac2fa547168ca52352892e5f9db3335724682e (diff) | |
download | gnuradio-4640708a2cb9740c41f0e27a6ce865a85473a4a0.tar.gz gnuradio-4640708a2cb9740c41f0e27a6ce865a85473a4a0.tar.bz2 gnuradio-4640708a2cb9740c41f0e27a6ce865a85473a4a0.zip |
Merge branch 'fll'
Diffstat (limited to 'gnuradio-core/src/python')
-rw-r--r-- | gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py | 64 | ||||
-rw-r--r-- | gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py | 56 |
2 files changed, 77 insertions, 43 deletions
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py b/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py index cd9a207c8..e9fb3df89 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py @@ -26,7 +26,7 @@ differential BPSK modulation and demodulation. """ from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt +from math import pi, sqrt, ceil import psk import cmath from pprint import pprint @@ -38,6 +38,7 @@ _def_gray_code = True _def_verbose = False _def_log = False +_def_freq_alpha = 4e-3 _def_costas_alpha = 0.1 _def_timing_alpha = 0.100 _def_timing_beta = 0.010 @@ -85,8 +86,6 @@ class dbpsk2_mod(gr.hier_block2): if not isinstance(self._samples_per_symbol, int) or self._samples_per_symbol < 2: raise TypeError, ("sbp must be an integer >= 2, is %d" % self._samples_per_symbol) - ntaps = 11 * self._samples_per_symbol - arity = pow(2,self.bits_per_symbol()) # turn bytes into k-bit vectors @@ -103,15 +102,15 @@ class dbpsk2_mod(gr.hier_block2): self.chunks2symbols = gr.chunks_to_symbols_bc(psk.constellation[arity]) # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (samples_per_symbol since we're - # interpolating by samples_per_symbol) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) + nfilts = 32 + ntaps = nfilts * 11 * self._samples_per_symbol # make nfilts filters of ntaps each + self.rrc_taps = gr.firdes.root_raised_cosine( + nfilts, # gain + nfilts, # sampling rate based on 32 filters in resampler + 1.0, # symbol rate + self._excess_bw, # excess bandwidth (roll-off factor) ntaps) - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, - self.rrc_taps) + self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps) # Connect self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, @@ -182,6 +181,7 @@ class dbpsk2_demod(gr.hier_block2): def __init__(self, samples_per_symbol=_def_samples_per_symbol, excess_bw=_def_excess_bw, + freq_alpha=_def_freq_alpha, costas_alpha=_def_costas_alpha, timing_alpha=_def_timing_alpha, timing_max_dev=_def_timing_max_dev, @@ -199,9 +199,11 @@ class dbpsk2_demod(gr.hier_block2): @type samples_per_symbol: float @param excess_bw: Root-raised cosine filter excess bandwidth @type excess_bw: float - @param costas_alpha: loop filter gain + @param freq_alpha: loop filter gain for frequency recovery + @type freq_alpha: float + @param costas_alpha: loop filter gain for phase/fine frequency recovery @type costas_alpha: float - @param timing_alpha: timing loop alpha gain + @param timing_alpha: loop alpha gain for timing recovery @type timing_alpha: float @param timing_max: timing loop maximum rate deviations @type timing_max: float @@ -223,6 +225,8 @@ class dbpsk2_demod(gr.hier_block2): self._samples_per_symbol = samples_per_symbol self._excess_bw = excess_bw + self._freq_alpha = freq_alpha + self._freq_beta = 0.25*self._freq_alpha**2 self._costas_alpha = costas_alpha self._timing_alpha = timing_alpha self._timing_beta = _def_timing_beta @@ -238,24 +242,32 @@ class dbpsk2_demod(gr.hier_block2): self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) #self.agc = gr.feedforward_agc_cc(16, 1.0) + # Frequency correction + self.freq_recov = gr.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw, + 11*int(self._samples_per_symbol), + self._freq_alpha, self._freq_beta) + + # symbol timing recovery with RRC data filter + nfilts = 32 + ntaps = 11 * int(self._samples_per_symbol*nfilts) + taps = gr.firdes.root_raised_cosine(nfilts, nfilts, + 1.0/float(self._samples_per_symbol), + self._excess_bw, ntaps) + self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol, + self._timing_alpha, + taps, nfilts, nfilts/2, self._timing_max_dev) + self.time_recov.set_beta(self._timing_beta) + + # Perform phase / fine frequency correction self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha # Allow a frequency swing of +/- half of the sample rate fmin = -0.5 fmax = 0.5 - self.clock_recov = gr.costas_loop_cc(self._costas_alpha, + self.phase_recov = gr.costas_loop_cc(self._costas_alpha, self._costas_beta, fmax, fmin, arity) - # symbol timing recovery with RRC data filter - nfilts = 32 - ntaps = 11 * samples_per_symbol*nfilts - taps = gr.firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(self._samples_per_symbol), self._excess_bw, ntaps) - self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol, - self._timing_alpha, - taps, nfilts, nfilts/2, self._timing_max_dev) - self.time_recov.set_beta(self._timing_beta) - # Do differential decoding based on phase change of symbols self.diffdec = gr.diff_phasor_cc() @@ -280,8 +292,7 @@ class dbpsk2_demod(gr.hier_block2): # Connect self.connect(self, self.agc, - self.clock_recov, - self.time_recov, + self.freq_recov, self.time_recov, self.phase_recov, self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self) if sync_out: self.connect(self.time_recov, (self, 1)) @@ -297,6 +308,7 @@ class dbpsk2_demod(gr.hier_block2): print "bits per symbol: %d" % self.bits_per_symbol() print "Gray code: %s" % self._gray_code print "RRC roll-off factor: %.2f" % self._excess_bw + print "FLL gain: %.2f" % self._freq_alpha print "Costas Loop alpha: %.2f" % self._costas_alpha print "Costas Loop beta: %.2f" % self._costas_beta print "Timing alpha gain: %.2f" % self._timing_alpha @@ -333,6 +345,8 @@ class dbpsk2_demod(gr.hier_block2): parser.add_option("", "--no-gray-code", dest="gray_code", action="store_false", default=_def_gray_code, help="disable gray coding on modulated bits (PSK)") + parser.add_option("", "--freq-alpha", type="float", default=_def_freq_alpha, + help="set frequency lock loop alpha gain value [default=%default] (PSK)") parser.add_option("", "--costas-alpha", type="float", default=None, help="set Costas loop alpha value [default=%default] (PSK)") parser.add_option("", "--gain-alpha", type="float", default=_def_timing_alpha, diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py b/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py index fd1e9f0ef..9fae6acca 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py @@ -38,6 +38,7 @@ _def_gray_code = True _def_verbose = False _def_log = False +_def_freq_alpha = 4e-3 _def_costas_alpha = 0.01 _def_timing_alpha = 0.100 _def_timing_beta = 0.010 @@ -105,14 +106,15 @@ class dqpsk2_mod(gr.hier_block2): self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (sps since we're interpolating by sps) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) + nfilts = 32 + ntaps = nfilts * 11 * self._samples_per_symbol # make nfilts filters of ntaps each + self.rrc_taps = gr.firdes.root_raised_cosine( + nfilts, # gain + nfilts, # sampling rate based on 32 filters in resampler + 1.0, # symbol rate + self._excess_bw, # excess bandwidth (roll-off factor) ntaps) - - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) + self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps) if verbose: self._print_verbage() @@ -182,6 +184,7 @@ class dqpsk2_demod(gr.hier_block2): def __init__(self, samples_per_symbol=_def_samples_per_symbol, excess_bw=_def_excess_bw, + freq_alpha=_def_freq_alpha, costas_alpha=_def_costas_alpha, timing_alpha=_def_timing_alpha, timing_max_dev=_def_timing_max_dev, @@ -199,6 +202,8 @@ class dqpsk2_demod(gr.hier_block2): @type samples_per_symbol: float @param excess_bw: Root-raised cosine filter excess bandwidth @type excess_bw: float + @param freq_alpha: loop filter gain for frequency recovery + @type freq_alpha: float @param costas_alpha: loop filter gain @type costas_alphas: float @param timing_alpha: timing loop alpha gain @@ -223,6 +228,8 @@ class dqpsk2_demod(gr.hier_block2): self._samples_per_symbol = samples_per_symbol self._excess_bw = excess_bw + self._freq_alpha = freq_alpha + self._freq_beta = 0.25*self._freq_alpha**2 self._costas_alpha = costas_alpha self._timing_alpha = timing_alpha self._timing_beta = _def_timing_beta @@ -238,24 +245,35 @@ class dqpsk2_demod(gr.hier_block2): self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) #self.agc = gr.feedforward_agc_cc(16, 2.0) - self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha - # Allow a frequency swing of +/- half of the sample rate - fmin = -0.5 - fmax = 0.5 + # Frequency correction + self.freq_recov = gr.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw, + 11*int(self._samples_per_symbol), + self._freq_alpha, self._freq_beta) - self.clock_recov = gr.costas_loop_cc(self._costas_alpha, - self._costas_beta, - fmax, fmin, arity) # symbol timing recovery with RRC data filter nfilts = 32 - ntaps = 11 * samples_per_symbol*nfilts - taps = gr.firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(self._samples_per_symbol), self._excess_bw, ntaps) + ntaps = 11 * int(samples_per_symbol*nfilts) + taps = gr.firdes.root_raised_cosine(nfilts, nfilts, + 1.0/float(self._samples_per_symbol), + self._excess_bw, ntaps) self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol, self._timing_alpha, taps, nfilts, nfilts/2, self._timing_max_dev) self.time_recov.set_beta(self._timing_beta) + + # Perform phase / fine frequency correction + self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha + # Allow a frequency swing of +/- half of the sample rate + fmin = -0.5 + fmax = 0.5 + + self.phase_recov = gr.costas_loop_cc(self._costas_alpha, + self._costas_beta, + fmax, fmin, arity) + + # Perform Differential decoding on the constellation self.diffdec = gr.diff_phasor_cc() @@ -280,8 +298,7 @@ class dqpsk2_demod(gr.hier_block2): # Connect self.connect(self, self.agc, - self.clock_recov, - self.time_recov, + self.freq_recov, self.time_recov, self.phase_recov, self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self) if sync_out: self.connect(self.time_recov, (self, 1)) @@ -297,6 +314,7 @@ class dqpsk2_demod(gr.hier_block2): print "bits per symbol: %d" % self.bits_per_symbol() print "Gray code: %s" % self._gray_code print "RRC roll-off factor: %.2f" % self._excess_bw + print "FLL gain: %.2f" % self._freq_alpha print "Costas Loop alpha: %.2e" % self._costas_alpha print "Costas Loop beta: %.2e" % self._costas_beta print "Timing alpha gain: %.2f" % self._timing_alpha @@ -333,6 +351,8 @@ class dqpsk2_demod(gr.hier_block2): parser.add_option("", "--no-gray-code", dest="gray_code", action="store_false", default=_def_gray_code, help="disable gray coding on modulated bits (PSK)") + parser.add_option("", "--freq-alpha", type="float", default=_def_freq_alpha, + help="set frequency lock loop alpha gain value [default=%default] (PSK)") parser.add_option("", "--costas-alpha", type="float", default=_def_costas_alpha, help="set Costas loop alpha value [default=%default] (PSK)") parser.add_option("", "--gain-alpha", type="float", default=_def_timing_alpha, |