Merge branch 'mossmann-master' into flash-investigation

This commit is contained in:
Dominic Spill
2017-12-05 16:18:19 -07:00
20 changed files with 8503 additions and 5933 deletions

View File

@ -24,10 +24,14 @@ before_script:
- export CFLAGS="-Wall -Wextra -Werror" - export CFLAGS="-Wall -Wextra -Werror"
before_install: before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew tap PX4/homebrew-px4; brew update; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew tap PX4/homebrew-px4; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libusb fftw gcc-arm-none-eabi dfu-util; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libusb fftw gcc-arm-none-eabi dfu-util; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then wget -O gcc-arm-none-eabi.tar.bz2 https://developer.arm.com/-/media/Files/downloads/gnu-rm/6-2017q2/gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then tar xf gcc-arm-none-eabi.tar.bz2; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export PATH=$PATH:$PWD/gcc-arm-none-eabi-6-2017-q2-update/bin; fi
# For virtualenv(?) reasons we can't apt-get install python-yaml # For virtualenv(?) reasons we can't apt-get install python-yaml
- pip install PyYAML - pip2 install PyYAML
script: script:
- mkdir host/build - mkdir host/build
@ -52,11 +56,7 @@ script:
addons: addons:
apt: apt:
sources:
- debian-sid
packages: packages:
- libusb-1.0-0-dev - libusb-1.0-0-dev
- libfftw3-dev - libfftw3-dev
- gcc-arm-none-eabi
- libnewlib-arm-none-eabi
- dfu-util - dfu-util

View File

@ -498,8 +498,6 @@ void cpu_clock_init(void)
si5351c_set_clock_source(&clock_gen, PLL_SOURCE_XTAL); si5351c_set_clock_source(&clock_gen, PLL_SOURCE_XTAL);
// soft reset // soft reset
// uint8_t resetdata[] = { 177, 0xac };
// si5351c_write(&clock_gen, resetdata, sizeof(resetdata));
si5351c_reset_pll(&clock_gen); si5351c_reset_pll(&clock_gen);
si5351c_enable_clock_outputs(&clock_gen); si5351c_enable_clock_outputs(&clock_gen);

View File

@ -197,12 +197,27 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll
si5351c_write(drv, data, sizeof(data)); si5351c_write(drv, data, sizeof(data));
} }
#define SI5351C_CLK_ENABLE(x) (0<<x)
#define SI5351C_CLK_DISABLE(x) (1<<x)
#define SI5351C_REG_OUTPUT_EN (3)
#define SI5351C_REG_CLK3_CTRL (19)
void si5351c_enable_clock_outputs(si5351c_driver_t* const drv) void si5351c_enable_clock_outputs(si5351c_driver_t* const drv)
{ {
/* Enable CLK outputs 0, 1, 2, 4, 5 only. */ /* Enable CLK outputs 0, 1, 2, 4, 5 only. */
/* 7: Clock to CPU is deactivated as it is not used and creates noise */ /* 7: Clock to CPU is deactivated as it is not used and creates noise */
/* 3: External clock output is deactivated by default */ /* 3: External clock output is deactivated by default */
uint8_t data[] = { 3, ~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4) | (1 << 5))}; // uint8_t data[] = { 3, ~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4) | (1 << 5))};
uint8_t data[] = { SI5351C_REG_OUTPUT_EN,
SI5351C_CLK_ENABLE(0) |
SI5351C_CLK_ENABLE(1) |
SI5351C_CLK_ENABLE(2) |
SI5351C_CLK_DISABLE(3) |
SI5351C_CLK_ENABLE(4) |
SI5351C_CLK_ENABLE(5) |
SI5351C_CLK_DISABLE(6) |
SI5351C_CLK_DISABLE(7)
};
si5351c_write(drv, data, sizeof(data)); si5351c_write(drv, data, sizeof(data));
} }
@ -244,3 +259,43 @@ void si5351c_activate_best_clock_source(si5351c_driver_t* const drv)
} }
} }
} }
void si5351c_clkout_enable(si5351c_driver_t* const drv, uint8_t enable)
{
/* Set optput in output enable register */
uint8_t output_enable = si5351c_read_single(drv, 3);
output_enable = output_enable & !SI5351C_CLK_DISABLE(3);
if(enable)
output_enable = output_enable | SI5351C_CLK_ENABLE(3);
else
output_enable = output_enable | SI5351C_CLK_DISABLE(3);
uint8_t oe_data[] = {SI5351C_REG_OUTPUT_EN, output_enable};
si5351c_write(drv, oe_data, 2);
/* Configure clock to 10MHz (TODO customisable?) */
si5351c_configure_multisynth(drv, 3, 80*128-512, 0, 1, 0);
/* Set power up/doen in CLK3 control register*/
uint8_t pll;
#ifdef RAD1O
/* PLLA on XTAL */
pll = SI5351C_CLK_PLL_SRC_A;
#endif
#if (defined JAWBREAKER || defined HACKRF_ONE)
if (active_clock_source == PLL_SOURCE_CLKIN) {
/* PLLB on CLKIN */
pll = SI5351C_CLK_PLL_SRC_B;
} else {
/* PLLA on XTAL */
pll = SI5351C_CLK_PLL_SRC_A;
}
#endif
uint8_t clk3_ctrl;
if(enable)
clk3_ctrl = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA);
else
clk3_ctrl = SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE;
uint8_t clk3_data[] = {SI5351C_REG_CLK3_CTRL, clk3_ctrl};
si5351c_write(drv, clk3_data, 2);
}

