From 30421a7e252889efbd1941d5220d06cbf7161160 Mon Sep 17 00:00:00 2001 From: Thomas Tsou Date: Wed, 13 Nov 2013 23:14:48 -0500 Subject: 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 --- Transceiver52M/Transceiver.cpp | 220 +++++++++++++++++++++++------------------ Transceiver52M/Transceiver.h | 16 +++ 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 &, 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, &, &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 &, 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, &, + &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, - &, - &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, &, &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 &, float &toa); + + /** Detect normal bursts */ + bool detectTSC(TransceiverState *state, + signalVector &burst, + complex &, 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; -- cgit v1.2.3