Merge remote-tracking branch 'mossmann/master' into opera-merge
Conflicts: firmware/common/hackrf_core.c firmware/common/rf_path.c firmware/hackrf-common.cmake firmware/hackrf_usb/hackrf_usb.c firmware/hackrf_usb/usb_api_transceiver.c host/hackrf-tools/src/hackrf_transfer.c
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,6 +5,7 @@
|
|||||||
*.hex
|
*.hex
|
||||||
*.srec
|
*.srec
|
||||||
host/build/
|
host/build/
|
||||||
|
host/**/build
|
||||||
|
|
||||||
# Operating system spew
|
# Operating system spew
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
43
.travis.yml
43
.travis.yml
@ -3,6 +3,7 @@ language: c
|
|||||||
cache: apt
|
cache: apt
|
||||||
|
|
||||||
sudo: false
|
sudo: false
|
||||||
|
dist: trusty
|
||||||
|
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
@ -10,32 +11,48 @@ os:
|
|||||||
|
|
||||||
compiler:
|
compiler:
|
||||||
- gcc
|
- gcc
|
||||||
# - clang
|
- clang
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
exclude:
|
||||||
|
- os: osx
|
||||||
|
compiler: gcc
|
||||||
|
- os: linux
|
||||||
|
compiler: clang
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
# - wget https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q1-update/+download/gcc-arm-none-eabi-5_3-2016q1-20160330-linux.tar.bz2 -O /tmp/gcc-arm.tar.bz2
|
|
||||||
# - tar -xvf /tmp/gcc-arm.tar.bz2
|
|
||||||
# - export PATH=$PWD/gcc-arm-none-eabi-5_3-2016q1/bin:$PATH
|
|
||||||
- export CFLAGS="-Wall -Wextra -Werror"
|
- export CFLAGS="-Wall -Wextra -Werror"
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew tap PX4/homebrew-px4; brew update; fi
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libusb; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libusb fftw gcc-arm-none-eabi dfu-util; fi
|
||||||
|
# For virtualenv(?) reasons we can't apt-get install python-yaml
|
||||||
|
- pip install PyYAML
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- mkdir host/build
|
- mkdir host/build
|
||||||
- cd host/build
|
- cd host/build
|
||||||
- cmake ..
|
- cmake ..
|
||||||
- make
|
- make
|
||||||
# - cd ../../firmware/hackrf_usb
|
- cd ../..
|
||||||
# - mkdir build
|
- mkdir firmware/build-hackrf-one
|
||||||
# - cd build
|
- mkdir firmware/build-jawbreaker
|
||||||
# - export CC="arm-none-eabi-gcc"
|
- cd firmware/libopencm3
|
||||||
# - export CXX="arm-none-eabi-g++"
|
- make
|
||||||
# - cmake ..
|
- cd ../build-hackrf-one
|
||||||
# - make
|
- cmake ..
|
||||||
|
- make
|
||||||
|
- cd ../build-jawbreaker
|
||||||
|
- cmake -DBOARD=JAWBREAKER ..
|
||||||
|
- make
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
|
sources:
|
||||||
|
- debian-sid
|
||||||
packages:
|
packages:
|
||||||
- libusb-1.0-0-dev
|
- libusb-1.0-0-dev
|
||||||
|
- libfftw3-dev
|
||||||
|
- gcc-arm-none-eabi
|
||||||
|
- libnewlib-arm-none-eabi
|
||||||
|
- dfu-util
|
||||||
|
27
appveyor.yml
Normal file
27
appveyor.yml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
os: Visual Studio 2015
|
||||||
|
clone_depth: 1
|
||||||
|
|
||||||
|
configuration:
|
||||||
|
- Release
|
||||||
|
- Debug
|
||||||
|
|
||||||
|
install:
|
||||||
|
- appveyor DownloadFile "https://downloads.sourceforge.net/project/libusb/libusb-1.0/libusb-1.0.21/libusb-1.0.21.7z?r=https%3A%2F%2Fsourceforge.net%2Fprojects%2Flibusb%2Ffiles%2Flibusb-1.0%2Flibusb-1.0.21%2F&ts=1485478643&use_mirror=cytranet" -FileName "C:\libusb.7z"
|
||||||
|
- 7z x -y "C:\libusb.7z" -o"C:\libusb"
|
||||||
|
- appveyor DownloadFile "http://mirrors.kernel.org/sourceware/pthreads-win32/pthreads-w32-2-9-1-release.zip" -FileName "C:\pthreads-w32-release.zip"
|
||||||
|
- 7z x -y "C:\pthreads-w32-release.zip" -o"C:\pthreads"
|
||||||
|
- appveyor DownloadFile "http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/pkg-config_0.26-1_win32.zip" -FileName "C:\pkg-config_win32.zip"
|
||||||
|
- 7z x -y "C:\pkg-config_win32.zip" -o"C:\pkg-config"
|
||||||
|
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- mkdir c:\projects\hackrf\host\build
|
||||||
|
- cd c:\projects\hackrf\host\build
|
||||||
|
- cmake -G "Visual Studio 14 2015 Win64" \
|
||||||
|
-DLIBUSB_LIBRARIES="C:\libusb\MS64\dll\libusb-1.0.lib" \
|
||||||
|
-DLIBUSB_INCLUDE_DIR="C:\libusb\include\libusb-1.0" \
|
||||||
|
-DTHREADS_PTHREADS_INCLUDE_DIR=c:\pthreads\Pre-built.2\include \
|
||||||
|
-DTHREADS_PTHREADS_WIN32_LIBRARY=c:\pthreads\Pre-built.2\lib\x64\pthreadVC2.lib \
|
||||||
|
-DPKG_CONFIG_EXECUTABLE="C:\pkg-config\bin\pkg-config.exe" \
|
||||||
|
..
|
||||||
|
- msbuild .\ALL_BUILD.vcxproj /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
@ -6,7 +6,7 @@ projects. The cpld directory contains HDL source for the CPLD.
|
|||||||
|
|
||||||
The firmware is set up for compilation with the GCC toolchain available here:
|
The firmware is set up for compilation with the GCC toolchain available here:
|
||||||
|
|
||||||
https://launchpad.net/gcc-arm-embedded
|
https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
|
||||||
|
|
||||||
Required dependency:
|
Required dependency:
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
pin_setup();
|
pin_setup();
|
||||||
|
|
||||||
/* enable all power supplies */
|
/* enable all power supplies */
|
||||||
@ -36,15 +35,13 @@ int main(void)
|
|||||||
led_on(LED2);
|
led_on(LED2);
|
||||||
led_on(LED3);
|
led_on(LED3);
|
||||||
|
|
||||||
for (i = 0; i < 2000000; i++) /* Wait a bit. */
|
delay(2000000);
|
||||||
__asm__("nop");
|
|
||||||
|
|
||||||
led_off(LED1);
|
led_off(LED1);
|
||||||
led_off(LED2);
|
led_off(LED2);
|
||||||
led_off(LED3);
|
led_off(LED3);
|
||||||
|
|
||||||
for (i = 0; i < 2000000; i++) /* Wait a bit. */
|
delay(2000000);
|
||||||
__asm__("nop");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -75,11 +75,24 @@ static struct gpio_t gpio_max2837_b7 = GPIO(2, 15);
|
|||||||
/* MAX5864 SPI chip select (AD_CS) GPIO PinMux */
|
/* MAX5864 SPI chip select (AD_CS) GPIO PinMux */
|
||||||
static struct gpio_t gpio_max5864_select = GPIO(2, 7);
|
static struct gpio_t gpio_max5864_select = GPIO(2, 7);
|
||||||
|
|
||||||
/* RF LDO control */
|
#if (defined JAWBREAKER || defined HACKRF_ONE || defined RAD1O)
|
||||||
#ifdef JAWBREAKER
|
/*
|
||||||
static struct gpio_t gpio_rf_ldo_enable = GPIO(2, 9);
|
static struct gpio_t gpio_sync_in_a = GPIO(3, 8);
|
||||||
|
static struct gpio_t gpio_sync_in_b = GPIO(3, 9);
|
||||||
|
static struct gpio_t gpio_sync_out_a = GPIO(3, 10);
|
||||||
|
static struct gpio_t gpio_sync_out_b = GPIO(3, 11);
|
||||||
|
*/
|
||||||
|
static struct gpio_t gpio_sync_in_a = GPIO(3, 10);
|
||||||
|
static struct gpio_t gpio_sync_in_b = GPIO(3, 11);
|
||||||
|
static struct gpio_t gpio_sync_out_a = GPIO(3, 8);
|
||||||
|
static struct gpio_t gpio_sync_out_b = GPIO(3, 9);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* RF LDO control */
|
||||||
|
// #ifdef JAWBREAKER
|
||||||
|
// static struct gpio_t gpio_rf_ldo_enable = GPIO(2, 9);
|
||||||
|
// #endif
|
||||||
|
|
||||||
/* RF supply (VAA) control */
|
/* RF supply (VAA) control */
|
||||||
#ifdef HACKRF_ONE
|
#ifdef HACKRF_ONE
|
||||||
static struct gpio_t gpio_vaa_disable = GPIO(2, 9);
|
static struct gpio_t gpio_vaa_disable = GPIO(2, 9);
|
||||||
@ -886,6 +899,15 @@ void pin_setup(void) {
|
|||||||
|
|
||||||
/* Safe state: start with VAA turned off: */
|
/* Safe state: start with VAA turned off: */
|
||||||
disable_rf_power();
|
disable_rf_power();
|
||||||
|
|
||||||
|
scu_pinmux(SCU_PINMUX_GPIO3_10, SCU_GPIO_PDN | SCU_CONF_FUNCTION0);
|
||||||
|
scu_pinmux(SCU_PINMUX_GPIO3_11, SCU_GPIO_PDN | SCU_CONF_FUNCTION0);
|
||||||
|
|
||||||
|
gpio_input(&gpio_sync_in_a);
|
||||||
|
gpio_input(&gpio_sync_in_b);
|
||||||
|
|
||||||
|
gpio_output(&gpio_sync_out_a);
|
||||||
|
gpio_output(&gpio_sync_out_b);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RAD1O
|
#ifdef RAD1O
|
||||||
@ -894,6 +916,15 @@ void pin_setup(void) {
|
|||||||
|
|
||||||
/* Safe state: start with VAA turned off: */
|
/* Safe state: start with VAA turned off: */
|
||||||
disable_rf_power();
|
disable_rf_power();
|
||||||
|
|
||||||
|
scu_pinmux(SCU_PINMUX_GPIO3_10, SCU_GPIO_PDN | SCU_CONF_FUNCTION0);
|
||||||
|
scu_pinmux(SCU_PINMUX_GPIO3_11, SCU_GPIO_PDN | SCU_CONF_FUNCTION0);
|
||||||
|
|
||||||
|
gpio_input(&gpio_sync_in_a);
|
||||||
|
gpio_input(&gpio_sync_in_b);
|
||||||
|
|
||||||
|
gpio_output(&gpio_sync_out_a);
|
||||||
|
gpio_output(&gpio_sync_out_b);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* enable input on SCL and SDA pins */
|
/* enable input on SCL and SDA pins */
|
||||||
@ -950,3 +981,33 @@ void led_off(const led_t led) {
|
|||||||
void led_toggle(const led_t led) {
|
void led_toggle(const led_t led) {
|
||||||
gpio_toggle(&gpio_led[led]);
|
gpio_toggle(&gpio_led[led]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hw_sync_syn() {
|
||||||
|
gpio_set(&gpio_sync_out_a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hw_sync_stop() {
|
||||||
|
gpio_clear(&gpio_sync_out_a);
|
||||||
|
gpio_clear(&gpio_sync_out_b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hw_sync_ack() {
|
||||||
|
gpio_set(&gpio_sync_out_b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hw_sync_copy_state() {
|
||||||
|
if(gpio_read(&gpio_sync_in_a)) {
|
||||||
|
gpio_set(&gpio_sync_out_a);
|
||||||
|
} else {
|
||||||
|
gpio_clear(&gpio_sync_out_a);
|
||||||
|
}
|
||||||
|
if(gpio_read(&gpio_sync_in_b)) {
|
||||||
|
gpio_set(&gpio_sync_out_b);
|
||||||
|
} else {
|
||||||
|
gpio_clear(&gpio_sync_out_b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hw_sync_ready() {
|
||||||
|
return (gpio_read(&gpio_sync_in_a) && gpio_read(&gpio_sync_in_b));
|
||||||
|
}
|
||||||
|
@ -264,6 +264,11 @@ typedef enum {
|
|||||||
TRANSCEIVER_MODE_CPLD_UPDATE = 4
|
TRANSCEIVER_MODE_CPLD_UPDATE = 4
|
||||||
} transceiver_mode_t;
|
} transceiver_mode_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
HW_SYNC_MODE_OFF = 0,
|
||||||
|
HW_SYNC_MODE_ON = 1,
|
||||||
|
} hw_sync_mode_t;
|
||||||
|
|
||||||
void delay(uint32_t duration);
|
void delay(uint32_t duration);
|
||||||
|
|
||||||
/* TODO: Hide these configurations */
|
/* TODO: Hide these configurations */
|
||||||
@ -279,6 +284,7 @@ extern w25q80bv_driver_t spi_flash;
|
|||||||
extern sgpio_config_t sgpio_config;
|
extern sgpio_config_t sgpio_config;
|
||||||
extern rf_path_t rf_path;
|
extern rf_path_t rf_path;
|
||||||
extern jtag_t jtag_cpld;
|
extern jtag_t jtag_cpld;
|
||||||
|
extern i2c_bus_t i2c0;
|
||||||
|
|
||||||
void cpu_clock_init(void);
|
void cpu_clock_init(void);
|
||||||
void cpu_clock_pll1_low_speed(void);
|
void cpu_clock_pll1_low_speed(void);
|
||||||
@ -311,6 +317,13 @@ void led_on(const led_t led);
|
|||||||
void led_off(const led_t led);
|
void led_off(const led_t led);
|
||||||
void led_toggle(const led_t led);
|
void led_toggle(const led_t led);
|
||||||
|
|
||||||
|
void hw_sync_syn();
|
||||||
|
void hw_sync_stop();
|
||||||
|
void hw_sync_ack();
|
||||||
|
bool hw_sync_ready();
|
||||||
|
void hw_sync_copy_state();
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -44,17 +44,23 @@ void i2c_lpc_transfer(i2c_bus_t* const bus,
|
|||||||
uint8_t* const data_rx, const size_t count_rx
|
uint8_t* const data_rx, const size_t count_rx
|
||||||
) {
|
) {
|
||||||
const uint32_t port = (uint32_t)bus->obj;
|
const uint32_t port = (uint32_t)bus->obj;
|
||||||
i2c_tx_start(port);
|
size_t i;
|
||||||
i2c_tx_byte(port, (slave_address << 1) | I2C_WRITE);
|
bool ack = false;
|
||||||
for(size_t i=0; i<count_tx; i++) {
|
if (data_tx && (count_tx > 0)) {
|
||||||
i2c_tx_byte(port, data_tx[i]);
|
i2c_tx_start(port);
|
||||||
|
i2c_tx_byte(port, (slave_address << 1) | I2C_WRITE);
|
||||||
|
for(i=0; i<count_tx; i++) {
|
||||||
|
i2c_tx_byte(port, data_tx[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( data_rx ) {
|
if (data_rx && (count_rx > 0)) {
|
||||||
i2c_tx_start(port);
|
i2c_tx_start(port);
|
||||||
i2c_tx_byte(port, (slave_address << 1) | I2C_READ);
|
i2c_tx_byte(port, (slave_address << 1) | I2C_READ);
|
||||||
for(size_t i=0; i<count_rx; i++) {
|
for(i=0; i<count_rx; i++) {
|
||||||
data_rx[i] = i2c_rx_byte(port);
|
/* ACK each byte except the last */
|
||||||
|
ack = (i!=count_rx-1);
|
||||||
|
data_rx[i] = i2c_rx_byte(port, ack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
147
firmware/common/operacake.c
Normal file
147
firmware/common/operacake.c
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Dominic Spill <dominicgs@gmail.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 "operacake.h"
|
||||||
|
#include "hackrf_core.h"
|
||||||
|
|
||||||
|
#define OPERACAKE_PIN_OE(x) (x<<7)
|
||||||
|
#define OPERACAKE_PIN_U2CTRL1(x) (x<<6)
|
||||||
|
#define OPERACAKE_PIN_U2CTRL0(x) (x<<5)
|
||||||
|
#define OPERACAKE_PIN_U3CTRL1(x) (x<<4)
|
||||||
|
#define OPERACAKE_PIN_U3CTRL0(x) (x<<3)
|
||||||
|
#define OPERACAKE_PIN_U1CTRL(x) (x<<2)
|
||||||
|
#define OPERACAKE_PIN_LEDEN2(x) (x<<1)
|
||||||
|
#define OPERACAKE_PIN_LEDEN(x) (x<<0)
|
||||||
|
|
||||||
|
#define OPERACAKE_PORT_A1 (OPERACAKE_PIN_U2CTRL0(0) | OPERACAKE_PIN_U2CTRL1(0))
|
||||||
|
#define OPERACAKE_PORT_A2 (OPERACAKE_PIN_U2CTRL0(1) | OPERACAKE_PIN_U2CTRL1(0))
|
||||||
|
#define OPERACAKE_PORT_A3 (OPERACAKE_PIN_U2CTRL0(0) | OPERACAKE_PIN_U2CTRL1(1))
|
||||||
|
#define OPERACAKE_PORT_A4 (OPERACAKE_PIN_U2CTRL0(1) | OPERACAKE_PIN_U2CTRL1(1))
|
||||||
|
|
||||||
|
#define OPERACAKE_PORT_B1 (OPERACAKE_PIN_U3CTRL0(0) | OPERACAKE_PIN_U3CTRL1(0))
|
||||||
|
#define OPERACAKE_PORT_B2 (OPERACAKE_PIN_U3CTRL0(1) | OPERACAKE_PIN_U3CTRL1(0))
|
||||||
|
#define OPERACAKE_PORT_B3 (OPERACAKE_PIN_U3CTRL0(0) | OPERACAKE_PIN_U3CTRL1(1))
|
||||||
|
#define OPERACAKE_PORT_B4 (OPERACAKE_PIN_U3CTRL0(1) | OPERACAKE_PIN_U3CTRL1(1))
|
||||||
|
|
||||||
|
#define OPERACAKE_SAMESIDE OPERACAKE_PIN_U1CTRL(1)
|
||||||
|
#define OPERACAKE_CROSSOVER OPERACAKE_PIN_U1CTRL(0)
|
||||||
|
#define OPERACAKE_EN_LEDS (OPERACAKE_PIN_LEDEN2(1) | OPERACAKE_PIN_LEDEN2(0))
|
||||||
|
#define OPERACAKE_GPIO_EN OPERACAKE_PIN_OE(0)
|
||||||
|
#define OPERACAKE_GPIO_DISABLE OPERACAKE_PIN_OE(1)
|
||||||
|
|
||||||
|
#define OPERACAKE_REG_INPUT 0x00
|
||||||
|
#define OPERACAKE_REG_OUTPUT 0x01
|
||||||
|
#define OPERACAKE_REG_POLARITY 0x02
|
||||||
|
#define OPERACAKE_REG_CONFIG 0x03
|
||||||
|
|
||||||
|
#define OPERACAKE_DEFAULT_OUTPUT (OPERACAKE_GPIO_DISABLE | OPERACAKE_SAMESIDE \
|
||||||
|
| OPERACAKE_PORT_A1 | OPERACAKE_PORT_B1 \
|
||||||
|
| OPERACAKE_EN_LEDS)
|
||||||
|
#define OPERACAKE_CONFIG_ALL_OUTPUT (0x00)
|
||||||
|
|
||||||
|
#define OPERACAKE_DEFAULT_ADDRESS 0x18
|
||||||
|
|
||||||
|
i2c_bus_t* const oc_bus = &i2c0;
|
||||||
|
uint8_t operacake_boards[8] = {0,0,0,0,0,0,0,0};
|
||||||
|
|
||||||
|
/* read single register */
|
||||||
|
uint8_t operacake_read_reg(i2c_bus_t* const bus, uint8_t address, uint8_t reg) {
|
||||||
|
const uint8_t data_tx[] = { reg };
|
||||||
|
uint8_t data_rx[] = { 0x00 };
|
||||||
|
i2c_bus_transfer(bus, address, data_tx, 1, data_rx, 1);
|
||||||
|
return data_rx[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write to one of the PCA9557 registers */
|
||||||
|
void operacake_write_reg(i2c_bus_t* const bus, uint8_t address, uint8_t reg, uint8_t value) {
|
||||||
|
const uint8_t data[] = {reg, value};
|
||||||
|
i2c_bus_transfer(bus, address, data, 2, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t operacake_init(void) {
|
||||||
|
uint8_t reg, addr, i, j = 0;
|
||||||
|
/* Find connected operacakes */
|
||||||
|
for(i=0; i<8; i++) {
|
||||||
|
addr = OPERACAKE_DEFAULT_ADDRESS | i;
|
||||||
|
operacake_write_reg(oc_bus, addr, OPERACAKE_REG_OUTPUT,
|
||||||
|
OPERACAKE_DEFAULT_OUTPUT);
|
||||||
|
operacake_write_reg(oc_bus, addr, OPERACAKE_REG_CONFIG,
|
||||||
|
OPERACAKE_CONFIG_ALL_OUTPUT);
|
||||||
|
reg = operacake_read_reg(oc_bus, addr, OPERACAKE_REG_CONFIG);
|
||||||
|
if(reg==OPERACAKE_CONFIG_ALL_OUTPUT)
|
||||||
|
operacake_boards[j++] = addr;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t port_to_pins(uint8_t port) {
|
||||||
|
switch(port) {
|
||||||
|
case OPERACAKE_PA1:
|
||||||
|
return OPERACAKE_PORT_A1;
|
||||||
|
case OPERACAKE_PA2:
|
||||||
|
return OPERACAKE_PORT_A2;
|
||||||
|
case OPERACAKE_PA3:
|
||||||
|
return OPERACAKE_PORT_A3;
|
||||||
|
case OPERACAKE_PA4:
|
||||||
|
return OPERACAKE_PORT_A4;
|
||||||
|
|
||||||
|
case OPERACAKE_PB1:
|
||||||
|
return OPERACAKE_PORT_B1;
|
||||||
|
case OPERACAKE_PB2:
|
||||||
|
return OPERACAKE_PORT_B2;
|
||||||
|
case OPERACAKE_PB3:
|
||||||
|
return OPERACAKE_PORT_B3;
|
||||||
|
case OPERACAKE_PB4:
|
||||||
|
return OPERACAKE_PORT_B4;
|
||||||
|
}
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t operacake_set_ports(uint8_t address, uint8_t PA, uint8_t PB) {
|
||||||
|
uint8_t side, pa, pb, reg;
|
||||||
|
/* Start with some error checking,
|
||||||
|
* which should have been done either
|
||||||
|
* on the host or elsewhere in firmware
|
||||||
|
*/
|
||||||
|
if((PA > OPERACAKE_PB4) || (PB > OPERACAKE_PB4)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* Check which side PA and PB are on */
|
||||||
|
if(((PA <= OPERACAKE_PA4) && (PB <= OPERACAKE_PA4))
|
||||||
|
|| ((PA > OPERACAKE_PA4) && (PB > OPERACAKE_PA4))) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(PA > OPERACAKE_PA4) {
|
||||||
|
side = OPERACAKE_CROSSOVER;
|
||||||
|
} else {
|
||||||
|
side = OPERACAKE_SAMESIDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pa = port_to_pins(PA);
|
||||||
|
pb = port_to_pins(PB);
|
||||||
|
|
||||||
|
reg = (OPERACAKE_GPIO_DISABLE | side
|
||||||
|
| pa | pb | OPERACAKE_EN_LEDS);
|
||||||
|
operacake_write_reg(oc_bus, address, OPERACAKE_REG_OUTPUT, reg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
53
firmware/common/operacake.h
Normal file
53
firmware/common/operacake.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Dominic Spill <dominicgs@gmail.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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __OPERACAKE_H
|
||||||
|
#define __OPERACAKE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "i2c_bus.h"
|
||||||
|
|
||||||
|
#define OPERACAKE_PA1 0
|
||||||
|
#define OPERACAKE_PA2 1
|
||||||
|
#define OPERACAKE_PA3 2
|
||||||
|
#define OPERACAKE_PA4 3
|
||||||
|
|
||||||
|
#define OPERACAKE_PB1 4
|
||||||
|
#define OPERACAKE_PB2 5
|
||||||
|
#define OPERACAKE_PB3 6
|
||||||
|
#define OPERACAKE_PB4 7
|
||||||
|
|
||||||
|
/* Up to 8 Operacake boards can be used with one HackRF */
|
||||||
|
extern uint8_t operacake_boards[8];
|
||||||
|
|
||||||
|
uint8_t operacake_init(void);
|
||||||
|
uint8_t operacake_set_ports(uint8_t address, uint8_t PA, uint8_t PB);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __OPERACAKE_H */
|
@ -230,6 +230,7 @@ static void switchctrl_set_rad1o(rf_path_t* const rf_path, uint8_t ctrl) {
|
|||||||
|
|
||||||
static void switchctrl_set(rf_path_t* const rf_path, const uint8_t gpo) {
|
static void switchctrl_set(rf_path_t* const rf_path, const uint8_t gpo) {
|
||||||
#ifdef JAWBREAKER
|
#ifdef JAWBREAKER
|
||||||
|
(void) rf_path; /* silence unused param warning */
|
||||||
mixer_set_gpo(&mixer, gpo);
|
mixer_set_gpo(&mixer, gpo);
|
||||||
#elif HACKRF_ONE
|
#elif HACKRF_ONE
|
||||||
switchctrl_set_hackrf_one(rf_path, gpo);
|
switchctrl_set_hackrf_one(rf_path, gpo);
|
||||||
@ -274,9 +275,13 @@ void rf_path_pin_setup(rf_path_t* const rf_path) {
|
|||||||
gpio_output(rf_path->gpio_tx);
|
gpio_output(rf_path->gpio_tx);
|
||||||
gpio_output(rf_path->gpio_mix_bypass);
|
gpio_output(rf_path->gpio_mix_bypass);
|
||||||
gpio_output(rf_path->gpio_rx);
|
gpio_output(rf_path->gpio_rx);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef RAD1O
|
/*
|
||||||
|
* Safe (initial) switch settings turn off both amplifiers and antenna port
|
||||||
|
* power and enable both amp bypass and mixer bypass.
|
||||||
|
*/
|
||||||
|
switchctrl_set(rf_path, SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_MIX_BYPASS);
|
||||||
|
#elif RAD1O
|
||||||
/* Configure RF switch control signals */
|
/* Configure RF switch control signals */
|
||||||
scu_pinmux(SCU_BY_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
|
scu_pinmux(SCU_BY_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
|
||||||
scu_pinmux(SCU_BY_AMP_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
|
scu_pinmux(SCU_BY_AMP_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
|
||||||
@ -305,13 +310,15 @@ void rf_path_pin_setup(rf_path_t* const rf_path) {
|
|||||||
gpio_output(rf_path->gpio_low_high_filt_n);
|
gpio_output(rf_path->gpio_low_high_filt_n);
|
||||||
gpio_output(rf_path->gpio_tx_amp);
|
gpio_output(rf_path->gpio_tx_amp);
|
||||||
gpio_output(rf_path->gpio_rx_lna);
|
gpio_output(rf_path->gpio_rx_lna);
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Safe (initial) switch settings turn off both amplifiers and antenna port
|
* Safe (initial) switch settings turn off both amplifiers and antenna port
|
||||||
* power and enable both amp bypass and mixer bypass.
|
* power and enable both amp bypass and mixer bypass.
|
||||||
*/
|
*/
|
||||||
switchctrl_set(rf_path, SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_MIX_BYPASS);
|
switchctrl_set(rf_path, SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_MIX_BYPASS);
|
||||||
|
#else
|
||||||
|
(void) rf_path; /* silence unused param warning */
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void rf_path_init(rf_path_t* const rf_path) {
|
void rf_path_init(rf_path_t* const rf_path) {
|
||||||
|
@ -117,6 +117,10 @@ void rffc5071_setup(rffc5071_driver_t* const drv)
|
|||||||
/* GPOs are active at all times */
|
/* GPOs are active at all times */
|
||||||
set_RFFC5071_GATE(drv, 1);
|
set_RFFC5071_GATE(drv, 1);
|
||||||
|
|
||||||
|
/* Output LOCK status on GPO4 and enable lock detect */
|
||||||
|
set_RFFC5071_LOCK(drv, 1);
|
||||||
|
set_RFFC5071_LDEN(drv, 1);
|
||||||
|
|
||||||
rffc5071_regs_commit(drv);
|
rffc5071_regs_commit(drv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,13 +258,6 @@ uint64_t rffc5071_config_synth_int(rffc5071_driver_t* const drv, uint16_t lo) {
|
|||||||
tune_freq_hz = (REF_FREQ * (tmp_n >> 5ULL) * fbkdiv * FREQ_ONE_MHZ)
|
tune_freq_hz = (REF_FREQ * (tmp_n >> 5ULL) * fbkdiv * FREQ_ONE_MHZ)
|
||||||
/ (lodiv * (1 << 24ULL));
|
/ (lodiv * (1 << 24ULL));
|
||||||
|
|
||||||
/* Path 1 */
|
|
||||||
set_RFFC5071_P1LODIV(drv, n_lo);
|
|
||||||
set_RFFC5071_P1N(drv, n);
|
|
||||||
set_RFFC5071_P1PRESC(drv, fbkdiv >> 1);
|
|
||||||
set_RFFC5071_P1NMSB(drv, p1nmsb);
|
|
||||||
set_RFFC5071_P1NLSB(drv, p1nlsb);
|
|
||||||
|
|
||||||
/* Path 2 */
|
/* Path 2 */
|
||||||
set_RFFC5071_P2LODIV(drv, n_lo);
|
set_RFFC5071_P2LODIV(drv, n_lo);
|
||||||
set_RFFC5071_P2N(drv, n);
|
set_RFFC5071_P2N(drv, n);
|
||||||
|
@ -94,10 +94,7 @@ void rffc5071_spi_stop(spi_bus_t* const bus) {
|
|||||||
|
|
||||||
static void rffc5071_spi_serial_delay(spi_bus_t* const bus) {
|
static void rffc5071_spi_serial_delay(spi_bus_t* const bus) {
|
||||||
(void)bus;
|
(void)bus;
|
||||||
volatile uint32_t i;
|
__asm__("nop");
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
__asm__("nop");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rffc5071_spi_sck(spi_bus_t* const bus) {
|
static void rffc5071_spi_sck(spi_bus_t* const bus) {
|
||||||
|
8
firmware/dfu.py
Normal file
8
firmware/dfu.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import os.path
|
||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
|
||||||
|
with open("_header.bin", "wb") as f:
|
||||||
|
x = struct.pack('<H', os.path.getsize(sys.argv[1] + '_dfu.bin') // 512 + 1)
|
||||||
|
y = [0xda, 0xff, x[0], x[1], 0xff, 0xff, 0xff, 0xff]
|
||||||
|
f.write(bytearray(y))
|
@ -42,6 +42,9 @@ set(SRC_M4
|
|||||||
usb_api_register.c
|
usb_api_register.c
|
||||||
usb_api_spiflash.c
|
usb_api_spiflash.c
|
||||||
usb_api_transceiver.c
|
usb_api_transceiver.c
|
||||||
|
"${PATH_HACKRF_FIRMWARE_COMMON}/operacake.c"
|
||||||
|
usb_api_operacake.c
|
||||||
|
usb_api_sweep.c
|
||||||
"${PATH_HACKRF_FIRMWARE_COMMON}/usb_queue.c"
|
"${PATH_HACKRF_FIRMWARE_COMMON}/usb_queue.c"
|
||||||
"${PATH_HACKRF_FIRMWARE_COMMON}/fault_handler.c"
|
"${PATH_HACKRF_FIRMWARE_COMMON}/fault_handler.c"
|
||||||
"${PATH_HACKRF_FIRMWARE_COMMON}/cpld_jtag.c"
|
"${PATH_HACKRF_FIRMWARE_COMMON}/cpld_jtag.c"
|
||||||
|
@ -22,12 +22,12 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include <libopencm3/cm3/vector.h>
|
|
||||||
|
|
||||||
#include <libopencm3/lpc43xx/m4/nvic.h>
|
#include <libopencm3/lpc43xx/m4/nvic.h>
|
||||||
|
|
||||||
#include <streaming.h>
|
#include <streaming.h>
|
||||||
|
|
||||||
|
#include "tuning.h"
|
||||||
|
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "usb_standard_request.h"
|
#include "usb_standard_request.h"
|
||||||
|
|
||||||
@ -40,77 +40,14 @@
|
|||||||
#include "usb_api_cpld.h"
|
#include "usb_api_cpld.h"
|
||||||
#include "usb_api_register.h"
|
#include "usb_api_register.h"
|
||||||
#include "usb_api_spiflash.h"
|
#include "usb_api_spiflash.h"
|
||||||
|
#include "usb_api_operacake.h"
|
||||||
|
#include "operacake.h"
|
||||||
|
#include "usb_api_sweep.h"
|
||||||
#include "usb_api_transceiver.h"
|
#include "usb_api_transceiver.h"
|
||||||
#include "sgpio_isr.h"
|
|
||||||
#include "usb_bulk_buffer.h"
|
#include "usb_bulk_buffer.h"
|
||||||
|
|
||||||
#include "hackrf-ui.h"
|
#include "hackrf-ui.h"
|
||||||
|
|
||||||
static volatile transceiver_mode_t _transceiver_mode = TRANSCEIVER_MODE_OFF;
|
|
||||||
|
|
||||||
void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) {
|
|
||||||
baseband_streaming_disable(&sgpio_config);
|
|
||||||
|
|
||||||
usb_endpoint_disable(&usb_endpoint_bulk_in);
|
|
||||||
usb_endpoint_disable(&usb_endpoint_bulk_out);
|
|
||||||
|
|
||||||
_transceiver_mode = new_transceiver_mode;
|
|
||||||
|
|
||||||
if( _transceiver_mode == TRANSCEIVER_MODE_RX ) {
|
|
||||||
led_off(LED3);
|
|
||||||
led_on(LED2);
|
|
||||||
usb_endpoint_init(&usb_endpoint_bulk_in);
|
|
||||||
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_RX);
|
|
||||||
vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx;
|
|
||||||
} else if (_transceiver_mode == TRANSCEIVER_MODE_TX) {
|
|
||||||
led_off(LED2);
|
|
||||||
led_on(LED3);
|
|
||||||
usb_endpoint_init(&usb_endpoint_bulk_out);
|
|
||||||
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_TX);
|
|
||||||
vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_tx;
|
|
||||||
} else {
|
|
||||||
led_off(LED2);
|
|
||||||
led_off(LED3);
|
|
||||||
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_OFF);
|
|
||||||
vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( _transceiver_mode != TRANSCEIVER_MODE_OFF ) {
|
|
||||||
si5351c_activate_best_clock_source(&clock_gen);
|
|
||||||
baseband_streaming_enable(&sgpio_config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transceiver_mode_t transceiver_mode(void) {
|
|
||||||
return _transceiver_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
usb_request_status_t usb_vendor_request_set_transceiver_mode(
|
|
||||||
usb_endpoint_t* const endpoint,
|
|
||||||
const usb_transfer_stage_t stage
|
|
||||||
) {
|
|
||||||
if( stage == USB_TRANSFER_STAGE_SETUP ) {
|
|
||||||
switch( endpoint->setup.value ) {
|
|
||||||
case TRANSCEIVER_MODE_OFF:
|
|
||||||
case TRANSCEIVER_MODE_RX:
|
|
||||||
case TRANSCEIVER_MODE_TX:
|
|
||||||
set_transceiver_mode(endpoint->setup.value);
|
|
||||||
usb_transfer_schedule_ack(endpoint->in);
|
|
||||||
return USB_REQUEST_STATUS_OK;
|
|
||||||
case TRANSCEIVER_MODE_CPLD_UPDATE:
|
|
||||||
usb_endpoint_init(&usb_endpoint_bulk_out);
|
|
||||||
start_cpld_update = true;
|
|
||||||
usb_transfer_schedule_ack(endpoint->in);
|
|
||||||
return USB_REQUEST_STATUS_OK;
|
|
||||||
default:
|
|
||||||
return USB_REQUEST_STATUS_STALL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return USB_REQUEST_STATUS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const usb_request_handler_fn vendor_request_handler[] = {
|
static const usb_request_handler_fn vendor_request_handler[] = {
|
||||||
NULL,
|
NULL,
|
||||||
usb_vendor_request_set_transceiver_mode,
|
usb_vendor_request_set_transceiver_mode,
|
||||||
@ -147,6 +84,11 @@ static const usb_request_handler_fn vendor_request_handler[] = {
|
|||||||
#endif
|
#endif
|
||||||
usb_vendor_request_set_freq_explicit,
|
usb_vendor_request_set_freq_explicit,
|
||||||
usb_vendor_request_read_wcid, // USB_WCID_VENDOR_REQ
|
usb_vendor_request_read_wcid, // USB_WCID_VENDOR_REQ
|
||||||
|
usb_vendor_request_init_sweep,
|
||||||
|
usb_vendor_request_operacake_get_boards,
|
||||||
|
usb_vendor_request_operacake_set_ports,
|
||||||
|
usb_vendor_request_set_hw_sync_mode,
|
||||||
|
usb_vendor_request_reset
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint32_t vendor_request_handler_count =
|
static const uint32_t vendor_request_handler_count =
|
||||||
@ -247,13 +189,23 @@ int main(void) {
|
|||||||
usb_run(&usb_device);
|
usb_run(&usb_device);
|
||||||
|
|
||||||
rf_path_init(&rf_path);
|
rf_path_init(&rf_path);
|
||||||
|
operacake_init();
|
||||||
|
|
||||||
unsigned int phase = 0;
|
unsigned int phase = 0;
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
// Check whether we need to initiate a CPLD update
|
// Check whether we need to initiate a CPLD update
|
||||||
if (start_cpld_update)
|
if (start_cpld_update)
|
||||||
cpld_update();
|
cpld_update();
|
||||||
|
|
||||||
|
// Check whether we need to initiate sweep mode
|
||||||
|
if (start_sweep_mode) {
|
||||||
|
start_sweep_mode = false;
|
||||||
|
sweep_mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
start_streaming_on_hw_sync();
|
||||||
|
|
||||||
// Set up IN transfer of buffer 0.
|
// Set up IN transfer of buffer 0.
|
||||||
if ( usb_bulk_buffer_offset >= 16384
|
if ( usb_bulk_buffer_offset >= 16384
|
||||||
&& phase == 1
|
&& phase == 1
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <hackrf_core.h>
|
#include <hackrf_core.h>
|
||||||
#include <rom_iap.h>
|
#include <rom_iap.h>
|
||||||
#include <usb_queue.h>
|
#include <usb_queue.h>
|
||||||
|
#include <libopencm3/lpc43xx/wwdt.h>
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -91,3 +92,13 @@ usb_request_status_t usb_vendor_request_read_partid_serialno(
|
|||||||
}
|
}
|
||||||
return USB_REQUEST_STATUS_OK;
|
return USB_REQUEST_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
usb_request_status_t usb_vendor_request_reset(
|
||||||
|
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
|
||||||
|
{
|
||||||
|
if (stage == USB_TRANSFER_STAGE_SETUP) {
|
||||||
|
wwdt_reset(100000);
|
||||||
|
usb_transfer_schedule_ack(endpoint->in);
|
||||||
|
}
|
||||||
|
return USB_REQUEST_STATUS_OK;
|
||||||
|
}
|
@ -39,5 +39,7 @@ usb_request_status_t usb_vendor_request_read_version_string(
|
|||||||
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_read_partid_serialno(
|
usb_request_status_t usb_vendor_request_read_partid_serialno(
|
||||||
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_reset(
|
||||||
|
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage);
|
||||||
|
|
||||||
#endif /* end of include guard: __USB_API_BOARD_INFO_H__ */
|
#endif /* end of include guard: __USB_API_BOARD_INFO_H__ */
|
||||||
|
49
firmware/hackrf_usb/usb_api_operacake.c
Normal file
49
firmware/hackrf_usb/usb_api_operacake.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Dominic Spill <dominicgs@gmail.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 "usb_api_operacake.h"
|
||||||
|
#include "usb_queue.h"
|
||||||
|
|
||||||
|
#include <operacake.h>
|
||||||
|
|
||||||
|
usb_request_status_t usb_vendor_request_operacake_get_boards(
|
||||||
|
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
|
||||||
|
{
|
||||||
|
if (stage == USB_TRANSFER_STAGE_SETUP) {
|
||||||
|
usb_transfer_schedule_block(endpoint->in, operacake_boards, 8, NULL, NULL);
|
||||||
|
usb_transfer_schedule_ack(endpoint->out);
|
||||||
|
}
|
||||||
|
return USB_REQUEST_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
usb_request_status_t usb_vendor_request_operacake_set_ports(
|
||||||
|
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
|
||||||
|
{
|
||||||
|
uint8_t address, port_a, port_b;
|
||||||
|
address = endpoint->setup.value & 0xFF;
|
||||||
|
port_a = endpoint->setup.index & 0xFF;
|
||||||
|
port_b = (endpoint->setup.index >> 8) & 0xFF;
|
||||||
|
if (stage == USB_TRANSFER_STAGE_SETUP) {
|
||||||
|
operacake_set_ports(address, port_a, port_b);
|
||||||
|
usb_transfer_schedule_ack(endpoint->in);
|
||||||
|
}
|
||||||
|
return USB_REQUEST_STATUS_OK;
|
||||||
|
}
|
34
firmware/hackrf_usb/usb_api_operacake.h
Normal file
34
firmware/hackrf_usb/usb_api_operacake.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Dominic Spill <dominicgs@gmail.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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __USB_API_OPERACAKE_H__
|
||||||
|
#define __USB_API_OPERACAKE_H__
|
||||||
|
|
||||||
|
#include <usb_type.h>
|
||||||
|
#include <usb_request.h>
|
||||||
|
|
||||||
|
usb_request_status_t usb_vendor_request_operacake_get_boards(
|
||||||
|
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage);
|
||||||
|
|
||||||
|
usb_request_status_t usb_vendor_request_operacake_set_ports(
|
||||||
|
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage);
|
||||||
|
|
||||||
|
#endif /* end of include guard: __USB_API_OPERACAKE_H__ */
|
109
firmware/hackrf_usb/usb_api_sweep.c
Normal file
109
firmware/hackrf_usb/usb_api_sweep.c
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Mike Walters, Dominic Spill
|
||||||
|
*
|
||||||
|
* 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 "usb_api_sweep.h"
|
||||||
|
#include "usb_queue.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <hackrf_core.h>
|
||||||
|
#include "usb_api_transceiver.h"
|
||||||
|
#include "usb_bulk_buffer.h"
|
||||||
|
#include "tuning.h"
|
||||||
|
#include "usb_endpoint.h"
|
||||||
|
|
||||||
|
#define MIN(x,y) ((x)<(y)?(x):(y))
|
||||||
|
#define MAX(x,y) ((x)>(y)?(x):(y))
|
||||||
|
#define FREQ_GRANULARITY 1000000
|
||||||
|
#define MIN_FREQ 1
|
||||||
|
#define MAX_FREQ 6000
|
||||||
|
#define MAX_FREQ_COUNT 1000
|
||||||
|
|
||||||
|
volatile bool start_sweep_mode = false;
|
||||||
|
static uint64_t sweep_freq;
|
||||||
|
bool odd = true;
|
||||||
|
static uint16_t frequencies[MAX_FREQ_COUNT];
|
||||||
|
static uint16_t frequency_count = 0;
|
||||||
|
static uint32_t dwell_blocks = 0;
|
||||||
|
|
||||||
|
usb_request_status_t usb_vendor_request_init_sweep(
|
||||||
|
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
|
||||||
|
{
|
||||||
|
uint32_t dwell_time;
|
||||||
|
if (stage == USB_TRANSFER_STAGE_SETUP) {
|
||||||
|
dwell_time = (endpoint->setup.index << 16) | endpoint->setup.value;
|
||||||
|
dwell_blocks = dwell_time / 0x4000;
|
||||||
|
frequency_count = endpoint->setup.length / sizeof(uint16_t);
|
||||||
|
usb_transfer_schedule_block(endpoint->out, &frequencies,
|
||||||
|
endpoint->setup.length, NULL, NULL);
|
||||||
|
} else if (stage == USB_TRANSFER_STAGE_DATA) {
|
||||||
|
sweep_freq = frequencies[0];
|
||||||
|
set_freq(sweep_freq*FREQ_GRANULARITY);
|
||||||
|
start_sweep_mode = true;
|
||||||
|
usb_transfer_schedule_ack(endpoint->in);
|
||||||
|
}
|
||||||
|
return USB_REQUEST_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sweep_mode(void) {
|
||||||
|
unsigned int blocks_queued = 0;
|
||||||
|
unsigned int phase = 0;
|
||||||
|
unsigned int ifreq = 0;
|
||||||
|
|
||||||
|
uint8_t *buffer;
|
||||||
|
bool transfer = false;
|
||||||
|
|
||||||
|
while(transceiver_mode() != TRANSCEIVER_MODE_OFF) {
|
||||||
|
// Set up IN transfer of buffer 0.
|
||||||
|
if ( usb_bulk_buffer_offset >= 16384 && phase == 1) {
|
||||||
|
transfer = true;
|
||||||
|
buffer = &usb_bulk_buffer[0x0000];
|
||||||
|
phase = 0;
|
||||||
|
blocks_queued++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up IN transfer of buffer 1.
|
||||||
|
if ( usb_bulk_buffer_offset < 16384 && phase == 0) {
|
||||||
|
transfer = true;
|
||||||
|
buffer = &usb_bulk_buffer[0x4000];
|
||||||
|
phase = 1;
|
||||||
|
blocks_queued++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transfer) {
|
||||||
|
*(uint16_t*)buffer = 0x7F7F;
|
||||||
|
*(uint16_t*)(buffer+2) = sweep_freq;
|
||||||
|
usb_transfer_schedule_block(
|
||||||
|
&usb_endpoint_bulk_in,
|
||||||
|
buffer,
|
||||||
|
0x4000,
|
||||||
|
NULL, NULL
|
||||||
|
);
|
||||||
|
transfer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blocks_queued >= dwell_blocks) {
|
||||||
|
if(++ifreq >= frequency_count)
|
||||||
|
ifreq = 0;
|
||||||
|
sweep_freq = frequencies[ifreq];
|
||||||
|
set_freq(sweep_freq*FREQ_GRANULARITY);
|
||||||
|
blocks_queued = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
firmware/hackrf_usb/usb_api_sweep.h
Normal file
36
firmware/hackrf_usb/usb_api_sweep.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Mike Walters, Dominic Spill
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __USB_API_SCAN_H__
|
||||||
|
#define __USB_API_SCAN_H__
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <usb_type.h>
|
||||||
|
#include <usb_request.h>
|
||||||
|
|
||||||
|
extern volatile bool start_sweep_mode;
|
||||||
|
|
||||||
|
usb_request_status_t usb_vendor_request_init_sweep(
|
||||||
|
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage);
|
||||||
|
|
||||||
|
void sweep_mode(void);
|
||||||
|
|
||||||
|
#endif /* __USB_API_SPCAN_H__ */
|
@ -23,10 +23,16 @@
|
|||||||
#include "usb_api_transceiver.h"
|
#include "usb_api_transceiver.h"
|
||||||
|
|
||||||
#include "hackrf-ui.h"
|
#include "hackrf-ui.h"
|
||||||
|
#include <libopencm3/cm3/vector.h>
|
||||||
|
#include <libopencm3/lpc43xx/m4/nvic.h>
|
||||||
|
#include "sgpio_isr.h"
|
||||||
|
|
||||||
|
#include "usb_api_cpld.h" // Remove when CPLD update is handled elsewhere
|
||||||
|
|
||||||
#include <max2837.h>
|
#include <max2837.h>
|
||||||
#include <rf_path.h>
|
#include <rf_path.h>
|
||||||
#include <tuning.h>
|
#include <tuning.h>
|
||||||
|
#include <streaming.h>
|
||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
#include <usb_queue.h>
|
#include <usb_queue.h>
|
||||||
|
|
||||||
@ -226,3 +232,105 @@ usb_request_status_t usb_vendor_request_set_freq_explicit(
|
|||||||
return USB_REQUEST_STATUS_OK;
|
return USB_REQUEST_STATUS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static volatile transceiver_mode_t _transceiver_mode = TRANSCEIVER_MODE_OFF;
|
||||||
|
static volatile hw_sync_mode_t _hw_sync_mode = HW_SYNC_MODE_OFF;
|
||||||
|
|
||||||
|
void set_hw_sync_mode(const hw_sync_mode_t new_hw_sync_mode) {
|
||||||
|
_hw_sync_mode = new_hw_sync_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
transceiver_mode_t transceiver_mode(void) {
|
||||||
|
return _transceiver_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) {
|
||||||
|
baseband_streaming_disable(&sgpio_config);
|
||||||
|
|
||||||
|
usb_endpoint_disable(&usb_endpoint_bulk_in);
|
||||||
|
usb_endpoint_disable(&usb_endpoint_bulk_out);
|
||||||
|
|
||||||
|
_transceiver_mode = new_transceiver_mode;
|
||||||
|
|
||||||
|
if( _transceiver_mode == TRANSCEIVER_MODE_RX ) {
|
||||||
|
led_off(LED3);
|
||||||
|
led_on(LED2);
|
||||||
|
usb_endpoint_init(&usb_endpoint_bulk_in);
|
||||||
|
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_RX);
|
||||||
|
vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx;
|
||||||
|
} else if (_transceiver_mode == TRANSCEIVER_MODE_TX) {
|
||||||
|
led_off(LED2);
|
||||||
|
led_on(LED3);
|
||||||
|
usb_endpoint_init(&usb_endpoint_bulk_out);
|
||||||
|
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_TX);
|
||||||
|
vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_tx;
|
||||||
|
} else {
|
||||||
|
led_off(LED2);
|
||||||
|
led_off(LED3);
|
||||||
|
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_OFF);
|
||||||
|
vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx;
|
||||||
|
|
||||||
|
hw_sync_stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
hw_sync_stop();
|
||||||
|
|
||||||
|
if( _transceiver_mode != TRANSCEIVER_MODE_OFF ) {
|
||||||
|
si5351c_activate_best_clock_source(&clock_gen);
|
||||||
|
|
||||||
|
if( _hw_sync_mode != HW_SYNC_MODE_OFF) {
|
||||||
|
hw_sync_syn();
|
||||||
|
} else {
|
||||||
|
baseband_streaming_enable(&sgpio_config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
usb_request_status_t usb_vendor_request_set_transceiver_mode(
|
||||||
|
usb_endpoint_t* const endpoint,
|
||||||
|
const usb_transfer_stage_t stage)
|
||||||
|
{
|
||||||
|
if( stage == USB_TRANSFER_STAGE_SETUP ) {
|
||||||
|
switch( endpoint->setup.value ) {
|
||||||
|
case TRANSCEIVER_MODE_OFF:
|
||||||
|
case TRANSCEIVER_MODE_RX:
|
||||||
|
case TRANSCEIVER_MODE_TX:
|
||||||
|
set_transceiver_mode(endpoint->setup.value);
|
||||||
|
usb_transfer_schedule_ack(endpoint->in);
|
||||||
|
return USB_REQUEST_STATUS_OK;
|
||||||
|
case TRANSCEIVER_MODE_CPLD_UPDATE:
|
||||||
|
usb_endpoint_init(&usb_endpoint_bulk_out);
|
||||||
|
start_cpld_update = true;
|
||||||
|
usb_transfer_schedule_ack(endpoint->in);
|
||||||
|
return USB_REQUEST_STATUS_OK;
|
||||||
|
default:
|
||||||
|
return USB_REQUEST_STATUS_STALL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return USB_REQUEST_STATUS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
usb_request_status_t usb_vendor_request_set_hw_sync_mode(
|
||||||
|
usb_endpoint_t* const endpoint,
|
||||||
|
const usb_transfer_stage_t stage)
|
||||||
|
{
|
||||||
|
if( stage == USB_TRANSFER_STAGE_SETUP ) {
|
||||||
|
set_hw_sync_mode(endpoint->setup.value);
|
||||||
|
usb_transfer_schedule_ack(endpoint->in);
|
||||||
|
return USB_REQUEST_STATUS_OK;
|
||||||
|
} else {
|
||||||
|
return USB_REQUEST_STATUS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void start_streaming_on_hw_sync()
|
||||||
|
{
|
||||||
|
if( _hw_sync_mode != HW_SYNC_MODE_OFF) {
|
||||||
|
while(!hw_sync_ready()) { }
|
||||||
|
hw_sync_ack();
|
||||||
|
led_on(LED3);
|
||||||
|
|
||||||
|
baseband_streaming_enable(&sgpio_config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <usb_type.h>
|
#include <usb_type.h>
|
||||||
#include <usb_request.h>
|
#include <usb_request.h>
|
||||||
|
|
||||||
|
void set_hw_sync_mode(const hw_sync_mode_t new_hw_sync_mode);
|
||||||
usb_request_status_t usb_vendor_request_set_transceiver_mode(
|
usb_request_status_t usb_vendor_request_set_transceiver_mode(
|
||||||
usb_endpoint_t* const endpoint,
|
usb_endpoint_t* const endpoint,
|
||||||
const usb_transfer_stage_t stage);
|
const usb_transfer_stage_t stage);
|
||||||
@ -52,5 +53,11 @@ 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_request_status_t usb_vendor_request_set_freq_explicit(
|
||||||
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_hw_sync_mode(
|
||||||
|
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage);
|
||||||
|
|
||||||
|
transceiver_mode_t transceiver_mode(void);
|
||||||
|
void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode);
|
||||||
|
void start_streaming_on_hw_sync();
|
||||||
|
|
||||||
#endif/*__USB_API_TRANSCEIVER_H__*/
|
#endif/*__USB_API_TRANSCEIVER_H__*/
|
||||||
|
Submodule firmware/libopencm3 updated: 50c51c7b5f...d3d6f3e74b
@ -46,20 +46,20 @@ void tx_test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void rx_test() {
|
void rx_test() {
|
||||||
volatile uint32_t buffer[4096];
|
volatile uint32_t buffer[4096];
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
uint32_t magsq;
|
uint32_t magsq;
|
||||||
int8_t sigi, sigq;
|
int8_t sigi, sigq;
|
||||||
|
|
||||||
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_RX);
|
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_RX);
|
||||||
sgpio_cpld_stream_enable(&sgpio_config);
|
sgpio_cpld_stream_enable(&sgpio_config);
|
||||||
|
|
||||||
led_on(LED2);
|
led_on(LED2);
|
||||||
while(true) {
|
while(true) {
|
||||||
while(SGPIO_STATUS_1 == 0);
|
while(SGPIO_STATUS_1 == 0);
|
||||||
led_on(LED1);
|
led_on(LED1);
|
||||||
SGPIO_CLR_STATUS_1 = 1;
|
SGPIO_CLR_STATUS_1 = 1;
|
||||||
buffer[i & 4095] = SGPIO_REG_SS(SGPIO_SLICE_A);
|
buffer[i & 4095] = SGPIO_REG_SS(SGPIO_SLICE_A);
|
||||||
|
|
||||||
/* find the magnitude squared */
|
/* find the magnitude squared */
|
||||||
sigi = buffer[i & 4095] & 0xff;
|
sigi = buffer[i & 4095] & 0xff;
|
||||||
@ -72,7 +72,7 @@ void rx_test() {
|
|||||||
else
|
else
|
||||||
led_off(LED3);
|
led_off(LED3);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
@ -86,7 +86,7 @@ int main(void) {
|
|||||||
enable_rf_power();
|
enable_rf_power();
|
||||||
#endif
|
#endif
|
||||||
cpu_clock_init();
|
cpu_clock_init();
|
||||||
rf_path_init(&rf_path);
|
rf_path_init(&rf_path);
|
||||||
|
|
||||||
set_freq(freq);
|
set_freq(freq);
|
||||||
|
|
||||||
|
109
host/README.md
109
host/README.md
@ -4,34 +4,34 @@ produce a low cost, open source software radio platform.
|
|||||||
##How to build the host software on Linux:
|
##How to build the host software on Linux:
|
||||||
|
|
||||||
###Prerequisites for Linux (Debian/Ubuntu):
|
###Prerequisites for Linux (Debian/Ubuntu):
|
||||||
|
`sudo apt-get install build-essential cmake libusb-1.0-0-dev pkg-config libfftw3-dev`
|
||||||
`sudo apt-get install build-essential cmake libusb-1.0-0-dev pkg-config`
|
|
||||||
|
|
||||||
###Build host software on Linux:
|
###Build host software on Linux:
|
||||||
|
```
|
||||||
|
mkdir host/build
|
||||||
|
cd host/build
|
||||||
|
cmake ..
|
||||||
|
make
|
||||||
|
sudo make install
|
||||||
|
sudo ldconfig
|
||||||
|
```
|
||||||
|
|
||||||
`cd host`
|
By defualt this will attempt to install a udev rule to '/etc/udev/rules.d` to
|
||||||
|
provide the `usb` or `plugdev` group access to HackRF. If your setup requires
|
||||||
|
the udev rule to be installed elsewhere you can modify the path with
|
||||||
|
`-DUDEV_RULES_PATH=/path/to/udev`.
|
||||||
|
|
||||||
`mkdir build`
|
Note: The udev rule is not installed for by default for PyBOMBS installs as
|
||||||
|
they do not ususally get installed with root privileges.
|
||||||
`cd build`
|
|
||||||
|
|
||||||
`cmake ../ -DINSTALL_UDEV_RULES=ON`
|
|
||||||
|
|
||||||
`make`
|
|
||||||
|
|
||||||
`sudo make install`
|
|
||||||
|
|
||||||
`sudo ldconfig`
|
|
||||||
|
|
||||||
##Clean CMake temporary files/dirs:
|
##Clean CMake temporary files/dirs:
|
||||||
|
```
|
||||||
`cd host/build`
|
cd host/build
|
||||||
|
rm -rf *
|
||||||
`rm -rf *`
|
```
|
||||||
|
|
||||||
##How to build host software on Windows:
|
##How to build host software on Windows:
|
||||||
|
###Prerequisites for cygwin, mingw, or Visual Studio:
|
||||||
###Prerequisites for cygwin or mingw:
|
|
||||||
|
|
||||||
* cmake-2.8.12.1 or more see http://www.cmake.org/cmake/resources/software.html
|
* cmake-2.8.12.1 or more see http://www.cmake.org/cmake/resources/software.html
|
||||||
* libusbx-1.0.18 or more see http://sourceforge.net/projects/libusbx/files/latest/download?source=files
|
* libusbx-1.0.18 or more see http://sourceforge.net/projects/libusbx/files/latest/download?source=files
|
||||||
@ -43,56 +43,45 @@ produce a low cost, open source software radio platform.
|
|||||||
Ctrl C is not managed correctly and especially for hackrf_transfer the Ctrl C(abort) will not stop correctly and will corrupt the file.
|
Ctrl C is not managed correctly and especially for hackrf_transfer the Ctrl C(abort) will not stop correctly and will corrupt the file.
|
||||||
|
|
||||||
###For Cygwin:
|
###For Cygwin:
|
||||||
|
```
|
||||||
`cd host`
|
mkdir host/build
|
||||||
|
cd host/build
|
||||||
`mkdir build`
|
cmake ../ -G "Unix Makefiles" -DCMAKE_LEGACY_CYGWIN_WIN32=1 -DLIBUSB_INCLUDE_DIR=/usr/local/include/libusb-1.0/
|
||||||
|
make
|
||||||
`cd build`
|
make install
|
||||||
|
```
|
||||||
`cmake ../ -G "Unix Makefiles" -DCMAKE_LEGACY_CYGWIN_WIN32=1 -DLIBUSB_INCLUDE_DIR=/usr/local/include/libusb-1.0/`
|
|
||||||
|
|
||||||
`make`
|
|
||||||
|
|
||||||
`make install`
|
|
||||||
|
|
||||||
|
|
||||||
###For MinGW:
|
###For MinGW:
|
||||||
|
```
|
||||||
|
mkdir host/build
|
||||||
|
cd host/build
|
||||||
|
cmake ../ -G "MSYS Makefiles" -DLIBUSB_INCLUDE_DIR=/usr/local/include/libusb-1.0/
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
`cd host`
|
###For Visual Studio 2015 x64
|
||||||
|
```
|
||||||
|
c:\hackrf\host\build> cmake ../ -G "Visual Studio 14 2015 Win64" \
|
||||||
|
-DLIBUSB_INCLUDE_DIR=c:\libusb-1.0.18-win\include\libusb-1.0 \
|
||||||
|
-DLIBUSB_LIBRARIES=c:\libusb-1.0.18-win\MS64\static\libusb-1.0.lib \
|
||||||
|
-DTHREADS_PTHREADS_INCLUDE_DIR=c:\pthreads-w32-2-9-1-release\Pre-built.2\include \
|
||||||
|
-DTHREADS_PTHREADS_WIN32_LIBRARY=c:\pthreads-w32-2-9-1-release\Pre-built.2\lib\x64\pthreadVC2.lib
|
||||||
|
```
|
||||||
|
|
||||||
`mkdir build`
|
Cmake will produce a solution file named `hackrf_all.sln` and a series of
|
||||||
|
project files which can be used with msbuild as follows:
|
||||||
`cd build`
|
`c:\hackrf\host\build> msbuild ALL_BUILD.vcxproj`
|
||||||
|
|
||||||
Normal version:
|
|
||||||
|
|
||||||
*
|
|
||||||
`cmake ../ -G "MSYS Makefiles" -DLIBUSB_INCLUDE_DIR=/usr/local/include/libusb-1.0/`
|
|
||||||
|
|
||||||
Debug version:
|
|
||||||
|
|
||||||
*
|
|
||||||
`cmake ../ -G "MSYS Makefiles" -DCMAKE_BUILD_TYPE=Debug -DLIBUSB_INCLUDE_DIR=/usr/local/include/libusb-1.0/`
|
|
||||||
|
|
||||||
`make`
|
|
||||||
|
|
||||||
`make install`
|
|
||||||
|
|
||||||
###For Visual Studio 2012 x64
|
|
||||||
`c:\hackrf\host\cmake>cmake ../ -G "Visual Studio 11 2012 Win64" -DLIBUSB_INCLUDE_DIR=c:\libusb-1.0.18-win\include\libusb-1.0 -DLIBUSB_LIBRARIES=c:\libusb-1.0.18-win\MS64\static\libusb-1.0.lib -DTHREADS_PTHREADS_INCLUDE_DIR=c:\pthreads-w32-2-9-1-release\Pre-built.2\include -DTHREADS_PTHREADS_WIN32_LIBRARY=c:\pthreads-w32-2-9-1-release\Pre-built.2\lib\x64\pthreadVC2.lib`
|
|
||||||
|
|
||||||
Solution file: `c:\hackrf\host\cmake\hackrf_all.sln`
|
|
||||||
|
|
||||||
##How to build host the software on FreeBSD
|
##How to build host the software on FreeBSD
|
||||||
|
|
||||||
You can use the binary package:
|
You can use the binary package:
|
||||||
`# pkg install hackrf`
|
`# pkg install hackrf`
|
||||||
|
|
||||||
You can build and install from ports:
|
You can build and install from ports:
|
||||||
`# cd /usr/ports/comms/hackrf`
|
```
|
||||||
`# make install`
|
# cd /usr/ports/comms/hackrf
|
||||||
|
# make install
|
||||||
|
```
|
||||||
|
|
||||||
principal author: Michael Ossmann <mike@ossmann.com>
|
principal author: Michael Ossmann <mike@ossmann.com>
|
||||||
|
|
||||||
|
22
host/cmake/modules/FindFFTW.cmake
Normal file
22
host/cmake/modules/FindFFTW.cmake
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# - Find FFTW
|
||||||
|
# Find the native FFTW includes and library
|
||||||
|
#
|
||||||
|
# FFTW_INCLUDES - where to find fftw3.h
|
||||||
|
# FFTW_LIBRARIES - List of libraries when using FFTW.
|
||||||
|
# FFTW_FOUND - True if FFTW found.
|
||||||
|
|
||||||
|
if (FFTW_INCLUDES)
|
||||||
|
# Already in cache, be silent
|
||||||
|
set (FFTW_FIND_QUIETLY TRUE)
|
||||||
|
endif (FFTW_INCLUDES)
|
||||||
|
|
||||||
|
find_path (FFTW_INCLUDES fftw3.h)
|
||||||
|
|
||||||
|
find_library (FFTW_LIBRARIES NAMES fftw3)
|
||||||
|
|
||||||
|
# handle the QUIETLY and REQUIRED arguments and set FFTW_FOUND to TRUE if
|
||||||
|
# all listed variables are TRUE
|
||||||
|
include (FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args (FFTW DEFAULT_MSG FFTW_LIBRARIES FFTW_INCLUDES)
|
||||||
|
|
||||||
|
mark_as_advanced (FFTW_LIBRARIES FFTW_INCLUDES)
|
@ -24,7 +24,7 @@
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
project(hackrf-tools C)
|
project(hackrf-tools C)
|
||||||
set(MAJOR_VERSION 0)
|
set(MAJOR_VERSION 0)
|
||||||
set(MINOR_VERSION 4)
|
set(MINOR_VERSION 5)
|
||||||
set(PACKAGE hackrf-tools)
|
set(PACKAGE hackrf-tools)
|
||||||
set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION})
|
set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION})
|
||||||
set(VERSION ${VERSION_STRING})
|
set(VERSION ${VERSION_STRING})
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
This repository contains hardware designs and software for HackRF, a project to
|
|
||||||
produce a low cost, open source software radio platform.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
How to build host software on Windows:
|
|
||||||
prerequisite for cygwin or mingw:
|
|
||||||
* cmake-2.8.10.2 or more see http://www.cmake.org/cmake/resources/software.html
|
|
||||||
* libusbx-1.0.14 or more see http://sourceforge.net/projects/libusbx/files/latest/download?source=files
|
|
||||||
* Install Windows driver for HackRF hardware or use Zadig see http://sourceforge.net/projects/libwdi/files/zadig
|
|
||||||
- If you want to use Zadig select HackRF USB device and just install/replace it with WinUSB driver.
|
|
||||||
* Build libhackrf before to build this library, see host/libhackrf/Readme.md.
|
|
||||||
|
|
||||||
For Cygwin:
|
|
||||||
cmake -G "Unix Makefiles" -DCMAKE_LEGACY_CYGWIN_WIN32=1 -DLIBUSB_INCLUDE_DIR=/usr/local/include/libusb-1.0/
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
|
|
||||||
For Mingw:
|
|
||||||
#normal version
|
|
||||||
cmake -G "MSYS Makefiles" -DLIBUSB_INCLUDE_DIR=/usr/local/include/libusb-1.0/
|
|
||||||
#debug version
|
|
||||||
cmake -G "MSYS Makefiles" -DCMAKE_BUILD_TYPE=Debug -DLIBUSB_INCLUDE_DIR=/usr/local/include/libusb-1.0/
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
|
|
||||||
How to build host software on Linux:
|
|
||||||
cmake ./
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
|
|
||||||
principal author: Michael Ossmann <mike@ossmann.com>
|
|
||||||
|
|
||||||
http://greatscottgadgets.com/hackrf/
|
|
@ -23,10 +23,16 @@
|
|||||||
|
|
||||||
set(INSTALL_DEFAULT_BINDIR "bin" CACHE STRING "Appended to CMAKE_INSTALL_PREFIX")
|
set(INSTALL_DEFAULT_BINDIR "bin" CACHE STRING "Appended to CMAKE_INSTALL_PREFIX")
|
||||||
|
|
||||||
|
INCLUDE(FindPkgConfig)
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
add_library(libgetopt_static STATIC
|
add_library(libgetopt_static STATIC
|
||||||
../getopt/getopt.c
|
../getopt/getopt.c
|
||||||
)
|
)
|
||||||
|
else()
|
||||||
|
pkg_check_modules(FFTW REQUIRED fftw3f)
|
||||||
|
LIST(APPEND TOOLS hackrf_sweep)
|
||||||
|
LIST(APPEND TOOLS_LINK_LIBS m fftw3f)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
SET(TOOLS
|
SET(TOOLS
|
||||||
@ -37,6 +43,7 @@ SET(TOOLS
|
|||||||
hackrf_spiflash
|
hackrf_spiflash
|
||||||
hackrf_cpldjtag
|
hackrf_cpldjtag
|
||||||
hackrf_info
|
hackrf_info
|
||||||
|
hackrf_operacake
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT libhackrf_SOURCE_DIR)
|
if(NOT libhackrf_SOURCE_DIR)
|
||||||
@ -55,4 +62,3 @@ foreach(tool ${TOOLS})
|
|||||||
target_link_libraries(${tool} ${TOOLS_LINK_LIBS})
|
target_link_libraries(${tool} ${TOOLS_LINK_LIBS})
|
||||||
install(TARGETS ${tool} RUNTIME DESTINATION ${INSTALL_DEFAULT_BINDIR})
|
install(TARGETS ${tool} RUNTIME DESTINATION ${INSTALL_DEFAULT_BINDIR})
|
||||||
endforeach(tool)
|
endforeach(tool)
|
||||||
|
|
||||||
|
@ -32,9 +32,10 @@ int main(void)
|
|||||||
uint8_t board_id = BOARD_ID_INVALID;
|
uint8_t board_id = BOARD_ID_INVALID;
|
||||||
char version[255 + 1];
|
char version[255 + 1];
|
||||||
read_partid_serialno_t read_partid_serialno;
|
read_partid_serialno_t read_partid_serialno;
|
||||||
|
uint8_t operacakes[8];
|
||||||
hackrf_device_list_t *list;
|
hackrf_device_list_t *list;
|
||||||
hackrf_device* device;
|
hackrf_device* device;
|
||||||
int i;
|
int i, j;
|
||||||
|
|
||||||
result = hackrf_init();
|
result = hackrf_init();
|
||||||
if (result != HACKRF_SUCCESS) {
|
if (result != HACKRF_SUCCESS) {
|
||||||
@ -99,6 +100,19 @@ int main(void)
|
|||||||
read_partid_serialno.serial_no[2],
|
read_partid_serialno.serial_no[2],
|
||||||
read_partid_serialno.serial_no[3]);
|
read_partid_serialno.serial_no[3]);
|
||||||
|
|
||||||
|
result = hackrf_get_operacake_boards(device, &operacakes[0]);
|
||||||
|
if (result != HACKRF_SUCCESS) {
|
||||||
|
fprintf(stderr, "hackrf_get_operacake_boards() failed: %s (%d)\n",
|
||||||
|
hackrf_error_name(result), result);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
for(j=0; j<8; j++) {
|
||||||
|
if(operacakes[j] == 0)
|
||||||
|
break;
|
||||||
|
printf("Operacake found, address: 0x%02x\n", operacakes[j]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
result = hackrf_close(device);
|
result = hackrf_close(device);
|
||||||
if (result != HACKRF_SUCCESS) {
|
if (result != HACKRF_SUCCESS) {
|
||||||
fprintf(stderr, "hackrf_close() failed: %s (%d)\n",
|
fprintf(stderr, "hackrf_close() failed: %s (%d)\n",
|
||||||
|
158
host/hackrf-tools/src/hackrf_operacake.c
Normal file
158
host/hackrf-tools/src/hackrf_operacake.c
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Dominic Spill <dominicgs@gmail.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 <hackrf.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
#ifndef bool
|
||||||
|
typedef int bool;
|
||||||
|
#define true 1
|
||||||
|
#define false 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void usage() {
|
||||||
|
printf("\nUsage:\n");
|
||||||
|
printf("\t-s, --serial <s>: specify a particular device by serial number\n");
|
||||||
|
printf("\t-d, --device <n>: specify a particular device by number\n");
|
||||||
|
printf("\t-o, --address <n>: specify a particular operacake by address [default: 0x00]\n");
|
||||||
|
printf("\t-a <n>: set port A connection\n");
|
||||||
|
printf("\t-b <n>: set port B connection\n");
|
||||||
|
printf("\t-v: verbose, list available operacake boards\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{ "device", no_argument, 0, 'd' },
|
||||||
|
{ "serial", no_argument, 0, 's' },
|
||||||
|
{ "address", no_argument, 0, 'o' },
|
||||||
|
{ 0, 0, 0, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
int parse_int(char* const s, uint16_t* const value) {
|
||||||
|
char* s_end = s;
|
||||||
|
const long long_value = strtol(s, &s_end, 10);
|
||||||
|
if( (s != s_end) && (*s_end == 0) ) {
|
||||||
|
*value = (uint16_t)long_value;
|
||||||
|
return HACKRF_SUCCESS;
|
||||||
|
} else {
|
||||||
|
return HACKRF_ERROR_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
int opt;
|
||||||
|
const char* serial_number = NULL;
|
||||||
|
int device_index = 0;
|
||||||
|
int operacake_address = 0;
|
||||||
|
int port_a = 0;
|
||||||
|
int port_b = 0;
|
||||||
|
int verbose = 0;
|
||||||
|
uint8_t operacakes[8];
|
||||||
|
int i = 0;
|
||||||
|
hackrf_device* device = NULL;
|
||||||
|
int option_index = 0;
|
||||||
|
|
||||||
|
int result = hackrf_init();
|
||||||
|
if( result ) {
|
||||||
|
printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( (opt = getopt_long(argc, argv, "d:s:o:a:b:v", long_options, &option_index)) != EOF ) {
|
||||||
|
switch( opt ) {
|
||||||
|
case 'd':
|
||||||
|
device_index = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
serial_number = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'o':
|
||||||
|
operacake_address = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'a':
|
||||||
|
port_a = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
port_b = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'v':
|
||||||
|
verbose = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( result != HACKRF_SUCCESS ) {
|
||||||
|
printf("argument error: %s (%d)\n", hackrf_error_name(result), result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(serial_number != NULL) {
|
||||||
|
result = hackrf_open_by_serial(serial_number, &device);
|
||||||
|
} else {
|
||||||
|
hackrf_device_list_t* device_list = hackrf_device_list();
|
||||||
|
if(device_list->devicecount <= 0) {
|
||||||
|
result = HACKRF_ERROR_NOT_FOUND;
|
||||||
|
} else {
|
||||||
|
result = hackrf_device_list_open(device_list, device_index, &device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( result ) {
|
||||||
|
printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(verbose) {
|
||||||
|
hackrf_get_operacake_boards(device, operacakes);
|
||||||
|
printf("Operacakes found:\n");
|
||||||
|
for(i=0; i<8; i++) {
|
||||||
|
if(operacakes[i] !=0)
|
||||||
|
printf("%d\n", operacakes[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
result = hackrf_set_operacake_ports(device, operacake_address, port_a, port_b);
|
||||||
|
if( result ) {
|
||||||
|
printf("hackrf_set_operacake_ports() failed: %s (%d)\n", hackrf_error_name(result), result);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = hackrf_close(device);
|
||||||
|
if( result ) {
|
||||||
|
printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hackrf_exit();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -91,6 +91,7 @@ static void usage()
|
|||||||
printf("\t-r <filename>: Read data into file.\n");
|
printf("\t-r <filename>: Read data into file.\n");
|
||||||
printf("\t-w <filename>: Write data from file.\n");
|
printf("\t-w <filename>: Write data from file.\n");
|
||||||
printf("\t-d <serialnumber>: Serial number of device, if multiple devices\n");
|
printf("\t-d <serialnumber>: Serial number of device, if multiple devices\n");
|
||||||
|
printf("\t-R: Reset HackRF after other operations.\n");
|
||||||
printf("\t-v: Verbose output.\n");
|
printf("\t-v: Verbose output.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,8 +113,9 @@ int main(int argc, char** argv)
|
|||||||
bool read = false;
|
bool read = false;
|
||||||
bool write = false;
|
bool write = false;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
|
bool reset = false;
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, "a:l:r:w:d:v", long_options,
|
while ((opt = getopt_long(argc, argv, "a:l:r:w:d:vR", long_options,
|
||||||
&option_index)) != EOF) {
|
&option_index)) != EOF) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'a':
|
case 'a':
|
||||||
@ -142,8 +144,16 @@ int main(int argc, char** argv)
|
|||||||
verbose = true;
|
verbose = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'R':
|
||||||
|
reset = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '?':
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "opt error: %d\n", opt);
|
fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg);
|
||||||
usage();
|
usage();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -156,18 +166,14 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write == read) {
|
if(write && read) {
|
||||||
if (write == true) {
|
fprintf(stderr, "Read and write options are mutually exclusive.\n");
|
||||||
fprintf(stderr, "Read and write options are mutually exclusive.\n");
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Specify either read or write option.\n");
|
|
||||||
}
|
|
||||||
usage();
|
usage();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path == NULL) {
|
if(!(write || read || reset)) {
|
||||||
fprintf(stderr, "Specify a path to a file.\n");
|
fprintf(stderr, "Specify either read, write, or reset option.\n");
|
||||||
usage();
|
usage();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -177,7 +183,7 @@ int main(int argc, char** argv)
|
|||||||
fd = fopen(path, "rb");
|
fd = fopen(path, "rb");
|
||||||
if(fd == NULL)
|
if(fd == NULL)
|
||||||
{
|
{
|
||||||
printf("Error to open file %s\n", path);
|
printf("Error opening file %s\n", path);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
/* Get size of the file */
|
/* Get size of the file */
|
||||||
@ -214,7 +220,7 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd == NULL) {
|
if((read || write) && (fd == NULL)) {
|
||||||
fprintf(stderr, "Failed to open file: %s\n", path);
|
fprintf(stderr, "Failed to open file: %s\n", path);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -233,8 +239,7 @@ int main(int argc, char** argv)
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read)
|
if(read) {
|
||||||
{
|
|
||||||
ssize_t bytes_written;
|
ssize_t bytes_written;
|
||||||
tmp_length = length;
|
tmp_length = length;
|
||||||
while (tmp_length)
|
while (tmp_length)
|
||||||
@ -261,7 +266,9 @@ int main(int argc, char** argv)
|
|||||||
fd = NULL;
|
fd = NULL;
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if(write) {
|
||||||
ssize_t bytes_read = fread(data, 1, length, fd);
|
ssize_t bytes_read = fread(data, 1, length, fd);
|
||||||
if (bytes_read != length) {
|
if (bytes_read != length) {
|
||||||
fprintf(stderr, "Failed read file (read %d bytes).\n",
|
fprintf(stderr, "Failed read file (read %d bytes).\n",
|
||||||
@ -297,6 +304,17 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(reset) {
|
||||||
|
result = hackrf_reset(device);
|
||||||
|
if (result != HACKRF_SUCCESS) {
|
||||||
|
fprintf(stderr, "hackrf_reset() failed: %s (%d)\n",
|
||||||
|
hackrf_error_name(result), result);
|
||||||
|
fclose(fd);
|
||||||
|
fd = NULL;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result = hackrf_close(device);
|
result = hackrf_close(device);
|
||||||
if (result != HACKRF_SUCCESS) {
|
if (result != HACKRF_SUCCESS) {
|
||||||
fprintf(stderr, "hackrf_close() failed: %s (%d)\n",
|
fprintf(stderr, "hackrf_close() failed: %s (%d)\n",
|
||||||
|
549
host/hackrf-tools/src/hackrf_sweep.c
Normal file
549
host/hackrf-tools/src/hackrf_sweep.c
Normal file
@ -0,0 +1,549 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Dominic Spill <dominicgs@gmail.com>
|
||||||
|
* Copyright 2016 Mike Walters <mike@flomp.net>
|
||||||
|
*
|
||||||
|
* 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 <hackrf.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fftw3.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
|
||||||
|
#ifndef bool
|
||||||
|
typedef int bool;
|
||||||
|
#define true 1
|
||||||
|
#define false 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
typedef int64_t ssize_t;
|
||||||
|
#else
|
||||||
|
typedef int32_t ssize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define strtoull _strtoui64
|
||||||
|
#define snprintf _snprintf
|
||||||
|
|
||||||
|
int gettimeofday(struct timeval *tv, void* ignored) {
|
||||||
|
FILETIME ft;
|
||||||
|
unsigned __int64 tmp = 0;
|
||||||
|
if (NULL != tv) {
|
||||||
|
GetSystemTimeAsFileTime(&ft);
|
||||||
|
tmp |= ft.dwHighDateTime;
|
||||||
|
tmp <<= 32;
|
||||||
|
tmp |= ft.dwLowDateTime;
|
||||||
|
tmp /= 10;
|
||||||
|
tmp -= 11644473600000000Ui64;
|
||||||
|
tv->tv_sec = (long)(tmp / 1000000UL);
|
||||||
|
tv->tv_usec = (long)(tmp % 1000000UL);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#define FD_BUFFER_SIZE (8*1024)
|
||||||
|
|
||||||
|
#define FREQ_ONE_MHZ (1000000ull)
|
||||||
|
|
||||||
|
#define FREQ_MIN_HZ (0ull) /* 0 Hz */
|
||||||
|
#define FREQ_MAX_HZ (7250000000ull) /* 7250MHz */
|
||||||
|
|
||||||
|
#define DEFAULT_SAMPLE_RATE_HZ (20000000) /* 20MHz default sample rate */
|
||||||
|
#define DEFAULT_BASEBAND_FILTER_BANDWIDTH (15000000) /* 5MHz default */
|
||||||
|
|
||||||
|
#define FREQ_STEP (DEFAULT_SAMPLE_RATE_HZ / FREQ_ONE_MHZ)
|
||||||
|
#define MAX_FREQ_COUNT 1000
|
||||||
|
|
||||||
|
#define DEFAULT_SAMPLE_COUNT 0x4000
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
#define sleep(a) Sleep( (a*1000) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_u32(char* s, uint32_t* const value) {
|
||||||
|
uint_fast8_t base = 10;
|
||||||
|
char* s_end;
|
||||||
|
uint64_t ulong_value;
|
||||||
|
|
||||||
|
if( strlen(s) > 2 ) {
|
||||||
|
if( s[0] == '0' ) {
|
||||||
|
if( (s[1] == 'x') || (s[1] == 'X') ) {
|
||||||
|
base = 16;
|
||||||
|
s += 2;
|
||||||
|
} else if( (s[1] == 'b') || (s[1] == 'B') ) {
|
||||||
|
base = 2;
|
||||||
|
s += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s_end = s;
|
||||||
|
ulong_value = strtoul(s, &s_end, base);
|
||||||
|
if( (s != s_end) && (*s_end == 0) ) {
|
||||||
|
*value = (uint32_t)ulong_value;
|
||||||
|
return HACKRF_SUCCESS;
|
||||||
|
} else {
|
||||||
|
return HACKRF_ERROR_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_u32_range(char* s, uint32_t* const value_min, uint32_t* const value_max) {
|
||||||
|
int result;
|
||||||
|
|
||||||
|
char *sep = strchr(s, ':');
|
||||||
|
if (!sep)
|
||||||
|
return HACKRF_ERROR_INVALID_PARAM;
|
||||||
|
|
||||||
|
*sep = 0;
|
||||||
|
|
||||||
|
result = parse_u32(s, value_min);
|
||||||
|
if (result != HACKRF_SUCCESS)
|
||||||
|
return result;
|
||||||
|
result = parse_u32(sep + 1, value_max);
|
||||||
|
if (result != HACKRF_SUCCESS)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
return HACKRF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
volatile bool do_exit = false;
|
||||||
|
|
||||||
|
FILE* fd = NULL;
|
||||||
|
volatile uint32_t byte_count = 0;
|
||||||
|
|
||||||
|
struct timeval time_start;
|
||||||
|
struct timeval t_start;
|
||||||
|
|
||||||
|
bool amp = false;
|
||||||
|
uint32_t amp_enable;
|
||||||
|
|
||||||
|
bool antenna = false;
|
||||||
|
uint32_t antenna_enable;
|
||||||
|
|
||||||
|
uint32_t freq_min;
|
||||||
|
uint32_t freq_max;
|
||||||
|
|
||||||
|
int fftSize;
|
||||||
|
fftwf_complex *fftwIn = NULL;
|
||||||
|
fftwf_complex *fftwOut = NULL;
|
||||||
|
fftwf_plan fftwPlan = NULL;
|
||||||
|
float* pwr;
|
||||||
|
float* window;
|
||||||
|
|
||||||
|
float logPower(fftwf_complex in, float scale)
|
||||||
|
{
|
||||||
|
float re = in[0] * scale;
|
||||||
|
float im = in[1] * scale;
|
||||||
|
float magsq = re * re + im * im;
|
||||||
|
return log2f(magsq) * 10.0f / log2(10.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rx_callback(hackrf_transfer* transfer) {
|
||||||
|
/* This is where we need to do interesting things with the samples
|
||||||
|
* FFT
|
||||||
|
* Throw away unused bins
|
||||||
|
* write output to pipe
|
||||||
|
*/
|
||||||
|
ssize_t bytes_to_write;
|
||||||
|
ssize_t bytes_written;
|
||||||
|
int8_t* buf;
|
||||||
|
float frequency;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
if( fd != NULL ) {
|
||||||
|
byte_count += transfer->valid_length;
|
||||||
|
bytes_to_write = transfer->valid_length;
|
||||||
|
buf = (int8_t*) transfer->buffer;
|
||||||
|
for(j=0; j<16; j++) {
|
||||||
|
if(buf[0] == 0x7F && buf[1] == 0x7F) {
|
||||||
|
frequency = *(uint16_t*)&buf[2];
|
||||||
|
}
|
||||||
|
/* copy to fftwIn as floats */
|
||||||
|
buf += 16384 - (fftSize * 2);
|
||||||
|
for(i=0; i < fftSize; i++) {
|
||||||
|
fftwIn[i][0] = buf[i*2] * window[i] * 1.0f / 128.0f;
|
||||||
|
fftwIn[i][1] = buf[i*2+1] * window[i] * 1.0f / 128.0f;
|
||||||
|
}
|
||||||
|
buf += fftSize * 2;
|
||||||
|
fftwf_execute(fftwPlan);
|
||||||
|
for (i=0; i < fftSize; i++) {
|
||||||
|
// Start from the middle of the FFTW array and wrap
|
||||||
|
// to rearrange the data
|
||||||
|
int k = i ^ (fftSize >> 1);
|
||||||
|
pwr[i] = logPower(fftwOut[k], 1.0f / fftSize);
|
||||||
|
}
|
||||||
|
fwrite(&frequency, sizeof(float), 1, stdout);
|
||||||
|
fwrite(pwr, sizeof(float), fftSize, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes_written = fwrite(transfer->buffer, 1, bytes_to_write, fd);
|
||||||
|
if (bytes_written != bytes_to_write) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usage() {
|
||||||
|
fprintf(stderr, "Usage:\n");
|
||||||
|
fprintf(stderr, "\t[-d serial_number] # Serial number of desired HackRF.\n");
|
||||||
|
fprintf(stderr, "\t[-a amp_enable] # RX/TX RF amplifier 1=Enable, 0=Disable.\n");
|
||||||
|
fprintf(stderr, "\t[-f freq_min:freq_max # Specify minimum & maximum sweep frequencies (MHz).\n");
|
||||||
|
fprintf(stderr, "\t[-p antenna_enable] # Antenna port power, 1=Enable, 0=Disable.\n");
|
||||||
|
fprintf(stderr, "\t[-l gain_db] # RX LNA (IF) gain, 0-40dB, 8dB steps\n");
|
||||||
|
fprintf(stderr, "\t[-g gain_db] # RX VGA (baseband) gain, 0-62dB, 2dB steps\n");
|
||||||
|
fprintf(stderr, "\t[-x gain_db] # TX VGA (IF) gain, 0-47dB, 1dB steps\n");
|
||||||
|
fprintf(stderr, "\t[-n num_samples] # Number of samples per frequency, 0-4294967296\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static hackrf_device* device = NULL;
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
BOOL WINAPI
|
||||||
|
sighandler(int signum) {
|
||||||
|
if (CTRL_C_EVENT == signum) {
|
||||||
|
fprintf(stderr, "Caught signal %d\n", signum);
|
||||||
|
do_exit = true;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void sigint_callback_handler(int signum) {
|
||||||
|
fprintf(stderr, "Caught signal %d\n", signum);
|
||||||
|
do_exit = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
int opt, i, result, ifreq = 0;
|
||||||
|
bool odd;
|
||||||
|
const char* path = "/dev/null";
|
||||||
|
const char* serial_number = NULL;
|
||||||
|
int exit_code = EXIT_SUCCESS;
|
||||||
|
struct timeval t_end;
|
||||||
|
float time_diff;
|
||||||
|
unsigned int lna_gain=16, vga_gain=20, txvga_gain=0;
|
||||||
|
uint16_t frequencies[MAX_FREQ_COUNT];
|
||||||
|
uint32_t num_samples = DEFAULT_SAMPLE_COUNT;
|
||||||
|
|
||||||
|
while( (opt = getopt(argc, argv, "a:f:p:l:g:x:d:n:")) != EOF ) {
|
||||||
|
result = HACKRF_SUCCESS;
|
||||||
|
switch( opt )
|
||||||
|
{
|
||||||
|
case 'd':
|
||||||
|
serial_number = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'a':
|
||||||
|
amp = true;
|
||||||
|
result = parse_u32(optarg, &_enable);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
result = parse_u32_range(optarg, &freq_min, &freq_max);
|
||||||
|
fprintf(stderr, "Scanning %uMHz to %uMHz\n", freq_min, freq_max);
|
||||||
|
frequencies[ifreq++] = freq_min;
|
||||||
|
odd = true;
|
||||||
|
while(frequencies[ifreq-1] <= freq_max) {
|
||||||
|
if (odd)
|
||||||
|
frequencies[ifreq] = frequencies[ifreq-1] + FREQ_STEP / 4;
|
||||||
|
else
|
||||||
|
frequencies[ifreq] = frequencies[ifreq-1] + 3*(FREQ_STEP/4);
|
||||||
|
ifreq++;
|
||||||
|
odd = !odd;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
antenna = true;
|
||||||
|
result = parse_u32(optarg, &antenna_enable);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
result = parse_u32(optarg, &lna_gain);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'g':
|
||||||
|
result = parse_u32(optarg, &vga_gain);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'x':
|
||||||
|
result = parse_u32(optarg, &txvga_gain);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'n':
|
||||||
|
result = parse_u32(optarg, &num_samples);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg);
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( result != HACKRF_SUCCESS ) {
|
||||||
|
fprintf(stderr, "argument error: '-%c %s' %s (%d)\n", opt, optarg, hackrf_error_name(result), result);
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lna_gain % 8)
|
||||||
|
fprintf(stderr, "warning: lna_gain (-l) must be a multiple of 8\n");
|
||||||
|
|
||||||
|
if (vga_gain % 2)
|
||||||
|
fprintf(stderr, "warning: vga_gain (-g) must be a multiple of 2\n");
|
||||||
|
|
||||||
|
if (num_samples % 0x4000) {
|
||||||
|
fprintf(stderr, "warning: num_samples (-n) must be a multiple of 16384\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( amp ) {
|
||||||
|
if( amp_enable > 1 ) {
|
||||||
|
fprintf(stderr, "argument error: amp_enable shall be 0 or 1.\n");
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (antenna) {
|
||||||
|
if (antenna_enable > 1) {
|
||||||
|
fprintf(stderr, "argument error: antenna_enable shall be 0 or 1.\n");
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ifreq == 0) {
|
||||||
|
fprintf(stderr, "argument error: must specify sweep frequency range (-f).\n");
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fftSize = 64;
|
||||||
|
fftwIn = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize);
|
||||||
|
fftwOut = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize);
|
||||||
|
fftwPlan = fftwf_plan_dft_1d(fftSize, fftwIn, fftwOut, FFTW_FORWARD, FFTW_MEASURE);
|
||||||
|
pwr = (float*)fftwf_malloc(sizeof(float) * fftSize);
|
||||||
|
window = (float*)fftwf_malloc(sizeof(float) * fftSize);
|
||||||
|
for (i = 0; i < fftSize; i++) {
|
||||||
|
window[i] = 0.5f * (1.0f - cos(2 * M_PI * i / (fftSize - 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
result = hackrf_init();
|
||||||
|
if( result != HACKRF_SUCCESS ) {
|
||||||
|
fprintf(stderr, "hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result);
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = hackrf_open_by_serial(serial_number, &device);
|
||||||
|
if( result != HACKRF_SUCCESS ) {
|
||||||
|
fprintf(stderr, "hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result);
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = fopen(path, "wb");
|
||||||
|
if( fd == NULL ) {
|
||||||
|
fprintf(stderr, "Failed to open file: %s\n", path);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
/* Change fd buffer to have bigger one to store or read data on/to HDD */
|
||||||
|
result = setvbuf(fd , NULL , _IOFBF , FD_BUFFER_SIZE);
|
||||||
|
if( result != 0 ) {
|
||||||
|
fprintf(stderr, "setvbuf() failed: %d\n", result);
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
SetConsoleCtrlHandler( (PHANDLER_ROUTINE) sighandler, TRUE );
|
||||||
|
#else
|
||||||
|
signal(SIGINT, &sigint_callback_handler);
|
||||||
|
signal(SIGILL, &sigint_callback_handler);
|
||||||
|
signal(SIGFPE, &sigint_callback_handler);
|
||||||
|
signal(SIGSEGV, &sigint_callback_handler);
|
||||||
|
signal(SIGTERM, &sigint_callback_handler);
|
||||||
|
signal(SIGABRT, &sigint_callback_handler);
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, "call hackrf_sample_rate_set(%.03f MHz)\n",
|
||||||
|
((float)DEFAULT_SAMPLE_RATE_HZ/(float)FREQ_ONE_MHZ));
|
||||||
|
result = hackrf_set_sample_rate_manual(device, DEFAULT_SAMPLE_RATE_HZ, 1);
|
||||||
|
if( result != HACKRF_SUCCESS ) {
|
||||||
|
fprintf(stderr, "hackrf_sample_rate_set() failed: %s (%d)\n",
|
||||||
|
hackrf_error_name(result), result);
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "call hackrf_baseband_filter_bandwidth_set(%.03f MHz)\n",
|
||||||
|
((float)DEFAULT_BASEBAND_FILTER_BANDWIDTH/(float)FREQ_ONE_MHZ));
|
||||||
|
result = hackrf_set_baseband_filter_bandwidth(device, DEFAULT_BASEBAND_FILTER_BANDWIDTH);
|
||||||
|
if( result != HACKRF_SUCCESS ) {
|
||||||
|
fprintf(stderr, "hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n",
|
||||||
|
hackrf_error_name(result), result);
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = hackrf_set_vga_gain(device, vga_gain);
|
||||||
|
result |= hackrf_set_lna_gain(device, lna_gain);
|
||||||
|
result |= hackrf_start_rx(device, rx_callback, NULL);
|
||||||
|
if (result != HACKRF_SUCCESS) {
|
||||||
|
fprintf(stderr, "hackrf_start_?x() failed: %s (%d)\n", hackrf_error_name(result), result);
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = hackrf_init_sweep(device, frequencies, ifreq, num_samples);
|
||||||
|
if( result != HACKRF_SUCCESS ) {
|
||||||
|
fprintf(stderr, "hackrf_init_sweep() failed: %s (%d)\n",
|
||||||
|
hackrf_error_name(result), result);
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amp) {
|
||||||
|
fprintf(stderr, "call hackrf_set_amp_enable(%u)\n", amp_enable);
|
||||||
|
result = hackrf_set_amp_enable(device, (uint8_t)amp_enable);
|
||||||
|
if (result != HACKRF_SUCCESS) {
|
||||||
|
fprintf(stderr, "hackrf_set_amp_enable() failed: %s (%d)\n",
|
||||||
|
hackrf_error_name(result), result);
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (antenna) {
|
||||||
|
fprintf(stderr, "call hackrf_set_antenna_enable(%u)\n", antenna_enable);
|
||||||
|
result = hackrf_set_antenna_enable(device, (uint8_t)antenna_enable);
|
||||||
|
if (result != HACKRF_SUCCESS) {
|
||||||
|
fprintf(stderr, "hackrf_set_antenna_enable() failed: %s (%d)\n",
|
||||||
|
hackrf_error_name(result), result);
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gettimeofday(&t_start, NULL);
|
||||||
|
gettimeofday(&time_start, NULL);
|
||||||
|
|
||||||
|
fprintf(stderr, "Stop with Ctrl-C\n");
|
||||||
|
while((hackrf_is_streaming(device) == HACKRF_TRUE) && (do_exit == false)) {
|
||||||
|
uint32_t byte_count_now;
|
||||||
|
struct timeval time_now;
|
||||||
|
float time_difference, rate;
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
gettimeofday(&time_now, NULL);
|
||||||
|
|
||||||
|
byte_count_now = byte_count;
|
||||||
|
byte_count = 0;
|
||||||
|
|
||||||
|
time_difference = TimevalDiff(&time_now, &time_start);
|
||||||
|
rate = (float)byte_count_now / time_difference;
|
||||||
|
fprintf(stderr, "%4.1f MiB / %5.3f sec = %4.1f MiB/second\n",
|
||||||
|
(byte_count_now / 1e6f), time_difference, (rate / 1e6f) );
|
||||||
|
|
||||||
|
time_start = time_now;
|
||||||
|
|
||||||
|
if (byte_count_now == 0) {
|
||||||
|
exit_code = EXIT_FAILURE;
|
||||||
|
fprintf(stderr, "\nCouldn't transfer any bytes for one second.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = hackrf_is_streaming(device);
|
||||||
|
if (do_exit) {
|
||||||
|
fprintf(stderr, "\nUser cancel, exiting...\n");
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "\nExiting... hackrf_is_streaming() result: %s (%d)\n",
|
||||||
|
hackrf_error_name(result), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
gettimeofday(&t_end, NULL);
|
||||||
|
time_diff = TimevalDiff(&t_end, &t_start);
|
||||||
|
fprintf(stderr, "Total time: %5.5f s\n", time_diff);
|
||||||
|
|
||||||
|
if(device != NULL) {
|
||||||
|
result = hackrf_stop_rx(device);
|
||||||
|
if(result != HACKRF_SUCCESS) {
|
||||||
|
fprintf(stderr, "hackrf_stop_rx() failed: %s (%d)\n",
|
||||||
|
hackrf_error_name(result), result);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "hackrf_stop_rx() done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
result = hackrf_close(device);
|
||||||
|
if(result != HACKRF_SUCCESS) {
|
||||||
|
fprintf(stderr, "hackrf_close() failed: %s (%d)\n",
|
||||||
|
hackrf_error_name(result), result);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "hackrf_close() done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
hackrf_exit();
|
||||||
|
fprintf(stderr, "hackrf_exit() done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fd != NULL) {
|
||||||
|
fclose(fd);
|
||||||
|
fd = NULL;
|
||||||
|
fprintf(stderr, "fclose(fd) done\n");
|
||||||
|
}
|
||||||
|
fprintf(stderr, "exit\n");
|
||||||
|
return exit_code;
|
||||||
|
}
|
@ -34,6 +34,8 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
|
||||||
#ifndef bool
|
#ifndef bool
|
||||||
typedef int bool;
|
typedef int bool;
|
||||||
#define true 1
|
#define true 1
|
||||||
@ -114,6 +116,11 @@ typedef enum {
|
|||||||
TRANSCEIVER_MODE_SS = 3,
|
TRANSCEIVER_MODE_SS = 3,
|
||||||
} transceiver_mode_t;
|
} transceiver_mode_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
HW_SYNC_MODE_OFF = 0,
|
||||||
|
HW_SYNC_MODE_ON = 1,
|
||||||
|
} hw_sync_mode_t;
|
||||||
|
|
||||||
/* WAVE or RIFF WAVE file format containing IQ 2x8bits data for HackRF compatible with SDR# Wav IQ file */
|
/* WAVE or RIFF WAVE file format containing IQ 2x8bits data for HackRF compatible with SDR# Wav IQ file */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -303,6 +310,8 @@ volatile uint32_t byte_count = 0;
|
|||||||
bool signalsource = false;
|
bool signalsource = false;
|
||||||
uint32_t amplitude = 0;
|
uint32_t amplitude = 0;
|
||||||
|
|
||||||
|
bool hw_sync = false;
|
||||||
|
|
||||||
bool receive = false;
|
bool receive = false;
|
||||||
bool receive_wav = false;
|
bool receive_wav = false;
|
||||||
uint64_t stream_size = 0;
|
uint64_t stream_size = 0;
|
||||||
@ -338,7 +347,7 @@ uint32_t sample_rate_hz;
|
|||||||
|
|
||||||
bool limit_num_samples = false;
|
bool limit_num_samples = false;
|
||||||
uint64_t samples_to_xfer = 0;
|
uint64_t samples_to_xfer = 0;
|
||||||
ssize_t bytes_to_xfer = 0;
|
size_t bytes_to_xfer = 0;
|
||||||
|
|
||||||
bool baseband_filter_bw = false;
|
bool baseband_filter_bw = false;
|
||||||
uint32_t baseband_filter_bw_hz = 0;
|
uint32_t baseband_filter_bw_hz = 0;
|
||||||
@ -349,9 +358,9 @@ bool crystal_correct = false;
|
|||||||
uint32_t crystal_correct_ppm ;
|
uint32_t crystal_correct_ppm ;
|
||||||
|
|
||||||
int rx_callback(hackrf_transfer* transfer) {
|
int rx_callback(hackrf_transfer* transfer) {
|
||||||
ssize_t bytes_to_write;
|
size_t bytes_to_write;
|
||||||
ssize_t bytes_written;
|
size_t bytes_written;
|
||||||
int i;
|
unsigned int i;
|
||||||
|
|
||||||
if( fd != NULL )
|
if( fd != NULL )
|
||||||
{
|
{
|
||||||
@ -370,25 +379,28 @@ int rx_callback(hackrf_transfer* transfer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stream_size>0){
|
if (stream_size>0){
|
||||||
if ((stream_size-1+stream_head-stream_tail)%stream_size <bytes_to_write){
|
#ifndef _WIN32
|
||||||
stream_drop++;
|
if ((stream_size-1+stream_head-stream_tail)%stream_size <bytes_to_write) {
|
||||||
}else{
|
stream_drop++;
|
||||||
if(stream_tail+bytes_to_write <= stream_size){
|
} else {
|
||||||
memcpy(stream_buf+stream_tail,transfer->buffer,bytes_to_write);
|
if(stream_tail+bytes_to_write <= stream_size) {
|
||||||
}else{
|
memcpy(stream_buf+stream_tail,transfer->buffer,bytes_to_write);
|
||||||
memcpy(stream_buf+stream_tail,transfer->buffer,(stream_size-stream_tail));
|
} else {
|
||||||
memcpy(stream_buf,transfer->buffer+(stream_size-stream_tail),bytes_to_write-(stream_size-stream_tail));
|
memcpy(stream_buf+stream_tail,transfer->buffer,(stream_size-stream_tail));
|
||||||
};
|
memcpy(stream_buf,transfer->buffer+(stream_size-stream_tail),bytes_to_write-(stream_size-stream_tail));
|
||||||
__atomic_store_n(&stream_tail,(stream_tail+bytes_to_write)%stream_size,__ATOMIC_RELEASE);
|
};
|
||||||
|
__atomic_store_n(&stream_tail,(stream_tail+bytes_to_write)%stream_size,__ATOMIC_RELEASE);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}else{
|
|
||||||
bytes_written = fwrite(transfer->buffer, 1, bytes_to_write, fd);
|
|
||||||
if ((bytes_written != bytes_to_write)
|
|
||||||
|| (limit_num_samples && (bytes_to_xfer == 0))) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
bytes_written = fwrite(transfer->buffer, 1, bytes_to_write, fd);
|
||||||
|
if ((bytes_written != bytes_to_write)
|
||||||
|
|| (limit_num_samples && (bytes_to_xfer == 0))) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -397,9 +409,9 @@ int rx_callback(hackrf_transfer* transfer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int tx_callback(hackrf_transfer* transfer) {
|
int tx_callback(hackrf_transfer* transfer) {
|
||||||
ssize_t bytes_to_read;
|
size_t bytes_to_read;
|
||||||
ssize_t bytes_read;
|
size_t bytes_read;
|
||||||
int i;
|
unsigned int i;
|
||||||
|
|
||||||
if( fd != NULL )
|
if( fd != NULL )
|
||||||
{
|
{
|
||||||
@ -416,15 +428,17 @@ int tx_callback(hackrf_transfer* transfer) {
|
|||||||
bytes_to_xfer -= bytes_to_read;
|
bytes_to_xfer -= bytes_to_read;
|
||||||
}
|
}
|
||||||
bytes_read = fread(transfer->buffer, 1, bytes_to_read, fd);
|
bytes_read = fread(transfer->buffer, 1, bytes_to_read, fd);
|
||||||
if ((bytes_read != bytes_to_read)
|
if (limit_num_samples && (bytes_to_xfer == 0)) {
|
||||||
|| (limit_num_samples && (bytes_to_xfer == 0))) {
|
return -1;
|
||||||
|
}
|
||||||
|
if (bytes_read != bytes_to_read) {
|
||||||
if (repeat) {
|
if (repeat) {
|
||||||
printf("Input file end reached. Rewind to beginning.\n");
|
printf("Input file end reached. Rewind to beginning.\n");
|
||||||
rewind(fd);
|
rewind(fd);
|
||||||
fread(transfer->buffer + bytes_read, 1, bytes_to_read - bytes_read, fd);
|
fread(transfer->buffer + bytes_read, 1, bytes_to_read - bytes_read, fd);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return -1; // not loopback mode, EOF
|
return -1; /* not repeat mode, end of file */
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -479,11 +493,15 @@ static void usage() {
|
|||||||
printf("\t[-s sample_rate_hz] # Sample rate in Hz (4/8/10/12.5/16/20MHz, default %sMHz).\n",
|
printf("\t[-s sample_rate_hz] # Sample rate in Hz (4/8/10/12.5/16/20MHz, default %sMHz).\n",
|
||||||
u64toa((DEFAULT_SAMPLE_RATE_HZ/FREQ_ONE_MHZ),&ascii_u64_data1));
|
u64toa((DEFAULT_SAMPLE_RATE_HZ/FREQ_ONE_MHZ),&ascii_u64_data1));
|
||||||
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");
|
||||||
|
#ifndef _WIN32
|
||||||
|
/* The required atomic load/store functions aren't available when using C with MSVC */
|
||||||
printf("\t[-S buf_size] # Enable receive streaming with buffer size buf_size.\n");
|
printf("\t[-S buf_size] # Enable receive streaming with buffer size buf_size.\n");
|
||||||
|
#endif
|
||||||
printf("\t[-c amplitude] # CW signal source mode, amplitude 0-127 (DC value to DAC).\n");
|
printf("\t[-c amplitude] # CW signal source mode, amplitude 0-127 (DC value to DAC).\n");
|
||||||
printf("\t[-R] # Repeat TX mode (default is off) \n");
|
printf("\t[-R] # Repeat TX mode (default is off) \n");
|
||||||
printf("\t[-b baseband_filter_bw_hz] # Set baseband filter bandwidth in Hz.\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 Hz.\n\tPossible values: 1.75/2.5/3.5/5/5.5/6/7/8/9/10/12/14/15/20/24/28MHz, default <= 0.75 * sample_rate_hz.\n" );
|
||||||
printf("\t[-C ppm] # Set Internal crystal clock error in ppm.\n");
|
printf("\t[-C ppm] # Set Internal crystal clock error in ppm.\n");
|
||||||
|
printf("\t[-H] # Synchronise USB transfer using GPIO pins.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static hackrf_device* device = NULL;
|
static hackrf_device* device = NULL;
|
||||||
@ -527,11 +545,14 @@ 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:i:o:m:a:p:s:n:b:l:g:x:c:d:C:RS:")) != EOF )
|
while( (opt = getopt(argc, argv, "Hwr:t:f:i:o:m:a:p:s:n:b:l:g:x:c:d:C:RS:")) != EOF )
|
||||||
{
|
{
|
||||||
result = HACKRF_SUCCESS;
|
result = HACKRF_SUCCESS;
|
||||||
switch( opt )
|
switch( opt )
|
||||||
{
|
{
|
||||||
|
case 'H':
|
||||||
|
hw_sync = true;
|
||||||
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
receive_wav = true;
|
receive_wav = true;
|
||||||
break;
|
break;
|
||||||
@ -653,6 +674,10 @@ int main(int argc, char** argv) {
|
|||||||
result = parse_u32(optarg, &crystal_correct_ppm);
|
result = parse_u32(optarg, &crystal_correct_ppm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '?':
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg);
|
fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg);
|
||||||
usage();
|
usage();
|
||||||
@ -778,24 +803,20 @@ int main(int argc, char** argv) {
|
|||||||
{
|
{
|
||||||
/* Compute nearest freq for bw filter */
|
/* Compute nearest freq for bw filter */
|
||||||
baseband_filter_bw_hz = hackrf_compute_baseband_filter_bw(baseband_filter_bw_hz);
|
baseband_filter_bw_hz = hackrf_compute_baseband_filter_bw(baseband_filter_bw_hz);
|
||||||
}else
|
|
||||||
{
|
|
||||||
/* Compute default value depending on sample rate */
|
|
||||||
baseband_filter_bw_hz = hackrf_compute_baseband_filter_bw_round_down_lt(sample_rate_hz);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (baseband_filter_bw_hz > BASEBAND_FILTER_BW_MAX) {
|
if (baseband_filter_bw_hz > BASEBAND_FILTER_BW_MAX) {
|
||||||
fprintf(stderr, "argument error: baseband_filter_bw_hz must be less or equal to %u Hz/%.03f MHz\n",
|
fprintf(stderr, "argument error: baseband_filter_bw_hz must be less or equal to %u Hz/%.03f MHz\n",
|
||||||
BASEBAND_FILTER_BW_MAX, (float)(BASEBAND_FILTER_BW_MAX/FREQ_ONE_MHZ));
|
BASEBAND_FILTER_BW_MAX, (float)(BASEBAND_FILTER_BW_MAX/FREQ_ONE_MHZ));
|
||||||
usage();
|
usage();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (baseband_filter_bw_hz < BASEBAND_FILTER_BW_MIN) {
|
if (baseband_filter_bw_hz < BASEBAND_FILTER_BW_MIN) {
|
||||||
fprintf(stderr, "argument error: baseband_filter_bw_hz must be greater or equal to %u Hz/%.03f MHz\n",
|
fprintf(stderr, "argument error: baseband_filter_bw_hz must be greater or equal to %u Hz/%.03f MHz\n",
|
||||||
BASEBAND_FILTER_BW_MIN, (float)(BASEBAND_FILTER_BW_MIN/FREQ_ONE_MHZ));
|
BASEBAND_FILTER_BW_MIN, (float)(BASEBAND_FILTER_BW_MIN/FREQ_ONE_MHZ));
|
||||||
usage();
|
usage();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (transmit == false) && (receive == receive_wav) )
|
if( (transmit == false) && (receive == receive_wav) )
|
||||||
@ -926,19 +947,30 @@ int main(int argc, char** argv) {
|
|||||||
signal(SIGTERM, &sigint_callback_handler);
|
signal(SIGTERM, &sigint_callback_handler);
|
||||||
signal(SIGABRT, &sigint_callback_handler);
|
signal(SIGABRT, &sigint_callback_handler);
|
||||||
#endif
|
#endif
|
||||||
fprintf(stderr, "call hackrf_sample_rate_set(%u Hz/%.03f MHz)\n", sample_rate_hz,((float)sample_rate_hz/(float)FREQ_ONE_MHZ));
|
fprintf(stderr, "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_manual(device, sample_rate_hz, 1);
|
result = hackrf_set_sample_rate(device, sample_rate_hz);
|
||||||
if( result != HACKRF_SUCCESS ) {
|
if( result != HACKRF_SUCCESS ) {
|
||||||
fprintf(stderr, "hackrf_sample_rate_set() failed: %s (%d)\n", hackrf_error_name(result), result);
|
fprintf(stderr, "hackrf_set_sample_rate() failed: %s (%d)\n", hackrf_error_name(result), result);
|
||||||
usage();
|
usage();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "call hackrf_baseband_filter_bandwidth_set(%d Hz/%.03f MHz)\n",
|
if( baseband_filter_bw ) {
|
||||||
baseband_filter_bw_hz, ((float)baseband_filter_bw_hz/(float)FREQ_ONE_MHZ));
|
fprintf(stderr, "call hackrf_baseband_filter_bandwidth_set(%d Hz/%.03f MHz)\n",
|
||||||
result = hackrf_set_baseband_filter_bandwidth(device, baseband_filter_bw_hz);
|
baseband_filter_bw_hz, ((float)baseband_filter_bw_hz/(float)FREQ_ONE_MHZ));
|
||||||
|
result = hackrf_set_baseband_filter_bandwidth(device, baseband_filter_bw_hz);
|
||||||
|
if( result != HACKRF_SUCCESS ) {
|
||||||
|
fprintf(stderr, "hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n", hackrf_error_name(result), result);
|
||||||
|
usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "call hackrf_set_hw_sync_mode(%d)\n",
|
||||||
|
hw_sync);
|
||||||
|
result = hackrf_set_hw_sync_mode(device, hw_sync ? HW_SYNC_MODE_ON : HW_SYNC_MODE_OFF);
|
||||||
if( result != HACKRF_SUCCESS ) {
|
if( result != HACKRF_SUCCESS ) {
|
||||||
fprintf(stderr, "hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n", hackrf_error_name(result), result);
|
fprintf(stderr, "hackrf_set_hw_sync_mode() failed: %s (%d)\n", hackrf_error_name(result), result);
|
||||||
usage();
|
usage();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -1017,47 +1049,49 @@ int main(int argc, char** argv) {
|
|||||||
uint32_t byte_count_now;
|
uint32_t byte_count_now;
|
||||||
struct timeval time_now;
|
struct timeval time_now;
|
||||||
float time_difference, rate;
|
float time_difference, rate;
|
||||||
if (stream_size>0){
|
if (stream_size>0) {
|
||||||
if(stream_head==stream_tail){
|
#ifndef _WIN32
|
||||||
usleep(10000); // queue empty
|
if(stream_head==stream_tail) {
|
||||||
}else{
|
usleep(10000); // queue empty
|
||||||
ssize_t len;
|
} else {
|
||||||
ssize_t bytes_written;
|
ssize_t len;
|
||||||
uint32_t _st= __atomic_load_n(&stream_tail,__ATOMIC_ACQUIRE);
|
ssize_t bytes_written;
|
||||||
if(stream_head<_st)
|
uint32_t _st= __atomic_load_n(&stream_tail,__ATOMIC_ACQUIRE);
|
||||||
len=_st-stream_head;
|
if(stream_head<_st)
|
||||||
else
|
len=_st-stream_head;
|
||||||
len=stream_size-stream_head;
|
else
|
||||||
bytes_written = fwrite(stream_buf+stream_head, 1, len, fd);
|
len=stream_size-stream_head;
|
||||||
if (len != bytes_written){
|
bytes_written = fwrite(stream_buf+stream_head, 1, len, fd);
|
||||||
printf("write failed");
|
if (len != bytes_written) {
|
||||||
do_exit=true;
|
printf("write failed");
|
||||||
};
|
do_exit=true;
|
||||||
stream_head=(stream_head+len)%stream_size;
|
};
|
||||||
|
stream_head=(stream_head+len)%stream_size;
|
||||||
}
|
}
|
||||||
if(stream_drop>0){
|
if(stream_drop>0) {
|
||||||
uint32_t drops= __atomic_exchange_n (&stream_drop,0,__ATOMIC_SEQ_CST);
|
uint32_t drops= __atomic_exchange_n (&stream_drop,0,__ATOMIC_SEQ_CST);
|
||||||
printf("dropped frames: [%d]\n",drops);
|
printf("dropped frames: [%d]\n",drops);
|
||||||
}
|
}
|
||||||
}else{
|
#endif
|
||||||
sleep(1);
|
} else {
|
||||||
|
sleep(1);
|
||||||
|
gettimeofday(&time_now, NULL);
|
||||||
|
|
||||||
gettimeofday(&time_now, NULL);
|
byte_count_now = byte_count;
|
||||||
|
byte_count = 0;
|
||||||
|
|
||||||
byte_count_now = byte_count;
|
time_difference = TimevalDiff(&time_now, &time_start);
|
||||||
byte_count = 0;
|
rate = (float)byte_count_now / time_difference;
|
||||||
|
fprintf(stderr, "%4.1f MiB / %5.3f sec = %4.1f MiB/second\n",
|
||||||
|
(byte_count_now / 1e6f), time_difference, (rate / 1e6f) );
|
||||||
|
|
||||||
time_difference = TimevalDiff(&time_now, &time_start);
|
time_start = time_now;
|
||||||
rate = (float)byte_count_now / time_difference;
|
|
||||||
fprintf(stderr, "%4.1f MiB / %5.3f sec = %4.1f MiB/second\n",
|
|
||||||
(byte_count_now / 1e6f), time_difference, (rate / 1e6f) );
|
|
||||||
|
|
||||||
time_start = time_now;
|
if (byte_count_now == 0) {
|
||||||
|
exit_code = EXIT_FAILURE;
|
||||||
if (byte_count_now == 0) {
|
fprintf(stderr, "\nCouldn't transfer any bytes for one second.\n");
|
||||||
exit_code = EXIT_FAILURE;
|
break;
|
||||||
fprintf(stderr, "\nCouldn't transfer any bytes for one second.\n");
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
This repository contains hardware designs and software for HackRF, a project to
|
|
||||||
produce a low cost, open source software radio platform.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
How to build host software on Windows:
|
|
||||||
prerequisite for cygwin or mingw:
|
|
||||||
* cmake-2.8.10.2 or more see http://www.cmake.org/cmake/resources/software.html
|
|
||||||
* libusbx-1.0.14 or more see http://sourceforge.net/projects/libusbx/files/latest/download?source=files
|
|
||||||
* Install Windows driver for HackRF hardware or use Zadig see http://sourceforge.net/projects/libwdi/files/zadig
|
|
||||||
- If you want to use Zadig select HackRF USB device and just install/replace it with WinUSB driver.
|
|
||||||
|
|
||||||
For Cygwin:
|
|
||||||
cmake -G "Unix Makefiles" -DCMAKE_LEGACY_CYGWIN_WIN32=1 -DLIBUSB_INCLUDE_DIR=/usr/local/include/libusb-1.0/
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
|
|
||||||
For Mingw:
|
|
||||||
#normal version
|
|
||||||
cmake -G "MSYS Makefiles" -DLIBUSB_INCLUDE_DIR=/usr/local/include/libusb-1.0/
|
|
||||||
#debug version
|
|
||||||
cmake -G "MSYS Makefiles" -DCMAKE_BUILD_TYPE=Debug -DLIBUSB_INCLUDE_DIR=/usr/local/include/libusb-1.0/
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
|
|
||||||
How to build host software on Linux:
|
|
||||||
cmake ./
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
|
|
||||||
principal author: Michael Ossmann <mike@ossmann.com>
|
|
||||||
|
|
||||||
http://greatscottgadgets.com/hackrf/
|
|
@ -26,6 +26,11 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSI
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <libusb.h>
|
#include <libusb.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
/* Avoid redefinition of timespec from time.h (included by libusb.h) */
|
||||||
|
#define HAVE_STRUCT_TIMESPEC 1
|
||||||
|
#endif
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#ifndef bool
|
#ifndef bool
|
||||||
@ -67,6 +72,12 @@ typedef enum {
|
|||||||
HACKRF_VENDOR_REQUEST_SET_TXVGA_GAIN = 21,
|
HACKRF_VENDOR_REQUEST_SET_TXVGA_GAIN = 21,
|
||||||
HACKRF_VENDOR_REQUEST_ANTENNA_ENABLE = 23,
|
HACKRF_VENDOR_REQUEST_ANTENNA_ENABLE = 23,
|
||||||
HACKRF_VENDOR_REQUEST_SET_FREQ_EXPLICIT = 24,
|
HACKRF_VENDOR_REQUEST_SET_FREQ_EXPLICIT = 24,
|
||||||
|
// USB_WCID_VENDOR_REQ = 25
|
||||||
|
HACKRF_VENDOR_REQUEST_INIT_SWEEP = 26,
|
||||||
|
HACKRF_VENDOR_REQUEST_OPERACAKE_GET_BOARDS = 27,
|
||||||
|
HACKRF_VENDOR_REQUEST_OPERACAKE_SET_PORTS = 28,
|
||||||
|
HACKRF_VENDOR_REQUEST_SET_HW_SYNC_MODE = 29,
|
||||||
|
HACKRF_VENDOR_REQUEST_RESET = 30,
|
||||||
} hackrf_vendor_request;
|
} hackrf_vendor_request;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -82,6 +93,11 @@ typedef enum {
|
|||||||
TRANSCEIVER_MODE_CPLD_UPDATE = 4,
|
TRANSCEIVER_MODE_CPLD_UPDATE = 4,
|
||||||
} hackrf_transceiver_mode;
|
} hackrf_transceiver_mode;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
HACKRF_HW_SYNC_MODE_OFF = 0,
|
||||||
|
HACKRF_HW_SYNC_MODE_ON = 1,
|
||||||
|
} hackrf_hw_sync_mode;
|
||||||
|
|
||||||
struct hackrf_device {
|
struct hackrf_device {
|
||||||
libusb_device_handle* usb_device;
|
libusb_device_handle* usb_device;
|
||||||
struct libusb_transfer** transfers;
|
struct libusb_transfer** transfers;
|
||||||
@ -1094,6 +1110,11 @@ typedef struct {
|
|||||||
} set_fracrate_params_t;
|
} set_fracrate_params_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* You should probably use hackrf_set_sample_rate() below instead of this
|
||||||
|
* function. They both result in automatic baseband filter selection as
|
||||||
|
* described below.
|
||||||
|
*/
|
||||||
int ADDCALL hackrf_set_sample_rate_manual(hackrf_device* device,
|
int ADDCALL hackrf_set_sample_rate_manual(hackrf_device* device,
|
||||||
const uint32_t freq_hz, uint32_t divider)
|
const uint32_t freq_hz, uint32_t divider)
|
||||||
{
|
{
|
||||||
@ -1120,10 +1141,17 @@ int ADDCALL hackrf_set_sample_rate_manual(hackrf_device* device,
|
|||||||
{
|
{
|
||||||
return HACKRF_ERROR_LIBUSB;
|
return HACKRF_ERROR_LIBUSB;
|
||||||
} else {
|
} else {
|
||||||
return HACKRF_SUCCESS;
|
return hackrf_set_baseband_filter_bandwidth(device,
|
||||||
|
hackrf_compute_baseband_filter_bw((uint32_t)(0.75*freq_hz/divider)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For anti-aliasing, the baseband filter bandwidth is automatically set to the
|
||||||
|
* widest available setting that is no more than 75% of the sample rate. This
|
||||||
|
* happens every time the sample rate is set. If you want to override the
|
||||||
|
* baseband filter selection, you must do so after setting the sample rate.
|
||||||
|
*/
|
||||||
int ADDCALL hackrf_set_sample_rate(hackrf_device* device, const double freq)
|
int ADDCALL hackrf_set_sample_rate(hackrf_device* device, const double freq)
|
||||||
{
|
{
|
||||||
const int MAX_N = 32;
|
const int MAX_N = 32;
|
||||||
@ -1417,6 +1445,7 @@ static int create_transfer_thread(hackrf_device* device,
|
|||||||
if( device->transfer_thread_started == false )
|
if( device->transfer_thread_started == false )
|
||||||
{
|
{
|
||||||
device->streaming = false;
|
device->streaming = false;
|
||||||
|
do_exit = false;
|
||||||
|
|
||||||
result = prepare_transfers(
|
result = prepare_transfers(
|
||||||
device, endpoint_address,
|
device, endpoint_address,
|
||||||
@ -1548,6 +1577,26 @@ int ADDCALL hackrf_close(hackrf_device* device)
|
|||||||
return result1;
|
return result1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ADDCALL hackrf_set_hw_sync_mode(hackrf_device* device, const uint8_t value) {
|
||||||
|
int result = libusb_control_transfer(
|
||||||
|
device->usb_device,
|
||||||
|
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
|
||||||
|
HACKRF_VENDOR_REQUEST_SET_HW_SYNC_MODE,
|
||||||
|
value,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
if( result != 0 )
|
||||||
|
{
|
||||||
|
return HACKRF_ERROR_LIBUSB;
|
||||||
|
} else {
|
||||||
|
return HACKRF_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char* ADDCALL hackrf_error_name(enum hackrf_error errcode)
|
const char* ADDCALL hackrf_error_name(enum hackrf_error errcode)
|
||||||
{
|
{
|
||||||
switch(errcode)
|
switch(errcode)
|
||||||
@ -1695,6 +1744,111 @@ uint32_t ADDCALL hackrf_compute_baseband_filter_bw(const uint32_t bandwidth_hz)
|
|||||||
return p->bandwidth_hz;
|
return p->bandwidth_hz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialise sweep mode with alist of frequencies and dwell time in samples */
|
||||||
|
int ADDCALL hackrf_init_sweep(hackrf_device* device, uint16_t* frequency_list, int length, uint32_t dwell_time)
|
||||||
|
{
|
||||||
|
int result, i;
|
||||||
|
int size = length * sizeof(frequency_list[0]);
|
||||||
|
|
||||||
|
for(i=0; i<length; i++)
|
||||||
|
frequency_list[i] = TO_LE(frequency_list[i]);
|
||||||
|
|
||||||
|
result = libusb_control_transfer(
|
||||||
|
device->usb_device,
|
||||||
|
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
|
||||||
|
HACKRF_VENDOR_REQUEST_INIT_SWEEP,
|
||||||
|
dwell_time & 0xffff,
|
||||||
|
(dwell_time >> 16) & 0xffff,
|
||||||
|
(unsigned char*)frequency_list,
|
||||||
|
size,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result < size) {
|
||||||
|
return HACKRF_ERROR_LIBUSB;
|
||||||
|
} else {
|
||||||
|
return HACKRF_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve list of Operacake board addresses
|
||||||
|
* boards must be *uint8_t[8]
|
||||||
|
*/
|
||||||
|
int ADDCALL hackrf_get_operacake_boards(hackrf_device* device, uint8_t* boards)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
result = libusb_control_transfer(
|
||||||
|
device->usb_device,
|
||||||
|
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
|
||||||
|
HACKRF_VENDOR_REQUEST_OPERACAKE_GET_BOARDS,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
boards,
|
||||||
|
8,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result < 8)
|
||||||
|
{
|
||||||
|
return HACKRF_ERROR_LIBUSB;
|
||||||
|
} else {
|
||||||
|
return HACKRF_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Operacake ports */
|
||||||
|
int ADDCALL hackrf_set_operacake_ports(hackrf_device* device,
|
||||||
|
uint8_t address,
|
||||||
|
uint8_t port_a,
|
||||||
|
uint8_t port_b)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
/* Error checking */
|
||||||
|
if((port_a > OPERACAKE_PB4) || (port_b > OPERACAKE_PB4)) {
|
||||||
|
return HACKRF_ERROR_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
/* Check which side PA and PB are on */
|
||||||
|
if(((port_a <= OPERACAKE_PA4) && (port_b <= OPERACAKE_PA4))
|
||||||
|
|| ((port_a > OPERACAKE_PA4) && (port_b > OPERACAKE_PA4))) {
|
||||||
|
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_OPERACAKE_SET_PORTS,
|
||||||
|
address,
|
||||||
|
port_a | (port_b<<8),
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result != 0) {
|
||||||
|
return HACKRF_ERROR_LIBUSB;
|
||||||
|
} else {
|
||||||
|
return HACKRF_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ADDCALL hackrf_reset(hackrf_device* device) {
|
||||||
|
int result = libusb_control_transfer(
|
||||||
|
device->usb_device,
|
||||||
|
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
|
||||||
|
HACKRF_VENDOR_REQUEST_RESET,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
if( result != 0 ) {
|
||||||
|
return HACKRF_ERROR_LIBUSB;
|
||||||
|
} else {
|
||||||
|
return HACKRF_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // __cplusplus defined.
|
} // __cplusplus defined.
|
||||||
#endif
|
#endif
|
||||||
|
@ -83,6 +83,17 @@ enum rf_path_filter {
|
|||||||
RF_PATH_FILTER_HIGH_PASS = 2,
|
RF_PATH_FILTER_HIGH_PASS = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum operacake_ports {
|
||||||
|
OPERACAKE_PA1 = 0,
|
||||||
|
OPERACAKE_PA2 = 1,
|
||||||
|
OPERACAKE_PA3 = 2,
|
||||||
|
OPERACAKE_PA4 = 3,
|
||||||
|
OPERACAKE_PB1 = 4,
|
||||||
|
OPERACAKE_PB2 = 5,
|
||||||
|
OPERACAKE_PB3 = 6,
|
||||||
|
OPERACAKE_PB4 = 7,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct hackrf_device hackrf_device;
|
typedef struct hackrf_device hackrf_device;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -187,6 +198,9 @@ extern ADDAPI int ADDCALL hackrf_set_txvga_gain(hackrf_device* device, uint32_t
|
|||||||
/* antenna port power control */
|
/* antenna port power control */
|
||||||
extern ADDAPI int ADDCALL hackrf_set_antenna_enable(hackrf_device* device, const uint8_t value);
|
extern ADDAPI int ADDCALL hackrf_set_antenna_enable(hackrf_device* device, const uint8_t value);
|
||||||
|
|
||||||
|
/* set hardware sync mode */
|
||||||
|
extern ADDAPI int ADDCALL hackrf_set_hw_sync_mode(hackrf_device* device, const uint8_t value);
|
||||||
|
|
||||||
extern ADDAPI const char* ADDCALL hackrf_error_name(enum hackrf_error errcode);
|
extern ADDAPI const char* ADDCALL hackrf_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_usb_board_id_name(enum hackrf_usb_board_id usb_board_id);
|
extern ADDAPI const char* ADDCALL hackrf_usb_board_id_name(enum hackrf_usb_board_id usb_board_id);
|
||||||
@ -196,6 +210,19 @@ extern ADDAPI const char* ADDCALL hackrf_filter_path_name(const enum rf_path_fil
|
|||||||
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);
|
||||||
/* Compute best default value depending on sample rate (auto filter) */
|
/* Compute best default value depending on sample rate (auto filter) */
|
||||||
extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw(const uint32_t bandwidth_hz);
|
extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw(const uint32_t bandwidth_hz);
|
||||||
|
/* Start scan mode */
|
||||||
|
extern ADDAPI int ADDCALL hackrf_init_sweep(hackrf_device* device,
|
||||||
|
uint16_t* frequency_list,
|
||||||
|
int length, uint32_t dwell_time);
|
||||||
|
|
||||||
|
/* Operacake functions */
|
||||||
|
extern ADDAPI int ADDCALL hackrf_get_operacake_boards(hackrf_device* device, uint8_t* boards);
|
||||||
|
extern ADDAPI int ADDCALL hackrf_set_operacake_ports(hackrf_device* device,
|
||||||
|
uint8_t address,
|
||||||
|
uint8_t port_a,
|
||||||
|
uint8_t port_b);
|
||||||
|
|
||||||
|
extern ADDAPI int ADDCALL hackrf_reset(hackrf_device* device);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // __cplusplus defined.
|
} // __cplusplus defined.
|
||||||
|
@ -1,53 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2012 Jared Boone
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
import usb
|
|
||||||
import struct
|
|
||||||
import sys
|
|
||||||
|
|
||||||
device = usb.core.find(idVendor=0x1d50, idProduct=0x604b)
|
|
||||||
if device:
|
|
||||||
print 'Find: HackRF Jawbreaker'
|
|
||||||
else:
|
|
||||||
device = usb.core.find(idVendor=0x1d50, idProduct=0x6089)
|
|
||||||
if device:
|
|
||||||
print 'Find: HackRF One'
|
|
||||||
else:
|
|
||||||
device = usb.core.find(idVendor=0x1d50, idProduct=0xcc15)
|
|
||||||
if device:
|
|
||||||
print 'Find: rad1o'
|
|
||||||
else:
|
|
||||||
print 'Not find any HackRF device.'
|
|
||||||
sys.exit()
|
|
||||||
device.set_configuration()
|
|
||||||
|
|
||||||
def read_max2837_register(register_number):
|
|
||||||
return struct.unpack('<H', device.ctrl_transfer(0xC0, 3, 0, register_number, 2))[0]
|
|
||||||
|
|
||||||
def write_max2837_register(register_number, value):
|
|
||||||
device.ctrl_transfer(0x40, 2, value, register_number)
|
|
||||||
|
|
||||||
def dump_max2837():
|
|
||||||
for i in range(32):
|
|
||||||
print('%2d: %03x' % (i, read_max2837_register(i)))
|
|
||||||
|
|
||||||
dump_max2837()
|
|
@ -1,54 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2012 Jared Boone
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import usb
|
|
||||||
|
|
||||||
device = usb.core.find(idVendor=0x1d50, idProduct=0x604b)
|
|
||||||
if device:
|
|
||||||
print 'Find: HackRF Jawbreaker'
|
|
||||||
else:
|
|
||||||
device = usb.core.find(idVendor=0x1d50, idProduct=0x6089)
|
|
||||||
if device:
|
|
||||||
print 'Find: HackRF One'
|
|
||||||
else:
|
|
||||||
device = usb.core.find(idVendor=0x1d50, idProduct=0xcc15)
|
|
||||||
if device:
|
|
||||||
print 'Find: rad1o'
|
|
||||||
else:
|
|
||||||
print 'Not find any HackRF device.'
|
|
||||||
sys.exit()
|
|
||||||
device.set_configuration()
|
|
||||||
|
|
||||||
def set_rx():
|
|
||||||
device.ctrl_transfer(0x40, 1, 1, 0)
|
|
||||||
|
|
||||||
def set_tx():
|
|
||||||
device.ctrl_transfer(0x40, 1, 2, 0)
|
|
||||||
|
|
||||||
if len(sys.argv) == 2:
|
|
||||||
if sys.argv[1] == 'tx':
|
|
||||||
set_tx()
|
|
||||||
elif sys.argv[1] == 'rx':
|
|
||||||
set_rx()
|
|
||||||
else:
|
|
||||||
print 'Usage: %s [rx|tx]' % sys.argv[0]
|
|
Reference in New Issue
Block a user