Skip to content

Commit 2cffabc

Browse files
committed
libhackrf: add 'hackrf_radio_set_frequency()', 'hackrf_radio_set_frequency_explicit()' and 'hackrf_radio_set_sample_rate()'
1 parent c83e55e commit 2cffabc

5 files changed

Lines changed: 371 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: 150 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
@@ -3741,6 +3744,153 @@ int ADDCALL hackrf_radio_set_mode(hackrf_device* device, const enum radio_config
37413744
return HACKRF_SUCCESS;
37423745
}
37433746

3747+
int ADDCALL hackrf_str_to_fp64(uint8_t Qn, char* str, char* endptr, uint64_t* const value)
3748+
{
3749+
uint64_t m = 0;
3750+
uint64_t n = 0;
3751+
uint64_t div = 1;
3752+
uint64_t div_max = ceil((double) Qn * log10(2.0)) * 10;
3753+
3754+
// parse integer component
3755+
for (; (*str >= '0') && (*str <= '9'); str++) {
3756+
m = (m * 10) + (*str - '0');
3757+
}
3758+
*value = (m << Qn);
3759+
3760+
if (*str != '.') {
3761+
return HACKRF_SUCCESS;
3762+
}
3763+
str++;
3764+
3765+
// parse fractional component
3766+
for (; (*str >= '0') && (*str <= '9') && (div < div_max); str++) {
3767+
n = (n * 10) + (*str - '0');
3768+
div *= 10;
3769+
}
3770+
endptr = str;
3771+
3772+
if (div == 1) {
3773+
return HACKRF_SUCCESS;
3774+
}
3775+
3776+
*value += ((n << Qn) + (div / 2)) / div;
3777+
3778+
return HACKRF_SUCCESS;
3779+
}
3780+
3781+
int ADDCALL hackrf_radio_set_frequency(hackrf_device* device, const fp_40_24_t freq_hz)
3782+
{
3783+
USB_API_REQUIRED(device, 0x0113);
3784+
uint64_t set_freq_fp_param;
3785+
uint8_t length;
3786+
int result;
3787+
3788+
// serialize parameters
3789+
set_freq_fp_param = TO_LE64(freq_hz);
3790+
length = sizeof(uint64_t);
3791+
3792+
result = libusb_control_transfer(
3793+
device->usb_device,
3794+
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
3795+
LIBUSB_RECIPIENT_DEVICE,
3796+
HACKRF_VENDOR_REQUEST_RADIO_SET_FREQUENCY,
3797+
0,
3798+
0,
3799+
(unsigned char*) &set_freq_fp_param,
3800+
length,
3801+
DEFAULT_REQUEST_TIMEOUT);
3802+
3803+
if (result < length) {
3804+
last_libusb_error = result;
3805+
return HACKRF_ERROR_LIBUSB;
3806+
}
3807+
3808+
return HACKRF_SUCCESS;
3809+
}
3810+
3811+
int ADDCALL hackrf_radio_set_frequency_explicit(
3812+
hackrf_device* device,
3813+
const fp_40_24_t if_freq_hz,
3814+
const fp_40_24_t lo_freq_hz,
3815+
const enum rf_path_filter path)
3816+
{
3817+
struct {
3818+
fp_40_24_t if_freq_hz;
3819+
fp_40_24_t lo_freq_hz;
3820+
uint8_t path;
3821+
} params;
3822+
3823+
uint8_t length;
3824+
int result;
3825+
3826+
// TODO are these values still correct for HackRF Pro ?
3827+
if (FP_FREQ_HZ(if_freq_hz) < 2000000000 || FP_FREQ_HZ(if_freq_hz) > 3000000000) {
3828+
return HACKRF_ERROR_INVALID_PARAM;
3829+
}
3830+
3831+
// TODO are these values still correct for HackRF Pro ?
3832+
if ((path != RF_PATH_FILTER_BYPASS) &&
3833+
(FP_FREQ_HZ(lo_freq_hz) < 84375000 || FP_FREQ_HZ(lo_freq_hz) > 5400000000)) {
3834+
return HACKRF_ERROR_INVALID_PARAM;
3835+
}
3836+
3837+
if (path > 2) {
3838+
return HACKRF_ERROR_INVALID_PARAM;
3839+
}
3840+
3841+
params.if_freq_hz = TO_LE(if_freq_hz);
3842+
params.lo_freq_hz = TO_LE(lo_freq_hz);
3843+
params.path = (uint8_t) path;
3844+
length = sizeof(params);
3845+
3846+
result = libusb_control_transfer(
3847+
device->usb_device,
3848+
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
3849+
LIBUSB_RECIPIENT_DEVICE,
3850+
HACKRF_VENDOR_REQUEST_RADIO_SET_FREQUENCY_EXPLICIT,
3851+
0,
3852+
0,
3853+
(unsigned char*) &params,
3854+
length,
3855+
DEFAULT_REQUEST_TIMEOUT);
3856+
3857+
if (result < length) {
3858+
last_libusb_error = result;
3859+
return HACKRF_ERROR_LIBUSB;
3860+
} else {
3861+
return HACKRF_SUCCESS;
3862+
}
3863+
}
3864+
3865+
int ADDCALL hackrf_radio_set_sample_rate(hackrf_device* device, const fp_28_36_t freq_hz)
3866+
{
3867+
USB_API_REQUIRED(device, 0x0113);
3868+
uint64_t set_sr_fp_param;
3869+
uint8_t length;
3870+
int result;
3871+
3872+
set_sr_fp_param = TO_LE64(freq_hz);
3873+
length = sizeof(uint64_t);
3874+
3875+
result = libusb_control_transfer(
3876+
device->usb_device,
3877+
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
3878+
LIBUSB_RECIPIENT_DEVICE,
3879+
HACKRF_VENDOR_REQUEST_RADIO_SET_SAMPLE_RATE,
3880+
0,
3881+
0,
3882+
(unsigned char*) &set_sr_fp_param,
3883+
length,
3884+
DEFAULT_REQUEST_TIMEOUT);
3885+
3886+
if (result < length) {
3887+
last_libusb_error = result;
3888+
return HACKRF_ERROR_LIBUSB;
3889+
}
3890+
3891+
return HACKRF_SUCCESS;
3892+
}
3893+
37443894
#ifdef __cplusplus
37453895
} // __cplusplus defined.
37463896
#endif

0 commit comments

Comments
 (0)