Compare commits
No commits in common. "antoinevg/radio-hackrf-transfer" and "main" have entirely different histories.
antoinevg/
...
main
16 changed files with 76 additions and 1167 deletions
|
|
@ -26,14 +26,6 @@
|
|||
|
||||
#include "ice40_spi.h"
|
||||
|
||||
/* Supported Bitstreams. */
|
||||
typedef enum {
|
||||
FPGA_BITSTREAM_STANDARD = 0,
|
||||
FPGA_BITSTREAM_HALFPREC = 1,
|
||||
FPGA_BITSTREAM_EXTPREC_RX = 2,
|
||||
FPGA_BITSTREAM_EXTPREC_TX = 3,
|
||||
} fpga_bitstream_index_t;
|
||||
|
||||
/* Up to 7 registers, each containing up to 8 bits of data */
|
||||
#define FPGA_NUM_REGS 7
|
||||
#define FPGA_DATA_REGS_MAX_VALUE 255
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ void radio_init(radio_t* const radio)
|
|||
radio->config[bank][reg] = RADIO_UNSET;
|
||||
}
|
||||
}
|
||||
radio->config_mode = RADIO_CONFIG_STANDARD;
|
||||
radio->config[RADIO_BANK_APPLIED][RADIO_OPMODE] = TRANSCEIVER_MODE_OFF;
|
||||
radio->config[RADIO_BANK_REQUESTED][RADIO_OPMODE] = TRANSCEIVER_MODE_OFF;
|
||||
radio->config[RADIO_BANK_IDLE][RADIO_OPMODE] = TRANSCEIVER_MODE_OFF;
|
||||
|
|
@ -61,7 +60,6 @@ void radio_init(radio_t* const radio)
|
|||
radio->config[RADIO_BANK_TX][RADIO_OPMODE] = TRANSCEIVER_MODE_TX;
|
||||
radio->config[RADIO_BANK_IDLE][RADIO_BIAS_TEE] = false;
|
||||
radio->regs_dirty = 0;
|
||||
radio->regs_locked = 0;
|
||||
}
|
||||
|
||||
static inline void mark_dirty(radio_t* const radio, radio_register_t reg)
|
||||
|
|
@ -69,11 +67,6 @@ static inline void mark_dirty(radio_t* const radio, radio_register_t reg)
|
|||
radio->regs_dirty |= (1 << reg);
|
||||
}
|
||||
|
||||
static inline bool check_locked(radio_t* const radio, radio_register_t reg)
|
||||
{
|
||||
return radio->regs_locked & (1 << reg);
|
||||
}
|
||||
|
||||
radio_error_t radio_reg_write(
|
||||
radio_t* const radio,
|
||||
const radio_register_bank_t bank,
|
||||
|
|
@ -84,10 +77,6 @@ radio_error_t radio_reg_write(
|
|||
return RADIO_ERR_INVALID_REGISTER;
|
||||
}
|
||||
|
||||
if (check_locked(radio, reg)) {
|
||||
return RADIO_ERR_LOCKED_REGISTER;
|
||||
}
|
||||
|
||||
switch (bank) {
|
||||
case RADIO_BANK_REQUESTED:
|
||||
mark_dirty(radio, reg);
|
||||
|
|
@ -118,20 +107,6 @@ uint64_t radio_reg_read(
|
|||
return radio->config[bank][reg];
|
||||
}
|
||||
|
||||
radio_error_t radio_reg_lock(
|
||||
radio_t* const radio,
|
||||
const radio_register_t reg,
|
||||
const bool locked)
|
||||
{
|
||||
if (reg > RADIO_NUM_REGS) {
|
||||
return RADIO_ERR_INVALID_REGISTER;
|
||||
}
|
||||
|
||||
radio->regs_locked = (radio->regs_locked & ~(1 << reg)) | (locked << reg);
|
||||
|
||||
return RADIO_OK;
|
||||
}
|
||||
|
||||
static uint32_t radio_update_direction(radio_t* const radio, uint64_t* bank)
|
||||
{
|
||||
const uint64_t requested = bank[RADIO_OPMODE];
|
||||
|
|
@ -1035,69 +1010,3 @@ void radio_switch_opmode(radio_t* const radio, const transceiver_mode_t mode)
|
|||
nvic_enable_irq(NVIC_USB0_IRQ);
|
||||
radio_update(radio);
|
||||
}
|
||||
|
||||
bool radio_set_config_mode(radio_t* const radio, const radio_config_mode_t mode)
|
||||
{
|
||||
// Check if the requested mode is supported.
|
||||
switch (mode) {
|
||||
case RADIO_CONFIG_STANDARD:
|
||||
// supported on all boards
|
||||
break;
|
||||
#ifdef IS_PRALINE
|
||||
case RADIO_CONFIG_HALF_PRECISION:
|
||||
case RADIO_CONFIG_EXT_PRECISION_RX:
|
||||
case RADIO_CONFIG_EXT_PRECISION_TX:
|
||||
// only supported on praline
|
||||
if (!IS_PRALINE) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't do anything if we're already in the requested mode.
|
||||
if (mode == radio->config_mode) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(IS_PRALINE) && !(defined(DFU_MODE) || defined(RAM_MODE))
|
||||
if (IS_PRALINE) {
|
||||
fpga_bitstream_index_t bitstream_index;
|
||||
switch (mode) {
|
||||
case RADIO_CONFIG_STANDARD:
|
||||
bitstream_index = FPGA_BITSTREAM_STANDARD;
|
||||
break;
|
||||
case RADIO_CONFIG_HALF_PRECISION:
|
||||
bitstream_index = FPGA_BITSTREAM_HALFPREC;
|
||||
break;
|
||||
case RADIO_CONFIG_EXT_PRECISION_RX:
|
||||
bitstream_index = FPGA_BITSTREAM_EXTPREC_RX;
|
||||
break;
|
||||
case RADIO_CONFIG_EXT_PRECISION_TX:
|
||||
bitstream_index = FPGA_BITSTREAM_EXTPREC_TX;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reset radio state.
|
||||
for (uint8_t reg = 0; reg < RADIO_NUM_REGS; reg++) {
|
||||
radio_reg_write(radio, RADIO_BANK_APPLIED, reg, RADIO_UNSET);
|
||||
radio_reg_write(radio, RADIO_BANK_REQUESTED, reg, RADIO_UNSET);
|
||||
}
|
||||
|
||||
// Load bitstream.
|
||||
extern struct fpga_loader_t fpga_loader;
|
||||
if (!fpga_image_load(&fpga_loader, bitstream_index)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Update radio config mode.
|
||||
radio->config_mode = mode;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ typedef enum {
|
|||
RADIO_ERR_INVALID_PARAM = -2,
|
||||
RADIO_ERR_INVALID_BANK = -3,
|
||||
RADIO_ERR_INVALID_REGISTER = -4,
|
||||
RADIO_ERR_LOCKED_REGISTER = -5,
|
||||
RADIO_ERR_UNSUPPORTED_OPERATION = -10,
|
||||
RADIO_ERR_UNIMPLEMENTED = -19,
|
||||
RADIO_ERR_OTHER = -9999,
|
||||
|
|
@ -42,12 +41,11 @@ typedef enum {
|
|||
|
||||
/* radio configuration modes */
|
||||
typedef enum {
|
||||
RADIO_CONFIG_STANDARD = 0,
|
||||
#ifdef IS_PRALINE
|
||||
RADIO_CONFIG_EXT_PRECISION_RX = 1,
|
||||
RADIO_CONFIG_EXT_PRECISION_TX = 2,
|
||||
RADIO_CONFIG_HALF_PRECISION = 3,
|
||||
#endif
|
||||
RADIO_CONFIG_LEGACY = 0,
|
||||
RADIO_CONFIG_STANDARD = 1,
|
||||
RADIO_CONFIG_EXT_PRECISION_RX = 2,
|
||||
RADIO_CONFIG_EXT_PRECISION_TX = 3,
|
||||
RADIO_CONFIG_HALF_PRECISION = 4,
|
||||
} radio_config_mode_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -233,7 +231,6 @@ typedef struct {
|
|||
radio_config_mode_t config_mode;
|
||||
uint64_t config[RADIO_NUM_BANKS][RADIO_NUM_REGS];
|
||||
volatile uint32_t regs_dirty;
|
||||
uint32_t regs_locked;
|
||||
update_fn update_cb;
|
||||
} radio_t;
|
||||
|
||||
|
|
@ -257,15 +254,6 @@ uint64_t radio_reg_read(
|
|||
const radio_register_bank_t bank,
|
||||
const radio_register_t reg);
|
||||
|
||||
/**
|
||||
* Lock a register. Prevents any future calls to `radio_reg_write`
|
||||
* from overwriting the current stored value of the register.
|
||||
*/
|
||||
radio_error_t radio_reg_lock(
|
||||
radio_t* const radio,
|
||||
const radio_register_t reg,
|
||||
const bool locked);
|
||||
|
||||
/**
|
||||
* Apply changes requested in RADIO_BANK_REQUESTED.
|
||||
* Return true if any changes were applied.
|
||||
|
|
@ -278,12 +266,6 @@ bool radio_update(radio_t* const radio);
|
|||
*/
|
||||
void radio_switch_opmode(radio_t* const radio, const transceiver_mode_t mode);
|
||||
|
||||
/**
|
||||
* Switch to a new configuration mode.
|
||||
* Return true if the mode was successfully switched.
|
||||
*/
|
||||
bool radio_set_config_mode(radio_t* const radio, const radio_config_mode_t mode);
|
||||
|
||||
/**
|
||||
* Driver instance.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ set(SRC_M4
|
|||
usb_api_spiflash.c
|
||||
usb_api_transceiver.c
|
||||
usb_api_operacake.c
|
||||
usb_api_radio.c
|
||||
usb_api_sweep.c
|
||||
usb_api_selftest.c
|
||||
usb_api_ui.c
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@
|
|||
#include "usb_api_board_info.h"
|
||||
#include "usb_api_m0_state.h"
|
||||
#include "usb_api_operacake.h"
|
||||
#include "usb_api_radio.h"
|
||||
#include "usb_api_register.h"
|
||||
#include "usb_api_selftest.h"
|
||||
#include "usb_api_spiflash.h"
|
||||
|
|
@ -183,13 +182,6 @@ static usb_request_handler_fn vendor_request_handler[] = {
|
|||
usb_vendor_request_write_radio_reg,
|
||||
usb_vendor_request_read_radio_reg,
|
||||
usb_vendor_request_get_buffer_size,
|
||||
usb_vendor_request_lock_radio_reg,
|
||||
usb_vendor_request_open,
|
||||
usb_vendor_request_close,
|
||||
usb_vendor_request_set_radio_mode,
|
||||
usb_vendor_request_set_radio_frequency,
|
||||
usb_vendor_request_set_radio_frequency_explicit,
|
||||
usb_vendor_request_set_radio_sample_rate,
|
||||
};
|
||||
|
||||
static const uint32_t vendor_request_handler_count =
|
||||
|
|
|
|||
|
|
@ -1,149 +0,0 @@
|
|||
/*
|
||||
* Copyright 2026 Great Scott Gadgets <info@greatscottgadgets.com>
|
||||
*
|
||||
* This file is part of HackRF.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <fixed_point.h>
|
||||
#include <radio.h>
|
||||
#include <usb_request.h>
|
||||
#include <usb_type.h>
|
||||
|
||||
#include "usb_queue.h"
|
||||
|
||||
usb_request_status_t usb_vendor_request_set_radio_mode(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage)
|
||||
{
|
||||
if (stage == USB_TRANSFER_STAGE_SETUP) {
|
||||
radio_config_mode_t mode = endpoint->setup.value;
|
||||
if (!radio_set_config_mode(&radio, mode)) {
|
||||
return USB_REQUEST_STATUS_STALL;
|
||||
}
|
||||
usb_transfer_schedule_ack(endpoint->in);
|
||||
}
|
||||
|
||||
return USB_REQUEST_STATUS_OK;
|
||||
}
|
||||
|
||||
usb_request_status_t usb_vendor_request_set_radio_frequency(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage)
|
||||
{
|
||||
static fp_40_24_t hz_param;
|
||||
|
||||
if (stage == USB_TRANSFER_STAGE_SETUP) {
|
||||
usb_transfer_schedule_block(
|
||||
endpoint->out,
|
||||
&hz_param,
|
||||
sizeof(fp_40_24_t),
|
||||
NULL,
|
||||
NULL);
|
||||
} else if (stage == USB_TRANSFER_STAGE_DATA) {
|
||||
radio_reg_write(
|
||||
&radio,
|
||||
RADIO_BANK_REQUESTED,
|
||||
RADIO_FREQUENCY_RF,
|
||||
hz_param);
|
||||
radio_reg_write(
|
||||
&radio,
|
||||
RADIO_BANK_REQUESTED,
|
||||
RADIO_FREQUENCY_IF,
|
||||
RADIO_UNSET);
|
||||
radio_reg_write(
|
||||
&radio,
|
||||
RADIO_BANK_REQUESTED,
|
||||
RADIO_FREQUENCY_LO,
|
||||
RADIO_UNSET);
|
||||
radio_reg_write(
|
||||
&radio,
|
||||
RADIO_BANK_REQUESTED,
|
||||
RADIO_IMAGE_REJECT,
|
||||
RADIO_UNSET);
|
||||
usb_transfer_schedule_ack(endpoint->in);
|
||||
}
|
||||
|
||||
return USB_REQUEST_STATUS_OK;
|
||||
}
|
||||
|
||||
usb_request_status_t usb_vendor_request_set_radio_frequency_explicit(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage)
|
||||
{
|
||||
static struct {
|
||||
fp_40_24_t if_freq_hz;
|
||||
fp_40_24_t lo_freq_hz;
|
||||
uint8_t path;
|
||||
} params;
|
||||
|
||||
if (stage == USB_TRANSFER_STAGE_SETUP) {
|
||||
usb_transfer_schedule_block(
|
||||
endpoint->out,
|
||||
¶ms,
|
||||
sizeof(params),
|
||||
NULL,
|
||||
NULL);
|
||||
} else if (stage == USB_TRANSFER_STAGE_DATA) {
|
||||
radio_reg_write(
|
||||
&radio,
|
||||
RADIO_BANK_REQUESTED,
|
||||
RADIO_FREQUENCY_IF,
|
||||
params.if_freq_hz);
|
||||
radio_reg_write(
|
||||
&radio,
|
||||
RADIO_BANK_REQUESTED,
|
||||
RADIO_FREQUENCY_LO,
|
||||
params.lo_freq_hz);
|
||||
radio_reg_write(
|
||||
&radio,
|
||||
RADIO_BANK_REQUESTED,
|
||||
RADIO_IMAGE_REJECT,
|
||||
params.path);
|
||||
usb_transfer_schedule_ack(endpoint->in);
|
||||
}
|
||||
|
||||
return USB_REQUEST_STATUS_OK;
|
||||
}
|
||||
|
||||
usb_request_status_t usb_vendor_request_set_radio_sample_rate(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage)
|
||||
{
|
||||
static fp_28_36_t sps_param;
|
||||
|
||||
if (stage == USB_TRANSFER_STAGE_SETUP) {
|
||||
usb_transfer_schedule_block(
|
||||
endpoint->out,
|
||||
&sps_param,
|
||||
sizeof(fp_28_36_t),
|
||||
NULL,
|
||||
NULL);
|
||||
} else if (stage == USB_TRANSFER_STAGE_DATA) {
|
||||
radio_reg_write(
|
||||
&radio,
|
||||
RADIO_BANK_REQUESTED,
|
||||
RADIO_SAMPLE_RATE,
|
||||
sps_param);
|
||||
usb_transfer_schedule_ack(endpoint->in);
|
||||
}
|
||||
|
||||
return USB_REQUEST_STATUS_OK;
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Copyright 2026 Great Scott Gadgets <info@greatscottgadgets.com>
|
||||
*
|
||||
* This file is part of HackRF.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <usb_request.h>
|
||||
#include <usb_type.h>
|
||||
|
||||
usb_request_status_t usb_vendor_request_set_radio_mode(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage);
|
||||
|
||||
usb_request_status_t usb_vendor_request_set_radio_frequency(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage);
|
||||
|
||||
usb_request_status_t usb_vendor_request_set_radio_frequency_explicit(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage);
|
||||
|
||||
usb_request_status_t usb_vendor_request_set_radio_sample_rate(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage);
|
||||
|
|
@ -416,20 +416,3 @@ usb_request_status_t usb_vendor_request_read_radio_reg(
|
|||
}
|
||||
return USB_REQUEST_STATUS_OK;
|
||||
}
|
||||
|
||||
usb_request_status_t usb_vendor_request_lock_radio_reg(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage)
|
||||
{
|
||||
if (stage == USB_TRANSFER_STAGE_SETUP) {
|
||||
uint8_t reg = endpoint->setup.index;
|
||||
bool locked = endpoint->setup.value != 0 ? true : false;
|
||||
if (reg >= RADIO_NUM_REGS) {
|
||||
return USB_REQUEST_STATUS_STALL;
|
||||
}
|
||||
radio_reg_lock(&radio, reg, locked);
|
||||
usb_transfer_schedule_ack(endpoint->in);
|
||||
}
|
||||
|
||||
return USB_REQUEST_STATUS_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,3 @@ usb_request_status_t usb_vendor_request_write_radio_reg(
|
|||
usb_request_status_t usb_vendor_request_read_radio_reg(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage);
|
||||
usb_request_status_t usb_vendor_request_lock_radio_reg(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage);
|
||||
|
|
|
|||
|
|
@ -486,42 +486,6 @@ usb_request_status_t usb_vendor_request_get_buffer_size(
|
|||
return USB_REQUEST_STATUS_OK;
|
||||
}
|
||||
|
||||
usb_request_status_t usb_vendor_request_open(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage)
|
||||
{
|
||||
uint16_t usb_api_version;
|
||||
radio_config_mode_t radio_config_mode;
|
||||
|
||||
if (stage == USB_TRANSFER_STAGE_SETUP) {
|
||||
usb_api_version = endpoint->setup.value;
|
||||
radio_config_mode = (radio_config_mode_t) endpoint->setup.index;
|
||||
|
||||
// TODO let device know we have a new libhackrf connection and its supported usb_api_version
|
||||
(void) usb_api_version;
|
||||
|
||||
// switch bitstreams and update radio mode
|
||||
if (!radio_set_config_mode(&radio, radio_config_mode)) {
|
||||
return USB_REQUEST_STATUS_STALL;
|
||||
}
|
||||
usb_transfer_schedule_ack(endpoint->in);
|
||||
}
|
||||
|
||||
return USB_REQUEST_STATUS_OK;
|
||||
}
|
||||
|
||||
usb_request_status_t usb_vendor_request_close(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage)
|
||||
{
|
||||
if (stage == USB_TRANSFER_STAGE_SETUP) {
|
||||
// TODO do nothing for now
|
||||
usb_transfer_schedule_ack(endpoint->in);
|
||||
}
|
||||
|
||||
return USB_REQUEST_STATUS_OK;
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
// Which GPDMA channel to use.
|
||||
|
|
|
|||
|
|
@ -80,12 +80,6 @@ usb_request_status_t usb_vendor_request_set_rx_overrun_limit(
|
|||
usb_request_status_t usb_vendor_request_get_buffer_size(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage);
|
||||
usb_request_status_t usb_vendor_request_open(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage);
|
||||
usb_request_status_t usb_vendor_request_close(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage);
|
||||
|
||||
void request_transceiver_mode(transceiver_mode_t mode);
|
||||
void transceiver_startup(transceiver_mode_t mode);
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#define USB_VENDOR_ID (0x1D50)
|
||||
|
||||
#define USB_API_VERSION (0x0114)
|
||||
#define USB_API_VERSION (0x0113)
|
||||
|
||||
#define USB_WORD(x) (x & 0xFF), ((x >> 8) & 0xFF)
|
||||
|
||||
|
|
|
|||
|
|
@ -545,30 +545,6 @@ int radio_write_register(
|
|||
return result;
|
||||
}
|
||||
|
||||
int radio_lock_register(
|
||||
hackrf_device* device,
|
||||
const uint16_t register_number,
|
||||
const bool register_locked)
|
||||
{
|
||||
int result = HACKRF_SUCCESS;
|
||||
result = hackrf_radio_lock_register(
|
||||
device,
|
||||
(uint8_t) register_number,
|
||||
register_locked);
|
||||
|
||||
if (result == HACKRF_SUCCESS) {
|
||||
printf("register [%2d] -> %s\n",
|
||||
register_number,
|
||||
register_locked ? "locked" : "unlocked");
|
||||
} else {
|
||||
printf("hackrf_radio_lock_register() failed: %s (%d)\n",
|
||||
hackrf_error_name(result),
|
||||
result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int read_register(
|
||||
hackrf_device* device,
|
||||
uint8_t part,
|
||||
|
|
@ -645,20 +621,6 @@ int write_register(
|
|||
return HACKRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
int lock_register(
|
||||
hackrf_device* device,
|
||||
uint8_t part,
|
||||
const uint16_t register_number,
|
||||
const bool register_locked)
|
||||
{
|
||||
switch (part) {
|
||||
case PART_RADIO:
|
||||
return radio_lock_register(device, register_number, register_locked);
|
||||
default:
|
||||
return HACKRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* mode_name(uint32_t mode)
|
||||
{
|
||||
const char* mode_names[] = {"IDLE", "WAIT", "RX", "TX_START", "TX_RUN"};
|
||||
|
|
@ -713,7 +675,6 @@ static void usage()
|
|||
printf("\t-n, --register <n>: set register number for read/write operations\n");
|
||||
printf("\t-r, --read: read register specified by last -n argument, or all registers\n");
|
||||
printf("\t-w, --write <v>: write register specified by last -n argument with value <v>\n");
|
||||
printf("\t-L, --lock <state>: lock register specified by last -n argument (0 for unlocked, 1 for locked)\n");
|
||||
printf("\t-c, --config: print SI5351C multisynth configuration information\n");
|
||||
printf("\t-d, --device <s>: specify a particular device by serial number\n");
|
||||
printf("\t-m, --max283x: target MAX283x\n");
|
||||
|
|
@ -748,7 +709,6 @@ static struct option long_options[] = {
|
|||
{"register", required_argument, 0, 'n'},
|
||||
{"write", required_argument, 0, 'w'},
|
||||
{"read", no_argument, 0, 'r'},
|
||||
{"lock", required_argument, 0, 'L'},
|
||||
{"device", required_argument, 0, 'd'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"max2837", no_argument, 0, 'm'},
|
||||
|
|
@ -780,12 +740,10 @@ int main(int argc, char** argv)
|
|||
int bank = -1;
|
||||
uint64_t register_number = REGISTER_INVALID;
|
||||
uint64_t register_value;
|
||||
uint64_t register_locked;
|
||||
hackrf_device* device = NULL;
|
||||
int option_index = 0;
|
||||
bool read = false;
|
||||
bool write = false;
|
||||
bool lock = false;
|
||||
bool dump_config = false;
|
||||
bool dump_state = false;
|
||||
uint8_t part = PART_NONE;
|
||||
|
|
@ -824,7 +782,7 @@ int main(int argc, char** argv)
|
|||
while ((opt = getopt_long(
|
||||
argc,
|
||||
argv,
|
||||
"b:n:rw:l:d:cmsfgi1:2:C:N:P:ST:R:h?u:l:ta:o",
|
||||
"b:n:rw:d:cmsfgi1:2:C:N:P:ST:R:h?u:l:ta:o",
|
||||
long_options,
|
||||
&option_index)) != EOF) {
|
||||
switch (opt) {
|
||||
|
|
@ -847,11 +805,6 @@ int main(int argc, char** argv)
|
|||
read = true;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
lock = true;
|
||||
result = parse_int(optarg, ®ister_locked);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
dump_config = true;
|
||||
break;
|
||||
|
|
@ -978,8 +931,8 @@ int main(int argc, char** argv)
|
|||
}
|
||||
}
|
||||
|
||||
if ((write && read) || (lock && write) || (lock && read)) {
|
||||
fprintf(stderr, "Read, write and lock options are mutually exclusive.\n");
|
||||
if (write && read) {
|
||||
fprintf(stderr, "Read and write options are mutually exclusive.\n");
|
||||
usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
|
@ -996,10 +949,6 @@ int main(int argc, char** argv)
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (lock && part != PART_RADIO) {
|
||||
fprintf(stderr, "Lock option is only valid for radio.\n");
|
||||
}
|
||||
|
||||
if ((bank > -1) && (part != PART_RADIO)) {
|
||||
fprintf(stderr, "Bank valid only for radio.\n");
|
||||
usage();
|
||||
|
|
@ -1010,11 +959,11 @@ int main(int argc, char** argv)
|
|||
bank = 0;
|
||||
}
|
||||
|
||||
if (!(write || read || lock || dump_config || dump_state || set_tx_limit ||
|
||||
if (!(write || read || dump_config || dump_state || set_tx_limit ||
|
||||
set_rx_limit || set_ui || set_leds || set_p1 || set_p2 || set_clkin ||
|
||||
set_narrowband || set_fpga_bitstream || read_selftest || test_rtc_osc ||
|
||||
read_adc)) {
|
||||
fprintf(stderr, "Specify read, write, lock, or config option.\n");
|
||||
fprintf(stderr, "Specify read, write, or config option.\n");
|
||||
usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
|
@ -1067,10 +1016,6 @@ int main(int argc, char** argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (lock) {
|
||||
result = lock_register(device, part, register_number, register_locked);
|
||||
}
|
||||
|
||||
if (dump_config) {
|
||||
si5351c_read_configuration(device);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@
|
|||
#include <windows.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
|
||||
#ifdef _WIN64
|
||||
typedef int64_t ssize_t;
|
||||
|
|
@ -195,38 +194,11 @@ typedef struct {
|
|||
|
||||
t_u64toa ascii_u64_data[4];
|
||||
|
||||
typedef struct {
|
||||
char data[U64TOA_MAX_DIGIT + 1];
|
||||
} t_fp64toa;
|
||||
|
||||
t_fp64toa ascii_fp64_data[4];
|
||||
|
||||
static float TimevalDiff(const struct timeval* a, const struct timeval* b)
|
||||
{
|
||||
return (a->tv_sec - b->tv_sec) + 1e-6f * (a->tv_usec - b->tv_usec);
|
||||
}
|
||||
|
||||
/**
|
||||
* (x * y) / z
|
||||
*/
|
||||
static uint64_t muldiv_fp64(uint64_t x, uint64_t y, uint64_t z)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
uint64_t hi;
|
||||
uint64_t lo;
|
||||
uint64_t remainder;
|
||||
lo = _umul128(x, y, &hi);
|
||||
return _udiv128(hi, lo, z, &remainder);
|
||||
#else
|
||||
return (uint64_t) (((__uint128_t) x * (__uint128_t) y) / z);
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint64_t double_to_fp(double input, uint8_t Qn)
|
||||
{
|
||||
return (uint64_t) round(input * (1ULL << Qn));
|
||||
}
|
||||
|
||||
int parse_u64(char* s, uint64_t* const value)
|
||||
{
|
||||
uint_fast8_t base = 10;
|
||||
|
|
@ -283,19 +255,18 @@ int parse_u32(char* s, uint32_t* const value)
|
|||
}
|
||||
}
|
||||
|
||||
int parse_double(char* optarg, double* value)
|
||||
/* Parse frequencies as doubles to take advantage of notation parsing */
|
||||
int parse_frequency_i64(char* optarg, char* endptr, int64_t* value)
|
||||
{
|
||||
char* endptr;
|
||||
*value = strtod(optarg, &endptr);
|
||||
*value = (int64_t) strtod(optarg, &endptr);
|
||||
if (optarg == endptr) {
|
||||
return HACKRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
return HACKRF_SUCCESS;
|
||||
}
|
||||
|
||||
int parse_frequency_u32(char* optarg, uint32_t* value)
|
||||
int parse_frequency_u32(char* optarg, char* endptr, uint32_t* value)
|
||||
{
|
||||
char* endptr;
|
||||
*value = (uint32_t) strtod(optarg, &endptr);
|
||||
if (optarg == endptr) {
|
||||
return HACKRF_ERROR_INVALID_PARAM;
|
||||
|
|
@ -303,78 +274,6 @@ int parse_frequency_u32(char* optarg, uint32_t* value)
|
|||
return HACKRF_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand a string in scientific notation to standard form.
|
||||
*/
|
||||
static int expand_notation(const char* src, char* dst)
|
||||
{
|
||||
// validate input
|
||||
char* endptr;
|
||||
strtod(src, &endptr);
|
||||
if (endptr == src || *endptr != '\0') {
|
||||
return HACKRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// tokenize input
|
||||
const char* token_sign = (*src == '-') ? src : NULL;
|
||||
const char* token_int = (*src == '+' || *src == '-') ? src + 1 : src;
|
||||
const char* token_dec = strchr(token_int, '.');
|
||||
const char* token_exp = strpbrk(token_int, "eE");
|
||||
const char* end_src = src + strlen(src);
|
||||
const char* end_int = token_dec ? token_dec : (token_exp ? token_exp : end_src);
|
||||
const char* end_dec = token_exp ? token_exp : end_src;
|
||||
|
||||
// calculate positions
|
||||
int len_int = end_int - token_int;
|
||||
int len_dec = token_dec ? (end_dec - token_dec - 1) : 0;
|
||||
int mag = token_exp ? atoi(token_exp + 1) : 0;
|
||||
int pos_dec = len_int + mag;
|
||||
int start = (pos_dec <= 0) ? (start = pos_dec - 1) : 0;
|
||||
int finish = (pos_dec > len_int + len_dec) ? pos_dec : (len_int + len_dec);
|
||||
|
||||
// expand input
|
||||
char* out = dst;
|
||||
if (token_sign) {
|
||||
*out++ = '-';
|
||||
}
|
||||
int i;
|
||||
for (i = start; i < finish; i++) {
|
||||
if (i == pos_dec) {
|
||||
*out++ = '.';
|
||||
}
|
||||
if (i < 0) {
|
||||
*out++ = '0';
|
||||
} else if (i < len_int) {
|
||||
*out++ = token_int[i];
|
||||
} else if (i < len_int + len_dec) {
|
||||
*out++ = token_dec[1 + i - len_int];
|
||||
} else {
|
||||
*out++ = '0';
|
||||
}
|
||||
}
|
||||
*out = '\0';
|
||||
|
||||
return HACKRF_SUCCESS;
|
||||
}
|
||||
|
||||
int parse_frequency_fp(char* optarg, fp_40_24_t* value)
|
||||
{
|
||||
char buf[64];
|
||||
if (expand_notation(optarg, buf) != HACKRF_SUCCESS) {
|
||||
return HACKRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
return hackrf_str_to_fp64(24, buf, value);
|
||||
}
|
||||
|
||||
int parse_sample_rate_fp(char* optarg, fp_28_36_t* value)
|
||||
{
|
||||
char buf[64];
|
||||
if (expand_notation(optarg, buf) != HACKRF_SUCCESS) {
|
||||
return HACKRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
return hackrf_str_to_fp64(36, buf, value);
|
||||
}
|
||||
|
||||
static char* stringrev(char* str)
|
||||
{
|
||||
char *p1, *p2;
|
||||
|
|
@ -420,51 +319,6 @@ char* u64toa(uint64_t val, t_u64toa* str)
|
|||
return res;
|
||||
}
|
||||
|
||||
char* fp64toa(uint8_t Qn, uint64_t value, t_fp64toa* str)
|
||||
{
|
||||
uint64_t mask = (1ULL << Qn) - 1;
|
||||
uint64_t m = value >> Qn;
|
||||
uint64_t n = (Qn == 0) ? 0 : value & mask;
|
||||
uint8_t precision = ceil((double) Qn * log10(2.0));
|
||||
|
||||
// format integer component
|
||||
char* p = str->data;
|
||||
p += sprintf(p, "%" PRIu64, m);
|
||||
|
||||
if (precision == 0 || n == 0) {
|
||||
*p = '\0';
|
||||
return str->data;
|
||||
}
|
||||
*p++ = '.';
|
||||
|
||||
// format fractional component
|
||||
uint8_t i;
|
||||
for (i = 0; i < precision; i++) {
|
||||
n *= 10;
|
||||
char c = '0' + (n >> Qn);
|
||||
*p++ = c;
|
||||
n &= mask;
|
||||
}
|
||||
|
||||
// trim trailing zeros
|
||||
while (p > str->data && p[-1] == '0') {
|
||||
--p;
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
return str->data;
|
||||
}
|
||||
|
||||
char* frequency_fp64toa(uint64_t value, t_fp64toa* str)
|
||||
{
|
||||
return fp64toa(24, value, str);
|
||||
}
|
||||
|
||||
char* sample_rate_fp64toa(uint64_t value, t_fp64toa* str)
|
||||
{
|
||||
return fp64toa(36, value, str);
|
||||
}
|
||||
|
||||
static volatile bool do_exit = false;
|
||||
static volatile bool interrupted = false;
|
||||
static volatile bool tx_complete = false;
|
||||
|
|
@ -497,13 +351,13 @@ struct timeval time_start;
|
|||
struct timeval t_start;
|
||||
|
||||
bool automatic_tuning = false;
|
||||
fp_40_24_t freq_fp_hz;
|
||||
int64_t freq_hz;
|
||||
|
||||
bool if_freq = false;
|
||||
fp_40_24_t if_freq_fp_hz;
|
||||
int64_t if_freq_hz;
|
||||
|
||||
bool lo_freq = false;
|
||||
fp_40_24_t lo_freq_fp_hz = FREQ_FP(DEFAULT_LO_HZ);
|
||||
int64_t lo_freq_hz = DEFAULT_LO_HZ;
|
||||
|
||||
bool image_reject = false;
|
||||
uint32_t image_reject_selection;
|
||||
|
|
@ -515,7 +369,7 @@ bool antenna = false;
|
|||
uint32_t antenna_enable;
|
||||
|
||||
bool sample_rate = false;
|
||||
fp_28_36_t sample_rate_fp_hz;
|
||||
uint32_t sample_rate_hz;
|
||||
|
||||
bool force_ranges = false;
|
||||
|
||||
|
|
@ -531,7 +385,7 @@ uint32_t baseband_filter_bw_hz = 0;
|
|||
bool repeat = false;
|
||||
|
||||
bool crystal_correct = false;
|
||||
double crystal_correct_ppm;
|
||||
uint32_t crystal_correct_ppm;
|
||||
|
||||
int requested_mode_count = 0;
|
||||
|
||||
|
|
@ -924,17 +778,17 @@ int main(int argc, char** argv)
|
|||
break;
|
||||
|
||||
case 'f':
|
||||
result = parse_frequency_fp(optarg, &freq_fp_hz);
|
||||
result = parse_frequency_i64(optarg, endptr, &freq_hz);
|
||||
automatic_tuning = true;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
result = parse_frequency_fp(optarg, &if_freq_fp_hz);
|
||||
result = parse_frequency_i64(optarg, endptr, &if_freq_hz);
|
||||
if_freq = true;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
result = parse_frequency_fp(optarg, &lo_freq_fp_hz);
|
||||
result = parse_frequency_i64(optarg, endptr, &lo_freq_hz);
|
||||
lo_freq = true;
|
||||
break;
|
||||
|
||||
|
|
@ -966,7 +820,7 @@ int main(int argc, char** argv)
|
|||
break;
|
||||
|
||||
case 's':
|
||||
result = parse_sample_rate_fp(optarg, &sample_rate_fp_hz);
|
||||
result = parse_frequency_u32(optarg, endptr, &sample_rate_hz);
|
||||
sample_rate = true;
|
||||
break;
|
||||
|
||||
|
|
@ -985,7 +839,10 @@ int main(int argc, char** argv)
|
|||
break;
|
||||
|
||||
case 'b':
|
||||
result = parse_frequency_u32(optarg, &baseband_filter_bw_hz);
|
||||
result = parse_frequency_u32(
|
||||
optarg,
|
||||
endptr,
|
||||
&baseband_filter_bw_hz);
|
||||
baseband_filter_bw = true;
|
||||
break;
|
||||
|
||||
|
|
@ -1001,7 +858,7 @@ int main(int argc, char** argv)
|
|||
|
||||
case 'C':
|
||||
crystal_correct = true;
|
||||
result = parse_double(optarg, &crystal_correct_ppm);
|
||||
result = parse_u32(optarg, &crystal_correct_ppm);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
|
|
@ -1062,8 +919,7 @@ int main(int argc, char** argv)
|
|||
usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (((FP_FREQ(if_freq_fp_hz) > IF_MAX_HZ) ||
|
||||
(FP_FREQ(if_freq_fp_hz) < IF_MIN_HZ)) &&
|
||||
if (((if_freq_hz > IF_MAX_HZ) || (if_freq_hz < IF_MIN_HZ)) &&
|
||||
!force_ranges) {
|
||||
fprintf(stderr,
|
||||
"argument error: if_freq_hz should be between %s and %s.\n",
|
||||
|
|
@ -1072,8 +928,7 @@ int main(int argc, char** argv)
|
|||
usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if ((FP_FREQ(if_freq_fp_hz) > IF_ABS_MAX_HZ) ||
|
||||
(FP_FREQ(if_freq_fp_hz) < IF_ABS_MIN_HZ)) {
|
||||
if ((if_freq_hz > IF_ABS_MAX_HZ) || (if_freq_hz < IF_ABS_MIN_HZ)) {
|
||||
fprintf(stderr,
|
||||
"argument error: if_freq_hz must be between %s and %s.\n",
|
||||
u64toa(IF_ABS_MIN_HZ, &ascii_u64_data[0]),
|
||||
|
|
@ -1081,8 +936,7 @@ int main(int argc, char** argv)
|
|||
usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if ((FP_FREQ(lo_freq_fp_hz) > LO_MAX_HZ) ||
|
||||
(FP_FREQ(lo_freq_fp_hz) < LO_MIN_HZ)) {
|
||||
if ((lo_freq_hz > LO_MAX_HZ) || (lo_freq_hz < LO_MIN_HZ)) {
|
||||
fprintf(stderr,
|
||||
"argument error: lo_freq_hz shall be between %s and %s.\n",
|
||||
u64toa(LO_MIN_HZ, &ascii_u64_data[0]),
|
||||
|
|
@ -1103,27 +957,24 @@ int main(int argc, char** argv)
|
|||
}
|
||||
switch (image_reject_selection) {
|
||||
case RF_PATH_FILTER_BYPASS:
|
||||
freq_fp_hz = if_freq_fp_hz;
|
||||
freq_hz = if_freq_hz;
|
||||
break;
|
||||
case RF_PATH_FILTER_LOW_PASS:
|
||||
freq_fp_hz = (if_freq_fp_hz > lo_freq_fp_hz) ?
|
||||
if_freq_fp_hz - lo_freq_fp_hz :
|
||||
lo_freq_fp_hz - if_freq_fp_hz;
|
||||
freq_hz = (int64_t) labs((long int) (if_freq_hz - lo_freq_hz));
|
||||
break;
|
||||
case RF_PATH_FILTER_HIGH_PASS:
|
||||
freq_fp_hz = if_freq_fp_hz + lo_freq_fp_hz;
|
||||
freq_hz = if_freq_hz + lo_freq_hz;
|
||||
break;
|
||||
default:
|
||||
freq_fp_hz = FREQ_FP(DEFAULT_FREQ_HZ);
|
||||
freq_hz = DEFAULT_FREQ_HZ;
|
||||
break;
|
||||
}
|
||||
fprintf(stderr,
|
||||
"explicit tuning specified for %s Hz.\n",
|
||||
frequency_fp64toa(freq_fp_hz, &ascii_fp64_data[0]));
|
||||
u64toa(freq_hz, &ascii_u64_data[0]));
|
||||
|
||||
} else if (automatic_tuning) {
|
||||
if (((FP_FREQ(freq_fp_hz) > FREQ_MAX_HZ) ||
|
||||
(FP_FREQ(freq_fp_hz) < FREQ_MIN_HZ)) &&
|
||||
if (((freq_hz > FREQ_MAX_HZ) || (freq_hz < FREQ_MIN_HZ)) &&
|
||||
!force_ranges) {
|
||||
fprintf(stderr,
|
||||
"argument error: freq_hz should be between %s and %s.\n",
|
||||
|
|
@ -1132,7 +983,7 @@ int main(int argc, char** argv)
|
|||
usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (FP_FREQ(freq_fp_hz) > FREQ_ABS_MAX_HZ) {
|
||||
if (freq_hz > FREQ_ABS_MAX_HZ) {
|
||||
fprintf(stderr,
|
||||
"argument error: freq_hz must be between %s and %s.\n",
|
||||
u64toa(FREQ_ABS_MIN_HZ, &ascii_u64_data[0]),
|
||||
|
|
@ -1142,7 +993,7 @@ int main(int argc, char** argv)
|
|||
}
|
||||
} else {
|
||||
/* Use default freq */
|
||||
freq_fp_hz = FREQ_FP(DEFAULT_FREQ_HZ);
|
||||
freq_hz = DEFAULT_FREQ_HZ;
|
||||
automatic_tuning = true;
|
||||
}
|
||||
|
||||
|
|
@ -1164,10 +1015,7 @@ int main(int argc, char** argv)
|
|||
}
|
||||
|
||||
if (sample_rate) {
|
||||
fprintf(stderr,
|
||||
"Setting sample rate to: %s Hz\n",
|
||||
sample_rate_fp64toa(sample_rate_fp_hz, &ascii_fp64_data[0]));
|
||||
if (FP_SR(sample_rate_fp_hz) > SAMPLE_RATE_MAX_HZ && !force_ranges) {
|
||||
if (sample_rate_hz > SAMPLE_RATE_MAX_HZ && !force_ranges) {
|
||||
fprintf(stderr,
|
||||
"argument error: sample_rate_hz should be less than or equal to %u Hz/%.03f MHz\n",
|
||||
SAMPLE_RATE_MAX_HZ,
|
||||
|
|
@ -1175,7 +1023,7 @@ int main(int argc, char** argv)
|
|||
usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (FP_SR(sample_rate_fp_hz) < SAMPLE_RATE_MIN_HZ && !force_ranges) {
|
||||
if (sample_rate_hz < SAMPLE_RATE_MIN_HZ && !force_ranges) {
|
||||
fprintf(stderr,
|
||||
"argument error: sample_rate_hz should be greater than or equal to %u Hz/%.03f MHz\n",
|
||||
SAMPLE_RATE_MIN_HZ,
|
||||
|
|
@ -1184,7 +1032,7 @@ int main(int argc, char** argv)
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
} else {
|
||||
sample_rate_fp_hz = SR_FP(DEFAULT_SAMPLE_RATE_HZ);
|
||||
sample_rate_hz = DEFAULT_SAMPLE_RATE_HZ;
|
||||
}
|
||||
|
||||
if (baseband_filter_bw) {
|
||||
|
|
@ -1252,7 +1100,7 @@ int main(int argc, char** argv)
|
|||
PATH_FILE_MAX_LEN,
|
||||
"HackRF_%sZ_%ukHz_IQ.wav",
|
||||
date_time,
|
||||
(uint32_t) (FP_FREQ(freq_fp_hz) / (1000ull)));
|
||||
(uint32_t) (freq_hz / (1000ull)));
|
||||
path = path_file;
|
||||
fprintf(stderr, "Receive wav file: %s\n", path);
|
||||
}
|
||||
|
|
@ -1268,14 +1116,9 @@ int main(int argc, char** argv)
|
|||
|
||||
// Change the freq and sample rate to correct the crystal clock error.
|
||||
if (crystal_correct) {
|
||||
sample_rate_fp_hz = (fp_28_36_t) muldiv_fp64(
|
||||
sample_rate_fp_hz,
|
||||
(fp_28_36_t) double_to_fp(1000000.0 - crystal_correct_ppm, 36),
|
||||
(fp_28_36_t) SR_FP(1000000));
|
||||
freq_fp_hz = (fp_40_24_t) muldiv_fp64(
|
||||
freq_fp_hz,
|
||||
(fp_40_24_t) double_to_fp(1000000.0 - crystal_correct_ppm, 24),
|
||||
(fp_40_24_t) FREQ_FP(1000000));
|
||||
sample_rate_hz =
|
||||
(uint32_t) ((double) sample_rate_hz * (1000000 - crystal_correct_ppm) / 1000000 + 0.5);
|
||||
freq_hz = freq_hz * (1000000 - crystal_correct_ppm) / 1000000;
|
||||
}
|
||||
|
||||
result = hackrf_init();
|
||||
|
|
@ -1349,13 +1192,13 @@ int main(int argc, char** argv)
|
|||
#endif
|
||||
|
||||
fprintf(stderr,
|
||||
"call hackrf_radio_set_sample_rate(%s Hz/%.03f MHz)\n",
|
||||
sample_rate_fp64toa(sample_rate_fp_hz, &ascii_fp64_data[0]),
|
||||
((float) FP_SR(sample_rate_fp_hz) / (float) FREQ_ONE_MHZ));
|
||||
result = hackrf_radio_set_sample_rate(device, sample_rate_fp_hz);
|
||||
"call hackrf_set_sample_rate(%u Hz/%.03f MHz)\n",
|
||||
sample_rate_hz,
|
||||
((float) sample_rate_hz / (float) FREQ_ONE_MHZ));
|
||||
result = hackrf_set_sample_rate(device, sample_rate_hz);
|
||||
if (result != HACKRF_SUCCESS) {
|
||||
fprintf(stderr,
|
||||
"hackrf_radio_set_sample_rate() failed: %s (%d)\n",
|
||||
"hackrf_set_sample_rate() failed: %s (%d)\n",
|
||||
hackrf_error_name(result),
|
||||
result);
|
||||
usage();
|
||||
|
|
@ -1403,13 +1246,13 @@ int main(int argc, char** argv)
|
|||
|
||||
if (automatic_tuning) {
|
||||
fprintf(stderr,
|
||||
"call hackrf_radio_set_frequency(%s Hz/%.03f MHz)\n",
|
||||
frequency_fp64toa(freq_fp_hz, &ascii_fp64_data[0]),
|
||||
((float) FP_FREQ(freq_fp_hz) / (float) FREQ_ONE_MHZ));
|
||||
result = hackrf_radio_set_frequency(device, freq_fp_hz);
|
||||
"call hackrf_set_freq(%s Hz/%.03f MHz)\n",
|
||||
u64toa(freq_hz, &ascii_u64_data[0]),
|
||||
((double) freq_hz / (double) FREQ_ONE_MHZ));
|
||||
result = hackrf_set_freq(device, freq_hz);
|
||||
if (result != HACKRF_SUCCESS) {
|
||||
fprintf(stderr,
|
||||
"hackrf_radio_set_frequency() failed: %s (%d)\n",
|
||||
"hackrf_set_freq() failed: %s (%d)\n",
|
||||
hackrf_error_name(result),
|
||||
result);
|
||||
usage();
|
||||
|
|
@ -1418,13 +1261,13 @@ int main(int argc, char** argv)
|
|||
} else {
|
||||
fprintf(stderr,
|
||||
"call hackrf_set_freq_explicit() with %s Hz IF, %s Hz LO, %s\n",
|
||||
frequency_fp64toa(if_freq_fp_hz, &ascii_fp64_data[0]),
|
||||
frequency_fp64toa(lo_freq_fp_hz, &ascii_fp64_data[0]),
|
||||
u64toa(if_freq_hz, &ascii_u64_data[0]),
|
||||
u64toa(lo_freq_hz, &ascii_u64_data[1]),
|
||||
hackrf_filter_path_name(image_reject_selection));
|
||||
result = hackrf_radio_set_frequency_explicit(
|
||||
result = hackrf_set_freq_explicit(
|
||||
device,
|
||||
if_freq_fp_hz,
|
||||
lo_freq_fp_hz,
|
||||
if_freq_hz,
|
||||
lo_freq_hz,
|
||||
image_reject_selection);
|
||||
if (result != HACKRF_SUCCESS) {
|
||||
fprintf(stderr,
|
||||
|
|
@ -1689,8 +1532,7 @@ int main(int argc, char** argv)
|
|||
file_pos = ftell(file);
|
||||
/* Update Wav Header */
|
||||
wave_file_hdr.hdr.size = file_pos - 8;
|
||||
wave_file_hdr.fmt_chunk.dwSamplesPerSec =
|
||||
FP_SR(sample_rate_fp_hz);
|
||||
wave_file_hdr.fmt_chunk.dwSamplesPerSec = sample_rate_hz;
|
||||
wave_file_hdr.fmt_chunk.dwAvgBytesPerSec =
|
||||
wave_file_hdr.fmt_chunk.dwSamplesPerSec * 2;
|
||||
wave_file_hdr.data_chunk.chunkSize =
|
||||
|
|
|
|||
|
|
@ -121,13 +121,6 @@ typedef enum {
|
|||
HACKRF_VENDOR_REQUEST_RADIO_WRITE_REG = 59,
|
||||
HACKRF_VENDOR_REQUEST_RADIO_READ_REG = 60,
|
||||
HACKRF_VENDOR_REQUEST_GET_BUFFER_SIZE = 61,
|
||||
HACKRF_VENDOR_REQUEST_RADIO_LOCK_REG = 62,
|
||||
HACKRF_VENDOR_REQUEST_OPEN = 63,
|
||||
HACKRF_VENDOR_REQUEST_CLOSE = 64,
|
||||
HACKRF_VENDOR_REQUEST_RADIO_SET_MODE = 65,
|
||||
HACKRF_VENDOR_REQUEST_RADIO_SET_FREQUENCY = 66,
|
||||
HACKRF_VENDOR_REQUEST_RADIO_SET_FREQUENCY_EXPLICIT = 67,
|
||||
HACKRF_VENDOR_REQUEST_RADIO_SET_SAMPLE_RATE = 68,
|
||||
} hackrf_vendor_request;
|
||||
|
||||
#define USB_CONFIG_STANDARD 0x1
|
||||
|
|
@ -205,8 +198,6 @@ static const max2837_ft_t max2837_ft[] = {
|
|||
if (device->usb_api_version < version) \
|
||||
return HACKRF_ERROR_USB_API_VERSION;
|
||||
|
||||
#define USB_API_REQUIRED_OR(device, version) if (device->usb_api_version < version)
|
||||
|
||||
static const uint16_t hackrf_usb_vid = 0x1d50;
|
||||
static const uint16_t hackrf_jawbreaker_usb_pid = 0x604b;
|
||||
static const uint16_t hackrf_one_usb_pid = 0x6089;
|
||||
|
|
@ -723,10 +714,7 @@ libusb_device_handle* hackrf_open_usb(const char* const desired_serial_number)
|
|||
return usb_device;
|
||||
}
|
||||
|
||||
static int hackrf_open_setup(
|
||||
enum radio_config_mode mode,
|
||||
libusb_device_handle* usb_device,
|
||||
hackrf_device** device)
|
||||
static int hackrf_open_setup(libusb_device_handle* usb_device, hackrf_device** device)
|
||||
{
|
||||
int result;
|
||||
hackrf_device* lib_device;
|
||||
|
|
@ -808,24 +796,6 @@ static int hackrf_open_setup(
|
|||
lib_device->buffer_size = 32768;
|
||||
}
|
||||
|
||||
if (lib_device->usb_api_version >= 0x0114) {
|
||||
// Send supported usb api version and requested configuration mode to device.
|
||||
result = libusb_control_transfer(
|
||||
lib_device->usb_device,
|
||||
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_RECIPIENT_DEVICE,
|
||||
HACKRF_VENDOR_REQUEST_OPEN,
|
||||
lib_device->usb_api_version,
|
||||
(uint16_t) mode,
|
||||
NULL,
|
||||
0,
|
||||
DEFAULT_REQUEST_TIMEOUT);
|
||||
if (result != 0) {
|
||||
last_libusb_error = result;
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
}
|
||||
|
||||
result = pthread_mutex_init(&lib_device->transfer_lock, NULL);
|
||||
if (result != 0) {
|
||||
free(lib_device);
|
||||
|
|
@ -864,7 +834,7 @@ static int hackrf_open_setup(
|
|||
return HACKRF_SUCCESS;
|
||||
}
|
||||
|
||||
int ADDCALL hackrf_open_mode(const enum radio_config_mode mode, hackrf_device** device)
|
||||
int ADDCALL hackrf_open(hackrf_device** device)
|
||||
{
|
||||
libusb_device_handle* usb_device;
|
||||
|
||||
|
|
@ -895,18 +865,17 @@ int ADDCALL hackrf_open_mode(const enum radio_config_mode mode, hackrf_device**
|
|||
return HACKRF_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
return hackrf_open_setup(mode, usb_device, device);
|
||||
return hackrf_open_setup(usb_device, device);
|
||||
}
|
||||
|
||||
int ADDCALL hackrf_open_mode_by_serial(
|
||||
const enum radio_config_mode mode,
|
||||
int ADDCALL hackrf_open_by_serial(
|
||||
const char* const desired_serial_number,
|
||||
hackrf_device** device)
|
||||
{
|
||||
libusb_device_handle* usb_device;
|
||||
|
||||
if (desired_serial_number == NULL) {
|
||||
return hackrf_open_mode(mode, device);
|
||||
return hackrf_open(device);
|
||||
}
|
||||
|
||||
if (device == NULL) {
|
||||
|
|
@ -919,11 +888,10 @@ int ADDCALL hackrf_open_mode_by_serial(
|
|||
return HACKRF_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
return hackrf_open_setup(mode, usb_device, device);
|
||||
return hackrf_open_setup(usb_device, device);
|
||||
}
|
||||
|
||||
int ADDCALL hackrf_device_list_open_mode(
|
||||
const enum radio_config_mode mode,
|
||||
int ADDCALL hackrf_device_list_open(
|
||||
hackrf_device_list_t* list,
|
||||
int idx,
|
||||
hackrf_device** device)
|
||||
|
|
@ -944,30 +912,7 @@ int ADDCALL hackrf_device_list_open_mode(
|
|||
return HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
|
||||
return hackrf_open_setup(mode, usb_device, device);
|
||||
}
|
||||
|
||||
int ADDCALL hackrf_open(hackrf_device** device)
|
||||
{
|
||||
return hackrf_open_mode(RADIO_CONFIG_STANDARD, device);
|
||||
}
|
||||
|
||||
int ADDCALL hackrf_open_by_serial(
|
||||
const char* const desired_serial_number,
|
||||
hackrf_device** device)
|
||||
{
|
||||
return hackrf_open_mode_by_serial(
|
||||
RADIO_CONFIG_STANDARD,
|
||||
desired_serial_number,
|
||||
device);
|
||||
}
|
||||
|
||||
int ADDCALL hackrf_device_list_open(
|
||||
hackrf_device_list_t* list,
|
||||
int idx,
|
||||
hackrf_device** device)
|
||||
{
|
||||
return hackrf_device_list_open_mode(RADIO_CONFIG_STANDARD, list, idx, device);
|
||||
return hackrf_open_setup(usb_device, device);
|
||||
}
|
||||
|
||||
int ADDCALL hackrf_device_list_bus_sharing(hackrf_device_list_t* list, int idx)
|
||||
|
|
@ -2498,11 +2443,10 @@ int ADDCALL hackrf_stop_tx(hackrf_device* device)
|
|||
|
||||
int ADDCALL hackrf_close(hackrf_device* device)
|
||||
{
|
||||
int result1, result2, result3;
|
||||
int result1, result2;
|
||||
|
||||
result1 = HACKRF_SUCCESS;
|
||||
result2 = HACKRF_SUCCESS;
|
||||
result3 = HACKRF_SUCCESS;
|
||||
|
||||
if (device != NULL) {
|
||||
result1 = hackrf_stop_cmd(device);
|
||||
|
|
@ -2512,27 +2456,6 @@ int ADDCALL hackrf_close(hackrf_device* device)
|
|||
* also cancel any pending transmit/receive transfers.
|
||||
*/
|
||||
result2 = kill_transfer_thread(device);
|
||||
|
||||
if (device->usb_api_version >= 0x0114) {
|
||||
/*
|
||||
* Let the device know it's been closed.
|
||||
*/
|
||||
result3 = libusb_control_transfer(
|
||||
device->usb_device,
|
||||
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_RECIPIENT_DEVICE,
|
||||
HACKRF_VENDOR_REQUEST_CLOSE,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
DEFAULT_REQUEST_TIMEOUT);
|
||||
if (result3 != 0) {
|
||||
last_libusb_error = result3;
|
||||
result3 = HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
}
|
||||
|
||||
if (device->usb_device != NULL) {
|
||||
libusb_release_interface(device->usb_device, 0);
|
||||
libusb_close(device->usb_device);
|
||||
|
|
@ -2551,12 +2474,7 @@ int ADDCALL hackrf_close(hackrf_device* device)
|
|||
if (result2 != HACKRF_SUCCESS) {
|
||||
return result2;
|
||||
}
|
||||
|
||||
if (result1 != HACKRF_SUCCESS) {
|
||||
return result1;
|
||||
}
|
||||
|
||||
return result3;
|
||||
return result1;
|
||||
}
|
||||
|
||||
const char* ADDCALL hackrf_error_name(enum hackrf_error errcode)
|
||||
|
|
@ -3657,234 +3575,6 @@ int ADDCALL hackrf_radio_write_register(
|
|||
}
|
||||
}
|
||||
|
||||
int ADDCALL hackrf_radio_lock_register(
|
||||
hackrf_device* device,
|
||||
const uint8_t register_number,
|
||||
const bool register_locked)
|
||||
{
|
||||
USB_API_REQUIRED(device, 0x0114);
|
||||
int result;
|
||||
|
||||
result = libusb_control_transfer(
|
||||
device->usb_device,
|
||||
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_RECIPIENT_DEVICE,
|
||||
HACKRF_VENDOR_REQUEST_RADIO_LOCK_REG,
|
||||
register_locked,
|
||||
register_number,
|
||||
NULL,
|
||||
0,
|
||||
DEFAULT_REQUEST_TIMEOUT);
|
||||
|
||||
if (result != 0) {
|
||||
last_libusb_error = result;
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
|
||||
return HACKRF_SUCCESS;
|
||||
}
|
||||
|
||||
int ADDCALL hackrf_radio_set_mode(hackrf_device* device, const enum radio_config_mode mode)
|
||||
{
|
||||
USB_API_REQUIRED(device, 0x0114);
|
||||
int result;
|
||||
|
||||
result = libusb_control_transfer(
|
||||
device->usb_device,
|
||||
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_RECIPIENT_DEVICE,
|
||||
HACKRF_VENDOR_REQUEST_RADIO_SET_MODE,
|
||||
mode,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
DEFAULT_REQUEST_TIMEOUT);
|
||||
|
||||
if (result != 0) {
|
||||
last_libusb_error = result;
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
|
||||
return HACKRF_SUCCESS;
|
||||
}
|
||||
|
||||
int ADDCALL hackrf_str_to_fp64(const uint8_t Qn, const char* str, uint64_t* const value)
|
||||
{
|
||||
uint64_t m = 0;
|
||||
uint64_t n = 0;
|
||||
uint64_t div = 1;
|
||||
uint64_t div_max = ceil((double) Qn * log10(2.0)) * 10;
|
||||
|
||||
// validate input
|
||||
char* endptr;
|
||||
strtod(str, &endptr);
|
||||
if (endptr == str || *endptr != '\0') {
|
||||
return HACKRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// parse sign
|
||||
bool negative = false;
|
||||
if (*str == '-' || *str == '+') {
|
||||
negative = (*str == '-');
|
||||
str++;
|
||||
}
|
||||
|
||||
// parse integer component
|
||||
for (; (*str >= '0') && (*str <= '9'); str++) {
|
||||
m = (m * 10) + (*str - '0');
|
||||
}
|
||||
*value = (m << Qn) * (negative ? -1 : 1);
|
||||
|
||||
if (*str != '.') {
|
||||
return HACKRF_SUCCESS;
|
||||
}
|
||||
str++;
|
||||
|
||||
// parse fractional component
|
||||
for (; (*str >= '0') && (*str <= '9') && (div < div_max); str++) {
|
||||
n = (n * 10) + (*str - '0');
|
||||
div *= 10;
|
||||
}
|
||||
|
||||
if (div == 1) {
|
||||
return HACKRF_SUCCESS;
|
||||
}
|
||||
|
||||
*value += ((n << Qn) + (div / 2)) / div;
|
||||
|
||||
return HACKRF_SUCCESS;
|
||||
}
|
||||
|
||||
int ADDCALL hackrf_radio_set_frequency(hackrf_device* device, const fp_40_24_t freq_hz)
|
||||
{
|
||||
USB_API_REQUIRED_OR(device, 0x0114)
|
||||
{
|
||||
return hackrf_set_freq(device, FP_FREQ(freq_hz));
|
||||
}
|
||||
|
||||
uint64_t set_freq_fp_param;
|
||||
uint8_t length;
|
||||
int result;
|
||||
|
||||
// serialize parameters
|
||||
set_freq_fp_param = TO_LE64(freq_hz);
|
||||
length = sizeof(uint64_t);
|
||||
|
||||
result = libusb_control_transfer(
|
||||
device->usb_device,
|
||||
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_RECIPIENT_DEVICE,
|
||||
HACKRF_VENDOR_REQUEST_RADIO_SET_FREQUENCY,
|
||||
0,
|
||||
0,
|
||||
(unsigned char*) &set_freq_fp_param,
|
||||
length,
|
||||
DEFAULT_REQUEST_TIMEOUT);
|
||||
|
||||
if (result < length) {
|
||||
last_libusb_error = result;
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
|
||||
return HACKRF_SUCCESS;
|
||||
}
|
||||
|
||||
int ADDCALL hackrf_radio_set_frequency_explicit(
|
||||
hackrf_device* device,
|
||||
const fp_40_24_t if_freq_hz,
|
||||
const fp_40_24_t lo_freq_hz,
|
||||
const enum rf_path_filter path)
|
||||
{
|
||||
USB_API_REQUIRED_OR(device, 0x0114)
|
||||
{
|
||||
return hackrf_set_freq_explicit(
|
||||
device,
|
||||
FP_FREQ(if_freq_hz),
|
||||
FP_FREQ(lo_freq_hz),
|
||||
path);
|
||||
}
|
||||
|
||||
struct {
|
||||
fp_40_24_t if_freq_hz;
|
||||
fp_40_24_t lo_freq_hz;
|
||||
uint8_t path;
|
||||
} params;
|
||||
|
||||
uint8_t length;
|
||||
int result;
|
||||
|
||||
// TODO are these values still correct for HackRF Pro ?
|
||||
if (FP_FREQ(if_freq_hz) < 2000000000 || FP_FREQ(if_freq_hz) > 3000000000) {
|
||||
return HACKRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// TODO are these values still correct for HackRF Pro ?
|
||||
if ((path != RF_PATH_FILTER_BYPASS) &&
|
||||
(FP_FREQ(lo_freq_hz) < 84375000 || FP_FREQ(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(params);
|
||||
|
||||
result = libusb_control_transfer(
|
||||
device->usb_device,
|
||||
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_RECIPIENT_DEVICE,
|
||||
HACKRF_VENDOR_REQUEST_RADIO_SET_FREQUENCY_EXPLICIT,
|
||||
0,
|
||||
0,
|
||||
(unsigned char*) ¶ms,
|
||||
length,
|
||||
DEFAULT_REQUEST_TIMEOUT);
|
||||
|
||||
if (result < length) {
|
||||
last_libusb_error = result;
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
} else {
|
||||
return HACKRF_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
int ADDCALL hackrf_radio_set_sample_rate(hackrf_device* device, const fp_28_36_t freq_hz)
|
||||
{
|
||||
USB_API_REQUIRED_OR(device, 0x0114)
|
||||
{
|
||||
return hackrf_set_sample_rate(device, (double) freq_hz / (1ULL << 36));
|
||||
}
|
||||
|
||||
uint64_t set_sr_fp_param;
|
||||
uint8_t length;
|
||||
int result;
|
||||
|
||||
set_sr_fp_param = TO_LE64(freq_hz);
|
||||
length = sizeof(uint64_t);
|
||||
|
||||
result = libusb_control_transfer(
|
||||
device->usb_device,
|
||||
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_RECIPIENT_DEVICE,
|
||||
HACKRF_VENDOR_REQUEST_RADIO_SET_SAMPLE_RATE,
|
||||
0,
|
||||
0,
|
||||
(unsigned char*) &set_sr_fp_param,
|
||||
length,
|
||||
DEFAULT_REQUEST_TIMEOUT);
|
||||
|
||||
if (result < length) {
|
||||
last_libusb_error = result;
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
|
||||
return HACKRF_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // __cplusplus defined.
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSI
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h> // for bool
|
||||
|
|
@ -947,18 +946,6 @@ enum clkin_ctrl_signal {
|
|||
CLKIN_SIGNAL_P22 = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* HackRF Pro Radio Configuration Mode.
|
||||
*
|
||||
* Used by @ref hackrf_open, @ref hackrf_open_mode_by_serial and @ref hackrf_device_list_open_mode to set the active configuration mode.
|
||||
*/
|
||||
enum radio_config_mode {
|
||||
RADIO_CONFIG_STANDARD = 0,
|
||||
RADIO_CONFIG_EXT_PRECISION_RX = 1,
|
||||
RADIO_CONFIG_EXT_PRECISION_TX = 2,
|
||||
RADIO_CONFIG_HALF_PRECISION = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @ingroup device
|
||||
|
|
@ -1212,7 +1199,6 @@ extern ADDAPI hackrf_device_list_t* ADDCALL hackrf_device_list();
|
|||
|
||||
/**
|
||||
* Open a @ref hackrf_device from a device list
|
||||
* @deprecated this function has been replaced by @ref hackrf_device_list_open_mode
|
||||
* @param[in] list device list to open device from
|
||||
* @param[in] idx index of the device to open
|
||||
* @param[out] device device handle to open
|
||||
|
|
@ -1224,24 +1210,6 @@ extern ADDAPI int ADDCALL hackrf_device_list_open(
|
|||
int idx,
|
||||
hackrf_device** device);
|
||||
|
||||
/**
|
||||
* Open a @ref hackrf_device from a device list and initialize it to the given radio configuration mode.
|
||||
*
|
||||
* Modes other than RADIO_CONFIG_STANDARD are only supported on HackRF Pro hardware.
|
||||
*
|
||||
* @param[in] mode configuration mode. Defaults to RADIO_CONFIG_STANDARD. Available modes are defined in @ref radio_config_mode.
|
||||
* @param[in] list device list to open device from
|
||||
* @param[in] idx index of the device to open
|
||||
* @param[out] device device handle to open
|
||||
* @return @ref HACKRF_SUCCESS on success, @ref HACKRF_ERROR_INVALID_PARAM on invalid parameters or other @ref hackrf_error variant
|
||||
* @ingroup device
|
||||
*/
|
||||
extern ADDAPI int ADDCALL hackrf_device_list_open_mode(
|
||||
const enum radio_config_mode mode,
|
||||
hackrf_device_list_t* list,
|
||||
int idx,
|
||||
hackrf_device** device);
|
||||
|
||||
/**
|
||||
* Check if a listed HackRF device is sharing its USB bus with other devices.
|
||||
*
|
||||
|
|
@ -1263,30 +1231,14 @@ extern ADDAPI void ADDCALL hackrf_device_list_free(hackrf_device_list_t* list);
|
|||
|
||||
/**
|
||||
* Open first available HackRF device
|
||||
* @deprecated this function has been replaced by @ref hackrf_open_mode
|
||||
* @param[out] device device handle
|
||||
* @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
|
||||
* @ingroup device
|
||||
*/
|
||||
extern ADDAPI int ADDCALL hackrf_open(hackrf_device** device);
|
||||
|
||||
/**
|
||||
* Open first available HackRF device and initialize it to the given radio configuration mode.
|
||||
*
|
||||
* Modes other than RADIO_CONFIG_STANDARD are only supported on HackRF Pro hardware.
|
||||
*
|
||||
* @param[in] mode configuration mode. Defaults to RADIO_CONFIG_STANDARD. Available modes are defined in @ref radio_config_mode.
|
||||
* @param[out] device device handle
|
||||
* @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
|
||||
* @ingroup device
|
||||
*/
|
||||
extern ADDAPI int ADDCALL hackrf_open_mode(
|
||||
const enum radio_config_mode mode,
|
||||
hackrf_device** device);
|
||||
|
||||
/**
|
||||
* Open HackRF device by serial number
|
||||
* @deprecated this function has been replaced by @ref hackrf_open_mode_by_serial
|
||||
* @param[in] desired_serial_number serial number of device to open. If NULL then default to first device found.
|
||||
* @param[out] device device handle
|
||||
* @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
|
||||
|
|
@ -1296,22 +1248,6 @@ extern ADDAPI int ADDCALL hackrf_open_by_serial(
|
|||
const char* const desired_serial_number,
|
||||
hackrf_device** device);
|
||||
|
||||
/**
|
||||
* Open HackRF device by serial number and initialize it to the given radio configuration mode.
|
||||
*
|
||||
* Modes other than RADIO_CONFIG_STANDARD are only supported on HackRF Pro hardware.
|
||||
*
|
||||
* @param[in] mode configuration mode. Defaults to RADIO_CONFIG_STANDARD. Available modes are defined in @ref radio_config_mode.
|
||||
* @param[in] desired_serial_number serial number of device to open. If NULL then default to first device found.
|
||||
* @param[out] device device handle
|
||||
* @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
|
||||
* @ingroup device
|
||||
*/
|
||||
extern ADDAPI int ADDCALL hackrf_open_mode_by_serial(
|
||||
const enum radio_config_mode mode,
|
||||
const char* const desired_serial_number,
|
||||
hackrf_device** device);
|
||||
|
||||
/**
|
||||
* Close a previously opened device
|
||||
* @param[in] device device to close
|
||||
|
|
@ -1816,8 +1752,7 @@ extern ADDAPI int ADDCALL hackrf_usb_api_version_read(
|
|||
* Simple (auto) tuning via specifying a center frequency in Hz
|
||||
*
|
||||
* This setting is not exact and depends on the PLL settings. Exact resolution is not determined, but the actual tuned frequency will be queryable in the future.
|
||||
*
|
||||
* @deprecated this function has been replaced by @ref hackrf_radio_set_frequency
|
||||
*
|
||||
* @param device device to tune
|
||||
* @param freq_hz center frequency in Hz. Defaults to 900MHz. Should be in range 1-6000MHz, but 0-7250MHz is possible. The resolution is ~50Hz, I could not find the exact number.
|
||||
* @return @ref HACKRF_SUCCESS on success or @ref hackrf_error variant
|
||||
|
|
@ -1829,8 +1764,7 @@ extern ADDAPI int ADDCALL hackrf_set_freq(hackrf_device* device, const uint64_t
|
|||
* Set the center frequency via explicit tuning
|
||||
*
|
||||
* Center frequency is set to \f$f_{center} = f_{IF} + k\cdot f_{LO}\f$ where \f$k\in\left\{-1; 0; 1\right\}\f$, depending on the value of @p path. See the documentation of @ref rf_path_filter for details
|
||||
*
|
||||
* @deprecated this function has been replaced by @ref hackrf_radio_set_frequency_explicit
|
||||
*
|
||||
* @param device device to tune
|
||||
* @param if_freq_hz tuning frequency of the MAX2837 transceiver IC in Hz. Must be in the range of 2150-2750MHz
|
||||
* @param lo_freq_hz tuning frequency of the RFFC5072 mixer/synthesizer IC in Hz. Must be in the range 84.375-5400MHz, defaults to 1000MHz. No effect if @p path is set to @ref RF_PATH_FILTER_BYPASS
|
||||
|
|
@ -1851,8 +1785,7 @@ extern ADDAPI int ADDCALL hackrf_set_freq_explicit(
|
|||
*
|
||||
* This function sets the sample rate by specifying a clock frequency in Hz and a divider, so the resulting sample rate will be @p freq_hz / @p divider.
|
||||
* This function also sets the baseband filter bandwidth to a value \f$ \le 0.75 \cdot F_s \f$, so any calls to @ref hackrf_set_baseband_filter_bandwidth should only be made after this.
|
||||
*
|
||||
* @deprecated this function has been replaced by @ref hackrf_radio_set_sample_rate
|
||||
*
|
||||
* @param device device to configure
|
||||
* @param freq_hz sample rate base frequency in Hz
|
||||
* @param divider frequency divider. Must be in the range 1-31
|
||||
|
|
@ -1870,7 +1803,6 @@ extern ADDAPI int ADDCALL hackrf_set_sample_rate_manual(
|
|||
* Sample rate should be in the range 2-20MHz, with the default being 10MHz. Lower & higher values are technically possible, but the performance is not guaranteed.
|
||||
* This function also sets the baseband filter bandwidth to a value \f$ \le 0.75 \cdot F_s \f$, so any calls to @ref hackrf_set_baseband_filter_bandwidth should only be made after this.
|
||||
*
|
||||
* @deprecated this function has been replaced by @ref hackrf_radio_set_sample_rate
|
||||
* @param device device to configure
|
||||
* @param freq_hz sample rate frequency in Hz. Should be in the range 2-20MHz
|
||||
* @return @ref HACKRF_SUCCESS on success or @ref hackrf_error variant
|
||||
|
|
@ -2453,128 +2385,6 @@ extern ADDAPI int ADDCALL hackrf_radio_write_register(
|
|||
const uint8_t register_number,
|
||||
const uint64_t value);
|
||||
|
||||
/**
|
||||
* Lock or unlock a radio configuration register.
|
||||
*
|
||||
* @param[in] device device to write
|
||||
* @param[in] register_number register number to mask
|
||||
* @param[out] locked locked state for the register
|
||||
* @return @ref HACKRF_SUCCESS on success or @ref hackrf_error variant
|
||||
* @ingroup debug
|
||||
*/
|
||||
extern ADDAPI int ADDCALL hackrf_radio_lock_register(
|
||||
hackrf_device* device,
|
||||
const uint8_t register_number,
|
||||
const bool register_locked);
|
||||
|
||||
/**
|
||||
* Switches the radio configuration mode.
|
||||
*
|
||||
* @param[in] device device to configure
|
||||
* @param[in] mode configuration mode. Defaults to RADIO_CONFIG_STANDARD. Available modes are defined in @ref radio_config_mode.
|
||||
* @return @ref HACKRF_SUCCESS on success or @ref hackrf_error variant
|
||||
* @ingroup configuration
|
||||
*/
|
||||
extern ADDAPI int ADDCALL hackrf_radio_set_mode(
|
||||
hackrf_device* device,
|
||||
const enum radio_config_mode mode);
|
||||
|
||||
/**
|
||||
* 40.24 Fixed-point type.
|
||||
*
|
||||
* Used by @ref hackrf_radio_set_frequency and @ref hackrf_radio_set_frequency_explicit
|
||||
* to represent a fractional tuning frequency.
|
||||
*/
|
||||
typedef uint64_t fp_40_24_t;
|
||||
|
||||
/**
|
||||
* 28.36 Fixed-point type.
|
||||
*
|
||||
* Used by @ref hackrf_radio_set_sample_rate to represent a fractional sample rate.
|
||||
*/
|
||||
typedef uint64_t fp_28_36_t;
|
||||
|
||||
/**
|
||||
* Convert an integer frequency value to its corresponding fixed-point value.
|
||||
*/
|
||||
#define FREQ_FP(u64) ((uint64_t) u64 << 24)
|
||||
|
||||
/**
|
||||
* Convert an integer sample rate value to its corresponding fixed-point value.
|
||||
*/
|
||||
#define SR_FP(u64) ((uint64_t) u64 << 36)
|
||||
|
||||
/**
|
||||
* Convert a fixed-point frequency value to its corresponding integer value, rounding up to the nearest integer.
|
||||
*
|
||||
*/
|
||||
#define FP_FREQ(u64) (((uint64_t) u64 + ((1ULL << 24) - 1)) >> 24)
|
||||
|
||||
/**
|
||||
* Convert a fixed-point sample rate value to its corresponding integer value, rounding up to the nearest integer.
|
||||
*/
|
||||
#define FP_SR(u64) (((uint64_t) u64 + ((1ULL << 36) - 1)) >> 36)
|
||||
|
||||
/**
|
||||
* Convert ASCII string to a 64 bit fixed-point number with a given number of bits of accuracy.
|
||||
*
|
||||
* @param[in] str string to parse
|
||||
* @param[in] Qn number of bits to use for fractional part
|
||||
* @param[out] value converted value
|
||||
* @return @ref HACKRF_SUCCESS on success or @ref hackrf_error variant
|
||||
* @ingroup configuration
|
||||
*/
|
||||
extern ADDAPI int ADDCALL hackrf_str_to_fp64(
|
||||
const uint8_t Qn,
|
||||
const char* str,
|
||||
uint64_t* const value);
|
||||
|
||||
/**
|
||||
* Set the radio center frequency to a fractional, fixed-point value.
|
||||
*
|
||||
* @param[in] device device to tune
|
||||
* @param[in] hz center frequency in Hz
|
||||
* @return @ref HACKRF_SUCCESS on success or @ref hackrf_error variant
|
||||
* @ingroup configuration
|
||||
*/
|
||||
extern ADDAPI int ADDCALL hackrf_radio_set_frequency(
|
||||
hackrf_device* device,
|
||||
const fp_40_24_t freq_hz);
|
||||
|
||||
/**
|
||||
* Set the radio center frequency to via explicit tuning.
|
||||
*
|
||||
* Center frequency is set to \f$f_{center} = f_{IF} + k\cdot f_{LO}\f$ where \f$k\in\left\{-1; 0; 1\right\}\f$, depending on the value of @p path. See the documentation of @ref rf_path_filter for details
|
||||
*
|
||||
* @param device device to tune
|
||||
* TODO are these values still applicable for HackRF Pro ?
|
||||
* @param if_freq_hz tuning frequency of the MAX2837 transceiver IC in Hz. Must be in the range of 2150-2750MHz
|
||||
* TODO are these values still applicable for HackRF Pro ?
|
||||
* @param lo_freq_hz tuning frequency of the RFFC5072 mixer/synthesizer IC in Hz. Must be in the range 84.375-5400MHz, defaults to 1000MHz. No effect if @p path is set to @ref RF_PATH_FILTER_BYPASS
|
||||
* @param path filter path for mixer. See the documentation for @ref rf_path_filter for details
|
||||
* @return @ref HACKRF_SUCCESS on success or @ref hackrf_error variant
|
||||
* @ingroup configuration
|
||||
*/
|
||||
extern ADDAPI int ADDCALL hackrf_radio_set_frequency_explicit(
|
||||
hackrf_device* device,
|
||||
const fp_40_24_t if_freq_hz,
|
||||
const fp_40_24_t lo_freq_hz,
|
||||
const enum rf_path_filter path);
|
||||
|
||||
/**
|
||||
* Set the radio sample rate to a fractional, fixed-point value.
|
||||
*
|
||||
* This function does not automatically configure the baseband filter bandwidth, so any calls to this function should be followed by @ref hackrf_set_baseband_filter_bandwidth should it require adjustment.
|
||||
*
|
||||
* @param[in] device device to configure
|
||||
* @param[in] sps samples per second
|
||||
* @return @ref HACKRF_SUCCESS on success or @ref hackrf_error variant
|
||||
* @ingroup configuration
|
||||
*/
|
||||
extern ADDAPI int ADDCALL hackrf_radio_set_sample_rate(
|
||||
hackrf_device* device,
|
||||
const fp_28_36_t freq_hz);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // __cplusplus defined.
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue