spectre-core 0.0.14__py3-none-any.whl → 0.0.16__py3-none-any.whl

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.
@@ -9,7 +9,7 @@ from ._capture_modes import CaptureMode
9
9
  from ._pvalidators import (
10
10
  validate_fixed_center_frequency, validate_non_overlapping_steps, validate_num_samples_per_step,
11
11
  validate_num_steps_per_sweep, validate_nyquist_criterion, validate_step_interval, validate_sweep_interval,
12
- validate_swept_center_frequency, validate_window
12
+ validate_swept_center_frequency, validate_window, validate_sample_rate_with_master_clock_rate
13
13
  )
14
14
  from ._capture_config import CaptureConfig
15
15
  from ._ptemplates import PTemplate, get_base_ptemplate
@@ -29,5 +29,5 @@ __all__ = [
29
29
  "PConstraint", "PConstraint", "Bound", "OneOf", "EnforceSign", "PowerOfTwo", "make_base_capture_template", "PName",
30
30
  "get_base_ptemplate", "BasePConstraint", "validate_fixed_center_frequency", "validate_non_overlapping_steps",
31
31
  "validate_num_samples_per_step", "validate_num_steps_per_sweep", "validate_nyquist_criterion", "validate_step_interval",
32
- "validate_sweep_interval", "validate_swept_center_frequency", "validate_window"
33
- ]
32
+ "validate_sweep_interval", "validate_swept_center_frequency", "validate_window", "validate_sample_rate_with_master_clock_rate"
33
+ ]
@@ -46,4 +46,7 @@ class PName(Enum):
46
46
  OBJECT = "object"
47
47
  OBS_LAT = "obs_lat"
48
48
  OBS_LON = "obs_lon"
49
- OBS_ALT = "obs_alt"
49
+ OBS_ALT = "obs_alt"
50
+ GAIN = "gain"
51
+ MASTER_CLOCK_RATE = "master_clock_rate"
52
+ WIRE_FORMAT = "wire_format"
@@ -7,7 +7,7 @@ from textwrap import dedent
7
7
  from copy import deepcopy
8
8
 
9
9
  from ._pnames import PName
10
- from ._pconstraints import BasePConstraint, EnforceSign, PowerOfTwo
10
+ from ._pconstraints import BasePConstraint, EnforceSign, PowerOfTwo, Bound
11
11
  from ._parameters import Parameter
12
12
 
13
13
  # value type
@@ -300,6 +300,24 @@ _base_ptemplates: dict[PName, PTemplate] = {
300
300
  pconstraints=[
301
301
  EnforceSign.non_positive
302
302
  ]),
