Skip to content

Commit 2f4fa47

Browse files
committed
libhackrf: add 'hackrf_radio_set_frequency()', 'hackrf_radio_set_frequency_explicit()' and 'hackrf_radio_set_sample_rate()'
1 parent 161f627 commit 2f4fa47

5 files changed

Lines changed: 375 additions & 3 deletions

File tree

firmware/hackrf_usb/hackrf_usb.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ static usb_request_handler_fn vendor_request_handler[] = {
187187
usb_vendor_request_open,
188188
usb_vendor_request_close,
189189
usb_vendor_request_set_radio_mode,
190+
usb_vendor_request_set_radio_frequency,
191+
usb_vendor_request_set_radio_frequency_explicit,
192+
usb_vendor_request_set_radio_sample_rate,
190193
};
191194

192195
static const uint32_t vendor_request_handler_count =

firmware/hackrf_usb/usb_api_radio.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
* Boston, MA 02110-1301, USA.
2020
*/
2121

22+
#include <stddef.h>
23+
#include <stdint.h>
24+
25+
#include <fixed_point.h>
2226
#include <radio.h>
2327
#include <usb_request.h>
2428
#include <usb_type.h>
@@ -39,3 +43,99 @@ usb_request_status_t usb_vendor_request_set_radio_mode(
3943

4044
return USB_REQUEST_STATUS_OK;
4145
}
46+
47+
usb_request_status_t usb_vendor_request_set_radio_frequency(
48+
usb_endpoint_t* const endpoint,
49+
const usb_transfer_stage_t stage)
50+
{
51+
static fp_40_24_t hz_param;
52+
53+
if (stage == USB_TRANSFER_STAGE_SETUP) {
54+
usb_transfer_schedule_block(
55+
endpoint->out,
56+
&hz_param,
57+
sizeof(fp_40_24_t),
58+
NULL,
59+
NULL);
60+
} else if (stage == USB_TRANSFER_STAGE_DATA) {
61+
radio_reg_write(&radio, RADIO_BANK_ACTIVE, RADIO_FREQUENCY_RF, hz_param);
62+
radio_reg_write(
63+
&radio,
64+
RADIO_BANK_ACTIVE,
65+
RADIO_FREQUENCY_IF,
66+
RADIO_UNSET);
67+
radio_reg_write(
68+
&radio,
69+
RADIO_BANK_ACTIVE,
70+
RADIO_FREQUENCY_LO,
71+
RADIO_UNSET);
72+
radio_reg_write(
73+
&radio,
74+
RADIO_BANK_ACTIVE,
75+
RADIO_IMAGE_REJECT,
76+
RADIO_UNSET);
77+
usb_transfer_schedule_ack(endpoint->in);
78+
}
79+
80+
return USB_REQUEST_STATUS_OK;
81+
}
82+
83+
usb_request_status_t usb_vendor_request_set_radio_frequency_explicit(
84+
usb_endpoint_t* const endpoint,
85+
const usb_transfer_stage_t stage)
86+
{
87+
static struct {
88+
fp_40_24_t if_freq_hz;
89+
fp_40_24_t lo_freq_hz;
90+
uint8_t path;
91+
} params;
92+
93+
if (stage == USB_TRANSFER_STAGE_SETUP) {
94+
usb_transfer_schedule_block(
95+
endpoint->out,
96+
&params,
97+
sizeof(params),
98+
NULL,
99+
NULL);
100+
} else if (stage == USB_TRANSFER_STAGE_DATA) {
101+
radio_reg_write(
102+
&radio,
103+
RADIO_BANK_ACTIVE,
104+
RADIO_FREQUENCY_IF,
105+
params.if_freq_hz);
106+
radio_reg_write(
107+
&radio,
108+
RADIO_BANK_ACTIVE,
109+
RADIO_FREQUENCY_LO,
110+
params.lo_freq_hz);
111+
radio_reg_write(
112+
&radio,
113+
RADIO_BANK_ACTIVE,
114+
RADIO_IMAGE_REJECT,
115+
params.path);
116+
usb_transfer_schedule_ack(endpoint->in);
117+
}
118+
119+
return USB_REQUEST_STATUS_OK;
120+
}
121+
122+
usb_request_status_t usb_vendor_request_set_radio_sample_rate(
123+
usb_endpoint_t* const endpoint,
124+
const usb_transfer_stage_t stage)
125+
{
126+
static fp_28_36_t sps_param;
127+
128+
if (stage == USB_TRANSFER_STAGE_SETUP) {
129+
usb_transfer_schedule_block(
130+
endpoint->out,
131+
&sps_param,
132+
sizeof(fp_28_36_t),
133+
NULL,
134+
NULL);
135+
} else if (stage == USB_TRANSFER_STAGE_DATA) {
136+
radio_reg_write(&radio, RADIO_BANK_ACTIVE, RADIO_SAMPLE_RATE, sps_param);
137+
usb_transfer_schedule_ack(endpoint->in);
138+
}
139+
140+
return USB_REQUEST_STATUS_OK;
141+
}

