Skip to content

Commit a5c223f

Browse files
authored
Merge pull request #674 from analogdevicesinc/ad9084-misc-sync
2 parents 5ff7246 + 620878b commit a5c223f

15 files changed

+1185
-14
lines changed

adi/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
from adi.ada4961 import ada4961
6060
from adi.adaq8092 import adaq8092
6161
from adi.adar1000 import adar1000, adar1000_array
62+
from adi.adf4030 import adf4030
6263
from adi.adf4159 import adf4159
6364
from adi.adf4355 import adf4355
6465
from adi.adf4371 import adf4371
@@ -100,6 +101,7 @@
100101
from adi.adxl355 import adxl355
101102
from adi.adxl380 import adxl380
102103
from adi.adxrs290 import adxrs290
104+
from adi.axi_aion_trig import axi_aion_trig
103105
from adi.cn0511 import cn0511
104106
from adi.cn0532 import cn0532
105107
from adi.cn0554 import cn0554
@@ -117,6 +119,7 @@
117119
from adi.fmcomms5 import FMComms5
118120
from adi.fmcomms11 import FMComms11
119121
from adi.gen_mux import genmux
122+
from adi.hmc7044 import hmc7044
120123
from adi.lm75 import lm75
121124
from adi.ltc2314_14 import ltc2314_14
122125
from adi.ltc2387 import ltc2387

adi/ad9084.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from adi.context_manager import context_manager
99
from adi.obs import obs, remap, tx_two
1010
from adi.rx_tx import rx_tx
11-
from adi.sync_start import sync_start
11+
from adi.sync_start import sync_start, sync_start_b
1212

1313

1414
def _map_to_dict(paths, ch):
@@ -56,7 +56,7 @@ def ignorealt(w):
5656
return chans_names_out
5757

5858

59-
class ad9084(rx_tx, context_manager, sync_start):
59+
class ad9084(rx_tx, context_manager, sync_start, sync_start_b):
6060
"""AD9084 Mixed-Signal Front End (MxFE)"""
6161

6262
_complex_data = True
@@ -188,6 +188,7 @@ def __init__(
188188

189189
rx_tx.__init__(self)
190190
sync_start.__init__(self)
191+
sync_start_b.__init__(self)
191192
self.rx_buffer_size = 2 ** 16
192193

193194
def _get_iio_attr_str_single(self, channel_name, attr, output):
@@ -281,6 +282,22 @@ def rx_main_nco_phases(self, value):
281282
self._rx_coarse_ddc_channel_names, "main_nco_phase", False, value,
282283
)
283284

285+
@property
286+
def rx_main_tb1_6db_digital_gain_en(self):
287+
"""main_tb1_6db_digital_gain_en: Receive path coarse DDC NCO phases"""
288+
return self._get_iio_attr_vec(
289+
self._rx_coarse_ddc_channel_names, "main_tb1_6db_digital_gain_en", False
290+
)
291+
292+
@rx_main_tb1_6db_digital_gain_en.setter
293+
def rx_main_tb1_6db_digital_gain_en(self, value):
294+
self._set_iio_attr_int_vec(
295+
self._rx_coarse_ddc_channel_names,
296+
"main_tb1_6db_digital_gain_en",
297+
False,
298+
value,
299+
)
300+
284301
@property
285302
def rx_test_mode(self):
286303
"""rx_test_mode: NCO Test Mode"""
@@ -459,6 +476,21 @@ def tx_ddr_offload(self):
459476
def tx_ddr_offload(self, value):
460477
self._set_iio_debug_attr_str("pl_ddr_fifo_enable", str(value * 1), self._txdac)
461478