303
+ PName.GAIN: PTemplate(PName.GAIN,
304
+ float,
305
+ help = """
306
+ The gain value for the SDR, in dB
307
+ """
308
+ ),
309
+ PName.MASTER_CLOCK_RATE: PTemplate(PName.MASTER_CLOCK_RATE,
310
+ int,
311
+ help = """
312
+ The primary reference clock for the SDR, specified in Hz.
313
+ """
314
+ ),
315
+ PName.WIRE_FORMAT: PTemplate(PName.WIRE_FORMAT,
316
+ str,
317
+ help = """
318
+ Controls the form of the data over the bus/network.
319
+ """
320
+ ),
303
321
  PName.EVENT_HANDLER_KEY: PTemplate(PName.EVENT_HANDLER_KEY,
304
322
  str,
305
323
  help = """
@@ -490,4 +508,4 @@ def get_base_ptemplate(
490
508
  # A deep copy is required as each receiver instance may mutate the original instance
491
509
  # according to its particular use case. Copying preserves the original instance,
492
510
  # enabling reuse.
493
- return deepcopy( _base_ptemplates[pname] )
511
+ return deepcopy( _base_ptemplates[pname] )
@@ -184,6 +184,22 @@ def validate_step_interval(
184
184
  f"derived api latency {api_retuning_latency} [s]; you may experience undefined behaviour!")
185
185
 
186
186
 
187
+ def validate_sample_rate_with_master_clock_rate(
188
+ parameters: Parameters,
189
+ ) -> None:
190
+ """Ensure that the master clock rate is an integer multiple of the sample rate.
191
+
192
+ :param parameters: The parameters to be validated.
193
+ :raises ValueError: If the master clock rate is not an integer multiple of the sample rate
194
+ """
195
+ master_clock_rate = cast(int, parameters.get_parameter_value(PName.MASTER_CLOCK_RATE))
196
+ sample_rate = cast(int, parameters.get_parameter_value(PName.SAMPLE_RATE))
197
+
198
+ if master_clock_rate % sample_rate != 0:
199
+ raise ValueError(f"The master clock rate of {master_clock_rate} [Hz] is not an integer "
200
+ f"multiple of the sample rate {sample_rate} [Hz].")
201
+
202
+
187
203
  def validate_fixed_center_frequency(
188
204
  parameters: Parameters
189
205
  ) -> None:
@@ -8,6 +8,7 @@ from .plugins._receiver_names import ReceiverName
8
8
  from .plugins._test import Test
9
9
  from .plugins._rsp1a import RSP1A
10
10
  from .plugins._rspduo import RSPduo
11
+ from .plugins._b200mini import B200mini
11
12
 
12
13
  from ._base import BaseReceiver
13
14
  from ._factory import get_receiver
@@ -15,6 +16,6 @@ from ._register import get_registered_receivers
15
16
  from ._spec_names import SpecName
16
17
 
17
18
  __all__ = [
18
- "Test", "RSP1A", "RSPduo", "BaseReceiver", "get_receiver",
19
+ "Test", "RSP1A", "RSPduo", "B200mini", "BaseReceiver", "get_receiver",
19
20
  "get_registered_receivers", "SpecName", "ReceiverName"
20
- ]
21
+ ]
@@ -3,7 +3,7 @@
3
3
  # SPDX-License-Identifier: GPL-3.0-or-later
4
4
 
5
5
  from abc import ABC, abstractmethod
6
- from typing import Callable, Optional, Literal, overload
6
+ from typing import Callable, Optional, Literal, overload, Any
7
7
 
8
8
  from spectre_core.exceptions import ModeNotFoundError
9
9
  from spectre_core.capture_configs import (
@@ -226,7 +226,7 @@ class BaseReceiver(ABC):
226
226
  def add_spec(
227
227
  self,
228
228
  name: SpecName,
229
- value: float|int|list[float|int]
229
+ value: Any
230
230
  ) -> None:
231
231
  """
232
232
  Add a hardware specification.
@@ -236,34 +236,11 @@ class BaseReceiver(ABC):
236
236
  """
237
237
  self.specs[name] = value
238
238
 
239
-
240
- # tell static type checkers the type of specification
241
- @overload
242
- def get_spec(self, spec_name: Literal[SpecName.API_RETUNING_LATENCY]) -> float: ...
243
- @overload
244
- def get_spec(self, spec_name: Literal[SpecName.FREQUENCY_LOWER_BOUND]) -> float: ...
245
- @overload
246
- def get_spec(self, spec_name: Literal[SpecName.FREQUENCY_UPPER_BOUND]) -> float: ...
247
- @overload
248
- def get_spec(self, spec_name: Literal[SpecName.SAMPLE_RATE_LOWER_BOUND]) -> int: ...
249
- @overload
250
- def get_spec(self, spec_name: Literal[SpecName.SAMPLE_RATE_UPPER_BOUND]) -> int: ...
251
- @overload
252
- def get_spec(self, spec_name: Literal[SpecName.BANDWIDTH_LOWER_BOUND]) -> float: ...
253
- @overload
254
- def get_spec(self, spec_name: Literal[SpecName.BANDWIDTH_UPPER_BOUND]) -> float: ...
255
- @overload
256
- def get_spec(self, spec_name: Literal[SpecName.RF_GAIN_UPPER_BOUND]) -> int: ...
257
- @overload
258
- def get_spec(self, spec_name: Literal[SpecName.IF_GAIN_UPPER_BOUND]) -> int: ...
259
- @overload
260
- def get_spec(self, spec_name: Literal[SpecName.BANDWIDTH_OPTIONS]) -> list[float]: ...
261
-
262
239
 
263
240
  def get_spec(
264
241
  self,
265
242
  spec_name: SpecName
266
- ) -> float|int|list[float|int]:
243
+ ) -> Any:
267
244
  """
268
245
  Retrieve a hardware specification.
269
246
 
@@ -328,4 +305,4 @@ class BaseReceiver(ABC):
328
305
  parameters = self.capture_template.apply_template(capture_config.parameters)
329
306
  self.pvalidator(parameters)
330
307
 
331
- return parameters
308
+ return parameters
@@ -11,6 +11,7 @@ from .plugins._receiver_names import ReceiverName
11
11
  from .plugins._rsp1a import RSP1A
12
12
  from .plugins._rspduo import RSPduo
13
13
  from .plugins._test import Test
14
+ from .plugins._b200mini import B200mini
14
15
 
15
16
 
16
17
  @overload
@@ -37,6 +38,14 @@ def get_receiver(
37
38
  ...
38
39
 
39
40
 
41
+ @overload
42
+ def get_receiver(
43
+ receiver_name: Literal[ReceiverName.B200MINI],
44
+ mode: Optional[str] = None
45
+ ) -> B200mini:
46
+ ...
47
+
48
+
40
49
  @overload
41
50
  def get_receiver(
42
51
  receiver_name: ReceiverName,
@@ -18,14 +18,24 @@ class SpecName(Enum):
18
18
  Negative values indicate attenuation.
19
19
  :ivar RF_GAIN_UPPER_BOUND: The upper bound for the radio frequency gain, in dB.
20
20
  Negative values indicate attenuation.
21
+ :ivar GAIN_UPPER_BOUND: The upper bound for the gain, in dB.
22
+ :ivar WIRE_FORMATS: Supported data types transferred over the bus/network.
23
+ :ivar MASTER_CLOCK_RATE_LOWER_BOUND: The lower bound for the SDR reference clock rate, in Hz.
24
+ :ivar MASTER_CLOCK_RATE_UPPER_BOUND: The upper bound for the SDR reference clock rate, in Hz.
25
+ :ivar API_RETUNING_LATENCY: An empirical estimate of the delay between issuing a command
26
+ for a receiver to retune its center frequency and the actual physical update of the center frequency.
21
27
  """
22
- FREQUENCY_LOWER_BOUND = "frequency_lower_bound"
23
- FREQUENCY_UPPER_BOUND = "frequency_upper_bound"
24
- SAMPLE_RATE_LOWER_BOUND = "sample_rate_lower_bound"
25
- SAMPLE_RATE_UPPER_BOUND = "sample_rate_upper_bound"
26
- BANDWIDTH_LOWER_BOUND = "bandwidth_lower_bound"
27
- BANDWIDTH_UPPER_BOUND = "bandwidth_upper_bound"
28
- BANDWIDTH_OPTIONS = "bandwidth_options"
29
- IF_GAIN_UPPER_BOUND = "if_gain_upper_bound"
30
- RF_GAIN_UPPER_BOUND = "rf_gain_upper_bound"
31
- API_RETUNING_LATENCY = "api_retuning_latency"
28
+ FREQUENCY_LOWER_BOUND = "frequency_lower_bound"
29
+ FREQUENCY_UPPER_BOUND = "frequency_upper_bound"
30
+ SAMPLE_RATE_LOWER_BOUND = "sample_rate_lower_bound"
31
+ SAMPLE_RATE_UPPER_BOUND = "sample_rate_upper_bound"
32
+ BANDWIDTH_LOWER_BOUND = "bandwidth_lower_bound"
33
+ BANDWIDTH_UPPER_BOUND = "bandwidth_upper_bound"
34
+ BANDWIDTH_OPTIONS = "bandwidth_options"
35
+ IF_GAIN_UPPER_BOUND = "if_gain_upper_bound"
36
+ RF_GAIN_UPPER_BOUND = "rf_gain_upper_bound"
37
+ GAIN_UPPER_BOUND = "gain_upper_bound"
38
+ WIRE_FORMATS = "wire_formats"
39
+ MASTER_CLOCK_RATE_LOWER_BOUND = "master_clock_rate_lower_bound"
40
+ MASTER_CLOCK_RATE_UPPER_BOUND = "master_clock_rate_upper_bound"
41
+ API_RETUNING_LATENCY = "api_retuning_latency"
@@ -0,0 +1,84 @@
1
+ # SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
2
+ # This file is part of SPECTRE
3
+ # SPDX-License-Identifier: GPL-3.0-or-later
4
+
5
+ from dataclasses import dataclass
6
+
7
+ from ._receiver_names import ReceiverName
8
+ from ._usrp import (
9
+ get_pvalidator_fixed_center_frequency, get_pvalidator_swept_center_frequency,
10
+ get_capture_template_fixed_center_frequency, get_capture_template_swept_center_frequency
11
+ )
12
+ from .gr._usrp import CaptureMethod
13
+ from .._spec_names import SpecName
14
+ from .._base import BaseReceiver
15
+ from .._register import register_receiver
16
+
17
+ @dataclass(frozen=True)
18
+ class Mode:
19
+ """An operating mode for the `B200mini` receiver."""
20
+ FIXED_CENTER_FREQUENCY = "fixed_center_frequency"
21
+ SWEPT_CENTER_FREQUENCY = "swept_center_frequency"
22
+
23
+
24
+ @register_receiver(ReceiverName.B200MINI)
25
+ class B200mini(BaseReceiver):
26
+ """Receiver implementation for the USRP B200mini (https://www.ettus.com/all-products/usrp-b200mini/)"""
27
+ def _add_specs(
28
+ self
29
+ ) -> None:
30
+ self.add_spec( SpecName.SAMPLE_RATE_LOWER_BOUND , 200e3 )
31
+ self.add_spec( SpecName.SAMPLE_RATE_UPPER_BOUND , 56e6 )
32
+ self.add_spec( SpecName.FREQUENCY_LOWER_BOUND , 70e6 )
33
+ self.add_spec( SpecName.FREQUENCY_UPPER_BOUND , 6e9 )
34
+ self.add_spec( SpecName.BANDWIDTH_LOWER_BOUND , 200e3 )
35
+ self.add_spec( SpecName.BANDWIDTH_UPPER_BOUND , 56e6 )
36
+ self.add_spec( SpecName.GAIN_UPPER_BOUND , 76 )
37
+ self.add_spec( SpecName.WIRE_FORMATS , ["sc8", "sc12", "sc16"])
38
+ self.add_spec( SpecName.MASTER_CLOCK_RATE_LOWER_BOUND, 5e6)
39
+ self.add_spec( SpecName.MASTER_CLOCK_RATE_UPPER_BOUND, 61.44e6)
40
+ self.add_spec( SpecName.API_RETUNING_LATENCY , 1e-5 ) # TODO: This is a ballpark, pending empirical testing
41
+
42
+
43
+ def _add_capture_methods(
44
+ self
45
+ ) -> None:
46
+ self.add_capture_method(Mode.FIXED_CENTER_FREQUENCY,
47
+ CaptureMethod.fixed_center_frequency)
48
+ self.add_capture_method(Mode.SWEPT_CENTER_FREQUENCY,
49
+ CaptureMethod.swept_center_frequency)
50
+
51
+
52
+ def _add_capture_templates(
53
+ self
54
+ ) -> None:
55
+ self.add_capture_template(Mode.FIXED_CENTER_FREQUENCY,
56
+ get_capture_template_fixed_center_frequency(self))
57
+ self.add_capture_template(Mode.SWEPT_CENTER_FREQUENCY,
58
+ get_capture_template_swept_center_frequency(self))
59
+
60
+
61
+ def _add_pvalidators(
62
+ self
63
+ ) -> None:
64
+ self.add_pvalidator(Mode.FIXED_CENTER_FREQUENCY,
65
+ get_pvalidator_fixed_center_frequency(self))
66
+ self.add_pvalidator(Mode.SWEPT_CENTER_FREQUENCY,
67
+ get_pvalidator_swept_center_frequency(self))
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+
80
+
81
+
82
+
83
+
84
+
@@ -10,7 +10,9 @@ class ReceiverName(Enum):
10
10
  :ivar RSP1A: SDRPlay RSP1A
11
11
  :ivar RSPDUO: SDRPlay RSPduo
12
12
  :ivar TEST: `spectre` test receiver.
13
+ :ivar B200MINI: USRP B200mini.
13
14
  """
14
- RSP1A = "rsp1a"
15
- RSPDUO = "rspduo"
16
- TEST = "test"
15
+ RSP1A = "rsp1a"
16
+ RSPDUO = "rspduo"
17
+ TEST = "test"
18
+ B200MINI = "b200mini"
@@ -6,8 +6,12 @@ from dataclasses import dataclass
6
6
 
7
7
  from ._receiver_names import ReceiverName
8
8
  from .gr._rsp1a import CaptureMethod
9
+ from ._sdrplay_receiver import (
10
+ get_pvalidator_fixed_center_frequency, get_pvalidator_swept_center_frequency,
11
+ get_capture_template_fixed_center_frequency, get_capture_template_swept_center_frequency
12
+ )
9
13
  from .._spec_names import SpecName
10
- from ._sdrplay_receiver import SDRPlayReceiver
14
+ from .._base import BaseReceiver
11
15
  from .._register import register_receiver
12
16
 
13
17
  @dataclass(frozen=True)
@@ -18,9 +22,11 @@ class Mode:
18
22
 
19
23
 
20
24
  @register_receiver(ReceiverName.RSP1A)
21
- class RSP1A(SDRPlayReceiver):
25
+ class RSP1A(BaseReceiver):
22
26
  """Receiver implementation for the SDRPlay RSP1A (https://www.sdrplay.com/rsp1a/)"""
23
- def _add_specs(self) -> None:
27
+ def _add_specs(
28
+ self
29
+ ) -> None:
24
30
  self.add_spec( SpecName.SAMPLE_RATE_LOWER_BOUND, 200e3 )
25
31
  self.add_spec( SpecName.SAMPLE_RATE_UPPER_BOUND, 10e6 )
26
32
  self.add_spec( SpecName.FREQUENCY_LOWER_BOUND , 1e3 )
@@ -45,15 +51,15 @@ class RSP1A(SDRPlayReceiver):
45
51
  self
46
52
  ) -> None:
47
53
  self.add_capture_template(Mode.FIXED_CENTER_FREQUENCY,
48
- self._get_capture_template_fixed_center_frequency())
54
+ get_capture_template_fixed_center_frequency(self))
49
55
  self.add_capture_template(Mode.SWEPT_CENTER_FREQUENCY,
50
- self._get_capture_template_swept_center_frequency())
56
+ get_capture_template_swept_center_frequency(self))
51
57
 
52
58
 
53
59
  def _add_pvalidators(
54
60
  self
55
61
  ) -> None:
56
62
  self.add_pvalidator(Mode.FIXED_CENTER_FREQUENCY,
57
- self._get_pvalidator_fixed_center_frequency())
63
+ get_pvalidator_fixed_center_frequency(self))
58
64
  self.add_pvalidator(Mode.SWEPT_CENTER_FREQUENCY,
59
- self._get_pvalidator_swept_center_frequency())
65
+ get_pvalidator_swept_center_frequency(self))
@@ -7,7 +7,11 @@ from dataclasses import dataclass
7
7
  from ._receiver_names import ReceiverName
