Skip to content

Commit

Permalink
Add compatibility layer for libiio 1.x
Browse files Browse the repository at this point in the history
Signed-off-by: Travis F. Collins <[email protected]>
  • Loading branch information
tfcollins committed Dec 6, 2023
1 parent 24b2795 commit 0257a54
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 27 deletions.
91 changes: 91 additions & 0 deletions adi/compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Copyright (C) 2023 Analog Devices, Inc.
#
# SPDX short identifier: ADIBSD
"""Compatibility module for libiio v1.X."""

from typing import Any

import iio


class compat_libiio:
"""Compatibility class for libiio v1.X."""

def __is_libiio_v1(self):
"""Check is we are using >= v1.X."""
v = iio.version
return v[0] >= 1

def _setup_v1_rx(self):
"""Setup for libiio v1.X RX side."""
self._rx_buffer_mask = None
self.__rx_stream = None
self._rx_buffer_num_blocks = 4

def _setup_v1_tx(self):
"""Setup for libiio v1.X TX side."""
self._tx_buffer_mask = None
self.__tx_stream = None
self._tx_buffer_num_blocks = 4

def __getattr__(self, __name: str) -> Any:
if __name in ["_rx_init_channels", "_tx_init_channels", "__tx_buffer_push"]:
if self.__is_libiio_v1():
return getattr(self, f"_{__name}_v1")
else:
return getattr(self, f"_{__name}")

def _rx_init_channels_v1(self):
if not self._rx_buffer_mask:
self._rx_buffer_mask = iio.ChannelsMask(self._rxadc)

channels = []
if self._complex_data:
for m in self.rx_enabled_channels:
v = self._rxadc.find_channel(self._rx_channel_names[m * 2])
channels.append(v)
v = self._rxadc.find_channel(self._rx_channel_names[m * 2 + 1])
channels.append(v)
else:
for m in self.rx_enabled_channels:
v = self._rxadc.find_channel(self._rx_channel_names[m])
channels.append(v)

self._rx_buffer_mask.channels = channels

self.__rxbuf = iio.Buffer(self._rxadc, self._rx_buffer_mask)
self.__rx_stream = iio.Stream(
buffer=self.__rxbuf,
nb_blocks=self._rx_buffer_num_blocks,
samples_count=self.rx_buffer_size,
)

def _tx_init_channels_v1(self):
if not self._tx_buffer_mask:
self._tx_buffer_mask = iio.ChannelsMask(self._txdac)

channels = []
if self._complex_data:
for m in self.tx_enabled_channels:
v = self._txdac.find_channel(self._tx_channel_names[m * 2], True)
channels.append(v)
v = self._txdac.find_channel(self._tx_channel_names[m * 2 + 1], True)
channels.append(v)
else:
for m in self.tx_enabled_channels:
v = self._txdac.find_channel(self._tx_channel_names[m], True)
channels.append(v)

self._tx_buffer_mask.channels = channels

self.__txbuf = iio.Buffer(self._txdac, self._tx_buffer_mask)
self.__block_tx = iio.Block(self.__txbuf, self._tx_buffer_size)

def __tx_buffer_push_v1(self, data):
"""Push data to TX buffer.
data: bytearray
"""
self.__block_tx.write(data)
self.__block_tx.enqueue(None, self.__tx_cyclic_buffer)
self.__txbuf.enabled = True
2 changes: 2 additions & 0 deletions adi/dds.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ def dds_single_tone(self, frequency, scale, channel=0):
+ "_F1",
True,
)
if not chan:
raise Exception(f"DDS Channel {channel} not found")
chan.attrs["frequency"].value = str(frequency)
chan.attrs["phase"].value = str(90000)
chan.attrs["scale"].value = str(scale)
Expand Down
49 changes: 22 additions & 27 deletions adi/rx_tx.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import numpy as np
from adi.attribute import attribute
from adi.compat import compat_libiio
from adi.context_manager import context_manager
from adi.dds import dds

Expand All @@ -20,7 +21,7 @@ def __del__(self):
self._ctrl = []


class rx_tx_common(attribute):
class rx_tx_common(attribute, compat_libiio):
"""Common functions for RX and TX"""

def _annotate(self, data, cnames: List[str], echans: List[int]):
Expand All @@ -43,9 +44,6 @@ class rx(rx_tx_common):
_rx_unbuffered_data = False
_rx_annotated = False
_rx_stack_interleaved = True # Convert from channel to sample interleaved
_rx_buffer_mask = None
__rx_stream = None
_rx_buffer_num_blocks = 4

