From 1303376ad1af451a0487a9015372e2fd068194e2 Mon Sep 17 00:00:00 2001 From: Thomas Tsou Date: Mon, 6 Oct 2014 19:05:52 -0700 Subject: ms: Enable synchronized uplink bursts Extend the measured SCH timing offset from the downlink to the uplink path. In order to absorb the frame timing adjustment and remove the potential of thread contention during the change, combine the lower FIFO threads into single drive loop. Force timing changes through to the UHD interface with stream flags triggered through the updateAlignment() call. Signed-off-by: Thomas Tsou --- Transceiver52M/Transceiver.cpp | 32 +++++++++++--------------------- Transceiver52M/Transceiver.h | 10 +++------- Transceiver52M/UHDDevice.cpp | 4 +++- Transceiver52M/radioClock.cpp | 17 +++++++++++------ Transceiver52M/radioClock.h | 2 ++ Transceiver52M/radioInterface.cpp | 16 ++++++++++++++-- Transceiver52M/radioInterface.h | 3 ++- 7 files changed, 46 insertions(+), 38 deletions(-) (limited to 'Transceiver52M') diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp index 2d1690f..e5223b7 100644 --- a/Transceiver52M/Transceiver.cpp +++ b/Transceiver52M/Transceiver.cpp @@ -103,8 +103,7 @@ Transceiver::Transceiver(int wBasePort, { GSM::Time startTime(random() % gHyperframe,0); - mRxLowerLoopThread = new Thread(32768); - mTxLowerLoopThread = new Thread(32768); + mLowerLoopThread = new Thread(32768); mTransmitDeadlineClock = startTime; mLastClockUpdateTime = startTime; @@ -235,7 +234,7 @@ void Transceiver::pushRadioVector(GSM::Time &nowTime) radioVector *burst; TransceiverState *state; std::vector bursts(mChans); - std::vector zeros(mChans); + std::vector zeros(mChans, false); std::vector filler(mChans, true); for (size_t i = 0; i < mChans; i ++) { @@ -252,7 +251,8 @@ void Transceiver::pushRadioVector(GSM::Time &nowTime) modFN = nowTime.FN() % state->fillerModulus[TN]; bursts[i] = state->fillerTable[modFN][TN]; - zeros[i] = state->chanType[TN] == NONE; + if (state->mode == TRX_MODE_BTS) + zeros[i] = state->chanType[TN] == NONE; if ((burst = mTxPriorityQueues[i].getCurrentBurst(nowTime))) { bursts[i] = burst->getVector(); @@ -672,6 +672,9 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI, diff_time = GSM::Time(sch_time.FN() - burst_time.FN(), -burst_time.TN()); mRadioInterface->adjustClock(diff_time); + mTransmitDeadlineClock = RadioClock::adjust( + mTransmitDeadlineClock, + diff_time); state->mode = TRX_MODE_MS_TRACK; std::cout << "SCH : Locking GSM clock " << std::endl; @@ -763,10 +766,8 @@ void Transceiver::driveControl(size_t chan) mRadioInterface->start(); // Start radio interface threads. - mTxLowerLoopThread->start((void * (*)(void*)) - TxLowerLoopAdapter,(void*) this); - mRxLowerLoopThread->start((void * (*)(void*)) - RxLowerLoopAdapter,(void*) this); + mLowerLoopThread->start((void * (*)(void*)) + LowerLoopAdapter,(void*) this); for (size_t i = 0; i < mChans; i++) { TransceiverChannel *chan = new TransceiverChannel(this, i); @@ -1041,8 +1042,7 @@ void Transceiver::driveTxFIFO() } } // time to push burst to transmit FIFO - if (mStates[0].mode == TRX_MODE_BTS) - pushRadioVector(mTransmitDeadlineClock); + pushRadioVector(mTransmitDeadlineClock); mTransmitDeadlineClock.incTN(); } @@ -1083,22 +1083,12 @@ void *RxUpperLoopAdapter(TransceiverChannel *chan) return NULL; } -void *RxLowerLoopAdapter(Transceiver *transceiver) +void *LowerLoopAdapter(Transceiver *transceiver) { transceiver->setPriority(0.45); while (1) { transceiver->driveReceiveRadio(); - pthread_testcancel(); - } - return NULL; -} - -void *TxLowerLoopAdapter(Transceiver *transceiver) -{ - transceiver->setPriority(0.44); - - while (1) { transceiver->driveTxFIFO(); pthread_testcancel(); } diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h index f328fb9..d6a326e 100644 --- a/Transceiver52M/Transceiver.h +++ b/Transceiver52M/Transceiver.h @@ -106,8 +106,7 @@ private: std::vector mReceiveFIFO; ///< radioInterface FIFO of receive bursts std::vector mRxServiceLoopThreads; ///< thread to pull bursts into receive FIFO - Thread *mRxLowerLoopThread; ///< thread to pull bursts into receive FIFO - Thread *mTxLowerLoopThread; ///< thread to push bursts into transmit FIFO + Thread *mLowerLoopThread; ///< thread to pull bursts into receive FIFO std::vector mControlServiceLoopThreads; ///< thread to process control messages from GSM core std::vector mTxPriorityQueueServiceLoopThreads; ///< thread to process transmit bursts from GSM core @@ -273,9 +272,7 @@ protected: friend void *TxUpperLoopAdapter(TransceiverChannel *); - friend void *RxLowerLoopAdapter(Transceiver *); - - friend void *TxLowerLoopAdapter(Transceiver *); + friend void *LowerLoopAdapter(Transceiver *); friend void *ControlServiceLoopAdapter(TransceiverChannel *); @@ -290,8 +287,7 @@ protected: void *RxUpperLoopAdapter(TransceiverChannel *); /** Main drive threads */ -void *RxLowerLoopAdapter(Transceiver *); -void *TxLowerLoopAdapter(Transceiver *); +void *LowerLoopAdapter(Transceiver *); /** control message handler thread loop */ void *ControlServiceLoopAdapter(TransceiverChannel *); diff --git a/Transceiver52M/UHDDevice.cpp b/Transceiver52M/UHDDevice.cpp index 3b9012a..88f005f 100644 --- a/Transceiver52M/UHDDevice.cpp +++ b/Transceiver52M/UHDDevice.cpp @@ -1002,8 +1002,10 @@ int uhd_device::writeSamples(std::vector &bufs, int len, bool *underrun return num_smpls; } -bool uhd_device::updateAlignment(TIMESTAMP timestamp) +bool uhd_device::updateAlignment(TIMESTAMP) { + aligned = false; + return true; } diff --git a/Transceiver52M/radioClock.cpp b/Transceiver52M/radioClock.cpp index d9d5229..98eaf35 100644 --- a/Transceiver52M/radioClock.cpp +++ b/Transceiver52M/radioClock.cpp @@ -29,14 +29,12 @@ void RadioClock::set(const GSM::Time& wTime) mLock.unlock(); } -void RadioClock::adjust(GSM::Time& wOffset) +GSM::Time RadioClock::adjust(GSM::Time &wBase, GSM::Time &wOffset) { int tn_diff, fn_diff = 0; - mLock.lock(); - /* Modulo TN adustment */ - tn_diff = mClock.TN() + wOffset.TN(); + tn_diff = wBase.TN() + wOffset.TN(); if (tn_diff < 0) { tn_diff += 8; fn_diff--; @@ -46,13 +44,20 @@ void RadioClock::adjust(GSM::Time& wOffset) } /* Modulo FN adjustment */ - fn_diff += mClock.FN() + wOffset.FN(); + fn_diff += wBase.FN() + wOffset.FN(); if (fn_diff < 0) fn_diff += GSM::gHyperframe; else if ((unsigned) fn_diff >= GSM::gHyperframe) fn_diff = fn_diff - GSM::gHyperframe; - mClock = GSM::Time(fn_diff, tn_diff); + return GSM::Time(fn_diff, tn_diff); +} + +void RadioClock::adjust(GSM::Time& wOffset) +{ + mLock.lock(); + + mClock = adjust(mClock, wOffset); updateSignal.signal(); mLock.unlock(); diff --git a/Transceiver52M/radioClock.h b/Transceiver52M/radioClock.h index 4ce8416..af45125 100644 --- a/Transceiver52M/radioClock.h +++ b/Transceiver52M/radioClock.h @@ -26,6 +26,8 @@ class RadioClock { public: + static GSM::Time adjust(GSM::Time &base, GSM::Time &offset); + void set(const GSM::Time& wTime); void adjust(GSM::Time &wOffset); void incTN(); diff --git a/Transceiver52M/radioInterface.cpp b/Transceiver52M/radioInterface.cpp index 75266dd..3d91cd1 100644 --- a/Transceiver52M/radioInterface.cpp +++ b/Transceiver52M/radioInterface.cpp @@ -38,7 +38,8 @@ RadioInterface::RadioInterface(RadioDevice *wRadio, int wReceiveOffset, GSM::Time wStartTime) : mRadio(wRadio), mSPSTx(sps), mSPSRx(1), mChans(chans), mMIMO(diversity), sendCursor(0), recvCursor(0), underrun(false), overrun(false), - receiveOffset(wReceiveOffset), shiftOffset(0), mOn(false) + receiveOffset(wReceiveOffset), shiftOffset(0), shiftUpdate(false), + mOn(false) { mClock.set(wStartTime); } @@ -301,6 +302,12 @@ bool RadioInterface::isUnderrun() return retVal; } +void RadioInterface::applyOffset(int offset) +{ + shiftOffset += offset; + shiftUpdate = true; +} + VectorFIFO* RadioInterface::receiveFIFO(size_t chan) { if (chan >= mReceiveFIFO.size()) @@ -374,11 +381,16 @@ void RadioInterface::pushBuffer() powerScaling[i], 2 * sendCursor); } + if (shiftUpdate) { + mRadio->updateAlignment(0); + shiftUpdate = false; + } + /* Send the all samples in the send buffer */ num_sent = mRadio->writeSamples(convertSendBuffer, sendCursor, &underrun, - writeTimestamp); + writeTimestamp + mSPSTx * shiftOffset); writeTimestamp += num_sent; sendCursor = 0; } diff --git a/Transceiver52M/radioInterface.h b/Transceiver52M/radioInterface.h index ebf8f38..f1ff5ea 100644 --- a/Transceiver52M/radioInterface.h +++ b/Transceiver52M/radioInterface.h @@ -57,6 +57,7 @@ protected: int receiveOffset; ///< offset b/w transmit and receive GSM timestamps, in timeslots int shiftOffset; + bool shiftUpdate; bool mOn; ///< indicates radio is on private: @@ -94,7 +95,7 @@ public: /** check for underrun, resets underrun value */ bool isUnderrun(); - void applyOffset(int offset) { shiftOffset += offset; } + void applyOffset(int offset); /** return the receive FIFO */ VectorFIFO* receiveFIFO(size_t chan = 0); -- cgit v1.2.3