View File

@ -89,6 +89,7 @@ void si5351c_activate_best_clock_source(si5351c_driver_t* const drv);
void si5351c_write_single(si5351c_driver_t* const drv, uint8_t reg, uint8_t val); void si5351c_write_single(si5351c_driver_t* const drv, uint8_t reg, uint8_t val);
uint8_t si5351c_read_single(si5351c_driver_t* const drv, uint8_t reg); uint8_t si5351c_read_single(si5351c_driver_t* const drv, uint8_t reg);
void si5351c_write(si5351c_driver_t* const drv, const uint8_t* const data, const size_t data_count); void si5351c_write(si5351c_driver_t* const drv, const uint8_t* const data, const size_t data_count);
void si5351c_clkout_enable(si5351c_driver_t* const drv, uint8_t enable);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -90,6 +90,7 @@ static const usb_request_handler_fn vendor_request_handler[] = {
usb_vendor_request_set_hw_sync_mode, usb_vendor_request_set_hw_sync_mode,
usb_vendor_request_reset, usb_vendor_request_reset,
usb_vendor_request_operacake_set_ranges, usb_vendor_request_operacake_set_ranges,
usb_vendor_request_set_clkout_enable,
usb_vendor_request_spiflash_status, usb_vendor_request_spiflash_status,
usb_vendor_request_spiflash_clear_status usb_vendor_request_spiflash_clear_status
}; };

View File

@ -149,3 +149,14 @@ usb_request_status_t usb_vendor_request_read_rffc5071(
} }
} }
#endif #endif
usb_request_status_t usb_vendor_request_set_clkout_enable(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage
) {
if (stage == USB_TRANSFER_STAGE_SETUP) {
si5351c_clkout_enable(&clock_gen, endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in);
}
return USB_REQUEST_STATUS_OK;
}

View File

@ -50,5 +50,9 @@ usb_request_status_t usb_vendor_request_read_rffc5071(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage
); );
usb_request_status_t usb_vendor_request_set_clkout_enable(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage
);
#endif /* end of include guard: __USB_API_REGISTER_H__ */ #endif /* end of include guard: __USB_API_REGISTER_H__ */

View File

