├── .clang-format ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── MANIFEST.md ├── README.md ├── apps └── CMakeLists.txt ├── cmake ├── Modules │ ├── CMakeParseArgumentsCopy.cmake │ ├── FindCppUnit.cmake │ ├── FindGnuradioRuntime.cmake │ ├── GrMiscUtils.cmake │ ├── GrPlatform.cmake │ ├── GrPython.cmake │ ├── GrSwig.cmake │ ├── GrTest.cmake │ ├── UseSWIG.cmake │ └── limesdrConfig.cmake └── cmake_uninstall.cmake.in ├── debian ├── changelog ├── compat ├── control ├── copyright ├── rules ├── source │ └── format └── triggers ├── docs ├── CMakeLists.txt ├── README.limesdr ├── doxygen │ ├── CMakeLists.txt │ ├── Doxyfile.in │ ├── Doxyfile.swig_doc.in │ ├── doxyxml │ │ ├── __init__.py │ │ ├── __init__.pyc │ │ ├── base.py │ │ ├── base.pyc │ │ ├── doxyindex.py │ │ ├── doxyindex.pyc │ │ ├── generated │ │ │ ├── __init__.py │ │ │ ├── __init__.pyc │ │ │ ├── compound.py │ │ │ ├── compound.pyc │ │ │ ├── compoundsuper.py │ │ │ ├── compoundsuper.pyc │ │ │ ├── index.py │ │ │ ├── index.pyc │ │ │ ├── indexsuper.py │ │ │ └── indexsuper.pyc │ │ ├── text.py │ │ └── text.pyc │ ├── other │ │ ├── group_defs.dox │ │ └── main_page.dox │ ├── swig_doc.py │ └── swig_doc.pyc └── known_issues.txt ├── examples ├── DVB_T_2k_64QAM_TX.grc ├── FM_RDS.grc ├── FM_receiver.grc ├── FM_transmitter.grc ├── GFSK.grc ├── guitar.wav ├── piano.wav ├── signal_analyzer.grc ├── signal_analyzer_with_rfe.grc └── signal_generator.grc ├── grc ├── CMakeLists.txt ├── limesdr_rfe.xml ├── limesdr_sink.xml └── limesdr_source.xml ├── include └── limesdr │ ├── CMakeLists.txt │ ├── api.h │ ├── rfe.h │ ├── sink.h │ └── source.h ├── lib ├── CMakeLists.txt ├── common │ ├── device_handler.cc │ └── device_handler.h ├── rfe_impl.cc ├── sink_impl.cc ├── sink_impl.h ├── source_impl.cc └── source_impl.h ├── python ├── CMakeLists.txt ├── __init__.py ├── __init__.pyc ├── build_utils.py ├── build_utils.pyc ├── build_utils_codes.py └── build_utils_codes.pyc └── swig ├── CMakeLists.txt └── limesdr_swig.i /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: LLVM 3 | IndentWidth: 4 4 | --- 5 | Language: Cpp 6 | BasedOnStyle: LLVM 7 | IndentWidth: 4 8 | AccessModifierOffset: 0 9 | AlignAfterOpenBracket: Align 10 | #AlignEscapedNewlines: Left 11 | AlignTrailingComments: true 12 | AlwaysBreakTemplateDeclarations: true 13 | BinPackArguments: false 14 | BinPackParameters: false 15 | ColumnLimit: 100 16 | #FixNamespaceComments: true 17 | MaxEmptyLinesToKeep: 2 18 | #CompactNamespaces: true 19 | NamespaceIndentation: None 20 | PointerAlignment: Left 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/** 2 | .vscode/** 3 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ######################################################################## 21 | # Project setup 22 | ######################################################################## 23 | cmake_minimum_required(VERSION 2.6) 24 | project(gr-limesdr CXX C) 25 | 26 | set(CMAKE_CXX_STANDARD 11) 27 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 28 | set(CMAKE_CXX_EXTENSIONS OFF) 29 | 30 | enable_testing() 31 | 32 | #select the release build type by default to get optimization flags 33 | if(NOT CMAKE_BUILD_TYPE) 34 | set(CMAKE_BUILD_TYPE "Release") 35 | message(STATUS "Build type not specified: defaulting to release.") 36 | endif(NOT CMAKE_BUILD_TYPE) 37 | set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") 38 | 39 | #make sure our local CMake Modules path comes first 40 | list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules) 41 | 42 | ######################################################################## 43 | # Compiler specific setup 44 | ######################################################################## 45 | if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) 46 | #http://gcc.gnu.org/wiki/Visibility 47 | add_definitions(-fvisibility=hidden) 48 | endif() 49 | 50 | ######################################################################## 51 | # Find boost 52 | ######################################################################## 53 | MESSAGE(STATUS "Configuring Boost C++ Libraries...") 54 | 55 | SET(BOOST_REQUIRED_COMPONENTS 56 | thread 57 | system 58 | ) 59 | 60 | if(UNIX AND EXISTS "/usr/lib64") 61 | list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix 62 | endif(UNIX AND EXISTS "/usr/lib64") 63 | 64 | set(Boost_ADDITIONAL_VERSIONS 65 | "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" 66 | "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" 67 | "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" 68 | "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" 69 | "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" 70 | "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" 71 | "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" 72 | ) 73 | 74 | find_package(Boost COMPONENTS ${BOOST_REQUIRED_COMPONENTS}) 75 | 76 | if(NOT Boost_FOUND) 77 | message(FATAL_ERROR "Boost required to compile limesdr") 78 | endif() 79 | 80 | ######################################################################## 81 | # Install directories 82 | ######################################################################## 83 | include(GrPlatform) #define LIB_SUFFIX 84 | set(GR_RUNTIME_DIR bin) 85 | set(GR_LIBRARY_DIR lib${LIB_SUFFIX}) 86 | set(GR_INCLUDE_DIR include/limesdr) 87 | set(GR_DATA_DIR share) 88 | set(GR_PKG_DATA_DIR ${GR_DATA_DIR}/${CMAKE_PROJECT_NAME}) 89 | set(GR_DOC_DIR ${GR_DATA_DIR}/doc) 90 | set(GR_PKG_DOC_DIR ${GR_DOC_DIR}/${CMAKE_PROJECT_NAME}) 91 | set(GR_CONF_DIR etc) 92 | set(GR_PKG_CONF_DIR ${GR_CONF_DIR}/${CMAKE_PROJECT_NAME}/conf.d) 93 | set(GR_LIBEXEC_DIR libexec) 94 | set(GR_PKG_LIBEXEC_DIR ${GR_LIBEXEC_DIR}/${CMAKE_PROJECT_NAME}) 95 | set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks) 96 | 97 | ######################################################################## 98 | # On Apple only, set install name and use rpath correctly, if not already set 99 | ######################################################################## 100 | if(APPLE) 101 | if(NOT CMAKE_INSTALL_NAME_DIR) 102 | set(CMAKE_INSTALL_NAME_DIR 103 | ${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE 104 | PATH "Library Install Name Destination Directory" FORCE) 105 | endif(NOT CMAKE_INSTALL_NAME_DIR) 106 | if(NOT CMAKE_INSTALL_RPATH) 107 | set(CMAKE_INSTALL_RPATH 108 | ${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE 109 | PATH "Library Install RPath" FORCE) 110 | endif(NOT CMAKE_INSTALL_RPATH) 111 | if(NOT CMAKE_BUILD_WITH_INSTALL_RPATH) 112 | set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE 113 | BOOL "Do Build Using Library Install RPath" FORCE) 114 | endif(NOT CMAKE_BUILD_WITH_INSTALL_RPATH) 115 | endif(APPLE) 116 | 117 | ######################################################################## 118 | # Find gnuradio build dependencies 119 | ######################################################################## 120 | # Search for GNU Radio and its components and versions. Add any 121 | # components required to the list of GR_REQUIRED_COMPONENTS (in all 122 | # caps such as FILTER or FFT) and change the version to the minimum 123 | # API compatible version required. 124 | find_package(Doxygen) 125 | 126 | MESSAGE(STATUS "Configuring GNU Radio C++ Libraries...") 127 | set(GR_REQUIRED_COMPONENTS RUNTIME PMT) 128 | set(MIN_GR_VERSION "3.7.8") 129 | set(MAX_GR_VERSION "3.8.0") 130 | find_package(Gnuradio REQUIRED) 131 | if("${Gnuradio_VERSION}" VERSION_LESS MIN_GR_VERSION OR NOT "${Gnuradio_VERSION}" 132 | VERSION_LESS MAX_GR_VERSION) 133 | MESSAGE(FATAL_ERROR "GnuRadio version required: >=\"" ${MIN_GR_VERSION} "\" \ 134 | < \"${MAX_GR_VERSION}\" found: \"" ${Gnuradio_VERSION} "\"") 135 | endif() 136 | 137 | ######################################################################## 138 | # Find LimeSuite 139 | ######################################################################## 140 | MESSAGE(STATUS "Configuring LimeSuite C++ Libraries...") 141 | INCLUDE(FindPkgConfig) 142 | PKG_CHECK_MODULES(PC_LIMESUITE LimeSuite) 143 | find_path(LIMESUITE_INCLUDE_DIRS 144 | NAMES LimeSuite.h 145 | HINTS ${PC_LIMESUITE_INCLUDEDIR}/lime 146 | PATHS ${LIMESUITE_PKG_INCLUDE_DIRS} 147 | /usr/include/lime 148 | /usr/local/include/lime 149 | ) 150 | find_library(LIMESUITE_LIB 151 | NAMES LimeSuite limesuite 152 | HINTS ${PC_LIMESUITE_LIBDIR} 153 | PATHS ${LIMESDR_PKG_LIBRARY_DIRS} 154 | /usr/lib 155 | /usr/local/lib 156 | ) 157 | 158 | message(STATUS "Found LimeSuite: ${LIMESUITE_INCLUDE_DIRS}, ${LIMESUITE_LIB}") 159 | 160 | ######################################################################## 161 | # LimeRFE 162 | ######################################################################## 163 | include(FeatureSummary) 164 | include(CMakeDependentOption) 165 | option(ENABLE_RFE "Enable LimeRFE support" OFF) 166 | add_feature_info(LimeRFE ENABLE_LIBRARY "LimeRFE support") 167 | if(ENABLE_RFE) 168 | message(STATUS "Enabling LimeRFE support") 169 | endif() 170 | 171 | ######################################################################## 172 | # Setup doxygen option 173 | ######################################################################## 174 | if(DOXYGEN_FOUND) 175 | option(ENABLE_DOXYGEN "Build docs using Doxygen" ON) 176 | else(DOXYGEN_FOUND) 177 | option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF) 178 | endif(DOXYGEN_FOUND) 179 | ######################################################################## 180 | # Setup the include and linker paths 181 | ######################################################################## 182 | include_directories( 183 | ${CMAKE_SOURCE_DIR}/lib 184 | ${CMAKE_SOURCE_DIR}/include 185 | ${CMAKE_BINARY_DIR}/lib 186 | ${CMAKE_BINARY_DIR}/include 187 | ${Boost_INCLUDE_DIRS} 188 | ${GNURADIO_ALL_INCLUDE_DIRS} 189 | ${LIMESUITE_INCLUDE_DIRS} 190 | ) 191 | 192 | link_directories( 193 | ${Boost_LIBRARY_DIRS} 194 | ${GNURADIO_RUNTIME_LIBRARY_DIRS} 195 | ${LIMESUITE_LIB} 196 | ) 197 | 198 | # Set component parameters 199 | set(GR_LIMESDR_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE INTERNAL "" FORCE) 200 | set(GR_LIMESDR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/swig CACHE INTERNAL "" FORCE) 201 | 202 | ######################################################################## 203 | # Create uninstall target 204 | ######################################################################## 205 | configure_file( 206 | ${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in 207 | ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake 208 | @ONLY) 209 | 210 | add_custom_target(uninstall 211 | ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake 212 | ) 213 | 214 | ######################################################################## 215 | # Add subdirectories 216 | ######################################################################## 217 | add_subdirectory(include/limesdr) 218 | add_subdirectory(lib) 219 | add_subdirectory(swig) 220 | add_subdirectory(python) 221 | add_subdirectory(grc) 222 | add_subdirectory(apps) 223 | add_subdirectory(docs) 224 | 225 | ######################################################################## 226 | # Install cmake search helper for this library 227 | ######################################################################## 228 | if(NOT CMAKE_MODULES_DIR) 229 | set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake) 230 | endif(NOT CMAKE_MODULES_DIR) 231 | 232 | install(FILES cmake/Modules/limesdrConfig.cmake 233 | DESTINATION ${CMAKE_MODULES_DIR}/limesdr 234 | ) 235 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2018 Lime Microsystems info@limemicro.com 2 | 3 | This program is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . -------------------------------------------------------------------------------- /MANIFEST.md: -------------------------------------------------------------------------------- 1 | title: The LIMESDR OOT Module 2 | brief: gr-limesdr blocks are used to control LimeSDR family devices 3 | tags: #sink, #source, #settings 4 | - sdr 5 | author: 6 | - Lime Microsystems 7 | copyright_owner: 8 | - Lime Microsystems 9 | license: 10 | #repo: 11 | #website: 12 | #icon: 13 | --- 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gr-limesdr 2 | 3 | Package includes GNU Radio blocks for various LimeSDR boards. 4 | 5 | ## Documentation 6 | 7 | * [MyriadRF Wiki page](https://wiki.myriadrf.org/Gr-limesdr_Plugin_for_GNURadio) 8 | 9 | ## Dependencies 10 | 11 | * GNU Radio(3.7) 12 | * BOOST 13 | * SWIG 14 | * LimeSuite 15 | 16 | ## Installation process 17 | 18 | #### Linux 19 | 20 | * Installing via PPA 21 |
22 | sudo add-apt-repository -y ppa:myriadrf/drivers
23 | sudo add-apt-repository -y ppa:myriadrf/gnuradio
24 | sudo apt update
25 | sudo apt install gr-limesdr
26 | 
27 | 28 | * Building from source 29 |
30 | git clone https://github.com/myriadrf/gr-limesdr.git
31 | cd gr-limesdr
32 | mkdir build
33 | cd build
34 | cmake ..
35 | make
36 | sudo make install
37 | sudo ldconfig
38 | 
39 | 40 | #### Windows 41 | 42 | Install GNU Radio then download zip file from [MyriadRF Wiki](http://downloads.myriadrf.org/project/limesuite/19.01/GNU_Radio_windows_19.01.zip) and extract it to: 43 |
44 | C:\Program Files\GNURadio-3.7
45 | 
46 | 47 | ## Known issues 48 | 49 | Known issues are located in: 50 | gr-limesdr/docs/known_issues.txt 51 | 52 | ## GNU Radio-Companion examples 53 | 54 | GNU Radio-Companion examples are located in: 55 | gr-limesdr/examples 56 | -------------------------------------------------------------------------------- /apps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | include(GrPython) 21 | 22 | GR_PYTHON_INSTALL( 23 | PROGRAMS 24 | DESTINATION bin 25 | ) 26 | -------------------------------------------------------------------------------- /cmake/Modules/CMakeParseArgumentsCopy.cmake: -------------------------------------------------------------------------------- 1 | # CMAKE_PARSE_ARGUMENTS( args...) 2 | # 3 | # CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for 4 | # parsing the arguments given to that macro or function. 5 | # It processes the arguments and defines a set of variables which hold the 6 | # values of the respective options. 7 | # 8 | # The argument contains all options for the respective macro, 9 | # i.e. keywords which can be used when calling the macro without any value 10 | # following, like e.g. the OPTIONAL keyword of the install() command. 11 | # 12 | # The argument contains all keywords for this macro 13 | # which are followed by one value, like e.g. DESTINATION keyword of the 14 | # install() command. 15 | # 16 | # The argument contains all keywords for this macro 17 | # which can be followed by more than one value, like e.g. the TARGETS or 18 | # FILES keywords of the install() command. 19 | # 20 | # When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the 21 | # keywords listed in , and 22 | # a variable composed of the given 23 | # followed by "_" and the name of the respective keyword. 24 | # These variables will then hold the respective value from the argument list. 25 | # For the keywords this will be TRUE or FALSE. 26 | # 27 | # All remaining arguments are collected in a variable 28 | # _UNPARSED_ARGUMENTS, this can be checked afterwards to see whether 29 | # your macro was called with unrecognized parameters. 30 | # 31 | # As an example here a my_install() macro, which takes similar arguments as the 32 | # real install() command: 33 | # 34 | # function(MY_INSTALL) 35 | # set(options OPTIONAL FAST) 36 | # set(oneValueArgs DESTINATION RENAME) 37 | # set(multiValueArgs TARGETS CONFIGURATIONS) 38 | # cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) 39 | # ... 40 | # 41 | # Assume my_install() has been called like this: 42 | # my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub) 43 | # 44 | # After the cmake_parse_arguments() call the macro will have set the following 45 | # variables: 46 | # MY_INSTALL_OPTIONAL = TRUE 47 | # MY_INSTALL_FAST = FALSE (this option was not used when calling my_install() 48 | # MY_INSTALL_DESTINATION = "bin" 49 | # MY_INSTALL_RENAME = "" (was not used) 50 | # MY_INSTALL_TARGETS = "foo;bar" 51 | # MY_INSTALL_CONFIGURATIONS = "" (was not used) 52 | # MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL" 53 | # 54 | # You can the continue and process these variables. 55 | # 56 | # Keywords terminate lists of values, e.g. if directly after a one_value_keyword 57 | # another recognized keyword follows, this is interpreted as the beginning of 58 | # the new option. 59 | # E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in 60 | # MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would 61 | # be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. 62 | 63 | #============================================================================= 64 | # Copyright 2010 Alexander Neundorf 65 | # 66 | # Distributed under the OSI-approved BSD License (the "License"); 67 | # see accompanying file Copyright.txt for details. 68 | # 69 | # This software is distributed WITHOUT ANY WARRANTY; without even the 70 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 71 | # See the License for more information. 72 | #============================================================================= 73 | # (To distribute this file outside of CMake, substitute the full 74 | # License text for the above reference.) 75 | 76 | 77 | if(__CMAKE_PARSE_ARGUMENTS_INCLUDED) 78 | return() 79 | endif() 80 | set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE) 81 | 82 | 83 | function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) 84 | # first set all result variables to empty/FALSE 85 | foreach(arg_name ${_singleArgNames} ${_multiArgNames}) 86 | set(${prefix}_${arg_name}) 87 | endforeach(arg_name) 88 | 89 | foreach(option ${_optionNames}) 90 | set(${prefix}_${option} FALSE) 91 | endforeach(option) 92 | 93 | set(${prefix}_UNPARSED_ARGUMENTS) 94 | 95 | set(insideValues FALSE) 96 | set(currentArgName) 97 | 98 | # now iterate over all arguments and fill the result variables 99 | foreach(currentArg ${ARGN}) 100 | list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword 101 | list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword 102 | list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword 103 | 104 | if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) 105 | if(insideValues) 106 | if("${insideValues}" STREQUAL "SINGLE") 107 | set(${prefix}_${currentArgName} ${currentArg}) 108 | set(insideValues FALSE) 109 | elseif("${insideValues}" STREQUAL "MULTI") 110 | list(APPEND ${prefix}_${currentArgName} ${currentArg}) 111 | endif() 112 | else(insideValues) 113 | list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) 114 | endif(insideValues) 115 | else() 116 | if(NOT ${optionIndex} EQUAL -1) 117 | set(${prefix}_${currentArg} TRUE) 118 | set(insideValues FALSE) 119 | elseif(NOT ${singleArgIndex} EQUAL -1) 120 | set(currentArgName ${currentArg}) 121 | set(${prefix}_${currentArgName}) 122 | set(insideValues "SINGLE") 123 | elseif(NOT ${multiArgIndex} EQUAL -1) 124 | set(currentArgName ${currentArg}) 125 | set(${prefix}_${currentArgName}) 126 | set(insideValues "MULTI") 127 | endif() 128 | endif() 129 | 130 | endforeach(currentArg) 131 | 132 | # propagate the result variables to the caller: 133 | foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) 134 | set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) 135 | endforeach(arg_name) 136 | set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) 137 | 138 | endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs) 139 | -------------------------------------------------------------------------------- /cmake/Modules/FindCppUnit.cmake: -------------------------------------------------------------------------------- 1 | # http://www.cmake.org/pipermail/cmake/2006-October/011446.html 2 | # Modified to use pkg config and use standard var names 3 | 4 | # 5 | # Find the CppUnit includes and library 6 | # 7 | # This module defines 8 | # CPPUNIT_INCLUDE_DIR, where to find tiff.h, etc. 9 | # CPPUNIT_LIBRARIES, the libraries to link against to use CppUnit. 10 | # CPPUNIT_FOUND, If false, do not try to use CppUnit. 11 | 12 | INCLUDE(FindPkgConfig) 13 | PKG_CHECK_MODULES(PC_CPPUNIT "cppunit") 14 | 15 | FIND_PATH(CPPUNIT_INCLUDE_DIRS 16 | NAMES cppunit/TestCase.h 17 | HINTS ${PC_CPPUNIT_INCLUDE_DIR} 18 | ${CMAKE_INSTALL_PREFIX}/include 19 | PATHS 20 | /usr/local/include 21 | /usr/include 22 | ) 23 | 24 | FIND_LIBRARY(CPPUNIT_LIBRARIES 25 | NAMES cppunit 26 | HINTS ${PC_CPPUNIT_LIBDIR} 27 | ${CMAKE_INSTALL_PREFIX}/lib 28 | ${CMAKE_INSTALL_PREFIX}/lib64 29 | PATHS 30 | ${CPPUNIT_INCLUDE_DIRS}/../lib 31 | /usr/local/lib 32 | /usr/lib 33 | ) 34 | 35 | LIST(APPEND CPPUNIT_LIBRARIES ${CMAKE_DL_LIBS}) 36 | 37 | INCLUDE(FindPackageHandleStandardArgs) 38 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPPUNIT DEFAULT_MSG CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS) 39 | MARK_AS_ADVANCED(CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS) 40 | -------------------------------------------------------------------------------- /cmake/Modules/FindGnuradioRuntime.cmake: -------------------------------------------------------------------------------- 1 | INCLUDE(FindPkgConfig) 2 | PKG_CHECK_MODULES(PC_GNURADIO_RUNTIME gnuradio-runtime) 3 | 4 | if(PC_GNURADIO_RUNTIME_FOUND) 5 | # look for include files 6 | FIND_PATH( 7 | GNURADIO_RUNTIME_INCLUDE_DIRS 8 | NAMES gnuradio/top_block.h 9 | HINTS $ENV{GNURADIO_RUNTIME_DIR}/include 10 | ${PC_GNURADIO_RUNTIME_INCLUDE_DIRS} 11 | ${CMAKE_INSTALL_PREFIX}/include 12 | PATHS /usr/local/include 13 | /usr/include 14 | ) 15 | 16 | # look for libs 17 | FIND_LIBRARY( 18 | GNURADIO_RUNTIME_LIBRARIES 19 | NAMES gnuradio-runtime 20 | HINTS $ENV{GNURADIO_RUNTIME_DIR}/lib 21 | ${PC_GNURADIO_RUNTIME_LIBDIR} 22 | ${CMAKE_INSTALL_PREFIX}/lib/ 23 | ${CMAKE_INSTALL_PREFIX}/lib64/ 24 | PATHS /usr/local/lib 25 | /usr/local/lib64 26 | /usr/lib 27 | /usr/lib64 28 | ) 29 | 30 | set(GNURADIO_RUNTIME_FOUND ${PC_GNURADIO_RUNTIME_FOUND}) 31 | endif(PC_GNURADIO_RUNTIME_FOUND) 32 | 33 | INCLUDE(FindPackageHandleStandardArgs) 34 | # do not check GNURADIO_RUNTIME_INCLUDE_DIRS, is not set when default include path us used. 35 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_RUNTIME DEFAULT_MSG GNURADIO_RUNTIME_LIBRARIES) 36 | MARK_AS_ADVANCED(GNURADIO_RUNTIME_LIBRARIES GNURADIO_RUNTIME_INCLUDE_DIRS) 37 | -------------------------------------------------------------------------------- /cmake/Modules/GrPlatform.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_PLATFORM_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_PLATFORM_CMAKE TRUE) 24 | 25 | ######################################################################## 26 | # Setup additional defines for OS types 27 | ######################################################################## 28 | if(CMAKE_SYSTEM_NAME STREQUAL "Linux") 29 | set(LINUX TRUE) 30 | endif() 31 | 32 | if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/debian_version") 33 | set(DEBIAN TRUE) 34 | endif() 35 | 36 | if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/redhat-release") 37 | set(REDHAT TRUE) 38 | endif() 39 | 40 | if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/slackware-version") 41 | set(SLACKWARE TRUE) 42 | endif() 43 | 44 | ######################################################################## 45 | # when the library suffix should be 64 (applies to redhat linux family) 46 | ######################################################################## 47 | if (REDHAT OR SLACKWARE) 48 | set(LIB64_CONVENTION TRUE) 49 | endif() 50 | 51 | if(NOT DEFINED LIB_SUFFIX AND LIB64_CONVENTION AND CMAKE_SYSTEM_PROCESSOR MATCHES "64$") 52 | set(LIB_SUFFIX 64) 53 | endif() 54 | set(LIB_SUFFIX ${LIB_SUFFIX} CACHE STRING "lib directory suffix") 55 | -------------------------------------------------------------------------------- /cmake/Modules/GrPython.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2010-2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_PYTHON_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_PYTHON_CMAKE TRUE) 24 | 25 | ######################################################################## 26 | # Setup the python interpreter: 27 | # This allows the user to specify a specific interpreter, 28 | # or finds the interpreter via the built-in cmake module. 29 | ######################################################################## 30 | #this allows the user to override PYTHON_EXECUTABLE 31 | if(PYTHON_EXECUTABLE) 32 | 33 | set(PYTHONINTERP_FOUND TRUE) 34 | 35 | #otherwise if not set, try to automatically find it 36 | else(PYTHON_EXECUTABLE) 37 | 38 | #use the built-in find script 39 | find_package(PythonInterp 2) 40 | 41 | #and if that fails use the find program routine 42 | if(NOT PYTHONINTERP_FOUND) 43 | find_program(PYTHON_EXECUTABLE NAMES python python2 python2.7 python2.6 python2.5) 44 | if(PYTHON_EXECUTABLE) 45 | set(PYTHONINTERP_FOUND TRUE) 46 | endif(PYTHON_EXECUTABLE) 47 | endif(NOT PYTHONINTERP_FOUND) 48 | 49 | endif(PYTHON_EXECUTABLE) 50 | 51 | if (CMAKE_CROSSCOMPILING) 52 | set(QA_PYTHON_EXECUTABLE "/usr/bin/python") 53 | else (CMAKE_CROSSCOMPILING) 54 | set(QA_PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE}) 55 | endif(CMAKE_CROSSCOMPILING) 56 | 57 | #make the path to the executable appear in the cmake gui 58 | set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter") 59 | set(QA_PYTHON_EXECUTABLE ${QA_PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter for QA tests") 60 | 61 | #make sure we can use -B with python (introduced in 2.6) 62 | if(PYTHON_EXECUTABLE) 63 | execute_process( 64 | COMMAND ${PYTHON_EXECUTABLE} -B -c "" 65 | OUTPUT_QUIET ERROR_QUIET 66 | RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT 67 | ) 68 | if(PYTHON_HAS_DASH_B_RESULT EQUAL 0) 69 | set(PYTHON_DASH_B "-B") 70 | endif() 71 | endif(PYTHON_EXECUTABLE) 72 | 73 | ######################################################################## 74 | # Check for the existence of a python module: 75 | # - desc a string description of the check 76 | # - mod the name of the module to import 77 | # - cmd an additional command to run 78 | # - have the result variable to set 79 | ######################################################################## 80 | macro(GR_PYTHON_CHECK_MODULE desc mod cmd have) 81 | message(STATUS "") 82 | message(STATUS "Python checking for ${desc}") 83 | execute_process( 84 | COMMAND ${PYTHON_EXECUTABLE} -c " 85 | ######################################### 86 | try: 87 | import ${mod} 88 | assert ${cmd} 89 | except ImportError, AssertionError: exit(-1) 90 | except: pass 91 | #########################################" 92 | RESULT_VARIABLE ${have} 93 | ) 94 | if(${have} EQUAL 0) 95 | message(STATUS "Python checking for ${desc} - found") 96 | set(${have} TRUE) 97 | else(${have} EQUAL 0) 98 | message(STATUS "Python checking for ${desc} - not found") 99 | set(${have} FALSE) 100 | endif(${have} EQUAL 0) 101 | endmacro(GR_PYTHON_CHECK_MODULE) 102 | 103 | ######################################################################## 104 | # Sets the python installation directory GR_PYTHON_DIR 105 | ######################################################################## 106 | if(NOT DEFINED GR_PYTHON_DIR) 107 | execute_process(COMMAND ${PYTHON_EXECUTABLE} -c " 108 | from distutils import sysconfig 109 | print sysconfig.get_python_lib(plat_specific=True, prefix='') 110 | " OUTPUT_VARIABLE GR_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE 111 | ) 112 | endif() 113 | file(TO_CMAKE_PATH ${GR_PYTHON_DIR} GR_PYTHON_DIR) 114 | 115 | ######################################################################## 116 | # Create an always-built target with a unique name 117 | # Usage: GR_UNIQUE_TARGET( ) 118 | ######################################################################## 119 | function(GR_UNIQUE_TARGET desc) 120 | file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}) 121 | execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib 122 | unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5] 123 | print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))" 124 | OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE) 125 | add_custom_target(${_target} ALL DEPENDS ${ARGN}) 126 | endfunction(GR_UNIQUE_TARGET) 127 | 128 | ######################################################################## 129 | # Install python sources (also builds and installs byte-compiled python) 130 | ######################################################################## 131 | function(GR_PYTHON_INSTALL) 132 | include(CMakeParseArgumentsCopy) 133 | CMAKE_PARSE_ARGUMENTS(GR_PYTHON_INSTALL "" "DESTINATION;COMPONENT" "FILES;PROGRAMS" ${ARGN}) 134 | 135 | #################################################################### 136 | if(GR_PYTHON_INSTALL_FILES) 137 | #################################################################### 138 | install(${ARGN}) #installs regular python files 139 | 140 | #create a list of all generated files 141 | unset(pysrcfiles) 142 | unset(pycfiles) 143 | unset(pyofiles) 144 | foreach(pyfile ${GR_PYTHON_INSTALL_FILES}) 145 | get_filename_component(pyfile ${pyfile} ABSOLUTE) 146 | list(APPEND pysrcfiles ${pyfile}) 147 | 148 | #determine if this file is in the source or binary directory 149 | file(RELATIVE_PATH source_rel_path ${CMAKE_CURRENT_SOURCE_DIR} ${pyfile}) 150 | string(LENGTH "${source_rel_path}" source_rel_path_len) 151 | file(RELATIVE_PATH binary_rel_path ${CMAKE_CURRENT_BINARY_DIR} ${pyfile}) 152 | string(LENGTH "${binary_rel_path}" binary_rel_path_len) 153 | 154 | #and set the generated path appropriately 155 | if(${source_rel_path_len} GREATER ${binary_rel_path_len}) 156 | set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${binary_rel_path}) 157 | else() 158 | set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${source_rel_path}) 159 | endif() 160 | list(APPEND pycfiles ${pygenfile}c) 161 | list(APPEND pyofiles ${pygenfile}o) 162 | 163 | #ensure generation path exists 164 | get_filename_component(pygen_path ${pygenfile} PATH) 165 | file(MAKE_DIRECTORY ${pygen_path}) 166 | 167 | endforeach(pyfile) 168 | 169 | #the command to generate the pyc files 170 | add_custom_command( 171 | DEPENDS ${pysrcfiles} OUTPUT ${pycfiles} 172 | COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pycfiles} 173 | ) 174 | 175 | #the command to generate the pyo files 176 | add_custom_command( 177 | DEPENDS ${pysrcfiles} OUTPUT ${pyofiles} 178 | COMMAND ${PYTHON_EXECUTABLE} -O ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pyofiles} 179 | ) 180 | 181 | #create install rule and add generated files to target list 182 | set(python_install_gen_targets ${pycfiles} ${pyofiles}) 183 | install(FILES ${python_install_gen_targets} 184 | DESTINATION ${GR_PYTHON_INSTALL_DESTINATION} 185 | COMPONENT ${GR_PYTHON_INSTALL_COMPONENT} 186 | ) 187 | 188 | #################################################################### 189 | elseif(GR_PYTHON_INSTALL_PROGRAMS) 190 | #################################################################### 191 | file(TO_NATIVE_PATH ${PYTHON_EXECUTABLE} pyexe_native) 192 | 193 | if (CMAKE_CROSSCOMPILING) 194 | set(pyexe_native "/usr/bin/env python") 195 | endif() 196 | 197 | foreach(pyfile ${GR_PYTHON_INSTALL_PROGRAMS}) 198 | get_filename_component(pyfile_name ${pyfile} NAME) 199 | get_filename_component(pyfile ${pyfile} ABSOLUTE) 200 | string(REPLACE "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" pyexefile "${pyfile}.exe") 201 | list(APPEND python_install_gen_targets ${pyexefile}) 202 | 203 | get_filename_component(pyexefile_path ${pyexefile} PATH) 204 | file(MAKE_DIRECTORY ${pyexefile_path}) 205 | 206 | add_custom_command( 207 | OUTPUT ${pyexefile} DEPENDS ${pyfile} 208 | COMMAND ${PYTHON_EXECUTABLE} -c 209 | "import re; R=re.compile('^\#!.*$\\n',flags=re.MULTILINE); open('${pyexefile}','w').write('\#!${pyexe_native}\\n'+R.sub('',open('${pyfile}','r').read()))" 210 | COMMENT "Shebangin ${pyfile_name}" 211 | VERBATIM 212 | ) 213 | 214 | #on windows, python files need an extension to execute 215 | get_filename_component(pyfile_ext ${pyfile} EXT) 216 | if(WIN32 AND NOT pyfile_ext) 217 | set(pyfile_name "${pyfile_name}.py") 218 | endif() 219 | 220 | install(PROGRAMS ${pyexefile} RENAME ${pyfile_name} 221 | DESTINATION ${GR_PYTHON_INSTALL_DESTINATION} 222 | COMPONENT ${GR_PYTHON_INSTALL_COMPONENT} 223 | ) 224 | endforeach(pyfile) 225 | 226 | endif() 227 | 228 | GR_UNIQUE_TARGET("pygen" ${python_install_gen_targets}) 229 | 230 | endfunction(GR_PYTHON_INSTALL) 231 | 232 | ######################################################################## 233 | # Write the python helper script that generates byte code files 234 | ######################################################################## 235 | file(WRITE ${CMAKE_BINARY_DIR}/python_compile_helper.py " 236 | import sys, py_compile 237 | files = sys.argv[1:] 238 | srcs, gens = files[:len(files)/2], files[len(files)/2:] 239 | for src, gen in zip(srcs, gens): 240 | py_compile.compile(file=src, cfile=gen, doraise=True) 241 | ") 242 | -------------------------------------------------------------------------------- /cmake/Modules/GrSwig.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2010-2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_SWIG_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_SWIG_CMAKE TRUE) 24 | 25 | include(GrPython) 26 | 27 | ######################################################################## 28 | # Builds a swig documentation file to be generated into python docstrings 29 | # Usage: GR_SWIG_MAKE_DOCS(output_file input_path input_path....) 30 | # 31 | # Set the following variable to specify extra dependent targets: 32 | # - GR_SWIG_DOCS_SOURCE_DEPS 33 | # - GR_SWIG_DOCS_TARGET_DEPS 34 | ######################################################################## 35 | function(GR_SWIG_MAKE_DOCS output_file) 36 | if(ENABLE_DOXYGEN) 37 | 38 | #setup the input files variable list, quote formated 39 | set(input_files) 40 | unset(INPUT_PATHS) 41 | foreach(input_path ${ARGN}) 42 | if(IS_DIRECTORY ${input_path}) #when input path is a directory 43 | file(GLOB input_path_h_files ${input_path}/*.h) 44 | else() #otherwise its just a file, no glob 45 | set(input_path_h_files ${input_path}) 46 | endif() 47 | list(APPEND input_files ${input_path_h_files}) 48 | set(INPUT_PATHS "${INPUT_PATHS} \"${input_path}\"") 49 | endforeach(input_path) 50 | 51 | #determine the output directory 52 | get_filename_component(name ${output_file} NAME_WE) 53 | get_filename_component(OUTPUT_DIRECTORY ${output_file} PATH) 54 | set(OUTPUT_DIRECTORY ${OUTPUT_DIRECTORY}/${name}_swig_docs) 55 | make_directory(${OUTPUT_DIRECTORY}) 56 | 57 | #generate the Doxyfile used by doxygen 58 | configure_file( 59 | ${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.swig_doc.in 60 | ${OUTPUT_DIRECTORY}/Doxyfile 61 | @ONLY) 62 | 63 | #Create a dummy custom command that depends on other targets 64 | include(GrMiscUtils) 65 | GR_GEN_TARGET_DEPS(_${name}_tag tag_deps ${GR_SWIG_DOCS_TARGET_DEPS}) 66 | 67 | #call doxygen on the Doxyfile + input headers 68 | add_custom_command( 69 | OUTPUT ${OUTPUT_DIRECTORY}/xml/index.xml 70 | DEPENDS ${input_files} ${GR_SWIG_DOCS_SOURCE_DEPS} ${tag_deps} 71 | COMMAND ${DOXYGEN_EXECUTABLE} ${OUTPUT_DIRECTORY}/Doxyfile 72 | COMMENT "Generating doxygen xml for ${name} docs" 73 | ) 74 | 75 | #call the swig_doc script on the xml files 76 | add_custom_command( 77 | OUTPUT ${output_file} 78 | DEPENDS ${input_files} ${stamp-file} ${OUTPUT_DIRECTORY}/xml/index.xml 79 | COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} 80 | ${CMAKE_SOURCE_DIR}/docs/doxygen/swig_doc.py 81 | ${OUTPUT_DIRECTORY}/xml 82 | ${output_file} 83 | COMMENT "Generating python docstrings for ${name}" 84 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/doxygen 85 | ) 86 | 87 | else(ENABLE_DOXYGEN) 88 | file(WRITE ${output_file} "\n") #no doxygen -> empty file 89 | endif(ENABLE_DOXYGEN) 90 | endfunction(GR_SWIG_MAKE_DOCS) 91 | 92 | ######################################################################## 93 | # Build a swig target for the common gnuradio use case. Usage: 94 | # GR_SWIG_MAKE(target ifile ifile ifile...) 95 | # 96 | # Set the following variables before calling: 97 | # - GR_SWIG_FLAGS 98 | # - GR_SWIG_INCLUDE_DIRS 99 | # - GR_SWIG_LIBRARIES 100 | # - GR_SWIG_SOURCE_DEPS 101 | # - GR_SWIG_TARGET_DEPS 102 | # - GR_SWIG_DOC_FILE 103 | # - GR_SWIG_DOC_DIRS 104 | ######################################################################## 105 | macro(GR_SWIG_MAKE name) 106 | set(ifiles ${ARGN}) 107 | 108 | # Shimming this in here to take care of a SWIG bug with handling 109 | # vector and vector (on 32-bit machines) and 110 | # vector (on 64-bit machines). Use this to test 111 | # the size of size_t, then set SIZE_T_32 if it's a 32-bit machine 112 | # or not if it's 64-bit. The logic in gr_type.i handles the rest. 113 | INCLUDE(CheckTypeSize) 114 | CHECK_TYPE_SIZE("size_t" SIZEOF_SIZE_T) 115 | CHECK_TYPE_SIZE("unsigned int" SIZEOF_UINT) 116 | if(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT}) 117 | list(APPEND GR_SWIG_FLAGS -DSIZE_T_32) 118 | endif(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT}) 119 | 120 | #do swig doc generation if specified 121 | if(GR_SWIG_DOC_FILE) 122 | set(GR_SWIG_DOCS_SOURCE_DEPS ${GR_SWIG_SOURCE_DEPS}) 123 | list(APPEND GR_SWIG_DOCS_TARGET_DEPS ${GR_SWIG_TARGET_DEPS}) 124 | GR_SWIG_MAKE_DOCS(${GR_SWIG_DOC_FILE} ${GR_SWIG_DOC_DIRS}) 125 | add_custom_target(${name}_swig_doc DEPENDS ${GR_SWIG_DOC_FILE}) 126 | list(APPEND GR_SWIG_TARGET_DEPS ${name}_swig_doc ${GR_RUNTIME_SWIG_DOC_FILE}) 127 | endif() 128 | 129 | #append additional include directories 130 | find_package(PythonLibs 2) 131 | list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_PATH}) #deprecated name (now dirs) 132 | list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS}) 133 | 134 | #prepend local swig directories 135 | list(INSERT GR_SWIG_INCLUDE_DIRS 0 ${CMAKE_CURRENT_SOURCE_DIR}) 136 | list(INSERT GR_SWIG_INCLUDE_DIRS 0 ${CMAKE_CURRENT_BINARY_DIR}) 137 | 138 | #determine include dependencies for swig file 139 | execute_process( 140 | COMMAND ${PYTHON_EXECUTABLE} 141 | ${CMAKE_BINARY_DIR}/get_swig_deps.py 142 | "${ifiles}" "${GR_SWIG_INCLUDE_DIRS}" 143 | OUTPUT_STRIP_TRAILING_WHITESPACE 144 | OUTPUT_VARIABLE SWIG_MODULE_${name}_EXTRA_DEPS 145 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 146 | ) 147 | 148 | #Create a dummy custom command that depends on other targets 149 | include(GrMiscUtils) 150 | GR_GEN_TARGET_DEPS(_${name}_swig_tag tag_deps ${GR_SWIG_TARGET_DEPS}) 151 | set(tag_file ${CMAKE_CURRENT_BINARY_DIR}/${name}.tag) 152 | add_custom_command( 153 | OUTPUT ${tag_file} 154 | DEPENDS ${GR_SWIG_SOURCE_DEPS} ${tag_deps} 155 | COMMAND ${CMAKE_COMMAND} -E touch ${tag_file} 156 | ) 157 | 158 | #append the specified include directories 159 | include_directories(${GR_SWIG_INCLUDE_DIRS}) 160 | list(APPEND SWIG_MODULE_${name}_EXTRA_DEPS ${tag_file}) 161 | 162 | #setup the swig flags with flags and include directories 163 | set(CMAKE_SWIG_FLAGS -fvirtual -modern -keyword -w511 -module ${name} ${GR_SWIG_FLAGS}) 164 | foreach(dir ${GR_SWIG_INCLUDE_DIRS}) 165 | list(APPEND CMAKE_SWIG_FLAGS "-I${dir}") 166 | endforeach(dir) 167 | 168 | #set the C++ property on the swig .i file so it builds 169 | set_source_files_properties(${ifiles} PROPERTIES CPLUSPLUS ON) 170 | 171 | #setup the actual swig library target to be built 172 | include(UseSWIG) 173 | SWIG_ADD_MODULE(${name} python ${ifiles}) 174 | SWIG_LINK_LIBRARIES(${name} ${PYTHON_LIBRARIES} ${GR_SWIG_LIBRARIES}) 175 | if(${name} STREQUAL "runtime_swig") 176 | SET_TARGET_PROPERTIES(${SWIG_MODULE_runtime_swig_REAL_NAME} PROPERTIES DEFINE_SYMBOL "gnuradio_runtime_EXPORTS") 177 | endif(${name} STREQUAL "runtime_swig") 178 | 179 | endmacro(GR_SWIG_MAKE) 180 | 181 | ######################################################################## 182 | # Install swig targets generated by GR_SWIG_MAKE. Usage: 183 | # GR_SWIG_INSTALL( 184 | # TARGETS target target target... 185 | # [DESTINATION destination] 186 | # [COMPONENT component] 187 | # ) 188 | ######################################################################## 189 | macro(GR_SWIG_INSTALL) 190 | 191 | include(CMakeParseArgumentsCopy) 192 | CMAKE_PARSE_ARGUMENTS(GR_SWIG_INSTALL "" "DESTINATION;COMPONENT" "TARGETS" ${ARGN}) 193 | 194 | foreach(name ${GR_SWIG_INSTALL_TARGETS}) 195 | install(TARGETS ${SWIG_MODULE_${name}_REAL_NAME} 196 | DESTINATION ${GR_SWIG_INSTALL_DESTINATION} 197 | COMPONENT ${GR_SWIG_INSTALL_COMPONENT} 198 | ) 199 | 200 | include(GrPython) 201 | GR_PYTHON_INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}.py 202 | DESTINATION ${GR_SWIG_INSTALL_DESTINATION} 203 | COMPONENT ${GR_SWIG_INSTALL_COMPONENT} 204 | ) 205 | 206 | GR_LIBTOOL( 207 | TARGET ${SWIG_MODULE_${name}_REAL_NAME} 208 | DESTINATION ${GR_SWIG_INSTALL_DESTINATION} 209 | ) 210 | 211 | endforeach(name) 212 | 213 | endmacro(GR_SWIG_INSTALL) 214 | 215 | ######################################################################## 216 | # Generate a python file that can determine swig dependencies. 217 | # Used by the make macro above to determine extra dependencies. 218 | # When you build C++, CMake figures out the header dependencies. 219 | # This code essentially performs that logic for swig includes. 220 | ######################################################################## 221 | file(WRITE ${CMAKE_BINARY_DIR}/get_swig_deps.py " 222 | 223 | import os, sys, re 224 | 225 | i_include_matcher = re.compile('%(include|import)\\s*[<|\"](.*)[>|\"]') 226 | h_include_matcher = re.compile('#(include)\\s*[<|\"](.*)[>|\"]') 227 | include_dirs = sys.argv[2].split(';') 228 | 229 | def get_swig_incs(file_path): 230 | if file_path.endswith('.i'): matcher = i_include_matcher 231 | else: matcher = h_include_matcher 232 | file_contents = open(file_path, 'r').read() 233 | return matcher.findall(file_contents, re.MULTILINE) 234 | 235 | def get_swig_deps(file_path, level): 236 | deps = [file_path] 237 | if level == 0: return deps 238 | for keyword, inc_file in get_swig_incs(file_path): 239 | for inc_dir in include_dirs: 240 | inc_path = os.path.join(inc_dir, inc_file) 241 | if not os.path.exists(inc_path): continue 242 | deps.extend(get_swig_deps(inc_path, level-1)) 243 | break #found, we dont search in lower prio inc dirs 244 | return deps 245 | 246 | if __name__ == '__main__': 247 | ifiles = sys.argv[1].split(';') 248 | deps = sum([get_swig_deps(ifile, 3) for ifile in ifiles], []) 249 | #sys.stderr.write(';'.join(set(deps)) + '\\n\\n') 250 | print(';'.join(set(deps))) 251 | ") 252 | -------------------------------------------------------------------------------- /cmake/Modules/GrTest.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2010-2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_TEST_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_TEST_CMAKE TRUE) 24 | 25 | ######################################################################## 26 | # Add a unit test and setup the environment for a unit test. 27 | # Takes the same arguments as the ADD_TEST function. 28 | # 29 | # Before calling set the following variables: 30 | # GR_TEST_TARGET_DEPS - built targets for the library path 31 | # GR_TEST_LIBRARY_DIRS - directories for the library path 32 | # GR_TEST_PYTHON_DIRS - directories for the python path 33 | # GR_TEST_ENVIRONS - other environment key/value pairs 34 | ######################################################################## 35 | function(GR_ADD_TEST test_name) 36 | 37 | #Ensure that the build exe also appears in the PATH. 38 | list(APPEND GR_TEST_TARGET_DEPS ${ARGN}) 39 | 40 | #In the land of windows, all libraries must be in the PATH. 41 | #Since the dependent libraries are not yet installed, 42 | #we must manually set them in the PATH to run tests. 43 | #The following appends the path of a target dependency. 44 | foreach(target ${GR_TEST_TARGET_DEPS}) 45 | get_target_property(location ${target} LOCATION) 46 | if(location) 47 | get_filename_component(path ${location} PATH) 48 | string(REGEX REPLACE "\\$\\(.*\\)" ${CMAKE_BUILD_TYPE} path ${path}) 49 | list(APPEND GR_TEST_LIBRARY_DIRS ${path}) 50 | endif(location) 51 | endforeach(target) 52 | 53 | if(WIN32) 54 | #SWIG generates the python library files into a subdirectory. 55 | #Therefore, we must append this subdirectory into PYTHONPATH. 56 | #Only do this for the python directories matching the following: 57 | foreach(pydir ${GR_TEST_PYTHON_DIRS}) 58 | get_filename_component(name ${pydir} NAME) 59 | if(name MATCHES "^(swig|lib|src)$") 60 | list(APPEND GR_TEST_PYTHON_DIRS ${pydir}/${CMAKE_BUILD_TYPE}) 61 | endif() 62 | endforeach(pydir) 63 | endif(WIN32) 64 | 65 | file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} srcdir) 66 | file(TO_NATIVE_PATH "${GR_TEST_LIBRARY_DIRS}" libpath) #ok to use on dir list? 67 | file(TO_NATIVE_PATH "${GR_TEST_PYTHON_DIRS}" pypath) #ok to use on dir list? 68 | 69 | set(environs "VOLK_GENERIC=1" "GR_DONT_LOAD_PREFS=1" "srcdir=${srcdir}") 70 | list(APPEND environs ${GR_TEST_ENVIRONS}) 71 | 72 | #http://www.cmake.org/pipermail/cmake/2009-May/029464.html 73 | #Replaced this add test + set environs code with the shell script generation. 74 | #Its nicer to be able to manually run the shell script to diagnose problems. 75 | #ADD_TEST(${ARGV}) 76 | #SET_TESTS_PROPERTIES(${test_name} PROPERTIES ENVIRONMENT "${environs}") 77 | 78 | if(UNIX) 79 | set(LD_PATH_VAR "LD_LIBRARY_PATH") 80 | if(APPLE) 81 | set(LD_PATH_VAR "DYLD_LIBRARY_PATH") 82 | endif() 83 | 84 | set(binpath "${CMAKE_CURRENT_BINARY_DIR}:$PATH") 85 | list(APPEND libpath "$${LD_PATH_VAR}") 86 | list(APPEND pypath "$PYTHONPATH") 87 | 88 | #replace list separator with the path separator 89 | string(REPLACE ";" ":" libpath "${libpath}") 90 | string(REPLACE ";" ":" pypath "${pypath}") 91 | list(APPEND environs "PATH=${binpath}" "${LD_PATH_VAR}=${libpath}" "PYTHONPATH=${pypath}") 92 | 93 | #generate a bat file that sets the environment and runs the test 94 | if (CMAKE_CROSSCOMPILING) 95 | set(SHELL "/bin/sh") 96 | else(CMAKE_CROSSCOMPILING) 97 | find_program(SHELL sh) 98 | endif(CMAKE_CROSSCOMPILING) 99 | set(sh_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.sh) 100 | file(WRITE ${sh_file} "#!${SHELL}\n") 101 | #each line sets an environment variable 102 | foreach(environ ${environs}) 103 | file(APPEND ${sh_file} "export ${environ}\n") 104 | endforeach(environ) 105 | #load the command to run with its arguments 106 | foreach(arg ${ARGN}) 107 | file(APPEND ${sh_file} "${arg} ") 108 | endforeach(arg) 109 | file(APPEND ${sh_file} "\n") 110 | 111 | #make the shell file executable 112 | execute_process(COMMAND chmod +x ${sh_file}) 113 | 114 | add_test(${test_name} ${SHELL} ${sh_file}) 115 | 116 | endif(UNIX) 117 | 118 | if(WIN32) 119 | list(APPEND libpath ${DLL_PATHS} "%PATH%") 120 | list(APPEND pypath "%PYTHONPATH%") 121 | 122 | #replace list separator with the path separator (escaped) 123 | string(REPLACE ";" "\\;" libpath "${libpath}") 124 | string(REPLACE ";" "\\;" pypath "${pypath}") 125 | list(APPEND environs "PATH=${libpath}" "PYTHONPATH=${pypath}") 126 | 127 | #generate a bat file that sets the environment and runs the test 128 | set(bat_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.bat) 129 | file(WRITE ${bat_file} "@echo off\n") 130 | #each line sets an environment variable 131 | foreach(environ ${environs}) 132 | file(APPEND ${bat_file} "SET ${environ}\n") 133 | endforeach(environ) 134 | #load the command to run with its arguments 135 | foreach(arg ${ARGN}) 136 | file(APPEND ${bat_file} "${arg} ") 137 | endforeach(arg) 138 | file(APPEND ${bat_file} "\n") 139 | 140 | add_test(${test_name} ${bat_file}) 141 | endif(WIN32) 142 | 143 | endfunction(GR_ADD_TEST) 144 | -------------------------------------------------------------------------------- /cmake/Modules/UseSWIG.cmake: -------------------------------------------------------------------------------- 1 | # - SWIG module for CMake 2 | # Defines the following macros: 3 | # SWIG_ADD_MODULE(name language [ files ]) 4 | # - Define swig module with given name and specified language 5 | # SWIG_LINK_LIBRARIES(name [ libraries ]) 6 | # - Link libraries to swig module 7 | # All other macros are for internal use only. 8 | # To get the actual name of the swig module, 9 | # use: ${SWIG_MODULE_${name}_REAL_NAME}. 10 | # Set Source files properties such as CPLUSPLUS and SWIG_FLAGS to specify 11 | # special behavior of SWIG. Also global CMAKE_SWIG_FLAGS can be used to add 12 | # special flags to all swig calls. 13 | # Another special variable is CMAKE_SWIG_OUTDIR, it allows one to specify 14 | # where to write all the swig generated module (swig -outdir option) 15 | # The name-specific variable SWIG_MODULE__EXTRA_DEPS may be used 16 | # to specify extra dependencies for the generated modules. 17 | # If the source file generated by swig need some special flag you can use 18 | # set_source_files_properties( ${swig_generated_file_fullname} 19 | # PROPERTIES COMPILE_FLAGS "-bla") 20 | 21 | 22 | #============================================================================= 23 | # Copyright 2004-2009 Kitware, Inc. 24 | # Copyright 2009 Mathieu Malaterre 25 | # 26 | # Distributed under the OSI-approved BSD License (the "License"); 27 | # see accompanying file Copyright.txt for details. 28 | # 29 | # This software is distributed WITHOUT ANY WARRANTY; without even the 30 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 31 | # See the License for more information. 32 | #============================================================================= 33 | # (To distribute this file outside of CMake, substitute the full 34 | # License text for the above reference.) 35 | 36 | set(SWIG_CXX_EXTENSION "cxx") 37 | set(SWIG_EXTRA_LIBRARIES "") 38 | 39 | set(SWIG_PYTHON_EXTRA_FILE_EXTENSION "py") 40 | 41 | # 42 | # For given swig module initialize variables associated with it 43 | # 44 | macro(SWIG_MODULE_INITIALIZE name language) 45 | string(TOUPPER "${language}" swig_uppercase_language) 46 | string(TOLOWER "${language}" swig_lowercase_language) 47 | set(SWIG_MODULE_${name}_LANGUAGE "${swig_uppercase_language}") 48 | set(SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG "${swig_lowercase_language}") 49 | 50 | set(SWIG_MODULE_${name}_REAL_NAME "${name}") 51 | if("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "UNKNOWN") 52 | message(FATAL_ERROR "SWIG Error: Language \"${language}\" not found") 53 | elseif("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "PYTHON") 54 | # when swig is used without the -interface it will produce in the module.py 55 | # a 'import _modulename' statement, which implies having a corresponding 56 | # _modulename.so (*NIX), _modulename.pyd (Win32). 57 | set(SWIG_MODULE_${name}_REAL_NAME "_${name}") 58 | elseif("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "PERL") 59 | set(SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow") 60 | endif() 61 | endmacro() 62 | 63 | # 64 | # For a given language, input file, and output file, determine extra files that 65 | # will be generated. This is internal swig macro. 66 | # 67 | 68 | macro(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile) 69 | set(${outfiles} "") 70 | get_source_file_property(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename 71 | ${infile} SWIG_MODULE_NAME) 72 | if(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename STREQUAL "NOTFOUND") 73 | get_filename_component(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename "${infile}" NAME_WE) 74 | endif() 75 | foreach(it ${SWIG_${language}_EXTRA_FILE_EXTENSION}) 76 | set(${outfiles} ${${outfiles}} 77 | "${generatedpath}/${SWIG_GET_EXTRA_OUTPUT_FILES_module_basename}.${it}") 78 | endforeach() 79 | endmacro() 80 | 81 | # 82 | # Take swig (*.i) file and add proper custom commands for it 83 | # 84 | macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile) 85 | set(swig_full_infile ${infile}) 86 | get_filename_component(swig_source_file_path "${infile}" PATH) 87 | get_filename_component(swig_source_file_name_we "${infile}" NAME_WE) 88 | get_source_file_property(swig_source_file_generated ${infile} GENERATED) 89 | get_source_file_property(swig_source_file_cplusplus ${infile} CPLUSPLUS) 90 | get_source_file_property(swig_source_file_flags ${infile} SWIG_FLAGS) 91 | if("${swig_source_file_flags}" STREQUAL "NOTFOUND") 92 | set(swig_source_file_flags "") 93 | endif() 94 | set(swig_source_file_fullname "${infile}") 95 | if(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_SOURCE_DIR}") 96 | string(REGEX REPLACE 97 | "^${CMAKE_CURRENT_SOURCE_DIR}" "" 98 | swig_source_file_relative_path 99 | "${swig_source_file_path}") 100 | else() 101 | if(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_BINARY_DIR}") 102 | string(REGEX REPLACE 103 | "^${CMAKE_CURRENT_BINARY_DIR}" "" 104 | swig_source_file_relative_path 105 | "${swig_source_file_path}") 106 | set(swig_source_file_generated 1) 107 | else() 108 | set(swig_source_file_relative_path "${swig_source_file_path}") 109 | if(swig_source_file_generated) 110 | set(swig_source_file_fullname "${CMAKE_CURRENT_BINARY_DIR}/${infile}") 111 | else() 112 | set(swig_source_file_fullname "${CMAKE_CURRENT_SOURCE_DIR}/${infile}") 113 | endif() 114 | endif() 115 | endif() 116 | 117 | set(swig_generated_file_fullname 118 | "${CMAKE_CURRENT_BINARY_DIR}") 119 | if(swig_source_file_relative_path) 120 | set(swig_generated_file_fullname 121 | "${swig_generated_file_fullname}/${swig_source_file_relative_path}") 122 | endif() 123 | # If CMAKE_SWIG_OUTDIR was specified then pass it to -outdir 124 | if(CMAKE_SWIG_OUTDIR) 125 | set(swig_outdir ${CMAKE_SWIG_OUTDIR}) 126 | else() 127 | set(swig_outdir ${CMAKE_CURRENT_BINARY_DIR}) 128 | endif() 129 | SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE} 130 | swig_extra_generated_files 131 | "${swig_outdir}" 132 | "${infile}") 133 | set(swig_generated_file_fullname 134 | "${swig_generated_file_fullname}/${swig_source_file_name_we}") 135 | # add the language into the name of the file (i.e. TCL_wrap) 136 | # this allows for the same .i file to be wrapped into different languages 137 | set(swig_generated_file_fullname 138 | "${swig_generated_file_fullname}${SWIG_MODULE_${name}_LANGUAGE}_wrap") 139 | 140 | if(swig_source_file_cplusplus) 141 | set(swig_generated_file_fullname 142 | "${swig_generated_file_fullname}.${SWIG_CXX_EXTENSION}") 143 | else() 144 | set(swig_generated_file_fullname 145 | "${swig_generated_file_fullname}.c") 146 | endif() 147 | 148 | # Shut up some warnings from poor SWIG code generation that we 149 | # can do nothing about, when this flag is available 150 | include(CheckCXXCompilerFlag) 151 | check_cxx_compiler_flag("-Wno-unused-but-set-variable" HAVE_WNO_UNUSED_BUT_SET_VARIABLE) 152 | if(HAVE_WNO_UNUSED_BUT_SET_VARIABLE) 153 | set_source_files_properties(${swig_generated_file_fullname} 154 | PROPERTIES COMPILE_FLAGS "-Wno-unused-but-set-variable") 155 | endif(HAVE_WNO_UNUSED_BUT_SET_VARIABLE) 156 | 157 | get_directory_property(cmake_include_directories INCLUDE_DIRECTORIES) 158 | set(swig_include_dirs) 159 | foreach(it ${cmake_include_directories}) 160 | set(swig_include_dirs ${swig_include_dirs} "-I${it}") 161 | endforeach() 162 | 163 | set(swig_special_flags) 164 | # default is c, so add c++ flag if it is c++ 165 | if(swig_source_file_cplusplus) 166 | set(swig_special_flags ${swig_special_flags} "-c++") 167 | endif() 168 | set(swig_extra_flags) 169 | if(SWIG_MODULE_${name}_EXTRA_FLAGS) 170 | set(swig_extra_flags ${swig_extra_flags} ${SWIG_MODULE_${name}_EXTRA_FLAGS}) 171 | endif() 172 | 173 | # hack to work around CMake bug in add_custom_command with multiple OUTPUT files 174 | 175 | file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}) 176 | execute_process( 177 | COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib 178 | unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5] 179 | print(re.sub('\\W', '_', '${name} ${reldir} ' + unique))" 180 | OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE 181 | ) 182 | 183 | file( 184 | WRITE ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp.in 185 | "int main(void){return 0;}\n" 186 | ) 187 | 188 | # create dummy dependencies 189 | add_custom_command( 190 | OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp 191 | COMMAND ${CMAKE_COMMAND} -E copy 192 | ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp.in 193 | ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp 194 | DEPENDS "${swig_source_file_fullname}" ${SWIG_MODULE_${name}_EXTRA_DEPS} 195 | COMMENT "" 196 | ) 197 | 198 | # create the dummy target 199 | add_executable(${_target} ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp) 200 | 201 | # add a custom command to the dummy target 202 | add_custom_command( 203 | TARGET ${_target} 204 | # Let's create the ${swig_outdir} at execution time, in case dir contains $(OutDir) 205 | COMMAND ${CMAKE_COMMAND} -E make_directory ${swig_outdir} 206 | COMMAND "${SWIG_EXECUTABLE}" 207 | ARGS "-${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}" 208 | ${swig_source_file_flags} 209 | ${CMAKE_SWIG_FLAGS} 210 | -outdir ${swig_outdir} 211 | ${swig_special_flags} 212 | ${swig_extra_flags} 213 | ${swig_include_dirs} 214 | -o "${swig_generated_file_fullname}" 215 | "${swig_source_file_fullname}" 216 | COMMENT "Swig source" 217 | ) 218 | 219 | #add dummy independent dependencies from the _target to each file 220 | #that will be generated by the SWIG command above 221 | 222 | set(${outfiles} "${swig_generated_file_fullname}" ${swig_extra_generated_files}) 223 | 224 | foreach(swig_gen_file ${${outfiles}}) 225 | add_custom_command( 226 | OUTPUT ${swig_gen_file} 227 | COMMAND "" 228 | DEPENDS ${_target} 229 | COMMENT "" 230 | ) 231 | endforeach() 232 | 233 | set_source_files_properties( 234 | ${outfiles} PROPERTIES GENERATED 1 235 | ) 236 | 237 | endmacro() 238 | 239 | # 240 | # Create Swig module 241 | # 242 | macro(SWIG_ADD_MODULE name language) 243 | SWIG_MODULE_INITIALIZE(${name} ${language}) 244 | set(swig_dot_i_sources) 245 | set(swig_other_sources) 246 | foreach(it ${ARGN}) 247 | if(${it} MATCHES ".*\\.i$") 248 | set(swig_dot_i_sources ${swig_dot_i_sources} "${it}") 249 | else() 250 | set(swig_other_sources ${swig_other_sources} "${it}") 251 | endif() 252 | endforeach() 253 | 254 | set(swig_generated_sources) 255 | foreach(it ${swig_dot_i_sources}) 256 | SWIG_ADD_SOURCE_TO_MODULE(${name} swig_generated_source ${it}) 257 | set(swig_generated_sources ${swig_generated_sources} "${swig_generated_source}") 258 | endforeach() 259 | get_directory_property(swig_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES) 260 | set_directory_properties(PROPERTIES 261 | ADDITIONAL_MAKE_CLEAN_FILES "${swig_extra_clean_files};${swig_generated_sources}") 262 | add_library(${SWIG_MODULE_${name}_REAL_NAME} 263 | MODULE 264 | ${swig_generated_sources} 265 | ${swig_other_sources}) 266 | string(TOLOWER "${language}" swig_lowercase_language) 267 | if ("${swig_lowercase_language}" STREQUAL "java") 268 | if (APPLE) 269 | # In java you want: 270 | # System.loadLibrary("LIBRARY"); 271 | # then JNI will look for a library whose name is platform dependent, namely 272 | # MacOS : libLIBRARY.jnilib 273 | # Windows: LIBRARY.dll 274 | # Linux : libLIBRARY.so 275 | set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".jnilib") 276 | endif () 277 | endif () 278 | if ("${swig_lowercase_language}" STREQUAL "python") 279 | # this is only needed for the python case where a _modulename.so is generated 280 | set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "") 281 | # Python extension modules on Windows must have the extension ".pyd" 282 | # instead of ".dll" as of Python 2.5. Older python versions do support 283 | # this suffix. 284 | # http://docs.python.org/whatsnew/ports.html#SECTION0001510000000000000000 285 | # 286 | # Windows: .dll is no longer supported as a filename extension for extension modules. 287 | # .pyd is now the only filename extension that will be searched for. 288 | # 289 | if(WIN32 AND NOT CYGWIN) 290 | set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".pyd") 291 | endif() 292 | endif () 293 | endmacro() 294 | 295 | # 296 | # Like TARGET_LINK_LIBRARIES but for swig modules 297 | # 298 | macro(SWIG_LINK_LIBRARIES name) 299 | if(SWIG_MODULE_${name}_REAL_NAME) 300 | target_link_libraries(${SWIG_MODULE_${name}_REAL_NAME} ${ARGN}) 301 | else() 302 | message(SEND_ERROR "Cannot find Swig library \"${name}\".") 303 | endif() 304 | endmacro() 305 | -------------------------------------------------------------------------------- /cmake/Modules/limesdrConfig.cmake: -------------------------------------------------------------------------------- 1 | INCLUDE(FindPkgConfig) 2 | PKG_CHECK_MODULES(PC_LIMESDR limesdr) 3 | 4 | FIND_PATH( 5 | LIMESDR_INCLUDE_DIRS 6 | NAMES limesdr/api.h 7 | HINTS $ENV{LIMESDR_DIR}/include 8 | ${PC_LIMESDR_INCLUDEDIR} 9 | PATHS ${CMAKE_INSTALL_PREFIX}/include 10 | /usr/local/include 11 | /usr/include 12 | ) 13 | 14 | FIND_LIBRARY( 15 | LIMESDR_LIBRARIES 16 | NAMES gnuradio-limesdr 17 | HINTS $ENV{LIMESDR_DIR}/lib 18 | ${PC_LIMESDR_LIBDIR} 19 | PATHS ${CMAKE_INSTALL_PREFIX}/lib 20 | ${CMAKE_INSTALL_PREFIX}/lib64 21 | /usr/local/lib 22 | /usr/local/lib64 23 | /usr/lib 24 | /usr/lib64 25 | ) 26 | 27 | INCLUDE(FindPackageHandleStandardArgs) 28 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIMESDR DEFAULT_MSG LIMESDR_LIBRARIES LIMESDR_INCLUDE_DIRS) 29 | MARK_AS_ADVANCED(LIMESDR_LIBRARIES LIMESDR_INCLUDE_DIRS) 30 | 31 | -------------------------------------------------------------------------------- /cmake/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | # http://www.vtk.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F 2 | 3 | IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 4 | MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") 5 | ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 6 | 7 | FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 8 | STRING(REGEX REPLACE "\n" ";" files "${files}") 9 | FOREACH(file ${files}) 10 | MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") 11 | IF(EXISTS "$ENV{DESTDIR}${file}") 12 | EXEC_PROGRAM( 13 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 14 | OUTPUT_VARIABLE rm_out 15 | RETURN_VALUE rm_retval 16 | ) 17 | IF(NOT "${rm_retval}" STREQUAL 0) 18 | MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 19 | ENDIF(NOT "${rm_retval}" STREQUAL 0) 20 | ELSEIF(IS_SYMLINK "$ENV{DESTDIR}${file}") 21 | EXEC_PROGRAM( 22 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 23 | OUTPUT_VARIABLE rm_out 24 | RETURN_VALUE rm_retval 25 | ) 26 | IF(NOT "${rm_retval}" STREQUAL 0) 27 | MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 28 | ENDIF(NOT "${rm_retval}" STREQUAL 0) 29 | ELSE(EXISTS "$ENV{DESTDIR}${file}") 30 | MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") 31 | ENDIF(EXISTS "$ENV{DESTDIR}${file}") 32 | ENDFOREACH(file) 33 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | gr-limesdr (2.1.7-1) unstable; urgency=low 2 | 3 | * Moved .ini file loading to advanced tab in GRC block description 4 | 5 | -- Lime Microsystems Thu, 29 Oct 2020 14:00:00 +0300 6 | gr-limesdr (2.1.6-1) unstable; urgency=low 7 | 8 | * Improve block labeling and documentation 9 | * Added LimeRFE board support 10 | * Fixed gain values to match LimeSuite 11 | * Updated required LimeSuite libraries to the newest version 12 | * Changed debian/rules to compile with LimeRFE support 13 | 14 | -- Lime Microsystems Wed, 29 Jul 2020 12:10:00 +0300 15 | gr-limesdr (2.1.4-2) unstable; urgency=low 16 | 17 | * Fix cmake for old versions 18 | 19 | -- Lime Microsystems Tue, 10 Dec 2019 11:47:20 +0300 20 | gr-limesdr (2.1.4-1) unstable; urgency=low 21 | 22 | * Allow change of parameters after the config file is loaded 23 | 24 | -- Lime Microsystems Tue, 10 Dec 2019 10:36:59 +0300 25 | gr-limesdr (2.1.3-1) unstable; urgency=low 26 | 27 | * debian packaging work for gr-limesdr 28 | 29 | -- Lime Microsystems Mon, 17 Jun 2019 13:46:48 +0300 30 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: gr-limesdr 2 | Section: comm 3 | Priority: optional 4 | Maintainer: Lime Microsystems 5 | Build-Depends: cmake, 6 | debhelper (>= 9~), 7 | gnuradio-dev, 8 | liblimesuite-dev (>= 20.07), 9 | pkg-config, 10 | python-dev, 11 | swig 12 | X-Python-Version: >= 2.7, << 2.8 13 | Standards-Version: 4.1.1 14 | Homepage: http://github.com/myriadrf/gr-limesdr 15 | Vcs-Git: git://github.com/myriadrf/gr-limesdr.git 16 | Vcs-Browser: https://github.com/myriadrf/gr-limesdr 17 | 18 | Package: gr-limesdr 19 | Architecture: any 20 | Pre-Depends: ${misc:Pre-Depends} 21 | Depends: ${misc:Depends}, ${python:Depends}, ${shlibs:Depends}, 22 | gnuradio, 23 | liblimesuite-dev (>= 20.07) 24 | Description:GNU-Radio blocks used to interface with various LimeSDR boards. 25 | Implementation of GNU-Radio out of tree modules which allow to interface with 26 | LimeSDR-USB, LimeSDR-Mini,LimeNET-Micro and LimeSDR-QPCIe boards. 27 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | 3 | Files: * 4 | Copyright: 2018 Lime Microsystems 5 | License: GPL-3+ 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; version 3 dated June, 2007, or (at 9 | your option) any later version. 10 | . 11 | On Debian systems, the complete text of version 3 of the GNU General 12 | Public License can be found in '/usr/share/common-licenses/GPL-3'. 13 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | %: 4 | dh $@ --with python2 --parallel 5 | 6 | override_dh_auto_configure: 7 | dh_auto_configure -- -DENABLE_RFE=ON -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /debian/triggers: -------------------------------------------------------------------------------- 1 | activate-noawait ldconfig 2 | -------------------------------------------------------------------------------- /docs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ######################################################################## 21 | # Setup dependencies 22 | ######################################################################## 23 | find_package(Doxygen) 24 | 25 | ######################################################################## 26 | # Begin conditional configuration 27 | ######################################################################## 28 | if(ENABLE_DOXYGEN) 29 | 30 | ######################################################################## 31 | # Add subdirectories 32 | ######################################################################## 33 | add_subdirectory(doxygen) 34 | 35 | endif(ENABLE_DOXYGEN) 36 | -------------------------------------------------------------------------------- /docs/README.limesdr: -------------------------------------------------------------------------------- 1 | This is the limesdr-write-a-block package meant as a guide to building 2 | out-of-tree packages. To use the limesdr blocks, the Python namespaces 3 | is in 'limesdr', which is imported as: 4 | 5 | import limesdr 6 | 7 | See the Doxygen documentation for details about the blocks available 8 | in this package. A quick listing of the details can be found in Python 9 | after importing by using: 10 | 11 | help(limesdr) 12 | -------------------------------------------------------------------------------- /docs/doxygen/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ######################################################################## 21 | # Create the doxygen configuration file 22 | ######################################################################## 23 | file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} top_srcdir) 24 | file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} top_builddir) 25 | file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} abs_top_srcdir) 26 | file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} abs_top_builddir) 27 | 28 | set(HAVE_DOT ${DOXYGEN_DOT_FOUND}) 29 | set(enable_html_docs YES) 30 | set(enable_latex_docs NO) 31 | set(enable_xml_docs YES) 32 | 33 | configure_file( 34 | ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in 35 | ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 36 | @ONLY) 37 | 38 | set(BUILT_DIRS ${CMAKE_CURRENT_BINARY_DIR}/xml ${CMAKE_CURRENT_BINARY_DIR}/html) 39 | 40 | ######################################################################## 41 | # Make and install doxygen docs 42 | ######################################################################## 43 | add_custom_command( 44 | OUTPUT ${BUILT_DIRS} 45 | COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 46 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 47 | COMMENT "Generating documentation with doxygen" 48 | ) 49 | 50 | add_custom_target(doxygen_target ALL DEPENDS ${BUILT_DIRS}) 51 | 52 | install(DIRECTORY ${BUILT_DIRS} DESTINATION ${GR_PKG_DOC_DIR}) 53 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file is part of GNU Radio 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | """ 22 | Python interface to contents of doxygen xml documentation. 23 | 24 | Example use: 25 | See the contents of the example folder for the C++ and 26 | doxygen-generated xml used in this example. 27 | 28 | >>> # Parse the doxygen docs. 29 | >>> import os 30 | >>> this_dir = os.path.dirname(globals()['__file__']) 31 | >>> xml_path = this_dir + "/example/xml/" 32 | >>> di = DoxyIndex(xml_path) 33 | 34 | Get a list of all top-level objects. 35 | 36 | >>> print([mem.name() for mem in di.members()]) 37 | [u'Aadvark', u'aadvarky_enough', u'main'] 38 | 39 | Get all functions. 40 | 41 | >>> print([mem.name() for mem in di.in_category(DoxyFunction)]) 42 | [u'aadvarky_enough', u'main'] 43 | 44 | Check if an object is present. 45 | 46 | >>> di.has_member(u'Aadvark') 47 | True 48 | >>> di.has_member(u'Fish') 49 | False 50 | 51 | Get an item by name and check its properties. 52 | 53 | >>> aad = di.get_member(u'Aadvark') 54 | >>> print(aad.brief_description) 55 | Models the mammal Aadvark. 56 | >>> print(aad.detailed_description) 57 | Sadly the model is incomplete and cannot capture all aspects of an aadvark yet. 58 | 59 | This line is uninformative and is only to test line breaks in the comments. 60 | >>> [mem.name() for mem in aad.members()] 61 | [u'aadvarkness', u'print', u'Aadvark', u'get_aadvarkness'] 62 | >>> aad.get_member(u'print').brief_description 63 | u'Outputs the vital aadvark statistics.' 64 | 65 | """ 66 | 67 | from doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther 68 | 69 | def _test(): 70 | import os 71 | this_dir = os.path.dirname(globals()['__file__']) 72 | xml_path = this_dir + "/example/xml/" 73 | di = DoxyIndex(xml_path) 74 | # Get the Aadvark class 75 | aad = di.get_member('Aadvark') 76 | aad.brief_description 77 | import doctest 78 | return doctest.testmod() 79 | 80 | if __name__ == "__main__": 81 | _test() 82 | 83 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/gr-limesdr/244c6bf4f1cb52a8b4d27240d7a4c88c9542cbbb/docs/doxygen/doxyxml/__init__.pyc -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/base.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file is part of GNU Radio 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | """ 22 | A base class is created. 23 | 24 | Classes based upon this are used to make more user-friendly interfaces 25 | to the doxygen xml docs than the generated classes provide. 26 | """ 27 | 28 | import os 29 | import pdb 30 | 31 | from xml.parsers.expat import ExpatError 32 | 33 | from generated import compound 34 | 35 | 36 | class Base(object): 37 | 38 | class Duplicate(StandardError): 39 | pass 40 | 41 | class NoSuchMember(StandardError): 42 | pass 43 | 44 | class ParsingError(StandardError): 45 | pass 46 | 47 | def __init__(self, parse_data, top=None): 48 | self._parsed = False 49 | self._error = False 50 | self._parse_data = parse_data 51 | self._members = [] 52 | self._dict_members = {} 53 | self._in_category = {} 54 | self._data = {} 55 | if top is not None: 56 | self._xml_path = top._xml_path 57 | # Set up holder of references 58 | else: 59 | top = self 60 | self._refs = {} 61 | self._xml_path = parse_data 62 | self.top = top 63 | 64 | @classmethod 65 | def from_refid(cls, refid, top=None): 66 | """ Instantiate class from a refid rather than parsing object. """ 67 | # First check to see if its already been instantiated. 68 | if top is not None and refid in top._refs: 69 | return top._refs[refid] 70 | # Otherwise create a new instance and set refid. 71 | inst = cls(None, top=top) 72 | inst.refid = refid 73 | inst.add_ref(inst) 74 | return inst 75 | 76 | @classmethod 77 | def from_parse_data(cls, parse_data, top=None): 78 | refid = getattr(parse_data, 'refid', None) 79 | if refid is not None and top is not None and refid in top._refs: 80 | return top._refs[refid] 81 | inst = cls(parse_data, top=top) 82 | if refid is not None: 83 | inst.refid = refid 84 | inst.add_ref(inst) 85 | return inst 86 | 87 | def add_ref(self, obj): 88 | if hasattr(obj, 'refid'): 89 | self.top._refs[obj.refid] = obj 90 | 91 | mem_classes = [] 92 | 93 | def get_cls(self, mem): 94 | for cls in self.mem_classes: 95 | if cls.can_parse(mem): 96 | return cls 97 | raise StandardError(("Did not find a class for object '%s'." \ 98 | % (mem.get_name()))) 99 | 100 | def convert_mem(self, mem): 101 | try: 102 | cls = self.get_cls(mem) 103 | converted = cls.from_parse_data(mem, self.top) 104 | if converted is None: 105 | raise StandardError('No class matched this object.') 106 | self.add_ref(converted) 107 | return converted 108 | except StandardError, e: 109 | print e 110 | 111 | @classmethod 112 | def includes(cls, inst): 113 | return isinstance(inst, cls) 114 | 115 | @classmethod 116 | def can_parse(cls, obj): 117 | return False 118 | 119 | def _parse(self): 120 | self._parsed = True 121 | 122 | def _get_dict_members(self, cat=None): 123 | """ 124 | For given category a dictionary is returned mapping member names to 125 | members of that category. For names that are duplicated the name is 126 | mapped to None. 127 | """ 128 | self.confirm_no_error() 129 | if cat not in self._dict_members: 130 | new_dict = {} 131 | for mem in self.in_category(cat): 132 | if mem.name() not in new_dict: 133 | new_dict[mem.name()] = mem 134 | else: 135 | new_dict[mem.name()] = self.Duplicate 136 | self._dict_members[cat] = new_dict 137 | return self._dict_members[cat] 138 | 139 | def in_category(self, cat): 140 | self.confirm_no_error() 141 | if cat is None: 142 | return self._members 143 | if cat not in self._in_category: 144 | self._in_category[cat] = [mem for mem in self._members 145 | if cat.includes(mem)] 146 | return self._in_category[cat] 147 | 148 | def get_member(self, name, cat=None): 149 | self.confirm_no_error() 150 | # Check if it's in a namespace or class. 151 | bits = name.split('::') 152 | first = bits[0] 153 | rest = '::'.join(bits[1:]) 154 | member = self._get_dict_members(cat).get(first, self.NoSuchMember) 155 | # Raise any errors that are returned. 156 | if member in set([self.NoSuchMember, self.Duplicate]): 157 | raise member() 158 | if rest: 159 | return member.get_member(rest, cat=cat) 160 | return member 161 | 162 | def has_member(self, name, cat=None): 163 | try: 164 | mem = self.get_member(name, cat=cat) 165 | return True 166 | except self.NoSuchMember: 167 | return False 168 | 169 | def data(self): 170 | self.confirm_no_error() 171 | return self._data 172 | 173 | def members(self): 174 | self.confirm_no_error() 175 | return self._members 176 | 177 | def process_memberdefs(self): 178 | mdtss = [] 179 | for sec in self._retrieved_data.compounddef.sectiondef: 180 | mdtss += sec.memberdef 181 | # At the moment we lose all information associated with sections. 182 | # Sometimes a memberdef is in several sectiondef. 183 | # We make sure we don't get duplicates here. 184 | uniques = set([]) 185 | for mem in mdtss: 186 | converted = self.convert_mem(mem) 187 | pair = (mem.name, mem.__class__) 188 | if pair not in uniques: 189 | uniques.add(pair) 190 | self._members.append(converted) 191 | 192 | def retrieve_data(self): 193 | filename = os.path.join(self._xml_path, self.refid + '.xml') 194 | try: 195 | self._retrieved_data = compound.parse(filename) 196 | except ExpatError: 197 | print('Error in xml in file %s' % filename) 198 | self._error = True 199 | self._retrieved_data = None 200 | 201 | def check_parsed(self): 202 | if not self._parsed: 203 | self._parse() 204 | 205 | def confirm_no_error(self): 206 | self.check_parsed() 207 | if self._error: 208 | raise self.ParsingError() 209 | 210 | def error(self): 211 | self.check_parsed() 212 | return self._error 213 | 214 | def name(self): 215 | # first see if we can do it without processing. 216 | if self._parse_data is not None: 217 | return self._parse_data.name 218 | self.check_parsed() 219 | return self._retrieved_data.compounddef.name 220 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/base.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/gr-limesdr/244c6bf4f1cb52a8b4d27240d7a4c88c9542cbbb/docs/doxygen/doxyxml/base.pyc -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/doxyindex.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file is part of GNU Radio 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | """ 22 | Classes providing more user-friendly interfaces to the doxygen xml 23 | docs than the generated classes provide. 24 | """ 25 | 26 | import os 27 | 28 | from generated import index 29 | from base import Base 30 | from text import description 31 | 32 | class DoxyIndex(Base): 33 | """ 34 | Parses a doxygen xml directory. 35 | """ 36 | 37 | __module__ = "gnuradio.utils.doxyxml" 38 | 39 | def _parse(self): 40 | if self._parsed: 41 | return 42 | super(DoxyIndex, self)._parse() 43 | self._root = index.parse(os.path.join(self._xml_path, 'index.xml')) 44 | for mem in self._root.compound: 45 | converted = self.convert_mem(mem) 46 | # For files we want the contents to be accessible directly 47 | # from the parent rather than having to go through the file 48 | # object. 49 | if self.get_cls(mem) == DoxyFile: 50 | if mem.name.endswith('.h'): 51 | self._members += converted.members() 52 | self._members.append(converted) 53 | else: 54 | self._members.append(converted) 55 | 56 | 57 | def generate_swig_doc_i(self): 58 | """ 59 | %feature("docstring") gr_make_align_on_samplenumbers_ss::align_state " 60 | Wraps the C++: gr_align_on_samplenumbers_ss::align_state"; 61 | """ 62 | pass 63 | 64 | 65 | class DoxyCompMem(Base): 66 | 67 | 68 | kind = None 69 | 70 | def __init__(self, *args, **kwargs): 71 | super(DoxyCompMem, self).__init__(*args, **kwargs) 72 | 73 | @classmethod 74 | def can_parse(cls, obj): 75 | return obj.kind == cls.kind 76 | 77 | def set_descriptions(self, parse_data): 78 | bd = description(getattr(parse_data, 'briefdescription', None)) 79 | dd = description(getattr(parse_data, 'detaileddescription', None)) 80 | self._data['brief_description'] = bd 81 | self._data['detailed_description'] = dd 82 | 83 | class DoxyCompound(DoxyCompMem): 84 | pass 85 | 86 | class DoxyMember(DoxyCompMem): 87 | pass 88 | 89 | 90 | class DoxyFunction(DoxyMember): 91 | 92 | __module__ = "gnuradio.utils.doxyxml" 93 | 94 | kind = 'function' 95 | 96 | def _parse(self): 97 | if self._parsed: 98 | return 99 | super(DoxyFunction, self)._parse() 100 | self.set_descriptions(self._parse_data) 101 | self._data['params'] = [] 102 | prms = self._parse_data.param 103 | for prm in prms: 104 | self._data['params'].append(DoxyParam(prm)) 105 | 106 | brief_description = property(lambda self: self.data()['brief_description']) 107 | detailed_description = property(lambda self: self.data()['detailed_description']) 108 | params = property(lambda self: self.data()['params']) 109 | 110 | Base.mem_classes.append(DoxyFunction) 111 | 112 | 113 | class DoxyParam(DoxyMember): 114 | 115 | __module__ = "gnuradio.utils.doxyxml" 116 | 117 | def _parse(self): 118 | if self._parsed: 119 | return 120 | super(DoxyParam, self)._parse() 121 | self.set_descriptions(self._parse_data) 122 | self._data['declname'] = self._parse_data.declname 123 | 124 | brief_description = property(lambda self: self.data()['brief_description']) 125 | detailed_description = property(lambda self: self.data()['detailed_description']) 126 | declname = property(lambda self: self.data()['declname']) 127 | 128 | class DoxyClass(DoxyCompound): 129 | 130 | __module__ = "gnuradio.utils.doxyxml" 131 | 132 | kind = 'class' 133 | 134 | def _parse(self): 135 | if self._parsed: 136 | return 137 | super(DoxyClass, self)._parse() 138 | self.retrieve_data() 139 | if self._error: 140 | return 141 | self.set_descriptions(self._retrieved_data.compounddef) 142 | # Sectiondef.kind tells about whether private or public. 143 | # We just ignore this for now. 144 | self.process_memberdefs() 145 | 146 | brief_description = property(lambda self: self.data()['brief_description']) 147 | detailed_description = property(lambda self: self.data()['detailed_description']) 148 | 149 | Base.mem_classes.append(DoxyClass) 150 | 151 | 152 | class DoxyFile(DoxyCompound): 153 | 154 | __module__ = "gnuradio.utils.doxyxml" 155 | 156 | kind = 'file' 157 | 158 | def _parse(self): 159 | if self._parsed: 160 | return 161 | super(DoxyFile, self)._parse() 162 | self.retrieve_data() 163 | self.set_descriptions(self._retrieved_data.compounddef) 164 | if self._error: 165 | return 166 | self.process_memberdefs() 167 | 168 | brief_description = property(lambda self: self.data()['brief_description']) 169 | detailed_description = property(lambda self: self.data()['detailed_description']) 170 | 171 | Base.mem_classes.append(DoxyFile) 172 | 173 | 174 | class DoxyNamespace(DoxyCompound): 175 | 176 | __module__ = "gnuradio.utils.doxyxml" 177 | 178 | kind = 'namespace' 179 | 180 | Base.mem_classes.append(DoxyNamespace) 181 | 182 | 183 | class DoxyGroup(DoxyCompound): 184 | 185 | __module__ = "gnuradio.utils.doxyxml" 186 | 187 | kind = 'group' 188 | 189 | def _parse(self): 190 | if self._parsed: 191 | return 192 | super(DoxyGroup, self)._parse() 193 | self.retrieve_data() 194 | if self._error: 195 | return 196 | cdef = self._retrieved_data.compounddef 197 | self._data['title'] = description(cdef.title) 198 | # Process inner groups 199 | grps = cdef.innergroup 200 | for grp in grps: 201 | converted = DoxyGroup.from_refid(grp.refid, top=self.top) 202 | self._members.append(converted) 203 | # Process inner classes 204 | klasses = cdef.innerclass 205 | for kls in klasses: 206 | converted = DoxyClass.from_refid(kls.refid, top=self.top) 207 | self._members.append(converted) 208 | # Process normal members 209 | self.process_memberdefs() 210 | 211 | title = property(lambda self: self.data()['title']) 212 | 213 | 214 | Base.mem_classes.append(DoxyGroup) 215 | 216 | 217 | class DoxyFriend(DoxyMember): 218 | 219 | __module__ = "gnuradio.utils.doxyxml" 220 | 221 | kind = 'friend' 222 | 223 | Base.mem_classes.append(DoxyFriend) 224 | 225 | 226 | class DoxyOther(Base): 227 | 228 | __module__ = "gnuradio.utils.doxyxml" 229 | 230 | kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum', 'dir', 'page']) 231 | 232 | @classmethod 233 | def can_parse(cls, obj): 234 | return obj.kind in cls.kinds 235 | 236 | Base.mem_classes.append(DoxyOther) 237 | 238 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/doxyindex.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/gr-limesdr/244c6bf4f1cb52a8b4d27240d7a4c88c9542cbbb/docs/doxygen/doxyxml/doxyindex.pyc -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/generated/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Contains generated files produced by generateDS.py. 3 | 4 | These do the real work of parsing the doxygen xml files but the 5 | resultant classes are not very friendly to navigate so the rest of the 6 | doxyxml module processes them further. 7 | """ 8 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/generated/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/gr-limesdr/244c6bf4f1cb52a8b4d27240d7a4c88c9542cbbb/docs/doxygen/doxyxml/generated/__init__.pyc -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/generated/compound.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/gr-limesdr/244c6bf4f1cb52a8b4d27240d7a4c88c9542cbbb/docs/doxygen/doxyxml/generated/compound.pyc -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/generated/compoundsuper.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/gr-limesdr/244c6bf4f1cb52a8b4d27240d7a4c88c9542cbbb/docs/doxygen/doxyxml/generated/compoundsuper.pyc -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/generated/index.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Generated Mon Feb 9 19:08:05 2009 by generateDS.py. 5 | """ 6 | 7 | from xml.dom import minidom 8 | 9 | import os 10 | import sys 11 | import compound 12 | 13 | import indexsuper as supermod 14 | 15 | class DoxygenTypeSub(supermod.DoxygenType): 16 | def __init__(self, version=None, compound=None): 17 | supermod.DoxygenType.__init__(self, version, compound) 18 | 19 | def find_compounds_and_members(self, details): 20 | """ 21 | Returns a list of all compounds and their members which match details 22 | """ 23 | 24 | results = [] 25 | for compound in self.compound: 26 | members = compound.find_members(details) 27 | if members: 28 | results.append([compound, members]) 29 | else: 30 | if details.match(compound): 31 | results.append([compound, []]) 32 | 33 | return results 34 | 35 | supermod.DoxygenType.subclass = DoxygenTypeSub 36 | # end class DoxygenTypeSub 37 | 38 | 39 | class CompoundTypeSub(supermod.CompoundType): 40 | def __init__(self, kind=None, refid=None, name='', member=None): 41 | supermod.CompoundType.__init__(self, kind, refid, name, member) 42 | 43 | def find_members(self, details): 44 | """ 45 | Returns a list of all members which match details 46 | """ 47 | 48 | results = [] 49 | 50 | for member in self.member: 51 | if details.match(member): 52 | results.append(member) 53 | 54 | return results 55 | 56 | supermod.CompoundType.subclass = CompoundTypeSub 57 | # end class CompoundTypeSub 58 | 59 | 60 | class MemberTypeSub(supermod.MemberType): 61 | 62 | def __init__(self, kind=None, refid=None, name=''): 63 | supermod.MemberType.__init__(self, kind, refid, name) 64 | 65 | supermod.MemberType.subclass = MemberTypeSub 66 | # end class MemberTypeSub 67 | 68 | 69 | def parse(inFilename): 70 | 71 | doc = minidom.parse(inFilename) 72 | rootNode = doc.documentElement 73 | rootObj = supermod.DoxygenType.factory() 74 | rootObj.build(rootNode) 75 | 76 | return rootObj 77 | 78 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/generated/index.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/gr-limesdr/244c6bf4f1cb52a8b4d27240d7a4c88c9542cbbb/docs/doxygen/doxyxml/generated/index.pyc -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/generated/indexsuper.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/gr-limesdr/244c6bf4f1cb52a8b4d27240d7a4c88c9542cbbb/docs/doxygen/doxyxml/generated/indexsuper.pyc -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/text.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file is part of GNU Radio 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | """ 22 | Utilities for extracting text from generated classes. 23 | """ 24 | 25 | def is_string(txt): 26 | if isinstance(txt, str): 27 | return True 28 | try: 29 | if isinstance(txt, unicode): 30 | return True 31 | except NameError: 32 | pass 33 | return False 34 | 35 | def description(obj): 36 | if obj is None: 37 | return None 38 | return description_bit(obj).strip() 39 | 40 | def description_bit(obj): 41 | if hasattr(obj, 'content'): 42 | contents = [description_bit(item) for item in obj.content] 43 | result = ''.join(contents) 44 | elif hasattr(obj, 'content_'): 45 | contents = [description_bit(item) for item in obj.content_] 46 | result = ''.join(contents) 47 | elif hasattr(obj, 'value'): 48 | result = description_bit(obj.value) 49 | elif is_string(obj): 50 | return obj 51 | else: 52 | raise StandardError('Expecting a string or something with content, content_ or value attribute') 53 | # If this bit is a paragraph then add one some line breaks. 54 | if hasattr(obj, 'name') and obj.name == 'para': 55 | result += "\n\n" 56 | return result 57 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/text.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/gr-limesdr/244c6bf4f1cb52a8b4d27240d7a4c88c9542cbbb/docs/doxygen/doxyxml/text.pyc -------------------------------------------------------------------------------- /docs/doxygen/other/group_defs.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * \defgroup block GNU Radio LIMESDR C++ Signal Processing Blocks 3 | * \brief All C++ blocks that can be used from the LIMESDR GNU Radio 4 | * module are listed here or in the subcategories below. 5 | * 6 | */ 7 | 8 | -------------------------------------------------------------------------------- /docs/doxygen/other/main_page.dox: -------------------------------------------------------------------------------- 1 | /*! \mainpage 2 | 3 | Welcome to the GNU Radio LIMESDR Block 4 | 5 | This is the intro page for the Doxygen manual generated for the LIMESDR 6 | block (docs/doxygen/other/main_page.dox). Edit it to add more detailed 7 | documentation about the new GNU Radio modules contained in this 8 | project. 9 | 10 | */ 11 | -------------------------------------------------------------------------------- /docs/doxygen/swig_doc.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010,2011 Free Software Foundation, Inc. 3 | # 4 | # This file is part of GNU Radio 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | """ 22 | Creates the swig_doc.i SWIG interface file. 23 | Execute using: python swig_doc.py xml_path outputfilename 24 | 25 | The file instructs SWIG to transfer the doxygen comments into the 26 | python docstrings. 27 | 28 | """ 29 | 30 | import sys 31 | 32 | try: 33 | from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile, base 34 | except ImportError: 35 | from gnuradio.doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile, base 36 | 37 | 38 | def py_name(name): 39 | bits = name.split('_') 40 | return '_'.join(bits[1:]) 41 | 42 | def make_name(name): 43 | bits = name.split('_') 44 | return bits[0] + '_make_' + '_'.join(bits[1:]) 45 | 46 | 47 | class Block(object): 48 | """ 49 | Checks if doxyxml produced objects correspond to a gnuradio block. 50 | """ 51 | 52 | @classmethod 53 | def includes(cls, item): 54 | if not isinstance(item, DoxyClass): 55 | return False 56 | # Check for a parsing error. 57 | if item.error(): 58 | return False 59 | return item.has_member(make_name(item.name()), DoxyFriend) 60 | 61 | 62 | def utoascii(text): 63 | """ 64 | Convert unicode text into ascii and escape quotes. 65 | """ 66 | if text is None: 67 | return '' 68 | out = text.encode('ascii', 'replace') 69 | out = out.replace('"', '\\"') 70 | return out 71 | 72 | 73 | def combine_descriptions(obj): 74 | """ 75 | Combines the brief and detailed descriptions of an object together. 76 | """ 77 | description = [] 78 | bd = obj.brief_description.strip() 79 | dd = obj.detailed_description.strip() 80 | if bd: 81 | description.append(bd) 82 | if dd: 83 | description.append(dd) 84 | return utoascii('\n\n'.join(description)).strip() 85 | 86 | 87 | entry_templ = '%feature("docstring") {name} "{docstring}"' 88 | def make_entry(obj, name=None, templ="{description}", description=None): 89 | """ 90 | Create a docstring entry for a swig interface file. 91 | 92 | obj - a doxyxml object from which documentation will be extracted. 93 | name - the name of the C object (defaults to obj.name()) 94 | templ - an optional template for the docstring containing only one 95 | variable named 'description'. 96 | description - if this optional variable is set then it's value is 97 | used as the description instead of extracting it from obj. 98 | """ 99 | if name is None: 100 | name=obj.name() 101 | if "operator " in name: 102 | return '' 103 | if description is None: 104 | description = combine_descriptions(obj) 105 | docstring = templ.format(description=description) 106 | if not docstring: 107 | return '' 108 | return entry_templ.format( 109 | name=name, 110 | docstring=docstring, 111 | ) 112 | 113 | 114 | def make_func_entry(func, name=None, description=None, params=None): 115 | """ 116 | Create a function docstring entry for a swig interface file. 117 | 118 | func - a doxyxml object from which documentation will be extracted. 119 | name - the name of the C object (defaults to func.name()) 120 | description - if this optional variable is set then it's value is 121 | used as the description instead of extracting it from func. 122 | params - a parameter list that overrides using func.params. 123 | """ 124 | if params is None: 125 | params = func.params 126 | params = [prm.declname for prm in params] 127 | if params: 128 | sig = "Params: (%s)" % ", ".join(params) 129 | else: 130 | sig = "Params: (NONE)" 131 | templ = "{description}\n\n" + sig 132 | return make_entry(func, name=name, templ=utoascii(templ), 133 | description=description) 134 | 135 | 136 | def make_class_entry(klass, description=None): 137 | """ 138 | Create a class docstring for a swig interface file. 139 | """ 140 | output = [] 141 | output.append(make_entry(klass, description=description)) 142 | for func in klass.in_category(DoxyFunction): 143 | name = klass.name() + '::' + func.name() 144 | output.append(make_func_entry(func, name=name)) 145 | return "\n\n".join(output) 146 | 147 | 148 | def make_block_entry(di, block): 149 | """ 150 | Create class and function docstrings of a gnuradio block for a 151 | swig interface file. 152 | """ 153 | descriptions = [] 154 | # Get the documentation associated with the class. 155 | class_desc = combine_descriptions(block) 156 | if class_desc: 157 | descriptions.append(class_desc) 158 | # Get the documentation associated with the make function 159 | make_func = di.get_member(make_name(block.name()), DoxyFunction) 160 | make_func_desc = combine_descriptions(make_func) 161 | if make_func_desc: 162 | descriptions.append(make_func_desc) 163 | # Get the documentation associated with the file 164 | try: 165 | block_file = di.get_member(block.name() + ".h", DoxyFile) 166 | file_desc = combine_descriptions(block_file) 167 | if file_desc: 168 | descriptions.append(file_desc) 169 | except base.Base.NoSuchMember: 170 | # Don't worry if we can't find a matching file. 171 | pass 172 | # And join them all together to make a super duper description. 173 | super_description = "\n\n".join(descriptions) 174 | # Associate the combined description with the class and 175 | # the make function. 176 | output = [] 177 | output.append(make_class_entry(block, description=super_description)) 178 | creator = block.get_member(block.name(), DoxyFunction) 179 | output.append(make_func_entry(make_func, description=super_description, 180 | params=creator.params)) 181 | return "\n\n".join(output) 182 | 183 | 184 | def make_swig_interface_file(di, swigdocfilename, custom_output=None): 185 | 186 | output = [""" 187 | /* 188 | * This file was automatically generated using swig_doc.py. 189 | * 190 | * Any changes to it will be lost next time it is regenerated. 191 | */ 192 | """] 193 | 194 | if custom_output is not None: 195 | output.append(custom_output) 196 | 197 | # Create docstrings for the blocks. 198 | blocks = di.in_category(Block) 199 | make_funcs = set([]) 200 | for block in blocks: 201 | try: 202 | make_func = di.get_member(make_name(block.name()), DoxyFunction) 203 | make_funcs.add(make_func.name()) 204 | output.append(make_block_entry(di, block)) 205 | except block.ParsingError: 206 | print('Parsing error for block %s' % block.name()) 207 | 208 | # Create docstrings for functions 209 | # Don't include the make functions since they have already been dealt with. 210 | funcs = [f for f in di.in_category(DoxyFunction) if f.name() not in make_funcs] 211 | for f in funcs: 212 | try: 213 | output.append(make_func_entry(f)) 214 | except f.ParsingError: 215 | print('Parsing error for function %s' % f.name()) 216 | 217 | # Create docstrings for classes 218 | block_names = [block.name() for block in blocks] 219 | klasses = [k for k in di.in_category(DoxyClass) if k.name() not in block_names] 220 | for k in klasses: 221 | try: 222 | output.append(make_class_entry(k)) 223 | except k.ParsingError: 224 | print('Parsing error for class %s' % k.name()) 225 | 226 | # Docstrings are not created for anything that is not a function or a class. 227 | # If this excludes anything important please add it here. 228 | 229 | output = "\n\n".join(output) 230 | 231 | swig_doc = file(swigdocfilename, 'w') 232 | swig_doc.write(output) 233 | swig_doc.close() 234 | 235 | if __name__ == "__main__": 236 | # Parse command line options and set up doxyxml. 237 | err_msg = "Execute using: python swig_doc.py xml_path outputfilename" 238 | if len(sys.argv) != 3: 239 | raise StandardError(err_msg) 240 | xml_path = sys.argv[1] 241 | swigdocfilename = sys.argv[2] 242 | di = DoxyIndex(xml_path) 243 | 244 | # gnuradio.gr.msq_queue.insert_tail and delete_head create errors unless docstrings are defined! 245 | # This is presumably a bug in SWIG. 246 | #msg_q = di.get_member(u'gr_msg_queue', DoxyClass) 247 | #insert_tail = msg_q.get_member(u'insert_tail', DoxyFunction) 248 | #delete_head = msg_q.get_member(u'delete_head', DoxyFunction) 249 | output = [] 250 | #output.append(make_func_entry(insert_tail, name='gr_py_msg_queue__insert_tail')) 251 | #output.append(make_func_entry(delete_head, name='gr_py_msg_queue__delete_head')) 252 | custom_output = "\n\n".join(output) 253 | 254 | # Generate the docstrings interface file. 255 | make_swig_interface_file(di, swigdocfilename, custom_output=custom_output) 256 | -------------------------------------------------------------------------------- /docs/doxygen/swig_doc.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/gr-limesdr/244c6bf4f1cb52a8b4d27240d7a4c88c9542cbbb/docs/doxygen/swig_doc.pyc -------------------------------------------------------------------------------- /docs/known_issues.txt: -------------------------------------------------------------------------------- 1 | 1. Python Path is not /usr/lib/python2.7/site-package/:/usr/local/lib/python2.7/site-package/ 2 | export PYTHONPATH="/usr/lib/python2.7/site-packages/:/usr/local/lib/python2.7/site-packages" 3 | 4 | this line is need to be added in the end of .bashrc file. 5 | 6 | 2. Blocks work with LimeSuite version 17.10.0 and above. 7 | 8 | 3. While running GNU Radio flowgraph “aUaU” message is thrown. This means audio underrun (not enough 9 | samples ready to send to sound sink. 10 | 11 | 4. Doesn't compile with GNU Radio 3.8. 12 | 13 | 5. CW is being transmitted when flowgraph is killed. 14 | -------------------------------------------------------------------------------- /examples/FM_transmitter.grc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tue Feb 20 16:22:48 2018 5 | 6 | options 7 | 8 | author 9 | Lime Microsystems 10 | 11 | 12 | window_size 13 | (1000,500) 14 | 15 | 16 | category 17 | Custom 18 | 19 | 20 | comment 21 | 22 | 23 | 24 | description 25 | 26 | 27 | 28 | _enabled 29 | True 30 | 31 | 32 | _coordinate 33 | (8, 8) 34 | 35 | 36 | _rotation 37 | 0 38 | 39 | 40 | generate_options 41 | wx_gui 42 | 43 | 44 | hier_block_src_path 45 | .: 46 | 47 | 48 | id 49 | top_block 50 | 51 | 52 | max_nouts 53 | 0 54 | 55 | 56 | qt_qss_theme 57 | 58 | 59 | 60 | realtime_scheduling 61 | 62 | 63 | 64 | run_command 65 | {python} -u {filename} 66 | 67 | 68 | run_options 69 | run 70 | 71 | 72 | run 73 | True 74 | 75 | 76 | sizing_mode 77 | fixed 78 | 79 | 80 | thread_safe_setters 81 | 82 | 83 | 84 | title 85 | FM transmitter 86 | 87 | 88 | placement 89 | (0,0) 90 | 91 | 92 | 93 | analog_nbfm_tx 94 | 95 | audio_rate 96 | 48000 97 | 98 | 99 | alias 100 | 101 | 102 | 103 | comment 104 | 105 | 106 | 107 | affinity 108 | 109 | 110 | 111 | _enabled 112 | 1 113 | 114 | 115 | _coordinate 116 | (200, 200) 117 | 118 | 119 | _rotation 120 | 0 121 | 122 | 123 | id 124 | analog_nbfm_tx_0_0 125 | 126 | 127 | max_dev 128 | 2e3 129 | 130 | 131 | maxoutbuf 132 | 0 133 | 134 | 135 | minoutbuf 136 | 0 137 | 138 | 139 | fh 140 | -1.0 141 | 142 | 143 | quad_rate 144 | 480000 145 | 146 | 147 | tau 148 | 75e-6 149 | 150 | 151 | 152 | blocks_wavfile_source 153 | 154 | alias 155 | 156 | 157 | 158 | comment 159 | 160 | 161 | 162 | affinity 163 | 164 | 165 | 166 | _enabled 167 | 1 168 | 169 | 170 | file 171 | /home/garmus/GITHUB/gr-limesdr/examples/guitar.wav 172 | 173 | 174 | _coordinate 175 | (16, 220) 176 | 177 | 178 | _rotation 179 | 0 180 | 181 | 182 | id 183 | blocks_wavfile_source_0_0 184 | 185 | 186 | maxoutbuf 187 | 0 188 | 189 | 190 | minoutbuf 191 | 0 192 | 193 | 194 | nchan 195 | 1 196 | 197 | 198 | repeat 199 | True 200 | 201 | 202 | 203 | limesdr_sink 204 | 205 | alias 206 | 207 | 208 | 209 | analog_bandw_ch0 210 | 5e6 211 | 212 | 213 | calibr_bandw_ch0 214 | 0 215 | 216 | 217 | digital_bandw_ch0 218 | 100e3 219 | 220 | 221 | gain_dB_ch0 222 | 60 223 | 224 | 225 | nco_freq_ch0 226 | 0 227 | 228 | 229 | pa_path_ch0 230 | 255 231 | 232 | 233 | analog_bandw_ch1 234 | 5e6 235 | 236 | 237 | calibr_bandw_ch1 238 | 0 239 | 240 | 241 | digital_bandw_ch1 242 | 100e3 243 | 244 | 245 | gain_dB_ch1 246 | 60 247 | 248 | 249 | nco_freq_ch1 250 | 0 251 | 252 | 253 | pa_path_ch1 254 | 1 255 | 256 | 257 | channel_mode 258 | 0 259 | 260 | 261 | comment 262 | 263 | 264 | 265 | affinity 266 | 267 | 268 | 269 | serial 270 | 271 | 272 | 273 | _enabled 274 | True 275 | 276 | 277 | filename 278 | 279 | 280 | 281 | _coordinate 282 | (696, 20) 283 | 284 | 285 | _rotation 286 | 0 287 | 288 | 289 | id 290 | limesdr_sink_0 291 | 292 | 293 | length_tag_name 294 | 295 | 296 | 297 | oversample 298 | 0 299 | 300 | 301 | rf_freq 302 | 446.09375e6 303 | 304 | 305 | samp_rate 306 | 2e6 307 | 308 | 309 | 310 | rational_resampler_xxx 311 | 312 | alias 313 | 314 | 315 | 316 | comment 317 | 318 | 319 | 320 | affinity 321 | 322 | 323 | 324 | decim 325 | 6 326 | 327 | 328 | _enabled 329 | 1 330 | 331 | 332 | fbw 333 | 0 334 | 335 | 336 | _coordinate 337 | (448, 208) 338 | 339 | 340 | _rotation 341 | 0 342 | 343 | 344 | id 345 | rational_resampler_xxx_0 346 | 347 | 348 | interp 349 | 25 350 | 351 | 352 | maxoutbuf 353 | 0 354 | 355 | 356 | minoutbuf 357 | 0 358 | 359 | 360 | taps 361 | 362 | 363 | 364 | type 365 | ccf 366 | 367 | 368 | 369 | wxgui_fftsink2 370 | 371 | avg_alpha 372 | 0 373 | 374 | 375 | average 376 | False 377 | 378 | 379 | baseband_freq 380 | 446.09375e6 381 | 382 | 383 | alias 384 | 385 | 386 | 387 | comment 388 | 389 | 390 | 391 | affinity 392 | 393 | 394 | 395 | _enabled 396 | True 397 | 398 | 399 | fft_size 400 | 1024 401 | 402 | 403 | freqvar 404 | None 405 | 406 | 407 | _coordinate 408 | (696, 308) 409 | 410 | 411 | _rotation 412 | 0 413 | 414 | 415 | grid_pos 416 | 417 | 418 | 419 | id 420 | wxgui_fftsink2_0 421 | 422 | 423 | notebook 424 | 425 | 426 | 427 | peak_hold 428 | False 429 | 430 | 431 | ref_level 432 | 0 433 | 434 | 435 | ref_scale 436 | 2.0 437 | 438 | 439 | fft_rate 440 | 15 441 | 442 | 443 | samp_rate 444 | 2e6 445 | 446 | 447 | title 448 | Transmitting data 449 | 450 | 451 | type 452 | complex 453 | 454 | 455 | win_size 456 | 457 | 458 | 459 | win 460 | None 461 | 462 | 463 | y_divs 464 | 10 465 | 466 | 467 | y_per_div 468 | 10 469 | 470 | 471 | 472 | analog_nbfm_tx_0_0 473 | rational_resampler_xxx_0 474 | 0 475 | 0 476 | 477 | 478 | blocks_wavfile_source_0_0 479 | analog_nbfm_tx_0_0 480 | 0 481 | 0 482 | 483 | 484 | rational_resampler_xxx_0 485 | limesdr_sink_0 486 | 0 487 | 0 488 | 489 | 490 | rational_resampler_xxx_0 491 | wxgui_fftsink2_0 492 | 0 493 | 0 494 | 495 | 496 | -------------------------------------------------------------------------------- /examples/guitar.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/gr-limesdr/244c6bf4f1cb52a8b4d27240d7a4c88c9542cbbb/examples/guitar.wav -------------------------------------------------------------------------------- /examples/piano.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/gr-limesdr/244c6bf4f1cb52a8b4d27240d7a4c88c9542cbbb/examples/piano.wav -------------------------------------------------------------------------------- /grc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | install(FILES 21 | limesdr_source.xml 22 | limesdr_sink.xml DESTINATION share/gnuradio/grc/blocks 23 | ) 24 | if(ENABLE_RFE) 25 | install(FILES limesdr_rfe.xml DESTINATION share/gnuradio/grc/blocks) 26 | endif() -------------------------------------------------------------------------------- /grc/limesdr_rfe.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | LimeRFE Control 4 | limesdr_rfe 5 | [LimeSuite] 6 | import limesdr 7 | limesdr.rfe($comm_type, 8 | #if $comm_type() == 0 9 | $com_port, 10 | #else 11 | $sdr_serial, 12 | #end if 13 | $filename, 14 | $rx_channel, 15 | $tx_channel, 16 | $rx_port, $tx_port, $mode, $notch, $atten) 17 | 18 | 19 | change_mode($mode) 20 | set_attenuation($atten) 21 | set_notch($notch) 22 | set_fan($fan) 23 | 24 | 25 | Communication 26 | comm_type 27 | 0 28 | int 29 | 33 | 37 | 38 | 39 | 40 | USB COM Port 41 | com_port 42 | 43 | string 44 | 45 | #if $comm_type() == 0 46 | part 47 | #else 48 | all 49 | #end if 50 | 51 | 52 | 53 | 54 | SDR Device Serial 55 | sdr_serial 56 | 57 | string 58 | 59 | #if $comm_type() == 1 60 | part 61 | #else 62 | all 63 | #end if 64 | 65 | 66 | 67 | 68 | Configuration File 69 | filename 70 | 71 | file_open 72 | part 73 | Advanced 74 | 75 | 76 | 77 | Enable Fan 78 | fan 79 | 0 80 | int 81 | part 82 | 86 | 90 | 91 | 92 | 93 | Mode 94 | mode 95 | 0 96 | int 97 | 101 | 105 | 109 | 113 | 114 | 115 | 116 | RX Channel 117 | rx_channel 118 | 1 119 | int 120 | 124 | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | 189 | 190 | 191 | RX Port 192 | rx_port 193 | 1 194 | int 195 | 199 | 203 | 204 | 205 | 206 | RX Attenuation(dB) 207 | atten 208 | 0 209 | int 210 | part 211 | 215 | 219 | 223 | 227 | 231 | 238 | 242 | 243 | 244 | 245 | AM FM Notch Filter 246 | notch 247 | 0 248 | int 249 | part 250 | 254 | 258 | 259 | 260 | 261 | TX Channel 262 | tx_channel 263 | 1 264 | int 265 | 266 | #if $rx_channel() > 11 267 | all 268 | #else 269 | none 270 | #end if 271 | 272 | 276 | 280 | 284 | 288 | 292 | 296 | 300 | 304 | 308 | 312 | 316 | 320 | 321 | 322 | 323 | TX Port 324 | tx_port 325 | 1 326 | int 327 | 331 | 335 | 339 | 340 | 341 | ------------------------------------------------------------------------------------------------------------------- 342 | COMMUNICATION 343 | 344 | Type of communication used to configure LimeRFE board. 345 | Direct USB: LimeRFE is configured directly through USB COM port 346 | SDR: LimeRFE is configured through LimeSDR device GPIO ports 347 | 348 | ------------------------------------------------------------------------------------------------------------------- 349 | USB COM PORT 350 | 351 | Specified USB COM Port device is connected to e.g. /dev/ttyUSB0 on linux or COM0 on windows 352 | ------------------------------------------------------------------------------------------------------------------- 353 | SDR DEVICE SERIAL 354 | 355 | SDR Device serial number obtained by running 356 | 357 | LimeUtil --find 358 | 359 | If left blank, the first device in the list will be used to configure LimeRFE board 360 | ------------------------------------------------------------------------------------------------------------------- 361 | ENABLE FAN 362 | 363 | Enable or disable fan connected to LimeRFE device 364 | ------------------------------------------------------------------------------------------------------------------- 365 | MODE 366 | 367 | Select LimeRFE mode to be used, valid values are: RX(0), TX(1), RX+TX(2), NONE(3) 368 | 369 | ------------------------------------------------------------------------------------------------------------------- 370 | RX CHANNEL 371 | 372 | Select RX channel to be configured, if Cellular Bands are selected, the same channel is set for TX 373 | 374 | ------------------------------------------------------------------------------------------------------------------- 375 | RX PORT 376 | 377 | Select hardware port to be used for receive 378 | 379 | ------------------------------------------------------------------------------------------------------------------- 380 | RX ATTENUATION 381 | 382 | Specifies the attenuation in the RX path. Attenuation [dB] = 2 * attenuation. 383 | Valid value range is [0,7] 384 | 385 | ------------------------------------------------------------------------------------------------------------------- 386 | AM FM NOTCH FILTER 387 | 388 | Enables or disables AM FM notch filter 389 | 390 | Note: Only works for specific channels(see block diagram of LimeRFE) 391 | 392 | ------------------------------------------------------------------------------------------------------------------- 393 | TX CHANNEL 394 | 395 | Select TX channel to be configured 396 | 397 | ------------------------------------------------------------------------------------------------------------------- 398 | TX PORT 399 | 400 | Select hardware port to be used for transmit 401 | ------------------------------------------------------------------------------------------------------------------- 402 | CONFIGURATION FILE 403 | 404 | This setting is available in "Advanced" tab of grc block. 405 | If set LimeRFE device will be configured using already generated .ini file 406 | 407 | Note: .ini file must be generated using LimeSuite->Modules->LimeRFE->save, general LimeSuite .ini file will not work 408 | ------------------------------------------------------------------------------------------------------------------- 409 | 410 | 411 | -------------------------------------------------------------------------------- /include/limesdr/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011,2012 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ######################################################################## 21 | # Install public header files 22 | ######################################################################## 23 | install(FILES 24 | api.h 25 | source.h 26 | sink.h 27 | DESTINATION include/limesdr 28 | ) 29 | if(ENABLE_RFE) 30 | install(FILES rfe.h DESTINATION include/limesdr 31 | ) 32 | endif() 33 | -------------------------------------------------------------------------------- /include/limesdr/api.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2018 Lime Microsystems info@limemicro.com 4 | * 5 | * GNU Radio is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * GNU Radio is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifndef INCLUDED_LIMESDR_API_H 22 | #define INCLUDED_LIMESDR_API_H 23 | 24 | #include 25 | 26 | #ifdef gnuradio_limesdr_EXPORTS 27 | #define LIMESDR_API __GR_ATTR_EXPORT 28 | #else 29 | #define LIMESDR_API __GR_ATTR_IMPORT 30 | #endif 31 | 32 | #endif /* INCLUDED_LIMESDR_API_H */ 33 | -------------------------------------------------------------------------------- /include/limesdr/rfe.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2020 Lime Microsystems 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifndef INCLUDED_LIMERFE_H 22 | #define INCLUDED_LIMERFE_H 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | namespace gr { 30 | namespace limesdr { 31 | 32 | /*! 33 | * \brief GNURadio block to control LimeRFE boards 34 | * \ingroup limesdr 35 | * 36 | */ 37 | class LIMESDR_API rfe 38 | { 39 | public: 40 | rfe(int comm_type, 41 | std::string device, 42 | std::string config_file, 43 | char IDRX, 44 | char IDTX, 45 | char PortRX, 46 | char PortTX, 47 | char Mode, 48 | char Notch, 49 | char Atten); 50 | ~rfe(); 51 | /** 52 | * Change LimeRFE Mode 53 | * 54 | * @param mode Mode to be set: RX(0), TX(1), NONE(2), TXRX(3) 55 | * 56 | * @return 0 on success, other on failure (see LimeRFE error codes) 57 | */ 58 | int change_mode(int mode); 59 | /** 60 | * Enable or disbale fan 61 | * 62 | * @param enable fan state: 0 - disable; 1 - enable. 63 | * 64 | * @return 0 on success, other on failure (see LimeRFE error codes) 65 | */ 66 | int set_fan(int enable); 67 | /** 68 | * Set RX Attenuation value 69 | * 70 | * @param attenuation Specifies the attenuation in the RX path. Attenuation [dB] = 71 | * 2 * attenuation. Value range: [0,7] 72 | * 73 | * @return 0 on success, other on failure (see LimeRFE error codes) 74 | */ 75 | int set_attenuation(int attenuation); 76 | /** 77 | * Enable or disable AM/FM notch filter 78 | * 79 | * @param enable notch state: 0 - disable; 1 - enable 80 | * 81 | * @note Notch filter is only possible up to HAM 430-440 MHz, or Wideband 1-1000 MHz 82 | * @return 0 on success, other on failure (see LimeRFE error codes) 83 | */ 84 | int set_notch(int enable); 85 | 86 | private: 87 | rfe_dev_t* rfe_dev = nullptr; 88 | rfe_boardState boardState = { RFE_CID_WB_1000, 89 | RFE_CID_WB_1000, 90 | RFE_PORT_1, 91 | RFE_PORT_1, 92 | RFE_MODE_NONE, 93 | RFE_NOTCH_OFF, 94 | 0, 95 | 0, 96 | 0 }; 97 | int sdr_device_num = 0; 98 | 99 | void print_error(int error); 100 | 101 | void get_board_state() 102 | { 103 | rfe_boardState currentState = { 0 }; 104 | if (RFE_GetState(rfe_dev, ¤tState) != 0) { 105 | std::cout << "LimeRFE: failed to get board state" << std::endl; 106 | return; 107 | } 108 | 109 | std::cout << "LimeRFE: RX channel: " << (int)currentState.channelIDRX << std::endl; 110 | std::cout << "LimeRFE: TX channel: " << (int)currentState.channelIDTX << std::endl; 111 | std::cout << "LimeRFE: PortRX: " << (int)currentState.selPortRX << std::endl; 112 | std::cout << "LimeRFE: PortTx: " << (int)currentState.selPortTX << std::endl; 113 | std::cout << "LimeRFE: Mode: " << (int)currentState.mode << std::endl; 114 | std::cout << "LimeRFE: Notch: " << (int)currentState.notchOnOff << std::endl; 115 | std::cout << "LimeRFE: Attenuation: " << (int)currentState.attValue << std::endl; 116 | std::cout << "LimeRFE: Enable SWR: " << (int)currentState.enableSWR << std::endl; 117 | std::cout << "LimeRFE: SourceSWR: " << (int)currentState.sourceSWR << std::endl; 118 | } 119 | }; 120 | 121 | } // namespace limesdr 122 | } // namespace gr 123 | 124 | #endif /* INCLUDED_LIMERFE_H */ 125 | -------------------------------------------------------------------------------- /include/limesdr/sink.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2018 Lime Microsystems info@limemicro.com 4 | * 5 | * GNU Radio is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * GNU Radio is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifndef INCLUDED_LIMESDR_SINK_H 22 | #define INCLUDED_LIMESDR_SINK_H 23 | 24 | #include 25 | #include 26 | 27 | namespace gr { 28 | namespace limesdr { 29 | class LIMESDR_API sink : virtual public gr::block { 30 | public: 31 | typedef boost::shared_ptr sptr; 32 | /*! 33 | * @brief Return a shared_ptr to a new instance of sink. 34 | * 35 | * To avoid accidental use of raw pointers, sink's 36 | * constructor is private. limesdr::sink::make is the public 37 | * interface for creating new instances. 38 | * 39 | * @param serial Device serial number. Cannot be left blank. 40 | * 41 | * @param channel_mode Channel and mode selection A(1), B(2), (A+B)MIMO(3). 42 | * 43 | * @param filename Path to file if file switch is turned on. 44 | * 45 | * @param length_tag_name Name of stream burst length tag 46 | * 47 | * @return a new limesdr sink block object 48 | */ 49 | static sptr make(std::string serial, 50 | int channel_mode, 51 | const std::string& filename, 52 | const std::string& length_tag_name); 53 | /** 54 | * Set center frequency 55 | * 56 | * @param freq Frequency to set in Hz 57 | * 58 | * @param chan Channel (not used) 59 | * 60 | * @return actual center frequency 61 | */ 62 | virtual double set_center_freq(double freq, size_t chan = 0) = 0; 63 | 64 | /** 65 | * Set which antenna is used 66 | * 67 | * @note setting antenna to BAND1 or BAND2 will enable PA path and because of that Lime boards 68 | * will transmit CW signal, even when stream is stopped. 69 | * 70 | * @param antenna Antenna to set: None(0), BAND1(1), BAND(2), NONE(3), AUTO(255) 71 | * 72 | * @param channel Channel selection: A(LMS_CH_0),B(LMS_CH_1). 73 | */ 74 | virtual void set_antenna(int antenna, int channel = 0) = 0; 75 | /** 76 | * Set NCO (numerically controlled oscillator). 77 | * By selecting NCO frequency 78 | * configure NCO. When NCO frequency is 0, NCO is off. 79 | * 80 | * @param nco_freq NCO frequency in Hz. 81 | * 82 | * @param channel Channel index. 83 | */ 84 | virtual void set_nco(float nco_freq, int channel) = 0; 85 | /** 86 | * Set analog filters. 87 | * 88 | * @param analog_bandw Channel filter bandwidth in Hz. 89 | * 90 | * @param channel Channel selection: A(LMS_CH_0),B(LMS_CH_1). 91 | * 92 | * @return actual filter bandwidth in Hz 93 | */ 94 | virtual double set_bandwidth(double analog_bandw, int channel = 0) = 0; 95 | /** 96 | * Set digital filters (GFIR). 97 | * 98 | * @param digital_bandw Channel filter bandwidth in Hz. 99 | * 100 | * @param channel Channel selection: A(LMS_CH_0),B(LMS_CH_1). 101 | */ 102 | virtual void set_digital_filter(double digital_bandw, int channel) = 0; 103 | /** 104 | * Set the combined gain value in dB 105 | * 106 | * @note actual gain depends on LO frequency and analog LPF configuration and 107 | * resulting output signal level may be different when those values are changed 108 | * 109 | * @param gain_dB Desired gain: [0,73] dB 110 | * 111 | * @param channel Channel selection: A(LMS_CH_0),B(LMS_CH_1). 112 | * 113 | * @return actual gain in dB 114 | */ 115 | virtual unsigned set_gain(unsigned gain_dB, int channel = 0) = 0; 116 | /** 117 | * Set the same sample rate for both channels. 118 | * 119 | * @param rate Sample rate in S/s. 120 | * 121 | * @return actual sample rate in S/s 122 | */ 123 | virtual double set_sample_rate(double rate) = 0; 124 | /** 125 | * Set oversampling for both channels. 126 | * 127 | * @param oversample Oversampling value (0 (default),1,2,4,8,16,32). 128 | */ 129 | virtual void set_oversampling(int oversample) = 0; 130 | /** 131 | * Perform device calibration. 132 | * 133 | * @param bandw Set calibration bandwidth in Hz. 134 | * 135 | * @param channel Channel selection: A(LMS_CH_0),B(LMS_CH_1). 136 | */ 137 | virtual void calibrate(double bandw, int channel = 0) = 0; 138 | /** 139 | * Set stream buffer size 140 | * 141 | * @param size FIFO buffer size in samples 142 | */ 143 | virtual void set_buffer_size(uint32_t size) = 0; 144 | /** 145 | * Set TCXO DAC. 146 | * @note Care must be taken as this parameter is returned to default value only after power off. 147 | * @note LimeSDR-Mini default value is 180 range is [0,255] 148 | * LimeSDR-USB default value is 125 range is [0,255] 149 | * LimeSDR-PCIe default value is 134 range is [0,255] 150 | * LimeNET-Micro default value is 30714 range is [0,65535] 151 | * 152 | * @param dacVal DAC value (0-65535) 153 | */ 154 | virtual void set_tcxo_dac(uint16_t dacVal = 125 ) = 0; 155 | }; 156 | } // namespace limesdr 157 | } // namespace gr 158 | 159 | #endif 160 | -------------------------------------------------------------------------------- /include/limesdr/source.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2018 Lime Microsystems info@limemicro.com 4 | * 5 | * GNU Radio is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * GNU Radio is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifndef INCLUDED_LIMESDR_SOURCE_H 22 | #define INCLUDED_LIMESDR_SOURCE_H 23 | 24 | #include 25 | #include 26 | 27 | namespace gr { 28 | namespace limesdr { 29 | class LIMESDR_API source : virtual public gr::block { 30 | public: 31 | typedef boost::shared_ptr sptr; 32 | 33 | /*! 34 | * @brief Return a shared_ptr to a new instance of source. 35 | * 36 | * To avoid accidental use of raw pointers, source's 37 | * constructor is private. limesdr::source::make is the public 38 | * interface for creating new instances. 39 | * 40 | * @param serial Device serial number. Cannot be left blank. 41 | * 42 | * @param channel_mode Channel and mode selection A(1), B(2), (A+B)MIMO(3). 43 | * 44 | * @param filename Path to file if file switch is turned on. 45 | * 46 | * @return a new limesdr source block object 47 | */ 48 | static sptr make(std::string serial, int channel_mode, const std::string& filename); 49 | 50 | /** 51 | * Set center frequency 52 | * 53 | * @param freq Frequency to set in Hz 54 | * 55 | * @param chan Channel (not used) 56 | * 57 | * @return actual center frequency in Hz 58 | */ 59 | virtual double set_center_freq(double freq, size_t chan = 0) = 0; 60 | 61 | /** 62 | * Set which antenna is used 63 | * 64 | * @param antenna Antenna to set: None(0), LNAH(1), LNAL(2), LNAW(3), AUTO(255) 65 | * 66 | * @param channel Channel selection: A(LMS_CH_0),B(LMS_CH_1). 67 | */ 68 | virtual void set_antenna(int antenna, int channel = 0) = 0; 69 | /** 70 | * Set NCO (numerically controlled oscillator). 71 | * By selecting NCO frequency 72 | * configure NCO. When NCO frequency is 0, NCO is off. 73 | * 74 | * @param nco_freq NCO frequency in Hz. 75 | * 76 | * @param channel Channel index. 77 | */ 78 | virtual void set_nco(float nco_freq, int channel) = 0; 79 | /** 80 | * Set analog filters. 81 | * 82 | * @param analog_bandw Channel filter bandwidth in Hz. 83 | * 84 | * @param channel Channel selection: A(LMS_CH_0),B(LMS_CH_1). 85 | * 86 | * @return actual filter bandwidth in Hz 87 | */ 88 | virtual double set_bandwidth(double analog_bandw, int channel = 0) = 0; 89 | /** 90 | * Set digital filters (GFIR). 91 | * 92 | * @param digital_bandw Channel filter bandwidth in Hz. 93 | * 94 | * @param channel Channel selection: A(LMS_CH_0),B(LMS_CH_1). 95 | */ 96 | virtual void set_digital_filter(double digital_bandw, int channel) = 0; 97 | /** 98 | * Set the combined gain value in dB 99 | * 100 | * @note actual gain depends on LO frequency and analog LPF configuration and 101 | * resulting output signal level may be different when those values are changed 102 | * 103 | * @param gain_dB Desired gain: [0,73] dB 104 | * 105 | * @param channel Channel selection: A(LMS_CH_0),B(LMS_CH_1). 106 | * 107 | * @return actual gain in dB 108 | */ 109 | virtual unsigned set_gain(unsigned gain_dB, int channel = 0) = 0; 110 | /** 111 | * Set the same sample rate for both channels. 112 | * 113 | * @param rate Sample rate in S/s. 114 | * 115 | * @return actual sample rate in S/s 116 | */ 117 | virtual double set_sample_rate(double rate) = 0; 118 | /** 119 | * Set oversampling for both channels. 120 | * 121 | * @param oversample Oversampling value (0 (default),1,2,4,8,16,32). 122 | */ 123 | virtual void set_oversampling(int oversample) = 0; 124 | /** 125 | * Perform device calibration. 126 | * 127 | * @param bandw Set calibration bandwidth in Hz. 128 | * 129 | * @param channel Channel selection: A(LMS_CH_0),B(LMS_CH_1). 130 | */ 131 | virtual void calibrate(double bandw, int channel = 0) = 0; 132 | /** 133 | * Set stream buffer size 134 | * 135 | * @param size FIFO buffer size in samples 136 | */ 137 | virtual void set_buffer_size(uint32_t size) = 0; 138 | /** 139 | * Set TCXO DAC. 140 | * @note Care must be taken as this parameter is returned to default value only after power off. 141 | * @note LimeSDR-Mini default value is 180 range is [0,255] 142 | * LimeSDR-USB default value is 125 range is [0,255] 143 | * LimeSDR-PCIe default value is 134 range is [0,255] 144 | * LimeNET-Micro default value is 30714 range is [0,65535] 145 | * 146 | * @param dacVal DAC value (0-65535) 147 | */ 148 | virtual void set_tcxo_dac(uint16_t dacVal = 125 ) = 0; 149 | }; 150 | } // namespace limesdr 151 | } // namespace gr 152 | 153 | #endif 154 | -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ######################################################################## 21 | # Setup library 22 | ######################################################################## 23 | include(GrPlatform) #define LIB_SUFFIX 24 | 25 | include_directories(${Boost_INCLUDE_DIR} 26 | ${LIMESUITE_INCLUDE_DIRS} 27 | ${CMAKE_CURRENT_BINARY_DIR}) 28 | link_directories(${Boost_LIBRARY_DIRS} 29 | ${LIMESDR_PKG_LIBRARY_DIRS}) 30 | 31 | list(APPEND limesdr_sources 32 | source_impl.cc 33 | sink_impl.cc 34 | common/device_handler.cc 35 | ) 36 | 37 | if(ENABLE_RFE) 38 | list(APPEND limesdr_sources 39 | rfe_impl.cc 40 | ) 41 | endif() 42 | 43 | set(limesdr_sources "${limesdr_sources}" PARENT_SCOPE) 44 | if(NOT limesdr_sources) 45 | MESSAGE(STATUS "No C++ sources... skipping lib/") 46 | return() 47 | endif(NOT limesdr_sources) 48 | 49 | add_library(gnuradio-limesdr SHARED ${limesdr_sources}) 50 | target_link_libraries( 51 | gnuradio-limesdr 52 | ${Boost_LIBRARIES} 53 | ${GNURADIO_ALL_LIBRARIES} 54 | ${LIMESUITE_LIB}) 55 | 56 | set_target_properties( 57 | gnuradio-limesdr PROPERTIES DEFINE_SYMBOL "gnuradio_limesdr_EXPORTS") 58 | 59 | if(APPLE) 60 | set_target_properties( 61 | gnuradio-limesdr PROPERTIES 62 | INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib") 63 | endif(APPLE) 64 | 65 | ######################################################################## 66 | # Install built library files 67 | ######################################################################## 68 | install(TARGETS gnuradio-limesdr 69 | LIBRARY DESTINATION lib${LIB_SUFFIX} # .so/.dylib file 70 | ARCHIVE DESTINATION lib${LIB_SUFFIX} # .lib file 71 | RUNTIME DESTINATION bin # .dll file 72 | ) 73 | -------------------------------------------------------------------------------- /lib/common/device_handler.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2018 Lime Microsystems info@limemicro.com 4 | * 5 | * GNU Radio is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * GNU Radio is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifndef DEVICE_HANDLER_H 22 | #define DEVICE_HANDLER_H 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #define LMS_CH_0 0 35 | #define LMS_CH_1 1 36 | 37 | #define LimeSDR_Mini 1 38 | #define LimeNET_Micro 2 39 | #define LimeSDR_USB 3 40 | 41 | #define GR_LIMESDR_VER "2.2.7" 42 | 43 | class device_handler { 44 | private: 45 | int open_devices = 0; 46 | // Read device list once flag 47 | bool list_read = false; 48 | // Calculate open devices to close them all on close_all_devices 49 | int device_count; 50 | 51 | struct device { 52 | // Device address 53 | lms_device_t* address = NULL; 54 | 55 | // Flags and variables used to check 56 | // shared settings and blocks usage 57 | bool source_flag = false; 58 | bool sink_flag = false; 59 | int source_channel_mode = -1; 60 | int sink_channel_mode = -1; 61 | std::string source_filename; 62 | std::string sink_filename; 63 | }; 64 | 65 | struct rfe_device 66 | { 67 | int rx_channel = 0; 68 | int tx_channel = 0; 69 | rfe_dev_t* rfe_dev = nullptr; 70 | }rfe_device; 71 | // Device list 72 | lms_info_str_t* list = new lms_info_str_t[20]; 73 | // Device vector. Adds devices from the list 74 | std::vector device_vector; 75 | // Run close_all_devices once with this flag 76 | bool close_flag = false; 77 | 78 | device_handler(){}; 79 | device_handler(device_handler const&); 80 | void operator=(device_handler const&); 81 | 82 | 83 | public: 84 | static device_handler& getInstance() { 85 | static device_handler instance; 86 | return instance; 87 | } 88 | ~device_handler(); 89 | 90 | mutable std::recursive_mutex block_mutex; 91 | 92 | 93 | /** 94 | * Print device error and close all devices. 95 | * 96 | * @param device_number Device number from the list of LMS_GetDeviceList. 97 | */ 98 | void error(int device_number); 99 | 100 | /** 101 | * Get device connection handler in order to configure it. 102 | * 103 | * @param device_number Device number from the list of LMS_GetDeviceList. 104 | */ 105 | lms_device_t* get_device(int device_number); 106 | 107 | /** 108 | * Connect to the device and create singletone. 109 | * 110 | * @param serial Device serial from the list of LMS_GetDeviceList. 111 | */ 112 | int open_device(std::string& serial); 113 | 114 | /** 115 | * Disconnect from the device. 116 | * 117 | * @param device_number Device number from the list of LMS_GetDeviceList. 118 | * 119 | * @param block_type Source block(1), Sink block(2). 120 | */ 121 | void close_device(int device_number, int block_type); 122 | 123 | /** 124 | * Disconnect from all devices. 125 | */ 126 | void close_all_devices(); 127 | 128 | /** 129 | * Check what blocks are used for single device. 130 | * 131 | * @param device_number Device number from the list of LMS_GetDeviceList. 132 | * 133 | * @param block_type Source block(1), Sink block(2). 134 | * 135 | * @param channel_mode Channel A(0), Channel B(1), MIMO(2) 136 | * 137 | * @param filename Path to file if file switch is turned on. 138 | */ 139 | void 140 | check_blocks(int device_number, int block_type, int channel_mode, const std::string& filename); 141 | 142 | /** 143 | * Load settings from .ini file. 144 | * 145 | * @param device_number Device number from the list of LMS_GetDeviceList. 146 | * 147 | * @param filename Path to file if file switch is turned on. 148 | * 149 | * @param antenna_tx Pointer to TX antenna, so PA path would be updated in sink block 150 | */ 151 | void settings_from_file(int device_number, const std::string& filename, int* antenna_tx); 152 | 153 | /** 154 | * Set used channels 155 | * 156 | * @param device_number Device number from the list of LMS_GetDeviceList. 157 | * 158 | * @param channel_mode Channel A(0), Channel B(1), MIMO(2) 159 | * 160 | * @param direction Direction of samples RX(LMS_CH_RX), TX(LMS_CH_RX). 161 | */ 162 | void enable_channels(int device_number, int channel_mode, bool direction); 163 | 164 | /** 165 | * Set the same sample rate for both channels. 166 | * 167 | * @param device_number Device number from the list of LMS_GetDeviceList. 168 | * 169 | * @param rate Sample rate in S/s. 170 | */ 171 | void set_samp_rate(int device_number, double& rate); 172 | 173 | /** 174 | * Set oversampling value for both channels 175 | * 176 | * @param device_number Device number from the list of LMS_GetDeviceList. 177 | * 178 | * @param oversample Oversampling value (0 (default),1,2,4,8,16,32). 179 | */ 180 | void set_oversampling(int device_number, int oversample); 181 | 182 | /** 183 | * Set RF frequency of both channels (RX and TX separately). 184 | * 185 | * @param device_number Device number from the list of LMS_GetDeviceList. 186 | * 187 | * @param direction Direction of samples RX(LMS_CH_RX), TX(LMS_CH_TX). 188 | * 189 | * @param channel selection: A(LMS_CH_0),B(LMS_CH_1). 190 | * 191 | * @param rf_freq RF frequency in Hz. 192 | * 193 | * @return returns RF frequency in Hz 194 | */ 195 | double set_rf_freq(int device_number, bool direction, int channel, float rf_freq); 196 | 197 | /** 198 | * Perform device calibration. 199 | * 200 | * @param device_number Device number from the list of LMS_GetDeviceList. 201 | * 202 | * @param direction Direction of samples: RX(LMS_CH_RX),TX(LMS_CH_RX). 203 | * 204 | * @param channel Channel selection: A(LMS_CH_0),B(LMS_CH_1). 205 | * 206 | * @param bandwidth Set calibration bandwidth in Hz. 207 | * 208 | */ 209 | void calibrate(int device_number, int direction, int channel, double bandwidth); 210 | 211 | /** 212 | * Set which antenna is used 213 | * 214 | * @param device_number Device number from the list of LMS_GetDeviceList. 215 | * 216 | * @param channel Channel selection: A(LMS_CH_0),B(LMS_CH_1). 217 | * 218 | * @param direction Direction of samples: RX(LMS_CH_RX),TX(LMS_CH_RX). 219 | * 220 | * @param antenna Antenna to set: None(0), LNAH(1), LNAL(2), LNAW(3) for RX 221 | * None(0), BAND1(1), BAND(2), NONE(3) for TX 222 | * 223 | */ 224 | void set_antenna(int device_number, int channel, int direction, int antenna); 225 | 226 | /** 227 | * Set analog filters. 228 | * 229 | * @param device_number Device number from the list of LMS_GetDeviceList. 230 | * 231 | * @param direction Direction of samples: RX(LMS_CH_RX),TX(LMS_CH_TX). 232 | * 233 | * @param channel Channel selection: A(LMS_CH_0),B(LMS_CH_1). 234 | * 235 | * @param analog_bandw Channel filter bandwidth in Hz. 236 | */ 237 | double set_analog_filter(int device_number, bool direction, int channel, double analog_bandw); 238 | 239 | /** 240 | * Set digital filters (GFIR). 241 | * 242 | * @param device_number Device number from the list of LMS_GetDeviceList. 243 | * 244 | * @param direction Direction of samples: RX(LMS_CH_RX),TX(LMS_CH_TX). 245 | * 246 | * @param channel Channel selection: A(LMS_CH_0),B(LMS_CH_1). 247 | * 248 | * @param digital_bandw Channel filter bandwidth in Hz. 249 | */ 250 | double set_digital_filter(int device_number, bool direction, int channel, double digital_bandw); 251 | 252 | /** 253 | * Set the combined gain value in dB 254 | * This function computes and sets the optimal gain values of various amplifiers 255 | * that are present in the device based on desired gain value in dB. 256 | * 257 | * @note actual gain depends on LO frequency and analog LPF configuration and 258 | * resulting output signal level may be different when those values are changed 259 | * 260 | * @param device_number Device number from the list of LMS_GetDeviceList. 261 | * 262 | * @param direction Select RX or TX. 263 | * 264 | * @param channel Channel selection: A(LMS_CH_0),B(LMS_CH_1). 265 | * 266 | * @param gain_dB Desired gain: [0,73] dB 267 | */ 268 | unsigned set_gain(int device_number, bool direction, int channel, unsigned gain_dB); 269 | 270 | /** 271 | * Set NCO (numerically controlled oscillator). 272 | * By selecting NCO frequency 273 | * configure NCO. When NCO frequency is 0, NCO is off. 274 | * 275 | * @param device_number Device number from the list of LMS_GetDeviceList. 276 | * 277 | * @param direction Select RX or TX. 278 | * 279 | * @param channel Channel index. 280 | * 281 | * @param nco_freq NCO frequency in Hz. 282 | */ 283 | void set_nco(int device_number, bool direction, int channel, float nco_freq); 284 | 285 | void disable_DC_corrections(int device_number); 286 | 287 | /** 288 | * Set TCXO DAC. 289 | * @note Care must be taken as this parameter is returned to default value only after power off. 290 | * @note LimeSDR-Mini default value is 180 range is [0,255] 291 | * LimeSDR-USB default value is 125 range is [0,255] 292 | * LimeSDR-PCIe default value is 134 range is [0,255] 293 | * LimeNET-Micro default value is 30714 range is [0,65535] 294 | * 295 | * @param device_number Device number from the list of LMS_GetDeviceList. 296 | * 297 | * @param dacVal DAC value (0-65535) 298 | */ 299 | void set_tcxo_dac(int device_number, uint16_t dacVal); 300 | /** 301 | * Sets up LimeRFE device pointer so that automatic channel configuration could be made 302 | * @param rfe_dev Pointer to LimeRFE device descriptor 303 | */ 304 | void set_rfe_device(rfe_dev_t* rfe_dev); 305 | /** 306 | * Assigns configured LimeSDR channels to LimeRFE for automatic channel switching 307 | */ 308 | void update_rfe_channels(); 309 | 310 | }; 311 | 312 | 313 | #endif 314 | -------------------------------------------------------------------------------- /lib/rfe_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2020 Lime Microsystems. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include "common/device_handler.h" 26 | #include 27 | 28 | namespace gr { 29 | namespace limesdr { 30 | rfe::rfe(int comm_type, 31 | std::string device, 32 | std::string config_file, 33 | char IDRX, 34 | char IDTX, 35 | char PortRX, 36 | char PortTX, 37 | char Mode, 38 | char Notch, 39 | char Atten) 40 | { 41 | std::cout << "---------------------------------------------------------------" 42 | << std::endl; 43 | std::cout << "LimeSuite RFE info" << std::endl; 44 | std::cout << std::endl; 45 | 46 | boardState.channelIDRX = IDRX; 47 | boardState.channelIDTX = IDTX; 48 | boardState.selPortRX = PortRX; 49 | boardState.selPortTX = PortTX; 50 | boardState.mode = Mode; 51 | boardState.notchOnOff = Notch; 52 | boardState.attValue = Atten; 53 | 54 | if (comm_type) // SDR GPIO communication 55 | { 56 | sdr_device_num = device_handler::getInstance().open_device(device); 57 | 58 | std::cout << "LimeRFE: Opening through GPIO communication" << std::endl; 59 | rfe_dev = 60 | RFE_Open(nullptr, device_handler::getInstance().get_device(sdr_device_num)); 61 | if (!rfe_dev) { 62 | std::cout << "LimeRFE: Failed to open device, exiting" << std::endl; 63 | exit(0); 64 | } 65 | 66 | // No need to set up this if it isn't automatic 67 | if (boardState.channelIDRX == RFE_CID_AUTO || 68 | boardState.channelIDTX == RFE_CID_AUTO) { 69 | device_handler::getInstance().set_rfe_device(rfe_dev); 70 | 71 | // Update the channels since the SDR could already be set up and working 72 | device_handler::getInstance().update_rfe_channels(); 73 | } 74 | } else // Direct USB 75 | { 76 | // Not using device handler so print the version 77 | std::cout << "##################" << std::endl; 78 | std::cout << "LimeSuite version: " << LMS_GetLibraryVersion() << std::endl; 79 | std::cout << "gr-limesdr version: " << GR_LIMESDR_VER << std::endl; 80 | std::cout << "##################" << std::endl; 81 | 82 | std::cout << "LimeRFE: Opening " << device << std::endl; 83 | rfe_dev = RFE_Open(device.c_str(), nullptr); 84 | if (!rfe_dev) { 85 | std::cout << "LimeRFE: Failed to open device, exiting" << std::endl; 86 | exit(0); 87 | } 88 | } 89 | 90 | int error = 0; 91 | unsigned char info[4] = { 0 }; 92 | if ((error = RFE_GetInfo(rfe_dev, info)) != 0) { 93 | std::cout << "LimeRFE: Failed to get device info: "; 94 | print_error(error); 95 | exit(0); 96 | } 97 | std::cout << "LimeRFE: FW: " << (int)info[0] << " HW: " << (int)info[1] << std::endl; 98 | 99 | if (config_file.empty()) { 100 | if ((error = RFE_ConfigureState(rfe_dev, boardState)) != 0) { 101 | std::cout << "LimeRFE: Failed to configure device: "; 102 | print_error(error); 103 | exit(0); 104 | } 105 | } else { 106 | std::cout << "LimeRFE: Loading configuration file" << std::endl; 107 | if ((error = RFE_LoadConfig(rfe_dev, config_file.c_str())) != 0) { 108 | std::cout << "LimeRFE: Failed to load configuration file: "; 109 | print_error(error); 110 | exit(0); 111 | } 112 | } 113 | std::cout << "LimeRFE: Board state: " << std::endl; 114 | get_board_state(); 115 | std::cout << "---------------------------------------------------------------" 116 | << std::endl; 117 | } 118 | 119 | rfe::~rfe() 120 | { 121 | std::cout << "LimeRFE: closing" << std::endl; 122 | if (rfe_dev) { 123 | RFE_Reset(rfe_dev); 124 | RFE_Close(rfe_dev); 125 | } 126 | } 127 | 128 | int rfe::change_mode(int mode) 129 | { 130 | if (rfe_dev) { 131 | if (mode == RFE_MODE_TXRX) { 132 | if (boardState.selPortRX == boardState.selPortTX && 133 | boardState.channelIDRX < RFE_CID_CELL_BAND01) { 134 | std::cout 135 | << "LimeRFE: mode cannot be set to RX+TX when same port is selected" 136 | << std::endl; 137 | return -1; 138 | } 139 | } 140 | int error = 0; 141 | if (mode > 3 || mode < 0) 142 | std::cout << "LimeRFE: invalid mode" << std::endl; 143 | std::string mode_str[4] = { "RX", "TX", "NONE", "RX+TX" }; 144 | std::cout << "LimeRFE: changing mode to " << mode_str[mode] << std::endl; 145 | if ((error = RFE_Mode(rfe_dev, mode)) != 0) { 146 | std::cout << "LimeRFE: failed to change mode:"; 147 | print_error(error); 148 | } 149 | boardState.mode = mode; 150 | return error; 151 | } 152 | std::cout << "LimeRFE: no RFE device opened" << std::endl; 153 | return -1; 154 | } 155 | 156 | int rfe::set_fan(int enable) 157 | { 158 | if (rfe_dev) { 159 | std::string enable_str[2] = { "disabling", "enabling" }; 160 | std::cout << "LimeRFE: " << enable_str[enable] << " fan" << std::endl; 161 | int error = 0; 162 | if ((error = RFE_Fan(rfe_dev, enable)) != 0) { 163 | std::cout << "LimeRFE: failed to change mode:"; 164 | print_error(error); 165 | } 166 | return error; 167 | } 168 | std::cout << "LimeRFE: no RFE device opened" << std::endl; 169 | return -1; 170 | } 171 | 172 | int rfe::set_attenuation(int attenuation) 173 | { 174 | if (rfe_dev) { 175 | int error = 0; 176 | if (attenuation > 7) { 177 | std::cout << "LimeRFE: attenuation value too high, valid range [0, 7]" 178 | << std::endl; 179 | return -1; 180 | } 181 | std::cout << "LimeRFE: changing attenuation value to: " << attenuation 182 | << std::endl; 183 | ; 184 | 185 | boardState.attValue = attenuation; 186 | if ((error = RFE_ConfigureState(rfe_dev, boardState)) != 0) { 187 | std::cout << "LimeRFE: failed to change attenuation: "; 188 | print_error(error); 189 | } 190 | return error; 191 | } 192 | std::cout << "LimeRFE: no RFE device opened" << std::endl; 193 | return -1; 194 | } 195 | 196 | int rfe::set_notch(int enable) 197 | { 198 | if (rfe_dev) { 199 | if (boardState.channelIDRX > RFE_CID_HAM_0920 || 200 | boardState.channelIDRX == RFE_CID_WB_4000) { 201 | std::cout << "LimeRFE: notch filter cannot be se for this RX channel" 202 | << std::endl; 203 | return -1; 204 | } 205 | int error = 0; //! TODO: might need renaming 206 | boardState.notchOnOff = enable; 207 | std::string en_dis[2] = { "disabling", "enabling" }; 208 | std::cout << "LimeRFE: " << en_dis[enable] << " notch filter" << std::endl; 209 | if ((error = RFE_ConfigureState(rfe_dev, boardState)) != 0) { 210 | std::cout << "LimeRFE: failed to change change attenuation: "; 211 | print_error(error); 212 | } 213 | return error; 214 | } 215 | return -1; 216 | } 217 | void rfe::print_error(int error) 218 | { 219 | switch (error) { 220 | case -4: 221 | std::cout << "error synchronizing communication" << std::endl; 222 | break; 223 | case -3: 224 | std::cout 225 | << "non-configurable GPIO pin specified. Only pins 4 and 5 are configurable." 226 | << std::endl; 227 | break; 228 | case -2: 229 | std::cout << "couldn't read the .ini configuration file" << std::endl; 230 | break; 231 | case -1: 232 | std::cout << "communication error" << std::endl; 233 | break; 234 | case 1: 235 | std::cout << "wrong TX port - not possible to route selected TX channel" 236 | << std::endl; 237 | break; 238 | case 2: 239 | std::cout << "wrong RX port - not possible to route selected RX channel" 240 | << std::endl; 241 | break; 242 | case 3: 243 | std::cout << "TX+RX mode cannot be used when same TX and RX port is used" 244 | << std::endl; 245 | break; 246 | case 4: 247 | std::cout << "wrong mode for the cellular channel" << std::endl; 248 | break; 249 | case 5: 250 | std::cout << "cellular channels must be the same both for RX and TX" << std::endl; 251 | break; 252 | case 6: 253 | std::cout << "requested channel code is wrong" << std::endl; 254 | break; 255 | default: 256 | std::cout << "error code doesn't match" << std::endl; 257 | break; 258 | } 259 | } 260 | 261 | } // namespace limesdr 262 | } // namespace gr 263 | -------------------------------------------------------------------------------- /lib/sink_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2018 Lime Microsystems info@limemicro.com 4 | * 5 | * GNU Radio is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * GNU Radio is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifndef INCLUDED_LIMESDR_SINK_IMPL_H 22 | #define INCLUDED_LIMESDR_SINK_IMPL_H 23 | 24 | #include "common/device_handler.h" 25 | #include 26 | 27 | 28 | static const pmt::pmt_t TIME_TAG = pmt::string_to_symbol("tx_time"); 29 | 30 | namespace gr { 31 | namespace limesdr { 32 | class sink_impl : public sink { 33 | private: 34 | lms_stream_t streamId[2]; 35 | 36 | bool stream_analyzer = false; 37 | 38 | int sink_block = 2; 39 | 40 | pmt::pmt_t LENGTH_TAG; 41 | lms_stream_meta_t tx_meta; 42 | long burst_length = 0; 43 | int nitems_send = 0; 44 | int ret[2] = {0}; 45 | int pa_path[2] = {0}; // TX PA path NONE 46 | 47 | struct constant_data { 48 | std::string serial; 49 | int device_number; 50 | int channel_mode; 51 | double samp_rate = 10e6; 52 | uint32_t FIFO_size = 0; 53 | } stored; 54 | 55 | std::chrono::high_resolution_clock::time_point t1, t2; 56 | 57 | void work_tags(int noutput_items); 58 | 59 | void print_stream_stats(int channel); 60 | 61 | public: 62 | sink_impl(std::string serial, 63 | int channel_mode, 64 | const std::string& filename, 65 | const std::string& length_tag_name); 66 | ~sink_impl(); 67 | 68 | int general_work(int noutput_items, 69 | gr_vector_int& ninput_items, 70 | gr_vector_const_void_star& input_items, 71 | gr_vector_void_star& output_items); 72 | 73 | bool start(void); 74 | 75 | bool stop(void); 76 | 77 | inline gr::io_signature::sptr args_to_io_signature(int channel_number); 78 | 79 | void init_stream(int device_number, int channel); 80 | void release_stream(int device_number, lms_stream_t* stream); 81 | 82 | double set_center_freq(double freq, size_t chan = 0); 83 | 84 | void set_antenna(int antenna, int channel = 0); 85 | void toggle_pa_path(int device_number, bool enable); 86 | 87 | void set_nco(float nco_freq, int channel = 0); 88 | 89 | double set_bandwidth(double analog_bandw, int channel = 0); 90 | 91 | void set_digital_filter(double digital_bandw, int channel = 0); 92 | 93 | unsigned set_gain(unsigned gain_dB, int channel = 0); 94 | 95 | double set_sample_rate(double rate); 96 | 97 | void set_oversampling(int oversample); 98 | 99 | void set_buffer_size(uint32_t size); 100 | 101 | void calibrate(double bandw, int channel = 0); 102 | 103 | void set_tcxo_dac(uint16_t dacVal = 125); 104 | }; 105 | } // namespace limesdr 106 | } // namespace gr 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /lib/source_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2018 Lime Microsystems info@limemicro.com 4 | * 5 | * GNU Radio is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * GNU Radio is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include "source_impl.h" 26 | #include 27 | 28 | namespace gr { 29 | namespace limesdr { 30 | source::sptr source::make(std::string serial, int channel_mode, const std::string& filename) { 31 | return gnuradio::get_initial_sptr(new source_impl(serial, channel_mode, filename)); 32 | } 33 | 34 | source_impl::source_impl(std::string serial, int channel_mode, const std::string& filename) 35 | : gr::block("source", 36 | gr::io_signature::make( 37 | 0, 0, 0), // Based on channel_mode SISO/MIMO use appropriate output signature 38 | args_to_io_signature(channel_mode)) { 39 | std::cout << "---------------------------------------------------------------" << std::endl; 40 | std::cout << "LimeSuite Source (RX) info" << std::endl; 41 | std::cout << std::endl; 42 | 43 | // 1. Store private variables upon implementation to protect from changing them later 44 | stored.serial = serial; 45 | stored.channel_mode = channel_mode; 46 | 47 | if (stored.channel_mode < 0 && stored.channel_mode > 2) { 48 | std::cout 49 | << "ERROR: source_impl::source_impl(): Channel must be A(0), B(1) or (A+B) MIMO(2)" 50 | << std::endl; 51 | exit(0); 52 | } 53 | 54 | // 2. Open device if not opened 55 | stored.device_number = device_handler::getInstance().open_device(stored.serial); 56 | // 3. Check where to load settings from (file or block) 57 | if (!filename.empty()) { 58 | device_handler::getInstance().settings_from_file(stored.device_number, filename, nullptr); 59 | device_handler::getInstance().check_blocks( 60 | stored.device_number, source_block, stored.channel_mode, filename); 61 | } else { 62 | // 4. Check how many blocks were used and check values between blocks 63 | device_handler::getInstance().check_blocks( 64 | stored.device_number, source_block, stored.channel_mode, ""); 65 | 66 | // 5. Enable required channel/s 67 | device_handler::getInstance().enable_channels( 68 | stored.device_number, stored.channel_mode, LMS_CH_RX); 69 | } 70 | } 71 | 72 | source_impl::~source_impl() { 73 | // Stop and destroy stream for channel 0 (if channel_mode is SISO) 74 | if (stored.channel_mode < 2) { 75 | this->release_stream(stored.device_number, &streamId[stored.channel_mode]); 76 | } 77 | // Stop and destroy stream for channels 0 & 1 (if channel_mode is MIMO) 78 | else if (stored.channel_mode == 2) { 79 | this->release_stream(stored.device_number, &streamId[LMS_CH_0]); 80 | this->release_stream(stored.device_number, &streamId[LMS_CH_1]); 81 | } 82 | device_handler::getInstance().close_device(stored.device_number, source_block); 83 | } 84 | 85 | bool source_impl::start(void) { 86 | std::unique_lock lock(device_handler::getInstance().block_mutex); 87 | // Initialize and start stream for channel 0 (if channel_mode is SISO) 88 | if (stored.channel_mode < 2) // If SISO configure prefered channel 89 | { 90 | this->init_stream(stored.device_number, stored.channel_mode); 91 | if (LMS_StartStream(&streamId[stored.channel_mode]) != LMS_SUCCESS) 92 | device_handler::getInstance().error(stored.device_number); 93 | } 94 | 95 | // Initialize and start stream for channels 0 & 1 (if channel_mode is MIMO) 96 | else if (stored.channel_mode == 2) { 97 | 98 | this->init_stream(stored.device_number, LMS_CH_0); 99 | this->init_stream(stored.device_number, LMS_CH_1); 100 | 101 | if (LMS_StartStream(&streamId[LMS_CH_0]) != LMS_SUCCESS) 102 | device_handler::getInstance().error(stored.device_number); 103 | if (LMS_StartStream(&streamId[LMS_CH_1]) != LMS_SUCCESS) 104 | device_handler::getInstance().error(stored.device_number); 105 | } 106 | std::unique_lock unlock(device_handler::getInstance().block_mutex); 107 | 108 | if (stream_analyzer) { 109 | t1 = std::chrono::high_resolution_clock::now(); 110 | t2 = t1; 111 | } 112 | 113 | add_tag = true; 114 | 115 | return true; 116 | } 117 | 118 | bool source_impl::stop(void) { 119 | std::unique_lock lock(device_handler::getInstance().block_mutex); 120 | // Stop stream for channel 0 (if channel_mode is SISO) 121 | if (stored.channel_mode < 2) { 122 | this->release_stream(stored.device_number, &streamId[stored.channel_mode]); 123 | } 124 | // Stop streams for channels 0 & 1 (if channel_mode is MIMO) 125 | else if (stored.channel_mode == 2) { 126 | this->release_stream(stored.device_number, &streamId[LMS_CH_0]); 127 | this->release_stream(stored.device_number, &streamId[LMS_CH_1]); 128 | } 129 | std::unique_lock unlock(device_handler::getInstance().block_mutex); 130 | return true; 131 | } 132 | 133 | int source_impl::general_work(int noutput_items, 134 | gr_vector_int& ninput_items, 135 | gr_vector_const_void_star& input_items, 136 | gr_vector_void_star& output_items) { 137 | // Receive stream for channel 0 (if channel_mode is SISO) 138 | if (stored.channel_mode < 2) { 139 | lms_stream_status_t status; 140 | lms_stream_meta_t rx_metadata; 141 | 142 | int ret0 = LMS_RecvStream( 143 | &streamId[stored.channel_mode], output_items[0], noutput_items, &rx_metadata, 100); 144 | if (ret0 < 0) { 145 | return 0; 146 | } 147 | 148 | LMS_GetStreamStatus(&streamId[stored.channel_mode], &status); 149 | 150 | if (add_tag || status.droppedPackets > 0) { 151 | pktLoss += status.droppedPackets; 152 | add_tag = false; 153 | this->add_time_tag(0, rx_metadata); 154 | } 155 | // Print stream stats to debug 156 | if (stream_analyzer == true) { 157 | this->print_stream_stats(status); 158 | } 159 | 160 | produce(0, ret0); 161 | return WORK_CALLED_PRODUCE; 162 | } 163 | // Receive stream for channels 0 & 1 (if channel_mode is MIMO) 164 | else if (stored.channel_mode == 2) { 165 | lms_stream_status_t status[2]; 166 | 167 | lms_stream_meta_t rx_metadata[2]; 168 | int ret0 = LMS_RecvStream( 169 | &streamId[LMS_CH_0], output_items[0], noutput_items, &rx_metadata[0], 100); 170 | int ret1 = LMS_RecvStream( 171 | &streamId[LMS_CH_1], output_items[1], noutput_items, &rx_metadata[1], 100); 172 | if (ret0 <= 0 || ret1 <= 0) { 173 | return 0; 174 | } 175 | 176 | LMS_GetStreamStatus(&streamId[LMS_CH_0], &status[0]); 177 | LMS_GetStreamStatus(&streamId[LMS_CH_1], &status[1]); 178 | 179 | if (add_tag || status[0].droppedPackets > 0 || status[1].droppedPackets > 0) { 180 | pktLoss += status[0].droppedPackets; // because every time GetStreamStatus is called, 181 | // packet loss is reset 182 | add_tag = false; 183 | this->add_time_tag(LMS_CH_0, rx_metadata[0]); 184 | this->add_time_tag(LMS_CH_1, rx_metadata[1]); 185 | } 186 | 187 | // Print stream stats to debug 188 | if (stream_analyzer == true) { 189 | this->print_stream_stats(status[0]); 190 | } 191 | 192 | this->produce(0, ret0); 193 | this->produce(1, ret1); 194 | return WORK_CALLED_PRODUCE; 195 | } 196 | return 0; 197 | } 198 | 199 | // Setup stream 200 | void source_impl::init_stream(int device_number, int channel) { 201 | streamId[channel].channel = channel; 202 | streamId[channel].fifoSize = 203 | (stored.FIFO_size == 0) ? (int)stored.samp_rate / 10 : stored.FIFO_size; 204 | streamId[channel].throughputVsLatency = 0.5; 205 | streamId[channel].isTx = LMS_CH_RX; 206 | streamId[channel].dataFmt = lms_stream_t::LMS_FMT_F32; 207 | 208 | if (LMS_SetupStream(device_handler::getInstance().get_device(stored.device_number), 209 | &streamId[channel]) != LMS_SUCCESS) 210 | device_handler::getInstance().error(stored.device_number); 211 | 212 | std::cout << "INFO: source_impl::init_stream(): source channel " << channel << " (device nr. " 213 | << device_number << ") stream setup done." << std::endl; 214 | } 215 | 216 | void source_impl::release_stream(int device_number, lms_stream_t* stream) { 217 | if (stream->handle != 0) { 218 | LMS_StopStream(stream); 219 | LMS_DestroyStream(device_handler::getInstance().get_device(device_number), stream); 220 | } 221 | } 222 | 223 | // Print stream status 224 | void source_impl::print_stream_stats(lms_stream_status_t status) { 225 | t2 = std::chrono::high_resolution_clock::now(); 226 | auto timePeriod = std::chrono::duration_cast(t2 - t1).count(); 227 | if (timePeriod >= 1000) { 228 | std::cout << std::endl; 229 | std::cout << "RX"; 230 | std::cout << "|rate: " << status.linkRate / 1e6 << " MB/s "; 231 | std::cout << "|dropped packets: " << pktLoss << " "; 232 | std::cout << "|FIFO: " << 100 * status.fifoFilledCount / status.fifoSize << "%" 233 | << std::endl; 234 | pktLoss = 0; 235 | t1 = t2; 236 | } 237 | } 238 | 239 | // Add rx_time tag to stream 240 | void source_impl::add_time_tag(int channel, lms_stream_meta_t meta) { 241 | 242 | uint64_t u_rate = (uint64_t)stored.samp_rate; 243 | double f_rate = stored.samp_rate - u_rate; 244 | uint64_t intpart = meta.timestamp / u_rate; 245 | double fracpart = (meta.timestamp - intpart * u_rate - intpart * f_rate) / stored.samp_rate; 246 | 247 | const pmt::pmt_t ID = pmt::string_to_symbol(stored.serial); 248 | const pmt::pmt_t t_val = pmt::make_tuple(pmt::from_uint64(intpart), pmt::from_double(fracpart)); 249 | this->add_item_tag(channel, nitems_written(channel), TIME_TAG, t_val, ID); 250 | } 251 | // Return io_signature to manage module output count 252 | // based on SISO (one output) and MIMO (two outputs) modes 253 | inline gr::io_signature::sptr source_impl::args_to_io_signature(int channel_number) { 254 | if (channel_number < 2) { 255 | return gr::io_signature::make(1, 1, sizeof(gr_complex)); 256 | } else if (channel_number == 2) { 257 | return gr::io_signature::make(2, 2, sizeof(gr_complex)); 258 | } else { 259 | std::cout << "ERROR: source_impl::args_to_io_signature(): channel_number must be 0,1 or 2." 260 | << std::endl; 261 | exit(0); 262 | } 263 | } 264 | double source_impl::set_center_freq(double freq, size_t chan) { 265 | add_tag = true; 266 | return device_handler::getInstance().set_rf_freq( 267 | stored.device_number, LMS_CH_RX, LMS_CH_0, freq); 268 | } 269 | 270 | void source_impl::set_nco(float nco_freq, int channel) { 271 | device_handler::getInstance().set_nco(stored.device_number, LMS_CH_RX, channel, nco_freq); 272 | add_tag = true; 273 | } 274 | 275 | void source_impl::set_antenna(int antenna, int channel) { 276 | device_handler::getInstance().set_antenna(stored.device_number, channel, LMS_CH_RX, antenna); 277 | } 278 | 279 | double source_impl::set_bandwidth(double analog_bandw, int channel) { 280 | add_tag = true; 281 | return device_handler::getInstance().set_analog_filter( 282 | stored.device_number, LMS_CH_RX, channel, analog_bandw); 283 | } 284 | 285 | void source_impl::set_digital_filter(double digital_bandw, int channel) { 286 | device_handler::getInstance().set_digital_filter( 287 | stored.device_number, LMS_CH_RX, channel, digital_bandw); 288 | add_tag = true; 289 | } 290 | 291 | unsigned source_impl::set_gain(unsigned gain_dB, int channel) { 292 | return device_handler::getInstance().set_gain( 293 | stored.device_number, LMS_CH_RX, channel, gain_dB); 294 | } 295 | 296 | void source_impl::calibrate(double bandw, int channel) { 297 | device_handler::getInstance().calibrate(stored.device_number, LMS_CH_RX, channel, bandw); 298 | } 299 | 300 | double source_impl::set_sample_rate(double rate) { 301 | device_handler::getInstance().set_samp_rate(stored.device_number, rate); 302 | stored.samp_rate = rate; 303 | return rate; 304 | } 305 | 306 | void source_impl::set_buffer_size(uint32_t size) { stored.FIFO_size = size; } 307 | 308 | void source_impl::set_oversampling(int oversample) { 309 | device_handler::getInstance().set_oversampling(stored.device_number, oversample); 310 | } 311 | 312 | void source_impl::set_tcxo_dac(uint16_t dacVal) { 313 | device_handler::getInstance().set_tcxo_dac(stored.device_number, dacVal); 314 | } 315 | 316 | } // namespace limesdr 317 | } // namespace gr 318 | -------------------------------------------------------------------------------- /lib/source_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2018 Lime Microsystems info@limemicro.com 4 | * 5 | * GNU Radio is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * GNU Radio is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifndef INCLUDED_LIMESDR_SOURCE_IMPL_H 22 | #define INCLUDED_LIMESDR_SOURCE_IMPL_H 23 | 24 | #include "common/device_handler.h" 25 | #include 26 | 27 | 28 | static const pmt::pmt_t TIME_TAG = pmt::string_to_symbol("rx_time"); 29 | 30 | namespace gr { 31 | namespace limesdr { 32 | class source_impl : public source { 33 | private: 34 | lms_stream_t streamId[2]; 35 | 36 | bool stream_analyzer = false; 37 | 38 | int source_block = 1; 39 | 40 | bool add_tag = false; 41 | uint32_t pktLoss = 0; 42 | 43 | struct constant_data { 44 | std::string serial; 45 | int device_number; 46 | int channel_mode; 47 | double samp_rate = 10e6; 48 | uint32_t FIFO_size = 0; 49 | } stored; 50 | 51 | std::chrono::high_resolution_clock::time_point t1, t2; 52 | 53 | void print_stream_stats(lms_stream_status_t status); 54 | 55 | void add_time_tag(int channel, lms_stream_meta_t meta); 56 | 57 | public: 58 | source_impl(std::string serial, int channel_mode, const std::string& filename); 59 | ~source_impl(); 60 | 61 | int general_work(int noutput_items, 62 | gr_vector_int& ninput_items, 63 | gr_vector_const_void_star& input_items, 64 | gr_vector_void_star& output_items); 65 | 66 | bool start(void); 67 | 68 | bool stop(void); 69 | 70 | inline gr::io_signature::sptr args_to_io_signature(int channel_mode); 71 | 72 | void init_stream(int device_number, int channel); 73 | void release_stream(int device_number, lms_stream_t *stream); 74 | 75 | double set_center_freq(double freq, size_t chan = 0); 76 | 77 | void set_antenna(int antenna, int channel = 0); 78 | 79 | void set_nco(float nco_freq, int channel = 0); 80 | 81 | double set_bandwidth(double analog_bandw, int channel = 0); 82 | 83 | void set_digital_filter(double digital_bandw, int channel = 0); 84 | 85 | unsigned set_gain(unsigned gain_dB, int channel = 0); 86 | 87 | double set_sample_rate(double rate); 88 | 89 | void set_oversampling(int oversample); 90 | 91 | void set_buffer_size(uint32_t size); 92 | 93 | void calibrate(double bandw, int channel = 0); 94 | 95 | void set_tcxo_dac(uint16_t dacVal = 125); 96 | }; 97 | } // namespace limesdr 98 | } // namespace gr 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ######################################################################## 21 | # Include python install macros 22 | ######################################################################## 23 | include(GrPython) 24 | if(NOT PYTHONINTERP_FOUND) 25 | return() 26 | endif() 27 | 28 | ######################################################################## 29 | # Install python sources 30 | ######################################################################## 31 | GR_PYTHON_INSTALL( 32 | FILES 33 | __init__.py 34 | DESTINATION ${GR_PYTHON_DIR}/limesdr 35 | ) 36 | 37 | ######################################################################## 38 | # Handle the unit tests 39 | ######################################################################## 40 | include(GrTest) 41 | 42 | set(GR_TEST_TARGET_DEPS gnuradio-limesdr) 43 | set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig) 44 | -------------------------------------------------------------------------------- /python/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2008,2009 Free Software Foundation, Inc. 3 | # 4 | # This application is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3, or (at your option) 7 | # any later version. 8 | # 9 | # This application is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License along 15 | # with this program; if not, write to the Free Software Foundation, Inc., 16 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | # 18 | 19 | # The presence of this file turns this directory into a Python package 20 | 21 | ''' 22 | This is the GNU Radio LIMESDR module. Place your Python package 23 | description here (python/__init__.py). 24 | ''' 25 | 26 | # import swig generated symbols into the limesdr namespace 27 | try: 28 | # this might fail if the module is python-only 29 | from limesdr_swig import * 30 | except ImportError: 31 | pass 32 | 33 | # import any pure python here 34 | # 35 | -------------------------------------------------------------------------------- /python/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/gr-limesdr/244c6bf4f1cb52a8b4d27240d7a4c88c9542cbbb/python/__init__.pyc -------------------------------------------------------------------------------- /python/build_utils.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2004,2009,2012 Free Software Foundation, Inc. 3 | # 4 | # This file is part of GNU Radio 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | 22 | """Misc utilities used at build time 23 | """ 24 | 25 | import re, os, os.path 26 | from build_utils_codes import * 27 | 28 | 29 | # set srcdir to the directory that contains Makefile.am 30 | try: 31 | srcdir = os.environ['srcdir'] 32 | except KeyError, e: 33 | srcdir = "." 34 | srcdir = srcdir + '/' 35 | 36 | # set do_makefile to either true or false dependeing on the environment 37 | try: 38 | if os.environ['do_makefile'] == '0': 39 | do_makefile = False 40 | else: 41 | do_makefile = True 42 | except KeyError, e: 43 | do_makefile = False 44 | 45 | # set do_sources to either true or false dependeing on the environment 46 | try: 47 | if os.environ['do_sources'] == '0': 48 | do_sources = False 49 | else: 50 | do_sources = True 51 | except KeyError, e: 52 | do_sources = True 53 | 54 | name_dict = {} 55 | 56 | def log_output_name (name): 57 | (base, ext) = os.path.splitext (name) 58 | ext = ext[1:] # drop the leading '.' 59 | 60 | entry = name_dict.setdefault (ext, []) 61 | entry.append (name) 62 | 63 | def open_and_log_name (name, dir): 64 | global do_sources 65 | if do_sources: 66 | f = open (name, dir) 67 | else: 68 | f = None 69 | log_output_name (name) 70 | return f 71 | 72 | def expand_template (d, template_filename, extra = ""): 73 | '''Given a dictionary D and a TEMPLATE_FILENAME, expand template into output file 74 | ''' 75 | global do_sources 76 | output_extension = extract_extension (template_filename) 77 | template = open_src (template_filename, 'r') 78 | output_name = d['NAME'] + extra + '.' + output_extension 79 | log_output_name (output_name) 80 | if do_sources: 81 | output = open (output_name, 'w') 82 | do_substitution (d, template, output) 83 | output.close () 84 | template.close () 85 | 86 | def output_glue (dirname): 87 | output_makefile_fragment () 88 | output_ifile_include (dirname) 89 | 90 | def output_makefile_fragment (): 91 | global do_makefile 92 | if not do_makefile: 93 | return 94 | # overwrite the source, which must be writable; this should have been 95 | # checked for beforehand in the top-level Makefile.gen.gen . 96 | f = open (os.path.join (os.environ.get('gendir', os.environ.get('srcdir', '.')), 'Makefile.gen'), 'w') 97 | f.write ('#\n# This file is machine generated. All edits will be overwritten\n#\n') 98 | output_subfrag (f, 'h') 99 | output_subfrag (f, 'i') 100 | output_subfrag (f, 'cc') 101 | f.close () 102 | 103 | def output_ifile_include (dirname): 104 | global do_sources 105 | if do_sources: 106 | f = open ('%s_generated.i' % (dirname,), 'w') 107 | f.write ('//\n// This file is machine generated. All edits will be overwritten\n//\n') 108 | files = name_dict.setdefault ('i', []) 109 | files.sort () 110 | f.write ('%{\n') 111 | for file in files: 112 | f.write ('#include <%s>\n' % (file[0:-1] + 'h',)) 113 | f.write ('%}\n\n') 114 | for file in files: 115 | f.write ('%%include <%s>\n' % (file,)) 116 | 117 | def output_subfrag (f, ext): 118 | files = name_dict.setdefault (ext, []) 119 | files.sort () 120 | f.write ("GENERATED_%s =" % (ext.upper ())) 121 | for file in files: 122 | f.write (" \\\n\t%s" % (file,)) 123 | f.write ("\n\n") 124 | 125 | def extract_extension (template_name): 126 | # template name is something like: GrFIRfilterXXX.h.t 127 | # we return everything between the penultimate . and .t 128 | mo = re.search (r'\.([a-z]+)\.t$', template_name) 129 | if not mo: 130 | raise ValueError, "Incorrectly formed template_name '%s'" % (template_name,) 131 | return mo.group (1) 132 | 133 | def open_src (name, mode): 134 | global srcdir 135 | return open (os.path.join (srcdir, name), mode) 136 | 137 | def do_substitution (d, in_file, out_file): 138 | def repl (match_obj): 139 | key = match_obj.group (1) 140 | # print key 141 | return d[key] 142 | 143 | inp = in_file.read () 144 | out = re.sub (r"@([a-zA-Z0-9_]+)@", repl, inp) 145 | out_file.write (out) 146 | 147 | 148 | 149 | copyright = '''/* -*- c++ -*- */ 150 | /* 151 | * Copyright 2003,2004 Free Software Foundation, Inc. 152 | * 153 | * This file is part of GNU Radio 154 | * 155 | * GNU Radio is free software; you can redistribute it and/or modify 156 | * it under the terms of the GNU General Public License as published by 157 | * the Free Software Foundation; either version 3, or (at your option) 158 | * any later version. 159 | * 160 | * GNU Radio is distributed in the hope that it will be useful, 161 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 162 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 163 | * GNU General Public License for more details. 164 | * 165 | * You should have received a copy of the GNU General Public License 166 | * along with GNU Radio; see the file COPYING. If not, write to 167 | * the Free Software Foundation, Inc., 51 Franklin Street, 168 | * Boston, MA 02110-1301, USA. 169 | */ 170 | ''' 171 | 172 | def is_complex (code3): 173 | if i_code (code3) == 'c' or o_code (code3) == 'c': 174 | return '1' 175 | else: 176 | return '0' 177 | 178 | 179 | def standard_dict (name, code3, package='gr'): 180 | d = {} 181 | d['NAME'] = name 182 | d['NAME_IMPL'] = name+'_impl' 183 | d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper()) 184 | d['GUARD_NAME_IMPL'] = 'INCLUDED_%s_%s_IMPL_H' % (package.upper(), name.upper()) 185 | d['BASE_NAME'] = re.sub ('^' + package + '_', '', name) 186 | d['SPTR_NAME'] = '%s_sptr' % name 187 | d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten' 188 | d['COPYRIGHT'] = copyright 189 | d['TYPE'] = i_type (code3) 190 | d['I_TYPE'] = i_type (code3) 191 | d['O_TYPE'] = o_type (code3) 192 | d['TAP_TYPE'] = tap_type (code3) 193 | d['IS_COMPLEX'] = is_complex (code3) 194 | return d 195 | 196 | 197 | def standard_dict2 (name, code3, package): 198 | d = {} 199 | d['NAME'] = name 200 | d['BASE_NAME'] = name 201 | d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper()) 202 | d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten' 203 | d['COPYRIGHT'] = copyright 204 | d['TYPE'] = i_type (code3) 205 | d['I_TYPE'] = i_type (code3) 206 | d['O_TYPE'] = o_type (code3) 207 | d['TAP_TYPE'] = tap_type (code3) 208 | d['IS_COMPLEX'] = is_complex (code3) 209 | return d 210 | 211 | def standard_impl_dict2 (name, code3, package): 212 | d = {} 213 | d['NAME'] = name 214 | d['IMPL_NAME'] = name 215 | d['BASE_NAME'] = name.rstrip("impl").rstrip("_") 216 | d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper()) 217 | d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten' 218 | d['COPYRIGHT'] = copyright 219 | d['FIR_TYPE'] = "fir_filter_" + code3 220 | d['CFIR_TYPE'] = "fir_filter_" + code3[0:2] + 'c' 221 | d['TYPE'] = i_type (code3) 222 | d['I_TYPE'] = i_type (code3) 223 | d['O_TYPE'] = o_type (code3) 224 | d['TAP_TYPE'] = tap_type (code3) 225 | d['IS_COMPLEX'] = is_complex (code3) 226 | return d 227 | -------------------------------------------------------------------------------- /python/build_utils.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/gr-limesdr/244c6bf4f1cb52a8b4d27240d7a4c88c9542cbbb/python/build_utils.pyc -------------------------------------------------------------------------------- /python/build_utils_codes.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2004 Free Software Foundation, Inc. 3 | # 4 | # This file is part of GNU Radio 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | 22 | def i_code (code3): 23 | return code3[0] 24 | 25 | def o_code (code3): 26 | if len (code3) >= 2: 27 | return code3[1] 28 | else: 29 | return code3[0] 30 | 31 | def tap_code (code3): 32 | if len (code3) >= 3: 33 | return code3[2] 34 | else: 35 | return code3[0] 36 | 37 | def i_type (code3): 38 | return char_to_type[i_code (code3)] 39 | 40 | def o_type (code3): 41 | return char_to_type[o_code (code3)] 42 | 43 | def tap_type (code3): 44 | return char_to_type[tap_code (code3)] 45 | 46 | 47 | char_to_type = {} 48 | char_to_type['s'] = 'short' 49 | char_to_type['i'] = 'int' 50 | char_to_type['f'] = 'float' 51 | char_to_type['c'] = 'gr_complex' 52 | char_to_type['b'] = 'unsigned char' 53 | -------------------------------------------------------------------------------- /python/build_utils_codes.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/gr-limesdr/244c6bf4f1cb52a8b4d27240d7a4c88c9542cbbb/python/build_utils_codes.pyc -------------------------------------------------------------------------------- /swig/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ######################################################################## 21 | # Check if there is C++ code at all 22 | ######################################################################## 23 | if(NOT limesdr_sources) 24 | MESSAGE(STATUS "No C++ sources... skipping swig/") 25 | return() 26 | endif(NOT limesdr_sources) 27 | 28 | if(ENABLE_RFE) 29 | set(GR_SWIG_FLAGS -DENABLE_RFE) 30 | endif() 31 | ######################################################################## 32 | # Include swig generation macros 33 | ######################################################################## 34 | find_package(SWIG REQUIRED) 35 | find_package(PythonLibs 2) 36 | if(NOT SWIG_FOUND OR NOT PYTHONLIBS_FOUND) 37 | return() 38 | endif() 39 | include(GrSwig) 40 | include(GrPython) 41 | 42 | ######################################################################## 43 | # Setup swig generation 44 | ######################################################################## 45 | foreach(incdir ${GNURADIO_RUNTIME_INCLUDE_DIRS}) 46 | list(APPEND GR_SWIG_INCLUDE_DIRS ${incdir}/gnuradio/swig) 47 | endforeach(incdir) 48 | 49 | set(GR_SWIG_LIBRARIES gnuradio-limesdr) 50 | set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/limesdr_swig_doc.i) 51 | set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include) 52 | 53 | GR_SWIG_MAKE(limesdr_swig limesdr_swig.i) 54 | 55 | ######################################################################## 56 | # Install the build swig module 57 | ######################################################################## 58 | GR_SWIG_INSTALL(TARGETS limesdr_swig DESTINATION ${GR_PYTHON_DIR}/limesdr) 59 | 60 | ######################################################################## 61 | # Install swig .i files for development 62 | ######################################################################## 63 | install( 64 | FILES 65 | limesdr_swig.i 66 | ${CMAKE_CURRENT_BINARY_DIR}/limesdr_swig_doc.i 67 | DESTINATION ${GR_INCLUDE_DIR}/limesdr/swig 68 | ) 69 | -------------------------------------------------------------------------------- /swig/limesdr_swig.i: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | 3 | #define LIMESDR_API 4 | 5 | %include "gnuradio.i" // the common stuff 6 | 7 | //load generated python docstrings 8 | %include "limesdr_swig_doc.i" 9 | 10 | %{ 11 | #include "limesdr/source.h" 12 | #include "limesdr/sink.h" 13 | %} 14 | 15 | %include "limesdr/source.h" 16 | GR_SWIG_BLOCK_MAGIC2(limesdr, source); 17 | 18 | %include "limesdr/sink.h" 19 | GR_SWIG_BLOCK_MAGIC2(limesdr, sink); 20 | 21 | #ifdef ENABLE_RFE 22 | %{ 23 | #include "limesdr/rfe.h" 24 | %} 25 | %include "limesdr/rfe.h" 26 | #endif 27 | --------------------------------------------------------------------------------