aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Tsou <tom@tsou.cc>2013-11-13 23:14:48 -0500
committerThomas Tsou <tom@tsou.cc>2013-11-15 23:35:07 -0500
commit30421a7e252889efbd1941d5220d06cbf7161160 (patch)
treea263fdcd2844c5e1910804b56d47241c77b0a938
parent34bbef754f6c053871ed1e2345c93d2586ce4616 (diff)
Transceiver52M: Refactor receive path outer burst handling
Separate the large pullRadioVector() call, which forms the central portion of the receive path burst processing. Break out RACH, normal burst, and demodulation into separate methods. This makes the burst handling from the FIFO read to soft bit output somewhat more manageable. Signed-off-by: Thomas Tsou <tom@tsou.cc>
-rw-r--r--Transceiver52M/Transceiver.cpp220
-rw-r--r--Transceiver52M/Transceiver.h16
2 files changed, 141 insertions, 95 deletions
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index caf2452..01fec5b 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -328,117 +328,147 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
}
}
-SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
- int &timingOffset, size_t chan)
+/*
+ * Detect RACH synchronization sequence within a burst. No equalization
+ * is used or available on the RACH channel.
+ */
+bool Transceiver::detectRACH(TransceiverState *state,
+ signalVector &burst,
+ complex &amp, float &toa)
{
- bool needDFE = false;
- bool success = false;
- complex amp = 0.0;
- float TOA = 0.0, avg = 0.0;
- TransceiverState *state = &mStates[chan];
+ float threshold = 6.0;
- radioVector *rxBurst = (radioVector *) mReceiveFIFO[chan]->read();
+ return detectRACHBurst(burst, threshold, mSPSRx, &amp, &toa);
+}
- if (!rxBurst) return NULL;
+/*
+ * Detect normal burst training sequence midamble. Update equalization
+ * state information and channel estimate if necessary. Equalization
+ * is currently disabled.
+ */
+bool Transceiver::detectTSC(TransceiverState *state,
+ signalVector &burst,
+ complex &amp, float &toa, GSM::Time &time)
+{
+ int tn = time.TN();
+ float chanOffset, threshold = 5.0;
+ bool needDFE = false, estimateChan = false;
+ double elapsed = time - state->chanEstimateTime[tn];
+ signalVector *chanResp;
+
+ /* Check equalization update state */
+ if ((elapsed > 50) || (!state->chanResponse[tn])) {
+ delete state->DFEForward[tn];
+ delete state->DFEFeedback[tn];
+ state->DFEForward[tn] = NULL;
+ state->DFEFeedback[tn] = NULL;
+
+ estimateChan = true;
+ }
+
+ /* Detect normal burst midambles */
+ if (!analyzeTrafficBurst(burst, mTSC, threshold, mSPSRx, &amp,
+ &toa, mMaxExpectedDelay, estimateChan,
+ &chanResp, &chanOffset)) {
+ return false;
+ }
- int timeslot = rxBurst->getTime().TN();
+ state->SNRestimate[tn] = amp.norm2() / (mNoiseLev * mNoiseLev + 1.0);
- CorrType corrType = expectedCorrType(rxBurst->getTime(), chan);
+ /* Set equalizer if unabled */
+ if (needDFE && estimateChan) {
+ state->chanResponse[tn] = chanResp;
+ state->chanRespOffset[tn] = chanOffset;
+ state->chanRespAmplitude[tn] = amp;
- if ((corrType==OFF) || (corrType==IDLE)) {
- delete rxBurst;
- return NULL;
+ scaleVector(*chanResp, complex(1.0, 0.0) / amp);
+
+ designDFE(*chanResp, state->SNRestimate[tn],
+ 7, &state->DFEForward[tn], &state->DFEFeedback[tn]);
+
+ state->chanEstimateTime[tn] = time;
}
- signalVector *vectorBurst = rxBurst->getVector();
+ return true;;
+}
- energyDetect(*vectorBurst, 20 * mSPSRx, 0.0, &avg);
+/*
+ * Demodulate GMSK burst using equalization if requested. Otherwise
+ * demodulate by direct rotation and soft slicing.
+ */
+SoftVector *Transceiver::demodulate(TransceiverState *state,
+ signalVector &burst, complex amp,
+ float toa, size_t tn, bool equalize)
+{
+ if (equalize) {
+ scaleVector(burst, complex(1.0, 0.0) / amp);
+ return equalizeBurst(burst,
+ toa - state->chanRespOffset[tn],
+ mSPSRx,
+ *state->DFEForward[tn],
+ *state->DFEFeedback[tn]);
+ }
- // Update noise level
+ return demodulateBurst(burst, mSPSRx, amp, toa);
+}
+
+/*
+ * Pull bursts from the FIFO and handle according to the slot
+ * and burst correlation type. Equalzation is currently disabled.
+ */
+SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
+ int &timingOffset, size_t chan)
+{
+ bool success, equalize = false;
+ complex amp;
+ float toa, pow, max = -1.0, avg = 0.0;
+ signalVector *burst;
+ SoftVector *bits;
+
+ /* Blocking FIFO read */
+ radioVector *radio_burst = mReceiveFIFO[chan]->read();
+ if (!radio_burst)
+ return NULL;
+
+ /* Set time and determine correlation type */
+ GSM::Time time = radio_burst->getTime();
+ CorrType type = expectedCorrType(time, chan);
+
+ if ((type == OFF) || (type == IDLE)) {
+ delete radio_burst;
+ return NULL;
+ }
+
+ /* Average noise on diversity paths and update global levels */
+ burst = radio_burst->getVector();
+ avg = avg / radio_burst->chans();
mNoiseLev = mNoises.avg();
avg = sqrt(avg);
- // run the proper correlator
- if (corrType==TSC) {
- LOG(DEBUG) << "looking for TSC at time: " << rxBurst->getTime();
- signalVector *channelResp;
- double framesElapsed = rxBurst->getTime() - state->chanEstimateTime[timeslot];
- bool estimateChannel = false;
- if ((framesElapsed > 50) || (state->chanResponse[timeslot]==NULL)) {
- if (state->chanResponse[timeslot])
- delete state->chanResponse[timeslot];
- if (state->DFEForward[timeslot])
- delete state->DFEForward[timeslot];
- if (state->DFEFeedback[timeslot])
- delete state->DFEFeedback[timeslot];
-
- state->chanResponse[timeslot] = NULL;
- state->DFEForward[timeslot] = NULL;
- state->DFEFeedback[timeslot] = NULL;
- estimateChannel = true;
- }
- if (!needDFE) estimateChannel = false;
- float chanOffset;
- success = analyzeTrafficBurst(*vectorBurst,
- mTSC,
- 5.0,
- mSPSRx,
- &amp,
- &TOA,
- mMaxExpectedDelay,
- estimateChannel,
- &channelResp,
- &chanOffset);
- if (success) {
- state->SNRestimate[timeslot] = amp.norm2() / (mNoiseLev * mNoiseLev + 1.0);
-
- if (estimateChannel) {
- state->chanResponse[timeslot] = channelResp;
- state->chanRespOffset[timeslot] = chanOffset;
- state->chanRespAmplitude[timeslot] = amp;
- scaleVector(*channelResp, complex(1.0, 0.0) / amp);
- designDFE(*channelResp, state->SNRestimate[timeslot],
- 7, &state->DFEForward[timeslot],
- &state->DFEFeedback[timeslot]);
-
- state->chanEstimateTime[timeslot] = rxBurst->getTime();
- }
- }
- else {
- state->chanResponse[timeslot] = NULL;
- mNoises.insert(avg);
- }
- }
- else {
- // RACH burst
- if ((success = detectRACHBurst(*vectorBurst, 6.0, mSPSRx, &amp, &TOA)))
- state->chanResponse[timeslot] = NULL;
- else
- mNoises.insert(avg);
- }
-
- // demodulate burst
- SoftVector *burst = NULL;
- if ((rxBurst) && (success)) {
- if ((corrType==RACH) || (!needDFE)) {
- burst = demodulateBurst(*vectorBurst, mSPSRx, amp, TOA);
- } else {
- scaleVector(*vectorBurst, complex(1.0, 0.0) / amp);
- burst = equalizeBurst(*vectorBurst,
- TOA - state->chanRespOffset[timeslot],
- mSPSRx,
- *state->DFEForward[timeslot],
- *state->DFEFeedback[timeslot]);
- }
- wTime = rxBurst->getTime();
- RSSI = (int) floor(20.0*log10(rxFullScale/avg));
- LOG(DEBUG) << "RSSI: " << RSSI;
- timingOffset = (int) round(TOA * 256.0 / mSPSRx);
+ /* Detect normal or RACH bursts */
+ if (type == TSC)
+ success = detectTSC(&mStates[chan], *burst, amp, toa, time);
+ else
+ success = detectRACH(&mStates[chan], *burst, amp, toa);
+
+ if (!success) {
+ mNoises.insert(avg);
+ delete radio_burst;
+ return NULL;
}
- delete rxBurst;
+ /* Demodulate and set output info */
+ if (equalize && (type != TSC))
+ equalize = false;
+
+ bits = demodulate(&mStates[chan], *burst, amp, toa, time.TN(), equalize);
+ wTime = time;
+ RSSI = (int) floor(20.0 * log10(rxFullScale / avg));
+ timingOffset = (int) round(toa * 256.0 / mSPSRx);
+
+ delete radio_burst;
- return burst;
+ return bits;
}
void Transceiver::start()
diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h
index 671603e..30b2fd3 100644
--- a/Transceiver52M/Transceiver.h
+++ b/Transceiver52M/Transceiver.h
@@ -137,6 +137,22 @@ private:
/** send messages over the clock socket */
void writeClockInterface(void);
+ /** Detect RACH bursts */
+ bool detectRACH(TransceiverState *state,
+ signalVector &burst,
+ complex &amp, float &toa);
+
+ /** Detect normal bursts */
+ bool detectTSC(TransceiverState *state,
+ signalVector &burst,
+ complex &amp, float &toa, GSM::Time &time);
+
+ /** Demodulat burst and output soft bits */
+ SoftVector *demodulate(TransceiverState *state,
+ signalVector &burst, complex amp,
+ float toa, size_t tn, bool equalize);
+
+
int mSPSTx; ///< number of samples per Tx symbol
int mSPSRx; ///< number of samples per Rx symbol
size_t mChans;