Skip to content

Commit c5a07b4

Browse files
committed
ad4080: add pyadi-iio support
Add support for ad4080. Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
1 parent 9653f85 commit c5a07b4

File tree

9 files changed

+215
-0
lines changed

9 files changed

+215
-0
lines changed

adi/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from adi.ad3552r import ad3552r
1717
from adi.ad3552r_hs import ad3552r_hs
1818
from adi.ad4020 import ad4000, ad4001, ad4002, ad4003, ad4020
19+
from adi.ad4080 import ad4080
1920
from adi.ad4110 import ad4110
2021
from adi.ad4130 import ad4130
2122
from adi.ad4170 import ad4170

adi/ad4080.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Copyright (C) 2025 Analog Devices, Inc.
2+
#
3+
# SPDX short identifier: ADIBSD
4+
5+
from adi.attribute import attribute
6+
from adi.context_manager import context_manager
7+
from adi.rx_tx import rx
8+
9+
10+
class ad4080(rx, context_manager):
11+
12+
""" AD4080 ADC """
13+
14+
_complex_data = False
15+
_device_name = ""
16+
channel = [] # type: ignore
17+
18+
def __init__(self, uri="", device_name="ad4080"):
19+
context_manager.__init__(self, uri, self._device_name)
20+
21+
compatible_part = "ad4080"
22+
self._ctrl = None
23+
24+
if not device_name:
25+
device_name = compatible_part
26+
else:
27+
if device_name != compatible_part:
28+
raise Exception(f"Not a compatible device: {device_name}")
29+
30+
# Select the device matching device_name as working device
31+
for device in self._ctx.devices:
32+
if device.name == device_name:
33+
self._ctrl = device
34+
self._rxadc = device
35+
break
36+
37+
# Raise an exception if the device isn't found
38+
if not self._ctrl:
39+
raise Exception("AD4080 device not found")
40+
41+
if not self._rxadc:
42+
raise Exception("Error in selecting matching device")
43+
44+
self._rx_channel_names = []
45+
self.channel = []
46+
for ch in self._ctrl.channels:
47+
name = ch.id
48+
self._rx_channel_names.append(name)
49+
self.channel.append(self._channel(self._ctrl, name))
50+
51+
rx.__init__(self)
52+
53+
class _channel(attribute):
54+
"""AD4080 channel"""
55+
56+
def __init__(self, ctrl, channel_name):
57+
self.name = channel_name
58+
self._ctrl = ctrl
59+
60+
@property
61+
def scale(self):
62+
"""Get Scale value"""
63+
return self._get_iio_attr("voltage0", "scale", False)
64+
65+
@property
66+
def sampling_frequency(self):
67+
"""Get Sampling frequency value"""
68+
return self._get_iio_dev_attr("sampling_frequency", False)
69+
70+
@property
71+
def oversampling_ratio_available(self):
72+
"""Get the oversampling ratio available values"""
73+
return self._get_iio_dev_attr("oversampling_ratio_available", False)
74+
75+
@property
76+
def oversampling_ratio(self):
77+
"""Get the oversampling ratio value"""
78+
return self._get_iio_dev_attr("oversampling_ratio", False)
79+
80+
@oversampling_ratio.setter
81+
def oversampling_ratio(self, value):
82+
"""Set the oversampling ratio value"""
83+
self._set_iio_dev_attr("oversampling_ratio", value)
84+
85+
@property
86+
def filter_type_available(self):
87+
"""Get the filter type available values"""
88+
return self._get_iio_dev_attr_str("filter_type_available", False)
89+
90+
@property
91+
def filter_type(self):
92+
"""Get the filter type value"""
93+
return self._get_iio_dev_attr_str("filter_type")
94+
95+
@filter_type.setter
96+
def filter_type(self, value):
97+
"""Set the filter type value"""
98+
self._set_iio_dev_attr_str("filter_type", value)
99+
100+
def reg_read(self, reg):
101+
"""Direct Register Access via debugfs"""
102+
self._set_iio_debug_attr_str("direct_reg_access", reg, self._ctrl)
103+
return self._get_iio_debug_attr_str("direct_reg_access", self._ctrl)
104+
105+
def reg_write(self, reg, value):
106+
"""Direct Register Access via debugfs"""
107+
self._set_iio_debug_attr_str("direct_reg_access", f"{reg} {value}", self._ctrl)

doc/source/devices/adi.ad4080.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
ad4080
2+
=================
3+
4+
.. automodule:: adi.ad4080
5+
:members:
6+
:undoc-members:
7+
:show-inheritance:

doc/source/devices/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Supported Devices
1414
adi.ad3552r_hs
1515
adi.ad4020
1616
adi.ad405x
17+
adi.ad4080
1718
adi.ad4110
1819
adi.ad4130
1920
adi.ad4170

