Use external callback to set radio sample rate

This commit is contained in:
Michael Ossmann
2026-02-24 20:32:51 -05:00
parent 467a72cf8e
commit 037c10ab4d
3 changed files with 31 additions and 12 deletions

View File

@@ -351,7 +351,9 @@ fpga_driver_t fpga = {
};
#endif
radio_t radio;
radio_t radio = {
.sample_rate_cb = sample_rate_set,
};
rf_path_t rf_path = {
.switchctrl = 0,

View File

@@ -210,21 +210,26 @@ static bool radio_update_sample_rate(radio_t* const radio, uint64_t* bank)
}
new_n = (n != previous_n);
fp_40_24_t afe_rate = rate << n;
afe_rate = sample_rate_set(afe_rate, false);
new_afe_rate = (afe_rate != applied_afe_rate);
if (new_afe_rate) {
afe_rate = sample_rate_set(afe_rate, true);
applied_afe_rate = afe_rate;
rate = afe_rate >> n;
if (radio->sample_rate_cb) {
fp_40_24_t afe_rate = rate << n;
afe_rate = radio->sample_rate_cb(afe_rate, false);
new_afe_rate = (afe_rate != applied_afe_rate);
if (new_afe_rate) {
afe_rate = radio->sample_rate_cb(afe_rate, true);
applied_afe_rate = afe_rate;
rate = afe_rate >> n;
}
} else {
rate = RADIO_UNSET;
}
new_rate = (rate != radio->config[RADIO_BANK_APPLIED][RADIO_SAMPLE_RATE]);
if (new_rate) {
radio->config[RADIO_BANK_APPLIED][RADIO_SAMPLE_RATE] = rate;
/* Round to the nearest Hz for display. */
const uint32_t rate_hz = (rate + (FP_ONE_HZ >> 1)) / FP_ONE_HZ;
hackrf_ui()->set_sample_rate(rate_hz);
if (rate != RADIO_UNSET) {
/* Round to the nearest Hz for display. */
const uint32_t rate_hz = (rate + (FP_ONE_HZ >> 1)) / FP_ONE_HZ;
hackrf_ui()->set_sample_rate(rate_hz);
}
}
return (new_afe_rate || new_rate || new_n);

View File

@@ -27,6 +27,8 @@
#include <stdint.h>
#include <stdbool.h>
#include "fixed_point.h"
typedef enum {
RADIO_OK = 1,
RADIO_ERR_INVALID_PARAM = -2,
@@ -205,10 +207,20 @@ typedef enum {
#define RADIO_NUM_BANKS (5)
/**
* A callback function must be provided that configures clock generation to
* produce the requested sample clock frequency. The function must return the
* configured sample rate. A boolean program argument may be set to false to
* execute a dry run, returning the sample rate without configuring clock
* generation.
*/
typedef fp_40_24_t (*sample_rate_fn)(const fp_40_24_t sample_rate, const bool program);
typedef struct radio_t {
radio_config_mode_t config_mode;
uint64_t config[RADIO_NUM_BANKS][RADIO_NUM_REGS];
volatile uint32_t regs_dirty;
sample_rate_fn sample_rate_cb;
} radio_t;
void radio_init(radio_t* const radio);