aboutsummaryrefslogtreecommitdiffstats
path: root/Transceiver52M/radioInterfaceMulti.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Transceiver52M/radioInterfaceMulti.cpp')
-rw-r--r--Transceiver52M/radioInterfaceMulti.cpp136
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);
}