remoteRF-server 0.2.4__tar.gz → 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/PKG-INFO +1 -1
  2. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/pyproject.toml +1 -1
  3. remoterf_server-1.0.0/src/remoteRF_server/common/idl/pluto_mimo_schema.py +6 -0
  4. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/idl/pluto_schema.py +66 -11
  5. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/idl/schema.py +8 -2
  6. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/utils/process_arg.py +20 -11
  7. remoterf_server-1.0.0/src/remoteRF_server/drivers/adalm_pluto/pluto_mimo_schema.py +181 -0
  8. remoterf_server-1.0.0/src/remoteRF_server/drivers/adalm_pluto/pluto_schema.py +229 -0
  9. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/host/host_tunnel_server.py +45 -1
  10. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/server/device_manager.py +266 -82
  11. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/server/grpc_server.py +1 -1
  12. remoterf_server-1.0.0/src/remoteRF_server/server/rpc_manager.py +288 -0
  13. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/server/user_group_cli.py +3 -3
  14. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/server/user_group_handler.py +13 -12
  15. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/serverrf_cli.py +159 -26
  16. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/tools/gist_status.py +14 -22
  17. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server.egg-info/PKG-INFO +1 -1
  18. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server.egg-info/SOURCES.txt +3 -0
  19. remoterf_server-0.2.4/src/remoteRF_server/server/rpc_manager.py +0 -104
  20. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/README.md +0 -0
  21. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/setup.cfg +0 -0
  22. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/__init__.py +0 -0
  23. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/__init__.py +0 -0
  24. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/grpc/__init__.py +0 -0
  25. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/grpc/grpc_host_pb2.py +0 -0
  26. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/grpc/grpc_host_pb2_grpc.py +0 -0
  27. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/grpc/grpc_pb2.py +0 -0
  28. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/grpc/grpc_pb2_grpc.py +0 -0
  29. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/idl/__init__.py +0 -0
  30. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/idl/device_schema.py +0 -0
  31. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/utils/__init__.py +0 -0
  32. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/utils/ansi_codes.py +0 -0
  33. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/utils/api_token.py +0 -0
  34. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/utils/db_connection.py +0 -0
  35. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/utils/db_location.py +0 -0
  36. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/common/utils/list_string.py +0 -0
  37. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/drivers/__init__.py +0 -0
  38. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/drivers/adalm_pluto/__init__.py +0 -0
  39. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/drivers/adalm_pluto/pluto_remote_server.py +0 -0
  40. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/host/__init__.py +0 -0
  41. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/host/host_auth_token.py +0 -0
  42. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/host/host_directory_store.py +0 -0
  43. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/server/__init__.py +0 -0
  44. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/server/acc_perms.py +0 -0
  45. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/server/cert_provider.py +0 -0
  46. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/server/reservation.py +0 -0
  47. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/tools/__init__.py +0 -0
  48. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/tools/gen_certs.py +0 -0
  49. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server/tools/gist_status_testing.py +0 -0
  50. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server.egg-info/dependency_links.txt +0 -0
  51. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server.egg-info/entry_points.txt +0 -0
  52. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server.egg-info/requires.txt +0 -0
  53. {remoterf_server-0.2.4 → remoterf_server-1.0.0}/src/remoteRF_server.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: remoteRF-server
3
- Version: 0.2.4
3
+ Version: 1.0.0
4
4
  Summary: RemoteRF server-side control package
5
5
  Requires-Python: >=3.8
6
6
  Description-Content-Type: text/markdown
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "remoteRF-server"
7
- version = "0.2.4"
7
+ version = "1.0.0"
8
8
  description = "RemoteRF server-side control package"
9
9
  requires-python = ">=3.8"