@ -217,6 +217,14 @@ uint8_t usb_descriptor_string_product[] = {
'k', 0x00, 'k', 0x00,
'e', 0x00, 'e', 0x00,
'r', 0x00, 'r', 0x00,
#elif RAD1O
12, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'r', 0x00,
'a', 0x00,
'd', 0x00,
'1', 0x00,
'o', 0x00,
#else #else
14, // bLength 14, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType

View File

@ -59,10 +59,14 @@ ENDDEF
DEF C C 0 10 N Y 1 F N DEF C C 0 10 N Y 1 F N
F0 "C" 25 100 50 H V L CNN F0 "C" 25 100 50 H V L CNN
F1 "C" 25 -100 50 H V L CNN F1 "C" 25 -100 50 H V L CNN
F2 "" 38 -150 50 H I C CNN F2 "" 38 -150 50 H V C CNN
F3 "" 0 0 50 H I C CNN F3 "" 0 0 50 H V C CNN
$FPLIST $FPLIST
C_* C?
C_????_*
C_????
SMD*_c
Capacitor*
$ENDFPLIST $ENDFPLIST
DRAW DRAW
P 2 0 1 20 -80 -30 80 -30 N P 2 0 1 20 -80 -30 80 -30 N
@ -74,17 +78,16 @@ ENDDEF
# #
# CONN_02X03 # CONN_02X03
# #
DEF CONN_02X03 J 0 1 Y N 1 F N DEF CONN_02X03 P 0 1 Y N 1 F N
F0 "J" 0 200 50 H V C CNN F0 "P" 0 200 50 H V C CNN
F1 "CONN_02X03" 0 -200 50 H V C CNN F1 "CONN_02X03" 0 -200 50 H V C CNN
F2 "" 0 -1200 50 H I C CNN F2 "" 0 -1200 50 H V C CNN
F3 "" 0 -1200 50 H I C CNN F3 "" 0 -1200 50 H V C CNN
$FPLIST $FPLIST
Pin_Header_Straight_2X* Pin_Header_Straight_2X03
Pin_Header_Angled_2X* Pin_Header_Angled_2X03
Socket_Strip_Straight_2X* Socket_Strip_Straight_2X03
Socket_Strip_Angled_2X* Socket_Strip_Angled_2X03
IDC_Header_Straight_*
$ENDFPLIST $ENDFPLIST
DRAW DRAW
S -100 -95 -50 -105 0 1 0 N S -100 -95 -50 -105 0 1 0 N
@ -105,17 +108,16 @@ ENDDEF
# #
# CONN_02X08 # CONN_02X08
# #
DEF CONN_02X08 J 0 1 Y N 1 F N DEF CONN_02X08 P 0 1 Y N 1 F N
F0 "J" 0 450 50 H V C CNN F0 "P" 0 450 50 H V C CNN
F1 "CONN_02X08" 0 0 50 V V C CNN F1 "CONN_02X08" 0 0 50 V V C CNN
F2 "" 0 -1200 50 H I C CNN F2 "" 0 -1200 50 H V C CNN
F3 "" 0 -1200 50 H I C CNN F3 "" 0 -1200 50 H V C CNN
$FPLIST $FPLIST
Pin_Header_Straight_2X* Pin_Header_Straight_2X08
Pin_Header_Angled_2X* Pin_Header_Angled_2X08
Socket_Strip_Straight_2X* Socket_Strip_Straight_2X08
Socket_Strip_Angled_2X* Socket_Strip_Angled_2X08
IDC_Header_Straight_*
$ENDFPLIST $ENDFPLIST
DRAW DRAW
S -100 -345 -50 -355 0 1 0 N S -100 -345 -50 -355 0 1 0 N
@ -156,16 +158,16 @@ ENDDEF
# #
# CONN_02X11 # CONN_02X11
# #
DEF CONN_02X11 J 0 1 Y N 1 F N DEF CONN_02X11 P 0 1 Y N 1 F N
F0 "J" 0 600 50 H V C CNN F0 "P" 0 600 50 H V C CNN
F1 "CONN_02X11" 0 0 50 V V C CNN F1 "CONN_02X11" 0 0 50 V V C CNN
F2 "" 0 -1200 50 H I C CNN F2 "" 0 -1200 50 H V C CNN
F3 "" 0 -1200 50 H I C CNN F3 "" 0 -1200 50 H V C CNN
$FPLIST $FPLIST
Pin_Header_Straight_2X* Pin_Header_Straight_2X11
Pin_Header_Angled_2X* Pin_Header_Angled_2X11
Socket_Strip_Straight_2X* Socket_Strip_Straight_2X11
Socket_Strip_Angled_2X* Socket_Strip_Angled_2X11
$ENDFPLIST $ENDFPLIST
DRAW DRAW
S -100 -495 -50 -505 0 1 0 N S -100 -495 -50 -505 0 1 0 N
@ -218,17 +220,16 @@ ENDDEF
# #
# CONN_02X13 # CONN_02X13
# #
DEF CONN_02X13 J 0 1 Y N 1 F N DEF CONN_02X13 P 0 1 Y N 1 F N
F0 "J" 0 700 50 H V C CNN F0 "P" 0 700 50 H V C CNN
F1 "CONN_02X13" 0 0 50 V V C CNN F1 "CONN_02X13" 0 0 50 V V C CNN
F2 "" 0 -1150 50 H I C CNN F2 "" 0 -1150 50 H V C CNN
F3 "" 0 -1150 50 H I C CNN F3 "" 0 -1150 50 H V C CNN
$FPLIST $FPLIST
Pin_Header_Straight_2X* Pin_Header_Straight_2X13
Pin_Header_Angled_2X* Pin_Header_Angled_2X13
Socket_Strip_Straight_2X* Socket_Strip_Straight_2X13
Socket_Strip_Angled_2X* Socket_Strip_Angled_2X13
IDC_Header_Straight_*
$ENDFPLIST $ENDFPLIST
DRAW DRAW
S -100 -595 -50 -605 0 1 0 N S -100 -595 -50 -605 0 1 0 N
@ -289,17 +290,16 @@ ENDDEF
# #
# CONN_02X20 # CONN_02X20
# #
DEF CONN_02X20 J 0 1 Y N 1 F N DEF CONN_02X20 P 0 1 Y N 1 F N
F0 "J" 0 1050 50 H V C CNN F0 "P" 0 1050 50 H V C CNN
F1 "CONN_02X20" 0 0 50 V V C CNN F1 "CONN_02X20" 0 0 50 V V C CNN
F2 "" 0 -950 50 H I C CNN F2 "" 0 -950 50 H V C CNN
F3 "" 0 -950 50 H I C CNN F3 "" 0 -950 50 H V C CNN
$FPLIST $FPLIST
Pin_Header_Straight_2X* Pin_Header_Straight_2X20
Pin_Header_Angled_2X* Pin_Header_Angled_2X20
Socket_Strip_Straight_2X* Socket_Strip_Straight_2X20
Socket_Strip_Angled_2X* Socket_Strip_Angled_2X20
IDC_Header_Straight_*
$ENDFPLIST $ENDFPLIST
DRAW DRAW
S -100 -945 -50 -955 0 1 0 N S -100 -945 -50 -955 0 1 0 N
@ -405,8 +405,8 @@ ENDDEF
DEF GND #PWR 0 0 Y Y 1 F P DEF GND #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 -250 50 H I C CNN F0 "#PWR" 0 -250 50 H I C CNN
F1 "GND" 0 -150 50 H V C CNN F1 "GND" 0 -150 50 H V C CNN
F2 "" 0 0 50 H I C CNN F2 "" 0 0 50 H V C CNN
F3 "" 0 0 50 H I C CNN F3 "" 0 0 50 H V C CNN
DRAW DRAW
P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N
X GND 1 0 0 0 D 50 50 1 1 W N X GND 1 0 0 0 D 50 50 1 1 W N
@ -453,8 +453,8 @@ ENDDEF
DEF LED D 0 40 Y N 1 F N DEF LED D 0 40 Y N 1 F N
F0 "D" 0 100 50 H V C CNN F0 "D" 0 100 50 H V C CNN
F1 "LED" 0 -100 50 H V C CNN F1 "LED" 0 -100 50 H V C CNN
F2 "" 0 0 50 H I C CNN F2 "" 0 0 50 H V C CNN
F3 "" 0 0 50 H I C CNN F3 "" 0 0 50 H V C CNN
$FPLIST $FPLIST
LED* LED*
$ENDFPLIST $ENDFPLIST
@ -527,11 +527,11 @@ ENDDEF
DEF R R 0 0 N Y 1 F N DEF R R 0 0 N Y 1 F N
F0 "R" 80 0 50 V V C CNN F0 "R" 80 0 50 V V C CNN
F1 "R" 0 0 50 V V C CNN F1 "R" 0 0 50 V V C CNN
F2 "" -70 0 50 V I C CNN F2 "" -70 0 50 V V C CNN
F3 "" 0 0 50 H I C CNN F3 "" 0 0 50 H V C CNN
$FPLIST $FPLIST
R_* R_*
R_* Resistor_*
$ENDFPLIST $ENDFPLIST
DRAW DRAW
S -40 -100 40 100 0 1 10 N S -40 -100 40 100 0 1 10 N
@ -600,8 +600,8 @@ ENDDEF
DEF VCC #PWR 0 0 Y Y 1 F P DEF VCC #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 -150 50 H I C CNN F0 "#PWR" 0 -150 50 H I C CNN
F1 "VCC" 0 150 50 H V C CNN F1 "VCC" 0 150 50 H V C CNN
F2 "" 0 0 50 H I C CNN F2 "" 0 0 50 H V C CNN
F3 "" 0 0 50 H I C CNN F3 "" 0 0 50 H V C CNN
DRAW DRAW
C 0 75 25 0 1 0 N C 0 75 25 0 1 0 N
P 2 0 1 0 0 0 0 50 N P 2 0 1 0 0 0 0 50 N

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,8 @@
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
project (HackRF) project (HackRF)
set(CMAKE_C_FLAGS "$ENV{CFLAGS}" CACHE STRING "C Flags")
add_subdirectory(libhackrf) add_subdirectory(libhackrf)
add_subdirectory(hackrf-tools) add_subdirectory(hackrf-tools)

View File

@ -1,12 +1,12 @@
This repository contains host software (Linux/Windows) for HackRF, a project to This repository contains host software (Linux/Windows) for HackRF, a project to
produce a low cost, open source software radio platform. 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 libfftw3-dev`
###Build host software on Linux: ### Build host software on Linux:
``` ```
mkdir host/build mkdir host/build
cd host/build cd host/build
@ -16,34 +16,34 @@ sudo make install
sudo ldconfig sudo ldconfig
``` ```
By defualt this will attempt to install a udev rule to '/etc/udev/rules.d` to By default this will attempt to install an udev rule to `/etc/udev/rules.d` to
provide the `usb` or `plugdev` group access to HackRF. If your setup requires 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 the udev rule to be installed elsewhere you can modify the path with
`-DUDEV_RULES_PATH=/path/to/udev`. `-DUDEV_RULES_PATH=/path/to/udev`.
Note: The udev rule is not installed for by default for PyBOMBS installs as Note: The udev rule is not installed by default for PyBOMBS installs as
they do not ususally get installed with root privileges. they do not ususally get installed with root privileges.
##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, MinGW, or Visual Studio:
* cmake-2.8.12.1 or later from http://www.cmake.org/cmake/resources/software.html * cmake-2.8.12.1 or later from http://www.cmake.org/cmake/resources/software.html
* libusbx-1.0.18 or later from http://sourceforge.net/projects/libusbx/files/latest/download?source=files * libusbx-1.0.18 or later from http://sourceforge.net/projects/libusbx/files/latest/download?source=files
* fftw-3.3.5 or later from http://www.fftw.org/install/windows.html * fftw-3.3.5 or later from http://www.fftw.org/install/windows.html
* Install Windows driver for HackRF hardware or use Zadig see http://sourceforge.net/projects/libwdi/files/zadig * 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. - If you want to use Zadig select HackRF USB device and just install/replace it with WinUSB driver.
>**Note for Windows build:** >**Note for Windows build:**
You shall always execute hackrf-tools from Windows command shell and not from Cygwin or Mingw shell because on Cygwin/Mingw You shall always execute hackrf-tools from Windows command shell and not from Cygwin or MinGW shell because on Cygwin/MinGW
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:
``` ```
mkdir host/build mkdir host/build
cd host/build cd host/build
@ -52,7 +52,7 @@ make
make install make install
``` ```
###For MinGW: ### For MinGW:
``` ```
mkdir host/build mkdir host/build
cd host/build cd host/build
@ -61,7 +61,7 @@ make
make install make install
``` ```
###For Visual Studio 2015 x64 ### For Visual Studio 2015 x64
Create library definition for MSVC to link to Create library definition for MSVC to link to
`C:\fftw-3.3.5-dll64> lib /machine:x64 /def:libfftw3f-3.def` `C:\fftw-3.3.5-dll64> lib /machine:x64 /def:libfftw3f-3.def`
@ -75,11 +75,11 @@ c:\hackrf\host\build> cmake ../ -G "Visual Studio 14 2015 Win64" \
-DFFTW_LIBRARIES=C:\fftw-3.3.5-dll64\libfftw3f-3.lib -DFFTW_LIBRARIES=C:\fftw-3.3.5-dll64\libfftw3f-3.lib
``` ```
Cmake will produce a solution file named `HackRF.sln` and a series of CMake will produce a solution file named `HackRF.sln` and a series of
project files which can be built with msbuild as follows: project files which can be built with msbuild as follows:
`c:\hackrf\host\build> msbuild HackRF.sln` `c:\hackrf\host\build> msbuild HackRF.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`

View File

@ -31,6 +31,7 @@ SET(TOOLS
hackrf_cpldjtag hackrf_cpldjtag
hackrf_info hackrf_info
hackrf_debug hackrf_debug
hackrf_clock
hackrf_sweep hackrf_sweep
hackrf_operacake hackrf_operacake
) )

