Skip to content

Commit d4fb086

Browse files
committed
Add 'hackrf_open_mode()', 'hackrf_open_mode_by_serial()' and 'hackrf_device_list_open_mode()'
1 parent b6afd9f commit d4fb086

5 files changed

Lines changed: 224 additions & 2 deletions

File tree

firmware/hackrf_usb/hackrf_usb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ static usb_request_handler_fn vendor_request_handler[] = {
183183
usb_vendor_request_read_radio_reg,
184184
usb_vendor_request_get_buffer_size,
185185
usb_vendor_request_lock_radio_reg,
186+
usb_vendor_request_open,
187+
usb_vendor_request_close,
186188
};
187189

188190
static const uint32_t vendor_request_handler_count =

firmware/hackrf_usb/usb_api_transceiver.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,42 @@ usb_request_status_t usb_vendor_request_get_buffer_size(
486486
return USB_REQUEST_STATUS_OK;
487487
}
488488

489+
usb_request_status_t usb_vendor_request_open(
490+
usb_endpoint_t* const endpoint,
491+
const usb_transfer_stage_t stage)
492+
{
493+
uint16_t usb_api_version;
494+
radio_config_mode_t radio_config_mode;
495+
496+
if (stage == USB_TRANSFER_STAGE_SETUP) {
497+
usb_api_version = endpoint->setup.value;
498+
radio_config_mode = (radio_config_mode_t) endpoint->setup.index;
499+
500+
// TODO let device know we have a new libhackrf connection and its supported usb_api_version
501+
(void) usb_api_version;
502+
503+
// switch bitstreams and update radio mode
504+
if (!radio_set_config_mode(&radio, radio_config_mode)) {
505+
return USB_REQUEST_STATUS_STALL;
506+
}
507+
usb_transfer_schedule_ack(endpoint->in);
508+
}
509+
510+
return USB_REQUEST_STATUS_OK;
511+
}
512+
513+
usb_request_status_t usb_vendor_request_close(
514+
usb_endpoint_t* const endpoint,
515+
const usb_transfer_stage_t stage)
516+
{
517+
if (stage == USB_TRANSFER_STAGE_SETUP) {
518+
// TODO do nothing for now
519+
usb_transfer_schedule_ack(endpoint->in);
520+
}
521+
522+
return USB_REQUEST_STATUS_OK;
523+
}
524+
489525
/* clang-format off */
490526

491527
// Which GPDMA channel to use.

firmware/hackrf_usb/usb_api_transceiver.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ usb_request_status_t usb_vendor_request_set_rx_overrun_limit(
8080
usb_request_status_t usb_vendor_request_get_buffer_size(
8181
usb_endpoint_t* const endpoint,
8282
const usb_transfer_stage_t stage);
83+
usb_request_status_t usb_vendor_request_open(
84+
usb_endpoint_t* const endpoint,
85+
const usb_transfer_stage_t stage);
86+
usb_request_status_t usb_vendor_request_close(
87+
usb_endpoint_t* const endpoint,
88+
const usb_transfer_stage_t stage);
8389

8490
void request_transceiver_mode(transceiver_mode_t mode);
8591
void transceiver_startup(transceiver_mode_t mode);

host/libhackrf/src/hackrf.c

Lines changed: 116 additions & 2 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_OPEN = 63,
125+
HACKRF_VENDOR_REQUEST_CLOSE = 64,
124126
} hackrf_vendor_request;
125127

126128
#define USB_CONFIG_STANDARD 0x1
@@ -834,6 +836,105 @@ static int hackrf_open_setup(libusb_device_handle* usb_device, hackrf_device** d
834836
return HACKRF_SUCCESS;
835837
}
836838

