diff options
-rw-r--r-- | Transceiver52M/Makefile.am | 8 | ||||
-rw-r--r-- | Transceiver52M/UHDDevice.cpp | 17 | ||||
-rw-r--r-- | Transceiver52M/USRPDevice.cpp | 12 | ||||
-rw-r--r-- | Transceiver52M/USRPDevice.h | 2 | ||||
-rw-r--r-- | Transceiver52M/radioDevice.h | 5 | ||||
-rw-r--r-- | Transceiver52M/radioIO.cpp | 91 | ||||
-rw-r--r-- | Transceiver52M/radioInterface.cpp | 60 | ||||
-rw-r--r-- | Transceiver52M/radioInterface.h | 23 | ||||
-rw-r--r-- | Transceiver52M/radioInterfaceResamp.cpp (renamed from Transceiver52M/radioIOResamp.cpp) | 12 | ||||
-rw-r--r-- | Transceiver52M/runTransceiver.cpp | 17 | ||||
-rw-r--r-- | configure.ac | 10 |
11 files changed, 127 insertions, 130 deletions
diff --git a/Transceiver52M/Makefile.am b/Transceiver52M/Makefile.am index 7bdc181..6fcef7c 100644 --- a/Transceiver52M/Makefile.am +++ b/Transceiver52M/Makefile.am @@ -55,15 +55,9 @@ COMMON_SOURCES = \ Transceiver.cpp \ DummyLoad.cpp -if RESAMPLE libtransceiver_la_SOURCES = \ $(COMMON_SOURCES) \ - radioIOResamp.cpp -else -libtransceiver_la_SOURCES = \ - $(COMMON_SOURCES) \ - radioIO.cpp -endif + radioInterfaceResamp.cpp noinst_PROGRAMS = \ USRPping \ diff --git a/Transceiver52M/UHDDevice.cpp b/Transceiver52M/UHDDevice.cpp index 8ef03bc..890fd20 100644 --- a/Transceiver52M/UHDDevice.cpp +++ b/Transceiver52M/UHDDevice.cpp @@ -213,7 +213,7 @@ public: uhd_device(int sps, bool skip_rx); ~uhd_device(); - bool open(const std::string &args); + int open(const std::string &args); bool start(); bool stop(); void restart(uhd::time_spec_t ts); @@ -513,7 +513,7 @@ bool uhd_device::parse_dev_type() return true; } -bool uhd_device::open(const std::string &args) +int uhd_device::open(const std::string &args) { // Register msg handler uhd::msg::register_handler(&uhd_msg_handler); @@ -523,7 +523,7 @@ bool uhd_device::open(const std::string &args) uhd::device_addrs_t dev_addrs = uhd::device::find(addr); if (dev_addrs.size() == 0) { LOG(ALERT) << "No UHD devices found with address '" << args << "'"; - return false; + return -1; } // Use the first found device @@ -532,12 +532,12 @@ bool uhd_device::open(const std::string &args) usrp_dev = uhd::usrp::multi_usrp::make(dev_addrs[0]); } catch(...) { LOG(ALERT) << "UHD make failed, device " << dev_addrs[0].to_string(); - return false; + return -1; } // Check for a valid device type and set bus type if (!parse_dev_type()) - return false; + return -1; #ifdef EXTREF set_ref_clk(true); @@ -562,7 +562,7 @@ bool uhd_device::open(const std::string &args) // Set rates desired_smpl_rt = select_rate(dev_type, sps); if (set_rates(desired_smpl_rt) < 0) - return false; + return -1; // Create receive buffer size_t buf_len = SAMPLE_BUF_SZ / sizeof(uint32_t); @@ -583,7 +583,10 @@ bool uhd_device::open(const std::string &args) // Print configuration LOG(INFO) << "\n" << usrp_dev->get_pp_string(); - return true; + if (dev_type == USRP2) + return RESAMP; + + return NORMAL; } bool uhd_device::flush_recv(size_t num_pkts) diff --git a/Transceiver52M/USRPDevice.cpp b/Transceiver52M/USRPDevice.cpp index cb933a3..5c99003 100644 --- a/Transceiver52M/USRPDevice.cpp +++ b/Transceiver52M/USRPDevice.cpp @@ -75,7 +75,7 @@ USRPDevice::USRPDevice(int sps, bool skipRx) #endif } -bool USRPDevice::open(const std::string &) +int USRPDevice::open(const std::string &) { writeLock.unlock(); @@ -97,7 +97,7 @@ bool USRPDevice::open(const std::string &) catch(...) { LOG(ALERT) << "make failed on Rx"; m_uRx.reset(); - return false; + return -1; } if (m_uRx->fpga_master_clock_freq() != masterClockRate) @@ -105,7 +105,7 @@ bool USRPDevice::open(const std::string &) LOG(ALERT) << "WRONG FPGA clock freq = " << m_uRx->fpga_master_clock_freq() << ", desired clock freq = " << masterClockRate; m_uRx.reset(); - return false; + return -1; } } @@ -120,7 +120,7 @@ bool USRPDevice::open(const std::string &) catch(...) { LOG(ALERT) << "make failed on Tx"; m_uTx.reset(); - return false; + return -1; } if (m_uTx->fpga_master_clock_freq() != masterClockRate) @@ -128,7 +128,7 @@ bool USRPDevice::open(const std::string &) LOG(ALERT) << "WRONG FPGA clock freq = " << m_uTx->fpga_master_clock_freq() << ", desired clock freq = " << masterClockRate; m_uTx.reset(); - return false; + return -1; } if (!skipRx) m_uRx->stop(); @@ -165,7 +165,7 @@ bool USRPDevice::open(const std::string &) samplesWritten = 0; started = false; - return true; + return NORMAL; } diff --git a/Transceiver52M/USRPDevice.h b/Transceiver52M/USRPDevice.h index 1417beb..f5bc939 100644 --- a/Transceiver52M/USRPDevice.h +++ b/Transceiver52M/USRPDevice.h @@ -115,7 +115,7 @@ private: USRPDevice(int sps, bool skipRx); /** Instantiate the USRP */ - bool open(const std::string &); + int open(const std::string &); /** Start the USRP */ bool start(); diff --git a/Transceiver52M/radioDevice.h b/Transceiver52M/radioDevice.h index d2308d5..b796ffd 100644 --- a/Transceiver52M/radioDevice.h +++ b/Transceiver52M/radioDevice.h @@ -33,10 +33,13 @@ class RadioDevice { /* Available transport bus types */ enum TxWindowType { TX_WINDOW_USRP1, TX_WINDOW_FIXED }; + /* Radio interface types */ + enum RadioInterfaceType { NORMAL, RESAMP }; + static RadioDevice *make(int sps, bool skipRx = false); /** Initialize the USRP */ - virtual bool open(const std::string &args)=0; + virtual int open(const std::string &args)=0; /** Start the USRP */ virtual bool start()=0; diff --git a/Transceiver52M/radioIO.cpp b/Transceiver52M/radioIO.cpp deleted file mode 100644 index 9956e87..0000000 --- a/Transceiver52M/radioIO.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Radio device I/O interface - * Written by Thomas Tsou <ttsou@vt.edu> - * - * Copyright 2011 Free Software Foundation, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * See the COPYING file in the main directory for details. - */ - -#include <radioInterface.h> -#include <Logger.h> - -/* Device side buffers */ -static short rx_buf[OUTCHUNK * 2 * 2]; -static short tx_buf[INCHUNK * 2 * 2]; - -/* Complex float to short conversion */ -static int float_to_short(short *shrt_out, float *flt_in, int num) -{ - int i; - - for (i = 0; i < num; i++) { - shrt_out[2 * i + 0] = flt_in[2 * i + 0]; - shrt_out[2 * i + 1] = flt_in[2 * i + 1]; - } - - return i; -} - -/* Comlpex short to float conversion */ -static int short_to_float(float *flt_out, short *shrt_in, int num) -{ - int i; - - for (i = 0; i < num; i++) { - flt_out[2 * i + 0] = shrt_in[2 * i + 0]; - flt_out[2 * i + 1] = shrt_in[2 * i + 1]; - } - - return i; -} - -/* Receive a timestamped chunk from the device */ -void RadioInterface::pullBuffer() -{ - bool local_underrun; - - /* Read samples. Fail if we don't get what we want. */ - int num_rd = mRadio->readSamples(rx_buf, OUTCHUNK, &overrun, - readTimestamp, &local_underrun); - - LOG(DEBUG) << "Rx read " << num_rd << " samples from device"; - assert(num_rd == OUTCHUNK); - - underrun |= local_underrun; - readTimestamp += (TIMESTAMP) num_rd; - - short_to_float(rcvBuffer + 2 * rcvCursor, rx_buf, num_rd); - rcvCursor += num_rd; -} - -/* Send timestamped chunk to the device with arbitrary size */ -void RadioInterface::pushBuffer() -{ - if (sendCursor < INCHUNK) - return; - - float_to_short(tx_buf, sendBuffer, sendCursor); - - /* Write samples. Fail if we don't get what we want. */ - int num_smpls = mRadio->writeSamples(tx_buf, - sendCursor, - &underrun, - writeTimestamp); - assert(num_smpls == sendCursor); - - writeTimestamp += (TIMESTAMP) num_smpls; - sendCursor = 0; -} diff --git a/Transceiver52M/radioInterface.cpp b/Transceiver52M/radioInterface.cpp index 95b8ab6..3cc15db 100644 --- a/Transceiver52M/radioInterface.cpp +++ b/Transceiver52M/radioInterface.cpp @@ -27,6 +27,28 @@ bool started = false; +/* Device side buffers */ +static short rx_buf[OUTCHUNK * 2 * 2]; +static short tx_buf[INCHUNK * 2 * 2]; + +/* Complex float to short conversion */ +static void floatToShort(short *out, float *in, int num) +{ + for (int i = 0; i < num; i++) { + out[2 * i + 0] = (short) in[2 * i + 0]; + out[2 * i + 1] = (short) in[2 * i + 1]; + } +} + +/* Complex short to float conversion */ +static void shortToFloat(float *out, short *in, int num) +{ + for (int i = 0; i < num; i++) { + out[2 * i + 0] = (float) in[2 * i + 0]; + out[2 * i + 1] = (float) in[2 * i + 1]; + } +} + RadioInterface::RadioInterface(RadioDevice *wRadio, int wReceiveOffset, int wSPS, @@ -236,3 +258,41 @@ double RadioInterface::getRxGain() else return -1; } + +/* Receive a timestamped chunk from the device */ +void RadioInterface::pullBuffer() +{ + bool local_underrun; + + /* Read samples. Fail if we don't get what we want. */ + int num_rd = mRadio->readSamples(rx_buf, OUTCHUNK, &overrun, + readTimestamp, &local_underrun); + + LOG(DEBUG) << "Rx read " << num_rd << " samples from device"; + assert(num_rd == OUTCHUNK); + + underrun |= local_underrun; + readTimestamp += (TIMESTAMP) num_rd; + + shortToFloat(rcvBuffer + 2 * rcvCursor, rx_buf, num_rd); + rcvCursor += num_rd; +} + +/* Send timestamped chunk to the device with arbitrary size */ +void RadioInterface::pushBuffer() +{ + if (sendCursor < INCHUNK) + return; + + floatToShort(tx_buf, sendBuffer, sendCursor); + + /* Write samples. Fail if we don't get what we want. */ + int num_smpls = mRadio->writeSamples(tx_buf, + sendCursor, + &underrun, + writeTimestamp); + assert(num_smpls == sendCursor); + + writeTimestamp += (TIMESTAMP) num_smpls; + sendCursor = 0; +} diff --git a/Transceiver52M/radioInterface.h b/Transceiver52M/radioInterface.h index 216cf3e..94d8917 100644 --- a/Transceiver52M/radioInterface.h +++ b/Transceiver52M/radioInterface.h @@ -31,7 +31,7 @@ static const unsigned gSlotLen = 148; ///< number of symbols per slot, not /** class to interface the transceiver with the USRP */ class RadioInterface { -private: +protected: Thread mAlignRadioServiceLoopThread; ///< thread that synchronizes transmit and receive sections @@ -63,6 +63,8 @@ private: int mNumARFCNs; signalVector *finalVec, *finalVec9; +private: + /** format samples to USRP */ int radioifyVector(signalVector &wVector, float *floatVector, @@ -73,10 +75,10 @@ private: int unRadioifyVector(float *floatVector, signalVector &wVector); /** push GSM bursts into the transmit buffer */ - void pushBuffer(void); + virtual void pushBuffer(void); /** pull GSM bursts from the receive buffer */ - void pullBuffer(void); + virtual void pullBuffer(void); public: @@ -154,3 +156,18 @@ protected: /** synchronization thread loop */ void *AlignRadioServiceLoopAdapter(RadioInterface*); #endif + +class RadioInterfaceResamp : public RadioInterface { + +private: + + void pushBuffer(); + void pullBuffer(); + +public: + + RadioInterfaceResamp(RadioDevice* wRadio = NULL, + int receiveOffset = 3, + int wSPS = SAMPSPERSYM, + GSM::Time wStartTime = GSM::Time(0)); +}; diff --git a/Transceiver52M/radioIOResamp.cpp b/Transceiver52M/radioInterfaceResamp.cpp index 8e8ac75..c7f17ea 100644 --- a/Transceiver52M/radioIOResamp.cpp +++ b/Transceiver52M/radioInterfaceResamp.cpp @@ -271,8 +271,16 @@ int tx_resmpl_flt_int(short *smpls_out, float *smpls_in, int num_smpls) return num_resmpl; } +RadioInterfaceResamp::RadioInterfaceResamp(RadioDevice *wRadio, + int wReceiveOffset, + int wSPS, + GSM::Time wStartTime) + : RadioInterface(wRadio, wReceiveOffset, wSPS, wStartTime) +{ +} + /* Receive a timestamped chunk from the device */ -void RadioInterface::pullBuffer() +void RadioInterfaceResamp::pullBuffer() { int num_cv, num_rd; bool local_underrun; @@ -297,7 +305,7 @@ void RadioInterface::pullBuffer() } /* Send a timestamped chunk to the device */ -void RadioInterface::pushBuffer() +void RadioInterfaceResamp::pushBuffer() { int num_cv, num_wr; diff --git a/Transceiver52M/runTransceiver.cpp b/Transceiver52M/runTransceiver.cpp index 6b35797..e61ba34 100644 --- a/Transceiver52M/runTransceiver.cpp +++ b/Transceiver52M/runTransceiver.cpp @@ -84,7 +84,8 @@ int main(int argc, char *argv[]) srandom(time(NULL)); RadioDevice *usrp = RadioDevice::make(SAMPSPERSYM); - if (!usrp->open(deviceArgs)) { + int radioType = usrp->open(deviceArgs); + if (radioType < 0) { LOG(ALERT) << "Transceiver exiting..." << std::endl; return EXIT_FAILURE; } @@ -102,7 +103,19 @@ int main(int argc, char *argv[]) LOG(INFO) << "transceiver using transmit antenna " << usrp->getRxAntenna(); LOG(INFO) << "transceiver using receive antenna " << usrp->getTxAntenna(); - RadioInterface* radio = new RadioInterface(usrp, 3, SAMPSPERSYM, false); + RadioInterface* radio; + switch (radioType) { + case RadioDevice::NORMAL: + radio = new RadioInterface(usrp, 3, SAMPSPERSYM, false); + break; + case RadioDevice::RESAMP: + radio = new RadioInterfaceResamp(usrp, 3, SAMPSPERSYM, false); + break; + default: + LOG(ALERT) << "Unsupported configuration"; + return EXIT_FAILURE; + } + Transceiver *trx = new Transceiver(gConfig.getNum("TRX.Port"),gConfig.getStr("TRX.IP").c_str(),SAMPSPERSYM,GSM::Time(3,0),radio); trx->receiveFIFO(radio->receiveFIFO()); diff --git a/configure.ac b/configure.ac index 1c96f51..3cf2783 100644 --- a/configure.ac +++ b/configure.ac @@ -72,11 +72,6 @@ AC_ARG_WITH(singledb, [ [enable single daughterboard use on USRP1]) ]) -AC_ARG_WITH(resamp, [ - AS_HELP_STRING([--with-resamp], - [enable resampling for non-52MHz devices]) -]) - AC_ARG_WITH(extref, [ AS_HELP_STRING([--with-extref], [enable external reference on UHD devices]) @@ -102,10 +97,6 @@ AS_IF([test "x$with_uhd" = "xyes"],[ AC_DEFINE(USE_UHD, 1, Define to 1 if using UHD) ]) -AS_IF([test "x$with_resamp" = "xyes"], [ - AC_DEFINE(RESAMPLE, 1, Define to 1 for resampling) -]) - AS_IF([test "x$with_extref" = "xyes"], [ AC_DEFINE(EXTREF, 1, Define to 1 for external reference) ]) @@ -114,7 +105,6 @@ AS_IF([test "x$with_singledb" = "xyes"], [ AC_DEFINE(SINGLEDB, 1, Define to 1 for single daughterboard) ]) -AM_CONDITIONAL(RESAMPLE, [test "x$with_resamp" = "xyes"]) AM_CONDITIONAL(UHD, [test "x$with_uhd" = "xyes"]) AM_CONDITIONAL(USRP1, [test "x$with_usrp1" = "xyes"]) |