mirror of
https://github.com/RangeNetworks/openbts.git
synced 2025-11-02 04:43:16 +00:00
Adding MultiARFCN support to RAD1 radio.
git-svn-id: http://wush.net/svn/range/software/public/openbts/trunk@3689 19bc5d8c-e614-43d4-8b26-e1612bc8e597
This commit is contained in:
@@ -124,21 +124,21 @@ private:
|
|||||||
static const unsigned BSC = 3; // bits 21,20 Div by 8 to be safe
|
static const unsigned BSC = 3; // bits 21,20 Div by 8 to be safe
|
||||||
static const unsigned TEST = 0; // bit 19
|
static const unsigned TEST = 0; // bit 19
|
||||||
static const unsigned LDP = 1; // bit 18
|
static const unsigned LDP = 1; // bit 18
|
||||||
static const unsigned ABP = 0; // bit 17,16 3ns
|
static const unsigned ABP = 2; // bit 17,16 6ns, 0 = 3ns
|
||||||
|
|
||||||
// N-Register Common Values
|
// N-Register Common Values
|
||||||
static const unsigned N_RSV = 0; // bit 7
|
static const unsigned N_RSV = 0; // bit 7
|
||||||
|
|
||||||
// Control Register Common Values
|
// Control Register Common Values
|
||||||
static const unsigned PD = 0; // bits 21,20 Normal operation
|
static const unsigned PD = 0; // bits 21,20 Normal operation
|
||||||
static const unsigned PL = 2; // bits 13,12 7.5mA, -6dbm
|
static const unsigned PL = 1; // bits 13,12 7.5mA, -6dbm
|
||||||
static const unsigned MTLD = 1; // bit 11 enabled
|
static const unsigned MTLD = 1; // bit 11 enabled
|
||||||
static const unsigned CPG = 0; // bit 10 CP setting 1
|
static const unsigned CPG = 0; // bit 10 CP setting 1
|
||||||
static const unsigned CP3S = 0; // bit 9 Normal
|
static const unsigned CP3S = 0; // bit 9 Normal
|
||||||
static const unsigned PDP = 1; // bit 8 Positive
|
static const unsigned PDP = 1; // bit 8 Positive
|
||||||
static const unsigned MUXOUT = 1;// bits 7:5 Digital Lock Detect
|
static const unsigned MUXOUT = 1;// bits 7:5 Digital Lock Detect
|
||||||
static const unsigned CR = 0; // bit 4 Normal
|
static const unsigned CR = 0; // bit 4 Normal
|
||||||
static const unsigned PC = 2; // bits 3,2 Core power 15mA
|
static const unsigned PC = 0; // bits 3,2 Core power 15mA
|
||||||
|
|
||||||
// ATR register value
|
// ATR register value
|
||||||
//static const int FR_ATR_MASK_0 = 20;
|
//static const int FR_ATR_MASK_0 = 20;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,25 @@
|
|||||||
/** Define this to be the slot number to be logged. */
|
/** Define this to be the slot number to be logged. */
|
||||||
//#define TRANSMIT_LOGGING 1
|
//#define TRANSMIT_LOGGING 1
|
||||||
|
|
||||||
|
#define MAXARFCN 5
|
||||||
|
|
||||||
|
|
||||||
|
/** Codes for burst types of received bursts*/
|
||||||
|
typedef enum {
|
||||||
|
OFF, ///< timeslot is off
|
||||||
|
TSC, ///< timeslot should contain a normal burst
|
||||||
|
RACH, ///< timeslot should contain an access burst
|
||||||
|
IDLE ///< timeslot is an idle (or dummy) burst
|
||||||
|
} CorrType;
|
||||||
|
|
||||||
|
class Demodulator;
|
||||||
|
class Transceiver;
|
||||||
|
|
||||||
|
typedef struct ThreadStruct {
|
||||||
|
Transceiver *trx;
|
||||||
|
unsigned ARFCN;
|
||||||
|
} ThreadStruct;
|
||||||
|
|
||||||
/** The Transceiver class, responsible for physical layer of basestation */
|
/** The Transceiver class, responsible for physical layer of basestation */
|
||||||
class Transceiver {
|
class Transceiver {
|
||||||
|
|
||||||
@@ -48,33 +67,33 @@ private:
|
|||||||
GSM::Time mTransmitLatency; ///< latency between basestation clock and transmit deadline clock
|
GSM::Time mTransmitLatency; ///< latency between basestation clock and transmit deadline clock
|
||||||
GSM::Time mLatencyUpdateTime; ///< last time latency was updated
|
GSM::Time mLatencyUpdateTime; ///< last time latency was updated
|
||||||
|
|
||||||
UDPSocket mDataSocket; ///< socket for writing to/reading from GSM core
|
UDPSocket *mDataSocket[MAXARFCN]; ///< socket for writing to/reading from GSM core
|
||||||
UDPSocket mControlSocket; ///< socket for writing/reading control commands from GSM core
|
UDPSocket *mControlSocket[MAXARFCN]; ///< socket for writing/reading control commands from GSM core
|
||||||
UDPSocket mClockSocket; ///< socket for writing clock updates to GSM core
|
UDPSocket mClockSocket; ///< socket for writing clock updates to GSM core
|
||||||
|
|
||||||
VectorQueue mTransmitPriorityQueue; ///< priority queue of transmit bursts received from GSM core
|
VectorQueue mTransmitPriorityQueue; ///< priority queue of transmit bursts received from GSM core
|
||||||
VectorFIFO* mTransmitFIFO; ///< radioInterface FIFO of transmit bursts
|
VectorFIFO* mTransmitFIFO; ///< radioInterface FIFO of transmit bursts
|
||||||
VectorFIFO* mReceiveFIFO; ///< radioInterface FIFO of receive bursts
|
VectorFIFO* mReceiveFIFO; ///< radioInterface FIFO of receive bursts
|
||||||
|
VectorFIFO* mDemodFIFO[MAXARFCN];
|
||||||
|
|
||||||
Thread *mFIFOServiceLoopThread; ///< thread to push/pull bursts into transmit/receive FIFO
|
Thread *mFIFOServiceLoopThread; ///< thread to push/pull bursts into transmit/receive FIFO
|
||||||
Thread *mControlServiceLoopThread; ///< thread to process control messages from GSM core
|
Thread *mRFIFOServiceLoopThread;
|
||||||
Thread *mTransmitPriorityQueueServiceLoopThread;///< thread to process transmit bursts from GSM core
|
Thread *mDemodServiceLoopThread[MAXARFCN]; ///< threads for demodulating individual ARFCNs
|
||||||
|
Thread *mControlServiceLoopThread[MAXARFCN]; ///< thread to process control messages from GSM core
|
||||||
|
Thread *mTransmitPriorityQueueServiceLoopThread[MAXARFCN];///< thread to process transmit bursts from GSM core
|
||||||
|
|
||||||
GSM::Time mTransmitDeadlineClock; ///< deadline for pushing bursts into transmit FIFO
|
GSM::Time mTransmitDeadlineClock; ///< deadline for pushing bursts into transmit FIFO
|
||||||
GSM::Time mLastClockUpdateTime; ///< last time clock update was sent up to core
|
GSM::Time mLastClockUpdateTime; ///< last time clock update was sent up to core
|
||||||
|
GSM::Time mStartTime;
|
||||||
|
|
||||||
RadioInterface *mRadioInterface; ///< associated radioInterface object
|
RadioInterface *mRadioInterface; ///< associated radioInterface object
|
||||||
double txFullScale; ///< full scale input to radio
|
double txFullScale; ///< full scale input to radio
|
||||||
double rxFullScale; ///< full scale output to radio
|
double rxFullScale;
|
||||||
|
|
||||||
/** Codes for burst types of received bursts*/
|
Mutex mControlLock;
|
||||||
typedef enum {
|
Mutex mTransmitPriorityQueueLock;
|
||||||
OFF, ///< timeslot is off
|
|
||||||
TSC, ///< timeslot should contain a normal burst
|
|
||||||
RACH, ///< timeslot should contain an access burst
|
|
||||||
IDLE ///< timeslot is an idle (or dummy) burst
|
|
||||||
} CorrType;
|
|
||||||
|
|
||||||
|
bool mLoadTest;
|
||||||
|
|
||||||
/** Codes for channel combinations */
|
/** Codes for channel combinations */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -99,22 +118,18 @@ private:
|
|||||||
/** modulate and add a burst to the transmit queue */
|
/** modulate and add a burst to the transmit queue */
|
||||||
void addRadioVector(BitVector &burst,
|
void addRadioVector(BitVector &burst,
|
||||||
int RSSI,
|
int RSSI,
|
||||||
GSM::Time &wTime);
|
GSM::Time &wTime,
|
||||||
|
int ARFCN);
|
||||||
|
|
||||||
/** Push modulated burst into transmit FIFO corresponding to a particular timestamp */
|
/** Push modulated burst into transmit FIFO corresponding to a particular timestamp */
|
||||||
void pushRadioVector(GSM::Time &nowTime);
|
void pushRadioVector(GSM::Time &nowTime);
|
||||||
|
|
||||||
/** Pull and demodulate a burst from the receive FIFO */
|
/** Pull and demodulate a burst from the receive FIFO */
|
||||||
SoftVector *pullRadioVector(GSM::Time &wTime,
|
void pullRadioVector(void);
|
||||||
int &RSSI,
|
|
||||||
int &timingOffset);
|
|
||||||
|
|
||||||
/** Set modulus for specific timeslot */
|
/** Set modulus for specific timeslot */
|
||||||
void setModulus(int timeslot);
|
void setModulus(int timeslot);
|
||||||
|
|
||||||
/** return the expected burst type for the specified timestamp */
|
|
||||||
CorrType expectedCorrType(GSM::Time currTime);
|
|
||||||
|
|
||||||
/** send messages over the clock socket */
|
/** send messages over the clock socket */
|
||||||
void writeClockInterface(void);
|
void writeClockInterface(void);
|
||||||
|
|
||||||
@@ -123,24 +138,27 @@ private:
|
|||||||
int mSamplesPerSymbol; ///< number of samples per GSM symbol
|
int mSamplesPerSymbol; ///< number of samples per GSM symbol
|
||||||
|
|
||||||
bool mOn; ///< flag to indicate that transceiver is powered on
|
bool mOn; ///< flag to indicate that transceiver is powered on
|
||||||
ChannelCombination mChanType[8]; ///< channel types for all timeslots
|
ChannelCombination mChanType[MAXARFCN][8]; ///< channel types for all timeslots
|
||||||
double mTxFreq; ///< the transmit frequency
|
double mTxFreq; ///< the transmit frequency
|
||||||
double mRxFreq; ///< the receive frequency
|
double mRxFreq; ///< the receive frequency
|
||||||
int mPower; ///< the transmit power in dB
|
int mPower; ///< the transmit power in dB
|
||||||
unsigned mTSC; ///< the midamble sequence code
|
unsigned mTSC; ///< the midamble sequence code
|
||||||
double mEnergyThreshold; ///< threshold to determine if received data is potentially a GSM burst
|
|
||||||
GSM::Time prevFalseDetectionTime; ///< last timestamp of a false energy detection
|
|
||||||
int fillerModulus[8]; ///< modulus values of all timeslots, in frames
|
int fillerModulus[8]; ///< modulus values of all timeslots, in frames
|
||||||
signalVector *fillerTable[102][8]; ///< table of modulated filler waveforms for all timeslots
|
signalVector *fillerTable[102][8]; ///< table of modulated filler waveforms for all timeslots
|
||||||
unsigned mMaxExpectedDelay; ///< maximum expected time-of-arrival offset in GSM symbols
|
unsigned mMaxExpectedDelay; ///< maximum expected time-of-arrival offset in GSM symbols
|
||||||
|
|
||||||
GSM::Time channelEstimateTime[8]; ///< last timestamp of each timeslot's channel estimate
|
unsigned int mNumARFCNs;
|
||||||
signalVector *channelResponse[8]; ///< most recent channel estimate of all timeslots
|
bool mMultipleARFCN;
|
||||||
float SNRestimate[8]; ///< most recent SNR estimate of all timeslots
|
unsigned char mOversamplingRate;
|
||||||
signalVector *DFEForward[8]; ///< most recent DFE feedforward filter of all timeslots
|
double mFreqOffset;
|
||||||
signalVector *DFEFeedback[8]; ///< most recent DFE feedback filter of all timeslots
|
signalVector *frequencyShifter[MAXARFCN];
|
||||||
float chanRespOffset[8]; ///< most recent timing offset, e.g. TOA, of all timeslots
|
signalVector *decimationFilter;
|
||||||
complex chanRespAmplitude[8]; ///< most recent channel amplitude of all timeslots
|
signalVector *interpolationFilter;
|
||||||
|
|
||||||
|
Demodulator *mDemodulators[MAXARFCN];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -155,7 +173,10 @@ public:
|
|||||||
const char *TRXAddress,
|
const char *TRXAddress,
|
||||||
int wSamplesPerSymbol,
|
int wSamplesPerSymbol,
|
||||||
GSM::Time wTransmitLatency,
|
GSM::Time wTransmitLatency,
|
||||||
RadioInterface *wRadioInterface);
|
RadioInterface *wRadioInterface,
|
||||||
|
unsigned int wNumARFCNs,
|
||||||
|
unsigned int wOversamplingRate,
|
||||||
|
bool wLoadTest);
|
||||||
|
|
||||||
/** Destructor */
|
/** Destructor */
|
||||||
~Transceiver();
|
~Transceiver();
|
||||||
@@ -163,12 +184,30 @@ public:
|
|||||||
/** start the Transceiver */
|
/** start the Transceiver */
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
|
bool multiARFCN() {return mMultipleARFCN;}
|
||||||
|
|
||||||
|
/** return the expected burst type for the specified timestamp */
|
||||||
|
CorrType expectedCorrType(GSM::Time currTime, int ARFCN);
|
||||||
|
|
||||||
/** attach the radioInterface receive FIFO */
|
/** attach the radioInterface receive FIFO */
|
||||||
void receiveFIFO(VectorFIFO *wFIFO) { mReceiveFIFO = wFIFO;}
|
void receiveFIFO(VectorFIFO *wFIFO) { mReceiveFIFO = wFIFO;}
|
||||||
|
|
||||||
/** attach the radioInterface transmit FIFO */
|
/** attach the radioInterface transmit FIFO */
|
||||||
void transmitFIFO(VectorFIFO *wFIFO) { mTransmitFIFO = wFIFO;}
|
void transmitFIFO(VectorFIFO *wFIFO) { mTransmitFIFO = wFIFO;}
|
||||||
|
|
||||||
|
VectorFIFO *demodFIFO(unsigned ARFCN) { return mDemodFIFO[ARFCN]; }
|
||||||
|
|
||||||
|
RadioInterface *radioInterface(void) { return mRadioInterface; }
|
||||||
|
|
||||||
|
unsigned samplesPerSymbol(void) { return mSamplesPerSymbol; }
|
||||||
|
|
||||||
|
UDPSocket *dataSocket(int ARFCN) { return mDataSocket[ARFCN]; }
|
||||||
|
|
||||||
|
signalVector *GSMPulse(void) { return gsmPulse; }
|
||||||
|
|
||||||
|
unsigned maxDelay(void) { return mMaxExpectedDelay; }
|
||||||
|
|
||||||
|
unsigned getTSC(void) { return mTSC; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@@ -179,19 +218,21 @@ protected:
|
|||||||
void driveTransmitFIFO();
|
void driveTransmitFIFO();
|
||||||
|
|
||||||
/** drive handling of control messages from GSM core */
|
/** drive handling of control messages from GSM core */
|
||||||
void driveControl();
|
void driveControl(unsigned ARFCN);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
drive modulation and sorting of GSM bursts from GSM core
|
drive modulation and sorting of GSM bursts from GSM core
|
||||||
@return true if a burst was transferred successfully
|
@return true if a burst was transferred successfully
|
||||||
*/
|
*/
|
||||||
bool driveTransmitPriorityQueue();
|
bool driveTransmitPriorityQueue(unsigned ARFCN);
|
||||||
|
|
||||||
friend void *FIFOServiceLoopAdapter(Transceiver *);
|
friend void *FIFOServiceLoopAdapter(Transceiver *);
|
||||||
|
|
||||||
friend void *ControlServiceLoopAdapter(Transceiver *);
|
friend void *RFIFOServiceLoopAdapter(Transceiver *);
|
||||||
|
|
||||||
|
friend void *ControlServiceLoopAdapter(ThreadStruct *);
|
||||||
|
|
||||||
friend void *TransmitPriorityQueueServiceLoopAdapter(Transceiver *);
|
friend void *TransmitPriorityQueueServiceLoopAdapter(ThreadStruct *);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
};
|
};
|
||||||
@@ -199,9 +240,61 @@ protected:
|
|||||||
/** FIFO thread loop */
|
/** FIFO thread loop */
|
||||||
void *FIFOServiceLoopAdapter(Transceiver *);
|
void *FIFOServiceLoopAdapter(Transceiver *);
|
||||||
|
|
||||||
|
void *RFIFOServiceLoopAdapter(Transceiver *);
|
||||||
|
|
||||||
/** control message handler thread loop */
|
/** control message handler thread loop */
|
||||||
void *ControlServiceLoopAdapter(Transceiver *);
|
void *ControlServiceLoopAdapter(ThreadStruct *);
|
||||||
|
|
||||||
/** transmit queueing thread loop */
|
/** transmit queueing thread loop */
|
||||||
void *TransmitPriorityQueueServiceLoopAdapter(Transceiver *);
|
void *TransmitPriorityQueueServiceLoopAdapter(ThreadStruct *);
|
||||||
|
|
||||||
|
class Demodulator {
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int mARFCN;
|
||||||
|
Transceiver *mTRX;
|
||||||
|
RadioInterface *mRadioInterface;
|
||||||
|
VectorFIFO *mDemodFIFO;
|
||||||
|
double mEnergyThreshold; ///< threshold to determine if received data is potentially a GSM burst
|
||||||
|
GSM::Time prevFalseDetectionTime; ///< last timestamp of a false energy detection
|
||||||
|
GSM::Time channelEstimateTime[8]; ///< last timestamp of each timeslot's channel estimate
|
||||||
|
signalVector *channelResponse[8]; ///< most recent channel estimate of all timeslots
|
||||||
|
float SNRestimate[8]; ///< most recent SNR estimate of all timeslots
|
||||||
|
signalVector *DFEForward[8]; ///< most recent DFE feedforward filter of all timeslots
|
||||||
|
signalVector *DFEFeedback[8]; ///< most recent DFE feedback filter of all timeslots
|
||||||
|
float chanRespOffset[8]; ///< most recent timing offset, e.g. TOA, of all timeslots
|
||||||
|
complex chanRespAmplitude[8]; ///< most recent channel amplitude of all timeslots
|
||||||
|
signalVector *gsmPulse;
|
||||||
|
unsigned mTSC;
|
||||||
|
unsigned mSamplesPerSymbol;
|
||||||
|
|
||||||
|
UDPSocket *mTRXDataSocket;
|
||||||
|
|
||||||
|
unsigned mMaxExpectedDelay;
|
||||||
|
|
||||||
|
double rxFullScale; ///< full scale output to radio
|
||||||
|
|
||||||
|
SoftVector* demodRadioVector(radioVector *rxBurst,
|
||||||
|
GSM::Time &wTime,
|
||||||
|
int &RSSI,
|
||||||
|
int &timingOffset);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Demodulator(int wARFCN,
|
||||||
|
Transceiver *wTRX,
|
||||||
|
GSM::Time wStartTime);
|
||||||
|
|
||||||
|
double getEnergyThreshold() {return mEnergyThreshold;}
|
||||||
|
|
||||||
|
|
||||||
|
//protected:
|
||||||
|
|
||||||
|
void driveDemod(bool wSingleARFCN = true);
|
||||||
|
protected:
|
||||||
|
friend void *DemodServiceLoopAdapter(Demodulator *);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void *DemodServiceLoopAdapter(Demodulator *);
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ RadioInterface::RadioInterface(RadioDevice *wRadio,
|
|||||||
int wReceiveOffset,
|
int wReceiveOffset,
|
||||||
int wRadioOversampling,
|
int wRadioOversampling,
|
||||||
int wTransceiverOversampling,
|
int wTransceiverOversampling,
|
||||||
|
bool wLoadTest,
|
||||||
|
unsigned int wNumARFCNs,
|
||||||
GSM::Time wStartTime)
|
GSM::Time wStartTime)
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -85,6 +87,9 @@ RadioInterface::RadioInterface(RadioDevice *wRadio,
|
|||||||
samplesPerSymbol = wRadioOversampling;
|
samplesPerSymbol = wRadioOversampling;
|
||||||
mClock.set(wStartTime);
|
mClock.set(wStartTime);
|
||||||
powerScaling = 1.0;
|
powerScaling = 1.0;
|
||||||
|
mNumARFCNs = wNumARFCNs;
|
||||||
|
|
||||||
|
loadTest = wLoadTest;
|
||||||
}
|
}
|
||||||
|
|
||||||
RadioInterface::~RadioInterface(void) {
|
RadioInterface::~RadioInterface(void) {
|
||||||
@@ -236,6 +241,34 @@ void RadioInterface::start()
|
|||||||
|
|
||||||
mOn = true;
|
mOn = true;
|
||||||
|
|
||||||
|
if (loadTest) {
|
||||||
|
int mOversamplingRate = samplesPerSymbol;
|
||||||
|
int numARFCN = mNumARFCNs;
|
||||||
|
signalVector *gsmPulse = generateGSMPulse(2,1);
|
||||||
|
BitVector normalBurstSeg = "0000101010100111110010101010010110101110011000111001101010000";
|
||||||
|
BitVector normalBurst(BitVector(normalBurstSeg,gTrainingSequence[2]),normalBurstSeg);
|
||||||
|
signalVector *modBurst = modulateBurst(normalBurst,*gsmPulse,8,1);
|
||||||
|
signalVector *modBurst9 = modulateBurst(normalBurst,*gsmPulse,9,1);
|
||||||
|
signalVector *interpolationFilter = createLPF(0.6/mOversamplingRate,6*mOversamplingRate,1);
|
||||||
|
scaleVector(*modBurst,mRadio->fullScaleInputValue());
|
||||||
|
scaleVector(*modBurst9,mRadio->fullScaleInputValue());
|
||||||
|
double beaconFreq = -1.0*(numARFCN-1)*200e3;
|
||||||
|
finalVec = new signalVector(156*mOversamplingRate);
|
||||||
|
finalVec9 = new signalVector(157*mOversamplingRate);
|
||||||
|
for (int j = 0; j < numARFCN; j++) {
|
||||||
|
signalVector *frequencyShifter = new signalVector(157*mOversamplingRate);
|
||||||
|
frequencyShifter->fill(1.0);
|
||||||
|
frequencyShift(frequencyShifter,frequencyShifter,2.0*M_PI*(beaconFreq+j*400e3)/(1625.0e3/6.0*mOversamplingRate));
|
||||||
|
signalVector *interpVec = polyphaseResampleVector(*modBurst,mOversamplingRate,1,interpolationFilter);
|
||||||
|
multVector(*interpVec,*frequencyShifter);
|
||||||
|
addVector(*finalVec,*interpVec);
|
||||||
|
interpVec = polyphaseResampleVector(*modBurst9,mOversamplingRate,1,interpolationFilter);
|
||||||
|
multVector(*interpVec,*frequencyShifter);
|
||||||
|
addVector(*finalVec9,*interpVec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *AlignRadioServiceLoopAdapter(RadioInterface *radioInterface)
|
void *AlignRadioServiceLoopAdapter(RadioInterface *radioInterface)
|
||||||
@@ -287,14 +320,15 @@ void RadioInterface::driveReceiveRadio() {
|
|||||||
GSM::Time tmpTime = rcvClock;
|
GSM::Time tmpTime = rcvClock;
|
||||||
if (rcvClock.FN() >= 0) {
|
if (rcvClock.FN() >= 0) {
|
||||||
//LOG(DEBUG) << "FN: " << rcvClock.FN();
|
//LOG(DEBUG) << "FN: " << rcvClock.FN();
|
||||||
|
int dummyARFCN = 0;
|
||||||
radioVector *rxBurst = NULL;
|
radioVector *rxBurst = NULL;
|
||||||
if (!loadTest)
|
if (!loadTest)
|
||||||
rxBurst = new radioVector(rxVector,tmpTime);
|
rxBurst = new radioVector(rxVector,tmpTime,dummyARFCN);
|
||||||
else {
|
else {
|
||||||
if (tN % 4 == 0)
|
if (tN % 4 == 0)
|
||||||
rxBurst = new radioVector(*finalVec9,tmpTime);
|
rxBurst = new radioVector(*finalVec9,tmpTime,dummyARFCN);
|
||||||
else
|
else
|
||||||
rxBurst = new radioVector(*finalVec,tmpTime);
|
rxBurst = new radioVector(*finalVec,tmpTime,dummyARFCN);
|
||||||
}
|
}
|
||||||
mReceiveFIFO.put(rxBurst);
|
mReceiveFIFO.put(rxBurst);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,16 +40,22 @@ class radioVector : public signalVector {
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
GSM::Time mTime; ///< the burst's GSM timestamp
|
GSM::Time mTime; ///< the burst's GSM timestamp
|
||||||
|
int mARFCN;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** constructor */
|
/** constructor */
|
||||||
radioVector(const signalVector& wVector,
|
radioVector(const signalVector& wVector,
|
||||||
GSM::Time& wTime): signalVector(wVector),mTime(wTime) {};
|
GSM::Time& wTime,
|
||||||
|
int& wARFCN): signalVector(wVector),mTime(wTime),mARFCN(wARFCN){};
|
||||||
|
|
||||||
/** timestamp read and write operators */
|
/** timestamp read and write operators */
|
||||||
GSM::Time time() const { return mTime;}
|
GSM::Time time() const { return mTime;}
|
||||||
void time(const GSM::Time& wTime) { mTime = wTime;}
|
void time(const GSM::Time& wTime) { mTime = wTime;}
|
||||||
|
|
||||||
|
/** ARFCN read and write operators */
|
||||||
|
int ARFCN() const { return mARFCN;}
|
||||||
|
void ARFCN(const int& wARFCN) { mARFCN = wARFCN;}
|
||||||
|
|
||||||
/** comparison operator, used for sorting */
|
/** comparison operator, used for sorting */
|
||||||
bool operator>(const radioVector& other) const {return mTime > other.mTime;}
|
bool operator>(const radioVector& other) const {return mTime > other.mTime;}
|
||||||
|
|
||||||
@@ -111,12 +117,12 @@ private:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
/** Set clock */
|
/** Set clock */
|
||||||
//void set(const GSM::Time& wTime) { ScopedLock lock(mLock); mClock = wTime; updateSignal.signal();}
|
void set(const GSM::Time& wTime) { ScopedLock lock(mLock); mClock = wTime; updateSignal.signal();}
|
||||||
void set(const GSM::Time& wTime) { ScopedLock lock(mLock); mClock = wTime; updateSignal.broadcast();;}
|
//void set(const GSM::Time& wTime) { ScopedLock lock(mLock); mClock = wTime; updateSignal.broadcast();;}
|
||||||
|
|
||||||
/** Increment clock */
|
/** Increment clock */
|
||||||
//void incTN() { ScopedLock lock(mLock); mClock.incTN(); updateSignal.signal();}
|
void incTN() { ScopedLock lock(mLock); mClock.incTN(); updateSignal.signal();}
|
||||||
void incTN() { ScopedLock lock(mLock); mClock.incTN(); updateSignal.broadcast();}
|
//void incTN() { ScopedLock lock(mLock); mClock.incTN(); updateSignal.broadcast();}
|
||||||
|
|
||||||
/** Get clock value */
|
/** Get clock value */
|
||||||
GSM::Time get() { ScopedLock lock(mLock); return mClock; }
|
GSM::Time get() { ScopedLock lock(mLock); return mClock; }
|
||||||
@@ -188,6 +194,8 @@ public:
|
|||||||
int receiveOffset = 3,
|
int receiveOffset = 3,
|
||||||
int wRadioOversampling = SAMPSPERSYM,
|
int wRadioOversampling = SAMPSPERSYM,
|
||||||
int wTransceiverOversampling = SAMPSPERSYM,
|
int wTransceiverOversampling = SAMPSPERSYM,
|
||||||
|
bool wLoadTest = false,
|
||||||
|
unsigned int wNumARFCNS = 1,
|
||||||
GSM::Time wStartTime = GSM::Time(0));
|
GSM::Time wStartTime = GSM::Time(0));
|
||||||
|
|
||||||
/** destructor */
|
/** destructor */
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ int usbMsg (struct libusb_device_handle *udh,
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
// we get EPIPE if the firmware stalls the endpoint.
|
// we get EPIPE if the firmware stalls the endpoint.
|
||||||
if (ret != LIBUSB_ERROR_PIPE) {
|
if (ret != LIBUSB_ERROR_PIPE) {
|
||||||
LOG(ALERT) << "libusb_control_transfer failed: " << _get_usb_error_str(ret);
|
LOG(ERR) << "libusb_control_transfer failed: " << _get_usb_error_str(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,16 +66,79 @@ int main(int argc, char *argv[])
|
|||||||
// Configure logger.
|
// Configure logger.
|
||||||
gLogInit("transceiver",gConfig.getStr("Log.Level").c_str(),LOG_LOCAL7);
|
gLogInit("transceiver",gConfig.getStr("Log.Level").c_str(),LOG_LOCAL7);
|
||||||
|
|
||||||
|
int numARFCN=1;
|
||||||
|
if (argc>1) numARFCN = atoi(argv[1]);
|
||||||
|
|
||||||
|
#ifdef SINGLEARFCN
|
||||||
|
numARFCN=1;
|
||||||
|
#endif
|
||||||
|
|
||||||
srandom(time(NULL));
|
srandom(time(NULL));
|
||||||
|
|
||||||
int mOversamplingRate = 1;
|
int mOversamplingRate = 1;
|
||||||
|
switch(numARFCN) {
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
mOversamplingRate = 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
mOversamplingRate = 6;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mOversamplingRate = 8;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
mOversamplingRate = 12;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
mOversamplingRate = 16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//int mOversamplingRate = numARFCN/2 + numARFCN;
|
||||||
|
//mOversamplingRate = 15; //mOversamplingRate*2;
|
||||||
|
//if ((numARFCN > 1) && (mOversamplingRate % 2)) mOversamplingRate++;
|
||||||
RAD1Device *usrp = new RAD1Device(mOversamplingRate*1625.0e3/6.0);
|
RAD1Device *usrp = new RAD1Device(mOversamplingRate*1625.0e3/6.0);
|
||||||
|
//DummyLoad *usrp = new DummyLoad(mOversamplingRate*1625.0e3/6.0);
|
||||||
usrp->make();
|
usrp->make();
|
||||||
|
|
||||||
RadioInterface* radio = new RadioInterface(usrp,3,SAMPSPERSYM,mOversamplingRate,false);
|
RadioInterface* radio = new RadioInterface(usrp,3,SAMPSPERSYM,mOversamplingRate,false,numARFCN);
|
||||||
Transceiver *trx = new Transceiver(5700,"127.0.0.1",SAMPSPERSYM,GSM::Time(2,0),radio);
|
Transceiver *trx = new Transceiver(5700,"127.0.0.1",SAMPSPERSYM,GSM::Time(2,0),radio,
|
||||||
|
numARFCN,mOversamplingRate,false);
|
||||||
trx->receiveFIFO(radio->receiveFIFO());
|
trx->receiveFIFO(radio->receiveFIFO());
|
||||||
|
|
||||||
|
/*
|
||||||
|
signalVector *gsmPulse = generateGSMPulse(2,1);
|
||||||
|
BitVector normalBurstSeg = "0000101010100111110010101010010110101110011000111001101010000";
|
||||||
|
BitVector normalBurst(BitVector(normalBurstSeg,gTrainingSequence[0]),normalBurstSeg);
|
||||||
|
signalVector *modBurst = modulateBurst(normalBurst,*gsmPulse,8,1);
|
||||||
|
signalVector *modBurst9 = modulateBurst(normalBurst,*gsmPulse,9,1);
|
||||||
|
signalVector *interpolationFilter = createLPF(0.6/mOversamplingRate,6*mOversamplingRate,1);
|
||||||
|
signalVector totalBurst1(*modBurst,*modBurst9);
|
||||||
|
signalVector totalBurst2(*modBurst,*modBurst);
|
||||||
|
signalVector totalBurst(totalBurst1,totalBurst2);
|
||||||
|
scaleVector(totalBurst,usrp->fullScaleInputValue());
|
||||||
|
double beaconFreq = -1.0*(numARFCN-1)*200e3;
|
||||||
|
signalVector finalVec(625*mOversamplingRate);
|
||||||
|
for (int j = 0; j < numARFCN; j++) {
|
||||||
|
signalVector *frequencyShifter = new signalVector(625*mOversamplingRate);
|
||||||
|
frequencyShifter->fill(1.0);
|
||||||
|
frequencyShift(frequencyShifter,frequencyShifter,2.0*M_PI*(beaconFreq+j*400e3)/(1625.0e3/6.0*mOversamplingRate));
|
||||||
|
signalVector *interpVec = polyphaseResampleVector(totalBurst,mOversamplingRate,1,interpolationFilter);
|
||||||
|
multVector(*interpVec,*frequencyShifter);
|
||||||
|
addVector(finalVec,*interpVec);
|
||||||
|
}
|
||||||
|
signalVector::iterator itr = finalVec.begin();
|
||||||
|
short finalVecShort[2*finalVec.size()];
|
||||||
|
short *shortItr = finalVecShort;
|
||||||
|
while (itr < finalVec.end()) {
|
||||||
|
*shortItr++ = (short) (itr->real());
|
||||||
|
*shortItr++ = (short) (itr->imag());
|
||||||
|
itr++;
|
||||||
|
}
|
||||||
|
usrp->loadBurst(finalVecShort,finalVec.size());
|
||||||
|
*/
|
||||||
trx->start();
|
trx->start();
|
||||||
//int i = 0;
|
//int i = 0;
|
||||||
while(!gbShutdown) { sleep(1); } //i++; if (i==60) exit(1);}
|
while(!gbShutdown) { sleep(1); } //i++; if (i==60) exit(1);}
|
||||||
|
|||||||
@@ -599,6 +599,7 @@ signalVector *modulateBurst(const BitVector &wBurst,
|
|||||||
modBurst.isRealOnly(true);
|
modBurst.isRealOnly(true);
|
||||||
//memset(staticBurst,0,sizeof(complex)*burstSize);
|
//memset(staticBurst,0,sizeof(complex)*burstSize);
|
||||||
modBurst.fill(0.0);
|
modBurst.fill(0.0);
|
||||||
|
//modBurst.fill(1.0);
|
||||||
signalVector::iterator modBurstItr = modBurst.begin();
|
signalVector::iterator modBurstItr = modBurst.begin();
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|||||||
Reference in New Issue
Block a user