839+
static int hackrf_open_cmd(hackrf_device* device, const enum radio_config_mode mode)
840+
{
841+
USB_API_REQUIRED(device, 0x0113);
842+
843+
uint16_t usb_api_version;
844+
int result;
845+
846+
result = hackrf_usb_api_version_read(device, &usb_api_version);
847+
if (result != HACKRF_SUCCESS) {
848+
return result;
849+
}
850+
851+
result = libusb_control_transfer(
852+
device->usb_device,
853+
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
854+
LIBUSB_RECIPIENT_DEVICE,
855+
HACKRF_VENDOR_REQUEST_OPEN,
856+
usb_api_version,
857+
(uint16_t) mode,
858+
NULL,
859+
0,
860+
DEFAULT_REQUEST_TIMEOUT);
861+
862+
if (result != 0) {
863+
last_libusb_error = result;
864+
return HACKRF_ERROR_LIBUSB;
865+
}
866+
867+
return HACKRF_SUCCESS;
868+
}
869+
870+
static int hackrf_close_cmd(hackrf_device* device)
871+
{
872+
USB_API_REQUIRED(device, 0x0113);
873+
874+
int result;
875+
876+
result = libusb_control_transfer(
877+
device->usb_device,
878+
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
879+
LIBUSB_RECIPIENT_DEVICE,
880+
HACKRF_VENDOR_REQUEST_CLOSE,
881+
0,
882+
0,
883+
NULL,
884+
0,
885+
DEFAULT_REQUEST_TIMEOUT);
886+
887+
if (result != 0) {
888+
last_libusb_error = result;
889+
return HACKRF_ERROR_LIBUSB;
890+
}
891+
892+
return HACKRF_SUCCESS;
893+
}
894+
895+
int ADDCALL hackrf_open_mode(const enum radio_config_mode mode, hackrf_device** device)
896+
{
897+
int result;
898+
899+
result = hackrf_open(device);
900+
if (result != HACKRF_SUCCESS) {
901+
return result;
902+
}
903+
904+
return hackrf_open_cmd(*device, mode);
905+
}
906+
907+
int ADDCALL hackrf_radio_open_mode_by_serial(
908+
const char* const desired_serial_number,
909+
const enum radio_config_mode mode,
910+
hackrf_device** device)
911+
{
912+
int result;
913+
914+
result = hackrf_open_by_serial(desired_serial_number, device);
915+
if (result != HACKRF_SUCCESS) {
916+
return result;
917+
}
918+
919+
return hackrf_open_cmd(*device, mode);
920+
}
921+
922+
int ADDCALL hackrf_device_list_open_mode(
923+
hackrf_device_list_t* list,
924+
int idx,
925+
const enum radio_config_mode mode,
926+
hackrf_device** device)
927+
{
928+
int result;
929+
930+
result = hackrf_device_list_open(list, idx, device);
931+
if (result != HACKRF_SUCCESS) {
932+
return result;
933+
}
934+
935+
return hackrf_open_cmd(*device, mode);
936+
}
937+
837938
int ADDCALL hackrf_open(hackrf_device** device)
838939
{
839940
libusb_device_handle* usb_device;
@@ -2443,7 +2544,7 @@ int ADDCALL hackrf_stop_tx(hackrf_device* device)
24432544

24442545
int ADDCALL hackrf_close(hackrf_device* device)
24452546
{
2446-
int result1, result2;
2547+
int result1, result2, result3;
24472548

24482549
result1 = HACKRF_SUCCESS;
24492550
result2 = HACKRF_SUCCESS;
@@ -2456,6 +2557,14 @@ int ADDCALL hackrf_close(hackrf_device* device)
24562557
* also cancel any pending transmit/receive transfers.
24572558
*/
24582559
result2 = kill_transfer_thread(device);
2560+
2561+
/*
2562+
* Let the device know it's been closed.
2563+
*
2564+
* TODO discuss the need for this
2565+
*/
2566+
result3 = hackrf_close_cmd(device);
2567+
24592568
if (device->usb_device != NULL) {
24602569
libusb_release_interface(device->usb_device, 0);
24612570
libusb_close(device->usb_device);
@@ -2474,7 +2583,12 @@ int ADDCALL hackrf_close(hackrf_device* device)
24742583
if (result2 != HACKRF_SUCCESS) {
24752584
return result2;
24762585
}
2477-
return result1;
2586+
2587+
if (result1 != HACKRF_SUCCESS) {
2588+
return result1;
2589+
}
2590+
2591+
return result3;
24782592
}
24792593

24802594
const char* ADDCALL hackrf_error_name(enum hackrf_error errcode)

host/libhackrf/src/hackrf.h

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

949+
/**
950+
* HackRF Pro Radio Configuration Mode.
951+
*
952+
* Used by @ref hackrf_open, @ref hackrf_open_mode_by_serial and @ref hackrf_device_list_open_mode to set the active configuration mode.
953+
*/
954+
enum radio_config_mode {
955+
RADIO_CONFIG_LEGACY = 0,
956+
RADIO_CONFIG_STANDARD = 1,
957+
RADIO_CONFIG_EXT_PRECISION_RX = 2,
958+
RADIO_CONFIG_EXT_PRECISION_TX = 3,
959+
RADIO_CONFIG_HALF_PRECISION = 4,
960+
};
961+
949962
/**
950963
* 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
951964
* @ingroup device
@@ -1199,6 +1212,7 @@ extern ADDAPI hackrf_device_list_t* ADDCALL hackrf_device_list();
11991212

12001213
/**
12011214
* Open a @ref hackrf_device from a device list
1215+
* @deprecated this function has been replaced by @ref hackrf_device_list_open_mode
12021216
* @param[in] list device list to open device from
12031217
* @param[in] idx index of the device to open
12041218
* @param[out] device device handle to open
@@ -1210,6 +1224,24 @@ extern ADDAPI int ADDCALL hackrf_device_list_open(
12101224
int idx,
12111225
hackrf_device** device);
12121226

1227+
/**
1228+
* Open a @ref hackrf_device from a device list and initialize it to the given radio configuration mode.
1229+
*
1230+
* Modes other than RADIO_CONFIG_STANDARD are only supported on HackRF Pro hardware.
1231+
*
1232+
* @param[in] list device list to open device from
1233+
* @param[in] idx index of the device to open
1234+
* @param[in] mode configuration mode. Defaults to RADIO_CONFIG_STANDARD. Available modes are defined in @ref radio_config_mode.
1235+
* @param[out] device device handle to open
1236+
* @return @ref HACKRF_SUCCESS on success, @ref HACKRF_ERROR_INVALID_PARAM on invalid parameters or other @ref hackrf_error variant
1237+
* @ingroup device
1238+
*/
1239+
extern ADDAPI int ADDCALL hackrf_device_list_open_mode(
1240+
hackrf_device_list_t* list,
1241+
int idx,
1242+
const enum radio_config_mode mode,
1243+
hackrf_device** device);
1244+
12131245
/**
12141246
* Check if a listed HackRF device is sharing its USB bus with other devices.
12151247
*
@@ -1231,14 +1263,30 @@ extern ADDAPI void ADDCALL hackrf_device_list_free(hackrf_device_list_t* list);
12311263

12321264
/**
12331265
* Open first available HackRF device
1266+
* @deprecated this function has been replaced by @ref hackrf_open_mode
12341267
* @param[out] device device handle
12351268
* @return @ref HACKRF_SUCCESS on success, @ref HACKRF_ERROR_INVALID_PARAM if @p device is NULL, @ref HACKRF_ERROR_NOT_FOUND if no HackRF devices are found or other @ref hackrf_error variant
12361269
* @ingroup device
12371270
*/
12381271
extern ADDAPI int ADDCALL hackrf_open(hackrf_device** device);
12391272

1273+
/**
1274+
* Open first available HackRF device and initialize it to the given radio configuration mode.
1275+
*
1276+
* Modes other than RADIO_CONFIG_STANDARD are only supported on HackRF Pro hardware.
1277+
*
1278+
* @param[in] mode configuration mode. Defaults to RADIO_CONFIG_STANDARD. Available modes are defined in @ref radio_config_mode.
1279+
* @param[out] device device handle
1280+
* @return @ref HACKRF_SUCCESS on success, @ref HACKRF_ERROR_INVALID_PARAM if @p device is NULL, @ref HACKRF_ERROR_NOT_FOUND if no HackRF devices are found or other @ref hackrf_error variant
1281+
* @ingroup device
1282+
*/
1283+
extern ADDAPI int ADDCALL hackrf_open_mode(
1284+
const enum radio_config_mode mode,
1285+
hackrf_device** device);
1286+
12401287
/**
12411288
* Open HackRF device by serial number
1289+
* @deprecated this function has been replaced by @ref hackrf_open_mode_by_serial
12421290
* @param[in] desired_serial_number serial number of device to open. If NULL then default to first device found.
12431291
* @param[out] device device handle
12441292
* @return @ref HACKRF_SUCCESS on success, @ref HACKRF_ERROR_INVALID_PARAM if @p device is NULL, @ref HACKRF_ERROR_NOT_FOUND if no HackRF devices are found or other @ref hackrf_error variant
@@ -1248,6 +1296,22 @@ extern ADDAPI int ADDCALL hackrf_open_by_serial(
12481296
const char* const desired_serial_number,
12491297
hackrf_device** device);
12501298

1299+
/**
1300+
* Open HackRF device by serial number and initialize it to the given radio configuration mode.
1301+
*
1302+
* Modes other than RADIO_CONFIG_STANDARD are only supported on HackRF Pro hardware.
1303+
*
1304+
* @param[in] desired_serial_number serial number of device to open. If NULL then default to first device found.
1305+
* @param[in] mode configuration mode. Defaults to RADIO_CONFIG_STANDARD. Available modes are defined in @ref radio_config_mode.
1306+
* @param[out] device device handle
1307+
* @return @ref HACKRF_SUCCESS on success, @ref HACKRF_ERROR_INVALID_PARAM if @p device is NULL, @ref HACKRF_ERROR_NOT_FOUND if no HackRF devices are found or other @ref hackrf_error variant
1308+
* @ingroup device
1309+
*/
1310+
extern ADDAPI int ADDCALL hackrf_open_mode_by_serial(
1311+
const char* const desired_serial_number,
1312+
const enum radio_config_mode mode,
1313+
hackrf_device** device);
1314+
12511315
/**
12521316
* Close a previously opened device
12531317
* @param[in] device device to close

0 commit comments

Comments
 (0)