8
8
  from .gr._rspduo import CaptureMethod
9
9
  from .._spec_names import SpecName
10
- from ._sdrplay_receiver import SDRPlayReceiver
10
+ from ._sdrplay_receiver import (
11
+ get_pvalidator_fixed_center_frequency, get_pvalidator_swept_center_frequency,
12
+ get_capture_template_fixed_center_frequency, get_capture_template_swept_center_frequency
13
+ )
14
+ from .._base import BaseReceiver
11
15
  from .._register import register_receiver
12
16
 
13
17
 
@@ -20,7 +24,7 @@ class Mode:
20
24
 
21
25
 
22
26
  @register_receiver(ReceiverName.RSPDUO)
23
- class RSPduo(SDRPlayReceiver):
27
+ class RSPduo(BaseReceiver):
24
28
  """Receiver implementation for the SDRPlay RSPduo (https://www.sdrplay.com/rspduo/)"""
25
29
  def _add_specs(self) -> None:
26
30
  self.add_spec( SpecName.SAMPLE_RATE_LOWER_BOUND, 200e3 )
@@ -49,19 +53,19 @@ class RSPduo(SDRPlayReceiver):
49
53
  self
50
54
  ) -> None:
51
55
  self.add_capture_template(Mode.TUNER_1_FIXED_CENTER_FREQUENCY,
52
- self._get_capture_template_fixed_center_frequency())
56
+ get_capture_template_fixed_center_frequency(self))
53
57
  self.add_capture_template(Mode.TUNER_2_FIXED_CENTER_FREQUENCY,
54
- self._get_capture_template_fixed_center_frequency())
58
+ get_capture_template_fixed_center_frequency(self))
55
59
  self.add_capture_template(Mode.TUNER_1_SWEPT_CENTER_FREQUENCY,
56
- self._get_capture_template_swept_center_frequency())
60
+ get_capture_template_swept_center_frequency(self))
57
61
 
58
62
 
59
63
  def _add_pvalidators(
60
64
  self
61
65
  ) -> None:
