forked from sdr/gr-osmosdr
Compare commits
196 Commits
Author | SHA1 | Date |
---|---|---|
Robert Ghilduta | 821fdb3822 | |
Robert Ghilduta | 038a26501c | |
Robert Ghilduta | 95b1025b01 | |
Robert Ghilduta | bfdc4d917c | |
Robert Ghilduta | 34daf86ec3 | |
Ryan Tucker | a343cc208b | |
Robert Ghilduta | f6a8992856 | |
Eric Wild | 6a22db7568 | |
Eric Wild | 6b11b02947 | |
Eric Wild | a309841752 | |
Eric Wild | 09e72004fe | |
Eric Wild | e13c2e4e1c | |
Vadim Yanitskiy | 9c58e8a991 | |
Ron Economos | a100eb024c | |
Ron Economos | ba755e113e | |
Eric Wild | 7e955ad284 | |
Eric Wild | 64781cc652 | |
Clayton Smith | c7012949e1 | |
Clayton Smith | 1f724162e1 | |
Matt Mills | f88dc7df2f | |
Matt Mills | 0d727b3ef8 | |
Clayton Smith | 159885f9e6 | |
Gwenhael Goavec-Merou | cffef690f2 | |
Clayton Smith | c3187ab875 | |
Clayton Smith | bc629b03fe | |
Adrian Chadd | 9b386707d8 | |
Csaba Sipos | dc82ffd1f8 | |
Clayton Smith | fe03d83703 | |
Clayton Smith | 2d504bde50 | |
Clayton Smith | e5bee0820f | |
Eric Wild | 90c3d5b555 | |
Mike Walters | bd668e97b6 | |
Eric Wild | 911082ff85 | |
Eric Wild | dadabeceaf | |
Mike Walters | 5cf6f4df96 | |
Wim Lewis | ad72126289 | |
Wim Lewis | 2e7d343fed | |
Clayton Smith | 800d2eaeaf | |
Clayton Smith | 52fcb0935f | |
Anton Blanchard | 49f9b2df2a | |
Clayton Smith | 137c568c60 | |
Piotr Krysik | 8cf6840da1 | |
Sylvain Munaut | af2fda22b3 | |
Sylvain Munaut | 77ac70ebc3 | |
Sylvain Munaut | 1b827b9913 | |
Stefan `Sec` Zehl | e63b8a7f6f | |
Sylvain Munaut | 465d2f433c | |
Sylvain Munaut | f609a44177 | |
Clayton Smith | 4d1c05e84b | |
Clayton Smith | ae2253c516 | |
Clayton Smith | 96dc33adf1 | |
Alexandru Csete | 743cac795e | |
Sylvain Munaut | 5d59e56ff9 | |
Sylvain Munaut | e9890283ca | |
Sylvain Munaut | 982945a477 | |
Sylvain Munaut | 8c2f912037 | |
Sylvain Munaut | b9e1ebd9e7 | |
Sylvain Munaut | a95bbd7418 | |
Robert Ghilduta | 4d83c6067f | |
Rey Tucker | c06db96489 | |
Rey Tucker | 2e2ff98c83 | |
Rey Tucker | b4e69137f3 | |
Rey Tucker | bee32d9f0d | |
Rey Tucker | 8f8b137cee | |
Rey Tucker | c4a0781367 | |
Ryan Tucker | c8e69edb7b | |
Ryan Tucker | 68ba383fd5 | |
Ryan Tucker | ea6cc4beb9 | |
Ryan Tucker | 0132f6c494 | |
Ryan Tucker | 814fe0809c | |
Ryan Tucker | 077697cb2d | |
Ryan Tucker | 399db91385 | |
Ryan Tucker | ed4dda192b | |
Ryan Tucker | cee878536a | |
Ryan Tucker | 07babe997d | |
Ryan Tucker | 3523097e00 | |
Ryan Tucker | 855ac41c12 | |
Rey Tucker | 4ffccd1363 | |
Rey Tucker | a6209e3250 | |
Ryan Tucker | 107b35bee3 | |
Ryan Tucker | 708096f6e4 | |
Ryan Tucker | 4395c3e6c7 | |
Rey Tucker | 56da34f7f2 | |
Josh Blum | 0b5c3911f7 | |
Dimitri Stolnikov | ea1fc34766 | |
Maxime Vincent | c98be5dd9d | |
Dimitri Stolnikov | ea6b356cfd | |
Dimitri Stolnikov | c653754dde | |
Dimitri Stolnikov | b7aab458ed | |
Lukas Lao Beyer | 1693e4e9d8 | |
Dimitri Stolnikov | 3c7d3f1664 | |
Dimitri Stolnikov | a3b4e5c815 | |
Krzysztof Halasa | 26f93e4687 | |
Krzysztof Halasa | 33a8d1c2ae | |
Josh Blum | cf9549485a | |
Josh Blum | 117f648859 | |
Josh Blum | b361fa5a77 | |
Josh Blum | a9e536f45b | |
Lukas Lao Beyer | 5ecfa255d2 | |
Dimitri Stolnikov | e9dde9afd7 | |
Sylvain Munaut | 71846180f5 | |
Dimitri Stolnikov | 43df1c98c4 | |
Dimitri Stolnikov | 20a5fd1a68 | |
Dimitri Stolnikov | 6a0cac6609 | |
Alexandru Csete | c6ed80aea7 | |
Alexandru Csete | 3823c8efce | |
Alexandru Csete | 6ea6c19028 | |
Alexandru Csete | 0dc8154f08 | |
Josh Blum | 2a2236cc9e | |
Josh Blum | 3511defbf4 | |
Josh Blum | ae686c462d | |
Josh Blum | 860e9a1a72 | |
Josh Blum | e3b6560b04 | |
Dimitri Stolnikov | 164a09fc11 | |
Dimitri Stolnikov | b206a90f49 | |
Dimitri Stolnikov | e6f46a1c04 | |
Dimitri Stolnikov | 2b79811350 | |
Jiří Pinkava | d230397957 | |
Jiří Pinkava | ac15e7897b | |
Dimitri Stolnikov | e321095445 | |
Dimitri Stolnikov | da2cf6a6f2 | |
Dimitri Stolnikov | 64cfd98c5b | |
Dimitri Stolnikov | 11257d0aa6 | |
Dimitri Stolnikov | 3fda9d6be5 | |
Marcus Müller | 20a5986ca0 | |
Marcus Müller | 84249efbea | |
Pavel Demin | f8cba954f0 | |
Pavel Demin | 810a981d0c | |
Dimitri Stolnikov | 55fe961987 | |
Pavel Demin | 3582ba17e0 | |
Alexandru Csete | 7cec4c0f51 | |
Dimitri Stolnikov | 2ca720cfee | |
Dimitri Stolnikov | 69ec75a0b4 | |
Dimitri Stolnikov | 3198eb927a | |
Josh Blum | c804460f5d | |
Josh Blum | 9ceadfb645 | |
Josh Blum | b3d915f591 | |
Jon Szymaniak | 86ad584204 | |
Jon Szymaniak | 43a00ae785 | |
Utomnia | ac1d8ec02d | |
Dimitri Stolnikov | 46e95395e0 | |
Dimitri Stolnikov | f33f30815a | |
Heikki Hannikainen | 2bcd86e55e | |
Heikki Hannikainen | dd6690b6ca | |
Heikki Hannikainen | 254e1b1981 | |
Heikki Hannikainen | e847176f3e | |
Heikki Hannikainen | dd6536757a | |
Heikki Hannikainen | 485b02e615 | |
Heikki Hannikainen | 592a814bdb | |
Heikki Hannikainen | 8e6ecd0644 | |
Heikki Hannikainen | 69181b0e85 | |
Heikki Hannikainen | 5dca656745 | |
Heikki Hannikainen | d4387f436d | |
Heikki Hannikainen | 9595b044b6 | |
Marcus Müller | b3fdf5b83d | |
Dimitri Stolnikov | 5943919828 | |
Dimitri Stolnikov | 44c223cb5d | |
Dimitri Stolnikov | 4582df6111 | |
Dimitri Stolnikov | 275e6aed19 | |
Dimitri Stolnikov | b226b85fa8 | |
Dimitri Stolnikov | 8d25584da3 | |
Dimitri Stolnikov | 3916b5bc4f | |
Dimitri Stolnikov | 3793a5e8b1 | |
Dimitri Stolnikov | 17c9497d4d | |
SDRplay | be9af0fe6f | |
SDRplay | 79b53f50e4 | |
SDRplay | afed5df615 | |
Josh Blum | 3532d60c11 | |
Josh Blum | c092f9e2a3 | |
Josh Blum | 61184a19e7 | |
Josh Blum | 53ed8918f3 | |
Josh Blum | a960600a1e | |
Josh Blum | cd0d9350c6 | |
Josh Blum | 535a505069 | |
Josh Blum | 6d6a483cfb | |
Josh Blum | 3afcb7e04f | |
Dimitri Stolnikov | 48045b597d | |
Dimitri Stolnikov | 46bb1ad1a0 | |
Dimitri Stolnikov | 20fd6a8c34 | |
Dimitri Stolnikov | 163cad2e96 | |
Dimitri Stolnikov | 13114b7830 | |
Dimitri Stolnikov | aa4094b3fd | |
Dimitri Stolnikov | da27f3fb0a | |
Jon Szymaniak | 8d9e6b58bb | |
Dimitri Stolnikov | 9fd5b367c1 | |
Dimitri Stolnikov | a45968f338 | |
Jon Szymaniak | 6e75abf198 | |
Jon Szymaniak | 7f82d289a6 | |
Jon Szymaniak | 23b1b9cdb1 | |
Dimitri Stolnikov | 42c66fdd70 | |
Dimitri Stolnikov | 39230788d7 | |
Dimitri Stolnikov | 7a8224bcb8 | |
Dimitri Stolnikov | 4bb2fa4e2f | |
Dimitri Stolnikov | 7a013ca84a | |
Dimitri Stolnikov | 8604d76df3 | |
Dimitri Stolnikov | a3ee4db0e7 |
|
@ -0,0 +1,4 @@
|
|||
/.vscode/*
|
||||
/build/*
|
||||
*.pyc
|
||||
*.pyo
|
5
AUTHORS
5
AUTHORS
|
@ -2,3 +2,8 @@ Dimitri Stolnikov <horiz0n@gmx.net>
|
|||
Steve Markgraf <steve@steve-m.de>
|
||||
Hoernchen <la@tfc-server.de>
|
||||
Nuand LLC folks
|
||||
Josh Blum
|
||||
SDRplay Ltd.
|
||||
Pavel Demin
|
||||
Marcus Müller
|
||||
Lukas Lao Beyer
|
||||
|
|
386
CMakeLists.txt
386
CMakeLists.txt
|
@ -1,30 +1,32 @@
|
|||
# Copyright 2012 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file is part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# gr-osmosdr 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio is distributed in the hope that it will be useful,
|
||||
# gr-osmosdr 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# along with gr-osmosdr; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
########################################################################
|
||||
# Project setup
|
||||
########################################################################
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
project(gr-osmosdr CXX C)
|
||||
include(GNUInstallDirs)
|
||||
enable_testing()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
|
||||
#policy setup
|
||||
cmake_policy(SET CMP0011 NEW)
|
||||
|
||||
#select the release build type by default to get optimization flags
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
|
@ -33,157 +35,205 @@ if(NOT CMAKE_BUILD_TYPE)
|
|||
endif(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
|
||||
|
||||
########################################################################
|
||||
# GNURadio setup
|
||||
########################################################################
|
||||
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules)
|
||||
|
||||
# Find GNURadio (pmt and runtime are core, always included)
|
||||
include(FindPkgConfig)
|
||||
find_package(Gnuradio "3.9" REQUIRED COMPONENTS blocks fft filter)
|
||||
|
||||
# Set the version information here
|
||||
set(VERSION_INFO_MAJOR_VERSION 0)
|
||||
set(VERSION_INFO_API_COMPAT 1)
|
||||
set(VERSION_INFO_MINOR_VERSION 2)
|
||||
set(VERSION_INFO_MAINT_VERSION 0)
|
||||
set(VERSION_MAJOR 0)
|
||||
set(VERSION_API 2)
|
||||
set(VERSION_ABI 0)
|
||||
set(VERSION_PATCH 0)
|
||||
include(GrVersion) #setup version info
|
||||
|
||||
########################################################################
|
||||
# Compiler specific setup
|
||||
########################################################################
|
||||
|
||||
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|x86")
|
||||
SET(USE_SIMD "SSE2" CACHE STRING "Use SIMD instructions")
|
||||
ELSE()
|
||||
SET(USE_SIMD "no" CACHE STRING "Use SIMD instructions")
|
||||
ENDIF()
|
||||
SET(USE_SIMD_VALUES "no" "SSE2" "AVX")
|
||||
SET_PROPERTY(CACHE USE_SIMD PROPERTY STRINGS ${USE_SIMD_VALUES})
|
||||
LIST(FIND USE_SIMD_VALUES ${USE_SIMD} USE_SIMD_INDEX)
|
||||
IF(${USE_SIMD_INDEX} EQUAL -1)
|
||||
message(FATAL_ERROR "Option ${USE_SIMD} not supported, valid entries are ${USE_SIMD_VALUES}")
|
||||
ENDIF()
|
||||
|
||||
IF(CMAKE_CXX_COMPILER MATCHES ".*clang")
|
||||
SET(CMAKE_COMPILER_IS_CLANGXX 1)
|
||||
ENDIF()
|
||||
|
||||
IF(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX)
|
||||
ADD_DEFINITIONS(-Wall)
|
||||
ADD_DEFINITIONS(-Wextra)
|
||||
ADD_DEFINITIONS(-Wno-unused-parameter)
|
||||
ADD_DEFINITIONS(-Wsign-compare)
|
||||
#ADD_DEFINITIONS(-Wconversion)
|
||||
#ADD_DEFINITIONS(-pedantic)
|
||||
#ADD_DEFINITIONS(-ansi)
|
||||
IF(NOT WIN32)
|
||||
#only export symbols that are declared to be part of the api (non dll platforms)
|
||||
ADD_DEFINITIONS(-fvisibility=hidden)
|
||||
ADD_DEFINITIONS(-fvisibility-inlines-hidden)
|
||||
ENDIF(NOT WIN32)
|
||||
IF(USE_SIMD MATCHES SSE2)
|
||||
ADD_DEFINITIONS(-msse2)
|
||||
ADD_DEFINITIONS(-DUSE_SSE2)
|
||||
ENDIF()
|
||||
IF(USE_SIMD MATCHES AVX)
|
||||
ADD_DEFINITIONS(-march=native)
|
||||
ADD_DEFINITIONS(-DUSE_AVX)
|
||||
ENDIF()
|
||||
ELSEIF(MSVC)
|
||||
IF(USE_SIMD MATCHES SSE2)
|
||||
ADD_DEFINITIONS(/arch:SSE2)
|
||||
ADD_DEFINITIONS(-DUSE_SSE2)
|
||||
ENDIF()
|
||||
IF(USE_SIMD MATCHES AVX)
|
||||
ADD_DEFINITIONS(/arch:AVX)
|
||||
ADD_DEFINITIONS(-DUSE_AVX)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
########################################################################
|
||||
# Setup boost
|
||||
########################################################################
|
||||
MESSAGE(STATUS "Configuring Boost C++ Libraries...")
|
||||
|
||||
# Although not required on my system, some users have linking issues without
|
||||
SET(BOOST_REQUIRED_COMPONENTS
|
||||
thread
|
||||
system
|
||||
)
|
||||
|
||||
if(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64")
|
||||
list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix
|
||||
endif(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64")
|
||||
|
||||
set(Boost_ADDITIONAL_VERSIONS
|
||||
"1.35.0" "1.35" "1.36.0" "1.36" "1.37.0" "1.37" "1.38.0" "1.38" "1.39.0" "1.39"
|
||||
"1.40.0" "1.40" "1.41.0" "1.41" "1.42.0" "1.42" "1.43.0" "1.43" "1.44.0" "1.44"
|
||||
"1.45.0" "1.45" "1.46.0" "1.46" "1.47.0" "1.47" "1.48.0" "1.48" "1.49.0" "1.49"
|
||||
"1.50.0" "1.50" "1.51.0" "1.51" "1.52.0" "1.52" "1.53.0" "1.53" "1.54.0" "1.54"
|
||||
"1.55.0" "1.55" "1.56.0" "1.56" "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59"
|
||||
"1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64"
|
||||
"1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69"
|
||||
)
|
||||
|
||||
find_package(Boost COMPONENTS ${BOOST_REQUIRED_COMPONENTS})
|
||||
|
||||
if(NOT Boost_FOUND)
|
||||
message(FATAL_ERROR "Boost required to build " ${CMAKE_PROJECT_NAME})
|
||||
if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
|
||||
CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
AND NOT WIN32)
|
||||
#http://gcc.gnu.org/wiki/Visibility
|
||||
add_definitions(-fvisibility=hidden)
|
||||
add_definitions(-fvisibility-inlines-hidden)
|
||||
endif()
|
||||
|
||||
ADD_DEFINITIONS(-DBOOST_ALL_DYN_LINK)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
# Misc options
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
|
||||
CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
add_definitions(-Wall)
|
||||
add_definitions(-Wextra)
|
||||
add_definitions(-Wno-unused-parameter)
|
||||
add_definitions(-Wsign-compare)
|
||||
#add_definitions(-Wconversion)
|
||||
#add_definitions(-pedantic)
|
||||
#add_definitions(-ansi)
|
||||
endif()
|
||||
|
||||
# SIMD
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|x86")
|
||||
set(USE_SIMD "SSE2" CACHE STRING "Use SIMD instructions")
|
||||
else()
|
||||
set(USE_SIMD "no" CACHE STRING "Use SIMD instructions")
|
||||
endif()
|
||||
set(USE_SIMD_VALUES "no" "SSE2" "AVX")
|
||||
set_property(CACHE USE_SIMD PROPERTY STRINGS ${USE_SIMD_VALUES})
|
||||
list(FIND USE_SIMD_VALUES ${USE_SIMD} USE_SIMD_INDEX)
|
||||
if(${USE_SIMD_INDEX} EQUAL -1)
|
||||
message(FATAL_ERROR "Option ${USE_SIMD} not supported, valid entries are ${USE_SIMD_VALUES}")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
|
||||
CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
if(USE_SIMD MATCHES SSE2)
|
||||
add_definitions(-msse2)
|
||||
add_definitions(-DUSE_SSE2)
|
||||
endif()
|
||||
if(USE_SIMD MATCHES AVX)
|
||||
add_definitions(-march=native)
|
||||
add_definitions(-DUSE_AVX)
|
||||
endif()
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
if(USE_SIMD MATCHES SSE2)
|
||||
add_definitions(/arch:SSE2)
|
||||
add_definitions(-DUSE_SSE2)
|
||||
endif()
|
||||
if(USE_SIMD MATCHES AVX)
|
||||
add_definitions(/arch:AVX)
|
||||
add_definitions(-DUSE_AVX)
|
||||
endif()
|
||||
# boost feels like using lib pragmas to link to libs,
|
||||
# but the boost libs might not even be in the (default) lib search path
|
||||
add_definitions(-DBOOST_ALL_NO_LIB)
|
||||
# macro turns std::min into errors...
|
||||
add_definitions(-DNOMINMAX)
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
# Find boost
|
||||
########################################################################
|
||||
find_package(Boost "1.65" REQUIRED chrono thread system)
|
||||
|
||||
if(NOT Boost_FOUND)
|
||||
message(FATAL_ERROR "Boost required to compile osmosdr")
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
# Find build dependencies and setup options
|
||||
########################################################################
|
||||
|
||||
include(GrComponent)
|
||||
|
||||
set(ENABLE_NONFREE FALSE CACHE BOOL "Enable or disable nonfree components.")
|
||||
|
||||
|
||||
# GNURadio components & OOTs
|
||||
##############################
|
||||
|
||||
|
||||
# Note this is not supposed to be lique that for GR components
|
||||
# but ATM GR's handling of components is broken
|
||||
message(STATUS "Searching for GNURadio-Blocks...")
|
||||
find_package(gnuradio-blocks PATHS ${Gnuradio_DIR})
|
||||
message(STATUS " Found GNURadio-Blocks: ${gnuradio-blocks_FOUND}")
|
||||
|
||||
message(STATUS "Searching for IQ Balance...")
|
||||
find_package(gnuradio-iqbalance PATHS ${Gnuradio_DIR})
|
||||
message (STATUS " Found IQ Balance: ${gnuradio-iqbalance_FOUND}")
|
||||
|
||||
message(STATUS "Searching for UHD Drivers...")
|
||||
find_package(UHD)
|
||||
message (STATUS " Found UHD Driver: ${UHD_FOUND}")
|
||||
|
||||
message(STATUS "Searching for UHD Block...")
|
||||
find_package(gnuradio-uhd PATHS ${Gnuradio_DIR})
|
||||
message (STATUS " Found UHD Block: ${gnuradio-uhd_FOUND}")
|
||||
|
||||
message(STATUS "Searching for Volk...")
|
||||
find_package(Volk REQUIRED)
|
||||
message (STATUS " Found Volk: ${Volk_FOUND}")
|
||||
|
||||
# Hardware drivers
|
||||
####################
|
||||
|
||||
find_package(LibRTLSDR)
|
||||
if(ENABLE_NONFREE)
|
||||
find_package(LibSDRplay)
|
||||
endif(ENABLE_NONFREE)
|
||||
find_package(LibHackRF)
|
||||
find_package(LibAIRSPY)
|
||||
find_package(LibAIRSPYHF)
|
||||
find_package(LibbladeRF)
|
||||
find_package(GnuradioFuncube)
|
||||
find_package(SoapySDR NO_MODULE)
|
||||
find_package(LibFreeSRP)
|
||||
find_package(LibXTRX)
|
||||
find_package(Doxygen)
|
||||
|
||||
# Python
|
||||
##########
|
||||
|
||||
find_package(PythonLibs 3)
|
||||
find_package(pybind11)
|
||||
|
||||
GR_REGISTER_COMPONENT("Python support" ENABLE_PYTHON
|
||||
PYTHONLIBS_FOUND
|
||||
pybind11_FOUND
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Install directories
|
||||
########################################################################
|
||||
include(GrPlatform) #define LIB_SUFFIX
|
||||
set(GR_RUNTIME_DIR bin)
|
||||
set(GR_LIBRARY_DIR lib${LIB_SUFFIX})
|
||||
|
||||
if(NOT CMAKE_MODULES_DIR)
|
||||
set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake)
|
||||
endif(NOT CMAKE_MODULES_DIR)
|
||||
|
||||
set(GR_INCLUDE_DIR include)
|
||||
set(GR_DATA_DIR share)
|
||||
set(GR_CMAKE_DIR ${CMAKE_MODULES_DIR}/osmosdr)
|
||||
set(GR_PKG_DATA_DIR ${GR_DATA_DIR}/${CMAKE_PROJECT_NAME})
|
||||
set(GR_DOC_DIR ${GR_DATA_DIR}/doc)
|
||||
if (NOT GR_PKG_DOC_DIR)
|
||||
set(GR_PKG_DOC_DIR ${GR_DOC_DIR}/${CMAKE_PROJECT_NAME})
|
||||
endif()
|
||||
set(GR_CONF_DIR etc)
|
||||
set(GR_PKG_DOC_DIR ${GR_DOC_DIR}/${CMAKE_PROJECT_NAME})
|
||||
set(GR_PKG_CONF_DIR ${GR_CONF_DIR}/${CMAKE_PROJECT_NAME}/conf.d)
|
||||
set(GR_LIBEXEC_DIR libexec)
|
||||
set(GR_PKG_LIBEXEC_DIR ${GR_LIBEXEC_DIR}/${CMAKE_PROJECT_NAME})
|
||||
set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks)
|
||||
|
||||
########################################################################
|
||||
# Find build dependencies
|
||||
# On Apple only, set install name and use rpath correctly, if not already set
|
||||
########################################################################
|
||||
if(APPLE)
|
||||
if(NOT CMAKE_INSTALL_NAME_DIR)
|
||||
set(CMAKE_INSTALL_NAME_DIR
|
||||
${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE
|
||||
PATH "Library Install Name Destination Directory" FORCE)
|
||||
endif(NOT CMAKE_INSTALL_NAME_DIR)
|
||||
if(NOT CMAKE_INSTALL_RPATH)
|
||||
set(CMAKE_INSTALL_RPATH
|
||||
${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE
|
||||
PATH "Library Install RPath" FORCE)
|
||||
endif(NOT CMAKE_INSTALL_RPATH)
|
||||
if(NOT CMAKE_BUILD_WITH_INSTALL_RPATH)
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE
|
||||
BOOL "Do Build Using Library Install RPath" FORCE)
|
||||
endif(NOT CMAKE_BUILD_WITH_INSTALL_RPATH)
|
||||
endif(APPLE)
|
||||
|
||||
########################################################################
|
||||
# Setup doxygen option
|
||||
########################################################################
|
||||
set(GR_REQUIRED_COMPONENTS RUNTIME PMT BLOCKS)
|
||||
find_package(Gnuradio 3.7.3 REQUIRED)
|
||||
find_package(GnuradioIQBalance)
|
||||
find_package(UHD)
|
||||
find_package(GnuradioUHD)
|
||||
find_package(GnuradioFCD)
|
||||
find_package(GnuradioFCDPP)
|
||||
find_package(LibOsmoSDR)
|
||||
find_package(LibRTLSDR)
|
||||
find_package(LibMiriSDR)
|
||||
find_package(LibHackRF)
|
||||
find_package(LibAIRSPY)
|
||||
find_package(LibbladeRF)
|
||||
find_package(Doxygen)
|
||||
|
||||
if(NOT GNURADIO_RUNTIME_FOUND)
|
||||
message(FATAL_ERROR "GnuRadio Runtime required to build " ${CMAKE_PROJECT_NAME})
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
# Setup the include and linker paths
|
||||
########################################################################
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
${CMAKE_SOURCE_DIR}/lib
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${GNURADIO_ALL_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
link_directories(
|
||||
${Boost_LIBRARY_DIRS}
|
||||
${GNURADIO_ALL_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
# Set component parameters
|
||||
set(GR_OSMOSDR_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE INTERNAL "" FORCE)
|
||||
set(GR_OSMOSDR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/swig CACHE INTERNAL "" FORCE)
|
||||
if(DOXYGEN_FOUND)
|
||||
option(ENABLE_DOXYGEN "Build docs using Doxygen" ON)
|
||||
else(DOXYGEN_FOUND)
|
||||
option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF)
|
||||
endif(DOXYGEN_FOUND)
|
||||
|
||||
########################################################################
|
||||
# Create uninstall target
|
||||
|
@ -195,28 +245,7 @@ configure_file(
|
|||
|
||||
add_custom_target(uninstall
|
||||
${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Enable python component
|
||||
########################################################################
|
||||
find_package(PythonLibs 2)
|
||||
find_package(SWIG)
|
||||
|
||||
if(SWIG_FOUND)
|
||||
message(STATUS "Minimum SWIG version required is 1.3.31")
|
||||
set(SWIG_VERSION_CHECK FALSE)
|
||||
if("${SWIG_VERSION}" VERSION_GREATER "1.3.30")
|
||||
set(SWIG_VERSION_CHECK TRUE)
|
||||
endif()
|
||||
endif(SWIG_FOUND)
|
||||
|
||||
include(GrComponent)
|
||||
GR_REGISTER_COMPONENT("Python support" ENABLE_PYTHON
|
||||
PYTHONLIBS_FOUND
|
||||
SWIG_FOUND
|
||||
SWIG_VERSION_CHECK
|
||||
)
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Add subdirectories
|
||||
|
@ -224,53 +253,22 @@ GR_REGISTER_COMPONENT("Python support" ENABLE_PYTHON
|
|||
add_subdirectory(include/osmosdr)
|
||||
add_subdirectory(lib)
|
||||
if(ENABLE_PYTHON)
|
||||
add_subdirectory(swig)
|
||||
add_subdirectory(python)
|
||||
add_subdirectory(grc)
|
||||
add_subdirectory(apps)
|
||||
endif(ENABLE_PYTHON)
|
||||
add_subdirectory(docs)
|
||||
|
||||
########################################################################
|
||||
# Create Pkg Config File
|
||||
########################################################################
|
||||
FOREACH(inc ${Boost_INCLUDE_DIRS})
|
||||
LIST(APPEND GR_OSMOSDR_PC_CFLAGS "-I${inc}")
|
||||
ENDFOREACH(inc)
|
||||
|
||||
FOREACH(lib ${Boost_LIBRARY_DIRS})
|
||||
LIST(APPEND GR_OSMOSDR_PC_LIBS "-L${lib}")
|
||||
ENDFOREACH(lib)
|
||||
|
||||
# use space-separation format for the pc file
|
||||
STRING(REPLACE ";" " " GR_OSMOSDR_PC_REQUIRES "${GR_OSMOSDR_PC_REQUIRES}")
|
||||
STRING(REPLACE ";" " " GR_OSMOSDR_PC_CFLAGS "${GR_OSMOSDR_PC_CFLAGS}")
|
||||
STRING(REPLACE ";" " " GR_OSMOSDR_PC_LIBS "${GR_OSMOSDR_PC_LIBS}")
|
||||
|
||||
# unset these vars to avoid hard-coded paths to cross environment
|
||||
IF(CMAKE_CROSSCOMPILING)
|
||||
UNSET(GR_OSMOSDR_PC_CFLAGS)
|
||||
UNSET(GR_OSMOSDR_PC_LIBS)
|
||||
ENDIF(CMAKE_CROSSCOMPILING)
|
||||
|
||||
# fake gnuradio cpack behavior as long as we don't use it directly
|
||||
set(CPACK_PACKAGE_NAME "gnuradio-osmosdr")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "GNU Radio block for various radio hardware")
|
||||
set(CPACK_PACKAGE_VERSION ${VERSION})
|
||||
|
||||
CONFIGURE_FILE(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-osmosdr.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/gnuradio-osmosdr.pc
|
||||
@ONLY)
|
||||
|
||||
INSTALL(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-osmosdr.pc
|
||||
DESTINATION ${GR_LIBRARY_DIR}/pkgconfig
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Print Summary
|
||||
########################################################################
|
||||
GR_PRINT_COMPONENT_SUMMARY()
|
||||
if(ENABLE_NONFREE)
|
||||
MESSAGE(STATUS
|
||||
"NONFREE components have been enabled. The resulting
|
||||
binaries cannot be distributed under GPL terms.
|
||||
")
|
||||
endif(ENABLE_NONFREE)
|
||||
|
||||
MESSAGE(STATUS "Building for version: ${VERSION} / ${LIBVER}")
|
||||
MESSAGE(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}")
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
title: gr-osmosdr
|
||||
brief: GNU Radio block for interfacing with various radio hardware
|
||||
tags:
|
||||
- rtlsdr
|
||||
- bladerf
|
||||
- airspy
|
||||
- rfspace
|
||||
- hackrf
|
||||
- soapy
|
||||
- sdrplay
|
||||
- uhd
|
||||
- osmocom
|
||||
author:
|
||||
- Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
copyright_owner:
|
||||
- Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
license: GPLv3
|
||||
repo: git://git.osmocom.org/gr-osmosdr
|
||||
website: http://sdr.osmocom.org/trac/wiki/GrOsmoSDR
|
||||
---
|
||||
GNU Radio block for interfacing with various radio hardware
|
||||
|
||||
![FFT](http://sdr.osmocom.org/trac/raw-attachment/wiki/GrOsmoSDR/fft-lte.png "osmocom_fft")
|
||||
![SIG](http://sdr.osmocom.org/trac/raw-attachment/wiki/GrOsmoSDR/siggen-gsm.png "osmocom_siggen")
|
||||
![GS2](http://sdr.osmocom.org/trac/raw-attachment/wiki/GrOsmoSDR/gsm-hackrf-8M.png "osmocom_siggen with hackrf")
|
||||
|
||||
Support for gr-fosphor in `osmocom_fft` is available through the -F option.
|
||||
|
||||
![LTE](http://sdr.osmocom.org/trac/raw-attachment/wiki/GrOsmoSDR/fosphor.png "LTE")
|
||||
![GSM](http://sdr.osmocom.org/trac/raw-attachment/wiki/GrOsmoSDR/fosphor2.png "GSM")
|
||||
|
||||
Please refer to the documentation on http://sdr.osmocom.org/trac/wiki/GrOsmoSDR
|
||||
for installation instructions.
|
12
README
12
README
|
@ -1,19 +1,21 @@
|
|||
While primarily being developed for the OsmoSDR hardware, this block
|
||||
as well supports:
|
||||
|
||||
* FUNcube Dongle through libgnuradio-fcd
|
||||
* FUNcube Dongle Pro+ through gr-fcdproplus
|
||||
* sysmocom OsmoSDR Devices through libosmosdr
|
||||
* FUNcube Dongle / Pro+ through gr-funcube
|
||||
* RTL2832U based DVB-T dongles through librtlsdr
|
||||
* RTL-TCP spectrum server (see librtlsdr project)
|
||||
* MSi2500 based DVB-T dongles through libmirisdr
|
||||
* SDRplay RSP through SDRplay API library
|
||||
* gnuradio .cfile input through libgnuradio-blocks
|
||||
* RFSPACE SDR-IQ, SDR-IP, NetSDR (incl. X2 option)
|
||||
* AirSpy Wideband Receiver through libairspy
|
||||
* CCCamp 2015 rad1o Badge through libhackrf
|
||||
* Great Scott Gadgets HackRF through libhackrf
|
||||
* Nuand LLC bladeRF through libbladeRF library
|
||||
* Ettus USRP Devices through Ettus UHD library
|
||||
* Fairwaves UmTRX through Fairwaves' fork of UHD
|
||||
* Fairwaves UmTRX through Fairwaves' module for UHD
|
||||
* Fairwaves XTRX through libxtrx
|
||||
* Red Pitaya SDR transceiver (http://bazaar.redpitaya.com)
|
||||
* FreeSRP through libfreesrp
|
||||
|
||||
By using the OsmoSDR block you can take advantage of a common software api in
|
||||
your application(s) independent of the underlying radio hardware.
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
# Copyright 2011 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file is part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# gr-osmosdr 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio is distributed in the hope that it will be useful,
|
||||
# gr-osmosdr 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# along with gr-osmosdr; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
|
@ -28,8 +28,8 @@ GR_PYTHON_INSTALL(
|
|||
GR_PYTHON_INSTALL(
|
||||
PROGRAMS
|
||||
osmocom_fft
|
||||
osmocom_siggen
|
||||
# osmocom_siggen
|
||||
osmocom_siggen_nogui
|
||||
osmocom_spectrum_sense
|
||||
# osmocom_spectrum_sense
|
||||
DESTINATION ${GR_RUNTIME_DIR}
|
||||
)
|
||||
|
|
946
apps/osmocom_fft
946
apps/osmocom_fft
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2009,2011,2012 Free Software Foundation, Inc.
|
||||
#
|
||||
|
@ -164,16 +164,19 @@ class app_gui(pubsub):
|
|||
)
|
||||
freq_hbox.AddSpacer(5)
|
||||
|
||||
forms.slider(
|
||||
parent=self.panel, sizer=freq_hbox,
|
||||
proportion=2,
|
||||
ps=self.tb,
|
||||
key=osmocom_siggen.TX_FREQ_KEY,
|
||||
minimum=self.tb[osmocom_siggen.FREQ_RANGE_KEY].start(),
|
||||
maximum=self.tb[osmocom_siggen.FREQ_RANGE_KEY].stop(),
|
||||
num_steps=101,
|
||||
)
|
||||
freq_hbox.AddSpacer(3)
|
||||
try:
|
||||
forms.slider(
|
||||
parent=self.panel, sizer=freq_hbox,
|
||||
proportion=2,
|
||||
ps=self.tb,
|
||||
key=osmocom_siggen.TX_FREQ_KEY,
|
||||
minimum=self.tb[osmocom_siggen.FREQ_RANGE_KEY].start(),
|
||||
maximum=self.tb[osmocom_siggen.FREQ_RANGE_KEY].stop(),
|
||||
num_steps=101,
|
||||
)
|
||||
freq_hbox.AddSpacer(3)
|
||||
except:
|
||||
pass
|
||||
|
||||
corr_hbox.AddSpacer(3)
|
||||
forms.text_box(
|
||||
|
@ -480,7 +483,7 @@ def main():
|
|||
app.MainLoop()
|
||||
|
||||
except RuntimeError, e:
|
||||
print e
|
||||
print(e)
|
||||
sys.exit(1)
|
||||
|
||||
# Make sure to create the top block (tb) within a function: That code
|
||||
|
|
|
@ -46,7 +46,7 @@ from gnuradio import blocks
|
|||
from gnuradio import filter
|
||||
from gnuradio import analog
|
||||
from gnuradio import digital
|
||||
from gnuradio import gr, gru, eng_notation
|
||||
from gnuradio import gr, eng_notation
|
||||
from gnuradio.gr.pubsub import pubsub
|
||||
from gnuradio.eng_option import eng_option
|
||||
from optparse import OptionParser
|
||||
|
@ -109,9 +109,9 @@ class gsm_source_c(gr.hier_block2):
|
|||
[0,0,0],
|
||||
]
|
||||
burst = sum(chunks,[])
|
||||
burst = sum(map(list, zip(burst, (1,) * len(burst))), [])
|
||||
burst = sum(list(map(list, list(zip(burst, (1,) * len(burst))))), [])
|
||||
burst += [1,0] * (l-148)
|
||||
return map(int, burst)
|
||||
return list(map(int, burst))
|
||||
|
||||
def gen_gsm_frame(self):
|
||||
return \
|
||||
|
@ -186,9 +186,13 @@ class top_block(gr.top_block, pubsub):
|
|||
try:
|
||||
self._sink.get_sample_rates().start()
|
||||
except RuntimeError:
|
||||
print "Sink has no sample rates (wrong device arguments?)."
|
||||
print("Sink has no sample rates (wrong device arguments?).")
|
||||
sys.exit(1)
|
||||
|
||||
# Set the clock source:
|
||||
if options.clock_source is not None:
|
||||
self.src.set_clock_source(options.clock_source)
|
||||
|
||||
if options.samp_rate is None:
|
||||
options.samp_rate = self._sink.get_sample_rates().start()
|
||||
|
||||
|
@ -198,42 +202,60 @@ class top_block(gr.top_block, pubsub):
|
|||
if(options.gain):
|
||||
gain = self._sink.set_gain(options.gain)
|
||||
if self._verbose:
|
||||
print "Set gain to:", gain
|
||||
print("Set gain to:", gain)
|
||||
|
||||
if self._verbose:
|
||||
gain_names = self.src.get_gain_names()
|
||||
gain_names = self._sink.get_gain_names()
|
||||
for name in gain_names:
|
||||
range = self.src.get_gain_range(name)
|
||||
print "%s gain range: start %d stop %d step %d" % (name, range.start(), range.stop(), range.step())
|
||||
range = self._sink.get_gain_range(name)
|
||||
print("%s gain range: start %d stop %d step %d" % (name, range.start(), range.stop(), range.step()))
|
||||
|
||||
if options.gains:
|
||||
for tuple in options.gains.split(","):
|
||||
name, gain = tuple.split(":")
|
||||
gain = int(gain)
|
||||
print "Setting gain %s to %d." % (name, gain)
|
||||
self.src.set_gain(gain, name)
|
||||
print("Setting gain %s to %d." % (name, gain))
|
||||
self._sink.set_gain(gain, name)
|
||||
|
||||
if self._verbose:
|
||||
rates = self.src.get_sample_rates()
|
||||
print 'Supported sample rates %d-%d step %d.' % (rates.start(), rates.stop(), rates.step())
|
||||
rates = self._sink.get_sample_rates()
|
||||
print('Supported sample rates %d-%d step %d.' % (rates.start(), rates.stop(), rates.step()))
|
||||
|
||||
# Set the antenna
|
||||
if self._verbose:
|
||||
print("setting antenna...")
|
||||
if(options.antenna):
|
||||
ant = self._sink.set_antenna(options.antenna, 0)
|
||||
if self._verbose:
|
||||
print "Set antenna to:", ant
|
||||
print("Set antenna to:", ant)
|
||||
try:
|
||||
self.publish(FREQ_RANGE_KEY, self._sink.get_freq_range)
|
||||
except:
|
||||
print("Couldn't publish %s" % FREQ_RANGE_KEY)
|
||||
|
||||
self.publish(FREQ_RANGE_KEY, self._sink.get_freq_range)
|
||||
try:
|
||||
for name in self.get_gain_names():
|
||||
self.publish(GAIN_RANGE_KEY(name), (lambda self=self,name=name: self._sink.get_gain_range(name)))
|
||||
except:
|
||||
print("Couldn't publish %s" % FREQ_RANGE_KEY)
|
||||
|
||||
for name in self.get_gain_names():
|
||||
self.publish(GAIN_RANGE_KEY(name), (lambda self=self,name=name: self._sink.get_gain_range(name)))
|
||||
try:
|
||||
self.publish(BWIDTH_RANGE_KEY, self._sink.get_bandwidth_range)
|
||||
except:
|
||||
if self._verbose:
|
||||
print("Couldn't publish %s" % BWIDTH_RANGE_KEY)
|
||||
|
||||
self.publish(BWIDTH_RANGE_KEY, self._sink.get_bandwidth_range)
|
||||
|
||||
for name in self.get_gain_names():
|
||||
self.publish(GAIN_KEY(name), (lambda self=self,name=name: self._sink.get_gain(name)))
|
||||
|
||||
self.publish(BWIDTH_KEY, self._sink.get_bandwidth)
|
||||
try:
|
||||
for name in self.get_gain_names():
|
||||
self.publish(GAIN_KEY(name), (lambda self=self,name=name: self._sink.get_gain(name)))
|
||||
except:
|
||||
if self._verbose:
|
||||
print("Couldn't publish GAIN_KEYs")
|
||||
try:
|
||||
self.publish(BWIDTH_KEY, self._sink.get_bandwidth)
|
||||
except:
|
||||
if self._verbose:
|
||||
print("Couldn't publish %s" % BWIDTH_KEY)
|
||||
|
||||
def get_gain_names(self):
|
||||
return self._sink.get_gain_names()
|
||||
|
@ -255,7 +277,7 @@ class top_block(gr.top_block, pubsub):
|
|||
return True # Waveform not yet set
|
||||
|
||||
if self._verbose:
|
||||
print "Set sample rate to:", sr
|
||||
print("Set sample rate to:", sr)
|
||||
|
||||
return True
|
||||
|
||||
|
@ -264,21 +286,27 @@ class top_block(gr.top_block, pubsub):
|
|||
g = self[GAIN_RANGE_KEY(name)]
|
||||
gain = float(g.start()+g.stop())/2
|
||||
if self._verbose:
|
||||
print "Using auto-calculated mid-point gain"
|
||||
print("Using auto-calculated mid-point gain")
|
||||
self[GAIN_KEY(name)] = gain
|
||||
return
|
||||
|
||||
gain = self._sink.set_gain(gain, name)
|
||||
if self._verbose:
|
||||
print "Set " + name + " gain to:", gain
|
||||
print("Set " + name + " gain to:", gain)
|
||||
|
||||
def set_bandwidth(self, bw):
|
||||
clipped_bw = self[BWIDTH_RANGE_KEY].clip(bw)
|
||||
try:
|
||||
clipped_bw = self[BWIDTH_RANGE_KEY].clip(bw)
|
||||
except:
|
||||
if self._verbose:
|
||||
print("couldn't clip bandwidth")
|
||||
return
|
||||
|
||||
if self._sink.get_bandwidth() != clipped_bw:
|
||||
bw = self._sink.set_bandwidth(clipped_bw)
|
||||
|
||||
if self._verbose:
|
||||
print "Set bandwidth to:", bw
|
||||
print("Set bandwidth to:", bw)
|
||||
|
||||
def set_dc_offset(self, value):
|
||||
correction = complex( self[DC_OFFSET_REAL], self[DC_OFFSET_IMAG] )
|
||||
|
@ -287,9 +315,9 @@ class top_block(gr.top_block, pubsub):
|
|||
self._sink.set_dc_offset( correction )
|
||||
|
||||
if self._verbose:
|
||||
print "Set DC offset to", correction
|
||||
print("Set DC offset to", correction)
|
||||
except RuntimeError as ex:
|
||||
print ex
|
||||
print(ex)
|
||||
|
||||
def set_iq_balance(self, value):
|
||||
correction = complex( self[IQ_BALANCE_MAG], self[IQ_BALANCE_PHA] )
|
||||
|
@ -298,16 +326,16 @@ class top_block(gr.top_block, pubsub):
|
|||
self._sink.set_iq_balance( correction )
|
||||
|
||||
if self._verbose:
|
||||
print "Set IQ balance to", correction
|
||||
print("Set IQ balance to", correction)
|
||||
except RuntimeError as ex:
|
||||
print ex
|
||||
print(ex)
|
||||
|
||||
def set_freq(self, freq):
|
||||
if freq is None:
|
||||
f = self[FREQ_RANGE_KEY]
|
||||
freq = float(f.start()+f.stop())/2.0
|
||||
if self._verbose:
|
||||
print "Using auto-calculated mid-point frequency"
|
||||
print("Using auto-calculated mid-point frequency")
|
||||
self[TX_FREQ_KEY] = freq
|
||||
return
|
||||
|
||||
|
@ -315,22 +343,22 @@ class top_block(gr.top_block, pubsub):
|
|||
if freq is not None:
|
||||
self._freq = freq
|
||||
if self._verbose:
|
||||
print "Set center frequency to", freq
|
||||
print("Set center frequency to", freq)
|
||||
elif self._verbose:
|
||||
print "Failed to set freq."
|
||||
print("Failed to set freq.")
|
||||
return freq
|
||||
|
||||
def set_freq_corr(self, ppm):
|
||||
if ppm is None:
|
||||
ppm = 0.0
|
||||
if self._verbose:
|
||||
print "Using frequency corrrection of", ppm
|
||||
print("Using frequency corrrection of", ppm)
|
||||
self[FREQ_CORR_KEY] = ppm
|
||||
return
|
||||
|
||||
ppm = self._sink.set_freq_corr(ppm)
|
||||
if self._verbose:
|
||||
print "Set frequency correction to:", ppm
|
||||
print("Set frequency correction to:", ppm)
|
||||
|
||||
def set_waveform_freq(self, freq):
|
||||
if self[TYPE_KEY] == analog.GR_SIN_WAVE:
|
||||
|
@ -405,24 +433,24 @@ class top_block(gr.top_block, pubsub):
|
|||
self.unlock()
|
||||
|
||||
if self._verbose:
|
||||
print "Set baseband modulation to:", waveforms[type]
|
||||
print("Set baseband modulation to:", waveforms[type])
|
||||
if type == analog.GR_SIN_WAVE:
|
||||
print "Modulation frequency: %sHz" % (n2s(self[WAVEFORM_FREQ_KEY]),)
|
||||
print "Initial phase:", self[WAVEFORM_OFFSET_KEY]
|
||||
print("Modulation frequency: %sHz" % (n2s(self[WAVEFORM_FREQ_KEY]),))
|
||||
print("Initial phase:", self[WAVEFORM_OFFSET_KEY])
|
||||
elif type == "2tone":
|
||||
print "Tone 1: %sHz" % (n2s(self[WAVEFORM_FREQ_KEY]),)
|
||||
print "Tone 2: %sHz" % (n2s(self[WAVEFORM2_FREQ_KEY]),)
|
||||
print("Tone 1: %sHz" % (n2s(self[WAVEFORM_FREQ_KEY]),))
|
||||
print("Tone 2: %sHz" % (n2s(self[WAVEFORM2_FREQ_KEY]),))
|
||||
elif type == "sweep":
|
||||
print "Sweeping across %sHz to %sHz" % (n2s(-self[WAVEFORM_FREQ_KEY]/2.0),n2s(self[WAVEFORM_FREQ_KEY]/2.0))
|
||||
print "Sweep rate: %sHz" % (n2s(self[WAVEFORM2_FREQ_KEY]),)
|
||||
print("Sweeping across %sHz to %sHz" % (n2s(-self[WAVEFORM_FREQ_KEY]/2.0),n2s(self[WAVEFORM_FREQ_KEY]/2.0)))
|
||||
print("Sweep rate: %sHz" % (n2s(self[WAVEFORM2_FREQ_KEY]),))
|
||||
elif type == "gsm":
|
||||
print "GSM Burst Sequence"
|
||||
print "TX amplitude:", self[AMPLITUDE_KEY]
|
||||
print("GSM Burst Sequence")
|
||||
print("TX amplitude:", self[AMPLITUDE_KEY])
|
||||
|
||||
def set_amplitude(self, amplitude):
|
||||
if amplitude < 0.0 or amplitude > 1.0:
|
||||
if self._verbose:
|
||||
print "Amplitude out of range:", amplitude
|
||||
print("Amplitude out of range:", amplitude)
|
||||
return False
|
||||
|
||||
if self[TYPE_KEY] in (analog.GR_SIN_WAVE, analog.GR_CONST_WAVE, analog.GR_GAUSSIAN, analog.GR_UNIFORM):
|
||||
|
@ -438,7 +466,7 @@ class top_block(gr.top_block, pubsub):
|
|||
return True # Waveform not yet set
|
||||
|
||||
if self._verbose:
|
||||
print "Set amplitude to:", amplitude
|
||||
print("Set amplitude to:", amplitude)
|
||||
return True
|
||||
|
||||
def get_options():
|
||||
|
@ -449,6 +477,8 @@ def get_options():
|
|||
help="Device args, [default=%default]")
|
||||
parser.add_option("-A", "--antenna", type="string", default=None,
|
||||
help="Select Rx Antenna where appropriate")
|
||||
parser.add_option("", "--clock-source",
|
||||
help="Set the clock source; typically 'internal', 'external', 'external_1pps', 'mimo' or 'gpsdo'")
|
||||
parser.add_option("-s", "--samp-rate", type="eng_float", default=None,
|
||||
help="Set sample rate (bandwidth), minimum by default")
|
||||
parser.add_option("-g", "--gain", type="eng_float", default=None,
|
||||
|
@ -495,19 +525,19 @@ def get_options():
|
|||
# the below does not run.
|
||||
def test_main():
|
||||
if gr.enable_realtime_scheduling() != gr.RT_OK:
|
||||
print "Note: failed to enable realtime scheduling, continuing"
|
||||
print("Note: failed to enable realtime scheduling, continuing")
|
||||
|
||||
# Grab command line options and create top block
|
||||
try:
|
||||
(options, args) = get_options()
|
||||
tb = top_block(options, args)
|
||||
|
||||
except RuntimeError, e:
|
||||
print e
|
||||
except RuntimeError as e:
|
||||
print(e)
|
||||
sys.exit(1)
|
||||
|
||||
tb.start()
|
||||
raw_input('Press Enter to quit: ')
|
||||
input('Press Enter to quit: ')
|
||||
tb.stop()
|
||||
tb.wait()
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2008,2009,2011,2012 Free Software Foundation, Inc.
|
||||
#
|
||||
|
@ -26,19 +26,19 @@ import sys
|
|||
|
||||
def main():
|
||||
if gr.enable_realtime_scheduling() != gr.RT_OK:
|
||||
print "Note: failed to enable realtime scheduling, continuing"
|
||||
print("Note: failed to enable realtime scheduling, continuing")
|
||||
|
||||
# Grab command line options and create top block
|
||||
try:
|
||||
(options, args) = osmocom_siggen.get_options()
|
||||
tb = osmocom_siggen.top_block(options, args)
|
||||
|
||||
except RuntimeError, e:
|
||||
print e
|
||||
except RuntimeError as e:
|
||||
print(e)
|
||||
sys.exit(1)
|
||||
|
||||
tb.start()
|
||||
raw_input('Press Enter to quit: ')
|
||||
input('Press Enter to quit: ')
|
||||
tb.stop()
|
||||
tb.wait()
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005,2007,2011 Free Software Foundation, Inc.
|
||||
#
|
||||
|
@ -71,13 +71,13 @@ class tune(gr.feval_dd):
|
|||
|
||||
# wait until msgq is empty before continuing
|
||||
while(self.tb.msgq.full_p()):
|
||||
#print "msgq full, holding.."
|
||||
#print("msgq full, holding..")
|
||||
time.sleep(0.1)
|
||||
|
||||
return new_freq
|
||||
|
||||
except Exception, e:
|
||||
print "tune: Exception: ", e
|
||||
except Exception as e:
|
||||
print("tune: Exception: ", e)
|
||||
|
||||
|
||||
class parse_msg(object):
|
||||
|
@ -147,7 +147,7 @@ class my_top_block(gr.top_block):
|
|||
realtime = True
|
||||
else:
|
||||
realtime = False
|
||||
print "Note: failed to enable realtime scheduling"
|
||||
print("Note: failed to enable realtime scheduling")
|
||||
|
||||
# build graph
|
||||
self.u = osmosdr.source(options.args)
|
||||
|
@ -155,7 +155,7 @@ class my_top_block(gr.top_block):
|
|||
try:
|
||||
self.u.get_sample_rates().start()
|
||||
except RuntimeError:
|
||||
print "Source has no sample rates (wrong device arguments?)."
|
||||
print("Source has no sample rates (wrong device arguments?).")
|
||||
sys.exit(1)
|
||||
|
||||
# Set the antenna
|
||||
|
@ -218,7 +218,7 @@ class my_top_block(gr.top_block):
|
|||
options.gain = float(g.start()+g.stop())/2.0
|
||||
|
||||
self.set_gain(options.gain)
|
||||
print "gain =", options.gain
|
||||
print("gain =", options.gain)
|
||||
|
||||
def set_next_freq(self):
|
||||
target_freq = self.next_freq
|
||||
|
@ -227,7 +227,7 @@ class my_top_block(gr.top_block):
|
|||
self.next_freq = self.min_center_freq
|
||||
|
||||
if not self.set_freq(target_freq):
|
||||
print "Failed to set frequency to", target_freq
|
||||
print("Failed to set frequency to", target_freq)
|
||||
sys.exit(1)
|
||||
|
||||
return target_freq
|
||||
|
@ -259,9 +259,9 @@ def main_loop(tb):
|
|||
def bin_freq(i_bin, center_freq):
|
||||
#hz_per_bin = tb.usrp_rate / tb.fft_size
|
||||
freq = center_freq - (tb.usrp_rate / 2) + (tb.channel_bandwidth * i_bin)
|
||||
#print "freq original:",freq
|
||||
#print("freq original:",freq)
|
||||
#freq = nearest_freq(freq, tb.channel_bandwidth)
|
||||
#print "freq rounded:",freq
|
||||
#print("freq rounded:",freq)
|
||||
return freq
|
||||
|
||||
bin_start = int(tb.fft_size * ((1 - 0.75) / 2))
|
||||
|
@ -287,7 +287,7 @@ def main_loop(tb):
|
|||
power_db = 10*math.log10(m.data[i_bin]/tb.usrp_rate) - noise_floor_db
|
||||
|
||||
if (power_db > tb.squelch_threshold) and (freq >= tb.min_freq) and (freq <= tb.max_freq):
|
||||
print datetime.now(), "center_freq", center_freq, "freq", freq, "power_db", power_db, "noise_floor_db", noise_floor_db
|
||||
print(datetime.now(), "center_freq", center_freq, "freq", freq, "power_db", power_db, "noise_floor_db", noise_floor_db)
|
||||
|
||||
if __name__ == '__main__':
|
||||
t = ThreadClass()
|
||||
|
|
|
@ -1,138 +0,0 @@
|
|||
# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...)
|
||||
#
|
||||
# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for
|
||||
# parsing the arguments given to that macro or function.
|
||||
# It processes the arguments and defines a set of variables which hold the
|
||||
# values of the respective options.
|
||||
#
|
||||
# The <options> argument contains all options for the respective macro,
|
||||
# i.e. keywords which can be used when calling the macro without any value
|
||||
# following, like e.g. the OPTIONAL keyword of the install() command.
|
||||
#
|
||||
# The <one_value_keywords> argument contains all keywords for this macro
|
||||
# which are followed by one value, like e.g. DESTINATION keyword of the
|
||||
# install() command.
|
||||
#
|
||||
# The <multi_value_keywords> argument contains all keywords for this macro
|
||||
# which can be followed by more than one value, like e.g. the TARGETS or
|
||||
# FILES keywords of the install() command.
|
||||
#
|
||||
# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the
|
||||
# keywords listed in <options>, <one_value_keywords> and
|
||||
# <multi_value_keywords> a variable composed of the given <prefix>
|
||||
# followed by "_" and the name of the respective keyword.
|
||||
# These variables will then hold the respective value from the argument list.
|
||||
# For the <options> keywords this will be TRUE or FALSE.
|
||||
#
|
||||
# All remaining arguments are collected in a variable
|
||||
# <prefix>_UNPARSED_ARGUMENTS, this can be checked afterwards to see whether
|
||||
# your macro was called with unrecognized parameters.
|
||||
#
|
||||
# As an example here a my_install() macro, which takes similar arguments as the
|
||||
# real install() command:
|
||||
#
|
||||
# function(MY_INSTALL)
|
||||
# set(options OPTIONAL FAST)
|
||||
# set(oneValueArgs DESTINATION RENAME)
|
||||
# set(multiValueArgs TARGETS CONFIGURATIONS)
|
||||
# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
|
||||
# ...
|
||||
#
|
||||
# Assume my_install() has been called like this:
|
||||
# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
|
||||
#
|
||||
# After the cmake_parse_arguments() call the macro will have set the following
|
||||
# variables:
|
||||
# MY_INSTALL_OPTIONAL = TRUE
|
||||
# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install()
|
||||
# MY_INSTALL_DESTINATION = "bin"
|
||||
# MY_INSTALL_RENAME = "" (was not used)
|
||||
# MY_INSTALL_TARGETS = "foo;bar"
|
||||
# MY_INSTALL_CONFIGURATIONS = "" (was not used)
|
||||
# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL"
|
||||
#
|
||||
# You can the continue and process these variables.
|
||||
#
|
||||
# Keywords terminate lists of values, e.g. if directly after a one_value_keyword
|
||||
# another recognized keyword follows, this is interpreted as the beginning of
|
||||
# the new option.
|
||||
# E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in
|
||||
# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would
|
||||
# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2010 Alexander Neundorf <neundorf@kde.org>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
|
||||
if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
|
||||
return()
|
||||
endif()
|
||||
set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
|
||||
|
||||
|
||||
function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
|
||||
# first set all result variables to empty/FALSE
|
||||
foreach(arg_name ${_singleArgNames} ${_multiArgNames})
|
||||
set(${prefix}_${arg_name})
|
||||
endforeach(arg_name)
|
||||
|
||||
foreach(option ${_optionNames})
|
||||
set(${prefix}_${option} FALSE)
|
||||
endforeach(option)
|
||||
|
||||
set(${prefix}_UNPARSED_ARGUMENTS)
|
||||
|
||||
set(insideValues FALSE)
|
||||
set(currentArgName)
|
||||
|
||||
# now iterate over all arguments and fill the result variables
|
||||
foreach(currentArg ${ARGN})
|
||||
list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
|
||||
list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
|
||||
list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
|
||||
|
||||
if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
|
||||
if(insideValues)
|
||||
if("${insideValues}" STREQUAL "SINGLE")
|
||||
set(${prefix}_${currentArgName} ${currentArg})
|
||||
set(insideValues FALSE)
|
||||
elseif("${insideValues}" STREQUAL "MULTI")
|
||||
list(APPEND ${prefix}_${currentArgName} ${currentArg})
|
||||
endif()
|
||||
else(insideValues)
|
||||
list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
|
||||
endif(insideValues)
|
||||
else()
|
||||
if(NOT ${optionIndex} EQUAL -1)
|
||||
set(${prefix}_${currentArg} TRUE)
|
||||
set(insideValues FALSE)
|
||||
elseif(NOT ${singleArgIndex} EQUAL -1)
|
||||
set(currentArgName ${currentArg})
|
||||
set(${prefix}_${currentArgName})
|
||||
set(insideValues "SINGLE")
|
||||
elseif(NOT ${multiArgIndex} EQUAL -1)
|
||||
set(currentArgName ${currentArg})
|
||||
set(${prefix}_${currentArgName})
|
||||
set(insideValues "MULTI")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endforeach(currentArg)
|
||||
|
||||
# propagate the result variables to the caller:
|
||||
foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
|
||||
set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
|
||||
endforeach(arg_name)
|
||||
set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
|
||||
|
||||
endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs)
|
|
@ -1,34 +0,0 @@
|
|||
INCLUDE(FindPkgConfig)
|
||||
PKG_CHECK_MODULES(PC_GNURADIO_FCD gnuradio-fcd)
|
||||
|
||||
FIND_PATH(
|
||||
GNURADIO_FCD_INCLUDE_DIRS
|
||||
NAMES gnuradio/fcd/api.h
|
||||
HINTS $ENV{GNURADIO_FCD_DIR}/include
|
||||
${PC_GNURADIO_FCD_INCLUDEDIR}
|
||||
PATHS /usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(
|
||||
GNURADIO_FCD_LIBRARIES
|
||||
NAMES gnuradio-fcd
|
||||
HINTS $ENV{GNURADIO_FCD_DIR}/lib
|
||||
${PC_GNURADIO_FCD_LIBDIR}
|
||||
PATHS /usr/local/lib
|
||||
/usr/local/lib64
|
||||
/usr/lib
|
||||
/usr/lib64
|
||||
)
|
||||
|
||||
if(GNURADIO_FCD_INCLUDE_DIRS AND GNURADIO_FCD_LIBRARIES)
|
||||
set(GNURADIO_FCD_FOUND TRUE CACHE INTERNAL "gnuradio-fcd found")
|
||||
message(STATUS "Found gnuradio-fcd: ${GNURADIO_FCD_INCLUDE_DIRS}, ${GNURADIO_FCD_LIBRARIES}")
|
||||
else(GNURADIO_FCD_INCLUDE_DIRS AND GNURADIO_FCD_LIBRARIES)
|
||||
set(GNURADIO_FCD_FOUND FALSE CACHE INTERNAL "gnuradio-fcd found")
|
||||
message(STATUS "gnuradio-fcd not found.")
|
||||
endif(GNURADIO_FCD_INCLUDE_DIRS AND GNURADIO_FCD_LIBRARIES)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_FCD DEFAULT_MSG GNURADIO_FCD_LIBRARIES GNURADIO_FCD_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(GNURADIO_FCD_LIBRARIES GNURADIO_FCD_INCLUDE_DIRS)
|
|
@ -1,34 +0,0 @@
|
|||
INCLUDE(FindPkgConfig)
|
||||
PKG_CHECK_MODULES(PC_GNURADIO_FCDPP gnuradio-fcdproplus)
|
||||
|
||||
FIND_PATH(
|
||||
GNURADIO_FCDPP_INCLUDE_DIRS
|
||||
NAMES fcdproplus/api.h
|
||||
HINTS $ENV{GNURADIO_FCDPP_DIR}/include
|
||||
${PC_GNURADIO_FCDPP_INCLUDEDIR}
|
||||
PATHS /usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(
|
||||
GNURADIO_FCDPP_LIBRARIES
|
||||
NAMES gnuradio-fcdproplus
|
||||
HINTS $ENV{GNURADIO_FCDPP_DIR}/lib
|
||||
${PC_GNURADIO_FCDPP_LIBDIR}
|
||||
PATHS /usr/local/lib
|
||||
/usr/local/lib64
|
||||
/usr/lib
|
||||
/usr/lib64
|
||||
)
|
||||
|
||||
if(GNURADIO_FCDPP_INCLUDE_DIRS AND GNURADIO_FCDPP_LIBRARIES)
|
||||
set(GNURADIO_FCDPP_FOUND TRUE CACHE INTERNAL "gnuradio-fcdproplus found")
|
||||
message(STATUS "Found gnuradio-fcdproplus: ${GNURADIO_FCDPP_INCLUDE_DIRS}, ${GNURADIO_FCDPP_LIBRARIES}")
|
||||
else(GNURADIO_FCDPP_INCLUDE_DIRS AND GNURADIO_FCDPP_LIBRARIES)
|
||||
set(GNURADIO_FCDPP_FOUND FALSE CACHE INTERNAL "gnuradio-fcdproplus found")
|
||||
message(STATUS "gnuradio-fcdproplus not found.")
|
||||
endif(GNURADIO_FCDPP_INCLUDE_DIRS AND GNURADIO_FCDPP_LIBRARIES)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_FCDPP DEFAULT_MSG GNURADIO_FCDPP_LIBRARIES GNURADIO_FCDPP_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(GNURADIO_FCDPP_LIBRARIES GNURADIO_FCDPP_INCLUDE_DIRS)
|
|
@ -0,0 +1,27 @@
|
|||
if(NOT GNURADIO_FUNCUBE_FOUND)
|
||||
pkg_check_modules (GNURADIO_FUNCUBE_PKG libgnuradio-funcube)
|
||||
find_path(GNURADIO_FUNCUBE_INCLUDE_DIRS NAMES funcube/api.h
|
||||
PATHS
|
||||
${GNURADIO_FUNCUBE_PKG_INCLUDE_DIRS}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
find_library(GNURADIO_FUNCUBE_LIBRARIES NAMES gnuradio-funcube
|
||||
PATHS
|
||||
${GNURADIO_FUNCUBE_PKG_LIBRARY_DIRS}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
)
|
||||
|
||||
if(GNURADIO_FUNCUBE_INCLUDE_DIRS AND GNURADIO_FUNCUBE_LIBRARIES)
|
||||
set(GNURADIO_FUNCUBE_FOUND TRUE CACHE INTERNAL "gnuradio-funcube found")
|
||||
message(STATUS "Found gnuradio-funcube: ${GNURADIO_FUNCUBE_INCLUDE_DIRS}, ${GNURADIO_FUNCUBE_LIBRARIES}")
|
||||
else(GNURADIO_FUNCUBE_INCLUDE_DIRS AND GNURADIO_FUNCUBE_LIBRARIES)
|
||||
set(GNURADIO_FUNCUBE_FOUND FALSE CACHE INTERNAL "gnuradio-funcube found")
|
||||
message(STATUS "gnuradio-funcube not found.")
|
||||
endif(GNURADIO_FUNCUBE_INCLUDE_DIRS AND GNURADIO_FUNCUBE_LIBRARIES)
|
||||
|
||||
mark_as_advanced(GNURADIO_FUNCUBE_LIBRARIES GNURADIO_FUNCUBE_INCLUDE_DIRS)
|
||||
|
||||
endif(NOT GNURADIO_FUNCUBE_FOUND)
|
|
@ -1,29 +0,0 @@
|
|||
INCLUDE(FindPkgConfig)
|
||||
PKG_CHECK_MODULES(PC_GNURADIO_IQBALANCE gnuradio-iqbalance)
|
||||
|
||||
FIND_PATH(
|
||||
GNURADIO_IQBALANCE_INCLUDE_DIRS
|
||||
NAMES gnuradio/iqbalance/api.h
|
||||
HINTS $ENV{GNURADIO_IQBALANCE_DIR}/include
|
||||
${PC_GNURADIO_IQBALANCE_INCLUDEDIR}
|
||||
${CMAKE_INSTALL_PREFIX}/include
|
||||
PATHS /usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(
|
||||
GNURADIO_IQBALANCE_LIBRARIES
|
||||
NAMES gnuradio-iqbalance
|
||||
HINTS $ENV{GNURADIO_IQBALANCE_DIR}/lib
|
||||
${PC_GNURADIO_IQBALANCE_LIBDIR}
|
||||
${CMAKE_INSTALL_PREFIX}/lib64
|
||||
${CMAKE_INSTALL_PREFIX}/lib
|
||||
PATHS /usr/local/lib
|
||||
/usr/local/lib64
|
||||
/usr/lib
|
||||
/usr/lib64
|
||||
)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_IQBALANCE DEFAULT_MSG GNURADIO_IQBALANCE_LIBRARIES GNURADIO_IQBALANCE_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(GNURADIO_IQBALANCE_LIBRARIES GNURADIO_IQBALANCE_INCLUDE_DIRS)
|
|
@ -1,34 +0,0 @@
|
|||
INCLUDE(FindPkgConfig)
|
||||
PKG_CHECK_MODULES(PC_GNURADIO_UHD gnuradio-uhd)
|
||||
|
||||
FIND_PATH(
|
||||
GNURADIO_UHD_INCLUDE_DIRS
|
||||
NAMES gnuradio/uhd/api.h
|
||||
HINTS $ENV{GNURADIO_UHD_DIR}/include
|
||||
${PC_GNURADIO_UHD_INCLUDEDIR}
|
||||
PATHS /usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(
|
||||
GNURADIO_UHD_LIBRARIES
|
||||
NAMES gnuradio-uhd
|
||||
HINTS $ENV{GNURADIO_UHD_DIR}/lib
|
||||
${PC_GNURADIO_UHD_LIBDIR}
|
||||
PATHS /usr/local/lib
|
||||
/usr/local/lib64
|
||||
/usr/lib
|
||||
/usr/lib64
|
||||
)
|
||||
|
||||
if(GNURADIO_UHD_INCLUDE_DIRS AND GNURADIO_UHD_LIBRARIES)
|
||||
set(GNURADIO_UHD_FOUND TRUE CACHE INTERNAL "gnuradio-uhd found")
|
||||
message(STATUS "Found gnuradio-uhd: ${GNURADIO_UHD_INCLUDE_DIRS}, ${GNURADIO_UHD_LIBRARIES}")
|
||||
else(GNURADIO_UHD_INCLUDE_DIRS AND GNURADIO_UHD_LIBRARIES)
|
||||
set(GNURADIO_UHD_FOUND FALSE CACHE INTERNAL "gnuradio-uhd found")
|
||||
message(STATUS "gnuradio-uhd not found.")
|
||||
endif(GNURADIO_UHD_INCLUDE_DIRS AND GNURADIO_UHD_LIBRARIES)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_UHD DEFAULT_MSG GNURADIO_UHD_LIBRARIES GNURADIO_UHD_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(GNURADIO_UHD_LIBRARIES GNURADIO_UHD_INCLUDE_DIRS)
|
|
@ -1,4 +1,6 @@
|
|||
INCLUDE(FindPkgConfig)
|
||||
if(NOT PKG_CONFIG_FOUND)
|
||||
INCLUDE(FindPkgConfig)
|
||||
endif()
|
||||
PKG_CHECK_MODULES(PC_LIBAIRSPY libairspy)
|
||||
|
||||
FIND_PATH(
|
||||
|
@ -20,5 +22,5 @@ FIND_LIBRARY(
|
|||
)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBAIRSPY DEFAULT_MSG LIBAIRSPY_LIBRARIES LIBAIRSPY_INCLUDE_DIRS)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibAIRSPY DEFAULT_MSG LIBAIRSPY_LIBRARIES LIBAIRSPY_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(LIBAIRSPY_LIBRARIES LIBAIRSPY_INCLUDE_DIRS)
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
if(NOT PKG_CONFIG_FOUND)
|
||||
INCLUDE(FindPkgConfig)
|
||||
endif()
|
||||
PKG_CHECK_MODULES(PC_LIBAIRSPYHF libairspyhf)
|
||||
|
||||
FIND_PATH(
|
||||
LIBAIRSPYHF_INCLUDE_DIRS
|
||||
NAMES libairspyhf/airspyhf.h
|
||||
HINTS $ENV{LIBAIRSPYHF_DIR}/include
|
||||
${PC_LIBAIRSPYHF_INCLUDEDIR}
|
||||
PATHS /usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(
|
||||
LIBAIRSPYHF_LIBRARIES
|
||||
NAMES airspyhf
|
||||
HINTS $ENV{LIBAIRSPYHF_DIR}/lib
|
||||
${PC_LIBAIRSPYHF_LIBDIR}
|
||||
PATHS /usr/local/lib
|
||||
/usr/lib
|
||||
)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibAIRSPYHF DEFAULT_MSG LIBAIRSPYHF_LIBRARIES LIBAIRSPYHF_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(LIBAIRSPYHF_LIBRARIES LIBAIRSPYHF_INCLUDE_DIRS)
|
|
@ -0,0 +1,27 @@
|
|||
if(NOT LIBFREESRP_FOUND)
|
||||
pkg_check_modules (LIBFREESRP_PKG libfreesrp)
|
||||
find_path(LIBFREESRP_INCLUDE_DIRS NAMES freesrp.hpp
|
||||
PATHS
|
||||
${LIBFREESRP_PKG_INCLUDE_DIRS}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
find_library(LIBFREESRP_LIBRARIES NAMES freesrp
|
||||
PATHS
|
||||
${LIBFREESRP_PKG_LIBRARY_DIRS}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
)
|
||||
|
||||
if(LIBFREESRP_INCLUDE_DIRS AND LIBFREESRP_LIBRARIES)
|
||||
set(LIBFREESRP_FOUND TRUE CACHE INTERNAL "libfreesrp found")
|
||||
message(STATUS "Found libfreesrp: ${LIBFREESRP_INCLUDE_DIRS}, ${LIBFREESRP_LIBRARIES}")
|
||||
else(LIBFREESRP_INCLUDE_DIRS AND LIBFREESRP_LIBRARIES)
|
||||
set(LIBFREESRP_FOUND FALSE CACHE INTERNAL "libfreesrp found")
|
||||
message(STATUS "libfreesrp not found.")
|
||||
endif(LIBFREESRP_INCLUDE_DIRS AND LIBFREESRP_LIBRARIES)
|
||||
|
||||
mark_as_advanced(LIBFREESRP_LIBRARIES LIBFREESRP_INCLUDE_DIRS)
|
||||
|
||||
endif(NOT LIBFREESRP_FOUND)
|
|
@ -1,4 +1,6 @@
|
|||
INCLUDE(FindPkgConfig)
|
||||
if(NOT PKG_CONFIG_FOUND)
|
||||
INCLUDE(FindPkgConfig)
|
||||
endif()
|
||||
PKG_CHECK_MODULES(PC_LIBHACKRF libhackrf)
|
||||
|
||||
FIND_PATH(
|
||||
|
@ -20,5 +22,6 @@ FIND_LIBRARY(
|
|||
)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBHACKRF DEFAULT_MSG LIBHACKRF_LIBRARIES LIBHACKRF_INCLUDE_DIRS)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibHackRF DEFAULT_MSG LIBHACKRF_LIBRARIES LIBHACKRF_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(LIBHACKRF_LIBRARIES LIBHACKRF_INCLUDE_DIRS)
|
||||
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
if(NOT LIBMIRISDR_FOUND)
|
||||
pkg_check_modules (LIBMIRISDR_PKG libmirisdr)
|
||||
find_path(LIBMIRISDR_INCLUDE_DIRS NAMES mirisdr.h
|
||||
PATHS
|
||||
${LIBMIRISDR_PKG_INCLUDE_DIRS}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
find_library(LIBMIRISDR_LIBRARIES NAMES mirisdr
|
||||
PATHS
|
||||
${LIBMIRISDR_PKG_LIBRARY_DIRS}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
)
|
||||
|
||||
if(LIBMIRISDR_INCLUDE_DIRS AND LIBMIRISDR_LIBRARIES)
|
||||
set(LIBMIRISDR_FOUND TRUE CACHE INTERNAL "libmirisdr found")
|
||||
message(STATUS "Found libmirisdr: ${LIBMIRISDR_INCLUDE_DIRS}, ${LIBMIRISDR_LIBRARIES}")
|
||||
else(LIBMIRISDR_INCLUDE_DIRS AND LIBMIRISDR_LIBRARIES)
|
||||
set(LIBMIRISDR_FOUND FALSE CACHE INTERNAL "libmirisdr found")
|
||||
message(STATUS "libmirisdr not found.")
|
||||
endif(LIBMIRISDR_INCLUDE_DIRS AND LIBMIRISDR_LIBRARIES)
|
||||
|
||||
mark_as_advanced(LIBMIRISDR_LIBRARIES LIBMIRISDR_INCLUDE_DIRS)
|
||||
|
||||
endif(NOT LIBMIRISDR_FOUND)
|
|
@ -1,27 +0,0 @@
|
|||
if(NOT LIBOSMOSDR_FOUND)
|
||||
pkg_check_modules (LIBOSMOSDR_PKG libosmosdr)
|
||||
find_path(LIBOSMOSDR_INCLUDE_DIRS NAMES osmosdr.h
|
||||
PATHS
|
||||
${LIBOSMOSDR_PKG_INCLUDE_DIRS}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
find_library(LIBOSMOSDR_LIBRARIES NAMES osmosdr
|
||||
PATHS
|
||||
${LIBOSMOSDR_PKG_LIBRARY_DIRS}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
)
|
||||
|
||||
if(LIBOSMOSDR_INCLUDE_DIRS AND LIBOSMOSDR_LIBRARIES)
|
||||
set(LIBOSMOSDR_FOUND TRUE CACHE INTERNAL "libosmosdr found")
|
||||
message(STATUS "Found libosmosdr: ${LIBOSMOSDR_INCLUDE_DIRS}, ${LIBOSMOSDR_LIBRARIES}")
|
||||
else(LIBOSMOSDR_INCLUDE_DIRS AND LIBOSMOSDR_LIBRARIES)
|
||||
set(LIBOSMOSDR_FOUND FALSE CACHE INTERNAL "libosmosdr found")
|
||||
message(STATUS "libosmosdr not found.")
|
||||
endif(LIBOSMOSDR_INCLUDE_DIRS AND LIBOSMOSDR_LIBRARIES)
|
||||
|
||||
mark_as_advanced(LIBOSMOSDR_LIBRARIES LIBOSMOSDR_INCLUDE_DIRS)
|
||||
|
||||
endif(NOT LIBOSMOSDR_FOUND)
|
|
@ -0,0 +1,27 @@
|
|||
if(NOT LIBSDRPLAY_FOUND)
|
||||
pkg_check_modules (LIBSDRPLAY_PKG libsdrplay)
|
||||
find_path(LIBSDRPLAY_INCLUDE_DIRS NAMES mirsdrapi-rsp.h
|
||||
PATHS
|
||||
${LIBSDRPLAY_PKG_INCLUDE_DIRS}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
find_library(LIBSDRPLAY_LIBRARIES NAMES mirsdrapi-rsp
|
||||
PATHS
|
||||
${LIBSDRPLAY_PKG_LIBRARY_DIRS}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
)
|
||||
|
||||
if(LIBSDRPLAY_INCLUDE_DIRS AND LIBSDRPLAY_LIBRARIES)
|
||||
set(LIBSDRPLAY_FOUND TRUE CACHE INTERNAL "libsdrplay found")
|
||||
message(STATUS "Found libsdrplay: ${LIBSDRPLAY_INCLUDE_DIRS}, ${LIBSDRPLAY_LIBRARIES}")
|
||||
else(LIBSDRPLAY_INCLUDE_DIRS AND LIBSDRPLAY_LIBRARIES)
|
||||
set(LIBSDRPLAY_FOUND FALSE CACHE INTERNAL "libsdrplay found")
|
||||
message(STATUS "libsdrplay not found.")
|
||||
endif(LIBSDRPLAY_INCLUDE_DIRS AND LIBSDRPLAY_LIBRARIES)
|
||||
|
||||
mark_as_advanced(LIBSDRPLAY_LIBRARIES LIBSDRPLAY_INCLUDE_DIRS)
|
||||
|
||||
endif(NOT LIBSDRPLAY_FOUND)
|
|
@ -0,0 +1,27 @@
|
|||
if(NOT LIBXTRX_FOUND)
|
||||
pkg_check_modules (LIBXTRX_PKG libxtrx)
|
||||
find_path(LIBXTRX_INCLUDE_DIRS NAMES xtrx_api.h
|
||||
PATHS
|
||||
${LIBXTRX_PKG_INCLUDE_DIRS}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
find_library(LIBXTRX_LIBRARIES NAMES xtrx
|
||||
PATHS
|
||||
${LIBXTRX_PKG_LIBRARY_DIRS}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
)
|
||||
|
||||
if(LIBXTRX_INCLUDE_DIRS AND LIBXTRX_LIBRARIES)
|
||||
set(LIBXTRX_FOUND TRUE CACHE INTERNAL "libxtrx found")
|
||||
message(STATUS "Found libxtrx: ${LIBXTRX_INCLUDE_DIRS}, ${LIBXTRX_LIBRARIES}")
|
||||
else(LIBXTRX_INCLUDE_DIRS AND LIBXTRX_LIBRARIES)
|
||||
set(LIBXTRX_FOUND FALSE CACHE INTERNAL "libxtrx found")
|
||||
message(STATUS "libxtrx not found.")
|
||||
endif(LIBXTRX_INCLUDE_DIRS AND LIBXTRX_LIBRARIES)
|
||||
|
||||
mark_as_advanced(LIBXTRX_LIBRARIES LIBXTRX_INCLUDE_DIRS)
|
||||
|
||||
endif(NOT LIBXTRX_FOUND)
|
|
@ -1,5 +1,9 @@
|
|||
if(NOT LIBBLADERF_FOUND)
|
||||
pkg_check_modules (LIBBLADERF_PKG libbladeRF)
|
||||
if (LIBBLADERF_PKG_FOUND AND LIBBLADERF_PKG_VERSION VERSION_LESS "2")
|
||||
message( FATAL_ERROR "Install version 2 or greater of libbladeRF."
|
||||
" Current version ( ${LIBBLADERF_PKG_VERSION} ) is out of date." )
|
||||
endif()
|
||||
find_path(LIBBLADERF_INCLUDE_DIRS NAMES libbladeRF.h
|
||||
PATHS
|
||||
${LIBBLADERF_PKG_INCLUDE_DIRS}
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
# Copyright 2010-2011 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
#
|
||||
# GNU Radio 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
if(DEFINED __INCLUDED_GR_COMPONENT_CMAKE)
|
||||
return()
|
||||
endif()
|
||||
set(__INCLUDED_GR_COMPONENT_CMAKE TRUE)
|
||||
|
||||
set(_gr_enabled_components "" CACHE INTERNAL "" FORCE)
|
||||
set(_gr_disabled_components "" CACHE INTERNAL "" FORCE)
|
||||
|
||||
if(NOT DEFINED ENABLE_DEFAULT)
|
||||
set(ENABLE_DEFAULT ON)
|
||||
message(STATUS "")
|
||||
message(STATUS "The build system will automatically enable all components.")
|
||||
message(STATUS "Use -DENABLE_DEFAULT=OFF to disable components by default.")
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
# Register a component into the system
|
||||
# - name: canonical component name
|
||||
# - var: variable for enabled status
|
||||
# - argn: list of dependencies
|
||||
########################################################################
|
||||
function(GR_REGISTER_COMPONENT name var)
|
||||
include(CMakeDependentOption)
|
||||
message(STATUS "")
|
||||
message(STATUS "Configuring ${name} support...")
|
||||
foreach(dep ${ARGN})
|
||||
message(STATUS " Dependency ${dep} = ${${dep}}")
|
||||
endforeach(dep)
|
||||
|
||||
#if the user set the var to force, we note this
|
||||
if("${${var}}" STREQUAL "FORCE")
|
||||
set(${var} ON)
|
||||
set(var_force TRUE)
|
||||
else()
|
||||
set(var_force FALSE)
|
||||
endif()
|
||||
|
||||
#rewrite the dependency list so that deps that are also components use the cached version
|
||||
unset(comp_deps)
|
||||
foreach(dep ${ARGN})
|
||||
list(FIND _gr_enabled_components ${dep} dep_enb_index)
|
||||
list(FIND _gr_disabled_components ${dep} dep_dis_index)
|
||||
if (${dep_enb_index} EQUAL -1 AND ${dep_dis_index} EQUAL -1)
|
||||
list(APPEND comp_deps ${dep})
|
||||
else()
|
||||
list(APPEND comp_deps ${dep}_cached) #is a component, use cached version
|
||||
endif()
|
||||
endforeach(dep)
|
||||
|
||||
#setup the dependent option for this component
|
||||
CMAKE_DEPENDENT_OPTION(${var} "enable ${name} support" ${ENABLE_DEFAULT} "${comp_deps}" OFF)
|
||||
set(${var} "${${var}}" PARENT_SCOPE)
|
||||
set(${var}_cached "${${var}}" CACHE INTERNAL "" FORCE)
|
||||
|
||||
#force was specified, but the dependencies were not met
|
||||
if(NOT ${var} AND var_force)
|
||||
message(FATAL_ERROR "user force-enabled ${name} but configuration checked failed")
|
||||
endif()
|
||||
|
||||
#append the component into one of the lists
|
||||
if(${var})
|
||||
message(STATUS " Enabling ${name} support.")
|
||||
list(APPEND _gr_enabled_components ${name})
|
||||
else(${var})
|
||||
message(STATUS " Disabling ${name} support.")
|
||||
list(APPEND _gr_disabled_components ${name})
|
||||
endif(${var})
|
||||
message(STATUS " Override with -D${var}=ON/OFF")
|
||||
|
||||
#make components lists into global variables
|
||||
set(_gr_enabled_components ${_gr_enabled_components} CACHE INTERNAL "" FORCE)
|
||||
set(_gr_disabled_components ${_gr_disabled_components} CACHE INTERNAL "" FORCE)
|
||||
endfunction(GR_REGISTER_COMPONENT)
|
||||
|
||||
########################################################################
|
||||
# Print the registered component summary
|
||||
########################################################################
|
||||
function(GR_PRINT_COMPONENT_SUMMARY)
|
||||
message(STATUS "")
|
||||
message(STATUS "######################################################")
|
||||
message(STATUS "# gr-osmosdr enabled components ")
|
||||
message(STATUS "######################################################")
|
||||
foreach(comp ${_gr_enabled_components})
|
||||
message(STATUS " * ${comp}")
|
||||
endforeach(comp)
|
||||
|
||||
message(STATUS "")
|
||||
message(STATUS "######################################################")
|
||||
message(STATUS "# gr-osmosdr disabled components ")
|
||||
message(STATUS "######################################################")
|
||||
foreach(comp ${_gr_disabled_components})
|
||||
message(STATUS " * ${comp}")
|
||||
endforeach(comp)
|
||||
|
||||
message(STATUS "")
|
||||
endfunction(GR_PRINT_COMPONENT_SUMMARY)
|
|
@ -1,519 +0,0 @@
|
|||
# Copyright 2010-2011,2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
#
|
||||
# GNU Radio 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
if(DEFINED __INCLUDED_GR_MISC_UTILS_CMAKE)
|
||||
return()
|
||||
endif()
|
||||
set(__INCLUDED_GR_MISC_UTILS_CMAKE TRUE)
|
||||
|
||||
########################################################################
|
||||
# Set global variable macro.
|
||||
# Used for subdirectories to export settings.
|
||||
# Example: include and library paths.
|
||||
########################################################################
|
||||
function(GR_SET_GLOBAL var)
|
||||
set(${var} ${ARGN} CACHE INTERNAL "" FORCE)
|
||||
endfunction(GR_SET_GLOBAL)
|
||||
|
||||
########################################################################
|
||||
# Set the pre-processor definition if the condition is true.
|
||||
# - def the pre-processor definition to set and condition name
|
||||
########################################################################
|
||||
function(GR_ADD_COND_DEF def)
|
||||
if(${def})
|
||||
add_definitions(-D${def})
|
||||
endif(${def})
|
||||
endfunction(GR_ADD_COND_DEF)
|
||||
|
||||
########################################################################
|
||||
# Check for a header and conditionally set a compile define.
|
||||
# - hdr the relative path to the header file
|
||||
# - def the pre-processor definition to set
|
||||
########################################################################
|
||||
function(GR_CHECK_HDR_N_DEF hdr def)
|
||||
include(CheckIncludeFileCXX)
|
||||
CHECK_INCLUDE_FILE_CXX(${hdr} ${def})
|
||||
GR_ADD_COND_DEF(${def})
|
||||
endfunction(GR_CHECK_HDR_N_DEF)
|
||||
|
||||
########################################################################
|
||||
# Include subdirectory macro.
|
||||
# Sets the CMake directory variables,
|
||||
# includes the subdirectory CMakeLists.txt,
|
||||
# resets the CMake directory variables.
|
||||
#
|
||||
# This macro includes subdirectories rather than adding them
|
||||
# so that the subdirectory can affect variables in the level above.
|
||||
# This provides a work-around for the lack of convenience libraries.
|
||||
# This way a subdirectory can append to the list of library sources.
|
||||
########################################################################
|
||||
macro(GR_INCLUDE_SUBDIRECTORY subdir)
|
||||
#insert the current directories on the front of the list
|
||||
list(INSERT _cmake_source_dirs 0 ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
list(INSERT _cmake_binary_dirs 0 ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
#set the current directories to the names of the subdirs
|
||||
set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${subdir})
|
||||
set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${subdir})
|
||||
|
||||
#include the subdirectory CMakeLists to run it
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
|
||||
|
||||
#reset the value of the current directories
|
||||
list(GET _cmake_source_dirs 0 CMAKE_CURRENT_SOURCE_DIR)
|
||||
list(GET _cmake_binary_dirs 0 CMAKE_CURRENT_BINARY_DIR)
|
||||
|
||||
#pop the subdir names of the front of the list
|
||||
list(REMOVE_AT _cmake_source_dirs 0)
|
||||
list(REMOVE_AT _cmake_binary_dirs 0)
|
||||
endmacro(GR_INCLUDE_SUBDIRECTORY)
|
||||
|
||||
########################################################################
|
||||
# Check if a compiler flag works and conditionally set a compile define.
|
||||
# - flag the compiler flag to check for
|
||||
# - have the variable to set with result
|
||||
########################################################################
|
||||
macro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE flag have)
|
||||
include(CheckCXXCompilerFlag)
|
||||
CHECK_CXX_COMPILER_FLAG(${flag} ${have})
|
||||
if(${have})
|
||||
add_definitions(${flag})
|
||||
endif(${have})
|
||||
endmacro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE)
|
||||
|
||||
########################################################################
|
||||
# Generates the .la libtool file
|
||||
# This appears to generate libtool files that cannot be used by auto*.
|
||||
# Usage GR_LIBTOOL(TARGET [target] DESTINATION [dest])
|
||||
# Notice: there is not COMPONENT option, these will not get distributed.
|
||||
########################################################################
|
||||
function(GR_LIBTOOL)
|
||||
if(NOT DEFINED GENERATE_LIBTOOL)
|
||||
set(GENERATE_LIBTOOL OFF) #disabled by default
|
||||
endif()
|
||||
|
||||
if(GENERATE_LIBTOOL)
|
||||
include(CMakeParseArgumentsCopy)
|
||||
CMAKE_PARSE_ARGUMENTS(GR_LIBTOOL "" "TARGET;DESTINATION" "" ${ARGN})
|
||||
|
||||
find_program(LIBTOOL libtool)
|
||||
if(LIBTOOL)
|
||||
include(CMakeMacroLibtoolFile)
|
||||
CREATE_LIBTOOL_FILE(${GR_LIBTOOL_TARGET} /${GR_LIBTOOL_DESTINATION})
|
||||
endif(LIBTOOL)
|
||||
endif(GENERATE_LIBTOOL)
|
||||
|
||||
endfunction(GR_LIBTOOL)
|
||||
|
||||
########################################################################
|
||||
# Do standard things to the library target
|
||||
# - set target properties
|
||||
# - make install rules
|
||||
# Also handle gnuradio custom naming conventions w/ extras mode.
|
||||
########################################################################
|
||||
function(GR_LIBRARY_FOO target)
|
||||
#parse the arguments for component names
|
||||
include(CMakeParseArgumentsCopy)
|
||||
CMAKE_PARSE_ARGUMENTS(GR_LIBRARY "" "RUNTIME_COMPONENT;DEVEL_COMPONENT" "" ${ARGN})
|
||||
|
||||
#set additional target properties
|
||||
set_target_properties(${target} PROPERTIES SOVERSION ${LIBVER})
|
||||
|
||||
#install the generated files like so...
|
||||
install(TARGETS ${target}
|
||||
LIBRARY DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .so/.dylib file
|
||||
ARCHIVE DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_DEVEL_COMPONENT} # .lib file
|
||||
RUNTIME DESTINATION ${GR_RUNTIME_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .dll file
|
||||
)
|
||||
|
||||
#extras mode enabled automatically on linux
|
||||
if(NOT DEFINED LIBRARY_EXTRAS)
|
||||
set(LIBRARY_EXTRAS ${LINUX})
|
||||
endif()
|
||||
|
||||
#special extras mode to enable alternative naming conventions
|
||||
if(LIBRARY_EXTRAS)
|
||||
|
||||
#create .la file before changing props
|
||||
GR_LIBTOOL(TARGET ${target} DESTINATION ${GR_LIBRARY_DIR})
|
||||
|
||||
#give the library a special name with ultra-zero soversion
|
||||
set_target_properties(${target} PROPERTIES OUTPUT_NAME ${target}-${LIBVER} SOVERSION "0.0.0")
|
||||
set(target_name lib${target}-${LIBVER}.so.0.0.0)
|
||||
|
||||
#custom command to generate symlinks
|
||||
add_custom_command(
|
||||
TARGET ${target}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0
|
||||
COMMAND ${CMAKE_COMMAND} -E touch ${target_name} #so the symlinks point to something valid so cmake 2.6 will install
|
||||
)
|
||||
|
||||
#and install the extra symlinks
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0
|
||||
DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT}
|
||||
)
|
||||
|
||||
endif(LIBRARY_EXTRAS)
|
||||
endfunction(GR_LIBRARY_FOO)
|
||||
|
||||
########################################################################
|
||||
# Create a dummy custom command that depends on other targets.
|
||||
# Usage:
|
||||
# GR_GEN_TARGET_DEPS(unique_name target_deps <target1> <target2> ...)
|
||||
# ADD_CUSTOM_COMMAND(<the usual args> ${target_deps})
|
||||
#
|
||||
# Custom command cant depend on targets, but can depend on executables,
|
||||
# and executables can depend on targets. So this is the process:
|
||||
########################################################################
|
||||
function(GR_GEN_TARGET_DEPS name var)
|
||||
file(
|
||||
WRITE ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in
|
||||
"int main(void){return 0;}\n"
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp
|
||||
)
|
||||
add_executable(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp)
|
||||
if(ARGN)
|
||||
add_dependencies(${name} ${ARGN})
|
||||
endif(ARGN)
|
||||
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
set(${var} "DEPENDS;${name}" PARENT_SCOPE) #cant call command when cross
|
||||
else()
|
||||
set(${var} "DEPENDS;${name};COMMAND;${name}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction(GR_GEN_TARGET_DEPS)
|
||||
|
||||
########################################################################
|
||||
# Control use of gr_logger
|
||||
# Usage:
|
||||
# GR_LOGGING()
|
||||
#
|
||||
# Will set ENABLE_GR_LOG to 1 by default.
|
||||
# Can manually set with -DENABLE_GR_LOG=0|1
|
||||
########################################################################
|
||||
function(GR_LOGGING)
|
||||
find_package(Log4cpp)
|
||||
|
||||
OPTION(ENABLE_GR_LOG "Use gr_logger" ON)
|
||||
if(ENABLE_GR_LOG)
|
||||
# If gr_logger is enabled, make it usable
|
||||
add_definitions( -DENABLE_GR_LOG )
|
||||
|
||||
# also test LOG4CPP; if we have it, use this version of the logger
|
||||
# otherwise, default to the stdout/stderr model.
|
||||
if(LOG4CPP_FOUND)
|
||||
SET(HAVE_LOG4CPP True CACHE INTERNAL "" FORCE)
|
||||
add_definitions( -DHAVE_LOG4CPP )
|
||||
else(not LOG4CPP_FOUND)
|
||||
SET(HAVE_LOG4CPP False CACHE INTERNAL "" FORCE)
|
||||
SET(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE)
|
||||
SET(LOG4CPP_LIBRARY_DIRS "" CACHE INTERNAL "" FORCE)
|
||||
SET(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE)
|
||||
endif(LOG4CPP_FOUND)
|
||||
|
||||
SET(ENABLE_GR_LOG ${ENABLE_GR_LOG} CACHE INTERNAL "" FORCE)
|
||||
|
||||
else(ENABLE_GR_LOG)
|
||||
SET(HAVE_LOG4CPP False CACHE INTERNAL "" FORCE)
|
||||
SET(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE)
|
||||
SET(LOG4CPP_LIBRARY_DIRS "" CACHE INTERNAL "" FORCE)
|
||||
SET(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE)
|
||||
endif(ENABLE_GR_LOG)
|
||||
|
||||
message(STATUS "ENABLE_GR_LOG set to ${ENABLE_GR_LOG}.")
|
||||
message(STATUS "HAVE_LOG4CPP set to ${HAVE_LOG4CPP}.")
|
||||
message(STATUS "LOG4CPP_LIBRARIES set to ${LOG4CPP_LIBRARIES}.")
|
||||
|
||||
endfunction(GR_LOGGING)
|
||||
|
||||
########################################################################
|
||||
# Run GRCC to compile .grc files into .py files.
|
||||
#
|
||||
# Usage: GRCC(filename, directory)
|
||||
# - filenames: List of file name of .grc file
|
||||
# - directory: directory of built .py file - usually in
|
||||
# ${CMAKE_CURRENT_BINARY_DIR}
|
||||
# - Sets PYFILES: output converted GRC file names to Python files.
|
||||
########################################################################
|
||||
function(GRCC)
|
||||
# Extract directory from list of args, remove it for the list of filenames.
|
||||
list(GET ARGV -1 directory)
|
||||
list(REMOVE_AT ARGV -1)
|
||||
set(filenames ${ARGV})
|
||||
file(MAKE_DIRECTORY ${directory})
|
||||
|
||||
SET(GRCC_COMMAND ${CMAKE_SOURCE_DIR}/gr-utils/python/grcc)
|
||||
|
||||
# GRCC uses some stuff in grc and gnuradio-runtime, so we force
|
||||
# the known paths here
|
||||
list(APPEND PYTHONPATHS
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/gnuradio-runtime/python
|
||||
${CMAKE_SOURCE_DIR}/gnuradio-runtime/lib/swig
|
||||
${CMAKE_BINARY_DIR}/gnuradio-runtime/lib/swig
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
#SWIG generates the python library files into a subdirectory.
|
||||
#Therefore, we must append this subdirectory into PYTHONPATH.
|
||||
#Only do this for the python directories matching the following:
|
||||
foreach(pydir ${PYTHONPATHS})
|
||||
get_filename_component(name ${pydir} NAME)
|
||||
if(name MATCHES "^(swig|lib|src)$")
|
||||
list(APPEND PYTHONPATHS ${pydir}/${CMAKE_BUILD_TYPE})
|
||||
endif()
|
||||
endforeach(pydir)
|
||||
endif(WIN32)
|
||||
|
||||
file(TO_NATIVE_PATH "${PYTHONPATHS}" pypath)
|
||||
|
||||
if(UNIX)
|
||||
list(APPEND pypath "$PYTHONPATH")
|
||||
string(REPLACE ";" ":" pypath "${pypath}")
|
||||
set(ENV{PYTHONPATH} ${pypath})
|
||||
endif(UNIX)
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND pypath "%PYTHONPATH%")
|
||||
string(REPLACE ";" "\\;" pypath "${pypath}")
|
||||
#list(APPEND environs "PYTHONPATH=${pypath}")
|
||||
set(ENV{PYTHONPATH} ${pypath})
|
||||
endif(WIN32)
|
||||
|
||||
foreach(f ${filenames})
|
||||
execute_process(
|
||||
COMMAND ${GRCC_COMMAND} -d ${directory} ${f}
|
||||
)
|
||||
string(REPLACE ".grc" ".py" pyfile "${f}")
|
||||
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" pyfile "${pyfile}")
|
||||
list(APPEND pyfiles ${pyfile})
|
||||
endforeach(f)
|
||||
|
||||
set(PYFILES ${pyfiles} PARENT_SCOPE)
|
||||
endfunction(GRCC)
|
||||
|
||||
########################################################################
|
||||
# Check if HAVE_PTHREAD_SETSCHEDPARAM and HAVE_SCHED_SETSCHEDULER
|
||||
# should be defined
|
||||
########################################################################
|
||||
macro(GR_CHECK_LINUX_SCHED_AVAIL)
|
||||
set(CMAKE_REQUIRED_LIBRARIES -lpthread)
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <pthread.h>
|
||||
int main(){
|
||||
pthread_t pthread;
|
||||
pthread_setschedparam(pthread, 0, 0);
|
||||
return 0;
|
||||
} " HAVE_PTHREAD_SETSCHEDPARAM
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_PTHREAD_SETSCHEDPARAM)
|
||||
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <sched.h>
|
||||
int main(){
|
||||
pid_t pid;
|
||||
sched_setscheduler(pid, 0, 0);
|
||||
return 0;
|
||||
} " HAVE_SCHED_SETSCHEDULER
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_SCHED_SETSCHEDULER)
|
||||
endmacro(GR_CHECK_LINUX_SCHED_AVAIL)
|
||||
|
||||
########################################################################
|
||||
# Macros to generate source and header files from template
|
||||
########################################################################
|
||||
macro(GR_EXPAND_X_H component root)
|
||||
|
||||
include(GrPython)
|
||||
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
|
||||
"#!${PYTHON_EXECUTABLE}
|
||||
|
||||
import sys, os, re
|
||||
sys.path.append('${GR_RUNTIME_PYTHONPATH}')
|
||||
os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
|
||||
os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
|
||||
|
||||
if __name__ == '__main__':
|
||||
import build_utils
|
||||
root, inp = sys.argv[1:3]
|
||||
for sig in sys.argv[3:]:
|
||||
name = re.sub ('X+', sig, root)
|
||||
d = build_utils.standard_dict2(name, sig, '${component}')
|
||||
build_utils.expand_template(d, inp)
|
||||
")
|
||||
|
||||
#make a list of all the generated headers
|
||||
unset(expanded_files_h)
|
||||
foreach(sig ${ARGN})
|
||||
string(REGEX REPLACE "X+" ${sig} name ${root})
|
||||
list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
|
||||
endforeach(sig)
|
||||
unset(name)
|
||||
|
||||
#create a command to generate the headers
|
||||
add_custom_command(
|
||||
OUTPUT ${expanded_files_h}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
|
||||
${root} ${root}.h.t ${ARGN}
|
||||
)
|
||||
|
||||
#install rules for the generated headers
|
||||
list(APPEND generated_includes ${expanded_files_h})
|
||||
|
||||
endmacro(GR_EXPAND_X_H)
|
||||
|
||||
macro(GR_EXPAND_X_CC_H component root)
|
||||
|
||||
include(GrPython)
|
||||
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
|
||||
"#!${PYTHON_EXECUTABLE}
|
||||
|
||||
import sys, os, re
|
||||
sys.path.append('${GR_RUNTIME_PYTHONPATH}')
|
||||
os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
|
||||
os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
|
||||
|
||||
if __name__ == '__main__':
|
||||
import build_utils
|
||||
root, inp = sys.argv[1:3]
|
||||
for sig in sys.argv[3:]:
|
||||
name = re.sub ('X+', sig, root)
|
||||
d = build_utils.standard_impl_dict2(name, sig, '${component}')
|
||||
build_utils.expand_template(d, inp)
|
||||
")
|
||||
|
||||
#make a list of all the generated files
|
||||
unset(expanded_files_cc)
|
||||
unset(expanded_files_h)
|
||||
foreach(sig ${ARGN})
|
||||
string(REGEX REPLACE "X+" ${sig} name ${root})
|
||||
list(APPEND expanded_files_cc ${CMAKE_CURRENT_BINARY_DIR}/${name}.cc)
|
||||
list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
|
||||
endforeach(sig)
|
||||
unset(name)
|
||||
|
||||
#create a command to generate the source files
|
||||
add_custom_command(
|
||||
OUTPUT ${expanded_files_cc}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.cc.t
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
|
||||
${root} ${root}.cc.t ${ARGN}
|
||||
)
|
||||
|
||||
#create a command to generate the header files
|
||||
add_custom_command(
|
||||
OUTPUT ${expanded_files_h}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
|
||||
${root} ${root}.h.t ${ARGN}
|
||||
)
|
||||
|
||||
#make source files depends on headers to force generation
|
||||
set_source_files_properties(${expanded_files_cc}
|
||||
PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
|
||||
)
|
||||
|
||||
#install rules for the generated files
|
||||
list(APPEND generated_sources ${expanded_files_cc})
|
||||
list(APPEND generated_headers ${expanded_files_h})
|
||||
|
||||
endmacro(GR_EXPAND_X_CC_H)
|
||||
|
||||
macro(GR_EXPAND_X_CC_H_IMPL component root)
|
||||
|
||||
include(GrPython)
|
||||
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
|
||||
"#!${PYTHON_EXECUTABLE}
|
||||
|
||||
import sys, os, re
|
||||
sys.path.append('${GR_RUNTIME_PYTHONPATH}')
|
||||
os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
|
||||
os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
|
||||
|
||||
if __name__ == '__main__':
|
||||
import build_utils
|
||||
root, inp = sys.argv[1:3]
|
||||
for sig in sys.argv[3:]:
|
||||
name = re.sub ('X+', sig, root)
|
||||
d = build_utils.standard_dict(name, sig, '${component}')
|
||||
build_utils.expand_template(d, inp, '_impl')
|
||||
")
|
||||
|
||||
#make a list of all the generated files
|
||||
unset(expanded_files_cc_impl)
|
||||
unset(expanded_files_h_impl)
|
||||
unset(expanded_files_h)
|
||||
foreach(sig ${ARGN})
|
||||
string(REGEX REPLACE "X+" ${sig} name ${root})
|
||||
list(APPEND expanded_files_cc_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.cc)
|
||||
list(APPEND expanded_files_h_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.h)
|
||||
list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/../include/gnuradio/${component}/${name}.h)
|
||||
endforeach(sig)
|
||||
unset(name)
|
||||
|
||||
#create a command to generate the _impl.cc files
|
||||
add_custom_command(
|
||||
OUTPUT ${expanded_files_cc_impl}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.cc.t
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
|
||||
${root} ${root}_impl.cc.t ${ARGN}
|
||||
)
|
||||
|
||||
#create a command to generate the _impl.h files
|
||||
add_custom_command(
|
||||
OUTPUT ${expanded_files_h_impl}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.h.t
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
|
||||
${root} ${root}_impl.h.t ${ARGN}
|
||||
)
|
||||
|
||||
#make _impl.cc source files depend on _impl.h to force generation
|
||||
set_source_files_properties(${expanded_files_cc_impl}
|
||||
PROPERTIES OBJECT_DEPENDS "${expanded_files_h_impl}"
|
||||
)
|
||||
|
||||
#make _impl.h source files depend on headers to force generation
|
||||
set_source_files_properties(${expanded_files_h_impl}
|
||||
PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
|
||||
)
|
||||
|
||||
#install rules for the generated files
|
||||
list(APPEND generated_sources ${expanded_files_cc_impl})
|
||||
list(APPEND generated_headers ${expanded_files_h_impl})
|
||||
|
||||
endmacro(GR_EXPAND_X_CC_H_IMPL)
|
|
@ -1,54 +0,0 @@
|
|||
# Copyright 2011 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
#
|
||||
# GNU Radio 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
if(DEFINED __INCLUDED_GR_PLATFORM_CMAKE)
|
||||
return()
|
||||
endif()
|
||||
set(__INCLUDED_GR_PLATFORM_CMAKE TRUE)
|
||||
|
||||
########################################################################
|
||||
# Setup additional defines for OS types
|
||||
########################################################################
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(LINUX TRUE)
|
||||
endif()
|
||||
|
||||
if(LINUX AND EXISTS "/etc/debian_version")
|
||||
set(DEBIAN TRUE)
|
||||
endif()
|
||||
|
||||
if(LINUX AND EXISTS "/etc/redhat-release")
|
||||
set(REDHAT TRUE)
|
||||
endif()
|
||||
|
||||
if(LINUX AND EXISTS "/etc/slackware-version")
|
||||
set(SLACKWARE TRUE)
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
# when the library suffix should be 64 (applies to redhat linux family)
|
||||
########################################################################
|
||||
if (REDHAT OR SLACKWARE)
|
||||
set(LIB64_CONVENTION TRUE)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED LIB_SUFFIX AND LIB64_CONVENTION AND CMAKE_SYSTEM_PROCESSOR MATCHES "64$")
|
||||
set(LIB_SUFFIX 64)
|
||||
endif()
|
||||
set(LIB_SUFFIX ${LIB_SUFFIX} CACHE STRING "lib directory suffix")
|
|
@ -1,242 +0,0 @@
|
|||
# Copyright 2010-2011 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
#
|
||||
# GNU Radio 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
if(DEFINED __INCLUDED_GR_PYTHON_CMAKE)
|
||||
return()
|
||||
endif()
|
||||
set(__INCLUDED_GR_PYTHON_CMAKE TRUE)
|
||||
|
||||
########################################################################
|
||||
# Setup the python interpreter:
|
||||
# This allows the user to specify a specific interpreter,
|
||||
# or finds the interpreter via the built-in cmake module.
|
||||
########################################################################
|
||||
#this allows the user to override PYTHON_EXECUTABLE
|
||||
if(PYTHON_EXECUTABLE)
|
||||
|
||||
set(PYTHONINTERP_FOUND TRUE)
|
||||
|
||||
#otherwise if not set, try to automatically find it
|
||||
else(PYTHON_EXECUTABLE)
|
||||
|
||||
#use the built-in find script
|
||||
find_package(PythonInterp 2)
|
||||
|
||||
#and if that fails use the find program routine
|
||||
if(NOT PYTHONINTERP_FOUND)
|
||||
find_program(PYTHON_EXECUTABLE NAMES python python2 python2.7 python2.6 python2.5)
|
||||
if(PYTHON_EXECUTABLE)
|
||||
set(PYTHONINTERP_FOUND TRUE)
|
||||
endif(PYTHON_EXECUTABLE)
|
||||
endif(NOT PYTHONINTERP_FOUND)
|
||||
|
||||
endif(PYTHON_EXECUTABLE)
|
||||
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
set(QA_PYTHON_EXECUTABLE "/usr/bin/python")
|
||||
else (CMAKE_CROSSCOMPILING)
|
||||
set(QA_PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
|
||||
endif(CMAKE_CROSSCOMPILING)
|
||||
|
||||
#make the path to the executable appear in the cmake gui
|
||||
set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter")
|
||||
set(QA_PYTHON_EXECUTABLE ${QA_PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter for QA tests")
|
||||
|
||||
#make sure we can use -B with python (introduced in 2.6)
|
||||
if(PYTHON_EXECUTABLE)
|
||||
execute_process(
|
||||
COMMAND ${PYTHON_EXECUTABLE} -B -c ""
|
||||
OUTPUT_QUIET ERROR_QUIET
|
||||
RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT
|
||||
)
|
||||
if(PYTHON_HAS_DASH_B_RESULT EQUAL 0)
|
||||
set(PYTHON_DASH_B "-B")
|
||||
endif()
|
||||
endif(PYTHON_EXECUTABLE)
|
||||
|
||||
########################################################################
|
||||
# Check for the existence of a python module:
|
||||
# - desc a string description of the check
|
||||
# - mod the name of the module to import
|
||||
# - cmd an additional command to run
|
||||
# - have the result variable to set
|
||||
########################################################################
|
||||
macro(GR_PYTHON_CHECK_MODULE desc mod cmd have)
|
||||
message(STATUS "")
|
||||
message(STATUS "Python checking for ${desc}")
|
||||
execute_process(
|
||||
COMMAND ${PYTHON_EXECUTABLE} -c "
|
||||
#########################################
|
||||
try:
|
||||
import ${mod}
|
||||
assert ${cmd}
|
||||
except ImportError, AssertionError: exit(-1)
|
||||
except: pass
|
||||
#########################################"
|
||||
RESULT_VARIABLE ${have}
|
||||
)
|
||||
if(${have} EQUAL 0)
|
||||
message(STATUS "Python checking for ${desc} - found")
|
||||
set(${have} TRUE)
|
||||
else(${have} EQUAL 0)
|
||||
message(STATUS "Python checking for ${desc} - not found")
|
||||
set(${have} FALSE)
|
||||
endif(${have} EQUAL 0)
|
||||
endmacro(GR_PYTHON_CHECK_MODULE)
|
||||
|
||||
########################################################################
|
||||
# Sets the python installation directory GR_PYTHON_DIR
|
||||
########################################################################
|
||||
if(NOT DEFINED GR_PYTHON_DIR)
|
||||
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "
|
||||
from distutils import sysconfig
|
||||
print sysconfig.get_python_lib(plat_specific=True, prefix='')
|
||||
" OUTPUT_VARIABLE GR_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
endif()
|
||||
file(TO_CMAKE_PATH ${GR_PYTHON_DIR} GR_PYTHON_DIR)
|
||||
|
||||
########################################################################
|
||||
# Create an always-built target with a unique name
|
||||
# Usage: GR_UNIQUE_TARGET(<description> <dependencies list>)
|
||||
########################################################################
|
||||
function(GR_UNIQUE_TARGET desc)
|
||||
file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
|
||||
unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5]
|
||||
print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))"
|
||||
OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
add_custom_target(${_target} ALL DEPENDS ${ARGN})
|
||||
endfunction(GR_UNIQUE_TARGET)
|
||||
|
||||
########################################################################
|
||||
# Install python sources (also builds and installs byte-compiled python)
|
||||
########################################################################
|
||||
function(GR_PYTHON_INSTALL)
|
||||
include(CMakeParseArgumentsCopy)
|
||||
CMAKE_PARSE_ARGUMENTS(GR_PYTHON_INSTALL "" "DESTINATION;COMPONENT" "FILES;PROGRAMS" ${ARGN})
|
||||
|
||||
####################################################################
|
||||
if(GR_PYTHON_INSTALL_FILES)
|
||||
####################################################################
|
||||
install(${ARGN}) #installs regular python files
|
||||
|
||||
#create a list of all generated files
|
||||
unset(pysrcfiles)
|
||||
unset(pycfiles)
|
||||
unset(pyofiles)
|
||||
foreach(pyfile ${GR_PYTHON_INSTALL_FILES})
|
||||
get_filename_component(pyfile ${pyfile} ABSOLUTE)
|
||||
list(APPEND pysrcfiles ${pyfile})
|
||||
|
||||
#determine if this file is in the source or binary directory
|
||||
file(RELATIVE_PATH source_rel_path ${CMAKE_CURRENT_SOURCE_DIR} ${pyfile})
|
||||
string(LENGTH "${source_rel_path}" source_rel_path_len)
|
||||
file(RELATIVE_PATH binary_rel_path ${CMAKE_CURRENT_BINARY_DIR} ${pyfile})
|
||||
string(LENGTH "${binary_rel_path}" binary_rel_path_len)
|
||||
|
||||
#and set the generated path appropriately
|
||||
if(${source_rel_path_len} GREATER ${binary_rel_path_len})
|
||||
set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${binary_rel_path})
|
||||
else()
|
||||
set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${source_rel_path})
|
||||
endif()
|
||||
list(APPEND pycfiles ${pygenfile}c)
|
||||
list(APPEND pyofiles ${pygenfile}o)
|
||||
|
||||
#ensure generation path exists
|
||||
get_filename_component(pygen_path ${pygenfile} PATH)
|
||||
file(MAKE_DIRECTORY ${pygen_path})
|
||||
|
||||
endforeach(pyfile)
|
||||
|
||||
#the command to generate the pyc files
|
||||
add_custom_command(
|
||||
DEPENDS ${pysrcfiles} OUTPUT ${pycfiles}
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pycfiles}
|
||||
)
|
||||
|
||||
#the command to generate the pyo files
|
||||
add_custom_command(
|
||||
DEPENDS ${pysrcfiles} OUTPUT ${pyofiles}
|
||||
COMMAND ${PYTHON_EXECUTABLE} -O ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pyofiles}
|
||||
)
|
||||
|
||||
#create install rule and add generated files to target list
|
||||
set(python_install_gen_targets ${pycfiles} ${pyofiles})
|
||||
install(FILES ${python_install_gen_targets}
|
||||
DESTINATION ${GR_PYTHON_INSTALL_DESTINATION}
|
||||
COMPONENT ${GR_PYTHON_INSTALL_COMPONENT}
|
||||
)
|
||||
|
||||
|
||||
####################################################################
|
||||
elseif(GR_PYTHON_INSTALL_PROGRAMS)
|
||||
####################################################################
|
||||
file(TO_NATIVE_PATH ${PYTHON_EXECUTABLE} pyexe_native)
|
||||
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
set(pyexe_native "/usr/bin/env python")
|
||||
endif()
|
||||
|
||||
foreach(pyfile ${GR_PYTHON_INSTALL_PROGRAMS})
|
||||
get_filename_component(pyfile_name ${pyfile} NAME)
|
||||
get_filename_component(pyfile ${pyfile} ABSOLUTE)
|
||||
string(REPLACE "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" pyexefile "${pyfile}.exe")
|
||||
list(APPEND python_install_gen_targets ${pyexefile})
|
||||
|
||||
get_filename_component(pyexefile_path ${pyexefile} PATH)
|
||||
file(MAKE_DIRECTORY ${pyexefile_path})
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${pyexefile} DEPENDS ${pyfile}
|
||||
COMMAND ${PYTHON_EXECUTABLE} -c
|
||||
"open('${pyexefile}','w').write('\#!${pyexe_native}\\n'+open('${pyfile}').read())"
|
||||
COMMENT "Shebangin ${pyfile_name}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
#on windows, python files need an extension to execute
|
||||
get_filename_component(pyfile_ext ${pyfile} EXT)
|
||||
if(WIN32 AND NOT pyfile_ext)
|
||||
set(pyfile_name "${pyfile_name}.py")
|
||||
endif()
|
||||
|
||||
install(PROGRAMS ${pyexefile} RENAME ${pyfile_name}
|
||||
DESTINATION ${GR_PYTHON_INSTALL_DESTINATION}
|
||||
COMPONENT ${GR_PYTHON_INSTALL_COMPONENT}
|
||||
)
|
||||
endforeach(pyfile)
|
||||
|
||||
endif()
|
||||
|
||||
GR_UNIQUE_TARGET("pygen" ${python_install_gen_targets})
|
||||
|
||||
endfunction(GR_PYTHON_INSTALL)
|
||||
|
||||
########################################################################
|
||||
# Write the python helper script that generates byte code files
|
||||
########################################################################
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/python_compile_helper.py "
|
||||
import sys, py_compile
|
||||
files = sys.argv[1:]
|
||||
srcs, gens = files[:len(files)/2], files[len(files)/2:]
|
||||
for src, gen in zip(srcs, gens):
|
||||
py_compile.compile(file=src, cfile=gen, doraise=True)
|
||||
")
|
|
@ -1,248 +0,0 @@
|
|||
# Copyright 2010-2011 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
#
|
||||
# GNU Radio 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
if(DEFINED __INCLUDED_GR_SWIG_CMAKE)
|
||||
return()
|
||||
endif()
|
||||
set(__INCLUDED_GR_SWIG_CMAKE TRUE)
|
||||
|
||||
include(GrPython)
|
||||
|
||||
########################################################################
|
||||
# Builds a swig documentation file to be generated into python docstrings
|
||||
# Usage: GR_SWIG_MAKE_DOCS(output_file input_path input_path....)
|
||||
#
|
||||
# Set the following variable to specify extra dependent targets:
|
||||
# - GR_SWIG_DOCS_SOURCE_DEPS
|
||||
# - GR_SWIG_DOCS_TARGET_DEPS
|
||||
########################################################################
|
||||
function(GR_SWIG_MAKE_DOCS output_file)
|
||||
if(ENABLE_DOXYGEN)
|
||||
|
||||
#setup the input files variable list, quote formated
|
||||
set(input_files)
|
||||
unset(INPUT_PATHS)
|
||||
foreach(input_path ${ARGN})
|
||||
if (IS_DIRECTORY ${input_path}) #when input path is a directory
|
||||
file(GLOB input_path_h_files ${input_path}/*.h)
|
||||
else() #otherwise its just a file, no glob
|
||||
set(input_path_h_files ${input_path})
|
||||
endif()
|
||||
list(APPEND input_files ${input_path_h_files})
|
||||
set(INPUT_PATHS "${INPUT_PATHS} \"${input_path}\"")
|
||||
endforeach(input_path)
|
||||
|
||||
#determine the output directory
|
||||
get_filename_component(name ${output_file} NAME_WE)
|
||||
get_filename_component(OUTPUT_DIRECTORY ${output_file} PATH)
|
||||
set(OUTPUT_DIRECTORY ${OUTPUT_DIRECTORY}/${name}_swig_docs)
|
||||
make_directory(${OUTPUT_DIRECTORY})
|
||||
|
||||
#generate the Doxyfile used by doxygen
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.swig_doc.in
|
||||
${OUTPUT_DIRECTORY}/Doxyfile
|
||||
@ONLY)
|
||||
|
||||
#Create a dummy custom command that depends on other targets
|
||||
include(GrMiscUtils)
|
||||
GR_GEN_TARGET_DEPS(_${name}_tag tag_deps ${GR_SWIG_DOCS_TARGET_DEPS})
|
||||
|
||||
#call doxygen on the Doxyfile + input headers
|
||||
add_custom_command(
|
||||
OUTPUT ${OUTPUT_DIRECTORY}/xml/index.xml
|
||||
DEPENDS ${input_files} ${GR_SWIG_DOCS_SOURCE_DEPS} ${tag_deps}
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${OUTPUT_DIRECTORY}/Doxyfile
|
||||
COMMENT "Generating doxygen xml for ${name} docs"
|
||||
)
|
||||
|
||||
#call the swig_doc script on the xml files
|
||||
add_custom_command(
|
||||
OUTPUT ${output_file}
|
||||
DEPENDS ${input_files} ${stamp-file} ${OUTPUT_DIRECTORY}/xml/index.xml
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
|
||||
${CMAKE_SOURCE_DIR}/docs/doxygen/swig_doc.py
|
||||
${OUTPUT_DIRECTORY}/xml
|
||||
${output_file}
|
||||
COMMENT "Generating python docstrings for ${name}"
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/doxygen
|
||||
)
|
||||
|
||||
else(ENABLE_DOXYGEN)
|
||||
file(WRITE ${output_file} "\n") #no doxygen -> empty file
|
||||
endif(ENABLE_DOXYGEN)
|
||||
endfunction(GR_SWIG_MAKE_DOCS)
|
||||
|
||||
########################################################################
|
||||
# Build a swig target for the common gnuradio use case. Usage:
|
||||
# GR_SWIG_MAKE(target ifile ifile ifile...)
|
||||
#
|
||||
# Set the following variables before calling:
|
||||
# - GR_SWIG_FLAGS
|
||||
# - GR_SWIG_INCLUDE_DIRS
|
||||
# - GR_SWIG_LIBRARIES
|
||||
# - GR_SWIG_SOURCE_DEPS
|
||||
# - GR_SWIG_TARGET_DEPS
|
||||
# - GR_SWIG_DOC_FILE
|
||||
# - GR_SWIG_DOC_DIRS
|
||||
########################################################################
|
||||
macro(GR_SWIG_MAKE name)
|
||||
set(ifiles ${ARGN})
|
||||
|
||||
# Shimming this in here to take care of a SWIG bug with handling
|
||||
# vector<size_t> and vector<unsigned int> (on 32-bit machines) and
|
||||
# vector<long unsigned int> (on 64-bit machines). Use this to test
|
||||
# the size of size_t, then set SIZE_T_32 if it's a 32-bit machine
|
||||
# or not if it's 64-bit. The logic in gr_type.i handles the rest.
|
||||
INCLUDE (CheckTypeSize)
|
||||
CHECK_TYPE_SIZE("size_t" SIZEOF_SIZE_T)
|
||||
CHECK_TYPE_SIZE("unsigned int" SIZEOF_UINT)
|
||||
if(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT})
|
||||
list(APPEND GR_SWIG_FLAGS -DSIZE_T_32)
|
||||
endif(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT})
|
||||
|
||||
#do swig doc generation if specified
|
||||
if (GR_SWIG_DOC_FILE)
|
||||
set(GR_SWIG_DOCS_SOURCE_DEPS ${GR_SWIG_SOURCE_DEPS})
|
||||
list(APPEND GR_SWIG_DOCS_TARGET_DEPS ${GR_SWIG_TARGET_DEPS})
|
||||
GR_SWIG_MAKE_DOCS(${GR_SWIG_DOC_FILE} ${GR_SWIG_DOC_DIRS})
|
||||
add_custom_target(${name}_swig_doc DEPENDS ${GR_SWIG_DOC_FILE})
|
||||
list(APPEND GR_SWIG_TARGET_DEPS ${name}_swig_doc ${GR_RUNTIME_SWIG_DOC_FILE})
|
||||
endif()
|
||||
|
||||
#append additional include directories
|
||||
find_package(PythonLibs 2)
|
||||
list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_PATH}) #deprecated name (now dirs)
|
||||
list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS})
|
||||
|
||||
#prepend local swig directories
|
||||
list(INSERT GR_SWIG_INCLUDE_DIRS 0 ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
list(INSERT GR_SWIG_INCLUDE_DIRS 0 ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
#determine include dependencies for swig file
|
||||
execute_process(
|
||||
COMMAND ${PYTHON_EXECUTABLE}
|
||||
${CMAKE_BINARY_DIR}/get_swig_deps.py
|
||||
"${ifiles}" "${GR_SWIG_INCLUDE_DIRS}"
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
OUTPUT_VARIABLE SWIG_MODULE_${name}_EXTRA_DEPS
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
#Create a dummy custom command that depends on other targets
|
||||
include(GrMiscUtils)
|
||||
GR_GEN_TARGET_DEPS(_${name}_swig_tag tag_deps ${GR_SWIG_TARGET_DEPS})
|
||||
set(tag_file ${CMAKE_CURRENT_BINARY_DIR}/${name}.tag)
|
||||
add_custom_command(
|
||||
OUTPUT ${tag_file}
|
||||
DEPENDS ${GR_SWIG_SOURCE_DEPS} ${tag_deps}
|
||||
COMMAND ${CMAKE_COMMAND} -E touch ${tag_file}
|
||||
)
|
||||
|
||||
#append the specified include directories
|
||||
include_directories(${GR_SWIG_INCLUDE_DIRS})
|
||||
list(APPEND SWIG_MODULE_${name}_EXTRA_DEPS ${tag_file})
|
||||
|
||||
#setup the swig flags with flags and include directories
|
||||
set(CMAKE_SWIG_FLAGS -fvirtual -modern -keyword -w511 -module ${name} ${GR_SWIG_FLAGS})
|
||||
foreach(dir ${GR_SWIG_INCLUDE_DIRS})
|
||||
list(APPEND CMAKE_SWIG_FLAGS "-I${dir}")
|
||||
endforeach(dir)
|
||||
|
||||
#set the C++ property on the swig .i file so it builds
|
||||
set_source_files_properties(${ifiles} PROPERTIES CPLUSPLUS ON)
|
||||
|
||||
#setup the actual swig library target to be built
|
||||
include(UseSWIG)
|
||||
SWIG_ADD_MODULE(${name} python ${ifiles})
|
||||
SWIG_LINK_LIBRARIES(${name} ${PYTHON_LIBRARIES} ${GR_SWIG_LIBRARIES})
|
||||
|
||||
endmacro(GR_SWIG_MAKE)
|
||||
|
||||
########################################################################
|
||||
# Install swig targets generated by GR_SWIG_MAKE. Usage:
|
||||
# GR_SWIG_INSTALL(
|
||||
# TARGETS target target target...
|
||||
# [DESTINATION destination]
|
||||
# [COMPONENT component]
|
||||
# )
|
||||
########################################################################
|
||||
macro(GR_SWIG_INSTALL)
|
||||
|
||||
include(CMakeParseArgumentsCopy)
|
||||
CMAKE_PARSE_ARGUMENTS(GR_SWIG_INSTALL "" "DESTINATION;COMPONENT" "TARGETS" ${ARGN})
|
||||
|
||||
foreach(name ${GR_SWIG_INSTALL_TARGETS})
|
||||
install(TARGETS ${SWIG_MODULE_${name}_REAL_NAME}
|
||||
DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
|
||||
COMPONENT ${GR_SWIG_INSTALL_COMPONENT}
|
||||
)
|
||||
|
||||
include(GrPython)
|
||||
GR_PYTHON_INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}.py
|
||||
DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
|
||||
COMPONENT ${GR_SWIG_INSTALL_COMPONENT}
|
||||
)
|
||||
|
||||
GR_LIBTOOL(
|
||||
TARGET ${SWIG_MODULE_${name}_REAL_NAME}
|
||||
DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
|
||||
)
|
||||
|
||||
endforeach(name)
|
||||
|
||||
endmacro(GR_SWIG_INSTALL)
|
||||
|
||||
########################################################################
|
||||
# Generate a python file that can determine swig dependencies.
|
||||
# Used by the make macro above to determine extra dependencies.
|
||||
# When you build C++, CMake figures out the header dependencies.
|
||||
# This code essentially performs that logic for swig includes.
|
||||
########################################################################
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/get_swig_deps.py "
|
||||
|
||||
import os, sys, re
|
||||
|
||||
i_include_matcher = re.compile('%(include|import)\\s*[<|\"](.*)[>|\"]')
|
||||
h_include_matcher = re.compile('#(include)\\s*[<|\"](.*)[>|\"]')
|
||||
include_dirs = sys.argv[2].split(';')
|
||||
|
||||
def get_swig_incs(file_path):
|
||||
if file_path.endswith('.i'): matcher = i_include_matcher
|
||||
else: matcher = h_include_matcher
|
||||
file_contents = open(file_path, 'r').read()
|
||||
return matcher.findall(file_contents, re.MULTILINE)
|
||||
|
||||
def get_swig_deps(file_path, level):
|
||||
deps = [file_path]
|
||||
if level == 0: return deps
|
||||
for keyword, inc_file in get_swig_incs(file_path):
|
||||
for inc_dir in include_dirs:
|
||||
inc_path = os.path.join(inc_dir, inc_file)
|
||||
if not os.path.exists(inc_path): continue
|
||||
deps.extend(get_swig_deps(inc_path, level-1))
|
||||
break #found, we dont search in lower prio inc dirs
|
||||
return deps
|
||||
|
||||
if __name__ == '__main__':
|
||||
ifiles = sys.argv[1].split(';')
|
||||
deps = sum([get_swig_deps(ifile, 3) for ifile in ifiles], [])
|
||||
#sys.stderr.write(';'.join(set(deps)) + '\\n\\n')
|
||||
print(';'.join(set(deps)))
|
||||
")
|
|
@ -1,143 +0,0 @@
|
|||
# Copyright 2010-2011 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
#
|
||||
# GNU Radio 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
if(DEFINED __INCLUDED_GR_TEST_CMAKE)
|
||||
return()
|
||||
endif()
|
||||
set(__INCLUDED_GR_TEST_CMAKE TRUE)
|
||||
|
||||
########################################################################
|
||||
# Add a unit test and setup the environment for a unit test.
|
||||
# Takes the same arguments as the ADD_TEST function.
|
||||
#
|
||||
# Before calling set the following variables:
|
||||
# GR_TEST_TARGET_DEPS - built targets for the library path
|
||||
# GR_TEST_LIBRARY_DIRS - directories for the library path
|
||||
# GR_TEST_PYTHON_DIRS - directories for the python path
|
||||
# GR_TEST_ENVIRONS - other environment key/value pairs
|
||||
########################################################################
|
||||
function(GR_ADD_TEST test_name)
|
||||
|
||||
#Ensure that the build exe also appears in the PATH.
|
||||
list(APPEND GR_TEST_TARGET_DEPS ${ARGN})
|
||||
|
||||
#In the land of windows, all libraries must be in the PATH.
|
||||
#Since the dependent libraries are not yet installed,
|
||||
#we must manually set them in the PATH to run tests.
|
||||
#The following appends the path of a target dependency.
|
||||
foreach(target ${GR_TEST_TARGET_DEPS})
|
||||
get_target_property(location ${target} LOCATION)
|
||||
if(location)
|
||||
get_filename_component(path ${location} PATH)
|
||||
string(REGEX REPLACE "\\$\\(.*\\)" ${CMAKE_BUILD_TYPE} path ${path})
|
||||
list(APPEND GR_TEST_LIBRARY_DIRS ${path})
|
||||
endif(location)
|
||||
endforeach(target)
|
||||
|
||||
if(WIN32)
|
||||
#SWIG generates the python library files into a subdirectory.
|
||||
#Therefore, we must append this subdirectory into PYTHONPATH.
|
||||
#Only do this for the python directories matching the following:
|
||||
foreach(pydir ${GR_TEST_PYTHON_DIRS})
|
||||
get_filename_component(name ${pydir} NAME)
|
||||
if(name MATCHES "^(swig|lib|src)$")
|
||||
list(APPEND GR_TEST_PYTHON_DIRS ${pydir}/${CMAKE_BUILD_TYPE})
|
||||
endif()
|
||||
endforeach(pydir)
|
||||
endif(WIN32)
|
||||
|
||||
file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} srcdir)
|
||||
file(TO_NATIVE_PATH "${GR_TEST_LIBRARY_DIRS}" libpath) #ok to use on dir list?
|
||||
file(TO_NATIVE_PATH "${GR_TEST_PYTHON_DIRS}" pypath) #ok to use on dir list?
|
||||
|
||||
set(environs "VOLK_GENERIC=1" "GR_DONT_LOAD_PREFS=1" "srcdir=${srcdir}")
|
||||
list(APPEND environs ${GR_TEST_ENVIRONS})
|
||||
|
||||
#http://www.cmake.org/pipermail/cmake/2009-May/029464.html
|
||||
#Replaced this add test + set environs code with the shell script generation.
|
||||
#Its nicer to be able to manually run the shell script to diagnose problems.
|
||||
#ADD_TEST(${ARGV})
|
||||
#SET_TESTS_PROPERTIES(${test_name} PROPERTIES ENVIRONMENT "${environs}")
|
||||
|
||||
if(UNIX)
|
||||
set(LD_PATH_VAR "LD_LIBRARY_PATH")
|
||||
if(APPLE)
|
||||
set(LD_PATH_VAR "DYLD_LIBRARY_PATH")
|
||||
endif()
|
||||
|
||||
set(binpath "${CMAKE_CURRENT_BINARY_DIR}:$PATH")
|
||||
list(APPEND libpath "$${LD_PATH_VAR}")
|
||||
list(APPEND pypath "$PYTHONPATH")
|
||||
|
||||
#replace list separator with the path separator
|
||||
string(REPLACE ";" ":" libpath "${libpath}")
|
||||
string(REPLACE ";" ":" pypath "${pypath}")
|
||||
list(APPEND environs "PATH=${binpath}" "${LD_PATH_VAR}=${libpath}" "PYTHONPATH=${pypath}")
|
||||
|
||||
#generate a bat file that sets the environment and runs the test
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
set(SHELL "/bin/sh")
|
||||
else(CMAKE_CROSSCOMPILING)
|
||||
find_program(SHELL sh)
|
||||
endif(CMAKE_CROSSCOMPILING)
|
||||
set(sh_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.sh)
|
||||
file(WRITE ${sh_file} "#!${SHELL}\n")
|
||||
#each line sets an environment variable
|
||||
foreach(environ ${environs})
|
||||
file(APPEND ${sh_file} "export ${environ}\n")
|
||||
endforeach(environ)
|
||||
#load the command to run with its arguments
|
||||
foreach(arg ${ARGN})
|
||||
file(APPEND ${sh_file} "${arg} ")
|
||||
endforeach(arg)
|
||||
file(APPEND ${sh_file} "\n")
|
||||
|
||||
#make the shell file executable
|
||||
execute_process(COMMAND chmod +x ${sh_file})
|
||||
|
||||
add_test(${test_name} ${SHELL} ${sh_file})
|
||||
|
||||
endif(UNIX)
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND libpath ${DLL_PATHS} "%PATH%")
|
||||
list(APPEND pypath "%PYTHONPATH%")
|
||||
|
||||
#replace list separator with the path separator (escaped)
|
||||
string(REPLACE ";" "\\;" libpath "${libpath}")
|
||||
string(REPLACE ";" "\\;" pypath "${pypath}")
|
||||
list(APPEND environs "PATH=${libpath}" "PYTHONPATH=${pypath}")
|
||||
|
||||
#generate a bat file that sets the environment and runs the test
|
||||
set(bat_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.bat)
|
||||
file(WRITE ${bat_file} "@echo off\n")
|
||||
#each line sets an environment variable
|
||||
foreach(environ ${environs})
|
||||
file(APPEND ${bat_file} "SET ${environ}\n")
|
||||
endforeach(environ)
|
||||
#load the command to run with its arguments
|
||||
foreach(arg ${ARGN})
|
||||
file(APPEND ${bat_file} "${arg} ")
|
||||
endforeach(arg)
|
||||
file(APPEND ${bat_file} "\n")
|
||||
|
||||
add_test(${test_name} ${bat_file})
|
||||
endif(WIN32)
|
||||
|
||||
endfunction(GR_ADD_TEST)
|
|
@ -1,82 +0,0 @@
|
|||
# Copyright 2011,2013 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
#
|
||||
# GNU Radio 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
if(DEFINED __INCLUDED_GR_VERSION_CMAKE)
|
||||
return()
|
||||
endif()
|
||||
set(__INCLUDED_GR_VERSION_CMAKE TRUE)
|
||||
|
||||
#eventually, replace version.sh and fill in the variables below
|
||||
set(MAJOR_VERSION ${VERSION_INFO_MAJOR_VERSION})
|
||||
set(API_COMPAT ${VERSION_INFO_API_COMPAT})
|
||||
set(MINOR_VERSION ${VERSION_INFO_MINOR_VERSION})
|
||||
set(MAINT_VERSION ${VERSION_INFO_MAINT_VERSION})
|
||||
|
||||
########################################################################
|
||||
# Extract the version string from git describe.
|
||||
########################################################################
|
||||
find_package(Git)
|
||||
|
||||
if(GIT_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/.git)
|
||||
message(STATUS "Extracting version information from git describe...")
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} describe --always --abbrev=8 --long
|
||||
OUTPUT_VARIABLE GIT_DESCRIBE OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
else()
|
||||
set(GIT_DESCRIBE "v${MAJOR_VERSION}.${API_COMPAT}.x-xxx-xunknown")
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
# Use the logic below to set the version constants
|
||||
########################################################################
|
||||
if("${MINOR_VERSION}" STREQUAL "git")
|
||||
# VERSION: 3.3git-xxx-gxxxxxxxx
|
||||
# DOCVER: 3.3git
|
||||
# LIBVER: 3.3git
|
||||
set(VERSION "${GIT_DESCRIBE}")
|
||||
set(DOCVER "${MAJOR_VERSION}.${API_COMPAT}${MINOR_VERSION}")
|
||||
set(LIBVER "${MAJOR_VERSION}.${API_COMPAT}${MINOR_VERSION}")
|
||||
set(RC_MINOR_VERSION "0")
|
||||
set(RC_MAINT_VERSION "0")
|
||||
elseif("${MAINT_VERSION}" STREQUAL "git")
|
||||
# VERSION: 3.3.1git-xxx-gxxxxxxxx
|
||||
# DOCVER: 3.3.1git
|
||||
# LIBVER: 3.3.1git
|
||||
set(VERSION "${GIT_DESCRIBE}")
|
||||
set(DOCVER "${MAJOR_VERSION}.${API_COMPAT}.${MINOR_VERSION}${MAINT_VERSION}")
|
||||
set(LIBVER "${MAJOR_VERSION}.${API_COMPAT}.${MINOR_VERSION}${MAINT_VERSION}")
|
||||
math(EXPR RC_MINOR_VERSION "${MINOR_VERSION} - 1")
|
||||
set(RC_MAINT_VERSION "0")
|
||||
else()
|
||||
# This is a numbered release.
|
||||
# VERSION: 3.3.1{.x}
|
||||
# DOCVER: 3.3.1{.x}
|
||||
# LIBVER: 3.3.1{.x}
|
||||
if("${MAINT_VERSION}" STREQUAL "0")
|
||||
set(VERSION "${MAJOR_VERSION}.${API_COMPAT}.${MINOR_VERSION}")
|
||||
else()
|
||||
set(VERSION "${MAJOR_VERSION}.${API_COMPAT}.${MINOR_VERSION}.${MAINT_VERSION}")
|
||||
endif()
|
||||
set(DOCVER "${VERSION}")
|
||||
set(LIBVER "${VERSION}")
|
||||
set(RC_MINOR_VERSION ${MINOR_VERSION})
|
||||
set(RC_MAINT_VERSION ${MAINT_VERSION})
|
||||
endif()
|
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2018 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
#
|
||||
# GNU Radio 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
|
||||
set(target_deps "@TARGET_DEPENDENCIES@")
|
||||
foreach(dep IN LISTS target_deps)
|
||||
find_dependency(${dep})
|
||||
endforeach()
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@TARGET@Targets.cmake")
|
|
@ -1,19 +1,19 @@
|
|||
# Copyright 2011 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file is part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# gr-osmosdr 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio is distributed in the hope that it will be useful,
|
||||
# gr-osmosdr 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# along with gr-osmosdr; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright 2011 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file was generated by gr_modtool, a tool from the GNU Radio framework
|
||||
# This file is a part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,8 @@
|
|||
#
|
||||
# Copyright 2010 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file was generated by gr_modtool, a tool from the GNU Radio framework
|
||||
# This file is a part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -63,8 +64,9 @@ This line is uninformative and is only to test line breaks in the comments.
|
|||
u'Outputs the vital aadvark statistics.'
|
||||
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther
|
||||
from .doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther
|
||||
|
||||
def _test():
|
||||
import os
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#
|
||||
# Copyright 2010 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file was generated by gr_modtool, a tool from the GNU Radio framework
|
||||
# This file is a part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -24,24 +25,26 @@ A base class is created.
|
|||
Classes based upon this are used to make more user-friendly interfaces
|
||||
to the doxygen xml docs than the generated classes provide.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import pdb
|
||||
|
||||
from xml.parsers.expat import ExpatError
|
||||
|
||||
from generated import compound
|
||||
from .generated import compound
|
||||
|
||||
|
||||
class Base(object):
|
||||
|
||||
class Duplicate(StandardError):
|
||||
class Duplicate(Exception):
|
||||
pass
|
||||
|
||||
class NoSuchMember(StandardError):
|
||||
class NoSuchMember(Exception):
|
||||
pass
|
||||
|
||||
class ParsingError(StandardError):
|
||||
class ParsingError(Exception):
|
||||
pass
|
||||
|
||||
def __init__(self, parse_data, top=None):
|
||||
|
@ -94,7 +97,7 @@ class Base(object):
|
|||
for cls in self.mem_classes:
|
||||
if cls.can_parse(mem):
|
||||
return cls
|
||||
raise StandardError(("Did not find a class for object '%s'." \
|
||||
raise Exception(("Did not find a class for object '%s'." \
|
||||
% (mem.get_name())))
|
||||
|
||||
def convert_mem(self, mem):
|
||||
|
@ -102,11 +105,11 @@ class Base(object):
|
|||
cls = self.get_cls(mem)
|
||||
converted = cls.from_parse_data(mem, self.top)
|
||||
if converted is None:
|
||||
raise StandardError('No class matched this object.')
|
||||
raise Exception('No class matched this object.')
|
||||
self.add_ref(converted)
|
||||
return converted
|
||||
except StandardError, e:
|
||||
print e
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
@classmethod
|
||||
def includes(cls, inst):
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#
|
||||
# Copyright 2010 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file was generated by gr_modtool, a tool from the GNU Radio framework
|
||||
# This file is a part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -22,12 +23,14 @@
|
|||
Classes providing more user-friendly interfaces to the doxygen xml
|
||||
docs than the generated classes provide.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
|
||||
from generated import index
|
||||
from base import Base
|
||||
from text import description
|
||||
from .generated import index
|
||||
from .base import Base
|
||||
from .text import description
|
||||
|
||||
class DoxyIndex(Base):
|
||||
"""
|
||||
|
@ -43,13 +46,16 @@ class DoxyIndex(Base):
|
|||
self._root = index.parse(os.path.join(self._xml_path, 'index.xml'))
|
||||
for mem in self._root.compound:
|
||||
converted = self.convert_mem(mem)
|
||||
# For files we want the contents to be accessible directly
|
||||
# from the parent rather than having to go through the file
|
||||
# object.
|
||||
# For files and namespaces we want the contents to be
|
||||
# accessible directly from the parent rather than having
|
||||
# to go through the file object.
|
||||
if self.get_cls(mem) == DoxyFile:
|
||||
if mem.name.endswith('.h'):
|
||||
self._members += converted.members()
|
||||
self._members.append(converted)
|
||||
elif self.get_cls(mem) == DoxyNamespace:
|
||||
self._members += converted.members()
|
||||
self._members.append(converted)
|
||||
else:
|
||||
self._members.append(converted)
|
||||
|
||||
|
@ -80,13 +86,29 @@ class DoxyCompMem(Base):
|
|||
self._data['brief_description'] = bd
|
||||
self._data['detailed_description'] = dd
|
||||
|
||||
def set_parameters(self, data):
|
||||
vs = [ddc.value for ddc in data.detaileddescription.content_]
|
||||
pls = []
|
||||
for v in vs:
|
||||
if hasattr(v, 'parameterlist'):
|
||||
pls += v.parameterlist
|
||||
pis = []
|
||||
for pl in pls:
|
||||
pis += pl.parameteritem
|
||||
dpis = []
|
||||
for pi in pis:
|
||||
dpi = DoxyParameterItem(pi)
|
||||
dpi._parse()
|
||||
dpis.append(dpi)
|
||||
self._data['params'] = dpis
|
||||
|
||||
|
||||
class DoxyCompound(DoxyCompMem):
|
||||
pass
|
||||
|
||||
class DoxyMember(DoxyCompMem):
|
||||
pass
|
||||
|
||||
|
||||
class DoxyFunction(DoxyMember):
|
||||
|
||||
__module__ = "gnuradio.utils.doxyxml"
|
||||
|
@ -98,10 +120,13 @@ class DoxyFunction(DoxyMember):
|
|||
return
|
||||
super(DoxyFunction, self)._parse()
|
||||
self.set_descriptions(self._parse_data)
|
||||
self._data['params'] = []
|
||||
prms = self._parse_data.param
|
||||
for prm in prms:
|
||||
self._data['params'].append(DoxyParam(prm))
|
||||
self.set_parameters(self._parse_data)
|
||||
if not self._data['params']:
|
||||
# If the params weren't set by a comment then just grab the names.
|
||||
self._data['params'] = []
|
||||
prms = self._parse_data.param
|
||||
for prm in prms:
|
||||
self._data['params'].append(DoxyParam(prm))
|
||||
|
||||
brief_description = property(lambda self: self.data()['brief_description'])
|
||||
detailed_description = property(lambda self: self.data()['detailed_description'])
|
||||
|
@ -121,9 +146,39 @@ class DoxyParam(DoxyMember):
|
|||
self.set_descriptions(self._parse_data)
|
||||
self._data['declname'] = self._parse_data.declname
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
descriptions = []
|
||||
if self.brief_description:
|
||||
descriptions.append(self.brief_description)
|
||||
if self.detailed_description:
|
||||
descriptions.append(self.detailed_description)
|
||||
return '\n\n'.join(descriptions)
|
||||
|
||||
brief_description = property(lambda self: self.data()['brief_description'])
|
||||
detailed_description = property(lambda self: self.data()['detailed_description'])
|
||||
declname = property(lambda self: self.data()['declname'])
|
||||
name = property(lambda self: self.data()['declname'])
|
||||
|
||||
class DoxyParameterItem(DoxyMember):
|
||||
"""A different representation of a parameter in Doxygen."""
|
||||
|
||||
def _parse(self):
|
||||
if self._parsed:
|
||||
return
|
||||
super(DoxyParameterItem, self)._parse()
|
||||
names = []
|
||||
for nl in self._parse_data.parameternamelist:
|
||||
for pn in nl.parametername:
|
||||
names.append(description(pn))
|
||||
# Just take first name
|
||||
self._data['name'] = names[0]
|
||||
# Get description
|
||||
pd = description(self._parse_data.get_parameterdescription())
|
||||
self._data['description'] = pd
|
||||
|
||||
description = property(lambda self: self.data()['description'])
|
||||
name = property(lambda self: self.data()['name'])
|
||||
|
||||
|
||||
class DoxyClass(DoxyCompound):
|
||||
|
||||
|
@ -139,12 +194,14 @@ class DoxyClass(DoxyCompound):
|
|||
if self._error:
|
||||
return
|
||||
self.set_descriptions(self._retrieved_data.compounddef)
|
||||
self.set_parameters(self._retrieved_data.compounddef)
|
||||
# Sectiondef.kind tells about whether private or public.
|
||||
# We just ignore this for now.
|
||||
self.process_memberdefs()
|
||||
|
||||
brief_description = property(lambda self: self.data()['brief_description'])
|
||||
detailed_description = property(lambda self: self.data()['detailed_description'])
|
||||
params = property(lambda self: self.data()['params'])
|
||||
|
||||
Base.mem_classes.append(DoxyClass)
|
||||
|
||||
|
@ -177,6 +234,16 @@ class DoxyNamespace(DoxyCompound):
|
|||
|
||||
kind = 'namespace'
|
||||
|
||||
def _parse(self):
|
||||
if self._parsed:
|
||||
return
|
||||
super(DoxyNamespace, self)._parse()
|
||||
self.retrieve_data()
|
||||
self.set_descriptions(self._retrieved_data.compounddef)
|
||||
if self._error:
|
||||
return
|
||||
self.process_memberdefs()
|
||||
|
||||
Base.mem_classes.append(DoxyNamespace)
|
||||
|
||||
|
||||
|
@ -227,11 +294,11 @@ class DoxyOther(Base):
|
|||
|
||||
__module__ = "gnuradio.utils.doxyxml"
|
||||
|
||||
kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum', 'dir', 'page'])
|
||||
kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum',
|
||||
'dir', 'page', 'signal', 'slot', 'property'])
|
||||
|
||||
@classmethod
|
||||
def can_parse(cls, obj):
|
||||
return obj.kind in cls.kinds
|
||||
|
||||
Base.mem_classes.append(DoxyOther)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,88 +0,0 @@
|
|||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.6.3">
|
||||
<compounddef id="aadvark_8cc" kind="file">
|
||||
<compoundname>aadvark.cc</compoundname>
|
||||
<includes local="no">iostream</includes>
|
||||
<includes refid="aadvark_8cc" local="yes">aadvark.h</includes>
|
||||
<includedby refid="aadvark_8cc" local="yes">aadvark.cc</includedby>
|
||||
<incdepgraph>
|
||||
<node id="0">
|
||||
<label>aadvark.cc</label>
|
||||
<link refid="aadvark.cc"/>
|
||||
<childnode refid="1" relation="include">
|
||||
</childnode>
|
||||
</node>
|
||||
<node id="1">
|
||||
<label>iostream</label>
|
||||
</node>
|
||||
</incdepgraph>
|
||||
<sectiondef kind="func">
|
||||
<memberdef kind="function" id="aadvark_8cc_1acb52858524210ec6dddc3e16d1e52946" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
|
||||
<type>bool</type>
|
||||
<definition>bool aadvarky_enough</definition>
|
||||
<argsstring>(Aadvark aad)</argsstring>
|
||||
<name>aadvarky_enough</name>
|
||||
<param>
|
||||
<type><ref refid="classAadvark" kindref="compound">Aadvark</ref></type>
|
||||
<declname>aad</declname>
|
||||
</param>
|
||||
<briefdescription>
|
||||
</briefdescription>
|
||||
<detaileddescription>
|
||||
</detaileddescription>
|
||||
<inbodydescription>
|
||||
</inbodydescription>
|
||||
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" line="10" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="10" bodyend="15"/>
|
||||
</memberdef>
|
||||
<memberdef kind="function" id="aadvark_8cc_1ae66f6b31b5ad750f1fe042a706a4e3d4" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
|
||||
<type>int</type>
|
||||
<definition>int main</definition>
|
||||
<argsstring>()</argsstring>
|
||||
<name>main</name>
|
||||
<briefdescription>
|
||||
</briefdescription>
|
||||
<detaileddescription>
|
||||
</detaileddescription>
|
||||
<inbodydescription>
|
||||
</inbodydescription>
|
||||
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" line="21" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="21" bodyend="28"/>
|
||||
</memberdef>
|
||||
</sectiondef>
|
||||
<briefdescription>
|
||||
</briefdescription>
|
||||
<detaileddescription>
|
||||
</detaileddescription>
|
||||
<programlisting>
|
||||
<codeline lineno="1"><highlight class="preprocessor">#include<sp/><iostream></highlight><highlight class="normal"></highlight></codeline>
|
||||
<codeline lineno="2"><highlight class="normal"></highlight><highlight class="preprocessor">#include<sp/>"aadvark.h"</highlight><highlight class="normal"></highlight></codeline>
|
||||
<codeline lineno="3"><highlight class="normal"></highlight></codeline>
|
||||
<codeline lineno="4"><highlight class="normal"></highlight><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/><ref refid="classAadvark_1abd061aa5f998002e72080a34f512a059" kindref="member" tooltip="Outputs the vital aadvark statistics.">Aadvark::print</ref>()<sp/>{</highlight></codeline>
|
||||
<codeline lineno="5"><highlight class="normal"><sp/><sp/>std::cout<sp/><<<sp/></highlight><highlight class="stringliteral">"aadvark<sp/>is<sp/>"</highlight><highlight class="normal"><sp/><<<sp/>aadvarkness<sp/><<<sp/></highlight><highlight class="stringliteral">"/10<sp/>aadvarky"</highlight><highlight class="normal"><sp/><<<sp/>std::endl;</highlight></codeline>
|
||||
<codeline lineno="6"><highlight class="normal">}</highlight></codeline>
|
||||
<codeline lineno="7"><highlight class="normal"></highlight></codeline>
|
||||
<codeline lineno="8"><highlight class="normal"><ref refid="classAadvark_1adf1a4b97a641411a74a04ab312484462" kindref="member">Aadvark::Aadvark</ref>(</highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>aaness):<sp/>aadvarkness(aaness)<sp/>{}</highlight></codeline>
|
||||
<codeline lineno="9"><highlight class="normal"></highlight></codeline>
|
||||
<codeline lineno="10"><highlight class="normal"></highlight><highlight class="keywordtype">bool</highlight><highlight class="normal"><sp/>aadvarky_enough(<ref refid="classAadvark" kindref="compound" tooltip="Models the mammal Aadvark.">Aadvark</ref><sp/>aad)<sp/>{</highlight></codeline>
|
||||
<codeline lineno="11"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">if</highlight><highlight class="normal"><sp/>(aad.get_aadvarkness()<sp/>><sp/>6)</highlight></codeline>
|
||||
<codeline lineno="12"><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/></highlight><highlight class="keyword">true</highlight><highlight class="normal">;</highlight></codeline>
|
||||
<codeline lineno="13"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">else</highlight><highlight class="normal"></highlight></codeline>
|
||||
<codeline lineno="14"><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/></highlight><highlight class="keyword">false</highlight><highlight class="normal">;</highlight></codeline>
|
||||
<codeline lineno="15"><highlight class="normal">}</highlight></codeline>
|
||||
<codeline lineno="16"><highlight class="normal"></highlight></codeline>
|
||||
<codeline lineno="17"><highlight class="normal"></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>Aadvark::get_aadvarkness()<sp/>{</highlight></codeline>
|
||||
<codeline lineno="18"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/>aadvarkness;</highlight></codeline>
|
||||
<codeline lineno="19"><highlight class="normal">}</highlight></codeline>
|
||||
<codeline lineno="20"><highlight class="normal"></highlight></codeline>
|
||||
<codeline lineno="21"><highlight class="normal"></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>main()<sp/>{</highlight></codeline>
|
||||
<codeline lineno="22"><highlight class="normal"><sp/><sp/><ref refid="classAadvark" kindref="compound" tooltip="Models the mammal Aadvark.">Aadvark</ref><sp/>arold<sp/>=<sp/><ref refid="classAadvark" kindref="compound" tooltip="Models the mammal Aadvark.">Aadvark</ref>(6);</highlight></codeline>
|
||||
<codeline lineno="23"><highlight class="normal"><sp/><sp/>arold.<ref refid="classAadvark_1abd061aa5f998002e72080a34f512a059" kindref="member" tooltip="Outputs the vital aadvark statistics.">print</ref>();</highlight></codeline>
|
||||
<codeline lineno="24"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">if</highlight><highlight class="normal"><sp/>(aadvarky_enough(arold))</highlight></codeline>
|
||||
<codeline lineno="25"><highlight class="normal"><sp/><sp/><sp/><sp/>std::cout<sp/><<<sp/></highlight><highlight class="stringliteral">"He<sp/>is<sp/>aadvarky<sp/>enough"</highlight><highlight class="normal"><sp/><<<sp/>std::endl;</highlight></codeline>
|
||||
<codeline lineno="26"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">else</highlight><highlight class="normal"></highlight></codeline>
|
||||
<codeline lineno="27"><highlight class="normal"><sp/><sp/><sp/><sp/>std::cout<sp/><<<sp/></highlight><highlight class="stringliteral">"He<sp/>is<sp/>not<sp/>aadvarky<sp/>enough"</highlight><highlight class="normal"><sp/><<<sp/>std::endl;</highlight></codeline>
|
||||
<codeline lineno="28"><highlight class="normal">}</highlight></codeline>
|
||||
<codeline lineno="29"><highlight class="normal"></highlight></codeline>
|
||||
</programlisting>
|
||||
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc"/>
|
||||
</compounddef>
|
||||
</doxygen>
|
|
@ -1,72 +0,0 @@
|
|||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.6.3">
|
||||
<compounddef id="aadvark_8h" kind="file">
|
||||
<compoundname>aadvark.h</compoundname>
|
||||
<includes local="no">iostream</includes>
|
||||
<incdepgraph>
|
||||
<node id="3">
|
||||
<label>aadvark.h</label>
|
||||
<link refid="aadvark.h"/>
|
||||
<childnode refid="4" relation="include">
|
||||
</childnode>
|
||||
</node>
|
||||
<node id="4">
|
||||
<label>iostream</label>
|
||||
</node>
|
||||
</incdepgraph>
|
||||
<innerclass refid="classAadvark" prot="public">Aadvark</innerclass>
|
||||
<sectiondef kind="func">
|
||||
<memberdef kind="function" id="aadvark_8h_1acb52858524210ec6dddc3e16d1e52946" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
|
||||
<type>bool</type>
|
||||
<definition>bool aadvarky_enough</definition>
|
||||
<argsstring>(Aadvark aad)</argsstring>
|
||||
<name>aadvarky_enough</name>
|
||||
<param>
|
||||
<type><ref refid="classAadvark" kindref="compound">Aadvark</ref></type>
|
||||
<declname>aad</declname>
|
||||
</param>
|
||||
<briefdescription>
|
||||
</briefdescription>
|
||||
<detaileddescription>
|
||||
</detaileddescription>
|
||||
<inbodydescription>
|
||||
</inbodydescription>
|
||||
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="21" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="10" bodyend="15"/>
|
||||
</memberdef>
|
||||
<memberdef kind="function" id="aadvark_8h_1ae66f6b31b5ad750f1fe042a706a4e3d4" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
|
||||
<type>int</type>
|
||||
<definition>int main</definition>
|
||||
<argsstring>()</argsstring>
|
||||
<name>main</name>
|
||||
<briefdescription>
|
||||
</briefdescription>
|
||||
<detaileddescription>
|
||||
</detaileddescription>
|
||||
<inbodydescription>
|
||||
</inbodydescription>
|
||||
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="23" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="21" bodyend="28"/>
|
||||
</memberdef>
|
||||
</sectiondef>
|
||||
<briefdescription>
|
||||
</briefdescription>
|
||||
<detaileddescription>
|
||||
</detaileddescription>
|
||||
<programlisting>
|
||||
<codeline lineno="1"><highlight class="preprocessor">#include<sp/><iostream></highlight><highlight class="normal"></highlight></codeline>
|
||||
<codeline lineno="2"><highlight class="normal"></highlight></codeline>
|
||||
<codeline lineno="10" refid="classAadvark" refkind="compound"><highlight class="keyword">class<sp/></highlight><highlight class="normal"><ref refid="classAadvark" kindref="compound" tooltip="Models the mammal Aadvark.">Aadvark</ref><sp/>{</highlight></codeline>
|
||||
<codeline lineno="11"><highlight class="normal"></highlight><highlight class="keyword">public</highlight><highlight class="normal">:</highlight></codeline>
|
||||
<codeline lineno="13"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/><ref refid="classAadvark_1abd061aa5f998002e72080a34f512a059" kindref="member" tooltip="Outputs the vital aadvark statistics.">print</ref>();</highlight></codeline>
|
||||
<codeline lineno="15"><highlight class="normal"><sp/><sp/><ref refid="classAadvark_1adf1a4b97a641411a74a04ab312484462" kindref="member">Aadvark</ref>(</highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>aaness);</highlight></codeline>
|
||||
<codeline lineno="16"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>get_aadvarkness();</highlight></codeline>
|
||||
<codeline lineno="17"><highlight class="normal"></highlight><highlight class="keyword">private</highlight><highlight class="normal">:</highlight></codeline>
|
||||
<codeline lineno="18"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>aadvarkness;</highlight></codeline>
|
||||
<codeline lineno="19"><highlight class="normal">};</highlight></codeline>
|
||||
<codeline lineno="20"><highlight class="normal"></highlight></codeline>
|
||||
<codeline lineno="21"><highlight class="normal"></highlight><highlight class="keywordtype">bool</highlight><highlight class="normal"><sp/>aadvarky_enough(<ref refid="classAadvark" kindref="compound" tooltip="Models the mammal Aadvark.">Aadvark</ref><sp/>aad);</highlight></codeline>
|
||||
<codeline lineno="22"><highlight class="normal"></highlight></codeline>
|
||||
<codeline lineno="23"><highlight class="normal"></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>main();</highlight></codeline>
|
||||
</programlisting>
|
||||
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h"/>
|
||||
</compounddef>
|
||||
</doxygen>
|
|
@ -1,86 +0,0 @@
|
|||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.6.3">
|
||||
<compounddef id="classAadvark" kind="class" prot="public">
|
||||
<compoundname>Aadvark</compoundname>
|
||||
<includes refid="aadvark_8h" local="no">aadvark.h</includes>
|
||||
<sectiondef kind="private-attrib">
|
||||
<memberdef kind="variable" id="classAadvark_1ab79eb58d7bb9d5ddfa5d6f783836cab9" prot="private" static="no" mutable="no">
|
||||
<type>int</type>
|
||||
<definition>int Aadvark::aadvarkness</definition>
|
||||
<argsstring></argsstring>
|
||||
<name>aadvarkness</name>
|
||||
<briefdescription>
|
||||
</briefdescription>
|
||||
<detaileddescription>
|
||||
</detaileddescription>
|
||||
<inbodydescription>
|
||||
</inbodydescription>
|
||||
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="18" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" bodystart="18" bodyend="-1"/>
|
||||
</memberdef>
|
||||
</sectiondef>
|
||||
<sectiondef kind="public-func">
|
||||
<memberdef kind="function" id="classAadvark_1abd061aa5f998002e72080a34f512a059" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
|
||||
<type>void</type>
|
||||
<definition>void Aadvark::print</definition>
|
||||
<argsstring>()</argsstring>
|
||||
<name>print</name>
|
||||
<briefdescription>
|
||||
<para>Outputs the vital aadvark statistics. </para> </briefdescription>
|
||||
<detaileddescription>
|
||||
</detaileddescription>
|
||||
<inbodydescription>
|
||||
</inbodydescription>
|
||||
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="13" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="4" bodyend="6"/>
|
||||
</memberdef>
|
||||
<memberdef kind="function" id="classAadvark_1adf1a4b97a641411a74a04ab312484462" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
|
||||
<type></type>
|
||||
<definition>Aadvark::Aadvark</definition>
|
||||
<argsstring>(int aaness)</argsstring>
|
||||
<name>Aadvark</name>
|
||||
<param>
|
||||
<type>int</type>
|
||||
<declname>aaness</declname>
|
||||
</param>
|
||||
<briefdescription>
|
||||
</briefdescription>
|
||||
<detaileddescription>
|
||||
<para><parameterlist kind="param"><parameteritem>
|
||||
<parameternamelist>
|
||||
<parametername>aaness</parametername>
|
||||
</parameternamelist>
|
||||
<parameterdescription>
|
||||
<para>The aadvarkness of an aadvark is a measure of how aadvarky it is. </para></parameterdescription>
|
||||
</parameteritem>
|
||||
</parameterlist>
|
||||
</para> </detaileddescription>
|
||||
<inbodydescription>
|
||||
</inbodydescription>
|
||||
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="15" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="8" bodyend="8"/>
|
||||
</memberdef>
|
||||
<memberdef kind="function" id="classAadvark_1affd2ada0a85807efcbe26615a848f53e" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
|
||||
<type>int</type>
|
||||
<definition>int Aadvark::get_aadvarkness</definition>
|
||||
<argsstring>()</argsstring>
|
||||
<name>get_aadvarkness</name>
|
||||
<briefdescription>
|
||||
</briefdescription>
|
||||
<detaileddescription>
|
||||
</detaileddescription>
|
||||
<inbodydescription>
|
||||
</inbodydescription>
|
||||
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="16" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="17" bodyend="19"/>
|
||||
</memberdef>
|
||||
</sectiondef>
|
||||
<briefdescription>
|
||||
<para>Models the mammal <ref refid="classAadvark" kindref="compound">Aadvark</ref>. </para> </briefdescription>
|
||||
<detaileddescription>
|
||||
<para>Sadly the model is incomplete and cannot capture all aspects of an aadvark yet.</para><para>This line is uninformative and is only to test line breaks in the comments. </para> </detaileddescription>
|
||||
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="10" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" bodystart="10" bodyend="19"/>
|
||||
<listofallmembers>
|
||||
<member refid="classAadvark_1adf1a4b97a641411a74a04ab312484462" prot="public" virt="non-virtual"><scope>Aadvark</scope><name>Aadvark</name></member>
|
||||
<member refid="classAadvark_1ab79eb58d7bb9d5ddfa5d6f783836cab9" prot="private" virt="non-virtual"><scope>Aadvark</scope><name>aadvarkness</name></member>
|
||||
<member refid="classAadvark_1affd2ada0a85807efcbe26615a848f53e" prot="public" virt="non-virtual"><scope>Aadvark</scope><name>get_aadvarkness</name></member>
|
||||
<member refid="classAadvark_1abd061aa5f998002e72080a34f512a059" prot="public" virt="non-virtual"><scope>Aadvark</scope><name>print</name></member>
|
||||
</listofallmembers>
|
||||
</compounddef>
|
||||
</doxygen>
|
|
@ -1,15 +0,0 @@
|
|||
<!-- XSLT script to combine the generated output into a single file.
|
||||
If you have xsltproc you could use:
|
||||
xsltproc combine.xslt index.xml >all.xml
|
||||
-->
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||
<xsl:output method="xml" version="1.0" indent="yes" standalone="yes" />
|
||||
<xsl:template match="/">
|
||||
<doxygen version="{doxygenindex/@version}">
|
||||
<!-- Load all doxgen generated xml files -->
|
||||
<xsl:for-each select="doxygenindex/compound">
|
||||
<xsl:copy-of select="document( concat( @refid, '.xml' ) )/doxygen/*" />
|
||||
</xsl:for-each>
|
||||
</doxygen>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
|
@ -1,814 +0,0 @@
|
|||
<?xml version='1.0' encoding='utf-8' ?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<xsd:element name="doxygen" type="DoxygenType"/>
|
||||
|
||||
<!-- Complex types -->
|
||||
|
||||
<xsd:complexType name="DoxygenType">
|
||||
<xsd:sequence maxOccurs="unbounded">
|
||||
<xsd:element name="compounddef" type="compounddefType" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="version" type="DoxVersionNumber" use="required" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="compounddefType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="compoundname" type="xsd:string"/>
|
||||
<xsd:element name="title" type="xsd:string" minOccurs="0" />
|
||||
<xsd:element name="basecompoundref" type="compoundRefType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="derivedcompoundref" type="compoundRefType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="includes" type="incType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="includedby" type="incType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="incdepgraph" type="graphType" minOccurs="0" />
|
||||
<xsd:element name="invincdepgraph" type="graphType" minOccurs="0" />
|
||||
<xsd:element name="innerdir" type="refType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="innerfile" type="refType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="innerclass" type="refType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="innernamespace" type="refType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="innerpage" type="refType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="innergroup" type="refType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="templateparamlist" type="templateparamlistType" minOccurs="0" />
|
||||
<xsd:element name="sectiondef" type="sectiondefType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
|
||||
<xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
|
||||
<xsd:element name="inheritancegraph" type="graphType" minOccurs="0" />
|
||||
<xsd:element name="collaborationgraph" type="graphType" minOccurs="0" />
|
||||
<xsd:element name="programlisting" type="listingType" minOccurs="0" />
|
||||
<xsd:element name="location" type="locationType" minOccurs="0" />
|
||||
<xsd:element name="listofallmembers" type="listofallmembersType" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
<xsd:attribute name="kind" type="DoxCompoundKind" />
|
||||
<xsd:attribute name="prot" type="DoxProtectionKind" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="listofallmembersType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="member" type="memberRefType" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="memberRefType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="scope" />
|
||||
<xsd:element name="name" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="refid" type="xsd:string" />
|
||||
<xsd:attribute name="prot" type="DoxProtectionKind" />
|
||||
<xsd:attribute name="virt" type="DoxVirtualKind" />
|
||||
<xsd:attribute name="ambiguityscope" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="compoundRefType" mixed="true">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:string">
|
||||
<xsd:attribute name="refid" type="xsd:string" use="optional" />
|
||||
<xsd:attribute name="prot" type="DoxProtectionKind" />
|
||||
<xsd:attribute name="virt" type="DoxVirtualKind" />
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="reimplementType" mixed="true">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:string">
|
||||
<xsd:attribute name="refid" type="xsd:string" />
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="incType" mixed="true">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:string">
|
||||
<xsd:attribute name="refid" type="xsd:string" />
|
||||
<xsd:attribute name="local" type="DoxBool" />
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="refType" mixed="true">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:string">
|
||||
<xsd:attribute name="refid" type="xsd:string" />
|
||||
<xsd:attribute name="prot" type="DoxProtectionKind" use="optional"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="refTextType" mixed="true">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:string">
|
||||
<xsd:attribute name="refid" type="xsd:string" />
|
||||
<xsd:attribute name="kindref" type="DoxRefKind" />
|
||||
<xsd:attribute name="external" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="tooltip" type="xsd:string" use="optional"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="sectiondefType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="header" type="xsd:string" minOccurs="0" />
|
||||
<xsd:element name="description" type="descriptionType" minOccurs="0" />
|
||||
<xsd:element name="memberdef" type="memberdefType" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="kind" type="DoxSectionKind" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="memberdefType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="templateparamlist" type="templateparamlistType" minOccurs="0" />
|
||||
<xsd:element name="type" type="linkedTextType" minOccurs="0" />
|
||||
<xsd:element name="definition" minOccurs="0" />
|
||||
<xsd:element name="argsstring" minOccurs="0" />
|
||||
<xsd:element name="name" />
|
||||
<xsd:element name="read" minOccurs="0" />
|
||||
<xsd:element name="write" minOccurs="0" />
|
||||
<xsd:element name="bitfield" minOccurs="0" />
|
||||
<xsd:element name="reimplements" type="reimplementType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="reimplementedby" type="reimplementType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="enumvalue" type="enumvalueType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="initializer" type="linkedTextType" minOccurs="0" />
|
||||
<xsd:element name="exceptions" type="linkedTextType" minOccurs="0" />
|
||||
<xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
|
||||
<xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
|
||||
<xsd:element name="inbodydescription" type="descriptionType" minOccurs="0" />
|
||||
<xsd:element name="location" type="locationType" />
|
||||
<xsd:element name="references" type="referenceType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="referencedby" type="referenceType" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="kind" type="DoxMemberKind" />
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
<xsd:attribute name="prot" type="DoxProtectionKind" />
|
||||
<xsd:attribute name="static" type="DoxBool" />
|
||||
<xsd:attribute name="const" type="DoxBool" />
|
||||
<xsd:attribute name="explicit" type="DoxBool" />
|
||||
<xsd:attribute name="inline" type="DoxBool" />
|
||||
<xsd:attribute name="virt" type="DoxVirtualKind" />
|
||||
<xsd:attribute name="volatile" type="DoxBool" />
|
||||
<xsd:attribute name="mutable" type="DoxBool" />
|
||||
<!-- Qt property -->
|
||||
<xsd:attribute name="readable" type="DoxBool" use="optional"/>
|
||||
<xsd:attribute name="writable" type="DoxBool" use="optional"/>
|
||||
<!-- C++/CLI variable -->
|
||||
<xsd:attribute name="initonly" type="DoxBool" use="optional"/>
|
||||
<!-- C++/CLI and C# property -->
|
||||
<xsd:attribute name="settable" type="DoxBool" use="optional"/>
|
||||
<xsd:attribute name="gettable" type="DoxBool" use="optional"/>
|
||||
<!-- C++/CLI function -->
|
||||
<xsd:attribute name="final" type="DoxBool" use="optional"/>
|
||||
<xsd:attribute name="sealed" type="DoxBool" use="optional"/>
|
||||
<xsd:attribute name="new" type="DoxBool" use="optional"/>
|
||||
<!-- C++/CLI event -->
|
||||
<xsd:attribute name="add" type="DoxBool" use="optional"/>
|
||||
<xsd:attribute name="remove" type="DoxBool" use="optional"/>
|
||||
<xsd:attribute name="raise" type="DoxBool" use="optional"/>
|
||||
<!-- Objective-C 2.0 protocol method -->
|
||||
<xsd:attribute name="optional" type="DoxBool" use="optional"/>
|
||||
<xsd:attribute name="required" type="DoxBool" use="optional"/>
|
||||
<!-- Objective-C 2.0 property accessor -->
|
||||
<xsd:attribute name="accessor" type="DoxAccessor" use="optional"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="descriptionType" mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="title" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="internal" type="docInternalType" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="enumvalueType" mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="name" />
|
||||
<xsd:element name="initializer" type="linkedTextType" minOccurs="0" />
|
||||
<xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
|
||||
<xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
<xsd:attribute name="prot" type="DoxProtectionKind" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="templateparamlistType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="paramType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="type" type="linkedTextType" minOccurs="0" />
|
||||
<xsd:element name="declname" minOccurs="0" />
|
||||
<xsd:element name="defname" minOccurs="0" />
|
||||
<xsd:element name="array" minOccurs="0" />
|
||||
<xsd:element name="defval" type="linkedTextType" minOccurs="0" />
|
||||
<xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="linkedTextType" mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="graphType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="node" type="nodeType" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="nodeType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="label" />
|
||||
<xsd:element name="link" type="linkType" minOccurs="0" />
|
||||
<xsd:element name="childnode" type="childnodeType" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="childnodeType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="edgelabel" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="refid" type="xsd:string" />
|
||||
<xsd:attribute name="relation" type="DoxGraphRelation" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="linkType">
|
||||
<xsd:attribute name="refid" type="xsd:string" />
|
||||
<xsd:attribute name="external" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="listingType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="codeline" type="codelineType" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="codelineType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="highlight" type="highlightType" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="lineno" type="xsd:integer" />
|
||||
<xsd:attribute name="refid" type="xsd:string" />
|
||||
<xsd:attribute name="refkind" type="DoxRefKind" />
|
||||
<xsd:attribute name="external" type="DoxBool" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="highlightType" mixed="true">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="sp" />
|
||||
<xsd:element name="ref" type="refTextType" />
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="class" type="DoxHighlightClass" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="referenceType" mixed="true">
|
||||
<xsd:attribute name="refid" type="xsd:string" />
|
||||
<xsd:attribute name="compoundref" type="xsd:string" use="optional" />
|
||||
<xsd:attribute name="startline" type="xsd:integer" />
|
||||
<xsd:attribute name="endline" type="xsd:integer" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="locationType">
|
||||
<xsd:attribute name="file" type="xsd:string" />
|
||||
<xsd:attribute name="line" type="xsd:integer" />
|
||||
<xsd:attribute name="bodyfile" type="xsd:string" />
|
||||
<xsd:attribute name="bodystart" type="xsd:integer" />
|
||||
<xsd:attribute name="bodyend" type="xsd:integer" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docSect1Type" mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="title" type="xsd:string" />
|
||||
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="sect2" type="docSect2Type" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="internal" type="docInternalS1Type" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docSect2Type" mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="title" type="xsd:string" />
|
||||
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="sect3" type="docSect3Type" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="internal" type="docInternalS2Type" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docSect3Type" mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="title" type="xsd:string" />
|
||||
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="sect4" type="docSect4Type" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="internal" type="docInternalS3Type" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docSect4Type" mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="title" type="xsd:string" />
|
||||
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="internal" type="docInternalS4Type" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docInternalType" mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docInternalS1Type" mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="sect2" type="docSect2Type" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docInternalS2Type" mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="sect3" type="docSect3Type" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docInternalS3Type" mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="sect3" type="docSect4Type" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docInternalS4Type" mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:group name="docTitleCmdGroup">
|
||||
<xsd:choice>
|
||||
<xsd:element name="ulink" type="docURLLink" />
|
||||
<xsd:element name="bold" type="docMarkupType" />
|
||||
<xsd:element name="emphasis" type="docMarkupType" />
|
||||
<xsd:element name="computeroutput" type="docMarkupType" />
|
||||
<xsd:element name="subscript" type="docMarkupType" />
|
||||
<xsd:element name="superscript" type="docMarkupType" />
|
||||
<xsd:element name="center" type="docMarkupType" />
|
||||
<xsd:element name="small" type="docMarkupType" />
|
||||
<xsd:element name="htmlonly" type="xsd:string" />
|
||||
<xsd:element name="latexonly" type="xsd:string" />
|
||||
<xsd:element name="dot" type="xsd:string" />
|
||||
<xsd:element name="anchor" type="docAnchorType" />
|
||||
<xsd:element name="formula" type="docFormulaType" />
|
||||
<xsd:element name="ref" type="docRefTextType" />
|
||||
<xsd:element name="copy" type="docEmptyType" />
|
||||
<xsd:element name="trademark" type="docEmptyType" />
|
||||
<xsd:element name="registered" type="docEmptyType" />
|
||||
<xsd:element name="lsquo" type="docEmptyType" />
|
||||
<xsd:element name="rsquo" type="docEmptyType" />
|
||||
<xsd:element name="ldquo" type="docEmptyType" />
|
||||
<xsd:element name="rdquo" type="docEmptyType" />
|
||||
<xsd:element name="ndash" type="docEmptyType" />
|
||||
<xsd:element name="mdash" type="docEmptyType" />
|
||||
<xsd:element name="umlaut" type="docCharType" />
|
||||
<xsd:element name="acute" type="docCharType" />
|
||||
<xsd:element name="grave" type="docCharType" />
|
||||
<xsd:element name="circ" type="docCharType" />
|
||||
<xsd:element name="slash" type="docCharType" />
|
||||
<xsd:element name="tilde" type="docCharType" />
|
||||
<xsd:element name="cedil" type="docCharType" />
|
||||
<xsd:element name="ring" type="docCharType" />
|
||||
<xsd:element name="szlig" type="docEmptyType" />
|
||||
<xsd:element name="nonbreakablespace" type="docEmptyType" />
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
|
||||
<xsd:complexType name="docTitleType" mixed="true">
|
||||
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:group name="docCmdGroup">
|
||||
<xsd:choice>
|
||||
<xsd:group ref="docTitleCmdGroup"/>
|
||||
<xsd:element name="linebreak" type="docEmptyType" />
|
||||
<xsd:element name="hruler" type="docEmptyType" />
|
||||
<xsd:element name="preformatted" type="docMarkupType" />
|
||||
<xsd:element name="programlisting" type="listingType" />
|
||||
<xsd:element name="verbatim" type="xsd:string" />
|
||||
<xsd:element name="indexentry" type="docIndexEntryType" />
|
||||
<xsd:element name="orderedlist" type="docListType" />
|
||||
<xsd:element name="itemizedlist" type="docListType" />
|
||||
<xsd:element name="simplesect" type="docSimpleSectType" />
|
||||
<xsd:element name="title" type="docTitleType" />
|
||||
<xsd:element name="variablelist" type="docVariableListType" />
|
||||
<xsd:element name="table" type="docTableType" />
|
||||
<xsd:element name="heading" type="docHeadingType" />
|
||||
<xsd:element name="image" type="docImageType" />
|
||||
<xsd:element name="dotfile" type="docDotFileType" />
|
||||
<xsd:element name="toclist" type="docTocListType" />
|
||||
<xsd:element name="language" type="docLanguageType" />
|
||||
<xsd:element name="parameterlist" type="docParamListType" />
|
||||
<xsd:element name="xrefsect" type="docXRefSectType" />
|
||||
<xsd:element name="copydoc" type="docCopyType" />
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
|
||||
<xsd:complexType name="docParaType" mixed="true">
|
||||
<xsd:group ref="docCmdGroup" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docMarkupType" mixed="true">
|
||||
<xsd:group ref="docCmdGroup" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docURLLink" mixed="true">
|
||||
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:attribute name="url" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docAnchorType" mixed="true">
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docFormulaType" mixed="true">
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docIndexEntryType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="primaryie" type="xsd:string" />
|
||||
<xsd:element name="secondaryie" type="xsd:string" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docListType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="listitem" type="docListItemType" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docListItemType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docSimpleSectType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="title" type="docTitleType" minOccurs="0" />
|
||||
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="para" type="docParaType" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xsd:element name="simplesectsep" type="docEmptyType" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="kind" type="DoxSimpleSectKind" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docVarListEntryType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="term" type="docTitleType" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:group name="docVariableListGroup">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="varlistentry" type="docVarListEntryType" />
|
||||
<xsd:element name="listitem" type="docListItemType" />
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
|
||||
<xsd:complexType name="docVariableListType">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="docVariableListGroup" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docRefTextType" mixed="true">
|
||||
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:attribute name="refid" type="xsd:string" />
|
||||
<xsd:attribute name="kindref" type="DoxRefKind" />
|
||||
<xsd:attribute name="external" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docTableType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="row" type="docRowType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="caption" type="docCaptionType" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="rows" type="xsd:integer" />
|
||||
<xsd:attribute name="cols" type="xsd:integer" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docRowType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="entry" type="docEntryType" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docEntryType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="thead" type="DoxBool" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docCaptionType" mixed="true">
|
||||
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docHeadingType" mixed="true">
|
||||
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:attribute name="level" type="xsd:integer" /> <!-- todo: range 1-6 -->
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docImageType" mixed="true">
|
||||
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:attribute name="type" type="DoxImageKind" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="width" type="xsd:string" />
|
||||
<xsd:attribute name="height" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docDotFileType" mixed="true">
|
||||
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docTocItemType" mixed="true">
|
||||
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docTocListType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="tocitem" type="docTocItemType" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docLanguageType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="langid" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docParamListType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="parameteritem" type="docParamListItem" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="kind" type="DoxParamListKind" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docParamListItem">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="parameternamelist" type="docParamNameList" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="parameterdescription" type="descriptionType" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docParamNameList">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="parametername" type="docParamName" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docParamName" mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="direction" type="DoxParamDir" use="optional" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docXRefSectType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="xreftitle" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="xrefdescription" type="descriptionType" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docCopyType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="internal" type="docInternalType" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="link" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docCharType">
|
||||
<xsd:attribute name="char" type="DoxCharRange"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="docEmptyType"/>
|
||||
|
||||
<!-- Simple types -->
|
||||
|
||||
<xsd:simpleType name="DoxBool">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="yes" />
|
||||
<xsd:enumeration value="no" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="DoxGraphRelation">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="include" />
|
||||
<xsd:enumeration value="usage" />
|
||||
<xsd:enumeration value="template-instance" />
|
||||
<xsd:enumeration value="public-inheritance" />
|
||||
<xsd:enumeration value="protected-inheritance" />
|
||||
<xsd:enumeration value="private-inheritance" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="DoxRefKind">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="compound" />
|
||||
<xsd:enumeration value="member" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="DoxMemberKind">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="define" />
|
||||
<xsd:enumeration value="property" />
|
||||
<xsd:enumeration value="event" />
|
||||
<xsd:enumeration value="variable" />
|
||||
<xsd:enumeration value="typedef" />
|
||||
<xsd:enumeration value="enum" />
|
||||
<xsd:enumeration value="function" />
|
||||
<xsd:enumeration value="signal" />
|
||||
<xsd:enumeration value="prototype" />
|
||||
<xsd:enumeration value="friend" />
|
||||
<xsd:enumeration value="dcop" />
|
||||
<xsd:enumeration value="slot" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="DoxProtectionKind">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="public" />
|
||||
<xsd:enumeration value="protected" />
|
||||
<xsd:enumeration value="private" />
|
||||
<xsd:enumeration value="package" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="DoxVirtualKind">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="non-virtual" />
|
||||
<xsd:enumeration value="virtual" />
|
||||
<xsd:enumeration value="pure-virtual" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="DoxCompoundKind">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="class" />
|
||||
<xsd:enumeration value="struct" />
|
||||
<xsd:enumeration value="union" />
|
||||
<xsd:enumeration value="interface" />
|
||||
<xsd:enumeration value="protocol" />
|
||||
<xsd:enumeration value="category" />
|
||||
<xsd:enumeration value="exception" />
|
||||
<xsd:enumeration value="file" />
|
||||
<xsd:enumeration value="namespace" />
|
||||
<xsd:enumeration value="group" />
|
||||
<xsd:enumeration value="page" />
|
||||
<xsd:enumeration value="example" />
|
||||
<xsd:enumeration value="dir" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="DoxSectionKind">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="user-defined" />
|
||||
<xsd:enumeration value="public-type" />
|
||||
<xsd:enumeration value="public-func" />
|
||||
<xsd:enumeration value="public-attrib" />
|
||||
<xsd:enumeration value="public-slot" />
|
||||
<xsd:enumeration value="signal" />
|
||||
<xsd:enumeration value="dcop-func" />
|
||||
<xsd:enumeration value="property" />
|
||||
<xsd:enumeration value="event" />
|
||||
<xsd:enumeration value="public-static-func" />
|
||||
<xsd:enumeration value="public-static-attrib" />
|
||||
<xsd:enumeration value="protected-type" />
|
||||
<xsd:enumeration value="protected-func" />
|
||||
<xsd:enumeration value="protected-attrib" />
|
||||
<xsd:enumeration value="protected-slot" />
|
||||
<xsd:enumeration value="protected-static-func" />
|
||||
<xsd:enumeration value="protected-static-attrib" />
|
||||
<xsd:enumeration value="package-type" />
|
||||
<xsd:enumeration value="package-func" />
|
||||
<xsd:enumeration value="package-attrib" />
|
||||
<xsd:enumeration value="package-static-func" />
|
||||
<xsd:enumeration value="package-static-attrib" />
|
||||
<xsd:enumeration value="private-type" />
|
||||
<xsd:enumeration value="private-func" />
|
||||
<xsd:enumeration value="private-attrib" />
|
||||
<xsd:enumeration value="private-slot" />
|
||||
<xsd:enumeration value="private-static-func" />
|
||||
<xsd:enumeration value="private-static-attrib" />
|
||||
<xsd:enumeration value="friend" />
|
||||
<xsd:enumeration value="related" />
|
||||
<xsd:enumeration value="define" />
|
||||
<xsd:enumeration value="prototype" />
|
||||
<xsd:enumeration value="typedef" />
|
||||
<xsd:enumeration value="enum" />
|
||||
<xsd:enumeration value="func" />
|
||||
<xsd:enumeration value="var" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="DoxHighlightClass">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="comment" />
|
||||
<xsd:enumeration value="normal" />
|
||||
<xsd:enumeration value="preprocessor" />
|
||||
<xsd:enumeration value="keyword" />
|
||||
<xsd:enumeration value="keywordtype" />
|
||||
<xsd:enumeration value="keywordflow" />
|
||||
<xsd:enumeration value="stringliteral" />
|
||||
<xsd:enumeration value="charliteral" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="DoxSimpleSectKind">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="see" />
|
||||
<xsd:enumeration value="return" />
|
||||
<xsd:enumeration value="author" />
|
||||
<xsd:enumeration value="authors" />
|
||||
<xsd:enumeration value="version" />
|
||||
<xsd:enumeration value="since" />
|
||||
<xsd:enumeration value="date" />
|
||||
<xsd:enumeration value="note" />
|
||||
<xsd:enumeration value="warning" />
|
||||
<xsd:enumeration value="pre" />
|
||||
<xsd:enumeration value="post" />
|
||||
<xsd:enumeration value="invariant" />
|
||||
<xsd:enumeration value="remark" />
|
||||
<xsd:enumeration value="attention" />
|
||||
<xsd:enumeration value="par" />
|
||||
<xsd:enumeration value="rcs" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="DoxVersionNumber">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern value="\d+\.\d+.*" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="DoxImageKind">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="html" />
|
||||
<xsd:enumeration value="latex" />
|
||||
<xsd:enumeration value="rtf" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="DoxParamListKind">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="param" />
|
||||
<xsd:enumeration value="retval" />
|
||||
<xsd:enumeration value="exception" />
|
||||
<xsd:enumeration value="templateparam" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="DoxCharRange">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern value="[aeiouncAEIOUNC]" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="DoxParamDir">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="in"/>
|
||||
<xsd:enumeration value="out"/>
|
||||
<xsd:enumeration value="inout"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="DoxAccessor">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="retain"/>
|
||||
<xsd:enumeration value="copy"/>
|
||||
<xsd:enumeration value="assign"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
</xsd:schema>
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<doxygenindex xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="index.xsd" version="1.6.3">
|
||||
<compound refid="classAadvark" kind="class"><name>Aadvark</name>
|
||||
<member refid="classAadvark_1ab79eb58d7bb9d5ddfa5d6f783836cab9" kind="variable"><name>aadvarkness</name></member>
|
||||
<member refid="classAadvark_1abd061aa5f998002e72080a34f512a059" kind="function"><name>print</name></member>
|
||||
<member refid="classAadvark_1adf1a4b97a641411a74a04ab312484462" kind="function"><name>Aadvark</name></member>
|
||||
<member refid="classAadvark_1affd2ada0a85807efcbe26615a848f53e" kind="function"><name>get_aadvarkness</name></member>
|
||||
</compound>
|
||||
<compound refid="aadvark_8cc" kind="file"><name>aadvark.cc</name>
|
||||
<member refid="aadvark_8cc_1acb52858524210ec6dddc3e16d1e52946" kind="function"><name>aadvarky_enough</name></member>
|
||||
<member refid="aadvark_8cc_1ae66f6b31b5ad750f1fe042a706a4e3d4" kind="function"><name>main</name></member>
|
||||
</compound>
|
||||
<compound refid="aadvark_8h" kind="file"><name>aadvark.h</name>
|
||||
<member refid="aadvark_8h_1acb52858524210ec6dddc3e16d1e52946" kind="function"><name>aadvarky_enough</name></member>
|
||||
<member refid="aadvark_8h_1ae66f6b31b5ad750f1fe042a706a4e3d4" kind="function"><name>main</name></member>
|
||||
</compound>
|
||||
</doxygenindex>
|
|
@ -1,66 +0,0 @@
|
|||
<?xml version='1.0' encoding='utf-8' ?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<xsd:element name="doxygenindex" type="DoxygenType"/>
|
||||
|
||||
<xsd:complexType name="DoxygenType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="compound" type="CompoundType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="version" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="CompoundType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="name" type="xsd:string"/>
|
||||
<xsd:element name="member" type="MemberType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="refid" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="kind" type="CompoundKind" use="required"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="MemberType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="name" type="xsd:string"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="refid" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="kind" type="MemberKind" use="required"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="CompoundKind">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="class"/>
|
||||
<xsd:enumeration value="struct"/>
|
||||
<xsd:enumeration value="union"/>
|
||||
<xsd:enumeration value="interface"/>
|
||||
<xsd:enumeration value="protocol"/>
|
||||
<xsd:enumeration value="category"/>
|
||||
<xsd:enumeration value="exception"/>
|
||||
<xsd:enumeration value="file"/>
|
||||
<xsd:enumeration value="namespace"/>
|
||||
<xsd:enumeration value="group"/>
|
||||
<xsd:enumeration value="page"/>
|
||||
<xsd:enumeration value="example"/>
|
||||
<xsd:enumeration value="dir"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="MemberKind">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="define"/>
|
||||
<xsd:enumeration value="property"/>
|
||||
<xsd:enumeration value="event"/>
|
||||
<xsd:enumeration value="variable"/>
|
||||
<xsd:enumeration value="typedef"/>
|
||||
<xsd:enumeration value="enum"/>
|
||||
<xsd:enumeration value="enumvalue"/>
|
||||
<xsd:enumeration value="function"/>
|
||||
<xsd:enumeration value="signal"/>
|
||||
<xsd:enumeration value="prototype"/>
|
||||
<xsd:enumeration value="friend"/>
|
||||
<xsd:enumeration value="dcop"/>
|
||||
<xsd:enumeration value="slot"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
</xsd:schema>
|
||||
|
|
@ -5,3 +5,4 @@ These do the real work of parsing the doxygen xml files but the
|
|||
resultant classes are not very friendly to navigate so the rest of the
|
||||
doxyxml module processes them further.
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
|
|
@ -3,15 +3,17 @@
|
|||
"""
|
||||
Generated Mon Feb 9 19:08:05 2009 by generateDS.py.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
from string import lower as str_lower
|
||||
from xml.dom import minidom
|
||||
from xml.dom import Node
|
||||
|
||||
import sys
|
||||
|
||||
import compoundsuper as supermod
|
||||
from compoundsuper import MixedContainer
|
||||
from . import compoundsuper as supermod
|
||||
from .compoundsuper import MixedContainer
|
||||
|
||||
|
||||
class DoxygenTypeSub(supermod.DoxygenType):
|
||||
|
|
|
@ -4,12 +4,17 @@
|
|||
# Generated Thu Jun 11 18:44:25 2009 by generateDS.py.
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import sys
|
||||
import getopt
|
||||
from string import lower as str_lower
|
||||
|
||||
from xml.dom import minidom
|
||||
from xml.dom import Node
|
||||
|
||||
import six
|
||||
|
||||
|
||||
#
|
||||
# User methods
|
||||
#
|
||||
|
@ -19,9 +24,9 @@ from xml.dom import Node
|
|||
|
||||
try:
|
||||
from generatedssuper import GeneratedsSuper
|
||||
except ImportError, exp:
|
||||
except ImportError as exp:
|
||||
|
||||
class GeneratedsSuper:
|
||||
class GeneratedsSuper(object):
|
||||
def format_string(self, input_data, input_name=''):
|
||||
return input_data
|
||||
def format_integer(self, input_data, input_name=''):
|
||||
|
@ -64,7 +69,7 @@ def showIndent(outfile, level):
|
|||
outfile.write(' ')
|
||||
|
||||
def quote_xml(inStr):
|
||||
s1 = (isinstance(inStr, basestring) and inStr or
|
||||
s1 = (isinstance(inStr, six.string_types) and inStr or
|
||||
'%s' % inStr)
|
||||
s1 = s1.replace('&', '&')
|
||||
s1 = s1.replace('<', '<')
|
||||
|
@ -72,7 +77,7 @@ def quote_xml(inStr):
|
|||
return s1
|
||||
|
||||
def quote_attrib(inStr):
|
||||
s1 = (isinstance(inStr, basestring) and inStr or
|
||||
s1 = (isinstance(inStr, six.string_types) and inStr or
|
||||
'%s' % inStr)
|
||||
s1 = s1.replace('&', '&')
|
||||
s1 = s1.replace('<', '<')
|
||||
|
@ -102,7 +107,7 @@ def quote_python(inStr):
|
|||
return '"""%s"""' % s1
|
||||
|
||||
|
||||
class MixedContainer:
|
||||
class MixedContainer(object):
|
||||
# Constants for category:
|
||||
CategoryNone = 0
|
||||
CategoryText = 1
|
||||
|
@ -4221,7 +4226,7 @@ class codelineType(GeneratedsSuper):
|
|||
if attrs.get('lineno'):
|
||||
try:
|
||||
self.lineno = int(attrs.get('lineno').value)
|
||||
except ValueError, exp:
|
||||
except ValueError as exp:
|
||||
raise ValueError('Bad integer attribute (lineno): %s' % exp)
|
||||
if attrs.get('refkind'):
|
||||
self.refkind = attrs.get('refkind').value
|
||||
|
@ -4504,12 +4509,12 @@ class referenceType(GeneratedsSuper):
|
|||
if attrs.get('endline'):
|
||||
try:
|
||||
self.endline = int(attrs.get('endline').value)
|
||||
except ValueError, exp:
|
||||
except ValueError as exp:
|
||||
raise ValueError('Bad integer attribute (endline): %s' % exp)
|
||||
if attrs.get('startline'):
|
||||
try:
|
||||
self.startline = int(attrs.get('startline').value)
|
||||
except ValueError, exp:
|
||||
except ValueError as exp:
|
||||
raise ValueError('Bad integer attribute (startline): %s' % exp)
|
||||
if attrs.get('refid'):
|
||||
self.refid = attrs.get('refid').value
|
||||
|
@ -4627,17 +4632,17 @@ class locationType(GeneratedsSuper):
|
|||
if attrs.get('bodystart'):
|
||||
try:
|
||||
self.bodystart = int(attrs.get('bodystart').value)
|
||||
except ValueError, exp:
|
||||
except ValueError as exp:
|
||||
raise ValueError('Bad integer attribute (bodystart): %s' % exp)
|
||||
if attrs.get('line'):
|
||||
try:
|
||||
self.line = int(attrs.get('line').value)
|
||||
except ValueError, exp:
|
||||
except ValueError as exp:
|
||||
raise ValueError('Bad integer attribute (line): %s' % exp)
|
||||
if attrs.get('bodyend'):
|
||||
try:
|
||||
self.bodyend = int(attrs.get('bodyend').value)
|
||||
except ValueError, exp:
|
||||
except ValueError as exp:
|
||||
raise ValueError('Bad integer attribute (bodyend): %s' % exp)
|
||||
if attrs.get('bodyfile'):
|
||||
self.bodyfile = attrs.get('bodyfile').value
|
||||
|
@ -6778,12 +6783,12 @@ class docTableType(GeneratedsSuper):
|
|||
if attrs.get('rows'):
|
||||
try:
|
||||
self.rows = int(attrs.get('rows').value)
|
||||
except ValueError, exp:
|
||||
except ValueError as exp:
|
||||
raise ValueError('Bad integer attribute (rows): %s' % exp)
|
||||
if attrs.get('cols'):
|
||||
try:
|
||||
self.cols = int(attrs.get('cols').value)
|
||||
except ValueError, exp:
|
||||
except ValueError as exp:
|
||||
raise ValueError('Bad integer attribute (cols): %s' % exp)
|
||||
def buildChildren(self, child_, nodeName_):
|
||||
if child_.nodeType == Node.ELEMENT_NODE and \
|
||||
|
@ -7108,7 +7113,7 @@ class docHeadingType(GeneratedsSuper):
|
|||
if attrs.get('level'):
|
||||
try:
|
||||
self.level = int(attrs.get('level').value)
|
||||
except ValueError, exp:
|
||||
except ValueError as exp:
|
||||
raise ValueError('Bad integer attribute (level): %s' % exp)
|
||||
def buildChildren(self, child_, nodeName_):
|
||||
if child_.nodeType == Node.TEXT_NODE:
|
||||
|
@ -8283,7 +8288,7 @@ Options:
|
|||
"""
|
||||
|
||||
def usage():
|
||||
print USAGE_TEXT
|
||||
print(USAGE_TEXT)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
@ -8339,4 +8344,3 @@ if __name__ == '__main__':
|
|||
main()
|
||||
#import pdb
|
||||
#pdb.run('main()')
|
||||
|
||||
|
|
|
@ -3,14 +3,16 @@
|
|||
"""
|
||||
Generated Mon Feb 9 19:08:05 2009 by generateDS.py.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from xml.dom import minidom
|
||||
|
||||
import os
|
||||
import sys
|
||||
import compound
|
||||
from . import compound
|
||||
|
||||
import indexsuper as supermod
|
||||
from . import indexsuper as supermod
|
||||
|
||||
class DoxygenTypeSub(supermod.DoxygenType):
|
||||
def __init__(self, version=None, compound=None):
|
||||
|
|
|
@ -4,12 +4,16 @@
|
|||
# Generated Thu Jun 11 18:43:54 2009 by generateDS.py.
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import sys
|
||||
import getopt
|
||||
from string import lower as str_lower
|
||||
|
||||
from xml.dom import minidom
|
||||
from xml.dom import Node
|
||||
|
||||
import six
|
||||
|
||||
#
|
||||
# User methods
|
||||
#
|
||||
|
@ -19,9 +23,9 @@ from xml.dom import Node
|
|||
|
||||
try:
|
||||
from generatedssuper import GeneratedsSuper
|
||||
except ImportError, exp:
|
||||
except ImportError as exp:
|
||||
|
||||
class GeneratedsSuper:
|
||||
class GeneratedsSuper(object):
|
||||
def format_string(self, input_data, input_name=''):
|
||||
return input_data
|
||||
def format_integer(self, input_data, input_name=''):
|
||||
|
@ -64,7 +68,7 @@ def showIndent(outfile, level):
|
|||
outfile.write(' ')
|
||||
|
||||
def quote_xml(inStr):
|
||||
s1 = (isinstance(inStr, basestring) and inStr or
|
||||
s1 = (isinstance(inStr, six.string_types) and inStr or
|
||||
'%s' % inStr)
|
||||
s1 = s1.replace('&', '&')
|
||||
s1 = s1.replace('<', '<')
|
||||
|
@ -72,7 +76,7 @@ def quote_xml(inStr):
|
|||
return s1
|
||||
|
||||
def quote_attrib(inStr):
|
||||
s1 = (isinstance(inStr, basestring) and inStr or
|
||||
s1 = (isinstance(inStr, six.string_types) and inStr or
|
||||
'%s' % inStr)
|
||||
s1 = s1.replace('&', '&')
|
||||
s1 = s1.replace('<', '<')
|
||||
|
@ -102,7 +106,7 @@ def quote_python(inStr):
|
|||
return '"""%s"""' % s1
|
||||
|
||||
|
||||
class MixedContainer:
|
||||
class MixedContainer(object):
|
||||
# Constants for category:
|
||||
CategoryNone = 0
|
||||
CategoryText = 1
|
||||
|
@ -462,7 +466,7 @@ Options:
|
|||
"""
|
||||
|
||||
def usage():
|
||||
print USAGE_TEXT
|
||||
print(USAGE_TEXT)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
@ -520,4 +524,3 @@ if __name__ == '__main__':
|
|||
main()
|
||||
#import pdb
|
||||
#pdb.run('main()')
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#
|
||||
# Copyright 2010 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file was generated by gr_modtool, a tool from the GNU Radio framework
|
||||
# This file is a part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -21,12 +22,13 @@
|
|||
"""
|
||||
Utilities for extracting text from generated classes.
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
def is_string(txt):
|
||||
if isinstance(txt, str):
|
||||
return True
|
||||
try:
|
||||
if isinstance(txt, unicode):
|
||||
if isinstance(txt, str):
|
||||
return True
|
||||
except NameError:
|
||||
pass
|
||||
|
@ -49,7 +51,7 @@ def description_bit(obj):
|
|||
elif is_string(obj):
|
||||
return obj
|
||||
else:
|
||||
raise StandardError('Expecting a string or something with content, content_ or value attribute')
|
||||
raise Exception('Expecting a string or something with content, content_ or value attribute')
|
||||
# If this bit is a paragraph then add one some line breaks.
|
||||
if hasattr(obj, 'name') and obj.name == 'para':
|
||||
result += "\n\n"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*!
|
||||
* \defgroup block GNU Radio OsmoSDR C++ Signal Processing Blocks
|
||||
* \brief All C++ blocks that can be used from the OsmoSDR GNU Radio
|
||||
* \defgroup block GNU Radio TEST C++ Signal Processing Blocks
|
||||
* \brief All C++ blocks that can be used from the TEST GNU Radio
|
||||
* module are listed here or in the subcategories below.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
/*! \mainpage
|
||||
|
||||
Welcome to the OsmoSDR GNUradio blocks
|
||||
Welcome to the GNU Radio TEST Block
|
||||
|
||||
This is the intro page for the Doxygen manual generated for the TEST
|
||||
block (docs/doxygen/other/main_page.dox). Edit it to add more detailed
|
||||
documentation about the new GNU Radio modules contained in this
|
||||
project.
|
||||
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef PYDOC_MACROS_H
|
||||
#define PYDOC_MACROS_H
|
||||
|
||||
#define __EXPAND(x) x
|
||||
#define __COUNT(_1, _2, _3, _4, _5, _6, _7, COUNT, ...) COUNT
|
||||
#define __VA_SIZE(...) __EXPAND(__COUNT(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1))
|
||||
#define __CAT1(a, b) a##b
|
||||
#define __CAT2(a, b) __CAT1(a, b)
|
||||
#define __DOC1(n1) __doc_##n1
|
||||
#define __DOC2(n1, n2) __doc_##n1##_##n2
|
||||
#define __DOC3(n1, n2, n3) __doc_##n1##_##n2##_##n3
|
||||
#define __DOC4(n1, n2, n3, n4) __doc_##n1##_##n2##_##n3##_##n4
|
||||
#define __DOC5(n1, n2, n3, n4, n5) __doc_##n1##_##n2##_##n3##_##n4##_##n5
|
||||
#define __DOC6(n1, n2, n3, n4, n5, n6) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6
|
||||
#define __DOC7(n1, n2, n3, n4, n5, n6, n7) \
|
||||
__doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6##_##n7
|
||||
#define DOC(...) __EXPAND(__EXPAND(__CAT2(__DOC, __VA_SIZE(__VA_ARGS__)))(__VA_ARGS__))
|
||||
|
||||
#endif // PYDOC_MACROS_H
|
|
@ -1,255 +0,0 @@
|
|||
#
|
||||
# Copyright 2010,2011 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
#
|
||||
# GNU Radio 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
"""
|
||||
Creates the swig_doc.i SWIG interface file.
|
||||
Execute using: python swig_doc.py xml_path outputfilename
|
||||
|
||||
The file instructs SWIG to transfer the doxygen comments into the
|
||||
python docstrings.
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
try:
|
||||
from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile, base
|
||||
except ImportError:
|
||||
from gnuradio.doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile, base
|
||||
|
||||
|
||||
def py_name(name):
|
||||
bits = name.split('_')
|
||||
return '_'.join(bits[1:])
|
||||
|
||||
def make_name(name):
|
||||
bits = name.split('_')
|
||||
return bits[0] + '_make_' + '_'.join(bits[1:])
|
||||
|
||||
|
||||
class Block(object):
|
||||
"""
|
||||
Checks if doxyxml produced objects correspond to a gnuradio block.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def includes(cls, item):
|
||||
if not isinstance(item, DoxyClass):
|
||||
return False
|
||||
# Check for a parsing error.
|
||||
if item.error():
|
||||
return False
|
||||
return item.has_member(make_name(item.name()), DoxyFriend)
|
||||
|
||||
|
||||
def utoascii(text):
|
||||
"""
|
||||
Convert unicode text into ascii and escape quotes.
|
||||
"""
|
||||
if text is None:
|
||||
return ''
|
||||
out = text.encode('ascii', 'replace')
|
||||
out = out.replace('"', '\\"')
|
||||
return out
|
||||
|
||||
|
||||
def combine_descriptions(obj):
|
||||
"""
|
||||
Combines the brief and detailed descriptions of an object together.
|
||||
"""
|
||||
description = []
|
||||
bd = obj.brief_description.strip()
|
||||
dd = obj.detailed_description.strip()
|
||||
if bd:
|
||||
description.append(bd)
|
||||
if dd:
|
||||
description.append(dd)
|
||||
return utoascii('\n\n'.join(description)).strip()
|
||||
|
||||
|
||||
entry_templ = '%feature("docstring") {name} "{docstring}"'
|
||||
def make_entry(obj, name=None, templ="{description}", description=None):
|
||||
"""
|
||||
Create a docstring entry for a swig interface file.
|
||||
|
||||
obj - a doxyxml object from which documentation will be extracted.
|
||||
name - the name of the C object (defaults to obj.name())
|
||||
templ - an optional template for the docstring containing only one
|
||||
variable named 'description'.
|
||||
description - if this optional variable is set then it's value is
|
||||
used as the description instead of extracting it from obj.
|
||||
"""
|
||||
if name is None:
|
||||
name=obj.name()
|
||||
if "operator " in name:
|
||||
return ''
|
||||
if description is None:
|
||||
description = combine_descriptions(obj)
|
||||
docstring = templ.format(description=description)
|
||||
if not docstring:
|
||||
return ''
|
||||
return entry_templ.format(
|
||||
name=name,
|
||||
docstring=docstring,
|
||||
)
|
||||
|
||||
|
||||
def make_func_entry(func, name=None, description=None, params=None):
|
||||
"""
|
||||
Create a function docstring entry for a swig interface file.
|
||||
|
||||
func - a doxyxml object from which documentation will be extracted.
|
||||
name - the name of the C object (defaults to func.name())
|
||||
description - if this optional variable is set then it's value is
|
||||
used as the description instead of extracting it from func.
|
||||
params - a parameter list that overrides using func.params.
|
||||
"""
|
||||
if params is None:
|
||||
params = func.params
|
||||
params = [prm.declname for prm in params]
|
||||
if params:
|
||||
sig = "Params: (%s)" % ", ".join(params)
|
||||
else:
|
||||
sig = "Params: (NONE)"
|
||||
templ = "{description}\n\n" + sig
|
||||
return make_entry(func, name=name, templ=utoascii(templ),
|
||||
description=description)
|
||||
|
||||
|
||||
def make_class_entry(klass, description=None):
|
||||
"""
|
||||
Create a class docstring for a swig interface file.
|
||||
"""
|
||||
output = []
|
||||
output.append(make_entry(klass, description=description))
|
||||
for func in klass.in_category(DoxyFunction):
|
||||
name = klass.name() + '::' + func.name()
|
||||
output.append(make_func_entry(func, name=name))
|
||||
return "\n\n".join(output)
|
||||
|
||||
|
||||
def make_block_entry(di, block):
|
||||
"""
|
||||
Create class and function docstrings of a gnuradio block for a
|
||||
swig interface file.
|
||||
"""
|
||||
descriptions = []
|
||||
# Get the documentation associated with the class.
|
||||
class_desc = combine_descriptions(block)
|
||||
if class_desc:
|
||||
descriptions.append(class_desc)
|
||||
# Get the documentation associated with the make function
|
||||
make_func = di.get_member(make_name(block.name()), DoxyFunction)
|
||||
make_func_desc = combine_descriptions(make_func)
|
||||
if make_func_desc:
|
||||
descriptions.append(make_func_desc)
|
||||
# Get the documentation associated with the file
|
||||
try:
|
||||
block_file = di.get_member(block.name() + ".h", DoxyFile)
|
||||
file_desc = combine_descriptions(block_file)
|
||||
if file_desc:
|
||||
descriptions.append(file_desc)
|
||||
except base.Base.NoSuchMember:
|
||||
# Don't worry if we can't find a matching file.
|
||||
pass
|
||||
# And join them all together to make a super duper description.
|
||||
super_description = "\n\n".join(descriptions)
|
||||
# Associate the combined description with the class and
|
||||
# the make function.
|
||||
output = []
|
||||
output.append(make_class_entry(block, description=super_description))
|
||||
creator = block.get_member(block.name(), DoxyFunction)
|
||||
output.append(make_func_entry(make_func, description=super_description,
|
||||
params=creator.params))
|
||||
return "\n\n".join(output)
|
||||
|
||||
|
||||
def make_swig_interface_file(di, swigdocfilename, custom_output=None):
|
||||
|
||||
output = ["""
|
||||
/*
|
||||
* This file was automatically generated using swig_doc.py.
|
||||
*
|
||||
* Any changes to it will be lost next time it is regenerated.
|
||||
*/
|
||||
"""]
|
||||
|
||||
if custom_output is not None:
|
||||
output.append(custom_output)
|
||||
|
||||
# Create docstrings for the blocks.
|
||||
blocks = di.in_category(Block)
|
||||
make_funcs = set([])
|
||||
for block in blocks:
|
||||
try:
|
||||
make_func = di.get_member(make_name(block.name()), DoxyFunction)
|
||||
make_funcs.add(make_func.name())
|
||||
output.append(make_block_entry(di, block))
|
||||
except block.ParsingError:
|
||||
print('Parsing error for block %s' % block.name())
|
||||
|
||||
# Create docstrings for functions
|
||||
# Don't include the make functions since they have already been dealt with.
|
||||
funcs = [f for f in di.in_category(DoxyFunction) if f.name() not in make_funcs]
|
||||
for f in funcs:
|
||||
try:
|
||||
output.append(make_func_entry(f))
|
||||
except f.ParsingError:
|
||||
print('Parsing error for function %s' % f.name())
|
||||
|
||||
# Create docstrings for classes
|
||||
block_names = [block.name() for block in blocks]
|
||||
klasses = [k for k in di.in_category(DoxyClass) if k.name() not in block_names]
|
||||
for k in klasses:
|
||||
try:
|
||||
output.append(make_class_entry(k))
|
||||
except k.ParsingError:
|
||||
print('Parsing error for class %s' % k.name())
|
||||
|
||||
# Docstrings are not created for anything that is not a function or a class.
|
||||
# If this excludes anything important please add it here.
|
||||
|
||||
output = "\n\n".join(output)
|
||||
|
||||
swig_doc = file(swigdocfilename, 'w')
|
||||
swig_doc.write(output)
|
||||
swig_doc.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Parse command line options and set up doxyxml.
|
||||
err_msg = "Execute using: python swig_doc.py xml_path outputfilename"
|
||||
if len(sys.argv) != 3:
|
||||
raise StandardError(err_msg)
|
||||
xml_path = sys.argv[1]
|
||||
swigdocfilename = sys.argv[2]
|
||||
di = DoxyIndex(xml_path)
|
||||
|
||||
# gnuradio.gr.msq_queue.insert_tail and delete_head create errors unless docstrings are defined!
|
||||
# This is presumably a bug in SWIG.
|
||||
#msg_q = di.get_member(u'gr_msg_queue', DoxyClass)
|
||||
#insert_tail = msg_q.get_member(u'insert_tail', DoxyFunction)
|
||||
#delete_head = msg_q.get_member(u'delete_head', DoxyFunction)
|
||||
output = []
|
||||
#output.append(make_func_entry(insert_tail, name='gr_py_msg_queue__insert_tail'))
|
||||
#output.append(make_func_entry(delete_head, name='gr_py_msg_queue__delete_head'))
|
||||
custom_output = "\n\n".join(output)
|
||||
|
||||
# Generate the docstrings interface file.
|
||||
make_swig_interface_file(di, swigdocfilename, custom_output=custom_output)
|
|
@ -0,0 +1,346 @@
|
|||
#
|
||||
# Copyright 2010-2012 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file was generated by gr_modtool, a tool from the GNU Radio framework
|
||||
# This file is a part of gnuradio
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
#
|
||||
"""
|
||||
Updates the *pydoc_h files for a module
|
||||
Execute using: python update_pydoc.py xml_path outputfilename
|
||||
|
||||
The file instructs Pybind11 to transfer the doxygen comments into the
|
||||
python docstrings.
|
||||
|
||||
"""
|
||||
|
||||
import os, sys, time, glob, re, json
|
||||
from argparse import ArgumentParser
|
||||
|
||||
from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile
|
||||
from doxyxml import DoxyOther, base
|
||||
|
||||
def py_name(name):
|
||||
bits = name.split('_')
|
||||
return '_'.join(bits[1:])
|
||||
|
||||
def make_name(name):
|
||||
bits = name.split('_')
|
||||
return bits[0] + '_make_' + '_'.join(bits[1:])
|
||||
|
||||
|
||||
class Block(object):
|
||||
"""
|
||||
Checks if doxyxml produced objects correspond to a gnuradio block.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def includes(cls, item):
|
||||
if not isinstance(item, DoxyClass):
|
||||
return False
|
||||
# Check for a parsing error.
|
||||
if item.error():
|
||||
return False
|
||||
friendname = make_name(item.name())
|
||||
is_a_block = item.has_member(friendname, DoxyFriend)
|
||||
# But now sometimes the make function isn't a friend so check again.
|
||||
if not is_a_block:
|
||||
is_a_block = di.has_member(friendname, DoxyFunction)
|
||||
return is_a_block
|
||||
|
||||
class Block2(object):
|
||||
"""
|
||||
Checks if doxyxml produced objects correspond to a new style
|
||||
gnuradio block.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def includes(cls, item):
|
||||
if not isinstance(item, DoxyClass):
|
||||
return False
|
||||
# Check for a parsing error.
|
||||
if item.error():
|
||||
return False
|
||||
is_a_block2 = item.has_member('make', DoxyFunction) and item.has_member('sptr', DoxyOther)
|
||||
return is_a_block2
|
||||
|
||||
|
||||
def utoascii(text):
|
||||
"""
|
||||
Convert unicode text into ascii and escape quotes and backslashes.
|
||||
"""
|
||||
if text is None:
|
||||
return ''
|
||||
out = text.encode('ascii', 'replace')
|
||||
# swig will require us to replace blackslash with 4 backslashes
|
||||
# TODO: evaluate what this should be for pybind11
|
||||
out = out.replace(b'\\', b'\\\\\\\\')
|
||||
out = out.replace(b'"', b'\\"').decode('ascii')
|
||||
return str(out)
|
||||
|
||||
|
||||
def combine_descriptions(obj):
|
||||
"""
|
||||
Combines the brief and detailed descriptions of an object together.
|
||||
"""
|
||||
description = []
|
||||
bd = obj.brief_description.strip()
|
||||
dd = obj.detailed_description.strip()
|
||||
if bd:
|
||||
description.append(bd)
|
||||
if dd:
|
||||
description.append(dd)
|
||||
return utoascii('\n\n'.join(description)).strip()
|
||||
|
||||
def format_params(parameteritems):
|
||||
output = ['Args:']
|
||||
template = ' {0} : {1}'
|
||||
for pi in parameteritems:
|
||||
output.append(template.format(pi.name, pi.description))
|
||||
return '\n'.join(output)
|
||||
|
||||
entry_templ = '%feature("docstring") {name} "{docstring}"'
|
||||
def make_entry(obj, name=None, templ="{description}", description=None, params=[]):
|
||||
"""
|
||||
Create a docstring key/value pair, where the key is the object name.
|
||||
|
||||
obj - a doxyxml object from which documentation will be extracted.
|
||||
name - the name of the C object (defaults to obj.name())
|
||||
templ - an optional template for the docstring containing only one
|
||||
variable named 'description'.
|
||||
description - if this optional variable is set then it's value is
|
||||
used as the description instead of extracting it from obj.
|
||||
"""
|
||||
if name is None:
|
||||
name=obj.name()
|
||||
if hasattr(obj,'_parse_data') and hasattr(obj._parse_data,'definition'):
|
||||
name=obj._parse_data.definition.split(' ')[-1]
|
||||
if "operator " in name:
|
||||
return ''
|
||||
if description is None:
|
||||
description = combine_descriptions(obj)
|
||||
if params:
|
||||
description += '\n\n'
|
||||
description += utoascii(format_params(params))
|
||||
docstring = templ.format(description=description)
|
||||
|
||||
return {name: docstring}
|
||||
|
||||
|
||||
def make_class_entry(klass, description=None, ignored_methods=[], params=None):
|
||||
"""
|
||||
Create a class docstring key/value pair.
|
||||
"""
|
||||
if params is None:
|
||||
params = klass.params
|
||||
output = {}
|
||||
output.update(make_entry(klass, description=description, params=params))
|
||||
for func in klass.in_category(DoxyFunction):
|
||||
if func.name() not in ignored_methods:
|
||||
name = klass.name() + '::' + func.name()
|
||||
output.update(make_entry(func, name=name))
|
||||
return output
|
||||
|
||||
|
||||
def make_block_entry(di, block):
|
||||
"""
|
||||
Create class and function docstrings of a gnuradio block
|
||||
"""
|
||||
descriptions = []
|
||||
# Get the documentation associated with the class.
|
||||
class_desc = combine_descriptions(block)
|
||||
if class_desc:
|
||||
descriptions.append(class_desc)
|
||||
# Get the documentation associated with the make function
|
||||
make_func = di.get_member(make_name(block.name()), DoxyFunction)
|
||||
make_func_desc = combine_descriptions(make_func)
|
||||
if make_func_desc:
|
||||
descriptions.append(make_func_desc)
|
||||
# Get the documentation associated with the file
|
||||
try:
|
||||
block_file = di.get_member(block.name() + ".h", DoxyFile)
|
||||
file_desc = combine_descriptions(block_file)
|
||||
if file_desc:
|
||||
descriptions.append(file_desc)
|
||||
except base.Base.NoSuchMember:
|
||||
# Don't worry if we can't find a matching file.
|
||||
pass
|
||||
# And join them all together to make a super duper description.
|
||||
super_description = "\n\n".join(descriptions)
|
||||
# Associate the combined description with the class and
|
||||
# the make function.
|
||||
output = {}
|
||||
output.update(make_class_entry(block, description=super_description))
|
||||
output.update(make_entry(make_func, description=super_description,
|
||||
params=block.params))
|
||||
return output
|
||||
|
||||
def make_block2_entry(di, block):
|
||||
"""
|
||||
Create class and function docstrings of a new style gnuradio block
|
||||
"""
|
||||
# For new style blocks all the relevant documentation should be
|
||||
# associated with the 'make' method.
|
||||
class_description = combine_descriptions(block)
|
||||
make_func = block.get_member('make', DoxyFunction)
|
||||
make_description = combine_descriptions(make_func)
|
||||
description = class_description + "\n\nConstructor Specific Documentation:\n\n" + make_description
|
||||
# Associate the combined description with the class and
|
||||
# the make function.
|
||||
output = {}
|
||||
output.update(make_class_entry(
|
||||
block, description=description,
|
||||
ignored_methods=['make'], params=make_func.params))
|
||||
makename = block.name() + '::make'
|
||||
output.update(make_entry(
|
||||
make_func, name=makename, description=description,
|
||||
params=make_func.params))
|
||||
return output
|
||||
|
||||
def get_docstrings_dict(di, custom_output=None):
|
||||
|
||||
output = {}
|
||||
if custom_output:
|
||||
output.update(custom_output)
|
||||
|
||||
# Create docstrings for the blocks.
|
||||
blocks = di.in_category(Block)
|
||||
blocks2 = di.in_category(Block2)
|
||||
|
||||
make_funcs = set([])
|
||||
for block in blocks:
|
||||
try:
|
||||
make_func = di.get_member(make_name(block.name()), DoxyFunction)
|
||||
# Don't want to risk writing to output twice.
|
||||
if make_func.name() not in make_funcs:
|
||||
make_funcs.add(make_func.name())
|
||||
output.update(make_block_entry(di, block))
|
||||
except block.ParsingError:
|
||||
sys.stderr.write('Parsing error for block {0}\n'.format(block.name()))
|
||||
raise
|
||||
|
||||
for block in blocks2:
|
||||
try:
|
||||
make_func = block.get_member('make', DoxyFunction)
|
||||
make_func_name = block.name() +'::make'
|
||||
# Don't want to risk writing to output twice.
|
||||
if make_func_name not in make_funcs:
|
||||
make_funcs.add(make_func_name)
|
||||
output.update(make_block2_entry(di, block))
|
||||
except block.ParsingError:
|
||||
sys.stderr.write('Parsing error for block {0}\n'.format(block.name()))
|
||||
raise
|
||||
|
||||
# Create docstrings for functions
|
||||
# Don't include the make functions since they have already been dealt with.
|
||||
funcs = [f for f in di.in_category(DoxyFunction)
|
||||
if f.name() not in make_funcs and not f.name().startswith('std::')]
|
||||
for f in funcs:
|
||||
try:
|
||||
output.update(make_entry(f))
|
||||
except f.ParsingError:
|
||||
sys.stderr.write('Parsing error for function {0}\n'.format(f.name()))
|
||||
|
||||
# Create docstrings for classes
|
||||
block_names = [block.name() for block in blocks]
|
||||
block_names += [block.name() for block in blocks2]
|
||||
klasses = [k for k in di.in_category(DoxyClass)
|
||||
if k.name() not in block_names and not k.name().startswith('std::')]
|
||||
for k in klasses:
|
||||
try:
|
||||
output.update(make_class_entry(k))
|
||||
except k.ParsingError:
|
||||
sys.stderr.write('Parsing error for class {0}\n'.format(k.name()))
|
||||
|
||||
# Docstrings are not created for anything that is not a function or a class.
|
||||
# If this excludes anything important please add it here.
|
||||
|
||||
return output
|
||||
|
||||
def sub_docstring_in_pydoc_h(pydoc_files, docstrings_dict, output_dir, filter_str=None):
|
||||
if filter_str:
|
||||
docstrings_dict = {k: v for k, v in docstrings_dict.items() if k.startswith(filter_str)}
|
||||
|
||||
with open(os.path.join(output_dir,'docstring_status'),'w') as status_file:
|
||||
|
||||
for pydoc_file in pydoc_files:
|
||||
if filter_str:
|
||||
filter_str2 = "::".join((filter_str,os.path.split(pydoc_file)[-1].split('_pydoc_template.h')[0]))
|
||||
docstrings_dict2 = {k: v for k, v in docstrings_dict.items() if k.startswith(filter_str2)}
|
||||
else:
|
||||
docstrings_dict2 = docstrings_dict
|
||||
|
||||
|
||||
|
||||
file_in = open(pydoc_file,'r').read()
|
||||
for key, value in docstrings_dict2.items():
|
||||
file_in_tmp = file_in
|
||||
try:
|
||||
doc_key = key.split("::")
|
||||
# if 'gr' in doc_key:
|
||||
# doc_key.remove('gr')
|
||||
doc_key = '_'.join(doc_key)
|
||||
regexp = r'(__doc_{} =\sR\"doc\()[^)]*(\)doc\")'.format(doc_key)
|
||||
regexp = re.compile(regexp, re.MULTILINE)
|
||||
|
||||
(file_in, nsubs) = regexp.subn(r'\1'+value+r'\2', file_in, count=1)
|
||||
if nsubs == 1:
|
||||
status_file.write("PASS: " + pydoc_file + "\n")
|
||||
except KeyboardInterrupt:
|
||||
raise KeyboardInterrupt
|
||||
except: # be permissive, TODO log, but just leave the docstring blank
|
||||
status_file.write("FAIL: " + pydoc_file + "\n")
|
||||
file_in = file_in_tmp
|
||||
|
||||
output_pathname = os.path.join(output_dir, os.path.basename(pydoc_file).replace('_template.h','.h'))
|
||||
# FIXME: Remove this debug print
|
||||
print('output docstrings to {}'.format(output_pathname))
|
||||
with open(output_pathname,'w') as file_out:
|
||||
file_out.write(file_in)
|
||||
|
||||
def copy_docstring_templates(pydoc_files, output_dir):
|
||||
with open(os.path.join(output_dir,'docstring_status'),'w') as status_file:
|
||||
for pydoc_file in pydoc_files:
|
||||
file_in = open(pydoc_file,'r').read()
|
||||
output_pathname = os.path.join(output_dir, os.path.basename(pydoc_file).replace('_template.h','.h'))
|
||||
# FIXME: Remove this debug print
|
||||
print('copy docstrings to {}'.format(output_pathname))
|
||||
with open(output_pathname,'w') as file_out:
|
||||
file_out.write(file_in)
|
||||
status_file.write("DONE")
|
||||
|
||||
def argParse():
|
||||
"""Parses commandline args."""
|
||||
desc='Scrape the doxygen generated xml for docstrings to insert into python bindings'
|
||||
parser = ArgumentParser(description=desc)
|
||||
|
||||
parser.add_argument("function", help="Operation to perform on docstrings", choices=["scrape","sub","copy"])
|
||||
|
||||
parser.add_argument("--xml_path")
|
||||
parser.add_argument("--bindings_dir")
|
||||
parser.add_argument("--output_dir")
|
||||
parser.add_argument("--json_path")
|
||||
parser.add_argument("--filter", default=None)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Parse command line options and set up doxyxml.
|
||||
args = argParse()
|
||||
if args.function.lower() == 'scrape':
|
||||
di = DoxyIndex(args.xml_path)
|
||||
docstrings_dict = get_docstrings_dict(di)
|
||||
with open(args.json_path, 'w') as fp:
|
||||
json.dump(docstrings_dict, fp)
|
||||
elif args.function.lower() == 'sub':
|
||||
with open(args.json_path, 'r') as fp:
|
||||
docstrings_dict = json.load(fp)
|
||||
pydoc_files = glob.glob(os.path.join(args.bindings_dir,'*_pydoc_template.h'))
|
||||
sub_docstring_in_pydoc_h(pydoc_files, docstrings_dict, args.output_dir, args.filter)
|
||||
elif args.function.lower() == 'copy':
|
||||
pydoc_files = glob.glob(os.path.join(args.bindings_dir,'*_pydoc_template.h'))
|
||||
copy_docstring_templates(pydoc_files, args.output_dir)
|
||||
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/@GR_LIBRARY_DIR@
|
||||
includedir=${prefix}/@GR_INCLUDE_DIR@
|
||||
|
||||
Name: @CPACK_PACKAGE_NAME@
|
||||
Description: @CPACK_PACKAGE_DESCRIPTION_SUMMARY@
|
||||
URL: http://sdr.osmocom.org/trac/wiki/GrOsmoSDR
|
||||
Version: @CPACK_PACKAGE_VERSION@
|
||||
Requires: gnuradio-runtime gnuradio-blocks
|
||||
Requires.private: @GR_OSMOSDR_PC_REQUIRES@
|
||||
Conflicts:
|
||||
Cflags: -I${includedir} @GR_OSMOSDR_PC_CFLAGS@
|
||||
Libs: -L${libdir} -lgnuradio-osmosdr
|
||||
Libs.private: @GR_OSMOSDR_PC_LIBS@
|
|
@ -1,45 +1,44 @@
|
|||
# Copyright 2011 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file is part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# gr-osmosdr 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio is distributed in the hope that it will be useful,
|
||||
# gr-osmosdr 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# along with gr-osmosdr; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
########################################################################
|
||||
# Rules for generating the source and sink xml wrappers
|
||||
# Rules for generating the source and sink yml wrappers
|
||||
########################################################################
|
||||
include(GrPython)
|
||||
|
||||
macro(GEN_BLOCK_XML _generator _xml_block)
|
||||
macro(GEN_BLOCK_YAML _generator _yaml_block)
|
||||
set(generator ${CMAKE_CURRENT_SOURCE_DIR}/${_generator})
|
||||
set(xml_block ${CMAKE_CURRENT_BINARY_DIR}/${_xml_block})
|
||||
list(APPEND xml_blocks ${xml_block})
|
||||
set(yaml_block ${CMAKE_CURRENT_BINARY_DIR}/${_yaml_block})
|
||||
list(APPEND yaml_blocks ${yaml_block})
|
||||
add_custom_command(
|
||||
DEPENDS ${generator} OUTPUT ${xml_block}
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${generator} ${xml_block}
|
||||
DEPENDS ${generator} OUTPUT ${yaml_block}
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${generator} ${yaml_block}
|
||||
)
|
||||
endmacro(GEN_BLOCK_XML)
|
||||
endmacro(GEN_BLOCK_YAML)
|
||||
|
||||
GEN_BLOCK_XML(gen_osmosdr_blocks.py rtlsdr_source.xml)
|
||||
GEN_BLOCK_XML(gen_osmosdr_blocks.py osmosdr_source.xml)
|
||||
GEN_BLOCK_XML(gen_osmosdr_blocks.py osmosdr_sink.xml)
|
||||
GEN_BLOCK_YAML(gen_osmosdr_blocks.py rtlsdr_source.block.yml)
|
||||
GEN_BLOCK_YAML(gen_osmosdr_blocks.py osmosdr_source.block.yml)
|
||||
GEN_BLOCK_YAML(gen_osmosdr_blocks.py osmosdr_sink.block.yml)
|
||||
|
||||
add_custom_target(osmosdr_grc_xml_blocks ALL DEPENDS ${xml_blocks})
|
||||
add_custom_target(osmosdr_grc_yaml_blocks ALL DEPENDS ${yaml_blocks})
|
||||
|
||||
install(FILES
|
||||
${xml_blocks}
|
||||
# DESTINATION ${GRC_BLOCKS_DIR}
|
||||
${yaml_blocks}
|
||||
DESTINATION share/gnuradio/grc/blocks
|
||||
)
|
||||
|
|
|
@ -19,369 +19,386 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|||
"""
|
||||
|
||||
MAIN_TMPL = """\
|
||||
<?xml version="1.0"?>
|
||||
<block>
|
||||
<name>$(title) $sourk.title()</name>
|
||||
<key>$(prefix)_$(sourk)</key>
|
||||
<category>$($sourk.title())s</category>
|
||||
<throttle>1</throttle>
|
||||
<import>import osmosdr</import>
|
||||
<make>osmosdr.$(sourk)( args="numchan=" + str(\$nchan) + " " + \$args )
|
||||
self.\$(id).set_sample_rate(\$sample_rate)
|
||||
#for $n in range($max_nchan)
|
||||
\#if \$nchan() > $n
|
||||
self.\$(id).set_center_freq(\$freq$(n), $n)
|
||||
self.\$(id).set_freq_corr(\$corr$(n), $n)
|
||||
#if $sourk == 'source':
|
||||
self.\$(id).set_dc_offset_mode(\$dc_offset_mode$(n), $n)
|
||||
self.\$(id).set_iq_balance_mode(\$iq_balance_mode$(n), $n)
|
||||
self.\$(id).set_gain_mode(\$gain_mode$(n), $n)
|
||||
#end if
|
||||
self.\$(id).set_gain(\$gain$(n), $n)
|
||||
self.\$(id).set_if_gain(\$if_gain$(n), $n)
|
||||
self.\$(id).set_bb_gain(\$bb_gain$(n), $n)
|
||||
self.\$(id).set_antenna(\$ant$(n), $n)
|
||||
self.\$(id).set_bandwidth(\$bw$(n), $n)
|
||||
\#end if
|
||||
#end for
|
||||
</make>
|
||||
<callback>set_sample_rate(\$sample_rate)</callback>
|
||||
#for $n in range($max_nchan)
|
||||
<callback>set_center_freq(\$freq$(n), $n)</callback>
|
||||
<callback>set_freq_corr(\$corr$(n), $n)</callback>
|
||||
#if $sourk == 'source':
|
||||
<callback>set_dc_offset_mode(\$dc_offset_mode$(n), $n)</callback>
|
||||
<callback>set_iq_balance_mode(\$iq_balance_mode$(n), $n)</callback>
|
||||
<callback>set_gain_mode(\$gain_mode$(n), $n)</callback>
|
||||
#end if
|
||||
<callback>set_gain(\$gain$(n), $n)</callback>
|
||||
<callback>set_if_gain(\$if_gain$(n), $n)</callback>
|
||||
<callback>set_bb_gain(\$bb_gain$(n), $n)</callback>
|
||||
<callback>set_antenna(\$ant$(n), $n)</callback>
|
||||
<callback>set_bandwidth(\$bw$(n), $n)</callback>
|
||||
#end for
|
||||
<param>
|
||||
<name>$(dir.title())put Type</name>
|
||||
<key>type</key>
|
||||
<type>enum</type>
|
||||
<option>
|
||||
<name>Complex float32</name>
|
||||
<key>fc32</key>
|
||||
<opt>type:fc32</opt>
|
||||
</option>
|
||||
</param>
|
||||
<param>
|
||||
<name>Device Arguments</name>
|
||||
<key>args</key>
|
||||
<value></value>
|
||||
<type>string</type>
|
||||
<hide>
|
||||
\#if \$args()
|
||||
none
|
||||
\#else
|
||||
part
|
||||
\#end if
|
||||
</hide>
|
||||
</param>
|
||||
<param>
|
||||
<name>Num Channels</name>
|
||||
<key>nchan</key>
|
||||
<value>1</value>
|
||||
<type>int</type>
|
||||
#for $n in range(1, $max_nchan+1)
|
||||
<option>
|
||||
<name>$(n)</name>
|
||||
<key>$n</key>
|
||||
</option>
|
||||
#end for
|
||||
</param>
|
||||
<param>
|
||||
<name>Sample Rate (sps)</name>
|
||||
<key>sample_rate</key>
|
||||
<value>samp_rate</value>
|
||||
<type>real</type>
|
||||
</param>
|
||||
$params
|
||||
<check>$max_nchan >= \$nchan</check>
|
||||
<check>\$nchan > 0</check>
|
||||
<$sourk>
|
||||
<name>$dir</name>
|
||||
<type>\$type.type</type>
|
||||
<nports>\$nchan</nports>
|
||||
</$sourk>
|
||||
<doc>
|
||||
The osmocom $sourk block:
|
||||
id: ${prefix}_${sourk}
|
||||
label: '${title} ${sourk.title()}'
|
||||
category: '[OsmoSDR]'
|
||||
flags: throttle
|
||||
|
||||
While primarily being developed for the OsmoSDR hardware, this block as well supports:
|
||||
parameters:
|
||||
- id: type
|
||||
label: '${direction.title()}put Type'
|
||||
dtype: enum
|
||||
options: [fc32]
|
||||
option_labels: [Complex Float32]
|
||||
option_attributes:
|
||||
type: [fc32]
|
||||
hide: part
|
||||
- id: args
|
||||
label: 'Device Arguments'
|
||||
dtype: string
|
||||
default: '""'
|
||||
hide: ${'$'}{ 'none' if args else 'part'}
|
||||
- id: sync
|
||||
label: Sync
|
||||
dtype: enum
|
||||
options: [sync, pc_clock, none]
|
||||
option_labels: [Unknown PPS, PC Clock, Don't Sync]
|
||||
hide: ${'$'}{ 'none' if sync else 'part'}
|
||||
- id: num_mboards
|
||||
label: 'Number MBoards'
|
||||
dtype: int
|
||||
default: 1
|
||||
options: [ ${", ".join([str(n) for n in range(1, max_mboards+1)])} ]
|
||||
hide: part
|
||||
% for m in range(max_mboards):
|
||||
- id: clock_source${m}
|
||||
label: 'MB${m}: Clock Source'
|
||||
dtype: string
|
||||
options: ['', internal, external, external_1pps, mimo, gpsdo]
|
||||
option_labels: [Default, Internal, External, External 1PPS, MIMO Cable, O/B GPSDO]
|
||||
hide: ${'$'}{ 'all' if not (num_mboards > ${m}) else ( 'none' if clock_source${m} else 'part' )}
|
||||
- id: time_source${m}
|
||||
label: 'MB${m}: Time Source'
|
||||
dtype: string
|
||||
options: ['', external, mimo, gpsdo]
|
||||
option_labels: [Default, External, MIMO Cable, O/B GPSDO]
|
||||
hide: ${'$'}{ 'all' if not (num_mboards > ${m}) else ( 'none' if time_source${m} else 'part' )}
|
||||
% endfor
|
||||
- id: nchan
|
||||
label: 'Number Channels'
|
||||
dtype: int
|
||||
default: 1
|
||||
options: [ ${", ".join([str(n) for n in range(1, max_nchan+1)])} ]
|
||||
- id: sample_rate
|
||||
label: 'Sample Rate (sps)'
|
||||
dtype: real
|
||||
default: samp_rate
|
||||
${params}
|
||||
|
||||
#if $sourk == 'source':
|
||||
* FUNcube Dongle through libgnuradio-fcd
|
||||
* FUNcube Dongle Pro+ through gr-fcdproplus
|
||||
* sysmocom OsmoSDR Devices through libosmosdr
|
||||
* RTL2832U based DVB-T dongles through librtlsdr
|
||||
* RTL-TCP spectrum server (see librtlsdr project)
|
||||
* MSi2500 based DVB-T dongles through libmirisdr
|
||||
* gnuradio .cfile input through libgnuradio-blocks
|
||||
* RFSPACE SDR-IQ, SDR-IP, NetSDR (incl. X2 option)
|
||||
* AirSpy Wideband Receiver through libairspy
|
||||
#end if
|
||||
* Great Scott Gadgets HackRF through libhackrf
|
||||
* Nuand LLC bladeRF through libbladeRF library
|
||||
* Ettus USRP Devices through Ettus UHD library
|
||||
* Fairwaves UmTRX through Fairwaves' fork of UHD
|
||||
inputs:
|
||||
- domain: message
|
||||
id: command
|
||||
optional: true
|
||||
% if sourk == 'source':
|
||||
|
||||
By using the osmocom $sourk block you can take advantage of a common software api in your application(s) independent of the underlying radio hardware.
|
||||
outputs:
|
||||
% endif
|
||||
- domain: stream
|
||||
dtype: ${'$'}{type.type}
|
||||
multiplicity: ${'$'}{nchan}
|
||||
% if sourk == 'sink':
|
||||
|
||||
Output Type:
|
||||
This parameter controls the data type of the stream in gnuradio. Only complex float32 samples are supported at the moment.
|
||||
outputs:
|
||||
- domain: message
|
||||
id: async_msgs
|
||||
optional: true
|
||||
% endif
|
||||
|
||||
Device Arguments:
|
||||
The device argument is a comma delimited string used to locate devices on your system. Device arguments for multiple devices may be given by separating them with a space.
|
||||
Use the device id or name/serial (if applicable) to specify a certain device or list of devices. If left blank, the first device found will be used.
|
||||
templates:
|
||||
imports: |-
|
||||
import osmosdr
|
||||
import time
|
||||
make: |
|
||||
osmosdr.${sourk}(
|
||||
args="numchan=" + str(${'$'}{nchan}) + " " + ${'$'}{args}
|
||||
)
|
||||
% for m in range(max_mboards):
|
||||
${'%'} if context.get('num_mboards')() > ${m}:
|
||||
${'%'} if context.get('clock_source${m}')():
|
||||
self.${'$'}{id}.set_clock_source(${'$'}{${'clock_source' + str(m)}}, ${m})
|
||||
${'%'} endif
|
||||
${'%'} if context.get('time_source${m}')():
|
||||
self.${'$'}{id}.set_time_source(${'$'}{${'time_source' + str(m)}}, ${m})
|
||||
${'%'} endif
|
||||
${'%'} endif
|
||||
% endfor
|
||||
${'%'} if sync == 'sync':
|
||||
self.${'$'}{id}.set_time_unknown_pps(osmosdr.time_spec_t())
|
||||
${'%'} elif sync == 'pc_clock':
|
||||
self.${'$'}{id}.set_time_now(osmosdr.time_spec_t(time.time()), osmosdr.ALL_MBOARDS)
|
||||
${'%'} endif
|
||||
self.${'$'}{id}.set_sample_rate(${'$'}{sample_rate})
|
||||
% for n in range(max_nchan):
|
||||
${'%'} if context.get('nchan')() > ${n}:
|
||||
self.${'$'}{id}.set_center_freq(${'$'}{${'freq' + str(n)}}, ${n})
|
||||
self.${'$'}{id}.set_freq_corr(${'$'}{${'corr' + str(n)}}, ${n})
|
||||
% if sourk == 'source':
|
||||
self.${'$'}{id}.set_dc_offset_mode(${'$'}{${'dc_offset_mode' + str(n)}}, ${n})
|
||||
self.${'$'}{id}.set_iq_balance_mode(${'$'}{${'iq_balance_mode' + str(n)}}, ${n})
|
||||
self.${'$'}{id}.set_gain_mode(${'$'}{${'gain_mode' + str(n)}}, ${n})
|
||||
% endif
|
||||
self.${'$'}{id}.set_gain(${'$'}{${'gain' + str(n)}}, ${n})
|
||||
self.${'$'}{id}.set_if_gain(${'$'}{${'if_gain' + str(n)}}, ${n})
|
||||
self.${'$'}{id}.set_bb_gain(${'$'}{${'bb_gain' + str(n)}}, ${n})
|
||||
self.${'$'}{id}.set_antenna(${'$'}{${'ant' + str(n)}}, ${n})
|
||||
self.${'$'}{id}.set_bandwidth(${'$'}{${'bw' + str(n)}}, ${n})
|
||||
${'%'} endif
|
||||
% endfor
|
||||
callbacks:
|
||||
- set_sample_rate(${'$'}{sample_rate})
|
||||
% for n in range(max_nchan):
|
||||
- set_center_freq(${'$'}{${'freq' + str(n)}}, ${n})
|
||||
- set_freq_corr(${'$'}{${'corr' + str(n)}}, ${n})
|
||||
% if sourk == 'source':
|
||||
- set_dc_offset_mode(${'$'}{${'dc_offset_mode' + str(n)}}, ${n})
|
||||
- set_iq_balance_mode(${'$'}{${'iq_balance_mode' + str(n)}}, ${n})
|
||||
- set_gain_mode(${'$'}{${'gain_mode' + str(n)}}, ${n})
|
||||
% endif
|
||||
- set_gain(${'$'}{${'gain' + str(n)}}, ${n})
|
||||
- set_if_gain(${'$'}{${'if_gain' + str(n)}}, ${n})
|
||||
- set_bb_gain(${'$'}{${'bb_gain' + str(n)}}, ${n})
|
||||
- set_antenna(${'$'}{${'ant' + str(n)}}, ${n})
|
||||
- set_bandwidth(${'$'}{${'bw' + str(n)}}, ${n})
|
||||
% endfor
|
||||
|
||||
Examples:
|
||||
documentation: |-
|
||||
The osmocom ${sourk} block:
|
||||
|
||||
Optional arguments are placed into [] brackets, remove the brackets before using them! Specific variable values are separated with a |, choose one of them. Variable values containing spaces shall be enclosed in '' as demonstrated in examples section below.
|
||||
Lines ending with ... mean it's possible to bind devices together by specifying multiple device arguments separated with a space.
|
||||
While primarily being developed for the OsmoSDR hardware, this block as well supports:
|
||||
|
||||
#if $sourk == 'source':
|
||||
fcd=0[,device=hw:2][,type=2]
|
||||
miri=0[,buffers=32] ...
|
||||
rtl=serial_number ...
|
||||
rtl=0[,rtl_xtal=28.8e6][,tuner_xtal=28.8e6] ...
|
||||
rtl=1[,buffers=32][,buflen=N*512] ...
|
||||
rtl=2[,direct_samp=0|1|2][,offset_tune=0|1] ...
|
||||
rtl_tcp=127.0.0.1:1234[,psize=16384][,direct_samp=0|1|2][,offset_tune=0|1] ...
|
||||
osmosdr=0[,buffers=32][,buflen=N*512] ...
|
||||
file='/path/to/your file',rate=1e6[,freq=100e6][,repeat=true][,throttle=true] ...
|
||||
netsdr=127.0.0.1[:50000][,nchan=2]
|
||||
sdr-ip=127.0.0.1[:50000]
|
||||
sdr-iq=/dev/ttyUSB0
|
||||
airspy=0
|
||||
#end if
|
||||
hackrf=0[,buffers=32]
|
||||
bladerf=0[,fpga='/path/to/the/bitstream.rbf']
|
||||
uhd[,serial=...][,lo_offset=0][,mcr=52e6][,nchan=2][,subdev='\\\\'B:0 A:0\\\\''] ...
|
||||
% if sourk == 'source':
|
||||
* RTL2832U based DVB-T dongles through librtlsdr
|
||||
* RTL-TCP spectrum server (see librtlsdr project)
|
||||
* SDRplay RSP devices through SDRplay library
|
||||
* gnuradio .cfile input through libgnuradio-blocks
|
||||
* RFSPACE SDR-IQ, SDR-IP, NetSDR (incl. X2 option)
|
||||
* AirSpy Wideband Receiver through libairspy
|
||||
% endif
|
||||
% if sourk == 'sink':
|
||||
* gnuradio .cfile output through libgnuradio-blocks
|
||||
% endif
|
||||
* CCCamp 2015 rad1o Badge through libhackrf
|
||||
* Great Scott Gadgets HackRF through libhackrf
|
||||
* Nuand LLC bladeRF through libbladeRF library
|
||||
* Ettus USRP Devices through Ettus UHD library
|
||||
* Fairwaves XTRX through libxtrx
|
||||
* Fairwaves UmTRX through Fairwaves' module for UHD
|
||||
* Red Pitaya SDR transceiver (http://bazaar.redpitaya.com)
|
||||
* FreeSRP through libfreesrp library
|
||||
|
||||
Num Channels:
|
||||
Selects the total number of channels in this multi-device configuration. Required when specifying multiple device arguments.
|
||||
By using the osmocom $sourk block you can take advantage of a common software api in your application(s) independent of the underlying radio hardware.
|
||||
|
||||
Sample Rate:
|
||||
The sample rate is the number of samples per second output by this block on each channel.
|
||||
Output Type:
|
||||
This parameter controls the data type of the stream in gnuradio. Only complex float32 samples are supported at the moment.
|
||||
|
||||
Frequency:
|
||||
The center frequency is the frequency the RF chain is tuned to.
|
||||
Device Arguments:
|
||||
The device argument is a comma delimited string used to locate devices on your system. Device arguments for multiple devices may be given by separating them with a space.
|
||||
Use the device id or name/serial (if applicable) to specify a certain device or list of devices. If left blank, the first device found will be used.
|
||||
|
||||
Freq. Corr.:
|
||||
The frequency correction factor in parts per million (ppm). Set to 0 if unknown.
|
||||
Examples:
|
||||
|
||||
#if $sourk == 'source':
|
||||
DC Offset Mode:
|
||||
Controls the behavior of hardware DC offset corrrection.
|
||||
Off: Disable correction algorithm (pass through).
|
||||
Manual: Keep last estimated correction when switched from Automatic to Manual.
|
||||
Automatic: Periodicallly find the best solution to compensate for DC offset.
|
||||
Optional arguments are placed into [] brackets, remove the brackets before using them! Specific variable values are separated with a |, choose one of them. Variable values containing spaces shall be enclosed in '' as demonstrated in examples section below.
|
||||
Lines ending with ... mean it's possible to bind devices together by specifying multiple device arguments separated with a space.
|
||||
|
||||
This functionality is available for USRP devices only.
|
||||
% if sourk == 'source':
|
||||
rtl=serial_number ...
|
||||
rtl=0[,rtl_xtal=28.8e6][,tuner_xtal=28.8e6] ...
|
||||
rtl=1[,buffers=32][,buflen=N*512] ...
|
||||
rtl=2[,direct_samp=0|1|2][,offset_tune=0|1][,bias=0|1] ...
|
||||
rtl_tcp=127.0.0.1:1234[,psize=16384][,direct_samp=0|1|2][,offset_tune=0|1][,bias=0|1] ...
|
||||
file='/path/to/your file',rate=1e6[,freq=100e6][,repeat=true][,throttle=true] ...
|
||||
netsdr=127.0.0.1[:50000][,nchan=2]
|
||||
sdr-ip=127.0.0.1[:50000]
|
||||
cloudiq=127.0.0.1[:50000]
|
||||
sdr-iq=/dev/ttyUSB0
|
||||
airspy=0[,bias=0|1][,linearity][,sensitivity]
|
||||
% endif
|
||||
% if sourk == 'sink':
|
||||
file='/path/to/your file',rate=1e6[,freq=100e6][,append=true][,throttle=true] ...
|
||||
% endif
|
||||
redpitaya=192.168.1.100[:1001]
|
||||
freesrp=0[,fx3='path/to/fx3.img',fpga='path/to/fpga.bin',loopback]
|
||||
hackrf=0[,buffers=32][,bias=0|1][,bias_tx=0|1]
|
||||
bladerf=0[,tamer=internal|external|external_1pps][,smb=25e6]
|
||||
uhd[,serial=...][,lo_offset=0][,mcr=52e6][,nchan=2][,subdev='\\\\'B:0 A:0\\\\''] ...
|
||||
xtrx
|
||||
|
||||
IQ Balance Mode:
|
||||
Controls the behavior of software IQ imbalance corrrection.
|
||||
Off: Disable correction algorithm (pass through).
|
||||
Manual: Keep last estimated correction when switched from Automatic to Manual.
|
||||
Automatic: Periodicallly find the best solution to compensate for image signals.
|
||||
Num Channels:
|
||||
Selects the total number of channels in this multi-device configuration. Required when specifying multiple device arguments.
|
||||
|
||||
This functionality depends on http://cgit.osmocom.org/cgit/gr-iqbal/
|
||||
Sample Rate:
|
||||
The sample rate is the number of samples per second output by this block on each channel.
|
||||
|
||||
Gain Mode:
|
||||
Chooses between the manual (default) and automatic gain mode where appropriate.
|
||||
To allow manual control of RF/IF/BB gain stages, manual gain mode must be configured.
|
||||
Currently, only RTL-SDR devices support automatic gain mode.
|
||||
Frequency:
|
||||
The center frequency is the frequency the RF chain is tuned to.
|
||||
|
||||
#end if
|
||||
RF Gain:
|
||||
Overall RF gain of the device.
|
||||
Freq. Corr.:
|
||||
The frequency correction factor in parts per million (ppm). Set to 0 if unknown.
|
||||
|
||||
IF Gain:
|
||||
Overall intermediate frequency gain of the device.
|
||||
This setting is available for RTL-SDR and OsmoSDR devices with E4000 tuners and HackRF Jawbreaker in receive and transmit mode. Observations lead to a reasonable gain range from 15 to 30dB.
|
||||
% if sourk == 'source':
|
||||
DC Offset Mode:
|
||||
Controls the behavior of hardware DC offset corrrection.
|
||||
Off: Disable correction algorithm (pass through).
|
||||
Manual: Keep last estimated correction when switched from Automatic to Manual.
|
||||
Automatic: Periodicallly find the best solution to compensate for DC offset.
|
||||
|
||||
BB Gain:
|
||||
Overall baseband gain of the device.
|
||||
This setting is available for HackRF Jawbreaker in receive mode. Observations lead to a reasonable gain range from 15 to 30dB.
|
||||
This functionality is available for USRP devices only.
|
||||
|
||||
Antenna:
|
||||
For devices with only one antenna, this may be left blank.
|
||||
Otherwise, the user should specify one of the possible antenna choices.
|
||||
IQ Balance Mode:
|
||||
Controls the behavior of software IQ imbalance corrrection.
|
||||
Off: Disable correction algorithm (pass through).
|
||||
Manual: Keep last estimated correction when switched from Automatic to Manual.
|
||||
Automatic: Periodicallly find the best solution to compensate for image signals.
|
||||
|
||||
Bandwidth:
|
||||
Set the bandpass filter on the radio frontend. To use the default (automatic) bandwidth filter setting, this should be zero.
|
||||
This functionality depends on http://cgit.osmocom.org/cgit/gr-iqbal/
|
||||
|
||||
See the OsmoSDR project page for more detailed documentation:
|
||||
http://sdr.osmocom.org/trac/wiki/GrOsmoSDR
|
||||
http://sdr.osmocom.org/trac/wiki/rtl-sdr
|
||||
http://sdr.osmocom.org/trac/
|
||||
</doc>
|
||||
</block>
|
||||
Gain Mode:
|
||||
Chooses between the manual (default) and automatic gain mode where appropriate.
|
||||
To allow manual control of RF/IF/BB gain stages, manual gain mode must be configured.
|
||||
Currently, only RTL-SDR devices support automatic gain mode.
|
||||
|
||||
% endif
|
||||
RF Gain:
|
||||
Overall RF gain of the device.
|
||||
|
||||
IF Gain:
|
||||
Overall intermediate frequency gain of the device.
|
||||
This setting is available for RTL-SDR and OsmoSDR devices with E4000 tuners and HackRF in receive and transmit mode. Observations lead to a reasonable gain range from 15 to 30dB.
|
||||
|
||||
BB Gain:
|
||||
Overall baseband gain of the device.
|
||||
This setting is available for HackRF in receive mode. Observations lead to a reasonable gain range from 15 to 30dB.
|
||||
|
||||
Antenna:
|
||||
For devices with only one antenna, this may be left blank.
|
||||
Otherwise, the user should specify one of the possible antenna choices.
|
||||
|
||||
Bandwidth:
|
||||
Set the bandpass filter on the radio frontend. To use the default (automatic) bandwidth filter setting, this should be zero.
|
||||
|
||||
See the OsmoSDR project page for more detailed documentation:
|
||||
http://sdr.osmocom.org/trac/wiki/GrOsmoSDR
|
||||
http://sdr.osmocom.org/trac/wiki/rtl-sdr
|
||||
http://sdr.osmocom.org/trac/
|
||||
|
||||
file_format: 1
|
||||
"""
|
||||
|
||||
# MAIN_TMPL = """\
|
||||
# <block>
|
||||
# <check>$max_nchan >= \$nchan</check>
|
||||
# <check>\$nchan > 0</check>
|
||||
# <check>$max_mboards >= \$num_mboards</check>
|
||||
# <check>\$num_mboards > 0</check>
|
||||
# <check>\$nchan >= \$num_mboards</check>
|
||||
# </block>
|
||||
# """
|
||||
|
||||
PARAMS_TMPL = """
|
||||
<param>
|
||||
<name>Ch$(n): Frequency (Hz)</name>
|
||||
<key>freq$(n)</key>
|
||||
<value>100e6</value>
|
||||
<type>real</type>
|
||||
<hide>\#if \$nchan() > $n then 'none' else 'all'#</hide>
|
||||
</param>
|
||||
<param>
|
||||
<name>Ch$(n): Freq. Corr. (ppm)</name>
|
||||
<key>corr$(n)</key>
|
||||
<value>0</value>
|
||||
<type>real</type>
|
||||
<hide>\#if \$nchan() > $n then 'none' else 'all'#</hide>
|
||||
</param>
|
||||
#if $sourk == 'source':
|
||||
<param>
|
||||
<name>Ch$(n): DC Offset Mode</name>
|
||||
<key>dc_offset_mode$(n)</key>
|
||||
<value>0</value>
|
||||
<type>int</type>
|
||||
<hide>\#if \$nchan() > $n then 'none' else 'all'#</hide>
|
||||
<option>
|
||||
<name>Off</name>
|
||||
<key>0</key>
|
||||
</option>
|
||||
<option>
|
||||
<name>Manual</name>
|
||||
<key>1</key>
|
||||
</option>
|
||||
<option>
|
||||
<name>Automatic</name>
|
||||
<key>2</key>
|
||||
</option>
|
||||
</param>
|
||||
<param>
|
||||
<name>Ch$(n): IQ Balance Mode</name>
|
||||
<key>iq_balance_mode$(n)</key>
|
||||
<value>0</value>
|
||||
<type>int</type>
|
||||
<hide>\#if \$nchan() > $n then 'none' else 'all'#</hide>
|
||||
<option>
|
||||
<name>Off</name>
|
||||
<key>0</key>
|
||||
</option>
|
||||
<option>
|
||||
<name>Manual</name>
|
||||
<key>1</key>
|
||||
</option>
|
||||
<option>
|
||||
<name>Automatic</name>
|
||||
<key>2</key>
|
||||
</option>
|
||||
</param>
|
||||
<param>
|
||||
<name>Ch$(n): Gain Mode</name>
|
||||
<key>gain_mode$(n)</key>
|
||||
<value>False</value>
|
||||
<type>bool</type>
|
||||
<hide>\#if \$nchan() > $n then 'none' else 'all'#</hide>
|
||||
<option>
|
||||
<name>Manual</name>
|
||||
<key>False</key>
|
||||
</option>
|
||||
<option>
|
||||
<name>Automatic</name>
|
||||
<key>True</key>
|
||||
</option>
|
||||
</param>
|
||||
#end if
|
||||
<param>
|
||||
<name>Ch$(n): RF Gain (dB)</name>
|
||||
<key>gain$(n)</key>
|
||||
<value>10</value>
|
||||
<type>real</type>
|
||||
<hide>\#if \$nchan() > $n then 'none' else 'all'#</hide>
|
||||
</param>
|
||||
<param>
|
||||
<name>Ch$(n): IF Gain (dB)</name>
|
||||
<key>if_gain$(n)</key>
|
||||
<value>20</value>
|
||||
<type>real</type>
|
||||
<hide>\#if \$nchan() > $n then 'none' else 'all'#</hide>
|
||||
</param>
|
||||
<param>
|
||||
<name>Ch$(n): BB Gain (dB)</name>
|
||||
<key>bb_gain$(n)</key>
|
||||
<value>20</value>
|
||||
<type>real</type>
|
||||
<hide>\#if \$nchan() > $n then 'none' else 'all'#</hide>
|
||||
</param>
|
||||
<param>
|
||||
<name>Ch$(n): Antenna</name>
|
||||
<key>ant$(n)</key>
|
||||
<value></value>
|
||||
<type>string</type>
|
||||
<hide>
|
||||
\#if not \$nchan() > $n
|
||||
all
|
||||
\#elif \$ant$(n)()
|
||||
none
|
||||
\#else
|
||||
part
|
||||
\#end if
|
||||
</hide>
|
||||
</param>
|
||||
<param>
|
||||
<name>Ch$(n): Bandwidth (Hz)</name>
|
||||
<key>bw$(n)</key>
|
||||
<value>0</value>
|
||||
<type>real</type>
|
||||
<hide>
|
||||
\#if not \$nchan() > $n
|
||||
all
|
||||
\#elif \$bw$(n)()
|
||||
none
|
||||
\#else
|
||||
part
|
||||
\#end if
|
||||
</hide>
|
||||
</param>
|
||||
- id: freq${n}
|
||||
label: 'Ch${n}: Frequency (Hz)'
|
||||
dtype: real
|
||||
default: 100e6
|
||||
hide: ${'$'}{'none' if (nchan > ${n}) else 'all'}
|
||||
- id: corr${n}
|
||||
label: 'Ch${n}: Frequency Correction (ppm)'
|
||||
dtype: real
|
||||
default: 0
|
||||
hide: ${'$'}{'none' if (nchan > ${n}) else 'all'}
|
||||
% if sourk == 'source':
|
||||
- id: dc_offset_mode${n}
|
||||
label: 'Ch${n}: DC Offset Mode'
|
||||
dtype: int
|
||||
default: 0
|
||||
options: [0, 1, 2]
|
||||
option_labels: [Off, Manual, Automatic]
|
||||
hide: ${'$'}{'none' if (nchan > ${n}) else 'all'}
|
||||
- id: iq_balance_mode${n}
|
||||
label: 'Ch${n}: IQ Balance Mode'
|
||||
dtype: int
|
||||
default: 0
|
||||
options: [0, 1, 2]
|
||||
option_labels: [Off, Manual, Automatic]
|
||||
hide: ${'$'}{'none' if (nchan > ${n}) else 'all'}
|
||||
- id: gain_mode${n}
|
||||
label: 'Ch${n}: Gain Mode'
|
||||
dtype: bool
|
||||
default: False
|
||||
options: [False, True]
|
||||
option_labels: [Manual, Automatic]
|
||||
hide: ${'$'}{'none' if (nchan > ${n}) else 'all'}
|
||||
% endif
|
||||
- id: gain${n}
|
||||
label: 'Ch${n}: RF Gain (dB)'
|
||||
dtype: real
|
||||
default: 10
|
||||
hide: ${'$'}{'none' if (nchan > ${n}) else 'all'}
|
||||
- id: if_gain${n}
|
||||
label: 'Ch${n}: IF Gain (dB)'
|
||||
dtype: real
|
||||
default: 20
|
||||
hide: ${'$'}{'none' if (nchan > ${n}) else 'all'}
|
||||
- id: bb_gain${n}
|
||||
label: 'Ch${n}: BB Gain (dB)'
|
||||
dtype: real
|
||||
default: 20
|
||||
hide: ${'$'}{'none' if (nchan > ${n}) else 'all'}
|
||||
- id: ant${n}
|
||||
label: 'Ch${n}: Antenna'
|
||||
dtype: string
|
||||
default: ""
|
||||
hide: ${'$'}{'all' if not (nchan > ${n}) else ('none' if eval('ant' + str(${n})) else 'part')}
|
||||
- id: bw${n}
|
||||
label: 'Ch${n}: Bandwidth (Hz)'
|
||||
dtype: real
|
||||
default: 0
|
||||
hide: ${'$'}{'all' if not (nchan > ${n}) else ('none' if eval('bw' + str(${n})) else 'part')}
|
||||
"""
|
||||
|
||||
def parse_tmpl(_tmpl, **kwargs):
|
||||
from Cheetah import Template
|
||||
return str(Template.Template(_tmpl, kwargs))
|
||||
|
||||
max_num_channels = 5
|
||||
def parse_tmpl(_tmpl, **kwargs):
|
||||
from mako.template import Template
|
||||
from mako import exceptions
|
||||
|
||||
try:
|
||||
block_template = Template(_tmpl)
|
||||
return str(block_template.render(**kwargs))
|
||||
except:
|
||||
print(exceptions.text_error_template().render())
|
||||
|
||||
MAX_NUM_MBOARDS = 8
|
||||
MAX_NUM_CHANNELS = MAX_NUM_MBOARDS * 4
|
||||
|
||||
import os.path
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
for file in sys.argv[1:]:
|
||||
head, tail = os.path.split(file)
|
||||
import sys
|
||||
|
||||
if tail.startswith('rtlsdr'):
|
||||
title = 'RTL-SDR'
|
||||
prefix = 'rtlsdr'
|
||||
elif tail.startswith('osmosdr'):
|
||||
title = 'osmocom'
|
||||
prefix = 'osmosdr'
|
||||
else: raise Exception, 'file %s has wrong syntax!'%tail
|
||||
for file in sys.argv[1:]:
|
||||
head, tail = os.path.split(file)
|
||||
|
||||
if tail.endswith ('source.xml'):
|
||||
sourk = 'source'
|
||||
dir = 'out'
|
||||
elif tail.endswith ('sink.xml'):
|
||||
sourk = 'sink'
|
||||
dir = 'in'
|
||||
else: raise Exception, 'is %s a source or sink?'%file
|
||||
if tail.startswith('rtlsdr'):
|
||||
title = 'RTL-SDR'
|
||||
prefix = 'rtlsdr'
|
||||
elif tail.startswith('osmosdr'):
|
||||
title = 'osmocom'
|
||||
prefix = 'osmosdr'
|
||||
else:
|
||||
raise Exception("file {} has wrong syntax!".format(tail))
|
||||
|
||||
params = ''.join([parse_tmpl(PARAMS_TMPL, n=n, sourk=sourk) for n in range(max_num_channels)])
|
||||
open(file, 'w').write(parse_tmpl(MAIN_TMPL,
|
||||
max_nchan=max_num_channels,
|
||||
params=params,
|
||||
title=title,
|
||||
prefix=prefix,
|
||||
sourk=sourk,
|
||||
dir=dir,
|
||||
))
|
||||
if tail.endswith('source.block.yml'):
|
||||
sourk = 'source'
|
||||
direction = 'out'
|
||||
elif tail.endswith('sink.block.yml'):
|
||||
sourk = 'sink'
|
||||
direction = 'in'
|
||||
else:
|
||||
raise Exception("is {} a source or sink?".format(file))
|
||||
|
||||
params = ''.join([
|
||||
parse_tmpl(PARAMS_TMPL, n=n, sourk=sourk)
|
||||
for n in range(MAX_NUM_CHANNELS)
|
||||
])
|
||||
|
||||
open(file, 'w').write(
|
||||
parse_tmpl(
|
||||
MAIN_TMPL,
|
||||
max_nchan=MAX_NUM_CHANNELS,
|
||||
max_mboards=MAX_NUM_MBOARDS,
|
||||
params=params,
|
||||
title=title,
|
||||
prefix=prefix,
|
||||
sourk=sourk,
|
||||
direction=direction,
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
# Copyright 2011 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file is part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# gr-osmosdr 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio is distributed in the hope that it will be useful,
|
||||
# gr-osmosdr 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# along with gr-osmosdr; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
|
@ -24,6 +24,7 @@ install(FILES
|
|||
api.h
|
||||
pimpl.h
|
||||
ranges.h
|
||||
time_spec.h
|
||||
device.h
|
||||
source.h
|
||||
sink.h
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#ifndef INCLUDED_OSMOSDR_PIMPL_H
|
||||
#define INCLUDED_OSMOSDR_PIMPL_H
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <memory>
|
||||
|
||||
/*! \file pimpl.h
|
||||
* "Pimpl idiom" (pointer to implementation idiom).
|
||||
|
@ -39,7 +39,7 @@
|
|||
* \param _name the name of the pimpl class
|
||||
*/
|
||||
#define OSMOSDR_PIMPL_DECL(_name) \
|
||||
struct _name; boost::shared_ptr<_name>
|
||||
struct _name; std::shared_ptr<_name>
|
||||
|
||||
/*!
|
||||
* Make an instance of a pimpl in a source file.
|
||||
|
@ -49,6 +49,6 @@
|
|||
* \param _args the constructor args for the pimpl
|
||||
*/
|
||||
#define OSMOSDR_PIMPL_MAKE(_name, _args) \
|
||||
boost::shared_ptr<_name>(new _name _args)
|
||||
std::shared_ptr<_name>(new _name _args)
|
||||
|
||||
#endif /* INCLUDED_OSMOSDR_PIMPL_H */
|
||||
|
|
|
@ -25,6 +25,12 @@
|
|||
|
||||
namespace osmosdr{
|
||||
|
||||
//! A wildcard motherboard index
|
||||
static const size_t ALL_MBOARDS = size_t(~0);
|
||||
|
||||
//! A wildcard channel index
|
||||
static const size_t ALL_CHANS = size_t(~0);
|
||||
|
||||
/*!
|
||||
* A range object describes a set of discrete values of the form:
|
||||
* y = start + step*n, where n is an integer between 0 and (stop - start)/step
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <osmosdr/api.h>
|
||||
#include <osmosdr/ranges.h>
|
||||
#include <osmosdr/time_spec.h>
|
||||
#include <gnuradio/hier_block2.h>
|
||||
|
||||
namespace osmosdr {
|
||||
|
@ -37,7 +38,7 @@ class sink;
|
|||
class OSMOSDR_API sink : virtual public gr::hier_block2
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr< sink > sptr;
|
||||
typedef std::shared_ptr< sink > sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of sink.
|
||||
|
@ -273,6 +274,103 @@ public:
|
|||
* \return a range of bandwidths in Hz
|
||||
*/
|
||||
virtual osmosdr::freq_range_t get_bandwidth_range( size_t chan = 0 ) = 0;
|
||||
|
||||
/*!
|
||||
* Set the time source for the device.
|
||||
* This sets the method of time synchronization,
|
||||
* typically a pulse per second or an encoded time.
|
||||
* Typical options for source: external, MIMO.
|
||||
* \param source a string representing the time source
|
||||
* \param mboard which motherboard to set the config
|
||||
*/
|
||||
virtual void set_time_source(const std::string &source,
|
||||
const size_t mboard = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Get the currently set time source.
|
||||
* \param mboard which motherboard to get the config
|
||||
* \return the string representing the time source
|
||||
*/
|
||||
virtual std::string get_time_source(const size_t mboard) = 0;
|
||||
|
||||
/*!
|
||||
* Get a list of possible time sources.
|
||||
* \param mboard which motherboard to get the list
|
||||
* \return a vector of strings for possible settings
|
||||
*/
|
||||
virtual std::vector<std::string> get_time_sources(const size_t mboard) = 0;
|
||||
|
||||
/*!
|
||||
* Set the clock source for the device.
|
||||
* This sets the source for a 10 Mhz reference clock.
|
||||
* Typical options for source: internal, external, MIMO.
|
||||
* \param source a string representing the clock source
|
||||
* \param mboard which motherboard to set the config
|
||||
*/
|
||||
virtual void set_clock_source(const std::string &source,
|
||||
const size_t mboard = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Get the currently set clock source.
|
||||
* \param mboard which motherboard to get the config
|
||||
* \return the string representing the clock source
|
||||
*/
|
||||
virtual std::string get_clock_source(const size_t mboard) = 0;
|
||||
|
||||
/*!
|
||||
* Get a list of possible clock sources.
|
||||
* \param mboard which motherboard to get the list
|
||||
* \return a vector of strings for possible settings
|
||||
*/
|
||||
virtual std::vector<std::string> get_clock_sources(const size_t mboard) = 0;
|
||||
|
||||
/*!
|
||||
* Get the master clock rate.
|
||||
* \param mboard the motherboard index 0 to M-1
|
||||
* \return the clock rate in Hz
|
||||
*/
|
||||
virtual double get_clock_rate(size_t mboard = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Set the master clock rate.
|
||||
* \param rate the new rate in Hz
|
||||
* \param mboard the motherboard index 0 to M-1
|
||||
*/
|
||||
virtual void set_clock_rate(double rate, size_t mboard = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Get the current time registers.
|
||||
* \param mboard the motherboard index 0 to M-1
|
||||
* \return the current device time
|
||||
*/
|
||||
virtual ::osmosdr::time_spec_t get_time_now(size_t mboard = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Get the time when the last pps pulse occured.
|
||||
* \param mboard the motherboard index 0 to M-1
|
||||
* \return the current device time
|
||||
*/
|
||||
virtual ::osmosdr::time_spec_t get_time_last_pps(size_t mboard = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Sets the time registers immediately.
|
||||
* \param time_spec the new time
|
||||
* \param mboard the motherboard index 0 to M-1
|
||||
*/
|
||||
virtual void set_time_now(const ::osmosdr::time_spec_t &time_spec,
|
||||
size_t mboard = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Set the time registers at the next pps.
|
||||
* \param time_spec the new time
|
||||
*/
|
||||
virtual void set_time_next_pps(const ::osmosdr::time_spec_t &time_spec) = 0;
|
||||
|
||||
/*!
|
||||
* Sync the time registers with an unknown pps edge.
|
||||
* \param time_spec the new time
|
||||
*/
|
||||
virtual void set_time_unknown_pps(const ::osmosdr::time_spec_t &time_spec) = 0;
|
||||
};
|
||||
|
||||
} /* namespace osmosdr */
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <osmosdr/api.h>
|
||||
#include <osmosdr/ranges.h>
|
||||
#include <osmosdr/time_spec.h>
|
||||
#include <gnuradio/hier_block2.h>
|
||||
|
||||
namespace osmosdr {
|
||||
|
@ -37,7 +38,7 @@ class source;
|
|||
class OSMOSDR_API source : virtual public gr::hier_block2
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr< source > sptr;
|
||||
typedef std::shared_ptr< source > sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of source.
|
||||
|
@ -62,6 +63,7 @@ public:
|
|||
*
|
||||
* \param seek_point sample offset in file
|
||||
* \param whence one of SEEK_SET, SEEK_CUR, SEEK_END (man fseek)
|
||||
* \param chan the channel index 0 to N-1
|
||||
* \return true on success
|
||||
*/
|
||||
virtual bool seek( long seek_point, int whence, size_t chan = 0 ) = 0;
|
||||
|
@ -317,6 +319,103 @@ public:
|
|||
* \return a range of bandwidths in Hz
|
||||
*/
|
||||
virtual osmosdr::freq_range_t get_bandwidth_range( size_t chan = 0 ) = 0;
|
||||
|
||||
/*!
|
||||
* Set the time source for the device.
|
||||
* This sets the method of time synchronization,
|
||||
* typically a pulse per second or an encoded time.
|
||||
* Typical options for source: external, MIMO.
|
||||
* \param source a string representing the time source
|
||||
* \param mboard which motherboard to set the config
|
||||
*/
|
||||
virtual void set_time_source(const std::string &source,
|
||||
const size_t mboard = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Get the currently set time source.
|
||||
* \param mboard which motherboard to get the config
|
||||
* \return the string representing the time source
|
||||
*/
|
||||
virtual std::string get_time_source(const size_t mboard) = 0;
|
||||
|
||||
/*!
|
||||
* Get a list of possible time sources.
|
||||
* \param mboard which motherboard to get the list
|
||||
* \return a vector of strings for possible settings
|
||||
*/
|
||||
virtual std::vector<std::string> get_time_sources(const size_t mboard) = 0;
|
||||
|
||||
/*!
|
||||
* Set the clock source for the device.
|
||||
* This sets the source for a 10 Mhz reference clock.
|
||||
* Typical options for source: internal, external, MIMO.
|
||||
* \param source a string representing the clock source
|
||||
* \param mboard which motherboard to set the config
|
||||
*/
|
||||
virtual void set_clock_source(const std::string &source,
|
||||
const size_t mboard = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Get the currently set clock source.
|
||||
* \param mboard which motherboard to get the config
|
||||
* \return the string representing the clock source
|
||||
*/
|
||||
virtual std::string get_clock_source(const size_t mboard) = 0;
|
||||
|
||||
/*!
|
||||
* Get a list of possible clock sources.
|
||||
* \param mboard which motherboard to get the list
|
||||
* \return a vector of strings for possible settings
|
||||
*/
|
||||
virtual std::vector<std::string> get_clock_sources(const size_t mboard) = 0;
|
||||
|
||||
/*!
|
||||
* Get the master clock rate.
|
||||
* \param mboard the motherboard index 0 to M-1
|
||||
* \return the clock rate in Hz
|
||||
*/
|
||||
virtual double get_clock_rate(size_t mboard = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Set the master clock rate.
|
||||
* \param rate the new rate in Hz
|
||||
* \param mboard the motherboard index 0 to M-1
|
||||
*/
|
||||
virtual void set_clock_rate(double rate, size_t mboard = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Get the current time registers.
|
||||
* \param mboard the motherboard index 0 to M-1
|
||||
* \return the current device time
|
||||
*/
|
||||
virtual ::osmosdr::time_spec_t get_time_now(size_t mboard = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Get the time when the last pps pulse occured.
|
||||
* \param mboard the motherboard index 0 to M-1
|
||||
* \return the current device time
|
||||
*/
|
||||
virtual ::osmosdr::time_spec_t get_time_last_pps(size_t mboard = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Sets the time registers immediately.
|
||||
* \param time_spec the new time
|
||||
* \param mboard the motherboard index 0 to M-1
|
||||
*/
|
||||
virtual void set_time_now(const ::osmosdr::time_spec_t &time_spec,
|
||||
size_t mboard = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Set the time registers at the next pps.
|
||||
* \param time_spec the new time
|
||||
*/
|
||||
virtual void set_time_next_pps(const ::osmosdr::time_spec_t &time_spec) = 0;
|
||||
|
||||
/*!
|
||||
* Sync the time registers with an unknown pps edge.
|
||||
* \param time_spec the new time
|
||||
*/
|
||||
virtual void set_time_unknown_pps(const ::osmosdr::time_spec_t &time_spec) = 0;
|
||||
};
|
||||
|
||||
} /* namespace osmosdr */
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
//
|
||||
// Copyright 2010-2012 Ettus Research LLC
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
#ifndef INCLUDED_OSMOSDR_TIME_SPEC_H
|
||||
#define INCLUDED_OSMOSDR_TIME_SPEC_H
|
||||
|
||||
#include <osmosdr/api.h>
|
||||
#include <boost/operators.hpp>
|
||||
#include <ctime>
|
||||
|
||||
namespace osmosdr{
|
||||
|
||||
/*!
|
||||
* A time_spec_t holds a seconds and a fractional seconds time value.
|
||||
* Depending upon usage, the time_spec_t can represent absolute times,
|
||||
* relative times, or time differences (between absolute times).
|
||||
*
|
||||
* The time_spec_t provides clock-domain independent time storage,
|
||||
* but can convert fractional seconds to/from clock-domain specific units.
|
||||
*
|
||||
* The fractional seconds are stored as double precision floating point.
|
||||
* This gives the fractional seconds enough precision to unambiguously
|
||||
* specify a clock-tick/sample-count up to rates of several petahertz.
|
||||
*/
|
||||
class OSMOSDR_API time_spec_t : boost::additive<time_spec_t>, boost::totally_ordered<time_spec_t>{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* Get the system time in time_spec_t format.
|
||||
* Uses the highest precision clock available.
|
||||
* \return the system time as a time_spec_t
|
||||
*/
|
||||
static time_spec_t get_system_time(void);
|
||||
|
||||
/*!
|
||||
* Create a time_spec_t from a real-valued seconds count.
|
||||
* \param secs the real-valued seconds count (default = 0)
|
||||
*/
|
||||
time_spec_t(double secs = 0);
|
||||
|
||||
/*!
|
||||
* Create a time_spec_t from whole and fractional seconds.
|
||||
* \param full_secs the whole/integer seconds count
|
||||
* \param frac_secs the fractional seconds count (default = 0)
|
||||
*/
|
||||
time_spec_t(time_t full_secs, double frac_secs = 0);
|
||||
|
||||
/*!
|
||||
* Create a time_spec_t from whole seconds and fractional ticks.
|
||||
* Translation from clock-domain specific units.
|
||||
* \param full_secs the whole/integer seconds count
|
||||
* \param tick_count the fractional seconds tick count
|
||||
* \param tick_rate the number of ticks per second
|
||||
*/
|
||||
time_spec_t(time_t full_secs, long tick_count, double tick_rate);
|
||||
|
||||
/*!
|
||||
* Create a time_spec_t from a 64-bit tick count.
|
||||
* Translation from clock-domain specific units.
|
||||
* \param ticks an integer count of ticks
|
||||
* \param tick_rate the number of ticks per second
|
||||
*/
|
||||
static time_spec_t from_ticks(long long ticks, double tick_rate);
|
||||
|
||||
/*!
|
||||
* Convert the fractional seconds to clock ticks.
|
||||
* Translation into clock-domain specific units.
|
||||
* \param tick_rate the number of ticks per second
|
||||
* \return the fractional seconds tick count
|
||||
*/
|
||||
long get_tick_count(double tick_rate) const;
|
||||
|
||||
/*!
|
||||
* Convert the time spec into a 64-bit tick count.
|
||||
* Translation into clock-domain specific units.
|
||||
* \param tick_rate the number of ticks per second
|
||||
* \return an integer number of ticks
|
||||
*/
|
||||
long long to_ticks(const double tick_rate) const;
|
||||
|
||||
/*!
|
||||
* Get the time as a real-valued seconds count.
|
||||
* Note: If this time_spec_t represents an absolute time,
|
||||
* the precision of the fractional seconds may be lost.
|
||||
* \return the real-valued seconds
|
||||
*/
|
||||
double get_real_secs(void) const;
|
||||
|
||||
/*!
|
||||
* Get the whole/integer part of the time in seconds.
|
||||
* \return the whole/integer seconds
|
||||
*/
|
||||
time_t get_full_secs(void) const;
|
||||
|
||||
/*!
|
||||
* Get the fractional part of the time in seconds.
|
||||
* \return the fractional seconds
|
||||
*/
|
||||
double get_frac_secs(void) const;
|
||||
|
||||
//! Implement addable interface
|
||||
time_spec_t &operator+=(const time_spec_t &);
|
||||
|
||||
//! Implement subtractable interface
|
||||
time_spec_t &operator-=(const time_spec_t &);
|
||||
|
||||
//private time storage details
|
||||
private: time_t _full_secs; double _frac_secs;
|
||||
};
|
||||
|
||||
//! Implement equality_comparable interface
|
||||
OSMOSDR_API bool operator==(const time_spec_t &, const time_spec_t &);
|
||||
|
||||
//! Implement less_than_comparable interface
|
||||
OSMOSDR_API bool operator<(const time_spec_t &, const time_spec_t &);
|
||||
|
||||
inline time_t time_spec_t::get_full_secs(void) const{
|
||||
return this->_full_secs;
|
||||
}
|
||||
|
||||
inline double time_spec_t::get_frac_secs(void) const{
|
||||
return this->_frac_secs;
|
||||
}
|
||||
|
||||
} //namespace osmosdr
|
||||
|
||||
#endif /* INCLUDED_OSMOSDR_TIME_SPEC_H */
|
|
@ -1,91 +1,154 @@
|
|||
# Copyright 2011 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file is part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# gr-osmosdr 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio is distributed in the hope that it will be useful,
|
||||
# gr-osmosdr 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# along with gr-osmosdr; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
########################################################################
|
||||
# Setup library
|
||||
########################################################################
|
||||
INCLUDE(GrPlatform) #define LIB_SUFFIX
|
||||
INCLUDE(GrMiscUtils)
|
||||
INCLUDE(GrComponent)
|
||||
include(GrPlatform) #define LIB_SUFFIX
|
||||
|
||||
########################################################################
|
||||
# Helpful Macros
|
||||
# Setup target
|
||||
########################################################################
|
||||
MACRO(GR_OSMOSDR_APPEND_SRCS)
|
||||
LIST(APPEND gr_osmosdr_srcs ${ARGV})
|
||||
ENDMACRO(GR_OSMOSDR_APPEND_SRCS)
|
||||
|
||||
MACRO(GR_OSMOSDR_APPEND_LIBS)
|
||||
LIST(APPEND gr_osmosdr_libs ${ARGV})
|
||||
ENDMACRO(GR_OSMOSDR_APPEND_LIBS)
|
||||
|
||||
GR_OSMOSDR_APPEND_SRCS(
|
||||
list(APPEND gr_osmosdr_srcs
|
||||
source_impl.cc
|
||||
sink_impl.cc
|
||||
ranges.cc
|
||||
device.cc
|
||||
time_spec.cc
|
||||
)
|
||||
|
||||
GR_OSMOSDR_APPEND_LIBS(
|
||||
${Boost_LIBRARIES}
|
||||
${GNURADIO_ALL_LIBRARIES}
|
||||
#-pthread Adds support for multithreading with the pthreads library.
|
||||
#This option sets flags for both the preprocessor and linker. (man gcc)
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
list(APPEND Boost_LIBRARIES -pthread)
|
||||
endif()
|
||||
|
||||
#dirty macro to allow appending from subdirs
|
||||
#this appends all unnamed implicit macro args!
|
||||
MACRO (APPEND_LIB_LIST)
|
||||
SET (gr_osmosdr_libs "${gr_osmosdr_libs};${ARGN}" CACHE INTERNAL "lib list")
|
||||
ENDMACRO (APPEND_LIB_LIST)
|
||||
|
||||
set(gr_osmosdr_libs "" CACHE INTERNAL "lib that accumulates link targets")
|
||||
|
||||
add_library(gnuradio-osmosdr SHARED)
|
||||
APPEND_LIB_LIST(${Boost_LIBRARIES} gnuradio::gnuradio-runtime)
|
||||
target_include_directories(gnuradio-osmosdr
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
PUBLIC ${Boost_INCLUDE_DIRS}
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
|
||||
PUBLIC $<INSTALL_INTERFACE:include>
|
||||
)
|
||||
set_target_properties(gnuradio-osmosdr PROPERTIES DEFINE_SYMBOL "gnuradio_osmosdr_EXPORTS")
|
||||
|
||||
if(APPLE)
|
||||
set_target_properties(gnuradio-osmosdr PROPERTIES
|
||||
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib"
|
||||
)
|
||||
endif(APPLE)
|
||||
|
||||
########################################################################
|
||||
# Setup defines for high resolution timing
|
||||
########################################################################
|
||||
message(STATUS "")
|
||||
message(STATUS "Configuring high resolution timing...")
|
||||
include(CheckCXXSourceCompiles)
|
||||
|
||||
set(CMAKE_REQUIRED_LIBRARIES -lrt)
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <ctime>
|
||||
int main(){
|
||||
timespec ts;
|
||||
return clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
}
|
||||
" HAVE_CLOCK_GETTIME
|
||||
)
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <mach/mach_time.h>
|
||||
int main(){
|
||||
mach_timebase_info_data_t info;
|
||||
mach_timebase_info(&info);
|
||||
mach_absolute_time();
|
||||
return 0;
|
||||
}
|
||||
" HAVE_MACH_ABSOLUTE_TIME
|
||||
)
|
||||
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <Windows.h>
|
||||
int main(){
|
||||
LARGE_INTEGER value;
|
||||
QueryPerformanceCounter(&value);
|
||||
QueryPerformanceFrequency(&value);
|
||||
return 0;
|
||||
}
|
||||
" HAVE_QUERY_PERFORMANCE_COUNTER
|
||||
)
|
||||
|
||||
if(HAVE_CLOCK_GETTIME)
|
||||
message(STATUS " High resolution timing supported through clock_gettime.")
|
||||
set(TIME_SPEC_DEFS HAVE_CLOCK_GETTIME)
|
||||
APPEND_LIB_LIST( "-lrt")
|
||||
elseif(HAVE_MACH_ABSOLUTE_TIME)
|
||||
message(STATUS " High resolution timing supported through mach_absolute_time.")
|
||||
set(TIME_SPEC_DEFS HAVE_MACH_ABSOLUTE_TIME)
|
||||
elseif(HAVE_QUERY_PERFORMANCE_COUNTER)
|
||||
message(STATUS " High resolution timing supported through QueryPerformanceCounter.")
|
||||
set(TIME_SPEC_DEFS HAVE_QUERY_PERFORMANCE_COUNTER)
|
||||
else()
|
||||
message(STATUS " High resolution timing supported through microsec_clock.")
|
||||
set(TIME_SPEC_DEFS HAVE_MICROSEC_CLOCK)
|
||||
endif()
|
||||
|
||||
set_source_files_properties(
|
||||
time_spec.cc
|
||||
PROPERTIES COMPILE_DEFINITIONS "${TIME_SPEC_DEFS}"
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Setup IQBalance component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("Osmocom IQ Imbalance Correction" ENABLE_IQBALANCE GNURADIO_IQBALANCE_FOUND)
|
||||
GR_REGISTER_COMPONENT("Osmocom IQ Imbalance Correction" ENABLE_IQBALANCE gnuradio-iqbalance_FOUND)
|
||||
if(ENABLE_IQBALANCE)
|
||||
add_definitions(-DHAVE_IQBALANCE=1)
|
||||
include_directories(${GNURADIO_IQBALANCE_INCLUDE_DIRS})
|
||||
GR_OSMOSDR_APPEND_LIBS(${GNURADIO_IQBALANCE_LIBRARIES})
|
||||
add_definitions(-DHAVE_IQBALANCE=1)
|
||||
target_include_directories(gnuradio-osmosdr PRIVATE ${gnuradio-iqbalance_INCLUDE_DIRS})
|
||||
APPEND_LIB_LIST( gnuradio::gnuradio-iqbalance)
|
||||
endif(ENABLE_IQBALANCE)
|
||||
|
||||
########################################################################
|
||||
# Setup OsmoSDR component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("sysmocom OsmoSDR" ENABLE_OSMOSDR LIBOSMOSDR_FOUND)
|
||||
if(ENABLE_OSMOSDR)
|
||||
GR_INCLUDE_SUBDIRECTORY(osmosdr)
|
||||
endif(ENABLE_OSMOSDR)
|
||||
|
||||
########################################################################
|
||||
# Setup FCD component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("FUNcube Dongle" ENABLE_FCD GNURADIO_FCD_FOUND)
|
||||
GR_REGISTER_COMPONENT("FUNcube Dongle Pro+" ENABLE_FCDPP GNURADIO_FCDPP_FOUND)
|
||||
GR_REGISTER_COMPONENT("FUNcube Dongle" ENABLE_FCD GNURADIO_FUNCUBE_FOUND)
|
||||
if(ENABLE_FCD)
|
||||
add_definitions(-DHAVE_FCD=1)
|
||||
add_subdirectory(fcd)
|
||||
endif(ENABLE_FCD)
|
||||
if(ENABLE_FCDPP)
|
||||
add_definitions(-DHAVE_FCDPP=1)
|
||||
endif(ENABLE_FCDPP)
|
||||
if(ENABLE_FCD OR ENABLE_FCDPP)
|
||||
GR_INCLUDE_SUBDIRECTORY(fcd)
|
||||
endif(ENABLE_FCD OR ENABLE_FCDPP)
|
||||
|
||||
########################################################################
|
||||
# Setup File component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("IQ File Source" ENABLE_FILE GNURADIO_BLOCKS_FOUND)
|
||||
GR_REGISTER_COMPONENT("IQ File Source & Sink" ENABLE_FILE gnuradio-blocks_FOUND)
|
||||
if(ENABLE_FILE)
|
||||
GR_INCLUDE_SUBDIRECTORY(file)
|
||||
add_subdirectory(file)
|
||||
endif(ENABLE_FILE)
|
||||
|
||||
########################################################################
|
||||
|
@ -93,39 +156,41 @@ endif(ENABLE_FILE)
|
|||
########################################################################
|
||||
GR_REGISTER_COMPONENT("Osmocom RTLSDR" ENABLE_RTL LIBRTLSDR_FOUND)
|
||||
if(ENABLE_RTL)
|
||||
GR_INCLUDE_SUBDIRECTORY(rtl)
|
||||
add_subdirectory(rtl)
|
||||
endif(ENABLE_RTL)
|
||||
|
||||
########################################################################
|
||||
# Setup RTL_TCP component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("RTLSDR TCP Client" ENABLE_RTL_TCP GNURADIO_BLOCKS_FOUND)
|
||||
GR_REGISTER_COMPONENT("RTLSDR TCP Client" ENABLE_RTL_TCP gnuradio-blocks_FOUND)
|
||||
if(ENABLE_RTL_TCP)
|
||||
GR_INCLUDE_SUBDIRECTORY(rtl_tcp)
|
||||
add_subdirectory(rtl_tcp)
|
||||
endif(ENABLE_RTL_TCP)
|
||||
|
||||
########################################################################
|
||||
# Setup UHD component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("Ettus USRP Devices" ENABLE_UHD UHD_FOUND GNURADIO_UHD_FOUND)
|
||||
GR_REGISTER_COMPONENT("Ettus USRP Devices" ENABLE_UHD UHD_FOUND gnuradio-uhd_FOUND)
|
||||
if(ENABLE_UHD)
|
||||
GR_INCLUDE_SUBDIRECTORY(uhd)
|
||||
add_subdirectory(uhd)
|
||||
endif(ENABLE_UHD)
|
||||
|
||||
########################################################################
|
||||
# Setup MiriSDR component
|
||||
# Setup SDRplay component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("Osmocom MiriSDR" ENABLE_MIRI LIBMIRISDR_FOUND)
|
||||
if(ENABLE_MIRI)
|
||||
GR_INCLUDE_SUBDIRECTORY(miri)
|
||||
endif(ENABLE_MIRI)
|
||||
if(ENABLE_NONFREE)
|
||||
GR_REGISTER_COMPONENT("SDRplay RSP (NONFREE)" ENABLE_SDRPLAY LIBSDRPLAY_FOUND)
|
||||
if(ENABLE_SDRPLAY)
|
||||
add_subdirectory(sdrplay)
|
||||
endif(ENABLE_SDRPLAY)
|
||||
endif(ENABLE_NONFREE)
|
||||
|
||||
########################################################################
|
||||
# Setup HackRF component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("HackRF Jawbreaker" ENABLE_HACKRF LIBHACKRF_FOUND)
|
||||
GR_REGISTER_COMPONENT("HackRF & rad1o Badge" ENABLE_HACKRF LIBHACKRF_FOUND)
|
||||
if(ENABLE_HACKRF)
|
||||
GR_INCLUDE_SUBDIRECTORY(hackrf)
|
||||
add_subdirectory(hackrf)
|
||||
endif(ENABLE_HACKRF)
|
||||
|
||||
########################################################################
|
||||
|
@ -133,7 +198,7 @@ endif(ENABLE_HACKRF)
|
|||
########################################################################
|
||||
GR_REGISTER_COMPONENT("nuand bladeRF" ENABLE_BLADERF LIBBLADERF_FOUND)
|
||||
if(ENABLE_BLADERF)
|
||||
GR_INCLUDE_SUBDIRECTORY(bladerf)
|
||||
add_subdirectory(bladerf)
|
||||
endif(ENABLE_BLADERF)
|
||||
|
||||
########################################################################
|
||||
|
@ -141,7 +206,7 @@ endif(ENABLE_BLADERF)
|
|||
########################################################################
|
||||
GR_REGISTER_COMPONENT("RFSPACE Receivers" ENABLE_RFSPACE)
|
||||
if(ENABLE_RFSPACE)
|
||||
GR_INCLUDE_SUBDIRECTORY(rfspace)
|
||||
add_subdirectory(rfspace)
|
||||
endif(ENABLE_RFSPACE)
|
||||
|
||||
########################################################################
|
||||
|
@ -149,37 +214,67 @@ endif(ENABLE_RFSPACE)
|
|||
########################################################################
|
||||
GR_REGISTER_COMPONENT("AIRSPY Receiver" ENABLE_AIRSPY LIBAIRSPY_FOUND)
|
||||
if(ENABLE_AIRSPY)
|
||||
GR_INCLUDE_SUBDIRECTORY(airspy)
|
||||
add_subdirectory(airspy)
|
||||
endif(ENABLE_AIRSPY)
|
||||
|
||||
########################################################################
|
||||
# Setup AIRSPYHF component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("AIRSPY HF+ Receiver" ENABLE_AIRSPYHF LIBAIRSPYHF_FOUND)
|
||||
if(ENABLE_AIRSPYHF)
|
||||
add_subdirectory(airspyhf)
|
||||
endif(ENABLE_AIRSPYHF)
|
||||
|
||||
########################################################################
|
||||
# Setup SoapySDR component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("SoapySDR support" ENABLE_SOAPY SoapySDR_FOUND)
|
||||
if(ENABLE_SOAPY)
|
||||
add_subdirectory(soapy)
|
||||
endif(ENABLE_SOAPY)
|
||||
|
||||
########################################################################
|
||||
# Setup Red Pitaya component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("Red Pitaya SDR" ENABLE_REDPITAYA)
|
||||
if(ENABLE_REDPITAYA)
|
||||
add_subdirectory(redpitaya)
|
||||
endif(ENABLE_REDPITAYA)
|
||||
|
||||
########################################################################
|
||||
# Setup FreeSRP component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("FreeSRP support" ENABLE_FREESRP LIBFREESRP_FOUND)
|
||||
if(ENABLE_FREESRP)
|
||||
add_subdirectory(freesrp)
|
||||
endif(ENABLE_FREESRP)
|
||||
|
||||
########################################################################
|
||||
# Setup XTRX component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("XTRX SDR" ENABLE_XTRX LIBXTRX_FOUND)
|
||||
if(ENABLE_XTRX)
|
||||
add_subdirectory(xtrx)
|
||||
endif(ENABLE_XTRX)
|
||||
|
||||
########################################################################
|
||||
# Setup configuration file
|
||||
########################################################################
|
||||
ADD_DEFINITIONS(-DHAVE_CONFIG_H=1)
|
||||
add_definitions(-DHAVE_CONFIG_H=1)
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
CONFIGURE_FILE(
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/config.h
|
||||
@ONLY)
|
||||
|
||||
########################################################################
|
||||
# Set up Windows DLL resource files
|
||||
# Finalize target
|
||||
########################################################################
|
||||
IF(MSVC)
|
||||
include(${CMAKE_SOURCE_DIR}/cmake/Modules/GrVersion.cmake)
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-osmosdr.rc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/gnuradio-osmosdr.rc
|
||||
@ONLY)
|
||||
|
||||
GR_OSMOSDR_APPEND_SRCS(${CMAKE_CURRENT_BINARY_DIR}/gnuradio-osmosdr.rc)
|
||||
ENDIF(MSVC)
|
||||
set_target_properties(gnuradio-osmosdr PROPERTIES SOURCES "${gr_osmosdr_srcs}")
|
||||
target_link_libraries(gnuradio-osmosdr ${gr_osmosdr_libs})
|
||||
|
||||
########################################################################
|
||||
# Setup libgnuradio-osmosdr library
|
||||
# Install built library files
|
||||
########################################################################
|
||||
ADD_LIBRARY(gnuradio-osmosdr SHARED ${gr_osmosdr_srcs})
|
||||
TARGET_LINK_LIBRARIES(gnuradio-osmosdr ${gr_osmosdr_libs})
|
||||
SET_TARGET_PROPERTIES(gnuradio-osmosdr PROPERTIES DEFINE_SYMBOL "gnuradio_osmosdr_EXPORTS")
|
||||
include(GrMiscUtils)
|
||||
GR_LIBRARY_FOO(gnuradio-osmosdr)
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
# Copyright 2012 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file is part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# gr-osmosdr 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio is distributed in the hope that it will be useful,
|
||||
# gr-osmosdr 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# along with gr-osmosdr; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
|
@ -21,17 +21,18 @@
|
|||
# This file included, use CMake directory variables
|
||||
########################################################################
|
||||
|
||||
include_directories(
|
||||
target_include_directories(gnuradio-osmosdr PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${LIBAIRSPY_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(airspy_srcs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/airspy_source_c.cc
|
||||
APPEND_LIB_LIST(
|
||||
gnuradio::gnuradio-filter
|
||||
${Gnuradio-blocks_LIBRARIES}
|
||||
${LIBAIRSPY_LIBRARIES}
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Append gnuradio-osmosdr library sources
|
||||
########################################################################
|
||||
list(APPEND gr_osmosdr_srcs ${airspy_srcs})
|
||||
list(APPEND gr_osmosdr_libs ${LIBAIRSPY_LIBRARIES} ${GNURADIO_FILTER_LIBRARIES} ${GNURADIO_BLOCKS_LIBRARIES})
|
||||
list(APPEND gr_osmosdr_srcs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/airspy_source_c.cc
|
||||
)
|
||||
set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
#pragma once
|
||||
|
||||
#define KERNEL_16_110_LEN 7
|
||||
const float KERNEL_16_110[] =
|
||||
{
|
||||
-0.031835079193115234f,
|
||||
0.000000000000000000f,
|
||||
0.281831502914428710f,
|
||||
0.500007271766662600f,
|
||||
0.281831502914428710f,
|
||||
0.000000000000000000f,
|
||||
-0.031835079193115234f
|
||||
};
|
||||
|
||||
#define KERNEL_8_100_LEN 11
|
||||
const float KERNEL_8_100[] =
|
||||
{
|
||||
0.006633400917053223f,
|
||||
0.000000000000000000f,
|
||||
-0.051035523414611816f,
|
||||
0.000000000000000000f,
|
||||
0.294403314590454100f,
|
||||
0.499997496604919430f,
|
||||
0.294403314590454100f,
|
||||
0.000000000000000000f,
|
||||
-0.051035523414611816f,
|
||||
0.000000000000000000f,
|
||||
0.006633400917053223f
|
||||
};
|
||||
|
||||
#define KERNEL_4_90_LEN 15
|
||||
const float KERNEL_4_90[] =
|
||||
{
|
||||
-0.002474188804626465f,
|
||||
0.000000000000000000f,
|
||||
0.016965746879577637f,
|
||||
0.000000000000000000f,
|
||||
-0.067680597305297852f,
|
||||
0.000000000000000000f,
|
||||
0.303180575370788570f,
|
||||
0.500017046928405760f,
|
||||
0.303180575370788570f,
|
||||
0.000000000000000000f,
|
||||
-0.067680597305297852f,
|
||||
0.000000000000000000f,
|
||||
0.016965746879577637f,
|
||||
0.000000000000000000f,
|
||||
-0.002474188804626465f
|
||||
};
|
||||
|
||||
#define KERNEL_2_80_LEN 47
|
||||
const float KERNEL_2_80[KERNEL_2_80_LEN] =
|
||||
{
|
||||
-0.000198006629943848f,
|
||||
0.000000000000000000f,
|
||||
0.000576853752136230f,
|
||||
0.000000000000000000f,
|
||||
-0.001352190971374512f,
|
||||
0.000000000000000000f,
|
||||
0.002729177474975586f,
|
||||
0.000000000000000000f,
|
||||
-0.004988193511962891f,
|
||||
0.000000000000000000f,
|
||||
0.008499503135681152f,
|
||||
0.000000000000000000f,
|
||||
-0.013788580894470215f,
|
||||
0.000000000000000000f,
|
||||
0.021713137626647949f,
|
||||
0.000000000000000000f,
|
||||
-0.033980011940002441f,
|
||||
0.000000000000000000f,
|
||||
0.054944872856140137f,
|
||||
0.000000000000000000f,
|
||||
-0.100657463073730470f,
|
||||
0.000000000000000000f,
|
||||
0.316457390785217290f,
|
||||
0.500000000000000000f,
|
||||
0.316457390785217290f,
|
||||
0.000000000000000000f,
|
||||
-0.100657463073730470f,
|
||||
0.000000000000000000f,
|
||||
0.054944872856140137f,
|
||||
0.000000000000000000f,
|
||||
-0.033980011940002441f,
|
||||
0.000000000000000000f,
|
||||
0.021713137626647949f,
|
||||
0.000000000000000000f,
|
||||
-0.013788580894470215f,
|
||||
0.000000000000000000f,
|
||||
0.008499503135681152f,
|
||||
0.000000000000000000f,
|
||||
-0.004988193511962891f,
|
||||
0.000000000000000000f,
|
||||
0.002729177474975586f,
|
||||
0.000000000000000000f,
|
||||
-0.001352190971374512f,
|
||||
0.000000000000000000f,
|
||||
0.000576853752136230f,
|
||||
0.000000000000000000f,
|
||||
-0.000198006629943848f
|
||||
};
|
|
@ -29,31 +29,34 @@
|
|||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/detail/endian.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
#include "airspy_source_c.h"
|
||||
#include "airspy_fir_kernels.h"
|
||||
|
||||
#include "arg_helpers.h"
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
#define AIRSPY_FORMAT_ERROR(ret, msg) \
|
||||
boost::str( boost::format(msg " (%1%) %2%") \
|
||||
% ret % airspy_error_name((enum airspy_error)ret) )
|
||||
|
||||
#define AIRSPY_THROW_ON_ERROR(ret, msg) \
|
||||
if ( ret != AIRSPY_SUCCESS ) \
|
||||
throw std::runtime_error( boost::str( boost::format(msg " (%d) %s") \
|
||||
% ret % airspy_error_name((enum airspy_error)ret) ) );
|
||||
if ( ret != AIRSPY_SUCCESS ) \
|
||||
{ \
|
||||
throw std::runtime_error( AIRSPY_FORMAT_ERROR(ret, msg) ); \
|
||||
}
|
||||
|
||||
#define AIRSPY_FUNC_STR(func, arg) \
|
||||
boost::str(boost::format(func "(%d)") % arg) + " has failed"
|
||||
|
||||
int airspy_source_c::_usage = 0;
|
||||
boost::mutex airspy_source_c::_usage_mutex;
|
||||
boost::str(boost::format(func "(%1%)") % arg) + " has failed"
|
||||
|
||||
airspy_source_c_sptr make_airspy_source_c (const std::string & args)
|
||||
{
|
||||
|
@ -86,6 +89,7 @@ airspy_source_c::airspy_source_c (const std::string &args)
|
|||
_center_freq(0),
|
||||
_freq_corr(0),
|
||||
_auto_gain(false),
|
||||
_gain_policy(linearity),
|
||||
_lna_gain(0),
|
||||
_mix_gain(0),
|
||||
_vga_gain(0),
|
||||
|
@ -95,15 +99,6 @@ airspy_source_c::airspy_source_c (const std::string &args)
|
|||
|
||||
dict_t dict = params_to_dict(args);
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock( _usage_mutex );
|
||||
|
||||
if ( _usage == 0 )
|
||||
airspy_init(); /* call only once before the first open */
|
||||
|
||||
_usage++;
|
||||
}
|
||||
|
||||
_dev = NULL;
|
||||
ret = airspy_open( &_dev );
|
||||
AIRSPY_THROW_ON_ERROR(ret, "Failed to open AirSpy device")
|
||||
|
@ -112,28 +107,66 @@ airspy_source_c::airspy_source_c (const std::string &args)
|
|||
ret = airspy_board_id_read( _dev, &board_id );
|
||||
AIRSPY_THROW_ON_ERROR(ret, "Failed to get AirSpy board id")
|
||||
|
||||
char version[40];
|
||||
char version[128];
|
||||
memset(version, 0, sizeof(version));
|
||||
ret = airspy_version_string_read( _dev, version, sizeof(version));
|
||||
AIRSPY_THROW_ON_ERROR(ret, "Failed to read version string")
|
||||
#if 0
|
||||
read_partid_serialno_t serial_number;
|
||||
ret = airspy_board_partid_serialno_read( _dev, &serial_number );
|
||||
airspy_read_partid_serialno_t part_serial;
|
||||
ret = airspy_board_partid_serialno_read( _dev, &part_serial );
|
||||
AIRSPY_THROW_ON_ERROR(ret, "Failed to read serial number")
|
||||
#endif
|
||||
std::cerr << "Using " << airspy_board_id_name(airspy_board_id(board_id)) << " "
|
||||
<< "with firmware " << version << " "
|
||||
<< std::endl;
|
||||
uint32_t num_rates;
|
||||
airspy_get_samplerates(_dev, &num_rates, 0);
|
||||
uint32_t *samplerates = (uint32_t *) malloc(num_rates * sizeof(uint32_t));
|
||||
airspy_get_samplerates(_dev, samplerates, num_rates);
|
||||
for (size_t i = 0; i < num_rates; i++)
|
||||
_sample_rates.push_back( std::pair<double, uint32_t>( samplerates[i], i ) );
|
||||
free(samplerates);
|
||||
|
||||
/* since they may (and will) give us an unsorted array we have to sort it here
|
||||
* to play nice with the monotonic requirement of meta-range later on */
|
||||
std::sort(_sample_rates.begin(), _sample_rates.end());
|
||||
|
||||
std::cerr << "Using " << version << ", samplerates: ";
|
||||
|
||||
for (size_t i = 0; i < _sample_rates.size(); i++)
|
||||
std::cerr << boost::format("%gM ") % (_sample_rates[i].first / 1e6);
|
||||
|
||||
std::cerr << std::endl;
|
||||
|
||||
set_center_freq( (get_freq_range().start() + get_freq_range().stop()) / 2.0 );
|
||||
set_sample_rate( get_sample_rates().start() );
|
||||
set_bandwidth( 0 );
|
||||
|
||||
set_gain( 8 ); /* preset to a reasonable default (non-GRC use case) */
|
||||
if ( dict.count( "linearity" ) )
|
||||
_gain_policy = linearity;
|
||||
|
||||
if ( dict.count( "sensitivity" ) )
|
||||
_gain_policy = sensitivity;
|
||||
|
||||
set_lna_gain( 8 ); /* preset to a reasonable default (non-GRC use case) */
|
||||
|
||||
set_mix_gain( 5 ); /* preset to a reasonable default (non-GRC use case) */
|
||||
|
||||
set_if_gain( 0 ); /* preset to a reasonable default (non-GRC use case) */
|
||||
set_if_gain( 5 ); /* preset to a reasonable default (non-GRC use case) */
|
||||
|
||||
if ( dict.count( "bias" ) )
|
||||
{
|
||||
bool bias = boost::lexical_cast<bool>( dict["bias"] );
|
||||
int ret = airspy_set_rf_bias(_dev, (uint8_t)bias);
|
||||
AIRSPY_THROW_ON_ERROR(ret, "Failed to enable DC bias")
|
||||
}
|
||||
|
||||
/* pack 4 sets of 12 bits into 3 sets 16 bits for the data transfer across the
|
||||
* USB bus. The default is is unpacked, to transfer 12 bits across the USB bus
|
||||
* in 16 bit words. libairspy transparently unpacks if packing is enabled */
|
||||
if ( dict.count( "pack" ) )
|
||||
{
|
||||
bool pack = boost::lexical_cast<bool>( dict["pack"] );
|
||||
int ret = airspy_set_packing(_dev, (uint8_t)pack);
|
||||
AIRSPY_THROW_ON_ERROR(ret, "Failed to set USB bit packing")
|
||||
}
|
||||
|
||||
_fifo = new boost::circular_buffer<gr_complex>(5000000);
|
||||
if (!_fifo) {
|
||||
|
@ -153,21 +186,18 @@ airspy_source_c::~airspy_source_c ()
|
|||
if ( airspy_is_streaming( _dev ) == AIRSPY_TRUE )
|
||||
{
|
||||
ret = airspy_stop_rx( _dev );
|
||||
AIRSPY_THROW_ON_ERROR(ret, "Failed to stop RX streaming")
|
||||
if ( ret != AIRSPY_SUCCESS )
|
||||
{
|
||||
std::cerr << AIRSPY_FORMAT_ERROR(ret, "Failed to stop RX streaming") << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
ret = airspy_close( _dev );
|
||||
AIRSPY_THROW_ON_ERROR(ret, "Failed to close AirSpy")
|
||||
_dev = NULL;
|
||||
|
||||
if ( ret != AIRSPY_SUCCESS )
|
||||
{
|
||||
boost::mutex::scoped_lock lock( _usage_mutex );
|
||||
|
||||
_usage--;
|
||||
|
||||
if ( _usage == 0 )
|
||||
airspy_exit(); /* call only once after last close */
|
||||
std::cerr << AIRSPY_FORMAT_ERROR(ret, "Failed to close AirSpy") << std::endl;
|
||||
}
|
||||
_dev = NULL;
|
||||
}
|
||||
|
||||
if (_fifo)
|
||||
|
@ -260,7 +290,7 @@ int airspy_source_c::work( int noutput_items,
|
|||
if ( ! running )
|
||||
return WORK_DONE;
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(_fifo_lock);
|
||||
std::unique_lock<std::mutex> lock(_fifo_lock);
|
||||
|
||||
/* Wait until we have the requested number of samples */
|
||||
int n_samples_avail = _fifo->size();
|
||||
|
@ -284,29 +314,6 @@ std::vector<std::string> airspy_source_c::get_devices()
|
|||
{
|
||||
std::vector<std::string> devices;
|
||||
std::string label;
|
||||
#if 0
|
||||
for (unsigned int i = 0; i < 1 /* TODO: missing libairspy api */; i++) {
|
||||
std::string args = "airspy=" + boost::lexical_cast< std::string >( i );
|
||||
|
||||
label.clear();
|
||||
|
||||
label = "AirSpy"; /* TODO: missing libairspy api */
|
||||
|
||||
boost::algorithm::trim(label);
|
||||
|
||||
args += ",label='" + label + "'";
|
||||
devices.push_back( args );
|
||||
}
|
||||
#else
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock( _usage_mutex );
|
||||
|
||||
if ( _usage == 0 )
|
||||
airspy_init(); /* call only once before the first open */
|
||||
|
||||
_usage++;
|
||||
}
|
||||
|
||||
int ret;
|
||||
airspy_device *dev = NULL;
|
||||
|
@ -330,16 +337,6 @@ std::vector<std::string> airspy_source_c::get_devices()
|
|||
ret = airspy_close(dev);
|
||||
}
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock( _usage_mutex );
|
||||
|
||||
_usage--;
|
||||
|
||||
if ( _usage == 0 )
|
||||
airspy_exit(); /* call only once after last close */
|
||||
}
|
||||
|
||||
#endif
|
||||
return devices;
|
||||
}
|
||||
|
||||
|
@ -352,7 +349,8 @@ osmosdr::meta_range_t airspy_source_c::get_sample_rates()
|
|||
{
|
||||
osmosdr::meta_range_t range;
|
||||
|
||||
range += osmosdr::range_t( 10e6 );
|
||||
for (size_t i = 0; i < _sample_rates.size(); i++)
|
||||
range += osmosdr::range_t( _sample_rates[i].first );
|
||||
|
||||
return range;
|
||||
}
|
||||
|
@ -362,12 +360,30 @@ double airspy_source_c::set_sample_rate( double rate )
|
|||
int ret = AIRSPY_SUCCESS;
|
||||
|
||||
if (_dev) {
|
||||
// ret = airspy_set_sample_rate( _dev, rate );
|
||||
bool found_supported_rate = false;
|
||||
uint32_t samp_rate_index = 0;
|
||||
|
||||
for( unsigned int i = 0; i < _sample_rates.size(); i++ )
|
||||
{
|
||||
if( _sample_rates[i].first == rate )
|
||||
{
|
||||
samp_rate_index = _sample_rates[i].second;
|
||||
|
||||
found_supported_rate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! found_supported_rate )
|
||||
{
|
||||
throw std::runtime_error(
|
||||
boost::str( boost::format("Unsupported samplerate: %gM") % (rate/1e6) ) );
|
||||
}
|
||||
|
||||
ret = airspy_set_samplerate( _dev, samp_rate_index );
|
||||
if ( AIRSPY_SUCCESS == ret ) {
|
||||
//_sample_rate = rate;
|
||||
_sample_rate = get_sample_rates().start();
|
||||
_sample_rate = rate;
|
||||
} else {
|
||||
AIRSPY_THROW_ON_ERROR( ret, AIRSPY_FUNC_STR( "airspy_set_sample_rate", rate ) )
|
||||
AIRSPY_THROW_ON_ERROR( ret, AIRSPY_FUNC_STR( "airspy_set_samplerate", rate ) )
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -439,11 +455,13 @@ std::vector<std::string> airspy_source_c::get_gain_names( size_t chan )
|
|||
|
||||
osmosdr::gain_range_t airspy_source_c::get_gain_range( size_t chan )
|
||||
{
|
||||
return get_gain_range( "LNA", chan );
|
||||
return osmosdr::gain_range_t( 0, 21, 1 );
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t airspy_source_c::get_gain_range( const std::string & name, size_t chan )
|
||||
{
|
||||
/* They don't spec any gain values in dB so we simply use gain stage indices for now. */
|
||||
|
||||
if ( "LNA" == name ) {
|
||||
return osmosdr::gain_range_t( 0, 15, 1 );
|
||||
}
|
||||
|
@ -461,6 +479,17 @@ osmosdr::gain_range_t airspy_source_c::get_gain_range( const std::string & name,
|
|||
|
||||
bool airspy_source_c::set_gain_mode( bool automatic, size_t chan )
|
||||
{
|
||||
if ( automatic ) {
|
||||
airspy_set_lna_agc( _dev, 1 );
|
||||
airspy_set_mixer_agc( _dev, 1 );
|
||||
} else {
|
||||
airspy_set_lna_agc( _dev, 0 );
|
||||
airspy_set_mixer_agc( _dev, 0 );
|
||||
|
||||
set_lna_gain( _lna_gain );
|
||||
set_mix_gain( _mix_gain );
|
||||
}
|
||||
|
||||
_auto_gain = automatic;
|
||||
|
||||
return get_gain_mode(chan);
|
||||
|
@ -474,27 +503,36 @@ bool airspy_source_c::get_gain_mode( size_t chan )
|
|||
double airspy_source_c::set_gain( double gain, size_t chan )
|
||||
{
|
||||
int ret = AIRSPY_SUCCESS;
|
||||
osmosdr::gain_range_t gains = get_gain_range( "LNA", chan );
|
||||
osmosdr::gain_range_t gains = get_gain_range( chan );
|
||||
|
||||
if (_dev) {
|
||||
double clip_gain = gains.clip( gain, true );
|
||||
uint8_t value = clip_gain;
|
||||
|
||||
ret = airspy_set_lna_gain( _dev, value );
|
||||
if ( AIRSPY_SUCCESS == ret ) {
|
||||
_lna_gain = clip_gain;
|
||||
} else {
|
||||
// AIRSPY_THROW_ON_ERROR( ret, AIRSPY_FUNC_STR( "airspy_set_lna_gain", value ) )
|
||||
if ( _gain_policy == linearity ) {
|
||||
ret = airspy_set_linearity_gain( _dev, value );
|
||||
if ( AIRSPY_SUCCESS == ret ) {
|
||||
_gain = clip_gain;
|
||||
} else {
|
||||
AIRSPY_THROW_ON_ERROR( ret, AIRSPY_FUNC_STR( "airspy_set_linearity_gain", value ) )
|
||||
}
|
||||
} else if ( _gain_policy == sensitivity ) {
|
||||
ret = airspy_set_sensitivity_gain( _dev, value );
|
||||
if ( AIRSPY_SUCCESS == ret ) {
|
||||
_gain = clip_gain;
|
||||
} else {
|
||||
AIRSPY_THROW_ON_ERROR( ret, AIRSPY_FUNC_STR( "airspy_set_sensitivity_gain", value ) )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _lna_gain;
|
||||
return _gain;
|
||||
}
|
||||
|
||||
double airspy_source_c::set_gain( double gain, const std::string & name, size_t chan)
|
||||
{
|
||||
if ( "LNA" == name ) {
|
||||
return set_gain( gain, chan );
|
||||
return set_lna_gain( gain, chan );
|
||||
}
|
||||
|
||||
if ( "MIX" == name ) {
|
||||
|
@ -510,13 +548,13 @@ double airspy_source_c::set_gain( double gain, const std::string & name, size_t
|
|||
|
||||
double airspy_source_c::get_gain( size_t chan )
|
||||
{
|
||||
return _lna_gain;
|
||||
return _gain;
|
||||
}
|
||||
|
||||
double airspy_source_c::get_gain( const std::string & name, size_t chan )
|
||||
{
|
||||
if ( "LNA" == name ) {
|
||||
return get_gain( chan );
|
||||
return _lna_gain;
|
||||
}
|
||||
|
||||
if ( "MIX" == name ) {
|
||||
|
@ -530,6 +568,26 @@ double airspy_source_c::get_gain( const std::string & name, size_t chan )
|
|||
return get_gain( chan );
|
||||
}
|
||||
|
||||
double airspy_source_c::set_lna_gain( double gain, size_t chan )
|
||||
{
|
||||
int ret = AIRSPY_SUCCESS;
|
||||
osmosdr::gain_range_t gains = get_gain_range( "LNA", chan );
|
||||
|
||||
if (_dev) {
|
||||
double clip_gain = gains.clip( gain, true );
|
||||
uint8_t value = clip_gain;
|
||||
|
||||
ret = airspy_set_lna_gain( _dev, value );
|
||||
if ( AIRSPY_SUCCESS == ret ) {
|
||||
_lna_gain = clip_gain;
|
||||
} else {
|
||||
AIRSPY_THROW_ON_ERROR( ret, AIRSPY_FUNC_STR( "airspy_set_lna_gain", value ) )
|
||||
}
|
||||
}
|
||||
|
||||
return _lna_gain;
|
||||
}
|
||||
|
||||
double airspy_source_c::set_mix_gain(double gain, size_t chan)
|
||||
{
|
||||
int ret;
|
||||
|
@ -543,7 +601,7 @@ double airspy_source_c::set_mix_gain(double gain, size_t chan)
|
|||
if ( AIRSPY_SUCCESS == ret ) {
|
||||
_mix_gain = clip_gain;
|
||||
} else {
|
||||
// AIRSPY_THROW_ON_ERROR( ret, AIRSPY_FUNC_STR( "airspy_set_mixer_gain", value ) )
|
||||
AIRSPY_THROW_ON_ERROR( ret, AIRSPY_FUNC_STR( "airspy_set_mixer_gain", value ) )
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -563,7 +621,7 @@ double airspy_source_c::set_if_gain(double gain, size_t chan)
|
|||
if ( AIRSPY_SUCCESS == ret ) {
|
||||
_vga_gain = clip_gain;
|
||||
} else {
|
||||
// AIRSPY_THROW_ON_ERROR( ret, AIRSPY_FUNC_STR( "airspy_set_vga_gain", value ) )
|
||||
AIRSPY_THROW_ON_ERROR( ret, AIRSPY_FUNC_STR( "airspy_set_vga_gain", value ) )
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -591,12 +649,58 @@ std::string airspy_source_c::get_antenna( size_t chan )
|
|||
|
||||
double airspy_source_c::set_bandwidth( double bandwidth, size_t chan )
|
||||
{
|
||||
if (bandwidth == 0.f)
|
||||
return get_bandwidth( chan );
|
||||
|
||||
{
|
||||
int ret;
|
||||
int decim;
|
||||
int size;
|
||||
const float *kernel;
|
||||
|
||||
decim = (int)(_sample_rate / bandwidth);
|
||||
// if (decim < 2)
|
||||
// {
|
||||
// kernel = 0;
|
||||
// size = 0;
|
||||
// }
|
||||
// else
|
||||
if (decim < 4)
|
||||
{
|
||||
kernel = KERNEL_2_80;
|
||||
size = KERNEL_2_80_LEN;
|
||||
}
|
||||
else if (decim < 8)
|
||||
{
|
||||
kernel = KERNEL_4_90;
|
||||
size = KERNEL_4_90_LEN;
|
||||
}
|
||||
else if (decim < 16)
|
||||
{
|
||||
kernel = KERNEL_8_100;
|
||||
size = KERNEL_8_100_LEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
kernel = KERNEL_16_110;
|
||||
size = KERNEL_16_110_LEN;
|
||||
}
|
||||
|
||||
if (size)
|
||||
{
|
||||
std::cerr << " Airspy decim:" << decim
|
||||
<< " kernel size:" << size << std::endl;
|
||||
ret = airspy_set_conversion_filter_float32(_dev, kernel, size);
|
||||
AIRSPY_THROW_ON_ERROR(ret, "Failed to set IQ conversion filter")
|
||||
}
|
||||
}
|
||||
|
||||
return get_bandwidth( chan );
|
||||
}
|
||||
|
||||
double airspy_source_c::get_bandwidth( size_t chan )
|
||||
{
|
||||
return 10e6;
|
||||
return _sample_rate;
|
||||
}
|
||||
|
||||
osmosdr::freq_range_t airspy_source_c::get_bandwidth_range( size_t chan )
|
||||
|
|
|
@ -23,8 +23,9 @@
|
|||
#define INCLUDED_AIRSPY_SOURCE_C_H
|
||||
|
||||
#include <boost/circular_buffer.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
|
@ -35,7 +36,7 @@
|
|||
class airspy_source_c;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr::blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
|
@ -43,9 +44,9 @@ class airspy_source_c;
|
|||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<airspy_source_c> airspy_source_c_sptr;
|
||||
typedef std::shared_ptr<airspy_source_c> airspy_source_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of airspy_source_c.
|
||||
|
@ -109,6 +110,7 @@ public:
|
|||
double get_gain( size_t chan = 0 );
|
||||
double get_gain( const std::string & name, size_t chan = 0 );
|
||||
|
||||
double set_lna_gain( double gain, size_t chan = 0 );
|
||||
double set_mix_gain(double gain, size_t chan = 0 );
|
||||
double set_if_gain( double gain, size_t chan = 0 );
|
||||
|
||||
|
@ -124,19 +126,24 @@ private:
|
|||
static int _airspy_rx_callback(airspy_transfer* transfer);
|
||||
int airspy_rx_callback(void *samples, int sample_count);
|
||||
|
||||
static int _usage;
|
||||
static boost::mutex _usage_mutex;
|
||||
|
||||
airspy_device *_dev;
|
||||
|
||||
boost::circular_buffer<gr_complex> *_fifo;
|
||||
boost::mutex _fifo_lock;
|
||||
boost::condition_variable _samp_avail;
|
||||
std::mutex _fifo_lock;
|
||||
std::condition_variable _samp_avail;
|
||||
|
||||
std::vector< std::pair<double, uint32_t> > _sample_rates;
|
||||
double _sample_rate;
|
||||
double _center_freq;
|
||||
double _freq_corr;
|
||||
bool _auto_gain;
|
||||
double _gain;
|
||||
enum gain_policy
|
||||
{
|
||||
linearity,
|
||||
sensitivity
|
||||
};
|
||||
enum gain_policy _gain_policy;
|
||||
double _lna_gain;
|
||||
double _mix_gain;
|
||||
double _vga_gain;
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# Copyright 2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of gr-osmosdr
|
||||
#
|
||||
# gr-osmosdr 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# gr-osmosdr 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 gr-osmosdr; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
########################################################################
|
||||
# This file included, use CMake directory variables
|
||||
########################################################################
|
||||
|
||||
target_include_directories(gnuradio-osmosdr PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${LIBAIRSPYHF_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
APPEND_LIB_LIST(
|
||||
${Gnuradio-blocks_LIBRARIES}
|
||||
${LIBAIRSPYHF_LIBRARIES}
|
||||
)
|
||||
|
||||
list(APPEND gr_osmosdr_srcs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/airspyhf_source_c.cc
|
||||
)
|
||||
set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
|
|
@ -0,0 +1,437 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
*
|
||||
* GNU Radio 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* config.h is generated by configure. It contains the results
|
||||
* of probing for features, options etc. It should be the first
|
||||
* file included in your .cc file.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
#include "airspyhf_source_c.h"
|
||||
#include "arg_helpers.h"
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
#define AIRSPYHF_FORMAT_ERROR(ret, msg) \
|
||||
boost::str( boost::format(msg " (%1%)") % ret )
|
||||
|
||||
#define AIRSPYHF_THROW_ON_ERROR(ret, msg) \
|
||||
if ( ret != AIRSPYHF_SUCCESS ) \
|
||||
{ \
|
||||
throw std::runtime_error( AIRSPYHF_FORMAT_ERROR(ret, msg) ); \
|
||||
}
|
||||
|
||||
#define AIRSPYHF_FUNC_STR(func, arg) \
|
||||
boost::str(boost::format(func "(%1%)") % arg) + " has failed"
|
||||
|
||||
airspyhf_source_c_sptr make_airspyhf_source_c (const std::string & args)
|
||||
{
|
||||
return gnuradio::get_initial_sptr(new airspyhf_source_c (args));
|
||||
}
|
||||
|
||||
/*
|
||||
* Specify constraints on number of input and output streams.
|
||||
* This info is used to construct the input and output signatures
|
||||
* (2nd & 3rd args to gr::block's constructor). The input and
|
||||
* output signatures are used by the runtime system to
|
||||
* check that a valid number and type of inputs and outputs
|
||||
* are connected to this block. In this case, we accept
|
||||
* only 0 input and 1 output.
|
||||
*/
|
||||
static const int MIN_IN = 0; // mininum number of input streams
|
||||
static const int MAX_IN = 0; // maximum number of input streams
|
||||
static const int MIN_OUT = 1; // minimum number of output streams
|
||||
static const int MAX_OUT = 1; // maximum number of output streams
|
||||
|
||||
/*
|
||||
* The private constructor
|
||||
*/
|
||||
airspyhf_source_c::airspyhf_source_c (const std::string &args)
|
||||
: gr::sync_block ("airspyhf_source_c",
|
||||
gr::io_signature::make(MIN_IN, MAX_IN, sizeof (gr_complex)),
|
||||
gr::io_signature::make(MIN_OUT, MAX_OUT, sizeof (gr_complex))),
|
||||
_dev(NULL),
|
||||
_sample_rate(0),
|
||||
_center_freq(0),
|
||||
_freq_corr(0)
|
||||
{
|
||||
int ret;
|
||||
|
||||
dict_t dict = params_to_dict(args);
|
||||
|
||||
_dev = NULL;
|
||||
ret = airspyhf_open( &_dev );
|
||||
AIRSPYHF_THROW_ON_ERROR(ret, "Failed to open Airspy HF+ device")
|
||||
|
||||
uint32_t num_rates;
|
||||
airspyhf_get_samplerates(_dev, &num_rates, 0);
|
||||
uint32_t *samplerates = (uint32_t *) malloc(num_rates * sizeof(uint32_t));
|
||||
airspyhf_get_samplerates(_dev, samplerates, num_rates);
|
||||
for (size_t i = 0; i < num_rates; i++)
|
||||
_sample_rates.push_back( std::pair<double, uint32_t>( samplerates[i], i ) );
|
||||
free(samplerates);
|
||||
|
||||
/* since they may (and will) give us an unsorted array we have to sort it here
|
||||
* to play nice with the monotonic requirement of meta-range later on */
|
||||
std::sort(_sample_rates.begin(), _sample_rates.end());
|
||||
|
||||
std::cerr << "Using libairspyhf" << AIRSPYHF_VERSION << ", samplerates: ";
|
||||
|
||||
for (size_t i = 0; i < _sample_rates.size(); i++)
|
||||
std::cerr << boost::format("%gM ") % (_sample_rates[i].first / 1e6);
|
||||
|
||||
std::cerr << std::endl;
|
||||
|
||||
set_center_freq( (get_freq_range().start() + get_freq_range().stop()) / 2.0 );
|
||||
set_sample_rate( get_sample_rates().start() );
|
||||
|
||||
_fifo = new boost::circular_buffer<gr_complex>(5000000);
|
||||
if (!_fifo) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"Failed to allocate a sample FIFO!" );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
airspyhf_source_c::~airspyhf_source_c ()
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (_dev) {
|
||||
if ( airspyhf_is_streaming( _dev ) )
|
||||
{
|
||||
ret = airspyhf_stop( _dev );
|
||||
if ( ret != AIRSPYHF_SUCCESS )
|
||||
{
|
||||
std::cerr << AIRSPYHF_FORMAT_ERROR(ret, "Failed to stop RX streaming") << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
ret = airspyhf_close( _dev );
|
||||
if ( ret != AIRSPYHF_SUCCESS )
|
||||
{
|
||||
std::cerr << AIRSPYHF_FORMAT_ERROR(ret, "Failed to close AirSpy") << std::endl;
|
||||
}
|
||||
_dev = NULL;
|
||||
}
|
||||
|
||||
if (_fifo)
|
||||
{
|
||||
delete _fifo;
|
||||
_fifo = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int airspyhf_source_c::_airspyhf_rx_callback(airspyhf_transfer_t *transfer)
|
||||
{
|
||||
airspyhf_source_c *obj = (airspyhf_source_c *)transfer->ctx;
|
||||
|
||||
return obj->airspyhf_rx_callback((float *)transfer->samples, transfer->sample_count);
|
||||
}
|
||||
|
||||
int airspyhf_source_c::airspyhf_rx_callback(void *samples, int sample_count)
|
||||
{
|
||||
size_t i, n_avail, to_copy, num_samples = sample_count;
|
||||
float *sample = (float *)samples;
|
||||
|
||||
_fifo_lock.lock();
|
||||
|
||||
n_avail = _fifo->capacity() - _fifo->size();
|
||||
to_copy = (n_avail < num_samples ? n_avail : num_samples);
|
||||
|
||||
for (i = 0; i < to_copy; i++ )
|
||||
{
|
||||
/* Push sample to the fifo */
|
||||
_fifo->push_back( gr_complex( *sample, *(sample+1) ) );
|
||||
|
||||
/* offset to the next I+Q sample */
|
||||
sample += 2;
|
||||
}
|
||||
|
||||
_fifo_lock.unlock();
|
||||
|
||||
/* We have made some new samples available to the consumer in work() */
|
||||
if (to_copy) {
|
||||
//std::cerr << "+" << std::flush;
|
||||
_samp_avail.notify_one();
|
||||
}
|
||||
|
||||
/* Indicate overrun, if neccesary */
|
||||
if (to_copy < num_samples)
|
||||
std::cerr << "O" << std::flush;
|
||||
|
||||
return 0; // TODO: return -1 on error/stop
|
||||
}
|
||||
|
||||
bool airspyhf_source_c::start()
|
||||
{
|
||||
if ( ! _dev )
|
||||
return false;
|
||||
|
||||
int ret = airspyhf_start( _dev, _airspyhf_rx_callback, (void *)this );
|
||||
if ( ret != AIRSPYHF_SUCCESS ) {
|
||||
std::cerr << "Failed to start RX streaming (" << ret << ")" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool airspyhf_source_c::stop()
|
||||
{
|
||||
if ( ! _dev )
|
||||
return false;
|
||||
|
||||
int ret = airspyhf_stop( _dev );
|
||||
if ( ret != AIRSPYHF_SUCCESS ) {
|
||||
std::cerr << "Failed to stop RX streaming (" << ret << ")" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int airspyhf_source_c::work( int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items )
|
||||
{
|
||||
gr_complex *out = (gr_complex *)output_items[0];
|
||||
|
||||
bool running = false;
|
||||
|
||||
if ( _dev )
|
||||
running = airspyhf_is_streaming( _dev );
|
||||
|
||||
if ( ! running )
|
||||
return WORK_DONE;
|
||||
|
||||
std::unique_lock<std::mutex> lock(_fifo_lock);
|
||||
|
||||
/* Wait until we have the requested number of samples */
|
||||
int n_samples_avail = _fifo->size();
|
||||
|
||||
while (n_samples_avail < noutput_items) {
|
||||
_samp_avail.wait(lock);
|
||||
n_samples_avail = _fifo->size();
|
||||
}
|
||||
|
||||
for(int i = 0; i < noutput_items; ++i) {
|
||||
out[i] = _fifo->at(0);
|
||||
_fifo->pop_front();
|
||||
}
|
||||
|
||||
return noutput_items;
|
||||
}
|
||||
|
||||
std::vector<std::string> airspyhf_source_c::get_devices()
|
||||
{
|
||||
std::vector<std::string> devices;
|
||||
std::string label;
|
||||
|
||||
int ret;
|
||||
airspyhf_device *dev = NULL;
|
||||
ret = airspyhf_open(&dev);
|
||||
if ( AIRSPYHF_SUCCESS == ret )
|
||||
{
|
||||
std::string args = "airspyhf=0,label='AirspyHF'";
|
||||
devices.push_back( args );
|
||||
ret = airspyhf_close(dev);
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
size_t airspyhf_source_c::get_num_channels()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
osmosdr::meta_range_t airspyhf_source_c::get_sample_rates()
|
||||
{
|
||||
osmosdr::meta_range_t range;
|
||||
|
||||
for (size_t i = 0; i < _sample_rates.size(); i++)
|
||||
range += osmosdr::range_t( _sample_rates[i].first );
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
double airspyhf_source_c::set_sample_rate( double rate )
|
||||
{
|
||||
int ret = AIRSPYHF_SUCCESS;
|
||||
|
||||
if (_dev) {
|
||||
bool found_supported_rate = false;
|
||||
uint32_t samp_rate_index = 0;
|
||||
|
||||
for( unsigned int i = 0; i < _sample_rates.size(); i++ )
|
||||
{
|
||||
if( _sample_rates[i].first == rate )
|
||||
{
|
||||
samp_rate_index = _sample_rates[i].second;
|
||||
|
||||
found_supported_rate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! found_supported_rate )
|
||||
{
|
||||
throw std::runtime_error(
|
||||
boost::str( boost::format("Unsupported samplerate: %gM") % (rate/1e6) ) );
|
||||
}
|
||||
|
||||
ret = airspyhf_set_samplerate( _dev, samp_rate_index );
|
||||
if ( AIRSPYHF_SUCCESS == ret ) {
|
||||
_sample_rate = rate;
|
||||
} else {
|
||||
AIRSPYHF_THROW_ON_ERROR( ret, AIRSPYHF_FUNC_STR( "airspyhf_set_samplerate", rate ) )
|
||||
}
|
||||
}
|
||||
|
||||
return get_sample_rate();
|
||||
}
|
||||
|
||||
double airspyhf_source_c::get_sample_rate()
|
||||
{
|
||||
return _sample_rate;
|
||||
}
|
||||
|
||||
osmosdr::freq_range_t airspyhf_source_c::get_freq_range( size_t chan )
|
||||
{
|
||||
osmosdr::freq_range_t range;
|
||||
|
||||
range += osmosdr::range_t( 0.0, 260.0e6 );
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
double airspyhf_source_c::set_center_freq( double freq, size_t chan )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (_dev) {
|
||||
ret = airspyhf_set_freq( _dev, freq );
|
||||
if ( AIRSPYHF_SUCCESS == ret ) {
|
||||
_center_freq = freq;
|
||||
} else {
|
||||
AIRSPYHF_THROW_ON_ERROR( ret, AIRSPYHF_FUNC_STR( "airspyhf_set_freq", freq ) )
|
||||
}
|
||||
}
|
||||
|
||||
return get_center_freq( chan );
|
||||
}
|
||||
|
||||
double airspyhf_source_c::get_center_freq( size_t chan )
|
||||
{
|
||||
return _center_freq;
|
||||
}
|
||||
|
||||
double airspyhf_source_c::set_freq_corr( double ppm, size_t chan )
|
||||
{
|
||||
int ret;
|
||||
int32_t ppb = (int32_t) (ppm * 1.0e3);
|
||||
|
||||
if (_dev) {
|
||||
ret = airspyhf_set_calibration( _dev, ppb );
|
||||
if ( AIRSPYHF_SUCCESS == ret ) {
|
||||
_freq_corr = ppm;
|
||||
} else {
|
||||
AIRSPYHF_THROW_ON_ERROR( ret, AIRSPYHF_FUNC_STR( "airspyhf_set_calibration", ppm ) )
|
||||
}
|
||||
}
|
||||
|
||||
return ppm;
|
||||
}
|
||||
|
||||
double airspyhf_source_c::get_freq_corr( size_t chan )
|
||||
{
|
||||
return _freq_corr;
|
||||
}
|
||||
|
||||
std::vector<std::string> airspyhf_source_c::get_gain_names( size_t chan )
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t airspyhf_source_c::get_gain_range( size_t chan )
|
||||
{
|
||||
return osmosdr::gain_range_t();
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t airspyhf_source_c::get_gain_range( const std::string & name, size_t chan )
|
||||
{
|
||||
return osmosdr::gain_range_t();
|
||||
}
|
||||
|
||||
|
||||
double airspyhf_source_c::set_gain( double gain, size_t chan )
|
||||
{
|
||||
return gain;
|
||||
}
|
||||
|
||||
double airspyhf_source_c::set_gain( double gain, const std::string & name, size_t chan)
|
||||
{
|
||||
return gain;
|
||||
}
|
||||
|
||||
double airspyhf_source_c::get_gain( size_t chan )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double airspyhf_source_c::get_gain( const std::string & name, size_t chan )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
std::vector< std::string > airspyhf_source_c::get_antennas( size_t chan )
|
||||
{
|
||||
std::vector< std::string > antennas;
|
||||
|
||||
antennas += get_antenna( chan );
|
||||
|
||||
return antennas;
|
||||
}
|
||||
|
||||
std::string airspyhf_source_c::set_antenna( const std::string & antenna, size_t chan )
|
||||
{
|
||||
return get_antenna( chan );
|
||||
}
|
||||
|
||||
std::string airspyhf_source_c::get_antenna( size_t chan )
|
||||
{
|
||||
return "RX";
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
* Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
*
|
||||
* This file is part of GNU Radio
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -17,63 +19,54 @@
|
|||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef INCLUDED_MIRI_SOURCE_C_H
|
||||
#define INCLUDED_MIRI_SOURCE_C_H
|
||||
#ifndef INCLUDED_AIRSPYHF_SOURCE_C_H
|
||||
#define INCLUDED_AIRSPYHF_SOURCE_C_H
|
||||
|
||||
#include <boost/circular_buffer.hpp>
|
||||
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
#include <gnuradio/thread/thread.h>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <libairspyhf/airspyhf.h>
|
||||
|
||||
#include "source_iface.h"
|
||||
|
||||
class miri_source_c;
|
||||
typedef struct mirisdr_dev mirisdr_dev_t;
|
||||
class airspyhf_source_c;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* to gr::blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
* C++ / Python system.
|
||||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<miri_source_c> miri_source_c_sptr;
|
||||
typedef std::shared_ptr<airspyhf_source_c> airspyhf_source_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of miri_source_c.
|
||||
* \brief Return a shared_ptr to a new instance of airspyhf_source_c.
|
||||
*
|
||||
* To avoid accidental use of raw pointers, miri_source_c's
|
||||
* constructor is private. make_miri_source_c is the public
|
||||
* To avoid accidental use of raw pointers, airspyhf_source_c's
|
||||
* constructor is private. make_airspyhf_source_c is the public
|
||||
* interface for creating new instances.
|
||||
*/
|
||||
miri_source_c_sptr make_miri_source_c (const std::string & args = "");
|
||||
airspyhf_source_c_sptr make_airspyhf_source_c (const std::string & args = "");
|
||||
|
||||
/*!
|
||||
* \brief Provides a stream of complex samples.
|
||||
* \ingroup block
|
||||
*/
|
||||
class miri_source_c :
|
||||
class airspyhf_source_c :
|
||||
public gr::sync_block,
|
||||
public source_iface
|
||||
{
|
||||
private:
|
||||
// The friend declaration allows make_miri_source_c to
|
||||
// The friend declaration allows make_airspyhf_source_c to
|
||||
// access the private constructor.
|
||||
|
||||
friend miri_source_c_sptr make_miri_source_c (const std::string & args);
|
||||
friend airspyhf_source_c_sptr make_airspyhf_source_c (const std::string & args);
|
||||
|
||||
/*!
|
||||
* \brief Provides a stream of complex samples.
|
||||
*/
|
||||
miri_source_c (const std::string & args); // private constructor
|
||||
airspyhf_source_c (const std::string & args);
|
||||
|
||||
public:
|
||||
~miri_source_c (); // public destructor
|
||||
public:
|
||||
~airspyhf_source_c ();
|
||||
|
||||
bool start();
|
||||
bool stop();
|
||||
|
||||
int work( int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
|
@ -96,8 +89,6 @@ private:
|
|||
std::vector<std::string> get_gain_names( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
|
||||
bool set_gain_mode( bool automatic, size_t chan = 0 );
|
||||
bool get_gain_mode( size_t chan = 0 );
|
||||
double set_gain( double gain, size_t chan = 0 );
|
||||
double set_gain( double gain, const std::string & name, size_t chan = 0 );
|
||||
double get_gain( size_t chan = 0 );
|
||||
|
@ -107,28 +98,21 @@ private:
|
|||
std::string set_antenna( const std::string & antenna, size_t chan = 0 );
|
||||
std::string get_antenna( size_t chan = 0 );
|
||||
|
||||
|
||||
private:
|
||||
static void _mirisdr_callback(unsigned char *buf, uint32_t len, void *ctx);
|
||||
void mirisdr_callback(unsigned char *buf, uint32_t len);
|
||||
static void _mirisdr_wait(miri_source_c *obj);
|
||||
void mirisdr_wait();
|
||||
static int _airspyhf_rx_callback(airspyhf_transfer_t* transfer);
|
||||
int airspyhf_rx_callback(void *samples, int sample_count);
|
||||
|
||||
mirisdr_dev_t *_dev;
|
||||
gr::thread::thread _thread;
|
||||
unsigned short **_buf;
|
||||
unsigned int *_buf_lens;
|
||||
unsigned int _buf_num;
|
||||
unsigned int _buf_head;
|
||||
unsigned int _buf_used;
|
||||
boost::mutex _buf_mutex;
|
||||
boost::condition_variable _buf_cond;
|
||||
bool _running;
|
||||
airspyhf_device *_dev;
|
||||
|
||||
unsigned int _buf_offset;
|
||||
int _samp_avail;
|
||||
boost::circular_buffer<gr_complex> *_fifo;
|
||||
std::mutex _fifo_lock;
|
||||
std::condition_variable _samp_avail;
|
||||
|
||||
bool _auto_gain;
|
||||
unsigned int _skipped;
|
||||
std::vector< std::pair<double, uint32_t> > _sample_rates;
|
||||
double _sample_rate;
|
||||
double _center_freq;
|
||||
double _freq_corr;
|
||||
};
|
||||
|
||||
#endif /* INCLUDED_MIRI_SOURCE_C_H */
|
||||
#endif /* INCLUDED_AIRSPY_SOURCE_C_H */
|
|
@ -29,11 +29,22 @@
|
|||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <ciso646>
|
||||
|
||||
typedef std::map< std::string, std::string > dict_t;
|
||||
typedef std::pair< std::string, std::string > pair_t;
|
||||
|
||||
inline std::string dict_to_args_string( const dict_t &d )
|
||||
{
|
||||
std::string out;
|
||||
for (const pair_t pair : d)
|
||||
{
|
||||
if (not out.empty()) out += ",";
|
||||
out += pair.first + "='" + pair.second + "'";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
inline std::vector< std::string > args_to_vector( const std::string &args )
|
||||
{
|
||||
std::vector< std::string > result;
|
||||
|
@ -42,7 +53,7 @@ inline std::vector< std::string > args_to_vector( const std::string &args )
|
|||
typedef boost::tokenizer< boost::escaped_list_separator<char> > tokenizer_t;
|
||||
tokenizer_t tokens(args, separator);
|
||||
|
||||
BOOST_FOREACH(std::string token, tokens)
|
||||
for (std::string token : tokens)
|
||||
result.push_back(token);
|
||||
|
||||
return result;
|
||||
|
@ -56,7 +67,7 @@ inline std::vector< std::string > params_to_vector( const std::string ¶ms )
|
|||
typedef boost::tokenizer< boost::escaped_list_separator<char> > tokenizer_t;
|
||||
tokenizer_t tokens(params, separator);
|
||||
|
||||
BOOST_FOREACH(std::string token, tokens)
|
||||
for (std::string token : tokens)
|
||||
result.push_back(token);
|
||||
|
||||
return result;
|
||||
|
@ -86,7 +97,7 @@ inline dict_t params_to_dict( const std::string ¶ms )
|
|||
dict_t result;
|
||||
|
||||
std::vector< std::string > param_list = params_to_vector( params );
|
||||
BOOST_FOREACH(std::string param, param_list)
|
||||
for (std::string param : param_list)
|
||||
{
|
||||
pair_t pair = param_to_pair( param );
|
||||
std::string value = pair.second;
|
||||
|
@ -112,7 +123,7 @@ inline gr::io_signature::sptr args_to_io_signature( const std::string &args )
|
|||
size_t dev_nchan = 0;
|
||||
std::vector< std::string > arg_list = args_to_vector( args );
|
||||
|
||||
BOOST_FOREACH( std::string arg, arg_list )
|
||||
for (std::string arg : arg_list)
|
||||
{
|
||||
if ( arg.find( "numchan=" ) == 0 ) // try to parse global nchan value
|
||||
{
|
||||
|
@ -129,7 +140,7 @@ inline gr::io_signature::sptr args_to_io_signature( const std::string &args )
|
|||
|
||||
// try to parse device specific nchan values, assume 1 channel if none given
|
||||
|
||||
BOOST_FOREACH( std::string arg, arg_list )
|
||||
for (std::string arg : arg_list)
|
||||
{
|
||||
dict_t dict = params_to_dict(arg);
|
||||
if (dict.count("nchan"))
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
# Copyright 2013 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file is part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# gr-osmosdr 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio is distributed in the hope that it will be useful,
|
||||
# gr-osmosdr 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# along with gr-osmosdr; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
|
@ -21,19 +21,20 @@
|
|||
# This file included, use CMake directory variables
|
||||
########################################################################
|
||||
|
||||
include_directories(
|
||||
target_include_directories(gnuradio-osmosdr PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${LIBBLADERF_INCLUDE_DIRS}
|
||||
${Volk_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(bladerf_srcs
|
||||
APPEND_LIB_LIST(
|
||||
${LIBBLADERF_LIBRARIES}
|
||||
${Volk_LIBRARIES}
|
||||
)
|
||||
|
||||
list(APPEND gr_osmosdr_srcs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bladerf_source_c.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bladerf_sink_c.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bladerf_common.cc
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Append gnuradio-osmosdr library sources
|
||||
########################################################################
|
||||
list(APPEND gr_osmosdr_srcs ${bladerf_srcs})
|
||||
list(APPEND gr_osmosdr_libs ${LIBBLADERF_LIBRARIES})
|
||||
set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2013 Nuand LLC
|
||||
* Copyright 2013-2017 Nuand LLC
|
||||
* Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
|
@ -21,84 +21,273 @@
|
|||
#ifndef INCLUDED_BLADERF_COMMON_H
|
||||
#define INCLUDED_BLADERF_COMMON_H
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include <boost/circular_buffer.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <gnuradio/thread/thread.h>
|
||||
#include <gnuradio/gr_complex.h>
|
||||
#include <vector>
|
||||
|
||||
#include <libbladeRF.h>
|
||||
|
||||
#include "osmosdr/ranges.h"
|
||||
#include "arg_helpers.h"
|
||||
|
||||
typedef boost::shared_ptr<struct bladerf> bladerf_sptr;
|
||||
#include "bladerf_compat.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <cstddef>
|
||||
typedef ptrdiff_t ssize_t;
|
||||
#endif //_MSC_VER
|
||||
|
||||
#define BLADERF_DEBUG_ENABLE
|
||||
|
||||
typedef std::shared_ptr<struct bladerf> bladerf_sptr;
|
||||
|
||||
/* Identification of the bladeRF hardware in use */
|
||||
typedef enum {
|
||||
BOARD_TYPE_UNKNOWN, /**< Board type is unknown */
|
||||
BOARD_TYPE_NONE, /**< Uninitialized or no board present */
|
||||
BOARD_TYPE_BLADERF_1, /**< bladeRF 1 (LMS6002D-based, 1RX/1TX) */
|
||||
BOARD_TYPE_BLADERF_2, /**< bladeRF 2 (AD9361-based, 2RX/2TX) */
|
||||
} bladerf_board_type;
|
||||
|
||||
/* Mapping of bladerf_channel to bool */
|
||||
typedef std::map<bladerf_channel, bool> bladerf_channel_enable_map;
|
||||
|
||||
/* Mapping of bladerf_channel to gnuradio port/chan */
|
||||
typedef std::map<bladerf_channel, int> bladerf_channel_map;
|
||||
|
||||
/* Convenience macros for throwing a runtime error */
|
||||
#define BLADERF_THROW(message) \
|
||||
{ \
|
||||
throw std::runtime_error(std::string(__FUNCTION__) + ": " + message); \
|
||||
}
|
||||
|
||||
#define BLADERF_THROW_STATUS(status, message) \
|
||||
{ \
|
||||
BLADERF_THROW(boost::str(boost::format("%s: %s (%d)") % message \
|
||||
% bladerf_strerror(status) % status)); \
|
||||
}
|
||||
|
||||
/* Convenience macros for printing a warning message to stderr */
|
||||
#define BLADERF_WARNING(message) \
|
||||
{ \
|
||||
std::cerr << _pfx << __FUNCTION__ << ": " << message << std::endl; \
|
||||
}
|
||||
|
||||
#define BLADERF_WARN_STATUS(status, message) \
|
||||
{ \
|
||||
BLADERF_WARNING(message << ": " << bladerf_strerror(status)); \
|
||||
} \
|
||||
|
||||
/* Convenience macro for printing an informational message to stdout */
|
||||
#define BLADERF_INFO(message) \
|
||||
{ \
|
||||
std::cout << _pfx << __FUNCTION__ << ": " << message << std::endl; \
|
||||
}
|
||||
|
||||
/* Convenience macro for printing a debug message to stdout */
|
||||
#ifdef BLADERF_DEBUG_ENABLE
|
||||
#define BLADERF_DEBUG(message) BLADERF_INFO("DEBUG: " << message)
|
||||
#else
|
||||
#define BLADERF_DEBUG(message)
|
||||
#endif // BLADERF_DEBUG_ENABLE
|
||||
|
||||
/* Given a bladerf_channel_layout, calculate the number of streams */
|
||||
size_t num_streams(bladerf_channel_layout layout);
|
||||
|
||||
/**
|
||||
* Common class for bladeRF interaction
|
||||
*/
|
||||
class bladerf_common
|
||||
{
|
||||
public:
|
||||
/*****************************************************************************
|
||||
* Public methods
|
||||
****************************************************************************/
|
||||
bladerf_common();
|
||||
virtual ~bladerf_common();
|
||||
|
||||
protected:
|
||||
/* Handle initialized and parameters common to both source & sink */
|
||||
void init(dict_t &dict, bladerf_module module);
|
||||
/*****************************************************************************
|
||||
* Protected methods
|
||||
****************************************************************************/
|
||||
|
||||
bool start(bladerf_module module);
|
||||
bool stop(bladerf_module module);
|
||||
/**
|
||||
* Handle initialization and parameters common to both source & sink
|
||||
*
|
||||
* Specify arguments in key=value,key=value format, e.g.
|
||||
* bladerf=0,buffers=512
|
||||
*
|
||||
* Recognized arguments:
|
||||
* Key Allowed values
|
||||
* ---------------------------------------------------------------------------
|
||||
* REQUIRED:
|
||||
* bladerf a valid instance or serial number
|
||||
* USB INTERFACE CONTROL:
|
||||
* buffers (default: NUM_BUFFERS)
|
||||
* buflen (default: NUM_SAMPLES_PER_BUFFER)
|
||||
* stream_timeout valid time in milliseconds (default: 3000)
|
||||
* transfers (default: NUM_TRANSFERS)
|
||||
* FPGA CONTROL:
|
||||
* enable_metadata 1 to enable metadata
|
||||
* fpga a path to a valid .rbf file
|
||||
* fpga-reload 1 to force reloading the FPGA unconditionally
|
||||
* RF CONTROL:
|
||||
* agc 1 to enable, 0 to disable (default: hardware-dependent)
|
||||
* agc_mode default, manual, fast, slow, hybrid (default: default)
|
||||
* loopback bb_txlpf_rxvga2, bb_txlpf_rxlpf, bb_txvga1_rxvga2,
|
||||
* bb_txvga1_rxlpf, rf_lna1, rf_lna2, rf_lna3, firmware,
|
||||
* ad9361_bist, none (default: none)
|
||||
* ** Note: valid on receive channels only
|
||||
* rxmux baseband, 12bit, 32bit, digital (default: baseband)
|
||||
* ** Note: valid on receive channels only
|
||||
* smb a valid frequency
|
||||
* tamer internal, external_1pps, external (default: internal)
|
||||
* xb200 auto, auto3db, 50M, 144M, 222M, custom (default: auto)
|
||||
* MISC:
|
||||
* verbosity verbose, debug, info, warning, error, critical, silent
|
||||
* (default: info)
|
||||
* ** Note: applies only to libbladeRF logging
|
||||
*/
|
||||
void init(dict_t const &dict, bladerf_direction direction);
|
||||
|
||||
double set_sample_rate(bladerf_module module, double rate);
|
||||
double get_sample_rate(bladerf_module module);
|
||||
/* Get a vector of available devices */
|
||||
static std::vector<std::string> devices();
|
||||
/* Get the type of the open bladeRF board */
|
||||
bladerf_board_type get_board_type();
|
||||
/* Get the maximum number of channels supported in a given direction */
|
||||
size_t get_max_channels(bladerf_direction direction);
|
||||
|
||||
int set_dc_offset(bladerf_module module, const std::complex<double> &offset, size_t chan);
|
||||
int set_iq_balance(bladerf_module module, const std::complex<double> &balance, size_t chan);
|
||||
void set_channel_enable(bladerf_channel ch, bool enable);
|
||||
bool get_channel_enable(bladerf_channel ch);
|
||||
|
||||
osmosdr::freq_range_t freq_range();
|
||||
osmosdr::meta_range_t sample_rates();
|
||||
osmosdr::freq_range_t filter_bandwidths();
|
||||
/* Set libbladeRF verbosity */
|
||||
void set_verbosity(std::string const &verbosity);
|
||||
|
||||
static std::vector< std::string > devices();
|
||||
/* Convert an antenna/channel name (e.g. "RX2") to a bladerf_channel */
|
||||
bladerf_channel str2channel(std::string const &ch);
|
||||
/* Convert a bladerf_channel to an antenna/channel name (e.g. "RX2") */
|
||||
std::string channel2str(bladerf_channel ch);
|
||||
/* Convert a bladerf_channel to a hardware port identifier */
|
||||
int channel2rfport(bladerf_channel ch);
|
||||
|
||||
bladerf_sptr _dev;
|
||||
/* Using the channel map, get the bladerf_channel for a gnuradio chan */
|
||||
bladerf_channel chan2channel(bladerf_direction direction, size_t chan = 0);
|
||||
|
||||
size_t _num_buffers;
|
||||
size_t _samples_per_buffer;
|
||||
size_t _num_transfers;
|
||||
unsigned int _stream_timeout_ms;
|
||||
/* Get range of supported sampling rates for channel ch */
|
||||
osmosdr::meta_range_t sample_rates(bladerf_channel ch);
|
||||
/* Set sampling rate on channel ch to rate */
|
||||
double set_sample_rate(double rate, bladerf_channel ch);
|
||||
/* Get the current sampling rate on channel ch */
|
||||
double get_sample_rate(bladerf_channel ch);
|
||||
|
||||
int16_t *_conv_buf;
|
||||
int _conv_buf_size; /* In units of samples */
|
||||
/* Get range of supported RF frequencies for channel ch */
|
||||
osmosdr::freq_range_t freq_range(bladerf_channel ch);
|
||||
/* Set center RF frequency of channel ch to freq */
|
||||
double set_center_freq(double freq, bladerf_channel ch);
|
||||
/* Get the center RF frequency of channel ch */
|
||||
double get_center_freq(bladerf_channel ch);
|
||||
|
||||
osmosdr::gain_range_t _vga1_range;
|
||||
osmosdr::gain_range_t _vga2_range;
|
||||
/* Get range of supported bandwidths for channel ch */
|
||||
osmosdr::freq_range_t filter_bandwidths(bladerf_channel ch);
|
||||
/* Set the bandwidth on channel ch to bandwidth */
|
||||
double set_bandwidth(double bandwidth, bladerf_channel ch);
|
||||
/* Get the current bandwidth of channel ch */
|
||||
double get_bandwidth(bladerf_channel ch);
|
||||
|
||||
std::string _pfx;
|
||||
/* Get the names of gain stages on channel ch */
|
||||
std::vector<std::string> get_gain_names(bladerf_channel ch);
|
||||
/* Get range of supported overall gain values on channel ch */
|
||||
osmosdr::gain_range_t get_gain_range(bladerf_channel ch);
|
||||
/* Get range of supported gain values for gain stage 'name' on channel ch */
|
||||
osmosdr::gain_range_t get_gain_range(std::string const &name,
|
||||
bladerf_channel ch);
|
||||
|
||||
bool _xb_200_attached;
|
||||
/* Enable or disable the automatic gain control on channel ch */
|
||||
bool set_gain_mode(bool automatic, bladerf_channel ch,
|
||||
bladerf_gain_mode agc_mode = BLADERF_GAIN_DEFAULT);
|
||||
/* Get the current automatic gain control status on channel ch */
|
||||
bool get_gain_mode(bladerf_channel ch);
|
||||
|
||||
/* Set the overall gain value on channel ch */
|
||||
double set_gain(double gain, bladerf_channel ch);
|
||||
/* Set the gain of stage 'name' on channel ch */
|
||||
double set_gain(double gain, std::string const &name, bladerf_channel ch);
|
||||
/* Get the overall gain value on channel ch */
|
||||
double get_gain(bladerf_channel ch);
|
||||
/* Get the gain of stage 'name' on channel ch */
|
||||
double get_gain(std::string const &name, bladerf_channel ch);
|
||||
|
||||
/* Get the list of antennas supported by a channel */
|
||||
std::vector<std::string> get_antennas(bladerf_direction dir);
|
||||
bool set_antenna(bladerf_direction dir, size_t chan, const std::string &antenna);
|
||||
|
||||
/* Set the DC offset on channel ch */
|
||||
int set_dc_offset(std::complex<double> const &offset, bladerf_channel ch);
|
||||
/* Set the IQ balance on channel ch */
|
||||
int set_iq_balance(std::complex<double> const &balance, bladerf_channel ch);
|
||||
|
||||
/* Get the list of supported clock sources */
|
||||
std::vector<std::string> get_clock_sources(size_t mboard = 0);
|
||||
/* Set the clock source to */
|
||||
void set_clock_source(std::string const &source, size_t mboard = 0);
|
||||
/* Get the name of the current clock source */
|
||||
std::string get_clock_source(size_t mboard = 0);
|
||||
|
||||
/* Set the SMB frequency */
|
||||
void set_smb_frequency(double frequency);
|
||||
/* Get the current SMB frequency */
|
||||
double get_smb_frequency();
|
||||
|
||||
/*****************************************************************************
|
||||
* Protected members
|
||||
****************************************************************************/
|
||||
bladerf_sptr _dev; /**< shared pointer for the active device */
|
||||
std::string _pfx; /**< prefix for console messages */
|
||||
unsigned int _failures; /**< counter for consecutive rx/tx failures */
|
||||
|
||||
size_t _num_buffers; /**< number of buffers to allocate */
|
||||
size_t _samples_per_buffer; /**< how many samples per buffer */
|
||||
size_t _num_transfers; /**< number of active backend transfers */
|
||||
unsigned int _stream_timeout; /**< timeout for backend transfers */
|
||||
|
||||
bladerf_format _format; /**< sample format to use */
|
||||
|
||||
bladerf_channel_map _chanmap; /**< map of antennas to channels */
|
||||
bladerf_channel_enable_map _enables; /**< enabled channels */
|
||||
|
||||
/*****************************************************************************
|
||||
* Protected constants
|
||||
****************************************************************************/
|
||||
/* Maximum bladerf_sync_{rx,tx} failures to allow before giving up */
|
||||
static const unsigned int MAX_CONSECUTIVE_FAILURES = 3;
|
||||
|
||||
/* BladeRF IQ correction parameters */
|
||||
static const int16_t DCOFF_SCALE = 2048;
|
||||
static const int16_t GAIN_SCALE = 4096;
|
||||
static const int16_t PHASE_SCALE = 4096;
|
||||
static const int16_t DCOFF_SCALE = 2048;
|
||||
static const int16_t GAIN_SCALE = 4096;
|
||||
static const int16_t PHASE_SCALE = 4096;
|
||||
|
||||
private:
|
||||
/*****************************************************************************
|
||||
* Private methods
|
||||
****************************************************************************/
|
||||
/* Open the bladeRF described by device_name. Returns a sptr if successful */
|
||||
bladerf_sptr open(const std::string &device_name);
|
||||
static void close(void *dev); /* called by shared_ptr */
|
||||
/* Called by shared_ptr when a bladerf_sptr hits a refcount of 0 */
|
||||
static void close(void *dev);
|
||||
/* If a device described by devinfo is open, this returns a sptr to it */
|
||||
static bladerf_sptr get_cached_device(struct bladerf_devinfo devinfo);
|
||||
/* Prints a summary of device information */
|
||||
void print_device_info();
|
||||
|
||||
void set_verbosity(const std::string &verbosity);
|
||||
void set_loopback_mode(const std::string &loopback);
|
||||
bool is_antenna_valid(bladerf_direction dir, const std::string &antenna);
|
||||
|
||||
static boost::mutex _devs_mutex;
|
||||
static std::list<boost::weak_ptr<struct bladerf> > _devs;
|
||||
/*****************************************************************************
|
||||
* Private members
|
||||
****************************************************************************/
|
||||
static std::mutex _devs_mutex; /**< mutex for access to _devs */
|
||||
static std::list<std::weak_ptr<struct bladerf> > _devs; /**< dev cache */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2017 Nuand LLC
|
||||
*
|
||||
* GNU Radio 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef INCLUDED_BLADERF_COMPAT_H
|
||||
#define INCLUDED_BLADERF_COMPAT_H
|
||||
|
||||
#if defined(LIBBLADERF_API_VERSION) && (LIBBLADERF_API_VERSION < 0x01080100)
|
||||
#warning Old libbladeRF detected: using compatibility workarounds.
|
||||
|
||||
#define BLADERF_COMPATIBILITY
|
||||
|
||||
/* New libbladeRF supports multiple channels, via various enums. */
|
||||
typedef bladerf_module bladerf_channel;
|
||||
#define BLADERF_CHANNEL_RX(ch) BLADERF_MODULE_RX
|
||||
#define BLADERF_CHANNEL_TX(ch) BLADERF_MODULE_TX
|
||||
#define BLADERF_CHANNEL_INVALID BLADERF_MODULE_INVALID
|
||||
|
||||
typedef bladerf_module bladerf_channel_layout;
|
||||
#define BLADERF_RX_X1 BLADERF_MODULE_RX
|
||||
#define BLADERF_TX_X1 BLADERF_MODULE_TX
|
||||
#define BLADERF_RX_X2 BLADERF_MODULE_INVALID
|
||||
#define BLADERF_TX_X2 BLADERF_MODULE_INVALID
|
||||
|
||||
typedef bladerf_module bladerf_direction;
|
||||
#define BLADERF_RX BLADERF_MODULE_RX
|
||||
#define BLADERF_TX BLADERF_MODULE_TX
|
||||
#define BLADERF_DIRECTION_MASK (0x1)
|
||||
|
||||
/* Changed API calls */
|
||||
static
|
||||
int bladerf_get_frequency(struct bladerf *dev,
|
||||
bladerf_channel ch,
|
||||
uint64_t *freq) // was unsigned int *frequency
|
||||
{
|
||||
unsigned int f32 = 0;
|
||||
int status = bladerf_get_frequency(dev, ch, &f32);
|
||||
*freq = static_cast<uint64_t>(f32);
|
||||
return status;
|
||||
}
|
||||
|
||||
static
|
||||
int bladerf_sync_tx(struct bladerf *dev,
|
||||
void const *samples, // was void *samples
|
||||
unsigned int num_samples,
|
||||
struct bladerf_metadata *metadata,
|
||||
unsigned int timeout_ms)
|
||||
{
|
||||
void *s = const_cast<void *>(samples);
|
||||
return bladerf_sync_tx(dev, s, num_samples, metadata, timeout_ms);
|
||||
}
|
||||
|
||||
/* Changed enums/defines */
|
||||
#define BLADERF_GAIN_DEFAULT BLADERF_GAIN_MANUAL
|
||||
#define BLADERF_GAIN_MGC BLADERF_GAIN_MANUAL
|
||||
#define BLADERF_RX_MUX_BASEBAND BLADERF_RX_MUX_BASEBAND_LMS
|
||||
|
||||
/* New functionality with no equivalent */
|
||||
#define BLADERF_LB_AD9361_BIST BLADERF_LB_NONE
|
||||
#define bladerf_get_board_name(name) "bladerf1"
|
||||
|
||||
#endif // libbladeRF < 1.8.1
|
||||
#endif // INCLUDED_BLADERF_COMPAT_H
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2013 Nuand LLC
|
||||
* Copyright 2013-2017 Nuand LLC
|
||||
* Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
|
@ -36,377 +36,570 @@
|
|||
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
#include <volk/volk.h>
|
||||
|
||||
#include "arg_helpers.h"
|
||||
#include "bladerf_sink_c.h"
|
||||
#include "osmosdr/sink.h"
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
/******************************************************************************
|
||||
* Functions
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* Create a new instance of bladerf_sink_c and return
|
||||
* a boost shared_ptr. This is effectively the public constructor.
|
||||
*/
|
||||
bladerf_sink_c_sptr make_bladerf_sink_c (const std::string &args)
|
||||
bladerf_sink_c_sptr make_bladerf_sink_c(const std::string &args)
|
||||
{
|
||||
return gnuradio::get_initial_sptr(new bladerf_sink_c (args));
|
||||
return gnuradio::get_initial_sptr(new bladerf_sink_c(args));
|
||||
}
|
||||
|
||||
/*
|
||||
* Specify constraints on number of input and output streams.
|
||||
* This info is used to construct the input and output signatures
|
||||
* (2nd & 3rd args to gr_block's constructor). The input and
|
||||
* output signatures are used by the runtime system to
|
||||
* check that a valid number and type of inputs and outputs
|
||||
* are connected to this block. In this case, we accept
|
||||
* only 0 input and 1 output.
|
||||
*/
|
||||
static const int MIN_IN = 1; // mininum number of input streams
|
||||
static const int MAX_IN = 1; // maximum number of input streams
|
||||
static const int MIN_OUT = 0; // minimum number of output streams
|
||||
static const int MAX_OUT = 0; // maximum number of output streams
|
||||
/******************************************************************************
|
||||
* Private methods
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* The private constructor
|
||||
*/
|
||||
bladerf_sink_c::bladerf_sink_c (const std::string &args)
|
||||
: gr::sync_block ("bladerf_sink_c",
|
||||
gr::io_signature::make (MIN_IN, MAX_IN, sizeof (gr_complex)),
|
||||
gr::io_signature::make (MIN_OUT, MAX_OUT, sizeof (gr_complex)))
|
||||
bladerf_sink_c::bladerf_sink_c(const std::string &args) :
|
||||
gr::sync_block( "bladerf_sink_c",
|
||||
args_to_io_signature(args),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
_16icbuf(NULL),
|
||||
_32fcbuf(NULL),
|
||||
_in_burst(false),
|
||||
_running(false)
|
||||
{
|
||||
dict_t dict = params_to_dict(args);
|
||||
|
||||
/* Perform src/sink agnostic initializations */
|
||||
init(dict, BLADERF_MODULE_TX);
|
||||
init(dict, BLADERF_TX);
|
||||
|
||||
/* Set the range of VGA1, VGA1GAINT[7:0] */
|
||||
_vga1_range = osmosdr::gain_range_t( -35, -4, 1 );
|
||||
|
||||
/* Set the range of VGA2, VGA2GAIN[4:0] */
|
||||
_vga2_range = osmosdr::gain_range_t( 0, 25, 1 );
|
||||
}
|
||||
|
||||
bool bladerf_sink_c::start()
|
||||
{
|
||||
return bladerf_common::start(BLADERF_MODULE_TX);
|
||||
}
|
||||
|
||||
bool bladerf_sink_c::stop()
|
||||
{
|
||||
return bladerf_common::stop(BLADERF_MODULE_TX);
|
||||
}
|
||||
|
||||
int bladerf_sink_c::work( int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items )
|
||||
{
|
||||
const gr_complex *in = (const gr_complex *) input_items[0];
|
||||
struct bladerf_metadata meta;
|
||||
const float scaling = 2000.0f;
|
||||
int ret;
|
||||
|
||||
if (noutput_items > _conv_buf_size) {
|
||||
void *tmp;
|
||||
|
||||
_conv_buf_size = noutput_items;
|
||||
tmp = realloc(_conv_buf, _conv_buf_size * 2 * sizeof(int16_t));
|
||||
if (tmp == NULL) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) +
|
||||
"Failed to realloc _conv_buf" );
|
||||
}
|
||||
|
||||
_conv_buf = static_cast<int16_t*>(tmp);
|
||||
/* Check for RX-only params */
|
||||
if (dict.count("loopback")) {
|
||||
BLADERF_WARNING("Warning: 'loopback' has been specified on a bladeRF "
|
||||
"sink, and will have no effect. This parameter should be "
|
||||
"specified on the associated bladeRF source.");
|
||||
}
|
||||
|
||||
/* Convert floating point samples into fixed point */
|
||||
for (int i = 0; i < 2 * noutput_items;) {
|
||||
_conv_buf[i++] = (int16_t)(scaling * real(*in));
|
||||
_conv_buf[i++] = (int16_t)(scaling * imag(*in++));
|
||||
if (dict.count("rxmux")) {
|
||||
BLADERF_WARNING("Warning: 'rxmux' has been specified on a bladeRF sink, "
|
||||
"and will have no effect.");
|
||||
}
|
||||
|
||||
/* Submit them to the device */
|
||||
ret = bladerf_sync_tx(_dev.get(), static_cast<void *>(_conv_buf),
|
||||
noutput_items, &meta, _stream_timeout_ms);
|
||||
|
||||
if ( ret != 0 ) {
|
||||
std::cerr << _pfx << "bladerf_sync_tx error: "
|
||||
<< bladerf_strerror(ret) << std::endl;
|
||||
return WORK_DONE;
|
||||
/* Bias tee */
|
||||
if (dict.count("biastee")) {
|
||||
set_biastee_mode(dict["biastee"]);
|
||||
}
|
||||
|
||||
return noutput_items;
|
||||
/* Initialize channel <-> antenna map */
|
||||
for (std::string ant : get_antennas()) {
|
||||
_chanmap[str2channel(ant)] = -1;
|
||||
}
|
||||
|
||||
/* Bounds-checking output signature depending on our underlying hardware */
|
||||
if (get_num_channels() > get_max_channels()) {
|
||||
BLADERF_WARNING("Warning: number of channels specified on command line ("
|
||||
<< get_num_channels() << ") is greater than the maximum "
|
||||
"number supported by this device (" << get_max_channels()
|
||||
<< "). Resetting to " << get_max_channels() << ".");
|
||||
|
||||
set_input_signature(gr::io_signature::make(get_max_channels(),
|
||||
get_max_channels(),
|
||||
sizeof(gr_complex)));
|
||||
}
|
||||
|
||||
/* Set up constraints */
|
||||
int const alignment_multiple = volk_get_alignment() / sizeof(gr_complex);
|
||||
set_alignment(std::max(1,alignment_multiple));
|
||||
set_max_noutput_items(_samples_per_buffer);
|
||||
set_output_multiple(get_num_channels());
|
||||
|
||||
/* Set channel layout */
|
||||
_layout = (get_num_channels() > 1) ? BLADERF_TX_X2 : BLADERF_TX_X1;
|
||||
|
||||
/* Initial wiring of antennas to channels */
|
||||
for (size_t ch = 0; ch < get_num_channels(); ++ch) {
|
||||
set_channel_enable(BLADERF_CHANNEL_TX(ch), true);
|
||||
_chanmap[BLADERF_CHANNEL_TX(ch)] = ch;
|
||||
}
|
||||
|
||||
BLADERF_DEBUG("initialization complete");
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Public methods
|
||||
******************************************************************************/
|
||||
|
||||
std::string bladerf_sink_c::name()
|
||||
{
|
||||
return "bladeRF transmitter";
|
||||
}
|
||||
|
||||
std::vector<std::string> bladerf_sink_c::get_devices()
|
||||
{
|
||||
return bladerf_common::devices();
|
||||
}
|
||||
|
||||
size_t bladerf_sink_c::get_max_channels()
|
||||
{
|
||||
return bladerf_common::get_max_channels(BLADERF_TX);
|
||||
}
|
||||
|
||||
size_t bladerf_sink_c::get_num_channels()
|
||||
{
|
||||
/* We only support a single channel for each bladeRF */
|
||||
return 1;
|
||||
return input_signature()->max_streams();
|
||||
}
|
||||
|
||||
bool bladerf_sink_c::start()
|
||||
{
|
||||
int status;
|
||||
|
||||
BLADERF_DEBUG("starting sink");
|
||||
|
||||
gr::thread::scoped_lock guard(d_mutex);
|
||||
|
||||
_in_burst = false;
|
||||
|
||||
status = bladerf_sync_config(_dev.get(), _layout, _format, _num_buffers,
|
||||
_samples_per_buffer, _num_transfers,
|
||||
_stream_timeout);
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "bladerf_sync_config failed");
|
||||
}
|
||||
|
||||
for (size_t ch = 0; ch < get_max_channels(); ++ch) {
|
||||
bladerf_channel brfch = BLADERF_CHANNEL_TX(ch);
|
||||
status = bladerf_enable_module(_dev.get(), brfch, get_channel_enable(brfch));
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate memory for conversions in work() */
|
||||
size_t alignment = volk_get_alignment();
|
||||
|
||||
_16icbuf = reinterpret_cast<int16_t *>(volk_malloc(2*_samples_per_buffer*sizeof(int16_t), alignment));
|
||||
_32fcbuf = reinterpret_cast<gr_complex *>(volk_malloc(_samples_per_buffer*sizeof(gr_complex), alignment));
|
||||
|
||||
_running = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bladerf_sink_c::stop()
|
||||
{
|
||||
int status;
|
||||
|
||||
BLADERF_DEBUG("stopping sink");
|
||||
|
||||
gr::thread::scoped_lock guard(d_mutex);
|
||||
|
||||
if (!_running) {
|
||||
BLADERF_WARNING("sink already stopped, nothing to do here");
|
||||
return true;
|
||||
}
|
||||
|
||||
_running = false;
|
||||
|
||||
for (size_t ch = 0; ch < get_max_channels(); ++ch) {
|
||||
bladerf_channel brfch = BLADERF_CHANNEL_TX(ch);
|
||||
status = bladerf_enable_module(_dev.get(), brfch, get_channel_enable(brfch));
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
|
||||
}
|
||||
}
|
||||
|
||||
/* Deallocate conversion memory */
|
||||
volk_free(_16icbuf);
|
||||
volk_free(_32fcbuf);
|
||||
_16icbuf = NULL;
|
||||
_32fcbuf = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int bladerf_sink_c::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
int status;
|
||||
size_t nstreams = num_streams(_layout);
|
||||
|
||||
gr::thread::scoped_lock guard(d_mutex);
|
||||
|
||||
// if we aren't running, nothing to do here
|
||||
if (!_running) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// copy the samples from input_items
|
||||
gr_complex const **in = reinterpret_cast<gr_complex const **>(&input_items[0]);
|
||||
|
||||
if (nstreams > 1) {
|
||||
// we need to interleave the streams as we copy
|
||||
gr_complex *intl_out = _32fcbuf;
|
||||
|
||||
for (size_t i = 0; i < (noutput_items/nstreams); ++i) {
|
||||
for (size_t n = 0; n < nstreams; ++n) {
|
||||
memcpy(intl_out++, in[n]++, sizeof(gr_complex));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// no interleaving to do: simply copy everything
|
||||
memcpy(_32fcbuf, in[0], noutput_items * sizeof(gr_complex));
|
||||
}
|
||||
|
||||
// convert floating point to fixed point and scale
|
||||
// input_items is gr_complex (2x float), so num_points is 2*noutput_items
|
||||
volk_32f_s32f_convert_16i(_16icbuf, reinterpret_cast<float const *>(_32fcbuf),
|
||||
SCALING_FACTOR, 2*noutput_items);
|
||||
|
||||
// transmit the samples from the temp buffer
|
||||
if (BLADERF_FORMAT_SC16_Q11_META == _format) {
|
||||
status = transmit_with_tags(_16icbuf, noutput_items);
|
||||
} else {
|
||||
status = bladerf_sync_tx(_dev.get(), static_cast<void const *>(_16icbuf),
|
||||
noutput_items, NULL, _stream_timeout);
|
||||
}
|
||||
|
||||
// handle failure
|
||||
if (status != 0) {
|
||||
BLADERF_WARNING("bladerf_sync_tx error: " << bladerf_strerror(status));
|
||||
++_failures;
|
||||
|
||||
if (_failures >= MAX_CONSECUTIVE_FAILURES) {
|
||||
BLADERF_WARNING("Consecutive error limit hit. Shutting down.");
|
||||
return WORK_DONE;
|
||||
}
|
||||
} else {
|
||||
_failures = 0;
|
||||
}
|
||||
|
||||
return noutput_items;
|
||||
}
|
||||
|
||||
int bladerf_sink_c::transmit_with_tags(int16_t const *samples,
|
||||
int noutput_items)
|
||||
{
|
||||
int status;
|
||||
int count = 0;
|
||||
|
||||
// For a long burst, we may be transmitting the burst contents over
|
||||
// multiple work calls, so we'll just be sending the entire buffer
|
||||
// Therefore, we initialize our indicies for this case.
|
||||
int start_idx = 0;
|
||||
int end_idx = (noutput_items - 1);
|
||||
|
||||
struct bladerf_metadata meta;
|
||||
std::vector<gr::tag_t> tags;
|
||||
|
||||
int const INVALID_IDX = -1;
|
||||
int16_t const zeros[8] = { 0 };
|
||||
|
||||
memset(&meta, 0, sizeof(meta));
|
||||
|
||||
BLADERF_DEBUG("transmit_with_tags(" << noutput_items << ")");
|
||||
|
||||
// Important Note: We assume that these tags are ordered by their offsets.
|
||||
// This is true for GNU Radio 3.7.7.x, since the GR runtime libs store
|
||||
// these in a multimap.
|
||||
//
|
||||
// If you're using an earlier GNU Radio version, you may have to sort
|
||||
// the tags vector.
|
||||
get_tags_in_window(tags, 0, 0, noutput_items);
|
||||
|
||||
if (tags.size() == 0) {
|
||||
if (_in_burst) {
|
||||
BLADERF_DEBUG("TX'ing " << noutput_items << " samples within a burst...");
|
||||
|
||||
return bladerf_sync_tx(_dev.get(), samples, noutput_items,
|
||||
&meta, _stream_timeout);
|
||||
} else {
|
||||
BLADERF_WARNING("Dropping " << noutput_items
|
||||
<< " samples not in a burst.");
|
||||
}
|
||||
}
|
||||
|
||||
for (gr::tag_t tag : tags) {
|
||||
// Upon seeing an SOB tag, update our offset. We'll TX the start of the
|
||||
// burst when we see an EOB or at the end of this function - whichever
|
||||
// occurs first.
|
||||
if (pmt::symbol_to_string(tag.key) == "tx_sob") {
|
||||
if (_in_burst) {
|
||||
BLADERF_WARNING("Got SOB while already within a burst");
|
||||
|
||||
return BLADERF_ERR_INVAL;
|
||||
} else {
|
||||
start_idx = static_cast<int>(tag.offset - nitems_read(0));
|
||||
|
||||
BLADERF_DEBUG("Got SOB " << start_idx << " samples into work payload");
|
||||
|
||||
meta.flags |= (BLADERF_META_FLAG_TX_NOW | BLADERF_META_FLAG_TX_BURST_START);
|
||||
_in_burst = true;
|
||||
}
|
||||
|
||||
} else if (pmt::symbol_to_string(tag.key) == "tx_eob") {
|
||||
if (!_in_burst) {
|
||||
BLADERF_WARNING("Got EOB while not in burst");
|
||||
return BLADERF_ERR_INVAL;
|
||||
}
|
||||
|
||||
// Upon seeing an EOB, transmit what we have and reset our state
|
||||
end_idx = static_cast<int>(tag.offset - nitems_read(0));
|
||||
BLADERF_DEBUG("Got EOB " << end_idx << " samples into work payload");
|
||||
|
||||
if ((start_idx == INVALID_IDX) || (start_idx > end_idx)) {
|
||||
BLADERF_DEBUG("Buffer indicies are in an invalid state!");
|
||||
return BLADERF_ERR_INVAL;
|
||||
}
|
||||
|
||||
count = end_idx - start_idx + 1;
|
||||
|
||||
BLADERF_DEBUG("TXing @ EOB [" << start_idx << ":" << end_idx << "]");
|
||||
|
||||
status = bladerf_sync_tx(_dev.get(),
|
||||
static_cast<void const *>(&samples[2 * start_idx]),
|
||||
count, &meta, _stream_timeout);
|
||||
if (status != 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* TODO: libbladeRF should now take care of this for us,
|
||||
* as of the libbladeRF version that includes the
|
||||
* TX_UPDATE_TIMESTAMP flag. Verify this potentially remove this.
|
||||
* (The meta.flags changes would then be applied to the previous
|
||||
* bladerf_sync_tx() call.)
|
||||
*/
|
||||
BLADERF_DEBUG("TXing Zeros with burst end flag");
|
||||
|
||||
meta.flags &= ~(BLADERF_META_FLAG_TX_NOW | BLADERF_META_FLAG_TX_BURST_START);
|
||||
meta.flags |= BLADERF_META_FLAG_TX_BURST_END;
|
||||
|
||||
status = bladerf_sync_tx(_dev.get(), static_cast<void const *>(zeros),
|
||||
4, &meta, _stream_timeout);
|
||||
|
||||
/* Reset our state */
|
||||
start_idx = INVALID_IDX;
|
||||
end_idx = (noutput_items - 1);
|
||||
meta.flags = 0;
|
||||
_in_burst = false;
|
||||
|
||||
if (status != 0) {
|
||||
BLADERF_DEBUG("Failed to send zero samples to flush EOB");
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We had a start of burst with no end yet - transmit those samples
|
||||
if (_in_burst) {
|
||||
count = end_idx - start_idx + 1;
|
||||
|
||||
BLADERF_DEBUG("TXing SOB [" << start_idx << ":" << end_idx << "]");
|
||||
|
||||
status = bladerf_sync_tx(_dev.get(),
|
||||
static_cast<void const *>(&samples[2 * start_idx]),
|
||||
count, &meta, _stream_timeout);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
osmosdr::meta_range_t bladerf_sink_c::get_sample_rates()
|
||||
{
|
||||
return sample_rates();
|
||||
return sample_rates(chan2channel(BLADERF_TX, 0));
|
||||
}
|
||||
|
||||
double bladerf_sink_c::set_sample_rate(double rate)
|
||||
{
|
||||
return bladerf_common::set_sample_rate(BLADERF_MODULE_TX, rate);
|
||||
return bladerf_common::set_sample_rate(rate, chan2channel(BLADERF_TX, 0));
|
||||
}
|
||||
|
||||
double bladerf_sink_c::get_sample_rate()
|
||||
{
|
||||
return bladerf_common::get_sample_rate(BLADERF_MODULE_TX);
|
||||
return bladerf_common::get_sample_rate(chan2channel(BLADERF_TX, 0));
|
||||
}
|
||||
|
||||
osmosdr::freq_range_t bladerf_sink_c::get_freq_range( size_t chan )
|
||||
osmosdr::freq_range_t bladerf_sink_c::get_freq_range(size_t chan)
|
||||
{
|
||||
return freq_range();
|
||||
return bladerf_common::freq_range(chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
double bladerf_sink_c::set_center_freq( double freq, size_t chan )
|
||||
double bladerf_sink_c::set_center_freq(double freq, size_t chan)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check frequency range */
|
||||
if( freq < get_freq_range( chan ).start() ||
|
||||
freq > get_freq_range( chan ).stop() ) {
|
||||
std::cerr << "Failed to set out of bound frequency: " << freq << std::endl;
|
||||
} else {
|
||||
ret = bladerf_set_frequency( _dev.get(), BLADERF_MODULE_TX, (uint32_t)freq );
|
||||
if( ret ) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"Failed to set center frequency " +
|
||||
boost::lexical_cast<std::string>(freq) +
|
||||
":" + std::string(bladerf_strerror(ret)));
|
||||
}
|
||||
}
|
||||
|
||||
return get_center_freq( chan );
|
||||
return bladerf_common::set_center_freq(freq, chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
double bladerf_sink_c::get_center_freq( size_t chan )
|
||||
double bladerf_sink_c::get_center_freq(size_t chan)
|
||||
{
|
||||
uint32_t freq;
|
||||
int ret;
|
||||
|
||||
ret = bladerf_get_frequency( _dev.get(), BLADERF_MODULE_TX, &freq );
|
||||
if( ret ) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"Failed to get center frequency:" +
|
||||
std::string(bladerf_strerror(ret)));
|
||||
}
|
||||
|
||||
return (double)freq;
|
||||
return bladerf_common::get_center_freq(chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
double bladerf_sink_c::set_freq_corr( double ppm, size_t chan )
|
||||
double bladerf_sink_c::set_freq_corr(double ppm, size_t chan)
|
||||
{
|
||||
/* TODO: Write the VCTCXO with a correction value (also changes RX ppm value!) */
|
||||
return get_freq_corr( chan );
|
||||
BLADERF_WARNING("Frequency correction is not implemented.");
|
||||
return get_freq_corr(chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
double bladerf_sink_c::get_freq_corr( size_t chan )
|
||||
double bladerf_sink_c::get_freq_corr(size_t chan)
|
||||
{
|
||||
/* TODO: Return back the frequency correction in ppm */
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<std::string> bladerf_sink_c::get_gain_names( size_t chan )
|
||||
std::vector<std::string> bladerf_sink_c::get_gain_names(size_t chan)
|
||||
{
|
||||
std::vector< std::string > names;
|
||||
|
||||
names += "VGA1", "VGA2";
|
||||
|
||||
return names;
|
||||
return bladerf_common::get_gain_names(chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t bladerf_sink_c::get_gain_range( size_t chan )
|
||||
osmosdr::gain_range_t bladerf_sink_c::get_gain_range(size_t chan)
|
||||
{
|
||||
/* TODO: This is an overall system gain range. Given the VGA1 and VGA2
|
||||
how much total gain can we have in the system */
|
||||
return get_gain_range( "VGA2", chan ); /* we use only VGA2 here for now */
|
||||
return bladerf_common::get_gain_range(chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t bladerf_sink_c::get_gain_range( const std::string & name, size_t chan )
|
||||
osmosdr::gain_range_t bladerf_sink_c::get_gain_range(const std::string &name,
|
||||
size_t chan)
|
||||
{
|
||||
osmosdr::gain_range_t range;
|
||||
return bladerf_common::get_gain_range(name, chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
if( name == "VGA1" ) {
|
||||
range = _vga1_range;
|
||||
} else if( name == "VGA2" ) {
|
||||
range = _vga2_range;
|
||||
bool bladerf_sink_c::set_gain_mode(bool automatic, size_t chan)
|
||||
{
|
||||
return bladerf_common::set_gain_mode(automatic,
|
||||
chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
bool bladerf_sink_c::get_gain_mode(size_t chan)
|
||||
{
|
||||
return bladerf_common::get_gain_mode(chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
double bladerf_sink_c::set_gain(double gain, size_t chan)
|
||||
{
|
||||
return bladerf_common::set_gain(gain, chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
double bladerf_sink_c::set_gain(double gain, const std::string &name,
|
||||
size_t chan)
|
||||
{
|
||||
return bladerf_common::set_gain(gain, name, chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
double bladerf_sink_c::get_gain(size_t chan)
|
||||
{
|
||||
return bladerf_common::get_gain(chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
double bladerf_sink_c::get_gain(const std::string &name, size_t chan)
|
||||
{
|
||||
return bladerf_common::get_gain(name, chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
std::vector<std::string> bladerf_sink_c::get_antennas(size_t chan)
|
||||
{
|
||||
return bladerf_common::get_antennas(BLADERF_TX);
|
||||
}
|
||||
|
||||
std::string bladerf_sink_c::set_antenna(const std::string &antenna,
|
||||
size_t chan)
|
||||
{
|
||||
bool _was_running = _running;
|
||||
|
||||
if (_was_running) {
|
||||
stop();
|
||||
}
|
||||
|
||||
bladerf_common::set_antenna(BLADERF_TX, chan, antenna);
|
||||
|
||||
if (_was_running) {
|
||||
start();
|
||||
}
|
||||
|
||||
return get_antenna(chan);
|
||||
}
|
||||
|
||||
std::string bladerf_sink_c::get_antenna(size_t chan)
|
||||
{
|
||||
return channel2str(chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
void bladerf_sink_c::set_dc_offset(const std::complex < double > &offset,
|
||||
size_t chan)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = bladerf_common::set_dc_offset(offset, chan2channel(BLADERF_TX, chan));
|
||||
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "could not set dc offset");
|
||||
}
|
||||
}
|
||||
|
||||
void bladerf_sink_c::set_iq_balance(const std::complex < double > &balance,
|
||||
size_t chan)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = bladerf_common::set_iq_balance(balance, chan2channel(BLADERF_TX, chan));
|
||||
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "could not set iq balance");
|
||||
}
|
||||
}
|
||||
|
||||
osmosdr::freq_range_t bladerf_sink_c::get_bandwidth_range(size_t chan)
|
||||
{
|
||||
return filter_bandwidths(chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
double bladerf_sink_c::set_bandwidth(double bandwidth, size_t chan)
|
||||
{
|
||||
return bladerf_common::set_bandwidth(bandwidth, chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
double bladerf_sink_c::get_bandwidth(size_t chan)
|
||||
{
|
||||
return bladerf_common::get_bandwidth(chan2channel(BLADERF_TX, chan));
|
||||
}
|
||||
|
||||
std::vector < std::string > bladerf_sink_c::get_clock_sources(size_t mboard)
|
||||
{
|
||||
return bladerf_common::get_clock_sources(mboard);
|
||||
}
|
||||
|
||||
void bladerf_sink_c::set_clock_source(const std::string &source,
|
||||
size_t mboard)
|
||||
{
|
||||
bladerf_common::set_clock_source(source, mboard);
|
||||
}
|
||||
|
||||
std::string bladerf_sink_c::get_clock_source(size_t mboard)
|
||||
{
|
||||
return bladerf_common::get_clock_source(mboard);
|
||||
}
|
||||
|
||||
void bladerf_sink_c::set_biastee_mode(const std::string &mode)
|
||||
{
|
||||
int status;
|
||||
bool enable;
|
||||
|
||||
if (mode == "on" || mode == "1" || mode == "rx") {
|
||||
enable = true;
|
||||
} else {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"Requested an invalid gain element " + name );
|
||||
enable = false;
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
bool bladerf_sink_c::set_gain_mode( bool automatic, size_t chan )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bladerf_sink_c::get_gain_mode( size_t chan )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
double bladerf_sink_c::set_gain( double gain, size_t chan )
|
||||
{
|
||||
return set_gain( gain, "VGA2", chan ); /* we use only VGA2 here for now */
|
||||
}
|
||||
|
||||
double bladerf_sink_c::set_gain( double gain, const std::string & name, size_t chan)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if( name == "VGA1" ) {
|
||||
ret = bladerf_set_txvga1( _dev.get(), (int)gain );
|
||||
} else if( name == "VGA2" ) {
|
||||
ret = bladerf_set_txvga2( _dev.get(), (int)gain );
|
||||
} else {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"Requested to set the gain " +
|
||||
"of an unknown gain element " + name );
|
||||
}
|
||||
|
||||
/* Check for errors */
|
||||
if( ret ) {
|
||||
throw std::runtime_error(std::string(__FUNCTION__) + " " +
|
||||
"Could not set " + name + " gain, error " +
|
||||
std::string(bladerf_strerror(ret)));
|
||||
}
|
||||
|
||||
return get_gain( name, chan );
|
||||
}
|
||||
|
||||
double bladerf_sink_c::get_gain( size_t chan )
|
||||
{
|
||||
return get_gain( "VGA2", chan ); /* we use only VGA2 here for now */
|
||||
}
|
||||
|
||||
double bladerf_sink_c::get_gain( const std::string & name, size_t chan )
|
||||
{
|
||||
int g;
|
||||
int ret = 0;
|
||||
|
||||
if( name == "VGA1" ) {
|
||||
ret = bladerf_get_txvga1( _dev.get(), &g );
|
||||
} else if( name == "VGA2" ) {
|
||||
ret = bladerf_get_txvga2( _dev.get(), &g );
|
||||
} else {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"Requested to get the gain " +
|
||||
"of an unknown gain element " + name );
|
||||
}
|
||||
|
||||
/* Check for errors */
|
||||
if( ret ) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"Could not get " + name + " gain, error " +
|
||||
std::string(bladerf_strerror(ret)));
|
||||
}
|
||||
|
||||
return (double)g;
|
||||
}
|
||||
|
||||
double bladerf_sink_c::set_bb_gain( double gain, size_t chan )
|
||||
{
|
||||
/* for TX, only VGA1 is in the BB path */
|
||||
osmosdr::gain_range_t bb_gains = get_gain_range( "VGA1", chan );
|
||||
|
||||
double clip_gain = bb_gains.clip( gain, true );
|
||||
gain = set_gain( clip_gain, "VGA1", chan );
|
||||
|
||||
return gain;
|
||||
}
|
||||
|
||||
std::vector< std::string > bladerf_sink_c::get_antennas( size_t chan )
|
||||
{
|
||||
std::vector< std::string > antennas;
|
||||
|
||||
antennas += get_antenna( chan );
|
||||
|
||||
return antennas;
|
||||
}
|
||||
|
||||
std::string bladerf_sink_c::set_antenna( const std::string & antenna, size_t chan )
|
||||
{
|
||||
return get_antenna( chan );
|
||||
}
|
||||
|
||||
std::string bladerf_sink_c::get_antenna( size_t chan )
|
||||
{
|
||||
/* We only have a single transmit antenna here */
|
||||
return "TX";
|
||||
}
|
||||
|
||||
void bladerf_sink_c::set_dc_offset( const std::complex<double> &offset, size_t chan )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = bladerf_common::set_dc_offset(BLADERF_MODULE_TX, offset, chan);
|
||||
|
||||
if( ret ) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"could not set dc offset: " +
|
||||
std::string(bladerf_strerror(ret)) );
|
||||
status = bladerf_set_bias_tee(_dev.get(), BLADERF_CHANNEL_TX(0), enable);
|
||||
if (BLADERF_ERR_UNSUPPORTED == status) {
|
||||
// unsupported, but not worth crashing out
|
||||
BLADERF_WARNING("Bias-tee not supported by device");
|
||||
} else if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "Failed to set bias-tee");
|
||||
}
|
||||
}
|
||||
|
||||
void bladerf_sink_c::set_iq_balance( const std::complex<double> &balance, size_t chan )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = bladerf_common::set_iq_balance(BLADERF_MODULE_TX, balance, chan);
|
||||
|
||||
if( ret ) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"could not set iq balance: " +
|
||||
std::string(bladerf_strerror(ret)) );
|
||||
}
|
||||
}
|
||||
|
||||
double bladerf_sink_c::set_bandwidth( double bandwidth, size_t chan )
|
||||
{
|
||||
int ret;
|
||||
uint32_t actual;
|
||||
|
||||
if ( bandwidth == 0.0 ) /* bandwidth of 0 means automatic filter selection */
|
||||
bandwidth = get_sample_rate() * 0.75; /* select narrower filters to prevent aliasing */
|
||||
|
||||
ret = bladerf_set_bandwidth( _dev.get(), BLADERF_MODULE_TX, (uint32_t)bandwidth, &actual );
|
||||
if( ret ) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"could not set bandwidth:" +
|
||||
std::string(bladerf_strerror(ret)) );
|
||||
}
|
||||
|
||||
return get_bandwidth();
|
||||
}
|
||||
|
||||
double bladerf_sink_c::get_bandwidth( size_t chan )
|
||||
{
|
||||
uint32_t bandwidth;
|
||||
int ret;
|
||||
|
||||
ret = bladerf_get_bandwidth( _dev.get(), BLADERF_MODULE_TX, &bandwidth );
|
||||
if( ret ) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"could not get bandwidth: " +
|
||||
std::string(bladerf_strerror(ret)) );
|
||||
}
|
||||
|
||||
return (double)bandwidth;
|
||||
}
|
||||
|
||||
osmosdr::freq_range_t bladerf_sink_c::get_bandwidth_range( size_t chan )
|
||||
{
|
||||
return filter_bandwidths();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2013 Nuand LLC
|
||||
* Copyright 2013-2017 Nuand LLC
|
||||
* Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
|
@ -21,18 +21,16 @@
|
|||
#ifndef INCLUDED_BLADERF_SINK_C_H
|
||||
#define INCLUDED_BLADERF_SINK_C_H
|
||||
|
||||
#include <gnuradio/thread/thread.h>
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
#include "osmosdr/ranges.h"
|
||||
#include "sink_iface.h"
|
||||
#include "bladerf_common.h"
|
||||
|
||||
#include "osmosdr/ranges.h"
|
||||
|
||||
class bladerf_sink_c;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr_blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
|
@ -40,9 +38,9 @@ class bladerf_sink_c;
|
|||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<bladerf_sink_c> bladerf_sink_c_sptr;
|
||||
typedef std::shared_ptr<bladerf_sink_c> bladerf_sink_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of bladerf_sink_c.
|
||||
|
@ -51,64 +49,91 @@ typedef boost::shared_ptr<bladerf_sink_c> bladerf_sink_c_sptr;
|
|||
* constructor is private. make_bladerf_sink_c is the public
|
||||
* interface for creating new instances.
|
||||
*/
|
||||
bladerf_sink_c_sptr make_bladerf_sink_c (const std::string & args = "");
|
||||
bladerf_sink_c_sptr make_bladerf_sink_c(const std::string &args = "");
|
||||
|
||||
class bladerf_sink_c :
|
||||
public gr::sync_block,
|
||||
public sink_iface,
|
||||
protected bladerf_common
|
||||
public gr::sync_block,
|
||||
public sink_iface,
|
||||
protected bladerf_common
|
||||
{
|
||||
private:
|
||||
// The friend declaration allows bladerf_make_sink_c to
|
||||
// access the private constructor.
|
||||
friend bladerf_sink_c_sptr make_bladerf_sink_c (const std::string & args);
|
||||
friend bladerf_sink_c_sptr make_bladerf_sink_c(const std::string &args);
|
||||
|
||||
bladerf_sink_c (const std::string & args); // private constructor
|
||||
bladerf_sink_c(const std::string &args);
|
||||
|
||||
bool is_antenna_valid(const std::string &antenna);
|
||||
|
||||
public:
|
||||
std::string name();
|
||||
|
||||
static std::vector<std::string> get_devices();
|
||||
|
||||
size_t get_max_channels(void);
|
||||
size_t get_num_channels(void);
|
||||
|
||||
bool start();
|
||||
bool stop();
|
||||
|
||||
int work( int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items );
|
||||
int work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
|
||||
static std::vector< std::string > get_devices();
|
||||
osmosdr::meta_range_t get_sample_rates(void);
|
||||
double set_sample_rate(double rate);
|
||||
double get_sample_rate(void);
|
||||
|
||||
size_t get_num_channels( void );
|
||||
osmosdr::freq_range_t get_freq_range(size_t chan = 0);
|
||||
double set_center_freq(double freq, size_t chan = 0);
|
||||
double get_center_freq(size_t chan = 0);
|
||||
|
||||
osmosdr::meta_range_t get_sample_rates( void );
|
||||
double set_sample_rate( double rate );
|
||||
double get_sample_rate( void );
|
||||
double set_freq_corr(double ppm, size_t chan = 0);
|
||||
double get_freq_corr(size_t chan = 0);
|
||||
|
||||
osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
|
||||
double set_center_freq( double freq, size_t chan = 0 );
|
||||
double get_center_freq( size_t chan = 0 );
|
||||
double set_freq_corr( double ppm, size_t chan = 0 );
|
||||
double get_freq_corr( size_t chan = 0 );
|
||||
std::vector<std::string> get_gain_names(size_t chan = 0);
|
||||
osmosdr::gain_range_t get_gain_range(size_t chan = 0);
|
||||
osmosdr::gain_range_t get_gain_range(const std::string &name,
|
||||
size_t chan = 0);
|
||||
bool set_gain_mode(bool automatic, size_t chan = 0);
|
||||
bool get_gain_mode(size_t chan = 0);
|
||||
double set_gain(double gain, size_t chan = 0);
|
||||
double set_gain(double gain, const std::string &name, size_t chan = 0);
|
||||
double get_gain(size_t chan = 0);
|
||||
double get_gain(const std::string &name, size_t chan = 0);
|
||||
|
||||
std::vector<std::string> get_gain_names( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
|
||||
bool set_gain_mode( bool automatic, size_t chan = 0 );
|
||||
bool get_gain_mode( size_t chan = 0 );
|
||||
double set_gain( double gain, size_t chan = 0 );
|
||||
double set_gain( double gain, const std::string & name, size_t chan = 0 );
|
||||
double get_gain( size_t chan = 0 );
|
||||
double get_gain( const std::string & name, size_t chan = 0 );
|
||||
std::vector<std::string> get_antennas(size_t chan = 0);
|
||||
std::string set_antenna(const std::string &antenna, size_t chan = 0);
|
||||
std::string get_antenna(size_t chan = 0);
|
||||
|
||||
double set_bb_gain( double gain, size_t chan = 0 );
|
||||
void set_dc_offset(const std::complex<double> &offset, size_t chan);
|
||||
void set_iq_balance(const std::complex<double> &balance, size_t chan);
|
||||
|
||||
std::vector< std::string > get_antennas( size_t chan = 0 );
|
||||
std::string set_antenna( const std::string & antenna, size_t chan = 0 );
|
||||
std::string get_antenna( size_t chan = 0 );
|
||||
osmosdr::freq_range_t get_bandwidth_range(size_t chan = 0);
|
||||
double set_bandwidth(double bandwidth, size_t chan = 0);
|
||||
double get_bandwidth(size_t chan = 0);
|
||||
|
||||
void set_dc_offset( const std::complex<double> &offset, size_t chan );
|
||||
void set_iq_balance( const std::complex<double> &balance, size_t chan );
|
||||
std::vector<std::string> get_clock_sources(size_t mboard);
|
||||
void set_clock_source(const std::string &source, size_t mboard = 0);
|
||||
std::string get_clock_source(size_t mboard);
|
||||
|
||||
double set_bandwidth( double bandwidth, size_t chan = 0 );
|
||||
double get_bandwidth( size_t chan = 0 );
|
||||
osmosdr::freq_range_t get_bandwidth_range( size_t chan = 0 );
|
||||
void set_biastee_mode(const std::string &mode);
|
||||
|
||||
private:
|
||||
int transmit_with_tags(int16_t const *samples, int noutput_items);
|
||||
|
||||
// Sample-handling buffers
|
||||
int16_t *_16icbuf; /**< raw samples to bladeRF */
|
||||
gr_complex *_32fcbuf; /**< intermediate buffer for conversions */
|
||||
|
||||
bool _in_burst; /**< are we currently in a burst? */
|
||||
bool _running; /**< is the sink running? */
|
||||
bladerf_channel_layout _layout; /**< channel layout */
|
||||
|
||||
gr::thread::mutex d_mutex; /**< mutex to protect set/work access */
|
||||
|
||||
/* Scaling factor used when converting from float to int16_t */
|
||||
const float SCALING_FACTOR = 2048.0f;
|
||||
};
|
||||
|
||||
#endif /* INCLUDED_BLADERF_SINK_C_H */
|
||||
#endif // INCLUDED_BLADERF_SINK_C_H
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2013 Nuand LLC
|
||||
* Copyright 2013-2017 Nuand LLC
|
||||
* Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
|
@ -36,153 +36,166 @@
|
|||
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
#include <volk/volk.h>
|
||||
|
||||
#include "arg_helpers.h"
|
||||
#include "bladerf_source_c.h"
|
||||
#include "osmosdr/source.h"
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
/******************************************************************************
|
||||
* Functions
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* Create a new instance of bladerf_source_c and return
|
||||
* a boost shared_ptr. This is effectively the public constructor.
|
||||
*/
|
||||
bladerf_source_c_sptr make_bladerf_source_c (const std::string &args)
|
||||
bladerf_source_c_sptr make_bladerf_source_c(const std::string &args)
|
||||
{
|
||||
return gnuradio::get_initial_sptr(new bladerf_source_c (args));
|
||||
return gnuradio::get_initial_sptr(new bladerf_source_c(args));
|
||||
}
|
||||
|
||||
/*
|
||||
* Specify constraints on number of input and output streams.
|
||||
* This info is used to construct the input and output signatures
|
||||
* (2nd & 3rd args to gr_block's constructor). The input and
|
||||
* output signatures are used by the runtime system to
|
||||
* check that a valid number and type of inputs and outputs
|
||||
* are connected to this block. In this case, we accept
|
||||
* only 0 input and 1 output.
|
||||
*/
|
||||
static const int MIN_IN = 0; // mininum number of input streams
|
||||
static const int MAX_IN = 0; // maximum number of input streams
|
||||
static const int MIN_OUT = 1; // minimum number of output streams
|
||||
static const int MAX_OUT = 1; // maximum number of output streams
|
||||
/******************************************************************************
|
||||
* Private methods
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* The private constructor
|
||||
*/
|
||||
bladerf_source_c::bladerf_source_c (const std::string &args)
|
||||
: gr::sync_block ("bladerf_source_c",
|
||||
gr::io_signature::make (MIN_IN, MAX_IN, sizeof (gr_complex)),
|
||||
gr::io_signature::make (MIN_OUT, MAX_OUT, sizeof (gr_complex)))
|
||||
bladerf_source_c::bladerf_source_c(const std::string &args) :
|
||||
gr::sync_block( "bladerf_source_c",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
args_to_io_signature(args)),
|
||||
_16icbuf(NULL),
|
||||
_32fcbuf(NULL),
|
||||
_running(false),
|
||||
_agcmode(BLADERF_GAIN_DEFAULT)
|
||||
{
|
||||
int ret;
|
||||
std::string device_name;
|
||||
struct bladerf_version fpga_version;
|
||||
int status;
|
||||
|
||||
dict_t dict = params_to_dict(args);
|
||||
|
||||
init(dict, BLADERF_MODULE_RX);
|
||||
/* Perform src/sink agnostic initializations */
|
||||
init(dict, BLADERF_RX);
|
||||
|
||||
if (dict.count("sampling"))
|
||||
{
|
||||
std::string sampling = dict["sampling"];
|
||||
/* Handle setting of sampling mode */
|
||||
if (dict.count("sampling")) {
|
||||
bladerf_sampling sampling = BLADERF_SAMPLING_UNKNOWN;
|
||||
|
||||
std::cerr << _pfx << "Setting bladerf sampling to " << sampling << std::endl;
|
||||
if( sampling == "internal") {
|
||||
ret = bladerf_set_sampling( _dev.get(), BLADERF_SAMPLING_INTERNAL );
|
||||
if ( ret != 0 )
|
||||
std::cerr << _pfx << "Problem while setting sampling mode:"
|
||||
<< bladerf_strerror(ret) << std::endl;
|
||||
} else if( sampling == "external" ) {
|
||||
ret = bladerf_set_sampling( _dev.get(), BLADERF_SAMPLING_EXTERNAL );
|
||||
if ( ret != 0 )
|
||||
std::cerr << _pfx << "Problem while setting sampling mode:"
|
||||
<< bladerf_strerror(ret) << std::endl;
|
||||
if (dict["sampling"] == "internal") {
|
||||
sampling = BLADERF_SAMPLING_INTERNAL;
|
||||
} else if (dict["sampling"] == "external") {
|
||||
sampling = BLADERF_SAMPLING_EXTERNAL;
|
||||
} else {
|
||||
std::cerr << _pfx << "Invalid sampling mode " << sampling << std::endl;
|
||||
BLADERF_WARNING("Invalid sampling mode: " + dict["sampling"]);
|
||||
}
|
||||
|
||||
if (sampling != BLADERF_SAMPLING_UNKNOWN) {
|
||||
status = bladerf_set_sampling(_dev.get(), sampling);
|
||||
if (status != 0) {
|
||||
BLADERF_WARNING("Problem while setting sampling mode: " <<
|
||||
bladerf_strerror(status));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the range of LNA, G_LNA_RXFE[1:0] */
|
||||
_lna_range = osmosdr::gain_range_t( 0, 6, 3 );
|
||||
/* Bias tee */
|
||||
if (dict.count("biastee")) {
|
||||
set_biastee_mode(dict["biastee"]);
|
||||
}
|
||||
|
||||
/* Set the range of VGA1, RFB_TIA_RXFE[6:0], nonlinear mapping done inside the lib */
|
||||
_vga1_range = osmosdr::gain_range_t( 5, 30, 1 );
|
||||
/* Loopback */
|
||||
set_loopback_mode(dict.count("loopback") ? dict["loopback"] : "none");
|
||||
|
||||
/* Set the range of VGA2 VGA2GAIN[4:0], not recommended to be used above 30dB */
|
||||
_vga2_range = osmosdr::gain_range_t( 0, 30, 3 );
|
||||
/* RX Mux */
|
||||
set_rx_mux_mode(dict.count("rxmux") ? dict["rxmux"] : "baseband");
|
||||
|
||||
/* AGC mode */
|
||||
if (dict.count("agc_mode")) {
|
||||
set_agc_mode(dict["agc_mode"]);
|
||||
}
|
||||
|
||||
/* Specify initial gain mode */
|
||||
if (dict.count("agc")) {
|
||||
for (size_t i = 0; i < get_max_channels(); ++i) {
|
||||
set_gain_mode(boost::lexical_cast<bool>(dict["agc"]), BLADERF_CHANNEL_RX(i));
|
||||
BLADERF_INFO(boost::str(boost::format("%s gain mode set to '%s'")
|
||||
% channel2str(BLADERF_CHANNEL_RX(i))
|
||||
% get_gain_mode(BLADERF_CHANNEL_RX(i))));
|
||||
}
|
||||
}
|
||||
|
||||
/* Warn user about using an old FPGA version, as we no longer strip off the
|
||||
* markers that were pressent in the pre-v0.0.1 FPGA */
|
||||
if (bladerf_fpga_version( _dev.get(), &fpga_version ) != 0) {
|
||||
std::cerr << _pfx << "Failed to get FPGA version" << std::endl;
|
||||
} else if ( fpga_version.major <= 0 &&
|
||||
fpga_version.minor <= 0 &&
|
||||
fpga_version.patch < 1 ) {
|
||||
{
|
||||
struct bladerf_version fpga_version;
|
||||
|
||||
std::cerr << _pfx << "Warning: FPGA version v0.0.1 or later is required. "
|
||||
<< "Using an earlier FPGA version will result in misinterpeted samples. "
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
bool bladerf_source_c::start()
|
||||
{
|
||||
return bladerf_common::start(BLADERF_MODULE_RX);
|
||||
}
|
||||
|
||||
bool bladerf_source_c::stop()
|
||||
{
|
||||
return bladerf_common::stop(BLADERF_MODULE_RX);
|
||||
}
|
||||
|
||||
int bladerf_source_c::work( int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items )
|
||||
{
|
||||
int ret;
|
||||
struct bladerf_metadata meta;
|
||||
int16_t *current;
|
||||
const float scaling = 1.0f / 2048.0f;
|
||||
gr_complex *out = static_cast<gr_complex *>(output_items[0]);
|
||||
|
||||
if (noutput_items > _conv_buf_size) {
|
||||
void *tmp;
|
||||
|
||||
_conv_buf_size = noutput_items;
|
||||
tmp = realloc(_conv_buf, _conv_buf_size * 2 * sizeof(int16_t));
|
||||
if (tmp == NULL) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) +
|
||||
"Failed to realloc _conv_buf" );
|
||||
if (bladerf_fpga_version(_dev.get(), &fpga_version) != 0) {
|
||||
BLADERF_WARNING("Failed to get FPGA version");
|
||||
} else if (fpga_version.major <= 0 &&
|
||||
fpga_version.minor <= 0 &&
|
||||
fpga_version.patch < 1) {
|
||||
BLADERF_WARNING("Warning: FPGA version v0.0.1 or later is required. "
|
||||
"Using an earlier FPGA version will result in "
|
||||
"misinterpeted samples.");
|
||||
}
|
||||
|
||||
_conv_buf = static_cast<int16_t*>(tmp);
|
||||
}
|
||||
|
||||
/* Grab all the samples into the temporary buffer */
|
||||
ret = bladerf_sync_rx(_dev.get(), static_cast<void *>(_conv_buf),
|
||||
noutput_items, &meta, _stream_timeout_ms);
|
||||
if ( ret != 0 ) {
|
||||
std::cerr << _pfx << "bladerf_sync_rx error: "
|
||||
<< bladerf_strerror(ret) << std::endl;
|
||||
return WORK_DONE;
|
||||
/* Initialize channel <-> antenna map */
|
||||
for (std::string ant : get_antennas()) {
|
||||
_chanmap[str2channel(ant)] = -1;
|
||||
}
|
||||
|
||||
current = _conv_buf;
|
||||
/* Bounds-checking output signature depending on our underlying hardware */
|
||||
if (get_num_channels() > get_max_channels()) {
|
||||
BLADERF_WARNING("Warning: number of channels specified on command line ("
|
||||
<< get_num_channels() << ") is greater than the maximum "
|
||||
"number supported by this device (" << get_max_channels()
|
||||
<< "). Resetting to " << get_max_channels() << ".");
|
||||
|
||||
/* Convert them from fixed to floating point */
|
||||
for (int i = 0; i < noutput_items; ++i) {
|
||||
float x, y;
|
||||
|
||||
x = scaling * *current;
|
||||
current++;
|
||||
|
||||
y = scaling * *current;
|
||||
current++;
|
||||
|
||||
out[i] = gr_complex(x, y) ;
|
||||
set_output_signature(gr::io_signature::make(get_max_channels(),
|
||||
get_max_channels(),
|
||||
sizeof(gr_complex)));
|
||||
}
|
||||
|
||||
return noutput_items;
|
||||
/* Set up constraints */
|
||||
int const alignment_multiple = volk_get_alignment() / sizeof(gr_complex);
|
||||
set_alignment(std::max(1,alignment_multiple));
|
||||
set_max_noutput_items(_samples_per_buffer);
|
||||
set_output_multiple(get_num_channels());
|
||||
|
||||
/* Set channel layout */
|
||||
_layout = (get_num_channels() > 1) ? BLADERF_RX_X2 : BLADERF_RX_X1;
|
||||
|
||||
/* Initial wiring of antennas to channels */
|
||||
for (size_t ch = 0; ch < get_num_channels(); ++ch) {
|
||||
set_channel_enable(BLADERF_CHANNEL_RX(ch), true);
|
||||
_chanmap[BLADERF_CHANNEL_RX(ch)] = ch;
|
||||
}
|
||||
|
||||
BLADERF_DEBUG("initialization complete");
|
||||
}
|
||||
|
||||
bool bladerf_source_c::is_antenna_valid(const std::string &antenna)
|
||||
{
|
||||
for (std::string ant : get_antennas()) {
|
||||
if (antenna == ant) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Public methods
|
||||
******************************************************************************/
|
||||
|
||||
std::string bladerf_source_c::name()
|
||||
{
|
||||
return "bladeRF receiver";
|
||||
}
|
||||
|
||||
std::vector<std::string> bladerf_source_c::get_devices()
|
||||
|
@ -190,319 +203,476 @@ std::vector<std::string> bladerf_source_c::get_devices()
|
|||
return bladerf_common::devices();
|
||||
}
|
||||
|
||||
size_t bladerf_source_c::get_max_channels()
|
||||
{
|
||||
return bladerf_common::get_max_channels(BLADERF_RX);
|
||||
}
|
||||
|
||||
size_t bladerf_source_c::get_num_channels()
|
||||
{
|
||||
/* We only support a single channel for each bladeRF */
|
||||
return 1;
|
||||
return output_signature()->max_streams();
|
||||
}
|
||||
|
||||
bool bladerf_source_c::start()
|
||||
{
|
||||
int status;
|
||||
|
||||
BLADERF_DEBUG("starting source");
|
||||
|
||||
gr::thread::scoped_lock guard(d_mutex);
|
||||
|
||||
status = bladerf_sync_config(_dev.get(), _layout, _format, _num_buffers,
|
||||
_samples_per_buffer, _num_transfers,
|
||||
_stream_timeout);
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "bladerf_sync_config failed");
|
||||
}
|
||||
|
||||
for (size_t ch = 0; ch < get_max_channels(); ++ch) {
|
||||
bladerf_channel brfch = BLADERF_CHANNEL_RX(ch);
|
||||
status = bladerf_enable_module(_dev.get(), brfch, get_channel_enable(brfch));
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate memory for conversions in work() */
|
||||
size_t alignment = volk_get_alignment();
|
||||
|
||||
_16icbuf = reinterpret_cast<int16_t *>(volk_malloc(2*_samples_per_buffer*sizeof(int16_t), alignment));
|
||||
_32fcbuf = reinterpret_cast<gr_complex *>(volk_malloc(_samples_per_buffer*sizeof(gr_complex), alignment));
|
||||
|
||||
_running = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bladerf_source_c::stop()
|
||||
{
|
||||
int status;
|
||||
|
||||
BLADERF_DEBUG("stopping source");
|
||||
|
||||
gr::thread::scoped_lock guard(d_mutex);
|
||||
|
||||
if (!_running) {
|
||||
BLADERF_WARNING("source already stopped, nothing to do here");
|
||||
return true;
|
||||
}
|
||||
|
||||
_running = false;
|
||||
|
||||
for (size_t ch = 0; ch < get_max_channels(); ++ch) {
|
||||
bladerf_channel brfch = BLADERF_CHANNEL_RX(ch);
|
||||
if (get_channel_enable(brfch)) {
|
||||
status = bladerf_enable_module(_dev.get(), brfch, false);
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Deallocate conversion memory */
|
||||
volk_free(_16icbuf);
|
||||
volk_free(_32fcbuf);
|
||||
_16icbuf = NULL;
|
||||
_32fcbuf = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int bladerf_source_c::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
int status;
|
||||
struct bladerf_metadata meta;
|
||||
struct bladerf_metadata *meta_ptr = NULL;
|
||||
size_t nstreams = num_streams(_layout);
|
||||
|
||||
gr::thread::scoped_lock guard(d_mutex);
|
||||
|
||||
// if we aren't running, nothing to do here
|
||||
if (!_running) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// set up metadata
|
||||
if (BLADERF_FORMAT_SC16_Q11_META == _format) {
|
||||
memset(&meta, 0, sizeof(meta));
|
||||
meta.flags = BLADERF_META_FLAG_RX_NOW;
|
||||
meta_ptr = &meta;
|
||||
}
|
||||
|
||||
// grab samples into temp buffer
|
||||
status = bladerf_sync_rx(_dev.get(), static_cast<void *>(_16icbuf),
|
||||
noutput_items, meta_ptr, _stream_timeout);
|
||||
if (status != 0) {
|
||||
BLADERF_WARNING(boost::str(boost::format("bladerf_sync_rx error: %s")
|
||||
% bladerf_strerror(status)));
|
||||
++_failures;
|
||||
|
||||
if (_failures >= MAX_CONSECUTIVE_FAILURES) {
|
||||
BLADERF_WARNING("Consecutive error limit hit. Shutting down.");
|
||||
return WORK_DONE;
|
||||
}
|
||||
} else {
|
||||
_failures = 0;
|
||||
}
|
||||
|
||||
// convert from int16_t to float
|
||||
// output_items is gr_complex (2x float), so num_points is 2*noutput_items
|
||||
volk_16i_s32f_convert_32f(reinterpret_cast<float *>(_32fcbuf), _16icbuf,
|
||||
SCALING_FACTOR, 2*noutput_items);
|
||||
|
||||
// copy the samples into output_items
|
||||
gr_complex **out = reinterpret_cast<gr_complex **>(&output_items[0]);
|
||||
|
||||
if (nstreams > 1) {
|
||||
// we need to deinterleave the multiplex as we copy
|
||||
gr_complex const *deint_in = _32fcbuf;
|
||||
|
||||
for (size_t i = 0; i < (noutput_items/nstreams); ++i) {
|
||||
for (size_t n = 0; n < nstreams; ++n) {
|
||||
memcpy(out[n]++, deint_in++, sizeof(gr_complex));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// no deinterleaving to do: simply copy everything
|
||||
memcpy(out[0], _32fcbuf, sizeof(gr_complex) * noutput_items);
|
||||
}
|
||||
|
||||
return noutput_items/(get_num_channels());
|
||||
}
|
||||
|
||||
osmosdr::meta_range_t bladerf_source_c::get_sample_rates()
|
||||
{
|
||||
return sample_rates();
|
||||
return sample_rates(chan2channel(BLADERF_RX, 0));
|
||||
}
|
||||
|
||||
double bladerf_source_c::set_sample_rate( double rate )
|
||||
double bladerf_source_c::set_sample_rate(double rate)
|
||||
{
|
||||
return bladerf_common::set_sample_rate( BLADERF_MODULE_RX, rate);
|
||||
return bladerf_common::set_sample_rate(rate, chan2channel(BLADERF_RX, 0));
|
||||
}
|
||||
|
||||
double bladerf_source_c::get_sample_rate()
|
||||
{
|
||||
return bladerf_common::get_sample_rate( BLADERF_MODULE_RX );
|
||||
return bladerf_common::get_sample_rate(chan2channel(BLADERF_RX, 0));
|
||||
}
|
||||
|
||||
osmosdr::freq_range_t bladerf_source_c::get_freq_range( size_t chan )
|
||||
osmosdr::freq_range_t bladerf_source_c::get_freq_range(size_t chan)
|
||||
{
|
||||
return freq_range();
|
||||
return bladerf_common::freq_range(chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
double bladerf_source_c::set_center_freq( double freq, size_t chan )
|
||||
double bladerf_source_c::set_center_freq(double freq, size_t chan)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check frequency range */
|
||||
if( freq < get_freq_range( chan ).start() ||
|
||||
freq > get_freq_range( chan ).stop() ) {
|
||||
std::cerr << "Failed to set out of bound frequency: " << freq << std::endl;
|
||||
} else {
|
||||
ret = bladerf_set_frequency( _dev.get(), BLADERF_MODULE_RX, (uint32_t)freq );
|
||||
if( ret ) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"failed to set center frequency " +
|
||||
boost::lexical_cast<std::string>(freq) + ": " +
|
||||
std::string(bladerf_strerror(ret)) );
|
||||
}
|
||||
}
|
||||
|
||||
return get_center_freq( chan );
|
||||
return bladerf_common::set_center_freq(freq, chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
double bladerf_source_c::get_center_freq( size_t chan )
|
||||
double bladerf_source_c::get_center_freq(size_t chan)
|
||||
{
|
||||
uint32_t freq;
|
||||
int ret;
|
||||
|
||||
ret = bladerf_get_frequency( _dev.get(), BLADERF_MODULE_RX, &freq );
|
||||
if( ret ) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"failed to get center frequency: " +
|
||||
std::string(bladerf_strerror(ret)) );
|
||||
}
|
||||
|
||||
return (double)freq;
|
||||
return bladerf_common::get_center_freq(chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
double bladerf_source_c::set_freq_corr( double ppm, size_t chan )
|
||||
double bladerf_source_c::set_freq_corr(double ppm, size_t chan)
|
||||
{
|
||||
/* TODO: Write the VCTCXO with a correction value (also changes TX ppm value!) */
|
||||
return get_freq_corr( chan );
|
||||
BLADERF_WARNING("Frequency correction is not implemented.");
|
||||
return get_freq_corr(chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
double bladerf_source_c::get_freq_corr( size_t chan )
|
||||
double bladerf_source_c::get_freq_corr(size_t chan)
|
||||
{
|
||||
/* TODO: Return back the frequency correction in ppm */
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<std::string> bladerf_source_c::get_gain_names( size_t chan )
|
||||
std::vector<std::string> bladerf_source_c::get_gain_names(size_t chan)
|
||||
{
|
||||
std::vector< std::string > names;
|
||||
|
||||
names += "LNA", "VGA1", "VGA2";
|
||||
|
||||
return names;
|
||||
return bladerf_common::get_gain_names(chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t bladerf_source_c::get_gain_range( size_t chan )
|
||||
osmosdr::gain_range_t bladerf_source_c::get_gain_range(size_t chan)
|
||||
{
|
||||
/* TODO: This is an overall system gain range. Given the LNA, VGA1 and VGA2
|
||||
how much total gain can we have in the system */
|
||||
return get_gain_range( "LNA", chan ); /* we use only LNA here for now */
|
||||
return bladerf_common::get_gain_range(chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t bladerf_source_c::get_gain_range( const std::string & name, size_t chan )
|
||||
osmosdr::gain_range_t bladerf_source_c::get_gain_range(const std::string &name,
|
||||
size_t chan)
|
||||
{
|
||||
osmosdr::gain_range_t range;
|
||||
return bladerf_common::get_gain_range(name, chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
if( name == "LNA" ) {
|
||||
range = _lna_range;
|
||||
} else if( name == "VGA1" ) {
|
||||
range = _vga1_range;
|
||||
} else if( name == "VGA2" ) {
|
||||
range = _vga2_range;
|
||||
} else {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"requested an invalid gain element " + name );
|
||||
bool bladerf_source_c::set_gain_mode(bool automatic, size_t chan)
|
||||
{
|
||||
return bladerf_common::set_gain_mode(automatic,
|
||||
chan2channel(BLADERF_RX, chan),
|
||||
_agcmode);
|
||||
}
|
||||
|
||||
bool bladerf_source_c::get_gain_mode(size_t chan)
|
||||
{
|
||||
return bladerf_common::get_gain_mode(chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
double bladerf_source_c::set_gain(double gain, size_t chan)
|
||||
{
|
||||
return bladerf_common::set_gain(gain, chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
double bladerf_source_c::set_gain(double gain, const std::string &name,
|
||||
size_t chan)
|
||||
{
|
||||
return bladerf_common::set_gain(gain, name, chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
double bladerf_source_c::get_gain(size_t chan)
|
||||
{
|
||||
return bladerf_common::get_gain(chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
double bladerf_source_c::get_gain(const std::string &name, size_t chan)
|
||||
{
|
||||
return bladerf_common::get_gain(name, chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
std::vector<std::string> bladerf_source_c::get_antennas(size_t chan)
|
||||
{
|
||||
return bladerf_common::get_antennas(BLADERF_RX);
|
||||
}
|
||||
|
||||
std::string bladerf_source_c::set_antenna(const std::string &antenna,
|
||||
size_t chan)
|
||||
{
|
||||
bool _was_running = _running;
|
||||
|
||||
if (_was_running) {
|
||||
stop();
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
bladerf_common::set_antenna(BLADERF_RX, chan, antenna);
|
||||
|
||||
bool bladerf_source_c::set_gain_mode( bool automatic, size_t chan )
|
||||
{
|
||||
/* TODO: Implement AGC in the FPGA */
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bladerf_source_c::get_gain_mode( size_t chan )
|
||||
{
|
||||
/* TODO: Read back AGC mode */
|
||||
return false;
|
||||
}
|
||||
|
||||
double bladerf_source_c::set_gain( double gain, size_t chan )
|
||||
{
|
||||
/* TODO: This is an overall system gain that has to be set */
|
||||
return set_gain( gain, "LNA", chan ); /* we use only LNA here for now */
|
||||
}
|
||||
|
||||
double bladerf_source_c::set_gain( double gain, const std::string & name, size_t chan )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if( name == "LNA" ) {
|
||||
bladerf_lna_gain g;
|
||||
|
||||
if ( gain >= 6.0f )
|
||||
g = BLADERF_LNA_GAIN_MAX;
|
||||
else if ( gain >= 3.0f )
|
||||
g = BLADERF_LNA_GAIN_MID;
|
||||
else /* gain < 3.0f */
|
||||
g = BLADERF_LNA_GAIN_BYPASS;
|
||||
|
||||
ret = bladerf_set_lna_gain( _dev.get(), g );
|
||||
} else if( name == "VGA1" ) {
|
||||
ret = bladerf_set_rxvga1( _dev.get(), (int)gain );
|
||||
} else if( name == "VGA2" ) {
|
||||
ret = bladerf_set_rxvga2( _dev.get(), (int)gain );
|
||||
} else {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"requested to set the gain "
|
||||
"of an unknown gain element " + name );
|
||||
if (_was_running) {
|
||||
start();
|
||||
}
|
||||
|
||||
/* Check for errors */
|
||||
if( ret ) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"could not set " + name + " gain: " +
|
||||
std::string(bladerf_strerror(ret)) );
|
||||
}
|
||||
|
||||
return get_gain( name, chan );
|
||||
return get_antenna(chan);
|
||||
}
|
||||
|
||||
double bladerf_source_c::get_gain( size_t chan )
|
||||
std::string bladerf_source_c::get_antenna(size_t chan)
|
||||
{
|
||||
/* TODO: This is an overall system gain that has to be set */
|
||||
return get_gain( "LNA", chan ); /* we use only LNA here for now */
|
||||
return channel2str(chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
double bladerf_source_c::get_gain( const std::string & name, size_t chan )
|
||||
void bladerf_source_c::set_dc_offset_mode(int mode, size_t chan)
|
||||
{
|
||||
int g;
|
||||
int ret = 0;
|
||||
|
||||
if( name == "LNA" ) {
|
||||
bladerf_lna_gain lna_g;
|
||||
ret = bladerf_get_lna_gain( _dev.get(), &lna_g );
|
||||
g = lna_g == BLADERF_LNA_GAIN_BYPASS ? 0 : lna_g == BLADERF_LNA_GAIN_MID ? 3 : 6;
|
||||
} else if( name == "VGA1" ) {
|
||||
ret = bladerf_get_rxvga1( _dev.get(), &g );
|
||||
} else if( name == "VGA2" ) {
|
||||
ret = bladerf_get_rxvga2( _dev.get(), &g );
|
||||
} else {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"requested to get the gain "
|
||||
"of an unknown gain element " + name );
|
||||
}
|
||||
|
||||
/* Check for errors */
|
||||
if( ret ) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"could not get " + name + " gain: " +
|
||||
std::string(bladerf_strerror(ret)) );
|
||||
}
|
||||
|
||||
return (double)g;
|
||||
}
|
||||
|
||||
double bladerf_source_c::set_bb_gain( double gain, size_t chan )
|
||||
{
|
||||
/* TODO: for RX, we should combine VGA1 & VGA2 which both are in BB path */
|
||||
osmosdr::gain_range_t bb_gains = get_gain_range( "VGA2", chan );
|
||||
|
||||
double clip_gain = bb_gains.clip( gain, true );
|
||||
gain = set_gain( clip_gain, "VGA2", chan );
|
||||
|
||||
return gain;
|
||||
}
|
||||
|
||||
std::vector< std::string > bladerf_source_c::get_antennas( size_t chan )
|
||||
{
|
||||
std::vector< std::string > antennas;
|
||||
|
||||
antennas += get_antenna( chan );
|
||||
|
||||
return antennas;
|
||||
}
|
||||
|
||||
std::string bladerf_source_c::set_antenna( const std::string & antenna, size_t chan )
|
||||
{
|
||||
return get_antenna( chan );
|
||||
}
|
||||
|
||||
std::string bladerf_source_c::get_antenna( size_t chan )
|
||||
{
|
||||
/* We only have a single receive antenna here */
|
||||
return "RX";
|
||||
}
|
||||
|
||||
void bladerf_source_c::set_dc_offset_mode( int mode, size_t chan )
|
||||
{
|
||||
if ( osmosdr::source::DCOffsetOff == mode ) {
|
||||
if (osmosdr::source::DCOffsetOff == mode) {
|
||||
//_src->set_auto_dc_offset( false, chan );
|
||||
set_dc_offset( std::complex<double>(0.0, 0.0), chan ); /* reset to default for off-state */
|
||||
} else if ( osmosdr::source::DCOffsetManual == mode ) {
|
||||
//_src->set_auto_dc_offset( false, chan ); /* disable auto mode, but keep correcting with last known values */
|
||||
} else if ( osmosdr::source::DCOffsetAutomatic == mode ) {
|
||||
/* reset to default for off-state */
|
||||
set_dc_offset(std::complex<double>(0.0, 0.0), chan);
|
||||
} else if (osmosdr::source::DCOffsetManual == mode) {
|
||||
/* disable auto mode, but keep correcting with last known values */
|
||||
//_src->set_auto_dc_offset( false, chan );
|
||||
} else if (osmosdr::source::DCOffsetAutomatic == mode) {
|
||||
//_src->set_auto_dc_offset( true, chan );
|
||||
std::cerr << "Automatic DC correction mode is not implemented." << std::endl;
|
||||
BLADERF_WARNING("Automatic DC correction mode is not implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
void bladerf_source_c::set_dc_offset( const std::complex<double> &offset, size_t chan )
|
||||
void bladerf_source_c::set_dc_offset(const std::complex<double> &offset,
|
||||
size_t chan)
|
||||
{
|
||||
int ret = 0;
|
||||
int status;
|
||||
|
||||
ret = bladerf_common::set_dc_offset(BLADERF_MODULE_RX, offset, chan);
|
||||
status = bladerf_common::set_dc_offset(offset, chan2channel(BLADERF_RX, chan));
|
||||
|
||||
if( ret ) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"could not set dc offset: " +
|
||||
std::string(bladerf_strerror(ret)) );
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "could not set dc offset");
|
||||
}
|
||||
}
|
||||
|
||||
void bladerf_source_c::set_iq_balance_mode( int mode, size_t chan )
|
||||
void bladerf_source_c::set_iq_balance_mode(int mode, size_t chan)
|
||||
{
|
||||
if ( osmosdr::source::IQBalanceOff == mode ) {
|
||||
if (osmosdr::source::IQBalanceOff == mode) {
|
||||
//_src->set_auto_iq_balance( false, chan );
|
||||
set_iq_balance( std::complex<double>(0.0, 0.0), chan ); /* reset to default for off-state */
|
||||
} else if ( osmosdr::source::IQBalanceManual == mode ) {
|
||||
//_src->set_auto_iq_balance( false, chan ); /* disable auto mode, but keep correcting with last known values */
|
||||
} else if ( osmosdr::source::IQBalanceAutomatic == mode ) {
|
||||
/* reset to default for off-state */
|
||||
set_iq_balance(std::complex<double>(0.0, 0.0), chan);
|
||||
} else if (osmosdr::source::IQBalanceManual == mode) {
|
||||
/* disable auto mode, but keep correcting with last known values */
|
||||
//_src->set_auto_iq_balance( false, chan );
|
||||
} else if (osmosdr::source::IQBalanceAutomatic == mode) {
|
||||
//_src->set_auto_iq_balance( true, chan );
|
||||
std::cerr << "Automatic IQ correction mode is not implemented." << std::endl;
|
||||
BLADERF_WARNING("Automatic IQ correction mode is not implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
void bladerf_source_c::set_iq_balance( const std::complex<double> &balance, size_t chan )
|
||||
void bladerf_source_c::set_iq_balance(const std::complex<double> &balance,
|
||||
size_t chan)
|
||||
{
|
||||
int ret = 0;
|
||||
int status;
|
||||
|
||||
ret = bladerf_common::set_iq_balance(BLADERF_MODULE_RX, balance, chan);
|
||||
status = bladerf_common::set_iq_balance(balance, chan2channel(BLADERF_RX, chan));
|
||||
|
||||
if( ret ) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"could not set iq balance: " +
|
||||
std::string(bladerf_strerror(ret)) );
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "could not set iq balance");
|
||||
}
|
||||
}
|
||||
|
||||
double bladerf_source_c::set_bandwidth( double bandwidth, size_t chan )
|
||||
osmosdr::freq_range_t bladerf_source_c::get_bandwidth_range(size_t chan)
|
||||
{
|
||||
int ret;
|
||||
uint32_t actual;
|
||||
return filter_bandwidths(chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
if ( bandwidth == 0.0 ) /* bandwidth of 0 means automatic filter selection */
|
||||
bandwidth = get_sample_rate() * 0.75; /* select narrower filters to prevent aliasing */
|
||||
double bladerf_source_c::set_bandwidth(double bandwidth, size_t chan)
|
||||
{
|
||||
return bladerf_common::set_bandwidth(bandwidth,
|
||||
chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
ret = bladerf_set_bandwidth( _dev.get(), BLADERF_MODULE_RX, (uint32_t)bandwidth, &actual );
|
||||
if( ret ) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"could not set bandwidth: " +
|
||||
std::string(bladerf_strerror(ret)) );
|
||||
double bladerf_source_c::get_bandwidth(size_t chan)
|
||||
{
|
||||
return bladerf_common::get_bandwidth(chan2channel(BLADERF_RX, chan));
|
||||
}
|
||||
|
||||
std::vector<std::string> bladerf_source_c::get_clock_sources(size_t mboard)
|
||||
{
|
||||
return bladerf_common::get_clock_sources(mboard);
|
||||
}
|
||||
|
||||
void bladerf_source_c::set_clock_source(const std::string &source,
|
||||
size_t mboard)
|
||||
{
|
||||
bladerf_common::set_clock_source(source, mboard);
|
||||
}
|
||||
|
||||
std::string bladerf_source_c::get_clock_source(size_t mboard)
|
||||
{
|
||||
return bladerf_common::get_clock_source(mboard);
|
||||
}
|
||||
|
||||
void bladerf_source_c::set_biastee_mode(const std::string &mode)
|
||||
{
|
||||
int status;
|
||||
bool enable;
|
||||
|
||||
if (mode == "on" || mode == "1" || mode == "rx") {
|
||||
enable = true;
|
||||
} else {
|
||||
enable = false;
|
||||
}
|
||||
|
||||
return get_bandwidth();
|
||||
status = bladerf_set_bias_tee(_dev.get(), BLADERF_CHANNEL_RX(0), enable);
|
||||
if (BLADERF_ERR_UNSUPPORTED == status) {
|
||||
// unsupported, but not worth crashing out
|
||||
BLADERF_WARNING("Bias-tee not supported by device");
|
||||
} else if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "Failed to set bias-tee");
|
||||
}
|
||||
}
|
||||
|
||||
double bladerf_source_c::get_bandwidth( size_t chan )
|
||||
void bladerf_source_c::set_loopback_mode(const std::string &loopback)
|
||||
{
|
||||
uint32_t bandwidth;
|
||||
int ret;
|
||||
int status;
|
||||
bladerf_loopback mode;
|
||||
|
||||
ret = bladerf_get_bandwidth( _dev.get(), BLADERF_MODULE_RX, &bandwidth );
|
||||
if( ret ) {
|
||||
throw std::runtime_error( std::string(__FUNCTION__) + " " +
|
||||
"could not get bandwidth:" +
|
||||
std::string(bladerf_strerror(ret)) );
|
||||
if (loopback == "bb_txlpf_rxvga2") {
|
||||
mode = BLADERF_LB_BB_TXLPF_RXVGA2;
|
||||
} else if (loopback == "bb_txlpf_rxlpf") {
|
||||
mode = BLADERF_LB_BB_TXLPF_RXLPF;
|
||||
} else if (loopback == "bb_txvga1_rxvga2") {
|
||||
mode = BLADERF_LB_BB_TXVGA1_RXVGA2;
|
||||
} else if (loopback == "bb_txvga1_rxlpf") {
|
||||
mode = BLADERF_LB_BB_TXVGA1_RXLPF;
|
||||
} else if (loopback == "rf_lna1") {
|
||||
mode = BLADERF_LB_RF_LNA1;
|
||||
} else if (loopback == "rf_lna2") {
|
||||
mode = BLADERF_LB_RF_LNA2;
|
||||
} else if (loopback == "rf_lna3") {
|
||||
mode = BLADERF_LB_RF_LNA3;
|
||||
} else if (loopback == "firmware") {
|
||||
mode = BLADERF_LB_FIRMWARE;
|
||||
} else if (loopback == "rfic_bist") {
|
||||
mode = BLADERF_LB_RFIC_BIST;
|
||||
} else if (loopback == "none") {
|
||||
mode = BLADERF_LB_NONE;
|
||||
} else {
|
||||
BLADERF_THROW("Unknown loopback mode: " + loopback);
|
||||
}
|
||||
|
||||
return (double)bandwidth;
|
||||
status = bladerf_set_loopback(_dev.get(), mode);
|
||||
if (BLADERF_ERR_UNSUPPORTED == status) {
|
||||
// unsupported, but not worth crashing out
|
||||
BLADERF_WARNING("Loopback mode not supported by device: " + loopback);
|
||||
} else if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "Failed to set loopback mode");
|
||||
}
|
||||
}
|
||||
|
||||
osmosdr::freq_range_t bladerf_source_c::get_bandwidth_range( size_t chan )
|
||||
void bladerf_source_c::set_rx_mux_mode(const std::string &rxmux)
|
||||
{
|
||||
return filter_bandwidths();
|
||||
int status;
|
||||
bladerf_rx_mux mode;
|
||||
|
||||
if (rxmux == "baseband") {
|
||||
mode = BLADERF_RX_MUX_BASEBAND;
|
||||
} else if (rxmux == "12bit") {
|
||||
mode = BLADERF_RX_MUX_12BIT_COUNTER;
|
||||
} else if (rxmux == "32bit") {
|
||||
mode = BLADERF_RX_MUX_32BIT_COUNTER;
|
||||
} else if (rxmux == "digital") {
|
||||
mode = BLADERF_RX_MUX_DIGITAL_LOOPBACK;
|
||||
} else {
|
||||
BLADERF_THROW("Unknown RX mux mode: " + rxmux);
|
||||
}
|
||||
|
||||
status = bladerf_set_rx_mux(_dev.get(), mode);
|
||||
if (BLADERF_ERR_UNSUPPORTED == status) {
|
||||
// unsupported, but not worth crashing out
|
||||
BLADERF_WARNING("RX mux mode not supported by device: " + rxmux);
|
||||
} else if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "Failed to set RX mux mode");
|
||||
}
|
||||
}
|
||||
|
||||
void bladerf_source_c::set_agc_mode(const std::string &agcmode)
|
||||
{
|
||||
#ifndef BLADERF_COMPATIBILITY
|
||||
int status;
|
||||
bladerf_gain_mode mode;
|
||||
bool ok = false;
|
||||
struct bladerf_gain_modes const *modes = NULL;
|
||||
|
||||
/* Get the list of AGC modes */
|
||||
status = bladerf_get_gain_modes(_dev.get(), BLADERF_CHANNEL_RX(0), &modes);
|
||||
if (status < 0) {
|
||||
BLADERF_THROW_STATUS(status, "failed to get gain modes");
|
||||
}
|
||||
|
||||
size_t count = status;
|
||||
|
||||
/* Compare... */
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
if (agcmode == std::string(modes[i].name)) {
|
||||
mode = modes[i].mode;
|
||||
ok = true;
|
||||
BLADERF_DEBUG("Setting gain mode to " << mode << " (" << agcmode << ")");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
BLADERF_WARNING("Unknown gain mode \"" << agcmode << "\"");
|
||||
return;
|
||||
}
|
||||
|
||||
_agcmode = mode;
|
||||
|
||||
for (size_t i = 0; i < get_num_channels(); ++i) {
|
||||
if (bladerf_common::get_gain_mode(BLADERF_CHANNEL_RX(i))) {
|
||||
/* Refresh this */
|
||||
bladerf_common::set_gain_mode(true, BLADERF_CHANNEL_RX(i), _agcmode);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2013 Nuand LLC
|
||||
* Copyright 2013-2017 Nuand LLC
|
||||
* Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
|
@ -21,18 +21,16 @@
|
|||
#ifndef INCLUDED_BLADERF_SOURCE_C_H
|
||||
#define INCLUDED_BLADERF_SOURCE_C_H
|
||||
|
||||
#include <gnuradio/thread/thread.h>
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
#include "osmosdr/ranges.h"
|
||||
#include "source_iface.h"
|
||||
#include "bladerf_common.h"
|
||||
|
||||
#include "osmosdr/ranges.h"
|
||||
|
||||
class bladerf_source_c;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr_blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
|
@ -40,9 +38,9 @@ class bladerf_source_c;
|
|||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<bladerf_source_c> bladerf_source_c_sptr;
|
||||
typedef std::shared_ptr<bladerf_source_c> bladerf_source_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of bladerf_source_c.
|
||||
|
@ -51,70 +49,96 @@ typedef boost::shared_ptr<bladerf_source_c> bladerf_source_c_sptr;
|
|||
* constructor is private. bladerf_make_source_c is the public
|
||||
* interface for creating new instances.
|
||||
*/
|
||||
bladerf_source_c_sptr make_bladerf_source_c (const std::string & args = "");
|
||||
bladerf_source_c_sptr make_bladerf_source_c(const std::string &args = "");
|
||||
|
||||
class bladerf_source_c :
|
||||
public gr::sync_block,
|
||||
public source_iface,
|
||||
protected bladerf_common
|
||||
public gr::sync_block,
|
||||
public source_iface,
|
||||
protected bladerf_common
|
||||
{
|
||||
private:
|
||||
// The friend declaration allows bladerf_make_source_c to
|
||||
// access the private constructor.
|
||||
friend bladerf_source_c_sptr make_bladerf_source_c (const std::string & args);
|
||||
friend bladerf_source_c_sptr make_bladerf_source_c(const std::string &args);
|
||||
|
||||
bladerf_source_c (const std::string & args); // private constructor
|
||||
bladerf_source_c(const std::string &args);
|
||||
|
||||
bool is_antenna_valid(const std::string &antenna);
|
||||
|
||||
public:
|
||||
std::string name();
|
||||
|
||||
static std::vector<std::string> get_devices();
|
||||
|
||||
size_t get_max_channels(void);
|
||||
size_t get_num_channels(void);
|
||||
|
||||
bool start();
|
||||
bool stop();
|
||||
|
||||
int work( int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items );
|
||||
int work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
|
||||
static std::vector< std::string > get_devices();
|
||||
osmosdr::meta_range_t get_sample_rates(void);
|
||||
double set_sample_rate(double rate);
|
||||
double get_sample_rate(void);
|
||||
|
||||
size_t get_num_channels( void );
|
||||
osmosdr::freq_range_t get_freq_range(size_t chan = 0);
|
||||
double set_center_freq(double freq, size_t chan = 0);
|
||||
double get_center_freq(size_t chan = 0);
|
||||
|
||||
osmosdr::meta_range_t get_sample_rates( void );
|
||||
double set_sample_rate( double rate );
|
||||
double get_sample_rate( void );
|
||||
double set_freq_corr(double ppm, size_t chan = 0);
|
||||
double get_freq_corr(size_t chan = 0);
|
||||
|
||||
osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
|
||||
double set_center_freq( double freq, size_t chan = 0 );
|
||||
double get_center_freq( size_t chan = 0 );
|
||||
double set_freq_corr( double ppm, size_t chan = 0 );
|
||||
double get_freq_corr( size_t chan = 0 );
|
||||
std::vector<std::string> get_gain_names(size_t chan = 0);
|
||||
osmosdr::gain_range_t get_gain_range(size_t chan = 0);
|
||||
osmosdr::gain_range_t get_gain_range(const std::string &name,
|
||||
size_t chan = 0);
|
||||
bool set_gain_mode(bool automatic, size_t chan = 0);
|
||||
bool get_gain_mode(size_t chan = 0);
|
||||
double set_gain(double gain, size_t chan = 0);
|
||||
double set_gain(double gain, const std::string &name, size_t chan = 0);
|
||||
double get_gain(size_t chan = 0);
|
||||
double get_gain(const std::string &name, size_t chan = 0);
|
||||
|
||||
std::vector<std::string> get_gain_names( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
|
||||
bool set_gain_mode( bool automatic, size_t chan = 0 );
|
||||
bool get_gain_mode( size_t chan = 0 );
|
||||
double set_gain( double gain, size_t chan = 0 );
|
||||
double set_gain( double gain, const std::string & name, size_t chan = 0 );
|
||||
double get_gain( size_t chan = 0 );
|
||||
double get_gain( const std::string & name, size_t chan = 0 );
|
||||
std::vector<std::string> get_antennas(size_t chan = 0);
|
||||
std::string set_antenna(const std::string &antenna, size_t chan = 0);
|
||||
std::string get_antenna(size_t chan = 0);
|
||||
|
||||
double set_bb_gain( double gain, size_t chan = 0 );
|
||||
void set_dc_offset_mode(int mode, size_t chan = 0);
|
||||
void set_dc_offset(const std::complex<double> &offset, size_t chan = 0);
|
||||
|
||||
std::vector< std::string > get_antennas( size_t chan = 0 );
|
||||
std::string set_antenna( const std::string & antenna, size_t chan = 0 );
|
||||
std::string get_antenna( size_t chan = 0 );
|
||||
void set_iq_balance_mode(int mode, size_t chan = 0);
|
||||
void set_iq_balance(const std::complex<double> &balance, size_t chan = 0);
|
||||
|
||||
void set_dc_offset_mode( int mode, size_t chan = 0 );
|
||||
void set_dc_offset( const std::complex<double> &offset, size_t chan = 0 );
|
||||
osmosdr::freq_range_t get_bandwidth_range(size_t chan = 0);
|
||||
double set_bandwidth(double bandwidth, size_t chan = 0);
|
||||
double get_bandwidth(size_t chan = 0);
|
||||
|
||||
void set_iq_balance_mode( int mode, size_t chan = 0 );
|
||||
void set_iq_balance( const std::complex<double> &balance, size_t chan = 0 );
|
||||
std::vector<std::string> get_clock_sources(size_t mboard);
|
||||
void set_clock_source(const std::string &source, size_t mboard = 0);
|
||||
std::string get_clock_source(size_t mboard);
|
||||
|
||||
double set_bandwidth( double bandwidth, size_t chan = 0 );
|
||||
double get_bandwidth( size_t chan = 0 );
|
||||
osmosdr::freq_range_t get_bandwidth_range( size_t chan = 0 );
|
||||
void set_biastee_mode(const std::string &mode);
|
||||
|
||||
void set_loopback_mode(const std::string &loopback);
|
||||
void set_rx_mux_mode(const std::string &rxmux);
|
||||
void set_agc_mode(const std::string &agcmode);
|
||||
|
||||
private:
|
||||
osmosdr::gain_range_t _lna_range;
|
||||
// Sample-handling buffers
|
||||
int16_t *_16icbuf; /**< raw samples from bladeRF */
|
||||
gr_complex *_32fcbuf; /**< intermediate buffer to gnuradio */
|
||||
|
||||
bool _running; /**< is the source running? */
|
||||
bladerf_channel_layout _layout; /**< channel layout */
|
||||
bladerf_gain_mode _agcmode; /**< gain mode when AGC is enabled */
|
||||
|
||||
gr::thread::mutex d_mutex; /**< mutex to protect set/work access */
|
||||
|
||||
/* Scaling factor used when converting from int16_t to float */
|
||||
const float SCALING_FACTOR = 2048.0f;
|
||||
};
|
||||
|
||||
#endif /* INCLUDED_BLADERF_SOURCE_C_H */
|
||||
#endif // INCLUDED_BLADERF_SOURCE_C_H
|
||||
|
|
|
@ -4,16 +4,26 @@
|
|||
#define GR_OSMOSDR_VERSION "@VERSION@"
|
||||
#define GR_OSMOSDR_LIBVER "@LIBVER@"
|
||||
|
||||
#cmakedefine ENABLE_OSMOSDR
|
||||
#cmakedefine ENABLE_FCD
|
||||
#cmakedefine ENABLE_FILE
|
||||
#cmakedefine ENABLE_RTL
|
||||
#cmakedefine ENABLE_RTL_TCP
|
||||
#cmakedefine ENABLE_UHD
|
||||
#cmakedefine ENABLE_MIRI
|
||||
#cmakedefine ENABLE_SDRPLAY
|
||||
#cmakedefine ENABLE_HACKRF
|
||||
#cmakedefine ENABLE_BLADERF
|
||||
#cmakedefine ENABLE_RFSPACE
|
||||
#cmakedefine ENABLE_AIRSPY
|
||||
#cmakedefine ENABLE_AIRSPYHF
|
||||
#cmakedefine ENABLE_SOAPY
|
||||
#cmakedefine ENABLE_REDPITAYA
|
||||
#cmakedefine ENABLE_FREESRP
|
||||
#cmakedefine ENABLE_XTRX
|
||||
|
||||
//provide NAN define for MSVC older than VC12
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1800)
|
||||
#include <limits>
|
||||
#define NAN std::numeric_limits<double>::quiet_NaN()
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_H_IN
|
||||
|
|
|
@ -20,20 +20,15 @@
|
|||
|
||||
#include <osmosdr/device.h>
|
||||
#include <stdexcept>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_OSMOSDR
|
||||
#include <osmosdr_src_c.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FCD
|
||||
#include <fcd_source_c.h>
|
||||
#endif
|
||||
|
@ -54,8 +49,8 @@
|
|||
#include <uhd_source_c.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MIRI
|
||||
#include <miri_source_c.h>
|
||||
#ifdef ENABLE_SDRPLAY
|
||||
#include <sdrplay_source_c.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_HACKRF
|
||||
|
@ -74,6 +69,22 @@
|
|||
#include <airspy_source_c.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_AIRSPYHF
|
||||
#include <airspyhf_source_c.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SOAPY
|
||||
#include <soapy_source_c.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_REDPITAYA
|
||||
#include <redpitaya_source_c.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FREESRP
|
||||
#include <freesrp_source_c.h>
|
||||
#endif
|
||||
|
||||
#include "arg_helpers.h"
|
||||
|
||||
using namespace osmosdr;
|
||||
|
@ -82,13 +93,13 @@ static const std::string args_delim = " ";
|
|||
static const std::string pairs_delim = ",";
|
||||
static const std::string pair_delim = "=";
|
||||
|
||||
static boost::mutex _device_mutex;
|
||||
static std::mutex _device_mutex;
|
||||
|
||||
device_t::device_t(const std::string &args)
|
||||
{
|
||||
dict_t dict = params_to_dict(args);
|
||||
|
||||
BOOST_FOREACH( dict_t::value_type &entry, dict )
|
||||
for (dict_t::value_type &entry : dict)
|
||||
(*this)[entry.first] = entry.second;
|
||||
}
|
||||
|
||||
|
@ -98,7 +109,7 @@ std::string device_t::to_pp_string(void) const
|
|||
|
||||
std::stringstream ss;
|
||||
ss << "Device Address:" << std::endl;
|
||||
BOOST_FOREACH(const device_t::value_type &entry, *this) {
|
||||
for (const device_t::value_type &entry : *this) {
|
||||
ss << boost::format(" %s: %s") % entry.first % entry.second << std::endl;
|
||||
}
|
||||
return ss.str();
|
||||
|
@ -108,7 +119,7 @@ std::string device_t::to_string(void) const
|
|||
{
|
||||
std::stringstream ss;
|
||||
size_t count = 0;
|
||||
BOOST_FOREACH(const device_t::value_type &entry, *this) {
|
||||
for (const device_t::value_type &entry : *this) {
|
||||
std::string value = entry.second;
|
||||
if (value.find(" ") != std::string::npos)
|
||||
value = "'" + value + "'";
|
||||
|
@ -121,7 +132,7 @@ std::string device_t::to_string(void) const
|
|||
|
||||
devices_t device::find(const device_t &hint)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(_device_mutex);
|
||||
std::lock_guard<std::mutex> lock(_device_mutex);
|
||||
|
||||
bool fake = true;
|
||||
|
||||
|
@ -130,52 +141,65 @@ devices_t device::find(const device_t &hint)
|
|||
|
||||
devices_t devices;
|
||||
|
||||
#ifdef ENABLE_OSMOSDR
|
||||
BOOST_FOREACH( std::string dev, osmosdr_src_c::get_devices() )
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_FCD
|
||||
BOOST_FOREACH( std::string dev, fcd_source_c::get_devices() )
|
||||
for (std::string dev : fcd_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_RTL
|
||||
BOOST_FOREACH( std::string dev, rtl_source_c::get_devices() )
|
||||
for (std::string dev : rtl_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_UHD
|
||||
BOOST_FOREACH( std::string dev, uhd_source_c::get_devices() )
|
||||
for (std::string dev : uhd_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_MIRI
|
||||
BOOST_FOREACH( std::string dev, miri_source_c::get_devices() )
|
||||
#ifdef ENABLE_SDRPLAY
|
||||
for (std::string dev : sdrplay_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_BLADERF
|
||||
BOOST_FOREACH( std::string dev, bladerf_source_c::get_devices() )
|
||||
for (std::string dev : bladerf_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_HACKRF
|
||||
BOOST_FOREACH( std::string dev, hackrf_source_c::get_devices() )
|
||||
for (std::string dev : hackrf_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_RFSPACE
|
||||
BOOST_FOREACH( std::string dev, rfspace_source_c::get_devices( fake ) )
|
||||
for (std::string dev : rfspace_source_c::get_devices( fake ))
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_AIRSPY
|
||||
BOOST_FOREACH( std::string dev, airspy_source_c::get_devices() )
|
||||
for (std::string dev : airspy_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_AIRSPYHF
|
||||
for (std::string dev : airspyhf_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_FREESRP
|
||||
for (std::string dev : freesrp_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_SOAPY
|
||||
for (std::string dev : soapy_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
|
||||
/* software-only sources should be appended at the very end,
|
||||
* hopefully resulting in hardware sources to be shown first
|
||||
* in a graphical interface etc... */
|
||||
|
||||
#ifdef ENABLE_RTL_TCP
|
||||
BOOST_FOREACH( std::string dev, rtl_tcp_source_c::get_devices( fake ) )
|
||||
for (std::string dev : rtl_tcp_source_c::get_devices( fake ))
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_REDPITAYA
|
||||
for (std::string dev : redpitaya_source_c::get_devices( fake ))
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_FILE
|
||||
BOOST_FOREACH( std::string dev, file_source_c::get_devices( fake ) )
|
||||
for (std::string dev : file_source_c::get_devices( fake ))
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
# Copyright 2012 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file is part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# gr-osmosdr 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio is distributed in the hope that it will be useful,
|
||||
# gr-osmosdr 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# along with gr-osmosdr; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
|
@ -21,29 +21,16 @@
|
|||
# This file included, use CMake directory variables
|
||||
########################################################################
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
if(ENABLE_FCD)
|
||||
include_directories(${GNURADIO_FCD_INCLUDE_DIRS})
|
||||
endif(ENABLE_FCD)
|
||||
|
||||
if(ENABLE_FCDPP)
|
||||
include_directories(${GNURADIO_FCDPP_INCLUDE_DIRS})
|
||||
endif(ENABLE_FCDPP)
|
||||
|
||||
set(fcd_srcs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/fcd_source_c.cc
|
||||
target_include_directories(gnuradio-osmosdr PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${GNURADIO_FUNCUBE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Append gnuradio-osmosdr library sources
|
||||
########################################################################
|
||||
list(APPEND gr_osmosdr_srcs ${fcd_srcs})
|
||||
APPEND_LIB_LIST(
|
||||
${GNURADIO_FUNCUBE_LIBRARIES}
|
||||
)
|
||||
|
||||
if(ENABLE_FCD)
|
||||
list(APPEND gr_osmosdr_libs ${GNURADIO_FCD_LIBRARIES})
|
||||
endif(ENABLE_FCD)
|
||||
|
||||
if(ENABLE_FCDPP)
|
||||
list(APPEND gr_osmosdr_libs ${GNURADIO_FCDPP_LIBRARIES})
|
||||
endif(ENABLE_FCDPP)
|
||||
list(APPEND gr_osmosdr_srcs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/fcd_source_c.cc
|
||||
)
|
||||
set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <sstream>
|
||||
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
|
@ -142,28 +141,24 @@ fcd_source_c::fcd_source_c(const std::string &args) :
|
|||
|
||||
std::cerr << "Using " << name() << " (" << dev_name << ")" << std::endl;
|
||||
|
||||
#ifdef HAVE_FCD
|
||||
if ( FUNCUBE_V1 == _type )
|
||||
{
|
||||
_src_v1 = gr::fcd::source_c::make( dev_name );
|
||||
_src_v1 = gr::funcube::fcd::make( dev_name );
|
||||
connect( _src_v1, 0, self(), 0 );
|
||||
|
||||
set_gain( 20, "LNA" );
|
||||
set_gain( 12, "MIX" );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCDPP
|
||||
if ( FUNCUBE_V2 == _type )
|
||||
{
|
||||
_src_v2 = gr::fcdproplus::fcdproplus::make( dev_name );
|
||||
_src_v2 = gr::funcube::fcdpp::make( dev_name );
|
||||
connect( _src_v2, 0, self(), 0 );
|
||||
|
||||
set_gain( 1, "LNA" );
|
||||
set_gain( 1, "MIX" );
|
||||
set_gain( 15, "BB" );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
fcd_source_c::~fcd_source_c()
|
||||
|
@ -175,7 +170,7 @@ std::vector< std::string > fcd_source_c::get_devices()
|
|||
int id = 0;
|
||||
std::vector< std::string > devices;
|
||||
|
||||
BOOST_FOREACH( device_t dev, _get_devices() )
|
||||
for (device_t dev : _get_devices())
|
||||
{
|
||||
std::string args = "fcd=" + boost::lexical_cast< std::string >( id++ );
|
||||
|
||||
|
@ -241,15 +236,11 @@ osmosdr::freq_range_t fcd_source_c::get_freq_range( size_t chan )
|
|||
|
||||
double fcd_source_c::set_center_freq( double freq, size_t chan )
|
||||
{
|
||||
#ifdef HAVE_FCD
|
||||
if ( FUNCUBE_V1 == _type )
|
||||
_src_v1->set_freq( float(freq) );
|
||||
#endif
|
||||
_src_v1->set_freq( freq );
|
||||
|
||||
#ifdef HAVE_FCDPP
|
||||
if ( FUNCUBE_V2 == _type )
|
||||
_src_v2->set_freq( float(freq) );
|
||||
#endif
|
||||
_src_v2->set_freq( freq );
|
||||
|
||||
_freq = freq;
|
||||
|
||||
|
@ -263,15 +254,11 @@ double fcd_source_c::get_center_freq( size_t chan )
|
|||
|
||||
double fcd_source_c::set_freq_corr( double ppm, size_t chan )
|
||||
{
|
||||
#ifdef HAVE_FCD
|
||||
if ( FUNCUBE_V1 == _type )
|
||||
_src_v1->set_freq_corr( ppm );
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCDPP
|
||||
if ( FUNCUBE_V2 == _type )
|
||||
_src_v2->set_freq_corr( ppm );
|
||||
#endif
|
||||
|
||||
_correct = ppm;
|
||||
|
||||
|
@ -343,7 +330,6 @@ double fcd_source_c::set_gain( double gain, size_t chan )
|
|||
|
||||
double fcd_source_c::set_gain( double gain, const std::string & name, size_t chan )
|
||||
{
|
||||
#ifdef HAVE_FCD
|
||||
if ( FUNCUBE_V1 == _type )
|
||||
{
|
||||
if ( "LNA" == name )
|
||||
|
@ -357,9 +343,7 @@ double fcd_source_c::set_gain( double gain, const std::string & name, size_t cha
|
|||
_src_v1->set_mixer_gain(_mix_gain);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCDPP
|
||||
if ( FUNCUBE_V2 == _type )
|
||||
{
|
||||
if ( "LNA" == name )
|
||||
|
@ -378,7 +362,6 @@ double fcd_source_c::set_gain( double gain, const std::string & name, size_t cha
|
|||
_src_v2->set_if_gain(_bb_gain);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return get_gain( name, chan );
|
||||
}
|
||||
|
|
|
@ -22,19 +22,14 @@
|
|||
|
||||
#include <gnuradio/hier_block2.h>
|
||||
|
||||
#ifdef HAVE_FCD
|
||||
#include <gnuradio/fcd/source_c.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCDPP
|
||||
#include <fcdproplus/fcdproplus.h>
|
||||
#endif
|
||||
#include <funcube/fcd.h>
|
||||
#include <funcube/fcdpp.h>
|
||||
|
||||
#include "source_iface.h"
|
||||
|
||||
class fcd_source_c;
|
||||
|
||||
typedef boost::shared_ptr< fcd_source_c > fcd_source_c_sptr;
|
||||
typedef std::shared_ptr< fcd_source_c > fcd_source_c_sptr;
|
||||
|
||||
fcd_source_c_sptr make_fcd_source_c( const std::string & args = "" );
|
||||
|
||||
|
@ -86,14 +81,10 @@ public:
|
|||
|
||||
private:
|
||||
dongle_type _type;
|
||||
#ifdef HAVE_FCD
|
||||
gr::fcd::source_c::sptr _src_v1;
|
||||
#endif
|
||||
#ifdef HAVE_FCDPP
|
||||
gr::fcdproplus::fcdproplus::sptr _src_v2;
|
||||
#endif
|
||||
gr::funcube::fcd::sptr _src_v1;
|
||||
gr::funcube::fcdpp::sptr _src_v2;
|
||||
double _lna_gain, _mix_gain, _bb_gain, _freq;
|
||||
int _correct;
|
||||
double _correct;
|
||||
};
|
||||
|
||||
#endif // FCD_SOURCE_C_H
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
# Copyright 2012 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file is part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# gr-osmosdr 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio is distributed in the hope that it will be useful,
|
||||
# gr-osmosdr 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# along with gr-osmosdr; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
|
@ -21,17 +21,17 @@
|
|||
# This file included, use CMake directory variables
|
||||
########################################################################
|
||||
|
||||
include_directories(
|
||||
target_include_directories(gnuradio-osmosdr PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
set(file_srcs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/file_source_c.cc
|
||||
APPEND_LIB_LIST(
|
||||
gnuradio::gnuradio-blocks
|
||||
)
|
||||
message(STATUS ${gnuradio-blocks_LIBRARIES})
|
||||
|
||||
########################################################################
|
||||
# Append gnuradio-osmosdr library sources
|
||||
########################################################################
|
||||
list(APPEND gr_osmosdr_srcs ${file_srcs})
|
||||
#list(APPEND gr_osmosdr_libs ${GNURADIO_BLOCKS_LIBRARIES})
|
||||
|
||||
list(APPEND gr_osmosdr_srcs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/file_source_c.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/file_sink_c.cc
|
||||
)
|
||||
set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
|
||||
|
|
|
@ -0,0 +1,226 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
*
|
||||
* GNU Radio 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
#include "file_sink_c.h"
|
||||
|
||||
#include "arg_helpers.h"
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
file_sink_c_sptr make_file_sink_c(const std::string &args)
|
||||
{
|
||||
return gnuradio::get_initial_sptr(new file_sink_c(args));
|
||||
}
|
||||
|
||||
file_sink_c::file_sink_c(const std::string &args) :
|
||||
gr::hier_block2("file_sink_c",
|
||||
gr::io_signature::make(1, 1, sizeof (gr_complex)),
|
||||
gr::io_signature::make(0, 0, 0))
|
||||
{
|
||||
std::string filename;
|
||||
bool append = false;
|
||||
bool throttle = false;
|
||||
_freq = 0;
|
||||
_rate = 0;
|
||||
|
||||
dict_t dict = params_to_dict(args);
|
||||
|
||||
if (dict.count("file"))
|
||||
filename = dict["file"];
|
||||
|
||||
if (dict.count("freq"))
|
||||
_freq = boost::lexical_cast< double >( dict["freq"] );
|
||||
|
||||
if (dict.count("rate"))
|
||||
_rate = boost::lexical_cast< double >( dict["rate"] );
|
||||
|
||||
if (dict.count("throttle"))
|
||||
throttle = ("true" == dict["throttle"] ? true : false);
|
||||
|
||||
if (dict.count("append"))
|
||||
append = ("true" == dict["append"] ? true : false);
|
||||
|
||||
if (!filename.length())
|
||||
throw std::runtime_error("No file name specified.");
|
||||
|
||||
if (_freq < 0)
|
||||
throw std::runtime_error("Parameter 'freq' may not be negative.");
|
||||
|
||||
if (0 == _rate && throttle)
|
||||
throw std::runtime_error("Parameter 'rate' is missing in arguments.");
|
||||
|
||||
_file_rate = _rate;
|
||||
|
||||
_sink = gr::blocks::file_sink::make( sizeof(gr_complex),
|
||||
filename.c_str(),
|
||||
append);
|
||||
|
||||
_throttle = gr::blocks::throttle::make( sizeof(gr_complex), _file_rate );
|
||||
|
||||
if (throttle) {
|
||||
connect( self(), 0, _throttle, 0 );
|
||||
connect( _throttle, 0, _sink, 0 );
|
||||
} else {
|
||||
connect( self(), 0, _sink, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
file_sink_c::~file_sink_c()
|
||||
{
|
||||
}
|
||||
|
||||
std::string file_sink_c::name()
|
||||
{
|
||||
return "IQ File sink";
|
||||
}
|
||||
|
||||
std::vector<std::string> file_sink_c::get_devices( bool fake )
|
||||
{
|
||||
std::vector<std::string> devices;
|
||||
|
||||
if ( fake )
|
||||
{
|
||||
std::string args = "file='/path/to/your/file'";
|
||||
args += ",rate=1e6,freq=100e6,throttle=true";
|
||||
args += ",label='Complex Sampled (IQ) File'";
|
||||
devices.push_back( args );
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
size_t file_sink_c::get_num_channels( void )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
osmosdr::meta_range_t file_sink_c::get_sample_rates( void )
|
||||
{
|
||||
osmosdr::meta_range_t range;
|
||||
|
||||
range += osmosdr::range_t( _file_rate , _file_rate); /* always return file's original rate */
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
double file_sink_c::set_sample_rate( double rate )
|
||||
{
|
||||
if ( _file_rate != rate )
|
||||
{
|
||||
std::cerr << boost::format("WARNING: Overriding original sample rate of %g with %g")
|
||||
% _file_rate % rate
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
_throttle->set_sample_rate( rate );
|
||||
|
||||
_rate = rate;
|
||||
|
||||
return get_sample_rate();
|
||||
}
|
||||
|
||||
double file_sink_c::get_sample_rate( void )
|
||||
{
|
||||
return _rate;
|
||||
}
|
||||
|
||||
osmosdr::freq_range_t file_sink_c::get_freq_range( size_t chan )
|
||||
{
|
||||
return osmosdr::freq_range_t(_freq, _freq);
|
||||
}
|
||||
|
||||
double file_sink_c::set_center_freq( double freq, size_t chan )
|
||||
{
|
||||
return get_center_freq(chan);
|
||||
}
|
||||
|
||||
double file_sink_c::get_center_freq( size_t chan )
|
||||
{
|
||||
return _freq;
|
||||
}
|
||||
|
||||
double file_sink_c::set_freq_corr( double ppm, size_t chan )
|
||||
{
|
||||
return get_freq_corr( chan );
|
||||
}
|
||||
|
||||
double file_sink_c::get_freq_corr( size_t chan )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<std::string> file_sink_c::get_gain_names( size_t chan )
|
||||
{
|
||||
return std::vector< std::string >();
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t file_sink_c::get_gain_range( size_t chan )
|
||||
{
|
||||
return osmosdr::gain_range_t();
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t file_sink_c::get_gain_range( const std::string & name, size_t chan )
|
||||
{
|
||||
return get_gain_range( chan );
|
||||
}
|
||||
|
||||
double file_sink_c::set_gain( double gain, size_t chan )
|
||||
{
|
||||
return get_gain(chan);
|
||||
}
|
||||
|
||||
double file_sink_c::set_gain( double gain, const std::string & name, size_t chan )
|
||||
{
|
||||
return set_gain(chan);
|
||||
}
|
||||
|
||||
double file_sink_c::get_gain( size_t chan )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
double file_sink_c::get_gain( const std::string & name, size_t chan )
|
||||
{
|
||||
return get_gain(chan);
|
||||
}
|
||||
|
||||
std::vector< std::string > file_sink_c::get_antennas( size_t chan )
|
||||
{
|
||||
return std::vector< std::string >();
|
||||
}
|
||||
|
||||
std::string file_sink_c::set_antenna( const std::string & antenna, size_t chan )
|
||||
{
|
||||
return get_antenna(chan);
|
||||
}
|
||||
|
||||
std::string file_sink_c::get_antenna( size_t chan )
|
||||
{
|
||||
return "";
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
*
|
||||
* GNU Radio 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef FILE_SINK_C_H
|
||||
#define FILE_SINK_C_H
|
||||
|
||||
#include <gnuradio/hier_block2.h>
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/blocks/throttle.h>
|
||||
|
||||
#include "sink_iface.h"
|
||||
|
||||
class file_sink_c;
|
||||
|
||||
typedef std::shared_ptr< file_sink_c > file_sink_c_sptr;
|
||||
|
||||
file_sink_c_sptr make_file_sink_c( const std::string & args = "" );
|
||||
|
||||
class file_sink_c :
|
||||
public gr::hier_block2,
|
||||
public sink_iface
|
||||
{
|
||||
private:
|
||||
friend file_sink_c_sptr make_file_sink_c(const std::string &args);
|
||||
|
||||
file_sink_c(const std::string &args);
|
||||
|
||||
public:
|
||||
~file_sink_c();
|
||||
|
||||
std::string name();
|
||||
|
||||
static std::vector< std::string > get_devices( bool fake = false );
|
||||
|
||||
size_t get_num_channels( void );
|
||||
|
||||
osmosdr::meta_range_t get_sample_rates( void );
|
||||
double set_sample_rate( double rate );
|
||||
double get_sample_rate( void );
|
||||
|
||||
osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
|
||||
double set_center_freq( double freq, size_t chan = 0 );
|
||||
double get_center_freq( size_t chan = 0 );
|
||||
double set_freq_corr( double ppm, size_t chan = 0 );
|
||||
double get_freq_corr( size_t chan = 0 );
|
||||
|
||||
std::vector<std::string> get_gain_names( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
|
||||
double set_gain( double gain, size_t chan = 0 );
|
||||
double set_gain( double gain, const std::string & name, size_t chan = 0 );
|
||||
double get_gain( size_t chan = 0 );
|
||||
double get_gain( const std::string & name, size_t chan = 0 );
|
||||
|
||||
std::vector< std::string > get_antennas( size_t chan = 0 );
|
||||
std::string set_antenna( const std::string & antenna, size_t chan = 0 );
|
||||
std::string get_antenna( size_t chan = 0 );
|
||||
|
||||
private:
|
||||
gr::blocks::file_sink::sptr _sink;
|
||||
gr::blocks::throttle::sptr _throttle;
|
||||
double _file_rate;
|
||||
double _freq, _rate;
|
||||
};
|
||||
|
||||
#endif // FILE_SINK_C_H
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
class file_source_c;
|
||||
|
||||
typedef boost::shared_ptr< file_source_c > file_source_c_sptr;
|
||||
typedef std::shared_ptr< file_source_c > file_source_c_sptr;
|
||||
|
||||
file_source_c_sptr make_file_source_c( const std::string & args = "" );
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
# Copyright 2012 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
# This file is part of gr-osmosdr
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# gr-osmosdr 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio is distributed in the hope that it will be useful,
|
||||
# gr-osmosdr 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 GNU Radio; see the file COPYING. If not, write to
|
||||
# along with gr-osmosdr; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
|
@ -21,17 +21,18 @@
|
|||
# This file included, use CMake directory variables
|
||||
########################################################################
|
||||
|
||||
include_directories(
|
||||
target_include_directories(gnuradio-osmosdr PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${LIBOSMOSDR_INCLUDE_DIRS}
|
||||
${LIBFREESRP_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(osmosdr_srcs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/osmosdr_src_c.cc
|
||||
APPEND_LIB_LIST(
|
||||
${LIBFREESRP_LIBRARIES}
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Append gnuradio-osmosdr library sources
|
||||
########################################################################
|
||||
list(APPEND gr_osmosdr_srcs ${osmosdr_srcs})
|
||||
list(APPEND gr_osmosdr_libs ${LIBOSMOSDR_LIBRARIES})
|
||||
list(APPEND gr_osmosdr_srcs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/freesrp_common.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/freesrp_source_c.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/freesrp_sink_c.cc
|
||||
)
|
||||
set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
|
|
@ -0,0 +1,198 @@
|
|||
#include "freesrp_common.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <boost/assign.hpp>
|
||||
|
||||
#include <arg_helpers.h>
|
||||
|
||||
using namespace FreeSRP;
|
||||
using namespace std;
|
||||
using namespace boost::assign;
|
||||
|
||||
std::shared_ptr<::FreeSRP::FreeSRP> freesrp_common::_srp;
|
||||
|
||||
freesrp_common::freesrp_common(const string &args)
|
||||
{
|
||||
dict_t dict = params_to_dict(args);
|
||||
|
||||
if(!_srp)
|
||||
{
|
||||
try
|
||||
{
|
||||
string serial = "";
|
||||
|
||||
if(dict.count("freesrp"))
|
||||
{
|
||||
serial = dict["freesrp"];
|
||||
}
|
||||
|
||||
if(dict.count("fx3"))
|
||||
{
|
||||
if(Util::find_fx3())
|
||||
{
|
||||
// Upload firmware to FX3
|
||||
string firmware_path = string(getenv("HOME")) + "/.freesrp/fx3.img";
|
||||
if(dict["fx3"].length() > 0)
|
||||
{
|
||||
firmware_path = dict["fx3"];
|
||||
}
|
||||
Util::find_fx3(true, firmware_path);
|
||||
cout << "FX3 programmed with '" << firmware_path << "'" << endl;
|
||||
// Give FX3 time to re-enumerate
|
||||
this_thread::sleep_for(chrono::milliseconds(600));
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "No FX3 in bootloader mode found" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
_srp.reset(new ::FreeSRP::FreeSRP(serial));
|
||||
|
||||
if(dict.count("fpga") || !_srp->fpga_loaded())
|
||||
{
|
||||
string bitstream_path = string(getenv("HOME")) + "/.freesrp/fpga.bin";
|
||||
if(dict["fpga"].length() > 0)
|
||||
{
|
||||
bitstream_path = dict["fpga"];
|
||||
}
|
||||
fpga_status stat = _srp->load_fpga(bitstream_path);
|
||||
switch(stat)
|
||||
{
|
||||
case FPGA_CONFIG_ERROR:
|
||||
throw runtime_error("Could not load FPGA configuration!");
|
||||
case FPGA_CONFIG_SKIPPED:
|
||||
cout << "FPGA already configured. Restart the FreeSRP to load a new bitstream." << endl;
|
||||
break;
|
||||
case FPGA_CONFIG_DONE:
|
||||
cout << "FPGA configured with '" << bitstream_path << "'" << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cout << "Connected to FreeSRP" << endl;
|
||||
|
||||
if(dict.count("loopback"))
|
||||
{
|
||||
response res = _srp->send_cmd({SET_LOOPBACK_EN, 1});
|
||||
if(res.error == CMD_OK)
|
||||
{
|
||||
cout << "AD9364 in loopback mode" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw runtime_error("Could not put AD9364 into loopback mode!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
response res = _srp->send_cmd({SET_LOOPBACK_EN, 0});
|
||||
if(res.error != CMD_OK)
|
||||
{
|
||||
throw runtime_error("Error disabling AD9364 loopback mode!");
|
||||
}
|
||||
}
|
||||
|
||||
if(dict.count("ignore_overflow"))
|
||||
{
|
||||
_ignore_overflow = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ignore_overflow = false;
|
||||
}
|
||||
}
|
||||
catch(const runtime_error& e)
|
||||
{
|
||||
cerr << "FreeSRP Error: " << e.what() << endl;
|
||||
throw runtime_error(e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vector<string> freesrp_common::get_devices()
|
||||
{
|
||||
vector<string> devices;
|
||||
|
||||
vector<string> serial_numbers = ::FreeSRP::FreeSRP::list_connected();
|
||||
|
||||
int index = 0;
|
||||
|
||||
for(string &serial : serial_numbers)
|
||||
{
|
||||
index++;
|
||||
|
||||
string str;
|
||||
str = "freesrp=" + serial + ",label='FreeSRP " + to_string(index) + "'";
|
||||
|
||||
devices.push_back(str);
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
size_t freesrp_common::get_num_channels( void )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
osmosdr::meta_range_t freesrp_common::get_sample_rates( void )
|
||||
{
|
||||
osmosdr::meta_range_t range;
|
||||
|
||||
// Any sample rate between 1e6 and 61.44e6 can be requested.
|
||||
// This list of some integer values is used instead of
|
||||
// range += osmosdr::range_t(1e6, 61.44e6);
|
||||
// because SoapyOsmo seems to handle the range object differently.
|
||||
range += osmosdr::range_t(1e6);
|
||||
range += osmosdr::range_t(8e6);
|
||||
range += osmosdr::range_t(16e6);
|
||||
range += osmosdr::range_t(20e6);
|
||||
range += osmosdr::range_t(40e6);
|
||||
range += osmosdr::range_t(50e6);
|
||||
range += osmosdr::range_t(61.44e6);
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
osmosdr::freq_range_t freesrp_common::get_freq_range(size_t chan)
|
||||
{
|
||||
osmosdr::meta_range_t freq_ranges;
|
||||
|
||||
freq_ranges.push_back(osmosdr::range_t(7e7, 6e9, 2.4));
|
||||
|
||||
return freq_ranges;
|
||||
}
|
||||
|
||||
|
||||
osmosdr::freq_range_t freesrp_common::get_bandwidth_range(size_t chan)
|
||||
{
|
||||
osmosdr::meta_range_t range;
|
||||
|
||||
//range += osmosdr::range_t(2e5, 56e6);
|
||||
|
||||
range += osmosdr::range_t(2e5);
|
||||
range += osmosdr::range_t(1e6);
|
||||
range += osmosdr::range_t(8e6);
|
||||
range += osmosdr::range_t(16e6);
|
||||
range += osmosdr::range_t(20e6);
|
||||
range += osmosdr::range_t(40e6);
|
||||
range += osmosdr::range_t(50e6);
|
||||
range += osmosdr::range_t(56e6);
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
|
||||
double freesrp_common::set_freq_corr( double ppm, size_t chan )
|
||||
{
|
||||
// TODO: Set DCXO tuning
|
||||
return 0;
|
||||
}
|
||||
|
||||
double freesrp_common::get_freq_corr( size_t chan )
|
||||
{
|
||||
// TODO: Get DCXO tuning
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef INCLUDED_FREESRP_COMMON_H
|
||||
#define INCLUDED_FREESRP_COMMON_H
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "osmosdr/ranges.h"
|
||||
|
||||
#include <freesrp.hpp>
|
||||
|
||||
class freesrp_common
|
||||
{
|
||||
protected:
|
||||
freesrp_common(const std::string &args);
|
||||
public:
|
||||
static std::vector<std::string> get_devices();
|
||||
|
||||
size_t get_num_channels( void );
|
||||
osmosdr::meta_range_t get_sample_rates( void );
|
||||
osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
|
||||
osmosdr::freq_range_t get_bandwidth_range( size_t chan = 0 );
|
||||
double set_freq_corr( double ppm, size_t chan = 0 );
|
||||
double get_freq_corr( size_t chan = 0 );
|
||||
protected:
|
||||
static std::shared_ptr<::FreeSRP::FreeSRP> _srp;
|
||||
bool _ignore_overflow = false;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,280 @@
|
|||
#include "freesrp_sink_c.h"
|
||||
|
||||
using namespace FreeSRP;
|
||||
using namespace std;
|
||||
|
||||
freesrp_sink_c_sptr make_freesrp_sink_c (const string &args)
|
||||
{
|
||||
return gnuradio::get_initial_sptr(new freesrp_sink_c (args));
|
||||
}
|
||||
|
||||
/*
|
||||
* Specify constraints on number of input and output streams.
|
||||
* This info is used to construct the input and output signatures
|
||||
* (2nd & 3rd args to gr_block's constructor). The input and
|
||||
* output signatures are used by the runtime system to
|
||||
* check that a valid number and type of inputs and outputs
|
||||
* are connected to this block. In this case, we accept
|
||||
* only 1 input and 0 output.
|
||||
*/
|
||||
static const int MIN_IN = 1; // mininum number of input streams
|
||||
static const int MAX_IN = 1; // maximum number of input streams
|
||||
static const int MIN_OUT = 0; // minimum number of output streams
|
||||
static const int MAX_OUT = 0; // maximum number of output streams
|
||||
|
||||
freesrp_sink_c::freesrp_sink_c (const string & args) : gr::sync_block("freesrp_sink_c",
|
||||
gr::io_signature::make (MIN_IN, MAX_IN, sizeof (gr_complex)),
|
||||
gr::io_signature::make (MIN_OUT, MAX_OUT, sizeof (gr_complex))),
|
||||
freesrp_common(args)
|
||||
{
|
||||
if(_srp == nullptr)
|
||||
{
|
||||
throw runtime_error("FreeSRP not initialized!");
|
||||
}
|
||||
}
|
||||
|
||||
bool freesrp_sink_c::start()
|
||||
{
|
||||
response res = _srp->send_cmd({SET_DATAPATH_EN, 1});
|
||||
if(res.error != CMD_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_srp->start_tx(std::bind(&freesrp_sink_c::freesrp_tx_callback, this, std::placeholders::_1));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool freesrp_sink_c::stop()
|
||||
{
|
||||
_srp->send_cmd({SET_DATAPATH_EN, 0});
|
||||
_srp->stop_tx();
|
||||
return true;
|
||||
}
|
||||
|
||||
void freesrp_sink_c::freesrp_tx_callback(vector<sample>& samples)
|
||||
{
|
||||
unique_lock<std::mutex> lk(_buf_mut);
|
||||
|
||||
for(sample &s : samples)
|
||||
{
|
||||
if(!_buf_queue.try_dequeue(s))
|
||||
{
|
||||
s.i = 0;
|
||||
s.q = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_buf_available_space++;
|
||||
}
|
||||
}
|
||||
|
||||
_buf_cond.notify_one();
|
||||
}
|
||||
|
||||
int freesrp_sink_c::work(int noutput_items, gr_vector_const_void_star& input_items, gr_vector_void_star& output_items)
|
||||
{
|
||||
const gr_complex *in = (const gr_complex *) input_items[0];
|
||||
|
||||
unique_lock<std::mutex> lk(_buf_mut);
|
||||
|
||||
// Wait until enough space is available
|
||||
while(_buf_available_space < (unsigned int) noutput_items)
|
||||
{
|
||||
_buf_cond.wait(lk);
|
||||
}
|
||||
|
||||
for(int i = 0; i < noutput_items; ++i)
|
||||
{
|
||||
sample s;
|
||||
s.i = (int16_t) (real(in[i]) * 2047.0f);
|
||||
s.q = (int16_t) (imag(in[i]) * 2047.0f);
|
||||
|
||||
if(!_buf_queue.try_enqueue(s))
|
||||
{
|
||||
throw runtime_error("Failed to add sample to buffer. This should never happen. Available space reported to be " + to_string(_buf_available_space) + " samples, noutput_items=" + to_string(noutput_items) + ", i=" + to_string(i));
|
||||
}
|
||||
else
|
||||
{
|
||||
_buf_available_space--;
|
||||
}
|
||||
}
|
||||
|
||||
return noutput_items;
|
||||
}
|
||||
|
||||
double freesrp_sink_c::set_sample_rate( double rate )
|
||||
{
|
||||
command cmd = _srp->make_command(SET_TX_SAMP_FREQ, rate);
|
||||
response r = _srp->send_cmd(cmd);
|
||||
if(r.error != CMD_OK)
|
||||
{
|
||||
cerr << "Could not set TX sample rate, error: " << r.error << endl;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<double>(r.param);
|
||||
}
|
||||
}
|
||||
|
||||
double freesrp_sink_c::get_sample_rate( void )
|
||||
{
|
||||
response r = _srp->send_cmd({GET_TX_SAMP_FREQ, 0});
|
||||
if(r.error != CMD_OK)
|
||||
{
|
||||
cerr << "Could not get TX sample rate, error: " << r.error << endl;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return r.param;
|
||||
}
|
||||
}
|
||||
|
||||
double freesrp_sink_c::set_center_freq( double freq, size_t chan )
|
||||
{
|
||||
command cmd = _srp->make_command(SET_TX_LO_FREQ, freq);
|
||||
response r = _srp->send_cmd(cmd);
|
||||
if(r.error != CMD_OK)
|
||||
{
|
||||
cerr << "Could not set TX LO frequency, error: " << r.error << endl;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<double>(r.param);
|
||||
}
|
||||
}
|
||||
|
||||
double freesrp_sink_c::get_center_freq( size_t chan )
|
||||
{
|
||||
response r = _srp->send_cmd({GET_TX_LO_FREQ, 0});
|
||||
if(r.error != CMD_OK)
|
||||
{
|
||||
cerr << "Could not get TX LO frequency, error: " << r.error << endl;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<double>(r.param);
|
||||
}
|
||||
}
|
||||
|
||||
vector<string> freesrp_sink_c::get_gain_names( size_t chan )
|
||||
{
|
||||
vector<string> names;
|
||||
|
||||
names.push_back("TX_RF");
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t freesrp_sink_c::get_gain_range(size_t chan)
|
||||
{
|
||||
osmosdr::meta_range_t gain_ranges;
|
||||
|
||||
gain_ranges.push_back(osmosdr::range_t(0, 89.75, 0.25));
|
||||
|
||||
return gain_ranges;
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t freesrp_sink_c::get_gain_range(const string& name, size_t chan)
|
||||
{
|
||||
return get_gain_range(chan);
|
||||
}
|
||||
|
||||
double freesrp_sink_c::set_gain(double gain, size_t chan)
|
||||
{
|
||||
gain = get_gain_range().clip(gain);
|
||||
|
||||
double atten = 89.75 - gain;
|
||||
|
||||
command cmd = _srp->make_command(SET_TX_ATTENUATION, atten * 1000);
|
||||
response r = _srp->send_cmd(cmd);
|
||||
if(r.error != CMD_OK)
|
||||
{
|
||||
cerr << "Could not set TX attenuation, error: " << r.error << endl;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 89.75 - (((double) r.param) / 1000.0);
|
||||
}
|
||||
}
|
||||
|
||||
double freesrp_sink_c::set_gain(double gain, const string& name, size_t chan)
|
||||
{
|
||||
return set_gain(gain, chan);
|
||||
}
|
||||
|
||||
double freesrp_sink_c::get_gain(size_t chan)
|
||||
{
|
||||
response r = _srp->send_cmd({GET_TX_ATTENUATION, 0});
|
||||
if(r.error != CMD_OK)
|
||||
{
|
||||
cerr << "Could not get TX RF attenuation, error: " << r.error << endl;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 89.75 - (((double) r.param) / 1000.0);
|
||||
}
|
||||
}
|
||||
|
||||
double freesrp_sink_c::get_gain(const string& name, size_t chan)
|
||||
{
|
||||
return get_gain(chan);
|
||||
}
|
||||
|
||||
double freesrp_sink_c::set_bb_gain(double gain, size_t chan)
|
||||
{
|
||||
return set_gain(gain, chan);
|
||||
}
|
||||
|
||||
vector<string> freesrp_sink_c::get_antennas(size_t chan)
|
||||
{
|
||||
vector<string> antennas;
|
||||
|
||||
antennas.push_back(get_antenna(chan));
|
||||
|
||||
return antennas;
|
||||
}
|
||||
|
||||
string freesrp_sink_c::set_antenna(const string& antenna, size_t chan)
|
||||
{
|
||||
return get_antenna(chan);
|
||||
}
|
||||
|
||||
string freesrp_sink_c::get_antenna(size_t chan)
|
||||
{
|
||||
return "TX";
|
||||
}
|
||||
|
||||
double freesrp_sink_c::set_bandwidth(double bandwidth, size_t chan)
|
||||
{
|
||||
command cmd = _srp->make_command(SET_TX_RF_BANDWIDTH, bandwidth);
|
||||
response r = _srp->send_cmd(cmd);
|
||||
if(r.error != CMD_OK)
|
||||
{
|
||||
cerr << "Could not set TX RF bandwidth, error: " << r.error << endl;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<double>(r.param);
|
||||
}
|
||||
}
|
||||
|
||||
double freesrp_sink_c::get_bandwidth(size_t chan)
|
||||
{
|
||||
response r = _srp->send_cmd({GET_TX_RF_BANDWIDTH, 0});
|
||||
if(r.error != CMD_OK)
|
||||
{
|
||||
cerr << "Could not get TX RF bandwidth, error: " << r.error << endl;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return r.param;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2015 Lukas Lao Beyer
|
||||
* Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
*
|
||||
* GNU Radio 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef INCLUDED_FREESRP_SINK_C_H
|
||||
#define INCLUDED_FREESRP_SINK_C_H
|
||||
|
||||
#include <gnuradio/thread/thread.h>
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
#include "osmosdr/ranges.h"
|
||||
#include "sink_iface.h"
|
||||
|
||||
#include "freesrp_common.h"
|
||||
#include "readerwriterqueue/readerwriterqueue.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include <freesrp.hpp>
|
||||
|
||||
class freesrp_sink_c;
|
||||
|
||||
/*
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr_blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
* C++ / Python system.
|
||||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef std::shared_ptr<freesrp_sink_c> freesrp_sink_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of freesrp_sink_c.
|
||||
*
|
||||
* To avoid accidental use of raw pointers, freesrp_sink_c's
|
||||
* constructor is private. make_freesrp_sink_c is the public
|
||||
* interface for creating new instances.
|
||||
*/
|
||||
freesrp_sink_c_sptr make_freesrp_sink_c (const std::string & args = "");
|
||||
|
||||
class freesrp_sink_c :
|
||||
public gr::sync_block,
|
||||
public sink_iface,
|
||||
public freesrp_common
|
||||
{
|
||||
private:
|
||||
// The friend declaration allows freesrp_make_sink_c to
|
||||
// access the private constructor.
|
||||
friend freesrp_sink_c_sptr make_freesrp_sink_c (const std::string & args);
|
||||
|
||||
freesrp_sink_c (const std::string & args); // private constructor
|
||||
|
||||
public:
|
||||
|
||||
// From freesrp_common:
|
||||
static std::vector<std::string> get_devices() { return freesrp_common::get_devices(); };
|
||||
size_t get_num_channels( void ) { return freesrp_common::get_num_channels(); }
|
||||
osmosdr::meta_range_t get_sample_rates( void ) { return freesrp_common::get_sample_rates(); }
|
||||
osmosdr::freq_range_t get_freq_range( size_t chan = 0 ) { return freesrp_common::get_freq_range(chan); }
|
||||
osmosdr::freq_range_t get_bandwidth_range( size_t chan = 0 ) { return freesrp_common::get_bandwidth_range(chan); }
|
||||
double set_freq_corr( double ppm, size_t chan = 0 ) { return freesrp_common::set_freq_corr(ppm, chan); }
|
||||
double get_freq_corr( size_t chan = 0 ) { return freesrp_common::get_freq_corr(chan); }
|
||||
|
||||
bool start();
|
||||
bool stop();
|
||||
|
||||
int work( int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items );
|
||||
|
||||
double set_sample_rate( double rate );
|
||||
double get_sample_rate( void );
|
||||
|
||||
double set_center_freq( double freq, size_t chan = 0 );
|
||||
double get_center_freq( size_t chan = 0 );
|
||||
|
||||
std::vector<std::string> get_gain_names( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
|
||||
//TODO: implement this: bool set_gain_mode( bool automatic, size_t chan = 0 );
|
||||
//TODO: implement this: bool get_gain_mode( size_t chan = 0 );
|
||||
double set_gain( double gain, size_t chan = 0 );
|
||||
double set_gain( double gain, const std::string & name, size_t chan = 0 );
|
||||
double get_gain( size_t chan = 0 );
|
||||
double get_gain( const std::string & name, size_t chan = 0 );
|
||||
|
||||
double set_bb_gain( double gain, size_t chan = 0 );
|
||||
|
||||
std::vector< std::string > get_antennas( size_t chan = 0 );
|
||||
std::string set_antenna( const std::string & antenna, size_t chan = 0 );
|
||||
std::string get_antenna( size_t chan = 0 );
|
||||
|
||||
double set_bandwidth( double bandwidth, size_t chan = 0 );
|
||||
double get_bandwidth( size_t chan = 0 );
|
||||
|
||||
private:
|
||||
|
||||
void freesrp_tx_callback(std::vector<::FreeSRP::sample> &samples);
|
||||
|
||||
bool _running = false;
|
||||
|
||||
std::mutex _buf_mut{};
|
||||
std::condition_variable _buf_cond{};
|
||||
size_t _buf_available_space = FREESRP_RX_TX_QUEUE_SIZE;
|
||||
moodycamel::ReaderWriterQueue<::FreeSRP::sample> _buf_queue{FREESRP_RX_TX_QUEUE_SIZE};
|
||||
};
|
||||
|
||||
#endif /* INCLUDED_FREESRP_SINK_C_H */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue