aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Tsou <tom@tsou.cc>2013-10-14 23:56:51 -0400
committerThomas Tsou <tom@tsou.cc>2013-10-18 13:10:18 -0400
commitfe269fe31dc2ae4bc3012d0b83ebc43edfd18cb5 (patch)
tree8c7cb5301de71ad875bf77cbfe656d00c945664b
parentc064124429890393ee9a447990bc861840d73803 (diff)
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 <tom@tsou.cc>
-rw-r--r--Transceiver52M/UHDDevice.cpp28
-rw-r--r--Transceiver52M/radioDevice.h2
-rw-r--r--Transceiver52M/radioInterface.cpp5
-rw-r--r--Transceiver52M/radioInterface.h11
-rw-r--r--Transceiver52M/radioInterfaceResamp.cpp66
-rw-r--r--Transceiver52M/runTransceiver.cpp22
6 files changed, 88 insertions, 46 deletions
diff --git a/Transceiver52M/UHDDevice.cpp b/Transceiver52M/UHDDevice.cpp
index f302ba0..f4b7cf4 100644
--- a/Transceiver52M/UHDDevice.cpp
+++ b/Transceiver52M/UHDDevice.cpp
@@ -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 @@ struct uhd_dev_offset {
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 @@ static double select_rate(uhd_dev_type type, int sps)
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 @@ int uhd_device::set_rates(double tx_rate, double rx_rate)
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 @@ int uhd_device::open(const std::string &args)
// 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;
}
diff --git a/Transceiver52M/radioDevice.h b/Transceiver52M/radioDevice.h
index 485d037..07ffd63 100644
--- a/Transceiver52M/radioDevice.h
+++ b/Transceiver52M/radioDevice.h
@@ -34,7 +34,7 @@ class RadioDevice {
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);
diff --git a/Transceiver52M/radioInterface.cpp b/Transceiver52M/radioInterface.cpp
index e9fcd49..a633738 100644
--- a/Transceiver52M/radioInterface.cpp
+++ b/Transceiver52M/radioInterface.cpp
@@ -51,8 +51,11 @@ RadioInterface::~RadioInterface(void)
close();
}
-bool RadioInterface::init()
+bool RadioInterface::init(int type)
{
+ if (type != RadioDevice::NORMAL)
+ return false;
+
close();
sendBuffer = new signalVector(OUTCHUNK * 20);
diff --git a/Transceiver52M/radioInterface.h b/Transceiver52M/radioInterface.h
index 98d0f9d..84de1e5 100644
--- a/Transceiver52M/radioInterface.h
+++ b/Transceiver52M/radioInterface.h
@@ -21,9 +21,6 @@
#include "radioVector.h"
#include "radioClock.h"
-/** samples per GSM symbol */
-#define SAMPSPERSYM 4
-
static const unsigned gSlotLen = 148; ///< number of symbols per slot, not counting guard periods
/** class to interface the transceiver with the USRP */
@@ -86,13 +83,13 @@ public:
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 */
@@ -172,11 +169,11 @@ public:
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();
};
diff --git a/Transceiver52M/radioInterfaceResamp.cpp b/Transceiver52M/radioInterfaceResamp.cpp
index 40bf32d..f857df9 100644
--- a/Transceiver52M/radioInterfaceResamp.cpp
+++ b/Transceiver52M/radioInterfaceResamp.cpp
@@ -28,9 +28,13 @@ extern "C" {
#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 @@ extern "C" {
*/
#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 @@ void RadioInterfaceResamp::close()
}
/* 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 @@ bool RadioInterfaceResamp::init()
* 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 @@ void RadioInterfaceResamp::pullBuffer()
{
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 @@ void RadioInterfaceResamp::pushBuffer()
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,
diff --git a/Transceiver52M/runTransceiver.cpp b/Transceiver52M/runTransceiver.cpp
index 5401c22..9a20ee6 100644
--- a/Transceiver52M/runTransceiver.cpp
+++ b/Transceiver52M/runTransceiver.cpp
@@ -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;
ConfigurationTable gConfig(CONFIGDB);
@@ -138,7 +147,7 @@ int main(int argc, char *argv[])
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;
@@ -148,21 +157,22 @@ int main(int argc, char *argv[])
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";
}