62
66
  self.add_pvalidator(Mode.TUNER_1_FIXED_CENTER_FREQUENCY,
63
- self._get_pvalidator_fixed_center_frequency())
67
+ get_pvalidator_fixed_center_frequency(self))
64
68
  self.add_pvalidator(Mode.TUNER_2_FIXED_CENTER_FREQUENCY,
65
- self._get_pvalidator_fixed_center_frequency())
69
+ get_pvalidator_fixed_center_frequency(self))
66
70
  self.add_pvalidator(Mode.TUNER_1_SWEPT_CENTER_FREQUENCY,
67
- self._get_pvalidator_swept_center_frequency())
71
+ get_pvalidator_swept_center_frequency(self))
@@ -12,179 +12,163 @@ from spectre_core.capture_configs import (
12
12
  from .._base import BaseReceiver
13
13
  from .._spec_names import SpecName
14
14
 
15
- class SDRPlayReceiver(BaseReceiver):
16
- """An abstract base class for SDRPlay receivers.
17
-
18
- Includes ready-to-go pvalidators and capture templates which are shared by all subclasses.
19
- Each subclasses must define the following hardware specifications:
20
-
21
- .. code-block:: python
22
- def _add_specs(self) -> None:
23
- self.add_spec( SpecName.SAMPLE_RATE_LOWER_BOUND, <TBD> )
24
- self.add_spec( SpecName.SAMPLE_RATE_UPPER_BOUND, <TBD> )
25
- self.add_spec( SpecName.FREQUENCY_LOWER_BOUND , <TBD> )
26
- self.add_spec( SpecName.FREQUENCY_UPPER_BOUND , <TBD> )
27
- self.add_spec( SpecName.IF_GAIN_UPPER_BOUND , <TBD> )
28
- self.add_spec( SpecName.RF_GAIN_UPPER_BOUND , <TBD> )
29
- self.add_spec( SpecName.API_RETUNING_LATENCY , <TBD> )
30
- self.add_spec( SpecName.BANDWIDTH_OPTIONS , <TBD> )
31
- """
32
- def _get_pvalidator_fixed_center_frequency(
33
- self
34
- ) -> Callable[[Parameters], None]:
35
- def pvalidator(parameters: Parameters):
36
- validate_fixed_center_frequency(parameters)
37
- return pvalidator
38
15
 
16
+ def get_pvalidator_fixed_center_frequency(
17
+ sdrplay_receiver: BaseReceiver
18
+ ) -> Callable[[Parameters], None]:
19
+ def pvalidator(parameters: Parameters) -> None:
20
+ validate_fixed_center_frequency(parameters)
21
+ return pvalidator
39
22
 
40
- def _get_pvalidator_swept_center_frequency(
41
- self
42
- ) -> Callable[[Parameters], None]:
43
- def pvalidator(parameters: Parameters):
44
- validate_swept_center_frequency(parameters,
45
- self.get_spec(SpecName.API_RETUNING_LATENCY))
46
- return pvalidator
47
23
 
24
+ def get_pvalidator_swept_center_frequency(
25
+ sdrplay_receiver: BaseReceiver
26
+ ) -> Callable[[Parameters], None]:
27
+ def pvalidator(parameters: Parameters) -> None:
28
+ validate_swept_center_frequency(parameters,
29
+ sdrplay_receiver.get_spec(SpecName.API_RETUNING_LATENCY))
30
+ return pvalidator
48
31
 
49
- def _get_capture_template_fixed_center_frequency(
50
- self
51
- ) -> CaptureTemplate:
52
-
53
- capture_template = get_base_capture_template( CaptureMode.FIXED_CENTER_FREQUENCY )
54
- capture_template.add_ptemplate( get_base_ptemplate(PName.BANDWIDTH) )
55
- capture_template.add_ptemplate( get_base_ptemplate(PName.IF_GAIN) )
56
- capture_template.add_ptemplate( get_base_ptemplate(PName.RF_GAIN) )
57
32
 
58
- capture_template.set_defaults(
59
- (PName.BATCH_SIZE, 3.0),
60
- (PName.CENTER_FREQUENCY, 95800000),
61
- (PName.SAMPLE_RATE, 600000),
62
- (PName.BANDWIDTH, 600000),
63
- (PName.WINDOW_HOP, 512),
64
- (PName.WINDOW_SIZE, 1024),
65
- (PName.WINDOW_TYPE, "blackman"),
66
- (PName.RF_GAIN, -30),
67
- (PName.IF_GAIN, -30)
68
- )
33
+ def get_capture_template_fixed_center_frequency(
34
+ sdrplay_receiver: BaseReceiver
35
+ ) -> CaptureTemplate:
36
+
37
+ capture_template = get_base_capture_template( CaptureMode.FIXED_CENTER_FREQUENCY )
38
+ capture_template.add_ptemplate( get_base_ptemplate(PName.BANDWIDTH) )
39
+ capture_template.add_ptemplate( get_base_ptemplate(PName.IF_GAIN) )
40
+ capture_template.add_ptemplate( get_base_ptemplate(PName.RF_GAIN) )
41
+
42
+ capture_template.set_defaults(
43
+ (PName.BATCH_SIZE, 3.0),
44
+ (PName.CENTER_FREQUENCY, 95800000),
45
+ (PName.SAMPLE_RATE, 600000),
46
+ (PName.BANDWIDTH, 600000),
47
+ (PName.WINDOW_HOP, 512),
48
+ (PName.WINDOW_SIZE, 1024),
49
+ (PName.WINDOW_TYPE, "blackman"),
50
+ (PName.RF_GAIN, -30),
51
+ (PName.IF_GAIN, -30)
52
+ )
69
53
 
70
- capture_template.add_pconstraint(
71
- PName.CENTER_FREQUENCY,
72
- [
73
- Bound(
74
- lower_bound=self.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
75
- upper_bound=self.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
76
- )
77
- ]
78
- )
79
- capture_template.add_pconstraint(
80
- PName.SAMPLE_RATE,
81
- [
82
- Bound(
83
- lower_bound=self.get_spec(SpecName.SAMPLE_RATE_LOWER_BOUND),
84
- upper_bound=self.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND)
85
- )
86
- ]
87
- )
88
- capture_template.add_pconstraint(
89
- PName.BANDWIDTH,
90
- [
91
- OneOf(
92
- self.get_spec( SpecName.BANDWIDTH_OPTIONS )
93
- )
94
- ]
95
- )
96
- capture_template.add_pconstraint(
97
- PName.IF_GAIN,
98
- [
99
- Bound(
100
- upper_bound=self.get_spec(SpecName.IF_GAIN_UPPER_BOUND)
101
- )
102
- ]
103
- )
104
- capture_template.add_pconstraint(
105
- PName.RF_GAIN,
106
- [
107
- Bound(
108
- upper_bound=self.get_spec(SpecName.RF_GAIN_UPPER_BOUND)
109
- )
110
- ]
111
- )
112
- return capture_template
54
+ capture_template.add_pconstraint(
55
+ PName.CENTER_FREQUENCY,
56
+ [
57
+ Bound(
58
+ lower_bound=sdrplay_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
59
+ upper_bound=sdrplay_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
60
+ )
61
+ ]
62
+ )
63
+ capture_template.add_pconstraint(
64
+ PName.SAMPLE_RATE,
65
+ [
66
+ Bound(
67
+ lower_bound=sdrplay_receiver.get_spec(SpecName.SAMPLE_RATE_LOWER_BOUND),
68
+ upper_bound=sdrplay_receiver.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND)
69
+ )
70
+ ]
71
+ )
72
+ capture_template.add_pconstraint(
73
+ PName.BANDWIDTH,
74
+ [
75
+ OneOf(
76
+ sdrplay_receiver.get_spec( SpecName.BANDWIDTH_OPTIONS )
77
+ )
78
+ ]
79
+ )
80
+ capture_template.add_pconstraint(
81
+ PName.IF_GAIN,
82
+ [
83
+ Bound(
84
+ upper_bound=sdrplay_receiver.get_spec(SpecName.IF_GAIN_UPPER_BOUND)
85
+ )
86
+ ]
87
+ )
88
+ capture_template.add_pconstraint(
89
+ PName.RF_GAIN,
90
+ [
91
+ Bound(
92
+ upper_bound=sdrplay_receiver.get_spec(SpecName.RF_GAIN_UPPER_BOUND)
93
+ )
94
+ ]
95
+ )
96
+ return capture_template
113
97
 
114
98
 
115
- def _get_capture_template_swept_center_frequency(
116
- self
117
- ) -> CaptureTemplate:
99
+ def get_capture_template_swept_center_frequency(
100
+ sdrplay_receiver: BaseReceiver
101
+ ) -> CaptureTemplate:
118
102
 
119
- capture_template = get_base_capture_template( CaptureMode.SWEPT_CENTER_FREQUENCY )
120
- capture_template.add_ptemplate( get_base_ptemplate(PName.BANDWIDTH) )
121
- capture_template.add_ptemplate( get_base_ptemplate(PName.IF_GAIN) )
122
- capture_template.add_ptemplate( get_base_ptemplate(PName.RF_GAIN) )
103
+ capture_template = get_base_capture_template( CaptureMode.SWEPT_CENTER_FREQUENCY )
104
+ capture_template.add_ptemplate( get_base_ptemplate(PName.BANDWIDTH) )
105
+ capture_template.add_ptemplate( get_base_ptemplate(PName.IF_GAIN) )
106
+ capture_template.add_ptemplate( get_base_ptemplate(PName.RF_GAIN) )
123
107
 
124
- capture_template.set_defaults(
125
- (PName.BATCH_SIZE, 4.0),
126
- (PName.MIN_FREQUENCY, 95000000),
127
- (PName.MAX_FREQUENCY, 100000000),
128
- (PName.SAMPLES_PER_STEP, 80000),
129
- (PName.FREQUENCY_STEP, 1536000),
130
- (PName.SAMPLE_RATE, 1536000),
131
- (PName.BANDWIDTH, 1536000),
132
- (PName.WINDOW_HOP, 512),
133
- (PName.WINDOW_SIZE, 1024),
134
- (PName.WINDOW_TYPE, "blackman"),
135
- (PName.RF_GAIN, -30),
136
- (PName.IF_GAIN, -30)
137
- )
108
+ capture_template.set_defaults(
109
+ (PName.BATCH_SIZE, 4.0),
110
+ (PName.MIN_FREQUENCY, 95000000),
111
+ (PName.MAX_FREQUENCY, 100000000),
112
+ (PName.SAMPLES_PER_STEP, 80000),
113
+ (PName.FREQUENCY_STEP, 1536000),
114
+ (PName.SAMPLE_RATE, 1536000),
115
+ (PName.BANDWIDTH, 1536000),
116
+ (PName.WINDOW_HOP, 512),
117
+ (PName.WINDOW_SIZE, 1024),
118
+ (PName.WINDOW_TYPE, "blackman"),
119
+ (PName.RF_GAIN, -30),
120
+ (PName.IF_GAIN, -30)
121
+ )
138
122
 
