diff options
author | Thomas Tsou <tom@tsou.cc> | 2013-10-17 21:23:34 -0400 |
---|---|---|
committer | Thomas Tsou <tom@tsou.cc> | 2013-10-18 13:10:18 -0400 |
commit | fa3a787ccbb250d929ebf78993047dd05e8765cb (patch) | |
tree | 4f14ca9fd9b87824ada664593cc24a70eadc1c54 /Transceiver52M/Transceiver.cpp | |
parent | 010fff783bf658e79b0b32ad64a44af4e3f22b1e (diff) |
Transceiver52M: Update noise measurement calculation
Previous removal of the energy detector requirement broke
the noise level calculation loop. The previous adaptive
approach was finicky - noticably at high gain levels. Since
we no longer use the energy threshold for primary burst gating,
we can return to a simpler world.
In the new approach, we compute a running average of energy
levels and track them with a noise vector. A timeslot that
passes the correlator threshold is a valid burst. These are
not used in the noise calculation. Everything else is
considered noise and used to compute the noise level with
respect to full scale input level, which for almost all
supported devices is 2^15.
Signed-off-by: Thomas Tsou <tom@tsou.cc>
Diffstat (limited to 'Transceiver52M/Transceiver.cpp')
-rw-r--r-- | Transceiver52M/Transceiver.cpp | 75 |
1 files changed, 22 insertions, 53 deletions
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp index 2557fec..bd7e7c6 100644 --- a/Transceiver52M/Transceiver.cpp +++ b/Transceiver52M/Transceiver.cpp @@ -46,7 +46,8 @@ using namespace GSM; # define USB_LATENCY_MIN 1,1 #endif -#define INIT_ENERGY_THRSHD 5.0f +/* Number of running values use in noise average */ +#define NOISE_CNT 20 Transceiver::Transceiver(int wBasePort, const char *TRXAddress, @@ -56,7 +57,7 @@ Transceiver::Transceiver(int wBasePort, :mDataSocket(wBasePort+2,TRXAddress,wBasePort+102), mControlSocket(wBasePort+1,TRXAddress,wBasePort+101), mClockSocket(wBasePort,TRXAddress,wBasePort+100), - mSPSTx(wSPS), mSPSRx(1) + mSPSTx(wSPS), mSPSRx(1), mNoises(NOISE_CNT) { GSM::Time startTime(random() % gHyperframe,0); @@ -80,9 +81,7 @@ Transceiver::Transceiver(int wBasePort, mTxFreq = 0.0; mRxFreq = 0.0; mPower = -10; - mEnergyThreshold = INIT_ENERGY_THRSHD; - prevFalseDetectionTime = startTime; - + mNoiseLev = 0.0; } Transceiver::~Transceiver() @@ -301,19 +300,20 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime) } } - + SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI, int &timingOffset) { bool needDFE = false; + bool success = false; + complex amplitude = 0.0; + float TOA = 0.0, avg = 0.0; radioVector *rxBurst = (radioVector *) mReceiveFIFO->get(); if (!rxBurst) return NULL; - LOG(DEBUG) << "receiveFIFO: read radio vector at time: " << rxBurst->getTime() << ", new size: " << mReceiveFIFO->size(); - int timeslot = rxBurst->getTime().TN(); CorrType corrType = expectedCorrType(rxBurst->getTime()); @@ -322,30 +322,15 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, delete rxBurst; return NULL; } - - // check to see if received burst has sufficient + signalVector *vectorBurst = rxBurst; - complex amplitude = 0.0; - float TOA = 0.0; - float avgPwr = 0.0; -#ifdef ENERGY_DETECT - if (!energyDetect(*vectorBurst, 20 * mSPSRx, mEnergyThreshold, &avgPwr)) { - LOG(DEBUG) << "Estimated Energy: " << sqrt(avgPwr) << ", at time " << rxBurst->getTime(); - double framesElapsed = rxBurst->getTime()-prevFalseDetectionTime; - if (framesElapsed > 50) { // if we haven't had any false detections for a while, lower threshold - mEnergyThreshold -= 10.0/10.0; - if (mEnergyThreshold < 0.0) - mEnergyThreshold = 0.0; - - prevFalseDetectionTime = rxBurst->getTime(); - } - delete rxBurst; - return NULL; - } - LOG(DEBUG) << "Estimated Energy: " << sqrt(avgPwr) << ", at time " << rxBurst->getTime(); -#endif + + energyDetect(*vectorBurst, 20 * mSPSRx, 0.0, &avg); + + // Update noise level + mNoiseLev = mNoises.avg(); + // run the proper correlator - bool success = false; if (corrType==TSC) { LOG(DEBUG) << "looking for TSC at time: " << rxBurst->getTime(); signalVector *channelResp; @@ -373,10 +358,7 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, &channelResp, &chanOffset); if (success) { - LOG(DEBUG) << "FOUND TSC!!!!!! " << amplitude << " " << TOA; - mEnergyThreshold -= 1.0F/10.0F; - if (mEnergyThreshold < 0.0) mEnergyThreshold = 0.0; - SNRestimate[timeslot] = amplitude.norm2()/(mEnergyThreshold*mEnergyThreshold+1.0); // this is not highly accurate + SNRestimate[timeslot] = amplitude.norm2()/(mNoiseLev*mNoiseLev+1.0); // this is not highly accurate if (estimateChannel) { LOG(DEBUG) << "estimating channel..."; channelResponse[timeslot] = channelResp; @@ -389,29 +371,17 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, } } else { - double framesElapsed = rxBurst->getTime()-prevFalseDetectionTime; - LOG(DEBUG) << "wTime: " << rxBurst->getTime() << ", pTime: " << prevFalseDetectionTime << ", fElapsed: " << framesElapsed; - mEnergyThreshold += 10.0F/10.0F*exp(-framesElapsed); - prevFalseDetectionTime = rxBurst->getTime(); channelResponse[timeslot] = NULL; + mNoises.insert(sqrt(avg)); } } else { // RACH burst - success = detectRACHBurst(*vectorBurst, 6.0, mSPSRx, &litude, &TOA); - if (success) { - LOG(DEBUG) << "FOUND RACH!!!!!! " << amplitude << " " << TOA; - mEnergyThreshold -= (1.0F/10.0F); - if (mEnergyThreshold < 0.0) mEnergyThreshold = 0.0; - channelResponse[timeslot] = NULL; - } - else { - double framesElapsed = rxBurst->getTime()-prevFalseDetectionTime; - mEnergyThreshold += (1.0F/10.0F)*exp(-framesElapsed); - prevFalseDetectionTime = rxBurst->getTime(); - } + if (success = detectRACHBurst(*vectorBurst, 6.0, mSPSRx, &litude, &TOA)) + channelResponse[timeslot] = NULL; + else + mNoises.insert(sqrt(avg)); } - LOG(DEBUG) << "energy Threshold = " << mEnergyThreshold; // demodulate burst SoftVector *burst = NULL; @@ -519,13 +489,12 @@ void Transceiver::driveControl() int newGain; sscanf(buffer,"%3s %s %d",cmdcheck,command,&newGain); newGain = mRadioInterface->setRxGain(newGain); - mEnergyThreshold = INIT_ENERGY_THRSHD; sprintf(response,"RSP SETRXGAIN 0 %d",newGain); } else if (strcmp(command,"NOISELEV")==0) { if (mOn) { sprintf(response,"RSP NOISELEV 0 %d", - (int) round(20.0*log10(rxFullScale/mEnergyThreshold))); + (int) round(20.0*log10(rxFullScale/mNoiseLev))); } else { sprintf(response,"RSP NOISELEV 1 0"); |