replaced set_freq_if() with set_freq_explicit() and implemented explicit tuning option in hackrf_transfer
This commit is contained in:
@ -37,9 +37,9 @@ typedef enum {
|
|||||||
void rf_path_set_direction(const rf_path_direction_t direction);
|
void rf_path_set_direction(const rf_path_direction_t direction);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RF_PATH_FILTER_BYPASS,
|
RF_PATH_FILTER_BYPASS = 0,
|
||||||
RF_PATH_FILTER_LOW_PASS,
|
RF_PATH_FILTER_LOW_PASS = 1,
|
||||||
RF_PATH_FILTER_HIGH_PASS,
|
RF_PATH_FILTER_HIGH_PASS = 2,
|
||||||
} rf_path_filter_t;
|
} rf_path_filter_t;
|
||||||
|
|
||||||
void rf_path_set_filter(const rf_path_filter_t filter);
|
void rf_path_set_filter(const rf_path_filter_t filter);
|
||||||
|
@ -25,8 +25,6 @@
|
|||||||
#include <rffc5071.h>
|
#include <rffc5071.h>
|
||||||
#include <max2837.h>
|
#include <max2837.h>
|
||||||
|
|
||||||
#include "rf_path.h"
|
|
||||||
|
|
||||||
#define FREQ_ONE_MHZ (1000*1000)
|
#define FREQ_ONE_MHZ (1000*1000)
|
||||||
|
|
||||||
#define MIN_LP_FREQ_MHZ (0)
|
#define MIN_LP_FREQ_MHZ (0)
|
||||||
@ -40,6 +38,9 @@
|
|||||||
#define MID2_HP_FREQ_MHZ (5100)
|
#define MID2_HP_FREQ_MHZ (5100)
|
||||||
#define MAX_HP_FREQ_MHZ (7250)
|
#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;
|
static uint32_t max2837_freq_nominal_hz=2560000000;
|
||||||
|
|
||||||
uint64_t freq_cache = 100000000;
|
uint64_t freq_cache = 100000000;
|
||||||
@ -54,7 +55,6 @@ bool set_freq(const uint64_t freq)
|
|||||||
uint32_t RFFC5071_freq_mhz;
|
uint32_t RFFC5071_freq_mhz;
|
||||||
uint32_t MAX2837_freq_hz;
|
uint32_t MAX2837_freq_hz;
|
||||||
uint64_t real_RFFC5071_freq_hz;
|
uint64_t real_RFFC5071_freq_hz;
|
||||||
uint32_t tmp_hz;
|
|
||||||
|
|
||||||
const uint32_t freq_mhz = freq / 1000000;
|
const uint32_t freq_mhz = freq / 1000000;
|
||||||
const uint32_t freq_hz = freq % 1000000;
|
const uint32_t freq_hz = freq % 1000000;
|
||||||
@ -105,11 +105,27 @@ bool set_freq(const uint64_t freq)
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
bool success = false;
|
const rf_path_filter_t path)
|
||||||
if( (freq_if_hz >= MIN_BYPASS_FREQ_MHZ) && (freq_if_hz <= MAX_BYPASS_FREQ_MHZ) ) {
|
{
|
||||||
max2837_freq_nominal_hz = freq_if_hz;
|
if ((if_freq_hz < ((uint64_t)MIN_BYPASS_FREQ_MHZ * FREQ_ONE_MHZ))
|
||||||
success = set_freq(freq_cache);
|
|| (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;
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,13 @@
|
|||||||
#ifndef __TUNING_H__
|
#ifndef __TUNING_H__
|
||||||
#define __TUNING_H__
|
#define __TUNING_H__
|
||||||
|
|
||||||
|
#include "rf_path.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
bool set_freq(const uint64_t freq);
|
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__*/
|
#endif/*__TUNING_H__*/
|
||||||
|
@ -125,12 +125,13 @@ static const usb_request_handler_fn vendor_request_handler[] = {
|
|||||||
usb_vendor_request_set_lna_gain,
|
usb_vendor_request_set_lna_gain,
|
||||||
usb_vendor_request_set_vga_gain,
|
usb_vendor_request_set_vga_gain,
|
||||||
usb_vendor_request_set_txvga_gain,
|
usb_vendor_request_set_txvga_gain,
|
||||||
usb_vendor_request_set_if_freq,
|
NULL, // was set_if_freq
|
||||||
#ifdef HACKRF_ONE
|
#ifdef HACKRF_ONE
|
||||||
usb_vendor_request_set_antenna_enable,
|
usb_vendor_request_set_antenna_enable,
|
||||||
#else
|
#else
|
||||||
NULL,
|
NULL,
|
||||||
#endif
|
#endif
|
||||||
|
usb_vendor_request_set_freq_explicit,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint32_t vendor_request_handler_count =
|
static const uint32_t vendor_request_handler_count =
|
||||||
|
@ -41,6 +41,14 @@ typedef struct {
|
|||||||
|
|
||||||
set_freq_params_t set_freq_params;
|
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 {
|
typedef struct {
|
||||||
uint32_t freq_hz;
|
uint32_t freq_hz;
|
||||||
uint32_t divider;
|
uint32_t divider;
|
||||||
@ -175,19 +183,6 @@ usb_request_status_t usb_vendor_request_set_txvga_gain(
|
|||||||
return USB_REQUEST_STATUS_OK;
|
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_request_status_t usb_vendor_request_set_antenna_enable(
|
||||||
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
|
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;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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_endpoint_t* const endpoint, const usb_transfer_stage_t stage);
|
||||||
usb_request_status_t usb_vendor_request_set_txvga_gain(
|
usb_request_status_t usb_vendor_request_set_txvga_gain(
|
||||||
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage);
|
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_request_status_t usb_vendor_request_set_antenna_enable(
|
||||||
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage);
|
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__*/
|
#endif/*__USB_API_TRANSCEIVER_H__*/
|
||||||
|
@ -86,6 +86,11 @@ int gettimeofday(struct timeval *tv, void* ignored)
|
|||||||
#define DEFAULT_FREQ_HZ (900000000ull) /* 900MHz */
|
#define DEFAULT_FREQ_HZ (900000000ull) /* 900MHz */
|
||||||
#define FREQ_MIN_HZ (0ull) /* 0 Hz */
|
#define FREQ_MIN_HZ (0ull) /* 0 Hz */
|
||||||
#define FREQ_MAX_HZ (7250000000ull) /* 7250MHz */
|
#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 */
|
#define DEFAULT_SAMPLE_RATE_HZ (10000000) /* 10MHz default sample rate */
|
||||||
|
|
||||||
@ -240,10 +245,19 @@ bool receive_wav = false;
|
|||||||
bool transmit = false;
|
bool transmit = false;
|
||||||
struct timeval time_start;
|
struct timeval time_start;
|
||||||
struct timeval t_start;
|
struct timeval t_start;
|
||||||
|
|
||||||
bool freq = false;
|
bool automatic_tuning = false;
|
||||||
uint64_t freq_hz;
|
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;
|
bool amp = false;
|
||||||
uint32_t amp_enable;
|
uint32_t amp_enable;
|
||||||
|
|
||||||
@ -326,13 +340,16 @@ static void usage() {
|
|||||||
printf("\t-t <filename> # Transmit data from file.\n");
|
printf("\t-t <filename> # Transmit data from file.\n");
|
||||||
printf("\t-w # Receive data into file with WAV header and automatic name.\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 # 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[-f freq_hz] # Frequency 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[-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[-p set_antenna] # Set antenna port power, 1=Enable, 0=Disable.\n");
|
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[-l gain_db] # Set lna gain, 0-40dB, 8dB steps\n");
|
printf("\t[-m image_reject] # Image rejection filter selection, 0=bypass, 1=low pass, 2=high pass.\n");
|
||||||
printf("\t[-i gain_db] # Set vga(if) gain, 0-62dB, 2dB steps\n");
|
printf("\t[-a amp_enable] # Amplifier 1=Enable, 0=Disable.\n");
|
||||||
printf("\t[-x gain_db] # Set TX vga gain, 0-47dB, 1dB steps\n");
|
printf("\t[-p antenna_enable] # Antenna port power, 1=Enable, 0=Disable.\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[-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[-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" );
|
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;
|
float time_diff;
|
||||||
unsigned int lna_gain=8, vga_gain=20, txvga_gain=0;
|
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;
|
result = HACKRF_SUCCESS;
|
||||||
switch( opt )
|
switch( opt )
|
||||||
@ -393,12 +410,27 @@ int main(int argc, char** argv) {
|
|||||||
transmit = true;
|
transmit = true;
|
||||||
path = optarg;
|
path = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
freq = true;
|
automatic_tuning = true;
|
||||||
result = parse_u64(optarg, &freq_hz);
|
result = parse_u64(optarg, &freq_hz);
|
||||||
break;
|
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':
|
case 'a':
|
||||||
amp = true;
|
amp = true;
|
||||||
result = parse_u32(optarg, &_enable);
|
result = parse_u32(optarg, &_enable);
|
||||||
@ -457,23 +489,74 @@ int main(int argc, char** argv) {
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( freq ) {
|
if (if_freq || lo_freq || image_reject) {
|
||||||
if( (freq_hz >= FREQ_MAX_HZ) || (freq_hz < FREQ_MIN_HZ) )
|
/* explicit tuning selected */
|
||||||
{
|
if (!if_freq) {
|
||||||
printf("argument error: set_freq_hz shall be between [%llu, %llu[.\n", FREQ_MIN_HZ, FREQ_MAX_HZ);
|
printf("argument error: if_freq_hz must be specified for explicit tuning.\n");
|
||||||
usage();
|
usage();
|
||||||
return EXIT_FAILURE;
|
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 */
|
/* Use default freq */
|
||||||
freq_hz = DEFAULT_FREQ_HZ;
|
freq_hz = DEFAULT_FREQ_HZ;
|
||||||
|
automatic_tuning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( amp ) {
|
if( amp ) {
|
||||||
if( amp_enable > 1 )
|
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();
|
usage();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -481,7 +564,7 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
if (antenna) {
|
if (antenna) {
|
||||||
if (antenna_enable > 1) {
|
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();
|
usage();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -645,12 +728,25 @@ int main(int argc, char** argv) {
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("call hackrf_set_freq(%lu Hz/%.03f MHz)\n", freq_hz, ((double)freq_hz/(double)FREQ_ONE_MHZ) );
|
if (automatic_tuning) {
|
||||||
result = hackrf_set_freq(device, freq_hz);
|
printf("call hackrf_set_freq(%lu Hz/%.03f MHz)\n", freq_hz, ((double)freq_hz/(double)FREQ_ONE_MHZ) );
|
||||||
if( result != HACKRF_SUCCESS ) {
|
result = hackrf_set_freq(device, freq_hz);
|
||||||
printf("hackrf_set_freq() failed: %s (%d)\n", hackrf_error_name(result), result);
|
if( result != HACKRF_SUCCESS ) {
|
||||||
usage();
|
printf("hackrf_set_freq() failed: %s (%d)\n", hackrf_error_name(result), result);
|
||||||
return EXIT_FAILURE;
|
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 ) {
|
if( amp ) {
|
||||||
|
@ -36,8 +36,10 @@ typedef int bool;
|
|||||||
|
|
||||||
#ifdef HACKRF_BIG_ENDIAN
|
#ifdef HACKRF_BIG_ENDIAN
|
||||||
#define TO_LE(x) __builtin_bswap32(x)
|
#define TO_LE(x) __builtin_bswap32(x)
|
||||||
|
#define TO_LE64(x) __builtin_bswap64(x)
|
||||||
#else
|
#else
|
||||||
#define TO_LE(x) x
|
#define TO_LE(x) x
|
||||||
|
#define TO_LE64(x) x
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: Factor this into a shared #include so that firmware can use
|
// 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_LNA_GAIN = 19,
|
||||||
HACKRF_VENDOR_REQUEST_SET_VGA_GAIN = 20,
|
HACKRF_VENDOR_REQUEST_SET_VGA_GAIN = 20,
|
||||||
HACKRF_VENDOR_REQUEST_SET_TXVGA_GAIN = 21,
|
HACKRF_VENDOR_REQUEST_SET_TXVGA_GAIN = 21,
|
||||||
HACKRF_VENDOR_REQUEST_SET_IF_FREQ = 22,
|
|
||||||
HACKRF_VENDOR_REQUEST_ANTENNA_ENABLE = 23,
|
HACKRF_VENDOR_REQUEST_ANTENNA_ENABLE = 23,
|
||||||
|
HACKRF_VENDOR_REQUEST_SET_FREQ_EXPLICIT = 24,
|
||||||
} hackrf_vendor_request;
|
} hackrf_vendor_request;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -724,7 +726,7 @@ int ADDCALL hackrf_version_string_read(hackrf_device* device, char* version,
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
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 */
|
uint32_t freq_hz; /* From 0 to 999999Hz */
|
||||||
/* Final Freq = freq_mhz+freq_hz */
|
/* Final Freq = freq_mhz+freq_hz */
|
||||||
} set_freq_params_t;
|
} 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 {
|
typedef struct {
|
||||||
uint32_t freq_hz;
|
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 ADDCALL hackrf_set_antenna_enable(hackrf_device* device, const uint8_t value)
|
||||||
{
|
{
|
||||||
int result;
|
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. */
|
/* 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)
|
uint32_t ADDCALL hackrf_compute_baseband_filter_bw_round_down_lt(const uint32_t bandwidth_hz)
|
||||||
{
|
{
|
||||||
|
@ -69,6 +69,12 @@ enum hackrf_board_id {
|
|||||||
BOARD_ID_INVALID = 0xFF,
|
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 hackrf_device hackrf_device;
|
||||||
|
|
||||||
typedef struct {
|
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_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);
|
extern ADDAPI int ADDCALL hackrf_set_freq(hackrf_device* device, const uint64_t freq_hz);
|
||||||
|
extern ADDAPI int ADDCALL hackrf_set_freq_explicit(hackrf_device* device,
|
||||||
/* range 2300-2700 Mhz */
|
const uint64_t if_freq_hz, const uint64_t lo_freq_hz,
|
||||||
extern ADDAPI int ADDCALL hackrf_set_if_freq(hackrf_device* device, const uint32_t freq_mhz);
|
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)
|
/* 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 */
|
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_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_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) */
|
/* 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);
|
extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw_round_down_lt(const uint32_t bandwidth_hz);
|
||||||
|
Reference in New Issue
Block a user