def __init__(self, rx_buffer_size=1024):
if self._complex_data:
Expand All @@ -56,6 +54,8 @@ def __init__(self, rx_buffer_size=1024):
self._num_rx_channels = len(self._rx_channel_names)
self.rx_enabled_channels = rx_enabled_channels
self.rx_buffer_size = rx_buffer_size
if self.__is_libiio_v1():
self._setup_v1_rx()

@property
def rx_channel_names(self) -> List[str]:
Expand Down Expand Up @@ -181,30 +181,23 @@ def __get_rx_channel_offsets(self):
return rx_offset

def _rx_init_channels(self):
for m in self._rx_channel_names:
v = self._rxadc.find_channel(m)
if not v:
raise Exception(f"Channel {m} not found")
v.enabled = False

if not self._rx_buffer_mask:
self._rx_buffer_mask = iio.ChannelsMask(self._rxadc)

channels = []
if self._complex_data:
for m in self.rx_enabled_channels:
v = self._rxadc.find_channel(self._rx_channel_names[m * 2])
channels.append(v)
v.enabled = True
v = self._rxadc.find_channel(self._rx_channel_names[m * 2 + 1])
channels.append(v)
v.enabled = True
else:
for m in self.rx_enabled_channels:
v = self._rxadc.find_channel(self._rx_channel_names[m])
channels.append(v)

self._rx_buffer_mask.channels = channels

self.__rxbuf = iio.Buffer(self._rxadc, self._rx_buffer_mask)
self.__rx_stream = iio.Stream(
buffer=self.__rxbuf,
nb_blocks=self._rx_buffer_num_blocks,
samples_count=self.rx_buffer_size,
)
v.enabled = True
self.__rxbuf = iio.Buffer(self._rxadc, self.__rx_buffer_size, False)

def __rx_unbuffered_data(self):
x = []
Expand Down Expand Up @@ -242,7 +235,7 @@ def __rx_buffered_data(self) -> Union[List[np.ndarray], np.ndarray]:
"""
if not self.__rxbuf:
self._rx_init_channels()
rx_block = next(self.__rx_stream)
self.__rxbuf.refill()

data_channel_interleaved = []
ecn = []
Expand All @@ -256,7 +249,7 @@ def __rx_buffered_data(self) -> Union[List[np.ndarray], np.ndarray]:

for name in ecn:
chan = self._rxadc.find_channel(name)
bytearray_data = chan.read(rx_block) # Do local type conversion
bytearray_data = chan.read(self.__rxbuf) # Do local type conversion
# create format strings
df = chan.data_format
fmt = ("i" if df.is_signed is True else "u") + str(df.length // 8)
Expand Down Expand Up @@ -332,6 +325,8 @@ def __init__(self, tx_cyclic_buffer=False):
self.tx_enabled_channels = tx_enabled_channels
self.tx_cyclic_buffer = tx_cyclic_buffer
dds.__init__(self)
if self.__is_libiio_v1():
self._setup_v1_tx()

def __del__(self):
self.__txbuf = []
Expand Down Expand Up @@ -518,8 +513,11 @@ def tx(self, data_np=None):
f.write(bytearray(data))
f.close()
else:
self.__txbuf.write(bytearray(data))
self.__txbuf.push()
self.__tx_buffer_push(data)

def __tx_buffer_push(self, data):
self.__txbuf.write(bytearray(data))
self.__txbuf.push()


class rx_tx(rx, tx, phy):
Expand Down Expand Up @@ -594,7 +592,6 @@ def __handle_init_args(self, args, kwargs):
def __init__(
self, *args: Union[str, iio.Context], **kwargs: Union[str, iio.Context]
) -> None:

# Handle Older API and Newer APIs
uri_ctx = self.__handle_init_args(args, kwargs)

Expand Down Expand Up @@ -653,7 +650,6 @@ def _rx_data_device_name(self) -> None:
def __init__(
self, *args: Union[str, iio.Context], **kwargs: Union[str, iio.Context]
) -> None:

shared_def.__init__(self, *args, **kwargs)

if self._rx_data_device_name:
Expand Down Expand Up @@ -701,7 +697,6 @@ def _tx_data_device_name(self) -> None:
def __init__(
self, *args: Union[str, iio.Context], **kwargs: Union[str, iio.Context]
) -> None:

shared_def.__init__(self, *args, **kwargs)

if self._tx_data_device_name:
Expand Down

0 comments on commit 0257a54

Please sign in to comment.