diff options
Diffstat (limited to 'Transceiver52M/radioInterfaceMulti.cpp')
-rw-r--r-- | Transceiver52M/radioInterfaceMulti.cpp | 136 |
1 files changed, 90 insertions, 46 deletions
diff --git a/Transceiver52M/radioInterfaceMulti.cpp b/Transceiver52M/radioInterfaceMulti.cpp index 0208e82..a7195b4 100644 --- a/Transceiver52M/radioInterfaceMulti.cpp +++ b/Transceiver52M/radioInterfaceMulti.cpp @@ -38,13 +38,15 @@ extern "C" { /* Universal resampling parameters */ #define NUMCHUNKS 24 +/* number of narrow-band virtual ARFCNs in this wide-band multi-ARFCN device */ #define MCHANS 4 RadioInterfaceMulti::RadioInterfaceMulti(RadioDevice *radio, size_t tx_sps, size_t rx_sps, size_t chans) : RadioInterface(radio, tx_sps, rx_sps, chans), - outerSendBuffer(NULL), outerRecvBuffer(NULL), - dnsampler(NULL), upsampler(NULL), channelizer(NULL), synthesis(NULL) + outerSendBuffer(NULL), outerRecvBuffer(NULL), history(mChans), active(MCHANS, false), + rx_freq_state(mChans), tx_freq_state(mChans), dnsampler(NULL), upsampler(NULL), channelizer(NULL), + synthesis(NULL) { } @@ -69,14 +71,24 @@ void RadioInterfaceMulti::close() channelizer = NULL; synthesis = NULL; - mReceiveFIFO.resize(0); - powerScaling.resize(0); - history.resize(0); - active.resize(0); + + for (std::vector<signalVector*>::iterator it = history.begin(); it != history.end(); ++it) + delete *it; + + mReceiveFIFO.clear(); + powerScaling.clear(); + history.clear(); + active.clear(); + rx_freq_state.clear(); + tx_freq_state.clear(); RadioInterface::close(); } +/*! we re-map the physical channels from the filter bank to logical per-TRX channels + * \param[in] pchan physical channel number within the channelizer + * \param[in] chans total number of narrow-band ARFCN channels + * \returns logical (TRX) channel number, or -1 in case there is none */ static int getLogicalChan(size_t pchan, size_t chans) { switch (chans) { @@ -111,6 +123,9 @@ static int getLogicalChan(size_t pchan, size_t chans) return -1; } +/*! do we need to frequency shift our spectrum or not? + * \param chans total number of channels + * \returns 1 if we need to shift; 0 if not; -1 on error */ static int getFreqShift(size_t chans) { switch (chans) { @@ -138,18 +153,10 @@ bool RadioInterfaceMulti::init(int type) return false; } - close(); - - sendBuffer.resize(mChans); - recvBuffer.resize(mChans); convertSendBuffer.resize(1); convertRecvBuffer.resize(1); - mReceiveFIFO.resize(mChans); - powerScaling.resize(mChans); - history.resize(mChans); - active.resize(MCHANS, false); - + /* 4 == sps */ inchunk = RESAMP_INRATE * 4; outchunk = RESAMP_OUTRATE * 4; @@ -238,7 +245,7 @@ int RadioInterfaceMulti::pullBuffer() return -1; /* Outer buffer access size is fixed */ - num = mRadio->readSamples(convertRecvBuffer, + num = mDevice->readSamples(convertRecvBuffer, outerRecvBuffer->size(), &overrun, readTimestamp, @@ -251,7 +258,7 @@ int RadioInterfaceMulti::pullBuffer() convert_short_float((float *) outerRecvBuffer->begin(), convertRecvBuffer[0], 2 * outerRecvBuffer->size()); - underrun |= local_underrun; + osmo_trx_sync_or_and_fetch(&underrun, local_underrun); readTimestamp += num; channelizer->rotate((float *) outerRecvBuffer->begin(), @@ -288,7 +295,7 @@ int RadioInterfaceMulti::pullBuffer() complex *dst = history[lchan]->begin(); float *fsrc = &buf[2 * (cLen - hLen)]; for (i = 0; i < hLen; i++) { - *dst = complex(fdst[0], fdst[1]); + *dst = complex(fsrc[0], fsrc[1]); fsrc += 2; dst++; } @@ -309,6 +316,7 @@ int RadioInterfaceMulti::pullBuffer() /* Send a timestamped chunk to the device */ bool RadioInterfaceMulti::pushBuffer() { + bool local_underrun; if (sendBuffer[0]->getAvailSegments() <= 0) return false; @@ -339,14 +347,15 @@ bool RadioInterfaceMulti::pushBuffer() (float *) outerSendBuffer->begin(), 1.0 / (float) mChans, 2 * outerSendBuffer->size()); - size_t num = mRadio->writeSamples(convertSendBuffer, + size_t num = mDevice->writeSamples(convertSendBuffer, outerSendBuffer->size(), - &underrun, + &local_underrun, writeTimestamp); if (num != outerSendBuffer->size()) { LOG(ALERT) << "Transmit error " << num; } + osmo_trx_sync_or_and_fetch(&underrun, local_underrun); writeTimestamp += num; return true; @@ -360,48 +369,83 @@ static bool fltcmp(double a, double b) return fabs(a - b) < FREQ_DELTA_LIMIT ? true : false; } +bool RadioInterfaceMulti::verify_arfcn_consistency(double freq, size_t chan, bool tx) +{ + double freq_i; + std::string str_dir = tx ? "Tx" : "Rx"; + std::vector<struct freq_cfg_state> &v = tx ? tx_freq_state : rx_freq_state; + + for (size_t i = 0; i < mChans; i++) { + if (i == chan) + continue; + if (!v[i].set) + continue; + + freq_i = v[i].freq_hz + (double) ((int)chan - (int)i) * MCBTS_SPACING; + if (!fltcmp(freq, freq_i)) { + LOGCHAN(chan, DMAIN, ERROR) + << "Setting " << str_dir << " frequency " << freq + << " is incompatible: already configured channel " + << i << " uses frequency " << v[i].freq_hz + << " (expected " << freq_i << ")"; + return false; + } + } + v[chan].set = true; + v[chan].freq_hz = freq; + return true; +} + bool RadioInterfaceMulti::tuneTx(double freq, size_t chan) { - if (chan >= mChans) - return false; + double shift; - double shift = (double) getFreqShift(mChans); + if (chan >= mChans) + return false; - if (!chan) - return mRadio->setTxFreq(freq + shift * MCBTS_SPACING); + if (!verify_arfcn_consistency(freq, chan, true)) + return false; - double center = mRadio->getTxFreq(); - if (!fltcmp(freq, center + (double) (chan - shift) * MCBTS_SPACING)) { - LOG(NOTICE) << "Channel " << chan << " RF frequency offset is " - << freq / 1e6 << " MHz"; - } + if (chan == 0) { + shift = (double) getFreqShift(mChans); + return mDevice->setTxFreq(freq + shift * MCBTS_SPACING); + } - return true; + return true; } bool RadioInterfaceMulti::tuneRx(double freq, size_t chan) { - if (chan >= mChans) - return false; + double shift; - double shift = (double) getFreqShift(mChans); + if (chan >= mChans) + return false; - if (!chan) - return mRadio->setRxFreq(freq + shift * MCBTS_SPACING); + if (!verify_arfcn_consistency(freq, chan, false)) + return false; - double center = mRadio->getRxFreq(); - if (!fltcmp(freq, center + (double) (chan - shift) * MCBTS_SPACING)) { - LOG(NOTICE) << "Channel " << chan << " RF frequency offset is " - << freq / 1e6 << " MHz"; - } + if (chan == 0) { + shift = (double) getFreqShift(mChans); + return mDevice->setRxFreq(freq + shift * MCBTS_SPACING); + } - return true; + return true; } double RadioInterfaceMulti::setRxGain(double db, size_t chan) { - if (!chan) - return mRadio->setRxGain(db); - else - return mRadio->getRxGain(); + if (chan == 0) + return mDevice->setRxGain(db); + else + return mDevice->getRxGain(); +} + +double RadioInterfaceMulti::rssiOffset(size_t chan) +{ + return mDevice->rssiOffset(0); +} + +int RadioInterfaceMulti::setPowerAttenuation(int atten, size_t chan) +{ + return RadioInterface::setPowerAttenuation(atten, 0); } |