FEAT: scheduled frequency change#1581
Conversation
There was a problem hiding this comment.
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:
-
The
whenparameter 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. -
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:
- telling the M0 core to switch to
WAITmode at the desired counter value. - waiting for the M0 to enter the
WAITmode. - telling the M0 to switch back to
TX_RUNorRXmode at the desired counter value, plus the pause count. - executing
set_freq - waiting for the M0 to switch back to
TX_RUNorRX.
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.
|
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. |
This implements the new API hackrf_set_freq_when() that schedules a center frequency change at a specific point in the RX/TX stream.