diff options
-rw-r--r-- | CMakeLists.txt | 51 | ||||
-rw-r--r-- | CommonLibs/CMakeLists.txt | 50 | ||||
-rw-r--r-- | GSM/CMakeLists.txt | 23 | ||||
-rw-r--r-- | INSTALLATION | 34 | ||||
-rw-r--r-- | Transceiver52M/CMakeLists.txt | 67 | ||||
-rw-r--r-- | Transceiver52M/XTRXDevice.cpp | 397 | ||||
-rw-r--r-- | Transceiver52M/XTRXDevice.h | 166 | ||||
-rw-r--r-- | Transceiver52M/osmo-trx.cpp | 4 | ||||
-rw-r--r-- | Transceiver52M/x86/CMakeLists.txt | 24 | ||||
-rw-r--r-- | cmake/FindFFTW.cmake | 96 | ||||
-rw-r--r-- | cmake/FindXTRX.cmake | 69 |
11 files changed, 948 insertions, 33 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5f80118 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 2.8) +project(osmo-trx C CXX) + +set(CMAKE_CXX_STANDARD 11) + +# Set the version information here +set(MAJOR_VERSION 0) +set(API_COMPAT 0) +set(MINOR_VERSION 1) +set(MAINT_VERSION git) + +set(LIBVER "${MAJOR_VERSION}.${API_COMPAT}.${MINOR_VERSION}") + +include_directories(CommonLibs) +include_directories(GSM) + +add_definitions(-Wall -g) + +#set(BUILD_SHARED_LIBS ON) + +CONFIGURE_FILE( + ${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/config.h +@ONLY) + +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +option(TRANS_FULL_VERSION "Compile with all Multichannel/Resampler support" OFF) +#option(SQLITE_CONFIG "Use config values from SQLite3 database" OFF) +set(SQLITE_CONFIG ON) + +if(TRANS_FULL_VERSION) + find_package(FFTW) +endif(TRANS_FULL_VERSION) + +find_package(XTRX) + +if(SQLITE_CONFIG) + find_library(sqlite3 sqlite3) +else(SQLITE_CONFIG) + add_definitions(-DNO_SQLITE_CONFIG) +endif(SQLITE_CONFIG) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + + +add_subdirectory(CommonLibs) +add_subdirectory(GSM) +add_subdirectory(Transceiver52M) + + diff --git a/CommonLibs/CMakeLists.txt b/CommonLibs/CMakeLists.txt new file mode 100644 index 0000000..7ce63d7 --- /dev/null +++ b/CommonLibs/CMakeLists.txt @@ -0,0 +1,50 @@ +# +# Copyright 2008, 2009 Free Software Foundation, Inc. +# Copyright 2011, 2012 Range Networks, Inc. +# +# This software is distributed under the terms of the GNU Public License. +# See the COPYING file in the main directory for details. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +set(EXTRA_DIST example.config README.common) + +set(libcommon_files + BitVector.cpp + LinkedLists.cpp + Sockets.cpp + Threads.cpp + Timeval.cpp + Logger.cpp) + +if(SQLITE_CONFIG) + set(libcommon_files + ${libcommon_files} + Configuration.cpp + sqlite3util.cpp) +endif(SQLITE_CONFIG) + +add_library(common ${libcommon_files}) + +add_executable(InterthreadTest InterthreadTest.cpp) +target_link_libraries(InterthreadTest common pthread) + +add_executable(SocketsTest SocketsTest.cpp) +target_link_libraries(SocketsTest common pthread) + +add_executable(TimevalTest TimevalTest.cpp) +target_link_libraries(TimevalTest common) + + diff --git a/GSM/CMakeLists.txt b/GSM/CMakeLists.txt new file mode 100644 index 0000000..d0f14b8 --- /dev/null +++ b/GSM/CMakeLists.txt @@ -0,0 +1,23 @@ +# +# Copyright 2008, 2009 Free Software Foundation, Inc. +# +# This software is distributed under the terms of the GNU Public License. +# See the COPYING file in the main directory for details. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +set(libGSM_files GSMCommon.cpp) +add_library(GSM ${libGSM_files}) + diff --git a/INSTALLATION b/INSTALLATION index 3e35d7e..a05f846 100644 --- a/INSTALLATION +++ b/INSTALLATION @@ -1,33 +1 @@ -Installation Requirements - - - -OpenBTS compiles to a simple Unix binary and does not require special -installation. - -One some systems (Ubuntu), you will need to define LIBS = -lpthread prior to -running configure. - -To run OpenBTS, the following should be installed: - - Asterisk (http://www.asterisk.org), running SIP on port 5060. - - libosip2 (http://www.gnu.org/software/osip/) - - libortp (http://freshmeat.net/projects/ortp/) - - libusrp (http://gnuradio.org). - This is part of the GNURadio installation. - It is the only part used by OpenBTS. - - -OpenBTS logs to syslogd as facility LOG_LOCAL7. Please set your /etc/syslog.conf -accordingly. - - -For information on specific executables, see tests/README.tests and -apps/README.apps. - -See http://gnuradio.org/redmine/wiki/gnuradio/OpenBTS/BuildingAndRunning for more -information. - +This is special branch for XTRX support. It should be configured with cmake, autoconf isn't supported yet.
\ No newline at end of file diff --git a/Transceiver52M/CMakeLists.txt b/Transceiver52M/CMakeLists.txt new file mode 100644 index 0000000..6c012d2 --- /dev/null +++ b/Transceiver52M/CMakeLists.txt @@ -0,0 +1,67 @@ +if(NOT TRANS_FULL_VERSION) + add_definitions(-DNO_RESAMPLER) + add_definitions(-DNO_MULTIARFCN) +endif() + + +add_subdirectory(x86) +include_directories(common) +include_directories(".") + +set(COMMON_FILES + radioInterface.cpp + radioVector.cpp + radioClock.cpp + radioBuffer.cpp + sigProcLib.cpp + signalVector.cpp + Transceiver.cpp) + +set(libtransceiver_files + Resampler.cpp + ${COMMON_FILES}) + +if(TRANS_FULL_VERSION) + set(libtransceiver_files + ${libtransceiver_files} + radioInterfaceResamp.cpp + radioInterfaceMulti.cpp + ChannelizerBase.cpp + Channelizer.cpp + Synthesis.cpp + common/fft.c + radioInterfaceDiversity.cpp) +endif(TRANS_FULL_VERSION) + +set(noinst_HEADERS + Complex.h + radioInterface.h + radioVector.h + radioClock.h + radioDevice.h + radioBuffer.h + sigProcLib.h + signalVector.h + Transceiver.h + USRPDevice.h + Resampler.h + ChannelizerBase.h + Channelizer.h + Synthesis.h + common/convolve.h + common/convert.h + common/scale.h + common/mult.h + common/fft.h) + +add_library(transceiver ${libtransceiver_files}) + + +set(DEVICE XTRXDevice.cpp) +set(DEVICE_LIBS ${XTRX_LIBRARIES}) +set(DEVICE_INC ${XTRX_INCLUDES}) + +include_directories(${DEVICE_INC}) +add_executable(osmo-trx osmo-trx.cpp ${DEVICE}) +target_link_libraries(osmo-trx transceiver arch GSM common ${sqlite3} ${FFTW_LIBRARIES} ${DEVICE_LIBS} pthread dl) + diff --git a/Transceiver52M/XTRXDevice.cpp b/Transceiver52M/XTRXDevice.cpp new file mode 100644 index 0000000..13b8035 --- /dev/null +++ b/Transceiver52M/XTRXDevice.cpp @@ -0,0 +1,397 @@ +#include <stdint.h> +#include <string.h> +#include <stdlib.h> +#include "Threads.h" +#include "XTRXDevice.h" + +#include <Logger.h> +#include <errno.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +using namespace std; + +const double defaultRXBandwidth = 2e6; +const double defaultTXBandwidth = 3e6; + +static int time_tx_corr = 60; //20+20+20+20+20; + +XTRXDevice::XTRXDevice(size_t txsps, size_t rxsps) +{ + LOG(INFO) << "creating XTRX device..."; + + this->txsps = txsps; + this->rxsps = rxsps; + + rxGain = 0; + + loopback = false; + device = NULL; +} + +static int parse_config(const char* line, const char* argument, int default_value) +{ + const char* arg_found = strstr(line, argument); + if (!arg_found) + return default_value; + + const char* qe_pos = strchr(arg_found, '='); + if (!qe_pos) + return default_value; + + int res = strtol(qe_pos + 1, NULL, 10); + if (res == 0 && errno) { + return default_value; + } + + return res; +} + +int XTRXDevice::open(const std::string &args, int ref, bool swap_channels) +{ + LOG(INFO) << "opening XTRX device '" << args << "'.."; + + int loglevel = parse_config(args.c_str(), "loglevel", 3); + int lb_param = parse_config(args.c_str(), "loopback", 0); + time_tx_corr = parse_config(args.c_str(), "tcorr", time_tx_corr); + int fref = parse_config(args.c_str(), "refclk", 30720000); + int rxdec = parse_config(args.c_str(), "rxdec", 0); + + char xtrx_name[500]; + const char* lend = strchr(args.c_str(), ','); + int len = (lend) ? (lend - args.c_str()) : sizeof(xtrx_name) - 1; + strncpy(xtrx_name, args.c_str(), len); + xtrx_name[len] = 0; + + if (lb_param) { + LOG(ALERT) << "XTRX LOOPBACK mode is set!"; + loopback = true; + } + + int res = xtrx_open(xtrx_name, loglevel, &device); + if (res) { + LOG(ALERT) << "XTRX creating failed, device " << xtrx_name << " code " << res; + return -1; + } + double actualMasterClock = 0; + + if (fref > 0) { + xtrx_set_ref_clk(device, fref, XTRX_CLKSRC_INT); + } + + res = xtrx_set_samplerate(device, + GSMRATE * (double) std::min(txsps, rxsps) * 32 * 4 * ((rxdec) ? 2 : 1), + GSMRATE * (double) rxsps, + GSMRATE * (double) txsps, + (rxdec) ? XTRX_SAMPLERATE_FORCE_RX_DECIM : 0, + &actualMasterClock, + &actualRXSampleRate, + &actualTXSampleRate); + if (res) { + LOG(ALERT) << "XTRX failed to set samplerate RX: " << GSMRATE * (double) rxsps + << " TX: " << GSMRATE * (double) txsps + << " res: " << res; + return -1; + } else { + LOG(INFO) << "XTRX set samplerate Master: " << actualMasterClock + << " RX: " << actualRXSampleRate + << " TX: " << actualTXSampleRate; + } + + + int i; + double bw; + double actualbw; + + actualbw = 0; + bw = defaultRXBandwidth; + for (i = 0, res = -1; res && (i < 4); i++, bw *= 1.5) { + res = xtrx_tune_rx_bandwidth(device, XTRX_CH_AB, bw, &actualbw); + } + if (res) { + LOG(ALERT) << "XTRX failed to set RX bandwidth: " << bw + << " res: " << res; + return -1; + } else { + LOG(INFO) << "XTRX set RX bandwidth: " << actualbw; + } + + actualbw = 0; + bw = defaultTXBandwidth; + for (i = 0, res = -1; res && (i < 4); i++, bw *= 1.1) { + res = xtrx_tune_tx_bandwidth(device, XTRX_CH_AB, bw, &actualbw); + } + if (res) { + LOG(ALERT) << "XTRX failed to set TX bandwidth: " << bw + << " res: " << res; + return -1; + } else { + LOG(INFO) << "XTRX set TX bandwidth: " << actualbw; + } + + samplesRead = 0; + samplesWritten = 0; + started = false; + + return NORMAL; +} + +XTRXDevice::~XTRXDevice() +{ + if (device) { + xtrx_close(device); + } +} + +bool XTRXDevice::start() +{ + LOG(INFO) << "starting XTRX..."; + if (started) { + return false; + } + + dataStart = 0; + dataEnd = 0; + timeStart = 0; + timeEnd = 0; + timeRx = initialReadTimestamp(); + timestampOffset = 0; + latestWriteTimestamp = 0; + lastPktTimestamp = 0; + hi32Timestamp = 0; + isAligned = false; + + //xtrx_stop(device, XTRX_TX); + //xtrx_stop(device, XTRX_RX); + + xtrx_set_antenna(device, XTRX_TX_L); + xtrx_set_antenna(device, XTRX_RX_L); + + xtrx_run_params_t params; + params.dir = XTRX_TRX; + params.nflags = (loopback) ? XTRX_RUN_DIGLOOPBACK : 0; + + params.rx.chs = XTRX_CH_AB; + params.rx.flags = XTRX_RSP_SISO_MODE; + params.rx.hfmt = XTRX_IQ_INT16; + params.rx.wfmt = XTRX_WF_16; + params.rx.paketsize = 625 * rxsps; + + params.tx.chs = XTRX_CH_AB; + params.tx.flags = XTRX_RSP_SISO_MODE; + params.tx.hfmt = XTRX_IQ_INT16; + params.tx.wfmt = XTRX_WF_16; + params.tx.paketsize = 625 * txsps; + + if (loopback) { + params.tx.flags |= XTRX_RSP_SWAP_AB | XTRX_RSP_SWAP_IQ; + } + + params.tx_repeat_buf = NULL; + params.rx_stream_start = initialReadTimestamp(); + + int res = xtrx_run_ex(device, ¶ms); + if (res) { + LOG(ALERT) << "XTRX start failed res: " << res; + } else { + LOG(INFO) << "XTRX started"; + started = true; + } + return started; +} + +bool XTRXDevice::stop() +{ + if (started) { + int res = xtrx_stop(device, XTRX_TRX); + if (res) { + LOG(ALERT) << "XTRX stop failed res: " << res; + } else { + LOG(INFO) << "XTRX stopped"; + started = false; + } + } + return !started; +} + +TIMESTAMP XTRXDevice::initialWriteTimestamp() +{ + if (/*(iface == MULTI_ARFCN) || */(rxsps == txsps)) + return initialReadTimestamp(); + else + return initialReadTimestamp() * txsps; +} + +double XTRXDevice::maxTxGain() +{ + return 30; +} + +double XTRXDevice::minTxGain() +{ + return 0; +} + +double XTRXDevice::maxRxGain() +{ + return 30; +} + +double XTRXDevice::minRxGain() +{ + return 0; +} + +double XTRXDevice::setTxGain(double dB, size_t chan) +{ + if (chan) { + LOG(ALERT) << "Invalid channel " << chan; + return 0.0; + } + double actual = 0; + LOG(NOTICE) << "Setting TX gain to " << dB << " dB."; + + int res = xtrx_set_gain(device, XTRX_CH_AB, XTRX_TX_PAD_GAIN, -10, &actual); + if (res) { + LOG(ERR) << "Error setting TX gain res: " << res; + } + + return actual; +} + + +double XTRXDevice::setRxGain(double dB, size_t chan) +{ + if (chan) { + LOG(ALERT) << "Invalid channel " << chan; + return 0.0; + } + double actual = 0; + LOG(NOTICE) << "Setting RX gain to " << dB << " dB."; + + int res = xtrx_set_gain(device, XTRX_CH_AB, XTRX_RX_LNA_GAIN, 25, &actual); + if (res) { + LOG(ERR) << "Error setting RX gain res: " << res; + } + + return actual; +} + +// NOTE: Assumes sequential reads +int XTRXDevice::readSamples(std::vector<short *> &bufs, int len, bool *overrun, + TIMESTAMP timestamp, bool *underrun, unsigned *RSSI) +{ + if (!started) + return -1; + + if (RSSI) { + *RSSI = 10; // TODO + } + + struct xtrx_recv_ex_info ri; + ri.samples = len; + ri.buffer_count = bufs.size(); + ri.buffers = (void* const*)&bufs[0]; + ri.flags = 0; + + int res = xtrx_recv_sync_ex(device, &ri); + if (res) { + LOG(ALERT) << "xtrx_recv_sync failed res " << res << " current TS " << timeRx << " req TS" << timestamp; + return -1; + } + timeRx += len; + + // TODO: remove this + int i; + for (i = 0; i < len * 2; i++) + bufs[0][i] <<= 4; + + if (underrun) { + *underrun = (ri.out_events & RCVEX_EVENT_FILLED_ZERO); + } + return len; + +} + +int XTRXDevice::writeSamples(std::vector<short *> &bufs, int len, + bool *underrun, unsigned long long timestamp, + bool isControl) +{ + if (!started) + return 0; + + xtrx_send_ex_info_t nfo; + nfo.buffers = (const void* const*)&bufs[0]; + nfo.buffer_count = bufs.size(); + nfo.flags = XTRX_TX_DONT_BUFFER; + nfo.samples = len; + nfo.ts = timestamp - time_tx_corr; + + int res = xtrx_send_sync_ex(device, &nfo); + if (res != 0) { + LOG(ALERT) << "xtrx_send_sync_ex returned " << res << " len=" << len << " ts=" << timestamp; + return 0; + } + + if (*underrun) { + *underrun = (nfo.out_flags & XTRX_TX_DISCARDED_TO); + } + + return len; +} + +bool XTRXDevice::updateAlignment(TIMESTAMP timestamp) +{ + LOG(ALERT) << "Update Aligment " << timestamp; + return true; +} + +bool XTRXDevice::setTxFreq(double wFreq, size_t chan) +{ + int res; + double actual = 0; + + if (chan) { + LOG(ALERT) << "Invalid channel " << chan; + return false; + } + + if ((res = xtrx_tune(device, XTRX_TUNE_TX_FDD, wFreq, &actual)) == 0) { + LOG(INFO) << "set RX: " << wFreq << std::endl + << " actual freq: " << actual << std::endl; + return true; + } + else { + LOG(ALERT) << "set RX: " << wFreq << "failed (code: " << res << ")" << std::endl; + return false; + } +} + +bool XTRXDevice::setRxFreq(double wFreq, size_t chan) +{ + int res; + double actual = 0; + + if (chan) { + LOG(ALERT) << "Invalid channel " << chan; + return false; + } + + if ((res = xtrx_tune(device, XTRX_TUNE_RX_FDD, wFreq, &actual)) == 0) { + LOG(INFO) << "set RX: " << wFreq << std::endl + << " actual freq: " << actual << std::endl; + return true; + } + else { + LOG(ALERT) << "set RX: " << wFreq << "failed (code: " << res << ")" << std::endl; + return false; + } +} + +RadioDevice *RadioDevice::make(size_t tx_sps, size_t rx_sps, InterfaceType type, + size_t chans, double offset) +{ + return new XTRXDevice(tx_sps, rx_sps); +} diff --git a/Transceiver52M/XTRXDevice.h b/Transceiver52M/XTRXDevice.h new file mode 100644 index 0000000..9b22ea4 --- /dev/null +++ b/Transceiver52M/XTRXDevice.h @@ -0,0 +1,166 @@ +#ifndef _XTRX_DEVICE_H_ +#define _XTRX_DEVICE_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "radioDevice.h" + +#include <stdint.h> +#include <sys/time.h> +#include <string> +#include <iostream> + +#include "Threads.h" +#include <xtrx_api.h> + +class XTRXDevice: public RadioDevice { +private: + int txsps; + int rxsps; + double actualTXSampleRate; ///< the actual XTRX sampling rate + double actualRXSampleRate; ///< the actual XTRX sampling rate + //unsigned int decimRate; ///< the XTRX decimation rate + //unsigned int interRate; ///< the XTRX decimation rate + + unsigned long long samplesRead; ///< number of samples read from XTRX + unsigned long long samplesWritten; ///< number of samples sent to XTRX + + bool started; ///< flag indicates XTRX has started + + short *data; + unsigned long dataStart; + unsigned long dataEnd; + TIMESTAMP timeStart; + TIMESTAMP timeEnd; + + TIMESTAMP timeRx; + bool isAligned; + + Mutex writeLock; + + short *currData; ///< internal data buffer when reading from XTRX + TIMESTAMP currTimestamp; ///< timestamp of internal data buffer + unsigned currLen; ///< size of internal data buffer + + 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 + + unsigned long hi32Timestamp; + unsigned long lastPktTimestamp; + + double rxGain; + bool loopback; + +#ifdef SWLOOPBACK + short loopbackBuffer[1000000]; + int loopbackBufferSize; + double samplePeriod; + + struct timeval startTime; + struct timeval lastReadTime; + bool firstRead; +#endif + + xtrx_dev* device; + public: + + /** Object constructor */ + XTRXDevice(size_t txsps, size_t rxsps); + + ~XTRXDevice(); + + /** Instantiate the XTRX */ + int open(const std::string &args, int ref, bool swap_channels); + + /** Start the XTRX */ + bool start(); + + /** Stop the XTRX */ + bool stop(); + + /** Set priority not supported */ + void setPriority(float prio = 0.5) { } + + enum TxWindowType getWindowType() { return TX_WINDOW_FIXED; } + + /** + Read samples from the XTRX. + @param buf preallocated buf to contain read result + @param len number of samples desired + @param overrun Set if read buffer has been overrun, e.g. data not being read fast enough + @param timestamp The timestamp of the first samples to be read + @param underrun Set if XTRX does not have data to transmit, e.g. data not being sent fast enough + @param RSSI The received signal strength of the read result + @return The number of samples actually read + */ + int readSamples(std::vector<short *> &buf, int len, bool *overrun, + TIMESTAMP timestamp = 0xffffffff, bool *underrun = NULL, + unsigned *RSSI = NULL); + /** + Write samples to the XTRX. + @param buf Contains the data to be written. + @param len number of samples to write. + @param underrun Set if XTRX does not have data to transmit, e.g. data not being sent fast enough + @param timestamp The timestamp of the first sample of the data buffer. + @param isControl Set if data is a control packet, e.g. a ping command + @return The number of samples actually written + */ + int writeSamples(std::vector<short *> &bufs, int len, bool *underrun, + TIMESTAMP timestamp = 0xffffffff, bool isControl = false); + + /** Update the alignment between the read and write timestamps */ + bool updateAlignment(TIMESTAMP timestamp); + + /** Set the transmitter frequency */ + bool setTxFreq(double wFreq, size_t chan = 0); + + /** Set the receiver frequency */ + bool setRxFreq(double wFreq, size_t chan = 0); + + /** Returns the starting write Timestamp*/ + TIMESTAMP initialWriteTimestamp(void); + + /** Returns the starting read Timestamp*/ + TIMESTAMP initialReadTimestamp(void) { return 20000;} + + /** returns the full-scale transmit amplitude **/ + double fullScaleInputValue() {return (double) 32767*0.7;} + + /** returns the full-scale receive amplitude **/ + double fullScaleOutputValue() {return (double) 32767;} + + /** sets the receive chan gain, returns the gain setting **/ + double setRxGain(double dB, size_t chan = 0); + + /** get the current receive gain */ + double getRxGain(size_t chan = 0) { return rxGain; } + + /** return maximum Rx Gain **/ + double maxRxGain(void); + + /** return minimum Rx Gain **/ + double minRxGain(void); + + /** sets the transmit chan gain, returns the gain setting **/ + double setTxGain(double dB, size_t chan = 0); + + /** return maximum Tx Gain **/ + double maxTxGain(void); + + /** return minimum Rx Gain **/ + double minTxGain(void); + + /** Return internal status values */ + inline double getTxFreq(size_t chan = 0) { return 0; } + inline double getRxFreq(size_t chan = 0) { return 0; } + inline double getSampleRate() { return actualTXSampleRate; } + inline double numberRead() { return samplesRead; } + inline double numberWritten() { return samplesWritten; } + +}; + +#endif // _XTRX_DEVICE_H_ + diff --git a/Transceiver52M/osmo-trx.cpp b/Transceiver52M/osmo-trx.cpp index 3f72fb7..b0d04ac 100644 --- a/Transceiver52M/osmo-trx.cpp +++ b/Transceiver52M/osmo-trx.cpp @@ -169,15 +169,19 @@ RadioInterface *makeRadioInterface(struct trx_config *config, radio = new RadioInterface(usrp, config->tx_sps, config->rx_sps, config->chans); break; +#ifndef NO_RESAMPLER case RadioDevice::RESAMP_64M: case RadioDevice::RESAMP_100M: radio = new RadioInterfaceResamp(usrp, config->tx_sps, config->rx_sps); break; +#endif +#ifndef NO_MULTIARFCN case RadioDevice::MULTI_ARFCN: radio = new RadioInterfaceMulti(usrp, config->tx_sps, config->rx_sps, config->chans); break; +#endif default: LOG(ALERT) << "Unsupported radio interface configuration"; return NULL; diff --git a/Transceiver52M/x86/CMakeLists.txt b/Transceiver52M/x86/CMakeLists.txt new file mode 100644 index 0000000..f7dbd26 --- /dev/null +++ b/Transceiver52M/x86/CMakeLists.txt @@ -0,0 +1,24 @@ +include_directories(../common) + +set(libarch_files + ../common/convert_base.c + ../common/convolve_base.c + convert.c + convolve.c) + +# TODO move to cmakedef +add_definitions(-DHAVE___BUILTIN_CPU_SUPPORTS) + +if(HAVE_SSE4_1) + add_definitions(-DHAVE_SSE4_1) + set(libarch_files ${libarch_files} convert_sse_4_1.c) +endif(HAVE_SSE4_1) + +if(HAVE_SSE3) + add_definitions(-HAVE_SSE3) + set(libarch_files ${libarch_files} convert_sse_3.c convert_sse_3.c) +endif(HAVE_SSE3) + + +add_library(arch ${libarch_files}) + diff --git a/cmake/FindFFTW.cmake b/cmake/FindFFTW.cmake new file mode 100644 index 0000000..2da4277 --- /dev/null +++ b/cmake/FindFFTW.cmake @@ -0,0 +1,96 @@ +# - Find the FFTW library +# +# Usage: +# find_package(FFTW [REQUIRED] [QUIET] ) +# +# It sets the following variables: +# FFTW_FOUND ... true if fftw is found on the system +# FFTW_LIBRARIES ... full path to fftw library +# FFTW_INCLUDES ... fftw include directory +# +# The following variables will be checked by the function +# FFTW_USE_STATIC_LIBS ... if true, only static libraries are found +# FFTW_ROOT ... if set, the libraries are exclusively searched +# under this path +# FFTW_LIBRARY ... fftw library to use +# FFTW_INCLUDE_DIR ... fftw include directory +# +#If environment variable FFTWDIR is specified, it has same effect as FFTW_ROOT +if( NOT FFTW_ROOT AND ENV{FFTWDIR} ) + set( FFTW_ROOT $ENV{FFTWDIR} ) +endif() +# Check if we can use PkgConfig +find_package(PkgConfig) +#Determine from PKG +if( PKG_CONFIG_FOUND AND NOT FFTW_ROOT ) + pkg_check_modules( PKG_FFTW QUIET "fftw3" ) +endif() +#Check whether to search static or dynamic libs +set( CMAKE_FIND_LIBRARY_SUFFIXES_SAV ${CMAKE_FIND_LIBRARY_SUFFIXES} ) +if( ${FFTW_USE_STATIC_LIBS} ) + set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX} ) +else() + set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX} ) +endif() +if( FFTW_ROOT ) + #find libs + find_library( + FFTW_LIB + NAMES "fftw3" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + find_library( + FFTWF_LIB + NAMES "fftw3f" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + find_library( + FFTWL_LIB + NAMES "fftw3l" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + #find includes + find_path( + FFTW_INCLUDES + NAMES "fftw3.h" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "include" + NO_DEFAULT_PATH + ) +else() + find_library( + FFTW_LIB + NAMES "fftw3" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + ) + find_library( + FFTWF_LIB + NAMES "fftw3f" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + ) + find_library( + FFTWL_LIB + NAMES "fftw3l" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + ) + find_path( + FFTW_INCLUDES + NAMES "fftw3.h" + PATHS ${PKG_FFTW_INCLUDE_DIRS} ${INCLUDE_INSTALL_DIR} + ) +endif( FFTW_ROOT ) +set(FFTW_LIBRARIES ${FFTW_LIB} ${FFTWF_LIB}) +if(FFTWL_LIB) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTWL_LIB}) +endif() +set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAV} ) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(FFTW DEFAULT_MSG + FFTW_INCLUDES FFTW_LIBRARIES) +mark_as_advanced(FFTW_INCLUDES FFTW_LIBRARIES FFTW_LIB FFTWF_LIB FFTWL_LIB) diff --git a/cmake/FindXTRX.cmake b/cmake/FindXTRX.cmake new file mode 100644 index 0000000..bb0f355 --- /dev/null +++ b/cmake/FindXTRX.cmake @@ -0,0 +1,69 @@ +# - Find the XTRX library +# +# Usage: +# find_package(XTRX [REQUIRED] [QUIET] ) +# +# It sets the following variables: +# XTRX_FOUND ... true if XTRX is found on the system +# XTRX_LIBRARIES ... full path to XTRX library +# XTRX_INCLUDES ... XTRX include directory +# +# The following variables will be checked by the function +# XTRX_USE_STATIC_LIBS ... if true, only static libraries are found +# XTRX_ROOT ... if set, the libraries are exclusively searched +# under this path +# XTRX_LIBRARY ... XTRX library to use +# XTRX_INCLUDE_DIR ... XTRX include directory +# +#If environment variable XTRXDIR is specified, it has same effect as XTRX_ROOT +if( NOT XTRX_ROOT AND ENV{XTRXDIR} ) + set( XTRX_ROOT $ENV{XTRXDIR} ) +endif() +# Check if we can use PkgConfig +find_package(PkgConfig) +#Determine from PKG +if( PKG_CONFIG_FOUND AND NOT XTRX_ROOT ) + pkg_check_modules( PKG_XTRX QUIET "libxtrx" ) +endif() +#Check whether to search static or dynamic libs +set( CMAKE_FIND_LIBRARY_SUFFIXES_SAV ${CMAKE_FIND_LIBRARY_SUFFIXES} ) +if( ${XTRX_USE_STATIC_LIBS} ) + set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX} ) +else() + set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX} ) +endif() +if( XTRX_ROOT ) + #find libs + find_library( + XTRX_LIB + NAMES "xtrx" + PATHS ${XTRX_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + #find includes + find_path( + XTRX_INCLUDES + NAMES "xtrx_api.h" + PATHS ${XTRX_ROOT} + PATH_SUFFIXES "include" + NO_DEFAULT_PATH + ) +else() + find_library( + XTRX_LIB + NAMES "xtrx" + PATHS ${PKG_XTRX_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + ) + find_path( + XTRX_INCLUDES + NAMES "xtrx_api.h" + PATHS ${PKG_XTRX_INCLUDE_DIRS} ${INCLUDE_INSTALL_DIR} + ) +endif( XTRX_ROOT ) +set(XTRX_LIBRARIES ${XTRX_LIB}) +set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAV} ) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(XTRX DEFAULT_MSG + XTRX_INCLUDES XTRX_LIBRARIES) +mark_as_advanced(XTRX_INCLUDES XTRX_LIBRARIES XTRX_LIB XTRXF_LIB XTRXL_LIB) |