From 1c7cf4712cec185248bd442a9ee43887575672d1 Mon Sep 17 00:00:00 2001 From: RibhuDP Date: Tue, 12 Sep 2023 13:57:57 +0530 Subject: [PATCH] adi:ad5754r: Add initial support Add initial attribute r/w support for ad5754r Signed-off-by: RibhuDP --- adi/__init__.py | 1 + adi/ad5754r.py | 209 +++++++++++++++++++++++++++++ doc/source/devices/adi.ad5754r.rst | 7 + doc/source/devices/index.rst | 1 + examples/ad5754r_example.py | 48 +++++++ supported_parts.md | 1 + test/emu/devices/ad5754r.xml | 1 + test/emu/hardware_map.yml | 9 ++ test/test_ad5754r.py | 53 ++++++++ 9 files changed, 330 insertions(+) create mode 100644 adi/ad5754r.py create mode 100644 doc/source/devices/adi.ad5754r.rst create mode 100644 examples/ad5754r_example.py create mode 100644 test/emu/devices/ad5754r.xml create mode 100644 test/test_ad5754r.py diff --git a/adi/__init__.py b/adi/__init__.py index 0cb356152..5a02742c9 100644 --- a/adi/__init__.py +++ b/adi/__init__.py @@ -13,6 +13,7 @@ from adi.ad4630 import ad4630 from adi.ad5592r import ad5592r from adi.ad5686 import ad5686 +from adi.ad5754r import ad5754r from adi.ad5940 import ad5940 from adi.ad6676 import ad6676 from adi.ad7124 import ad7124 diff --git a/adi/ad5754r.py b/adi/ad5754r.py new file mode 100644 index 000000000..2dbd2aceb --- /dev/null +++ b/adi/ad5754r.py @@ -0,0 +1,209 @@ +# Copyright (C) 2020-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 ad5754r(tx, context_manager): + """ AD5754R DAC """ + + _complex_data = False + channel = [] + _device_name = "" + + def __init__(self, uri="", device_name=""): + """ Constructor for AD5754R driver class """ + + context_manager.__init__(self, uri, self._device_name) + + compatible_parts = ["ad5754r"] + 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 int_ref_powerup(self): + """Get internal reference powerup""" + return self._get_iio_dev_attr_str("int_ref_powerup") + + @property + def int_ref_powerup_available(self): + """Get list of all internal reference powerup settings""" + return self._get_iio_dev_attr_str("int_ref_powerup_available") + + @int_ref_powerup.setter + def int_ref_powerup(self, value): + """Set internal reference powerup""" + if value in self.int_ref_powerup_available: + self._set_iio_dev_attr_str("int_ref_powerup", value) + else: + raise ValueError( + "Error: internal reference powerup not supported \nUse one of: " + + str(self.int_ref_powerup_available) + ) + + @property + def clear_setting(self): + """Get clear code setting""" + return self._get_iio_dev_attr_str("clear_setting") + + @property + def clear_setting_available(self): + """Get list of all clear code settings""" + return self._get_iio_dev_attr_str("clear_setting_available") + + @clear_setting.setter + def clear_setting(self, value): + """Set clear setting""" + if value in self.clear_setting_available: + self._set_iio_dev_attr_str("clear_setting", value) + else: + raise ValueError( + "Error: clear setting not supported \nUse one of: " + + str(self.clear_setting_available) + ) + + @property + def sdo_disable(self): + """Get sdo disable""" + return self._get_iio_dev_attr_str("sdo_disable") + + @property + def sdo_disable_available(self): + """Get list of all sdo enable/disable settings""" + return self._get_iio_dev_attr_str("sdo_disable_available") + + @sdo_disable.setter + def sdo_disable(self, value): + """Set sdo enable/disable setting""" + if value in self.sdo_disable_available: + self._set_iio_dev_attr_str("sdo_disable", value) + else: + raise ValueError( + "Error: sdo setting not supported \nUse one of: " + + str(self.sdo_disable_available) + ) + + @property + def sampling_frequency(self): + """Get sampling frequency""" + return self._get_iio_dev_attr_str("sampling_frequency") + + @sampling_frequency.setter + def sampling_frequency(self, value): + """Set sampling frequency""" + self._set_iio_dev_attr_str("sampling_frequency", value) + + class _channel(attribute): + """AD5754R channel""" + + def __init__(self, ctrl, channel_name): + self.name = channel_name + self._ctrl = ctrl + + @property + def raw(self): + """Get channel raw value + DAC code in the range 0-65535""" + return self._get_iio_attr(self.name, "raw", True) + + @raw.setter + def raw(self, value): + """Set channel raw value""" + self._set_iio_attr(self.name, "raw", True, str(int(value))) + + @property + def offset(self): + """Get channel offset""" + return self._get_iio_attr_str(self.name, "offset", True) + + @offset.setter + def offset(self, value): + """Set channel offset""" + self._set_iio_attr(self.name, "offset", True, str(Decimal(value).real)) + + @property + def scale(self): + """Get channel scale""" + return float(self._get_iio_attr_str(self.name, "scale", True)) + + @scale.setter + def scale(self, value): + """Set channel scale""" + self._set_iio_attr(self.name, "scale", True, str(Decimal(value).real)) + + @property + def powerup(self): + """Get DAC chn powerup""" + return self._get_iio_attr_str(self.name, "powerup", True) + + @property + def powerup_available(self): + """Get list of DAC chn powerup settings""" + return self._get_iio_attr_str(self.name, "powerup_available", True) + + @powerup.setter + def powerup(self, value): + """Set DAC chn powerup""" + if value in self.powerup_available: + self._set_iio_attr(self.name, "powerup", True, value) + else: + raise ValueError( + "Error: powerup setting not supported \nUse one of: " + + str(self.powerup_available) + ) + + @property + def range(self): + """Get output range""" + return self._get_iio_attr(self.name, "range", True) + + @property + def range_available(self): + """Get list of all output ranges""" + return self._get_iio_attr_str(self.name, "range_available", True) + + @range.setter + def range(self, value): + """Set DAC chn range""" + if value in self.range_available: + self._set_iio_attr(self.name, "range", True, value) + else: + raise ValueError( + "Error: range setting not supported \nUse one of: " + + str(self.range_available) + ) diff --git a/doc/source/devices/adi.ad5754r.rst b/doc/source/devices/adi.ad5754r.rst new file mode 100644 index 000000000..d5325e9fa --- /dev/null +++ b/doc/source/devices/adi.ad5754r.rst @@ -0,0 +1,7 @@ +ad5754r +================= + +.. automodule:: adi.ad5754r + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/devices/index.rst b/doc/source/devices/index.rst index 51ca275ea..1c88deb56 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.ad5754r adi.ad5940 adi.ad6676 adi.ad7124 diff --git a/examples/ad5754r_example.py b/examples/ad5754r_example.py new file mode 100644 index 000000000..0cc090350 --- /dev/null +++ b/examples/ad5754r_example.py @@ -0,0 +1,48 @@ +# 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 + +# Set up AD5754R +ad578x_dev = adi.ad5754r(uri="serial:COM46,230400,8n1n") +ad578x.int_ref_powerup = "powerup" + +# Configure channel 0 +chn_num = 0 +ad5754r_chan = ad5754r_dev.channel[chn_num] +ad5754r_chan.powerup = "powerup" + +raw = int(ad5754r_chan.raw) +scale = float(ad5754r_chan.scale) +offset = int(ad5754r_chan.offset) +print(f"Channel{chn_num} voltage: {(raw + offset) * scale}") diff --git a/supported_parts.md b/supported_parts.md index c4d430d98..ba969cd6a 100644 --- a/supported_parts.md +++ b/supported_parts.md @@ -55,6 +55,7 @@ - AD5695R - AD5696 - AD5696R +- AD5754R - AD5940 - AD6676 - AD7124 diff --git a/test/emu/devices/ad5754r.xml b/test/emu/devices/ad5754r.xml new file mode 100644 index 000000000..2bb4f8d03 --- /dev/null +++ b/test/emu/devices/ad5754r.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 43841da98..4ef7e4c76 100644 --- a/test/emu/hardware_map.yml +++ b/test/emu/hardware_map.yml @@ -350,6 +350,15 @@ ad5592r: - filename: ad5592r.xml - data_devices: - iio:device0 + +ad5754r: + - ad5754r + - pyadi_iio_class_support: + - ad5754r + - emulate: + - filename: ad5754r.xml + - data_devices: + - iio:device0 ad7291: - ad7291 diff --git a/test/test_ad5754r.py b/test/test_ad5754r.py new file mode 100644 index 000000000..d0cac293f --- /dev/null +++ b/test/test_ad5754r.py @@ -0,0 +1,53 @@ +import adi +import pytest + +hardware = "ad5754r" +classname = "adi.ad5754r" + +######################################### +@pytest.mark.iio_hardware(hardware) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize( + "attr, val", + [ + ("int_ref_powerup", ["powerdown", "powerup"],), + ("clear_setting", ["0v", "midscale_code"],), + ("sdo_disable", ["enable", "disable"],), + ], +) +def test_ad5754r_global_attr( + test_attribute_multipe_values, iio_uri, classname, attr, val +): + test_attribute_multipe_values(iio_uri, classname, attr, val, 0) + + +######################################### +@pytest.mark.iio_hardware(hardware) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize("channel", [0, 1, 2, 3]) +@pytest.mark.parametrize( + "attr, val", + [ + ("powerup", ["powerdown", "powerup"],), + ( + "range", + [ + "0v_to_5v", + "0v_to_10v", + "0v_to_10v8", + "neg5v_to_5v", + "neg10v_to_10v", + "neg10v8_to_10v8", + ], + ), + ], +) +def test_ad5754r_channel_attr(iio_uri, classname, channel, attr, val): + dev = adi.ad5754r(iio_uri) + assert dev + dev_chan = dev.channel[channel] + assert dev_chan + for value in val: + eval(f'dev_chan.{attr} = "{value}"') + val_read = eval(f"dev_chan.{attr}") + assert val_read == value