diff options
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") |