From ea1b389edb7fdcedca84b088b913de4666dbff0d Mon Sep 17 00:00:00 2001 From: SGudla Date: Fri, 7 Jul 2023 14:26:44 +0530 Subject: [PATCH] Add support for AD5780, AD5781, AD5790, AD5791, AD5760 Add ad578x.py Add a test script - test_ad578x.py Add an example code - ad578x_example.py Update index.rst Update init.py Update supported_parts.md Add adi.ad578x.rst Signed-off-by: SGudla --- adi/__init__.py | 1 + adi/ad578x.py | 143 ++++++++++++++++++++++++++++++ doc/source/devices/adi.ad578x.rst | 7 ++ doc/source/devices/index.rst | 1 + examples/ad578x_example.py | 50 +++++++++++ supported_parts.md | 5 ++ tasks.py | 1 + test/emu/devices/ad578x.xml | 1 + test/emu/hardware_map.yml | 9 ++ test/test_ad578x.py | 11 +++ 10 files changed, 229 insertions(+) create mode 100644 adi/ad578x.py create mode 100644 doc/source/devices/adi.ad578x.rst create mode 100644 examples/ad578x_example.py create mode 100644 test/emu/devices/ad578x.xml create mode 100644 test/test_ad578x.py diff --git a/adi/__init__.py b/adi/__init__.py index 39c23e94b..298894fb6 100644 --- a/adi/__init__.py +++ b/adi/__init__.py @@ -3,6 +3,7 @@ # SPDX short identifier: ADIBSD from adi.ad469x import ad469x +from adi.ad578x import ad578x from adi.ad717x import ad717x from adi.ad719x import ad719x from adi.ad777x import ad777x diff --git a/adi/ad578x.py b/adi/ad578x.py new file mode 100644 index 000000000..26e102dc0 --- /dev/null +++ b/adi/ad578x.py @@ -0,0 +1,143 @@ +# Copyright (C) 2023 Analog Devices, Inc. +# +# SPDX short identifier: ADIBSD + + +from decimal import Decimal + +from adi.attribute import attribute +from adi.context_manager import context_manager +from adi.rx_tx import tx + + +class ad578x(tx, context_manager): + """ AD578x DAC """ + + _complex_data = False + channel = [] # type: ignore + _device_name = "" + + def __init__(self, uri="", device_name=""): + """Constructor for AD578x class.""" + context_manager.__init__(self, uri, self._device_name) + + compatible_parts = [ + "ad5780", + "ad5781", + "ad5790", + "ad5791", + "ad5760", + ] + + self._ctrl = None + + if not device_name: + device_name = compatible_parts[0] + else: + if device_name not in compatible_parts: + raise Exception( + f"Not a compatible device: {device_name}. Supported device names " + f"are: {','.join(compatible_parts)}" + ) + + # Select the device matching device_name as working device + for device in self._ctx.devices: + if device.name == device_name: + self._ctrl = device + self._txdac = device + break + + if not self._ctrl: + raise Exception("Error in selecting matching device") + + if not self._txdac: + raise Exception("Error in selecting matching device") + + self.output_bits = [] + for ch in self._ctrl.channels: + name = ch.id + self.output_bits.append(ch.data_format.bits) + self._tx_channel_names.append(name) + self.channel.append(self._channel(self._ctrl, name)) + + tx.__init__(self) + + @property + def powerdown_mode(self): + """Ad578x powerdown_mode config""" + return self._get_iio_dev_attr_str("powerdown_mode") + + @powerdown_mode.setter + def powerdown_mode(self, value): + self._set_iio_dev_attr_str("powerdown_mode", value) + + @property + def powerdown_mode_available(self): + """AD578x powedown mode available""" + return self._get_iio_dev_attr_str("powerdown_mode_available") + + @property + def sampling_frequency(self): + """AD578x sampling frequency config""" + return self._get_iio_dev_attr_str("sampling_frequency") + + @sampling_frequency.setter + def sampling_frequency(self, value): + self._set_iio_dev_attr_str("sampling_frequency", value) + + @property + def code_select(self): + """AD578x code format config""" + return self._get_iio_dev_attr_str("code_select") + + @code_select.setter + def code_select(self, value): + self._set_iio_dev_attr_str("code_select", value) + + @property + def code_select_available(self): + """AD578x code format available""" + return self._get_iio_dev_attr_str("code_select_available") + + class _channel(attribute): + """AD578x channel""" + + def __init__(self, ctrl, channel_name): + self.name = channel_name + self._ctrl = ctrl + + @property + def raw(self): + """AD578x channel raw value""" + return self._get_iio_attr(self.name, "raw", True) + + @raw.setter + def raw(self, value): + self._set_iio_attr(self.name, "raw", True, str(int(value))) + + @property + def offset(self): + """AD578x channel offset""" + return self._get_iio_attr(self.name, "offset", True) + + @offset.setter + def offset(self, value): + self._set_iio_attr(self.name, "offset", True, str(Decimal(value).real)) + + @property + def scale(self): + """AD578x channel scale""" + return self._get_iio_attr(self.name, "scale", True) + + @scale.setter + def scale(self, value): + self._set_iio_attr(self.name, "scale", True, str(Decimal(value).real)) + + @property + def powerdown(self): + """AD578x powerdown config""" + return self._get_iio_attr(self.name, "powerdown", True) + + @powerdown.setter + def powerdown(self, value): + self._set_iio_attr(self.name, "powerdown", True, value) diff --git a/doc/source/devices/adi.ad578x.rst b/doc/source/devices/adi.ad578x.rst new file mode 100644 index 000000000..cd769629a --- /dev/null +++ b/doc/source/devices/adi.ad578x.rst @@ -0,0 +1,7 @@ +ad578x +================= + +.. automodule:: adi.ad578x + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/devices/index.rst b/doc/source/devices/index.rst index 520821b85..467786497 100644 --- a/doc/source/devices/index.rst +++ b/doc/source/devices/index.rst @@ -16,6 +16,7 @@ Supported Devices adi.ad5592r adi.ad5627 adi.ad5686 + adi.ad578x adi.ad5940 adi.ad6676 adi.ad7124 diff --git a/examples/ad578x_example.py b/examples/ad578x_example.py new file mode 100644 index 000000000..216a32f41 --- /dev/null +++ b/examples/ad578x_example.py @@ -0,0 +1,50 @@ +# Copyright (C) 2023 Analog Devices, Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# - Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# - Neither the name of Analog Devices, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# - The use of this software may or may not infringe the patent rights +# of one or more patent holders. This license does not release you +# from the requirement that you obtain separate licenses from these +# patent holders to use this software. +# - Use of the software either in source or binary form, must be run +# on or directly connected to an Analog Devices Inc. component. +# +# THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. +# +# IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY +# RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import adi +import numpy as np + +# Set up AD578X +ad578x_dev = adi.ad578x(uri="ip:analog") + +chn = 0 +ad578x_dev._tx_data_type = np.int32 +ad578x_dev.tx_enabled_channels = [chn] + +raw = ad578x_dev.channel[0].raw +print(raw) + +arr = [0, 1000, 2000, 3000, 4000] +data = np.array(arr) + +ad578x_dev.tx(data) diff --git a/supported_parts.md b/supported_parts.md index 203614346..102189cfa 100644 --- a/supported_parts.md +++ b/supported_parts.md @@ -55,6 +55,11 @@ - AD5695R - AD5696 - AD5696R +- AD5760 +- AD5780 +- AD5781 +- AD5790 +- AD5791 - AD5940 - AD6676 - AD7124 diff --git a/tasks.py b/tasks.py index 5af5aac8a..62e42312c 100644 --- a/tasks.py +++ b/tasks.py @@ -175,6 +175,7 @@ def checkparts(c): "ad719x", "ad469x", "ad777x", + "ad578x", ] for c in dir(mod): if ( diff --git a/test/emu/devices/ad578x.xml b/test/emu/devices/ad578x.xml new file mode 100644 index 000000000..d220f2338 --- /dev/null +++ b/test/emu/devices/ad578x.xml @@ -0,0 +1 @@ +]> \ No newline at end of file diff --git a/test/emu/hardware_map.yml b/test/emu/hardware_map.yml index ae20cd4b6..56e28c375 100644 --- a/test/emu/hardware_map.yml +++ b/test/emu/hardware_map.yml @@ -320,6 +320,15 @@ ad5592r: - filename: ad5592r.xml - data_devices: - iio:device0 + +ad578x: + - ad578x + - pyadi_iio_class_support: + - ad578x + - emulate: + - filename: ad578x.xml + - data_devices: + - iio:device0 ad7291: - ad7291 diff --git a/test/test_ad578x.py b/test/test_ad578x.py new file mode 100644 index 000000000..e74b231e8 --- /dev/null +++ b/test/test_ad578x.py @@ -0,0 +1,11 @@ +import pytest + +hardware = "ad5780" +classname = "adi.ad578x" + +######################################### +@pytest.mark.iio_hardware(hardware, True) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize("channel", [0]) +def test_ad578x_tx_data(test_dma_tx, iio_uri, classname, channel): + test_dma_tx(iio_uri, classname, channel)