You can subscribe to this list here.
| 2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(81) |
Dec
(12) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2012 |
Jan
(19) |
Feb
(20) |
Mar
(12) |
Apr
(2) |
May
(6) |
Jun
(10) |
Jul
(7) |
Aug
(5) |
Sep
(10) |
Oct
(15) |
Nov
(28) |
Dec
(25) |
| 2013 |
Jan
(1) |
Feb
(13) |
Mar
(3) |
Apr
(1) |
May
(10) |
Jun
(21) |
Jul
(12) |
Aug
(54) |
Sep
(40) |
Oct
(51) |
Nov
(1) |
Dec
(2) |
| 2014 |
Jan
(1) |
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <do_...@wu...> - 2014-02-13 21:00:29
|
Author: ttsou Date: 2014-02-13 15:00:22 -0600 (Thu, 13 Feb 2014) New Revision: 7530 Modified: software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp Log: Transceiver52M: Set B2XX clock frequency to 26 MHz Change from the original USRP1 rate of 52 MHz. On B2XX we can use 26 MHz, which is closer to the default 32 MHz of the device. Signed-off-by: Thomas Tsou <to...@ts...> Modified: software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp =================================================================== --- software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2014-02-13 19:11:00 UTC (rev 7529) +++ software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2014-02-13 21:00:22 UTC (rev 7530) @@ -32,7 +32,7 @@ #include "config.h" #endif -#define B2XX_CLK_RT 52e6 +#define B2XX_CLK_RT 26e6 #define B2XX_BASE_RT GSMRATE #define B100_BASE_RT 400000 #define USRP2_BASE_RT 390625 |
|
From: <do_...@wu...> - 2014-01-14 02:30:02
|
Author: hsamra
Date: 2014-01-13 20:29:55 -0600 (Mon, 13 Jan 2014)
New Revision: 7258
Modified:
software/public/openbts/trunk/TransceiverRAD1/radioInterface.cpp
Log:
Fix incorrect buffer management in send and rcv buffering.
Modified: software/public/openbts/trunk/TransceiverRAD1/radioInterface.cpp
===================================================================
--- software/public/openbts/trunk/TransceiverRAD1/radioInterface.cpp 2014-01-14 02:19:54 UTC (rev 7257)
+++ software/public/openbts/trunk/TransceiverRAD1/radioInterface.cpp 2014-01-14 02:29:55 UTC (rev 7258)
@@ -170,7 +170,7 @@
writeTimestamp += (TIMESTAMP) samplesWritten;
if (sendCursor > 2*samplesWritten)
- memcpy(sendBuffer,sendBuffer+samplesWritten*2,sizeof(short)*2*(sendCursor-2*samplesWritten));
+ memcpy(sendBuffer,sendBuffer+samplesWritten*2,sizeof(short)*(sendCursor-2*samplesWritten));
sendCursor = sendCursor - 2*samplesWritten;
}
@@ -338,7 +338,7 @@
}
if (readSz > 0) {
- memcpy(rcvBuffer,rcvBuffer+2*readSz,sizeof(short)*2*(rcvCursor-readSz));
+ memcpy(rcvBuffer,rcvBuffer+2*readSz,sizeof(short)*(rcvCursor-2*readSz));
rcvCursor = rcvCursor-2*readSz;
}
}
|
|
From: <do_...@wu...> - 2013-12-31 19:55:24
|
Author: kurtis.heimerl
Date: 2013-12-31 13:55:16 -0600 (Tue, 31 Dec 2013)
New Revision: 7155
Modified:
software/public/CommonLibs/trunk/Configuration.cpp
Log:
allow EGSM
Modified: software/public/CommonLibs/trunk/Configuration.cpp
===================================================================
--- software/public/CommonLibs/trunk/Configuration.cpp 2013-12-31 00:44:10 UTC (rev 7154)
+++ software/public/CommonLibs/trunk/Configuration.cpp 2013-12-31 19:55:16 UTC (rev 7155)
@@ -959,14 +959,16 @@
uplink += 0.2;
}
- // 1:124 PGSM900
- downlink = 935.2;
- uplink = 890.2;
- for (i = 1; i <= 124; i++) {
- ss << i << "|PGSM900 #" << i << " : " << downlink << " MHz downlink / " << uplink << " MHz uplink,";
- downlink += 0.2;
- uplink += 0.2;
+ // 0:124 EGSM900
+ downlink = 935.0;
+ uplink = 890.0;
+ for (i = 0; i <= 124; i++) {
+ ss << i << "|PGSM900 #" << i << " : " << (downlink + (0.2*i)) << " MHz downlink / " << (uplink + (0.2*i)) << " MHz uplink,";
}
+ // 975:1023 EGSM900
+ for (i = 975; i <= 1023 ; i++) {
+ ss << i << "|PGSM900 #" << i << " : " << (downlink + (0.2*i)) << " MHz downlink / " << (uplink + (0.2*i)) << " MHz uplink,";
+ }
// 512:885 DCS1800
downlink = 1805.2;
|
|
From: <do_...@wu...> - 2013-12-31 00:44:17
|
Author: kurtis.heimerl Date: 2013-12-30 18:44:10 -0600 (Mon, 30 Dec 2013) New Revision: 7154 Modified: software/public/openbts/trunk/SIP/SIPEngine.cpp Log: Fixes handover assert. Basically, an earlier patch changed the RTP packet size. Modified: software/public/openbts/trunk/SIP/SIPEngine.cpp =================================================================== --- software/public/openbts/trunk/SIP/SIPEngine.cpp 2013-12-30 22:35:42 UTC (rev 7153) +++ software/public/openbts/trunk/SIP/SIPEngine.cpp 2013-12-31 00:44:10 UTC (rev 7154) @@ -1635,7 +1635,7 @@ RTPState.push_back(strtol(thisItem,NULL,10)); } free(items); - assert(RTPState.size() == 22); + assert(RTPState.size() == 19); /* Out of desperation, when the RTP refused to work, I transferred from BS1 to BS2 just about * all the state in this struct. Well, it turns out NONE of it is necessary. Something else * entirely was the problem. (Or, technically, state in a different struct.) Anyway, I'm |
|
From: <do_...@wu...> - 2013-11-08 04:11:36
|
Author: ttsou
Date: 2013-11-07 22:11:28 -0600 (Thu, 07 Nov 2013)
New Revision: 6844
Modified:
software/public/openbts/trunk/Transceiver52M/convert.c
Log:
Transceiver52M: Fix SSE preprocessor definition
Using non-SSE4.1 enabled architecture would cause undefined
reference to 'convert_si16_ps' call.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/convert.c
===================================================================
--- software/public/openbts/trunk/Transceiver52M/convert.c 2013-11-08 01:19:37 UTC (rev 6843)
+++ software/public/openbts/trunk/Transceiver52M/convert.c 2013-11-08 04:11:28 UTC (rev 6844)
@@ -164,7 +164,7 @@
}
#endif
-#ifndef HAVE_SSE_4_1
+#ifndef HAVE_SSE4_1
static void convert_si16_ps(float *out, short *in, int len)
{
for (int i = 0; i < len; i++)
|
|
From: <do_...@wu...> - 2013-10-25 14:42:07
|
Author: ttsou
Date: 2013-10-25 09:42:00 -0500 (Fri, 25 Oct 2013)
New Revision: 6817
Modified:
software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
Log:
Transceiver52M: Reset overrun and underrun indicators
Underruns are only explicitly set on the downlink side. Overruns
are logged but unused. In either case, reset indicators to false
to avoid sending false state information.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-24 23:02:20 UTC (rev 6816)
+++ software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-25 14:42:00 UTC (rev 6817)
@@ -727,6 +727,9 @@
if (skip_rx)
return 0;
+ *overrun = false;
+ *underrun = false;
+
// Shift read time with respect to transmit clock
timestamp += ts_offset;
@@ -801,6 +804,8 @@
metadata.end_of_burst = false;
metadata.time_spec = convert_time(timestamp, tx_rate);
+ *underrun = false;
+
// No control packets
if (isControl) {
LOG(ERR) << "Control packets not supported";
|
|
From: <do_...@wu...> - 2013-10-18 15:00:04
|
Author: ttsou
Date: 2013-10-18 09:59:57 -0500 (Fri, 18 Oct 2013)
New Revision: 6761
Modified:
software/public/openbts/trunk/Transceiver52M/Transceiver.cpp
Log:
Transceiver52M: Update RSSI calculation
Use the same measurement method for RSSI as the noise level. Previous
method was to use the peak correlation amplitude relative to the
expected value. This created two very different amplitude approaches
between the noise measurement and RSSI measurement, which would
throw off the upper layer MS power control loop.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/Transceiver.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/Transceiver.cpp 2013-10-18 09:23:42 UTC (rev 6760)
+++ software/public/openbts/trunk/Transceiver52M/Transceiver.cpp 2013-10-18 14:59:57 UTC (rev 6761)
@@ -351,6 +351,7 @@
// Update noise level
mNoiseLev = mNoises.avg();
+ avg = sqrt(avg);
// run the proper correlator
if (corrType==TSC) {
@@ -394,7 +395,7 @@
}
else {
channelResponse[timeslot] = NULL;
- mNoises.insert(sqrt(avg));
+ mNoises.insert(avg);
}
}
else {
@@ -402,7 +403,7 @@
if (success = detectRACHBurst(*vectorBurst, 6.0, mSPSRx, &litude, &TOA))
channelResponse[timeslot] = NULL;
else
- mNoises.insert(sqrt(avg));
+ mNoises.insert(avg);
}
// demodulate burst
@@ -419,7 +420,7 @@
*DFEFeedback[timeslot]);
}
wTime = rxBurst->getTime();
- RSSI = (int) floor(20.0*log10(rxFullScale/amplitude.abs()));
+ RSSI = (int) floor(20.0*log10(rxFullScale/avg));
LOG(DEBUG) << "RSSI: " << RSSI;
timingOffset = (int) round(TOA * 256.0 / mSPSRx);
}
|
|
From: <do_...@wu...> - 2013-10-18 07:21:47
|
Author: kurtis.heimerl
Date: 2013-10-18 02:21:40 -0500 (Fri, 18 Oct 2013)
New Revision: 6759
Modified:
software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp
software/public/openbts/trunk/TransceiverRAD1/runTransceiver.cpp
software/public/openbts/trunk/apps/OpenBTS.cpp
Log:
small bug fixes from last patch
Modified: software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp 2013-10-18 06:51:25 UTC (rev 6758)
+++ software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp 2013-10-18 07:21:40 UTC (rev 6759)
@@ -50,7 +50,7 @@
std::vector<std::string> configurationCrossCheck(const std::string& key);
static const char *cOpenBTSConfigEnv = "OpenBTSConfigFile";
// Load configuration from a file.
-ConfigurationTable gConfig(getenv(cOpenBTSConfigEnv)?getenv(cOpenBTSConfigEnv):CONFIGDB,"OpenBTS", getConfigurationKeys());
+ConfigurationTable gConfig(getenv(cOpenBTSConfigEnv)?getenv(cOpenBTSConfigEnv):CONFIGDB,"transceiver", getConfigurationKeys());
volatile bool gbShutdown = false;
Modified: software/public/openbts/trunk/TransceiverRAD1/runTransceiver.cpp
===================================================================
--- software/public/openbts/trunk/TransceiverRAD1/runTransceiver.cpp 2013-10-18 06:51:25 UTC (rev 6758)
+++ software/public/openbts/trunk/TransceiverRAD1/runTransceiver.cpp 2013-10-18 07:21:40 UTC (rev 6759)
@@ -33,7 +33,7 @@
std::vector<std::string> configurationCrossCheck(const std::string& key);
static const char *cOpenBTSConfigEnv = "OpenBTSConfigFile";
// Load configuration from a file.
-ConfigurationTable gConfig(getenv(cOpenBTSConfigEnv)?getenv(cOpenBTSConfigEnv):"/etc/OpenBTS/OpenBTS.db","OpenBTS", getConfigurationKeys());
+ConfigurationTable gConfig(getenv(cOpenBTSConfigEnv)?getenv(cOpenBTSConfigEnv):"/etc/OpenBTS/OpenBTS.db","transceiver", getConfigurationKeys());
FactoryCalibration gFactoryCalibration;
volatile bool gbShutdown = false;
Modified: software/public/openbts/trunk/apps/OpenBTS.cpp
===================================================================
--- software/public/openbts/trunk/apps/OpenBTS.cpp 2013-10-18 06:51:25 UTC (rev 6758)
+++ software/public/openbts/trunk/apps/OpenBTS.cpp 2013-10-18 07:21:40 UTC (rev 6759)
@@ -130,9 +130,12 @@
void startTransceiver()
{
- // kill any stray transceiver process
- //don't do this if we want to run two of them -kurtis
- if (system("killall transceiver 2>/dev/null")) {}
+ //if local kill the process currently listening on this port
+ char killCmd[32];
+ if (gConfig.getStr("TRX.IP") == "127.0.0.1"){
+ sprintf(killCmd,"fuser -k -n udp %d",(int)gConfig.getNum("TRX.Port"));
+ if (system(killCmd)) {}
+ }
// Start the transceiver binary, if the path is defined.
// If the path is not defined, the transceiver must be started by some other process.
|
|
From: <do_...@wu...> - 2013-10-18 06:10:31
|
Author: kurtis.heimerl
Date: 2013-10-18 01:10:23 -0500 (Fri, 18 Oct 2013)
New Revision: 6757
Modified:
software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp
software/public/openbts/trunk/TransceiverRAD1/FactoryCalibration.cpp
software/public/openbts/trunk/TransceiverRAD1/FactoryCalibration.h
software/public/openbts/trunk/TransceiverRAD1/RAD1Device.cpp
software/public/openbts/trunk/TransceiverRAD1/RAD1Device.h
software/public/openbts/trunk/TransceiverRAD1/RAD1RxRawPower.cpp
software/public/openbts/trunk/TransceiverRAD1/RAD1RxRawPowerSweep.cpp
software/public/openbts/trunk/TransceiverRAD1/RAD1ping.cpp
software/public/openbts/trunk/TransceiverRAD1/runTransceiver.cpp
software/public/openbts/trunk/apps/GetConfigurationKeys.cpp
software/public/openbts/trunk/apps/OpenBTS.cpp
software/public/openbts/trunk/apps/OpenBTS.example.sql
Log:
Patching cleaning up rotted code. Now able to select device to run for both 52M and RAD1 from a config variable. Also fixed RAD1 not listening to TRX.Port or TRX.IP.
Modified: software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp 2013-10-18 05:01:17 UTC (rev 6756)
+++ software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp 2013-10-18 06:10:23 UTC (rev 6757)
@@ -47,8 +47,10 @@
*/
#define SPS 4
-ConfigurationKeyMap getConfigurationKeys();
-ConfigurationTable gConfig(CONFIGDB, 0, getConfigurationKeys());
+std::vector<std::string> configurationCrossCheck(const std::string& key);
+static const char *cOpenBTSConfigEnv = "OpenBTSConfigFile";
+// Load configuration from a file.
+ConfigurationTable gConfig(getenv(cOpenBTSConfigEnv)?getenv(cOpenBTSConfigEnv):CONFIGDB,"OpenBTS", getConfigurationKeys());
volatile bool gbShutdown = false;
@@ -131,7 +133,7 @@
}
// Configure logger.
- if (testConfig(CONFIGDB) < 0) {
+ if (testConfig(getenv(cOpenBTSConfigEnv)?getenv(cOpenBTSConfigEnv):CONFIGDB) < 0) {
std::cerr << "Config: Database failure" << std::endl;
return EXIT_FAILURE;
}
Modified: software/public/openbts/trunk/TransceiverRAD1/FactoryCalibration.cpp
===================================================================
--- software/public/openbts/trunk/TransceiverRAD1/FactoryCalibration.cpp 2013-10-18 05:01:17 UTC (rev 6756)
+++ software/public/openbts/trunk/TransceiverRAD1/FactoryCalibration.cpp 2013-10-18 06:10:23 UTC (rev 6757)
@@ -151,10 +151,10 @@
}
}
-void FactoryCalibration::readEEPROM() {
+void FactoryCalibration::readEEPROM(int deviceID) {
core = new rnrad1Core(
- 0,
+ deviceID,
RAD1_CMD_INTERFACE,
RAD1_CMD_ALTINTERFACE,
"fpga.rbf",
Modified: software/public/openbts/trunk/TransceiverRAD1/FactoryCalibration.h
===================================================================
--- software/public/openbts/trunk/TransceiverRAD1/FactoryCalibration.h 2013-10-18 05:01:17 UTC (rev 6756)
+++ software/public/openbts/trunk/TransceiverRAD1/FactoryCalibration.h 2013-10-18 06:10:23 UTC (rev 6757)
@@ -41,5 +41,5 @@
public:
unsigned int getValue(std::string name);
- void readEEPROM();
+ void readEEPROM(int deviceID);
};
Modified: software/public/openbts/trunk/TransceiverRAD1/RAD1Device.cpp
===================================================================
--- software/public/openbts/trunk/TransceiverRAD1/RAD1Device.cpp 2013-10-18 05:01:17 UTC (rev 6756)
+++ software/public/openbts/trunk/TransceiverRAD1/RAD1Device.cpp 2013-10-18 06:10:23 UTC (rev 6757)
@@ -180,7 +180,7 @@
#endif
}
-bool RAD1Device::make(bool wSkipRx)
+bool RAD1Device::make(bool wSkipRx, int devID)
{
skipRx = wSkipRx;
@@ -192,7 +192,7 @@
//string rbf = "inband_1rxhb_1tx.rbf";
if (!skipRx) {
try {
- m_uRx = rnrad1Rx::make(0,decimRate,
+ m_uRx = rnrad1Rx::make(devID,decimRate,
rbf,"ezusb.ihx");
m_uRx->setFpgaMasterClockFreq(masterClockRate);
}
@@ -220,7 +220,7 @@
}
try {
- m_uTx = rnrad1Tx::make(0,decimRate*2,
+ m_uTx = rnrad1Tx::make(devID,decimRate*2,
rbf,"ezusb.ihx");
m_uTx->setFpgaMasterClockFreq(masterClockRate);
}
Modified: software/public/openbts/trunk/TransceiverRAD1/RAD1Device.h
===================================================================
--- software/public/openbts/trunk/TransceiverRAD1/RAD1Device.h 2013-10-18 05:01:17 UTC (rev 6756)
+++ software/public/openbts/trunk/TransceiverRAD1/RAD1Device.h 2013-10-18 06:10:23 UTC (rev 6757)
@@ -168,7 +168,7 @@
RAD1Device (double _desiredSampleRate);
/** Instantiate the USRP */
- bool make(bool skipRx = false);
+ bool make(bool skipRx, int devID);
/** Start the USRP */
bool start();
Modified: software/public/openbts/trunk/TransceiverRAD1/RAD1RxRawPower.cpp
===================================================================
--- software/public/openbts/trunk/TransceiverRAD1/RAD1RxRawPower.cpp 2013-10-18 05:01:17 UTC (rev 6756)
+++ software/public/openbts/trunk/TransceiverRAD1/RAD1RxRawPower.cpp 2013-10-18 06:10:23 UTC (rev 6757)
@@ -45,7 +45,7 @@
RAD1Device *usrp = new RAD1Device(52.0e6/192.0);
- usrp->make();
+ usrp->make(false, 0);
double freqkHz = 0.0;
if (argc > 2) freqkHz = (double) atoi(argv[2]);
Modified: software/public/openbts/trunk/TransceiverRAD1/RAD1RxRawPowerSweep.cpp
===================================================================
--- software/public/openbts/trunk/TransceiverRAD1/RAD1RxRawPowerSweep.cpp 2013-10-18 05:01:17 UTC (rev 6756)
+++ software/public/openbts/trunk/TransceiverRAD1/RAD1RxRawPowerSweep.cpp 2013-10-18 06:10:23 UTC (rev 6757)
@@ -45,7 +45,7 @@
RAD1Device *usrp = new RAD1Device(52.0e6/192.0);
- usrp->make();
+ usrp->make(false, 0);
double startFreqkHz = 0.0;
double endFreqkHz = 0.0;
Modified: software/public/openbts/trunk/TransceiverRAD1/RAD1ping.cpp
===================================================================
--- software/public/openbts/trunk/TransceiverRAD1/RAD1ping.cpp 2013-10-18 05:01:17 UTC (rev 6756)
+++ software/public/openbts/trunk/TransceiverRAD1/RAD1ping.cpp 2013-10-18 06:10:23 UTC (rev 6757)
@@ -40,6 +40,9 @@
if (argc>1) gLogInit(argv[1]);
else gLogInit("DEBUG");
+ int deviceID = 0;
+ if (argc>2) deviceID = atoi(argv[2]);
+
gLogInit("openbts",argv[1],LOG_LOCAL7);
@@ -47,7 +50,7 @@
RAD1Device *usrp = new RAD1Device(52.0e6/192.0);
- usrp->make();
+ usrp->make(false, deviceID);
TIMESTAMP timestamp;
Modified: software/public/openbts/trunk/TransceiverRAD1/runTransceiver.cpp
===================================================================
--- software/public/openbts/trunk/TransceiverRAD1/runTransceiver.cpp 2013-10-18 05:01:17 UTC (rev 6756)
+++ software/public/openbts/trunk/TransceiverRAD1/runTransceiver.cpp 2013-10-18 06:10:23 UTC (rev 6757)
@@ -30,8 +30,10 @@
using namespace std;
-ConfigurationKeyMap getConfigurationKeys();
-ConfigurationTable gConfig("/etc/OpenBTS/OpenBTS.db", 0, getConfigurationKeys());
+std::vector<std::string> configurationCrossCheck(const std::string& key);
+static const char *cOpenBTSConfigEnv = "OpenBTSConfigFile";
+// Load configuration from a file.
+ConfigurationTable gConfig(getenv(cOpenBTSConfigEnv)?getenv(cOpenBTSConfigEnv):"/etc/OpenBTS/OpenBTS.db","OpenBTS", getConfigurationKeys());
FactoryCalibration gFactoryCalibration;
volatile bool gbShutdown = false;
@@ -58,15 +60,15 @@
// Configure logger.
gLogInit("transceiver",gConfig.getStr("Log.Level").c_str(),LOG_LOCAL7);
- gFactoryCalibration.readEEPROM();
-
int numARFCN=1;
if (argc>1) numARFCN = atoi(argv[1]);
-#ifdef SINGLEARFCN
- numARFCN=1;
-#endif
+ int deviceID = 0;
+ if (argc>2) deviceID = atoi(argv[2]);
+ gFactoryCalibration.readEEPROM(deviceID);
+
+
srandom(time(NULL));
int mOversamplingRate = 1;
@@ -95,10 +97,10 @@
//if ((numARFCN > 1) && (mOversamplingRate % 2)) mOversamplingRate++;
RAD1Device *usrp = new RAD1Device(mOversamplingRate*1625.0e3/6.0);
//DummyLoad *usrp = new DummyLoad(mOversamplingRate*1625.0e3/6.0);
- usrp->make();
+ usrp->make(false, deviceID);
RadioInterface* radio = new RadioInterface(usrp,3,SAMPSPERSYM,mOversamplingRate,false,numARFCN);
- Transceiver *trx = new Transceiver(5700,"127.0.0.1",SAMPSPERSYM,GSM::Time(2,0),radio,
+ Transceiver *trx = new Transceiver(gConfig.getNum("TRX.Port"),gConfig.getStr("TRX.IP").c_str(),SAMPSPERSYM,GSM::Time(2,0),radio,
numARFCN,mOversamplingRate,false);
trx->receiveFIFO(radio->receiveFIFO());
Modified: software/public/openbts/trunk/apps/GetConfigurationKeys.cpp
===================================================================
--- software/public/openbts/trunk/apps/GetConfigurationKeys.cpp 2013-10-18 05:01:17 UTC (rev 6756)
+++ software/public/openbts/trunk/apps/GetConfigurationKeys.cpp 2013-10-18 06:10:23 UTC (rev 6757)
@@ -2713,6 +2713,18 @@
map[tmp->getName()] = *tmp;
delete tmp;
+ //kurtis
+ tmp = new ConfigurationKey("TRX.Args","",
+ "",
+ ConfigurationKey::CUSTOMER,
+ ConfigurationKey::STRING,
+ "",
+ false,
+ "Extra arguments for the Transceiver"
+ );
+ map[tmp->getName()] = *tmp;
+ delete tmp;
+
tmp = new ConfigurationKey("Test.GSM.SimulatedFER.Downlink","0",
"probability in %",
ConfigurationKey::DEVELOPER,
Modified: software/public/openbts/trunk/apps/OpenBTS.cpp
===================================================================
--- software/public/openbts/trunk/apps/OpenBTS.cpp 2013-10-18 05:01:17 UTC (rev 6756)
+++ software/public/openbts/trunk/apps/OpenBTS.cpp 2013-10-18 06:10:23 UTC (rev 6757)
@@ -131,18 +131,20 @@
void startTransceiver()
{
// kill any stray transceiver process
+ //don't do this if we want to run two of them -kurtis
if (system("killall transceiver 2>/dev/null")) {}
// Start the transceiver binary, if the path is defined.
// If the path is not defined, the transceiver must be started by some other process.
char TRXnumARFCN[4];
sprintf(TRXnumARFCN,"%1d",(int)gConfig.getNum("GSM.Radio.ARFCNs"));
- LOG(NOTICE) << "starting transceiver " << transceiverPath << " " << TRXnumARFCN;
+ std::string extra_args = gConfig.getStr("TRX.Args");
+ LOG(NOTICE) << "starting transceiver " << transceiverPath << " w/ " << TRXnumARFCN << " ARFCNs and Args:" << extra_args;
gTransceiverPid = vfork();
LOG_ASSERT(gTransceiverPid>=0);
if (gTransceiverPid==0) {
// Pid==0 means this is the process that starts the transceiver.
- execlp(transceiverPath,transceiverPath,TRXnumARFCN,(void*)NULL);
+ execlp(transceiverPath,transceiverPath,TRXnumARFCN,extra_args.c_str(),(void*)NULL);
LOG(EMERG) << "cannot find " << transceiverPath;
_exit(1);
} else {
Modified: software/public/openbts/trunk/apps/OpenBTS.example.sql
===================================================================
--- software/public/openbts/trunk/apps/OpenBTS.example.sql 2013-10-18 05:01:17 UTC (rev 6756)
+++ software/public/openbts/trunk/apps/OpenBTS.example.sql 2013-10-18 06:10:23 UTC (rev 6757)
@@ -225,6 +225,7 @@
INSERT OR IGNORE INTO "CONFIG" VALUES('TRX.Timeout.Clock','10',0,0,'How long to wait during a read operation from the transceiver before giving up.');
INSERT OR IGNORE INTO "CONFIG" VALUES('TRX.Timeout.Start','2',0,0,'How long to wait during system startup before checking to see if the transceiver can be reached.');
INSERT OR IGNORE INTO "CONFIG" VALUES('TRX.TxAttenOffset','0',1,0,'Hardware-specific gain adjustment for transmitter, matched to the power amplifier, expessed as an attenuationi in dB. Set at the factory. Do not adjust without proper calibration. Static.');
+INSERT OR IGNORE INTO "CONFIG" VALUES('TRX.Args','',1,0,'Extra arguments for the Transceiver');
INSERT OR IGNORE INTO "CONFIG" VALUES('Test.GSM.SimulatedFER.Downlink','0',1,0,'Probability (0-100) of dropping any downlink frame to test robustness. Static.');
INSERT OR IGNORE INTO "CONFIG" VALUES('Test.GSM.SimulatedFER.Uplink','0',1,0,'Probability (0-100) of dropping any uplink frame to test robustness. Static.');
INSERT OR IGNORE INTO "CONFIG" VALUES('Test.GSM.UplinkFuzzingRate','0',1,0,'Probability (0-100) of flipping a bit in any uplink frame to test robustness. Static.');
|
|
From: <do_...@wu...> - 2013-10-18 01:45:49
|
Author: ttsou
Date: 2013-10-17 20:45:41 -0500 (Thu, 17 Oct 2013)
New Revision: 6755
Modified:
software/public/openbts/trunk/Transceiver52M/Transceiver.cpp
software/public/openbts/trunk/Transceiver52M/Transceiver.h
software/public/openbts/trunk/Transceiver52M/radioVector.cpp
software/public/openbts/trunk/Transceiver52M/radioVector.h
Log:
Transceiver52M: Update noise measurement calculation
Previous removal of the energy detector requirement broke
the noise level calculation loop. The previous adaptive
approach was finicky - noticably at high gain levels. Since
we no longer use the energy threshold for primary burst gating,
we can return to a simpler world.
In the new approach, we compute a running average of energy
levels and track them with a noise vector. A timeslot that
passes the correlator threshold is a valid burst. These are
not used in the noise calculation. Everything else is
considered noise and used to compute the noise level with
respect to full scale input level, which for almost all
supported devices is 2^15.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/Transceiver.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/Transceiver.cpp 2013-10-17 06:19:30 UTC (rev 6754)
+++ software/public/openbts/trunk/Transceiver52M/Transceiver.cpp 2013-10-18 01:45:41 UTC (rev 6755)
@@ -44,7 +44,8 @@
# define USB_LATENCY_MIN 1,1
#endif
-#define INIT_ENERGY_THRSHD 5.0f
+/* Number of running values use in noise average */
+#define NOISE_CNT 20
Transceiver::Transceiver(int wBasePort,
const char *TRXAddress,
@@ -54,7 +55,7 @@
:mDataSocket(wBasePort+2,TRXAddress,wBasePort+102),
mControlSocket(wBasePort+1,TRXAddress,wBasePort+101),
mClockSocket(wBasePort,TRXAddress,wBasePort+100),
- mSPSTx(wSPS), mSPSRx(1)
+ mSPSTx(wSPS), mSPSRx(1), mNoises(NOISE_CNT)
{
GSM::Time startTime(random() % gHyperframe,0);
@@ -78,12 +79,9 @@
mTxFreq = 0.0;
mRxFreq = 0.0;
mPower = -10;
- mEnergyThreshold = INIT_ENERGY_THRSHD;
- prevFalseDetectionTime = startTime;
-
+ mNoiseLev = 0.0;
}
-
Transceiver::~Transceiver()
{
sigProcLibDestroy();
@@ -324,19 +322,20 @@
}
}
-
+
SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime,
int &RSSI,
int &timingOffset)
{
bool needDFE = false;
+ bool success = false;
+ complex amplitude = 0.0;
+ float TOA = 0.0, avg = 0.0;
radioVector *rxBurst = (radioVector *) mReceiveFIFO->get();
if (!rxBurst) return NULL;
- LOG(DEBUG) << "receiveFIFO: read radio vector at time: " << rxBurst->getTime() << ", new size: " << mReceiveFIFO->size();
-
int timeslot = rxBurst->getTime().TN();
CorrType corrType = expectedCorrType(rxBurst->getTime());
@@ -345,30 +344,15 @@
delete rxBurst;
return NULL;
}
-
- // check to see if received burst has sufficient
+
signalVector *vectorBurst = rxBurst;
- complex amplitude = 0.0;
- float TOA = 0.0;
- float avgPwr = 0.0;
-#ifdef ENERGY_DETECT
- 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
- mEnergyThreshold -= 10.0/10.0;
- if (mEnergyThreshold < 0.0)
- mEnergyThreshold = 0.0;
- prevFalseDetectionTime = rxBurst->getTime();
- }
- delete rxBurst;
- return NULL;
- }
- LOG(DEBUG) << "Estimated Energy: " << sqrt(avgPwr) << ", at time " << rxBurst->getTime();
-#endif
+ energyDetect(*vectorBurst, 20 * mSPSRx, 0.0, &avg);
+
+ // Update noise level
+ mNoiseLev = mNoises.avg();
+
// run the proper correlator
- bool success = false;
if (corrType==TSC) {
LOG(DEBUG) << "looking for TSC at time: " << rxBurst->getTime();
signalVector *channelResp;
@@ -396,10 +380,7 @@
&channelResp,
&chanOffset);
if (success) {
- LOG(DEBUG) << "FOUND TSC!!!!!! " << amplitude << " " << TOA;
- mEnergyThreshold -= 1.0F/10.0F;
- if (mEnergyThreshold < 0.0) mEnergyThreshold = 0.0;
- SNRestimate[timeslot] = amplitude.norm2()/(mEnergyThreshold*mEnergyThreshold+1.0); // this is not highly accurate
+ SNRestimate[timeslot] = amplitude.norm2()/(mNoiseLev*mNoiseLev+1.0); // this is not highly accurate
if (estimateChannel) {
LOG(DEBUG) << "estimating channel...";
channelResponse[timeslot] = channelResp;
@@ -412,29 +393,17 @@
}
}
else {
- double framesElapsed = rxBurst->getTime()-prevFalseDetectionTime;
- LOG(DEBUG) << "wTime: " << rxBurst->getTime() << ", pTime: " << prevFalseDetectionTime << ", fElapsed: " << framesElapsed;
- mEnergyThreshold += 10.0F/10.0F*exp(-framesElapsed);
- prevFalseDetectionTime = rxBurst->getTime();
channelResponse[timeslot] = NULL;
+ mNoises.insert(sqrt(avg));
}
}
else {
// RACH burst
- success = detectRACHBurst(*vectorBurst, 6.0, mSPSRx, &litude, &TOA);
- if (success) {
- LOG(DEBUG) << "FOUND RACH!!!!!! " << amplitude << " " << TOA;
- mEnergyThreshold -= (1.0F/10.0F);
- if (mEnergyThreshold < 0.0) mEnergyThreshold = 0.0;
- channelResponse[timeslot] = NULL;
- }
- else {
- double framesElapsed = rxBurst->getTime()-prevFalseDetectionTime;
- mEnergyThreshold += (1.0F/10.0F)*exp(-framesElapsed);
- prevFalseDetectionTime = rxBurst->getTime();
- }
+ if (success = detectRACHBurst(*vectorBurst, 6.0, mSPSRx, &litude, &TOA))
+ channelResponse[timeslot] = NULL;
+ else
+ mNoises.insert(sqrt(avg));
}
- LOG(DEBUG) << "energy Threshold = " << mEnergyThreshold;
// demodulate burst
SoftVector *burst = NULL;
@@ -542,13 +511,12 @@
int newGain;
sscanf(buffer,"%3s %s %d",cmdcheck,command,&newGain);
newGain = mRadioInterface->setRxGain(newGain);
- mEnergyThreshold = INIT_ENERGY_THRSHD;
sprintf(response,"RSP SETRXGAIN 0 %d",newGain);
}
else if (strcmp(command,"NOISELEV")==0) {
if (mOn) {
sprintf(response,"RSP NOISELEV 0 %d",
- (int) round(20.0*log10(rxFullScale/mEnergyThreshold)));
+ (int) round(20.0*log10(rxFullScale/mNoiseLev)));
}
else {
sprintf(response,"RSP NOISELEV 1 0");
Modified: software/public/openbts/trunk/Transceiver52M/Transceiver.h
===================================================================
--- software/public/openbts/trunk/Transceiver52M/Transceiver.h 2013-10-17 06:19:30 UTC (rev 6754)
+++ software/public/openbts/trunk/Transceiver52M/Transceiver.h 2013-10-18 01:45:41 UTC (rev 6755)
@@ -92,6 +92,8 @@
IGPRS ///< GPRS channel, like I but static filler frames.
} ChannelCombination;
+ float mNoiseLev; ///< Average noise level
+ noiseVector mNoises; ///< Vector holding running noise measurements
/** unmodulate a modulated burst */
#ifdef TRANSMIT_LOGGING
@@ -129,8 +131,6 @@
double mRxFreq; ///< the receive frequency
int mPower; ///< the transmit power in dB
unsigned mTSC; ///< the midamble sequence code
- double mEnergyThreshold; ///< threshold to determine if received data is potentially a GSM burst
- GSM::Time prevFalseDetectionTime; ///< last timestamp of a false energy detection
int fillerModulus[8]; ///< modulus values of all timeslots, in frames
signalVector *fillerTable[102][8]; ///< table of modulated filler waveforms for all timeslots
unsigned mMaxExpectedDelay; ///< maximum expected time-of-arrival offset in GSM symbols
Modified: software/public/openbts/trunk/Transceiver52M/radioVector.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/radioVector.cpp 2013-10-17 06:19:30 UTC (rev 6754)
+++ software/public/openbts/trunk/Transceiver52M/radioVector.cpp 2013-10-18 01:45:41 UTC (rev 6755)
@@ -41,6 +41,35 @@
return mTime > other.mTime;
}
+noiseVector::noiseVector(size_t n)
+{
+ this->resize(n);
+ it = this->begin();
+}
+
+float noiseVector::avg()
+{
+ float val = 0.0;
+
+ for (int i = 0; i < size(); i++)
+ val += (*this)[i];
+
+ return val / (float) size();
+}
+
+bool noiseVector::insert(float val)
+{
+ if (!size())
+ return false;
+
+ if (it == this->end())
+ it = this->begin();
+
+ *it++ = val;
+
+ return true;
+}
+
unsigned VectorFIFO::size()
{
return mQ.size();
Modified: software/public/openbts/trunk/Transceiver52M/radioVector.h
===================================================================
--- software/public/openbts/trunk/Transceiver52M/radioVector.h 2013-10-17 06:19:30 UTC (rev 6754)
+++ software/public/openbts/trunk/Transceiver52M/radioVector.h 2013-10-18 01:45:41 UTC (rev 6755)
@@ -36,6 +36,16 @@
GSM::Time mTime;
};
+class noiseVector : std::vector<float> {
+public:
+ noiseVector(size_t len = 0);
+ bool insert(float val);
+ float avg();
+
+private:
+ std::vector<float>::iterator it;
+};
+
class VectorFIFO {
public:
unsigned size();
|
|
From: <do_...@wu...> - 2013-10-17 06:19:38
|
Author: ttsou
Date: 2013-10-17 01:19:30 -0500 (Thu, 17 Oct 2013)
New Revision: 6754
Modified:
software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
software/public/openbts/trunk/Transceiver52M/USRPDevice.cpp
software/public/openbts/trunk/Transceiver52M/USRPDevice.h
software/public/openbts/trunk/Transceiver52M/USRPping.cpp
software/public/openbts/trunk/Transceiver52M/radioDevice.h
software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp
software/public/openbts/trunk/configure.ac
Log:
Transceiver52M: Move reference select from compile time to database
Enabling the external reference on UHD devices through the configure
time switch is awkward. Use a database variable "TRX.Reference" with
'0' or '1' value for internal and external references respectively.
Use internal reference is no entry is defined.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-17 06:19:26 UTC (rev 6753)
+++ software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-17 06:19:30 UTC (rev 6754)
@@ -214,7 +214,7 @@
uhd_device(int sps, bool skip_rx);
~uhd_device();
- int open(const std::string &args);
+ int open(const std::string &args, bool extref);
bool start();
bool stop();
void restart(uhd::time_spec_t ts);
@@ -519,7 +519,7 @@
return true;
}
-int uhd_device::open(const std::string &args)
+int uhd_device::open(const std::string &args, bool extref)
{
// Find UHD devices
uhd::device_addr_t addr(args);
@@ -542,9 +542,9 @@
if (!parse_dev_type())
return -1;
-#ifdef EXTREF
- set_ref_clk(true);
-#endif
+ if (extref)
+ set_ref_clk(true);
+
// Create TX and RX streamers
uhd::stream_args_t stream_args("sc16");
tx_stream = usrp_dev->get_tx_stream(stream_args);
Modified: software/public/openbts/trunk/Transceiver52M/USRPDevice.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/USRPDevice.cpp 2013-10-17 06:19:26 UTC (rev 6753)
+++ software/public/openbts/trunk/Transceiver52M/USRPDevice.cpp 2013-10-17 06:19:30 UTC (rev 6754)
@@ -90,7 +90,7 @@
#endif
}
-int USRPDevice::open(const std::string &)
+int USRPDevice::open(const std::string &, bool)
{
writeLock.unlock();
Modified: software/public/openbts/trunk/Transceiver52M/USRPDevice.h
===================================================================
--- software/public/openbts/trunk/Transceiver52M/USRPDevice.h 2013-10-17 06:19:26 UTC (rev 6753)
+++ software/public/openbts/trunk/Transceiver52M/USRPDevice.h 2013-10-17 06:19:30 UTC (rev 6754)
@@ -105,7 +105,7 @@
USRPDevice(int sps, bool skipRx);
/** Instantiate the USRP */
- int open(const std::string &);
+ int open(const std::string &, bool);
/** Start the USRP */
bool start();
Modified: software/public/openbts/trunk/Transceiver52M/USRPping.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/USRPping.cpp 2013-10-17 06:19:26 UTC (rev 6753)
+++ software/public/openbts/trunk/Transceiver52M/USRPping.cpp 2013-10-17 06:19:30 UTC (rev 6754)
@@ -43,7 +43,7 @@
RadioDevice *usrp = RadioDevice::make(52.0e6/192.0, 1);
- usrp->open("");
+ usrp->open();
TIMESTAMP timestamp;
Modified: software/public/openbts/trunk/Transceiver52M/radioDevice.h
===================================================================
--- software/public/openbts/trunk/Transceiver52M/radioDevice.h 2013-10-17 06:19:26 UTC (rev 6753)
+++ software/public/openbts/trunk/Transceiver52M/radioDevice.h 2013-10-17 06:19:30 UTC (rev 6754)
@@ -39,7 +39,7 @@
static RadioDevice *make(int sps, bool skipRx = false);
/** Initialize the USRP */
- virtual int open(const std::string &args)=0;
+ virtual int open(const std::string &args = "", bool extref = false)=0;
/** Start the USRP */
virtual bool start()=0;
Modified: software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp 2013-10-17 06:19:26 UTC (rev 6753)
+++ software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp 2013-10-17 06:19:30 UTC (rev 6754)
@@ -109,7 +109,7 @@
int main(int argc, char *argv[])
{
- int trxPort, fail = 0;
+ int trxPort, radioType, extref = 0, fail = 0;
std::string deviceArgs, logLevel, trxAddr;
RadioDevice *usrp = NULL;
RadioInterface *radio = NULL;
@@ -139,12 +139,21 @@
logLevel = gConfig.getStr("Log.Level");
trxPort = gConfig.getNum("TRX.Port");
trxAddr = gConfig.getStr("TRX.IP");
+
+ if (gConfig.defines("TRX.Reference"))
+ extref = gConfig.getNum("TRX.Reference");
+
+ if (extref)
+ std::cout << "Using external clock reference" << std::endl;
+ else
+ std::cout << "Using internal clock reference" << std::endl;
+
gLogInit("transceiver", logLevel.c_str(), LOG_LOCAL7);
srandom(time(NULL));
usrp = RadioDevice::make(SPS);
- int radioType = usrp->open(deviceArgs);
+ radioType = usrp->open(deviceArgs, extref);
if (radioType < 0) {
LOG(ALERT) << "Transceiver exiting..." << std::endl;
return EXIT_FAILURE;
Modified: software/public/openbts/trunk/configure.ac
===================================================================
--- software/public/openbts/trunk/configure.ac 2013-10-17 06:19:26 UTC (rev 6753)
+++ software/public/openbts/trunk/configure.ac 2013-10-17 06:19:30 UTC (rev 6754)
@@ -70,11 +70,6 @@
[enable single daughterboard use on USRP1])
])
-AC_ARG_WITH(extref, [
- AS_HELP_STRING([--with-extref],
- [enable external reference on UHD devices])
-])
-
AS_IF([test "x$with_usrp1" = "xyes"], [
PKG_CHECK_MODULES(USRP, usrp >= 3.3)
# Find and define supported SIMD extensions
@@ -87,10 +82,6 @@
AX_EXT
])
-AS_IF([test "x$with_extref" = "xyes"], [
- AC_DEFINE(EXTREF, 1, Define to 1 for external reference)
-])
-
AS_IF([test "x$with_singledb" = "xyes"], [
AC_DEFINE(SINGLEDB, 1, Define to 1 for single daughterboard)
])
|
|
From: <do_...@wu...> - 2013-10-17 06:19:29
|
Author: ttsou
Date: 2013-10-17 01:19:23 -0500 (Thu, 17 Oct 2013)
New Revision: 6752
Modified:
software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp
software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp
Log:
Transceiver52M: Deallocate high level resources on shutdown
This primarily addresses the error case at initialization.
In the event that the transceiver fails to start, we should
be able cleanly shutdown and release while providing a useful
reason for exiting.
After the radio is started and threads launched, there
are no thread state variables or shutdown messaging between
threads, and the transceiver cannot be consistently
shutdown. This issue remains to be solved.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp 2013-10-17 06:19:19 UTC (rev 6751)
+++ software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp 2013-10-17 06:19:23 UTC (rev 6752)
@@ -75,8 +75,6 @@
void RadioInterfaceResamp::close()
{
- RadioInterface::close();
-
delete innerSendBuffer;
delete outerSendBuffer;
delete innerRecvBuffer;
@@ -89,9 +87,13 @@
outerSendBuffer = NULL;
innerRecvBuffer = NULL;
outerRecvBuffer = NULL;
+ sendBuffer = NULL;
+ recvBuffer = NULL;
upsampler = NULL;
dnsampler = NULL;
+
+ RadioInterface::close();
}
/* Initialize I/O specific objects */
Modified: software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp 2013-10-17 06:19:19 UTC (rev 6751)
+++ software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp 2013-10-17 06:19:23 UTC (rev 6752)
@@ -47,8 +47,6 @@
*/
#define SPS 4
-using namespace std;
-
ConfigurationKeyMap getConfigurationKeys();
ConfigurationTable gConfig(CONFIGDB, 0, getConfigurationKeys());
@@ -56,8 +54,8 @@
static void ctrlCHandler(int signo)
{
- cout << "Received shutdown signal" << endl;;
- gbShutdown = true;
+ std::cout << "Received shutdown signal" << std::endl;
+ gbShutdown = true;
}
/*
@@ -111,28 +109,25 @@
int main(int argc, char *argv[])
{
- int trxPort;
+ int trxPort, fail = 0;
std::string deviceArgs, logLevel, trxAddr;
+ RadioDevice *usrp = NULL;
+ RadioInterface *radio = NULL;
+ Transceiver *trx = NULL;
if (argc == 3)
- {
deviceArgs = std::string(argv[2]);
- }
else
- {
deviceArgs = "";
- }
- if ( signal( SIGINT, ctrlCHandler ) == SIG_ERR )
- {
- cerr << "Couldn't install signal handler for SIGINT" << endl;
- exit(1);
+ if (signal(SIGINT, ctrlCHandler) == SIG_ERR) {
+ std::cerr << "Couldn't install signal handler for SIGINT" << std::endl;
+ return EXIT_FAILURE;
}
- if ( signal( SIGTERM, ctrlCHandler ) == SIG_ERR )
- {
- cerr << "Couldn't install signal handler for SIGTERM" << endl;
- exit(1);
+ if (signal(SIGTERM, ctrlCHandler) == SIG_ERR) {
+ std::cerr << "Couldn't install signal handler for SIGTERM" << std::endl;
+ return EXIT_FAILURE;
}
// Configure logger.
@@ -148,14 +143,13 @@
srandom(time(NULL));
- RadioDevice *usrp = RadioDevice::make(SPS);
+ usrp = RadioDevice::make(SPS);
int radioType = usrp->open(deviceArgs);
if (radioType < 0) {
LOG(ALERT) << "Transceiver exiting..." << std::endl;
return EXIT_FAILURE;
}
- RadioInterface* radio;
switch (radioType) {
case RadioDevice::NORMAL:
radio = new RadioInterface(usrp, 3, SPS, false);
@@ -166,27 +160,38 @@
break;
default:
LOG(ALERT) << "Unsupported configuration";
- return EXIT_FAILURE;
+ fail = 1;
+ goto shutdown;
}
if (!radio->init(radioType)) {
LOG(ALERT) << "Failed to initialize radio interface";
+ fail = 1;
+ goto shutdown;
}
- Transceiver *trx = new Transceiver(trxPort, trxAddr.c_str(),
- SPS, GSM::Time(3,0), radio);
+ trx = new Transceiver(trxPort, trxAddr.c_str(), SPS, GSM::Time(3,0), radio);
if (!trx->init()) {
LOG(ALERT) << "Failed to initialize transceiver";
+ fail = 1;
+ goto shutdown;
}
trx->receiveFIFO(radio->receiveFIFO());
trx->start();
- while (!gbShutdown) {
+ while (!gbShutdown)
sleep(1);
- }
- cout << "Shutting down transceiver..." << endl;
+shutdown:
+ std::cout << "Shutting down transceiver..." << std::endl;
delete trx;
+ delete radio;
+ delete usrp;
+
+ if (fail)
+ return EXIT_FAILURE;
+
+ return 0;
}
ConfigurationKeyMap getConfigurationKeys()
|
|
From: <do_...@wu...> - 2013-10-17 06:19:27
|
Author: ttsou
Date: 2013-10-17 01:19:26 -0500 (Thu, 17 Oct 2013)
New Revision: 6753
Modified:
software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
Log:
Transceiver52M: Delay UHD messaging registration until after start
We want to push UHD logs to the OpenBTS logging system, but most
device errors occur at startup, so keep the output on stdout until
after device initialization. That way obvious errors are easily
viewable before seeing the useless TRX timeout message.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-17 06:19:23 UTC (rev 6752)
+++ software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-17 06:19:26 UTC (rev 6753)
@@ -521,9 +521,6 @@
int uhd_device::open(const std::string &args)
{
- // Register msg handler
- uhd::msg::register_handler(&uhd_msg_handler);
-
// Find UHD devices
uhd::device_addr_t addr(args);
uhd::device_addrs_t dev_addrs = uhd::device::find(addr);
@@ -644,6 +641,9 @@
setPriority();
+ // Register msg handler
+ uhd::msg::register_handler(&uhd_msg_handler);
+
// Start asynchronous event (underrun check) loop
async_event_thrd.start((void * (*)(void*))async_event_loop, (void*)this);
|
|
From: <do_...@wu...> - 2013-10-17 06:19:26
|
Author: ttsou
Date: 2013-10-17 01:19:19 -0500 (Thu, 17 Oct 2013)
New Revision: 6751
Modified:
software/public/openbts/trunk/Transceiver52M/radioInterface.cpp
software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp
Log:
Transceiver52M: Reduce and place bounds checking on I/O buffers
Previous send and receive buffers at the radio interface were
arbitrarily set to a sufficient size. For normal (non-resampling)
devices, use a block (chunk) size of 625 samples. For 64 or 100
MHz resampling devices, use 4 times the reduced resampling
numerator or denominator and provide bounds checking where
appropriate.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/radioInterface.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/radioInterface.cpp 2013-10-17 06:19:16 UTC (rev 6750)
+++ software/public/openbts/trunk/Transceiver52M/radioInterface.cpp 2013-10-17 06:19:19 UTC (rev 6751)
@@ -30,8 +30,8 @@
#include "convert.h"
}
-#define INCHUNK (625 * SAMPSPERSYM)
-#define OUTCHUNK (625 * SAMPSPERSYM)
+#define CHUNK 625
+#define NUMCHUNKS 4
RadioInterface::RadioInterface(RadioDevice *wRadio,
int wReceiveOffset,
@@ -58,11 +58,11 @@
close();
- sendBuffer = new signalVector(OUTCHUNK * 20);
- recvBuffer = new signalVector(INCHUNK * 20);
+ sendBuffer = new signalVector(CHUNK * mSPSTx);
+ recvBuffer = new signalVector(NUMCHUNKS * CHUNK * mSPSRx);
- convertSendBuffer = new short[OUTCHUNK * 2 * 20];
- convertRecvBuffer = new short[OUTCHUNK * 2 * 2];
+ convertSendBuffer = new short[sendBuffer->size() * 2];
+ convertRecvBuffer = new short[recvBuffer->size() * 2];
sendCursor = 0;
recvCursor = 0;
@@ -276,23 +276,26 @@
void RadioInterface::pullBuffer()
{
bool local_underrun;
- int num_recv, len = OUTCHUNK / mSPSTx;
+ int num_recv;
float *output;
+ if (recvCursor > recvBuffer->size() - CHUNK)
+ return;
+
/* Outer buffer access size is fixed */
num_recv = mRadio->readSamples(convertRecvBuffer,
- len,
+ CHUNK,
&overrun,
readTimestamp,
&local_underrun);
- if (num_recv != len) {
+ if (num_recv != CHUNK) {
LOG(ALERT) << "Receive error " << num_recv;
return;
}
output = (float *) (recvBuffer->begin() + recvCursor);
- convert_short_float(output, convertRecvBuffer, 2 * len);
+ convert_short_float(output, convertRecvBuffer, 2 * num_recv);
underrun |= local_underrun;
@@ -305,9 +308,12 @@
{
int num_sent;
- if (sendCursor < INCHUNK)
+ if (sendCursor < CHUNK)
return;
+ if (sendCursor > sendBuffer->size())
+ LOG(ALERT) << "Send buffer overflow";
+
convert_float_short(convertSendBuffer,
(float *) sendBuffer->begin(),
powerScaling, 2 * sendCursor);
Modified: software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp 2013-10-17 06:19:16 UTC (rev 6750)
+++ software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp 2013-10-17 06:19:19 UTC (rev 6751)
@@ -36,6 +36,9 @@
#define RESAMP_100M_INRATE 52
#define RESAMP_100M_OUTRATE 75
+/* Universal resampling parameters */
+#define NUMCHUNKS 24
+
/*
* Resampling filter bandwidth scaling factor
* This narrows the filter cutoff relative to the output bandwidth
@@ -116,6 +119,11 @@
resamp_inchunk = resamp_inrate * 4;
resamp_outchunk = resamp_outrate * 4;
+ if (resamp_inchunk * NUMCHUNKS < 157 * mSPSTx * 2) {
+ LOG(ALERT) << "Invalid inner chunk size " << resamp_inchunk;
+ return false;
+ }
+
if (mSPSTx == 4)
cutoff = RESAMP_TX4_FILTER;
@@ -137,17 +145,18 @@
* and requires headroom equivalent to the filter length. Low
* rate buffers are allocated in the main radio interface code.
*/
- innerSendBuffer = new signalVector(resamp_inchunk * 20,
- upsampler->len());
- outerSendBuffer = new signalVector(resamp_outchunk * 20);
+ innerSendBuffer =
+ new signalVector(NUMCHUNKS * resamp_inchunk, upsampler->len());
+ outerSendBuffer =
+ new signalVector(NUMCHUNKS * resamp_outchunk);
+ outerRecvBuffer =
+ new signalVector(resamp_outchunk, dnsampler->len());
+ innerRecvBuffer =
+ new signalVector(NUMCHUNKS * resamp_inchunk / mSPSTx);
- outerRecvBuffer = new signalVector(resamp_outchunk * 2,
- dnsampler->len());
- innerRecvBuffer = new signalVector(resamp_inchunk * 20);
+ convertSendBuffer = new short[outerSendBuffer->size() * 2];
+ convertRecvBuffer = new short[outerRecvBuffer->size() * 2];
- convertSendBuffer = new short[resamp_outchunk * 2 * 20];
- convertRecvBuffer = new short[resamp_outchunk * 2 * 2];
-
sendBuffer = innerSendBuffer;
recvBuffer = innerRecvBuffer;
@@ -159,35 +168,37 @@
{
bool local_underrun;
int rc, num_recv;
- int inner_len = resamp_inchunk;
- int outer_len = resamp_outchunk;
+ if (recvCursor > innerRecvBuffer->size() - resamp_inchunk)
+ return;
+
/* Outer buffer access size is fixed */
num_recv = mRadio->readSamples(convertRecvBuffer,
- outer_len,
+ resamp_outchunk,
&overrun,
readTimestamp,
&local_underrun);
- if (num_recv != outer_len) {
+ if (num_recv != resamp_outchunk) {
LOG(ALERT) << "Receive error " << num_recv;
return;
}
convert_short_float((float *) outerRecvBuffer->begin(),
- convertRecvBuffer, 2 * outer_len);
+ convertRecvBuffer, 2 * resamp_outchunk);
underrun |= local_underrun;
- readTimestamp += (TIMESTAMP) num_recv;
+ readTimestamp += (TIMESTAMP) resamp_outchunk;
/* Write to the end of the inner receive buffer */
- rc = dnsampler->rotate((float *) outerRecvBuffer->begin(), outer_len,
+ rc = dnsampler->rotate((float *) outerRecvBuffer->begin(),
+ resamp_outchunk,
(float *) (innerRecvBuffer->begin() + recvCursor),
- inner_len);
+ resamp_inchunk);
if (rc < 0) {
LOG(ALERT) << "Sample rate upsampling error";
}
- recvCursor += inner_len;
+ recvCursor += resamp_inchunk;
}
/* Send a timestamped chunk to the device */
@@ -199,9 +210,10 @@
if (sendCursor < resamp_inchunk)
return;
+ if (sendCursor > innerSendBuffer->size())
+ LOG(ALERT) << "Send buffer overflow";
+
chunks = sendCursor / resamp_inchunk;
- if (chunks > 8)
- chunks = 8;
inner_len = chunks * resamp_inchunk;
outer_len = chunks * resamp_outchunk;
|
|
From: <do_...@wu...> - 2013-10-17 06:19:23
|
Author: ttsou
Date: 2013-10-17 01:19:16 -0500 (Thu, 17 Oct 2013)
New Revision: 6750
Modified:
software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
software/public/openbts/trunk/Transceiver52M/radioDevice.h
software/public/openbts/trunk/Transceiver52M/radioInterface.cpp
software/public/openbts/trunk/Transceiver52M/radioInterface.h
software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp
software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp
Log:
Transceiver52M: Add 64 MHz resampling option with B100
Move B100 to the resampling interface with default
clocking. This temporarily resolves undetermined
FPGA clocking issues. This also provides extensible
support for multiple clocking rates and resampling
ratios.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-17 06:19:12 UTC (rev 6749)
+++ software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-17 06:19:16 UTC (rev 6750)
@@ -32,8 +32,9 @@
#include "config.h"
#endif
-#define BXXX_CLK_RT 52e6
-#define BXXX_BASE_RT GSMRATE
+#define B2XX_CLK_RT 52e6
+#define B2XX_BASE_RT GSMRATE
+#define B100_BASE_RT 400000
#define USRP2_BASE_RT 390625
#define TX_AMPL 0.3
#define SAMPLE_BUF_SZ (1 << 20)
@@ -66,10 +67,10 @@
static struct uhd_dev_offset uhd_offsets[NUM_USRP_TYPES * 2] = {
{ USRP1, 1, 0.0 },
{ USRP1, 4, 0.0 },
- { USRP2, 1, 1.1815e-4 },
- { USRP2, 4, 7.7538e-5 },
- { B100, 1, 9.9692e-5 },
- { B100, 4, 6.5545e-5 },
+ { USRP2, 1, 1.2184e-4 },
+ { USRP2, 4, 8.0230e-5 },
+ { B100, 1, 1.2104e-4 },
+ { B100, 4, 7.9307e-5 },
{ B2XX, 1, 9.9692e-5 },
{ B2XX, 4, 6.9248e-5 },
{ UMTRX, 1, 9.9692e-5 },
@@ -108,6 +109,7 @@
case USRP2:
return USRP2_BASE_RT * sps;
case B100:
+ return B100_BASE_RT * sps;
case B2XX:
case UMTRX:
return GSMRATE * sps;
@@ -412,9 +414,9 @@
double offset_limit = 1.0;
double tx_offset, rx_offset;
- // B100/200 are the only device where we set FPGA clocking
- if ((dev_type == B100) || (dev_type == B2XX)) {
- if (set_master_clk(BXXX_CLK_RT) < 0)
+ // B2XX is the only device where we set FPGA clocking
+ if (dev_type == B2XX) {
+ if (set_master_clk(B2XX_CLK_RT) < 0)
return -1;
}
@@ -580,8 +582,12 @@
// Print configuration
LOG(INFO) << "\n" << usrp_dev->get_pp_string();
- if (dev_type == USRP2)
- return RESAMP;
+ switch (dev_type) {
+ case B100:
+ return RESAMP_64M;
+ case USRP2:
+ return RESAMP_100M;
+ }
return NORMAL;
}
Modified: software/public/openbts/trunk/Transceiver52M/radioDevice.h
===================================================================
--- software/public/openbts/trunk/Transceiver52M/radioDevice.h 2013-10-17 06:19:12 UTC (rev 6749)
+++ software/public/openbts/trunk/Transceiver52M/radioDevice.h 2013-10-17 06:19:16 UTC (rev 6750)
@@ -34,7 +34,7 @@
enum TxWindowType { TX_WINDOW_USRP1, TX_WINDOW_FIXED };
/* Radio interface types */
- enum RadioInterfaceType { NORMAL, RESAMP };
+ enum RadioInterfaceType { NORMAL, RESAMP_64M, RESAMP_100M };
static RadioDevice *make(int sps, bool skipRx = false);
Modified: software/public/openbts/trunk/Transceiver52M/radioInterface.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/radioInterface.cpp 2013-10-17 06:19:12 UTC (rev 6749)
+++ software/public/openbts/trunk/Transceiver52M/radioInterface.cpp 2013-10-17 06:19:16 UTC (rev 6750)
@@ -51,8 +51,11 @@
close();
}
-bool RadioInterface::init()
+bool RadioInterface::init(int type)
{
+ if (type != RadioDevice::NORMAL)
+ return false;
+
close();
sendBuffer = new signalVector(OUTCHUNK * 20);
Modified: software/public/openbts/trunk/Transceiver52M/radioInterface.h
===================================================================
--- software/public/openbts/trunk/Transceiver52M/radioInterface.h 2013-10-17 06:19:12 UTC (rev 6749)
+++ software/public/openbts/trunk/Transceiver52M/radioInterface.h 2013-10-17 06:19:16 UTC (rev 6750)
@@ -21,9 +21,6 @@
#include "radioVector.h"
#include "radioClock.h"
-/** samples per GSM symbol */
-#define SAMPSPERSYM 4
-
/** class to interface the transceiver with the USRP */
class RadioInterface {
@@ -84,13 +81,13 @@
void start();
/** intialization */
- virtual bool init();
+ virtual bool init(int type);
virtual void close();
/** constructor */
RadioInterface(RadioDevice* wRadio = NULL,
int receiveOffset = 3,
- int wSPS = SAMPSPERSYM,
+ int wSPS = 4,
GSM::Time wStartTime = GSM::Time(0));
/** destructor */
@@ -170,11 +167,11 @@
RadioInterfaceResamp(RadioDevice* wRadio = NULL,
int receiveOffset = 3,
- int wSPS = SAMPSPERSYM,
+ int wSPS = 4,
GSM::Time wStartTime = GSM::Time(0));
~RadioInterfaceResamp();
- bool init();
+ bool init(int type);
void close();
};
Modified: software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp 2013-10-17 06:19:12 UTC (rev 6749)
+++ software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp 2013-10-17 06:19:16 UTC (rev 6750)
@@ -28,9 +28,13 @@
#include "convert.h"
}
+/* Resampling parameters for 64 MHz clocking */
+#define RESAMP_64M_INRATE 65
+#define RESAMP_64M_OUTRATE 96
+
/* Resampling parameters for 100 MHz clocking */
-#define RESAMP_INRATE 52
-#define RESAMP_OUTRATE 75
+#define RESAMP_100M_INRATE 52
+#define RESAMP_100M_OUTRATE 75
/*
* Resampling filter bandwidth scaling factor
@@ -41,11 +45,13 @@
*/
#define RESAMP_TX4_FILTER 0.45
-#define INCHUNK (RESAMP_INRATE * 4)
-#define OUTCHUNK (RESAMP_OUTRATE * 4)
-
static Resampler *upsampler = NULL;
static Resampler *dnsampler = NULL;
+static int resamp_inrate = 0;
+static int resamp_inchunk = 0;
+static int resamp_outrate = 0;
+static int resamp_outchunk = 0;
+
short *convertRecvBuffer = NULL;
short *convertSendBuffer = NULL;
@@ -86,22 +92,40 @@
}
/* Initialize I/O specific objects */
-bool RadioInterfaceResamp::init()
+bool RadioInterfaceResamp::init(int type)
{
float cutoff = 1.0f;
close();
+ switch (type) {
+ case RadioDevice::RESAMP_64M:
+ resamp_inrate = RESAMP_64M_INRATE;
+ resamp_outrate = RESAMP_64M_OUTRATE;
+ break;
+ case RadioDevice::RESAMP_100M:
+ resamp_inrate = RESAMP_100M_INRATE;
+ resamp_outrate = RESAMP_100M_OUTRATE;
+ break;
+ case RadioDevice::NORMAL:
+ default:
+ LOG(ALERT) << "Invalid device configuration";
+ return false;
+ }
+
+ resamp_inchunk = resamp_inrate * 4;
+ resamp_outchunk = resamp_outrate * 4;
+
if (mSPSTx == 4)
cutoff = RESAMP_TX4_FILTER;
- dnsampler = new Resampler(RESAMP_INRATE, RESAMP_OUTRATE);
+ dnsampler = new Resampler(resamp_inrate, resamp_outrate);
if (!dnsampler->init()) {
LOG(ALERT) << "Rx resampler failed to initialize";
return false;
}
- upsampler = new Resampler(RESAMP_OUTRATE, RESAMP_INRATE);
+ upsampler = new Resampler(resamp_outrate, resamp_inrate);
if (!upsampler->init(cutoff)) {
LOG(ALERT) << "Tx resampler failed to initialize";
return false;
@@ -113,14 +137,16 @@
* and requires headroom equivalent to the filter length. Low
* rate buffers are allocated in the main radio interface code.
*/
- innerSendBuffer = new signalVector(INCHUNK * 20, upsampler->len());
- outerSendBuffer = new signalVector(OUTCHUNK * 20);
+ innerSendBuffer = new signalVector(resamp_inchunk * 20,
+ upsampler->len());
+ outerSendBuffer = new signalVector(resamp_outchunk * 20);
- outerRecvBuffer = new signalVector(OUTCHUNK * 2, dnsampler->len());
- innerRecvBuffer = new signalVector(INCHUNK * 20);
+ outerRecvBuffer = new signalVector(resamp_outchunk * 2,
+ dnsampler->len());
+ innerRecvBuffer = new signalVector(resamp_inchunk * 20);
- convertSendBuffer = new short[OUTCHUNK * 2 * 20];
- convertRecvBuffer = new short[OUTCHUNK * 2 * 2];
+ convertSendBuffer = new short[resamp_outchunk * 2 * 20];
+ convertRecvBuffer = new short[resamp_outchunk * 2 * 2];
sendBuffer = innerSendBuffer;
recvBuffer = innerRecvBuffer;
@@ -133,8 +159,8 @@
{
bool local_underrun;
int rc, num_recv;
- int inner_len = INCHUNK;
- int outer_len = OUTCHUNK;
+ int inner_len = resamp_inchunk;
+ int outer_len = resamp_outchunk;
/* Outer buffer access size is fixed */
num_recv = mRadio->readSamples(convertRecvBuffer,
@@ -170,15 +196,15 @@
int rc, chunks, num_sent;
int inner_len, outer_len;
- if (sendCursor < INCHUNK)
+ if (sendCursor < resamp_inchunk)
return;
- chunks = sendCursor / INCHUNK;
+ chunks = sendCursor / resamp_inchunk;
if (chunks > 8)
chunks = 8;
- inner_len = chunks * INCHUNK;
- outer_len = chunks * OUTCHUNK;
+ inner_len = chunks * resamp_inchunk;
+ outer_len = chunks * resamp_outchunk;
/* Always send from the beginning of the buffer */
rc = upsampler->rotate((float *) innerSendBuffer->begin(), inner_len,
Modified: software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp 2013-10-17 06:19:12 UTC (rev 6749)
+++ software/public/openbts/trunk/Transceiver52M/runTransceiver.cpp 2013-10-17 06:19:16 UTC (rev 6750)
@@ -38,6 +38,15 @@
#define CONFIGDB "/etc/OpenBTS/OpenBTS.db"
+/* Samples-per-symbol for downlink path
+ * 4 - Uses precision modulator (more computation, less distortion)
+ * 1 - Uses minimized modulator (less computation, more distortion)
+ *
+ * Other values are invalid. Receive path (uplink) is always
+ * downsampled to 1 sps
+ */
+#define SPS 4
+
using namespace std;
ConfigurationKeyMap getConfigurationKeys();
@@ -139,7 +148,7 @@
srandom(time(NULL));
- RadioDevice *usrp = RadioDevice::make(SAMPSPERSYM);
+ RadioDevice *usrp = RadioDevice::make(SPS);
int radioType = usrp->open(deviceArgs);
if (radioType < 0) {
LOG(ALERT) << "Transceiver exiting..." << std::endl;
@@ -149,21 +158,22 @@
RadioInterface* radio;
switch (radioType) {
case RadioDevice::NORMAL:
- radio = new RadioInterface(usrp, 3, SAMPSPERSYM, false);
+ radio = new RadioInterface(usrp, 3, SPS, false);
break;
- case RadioDevice::RESAMP:
- radio = new RadioInterfaceResamp(usrp, 3, SAMPSPERSYM, false);
+ case RadioDevice::RESAMP_64M:
+ case RadioDevice::RESAMP_100M:
+ radio = new RadioInterfaceResamp(usrp, 3, SPS, false);
break;
default:
LOG(ALERT) << "Unsupported configuration";
return EXIT_FAILURE;
}
- if (!radio->init()) {
+ if (!radio->init(radioType)) {
LOG(ALERT) << "Failed to initialize radio interface";
}
Transceiver *trx = new Transceiver(trxPort, trxAddr.c_str(),
- SAMPSPERSYM, GSM::Time(3,0), radio);
+ SPS, GSM::Time(3,0), radio);
if (!trx->init()) {
LOG(ALERT) << "Failed to initialize transceiver";
}
|
|
From: <do_...@wu...> - 2013-10-17 06:19:20
|
Author: ttsou
Date: 2013-10-17 01:19:12 -0500 (Thu, 17 Oct 2013)
New Revision: 6749
Modified:
software/public/openbts/trunk/Transceiver52M/USRPDevice.cpp
software/public/openbts/trunk/Transceiver52M/USRPDevice.h
software/public/openbts/trunk/configure.ac
Log:
Transceiver52M: Remove support for ancient libusrp versions
Current functionality with these old versions is questionable.
There is no reason to use any version of GNU Radio / libusrp older
than 3.3. Version 3.4.2 is the only recommended version for USRP1
users.
Non-USRP1 users must use UHD driver from Ettus Research.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/USRPDevice.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/USRPDevice.cpp 2013-10-17 06:19:08 UTC (rev 6748)
+++ software/public/openbts/trunk/Transceiver52M/USRPDevice.cpp 2013-10-17 06:19:12 UTC (rev 6749)
@@ -105,11 +105,9 @@
0, decimRate * sps, 1, -1,
usrp_standard_rx::FPGA_MODE_NORMAL,
1024, 16 * 8, rbf));
-#ifdef HAVE_LIBUSRP_3_2
m_uRx->set_fpga_master_clock_freq(masterClockRate);
-#endif
}
-
+
catch(...) {
LOG(ALERT) << "make failed on Rx";
m_uRx.reset();
@@ -129,11 +127,9 @@
m_uTx = usrp_standard_tx_sptr(usrp_standard_tx::make(
0, decimRate * 2, 1, -1,
1024, 16 * 8, rbf));
-#ifdef HAVE_LIBUSRP_3_2
m_uTx->set_fpga_master_clock_freq(masterClockRate);
-#endif
}
-
+
catch(...) {
LOG(ALERT) << "make failed on Tx";
m_uTx.reset();
Modified: software/public/openbts/trunk/Transceiver52M/USRPDevice.h
===================================================================
--- software/public/openbts/trunk/Transceiver52M/USRPDevice.h 2013-10-17 06:19:08 UTC (rev 6748)
+++ software/public/openbts/trunk/Transceiver52M/USRPDevice.h 2013-10-17 06:19:12 UTC (rev 6749)
@@ -21,30 +21,18 @@
#include "radioDevice.h"
-#ifdef HAVE_LIBUSRP_3_3 // [
-# include <usrp/usrp_standard.h>
-# include <usrp/usrp_bytesex.h>
-# include <usrp/usrp_prims.h>
-#else // HAVE_LIBUSRP_3_3 ][
-# include "usrp_standard.h"
-# include "usrp_bytesex.h"
-# include "usrp_prims.h"
-#endif // !HAVE_LIBUSRP_3_3 ]
+#include <usrp/usrp_standard.h>
+#include <usrp/usrp_bytesex.h>
+#include <usrp/usrp_prims.h>
#include <sys/time.h>
#include <math.h>
#include <string>
#include <iostream>
-
-/** Define types which are not defined in libusrp-3.1 */
-#ifndef HAVE_LIBUSRP_3_2
#include <boost/shared_ptr.hpp>
typedef boost::shared_ptr<usrp_standard_tx> usrp_standard_tx_sptr;
typedef boost::shared_ptr<usrp_standard_rx> usrp_standard_rx_sptr;
-#endif // HAVE_LIBUSRP_3_2
-
-
/** A class to handle a USRP rev 4, with a two RFX900 daughterboards */
class USRPDevice: public RadioDevice {
Modified: software/public/openbts/trunk/configure.ac
===================================================================
--- software/public/openbts/trunk/configure.ac 2013-10-17 06:19:08 UTC (rev 6748)
+++ software/public/openbts/trunk/configure.ac 2013-10-17 06:19:12 UTC (rev 6749)
@@ -76,18 +76,7 @@
])
AS_IF([test "x$with_usrp1" = "xyes"], [
- # Defines USRP_CFLAGS, USRP_INCLUDEDIR, and USRP_LIBS
- PKG_CHECK_MODULES(USRP, usrp > 3.1)
- # Check whether we have libusrp >= 3.2
- PKG_CHECK_EXISTS(usrp >= 3.2, libusrp_3_2=yes, libusrp_3_2=no)
- if test "x$libusrp_3_2" = "xyes";then
- AC_DEFINE(HAVE_LIBUSRP_3_2, 1, Define to 1 if you have libusrp >= 3.2)
- fi
- # Check whether we have libusrp >= 3.3
- PKG_CHECK_EXISTS(usrp >= 3.3, libusrp_3_3=yes, libusrp_3_3=no)
- if test "x$libusrp_3_3" = "xyes";then
- AC_DEFINE(HAVE_LIBUSRP_3_3, 1, Define to 1 if you have libusrp >= 3.3)
- fi
+ PKG_CHECK_MODULES(USRP, usrp >= 3.3)
# Find and define supported SIMD extensions
AX_EXT
])
|
|
From: <do_...@wu...> - 2013-10-17 06:19:15
|
Author: ttsou
Date: 2013-10-17 01:19:08 -0500 (Thu, 17 Oct 2013)
New Revision: 6748
Modified:
software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
Log:
Transceiver52M: Add B210 support
Identical to B200 support, but explicitly check for the device type
name.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-17 06:19:05 UTC (rev 6747)
+++ software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-17 06:19:08 UTC (rev 6748)
@@ -42,7 +42,7 @@
USRP1,
USRP2,
B100,
- B200,
+ B2XX,
UMTRX,
NUM_USRP_TYPES,
};
@@ -70,8 +70,8 @@
{ USRP2, 4, 7.7538e-5 },
{ B100, 1, 9.9692e-5 },
{ B100, 4, 6.5545e-5 },
- { B200, 1, 9.6000e-5 },
- { B200, 4, 6.4615e-5 },
+ { B2XX, 1, 9.9692e-5 },
+ { B2XX, 4, 6.9248e-5 },
{ UMTRX, 1, 9.9692e-5 },
{ UMTRX, 4, 7.3846e-5 },
};
@@ -108,7 +108,7 @@
case USRP2:
return USRP2_BASE_RT * sps;
case B100:
- case B200:
+ case B2XX:
case UMTRX:
return GSMRATE * sps;
default:
@@ -413,7 +413,7 @@
double tx_offset, rx_offset;
// B100/200 are the only device where we set FPGA clocking
- if ((dev_type == B100) || (dev_type == B200)) {
+ if ((dev_type == B100) || (dev_type == B2XX)) {
if (set_master_clk(BXXX_CLK_RT) < 0)
return -1;
}
@@ -472,7 +472,7 @@
{
std::string mboard_str, dev_str;
uhd::property_tree::sptr prop_tree;
- size_t usrp1_str, usrp2_str, b100_str, b200_str, umtrx_str;
+ size_t usrp1_str, usrp2_str, b100_str, b200_str, b210_str, umtrx_str;
prop_tree = usrp_dev->get_device()->get_tree();
dev_str = prop_tree->access<std::string>("/name").get();
@@ -482,6 +482,7 @@
usrp2_str = dev_str.find("USRP2");
b100_str = mboard_str.find("B100");
b200_str = mboard_str.find("B200");
+ b210_str = mboard_str.find("B210");
umtrx_str = dev_str.find("UmTRX");
if (usrp1_str != std::string::npos) {
@@ -498,7 +499,9 @@
dev_type = B100;
return true;
} else if (b200_str != std::string::npos) {
- dev_type = B200;
+ dev_type = B2XX;
+ } else if (b210_str != std::string::npos) {
+ dev_type = B2XX;
} else if (usrp2_str != std::string::npos) {
dev_type = USRP2;
} else if (umtrx_str != std::string::npos) {
|
|
From: <do_...@wu...> - 2013-10-17 06:19:13
|
Author: ttsou
Date: 2013-10-17 01:19:05 -0500 (Thu, 17 Oct 2013)
New Revision: 6747
Modified:
software/public/openbts/trunk/Transceiver52M/Transceiver.cpp
software/public/openbts/trunk/Transceiver52M/Transceiver.h
software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
software/public/openbts/trunk/Transceiver52M/USRPDevice.cpp
software/public/openbts/trunk/Transceiver52M/USRPDevice.h
software/public/openbts/trunk/Transceiver52M/radioInterface.cpp
software/public/openbts/trunk/Transceiver52M/radioInterface.h
software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp
software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp
software/public/openbts/trunk/Transceiver52M/sigProcLib.h
Log:
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 <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/Transceiver.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/Transceiver.cpp 2013-10-17 06:18:59 UTC (rev 6746)
+++ software/public/openbts/trunk/Transceiver52M/Transceiver.cpp 2013-10-17 06:19:05 UTC (rev 6747)
@@ -53,7 +53,8 @@
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);
@@ -62,7 +63,6 @@
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;
@@ -92,7 +92,7 @@
bool Transceiver::init()
{
- if (!sigProcLibSetup(mSPS)) {
+ if (!sigProcLibSetup(mSPSTx)) {
LOG(ALERT) << "Failed to initialize signal processing library";
return false;
}
@@ -101,7 +101,7 @@
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 @@
// 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);
@@ -146,7 +146,7 @@
#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;
/*
@@ -352,7 +352,7 @@
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
@@ -388,7 +388,7 @@
success = analyzeTrafficBurst(*vectorBurst,
mTSC,
5.0,
- mSPS,
+ mSPSRx,
&litude,
&TOA,
mMaxExpectedDelay,
@@ -421,11 +421,7 @@
}
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);
@@ -444,22 +440,19 @@
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';
@@ -618,7 +611,7 @@
sprintf(response,"RSP SETTSC 1 %d",TSC);
else {
mTSC = TSC;
- generateMidamble(mSPS, TSC);
+ generateMidamble(mSPSRx, TSC);
sprintf(response,"RSP SETTSC 0 %d", TSC);
}
}
Modified: software/public/openbts/trunk/Transceiver52M/Transceiver.h
===================================================================
--- software/public/openbts/trunk/Transceiver52M/Transceiver.h 2013-10-17 06:18:59 UTC (rev 6746)
+++ software/public/openbts/trunk/Transceiver52M/Transceiver.h 2013-10-17 06:19:05 UTC (rev 6747)
@@ -120,7 +120,8 @@
/** send messages over the clock socket */
void writeClockInterface(void);
- int mSPS; ///< number of samples per GSM symbol
+ int mSPSTx; ///< number of samples per Tx symbol
+ int mSPSRx; ///< number of samples per Rx symbol
bool mOn; ///< flag to indicate that transceiver is powered on
ChannelCombination mChanType[8]; ///< channel types for all timeslots
Modified: software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-17 06:18:59 UTC (rev 6746)
+++ software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-17 06:19:05 UTC (rev 6747)
@@ -66,14 +66,14 @@
static struct uhd_dev_offset uhd_offsets[NUM_USRP_TYPES * 2] = {
{ USRP1, 1, 0.0 },
{ USRP1, 4, 0.0 },
- { USRP2, 1, 5.4394e-5 },
- { USRP2, 4, 0.0 },
- { B100, 1, 9.4778e-5 },
- { B100, 4, 2.9418e-5 },
- { B200, 1, 0.0 },
- { B200, 4, 9.8358e-5 },
- { UMTRX, 1, 9.4778e-5 },
- { UMTRX, 4, 0.0 },
+ { USRP2, 1, 1.1815e-4 },
+ { USRP2, 4, 7.7538e-5 },
+ { B100, 1, 9.9692e-5 },
+ { B100, 4, 6.5545e-5 },
+ { B200, 1, 9.6000e-5 },
+ { B200, 4, 6.4615e-5 },
+ { UMTRX, 1, 9.9692e-5 },
+ { UMTRX, 4, 7.3846e-5 },
};
static double get_dev_offset(enum uhd_dev_type type, int sps)
@@ -248,7 +248,7 @@
double getTxFreq() { return tx_freq; }
double getRxFreq() { return rx_freq; }
- inline double getSampleRate() { return actual_smpl_rt; }
+ inline double getSampleRate() { return tx_rate; }
inline double numberRead() { return rx_pkt_cnt; }
inline double numberWritten() { return 0; }
@@ -271,7 +271,7 @@
enum uhd_dev_type dev_type;
int sps;
- double desired_smpl_rt, actual_smpl_rt;
+ double tx_rate, rx_rate;
double tx_gain, tx_gain_min, tx_gain_max;
double rx_gain, rx_gain_min, rx_gain_max;
@@ -293,7 +293,7 @@
void init_gains();
void set_ref_clk(bool ext_clk);
int set_master_clk(double rate);
- int set_rates(double rate);
+ int set_rates(double tx_rate, double rx_rate);
bool parse_dev_type();
bool flush_recv(size_t num_pkts);
int check_rx_md_err(uhd::rx_metadata_t &md, ssize_t num_smpls);
@@ -407,7 +407,7 @@
return 0;
}
-int uhd_device::set_rates(double rate)
+int uhd_device::set_rates(double tx_rate, double rx_rate)
{
double offset_limit = 1.0;
double tx_offset, rx_offset;
@@ -420,21 +420,22 @@
// Set sample rates
try {
- usrp_dev->set_tx_rate(rate);
- usrp_dev->set_rx_rate(rate);
+ usrp_dev->set_tx_rate(tx_rate);
+ usrp_dev->set_rx_rate(rx_rate);
} catch (const std::exception &ex) {
- LOG(ALERT) << "UHD rate setting failed: " << rate;
+ LOG(ALERT) << "UHD rate setting failed";
LOG(ALERT) << ex.what();
return -1;
}
- actual_smpl_rt = usrp_dev->get_tx_rate();
+ this->tx_rate = usrp_dev->get_tx_rate();
+ this->rx_rate = usrp_dev->get_rx_rate();
- tx_offset = fabs(usrp_dev->get_tx_rate() - rate);
- rx_offset = fabs(usrp_dev->get_rx_rate() - rate);
+ tx_offset = fabs(this->tx_rate - tx_rate);
+ rx_offset = fabs(this->rx_rate - rx_rate);
if ((tx_offset > offset_limit) || (rx_offset > offset_limit)) {
LOG(ALERT) << "Actual sample rate differs from desired rate";
- LOG(ALERT) << "Tx/Rx (" << usrp_dev->get_rx_rate() << "/"
- << usrp_dev->get_rx_rate() << ")";
+ LOG(ALERT) << "Tx/Rx (" << this->tx_rate << "/"
+ << this->rx_rate << ")";
return -1;
}
@@ -552,13 +553,14 @@
rx_spp = rx_stream->get_max_num_samps();
// Set rates
- desired_smpl_rt = select_rate(dev_type, sps);
- if ((desired_smpl_rt > 0.0) && (set_rates(desired_smpl_rt) < 0))
+ double _tx_rate = select_rate(dev_type, sps);
+ double _rx_rate = _tx_rate / sps;
+ if ((_tx_rate > 0.0) && (set_rates(_tx_rate, _rx_rate) < 0))
return -1;
// Create receive buffer
size_t buf_len = SAMPLE_BUF_SZ / sizeof(uint32_t);
- rx_smpl_buf = new smpl_buf(buf_len, actual_smpl_rt);
+ rx_smpl_buf = new smpl_buf(buf_len, rx_rate);
// Set receive chain sample offset
double offset = get_dev_offset(dev_type, sps);
@@ -566,7 +568,7 @@
LOG(ERR) << "Unsupported configuration, no correction applied";
ts_offset = 0;
} else {
- ts_offset = (TIMESTAMP) (offset * actual_smpl_rt);
+ ts_offset = (TIMESTAMP) (offset * rx_rate);
}
// Initialize and shadow gain values
@@ -719,7 +721,7 @@
// Shift read time with respect to transmit clock
timestamp += ts_offset;
- ts = convert_time(timestamp, actual_smpl_rt);
+ ts = convert_time(timestamp, rx_rate);
LOG(DEBUG) << "Requested timestamp = " << ts.get_real_secs();
// Check that timestamp is valid
@@ -788,7 +790,7 @@
metadata.has_time_spec = true;
metadata.start_of_burst = false;
metadata.end_of_burst = false;
- metadata.time_spec = convert_time(timestamp, actual_smpl_rt);
+ metadata.time_spec = convert_time(timestamp, tx_rate);
// No control packets
if (isControl) {
Modified: software/public/openbts/trunk/Transceiver52M/USRPDevice.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/USRPDevice.cpp 2013-10-17 06:18:59 UTC (rev 6746)
+++ software/public/openbts/trunk/Transceiver52M/USRPDevice.cpp 2013-10-17 06:19:05 UTC (rev 6747)
@@ -63,10 +63,25 @@
: skipRx(skipRx)
{
LOG(INFO) << "creating USRP device...";
+
+ this->sps = sps;
decimRate = (unsigned int) round(masterClockRate/((GSMRATE) * (double) sps));
actualSampleRate = masterClockRate/decimRate;
rxGain = 0;
+ /*
+ * Undetermined delay b/w ping response timestamp and true
+ * receive timestamp. Values are empirically measured. With
+ * split sample rate Tx/Rx - 4/1 sps we need to need to
+ * compensate for advance rather than delay.
+ */
+ if (sps == 1)
+ pingOffset = 272;
+ else if (sps == 4)
+ pingOffset = 269 - 7500;
+ else
+ pingOffset = 0;
+
#ifdef SWLOOPBACK
samplePeriod = 1.0e6/actualSampleRate;
loopbackBufferSize = 0;
@@ -86,9 +101,10 @@
m_uRx.reset();
if (!skipRx) {
try {
- m_uRx = usrp_standard_rx_sptr(usrp_standard_rx::make(0,decimRate,1,-1,
- usrp_standard_rx::FPGA_MODE_NORMAL,
- 1024,16*8,rbf));
+ m_uRx = usrp_standard_rx_sptr(usrp_standard_rx::make(
+ 0, decimRate * sps, 1, -1,
+ usrp_standard_rx::FPGA_MODE_NORMAL,
+ 1024, 16 * 8, rbf));
#ifdef HAVE_LIBUSRP_3_2
m_uRx->set_fpga_master_clock_freq(masterClockRate);
#endif
@@ -110,8 +126,9 @@
}
try {
- m_uTx = usrp_standard_tx_sptr(usrp_standard_tx::make(0,decimRate*2,1,-1,
- 1024,16*8,rbf));
+ m_uTx = usrp_standard_tx_sptr(usrp_standard_tx::make(
+ 0, decimRate * 2, 1, -1,
+ 1024, 16 * 8, rbf));
#ifdef HAVE_LIBUSRP_3_2
m_uTx->set_fpga_master_clock_freq(masterClockRate);
#endif
@@ -341,7 +358,7 @@
uint32_t word2 = usrp_to_host_u32(tmpBuf[2]);
if ((word2 >> 16) == ((0x01 << 8) | 0x02)) {
timestamp -= timestampOffset;
- timestampOffset = pktTimestamp - pingTimestamp + PINGOFFSET;
+ timestampOffset = pktTimestamp - pingTimestamp + pingOffset;
LOG(DEBUG) << "updating timestamp offset to: " << timestampOffset;
timestamp += timestampOffset;
isAligned = true;
Modified: software/public/openbts/trunk/Transceiver52M/USRPDevice.h
===================================================================
--- software/public/openbts/trunk/Transceiver52M/USRPDevice.h 2013-10-17 06:18:59 UTC (rev 6746)
+++ software/public/openbts/trunk/Transceiver52M/USRPDevice.h 2013-10-17 06:19:05 UTC (rev 6747)
@@ -60,6 +60,7 @@
usrp_subdev_spec rxSubdevSpec;
usrp_subdev_spec txSubdevSpec;
+ int sps;
double actualSampleRate; ///< the actual USRP sampling rate
unsigned int decimRate; ///< the USRP decimation rate
@@ -87,7 +88,8 @@
TIMESTAMP timestampOffset; ///< timestamp offset b/w Tx and Rx blocks
TIMESTAMP latestWriteTimestamp; ///< timestamp of most recent ping command
TIMESTAMP pingTimestamp; ///< timestamp of most recent ping response
- static const TIMESTAMP PINGOFFSET = 272; ///< undetermined delay b/w ping response timestamp and true receive timestamp
+
+ long long pingOffset;
unsigned long hi32Timestamp;
unsigned long lastPktTimestamp;
Modified: software/public/openbts/trunk/Transceiver52M/radioInterface.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/radioInterface.cpp 2013-10-17 06:18:59 UTC (rev 6746)
+++ software/public/openbts/trunk/Transceiver52M/radioInterface.cpp 2013-10-17 06:19:05 UTC (rev 6747)
@@ -23,13 +23,15 @@
*/
#include "radioInterface.h"
+#include "Resampler.h"
#include <Logger.h>
extern "C" {
#include "convert.h"
}
-bool started = false;
+#define INCHUNK (625 * SAMPSPERSYM)
+#define OUTCHUNK (625 * SAMPSPERSYM)
RadioInterface::RadioInterface(RadioDevice *wRadio,
int wReceiveOffset,
@@ -37,7 +39,7 @@
GSM::Time wStartTime)
: underrun(false), sendCursor(0), recvCursor(0), mOn(false),
mRadio(wRadio), receiveOffset(wReceiveOffset),
- sps(wSPS), powerScaling(1.0),
+ mSPSTx(wSPS), mSPSRx(1), powerScaling(1.0),
loadTest(false), sendBuffer(NULL), recvBuffer(NULL),
convertRecvBuffer(NULL), convertSendBuffer(NULL)
{
@@ -209,8 +211,8 @@
// while there's enough data in receive buffer, form received
// GSM bursts and pass up to Transceiver
// Using the 157-156-156-156 symbols per timeslot format.
- while (rcvSz > (symbolsPerSlot + (tN % 4 == 0)) * sps) {
- signalVector rxVector((symbolsPerSlot + (tN % 4 == 0)) * sps);
+ while (rcvSz > (symbolsPerSlot + (tN % 4 == 0)) * mSPSRx) {
+ signalVector rxVector((symbolsPerSlot + (tN % 4 == 0)) * mSPSRx);
unRadioifyVector((float *) (recvBuffer->begin() + readSz), rxVector);
GSM::Time tmpTime = rcvClock;
if (rcvClock.FN() >= 0) {
@@ -228,8 +230,8 @@
}
mClock.incTN();
rcvClock.incTN();
- readSz += (symbolsPerSlot+(tN % 4 == 0)) * sps;
- rcvSz -= (symbolsPerSlot+(tN % 4 == 0)) * sps;
+ readSz += (symbolsPerSlot+(tN % 4 == 0)) * mSPSRx;
+ rcvSz -= (symbolsPerSlot+(tN % 4 == 0)) * mSPSRx;
tN = rcvClock.TN();
}
@@ -267,33 +269,35 @@
return -1;
}
-/* Receive a timestamped chunk from the device */
+/* Receive a timestamped chunk from the device */
void RadioInterface::pullBuffer()
{
bool local_underrun;
- int num_recv;
+ int num_recv, len = OUTCHUNK / mSPSTx;
+ float *output;
- /* Outer buffer access size is fixed */
+ /* Outer buffer access size is fixed */
num_recv = mRadio->readSamples(convertRecvBuffer,
- OUTCHUNK,
+ len,
&overrun,
readTimestamp,
&local_underrun);
- if (num_recv != OUTCHUNK) {
+ if (num_recv != len) {
LOG(ALERT) << "Receive error " << num_recv;
return;
}
- convert_short_float((float *) (recvBuffer->begin() + recvCursor),
- convertRecvBuffer, 2 * OUTCHUNK);
+ output = (float *) (recvBuffer->begin() + recvCursor);
+ convert_short_float(output, convertRecvBuffer, 2 * len);
+
underrun |= local_underrun;
+
readTimestamp += num_recv;
-
recvCursor += num_recv;
}
-/* Send timestamped chunk to the device with arbitrary size */
+/* Send timestamped chunk to the device with arbitrary size */
void RadioInterface::pushBuffer()
{
int num_sent;
Modified: software/public/openbts/trunk/Transceiver52M/radioInterface.h
===================================================================
--- software/public/openbts/trunk/Transceiver52M/radioInterface.h 2013-10-17 06:18:59 UTC (rev 6746)
+++ software/public/openbts/trunk/Transceiver52M/radioInterface.h 2013-10-17 06:19:05 UTC (rev 6747)
@@ -23,8 +23,6 @@
/** samples per GSM symbol */
#define SAMPSPERSYM 4
-#define INCHUNK (625)
-#define OUTCHUNK (625)
/** class to interface the transceiver with the USRP */
class RadioInterface {
@@ -36,7 +34,9 @@
VectorFIFO mReceiveFIFO; ///< FIFO that holds receive bursts
RadioDevice *mRadio; ///< the USRP object
-
+
+ int mSPSTx;
+ int mSPSRx;
signalVector *sendBuffer;
signalVector *recvBuffer;
unsigned sendCursor;
@@ -52,7 +52,6 @@
RadioClock mClock; ///< the basestation clock!
- int sps; ///< samples per GSM symbol
int receiveOffset; ///< offset b/w transmit and receive GSM timestamps, in timeslots
bool mOn; ///< indicates radio is on
Modified: software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp 2013-10-17 06:18:59 UTC (rev 6746)
+++ software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp 2013-10-17 06:19:05 UTC (rev 6747)
@@ -28,14 +28,6 @@
#include "convert.h"
}
-/* New chunk sizes for resampled rate */
-#ifdef INCHUNK
- #undef INCHUNK
-#endif
-#ifdef OUTCHUNK
- #undef OUTCHUNK
-#endif
-
/* Resampling parameters for 100 MHz clocking */
#define RESAMP_INRATE 52
#define RESAMP_OUTRATE 75
@@ -104,7 +96,7 @@
cutoff = RESAMP_TX4_FILTER;
dnsampler = new Resampler(RESAMP_INRATE, RESAMP_OUTRATE);
- if (!dnsampler->init(cutoff)) {
+ if (!dnsampler->init()) {
LOG(ALERT) << "Rx resampler failed to initialize";
return false;
}
@@ -121,10 +113,10 @@
* and requires headroom equivalent to the filter length. Low
* rate buffers are allocated in the main radio interface code.
*/
- innerSendBuffer = new signalVector(INCHUNK * 20, RESAMP_FILT_LEN);
+ innerSendBuffer = new signalVector(INCHUNK * 20, upsampler->len());
outerSendBuffer = new signalVector(OUTCHUNK * 20);
- outerRecvBuffer = new signalVector(OUTCHUNK * 2, RESAMP_FILT_LEN);
+ outerRecvBuffer = new signalVector(OUTCHUNK * 2, dnsampler->len());
innerRecvBuffer = new signalVector(INCHUNK * 20);
convertSendBuffer = new short[OUTCHUNK * 2 * 20];
Modified: software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp 2013-10-17 06:18:59 UTC (rev 6746)
+++ software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp 2013-10-17 06:19:05 UTC (rev 6747)
@@ -42,9 +42,11 @@
static const float M_2PI_F = (float)(2.0*M_PI);
static const float M_1_2PI_F = 1/M_2PI_F;
-/** Static vectors that contain a precomputed +/- f_b/4 sinusoid */
-signalVector *GMSKRotation = NULL;
-signalVector *GMSKReverseRotation = NULL;
+/* Precomputed rotation vectors */
+static signalVector *GMSKRotationN = NULL;
+static signalVector *GMSKReverseRotationN = NULL;
+static signalVector *GMSKRotation1 = NULL;
+static signalVector *GMSKReverseRotation1 = NULL;
/*
* RACH and midamble correlation waveforms. Store the buffer separately
@@ -65,7 +67,7 @@
signalVector *sequence;
void *buffer;
- float TOA;
+ float toa;
complex gain;
};
@@ -99,6 +101,7 @@
CorrelationSequence *gMidambles[] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
CorrelationSequence *gRACHSequence = NULL;
PulseSequence *GSMPulse = NULL;
+PulseSequence *GSMPulse1 = NULL;
void sigProcLibDestroy()
{
@@ -107,15 +110,21 @@
gMidambles[i] = NULL;
}
- delete GMSKRotation;
- delete GMSKReverseRotation;
+ delete GMSKRotationN;
+ delete GMSKReverseRotationN;
+ delete GMSKRotation1;
+ delete GMSKReverseRotation1;
delete gRACHSequence;
delete GSMPulse;
+ delete GSMPulse1;
- GMSKRotation = NULL;
- GMSKReverseRotation = NULL;
+ GMSKRotationN = NULL;
+ GMSKRotation1 = NULL;
+ GMSKReverseRotationN = NULL;
+ GMSKReverseRotation1 = NULL;
gRACHSequence = NULL;
GSMPulse = NULL;
+ GSMPulse1 = NULL;
}
// dB relative to 1.0.
@@ -248,38 +257,38 @@
void initGMSKRotationTables(int sps)
{
- GMSKRotation = new signalVector(157 * sps);
- GMSKReverseRotation = new signalVector(157 * sps);
- signalVector::iterator rotPtr = GMSKRotation->begin();
- signalVector::iterator revPtr = GMSKReverseRotation->begin();
+ GMSKRotationN = new signalVector(157 * sps);
+ GMSKReverseRotationN = new signalVector(157 * sps);
+ signalVector::iterator rotPtr = GMSKRotationN->begin();
+ signalVector::iterator revPtr = GMSKReverseRotationN->begin();
float phase = 0.0;
- while (rotPtr != GMSKRotation->end()) {
+ while (rotPtr != GMSKRotationN->end()) {
*rotPtr++ = expjLookup(phase);
*revPtr++ = expjLookup(-phase);
phase += M_PI_F / 2.0F / (float) sps;
}
+
+ GMSKRotation1 = new signalVector(157);
+ GMSKReverseRotation1 = new signalVector(157);
+ rotPtr = GMSKRotation1->begin();
+ revPtr = GMSKReverseRotation1->begin();
+ phase = 0.0;
+ while (rotPtr != GMSKRotation1->end()) {
+ *rotPtr++ = expjLookup(phase);
+ *revPtr++ = expjLookup(-phase);
+ phase += M_PI_F / 2.0F;
+ }
}
-bool sigProcLibSetup(int sps)
+static void GMSKRotate(signalVector &x, int sps)
{
- if ((sps != 1) && (sps != 4))
- return false;
+ signalVector::iterator rotPtr, xPtr = x.begin();
- initTrigTables();
- initGMSKRotationTables(sps);
- generateGSMPulse(sps, 2);
+ if (sps == 1)
+ rotPtr = GMSKRotation1->begin();
+ else
+ rotPtr = GMSKRotationN->begin();
- if (!generateRACHSequence(sps)) {
- sigProcLibDestroy();
- return false;
- }
-
- return true;
-}
-
-void GMSKRotate(signalVector &x) {
- signalVector::iterator xPtr = x.begin();
- signalVector::iterator rotPtr = GMSKRotation->begin();
if (x.isRealOnly()) {
while (xPtr < x.end()) {
*xPtr = *rotPtr++ * (xPtr->real());
@@ -294,9 +303,15 @@
}
}
-void GMSKReverseRotate(signalVector &x) {
- signalVector::iterator xPtr= x.begin();
- signalVector::iterator rotPtr = GMSKReverseRotation->begin();
+static void GMSKReverseRotate(signalVector &x, int sps)
+{
+ signalVector::iterator rotPtr, xPtr= x.begin();
+
+ if (sps == 1)
+ rotPtr = GMSKReverseRotation1->begin();
+ else
+ rotPtr = GMSKReverseRotationN->begin();
+
if (x.isRealOnly()) {
while (xPtr < x.end()) {
*xPtr = *rotPtr++ * (xPtr->real());
@@ -412,10 +427,13 @@
return y;
}
-bool generateC1Pulse(int sps)
+static bool generateC1Pulse(int sps, PulseSequence *pulse)
{
int len;
+ if (!pulse)
+ return false;
+
switch (sps) {
case 4:
len = 8;
@@ -424,20 +442,20 @@
return false;
}
- GSMPulse->c1_buffer = convolve_h_alloc(len);
- GSMPulse->c1 = new signalVector((complex *)
- GSMPulse->c1_buffer, 0, len);
- GSMPulse->c1->isRealOnly(true);
+ pulse->c1_buffer = convolve_h_alloc(len);
+ pulse->c1 = new signalVector((complex *)
+ pulse->c1_buffer, 0, len);
+ pulse->c1->isRealOnly(true);
/* Enable alignment for SSE usage */
- GSMPulse->c1->setAligned(true);
+ pulse->c1->setAligned(true);
- signalVector::iterator xP = GSMPulse->c1->begin();
+ signalVector::iterator xP = pulse->c1->begin();
switch (sps) {
case 4:
/* BT = 0.30 */
- *xP++ = 0.0;
+ *xP++ = 0.0;
*xP++ = 8.16373112e-03;
*xP++ = 2.84385729e-02;
*xP++ = 5.64158904e-02;
@@ -450,18 +468,17 @@
return true;
}
-void generateGSMPulse(int sps, int symbolLength)
+static PulseSequence *generateGSMPulse(int sps, int symbolLength)
{
int len;
float arg, avg, center;
+ PulseSequence *pulse;
- 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;
+ pulse = new PulseSequence();
+ pulse->empty = new signalVector(1);
+ pulse->empty->isRealOnly(true);
+ *(pulse->empty->begin()) = 1.0f;
/*
* For 4 samples-per-symbol use a precomputed single pulse Laurent
@@ -479,15 +496,14 @@
len = 4;
}
- GSMPulse->c0_buffer = convolve_h_alloc(len);
- GSMPulse->c0 = new signalVector((complex *)
- GSMPulse->c0_buffer, 0, len);
- GSMPulse->c0->isRealOnly(true);
+ pulse->c0_buffer = convolve_h_alloc(len);
+ pulse->c0 = new signalVector((complex *) pulse->c0_buffer, 0, len);
+ pulse->c0->isRealOnly(true);
/* Enable alingnment for SSE usage */
- GSMPulse->c0->setAligned(true);
+ pulse->c0->setAligned(true);
- signalVector::iterator xP = GSMPulse->c0->begin();
+ signalVector::iterator xP = pulse->c0->begin();
if (sps == 4) {
*xP++ = 0.0;
@@ -506,7 +522,7 @@
*xP++ = 1.03184855e-01;
*xP++ = 2.84385729e-02;
*xP++ = 4.46348606e-03;
- generateC1Pulse(sps);
+ generateC1Pulse(sps, pulse);
} else {
center = (float) (len - 1.0) / 2.0;
@@ -517,11 +533,13 @@
0.527 * arg * arg * arg * arg);
}
- avg = sqrtf(vectorNorm2(*GSMPulse->c0) / sps);
- xP = GSMPulse->c0->begin();
- for (int i = 0; i < len; i++)
+ avg = sqrtf(vectorNorm2(*pulse->c0) / sps);
+ xP = pulse->c0->begin();
+ for (int i = 0; i < len; i++)
*xP++ /= avg;
}
+
+ return pulse;
}
signalVector* frequencyShift(signalVector *y,
@@ -610,7 +628,7 @@
signalVector *pulse, rotated, *shaped;
signalVector::iterator itr;
- pulse = GSMPulse->empty;
+ pulse = GSMPulse1->empty;
burst_len = sps * (wBurst.size() + guardPeriodLength);
rotated = signalVector(burst_len);
itr = rotated.begin();
@@ -620,7 +638,7 @@
itr += sps;
}
- GMSKRotate(rotated);
+ GMSKRotate(rotated, sps);
rotated.isRealOnly(false);
/* Dummy filter operation */
@@ -673,7 +691,7 @@
*c0_itr = 2.0 * (0x01 & 0x01) - 1.0;
/* Generate C0 phase coefficients */
- GMSKRotate(c0_burst);
+ GMSKRotate(c0_burst, sps);
c0_burst.isRealOnly(false);
c0_itr = c0_burst.begin();
@@ -722,7 +740,11 @@
signalVector *pulse, burst, *shaped;
signalVector::iterator burst_itr;
- pulse = GSMPulse->c0;
+ if (sps == 1)
+ pulse = GSMPulse1->c0;
+ else
+ pulse = GSMPulse->c0;
+
burst_len = sps * (bits.size() + guard_len);
burst = signalVector(burst_len);
@@ -735,7 +757,7 @@
burst_itr += sps;
}
- GMSKRotate(burst);
+ GMSKRotate(burst, sps);
burst.isRealOnly(false);
/* Single Gaussian pulse approximation shaping */
@@ -1018,6 +1040,7 @@
bool generateMidamble(int sps, int tsc)
{
bool status = true;
+ float toa;
complex *data = NULL;
signalVector *autocorr = NULL, *midamble = NULL;
signalVector *midMidamble = NULL, *_midMidamble = NULL;
@@ -1065,8 +1088,17 @@
gMidambles[tsc] = new CorrelationSequence;
gMidambles[tsc]->buffer = data;
gMidambles[tsc]->sequence = _midMidamble;
- gMidambles[tsc]->gain = peakDetect(*autocorr,&gMidambles[tsc]->TOA, NULL);
+ gMidambles[tsc]->gain = peakDetect(*autocorr, &toa, NULL);
+ /* For 1 sps only
+ * (Half of correlation length - 1) + midpoint of pulse shape + remainder
+ * 13.5 = (16 / 2 - 1) + 1.5 + (26 - 10) / 2
+ */
+ if (sps == 1)
+ gMidambles[tsc]->toa = toa - 13.5;
+ else
+ gMidambles[tsc]->toa = 0;
+
release:
delete autocorr;
delete midamble;
@@ -1084,6 +1116,7 @@
bool generateRACHSequence(int sps)
{
bool status = true;
+ float toa;
complex *data = NULL;
signalVector *autocorr = NULL;
signalVector *seq0 = NULL, *seq1 = NULL, *_seq1 = NULL;
@@ -1117,8 +1150,17 @@
gRACHSequence = new CorrelationSequence;
gRACHSequence->sequence = _seq1;
gRACHSequence->buffer = data;
- gRACHSequence->gain = peakDetect(*autocorr,&gRACHSequence->TOA, NULL);
+ gRACHSequence->gain = peakDetect(*autocorr, &toa, NULL);
+ /* For 1 sps only
+ * (Half of correlation length - 1) + midpoint of pulse shaping filer
+ * 20.5 = (40 / 2 - 1) + 1.5
+ */
+ if (sps == 1)
+ gRACHSequence->toa = toa - 20.5;
+ else
+ gRACHSequence->toa = 0.0;
+
release:
delete autocorr;
delete seq0;
@@ -1222,6 +1264,9 @@
if (sps == 4)
*amp = *amp * complex(0.0, 1.0);
+ /* Compensate for residuate time lag */
+ *toa = *toa - sync->toa;
+
return 1;
}
@@ -1365,7 +1410,7 @@
// shift up by a quarter of a frequency
// ignore starting phase, since spec allows for discontinuous phase
- GMSKReverseRotate(*shapedBurst);
+ GMSKReverseRotate(*shapedBurst, sps);
// run through slicer
if (sps > 1) {
@@ -1508,8 +1553,8 @@
signalVector::iterator dPtr = postForward->begin();
signalVector::iterator dBackPtr;
- signalVector::iterator rotPtr = GMSKRotation->begin();
- signalVector::iterator revRotPtr = GMSKReverseRotation->begin();
+ signalVector::iterator rotPtr = GMSKRotationN->begin();
+ signalVector::iterator revRotPtr = GMSKReverseRotationN->begin();
signalVector *DFEoutput = new signalVector(postForward->size());
signalVector::iterator DFEItr = DFEoutput->begin();
@@ -1548,3 +1593,23 @@
return burstBits;
}
+
+bool sigProcLibSetup(int sps)
+{
+ if ((sps != 1) && (sps != 4))
+ return false;
+
+ initTrigTables();
+ initGMSKRotationTables(sps);
+
+ GSMPulse1 = generateGSMPulse(1, 2);
+ if (sps > 1)
+ GSMPulse = generateGSMPulse(sps, 2);
+
+ if (!generateRACHSequence(1)) {
+ sigProcLibDestroy();
+ return false;
+ }
+
+ return true;
+}
Modified: software/public/openbts/trunk/Transceiver52M/sigProcLib.h
===================================================================
--- software/public/openbts/trunk/Transceiver52M/sigProcLib.h 2013-10-17 06:18:59 UTC (rev 6746)
+++ software/public/openbts/trunk/Transceiver52M/sigProcLib.h 2013-10-17 06:19:05 UTC (rev 6747)
@@ -145,14 +145,6 @@
unsigned step = 1, int offset = 0);
/**
- Generate the GSM pulse.
- @param sps The number of samples per GSM symbol.
- @param symbolLength The size of the pulse.
- @return The GSM pulse.
-*/
-void generateGSMPulse(int sps, int symbolLength);
-
-/**
Frequency shift a vector.
@param y The frequency shifted vector.
@param x The vector to-be-shifted.
|
|
From: <do_...@wu...> - 2013-10-17 06:19:03
|
Author: ttsou
Date: 2013-10-17 01:18:56 -0500 (Thu, 17 Oct 2013)
New Revision: 6745
Modified:
software/public/openbts/trunk/Transceiver52M/Transceiver.cpp
software/public/openbts/trunk/Transceiver52M/Transceiver.h
Log:
Transceiver52M: Separate main transmit and receive drive threads
This patch primarily addresses observed repeated overrun
conditions in embedded environments - namely ARM.
The heartbeat of the transceiver is derived from the receive
sample stream, which drives the main GSM clock. Detach the
transmit thread from the receive loop to avoid interfering with
the receive I/O, which is sensitive to overrun conditions if
pull process is interrupted.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/Transceiver.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/Transceiver.cpp 2013-10-17 06:18:53 UTC (rev 6744)
+++ software/public/openbts/trunk/Transceiver52M/Transceiver.cpp 2013-10-17 06:18:56 UTC (rev 6745)
@@ -57,7 +57,8 @@
{
GSM::Time startTime(random() % gHyperframe,0);
- mFIFOServiceLoopThread = new Thread(32768); ///< thread to push bursts into transmit FIFO
+ mRxServiceLoopThread = new Thread(32768);
+ mTxServiceLoopThread = new Thread(32768);
mControlServiceLoopThread = new Thread(32768); ///< thread to process control messages from GSM core
mTransmitPriorityQueueServiceLoopThread = new Thread(32768);///< thread to process transmit bursts from GSM core
@@ -527,7 +528,8 @@
mRadioInterface->start();
// Start radio interface threads.
- mFIFOServiceLoopThread->start((void * (*)(void*))FIFOServiceLoopAdapter,(void*) this);
+ mTxServiceLoopThread->start((void * (*)(void*))TxServiceLoopAdapter,(void*) this);
+ mRxServiceLoopThread->start((void * (*)(void*))RxServiceLoopAdapter,(void*) this);
mTransmitPriorityQueueServiceLoopThread->start((void * (*)(void*))TransmitPriorityQueueServiceLoopAdapter,(void*) this);
writeClockInterface();
@@ -836,11 +838,9 @@
pushRadioVector(mTransmitDeadlineClock);
mTransmitDeadlineClock.incTN();
}
-
}
- // FIXME -- This should not be a hard spin.
- // But any delay here causes us to throw omni_thread_fatal.
- //else radioClock->wait();
+
+ radioClock->wait();
}
@@ -857,17 +857,22 @@
mLastClockUpdateTime = mTransmitDeadlineClock;
-}
-
+}
-
-
-void *FIFOServiceLoopAdapter(Transceiver *transceiver)
+void *RxServiceLoopAdapter(Transceiver *transceiver)
{
transceiver->setPriority();
while (1) {
transceiver->driveReceiveFIFO();
+ pthread_testcancel();
+ }
+ return NULL;
+}
+
+void *TxServiceLoopAdapter(Transceiver *transceiver)
+{
+ while (1) {
transceiver->driveTransmitFIFO();
pthread_testcancel();
}
Modified: software/public/openbts/trunk/Transceiver52M/Transceiver.h
===================================================================
--- software/public/openbts/trunk/Transceiver52M/Transceiver.h 2013-10-17 06:18:53 UTC (rev 6744)
+++ software/public/openbts/trunk/Transceiver52M/Transceiver.h 2013-10-17 06:18:56 UTC (rev 6745)
@@ -56,7 +56,8 @@
VectorFIFO* mTransmitFIFO; ///< radioInterface FIFO of transmit bursts
VectorFIFO* mReceiveFIFO; ///< radioInterface FIFO of receive bursts
- Thread *mFIFOServiceLoopThread; ///< thread to push/pull bursts into transmit/receive FIFO
+ Thread *mRxServiceLoopThread; ///< thread to pull bursts into receive FIFO
+ Thread *mTxServiceLoopThread; ///< thread to push bursts into transmit FIFO
Thread *mControlServiceLoopThread; ///< thread to process control messages from GSM core
Thread *mTransmitPriorityQueueServiceLoopThread;///< thread to process transmit bursts from GSM core
@@ -193,8 +194,10 @@
*/
bool driveTransmitPriorityQueue();
- friend void *FIFOServiceLoopAdapter(Transceiver *);
+ friend void *RxServiceLoopAdapter(Transceiver *);
+ friend void *TxServiceLoopAdapter(Transceiver *);
+
friend void *ControlServiceLoopAdapter(Transceiver *);
friend void *TransmitPriorityQueueServiceLoopAdapter(Transceiver *);
@@ -206,8 +209,9 @@
};
-/** FIFO thread loop */
-void *FIFOServiceLoopAdapter(Transceiver *);
+/** Main drive threads */
+void *RxServiceLoopAdapter(Transceiver *);
+void *TxServiceLoopAdapter(Transceiver *);
/** control message handler thread loop */
void *ControlServiceLoopAdapter(Transceiver *);
|
|
From: <do_...@wu...> - 2013-10-17 06:19:01
|
Author: ttsou
Date: 2013-10-17 01:18:59 -0500 (Thu, 17 Oct 2013)
New Revision: 6746
Modified:
software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp
Log:
Transceiver52M: Generate delay filter with SSE memory alignment
This requires an additional memcpy() on the signal vector
constructor, but allows the interpolation filter to use
SSE optimzationed convolution.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp 2013-10-17 06:18:56 UTC (rev 6745)
+++ software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp 2013-10-17 06:18:59 UTC (rev 6746)
@@ -764,44 +764,61 @@
bool delayVector(signalVector &wBurst, float delay)
{
-
- int intOffset = (int) floor(delay);
- float fracOffset = delay - intOffset;
+ int whole, h_len = 20;
+ float frac;
+ complex *data;
+ signalVector *h, *shift;
+ signalVector::iterator itr;
- // do fractional shift first, only do it for reasonable offsets
- if (fabs(fracOffset) > 1e-2) {
- // create sinc function
- signalVector sincVector(21);
- sincVector.isRealOnly(true);
- signalVector::iterator sincBurstItr = sincVector.end();
- for (int i = 0; i < 21; i++)
- *--sincBurstItr = (complex) sinc(M_PI_F*(i-10-fracOffset));
-
- signalVector shiftedBurst(wBurst.size());
- if (!convolve(&wBurst, &sincVector, &shiftedBurst, NO_DELAY))
+ whole = floor(delay);
+ frac = delay - whole;
+
+ /* Sinc interpolated fractional shift (if allowable) */
+ if (fabs(frac) > 1e-2) {
+ data = (complex *) convolve_h_alloc(h_len);
+ h = new signalVector(data, 0, h_len);
+ h->setAligned(true);
+ h->isRealOnly(true);
+
+ itr = h->end();
+ for (int i = 0; i < h_len; i++)
+ *--itr = (complex) sinc(M_PI_F * (i - h_len / 2 - frac));
+
+ shift = convolve(&wBurst, h, NULL, NO_DELAY);
+
+ delete h;
+ free(data);
+
+ if (!shift)
return false;
- wBurst.clone(shiftedBurst);
+
+ wBurst.clone(*shift);
+ delete shift;
}
- if (intOffset < 0) {
- intOffset = -intOffset;
+ /* Integer sample shift */
+ if (whole < 0) {
+ whole = -whole;
signalVector::iterator wBurstItr = wBurst.begin();
- signalVector::iterator shiftedItr = wBurst.begin()+intOffset;
+ signalVector::iterator shiftedItr = wBurst.begin() + whole;
+
while (shiftedItr < wBurst.end())
*wBurstItr++ = *shiftedItr++;
while (wBurstItr < wBurst.end())
*wBurstItr++ = 0.0;
- }
- else {
- signalVector::iterator wBurstItr = wBurst.end()-1;
- signalVector::iterator shiftedItr = wBurst.end()-1-intOffset;
+ } else {
+ signalVector::iterator wBurstItr = wBurst.end() - 1;
+ signalVector::iterator shiftedItr = wBurst.end() - 1 - whole;
+
while (shiftedItr >= wBurst.begin())
*wBurstItr-- = *shiftedItr--;
while (wBurstItr >= wBurst.begin())
*wBurstItr-- = 0.0;
}
+
+ return true;
}
-
+
signalVector *gaussianNoise(int length,
float variance,
complex mean)
|
|
From: <do_...@wu...> - 2013-10-17 06:18:59
|
Author: ttsou
Date: 2013-10-17 01:18:53 -0500 (Thu, 17 Oct 2013)
New Revision: 6744
Modified:
software/public/openbts/trunk/Transceiver52M/Transceiver.cpp
Log:
Transceiver52M: Disable equalization
Unsupported at 4 sps, and performance benefits remain
to be proven at 1 sps. Disable until further testing.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/Transceiver.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/Transceiver.cpp 2013-10-17 06:18:49 UTC (rev 6743)
+++ software/public/openbts/trunk/Transceiver52M/Transceiver.cpp 2013-10-17 06:18:53 UTC (rev 6744)
@@ -328,7 +328,7 @@
int &RSSI,
int &timingOffset)
{
- bool needDFE = (mMaxExpectedDelay > 1);
+ bool needDFE = false;
radioVector *rxBurst = (radioVector *) mReceiveFIFO->get();
|
|
From: <do_...@wu...> - 2013-10-17 06:18:56
|
Author: ttsou
Date: 2013-10-17 01:18:49 -0500 (Thu, 17 Oct 2013)
New Revision: 6743
Modified:
software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp
Log:
Transceiver52M: Reduce RACH and TSC correlation windows
Start the correlation search window at 4 symbols before
the expected correlation peak. End the search at 10
symbols and 4 + maximum expected delay for RACH and TSC
bursts respectively.
This change lowers receive side cpu utilization while
maintaining reasonable timing jitter and accuracy tolerance.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp 2013-10-17 06:18:46 UTC (rev 6742)
+++ software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp 2013-10-17 06:18:49 UTC (rev 6743)
@@ -1213,8 +1213,8 @@
*
* Correlation window parameters:
* target: Tail bits + RACH length (reduced from 41 to a multiple of 4)
- * head: Search 8 symbols before target
- * tail: Search 8 symbols after target
+ * head: Search 4 symbols before target
+ * tail: Search 10 symbols after target
*/
int detectRACHBurst(signalVector &rxBurst,
float thresh,
@@ -1232,8 +1232,8 @@
return -1;
target = 8 + 40;
- head = 8;
- tail = head;
+ head = 4;
+ tail = 10;
start = (target - head) * sps - 1;
len = (head + tail) * sps;
@@ -1266,8 +1266,8 @@
*
* Correlation window parameters:
* target: Tail + data + mid-midamble + 1/2 remaining midamblebits
- * head: Search 8 symbols before target
- * tail: Search 8 symbols + maximum expected delay
+ * head: Search 4 symbols before target
+ * tail: Search 4 symbols + maximum expected delay
*/
int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh,
int sps, complex *amp, float *toa, unsigned max_toa,
@@ -1283,8 +1283,8 @@
return -1;
target = 3 + 58 + 16 + 5;
- head = 8;
- tail = head + max_toa;
+ head = 4;
+ tail = 4 + max_toa;
start = (target - head) * sps - 1;
len = (head + tail) * sps;
|
|
From: <do_...@wu...> - 2013-10-17 06:18:52
|
Author: ttsou
Date: 2013-10-17 01:18:46 -0500 (Thu, 17 Oct 2013)
New Revision: 6742
Modified:
software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp
Log:
Transceiver52M: Narrow resampling filter bandwidth
This patch only applies to resampling use at 4 samples-per-symbol.
By extention that means only USRP2 / N2xx devices are affected.
At 4 samples-per-symbol we restrict output bandwidth to roughly
roughly 700 MHz, which combined with the 2 pulse Laurent
approximation yields < 0.5 degrees of RMS phase error at the
resampler output.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp 2013-10-17 06:18:43 UTC (rev 6741)
+++ software/public/openbts/trunk/Transceiver52M/radioInterfaceResamp.cpp 2013-10-17 06:18:46 UTC (rev 6742)
@@ -39,8 +39,16 @@
/* Resampling parameters for 100 MHz clocking */
#define RESAMP_INRATE 52
#define RESAMP_OUTRATE 75
-#define RESAMP_FILT_LEN 16
+/*
+ * Resampling filter bandwidth scaling factor
+ * This narrows the filter cutoff relative to the output bandwidth
+ * of the polyphase resampler. At 4 samples-per-symbol using the
+ * 2 pulse Laurent GMSK approximation gives us below 0.5 degrees
+ * RMS phase error at the resampler output.
+ */
+#define RESAMP_TX4_FILTER 0.45
+
#define INCHUNK (RESAMP_INRATE * 4)
#define OUTCHUNK (RESAMP_OUTRATE * 4)
@@ -92,13 +100,8 @@
close();
- /*
- * With oversampling, restrict bandwidth to 150% of base rate. This also
- * provides last ditch bandwith limiting if the pulse shaping filter is
- * insufficient.
- */
- if (sps > 1)
- cutoff = 1.5 / sps;
+ if (mSPSTx == 4)
+ cutoff = RESAMP_TX4_FILTER;
dnsampler = new Resampler(RESAMP_INRATE, RESAMP_OUTRATE);
if (!dnsampler->init(cutoff)) {
|
|
From: <do_...@wu...> - 2013-10-17 06:18:47
|
Author: ttsou
Date: 2013-10-17 01:18:39 -0500 (Thu, 17 Oct 2013)
New Revision: 6740
Modified:
software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
software/public/openbts/trunk/Transceiver52M/radioInterface.h
software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp
Log:
Transceiver52M: Setup dual Laurent pulse shaping filter
Provides substantially improved transmit phase error
performance when enabled. Requires use of 4 samples
per symbol, and is enabled by default when set.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-17 06:18:36 UTC (rev 6739)
+++ software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-17 06:18:39 UTC (rev 6740)
@@ -62,18 +62,14 @@
* Notes:
* USRP1 with timestamps is not supported by UHD.
*/
-static struct uhd_dev_offset uhd_offsets[NUM_USRP_TYPES * 3] = {
+static struct uhd_dev_offset uhd_offsets[NUM_USRP_TYPES * 2] = {
{ USRP1, 1, 0.0 },
- { USRP1, 2, 0.0 },
{ USRP1, 4, 0.0 },
{ USRP2, 1, 5.4394e-5 },
- { USRP2, 2, 0.0 },
{ USRP2, 4, 0.0 },
{ B100, 1, 9.4778e-5 },
- { B100, 2, 5.1100e-5 },
{ B100, 4, 2.9418e-5 },
{ UMTRX, 1, 9.4778e-5 },
- { UMTRX, 2, 0.0 },
{ UMTRX, 4, 0.0 },
};
@@ -86,25 +82,23 @@
switch (sps) {
case 1:
- return uhd_offsets[3 * type + 0].offset;
- case 2:
- return uhd_offsets[3 * type + 1].offset;
+ return uhd_offsets[2 * type + 0].offset;
case 4:
- return uhd_offsets[3 * type + 2].offset;
+ return uhd_offsets[2 * type + 1].offset;
}
LOG(ERR) << "Unsupported samples-per-symbols: " << sps;
- return 0.0;
+ return 0.0;
}
/*
* Select sample rate based on device type and requested samples-per-symbol.
* The base rate is either GSM symbol rate, 270.833 kHz, or the minimum
* usable channel spacing of 400 kHz.
- */
+ */
static double select_rate(uhd_dev_type type, int sps)
{
- if ((sps != 4) && (sps != 2) && (sps != 1))
+ if ((sps != 4) && (sps != 1))
return -9999.99;
switch (type) {
Modified: software/public/openbts/trunk/Transceiver52M/radioInterface.h
===================================================================
--- software/public/openbts/trunk/Transceiver52M/radioInterface.h 2013-10-17 06:18:36 UTC (rev 6739)
+++ software/public/openbts/trunk/Transceiver52M/radioInterface.h 2013-10-17 06:18:39 UTC (rev 6740)
@@ -22,7 +22,7 @@
#include "radioClock.h"
/** samples per GSM symbol */
-#define SAMPSPERSYM 1
+#define SAMPSPERSYM 4
#define INCHUNK (625)
#define OUTCHUNK (625)
Modified: software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp 2013-10-17 06:18:36 UTC (rev 6739)
+++ software/public/openbts/trunk/Transceiver52M/sigProcLib.cpp 2013-10-17 06:18:39 UTC (rev 6740)
@@ -75,20 +75,25 @@
* for SSE instructions.
*/
struct PulseSequence {
- PulseSequence() : gaussian(NULL), empty(NULL), buffer(NULL)
+ PulseSequence() : c0(NULL), c1(NULL), empty(NULL),
+ c0_buffer(NULL), c1_buffer(NULL)
{
}
~PulseSequence()
{
- delete gaussian;
+ delete c0;
+ delete c1;
delete empty;
- free(buffer);
+ free(c0_buffer);
+ free(c1_buffer);
}
- signalVector *gaussian;
+ signalVector *c0;
+ signalVector *c1;
signalVector *empty;
- void *buffer;
+ void *c0_buffer;
+ void *c1_buffer;
};
CorrelationSequence *gMidambles[] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
@@ -407,10 +412,48 @@
return y;
}
+bool generateC1Pulse(int sps)
+{
+ int len;
+
+ switch (sps) {
+ case 4:
+ len = 8;
+ break;
+ default:
+ return false;
+ }
+
+ GSMPulse->c1_buffer = convolve_h_alloc(len);
+ GSMPulse->c1 = new signalVector((complex *)
+ GSMPulse->c1_buffer, 0, len);
+ GSMPulse->c1->isRealOnly(true);
+
+ /* Enable alignment for SSE usage */
+ GSMPulse->c1->setAligned(true);
+
+ signalVector::iterator xP = GSMPulse->c1->begin();
+
+ switch (sps) {
+ case 4:
+ /* BT = 0.30 */
+ *xP++ = 0.0;
+ *xP++ = 8.16373112e-03;
+ *xP++ = 2.84385729e-02;
+ *xP++ = 5.64158904e-02;
+ *xP++ = 7.05463553e-02;
+ *xP++ = 5.64158904e-02;
+ *xP++ = 2.84385729e-02;
+ *xP++ = 8.16373112e-03;
+ }
+
+ return true;
+}
+
void generateGSMPulse(int sps, int symbolLength)
{
int len;
- float arg, center;
+ float arg, avg, center;
delete GSMPulse;
@@ -436,15 +479,18 @@
len = 4;
}
- GSMPulse->buffer = convolve_h_alloc(len);
- GSMPulse->gaussian = new signalVector((complex *)
- GSMPulse->buffer, 0, len);
- GSMPulse->gaussian->setAligned(true);
- GSMPulse->gaussian->isRealOnly(true);
+ GSMPulse->c0_buffer = convolve_h_alloc(len);
+ GSMPulse->c0 = new signalVector((complex *)
+ GSMPulse->c0_buffer, 0, len);
+ GSMPulse->c0->isRealOnly(true);
- signalVector::iterator xP = GSMPulse->gaussian->begin();
+ /* Enable alingnment for SSE usage */
+ GSMPulse->c0->setAligned(true);
+ signalVector::iterator xP = GSMPulse->c0->begin();
+
if (sps == 4) {
+ *xP++ = 0.0;
*xP++ = 4.46348606e-03;
*xP++ = 2.84385729e-02;
*xP++ = 1.03184855e-01;
@@ -460,7 +506,7 @@
*xP++ = 1.03184855e-01;
*xP++ = 2.84385729e-02;
*xP++ = 4.46348606e-03;
- *xP++ = 0.0;
+ generateC1Pulse(sps);
} else {
center = (float) (len - 1.0) / 2.0;
@@ -470,12 +516,12 @@
*xP++ = 0.96 * exp(-1.1380 * arg * arg -
0.527 * arg * arg * arg * arg);
}
+
+ avg = sqrtf(vectorNorm2(*GSMPulse->c0) / sps);
+ xP = GSMPulse->c0->begin();
+ for (int i = 0; i < len; i++)
+ *xP++ /= avg;
}
-
- float avgAbsval = sqrtf(vectorNorm2(*GSMPulse->gaussian)/sps);
- xP = GSMPulse->gaussian->begin();
- for (int i = 0; i < len; i++)
- *xP++ /= avgAbsval;
}
signalVector* frequencyShift(signalVector *y,
@@ -557,44 +603,161 @@
return true;
}
-/* Assume input bits are not differentially encoded */
-signalVector *modulateBurst(const BitVector &wBurst, int guardPeriodLength,
- int sps, bool emptyPulse)
+static signalVector *rotateBurst(const BitVector &wBurst,
+ int guardPeriodLength, int sps)
{
- int burstLen;
- signalVector *pulse, *shapedBurst, modBurst;
- signalVector::iterator modBurstItr;
+ int burst_len;
+ signalVector *pulse, rotated, *shaped;
+ signalVector::iterator itr;
- if (emptyPulse)
- pulse = GSMPulse->empty;
- else
- pulse = GSMPulse->gaussian;
+ pulse = GSMPulse->empty;
+ burst_len = sps * (wBurst.size() + guardPeriodLength);
+ rotated = signalVector(burst_len);
+ itr = rotated.begin();
- burstLen = sps * (wBurst.size() + guardPeriodLength);
- modBurst = signalVector(burstLen);
- modBurstItr = modBurst.begin();
+ for (unsigned i = 0; i < wBurst.size(); i++) {
+ *itr = 2.0 * (wBurst[i] & 0x01) - 1.0;
+ itr += sps;
+ }
- for (unsigned int i = 0; i < wBurst.size(); i++) {
- *modBurstItr = 2.0*(wBurst[i] & 0x01)-1.0;
- modBurstItr += sps;
+ GMSKRotate(rotated);
+ rotated.isRealOnly(false);
+
+ /* Dummy filter operation */
+ shaped = convolve(&rotated, pulse, NULL, START_ONLY);
+ if (!shaped)
+ return NULL;
+
+ return shaped;
+}
+
+static signalVector *modulateBurstLaurent(const BitVector &bits,
+ int guard_len, int sps)
+{
+ int burst_len;
+ float phase;
+ signalVector *c0_pulse, *c1_pulse, c0_burst, c1_burst, *c0_shaped, *c1_shaped;
+ signalVector::iterator c0_itr, c1_itr;
+
+ /*
+ * Apply before and after bits to reduce phase error at burst edges.
+ * Make sure there is enough room in the burst to accomodate all bits.
+ */
+ if (guard_len < 4)
+ guard_len = 4;
+
+ c0_pulse = GSMPulse->c0;
+ c1_pulse = GSMPulse->c1;
+
+ burst_len = sps * (bits.size() + guard_len);
+
+ c0_burst = signalVector(burst_len);
+ c0_burst.isRealOnly(true);
+ c0_itr = c0_burst.begin();
+
+ c1_burst = signalVector(burst_len);
+ c1_burst.isRealOnly(true);
+ c1_itr = c1_burst.begin();
+
+ /* Padded differential start bits */
+ *c0_itr = 2.0 * (0x00 & 0x01) - 1.0;
+ c0_itr += sps;
+
+ /* Main burst bits */
+ for (unsigned i = 0; i < bits.size(); i++) {
+ *c0_itr = 2.0 * (bits[i] & 0x01) - 1.0;
+ c0_itr += sps;
}
- // shift up pi/2
- // ignore starting phase, since spec allows for discontinuous phase
- GMSKRotate(modBurst);
+ /* Padded differential end bits */
+ *c0_itr = 2.0 * (0x01 & 0x01) - 1.0;
- modBurst.isRealOnly(false);
+ /* Generate C0 phase coefficients */
+ GMSKRotate(c0_burst);
+ c0_burst.isRealOnly(false);
- // filter w/ pulse shape
- shapedBurst = convolve(&modBurst, pulse, NULL, START_ONLY);
- if (!shapedBurst)
- return NULL;
+ c0_itr = c0_burst.begin();
+ c0_itr += sps * 2;
+ c1_itr += sps * 2;
- return shapedBurst;
+ /* Start magic */
+ phase = 2.0 * ((0x01 & 0x01) ^ (0x01 & 0x01)) - 1.0;
+ *c1_itr = *c0_itr * Complex<float>(0, phase);
+ c0_itr += sps;
+ c1_itr += sps;
+
+ /* Generate C1 phase coefficients */
+ for (unsigned i = 2; i < bits.size(); i++) {
+ phase = 2.0 * ((bits[i - 1] & 0x01) ^ (bits[i - 2] & 0x01)) - 1.0;
+ *c1_itr = *c0_itr * Complex<float>(0, phase);
+
+ c0_itr += sps;
+ c1_itr += sps;
+ }
+
+ /* End magic */
+ int i = bits.size();
+ phase = 2.0 * ((bits[i-1] & 0x01) ^ (bits[i-2] & 0x01)) - 1.0;
+ *c1_itr = *c0_itr * Complex<float>(0, phase);
+
+ /* Primary (C0) and secondary (C1) pulse shaping */
+ c0_shaped = convolve(&c0_burst, c0_pulse, NULL, START_ONLY);
+ c1_shaped = convolve(&c1_burst, c1_pulse, NULL, START_ONLY);
+
+ /* Sum shaped outputs into C0 */
+ c0_itr = c0_shaped->begin();
+ c1_itr = c1_shaped->begin();
+ for (unsigned i = 0; i < c0_shaped->size(); i++ )
+ *c0_itr++ += *c1_itr++;
+
+ delete c1_shaped;
+
+ return c0_shaped;
}
-float sinc(float x)
+static signalVector *modulateBurstBasic(const BitVector &bits,
+ int guard_len, int sps)
{
+ int burst_len;
+ signalVector *pulse, burst, *shaped;
+ signalVector::iterator burst_itr;
+
+ pulse = GSMPulse->c0;
+ burst_len = sps * (bits.size() + guard_len);
+
+ burst = signalVector(burst_len);
+ burst.isRealOnly(true);
+ burst_itr = burst.begin();
+
+ /* Raw bits are not differentially encoded */
+ for (unsigned i = 0; i < bits.size(); i++) {
+ *burst_itr = 2.0 * (bits[i] & 0x01) - 1.0;
+ burst_itr += sps;
+ }
+
+ GMSKRotate(burst);
+ burst.isRealOnly(false);
+
+ /* Single Gaussian pulse approximation shaping */
+ shaped = convolve(&burst, pulse, NULL, START_ONLY);
+
+ return shaped;
+}
+
+/* Assume input bits are not differentially encoded */
+signalVector *modulateBurst(const BitVector &wBurst, int guardPeriodLength,
+ int sps, bool emptyPulse)
+{
+ if (emptyPulse)
+ return rotateBurst(wBurst, guardPeriodLength, sps);
+ else if (sps == 4)
+ return modulateBurstLaurent(wBurst, guardPeriodLength, sps);
+ else
+ return modulateBurstBasic(wBurst, guardPeriodLength, sps);
+}
+
+float sinc(float x)
+{
if ((x >= 0.01F) || (x <= -0.01F)) return (sinLookup(x)/x);
return 1.0F;
}
@@ -1038,6 +1201,10 @@
/* Normalize our channel gain */
*amp = *amp / sync->gain;
+ /* Compenate for residual rotation with dual Laurent pulse */
+ if (sps == 4)
+ *amp = *amp * complex(0.0, 1.0);
+
return 1;
}
|
|
From: <do_...@wu...> - 2013-10-17 06:18:44
|
Author: ttsou
Date: 2013-10-17 01:18:43 -0500 (Thu, 17 Oct 2013)
New Revision: 6741
Modified:
software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
Log:
Transceiver52M: Add B200 support
Set master clock rate to 52 MHz for B200. Also, we want to avoid
floating point comparison errors on clock rate settings, but we
expect to be able really set the rates we specify. Set the
offset limit to 1 Hz. If we can't set our rates with that level
of precision, then something is wrong.
Signed-off-by: Thomas Tsou <to...@ts...>
Modified: software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp
===================================================================
--- software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-17 06:18:39 UTC (rev 6740)
+++ software/public/openbts/trunk/Transceiver52M/UHDDevice.cpp 2013-10-17 06:18:43 UTC (rev 6741)
@@ -32,8 +32,8 @@
#include "config.h"
#endif
-#define B100_CLK_RT 52e6
-#define B100_BASE_RT GSMRATE
+#define BXXX_CLK_RT 52e6
+#define BXXX_BASE_RT GSMRATE
#define USRP2_BASE_RT 390625
#define TX_AMPL 0.3
#define SAMPLE_BUF_SZ (1 << 20)
@@ -42,6 +42,7 @@
USRP1,
USRP2,
B100,
+ B200,
UMTRX,
NUM_USRP_TYPES,
};
@@ -69,6 +70,8 @@
{ USRP2, 4, 0.0 },
{ B100, 1, 9.4778e-5 },
{ B100, 4, 2.9418e-5 },
+ { B200, 1, 0.0 },
+ { B200, 4, 9.8358e-5 },
{ UMTRX, 1, 9.4778e-5 },
{ UMTRX, 4, 0.0 },
};
@@ -105,6 +108,7 @@
case USRP2:
return USRP2_BASE_RT * sps;
case B100:
+ case B200:
case UMTRX:
return GSMRATE * sps;
default:
@@ -380,21 +384,23 @@
int uhd_device::set_master_clk(double clk_rate)
{
- double actual_clk_rt;
+ double actual, offset, limit = 1.0;
try {
usrp_dev->set_master_clock_rate(clk_rate);
- actual_clk_rt = usrp_dev->get_master_clock_rate();
} catch (const std::exception &ex) {
LOG(ALERT) << "UHD clock rate setting failed: " << clk_rate;
LOG(ALERT) << ex.what();
return -1;
}
- if (actual_clk_rt != clk_rate) {
+ actual = usrp_dev->get_master_clock_rate();
+ offset = fabs(clk_rate - actual);
+
+ if (offset > limit) {
LOG(ALERT) << "Failed to set master clock rate";
LOG(ALERT) << "Requested clock rate " << clk_rate;
- LOG(ALERT) << "Actual clock rate " << actual_clk_rt;
+ LOG(ALERT) << "Actual clock rate " << actual;
return -1;
}
@@ -403,12 +409,12 @@
int uhd_device::set_rates(double rate)
{
- double offset_limit = 10.0;
+ double offset_limit = 1.0;
double tx_offset, rx_offset;
- // B100 is the only device where we set FPGA clocking
- if (dev_type == B100) {
- if (set_master_clk(B100_CLK_RT) < 0)
+ // B100/200 are the only device where we set FPGA clocking
+ if ((dev_type == B100) || (dev_type == B200)) {
+ if (set_master_clk(BXXX_CLK_RT) < 0)
return -1;
}
@@ -423,11 +429,11 @@
}
actual_smpl_rt = usrp_dev->get_tx_rate();
- tx_offset = actual_smpl_rt - rate;
- rx_offset = usrp_dev->get_rx_rate() - rate;
+ tx_offset = fabs(usrp_dev->get_tx_rate() - rate);
+ rx_offset = fabs(usrp_dev->get_rx_rate() - rate);
if ((tx_offset > offset_limit) || (rx_offset > offset_limit)) {
LOG(ALERT) << "Actual sample rate differs from desired rate";
- LOG(ALERT) << "Tx/Rx (" << actual_smpl_rt << "/"
+ LOG(ALERT) << "Tx/Rx (" << usrp_dev->get_rx_rate() << "/"
<< usrp_dev->get_rx_rate() << ")";
return -1;
}
@@ -465,7 +471,7 @@
{
std::string mboard_str, dev_str;
uhd::property_tree::sptr prop_tree;
- size_t usrp1_str, usrp2_str, b100_str, umtrx_str;
+ size_t usrp1_str, usrp2_str, b100_str, b200_str, umtrx_str;
prop_tree = usrp_dev->get_device()->get_tree();
dev_str = prop_tree->access<std::string>("/name").get();
@@ -474,6 +480,7 @@
usrp1_str = dev_str.find("USRP1");
usrp2_str = dev_str.find("USRP2");
b100_str = mboard_str.find("B100");
+ b200_str = mboard_str.find("B200");
umtrx_str = dev_str.find("UmTRX");
if (usrp1_str != std::string::npos) {
@@ -489,12 +496,14 @@
<< dev_str << " " << mboard_str;
dev_type = B100;
return true;
+ } else if (b200_str != std::string::npos) {
+ dev_type = B200;
} else if (usrp2_str != std::string::npos) {
dev_type = USRP2;
} else if (umtrx_str != std::string::npos) {
dev_type = UMTRX;
} else {
- LOG(ALERT) << "Unknown UHD device type";
+ LOG(ALERT) << "Unknown UHD device type " << dev_str;
return false;
}
|