479+
@property
480+
def tx_b_ddr_offload(self):
481+
"""tx_b_ddr_offload: Enable DDR offload
482+
483+
When true the DMA will pass buffers into the BRAM FIFO for data repeating.
484+
This is necessary when operating at high DAC sample rates. This can reduce
485+
the maximum buffer size but data passed to DACs in cyclic mode will not
486+
underflow due to memory bottlenecks.
487+
"""
488+
return self._get_iio_debug_attr("pl_ddr_fifo_enable", self._txdac2)
489+
490+
@tx_b_ddr_offload.setter
491+
def tx_b_ddr_offload(self, value):
492+
self._set_iio_debug_attr_str("pl_ddr_fifo_enable", str(value * 1), self._txdac2)
493+
462494
@property
463495
def rx_sample_rate(self):
464496
"""rx_sampling_frequency: Sample rate after decimation"""

adi/adf4030.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Copyright (C) 2025 Analog Devices, Inc.
2+
#
3+
# SPDX short identifier: ADIBSD
4+
5+
6+
from adi.attribute import attribute
7+
from adi.context_manager import context_manager
8+
9+
10+
class adf4030(context_manager, attribute):
11+
"""
12+
This class provides an interface to the ADF4030 device via the IIO framework.
13+
14+
Args:
15+
uri (str, optional): URI of the IIO context. Defaults to "".
16+
17+
Attributes:
18+
_device_name (str): Name of the IIO device ("adf4030").
19+
_ctrl: Reference to the IIO device controller.
20+
_attrs (list): List of supported channel attributes.
21+
22+
Properties:
23+
in_temp0_input (float): Returns the temperature sensor input value.
24+
25+
Dynamic Channel Properties:
26+
For each channel with an ID starting with "altvoltage", the following
27+
properties are dynamically created (where <name> is the channel label
28+
or ID):
29+
30+
<name>_duty_cycle (float): Duty cycle of the channel.
31+
<name>_frequency (float): Frequency of the channel.
32+
<name>_label (str): Label of the channel.
33+
<name>_output_enable (bool): Output enable status of the channel.
34+
<name>_phase (float): Phase of the channel.
35+
<name>_reference_channel (int): Reference channel index.
36+
<name>_autoalign_iteration (int): Auto-align iteration value.
37+
<name>_autoalign_threshold (float): Auto-align threshold value.
38+
<name>_autoalign_threshold_en (bool): Enable/disable auto-align threshold.
39+
<name>_background_serial_alignment_en (bool): Enable/disable background serial alignment.
40+
<name>_oversampling_ratio (int): Oversampling ratio.
41+
<name>_oversampling_ratio_available (list): List of available oversampling ratios.
42+
43+
Raises:
44+
Exception: If the ADF4030 device is not found in the IIO context.
45+
46+
Methods:
47+
_make_channel_property(channel, attr): Creates a property for a given channel and attribute.
48+
_add_channel_properties(): Adds dynamic properties for each supported channel and attribute.
49+
50+
Example:
51+
>>> from adi.hmc7044 import adf4030
52+
>>> dev = adf4030(uri="ip:192.168.2.1")
53+
>>> print(dev.in_temp0_input)
54+
>>> dev.altvoltage0_frequency = 10000000
55+
>>> print(dev.altvoltage0_frequency)
56+
"""
57+
58+
_device_name = "adf4030"
59+
60+
def __init__(self, uri=""):
61+
context_manager.__init__(self, uri, self._device_name)
62+
self._ctrl = self._ctx.find_device(self._device_name)
63+
if not self._ctrl:
64+
raise Exception("ADF4030 device not found")
65+
self._add_channel_properties()
66+
67+
@property
68+
def in_temp0_input(self):
69+
return self._get_iio_attr("temp0", "input", False, self._ctrl)
70+
71+
def _make_channel_property(self, channel, attr):
72+
def getter(self):
73+
return self._get_iio_attr(channel, attr, True, self._ctrl)
74+
75+
def setter(self, value):
76+
self._set_iio_attr(channel, attr, True, value, self._ctrl)
77+
78+
return property(getter, setter)
79+
80+
# List of channels and their attributes
81+
_attrs = [
82+
"duty_cycle",
83+
"frequency",
84+
"label",
85+
"output_enable",
86+
"phase",
87+
"reference_channel",
88+
"autoalign_iteration",
89+
"autoalign_threshold",
90+
"autoalign_threshold_en",
91+
"background_serial_alignment_en",
92+
"oversampling_ratio",
93+
"oversampling_ratio_available",
94+
]
95+
96+
def _add_channel_properties(self):
97+
for ch in self._ctrl.channels:
98+
if not ch._id.startswith("altvoltage"):
99+
continue
100+
101+
if "label" in ch.attrs:
102+
name = ch.attrs["label"].value
103+
else:
104+
name = ch._id
105+
106+
for attr in self._attrs:
107+
prop_name = f"{name}_{attr}"
108+
setattr(
109+
self.__class__, prop_name, self._make_channel_property(ch._id, attr)
110+
)

