OpenBTS/Transceiver52M/radioInterface.h
Thomas Tsou 22bc28edc4 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
2013-10-17 06:19:05 +00:00

180 lines
4.5 KiB
C++

/*
* Copyright 2008 Free Software Foundation, Inc.
*
* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribuion.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
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.
*/
#include "sigProcLib.h"
#include "GSMCommon.h"
#include "LinkedLists.h"
#include "radioDevice.h"
#include "radioVector.h"
#include "radioClock.h"
/** samples per GSM symbol */
#define SAMPSPERSYM 4
/** class to interface the transceiver with the USRP */
class RadioInterface {
protected:
Thread mAlignRadioServiceLoopThread; ///< thread that synchronizes transmit and receive sections
VectorFIFO mReceiveFIFO; ///< FIFO that holds receive bursts
RadioDevice *mRadio; ///< the USRP object
int mSPSTx;
int mSPSRx;
signalVector *sendBuffer;
signalVector *recvBuffer;
unsigned sendCursor;
unsigned recvCursor;
short *convertRecvBuffer;
short *convertSendBuffer;
bool underrun; ///< indicates writes to USRP are too slow
bool overrun; ///< indicates reads from USRP are too slow
TIMESTAMP writeTimestamp; ///< sample timestamp of next packet written to USRP
TIMESTAMP readTimestamp; ///< sample timestamp of next packet read from USRP
RadioClock mClock; ///< the basestation clock!
int receiveOffset; ///< offset b/w transmit and receive GSM timestamps, in timeslots
bool mOn; ///< indicates radio is on
double powerScaling;
bool loadTest;
int mNumARFCNs;
signalVector *finalVec, *finalVec9;
private:
/** format samples to USRP */
int radioifyVector(signalVector &wVector,
float *floatVector,
bool zero);
/** format samples from USRP */
int unRadioifyVector(float *floatVector, signalVector &wVector);
/** push GSM bursts into the transmit buffer */
virtual void pushBuffer(void);
/** pull GSM bursts from the receive buffer */
virtual void pullBuffer(void);
public:
/** start the interface */
void start();
/** intialization */
virtual bool init();
virtual void close();
/** constructor */
RadioInterface(RadioDevice* wRadio = NULL,
int receiveOffset = 3,
int wSPS = SAMPSPERSYM,
GSM::Time wStartTime = GSM::Time(0));
/** destructor */
virtual ~RadioInterface();
/** check for underrun, resets underrun value */
bool isUnderrun();
/** attach an existing USRP to this interface */
void attach(RadioDevice *wRadio, int wRadioOversampling);
/** return the receive FIFO */
VectorFIFO* receiveFIFO() { return &mReceiveFIFO;}
/** return the basestation clock */
RadioClock* getClock(void) { return &mClock;};
/** set transmit frequency */
bool tuneTx(double freq);
/** set receive frequency */
bool tuneRx(double freq);
/** set receive gain */
double setRxGain(double dB);
/** get receive gain */
double getRxGain(void);
/** drive transmission of GSM bursts */
void driveTransmitRadio(signalVector &radioBurst, bool zeroBurst);
/** drive reception of GSM bursts */
void driveReceiveRadio();
void setPowerAttenuation(double atten);
/** returns the full-scale transmit amplitude **/
double fullScaleInputValue();
/** returns the full-scale receive amplitude **/
double fullScaleOutputValue();
/** set thread priority on current thread */
void setPriority() { mRadio->setPriority(); }
/** get transport window type of attached device */
enum RadioDevice::TxWindowType getWindowType() { return mRadio->getWindowType(); }
#if USRP1
protected:
/** drive synchronization of Tx/Rx of USRP */
void alignRadio();
friend void *AlignRadioServiceLoopAdapter(RadioInterface*);
#endif
};
#if USRP1
/** synchronization thread loop */
void *AlignRadioServiceLoopAdapter(RadioInterface*);
#endif
class RadioInterfaceResamp : public RadioInterface {
private:
signalVector *innerSendBuffer;
signalVector *outerSendBuffer;
signalVector *innerRecvBuffer;
signalVector *outerRecvBuffer;
void pushBuffer();
void pullBuffer();
public:
RadioInterfaceResamp(RadioDevice* wRadio = NULL,
int receiveOffset = 3,
int wSPS = SAMPSPERSYM,
GSM::Time wStartTime = GSM::Time(0));
~RadioInterfaceResamp();
bool init();
void close();
};