diff options
Diffstat (limited to 'Transceiver52M/radioInterface.cpp')
-rw-r--r-- | Transceiver52M/radioInterface.cpp | 202 |
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; } |