139
- capture_template.add_pconstraint(
140
- PName.MIN_FREQUENCY,
141
- [
142
- Bound(
143
- lower_bound=self.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
144
- upper_bound=self.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
145
- )
146
- ]
147
- )
148
- capture_template.add_pconstraint(
149
- PName.MAX_FREQUENCY,
150
- [
151
- Bound(
152
- lower_bound=self.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
153
- upper_bound=self.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
154
- )
155
- ]
156
- )
157
- capture_template.add_pconstraint(
158
- PName.SAMPLE_RATE,
159
- [
160
- Bound(
161
- lower_bound=self.get_spec(SpecName.SAMPLE_RATE_LOWER_BOUND),
162
- upper_bound=self.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND)
163
- )
164
- ]
165
- )
166
- capture_template.add_pconstraint(
167
- PName.BANDWIDTH,
168
- [
169
- OneOf(
170
- self.get_spec( SpecName.BANDWIDTH_OPTIONS )
171
- )
172
- ]
173
- )
174
- capture_template.add_pconstraint(
175
- PName.IF_GAIN,
176
- [
177
- Bound(
178
- upper_bound=self.get_spec(SpecName.IF_GAIN_UPPER_BOUND)
179
- )
180
- ]
181
- )
182
- capture_template.add_pconstraint(
183
- PName.RF_GAIN,
184
- [
185
- Bound(
186
- upper_bound=self.get_spec(SpecName.RF_GAIN_UPPER_BOUND)
187
- )
188
- ]
189
- )
190
- return capture_template
123
+ capture_template.add_pconstraint(
124
+ PName.MIN_FREQUENCY,
125
+ [
126
+ Bound(
127
+ lower_bound=sdrplay_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
128
+ upper_bound=sdrplay_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
129
+ )
130
+ ]
131
+ )
132
+ capture_template.add_pconstraint(
133
+ PName.MAX_FREQUENCY,
134
+ [
135
+ Bound(
136
+ lower_bound=sdrplay_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
137
+ upper_bound=sdrplay_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
138
+ )
139
+ ]
140
+ )
141
+ capture_template.add_pconstraint(
142
+ PName.SAMPLE_RATE,
143
+ [
144
+ Bound(
145
+ lower_bound=sdrplay_receiver.get_spec(SpecName.SAMPLE_RATE_LOWER_BOUND),
146
+ upper_bound=sdrplay_receiver.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND)
147
+ )
148
+ ]
149
+ )
150
+ capture_template.add_pconstraint(
151
+ PName.BANDWIDTH,
152
+ [
153
+ OneOf(
154
+ sdrplay_receiver.get_spec( SpecName.BANDWIDTH_OPTIONS )
155
+ )
156
+ ]
157
+ )
158
+ capture_template.add_pconstraint(
159
+ PName.IF_GAIN,
160
+ [
161
+ Bound(
162
+ upper_bound=sdrplay_receiver.get_spec(SpecName.IF_GAIN_UPPER_BOUND)
163
+ )
164
+ ]
165
+ )
166
+ capture_template.add_pconstraint(
167
+ PName.RF_GAIN,
168
+ [
169
+ Bound(
170
+ upper_bound=sdrplay_receiver.get_spec(SpecName.RF_GAIN_UPPER_BOUND)
171
+ )
172
+ ]
173
+ )
174
+ return capture_template
@@ -0,0 +1,205 @@
1
+ # SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
2
+ # This file is part of SPECTRE
3
+ # SPDX-License-Identifier: GPL-3.0-or-later
4
+
5
+ from typing import Callable, overload
6
+
7
+ from spectre_core.capture_configs import (
8
+ CaptureTemplate, CaptureMode, Parameters, Bound, PName,
9
+ get_base_capture_template, get_base_ptemplate, OneOf,
10
+ validate_sample_rate_with_master_clock_rate,
11
+ validate_fixed_center_frequency, validate_swept_center_frequency
12
+ )
13
+ from .._base import BaseReceiver
14
+ from .._spec_names import SpecName
15
+
16
+
17
+ def get_pvalidator_fixed_center_frequency(
18
+ usrp_receiver: BaseReceiver
19
+ ) -> Callable[[Parameters], None]:
20
+ def pvalidator(parameters: Parameters) -> None:
21
+ validate_fixed_center_frequency(parameters)
22
+ validate_sample_rate_with_master_clock_rate(parameters)
23
+ return pvalidator
24
+
25
+
26
+ def get_pvalidator_swept_center_frequency(
27
+ usrp_receiver: BaseReceiver
28
+ ) -> Callable[[Parameters], None]:
29
+ def pvalidator(parameters: Parameters) -> None:
30
+ validate_swept_center_frequency(parameters,
31
+ usrp_receiver.get_spec(SpecName.API_RETUNING_LATENCY))
32
+ validate_sample_rate_with_master_clock_rate(parameters)
33
+ return pvalidator
34
+
35
+
36
+ def get_capture_template_fixed_center_frequency(
37
+ usrp_receiver: BaseReceiver
38
+ ) -> CaptureTemplate:
39
+
40
+ capture_template = get_base_capture_template( CaptureMode.FIXED_CENTER_FREQUENCY )
41
+ capture_template.add_ptemplate( get_base_ptemplate(PName.BANDWIDTH) )
42
+ capture_template.add_ptemplate( get_base_ptemplate(PName.GAIN) )
43
+ capture_template.add_ptemplate( get_base_ptemplate(PName.WIRE_FORMAT) )
44
+ capture_template.add_ptemplate( get_base_ptemplate(PName.MASTER_CLOCK_RATE) )
45
+
46
+ # TODO: Delegate defaults to receiver subclasses. Currently, these are sensible defaults for the b200mini
47
+ capture_template.set_defaults(
48
+ (PName.BATCH_SIZE, 4.0),
49
+ (PName.CENTER_FREQUENCY, 95800000),
50
+ (PName.SAMPLE_RATE, 2000000),
51
+ (PName.BANDWIDTH, 2000000),
52
+ (PName.WINDOW_HOP, 512),
53
+ (PName.WINDOW_SIZE, 1024),
54
+ (PName.WINDOW_TYPE, "blackman"),
55
+ (PName.GAIN, 35),
56
+ (PName.WIRE_FORMAT, "sc16"),
57
+ (PName.MASTER_CLOCK_RATE, 40e6)
58
+ )
59
+
60
+ capture_template.add_pconstraint(
61
+ PName.CENTER_FREQUENCY,
62
+ [
63
+ Bound(
64
+ lower_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
65
+ upper_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
66
+ )
67
+ ]
68
+ )
69
+ capture_template.add_pconstraint(
70
+ PName.SAMPLE_RATE,
71
+ [
72
+ Bound(
73
+ lower_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_LOWER_BOUND),
74
+ upper_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND)
75
+ )
76
+ ]
77
+ )
78
+ capture_template.add_pconstraint(
79
+ PName.BANDWIDTH,
80
+ [
81
+ Bound(
82
+ lower_bound=usrp_receiver.get_spec( SpecName.BANDWIDTH_LOWER_BOUND ),
83
+ upper_bound=usrp_receiver.get_spec( SpecName.BANDWIDTH_UPPER_BOUND )
84
+ )
85
+ ]
86
+ )
87
+ capture_template.add_pconstraint(
88
+ PName.GAIN,
89
+ [
90
+ Bound(
91
+ lower_bound=0,
92
+ upper_bound=usrp_receiver.get_spec( SpecName.GAIN_UPPER_BOUND )
93
+ )
94
+ ]
95
+ )
96
+ capture_template.add_pconstraint(
97
+ PName.WIRE_FORMAT,
98
+ [
99
+ OneOf(
100
+ usrp_receiver.get_spec( SpecName.WIRE_FORMATS )
101
+ )
102
+ ]
103
+ )
104
+ capture_template.add_pconstraint(
105
+ PName.MASTER_CLOCK_RATE,
106
+ [
107
+ Bound(
108
+ lower_bound=usrp_receiver.get_spec( SpecName.MASTER_CLOCK_RATE_LOWER_BOUND ),
109
+ upper_bound=usrp_receiver.get_spec( SpecName.MASTER_CLOCK_RATE_UPPER_BOUND )
110
+ )
111
+ ]
112
+ )
113
+ return capture_template
114
+
115
+
116
+ def get_capture_template_swept_center_frequency(
117
+ usrp_receiver: BaseReceiver
118
+ ) -> CaptureTemplate:
119
+
120
+ capture_template = get_base_capture_template( CaptureMode.SWEPT_CENTER_FREQUENCY )
121
+ capture_template.add_ptemplate( get_base_ptemplate(PName.BANDWIDTH) )
122
+ capture_template.add_ptemplate( get_base_ptemplate(PName.GAIN) )
123
+ capture_template.add_ptemplate( get_base_ptemplate(PName.WIRE_FORMAT) )
124
+ capture_template.add_ptemplate( get_base_ptemplate(PName.MASTER_CLOCK_RATE) )
125
+
126
+ # TODO: Delegate defaults to receiver subclasses. Currently, these are sensible defaults for the b200mini
127
+ capture_template.set_defaults(
128
+ (PName.BATCH_SIZE, 4.0),
129
+ (PName.MIN_FREQUENCY, 95000000),
130
+ (PName.MAX_FREQUENCY, 105000000),
131
+ (PName.SAMPLES_PER_STEP, 30000),
132
+ (PName.FREQUENCY_STEP, 2000000),
133
+ (PName.SAMPLE_RATE, 2000000),
134
+ (PName.BANDWIDTH, 2000000),
135
+ (PName.WINDOW_HOP, 512),
136
+ (PName.WINDOW_SIZE, 1024),
137
+ (PName.WINDOW_TYPE, "blackman"),
138
+ (PName.GAIN, 35),
139
+ (PName.WIRE_FORMAT, "sc16"),
140
+ (PName.MASTER_CLOCK_RATE, 40e6)
141
+ )
142
+
143
+ capture_template.add_pconstraint(
144
+ PName.MIN_FREQUENCY,
145
+ [
146
+ Bound(
147
+ lower_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
148
+ upper_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
149
+ )
150
+ ]
151
+ )
152
+ capture_template.add_pconstraint(
153
+ PName.MAX_FREQUENCY,
154
+ [
155
+ Bound(
156
+ lower_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
157
+ upper_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
158
+ )
159
+ ]
160
+ )
161
+ capture_template.add_pconstraint(
162
+ PName.SAMPLE_RATE,
163
+ [
164
+ Bound(
165
+ lower_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_LOWER_BOUND),
166
+ upper_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND)
167
+ )
168
+ ]
169
+ )
170
+ capture_template.add_pconstraint(
171
+ PName.BANDWIDTH,
172
+ [
173
+ Bound(
174
+ lower_bound=usrp_receiver.get_spec(SpecName.BANDWIDTH_LOWER_BOUND),
175
+ upper_bound=usrp_receiver.get_spec(SpecName.BANDWIDTH_UPPER_BOUND),
176
+ )
177
+ ]
178
+ )
179
+ capture_template.add_pconstraint(
180
+ PName.GAIN,
181
+ [
182
+ Bound(
183
+ lower_bound=0,
184
+ upper_bound=usrp_receiver.get_spec( SpecName.GAIN_UPPER_BOUND )
185
+ )
186
+ ]
187
+ )
188
+ capture_template.add_pconstraint(
189
+ PName.WIRE_FORMAT,
190
+ [
191
+ OneOf(
192
+ usrp_receiver.get_spec( SpecName.WIRE_FORMATS )
193
+ )
194
+ ]
195
+ )
196
+ capture_template.add_pconstraint(
197
+ PName.MASTER_CLOCK_RATE,
198
+ [
199
+ Bound(
200
+ lower_bound=usrp_receiver.get_spec( SpecName.MASTER_CLOCK_RATE_LOWER_BOUND ),
201
+ upper_bound=usrp_receiver.get_spec( SpecName.MASTER_CLOCK_RATE_UPPER_BOUND )
202
+ )
203
+ ]
204
+ )
205
+ return capture_template
@@ -1,17 +1,3 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
-
4
- #
5
- # SPDX-License-Identifier: GPL-3.0
6
- #
7
- # GNU Radio Python Flow Graph
8
- # Title: Test receiver
9
- # GNU Radio version: 3.10.1.1
10
-
11
- # SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
12
- # This file is part of SPECTRE
13
- # SPDX-License-Identifier: GPL-3.0-or-later
14
-
15
1
  #
