summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/Modules/GrMiscUtils.cmake8
-rw-r--r--cmake/Modules/GrSwig.cmake15
-rwxr-xr-xgnuradio-examples/python/tags/uhd_burst_detector.py4
-rw-r--r--gr-digital/examples/narrowband/uhd_interface.py8
-rw-r--r--gr-digital/examples/ofdm/uhd_interface.py8
-rw-r--r--gr-howto-write-a-block-cmake/cmake/Modules/GrMiscUtils.cmake8
-rw-r--r--gr-howto-write-a-block-cmake/cmake/Modules/GrSwig.cmake15
-rwxr-xr-xgr-pager/apps/usrp_flex.py4
-rwxr-xr-xgr-pager/apps/usrp_flex_all.py4
-rwxr-xr-xgr-pager/apps/usrp_flex_band.py4
-rwxr-xr-xgr-qtgui/apps/uhd_display.py4
-rw-r--r--gr-qtgui/lib/CMakeLists.txt1
-rwxr-xr-xgr-uhd/apps/uhd_fft.py12
-rwxr-xr-xgr-uhd/apps/uhd_rx_cfile.py8
-rwxr-xr-xgr-uhd/apps/uhd_rx_nogui.py4
-rwxr-xr-xgr-uhd/apps/uhd_siggen.py12
-rwxr-xr-xgr-uhd/examples/fm_tx4.py4
-rwxr-xr-xgr-uhd/examples/fm_tx_2_daughterboards.py5
-rwxr-xr-xgr-uhd/examples/max_power.py5
-rw-r--r--gr-uhd/examples/tags_demo.cc4
-rwxr-xr-xgr-uhd/examples/usrp_am_mw_rcv.py4
-rwxr-xr-xgr-uhd/examples/usrp_nbfm_ptt.py4
-rwxr-xr-xgr-uhd/examples/usrp_nbfm_rcv.py4
-rwxr-xr-xgr-uhd/examples/usrp_spectrum_sense.py4
-rwxr-xr-xgr-uhd/examples/usrp_tv_rcv.py4
-rwxr-xr-xgr-uhd/examples/usrp_tv_rcv_nogui.py4
-rwxr-xr-xgr-uhd/examples/usrp_wfm_rcv.py4
-rwxr-xr-xgr-uhd/examples/usrp_wfm_rcv2_nogui.py5
-rwxr-xr-xgr-uhd/examples/usrp_wfm_rcv_fmdet.py4
-rwxr-xr-xgr-uhd/examples/usrp_wfm_rcv_nogui.py4
-rwxr-xr-xgr-uhd/examples/usrp_wfm_rcv_pll.py4
-rwxr-xr-xgr-uhd/examples/usrp_wfm_rcv_sca.py4
-rwxr-xr-xgr-uhd/examples/usrp_wxapt_rcv.py4
-rw-r--r--gr-uhd/grc/gen_uhd_usrp_blocks.py132
-rw-r--r--gr-uhd/include/gr_uhd_usrp_sink.h164
-rw-r--r--gr-uhd/include/gr_uhd_usrp_source.h175
-rw-r--r--gr-uhd/lib/gr_uhd_usrp_sink.cc169
-rw-r--r--gr-uhd/lib/gr_uhd_usrp_source.cc186
-rw-r--r--gr-uhd/swig/__init__.py25
-rw-r--r--gr-uhd/swig/uhd_swig.i2
-rw-r--r--volk/CMakeLists.txt26
-rw-r--r--volk/cmake/FindORC.cmake36
-rw-r--r--volk/gen/archs.xml9
-rw-r--r--volk/gen/compilers.xml18
-rw-r--r--volk/gen/make_cpuid_c.py22
-rw-r--r--volk/lib/CMakeLists.txt213
46 files changed, 1092 insertions, 275 deletions
diff --git a/cmake/Modules/GrMiscUtils.cmake b/cmake/Modules/GrMiscUtils.cmake
index 540b97b93..0e1f40027 100644
--- a/cmake/Modules/GrMiscUtils.cmake
+++ b/cmake/Modules/GrMiscUtils.cmake
@@ -164,6 +164,7 @@ function(GR_LIBRARY_FOO target)
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so
COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0
+ COMMAND ${CMAKE_COMMAND} -E touch ${target_name} #so the symlinks point to something valid so cmake 2.6 will install
)
#and install the extra symlinks
@@ -200,5 +201,10 @@ function(GR_GEN_TARGET_DEPS name var)
if(ARGN)
add_dependencies(${name} ${ARGN})
endif(ARGN)
- set(${var} "DEPENDS;${name};COMMAND;${name}" PARENT_SCOPE)
+
+ if(CMAKE_CROSSCOMPILING)
+ set(${var} "DEPENDS;${name}" PARENT_SCOPE) #cant call command when cross
+ else()
+ set(${var} "DEPENDS;${name};COMMAND;${name}" PARENT_SCOPE)
+ endif()
endfunction(GR_GEN_TARGET_DEPS)
diff --git a/cmake/Modules/GrSwig.cmake b/cmake/Modules/GrSwig.cmake
index 4be583aa1..51d9203dd 100644
--- a/cmake/Modules/GrSwig.cmake
+++ b/cmake/Modules/GrSwig.cmake
@@ -38,10 +38,18 @@ include(GrPython)
macro(GR_SWIG_MAKE name)
set(ifiles ${ARGN})
+ #append additional include directories
+ find_package(PythonLibs)
+ list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_PATH}) #deprecated name (now dirs)
+ list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS})
+ list(APPEND GR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
+ list(APPEND GR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR})
+
#determine include dependencies for swig file
execute_process(
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/get_swig_deps.py
- "${ifiles}" "${GR_SWIG_INCLUDE_DIRS}"
+ COMMAND ${PYTHON_EXECUTABLE}
+ ${CMAKE_BINARY_DIR}/get_swig_deps.py
+ "${ifiles}" "${GR_SWIG_INCLUDE_DIRS}"
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE SWIG_MODULE_${name}_EXTRA_DEPS
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
@@ -61,9 +69,6 @@ macro(GR_SWIG_MAKE name)
include_directories(${GR_SWIG_INCLUDE_DIRS})
list(APPEND SWIG_MODULE_${name}_EXTRA_DEPS ${tag_file})
- find_package(PythonLibs)
- include_directories(${PYTHON_INCLUDE_DIRS})
-
#setup the swig flags with flags and include directories
set(CMAKE_SWIG_FLAGS -fvirtual -modern -keyword -w511 -module ${name} ${GR_SWIG_FLAGS})
foreach(dir ${GR_SWIG_INCLUDE_DIRS})
diff --git a/gnuradio-examples/python/tags/uhd_burst_detector.py b/gnuradio-examples/python/tags/uhd_burst_detector.py
index ffa419562..7411ab06e 100755
--- a/gnuradio-examples/python/tags/uhd_burst_detector.py
+++ b/gnuradio-examples/python/tags/uhd_burst_detector.py
@@ -42,9 +42,7 @@ class uhd_burst_detector(gr.top_block):
self.uhd_src = uhd.single_usrp_source(
device_addr=self.uhd_addr,
- io_type=uhd.io_type_t.COMPLEX_FLOAT32,
- num_channels=1,
- )
+ stream_args=uhd.stream_args('fc32'))
self.uhd_src.set_samp_rate(self.samp_rate)
self.uhd_src.set_center_freq(self.freq, 0)
diff --git a/gr-digital/examples/narrowband/uhd_interface.py b/gr-digital/examples/narrowband/uhd_interface.py
index 21930ad01..27e370911 100644
--- a/gr-digital/examples/narrowband/uhd_interface.py
+++ b/gr-digital/examples/narrowband/uhd_interface.py
@@ -46,13 +46,9 @@ class uhd_interface:
gain=None, spec=None, antenna=None):
if(istx):
- self.u = uhd.usrp_sink(device_addr=args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_sink(device_addr=args, stream_args=uhd.stream_args('fc32'))
else:
- self.u = uhd.usrp_source(device_addr=args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=args, stream_args=uhd.stream_args('fc32'))
self._args = args
self._ant = antenna
diff --git a/gr-digital/examples/ofdm/uhd_interface.py b/gr-digital/examples/ofdm/uhd_interface.py
index 476d3c842..14a542b0f 100644
--- a/gr-digital/examples/ofdm/uhd_interface.py
+++ b/gr-digital/examples/ofdm/uhd_interface.py
@@ -46,13 +46,9 @@ class uhd_interface:
gain=None, spec=None, antenna=None):
if(istx):
- self.u = uhd.usrp_sink(device_addr=args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_sink(device_addr=args, stream_args=uhd.stream_args('fc32'))
else:
- self.u = uhd.usrp_source(device_addr=args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=args, stream_args=uhd.stream_args('fc32'))
self._args = args
self._ant = antenna
diff --git a/gr-howto-write-a-block-cmake/cmake/Modules/GrMiscUtils.cmake b/gr-howto-write-a-block-cmake/cmake/Modules/GrMiscUtils.cmake
index 540b97b93..0e1f40027 100644
--- a/gr-howto-write-a-block-cmake/cmake/Modules/GrMiscUtils.cmake
+++ b/gr-howto-write-a-block-cmake/cmake/Modules/GrMiscUtils.cmake
@@ -164,6 +164,7 @@ function(GR_LIBRARY_FOO target)
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so
COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0
+ COMMAND ${CMAKE_COMMAND} -E touch ${target_name} #so the symlinks point to something valid so cmake 2.6 will install
)
#and install the extra symlinks
@@ -200,5 +201,10 @@ function(GR_GEN_TARGET_DEPS name var)
if(ARGN)
add_dependencies(${name} ${ARGN})
endif(ARGN)
- set(${var} "DEPENDS;${name};COMMAND;${name}" PARENT_SCOPE)
+
+ if(CMAKE_CROSSCOMPILING)
+ set(${var} "DEPENDS;${name}" PARENT_SCOPE) #cant call command when cross
+ else()
+ set(${var} "DEPENDS;${name};COMMAND;${name}" PARENT_SCOPE)
+ endif()
endfunction(GR_GEN_TARGET_DEPS)
diff --git a/gr-howto-write-a-block-cmake/cmake/Modules/GrSwig.cmake b/gr-howto-write-a-block-cmake/cmake/Modules/GrSwig.cmake
index 4be583aa1..51d9203dd 100644
--- a/gr-howto-write-a-block-cmake/cmake/Modules/GrSwig.cmake
+++ b/gr-howto-write-a-block-cmake/cmake/Modules/GrSwig.cmake
@@ -38,10 +38,18 @@ include(GrPython)
macro(GR_SWIG_MAKE name)
set(ifiles ${ARGN})
+ #append additional include directories
+ find_package(PythonLibs)
+ list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_PATH}) #deprecated name (now dirs)
+ list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS})
+ list(APPEND GR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
+ list(APPEND GR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR})
+
#determine include dependencies for swig file
execute_process(
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/get_swig_deps.py
- "${ifiles}" "${GR_SWIG_INCLUDE_DIRS}"
+ COMMAND ${PYTHON_EXECUTABLE}
+ ${CMAKE_BINARY_DIR}/get_swig_deps.py
+ "${ifiles}" "${GR_SWIG_INCLUDE_DIRS}"
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE SWIG_MODULE_${name}_EXTRA_DEPS
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
@@ -61,9 +69,6 @@ macro(GR_SWIG_MAKE name)
include_directories(${GR_SWIG_INCLUDE_DIRS})
list(APPEND SWIG_MODULE_${name}_EXTRA_DEPS ${tag_file})
- find_package(PythonLibs)
- include_directories(${PYTHON_INCLUDE_DIRS})
-
#setup the swig flags with flags and include directories
set(CMAKE_SWIG_FLAGS -fvirtual -modern -keyword -w511 -module ${name} ${GR_SWIG_FLAGS})
foreach(dir ${GR_SWIG_INCLUDE_DIRS})
diff --git a/gr-pager/apps/usrp_flex.py b/gr-pager/apps/usrp_flex.py
index 7c90d9296..7d0d66a95 100755
--- a/gr-pager/apps/usrp_flex.py
+++ b/gr-pager/apps/usrp_flex.py
@@ -35,9 +35,7 @@ class app_top_block(gr.top_block):
if options.from_file is None:
# Set up USRP source
- self.u = uhd.usrp_source(device_addr=options.address,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=options.address, stream_args=uhd.stream_args('fc32'))
# Grab 250 KHz of spectrum
# (A UHD facility to get sample rate range and granularity would be useful)
diff --git a/gr-pager/apps/usrp_flex_all.py b/gr-pager/apps/usrp_flex_all.py
index 71a0a398e..36bd90034 100755
--- a/gr-pager/apps/usrp_flex_all.py
+++ b/gr-pager/apps/usrp_flex_all.py
@@ -39,9 +39,7 @@ class app_top_block(gr.top_block):
else:
# Set up USRP source
- self.u = uhd.usrp_source(device_addr=options.address,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=options.address, stream_args=uhd.stream_args('fc32'))
# Tune daughterboard
r = self.u.set_center_freq(options.freq+options.calibration, 0)
diff --git a/gr-pager/apps/usrp_flex_band.py b/gr-pager/apps/usrp_flex_band.py
index 8ea76c229..63fb93fa1 100755
--- a/gr-pager/apps/usrp_flex_band.py
+++ b/gr-pager/apps/usrp_flex_band.py
@@ -35,9 +35,7 @@ class app_top_block(gr.top_block):
print "Reading samples from file", options.from_file
else:
# Set up USRP source
- self.u = uhd.usrp_source(device_addr=options.address,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=options.address, stream_args=uhd.stream_args('fc32'))
# Grab 1 MHz of spectrum
# (A UHD facility to get sample rate range and granularity would be useful)
diff --git a/gr-qtgui/apps/uhd_display.py b/gr-qtgui/apps/uhd_display.py
index 806914797..94e4f099c 100755
--- a/gr-qtgui/apps/uhd_display.py
+++ b/gr-qtgui/apps/uhd_display.py
@@ -171,9 +171,7 @@ class my_top_block(gr.top_block):
self.qapp = QtGui.QApplication(sys.argv)
- self.u = uhd.usrp_source(device_addr=options.address,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=options.address, stream_args=uhd.stream_args('fc32'))
self.set_bandwidth(options.samp_rate)
if options.gain is None:
diff --git a/gr-qtgui/lib/CMakeLists.txt b/gr-qtgui/lib/CMakeLists.txt
index f60595ee6..2dc35e81c 100644
--- a/gr-qtgui/lib/CMakeLists.txt
+++ b/gr-qtgui/lib/CMakeLists.txt
@@ -73,6 +73,7 @@ include_directories(${QWT_INCLUDE_DIRS})
link_directories(${QWT_LIBRARY_DIRS})
include_directories(${PYTHON_INCLUDE_DIRS})
+include_directories(${PYTHON_INCLUDE_PATH}) #deprecated for dirs (cmake 2.6)
########################################################################
# Setup library
diff --git a/gr-uhd/apps/uhd_fft.py b/gr-uhd/apps/uhd_fft.py
index 7f529a528..c06a23036 100755
--- a/gr-uhd/apps/uhd_fft.py
+++ b/gr-uhd/apps/uhd_fft.py
@@ -74,9 +74,11 @@ class app_top_block(stdgui2.std_top_block):
self.options = options
self.show_debug_info = True
- self.u = uhd.usrp_source(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32'))
+
+ # Set the subdevice spec
+ if(options.spec):
+ self.u.set_subdev_spec(options.spec, 0)
self.u.set_samp_rate(options.samp_rate)
input_rate = self.u.get_samp_rate()
@@ -119,10 +121,6 @@ class app_top_block(stdgui2.std_top_block):
self.set_gain(options.gain)
- # Set the subdevice spec
- if(options.spec):
- self.u.set_subdev_spec(options.spec, 0)
-
# Set the antenna
if(options.antenna):
self.u.set_antenna(options.antenna, 0)
diff --git a/gr-uhd/apps/uhd_rx_cfile.py b/gr-uhd/apps/uhd_rx_cfile.py
index 625de36d3..61d5342c5 100755
--- a/gr-uhd/apps/uhd_rx_cfile.py
+++ b/gr-uhd/apps/uhd_rx_cfile.py
@@ -41,14 +41,10 @@ class rx_cfile_block(gr.top_block):
# Create a UHD device source
if options.output_shorts:
- self._u = uhd.usrp_source(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_INT16,
- num_channels=1)
+ self._u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('sc16'))
self._sink = gr.file_sink(gr.sizeof_short*2, filename)
else:
- self._u = uhd.usrp_source(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self._u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32'))
self._sink = gr.file_sink(gr.sizeof_gr_complex, filename)
# Set receiver sample rate
diff --git a/gr-uhd/apps/uhd_rx_nogui.py b/gr-uhd/apps/uhd_rx_nogui.py
index 25068b3ac..7a2e0a07a 100755
--- a/gr-uhd/apps/uhd_rx_nogui.py
+++ b/gr-uhd/apps/uhd_rx_nogui.py
@@ -88,9 +88,7 @@ class uhd_src(gr.hier_block2):
gr.io_signature(0, 0, 0), # Input signature
gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
- self._src = uhd.usrp_source(device_addr=args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self._src = uhd.usrp_source(device_addr=args, stream_args=uhd.stream_args('fc32'))
self._src.set_samp_rate(samp_rate)
dev_rate = self._src.get_samp_rate()
diff --git a/gr-uhd/apps/uhd_siggen.py b/gr-uhd/apps/uhd_siggen.py
index 4b7060460..27e9e8e01 100755
--- a/gr-uhd/apps/uhd_siggen.py
+++ b/gr-uhd/apps/uhd_siggen.py
@@ -92,15 +92,17 @@ class top_block(gr.top_block, pubsub):
self[TYPE_KEY] = options.type #set type last
def _setup_usrpx(self, options):
- self._u = uhd.usrp_sink(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self._u = uhd.usrp_sink(device_addr=options.args, stream_args=uhd.stream_args('fc32'))
self._u.set_samp_rate(options.samp_rate)
# Set the subdevice spec
if(options.spec):
self._u.set_subdev_spec(options.spec, 0)
+ # Set the gain on the usrp from options
+ if(options.gain):
+ self._u.set_gain(options.gain)
+
# Set the antenna
if(options.antenna):
self._u.set_antenna(options.antenna, 0)
@@ -145,7 +147,7 @@ class top_block(gr.top_block, pubsub):
def set_gain(self, gain):
if gain is None:
g = self[GAIN_RANGE_KEY]
- gain = float(g[0]+g[1])/2
+ gain = float(g.start()+g.stop())/2
if self._verbose:
print "Using auto-calculated mid-point TX gain"
self[GAIN_KEY] = gain
@@ -158,7 +160,7 @@ class top_block(gr.top_block, pubsub):
if target_freq is None:
f = self[FREQ_RANGE_KEY]
- target_freq = float(f[0]+f[1])/2.0
+ target_freq = float(f.start()+f.stop())/2.0
if self._verbose:
print "Using auto-calculated mid-point frequency"
self[TX_FREQ_KEY] = target_freq
diff --git a/gr-uhd/examples/fm_tx4.py b/gr-uhd/examples/fm_tx4.py
index 11148ea63..714eed3cf 100755
--- a/gr-uhd/examples/fm_tx4.py
+++ b/gr-uhd/examples/fm_tx4.py
@@ -117,9 +117,7 @@ class fm_tx_block(stdgui2.std_top_block):
# ----------------------------------------------------------------
# Set up constants and parameters
- self.u = uhd.usrp_sink(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_sink(device_addr=options.args, stream_args=uhd.stream_args('fc32'))
self.usrp_rate = options.samp_rate
self.u.set_samp_rate(self.usrp_rate)
diff --git a/gr-uhd/examples/fm_tx_2_daughterboards.py b/gr-uhd/examples/fm_tx_2_daughterboards.py
index 61c437a98..c0a7112de 100755
--- a/gr-uhd/examples/fm_tx_2_daughterboards.py
+++ b/gr-uhd/examples/fm_tx_2_daughterboards.py
@@ -113,9 +113,8 @@ class my_top_block(gr.top_block):
d = uhd.find_devices(uhd.device_addr(options.args))
uhd_type = d[0].get('type')
- self.u = uhd.usrp_sink(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=2)
+ stream_args = uhd.stream_args('fc32', channels=range(2))
+ self.u = uhd.usrp_sink(device_addr=options.args, stream_args=stream_args)
# Set up USRP system based on type
if(uhd_type == "usrp"):
diff --git a/gr-uhd/examples/max_power.py b/gr-uhd/examples/max_power.py
index 53e1b413c..a849432ee 100755
--- a/gr-uhd/examples/max_power.py
+++ b/gr-uhd/examples/max_power.py
@@ -59,9 +59,8 @@ class build_block(gr.top_block):
if tx_enable:
print "\nTRANSMIT CHAIN"
- self.u_tx = uhd.usrp_sink(device_addr=args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=tx_nchan)
+ stream_args = uhd.stream_args('fc32', channels=range(tx_nchan))
+ self.u_tx = uhd.usrp_sink(device_addr=args, stream_args=stream_args)
self.u_tx.set_samp_rate(MAX_RATE)
self.tx_src0 = gr.sig_source_c(self.u_tx.get_samp_rate(),
diff --git a/gr-uhd/examples/tags_demo.cc b/gr-uhd/examples/tags_demo.cc
index b40518f34..f7442f098 100644
--- a/gr-uhd/examples/tags_demo.cc
+++ b/gr-uhd/examples/tags_demo.cc
@@ -80,7 +80,7 @@ int main(int argc, char *argv[]){
//-- make the usrp source test blocks
//------------------------------------------------------------------
boost::shared_ptr<uhd_usrp_source> usrp_source = uhd_make_usrp_source(
- device_addr, uhd::io_type_t::COMPLEX_FLOAT32, 1
+ device_addr, uhd::stream_args_t("fc32")
);
usrp_source->set_samp_rate(samp_rate);
usrp_source->set_center_freq(center_freq);
@@ -96,7 +96,7 @@ int main(int argc, char *argv[]){
//-- make the usrp sink test blocks
//------------------------------------------------------------------
boost::shared_ptr<uhd_usrp_sink> usrp_sink = uhd_make_usrp_sink(
- device_addr, uhd::io_type_t::COMPLEX_FLOAT32, 1
+ device_addr, uhd::stream_args_t("fc32")
);
usrp_sink->set_samp_rate(samp_rate);
usrp_sink->set_center_freq(center_freq);
diff --git a/gr-uhd/examples/usrp_am_mw_rcv.py b/gr-uhd/examples/usrp_am_mw_rcv.py
index db3b35760..31fe9af70 100755
--- a/gr-uhd/examples/usrp_am_mw_rcv.py
+++ b/gr-uhd/examples/usrp_am_mw_rcv.py
@@ -75,9 +75,7 @@ class wfm_rx_block (stdgui2.std_top_block):
self.freq = 0
# build graph
- self.u = uhd.usrp_source(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32'))
usrp_rate = 256e3
demod_rate = 64e3
diff --git a/gr-uhd/examples/usrp_nbfm_ptt.py b/gr-uhd/examples/usrp_nbfm_ptt.py
index 8f7ddee7d..3b28bc2ea 100755
--- a/gr-uhd/examples/usrp_nbfm_ptt.py
+++ b/gr-uhd/examples/usrp_nbfm_ptt.py
@@ -281,9 +281,7 @@ class transmit_path(gr.hier_block2):
gr.io_signature(0, 0, 0), # Input signature
gr.io_signature(0, 0, 0)) # Output signature
- self.u = uhd.usrp_sink(device_addr=args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_sink(device_addr=args, stream_args=uhd.stream_args('fc32'))
self.if_rate = 320e3
self.audio_rate = 32e3
diff --git a/gr-uhd/examples/usrp_nbfm_rcv.py b/gr-uhd/examples/usrp_nbfm_rcv.py
index a558b9347..7e15abbcf 100755
--- a/gr-uhd/examples/usrp_nbfm_rcv.py
+++ b/gr-uhd/examples/usrp_nbfm_rcv.py
@@ -266,9 +266,7 @@ class receive_path(gr.hier_block2):
gr.io_signature(0, 0, 0), # Input signature
gr.io_signature(0, 0, 0)) # Output signature
- self.u = uhd.usrp_source(device_addr=args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=args, stream_args=uhd.stream_args('fc32'))
self.if_rate = 256e3
self.quad_rate = 64e3
diff --git a/gr-uhd/examples/usrp_spectrum_sense.py b/gr-uhd/examples/usrp_spectrum_sense.py
index 01ca60396..ceb95ea2a 100755
--- a/gr-uhd/examples/usrp_spectrum_sense.py
+++ b/gr-uhd/examples/usrp_spectrum_sense.py
@@ -131,9 +131,7 @@ class my_top_block(gr.top_block):
print "Note: failed to enable realtime scheduling"
# build graph
- self.u = uhd.usrp_source(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32'))
usrp_rate = options.samp_rate
self.u.set_samp_rate(usrp_rate)
diff --git a/gr-uhd/examples/usrp_tv_rcv.py b/gr-uhd/examples/usrp_tv_rcv.py
index 22493dd00..6e61eceec 100755
--- a/gr-uhd/examples/usrp_tv_rcv.py
+++ b/gr-uhd/examples/usrp_tv_rcv.py
@@ -131,9 +131,7 @@ class tv_rx_block (stdgui2.std_top_block):
self.gain=0.0
else: # use a UHD device
- self.u = uhd.usrp_source(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32'))
self.u.set_samp_rate(usrp_rate)
dev_rate = self.u.get_samp_rate()
diff --git a/gr-uhd/examples/usrp_tv_rcv_nogui.py b/gr-uhd/examples/usrp_tv_rcv_nogui.py
index 2324eb29e..f6a40d675 100755
--- a/gr-uhd/examples/usrp_tv_rcv_nogui.py
+++ b/gr-uhd/examples/usrp_tv_rcv_nogui.py
@@ -131,9 +131,7 @@ class my_top_block(gr.top_block):
raise SystemExit, 1
# build the graph
- self.u = uhd.usrp_source(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32'))
self.u.set_samp_rate(input_rate)
dev_rate = self.u.get_samp_rate()
diff --git a/gr-uhd/examples/usrp_wfm_rcv.py b/gr-uhd/examples/usrp_wfm_rcv.py
index cfdaa6d6f..a4abdd2a7 100755
--- a/gr-uhd/examples/usrp_wfm_rcv.py
+++ b/gr-uhd/examples/usrp_wfm_rcv.py
@@ -69,9 +69,7 @@ class wfm_rx_block (stdgui2.std_top_block):
self.fm_freq_max = options.freq_max
# build graph
- self.u = uhd.usrp_source(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32'))
usrp_rate = 320e3
demod_rate = 320e3
diff --git a/gr-uhd/examples/usrp_wfm_rcv2_nogui.py b/gr-uhd/examples/usrp_wfm_rcv2_nogui.py
index 8cbd18475..4173468ef 100755
--- a/gr-uhd/examples/usrp_wfm_rcv2_nogui.py
+++ b/gr-uhd/examples/usrp_wfm_rcv2_nogui.py
@@ -70,9 +70,8 @@ class wfm_rx_block (gr.top_block):
self.fm_freq_max = options.freq_max
# build graph
- self.u = uhd.usrp_source(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=2)
+ stream_args = uhd.stream_args('fc32', channels=range(2))
+ self.u = uhd.usrp_source(device_addr=options.args, stream_args=stream_args)
# Set front end channel mapping
self.u.set_subdev_spec(options.spec)
diff --git a/gr-uhd/examples/usrp_wfm_rcv_fmdet.py b/gr-uhd/examples/usrp_wfm_rcv_fmdet.py
index 39c711a6d..225c9607b 100755
--- a/gr-uhd/examples/usrp_wfm_rcv_fmdet.py
+++ b/gr-uhd/examples/usrp_wfm_rcv_fmdet.py
@@ -71,9 +71,7 @@ class wfm_rx_block (stdgui2.std_top_block):
self.fm_freq_max = options.freq_max
# build graph
- self.u = uhd.usrp_source(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32'))
usrp_rate = 320e3
demod_rate = 320e3
diff --git a/gr-uhd/examples/usrp_wfm_rcv_nogui.py b/gr-uhd/examples/usrp_wfm_rcv_nogui.py
index 90caf7d08..498d2dec6 100755
--- a/gr-uhd/examples/usrp_wfm_rcv_nogui.py
+++ b/gr-uhd/examples/usrp_wfm_rcv_nogui.py
@@ -63,9 +63,7 @@ class wfm_rx_block (gr.top_block):
self.fm_freq_max = options.freq_max
# build graph
- self.u = uhd.usrp_source(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32'))
usrp_rate = 320e3
demod_rate = 320e3
diff --git a/gr-uhd/examples/usrp_wfm_rcv_pll.py b/gr-uhd/examples/usrp_wfm_rcv_pll.py
index 2901bf735..383670c75 100755
--- a/gr-uhd/examples/usrp_wfm_rcv_pll.py
+++ b/gr-uhd/examples/usrp_wfm_rcv_pll.py
@@ -71,9 +71,7 @@ class wfm_rx_block (stdgui2.std_top_block):
self.fm_freq_max = options.freq_max
# build graph
- self.u = uhd.usrp_source(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32'))
usrp_rate = 320e3
demod_rate = 320e3
diff --git a/gr-uhd/examples/usrp_wfm_rcv_sca.py b/gr-uhd/examples/usrp_wfm_rcv_sca.py
index 9caef7499..9b233a7fb 100755
--- a/gr-uhd/examples/usrp_wfm_rcv_sca.py
+++ b/gr-uhd/examples/usrp_wfm_rcv_sca.py
@@ -100,9 +100,7 @@ class wfm_rx_sca_block (stdgui2.std_top_block):
# build graph
- self.u = uhd.usrp_source(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32'))
usrp_rate = 320e3
demod_rate = 320e3
diff --git a/gr-uhd/examples/usrp_wxapt_rcv.py b/gr-uhd/examples/usrp_wxapt_rcv.py
index 1da51d363..78cc7bd08 100755
--- a/gr-uhd/examples/usrp_wxapt_rcv.py
+++ b/gr-uhd/examples/usrp_wxapt_rcv.py
@@ -69,9 +69,7 @@ class wxapt_rx_block (stdgui2.std_top_block):
self.freq_max = options.freq_max
# build graph
- self.u = uhd.usrp_source(device_addr=options.args,
- io_type=uhd.io_type.COMPLEX_FLOAT32,
- num_channels=1)
+ self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32'))
usrp_rate = 320e3
demod_rate = 320e3
diff --git a/gr-uhd/grc/gen_uhd_usrp_blocks.py b/gr-uhd/grc/gen_uhd_usrp_blocks.py
index 7116dad3b..67343541c 100644
--- a/gr-uhd/grc/gen_uhd_usrp_blocks.py
+++ b/gr-uhd/grc/gen_uhd_usrp_blocks.py
@@ -27,27 +27,28 @@ MAIN_TMPL = """\
<import>from gnuradio import uhd</import>
<make>uhd.usrp_$(sourk)(
device_addr=\$dev_addr,
- io_type=uhd.io_type.\$type.type,
- num_channels=\$nchan,
+ stream_args=uhd.stream_args(
+ cpu_format="\$type",
+ \#if \$otw()
+ otw_format=\$otw,
+ \#end if
+ \#if \$stream_args()
+ args=\$stream_args,
+ \#end if
+ channels=range(\$nchan),
+ ),
)
\#if \$clock_rate()
self.\$(id).set_clock_rate(\$clock_rate, uhd.ALL_MBOARDS)
\#end if
#for $m in range($max_mboards)
########################################################################
-\#if \$num_mboards() > $m and \$ref_source$(m)() == 'external'
-self.\$(id).set_clock_config(uhd.clock_config.external(), $m)
+\#if \$num_mboards() > $m and \$clock_source$(m)()
+self.\$(id).set_clock_source(\$clock_source$(m), $m)
\#end if
########################################################################
-\#if \$num_mboards() > $m and \$ref_source$(m)() == 'internal'
-self.\$(id).set_clock_config(uhd.clock_config.internal(), $m)
-\#end if
-########################################################################
-\#if \$num_mboards() > $m and \$ref_source$(m)() == 'mimo'
-_config = uhd.clock_config()
-_config.ref_source = uhd.clock_config.REF_MIMO
-_config.pps_source = uhd.clock_config.PPS_MIMO
-self.\$(id).set_clock_config(_config, $m)
+\#if \$num_mboards() > $m and \$time_source$(m)()
+self.\$(id).set_time_source(\$time_source$(m), $m)
\#end if
########################################################################
\#if \$num_mboards() > $m and \$sd_spec$(m)()
@@ -84,16 +85,61 @@ self.\$(id).set_bandwidth(\$bw$(n), $n)
<key>type</key>
<type>enum</type>
<option>
- <name>Complex</name>
- <key>complex</key>
- <opt>type:COMPLEX_FLOAT32</opt>
- <opt>vlen:1</opt>
+ <name>Complex float32</name>
+ <key>fc32</key>
+ <opt>type:fc32</opt>
+ </option>
+ <option>
+ <name>Complex int16</name>
+ <key>sc16</key>
+ <opt>type:sc16</opt>
</option>
<option>
- <name>Short</name>
- <key>short</key>
- <opt>type:COMPLEX_INT16</opt>
- <opt>vlen:2</opt>
+ <name>VITA word32</name>
+ <key>item32</key>
+ <opt>type:s32</opt>
+ </option>
+ </param>
+ <param>
+ <name>Wire Format</name>
+ <key>otw</key>
+ <value></value>
+ <type>string</type>
+ <hide>
+ \#if \$otw()
+ none
+ \#else
+ part
+ \#end if
+ </hide>
+ <option>
+ <name>Automatic</name>
+ <key></key>
+ </option>
+ <option>
+ <name>Complex int16</name>
+ <key>sc16</key>
+ </option>
+ <option>
+ <name>Complex int8</name>
+ <key>sc8</key>
+ </option>
+ </param>
+ <param>
+ <name>Stream args</name>
+ <key>stream_args</key>
+ <value></value>
+ <type>string</type>
+ <hide>
+ \#if \$stream_args()
+ none
+ \#else
+ part
+ \#end if
+ </hide>
+ <option>
+ <name>scalar=1024</name>
+ <key>scalar=1024</key>
</option>
</param>
<param>
@@ -150,14 +196,14 @@ self.\$(id).set_bandwidth(\$bw$(n), $n)
</param>
#for $m in range($max_mboards)
<param>
- <name>Mb$(m): Ref Source</name>
- <key>ref_source$(m)</key>
+ <name>Mb$(m): Clock Source</name>
+ <key>clock_source$(m)</key>
<value></value>
- <type>enum</type>
+ <type>string</type>
<hide>
\#if not \$num_mboards() > $m
all
- \#elif \$ref_source$(m)()
+ \#elif \$clock_source$(m)()
none
\#else
part
@@ -167,6 +213,26 @@ self.\$(id).set_bandwidth(\$bw$(n), $n)
<option><name>Internal</name><key>internal</key></option>
<option><name>External</name><key>external</key></option>
<option><name>MIMO Cable</name><key>mimo</key></option>
+ <option><name>O/B GPSDO</name><key>gpsdo</key></option>
+ </param>
+ <param>
+ <name>Mb$(m): Time Source</name>
+ <key>time_source$(m)</key>
+ <value></value>
+ <type>string</type>
+ <hide>
+ \#if not \$num_mboards() > $m
+ all
+ \#elif \$time_source$(m)()
+ none
+ \#else
+ part
+ \#end if
+ </hide>
+ <option><name>Default</name><key></key></option>
+ <option><name>External</name><key>external</key></option>
+ <option><name>MIMO Cable</name><key>mimo</key></option>
+ <option><name>O/B GPSDO</name><key>gpsdo</key></option>
</param>
<param>
<name>Mb$(m): Subdev Spec</name>
@@ -210,8 +276,7 @@ self.\$(id).set_bandwidth(\$bw$(n), $n)
<check>\$nchan >= \$num_mboards</check>
<$sourk>
<name>$direction</name>
- <type>\$type</type>
- <vlen>\$type.vlen</vlen>
+ <type>\$type.type</type>
<nports>\$nchan</nports>
</$sourk>
<doc>
@@ -225,6 +290,19 @@ USRP1 Example: serial=12345678
USRP2 Example: addr=192.168.10.2
USRP2 Example: addr0=192.168.10.2, addr1=192.168.10.3
+$(direction.title()) Type:
+This parameter controls the data type of the stream in gnuradio.
+
+Wire Format:
+This parameter controls the form of the data over the bus/network. \
+Complex bytes may be used to trade off precision for bandwidth. \
+Not all formats are supported on all devices.
+
+Stream Args:
+Optional arguments to be passed in the UHD streamer object. \
+Streamer args is a list of key/value pairs; usage is determined by the implementation.
+Ex: the scalar key affects the scaling between 16 and 8 bit integers in sc8 wire format.
+
Num Motherboards:
Selects the number of USRP motherboards in this device configuration.
diff --git a/gr-uhd/include/gr_uhd_usrp_sink.h b/gr-uhd/include/gr_uhd_usrp_sink.h
index f11d00063..ce76ec03b 100644
--- a/gr-uhd/include/gr_uhd_usrp_sink.h
+++ b/gr-uhd/include/gr_uhd_usrp_sink.h
@@ -26,6 +26,27 @@
#include <gr_sync_block.h>
#include <uhd/usrp/multi_usrp.hpp>
+#ifndef INCLUDED_UHD_STREAM_HPP
+namespace uhd{
+ struct GR_UHD_API stream_args_t{
+ stream_args_t(
+ const std::string &cpu = "",
+ const std::string &otw = ""
+ ){
+ cpu_format = cpu;
+ otw_format = otw;
+ }
+ std::string cpu_format;
+ std::string otw_format;
+ device_addr_t args;
+ std::vector<size_t> channels;
+ };
+}
+# define INCLUDED_UHD_STREAM_HPP
+#else
+# define GR_UHD_USE_STREAM_API
+#endif
+
class uhd_usrp_sink;
/*!
@@ -62,11 +83,42 @@ GR_UHD_API boost::shared_ptr<uhd_usrp_sink> uhd_make_usrp_sink(
size_t num_channels
);
+/*!
+ * \brief Make a new USRP sink block.
+ *
+ * The USRP sink block reads a stream and transmits the samples.
+ * The sink block also provides API calls for transmitter settings.
+ *
+ * TX Stream tagging:
+ *
+ * The following tag keys will be consumed by the work function:
+ * - pmt::pmt_string_to_symbol("tx_sob")
+ * - pmt::pmt_string_to_symbol("tx_eob")
+ * - pmt::pmt_string_to_symbol("tx_time")
+ *
+ * The sob and eob (start and end of burst) tag values are pmt booleans.
+ * When present, burst tags should be set to true (pmt::PMT_T).
+ *
+ * The timstamp tag value is a pmt tuple of the following:
+ * (uint64 seconds, and double fractional seconds).
+ *
+ * See the UHD manual for more detailed documentation:
+ * http://code.ettus.com/redmine/ettus/projects/uhd/wiki
+ *
+ * \param device_addr the address to identify the hardware
+ * \param stream_args the IO format and channel specification
+ * \return a new USRP sink block object
+ */
+GR_UHD_API boost::shared_ptr<uhd_usrp_sink> uhd_make_usrp_sink(
+ const uhd::device_addr_t &device_addr,
+ const uhd::stream_args_t &stream_args
+);
+
class GR_UHD_API uhd_usrp_sink : virtual public gr_sync_block{
public:
/*!
- * Set the subdevice specification.
+ * Set the frontend specification.
* \param spec the subdev spec markup string
* \param mboard the motherboard index 0 to M-1
*/
@@ -86,6 +138,12 @@ public:
virtual double get_samp_rate(void) = 0;
/*!
+ * Get the possible sample rates for the usrp device.
+ * \return a range of rates in Sps
+ */
+ virtual uhd::meta_range_t get_samp_rates(void) = 0;
+
+ /*!
* Tune the usrp device to the desired center frequency.
* \param tune_request the tune request instructions
* \param chan the channel index 0 to N-1
@@ -195,26 +253,53 @@ public:
virtual std::vector<std::string> get_antennas(size_t chan = 0) = 0;
/*!
- * Set the subdevice bandpass filter.
+ * Set the bandpass filter on the RF frontend.
* \param chan the channel index 0 to N-1
* \param bandwidth the filter bandwidth in Hz
*/
virtual void set_bandwidth(double bandwidth, size_t chan = 0) = 0;
/*!
- * Get a daughterboard sensor value.
+ * Set a constant DC offset value.
+ * The value is complex to control both I and Q.
+ * \param offset the dc offset (1.0 is full-scale)
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void set_dc_offset(const std::complex<double> &offset, size_t chan = 0) = 0;
+
+ /*!
+ * Set the RX frontend IQ imbalance correction.
+ * Use this to adjust the magnitude and phase of I and Q.
+ *
+ * \param correction the complex correction (1.0 is full-scale)
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void set_iq_balance(const std::complex<double> &correction, size_t chan = 0) = 0;
+
+ /*!
+ * Get an RF frontend sensor value.
* \param name the name of the sensor
* \param chan the channel index 0 to N-1
* \return a sensor value object
*/
- virtual uhd::sensor_value_t get_dboard_sensor(const std::string &name, size_t chan = 0) = 0;
+ virtual uhd::sensor_value_t get_sensor(const std::string &name, size_t chan = 0) = 0;
/*!
- * Get a list of possible daughterboard sensor names.
+ * Get a list of possible RF frontend sensor names.
* \param chan the channel index 0 to N-1
* \return a vector of sensor names
*/
- virtual std::vector<std::string> get_dboard_sensor_names(size_t chan = 0) = 0;
+ virtual std::vector<std::string> get_sensor_names(size_t chan = 0) = 0;
+
+ //! DEPRECATED use get_sensor
+ uhd::sensor_value_t get_dboard_sensor(const std::string &name, size_t chan = 0){
+ return this->get_sensor(name, chan);
+ }
+
+ //! DEPRECATED use get_sensor_names
+ std::vector<std::string> get_dboard_sensor_names(size_t chan = 0){
+ return this->get_sensor_names(chan);
+ }
/*!
* Get a motherboard sensor value.
@@ -233,12 +318,60 @@ public:
/*!
* Set the clock configuration.
+ * DEPRECATED for set_time/clock_source.
* \param clock_config the new configuration
* \param mboard the motherboard index 0 to M-1
*/
virtual void set_clock_config(const uhd::clock_config_t &clock_config, size_t mboard = 0) = 0;
/*!
+ * Set the time source for the usrp device.
+ * This sets the method of time synchronization,
+ * typically a pulse per second or an encoded time.
+ * Typical options for source: external, MIMO.
+ * \param source a string representing the time source
+ * \param mboard which motherboard to set the config
+ */
+ virtual void set_time_source(const std::string &source, const size_t mboard = 0) = 0;
+
+ /*!
+ * Get the currently set time source.
+ * \param mboard which motherboard to get the config
+ * \return the string representing the time source
+ */
+ virtual std::string get_time_source(const size_t mboard) = 0;
+
+ /*!
+ * Get a list of possible time sources.
+ * \param mboard which motherboard to get the list
+ * \return a vector of strings for possible settings
+ */
+ virtual std::vector<std::string> get_time_sources(const size_t mboard) = 0;
+
+ /*!
+ * Set the clock source for the usrp device.
+ * This sets the source for a 10 Mhz reference clock.
+ * Typical options for source: internal, external, MIMO.
+ * \param source a string representing the clock source
+ * \param mboard which motherboard to set the config
+ */
+ virtual void set_clock_source(const std::string &source, const size_t mboard = 0) = 0;
+
+ /*!
+ * Get the currently set clock source.
+ * \param mboard which motherboard to get the config
+ * \return the string representing the clock source
+ */
+ virtual std::string get_clock_source(const size_t mboard) = 0;
+
+ /*!
+ * Get a list of possible clock sources.
+ * \param mboard which motherboard to get the list
+ * \return a vector of strings for possible settings
+ */
+ virtual std::vector<std::string> get_clock_sources(const size_t mboard) = 0;
+
+ /*!
* Get the master clock rate.
* \param mboard the motherboard index 0 to M-1
* \return the clock rate in Hz
@@ -286,6 +419,25 @@ public:
virtual void set_time_unknown_pps(const uhd::time_spec_t &time_spec) = 0;
/*!
+ * Set the time at which the control commands will take effect.
+ *
+ * A timed command will back-pressure all subsequent timed commands,
+ * assuming that the subsequent commands occur within the time-window.
+ * If the time spec is late, the command will be activated upon arrival.
+ *
+ * \param time_spec the time at which the next command will activate
+ * \param mboard which motherboard to set the config
+ */
+ virtual void set_command_time(const uhd::time_spec_t &time_spec, size_t mboard = 0) = 0;
+
+ /*!
+ * Clear the command time so future commands are sent ASAP.
+ *
+ * \param mboard which motherboard to set the config
+ */
+ virtual void clear_command_time(size_t mboard = 0) = 0;
+
+ /*!
* Get access to the underlying uhd dboard iface object.
* \return the dboard_iface object
*/
diff --git a/gr-uhd/include/gr_uhd_usrp_source.h b/gr-uhd/include/gr_uhd_usrp_source.h
index fecc6e94d..e9fc41b93 100644
--- a/gr-uhd/include/gr_uhd_usrp_source.h
+++ b/gr-uhd/include/gr_uhd_usrp_source.h
@@ -26,6 +26,27 @@
#include <gr_sync_block.h>
#include <uhd/usrp/multi_usrp.hpp>
+#ifndef INCLUDED_UHD_STREAM_HPP
+namespace uhd{
+ struct GR_UHD_API stream_args_t{
+ stream_args_t(
+ const std::string &cpu = "",
+ const std::string &otw = ""
+ ){
+ cpu_format = cpu;
+ otw_format = otw;
+ }
+ std::string cpu_format;
+ std::string otw_format;
+ device_addr_t args;
+ std::vector<size_t> channels;
+ };
+}
+# define INCLUDED_UHD_STREAM_HPP
+#else
+# define GR_UHD_USE_STREAM_API
+#endif
+
class uhd_usrp_source;
/*!
@@ -58,11 +79,38 @@ GR_UHD_API boost::shared_ptr<uhd_usrp_source> uhd_make_usrp_source(
size_t num_channels
);
+/*!
+ * \brief Make a new USRP source block.
+ *
+ * The USRP source block receives samples and writes to a stream.
+ * The source block also provides API calls for receiver settings.
+ *
+ * RX Stream tagging:
+ *
+ * The following tag keys will be produced by the work function:
+ * - pmt::pmt_string_to_symbol("rx_time")
+ *
+ * The timstamp tag value is a pmt tuple of the following:
+ * (uint64 seconds, and double fractional seconds).
+ * A timestamp tag is produced at start() and after overflows.
+ *
+ * See the UHD manual for more detailed documentation:
+ * http://code.ettus.com/redmine/ettus/projects/uhd/wiki
+ *
+ * \param device_addr the address to identify the hardware
+ * \param stream_args the IO format and channel specification
+ * \return a new USRP source block object
+ */
+GR_UHD_API boost::shared_ptr<uhd_usrp_source> uhd_make_usrp_source(
+ const uhd::device_addr_t &device_addr,
+ const uhd::stream_args_t &stream_args
+);
+
class GR_UHD_API uhd_usrp_source : virtual public gr_sync_block{
public:
/*!
- * Set the subdevice specification.
+ * Set the frontend specification.
* \param spec the subdev spec markup string
* \param mboard the motherboard index 0 to M-1
*/
@@ -82,6 +130,12 @@ public:
virtual double get_samp_rate(void) = 0;
/*!
+ * Get the possible sample rates for the usrp device.
+ * \return a range of rates in Sps
+ */
+ virtual uhd::meta_range_t get_samp_rates(void) = 0;
+
+ /*!
* Tune the usrp device to the desired center frequency.
* \param tune_request the tune request instructions
* \param chan the channel index 0 to N-1
@@ -191,26 +245,68 @@ public:
virtual std::vector<std::string> get_antennas(size_t chan = 0) = 0;
/*!
- * Set the subdevice bandpass filter.
+ * Set the bandpass filter on the RF frontend.
* \param bandwidth the filter bandwidth in Hz
* \param chan the channel index 0 to N-1
*/
virtual void set_bandwidth(double bandwidth, size_t chan = 0) = 0;
/*!
- * Get a daughterboard sensor value.
+ * Enable/disable the automatic DC offset correction.
+ * The automatic correction subtracts out the long-run average.
+ *
+ * When disabled, the averaging option operation is halted.
+ * Once halted, the average value will be held constant
+ * until the user re-enables the automatic correction
+ * or overrides the value by manually setting the offset.
+ *
+ * \param enb true to enable automatic DC offset correction
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void set_dc_offset(const bool enb, size_t chan = 0) = 0;
+
+ /*!
+ * Set a constant DC offset value.
+ * The value is complex to control both I and Q.
+ * Only set this when automatic correction is disabled.
+ * \param offset the dc offset (1.0 is full-scale)
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void set_dc_offset(const std::complex<double> &offset, size_t chan = 0) = 0;
+
+ /*!
+ * Set the RX frontend IQ imbalance correction.
+ * Use this to adjust the magnitude and phase of I and Q.
+ *
+ * \param correction the complex correction value
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void set_iq_balance(const std::complex<double> &correction, size_t chan = 0) = 0;
+
+ /*!
+ * Get a RF frontend sensor value.
* \param name the name of the sensor
* \param chan the channel index 0 to N-1
* \return a sensor value object
*/
- virtual uhd::sensor_value_t get_dboard_sensor(const std::string &name, size_t chan = 0) = 0;
+ virtual uhd::sensor_value_t get_sensor(const std::string &name, size_t chan = 0) = 0;
/*!
- * Get a list of possible daughterboard sensor names.
+ * Get a list of possible RF frontend sensor names.
* \param chan the channel index 0 to N-1
* \return a vector of sensor names
*/
- virtual std::vector<std::string> get_dboard_sensor_names(size_t chan = 0) = 0;
+ virtual std::vector<std::string> get_sensor_names(size_t chan = 0) = 0;
+
+ //! DEPRECATED use get_sensor
+ uhd::sensor_value_t get_dboard_sensor(const std::string &name, size_t chan = 0){
+ return this->get_sensor(name, chan);
+ }
+
+ //! DEPRECATED use get_sensor_names
+ std::vector<std::string> get_dboard_sensor_names(size_t chan = 0){
+ return this->get_sensor_names(chan);
+ }
/*!
* Get a motherboard sensor value.
@@ -229,11 +325,59 @@ public:
/*!
* Set the clock configuration.
+ * DEPRECATED for set_time/clock_source.
* \param clock_config the new configuration
* \param mboard the motherboard index 0 to M-1
*/
virtual void set_clock_config(const uhd::clock_config_t &clock_config, size_t mboard = 0) = 0;
+ /*!
+ * Set the time source for the usrp device.
+ * This sets the method of time synchronization,
+ * typically a pulse per second or an encoded time.
+ * Typical options for source: external, MIMO.
+ * \param source a string representing the time source
+ * \param mboard which motherboard to set the config
+ */
+ virtual void set_time_source(const std::string &source, const size_t mboard = 0) = 0;
+
+ /*!
+ * Get the currently set time source.
+ * \param mboard which motherboard to get the config
+ * \return the string representing the time source
+ */
+ virtual std::string get_time_source(const size_t mboard) = 0;
+
+ /*!
+ * Get a list of possible time sources.
+ * \param mboard which motherboard to get the list
+ * \return a vector of strings for possible settings
+ */
+ virtual std::vector<std::string> get_time_sources(const size_t mboard) = 0;
+
+ /*!
+ * Set the clock source for the usrp device.
+ * This sets the source for a 10 Mhz reference clock.
+ * Typical options for source: internal, external, MIMO.
+ * \param source a string representing the clock source
+ * \param mboard which motherboard to set the config
+ */
+ virtual void set_clock_source(const std::string &source, const size_t mboard = 0) = 0;
+
+ /*!
+ * Get the currently set clock source.
+ * \param mboard which motherboard to get the config
+ * \return the string representing the clock source
+ */
+ virtual std::string get_clock_source(const size_t mboard) = 0;
+
+ /*!
+ * Get a list of possible clock sources.
+ * \param mboard which motherboard to get the list
+ * \return a vector of strings for possible settings
+ */
+ virtual std::vector<std::string> get_clock_sources(const size_t mboard) = 0;
+
/*!
* Get the master clock rate.
* \param mboard the motherboard index 0 to M-1
@@ -282,6 +426,25 @@ public:
virtual void set_time_unknown_pps(const uhd::time_spec_t &time_spec) = 0;
/*!
+ * Set the time at which the control commands will take effect.
+ *
+ * A timed command will back-pressure all subsequent timed commands,
+ * assuming that the subsequent commands occur within the time-window.
+ * If the time spec is late, the command will be activated upon arrival.
+ *
+ * \param time_spec the time at which the next command will activate
+ * \param mboard which motherboard to set the config
+ */
+ virtual void set_command_time(const uhd::time_spec_t &time_spec, size_t mboard = 0) = 0;
+
+ /*!
+ * Clear the command time so future commands are sent ASAP.
+ *
+ * \param mboard which motherboard to set the config
+ */
+ virtual void clear_command_time(size_t mboard = 0) = 0;
+
+ /*!
* Get access to the underlying uhd dboard iface object.
* \return the dboard_iface object
*/
diff --git a/gr-uhd/lib/gr_uhd_usrp_sink.cc b/gr-uhd/lib/gr_uhd_usrp_sink.cc
index 1a6595293..05237100c 100644
--- a/gr-uhd/lib/gr_uhd_usrp_sink.cc
+++ b/gr-uhd/lib/gr_uhd_usrp_sink.cc
@@ -22,11 +22,25 @@
#include <gr_uhd_usrp_sink.h>
#include <gr_io_signature.h>
#include <stdexcept>
+#include <boost/make_shared.hpp>
static const pmt::pmt_t SOB_KEY = pmt::pmt_string_to_symbol("tx_sob");
static const pmt::pmt_t EOB_KEY = pmt::pmt_string_to_symbol("tx_eob");
static const pmt::pmt_t TIME_KEY = pmt::pmt_string_to_symbol("tx_time");
+#include <uhd/convert.hpp>
+inline gr_io_signature_sptr args_to_io_sig(const uhd::stream_args_t &args){
+ const size_t nchan = std::max<size_t>(args.channels.size(), 1);
+ #ifdef GR_UHD_USE_STREAM_API
+ const size_t size = uhd::convert::get_bytes_per_item(args.cpu_format);
+ #else
+ size_t size = 0;
+ if (args.cpu_format == "fc32") size = 8;
+ if (args.cpu_format == "sc16") size = 4;
+ #endif
+ return gr_make_io_signature(nchan, nchan, size);
+}
+
/***********************************************************************
* UHD Multi USRP Sink Impl
**********************************************************************/
@@ -34,17 +48,18 @@ class uhd_usrp_sink_impl : public uhd_usrp_sink{
public:
uhd_usrp_sink_impl(
const uhd::device_addr_t &device_addr,
- const uhd::io_type_t &io_type,
- size_t num_channels
+ const uhd::stream_args_t &stream_args
):
gr_sync_block(
"gr uhd usrp sink",
- gr_make_io_signature(num_channels, num_channels, io_type.size),
+ args_to_io_sig(stream_args),
gr_make_io_signature(0, 0, 0)
),
- _type(io_type),
- _nchan(num_channels)
+ _stream_args(stream_args),
+ _nchan(std::max<size_t>(1, stream_args.channels.size()))
{
+ if (stream_args.cpu_format == "fc32") _type = boost::make_shared<uhd::io_type_t>(uhd::io_type_t::COMPLEX_FLOAT32);
+ if (stream_args.cpu_format == "sc16") _type = boost::make_shared<uhd::io_type_t>(uhd::io_type_t::COMPLEX_INT16);
_dev = uhd::usrp::multi_usrp::make(device_addr);
}
@@ -61,6 +76,14 @@ public:
return _dev->get_tx_rate();
}
+ uhd::meta_range_t get_samp_rates(void){
+ #ifdef UHD_USRP_MULTI_USRP_GET_RATES_API
+ return _dev->get_tx_rates();
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
uhd::tune_result_t set_center_freq(
const uhd::tune_request_t tune_request, size_t chan
){
@@ -119,11 +142,27 @@ public:
return _dev->set_tx_bandwidth(bandwidth, chan);
}
- uhd::sensor_value_t get_dboard_sensor(const std::string &name, size_t chan){
+ void set_dc_offset(const std::complex<double> &offset, size_t chan){
+ #ifdef UHD_USRP_MULTI_USRP_FRONTEND_CAL_API
+ return _dev->set_tx_dc_offset(offset, chan);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ void set_iq_balance(const std::complex<double> &correction, size_t chan){
+ #ifdef UHD_USRP_MULTI_USRP_FRONTEND_CAL_API
+ return _dev->set_tx_iq_balance(correction, chan);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ uhd::sensor_value_t get_sensor(const std::string &name, size_t chan){
return _dev->get_tx_sensor(name, chan);
}
- std::vector<std::string> get_dboard_sensor_names(size_t chan){
+ std::vector<std::string> get_sensor_names(size_t chan){
return _dev->get_tx_sensor_names(chan);
}
@@ -139,6 +178,54 @@ public:
return _dev->set_clock_config(clock_config, mboard);
}
+ void set_time_source(const std::string &source, const size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API
+ return _dev->set_time_source(source, mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ std::string get_time_source(const size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API
+ return _dev->get_time_source(mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ std::vector<std::string> get_time_sources(const size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API
+ return _dev->get_time_sources(mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ void set_clock_source(const std::string &source, const size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API
+ return _dev->set_clock_source(source, mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ std::string get_clock_source(const size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API
+ return _dev->get_clock_source(mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ std::vector<std::string> get_clock_sources(const size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API
+ return _dev->get_clock_sources(mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
double get_clock_rate(size_t mboard){
return _dev->get_master_clock_rate(mboard);
}
@@ -167,6 +254,22 @@ public:
return _dev->set_time_unknown_pps(time_spec);
}
+ void set_command_time(const uhd::time_spec_t &time_spec, size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_COMMAND_TIME_API
+ return _dev->set_command_time(time_spec, mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ void clear_command_time(size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_COMMAND_TIME_API
+ return _dev->clear_command_time(mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
uhd::usrp::dboard_iface::sptr get_dboard_iface(size_t chan){
return _dev->get_tx_dboard_iface(chan);
}
@@ -194,11 +297,17 @@ public:
get_tags_in_range(_tags, 0, samp0_count, samp0_count + ninput_items);
if (not _tags.empty()) this->tag_work(ninput_items);
+ #ifdef GR_UHD_USE_STREAM_API
//send all ninput_items with metadata
+ const size_t num_sent = _tx_stream->send(
+ input_items, ninput_items, _metadata, 1.0
+ );
+ #else
const size_t num_sent = _dev->get_device()->send(
input_items, ninput_items, _metadata,
- _type, uhd::device::SEND_MODE_FULL_BUFF, 1.0
+ *_type, uhd::device::SEND_MODE_FULL_BUFF, 1.0
);
+ #endif
//increment the timespec by the number of samples sent
_metadata.time_spec += uhd::time_spec_t(0, num_sent, _sample_rate);
@@ -266,15 +375,25 @@ public:
//Send an empty start-of-burst packet to begin streaming.
//Set at a time in the near future to avoid late packets.
bool start(void){
+ #ifdef GR_UHD_USE_STREAM_API
+ _tx_stream = _dev->get_tx_stream(_stream_args);
+ #endif
+
_metadata.start_of_burst = true;
_metadata.end_of_burst = false;
_metadata.has_time_spec = _nchan > 1;
_metadata.time_spec = get_time_now() + uhd::time_spec_t(0.01);
+ #ifdef GR_UHD_USE_STREAM_API
+ _tx_stream->send(
+ gr_vector_const_void_star(_nchan), 0, _metadata, 1.0
+ );
+ #else
_dev->get_device()->send(
gr_vector_const_void_star(_nchan), 0, _metadata,
- _type, uhd::device::SEND_MODE_ONE_PACKET, 1.0
+ *_type, uhd::device::SEND_MODE_ONE_PACKET, 1.0
);
+ #endif
return true;
}
@@ -285,16 +404,24 @@ public:
_metadata.end_of_burst = true;
_metadata.has_time_spec = false;
+ #ifdef GR_UHD_USE_STREAM_API
+ _tx_stream->send(gr_vector_const_void_star(_nchan), 0, _metadata, 1.0);
+ #else
_dev->get_device()->send(
gr_vector_const_void_star(_nchan), 0, _metadata,
- _type, uhd::device::SEND_MODE_ONE_PACKET, 1.0
+ *_type, uhd::device::SEND_MODE_ONE_PACKET, 1.0
);
+ #endif
return true;
}
private:
uhd::usrp::multi_usrp::sptr _dev;
- const uhd::io_type_t _type;
+ const uhd::stream_args_t _stream_args;
+ boost::shared_ptr<uhd::io_type_t> _type;
+ #ifdef GR_UHD_USE_STREAM_API
+ uhd::tx_streamer::sptr _tx_stream;
+ #endif
size_t _nchan;
uhd::tx_metadata_t _metadata;
double _sample_rate;
@@ -311,7 +438,25 @@ boost::shared_ptr<uhd_usrp_sink> uhd_make_usrp_sink(
const uhd::io_type_t &io_type,
size_t num_channels
){
+ //fill in the streamer args
+ uhd::stream_args_t stream_args;
+ switch(io_type.tid){
+ case uhd::io_type_t::COMPLEX_FLOAT32: stream_args.cpu_format = "fc32"; break;
+ case uhd::io_type_t::COMPLEX_INT16: stream_args.cpu_format = "sc16"; break;
+ default: throw std::runtime_error("only complex float and shorts known to work");
+ }
+ stream_args.otw_format = "sc16"; //only sc16 known to work
+ for (size_t chan = 0; chan < num_channels; chan++)
+ stream_args.channels.push_back(chan); //linear mapping
+
+ return uhd_make_usrp_sink(device_addr, stream_args);
+}
+
+boost::shared_ptr<uhd_usrp_sink> uhd_make_usrp_sink(
+ const uhd::device_addr_t &device_addr,
+ const uhd::stream_args_t &stream_args
+){
return boost::shared_ptr<uhd_usrp_sink>(
- new uhd_usrp_sink_impl(device_addr, io_type, num_channels)
+ new uhd_usrp_sink_impl(device_addr, stream_args)
);
}
diff --git a/gr-uhd/lib/gr_uhd_usrp_source.cc b/gr-uhd/lib/gr_uhd_usrp_source.cc
index a3369ade0..953ef6995 100644
--- a/gr-uhd/lib/gr_uhd_usrp_source.cc
+++ b/gr-uhd/lib/gr_uhd_usrp_source.cc
@@ -24,9 +24,23 @@
#include <stdexcept>
#include <iostream>
#include <boost/format.hpp>
+#include <boost/make_shared.hpp>
static const pmt::pmt_t TIME_KEY = pmt::pmt_string_to_symbol("rx_time");
+#include <uhd/convert.hpp>
+inline gr_io_signature_sptr args_to_io_sig(const uhd::stream_args_t &args){
+ const size_t nchan = std::max<size_t>(args.channels.size(), 1);
+ #ifdef GR_UHD_USE_STREAM_API
+ const size_t size = uhd::convert::get_bytes_per_item(args.cpu_format);
+ #else
+ size_t size = 0;
+ if (args.cpu_format == "fc32") size = 8;
+ if (args.cpu_format == "sc16") size = 4;
+ #endif
+ return gr_make_io_signature(nchan, nchan, size);
+}
+
/***********************************************************************
* UHD Multi USRP Source Impl
**********************************************************************/
@@ -34,19 +48,20 @@ class uhd_usrp_source_impl : public uhd_usrp_source{
public:
uhd_usrp_source_impl(
const uhd::device_addr_t &device_addr,
- const uhd::io_type_t &io_type,
- size_t num_channels
+ const uhd::stream_args_t &stream_args
):
gr_sync_block(
"gr uhd usrp source",
gr_make_io_signature(0, 0, 0),
- gr_make_io_signature(num_channels, num_channels, io_type.size)
+ args_to_io_sig(stream_args)
),
- _type(io_type),
- _nchan(num_channels),
+ _stream_args(stream_args),
+ _nchan(std::max<size_t>(1, stream_args.channels.size())),
_stream_now(_nchan == 1),
_tag_now(false)
{
+ if (stream_args.cpu_format == "fc32") _type = boost::make_shared<uhd::io_type_t>(uhd::io_type_t::COMPLEX_FLOAT32);
+ if (stream_args.cpu_format == "sc16") _type = boost::make_shared<uhd::io_type_t>(uhd::io_type_t::COMPLEX_INT16);
std::stringstream str;
str << name() << unique_id();
_id = pmt::pmt_string_to_symbol(str.str());
@@ -65,6 +80,14 @@ public:
return _dev->get_rx_rate();
}
+ uhd::meta_range_t get_samp_rates(void){
+ #ifdef UHD_USRP_MULTI_USRP_GET_RATES_API
+ return _dev->get_rx_rates();
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
uhd::tune_result_t set_center_freq(
const uhd::tune_request_t tune_request, size_t chan
){
@@ -123,11 +146,35 @@ public:
return _dev->set_rx_bandwidth(bandwidth, chan);
}
- uhd::sensor_value_t get_dboard_sensor(const std::string &name, size_t chan){
+ void set_dc_offset(const bool enable, size_t chan){
+ #ifdef UHD_USRP_MULTI_USRP_FRONTEND_CAL_API
+ return _dev->set_rx_dc_offset(enable, chan);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ void set_dc_offset(const std::complex<double> &offset, size_t chan){
+ #ifdef UHD_USRP_MULTI_USRP_FRONTEND_CAL_API
+ return _dev->set_rx_dc_offset(offset, chan);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ void set_iq_balance(const std::complex<double> &correction, size_t chan){
+ #ifdef UHD_USRP_MULTI_USRP_FRONTEND_CAL_API
+ return _dev->set_rx_iq_balance(correction, chan);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ uhd::sensor_value_t get_sensor(const std::string &name, size_t chan){
return _dev->get_rx_sensor(name, chan);
}
- std::vector<std::string> get_dboard_sensor_names(size_t chan){
+ std::vector<std::string> get_sensor_names(size_t chan){
return _dev->get_rx_sensor_names(chan);
}
@@ -143,6 +190,54 @@ public:
return _dev->set_clock_config(clock_config, mboard);
}
+ void set_time_source(const std::string &source, const size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API
+ return _dev->set_time_source(source, mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ std::string get_time_source(const size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API
+ return _dev->get_time_source(mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ std::vector<std::string> get_time_sources(const size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API
+ return _dev->get_time_sources(mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ void set_clock_source(const std::string &source, const size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API
+ return _dev->set_clock_source(source, mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ std::string get_clock_source(const size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API
+ return _dev->get_clock_source(mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ std::vector<std::string> get_clock_sources(const size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API
+ return _dev->get_clock_sources(mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
double get_clock_rate(size_t mboard){
return _dev->get_master_clock_rate(mboard);
}
@@ -171,6 +266,22 @@ public:
return _dev->set_time_unknown_pps(time_spec);
}
+ void set_command_time(const uhd::time_spec_t &time_spec, size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_COMMAND_TIME_API
+ return _dev->set_command_time(time_spec, mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
+ void clear_command_time(size_t mboard){
+ #ifdef UHD_USRP_MULTI_USRP_COMMAND_TIME_API
+ return _dev->clear_command_time(mboard);
+ #else
+ throw std::runtime_error("not implemented in this version");
+ #endif
+ }
+
uhd::usrp::dboard_iface::sptr get_dboard_iface(size_t chan){
return _dev->get_rx_dboard_iface(chan);
}
@@ -187,22 +298,33 @@ public:
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items
){
+ #ifdef GR_UHD_USE_STREAM_API
//In order to allow for low-latency:
//We receive all available packets without timeout.
//This call can timeout under regular operation...
- size_t num_samps = _dev->get_device()->recv(
- output_items, noutput_items, _metadata,
- _type, uhd::device::RECV_MODE_FULL_BUFF, 0.0
+ size_t num_samps = _rx_stream->recv(
+ output_items, noutput_items, _metadata, 0.0
);
//If receive resulted in a timeout condition:
//We now receive a single packet with a large timeout.
if (_metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT){
+ num_samps = _rx_stream->recv(
+ output_items, noutput_items, _metadata, 1.0, true/*one pkt*/
+ );
+ }
+ #else
+ size_t num_samps = _dev->get_device()->recv(
+ output_items, noutput_items, _metadata,
+ *_type, uhd::device::RECV_MODE_FULL_BUFF, 0.0
+ );
+ if (_metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT){
num_samps = _dev->get_device()->recv(
output_items, noutput_items, _metadata,
- _type, uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ *_type, uhd::device::RECV_MODE_ONE_PACKET, 1.0
);
}
+ #endif
//handle possible errors conditions
switch(_metadata.error_code){
@@ -242,6 +364,10 @@ public:
}
bool start(void){
+ #ifdef GR_UHD_USE_STREAM_API
+ _rx_stream = _dev->get_rx_stream(_stream_args);
+ _samps_per_packet = _rx_stream->get_max_num_samps();
+ #endif
//setup a stream command that starts streaming slightly in the future
static const double reasonable_delay = 0.1; //order of magnitude over RTT
uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
@@ -260,10 +386,17 @@ public:
outputs.push_back(&buffs[i].front());
}
while (true){
+ #ifdef GR_UHD_USE_STREAM_API
+ const size_t bpi = uhd::convert::get_bytes_per_item(_stream_args.cpu_format);
+ const size_t num_samps = _rx_stream->recv(
+ outputs, nbytes/bpi, _metadata, 0.0
+ );
+ #else
const size_t num_samps = _dev->get_device()->recv(
- outputs, nbytes/_type.size, _metadata,
- _type, uhd::device::RECV_MODE_FULL_BUFF, 0.0
+ outputs, nbytes/_type->size, _metadata,
+ *_type, uhd::device::RECV_MODE_FULL_BUFF, 0.0
);
+ #endif
if (_metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) break;
}
}
@@ -278,7 +411,12 @@ public:
private:
uhd::usrp::multi_usrp::sptr _dev;
- const uhd::io_type_t _type;
+ const uhd::stream_args_t _stream_args;
+ boost::shared_ptr<uhd::io_type_t> _type;
+ #ifdef GR_UHD_USE_STREAM_API
+ uhd::rx_streamer::sptr _rx_stream;
+ size_t _samps_per_packet;
+ #endif
size_t _nchan;
bool _stream_now, _tag_now;
uhd::rx_metadata_t _metadata;
@@ -294,7 +432,25 @@ boost::shared_ptr<uhd_usrp_source> uhd_make_usrp_source(
const uhd::io_type_t &io_type,
size_t num_channels
){
+ //fill in the streamer args
+ uhd::stream_args_t stream_args;
+ switch(io_type.tid){
+ case uhd::io_type_t::COMPLEX_FLOAT32: stream_args.cpu_format = "fc32"; break;
+ case uhd::io_type_t::COMPLEX_INT16: stream_args.cpu_format = "sc16"; break;
+ default: throw std::runtime_error("only complex float and shorts known to work");
+ }
+ stream_args.otw_format = "sc16"; //only sc16 known to work
+ for (size_t chan = 0; chan < num_channels; chan++)
+ stream_args.channels.push_back(chan); //linear mapping
+
+ return uhd_make_usrp_source(device_addr, stream_args);
+}
+
+boost::shared_ptr<uhd_usrp_source> uhd_make_usrp_source(
+ const uhd::device_addr_t &device_addr,
+ const uhd::stream_args_t &stream_args
+){
return boost::shared_ptr<uhd_usrp_source>(
- new uhd_usrp_source_impl(device_addr, io_type, num_channels)
+ new uhd_usrp_source_impl(device_addr, stream_args)
);
}
diff --git a/gr-uhd/swig/__init__.py b/gr-uhd/swig/__init__.py
index 7745b4b79..d098a7b8a 100644
--- a/gr-uhd/swig/__init__.py
+++ b/gr-uhd/swig/__init__.py
@@ -57,6 +57,20 @@ def _prepare_uhd_swig():
def __setitem__(self, key, val): self.set(key, val)
setattr(uhd_swig, 'device_addr_t', device_addr_t)
+ #make the streamer args take **kwargs on init
+ class stream_args_t(uhd_swig.stream_args_t):
+ def __init__(self, *args, **kwargs):
+ super(stream_args_t, self).__init__(*args)
+ for key, val in kwargs.iteritems():
+ #for some reason, i cant assign a list in the constructor
+ #but what i can do is append the elements individually
+ if key == 'channels':
+ for v in val: self.channels.append(v)
+ elif key == 'args':
+ self.args = device_addr_t(val)
+ else: setattr(self, key, val)
+ setattr(uhd_swig, 'stream_args_t', stream_args_t)
+
#handle general things on all uhd_swig attributes
#Install the __str__ and __repr__ handlers if applicable
#Create aliases for uhd swig attributes to avoid the "_t"
@@ -88,9 +102,14 @@ def _prepare_uhd_swig():
(0, 'device_addr', device_addr),
(1, 'io_type', io_type),
):
- if len(args) > index: args[index] = cast(args[index])
- if kwargs.has_key(key): kwargs[key] = cast(kwargs[key])
- return old_constructor(*args, **kwargs)
+ try:
+ if len(args) > index: args[index] = cast(args[index])
+ if kwargs.has_key(key): kwargs[key] = cast(kwargs[key])
+ except: pass
+ #dont pass kwargs, it confuses swig, map into args list:
+ for key in ('device_addr', 'stream_args', 'io_type', 'num_channels'):
+ if kwargs.has_key(key): args.append(kwargs[key])
+ return old_constructor(*args)
return constructor_interceptor
setattr(uhd_swig, attr, constructor_factory(getattr(uhd_swig, attr)))
diff --git a/gr-uhd/swig/uhd_swig.i b/gr-uhd/swig/uhd_swig.i
index 7e612907c..6ff9d9843 100644
--- a/gr-uhd/swig/uhd_swig.i
+++ b/gr-uhd/swig/uhd_swig.i
@@ -48,6 +48,8 @@
////////////////////////////////////////////////////////////////////////
%template(string_vector_t) std::vector<std::string>;
+%template(size_vector_t) std::vector<size_t>;
+
%include <uhd/config.hpp>
%include <uhd/utils/pimpl.hpp>
diff --git a/volk/CMakeLists.txt b/volk/CMakeLists.txt
index 4b8fda059..fdde308ad 100644
--- a/volk/CMakeLists.txt
+++ b/volk/CMakeLists.txt
@@ -32,14 +32,32 @@ set(LIBVER 0.0.0)
set(CMAKE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) #allows this to be a sub-project
set(CMAKE_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) #allows this to be a sub-project
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) #location for custom "Modules"
+
+########################################################################
+# Environment setup
+########################################################################
+IF(NOT DEFINED BOOST_ROOT)
+ SET(BOOST_ROOT "")
+ENDIF()
+SET(BOOST_ROOT ${BOOST_ROOT} CACHE STRING "Modify search path for Boost components")
+
+#after caching user-defined value, make sure to add the install prefix
+SET(BOOST_ROOT ${BOOST_ROOT}:${CMAKE_INSTALL_PREFIX})
+
+IF(NOT DEFINED CROSSCOMPILE_MULTILIB)
+ SET(CROSSCOMPILE_MULTILIB "")
+ENDIF()
+SET(CROSSCOMPILE_MULTILIB ${CROSSCOMPILE_MULTILIB} CACHE STRING "Define \"true\" if you have and want to use multiple C development libs installed for cross compile")
+
########################################################################
# Dependencies setup
########################################################################
-find_package(PythonInterp)
-if(NOT PYTHONINTERP_FOUND)
- message(FATAL_ERROR "Python interpreter required by the build system.")
-endif(NOT PYTHONINTERP_FOUND)
+find_package(PythonInterp REQUIRED PYTHON_EXECUTABLE)
+find_package(Boost COMPONENTS unit_test_framework)
+find_package(ORC)
+
########################################################################
# Setup the package config file
diff --git a/volk/cmake/FindORC.cmake b/volk/cmake/FindORC.cmake
new file mode 100644
index 000000000..8d8c2d13e
--- /dev/null
+++ b/volk/cmake/FindORC.cmake
@@ -0,0 +1,36 @@
+FIND_PACKAGE(PkgConfig)
+PKG_CHECK_MODULES(PC_ORC orc-0.4)
+
+
+
+
+FIND_PROGRAM(ORCC_EXECUTABLE orcc
+ HINTS ${PC_ORC_TOOLSDIR}
+ PATHS ${ORC_ROOT}/bin ${CMAKE_INSTALL_PREFIX}/bin)
+
+FIND_PATH(ORC_INCLUDE_DIR NAMES orc/orc.h
+ HINTS ${PC_ORC_INCLUDEDIR}
+ PATHS ${ORC_ROOT}/include/orc-0.4 ${CMAKE_INSTALL_PREFIX}/include/orc-0.4)
+
+
+FIND_PATH(ORC_LIBRARY_DIR NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}orc-0.4${CMAKE_SHARED_LIBRARY_SUFFIX}
+ HINTS ${PC_ORC_LIBDIR}
+ PATHS ${ORC_ROOT}/lib${LIB_SUFFIX} ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
+
+FIND_LIBRARY(ORC_LIB orc-0.4
+ HINTS ${PC_ORC_LIBRARY_DIRS}
+ PATHS ${ORC_ROOT}/lib${LIB_SUFFIX} ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
+
+LIST(APPEND ORC_LIBRARY
+ ${ORC_LIB}
+)
+
+
+SET(ORC_INCLUDE_DIRS ${ORC_INCLUDE_DIR})
+SET(ORC_LIBRARIES ${ORC_LIBRARY})
+SET(ORC_LIBRARY_DIRS ${ORC_LIBRARY_DIR})
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(ORC "orc files" ORC_LIBRARY ORC_INCLUDE_DIR ORCC_EXECUTABLE)
+
+mark_as_advanced(ICE_INCLUDE_DIR ICE_LIBRARY ORCC_EXECUTABLE)
diff --git a/volk/gen/archs.xml b/volk/gen/archs.xml
index 960558b7c..effd90d33 100644
--- a/volk/gen/archs.xml
+++ b/volk/gen/archs.xml
@@ -1,8 +1,8 @@
<!-- archs appear in order of significance for blind, de-facto version ordering -->
<grammar>
-<arch name="generic" type="all">
- <flag>none</flag>
+<arch name="generic" type="all"> <!-- name and type are both required-->
+ <flag>none</flag> <!-- flag is the only required field-->
</arch>
<arch name="altivec" type="powerpc">
@@ -11,7 +11,7 @@
</arch>
<arch name="neon" type="arm">
- <flag>mfpu=neon -mfloat-abi=softfp -funsafe-math-optimizations</flag>
+ <flag>mfpu=neon,mfloat-abi=softfp,funsafe-math-optimizations</flag>
<alignment>16</alignment>
</arch>
@@ -29,7 +29,6 @@
<val>1</val>
<overrule>MD_SUBCPU</overrule>
<overrule_val>x86</overrule_val>
- <mutex>32</mutex>
</arch>
<arch name="3dnow" type="x86">
@@ -46,7 +45,7 @@
<op>0x80000001</op>
<reg>d</reg>
<shift>5</shift>
- <flag>sse4.2</flag>
+ <flag>msse4.2</flag>
<alignment>16</alignment>
</arch>
diff --git a/volk/gen/compilers.xml b/volk/gen/compilers.xml
new file mode 100644
index 000000000..70c82e555
--- /dev/null
+++ b/volk/gen/compilers.xml
@@ -0,0 +1,18 @@
+<!-- compilers remap gcc-specific information from archs.xml to specific compiler cases-->
+<grammar>
+
+<compiler name="MSVC">
+ <remap name="mmmx">arch:SSE</remap>
+ <remap name="msse">arch:SSE</remap>
+ <remap name="msse2">arch:SSE2</remap>
+ <prefix>/</prefix>
+</compiler>
+
+<compiler name="GNU">
+ <prefix>-</prefix>
+</compiler>
+
+
+
+
+</grammar> \ No newline at end of file
diff --git a/volk/gen/make_cpuid_c.py b/volk/gen/make_cpuid_c.py
index eb88dcd7f..7281f45a3 100644
--- a/volk/gen/make_cpuid_c.py
+++ b/volk/gen/make_cpuid_c.py
@@ -30,7 +30,11 @@ HEADER_TEMPL = """\
struct VOLK_CPU volk_cpu;
-#if defined(__i386__) || (__x86_64__)
+#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
+# define VOLK_CPU_x86
+#endif
+
+#if defined(VOLK_CPU_x86)
//implement get cpuid for gcc compilers using a copy of cpuid.h
#if defined(__GNUC__)
@@ -40,32 +44,32 @@ struct VOLK_CPU volk_cpu;
//implement get cpuid for MSVC compilers using __cpuid intrinsic
#elif defined(_MSC_VER)
#include <intrin.h>
-#define cpuid(op, r) __cpuid(r, op)
+#define cpuid_x86(op, r) __cpuid(r, op)
#else
#error "A get cpuid for volk is not available on this compiler..."
#endif
static inline unsigned int cpuid_eax(unsigned int op) {
- unsigned int regs[4];
+ int regs[4];
cpuid_x86 (op, regs);
return regs[0];
}
static inline unsigned int cpuid_ebx(unsigned int op) {
- unsigned int regs[4];
+ int regs[4];
cpuid_x86 (op, regs);
return regs[1];
}
static inline unsigned int cpuid_ecx(unsigned int op) {
- unsigned int regs[4];
+ int regs[4];
cpuid_x86 (op, regs);
return regs[2];
}
static inline unsigned int cpuid_edx(unsigned int op) {
- unsigned int regs[4];
+ int regs[4];
cpuid_x86 (op, regs);
return regs[3];
}
@@ -103,7 +107,7 @@ def make_cpuid_c(dom) :
if no_test:
tempstring = tempstring + """\
int i_can_has_%s () {
-#if defined(__i386__) || (__x86_64__)
+#if defined(VOLK_CPU_x86)
return 1;
#else
return 0;
@@ -115,7 +119,7 @@ int i_can_has_%s () {
elif op == "1":
tempstring = tempstring + """\
int i_can_has_%s () {
-#if defined(__i386__) || (__x86_64__)
+#if defined(VOLK_CPU_x86)
unsigned int e%sx = cpuid_e%sx (%s);
return ((e%sx >> %s) & 1) == %s;
#else
@@ -128,7 +132,7 @@ int i_can_has_%s () {
elif op == "0x80000001":
tempstring = tempstring + """\
int i_can_has_%s () {
-#if defined(__i386__) || (__x86_64__)
+#if defined(VOLK_CPU_x86)
unsigned int extended_fct_count = cpuid_eax(0x80000000);
if (extended_fct_count < 0x80000001)
return %s^1;
diff --git a/volk/lib/CMakeLists.txt b/volk/lib/CMakeLists.txt
index e18d13677..092c3ba0d 100644
--- a/volk/lib/CMakeLists.txt
+++ b/volk/lib/CMakeLists.txt
@@ -16,76 +16,141 @@
#
########################################################################
+# Setup the compiler name
+########################################################################
+set(COMPILER_NAME ${CMAKE_C_COMPILER_ID})
+if(MSVC) #its not set otherwise
+ set(COMPILER_NAME MSVC)
+endif()
+
+if(NOT DEFINED COMPILER_NAME)
+ message(FATAL_ERROR "COMPILER_NAME undefined. Volk build may not support this compiler.")
+endif()
+
+########################################################################
# Parse the arches xml file:
# Test each arch to see if the compiler supports the flag.
# If the test passes append the arch to the available list.
########################################################################
-#extract the arch lines from the xml file using crazy python
+#extract the compiler lines from the xml file using abusive python
+
+
+
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c
- "from xml.dom import minidom; print ';'.join(map(lambda a: '%s %s'%(a.attributes['name'].value,a.getElementsByTagName('flag')[0].firstChild.data),minidom.parse('${CMAKE_SOURCE_DIR}/gen/archs.xml').getElementsByTagName('arch')))"
- OUTPUT_VARIABLE arch_lines OUTPUT_STRIP_TRAILING_WHITESPACE
+ "from xml.dom import minidom; print ';'.join(map(lambda b: ','.join([','.join([b.attributes['name'].value,item.attributes['name'].value,item.firstChild.data]) for item in b.getElementsByTagName('remap')]), minidom.parse('${CMAKE_SOURCE_DIR}/gen/compilers.xml').getElementsByTagName('compiler')))"
+
+ OUTPUT_VARIABLE compiler_lines OUTPUT_STRIP_TRAILING_WHITESPACE
)
-#get any mutually exclusive archs so we can exclude them
-#this is really for compilers which can do both 32- and 64-bit compilations.
+foreach(thing ${compiler_lines})
+ string(REGEX REPLACE "," ";" thing_list ${thing})
+ list(FIND thing_list ${COMPILER_NAME} check_val)
+ if(NOT ("${check_val}" STREQUAL "-1"))
+ string(REGEX REPLACE "${COMPILER_NAME}," ";" filter_string ${thing})
+ endif()
+endforeach()
+
+
+#extract compiler prefixes from the xml file using abusive python
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c
- "from xml.dom import minidom; print ';'.join(map(lambda a: '%s %s'%(a.parentNode.attributes['name'].value,a.firstChild.data),minidom.parse('${CMAKE_SOURCE_DIR}/gen/archs.xml').getElementsByTagName('mutex')))"
- OUTPUT_VARIABLE mutex_lines OUTPUT_STRIP_TRAILING_WHITESPACE
+ "from xml.dom import minidom; print ';'.join(map(lambda b: ','.join([','.join([b.attributes['name'].value,item.firstChild.data]) for item in b.getElementsByTagName('prefix')]), minidom.parse('${CMAKE_SOURCE_DIR}/gen/compilers.xml').getElementsByTagName('compiler')))"
+
+ OUTPUT_VARIABLE compiler_prefixes OUTPUT_STRIP_TRAILING_WHITESPACE
)
-#This macro sets the ${arch}_flag variable,
-#and handles special cases for MSVC arch flags.
-macro(set_arch_flag name flag)
- if(MSVC AND ${name} STREQUAL "mmx")
- set(${name}_flag "/arch:SSE") #no /arch:MMX
- elseif(MSVC AND ${name} STREQUAL "sse")
- set(${name}_flag "/arch:SSE")
- elseif(MSVC AND ${name} STREQUAL "sse2")
- set(${name}_flag "/arch:SSE2")
- else()
- set(${name}_flag -${flag})
+foreach(thing ${compiler_prefixes})
+ string(REGEX REPLACE "," ";" thing_list ${thing})
+ list(FIND thing_list ${COMPILER_NAME} check_val)
+ if(NOT ("${check_val}" STREQUAL "-1"))
+ list(GET thing_list "1" prefix)
endif()
-endmacro(set_arch_flag)
+endforeach()
+
+
+
+
+#extract the arch lines from the xml file using abusive python
+execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} -c
+ "from xml.dom import minidom; print ';'.join(map(lambda a: '%s %s %s %s'%(a.attributes['name'].value,a.getElementsByTagName('flag')[0].firstChild.data,a.getElementsByTagName('overrule')[0].firstChild.data,a.getElementsByTagName('overrule_val')[0].firstChild.data) if (len(a.getElementsByTagName('overrule'))) else '%s %s %s %s'%(a.attributes['name'].value,a.getElementsByTagName('flag')[0].firstChild.data,'no_overrule', 'no_overrule_val'), minidom.parse('${CMAKE_SOURCE_DIR}/gen/archs.xml').getElementsByTagName('arch')))"
+
+ OUTPUT_VARIABLE arch_lines OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+
+
+
+#set the various overrule values (see archs.xml)
+#a lot of this is translating between automake and cmake
+if(NOT "${CROSSCOMPILE_MULTILIB}" STREQUAL "true")
+ set(MD_SUBCPU ${CMAKE_HOST_SYSTEM_PROCESSOR})
+endif()
+if(NOT "${ORC_FOUND}" STREQUAL "TRUE")
+ set(LV_HAVE_ORC "no")
+endif()
+
+
+
-macro(handle_arch name flag)
+
+macro(compiler_filter name flag)
+ set(filtered_flag ${flag})
+ foreach(thing ${filter_string})
+ string(REGEX REPLACE "," ";" flagmap ${thing})
+ list(GET flagmap "0" key)
+ list(GET flagmap "1" val)
+ string(REGEX MATCH "^${key}$" found ${flag})
+ if("${found}" STREQUAL "${key}")
+ string(REGEX REPLACE "^${key}$" "${val}" filtered_flag ${flag})
+ endif()
+ endforeach()
+ set(${name}_flag "${prefix}${filtered_flag}")
+endmacro()
+
+
+
+
+
+
+
+macro(handle_arch name flag overrule overrule_val)
+
+ #handle overrule
+ if("${${overrule}}" STREQUAL "${overrule_val}")
+ set(have_${name} FALSE)
+ message(STATUS "${name} overruled")
#handle special case for none flag
- if(${flag} STREQUAL "none")
+ elseif(${flag} STREQUAL "none")
set(have_${name} TRUE)
-
- #otherwise test the flag against the compiler
+ #otherwise test the flag(s) against the compiler
else()
include(CheckCXXCompilerFlag)
- set_arch_flag(${name} ${flag})
- CHECK_CXX_COMPILER_FLAG(${${name}_flag} have_${name})
+ string(REGEX REPLACE "," ";" flag_list ${flag})
+ set(have_${name} 1)
+ foreach(thing ${flag_list})
+ compiler_filter(${name} ${thing})
+ CHECK_CXX_COMPILER_FLAG(${${name}_flag} have_${thing})
+ if(NOT (${have_${name}} AND ("${have_${thing}}" STREQUAL "1")))
+ set(have_${name} 0)
+ endif()
+ endforeach()
endif()
if(have_${name})
list(APPEND available_arches ${name})
endif()
-endmacro(handle_arch)
-macro(remove_mutex name mutex)
- if(have_${name})
- unset(have_${mutex})
- endif()
- list(REMOVE_ITEM available_arches ${mutex})
-endmacro(remove_mutex)
+endmacro(handle_arch)
#create a list of available arches
foreach(arch_line ${arch_lines})
- separate_arguments(args UNIX_COMMAND "${arch_line}")
+ string(REPLACE " " ";" args "${arch_line}")
handle_arch(${args})
endforeach(arch_line)
-#strip out mutex archs
-foreach(mutex_line ${mutex_lines})
- separate_arguments(args UNIX_COMMAND "${mutex_line}")
- remove_mutex(${args})
-endforeach(mutex_line)
-
message(STATUS "Available arches: ${available_arches}")
########################################################################
@@ -114,10 +179,12 @@ macro(handle_machine1 name)
set(machine_flags "${machine_flags} ${${arch}_flag}")
endforeach(arch)
+ string(REGEX REPLACE "^[ \t]+" "" machine_flags "${machine_flags}")
+
if(is_match)
#this is a match, append the source and set its flags
set(machine_source ${CMAKE_CURRENT_BINARY_DIR}/volk_machine_${name}.c)
- set_source_files_properties(${machine_source} PROPERTIES COMPILE_FLAGS ${machine_flags})
+ set_source_files_properties(${machine_source} PROPERTIES COMPILE_FLAGS "${machine_flags}")
list(APPEND machine_sources ${machine_source})
list(APPEND machine_defs ${machine_def})
list(APPEND available_machines ${name})
@@ -138,7 +205,7 @@ endmacro(handle_machine)
#setup the available machines
foreach(machine_line ${machine_lines})
- separate_arguments(args UNIX_COMMAND "${machine_line}")
+ string(REPLACE " " ";" args "${machine_line}")
handle_machine(${args})
endforeach(machine_line)
@@ -168,20 +235,10 @@ file(GLOB xml_files ${CMAKE_SOURCE_DIR}/gen/*.xml)
file(GLOB py_files ${CMAKE_SOURCE_DIR}/gen/*.py)
file(GLOB h_files ${CMAKE_SOURCE_DIR}/include/volk/*.h)
-#make sure we can use -B with python (introduced in 2.6)
-execute_process(
- COMMAND ${PYTHON_EXECUTABLE} -B -c ""
- OUTPUT_QUIET ERROR_QUIET
- RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT
-)
-if(PYTHON_HAS_DASH_B_RESULT EQUAL 0)
- set(PYTHON_DASH_B "-B")
-endif()
-
add_custom_command(
OUTPUT ${volk_gen_sources}
DEPENDS ${xml_files} ${py_files} ${h_files}
- COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ COMMAND ${PYTHON_EXECUTABLE} -B
${CMAKE_SOURCE_DIR}/gen/volk_register.py
${CMAKE_BINARY_DIR}
)
@@ -189,14 +246,12 @@ add_custom_command(
########################################################################
# Handle orc support
########################################################################
-find_package(PkgConfig)
-if(PKG_CONFIG_FOUND)
-PKG_CHECK_MODULES(ORC "orc-0.4 > 0.4.11")
-endif(PKG_CONFIG_FOUND)
-find_program(ORCC_EXECUTABLE orcc)
-if(ORC_FOUND AND ORCC_EXECUTABLE)
+
+
+
+if(ORC_FOUND)
#setup orc library usage
include_directories(${ORC_INCLUDE_DIRS})
link_directories(${ORC_LIBRARY_DIRS})
@@ -225,16 +280,15 @@ endif()
########################################################################
# Setup the volk sources list and library
########################################################################
-if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
- #http://gcc.gnu.org/wiki/Visibility
+if(NOT WIN32)
add_definitions(-fvisibility=hidden)
endif()
include_directories(
- ${CMAKE_BINARY_DIR}/include
${CMAKE_SOURCE_DIR}/include
- ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
)
list(APPEND volk_sources
@@ -254,11 +308,13 @@ if(MSVC)
include_directories(${CMAKE_SOURCE_DIR}/msvc)
#compile the sources as C++ due to the lack of complex.h under MSVC
set_source_files_properties(${volk_sources} PROPERTIES LANGUAGE CXX)
-endif(MSVC)
+endif()
#create the volk runtime library
add_library(volk SHARED ${volk_sources})
-target_link_libraries(volk ${ORC_LIBRARIES})
+if(ORC_FOUND)
+ target_link_libraries(volk ${ORC_LIBRARIES})
+endif(ORC_FOUND)
set_target_properties(volk PROPERTIES SOVERSION ${LIBVER})
set_target_properties(volk PROPERTIES DEFINE_SYMBOL "volk_EXPORTS")
@@ -271,23 +327,24 @@ install(TARGETS volk
########################################################################
# Build the QA test application
########################################################################
-find_package(Boost COMPONENTS unit_test_framework)
+
if(Boost_FOUND)
-set_source_files_properties(
- ${CMAKE_CURRENT_SOURCE_DIR}/testqa.cc PROPERTIES
- COMPILE_DEFINITIONS "BOOST_TEST_DYN_LINK;BOOST_TEST_MAIN"
-)
+ set_source_files_properties(
+ ${CMAKE_CURRENT_SOURCE_DIR}/testqa.cc PROPERTIES
+ COMPILE_DEFINITIONS "BOOST_TEST_DYN_LINK;BOOST_TEST_MAIN"
+ )
-include_directories(${Boost_INCLUDE_DIRS})
-link_directories(${Boost_LIBRARY_DIRS})
+ include_directories(${Boost_INCLUDE_DIRS})
+ link_directories(${Boost_LIBRARY_DIRS})
-add_executable(test_all
- ${CMAKE_CURRENT_SOURCE_DIR}/testqa.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/qa_utils.cc
-)
-target_link_libraries(test_all volk ${Boost_LIBRARIES})
-#ADD_TEST(qa_volk_test_all test_all)
+ add_executable(test_all
+ ${CMAKE_CURRENT_SOURCE_DIR}/testqa.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_utils.cc
+ )
+ target_link_libraries(test_all volk ${Boost_LIBRARIES})
+ add_test(qa_volk_test_all test_all)
+
+endif(Boost_FOUND)
-endif()