Skip to content

Commit 0c4b6f1

Browse files
committed
ad4880: add pyadi support
Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
1 parent 80796c5 commit 0c4b6f1

File tree

9 files changed

+218
-0
lines changed

9 files changed

+218
-0
lines changed

adi/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from adi.ad4170 import ad4170
2121
from adi.ad4630 import ad4630, adaq42xx
2222
from adi.ad4858 import ad4858
23+
from adi.ad4880 import ad4880
2324
from adi.ad5592r import ad5592r
2425
from adi.ad5686 import ad5686
2526
from adi.ad5754r import ad5754r

adi/ad4880.py

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# Copyright (C) 2022-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 ad4880(rx, context_manager):
11+
12+
""" AD4880 ADC """
13+
14+
_complex_data = False
15+
channel = [] # type: ignore
16+
_device_name = ""
17+
18+
def __init__(self, uri="", device_name="ad4880"):
19+
20+
"""Initialize."""
21+
context_manager.__init__(self, uri, self._device_name)
22+
23+
compatible_part = "ad4880"
24+
self._ctrl = None
25+
26+
if not device_name:
27+
device_name = compatible_part
28+
else:
29+
if device_name != compatible_part:
30+
raise Exception(f"Not a compatible device: {device_name}")
31+
32+
# Select the device matching device_name as working device
33+
for device in self._ctx.devices:
34+
if device.name == device_name:
35+
self._ctrl = device
36+
self._rxadc = device
37+
break
38+
39+
if not self._ctrl:
40+
raise Exception("Error in selecting matching device")
41+
42+
if not self._rxadc:
43+
raise Exception("Error in selecting matching device")
44+
45+
self._rx_channel_names = []
46+
self.channel = []
47+
for ch in self._ctrl.channels:
48+
name = ch._id
49+
self._rx_channel_names.append(name)
50+
self.channel.append(self._channel(self._ctrl, name))
51+
52+
rx.__init__(self)
53+
54+
class _channel(attribute):
55+
def __init__(self, ctrl, channel_name):
56+
self.name = channel_name
57+
self._ctrl = ctrl
58+
59+
@property
60+
def scale(self):
61+
"""scale: Scale value"""
62+
return self._get_iio_attr(self.name, "scale", False)
63+
64+
@property
65+
def lvds_cnv(self):
66+
"""scale: Scale value"""
67+
return self._get_iio_attr(self.name, "lvds_cnv", False)
68+
69+
@lvds_cnv.setter
70+
def lvds_cnv(self, calibscale):
71+
""""""
72+
self._set_iio_attr(self.name, "lvds_cnv", False, calibscale, self._ctrl)
73+
74+
@property
75+
def lvds_sync(self):
76+
""""""
77+
return self._get_iio_attr(self.name, "lvds_sync", False)
78+
79+
@lvds_sync.setter
80+
def calibscale(self, calibscale):
81+
"""Set calibration scale value."""
82+
self._set_iio_attr(self.name, "lvds_sync", False, calibscale, self._ctrl)
83+
84+
@property
85+
def sampling_frequency(self):
86+
"""sampling_frequency: Sampling frequency value"""
87+
return self._get_iio_dev_attr("sampling_frequency", False)
88+
89+
@property
90+
def sinc_dec_rate_available(self):
91+
""""""
92+
return self._get_iio_dev_attr("sinc_dec_rate_available", False)
93+
94+
@property
95+
def sinc_dec_rate(self):
96+
""""""
97+
return self._get_iio_dev_attr("sinc_dec_rate", False)
98+
99+
@sinc_dec_rate.setter
100+
def sinc_dec_rate(self, value):
101+
self._set_iio_dev_attr("sinc_dec_rate", value)
102+
103+
@property
104+
def filter_sel_available(self):
105+
""""""
106+
return self._get_iio_dev_attr_str("filter_sel_available", False)
107+
108+
@property
109+
def filter_sel(self):
110+
""""""
111+
return self._get_iio_dev_attr_str("filter_sel", False)
112+
113+
@filter_sel.setter
114+
def filter_sel(self, value):
115+
self._set_iio_dev_attr_str("filter_sel", value)