16
2
  # RSP1A receiver top blocks
17
3
  #
@@ -145,4 +131,4 @@ class _swept_center_frequency(spectre_top_block):
145
131
  @dataclass(frozen=True)
146
132
  class CaptureMethod:
147
133
  fixed_center_frequency = partial(capture, top_block_cls=_fixed_center_frequency)
148
- swept_center_frequency = partial(capture, top_block_cls=_swept_center_frequency, max_noutput_items=1024)
134
+ swept_center_frequency = partial(capture, top_block_cls=_swept_center_frequency, max_noutput_items=1024)
@@ -0,0 +1,139 @@
1
+ #
2
+ # USRP top blocks
3
+ #
4
+
5
+ from functools import partial
6
+ from dataclasses import dataclass
7
+ import time
8
+
9
+ from logging import getLogger
10
+ _LOGGER = getLogger(__name__)
11
+
12
+ from spectre_core.capture_configs import Parameters, PName
13
+ from spectre_core.config import get_batches_dir_path
14
+ from ._base import capture, spectre_top_block
15
+
16
+
17
+ class _fixed_center_frequency(spectre_top_block):
18
+ def flowgraph(
19
+ self,
20
+ tag: str,
21
+ parameters: Parameters
22
+ ) -> None:
23
+ # OOT moudle inline imports
24
+ from gnuradio import spectre
25
+ from gnuradio import uhd
26
+
27
+ # Unpack capture config parameters
28
+ sample_rate = parameters.get_parameter_value(PName.SAMPLE_RATE)
29
+ gain = parameters.get_parameter_value(PName.GAIN)
30
+ center_freq = parameters.get_parameter_value(PName.CENTER_FREQUENCY)
31
+ master_clock_rate = parameters.get_parameter_value(PName.MASTER_CLOCK_RATE)
32
+ wire_format = parameters.get_parameter_value(PName.WIRE_FORMAT)
33
+ batch_size = parameters.get_parameter_value(PName.BATCH_SIZE)
34
+ bandwidth = parameters.get_parameter_value(PName.BANDWIDTH)
35
+
36
+ # Blocks
37
+ master_clock_rate = f"master_clock_rate={master_clock_rate}"
38
+ self.uhd_usrp_source_0 = uhd.usrp_source(
39
+ ",".join(("", '', master_clock_rate)),
40
+ uhd.stream_args(
41
+ cpu_format="fc32",
42
+ otw_format=wire_format,
43
+ args='',
44
+ channels=[0],
45
+ ),
46
+ )
47
+ self.uhd_usrp_source_0.set_samp_rate(sample_rate)
48
+ self.uhd_usrp_source_0.set_time_now(uhd.time_spec(time.time()), uhd.ALL_MBOARDS)
49
+
50
+ self.uhd_usrp_source_0.set_center_freq(center_freq, 0)
51
+ self.uhd_usrp_source_0.set_antenna("RX2", 0)
52
+ self.uhd_usrp_source_0.set_bandwidth(bandwidth, 0)
53
+ self.uhd_usrp_source_0.set_rx_agc(False, 0)
54
+ self.uhd_usrp_source_0.set_auto_dc_offset(False, 0)
55
+ self.uhd_usrp_source_0.set_auto_iq_balance(False, 0)
56
+ self.uhd_usrp_source_0.set_gain(gain, 0)
57
+ self.spectre_batched_file_sink_0 = spectre.batched_file_sink(get_batches_dir_path(),
58
+ tag,
59
+ batch_size,
60
+ sample_rate, False,
61
+ 'rx_freq',
62
+ 0)
63
+
64
+
65
+ # Connections
66
+ self.connect((self.uhd_usrp_source_0, 0), (self.spectre_batched_file_sink_0, 0))
67
+
68
+
69
+ class _swept_center_frequency(spectre_top_block):
70
+ def flowgraph(
71
+ self,
72
+ tag: str,
73
+ parameters: Parameters
74
+ ) -> None:
75
+ # OOT module inline imports
76
+ from gnuradio import spectre
77
+ from gnuradio import uhd
78
+
79
+ # Unpack capture config parameters
80
+ sample_rate = parameters.get_parameter_value(PName.SAMPLE_RATE)
81
+ bandwidth = parameters.get_parameter_value(PName.BANDWIDTH)
82
+ min_frequency = parameters.get_parameter_value(PName.MIN_FREQUENCY)
83
+ max_frequency = parameters.get_parameter_value(PName.MAX_FREQUENCY)
84
+ frequency_step = parameters.get_parameter_value(PName.FREQUENCY_STEP)
85
+ samples_per_step = parameters.get_parameter_value(PName.SAMPLES_PER_STEP)
86
+ master_clock_rate = parameters.get_parameter_value(PName.MASTER_CLOCK_RATE)
87
+ master_clock_rate = master_clock_rate = parameters.get_parameter_value(PName.MASTER_CLOCK_RATE)
88
+ wire_format = parameters.get_parameter_value(PName.WIRE_FORMAT)
89
+ gain = parameters.get_parameter_value(PName.GAIN)
90
+ batch_size = parameters.get_parameter_value(PName.BATCH_SIZE)
91
+
92
+ # Blocks
93
+ _LOGGER.warning(f"USRP frequency sweep modes will not work as expected until a known bug is fixed in the USRP source block. "
94
+ f"Please refer to this GitHub issue for more information: https://github.com/gnuradio/gnuradio/issues/7725")
95
+ master_clock_rate = f"master_clock_rate={master_clock_rate}"
96
+ self.uhd_usrp_source_0 = uhd.usrp_source(
97
+ ",".join(("", '', master_clock_rate)),
98
+ uhd.stream_args(
99
+ cpu_format="fc32",
100
+ otw_format=wire_format,
101
+ args='',
102
+ channels=[0],
103
+ ),
104
+ )
105
+ self.uhd_usrp_source_0.set_samp_rate(sample_rate)
106
+ self.uhd_usrp_source_0.set_time_now(uhd.time_spec(time.time()), uhd.ALL_MBOARDS)
107
+ self.uhd_usrp_source_0.set_center_freq(min_frequency, 0)
108
+ self.uhd_usrp_source_0.set_antenna("RX2", 0)
109
+ self.uhd_usrp_source_0.set_bandwidth(bandwidth, 0)
110
+ self.uhd_usrp_source_0.set_rx_agc(False, 0)
111
+ self.uhd_usrp_source_0.set_auto_dc_offset(False, 0)
112
+ self.uhd_usrp_source_0.set_auto_iq_balance(False, 0)
113
+ self.uhd_usrp_source_0.set_gain(gain, 0)
114
+
115
+ self.spectre_sweep_driver_0 = spectre.sweep_driver(min_frequency,
116
+ max_frequency,
117
+ frequency_step,
118
+ sample_rate,
119
+ samples_per_step,
120
+ 'freq')
121
+
122
+ self.spectre_batched_file_sink_0 = spectre.batched_file_sink(get_batches_dir_path(),
123
+ tag,
124
+ batch_size,
125
+ sample_rate,
126
+ True,
127
+ 'rx_freq',
128
+ min_frequency)
129
+
130
+ # Connections
131
+ self.msg_connect((self.spectre_sweep_driver_0, 'freq'), (self.uhd_usrp_source_0, 'command'))
132
+ self.connect((self.uhd_usrp_source_0, 0), (self.spectre_batched_file_sink_0, 0))
133
+ self.connect((self.uhd_usrp_source_0, 0), (self.spectre_sweep_driver_0, 0))
134
+
135
+
136
+ @dataclass(frozen=True)
137
+ class CaptureMethod:
138
+ fixed_center_frequency = partial(capture, top_block_cls=_fixed_center_frequency)
139
+ swept_center_frequency = partial(capture, top_block_cls=_swept_center_frequency, max_noutput_items=1024)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: spectre-core
3
- Version: 0.0.14
3
+ Version: 0.0.16
4
4
  Summary: The core Python package used by the spectre program.
