diff --git a/.clang-format b/.clang-format old mode 100755 new mode 100644 index 02e7b95..3e4ddd4 --- a/.clang-format +++ b/.clang-format @@ -1,20 +1,104 @@ --- -BasedOnStyle: LLVM -IndentWidth: 4 ---- Language: Cpp -BasedOnStyle: LLVM -IndentWidth: 4 -AccessModifierOffset: 0 +# BasedOnStyle: LLVM +AccessModifierOffset: -4 AlignAfterOpenBracket: Align -#AlignEscapedNewlines: Left +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: true +AlignOperands: true AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: true BinPackArguments: false BinPackParameters: false -ColumnLimit: 100 -#FixNamespaceComments: true +BreakBeforeBraces: Custom +BraceWrapping: + AfterClass: true + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 90 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeCategories: + - Regex: '^"(gnuradio)/' + Priority: 1 + - Regex: '^<(gnuradio)/' + Priority: 2 + - Regex: '^<(boost)/' + Priority: 98 + - Regex: '^<[a-z]*>$' + Priority: 99 + - Regex: '^".*"$' + Priority: 0 + - Regex: '.*' + Priority: 10 + +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' MaxEmptyLinesToKeep: 2 -#CompactNamespaces: true NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 8 +UseTab: Never diff --git a/.gitignore b/.gitignore index 065e739..85c92e8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ -build/** -.vscode/** +*~ +*.pyc +*.pyo +build*/ +examples/grc/*.py diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100755 new mode 100644 index dc28166..1572d1e --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,98 +1,94 @@ -# Copyright 2011 Free Software Foundation, Inc. +# Copyright 2011-2020 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-limesdr # -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. +# SPDX-License-Identifier: GPL-3.0-or-later # -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. ######################################################################## # Project setup ######################################################################## -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 3.8) project(gr-limesdr CXX C) - -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - enable_testing() -#select the release build type by default to get optimization flags +# Install to PyBOMBS target prefix if defined +if(DEFINED ENV{PYBOMBS_PREFIX}) + set(CMAKE_INSTALL_PREFIX $ENV{PYBOMBS_PREFIX}) + message(STATUS "PyBOMBS installed GNU Radio. Setting CMAKE_INSTALL_PREFIX to $ENV{PYBOMBS_PREFIX}") +endif() + +# Select the release build type by default to get optimization flags if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") message(STATUS "Build type not specified: defaulting to release.") endif(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") -#make sure our local CMake Modules path comes first +# Make sure our local CMake Modules path comes first list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules) +# Set the version information here +set(VERSION_MAJOR 1) +set(VERSION_API 0) +set(VERSION_ABI 0) +set(VERSION_PATCH git) + +cmake_policy(SET CMP0011 NEW) + +# Enable generation of compile_commands.json for code completion engines +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + ######################################################################## # Compiler specific setup ######################################################################## -if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) +if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR + CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + AND NOT WIN32) #http://gcc.gnu.org/wiki/Visibility add_definitions(-fvisibility=hidden) endif() -######################################################################## -# Find boost -######################################################################## -MESSAGE(STATUS "Configuring Boost C++ Libraries...") - -SET(BOOST_REQUIRED_COMPONENTS - thread - system -) - -if(UNIX AND EXISTS "/usr/lib64") - list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix -endif(UNIX AND EXISTS "/usr/lib64") - -set(Boost_ADDITIONAL_VERSIONS - "1.35.0" "1.35" "1.36.0" "1.36" "1.37.0" "1.37" "1.38.0" "1.38" "1.39.0" "1.39" - "1.40.0" "1.40" "1.41.0" "1.41" "1.42.0" "1.42" "1.43.0" "1.43" "1.44.0" "1.44" - "1.45.0" "1.45" "1.46.0" "1.46" "1.47.0" "1.47" "1.48.0" "1.48" "1.49.0" "1.49" - "1.50.0" "1.50" "1.51.0" "1.51" "1.52.0" "1.52" "1.53.0" "1.53" "1.54.0" "1.54" - "1.55.0" "1.55" "1.56.0" "1.56" "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59" - "1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64" - "1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69" -) - -find_package(Boost COMPONENTS ${BOOST_REQUIRED_COMPONENTS}) - -if(NOT Boost_FOUND) - message(FATAL_ERROR "Boost required to compile limesdr") -endif() +IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + SET(CMAKE_CXX_STANDARD 14) +ELSEIF(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + SET(CMAKE_CXX_STANDARD 14) +ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + SET(CMAKE_CXX_STANDARD 14) +ELSE() + message(WARNING "C++ standard could not be set because compiler is not GNU, Clang or MSVC.") +ENDIF() + +IF(CMAKE_C_COMPILER_ID STREQUAL "GNU") + SET(CMAKE_C_STANDARD 11) +ELSEIF(CMAKE_C_COMPILER_ID MATCHES "Clang") + SET(CMAKE_C_STANDARD 11) +ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "MSVC") + SET(CMAKE_C_STANDARD 11) +ELSE() + message(WARNING "C standard could not be set because compiler is not GNU, Clang or MSVC.") +ENDIF() ######################################################################## # Install directories ######################################################################## +include(FindPkgConfig) +find_package(Gnuradio "3.9" REQUIRED) +include(GrVersion) + include(GrPlatform) #define LIB_SUFFIX -set(GR_RUNTIME_DIR bin) -set(GR_LIBRARY_DIR lib${LIB_SUFFIX}) + +if(NOT CMAKE_MODULES_DIR) + set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake) +endif(NOT CMAKE_MODULES_DIR) + set(GR_INCLUDE_DIR include/limesdr) -set(GR_DATA_DIR share) +set(GR_CMAKE_DIR ${CMAKE_MODULES_DIR}/limesdr) set(GR_PKG_DATA_DIR ${GR_DATA_DIR}/${CMAKE_PROJECT_NAME}) -set(GR_DOC_DIR ${GR_DATA_DIR}/doc) set(GR_PKG_DOC_DIR ${GR_DOC_DIR}/${CMAKE_PROJECT_NAME}) -set(GR_CONF_DIR etc) set(GR_PKG_CONF_DIR ${GR_CONF_DIR}/${CMAKE_PROJECT_NAME}/conf.d) -set(GR_LIBEXEC_DIR libexec) set(GR_PKG_LIBEXEC_DIR ${GR_LIBEXEC_DIR}/${CMAKE_PROJECT_NAME}) -set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks) ######################################################################## # On Apple only, set install name and use rpath correctly, if not already set @@ -117,22 +113,20 @@ endif(APPLE) ######################################################################## # Find gnuradio build dependencies ######################################################################## -# Search for GNU Radio and its components and versions. Add any -# components required to the list of GR_REQUIRED_COMPONENTS (in all -# caps such as FILTER or FFT) and change the version to the minimum -# API compatible version required. find_package(Doxygen) -MESSAGE(STATUS "Configuring GNU Radio C++ Libraries...") -set(GR_REQUIRED_COMPONENTS RUNTIME PMT) -set(MIN_GR_VERSION "3.7.8") -set(MAX_GR_VERSION "3.8.0") -find_package(Gnuradio REQUIRED) -if("${Gnuradio_VERSION}" VERSION_LESS MIN_GR_VERSION OR NOT "${Gnuradio_VERSION}" - VERSION_LESS MAX_GR_VERSION) - MESSAGE(FATAL_ERROR "GnuRadio version required: >=\"" ${MIN_GR_VERSION} "\" \ - < \"${MAX_GR_VERSION}\" found: \"" ${Gnuradio_VERSION} "\"") -endif() +######################################################################## +# PyBind11 Related +######################################################################## + +find_package(pybind11 REQUIRED) +execute_process( + COMMAND "${PYTHON_EXECUTABLE}" -c + "try:\n import numpy\n import os\n inc_path = numpy.get_include()\n if os.path.exists(os.path.join(inc_path, 'numpy', 'arrayobject.h')):\n print(inc_path, end='')\nexcept:\n pass" + OUTPUT_VARIABLE PYTHON_NUMPY_INCLUDE_DIR) +# format path in CMake-style for consistency with other path variables +# (a consistent style helps conda builds by using the same path separators) +file(TO_CMAKE_PATH "${PYTHON_NUMPY_INCLUDE_DIR}" PYTHON_NUMPY_INCLUDE_DIR) ######################################################################## # Find LimeSuite @@ -140,14 +134,14 @@ endif() MESSAGE(STATUS "Configuring LimeSuite C++ Libraries...") INCLUDE(FindPkgConfig) PKG_CHECK_MODULES(PC_LIMESUITE LimeSuite) -find_path(LIMESUITE_INCLUDE_DIRS +find_path(LIMESUITE_INCLUDE_DIRS NAMES LimeSuite.h HINTS ${PC_LIMESUITE_INCLUDEDIR}/lime PATHS ${LIMESUITE_PKG_INCLUDE_DIRS} /usr/include/lime /usr/local/include/lime ) -find_library(LIMESUITE_LIB +find_library(LIMESUITE_LIB NAMES LimeSuite limesuite HINTS ${PC_LIMESUITE_LIBDIR} PATHS ${LIMESDR_PKG_LIBRARY_DIRS} @@ -172,32 +166,10 @@ endif() # Setup doxygen option ######################################################################## if(DOXYGEN_FOUND) - option(ENABLE_DOXYGEN "Build docs using Doxygen" ON) + option(ENABLE_DOXYGEN "Build docs using Doxygen" ON) else(DOXYGEN_FOUND) - option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF) + option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF) endif(DOXYGEN_FOUND) -######################################################################## -# Setup the include and linker paths -######################################################################## -include_directories( - ${CMAKE_SOURCE_DIR}/lib - ${CMAKE_SOURCE_DIR}/include - ${CMAKE_BINARY_DIR}/lib - ${CMAKE_BINARY_DIR}/include - ${Boost_INCLUDE_DIRS} - ${GNURADIO_ALL_INCLUDE_DIRS} - ${LIMESUITE_INCLUDE_DIRS} -) - -link_directories( - ${Boost_LIBRARY_DIRS} - ${GNURADIO_RUNTIME_LIBRARY_DIRS} - ${LIMESUITE_LIB} -) - -# Set component parameters -set(GR_LIMESDR_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE INTERNAL "" FORCE) -set(GR_LIMESDR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/swig CACHE INTERNAL "" FORCE) ######################################################################## # Create uninstall target @@ -209,25 +181,27 @@ configure_file( add_custom_target(uninstall ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake -) + ) ######################################################################## # Add subdirectories ######################################################################## add_subdirectory(include/limesdr) add_subdirectory(lib) -add_subdirectory(swig) -add_subdirectory(python) -add_subdirectory(grc) add_subdirectory(apps) add_subdirectory(docs) +# NOTE: manually update below to use GRC to generate C++ flowgraphs w/o python +if(ENABLE_PYTHON) + message(STATUS "PYTHON and GRC components are enabled") + add_subdirectory(python) + add_subdirectory(grc) +else(ENABLE_PYTHON) + message(STATUS "PYTHON and GRC components are disabled") +endif(ENABLE_PYTHON) ######################################################################## # Install cmake search helper for this library ######################################################################## -if(NOT CMAKE_MODULES_DIR) - set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake) -endif(NOT CMAKE_MODULES_DIR) install(FILES cmake/Modules/limesdrConfig.cmake DESTINATION ${CMAKE_MODULES_DIR}/limesdr diff --git a/MANIFEST.md b/MANIFEST.md old mode 100755 new mode 100644 index d189447..303d9c5 --- a/MANIFEST.md +++ b/MANIFEST.md @@ -1,13 +1,17 @@ title: The LIMESDR OOT Module -brief: gr-limesdr blocks are used to control LimeSDR family devices -tags: #sink, #source, #settings +brief: Short description of gr-limesdr +tags: # Tags are arbitrary, but look at CGRAN what other authors are using - sdr author: - - Lime Microsystems + - Author Name copyright_owner: - - Lime Microsystems + - Copyright Owner 1 license: -#repo: -#website: -#icon: +gr_supported_version: # Put a comma separated list of supported GR versions here +#repo: # Put the URL of the repository here, or leave blank for default +#website: # If you have a separate project website, put it here +#icon: # Put a URL to a square image here that will be used as an icon on CGRAN --- +A longer, multi-line description of gr-limesdr. +You may use some *basic* Markdown here. +If left empty, it will try to find a README file instead. diff --git a/README.md b/README.md index aac8b98..0e7142b 100755 --- a/README.md +++ b/README.md @@ -8,26 +8,18 @@ Package includes GNU Radio blocks for various LimeSDR boards. ## Dependencies -* GNU Radio(3.7) +* GNU Radio(3.9) * BOOST -* SWIG +* pybind11 * LimeSuite ## Installation process #### Linux -* Installing via PPA -
-sudo add-apt-repository -y ppa:myriadrf/drivers
-sudo add-apt-repository -y ppa:myriadrf/gnuradio
-sudo apt update
-sudo apt install gr-limesdr
-
- * Building from source
-git clone https://github.com/myriadrf/gr-limesdr.git
+git clone https://github.com/chrisjohgorman/gr-limesdr.git
 cd gr-limesdr
 mkdir build
 cd build
@@ -37,13 +29,6 @@ sudo make install
 sudo ldconfig
 
-#### Windows - -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: -
-C:\Program Files\GNURadio-3.7
-
- ## Known issues Known issues are located in: diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt old mode 100755 new mode 100644 index c837d77..7dbba51 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -1,21 +1,10 @@ # Copyright 2011 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-limesdr # -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. +# SPDX-License-Identifier: GPL-3.0-or-later # -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. include(GrPython) diff --git a/cmake/Modules/CMakeParseArgumentsCopy.cmake b/cmake/Modules/CMakeParseArgumentsCopy.cmake old mode 100755 new mode 100644 index 7ce4c49..66016cb --- a/cmake/Modules/CMakeParseArgumentsCopy.cmake +++ b/cmake/Modules/CMakeParseArgumentsCopy.cmake @@ -58,7 +58,7 @@ # the new option. # E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in # MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would -# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. +# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefore. #============================================================================= # Copyright 2010 Alexander Neundorf diff --git a/cmake/Modules/limesdrConfig.cmake b/cmake/Modules/limesdrConfig.cmake old mode 100755 new mode 100644 index f19ca00..4564656 --- a/cmake/Modules/limesdrConfig.cmake +++ b/cmake/Modules/limesdrConfig.cmake @@ -1,4 +1,6 @@ -INCLUDE(FindPkgConfig) +if(NOT PKG_CONFIG_FOUND) + INCLUDE(FindPkgConfig) +endif() PKG_CHECK_MODULES(PC_LIMESDR limesdr) FIND_PATH( @@ -22,9 +24,10 @@ FIND_LIBRARY( /usr/local/lib64 /usr/lib /usr/lib64 -) + ) + +include("${CMAKE_CURRENT_LIST_DIR}/limesdrTarget.cmake") INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIMESDR DEFAULT_MSG LIMESDR_LIBRARIES LIMESDR_INCLUDE_DIRS) MARK_AS_ADVANCED(LIMESDR_LIBRARIES LIMESDR_INCLUDE_DIRS) - diff --git a/cmake/Modules/targetConfig.cmake.in b/cmake/Modules/targetConfig.cmake.in new file mode 100644 index 0000000..4a1fb31 --- /dev/null +++ b/cmake/Modules/targetConfig.cmake.in @@ -0,0 +1,14 @@ +# Copyright 2018 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +include(CMakeFindDependencyMacro) + +set(target_deps "@TARGET_DEPENDENCIES@") +foreach(dep IN LISTS target_deps) + find_dependency(${dep}) +endforeach() +include("${CMAKE_CURRENT_LIST_DIR}/@TARGET@Targets.cmake") diff --git a/cmake/cmake_uninstall.cmake.in b/cmake/cmake_uninstall.cmake.in old mode 100755 new mode 100644 diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt old mode 100755 new mode 100644 index f16fbf6..3dfec04 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -1,21 +1,10 @@ # Copyright 2011 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-limesdr # -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. +# SPDX-License-Identifier: GPL-3.0-or-later # -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. ######################################################################## # Setup dependencies diff --git a/docs/README.limesdr b/docs/README.limesdr old mode 100755 new mode 100644 diff --git a/docs/doxygen/CMakeLists.txt b/docs/doxygen/CMakeLists.txt old mode 100755 new mode 100644 index 1b44799..bee1232 --- a/docs/doxygen/CMakeLists.txt +++ b/docs/doxygen/CMakeLists.txt @@ -1,21 +1,10 @@ # Copyright 2011 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-limesdr # -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. +# SPDX-License-Identifier: GPL-3.0-or-later # -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. ######################################################################## # Create the doxygen configuration file @@ -28,6 +17,7 @@ file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} abs_top_builddir) set(HAVE_DOT ${DOXYGEN_DOT_FOUND}) set(enable_html_docs YES) set(enable_latex_docs NO) +set(enable_mathjax NO) set(enable_xml_docs YES) configure_file( diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in old mode 100755 new mode 100644 index 5a07f02..91a2019 --- a/docs/doxygen/Doxyfile.in +++ b/docs/doxygen/Doxyfile.in @@ -199,13 +199,6 @@ TAB_SIZE = 8 ALIASES = -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding -# "class=itcl::class" will allow you to use the command class in the -# itcl::class meaning. - -TCL_SUBST = - # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list @@ -654,8 +647,8 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = @top_srcdir@ \ - @top_builddir@ +INPUT = "@top_srcdir@" \ + "@top_builddir@" # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -723,8 +716,6 @@ EXCLUDE_PATTERNS = */.deps/* \ EXCLUDE_SYMBOLS = ad9862 \ numpy \ - *swig* \ - *Swig* \ *my_top_block* \ *my_graph* \ *app_top_block* \ @@ -790,7 +781,7 @@ INPUT_FILTER = # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. -FILTER_PATTERNS = *.py=@top_srcdir@/doc/doxygen/other/doxypy.py +FILTER_PATTERNS = *.py="@top_srcdir@"/doc/doxygen/other/doxypy.py # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source @@ -945,7 +936,7 @@ HTML_STYLESHEET = # user-defined cascading style sheet that is included after the standard # style sheets created by doxygen. Using this option one can overrule # certain style aspects. This is preferred over using HTML_STYLESHEET -# since it does not replace the standard style sheet and is therefor more +# since it does not replace the standard style sheet and is therefore more # robust against future updates. Doxygen will copy the style sheet file to # the output directory. @@ -989,7 +980,7 @@ HTML_COLORSTYLE_GAMMA = 80 # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. -HTML_TIMESTAMP = YES +HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the @@ -1220,14 +1211,14 @@ FORMULA_TRANSPARENT = YES # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. -USE_MATHJAX = NO +USE_MATHJAX = @enable_mathjax@ # When MathJax is enabled you can set the default output format to be used for # the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and # SVG. The default value is HTML-CSS, which is slower, but has the best # compatibility. -MATHJAX_FORMAT = HTML-CSS +MATHJAX_FORMAT = SVG # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination @@ -1239,12 +1230,12 @@ MATHJAX_FORMAT = HTML-CSS # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_RELPATH = @MATHJAX2_PATH@ # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. -MATHJAX_EXTENSIONS = +MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # The MATHJAX_CODEFILE tag can be used to specify a file with javascript # pieces of code that will be used on startup of the MathJax code. @@ -1503,7 +1494,6 @@ GENERATE_XML = @enable_xml_docs@ XML_OUTPUT = xml - # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that @@ -1681,11 +1671,6 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- @@ -1698,15 +1683,6 @@ PERL_PATH = /usr/bin/perl CLASS_DIAGRAMS = YES -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. @@ -1835,7 +1811,7 @@ DIRECTORY_GRAPH = YES # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). -DOT_IMAGE_FORMAT = png +DOT_IMAGE_FORMAT = svg # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. diff --git a/docs/doxygen/doxyxml/__init__.py b/docs/doxygen/doxyxml/__init__.py old mode 100755 new mode 100644 index 5cd0b3c..be2978b --- a/docs/doxygen/doxyxml/__init__.py +++ b/docs/doxygen/doxyxml/__init__.py @@ -1,22 +1,11 @@ # # Copyright 2010 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-limesdr # -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. +# SPDX-License-Identifier: GPL-3.0-or-later # -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. # """ Python interface to contents of doxygen xml documentation. @@ -64,7 +53,7 @@ """ -from doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther +from .doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther def _test(): import os diff --git a/docs/doxygen/doxyxml/base.py b/docs/doxygen/doxyxml/base.py old mode 100755 new mode 100644 index e8f026a..9807e1e --- a/docs/doxygen/doxyxml/base.py +++ b/docs/doxygen/doxyxml/base.py @@ -1,22 +1,11 @@ # # Copyright 2010 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-limesdr # -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. +# SPDX-License-Identifier: GPL-3.0-or-later # -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. # """ A base class is created. @@ -30,18 +19,18 @@ from xml.parsers.expat import ExpatError -from generated import compound +from .generated import compound class Base(object): - class Duplicate(StandardError): + class Duplicate(Exception): pass - class NoSuchMember(StandardError): + class NoSuchMember(Exception): pass - class ParsingError(StandardError): + class ParsingError(Exception): pass def __init__(self, parse_data, top=None): @@ -94,7 +83,7 @@ def get_cls(self, mem): for cls in self.mem_classes: if cls.can_parse(mem): return cls - raise StandardError(("Did not find a class for object '%s'." \ + raise Exception(("Did not find a class for object '%s'." \ % (mem.get_name()))) def convert_mem(self, mem): @@ -102,11 +91,11 @@ def convert_mem(self, mem): cls = self.get_cls(mem) converted = cls.from_parse_data(mem, self.top) if converted is None: - raise StandardError('No class matched this object.') + raise Exception('No class matched this object.') self.add_ref(converted) return converted - except StandardError, e: - print e + except Exception as e: + print(e) @classmethod def includes(cls, inst): diff --git a/docs/doxygen/doxyxml/doxyindex.py b/docs/doxygen/doxyxml/doxyindex.py old mode 100755 new mode 100644 index 0132ab8..c59050e --- a/docs/doxygen/doxyxml/doxyindex.py +++ b/docs/doxygen/doxyxml/doxyindex.py @@ -1,22 +1,11 @@ # # Copyright 2010 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-limesdr # -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. +# SPDX-License-Identifier: GPL-3.0-or-later # -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. # """ Classes providing more user-friendly interfaces to the doxygen xml @@ -25,9 +14,9 @@ import os -from generated import index -from base import Base -from text import description +from .generated import index +from .base import Base +from .text import description class DoxyIndex(Base): """ @@ -43,25 +32,20 @@ def _parse(self): self._root = index.parse(os.path.join(self._xml_path, 'index.xml')) for mem in self._root.compound: converted = self.convert_mem(mem) - # For files we want the contents to be accessible directly - # from the parent rather than having to go through the file - # object. + # For files and namespaces we want the contents to be + # accessible directly from the parent rather than having + # to go through the file object. if self.get_cls(mem) == DoxyFile: if mem.name.endswith('.h'): self._members += converted.members() self._members.append(converted) + elif self.get_cls(mem) == DoxyNamespace: + self._members += converted.members() + self._members.append(converted) else: self._members.append(converted) -def generate_swig_doc_i(self): - """ - %feature("docstring") gr_make_align_on_samplenumbers_ss::align_state " - Wraps the C++: gr_align_on_samplenumbers_ss::align_state"; - """ - pass - - class DoxyCompMem(Base): @@ -80,13 +64,29 @@ def set_descriptions(self, parse_data): self._data['brief_description'] = bd self._data['detailed_description'] = dd + def set_parameters(self, data): + vs = [ddc.value for ddc in data.detaileddescription.content_] + pls = [] + for v in vs: + if hasattr(v, 'parameterlist'): + pls += v.parameterlist + pis = [] + for pl in pls: + pis += pl.parameteritem + dpis = [] + for pi in pis: + dpi = DoxyParameterItem(pi) + dpi._parse() + dpis.append(dpi) + self._data['params'] = dpis + + class DoxyCompound(DoxyCompMem): pass class DoxyMember(DoxyCompMem): pass - class DoxyFunction(DoxyMember): __module__ = "gnuradio.utils.doxyxml" @@ -98,10 +98,13 @@ def _parse(self): return super(DoxyFunction, self)._parse() self.set_descriptions(self._parse_data) - self._data['params'] = [] - prms = self._parse_data.param - for prm in prms: - self._data['params'].append(DoxyParam(prm)) + self.set_parameters(self._parse_data) + if not self._data['params']: + # If the params weren't set by a comment then just grab the names. + self._data['params'] = [] + prms = self._parse_data.param + for prm in prms: + self._data['params'].append(DoxyParam(prm)) brief_description = property(lambda self: self.data()['brief_description']) detailed_description = property(lambda self: self.data()['detailed_description']) @@ -121,9 +124,39 @@ def _parse(self): self.set_descriptions(self._parse_data) self._data['declname'] = self._parse_data.declname + @property + def description(self): + descriptions = [] + if self.brief_description: + descriptions.append(self.brief_description) + if self.detailed_description: + descriptions.append(self.detailed_description) + return '\n\n'.join(descriptions) + brief_description = property(lambda self: self.data()['brief_description']) detailed_description = property(lambda self: self.data()['detailed_description']) - declname = property(lambda self: self.data()['declname']) + name = property(lambda self: self.data()['declname']) + +class DoxyParameterItem(DoxyMember): + """A different representation of a parameter in Doxygen.""" + + def _parse(self): + if self._parsed: + return + super(DoxyParameterItem, self)._parse() + names = [] + for nl in self._parse_data.parameternamelist: + for pn in nl.parametername: + names.append(description(pn)) + # Just take first name + self._data['name'] = names[0] + # Get description + pd = description(self._parse_data.get_parameterdescription()) + self._data['description'] = pd + + description = property(lambda self: self.data()['description']) + name = property(lambda self: self.data()['name']) + class DoxyClass(DoxyCompound): @@ -139,12 +172,14 @@ def _parse(self): if self._error: return self.set_descriptions(self._retrieved_data.compounddef) + self.set_parameters(self._retrieved_data.compounddef) # Sectiondef.kind tells about whether private or public. # We just ignore this for now. self.process_memberdefs() brief_description = property(lambda self: self.data()['brief_description']) detailed_description = property(lambda self: self.data()['detailed_description']) + params = property(lambda self: self.data()['params']) Base.mem_classes.append(DoxyClass) @@ -177,6 +212,16 @@ class DoxyNamespace(DoxyCompound): kind = 'namespace' + def _parse(self): + if self._parsed: + return + super(DoxyNamespace, self)._parse() + self.retrieve_data() + self.set_descriptions(self._retrieved_data.compounddef) + if self._error: + return + self.process_memberdefs() + Base.mem_classes.append(DoxyNamespace) @@ -227,11 +272,11 @@ class DoxyOther(Base): __module__ = "gnuradio.utils.doxyxml" - kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum', 'dir', 'page']) + kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum', + 'dir', 'page', 'signal', 'slot', 'property']) @classmethod def can_parse(cls, obj): return obj.kind in cls.kinds Base.mem_classes.append(DoxyOther) - diff --git a/docs/doxygen/doxyxml/generated/__init__.py b/docs/doxygen/doxyxml/generated/__init__.py old mode 100755 new mode 100644 diff --git a/docs/doxygen/doxyxml/generated/compound.py b/docs/doxygen/doxyxml/generated/compound.py old mode 100755 new mode 100644 index 1522ac2..d0b164e --- a/docs/doxygen/doxyxml/generated/compound.py +++ b/docs/doxygen/doxyxml/generated/compound.py @@ -4,14 +4,14 @@ Generated Mon Feb 9 19:08:05 2009 by generateDS.py. """ -from string import lower as str_lower + from xml.dom import minidom from xml.dom import Node import sys -import compoundsuper as supermod -from compoundsuper import MixedContainer +from . import compoundsuper as supermod +from .compoundsuper import MixedContainer class DoxygenTypeSub(supermod.DoxygenType): diff --git a/docs/doxygen/doxyxml/generated/compoundsuper.py b/docs/doxygen/doxyxml/generated/compoundsuper.py old mode 100755 new mode 100644 index 6255dda..05c4928 --- a/docs/doxygen/doxyxml/generated/compoundsuper.py +++ b/docs/doxygen/doxyxml/generated/compoundsuper.py @@ -4,9 +4,9 @@ # Generated Thu Jun 11 18:44:25 2009 by generateDS.py. # + import sys -import getopt -from string import lower as str_lower + from xml.dom import minidom from xml.dom import Node @@ -19,9 +19,9 @@ try: from generatedssuper import GeneratedsSuper -except ImportError, exp: +except ImportError as exp: - class GeneratedsSuper: + class GeneratedsSuper(object): def format_string(self, input_data, input_name=''): return input_data def format_integer(self, input_data, input_name=''): @@ -64,7 +64,7 @@ def showIndent(outfile, level): outfile.write(' ') def quote_xml(inStr): - s1 = (isinstance(inStr, basestring) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') @@ -72,7 +72,7 @@ def quote_xml(inStr): return s1 def quote_attrib(inStr): - s1 = (isinstance(inStr, basestring) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') @@ -102,7 +102,7 @@ def quote_python(inStr): return '"""%s"""' % s1 -class MixedContainer: +class MixedContainer(object): # Constants for category: CategoryNone = 0 CategoryText = 1 @@ -4221,7 +4221,7 @@ def buildAttributes(self, attrs): if attrs.get('lineno'): try: self.lineno = int(attrs.get('lineno').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (lineno): %s' % exp) if attrs.get('refkind'): self.refkind = attrs.get('refkind').value @@ -4504,12 +4504,12 @@ def buildAttributes(self, attrs): if attrs.get('endline'): try: self.endline = int(attrs.get('endline').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (endline): %s' % exp) if attrs.get('startline'): try: self.startline = int(attrs.get('startline').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (startline): %s' % exp) if attrs.get('refid'): self.refid = attrs.get('refid').value @@ -4627,17 +4627,17 @@ def buildAttributes(self, attrs): if attrs.get('bodystart'): try: self.bodystart = int(attrs.get('bodystart').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (bodystart): %s' % exp) if attrs.get('line'): try: self.line = int(attrs.get('line').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (line): %s' % exp) if attrs.get('bodyend'): try: self.bodyend = int(attrs.get('bodyend').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (bodyend): %s' % exp) if attrs.get('bodyfile'): self.bodyfile = attrs.get('bodyfile').value @@ -6778,12 +6778,12 @@ def buildAttributes(self, attrs): if attrs.get('rows'): try: self.rows = int(attrs.get('rows').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (rows): %s' % exp) if attrs.get('cols'): try: self.cols = int(attrs.get('cols').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (cols): %s' % exp) def buildChildren(self, child_, nodeName_): if child_.nodeType == Node.ELEMENT_NODE and \ @@ -7108,7 +7108,7 @@ def buildAttributes(self, attrs): if attrs.get('level'): try: self.level = int(attrs.get('level').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (level): %s' % exp) def buildChildren(self, child_, nodeName_): if child_.nodeType == Node.TEXT_NODE: @@ -8283,7 +8283,7 @@ def buildChildren(self, child_, nodeName_): """ def usage(): - print USAGE_TEXT + print(USAGE_TEXT) sys.exit(1) @@ -8339,4 +8339,3 @@ def main(): main() #import pdb #pdb.run('main()') - diff --git a/docs/doxygen/doxyxml/generated/index.py b/docs/doxygen/doxyxml/generated/index.py old mode 100755 new mode 100644 index 7a70e14..c58407d --- a/docs/doxygen/doxyxml/generated/index.py +++ b/docs/doxygen/doxyxml/generated/index.py @@ -8,9 +8,9 @@ import os import sys -import compound +from . import compound -import indexsuper as supermod +from . import indexsuper as supermod class DoxygenTypeSub(supermod.DoxygenType): def __init__(self, version=None, compound=None): diff --git a/docs/doxygen/doxyxml/generated/indexsuper.py b/docs/doxygen/doxyxml/generated/indexsuper.py old mode 100755 new mode 100644 index a991530..cc2c112 --- a/docs/doxygen/doxyxml/generated/indexsuper.py +++ b/docs/doxygen/doxyxml/generated/indexsuper.py @@ -4,9 +4,9 @@ # Generated Thu Jun 11 18:43:54 2009 by generateDS.py. # + import sys -import getopt -from string import lower as str_lower + from xml.dom import minidom from xml.dom import Node @@ -19,9 +19,9 @@ try: from generatedssuper import GeneratedsSuper -except ImportError, exp: +except ImportError as exp: - class GeneratedsSuper: + class GeneratedsSuper(object): def format_string(self, input_data, input_name=''): return input_data def format_integer(self, input_data, input_name=''): @@ -64,7 +64,7 @@ def showIndent(outfile, level): outfile.write(' ') def quote_xml(inStr): - s1 = (isinstance(inStr, basestring) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') @@ -72,7 +72,7 @@ def quote_xml(inStr): return s1 def quote_attrib(inStr): - s1 = (isinstance(inStr, basestring) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') @@ -102,7 +102,7 @@ def quote_python(inStr): return '"""%s"""' % s1 -class MixedContainer: +class MixedContainer(object): # Constants for category: CategoryNone = 0 CategoryText = 1 @@ -462,7 +462,7 @@ def buildChildren(self, child_, nodeName_): """ def usage(): - print USAGE_TEXT + print(USAGE_TEXT) sys.exit(1) @@ -520,4 +520,3 @@ def main(): main() #import pdb #pdb.run('main()') - diff --git a/docs/doxygen/doxyxml/text.py b/docs/doxygen/doxyxml/text.py old mode 100755 new mode 100644 index 629edd1..45de7a8 --- a/docs/doxygen/doxyxml/text.py +++ b/docs/doxygen/doxyxml/text.py @@ -1,22 +1,11 @@ # # Copyright 2010 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-limesdr # -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. +# SPDX-License-Identifier: GPL-3.0-or-later # -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. # """ Utilities for extracting text from generated classes. @@ -26,7 +15,7 @@ def is_string(txt): if isinstance(txt, str): return True try: - if isinstance(txt, unicode): + if isinstance(txt, str): return True except NameError: pass @@ -49,7 +38,7 @@ def description_bit(obj): elif is_string(obj): return obj else: - raise StandardError('Expecting a string or something with content, content_ or value attribute') + raise Exception('Expecting a string or something with content, content_ or value attribute') # If this bit is a paragraph then add one some line breaks. if hasattr(obj, 'name') and obj.name == 'para': result += "\n\n" diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox old mode 100755 new mode 100644 diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox old mode 100755 new mode 100644 diff --git a/docs/doxygen/pydoc_macros.h b/docs/doxygen/pydoc_macros.h new file mode 100644 index 0000000..98bf7cd --- /dev/null +++ b/docs/doxygen/pydoc_macros.h @@ -0,0 +1,19 @@ +#ifndef PYDOC_MACROS_H +#define PYDOC_MACROS_H + +#define __EXPAND(x) x +#define __COUNT(_1, _2, _3, _4, _5, _6, _7, COUNT, ...) COUNT +#define __VA_SIZE(...) __EXPAND(__COUNT(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1)) +#define __CAT1(a, b) a##b +#define __CAT2(a, b) __CAT1(a, b) +#define __DOC1(n1) __doc_##n1 +#define __DOC2(n1, n2) __doc_##n1##_##n2 +#define __DOC3(n1, n2, n3) __doc_##n1##_##n2##_##n3 +#define __DOC4(n1, n2, n3, n4) __doc_##n1##_##n2##_##n3##_##n4 +#define __DOC5(n1, n2, n3, n4, n5) __doc_##n1##_##n2##_##n3##_##n4##_##n5 +#define __DOC6(n1, n2, n3, n4, n5, n6) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6 +#define __DOC7(n1, n2, n3, n4, n5, n6, n7) \ + __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6##_##n7 +#define DOC(...) __EXPAND(__EXPAND(__CAT2(__DOC, __VA_SIZE(__VA_ARGS__)))(__VA_ARGS__)) + +#endif // PYDOC_MACROS_H \ No newline at end of file diff --git a/docs/doxygen/update_pydoc.py b/docs/doxygen/update_pydoc.py new file mode 100644 index 0000000..e6b4544 --- /dev/null +++ b/docs/doxygen/update_pydoc.py @@ -0,0 +1,346 @@ +# +# Copyright 2010-2012 Free Software Foundation, Inc. +# +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gnuradio +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +# +""" +Updates the *pydoc_h files for a module +Execute using: python update_pydoc.py xml_path outputfilename + +The file instructs Pybind11 to transfer the doxygen comments into the +python docstrings. + +""" + +import os, sys, time, glob, re, json +from argparse import ArgumentParser + +from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile +from doxyxml import DoxyOther, base + +def py_name(name): + bits = name.split('_') + return '_'.join(bits[1:]) + +def make_name(name): + bits = name.split('_') + return bits[0] + '_make_' + '_'.join(bits[1:]) + + +class Block(object): + """ + Checks if doxyxml produced objects correspond to a gnuradio block. + """ + + @classmethod + def includes(cls, item): + if not isinstance(item, DoxyClass): + return False + # Check for a parsing error. + if item.error(): + return False + friendname = make_name(item.name()) + is_a_block = item.has_member(friendname, DoxyFriend) + # But now sometimes the make function isn't a friend so check again. + if not is_a_block: + is_a_block = di.has_member(friendname, DoxyFunction) + return is_a_block + +class Block2(object): + """ + Checks if doxyxml produced objects correspond to a new style + gnuradio block. + """ + + @classmethod + def includes(cls, item): + if not isinstance(item, DoxyClass): + return False + # Check for a parsing error. + if item.error(): + return False + is_a_block2 = item.has_member('make', DoxyFunction) and item.has_member('sptr', DoxyOther) + return is_a_block2 + + +def utoascii(text): + """ + Convert unicode text into ascii and escape quotes and backslashes. + """ + if text is None: + return '' + out = text.encode('ascii', 'replace') + # swig will require us to replace blackslash with 4 backslashes + # TODO: evaluate what this should be for pybind11 + out = out.replace(b'\\', b'\\\\\\\\') + out = out.replace(b'"', b'\\"').decode('ascii') + return str(out) + + +def combine_descriptions(obj): + """ + Combines the brief and detailed descriptions of an object together. + """ + description = [] + bd = obj.brief_description.strip() + dd = obj.detailed_description.strip() + if bd: + description.append(bd) + if dd: + description.append(dd) + return utoascii('\n\n'.join(description)).strip() + +def format_params(parameteritems): + output = ['Args:'] + template = ' {0} : {1}' + for pi in parameteritems: + output.append(template.format(pi.name, pi.description)) + return '\n'.join(output) + +entry_templ = '%feature("docstring") {name} "{docstring}"' +def make_entry(obj, name=None, templ="{description}", description=None, params=[]): + """ + Create a docstring key/value pair, where the key is the object name. + + obj - a doxyxml object from which documentation will be extracted. + name - the name of the C object (defaults to obj.name()) + templ - an optional template for the docstring containing only one + variable named 'description'. + description - if this optional variable is set then it's value is + used as the description instead of extracting it from obj. + """ + if name is None: + name=obj.name() + if hasattr(obj,'_parse_data') and hasattr(obj._parse_data,'definition'): + name=obj._parse_data.definition.split(' ')[-1] + if "operator " in name: + return '' + if description is None: + description = combine_descriptions(obj) + if params: + description += '\n\n' + description += utoascii(format_params(params)) + docstring = templ.format(description=description) + + return {name: docstring} + + +def make_class_entry(klass, description=None, ignored_methods=[], params=None): + """ + Create a class docstring key/value pair. + """ + if params is None: + params = klass.params + output = {} + output.update(make_entry(klass, description=description, params=params)) + for func in klass.in_category(DoxyFunction): + if func.name() not in ignored_methods: + name = klass.name() + '::' + func.name() + output.update(make_entry(func, name=name)) + return output + + +def make_block_entry(di, block): + """ + Create class and function docstrings of a gnuradio block + """ + descriptions = [] + # Get the documentation associated with the class. + class_desc = combine_descriptions(block) + if class_desc: + descriptions.append(class_desc) + # Get the documentation associated with the make function + make_func = di.get_member(make_name(block.name()), DoxyFunction) + make_func_desc = combine_descriptions(make_func) + if make_func_desc: + descriptions.append(make_func_desc) + # Get the documentation associated with the file + try: + block_file = di.get_member(block.name() + ".h", DoxyFile) + file_desc = combine_descriptions(block_file) + if file_desc: + descriptions.append(file_desc) + except base.Base.NoSuchMember: + # Don't worry if we can't find a matching file. + pass + # And join them all together to make a super duper description. + super_description = "\n\n".join(descriptions) + # Associate the combined description with the class and + # the make function. + output = {} + output.update(make_class_entry(block, description=super_description)) + output.update(make_entry(make_func, description=super_description, + params=block.params)) + return output + +def make_block2_entry(di, block): + """ + Create class and function docstrings of a new style gnuradio block + """ + # For new style blocks all the relevant documentation should be + # associated with the 'make' method. + class_description = combine_descriptions(block) + make_func = block.get_member('make', DoxyFunction) + make_description = combine_descriptions(make_func) + description = class_description + "\n\nConstructor Specific Documentation:\n\n" + make_description + # Associate the combined description with the class and + # the make function. + output = {} + output.update(make_class_entry( + block, description=description, + ignored_methods=['make'], params=make_func.params)) + makename = block.name() + '::make' + output.update(make_entry( + make_func, name=makename, description=description, + params=make_func.params)) + return output + +def get_docstrings_dict(di, custom_output=None): + + output = {} + if custom_output: + output.update(custom_output) + + # Create docstrings for the blocks. + blocks = di.in_category(Block) + blocks2 = di.in_category(Block2) + + make_funcs = set([]) + for block in blocks: + try: + make_func = di.get_member(make_name(block.name()), DoxyFunction) + # Don't want to risk writing to output twice. + if make_func.name() not in make_funcs: + make_funcs.add(make_func.name()) + output.update(make_block_entry(di, block)) + except block.ParsingError: + sys.stderr.write('Parsing error for block {0}\n'.format(block.name())) + raise + + for block in blocks2: + try: + make_func = block.get_member('make', DoxyFunction) + make_func_name = block.name() +'::make' + # Don't want to risk writing to output twice. + if make_func_name not in make_funcs: + make_funcs.add(make_func_name) + output.update(make_block2_entry(di, block)) + except block.ParsingError: + sys.stderr.write('Parsing error for block {0}\n'.format(block.name())) + raise + + # Create docstrings for functions + # Don't include the make functions since they have already been dealt with. + funcs = [f for f in di.in_category(DoxyFunction) + if f.name() not in make_funcs and not f.name().startswith('std::')] + for f in funcs: + try: + output.update(make_entry(f)) + except f.ParsingError: + sys.stderr.write('Parsing error for function {0}\n'.format(f.name())) + + # Create docstrings for classes + block_names = [block.name() for block in blocks] + block_names += [block.name() for block in blocks2] + klasses = [k for k in di.in_category(DoxyClass) + if k.name() not in block_names and not k.name().startswith('std::')] + for k in klasses: + try: + output.update(make_class_entry(k)) + except k.ParsingError: + sys.stderr.write('Parsing error for class {0}\n'.format(k.name())) + + # Docstrings are not created for anything that is not a function or a class. + # If this excludes anything important please add it here. + + return output + +def sub_docstring_in_pydoc_h(pydoc_files, docstrings_dict, output_dir, filter_str=None): + if filter_str: + docstrings_dict = {k: v for k, v in docstrings_dict.items() if k.startswith(filter_str)} + + with open(os.path.join(output_dir,'docstring_status'),'w') as status_file: + + for pydoc_file in pydoc_files: + if filter_str: + filter_str2 = "::".join((filter_str,os.path.split(pydoc_file)[-1].split('_pydoc_template.h')[0])) + docstrings_dict2 = {k: v for k, v in docstrings_dict.items() if k.startswith(filter_str2)} + else: + docstrings_dict2 = docstrings_dict + + + + file_in = open(pydoc_file,'r').read() + for key, value in docstrings_dict2.items(): + file_in_tmp = file_in + try: + doc_key = key.split("::") + # if 'gr' in doc_key: + # doc_key.remove('gr') + doc_key = '_'.join(doc_key) + regexp = r'(__doc_{} =\sR\"doc\()[^)]*(\)doc\")'.format(doc_key) + regexp = re.compile(regexp, re.MULTILINE) + + (file_in, nsubs) = regexp.subn(r'\1'+value+r'\2', file_in, count=1) + if nsubs == 1: + status_file.write("PASS: " + pydoc_file + "\n") + except KeyboardInterrupt: + raise KeyboardInterrupt + except: # be permissive, TODO log, but just leave the docstring blank + status_file.write("FAIL: " + pydoc_file + "\n") + file_in = file_in_tmp + + output_pathname = os.path.join(output_dir, os.path.basename(pydoc_file).replace('_template.h','.h')) + # FIXME: Remove this debug print + print('output docstrings to {}'.format(output_pathname)) + with open(output_pathname,'w') as file_out: + file_out.write(file_in) + +def copy_docstring_templates(pydoc_files, output_dir): + with open(os.path.join(output_dir,'docstring_status'),'w') as status_file: + for pydoc_file in pydoc_files: + file_in = open(pydoc_file,'r').read() + output_pathname = os.path.join(output_dir, os.path.basename(pydoc_file).replace('_template.h','.h')) + # FIXME: Remove this debug print + print('copy docstrings to {}'.format(output_pathname)) + with open(output_pathname,'w') as file_out: + file_out.write(file_in) + status_file.write("DONE") + +def argParse(): + """Parses commandline args.""" + desc='Scrape the doxygen generated xml for docstrings to insert into python bindings' + parser = ArgumentParser(description=desc) + + parser.add_argument("function", help="Operation to perform on docstrings", choices=["scrape","sub","copy"]) + + parser.add_argument("--xml_path") + parser.add_argument("--bindings_dir") + parser.add_argument("--output_dir") + parser.add_argument("--json_path") + parser.add_argument("--filter", default=None) + + return parser.parse_args() + +if __name__ == "__main__": + # Parse command line options and set up doxyxml. + args = argParse() + if args.function.lower() == 'scrape': + di = DoxyIndex(args.xml_path) + docstrings_dict = get_docstrings_dict(di) + with open(args.json_path, 'w') as fp: + json.dump(docstrings_dict, fp) + elif args.function.lower() == 'sub': + with open(args.json_path, 'r') as fp: + docstrings_dict = json.load(fp) + pydoc_files = glob.glob(os.path.join(args.bindings_dir,'*_pydoc_template.h')) + sub_docstring_in_pydoc_h(pydoc_files, docstrings_dict, args.output_dir, args.filter) + elif args.function.lower() == 'copy': + pydoc_files = glob.glob(os.path.join(args.bindings_dir,'*_pydoc_template.h')) + copy_docstring_templates(pydoc_files, args.output_dir) + + diff --git a/examples/README b/examples/README new file mode 100644 index 0000000..c012bdf --- /dev/null +++ b/examples/README @@ -0,0 +1,4 @@ +It is considered good practice to add examples in here to demonstrate the +functionality of your OOT module. Python scripts, GRC flow graphs or other +code can go here. + diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index b53ae11..e0f8082 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -18,9 +18,10 @@ # Boston, MA 02110-1301, USA. install(FILES - limesdr_source.xml - limesdr_sink.xml DESTINATION share/gnuradio/grc/blocks + limesdr_source.block.yml + limesdr_sink.block.yml + DESTINATION share/gnuradio/grc/blocks ) if(ENABLE_RFE) - install(FILES limesdr_rfe.xml DESTINATION share/gnuradio/grc/blocks) + install(FILES limesdr_rfe.block.yml DESTINATION share/gnuradio/grc/blocks) endif() \ No newline at end of file diff --git a/grc/limesdr_rfe.block.yml b/grc/limesdr_rfe.block.yml new file mode 100644 index 0000000..59c7d13 --- /dev/null +++ b/grc/limesdr_rfe.block.yml @@ -0,0 +1,172 @@ +# auto-generated by grc.converter + +id: limesdr_rfe +label: LimeRFE Control +category: '[LimeSuite]' + +parameters: +- id: comm_type + label: Communication + dtype: int + default: '0' + options: ['0', '1'] + option_labels: [Direct USB, SDR] +- id: com_port + label: USB COM Port + dtype: string + hide: ${ 'part' if comm_type == 0 else 'all' } +- id: sdr_serial + label: SDR Device Serial + dtype: string + hide: ${ 'part' if comm_type == 1 else 'all' } +- id: filename + label: Configuration File + category: Advanced + dtype: file_open + hide: part +- id: fan + label: Enable Fan + dtype: int + default: '0' + options: ['0', '1'] + option_labels: ['False', 'True'] + hide: part +- id: mode + label: Mode + dtype: int + default: '0' + options: ['0', '1', '3', '2'] + option_labels: [RX, TX, RX+TX, NONE] +- id: rx_channel + label: RX Channel + dtype: int + default: '1' + options: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', + '14', '15', '16', '-2'] + option_labels: [Wideband 1-1000, Wideband 1000-4000, HAM 30, HAM 50-70, HAM 144-146, + HAM 220-225, HAM 430-440, HAM 902-928, HAM 1240-1325, HAM 2300-2450, HAM 3300-3500, + Cellular Band 1, Cellular Band 2/PCS-1900, Cellular Band 3/PCS-1800, Cellular + Band 7, Cellular Band 38, Auto] +- id: rx_port + label: RX Port + dtype: int + default: '1' + options: ['1', '3'] + option_labels: [TX/RX(J3), 30 MHz TX/RX(J5)] +- id: atten + label: RX Attenuation(dB) + dtype: int + default: '0' + options: ['0', '1', '2', '3', '4', '5', '6', '7'] + option_labels: ['0', '2', '4', '6', '8', '10', '12', '14'] + hide: part +- id: notch + label: AM FM Notch Filter + dtype: int + default: '0' + options: ['0', '1'] + option_labels: [Disabled, Enabled] + hide: part +- id: tx_channel + label: TX Channel + dtype: int + default: '1' + options: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '-2'] + option_labels: [Wideband 1-1000, Wideband 1000-4000, HAM 30, HAM 50-70, HAM 144-146, + HAM 220-225, HAM 430-440, HAM 902-928, HAM 1240-1325, HAM 2300-2450, HAM 3300-3500, + Auto] + hide: ${ 'all' if rx_channel > 11 else 'none' } +- id: tx_port + label: TX Port + dtype: int + default: '1' + options: ['1', '2', '3'] + option_labels: [TX/RX(J3), TX (J4), 30 MHz TX/RX(J5)] + +templates: + imports: import limesdr + make: |- + limesdr.rfe(${comm_type}, + % if comm_type == 0: + ${com_port}, + % else: + ${sdr_serial}, + % endif + ${filename}, ${rx_channel}, ${tx_channel}, ${rx_port}, ${tx_port}, ${mode}, ${notch}, ${atten}) + callbacks: + - change_mode(${mode}) + - set_attenuation(${atten}) + - set_notch(${notch}) + - set_fan(${fan}) + +documentation: |- + ------------------------------------------------------------------------------------------------------------------- + COMMUNICATION + + Type of communication used to configure LimeRFE board. + Direct USB: LimeRFE is configured directly through USB COM port + SDR: LimeRFE is configured through LimeSDR device GPIO ports + + ------------------------------------------------------------------------------------------------------------------- + USB COM PORT + + Specified USB COM Port device is connected to e.g. /dev/ttyUSB0 on linux or COM0 on windows + ------------------------------------------------------------------------------------------------------------------- + SDR DEVICE SERIAL + + SDR Device serial number obtained by running + + LimeUtil --find + + If left blank, the first device in the list will be used to configure LimeRFE board + ------------------------------------------------------------------------------------------------------------------- + ENABLE FAN + + Enable or disable fan connected to LimeRFE device + ------------------------------------------------------------------------------------------------------------------- + MODE + + Select LimeRFE mode to be used, valid values are: RX(0), TX(1), RX+TX(2), NONE(3) + + ------------------------------------------------------------------------------------------------------------------- + RX CHANNEL + + Select RX channel to be configured, if Cellular Bands are selected, the same channel is set for TX + + ------------------------------------------------------------------------------------------------------------------- + RX PORT + + Select hardware port to be used for receive + + ------------------------------------------------------------------------------------------------------------------- + RX ATTENUATION + + Specifies the attenuation in the RX path. Attenuation [dB] = 2 * attenuation. + Valid value range is [0,7] + + ------------------------------------------------------------------------------------------------------------------- + AM FM NOTCH FILTER + + Enables or disables AM FM notch filter + + Note: Only works for specific channels(see block diagram of LimeRFE) + + ------------------------------------------------------------------------------------------------------------------- + TX CHANNEL + + Select TX channel to be configured + + ------------------------------------------------------------------------------------------------------------------- + TX PORT + + Select hardware port to be used for transmit + ------------------------------------------------------------------------------------------------------------------- + CONFIGURATION FILE + + This setting is available in "Advanced" tab of grc block. + If set LimeRFE device will be configured using already generated .ini file + + Note: .ini file must be generated using LimeSuite->Modules->LimeRFE->save, general LimeSuite .ini file will not work + ------------------------------------------------------------------------------------------------------------------- + +file_format: 1 diff --git a/grc/limesdr_sink.block.yml b/grc/limesdr_sink.block.yml new file mode 100644 index 0000000..70467c4 --- /dev/null +++ b/grc/limesdr_sink.block.yml @@ -0,0 +1,323 @@ +# auto-generated by grc.converter + +id: limesdr_sink +label: LimeSuite Sink (TX) +category: '[LimeSuite]' +flags: +- throttle + +parameters: +- id: serial + label: Device Serial + dtype: string + hide: none +- id: filename + label: File + category: Advanced + dtype: file_open +- id: channel_mode + label: Channel + dtype: int + default: '0' + options: ['0', '1', '2'] + option_labels: [A, B, A+B (MIMO)] + hide: part +- id: rf_freq + label: RF Frequency + dtype: float + default: 100e6 +- id: samp_rate + label: Sample Rate + dtype: float + default: samp_rate + hide: ${ 'all' if filename != "" else 'none' } +- id: oversample + label: Oversample + dtype: int + default: '0' + options: ['0', '1', '2', '4', '8', '16', '32'] + option_labels: [Default, '1', '2', '4', '8', '16', '32'] + hide: ${ 'all' if filename != "" else 'none' } +- id: dacVal + label: DAC Value (TCXO) + dtype: int + default: '125' + hide: ${ 'all' if allow_tcxo_dac == 0 else 'none' } +- id: length_tag_name + label: Length Tag Name + dtype: string + hide: none +- id: nco_freq_ch0 + label: NCO Frequency + category: Channel A + dtype: float + default: '0' + hide: ${ 'all' if channel_mode == 1 else 'none' } +- id: calibr_bandw_ch0 + label: Calibration BW + category: Channel A + dtype: float + default: 5e6 + hide: ${ 'all' if channel_mode == 1 or filename != "" else 'none' } +- id: pa_path_ch0 + label: PA Path + category: Channel A + dtype: int + default: '255' + options: ['255', '1', '2'] + option_labels: [Auto (Default), Band 1, Band 2] + hide: ${ 'all' if channel_mode == 1 else 'none' } +- id: analog_bandw_ch0 + label: Analog Filter BW + category: Channel A + dtype: float + default: 5e6 + hide: ${ 'all' if channel_mode == 1 else 'none' } +- id: digital_bandw_ch0 + label: Digital Filter BW + category: Channel A + dtype: float + default: '0' + hide: ${ 'all' if channel_mode == 1 else 'none' } +- id: gain_dB_ch0 + label: Gain (dB) + category: Channel A + dtype: int + default: '30' + hide: ${ 'all' if channel_mode == 1 else 'none' } +- id: nco_freq_ch1 + label: NCO Frequency + category: Channel B + dtype: float + default: '0' + hide: ${ 'all' if channel_mode == 0 else 'none' } +- id: calibr_bandw_ch1 + label: Calibration BW + category: Channel B + dtype: float + default: 5e6 + hide: ${ 'all' if channel_mode == 0 or filename != "" else 'none' } +- id: pa_path_ch1 + label: PA Path + category: Channel B + dtype: int + default: '1' + options: ['1', '2'] + option_labels: [Band 1, Band 2] + hide: ${ 'all' if channel_mode == 0 else 'none' } +- id: analog_bandw_ch1 + label: Analog Filter BW + category: Channel B + dtype: float + default: 5e6 + hide: ${ 'all' if channel_mode == 0 else 'none' } + +- id: digital_bandw_ch1 + label: Digital Filter BW + category: Channel B + dtype: float + default: '0' + hide: ${ 'all' if channel_mode == 0 else 'none' } +- id: gain_dB_ch1 + label: Gain (dB) + category: Channel B + dtype: int + default: '30' + hide: ${ 'all' if channel_mode == 0 else 'none' } +- id: allow_tcxo_dac + label: Allow TCXO DAC Control + category: Advanced + dtype: int + default: '0' + options: ['1', '0'] + option_labels: ['Yes', 'No'] + hide: part + +inputs: +- domain: stream + dtype: complex + multiplicity: ${ channel_mode } +asserts: +- ${ channel_mode >= 0 } +- ${ 2 >= channel_mode } +- ${ rf_freq > 0 } +- ${ calibr_bandw_ch0 >= 2.5e6 or calibr_bandw_ch0 == 0 } +- ${ 120e6 >= calibr_bandw_ch0 } +- ${ calibr_bandw_ch1 >= 2.5e6 or calibr_bandw_ch1 == 0 } +- ${ 120e6 >= calibr_bandw_ch1 } +- ${ analog_bandw_ch0 >= 5e6 or analog_bandw_ch0 == 0 } +- ${ 130e6 >= analog_bandw_ch0 } +- ${ analog_bandw_ch1 >= 5e6 or analog_bandw_ch1 == 0 } +- ${ 130e6 >= analog_bandw_ch1 } +- ${ digital_bandw_ch0 >= 0 } +- ${ samp_rate >= digital_bandw_ch0 or digital_bandw_ch0 == 0 } +- ${ digital_bandw_ch1 >= 0 } +- ${ samp_rate >= digital_bandw_ch1 or digital_bandw_ch1 == 0 } +- ${ gain_dB_ch0 >= 0 } +- ${ 73 >= gain_dB_ch0 } +- ${ gain_dB_ch1 >= 0 } +- ${ 73 >= gain_dB_ch1 } +- ${ samp_rate > 0 } +- ${ 61.44e6 >= samp_rate } + +templates: + imports: import limesdr + make: |- + limesdr.sink(${serial}, ${channel_mode}, ${filename}, ${length_tag_name}) + % if filename == "": + self.${id}.set_sample_rate(${samp_rate}) + % if oversample > 0: + self.${id}.set_oversampling(${oversample}) + % endif + self.${id}.set_center_freq(${rf_freq}, 0) + % if analog_bandw_ch0 > 0 and (channel_mode == 0 or channel_mode == 2): + self.${id}.set_bandwidth(${analog_bandw_ch0},0) + % endif + % if analog_bandw_ch1 > 0 and channel_mode > 0: + self.${id}.set_bandwidth(${analog_bandw_ch1},1) + % endif + % if digital_bandw_ch0 > 0 and (channel_mode == 0 or channel_mode == 2): + self.${id}.set_digital_filter(${digital_bandw_ch0},0) + % endif + % if digital_bandw_ch1 > 0 and channel_mode > 0: + self.${id}.set_digital_filter(${digital_bandw_ch1},1) + % endif + % if channel_mode == 0 or channel_mode == 2: + self.${id}.set_gain(${gain_dB_ch0},0) + % endif + % if channel_mode > 0: + self.${id}.set_gain(${gain_dB_ch1},1) + % endif + % if channel_mode == 0 or channel_mode == 2: + self.${id}.set_antenna(${pa_path_ch0},0) + % endif + % if channel_mode > 0: + self.${id}.set_antenna(${pa_path_ch1},1) + % endif + % if calibr_bandw_ch0 > 0 and (channel_mode == 0 or channel_mode == 2): + self.${id}.calibrate(${calibr_bandw_ch0}, 0) + % endif + % if calibr_bandw_ch1 > 0 and channel_mode > 0: + self.${id}.calibrate(${calibr_bandw_ch1}, 1) + % endif + % if nco_freq_ch0 != 0 and (channel_mode == 0 or channel_mode == 2): + self.${id}.set_nco(${nco_freq_ch0},0) + % endif + % if nco_freq_ch1 != 0 and channel_mode > 0: + self.${id}.set_nco(${nco_freq_ch1},1) + % endif + % endif + % if allow_tcxo_dac == 1: + self.${id}.set_tcxo_dac(${dacVal}) + % end if + callbacks: + - set_center_freq(${rf_freq}, 0) + - set_antenna(${pa_path_ch0},0) + - set_antenna(${pa_path_ch1},1) + - set_nco(${nco_freq_ch0},0) + - set_nco(${nco_freq_ch1},1) + - set_bandwidth(${analog_bandw_ch0},0) + - set_bandwidth(${analog_bandw_ch1},1) + - set_digital_filter(${digital_bandw_ch0},0) + - set_digital_filter(${digital_bandw_ch1},1) + - set_gain(${gain_dB_ch0},0) + - set_gain(${gain_dB_ch1},1) + - set_tcxo_dac(${dacVal}) + +documentation: |- + ------------------------------------------------------------------------------------------------------------------- + DEVICE SERIAL + + Device serial number obtained by running + + LimeUtil --find + + If left blank, the first device in the list is used. + ------------------------------------------------------------------------------------------------------------------- + CHANNEL + + Use this setting to choose between SISO channels or MIMO mode. + + Note: not all devices support MIMO mode and have more than one channel. + ------------------------------------------------------------------------------------------------------------------- + RF FREQUENCY + + Set RF center frequency for TX (both channels). + LimeSDR-USB supports [100e3,3800e6] Hz. + LimeSDR-PCIe supports [100e3,3800e6] Hz. + LimeSDR-Mini supports [10e6,3500e6] Hz. + LimeNET-Micro supports [10e6,3500e6] Hz. + ------------------------------------------------------------------------------------------------------------------- + SAMPLE RATE + + Here you can enter sample rate for TX. + + LimeSDR-USB sample rate must be no more than 61.44e6 S/s. + LimeSDR-PCIe sample rate must be no more than 61.44e6 S/s. + LimeSDR-Mini sample rate must be no more than 30.72e6 S/s. + LimeNET-Micro sample rate must be no more than 10e6 S/s. + + Note: LimeSDR-Mini and LimeNET-Micro supports only the same sample rate for TX and RX. + ------------------------------------------------------------------------------------------------------------------- + OVERSAMPLE + + Here you can select oversampling value for TX. Default value uses highest possible oversampling value. + + Note: LimeSDR-Mini and LimeNET-Micro supports only the same oversampling value for TX and RX. + ------------------------------------------------------------------------------------------------------------------- + Length tag name + + Set name of stream tag with which number of samples sent is set. + ------------------------------------------------------------------------------------------------------------------- + NCO FREQUENCY + + Adjust numerically controlled oscillator for each channel. 0 means that NCO is OFF. + ------------------------------------------------------------------------------------------------------------------- + CALIBRATION BANDW. + + This setting is used to set bandwidth for calibration for each channel. This value should be equal to your signal bandwidth. + Calibration is off when bandwidth is set to 0. + + Calibration bandwidth range must be [2.5e6,120e6] Hz. + ------------------------------------------------------------------------------------------------------------------- + PA PATH + + Select active power amplifier path of each channel. + For LimeSDR-Mini and LimeNET-Micro Auto(Default) option sets preferred PA path depending on RF frequency. + For LimeSDR-USB and LimeSDR-PCIe Auto(Default) sets PA path to Band1. + ------------------------------------------------------------------------------------------------------------------- + ANALOG FILTER BANDW. + + Enter analog filter bandwidth for each channel. Analog filter is off if bandwidth is set to 0. + Analog filter bandwidth range must be [5e6,130e6] Hz. + ------------------------------------------------------------------------------------------------------------------- + DIGITAL FILTER BANDW. + + Enter digital filter bandwidth for each channel. Digital filter if off if bandwidth is set to 0. + Bandwidth should not be higher than sample rate. + ------------------------------------------------------------------------------------------------------------------- + GAIN + + Controls combined TX gain settings. Gain range must be [0,73] dB. + ------------------------------------------------------------------------------------------------------------------- + FILE + + This setting is available in "Advanced" tab of grc block. + Use .ini file generated by LimeSuiteGUI to configure the device. + RF frequency, sampling rate, oversampling, filters, gain and antenna settings won't be used from GRC blocks when + device is started. Runtime variables(RF frequency, gain...) can still be modified when flowgraph is running. + + Note: setting must match in LimeSuite Source and Sink for the same device. + ------------------------------------------------------------------------------------------------------------------- + TCXO DAC + + Controls 40 MHz TCXO DAC settings. To enable this parameter "Allow TCXO DAC control" in the "Advanced" tab must be set to "Yes" + Care must be taken as this parameter is returned to default value only after power off. + + LimeSDR-Mini default value is 180 range is [0,255] + LimeSDR-USB default value is 125 range is [0,255] + LimeSDR-PCIe default value is 134 range is [0,255] + LimeNET-Micro default value is 30714 range is [0,65535] + ------------------------------------------------------------------------------------------------------------------- + +file_format: 1 diff --git a/grc/limesdr_source.block.yml b/grc/limesdr_source.block.yml new file mode 100644 index 0000000..5be9386 --- /dev/null +++ b/grc/limesdr_source.block.yml @@ -0,0 +1,314 @@ +# auto-generated by grc.converter + +id: limesdr_source +label: LimeSuite Source (RX) +category: '[LimeSuite]' +flags: +- throttle + +parameters: +- id: serial + label: Device Serial + dtype: string + hide: none +- id: filename + label: File + category: Advanced + dtype: file_open +- id: channel_mode + label: Channel + dtype: int + default: '0' + options: ['0', '1', '2'] + option_labels: [A, B, A+B (MIMO)] + hide: part +- id: rf_freq + label: RF Frequency + dtype: float + default: 100e6 +- id: samp_rate + label: Sample Rate + dtype: float + default: samp_rate + hide: ${ 'all' if filename != "" else 'none' } +- id: oversample + label: Oversample + dtype: int + default: '0' + options: ['0', '1', '2', '4', '8', '16', '32'] + option_labels: [Default, '1', '2', '4', '8', '16', '32'] + hide: ${ 'all' if filename != "" else 'none' } +- id: dacVal + label: TCXO DAC Value + dtype: int + default: '125' + hide: ${ 'all' if allow_tcxo_dac == 0 else 'none' } +- id: nco_freq_ch0 + label: NCO Frequency + category: Channel A + dtype: float + default: '0' + hide: ${ 'all' if channel_mode == 1 else 'none' } +- id: calibr_bandw_ch0 + label: Calibration BW + category: Channel A + dtype: float + default: 5e6 + hide: ${ 'all' if filename != "" or channel_mode == 1 else 'none' } +- id: lna_path_ch0 + label: LNA Path + category: Channel A + dtype: int + default: '255' + options: ['255', '1', '2', '3'] + option_labels: [Auto(Default), H, L, W] + hide: ${ 'all' if channel_mode == 1 else 'none' } +- id: analog_bandw_ch0 + label: Analog Filter BW + category: Channel A + dtype: float + default: 5e6 + hide: ${ 'all' if channel_mode == 1 else 'none' } +- id: digital_bandw_ch0 + label: Digital Filter BW + category: Channel A + dtype: float + default: '0' + hide: ${ 'all' if channel_mode == 1 else 'none' } +- id: gain_dB_ch0 + label: Gain (dB) + category: Channel A + dtype: int + default: '30' + hide: ${ 'all' if channel_mode == 1 else 'none' } +- id: nco_freq_ch1 + label: NCO Frequency + category: Channel B + dtype: float + default: '0' + hide: ${ 'all' if channel_mode == 0 else 'none' } +- id: calibr_bandw_ch1 + label: Calibration BW + category: Channel B + dtype: float + default: 5e6 + hide: ${ 'all' if filename != "" or channel_mode == 0 else 'none' } +- id: lna_path_ch1 + label: LNA Path + category: Channel B + dtype: int + default: '2' + options: ['1', '2', '3'] + option_labels: [H, L, W] + hide: ${ 'all' if channel_mode == 0 else 'none' } +- id: analog_bandw_ch1 + label: Analog Filter BW + category: Channel B + dtype: float + default: 5e6 + hide: ${ 'all' if channel_mode == 0 else 'none' } +- id: digital_bandw_ch1 + label: Digital Filter BW + category: Channel B + dtype: float + default: '0' + hide: ${ 'all' if channel_mode == 0 else 'none' } +- id: gain_dB_ch1 + label: Gain (dB) + category: Channel B + dtype: int + default: '30' + hide: ${ 'all' if channel_mode == 0 else 'none' } +- id: allow_tcxo_dac + label: Allow TCXO DAC Control + category: Advanced + dtype: int + default: '0' + options: ['1', '0'] + option_labels: ['Yes', 'No'] + hide: part + +outputs: +- domain: stream + dtype: complex + multiplicity: ${ channel_mode } +asserts: +- ${ channel_mode >= 0 } +- ${ 2 >= channel_mode } +- ${ rf_freq > 0 } +- ${ calibr_bandw_ch0 >= 2.5e6 or calibr_bandw_ch0 == 0 } +- ${ 120e6 >= calibr_bandw_ch0 } +- ${ calibr_bandw_ch1 >= 2.5e6 or calibr_bandw_ch1 == 0 } +- ${ 120e6 >= calibr_bandw_ch1 } +- ${ analog_bandw_ch0 >= 1.5e6 or analog_bandw_ch0 == 0 } +- ${ 130e6 >= analog_bandw_ch0 } +- ${ analog_bandw_ch1 >= 1.5e6 or analog_bandw_ch1 == 0 } +- ${ 130e6 >= analog_bandw_ch1 } +- ${ digital_bandw_ch0 >= 0 } +- ${ samp_rate >= digital_bandw_ch0 or digital_bandw_ch0 == 0 } +- ${ digital_bandw_ch1 >= 0 } +- ${ samp_rate >= digital_bandw_ch1 or digital_bandw_ch0 == 0 } +- ${ gain_dB_ch0 >= 0 } +- ${ 73 >= gain_dB_ch0 } +- ${ gain_dB_ch1 >= 0 } +- ${ 73 >= gain_dB_ch1 } +- ${ samp_rate > 0 } +- ${ 61.44e6 >= samp_rate } + +templates: + imports: import limesdr + make: |- + limesdr.source(${serial}, ${channel_mode}, ${filename}) + % if filename == "": + self.${id}.set_sample_rate(${samp_rate}) + % if oversample > 0: + self.${id}.set_oversampling(${oversample}) + % endif + self.${id}.set_center_freq(${rf_freq}, 0) + % if analog_bandw_ch0 > 0 and (channel_mode == 0 or channel_mode == 2): + self.${id}.set_bandwidth(${analog_bandw_ch0}, 0) + % endif + % if analog_bandw_ch1 > 0 and channel_mode > 0: + self.${id}.set_bandwidth(${analog_bandw_ch1}, 1) + % endif + % if digital_bandw_ch0 > 0 and (channel_mode == 0 or channel_mode == 2): + self.${id}.set_digital_filter(${digital_bandw_ch0},0) + % endif + % if digital_bandw_ch1 > 0 and channel_mode > 0: + self.${id}.set_digital_filter(${digital_bandw_ch1},1) + % endif + % if channel_mode == 0 or channel_mode == 2: + self.${id}.set_gain(${gain_dB_ch0},0) + % endif + % if channel_mode > 0: + self.${id}.set_gain(${gain_dB_ch1},1) + % endif + % if channel_mode == 0 or channel_mode == 2: + self.${id}.set_antenna(${lna_path_ch0},0) + % endif + % if channel_mode > 0: + self.${id}.set_antenna(${lna_path_ch1},1) + % endif + % if calibr_bandw_ch0 > 0 and (channel_mode == 0 or channel_mode == 2): + self.${id}.calibrate(${calibr_bandw_ch0}, 0) + % endif + % if calibr_bandw_ch1 > 0 and channel_mode > 0: + self.${id}.calibrate(${calibr_bandw_ch1}, 1) + % endif + % if nco_freq_ch0 != 0 and (channel_mode == 0 or channel_mode == 2): + self.${id}.set_nco(${nco_freq_ch0},0) + % endif + % if nco_freq_ch1 != 0 and channel_mode > 0: + self.${id}.set_nco(${nco_freq_ch1},1) + % endif + % endif + % if allow_tcxo_dac == 1: + self.${id}.set_tcxo_dac(${dacVal}) + % endif + callbacks: + - set_center_freq(${rf_freq}, 0) + - set_antenna(${lna_path_ch0},0) + - set_antenna(${lna_path_ch1},1) + - set_nco(${nco_freq_ch0},0) + - set_nco(${nco_freq_ch1},1) + - set_bandwidth(${analog_bandw_ch0},0) + - set_bandwidth(${analog_bandw_ch1},1) + - set_digital_filter(${digital_bandw_ch0},0) + - set_digital_filter(${digital_bandw_ch1},1) + - set_gain(${gain_dB_ch0},0) + - set_gain(${gain_dB_ch1},1) + - set_tcxo_dac(${dacVal}) + +documentation: |- + ------------------------------------------------------------------------------------------------------------------- + DEVICE SERIAL + + Device serial number obtained by running + + LimeUtil --find + + If left blank, the first device in the list is used. + ------------------------------------------------------------------------------------------------------------------- + CHANNEL + + Use this setting to choose between SISO channels or MIMO mode. + + Note: not all devices support MIMO mode and have more than one channel. + ------------------------------------------------------------------------------------------------------------------- + RF FREQUENCY + + Set RF center frequency for RX (both channels). + LimeSDR-USB supports [100e3,3800e6] Hz. + LimeSDR-PCIe supports [100e3,3800e6] Hz. + LimeSDR-Mini supports [10e6,3500e6] Hz. + LimeSDR-Micro supports [10e6,3500e6] Hz. + ------------------------------------------------------------------------------------------------------------------- + SAMPLE RATE + + Here you can enter sample rate for RX. + + LimeSDR-USB sample rate must be no more than 61.44e6 S/s. + LimeSDR-PCIe sample rate must be no more than 61.44e6 S/s. + LimeSDR-Mini sample rate must be no more than 30.72e6 S/s. + LimeSDR-Micro sample rate must be no more than 10e6 S/s. + + Note: LimeSDR-Mini and LimeSDR-Micro supports only the same sample rate for TX and RX. + ------------------------------------------------------------------------------------------------------------------- + OVERSAMPLE + + Here you can select oversampling value for RX. Default value uses highest possible oversampling value. + + Note: LimeSDR-Mini and LimeSDR-Micro supports only the same oversampling value for TX and RX. + ------------------------------------------------------------------------------------------------------------------- + NCO FREQUENCY + + Adjust numerically controlled oscillator for each channel. 0 means that NCO is OFF. + ------------------------------------------------------------------------------------------------------------------- + CALIBRATION BANDW. + + This setting is used to set bandwidth for calibration for each channel. This value should be equal to your signal bandwidth. + Calibration is off when bandwidth is set to 0. + + Calibration bandwidth range must be [2.5e6,120e6] Hz. + ------------------------------------------------------------------------------------------------------------------- + LNA PATH + + Select active low-noise amplifier path of each channel. + For LimeSDR-Mini and LimeNET-Micro Auto(Default) option sets preferred LNA path depending on RF frequency. + For LimeSDR-USB and LimeSDR-PCIe Auto(Default) sets LNA path to LNAL. + ------------------------------------------------------------------------------------------------------------------- + ANALOG FILTER BANDW. + + Enter analog filter bandwidth for each channel. Analog filter is off if bandwidth is set to 0. + Analog filter bandwidth range must be [1.5e6,130e6] Hz. + ------------------------------------------------------------------------------------------------------------------- + DIGITAL FILTER BANDW. + + Enter digital filter bandwidth for each channel. Digital filter if off if bandwidth is set to 0. + Bandwidth should not be higher than sample rate. + ------------------------------------------------------------------------------------------------------------------- + GAIN + + Controls combined RX gain settings. Gain range must be [0,73] dB. + ------------------------------------------------------------------------------------------------------------------- + FILE + + This setting is available in "Advanced" tab of grc block. + Use .ini file generated by LimeSuiteGUI to configure the device. + RF frequency, sampling rate, oversampling, filters, gain and antenna settings won't be used from GRC blocks when + device is started. Runtime variables(RF frequency, gain...) can still be modified when flowgraph is running. + + Note: setting must match in LimeSuite Source and Sink for the same device. + ------------------------------------------------------------------------------------------------------------------- + TCXO DAC + + Controls 40 MHz TCXO DAC settings. To enable this parameter "Allow TCXO DAC control" in the "Advanced" tab must be set to "Yes" + Care must be taken as this parameter is returned to default value only after power off. + + LimeSDR-Mini default value is 180 range is [0,255] + LimeSDR-USB default value is 125 range is [0,255] + LimeSDR-PCIe default value is 134 range is [0,255] + LimeNET-Micro default value is 30714 range is [0,65535] + ------------------------------------------------------------------------------------------------------------------- + +file_format: 1 diff --git a/include/limesdr/CMakeLists.txt b/include/limesdr/CMakeLists.txt old mode 100755 new mode 100644 index 34bde9c..79db477 --- a/include/limesdr/CMakeLists.txt +++ b/include/limesdr/CMakeLists.txt @@ -1,29 +1,18 @@ # Copyright 2011,2012 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-limesdr # -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. +# SPDX-License-Identifier: GPL-3.0-or-later # -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. ######################################################################## # Install public header files ######################################################################## install(FILES api.h + sink.h source.h - sink.h DESTINATION include/limesdr ) if(ENABLE_RFE) diff --git a/include/limesdr/api.h b/include/limesdr/api.h old mode 100755 new mode 100644 index c7bd9fd..82d99e3 --- a/include/limesdr/api.h +++ b/include/limesdr/api.h @@ -1,21 +1,11 @@ -/* -*- c++ -*- */ /* - * Copyright 2018 Lime Microsystems info@limemicro.com + * Copyright 2011 Free Software Foundation, Inc. * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. + * This file was generated by gr_modtool, a tool from the GNU Radio framework + * This file is a part of gr-limesdr * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * SPDX-License-Identifier: GPL-3.0-or-later * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. */ #ifndef INCLUDED_LIMESDR_API_H diff --git a/include/limesdr/rfe.h b/include/limesdr/rfe.h index 7b92f00..0a63f2f 100644 --- a/include/limesdr/rfe.h +++ b/include/limesdr/rfe.h @@ -21,7 +21,7 @@ #ifndef INCLUDED_LIMERFE_H #define INCLUDED_LIMERFE_H -#include +#include #include #include #include diff --git a/include/limesdr/sink.h b/include/limesdr/sink.h index 3d86319..578dd80 100755 --- a/include/limesdr/sink.h +++ b/include/limesdr/sink.h @@ -28,7 +28,7 @@ namespace gr { namespace limesdr { class LIMESDR_API sink : virtual public gr::block { public: - typedef boost::shared_ptr sptr; + typedef std::shared_ptr sptr; /*! * @brief Return a shared_ptr to a new instance of sink. * diff --git a/include/limesdr/source.h b/include/limesdr/source.h index 27de52d..82fda31 100755 --- a/include/limesdr/source.h +++ b/include/limesdr/source.h @@ -28,7 +28,7 @@ namespace gr { namespace limesdr { class LIMESDR_API source : virtual public gr::block { public: - typedef boost::shared_ptr sptr; + typedef std::shared_ptr sptr; /*! * @brief Return a shared_ptr to a new instance of source. diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt old mode 100755 new mode 100644 index d00a1bc..81c9482 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,33 +1,16 @@ -# Copyright 2011 Free Software Foundation, Inc. +# Copyright 2011,2012,2016,2018,2019 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-limesdr # -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. +# SPDX-License-Identifier: GPL-3.0-or-later # -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. ######################################################################## # Setup library ######################################################################## include(GrPlatform) #define LIB_SUFFIX -include_directories(${Boost_INCLUDE_DIR} - ${LIMESUITE_INCLUDE_DIRS} - ${CMAKE_CURRENT_BINARY_DIR}) -link_directories(${Boost_LIBRARY_DIRS} - ${LIMESDR_PKG_LIBRARY_DIRS}) - list(APPEND limesdr_sources source_impl.cc sink_impl.cc @@ -42,31 +25,56 @@ endif() set(limesdr_sources "${limesdr_sources}" PARENT_SCOPE) if(NOT limesdr_sources) - MESSAGE(STATUS "No C++ sources... skipping lib/") - return() + MESSAGE(STATUS "No C++ sources... skipping lib/") + return() endif(NOT limesdr_sources) add_library(gnuradio-limesdr SHARED ${limesdr_sources}) -target_link_libraries( - gnuradio-limesdr - ${Boost_LIBRARIES} - ${GNURADIO_ALL_LIBRARIES} - ${LIMESUITE_LIB}) - -set_target_properties( - gnuradio-limesdr PROPERTIES DEFINE_SYMBOL "gnuradio_limesdr_EXPORTS") +target_link_libraries(gnuradio-limesdr gnuradio::gnuradio-runtime LimeSuite) +target_include_directories(gnuradio-limesdr + PUBLIC $ + PUBLIC $ + ) +set_target_properties(gnuradio-limesdr PROPERTIES DEFINE_SYMBOL "gnuradio_limesdr_EXPORTS") if(APPLE) - set_target_properties( - gnuradio-limesdr PROPERTIES - INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib") + set_target_properties(gnuradio-limesdr PROPERTIES + INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib" + ) endif(APPLE) ######################################################################## # Install built library files ######################################################################## -install(TARGETS gnuradio-limesdr - LIBRARY DESTINATION lib${LIB_SUFFIX} # .so/.dylib file - ARCHIVE DESTINATION lib${LIB_SUFFIX} # .lib file - RUNTIME DESTINATION bin # .dll file - ) +include(GrMiscUtils) +GR_LIBRARY_FOO(gnuradio-limesdr) + +######################################################################## +# Print summary +######################################################################## +message(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}") +message(STATUS "Building for version: ${VERSION} / ${LIBVER}") + +######################################################################## +# Build and register unit test +######################################################################## +include(GrTest) + +# If your unit tests require special include paths, add them here +#include_directories() +# List all files that contain Boost.UTF unit tests here +list(APPEND test_limesdr_sources +) +# Anything we need to link to for the unit tests go here +list(APPEND GR_TEST_TARGET_DEPS gnuradio-limesdr) + +if(NOT test_limesdr_sources) + MESSAGE(STATUS "No C++ unit tests... skipping") + return() +endif(NOT test_limesdr_sources) + +foreach(qa_file ${test_limesdr_sources}) + GR_ADD_CPP_TEST("limesdr_${qa_file}" + ${CMAKE_CURRENT_SOURCE_DIR}/${qa_file} + ) +endforeach(qa_file) diff --git a/lib/common/device_handler.cc b/lib/common/device_handler.cc index 89a69d3..80070fb 100755 --- a/lib/common/device_handler.cc +++ b/lib/common/device_handler.cc @@ -19,7 +19,7 @@ */ #include "device_handler.h" -#include +#include device_handler::~device_handler() { delete list; } @@ -577,4 +577,4 @@ void device_handler::update_rfe_channels() << "ERROR: device_handler::update_rfe_channels(): no assigned RFE device" << std::endl; } -} \ No newline at end of file +} diff --git a/lib/common/device_handler.h b/lib/common/device_handler.h index 55de9aa..d34756e 100755 --- a/lib/common/device_handler.h +++ b/lib/common/device_handler.h @@ -21,8 +21,8 @@ #ifndef DEVICE_HANDLER_H #define DEVICE_HANDLER_H -#include -#include +#include +#include #include #include #include diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt old mode 100755 new mode 100644 index 6ccc1f1..7a00d10 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,21 +1,10 @@ # Copyright 2011 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-limesdr # -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. +# SPDX-License-Identifier: GPL-3.0-or-later # -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. ######################################################################## # Include python install macros @@ -25,6 +14,8 @@ if(NOT PYTHONINTERP_FOUND) return() endif() +add_subdirectory(bindings) + ######################################################################## # Install python sources ######################################################################## @@ -40,4 +31,3 @@ GR_PYTHON_INSTALL( include(GrTest) set(GR_TEST_TARGET_DEPS gnuradio-limesdr) -set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig) diff --git a/python/__init__.py b/python/__init__.py old mode 100755 new mode 100644 index 218c1fb..6c22ce0 --- a/python/__init__.py +++ b/python/__init__.py @@ -1,19 +1,7 @@ # # Copyright 2008,2009 Free Software Foundation, Inc. # -# This application is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# This application is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# SPDX-License-Identifier: GPL-3.0-or-later # # The presence of this file turns this directory into a Python package @@ -22,13 +10,14 @@ This is the GNU Radio LIMESDR module. Place your Python package description here (python/__init__.py). ''' +import os -# import swig generated symbols into the limesdr namespace +# import pybind11 generated symbols into the limesdr namespace try: - # this might fail if the module is python-only - from limesdr_swig import * -except ImportError: - pass + # this might fail if the module is python-only + from .limesdr_python import * +except ModuleNotFoundError: + pass # import any pure python here # diff --git a/python/__init__.pyc b/python/__init__.pyc deleted file mode 100755 index c0244b6..0000000 Binary files a/python/__init__.pyc and /dev/null differ diff --git a/python/bindings/CMakeLists.txt b/python/bindings/CMakeLists.txt new file mode 100644 index 0000000..218be96 --- /dev/null +++ b/python/bindings/CMakeLists.txt @@ -0,0 +1,46 @@ +# Copyright 2020 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +######################################################################## +# Check if there is C++ code at all +######################################################################## +if(NOT limesdr_sources) + MESSAGE(STATUS "No C++ sources... skipping python bindings") + return() +endif(NOT limesdr_sources) + +######################################################################## +# Check for pygccxml +######################################################################## +GR_PYTHON_CHECK_MODULE_RAW( + "pygccxml" + "import pygccxml" + PYGCCXML_FOUND + ) + +include(GrPybind) + +######################################################################## +# Python Bindings +######################################################################## + +list(APPEND limesdr_python_files + sink_python.cc + source_python.cc + python_bindings.cc) + +if(ENABLE_RFE) + list(APPEND limesdr_python_files rfe_python.cc) + add_compile_definitions(ENABLE_RFE) +endif() + +GR_PYBIND_MAKE_OOT(limesdr + ../.. + gr::limesdr + "${limesdr_python_files}") + +install(TARGETS limesdr_python DESTINATION ${GR_PYTHON_DIR}/limesdr COMPONENT pythonapi) diff --git a/python/bindings/README.md b/python/bindings/README.md new file mode 100644 index 0000000..e69de29 diff --git a/python/bindings/bind_oot_file.py b/python/bindings/bind_oot_file.py new file mode 100644 index 0000000..91719f7 --- /dev/null +++ b/python/bindings/bind_oot_file.py @@ -0,0 +1,57 @@ +import warnings +import argparse +import os +from gnuradio.bindtool import BindingGenerator +import pathlib +import sys + +parser = argparse.ArgumentParser(description='Bind a GR Out of Tree Block') +parser.add_argument('--module', type=str, + help='Name of gr module containing file to bind (e.g. fft digital analog)') + +parser.add_argument('--output_dir', default='/tmp', + help='Output directory of generated bindings') +parser.add_argument('--prefix', help='Prefix of Installed GNU Radio') +parser.add_argument('--src', help='Directory of gnuradio source tree', + default=os.path.dirname(os.path.abspath(__file__))+'/../../..') + +parser.add_argument( + '--filename', help="File to be parsed") + +parser.add_argument( + '--defines', help='Set additional defines for precompiler',default=(), nargs='*') +parser.add_argument( + '--include', help='Additional Include Dirs, separated', default=(), nargs='*') + +parser.add_argument( + '--status', help='Location of output file for general status (used during cmake)', default=None +) +parser.add_argument( + '--flag_automatic', default='0' +) +parser.add_argument( + '--flag_pygccxml', default='0' +) + +args = parser.parse_args() + +prefix = args.prefix +output_dir = args.output_dir +defines = tuple(','.join(args.defines).split(',')) +includes = ','.join(args.include) +name = args.module + +namespace = ['gr', name] +prefix_include_root = name + + +with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=DeprecationWarning) + + bg = BindingGenerator(prefix, namespace, + prefix_include_root, output_dir, define_symbols=defines, addl_includes=includes, + catch_exceptions=False, write_json_output=False, status_output=args.status, + flag_automatic=True if args.flag_automatic.lower() in [ + '1', 'true'] else False, + flag_pygccxml=True if args.flag_pygccxml.lower() in ['1', 'true'] else False) + bg.gen_file_binding(args.filename) diff --git a/python/bindings/docstrings/README.md b/python/bindings/docstrings/README.md new file mode 100644 index 0000000..295455a --- /dev/null +++ b/python/bindings/docstrings/README.md @@ -0,0 +1 @@ +This directory stores templates for docstrings that are scraped from the include header files for each block \ No newline at end of file diff --git a/python/bindings/docstrings/rfe_pydoc_template.h b/python/bindings/docstrings/rfe_pydoc_template.h new file mode 100644 index 0000000..239a87a --- /dev/null +++ b/python/bindings/docstrings/rfe_pydoc_template.h @@ -0,0 +1,39 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,limesdr, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_limesdr_rfe = R"doc()doc"; + + + static const char *__doc_gr_limesdr_rfe_rfe_0 = R"doc()doc"; + + + static const char *__doc_gr_limesdr_rfe_rfe_1 = R"doc()doc"; + + + static const char *__doc_gr_limesdr_rfe_change_mode = R"doc()doc"; + + + static const char *__doc_gr_limesdr_rfe_set_fan = R"doc()doc"; + + + static const char *__doc_gr_limesdr_rfe_set_attenuation = R"doc()doc"; + + + static const char *__doc_gr_limesdr_rfe_set_notch = R"doc()doc"; + + diff --git a/python/bindings/docstrings/sink_pydoc_template.h b/python/bindings/docstrings/sink_pydoc_template.h new file mode 100644 index 0000000..4a1ecac --- /dev/null +++ b/python/bindings/docstrings/sink_pydoc_template.h @@ -0,0 +1,63 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,limesdr, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_limesdr_sink = R"doc()doc"; + + + static const char *__doc_gr_limesdr_sink_sink_0 = R"doc()doc"; + + + static const char *__doc_gr_limesdr_sink_sink_1 = R"doc()doc"; + + + static const char *__doc_gr_limesdr_sink_make = R"doc()doc"; + + + static const char *__doc_gr_limesdr_sink_set_center_freq = R"doc()doc"; + + + static const char *__doc_gr_limesdr_sink_set_antenna = R"doc()doc"; + + + static const char *__doc_gr_limesdr_sink_set_nco = R"doc()doc"; + + + static const char *__doc_gr_limesdr_sink_set_bandwidth = R"doc()doc"; + + + static const char *__doc_gr_limesdr_sink_set_digital_filter = R"doc()doc"; + + + static const char *__doc_gr_limesdr_sink_set_gain = R"doc()doc"; + + + static const char *__doc_gr_limesdr_sink_set_sample_rate = R"doc()doc"; + + + static const char *__doc_gr_limesdr_sink_set_oversampling = R"doc()doc"; + + + static const char *__doc_gr_limesdr_sink_calibrate = R"doc()doc"; + + + static const char *__doc_gr_limesdr_sink_set_buffer_size = R"doc()doc"; + + + static const char *__doc_gr_limesdr_sink_set_tcxo_dac = R"doc()doc"; + + diff --git a/python/bindings/docstrings/source_pydoc_template.h b/python/bindings/docstrings/source_pydoc_template.h new file mode 100644 index 0000000..c105b3d --- /dev/null +++ b/python/bindings/docstrings/source_pydoc_template.h @@ -0,0 +1,63 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,limesdr, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_limesdr_source = R"doc()doc"; + + + static const char *__doc_gr_limesdr_source_source_0 = R"doc()doc"; + + + static const char *__doc_gr_limesdr_source_source_1 = R"doc()doc"; + + + static const char *__doc_gr_limesdr_source_make = R"doc()doc"; + + + static const char *__doc_gr_limesdr_source_set_center_freq = R"doc()doc"; + + + static const char *__doc_gr_limesdr_source_set_antenna = R"doc()doc"; + + + static const char *__doc_gr_limesdr_source_set_nco = R"doc()doc"; + + + static const char *__doc_gr_limesdr_source_set_bandwidth = R"doc()doc"; + + + static const char *__doc_gr_limesdr_source_set_digital_filter = R"doc()doc"; + + + static const char *__doc_gr_limesdr_source_set_gain = R"doc()doc"; + + + static const char *__doc_gr_limesdr_source_set_sample_rate = R"doc()doc"; + + + static const char *__doc_gr_limesdr_source_set_oversampling = R"doc()doc"; + + + static const char *__doc_gr_limesdr_source_calibrate = R"doc()doc"; + + + static const char *__doc_gr_limesdr_source_set_buffer_size = R"doc()doc"; + + + static const char *__doc_gr_limesdr_source_set_tcxo_dac = R"doc()doc"; + + diff --git a/python/bindings/header_utils.py b/python/bindings/header_utils.py new file mode 100644 index 0000000..165124e --- /dev/null +++ b/python/bindings/header_utils.py @@ -0,0 +1,78 @@ +# Utilities for reading values in header files + +from argparse import ArgumentParser +import re + + +class PybindHeaderParser: + def __init__(self, pathname): + with open(pathname,'r') as f: + self.file_txt = f.read() + + def get_flag_automatic(self): + # p = re.compile(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)', self.file_txt) + if (m and m.group(1) == '1'): + return True + else: + return False + + def get_flag_pygccxml(self): + # p = re.compile(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)', self.file_txt) + if (m and m.group(1) == '1'): + return True + else: + return False + + def get_header_filename(self): + # p = re.compile(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)', self.file_txt) + if (m): + return m.group(1) + else: + return None + + def get_header_file_hash(self): + # p = re.compile(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)', self.file_txt) + if (m): + return m.group(1) + else: + return None + + def get_flags(self): + return f'{self.get_flag_automatic()};{self.get_flag_pygccxml()};{self.get_header_filename()};{self.get_header_file_hash()};' + + + +def argParse(): + """Parses commandline args.""" + desc='Reads the parameters from the comment block in the pybind files' + parser = ArgumentParser(description=desc) + + parser.add_argument("function", help="Operation to perform on comment block of pybind file", choices=["flag_auto","flag_pygccxml","header_filename","header_file_hash","all"]) + parser.add_argument("pathname", help="Pathname of pybind c++ file to read, e.g. blockname_python.cc") + + return parser.parse_args() + +if __name__ == "__main__": + # Parse command line options and set up doxyxml. + args = argParse() + + pbhp = PybindHeaderParser(args.pathname) + + if args.function == "flag_auto": + print(pbhp.get_flag_automatic()) + elif args.function == "flag_pygccxml": + print(pbhp.get_flag_pygccxml()) + elif args.function == "header_filename": + print(pbhp.get_header_filename()) + elif args.function == "header_file_hash": + print(pbhp.get_header_file_hash()) + elif args.function == "all": + print(pbhp.get_flags()) \ No newline at end of file diff --git a/python/bindings/python_bindings.cc b/python/bindings/python_bindings.cc new file mode 100644 index 0000000..e7ad9ad --- /dev/null +++ b/python/bindings/python_bindings.cc @@ -0,0 +1,63 @@ +/* + * Copyright 2020 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include + +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION +#include + +namespace py = pybind11; + +// Headers for binding functions +/**************************************/ +// The following comment block is used for +// gr_modtool to insert function prototypes +// Please do not delete +/**************************************/ +// BINDING_FUNCTION_PROTOTYPES( + void bind_sink(py::module& m); + void bind_source(py::module& m); +#ifdef ENABLE_RFE + void bind_rfe(py::module& m); +#endif +// ) END BINDING_FUNCTION_PROTOTYPES + + +// We need this hack because import_array() returns NULL +// for newer Python versions. +// This function is also necessary because it ensures access to the C API +// and removes a warning. +void* init_numpy() +{ + import_array(); + return NULL; +} + +PYBIND11_MODULE(limesdr_python, m) +{ + // Initialize the numpy C API + // (otherwise we will see segmentation faults) + init_numpy(); + + // Allow access to base block methods + py::module::import("gnuradio.gr"); + + /**************************************/ + // The following comment block is used for + // gr_modtool to insert binding function calls + // Please do not delete + /**************************************/ + // BINDING_FUNCTION_CALLS( + bind_sink(m); + bind_source(m); +#ifdef ENABLE_RFE + bind_rfe(m); +#endif + // ) END BINDING_FUNCTION_CALLS +} \ No newline at end of file diff --git a/python/bindings/rfe_python.cc b/python/bindings/rfe_python.cc new file mode 100644 index 0000000..6b9945d --- /dev/null +++ b/python/bindings/rfe_python.cc @@ -0,0 +1,96 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/***********************************************************************************/ +/* This file is automatically generated using bindtool and can be manually edited */ +/* The following lines can be configured to regenerate this file during cmake */ +/* If manual edits are made, the following tags should be modified accordingly. */ +/* BINDTOOL_GEN_AUTOMATIC(0) */ +/* BINDTOOL_USE_PYGCCXML(0) */ +/* BINDTOOL_HEADER_FILE(rfe.h) */ +/* BINDTOOL_HEADER_FILE_HASH(f9a316bfe452c1b3fe6c6ba827ced967) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_rfe(py::module& m) +{ + + using rfe = ::gr::limesdr::rfe; + + + py::class_>(m, "rfe", D(rfe)) + + .def(py::init(), py::arg("comm_type"), + py::arg("device"), + py::arg("config_file"), + py::arg("IDRX"), + py::arg("IDTX"), + py::arg("PortRX"), + py::arg("PortTX"), + py::arg("Mode"), + py::arg("Notch"), + py::arg("Atten"), + D(rfe,rfe,0) + ) + .def(py::init(), py::arg("arg0"), + D(rfe,rfe,1) + ) + + + + .def("change_mode",&rfe::change_mode, + py::arg("mode"), + D(rfe,change_mode) + ) + + + + .def("set_fan",&rfe::set_fan, + py::arg("enable"), + D(rfe,set_fan) + ) + + + + .def("set_attenuation",&rfe::set_attenuation, + py::arg("attenuation"), + D(rfe,set_attenuation) + ) + + + + .def("set_notch",&rfe::set_notch, + py::arg("enable"), + D(rfe,set_notch) + ) + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/sink_python.cc b/python/bindings/sink_python.cc new file mode 100644 index 0000000..f624d7a --- /dev/null +++ b/python/bindings/sink_python.cc @@ -0,0 +1,147 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/***********************************************************************************/ +/* This file is automatically generated using bindtool and can be manually edited */ +/* The following lines can be configured to regenerate this file during cmake */ +/* If manual edits are made, the following tags should be modified accordingly. */ +/* BINDTOOL_GEN_AUTOMATIC(0) */ +/* BINDTOOL_USE_PYGCCXML(0) */ +/* BINDTOOL_HEADER_FILE(sink.h) */ +/* BINDTOOL_HEADER_FILE_HASH(86de0559ad51d7da08762714c3ed3f77) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_sink(py::module& m) +{ + + using sink = ::gr::limesdr::sink; + + + py::class_>(m, "sink", D(sink)) + + .def(py::init(&sink::make), + py::arg("serial"), + py::arg("channel_mode"), + py::arg("filename"), + py::arg("length_tag_name"), + D(sink,make) + ) + + + + + + + .def("set_center_freq",&sink::set_center_freq, + py::arg("freq"), + py::arg("chan") = 0, + D(sink,set_center_freq) + ) + + + + .def("set_antenna",&sink::set_antenna, + py::arg("antenna"), + py::arg("channel") = 0, + D(sink,set_antenna) + ) + + + + .def("set_nco",&sink::set_nco, + py::arg("nco_freq"), + py::arg("channel"), + D(sink,set_nco) + ) + + + + .def("set_bandwidth",&sink::set_bandwidth, + py::arg("analog_bandw"), + py::arg("channel") = 0, + D(sink,set_bandwidth) + ) + + + + .def("set_digital_filter",&sink::set_digital_filter, + py::arg("digital_bandw"), + py::arg("channel"), + D(sink,set_digital_filter) + ) + + + + .def("set_gain",&sink::set_gain, + py::arg("gain_dB"), + py::arg("channel") = 0, + D(sink,set_gain) + ) + + + + .def("set_sample_rate",&sink::set_sample_rate, + py::arg("rate"), + D(sink,set_sample_rate) + ) + + + + .def("set_oversampling",&sink::set_oversampling, + py::arg("oversample"), + D(sink,set_oversampling) + ) + + + + .def("calibrate",&sink::calibrate, + py::arg("bandw"), + py::arg("channel") = 0, + D(sink,calibrate) + ) + + + + .def("set_buffer_size",&sink::set_buffer_size, + py::arg("size"), + D(sink,set_buffer_size) + ) + + + + .def("set_tcxo_dac",&sink::set_tcxo_dac, + py::arg("dacVal") = 125, + D(sink,set_tcxo_dac) + ) + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/source_python.cc b/python/bindings/source_python.cc new file mode 100644 index 0000000..d8584be --- /dev/null +++ b/python/bindings/source_python.cc @@ -0,0 +1,146 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/***********************************************************************************/ +/* This file is automatically generated using bindtool and can be manually edited */ +/* The following lines can be configured to regenerate this file during cmake */ +/* If manual edits are made, the following tags should be modified accordingly. */ +/* BINDTOOL_GEN_AUTOMATIC(0) */ +/* BINDTOOL_USE_PYGCCXML(0) */ +/* BINDTOOL_HEADER_FILE(source.h) */ +/* BINDTOOL_HEADER_FILE_HASH(202afe28ab16609914f3a3a1dbdb9e56) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_source(py::module& m) +{ + + using source = ::gr::limesdr::source; + + + py::class_>(m, "source", D(source)) + + .def(py::init(&source::make), + py::arg("serial"), + py::arg("channel_mode"), + py::arg("filename"), + D(source,make) + ) + + + + + + + .def("set_center_freq",&source::set_center_freq, + py::arg("freq"), + py::arg("chan") = 0, + D(source,set_center_freq) + ) + + + + .def("set_antenna",&source::set_antenna, + py::arg("antenna"), + py::arg("channel") = 0, + D(source,set_antenna) + ) + + + + .def("set_nco",&source::set_nco, + py::arg("nco_freq"), + py::arg("channel"), + D(source,set_nco) + ) + + + + .def("set_bandwidth",&source::set_bandwidth, + py::arg("analog_bandw"), + py::arg("channel") = 0, + D(source,set_bandwidth) + ) + + + + .def("set_digital_filter",&source::set_digital_filter, + py::arg("digital_bandw"), + py::arg("channel"), + D(source,set_digital_filter) + ) + + + + .def("set_gain",&source::set_gain, + py::arg("gain_dB"), + py::arg("channel") = 0, + D(source,set_gain) + ) + + + + .def("set_sample_rate",&source::set_sample_rate, + py::arg("rate"), + D(source,set_sample_rate) + ) + + + + .def("set_oversampling",&source::set_oversampling, + py::arg("oversample"), + D(source,set_oversampling) + ) + + + + .def("calibrate",&source::calibrate, + py::arg("bandw"), + py::arg("channel") = 0, + D(source,calibrate) + ) + + + + .def("set_buffer_size",&source::set_buffer_size, + py::arg("size"), + D(source,set_buffer_size) + ) + + + + .def("set_tcxo_dac",&source::set_tcxo_dac, + py::arg("dacVal") = 125, + D(source,set_tcxo_dac) + ) + + ; + + + + +} + + + + + + + + diff --git a/python/build_utils.py b/python/build_utils.py deleted file mode 100755 index cf58a97..0000000 --- a/python/build_utils.py +++ /dev/null @@ -1,226 +0,0 @@ -# -# Copyright 2004,2009,2012 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -"""Misc utilities used at build time -""" - -import re, os, os.path -from build_utils_codes import * - - -# set srcdir to the directory that contains Makefile.am -try: - srcdir = os.environ['srcdir'] -except KeyError, e: - srcdir = "." -srcdir = srcdir + '/' - -# set do_makefile to either true or false dependeing on the environment -try: - if os.environ['do_makefile'] == '0': - do_makefile = False - else: - do_makefile = True -except KeyError, e: - do_makefile = False - -# set do_sources to either true or false dependeing on the environment -try: - if os.environ['do_sources'] == '0': - do_sources = False - else: - do_sources = True -except KeyError, e: - do_sources = True - -name_dict = {} - -def log_output_name (name): - (base, ext) = os.path.splitext (name) - ext = ext[1:] # drop the leading '.' - - entry = name_dict.setdefault (ext, []) - entry.append (name) - -def open_and_log_name (name, dir): - global do_sources - if do_sources: - f = open (name, dir) - else: - f = None - log_output_name (name) - return f - -def expand_template (d, template_filename, extra = ""): - '''Given a dictionary D and a TEMPLATE_FILENAME, expand template into output file - ''' - global do_sources - output_extension = extract_extension (template_filename) - template = open_src (template_filename, 'r') - output_name = d['NAME'] + extra + '.' + output_extension - log_output_name (output_name) - if do_sources: - output = open (output_name, 'w') - do_substitution (d, template, output) - output.close () - template.close () - -def output_glue (dirname): - output_makefile_fragment () - output_ifile_include (dirname) - -def output_makefile_fragment (): - global do_makefile - if not do_makefile: - return -# overwrite the source, which must be writable; this should have been -# checked for beforehand in the top-level Makefile.gen.gen . - f = open (os.path.join (os.environ.get('gendir', os.environ.get('srcdir', '.')), 'Makefile.gen'), 'w') - f.write ('#\n# This file is machine generated. All edits will be overwritten\n#\n') - output_subfrag (f, 'h') - output_subfrag (f, 'i') - output_subfrag (f, 'cc') - f.close () - -def output_ifile_include (dirname): - global do_sources - if do_sources: - f = open ('%s_generated.i' % (dirname,), 'w') - f.write ('//\n// This file is machine generated. All edits will be overwritten\n//\n') - files = name_dict.setdefault ('i', []) - files.sort () - f.write ('%{\n') - for file in files: - f.write ('#include <%s>\n' % (file[0:-1] + 'h',)) - f.write ('%}\n\n') - for file in files: - f.write ('%%include <%s>\n' % (file,)) - -def output_subfrag (f, ext): - files = name_dict.setdefault (ext, []) - files.sort () - f.write ("GENERATED_%s =" % (ext.upper ())) - for file in files: - f.write (" \\\n\t%s" % (file,)) - f.write ("\n\n") - -def extract_extension (template_name): - # template name is something like: GrFIRfilterXXX.h.t - # we return everything between the penultimate . and .t - mo = re.search (r'\.([a-z]+)\.t$', template_name) - if not mo: - raise ValueError, "Incorrectly formed template_name '%s'" % (template_name,) - return mo.group (1) - -def open_src (name, mode): - global srcdir - return open (os.path.join (srcdir, name), mode) - -def do_substitution (d, in_file, out_file): - def repl (match_obj): - key = match_obj.group (1) - # print key - return d[key] - - inp = in_file.read () - out = re.sub (r"@([a-zA-Z0-9_]+)@", repl, inp) - out_file.write (out) - - - -copyright = '''/* -*- c++ -*- */ -/* - * Copyright 2003,2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ -''' - -def is_complex (code3): - if i_code (code3) == 'c' or o_code (code3) == 'c': - return '1' - else: - return '0' - - -def standard_dict (name, code3, package='gr'): - d = {} - d['NAME'] = name - d['NAME_IMPL'] = name+'_impl' - d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper()) - d['GUARD_NAME_IMPL'] = 'INCLUDED_%s_%s_IMPL_H' % (package.upper(), name.upper()) - d['BASE_NAME'] = re.sub ('^' + package + '_', '', name) - d['SPTR_NAME'] = '%s_sptr' % name - d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten' - d['COPYRIGHT'] = copyright - d['TYPE'] = i_type (code3) - d['I_TYPE'] = i_type (code3) - d['O_TYPE'] = o_type (code3) - d['TAP_TYPE'] = tap_type (code3) - d['IS_COMPLEX'] = is_complex (code3) - return d - - -def standard_dict2 (name, code3, package): - d = {} - d['NAME'] = name - d['BASE_NAME'] = name - d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper()) - d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten' - d['COPYRIGHT'] = copyright - d['TYPE'] = i_type (code3) - d['I_TYPE'] = i_type (code3) - d['O_TYPE'] = o_type (code3) - d['TAP_TYPE'] = tap_type (code3) - d['IS_COMPLEX'] = is_complex (code3) - return d - -def standard_impl_dict2 (name, code3, package): - d = {} - d['NAME'] = name - d['IMPL_NAME'] = name - d['BASE_NAME'] = name.rstrip("impl").rstrip("_") - d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper()) - d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten' - d['COPYRIGHT'] = copyright - d['FIR_TYPE'] = "fir_filter_" + code3 - d['CFIR_TYPE'] = "fir_filter_" + code3[0:2] + 'c' - d['TYPE'] = i_type (code3) - d['I_TYPE'] = i_type (code3) - d['O_TYPE'] = o_type (code3) - d['TAP_TYPE'] = tap_type (code3) - d['IS_COMPLEX'] = is_complex (code3) - return d diff --git a/python/build_utils.pyc b/python/build_utils.pyc deleted file mode 100755 index cd94029..0000000 Binary files a/python/build_utils.pyc and /dev/null differ diff --git a/python/build_utils_codes.py b/python/build_utils_codes.py deleted file mode 100755 index 9ea96ba..0000000 --- a/python/build_utils_codes.py +++ /dev/null @@ -1,52 +0,0 @@ -# -# Copyright 2004 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -def i_code (code3): - return code3[0] - -def o_code (code3): - if len (code3) >= 2: - return code3[1] - else: - return code3[0] - -def tap_code (code3): - if len (code3) >= 3: - return code3[2] - else: - return code3[0] - -def i_type (code3): - return char_to_type[i_code (code3)] - -def o_type (code3): - return char_to_type[o_code (code3)] - -def tap_type (code3): - return char_to_type[tap_code (code3)] - - -char_to_type = {} -char_to_type['s'] = 'short' -char_to_type['i'] = 'int' -char_to_type['f'] = 'float' -char_to_type['c'] = 'gr_complex' -char_to_type['b'] = 'unsigned char' diff --git a/python/build_utils_codes.pyc b/python/build_utils_codes.pyc deleted file mode 100755 index 6f2a933..0000000 Binary files a/python/build_utils_codes.pyc and /dev/null differ diff --git a/swig/CMakeLists.txt b/swig/CMakeLists.txt deleted file mode 100755 index 71b8ba4..0000000 --- a/swig/CMakeLists.txt +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright 2011 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. - -######################################################################## -# Check if there is C++ code at all -######################################################################## -if(NOT limesdr_sources) - MESSAGE(STATUS "No C++ sources... skipping swig/") - return() -endif(NOT limesdr_sources) - -if(ENABLE_RFE) - set(GR_SWIG_FLAGS -DENABLE_RFE) -endif() -######################################################################## -# Include swig generation macros -######################################################################## -find_package(SWIG REQUIRED) -find_package(PythonLibs 2) -if(NOT SWIG_FOUND OR NOT PYTHONLIBS_FOUND) - return() -endif() -include(GrSwig) -include(GrPython) - -######################################################################## -# Setup swig generation -######################################################################## -foreach(incdir ${GNURADIO_RUNTIME_INCLUDE_DIRS}) - list(APPEND GR_SWIG_INCLUDE_DIRS ${incdir}/gnuradio/swig) -endforeach(incdir) - -set(GR_SWIG_LIBRARIES gnuradio-limesdr) -set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/limesdr_swig_doc.i) -set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include) - -GR_SWIG_MAKE(limesdr_swig limesdr_swig.i) - -######################################################################## -# Install the build swig module -######################################################################## -GR_SWIG_INSTALL(TARGETS limesdr_swig DESTINATION ${GR_PYTHON_DIR}/limesdr) - -######################################################################## -# Install swig .i files for development -######################################################################## -install( - FILES - limesdr_swig.i - ${CMAKE_CURRENT_BINARY_DIR}/limesdr_swig_doc.i - DESTINATION ${GR_INCLUDE_DIR}/limesdr/swig -) diff --git a/swig/limesdr_swig.i b/swig/limesdr_swig.i deleted file mode 100755 index 24ad24e..0000000 --- a/swig/limesdr_swig.i +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- c++ -*- */ - -#define LIMESDR_API - -%include "gnuradio.i" // the common stuff - -//load generated python docstrings -%include "limesdr_swig_doc.i" - -%{ -#include "limesdr/source.h" -#include "limesdr/sink.h" -%} - -%include "limesdr/source.h" -GR_SWIG_BLOCK_MAGIC2(limesdr, source); - -%include "limesdr/sink.h" -GR_SWIG_BLOCK_MAGIC2(limesdr, sink); - -#ifdef ENABLE_RFE -%{ -#include "limesdr/rfe.h" -%} -%include "limesdr/rfe.h" -#endif