Transceiver52M: Setup dual sample rate transceiver

This patch applies oversampling, when selected with 4 sps,
to the downlink only, while running the receiver with
minimal sampling at 1 sps. These split sample rates allow
us to run a highly accurate downlink signal with minimal
distortion, while keeping receive path channel filtering
on the FPGA.

Without this patch, we oversample the receive path and
require a steep receive filter to get similar adjacent
channel suppression as the FPGA halfband / CIC filter
combination, which comes with a high computational cost.

Signed-off-by: Thomas Tsou <tom@tsou.cc>

git-svn-id: http://wush.net/svn/range/software/public/openbts/trunk@6747 19bc5d8c-e614-43d4-8b26-e1612bc8e597
This commit is contained in:
Thomas Tsou
2013-10-17 06:19:05 +00:00
parent 8652b22386
commit 22bc28edc4
10 changed files with 229 additions and 162 deletions

View File

@@ -23,13 +23,15 @@
*/
#include "radioInterface.h"
#include "Resampler.h"
#include <Logger.h>
extern "C" {
#include "convert.h"
}
bool started = false;
#define INCHUNK (625 * SAMPSPERSYM)
#define OUTCHUNK (625 * SAMPSPERSYM)
RadioInterface::RadioInterface(RadioDevice *wRadio,
int wReceiveOffset,
@@ -37,7 +39,7 @@ RadioInterface::RadioInterface(RadioDevice *wRadio,
GSM::Time wStartTime)
: underrun(false), sendCursor(0), recvCursor(0), mOn(false),
mRadio(wRadio), receiveOffset(wReceiveOffset),
sps(wSPS), powerScaling(1.0),
mSPSTx(wSPS), mSPSRx(1), powerScaling(1.0),
loadTest(false), sendBuffer(NULL), recvBuffer(NULL),
convertRecvBuffer(NULL), convertSendBuffer(NULL)
{
@@ -209,8 +211,8 @@ void RadioInterface::driveReceiveRadio() {
// while there's enough data in receive buffer, form received
// GSM bursts and pass up to Transceiver
// Using the 157-156-156-156 symbols per timeslot format.
while (rcvSz > (symbolsPerSlot + (tN % 4 == 0)) * sps) {
signalVector rxVector((symbolsPerSlot + (tN % 4 == 0)) * sps);
while (rcvSz > (symbolsPerSlot + (tN % 4 == 0)) * mSPSRx) {
signalVector rxVector((symbolsPerSlot + (tN % 4 == 0)) * mSPSRx);
unRadioifyVector((float *) (recvBuffer->begin() + readSz), rxVector);
GSM::Time tmpTime = rcvClock;
if (rcvClock.FN() >= 0) {
@@ -228,8 +230,8 @@ void RadioInterface::driveReceiveRadio() {
}
mClock.incTN();
rcvClock.incTN();
readSz += (symbolsPerSlot+(tN % 4 == 0)) * sps;
rcvSz -= (symbolsPerSlot+(tN % 4 == 0)) * sps;
readSz += (symbolsPerSlot+(tN % 4 == 0)) * mSPSRx;
rcvSz -= (symbolsPerSlot+(tN % 4 == 0)) * mSPSRx;
tN = rcvClock.TN();
}
@@ -267,33 +269,35 @@ double RadioInterface::getRxGain()
return -1;
}
/* Receive a timestamped chunk from the device */
/* Receive a timestamped chunk from the device */
void RadioInterface::pullBuffer()
{
bool local_underrun;
int num_recv;
int num_recv, len = OUTCHUNK / mSPSTx;
float *output;
/* Outer buffer access size is fixed */
/* Outer buffer access size is fixed */
num_recv = mRadio->readSamples(convertRecvBuffer,
OUTCHUNK,
len,
&overrun,
readTimestamp,
&local_underrun);
if (num_recv != OUTCHUNK) {
if (num_recv != len) {
LOG(ALERT) << "Receive error " << num_recv;
return;
}
convert_short_float((float *) (recvBuffer->begin() + recvCursor),
convertRecvBuffer, 2 * OUTCHUNK);
output = (float *) (recvBuffer->begin() + recvCursor);
convert_short_float(output, convertRecvBuffer, 2 * len);
underrun |= local_underrun;
readTimestamp += num_recv;
readTimestamp += num_recv;
recvCursor += num_recv;
}
/* Send timestamped chunk to the device with arbitrary size */
/* Send timestamped chunk to the device with arbitrary size */
void RadioInterface::pushBuffer()
{
int num_sent;