aboutsummaryrefslogtreecommitdiffstats
path: root/Transceiver52M/radioInterface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Transceiver52M/radioInterface.cpp')
-rw-r--r--Transceiver52M/radioInterface.cpp202
1 files changed, 75 insertions, 127 deletions
diff --git a/Transceiver52M/radioInterface.cpp b/Transceiver52M/radioInterface.cpp
index b719c94..052b439 100644
--- a/Transceiver52M/radioInterface.cpp
+++ b/Transceiver52M/radioInterface.cpp
@@ -1,26 +1,23 @@
/*
-* Copyright 2008, 2009 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Affero Public License.
-* See the COPYING file in the main directory for details.
-*
-* This use of this software may be subject to additional restrictions.
-* See the LEGAL file in the main directory for details.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-*/
+ * Radio device interface
+ *
+ * Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ * Copyright (C) 2015 Ettus Research LLC
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * See the COPYING file in the main directory for details.
+ */
#include "radioInterface.h"
#include "Resampler.h"
@@ -37,8 +34,8 @@ RadioInterface::RadioInterface(RadioDevice *wRadio, size_t tx_sps,
size_t rx_sps, size_t chans, size_t diversity,
int wReceiveOffset, GSM::Time wStartTime)
: mRadio(wRadio), mSPSTx(tx_sps), mSPSRx(rx_sps), mChans(chans),
- mMIMO(diversity), sendCursor(0), recvCursor(0), underrun(false),
- overrun(false), receiveOffset(wReceiveOffset), mOn(false)
+ mMIMO(diversity), underrun(false), overrun(false),
+ receiveOffset(wReceiveOffset), mOn(false)
{
mClock.set(wStartTime);
}
@@ -65,35 +62,20 @@ bool RadioInterface::init(int type)
powerScaling.resize(mChans);
for (size_t i = 0; i < mChans; i++) {
- sendBuffer[i] = new signalVector(CHUNK * mSPSTx);
- recvBuffer[i] = new signalVector(NUMCHUNKS * CHUNK * mSPSRx);
+ sendBuffer[i] = new RadioBuffer(NUMCHUNKS, CHUNK * mSPSTx, 0, true);
+ recvBuffer[i] = new RadioBuffer(NUMCHUNKS, CHUNK * mSPSRx, 0, false);
- convertSendBuffer[i] = new short[sendBuffer[i]->size() * 2];
- convertRecvBuffer[i] = new short[recvBuffer[i]->size() * 2];
+ convertSendBuffer[i] = new short[CHUNK * mSPSTx * 2];
+ convertRecvBuffer[i] = new short[CHUNK * mSPSRx * 2];
powerScaling[i] = 1.0;
}
- sendCursor = 0;
- recvCursor = 0;
-
return true;
}
void RadioInterface::close()
{
- for (size_t i = 0; i < sendBuffer.size(); i++)
- delete sendBuffer[i];
-
- for (size_t i = 0; i < recvBuffer.size(); i++)
- delete recvBuffer[i];
-
- for (size_t i = 0; i < convertSendBuffer.size(); i++)
- delete convertSendBuffer[i];
-
- for (size_t i = 0; i < convertRecvBuffer.size(); i++)
- delete convertRecvBuffer[i];
-
sendBuffer.resize(0);
recvBuffer.resize(0);
convertSendBuffer.resize(0);
@@ -132,35 +114,26 @@ int RadioInterface::setPowerAttenuation(int atten, size_t chan)
}
int RadioInterface::radioifyVector(signalVector &wVector,
- float *retVector,
- bool zero)
+ size_t chan, bool zero)
{
- if (zero) {
- memset(retVector, 0, wVector.size() * 2 * sizeof(float));
- return wVector.size();
- }
-
- memcpy(retVector, wVector.begin(), wVector.size() * 2 * sizeof(float));
+ if (zero)
+ sendBuffer[chan]->zero(wVector.size());
+ else
+ sendBuffer[chan]->write((float *) wVector.begin(), wVector.size());
return wVector.size();
}
-int RadioInterface::unRadioifyVector(float *floatVector,
- signalVector& newVector)
+int RadioInterface::unRadioifyVector(signalVector *newVector, size_t chan)
{
- signalVector::iterator itr = newVector.begin();
-
- if (newVector.size() > recvCursor) {
+ if (newVector->size() > recvBuffer[chan]->getAvailSamples()) {
LOG(ALERT) << "Insufficient number of samples in receive buffer";
return -1;
}
- for (size_t i = 0; i < newVector.size(); i++) {
- *itr++ = Complex<float>(floatVector[2 * i + 0],
- floatVector[2 * i + 1]);
- }
+ recvBuffer[chan]->read((float *) newVector->begin(), newVector->size());
- return newVector.size();
+ return newVector->size();
}
bool RadioInterface::tuneTx(double freq, size_t chan)
@@ -187,8 +160,10 @@ bool RadioInterface::start()
if (!mRadio->start())
return false;
- recvCursor = 0;
- sendCursor = 0;
+ for (size_t i = 0; i < mChans; i++) {
+ sendBuffer[i]->reset();
+ recvBuffer[i]->reset();
+ }
writeTimestamp = mRadio->initialWriteTimestamp();
readTimestamp = mRadio->initialReadTimestamp();
@@ -239,14 +214,10 @@ void RadioInterface::driveTransmitRadio(std::vector<signalVector *> &bursts,
if (!mOn)
return;
- for (size_t i = 0; i < mChans; i++) {
- radioifyVector(*bursts[i],
- (float *) (sendBuffer[i]->begin() + sendCursor), zeros[i]);
- }
-
- sendCursor += bursts[0]->size();
+ for (size_t i = 0; i < mChans; i++)
+ radioifyVector(*bursts[i], i, zeros[i]);
- pushBuffer();
+ while (pushBuffer());
}
bool RadioInterface::driveReceiveRadio()
@@ -261,8 +232,7 @@ bool RadioInterface::driveReceiveRadio()
GSM::Time rcvClock = mClock.get();
rcvClock.decTN(receiveOffset);
unsigned tN = rcvClock.TN();
- int recvSz = recvCursor;
- int readSz = 0;
+ int recvSz = recvBuffer[0]->getAvailSamples();
const int symbolsPerSlot = gSlotLen + 8;
int burstSize;
@@ -285,11 +255,8 @@ bool RadioInterface::driveReceiveRadio()
for (size_t i = 0; i < mChans; i++) {
burst = new radioVector(rcvClock, burstSize, head, mMIMO);
- for (size_t n = 0; n < mMIMO; n++) {
- unRadioifyVector((float *)
- (recvBuffer[mMIMO * i + n]->begin() + readSz),
- *burst->getVector(n));
- }
+ for (size_t n = 0; n < mMIMO; n++)
+ unRadioifyVector(burst->getVector(n), i);
if (mReceiveFIFO[i].size() < 32)
mReceiveFIFO[i].write(burst);
@@ -299,7 +266,6 @@ bool RadioInterface::driveReceiveRadio()
mClock.incTN();
rcvClock.incTN();
- readSz += burstSize;
recvSz -= burstSize;
tN = rcvClock.TN();
@@ -308,16 +274,6 @@ bool RadioInterface::driveReceiveRadio()
burstSize = (symbolsPerSlot + (tN % 4 == 0)) * mSPSRx;
}
- if (readSz > 0) {
- for (size_t i = 0; i < recvBuffer.size(); i++) {
- memmove(recvBuffer[i]->begin(),
- recvBuffer[i]->begin() + readSz,
- (recvCursor - readSz) * 2 * sizeof(float));
- }
-
- recvCursor -= readSz;
- }
-
return true;
}
@@ -339,74 +295,66 @@ VectorFIFO* RadioInterface::receiveFIFO(size_t chan)
double RadioInterface::setRxGain(double dB, size_t chan)
{
- if (mRadio)
- return mRadio->setRxGain(dB, chan);
- else
- return -1;
+ return mRadio->setRxGain(dB, chan);
}
double RadioInterface::getRxGain(size_t chan)
{
- if (mRadio)
- return mRadio->getRxGain(chan);
- else
- return -1;
+ return mRadio->getRxGain(chan);
}
/* Receive a timestamped chunk from the device */
void RadioInterface::pullBuffer()
{
bool local_underrun;
- int num_recv;
- float *output;
+ size_t numRecv, segmentLen = recvBuffer[0]->getSegmentLen();
- if (recvCursor > recvBuffer[0]->size() - CHUNK)
+ if (recvBuffer[0]->getFreeSegments() <= 0)
return;
/* Outer buffer access size is fixed */
- num_recv = mRadio->readSamples(convertRecvBuffer,
- CHUNK,
- &overrun,
- readTimestamp,
- &local_underrun);
- if (num_recv != CHUNK) {
- LOG(ALERT) << "Receive error " << num_recv;
+ numRecv = mRadio->readSamples(convertRecvBuffer,
+ segmentLen,
+ &overrun,
+ readTimestamp,
+ &local_underrun);
+
+ if (numRecv != segmentLen) {
+ LOG(ALERT) << "Receive error " << numRecv;
return;
}
for (size_t i = 0; i < mChans; i++) {
- output = (float *) (recvBuffer[i]->begin() + recvCursor);
- convert_short_float(output, convertRecvBuffer[i], 2 * num_recv);
+ convert_short_float(recvBuffer[i]->getWriteSegment(),
+ convertRecvBuffer[i],
+ segmentLen * 2);
}
underrun |= local_underrun;
-
- readTimestamp += num_recv;
- recvCursor += num_recv;
+ readTimestamp += numRecv;
}
/* Send timestamped chunk to the device with arbitrary size */
-void RadioInterface::pushBuffer()
+bool RadioInterface::pushBuffer()
{
- int num_sent;
+ size_t numSent, segmentLen = sendBuffer[0]->getSegmentLen();
- if (sendCursor < CHUNK)
- return;
-
- if (sendCursor > sendBuffer[0]->size())
- LOG(ALERT) << "Send buffer overflow";
+ if (sendBuffer[0]->getAvailSegments() < 1)
+ return false;
for (size_t i = 0; i < mChans; i++) {
convert_float_short(convertSendBuffer[i],
- (float *) sendBuffer[i]->begin(),
- powerScaling[i], 2 * sendCursor);
+ (float *) sendBuffer[0]->getReadSegment(),
+ powerScaling[i],
+ segmentLen * 2);
}
- /* Send the all samples in the send buffer */
- num_sent = mRadio->writeSamples(convertSendBuffer,
- sendCursor,
- &underrun,
- writeTimestamp);
- writeTimestamp += num_sent;
- sendCursor = 0;
+ /* Send the all samples in the send buffer */
+ numSent = mRadio->writeSamples(convertSendBuffer,
+ segmentLen,
+ &underrun,
+ writeTimestamp);
+ writeTimestamp += numSent;
+
+ return true;
}