Skip to content

Commit

Permalink
adi: ad4020: Add reset_buffer convenience decorator
Browse files Browse the repository at this point in the history
Functions that need to write to the device may fail if there is an active
(enabled) IIO buffer at the moment. That's because the same physical SPI
lines cannot both provide data to the host controller and receive
configuration at the same time. Driver developers (and the Linux IIO
subsystem) prevent such concurrent access by locking a mutex and not
allowing buffered readings until configuration transfers end. Conversely,
attempts to do direct transfers while a buffer is enabled return -EBUSY.
Decorate functions that do direct device access to reset (and disable)
the read buffer, thus allowing the device configuration to happen.

Signed-off-by: Marcelo Schmitt <[email protected]>
  • Loading branch information
machschmitt committed Jul 4, 2024
1 parent 3814809 commit aef7b26
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions adi/ad4020.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@
from adi.rx_tx import rx


def reset_buffer(func):
"""Wrapper for set calls that require device configuration.
Without disabling the buffer, direct access will return -EBUSY
"""

def wrapper(*args, **kwargs):
if args[0]._reset_on_spi_writes:
args[0].rx_destroy_buffer()
func(*args, **kwargs)

return wrapper


class ad4020(rx, context_manager):
"""AD4000 series of differential SAR ADC device"""

Expand All @@ -23,6 +36,7 @@ class ad4020(rx, context_manager):
_rx_data_type = np.int32
_complex_data = False
_rx_channel_names = ["voltage0"]
_reset_on_spi_writes = True

def __init__(self, uri="", device_name="ad4020"):
if not device_name:
Expand Down Expand Up @@ -51,13 +65,16 @@ def sampling_frequency(self):
return self._get_iio_dev_attr("sampling_frequency")

@sampling_frequency.setter
@reset_buffer
def sampling_frequency(self, value):
"""Set the sampling frequency."""
self._set_iio_dev_attr("sampling_frequency", str(value))

class _channel_adc(attribute):
"""AD4000 series differential input voltage channel"""

_reset_on_spi_writes = True

# AD4000 series ADC channel
def __init__(self, ctrl, channel_name, output):
self.name = channel_name
Expand All @@ -73,6 +90,7 @@ def scale(self):
return float(self._get_iio_attr_str(self.name, "scale", self._output))

@scale.setter
@reset_buffer
def scale(self, value):
self._set_iio_attr(self.name, "scale", False, str(Decimal(value).real))

Expand Down

0 comments on commit aef7b26

Please sign in to comment.