mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-trx.git
				synced 2025-11-04 06:03:17 +00:00 
			
		
		
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			1.1.0
			...
			fairwaves/
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					e97bddbbd2 | ||
| 
						 | 
					8176f8b811 | 
							
								
								
									
										51
									
								
								CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -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}/cmake_config.in.h
 | 
				
			||||||
 | 
					    ${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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										50
									
								
								CommonLibs/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								CommonLibs/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										23
									
								
								GSM/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								GSM/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -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})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										34
									
								
								INSTALLATION
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								INSTALLATION
									
									
									
									
									
								
							@@ -1,33 +1 @@
 | 
				
			|||||||
Installation Requirements
 | 
					This is special branch for XTRX support. It should be configured with cmake, autoconf isn't supported yet.
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										67
									
								
								Transceiver52M/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								Transceiver52M/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										397
									
								
								Transceiver52M/XTRXDevice.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										397
									
								
								Transceiver52M/XTRXDevice.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										166
									
								
								Transceiver52M/XTRXDevice.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								Transceiver52M/XTRXDevice.h
									
									
									
									
									
										Normal file
									
								
							@@ -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_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -169,15 +169,19 @@ RadioInterface *makeRadioInterface(struct trx_config *config,
 | 
				
			|||||||
		radio = new RadioInterface(usrp, config->tx_sps,
 | 
							radio = new RadioInterface(usrp, config->tx_sps,
 | 
				
			||||||
					   config->rx_sps, config->chans);
 | 
										   config->rx_sps, config->chans);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					#ifndef NO_RESAMPLER
 | 
				
			||||||
	case RadioDevice::RESAMP_64M:
 | 
						case RadioDevice::RESAMP_64M:
 | 
				
			||||||
	case RadioDevice::RESAMP_100M:
 | 
						case RadioDevice::RESAMP_100M:
 | 
				
			||||||
		radio = new RadioInterfaceResamp(usrp, config->tx_sps,
 | 
							radio = new RadioInterfaceResamp(usrp, config->tx_sps,
 | 
				
			||||||
						 config->rx_sps);
 | 
											 config->rx_sps);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef NO_MULTIARFCN
 | 
				
			||||||
	case RadioDevice::MULTI_ARFCN:
 | 
						case RadioDevice::MULTI_ARFCN:
 | 
				
			||||||
		radio = new RadioInterfaceMulti(usrp, config->tx_sps,
 | 
							radio = new RadioInterfaceMulti(usrp, config->tx_sps,
 | 
				
			||||||
						config->rx_sps, config->chans);
 | 
											config->rx_sps, config->chans);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		LOG(ALERT) << "Unsupported radio interface configuration";
 | 
							LOG(ALERT) << "Unsupported radio interface configuration";
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										24
									
								
								Transceiver52M/x86/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Transceiver52M/x86/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -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})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										96
									
								
								cmake/FindFFTW.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								cmake/FindFFTW.cmake
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
				
			||||||
							
								
								
									
										69
									
								
								cmake/FindXTRX.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								cmake/FindXTRX.cmake
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
				
			||||||
							
								
								
									
										0
									
								
								cmake_config.in.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								cmake_config.in.h
									
									
									
									
									
										Normal file
									
								
							
		Reference in New Issue
	
	Block a user