10
10
  dependencies = [
@@ -0,0 +1,6 @@
1
+ # Built-in import shim for the packaged ADALM Pluto MIMO schema.
2
+
3
+ from remoteRF_server.drivers.adalm_pluto.pluto_mimo_schema import ( # noqa: F401
4
+ PlutoMIMOSchema,
5
+ connect_pluto_mimo,
6
+ )
@@ -1,15 +1,14 @@
1
- # ~/.config/remoterf/drivers/pluto_schema.py
2
- #
3
- # Admin-written schema for ADALM-Pluto devices.
4
- # Drop this file into the drivers folder, restart the server. Done.
1
+ # SAMPLE schema for ADI Pluto SDR.
2
+ # Place into -> ~/.config/remoterf/drivers and restart server to utilize!
5
3
 
6
- from . import *
4
+
5
+ from remoteRF_server.common.idl import DeviceSchema, idl_register, idl_expose
7
6
 
8
7
  import subprocess
9
8
  import re
10
9
  import adi
11
10
 
12
- # ========================= PLUTO Connection Logic =========================
11
+ # == PLUTO Connection Logic ==
13
12
 
14
13
  def connect_pluto(*, serial: str):
15
14
  serial = (serial or "").strip()
@@ -46,10 +45,11 @@ def connect_pluto(*, serial: str):
46
45
 
47
46
  # ========================= PLUTO Schema =========================
48
47
 
49
- @idl_register("pluto")
48
+ @idl_register("adalm_pluto")
50
49
  class PlutoSchema(DeviceSchema):
51
50
 
52
- device_type = "pluto"
51
+ device_type = "adalm_pluto"
52
+ client_class = "Pluto"
53
53
  driver_version = "0.0.1"
54
54
 
55
55
  @staticmethod
@@ -85,11 +85,13 @@ class PlutoSchema(DeviceSchema):
85
85
 
86
86
  @idl_expose(kind="get")
87
87
  def get_rx_hardwaregain_chan0(self):
88
- return self.device.rx_hardwaregain_chan0
88
+ """RX hardware gain (dB). pyadi-iio attribute: hardwaregain_chan0"""
89
+ return self.device.hardwaregain_chan0
89
90
 
90
91
  @idl_expose(kind="set")
91
92
  def set_rx_hardwaregain_chan0(self, value):
92
- self.device.rx_hardwaregain_chan0 = value
93
+ """RX hardware gain (dB). pyadi-iio attribute: hardwaregain_chan0"""
94
+ self.device.hardwaregain_chan0 = value
93
95
 
94
96
  @idl_expose(kind="get")
95
97
  def get_tx_hardwaregain_chan0(self):
@@ -171,4 +173,57 @@ class PlutoSchema(DeviceSchema):
171
173
 
172
174
  @idl_expose(kind="call")
173
175
  def call_tx_destroy_buffer(self):
174
- self.device.tx_destroy_buffer()
176
+ self.device.tx_destroy_buffer()
177
+
178
+ @idl_expose(kind="call")
179
+ def call_disable_dds(self):
180
+ """Disable the internal DDS tone generator."""
181
+ self.device.disable_dds()
182
+
183
+ # endregion
184
+
185
+ # region ip / repr
186
+
187
+ @idl_expose(kind="call")
188
+ def call_ip(self):
189
+ """Return a connection identifier for this device (ping / verify)."""
190
+ try:
191
+ return str(self.device.uri)
192
+ except AttributeError:
193
+ return str(self.device._uri_auto)
194
+
195
+ @idl_expose(kind="get")
196
+ def get_repr(self):
197
+ """Return repr() of the underlying device object."""
198
+ return repr(self.device)
199
+
200
+ # endregion
201
+
202
+ # region _dec_int_fpga_filter
203
+
204
+ @idl_expose(kind="get")
205
+ def get_rx_dec8_filter_en(self):
206
+ """rx_dec8_filter_en: Enable decimate-by-8 filter in FPGA"""
207
+ return bool(self.device.rx_dec8_filter_en)
208
+
209
+ @idl_expose(kind="set")
210
+ def set_rx_dec8_filter_en(self, value):
211
+ """rx_dec8_filter_en: Enable decimate-by-8 filter in FPGA"""
212
+ self.device.rx_dec8_filter_en = value
213
+
214
+ @idl_expose(kind="get")
215
+ def get_tx_int8_filter_en(self):
216
+ """tx_int8_filter_en: Enable interpolate-by-8 filter in FPGA"""
217
+ return bool(self.device.tx_int8_filter_en)
218
+
219
+ @idl_expose(kind="set")
220
+ def set_tx_int8_filter_en(self, value):
221
+ """tx_int8_filter_en: Enable interpolate-by-8 filter in FPGA"""
222
+ self.device.tx_int8_filter_en = value
223
+
224
+ @idl_expose(kind="get")
225
+ def get_rates(self):
226
+ """Get decimation/interpolation rates from the FPGA filter block."""
227
+ return self.device._get_rates(self.device._rxadc, False)
228
+
229
+ # endregion
@@ -263,7 +263,7 @@ class DeviceSchema:
263
263
  elif ex.kind == "call":
264
264
  calls[name] = entry
265
265
 
266
- return {
266
+ body = {
267
267
  "schema_version": "1.0",
268
268
  "device_type": self.device_type,
269
269
  "driver_version": self.driver_version,
@@ -272,6 +272,12 @@ class DeviceSchema:
272
272
  "calls": calls,
273
273
  }
274
274
 
275
+ client_class = getattr(self, "client_class", "")
276
+ if client_class:
277
+ body["client_class"] = str(client_class)
278
+
279
+ return body
280
+
275
281
  # ── Dispatch (server RPC layer calls this) ────────────────────
276
282
 
277
283
  def dispatch(self, method_name: str, args: dict) -> Any:
@@ -355,4 +361,4 @@ class _Exposed:
355
361
  self.name = name
356
362
  self.fn = fn
357
363
  self.kind = kind
358
- self.doc = doc
364
+ self.doc = doc
@@ -23,26 +23,36 @@ def unmap_arg(arg):
23
23
  def map_arg(value):
24
24
  arg = grpc_pb2.Argument()
25
25
 
26
- if isinstance(value, int):
27
- arg.int64_value = value
28
- elif isinstance(value, float):
29
- arg.float_value = value
26
+ if isinstance(value, (bool, np.bool_)):
27
+ arg.bool_value = bool(value)
28
+ elif isinstance(value, (int, np.integer)):
29
+ arg.int64_value = int(value)
30
+ elif isinstance(value, (float, np.floating)):
31
+ arg.float_value = float(value)
30
32
  elif isinstance(value, str):
31
33
  arg.string_value = value
32
- elif isinstance(value, bool):
33
- arg.bool_value = value
34
+ elif isinstance(value, (list, tuple)):
35
+ array = np.asarray(value)
36
+ if array.dtype == object:
37
+ try:
38
+ array = np.stack(value)
39
+ except Exception as exc:
40
+ raise ValueError(f"Cannot map ragged/object array value: {value}") from exc
41
+ return map_arg(array)
34
42
  elif isinstance(value, np.ndarray):
43
+ if value.dtype == object:
44
+ raise ValueError(f"Cannot map object-dtype array: {value!r}")
35
45
  if np.iscomplexobj(value):
36
46
  complex_array = arg.complex_array
37
47
  complex_array.shape.dim.extend(value.shape)
38
- for num in value.ravel():
48
+ for num in np.asarray(value, dtype=np.complex64).ravel():
39
49
  complex_num = complex_array.data.add()
40
- complex_num.real = num.real
41
- complex_num.imag = num.imag
50
+ complex_num.real = float(num.real)
51
+ complex_num.imag = float(num.imag)
42
52
  else:
43
53
  float_array = arg.real_array
44
54
  float_array.shape.dim.extend(value.shape)
45
- float_array.data.extend(value.ravel())
55
+ float_array.data.extend(np.asarray(value, dtype=np.float32).ravel())
46
56
  else:
47
57
  raise ValueError(f"Unknown argument type during mapping: {value}")
48
58
  return arg
@@ -77,4 +87,3 @@ def unmap_array_proto(arg):
77
87
  return np.array(arg.float_array.data, dtype=np.float32)
78
88
  else:
79
89
  raise ValueError("Argument does not contain a recognizable array.")
80
-
@@ -0,0 +1,181 @@
1
+ # SAMPLE schema for ADI Pluto SDR in AD9361 MIMO / 2R2T mode.
2
+ # Place into -> ~/.config/remoterf/drivers and restart server to utilize!
3
+
4
+ from remoteRF_server.common.idl import idl_register, idl_expose
5
+ from remoteRF_server.common.idl.pluto_schema import PlutoSchema
6
+
7
+ import subprocess
8
+ import re
9
+ import adi
10
+
11
+
12
+ def _normalize_channels(value, default):
13
+ if value is None:
14
+ return list(default)
15
+ if isinstance(value, str):
16
+ if not value.strip():
17
+ return list(default)
18
+ return [int(part.strip()) for part in value.split(",") if part.strip()]
19
+ return [int(ch) for ch in value]
20
+
21
+
22
+ def _get_attr(device, *names):
23
+ for name in names:
24
+ if hasattr(device, name):
25
+ return getattr(device, name)
26
+ raise AttributeError(f"{device!r} has none of: {', '.join(names)}")
27
+
28
+
29
+ def _set_attr(device, value, *names):
30
+ for name in names:
31
+ if hasattr(device, name):
32
+ setattr(device, name, value)
33
+ return
34
+ raise AttributeError(f"{device!r} has none of: {', '.join(names)}")
35
+
36
+
37
+ def _apply_initial_settings(device, settings):
38
+ int_attrs = (
39
+ "sample_rate",
40
+ "rx_lo",
41
+ "tx_lo",
42
+ "rx_rf_bandwidth",
43
+ "tx_rf_bandwidth",
44
+ "rx_buffer_size",
45
+ )
46
+ for attr in int_attrs:
47
+ value = settings.get(attr)
48
+ if value is not None:
49
+ setattr(device, attr, int(value))
50
+
51
+
52
+ # == PLUTO MIMO Connection Logic ==
53
+
54
+ def connect_pluto_mimo(
55
+ *,
56
+ serial,
57
+ rx_enabled_channels=None,
58
+ tx_enabled_channels=None,
59
+ initial_settings=None,
60
+ ):
61
+ serial = (serial or "").strip()
62
+ if not serial:
63
+ print("An adalm_pluto_mimo serial must be provided")
64
+ return None
65
+
66
+ try:
67
+ out = subprocess.check_output(
68
+ ["iio_info", "-s"],
69
+ text=True,
70
+ stderr=subprocess.STDOUT,
71
+ )
72
+
73
+ usb = None
74
+ for line in out.splitlines():
75
+ if (f"serial={serial}" in line) or (f"hw_serial={serial}" in line):
76
+ m = re.search(r"\[usb:([^\]]+)\]", line)
77
+ if m:
78
+ usb = m.group(1).strip()
79
+ break
80
+
81
+ if not usb:
82
+ print(f"No adalm_pluto_mimo device found with serial {serial}")
83
+ return None
84
+
85
+ dev = adi.ad9361(f"usb:{usb}")
86
+ dev.rx_enabled_channels = _normalize_channels(rx_enabled_channels, [0, 1])
87
+ dev.tx_enabled_channels = _normalize_channels(tx_enabled_channels, [0, 1])
88
+ _apply_initial_settings(dev, initial_settings or {})
89
+ print(f"Connected to adalm_pluto_mimo serial={serial} via usb:{usb}")
90
+ return dev
91
+
92
+ except Exception as e:
93
+ print(f"Failed to connect to adalm_pluto_mimo serial={serial}: {e}")
94
+ return None
95
+
96
+
97
+ # ========================= PLUTO MIMO Schema =========================
98
+
99
+ @idl_register("adalm_pluto_mimo")
100
+ class PlutoMIMOSchema(PlutoSchema):
101
+
102
+ device_type = "adalm_pluto_mimo"
103
+ client_class = "PlutoMIMO"
104
+ driver_version = "0.0.1"
105
+
106
+ @staticmethod
107
+ def make_device(**kwargs):
108
+ return connect_pluto_mimo(
109
+ serial=kwargs.get("serial"),
110
+ rx_enabled_channels=kwargs.get("rx_enabled_channels"),
111
+ tx_enabled_channels=kwargs.get("tx_enabled_channels"),
112
+ initial_settings=kwargs,
113
+ )
114
+
115
+ # region MIMO channel selection
116
+
117
+ @idl_expose(kind="get")
118
+ def get_mode(self):
119
+ return "mimo"
120
+
121
+ @idl_expose(kind="get")
122
+ def get_rx_enabled_channels(self):
123
+ return list(self.device.rx_enabled_channels)
124
+
125
+ @idl_expose(kind="set")
126
+ def set_rx_enabled_channels(self, value):
127
+ self.device.rx_enabled_channels = _normalize_channels(value, [0, 1])
128
+
129
+ @idl_expose(kind="get")
130
+ def get_tx_enabled_channels(self):
131
+ return list(self.device.tx_enabled_channels)
132
+
133
+ @idl_expose(kind="set")
134
+ def set_tx_enabled_channels(self, value):
135
+ self.device.tx_enabled_channels = _normalize_channels(value, [0, 1])
136
+
137
+ # endregion
138
+
139
+ # region channel 1 controls
140
+
141
+ @idl_expose(kind="get")
142
+ def get_gain_control_mode_chan1(self):
143
+ return self.device.gain_control_mode_chan1
144
+
145
+ @idl_expose(kind="set")
146
+ def set_gain_control_mode_chan1(self, value):
147
+ self.device.gain_control_mode_chan1 = value
148
+
149
+ @idl_expose(kind="get")
150
+ def get_rx_hardwaregain_chan1(self):
151
+ """RX channel 1 hardware gain (dB)."""
152
+ return _get_attr(self.device, "rx_hardwaregain_chan1", "hardwaregain_chan1")
153
+
154
+ @idl_expose(kind="set")
155
+ def set_rx_hardwaregain_chan1(self, value):
156
+ """RX channel 1 hardware gain (dB)."""
157
+ _set_attr(self.device, value, "rx_hardwaregain_chan1", "hardwaregain_chan1")
158
+
159
+ @idl_expose(kind="get")
160
+ def get_tx_hardwaregain_chan1(self):
161
+ return self.device.tx_hardwaregain_chan1
162
+
163
+ @idl_expose(kind="set")
164
+ def set_tx_hardwaregain_chan1(self, value):
165
+ self.device.tx_hardwaregain_chan1 = value
166
+
167
+ # endregion
168
+
169
+ # region AD9361 gain compatibility
170
+
171
+ @idl_expose(kind="get")
172
+ def get_rx_hardwaregain_chan0(self):
173
+ """RX channel 0 hardware gain (dB)."""
174
+ return _get_attr(self.device, "rx_hardwaregain_chan0", "hardwaregain_chan0")
175
+
176
+ @idl_expose(kind="set")
177
+ def set_rx_hardwaregain_chan0(self, value):
178
+ """RX channel 0 hardware gain (dB)."""
179
+ _set_attr(self.device, value, "rx_hardwaregain_chan0", "hardwaregain_chan0")
180
+
181
+ # endregion
@@ -0,0 +1,229 @@
1
+ # SAMPLE schema for ADI Pluto SDR.
2
+ # Place into -> ~/.config/remoterf/drivers and restart server to utilize!
3
+
4
+
5
+ from remoteRF_server.common.idl import DeviceSchema, idl_register, idl_expose
6
+
7
+ import subprocess
8
+ import re
9
+ import adi
10
+
11
+ # == PLUTO Connection Logic ==
12
+
13
+ def connect_pluto(*, serial: str):
14
+ serial = (serial or "").strip()
15
+ if not serial:
16
+ print("A Pluto serial must be provided")
17
+ return None
18
+
19
+ try:
20
+ out = subprocess.check_output(
21
+ ["iio_info", "-s"],
22
+ text=True,
23
+ stderr=subprocess.STDOUT
24
+ )
25
+
26
+ usb = None
27
+ for line in out.splitlines():
28
+ if (f"serial={serial}" in line) or (f"hw_serial={serial}" in line):
29
+ m = re.search(r"\[usb:([^\]]+)\]", line)
30
+ if m:
31
+ usb = m.group(1).strip()
32
+ break
33
+
34
+ if not usb:
35
+ print(f"No device found with serial {serial}")
36
+ return None
37
+
38
+ dev = adi.Pluto(f"usb:{usb}")
39
+ print(f"Connected to Pluto serial={serial} via usb:{usb}")
40
+ return dev
41
+
42
+ except Exception as e:
43
+ print(f"Failed to connect to Pluto serial={serial}: {e}")
44
+ return None
45
+
46
+ # ========================= PLUTO Schema =========================
47
+
48
+ @idl_register("adalm_pluto")
49
+ class PlutoSchema(DeviceSchema):
50
+
51
+ device_type = "adalm_pluto"
52
+ client_class = "Pluto"
53
+ driver_version = "0.0.1"
54
+
55
+ @staticmethod
56
+ def make_device(**kwargs):
57
+ serial = kwargs.get("serial")
58
+ return connect_pluto(serial=serial)
59
+
60
+ # region ad9364
61
+
62
+ @idl_expose(kind="get")
63
+ def get_filter(self):
64
+ return self.device.filter
65
+
66
+ @idl_expose(kind="set")
67
+ def set_filter(self, value):
68
+ self.device.filter = value
69
+
70
+ @idl_expose(kind="get")
71
+ def get_loopback(self):
72
+ return self.device.loopback
73
+
74
+ @idl_expose(kind="set")
75
+ def set_loopback(self, value):
76
+ self.device.loopback = value
77
+
78
+ @idl_expose(kind="get")
79
+ def get_gain_control_mode_chan0(self):
80
+ return self.device.gain_control_mode_chan0
81
+
82
+ @idl_expose(kind="set")
83
+ def set_gain_control_mode_chan0(self, value):
84
+ self.device.gain_control_mode_chan0 = value
85
+
86
+ @idl_expose(kind="get")
87
+ def get_rx_hardwaregain_chan0(self):
88
+ """RX hardware gain (dB). pyadi-iio attribute: hardwaregain_chan0"""
89
+ return self.device.hardwaregain_chan0
90
+
91
+ @idl_expose(kind="set")
92
+ def set_rx_hardwaregain_chan0(self, value):
93
+ """RX hardware gain (dB). pyadi-iio attribute: hardwaregain_chan0"""
94
+ self.device.hardwaregain_chan0 = value
95
+
96
+ @idl_expose(kind="get")
97
+ def get_tx_hardwaregain_chan0(self):
98
+ return self.device.tx_hardwaregain_chan0
99
+
100
+ @idl_expose(kind="set")
101
+ def set_tx_hardwaregain_chan0(self, value):
102
+ self.device.tx_hardwaregain_chan0 = value
103
+
104
+ @idl_expose(kind="get")
105
+ def get_rx_rf_bandwidth(self):
106
+ return self.device.rx_rf_bandwidth
107
+
108
+ @idl_expose(kind="set")
109
+ def set_rx_rf_bandwidth(self, value):
110
+ self.device.rx_rf_bandwidth = value
111
+
112
+ @idl_expose(kind="get")
113
+ def get_tx_rf_bandwidth(self):
114
+ return self.device.tx_rf_bandwidth
115
+
116
+ @idl_expose(kind="set")
117
+ def set_tx_rf_bandwidth(self, value):
118
+ self.device.tx_rf_bandwidth = value
119
+
120
+ @idl_expose(kind="get")
121
+ def get_sample_rate(self):
122
+ return self.device.sample_rate
123
+
124
+ @idl_expose(kind="set")
125
+ def set_sample_rate(self, value):
126
+ self.device.sample_rate = value
127
+
128
+ @idl_expose(kind="get")
129
+ def get_rx_lo(self):
130
+ return self.device.rx_lo
131
+
132
+ @idl_expose(kind="set")
133
+ def set_rx_lo(self, value):
134
+ self.device.rx_lo = value
135
+
136
+ @idl_expose(kind="get")
137
+ def get_tx_lo(self):
138
+ return self.device.tx_lo
139
+
140
+ @idl_expose(kind="set")
141
+ def set_tx_lo(self, value):
142
+ self.device.tx_lo = value
143
+
144
+ @idl_expose(kind="get")
145
+ def get_tx_cyclic_buffer(self):
146
+ return self.device.tx_cyclic_buffer
147
+
148
+ @idl_expose(kind="set")
149
+ def set_tx_cyclic_buffer(self, value):
150
+ self.device.tx_cyclic_buffer = value
151
+
152
+ # region RX/TX
153
+
154
+ @idl_expose(kind="call")
155
+ def call_rx(self):
156
+ return self.device.rx()
157
+
158
+ @idl_expose(kind="get")
159
+ def get_rx_buffer_size(self):
160
+ return self.device.rx_buffer_size
161
+
162
+ @idl_expose(kind="set")
163
+ def set_rx_buffer_size(self, value):
164
+ self.device.rx_buffer_size = value
165
+
166
+ @idl_expose(kind="call")
167
+ def call_rx_destroy_buffer(self):
168
+ self.device.rx_destroy_buffer()
169
+
170
+ @idl_expose(kind="call")
171
+ def call_tx(self, value):
172
+ self.device.tx(value)
173
+
174
+ @idl_expose(kind="call")
175
+ def call_tx_destroy_buffer(self):
176
+ self.device.tx_destroy_buffer()
177
+
178
+ @idl_expose(kind="call")
179
+ def call_disable_dds(self):
180
+ """Disable the internal DDS tone generator."""
181
+ self.device.disable_dds()
182
+
183
+ # endregion
184
+
185
+ # region ip / repr
186
+
187
+ @idl_expose(kind="call")
188
+ def call_ip(self):
189
+ """Return a connection identifier for this device (ping / verify)."""
190
+ try:
191
+ return str(self.device.uri)
192
+ except AttributeError:
193
+ return str(self.device._uri_auto)
194
+
195
+ @idl_expose(kind="get")
196
+ def get_repr(self):
197
+ """Return repr() of the underlying device object."""
198
+ return repr(self.device)
199
+
200
+ # endregion
201
+
202
+ # region _dec_int_fpga_filter
203
+
204
+ @idl_expose(kind="get")
205
+ def get_rx_dec8_filter_en(self):
206
+ """rx_dec8_filter_en: Enable decimate-by-8 filter in FPGA"""
207
+ return bool(self.device.rx_dec8_filter_en)
208
+
209
+ @idl_expose(kind="set")
210
+ def set_rx_dec8_filter_en(self, value):
211
+ """rx_dec8_filter_en: Enable decimate-by-8 filter in FPGA"""
212
+ self.device.rx_dec8_filter_en = value
213
+
214
+ @idl_expose(kind="get")
215
+ def get_tx_int8_filter_en(self):
216
+ """tx_int8_filter_en: Enable interpolate-by-8 filter in FPGA"""
217
+ return bool(self.device.tx_int8_filter_en)
218
+
219
+ @idl_expose(kind="set")
220
+ def set_tx_int8_filter_en(self, value):
221
+ """tx_int8_filter_en: Enable interpolate-by-8 filter in FPGA"""
222
+ self.device.tx_int8_filter_en = value
223
+
224
+ @idl_expose(kind="get")
225
+ def get_rates(self):
226
+ """Get decimation/interpolation rates from the FPGA filter block."""
227
+ return self.device._get_rates(self.device._rxadc, False)
228
+
229
+ # endregion