aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--GSM/GSMCommon.cpp2
-rw-r--r--GSM/GSMCommon.h2
-rw-r--r--Transceiver52M/Transceiver.cpp25
-rw-r--r--Transceiver52M/Transceiver.h5
-rw-r--r--Transceiver52M/radioInterface.cpp4
-rw-r--r--Transceiver52M/radioInterface.h3
-rw-r--r--Transceiver52M/radioInterfaceDiversity.cpp2
-rw-r--r--Transceiver52M/radioInterfaceResamp.cpp2
-rw-r--r--Transceiver52M/sigProcLib.cpp134
-rw-r--r--Transceiver52M/sigProcLib.h7
10 files changed, 179 insertions, 7 deletions
diff --git a/GSM/GSMCommon.cpp b/GSM/GSMCommon.cpp
index 87f5ab2..e389e96 100644
--- a/GSM/GSMCommon.cpp
+++ b/GSM/GSMCommon.cpp
@@ -45,6 +45,8 @@ const BitVector GSM::gDummyBurst("0001111101101110110000010100100111000001001000
const BitVector GSM::gRACHSynchSequence("01001011011111111001100110101010001111000");
+const BitVector GSM::gSCHSynchSequence("1011100101100010000001000000111100101101010001010111011000011011");
+
int32_t GSM::FNDelta(int32_t v1, int32_t v2)
{
diff --git a/GSM/GSMCommon.h b/GSM/GSMCommon.h
index 80c5608..db315be 100644
--- a/GSM/GSMCommon.h
+++ b/GSM/GSMCommon.h
@@ -53,6 +53,8 @@ extern const BitVector gDummyBurst;
/** Random access burst synch. sequence */
extern const BitVector gRACHSynchSequence;
+/** Synchronization burst sync sequence */
+extern const BitVector gSCHSynchSequence;
/**@name Modulus operations for frame numbers. */
//@{
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index 415505c..af10a7a 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -376,6 +376,31 @@ bool Transceiver::detectRACH(TransceiverState *state,
return detectRACHBurst(burst, threshold, mSPSRx, &amp, &toa);
}
+/* Detect SCH synchronization sequence within a burst */
+bool Transceiver::detectSCH(TransceiverState *state,
+ signalVector &burst,
+ complex &amp, float &toa)
+{
+ int shift;
+ float mag, threshold = 7.0;
+
+ if (!detectSCHBurst(burst, threshold, mSPSRx, &amp, &toa))
+ return false;
+
+ std::cout << "SCH : Timing offset " << toa << " symbols" << std::endl;
+
+ mag = fabsf(toa);
+ if (mag < 1.0f)
+ return true;
+
+ shift = (int) (mag / 2.0f);
+ if (!shift)
+ shift++;
+
+ mRadioInterface->applyOffset(toa > 0 ? shift : -shift);
+ return false;
+}
+
/*
* Detect normal burst training sequence midamble. Update equalization
* state information and channel estimate if necessary. Equalization
diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h
index df029a6..8433406 100644
--- a/Transceiver52M/Transceiver.h
+++ b/Transceiver52M/Transceiver.h
@@ -116,6 +116,7 @@ private:
OFF, ///< timeslot is off
TSC, ///< timeslot should contain a normal burst
RACH, ///< timeslot should contain an access burst
+ SCH, ///< timeslot should contain a SCH burst
IDLE ///< timeslot is an idle (or dummy) burst
} CorrType;
@@ -147,6 +148,10 @@ private:
signalVector &burst,
complex &amp, float &toa);
+ bool detectSCH(TransceiverState *state,
+ signalVector &burst,
+ complex &amp, float &toa);
+
/** Detect normal bursts */
bool detectTSC(TransceiverState *state,
signalVector &burst,
diff --git a/Transceiver52M/radioInterface.cpp b/Transceiver52M/radioInterface.cpp
index 1329ef1..d55761a 100644
--- a/Transceiver52M/radioInterface.cpp
+++ b/Transceiver52M/radioInterface.cpp
@@ -38,7 +38,7 @@ RadioInterface::RadioInterface(RadioDevice *wRadio,
int wReceiveOffset, GSM::Time wStartTime)
: mRadio(wRadio), mSPSTx(sps), mSPSRx(1), mChans(chans), mMIMO(diversity),
sendCursor(0), recvCursor(0), underrun(false), overrun(false),
- receiveOffset(wReceiveOffset), mOn(false)
+ receiveOffset(wReceiveOffset), shiftOffset(0), mOn(false)
{
mClock.set(wStartTime);
}
@@ -330,7 +330,7 @@ void RadioInterface::pullBuffer()
num_recv = mRadio->readSamples(convertRecvBuffer,
CHUNK,
&overrun,
- readTimestamp,
+ readTimestamp + shiftOffset,
&local_underrun);
if (num_recv != CHUNK) {
LOG(ALERT) << "Receive error " << num_recv;
diff --git a/Transceiver52M/radioInterface.h b/Transceiver52M/radioInterface.h
index b88fe6b..36bc6ea 100644
--- a/Transceiver52M/radioInterface.h
+++ b/Transceiver52M/radioInterface.h
@@ -56,7 +56,7 @@ protected:
RadioClock mClock; ///< the basestation clock!
int receiveOffset; ///< offset b/w transmit and receive GSM timestamps, in timeslots
-
+ int shiftOffset;
bool mOn; ///< indicates radio is on
private:
@@ -94,6 +94,7 @@ public:
/** check for underrun, resets underrun value */
bool isUnderrun();
+ void applyOffset(int offset) { shiftOffset += offset; }
/** return the receive FIFO */
VectorFIFO* receiveFIFO(size_t chan = 0);
diff --git a/Transceiver52M/radioInterfaceDiversity.cpp b/Transceiver52M/radioInterfaceDiversity.cpp
index 8e921b1..b76a15f 100644
--- a/Transceiver52M/radioInterfaceDiversity.cpp
+++ b/Transceiver52M/radioInterfaceDiversity.cpp
@@ -189,7 +189,7 @@ void RadioInterfaceDiversity::pullBuffer()
num = mRadio->readSamples(convertRecvBuffer,
resamp_outchunk,
&overrun,
- readTimestamp,
+ readTimestamp + shiftOffset,
&local_underrun);
if ((size_t) num != resamp_outchunk) {
LOG(ALERT) << "Receive error " << num;
diff --git a/Transceiver52M/radioInterfaceResamp.cpp b/Transceiver52M/radioInterfaceResamp.cpp
index f898d65..c6e5ee1 100644
--- a/Transceiver52M/radioInterfaceResamp.cpp
+++ b/Transceiver52M/radioInterfaceResamp.cpp
@@ -188,7 +188,7 @@ void RadioInterfaceResamp::pullBuffer()
num_recv = mRadio->readSamples(convertRecvBuffer,
resamp_outchunk,
&overrun,
- readTimestamp,
+ readTimestamp + shiftOffset,
&local_underrun);
if (num_recv != (int) resamp_outchunk) {
LOG(ALERT) << "Receive error " << num_recv;
diff --git a/Transceiver52M/sigProcLib.cpp b/Transceiver52M/sigProcLib.cpp
index 54dd8fc..0db3a81 100644
--- a/Transceiver52M/sigProcLib.cpp
+++ b/Transceiver52M/sigProcLib.cpp
@@ -78,6 +78,7 @@ struct CorrelationSequence {
signalVector *sequence;
void *buffer;
+ void *history;
float toa;
complex gain;
};
@@ -111,6 +112,7 @@ struct PulseSequence {
CorrelationSequence *gMidambles[] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
CorrelationSequence *gRACHSequence = NULL;
+CorrelationSequence *gSCHSequence = NULL;
PulseSequence *GSMPulse = NULL;
PulseSequence *GSMPulse1 = NULL;
@@ -131,6 +133,7 @@ void sigProcLibDestroy()
delete GMSKRotation1;
delete GMSKReverseRotation1;
delete gRACHSequence;
+ delete gSCHSequence;
delete GSMPulse;
delete GSMPulse1;
@@ -139,6 +142,7 @@ void sigProcLibDestroy()
GMSKReverseRotationN = NULL;
GMSKReverseRotation1 = NULL;
gRACHSequence = NULL;
+ gSCHSequence = NULL;
GSMPulse = NULL;
GSMPulse1 = NULL;
}
@@ -395,8 +399,10 @@ signalVector *convolve(const signalVector *x,
break;
case CUSTOM:
if (start < h->size() - 1) {
- head = h->size() - start;
- append = true;
+ if (x->getStart() < h->size() - 1) {
+ head = h->size() - start;
+ append = true;
+ }
}
if (start + len > x->size()) {
tail = start + len - x->size();
@@ -1274,6 +1280,69 @@ release:
return status;
}
+bool generateSCHSequence(int sps)
+{
+ bool status = true;
+ float toa;
+ complex *data = NULL;
+ signalVector *autocorr = NULL;
+ signalVector *seq0 = NULL, *seq1 = NULL, *_seq1 = NULL;
+
+ delete gSCHSequence;
+
+ seq0 = modulateBurst(gSCHSynchSequence, 0, sps, false);
+ if (!seq0)
+ return false;
+
+ seq1 = modulateBurst(gSCHSynchSequence, 0, sps, true);
+ if (!seq1) {
+ status = false;
+ goto release;
+ }
+
+ conjugateVector(*seq1);
+
+ /* For SSE alignment, reallocate the midamble sequence on 16-byte boundary */
+ data = (complex *) convolve_h_alloc(seq1->size());
+ _seq1 = new signalVector(data, 0, seq1->size());
+ _seq1->setAligned(true);
+ memcpy(_seq1->begin(), seq1->begin(), seq1->size() * sizeof(complex));
+
+ autocorr = convolve(seq0, _seq1, autocorr, NO_DELAY);
+ if (!autocorr) {
+ status = false;
+ goto release;
+ }
+
+ gSCHSequence = new CorrelationSequence;
+ gSCHSequence->sequence = _seq1;
+ gSCHSequence->buffer = data;
+ gSCHSequence->gain = peakDetect(*autocorr, &toa, NULL);
+ gSCHSequence->history = new complex[_seq1->size()];
+
+ /* For 1 sps only
+ * (Half of correlation length - 1) + midpoint of pulse shaping filer
+ * 20.5 = (64 / 2 - 1) + 1.5
+ */
+ if (sps == 1)
+ gSCHSequence->toa = toa - 32.5;
+ else
+ gSCHSequence->toa = 0.0;
+
+release:
+ delete autocorr;
+ delete seq0;
+ delete seq1;
+
+ if (!status) {
+ delete _seq1;
+ free(data);
+ gSCHSequence = NULL;
+ }
+
+ return status;
+}
+
static float computePeakRatio(signalVector *corr,
int sps, float toa, complex amp)
{
@@ -1424,6 +1493,62 @@ int detectRACHBurst(signalVector &rxBurst,
return 1;
}
+int detectSCHBurst(signalVector &burst,
+ float thresh,
+ int sps,
+ complex *amp,
+ float *toa)
+{
+ int rc, start, target, head, tail, len;
+ float _toa;
+ complex _amp;
+ signalVector *corr, *_burst;
+ CorrelationSequence *sync;
+
+ if ((sps != 1) && (sps != 4))
+ return -1;
+
+ /* Search full length */
+ target = 3 + 39 + 64;
+ head = target - 1;
+ tail = 39 + 3 + 9;
+
+ start = (target - head) * sps - 1;
+ len = (head + tail) * sps;
+ sync = gSCHSequence;
+ corr = new signalVector(len);
+
+ _burst = new signalVector(burst, sync->sequence->size(), 5);
+
+ memcpy(_burst->begin() - sync->sequence->size(), sync->history,
+ sync->sequence->size() * sizeof(complex));
+
+ memcpy(sync->history, &burst.begin()[burst.size() - sync->sequence->size()],
+ sync->sequence->size() * sizeof(complex));
+
+ rc = detectBurst(*_burst, *corr, sync,
+ thresh, sps, &_amp, &_toa, start, len);
+ delete corr;
+
+ 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 */
+ if (toa)
+ *toa = _toa - head * sps;
+ if (amp)
+ *amp = _amp;
+
+ return 1;
+}
+
/*
* Normal burst detection
*
@@ -1717,6 +1842,11 @@ bool sigProcLibSetup(int sps)
return false;
}
+ if (!generateSCHSequence(1)) {
+ sigProcLibDestroy();
+ return false;
+ }
+
generateDelayFilters();
return true;
diff --git a/Transceiver52M/sigProcLib.h b/Transceiver52M/sigProcLib.h
index 147c14c..90b6852 100644
--- a/Transceiver52M/sigProcLib.h
+++ b/Transceiver52M/sigProcLib.h
@@ -158,6 +158,7 @@ bool generateMidamble(int sps, int tsc);
@return Success.
*/
bool generateRACHSequence(int sps);
+bool generateSCHSequence(int sps);
/**
Energy detector, checks to see if received burst energy is above a threshold.
@@ -187,6 +188,12 @@ int detectRACHBurst(signalVector &rxBurst,
complex *amplitude,
float* TOA);
+int detectSCHBurst(signalVector &rxBurst,
+ float detectThreshold,
+ int sps,
+ complex *amplitude,
+ float* TOA);
+
/**
Normal burst correlator, detector, channel estimator.
@param rxBurst The received GSM burst of interest.