Skip to content

Commit 59f47b8

Browse files
committed
libhackrf: add 'hackrf_radio_set_frequency_fp()' and 'hackrf_radio_set_sample_rate_fp()'
1 parent e88882b commit 59f47b8

6 files changed

Lines changed: 222 additions & 0 deletions

File tree

firmware/hackrf_usb/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ set(SRC_M4
5656
usb_endpoint.c
5757
usb_api_board_info.c
5858
usb_api_m0_state.c
59+
usb_api_radio.c
5960
usb_api_register.c
6061
usb_api_spiflash.c
6162
usb_api_transceiver.c

firmware/hackrf_usb/hackrf_usb.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
#include "usb_api_board_info.h"
7676
#include "usb_api_m0_state.h"
7777
#include "usb_api_operacake.h"
78+
#include "usb_api_radio.h"
7879
#include "usb_api_register.h"
7980
#include "usb_api_selftest.h"
8081
#include "usb_api_spiflash.h"
@@ -183,6 +184,8 @@ static usb_request_handler_fn vendor_request_handler[] = {
183184
usb_vendor_request_read_radio_reg,
184185
usb_vendor_request_get_buffer_size,
185186
usb_vendor_request_lock_radio_reg,
187+
usb_vendor_request_set_radio_frequency_fp,
188+
usb_vendor_request_set_radio_sample_rate_fp,
186189
};
187190

188191
static const uint32_t vendor_request_handler_count =
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright 2026 Great Scott Gadgets <info@greatscottgadgets.com>
3+
*
4+
* This file is part of HackRF.
5+
*
6+
* This program is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation; either version 2, or (at your option)
9+
* any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program; see the file COPYING. If not, write to
18+
* the Free Software Foundation, Inc., 51 Franklin Street,
19+
* Boston, MA 02110-1301, USA.
20+
*/
21+
22+
#include <stddef.h>
23+
24+
#include <fixed_point.h>
25+
#include <radio.h>
26+
#include <usb_request.h>
27+
#include <usb_type.h>
28+
29+
#include "usb_queue.h"
30+
31+
usb_request_status_t usb_vendor_request_set_radio_frequency_fp(
32+
usb_endpoint_t* const endpoint,
33+
const usb_transfer_stage_t stage)
34+
{
35+
static fp_40_24_t hz_param;
36+
37+
if (stage == USB_TRANSFER_STAGE_SETUP) {
38+
usb_transfer_schedule_block(
39+
endpoint->out,
40+
&hz_param,
41+
sizeof(fp_40_24_t),
42+
NULL,
43+
NULL);
44+
} else if (stage == USB_TRANSFER_STAGE_DATA) {
45+
radio_reg_write(&radio, RADIO_BANK_ACTIVE, RADIO_FREQUENCY_RF, hz_param);
46+
radio_reg_write(
47+
&radio,
48+
RADIO_BANK_ACTIVE,
49+
RADIO_FREQUENCY_IF,
50+
RADIO_UNSET);
51+
radio_reg_write(
52+
&radio,
53+
RADIO_BANK_ACTIVE,
54+
RADIO_FREQUENCY_LO,
55+
RADIO_UNSET);
56+
radio_reg_write(
57+
&radio,
58+
RADIO_BANK_ACTIVE,
59+
RADIO_IMAGE_REJECT,
60+
RADIO_UNSET);
61+
usb_transfer_schedule_ack(endpoint->in);
62+
}
63+
64+
return USB_REQUEST_STATUS_OK;
65+
}
66+
67+
usb_request_status_t usb_vendor_request_set_radio_sample_rate_fp(
68+
usb_endpoint_t* const endpoint,
69+
const usb_transfer_stage_t stage)
70+
{
71+
static fp_28_36_t sps_param;
72+
73+
if (stage == USB_TRANSFER_STAGE_SETUP) {
74+
usb_transfer_schedule_block(
75+
endpoint->out,
76+
&sps_param,
77+
sizeof(fp_28_36_t),
78+
NULL,
79+
NULL);
80+
} else if (stage == USB_TRANSFER_STAGE_DATA) {
81+
radio_reg_write(&radio, RADIO_BANK_ACTIVE, RADIO_SAMPLE_RATE, sps_param);
82+
usb_transfer_schedule_ack(endpoint->in);
83+
}
84+
85+
return USB_REQUEST_STATUS_OK;
86+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2026 Great Scott Gadgets <info@greatscottgadgets.com>
3+
*
4+
* This file is part of HackRF.
5+
*
6+
* This program is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation; either version 2, or (at your option)
9+
* any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program; see the file COPYING. If not, write to
18+
* the Free Software Foundation, Inc., 51 Franklin Street,
19+
* Boston, MA 02110-1301, USA.
20+
*/
21+
22+
#pragma once
23+
24+
#include <usb_request.h>
25+
#include <usb_type.h>
26+
27+
usb_request_status_t usb_vendor_request_set_radio_frequency_fp(
28+
usb_endpoint_t* const endpoint,
29+
const usb_transfer_stage_t stage);
30+
31+
usb_request_status_t usb_vendor_request_set_radio_sample_rate_fp(
32+
usb_endpoint_t* const endpoint,
33+
const usb_transfer_stage_t stage);

host/libhackrf/src/hackrf.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ typedef enum {
121121
HACKRF_VENDOR_REQUEST_RADIO_READ_REG = 60,
122122
HACKRF_VENDOR_REQUEST_GET_BUFFER_SIZE = 61,
123123
HACKRF_VENDOR_REQUEST_RADIO_LOCK_REG = 62,
124+
HACKRF_VENDOR_REQUEST_RADIO_SET_FREQUENCY_FP = 63,
125+
HACKRF_VENDOR_REQUEST_RADIO_SET_SAMPLE_RATE_FP = 64,
124126
} hackrf_vendor_request;
125127

126128
#define USB_CONFIG_STANDARD 0x1
@@ -1843,6 +1845,36 @@ int ADDCALL hackrf_set_freq_explicit(
18431845
}
18441846
}
18451847

1848+
int ADDCALL hackrf_radio_set_frequency_fp(hackrf_device* device, const fp_40_24_t freq_hz)
1849+
{
1850+
USB_API_REQUIRED(device, 0x0113);
1851+
uint64_t set_freq_fp_param;
1852+
uint8_t length;
1853+
int result;
1854+
1855+
// serialize parameters
1856+
set_freq_fp_param = TO_LE64(freq_hz);
1857+
length = sizeof(uint64_t);
1858+
1859+
result = libusb_control_transfer(
1860+
device->usb_device,
1861+
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
1862+
LIBUSB_RECIPIENT_DEVICE,
1863+
HACKRF_VENDOR_REQUEST_RADIO_SET_FREQUENCY_FP,
1864+
0,
1865+
0,
1866+
(unsigned char*) &set_freq_fp_param,
1867+
length,
1868+
DEFAULT_REQUEST_TIMEOUT);
1869+
1870+
if (result < length) {
1871+
last_libusb_error = result;
1872+
return HACKRF_ERROR_LIBUSB;
1873+
}
1874+
1875+
return HACKRF_SUCCESS;
1876+
}
1877+
18461878
typedef struct {
18471879
uint32_t freq_hz;
18481880
uint32_t divider;
@@ -1935,6 +1967,37 @@ int ADDCALL hackrf_set_sample_rate(hackrf_device* device, const double freq)
19351967
return hackrf_set_sample_rate_manual(device, freq_hz, divider);
19361968
}
19371969

1970+
int ADDCALL hackrf_radio_set_sample_rate_fp(
1971+
hackrf_device* device,
1972+
const fp_28_36_t freq_hz)
1973+
{
1974+
USB_API_REQUIRED(device, 0x0113);
1975+
uint64_t set_sr_fp_param;
1976+
uint8_t length;
1977+
int result;
1978+
1979+
set_sr_fp_param = TO_LE64(freq_hz);
1980+
length = sizeof(uint64_t);
1981+
1982+
result = libusb_control_transfer(
1983+
device->usb_device,
1984+
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
1985+
LIBUSB_RECIPIENT_DEVICE,
1986+
HACKRF_VENDOR_REQUEST_RADIO_SET_SAMPLE_RATE_FP,
1987+
0,
1988+
0,
1989+
(unsigned char*) &set_sr_fp_param,
1990+
length,
1991+
DEFAULT_REQUEST_TIMEOUT);
1992+
1993+
if (result < length) {
1994+
last_libusb_error = result;
1995+
return HACKRF_ERROR_LIBUSB;
1996+
}
1997+
1998+
return HACKRF_SUCCESS;
1999+
}
2000+
19382001
int ADDCALL hackrf_set_amp_enable(hackrf_device* device, const uint8_t value)
19392002
{
19402003
int result;

host/libhackrf/src/hackrf.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,16 @@ enum clkin_ctrl_signal {
946946
CLKIN_SIGNAL_P22 = 1,
947947
};
948948

949+
/**
950+
* 40.24 Fixed-point type.
951+
*/
952+
typedef uint64_t fp_40_24_t;
953+
954+
/**
955+
* 28.36 Fixed-point type.
956+
*/
957+
typedef uint64_t fp_28_36_t;
958+
949959
/**
950960
* Opaque struct for hackrf device info. Object can be created via @ref hackrf_open, @ref hackrf_device_list_open or @ref hackrf_open_by_serial and be destroyed via @ref hackrf_close
951961
* @ingroup device
@@ -1778,6 +1788,18 @@ extern ADDAPI int ADDCALL hackrf_set_freq_explicit(
17781788
const uint64_t lo_freq_hz,
17791789
const enum rf_path_filter path);
17801790

1791+
/**
1792+
* Set the radio center frequency to a fractional, fixed-point value.
1793+
*
1794+
* @param[in] device device to query
1795+
* @param[in] hz center frequency in Hz
1796+
* @return @ref HACKRF_SUCCESS on success or @ref hackrf_error variant
1797+
* @ingroup configuration
1798+
*/
1799+
extern ADDAPI int ADDCALL hackrf_radio_set_frequency_fp(
1800+
hackrf_device* device,
1801+
const fp_40_24_t freq_hz);
1802+
17811803
/**
17821804
* Set sample rate explicitly
17831805
*
@@ -1812,6 +1834,20 @@ extern ADDAPI int ADDCALL hackrf_set_sample_rate(
18121834
hackrf_device* device,
18131835
const double freq_hz);
18141836

1837+
/**
1838+
* Set the radio sample rate to a fractional, fixed-point value.
1839+
*
1840+
* This function does not automatically configure the baseband filter bandwidth, so any calls to this function should be followed by @ref hackrf_set_baseband_filter_bandwidth should it require adjustment.
1841+
*
1842+
* @param[in] device device to query
1843+
* @param[in] sps samples per second
1844+
* @return @ref HACKRF_SUCCESS on success or @ref hackrf_error variant
1845+
* @ingroup configuration
1846+
*/
1847+
extern ADDAPI int ADDCALL hackrf_radio_set_sample_rate_fp(
1848+
hackrf_device* device,
1849+
const fp_28_36_t freq_hz);
1850+
18151851
/**
18161852
* Enable/disable 14dB RF amplifier
18171853
*

0 commit comments

Comments
 (0)