From 9b557835d5fbdba543491f6a04f11b335653b2c4 Mon Sep 17 00:00:00 2001 From: "kurtis.heimerl" Date: Sat, 26 Nov 2011 03:18:34 +0000 Subject: transceiver: separate I/O portion of radio interface implementation Move push and pull of buffers into a dedicated file. This will allow us to swap out resampling, non-resampling, and possibly floating point device interfaces while presenting a single floating point abstration in the interface itself. Signed-off-by: Thomas Tsou git-svn-id: http://wush.net/svn/range/software/public/openbts/trunk@2670 19bc5d8c-e614-43d4-8b26-e1612bc8e597 --- Transceiver52M/Makefile.am | 3 +- Transceiver52M/radioIO.cpp | 91 +++++++++++++++++++++++++++++ Transceiver52M/radioInterface.cpp | 118 +++++++++++--------------------------- Transceiver52M/radioInterface.h | 14 ++--- 4 files changed, 133 insertions(+), 93 deletions(-) create mode 100644 Transceiver52M/radioIO.cpp (limited to 'Transceiver52M') diff --git a/Transceiver52M/Makefile.am b/Transceiver52M/Makefile.am index 5bad45e..652663b 100644 --- a/Transceiver52M/Makefile.am +++ b/Transceiver52M/Makefile.am @@ -46,7 +46,8 @@ COMMON_SOURCES = \ DummyLoad.cpp libtransceiver_la_SOURCES = \ - $(COMMON_SOURCES) + $(COMMON_SOURCES) \ + radioIO.cpp noinst_PROGRAMS = \ USRPping \ diff --git a/Transceiver52M/radioIO.cpp b/Transceiver52M/radioIO.cpp new file mode 100644 index 0000000..9956e87 --- /dev/null +++ b/Transceiver52M/radioIO.cpp @@ -0,0 +1,91 @@ +/* + * Radio device I/O interface + * Written by Thomas Tsou + * + * Copyright 2011 Free Software Foundation, Inc. + * + * 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 . + * See the COPYING file in the main directory for details. + */ + +#include +#include + +/* Device side buffers */ +static short rx_buf[OUTCHUNK * 2 * 2]; +static short tx_buf[INCHUNK * 2 * 2]; + +/* Complex float to short conversion */ +static int float_to_short(short *shrt_out, float *flt_in, int num) +{ + int i; + + for (i = 0; i < num; i++) { + shrt_out[2 * i + 0] = flt_in[2 * i + 0]; + shrt_out[2 * i + 1] = flt_in[2 * i + 1]; + } + + return i; +} + +/* Comlpex short to float conversion */ +static int short_to_float(float *flt_out, short *shrt_in, int num) +{ + int i; + + for (i = 0; i < num; i++) { + flt_out[2 * i + 0] = shrt_in[2 * i + 0]; + flt_out[2 * i + 1] = shrt_in[2 * i + 1]; + } + + return i; +} + +/* Receive a timestamped chunk from the device */ +void RadioInterface::pullBuffer() +{ + bool local_underrun; + + /* Read samples. Fail if we don't get what we want. */ + int num_rd = mRadio->readSamples(rx_buf, OUTCHUNK, &overrun, + readTimestamp, &local_underrun); + + LOG(DEBUG) << "Rx read " << num_rd << " samples from device"; + assert(num_rd == OUTCHUNK); + + underrun |= local_underrun; + readTimestamp += (TIMESTAMP) num_rd; + + short_to_float(rcvBuffer + 2 * rcvCursor, rx_buf, num_rd); + rcvCursor += num_rd; +} + +/* Send timestamped chunk to the device with arbitrary size */ +void RadioInterface::pushBuffer() +{ + if (sendCursor < INCHUNK) + return; + + float_to_short(tx_buf, sendBuffer, sendCursor); + + /* Write samples. Fail if we don't get what we want. */ + int num_smpls = mRadio->writeSamples(tx_buf, + sendCursor, + &underrun, + writeTimestamp); + assert(num_smpls == sendCursor); + + writeTimestamp += (TIMESTAMP) num_smpls; + sendCursor = 0; +} diff --git a/Transceiver52M/radioInterface.cpp b/Transceiver52M/radioInterface.cpp index 4e261f7..1482eb6 100644 --- a/Transceiver52M/radioInterface.cpp +++ b/Transceiver52M/radioInterface.cpp @@ -25,6 +25,8 @@ #include "radioInterface.h" #include +bool started = false; + RadioInterface::RadioInterface(RadioDevice *wRadio, int wReceiveOffset, int wRadioOversampling, @@ -73,94 +75,40 @@ void RadioInterface::setPowerAttenuation(double atten) powerScaling = 1.0/sqrt(pow(10, (digAtten/10.0))); } -short *RadioInterface::radioifyVector(signalVector &wVector, - short *retVector, - float scale, - bool zeroOut) +int RadioInterface::radioifyVector(signalVector &wVector, + float *retVector, + float scale, + bool zero) { + int i; signalVector::iterator itr = wVector.begin(); - short *shortItr = retVector; - if (zeroOut) { - while (itr < wVector.end()) { - *shortItr++ = 0; - *shortItr++ = 0; - itr++; - } - } else if (scale != 1.0) { - while (itr < wVector.end()) { - *shortItr++ = (short) (itr->real() * scale); - *shortItr++ = (short) (itr->imag() * scale); - itr++; - } - } else { - while (itr < wVector.end()) { - *shortItr++ = (short) (itr->real()); - *shortItr++ = (short) (itr->imag()); - itr++; - } - } - return retVector; -} - -void RadioInterface::unRadioifyVector(short *shortVector, signalVector& newVector) -{ - - signalVector::iterator itr = newVector.begin(); - short *shortItr = shortVector; - while (itr < newVector.end()) { - *itr++ = Complex(*shortItr,*(shortItr+1)); - shortItr += 2; + if (zero) { + memset(retVector, 0, wVector.size() * 2 * sizeof(float)); + return wVector.size(); } -} - - -bool started = false; - -void RadioInterface::pushBuffer(void) { - - if (sendCursor < 2*INCHUNK*samplesPerSymbol) return; - - // send resampleVector - int samplesWritten = mRadio->writeSamples(sendBuffer, - INCHUNK*samplesPerSymbol, - &underrun, - writeTimestamp); - - writeTimestamp += (TIMESTAMP) samplesWritten; + for (i = 0; i < wVector.size(); i++) { + retVector[2 * i + 0] = itr->real() * scale; + retVector[2 * i + 1] = itr->imag() * scale; + itr++; + } - if (sendCursor > 2*samplesWritten) - memcpy(sendBuffer,sendBuffer+samplesWritten*2,sizeof(short)*2*(sendCursor-2*samplesWritten)); - sendCursor = sendCursor - 2*samplesWritten; + return wVector.size(); } - -void RadioInterface::pullBuffer(void) +int RadioInterface::unRadioifyVector(float *floatVector, + signalVector& newVector) { - - bool localUnderrun; - - // receive receiveVector - short* shortVector = rcvBuffer+rcvCursor; - //LOG(DEBUG) << "Reading USRP samples at timestamp " << readTimestamp; - int samplesRead = mRadio->readSamples(shortVector,OUTCHUNK*samplesPerSymbol,&overrun,readTimestamp,&localUnderrun); - underrun |= localUnderrun; - readTimestamp += (TIMESTAMP) samplesRead; - while (samplesRead < OUTCHUNK*samplesPerSymbol) { - int oldSamplesRead = samplesRead; - samplesRead += mRadio->readSamples(shortVector+2*samplesRead, - OUTCHUNK*samplesPerSymbol-samplesRead, - &overrun, - readTimestamp, - &localUnderrun); - underrun |= localUnderrun; - readTimestamp += (TIMESTAMP) (samplesRead - oldSamplesRead); - } - //LOG(DEBUG) << "samplesRead " << samplesRead; + int i; + signalVector::iterator itr = newVector.begin(); - rcvCursor += samplesRead*2; + for (i = 0; i < newVector.size(); i++) { + *itr++ = Complex(floatVector[2 * i + 0], + floatVector[2 * i + 1]); + } + return newVector.size(); } bool RadioInterface::tuneTx(double freq) @@ -186,8 +134,8 @@ void RadioInterface::start() mRadio->updateAlignment(writeTimestamp-10000); mRadio->updateAlignment(writeTimestamp-10000); - sendBuffer = new short[2*2*INCHUNK*samplesPerSymbol]; - rcvBuffer = new short[2*2*OUTCHUNK*samplesPerSymbol]; + sendBuffer = new float[2*2*INCHUNK*samplesPerSymbol]; + rcvBuffer = new float[2*2*OUTCHUNK*samplesPerSymbol]; mOn = true; @@ -211,9 +159,9 @@ void RadioInterface::driveTransmitRadio(signalVector &radioBurst, bool zeroBurst if (!mOn) return; - radioifyVector(radioBurst, sendBuffer+sendCursor, powerScaling, zeroBurst); + radioifyVector(radioBurst, sendBuffer + 2 * sendCursor, powerScaling, zeroBurst); - sendCursor += (radioBurst.size()*2); + sendCursor += radioBurst.size(); pushBuffer(); } @@ -229,7 +177,7 @@ void RadioInterface::driveReceiveRadio() { GSM::Time rcvClock = mClock.get(); rcvClock.decTN(receiveOffset); unsigned tN = rcvClock.TN(); - int rcvSz = rcvCursor/2; + int rcvSz = rcvCursor; int readSz = 0; const int symbolsPerSlot = gSlotLen + 8; @@ -263,9 +211,9 @@ void RadioInterface::driveReceiveRadio() { tN = rcvClock.TN(); } - if (readSz > 0) { - memcpy(rcvBuffer,rcvBuffer+2*readSz,sizeof(short)*2*(rcvCursor-readSz)); - rcvCursor = rcvCursor-2*readSz; + if (readSz > 0) { + rcvCursor -= readSz; + memmove(rcvBuffer,rcvBuffer+2*readSz,sizeof(float) * 2 * rcvCursor); } } diff --git a/Transceiver52M/radioInterface.h b/Transceiver52M/radioInterface.h index 8fb9f27..9b5c2b1 100644 --- a/Transceiver52M/radioInterface.h +++ b/Transceiver52M/radioInterface.h @@ -37,10 +37,10 @@ private: RadioDevice *mRadio; ///< the USRP object - short *sendBuffer; //[2*2*INCHUNK]; + float *sendBuffer; unsigned sendCursor; - short *rcvBuffer; //[2*2*OUTCHUNK]; + float *rcvBuffer; unsigned rcvCursor; bool underrun; ///< indicates writes to USRP are too slow @@ -64,13 +64,13 @@ private: signalVector *finalVec, *finalVec9; /** format samples to USRP */ - short *radioifyVector(signalVector &wVector, - short *shortVector, - float scale, - bool zeroOut); + int radioifyVector(signalVector &wVector, + float *floatVector, + float scale, + bool zero); /** format samples from USRP */ - void unRadioifyVector(short *shortVector, signalVector &wVector); + int unRadioifyVector(float *floatVector, signalVector &wVector); /** push GSM bursts into the transmit buffer */ void pushBuffer(void); -- cgit v1.2.3