Transceiver52M: Use independent noise vectors for each channel
Each ARFCN channel may be independently configureted and possibly on separate hardware, so don't share a single vector for noise estimate calculations. Allow a non-pointer based iterator so we can get away with using the default copy constructor. Signed-off-by: Thomas Tsou <tom@tsou.cc>
This commit is contained in:
parent
ef25dba4e7
commit
a0179e37f8
|
@ -43,6 +43,7 @@ using namespace GSM;
|
|||
#define NOISE_CNT 20
|
||||
|
||||
TransceiverState::TransceiverState()
|
||||
: mNoiseLev(0.0), mNoises(NOISE_CNT)
|
||||
{
|
||||
for (int i = 0; i < 8; i++) {
|
||||
chanType[i] = Transceiver::NONE;
|
||||
|
@ -80,8 +81,8 @@ Transceiver::Transceiver(int wBasePort,
|
|||
GSM::Time wTransmitLatency,
|
||||
RadioInterface *wRadioInterface)
|
||||
: mBasePort(wBasePort), mAddr(TRXAddress),
|
||||
mTransmitLatency(wTransmitLatency), mClockSocket(NULL), mRadioInterface(wRadioInterface),
|
||||
mNoiseLev(0.0), mNoises(NOISE_CNT), mSPSTx(wSPS), mSPSRx(1), mChans(wChans),
|
||||
mTransmitLatency(wTransmitLatency), mClockSocket(NULL),
|
||||
mRadioInterface(wRadioInterface), mSPSTx(wSPS), mSPSRx(1), mChans(wChans),
|
||||
mOn(false), mTxFreq(0.0), mRxFreq(0.0), mPower(-10), mMaxExpectedDelay(0)
|
||||
{
|
||||
GSM::Time startTime(random() % gHyperframe,0);
|
||||
|
@ -351,13 +352,12 @@ bool Transceiver::detectRACH(TransceiverState *state,
|
|||
* state information and channel estimate if necessary. Equalization
|
||||
* is currently disabled.
|
||||
*/
|
||||
bool Transceiver::detectTSC(TransceiverState *state,
|
||||
signalVector &burst,
|
||||
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;
|
||||
bool noise, needDFE = false, estimateChan = false;
|
||||
double elapsed = time - state->chanEstimateTime[tn];
|
||||
signalVector *chanResp;
|
||||
|
||||
|
@ -378,7 +378,8 @@ bool Transceiver::detectTSC(TransceiverState *state,
|
|||
return false;
|
||||
}
|
||||
|
||||
state->SNRestimate[tn] = amp.norm2() / (mNoiseLev * mNoiseLev + 1.0);
|
||||
noise = state->mNoiseLev;
|
||||
state->SNRestimate[tn] = amp.norm2() / (noise * noise + 1.0);
|
||||
|
||||
/* Set equalizer if unabled */
|
||||
if (needDFE && estimateChan) {
|
||||
|
@ -430,6 +431,7 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
|
|||
int max_i = -1;
|
||||
signalVector *burst;
|
||||
SoftVector *bits = NULL;
|
||||
TransceiverState *state = &mStates[chan];
|
||||
|
||||
/* Blocking FIFO read */
|
||||
radioVector *radio_burst = mReceiveFIFO[chan]->read();
|
||||
|
@ -464,16 +466,16 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
|
|||
/* Average noise on diversity paths and update global levels */
|
||||
burst = radio_burst->getVector(max_i);
|
||||
avg = sqrt(avg / radio_burst->chans());
|
||||
mNoiseLev = mNoises.avg();
|
||||
state->mNoiseLev = state->mNoises.avg();
|
||||
|
||||
/* Detect normal or RACH bursts */
|
||||
if (type == TSC)
|
||||
success = detectTSC(&mStates[chan], *burst, amp, toa, time);
|
||||
success = detectTSC(state, *burst, amp, toa, time);
|
||||
else
|
||||
success = detectRACH(&mStates[chan], *burst, amp, toa);
|
||||
success = detectRACH(state, *burst, amp, toa);
|
||||
|
||||
if (!success) {
|
||||
mNoises.insert(avg);
|
||||
state->mNoises.insert(avg);
|
||||
delete radio_burst;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -482,8 +484,8 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
|
|||
if (equalize && (type != TSC))
|
||||
equalize = false;
|
||||
|
||||
if (avg - mNoiseLev > 0.0)
|
||||
bits = demodulate(&mStates[chan], *burst, amp, toa, time.TN(), equalize);
|
||||
if (avg - state->mNoiseLev > 0.0)
|
||||
bits = demodulate(state, *burst, amp, toa, time.TN(), equalize);
|
||||
|
||||
wTime = time;
|
||||
RSSI = (int) floor(20.0 * log10(rxFullScale / avg));
|
||||
|
@ -594,8 +596,9 @@ void Transceiver::driveControl(size_t chan)
|
|||
}
|
||||
else if (strcmp(command,"NOISELEV")==0) {
|
||||
if (mOn) {
|
||||
float lev = mStates[chan].mNoiseLev;
|
||||
sprintf(response,"RSP NOISELEV 0 %d",
|
||||
(int) round(20.0*log10(rxFullScale/mNoiseLev)));
|
||||
(int) round(20.0 * log10(rxFullScale / lev)));
|
||||
}
|
||||
else {
|
||||
sprintf(response,"RSP NOISELEV 1 0");
|
||||
|
|
|
@ -76,6 +76,10 @@ struct TransceiverState {
|
|||
float SNRestimate[8];
|
||||
float chanRespOffset[8];
|
||||
complex chanRespAmplitude[8];
|
||||
|
||||
/* Received noise energy levels */
|
||||
float mNoiseLev;
|
||||
noiseVector mNoises;
|
||||
};
|
||||
|
||||
/** The Transceiver class, responsible for physical layer of basestation */
|
||||
|
@ -114,9 +118,6 @@ private:
|
|||
IDLE ///< timeslot is an idle (or dummy) burst
|
||||
} CorrType;
|
||||
|
||||
float mNoiseLev; ///< Average noise level
|
||||
noiseVector mNoises; ///< Vector holding running noise measurements
|
||||
|
||||
/** modulate and add a burst to the transmit queue */
|
||||
void addRadioVector(size_t chan, BitVector &bits,
|
||||
int RSSI, GSM::Time &wTime);
|
||||
|
|
|
@ -74,10 +74,9 @@ bool radioVector::setVector(signalVector *vector, size_t chan)
|
|||
return true;
|
||||
}
|
||||
|
||||
noiseVector::noiseVector(size_t n)
|
||||
noiseVector::noiseVector(size_t size)
|
||||
: std::vector<float>(size), itr(0)
|
||||
{
|
||||
this->resize(n);
|
||||
it = this->begin();
|
||||
}
|
||||
|
||||
float noiseVector::avg()
|
||||
|
@ -95,10 +94,10 @@ bool noiseVector::insert(float val)
|
|||
if (!size())
|
||||
return false;
|
||||
|
||||
if (it == this->end())
|
||||
it = this->begin();
|
||||
if (itr >= this->size())
|
||||
itr = 0;
|
||||
|
||||
*it++ = val;
|
||||
(*this)[itr++] = val;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -48,12 +48,12 @@ private:
|
|||
|
||||
class noiseVector : std::vector<float> {
|
||||
public:
|
||||
noiseVector(size_t len = 0);
|
||||
noiseVector(size_t size = 0);
|
||||
bool insert(float val);
|
||||
float avg();
|
||||
|
||||
private:
|
||||
std::vector<float>::iterator it;
|
||||
size_t itr;
|
||||
};
|
||||
|
||||
class VectorFIFO : public InterthreadQueue<radioVector> { };
|
||||
|
|
Loading…
Reference in New Issue