firmware/hackrf_usb/usb_api_radio.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,15 @@
2727
usb_request_status_t usb_vendor_request_set_radio_mode(
2828
usb_endpoint_t* const endpoint,
2929
const usb_transfer_stage_t stage);
30+
31+
usb_request_status_t usb_vendor_request_set_radio_frequency(
32+
usb_endpoint_t* const endpoint,
33+
const usb_transfer_stage_t stage);
34+
35+
usb_request_status_t usb_vendor_request_set_radio_frequency_explicit(
36+
usb_endpoint_t* const endpoint,
37+
const usb_transfer_stage_t stage);
38+
39+
usb_request_status_t usb_vendor_request_set_radio_sample_rate(
40+
usb_endpoint_t* const endpoint,
41+
const usb_transfer_stage_t stage);

host/libhackrf/src/hackrf.c

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ typedef enum {
124124
HACKRF_VENDOR_REQUEST_OPEN = 63,
125125
HACKRF_VENDOR_REQUEST_CLOSE = 64,
126126
HACKRF_VENDOR_REQUEST_RADIO_SET_MODE = 65,
127+
HACKRF_VENDOR_REQUEST_RADIO_SET_FREQUENCY = 66,
128+
HACKRF_VENDOR_REQUEST_RADIO_SET_FREQUENCY_EXPLICIT = 67,
129+
HACKRF_VENDOR_REQUEST_RADIO_SET_SAMPLE_RATE = 68,
127130
} hackrf_vendor_request;
128131

129132
#define USB_CONFIG_STANDARD 0x1
@@ -3702,6 +3705,159 @@ int ADDCALL hackrf_radio_set_mode(hackrf_device* device, const enum radio_config
37023705
return HACKRF_SUCCESS;
37033706
}
37043707

