laforge
/
openbts-osmo
Archived
1
0
Fork 0

transceiver: make the transmit drive loop bus dependent

With the introduction of the B100, there is USB support
using UHD devices. The characteristics of the trasmit
side burst submissions are more reflective of the bus
type than the device or driver.

Use a fixed latency interval for network devices and the
adaptive underrun approach for USB devices - regardless
of driver or device type.

The GPMC based transport on the E100 appears unaffected
by either latency scheme, which defaults to network.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
This commit is contained in:
Thomas Tsou 2011-10-07 15:24:31 -04:00
parent cdbfa6910f
commit eb10d9b31d
5 changed files with 58 additions and 25 deletions

View File

@ -714,27 +714,27 @@ void Transceiver::driveTransmitFIFO()
while (radioClock->get() + mTransmitLatency > mTransmitDeadlineClock) { while (radioClock->get() + mTransmitLatency > mTransmitDeadlineClock) {
// if underrun, then we're not providing bursts to radio/USRP fast // if underrun, then we're not providing bursts to radio/USRP fast
// enough. Need to increase latency by one GSM frame. // enough. Need to increase latency by one GSM frame.
#ifndef USE_UHD if (mRadioInterface->getBus() == RadioDevice::USB) {
if (mRadioInterface->isUnderrun()) { if (mRadioInterface->isUnderrun()) {
// only do latency update every 10 frames, so we don't over update // only do latency update every 10 frames, so we don't over update
if (radioClock->get() > mLatencyUpdateTime + GSM::Time(10,0)) { if (radioClock->get() > mLatencyUpdateTime + GSM::Time(10,0)) {
mTransmitLatency = mTransmitLatency + GSM::Time(1,0); mTransmitLatency = mTransmitLatency + GSM::Time(1,0);
LOG(INFO) << "new latency: " << mTransmitLatency; LOG(INFO) << "new latency: " << mTransmitLatency;
mLatencyUpdateTime = radioClock->get(); mLatencyUpdateTime = radioClock->get();
} }
}
else {
// if underrun hasn't occurred in the last sec (216 frames) drop
// transmit latency by a timeslot
if (mTransmitLatency > GSM::Time(1,1)) {
if (radioClock->get() > mLatencyUpdateTime + GSM::Time(216,0)) {
mTransmitLatency.decTN();
LOG(INFO) << "reduced latency: " << mTransmitLatency;
mLatencyUpdateTime = radioClock->get();
}
}
}
} }
else {
// if underrun hasn't occurred in the last sec (216 frames) drop
// transmit latency by a timeslot
if (mTransmitLatency > GSM::Time(1,1)) {
if (radioClock->get() > mLatencyUpdateTime + GSM::Time(216,0)) {
mTransmitLatency.decTN();
LOG(INFO) << "reduced latency: " << mTransmitLatency;
mLatencyUpdateTime = radioClock->get();
}
}
}
#endif
// time to push burst to transmit FIFO // time to push burst to transmit FIFO
pushRadioVector(mTransmitDeadlineClock); pushRadioVector(mTransmitDeadlineClock);
mTransmitDeadlineClock.incTN(); mTransmitDeadlineClock.incTN();

View File

@ -22,6 +22,7 @@
#include "radioDevice.h" #include "radioDevice.h"
#include "Threads.h" #include "Threads.h"
#include "Logger.h" #include "Logger.h"
#include <uhd/property_tree.hpp>
#include <uhd/usrp/single_usrp.hpp> #include <uhd/usrp/single_usrp.hpp>
#include <uhd/utils/thread_priority.hpp> #include <uhd/utils/thread_priority.hpp>
#include <uhd/utils/msg.hpp> #include <uhd/utils/msg.hpp>
@ -154,6 +155,7 @@ public:
bool stop(); bool stop();
void restart(uhd::time_spec_t ts); void restart(uhd::time_spec_t ts);
void setPriority(); void setPriority();
enum busType getBus() { return bus; }
int readSamples(short *buf, int len, bool *overrun, int readSamples(short *buf, int len, bool *overrun,
TIMESTAMP timestamp, bool *underrun, unsigned *RSSI); TIMESTAMP timestamp, bool *underrun, unsigned *RSSI);
@ -201,6 +203,7 @@ public:
private: private:
uhd::usrp::single_usrp::sptr usrp_dev; uhd::usrp::single_usrp::sptr usrp_dev;
enum busType bus;
double desired_smpl_rt, actual_smpl_rt; double desired_smpl_rt, actual_smpl_rt;
@ -373,22 +376,40 @@ double uhd_device::setRxGain(double db)
bool uhd_device::open() bool uhd_device::open()
{ {
LOG(INFO) << "creating USRP device..."; std::string dev_str;
uhd::property_tree::sptr prop_tree;
// Register msg handler // Register msg handler
uhd::msg::register_handler(&uhd_msg_handler); uhd::msg::register_handler(&uhd_msg_handler);
// Allow all UHD devices // Allow all UHD devices
LOG(INFO) << "Creating transceiver with first found UHD device";
uhd::device_addr_t dev_addr(""); uhd::device_addr_t dev_addr("");
try { try {
usrp_dev = uhd::usrp::single_usrp::make(dev_addr); usrp_dev = uhd::usrp::single_usrp::make(dev_addr);
} } catch(...) {
LOG(ERROR) << "UHD make failed";
catch(...) {
LOG(ERROR) << "USRP make failed";
return false; return false;
} }
// Set the device name and bus type
dev_str = usrp_dev->get_mboard_name();
LOG(NOTICE) << "Found " << dev_str;
prop_tree = usrp_dev->get_device()->get_tree();
dev_str = prop_tree->access<std::string>("/name").get();
size_t res1 = dev_str.find("B100");
size_t res2 = dev_str.find("B-Series");
if ((res1 != std::string::npos) || (res2 != std::string::npos)) {
bus = USB;
LOG(NOTICE) << "Using USB bus for " << dev_str;
} else {
bus = NET;
LOG(NOTICE) << "Using network bus for " << dev_str;
}
// Number of samples per over-the-wire packet // Number of samples per over-the-wire packet
tx_spp = usrp_dev->get_device()->get_max_send_samps_per_packet(); tx_spp = usrp_dev->get_device()->get_max_send_samps_per_packet();
rx_spp = usrp_dev->get_device()->get_max_recv_samps_per_packet(); rx_spp = usrp_dev->get_device()->get_max_recv_samps_per_packet();

View File

@ -136,6 +136,9 @@ private:
/** Set priority not supported */ /** Set priority not supported */
void setPriority() { return; } void setPriority() { return; }
/** Only USB bus supported */
busType getBus() { return USB; }
/** /**
Read samples from the USRP. Read samples from the USRP.
@param buf preallocated buf to contain read result @param buf preallocated buf to contain read result

View File

@ -37,6 +37,9 @@ typedef unsigned long long TIMESTAMP;
class RadioDevice { class RadioDevice {
public: public:
/* Available transport bus types */
enum busType { USB, NET };
static RadioDevice *make(double desiredSampleRate, bool skipRx = false); static RadioDevice *make(double desiredSampleRate, bool skipRx = false);
/** Initialize the USRP */ /** Initialize the USRP */
@ -48,6 +51,9 @@ class RadioDevice {
/** Stop the USRP */ /** Stop the USRP */
virtual bool stop()=0; virtual bool stop()=0;
/** Get the bus type */
virtual enum busType getBus()=0;
/** Enable thread priority */ /** Enable thread priority */
virtual void setPriority()=0; virtual void setPriority()=0;

View File

@ -140,6 +140,9 @@ public:
/** set thread priority on current thread */ /** set thread priority on current thread */
void setPriority() { mRadio->setPriority(); } void setPriority() { mRadio->setPriority(); }
/** get transport bus type of attached device */
enum RadioDevice::busType getBus() { return mRadio->getBus(); }
protected: protected:
/** drive synchronization of Tx/Rx of USRP */ /** drive synchronization of Tx/Rx of USRP */