From 26c20f5762eb0c90ad7679bfead2debf2c8dffe1 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Tue, 13 Jan 2026 19:28:42 -0500 Subject: [PATCH] Call a sample rate a sample rate Previously we used "sample rate" to mean a rate that is twice the sample rate in several places in firmware. --- firmware/common/fpga_selftest.c | 4 ++-- firmware/common/hackrf_core.c | 12 +++++++++++- firmware/common/radio.c | 8 ++++---- firmware/hackrf_usb/usb_api_transceiver.c | 2 +- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/firmware/common/fpga_selftest.c b/firmware/common/fpga_selftest.c index 287c6adc..31cc1760 100644 --- a/firmware/common/fpga_selftest.c +++ b/firmware/common/fpga_selftest.c @@ -189,7 +189,7 @@ bool fpga_if_xcvr_selftest() max2831_set_frequency(&max283x, 2500000000); // Capture 1: 4 Msps, tone at 0.5 MHz, narrowband filter OFF - sample_rate_frac_set(4000000 * 2, 1); + sample_rate_frac_set(4000000, 1); delay_us_at_mhz(1000, 204); if (rx_samples(num_samples, 2000000) == -1) { timeout = true; @@ -212,7 +212,7 @@ bool fpga_if_xcvr_selftest() // Capture 3: 20 Msps, tone at 5 MHz, narrowband filter OFF fpga_set_tx_nco_pstep(&fpga, 255); - sample_rate_frac_set(20000000 * 2, 1); + sample_rate_frac_set(20000000, 1); narrowband_filter_set(0); delay_us_at_mhz(1000, 204); if (rx_samples(num_samples, 2000000) == -1) { diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 5d59da00..3bd25ff9 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -505,7 +505,17 @@ bool sample_rate_frac_set(uint32_t rate_num, uint32_t rate_denom) uint32_t a, b, c; uint32_t rem; - hackrf_ui()->set_sample_rate(rate_num / 2); + /* Round to the nearest Hz for display. */ + uint32_t rate_hz = (rate_num + (rate_denom >> 1)) / rate_denom; + hackrf_ui()->set_sample_rate(rate_hz); + + /* + * First double the sample rate so that we can produce a clock at twice + * the intended sample rate. The 2x clock is sometimes used directly, + * and it is divided by two in an output divider to produce the actual + * AFE clock. + */ + rate_num *= 2; /* Find best config */ a = (VCO_FREQ * rate_denom) / rate_num; diff --git a/firmware/common/radio.c b/firmware/common/radio.c index 29aba95c..d7eeffb6 100644 --- a/firmware/common/radio.c +++ b/firmware/common/radio.c @@ -59,7 +59,7 @@ radio_error_t radio_set_sample_rate( if ((config->mode == TRANSCEIVER_MODE_RX) || (config->mode == TRANSCEIVER_MODE_RX_SWEEP)) { n = 1; - uint32_t afe_rate_x2 = 2 * sample_rate.hz; + uint32_t afe_rate_x2 = 4 * sample_rate.hz; while ((afe_rate_x2 <= MAX_AFE_RATE) && (n < MAX_N)) { afe_rate_x2 <<= 1; n++; @@ -120,12 +120,12 @@ radio_error_t radio_set_filter( max283x_set_lpf_bandwidth(&max283x, filter.hz); #else uint32_t lpf_bandwidth = - (config->sample_rate[RADIO_SAMPLE_RATE_CLOCKGEN].hz * 3) / 8; + (config->sample_rate[RADIO_SAMPLE_RATE_CLOCKGEN].hz * 3) / 4; uint32_t offset = 0; if (config->shift != FPGA_QUARTER_SHIFT_MODE_NONE) { offset = (config->sample_rate[RADIO_SAMPLE_RATE_CLOCKGEN].hz << config->resampling_n) / - 8; + 4; } lpf_bandwidth += offset * 2; max2831_set_lpf_bandwidth(&max283x, lpf_bandwidth); @@ -306,7 +306,7 @@ radio_error_t radio_set_frequency( config->shift = tune_config->shift; uint32_t offset = (config->sample_rate[RADIO_SAMPLE_RATE_CLOCKGEN].hz << config->resampling_n) / - 8; + 4; ok = tuning_set_frequency(tune_config, frequency.hz, offset); if (ok) { radio_channel_t* channel = &radio->channel[chan_id]; diff --git a/firmware/hackrf_usb/usb_api_transceiver.c b/firmware/hackrf_usb/usb_api_transceiver.c index cbc8e293..d72e57a1 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.c +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -177,7 +177,7 @@ usb_request_status_t usb_vendor_request_set_sample_rate_frac( RADIO_CHANNEL0, RADIO_SAMPLE_RATE_CLOCKGEN, (radio_sample_rate_t){ - .num = set_sample_r_params.freq_hz * 2, + .num = set_sample_r_params.freq_hz, .div = set_sample_r_params.divider, }); if (result == RADIO_OK) {