aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--cmake/Modules/FindAD9361.cmake52
-rw-r--r--cmake/Modules/FindIIO.cmake52
-rw-r--r--gnuradio-runtime/python/gnuradio/__init__.py1
-rw-r--r--gr-iio/CMakeLists.txt65
-rw-r--r--gr-iio/examples/CMakeLists.txt18
-rw-r--r--gr-iio/examples/attr-sink-source.grc310
-rw-r--r--gr-iio/examples/attr-source.grc1892
-rw-r--r--gr-iio/examples/cyclic-sine.grc195
-rw-r--r--gr-iio/examples/cyclic-sine_pluto.grc173
-rw-r--r--gr-iio/examples/fm-transmitter_pluto.grc202
-rw-r--r--gr-iio/examples/fmradio_pluto.grc265
-rw-r--r--gr-iio/gnuradio-iio.pc.in11
-rw-r--r--gr-iio/grc/CMakeLists.txt9
-rw-r--r--gr-iio/grc/iio.tree.yml17
-rw-r--r--gr-iio/grc/iio_attr_sink.block.yml52
-rw-r--r--gr-iio/grc/iio_attr_source.block.yml85
-rw-r--r--gr-iio/grc/iio_attr_updater.block.yml31
-rw-r--r--gr-iio/grc/iio_dds_control.block.yml212
-rw-r--r--gr-iio/grc/iio_device_sink.block.yml58
-rw-r--r--gr-iio/grc/iio_device_source.block.yml51
-rw-r--r--gr-iio/grc/iio_fmcomms2_sink.block.yml129
-rw-r--r--gr-iio/grc/iio_fmcomms2_source.block.yml154
-rw-r--r--gr-iio/grc/iio_fmcomms5_sink.block.yml161
-rw-r--r--gr-iio/grc/iio_fmcomms5_source.block.yml207
-rw-r--r--gr-iio/grc/iio_pluto_sink.block.yml94
-rw-r--r--gr-iio/grc/iio_pluto_source.block.yml116
-rw-r--r--gr-iio/include/gnuradio/iio/CMakeLists.txt27
-rw-r--r--gr-iio/include/gnuradio/iio/api.h21
-rw-r--r--gr-iio/include/gnuradio/iio/attr_sink.h64
-rw-r--r--gr-iio/include/gnuradio/iio/attr_source.h78
-rw-r--r--gr-iio/include/gnuradio/iio/attr_updater.h53
-rw-r--r--gr-iio/include/gnuradio/iio/dds_control.h62
-rw-r--r--gr-iio/include/gnuradio/iio/device_sink.h79
-rw-r--r--gr-iio/include/gnuradio/iio/device_source.h77
-rw-r--r--gr-iio/include/gnuradio/iio/fmcomms2_sink.h229
-rw-r--r--gr-iio/include/gnuradio/iio/fmcomms2_source.h305
-rw-r--r--gr-iio/include/gnuradio/iio/fmcomms5_sink.h278
-rw-r--r--gr-iio/include/gnuradio/iio/fmcomms5_source.h387
-rw-r--r--gr-iio/include/gnuradio/iio/pluto_sink.h78
-rw-r--r--gr-iio/include/gnuradio/iio/pluto_source.h91
-rw-r--r--gr-iio/lib/CMakeLists.txt63
-rw-r--r--gr-iio/lib/attr_sink_impl.cc153
-rw-r--r--gr-iio/lib/attr_sink_impl.h52
-rw-r--r--gr-iio/lib/attr_source_impl.cc286
-rw-r--r--gr-iio/lib/attr_source_impl.h74
-rw-r--r--gr-iio/lib/attr_updater_impl.cc120
-rw-r--r--gr-iio/lib/attr_updater_impl.h50
-rw-r--r--gr-iio/lib/dds_control.cc155
-rw-r--r--gr-iio/lib/dds_control.h53
-rw-r--r--gr-iio/lib/device_sink_impl.cc201
-rw-r--r--gr-iio/lib/device_sink_impl.h61
-rw-r--r--gr-iio/lib/device_source_impl.cc409
-rw-r--r--gr-iio/lib/device_source_impl.h102
-rw-r--r--gr-iio/lib/fmcomms2_sink_impl.cc294
-rw-r--r--gr-iio/lib/fmcomms2_sink_impl.h76
-rw-r--r--gr-iio/lib/fmcomms2_source_impl.cc348
-rw-r--r--gr-iio/lib/fmcomms2_source_impl.h77
-rw-r--r--gr-iio/lib/fmcomms5_sink_impl.cc358
-rw-r--r--gr-iio/lib/fmcomms5_sink_impl.h100
-rw-r--r--gr-iio/lib/fmcomms5_source_impl.cc413
-rw-r--r--gr-iio/lib/fmcomms5_source_impl.h113
-rw-r--r--gr-iio/lib/pluto_sink_impl.cc82
-rw-r--r--gr-iio/lib/pluto_sink_impl.h42
-rw-r--r--gr-iio/lib/pluto_source_impl.cc137
-rw-r--r--gr-iio/lib/pluto_source_impl.h51
-rw-r--r--gr-iio/python/iio/CMakeLists.txt40
-rw-r--r--gr-iio/python/iio/__init__.py35
-rw-r--r--gr-iio/python/iio/bindings/CMakeLists.txt31
-rw-r--r--gr-iio/python/iio/bindings/attr_sink_python.cc49
-rw-r--r--gr-iio/python/iio/bindings/attr_source_python.cc57
-rw-r--r--gr-iio/python/iio/bindings/attr_updater_python.cc51
-rw-r--r--gr-iio/python/iio/bindings/dds_control_python.cc55
-rw-r--r--gr-iio/python/iio/bindings/device_sink_python.cc54
-rw-r--r--gr-iio/python/iio/bindings/device_source_python.cc63
-rw-r--r--gr-iio/python/iio/bindings/docstrings/attr_sink_pydoc_template.h19
-rw-r--r--gr-iio/python/iio/bindings/docstrings/attr_source_pydoc_template.h19
-rw-r--r--gr-iio/python/iio/bindings/docstrings/attr_updater_pydoc_template.h21
-rw-r--r--gr-iio/python/iio/bindings/docstrings/dds_control_pydoc_template.h22
-rw-r--r--gr-iio/python/iio/bindings/docstrings/device_sink_pydoc_template.h19
-rw-r--r--gr-iio/python/iio/bindings/docstrings/device_source_pydoc_template.h23
-rw-r--r--gr-iio/python/iio/bindings/docstrings/fmcomms2_sink_f32c_pydoc_template.h21
-rw-r--r--gr-iio/python/iio/bindings/docstrings/fmcomms2_sink_pydoc_template.h21
-rw-r--r--gr-iio/python/iio/bindings/docstrings/fmcomms2_source_f32c_pydoc_template.h21
-rw-r--r--gr-iio/python/iio/bindings/docstrings/fmcomms2_source_pydoc_template.h21
-rw-r--r--gr-iio/python/iio/bindings/docstrings/fmcomms5_sink_f32c_pydoc_template.h21
-rw-r--r--gr-iio/python/iio/bindings/docstrings/fmcomms5_sink_pydoc_template.h21
-rw-r--r--gr-iio/python/iio/bindings/docstrings/fmcomms5_source_f32c_pydoc_template.h21
-rw-r--r--gr-iio/python/iio/bindings/docstrings/fmcomms5_source_pydoc_template.h21
-rw-r--r--gr-iio/python/iio/bindings/docstrings/pluto_sink_pydoc_template.h21
-rw-r--r--gr-iio/python/iio/bindings/docstrings/pluto_source_pydoc_template.h21
-rw-r--r--gr-iio/python/iio/bindings/fmcomms2_sink_f32c_python.cc75
-rw-r--r--gr-iio/python/iio/bindings/fmcomms2_sink_python.cc77
-rw-r--r--gr-iio/python/iio/bindings/fmcomms2_source_f32c_python.cc84
-rw-r--r--gr-iio/python/iio/bindings/fmcomms2_source_python.cc86
-rw-r--r--gr-iio/python/iio/bindings/fmcomms5_sink_f32c_python.cc83
-rw-r--r--gr-iio/python/iio/bindings/fmcomms5_sink_python.cc87
-rw-r--r--gr-iio/python/iio/bindings/fmcomms5_source_f32c_python.cc96
-rw-r--r--gr-iio/python/iio/bindings/fmcomms5_source_python.cc100
-rw-r--r--gr-iio/python/iio/bindings/pluto_sink_python.cc65
-rw-r--r--gr-iio/python/iio/bindings/pluto_source_python.cc75
-rw-r--r--gr-iio/python/iio/bindings/python_bindings.cc69
-rw-r--r--gr-iio/python/iio/qa_iio.py45
103 files changed, 12022 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e916d1da1e..ebedcee677 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -461,6 +461,7 @@ add_subdirectory(gr-dtv)
add_subdirectory(gr-audio)
add_subdirectory(gr-channels)
add_subdirectory(gr-pdu)
+add_subdirectory(gr-iio)
add_subdirectory(gr-qtgui)
add_subdirectory(gr-trellis)
add_subdirectory(gr-uhd)
diff --git a/cmake/Modules/FindAD9361.cmake b/cmake/Modules/FindAD9361.cmake
new file mode 100644
index 0000000000..b17798c27b
--- /dev/null
+++ b/cmake/Modules/FindAD9361.cmake
@@ -0,0 +1,52 @@
+# Copyright 2021 Horden Engineering
+# Author: Adam Horden <adam.horden@horden.engineering>
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+# - Find libad9361
+# Find the native libad9361 includes and library
+#
+# LIBAD9361_FOUND - True if libad9361 is found.
+# LIBAD9361_INCLUDE_DIR - Where to find ad9361.h.
+# LIBAD9361_LIBRARIES - List of libraries when using libad9361.
+
+set(LIBAD9361_NAMES ad9361)
+find_library(LIBAD9361_LIBRARY
+ NAMES ${LIBAD9361_NAMES}
+ PATHS /usr/lib
+ /usr/lib64
+ /usr/local/lib
+ /usr/local/lib64
+ /opt/local/lib
+ /opt/local/lib64
+)
+
+find_path(LIBAD9361_INCLUDE_DIR ad9361.h
+ /usr/include
+ /usr/local/include
+ /opt/local/include
+)
+
+if (LIBAD9361_INCLUDE_DIR AND LIBAD9361_LIBRARY)
+ set(LIBAD9361_FOUND TRUE)
+ set(LIBAD9361_INCLUDE_DIRS ${LIBAD9361_INCLUDE_DIR})
+ set(LIBAD9361_LIBRARIES ${LIBAD9361_LIBRARY})
+else ()
+ set(LIBAD9361_FOUND FALSE)
+ set(LIBAD9361_INCLUDE_DIR "")
+ set(LIBAD9361_INCLUDE_DIRS "")
+ set(LIBAD9361_LIBRARY "")
+ set(LIBAD9361_LIBRARIES "")
+endif ()
+
+if (LIBAD9361_FOUND)
+ message(STATUS "Found libad9361 library: ${LIBAD9361_LIBRARIES}")
+endif ()
+
+mark_as_advanced(
+ LIBAD9361_INCLUDE_DIRS
+ LIBAD9361_LIBRARIES
+)
diff --git a/cmake/Modules/FindIIO.cmake b/cmake/Modules/FindIIO.cmake
new file mode 100644
index 0000000000..a14c216984
--- /dev/null
+++ b/cmake/Modules/FindIIO.cmake
@@ -0,0 +1,52 @@
+# Copyright 2021 Horden Engineering
+# Author: Adam Horden <adam.horden@horden.engineering>
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+# - Find libiio
+# Find the native libiio includes and library
+#
+# LIBIIO_FOUND - True if libiio is found.
+# LIBIIO_INCLUDE_DIR - Where to find iio.h.
+# LIBIIO_LIBRARIES - List of libraries when using libiio.
+
+set(LIBIIO_NAMES iio)
+find_library(LIBIIO_LIBRARY
+ NAMES ${LIBIIO_NAMES}
+ PATHS /usr/lib
+ /usr/lib64
+ /usr/local/lib
+ /usr/local/lib64
+ /opt/local/lib
+ /opt/local/lib64
+)
+
+find_path(LIBIIO_INCLUDE_DIR iio.h
+ /usr/include
+ /usr/local/include
+ /opt/local/include
+)
+
+if (LIBIIO_INCLUDE_DIR AND LIBIIO_LIBRARY)
+ set(LIBIIO_FOUND TRUE)
+ set(LIBIIO_INCLUDE_DIRS ${LIBIIO_INCLUDE_DIR})
+ set(LIBIIO_LIBRARIES ${LIBIIO_LIBRARY})
+else ()
+ set(LIBIIO_FOUND FALSE)
+ set(LIBIIO_INCLUDE_DIR "")
+ set(LIBIIO_INCLUDE_DIRS "")
+ set(LIBIIO_LIBRARY "")
+ set(LIBIIO_LIBRARIES "")
+endif ()
+
+if (LIBIIO_FOUND)
+ message(STATUS "Found libiio library: ${LIBIIO_LIBRARIES}")
+endif ()
+
+mark_as_advanced(
+ LIBIIO_INCLUDE_DIRS
+ LIBIIO_LIBRARIES
+)
diff --git a/gnuradio-runtime/python/gnuradio/__init__.py b/gnuradio-runtime/python/gnuradio/__init__.py
index 7e8633b746..8b9e89c177 100644
--- a/gnuradio-runtime/python/gnuradio/__init__.py
+++ b/gnuradio-runtime/python/gnuradio/__init__.py
@@ -55,6 +55,7 @@ if path.endswith(path_ending):
__path__.append(os.path.join(build_path, 'gr-channels', 'python'))
__path__.append(os.path.join(build_path, 'gr-fec', 'python'))
__path__.append(os.path.join(build_path, 'gr-utils'))
+ __path__.append(os.path.join(build_path, 'gr-iio', 'python'))
__path__.append(os.path.join(build_path, 'gr-uhd', 'python'))
__path__.append(os.path.join(build_path, 'gr-pdu', 'python'))
__path__.append(os.path.join(build_path, 'gr-network', 'python'))
diff --git a/gr-iio/CMakeLists.txt b/gr-iio/CMakeLists.txt
new file mode 100644
index 0000000000..a53159d60b
--- /dev/null
+++ b/gr-iio/CMakeLists.txt
@@ -0,0 +1,65 @@
+# Copyright 2021 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+########################################################################
+# Setup dependencies
+########################################################################
+include(GrBoost)
+
+find_package(AD9361 QUIET)
+find_package(IIO)
+
+set(GR_IIO_DEPENDENCIES
+ Boost_FOUND
+ ENABLE_GNURADIO_RUNTIME
+ ENABLE_GR_BLOCKS
+ LIBIIO_FOUND)
+
+if (LIBAD9361_FOUND)
+ list(APPEND GR_IIO_DEPENDENCIES LIBAD9361_FOUND)
+endif()
+
+########################################################################
+# Register component
+########################################################################
+include(GrComponent)
+GR_REGISTER_COMPONENT("gr-iio" ENABLE_GR_IIO ${GR_IIO_DEPENDENCIES})
+
+SET(GR_PKG_IIO_EXAMPLES_DIR ${GR_PKG_DATA_DIR}/examples/iio)
+
+########################################################################
+# Begin conditional configuration
+########################################################################
+if(ENABLE_GR_IIO)
+
+########################################################################
+# Add subdirectories
+########################################################################
+add_subdirectory(include/gnuradio/iio)
+add_subdirectory(lib)
+if(ENABLE_PYTHON)
+ add_subdirectory(python/iio)
+ add_subdirectory(examples)
+endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
+
+########################################################################
+# Create Pkg Config File
+########################################################################
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-iio.pc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-iio.pc
+@ONLY)
+
+install(
+ FILES ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-iio.pc
+ DESTINATION ${GR_LIBRARY_DIR}/pkgconfig
+)
+
+endif(ENABLE_GR_IIO)
diff --git a/gr-iio/examples/CMakeLists.txt b/gr-iio/examples/CMakeLists.txt
new file mode 100644
index 0000000000..997132035b
--- /dev/null
+++ b/gr-iio/examples/CMakeLists.txt
@@ -0,0 +1,18 @@
+# Copyright 2021 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+INSTALL(
+ FILES
+ attr-sink-source.grc
+ attr-source.grc
+ cyclic-sine.grc
+ cyclic-sine_pluto.grc
+ fmradio_pluto.grc
+ fm-transmitter_pluto.grc
+ DESTINATION ${GR_PKG_IIO_EXAMPLES_DIR}
+ COMPONENT "iio_python"
+)
diff --git a/gr-iio/examples/attr-sink-source.grc b/gr-iio/examples/attr-sink-source.grc
new file mode 100644
index 0000000000..43cdf6c33a
--- /dev/null
+++ b/gr-iio/examples/attr-sink-source.grc
@@ -0,0 +1,310 @@
+options:
+ parameters:
+ author: Travis Collins <travis.collins@analog.com>
+ category: '[GRC Hier Blocks]'
+ copyright: Analog Devices, Inc.
+ gen_cmake: 'On'
+ gen_linking: dynamic
+ generate_options: qt_gui
+ hier_block_src_path: '.:'
+ id: attribute_sink_source
+ max_nouts: '0'
+ output_language: python
+ placement: (0,0)
+ run: 'True'
+ run_command: '{python} -u {filename}'
+ run_options: prompt
+ sizing_mode: fixed
+ title: Attribute Sink Source Example
+ states:
+ coordinate: [8, 8]
+ rotation: 0
+ state: enabled
+
+blocks:
+- name: rf_bandwidth_range
+ id: variable_qtgui_range
+ parameters:
+ min_len: '200'
+ orient: Qt.Horizontal
+ rangeType: int
+ start: '200000'
+ step: '100000'
+ stop: '1000000'
+ value: '300000'
+ widget: counter_slider
+ states:
+ coordinate: [418, 12]
+ rotation: 0
+ state: true
+- name: samp_rate
+ id: variable
+ parameters:
+ value: '2084000'
+ states:
+ coordinate: [184, 12]
+ rotation: 0
+ state: enabled
+- name: uri
+ id: variable
+ parameters:
+ value: '''ip:192.168.2.1'''
+ states:
+ coordinate: [284, 12]
+ rotation: 0
+ state: enabled
+- name: blocks_message_debug_0
+ id: blocks_message_debug
+ parameters: {}
+ states:
+ coordinate: [976, 71]
+ rotation: 0
+ state: true
+- name: iio_attr_sink_0
+ id: iio_attr_sink
+ parameters:
+ attr_type: '0'
+ channel: voltage0
+ device: ad9361-phy
+ output: 'False'
+ required_enable: 'False'
+ uri: uri
+ states:
+ coordinate: [920, 202]
+ rotation: 0
+ state: enabled
+- name: iio_attr_source_0
+ id: iio_attr_source
+ parameters:
+ address: int("0x123",0)
+ attr_type: '0'
+ attribute: hardwaregain
+ channel: voltage0
+ device: ad9361-phy
+ output: 'False'
+ required_enable: 'False'
+ samples_per_update: '1024'
+ type: '1'
+ update_interval_ms: '1'
+ uri: uri
+ states:
+ coordinate: [620, 323]
+ rotation: 0
+ state: true
+- name: iio_attr_source_1
+ id: iio_attr_source
+ parameters:
+ address: int("0x123",0)
+ attr_type: '0'
+ attribute: rf_bandwidth
+ channel: voltage0
+ device: ad9361-phy
+ output: 'False'
+ required_enable: 'False'
+ samples_per_update: '1024'
+ type: '1'
+ update_interval_ms: '1'
+ uri: uri
+ states:
+ coordinate: [617, 477]
+ rotation: 0
+ state: true
+- name: iio_attr_updater_0
+ id: iio_attr_updater
+ parameters:
+ attr: rf_bandwidth
+ update_interval_ms: '1000'
+ value: str(rf_bandwidth_range)
+ states:
+ coordinate: [521, 167]
+ rotation: 0
+ state: true
+- name: qtgui_time_sink_x_0
+ id: qtgui_time_sink_x
+ parameters:
+ alpha1: '1.0'
+ alpha10: '1.0'
+ alpha2: '1.0'
+ alpha3: '1.0'
+ alpha4: '1.0'
+ alpha5: '1.0'
+ alpha6: '1.0'
+ alpha7: '1.0'
+ alpha8: '1.0'
+ alpha9: '1.0'
+ autoscale: 'True'
+ axislabels: 'True'
+ color1: blue
+ color10: blue
+ color2: green
+ color3: black
+ color4: cyan
+ color5: magenta
+ color6: yellow
+ color7: dark red
+ color8: dark green
+ color9: Dark Blue
+ ctrlpanel: 'False'
+ entags: 'True'
+ grid: 'True'
+ label1: Signal 1
+ label10: Signal 10
+ label2: Signal 2
+ label3: Signal 3
+ label4: Signal 4
+ label5: Signal 5
+ label6: Signal 6
+ label7: Signal 7
+ label8: Signal 8
+ label9: Signal 9
+ legend: 'True'
+ marker1: '1'
+ marker10: '1'
+ marker2: '1'
+ marker3: '1'
+ marker4: '1'
+ marker5: '1'
+ marker6: '1'
+ marker7: '1'
+ marker8: '1'
+ marker9: '1'
+ name: '""'
+ nconnections: '1'
+ size: '1024'
+ srate: samp_rate
+ stemplot: 'False'
+ style1: '1'
+ style10: '1'
+ style2: '1'
+ style3: '1'
+ style4: '1'
+ style5: '1'
+ style6: '1'
+ style7: '1'
+ style8: '1'
+ style9: '1'
+ tr_chan: '0'
+ tr_delay: '0'
+ tr_level: '0.0'
+ tr_mode: qtgui.TRIG_MODE_FREE
+ tr_slope: qtgui.TRIG_SLOPE_POS
+ tr_tag: '""'
+ type: float
+ update_time: '0.10'
+ width1: '1'
+ width10: '1'
+ width2: '1'
+ width3: '1'
+ width4: '1'
+ width5: '1'
+ width6: '1'
+ width7: '1'
+ width8: '1'
+ width9: '1'
+ ylabel: Amplitude
+ ymax: '1'
+ ymin: '-1'
+ yunit: '""'
+ states:
+ coordinate: [926, 356]
+ rotation: 0
+ state: true
+- name: qtgui_time_sink_x_1
+ id: qtgui_time_sink_x
+ parameters:
+ alpha1: '1.0'
+ alpha10: '1.0'
+ alpha2: '1.0'
+ alpha3: '1.0'
+ alpha4: '1.0'
+ alpha5: '1.0'
+ alpha6: '1.0'
+ alpha7: '1.0'
+ alpha8: '1.0'
+ alpha9: '1.0'
+ autoscale: 'True'
+ axislabels: 'True'
+ color1: blue
+ color10: blue
+ color2: green
+ color3: black
+ color4: cyan
+ color5: magenta
+ color6: yellow
+ color7: dark red
+ color8: dark green
+ color9: Dark Blue
+ ctrlpanel: 'False'
+ entags: 'True'
+ grid: 'True'
+ label1: Signal 1
+ label10: Signal 10
+ label2: Signal 2
+ label3: Signal 3
+ label4: Signal 4
+ label5: Signal 5
+ label6: Signal 6
+ label7: Signal 7
+ label8: Signal 8
+ label9: Signal 9
+ legend: 'True'
+ marker1: '1'
+ marker10: '1'
+ marker2: '1'
+ marker3: '1'
+ marker4: '1'
+ marker5: '1'
+ marker6: '1'
+ marker7: '1'
+ marker8: '1'
+ marker9: '1'
+ name: '""'
+ nconnections: '1'
+ size: '1024'
+ srate: samp_rate
+ stemplot: 'False'
+ style1: '1'
+ style10: '1'
+ style2: '1'
+ style3: '1'
+ style4: '1'
+ style5: '1'
+ style6: '1'
+ style7: '1'
+ style8: '1'
+ style9: '1'
+ tr_chan: '0'
+ tr_delay: '0'
+ tr_level: '0.0'
+ tr_mode: qtgui.TRIG_MODE_FREE
+ tr_slope: qtgui.TRIG_SLOPE_POS
+ tr_tag: '""'
+ type: float
+ update_time: '0.10'
+ width1: '1'
+ width10: '1'
+ width2: '1'
+ width3: '1'
+ width4: '1'
+ width5: '1'
+ width6: '1'
+ width7: '1'
+ width8: '1'
+ width9: '1'
+ ylabel: Amplitude
+ ymax: '1'
+ ymin: '-1'
+ yunit: '""'
+ states:
+ coordinate: [923, 510]
+ rotation: 0
+ state: true
+
+connections:
+- [iio_attr_source_0, '0', qtgui_time_sink_x_0, '0']
+- [iio_attr_source_1, '0', qtgui_time_sink_x_1, '0']
+- [iio_attr_updater_0, out, blocks_message_debug_0, print]
+- [iio_attr_updater_0, out, iio_attr_sink_0, attr]
+
+metadata:
+ file_format: 1
diff --git a/gr-iio/examples/attr-source.grc b/gr-iio/examples/attr-source.grc
new file mode 100644
index 0000000000..b20cc10588
--- /dev/null
+++ b/gr-iio/examples/attr-source.grc
@@ -0,0 +1,1892 @@
+<?xml version='1.0' encoding='utf-8'?>
+<?grc format='1' created='3.7.11'?>
+<flow_graph>
+ <timestamp>Thu Aug 2 18:56:14 2018</timestamp>
+ <block>
+ <key>options</key>
+ <param>
+ <key>author</key>
+ <value>Travis Collins</value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value></value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>[GRC Hier Blocks]</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(8, 8)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>qt_gui</value>
+ </param>
+ <param>
+ <key>hier_block_src_path</key>
+ <value>.:</value>
+ </param>
+ <param>
+ <key>id</key>
+ <value>attr_source_example</value>
+ </param>
+ <param>
+ <key>max_nouts</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>qt_qss_theme</key>
+ <value></value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>run_command</key>
+ <value>{python} -u {filename}</value>
+ </param>
+ <param>
+ <key>run_options</key>
+ <value>prompt</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>thread_safe_setters</key>
+ <value></value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>Attribute Source Example</value>
+ </param>
+ </block>
+ <block>
+ <key>iio_attr_source</key>
+ <param>
+ <key>attribute</key>
+ <value>"adi,gc-lmt-overload-high-thresh"</value>
+ </param>
+ <param>
+ <key>attr_type</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>channel</key>
+ <value>"voltage0"</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>device</key>
+ <value>"ad9361-phy"</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(280, 56)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>id</key>
+ <value>iio_attr_source_0</value>
+ </param>
+ <param>
+ <key>output</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>address</key>
+ <value>int("0x123",0)</value>
+ </param>
+ <param>
+ <key>required_enable</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>samples_per_update</key>
+ <value>32</value>
+ </param>
+ <param>
+ <key>update_interval_ms</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>uri</key>
+ <value>"ip:192.168.2.1"</value>
+ </param>
+ </block>
+ <block>
+ <key>iio_attr_source</key>
+ <param>
+ <key>attribute</key>
+ <value>"rssi"</value>
+ </param>
+ <param>
+ <key>attr_type</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>channel</key>
+ <value>"voltage0"</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>device</key>
+ <value>"ad9361-phy"</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(280, 200)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>id</key>
+ <value>iio_attr_source_0_0</value>
+ </param>
+ <param>
+ <key>output</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>address</key>
+ <value>int("0x123",0)</value>
+ </param>
+ <param>
+ <key>required_enable</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>samples_per_update</key>
+ <value>32</value>
+ </param>
+ <param>
+ <key>update_interval_ms</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>uri</key>
+ <value>"ip:192.168.2.1"</value>
+ </param>
+ </block>
+ <block>
+ <key>iio_attr_source</key>
+ <param>
+ <key>attribute</key>
+ <value>"hardwaregain"</value>
+ </param>
+ <param>
+ <key>attr_type</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>channel</key>
+ <value>"voltage0"</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>device</key>
+ <value>"ad9361-phy"</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(280, 348)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>id</key>
+ <value>iio_attr_source_0_0_0</value>
+ </param>
+ <param>
+ <key>output</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>address</key>
+ <value>int("0x123",0)</value>
+ </param>
+ <param>
+ <key>required_enable</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>samples_per_update</key>
+ <value>32</value>
+ </param>
+ <param>
+ <key>update_interval_ms</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>uri</key>
+ <value>"ip:192.168.2.1"</value>
+ </param>
+ </block>
+ <block>
+ <key>iio_attr_source</key>
+ <param>
+ <key>attribute</key>
+ <value>"xo_correction"</value>
+ </param>
+ <param>
+ <key>attr_type</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>channel</key>
+ <value>"voltage0"</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>device</key>
+ <value>"ad9361-phy"</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(280, 492)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>id</key>
+ <value>iio_attr_source_0_0_0_0</value>
+ </param>
+ <param>
+ <key>output</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>address</key>
+ <value>int("0x123",0)</value>
+ </param>
+ <param>
+ <key>required_enable</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>samples_per_update</key>
+ <value>32</value>
+ </param>
+ <param>
+ <key>update_interval_ms</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>uri</key>
+ <value>"ip:192.168.2.1"</value>
+ </param>
+ </block>
+ <block>
+ <key>qtgui_time_sink_x</key>
+ <param>
+ <key>autoscale</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>axislabels</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>ctrlpanel</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>entags</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(544, 80)</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>grid</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>id</key>
+ <value>qtgui_time_sink_x_0</value>
+ </param>
+ <param>
+ <key>legend</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alpha1</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color1</key>
+ <value>"blue"</value>
+ </param>
+ <param>
+ <key>label1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker1</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style1</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width1</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha10</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color10</key>
+ <value>"blue"</value>
+ </param>
+ <param>
+ <key>label10</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker10</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style10</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width10</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha2</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color2</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>label2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker2</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style2</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width2</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha3</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color3</key>
+ <value>"green"</value>
+ </param>
+ <param>
+ <key>label3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker3</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style3</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width3</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha4</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color4</key>
+ <value>"black"</value>
+ </param>
+ <param>
+ <key>label4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker4</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style4</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width4</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha5</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color5</key>
+ <value>"cyan"</value>
+ </param>
+ <param>
+ <key>label5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker5</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style5</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width5</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha6</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color6</key>
+ <value>"magenta"</value>
+ </param>
+ <param>
+ <key>label6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker6</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style6</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width6</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha7</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color7</key>
+ <value>"yellow"</value>
+ </param>
+ <param>
+ <key>label7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker7</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style7</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width7</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha8</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color8</key>
+ <value>"dark red"</value>
+ </param>
+ <param>
+ <key>label8</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker8</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style8</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width8</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha9</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color9</key>
+ <value>"dark green"</value>
+ </param>
+ <param>
+ <key>label9</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker9</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style9</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width9</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>nconnections</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>size</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>srate</key>
+ <value>1000</value>
+ </param>
+ <param>
+ <key>tr_chan</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tr_delay</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tr_level</key>
+ <value>0.0</value>
+ </param>
+ <param>
+ <key>tr_mode</key>
+ <value>qtgui.TRIG_MODE_FREE</value>
+ </param>
+ <param>
+ <key>tr_slope</key>
+ <value>qtgui.TRIG_SLOPE_POS</value>
+ </param>
+ <param>
+ <key>tr_tag</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>update_time</key>
+ <value>0.10</value>
+ </param>
+ <param>
+ <key>ylabel</key>
+ <value>Amplitude</value>
+ </param>
+ <param>
+ <key>yunit</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>ymax</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>ymin</key>
+ <value>-1</value>
+ </param>
+ </block>
+ <block>
+ <key>qtgui_time_sink_x</key>
+ <param>
+ <key>autoscale</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>axislabels</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>ctrlpanel</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>entags</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(552, 232)</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>grid</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>id</key>
+ <value>qtgui_time_sink_x_0_0</value>
+ </param>
+ <param>
+ <key>legend</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alpha1</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color1</key>
+ <value>"blue"</value>
+ </param>
+ <param>
+ <key>label1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker1</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style1</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width1</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha10</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color10</key>
+ <value>"blue"</value>
+ </param>
+ <param>
+ <key>label10</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker10</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style10</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width10</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha2</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color2</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>label2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker2</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style2</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width2</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha3</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color3</key>
+ <value>"green"</value>
+ </param>
+ <param>
+ <key>label3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker3</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style3</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width3</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha4</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color4</key>
+ <value>"black"</value>
+ </param>
+ <param>
+ <key>label4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker4</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style4</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width4</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha5</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color5</key>
+ <value>"cyan"</value>
+ </param>
+ <param>
+ <key>label5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker5</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style5</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width5</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha6</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color6</key>
+ <value>"magenta"</value>
+ </param>
+ <param>
+ <key>label6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker6</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style6</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width6</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha7</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color7</key>
+ <value>"yellow"</value>
+ </param>
+ <param>
+ <key>label7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker7</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style7</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width7</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha8</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color8</key>
+ <value>"dark red"</value>
+ </param>
+ <param>
+ <key>label8</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker8</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style8</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width8</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha9</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color9</key>
+ <value>"dark green"</value>
+ </param>
+ <param>
+ <key>label9</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker9</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style9</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width9</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>nconnections</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>size</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>srate</key>
+ <value>1000</value>
+ </param>
+ <param>
+ <key>tr_chan</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tr_delay</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tr_level</key>
+ <value>0.0</value>
+ </param>
+ <param>
+ <key>tr_mode</key>
+ <value>qtgui.TRIG_MODE_FREE</value>
+ </param>
+ <param>
+ <key>tr_slope</key>
+ <value>qtgui.TRIG_SLOPE_POS</value>
+ </param>
+ <param>
+ <key>tr_tag</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>update_time</key>
+ <value>0.10</value>
+ </param>
+ <param>
+ <key>ylabel</key>
+ <value>Amplitude</value>
+ </param>
+ <param>
+ <key>yunit</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>ymax</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>ymin</key>
+ <value>-1</value>
+ </param>
+ </block>
+ <block>
+ <key>qtgui_time_sink_x</key>
+ <param>
+ <key>autoscale</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>axislabels</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>ctrlpanel</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>entags</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(544, 384)</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>grid</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>id</key>
+ <value>qtgui_time_sink_x_0_0_0</value>
+ </param>
+ <param>
+ <key>legend</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alpha1</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color1</key>
+ <value>"blue"</value>
+ </param>
+ <param>
+ <key>label1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker1</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style1</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width1</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha10</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color10</key>
+ <value>"blue"</value>
+ </param>
+ <param>
+ <key>label10</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker10</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style10</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width10</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha2</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color2</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>label2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker2</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style2</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width2</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha3</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color3</key>
+ <value>"green"</value>
+ </param>
+ <param>
+ <key>label3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker3</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style3</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width3</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha4</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color4</key>
+ <value>"black"</value>
+ </param>
+ <param>
+ <key>label4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker4</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style4</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width4</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha5</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color5</key>
+ <value>"cyan"</value>
+ </param>
+ <param>
+ <key>label5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker5</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style5</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width5</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha6</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color6</key>
+ <value>"magenta"</value>
+ </param>
+ <param>
+ <key>label6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker6</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style6</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width6</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha7</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color7</key>
+ <value>"yellow"</value>
+ </param>
+ <param>
+ <key>label7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker7</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style7</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width7</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha8</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color8</key>
+ <value>"dark red"</value>
+ </param>
+ <param>
+ <key>label8</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker8</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style8</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width8</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha9</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color9</key>
+ <value>"dark green"</value>
+ </param>
+ <param>
+ <key>label9</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker9</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style9</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width9</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>nconnections</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>size</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>srate</key>
+ <value>1000</value>
+ </param>
+ <param>
+ <key>tr_chan</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tr_delay</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tr_level</key>
+ <value>0.0</value>
+ </param>
+ <param>
+ <key>tr_mode</key>
+ <value>qtgui.TRIG_MODE_FREE</value>
+ </param>
+ <param>
+ <key>tr_slope</key>
+ <value>qtgui.TRIG_SLOPE_POS</value>
+ </param>
+ <param>
+ <key>tr_tag</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>update_time</key>
+ <value>0.10</value>
+ </param>
+ <param>
+ <key>ylabel</key>
+ <value>Amplitude</value>
+ </param>
+ <param>
+ <key>yunit</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>ymax</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>ymin</key>
+ <value>-1</value>
+ </param>
+ </block>
+ <block>
+ <key>qtgui_time_sink_x</key>
+ <param>
+ <key>autoscale</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>axislabels</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>ctrlpanel</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>entags</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(568, 512)</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>grid</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>id</key>
+ <value>qtgui_time_sink_x_0_0_0_0</value>
+ </param>
+ <param>
+ <key>legend</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alpha1</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color1</key>
+ <value>"blue"</value>
+ </param>
+ <param>
+ <key>label1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker1</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style1</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width1</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha10</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color10</key>
+ <value>"blue"</value>
+ </param>
+ <param>
+ <key>label10</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker10</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style10</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width10</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha2</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color2</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>label2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker2</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style2</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width2</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha3</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color3</key>
+ <value>"green"</value>
+ </param>
+ <param>
+ <key>label3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker3</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style3</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width3</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha4</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color4</key>
+ <value>"black"</value>
+ </param>
+ <param>
+ <key>label4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker4</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style4</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width4</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha5</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color5</key>
+ <value>"cyan"</value>
+ </param>
+ <param>
+ <key>label5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker5</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style5</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width5</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha6</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color6</key>
+ <value>"magenta"</value>
+ </param>
+ <param>
+ <key>label6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker6</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style6</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width6</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha7</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color7</key>
+ <value>"yellow"</value>
+ </param>
+ <param>
+ <key>label7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker7</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style7</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width7</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha8</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color8</key>
+ <value>"dark red"</value>
+ </param>
+ <param>
+ <key>label8</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker8</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style8</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width8</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alpha9</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>color9</key>
+ <value>"dark green"</value>
+ </param>
+ <param>
+ <key>label9</key>
+ <value></value>
+ </param>
+ <param>
+ <key>marker9</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>style9</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>width9</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>nconnections</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>size</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>srate</key>
+ <value>1000</value>
+ </param>
+ <param>
+ <key>tr_chan</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tr_delay</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tr_level</key>
+ <value>0.0</value>
+ </param>
+ <param>
+ <key>tr_mode</key>
+ <value>qtgui.TRIG_MODE_FREE</value>
+ </param>
+ <param>
+ <key>tr_slope</key>
+ <value>qtgui.TRIG_SLOPE_POS</value>
+ </param>
+ <param>
+ <key>tr_tag</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>update_time</key>
+ <value>0.10</value>
+ </param>
+ <param>
+ <key>ylabel</key>
+ <value>Amplitude</value>
+ </param>
+ <param>
+ <key>yunit</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>ymax</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>ymin</key>
+ <value>-1</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>iio_attr_source_0</source_block_id>
+ <sink_block_id>qtgui_time_sink_x_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>iio_attr_source_0_0</source_block_id>
+ <sink_block_id>qtgui_time_sink_x_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>iio_attr_source_0_0_0</source_block_id>
+ <sink_block_id>qtgui_time_sink_x_0_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>iio_attr_source_0_0_0_0</source_block_id>
+ <sink_block_id>qtgui_time_sink_x_0_0_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gr-iio/examples/cyclic-sine.grc b/gr-iio/examples/cyclic-sine.grc
new file mode 100644
index 0000000000..a38970fd8c
--- /dev/null
+++ b/gr-iio/examples/cyclic-sine.grc
@@ -0,0 +1,195 @@
+options:
+ parameters:
+ author: ''
+ category: Custom
+ cmake_opt: ''
+ comment: ''
+ copyright: ''
+ description: ''
+ gen_cmake: 'On'
+ gen_linking: dynamic
+ generate_options: qt_gui
+ hier_block_src_path: '.:'
+ id: top_block
+ max_nouts: '0'
+ output_language: python
+ placement: (0,0)
+ qt_qss_theme: ''
+ realtime_scheduling: ''
+ run: 'True'
+ run_command: '{python} -u {filename}'
+ run_options: prompt
+ sizing_mode: fixed
+ thread_safe_setters: ''
+ title: ''
+ window_size: 1280, 1024
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [10, 10]
+ rotation: 0
+ state: enabled
+
+blocks:
+- name: period_samples
+ id: variable
+ parameters:
+ comment: ''
+ value: '0x8000'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [16, 113]
+ rotation: 0
+ state: enabled
+- name: samp_rate
+ id: variable
+ parameters:
+ comment: ''
+ value: '2200000'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [14, 176]
+ rotation: 0
+ state: enabled
+- name: analog_sig_source_x_0
+ id: analog_sig_source_x
+ parameters:
+ affinity: ''
+ alias: ''
+ amp: '1'
+ comment: ''
+ freq: period_samples
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ offset: '0'
+ phase: '0'
+ samp_rate: samp_rate
+ type: complex
+ waveform: analog.GR_SIN_WAVE
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [680, 104]
+ rotation: 0
+ state: enabled
+- name: iio_fmcomms2_sink_0
+ id: iio_fmcomms2_sink
+ parameters:
+ affinity: ''
+ alias: ''
+ attenuation1: '10.0'
+ attenuation2: '10.0'
+ bandwidth: '200000'
+ buffer_size: period_samples
+ comment: ''
+ cyclic: 'True'
+ filter: ''
+ filter_source: '''Auto'''
+ fpass: samp_rate/4
+ frequency: '2400000000'
+ fstop: samp_rate/3
+ rf_port_select: '''A'''
+ samplerate: samp_rate
+ tx1_en: 'True'
+ tx2_en: 'False'
+ uri: uri
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [928, 56]
+ rotation: 0
+ state: enabled
+- name: iio_fmcomms2_source_0
+ id: iio_fmcomms2_source
+ parameters:
+ affinity: ''
+ alias: ''
+ bandwidth: '200000'
+ bbdc: 'True'
+ buffer_size: '0x8000'
+ comment: ''
+ filter: ''
+ filter_source: '''Auto'''
+ fpass: samp_rate/4
+ frequency: '2400000000'
+ fstop: samp_rate/3
+ gain1: '''slow_attack'''
+ gain2: '''slow_attack'''
+ manual_gain1: '64.0'
+ manual_gain2: '64.0'
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ quadrature: 'True'
+ rf_port_select: '''A_BALANCED'''
+ rfdc: 'True'
+ rx1_en: 'True'
+ rx2_en: 'False'
+ samplerate: samp_rate
+ uri: uri
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [252, 224]
+ rotation: 0
+ state: enabled
+- name: qtgui_sink_x_0
+ id: qtgui_sink_x
+ parameters:
+ affinity: ''
+ alias: ''
+ bw: samp_rate
+ comment: ''
+ fc: '2400000000'
+ fftsize: '1024'
+ gui_hint: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ name: '""'
+ plotconst: 'True'
+ plotfreq: 'True'
+ plottime: 'True'
+ plotwaterfall: 'True'
+ rate: '10'
+ showports: 'True'
+ showrf: 'False'
+ type: complex
+ wintype: firdes.WIN_BLACKMAN_hARRIS
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [560, 312]
+ rotation: 0
+ state: enabled
+- name: uri
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: URI
+ short_id: ''
+ type: ''
+ value: '''ip:analog.local'''
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [14, 247]
+ rotation: 0
+ state: enabled
+
+connections:
+- [analog_sig_source_x_0, '0', iio_fmcomms2_sink_0, '0']
+- [iio_fmcomms2_source_0, '0', qtgui_sink_x_0, '0']
+
+metadata:
+ file_format: 1
diff --git a/gr-iio/examples/cyclic-sine_pluto.grc b/gr-iio/examples/cyclic-sine_pluto.grc
new file mode 100644
index 0000000000..c357dd87ae
--- /dev/null
+++ b/gr-iio/examples/cyclic-sine_pluto.grc
@@ -0,0 +1,173 @@
+options:
+ parameters:
+ author: Travis Collins <travis.collins@analog.com>
+ category: '[GRC Hier Blocks]'
+ copyright: Analog Devices, Inc.
+ gen_cmake: 'On'
+ gen_linking: dynamic
+ generate_options: qt_gui
+ hier_block_src_path: '.:'
+ id: cyclic_sine_pluto
+ max_nouts: '0'
+ output_language: python
+ placement: (0,0)
+ run: 'True'
+ run_command: '{python} -u {filename}'
+ run_options: prompt
+ sizing_mode: fixed
+ title: 'Pluto Example: Cyclic-Sine'
+ states:
+ coordinate: [8, 8]
+ rotation: 0
+ state: enabled
+
+blocks:
+- name: samp_rate
+ id: variable
+ parameters:
+ value: '2084000'
+ states:
+ coordinate: [184, 12]
+ rotation: 0
+ state: enabled
+- name: analog_sig_source_x_0
+ id: analog_sig_source_x
+ parameters:
+ amp: '1'
+ freq: samp_rate/100
+ offset: '0'
+ samp_rate: samp_rate
+ type: complex
+ waveform: analog.GR_COS_WAVE
+ states:
+ coordinate: [171, 400]
+ rotation: 0
+ state: true
+- name: iio_pluto_sink_0
+ id: iio_pluto_sink
+ parameters:
+ attenuation1: '30.0'
+ auto_filter: 'True'
+ bandwidth: '20000000'
+ buffer_size: '32768'
+ cyclic: 'False'
+ frequency: '2400000000'
+ samplerate: samp_rate
+ states:
+ coordinate: [421, 337]
+ rotation: 0
+ state: true
+- name: iio_pluto_source_0
+ id: iio_pluto_source
+ parameters:
+ auto_filter: 'True'
+ bandwidth: '20000000'
+ bbdc: 'True'
+ buffer_size: '32768'
+ frequency: '2400000000'
+ gain1: '''slow_attack'''
+ manual_gain1: '64'
+ quadrature: 'True'
+ rfdc: 'True'
+ samplerate: samp_rate
+ states:
+ coordinate: [143, 125]
+ rotation: 0
+ state: true
+- name: qtgui_time_sink_x_0
+ id: qtgui_time_sink_x
+ parameters:
+ alpha1: '1.0'
+ alpha10: '1.0'
+ alpha2: '1.0'
+ alpha3: '1.0'
+ alpha4: '1.0'
+ alpha5: '1.0'
+ alpha6: '1.0'
+ alpha7: '1.0'
+ alpha8: '1.0'
+ alpha9: '1.0'
+ autoscale: 'False'
+ axislabels: 'True'
+ color1: blue
+ color10: blue
+ color2: green
+ color3: black
+ color4: cyan
+ color5: magenta
+ color6: yellow
+ color7: dark red
+ color8: dark green
+ color9: Dark Blue
+ ctrlpanel: 'False'
+ entags: 'True'
+ grid: 'False'
+ label1: Signal 1
+ label10: Signal 10
+ label2: Signal 2
+ label3: Signal 3
+ label4: Signal 4
+ label5: Signal 5
+ label6: Signal 6
+ label7: Signal 7
+ label8: Signal 8
+ label9: Signal 9
+ legend: 'True'
+ marker1: '1'
+ marker10: '1'
+ marker2: '1'
+ marker3: '1'
+ marker4: '1'
+ marker5: '1'
+ marker6: '1'
+ marker7: '1'
+ marker8: '1'
+ marker9: '1'
+ name: '""'
+ nconnections: '1'
+ size: '1024'
+ srate: samp_rate
+ stemplot: 'False'
+ style1: '1'
+ style10: '1'
+ style2: '1'
+ style3: '1'
+ style4: '1'
+ style5: '1'
+ style6: '1'
+ style7: '1'
+ style8: '1'
+ style9: '1'
+ tr_chan: '0'
+ tr_delay: '0'
+ tr_level: '0.0'
+ tr_mode: qtgui.TRIG_MODE_FREE
+ tr_slope: qtgui.TRIG_SLOPE_POS
+ tr_tag: '""'
+ type: complex
+ update_time: '0.10'
+ width1: '1'
+ width10: '1'
+ width2: '1'
+ width3: '1'
+ width4: '1'
+ width5: '1'
+ width6: '1'
+ width7: '1'
+ width8: '1'
+ width9: '1'
+ ylabel: Amplitude
+ ymax: '1'
+ ymin: '-1'
+ yunit: '""'
+ states:
+ coordinate: [427, 214]
+ rotation: 0
+ state: true
+
+connections:
+- [analog_sig_source_x_0, '0', iio_pluto_sink_0, '0']
+- [iio_pluto_source_0, '0', qtgui_time_sink_x_0, '0']
+
+metadata:
+ file_format: 1
diff --git a/gr-iio/examples/fm-transmitter_pluto.grc b/gr-iio/examples/fm-transmitter_pluto.grc
new file mode 100644
index 0000000000..fafc8480c0
--- /dev/null
+++ b/gr-iio/examples/fm-transmitter_pluto.grc
@@ -0,0 +1,202 @@
+options:
+ parameters:
+ author: ''
+ category: Custom
+ cmake_opt: ''
+ comment: ''
+ copyright: ''
+ description: ''
+ gen_cmake: 'On'
+ gen_linking: dynamic
+ generate_options: no_gui
+ hier_block_src_path: '.:'
+ id: top_block
+ max_nouts: '0'
+ output_language: python
+ placement: (0,0)
+ qt_qss_theme: ''
+ realtime_scheduling: '1'
+ run: 'True'
+ run_command: '{python} -u {filename}'
+ run_options: prompt
+ sizing_mode: fixed
+ thread_safe_setters: ''
+ title: ''
+ window_size: 1280, 1024
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [12, 8]
+ rotation: 0
+ state: enabled
+
+blocks:
+- name: fm_station
+ id: variable
+ parameters:
+ comment: ''
+ value: '98100000'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [18, 179]
+ rotation: 0
+ state: enabled
+- name: samp_rate
+ id: variable
+ parameters:
+ comment: ''
+ value: '2304000'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [17, 114]
+ rotation: 0
+ state: enabled
+- name: analog_nbfm_tx_0
+ id: analog_nbfm_tx
+ parameters:
+ affinity: ''
+ alias: ''
+ audio_rate: '48000'
+ comment: ''
+ fh: '-1.0'
+ max_dev: 75e3
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ quad_rate: int(samp_rate / 8)
+ tau: 75e-6
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [623, 105]
+ rotation: 0
+ state: enabled
+- name: blocks_add_xx_0
+ id: blocks_add_xx
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ num_inputs: '2'
+ type: float
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [502, 115]
+ rotation: 0
+ state: enabled
+- name: blocks_wavfile_source_0
+ id: blocks_wavfile_source
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ file: wav_file
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ nchan: '2'
+ repeat: 'True'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [256, 115]
+ rotation: 0
+ state: enabled
+- name: iio_pluto_sink_0
+ id: iio_pluto_sink
+ parameters:
+ affinity: ''
+ alias: ''
+ attenuation1: '10.0'
+ bandwidth: '20000000'
+ buffer_size: '32768'
+ comment: ''
+ cyclic: 'False'
+ filter: ''
+ filter_source: '''Auto'''
+ fpass: samp_rate/4
+ frequency: fm_station
+ fstop: samp_rate/3
+ samplerate: samp_rate
+ uri: ''
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [696, 372.0]
+ rotation: 0
+ state: true
+- name: interpolation
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Interpolation
+ short_id: ''
+ type: intx
+ value: '2'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [16, 344]
+ rotation: 0
+ state: enabled
+- name: rational_resampler_xxx_0
+ id: rational_resampler_xxx
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ decim: '1'
+ fbw: '0'
+ interp: int(8 / interpolation)
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ taps: ''
+ type: ccc
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [704, 252.0]
+ rotation: 180
+ state: enabled
+- name: wav_file
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: WAV File
+ short_id: ''
+ type: ''
+ value: /home/paul/Epoq.wav
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [19, 248]
+ rotation: 0
+ state: enabled
+
+connections:
+- [analog_nbfm_tx_0, '0', rational_resampler_xxx_0, '0']
+- [blocks_add_xx_0, '0', analog_nbfm_tx_0, '0']
+- [blocks_wavfile_source_0, '0', blocks_add_xx_0, '0']
+- [blocks_wavfile_source_0, '1', blocks_add_xx_0, '1']
+- [rational_resampler_xxx_0, '0', iio_pluto_sink_0, '0']
+
+metadata:
+ file_format: 1
diff --git a/gr-iio/examples/fmradio_pluto.grc b/gr-iio/examples/fmradio_pluto.grc
new file mode 100644
index 0000000000..26d5436237
--- /dev/null
+++ b/gr-iio/examples/fmradio_pluto.grc
@@ -0,0 +1,265 @@
+options:
+ parameters:
+ author: Travis Collins <travis.collins@analog.com>
+ category: '[GRC Hier Blocks]'
+ copyright: Analog Devices, Inc.
+ gen_cmake: 'On'
+ gen_linking: dynamic
+ generate_options: qt_gui
+ hier_block_src_path: '.:'
+ id: cyclic_sine_pluto
+ max_nouts: '0'
+ output_language: python
+ placement: (0,0)
+ run: 'True'
+ run_command: '{python} -u {filename}'
+ run_options: prompt
+ sizing_mode: fixed
+ title: 'Pluto Example: Cyclic-Sine'
+ states:
+ coordinate: [8, 8]
+ rotation: 0
+ state: enabled
+
+blocks:
+- name: RF
+ id: variable_qtgui_range
+ parameters:
+ min_len: '200'
+ orient: Qt.Horizontal
+ rangeType: int
+ start: '1'
+ step: '1'
+ stop: '4'
+ value: '1'
+ widget: counter_slider
+ states:
+ coordinate: [802, 33]
+ rotation: 0
+ state: true
+- name: Station
+ id: variable
+ parameters:
+ value: '105900000'
+ states:
+ coordinate: [288, 10]
+ rotation: 0
+ state: enabled
+- name: audiodecimation
+ id: variable
+ parameters:
+ value: '4'
+ states:
+ coordinate: [478, 13]
+ rotation: 0
+ state: enabled
+- name: audiorate
+ id: variable
+ parameters:
+ value: '48000'
+ states:
+ coordinate: [391, 11]
+ rotation: 0
+ state: enabled
+- name: channeldecimation
+ id: variable
+ parameters:
+ value: '10'
+ states:
+ coordinate: [565, 16]
+ rotation: 0
+ state: enabled
+- name: samp_rate
+ id: variable
+ parameters:
+ value: audiorate*audiodecimation*channeldecimation
+ states:
+ coordinate: [184, 12]
+ rotation: 0
+ state: enabled
+- name: uri
+ id: variable
+ parameters:
+ value: '''ip:192.168.2.1'''
+ states:
+ coordinate: [640, 16]
+ rotation: 0
+ state: enabled
+- name: analog_wfm_rcv_0
+ id: analog_wfm_rcv
+ parameters:
+ audio_decimation: audiodecimation
+ quad_rate: audiorate*audiodecimation
+ states:
+ coordinate: [776, 211]
+ rotation: 0
+ state: enabled
+- name: analog_wfm_tx_0
+ id: analog_wfm_tx
+ parameters:
+ audio_rate: audiorate
+ fh: '-1.0'
+ max_dev: 5e3
+ quad_rate: audiorate*audiodecimation
+ tau: 75e-6
+ states:
+ coordinate: [479, 502]
+ rotation: 0
+ state: true
+- name: audio_sink_0
+ id: audio_sink
+ parameters:
+ num_inputs: '1'
+ ok_to_block: 'True'
+ samp_rate: '48000'
+ states:
+ coordinate: [1049, 169]
+ rotation: 0
+ state: enabled
+- name: blocks_wavfile_source_0
+ id: blocks_wavfile_source
+ parameters:
+ file: /home/tcollins/Downloads/audiocheck.net_hdsweep_1Hz_48000Hz_-3dBFS_30s.wav
+ nchan: '1'
+ repeat: 'True'
+ states:
+ coordinate: [194, 462]
+ rotation: 0
+ state: true
+- name: iio_pluto_sink_0
+ id: iio_pluto_sink
+ parameters:
+ attenuation1: '30.0'
+ auto_filter: 'True'
+ bandwidth: audiorate*audiodecimation*channeldecimation
+ buffer_size: '32768'
+ cyclic: 'False'
+ frequency: '2400000000'
+ samplerate: audiorate*audiodecimation*channeldecimation
+ uri: uri
+ states:
+ coordinate: [996, 360]
+ rotation: 0
+ state: true
+- name: iio_pluto_source_0
+ id: iio_pluto_source
+ parameters:
+ auto_filter: 'True'
+ bandwidth: audiorate*audiodecimation*channeldecimation
+ bbdc: 'True'
+ buffer_size: '32768'
+ frequency: '2400000000'
+ gain1: '''slow_attack'''
+ manual_gain1: '50'
+ quadrature: 'True'
+ rfdc: 'True'
+ samplerate: audiorate*audiodecimation*channeldecimation
+ uri: uri
+ states:
+ coordinate: [148, 159]
+ rotation: 0
+ state: enabled
+- name: qtgui_freq_sink_x_0
+ id: qtgui_freq_sink_x
+ parameters:
+ alpha1: '1.0'
+ alpha10: '1.0'
+ alpha2: '1.0'
+ alpha3: '1.0'
+ alpha4: '1.0'
+ alpha5: '1.0'
+ alpha6: '1.0'
+ alpha7: '1.0'
+ alpha8: '1.0'
+ alpha9: '1.0'
+ autoscale: 'False'
+ average: '1.0'
+ axislabels: 'True'
+ bw: samp_rate
+ color1: '"blue"'
+ color10: '"dark blue"'
+ color2: '"red"'
+ color3: '"green"'
+ color4: '"black"'
+ color5: '"cyan"'
+ color6: '"magenta"'
+ color7: '"yellow"'
+ color8: '"dark red"'
+ color9: '"dark green"'
+ ctrlpanel: 'False'
+ fc: '0'
+ fftsize: '1024'
+ freqhalf: 'True'
+ grid: 'False'
+ label: Relative Gain
+ label10: ''''''
+ label2: ''''''
+ label3: ''''''
+ label4: ''''''
+ label5: ''''''
+ label6: ''''''
+ label7: ''''''
+ label8: ''''''
+ label9: ''''''
+ legend: 'True'
+ name: '""'
+ nconnections: '1'
+ showports: 'True'
+ tr_chan: '0'
+ tr_level: '0.0'
+ tr_mode: qtgui.TRIG_MODE_FREE
+ tr_tag: '""'
+ type: complex
+ units: dB
+ update_time: '0.10'
+ width1: '1'
+ width10: '1'
+ width2: '1'
+ width3: '1'
+ width4: '1'
+ width5: '1'
+ width6: '1'
+ width7: '1'
+ width8: '1'
+ width9: '1'
+ wintype: firdes.WIN_BLACKMAN_hARRIS
+ ymax: '10'
+ ymin: '-140'
+ states:
+ coordinate: [538, 138]
+ rotation: 0
+ state: enabled
+- name: rational_resampler_xxx_0
+ id: rational_resampler_xxx
+ parameters:
+ decim: audiorate*audiodecimation*channeldecimation
+ fbw: '0.2'
+ interp: audiorate*audiodecimation
+ type: ccc
+ states:
+ coordinate: [551, 292]
+ rotation: 0
+ state: enabled
+- name: rational_resampler_xxx_1
+ id: rational_resampler_xxx
+ parameters:
+ decim: audiorate*audiodecimation
+ fbw: '0.2'
+ interp: audiorate*audiodecimation*channeldecimation
+ type: ccc
+ states:
+ coordinate: [787, 465]
+ rotation: 0
+ state: enabled
+
+connections:
+- [analog_wfm_rcv_0, '0', audio_sink_0, '0']
+- [analog_wfm_tx_0, '0', rational_resampler_xxx_1, '0']
+- [blocks_wavfile_source_0, '0', analog_wfm_tx_0, '0']
+- [iio_pluto_source_0, '0', qtgui_freq_sink_x_0, '0']
+- [iio_pluto_source_0, '0', rational_resampler_xxx_0, '0']
+- [rational_resampler_xxx_0, '0', analog_wfm_rcv_0, '0']
+- [rational_resampler_xxx_1, '0', iio_pluto_sink_0, '0']
+
+metadata:
+ file_format: 1
diff --git a/gr-iio/gnuradio-iio.pc.in b/gr-iio/gnuradio-iio.pc.in
new file mode 100644
index 0000000000..256f34d13d
--- /dev/null
+++ b/gr-iio/gnuradio-iio.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-iio
+Description: GNU Radio blocks for IIO devices
+Requires: gnuradio-runtime gnuradio-blocks
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-iio -lgnuradio-blocks
+Cflags: -I${includedir}
diff --git a/gr-iio/grc/CMakeLists.txt b/gr-iio/grc/CMakeLists.txt
new file mode 100644
index 0000000000..78942023ab
--- /dev/null
+++ b/gr-iio/grc/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Copyright 2021 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+file(GLOB yml_files "*.yml")
+install(FILES ${yml_files} DESTINATION ${GRC_BLOCKS_DIR})
diff --git a/gr-iio/grc/iio.tree.yml b/gr-iio/grc/iio.tree.yml
new file mode 100644
index 0000000000..92a6cf4d2c
--- /dev/null
+++ b/gr-iio/grc/iio.tree.yml
@@ -0,0 +1,17 @@
+'[Core]':
+- 'Industrial I/O':
+ - 'Generic':
+ - iio_device_source
+ - iio_device_sink
+ - iio_attr_source
+ - iio_attr_sink
+ - iio_attr_updater
+ - iio_dds_control
+ - 'FMComms':
+ - iio_fmcomms2_source
+ - iio_fmcomms2_sink
+ - iio_fmcomms5_source
+ - iio_fmcomms5_sink
+ - 'PlutoSDR':
+ - iio_pluto_source
+ - iio_pluto_sink
diff --git a/gr-iio/grc/iio_attr_sink.block.yml b/gr-iio/grc/iio_attr_sink.block.yml
new file mode 100644
index 0000000000..4acb5ba172
--- /dev/null
+++ b/gr-iio/grc/iio_attr_sink.block.yml
@@ -0,0 +1,52 @@
+id: iio_attr_sink
+label: IIO Attribute Sink
+flags: [ python ]
+
+parameters:
+- id: uri
+ label: IIO context URI
+ dtype: string
+ default: 'local:'
+
+- id: device
+ label: Device Name/ID
+ dtype: string
+
+- id: attr_type
+ label: Attribute Type
+ dtype: enum
+ default: "'Channel'"
+ options: ['0', '1', '2', '3', '4']
+ option_labels: ['Channel', 'Device', 'Device Buffer', 'Device Debug', 'Register']
+
+- id: required_enable
+ label: Required Enable
+ dtype: bool
+ default: False
+ hide: ${ ('part' if (attr_type == '4') else 'all') }
+
+- id: output
+ label: Input/Output
+ dtype: enum
+ default: "'Input'"
+ options: ['False', 'True']
+ option_labels: ['Input', 'Output']
+ hide: ${ ('part' if (attr_type == '0') else 'all') }
+
+- id: channel
+ label: Channel Name
+ dtype: string
+ default: ""
+ hide: ${ ('none' if attr_type == '0' else 'all') }
+
+inputs:
+- domain: message
+ id: attr
+
+templates:
+ imports: from gnuradio import iio
+ make: iio.attr_sink(${uri}, ${device}, ${channel}, ${attr_type}, ${output}, ${required_enable})
+
+documentation: https://wiki.analog.com/resources/tools-software/linux-software/gnuradio
+
+file_format: 1
diff --git a/gr-iio/grc/iio_attr_source.block.yml b/gr-iio/grc/iio_attr_source.block.yml
new file mode 100644
index 0000000000..ec04835014
--- /dev/null
+++ b/gr-iio/grc/iio_attr_source.block.yml
@@ -0,0 +1,85 @@
+id: iio_attr_source
+label: IIO Attribute Source
+flags: [ python ]
+
+parameters:
+- id: uri
+ label: IIO context URI
+ dtype: string
+ default: 'local:'
+
+- id: device
+ label: Device Name/ID
+ dtype: string
+
+- id: attr_type
+ label: Attribute Type
+ dtype: enum
+ default: "'Channel'"
+ options: ['0', '1', '2', '3']
+ option_labels: ['Channel', 'Device', 'Device Debug', 'Register']
+
+- id: output
+ label: Input/Output
+ dtype: enum
+ default: "'Input'"
+ options: ['False', 'True']
+ option_labels: ['Input', 'Output']
+ hide: ${ ('part' if (attr_type == '0') else 'all') }
+
+- id: channel
+ label: Channel Name
+ dtype: string
+ default: ""
+ hide: ${ ('none' if attr_type == '0' else 'all') }
+
+- id: attribute
+ label: Attribute Name
+ dtype: string
+ default: ""
+ hide: ${ ('none' if attr_type != '3' else 'all') }
+
+- id: address
+ label: Register Address
+ dtype: int
+ default: int("0x123",0)
+ hide: ${ ('none' if attr_type == '3' else 'all') }
+
+- id: required_enable
+ label: Required Enable
+ dtype: bool
+ default: False
+ options: ['False', 'True']
+ hide: ${ ('part' if (attr_type == '3') else 'all') }
+
+- id: type
+ label: Data Type
+ dtype: enum
+ default: "'Input'"
+ options: ['0', '1', '2', '3', '4']
+ option_labels: ['Double', 'Float (casted from double)', 'Long Long', 'Long (casted from long long)', 'Bool']
+ option_attributes:
+ fcn: [f64, f32, s64, s32, s8]
+ hide: ${ ('part' if (attr_type != '3') else 'all') }
+
+- id: update_interval_ms
+ label: Update Interval (ms)
+ dtype: int
+ default: 1
+
+- id: samples_per_update
+ label: Samples Per Update
+ dtype: int
+ default: 1024
+
+outputs:
+- domain: stream
+ dtype: ${ type.fcn }
+
+templates:
+ imports: from gnuradio import iio
+ make: iio.attr_source(${uri}, ${device}, ${channel}, ${attribute}, ${update_interval_ms}, ${samples_per_update}, ${type}, ${attr_type}, ${output}, ${address}, ${required_enable})
+
+documentation: https://wiki.analog.com/resources/tools-software/linux-software/gnuradio
+
+file_format: 1
diff --git a/gr-iio/grc/iio_attr_updater.block.yml b/gr-iio/grc/iio_attr_updater.block.yml
new file mode 100644
index 0000000000..751d3f25d0
--- /dev/null
+++ b/gr-iio/grc/iio_attr_updater.block.yml
@@ -0,0 +1,31 @@
+id: iio_attr_updater
+label: IIO Attribute Updater
+category: '[Industrial IO]'
+
+parameters:
+- id: attr
+ label: Attribute
+ dtype: string
+ default: ''
+
+- id: value
+ label: Value
+ dtype: string
+ default: ''
+
+- id: interval
+ label: Interval (ms)
+ dtype: int
+ default: 1000
+
+outputs:
+- domain: message
+ id: out
+
+templates:
+ imports: from gnuradio import iio
+ make: iio.attr_updater(${attr}, ${value}, ${interval})
+ callbacks:
+ - set_value(${value})
+
+file_format: 1
diff --git a/gr-iio/grc/iio_dds_control.block.yml b/gr-iio/grc/iio_dds_control.block.yml
new file mode 100644
index 0000000000..50cfa29ee7
--- /dev/null
+++ b/gr-iio/grc/iio_dds_control.block.yml
@@ -0,0 +1,212 @@
+id: iio_dds_control
+label: DDS Control
+
+parameters:
+- id: uri
+ label: IIO context URI
+ dtype: string
+ default: ip:analog
+
+- id: enabled_dds1
+ label: Enabled DDSs (TX1)
+ category: TX1
+ dtype: enum
+ default: 'False'
+ options: ['True', 'False']
+
+- id: freq_t1
+ label: Channel I Freq (Tone 1)
+ category: TX1
+ dtype: int
+ default: '100000'
+ hide: ${ ('none' if enabled_dds1 == 'True' else 'all') }
+
+- id: phase_t1
+ label: Channel I Phase (Tone 1)
+ category: TX1
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds1 == 'True' else 'all') }
+
+- id: scale_t1
+ label: Channel I Scale (Tone 1)
+ category: TX1
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds1 == 'True' else 'all') }
+
+- id: freq_t2
+ label: Channel I Freq (Tone 2)
+ category: TX1
+ dtype: int
+ default: '100000'
+ hide: ${ ('none' if enabled_dds1 == 'True' else 'all') }
+
+- id: phase_t2
+ label: Channel I Phase (Tone 2)
+ category: TX1
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds1 == 'True' else 'all') }
+
+- id: scale_t2
+ label: Channel I Scale (Tone 2)
+ category: TX1
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds1 == 'True' else 'all') }
+
+- id: freq_t1_q
+ label: Channel Q Freq (Tone 1)
+ category: TX1
+ dtype: int
+ default: '100000'
+ hide: ${ ('none' if enabled_dds1 == 'True' else 'all') }
+
+- id: phase_t1_q
+ label: Channel Q Phase (Tone 1)
+ category: TX1
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds1 == 'True' else 'all') }
+
+- id: scale_t1_q
+ label: Channel Q Scale (Tone 1)
+ category: TX1
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds1 == 'True' else 'all') }
+
+- id: freq_t2_q
+ label: Channel Q Freq (Tone 2)
+ category: TX1
+ dtype: int
+ default: '100000'
+ hide: ${ ('none' if enabled_dds1 == 'True' else 'all') }
+
+- id: phase_t2_q
+ label: Channel Q Phase (Tone 2)
+ category: TX1
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds1 == 'True' else 'all') }
+
+- id: scale_t2_q
+ label: Channel Q Scale (Tone 2)
+ category: TX1
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds1 == 'True' else 'all') }
+
+- id: enabled_dds2
+ label: Enabled DDSs (TX2)
+ category: TX2
+ dtype: enum
+ default: 'False'
+ options: ['True', 'False']
+- id: freq_t1_b
+ label: Channel I Freq (Tone 1)
+ category: TX2
+ dtype: int
+ default: '100000'
+ hide: ${ ('none' if enabled_dds2 == 'True' else 'all') }
+
+- id: phase_t1_b
+ label: Channel I Phase (Tone 1)
+ category: TX2
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds2 == 'True' else 'all') }
+
+- id: scale_t1_b
+ label: Channel I Scale (Tone 1)
+ category: TX2
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds2 == 'True' else 'all') }
+
+- id: freq_t2_b
+ label: Channel I Freq (Tone 2)
+ category: TX2
+ dtype: int
+ default: '100000'
+ hide: ${ ('none' if enabled_dds2 == 'True' else 'all') }
+
+- id: phase_t2_b
+ label: Channel I Phase (Tone 2)
+ category: TX2
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds2 == 'True' else 'all') }
+
+- id: scale_t2_b
+ label: Channel I Scale (Tone 2)
+ category: TX2
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds2 == 'True' else 'all') }
+
+- id: freq_t1_b_q
+ label: Channel Q Freq (Tone 1)
+ category: TX2
+ dtype: int
+ default: '100000'
+ hide: ${ ('none' if enabled_dds2 == 'True' else 'all') }
+
+- id: phase_t1_b_q
+ label: Channel Q Phase (Tone 1)
+ category: TX2
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds2 == 'True' else 'all') }
+
+- id: scale_t1_b_q
+ label: Channel Q Scale (Tone 1)
+ category: TX2
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds2 == 'True' else 'all') }
+
+- id: freq_t2_b_q
+ label: Channel Q Freq (Tone 2)
+ category: TX2
+ dtype: int
+ default: '100000'
+ hide: ${ ('none' if enabled_dds2 == 'True' else 'all') }
+
+- id: phase_t2_b_q
+ label: Channel Q Phase (Tone 2)
+ category: TX2
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds2 == 'True' else 'all') }
+
+- id: scale_t2_b_q
+ label: Channel Q Scale (Tone 2)
+ category: TX2
+ dtype: float
+ default: '0'
+ hide: ${ ('none' if enabled_dds2 == 'True' else 'all') }
+
+templates:
+ imports: from gnuradio import iio
+ make: |-
+ iio.dds_control(${uri}, [int(${enabled_dds1}),int(${enabled_dds2})],\
+ [${freq_t1}, ${freq_t2}, ${freq_t1_q}, ${freq_t2_q}, ${freq_t1_b}, ${freq_t2_b}, ${freq_t1_b_q}, ${freq_t2_b_q}], \
+ [${phase_t1},${phase_t1},${phase_t1_q},${phase_t1_q}, ${phase_t1_b},${phase_t2_b},${phase_t1_b_q},${phase_t2_b_q}], \
+ [${scale_t1},${scale_t2},${scale_t1_q},${scale_t2_q}, ${scale_t1_b},${scale_t2_b},${scale_t1_b_q},${scale_t2_b_q}])
+ callbacks:
+ - "set_dds_confg([${freq_t1}, ${freq_t2}, ${freq_t1_q}, ${freq_t2_q}, ${freq_t1_b},\
+ \ ${freq_t2_b}, ${freq_t1_b_q}, ${freq_t2_b_q}], \\\n [${phase_t1},${phase_t1},${phase_t1_q},${phase_t1_q},\
+ \ ${phase_t1_b},${phase_t2_b},${phase_t1_b_q},${phase_t2_b_q}], \\\n [${scale_t1},${scale_t2},${scale_t1_q},${scale_t2_q},\
+ \ ${scale_t1_b},${scale_t2_b},${scale_t1_b_q},${scale_t2_b_q}])"
+
+documentation: |-
+ Transmitter blocks cannot be run simultaneously with this block for the same device
+
+ DDS units and ranges:
+ - Frequency: [0 samp_rate/2] Hz
+ - Phase: [0 360] Degress
+ - Scale: [0 1] Fullscale=1
+
+file_format: 1
diff --git a/gr-iio/grc/iio_device_sink.block.yml b/gr-iio/grc/iio_device_sink.block.yml
new file mode 100644
index 0000000000..4a2d0de742
--- /dev/null
+++ b/gr-iio/grc/iio_device_sink.block.yml
@@ -0,0 +1,58 @@
+id: iio_device_sink
+label: IIO Device Sink
+flags: [ python ]
+
+parameters:
+- id: uri
+ label: IIO context URI
+ dtype: string
+ default: 'local:'
+
+- id: device
+ label: Device Name/ID
+ dtype: string
+
+- id: device_phy
+ label: PHY Device Name/ID
+ dtype: string
+
+- id: channels
+ label: Channels
+ dtype: raw
+ default: []
+
+- id: buffer_size
+ label: Buffer size
+ dtype: int
+ default: 0x8000
+
+- id: interpolation
+ label: Interpolation
+ dtype: int
+ default: 1
+
+- id: cyclic
+ label: Cyclic
+ dtype: bool
+ default: 'False'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: params
+ label: Parameters
+ dtype: raw
+ default: []
+
+inputs:
+- domain: stream
+ dtype: short
+ multiplicity: ${ len(channels) }
+
+asserts:
+- ${ len(channels) > 0 }
+
+templates:
+ imports: from gnuradio import iio
+ make: iio.device_sink(${uri}, ${device}, ${channels}, ${device_phy}, ${params}, ${buffer_size}, ${interpolation} - 1, ${cyclic})
+
+file_format: 1
diff --git a/gr-iio/grc/iio_device_source.block.yml b/gr-iio/grc/iio_device_source.block.yml
new file mode 100644
index 0000000000..3fc945b77d
--- /dev/null
+++ b/gr-iio/grc/iio_device_source.block.yml
@@ -0,0 +1,51 @@
+id: iio_device_source
+label: IIO Device Source
+flags: [ python ]
+
+parameters:
+- id: uri
+ label: IIO context URI
+ dtype: string
+ default: 'local:'
+
+- id: device
+ label: Device Name/ID
+ dtype: string
+
+- id: device_phy
+ label: PHY Device Name/ID
+ dtype: string
+
+- id: channels
+ label: Channels
+ dtype: raw
+ default: []
+
+- id: buffer_size
+ label: Buffer size
+ dtype: int
+ default: 0x8000
+
+- id: decimation
+ label: Decimation
+ dtype: int
+ default: 1
+
+- id: params
+ label: Parameters
+ dtype: raw
+ default: []
+
+outputs:
+- domain: stream
+ dtype: short
+ multiplicity: ${ len(channels) }
+- domain: message
+ id: msg
+ optional: true
+
+templates:
+ imports: from gnuradio import iio
+ make: iio.device_source(${uri}, ${device}, ${channels}, ${device_phy}, ${params}, ${buffer_size}, ${decimation} - 1)
+
+file_format: 1
diff --git a/gr-iio/grc/iio_fmcomms2_sink.block.yml b/gr-iio/grc/iio_fmcomms2_sink.block.yml
new file mode 100644
index 0000000000..53979c2d4a
--- /dev/null
+++ b/gr-iio/grc/iio_fmcomms2_sink.block.yml
@@ -0,0 +1,129 @@
+id: iio_fmcomms2_sink
+label: FMComms2/3/4 Sink
+flags: [ python ]
+
+parameters:
+- id: uri
+ label: IIO context URI
+ dtype: string
+ default: 'local:'
+
+- id: frequency
+ label: LO Frequency
+ dtype: int
+ default: 2400000000
+
+- id: samplerate
+ label: Sample Rate
+ dtype: int
+ default: samp_rate
+
+- id: bandwidth
+ label: RF Bandwidth
+ dtype: int
+ default: 20000000
+
+- id: buffer_size
+ label: Buffer size
+ dtype: int
+ default: 0x8000
+
+- id: tx1_en
+ label: TX1 Enabled
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: tx2_en
+ label: TX2 Enabled
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: cyclic
+ label: Cyclic
+ dtype: bool
+ default: 'False'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: rf_port_select
+ label: RF Port Select
+ dtype: enum
+ default: "'A'"
+ options: ["'A'", "'B'"]
+ option_labels: ['A', 'B']
+
+- id: attenuation1
+ label: Attenuation TX1 (dB)
+ dtype: float
+ default: 10.0
+ hide: ${ ('part' if tx1_en else 'all') }
+
+- id: attenuation2
+ label: Attenuation TX2 (dB)
+ dtype: float
+ default: 10.0
+ hide: ${ ('part' if tx2_en else 'all') }
+
+- id: filter_source
+ category: Filter
+ label: Filter Configuration
+ dtype: enum
+ default: "'Auto'"
+ options: ["'Off'", "'Auto'", "'File'", "'Design'"]
+ option_labels: ['Off', 'Auto', 'File', 'Design']
+
+- id: filter
+ category: Filter
+ label: Filter
+ dtype: file_open
+ default: ''
+ hide: ${ ('none' if filter_source == "'File'" else 'all') }
+
+- id: fpass
+ category: Filter
+ label: Fpass (Hz)
+ dtype: float
+ default: samp_rate/4
+ hide: ${ ('none' if filter_source == "'Design'" else 'all') }
+
+- id: fstop
+ category: Filter
+ label: Fstop (Hz)
+ dtype: float
+ default: samp_rate/3
+ hide: ${ ('none' if filter_source == "'Design'" else 'all') }
+
+- id: bandwidth
+ category: Filter
+ label: RF Bandwidth (Hz)
+ dtype: int
+ default: 20000000
+ hide: ${ ('all' if filter_source == "'File'" else 'none') }
+
+inputs:
+- domain: stream
+ dtype: complex
+ multiplicity: ${ sum([tx1_en, tx2_en]) }
+
+asserts:
+- ${ sum([tx1_en, tx2_en]) > 0 }
+- ${ ((samplerate>=2084000) or (filter_source!="'Off'")) }
+- ${ ((filter_source!="'File'") or (len(filter)>0)) }
+- ${ ((samplerate<=61440000) and (samplerate>=520833)) }
+- ${ ((bandwidth<=40000000) and (bandwidth>=200000)) }
+- ${ ((frequency<=6000000000) and (frequency>=47000000)) }
+- ${ ((filter_source!="'Design'") or (fpass<=samplerate)) }
+- ${ ((filter_source!="'Design'") or (fstop<=samplerate)) }
+- ${ ((filter_source!="'Design'") or (fstop>fpass)) }
+
+templates:
+ imports: from gnuradio import iio
+ make: iio.fmcomms2_sink_f32c(${uri}, ${frequency}, ${samplerate}, ${bandwidth}, ${tx1_en}, ${tx2_en}, ${buffer_size}, ${cyclic}, ${rf_port_select}, ${attenuation1}, ${attenuation2}, ${filter_source}, ${filter}, ${fpass}, ${fstop})
+ callbacks:
+ - set_params(${frequency}, ${samplerate}, ${bandwidth}, ${rf_port_select}, ${attenuation1}, ${attenuation2}, ${filter_source}, ${filter}, ${fpass}, ${fstop})
+
+file_format: 1
diff --git a/gr-iio/grc/iio_fmcomms2_source.block.yml b/gr-iio/grc/iio_fmcomms2_source.block.yml
new file mode 100644
index 0000000000..d30bf718da
--- /dev/null
+++ b/gr-iio/grc/iio_fmcomms2_source.block.yml
@@ -0,0 +1,154 @@
+id: iio_fmcomms2_source
+label: FMComms2/3/4 Source
+flags: [ python, throttle ]
+
+parameters:
+- id: uri
+ label: IIO context URI
+ dtype: string
+ default: 'local:'
+
+- id: frequency
+ label: LO Frequency
+ dtype: int
+ default: 2400000000
+
+- id: samplerate
+ label: Sample Rate
+ dtype: int
+ default: samp_rate
+
+- id: buffer_size
+ label: Buffer size
+ dtype: int
+ default: 0x8000
+
+- id: rx1_en
+ label: RX1 Enabled
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: rx2_en
+ label: RX2 Enabled
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: quadrature
+ label: Quadrature
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: rfdc
+ label: RF DC Correction
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: bbdc
+ label: BB DC Correction
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: gain1
+ label: Gain Mode (RX1)
+ dtype: enum
+ default: "'slow_attack'"
+ options: ["'manual'", "'slow_attack'", "'fast_attack'", "'hybrid'"]
+ option_labels: ['Manual', 'Slow Attack', 'Fast Attack', 'Hybrid']
+ hide: ${ ('none' if rx1_en else 'all') }
+
+- id: manual_gain1
+ label: Manual Gain (RX1)(dB)
+ dtype: float
+ default: 64
+ hide: ${ ('none' if ((gain1 == "'manual'") and (rx1_en)) else 'all') }
+
+- id: gain2
+ label: Gain Mode (RX2)
+ dtype: enum
+ default: "'slow_attack'"
+ options: ["'manual'", "'slow_attack'", "'fast_attack'", "'hybrid'"]
+ option_labels: ['Manual', 'Slow Attack', 'Fast Attack', 'Hybrid']
+ hide: ${ ('none' if rx2_en else 'all') }
+
+- id: manual_gain2
+ label: Manual Gain (RX2)(dB)
+ dtype: float
+ default: 64
+ hide: ${ ('none' if ((gain2 == "'manual'") and (rx2_en)) else 'all') }
+
+- id: rf_port_select
+ label: RF Port Select
+ dtype: enum
+ default: "'A_BALANCED'"
+ options: ["'A_BALANCED'", "'B_BALANCED'", "'C_BALANCED'", "'A_N'", "'A_P'", "'B_N'", "'B_P'", "'C_N'", "'C_P'", "'TX_MONITOR1'", "'TX_MONITOR2'", "'TX_MONITOR1_2'"]
+ option_labels: ['A_BALANCED', 'B_BALANCED', 'C_BALANCED', 'A_N', 'A_P', 'B_N', 'B_P', 'C_N', 'C_P', 'TX_MONITOR1', 'TX_MONITOR2', 'TX_MONITOR1_2']
+
+- id: filter_source
+ category: Filter
+ label: Filter Configuration
+ dtype: enum
+ default: "'Auto'"
+ options: ["'Off'", "'Auto'", "'File'", "'Design'"]
+ option_labels: ['Off', 'Auto', 'File', 'Design']
+
+- id: filter
+ category: Filter
+ label: Filter
+ dtype: file_open
+ default: ''
+ hide: ${ ('none' if filter_source == "'File'" else 'all') }
+
+- id: fpass
+ category: Filter
+ label: Fpass (Hz)
+ dtype: float
+ default: samp_rate/4
+ hide: ${ ('none' if filter_source == "'Design'" else 'all') }
+
+- id: fstop
+ category: Filter
+ label: Fstop (Hz)
+ dtype: float
+ default: samp_rate/3
+ hide: ${ ('none' if filter_source == "'Design'" else 'all') }
+
+- id: bandwidth
+ category: Filter
+ label: RF Bandwidth (Hz)
+ dtype: int
+ default: 20000000
+ hide: ${ ('all' if filter_source == "'File'" else 'none') }
+
+outputs:
+- domain: stream
+ dtype: complex
+ multiplicity: ${ sum([rx1_en, rx2_en]) }
+
+asserts:
+- ${ sum([rx1_en, rx2_en]) > 0 }
+- ${ ((samplerate>=2084000) or (filter_source!="'Off'")) }
+- ${ ((filter_source!="'File'") or (len(filter)>0)) }
+- ${ ((samplerate<=61440000) and (samplerate>=520833)) }
+- ${ ((bandwidth<=52000000) and (bandwidth>=200000)) }
+- ${ ((frequency<=6000000000) and (frequency>=70000000)) }
+- ${ ((filter_source!="'Design'") or (fpass<=samplerate)) }
+- ${ ((filter_source!="'Design'") or (fstop<=samplerate)) }
+- ${ ((filter_source!="'Design'") or (fstop>fpass)) }
+
+templates:
+ imports: from gnuradio import iio
+ make: iio.fmcomms2_source_f32c(${uri}, ${frequency}, ${samplerate}, ${bandwidth}, ${rx1_en}, ${rx2_en}, ${buffer_size}, ${quadrature}, ${rfdc}, ${bbdc}, ${gain1}, ${manual_gain1}, ${gain2}, ${manual_gain2}, ${rf_port_select}, ${filter_source}, ${filter}, ${fpass}, ${fstop})
+ callbacks:
+ - set_params(${frequency}, ${samplerate}, ${bandwidth}, ${quadrature}, ${rfdc}, ${bbdc}, ${gain1}, ${manual_gain1}, ${gain2}, ${manual_gain2}, ${rf_port_select}, ${filter_source}, ${filter}, ${fpass}, ${fstop})
+
+file_format: 1
diff --git a/gr-iio/grc/iio_fmcomms5_sink.block.yml b/gr-iio/grc/iio_fmcomms5_sink.block.yml
new file mode 100644
index 0000000000..085482f968
--- /dev/null
+++ b/gr-iio/grc/iio_fmcomms5_sink.block.yml
@@ -0,0 +1,161 @@
+id: iio_fmcomms5_sink
+label: FMComms5 Sink
+flags: [ python ]
+
+parameters:
+- id: uri
+ label: IIO context URI
+ dtype: string
+ default: 'local:'
+
+- id: frequency1
+ label: LO Frequency (RX1/RX2)
+ dtype: int
+ default: 2400000000
+
+- id: frequency2
+ label: LO Frequency (RX3/RX4)
+ dtype: int
+ default: 2400000000
+
+- id: samplerate
+ label: Sample Rate
+ dtype: int
+ default: 2084000
+
+- id: bandwidth
+ label: RF Bandwidth
+ dtype: int
+ default: 20000000
+
+- id: buffer_size
+ label: Buffer size
+ dtype: int
+ default: 0x8000
+
+- id: tx1_en
+ label: TX1 Enabled
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: tx2_en
+ label: TX2 Enabled
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: tx3_en
+ label: TX3 Enabled
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: tx4_en
+ label: TX4 Enabled
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: cyclic
+ label: Cyclic
+ dtype: bool
+ default: 'False'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: rf_port_select
+ label: RF Port Select
+ dtype: enum
+ default: "'A'"
+ options: ["'A'", "'B'"]
+ option_labels: ['A', 'B']
+
+- id: attenuation1
+ label: Attenuation TX1 (dB)
+ dtype: float
+ default: 10.0
+ hide: ${ ('part' if tx1_en else 'all') }
+
+- id: attenuation2
+ label: Attenuation TX2 (dB)
+ dtype: float
+ default: 10.0
+ hide: ${ ('part' if tx2_en else 'all') }
+
+- id: attenuation3
+ label: Attenuation TX3 (dB)
+ dtype: float
+ default: 10.0
+ hide: ${ ('part' if tx3_en else 'all') }
+
+- id: attenuation4
+ label: Attenuation TX4 (dB)
+ dtype: float
+ default: 10.0
+ hide: ${ ('part' if tx4_en else 'all') }
+
+- id: filter_source
+ category: Filter
+ label: Filter Configuration
+ dtype: enum
+ default: "'Auto'"
+ options: ["'Off'", "'Auto'", "'File'", "'Design'"]
+ option_labels: ['Off', 'Auto', 'File', 'Design']
+
+- id: filter
+ category: Filter
+ label: Filter
+ dtype: file_open
+ default: ''
+ hide: ${ ('none' if filter_source == "'File'" else 'all') }
+
+- id: fpass
+ category: Filter
+ label: Fpass (Hz)
+ dtype: float
+ default: samp_rate/4
+ hide: ${ ('none' if filter_source == "'Design'" else 'all') }
+
+- id: fstop
+ category: Filter
+ label: Fstop (Hz)
+ dtype: float
+ default: samp_rate/3
+ hide: ${ ('none' if filter_source == "'Design'" else 'all') }
+
+- id: bandwidth
+ category: Filter
+ label: RF Bandwidth (Hz)
+ dtype: int
+ default: 20000000
+ hide: ${ ('all' if filter_source == "'File'" else 'none') }
+
+inputs:
+- domain: stream
+ dtype: complex
+ multiplicity: ${ sum([tx1_en, tx2_en, tx3_en, tx4_en]) }
+
+asserts:
+- ${ sum([tx1_en, tx2_en, tx3_en, tx4_en]) > 0 }
+- ${ ((samplerate>=2084000) or (filter_source!="'Off'")) }
+- ${ ((filter_source!="'File'") or (len(filter)>0)) }
+- ${ ((samplerate<=61440000) and (samplerate>=520833)) }
+- ${ ((bandwidth<=52000000) and (bandwidth>=200000)) }
+- ${ ((frequency1<=6000000000) and (frequency1>=47000000)) }
+- ${ ((frequency2<=6000000000) and (frequency2>=47000000)) }
+- ${ ((filter_source!="'Design'") or (fpass<=samplerate)) }
+- ${ ((filter_source!="'Design'") or (fstop<=samplerate)) }
+- ${ ((filter_source!="'Design'") or (fstop>fpass)) }
+
+templates:
+ imports: from gnuradio import iio
+ make: iio.fmcomms5_sink_f32c(${uri}, ${frequency1}, ${frequency2}, ${samplerate}, ${bandwidth}, ${tx1_en}, ${tx2_en}, ${tx3_en}, ${tx4_en}, ${buffer_size}, ${cyclic}, ${rf_port_select}, ${attenuation1}, ${attenuation2}, ${attenuation3}, ${attenuation4}, ${filter_source}, ${filter}, ${fpass}, ${fstop})
+ callbacks:
+ - set_params(${frequency1}, ${frequency2}, ${samplerate}, ${bandwidth}, ${rf_port_select}, ${attenuation1}, ${attenuation2}, ${attenuation3}, ${attenuation4}, ${filter_source}, ${filter}, ${fpass}, ${fstop})
+
+file_format: 1
diff --git a/gr-iio/grc/iio_fmcomms5_source.block.yml b/gr-iio/grc/iio_fmcomms5_source.block.yml
new file mode 100644
index 0000000000..1336d7627c
--- /dev/null
+++ b/gr-iio/grc/iio_fmcomms5_source.block.yml
@@ -0,0 +1,207 @@
+id: iio_fmcomms5_source
+label: FMComms5 Source
+flags: [ throttle ]
+
+parameters:
+- id: uri
+ label: IIO context URI
+ dtype: string
+ default: 'local:'
+
+- id: frequency1
+ label: LO Frequency (RX1/RX2)
+ dtype: int
+ default: 2400000000
+
+- id: frequency2
+ label: LO Frequency (RX3/RX4)
+ dtype: int
+ default: 2400000000
+
+- id: samplerate
+ label: Sample Rate
+ dtype: int
+ default: 2084000
+
+- id: bandwidth
+ label: RF Bandwidth
+ dtype: int
+ default: 20000000
+
+- id: buffer_size
+ label: Buffer size
+ dtype: int
+ default: 0x8000
+
+- id: rx1_en
+ label: RX1 Enabled
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: rx2_en
+ label: RX2 Enabled
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: rx3_en
+ label: RX3 Enabled
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: rx4_en
+ label: RX4 Enabled
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: quadrature
+ label: Quadrature
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: rfdc
+ label: RF DC Correction
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: bbdc
+ label: BB DC Correction
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: gain1
+ label: Gain Mode (RX1)
+ dtype: enum
+ default: "'manual'"
+ options: ["'manual'", "'slow_attack'", "'fast_attack'", "'hybrid'"]
+ option_labels: ['Manual', 'Slow Attack', 'Fast Attack', 'Hybrid']
+ hide: ${ ('none' if rx1_en else 'all') }
+
+- id: manual_gain1
+ label: Manual Gain (RX1)(dB)
+ dtype: float
+ default: 64
+ hide: ${ ('none' if ((gain1 == "'manual'") and (rx1_en)) else 'all') }
+
+- id: gain2
+ label: Gain Mode (RX2)
+ dtype: enum
+ default: "'manual'"
+ options: ["'manual'", "'slow_attack'", "'fast_attack'", "'hybrid'"]
+ option_labels: ['Manual', 'Slow Attack', 'Fast Attack', 'Hybrid']
+ hide: ${ ('none' if rx2_en else 'all') }
+
+- id: manual_gain2
+ label: Manual Gain (RX2)(dB)
+ dtype: float
+ default: 64
+ hide: ${ ('none' if ((gain2 == "'manual'") and (rx2_en)) else 'all') }
+
+- id: gain3
+ label: Gain Mode (RX3)
+ dtype: enum
+ default: "'manual'"
+ options: ["'manual'", "'slow_attack'", "'fast_attack'", "'hybrid'"]
+ option_labels: ['Manual', 'Slow Attack', 'Fast Attack', 'Hybrid']
+ hide: ${ ('none' if rx3_en else 'all') }
+
+- id: manual_gain3
+ label: Manual Gain (RX3)(dB)
+ dtype: float
+ default: 64
+ hide: ${ ('none' if ((gain3 == "'manual'") and (rx3_en)) else 'all') }
+
+- id: gain4
+ label: Gain Mode (RX4)
+ dtype: enum
+ default: "'manual'"
+ options: ["'manual'", "'slow_attack'", "'fast_attack'", "'hybrid'"]
+ option_labels: ['Manual', 'Slow Attack', 'Fast Attack', 'Hybrid']
+ hide: ${ ('none' if rx4_en else 'all') }
+
+- id: manual_gain4
+ label: Manual Gain (RX4)(dB)
+ dtype: float
+ default: 64
+ hide: ${ ('none' if ((gain4 == "'manual'") and (rx4_en)) else 'all') }
+
+- id: rf_port_select
+ label: RF Port Select
+ dtype: enum
+ default: "'A_BALANCED'"
+ options: ["'A_BALANCED'", "'B_BALANCED'", "'C_BALANCED'", "'A_N'", "'A_P'", "'B_N'", "'B_P'", "'C_N'", "'C_P'", "'TX_MONITOR1'", "'TX_MONITOR2'", "'TX_MONITOR1_2'"]
+ option_labels: ['A_BALANCED', 'B_BALANCED', 'C_BALANCED', 'A_N', 'A_P', 'B_N', 'B_P', 'C_N', 'C_P', 'TX_MONITOR1', 'TX_MONITOR2', 'TX_MONITOR1_2']
+
+- id: filter_source
+ category: Filter
+ label: Filter Configuration
+ dtype: enum
+ default: "'Auto'"
+ options: ["'Off'", "'Auto'", "'File'", "'Design'"]
+ option_labels: ['Off', 'Auto', 'File', 'Design']
+
+- id: filter
+ category: Filter
+ label: Filter
+ dtype: file_open
+ default: ''
+ hide: ${ ('none' if filter_source == "'File'" else 'all') }
+
+- id: fpass
+ category: Filter
+ label: Fpass (Hz)
+ dtype: float
+ default: samp_rate/4
+ hide: ${ ('none' if filter_source == "'Design'" else 'all') }
+
+- id: fstop
+ category: Filter
+ label: Fstop (Hz)
+ dtype: float
+ default: samp_rate/3
+ hide: ${ ('none' if filter_source == "'Design'" else 'all') }
+
+- id: bandwidth
+ category: Filter
+ label: RF Bandwidth (Hz)
+ dtype: int
+ default: 20000000
+ hide: ${ ('all' if filter_source == "'File'" else 'none') }
+
+outputs:
+- domain: stream
+ dtype: complex
+ multiplicity: ${ sum([rx1_en, rx2_en, rx3_en, rx4_en]) }
+
+asserts:
+- ${ sum([rx1_en, rx2_en, rx3_en, rx4_en]) > 0 }
+- ${ ((samplerate>=2084000) or (filter_source!="'Off'")) }
+- ${ ((filter_source!="'File'") or (len(filter)>0)) }
+- ${ ((samplerate<=61440000) and (samplerate>=520833)) }
+- ${ ((bandwidth<=52000000) and (bandwidth>=200000)) }
+- ${ ((frequency1<=6000000000) and (frequency1>=70000000)) }
+- ${ ((frequency2<=6000000000) and (frequency2>=70000000)) }
+- ${ ((filter_source!="'Design'") or (fpass<=samplerate)) }
+- ${ ((filter_source!="'Design'") or (fstop<=samplerate)) }
+- ${ ((filter_source!="'Design'") or (fstop>fpass)) }
+
+templates:
+ imports: from gnuradio import iio
+ make: iio.fmcomms5_source_f32c(${uri}, ${frequency1}, ${frequency2}, ${samplerate}, ${bandwidth}, ${rx1_en}, ${rx2_en}, ${rx3_en}, ${rx4_en}, ${buffer_size}, ${quadrature}, ${rfdc}, ${bbdc}, ${gain1}, ${manual_gain1}, ${gain2}, ${manual_gain2}, ${gain3}, ${manual_gain3}, ${gain4}, ${manual_gain4}, ${rf_port_select}, ${filter_source}, ${filter}, ${fpass}, ${fstop})
+ callbacks:
+ - set_params(${frequency1}, ${frequency2}, ${samplerate}, ${bandwidth}, ${quadrature}, ${rfdc}, ${bbdc}, ${gain1}, ${manual_gain1}, ${gain2}, ${manual_gain2}, ${gain3}, ${manual_gain3}, ${gain4}, ${manual_gain4}, ${rf_port_select}, ${filter_source}, ${filter}, ${fpass}, ${fstop})
+
+file_format: 1
diff --git a/gr-iio/grc/iio_pluto_sink.block.yml b/gr-iio/grc/iio_pluto_sink.block.yml
new file mode 100644
index 0000000000..6c965becd1
--- /dev/null
+++ b/gr-iio/grc/iio_pluto_sink.block.yml
@@ -0,0 +1,94 @@
+id: iio_pluto_sink
+label: PlutoSDR Sink
+flags: [ python ]
+
+parameters:
+- id: uri
+ label: IIO context URI
+ dtype: string
+ default: ''
+
+- id: frequency
+ label: LO Frequency
+ dtype: int
+ default: 2400000000
+
+- id: samplerate
+ label: Sample Rate
+ dtype: int
+ default: samp_rate
+
+- id: buffer_size
+ label: Buffer size
+ dtype: int
+ default: 0x8000
+
+- id: cyclic
+ label: Cyclic
+ dtype: bool
+ default: 'False'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: attenuation1
+ label: Attenuation TX1 (dB)
+ dtype: float
+ default: 10.0
+
+- id: filter_source
+ category: Filter
+ label: Filter Configuration
+ dtype: enum
+ default: "'Auto'"
+ options: ["'Off'", "'Auto'", "'File'", "'Design'"]
+ option_labels: ['Off', 'Auto', 'File', 'Design']
+
+- id: filter
+ category: Filter
+ label: Filter
+ dtype: file_open
+ default: ''
+ hide: ${ ('none' if filter_source == "'File'" else 'all') }
+
+- id: fpass
+ category: Filter
+ label: Fpass (Hz)
+ dtype: float
+ default: samp_rate/4
+ hide: ${ ('none' if filter_source == "'Design'" else 'all') }
+
+- id: fstop
+ category: Filter
+ label: Fstop (Hz)
+ dtype: float
+ default: samp_rate/3
+ hide: ${ ('none' if filter_source == "'Design'" else 'all') }
+
+- id: bandwidth
+ category: Filter
+ label: RF Bandwidth (Hz)
+ dtype: int
+ default: 20000000
+ hide: ${ ('all' if filter_source == "'File'" else 'none') }
+
+inputs:
+- domain: stream
+ dtype: complex
+
+asserts:
+- ${ ((samplerate>=2084000) or (filter_source!="'Off'")) }
+- ${ ((filter_source!="'File'") or (len(filter)>0)) }
+- ${ ((samplerate<=61440000) and (samplerate>=65105)) }
+- ${ ((bandwidth<=40000000) and (bandwidth>=200000)) }
+- ${ ((frequency<=6000000000) and (frequency>=47000000)) }
+- ${ ((filter_source!="'Design'") or (fpass<=samplerate)) }
+- ${ ((filter_source!="'Design'") or (fstop<=samplerate)) }
+- ${ ((filter_source!="'Design'") or (fstop>fpass)) }
+
+templates:
+ imports: from gnuradio import iio
+ make: iio.pluto_sink(${uri}, ${frequency}, ${samplerate}, ${bandwidth}, ${buffer_size}, ${cyclic}, ${attenuation1}, ${filter_source}, ${filter}, ${fpass}, ${fstop})
+ callbacks:
+ - set_params(${frequency}, ${samplerate}, ${bandwidth}, ${buffer_size}, ${cyclic}, ${attenuation1}, ${filter_source}, ${filter}, ${fpass}, ${fstop})
+
+file_format: 1
diff --git a/gr-iio/grc/iio_pluto_source.block.yml b/gr-iio/grc/iio_pluto_source.block.yml
new file mode 100644
index 0000000000..8bce18f8ba
--- /dev/null
+++ b/gr-iio/grc/iio_pluto_source.block.yml
@@ -0,0 +1,116 @@
+id: iio_pluto_source
+label: PlutoSDR Source
+flags: [ throttle ]
+
+parameters:
+- id: uri
+ label: IIO context URI
+ dtype: string
+ default: ''
+
+- id: frequency
+ label: LO Frequency
+ dtype: int
+ default: 2400000000
+
+- id: samplerate
+ label: Sample Rate
+ dtype: int
+ default: samp_rate
+
+- id: buffer_size
+ label: Buffer size
+ dtype: int
+ default: 0x8000
+
+- id: quadrature
+ label: Quadrature
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: rfdc
+ label: RF DC Correction
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: bbdc
+ label: BB DC Correction
+ dtype: bool
+ default: 'True'
+ options: ['False', 'True']
+ option_labels: ['False', 'True']
+
+- id: gain1
+ label: Gain Mode (RX1)
+ dtype: enum
+ default: "'slow_attack'"
+ options: ["'manual'", "'slow_attack'", "'fast_attack'", "'hybrid'"]
+ option_labels: ['Manual', 'Slow Attack', 'Fast Attack', 'Hybrid']
+
+- id: manual_gain1
+ label: Manual Gain (RX1)(dB)
+ dtype: float
+ default: 64
+ hide: ${ ('none' if gain1 == "'manual'" else 'all') }
+
+- id: filter_source
+ category: Filter
+ label: Filter Configuration
+ dtype: enum
+ default: "'Auto'"
+ options: ["'Off'", "'Auto'", "'File'", "'Design'"]
+ option_labels: ['Off', 'Auto', 'File', 'Design']
+
+- id: filter
+ category: Filter
+ label: Filter
+ dtype: file_open
+ default: ''
+ hide: ${ ('none' if filter_source == "'File'" else 'all') }
+
+- id: fpass
+ category: Filter
+ label: Fpass (Hz)
+ dtype: float
+ default: samp_rate/4
+ hide: ${ ('none' if filter_source == "'Design'" else 'all') }
+
+- id: fstop
+ category: Filter
+ label: Fstop (Hz)
+ dtype: float
+ default: samp_rate/3
+ hide: ${ ('none' if filter_source == "'Design'" else 'all') }
+
+- id: bandwidth
+ category: Filter
+ label: RF Bandwidth (Hz)
+ dtype: int
+ default: 20000000
+ hide: ${ ('all' if filter_source == "'File'" else 'none') }
+
+outputs:
+- domain: stream
+ dtype: complex
+
+asserts:
+- ${ ((samplerate>=2084000) or (filter_source!="'Off'")) }
+- ${ ((filter_source!="'File'") or (len(filter)>0)) }
+- ${ ((samplerate<=61440000) and (samplerate>=65105)) }
+- ${ ((bandwidth<=52000000) and (bandwidth>=200000)) }
+- ${ ((frequency<=6000000000) and (frequency>=70000000)) }
+- ${ ((filter_source!="'Design'") or (fpass<=samplerate)) }
+- ${ ((filter_source!="'Design'") or (fstop<=samplerate)) }
+- ${ ((filter_source!="'Design'") or (fstop>fpass)) }
+
+templates:
+ imports: from gnuradio import iio
+ make: iio.pluto_source(${uri}, ${frequency}, ${samplerate}, ${bandwidth}, ${buffer_size}, ${quadrature}, ${rfdc}, ${bbdc}, ${gain1}, ${manual_gain1}, ${filter_source}, ${filter}, ${fpass}, ${fstop})
+ callbacks:
+ - set_params(${frequency}, ${samplerate}, ${bandwidth}, ${buffer_size}, ${quadrature}, ${rfdc}, ${bbdc}, ${gain1}, ${manual_gain1}, ${filter_source}, ${filter}, ${fpass}, ${fstop})
+
+file_format: 1
diff --git a/gr-iio/include/gnuradio/iio/CMakeLists.txt b/gr-iio/include/gnuradio/iio/CMakeLists.txt
new file mode 100644
index 0000000000..cf65dc274a
--- /dev/null
+++ b/gr-iio/include/gnuradio/iio/CMakeLists.txt
@@ -0,0 +1,27 @@
+# Copyright 2021 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+########################################################################
+# Install public header files
+########################################################################
+
+install(FILES
+ api.h
+ attr_sink.h
+ attr_source.h
+ attr_updater.h
+ device_sink.h
+ device_source.h
+ dds_control.h
+ fmcomms2_sink.h
+ fmcomms2_source.h
+ fmcomms5_sink.h
+ fmcomms5_source.h
+ pluto_sink.h
+ pluto_source.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/iio
+)
diff --git a/gr-iio/include/gnuradio/iio/api.h b/gr-iio/include/gnuradio/iio/api.h
new file mode 100644
index 0000000000..e5badb98fd
--- /dev/null
+++ b/gr-iio/include/gnuradio/iio/api.h
@@ -0,0 +1,21 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_IIO_API_H
+#define INCLUDED_IIO_API_H
+
+#include <gnuradio/attributes.h>
+
+#ifdef gnuradio_iio_EXPORTS
+#define IIO_API __GR_ATTR_EXPORT
+#else
+#define IIO_API __GR_ATTR_IMPORT
+#endif
+
+#endif /* INCLUDED_IIO_API_H */
diff --git a/gr-iio/include/gnuradio/iio/attr_sink.h b/gr-iio/include/gnuradio/iio/attr_sink.h
new file mode 100644
index 0000000000..a343ddbc16
--- /dev/null
+++ b/gr-iio/include/gnuradio/iio/attr_sink.h
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2018 Analog Devices Inc.
+ * Author: Travis Collins <travis.collins@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+
+#ifndef INCLUDED_IIO_ATTR_SINK_H
+#define INCLUDED_IIO_ATTR_SINK_H
+
+#include <gnuradio/block.h>
+#include <gnuradio/iio/api.h>
+
+namespace gr {
+namespace iio {
+
+/*!
+ * \brief Generic writer for attributes of IIO devices
+ * \ingroup iio
+ *
+ * \details
+ * This block allow for updating of any IIO attribute that is writable. This
+ * includes channel, device, device buffer, device debug, and direct register
+ * attributes. All messages must be a pmt dictionary where the key is the
+ * attribute to update and the value is the value to be written. Messages can
+ * be an array of dictionaries or a single dictionary.
+ */
+class IIO_API attr_sink : virtual public gr::block
+{
+public:
+ typedef std::shared_ptr<attr_sink> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::attr_sink.
+ *
+ * \param uri String of context uri
+ * \param device String of device name
+ * \param channel String of device name
+ * \param type Integer determining attribute type:
+ * 0: Channel attribute
+ * 1: Device attribute
+ * 2: Device buffer attribute
+ * 3: Device debug attribute
+ * 4: Direct register access
+ * \param output Boolean when True if channel attribute is an output
+ * \param required_enable Boolean when True if an extra register_access
+ * attribute write is required for use a register. This is required
+ * for MathWorks generated IP.
+ */
+ static sptr make(const std::string& uri,
+ const std::string& device,
+ const std::string& channel,
+ int type,
+ bool output,
+ bool required_enable);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_ATTR_SINK_H */
diff --git a/gr-iio/include/gnuradio/iio/attr_source.h b/gr-iio/include/gnuradio/iio/attr_source.h
new file mode 100644
index 0000000000..d987380a67
--- /dev/null
+++ b/gr-iio/include/gnuradio/iio/attr_source.h
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2018 Analog Devices Inc.
+ * Author: Travis Collins <travis.collins@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+
+#ifndef INCLUDED_IIO_ATTR_SOURCE_H
+#define INCLUDED_IIO_ATTR_SOURCE_H
+
+#include <gnuradio/iio/api.h>
+#include <gnuradio/sync_block.h>
+
+namespace gr {
+namespace iio {
+
+/*!
+ * \brief Generic reader for attributes of IIO devices
+ * \ingroup iio
+ *
+ * \details
+ * This block allow for reading of any IIO attribute that is readable. This
+ * includes channel, device, device buffer, device debug, and direct register
+ * attributes.
+ */
+class IIO_API attr_source : virtual public gr::sync_block
+{
+public:
+ typedef std::shared_ptr<attr_source> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::attr_source.
+ *
+ * \param uri String of the context uri
+ * \param device String of device name
+ * \param channel String of device name
+ * \param attribute String of attribute name
+ * \param update_interval_ms Integer number of milliseconds between
+ * attribute reads
+ * \param samples_per_update Integer number of samples to collect before
+ * block returns
+ * \param data_type Integer which selects what data type to output for
+ * received data:
+ * 0: double
+ * 1: float
+ * 2: long long
+ * 3: int
+ * 4: uint8
+ * \param attr_type Integer determining attribute type:
+ * 0: Channel attribute
+ * 1: Device attribute
+ * 2: Device debug attribute
+ * \param output Boolean when True if channel attribute is an output
+ * \param address uint32 register address of register to be read
+ * \param required_enable Boolean when True if an extra register_access
+ * attribute write is required for use a register. This is required
+ * for MathWorks generated IP.
+ */
+ static sptr make(const std::string& uri,
+ const std::string& device,
+ const std::string& channel,
+ const std::string& attribute,
+ int update_interval_ms,
+ int samples_per_update,
+ int data_type,
+ int attr_type,
+ bool output,
+ uint32_t address,
+ bool required_enable);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_ATTR_SOURCE_H */
diff --git a/gr-iio/include/gnuradio/iio/attr_updater.h b/gr-iio/include/gnuradio/iio/attr_updater.h
new file mode 100644
index 0000000000..3991b2c686
--- /dev/null
+++ b/gr-iio/include/gnuradio/iio/attr_updater.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2019 Analog Devices Inc.
+ * Author: Travis Collins <travis.collins@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+
+#ifndef INCLUDED_IIO_ATTR_UPDATER_H
+#define INCLUDED_IIO_ATTR_UPDATER_H
+
+#include <gnuradio/block.h>
+#include <gnuradio/iio/api.h>
+
+namespace gr {
+namespace iio {
+
+/*!
+ * \brief Generic helper block to create message in a format that will be
+ * accepted by the IIO Attribute Sink Block
+ * \ingroup iio
+ *
+ * \details
+ * This block is a simple but flexible message source which can be connected to
+ * the IIO Attribute Sink block for easy interaction and real-time control of
+ * IIO driver attributes.
+ */
+class IIO_API attr_updater : virtual public gr::block
+{
+public:
+ typedef std::shared_ptr<attr_updater> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::attr_updater.
+ *
+ * \param attribute String of name of attribute to be updated
+ * \param value String of value to update the attribute too
+ * \param interval_ms Integer of interval in milliseconds to produce
+ * messages. If zero outputs will be made only on callback changes
+ * and when the flowgraph starts
+ */
+ static sptr
+ make(const std::string attribute, const std::string value, unsigned int interval_ms);
+
+ virtual void set_value(std::string value) = 0;
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_ATTR_UPDATER_H */
diff --git a/gr-iio/include/gnuradio/iio/dds_control.h b/gr-iio/include/gnuradio/iio/dds_control.h
new file mode 100644
index 0000000000..248b87d24a
--- /dev/null
+++ b/gr-iio/include/gnuradio/iio/dds_control.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2019 Analog Devices Inc.
+ * Author: Travis Collins <travis.collins@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+
+#ifndef INCLUDED_IIO_DDS_CONTROL_H
+#define INCLUDED_IIO_DDS_CONTROL_H
+
+#include <gnuradio/block.h>
+#include <gnuradio/iio/api.h>
+
+namespace gr {
+namespace iio {
+
+/*!
+ * \brief Control block for DDSs which are available in controlling FPGAs of
+ * certain IIO drivers
+ * \ingroup iio
+ *
+ * \details
+ * This block allow for control of multiple direct digital synthesizers (DDS)
+ * to create transmit tones. The are available in the generic AXI DAC driver
+ * from Analog Devices.
+ */
+class IIO_API dds_control : virtual public gr::block
+{
+public:
+ typedef std::shared_ptr<dds_control> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::dds_control.
+ *
+ * \param uri String of the context uri
+ * \param enabled Vector of integers where individual indexes represent
+ * specific DDSs and when not zero the are enabled
+ * \param frequencies Vector of long integers where individual indexes
+ * represent specific DDS frequencies in Hz
+ * \param phases Vector of floats where individual indexes represent
+ * specific DDS phase in degrees
+ * \param scales Vector of floats where individual indexes represent
+ * specific DDS scale from 0 to 1
+ */
+ static sptr make(const std::string& uri,
+ std::vector<int> enabled,
+ std::vector<long> frequencies,
+ std::vector<float> phases,
+ std::vector<float> scales);
+
+ virtual void set_dds_confg(std::vector<long> frequencies,
+ std::vector<float> phases,
+ std::vector<float> scales) = 0;
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_DDS_CONTROL_H */
diff --git a/gr-iio/include/gnuradio/iio/device_sink.h b/gr-iio/include/gnuradio/iio/device_sink.h
new file mode 100644
index 0000000000..e28c134a68
--- /dev/null
+++ b/gr-iio/include/gnuradio/iio/device_sink.h
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+
+#ifndef INCLUDED_IIO_DEVICE_SINK_H
+#define INCLUDED_IIO_DEVICE_SINK_H
+
+#include <gnuradio/iio/api.h>
+#include <gnuradio/sync_block.h>
+
+#define DEFAULT_BUFFER_SIZE 0x8000
+
+extern "C" {
+struct iio_context;
+};
+
+namespace gr {
+namespace iio {
+
+/*!
+ * \brief Generic sink for IIO drivers with buffered input channels
+ * \ingroup iio
+ *
+ * \details
+ * This block allows for streaming data to any IIO driver which has input
+ * scan elements or buffered channels.
+ */
+class IIO_API device_sink : virtual public gr::sync_block
+{
+public:
+ typedef std::shared_ptr<device_sink> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::device.
+ *
+ * \param uri String of the context uri
+ * \param device String of device name
+ * \param channels Vector of strings of channels names
+ * \param device_phy String of phy device name where attribute updates are
+ * applied
+ * \param params Vector of strings of attributes to set in form:
+ * "<attribute name>=<value to set>,<attribute name>=<value to set>"
+ * \param buffer_size Integer number of samples to be put into each IIO
+ * buffered passed to hardware.
+ * \param interpolation Integer number of zeros to insert into transmit
+ * transmit buffers between samples
+ * \param cyclic Boolean when True sends first buffer_size number of samples
+ * to hardware which is repeated in the hardware itself. Future
+ * samples are ignored.
+ */
+ static sptr make(const std::string& uri,
+ const std::string& device,
+ const std::vector<std::string>& channels,
+ const std::string& device_phy,
+ const std::vector<std::string>& params,
+ unsigned int buffer_size = DEFAULT_BUFFER_SIZE,
+ unsigned int interpolation = 0,
+ bool cyclic = false);
+
+ static sptr make_from(struct iio_context* ctx,
+ const std::string& device,
+ const std::vector<std::string>& channels,
+ const std::string& device_phy,
+ const std::vector<std::string>& params,
+ unsigned int buffer_size = DEFAULT_BUFFER_SIZE,
+ unsigned int interpolation = 0,
+ bool cyclic = false);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_DEVICE_SINK_H */
diff --git a/gr-iio/include/gnuradio/iio/device_source.h b/gr-iio/include/gnuradio/iio/device_source.h
new file mode 100644
index 0000000000..4223858e7f
--- /dev/null
+++ b/gr-iio/include/gnuradio/iio/device_source.h
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+
+#ifndef INCLUDED_IIO_DEVICE_SOURCE_H
+#define INCLUDED_IIO_DEVICE_SOURCE_H
+
+#include <gnuradio/iio/api.h>
+#include <gnuradio/sync_block.h>
+
+#define DEFAULT_BUFFER_SIZE 0x8000
+
+extern "C" {
+struct iio_context;
+};
+
+namespace gr {
+namespace iio {
+
+/*!
+ * \brief Generic source for IIO drivers with buffered output channels
+ * \ingroup iio
+ *
+ * \details
+ * This block allows for streaming data from any IIO driver which has output
+ * scan elements or buffered channels.
+ */
+class IIO_API device_source : virtual public gr::sync_block
+{
+public:
+ typedef std::shared_ptr<device_source> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::device.
+ *
+ * \param uri String of the context uri
+ * \param device String of device name
+ * \param channels Vector of strings of channels names
+ * \param device_phy String of phy device name where attribute updates are
+ * applied
+ * \param params Vector of strings of attributes to set in form:
+ * "<attribute name>=<value to set>,<attribute name>=<value to set>"
+ * \param buffer_size Integer number of samples to be put into each IIO
+ * buffered passed to hardware.
+ * \param decimation Integer number of sample to remove from received
+ * data buffers between successive samples
+ */
+ static sptr make(const std::string& uri,
+ const std::string& device,
+ const std::vector<std::string>& channels,
+ const std::string& device_phy,
+ const std::vector<std::string>& params,
+ unsigned int buffer_size = DEFAULT_BUFFER_SIZE,
+ unsigned int decimation = 0);
+
+ static sptr make_from(struct iio_context* ctx,
+ const std::string& device,
+ const std::vector<std::string>& channels,
+ const std::string& device_phy,
+ const std::vector<std::string>& params,
+ unsigned int buffer_size = DEFAULT_BUFFER_SIZE,
+ unsigned int decimation = 0);
+
+ virtual void set_buffer_size(unsigned int buffer_size) = 0;
+ virtual void set_timeout_ms(unsigned long timeout) = 0;
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_DEVICE_SOURCE_H */
diff --git a/gr-iio/include/gnuradio/iio/fmcomms2_sink.h b/gr-iio/include/gnuradio/iio/fmcomms2_sink.h
new file mode 100644
index 0000000000..071cef6161
--- /dev/null
+++ b/gr-iio/include/gnuradio/iio/fmcomms2_sink.h
@@ -0,0 +1,229 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+
+#ifndef INCLUDED_IIO_FMCOMMS2_SINK_H
+#define INCLUDED_IIO_FMCOMMS2_SINK_H
+
+#include <gnuradio/hier_block2.h>
+#include <gnuradio/iio/api.h>
+#include <gnuradio/sync_block.h>
+
+#include "device_sink.h"
+
+namespace gr {
+namespace iio {
+
+/*!
+ * \brief Device specific sink for FMComms evaluation cards
+ * \ingroup iio
+ *
+ * \details
+ * This block is a sink specifically designed for FMComms2/3/4 evaluation
+ * cards. However, it should support any AD936x based device using an IIO
+ * driver.
+ */
+class IIO_API fmcomms2_sink : virtual public gr::sync_block
+{
+public:
+ typedef std::shared_ptr<fmcomms2_sink> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::fmcomms2_sink.
+ *
+ * \param uri String of the context uri
+ * \param frequency Long long of LO frequency in Hz
+ * \param samplerate Long of sample rate in samples per second
+ * \param bandwidth Long of bandwidth of front-end analog filter in
+ * in Hz
+ * \param ch1_en Boolean enable channel 1
+ * \param ch2_en Boolean enable channel 2
+ * \param ch3_en Boolean enable channel 3
+ * \param ch4_en Boolean enable channel 4
+ * \param buffer_size Long of number of samples in buffer to send to device
+ * \param cyclic Boolean when True sends first buffer_size number of samples
+ * to hardware which is repeated in the hardware itself. Future
+ * samples are ignored.
+ * \param rf_port_select String of name of port to use for TX output mux
+ * with options: 'A', 'B'
+ * \param attenuation1 Double of TX channel 1 attenuation in dB [0, 90]
+ * \param attenuation2 Double of TX channel 2 attenuation in dB [0, 90]
+ * \param filter_source String which selects filter configuration with
+ * options:
+ * - 'Off': Disable filter
+ * - 'Auto': Use auto-generated filters
+ * - 'File': Use provide filter filter in filter_filename input
+ * - 'Design': Create filter from Fpass, Fstop, samplerate, and
+ * bandwidth parameters
+ * \param filter_filename String of path to filter file
+ * \param Fpass Float of edge of passband frequency in Hz for designed FIR
+ * \param Fstop Float of edge of stopband frequency in Hz for designed FIR
+ */
+ static sptr make(const std::string& uri,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ unsigned long buffer_size,
+ bool cyclic,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0);
+
+ static sptr make_from(struct iio_context* ctx,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ unsigned long buffer_size,
+ bool cyclic,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0);
+
+ virtual void set_params(unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0) = 0;
+};
+
+/*!
+ * \brief Device specific sink for FMComms evaluation cards
+ * \ingroup iio
+ *
+ * \details
+ * This block is a sink specifically designed for FMComms2/3/4 evaluation
+ * cards. However, it should support any AD936x based device using an IIO
+ * driver.
+ */
+class IIO_API fmcomms2_sink_f32c : virtual public gr::hier_block2
+{
+public:
+ typedef std::shared_ptr<fmcomms2_sink_f32c> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::fmcomms2_sink.
+ *
+ * \param uri String of the context uri
+ * \param frequency Long long of LO frequency in Hz
+ * \param samplerate Long of sample rate in samples per second
+ * \param bandwidth Long of bandwidth of front-end analog filter in
+ * in Hz
+ * \param tx1_en Boolean enable channel 1
+ * \param tx2_en Boolean enable channel 2
+ * \param buffer_size Long of number of samples in buffer to send to device
+ * \param cyclic Boolean when True sends first buffer_size number of samples
+ * to hardware which is repeated in the hardware itself. Future
+ * samples are ignored.
+ * \param rf_port_select String of name of port to use for TX output mux
+ * with options: 'A', 'B'
+ * \param attenuation1 Double of TX channel 1 attenuation in dB [0, 90]
+ * \param attenuation2 Double of TX channel 2 attenuation in dB [0, 90]
+ * \param filter_source String which selects filter configuration with
+ * options:
+ * - 'Off': Disable filter
+ * - 'Auto': Use auto-generated filters
+ * - 'File': Use provide filter filter in filter_filename input
+ * - 'Design': Create filter from Fpass, Fstop, samplerate, and
+ * bandwidth parameters
+ * \param filter_filename String of path to filter file
+ * \param Fpass Float of edge of passband frequency in Hz for designed FIR
+ * \param Fstop Float of edge of stopband frequency in Hz for designed FIR
+ */
+ static sptr make(const std::string& uri,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool tx1_en,
+ bool tx2_en,
+ unsigned long buffer_size,
+ bool cyclic,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0)
+ {
+ fmcomms2_sink::sptr block = fmcomms2_sink::make(uri,
+ frequency,
+ samplerate,
+ bandwidth,
+ tx1_en,
+ tx1_en,
+ tx2_en,
+ tx2_en,
+ buffer_size,
+ cyclic,
+ rf_port_select,
+ attenuation1,
+ attenuation2,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+
+ return gnuradio::get_initial_sptr(new fmcomms2_sink_f32c(tx1_en, tx2_en, block));
+ }
+
+ void set_params(unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0)
+ {
+ fmcomms2_block->set_params(frequency,
+ samplerate,
+ bandwidth,
+ rf_port_select,
+ attenuation1,
+ attenuation2,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+ }
+
+private:
+ fmcomms2_sink::sptr fmcomms2_block;
+
+protected:
+ explicit fmcomms2_sink_f32c(bool tx1_en, bool tx2_en, fmcomms2_sink::sptr block);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_FMCOMMS2_SINK_H */
diff --git a/gr-iio/include/gnuradio/iio/fmcomms2_source.h b/gr-iio/include/gnuradio/iio/fmcomms2_source.h
new file mode 100644
index 0000000000..39f638d24e
--- /dev/null
+++ b/gr-iio/include/gnuradio/iio/fmcomms2_source.h
@@ -0,0 +1,305 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+
+#ifndef INCLUDED_IIO_FMCOMMS2_SOURCE_H
+#define INCLUDED_IIO_FMCOMMS2_SOURCE_H
+
+#include <gnuradio/hier_block2.h>
+#include <gnuradio/iio/api.h>
+#include <gnuradio/sync_block.h>
+
+#include "device_source.h"
+
+namespace gr {
+namespace iio {
+
+/*!
+ * \brief Device specific source for FMComms evaluation cards
+ * \ingroup iio
+ *
+ * \details
+ * This block is a source specifically designed for FMComms2/3/4 evaluation
+ * cards. However, it should support any AD936x based device using an IIO
+ * driver.
+ */
+class IIO_API fmcomms2_source : virtual public gr::sync_block
+{
+public:
+ typedef std::shared_ptr<fmcomms2_source> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::fmcomms2_source.
+ *
+ * \param uri String of the context uri
+ * \param frequency Long long of LO frequency in Hz
+ * \param samplerate Long of sample rate in samples per second
+ * \param bandwidth Long of bandwidth of front-end analog filter in
+ * in Hz
+ * \param ch1_en Boolean enable channel 1
+ * \param ch2_en Boolean enable channel 2
+ * \param ch3_en Boolean enable channel 3
+ * \param ch4_en Boolean enable channel 4
+ * \param quadrature Boolean enable RX quadrature tracking
+ * \param rfdc Boolean enable RX RF DC tracking
+ * \param bbdc Boolean enable RX Baseband DC tracking
+ * \param buffer_size Long of number of samples in buffer to send to device
+ * \param rf_port_select String of name of port to use for TX output mux
+ * with options:
+ * - 'A_BALANCED'
+ * - 'B_BALANCED'
+ * - 'C_BALANCED'
+ * - 'A_N'
+ * - 'A_P'
+ * - 'B_N'
+ * - 'B_P'
+ * - 'C_N'
+ * - 'C_P'
+ * - 'TX_MONITOR1'
+ * - 'TX_MONITOR2'
+ * - 'TX_MONITOR1_2'
+ * \param gain1 String of gain mode for channel 1 with options:
+ * - 'manual'
+ * - 'slow_attack'
+ * - 'fast_attack'
+ * - 'hybrid'
+ * \param gain1_value Double of RX channel 1 gain in dB [0, 76]
+ * \param gain2 String of gain mode for channel 1 with options:
+ * - 'manual'
+ * - 'slow_attack'
+ * - 'fast_attack'
+ * - 'hybrid'
+ * \param gain2_value Double of RX channel 2 gain in dB [0, 76]
+ * \param filter_source String which selects filter configuration with
+ * options:
+ * - 'Off': Disable filter
+ * - 'Auto': Use auto-generated filters
+ * - 'File': Use provide filter filter in filter_filename input
+ * - 'Design': Create filter from Fpass, Fstop, samplerate, and
+ * bandwidth parameters
+ * \param filter_filename String of path to filter file
+ * \param Fpass Float of edge of passband frequency in Hz for designed FIR
+ * \param Fstop Float of edge of stopband frequency in Hz for designed FIR
+ */
+ static sptr make(const std::string& uri,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* rf_port_select,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0);
+
+ static sptr make_from(struct iio_context* ctx,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* rf_port_select,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0);
+
+ virtual void set_params(unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* rf_port_select,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0) = 0;
+};
+
+/*!
+ * \brief Device specific source for FMComms evaluation cards
+ * \ingroup iio
+ *
+ * \details
+ * This block is a source specifically designed for FMComms2/3/4 evaluation
+ * cards. However, it should support any AD936x based device using an IIO
+ * driver.
+ */
+class IIO_API fmcomms2_source_f32c : virtual public gr::hier_block2
+{
+public:
+ typedef std::shared_ptr<fmcomms2_source_f32c> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::fmcomms2_source.
+ *
+ * \param uri String of the context uri
+ * \param frequency Long long of LO frequency in Hz
+ * \param samplerate Long of sample rate in samples per second
+ * \param bandwidth Long of bandwidth of front-end analog filter in
+ * in Hz
+ * \param rx1_en Boolean enable channel 1
+ * \param rx2_en Boolean enable channel 2
+ * \param quadrature Boolean enable RX quadrature tracking
+ * \param rfdc Boolean enable RX RF DC tracking
+ * \param bbdc Boolean enable RX Baseband DC tracking
+ * \param buffer_size Long of number of samples in buffer to send to device
+ * \param rf_port_select String of name of port to use for TX output mux
+ * with options:
+ * - 'A_BALANCED'
+ * - 'B_BALANCED'
+ * - 'C_BALANCED'
+ * - 'A_N'
+ * - 'A_P'
+ * - 'B_N'
+ * - 'B_P'
+ * - 'C_N'
+ * - 'C_P'
+ * - 'TX_MONITOR1'
+ * - 'TX_MONITOR2'
+ * - 'TX_MONITOR1_2'
+ * \param gain1 String of gain mode for channel 1 with options:
+ * - 'manual'
+ * - 'slow_attack'
+ * - 'fast_attack'
+ * - 'hybrid'
+ * \param gain1_value Double of RX channel 1 gain in dB [0, 76]
+ * \param gain2 String of gain mode for channel 1 with options:
+ * - 'manual'
+ * - 'slow_attack'
+ * - 'fast_attack'
+ * - 'hybrid'
+ * \param gain2_value Double of RX channel 2 gain in dB [0, 76]
+ * \param filter_source String which selects filter configuration with
+ * options:
+ * - 'Off': Disable filter
+ * - 'Auto': Use auto-generated filters
+ * - 'File': Use provide filter filter in filter_filename input
+ * - 'Design': Create filter from Fpass, Fstop, samplerate, and
+ * bandwidth parameters
+ * \param filter_filename String of path to filter file
+ * \param Fpass Float of edge of passband frequency in Hz for designed FIR
+ * \param Fstop Float of edge of stopband frequency in Hz for designed FIR
+ */
+ static sptr make(const std::string& uri,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool rx1_en,
+ bool rx2_en,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* rf_port_select,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0)
+ {
+ fmcomms2_source::sptr block = fmcomms2_source::make(uri,
+ frequency,
+ samplerate,
+ bandwidth,
+ rx1_en,
+ rx1_en,
+ rx2_en,
+ rx2_en,
+ buffer_size,
+ quadrature,
+ rfdc,
+ bbdc,
+ gain1,
+ gain1_value,
+ gain2,
+ gain2_value,
+ rf_port_select,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+
+ return gnuradio::get_initial_sptr(
+ new fmcomms2_source_f32c(rx1_en, rx2_en, block));
+ }
+
+ void set_params(unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* rf_port_select,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0)
+ {
+ fmcomms2_block->set_params(frequency,
+ samplerate,
+ bandwidth,
+ quadrature,
+ rfdc,
+ bbdc,
+ gain1,
+ gain1_value,
+ gain2,
+ gain2_value,
+ rf_port_select,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+ }
+
+private:
+ fmcomms2_source::sptr fmcomms2_block;
+
+protected:
+ explicit fmcomms2_source_f32c(bool rx1_en, bool rx2_en, fmcomms2_source::sptr block);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_FMCOMMS2_SOURCE_H */
diff --git a/gr-iio/include/gnuradio/iio/fmcomms5_sink.h b/gr-iio/include/gnuradio/iio/fmcomms5_sink.h
new file mode 100644
index 0000000000..93905a5571
--- /dev/null
+++ b/gr-iio/include/gnuradio/iio/fmcomms5_sink.h
@@ -0,0 +1,278 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2015 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+
+#ifndef INCLUDED_IIO_FMCOMMS5_SINK_H
+#define INCLUDED_IIO_FMCOMMS5_SINK_H
+
+#include <gnuradio/hier_block2.h>
+#include <gnuradio/iio/api.h>
+#include <gnuradio/sync_block.h>
+
+#include "device_sink.h"
+
+namespace gr {
+namespace iio {
+
+/*!
+ * \brief Device specific sink for FMComms5 evaluation card
+ * \ingroup iio
+ *
+ * \details
+ * This block is a sink specifically designed for FMComms5 evaluation
+ * card. The FMComms5 is a dual AD9361 FMC card which enables 4x4
+ * applications.
+ */
+class IIO_API fmcomms5_sink : virtual public gr::sync_block
+{
+public:
+ typedef std::shared_ptr<fmcomms5_sink> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::fmcomms5_sink.
+ *
+ * \param uri String of the context uri
+ * \param frequency1 Long long of LO frequency in Hz of chip A
+ * \param frequency2 Long long of LO frequency in Hz of chip B
+ * \param samplerate Long of sample rate in samples per second
+ * \param bandwidth Long of bandwidth of front-end analog filter in
+ * in Hz
+ * \param ch1_en Boolean enable channel 1
+ * \param ch2_en Boolean enable channel 2
+ * \param ch3_en Boolean enable channel 3
+ * \param ch4_en Boolean enable channel 4
+ * \param ch5_en Boolean enable channel 5
+ * \param ch6_en Boolean enable channel 6
+ * \param ch7_en Boolean enable channel 7
+ * \param ch8_en Boolean enable channel 8
+ * \param buffer_size Long of number of samples in buffer to send to device
+ * \param cyclic Boolean when True sends first buffer_size number of samples
+ * to hardware which is repeated in the hardware itself. Future
+ * samples are ignored.
+ * \param rf_port_select String of name of port to use for TX output mux
+ * with options: 'A', 'B'
+ * \param attenuation1 Double of TX channel 1 attenuation in dB [0, 90]
+ * \param attenuation2 Double of TX channel 2 attenuation in dB [0, 90]
+ * \param attenuation3 Double of TX channel 3 attenuation in dB [0, 90]
+ * \param attenuation4 Double of TX channel 4 attenuation in dB [0, 90]
+ * \param filter_source String which selects filter configuration with
+ * options:
+ * - 'Off': Disable filter
+ * - 'Auto': Use auto-generated filters
+ * - 'File': Use provide filter filter in filter_filename input
+ * - 'Design': Create filter from Fpass, Fstop, samplerate, and
+ * bandwidth parameters
+ * \param filter_filename String of path to filter file
+ * \param Fpass Float of edge of passband frequency in Hz for designed FIR
+ * \param Fstop Float of edge of stopband frequency in Hz for designed FIR
+ */
+ static sptr make(const std::string& uri,
+ unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en,
+ unsigned long buffer_size,
+ bool cyclic,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ double attenuation3,
+ double attenuation4,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0);
+
+ static sptr make_from(struct iio_context* ctx,
+ unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en,
+ unsigned long buffer_size,
+ bool cyclic,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ double attenuation3,
+ double attenuation4,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0);
+
+ virtual void set_params(unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ double attenuation3,
+ double attenuation4,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop) = 0;
+};
+
+/*!
+ * \brief Device specific sink for FMComms5 evaluation card
+ * \ingroup iio
+ *
+ * \details
+ * This block is a sink specifically designed for FMComms5 evaluation
+ * card. The FMComms5 is a dual AD9361 FMC card which enables 4x4
+ * applications.
+ */
+class IIO_API fmcomms5_sink_f32c : virtual public gr::hier_block2
+{
+public:
+ typedef std::shared_ptr<fmcomms5_sink_f32c> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::fmcomms5_sink.
+ *
+ * \param uri String of the context uri
+ * \param frequency1 Long long of LO frequency in Hz of chip A
+ * \param frequency2 Long long of LO frequency in Hz of chip B
+ * \param samplerate Long of sample rate in samples per second
+ * \param bandwidth Long of bandwidth of front-end analog filter in
+ * in Hz
+ * \param tx1_en Boolean enable channel 1
+ * \param tx2_en Boolean enable channel 2
+ * \param tx3_en Boolean enable channel 3
+ * \param tx4_en Boolean enable channel 4
+ * \param buffer_size Long of number of samples in buffer to send to device
+ * \param cyclic Boolean when True sends first buffer_size number of samples
+ * to hardware which is repeated in the hardware itself. Future
+ * samples are ignored.
+ * \param rf_port_select String of name of port to use for TX output mux
+ * with options: 'A', 'B'
+ * \param attenuation1 Double of TX channel 1 attenuation in dB [0, 90]
+ * \param attenuation2 Double of TX channel 2 attenuation in dB [0, 90]
+ * \param attenuation3 Double of TX channel 3 attenuation in dB [0, 90]
+ * \param attenuation4 Double of TX channel 4 attenuation in dB [0, 90]
+ * \param filter_source String which selects filter configuration with
+ * options:
+ * - 'Off': Disable filter
+ * - 'Auto': Use auto-generated filters
+ * - 'File': Use provide filter filter in filter_filename input
+ * - 'Design': Create filter from Fpass, Fstop, samplerate, and
+ * bandwidth parameters
+ * \param filter_filename String of path to filter file
+ * \param Fpass Float of edge of passband frequency in Hz for designed FIR
+ * \param Fstop Float of edge of stopband frequency in Hz for designed FIR
+ */
+ static sptr make(const std::string& uri,
+ unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool tx1_en,
+ bool tx2_en,
+ bool tx3_en,
+ bool tx4_en,
+ unsigned long buffer_size,
+ bool cyclic,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ double attenuation3,
+ double attenuation4,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0)
+ {
+ fmcomms5_sink::sptr block = fmcomms5_sink::make(uri,
+ frequency1,
+ frequency2,
+ samplerate,
+ bandwidth,
+ tx1_en,
+ tx1_en,
+ tx2_en,
+ tx2_en,
+ tx3_en,
+ tx3_en,
+ tx4_en,
+ tx4_en,
+ buffer_size,
+ cyclic,
+ rf_port_select,
+ attenuation1,
+ attenuation2,
+ attenuation3,
+ attenuation4,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+
+ return gnuradio::get_initial_sptr(
+ new fmcomms5_sink_f32c(tx1_en, tx2_en, tx3_en, tx4_en, block));
+ }
+
+ void set_params(unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ double attenuation3,
+ double attenuation4,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+ {
+ fmcomms5_block->set_params(frequency1,
+ frequency2,
+ samplerate,
+ bandwidth,
+ rf_port_select,
+ attenuation1,
+ attenuation2,
+ attenuation3,
+ attenuation4,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+ }
+
+private:
+ fmcomms5_sink::sptr fmcomms5_block;
+
+protected:
+ explicit fmcomms5_sink_f32c(
+ bool tx1_en, bool tx2_en, bool tx3_en, bool tx4_en, fmcomms5_sink::sptr block);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_FMCOMMS5_SINK_H */
diff --git a/gr-iio/include/gnuradio/iio/fmcomms5_source.h b/gr-iio/include/gnuradio/iio/fmcomms5_source.h
new file mode 100644
index 0000000000..eea19e563c
--- /dev/null
+++ b/gr-iio/include/gnuradio/iio/fmcomms5_source.h
@@ -0,0 +1,387 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+
+#ifndef INCLUDED_IIO_FMCOMMS5_SOURCE_H
+#define INCLUDED_IIO_FMCOMMS5_SOURCE_H
+
+#include <gnuradio/hier_block2.h>
+#include <gnuradio/iio/api.h>
+#include <gnuradio/sync_block.h>
+
+#include "device_source.h"
+
+namespace gr {
+namespace iio {
+
+/*!
+ * \brief Device specific source for the FMComms5 evaluation card
+ * \ingroup iio
+ *
+ * \details
+ * This block is a source specifically designed for FMComms5 evaluation
+ * card. The FMComms5 is a dual AD9361 FMC card which enables 4x4
+ * applications.
+ */
+class IIO_API fmcomms5_source : virtual public gr::sync_block
+{
+public:
+ typedef std::shared_ptr<fmcomms5_source> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::device.
+ *
+ * \param uri String of the context uri
+ * \param frequency1 Long long of LO frequency in Hz of chip A
+ * \param frequency2 Long long of LO frequency in Hz of chip A
+ * \param samplerate Long of sample rate in samples per second
+ * \param bandwidth Long of bandwidth of front-end analog filter in
+ * in Hz
+ * \param ch1_en Boolean enable channel 1
+ * \param ch2_en Boolean enable channel 2
+ * \param ch3_en Boolean enable channel 3
+ * \param ch4_en Boolean enable channel 4
+ * \param ch5_en Boolean enable channel 5
+ * \param ch6_en Boolean enable channel 6
+ * \param ch7_en Boolean enable channel 7
+ * \param ch8_en Boolean enable channel 8
+ * \param quadrature Boolean enable RX quadrature tracking
+ * \param rfdc Boolean enable RX RF DC tracking
+ * \param bbdc Boolean enable RX Baseband DC tracking
+ * \param buffer_size Long of number of samples in buffer to send to device
+ * \param rf_port_select String of name of port to use for TX output mux
+ * with options:
+ * - 'A_BALANCED'
+ * - 'B_BALANCED'
+ * - 'C_BALANCED'
+ * - 'A_N'
+ * - 'A_P'
+ * - 'B_N'
+ * - 'B_P'
+ * - 'C_N'
+ * - 'C_P'
+ * - 'TX_MONITOR1'
+ * - 'TX_MONITOR2'
+ * - 'TX_MONITOR1_2'
+ * \param gain1 String of gain mode for channel 1 with options:
+ * - 'manual'
+ * - 'slow_attack'
+ * - 'fast_attack'
+ * - 'hybrid'
+ * \param gain1_value Double of RX channel 1 gain in dB [0, 76]
+ * \param gain2 String of gain mode for channel 2 with options:
+ * - 'manual'
+ * - 'slow_attack'
+ * - 'fast_attack'
+ * - 'hybrid'
+ * \param gain2_value Double of RX channel 2 gain in dB [0, 76]
+ * \param gain3 String of gain mode for channel 3 with options:
+ * - 'manual'
+ * - 'slow_attack'
+ * - 'fast_attack'
+ * - 'hybrid'
+ * \param gain3_value Double of RX channel 3 gain in dB [0, 76]
+ * \param gain4 String of gain mode for channel 4 with options:
+ * - 'manual'
+ * - 'slow_attack'
+ * - 'fast_attack'
+ * - 'hybrid'
+ * \param gain4_value Double of RX channel 4 gain in dB [0, 76]
+ * \param filter_source String which selects filter configuration with
+ * options:
+ * - 'Off': Disable filter
+ * - 'Auto': Use auto-generated filters
+ * - 'File': Use provide filter filter in filter_filename input
+ * - 'Design': Create filter from Fpass, Fstop, samplerate, and
+ * bandwidth parameters
+ * \param filter_filename String of path to filter file
+ * \param Fpass Float of edge of passband frequency in Hz for designed FIR
+ * \param Fstop Float of edge of stopband frequency in Hz for designed FIR
+ */
+ static sptr make(const std::string& uri,
+ unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* gain3,
+ double gain3_value,
+ const char* gain4,
+ double gain4_value,
+ const char* rf_port_select,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0);
+
+ static sptr make_from(struct iio_context* ctx,
+ unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* gain3,
+ double gain3_value,
+ const char* gain4,
+ double gain4_value,
+ const char* rf_port_select,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0);
+
+ virtual void set_params(unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* gain3,
+ double gain3_value,
+ const char* gain4,
+ double gain4_value,
+ const char* rf_port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop) = 0;
+};
+
+/*!
+ * \brief Device specific source for the FMComms5 evaluation card
+ * \ingroup iio
+ *
+ * \details
+ * This block is a source specifically designed for FMComms5 evaluation
+ * card. The FMComms5 is a dual AD9361 FMC card which enables 4x4
+ * applications.
+ */
+class IIO_API fmcomms5_source_f32c : virtual public gr::hier_block2
+{
+public:
+ typedef std::shared_ptr<fmcomms5_source_f32c> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::device.
+ *
+ * \param uri String of the context uri
+ * \param frequency1 Long long of LO frequency in Hz of chip A
+ * \param frequency2 Long long of LO frequency in Hz of chip A
+ * \param samplerate Long of sample rate in samples per second
+ * \param bandwidth Long of bandwidth of front-end analog filter in
+ * in Hz
+ * \param rx1_en Boolean enable channel 1
+ * \param rx2_en Boolean enable channel 2
+ * \param rx3_en Boolean enable channel 3
+ * \param rx4_en Boolean enable channel 4
+ * \param quadrature Boolean enable RX quadrature tracking
+ * \param rfdc Boolean enable RX RF DC tracking
+ * \param bbdc Boolean enable RX Baseband DC tracking
+ * \param buffer_size Long of number of samples in buffer to send to device
+ * \param rf_port_select String of name of port to use for TX output mux
+ * with options:
+ * - 'A_BALANCED'
+ * - 'B_BALANCED'
+ * - 'C_BALANCED'
+ * - 'A_N'
+ * - 'A_P'
+ * - 'B_N'
+ * - 'B_P'
+ * - 'C_N'
+ * - 'C_P'
+ * - 'TX_MONITOR1'
+ * - 'TX_MONITOR2'
+ * - 'TX_MONITOR1_2'
+ * \param gain1 String of gain mode for channel 1 with options:
+ * - 'manual'
+ * - 'slow_attack'
+ * - 'fast_attack'
+ * - 'hybrid'
+ * \param gain1_value Double of RX channel 1 gain in dB [0, 76]
+ * \param gain2 String of gain mode for channel 2 with options:
+ * - 'manual'
+ * - 'slow_attack'
+ * - 'fast_attack'
+ * - 'hybrid'
+ * \param gain2_value Double of RX channel 2 gain in dB [0, 76]
+ * \param gain3 String of gain mode for channel 3 with options:
+ * - 'manual'
+ * - 'slow_attack'
+ * - 'fast_attack'
+ * - 'hybrid'
+ * \param gain3_value Double of RX channel 3 gain in dB [0, 76]
+ * \param gain4 String of gain mode for channel 4 with options:
+ * - 'manual'
+ * - 'slow_attack'
+ * - 'fast_attack'
+ * - 'hybrid'
+ * \param gain4_value Double of RX channel 4 gain in dB [0, 76]
+ * \param filter_source String which selects filter configuration with
+ * options:
+ * - 'Off': Disable filter
+ * - 'Auto': Use auto-generated filters
+ * - 'File': Use provide filter filter in filter_filename input
+ * - 'Design': Create filter from Fpass, Fstop, samplerate, and
+ * bandwidth parameters
+ * \param filter_filename String of path to filter file
+ * \param Fpass Float of edge of passband frequency in Hz for designed FIR
+ * \param Fstop Float of edge of stopband frequency in Hz for designed FIR
+ */
+ static sptr make(const std::string& uri,
+ unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool rx1_en,
+ bool rx2_en,
+ bool rx3_en,
+ bool rx4_en,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* gain3,
+ double gain3_value,
+ const char* gain4,
+ double gain4_value,
+ const char* rf_port_select,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0)
+ {
+ fmcomms5_source::sptr block = fmcomms5_source::make(uri,
+ frequency1,
+ frequency2,
+ samplerate,
+ bandwidth,
+ rx1_en,
+ rx1_en,
+ rx2_en,
+ rx2_en,
+ rx3_en,
+ rx3_en,
+ rx4_en,
+ rx4_en,
+ buffer_size,
+ quadrature,
+ rfdc,
+ bbdc,
+ gain1,
+ gain1_value,
+ gain2,
+ gain2_value,
+ gain3,
+ gain3_value,
+ gain4,
+ gain4_value,
+ rf_port_select,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+
+ return gnuradio::get_initial_sptr(
+ new fmcomms5_source_f32c(rx1_en, rx2_en, rx3_en, rx4_en, block));
+ }
+
+ void set_params(unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* gain3,
+ double gain3_value,
+ const char* gain4,
+ double gain4_value,
+ const char* rf_port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+ {
+ fmcomms5_block->set_params(frequency1,
+ frequency2,
+ samplerate,
+ bandwidth,
+ quadrature,
+ rfdc,
+ bbdc,
+ gain1,
+ gain1_value,
+ gain2,
+ gain2_value,
+ gain3,
+ gain3_value,
+ gain4,
+ gain4_value,
+ rf_port_select,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+ }
+
+private:
+ fmcomms5_source::sptr fmcomms5_block;
+
+protected:
+ explicit fmcomms5_source_f32c(
+ bool rx1_en, bool rx2_en, bool rx3_en, bool rx4_en, fmcomms5_source::sptr block);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_FMCOMMS5_SOURCE_H */
diff --git a/gr-iio/include/gnuradio/iio/pluto_sink.h b/gr-iio/include/gnuradio/iio/pluto_sink.h
new file mode 100644
index 0000000000..a0f48295dc
--- /dev/null
+++ b/gr-iio/include/gnuradio/iio/pluto_sink.h
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2017 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+
+#ifndef INCLUDED_IIO_PLUTO_SINK_H
+#define INCLUDED_IIO_PLUTO_SINK_H
+
+#include <gnuradio/hier_block2.h>
+#include <gnuradio/iio/api.h>
+
+namespace gr {
+namespace iio {
+/*!
+ * \brief Sink block for the PlutoSDR
+ * \ingroup iio
+ *
+ */
+class IIO_API pluto_sink : virtual public gr::hier_block2
+{
+public:
+ typedef std::shared_ptr<pluto_sink> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::fmcomms2_sink.
+ *
+ * \param uri String of the context uri
+ * \param frequency Long long of LO frequency in Hz
+ * \param samplerate Long of sample rate in samples per second
+ * \param bandwidth Long of bandwidth of front-end analog filter in
+ * in Hz
+ * \param buffer_size Long of number of samples in buffer to send to device
+ * \param cyclic Boolean when True sends first buffer_size number of samples
+ * to hardware which is repeated in the hardware itself. Future
+ * samples are ignored.
+ * \param attenuation Double of TX channel attenuation in dB [0, 90]
+ * \param filter_source String which selects filter configuration with
+ * options:
+ * - 'Off': Disable filter
+ * - 'Auto': Use auto-generated filters
+ * - 'File': Use provide filter filter in filter_filename input
+ * - 'Design': Create filter from Fpass, Fstop, samplerate, and
+ * bandwidth parameters
+ * \param filter_filename String of path to filter file
+ * \param Fpass Float of edge of passband frequency in Hz for designed FIR
+ * \param Fstop Float of edge of stopband frequency in Hz for designed FIR
+ */
+ static sptr make(const std::string& uri,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ unsigned long buffer_size,
+ bool cyclic,
+ double attenuation,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0);
+
+ virtual void set_params(unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ double attenuation,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0) = 0;
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_PLUTO_SINK_H */
diff --git a/gr-iio/include/gnuradio/iio/pluto_source.h b/gr-iio/include/gnuradio/iio/pluto_source.h
new file mode 100644
index 0000000000..e828c99294
--- /dev/null
+++ b/gr-iio/include/gnuradio/iio/pluto_source.h
@@ -0,0 +1,91 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2017 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+
+#ifndef INCLUDED_IIO_PLUTO_SOURCE_H
+#define INCLUDED_IIO_PLUTO_SOURCE_H
+
+#include <gnuradio/hier_block2.h>
+#include <gnuradio/iio/api.h>
+
+namespace gr {
+namespace iio {
+/*!
+ * \brief Source block for the PlutoSDR
+ * \ingroup iio
+ *
+ */
+class IIO_API pluto_source : virtual public gr::hier_block2
+{
+public:
+ typedef std::shared_ptr<pluto_source> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of iio::fmcomms2_source.
+ *
+ * \param uri String of the context uri
+ * \param frequency Long long of LO frequency in Hz
+ * \param samplerate Long of sample rate in samples per second
+ * \param bandwidth Long of bandwidth of front-end analog filter in
+ * in Hz
+ * \param quadrature Boolean enable RX quadrature tracking
+ * \param rfdc Boolean enable RX RF DC tracking
+ * \param bbdc Boolean enable RX Baseband DC tracking
+ * \param buffer_size Long of number of samples in buffer to send to device
+ * \param gain String of gain mode with options:
+ * - 'manual'
+ * - 'slow_attack'
+ * - 'fast_attack'
+ * - 'hybrid'
+ * \param gain_value Double of RX channel in dB [0, 76]
+ * \param filter_source String which selects filter configuration with
+ * options:
+ * - 'Off': Disable filter
+ * - 'Auto': Use auto-generated filters
+ * - 'File': Use provide filter filter in filter_filename input
+ * - 'Design': Create filter from Fpass, Fstop, samplerate, and
+ * bandwidth parameters
+ * \param filter_filename String of path to filter file
+ * \param Fpass Float of edge of passband frequency in Hz for designed FIR
+ * \param Fstop Float of edge of stopband frequency in Hz for designed FIR
+ */
+ static sptr make(const std::string& uri,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain,
+ double gain_value,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0);
+
+ // virtual void update_sample_rate(unsigned long samplerate) = 0;
+
+ virtual void set_params(unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain,
+ double gain_value,
+ const char* filter_source = "",
+ const char* filter_filename = "",
+ float Fpass = 0.0,
+ float Fstop = 0.0) = 0;
+};
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_PLUTO_SOURCE_H */
diff --git a/gr-iio/lib/CMakeLists.txt b/gr-iio/lib/CMakeLists.txt
new file mode 100644
index 0000000000..b5ddc19955
--- /dev/null
+++ b/gr-iio/lib/CMakeLists.txt
@@ -0,0 +1,63 @@
+# Copyright 2021 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+########################################################################
+# Setup library
+########################################################################
+add_library(gnuradio-iio
+ attr_sink_impl.cc
+ attr_source_impl.cc
+ attr_updater_impl.cc
+ dds_control.cc
+ device_sink_impl.cc
+ device_source_impl.cc
+)
+
+target_include_directories(gnuradio-iio
+ PUBLIC
+ $<INSTALL_INTERFACE:include>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
+ )
+
+target_link_libraries(gnuradio-iio PUBLIC
+ gnuradio-runtime
+ ${LIBIIO_LIBRARIES}
+ ${GR_VOLK_LIB}
+ PRIVATE
+ gnuradio-blocks
+)
+
+if(LIBAD9361_FOUND)
+ target_sources(gnuradio-iio PRIVATE
+ fmcomms2_sink_impl.cc
+ fmcomms2_source_impl.cc
+ fmcomms5_sink_impl.cc
+ fmcomms5_source_impl.cc
+ pluto_sink_impl.cc
+ pluto_source_impl.cc
+ )
+ target_include_directories(gnuradio-iio PUBLIC ${LIBAD9361_INCLUDE_DIRS})
+ target_link_libraries(gnuradio-iio PUBLIC ${LIBAD9361_LIBRARIES})
+endif(LIBAD9361_FOUND)
+
+#Add Windows DLL resource file if using MSVC
+if(MSVC)
+ include(${CMAKE_SOURCE_DIR}/cmake/Modules/GrVersion.cmake)
+
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-iio.rc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-iio.rc
+ @ONLY)
+
+ target_sources(gnuradio-iio PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-iio.rc
+ )
+endif(MSVC)
+
+if(BUILD_SHARED_LIBS)
+ GR_LIBRARY_FOO(gnuradio-iio IIO)
+endif()
diff --git a/gr-iio/lib/attr_sink_impl.cc b/gr-iio/lib/attr_sink_impl.cc
new file mode 100644
index 0000000000..6259e76064
--- /dev/null
+++ b/gr-iio/lib/attr_sink_impl.cc
@@ -0,0 +1,153 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2018 Analog Devices Inc.
+ * Author: Travis Collins <travis.collins@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "attr_sink_impl.h"
+#include <gnuradio/io_signature.h>
+#include <boost/lexical_cast.hpp>
+#include <cstdio>
+#include <iostream>
+
+namespace gr {
+namespace iio {
+
+attr_sink::sptr attr_sink::make(const std::string& uri,
+ const std::string& device,
+ const std::string& channel,
+ int type,
+ bool output,
+ bool required_enable)
+{
+ return gnuradio::get_initial_sptr(
+ new attr_sink_impl(uri, device, channel, type, output, required_enable));
+}
+
+/*
+ * The private constructor
+ */
+attr_sink_impl::attr_sink_impl(const std::string& uri,
+ const std::string& device,
+ const std::string& channel,
+ int type,
+ bool output,
+ bool required_enable)
+ : gr::block(
+ "attr_sink", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)),
+ device(device),
+ channel(channel),
+ uri(uri),
+ type(type),
+ output(output),
+ required_enable(required_enable)
+{
+
+ ctx = device_source_impl::get_context(uri);
+ if (!ctx)
+ throw std::runtime_error("Unable to create context");
+
+ dev = iio_context_find_device(ctx, device.c_str());
+ if (!dev) {
+ iio_context_destroy(ctx);
+ throw std::runtime_error("Device not found");
+ }
+
+ if (type == 0) {
+ chan = iio_device_find_channel(dev, channel.c_str(), output);
+ if (!chan) {
+ iio_context_destroy(ctx);
+ throw std::runtime_error("Channel not found");
+ }
+ }
+
+ // Required for MathWorks generated IP
+ if ((type == 4) && required_enable) {
+ // int ret = iio_device_debug_attr_write(dev, "direct_reg_access", "enabled");
+ int ret = iio_device_attr_write(dev, "reg_access", "enabled");
+
+ if (ret < 0) {
+ char error[1024];
+ sprintf(error,
+ "Failed to enabled register for device: %s [%d]",
+ device.c_str(),
+ ret);
+ throw std::runtime_error(error);
+ }
+ }
+
+ message_port_register_in(pmt::mp("attr"));
+ set_msg_handler(pmt::mp("attr"),
+ [this](pmt::pmt_t pdu) { this->write_attribute(pdu); });
+}
+
+/*
+ * Our virtual destructor.
+ */
+attr_sink_impl::~attr_sink_impl() {}
+
+void attr_sink_impl::write_attribute(pmt::pmt_t pdu)
+{
+ int ret = 0;
+ uint16_t k;
+ std::string value, attribute;
+ pmt::pmt_t keys;
+
+ if (!is_dict(pdu))
+ throw std::runtime_error("Message not a dictionary!\n");
+
+ keys = pmt::dict_keys(pdu);
+
+ for (k = 0; k < pmt::length(keys); k++) {
+
+ attribute = pmt::symbol_to_string(pmt::nth(k, keys));
+ value =
+ pmt::symbol_to_string(pmt::dict_ref(pdu, pmt::nth(k, keys), pmt::PMT_NIL));
+
+ switch (type) {
+ case 0:
+ ret = iio_channel_attr_write(chan, attribute.c_str(), value.c_str());
+ break;
+ case 1:
+ ret = iio_device_attr_write(dev, attribute.c_str(), value.c_str());
+ break;
+ case 2:
+ ret = iio_device_buffer_attr_write(dev, attribute.c_str(), value.c_str());
+ break;
+ case 3:
+ ret = iio_device_debug_attr_write(dev, attribute.c_str(), value.c_str());
+ break;
+ default: // case 4:
+ try {
+ uint32_t address = boost::lexical_cast<uint32_t>(attribute);
+ uint32_t value32 = boost::lexical_cast<uint32_t>(value);
+ ret = iio_device_reg_write(dev, address, value32);
+ } catch (const boost::bad_lexical_cast& e) {
+ std::cerr << e.what() << '\n';
+ }
+ break;
+ }
+
+ if (ret < 0) {
+ char error[1024];
+ sprintf(error,
+ "Attribute write '%s' failed to %s:%s:%s\n",
+ value.c_str(),
+ device.c_str(),
+ channel.c_str(),
+ attribute.c_str());
+ throw std::runtime_error(error);
+ }
+ }
+}
+
+
+} /* namespace iio */
+} /* namespace gr */
diff --git a/gr-iio/lib/attr_sink_impl.h b/gr-iio/lib/attr_sink_impl.h
new file mode 100644
index 0000000000..97d0df858c
--- /dev/null
+++ b/gr-iio/lib/attr_sink_impl.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2018 Analog Devices Inc.
+ * Author: Travis Collins <travis.collins@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_IIO_ATTR_SINK_IMPL_H
+#define INCLUDED_IIO_ATTR_SINK_IMPL_H
+
+#include <gnuradio/iio/attr_sink.h>
+#include <iio.h>
+#include <pmt/pmt.h>
+
+#include "device_source_impl.h"
+
+namespace gr {
+namespace iio {
+
+class attr_sink_impl : public attr_sink
+{
+private:
+ std::string device;
+ std::string channel;
+ std::string uri;
+ int type;
+ bool output;
+ bool required_enable;
+
+protected:
+ struct iio_context* ctx;
+ struct iio_device* dev;
+ struct iio_channel* chan;
+
+public:
+ attr_sink_impl(const std::string& uri,
+ const std::string& device,
+ const std::string& channel,
+ int type,
+ bool output,
+ bool required_enable);
+ ~attr_sink_impl();
+
+ void write_attribute(pmt::pmt_t pdu);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_ATTR_SINK_IMPL_H */
diff --git a/gr-iio/lib/attr_source_impl.cc b/gr-iio/lib/attr_source_impl.cc
new file mode 100644
index 0000000000..86ff59417c
--- /dev/null
+++ b/gr-iio/lib/attr_source_impl.cc
@@ -0,0 +1,286 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2018 Analog Devices Inc.
+ * Author: Travis Collins <travis.collins@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "attr_source_impl.h"
+#include <gnuradio/io_signature.h>
+#include <boost/lexical_cast.hpp>
+#include <boost/thread/thread.hpp>
+#include <chrono>
+#include <thread>
+#include <vector>
+
+
+namespace gr {
+namespace iio {
+
+attr_source::sptr attr_source::make(const std::string& uri,
+ const std::string& device,
+ const std::string& channel,
+ const std::string& attribute,
+ int update_interval_ms,
+ int samples_per_update,
+ int data_type,
+ int attr_type,
+ bool output,
+ uint32_t address,
+ bool required_enable)
+{
+ return gnuradio::get_initial_sptr(new attr_source_impl(uri,
+ device,
+ channel,
+ attribute,
+ update_interval_ms,
+ samples_per_update,
+ data_type,
+ attr_type,
+ output,
+ address,
+ required_enable));
+}
+
+size_t attr_source_impl::type_sizeof(int data_type, int attr_type)
+{
+ size_t dsize = 0;
+ if (attr_type == 3)
+ dsize = sizeof(int);
+ else {
+ switch (data_type) {
+ case 0:
+ dsize = sizeof(double);
+ break;
+ case 1:
+ dsize = sizeof(float);
+ break;
+ case 2:
+ dsize = sizeof(long long);
+ break;
+ case 3:
+ dsize = sizeof(int);
+ break;
+ case 4:
+ dsize = sizeof(uint8_t);
+ break;
+ }
+ }
+ return dsize;
+}
+
+/*
+ * The private constructor
+ */
+attr_source_impl::attr_source_impl(const std::string& uri,
+ const std::string& device,
+ const std::string& channel,
+ const std::string& attribute,
+ int update_interval_ms,
+ int samples_per_update,
+ int data_type,
+ int attr_type,
+ bool output,
+ uint32_t address,
+ bool required_enable)
+ : gr::sync_block("attr_source",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(1, -1, type_sizeof(data_type, attr_type))),
+ device(device),
+ channel(channel),
+ uri(uri),
+ attribute(attribute),
+ update_interval_ms(update_interval_ms),
+ samples_per_update(samples_per_update),
+ attr_type(attr_type),
+ data_type(data_type),
+ output(output),
+ address(address),
+ required_enable(required_enable)
+{
+ ctx = device_source_impl::get_context(uri);
+ if (!ctx)
+ throw std::runtime_error("Unable to create context");
+
+ dev = iio_context_find_device(ctx, device.c_str());
+ if (!dev) {
+ iio_context_destroy(ctx);
+ throw std::runtime_error("Device not found");
+ }
+ // Channel only needed for channel attributes
+ if (attr_type == 0) {
+ chan = iio_device_find_channel(dev, channel.c_str(), output);
+ if (!chan) {
+ iio_context_destroy(ctx);
+ throw std::runtime_error("Channel not found");
+ }
+ }
+
+ // Required for MathWorks generated IP
+ if ((attr_type == 3) && required_enable) {
+ int ret = iio_device_attr_write(dev, "reg_access", "enabled");
+
+ if (ret < 0) {
+ char error[1024];
+ sprintf(error,
+ "Failed to enabled register for device: %s [%d]",
+ device.c_str(),
+ ret);
+ throw std::runtime_error(error);
+ }
+ }
+
+ set_output_multiple(samples_per_update);
+}
+
+/*
+ * Our virtual destructor.
+ */
+attr_source_impl::~attr_source_impl() {}
+
+void attr_source_impl::check(int ret)
+{
+ if (ret < 0)
+ std::cerr << "Reading parameter failed: " << ret << std::endl;
+}
+
+void attr_source_impl::get_register_data(uint32_t address, int* value)
+{
+ uint32_t u32value;
+ ret = iio_device_reg_read(dev, address, &u32value);
+ attr_source_impl::check(ret);
+ *value = boost::lexical_cast<int>(u32value);
+}
+
+void attr_source_impl::get_attribute_data(const std::string& attribute, double* value)
+{
+ switch (attr_type) {
+ case 0:
+ ret = iio_channel_attr_read_double(chan, attribute.c_str(), value);
+ break;
+ case 1:
+ ret = iio_device_attr_read_double(dev, attribute.c_str(), value);
+ break;
+ default:
+ ret = iio_device_debug_attr_read_double(dev, attribute.c_str(), value);
+ break;
+ }
+ attr_source_impl::check(ret);
+}
+
+void attr_source_impl::get_attribute_data(const std::string& attribute, float* value)
+{
+ double dvalue;
+ switch (attr_type) {
+ case 0:
+ ret = iio_channel_attr_read_double(chan, attribute.c_str(), &dvalue);
+ break;
+ case 1:
+ ret = iio_device_attr_read_double(dev, attribute.c_str(), &dvalue);
+ break;
+ default:
+ ret = iio_device_debug_attr_read_double(dev, attribute.c_str(), &dvalue);
+ break;
+ }
+ attr_source_impl::check(ret);
+ *value = boost::lexical_cast<float>(dvalue);
+}
+
+void attr_source_impl::get_attribute_data(const std::string& attribute, long long* value)
+{
+ switch (attr_type) {
+ case 0:
+ ret = iio_channel_attr_read_longlong(chan, attribute.c_str(), value);
+ break;
+ case 1:
+ ret = iio_device_attr_read_longlong(dev, attribute.c_str(), value);
+ break;
+ default:
+ ret = iio_device_debug_attr_read_longlong(dev, attribute.c_str(), value);
+ break;
+ }
+ attr_source_impl::check(ret);
+}
+
+void attr_source_impl::get_attribute_data(const std::string& attribute, int* value)
+{
+ long long llvalue;
+ switch (attr_type) {
+ case 0:
+ ret = iio_channel_attr_read_longlong(chan, attribute.c_str(), &llvalue);
+ break;
+ case 1:
+ ret = iio_device_attr_read_longlong(dev, attribute.c_str(), &llvalue);
+ break;
+ default:
+ ret = iio_device_debug_attr_read_longlong(dev, attribute.c_str(), &llvalue);
+ break;
+ }
+ attr_source_impl::check(ret);
+ *value = boost::lexical_cast<int>(llvalue);
+}
+
+void attr_source_impl::get_attribute_data(const std::string& attribute, uint8_t* value)
+{
+ bool bvalue;
+ switch (attr_type) {
+ case 0:
+ ret = iio_channel_attr_read_bool(chan, attribute.c_str(), &bvalue);
+ break;
+ case 1:
+ ret = iio_device_attr_read_bool(dev, attribute.c_str(), &bvalue);
+ break;
+ default:
+ ret = iio_device_debug_attr_read_bool(dev, attribute.c_str(), &bvalue);
+ break;
+ }
+ attr_source_impl::check(ret);
+ *value = boost::lexical_cast<uint8_t>(bvalue);
+}
+
+int attr_source_impl::work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ int sample;
+ void* out;
+
+ out = output_items[0];
+
+ for (sample = 0; sample < samples_per_update; sample++) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(update_interval_ms));
+ if (attr_type == 3)
+ get_register_data(address, (((int*)out) + sample));
+ else {
+ switch (data_type) {
+ case 0:
+ get_attribute_data(attribute, ((double*)out + sample));
+ break;
+ case 1:
+ get_attribute_data(attribute, ((float*)out + sample));
+ break;
+ case 2:
+ get_attribute_data(attribute, ((long long*)out + sample));
+ break;
+ case 3:
+ get_attribute_data(attribute, ((int*)out + sample));
+ break;
+ case 4:
+ get_attribute_data(attribute, ((uint8_t*)out + sample));
+ break;
+ }
+ }
+ }
+
+ // Tell runtime system how many output items we produced.
+ return samples_per_update;
+}
+
+} /* namespace iio */
+} /* namespace gr */
diff --git a/gr-iio/lib/attr_source_impl.h b/gr-iio/lib/attr_source_impl.h
new file mode 100644
index 0000000000..f29e3b81ac
--- /dev/null
+++ b/gr-iio/lib/attr_source_impl.h
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2018 Analog Devices Inc.
+ * Author: Travis Collins <travis.collins@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_IIO_ATTR_SOURCE_IMPL_H
+#define INCLUDED_IIO_ATTR_SOURCE_IMPL_H
+
+#include <gnuradio/iio/attr_source.h>
+#include <vector>
+
+#include "device_source_impl.h"
+
+namespace gr {
+namespace iio {
+
+class attr_source_impl : public attr_source
+{
+private:
+ std::string device;
+ std::string channel;
+ std::string uri;
+ std::string attribute;
+ int update_interval_ms;
+ int samples_per_update;
+ int attr_type;
+ int data_type;
+ bool output;
+ int ret;
+ uint32_t address;
+ bool required_enable;
+
+protected:
+ struct iio_context* ctx;
+ struct iio_device* dev;
+ struct iio_channel* chan;
+
+public:
+ attr_source_impl(const std::string& uri,
+ const std::string& device,
+ const std::string& channel,
+ const std::string& attribute,
+ int update_interval_ms,
+ int samples_per_update,
+ int data_type,
+ int attr_type,
+ bool output,
+ uint32_t address,
+ bool required_enable);
+ ~attr_source_impl();
+
+ // Where all the action really happens
+ int work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+
+ size_t type_sizeof(int data_type, int attr_type);
+ void get_attribute_data(const std::string& attribute, double* value);
+ void get_attribute_data(const std::string& attribute, float* value);
+ void get_attribute_data(const std::string& attribute, long long* value);
+ void get_attribute_data(const std::string& attribute, int* value);
+ void get_attribute_data(const std::string& attribute, uint8_t* value);
+ void get_register_data(uint32_t address, int* value);
+ void check(int ret);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_ATTR_SOURCE_IMPL_H */
diff --git a/gr-iio/lib/attr_updater_impl.cc b/gr-iio/lib/attr_updater_impl.cc
new file mode 100644
index 0000000000..4e6e04c267
--- /dev/null
+++ b/gr-iio/lib/attr_updater_impl.cc
@@ -0,0 +1,120 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2018 Analog Devices Inc.
+ * Author: Travis Collins <travis.collins@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "attr_updater_impl.h"
+#include <gnuradio/io_signature.h>
+#include <chrono>
+#include <thread>
+
+namespace gr {
+namespace iio {
+
+attr_updater::sptr attr_updater::make(const std::string attribute,
+ const std::string value,
+ unsigned int interval_ms)
+{
+ return gnuradio::get_initial_sptr(
+ new attr_updater_impl(attribute, value, interval_ms));
+}
+
+/*
+ * The private constructor
+ */
+attr_updater_impl::attr_updater_impl(const std::string attribute,
+ const std::string value,
+ unsigned int interval_ms)
+ : gr::block("attr_updater",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(0, 0, 0)),
+ d_attribute(attribute),
+ d_value(value),
+ d_port(pmt::mp("out")),
+ d_interval_ms(interval_ms),
+ d_finished(false)
+{
+ d_msg = pmt::make_dict();
+ pmt::pmt_t key = pmt::string_to_symbol(d_attribute);
+ pmt::pmt_t dvalue = pmt::string_to_symbol(value);
+ d_msg = pmt::dict_add(d_msg, key, dvalue);
+ message_port_register_out(d_port);
+}
+
+/*
+ * Our virtual destructor.
+ */
+attr_updater_impl::~attr_updater_impl() {}
+
+void attr_updater_impl::set_value(std::string value)
+{
+ // Check if message is different
+ if (d_value.compare(value) == 0)
+ return;
+ else
+ d_value = value;
+
+ // Build message
+ pmt::pmt_t msg = pmt::make_dict();
+ pmt::pmt_t key = pmt::string_to_symbol(d_attribute);
+ pmt::pmt_t dvalue = pmt::string_to_symbol(value);
+ msg = pmt::dict_add(msg, key, dvalue);
+ // Update
+ if (d_interval_ms == 0)
+ message_port_pub(d_port, msg);
+ else {
+ d_mtx.lock();
+ d_msg = msg;
+ d_mtx.unlock();
+ }
+}
+
+bool attr_updater_impl::start()
+{
+ if (d_interval_ms <= 0.0) {
+ message_port_pub(d_port, d_msg);
+ } else {
+ d_mtx.lock();
+ d_finished = false;
+ d_mtx.unlock();
+ d_thread = std::shared_ptr<gr::thread::thread>(
+ new gr::thread::thread(boost::bind(&attr_updater_impl::run, this)));
+ }
+ return block::start();
+}
+
+bool attr_updater_impl::stop()
+{
+ // Shut down the thread
+ d_finished = true;
+ d_thread->interrupt();
+ d_thread->join();
+
+ return block::stop();
+}
+
+
+void attr_updater_impl::run()
+{
+ while (!d_finished) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(d_interval_ms));
+ if (d_finished) {
+ return;
+ }
+ d_mtx.lock();
+ message_port_pub(d_port, d_msg);
+ d_mtx.unlock();
+ }
+}
+
+
+} /* namespace iio */
+} /* namespace gr */
diff --git a/gr-iio/lib/attr_updater_impl.h b/gr-iio/lib/attr_updater_impl.h
new file mode 100644
index 0000000000..120c15c8a5
--- /dev/null
+++ b/gr-iio/lib/attr_updater_impl.h
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2019 Analog Devices Inc.
+ * Author: Travis Collins <travis.collins@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_IIO_ATTR_UPDATER_IMPL_H
+#define INCLUDED_IIO_ATTR_UPDATER_IMPL_H
+
+#include <gnuradio/iio/attr_updater.h>
+
+#include <mutex>
+
+namespace gr {
+namespace iio {
+
+class attr_updater_impl : public attr_updater
+{
+private:
+ const std::string d_attribute;
+ std::string d_value;
+ const pmt::pmt_t d_port;
+ bool d_update_on_change;
+ unsigned int d_interval_ms;
+ bool d_finished;
+ bool d_updated;
+ pmt::pmt_t d_msg;
+ std::mutex d_mtx;
+ std::shared_ptr<gr::thread::thread> d_thread;
+
+ void run();
+
+public:
+ attr_updater_impl(const std::string attribute,
+ const std::string value,
+ unsigned int interval_ms);
+ ~attr_updater_impl();
+
+ void set_value(std::string value);
+ bool start();
+ bool stop();
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_ATTR_UPDATER_IMPL_H */
diff --git a/gr-iio/lib/dds_control.cc b/gr-iio/lib/dds_control.cc
new file mode 100644
index 0000000000..186aa8fc06
--- /dev/null
+++ b/gr-iio/lib/dds_control.cc
@@ -0,0 +1,155 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2019 Analog Devices Inc.
+ * Author: Travis Collins <travis.collins@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "dds_control.h"
+#include <gnuradio/io_signature.h>
+#include <cstdio>
+#include <iostream>
+
+namespace gr {
+namespace iio {
+
+dds_control::sptr dds_control::make(const std::string& uri,
+ std::vector<int> enabled,
+ std::vector<long> frequencies,
+ std::vector<float> phases,
+ std::vector<float> scales)
+{
+ return gnuradio::get_initial_sptr(
+ new dds_control_impl(uri, enabled, frequencies, phases, scales));
+}
+
+/*
+ * The private constructor
+ */
+dds_control_impl::dds_control_impl(const std::string& uri,
+ std::vector<int> enabled,
+ std::vector<long> frequencies,
+ std::vector<float> phases,
+ std::vector<float> scales)
+ : gr::block("dds_control",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(0, 0, 0)),
+ d_enabled(enabled),
+ d_frequencies(frequencies),
+ d_phases(phases),
+ d_scales(scales),
+ d_uri(uri)
+{
+ int k, chans;
+ unsigned int ku = 0, count = 0;
+ struct iio_channel* chan;
+
+ d_ctx = device_source_impl::get_context(uri);
+ if (!d_ctx)
+ throw std::runtime_error("Unable to create context");
+
+ int d = iio_context_get_devices_count(d_ctx);
+ struct iio_device* dev;
+ const char* name;
+ // Find dds device
+ for (k = 0; k < d; k++) {
+ dev = iio_context_get_device(d_ctx, k);
+ name = iio_device_get_name(dev);
+ std::string name_s(name);
+ if (name_s.find("dds-core") != std::string::npos) {
+ d_dev = dev;
+ break;
+ }
+ }
+ if (!d_dev) {
+ iio_context_destroy(d_ctx);
+ throw std::runtime_error("Device not found");
+ }
+ // Check that we have enough DDSs
+ chans = iio_device_get_channels_count(d_dev);
+ for (k = 0; k < chans; k++) {
+ chan = iio_device_get_channel(d_dev, k);
+ if (iio_channel_find_attr(chan, "raw") != NULL)
+ count++;
+ }
+ for (ku = 1; ku <= enabled.size(); ku++)
+ if ((count < ku * 4) && enabled[ku - 1] > 0)
+ throw std::runtime_error(
+ "Not enough DDSs available in hardware for configuration");
+
+ set_dds_confg(frequencies, phases, scales);
+}
+
+void dds_control_impl::set_dds_confg(std::vector<long> frequencies,
+ std::vector<float> phases,
+ std::vector<float> scales)
+{
+ int ret, chans, k, dds_indx = 0, enable_indx = 0, enable = 0;
+ unsigned int ku;
+ struct iio_channel* chan;
+
+ // Check vector sizes
+ if ((frequencies.size() != phases.size()) || (phases.size() != scales.size()))
+ throw std::runtime_error(
+ "Frequencies, Phases, and Scales must be all the same size");
+
+ for (ku = 0; ku < d_frequencies.size(); ku++) {
+ d_frequencies[ku] = frequencies[ku];
+ d_phases[ku] = phases[ku] * 1000;
+ d_scales[ku] = scales[ku];
+ }
+ // DDS raw settings must be all on or all off
+ for (ku = 0; ku < d_enabled.size(); ku++)
+ enable += d_enabled[ku];
+
+ // Enable/Disable DDSs
+ chans = iio_device_get_channels_count(d_dev);
+ for (k = 0; k < chans; k++) {
+
+ chan = iio_device_get_channel(d_dev, k);
+
+ if (iio_channel_find_attr(chan, "raw") != NULL) {
+
+ ret = iio_channel_attr_write_longlong(
+ chan, "frequency", d_frequencies[dds_indx]);
+ if (ret < 0)
+ std::cerr << "Unable to set DDS frequency: " << d_frequencies[dds_indx]
+ << std::endl;
+
+ ret = iio_channel_attr_write_longlong(chan, "phase", d_phases[dds_indx]);
+ if (ret < 0)
+ std::cerr << "Unable to set DDS phase: " << d_phases[dds_indx]
+ << std::endl;
+
+ if (d_enabled[enable_indx])
+ ret = iio_channel_attr_write_double(chan, "scale", d_scales[dds_indx]);
+ else
+ ret = iio_channel_attr_write_double(chan, "scale", 0);
+ if (ret < 0)
+ std::cerr << "Unable to set DDS scale: " << d_scales[dds_indx]
+ << std::endl;
+
+ ret = iio_channel_attr_write_longlong(chan, "raw", enable);
+ if (ret < 0)
+ std::cerr << "Unable to set DDS: " << ret << std::endl;
+
+ dds_indx++;
+ if ((dds_indx % 4) == 0)
+ enable_indx++;
+ }
+ }
+}
+
+/*
+ * Our virtual destructor.
+ */
+dds_control_impl::~dds_control_impl() {}
+
+} /* namespace iio */
+} /* namespace gr */
diff --git a/gr-iio/lib/dds_control.h b/gr-iio/lib/dds_control.h
new file mode 100644
index 0000000000..dba276aecd
--- /dev/null
+++ b/gr-iio/lib/dds_control.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2019 Analog Devices Inc.
+ * Author: Travis Collins <travis.collins@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_IIO_DDS_CONTROL_IMPL_H
+#define INCLUDED_IIO_DDS_CONTROL_IMPL_H
+
+#include <gnuradio/iio/dds_control.h>
+#include <iio.h>
+#include <pmt/pmt.h>
+
+#include "device_source_impl.h"
+
+namespace gr {
+namespace iio {
+
+class dds_control_impl : public dds_control
+{
+private:
+ std::vector<int> d_enabled;
+ std::vector<long> d_frequencies;
+ std::vector<float> d_phases;
+ std::vector<float> d_scales;
+ std::string d_uri;
+
+protected:
+ struct iio_context* d_ctx;
+ struct iio_device* d_dev;
+
+public:
+ dds_control_impl(const std::string& uri,
+ std::vector<int> enabled,
+ std::vector<long> frequencies,
+ std::vector<float> phases,
+ std::vector<float> scales);
+ ~dds_control_impl();
+
+ void set_dds_confg(std::vector<long> frequencies,
+ std::vector<float> phases,
+ std::vector<float> scales);
+
+ // void write_attribute(pmt::pmt_t pdu);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_DDS_CONTROL_IMPL_H */
diff --git a/gr-iio/lib/device_sink_impl.cc b/gr-iio/lib/device_sink_impl.cc
new file mode 100644
index 0000000000..c015a7f2da
--- /dev/null
+++ b/gr-iio/lib/device_sink_impl.cc
@@ -0,0 +1,201 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "device_sink_impl.h"
+#include "device_source_impl.h"
+#include <gnuradio/io_signature.h>
+
+#include <cstdio>
+
+namespace gr {
+namespace iio {
+
+device_sink::sptr device_sink::make(const std::string& uri,
+ const std::string& device,
+ const std::vector<std::string>& channels,
+ const std::string& device_phy,
+ const std::vector<std::string>& params,
+ unsigned int buffer_size,
+ unsigned int interpolation,
+ bool cyclic)
+{
+ return gnuradio::get_initial_sptr(
+ new device_sink_impl(device_source_impl::get_context(uri),
+ true,
+ device,
+ channels,
+ device_phy,
+ params,
+ buffer_size,
+ interpolation,
+ cyclic));
+}
+
+device_sink::sptr device_sink::make_from(struct iio_context* ctx,
+ const std::string& device,
+ const std::vector<std::string>& channels,
+ const std::string& device_phy,
+ const std::vector<std::string>& params,
+ unsigned int buffer_size,
+ unsigned int interpolation,
+ bool cyclic)
+{
+ return gnuradio::get_initial_sptr(new device_sink_impl(ctx,
+ false,
+ device,
+ channels,
+ device_phy,
+ params,
+ buffer_size,
+ interpolation,
+ cyclic));
+}
+
+void device_sink_impl::set_params(const std::vector<std::string>& params)
+{
+ device_source_impl::set_params(this->phy, params);
+}
+
+/*
+ * The private constructor
+ */
+device_sink_impl::device_sink_impl(struct iio_context* ctx,
+ bool destroy_ctx,
+ const std::string& device,
+ const std::vector<std::string>& channels,
+ const std::string& device_phy,
+ const std::vector<std::string>& params,
+ unsigned int buffer_size,
+ unsigned int interpolation,
+ bool cyclic)
+ : gr::sync_block("device_sink",
+ gr::io_signature::make(1, -1, sizeof(short)),
+ gr::io_signature::make(0, 0, 0)),
+ ctx(ctx),
+ interpolation(interpolation),
+ buffer_size(buffer_size),
+ destroy_ctx(destroy_ctx)
+{
+ unsigned int nb_channels, i;
+
+ /* Set minimum input size */
+ set_output_multiple(buffer_size / (interpolation + 1));
+
+ if (!ctx)
+ throw std::runtime_error("Unable to create context");
+
+ dev = iio_context_find_device(ctx, device.c_str());
+ phy = iio_context_find_device(ctx, device_phy.c_str());
+ if (!dev || !phy) {
+ if (destroy_ctx)
+ iio_context_destroy(ctx);
+ throw std::runtime_error("Device not found");
+ }
+
+ /* First disable all channels */
+ nb_channels = iio_device_get_channels_count(dev);
+ for (i = 0; i < nb_channels; i++)
+ iio_channel_disable(iio_device_get_channel(dev, i));
+
+ if (channels.empty()) {
+ for (i = 0; i < nb_channels; i++) {
+ struct iio_channel* chn = iio_device_get_channel(dev, i);
+
+ iio_channel_enable(chn);
+ channel_list.push_back(chn);
+ }
+ } else {
+ for (std::vector<std::string>::const_iterator it = channels.begin();
+ it != channels.end();
+ ++it) {
+ struct iio_channel* chn = iio_device_find_channel(dev, it->c_str(), true);
+ if (!chn) {
+ if (destroy_ctx)
+ iio_context_destroy(ctx);
+ throw std::runtime_error("Channel not found");
+ }
+
+ iio_channel_enable(chn);
+ if (!iio_channel_is_enabled(chn))
+ throw std::runtime_error("Channel not enabled");
+ channel_list.push_back(chn);
+ }
+ }
+
+ set_params(params);
+
+ buf = iio_device_create_buffer(dev, buffer_size, cyclic);
+ if (!buf)
+ throw std::runtime_error("Unable to create buffer: " + boost::to_string(-errno));
+}
+
+/*
+ * Our virtual destructor.
+ */
+device_sink_impl::~device_sink_impl()
+{
+ iio_buffer_destroy(buf);
+ device_source_impl::remove_ctx_history(ctx, destroy_ctx);
+}
+
+void device_sink_impl::channel_write(const struct iio_channel* chn,
+ const void* src,
+ size_t len)
+{
+ uintptr_t dst_ptr, src_ptr = (uintptr_t)src, end = src_ptr + len;
+ unsigned int length = iio_channel_get_data_format(chn)->length / 8;
+ uintptr_t buf_end = (uintptr_t)iio_buffer_end(buf);
+ ptrdiff_t buf_step = iio_buffer_step(buf) * (interpolation + 1);
+
+ for (dst_ptr = (uintptr_t)iio_buffer_first(buf, chn);
+ dst_ptr < buf_end && src_ptr + length <= end;
+ dst_ptr += buf_step, src_ptr += length)
+ iio_channel_convert_inverse(chn, (void*)dst_ptr, (const void*)src_ptr);
+}
+
+int device_sink_impl::work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ int ret;
+
+ if (interpolation >= 1) {
+ ptrdiff_t len = (intptr_t)iio_buffer_end(buf) - (intptr_t)iio_buffer_start(buf);
+ memset(iio_buffer_start(buf), 0, len);
+ }
+
+ for (unsigned int i = 0; i < input_items.size(); i++)
+ channel_write(channel_list[i], input_items[i], noutput_items * sizeof(short));
+
+ ret = iio_buffer_push(buf);
+ if (ret < 0) {
+ char buf[256];
+ iio_strerror(-ret, buf, sizeof(buf));
+ std::string error(buf);
+
+ std::cerr << "Unable to push buffer: " << error << std::endl;
+ return -1; /* EOF */
+ }
+
+ consume_each(buffer_size / (interpolation + 1));
+ return 0;
+}
+
+void device_sink_impl::forecast(int noutput_items, gr_vector_int& ninput_items_required)
+{
+ for (unsigned int i = 0; i < ninput_items_required.size(); i++)
+ ninput_items_required[i] = noutput_items;
+}
+
+} /* namespace iio */
+} /* namespace gr */
diff --git a/gr-iio/lib/device_sink_impl.h b/gr-iio/lib/device_sink_impl.h
new file mode 100644
index 0000000000..cd270287df
--- /dev/null
+++ b/gr-iio/lib/device_sink_impl.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_IIO_DEVICE_SINK_IMPL_H
+#define INCLUDED_IIO_DEVICE_SINK_IMPL_H
+
+#include <string>
+#include <vector>
+
+#include <gnuradio/iio/device_sink.h>
+#include <iio.h>
+
+namespace gr {
+namespace iio {
+
+class device_sink_impl : public device_sink
+{
+private:
+ void channel_write(const struct iio_channel* chn, const void* src, size_t len);
+
+protected:
+ struct iio_context* ctx;
+ struct iio_device *dev, *phy;
+ struct iio_buffer* buf;
+ std::vector<struct iio_channel*> channel_list;
+ unsigned int interpolation;
+ unsigned int buffer_size;
+ bool destroy_ctx;
+
+public:
+ device_sink_impl(struct iio_context* ctx,
+ bool destroy_ctx,
+ const std::string& device,
+ const std::vector<std::string>& channels,
+ const std::string& device_phy,
+ const std::vector<std::string>& params,
+ unsigned int buffer_size = DEFAULT_BUFFER_SIZE,
+ unsigned int interpolation = 0,
+ bool cyclic = false);
+ ~device_sink_impl();
+
+ void set_params(const std::vector<std::string>& params);
+
+ // Where all the action really happens
+ int work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+
+ void forecast(int noutput_items, gr_vector_int& ninput_items_required);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_DEVICE_SINK_IMPL_H */
diff --git a/gr-iio/lib/device_source_impl.cc b/gr-iio/lib/device_source_impl.cc
new file mode 100644
index 0000000000..797de18d1f
--- /dev/null
+++ b/gr-iio/lib/device_source_impl.cc
@@ -0,0 +1,409 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "device_source_impl.h"
+#include <gnuradio/io_signature.h>
+#include <gnuradio/thread/thread.h>
+
+#include <cstdio>
+#include <fstream>
+#include <string>
+
+namespace gr {
+namespace iio {
+
+device_source::sptr device_source::make(const std::string& uri,
+ const std::string& device,
+ const std::vector<std::string>& channels,
+ const std::string& device_phy,
+ const std::vector<std::string>& params,
+ unsigned int buffer_size,
+ unsigned int decimation)
+{
+ return gnuradio::get_initial_sptr(
+ new device_source_impl(device_source_impl::get_context(uri),
+ true,
+ device,
+ channels,
+ device_phy,
+ params,
+ buffer_size,
+ decimation));
+}
+
+device_source::sptr device_source::make_from(struct iio_context* ctx,
+ const std::string& device,
+ const std::vector<std::string>& channels,
+ const std::string& device_phy,
+ const std::vector<std::string>& params,
+ unsigned int buffer_size,
+ unsigned int decimation)
+{
+ return gnuradio::get_initial_sptr(new device_source_impl(
+ ctx, false, device, channels, device_phy, params, buffer_size, decimation));
+}
+
+void device_source_impl::set_params(struct iio_device* phy,
+ const std::vector<std::string>& params)
+{
+ for (std::vector<std::string>::const_iterator it = params.begin(); it != params.end();
+ ++it) {
+ struct iio_channel* chn = NULL;
+ const char* attr = NULL;
+ size_t pos;
+ int ret;
+
+ pos = it->find('=');
+ if (pos == std::string::npos) {
+ std::cerr << "Misformed line: " << *it << std::endl;
+ continue;
+ }
+
+ std::string key = it->substr(0, pos);
+ std::string val = it->substr(pos + 1, std::string::npos);
+
+ ret = iio_device_identify_filename(phy, key.c_str(), &chn, &attr);
+ if (ret) {
+ std::cerr << "Parameter not recognized: " << key << std::endl;
+ continue;
+ }
+
+ if (chn)
+ ret = iio_channel_attr_write(chn, attr, val.c_str());
+ else if (iio_device_find_attr(phy, attr))
+ ret = iio_device_attr_write(phy, attr, val.c_str());
+ else
+ ret = iio_device_debug_attr_write(phy, attr, val.c_str());
+ if (ret < 0) {
+ std::cerr << "Unable to write attribute " << key << ": " << ret << std::endl;
+ }
+ }
+}
+
+void device_source_impl::set_params(const std::vector<std::string>& params)
+{
+ set_params(this->phy, params);
+}
+
+void device_source_impl::set_buffer_size(unsigned int _buffer_size)
+{
+ boost::unique_lock<boost::mutex> lock(iio_mutex);
+
+ if (buf && this->buffer_size != _buffer_size) {
+ iio_buffer_destroy(buf);
+
+ buf = iio_device_create_buffer(dev, _buffer_size, false);
+ if (!buf)
+ throw std::runtime_error("Unable to create buffer!\n");
+ }
+
+ this->buffer_size = _buffer_size;
+}
+
+void device_source_impl::set_timeout_ms(unsigned long _timeout)
+{
+ this->timeout = _timeout;
+}
+
+struct iio_context* device_source_impl::get_context(const std::string& uri)
+{
+ struct iio_context* ctx;
+
+ // Check if we have a context with the same URI open
+ if (!contexts.empty()) {
+ for (ctx_it it = contexts.begin(); it != contexts.end(); ++it) {
+ if (it->uri.compare(uri) == 0) {
+ it->count++;
+ return it->ctx;
+ }
+ }
+ }
+
+ if (uri.empty()) {
+ ctx = iio_create_default_context();
+ if (!ctx)
+ ctx = iio_create_network_context(NULL);
+ } else {
+ ctx = iio_create_context_from_uri(uri.c_str());
+
+ /* Stay compatible with old graphs, by accepting an
+ * IP/hostname instead of an URI */
+ if (!ctx)
+ ctx = iio_create_network_context(uri.c_str());
+ }
+ // Save context info for future checks
+ ctxInfo ci = { uri, ctx, 1 };
+ contexts.push_back(ci);
+
+ return ctx;
+}
+
+/*
+ * The private constructor
+ */
+device_source_impl::device_source_impl(struct iio_context* ctx,
+ bool destroy_ctx,
+ const std::string& device,
+ const std::vector<std::string>& channels,
+ const std::string& device_phy,
+ const std::vector<std::string>& params,
+ unsigned int buffer_size,
+ unsigned int decimation)
+ : gr::sync_block("device_source",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(1, -1, sizeof(short))),
+ port_id(pmt::mp("msg")),
+ timeout(100),
+ ctx(ctx),
+ buf(NULL),
+ buffer_size(buffer_size),
+ decimation(decimation),
+ destroy_ctx(destroy_ctx)
+{
+ unsigned int nb_channels, i;
+
+ if (!ctx)
+ throw std::runtime_error("Unable to create context");
+
+ dev = iio_context_find_device(ctx, device.c_str());
+ phy = iio_context_find_device(ctx, device_phy.c_str());
+ if (!dev || !phy) {
+ if (destroy_ctx)
+ iio_context_destroy(ctx);
+ throw std::runtime_error("Device not found");
+ }
+
+ /* First disable all channels */
+ nb_channels = iio_device_get_channels_count(dev);
+ for (i = 0; i < nb_channels; i++)
+ iio_channel_disable(iio_device_get_channel(dev, i));
+
+ if (channels.empty()) {
+ for (i = 0; i < nb_channels; i++) {
+ struct iio_channel* chn = iio_device_get_channel(dev, i);
+
+ iio_channel_enable(chn);
+ channel_list.push_back(chn);
+ }
+ } else {
+ for (std::vector<std::string>::const_iterator it = channels.begin();
+ it != channels.end();
+ ++it) {
+ struct iio_channel* chn = iio_device_find_channel(dev, it->c_str(), false);
+ if (!chn) {
+ if (destroy_ctx)
+ iio_context_destroy(ctx);
+ throw std::runtime_error("Channel not found");
+ }
+
+ iio_channel_enable(chn);
+ channel_list.push_back(chn);
+ }
+ }
+
+ set_params(params);
+ set_output_multiple(0x400);
+
+ message_port_register_out(port_id);
+}
+
+void device_source_impl::remove_ctx_history(struct iio_context* ctx_from_block,
+ bool destroy_ctx)
+{
+ boost::lock_guard<boost::mutex> lock(ctx_mutex);
+
+ for (ctx_it it = contexts.begin(); it != contexts.end(); ++it) {
+ if (it->ctx == ctx_from_block) {
+ if (it->count == 1) {
+ if (destroy_ctx)
+ iio_context_destroy(ctx_from_block);
+ it = contexts.erase(it);
+ return;
+ } else
+ it->count--;
+ }
+ }
+}
+
+
+/*
+ * Our virtual destructor.
+ */
+device_source_impl::~device_source_impl()
+{
+ // Make sure this is the last open block with a given context
+ // before removing the context
+ remove_ctx_history(ctx, destroy_ctx);
+}
+
+void device_source_impl::channel_read(const struct iio_channel* chn,
+ void* dst,
+ size_t len)
+{
+ uintptr_t src_ptr, dst_ptr = (uintptr_t)dst, end = dst_ptr + len;
+ unsigned int length = iio_channel_get_data_format(chn)->length / 8;
+ uintptr_t buf_end = (uintptr_t)iio_buffer_end(buf);
+ ptrdiff_t buf_step = iio_buffer_step(buf) * (decimation + 1);
+
+ for (src_ptr = (uintptr_t)iio_buffer_first(buf, chn) + byte_offset;
+ src_ptr < buf_end && dst_ptr + length <= end;
+ src_ptr += buf_step, dst_ptr += length)
+ iio_channel_convert(chn, (void*)dst_ptr, (const void*)src_ptr);
+}
+
+int device_source_impl::work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ ssize_t ret;
+
+ // Check if we've processed what we have first
+ if (!items_in_buffer) {
+ ret = iio_buffer_refill(buf);
+ if (ret < 0) {
+ /* -EBADF happens when the buffer is cancelled */
+ if (ret != -EBADF) {
+
+ char buf[256];
+ iio_strerror(-ret, buf, sizeof(buf));
+ std::string error(buf);
+
+ std::cerr << "Unable to refill buffer: " << error << std::endl;
+ }
+ return -1;
+ }
+
+ items_in_buffer = (unsigned long)ret / iio_buffer_step(buf);
+ if (!items_in_buffer)
+ return 0;
+
+ byte_offset = 0;
+ }
+
+ // Process samples
+ unsigned long items = std::min(items_in_buffer, (unsigned long)noutput_items);
+
+ for (unsigned int i = 0; i < output_items.size(); i++)
+ channel_read(channel_list[i], output_items[i], items * sizeof(short));
+
+ items_in_buffer -= items;
+ byte_offset += items * iio_buffer_step(buf);
+
+ return (int)items;
+}
+
+bool device_source_impl::start()
+{
+ items_in_buffer = 0;
+ byte_offset = 0;
+ thread_stopped = false;
+
+ buf = iio_device_create_buffer(dev, buffer_size, false);
+ if (!buf) {
+ throw std::runtime_error("Unable to create buffer!\n");
+ }
+
+ return !!buf;
+}
+
+bool device_source_impl::stop()
+{
+ thread_stopped = true;
+
+ if (buf)
+ iio_buffer_cancel(buf);
+
+ if (buf) {
+ iio_buffer_destroy(buf);
+ buf = NULL;
+ }
+
+ return true;
+}
+
+bool device_source_impl::load_fir_filter(std::string& filter, struct iio_device* phy)
+{
+ if (filter.empty() || !iio_device_find_attr(phy, "filter_fir_config"))
+ return false;
+
+ std::ifstream ifs(filter.c_str(), std::ifstream::binary);
+ if (!ifs)
+ return false;
+
+ /* Here, we verify that the filter file contains data for both RX+TX. */
+ {
+ char buf[256];
+
+ do {
+ ifs.getline(buf, sizeof(buf));
+ } while (!(buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9')));
+
+ std::string line(buf);
+ if (line.find(',') == std::string::npos)
+ throw std::runtime_error("Incompatible filter file");
+ }
+
+ ifs.seekg(0, ifs.end);
+ int length = ifs.tellg();
+ ifs.seekg(0, ifs.beg);
+
+ char* buffer = new char[length];
+
+ ifs.read(buffer, length);
+ ifs.close();
+
+ int ret = iio_device_attr_write_raw(phy, "filter_fir_config", buffer, length);
+
+ delete[] buffer;
+ return ret > 0;
+}
+
+
+int device_source_impl::handle_decimation_interpolation(unsigned long samplerate,
+ const char* channel_name,
+ const char* attr_name,
+ struct iio_device* dev,
+ bool disable_dec)
+{
+ int ret;
+ struct iio_channel* chan;
+ char buff[128];
+ unsigned long long min, max;
+
+ std::string an(attr_name);
+ an.append("_available");
+
+ // Get ranges
+ chan = iio_device_find_channel(dev, channel_name, false);
+ if (chan == NULL)
+ return -1; // Channel doesn't exist so the dec/int filters probably don't exist
+
+ ret = iio_channel_attr_read(chan, an.c_str(), buff, sizeof(buff));
+ if (ret < 0)
+ return -1; // Channel attribute does not exist so no dec/int filter exist
+
+ sscanf(buff, "%llu %llu ", &max, &min);
+
+ // Write lower range (maybe)
+ if (disable_dec)
+ min = max;
+
+ ret = iio_channel_attr_write_longlong(chan, "sampling_frequency", min);
+ if (ret < 0)
+ std::cerr << "Unable to write attribute sampling_frequency\n";
+
+ return ret;
+}
+
+} /* namespace iio */
+} /* namespace gr */
diff --git a/gr-iio/lib/device_source_impl.h b/gr-iio/lib/device_source_impl.h
new file mode 100644
index 0000000000..07f331f233
--- /dev/null
+++ b/gr-iio/lib/device_source_impl.h
@@ -0,0 +1,102 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_IIO_DEVICE_SOURCE_IMPL_H
+#define INCLUDED_IIO_DEVICE_SOURCE_IMPL_H
+
+#include <string>
+#include <vector>
+
+#include <gnuradio/iio/device_source.h>
+#include <iio.h>
+#include <boost/thread.hpp>
+
+namespace gr {
+namespace iio {
+
+struct ctxInfo {
+ std::string uri;
+ struct iio_context* ctx;
+ int count;
+};
+static std::vector<ctxInfo> contexts;
+static boost::mutex ctx_mutex;
+
+typedef std::vector<ctxInfo>::iterator ctx_it;
+
+class device_source_impl : public device_source
+{
+private:
+ void channel_read(const struct iio_channel* chn, void* dst, size_t len);
+
+ boost::mutex iio_mutex;
+ boost::condition_variable iio_cond, iio_cond2;
+ unsigned long items_in_buffer;
+ off_t byte_offset;
+ volatile bool please_refill_buffer;
+ pmt::pmt_t port_id;
+
+ boost::thread refill_thd;
+
+ unsigned long timeout;
+
+ void refill_thread();
+
+protected:
+ struct iio_context* ctx;
+ struct iio_device *dev, *phy;
+ struct iio_buffer* buf;
+ std::vector<struct iio_channel*> channel_list;
+ unsigned int buffer_size;
+ unsigned int decimation;
+ bool destroy_ctx;
+ volatile bool thread_stopped;
+
+
+public:
+ device_source_impl(struct iio_context* ctx,
+ bool destroy_ctx,
+ const std::string& device,
+ const std::vector<std::string>& channels,
+ const std::string& device_phy,
+ const std::vector<std::string>& params,
+ unsigned int buffer_size = DEFAULT_BUFFER_SIZE,
+ unsigned int decimation = 0);
+ ~device_source_impl();
+
+ static void set_params(struct iio_device* phy,
+ const std::vector<std::string>& params);
+
+ void set_params(const std::vector<std::string>& params);
+ void set_buffer_size(unsigned int buffer_size);
+ void set_timeout_ms(unsigned long timeout);
+
+ // Where all the action really happens
+ int work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+
+ bool start();
+ bool stop();
+
+ static void remove_ctx_history(struct iio_context* ctx, bool destroy_ctx);
+
+ static struct iio_context* get_context(const std::string& uri);
+ static bool load_fir_filter(std::string& filter, struct iio_device* phy);
+ int handle_decimation_interpolation(unsigned long samplerate,
+ const char* channel_name,
+ const char* attr_name,
+ struct iio_device* dev,
+ bool disable_dec);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_DEVICE_SOURCE_IMPL_H */
diff --git a/gr-iio/lib/fmcomms2_sink_impl.cc b/gr-iio/lib/fmcomms2_sink_impl.cc
new file mode 100644
index 0000000000..cd2ef4a3fa
--- /dev/null
+++ b/gr-iio/lib/fmcomms2_sink_impl.cc
@@ -0,0 +1,294 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cstdio>
+
+#include "device_source_impl.h"
+#include "fmcomms2_sink_impl.h"
+#include <gnuradio/io_signature.h>
+
+#include <gnuradio/blocks/complex_to_float.h>
+#include <gnuradio/blocks/float_to_short.h>
+
+#include <ad9361.h>
+
+#define OVERFLOW_CHECK_PERIOD_MS 1000
+
+using namespace gr::blocks;
+
+namespace gr {
+namespace iio {
+
+fmcomms2_sink_f32c::fmcomms2_sink_f32c(bool tx1_en,
+ bool tx2_en,
+ fmcomms2_sink::sptr sink_block)
+ : hier_block2("fmcomms2_sink_f32c",
+ io_signature::make((int)tx1_en + (int)tx2_en,
+ (int)tx1_en + (int)tx2_en,
+ sizeof(gr_complex)),
+ io_signature::make(0, 0, 0)),
+ fmcomms2_block(sink_block)
+{
+ basic_block_sptr hier = shared_from_this();
+ unsigned int num_streams = (int)tx1_en + (int)tx2_en;
+
+ for (unsigned int i = 0; i < num_streams; i++) {
+ float_to_short::sptr f2s1 = float_to_short::make(1, 32768.0);
+ float_to_short::sptr f2s2 = float_to_short::make(1, 32768.0);
+ complex_to_float::sptr c2f = complex_to_float::make();
+
+ connect(hier, i, c2f, 0);
+ connect(c2f, 0, f2s1, 0);
+ connect(c2f, 1, f2s2, 0);
+ connect(f2s1, 0, sink_block, i * 2);
+ connect(f2s2, 0, sink_block, i * 2 + 1);
+ }
+}
+
+fmcomms2_sink::sptr fmcomms2_sink::make(const std::string& uri,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ unsigned long buffer_size,
+ bool cyclic,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ return gnuradio::get_initial_sptr(
+ new fmcomms2_sink_impl(device_source_impl::get_context(uri),
+ true,
+ frequency,
+ samplerate,
+ bandwidth,
+ ch1_en,
+ ch2_en,
+ ch3_en,
+ ch4_en,
+ buffer_size,
+ cyclic,
+ rf_port_select,
+ attenuation1,
+ attenuation2,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop));
+}
+
+fmcomms2_sink::sptr fmcomms2_sink::make_from(struct iio_context* ctx,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ unsigned long buffer_size,
+ bool cyclic,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ return gnuradio::get_initial_sptr(new fmcomms2_sink_impl(ctx,
+ false,
+ frequency,
+ samplerate,
+ bandwidth,
+ ch1_en,
+ ch2_en,
+ ch3_en,
+ ch4_en,
+ buffer_size,
+ cyclic,
+ rf_port_select,
+ attenuation1,
+ attenuation2,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop));
+}
+
+std::vector<std::string> fmcomms2_sink_impl::get_channels_vector(bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en)
+{
+ std::vector<std::string> channels;
+ if (ch1_en)
+ channels.push_back("voltage0");
+ if (ch2_en)
+ channels.push_back("voltage1");
+ if (ch3_en)
+ channels.push_back("voltage2");
+ if (ch4_en)
+ channels.push_back("voltage3");
+ return channels;
+}
+
+fmcomms2_sink_impl::fmcomms2_sink_impl(struct iio_context* ctx,
+ bool destroy_ctx,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ unsigned long buffer_size,
+ bool cyclic,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+ : gr::sync_block("fmcomms2_sink",
+ gr::io_signature::make(1, -1, sizeof(short)),
+ gr::io_signature::make(0, 0, 0)),
+ device_sink_impl(ctx,
+ destroy_ctx,
+ "cf-ad9361-dds-core-lpc",
+ get_channels_vector(ch1_en, ch2_en, ch3_en, ch4_en),
+ "ad9361-phy",
+ std::vector<std::string>(),
+ buffer_size,
+ 0,
+ cyclic),
+ cyclic(cyclic)
+{
+ set_params(frequency,
+ samplerate,
+ bandwidth,
+ rf_port_select,
+ attenuation1,
+ attenuation2,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+
+ stop_thread = false;
+ underflow_thd = boost::thread(&fmcomms2_sink_impl::check_underflow, this);
+}
+
+fmcomms2_sink_impl::~fmcomms2_sink_impl()
+{
+ boost::unique_lock<boost::mutex> lock(uf_mutex);
+ stop_thread = true;
+ lock.unlock();
+ underflow_thd.join();
+}
+
+void fmcomms2_sink_impl::check_underflow(void)
+{
+ uint32_t status;
+ int ret;
+ boost::unique_lock<boost::mutex> lock(uf_mutex, boost::defer_lock);
+
+ // Clear status registers
+ iio_device_reg_write(dev, 0x80000088, 0x6);
+
+ for (;;) {
+ ret = iio_device_reg_read(dev, 0x80000088, &status);
+ if (ret) {
+ throw std::runtime_error("Failed to read underflow status register");
+ }
+ if (status & 1) {
+ printf("U");
+ // Clear status registers
+ iio_device_reg_write(dev, 0x80000088, 1);
+ }
+#ifdef _WIN32
+ Sleep(OVERFLOW_CHECK_PERIOD_MS);
+#else
+ usleep(OVERFLOW_CHECK_PERIOD_MS * 1000);
+#endif
+ lock.lock();
+ if (stop_thread)
+ break;
+ lock.unlock();
+ }
+}
+
+void fmcomms2_sink_impl::set_params(unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ bool is_fmcomms4 = !iio_device_find_channel(phy, "voltage1", false);
+ std::vector<std::string> params;
+
+ bool auto_filter = false;
+ if (filter_filename && filter_filename[0])
+ auto_filter = false;
+
+ params.push_back("out_altvoltage1_TX_LO_frequency=" + boost::to_string(frequency));
+ if (!auto_filter) {
+ params.push_back("out_voltage_sampling_frequency=" +
+ boost::to_string(samplerate));
+ }
+ params.push_back("out_voltage_rf_bandwidth=" + boost::to_string(bandwidth));
+ params.push_back("out_voltage0_rf_port_select=" + boost::to_string(rf_port_select));
+ params.push_back("out_voltage0_hardwaregain=" + boost::to_string(-attenuation1));
+
+ if (!is_fmcomms4) {
+ params.push_back("out_voltage1_hardwaregain=" + boost::to_string(-attenuation2));
+ }
+
+ device_source_impl::set_params(this->phy, params);
+
+ if (auto_filter) {
+ int ret = ad9361_set_bb_rate(phy, samplerate);
+ if (ret) {
+ throw std::runtime_error("Unable to set BB rate");
+ }
+ } else if (filter_filename && filter_filename[0]) {
+ std::string f(filter_filename);
+ if (!device_source_impl::load_fir_filter(f, phy))
+ throw std::runtime_error("Unable to load filter file");
+ }
+}
+
+int fmcomms2_sink_impl::work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ int ret = device_sink_impl::work(noutput_items, input_items, output_items);
+ if (ret < 0 || !cyclic)
+ return ret;
+ else
+ return WORK_DONE;
+}
+} /* namespace iio */
+} /* namespace gr */
diff --git a/gr-iio/lib/fmcomms2_sink_impl.h b/gr-iio/lib/fmcomms2_sink_impl.h
new file mode 100644
index 0000000000..b520b90e86
--- /dev/null
+++ b/gr-iio/lib/fmcomms2_sink_impl.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_IIO_FMCOMMS2_SINK_IMPL_H
+#define INCLUDED_IIO_FMCOMMS2_SINK_IMPL_H
+
+#include <string>
+#include <vector>
+
+#include <gnuradio/iio/fmcomms2_sink.h>
+
+#include "device_sink_impl.h"
+
+namespace gr {
+namespace iio {
+
+class fmcomms2_sink_impl : public fmcomms2_sink, public device_sink_impl
+{
+private:
+ bool cyclic, stop_thread;
+ boost::mutex uf_mutex;
+ boost::thread underflow_thd;
+
+ std::vector<std::string>
+ get_channels_vector(bool ch1_en, bool ch2_en, bool ch3_en, bool ch4_en);
+
+ void check_underflow(void);
+
+public:
+ fmcomms2_sink_impl(struct iio_context* ctx,
+ bool destroy_ctx,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ unsigned long buffer_size,
+ bool cyclic,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop);
+
+ ~fmcomms2_sink_impl();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+
+ void set_params(unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_FMCOMMS2_SINK_IMPL_H */
diff --git a/gr-iio/lib/fmcomms2_source_impl.cc b/gr-iio/lib/fmcomms2_source_impl.cc
new file mode 100644
index 0000000000..d34496d26f
--- /dev/null
+++ b/gr-iio/lib/fmcomms2_source_impl.cc
@@ -0,0 +1,348 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cstdio>
+
+#include "fmcomms2_source_impl.h"
+#include <gnuradio/io_signature.h>
+
+#include <gnuradio/blocks/float_to_complex.h>
+#include <gnuradio/blocks/short_to_float.h>
+
+#include <ad9361.h>
+
+#define MIN_RATE 520333
+#define DECINT_RATIO 8
+#define OVERFLOW_CHECK_PERIOD_MS 1000
+
+using namespace gr::blocks;
+
+namespace gr {
+namespace iio {
+
+fmcomms2_source_f32c::fmcomms2_source_f32c(bool rx1_en,
+ bool rx2_en,
+ fmcomms2_source::sptr src_block)
+ : hier_block2("fmcomms2_f32c",
+ io_signature::make(0, 0, 0),
+ io_signature::make((int)rx1_en + (int)rx2_en,
+ (int)rx1_en + (int)rx2_en,
+ sizeof(gr_complex))),
+ fmcomms2_block(src_block)
+{
+ basic_block_sptr hier = shared_from_this();
+ unsigned int num_streams = (int)rx1_en + (int)rx2_en;
+
+ for (unsigned int i = 0; i < num_streams; i++) {
+ short_to_float::sptr s2f1 = short_to_float::make(1, 2048.0);
+ short_to_float::sptr s2f2 = short_to_float::make(1, 2048.0);
+ float_to_complex::sptr f2c = float_to_complex::make(1);
+
+ connect(src_block, i * 2, s2f1, 0);
+ connect(src_block, i * 2 + 1, s2f2, 0);
+ connect(s2f1, 0, f2c, 0);
+ connect(s2f2, 0, f2c, 1);
+ connect(f2c, 0, hier, i);
+ }
+}
+
+fmcomms2_source::sptr fmcomms2_source::make(const std::string& uri,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ return gnuradio::get_initial_sptr(
+ new fmcomms2_source_impl(device_source_impl::get_context(uri),
+ true,
+ frequency,
+ samplerate,
+ bandwidth,
+ ch1_en,
+ ch2_en,
+ ch3_en,
+ ch4_en,
+ buffer_size,
+ quadrature,
+ rfdc,
+ bbdc,
+ gain1,
+ gain1_value,
+ gain2,
+ gain2_value,
+ port_select,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop));
+}
+
+fmcomms2_source::sptr fmcomms2_source::make_from(struct iio_context* ctx,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ return gnuradio::get_initial_sptr(new fmcomms2_source_impl(ctx,
+ false,
+ frequency,
+ samplerate,
+ bandwidth,
+ ch1_en,
+ ch2_en,
+ ch3_en,
+ ch4_en,
+ buffer_size,
+ quadrature,
+ rfdc,
+ bbdc,
+ gain1,
+ gain1_value,
+ gain2,
+ gain2_value,
+ port_select,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop));
+}
+
+std::vector<std::string> fmcomms2_source_impl::get_channels_vector(bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en)
+{
+ std::vector<std::string> channels;
+ if (ch1_en)
+ channels.push_back("voltage0");
+ if (ch2_en)
+ channels.push_back("voltage1");
+ if (ch3_en)
+ channels.push_back("voltage2");
+ if (ch4_en)
+ channels.push_back("voltage3");
+ return channels;
+}
+
+fmcomms2_source_impl::fmcomms2_source_impl(struct iio_context* ctx,
+ bool destroy_ctx,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+ : gr::sync_block("fmcomms2_source",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(1, -1, sizeof(short))),
+ device_source_impl(ctx,
+ destroy_ctx,
+ "cf-ad9361-lpc",
+ get_channels_vector(ch1_en, ch2_en, ch3_en, ch4_en),
+ "ad9361-phy",
+ std::vector<std::string>(),
+ buffer_size,
+ 0)
+{
+ set_params(frequency,
+ samplerate,
+ bandwidth,
+ quadrature,
+ rfdc,
+ bbdc,
+ gain1,
+ gain1_value,
+ gain2,
+ gain2_value,
+ port_select,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+
+ overflow_thd = boost::thread(&fmcomms2_source_impl::check_overflow, this);
+}
+
+fmcomms2_source_impl::~fmcomms2_source_impl() { overflow_thd.join(); }
+
+void fmcomms2_source_impl::check_overflow(void)
+{
+ uint32_t status;
+ int ret;
+
+ // Wait for stream startup
+#ifdef _WIN32
+ while (thread_stopped) {
+ Sleep(OVERFLOW_CHECK_PERIOD_MS);
+ }
+ Sleep(OVERFLOW_CHECK_PERIOD_MS);
+#else
+ while (thread_stopped) {
+ usleep(OVERFLOW_CHECK_PERIOD_MS * 1000);
+ }
+ usleep(OVERFLOW_CHECK_PERIOD_MS * 1000);
+#endif
+
+ // Clear status registers
+ iio_device_reg_write(dev, 0x80000088, 0x6);
+
+ while (!thread_stopped) {
+ ret = iio_device_reg_read(dev, 0x80000088, &status);
+ if (ret) {
+ throw std::runtime_error("Failed to read overflow status register");
+ }
+ if (status & 4) {
+ printf("O");
+ // Clear status registers
+ iio_device_reg_write(dev, 0x80000088, 4);
+ }
+#ifdef _WIN32
+ Sleep(OVERFLOW_CHECK_PERIOD_MS);
+#else
+ usleep(OVERFLOW_CHECK_PERIOD_MS * 1000);
+#endif
+ }
+}
+
+void fmcomms2_source_impl::set_params(unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ bool is_fmcomms4 = !iio_device_find_channel(phy, "voltage1", false);
+ std::vector<std::string> params;
+ int ret;
+
+ if (samplerate < MIN_RATE) {
+ int ret;
+ samplerate = samplerate * DECINT_RATIO;
+ ret = device_source_impl::handle_decimation_interpolation(
+ samplerate, "voltage0", "sampling_frequency", dev, false);
+ if (ret < 0)
+ samplerate = samplerate / 8;
+ } else // Disable decimation filter if on
+ device_source_impl::handle_decimation_interpolation(
+ samplerate, "voltage0", "sampling_frequency", dev, true);
+
+ params.push_back("out_altvoltage0_RX_LO_frequency=" + boost::to_string(frequency));
+ params.push_back("in_voltage_quadrature_tracking_en=" + boost::to_string(quadrature));
+ params.push_back("in_voltage_rf_dc_offset_tracking_en=" + boost::to_string(rfdc));
+ params.push_back("in_voltage_bb_dc_offset_tracking_en=" + boost::to_string(bbdc));
+ std::string gain1_str = boost::to_string(gain1);
+ params.push_back("in_voltage0_gain_control_mode=" + gain1_str);
+ if (gain1_str.compare("manual") == 0) {
+ params.push_back("in_voltage0_hardwaregain=" + boost::to_string(gain1_value));
+ }
+
+ // Set rate configuration
+ std::string filt_config(filter_source);
+ if (filt_config.compare("Off") == 0) {
+ params.push_back("in_voltage_sampling_frequency=" + boost::to_string(samplerate));
+ params.push_back("in_voltage_rf_bandwidth=" + boost::to_string(bandwidth));
+ } else if (filt_config.compare("Auto") == 0) {
+ int ret = ad9361_set_bb_rate(phy, samplerate);
+ if (ret) {
+ throw std::runtime_error("Unable to set BB rate");
+ params.push_back("in_voltage_rf_bandwidth=" + boost::to_string(bandwidth));
+ }
+ } else if (filt_config.compare("File") == 0) {
+ std::string filt(filter_filename);
+ if (!load_fir_filter(filt, phy))
+ throw std::runtime_error("Unable to load filter file");
+ } else if (filt_config.compare("Design") == 0) {
+ ret = ad9361_set_bb_rate_custom_filter_manual(
+ phy, samplerate, Fpass, Fstop, bandwidth, bandwidth);
+ if (ret) {
+ throw std::runtime_error("Unable to set BB rate");
+ }
+ } else
+ throw std::runtime_error("Unknown filter configuration");
+
+ if (!is_fmcomms4) {
+ std::string gain2_str = boost::to_string(gain2);
+ params.push_back("in_voltage1_gain_control_mode=" + gain2_str);
+ if (gain2_str.compare("manual") == 0) {
+ params.push_back("in_voltage1_hardwaregain=" + boost::to_string(gain2_value));
+ }
+ }
+ params.push_back("in_voltage0_rf_port_select=" + boost::to_string(port_select));
+
+ device_source_impl::set_params(params);
+ // Filters can only be disabled after the sample rate has been set
+ if (filt_config.compare("Off") == 0) {
+ ret = ad9361_set_trx_fir_enable(phy, false);
+ if (ret) {
+ throw std::runtime_error("Unable to disable fitlers");
+ }
+ }
+}
+
+} /* namespace iio */
+} /* namespace gr */
diff --git a/gr-iio/lib/fmcomms2_source_impl.h b/gr-iio/lib/fmcomms2_source_impl.h
new file mode 100644
index 0000000000..631024f1c8
--- /dev/null
+++ b/gr-iio/lib/fmcomms2_source_impl.h
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_IIO_FMCOMMS2_SOURCE_IMPL_H
+#define INCLUDED_IIO_FMCOMMS2_SOURCE_IMPL_H
+
+#include <string>
+#include <vector>
+
+#include <gnuradio/iio/fmcomms2_source.h>
+
+#include "device_source_impl.h"
+
+namespace gr {
+namespace iio {
+
+class fmcomms2_source_impl : public fmcomms2_source, public device_source_impl
+{
+private:
+ std::vector<std::string>
+ get_channels_vector(bool ch1_en, bool ch2_en, bool ch3_en, bool ch4_en);
+ boost::thread overflow_thd;
+ void check_overflow(void);
+
+public:
+ fmcomms2_source_impl(struct iio_context* ctx,
+ bool destroy_ctx,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* rf_port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop);
+
+ ~fmcomms2_source_impl();
+
+ void set_params(unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* rf_port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_FMCOMMS2_SOURCE_IMPL_H */
diff --git a/gr-iio/lib/fmcomms5_sink_impl.cc b/gr-iio/lib/fmcomms5_sink_impl.cc
new file mode 100644
index 0000000000..3e1b0cfdf4
--- /dev/null
+++ b/gr-iio/lib/fmcomms5_sink_impl.cc
@@ -0,0 +1,358 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2015 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cstdio>
+
+#include "device_source_impl.h"
+#include "fmcomms5_sink_impl.h"
+#include <gnuradio/io_signature.h>
+
+#include <gnuradio/blocks/complex_to_float.h>
+#include <gnuradio/blocks/float_to_short.h>
+
+#include <ad9361.h>
+
+using namespace gr::blocks;
+
+namespace gr {
+namespace iio {
+
+fmcomms5_sink_f32c::fmcomms5_sink_f32c(
+ bool tx1_en, bool tx2_en, bool tx3_en, bool tx4_en, fmcomms5_sink::sptr sink_block)
+ : hier_block2(
+ "fmcomms5_sink_f32c",
+ io_signature::make((int)tx1_en + (int)tx2_en + (int)tx3_en + (int)tx4_en,
+ (int)tx1_en + (int)tx2_en + (int)tx3_en + (int)tx4_en,
+ sizeof(gr_complex)),
+ io_signature::make(0, 0, 0)),
+ fmcomms5_block(sink_block)
+{
+ basic_block_sptr hier = shared_from_this();
+ unsigned int num_streams = (int)tx1_en + (int)tx2_en + (int)tx3_en + (int)tx4_en;
+
+ for (unsigned int i = 0; i < num_streams; i++) {
+ float_to_short::sptr f2s1 = float_to_short::make(1, 32768.0);
+ float_to_short::sptr f2s2 = float_to_short::make(1, 32768.0);
+ complex_to_float::sptr c2f = complex_to_float::make();
+
+ connect(hier, i, c2f, 0);
+ connect(c2f, 0, f2s1, 0);
+ connect(c2f, 1, f2s2, 0);
+ connect(f2s1, 0, sink_block, i * 2);
+ connect(f2s2, 0, sink_block, i * 2 + 1);
+ }
+}
+
+fmcomms5_sink::sptr fmcomms5_sink::make(const std::string& uri,
+ unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en,
+ unsigned long buffer_size,
+ bool cyclic,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ double attenuation3,
+ double attenuation4,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ return gnuradio::get_initial_sptr(
+ new fmcomms5_sink_impl(device_source_impl::get_context(uri),
+ true,
+ frequency1,
+ frequency2,
+ samplerate,
+ bandwidth,
+ ch1_en,
+ ch2_en,
+ ch3_en,
+ ch4_en,
+ ch5_en,
+ ch6_en,
+ ch7_en,
+ ch8_en,
+ buffer_size,
+ cyclic,
+ rf_port_select,
+ attenuation1,
+ attenuation2,
+ attenuation3,
+ attenuation4,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop));
+}
+
+fmcomms5_sink::sptr fmcomms5_sink::make_from(struct iio_context* ctx,
+ unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en,
+ unsigned long buffer_size,
+ bool cyclic,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ double attenuation3,
+ double attenuation4,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ return gnuradio::get_initial_sptr(new fmcomms5_sink_impl(ctx,
+ false,
+ frequency1,
+ frequency2,
+ samplerate,
+ bandwidth,
+ ch1_en,
+ ch2_en,
+ ch3_en,
+ ch4_en,
+ ch5_en,
+ ch6_en,
+ ch7_en,
+ ch8_en,
+ buffer_size,
+ cyclic,
+ rf_port_select,
+ attenuation1,
+ attenuation2,
+ attenuation3,
+ attenuation4,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop));
+}
+
+std::vector<std::string> fmcomms5_sink_impl::get_channels_vector(bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en)
+{
+ std::vector<std::string> channels;
+ if (ch1_en)
+ channels.push_back("voltage0");
+ if (ch2_en)
+ channels.push_back("voltage1");
+ if (ch3_en)
+ channels.push_back("voltage2");
+ if (ch4_en)
+ channels.push_back("voltage3");
+ if (ch5_en)
+ channels.push_back("voltage4");
+ if (ch6_en)
+ channels.push_back("voltage5");
+ if (ch7_en)
+ channels.push_back("voltage6");
+ if (ch8_en)
+ channels.push_back("voltage7");
+ return channels;
+}
+
+fmcomms5_sink_impl::fmcomms5_sink_impl(struct iio_context* ctx,
+ bool destroy_ctx,
+ unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en,
+ unsigned long buffer_size,
+ bool cyclic,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ double attenuation3,
+ double attenuation4,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+ : gr::sync_block("fmcomms5_sink",
+ gr::io_signature::make(1, -1, sizeof(short)),
+ gr::io_signature::make(0, 0, 0)),
+ device_sink_impl(
+ ctx,
+ destroy_ctx,
+ "cf-ad9361-dds-core-lpc",
+ get_channels_vector(
+ ch1_en, ch2_en, ch3_en, ch4_en, ch5_en, ch6_en, ch7_en, ch8_en),
+ "ad9361-phy",
+ std::vector<std::string>(),
+ buffer_size,
+ 0,
+ cyclic),
+ cyclic(cyclic),
+ samplerate(0)
+{
+ phy2 = iio_context_find_device(ctx, "ad9361-phy-B");
+ if (!phy2)
+ throw std::runtime_error("Device not found");
+
+ set_params(frequency1,
+ frequency2,
+ samplerate,
+ bandwidth,
+ rf_port_select,
+ attenuation1,
+ attenuation2,
+ attenuation3,
+ attenuation4,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+}
+
+void fmcomms5_sink_impl::set_params(struct iio_device* phy_device,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ std::vector<std::string> params;
+ int ret;
+
+ params.push_back("out_altvoltage1_TX_LO_frequency=" + boost::to_string(frequency));
+ params.push_back("out_voltage0_rf_port_select=" + boost::to_string(rf_port_select));
+ params.push_back("out_voltage0_hardwaregain=" + boost::to_string(-attenuation1));
+ params.push_back("out_voltage1_hardwaregain=" + boost::to_string(-attenuation2));
+
+ // Set rate configuration
+ std::string filt_config(filter_source);
+ if (filt_config.compare("Off") == 0) {
+ params.push_back("in_voltage_sampling_frequency=" + boost::to_string(samplerate));
+ params.push_back("in_voltage_rf_bandwidth=" + boost::to_string(bandwidth));
+ } else if (filt_config.compare("Auto") == 0) {
+ params.push_back("in_voltage_rf_bandwidth=" + boost::to_string(bandwidth));
+ ret = ad9361_set_bb_rate(phy_device, samplerate);
+ if (ret)
+ throw std::runtime_error("Unable to set BB rate");
+ } else if (filt_config.compare("File") == 0) {
+ std::string filt(filter_filename);
+ if (!filt.empty() && !device_source_impl::load_fir_filter(filt, phy_device))
+ throw std::runtime_error("Unable to load filter file");
+ } else if (filt_config.compare("Design") == 0) {
+ ret = ad9361_set_bb_rate_custom_filter_manual(
+ phy_device, samplerate, Fpass, Fstop, bandwidth, bandwidth);
+ if (ret)
+ throw std::runtime_error("Unable to set BB rate");
+ } else
+ throw std::runtime_error("Unknown filter configuration");
+
+ device_source_impl::set_params(phy_device, params);
+
+ // Filters can only be disabled after the sample rate has been set
+ if (filt_config.compare("Off") == 0) {
+ ret = ad9361_set_trx_fir_enable(phy_device, false);
+ if (ret) {
+ throw std::runtime_error("Unable to disable fitlers");
+ }
+ }
+}
+
+void fmcomms5_sink_impl::set_params(unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ double attenuation3,
+ double attenuation4,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ set_params(this->phy,
+ frequency1,
+ samplerate,
+ bandwidth,
+ rf_port_select,
+ attenuation1,
+ attenuation2,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+ set_params(this->phy2,
+ frequency2,
+ samplerate,
+ bandwidth,
+ rf_port_select,
+ attenuation3,
+ attenuation4,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+
+ if (this->samplerate != samplerate) {
+ ad9361_fmcomms5_multichip_sync(ctx, FIXUP_INTERFACE_TIMING | CHECK_SAMPLE_RATES);
+ this->samplerate = samplerate;
+ }
+}
+
+int fmcomms5_sink_impl::work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ int ret = device_sink_impl::work(noutput_items, input_items, output_items);
+ if (ret < 0 || !cyclic)
+ return ret;
+ else
+ return WORK_DONE;
+}
+} /* namespace iio */
+} /* namespace gr */
diff --git a/gr-iio/lib/fmcomms5_sink_impl.h b/gr-iio/lib/fmcomms5_sink_impl.h
new file mode 100644
index 0000000000..eb7a991fc1
--- /dev/null
+++ b/gr-iio/lib/fmcomms5_sink_impl.h
@@ -0,0 +1,100 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2015 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_IIO_FMCOMMS5_SINK_IMPL_H
+#define INCLUDED_IIO_FMCOMMS5_SINK_IMPL_H
+
+#include <string>
+#include <vector>
+
+#include <gnuradio/iio/fmcomms5_sink.h>
+
+#include "device_sink_impl.h"
+
+namespace gr {
+namespace iio {
+
+class fmcomms5_sink_impl : public fmcomms5_sink, public device_sink_impl
+{
+private:
+ bool cyclic;
+ unsigned long samplerate;
+ struct iio_device* phy2;
+
+ static void set_params(struct iio_device* phy_device,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop);
+
+ std::vector<std::string> get_channels_vector(bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en);
+
+public:
+ fmcomms5_sink_impl(struct iio_context* ctx,
+ bool destroy_ctx,
+ unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en,
+ unsigned long buffer_size,
+ bool cyclic,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ double attenuation3,
+ double attenuation4,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+
+ void set_params(unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ const char* rf_port_select,
+ double attenuation1,
+ double attenuation2,
+ double attenuation3,
+ double attenuation4,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_FMCOMMS2_SINK_IMPL_H */
diff --git a/gr-iio/lib/fmcomms5_source_impl.cc b/gr-iio/lib/fmcomms5_source_impl.cc
new file mode 100644
index 0000000000..99f2c2d6ab
--- /dev/null
+++ b/gr-iio/lib/fmcomms5_source_impl.cc
@@ -0,0 +1,413 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2015 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cstdio>
+
+#include "fmcomms5_source_impl.h"
+#include <gnuradio/io_signature.h>
+
+#include <gnuradio/blocks/float_to_complex.h>
+#include <gnuradio/blocks/short_to_float.h>
+
+#include <ad9361.h>
+
+using namespace gr::blocks;
+
+namespace gr {
+namespace iio {
+
+fmcomms5_source_f32c::fmcomms5_source_f32c(
+ bool rx1_en, bool rx2_en, bool rx3_en, bool rx4_en, fmcomms5_source::sptr src_block)
+ : hier_block2(
+ "fmcomms5_f32c",
+ io_signature::make(0, 0, 0),
+ io_signature::make((int)rx1_en + (int)rx2_en + (int)rx3_en + (int)rx4_en,
+ (int)rx1_en + (int)rx2_en + (int)rx3_en + (int)rx4_en,
+ sizeof(gr_complex))),
+ fmcomms5_block(src_block)
+{
+ basic_block_sptr hier = shared_from_this();
+ unsigned int num_streams = (int)rx1_en + (int)rx2_en + (int)rx3_en + (int)rx4_en;
+
+ for (unsigned int i = 0; i < num_streams; i++) {
+ short_to_float::sptr s2f1 = short_to_float::make(1, 2048.0);
+ short_to_float::sptr s2f2 = short_to_float::make(1, 2048.0);
+ float_to_complex::sptr f2c = float_to_complex::make(1);
+
+ connect(src_block, i * 2, s2f1, 0);
+ connect(src_block, i * 2 + 1, s2f2, 0);
+ connect(s2f1, 0, f2c, 0);
+ connect(s2f2, 0, f2c, 1);
+ connect(f2c, 0, hier, i);
+ }
+}
+
+fmcomms5_source::sptr fmcomms5_source::make(const std::string& uri,
+ unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* gain3,
+ double gain3_value,
+ const char* gain4,
+ double gain4_value,
+ const char* port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ return gnuradio::get_initial_sptr(
+ new fmcomms5_source_impl(device_source_impl::get_context(uri),
+ true,
+ frequency1,
+ frequency2,
+ samplerate,
+ bandwidth,
+ ch1_en,
+ ch2_en,
+ ch3_en,
+ ch4_en,
+ ch5_en,
+ ch6_en,
+ ch7_en,
+ ch8_en,
+ buffer_size,
+ quadrature,
+ rfdc,
+ bbdc,
+ gain1,
+ gain1_value,
+ gain2,
+ gain2_value,
+ gain3,
+ gain3_value,
+ gain4,
+ gain4_value,
+ port_select,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop));
+}
+
+fmcomms5_source::sptr fmcomms5_source::make_from(struct iio_context* ctx,
+ unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* gain3,
+ double gain3_value,
+ const char* gain4,
+ double gain4_value,
+ const char* port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ return gnuradio::get_initial_sptr(new fmcomms5_source_impl(ctx,
+ false,
+ frequency1,
+ frequency2,
+ samplerate,
+ bandwidth,
+ ch1_en,
+ ch2_en,
+ ch3_en,
+ ch4_en,
+ ch5_en,
+ ch6_en,
+ ch7_en,
+ ch8_en,
+ buffer_size,
+ quadrature,
+ rfdc,
+ bbdc,
+ gain1,
+ gain1_value,
+ gain2,
+ gain2_value,
+ gain3,
+ gain3_value,
+ gain4,
+ gain4_value,
+ port_select,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop));
+}
+
+std::vector<std::string> fmcomms5_source_impl::get_channels_vector(bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en)
+{
+ std::vector<std::string> channels;
+ if (ch1_en)
+ channels.push_back("voltage0");
+ if (ch2_en)
+ channels.push_back("voltage1");
+ if (ch3_en)
+ channels.push_back("voltage2");
+ if (ch4_en)
+ channels.push_back("voltage3");
+ if (ch5_en)
+ channels.push_back("voltage4");
+ if (ch6_en)
+ channels.push_back("voltage5");
+ if (ch7_en)
+ channels.push_back("voltage6");
+ if (ch8_en)
+ channels.push_back("voltage7");
+ return channels;
+}
+
+fmcomms5_source_impl::fmcomms5_source_impl(struct iio_context* ctx,
+ bool destroy_ctx,
+ unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* gain3,
+ double gain3_value,
+ const char* gain4,
+ double gain4_value,
+ const char* port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+ : gr::sync_block("fmcomms5_source",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(1, -1, sizeof(short))),
+ device_source_impl(
+ ctx,
+ destroy_ctx,
+ "cf-ad9361-A",
+ get_channels_vector(
+ ch1_en, ch2_en, ch3_en, ch4_en, ch5_en, ch6_en, ch7_en, ch8_en),
+ "ad9361-phy",
+ std::vector<std::string>(),
+ buffer_size,
+ 0),
+ samplerate(0)
+{
+ phy2 = iio_context_find_device(ctx, "ad9361-phy-B");
+ if (!phy2)
+ throw std::runtime_error("Device not found");
+
+ set_params(frequency1,
+ frequency2,
+ samplerate,
+ bandwidth,
+ quadrature,
+ rfdc,
+ bbdc,
+ gain1,
+ gain1_value,
+ gain2,
+ gain2_value,
+ gain3,
+ gain3_value,
+ gain4,
+ gain4_value,
+ port_select,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+}
+
+void fmcomms5_source_impl::set_params(struct iio_device* phy_device,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ std::vector<std::string> params;
+ std::string gain1_str(gain1);
+ std::string gain2_str(gain2);
+ int ret;
+
+ params.push_back("out_altvoltage0_RX_LO_frequency=" + boost::to_string(frequency));
+ params.push_back("in_voltage_quadrature_tracking_en=" + boost::to_string(quadrature));
+ params.push_back("in_voltage_rf_dc_offset_tracking_en=" + boost::to_string(rfdc));
+ params.push_back("in_voltage_bb_dc_offset_tracking_en=" + boost::to_string(bbdc));
+ params.push_back("in_voltage0_gain_control_mode=" + boost::to_string(gain1));
+ if (gain1_str.compare("manual") == 0)
+ params.push_back("in_voltage0_hardwaregain=" + boost::to_string(gain1_value));
+ params.push_back("in_voltage1_gain_control_mode=" + boost::to_string(gain2));
+ if (gain2_str.compare("manual") == 0)
+ params.push_back("in_voltage1_hardwaregain=" + boost::to_string(gain2_value));
+ params.push_back("in_voltage0_rf_port_select=" + boost::to_string(port_select));
+
+ // Set rate configuration
+ std::string filt_config(filter_source);
+ if (filt_config.compare("Off") == 0) {
+ params.push_back("in_voltage_sampling_frequency=" + boost::to_string(samplerate));
+ params.push_back("in_voltage_rf_bandwidth=" + boost::to_string(bandwidth));
+ } else if (filt_config.compare("Auto") == 0) {
+ params.push_back("in_voltage_rf_bandwidth=" + boost::to_string(bandwidth));
+ ret = ad9361_set_bb_rate(phy_device, samplerate);
+ if (ret)
+ throw std::runtime_error("Unable to set BB rate");
+ } else if (filt_config.compare("File") == 0) {
+ std::string filt(filter_filename);
+ if (!filt.empty() && !load_fir_filter(filt, phy_device))
+ throw std::runtime_error("Unable to load filter file");
+ } else if (filt_config.compare("Design") == 0) {
+ ret = ad9361_set_bb_rate_custom_filter_manual(
+ phy_device, samplerate, Fpass, Fstop, bandwidth, bandwidth);
+ if (ret)
+ throw std::runtime_error("Unable to set BB rate");
+ } else
+ throw std::runtime_error("Unknown filter configuration");
+
+ device_source_impl::set_params(phy_device, params);
+
+ // Filters can only be disabled after the sample rate has been set
+ if (filt_config.compare("Off") == 0) {
+ ret = ad9361_set_trx_fir_enable(phy_device, false);
+ if (ret) {
+ throw std::runtime_error("Unable to disable fitlers");
+ }
+ }
+}
+
+void fmcomms5_source_impl::set_params(unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* gain3,
+ double gain3_value,
+ const char* gain4,
+ double gain4_value,
+ const char* port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ set_params(this->phy,
+ frequency1,
+ samplerate,
+ bandwidth,
+ quadrature,
+ rfdc,
+ bbdc,
+ gain1,
+ gain1_value,
+ gain2,
+ gain2_value,
+ port_select,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+ set_params(this->phy2,
+ frequency2,
+ samplerate,
+ bandwidth,
+ quadrature,
+ rfdc,
+ bbdc,
+ gain3,
+ gain3_value,
+ gain4,
+ gain4_value,
+ port_select,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+
+ if (this->samplerate != samplerate) {
+ ad9361_fmcomms5_multichip_sync(ctx, FIXUP_INTERFACE_TIMING | CHECK_SAMPLE_RATES);
+ this->samplerate = samplerate;
+ }
+}
+
+} /* namespace iio */
+} /* namespace gr */
diff --git a/gr-iio/lib/fmcomms5_source_impl.h b/gr-iio/lib/fmcomms5_source_impl.h
new file mode 100644
index 0000000000..78497b8b03
--- /dev/null
+++ b/gr-iio/lib/fmcomms5_source_impl.h
@@ -0,0 +1,113 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_IIO_FMCOMMS5_SOURCE_IMPL_H
+#define INCLUDED_IIO_FMCOMMS5_SOURCE_IMPL_H
+
+#include <string>
+#include <vector>
+
+#include <gnuradio/iio/fmcomms5_source.h>
+
+#include "device_source_impl.h"
+
+namespace gr {
+namespace iio {
+
+class fmcomms5_source_impl : public fmcomms5_source, public device_source_impl
+{
+private:
+ unsigned long samplerate;
+ struct iio_device* phy2;
+
+ static void set_params(struct iio_device* phy_device,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop);
+
+ std::vector<std::string> get_channels_vector(bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en);
+
+public:
+ fmcomms5_source_impl(struct iio_context* ctx,
+ bool destroy_ctx,
+ unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en,
+ bool ch5_en,
+ bool ch6_en,
+ bool ch7_en,
+ bool ch8_en,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* gain3,
+ double gain3_value,
+ const char* gain4,
+ double gain4_value,
+ const char* rf_port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop);
+
+ void set_params(unsigned long long frequency1,
+ unsigned long long frequency2,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain1,
+ double gain1_value,
+ const char* gain2,
+ double gain2_value,
+ const char* gain3,
+ double gain3_value,
+ const char* gain4,
+ double gain4_value,
+ const char* rf_port_select,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_FMCOMMS5_SOURCE_IMPL_H */
diff --git a/gr-iio/lib/pluto_sink_impl.cc b/gr-iio/lib/pluto_sink_impl.cc
new file mode 100644
index 0000000000..e081a52523
--- /dev/null
+++ b/gr-iio/lib/pluto_sink_impl.cc
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2017 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "pluto_sink_impl.h"
+#include "pluto_source_impl.h"
+
+#include <iio.h>
+
+namespace gr {
+namespace iio {
+
+pluto_sink::sptr pluto_sink::make(const std::string& uri,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ unsigned long buffer_size,
+ bool cyclic,
+ double attenuation,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ fmcomms2_sink::sptr block =
+ fmcomms2_sink::make(uri.empty() ? pluto_source_impl::get_uri() : uri,
+ frequency,
+ samplerate,
+ bandwidth,
+ true,
+ true,
+ false,
+ false,
+ buffer_size,
+ cyclic,
+ "A",
+ attenuation,
+ 0.0,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+
+ return gnuradio::get_initial_sptr(new pluto_sink_impl(block));
+}
+
+pluto_sink_impl::pluto_sink_impl(fmcomms2_sink::sptr block)
+ : hier_block2("pluto_sink",
+ io_signature::make(1, 1, sizeof(gr_complex)),
+ io_signature::make(0, 0, 0)),
+ fmcomms2_sink_f32c(true, false, block)
+{
+}
+
+void pluto_sink_impl::set_params(unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ double attenuation,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ fmcomms2_sink_f32c::set_params(frequency,
+ samplerate,
+ bandwidth,
+ "A",
+ attenuation,
+ 0.0,
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+}
+
+} // namespace iio
+} // namespace gr
diff --git a/gr-iio/lib/pluto_sink_impl.h b/gr-iio/lib/pluto_sink_impl.h
new file mode 100644
index 0000000000..5b6d987686
--- /dev/null
+++ b/gr-iio/lib/pluto_sink_impl.h
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2017 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_IIO_PLUTO_SINK_IMPL_H
+#define INCLUDED_IIO_PLUTO_SINK_IMPL_H
+
+#include <string>
+#include <vector>
+
+#include <gnuradio/iio/fmcomms2_sink.h>
+#include <gnuradio/iio/pluto_sink.h>
+
+#include "device_sink_impl.h"
+
+namespace gr {
+namespace iio {
+
+class pluto_sink_impl : public pluto_sink, public fmcomms2_sink_f32c
+{
+public:
+ explicit pluto_sink_impl(fmcomms2_sink::sptr block);
+
+ void set_params(unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ double attenuation,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_PLUTO_SINK_IMPL_H */
diff --git a/gr-iio/lib/pluto_source_impl.cc b/gr-iio/lib/pluto_source_impl.cc
new file mode 100644
index 0000000000..8c797c0d91
--- /dev/null
+++ b/gr-iio/lib/pluto_source_impl.cc
@@ -0,0 +1,137 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2017 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "pluto_source_impl.h"
+
+#include <iio.h>
+#include <stdio.h>
+
+namespace gr {
+namespace iio {
+
+pluto_source::sptr pluto_source::make(const std::string& uri,
+ unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ unsigned long buffer_size,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain,
+ double gain_value,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ fmcomms2_source::sptr block =
+ fmcomms2_source::make(uri.empty() ? pluto_source_impl::get_uri() : uri,
+ frequency,
+ samplerate,
+ bandwidth,
+ true,
+ true,
+ false,
+ false,
+ buffer_size,
+ quadrature,
+ rfdc,
+ bbdc,
+ gain,
+ gain_value,
+ NULL,
+ 0.0,
+ "A_BALANCED",
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+
+ return gnuradio::get_initial_sptr(new pluto_source_impl(block));
+}
+
+std::string pluto_source_impl::get_uri()
+{
+ struct iio_scan_context* ctx = iio_create_scan_context("usb", 0);
+ if (!ctx)
+ throw std::runtime_error("Unable to create scan context");
+
+ struct iio_context_info** info;
+ int ret = iio_scan_context_get_info_list(ctx, &info);
+ if (ret < 0) {
+ iio_scan_context_destroy(ctx);
+ throw std::runtime_error("Unable to scan for Pluto devices");
+ }
+
+ if (ret == 0) {
+ iio_context_info_list_free(info);
+ iio_scan_context_destroy(ctx);
+ throw std::runtime_error("No Pluto device found");
+ }
+
+ if (ret > 1) {
+ printf("More than one Pluto found:\n");
+
+ for (unsigned int i = 0; i < (size_t)ret; i++) {
+ printf("\t%d: %s [%s]\n",
+ i,
+ iio_context_info_get_description(info[i]),
+ iio_context_info_get_uri(info[i]));
+ }
+
+ printf("We will use the first one.\n");
+ }
+
+ std::string uri(iio_context_info_get_uri(info[0]));
+ iio_context_info_list_free(info);
+ iio_scan_context_destroy(ctx);
+
+ return uri;
+}
+
+pluto_source_impl::pluto_source_impl(fmcomms2_source::sptr block)
+ : hier_block2("pluto_source",
+ io_signature::make(0, 0, 0),
+ io_signature::make(1, 1, sizeof(gr_complex))),
+ fmcomms2_source_f32c(true, false, block)
+{
+}
+
+void pluto_source_impl::set_params(unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain,
+ double gain_value,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop)
+{
+ fmcomms2_source_f32c::set_params(frequency,
+ samplerate,
+ bandwidth,
+ quadrature,
+ rfdc,
+ bbdc,
+ gain,
+ gain_value,
+ NULL,
+ 0.0,
+ "A_BALANCED",
+ filter_source,
+ filter_filename,
+ Fpass,
+ Fstop);
+}
+
+} // namespace iio
+} // namespace gr
diff --git a/gr-iio/lib/pluto_source_impl.h b/gr-iio/lib/pluto_source_impl.h
new file mode 100644
index 0000000000..82f79ccc92
--- /dev/null
+++ b/gr-iio/lib/pluto_source_impl.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2017 Analog Devices Inc.
+ * Author: Paul Cercueil <paul.cercueil@analog.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_IIO_PLUTO_SOURCE_IMPL_H
+#define INCLUDED_IIO_PLUTO_SOURCE_IMPL_H
+
+#include <string>
+#include <vector>
+
+#include <gnuradio/iio/fmcomms2_source.h>
+#include <gnuradio/iio/pluto_source.h>
+
+#include "device_source_impl.h"
+
+namespace gr {
+namespace iio {
+
+class pluto_source_impl : public pluto_source, public fmcomms2_source_f32c
+{
+private:
+ // void update_rate(unsigned long samplerate)
+
+public:
+ explicit pluto_source_impl(fmcomms2_source::sptr block);
+
+ static std::string get_uri();
+
+ void set_params(unsigned long long frequency,
+ unsigned long samplerate,
+ unsigned long bandwidth,
+ bool quadrature,
+ bool rfdc,
+ bool bbdc,
+ const char* gain,
+ double gain_value,
+ const char* filter_source,
+ const char* filter_filename,
+ float Fpass,
+ float Fstop);
+};
+
+} // namespace iio
+} // namespace gr
+
+#endif /* INCLUDED_IIO_PLUTO_SOURCE_IMPL_H */
diff --git a/gr-iio/python/iio/CMakeLists.txt b/gr-iio/python/iio/CMakeLists.txt
new file mode 100644
index 0000000000..9f121cb9f1
--- /dev/null
+++ b/gr-iio/python/iio/CMakeLists.txt
@@ -0,0 +1,40 @@
+# Copyright 2021 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+########################################################################
+# Include python install macros
+########################################################################
+include(GrPython)
+
+########################################################################
+# Install python sources
+########################################################################
+GR_PYTHON_INSTALL(
+ FILES
+ __init__.py
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio/iio
+)
+
+########################################################################
+# Handle the unit tests
+########################################################################
+if(ENABLE_TESTING)
+ set(GR_TEST_TARGET_DEPS "")
+ set(GR_TEST_LIBRARY_DIRS "")
+ set(GR_TEST_PYTHON_DIRS
+ ${CMAKE_BINARY_DIR}/gnuradio-runtime/python
+ )
+
+ include(GrTest)
+ file(GLOB py_qa_test_files "qa_*.py")
+ foreach(py_qa_test_file ${py_qa_test_files})
+ get_filename_component(py_qa_test_name ${py_qa_test_file} NAME_WE)
+ GR_ADD_TEST(${py_qa_test_name} ${QA_PYTHON_EXECUTABLE} -B ${py_qa_test_file})
+ endforeach(py_qa_test_file)
+endif(ENABLE_TESTING)
+
+add_subdirectory(bindings)
diff --git a/gr-iio/python/iio/__init__.py b/gr-iio/python/iio/__init__.py
new file mode 100644
index 0000000000..df0aa9a6a3
--- /dev/null
+++ b/gr-iio/python/iio/__init__.py
@@ -0,0 +1,35 @@
+#
+# Copyright 2008,2009 Free Software Foundation, Inc.
+#
+# This application is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This application is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+# The presence of this file turns this directory into a Python package
+
+'''
+Interface blocks for IIO devices
+'''
+
+from __future__ import absolute_import
+from __future__ import unicode_literals
+
+import os
+
+try:
+ from .iio_python import *
+except ImportError:
+ dirname, filename = os.path.split(os.path.abspath(__file__))
+ __path__.append(os.path.join(dirname, "bindings"))
+ from .iio_python import *
diff --git a/gr-iio/python/iio/bindings/CMakeLists.txt b/gr-iio/python/iio/bindings/CMakeLists.txt
new file mode 100644
index 0000000000..e201fd0838
--- /dev/null
+++ b/gr-iio/python/iio/bindings/CMakeLists.txt
@@ -0,0 +1,31 @@
+include(GrPybind)
+
+########################################################################
+# Python Bindings
+########################################################################
+
+list(APPEND iio_python_files
+ attr_sink_python.cc
+ attr_source_python.cc
+ attr_updater_python.cc
+ dds_control_python.cc
+ device_sink_python.cc
+ device_source_python.cc
+ fmcomms2_sink_f32c_python.cc
+ fmcomms2_sink_python.cc
+ fmcomms2_source_f32c_python.cc
+ fmcomms2_source_python.cc
+ fmcomms5_sink_f32c_python.cc
+ fmcomms5_sink_python.cc
+ fmcomms5_source_f32c_python.cc
+ fmcomms5_source_python.cc
+ pluto_sink_python.cc
+ pluto_source_python.cc
+ python_bindings.cc)
+
+GR_PYBIND_MAKE_CHECK_HASH(iio
+ ../../..
+ gr::iio
+ "${iio_python_files}")
+
+install(TARGETS iio_python DESTINATION ${GR_PYTHON_DIR}/gnuradio/iio COMPONENT pythonapi)
diff --git a/gr-iio/python/iio/bindings/attr_sink_python.cc b/gr-iio/python/iio/bindings/attr_sink_python.cc
new file mode 100644
index 0000000000..d3def75068
--- /dev/null
+++ b/gr-iio/python/iio/bindings/attr_sink_python.cc
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(attr_sink.h) */
+/* BINDTOOL_HEADER_FILE_HASH(2f43dea87847934b54d7b782a0d9dd2f) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/attr_sink.h>
+// pydoc.h is automatically generated in the build directory
+#include <attr_sink_pydoc.h>
+
+void bind_attr_sink(py::module& m)
+{
+
+ using attr_sink = gr::iio::attr_sink;
+
+
+ py::class_<attr_sink, gr::block, gr::basic_block, std::shared_ptr<attr_sink>>(
+ m, "attr_sink", D(attr_sink))
+
+ .def(py::init(&attr_sink::make),
+ py::arg("uri"),
+ py::arg("device"),
+ py::arg("channel"),
+ py::arg("type"),
+ py::arg("output"),
+ py::arg("required_enable"),
+ D(attr_sink, make))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/attr_source_python.cc b/gr-iio/python/iio/bindings/attr_source_python.cc
new file mode 100644
index 0000000000..efe9d76380
--- /dev/null
+++ b/gr-iio/python/iio/bindings/attr_source_python.cc
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(attr_source.h) */
+/* BINDTOOL_HEADER_FILE_HASH(7750ad16326387730e3d6b2e08657fe3) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/attr_source.h>
+// pydoc.h is automatically generated in the build directory
+#include <attr_source_pydoc.h>
+
+void bind_attr_source(py::module& m)
+{
+
+ using attr_source = gr::iio::attr_source;
+
+
+ py::class_<attr_source,
+ gr::sync_block,
+ gr::block,
+ gr::basic_block,
+ std::shared_ptr<attr_source>>(m, "attr_source", D(attr_source))
+
+ .def(py::init(&attr_source::make),
+ py::arg("uri"),
+ py::arg("device"),
+ py::arg("channel"),
+ py::arg("attribute"),
+ py::arg("update_interval_ms"),
+ py::arg("samples_per_update"),
+ py::arg("data_type"),
+ py::arg("attr_type"),
+ py::arg("output"),
+ py::arg("address"),
+ py::arg("required_enable"),
+ D(attr_source, make))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/attr_updater_python.cc b/gr-iio/python/iio/bindings/attr_updater_python.cc
new file mode 100644
index 0000000000..ba33df3165
--- /dev/null
+++ b/gr-iio/python/iio/bindings/attr_updater_python.cc
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(attr_updater.h) */
+/* BINDTOOL_HEADER_FILE_HASH(f6f58dbb206b0719ecd9b99b91a6eb82) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/attr_updater.h>
+// pydoc.h is automatically generated in the build directory
+#include <attr_updater_pydoc.h>
+
+void bind_attr_updater(py::module& m)
+{
+
+ using attr_updater = gr::iio::attr_updater;
+
+
+ py::class_<attr_updater, gr::block, gr::basic_block, std::shared_ptr<attr_updater>>(
+ m, "attr_updater", D(attr_updater))
+
+ .def(py::init(&attr_updater::make),
+ py::arg("attribute"),
+ py::arg("value"),
+ py::arg("interval_ms"),
+ D(attr_updater, make))
+
+ .def("set_params",
+ &attr_updater::set_value,
+ py::arg("value"),
+ D(attr_updater, make))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/dds_control_python.cc b/gr-iio/python/iio/bindings/dds_control_python.cc
new file mode 100644
index 0000000000..7a7b7954e2
--- /dev/null
+++ b/gr-iio/python/iio/bindings/dds_control_python.cc
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(dds_control.h) */
+/* BINDTOOL_HEADER_FILE_HASH(ff3fc63a928b75b6ed3e7bb82fd8cc71) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/dds_control.h>
+// pydoc.h is automatically generated in the build directory
+#include <dds_control_pydoc.h>
+
+void bind_dds_control(py::module& m)
+{
+
+ using dds_control = gr::iio::dds_control;
+
+
+ py::class_<dds_control, gr::block, gr::basic_block, std::shared_ptr<dds_control>>(
+ m, "dds_control", D(dds_control))
+
+ .def(py::init(&dds_control::make),
+ py::arg("uri"),
+ py::arg("enabled"),
+ py::arg("frequencies"),
+ py::arg("phases"),
+ py::arg("scales"),
+ D(dds_control, make))
+
+ .def("set_dds_confg",
+ &dds_control::set_dds_confg,
+ py::arg("frequencies"),
+ py::arg("phases"),
+ py::arg("scales"),
+ D(dds_control, set_dds_confg))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/device_sink_python.cc b/gr-iio/python/iio/bindings/device_sink_python.cc
new file mode 100644
index 0000000000..e91ccc5882
--- /dev/null
+++ b/gr-iio/python/iio/bindings/device_sink_python.cc
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(device_sink.h) */
+/* BINDTOOL_HEADER_FILE_HASH(a18ca2be4b936386305f32fb9ea40ade) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/device_sink.h>
+// pydoc.h is automatically generated in the build directory
+#include <device_sink_pydoc.h>
+
+void bind_device_sink(py::module& m)
+{
+
+ using device_sink = gr::iio::device_sink;
+
+
+ py::class_<device_sink,
+ gr::sync_block,
+ gr::block,
+ gr::basic_block,
+ std::shared_ptr<device_sink>>(m, "device_sink", D(device_sink))
+
+ .def(py::init(&device_sink::make),
+ py::arg("uri"),
+ py::arg("device"),
+ py::arg("channels"),
+ py::arg("device_phy"),
+ py::arg("params"),
+ py::arg("buffer_size") = DEFAULT_BUFFER_SIZE,
+ py::arg("interpolation") = 0,
+ py::arg("cyclic") = false,
+ D(device_sink, make))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/device_source_python.cc b/gr-iio/python/iio/bindings/device_source_python.cc
new file mode 100644
index 0000000000..4f6b30b706
--- /dev/null
+++ b/gr-iio/python/iio/bindings/device_source_python.cc
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(device_source.h) */
+/* BINDTOOL_HEADER_FILE_HASH(09eb30139a946becee62a26128da7dc7) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/device_source.h>
+// pydoc.h is automatically generated in the build directory
+#include <device_source_pydoc.h>
+
+void bind_device_source(py::module& m)
+{
+
+ using device_source = gr::iio::device_source;
+
+
+ py::class_<device_source,
+ gr::sync_block,
+ gr::block,
+ gr::basic_block,
+ std::shared_ptr<device_source>>(m, "device_source", D(device_source))
+
+ .def(py::init(&device_source::make),
+ py::arg("uri"),
+ py::arg("device"),
+ py::arg("channels"),
+ py::arg("device_phy"),
+ py::arg("params"),
+ py::arg("buffer_size") = DEFAULT_BUFFER_SIZE,
+ py::arg("decimation") = 0,
+ D(device_source, make))
+
+ .def("set_buffer_size",
+ &device_source::set_buffer_size,
+ py::arg("buffer_size") = DEFAULT_BUFFER_SIZE,
+ D(device_source, set_buffer_size))
+
+ .def("set_timeout_ms",
+ &device_source::set_timeout_ms,
+ py::arg("timeout"),
+ D(device_source, set_timeout_ms))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/docstrings/attr_sink_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/attr_sink_pydoc_template.h
new file mode 100644
index 0000000000..2b6a658d0d
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/attr_sink_pydoc_template.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+static const char* __doc_gr_iio_attr_sink = R"doc()doc";
+
+static const char* __doc_gr_iio_attr_sink_make = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/docstrings/attr_source_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/attr_source_pydoc_template.h
new file mode 100644
index 0000000000..f5f40f60f2
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/attr_source_pydoc_template.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+static const char* __doc_gr_iio_attr_source = R"doc()doc";
+
+static const char* __doc_gr_iio_attr_source_make = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/docstrings/attr_updater_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/attr_updater_pydoc_template.h
new file mode 100644
index 0000000000..61cacb0822
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/attr_updater_pydoc_template.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+static const char* __doc_gr_iio_attr_updater = R"doc()doc";
+
+static const char* __doc_gr_iio_attr_updater_make = R"doc()doc";
+
+static const char* __doc_gr_iio_attr_set_value = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/docstrings/dds_control_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/dds_control_pydoc_template.h
new file mode 100644
index 0000000000..6e448f4b6f
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/dds_control_pydoc_template.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+
+static const char* __doc_gr_iio_dds_control = R"doc()doc";
+
+static const char* __doc_gr_iio_dds_control_make = R"doc()doc";
+
+static const char* __doc_gr_iio_dds_control_set_dds_confg = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/docstrings/device_sink_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/device_sink_pydoc_template.h
new file mode 100644
index 0000000000..88a7bd6c03
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/device_sink_pydoc_template.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+static const char* __doc_gr_iio_device_sink = R"doc()doc";
+
+static const char* __doc_gr_iio_device_sink_make = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/docstrings/device_source_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/device_source_pydoc_template.h
new file mode 100644
index 0000000000..5fa41a537c
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/device_source_pydoc_template.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+static const char* __doc_gr_iio_device_source = R"doc()doc";
+
+static const char* __doc_gr_iio_device_source_make = R"doc()doc";
+
+static const char* __doc_gr_iio_device_source_set_buffer_size = R"doc()doc";
+
+static const char* __doc_gr_iio_device_source_set_timeout_ms = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/docstrings/fmcomms2_sink_f32c_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/fmcomms2_sink_f32c_pydoc_template.h
new file mode 100644
index 0000000000..c8ed763879
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/fmcomms2_sink_f32c_pydoc_template.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+static const char* __doc_gr_iio_fmcomms2_sink_f32c = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms2_sink_f32c_make = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms2_sink_f32c_set_params = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/docstrings/fmcomms2_sink_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/fmcomms2_sink_pydoc_template.h
new file mode 100644
index 0000000000..03ba0c36b4
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/fmcomms2_sink_pydoc_template.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+static const char* __doc_gr_iio_fmcomms2_sink = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms2_sink_make = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms2_sink_set_params = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/docstrings/fmcomms2_source_f32c_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/fmcomms2_source_f32c_pydoc_template.h
new file mode 100644
index 0000000000..9a47adf36b
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/fmcomms2_source_f32c_pydoc_template.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+static const char* __doc_gr_iio_fmcomms2_source_f32c = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms2_source_f32c_make = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms2_source_f32c_set_params = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/docstrings/fmcomms2_source_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/fmcomms2_source_pydoc_template.h
new file mode 100644
index 0000000000..1ab36625b5
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/fmcomms2_source_pydoc_template.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+static const char* __doc_gr_iio_fmcomms2_source = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms2_source_make = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms2_source_set_params = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/docstrings/fmcomms5_sink_f32c_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/fmcomms5_sink_f32c_pydoc_template.h
new file mode 100644
index 0000000000..2bdd734cbe
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/fmcomms5_sink_f32c_pydoc_template.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+static const char* __doc_gr_iio_fmcomms5_sink_f32c = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms5_sink_f32c_make = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms5_sink_f32c_set_params = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/docstrings/fmcomms5_sink_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/fmcomms5_sink_pydoc_template.h
new file mode 100644
index 0000000000..57f2b7a02e
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/fmcomms5_sink_pydoc_template.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+static const char* __doc_gr_iio_fmcomms5_sink = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms5_sink_make = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms5_sink_set_params = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/docstrings/fmcomms5_source_f32c_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/fmcomms5_source_f32c_pydoc_template.h
new file mode 100644
index 0000000000..8f4d82f1c0
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/fmcomms5_source_f32c_pydoc_template.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+static const char* __doc_gr_iio_fmcomms5_source_f32c = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms5_source_f32c_make = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms5_source_f32c_set_params = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/docstrings/fmcomms5_source_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/fmcomms5_source_pydoc_template.h
new file mode 100644
index 0000000000..06c0c29594
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/fmcomms5_source_pydoc_template.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+static const char* __doc_gr_iio_fmcomms5_source = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms5_source_make = R"doc()doc";
+
+static const char* __doc_gr_iio_fmcomms5_source_set_params = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/docstrings/pluto_sink_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/pluto_sink_pydoc_template.h
new file mode 100644
index 0000000000..1c2ce3439e
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/pluto_sink_pydoc_template.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+static const char* __doc_gr_iio_pluto_sink = R"doc()doc";
+
+static const char* __doc_gr_iio_pluto_sink_make = R"doc()doc";
+
+static const char* __doc_gr_iio_pluto_sink_set_params = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/docstrings/pluto_source_pydoc_template.h b/gr-iio/python/iio/bindings/docstrings/pluto_source_pydoc_template.h
new file mode 100644
index 0000000000..8b09b24519
--- /dev/null
+++ b/gr-iio/python/iio/bindings/docstrings/pluto_source_pydoc_template.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, iio, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+static const char* __doc_gr_iio_pluto_source = R"doc()doc";
+
+static const char* __doc_gr_iio_pluto_source_make = R"doc()doc";
+
+static const char* __doc_gr_iio_pluto_source_set_params = R"doc()doc";
diff --git a/gr-iio/python/iio/bindings/fmcomms2_sink_f32c_python.cc b/gr-iio/python/iio/bindings/fmcomms2_sink_f32c_python.cc
new file mode 100644
index 0000000000..6603a6edce
--- /dev/null
+++ b/gr-iio/python/iio/bindings/fmcomms2_sink_f32c_python.cc
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(fmcomms2_sink.h) */
+/* BINDTOOL_HEADER_FILE_HASH(9f2679554149aa23caf1ccb4b0ddd02c) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/fmcomms2_sink.h>
+// pydoc.h is automatically generated in the build directory
+#include <fmcomms2_sink_f32c_pydoc.h>
+
+void bind_fmcomms2_sink_f32c(py::module& m)
+{
+
+ using fmcomms2_sink_f32c = gr::iio::fmcomms2_sink_f32c;
+
+
+ py::class_<fmcomms2_sink_f32c,
+ gr::hier_block2,
+ gr::basic_block,
+ std::shared_ptr<fmcomms2_sink_f32c>>(
+ m, "fmcomms2_sink_f32c", D(fmcomms2_sink_f32c))
+
+ .def(py::init(&fmcomms2_sink_f32c::make),
+ py::arg("uri"),
+ py::arg("longfrequency"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("tx1_en"),
+ py::arg("tx2_en"),
+ py::arg("buffer_size"),
+ py::arg("cyclic"),
+ py::arg("rf_port_select"),
+ py::arg("attenuation1"),
+ py::arg("attenuation2"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms2_sink_f32c, make))
+
+ .def("set_params",
+ &fmcomms2_sink_f32c::set_params,
+ py::arg("longfrequency"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("rf_port_select"),
+ py::arg("attenuation1"),
+ py::arg("attenuation2"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms2_sink_f32c, set_params))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/fmcomms2_sink_python.cc b/gr-iio/python/iio/bindings/fmcomms2_sink_python.cc
new file mode 100644
index 0000000000..fa1a879035
--- /dev/null
+++ b/gr-iio/python/iio/bindings/fmcomms2_sink_python.cc
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(fmcomms2_sink.h) */
+/* BINDTOOL_HEADER_FILE_HASH(9f2679554149aa23caf1ccb4b0ddd02c) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/fmcomms2_sink.h>
+// pydoc.h is automatically generated in the build directory
+#include <fmcomms2_sink_pydoc.h>
+
+void bind_fmcomms2_sink(py::module& m)
+{
+
+ using fmcomms2_sink = gr::iio::fmcomms2_sink;
+
+
+ py::class_<fmcomms2_sink,
+ gr::sync_block,
+ gr::block,
+ gr::basic_block,
+ std::shared_ptr<fmcomms2_sink>>(m, "fmcomms2_sink", D(fmcomms2_sink))
+
+ .def(py::init(&fmcomms2_sink::make),
+ py::arg("uri"),
+ py::arg("longfrequency"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("ch1_en"),
+ py::arg("ch2_en"),
+ py::arg("ch3_en"),
+ py::arg("ch4_en"),
+ py::arg("buffer_size"),
+ py::arg("cyclic"),
+ py::arg("rf_port_select"),
+ py::arg("attenuation1"),
+ py::arg("attenuation2"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms2_sink, make))
+
+ .def("set_params",
+ &fmcomms2_sink::set_params,
+ py::arg("longfrequency"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("rf_port_select"),
+ py::arg("attenuation1"),
+ py::arg("attenuation2"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms2_sink, set_params))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/fmcomms2_source_f32c_python.cc b/gr-iio/python/iio/bindings/fmcomms2_source_f32c_python.cc
new file mode 100644
index 0000000000..e804ebf485
--- /dev/null
+++ b/gr-iio/python/iio/bindings/fmcomms2_source_f32c_python.cc
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(fmcomms2_source.h) */
+/* BINDTOOL_HEADER_FILE_HASH(1069e19d257339872c0475ae5ec2e478) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/fmcomms2_source.h>
+// pydoc.h is automatically generated in the build directory
+#include <fmcomms2_source_f32c_pydoc.h>
+
+void bind_fmcomms2_source_f32c(py::module& m)
+{
+
+ using fmcomms2_source_f32c = gr::iio::fmcomms2_source_f32c;
+
+
+ py::class_<fmcomms2_source_f32c,
+ gr::hier_block2,
+ gr::basic_block,
+ std::shared_ptr<fmcomms2_source_f32c>>(
+ m, "fmcomms2_source_f32c", D(fmcomms2_source_f32c))
+
+ .def(py::init(&fmcomms2_source_f32c::make),
+ py::arg("uri"),
+ py::arg("longfrequency"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("rx1_en"),
+ py::arg("rx2_en"),
+ py::arg("buffer_size"),
+ py::arg("quadrature"),
+ py::arg("rfdc"),
+ py::arg("bbdc"),
+ py::arg("gain1"),
+ py::arg("gain1_value"),
+ py::arg("gain2"),
+ py::arg("gain2_value"),
+ py::arg("rf_port_select"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms2_source_f32c, make))
+
+ .def("set_params",
+ &fmcomms2_source_f32c::set_params,
+ py::arg("longfrequency"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("quadrature"),
+ py::arg("rfdc"),
+ py::arg("bbdc"),
+ py::arg("gain1"),
+ py::arg("gain1_value"),
+ py::arg("gain2"),
+ py::arg("gain2_value"),
+ py::arg("rf_port_select"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms2_source_f32c, set_params))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/fmcomms2_source_python.cc b/gr-iio/python/iio/bindings/fmcomms2_source_python.cc
new file mode 100644
index 0000000000..22a7ace50f
--- /dev/null
+++ b/gr-iio/python/iio/bindings/fmcomms2_source_python.cc
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(fmcomms2_source.h) */
+/* BINDTOOL_HEADER_FILE_HASH(1069e19d257339872c0475ae5ec2e478) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/fmcomms2_source.h>
+// pydoc.h is automatically generated in the build directory
+#include <fmcomms2_source_pydoc.h>
+
+void bind_fmcomms2_source(py::module& m)
+{
+
+ using fmcomms2_source = gr::iio::fmcomms2_source;
+
+
+ py::class_<fmcomms2_source,
+ gr::sync_block,
+ gr::block,
+ gr::basic_block,
+ std::shared_ptr<fmcomms2_source>>(m, "fmcomms2_source", D(fmcomms2_source))
+
+ .def(py::init(&fmcomms2_source::make),
+ py::arg("uri"),
+ py::arg("longfrequency"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("ch1_en"),
+ py::arg("ch2_en"),
+ py::arg("ch3_en"),
+ py::arg("ch4_en"),
+ py::arg("buffer_size"),
+ py::arg("quadrature"),
+ py::arg("rfdc"),
+ py::arg("bbdc"),
+ py::arg("gain1"),
+ py::arg("gain1_value"),
+ py::arg("gain2"),
+ py::arg("gain2_value"),
+ py::arg("rf_port_select"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms2_source, make))
+
+ .def("set_params",
+ &fmcomms2_source::set_params,
+ py::arg("longfrequency"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("quadrature"),
+ py::arg("rfdc"),
+ py::arg("bbdc"),
+ py::arg("gain1"),
+ py::arg("gain1_value"),
+ py::arg("gain2"),
+ py::arg("gain2_value"),
+ py::arg("rf_port_select"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms2_source, set_params))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/fmcomms5_sink_f32c_python.cc b/gr-iio/python/iio/bindings/fmcomms5_sink_f32c_python.cc
new file mode 100644
index 0000000000..eaabe7a877
--- /dev/null
+++ b/gr-iio/python/iio/bindings/fmcomms5_sink_f32c_python.cc
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(fmcomms5_sink.h) */
+/* BINDTOOL_HEADER_FILE_HASH(86b4898504a92fd7f157a4cde608c4f1) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/fmcomms5_sink.h>
+// pydoc.h is automatically generated in the build directory
+#include <fmcomms5_sink_f32c_pydoc.h>
+
+void bind_fmcomms5_sink_f32c(py::module& m)
+{
+
+ using fmcomms5_sink_f32c = gr::iio::fmcomms5_sink_f32c;
+
+
+ py::class_<fmcomms5_sink_f32c,
+ gr::hier_block2,
+ gr::basic_block,
+ std::shared_ptr<fmcomms5_sink_f32c>>(
+ m, "fmcomms5_sink_f32c", D(fmcomms5_sink_f32c))
+
+ .def(py::init(&fmcomms5_sink_f32c::make),
+ py::arg("uri"),
+ py::arg("longfrequency1"),
+ py::arg("longfrequency2"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("tx1_en"),
+ py::arg("tx2_en"),
+ py::arg("tx3_en"),
+ py::arg("tx4_en"),
+ py::arg("buffer_size"),
+ py::arg("cyclic"),
+ py::arg("rf_port_select"),
+ py::arg("attenuation1"),
+ py::arg("attenuation2"),
+ py::arg("attenuation3"),
+ py::arg("attenuation4"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms5_sink_f32c, make))
+
+ .def("set_params",
+ &fmcomms5_sink_f32c::set_params,
+ py::arg("longfrequency1"),
+ py::arg("longfrequency2"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("rf_port_select"),
+ py::arg("attenuation1"),
+ py::arg("attenuation2"),
+ py::arg("attenuation3"),
+ py::arg("attenuation4"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms5_sink_f32c, set_params))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/fmcomms5_sink_python.cc b/gr-iio/python/iio/bindings/fmcomms5_sink_python.cc
new file mode 100644
index 0000000000..088116a436
--- /dev/null
+++ b/gr-iio/python/iio/bindings/fmcomms5_sink_python.cc
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(fmcomms5_sink.h) */
+/* BINDTOOL_HEADER_FILE_HASH(86b4898504a92fd7f157a4cde608c4f1) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/fmcomms5_sink.h>
+// pydoc.h is automatically generated in the build directory
+#include <fmcomms5_sink_pydoc.h>
+
+void bind_fmcomms5_sink(py::module& m)
+{
+
+ using fmcomms5_sink = gr::iio::fmcomms5_sink;
+
+
+ py::class_<fmcomms5_sink,
+ gr::sync_block,
+ gr::block,
+ gr::basic_block,
+ std::shared_ptr<fmcomms5_sink>>(m, "fmcomms5_sink", D(fmcomms5_sink))
+
+ .def(py::init(&fmcomms5_sink::make),
+ py::arg("uri"),
+ py::arg("longfrequency1"),
+ py::arg("longfrequency2"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("ch1_en"),
+ py::arg("ch2_en"),
+ py::arg("ch3_en"),
+ py::arg("ch4_en"),
+ py::arg("ch5_en"),
+ py::arg("ch6_en"),
+ py::arg("ch7_en"),
+ py::arg("ch8_en"),
+ py::arg("buffer_size"),
+ py::arg("cyclic"),
+ py::arg("rf_port_select"),
+ py::arg("attenuation1"),
+ py::arg("attenuation2"),
+ py::arg("attenuation3"),
+ py::arg("attenuation4"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms5_sink, make))
+
+ .def("set_params",
+ &fmcomms5_sink::set_params,
+ py::arg("longfrequency1"),
+ py::arg("longfrequency2"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("rf_port_select"),
+ py::arg("attenuation1"),
+ py::arg("attenuation2"),
+ py::arg("attenuation3"),
+ py::arg("attenuation4"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms5_sink, set_params))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/fmcomms5_source_f32c_python.cc b/gr-iio/python/iio/bindings/fmcomms5_source_f32c_python.cc
new file mode 100644
index 0000000000..5b9f71964f
--- /dev/null
+++ b/gr-iio/python/iio/bindings/fmcomms5_source_f32c_python.cc
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(fmcomms5_source.h) */
+/* BINDTOOL_HEADER_FILE_HASH(c665df9240c9c1460e51d3678c16deb5) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/fmcomms5_source.h>
+// pydoc.h is automatically generated in the build directory
+#include <fmcomms5_source_f32c_pydoc.h>
+
+void bind_fmcomms5_source_f32c(py::module& m)
+{
+
+ using fmcomms5_source_f32c = gr::iio::fmcomms5_source_f32c;
+
+
+ py::class_<fmcomms5_source_f32c,
+ gr::hier_block2,
+ gr::basic_block,
+ std::shared_ptr<fmcomms5_source_f32c>>(
+ m, "fmcomms5_source_f32c", D(fmcomms5_source_f32c))
+
+ .def(py::init(&fmcomms5_source_f32c::make),
+ py::arg("uri"),
+ py::arg("longfrequency1"),
+ py::arg("longfrequency2"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("tx1_en"),
+ py::arg("tx2_en"),
+ py::arg("tx3_en"),
+ py::arg("tx4_en"),
+ py::arg("buffer_size"),
+ py::arg("quadrature"),
+ py::arg("rfdc"),
+ py::arg("bbdc"),
+ py::arg("gain1"),
+ py::arg("gain1_value"),
+ py::arg("gain2"),
+ py::arg("gain2_value"),
+ py::arg("gain3"),
+ py::arg("gain3_value"),
+ py::arg("gain4"),
+ py::arg("gain4_value"),
+ py::arg("rf_port_select"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms5_source_f32c, make))
+
+ .def("set_params",
+ &fmcomms5_source_f32c::set_params,
+ py::arg("longfrequency1"),
+ py::arg("longfrequency2"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("quadrature"),
+ py::arg("rfdc"),
+ py::arg("bbdc"),
+ py::arg("gain1"),
+ py::arg("gain1_value"),
+ py::arg("gain2"),
+ py::arg("gain2_value"),
+ py::arg("gain3"),
+ py::arg("gain3_value"),
+ py::arg("gain4"),
+ py::arg("gain4_value"),
+ py::arg("rf_port_select"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms5_source_f32c, set_params))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/fmcomms5_source_python.cc b/gr-iio/python/iio/bindings/fmcomms5_source_python.cc
new file mode 100644
index 0000000000..fa86b878c7
--- /dev/null
+++ b/gr-iio/python/iio/bindings/fmcomms5_source_python.cc
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(fmcomms5_source.h) */
+/* BINDTOOL_HEADER_FILE_HASH(c665df9240c9c1460e51d3678c16deb5) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/fmcomms5_source.h>
+// pydoc.h is automatically generated in the build directory
+#include <fmcomms5_source_pydoc.h>
+
+void bind_fmcomms5_source(py::module& m)
+{
+
+ using fmcomms5_source = gr::iio::fmcomms5_source;
+
+
+ py::class_<fmcomms5_source,
+ gr::sync_block,
+ gr::block,
+ gr::basic_block,
+ std::shared_ptr<fmcomms5_source>>(m, "fmcomms5_source", D(fmcomms5_source))
+
+ .def(py::init(&fmcomms5_source::make),
+ py::arg("uri"),
+ py::arg("longfrequency1"),
+ py::arg("longfrequency2"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("ch1_en"),
+ py::arg("ch2_en"),
+ py::arg("ch3_en"),
+ py::arg("ch4_en"),
+ py::arg("ch5_en"),
+ py::arg("ch6_en"),
+ py::arg("ch7_en"),
+ py::arg("ch8_en"),
+ py::arg("buffer_size"),
+ py::arg("quadrature"),
+ py::arg("rfdc"),
+ py::arg("bbdc"),
+ py::arg("gain1"),
+ py::arg("gain1_value"),
+ py::arg("gain2"),
+ py::arg("gain2_value"),
+ py::arg("gain3"),
+ py::arg("gain3_value"),
+ py::arg("gain4"),
+ py::arg("gain4_value"),
+ py::arg("rf_port_select"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms5_source, make))
+
+ .def("set_params",
+ &fmcomms5_source::set_params,
+ py::arg("longfrequency1"),
+ py::arg("longfrequency2"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("quadrature"),
+ py::arg("rfdc"),
+ py::arg("bbdc"),
+ py::arg("gain1"),
+ py::arg("gain1_value"),
+ py::arg("gain2"),
+ py::arg("gain2_value"),
+ py::arg("gain3"),
+ py::arg("gain3_value"),
+ py::arg("gain4"),
+ py::arg("gain4_value"),
+ py::arg("rf_port_select"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(fmcomms5_source, set_params))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/pluto_sink_python.cc b/gr-iio/python/iio/bindings/pluto_sink_python.cc
new file mode 100644
index 0000000000..3a31b1ad50
--- /dev/null
+++ b/gr-iio/python/iio/bindings/pluto_sink_python.cc
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(pluto_sink.h) */
+/* BINDTOOL_HEADER_FILE_HASH(156bd835e28cf4f40bb68897fe691a94) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/pluto_sink.h>
+// pydoc.h is automatically generated in the build directory
+#include <pluto_sink_pydoc.h>
+
+void bind_pluto_sink(py::module& m)
+{
+
+ using pluto_sink = gr::iio::pluto_sink;
+
+ py::class_<pluto_sink, gr::hier_block2, gr::basic_block, std::shared_ptr<pluto_sink>>(
+ m, "pluto_sink", D(pluto_sink))
+
+ .def(py::init(&pluto_sink::make),
+ py::arg("uri"),
+ py::arg("longfrequency"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("buffer_size"),
+ py::arg("cyclic"),
+ py::arg("attenuation"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(pluto_sink, make))
+
+ .def("set_params",
+ &pluto_sink::set_params,
+ py::arg("longfrequency"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("attenuation"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(pluto_sink, set_params))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/pluto_source_python.cc b/gr-iio/python/iio/bindings/pluto_source_python.cc
new file mode 100644
index 0000000000..c3327ee6ba
--- /dev/null
+++ b/gr-iio/python/iio/bindings/pluto_source_python.cc
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(pluto_source.h) */
+/* BINDTOOL_HEADER_FILE_HASH(68ea89af32db39f870bfa404f3fbc6c2) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/iio/pluto_source.h>
+// pydoc.h is automatically generated in the build directory
+#include <pluto_source_pydoc.h>
+
+void bind_pluto_source(py::module& m)
+{
+
+ using pluto_source = gr::iio::pluto_source;
+
+
+ py::class_<pluto_source,
+ gr::hier_block2,
+ gr::basic_block,
+ std::shared_ptr<pluto_source>>(m, "pluto_source", D(pluto_source))
+
+ .def(py::init(&pluto_source::make),
+ py::arg("uri"),
+ py::arg("longfrequency"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("buffer_size"),
+ py::arg("quadrature"),
+ py::arg("rfdc"),
+ py::arg("bbdc"),
+ py::arg("gain"),
+ py::arg("gain_value"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(pluto_source, make))
+
+ .def("set_params",
+ &pluto_source::set_params,
+ py::arg("longfrequency"),
+ py::arg("samplerate"),
+ py::arg("bandwidth"),
+ py::arg("quadrature"),
+ py::arg("rfdc"),
+ py::arg("bbdc"),
+ py::arg("gain"),
+ py::arg("gain_value"),
+ py::arg("filter_source") = "",
+ py::arg("filter_filename") = "",
+ py::arg("Fpass") = 0.0,
+ py::arg("Fstop") = 0.0,
+ D(pluto_source, set_params))
+
+ ;
+}
diff --git a/gr-iio/python/iio/bindings/python_bindings.cc b/gr-iio/python/iio/bindings/python_bindings.cc
new file mode 100644
index 0000000000..6340cfe193
--- /dev/null
+++ b/gr-iio/python/iio/bindings/python_bindings.cc
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include <pybind11/pybind11.h>
+
+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+#include <numpy/arrayobject.h>
+
+namespace py = pybind11;
+
+void bind_device_source(py::module& m);
+void bind_fmcomms2_source(py::module& m);
+void bind_fmcomms2_source_f32c(py::module& m);
+void bind_fmcomms5_source(py::module& m);
+void bind_fmcomms5_source_f32c(py::module& m);
+void bind_attr_source(py::module& m);
+void bind_device_sink(py::module& m);
+void bind_fmcomms2_sink(py::module& m);
+void bind_fmcomms2_sink_f32c(py::module& m);
+void bind_fmcomms5_sink(py::module& m);
+void bind_fmcomms5_sink_f32c(py::module& m);
+void bind_attr_sink(py::module& m);
+void bind_dds_control(py::module& m);
+void bind_attr_updater(py::module& m);
+void bind_pluto_sink(py::module& m);
+void bind_pluto_source(py::module& m);
+
+// We need this hack because import_array() returns NULL
+// for newer Python versions.
+// This function is also necessary because it ensures access to the C API
+// and removes a warning.
+void* init_numpy()
+{
+ import_array();
+ return NULL;
+}
+
+PYBIND11_MODULE(iio_python, m)
+{
+ // Initialize the numpy C API
+ // (otherwise we will see segmentation faults)
+ init_numpy();
+
+ // Allow access to base block methods
+ py::module::import("gnuradio.gr");
+
+ bind_device_source(m);
+ bind_fmcomms2_source(m);
+ bind_fmcomms2_source_f32c(m);
+ bind_fmcomms5_source(m);
+ bind_fmcomms5_source_f32c(m);
+ bind_attr_source(m);
+ bind_device_sink(m);
+ bind_fmcomms2_sink(m);
+ bind_fmcomms2_sink_f32c(m);
+ bind_fmcomms5_sink(m);
+ bind_fmcomms5_sink_f32c(m);
+ bind_attr_sink(m);
+ bind_dds_control(m);
+ bind_attr_updater(m);
+ bind_pluto_sink(m);
+ bind_pluto_source(m);
+}
diff --git a/gr-iio/python/iio/qa_iio.py b/gr-iio/python/iio/qa_iio.py
new file mode 100644
index 0000000000..f28ec76e7f
--- /dev/null
+++ b/gr-iio/python/iio/qa_iio.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+#
+# Copyright 2019 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+from __future__ import print_function
+import time
+from gnuradio import gr, gr_unittest, iio, blocks
+
+import pmt
+
+class test_iio(gr_unittest.TestCase):
+
+ def test_import(self):
+ """Just see if we can import the module...
+ They may not have a IIO device connected, etc. Don't try to run anything"""
+ pass
+
+ def test_attribute_updater(self):
+ attr = "Test"
+ val = "100"
+ key0 = pmt.intern(attr)
+ val0 = pmt.intern(val)
+ msg_dic = pmt.make_dict()
+ msg_dic = pmt.dict_add(msg_dic, key0, val0)
+
+ src = iio.attr_updater(attr,val,500)
+ snk = blocks.message_debug()
+
+ tb = gr.top_block()
+ tb.msg_connect((src, "out"), (snk, "store"))
+ tb.start()
+ time.sleep(1)
+ tb.stop()
+ tb.wait()
+
+ rec_msg = snk.get_message(0)
+ self.assertTrue(pmt.equal(rec_msg, msg_dic))
+
+if __name__ == '__main__':
+ gr_unittest.run(test_iio, "test_iio.xml")