diff --git a/adi/__init__.py b/adi/__init__.py index f521b1292..6d5332f68 100644 --- a/adi/__init__.py +++ b/adi/__init__.py @@ -8,6 +8,7 @@ from adi.ad579x import ad579x from adi.ad717x import ad717x from adi.ad719x import ad719x +from adi.ad738x import ad738x from adi.ad777x import ad777x from adi.ad936x import Pluto, ad9361, ad9363, ad9364 from adi.ad937x import ad9371, ad9375 diff --git a/adi/ad738x.py b/adi/ad738x.py new file mode 100644 index 000000000..eaadd83aa --- /dev/null +++ b/adi/ad738x.py @@ -0,0 +1,118 @@ +# Copyright (C) 2024 Analog Devices, Inc. +# +# SPDX short identifier: ADIBSD + +from decimal import Decimal + +import numpy as np +from adi.attribute import attribute +from adi.context_manager import context_manager +from adi.rx_tx import rx + + +class ad738x(rx, context_manager): + + """ AD738x ADC """ + + _complex_data = False + channel = [] # type: ignore + _device_name = "" + + def __init__(self, uri="", device_name="ad7381"): + """Constructor for AD738x class.""" + context_manager.__init__(self, uri, self._device_name) + + compatible_parts = [ + "ad7380", + "ad7380-4", + "ad7389-4", + "ad7381", + "ad7381-4", + "ad7383", + "ad7384", + "ad7386", + "ad7387", + "ad7388", + "ad4680", + "ad4681", + "ad4682", + "ad4683", + ] + + self._ctrl = None + + if not device_name: + device_name = compatible_parts[0] + else: + if device_name not in compatible_parts: + raise Exception("Not a compatible device: " + device_name) + + # Select the device matching device_name as working device + for device in self._ctx.devices: + if device.name == device_name: + self._ctrl = device + self._rxadc = device + break + + if not self._ctrl: + raise Exception("Error in selecting matching device") + + if not self._rxadc: + raise Exception("Error in selecting matching device") + + self._rx_channel_names = [] + self.channel = [] + for ch in self._ctrl.channels: + name = ch._id + self._rx_channel_names.append(name) + self.channel.append(self._channel(self._ctrl, name)) + + rx.__init__(self) + + class _channel(attribute): + + """ AD738x channel """ + + def __init__(self, ctrl, channel_name): + self.name = channel_name + self._ctrl = ctrl + + @property + def raw(self): + """AD738x channel raw value.""" + return self._get_iio_attr(self.name, "raw", False) + + @property + def scale(self): + """AD738x channel scale.""" + return float(self._get_iio_attr_str(self.name, "scale", False)) + + @scale.setter + def scale(self, value): + self._set_iio_attr(self.name, "scale", False, str(Decimal(value).real)) + + @property + def offset(self): + """AD738x channel offset.""" + return float(self._get_iio_attr_str(self.name, "offset", False)) + + @offset.setter + def offset(self, value): + self._set_iio_attr(self.name, "offset", False, str(Decimal(value).real)) + + def to_volts(self, index, val): + """Converts raw value to SI.""" + _scale = self.channel[index].scale + + ret = None + + if isinstance(val, np.int32): + ret = val * _scale + + if isinstance(val, np.ndarray): + ret = [x * _scale for x in val] + + if ret is None: + raise Exception("Error in converting to actual voltage") + + return ret diff --git a/doc/source/devices/adi.ad738x.rst b/doc/source/devices/adi.ad738x.rst new file mode 100644 index 000000000..4bc2e9baf --- /dev/null +++ b/doc/source/devices/adi.ad738x.rst @@ -0,0 +1,7 @@ +ad738x +================= + +.. automodule:: adi.ad738x + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/devices/index.rst b/doc/source/devices/index.rst index 0401722cf..fff19a767 100644 --- a/doc/source/devices/index.rst +++ b/doc/source/devices/index.rst @@ -28,6 +28,7 @@ Supported Devices adi.ad717x adi.ad719x adi.ad7291 + adi.ad738x adi.ad7606 adi.ad7689 adi.ad7746 diff --git a/examples/ad738x_example.py b/examples/ad738x_example.py new file mode 100644 index 000000000..e92cf047b --- /dev/null +++ b/examples/ad738x_example.py @@ -0,0 +1,19 @@ +# Copyright (C) 2022 Analog Devices, Inc. +# +# SPDX short identifier: ADIBSD +import sys + +import adi +import numpy as np + +my_uri = sys.argv[1] if len(sys.argv) >= 2 else "ip:analog.local" +print("uri: " + str(my_uri)) + +ad738x_dev = adi.ad738x(uri=my_uri, device_name="ad7381") +ad738x_dev.rx_annotated = True +ad738x_dev.rx_output_type = "SI" +ad738x_dev.rx_enabled_channels = [1, 2] + +data = ad738x_dev.rx() + +print(data) diff --git a/supported_parts.md b/supported_parts.md index e20cb0d5e..14a4d7ca1 100644 --- a/supported_parts.md +++ b/supported_parts.md @@ -201,3 +201,4 @@ - MAX31865 - MAX9611 - AD7690 +- AD738x (AD7380, AD7380-4, AD7381, AD7381-4, AD7389-4, AD7383, AD7384, AD7385, AD7386, AD7387, AD7388, AD4680, AD4681, AD4682, AD4683) diff --git a/test/emu/devices/ad7381.xml b/test/emu/devices/ad7381.xml new file mode 100644 index 000000000..fdd9a73b7 --- /dev/null +++ b/test/emu/devices/ad7381.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 ce4f03655..74a93f9e1 100644 --- a/test/emu/hardware_map.yml +++ b/test/emu/hardware_map.yml @@ -583,7 +583,7 @@ lm75: - filename: lm75.xml - data_devices: - hwmon0 - + ad405x: - ad4052 - pyadi_iio_class_support: @@ -610,3 +610,13 @@ ad4170: - filename: ad4170.xml - data_devices: - iio:device0 + +ad738x: + - ad738x + - pyadi_iio_class_support: + - ad738x + - emulate: + - filename: ad7381.xml + - data_devices: + - iio:device0 + diff --git a/test/test_ad738x.py b/test/test_ad738x.py new file mode 100644 index 000000000..263ce309b --- /dev/null +++ b/test/test_ad738x.py @@ -0,0 +1,11 @@ +import pytest + +hardware = "ad738x" +classname = "adi.ad738x" + +######################################### +@pytest.mark.iio_hardware(hardware, True) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize("channel", [1]) +def test_ad738x_rx_data(test_dma_rx, iio_uri, classname, channel): + test_dma_rx(iio_uri, classname, channel)