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