5
5
  Maintainer-email: Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -11,15 +11,15 @@ spectre_core/batches/_register.py,sha256=dSQC8KXj_jG8EiPwmKPdV0HSSalIZLaWt-8E29s
11
11
  spectre_core/batches/plugins/_batch_keys.py,sha256=8v0KE1n0NAQX0i9SwwB4Lgkct7Q_jna-H5S0Gs6p1qg,544
12
12
  spectre_core/batches/plugins/_callisto.py,sha256=ijm-VzGGlLQJjB2eQWw-04R6belCJ_NzSL9Jr7VTu2Q,6259
13
13
  spectre_core/batches/plugins/_iq_stream.py,sha256=DSto5ZzPk7A4VAe_HUAKNd2M9NuWqxcL--_Vneo08Bc,12583
14
- spectre_core/capture_configs/__init__.py,sha256=sUgwilZvQHAexAw_wao49qoBnu0CEBHIicI1kNfvCHg,1645
14
+ spectre_core/capture_configs/__init__.py,sha256=bhwp1Kf2llzd8HpkMPxeM_ZJoIoCFLQoMZJ44AAH6s0,1738
15
15
  spectre_core/capture_configs/_capture_config.py,sha256=ngbIzySgjsgBRJyrfgYZrJtr0wqcKDn8xBH0T1vi-yY,4546
16
16
  spectre_core/capture_configs/_capture_modes.py,sha256=uFBMwHYJCDqqQfYJvAUKzKXTmSBANRZMLlRSKV8WRb8,898
17
17
  spectre_core/capture_configs/_capture_templates.py,sha256=nSAxhOh1DeBzYY16evgOTkDuxRugGG5weJsICUouLPQ,10353
18
18
  spectre_core/capture_configs/_parameters.py,sha256=9KoNuwzDKtnyeju53fkImi1SeUjDn89cNwDL8zxX-YU,5563
19
19
  spectre_core/capture_configs/_pconstraints.py,sha256=bnl1m6M9iyo5KOsPKT_arwrrAZbxRKXVwTHQACzvs2g,5227
20
- spectre_core/capture_configs/_pnames.py,sha256=05mrrGfYHudaD2dYyukijbW-YtUnifZRn05xcBGv-fI,1852
21
- spectre_core/capture_configs/_ptemplates.py,sha256=p4lOi6W5B9gWv0d6ryNK9f_zxLHsj5PWW8Lmdco9ofg,24508
22
- spectre_core/capture_configs/_pvalidators.py,sha256=0W-OMDY1lifRPonwgEAwoMYkA0PWbqlK5nE0zsYVcTw,9596
20
+ spectre_core/capture_configs/_pnames.py,sha256=3bJhT4kM5WuiH9SSs4UyBcq_mDybzx-bRiWJcIOqeLA,1975
21
+ spectre_core/capture_configs/_ptemplates.py,sha256=Pepzs7eq31WPdTYmIICJjIVOzf-j5LdA2SD_f2RUZ54,25609
22
+ spectre_core/capture_configs/_pvalidators.py,sha256=fRlFL3rTIpDU2G4iUKp3Lb_jFX5ddHNuUbY5hTzZQQg,10325
23
23
  spectre_core/config/__init__.py,sha256=CVddibAIWU4cNerXCxfeUn_cvnWWDBm4pWeUifqM6Ko,502
24
24
  spectre_core/config/_paths.py,sha256=Qn0KVe27P6Bo65MfHe4LpH_ryPvLgbTxKjc4MTw1BB8,4090
25
25
  spectre_core/config/_time_formats.py,sha256=gS0j5zIvBhnV7KMYvTloloIbVwmCYn8MMKn3zNeQ4Xc,857
