Skip to content

Conversation

@klemmm
Copy link

@klemmm klemmm commented Sep 3, 2025

This implements the new API hackrf_set_freq_when() that schedules a center frequency change at a specific point in the RX/TX stream.

@martinling martinling self-assigned this Sep 4, 2025
Copy link
Member

@martinling martinling left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR!

Our main concern with adding this feature was whether we might prefer to do this as part of a more general capability for scheduled operations, i.e:

  • Scheduling other kinds of changes like gain changes, bias-T on/off, antenna switching with Opera Cake, or stopping TX/RX.
  • Scheduling more than one change, by queuing up a sequence of changes.
  • Scheduling a repeating sequence of changes (like with Opera Cake time mode).

...and if so, whether we want to go ahead with merging a single-function implementation now.

However, you've shown that having this single call is useful on its own, and in the event that we do implement a more general timed operations feature, I'm pretty sure we would be able to adapt this call to become a convenience method for setting up a single frequency change.

So in principle I think we should accept this.

Looking at the proposed API and implementation though, I see two significant ways in which it could be improved:

  1. The when parameter is specified in terms of the M0 count, which is an implementation detail of the current hardware & firmware. At the very least, the documentation needs to describe what this means for the user: it's the number of bytes since the start of TX/RX, modulo 2^32. Better still might be to take a 64-bit sample count, and handle rollovers internally.

  2. It would make sense to stop the flow of samples while retuning, since whilst the frequency is being changed, the RX samples are somewhat meaningless, and in TX, continuing to transmit during retuning may cause transmission on unwanted intermediate frequencies.

To achieve (2), we could add an additional parameter to hackrf_set_freq_when, specifying a pause time, i.e. the number of bytes or samples that TX/RX should be paused for during retuning.

The worst case tuning time on HackRF One is around 760us, so in most cases, the caller could just choose a pause time that exceeds this.

Some types of frequency changes can be faster than others though - it depends what settings need to be changed to achieve the retune. It will also differ between the different hardware platforms we support.

So it makes sense to have this configurable, and if it's the caller that specifies the pause count, that means they always know how many samples are "skipped" on a retune.

It should be possible to specify a pause count of zero too, if the user doesn't care about any of this. In that case the behaviour would be as you have implemented it now.

Within the TX/RX loops, implementing a pause would involve:

  1. telling the M0 core to switch to WAIT mode at the desired counter value.
  2. waiting for the M0 to enter the WAIT mode.
  3. telling the M0 to switch back to TX_RUN or RX mode at the desired counter value, plus the pause count.
  4. executing set_freq
  5. waiting for the M0 to switch back to TX_RUN or RX.

For an example of this, see how sweep_mode is implemented in usb_api_sweep.c.

There is one slight complexity here, which is that the M0 advances its count in steps of 32 bytes (i.e. 16 samples), and will only switch modes on an exact match. So both the switch time and the pause time would need to be adjusted to appropriate boundaries.

@klemmm
Copy link
Author

klemmm commented Oct 17, 2025

Hello,

Thanks for the feedback.

You are correct about the "pause", this crucial for TX mode. Since I used this only on RX mode, I didn't think of the potentially disastrous consequences of continuing to transmit while switching frequencies.

Right now I'm very busy at work but I'll definitely find some time to work on this whenever I get some free time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants