From 7c3f6340ed8cff29eb3776f3993a092f0b1cdfaa Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 12 Mar 2014 17:21:49 -0600 Subject: [PATCH] HackRF One antenna port power control in firmware, libhackrf, and hackrf_transfer --- firmware/common/rf_path.c | 17 ++++++++++++- firmware/common/rf_path.h | 1 + firmware/hackrf_usb/hackrf_usb.c | 5 ++++ firmware/hackrf_usb/usb_api_transceiver.c | 21 +++++++++++++++ firmware/hackrf_usb/usb_api_transceiver.h | 2 ++ host/hackrf-tools/src/hackrf_transfer.c | 31 +++++++++++++++++++++-- host/libhackrf/src/hackrf.c | 23 +++++++++++++++++ host/libhackrf/src/hackrf.h | 3 +++ 8 files changed, 100 insertions(+), 3 deletions(-) diff --git a/firmware/common/rf_path.c b/firmware/common/rf_path.c index 56c8d5d3..46aaac44 100644 --- a/firmware/common/rf_path.c +++ b/firmware/common/rf_path.c @@ -75,7 +75,6 @@ uint8_t switchctrl = SWITCHCTRL_SAFE; -#ifdef HACKRF_ONE /* * Antenna port power on HackRF One is controlled by GPO1 on the RFFC5072. * This is the only thing we use RFFC5072 GPO for on HackRF One. The value of @@ -83,6 +82,8 @@ uint8_t switchctrl = SWITCHCTRL_SAFE; * register. */ #define SWITCHCTRL_ANT_PWR (1 << 6) /* turn on antenna port power */ + +#ifdef HACKRF_ONE static void switchctrl_set_hackrf_one(uint8_t ctrl) { if (ctrl & SWITCHCTRL_TX) { gpio_set(PORT_TX, PIN_TX); @@ -262,6 +263,9 @@ void rf_path_set_direction(const rf_path_direction_t direction) { case RF_PATH_DIRECTION_OFF: default: +#ifdef HACKRF_ONE + rf_path_set_antenna(0); +#endif /* Set RF path to receive direction when "off" */ switchctrl &= ~SWITCHCTRL_TX; rffc5071_disable(); @@ -317,3 +321,14 @@ void rf_path_set_lna(const uint_fast8_t enable) { switchctrl_set(switchctrl); } + +/* antenna port power control */ +void rf_path_set_antenna(const uint_fast8_t enable) { + if (enable) { + switchctrl |= SWITCHCTRL_ANT_PWR; + } else { + switchctrl &= ~(SWITCHCTRL_ANT_PWR); + } + + switchctrl_set(switchctrl); +} diff --git a/firmware/common/rf_path.h b/firmware/common/rf_path.h index 6b959b53..8e88a989 100644 --- a/firmware/common/rf_path.h +++ b/firmware/common/rf_path.h @@ -45,5 +45,6 @@ typedef enum { void rf_path_set_filter(const rf_path_filter_t filter); void rf_path_set_lna(const uint_fast8_t enable); +void rf_path_set_antenna(const uint_fast8_t enable); #endif/*__RFPATH_H__*/ diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 32d60215..fc5acba5 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -126,6 +126,11 @@ static const usb_request_handler_fn vendor_request_handler[] = { usb_vendor_request_set_vga_gain, usb_vendor_request_set_txvga_gain, usb_vendor_request_set_if_freq, +#ifdef HACKRF_ONE + usb_vendor_request_set_antenna_enable, +#else + NULL, +#endif }; static const uint32_t vendor_request_handler_count = diff --git a/firmware/hackrf_usb/usb_api_transceiver.c b/firmware/hackrf_usb/usb_api_transceiver.c index bb1c2408..26230d87 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.c +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -187,3 +187,24 @@ usb_request_status_t usb_vendor_request_set_if_freq( } return USB_REQUEST_STATUS_OK; } + +usb_request_status_t usb_vendor_request_set_antenna_enable( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + if (stage == USB_TRANSFER_STAGE_SETUP) { + switch (endpoint->setup.value) { + case 0: + rf_path_set_antenna(0); + usb_transfer_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + case 1: + rf_path_set_antenna(1); + usb_transfer_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + default: + return USB_REQUEST_STATUS_STALL; + } + } else { + return USB_REQUEST_STATUS_OK; + } +} diff --git a/firmware/hackrf_usb/usb_api_transceiver.h b/firmware/hackrf_usb/usb_api_transceiver.h index 4cc98dd4..414ac541 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.h +++ b/firmware/hackrf_usb/usb_api_transceiver.h @@ -50,5 +50,7 @@ usb_request_status_t usb_vendor_request_set_txvga_gain( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_request_status_t usb_vendor_request_set_if_freq( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_set_antenna_enable( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); #endif/*__USB_API_TRANSCEIVER_H__*/ diff --git a/host/hackrf-tools/src/hackrf_transfer.c b/host/hackrf-tools/src/hackrf_transfer.c index cbae598d..db7964f5 100644 --- a/host/hackrf-tools/src/hackrf_transfer.c +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -247,6 +247,9 @@ uint64_t freq_hz; bool amp = false; uint32_t amp_enable; +bool antenna = false; +uint32_t antenna_enable; + bool sample_rate = false; uint32_t sample_rate_hz; @@ -325,6 +328,7 @@ static void usage() { printf("\t # This is for SDR# compatibility and may not work with other software.\n"); printf("\t[-f set_freq_hz] # Set Freq in Hz between [%lluMHz, %lluMHz].\n", FREQ_MIN_HZ/FREQ_ONE_MHZ, FREQ_MAX_HZ/FREQ_ONE_MHZ); printf("\t[-a set_amp] # Set Amp 1=Enable, 0=Disable.\n"); + printf("\t[-p set_antenna] # Set antenna port power, 1=Enable, 0=Disable.\n"); printf("\t[-l gain_db] # Set lna gain, 0-40dB, 8dB steps\n"); printf("\t[-i gain_db] # Set vga(if) gain, 0-62dB, 2dB steps\n"); printf("\t[-x gain_db] # Set TX vga gain, 0-47dB, 1dB steps\n"); @@ -371,7 +375,7 @@ int main(int argc, char** argv) { float time_diff; unsigned int lna_gain=8, vga_gain=20, txvga_gain=0; - while( (opt = getopt(argc, argv, "wr:t:f:a:s:n:b:l:i:x:")) != EOF ) + while( (opt = getopt(argc, argv, "wr:t:f:a:p:s:n:b:l:i:x:")) != EOF ) { result = HACKRF_SUCCESS; switch( opt ) @@ -400,6 +404,11 @@ int main(int argc, char** argv) { result = parse_u32(optarg, &_enable); break; + case 'p': + antenna = true; + result = parse_u32(optarg, &antenna_enable); + break; + case 'l': result = parse_u32(optarg, &lna_gain); break; @@ -470,6 +479,14 @@ int main(int argc, char** argv) { } } + if (antenna) { + if (antenna_enable > 1) { + printf("argument error: set_antenna shall be 0 or 1.\n"); + usage(); + return EXIT_FAILURE; + } + } + if( sample_rate == false ) { sample_rate_hz = DEFAULT_SAMPLE_RATE_HZ; @@ -645,7 +662,17 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } } - + + if (antenna) { + printf("call hackrf_set_antenna_enable(%u)\n", antenna_enable); + result = hackrf_set_antenna_enable(device, (uint8_t)antenna_enable); + if (result != HACKRF_SUCCESS) { + printf("hackrf_set_antenna_enable() failed: %s (%d)\n", hackrf_error_name(result), result); + usage(); + return EXIT_FAILURE; + } + } + if( limit_num_samples ) { printf("samples_to_xfer %lu/%lluMio\n", samples_to_xfer, (samples_to_xfer/FREQ_ONE_MHZ) ); } diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 20ac5133..f52cc4d9 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -64,6 +64,7 @@ typedef enum { HACKRF_VENDOR_REQUEST_SET_VGA_GAIN = 20, HACKRF_VENDOR_REQUEST_SET_TXVGA_GAIN = 21, HACKRF_VENDOR_REQUEST_SET_IF_FREQ = 22, + HACKRF_VENDOR_REQUEST_ANTENNA_ENABLE = 23, } hackrf_vendor_request; typedef enum { @@ -1010,6 +1011,28 @@ int ADDCALL hackrf_set_if_freq(hackrf_device* device, const uint32_t freq_mhz) } } +int ADDCALL hackrf_set_antenna_enable(hackrf_device* device, const uint8_t value) +{ + int result; + result = libusb_control_transfer( + device->usb_device, + LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, + HACKRF_VENDOR_REQUEST_ANTENNA_ENABLE, + value, + 0, + NULL, + 0, + 0 + ); + + if (result != 0) + { + return HACKRF_ERROR_LIBUSB; + } else { + return HACKRF_SUCCESS; + } +} + static void* transfer_threadproc(void* arg) { hackrf_device* device = (hackrf_device*)arg; diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index c3a15c4f..0fecce9b 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -153,6 +153,9 @@ extern ADDAPI int ADDCALL hackrf_set_vga_gain(hackrf_device* device, uint32_t va /* range 0-47 step 1db */ extern ADDAPI int ADDCALL hackrf_set_txvga_gain(hackrf_device* device, uint32_t value); +/* antenna port power control */ +extern ADDAPI int ADDCALL hackrf_set_antenna_enable(hackrf_device* device, const uint8_t value); + extern ADDAPI const char* ADDCALL hackrf_error_name(enum hackrf_error errcode); extern ADDAPI const char* ADDCALL hackrf_board_id_name(enum hackrf_board_id board_id);