examples/ad4080_example.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Copyright (C) 2025 Analog Devices, Inc.
2+
#
3+
# All rights reserved.
4+
#
5+
# Redistribution and use in source and binary forms, with or without modification,
6+
# are permitted provided that the following conditions are met:
7+
# - Redistributions of source code must retain the above copyright
8+
# notice, this list of conditions and the following disclaimer.
9+
# - Redistributions in binary form must reproduce the above copyright
10+
# notice, this list of conditions and the following disclaimer in
11+
# the documentation and/or other materials provided with the
12+
# distribution.
13+
# - Neither the name of Analog Devices, Inc. nor the names of its
14+
# contributors may be used to endorse or promote products derived
15+
# from this software without specific prior written permission.
16+
# - The use of this software may or may not infringe the patent rights
17+
# of one or more patent holders. This license does not release you
18+
# from the requirement that you obtain separate licenses from these
19+
# patent holders to use this software.
20+
# - Use of the software either in source or binary form, must be run
21+
# on or directly connected to an Analog Devices Inc. component.
22+
#
23+
# THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24+
# INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
25+
# PARTICULAR PURPOSE ARE DISCLAIMED.
26+
#
27+
# IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
29+
# RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30+
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
32+
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33+
34+
import sys
35+
36+
import matplotlib.pyplot as plt
37+
import numpy as np
38+
39+
from adi import ad4080
40+
41+
# Optionally pass URI as command line argument,
42+
# else use default ip:analog.local
43+
my_uri = sys.argv[1] if len(sys.argv) >= 2 else "ip:analog.local"
44+
print("uri: " + str(my_uri))
45+
46+
my_adc = ad4080(uri=my_uri)
47+
48+
print("Sampling frequency: ", my_adc.sampling_frequency)
49+
print("Filter type: ", my_adc.filter_type)
50+
print("Scale: ", my_adc.channel[0].scale)
51+
print("Oversampling ratio: ", my_adc.oversampling_ratio)
52+
53+
plt.clf()
54+
# Collect data
55+
data = my_adc.rx()
56+
57+
plt.plot(range(0, len(data)), data, label="channel0")
58+
plt.xlabel("Data Point")
59+
plt.ylabel("ADC counts")
60+
plt.legend(
61+
bbox_to_anchor=(0.0, 1.02, 1.0, 0.102),
62+
loc="lower left",
63+
ncol=4,
64+
mode="expand",
65+
borderaxespad=0.0,
66+
)
67+
68+
plt.show()

supported_parts.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
- AD4003 (AD4007, AD4011)
2121
- AD4020
2222
- AD405x
23+
- AD4080
2324
- AD4130
2425
- AD4110
2526
- AD4111

