aboutsummaryrefslogtreecommitdiffstats
path: root/Transceiver52M
diff options
context:
space:
mode:
Diffstat (limited to 'Transceiver52M')
-rw-r--r--Transceiver52M/Transceiver.cpp72
-rw-r--r--Transceiver52M/Transceiver.h3
-rw-r--r--Transceiver52M/sigProcLib.cpp135
-rw-r--r--Transceiver52M/sigProcLib.h17
4 files changed, 112 insertions, 115 deletions
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index b60496a..a7c629e 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -57,15 +57,12 @@ Transceiver::Transceiver(int wBasePort,
mControlSocket(wBasePort+1,TRXAddress,wBasePort+101),
mClockSocket(wBasePort,TRXAddress,wBasePort+100)
{
- //GSM::Time startTime(0,0);
- //GSM::Time startTime(gHyperframe/2 - 4*216*60,0);
GSM::Time startTime(random() % gHyperframe,0);
mFIFOServiceLoopThread = new Thread(32768); ///< thread to push bursts into transmit FIFO
mControlServiceLoopThread = new Thread(32768); ///< thread to process control messages from GSM core
mTransmitPriorityQueueServiceLoopThread = new Thread(32768);///< thread to process transmit bursts from GSM core
-
mSPS = wSPS;
mRadioInterface = wRadioInterface;
mTransmitLatency = wTransmitLatency;
@@ -75,54 +72,65 @@ Transceiver::Transceiver(int wBasePort,
mRadioInterface->getClock()->set(startTime);
mMaxExpectedDelay = 0;
- // generate pulse and setup up signal processing library
- gsmPulse = generateGSMPulse(2, mSPS);
- LOG(DEBUG) << "gsmPulse: " << *gsmPulse;
- sigProcLibSetup(mSPS);
-
txFullScale = mRadioInterface->fullScaleInputValue();
rxFullScale = mRadioInterface->fullScaleOutputValue();
- // initialize filler tables with dummy bursts, initialize other per-timeslot variables
+ mOn = false;
+ mTxFreq = 0.0;
+ mRxFreq = 0.0;
+ mPower = -10;
+ mEnergyThreshold = INIT_ENERGY_THRSHD;
+ prevFalseDetectionTime = startTime;
+
+}
+
+Transceiver::~Transceiver()
+{
+ sigProcLibDestroy();
+ mTransmitPriorityQueue.clear();
+}
+
+bool Transceiver::init()
+{
+ if (!sigProcLibSetup(mSPS)) {
+ LOG(ALERT) << "Failed to initialize signal processing library";
+ return false;
+ }
+
+ // initialize filler tables with dummy bursts
for (int i = 0; i < 8; i++) {
- signalVector* modBurst = modulateBurst(gDummyBurst,*gsmPulse,
+ signalVector* modBurst = modulateBurst(gDummyBurst,
8 + (i % 4 == 0),
mSPS);
+ if (!modBurst) {
+ sigProcLibDestroy();
+ LOG(ALERT) << "Failed to initialize filler table";
+ return false;
+ }
+
scaleVector(*modBurst,txFullScale);
fillerModulus[i]=26;
for (int j = 0; j < 102; j++) {
fillerTable[j][i] = new signalVector(*modBurst);
}
+
delete modBurst;
mChanType[i] = NONE;
channelResponse[i] = NULL;
DFEForward[i] = NULL;
DFEFeedback[i] = NULL;
- channelEstimateTime[i] = startTime;
+ channelEstimateTime[i] = mTransmitDeadlineClock;
}
- mOn = false;
- mTxFreq = 0.0;
- mRxFreq = 0.0;
- mPower = -10;
- mEnergyThreshold = INIT_ENERGY_THRSHD;
- prevFalseDetectionTime = startTime;
-}
-
-Transceiver::~Transceiver()
-{
- delete gsmPulse;
- sigProcLibDestroy();
- mTransmitPriorityQueue.clear();
+ return true;
}
-
void Transceiver::addRadioVector(BitVector &burst,
int RSSI,
GSM::Time &wTime)
{
// modulate and stick into queue
- signalVector* modBurst = modulateBurst(burst,*gsmPulse,
+ signalVector* modBurst = modulateBurst(burst,
8 + (wTime.TN() % 4 == 0),
mSPS);
scaleVector(*modBurst,txFullScale * pow(10,-RSSI/10));
@@ -135,10 +143,7 @@ void Transceiver::addRadioVector(BitVector &burst,
#ifdef TRANSMIT_LOGGING
void Transceiver::unModulateVector(signalVector wVector)
{
- SoftVector *burst = demodulateBurst(wVector,
- *gsmPulse,
- mSPS,
- 1.0,0.0);
+ SoftVector *burst = demodulateBurst(wVector, mSPS, 1.0, 0.0);
LOG(DEBUG) << "LOGGED BURST: " << *burst;
/*
@@ -415,7 +420,6 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime,
if ((rxBurst) && (success)) {
if ((corrType==RACH) || (!needDFE)) {
burst = demodulateBurst(*vectorBurst,
- *gsmPulse,
mSPS,
amplitude,TOA);
}
@@ -497,7 +501,7 @@ void Transceiver::driveControl()
// Prepare for thread start
mPower = -20;
mRadioInterface->start();
- generateRACHSequence(*gsmPulse, mSPS);
+ generateRACHSequence(mSPS);
// Start radio interface threads.
mFIFOServiceLoopThread->start((void * (*)(void*))FIFOServiceLoopAdapter,(void*) this);
@@ -589,8 +593,8 @@ void Transceiver::driveControl()
sprintf(response,"RSP SETTSC 1 %d",TSC);
else {
mTSC = TSC;
- generateMidamble(*gsmPulse, mSPS, TSC);
- sprintf(response,"RSP SETTSC 0 %d",TSC);
+ generateMidamble(mSPS, TSC);
+ sprintf(response,"RSP SETTSC 0 %d", TSC);
}
}
else if (strcmp(command,"SETSLOT")==0) {
diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h
index 91d92b2..3175213 100644
--- a/Transceiver52M/Transceiver.h
+++ b/Transceiver52M/Transceiver.h
@@ -124,8 +124,6 @@ private:
/** send messages over the clock socket */
void writeClockInterface(void);
- signalVector *gsmPulse; ///< the GSM shaping pulse for modulation
-
int mSPS; ///< number of samples per GSM symbol
bool mOn; ///< flag to indicate that transceiver is powered on
@@ -168,6 +166,7 @@ public:
/** start the Transceiver */
void start();
+ bool init();
/** attach the radioInterface receive FIFO */
void receiveFIFO(VectorFIFO *wFIFO) { mReceiveFIFO = wFIFO;}
diff --git a/Transceiver52M/sigProcLib.cpp b/Transceiver52M/sigProcLib.cpp
index b7f3511..ab605cf 100644
--- a/Transceiver52M/sigProcLib.cpp
+++ b/Transceiver52M/sigProcLib.cpp
@@ -58,8 +58,27 @@ typedef struct {
complex gain;
} CorrelationSequence;
+/*
+ * Gaussian and empty modulation pulses
+ */
+struct PulseSequence {
+ PulseSequence() : gaussian(NULL), empty(NULL)
+ {
+ }
+
+ ~PulseSequence()
+ {
+ delete gaussian;
+ delete empty;
+ }
+
+ signalVector *gaussian;
+ signalVector *empty;
+};
+
CorrelationSequence *gMidambles[] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
CorrelationSequence *gRACHSequence = NULL;
+PulseSequence *GSMPulse = NULL;
void sigProcLibDestroy(void) {
if (GMSKRotation) {
@@ -234,6 +253,7 @@ void sigProcLibSetup(int sps)
{
initTrigTables();
initGMSKRotationTables(sps);
+ generateGSMPulse(sps, 2);
}
void GMSKRotate(signalVector &x) {
@@ -439,25 +459,36 @@ signalVector* convolve(const signalVector *a,
}
-signalVector* generateGSMPulse(int sps, int symbolLength)
+void generateGSMPulse(int sps, int symbolLength)
{
+ int len;
+ float arg, center;
- int numSamples = sps * symbolLength + 1;
- signalVector *x = new signalVector(numSamples);
- signalVector::iterator xP = x->begin();
- int centerPoint = (numSamples-1)/2;
- for (int i = 0; i < numSamples; i++) {
- float arg = (float) (i - centerPoint) / (float) sps;
- *xP++ = 0.96*exp(-1.1380*arg*arg-0.527*arg*arg*arg*arg); // GSM pulse approx.
+ delete GSMPulse;
+
+ /* Store a single tap filter used for correlation sequence generation */
+ GSMPulse = new PulseSequence();
+ GSMPulse->empty = new signalVector(1);
+ GSMPulse->empty->isRealOnly(true);
+ *(GSMPulse->empty->begin()) = 1.0f;
+
+ /* GSM pulse approximation */
+ GSMPulse->gaussian = new signalVector(len);
+ GSMPulse->gaussian->isRealOnly(true);
+ signalVector::iterator xP = GSMPulse->gaussian->begin();
+
+ center = (float) (len - 1.0) / 2.0;
+
+ for (int i = 0; i < len; i++) {
+ arg = ((float) i - center) / (float) sps;
+ *xP++ = 0.96 * exp(-1.1380 * arg * arg -
+ 0.527 * arg * arg * arg * arg);
}
- float avgAbsval = sqrtf(vectorNorm2(*x) / sps);
- xP = x->begin();
- for (int i = 0; i < numSamples; i++)
+ float avgAbsval = sqrtf(vectorNorm2(*GSMPulse->gaussian)/sps);
+ xP = GSMPulse->gaussian->begin();
+ for (int i = 0; i < len; i++)
*xP++ /= avgAbsval;
- x->isRealOnly(true);
- x->setSymmetry(ABSSYM);
- return x;
}
signalVector* frequencyShift(signalVector *y,
@@ -564,36 +595,22 @@ bool vectorSlicer(signalVector *x)
return true;
}
-signalVector *modulateBurst(const BitVector &wBurst,
- const signalVector &gsmPulse,
- int guardPeriodLength,
- int sps)
+signalVector *modulateBurst(const BitVector &wBurst, int guardPeriodLength,
+ int sps, bool emptyPulse)
{
+ int burstLen;
+ signalVector *pulse, modBurst;
+ signalVector::iterator modBurstItr;
+
+ if (emptyPulse)
+ pulse = GSMPulse->empty;
+ else
+ pulse = GSMPulse->gaussian;
+
+ burstLen = sps * (wBurst.size() + guardPeriodLength);
+ modBurst = signalVector(burstLen);
+ modBurstItr = modBurst.begin();
- //static complex staticBurst[157];
-
- int burstSize = sps * (wBurst.size() + guardPeriodLength);
- //signalVector modBurst((complex *) staticBurst,0,burstSize);
- signalVector modBurst(burstSize);// = new signalVector(burstSize);
- modBurst.isRealOnly(true);
- //memset(staticBurst,0,sizeof(complex)*burstSize);
- modBurst.fill(0.0);
- signalVector::iterator modBurstItr = modBurst.begin();
-
-#if 0
- // if wBurst is already differentially decoded
- *modBurstItr = 2.0*(wBurst[0] & 0x01)-1.0;
- signalVector::iterator prevVal = modBurstItr;
- for (unsigned int i = 1; i < wBurst.size(); i++) {
- modBurstItr += sps;
- if (wBurst[i] & 0x01)
- *modBurstItr = *prevVal * complex(0.0,1.0);
- else
- *modBurstItr = *prevVal * complex(0.0,-1.0);
- prevVal = modBurstItr;
- }
-#else
- // if wBurst are the raw bits
for (unsigned int i = 0; i < wBurst.size(); i++) {
*modBurstItr = 2.0*(wBurst[i] & 0x01)-1.0;
modBurstItr += sps;
@@ -602,16 +619,13 @@ signalVector *modulateBurst(const BitVector &wBurst,
// shift up pi/2
// ignore starting phase, since spec allows for discontinuous phase
GMSKRotate(modBurst);
-#endif
+
modBurst.isRealOnly(false);
// filter w/ pulse shape
- signalVector *shapedBurst = convolve(&modBurst,&gsmPulse,NULL,NO_DELAY);
+ signalVector *shapedBurst = convolve(&modBurst, pulse, NULL, NO_DELAY);
- //delete modBurst;
-
return shapedBurst;
-
}
float sinc(float x)
@@ -837,11 +851,8 @@ void offsetVector(signalVector &x,
}
}
-bool generateMidamble(signalVector &gsmPulse,
- int sps,
- int TSC)
+bool generateMidamble(int sps, int TSC)
{
-
if ((TSC < 0) || (TSC > 7))
return false;
@@ -850,18 +861,13 @@ bool generateMidamble(signalVector &gsmPulse,
if (gMidambles[TSC]->sequenceReversedConjugated!=NULL) delete gMidambles[TSC]->sequenceReversedConjugated;
}
- signalVector emptyPulse(1);
- *(emptyPulse.begin()) = 1.0;
-
// only use middle 16 bits of each TSC
signalVector *middleMidamble = modulateBurst(gTrainingSequence[TSC].segment(5,16),
- emptyPulse,
0,
- sps);
+ sps, true);
signalVector *midamble = modulateBurst(gTrainingSequence[TSC],
- gsmPulse,
0,
- sps);
+ sps, false);
if (midamble == NULL) return false;
if (middleMidamble == NULL) return false;
@@ -895,17 +901,14 @@ bool generateMidamble(signalVector &gsmPulse,
return true;
}
-bool generateRACHSequence(signalVector &gsmPulse,
- int sps)
+bool generateRACHSequence(int sps)
{
-
if (gRACHSequence) {
if (gRACHSequence->sequence!=NULL) delete gRACHSequence->sequence;
if (gRACHSequence->sequenceReversedConjugated!=NULL) delete gRACHSequence->sequenceReversedConjugated;
}
signalVector *RACHSeq = modulateBurst(gRACHSynchSequence,
- gsmPulse,
0,
sps);
@@ -1136,12 +1139,8 @@ signalVector *decimateVector(signalVector &wVector,
}
-SoftVector *demodulateBurst(signalVector &rxBurst,
- const signalVector &gsmPulse,
- int sps,
- complex channel,
- float TOA)
-
+SoftVector *demodulateBurst(signalVector &rxBurst, int sps,
+ complex channel, float TOA)
{
scaleVector(rxBurst,((complex) 1.0)/channel);
delayVector(rxBurst,-TOA);
diff --git a/Transceiver52M/sigProcLib.h b/Transceiver52M/sigProcLib.h
index e91644c..a9fabb0 100644
--- a/Transceiver52M/sigProcLib.h
+++ b/Transceiver52M/sigProcLib.h
@@ -125,7 +125,7 @@ signalVector* convolve(const signalVector *a,
@param symbolLength The size of the pulse.
@return The GSM pulse.
*/
-signalVector* generateGSMPulse(int sps, int symbolLength);
+void generateGSMPulse(int sps, int symbolLength);
/**
Frequency shift a vector.
@@ -162,9 +162,8 @@ bool vectorSlicer(signalVector *x);
/** GMSK modulate a GSM burst of bits */
signalVector *modulateBurst(const BitVector &wBurst,
- const signalVector &gsmPulse,
int guardPeriodLength,
- int sps);
+ int sps, bool emptyPulse = false);
/** Sinc function */
float sinc(float x);
@@ -229,15 +228,14 @@ void offsetVector(signalVector &x,
@param TSC The training sequence [0..7]
@return Success.
*/
-bool generateMidamble(signalVector &gsmPulse, int sps, int tsc);
+bool generateMidamble(int sps, int tsc);
/**
Generate a modulated RACH sequence, stored within the library.
@param gsmPulse The GSM pulse used for modulation.
@param sps The number of samples per GSM symbol.
@return Success.
*/
-bool generateRACHSequence(signalVector &gsmPulse,
- int sps);
+bool generateRACHSequence(int sps);
/**
Energy detector, checks to see if received burst energy is above a threshold.
@@ -310,11 +308,8 @@ signalVector *decimateVector(signalVector &wVector,
@param TOA The time-of-arrival of the received burst.
@return The demodulated bit sequence.
*/
-SoftVector *demodulateBurst(signalVector &rxBurst,
- const signalVector &gsmPulse,
- int sps,
- complex channel,
- float TOA);
+SoftVector *demodulateBurst(signalVector &rxBurst, int sps,
+ complex channel, float TOA);
/**
Creates a simple Kaiser-windowed low-pass FIR filter.