From 037c10ab4df4efb5faa8b504cd64f67fe82c665e Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Tue, 24 Feb 2026 20:32:51 -0500 Subject: [PATCH] Use external callback to set radio sample rate --- firmware/common/hackrf_core.c | 4 +++- firmware/common/radio.c | 27 ++++++++++++++++----------- firmware/common/radio.h | 12 ++++++++++++ 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 8eaecfbc..081ca110 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -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, diff --git a/firmware/common/radio.c b/firmware/common/radio.c index 01a7b05a..3f06867d 100644 --- a/firmware/common/radio.c +++ b/firmware/common/radio.c @@ -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); diff --git a/firmware/common/radio.h b/firmware/common/radio.h index 59f9592a..13cd2626 100644 --- a/firmware/common/radio.h +++ b/firmware/common/radio.h @@ -27,6 +27,8 @@ #include #include +#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);