test/emu/devices/ad4080.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE context [<!ELEMENT context (device | context-attribute)*><!ELEMENT context-attribute EMPTY><!ELEMENT device (channel | attribute | debug-attribute | buffer-attribute)*><!ELEMENT channel (scan-element?, attribute*)><!ELEMENT attribute EMPTY><!ELEMENT scan-element EMPTY><!ELEMENT debug-attribute EMPTY><!ELEMENT buffer-attribute EMPTY><!ATTLIST context name CDATA #REQUIRED description CDATA #IMPLIED><!ATTLIST context-attribute name CDATA #REQUIRED value CDATA #REQUIRED><!ATTLIST device id CDATA #REQUIRED name CDATA #IMPLIED><!ATTLIST channel id CDATA #REQUIRED type (input|output) #REQUIRED name CDATA #IMPLIED><!ATTLIST scan-element index CDATA #REQUIRED format CDATA #REQUIRED scale CDATA #IMPLIED><!ATTLIST attribute name CDATA #REQUIRED filename CDATA #IMPLIED value CDATA #IMPLIED><!ATTLIST debug-attribute name CDATA #REQUIRED value CDATA #IMPLIED><!ATTLIST buffer-attribute name CDATA #REQUIRED value CDATA #IMPLIED>]><context name="network" description="10.48.65.239 Linux analog 6.15.0-rc1-00274-gf1bd9f3b3978 #258 SMP PREEMPT Tue May 20 14:37:17 EEST 2025 armv7l" ><context-attribute name="hw_model" value="EVAL-AD4080-FMCZ on Xilinx Zynq ZED" /><context-attribute name="hw_carrier" value="Xilinx Zynq ZED" /><context-attribute name="hdl_system_id" value="[ad408x_fmc_evb] on [zed] git branch [dev_segura] git [97dda1eb9101a238f13f40991cd25452e6536611] dirty [2025-05-12 11:17:41] UTC" /><context-attribute name="hw_mezzanine" value="EVAL-AD4080-FMCZ" /><context-attribute name="hw_name" value="EVAL-AD4080-FMCZ" /><context-attribute name="hw_vendor" value="Analog Devices" /><context-attribute name="hw_serial" value="Empty Field" /><context-attribute name="local,kernel" value="6.15.0-rc1-00274-gf1bd9f3b3978" /><context-attribute name="uri" value="ip:10.48.65.239" /><context-attribute name="ip,ip-addr" value="10.48.65.239" /><device id="hwmon0" name="e000b000ethernetffffffff00" ><channel id="temp1" type="input" ><attribute name="crit" filename="temp1_crit" value="100000" /><attribute name="input" filename="temp1_input" value="41000" /><attribute name="max_alarm" filename="temp1_max_alarm" value="0" /></channel></device><device id="iio:device0" name="/axi/spi@e0007000/adf4350@1" ><channel id="altvoltage0" type="output" ><attribute name="frequency" filename="out_altvoltage0_frequency" value="400000000" /><attribute name="frequency_resolution" filename="out_altvoltage0_frequency_resolution" value="100000" /><attribute name="powerdown" filename="out_altvoltage0_powerdown" value="0" /><attribute name="refin_frequency" filename="out_altvoltage0_refin_frequency" value="25000000" /></channel><attribute name="waiting_for_supplier" value="0" /><debug-attribute name="direct_reg_access" value="0x400000" /></device><device id="iio:device1" name="ad9508" ><channel id="altvoltage3" name="MACH1_CLK" type="output" ><attribute name="frequency" filename="out_altvoltage3_MACH1_CLK_frequency" value="400000000" /><attribute name="label" filename="out_altvoltage3_MACH1_CLK_label" value="MACH1_CLK" /><attribute name="phase" filename="out_altvoltage3_MACH1_CLK_phase" value="0.000000" /><attribute name="raw" filename="out_altvoltage3_MACH1_CLK_raw" value="1" /></channel><channel id="altvoltage1" name="CLK10M" type="output" ><attribute name="frequency" filename="out_altvoltage1_CLK10M_frequency" value="10000000" /><attribute name="label" filename="out_altvoltage1_CLK10M_label" value="CLK10M" /><attribute name="phase" filename="out_altvoltage1_CLK10M_phase" value="0.000000" /><attribute name="raw" filename="out_altvoltage1_CLK10M_raw" value="1" /></channel><channel id="altvoltage2" name="CNV" type="output" ><attribute name="frequency" filename="out_altvoltage2_CNV_frequency" value="40000000" /><attribute name="label" filename="out_altvoltage2_CNV_label" value="CNV" /><attribute name="phase" filename="out_altvoltage2_CNV_phase" value="0.000000" /><attribute name="raw" filename="out_altvoltage2_CNV_raw" value="1" /></channel><channel id="altvoltage0" name="CNV_COPY" type="output" ><attribute name="frequency" filename="out_altvoltage0_CNV_COPY_frequency" value="40000000" /><attribute name="label" filename="out_altvoltage0_CNV_COPY_label" value="CNV_COPY" /><attribute name="phase" filename="out_altvoltage0_CNV_COPY_phase" value="0.000000" /><attribute name="raw" filename="out_altvoltage0_CNV_COPY_raw" value="1" /></channel><attribute name="sync_dividers" value="ERROR" /><attribute name="waiting_for_supplier" value="0" /><debug-attribute name="direct_reg_access" value="0x81" /></device><device id="iio:device2" name="ad4080" ><channel id="voltage0" type="input" ><scan-element index="0" format="le:s20/32&gt;&gt;0" scale="0.000006" /><attribute name="scale" filename="in_voltage0_scale" value="0.000005722" /></channel><attribute name="filter_type" value="none" /><attribute name="filter_type_available" value="none sinc1 sinc5 sinc5+pf1" /><attribute name="oversampling_ratio" value="1" /><attribute name="oversampling_ratio_available" value="1" /><attribute name="sampling_frequency" value="40000000" /><attribute name="waiting_for_supplier" value="0" /><buffer-attribute name="data_available" value="16384" /><buffer-attribute name="direction" value="in" /><buffer-attribute name="length_align_bytes" value="8" /><debug-attribute name="direct_reg_access" value="0x10" /></device></context>

test/emu/hardware_map.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,3 +721,11 @@ ad738x:
721721
- data_devices:
722722
- iio:device0
723723

724+
ad4080:
725+
- ad4080
726+
- pyadi_iio_class_support:
727+
- ad4080
728+
- emulate:
729+
- filename: ad4080.xml
730+
- data_devices:
731+
- iio:device2

test/test_ad4080.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import pytest
2+
3+
hardware = ["ad4080"]
4+
classname = ["adi.ad4080"]
5+
6+
#########################################
7+
@pytest.mark.iio_hardware(hardware)
8+
@pytest.mark.parametrize("classname", [(classname)])
9+
@pytest.mark.parametrize(
10+
"attr, val", [("filter_type", ["none", "sinc1", "sinc5"],),],
11+
)
12+
def test_ad4080_attr(test_attribute_multiple_values, iio_uri, classname, attr, val):
13+
test_attribute_multiple_values(iio_uri, classname, attr, val, 0)
14+
15+
16+
#########################################
17+
@pytest.mark.iio_hardware(hardware, True)
18+
@pytest.mark.parametrize("classname", [(classname)])
19+
@pytest.mark.parametrize("channel", [0])
20+
def test_ad4080_rx_data(test_dma_rx, iio_uri, classname, channel):
21+
test_dma_rx(iio_uri, classname, channel)

0 commit comments

Comments
 (0)