mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-13 00:57:31 -05:00
P25 - enhancement for LSM demod phase lock errors - adds new sync pattern detectors to detect Costas Loop phase lock errors and apply immediate correction to enable accurate symbol slicing.
This commit is contained in:
@@ -76,6 +76,8 @@ public class CQPSKDemodulator implements Instrumentable,
|
||||
|
||||
private GardnerSymbolTiming mGardnerDetector = new GardnerSymbolTiming();
|
||||
|
||||
private CostasLoop mCostasLoop = new CostasLoop();
|
||||
|
||||
private FrequencyChangeListener mFrequencyChangeListener;
|
||||
|
||||
private EyeDiagramDataTap mEyeDiagramDataTap;
|
||||
@@ -90,6 +92,17 @@ public class CQPSKDemodulator implements Instrumentable,
|
||||
mGardnerDetector.receive( sample );
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a phase correction value to the costas loop to correct when a
|
||||
* phase lock error is detected in the binary output stream.
|
||||
*
|
||||
* @param correction - value in radians
|
||||
*/
|
||||
public void correctPhaseError( double correction )
|
||||
{
|
||||
mCostasLoop.correctPhaseError( correction );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constrains value to the range of ( -maximum <> maximum )
|
||||
*/
|
||||
@@ -207,7 +220,7 @@ public class CQPSKDemodulator implements Instrumentable,
|
||||
|
||||
/* Sampling point */
|
||||
private float mMu = 10.0f;
|
||||
private float mGainMu = 0.25f;
|
||||
private float mGainMu = 0.1f;
|
||||
|
||||
/* Samples per symbol */
|
||||
private float mOmega = 10.0f;
|
||||
@@ -215,8 +228,6 @@ public class CQPSKDemodulator implements Instrumentable,
|
||||
private float mOmegaRel = 0.005f;
|
||||
private float mOmegaMid = 10.0f;
|
||||
|
||||
private CostasLoop mCostasLoop = new CostasLoop();
|
||||
|
||||
private QPSKInterpolator mInterpolator = new QPSKInterpolator( 1.0f );
|
||||
|
||||
private ComplexSample mPreviousSample = new ComplexSample( 0.0f, 0.0f );
|
||||
@@ -347,7 +358,7 @@ public class CQPSKDemodulator implements Instrumentable,
|
||||
public static final double TWO_PI = 2.0 * Math.PI;
|
||||
|
||||
private static final float MAXIMUM_FREQUENCY =
|
||||
( 1200.0f * (float)TWO_PI ) / 48000.0f;
|
||||
( 2400.0f * (float)TWO_PI ) / 48000.0f;
|
||||
|
||||
/* http://www.trondeau.com/blog/2011/8/13/control-loop-gain-values.html */
|
||||
private float mDamping = (float)Math.sqrt( 2.0 ) / 2.0f;
|
||||
@@ -374,6 +385,33 @@ public class CQPSKDemodulator implements Instrumentable,
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a phase correction value to the current phasor. Use this
|
||||
* method to apply correction when a +/- 90, or 180 degree phase error
|
||||
* is detected in the binary output stream.
|
||||
*
|
||||
* If the supplied correction value places the loop frequency outside
|
||||
* of the max frequency, then the frequency will be corrected 360
|
||||
* degrees in the opposite direction to maintain within the max
|
||||
* frequency bounds.
|
||||
*
|
||||
* @param correction - correction value in radians
|
||||
*/
|
||||
public void correctPhaseError( double correction )
|
||||
{
|
||||
mLoopFrequency += correction;
|
||||
|
||||
if( mLoopFrequency > MAXIMUM_FREQUENCY )
|
||||
{
|
||||
mLoopFrequency -= 2.0d * MAXIMUM_FREQUENCY;
|
||||
}
|
||||
|
||||
if( mLoopFrequency < -MAXIMUM_FREQUENCY )
|
||||
{
|
||||
mLoopFrequency += 2.0d * MAXIMUM_FREQUENCY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the phase of the loop
|
||||
*/
|
||||
|
||||
@@ -13,9 +13,9 @@ public class QPSKStarSlicer implements Listener<ComplexSample>
|
||||
* Slices a ComplexSample representing a phase shifted symbol according to
|
||||
* the following constellation pattern:
|
||||
*
|
||||
* 11 | 01
|
||||
* 00 | 01
|
||||
* ---|---
|
||||
* 10 | 00
|
||||
* 10 | 11
|
||||
*/
|
||||
public QPSKStarSlicer()
|
||||
{
|
||||
|
||||
@@ -2,8 +2,10 @@ package dsp.symbol;
|
||||
|
||||
public enum FrameSync
|
||||
{
|
||||
P25_PHASE1( 0x5575F5FF77FFl ), //+3 +3 +3 +3 +3 -3 +3 +3 -3 -3 +3 +3 -3 -3 -3 -3 +3 -3 +3 -3 -3 -3 -3 -3
|
||||
P25_PHASE1_INVERTED( 0xFFDF5F55DD55l );
|
||||
P25_PHASE1_ERROR_90_CCW( 0xFFEFAFAAEEAAl ),
|
||||
P25_PHASE1_NORMAL( 0x5575F5FF77FFl ), // +33333 -3 +33 -33 +33 -3333 +3 -3 +3 -33333
|
||||
P25_PHASE1_ERROR_90_CW( 0x001050551155l ),
|
||||
P25_PHASE1_ERROR_180( 0xAA8A0A008800l );
|
||||
|
||||
private long mSync;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user