From ef7c258cbf2b56a9dca6df68c4b03f60cdd52bd4 Mon Sep 17 00:00:00 2001 From: Thomas Tsou Date: Wed, 21 Aug 2013 20:58:00 -0400 Subject: Transceiver52M: Refactor RACH and TSC detection Both RACH and normal bursts are detected with the same approach of midamble correlation combined with peak-to-average ratio. The difference is the midamble placements and lengths. Thus, there is no reason to have independent implementations. This patch creates a common call burstDetect(), while leaving the correlation window indexing in the original calls. Signed-off-by: Thomas Tsou --- Transceiver52M/sigProcLib.cpp | 250 ++++++++++++++++++++++-------------------- 1 file changed, 133 insertions(+), 117 deletions(-) diff --git a/Transceiver52M/sigProcLib.cpp b/Transceiver52M/sigProcLib.cpp index b34c580..74dd915 100644 --- a/Transceiver52M/sigProcLib.cpp +++ b/Transceiver52M/sigProcLib.cpp @@ -955,78 +955,36 @@ release: return status; } -int detectRACHBurst(signalVector &rxBurst, - float thresh, - int sps, - complex *amp, - float *toa) +static float computePeakRatio(signalVector *corr, + int sps, float toa, complex amp) { - int start, len, num = 0; - float _toa, rms, par, avg = 0.0f; - complex _amp, *peak; - signalVector corr, *sync = gRACHSequence->sequence; - - if ((sps != 1) && (sps != 2) && (sps != 4)) - return -1; + int num = 0; + complex *peak; + float rms, avg = 0.0; - start = 40 * sps; - len = 24 * sps; - corr = signalVector(len); + peak = corr->begin() + (int) rint(toa); - if (!convolve(&rxBurst, sync, &corr, - CUSTOM, start, len, sps, 0)) { - return -1; - } - - /* Perform fast peak detection (no interpolation) for initial gating */ - _amp = fastPeakDetect(corr, &_toa); - - /* Restrict peak-to-average calculations at the edges */ - if ((_toa < 3) || (_toa > len - 3)) - goto notfound; - - peak = corr.begin() + (int) rint(_toa); + /* Check for bogus results */ + if ((toa < 0.0) || (toa > corr->size())) + return 0.0; - /* Compute peak-to-average ratio. Reject if we don't have enough values */ for (int i = 2 * sps; i <= 5 * sps; i++) { - if (peak - i >= corr.begin()) { + if (peak - i >= corr->begin()) { avg += (peak - i)->norm2(); num++; } - if (peak + i < corr.end()) { + if (peak + i < corr->end()) { avg += (peak + i)->norm2(); num++; } } if (num < 2) - goto notfound; + return 0.0; rms = sqrtf(avg / (float) num) + 0.00001; - par = _amp.abs() / rms; - if (par < thresh) - goto notfound; - - /* Run the full peak detection to obtain when we have a burst */ - _amp = peakDetect(corr, &_toa, NULL); - - /* Subtract forward tail bits from delay */ - if (toa) - *toa = _toa - 8 * sps; - - /* Normalize our channel gain */ - if (amp) - *amp = _amp / gRACHSequence->gain; - - return 1; - -notfound: - if (amp) - *amp = 0.0f; - if (toa) - *toa = 0.0f; - return 0; + return (amp.abs()) / rms; } bool energyDetect(signalVector &rxBurst, @@ -1047,94 +1005,152 @@ bool energyDetect(signalVector &rxBurst, return (energy/windowLength > detectThreshold*detectThreshold); } -int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh, - int sps, complex *amp, float *toa, unsigned max_toa, - bool chan_req, signalVector **chan, float *chan_offset) +/* + * Detect a burst based on correlation and peak-to-average ratio. Perform + * fast peak detection (no interpolation) for initial gating. Interpolate + * the sub-sample peak after we have detected the burst. + */ +static int detectBurst(signalVector &burst, + signalVector &corr, CorrelationSequence *sync, + float thresh, int sps, complex *amp, float *toa, + int start, int len) { - int start, target, len, num = 0; - complex _amp, *peak; - float _toa, rms, par, avg = 0.0f; - signalVector corr, *sync, *_chan; + /* Correlate */ + if (!convolve(&burst, sync->sequence, &corr, + CUSTOM, start, len, sps, 0)) { + return -1; + } - if ((tsc < 0) || (tsc > 7) || ((sps != 1) && (sps != 2) && (sps != 4))) + /* Peak detection - place restrictions at correlation edges */ + *amp = fastPeakDetect(corr, toa); + + if ((*toa < 3 * sps) || (*toa > len - 3 * sps)) + return 0; + + /* Peak -to-average ratio */ + if (computePeakRatio(&corr, sps, *toa, *amp) < thresh) + return 0; + + /* Run the full peak detection when we have a burst */ + *amp = peakDetect(corr, toa, NULL); + + /* Normalize our channel gain */ + *amp = *amp / sync->gain; + + return 1; +} + +/* + * RACH burst detection + * + * Correlation window parameters: + * target: Tail bits + RACH length (reduced from 41 to a multiple of 4) + * head: Search 4 symbols before target + * tail: Search 8 symbols after target + */ +int detectRACHBurst(signalVector &rxBurst, + float thresh, + int sps, + complex *amp, + float *toa) +{ + int rc, start, target, head, tail, len; + float _toa; + complex _amp; + signalVector corr; + CorrelationSequence *sync; + + if ((sps != 1) && (sps != 2) && (sps != 4)) return -1; - target = 3 + 58 + 5 + 16; - start = (target - 8) * sps; - len = (8 + 8 + max_toa) * sps; + target = 8 + 40; + head = 4; + tail = 8; - sync = gMidambles[tsc]->sequence; - sync = gMidambles[tsc]->sequence; + start = (target - head) * sps - 1; + len = (head + tail) * sps; + sync = gRACHSequence; corr = signalVector(len); - if (!convolve(&rxBurst, sync, &corr, - CUSTOM, start, len, sps, 0)) { + rc = detectBurst(rxBurst, corr, sync, + thresh, sps, &_amp, &_toa, start, len); + if (rc < 0) { return -1; + } else if (!rc) { + if (amp) + *amp = 0.0f; + if (toa) + *toa = 0.0f; + return 0; } - _amp = peakDetect(corr, &_toa, NULL); - peak = corr.begin() + (int) rint(_toa); + /* Subtract forward search bits from delay */ + if (toa) + *toa = _toa - head * sps; + if (amp) + *amp = _amp; - /* Check for bogus results */ - if ((_toa < 0.0) || (_toa > corr.size())) - goto notfound; + return 1; +} - for (int i = 2 * sps; i <= 5 * sps; i++) { - if (peak - i >= corr.begin()) { - avg += (peak - i)->norm2(); - num++; - } - if (peak + i < corr.end()) { - avg += (peak + i)->norm2(); - num++; - } - } +/* + * Normal burst detection + * + * Correlation window parameters: + * target: Tail + data + mid-midamble + 1/2 remaining midamblebits + * head: Search 4 symbols before target + * tail: Search 6 symbols + maximum expected delay + */ +int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh, + int sps, complex *amp, float *toa, unsigned max_toa, + bool chan_req, signalVector **chan, float *chan_offset) +{ + int rc, start, target, head, tail, len; + complex _amp; + float _toa; + signalVector corr, *_chan; + CorrelationSequence *sync; - if (num < 2) - goto notfound; + if ((tsc < 0) || (tsc > 7) || ((sps != 1) && (sps != 2) && (sps != 4))) + return -1; - rms = sqrtf(avg / (float) num) + 0.00001; - par = (_amp.abs()) / rms; - if (par < thresh) - goto notfound; + target = 3 + 58 + 16 + 5; + head = 4; + tail = 6 + max_toa; - /* - * NOTE: Because ideal TSC is 66 symbols into burst, - * the ideal TSC has an +/- 180 degree phase shift, - * due to the pi/4 frequency shift, that - * needs to be accounted for. - */ - if (amp) - *amp = _amp / gMidambles[tsc]->gain; + start = (target - head) * sps - 1; + len = (head + tail) * sps; + sync = gMidambles[tsc]; + corr = signalVector(len); - /* Delay one half of peak-centred correlation length */ - _toa -= sps * 8; + rc = detectBurst(rxBurst, corr, sync, + thresh, sps, &_amp, &_toa, start, len); + if (rc < 0) { + return -1; + } else if (!rc) { + if (amp) + *amp = 0.0f; + if (toa) + *toa = 0.0f; + return 0; + } + /* Subtract forward search bits from delay */ + _toa -= head * sps; if (toa) *toa = _toa; + if (amp) + *amp = _amp; + /* Equalization not currently supported */ if (chan_req) { - _chan = new signalVector(6 * sps); - - delayVector(corr, -_toa); - corr.segmentCopyTo(*_chan, target - 3, _chan->size()); - scaleVector(*_chan, complex(1.0, 0.0) / gMidambles[tsc]->gain); - - *chan = _chan; + *chan = new signalVector(6 * sps); if (chan_offset) - *chan_offset = 3.0 * sps;; + *chan_offset = 0.0; } return 1; - -notfound: - if (amp) - *amp = 0.0f; - if (toa) - *toa = 0.0f; - - return 0; } signalVector *decimateVector(signalVector &wVector, -- cgit v1.2.3