@@ -45,22 +45,25 @@ spectre_core/post_processing/_register.py,sha256=chK5bCQ-0bpMhplbKT3cdS5anLhIA5T
45
45
  spectre_core/post_processing/plugins/_event_handler_keys.py,sha256=LPA71kKsaLPyT2vpPJwm88-RWfX-AU0_T9H8-GdjINQ,614
46
46
  spectre_core/post_processing/plugins/_fixed_center_frequency.py,sha256=24LB3iDMa2KvgM7jyRnEr7Y45VK46bUT7Nj8bXGiGwc,5231
47
47
  spectre_core/post_processing/plugins/_swept_center_frequency.py,sha256=fzPAZ4zK1DRAHushUB-JS2IgKAuXyP4hdBLZJX6jBmo,20971
48
- spectre_core/receivers/__init__.py,sha256=A-BuCrnIRdRZe6HGXlLzKHGm8Zjfb8I9dzslBTeUHn4,660
49
- spectre_core/receivers/_base.py,sha256=E2aSYmveSMYxLrm5Uv235KlsehOyq82DvSolCIF6xug,10096
50
- spectre_core/receivers/_factory.py,sha256=5NdwZzBmUEHZQHltggDmuEoi-DRS6fHPSBzxvmq50zs,1843
48
+ spectre_core/receivers/__init__.py,sha256=uT3XNn12gSfK_M_GE__sK-TRWra92qkttnUJ-_6uViE,714
49
+ spectre_core/receivers/_base.py,sha256=PSC8XWnlVyxkyLa_64Haq4bZTTIxGf42_X8z8_9gYng,8972
50
+ spectre_core/receivers/_factory.py,sha256=xViruRYb9kFjndY_GmhK5vNQ0VxCE3rbKB3uzqtp_zE,2018
51
51
  spectre_core/receivers/_register.py,sha256=jWS3Q_ZOZcqUFunxJwR5VRZN4_eS3LzcP-5edQdmj4c,1366
52
- spectre_core/receivers/_spec_names.py,sha256=pLYM9rMoZkT3JmRvSNfWKFiIJmj07vrphDbw-fNhpO8,1611
52
+ spectre_core/receivers/_spec_names.py,sha256=V370aeclNqW0hGdbx6C8v61GPnPDkSMol692igv0Aq4,2446
53
53
  spectre_core/receivers/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
- spectre_core/receivers/plugins/_receiver_names.py,sha256=GZi4xznxscLBJXbfkZLtQ-m0U3GH362HiI5-y_FQO1k,426
55
- spectre_core/receivers/plugins/_rsp1a.py,sha256=LAvjxcxIkZRPpc96wqkco7rQ-H3AvUowsp0WG8vgAkw,2438
56
- spectre_core/receivers/plugins/_rspduo.py,sha256=ypr4xiEMOq4EJKFECz01PZjUJ2UcsWJVZRou8Ln5Ogw,3049
57
- spectre_core/receivers/plugins/_sdrplay_receiver.py,sha256=QpQ2sRc9Tz2IZRL_LyBX3UPCQ270RQMHH2mP6Y_n1-o,6899
54
+ spectre_core/receivers/plugins/_b200mini.py,sha256=l0baAg6tRdAfT7N1eAmHoQ9fJlKQO8-AsPZ7YAyc8t4,2890
55
+ spectre_core/receivers/plugins/_receiver_names.py,sha256=b8cUln47Ya8rr8vnnHQEGa7j9Hf-hJsNbTNtGuZaWlA,498
56
+ spectre_core/receivers/plugins/_rsp1a.py,sha256=zgPemoRjd93CvI9bRg7PHzgAUHB9xXg5LCvkLHa3jbI,2641
57
+ spectre_core/receivers/plugins/_rspduo.py,sha256=Sim1TXcG_g1ohWKwvMk7XzrQC8NGydCMGZEf9hhvX-0,3230
58
+ spectre_core/receivers/plugins/_sdrplay_receiver.py,sha256=bdfjGvKSFW_jfQFIQQcIIf8UfbuMwW04SK6YMNMIINI,5737
58
59
  spectre_core/receivers/plugins/_test.py,sha256=t8oE4zQLYYWJV6SMIZAlNHs9mig263QJmP6XRLyF0RU,8277
60
+ spectre_core/receivers/plugins/_usrp.py,sha256=Z0KxOcreic4Bxefeyy6xJ8ips8Q76XBiQcOui56QClU,7603
59
61
  spectre_core/receivers/plugins/gr/__init__.py,sha256=oFSWmGoXQLK5X5xHvWzTdNr9amuaiiGjZirXZVogACU,154
60
62
  spectre_core/receivers/plugins/gr/_base.py,sha256=woFF6498aLIDf4EC7aD-TolY9LtZBqlLy-Vai_gfIvc,2571
61
- spectre_core/receivers/plugins/gr/_rsp1a.py,sha256=Nq0VNWjzfTd4Mruz4FSk6bfso6zh1cMw-C-qn5LpPv8,6614
63
+ spectre_core/receivers/plugins/gr/_rsp1a.py,sha256=JLMRCNouSblNizth7EmLrtWvbnpD-5zd7uhc6Pjcopw,6288
62
64
  spectre_core/receivers/plugins/gr/_rspduo.py,sha256=s5g5nOQHiVHCESaHdj2VmgXl_LaiMaqXhTJfUbC7Iew,9811
63
65
  spectre_core/receivers/plugins/gr/_test.py,sha256=YA3JKdJ_CT3J93pqHUjltKrQUoaDXzUloEJEXVHH718,5780
66
+ spectre_core/receivers/plugins/gr/_usrp.py,sha256=qhJ701mU5hVI9X7QQN6V4xmrFi2VlDMTz3XfjbCkxRo,6635
64
67
  spectre_core/spectrograms/__init__.py,sha256=AsiOmn9XrAAHUvK-fdhRddAxX4M1Wd6TCtdmxGkl3FA,763
65
68
  spectre_core/spectrograms/_analytical.py,sha256=Axnt9JOJnWXRRuVU5nHPz5QU09KoWqNZkR5NnTX6kMY,11356
66
69
  spectre_core/spectrograms/_array_operations.py,sha256=79vddwWqR5i6OkeD5L_84t8svslpmzW4b8uxbiCQl0I,7553
@@ -68,8 +71,8 @@ spectre_core/spectrograms/_spectrogram.py,sha256=WhHEt_QpmzspDqYlzdZcJ8CAXxRfs8-
68
71
  spectre_core/spectrograms/_transform.py,sha256=WZ5jAe3bOpNldxHDSHPf8Q_1ifBdWqXB_mlF6DL1VuE,11734
69
72
  spectre_core/wgetting/__init__.py,sha256=UkS0Z0wuuqpoZ1EL35wJcDpjBiAaZgdZ7064yGESxNE,341
70
73
  spectre_core/wgetting/_callisto.py,sha256=m9II6ayswrY4h_ST3TodioZ4C865lN_uOF-BozvjZAg,6952
71
- spectre_core-0.0.14.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
72
- spectre_core-0.0.14.dist-info/METADATA,sha256=jnIwMHNSSSQgJLudB3KHNRL8t00qR_TPkgxoHtW-9AM,42100
73
- spectre_core-0.0.14.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
74
- spectre_core-0.0.14.dist-info/top_level.txt,sha256=-UsyjpFohXgZpgcZ9QbVeXhsIyF3Am8RxNFNDV_Ta2Y,13
75
- spectre_core-0.0.14.dist-info/RECORD,,
74
+ spectre_core-0.0.16.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
75
+ spectre_core-0.0.16.dist-info/METADATA,sha256=7CfIEsTWqo1hw0GvOBc0NKv1o5jIezp0_WcpK5xAbx4,42100
76
+ spectre_core-0.0.16.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
77
+ spectre_core-0.0.16.dist-info/top_level.txt,sha256=-UsyjpFohXgZpgcZ9QbVeXhsIyF3Am8RxNFNDV_Ta2Y,13
78
+ spectre_core-0.0.16.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (75.8.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5