doc/source/devices/adi.ad4880.rst

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
ad4880
2+
=================
3+
4+
.. automodule:: adi.ad4880
5+
:members:
6+
:undoc-members:
7+
:show-inheritance:

doc/source/devices/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Supported Devices
1818
adi.ad4170
1919
adi.ad4630
2020
adi.ad469x
21+
adi.ad4880
2122
adi.ad5592r
2223
adi.ad5627
2324
adi.ad5686

examples/ad4880_example.py

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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+
from adi import ad4880
39+
40+
# Optionally pass URI as command line argument,
41+
# else use default ip:analog.local
42+
my_uri = sys.argv[1] if len(sys.argv) >= 2 else "ip:analog.local"
43+
print("uri: " + str(my_uri))
44+
45+
my_adc = ad4880(uri=my_uri, device_name="ad4880")
46+
47+
48+
my_adc.rx_enabled_channels = [0, 1, 2, 3, 4, 5]
49+
50+
print("Sampling frequency: ", my_adc.sampling_frequency)
51+
# print("Test mode: ", my_adc.test_mode)
52+
print("Scale: ", my_adc.scale)
53+
54+
plt.clf()
55+
# Collect data
56+
data = my_adc.rx()
57+
58+
for i, d in enumerate(data):
59+
plt.plot(d, label=my_adc._rx_channel_names[my_adc.rx_enabled_channels[i]])
60+
plt.xlabel("Data Point")
61+
plt.ylabel("ADC counts")
62+
plt.legend(
63+
bbox_to_anchor=(0.0, 1.02, 1.0, 0.102),
64+
loc="lower left",
65+
ncol=4,
66+
mode="expand",
67+
borderaxespad=0.0,
68+
)
69+
70+
plt.show()
71+
del my_adc

supported_parts.md

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
- AD4696
3535
- AD4697
3636
- AD4698
37+
- AD4880
3738
- AD5310R
3839
- AD5311R
3940
- AD5592R

