diff --git a/firmware/common/rf_path.h b/firmware/common/rf_path.h index 8e88a989..7fe1fa79 100644 --- a/firmware/common/rf_path.h +++ b/firmware/common/rf_path.h @@ -37,9 +37,9 @@ typedef enum { void rf_path_set_direction(const rf_path_direction_t direction); typedef enum { - RF_PATH_FILTER_BYPASS, - RF_PATH_FILTER_LOW_PASS, - RF_PATH_FILTER_HIGH_PASS, + RF_PATH_FILTER_BYPASS = 0, + RF_PATH_FILTER_LOW_PASS = 1, + RF_PATH_FILTER_HIGH_PASS = 2, } rf_path_filter_t; void rf_path_set_filter(const rf_path_filter_t filter); diff --git a/firmware/common/tuning.c b/firmware/common/tuning.c index c056bf27..050a0602 100644 --- a/firmware/common/tuning.c +++ b/firmware/common/tuning.c @@ -25,8 +25,6 @@ #include #include -#include "rf_path.h" - #define FREQ_ONE_MHZ (1000*1000) #define MIN_LP_FREQ_MHZ (0) @@ -40,6 +38,9 @@ #define MID2_HP_FREQ_MHZ (5100) #define MAX_HP_FREQ_MHZ (7250) +#define MIN_LO_FREQ_HZ (84375000) +#define MAX_LO_FREQ_HZ (5400000000ULL) + static uint32_t max2837_freq_nominal_hz=2560000000; uint64_t freq_cache = 100000000; @@ -54,7 +55,6 @@ bool set_freq(const uint64_t freq) uint32_t RFFC5071_freq_mhz; uint32_t MAX2837_freq_hz; uint64_t real_RFFC5071_freq_hz; - uint32_t tmp_hz; const uint32_t freq_mhz = freq / 1000000; const uint32_t freq_hz = freq % 1000000; @@ -105,11 +105,27 @@ bool set_freq(const uint64_t freq) return success; } -bool set_freq_if(const uint32_t freq_if_hz) { - bool success = false; - if( (freq_if_hz >= MIN_BYPASS_FREQ_MHZ) && (freq_if_hz <= MAX_BYPASS_FREQ_MHZ) ) { - max2837_freq_nominal_hz = freq_if_hz; - success = set_freq(freq_cache); +bool set_freq_explicit(const uint64_t if_freq_hz, const uint64_t lo_freq_hz, + const rf_path_filter_t path) +{ + if ((if_freq_hz < ((uint64_t)MIN_BYPASS_FREQ_MHZ * FREQ_ONE_MHZ)) + || (if_freq_hz > ((uint64_t)MAX_BYPASS_FREQ_MHZ * FREQ_ONE_MHZ))) { + return false; } - return success; + + if ((path != RF_PATH_FILTER_BYPASS) && + (lo_freq_hz < MIN_LO_FREQ_HZ) || (lo_freq_hz > MAX_LO_FREQ_HZ)) { + return false; + } + + if (path > 2) { + return false; + } + + rf_path_set_filter(path); + max2837_set_frequency(if_freq_hz); + if (path != RF_PATH_FILTER_BYPASS) { + (void)rffc5071_set_frequency(lo_freq_hz / FREQ_ONE_MHZ); + } + return true; } diff --git a/firmware/common/tuning.h b/firmware/common/tuning.h index 16887c9e..38e26d65 100644 --- a/firmware/common/tuning.h +++ b/firmware/common/tuning.h @@ -23,10 +23,13 @@ #ifndef __TUNING_H__ #define __TUNING_H__ +#include "rf_path.h" + #include #include bool set_freq(const uint64_t freq); -bool set_freq_if(const uint32_t freq_if_hz); +bool set_freq_explicit(const uint64_t if_freq_hz, const uint64_t lo_freq_hz, + const rf_path_filter_t path); #endif/*__TUNING_H__*/ diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index fc5acba5..d2605f1a 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -125,12 +125,13 @@ static const usb_request_handler_fn vendor_request_handler[] = { usb_vendor_request_set_lna_gain, usb_vendor_request_set_vga_gain, usb_vendor_request_set_txvga_gain, - usb_vendor_request_set_if_freq, + NULL, // was set_if_freq #ifdef HACKRF_ONE usb_vendor_request_set_antenna_enable, #else NULL, #endif + usb_vendor_request_set_freq_explicit, }; 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 26230d87..7ab06376 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.c +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -41,6 +41,14 @@ typedef struct { set_freq_params_t set_freq_params; +struct set_freq_explicit_params { + uint64_t if_freq_hz; /* intermediate frequency */ + uint64_t lo_freq_hz; /* front-end local oscillator frequency */ + uint8_t path; /* image rejection filter path */ +}; + +struct set_freq_explicit_params explicit_params; + typedef struct { uint32_t freq_hz; uint32_t divider; @@ -175,19 +183,6 @@ usb_request_status_t usb_vendor_request_set_txvga_gain( return USB_REQUEST_STATUS_OK; } -usb_request_status_t usb_vendor_request_set_if_freq( - usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage -) { - if( stage == USB_TRANSFER_STAGE_SETUP ) { - if( set_freq_if((uint32_t)endpoint->setup.index * 1000 * 1000) ) { - usb_transfer_schedule_ack(endpoint->in); - } else { - return USB_REQUEST_STATUS_STALL; - } - } - 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) { @@ -208,3 +203,23 @@ usb_request_status_t usb_vendor_request_set_antenna_enable( return USB_REQUEST_STATUS_OK; } } + +usb_request_status_t usb_vendor_request_set_freq_explicit( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage) +{ + if (stage == USB_TRANSFER_STAGE_SETUP) { + usb_transfer_schedule_block(endpoint->out, &explicit_params, + sizeof(struct set_freq_explicit_params), NULL, NULL); + return USB_REQUEST_STATUS_OK; + } else if (stage == USB_TRANSFER_STAGE_DATA) { + if (set_freq_explicit(explicit_params.if_freq_hz, + explicit_params.lo_freq_hz, explicit_params.path)) { + usb_transfer_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + } + 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 414ac541..24244025 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.h +++ b/firmware/hackrf_usb/usb_api_transceiver.h @@ -48,9 +48,9 @@ usb_request_status_t usb_vendor_request_set_vga_gain( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); 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); +usb_request_status_t usb_vendor_request_set_freq_explicit( + 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 db7964f5..980201c9 100644 --- a/host/hackrf-tools/src/hackrf_transfer.c +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -86,6 +86,11 @@ int gettimeofday(struct timeval *tv, void* ignored) #define DEFAULT_FREQ_HZ (900000000ull) /* 900MHz */ #define FREQ_MIN_HZ (0ull) /* 0 Hz */ #define FREQ_MAX_HZ (7250000000ull) /* 7250MHz */ +#define IF_MIN_HZ (2150000000ull) +#define IF_MAX_HZ (2750000000ull) +#define LO_MIN_HZ (84375000ull) +#define LO_MAX_HZ (5400000000ull) +#define DEFAULT_LO_HZ (1000000000ull) #define DEFAULT_SAMPLE_RATE_HZ (10000000) /* 10MHz default sample rate */ @@ -240,10 +245,19 @@ bool receive_wav = false; bool transmit = false; struct timeval time_start; struct timeval t_start; - -bool freq = false; + +bool automatic_tuning = false; uint64_t freq_hz; +bool if_freq = false; +uint64_t if_freq_hz; + +bool lo_freq = false; +uint64_t lo_freq_hz = DEFAULT_LO_HZ; + +bool image_reject = false; +uint32_t image_reject_selection; + bool amp = false; uint32_t amp_enable; @@ -326,13 +340,16 @@ static void usage() { printf("\t-t # Transmit data from file.\n"); printf("\t-w # Receive data into file with WAV header and automatic name.\n"); 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"); - printf("\t[-s sample_rate_hz] # Set sample rate in Hz (8/10/12.5/16/20MHz, default %lldMHz).\n", DEFAULT_SAMPLE_RATE_HZ/FREQ_ONE_MHZ); + printf("\t[-f freq_hz] # Frequency in Hz between [%lluMHz, %lluMHz].\n", FREQ_MIN_HZ/FREQ_ONE_MHZ, FREQ_MAX_HZ/FREQ_ONE_MHZ); + printf("\t[-e if_freq_hz] # Intermediate Frequency (IF) in Hz [%lluMHz to %lluMHz].\n", IF_MIN_HZ/FREQ_ONE_MHZ, IF_MAX_HZ/FREQ_ONE_MHZ); + printf("\t[-o lo_freq_hz] # Front-end Local Oscillator (LO) frequency in Hz [%lluMHz to %lluMHz].\n", LO_MIN_HZ/FREQ_ONE_MHZ, LO_MAX_HZ/FREQ_ONE_MHZ); + printf("\t[-m image_reject] # Image rejection filter selection, 0=bypass, 1=low pass, 2=high pass.\n"); + printf("\t[-a amp_enable] # Amplifier 1=Enable, 0=Disable.\n"); + printf("\t[-p antenna_enable] # Antenna port power, 1=Enable, 0=Disable.\n"); + printf("\t[-l gain_db] # LNA gain, 0-40dB, 8dB steps\n"); + printf("\t[-i gain_db] # VGA(IF) gain, 0-62dB, 2dB steps\n"); + printf("\t[-x gain_db] # TX VGA gain, 0-47dB, 1dB steps\n"); + printf("\t[-s sample_rate_hz] # Sample rate in Hz (8/10/12.5/16/20MHz, default %lldMHz).\n", DEFAULT_SAMPLE_RATE_HZ/FREQ_ONE_MHZ); printf("\t[-n num_samples] # Number of samples to transfer (default is unlimited).\n"); printf("\t[-b baseband_filter_bw_hz] # Set baseband filter bandwidth in MHz.\n\tPossible values: 1.75/2.5/3.5/5/5.5/6/7/8/9/10/12/14/15/20/24/28MHz, default < sample_rate_hz.\n" ); } @@ -375,7 +392,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:p:s:n:b:l:i:x:")) != EOF ) + while( (opt = getopt(argc, argv, "wr:t:f:e:o:m:a:p:s:n:b:l:i:x:")) != EOF ) { result = HACKRF_SUCCESS; switch( opt ) @@ -393,12 +410,27 @@ int main(int argc, char** argv) { transmit = true; path = optarg; break; - + case 'f': - freq = true; + automatic_tuning = true; result = parse_u64(optarg, &freq_hz); break; + case 'e': + if_freq = true; + result = parse_u64(optarg, &if_freq_hz); + break; + + case 'o': + lo_freq = true; + result = parse_u64(optarg, &lo_freq_hz); + break; + + case 'm': + image_reject = true; + result = parse_u32(optarg, &image_reject_selection); + break; + case 'a': amp = true; result = parse_u32(optarg, &_enable); @@ -457,23 +489,74 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - if( freq ) { - if( (freq_hz >= FREQ_MAX_HZ) || (freq_hz < FREQ_MIN_HZ) ) - { - printf("argument error: set_freq_hz shall be between [%llu, %llu[.\n", FREQ_MIN_HZ, FREQ_MAX_HZ); + if (if_freq || lo_freq || image_reject) { + /* explicit tuning selected */ + if (!if_freq) { + printf("argument error: if_freq_hz must be specified for explicit tuning.\n"); usage(); return EXIT_FAILURE; } - }else - { + if (!image_reject) { + printf("argument error: image_reject must be specified for explicit tuning.\n"); + usage(); + return EXIT_FAILURE; + } + if (!lo_freq && (image_reject_selection != RF_PATH_FILTER_BYPASS)) { + printf("argument error: lo_freq_hz must be specified for explicit tuning unless image_reject is set to bypass.\n"); + usage(); + return EXIT_FAILURE; + } + if ((if_freq_hz > IF_MAX_HZ) || (if_freq_hz < IF_MIN_HZ)) { + printf("argument error: if_freq_hz shall be between %llu and %llu.\n", IF_MIN_HZ, IF_MAX_HZ); + usage(); + return EXIT_FAILURE; + } + if ((lo_freq_hz > LO_MAX_HZ) || (lo_freq_hz < LO_MIN_HZ)) { + printf("argument error: lo_freq_hz shall be between %llu and %llu.\n", LO_MIN_HZ, LO_MAX_HZ); + usage(); + return EXIT_FAILURE; + } + if (image_reject_selection > 2) { + printf("argument error: image_reject must be 0, 1, or 2 .\n"); + usage(); + return EXIT_FAILURE; + } + if (automatic_tuning) { + printf("warning: freq_hz ignored by explicit tuning selection.\n"); + automatic_tuning = false; + } + switch (image_reject_selection) { + case RF_PATH_FILTER_BYPASS: + freq_hz = if_freq_hz; + break; + case RF_PATH_FILTER_LOW_PASS: + freq_hz = abs(if_freq_hz - lo_freq_hz); + break; + case RF_PATH_FILTER_HIGH_PASS: + freq_hz = if_freq_hz + lo_freq_hz; + break; + default: + freq_hz = DEFAULT_FREQ_HZ; + break; + } + printf("explicit tuning specified for %lu Hz.\n", freq_hz); + } else if (automatic_tuning) { + if( (freq_hz > FREQ_MAX_HZ) || (freq_hz < FREQ_MIN_HZ) ) + { + printf("argument error: freq_hz shall be between %llu and %llu.\n", FREQ_MIN_HZ, FREQ_MAX_HZ); + usage(); + return EXIT_FAILURE; + } + } else { /* Use default freq */ freq_hz = DEFAULT_FREQ_HZ; + automatic_tuning = true; } if( amp ) { if( amp_enable > 1 ) { - printf("argument error: set_amp shall be 0 or 1.\n"); + printf("argument error: amp_enable shall be 0 or 1.\n"); usage(); return EXIT_FAILURE; } @@ -481,7 +564,7 @@ int main(int argc, char** argv) { if (antenna) { if (antenna_enable > 1) { - printf("argument error: set_antenna shall be 0 or 1.\n"); + printf("argument error: antenna_enable shall be 0 or 1.\n"); usage(); return EXIT_FAILURE; } @@ -645,12 +728,25 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - printf("call hackrf_set_freq(%lu Hz/%.03f MHz)\n", freq_hz, ((double)freq_hz/(double)FREQ_ONE_MHZ) ); - result = hackrf_set_freq(device, freq_hz); - if( result != HACKRF_SUCCESS ) { - printf("hackrf_set_freq() failed: %s (%d)\n", hackrf_error_name(result), result); - usage(); - return EXIT_FAILURE; + if (automatic_tuning) { + printf("call hackrf_set_freq(%lu Hz/%.03f MHz)\n", freq_hz, ((double)freq_hz/(double)FREQ_ONE_MHZ) ); + result = hackrf_set_freq(device, freq_hz); + if( result != HACKRF_SUCCESS ) { + printf("hackrf_set_freq() failed: %s (%d)\n", hackrf_error_name(result), result); + usage(); + return EXIT_FAILURE; + } + } else { + printf("call hackrf_set_freq_explicit() with %lu Hz IF, %lu Hz LO, %s\n", + if_freq_hz, lo_freq_hz, hackrf_filter_path_name(image_reject_selection)); + result = hackrf_set_freq_explicit(device, if_freq_hz, lo_freq_hz, + image_reject_selection); + if (result != HACKRF_SUCCESS) { + printf("hackrf_set_freq_explicit() failed: %s (%d)\n", + hackrf_error_name(result), result); + usage(); + return EXIT_FAILURE; + } } if( amp ) { diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index f52cc4d9..ad25d714 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -36,8 +36,10 @@ typedef int bool; #ifdef HACKRF_BIG_ENDIAN #define TO_LE(x) __builtin_bswap32(x) +#define TO_LE64(x) __builtin_bswap64(x) #else #define TO_LE(x) x +#define TO_LE64(x) x #endif // TODO: Factor this into a shared #include so that firmware can use @@ -63,8 +65,8 @@ typedef enum { HACKRF_VENDOR_REQUEST_SET_LNA_GAIN = 19, 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_SET_FREQ_EXPLICIT = 24, } hackrf_vendor_request; typedef enum { @@ -724,7 +726,7 @@ int ADDCALL hackrf_version_string_read(hackrf_device* device, char* version, } typedef struct { - uint32_t freq_mhz; /* From 30 to 6000MHz */ + uint32_t freq_mhz; /* From 0 to 6000+MHz */ uint32_t freq_hz; /* From 0 to 999999Hz */ /* Final Freq = freq_mhz+freq_hz */ } set_freq_params_t; @@ -764,6 +766,56 @@ int ADDCALL hackrf_set_freq(hackrf_device* device, const uint64_t freq_hz) } } +struct set_freq_explicit_params { + uint64_t if_freq_hz; /* intermediate frequency */ + uint64_t lo_freq_hz; /* front-end local oscillator frequency */ + uint8_t path; /* image rejection filter path */ +}; + +int ADDCALL hackrf_set_freq_explicit(hackrf_device* device, + const uint64_t if_freq_hz, const uint64_t lo_freq_hz, + const enum rf_path_filter path) +{ + struct set_freq_explicit_params params; + uint8_t length; + int result; + + if (if_freq_hz < 2150000000 || if_freq_hz > 2750000000) { + return HACKRF_ERROR_INVALID_PARAM; + } + + if ((path != RF_PATH_FILTER_BYPASS) && + (lo_freq_hz < 84375000 || lo_freq_hz > 5400000000)) { + return HACKRF_ERROR_INVALID_PARAM; + } + + if (path > 2) { + return HACKRF_ERROR_INVALID_PARAM; + } + + params.if_freq_hz = TO_LE(if_freq_hz); + params.lo_freq_hz = TO_LE(lo_freq_hz); + params.path = (uint8_t)path; + length = sizeof(struct set_freq_explicit_params); + + result = libusb_control_transfer( + device->usb_device, + LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, + HACKRF_VENDOR_REQUEST_SET_FREQ_EXPLICIT, + 0, + 0, + (unsigned char*)¶ms, + length, + 0 + ); + + if (result < length) + { + return HACKRF_ERROR_LIBUSB; + } else { + return HACKRF_SUCCESS; + } +} typedef struct { uint32_t freq_hz; @@ -983,34 +1035,6 @@ int ADDCALL hackrf_set_txvga_gain(hackrf_device* device, uint32_t value) } } -int ADDCALL hackrf_set_if_freq(hackrf_device* device, const uint32_t freq_mhz) -{ - int result; - - if(freq_mhz < 2300 || freq_mhz > 2700) - { - return HACKRF_ERROR_INVALID_PARAM; - } - - result = libusb_control_transfer( - device->usb_device, - LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, - HACKRF_VENDOR_REQUEST_SET_IF_FREQ, - 0, - freq_mhz, - NULL, - 0, - 0 - ); - - if( result != 0 ) - { - return HACKRF_ERROR_LIBUSB; - } else { - return HACKRF_SUCCESS; - } -} - int ADDCALL hackrf_set_antenna_enable(hackrf_device* device, const uint8_t value) { int result; @@ -1317,6 +1341,20 @@ const char* ADDCALL hackrf_board_id_name(enum hackrf_board_id board_id) } } +const char* ADDCALL hackrf_filter_path_name(const enum rf_path_filter path) +{ + switch(path) { + case RF_PATH_FILTER_BYPASS: + return "mixer bypass"; + case RF_PATH_FILTER_LOW_PASS: + return "low pass filter"; + case RF_PATH_FILTER_HIGH_PASS: + return "high pass filter"; + default: + return "invalid filter path"; + } +} + /* Return final bw round down and less than expected bw. */ uint32_t ADDCALL hackrf_compute_baseband_filter_bw_round_down_lt(const uint32_t bandwidth_hz) { diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 0fecce9b..130f33e9 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -69,6 +69,12 @@ enum hackrf_board_id { BOARD_ID_INVALID = 0xFF, }; +enum rf_path_filter { + RF_PATH_FILTER_BYPASS = 0, + RF_PATH_FILTER_LOW_PASS = 1, + RF_PATH_FILTER_HIGH_PASS = 2, +}; + typedef struct hackrf_device hackrf_device; typedef struct { @@ -130,9 +136,9 @@ extern ADDAPI int ADDCALL hackrf_board_id_read(hackrf_device* device, uint8_t* v extern ADDAPI int ADDCALL hackrf_version_string_read(hackrf_device* device, char* version, uint8_t length); extern ADDAPI int ADDCALL hackrf_set_freq(hackrf_device* device, const uint64_t freq_hz); - -/* range 2300-2700 Mhz */ -extern ADDAPI int ADDCALL hackrf_set_if_freq(hackrf_device* device, const uint32_t freq_mhz); +extern ADDAPI int ADDCALL hackrf_set_freq_explicit(hackrf_device* device, + const uint64_t if_freq_hz, const uint64_t lo_freq_hz, + const enum rf_path_filter path); /* currently 8-20Mhz - either as a fraction, i.e. freq 20000000hz divider 2 -> 10Mhz or as plain old 10000000hz (double) preferred rates are 8, 10, 12.5, 16, 20Mhz due to less jitter */ @@ -158,6 +164,7 @@ extern ADDAPI int ADDCALL hackrf_set_antenna_enable(hackrf_device* device, const 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); +extern ADDAPI const char* ADDCALL hackrf_filter_path_name(const enum rf_path_filter path); /* Compute nearest freq for bw filter (manual filter) */ extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw_round_down_lt(const uint32_t bandwidth_hz);