View File

@ -0,0 +1,337 @@
/*
* Copyright 2017 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 <string.h>
#include <stdlib.h>
#include <getopt.h>
#ifndef bool
typedef int bool;
#define true 1
#define false 0
#endif
#define CLOCK_UNDEFINED 0xFF
#define REGISTER_INVALID 32767
int parse_int(char* s, uint16_t* const value) {
uint_fast8_t base = 10;
char* s_end;
long long_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;
long_value = strtol(s, &s_end, base);
if( (s != s_end) && (*s_end == 0) ) {
*value = (uint16_t)long_value;
return HACKRF_SUCCESS;
} else {
return HACKRF_ERROR_INVALID_PARAM;
}
}
int si5351c_read_register(hackrf_device* device, const uint16_t register_number) {
uint16_t register_value;
int result = hackrf_si5351c_read(device, register_number, &register_value);
if( result == HACKRF_SUCCESS ) {
printf("[%3d] -> 0x%02x\n", register_number, register_value);
} else {
printf("hackrf_si5351c_read() failed: %s (%d)\n", hackrf_error_name(result), result);
}
return result;
}
int si5351c_write_register(
hackrf_device* device,
const uint16_t register_number,
const uint16_t register_value
) {
int result = HACKRF_SUCCESS;
result = hackrf_si5351c_write(device, register_number, register_value);
if( result == HACKRF_SUCCESS ) {
printf("0x%2x -> [%3d]\n", register_value, register_number);
} else {
printf("hackrf_max2837_write() failed: %s (%d)\n", hackrf_error_name(result), result);
}
return result;
}
#define SI5351C_CLK_POWERDOWN (1<<7)
#define SI5351C_CLK_INT_MODE (1<<6)
#define SI5351C_CLK_PLL_SRC (1<<5)
#define SI5351C_CLK_INV (1<<4)
#define SI5351C_CLK_SRC_XTAL 0
#define SI5351C_CLK_SRC_CLKIN 1
#define SI5351C_CLK_SRC_MULTISYNTH_0_4 2
#define SI5351C_CLK_SRC_MULTISYNTH_SELF 3
void print_clk_control(uint8_t clk_ctrl) {
uint8_t clk_src, clk_pwr;
printf("\tclock control = ");
if(clk_ctrl & SI5351C_CLK_POWERDOWN)
printf("Down, ");
else
printf("Up, ");
if(clk_ctrl & SI5351C_CLK_INT_MODE)
printf("Int Mode, ");
else
printf("Frac Mode, ");
if(clk_ctrl & SI5351C_CLK_PLL_SRC)
printf("PLL src B, ");
else
printf("PLL src A, ");
if(clk_ctrl & SI5351C_CLK_INV)
printf("Inverted, ");
clk_src = (clk_ctrl >> 2) & 0x3;
switch (clk_src) {
case 0:
printf("XTAL, ");
break;
case 1:
printf("CLKIN, ");
break;
case 2:
printf("MULTISYNTH 0 4, ");
break;
case 3:
printf("MULTISYNTH SELF, ");
break;
}
clk_pwr = clk_ctrl & 0x3;
switch (clk_pwr) {
case 0:
printf("2 mA\n");
break;
case 1:
printf("4 mA\n");
break;
case 2:
printf("6 mA\n");
break;
case 3:
printf("8 mA\n");
break;
}
}
int si5351c_read_multisynth_config(hackrf_device* device, const uint_fast8_t ms_number) {
uint_fast8_t i, reg_base, reg_number;
uint16_t parameters[8], clk_control;
uint32_t p1,p2,p3,r_div;
uint_fast8_t div_lut[] = {1,2,4,8,16,32,64,128};
int result;
printf("MS%d:\n", ms_number);
result = hackrf_si5351c_read(device, 16+ms_number, &clk_control);
if( result != HACKRF_SUCCESS ) {
return result;
}
print_clk_control(clk_control);
if(ms_number <6){
reg_base = 42 + (ms_number * 8);
for(i=0; i<8; i++) {
reg_number = reg_base + i;
result = hackrf_si5351c_read(device, reg_number, &parameters[i]);
if( result != HACKRF_SUCCESS ) {
return result;
}
}
p1 = ((parameters[2] & 0x03) << 16)
| (parameters[3] << 8)
| parameters[4];
p2 = ((parameters[5] & 0x0F) << 16)
| (parameters[6] << 8)
| parameters[7];
p3 = ((parameters[5] & 0xF0) << 12)
| (parameters[0] << 8)
| parameters[1];
r_div = (parameters[2] >> 4) & 0x7;
printf("\tp1 = %u\n", p1);
printf("\tp2 = %u\n", p2);
printf("\tp3 = %u\n", p3);
if(p3)
printf("\tOutput (800Mhz PLL): %#.10f Mhz\n", ((double)800 / (double)(((double)p1*p3 + p2 + 512*p3)/(double)(128*p3))) / div_lut[r_div] );
} else {
// MS6 and 7 are integer only
unsigned int parms;
reg_base = 90;
for(i=0; i<3; i++) {
uint_fast8_t reg_number = reg_base + i;
int result = hackrf_si5351c_read(device, reg_number, &parameters[i]);
if( result != HACKRF_SUCCESS ) {
return result;
}
}
r_div = (ms_number == 6) ? parameters[2] & 0x7 : (parameters[2] & 0x70) >> 4 ;
parms = (ms_number == 6) ? parameters[0] : parameters[1];
printf("\tp1_int = %u\n", parms);
if(parms)
printf("\tOutput (800Mhz PLL): %#.10f Mhz\n", (800.0f / parms) / div_lut[r_div] );
}
printf("\toutput divider = %u\n", div_lut[r_div]);
return HACKRF_SUCCESS;
}
int si5351c_read_configuration(hackrf_device* device) {
uint_fast8_t ms_number;
int result;
for(ms_number=0; ms_number<8; ms_number++) {
result = si5351c_read_multisynth_config(device, ms_number);
if( result != HACKRF_SUCCESS ) {
return result;
}
}
return HACKRF_SUCCESS;
}
static void usage() {
printf("hackrf_clock - HackRF clock configuration utility\n");
printf("Usage:\n");
printf("\t-h, --help: this help\n");
printf("\t-r, --read <clock_num>: read settings for clock_num\n");
printf("\t-a, --all: read settings for all clocks\n");
printf("\t-o, --clkout <clkout_enable>: enable/disable CLKOUT\n");
printf("\t-d, --device <serial_number>: Serial number of desired HackRF.\n");
printf("\nExamples:\n");
printf("\thackrf_clock -r 3 : prints settings for CLKOUT\n");
}
static struct option long_options[] = {
{ "help", no_argument, 0, 'h' },
{ "read", required_argument, 0, 'r' },
{ "all", no_argument, 0, 'a' },
{ "clkout", required_argument, 0, 'o' },
{ "device", required_argument, 0, 'd' },
{ 0, 0, 0, 0 },
};
int main(int argc, char** argv) {
hackrf_device* device = NULL;
int opt, option_index = 0;
bool read = false;
uint16_t clock = CLOCK_UNDEFINED;
bool clkout = false;
uint16_t clkout_enable;
const char* serial_number = NULL;
int result = hackrf_init();
if(result) {
printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result);
return EXIT_FAILURE;
}
while( (opt = getopt_long(argc, argv, "r:ao:d:h?", long_options, &option_index)) != EOF ) {
switch( opt ) {
case 'r':
read = true;
result = parse_int(optarg, &clock);
break;
case 'a':
read = true;
break;
case 'o':
clkout = true;
result = parse_int(optarg, &clkout_enable);
break;
case 'd':
serial_number = optarg;
break;
case 'h':
case '?':
usage();
return EXIT_SUCCESS;
default:
fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg);
usage();
return EXIT_FAILURE;
}
if(result != HACKRF_SUCCESS) {
printf("argument error: %s (%d)\n", hackrf_error_name(result), result);
usage();
return EXIT_FAILURE;
}
}
if(!clkout && !read) {
fprintf(stderr, "Either read or enable CLKOUT option must be specified.\n");
usage();
return EXIT_FAILURE;
}
result = hackrf_open_by_serial(serial_number, &device);
if(result) {
printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result);
return EXIT_FAILURE;
}
if(clkout) {
result = hackrf_set_clkout_enable(device, clkout_enable);
if(result) {
printf("hackrf_set_clkout_enable() failed: %s (%d)\n", hackrf_error_name(result), result);
return EXIT_FAILURE;
}
}
if(read) {
if(clock == CLOCK_UNDEFINED)
si5351c_read_configuration(device);
else {
printf("%d\n", clock);
si5351c_read_multisynth_config(device, clock);
}
}
result = hackrf_close(device);
if(result) {
printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result);
return EXIT_FAILURE;
}
hackrf_exit();
return EXIT_SUCCESS;
}

View File

@ -51,6 +51,7 @@ static struct option long_options[] = {
{ "length", required_argument, 0, 'l' }, { "length", required_argument, 0, 'l' },
{ "read", required_argument, 0, 'r' }, { "read", required_argument, 0, 'r' },
{ "write", required_argument, 0, 'w' }, { "write", required_argument, 0, 'w' },
{ "compatibility", no_argument, 0, 'c' },
{ "device", required_argument, 0, 'd' }, { "device", required_argument, 0, 'd' },
{ "reset", no_argument, 0, 'R' }, { "reset", no_argument, 0, 'R' },
{ "status", no_argument, 0, 's' }, { "status", no_argument, 0, 's' },
@ -60,6 +61,54 @@ static struct option long_options[] = {
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 },
}; };
/* Check for USB product string descriptor text in firmware file
* It should match the appropriate one for the BOARD_ID
* If you're already running firmware that reports the wrong ID
* I can't help you, but you can use the -i optionto ignore (or DFU)
*/
int compatibility_check(uint8_t* data, int length, hackrf_device* device)
{
int str_len, i,j;
bool match = false;
uint8_t board_id;
char* dev_str;
hackrf_board_id_read(device, &board_id);
switch(board_id)
{
case BOARD_ID_JAWBREAKER:
dev_str = "HackRF Jawbreaker";
str_len = 17;
break;
case BOARD_ID_HACKRF_ONE:
dev_str = "HackRF One";
str_len = 10;
break;
case BOARD_ID_RAD1O:
dev_str = "rad1o";
str_len = 5;
break;
default:
printf("Unknown Board ID");
return 1;
}
// Search for dev_str in uint8_t array of bytes that we're flashing
for(i=0; i<length-str_len; i++){
if(data[i] == dev_str[0]) {
match = true;
for(j=1; j<str_len; j++) {
if((data[i+j*2] != dev_str[j]) ||
(data[1+i+j*2] != 0x00)) {
match = false;
break;
}
}
if(match)
return 0;
}
}
return 1;
}
int parse_u32(char* s, uint32_t* const value) int parse_u32(char* s, uint32_t* const value)
{ {
char* s_end; char* s_end;
@ -96,6 +145,7 @@ static void usage()
printf("\t-l, --length <n>: number of bytes to read (default: %d)\n", MAX_LENGTH); printf("\t-l, --length <n>: number of bytes to read (default: %d)\n", MAX_LENGTH);
printf("\t-r, --read <filename>: Read data into file.\n"); printf("\t-r, --read <filename>: Read data into file.\n");
printf("\t-w, --write <filename>: Write data from file.\n"); printf("\t-w, --write <filename>: Write data from file.\n");
printf("\t-i, --no-check: Skip check for firmware compatibility with target device.\n");
printf("\t-d, --device <serialnumber>: Serial number of device, if multiple devices\n"); printf("\t-d, --device <serialnumber>: Serial number of device, if multiple devices\n");
printf("\t-s, --status: Read SPI flash status registers before other operations.\n"); printf("\t-s, --status: Read SPI flash status registers before other operations.\n");
printf("\t-c, --clear: Clear SPI flash status registers before other operations.\n"); printf("\t-c, --clear: Clear SPI flash status registers before other operations.\n");
@ -121,13 +171,14 @@ int main(int argc, char** argv)
FILE* fd = NULL; FILE* fd = NULL;
bool read = false; bool read = false;
bool write = false; bool write = false;
bool ignore_compat_check = false;
bool verbose = false; bool verbose = false;
bool reset = false; bool reset = false;
bool read_status = false; bool read_status = false;
bool clear_status = false; bool clear_status = false;
uint16_t usb_api; uint16_t usb_api;
while ((opt = getopt_long(argc, argv, "a:l:r:w:d:scvRh?", long_options, while ((opt = getopt_long(argc, argv, "a:l:r:w:id:scvRh?", long_options,
&option_index)) != EOF) { &option_index)) != EOF) {
switch (opt) { switch (opt) {
case 'a': case 'a':
@ -148,6 +199,10 @@ int main(int argc, char** argv)
path = optarg; path = optarg;
break; break;
case 'i':
ignore_compat_check = true;
break;
case 'd': case 'd':
serial_number = optarg; serial_number = optarg;
break; break;
@ -329,6 +384,16 @@ int main(int argc, char** argv)
fd = NULL; fd = NULL;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if(!ignore_compat_check) {
printf("Checking target device compatibility\n");
result = compatibility_check(data, length, device);
if(result) {
printf("Compatibility test failed.\n");
fclose(fd);
fd = NULL;
return EXIT_FAILURE;
}
}
printf("Erasing SPI flash.\n"); printf("Erasing SPI flash.\n");
result = hackrf_spiflash_erase(device); result = hackrf_spiflash_erase(device);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {

View File

@ -252,8 +252,8 @@ int rx_callback(hackrf_transfer* transfer) {
(uint64_t)(num_samples + THROWAWAY_BLOCKS * SAMPLES_PER_BLOCK) (uint64_t)(num_samples + THROWAWAY_BLOCKS * SAMPLES_PER_BLOCK)
* j * FREQ_ONE_MHZ / DEFAULT_SAMPLE_RATE_HZ; * j * FREQ_ONE_MHZ / DEFAULT_SAMPLE_RATE_HZ;
if(999999 < time_stamp.tv_usec) { if(999999 < time_stamp.tv_usec) {
time_stamp.tv_usec = time_stamp.tv_usec % 1000000;
time_stamp.tv_sec += time_stamp.tv_usec / 1000000; time_stamp.tv_sec += time_stamp.tv_usec / 1000000;
time_stamp.tv_usec = time_stamp.tv_usec % 1000000;
} }
} }
if(do_exit) { if(do_exit) {
@ -310,7 +310,8 @@ int rx_callback(hackrf_transfer* transfer) {
ifftwIn[ifft_idx + i][1] = fftwOut[i + 1 + (fftSize/8)][1]; ifftwIn[ifft_idx + i][1] = fftwOut[i + 1 + (fftSize/8)][1];
} }
} else { } else {
fft_time = localtime(&time_stamp.tv_sec); time_t time_stamp_seconds = time_stamp.tv_sec;
fft_time = localtime(&time_stamp_seconds);
strftime(time_str, 50, "%Y-%m-%d, %H:%M:%S", fft_time); strftime(time_str, 50, "%Y-%m-%d, %H:%M:%S", fft_time);
fprintf(fd, "%s.%06ld, %" PRIu64 ", %" PRIu64 ", %.2f, %u", fprintf(fd, "%s.%06ld, %" PRIu64 ", %" PRIu64 ", %.2f, %u",
time_str, time_str,

View File

@ -79,8 +79,9 @@ typedef enum {
HACKRF_VENDOR_REQUEST_SET_HW_SYNC_MODE = 29, HACKRF_VENDOR_REQUEST_SET_HW_SYNC_MODE = 29,
HACKRF_VENDOR_REQUEST_RESET = 30, HACKRF_VENDOR_REQUEST_RESET = 30,
HACKRF_VENDOR_REQUEST_OPERACAKE_SET_RANGES = 31, HACKRF_VENDOR_REQUEST_OPERACAKE_SET_RANGES = 31,
HACKRF_VENDOR_REQUEST_SPIFLASH_STATUS = 32, HACKRF_VENDOR_REQUEST_CLKOUT_ENABLE = 32,
HACKRF_VENDOR_REQUEST_SPIFLASH_CLEAR_STATUS = 33, HACKRF_VENDOR_REQUEST_SPIFLASH_STATUS = 33,
HACKRF_VENDOR_REQUEST_SPIFLASH_CLEAR_STATUS = 34,
} hackrf_vendor_request; } hackrf_vendor_request;
#define USB_CONFIG_STANDARD 0x1 #define USB_CONFIG_STANDARD 0x1
@ -2043,6 +2044,30 @@ int ADDCALL hackrf_set_operacake_ranges(hackrf_device* device, uint8_t* ranges,
} }
} }
int ADDCALL hackrf_set_clkout_enable(hackrf_device* device, const uint8_t value)
{
USB_API_REQUIRED(device, 0x0103)
int result;
result = libusb_control_transfer(
device->usb_device,
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
HACKRF_VENDOR_REQUEST_CLKOUT_ENABLE,
value,
0,
NULL,
0,
0
);
if (result != 0)
{
last_libusb_error = result;
return HACKRF_ERROR_LIBUSB;
} else {
return HACKRF_SUCCESS;
}
}
#ifdef __cplusplus #ifdef __cplusplus
} // __cplusplus defined. } // __cplusplus defined.
#endif #endif

View File

@ -248,6 +248,8 @@ extern ADDAPI int ADDCALL hackrf_set_operacake_ranges(hackrf_device* device,
uint8_t* ranges, uint8_t* ranges,
uint8_t num_ranges); uint8_t num_ranges);
extern ADDAPI int ADDCALL hackrf_set_clkout_enable(hackrf_device* device, const uint8_t value);
#ifdef __cplusplus #ifdef __cplusplus
} // __cplusplus defined. } // __cplusplus defined.
#endif #endif