test/emu/devices/ad4880.xml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
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.248 Linux analog 6.1.0-271838-g69fc41f0840e-dirty #11 SMP PREEMPT Wed Jan 15 17:36:35 EET 2025 armv7l" ><context-attribute name="hdl_system_id" value="[ad488x_fmc_evb] on [zed] git branch [dev_ad4880] git [d3d3fc1afff25028fa728ee5f50e95d664c7ee31] dirty [2025-01-15 13:50:03] UTC" /><context-attribute name="hw_model" value="EVAL-AD4880-FMCZU1 on Xilinx Zynq ZED" /><context-attribute name="hw_carrier" value="Xilinx Zynq ZED" /><context-attribute name="hw_mezzanine" value="EVAL-AD4880-FMCZU1" /><context-attribute name="hw_name" value="EVAL-AD4880-FMCZ-U1" /><context-attribute name="hw_vendor" value="Analog Devices" /><context-attribute name="hw_serial" value="Empty Field" /><context-attribute name="local,kernel" value="6.1.0-271838-g69fc41f0840e-dirty" /><context-attribute name="uri" value="ip:10.48.65.248" /><context-attribute name="ip,ip-addr" value="10.48.65.248" /><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="xadc" ><channel id="voltage5" name="vccoddr" type="input" ><attribute name="label" filename="in_voltage5_vccoddr_label" value="vccoddr" /><attribute name="raw" filename="in_voltage5_vccoddr_raw" value="2038" /><attribute name="scale" filename="in_voltage5_vccoddr_scale" value="0.732421875" /></channel><channel id="voltage0" name="vccint" type="input" ><attribute name="label" filename="in_voltage0_vccint_label" value="vccint" /><attribute name="raw" filename="in_voltage0_vccint_raw" value="1387" /><attribute name="scale" filename="in_voltage0_vccint_scale" value="0.732421875" /></channel><channel id="voltage4" name="vccpaux" type="input" ><attribute name="label" filename="in_voltage4_vccpaux_label" value="vccpaux" /><attribute name="raw" filename="in_voltage4_vccpaux_raw" value="2451" /><attribute name="scale" filename="in_voltage4_vccpaux_scale" value="0.732421875" /></channel><channel id="temp0" type="input" ><attribute name="offset" filename="in_temp0_offset" value="-2219" /><attribute name="raw" filename="in_temp0_raw" value="2626" /><attribute name="scale" filename="in_temp0_scale" value="123.040771484" /></channel><channel id="voltage7" name="vrefn" type="input" ><attribute name="label" filename="in_voltage7_vrefn_label" value="vrefn" /><attribute name="raw" filename="in_voltage7_vrefn_raw" value="5" /><attribute name="scale" filename="in_voltage7_vrefn_scale" value="0.732421875" /></channel><channel id="voltage1" name="vccaux" type="input" ><attribute name="label" filename="in_voltage1_vccaux_label" value="vccaux" /><attribute name="raw" filename="in_voltage1_vccaux_raw" value="2451" /><attribute name="scale" filename="in_voltage1_vccaux_scale" value="0.732421875" /></channel><channel id="voltage2" name="vccbram" type="input" ><attribute name="label" filename="in_voltage2_vccbram_label" value="vccbram" /><attribute name="raw" filename="in_voltage2_vccbram_raw" value="1391" /><attribute name="scale" filename="in_voltage2_vccbram_scale" value="0.732421875" /></channel><channel id="voltage3" name="vccpint" type="input" ><attribute name="label" filename="in_voltage3_vccpint_label" value="vccpint" /><attribute name="raw" filename="in_voltage3_vccpint_raw" value="1387" /><attribute name="scale" filename="in_voltage3_vccpint_scale" value="0.732421875" /></channel><channel id="voltage6" name="vrefp" type="input" ><attribute name="label" filename="in_voltage6_vrefp_label" value="vrefp" /><attribute name="raw" filename="in_voltage6_vrefp_raw" value="1713" /><attribute name="scale" filename="in_voltage6_vrefp_scale" value="0.732421875" /></channel><attribute name="sampling_frequency" value="961538" /><attribute name="waiting_for_supplier" value="0" /></device><device id="iio:device1" name="one-bit-adc-dac" ><channel id="voltage0" type="output" ><attribute name="label" filename="out_voltage0_label" value="SYNC_N" /><attribute name="raw" filename="out_voltage0_raw" value="0" /></channel><attribute name="waiting_for_supplier" value="0" /></device><device id="iio:device2" 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:device3" name="ad9508" ><channel id="altvoltage3" name="CLK_A" type="output" ><attribute name="frequency" filename="out_altvoltage3_CLK_A_frequency" value="400000000" /><attribute name="label" filename="out_altvoltage3_CLK_A_label" value="CLK_A" /><attribute name="phase" filename="out_altvoltage3_CLK_A_phase" value="0.000000" /><attribute name="raw" filename="out_altvoltage3_CLK_A_raw" value="1" /></channel><channel id="altvoltage0" name="CNV_B" type="output" ><attribute name="frequency" filename="out_altvoltage0_CNV_B_frequency" value="40000000" /><attribute name="label" filename="out_altvoltage0_CNV_B_label" value="CNV_B" /><attribute name="phase" filename="out_altvoltage0_CNV_B_phase" value="0.000000" /><attribute name="raw" filename="out_altvoltage0_CNV_B_raw" value="1" /></channel><channel id="altvoltage1" name="CLK_B" type="output" ><attribute name="frequency" filename="out_altvoltage1_CLK_B_frequency" value="400000000" /><attribute name="label" filename="out_altvoltage1_CLK_B_label" value="CLK_B" /><attribute name="phase" filename="out_altvoltage1_CLK_B_phase" value="0.000000" /><attribute name="raw" filename="out_altvoltage1_CLK_B_raw" value="1" /></channel><channel id="altvoltage2" name="CNV_A" type="output" ><attribute name="frequency" filename="out_altvoltage2_CNV_A_frequency" value="40000000" /><attribute name="label" filename="out_altvoltage2_CNV_A_label" value="CNV_A" /><attribute name="phase" filename="out_altvoltage2_CNV_A_phase" value="0.000000" /><attribute name="raw" filename="out_altvoltage2_CNV_A_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:device6" name="ad4880" ><channel id="voltage0" type="input" ><scan-element index="0" format="le:S20/32&gt;&gt;0" scale="0.000006" /><attribute name="lvds_cnv" filename="in_voltage0_lvds_cnv" value="1" /><attribute name="lvds_sync" filename="in_voltage0_lvds_sync" value="enable" /><attribute name="scale" filename="in_voltage0_scale" value="0.000005722" /></channel><channel id="voltage1" type="input" ><scan-element index="1" format="le:S20/32&gt;&gt;0" scale="0.000006" /><attribute name="lvds_cnv" filename="in_voltage1_lvds_cnv" value="1" /><attribute name="lvds_sync" filename="in_voltage1_lvds_sync" value="enable" /><attribute name="scale" filename="in_voltage1_scale" value="0.000005722" /></channel><attribute name="filter_sel" value="disabled" /><attribute name="filter_sel_available" value="disabled sinc1 sinc5 sinc5_plus_compensation" /><attribute name="sampling_frequency" value="40000000" /><attribute name="sinc_dec_rate" value="2" /><attribute name="sinc_dec_rate_available" value="2 4 8 16 32 64 128 256 512 1024" /><attribute name="sync_start_enable" value="disarm" /><attribute name="sync_start_enable_available" value="arm" /><attribute name="waiting_for_supplier" value="0" /><buffer-attribute name="data_available" value="0" /><buffer-attribute name="direction" value="in" /><buffer-attribute name="length_align_bytes" value="8" /><debug-attribute name="pseudorandom_err_check" value="CH0 : PN9 : In Sync : OK" /><debug-attribute name="direct_reg_access" value="0x10" /></device><device id="iio:device7" name="ad4880_chb" ><channel id="voltage0" type="input" ><attribute name="lvds_cnv" filename="in_voltage0_lvds_cnv" value="1" /><attribute name="lvds_sync" filename="in_voltage0_lvds_sync" value="enable" /><attribute name="scale" filename="in_voltage0_scale" value="0.000005722" /></channel><channel id="voltage1" type="input" ><attribute name="lvds_cnv" filename="in_voltage1_lvds_cnv" value="1" /><attribute name="lvds_sync" filename="in_voltage1_lvds_sync" value="enable" /><attribute name="scale" filename="in_voltage1_scale" value="0.000005722" /></channel><attribute name="filter_sel" value="disabled" /><attribute name="filter_sel_available" value="disabled sinc1 sinc5 sinc5_plus_compensation" /><attribute name="sampling_frequency" value="40000000" /><attribute name="sinc_dec_rate" value="2" /><attribute name="sinc_dec_rate_available" value="2 4 8 16 32 64 128 256 512 1024" /><attribute name="sync_start_enable" value="disarm" /><attribute name="sync_start_enable_available" value="arm" /><attribute name="waiting_for_supplier" value="0" /><debug-attribute name="pseudorandom_err_check" value="CH0 : PN9 : In Sync : OK
2+
CH1 : UNDEF : In Sync : PN Error" /><debug-attribute name="direct_reg_access" value="0x10" /></device><device id="iio_sysfs_trigger" ><attribute name="add_trigger" value="ERROR" /><attribute name="remove_trigger" value="ERROR" /></device></context>

test/emu/hardware_map.yml

+8
Original file line numberDiff line numberDiff line change
@@ -703,3 +703,11 @@ ad738x:
703703
- data_devices:
704704
- iio:device0
705705

706+
ad4080:
707+
- ad4080
708+
- pyadi_iio_class_support:
709+
- ad4080
710+
- emulate:
711+
- filename: ad4080.xml
712+
- data_devices:
713+
- iio:device6

test/test_ad4880.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import pytest
2+
3+
hardware = ["ad4880"]
4+
classname = ["adi.ad4880"]
5+
6+
7+
#########################################
8+
@pytest.mark.iio_hardware(hardware, True)
9+
@pytest.mark.parametrize("classname", [(classname)])
10+
@pytest.mark.parametrize("channel", [0, 1])
11+
def test_ad4880_rx_data(test_dma_rx, iio_uri, classname, channel):
12+
test_dma_rx(iio_uri, classname, channel)

0 commit comments

Comments
 (0)