adi/axi_aion_trig.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Copyright (C) 2025 Analog Devices, Inc.
2+
#
3+
# SPDX short identifier: ADIBSD
4+
5+
6+
from adi.attribute import attribute
7+
from adi.context_manager import context_manager
8+
9+
10+
class axi_aion_trig(context_manager, attribute):
11+
"""axi_aion_trig IIO Device Interface
12+
13+
This class provides an interface to the 'axi_aion_trig' IIO device, allowing
14+
control and monitoring of its voltage channels and associated attributes.
15+
16+
Parameters
17+
----------
18+
uri : str, optional
19+
URI of the IIO context to connect to. Defaults to an empty string.
20+
21+
Attributes (per voltage channel)
22+
--------------------------------
23+
For each voltage channel (e.g., voltage0, voltage1, ...), the following
24+
properties are dynamically created:
25+
26+
- trig{N}_en : bool
27+
Enable or disable the trigger for channel N.
28+
- trig{N}_phase : int
29+
Phase setting for channel N.
30+
- trig{N}_status : int
31+
Status of the trigger for channel N.
32+
- trig{N}_frequency : int
33+
Frequency setting for channel N.
34+
- trig{N}_internal_bsync_enable : bool
35+
Enable or disable internal bsync for channel N.
36+
- trig{N}_output_enable : bool
37+
Enable or disable output for channel N.
38+
- trig{N}_trigger_now : bool
39+
Trigger an immediate event on channel N.
40+
- trig{N}_trigger_select_gpio_enable : bool
41+
Enable or disable GPIO selection for trigger on channel N.
42+
43+
Raises
44+
------
45+
Exception
46+
If the 'axi_aion_trig' device is not found in the IIO context.
47+
48+
Examples
49+
--------
50+
>>> trig = axi_aion_trig("ip:192.168.1.100")
51+
>>> trig.trig0_en = True
52+
>>> print(trig.trig0_status)
53+
"""
54+
55+
_device_name = "axi_aion_trig"
56+
57+
def __init__(self, uri=""):
58+
context_manager.__init__(self, uri, self._device_name)
59+
self._ctrl = self._ctx.find_device(self._device_name)
60+
if not self._ctrl:
61+
raise Exception("axi_aion_trig device not found")
62+
self._add_channel_properties()
63+
64+
def _make_channel_property(self, channel, attr):
65+
def getter(self):
66+
return self._get_iio_attr(channel, attr, False, self._ctrl)
67+
68+
def setter(self, value):
69+
self._set_iio_attr(channel, attr, False, value, self._ctrl)
70+
71+
return property(getter, setter)
72+
73+
# Attributes for in_voltage channels and device properties
74+
_attrs = [
75+
"en",
76+
"phase",
77+
"status",
78+
"frequency",
79+
"internal_bsync_enable",
80+
"output_enable",
81+
"trigger_now",
82+
"trigger_select_gpio_enable",
83+
]
84+
85+
def _add_channel_properties(self):
86+
for ch in self._ctrl.channels:
87+
if not ch._id.startswith("voltage"):
88+
continue
89+
name = ch._id.replace("voltage", "")
90+
91+
for attr in self._attrs:
92+
prop_name = f"trig{name}_{attr}"
93+
setattr(
94+
self.__class__, prop_name, self._make_channel_property(ch._id, attr)
95+
)

0 commit comments

Comments
 (0)