Struct Sweep

Source
pub struct Sweep { /* private fields */ }
Expand description

A HackRF operating in sweep mode.

A sweep continually retunes the HackRF, grabbing a block of 8187 samples (8192, but the first 5 are overwritten with an internal header) at each tuning. The process is:

  1. Get the lower frequency in a range.
  2. Tune to that frequency after adding the frequency offset, then grab the samples.
  3. If multiple blocks are requested, grab another (non-sequential) block of samples. Repeat until all requested blocks have been retrieved.
  4. Add the step (ignoring any offset). If using interleaved mode, the first sub-step is 1/4 of the step size, and the second sub-step is 3/4 of the step size.
  5. If the new frequency is greater or equal to the upper frequency in the range, go to the next range and repeat from step 1. Otherwise go to step 2 with the frequency from step 4.

To receive sweeps, first take a HackRF peripheral and call HackRf::start_rx_sweep, or use Sweep::new with it.

Next, call submit to queue up requests, stopping when there are enough pending requests. libhackrf queues up 1 MiB of data, or 64 sweep blocks. You’ll probably want something similar.

Actual reception is done with next_complete, which will panic if there are no pending requests. The number of pending requests can always be checked with pending.

A sweep requires configuration using SweepParams. The recommended way to set this up is with SweepParams::init_sample_rate, which does the following:

  1. Configures for interleaved mode.
  2. Finds the actual baseband filter bandwidth for a given sample rate.
  3. Sets the offset to 1/2 of the filter bandwidth, aligning the lower end of the baseband to the lower frequency.
  4. Sets the step width to be 4/3 of the filter bandwidth.

When processing the retrieved data, if we mark the full sample band as spanning from -4 to 4:

  • -4 to -3: lower band edge, filtered out by baseband filter
  • -3 to -1: in-band, low side
  • -1 to 1: Too close to DC spur, discard from FFT
  • 1 to 3: in-band, upper side
  • 3 to 4: upper band edge, filtered out by baseband filter

Note that, in a normal FFT where at least two of the prime factors are 2, the transition points are also centered on FFT bins. Using an Offset DFT can fix this, putting the FFT bin transitions at the transition points instead.

Implementations§

Source§

impl Sweep

Source

pub async fn new( rf: HackRf, params: &SweepParams, ) -> Result<Self, StateChangeError>

Start a new RX sweep using the provided parameters.

Buffers are reused across sweep operations, provided that HackRf::start_rx isn’t used, or is used with a 8192 sample buffer size.

Source

pub async fn new_with_custom_sample_rate( rf: HackRf, params: &SweepParams, ) -> Result<Self, StateChangeError>

Start a new RX sweep without configuring the sample rate or baseband filter.

Buffers are reused across sweep operations, provided that HackRf::start_rx isn’t used, or is used with a 8192 sample buffer size.

Source

pub fn submit(&mut self)

Queue up a sweep transfer.

This will pull from a reusable buffer pool first, and allocate a new buffer if none are available in the pool.

The buffer pool will grow so long as completed buffers aren’t dropped.

Source

pub async fn next_complete(&mut self) -> Result<SweepBuf, Error>

Retrieve the next chunk of receive data.

This future is cancel-safe, so feel free to use it alongside a timeout or a select!-type pattern.

Source

pub fn pending(&self) -> usize

Get the number of pending requests.

Source

pub async fn stop(self) -> Result<HackRf, Error>

Halt receiving and return to idle mode.

This attempts to cancel all transfers and then complete whatever is left. Transfer errors are ignored.

Auto Trait Implementations§

§

impl Freeze for Sweep

§

impl !RefUnwindSafe for Sweep

§

impl Send for Sweep

§

impl !Sync for Sweep

§

impl Unpin for Sweep

§

impl !UnwindSafe for Sweep

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.