aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Tsou <tom@tsou.cc>2013-10-17 21:23:34 -0400
committerThomas Tsou <tom@tsou.cc>2013-10-18 13:10:18 -0400
commitfa3a787ccbb250d929ebf78993047dd05e8765cb (patch)
tree4f14ca9fd9b87824ada664593cc24a70eadc1c54
parent010fff783bf658e79b0b32ad64a44af4e3f22b1e (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>
-rw-r--r--Transceiver52M/Transceiver.cpp75
-rw-r--r--Transceiver52M/Transceiver.h4
-rw-r--r--Transceiver52M/radioVector.cpp29
-rw-r--r--Transceiver52M/radioVector.h10
4 files changed, 63 insertions, 55 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, &amplitude, &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, &amplitude, &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");
diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h
index d243214..c0ada1d 100644
--- a/Transceiver52M/Transceiver.h
+++ b/Transceiver52M/Transceiver.h
@@ -97,6 +97,8 @@ private:
LOOPBACK ///< similar go VII, used in loopback testing
} ChannelCombination;
+ float mNoiseLev; ///< Average noise level
+ noiseVector mNoises; ///< Vector holding running noise measurements
/** unmodulate a modulated burst */
#ifdef TRANSMIT_LOGGING
@@ -134,8 +136,6 @@ private:
double mRxFreq; ///< the receive frequency
int mPower; ///< the transmit power in dB
unsigned mTSC; ///< the midamble sequence code
- double mEnergyThreshold; ///< threshold to determine if received data is potentially a GSM burst
- GSM::Time prevFalseDetectionTime; ///< last timestamp of a false energy detection
int fillerModulus[8]; ///< modulus values of all timeslots, in frames
signalVector *fillerTable[102][8]; ///< table of modulated filler waveforms for all timeslots
unsigned mMaxExpectedDelay; ///< maximum expected time-of-arrival offset in GSM symbols
diff --git a/Transceiver52M/radioVector.cpp b/Transceiver52M/radioVector.cpp
index f20d97a..043effa 100644
--- a/Transceiver52M/radioVector.cpp
+++ b/Transceiver52M/radioVector.cpp
@@ -41,6 +41,35 @@ bool radioVector::operator>(const radioVector& other) const
return mTime > other.mTime;
}
+noiseVector::noiseVector(size_t n)
+{
+ this->resize(n);
+ it = this->begin();
+}
+
+float noiseVector::avg()
+{
+ float val = 0.0;
+
+ for (int i = 0; i < size(); i++)
+ val += (*this)[i];
+
+ return val / (float) size();
+}
+
+bool noiseVector::insert(float val)
+{
+ if (!size())
+ return false;
+
+ if (it == this->end())
+ it = this->begin();
+
+ *it++ = val;
+
+ return true;
+}
+
unsigned VectorFIFO::size()
{
return mQ.size();
diff --git a/Transceiver52M/radioVector.h b/Transceiver52M/radioVector.h
index 8de4493..8dc1c13 100644
--- a/Transceiver52M/radioVector.h
+++ b/Transceiver52M/radioVector.h
@@ -37,6 +37,16 @@ private:
GSM::Time mTime;
};
+class noiseVector : std::vector<float> {
+public:
+ noiseVector(size_t len = 0);
+ bool insert(float val);
+ float avg();
+
+private:
+ std::vector<float>::iterator it;
+};
+
class VectorFIFO {
public:
unsigned size();