From b5def414b8c485c8fb434a427ed8f4df427ae224 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Fri, 3 May 2019 21:08:40 +0200 Subject: smpl_buf: Move it to device/common and create libdevice_common.la Since in next commit osmo-trx-lms starts using smpl_buf.cpp, it seems some automake step doesn't like including a cpp file twice from a different directory, since race conditions can occur building it. Instead we define the dependency by first building a static lib and then using it on each libdevice.la (one per device type). We already do the similar under arch/ subdir, where we have a common/ subdir and then one subdir and lib per architecture. Change-Id: I465ad0f6d5569bb3006d711c8fd0df14391fcf35 --- Transceiver52M/Makefile.am | 2 +- Transceiver52M/device/Makefile.am | 4 +- Transceiver52M/device/common/Makefile.am | 12 ++ Transceiver52M/device/common/radioDevice.h | 208 +++++++++++++++++++++++++++++ Transceiver52M/device/common/smpl_buf.cpp | 169 +++++++++++++++++++++++ Transceiver52M/device/common/smpl_buf.h | 87 ++++++++++++ Transceiver52M/device/lms/Makefile.am | 2 +- Transceiver52M/device/radioDevice.h | 208 ----------------------------- Transceiver52M/device/smpl_buf.cpp | 169 ----------------------- Transceiver52M/device/smpl_buf.h | 87 ------------ Transceiver52M/device/uhd/Makefile.am | 5 +- Transceiver52M/device/usrp1/Makefile.am | 2 +- configure.ac | 1 + 13 files changed, 484 insertions(+), 472 deletions(-) create mode 100644 Transceiver52M/device/common/Makefile.am create mode 100644 Transceiver52M/device/common/radioDevice.h create mode 100644 Transceiver52M/device/common/smpl_buf.cpp create mode 100644 Transceiver52M/device/common/smpl_buf.h delete mode 100644 Transceiver52M/device/radioDevice.h delete mode 100644 Transceiver52M/device/smpl_buf.cpp delete mode 100644 Transceiver52M/device/smpl_buf.h diff --git a/Transceiver52M/Makefile.am b/Transceiver52M/Makefile.am index 28c47ab..89ab796 100644 --- a/Transceiver52M/Makefile.am +++ b/Transceiver52M/Makefile.am @@ -23,7 +23,7 @@ include $(top_srcdir)/Makefile.common SUBDIRS = arch device -AM_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) -I${srcdir}/arch/common -I${srcdir}/device +AM_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) -I${srcdir}/arch/common -I${srcdir}/device/common AM_CXXFLAGS = -lpthread $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS) rev2dir = $(datadir)/usrp/rev2 diff --git a/Transceiver52M/device/Makefile.am b/Transceiver52M/device/Makefile.am index e653a9e..369e877 100644 --- a/Transceiver52M/device/Makefile.am +++ b/Transceiver52M/device/Makefile.am @@ -1,8 +1,6 @@ include $(top_srcdir)/Makefile.common -noinst_HEADERS = radioDevice.h smpl_buf.h - -SUBDIRS = +SUBDIRS = common if DEVICE_USRP1 SUBDIRS += usrp1 diff --git a/Transceiver52M/device/common/Makefile.am b/Transceiver52M/device/common/Makefile.am new file mode 100644 index 0000000..e14cc38 --- /dev/null +++ b/Transceiver52M/device/common/Makefile.am @@ -0,0 +1,12 @@ +include $(top_srcdir)/Makefile.common + +AM_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) +AM_CXXFLAGS = -lpthread $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LMS_CFLAGS) + + +noinst_HEADERS = radioDevice.h smpl_buf.h + +noinst_LTLIBRARIES = libdevice_common.la + +libdevice_common_la_SOURCES = \ + smpl_buf.cpp diff --git a/Transceiver52M/device/common/radioDevice.h b/Transceiver52M/device/common/radioDevice.h new file mode 100644 index 0000000..30e0f43 --- /dev/null +++ b/Transceiver52M/device/common/radioDevice.h @@ -0,0 +1,208 @@ +/* +* Copyright 2008 Free Software Foundation, Inc. +* +* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribuion. +* +* This use of this software may be subject to additional restrictions. +* See the LEGAL file in the main directory for details. + + 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. + +*/ + +#ifndef __RADIO_DEVICE_H__ +#define __RADIO_DEVICE_H__ + +#include +#include + +#include "GSMCommon.h" +#include "Logger.h" + +extern "C" { +#include "config_defs.h" +} + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define GSMRATE (1625e3/6) +#define MCBTS_SPACING 800000.0 + +/** a 64-bit virtual timestamp for radio data */ +typedef unsigned long long TIMESTAMP; + +/** A class to handle a USRP rev 4, with a two RFX900 daughterboards */ +class RadioDevice { + + public: + /* Available transport bus types */ + enum TxWindowType { TX_WINDOW_USRP1, TX_WINDOW_FIXED, TX_WINDOW_LMS1 }; + + /* Radio interface types */ + enum InterfaceType { + NORMAL, + RESAMP_64M, + RESAMP_100M, + MULTI_ARFCN, + }; + + static RadioDevice *make(size_t tx_sps, size_t rx_sps, InterfaceType type, + size_t chans = 1, double offset = 0.0, + const std::vector& tx_paths = std::vector(1, ""), + const std::vector& rx_paths = std::vector(1, "")); + + /** Initialize the USRP */ + virtual int open(const std::string &args, int ref, bool swap_channels)=0; + + virtual ~RadioDevice() { } + + /** Start the USRP */ + virtual bool start()=0; + + /** Stop the USRP */ + virtual bool stop()=0; + + /** Get the Tx window type */ + virtual enum TxWindowType getWindowType()=0; + + /** Enable thread priority */ + virtual void setPriority(float prio = 0.5) = 0; + + /** + Read samples from the radio. + @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 radio 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 + */ + virtual int readSamples(std::vector &bufs, int len, bool *overrun, + TIMESTAMP timestamp = 0xffffffff, bool *underrun = 0, + unsigned *RSSI = 0) = 0; + /** + Write samples to the radio. + @param buf Contains the data to be written. + @param len number of samples to write. + @param underrun Set if radio 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 + */ + virtual int writeSamples(std::vector &bufs, int len, bool *underrun, + TIMESTAMP timestamp, bool isControl = false) = 0; + + /** Update the alignment between the read and write timestamps */ + virtual bool updateAlignment(TIMESTAMP timestamp)=0; + + /** Set the transmitter frequency */ + virtual bool setTxFreq(double wFreq, size_t chan = 0) = 0; + + /** Set the receiver frequency */ + virtual bool setRxFreq(double wFreq, size_t chan = 0) = 0; + + /** Returns the starting write Timestamp*/ + virtual TIMESTAMP initialWriteTimestamp(void)=0; + + /** Returns the starting read Timestamp*/ + virtual TIMESTAMP initialReadTimestamp(void)=0; + + /** returns the full-scale transmit amplitude **/ + virtual double fullScaleInputValue()=0; + + /** returns the full-scale receive amplitude **/ + virtual double fullScaleOutputValue()=0; + + /** sets the receive chan gain, returns the gain setting **/ + virtual double setRxGain(double dB, size_t chan = 0) = 0; + + /** gets the current receive gain **/ + virtual double getRxGain(size_t chan = 0) = 0; + + /** return maximum Rx Gain **/ + virtual double maxRxGain(void) = 0; + + /** return minimum Rx Gain **/ + virtual double minRxGain(void) = 0; + + /** sets the transmit chan gain, returns the gain setting **/ + virtual double setTxGain(double dB, size_t chan = 0) = 0; + + /** return maximum Tx Gain **/ + virtual double maxTxGain(void) = 0; + + /** return minimum Tx Gain **/ + virtual double minTxGain(void) = 0; + + /** sets the RX path to use, returns true if successful and false otherwise */ + virtual bool setRxAntenna(const std::string &ant, size_t chan = 0) = 0; + + /** return the used RX path */ + virtual std::string getRxAntenna(size_t chan = 0) = 0; + + /** sets the RX path to use, returns true if successful and false otherwise */ + virtual bool setTxAntenna(const std::string &ant, size_t chan = 0) = 0; + + /** return the used RX path */ + virtual std::string getTxAntenna(size_t chan = 0) = 0; + + /** return whether user drives synchronization of Tx/Rx of USRP */ + virtual bool requiresRadioAlign() = 0; + + /** Minimum latency that the device can achieve */ + virtual GSM::Time minLatency() = 0; + + /** Return internal status values */ + virtual double getTxFreq(size_t chan = 0) = 0; + virtual double getRxFreq(size_t chan = 0) = 0; + virtual double getSampleRate()=0; + + protected: + size_t tx_sps, rx_sps; + InterfaceType iface; + size_t chans; + double lo_offset; + std::vector tx_paths, rx_paths; + + RadioDevice(size_t tx_sps, size_t rx_sps, InterfaceType type, size_t chans, double offset, + const std::vector& tx_paths, + const std::vector& rx_paths): + tx_sps(tx_sps), rx_sps(rx_sps), iface(type), chans(chans), lo_offset(offset), + tx_paths(tx_paths), rx_paths(rx_paths) + { } + + bool set_antennas() { + unsigned int i; + + for (i = 0; i < tx_paths.size(); i++) { + if (tx_paths[i] == "") + continue; + LOG(DEBUG) << "Configuring channel " << i << " with antenna " << tx_paths[i]; + if (!setTxAntenna(tx_paths[i], i)) { + LOG(ALERT) << "Failed configuring channel " << i << " with antenna " << tx_paths[i]; + return false; + } + } + + for (i = 0; i < rx_paths.size(); i++) { + if (rx_paths[i] == "") + continue; + LOG(DEBUG) << "Configuring channel " << i << " with antenna " << rx_paths[i]; + if (!setRxAntenna(rx_paths[i], i)) { + LOG(ALERT) << "Failed configuring channel " << i << " with antenna " << rx_paths[i]; + return false; + } + } + LOG(INFO) << "Antennas configured successfully"; + return true; + } + + +}; + +#endif diff --git a/Transceiver52M/device/common/smpl_buf.cpp b/Transceiver52M/device/common/smpl_buf.cpp new file mode 100644 index 0000000..c21f306 --- /dev/null +++ b/Transceiver52M/device/common/smpl_buf.cpp @@ -0,0 +1,169 @@ +/* + * Sample Buffer - Allows reading and writing of timed samples + * + * Copyright 2010,2011 Free Software Foundation, Inc. + * Copyright (C) 2015 Ettus Research LLC + * Copyright 2019 sysmocom - s.f.m.c. GmbH + * + * Author: Tom Tsou + * + * 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 . + * See the COPYING file in the main directory for details. + */ + +#include "smpl_buf.h" +#include + +smpl_buf::smpl_buf(size_t len) + : buf_len(len), time_start(0), time_end(0), + data_start(0), data_end(0) +{ + data = new uint32_t[len]; +} + +smpl_buf::~smpl_buf() +{ + delete[] data; +} + +ssize_t smpl_buf::avail_smpls(TIMESTAMP timestamp) const +{ + if (timestamp < time_start) + return ERROR_TIMESTAMP; + else if (timestamp >= time_end) + return 0; + else + return time_end - timestamp; +} + +ssize_t smpl_buf::read(void *buf, size_t len, TIMESTAMP timestamp) +{ + int type_sz = 2 * sizeof(short); + + // Check for valid read + if (timestamp < time_start) + return ERROR_TIMESTAMP; + if (timestamp >= time_end) + return 0; + if (len >= buf_len) + return ERROR_READ; + + // How many samples should be copied + size_t num_smpls = time_end - timestamp; + if (num_smpls > len) + num_smpls = len; + + // Starting index + size_t read_start = (data_start + (timestamp - time_start)) % buf_len; + + // Read it + if (read_start + num_smpls < buf_len) { + size_t numBytes = len * type_sz; + memcpy(buf, data + read_start, numBytes); + } else { + size_t first_cp = (buf_len - read_start) * type_sz; + size_t second_cp = len * type_sz - first_cp; + + memcpy(buf, data + read_start, first_cp); + memcpy((char*) buf + first_cp, data, second_cp); + } + + data_start = (read_start + len) % buf_len; + time_start = timestamp + len; + + if (time_start > time_end) + return ERROR_READ; + else + return num_smpls; +} + +ssize_t smpl_buf::write(void *buf, size_t len, TIMESTAMP timestamp) +{ + int type_sz = 2 * sizeof(short); + + // Check for valid write + if ((len == 0) || (len >= buf_len)) + return ERROR_WRITE; + if ((timestamp + len) <= time_end) + return ERROR_TIMESTAMP; + + if (timestamp < time_end) { + LOGC(DDEV, ERR) << "Overwriting old buffer data: timestamp=" + << timestamp << " time_end=" << time_end; + // Do not return error here, because it's a rounding error and is not fatal + } + if (timestamp > time_end && time_end != 0) { + LOGC(DDEV, ERR) << "Skipping buffer data: timestamp=" + << timestamp << " time_end=" << time_end; + // Do not return error here, because it's a rounding error and is not fatal + } + + // Starting index + size_t write_start = (data_start + (timestamp - time_start)) % buf_len; + + // Write it + if ((write_start + len) < buf_len) { + size_t numBytes = len * type_sz; + memcpy(data + write_start, buf, numBytes); + } else { + size_t first_cp = (buf_len - write_start) * type_sz; + size_t second_cp = len * type_sz - first_cp; + + memcpy(data + write_start, buf, first_cp); + memcpy(data, (char*) buf + first_cp, second_cp); + } + + data_end = (write_start + len) % buf_len; + time_end = timestamp + len; + + if (!data_start) + data_start = write_start; + + if (((write_start + len) > buf_len) && (data_end > data_start)) + return ERROR_OVERFLOW; + else if (time_end <= time_start) + return ERROR_WRITE; + else + return len; +} + +std::string smpl_buf::str_status(TIMESTAMP timestamp) const +{ + std::ostringstream ost("Sample buffer: "); + + ost << "timestamp = " << timestamp; + ost << ", length = " << buf_len; + ost << ", time_start = " << time_start; + ost << ", time_end = " << time_end; + ost << ", data_start = " << data_start; + ost << ", data_end = " << data_end; + + return ost.str(); +} + +std::string smpl_buf::str_code(ssize_t code) +{ + switch (code) { + case ERROR_TIMESTAMP: + return "Sample buffer: Requested timestamp is not valid"; + case ERROR_READ: + return "Sample buffer: Read error"; + case ERROR_WRITE: + return "Sample buffer: Write error"; + case ERROR_OVERFLOW: + return "Sample buffer: Overrun"; + default: + return "Sample buffer: Unknown error"; + } +} diff --git a/Transceiver52M/device/common/smpl_buf.h b/Transceiver52M/device/common/smpl_buf.h new file mode 100644 index 0000000..24d3ce9 --- /dev/null +++ b/Transceiver52M/device/common/smpl_buf.h @@ -0,0 +1,87 @@ +/* + * Sample Buffer - Allows reading and writing of timed samples + * + * Copyright 2010,2011 Free Software Foundation, Inc. + * Copyright (C) 2015 Ettus Research LLC + * Copyright 2019 sysmocom - s.f.m.c. GmbH + * + * Author: Tom Tsou + * + * 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 . + * See the COPYING file in the main directory for details. + */ + +#pragma once + +#include + +#include "radioDevice.h" + +/* + Sample Buffer - Allows reading and writing of timed samples using osmo-trx + timestamps. Time conversions are handled + internally or accessable through the static convert calls. +*/ +class smpl_buf { +public: + /** Sample buffer constructor + @param len number of 32-bit samples the buffer should hold + @param timestamp + */ + smpl_buf(size_t len); + ~smpl_buf(); + + /** Query number of samples available for reading + @param timestamp time of first sample + @return number of available samples or error + */ + ssize_t avail_smpls(TIMESTAMP timestamp) const; + + /** Read and write + @param buf pointer to buffer + @param len number of samples desired to read or write + @param timestamp time of first stample + @return number of actual samples read or written or error + */ + ssize_t read(void *buf, size_t len, TIMESTAMP timestamp); + ssize_t write(void *buf, size_t len, TIMESTAMP timestamp); + + /** Buffer status string + @return a formatted string describing internal buffer state + */ + std::string str_status(TIMESTAMP timestamp) const; + + /** Formatted error string + @param code an error code + @return a formatted error string + */ + static std::string str_code(ssize_t code); + + enum err_code { + ERROR_TIMESTAMP = -1, + ERROR_READ = -2, + ERROR_WRITE = -3, + ERROR_OVERFLOW = -4 + }; + +private: + uint32_t *data; + size_t buf_len; + + TIMESTAMP time_start; + TIMESTAMP time_end; + + size_t data_start; + size_t data_end; +}; diff --git a/Transceiver52M/device/lms/Makefile.am b/Transceiver52M/device/lms/Makefile.am index 8471074..682cf26 100644 --- a/Transceiver52M/device/lms/Makefile.am +++ b/Transceiver52M/device/lms/Makefile.am @@ -1,6 +1,6 @@ include $(top_srcdir)/Makefile.common -AM_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) -I${srcdir}/.. +AM_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) -I${srcdir}/../common AM_CXXFLAGS = -lpthread $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LMS_CFLAGS) noinst_HEADERS = LMSDevice.h diff --git a/Transceiver52M/device/radioDevice.h b/Transceiver52M/device/radioDevice.h deleted file mode 100644 index 30e0f43..0000000 --- a/Transceiver52M/device/radioDevice.h +++ /dev/null @@ -1,208 +0,0 @@ -/* -* Copyright 2008 Free Software Foundation, Inc. -* -* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribuion. -* -* This use of this software may be subject to additional restrictions. -* See the LEGAL file in the main directory for details. - - 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. - -*/ - -#ifndef __RADIO_DEVICE_H__ -#define __RADIO_DEVICE_H__ - -#include -#include - -#include "GSMCommon.h" -#include "Logger.h" - -extern "C" { -#include "config_defs.h" -} - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define GSMRATE (1625e3/6) -#define MCBTS_SPACING 800000.0 - -/** a 64-bit virtual timestamp for radio data */ -typedef unsigned long long TIMESTAMP; - -/** A class to handle a USRP rev 4, with a two RFX900 daughterboards */ -class RadioDevice { - - public: - /* Available transport bus types */ - enum TxWindowType { TX_WINDOW_USRP1, TX_WINDOW_FIXED, TX_WINDOW_LMS1 }; - - /* Radio interface types */ - enum InterfaceType { - NORMAL, - RESAMP_64M, - RESAMP_100M, - MULTI_ARFCN, - }; - - static RadioDevice *make(size_t tx_sps, size_t rx_sps, InterfaceType type, - size_t chans = 1, double offset = 0.0, - const std::vector& tx_paths = std::vector(1, ""), - const std::vector& rx_paths = std::vector(1, "")); - - /** Initialize the USRP */ - virtual int open(const std::string &args, int ref, bool swap_channels)=0; - - virtual ~RadioDevice() { } - - /** Start the USRP */ - virtual bool start()=0; - - /** Stop the USRP */ - virtual bool stop()=0; - - /** Get the Tx window type */ - virtual enum TxWindowType getWindowType()=0; - - /** Enable thread priority */ - virtual void setPriority(float prio = 0.5) = 0; - - /** - Read samples from the radio. - @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 radio 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 - */ - virtual int readSamples(std::vector &bufs, int len, bool *overrun, - TIMESTAMP timestamp = 0xffffffff, bool *underrun = 0, - unsigned *RSSI = 0) = 0; - /** - Write samples to the radio. - @param buf Contains the data to be written. - @param len number of samples to write. - @param underrun Set if radio 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 - */ - virtual int writeSamples(std::vector &bufs, int len, bool *underrun, - TIMESTAMP timestamp, bool isControl = false) = 0; - - /** Update the alignment between the read and write timestamps */ - virtual bool updateAlignment(TIMESTAMP timestamp)=0; - - /** Set the transmitter frequency */ - virtual bool setTxFreq(double wFreq, size_t chan = 0) = 0; - - /** Set the receiver frequency */ - virtual bool setRxFreq(double wFreq, size_t chan = 0) = 0; - - /** Returns the starting write Timestamp*/ - virtual TIMESTAMP initialWriteTimestamp(void)=0; - - /** Returns the starting read Timestamp*/ - virtual TIMESTAMP initialReadTimestamp(void)=0; - - /** returns the full-scale transmit amplitude **/ - virtual double fullScaleInputValue()=0; - - /** returns the full-scale receive amplitude **/ - virtual double fullScaleOutputValue()=0; - - /** sets the receive chan gain, returns the gain setting **/ - virtual double setRxGain(double dB, size_t chan = 0) = 0; - - /** gets the current receive gain **/ - virtual double getRxGain(size_t chan = 0) = 0; - - /** return maximum Rx Gain **/ - virtual double maxRxGain(void) = 0; - - /** return minimum Rx Gain **/ - virtual double minRxGain(void) = 0; - - /** sets the transmit chan gain, returns the gain setting **/ - virtual double setTxGain(double dB, size_t chan = 0) = 0; - - /** return maximum Tx Gain **/ - virtual double maxTxGain(void) = 0; - - /** return minimum Tx Gain **/ - virtual double minTxGain(void) = 0; - - /** sets the RX path to use, returns true if successful and false otherwise */ - virtual bool setRxAntenna(const std::string &ant, size_t chan = 0) = 0; - - /** return the used RX path */ - virtual std::string getRxAntenna(size_t chan = 0) = 0; - - /** sets the RX path to use, returns true if successful and false otherwise */ - virtual bool setTxAntenna(const std::string &ant, size_t chan = 0) = 0; - - /** return the used RX path */ - virtual std::string getTxAntenna(size_t chan = 0) = 0; - - /** return whether user drives synchronization of Tx/Rx of USRP */ - virtual bool requiresRadioAlign() = 0; - - /** Minimum latency that the device can achieve */ - virtual GSM::Time minLatency() = 0; - - /** Return internal status values */ - virtual double getTxFreq(size_t chan = 0) = 0; - virtual double getRxFreq(size_t chan = 0) = 0; - virtual double getSampleRate()=0; - - protected: - size_t tx_sps, rx_sps; - InterfaceType iface; - size_t chans; - double lo_offset; - std::vector tx_paths, rx_paths; - - RadioDevice(size_t tx_sps, size_t rx_sps, InterfaceType type, size_t chans, double offset, - const std::vector& tx_paths, - const std::vector& rx_paths): - tx_sps(tx_sps), rx_sps(rx_sps), iface(type), chans(chans), lo_offset(offset), - tx_paths(tx_paths), rx_paths(rx_paths) - { } - - bool set_antennas() { - unsigned int i; - - for (i = 0; i < tx_paths.size(); i++) { - if (tx_paths[i] == "") - continue; - LOG(DEBUG) << "Configuring channel " << i << " with antenna " << tx_paths[i]; - if (!setTxAntenna(tx_paths[i], i)) { - LOG(ALERT) << "Failed configuring channel " << i << " with antenna " << tx_paths[i]; - return false; - } - } - - for (i = 0; i < rx_paths.size(); i++) { - if (rx_paths[i] == "") - continue; - LOG(DEBUG) << "Configuring channel " << i << " with antenna " << rx_paths[i]; - if (!setRxAntenna(rx_paths[i], i)) { - LOG(ALERT) << "Failed configuring channel " << i << " with antenna " << rx_paths[i]; - return false; - } - } - LOG(INFO) << "Antennas configured successfully"; - return true; - } - - -}; - -#endif diff --git a/Transceiver52M/device/smpl_buf.cpp b/Transceiver52M/device/smpl_buf.cpp deleted file mode 100644 index c21f306..0000000 --- a/Transceiver52M/device/smpl_buf.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Sample Buffer - Allows reading and writing of timed samples - * - * Copyright 2010,2011 Free Software Foundation, Inc. - * Copyright (C) 2015 Ettus Research LLC - * Copyright 2019 sysmocom - s.f.m.c. GmbH - * - * Author: Tom Tsou - * - * 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 . - * See the COPYING file in the main directory for details. - */ - -#include "smpl_buf.h" -#include - -smpl_buf::smpl_buf(size_t len) - : buf_len(len), time_start(0), time_end(0), - data_start(0), data_end(0) -{ - data = new uint32_t[len]; -} - -smpl_buf::~smpl_buf() -{ - delete[] data; -} - -ssize_t smpl_buf::avail_smpls(TIMESTAMP timestamp) const -{ - if (timestamp < time_start) - return ERROR_TIMESTAMP; - else if (timestamp >= time_end) - return 0; - else - return time_end - timestamp; -} - -ssize_t smpl_buf::read(void *buf, size_t len, TIMESTAMP timestamp) -{ - int type_sz = 2 * sizeof(short); - - // Check for valid read - if (timestamp < time_start) - return ERROR_TIMESTAMP; - if (timestamp >= time_end) - return 0; - if (len >= buf_len) - return ERROR_READ; - - // How many samples should be copied - size_t num_smpls = time_end - timestamp; - if (num_smpls > len) - num_smpls = len; - - // Starting index - size_t read_start = (data_start + (timestamp - time_start)) % buf_len; - - // Read it - if (read_start + num_smpls < buf_len) { - size_t numBytes = len * type_sz; - memcpy(buf, data + read_start, numBytes); - } else { - size_t first_cp = (buf_len - read_start) * type_sz; - size_t second_cp = len * type_sz - first_cp; - - memcpy(buf, data + read_start, first_cp); - memcpy((char*) buf + first_cp, data, second_cp); - } - - data_start = (read_start + len) % buf_len; - time_start = timestamp + len; - - if (time_start > time_end) - return ERROR_READ; - else - return num_smpls; -} - -ssize_t smpl_buf::write(void *buf, size_t len, TIMESTAMP timestamp) -{ - int type_sz = 2 * sizeof(short); - - // Check for valid write - if ((len == 0) || (len >= buf_len)) - return ERROR_WRITE; - if ((timestamp + len) <= time_end) - return ERROR_TIMESTAMP; - - if (timestamp < time_end) { - LOGC(DDEV, ERR) << "Overwriting old buffer data: timestamp=" - << timestamp << " time_end=" << time_end; - // Do not return error here, because it's a rounding error and is not fatal - } - if (timestamp > time_end && time_end != 0) { - LOGC(DDEV, ERR) << "Skipping buffer data: timestamp=" - << timestamp << " time_end=" << time_end; - // Do not return error here, because it's a rounding error and is not fatal - } - - // Starting index - size_t write_start = (data_start + (timestamp - time_start)) % buf_len; - - // Write it - if ((write_start + len) < buf_len) { - size_t numBytes = len * type_sz; - memcpy(data + write_start, buf, numBytes); - } else { - size_t first_cp = (buf_len - write_start) * type_sz; - size_t second_cp = len * type_sz - first_cp; - - memcpy(data + write_start, buf, first_cp); - memcpy(data, (char*) buf + first_cp, second_cp); - } - - data_end = (write_start + len) % buf_len; - time_end = timestamp + len; - - if (!data_start) - data_start = write_start; - - if (((write_start + len) > buf_len) && (data_end > data_start)) - return ERROR_OVERFLOW; - else if (time_end <= time_start) - return ERROR_WRITE; - else - return len; -} - -std::string smpl_buf::str_status(TIMESTAMP timestamp) const -{ - std::ostringstream ost("Sample buffer: "); - - ost << "timestamp = " << timestamp; - ost << ", length = " << buf_len; - ost << ", time_start = " << time_start; - ost << ", time_end = " << time_end; - ost << ", data_start = " << data_start; - ost << ", data_end = " << data_end; - - return ost.str(); -} - -std::string smpl_buf::str_code(ssize_t code) -{ - switch (code) { - case ERROR_TIMESTAMP: - return "Sample buffer: Requested timestamp is not valid"; - case ERROR_READ: - return "Sample buffer: Read error"; - case ERROR_WRITE: - return "Sample buffer: Write error"; - case ERROR_OVERFLOW: - return "Sample buffer: Overrun"; - default: - return "Sample buffer: Unknown error"; - } -} diff --git a/Transceiver52M/device/smpl_buf.h b/Transceiver52M/device/smpl_buf.h deleted file mode 100644 index 24d3ce9..0000000 --- a/Transceiver52M/device/smpl_buf.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Sample Buffer - Allows reading and writing of timed samples - * - * Copyright 2010,2011 Free Software Foundation, Inc. - * Copyright (C) 2015 Ettus Research LLC - * Copyright 2019 sysmocom - s.f.m.c. GmbH - * - * Author: Tom Tsou - * - * 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 . - * See the COPYING file in the main directory for details. - */ - -#pragma once - -#include - -#include "radioDevice.h" - -/* - Sample Buffer - Allows reading and writing of timed samples using osmo-trx - timestamps. Time conversions are handled - internally or accessable through the static convert calls. -*/ -class smpl_buf { -public: - /** Sample buffer constructor - @param len number of 32-bit samples the buffer should hold - @param timestamp - */ - smpl_buf(size_t len); - ~smpl_buf(); - - /** Query number of samples available for reading - @param timestamp time of first sample - @return number of available samples or error - */ - ssize_t avail_smpls(TIMESTAMP timestamp) const; - - /** Read and write - @param buf pointer to buffer - @param len number of samples desired to read or write - @param timestamp time of first stample - @return number of actual samples read or written or error - */ - ssize_t read(void *buf, size_t len, TIMESTAMP timestamp); - ssize_t write(void *buf, size_t len, TIMESTAMP timestamp); - - /** Buffer status string - @return a formatted string describing internal buffer state - */ - std::string str_status(TIMESTAMP timestamp) const; - - /** Formatted error string - @param code an error code - @return a formatted error string - */ - static std::string str_code(ssize_t code); - - enum err_code { - ERROR_TIMESTAMP = -1, - ERROR_READ = -2, - ERROR_WRITE = -3, - ERROR_OVERFLOW = -4 - }; - -private: - uint32_t *data; - size_t buf_len; - - TIMESTAMP time_start; - TIMESTAMP time_end; - - size_t data_start; - size_t data_end; -}; diff --git a/Transceiver52M/device/uhd/Makefile.am b/Transceiver52M/device/uhd/Makefile.am index 11b380e..ab63a4a 100644 --- a/Transceiver52M/device/uhd/Makefile.am +++ b/Transceiver52M/device/uhd/Makefile.am @@ -1,10 +1,11 @@ include $(top_srcdir)/Makefile.common -AM_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) -I${srcdir}/.. +AM_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) -I${srcdir}/../common AM_CXXFLAGS = -lpthread $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(UHD_CFLAGS) noinst_HEADERS = UHDDevice.h noinst_LTLIBRARIES = libdevice.la -libdevice_la_SOURCES = UHDDevice.cpp ../smpl_buf.cpp +libdevice_la_SOURCES = UHDDevice.cpp +libdevice_la_LIBADD = $(top_builddir)/Transceiver52M/device/common/libdevice_common.la diff --git a/Transceiver52M/device/usrp1/Makefile.am b/Transceiver52M/device/usrp1/Makefile.am index d99874a..5078934 100644 --- a/Transceiver52M/device/usrp1/Makefile.am +++ b/Transceiver52M/device/usrp1/Makefile.am @@ -1,6 +1,6 @@ include $(top_srcdir)/Makefile.common -AM_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) -I${srcdir}/.. +AM_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) -I${srcdir}/../common AM_CXXFLAGS = -lpthread $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(USRP_CFLAGS) noinst_HEADERS = USRPDevice.h diff --git a/configure.ac b/configure.ac index bd421aa..e2a07f8 100644 --- a/configure.ac +++ b/configure.ac @@ -296,6 +296,7 @@ AC_CONFIG_FILES([\ Transceiver52M/arch/arm/Makefile \ Transceiver52M/arch/x86/Makefile \ Transceiver52M/device/Makefile \ + Transceiver52M/device/common/Makefile \ Transceiver52M/device/uhd/Makefile \ Transceiver52M/device/usrp1/Makefile \ Transceiver52M/device/lms/Makefile \ -- cgit v1.2.3