aboutsummaryrefslogtreecommitdiffstats
path: root/Transceiver52M/Transceiver.cpp
diff options
context:
space:
mode:
authorThomas Tsou <tom@tsou.cc>2013-10-11 13:49:55 -0400
committerThomas Tsou <tom@tsou.cc>2013-10-18 13:10:17 -0400
commitc1f7c42a33a1125f8b39f53a1b6e1bae38376857 (patch)
treefd79543a262281b4cbf04bfb09f305b95a715dd4 /Transceiver52M/Transceiver.cpp
parent2c282f5e1268146761413a145fd8ae2fb523fa4f (diff)
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>
Diffstat (limited to 'Transceiver52M/Transceiver.cpp')
-rw-r--r--Transceiver52M/Transceiver.cpp35
1 files changed, 14 insertions, 21 deletions
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index 03aa3c1..2557fec 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -55,7 +55,8 @@ Transceiver::Transceiver(int wBasePort,
RadioInterface *wRadioInterface)
:mDataSocket(wBasePort+2,TRXAddress,wBasePort+102),
mControlSocket(wBasePort+1,TRXAddress,wBasePort+101),
- mClockSocket(wBasePort,TRXAddress,wBasePort+100)
+ mClockSocket(wBasePort,TRXAddress,wBasePort+100),
+ mSPSTx(wSPS), mSPSRx(1)
{
GSM::Time startTime(random() % gHyperframe,0);
@@ -64,7 +65,6 @@ Transceiver::Transceiver(int wBasePort,
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;
mTransmitDeadlineClock = startTime;
@@ -93,7 +93,7 @@ Transceiver::~Transceiver()
bool Transceiver::init()
{
- if (!sigProcLibSetup(mSPS)) {
+ if (!sigProcLibSetup(mSPSTx)) {
LOG(ALERT) << "Failed to initialize signal processing library";
return false;
}
@@ -102,7 +102,7 @@ bool Transceiver::init()
for (int i = 0; i < 8; i++) {
signalVector* modBurst = modulateBurst(gDummyBurst,
8 + (i % 4 == 0),
- mSPS);
+ mSPSTx);
if (!modBurst) {
sigProcLibDestroy();
LOG(ALERT) << "Failed to initialize filler table";
@@ -133,7 +133,7 @@ void Transceiver::addRadioVector(BitVector &burst,
// modulate and stick into queue
signalVector* modBurst = modulateBurst(burst,
8 + (wTime.TN() % 4 == 0),
- mSPS);
+ mSPSTx);
scaleVector(*modBurst,txFullScale * pow(10,-RSSI/10));
radioVector *newVec = new radioVector(*modBurst,wTime);
mTransmitPriorityQueue.write(newVec);
@@ -144,7 +144,7 @@ void Transceiver::addRadioVector(BitVector &burst,
#ifdef TRANSMIT_LOGGING
void Transceiver::unModulateVector(signalVector wVector)
{
- SoftVector *burst = demodulateBurst(wVector, mSPS, 1.0, 0.0);
+ SoftVector *burst = demodulateBurst(wVector, mSPSTx, 1.0, 0.0);
LOG(DEBUG) << "LOGGED BURST: " << *burst;
/*
@@ -329,7 +329,7 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime,
float TOA = 0.0;
float avgPwr = 0.0;
#ifdef ENERGY_DETECT
- if (!energyDetect(*vectorBurst, 20 * mSPS, mEnergyThreshold, &avgPwr)) {
+ if (!energyDetect(*vectorBurst, 20 * mSPSRx, mEnergyThreshold, &avgPwr)) {
LOG(DEBUG) << "Estimated Energy: " << sqrt(avgPwr) << ", at time " << rxBurst->getTime();
double framesElapsed = rxBurst->getTime()-prevFalseDetectionTime;
if (framesElapsed > 50) { // if we haven't had any false detections for a while, lower threshold
@@ -365,7 +365,7 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime,
success = analyzeTrafficBurst(*vectorBurst,
mTSC,
5.0,
- mSPS,
+ mSPSRx,
&amplitude,
&TOA,
mMaxExpectedDelay,
@@ -398,11 +398,7 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime,
}
else {
// RACH burst
- success = detectRACHBurst(*vectorBurst,
- 6.0,
- mSPS,
- &amplitude,
- &TOA);
+ success = detectRACHBurst(*vectorBurst, 6.0, mSPSRx, &amplitude, &TOA);
if (success) {
LOG(DEBUG) << "FOUND RACH!!!!!! " << amplitude << " " << TOA;
mEnergyThreshold -= (1.0F/10.0F);
@@ -421,22 +417,19 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime,
SoftVector *burst = NULL;
if ((rxBurst) && (success)) {
if ((corrType==RACH) || (!needDFE)) {
- burst = demodulateBurst(*vectorBurst,
- mSPS,
- amplitude,TOA);
- }
- else { // TSC
+ burst = demodulateBurst(*vectorBurst, mSPSRx, amplitude, TOA);
+ } else {
scaleVector(*vectorBurst,complex(1.0,0.0)/amplitude);
burst = equalizeBurst(*vectorBurst,
TOA-chanRespOffset[timeslot],
- mSPS,
+ mSPSRx,
*DFEForward[timeslot],
*DFEFeedback[timeslot]);
}
wTime = rxBurst->getTime();
RSSI = (int) floor(20.0*log10(rxFullScale/amplitude.abs()));
LOG(DEBUG) << "RSSI: " << RSSI;
- timingOffset = (int) round(TOA * 256.0 / mSPS);
+ timingOffset = (int) round(TOA * 256.0 / mSPSRx);
}
//if (burst) LOG(DEBUG) << "burst: " << *burst << '\n';
@@ -595,7 +588,7 @@ void Transceiver::driveControl()
sprintf(response,"RSP SETTSC 1 %d",TSC);
else {
mTSC = TSC;
- generateMidamble(mSPS, TSC);
+ generateMidamble(mSPSRx, TSC);
sprintf(response,"RSP SETTSC 0 %d", TSC);
}
}