3708+
int ADDCALL hackrf_str_to_fp64(const uint8_t Qn, const char* str, uint64_t* const value)
3709+
{
3710+
uint64_t m = 0;
3711+
uint64_t n = 0;
3712+
uint64_t div = 1;
3713+
uint64_t div_max = ceil((double) Qn * log10(2.0)) * 10;
3714+
3715+
// validate input
3716+
char* endptr;
3717+
strtod(str, &endptr);
3718+
if (endptr == str || *endptr != '\0') {
3719+
return HACKRF_ERROR_INVALID_PARAM;
3720+
}
3721+
3722+
// parse integer component
3723+
for (; (*str >= '0') && (*str <= '9'); str++) {
3724+
m = (m * 10) + (*str - '0');
3725+
}
3726+
*value = (m << Qn);
3727+
3728+
if (*str != '.') {
3729+
return HACKRF_SUCCESS;
3730+
}
3731+
str++;
3732+
3733+
// parse fractional component
3734+
for (; (*str >= '0') && (*str <= '9') && (div < div_max); str++) {
3735+
n = (n * 10) + (*str - '0');
3736+
div *= 10;
3737+
}
3738+
3739+
if (div == 1) {
3740+
return HACKRF_SUCCESS;
3741+
}
3742+
3743+
*value += ((n << Qn) + (div / 2)) / div;
3744+
3745+
return HACKRF_SUCCESS;
3746+
}
3747+
3748+
int ADDCALL hackrf_radio_set_frequency(hackrf_device* device, const fp_40_24_t freq_hz)
3749+
{
3750+
USB_API_REQUIRED(device, 0x0113);
3751+
uint64_t set_freq_fp_param;
3752+
uint8_t length;
3753+
int result;
3754+
3755+
// serialize parameters
3756+
set_freq_fp_param = TO_LE64(freq_hz);
3757+
length = sizeof(uint64_t);
3758+
3759+
result = libusb_control_transfer(
3760+
device->usb_device,
3761+
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
3762+
LIBUSB_RECIPIENT_DEVICE,
3763+
HACKRF_VENDOR_REQUEST_RADIO_SET_FREQUENCY,
3764+
0,
3765+
0,
3766+
(unsigned char*) &set_freq_fp_param,
3767+
length,
3768+
DEFAULT_REQUEST_TIMEOUT);
3769+
3770+
if (result < length) {
3771+
last_libusb_error = result;
3772+
return HACKRF_ERROR_LIBUSB;
3773+
}
3774+
3775+
return HACKRF_SUCCESS;
3776+
}
3777+
3778+
int ADDCALL hackrf_radio_set_frequency_explicit(
3779+
hackrf_device* device,
3780+
const fp_40_24_t if_freq_hz,
3781+
const fp_40_24_t lo_freq_hz,
3782+
const enum rf_path_filter path)
3783+
{
3784+
struct {
3785+
fp_40_24_t if_freq_hz;
3786+
fp_40_24_t lo_freq_hz;
3787+
uint8_t path;
3788+
} params;
3789+
3790+
uint8_t length;
3791+
int result;
3792+
3793+
// TODO are these values still correct for HackRF Pro ?
3794+
if (FP_FREQ_HZ(if_freq_hz) < 2000000000 || FP_FREQ_HZ(if_freq_hz) > 3000000000) {
3795+
return HACKRF_ERROR_INVALID_PARAM;
3796+
}
3797+
3798+
// TODO are these values still correct for HackRF Pro ?
3799+
if ((path != RF_PATH_FILTER_BYPASS) &&
3800+
(FP_FREQ_HZ(lo_freq_hz) < 84375000 || FP_FREQ_HZ(lo_freq_hz) > 5400000000)) {
3801+
return HACKRF_ERROR_INVALID_PARAM;
3802+
}
3803+
3804+
if (path > 2) {
3805+
return HACKRF_ERROR_INVALID_PARAM;
3806+
}
3807+
3808+
params.if_freq_hz = TO_LE(if_freq_hz);
3809+
params.lo_freq_hz = TO_LE(lo_freq_hz);
3810+
params.path = (uint8_t) path;
3811+
length = sizeof(params);
3812+
3813+
result = libusb_control_transfer(
3814+
device->usb_device,
3815+
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
3816+
LIBUSB_RECIPIENT_DEVICE,
3817+
HACKRF_VENDOR_REQUEST_RADIO_SET_FREQUENCY_EXPLICIT,
3818+
0,
3819+
0,
3820+
(unsigned char*) &params,
3821+
length,
3822+
DEFAULT_REQUEST_TIMEOUT);
3823+
3824+
if (result < length) {
3825+
last_libusb_error = result;
3826+
return HACKRF_ERROR_LIBUSB;
3827+
} else {
3828+
return HACKRF_SUCCESS;
3829+
}
3830+
}
3831+
3832+
int ADDCALL hackrf_radio_set_sample_rate(hackrf_device* device, const fp_28_36_t freq_hz)
3833+
{
3834+
USB_API_REQUIRED(device, 0x0113);
3835+
uint64_t set_sr_fp_param;
3836+
uint8_t length;
3837+
int result;
3838+
3839+
set_sr_fp_param = TO_LE64(freq_hz);
3840+
length = sizeof(uint64_t);
3841+
3842+
result = libusb_control_transfer(
3843+
device->usb_device,
3844+
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
3845+
LIBUSB_RECIPIENT_DEVICE,
3846+
HACKRF_VENDOR_REQUEST_RADIO_SET_SAMPLE_RATE,
3847+
0,
3848+
0,
3849+
(unsigned char*) &set_sr_fp_param,
3850+
length,
3851+
DEFAULT_REQUEST_TIMEOUT);
3852+
3853+
if (result < length) {
3854+
last_libusb_error = result;
3855+
return HACKRF_ERROR_LIBUSB;
3856+
}
3857+
3858+
return HACKRF_SUCCESS;
3859+
}
3860+
37053861
#ifdef __cplusplus
37063862
} // __cplusplus defined.
37073863
#endif

0 commit comments

Comments
 (0)