diff options
author | Thomas Tsou <tom@tsou.cc> | 2013-10-11 13:49:55 -0400 |
---|---|---|
committer | Thomas Tsou <tom@tsou.cc> | 2013-10-18 13:10:17 -0400 |
commit | c1f7c42a33a1125f8b39f53a1b6e1bae38376857 (patch) | |
tree | fd79543a262281b4cbf04bfb09f305b95a715dd4 /Transceiver52M/Transceiver.cpp | |
parent | 2c282f5e1268146761413a145fd8ae2fb523fa4f (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.cpp | 35 |
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, &litude, &TOA, mMaxExpectedDelay, @@ -398,11 +398,7 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, } else { // RACH burst - success = detectRACHBurst(*vectorBurst, - 6.0, - mSPS, - &litude, - &TOA); + success = detectRACHBurst(*vectorBurst, 6.0, mSPSRx, &litude, &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); } } |