From a4036eab76098376044997db6e673825f5679f35 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Thu, 16 Feb 2017 18:03:32 -0700 Subject: [PATCH 01/16] Remove last mentions of Jellybean --- firmware/common/LPC4330_M4_memory.ld | 34 - firmware/common/hackrf_core.c | 10 +- firmware/cpld/sgpio_if/README.md | 20 +- firmware/cpld/sgpio_if/program | 10 - firmware/cpld/sgpio_if_passthrough/README.md | 37 - firmware/cpld/sgpio_if_passthrough/program | 10 - .../sgpio_if_passthrough.svf | 2079 ----------------- .../sgpio_if_passthrough.xise | 242 -- firmware/cpld/sgpio_if_passthrough/top.ucf | 89 - firmware/cpld/sgpio_if_passthrough/top.vhd | 60 - 10 files changed, 5 insertions(+), 2586 deletions(-) delete mode 100644 firmware/common/LPC4330_M4_memory.ld delete mode 100755 firmware/cpld/sgpio_if/program delete mode 100644 firmware/cpld/sgpio_if_passthrough/README.md delete mode 100755 firmware/cpld/sgpio_if_passthrough/program delete mode 100755 firmware/cpld/sgpio_if_passthrough/sgpio_if_passthrough.svf delete mode 100755 firmware/cpld/sgpio_if_passthrough/sgpio_if_passthrough.xise delete mode 100755 firmware/cpld/sgpio_if_passthrough/top.ucf delete mode 100755 firmware/cpld/sgpio_if_passthrough/top.vhd diff --git a/firmware/common/LPC4330_M4_memory.ld b/firmware/common/LPC4330_M4_memory.ld deleted file mode 100644 index 42e217cf..00000000 --- a/firmware/common/LPC4330_M4_memory.ld +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2012 Michael Ossmann - * 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. - */ - -/* Linker script for HackRF Jellybean/Jawbreaker (LPC4330, 1M SPI flash, 264K SRAM). */ - -MEMORY -{ - /* rom is really the shadow region that points to SPI flash or elsewhere */ - rom (rx) : ORIGIN = 0x00000000, LENGTH = 128K - ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K - ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 64K - ram_sleep (rwx) : ORIGIN = 0x10090000, LENGTH = 8K -} - -INCLUDE LPC43xx_M4_memory.ld diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 9bdcf9d6..80841c65 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -470,8 +470,7 @@ bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz) { return bandwidth_hz_real != 0; } -/* clock startup for Jellybean with Lemondrop attached -Configure PLL1 to max speed (204MHz). +/* clock startup for LPC4320 configure PLL1 to max speed (204MHz). Note: PLL1 clock is used by M4/M0 core, Peripheral, APB1. */ void cpu_clock_init(void) { @@ -546,7 +545,7 @@ void cpu_clock_init(void) si5351c_write(&clock_gen, ms7data, sizeof(ms7data)); #endif - /* Set to 10 MHz, the common rate between Jellybean and Jawbreaker. */ + /* Set to 10 MHz, the common rate between Jawbreaker and HackRF One. */ sample_rate_set(10000000); si5351c_set_clock_source(&clock_gen, PLL_SOURCE_XTAL); @@ -560,9 +559,8 @@ void cpu_clock_init(void) i2c_bus_start(clock_gen.bus, &i2c_config_si5351c_fast_clock); /* - * 12MHz clock is entering LPC XTAL1/OSC input now. On - * Jellybean/Lemondrop, this is a signal from the clock generator. On - * Jawbreaker, there is a 12 MHz crystal at the LPC. + * 12MHz clock is entering LPC XTAL1/OSC input now. + * On HackRF One and Jawbreaker, there is a 12 MHz crystal at the LPC. * Set up PLL1 to run from XTAL1 input. */ diff --git a/firmware/cpld/sgpio_if/README.md b/firmware/cpld/sgpio_if/README.md index 44fe9a8c..e56d33a6 100644 --- a/firmware/cpld/sgpio_if/README.md +++ b/firmware/cpld/sgpio_if/README.md @@ -8,20 +8,6 @@ To build this VHDL project and produce an SVF file for flashing the CPLD: * Xilinx WebPACK 13.4 for Windows or Linux. -To program the SVF file into the CPLD: - -* Dangerous Prototypes Bus Blaster v2: - * Configured with [JTAGKey buffers](http://dangerousprototypes.com/docs/Bus_Blaster_v2_buffer_logic). - * Connected to CPLD JTAG signals on Jellybean. - -* urJTAG built with libftdi support. - -* BSDL model files for Xilinx CoolRunner-II XC264A, available at xilinx.com, - in the "Device Models" Support Resources section of the CoolRunner-II - Product Support & Documentation page. Only one file from the BSDL package is - required, and the "program" script below expects it to be at the relative - path "bsdl/xc2c/xc2c64.bsd". - Generate an XSVF ================ @@ -44,8 +30,4 @@ After generating a programming file: To Program ========== -./program - -...which connects to the Bus Blaster interface 0, sets the BSDL directory, -detects devices on the JTAG chain, and writes the sgpio_if.svf file to the -CPLD. +$ hackrf_cpldjtag -x default.xsvf diff --git a/firmware/cpld/sgpio_if/program b/firmware/cpld/sgpio_if/program deleted file mode 100755 index d0b097ca..00000000 --- a/firmware/cpld/sgpio_if/program +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -echo Program Xilinx CoolRunner-II CPLD on Jellybean, using Bus Blaster v2 - -jtag < SGPIO[0-15] -B1AUX9=1 control SGPIO0 to 15 as Output. SGPIO[0-15] => B2AUX[1-16] diff --git a/firmware/cpld/sgpio_if_passthrough/program b/firmware/cpld/sgpio_if_passthrough/program deleted file mode 100755 index 0aba6b0e..00000000 --- a/firmware/cpld/sgpio_if_passthrough/program +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -echo Program Xilinx CoolRunner-II CPLD on Jellybean, using Bus Blaster v2 - -jtag < - - -
- - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/firmware/cpld/sgpio_if_passthrough/top.ucf b/firmware/cpld/sgpio_if_passthrough/top.ucf deleted file mode 100755 index cd6a2e70..00000000 --- a/firmware/cpld/sgpio_if_passthrough/top.ucf +++ /dev/null @@ -1,89 +0,0 @@ -# -# 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. - -NET "CODEC_CLK" LOC="23" |FAST |IOSTANDARD=LVCMOS18; -NET "CODEC_X2_CLK" LOC="27" |FAST |IOSTANDARD=LVCMOS18; -#NET "GCLK0" LOC="22" |FAST |IOSTANDARD=LVCMOS18; - -NET "CODEC_X2_CLK" TNM_NET = CODEC_X2_CLK; -TIMESPEC TS_codec_x2_data = PERIOD "CODEC_X2_CLK" 50 ns; - -NET "DA<7>" LOC="35" |FAST |IOSTANDARD=LVCMOS18; -NET "DA<6>" LOC="36" |FAST |IOSTANDARD=LVCMOS18; -NET "DA<5>" LOC="37" |FAST |IOSTANDARD=LVCMOS18; -NET "DA<4>" LOC="39" |FAST |IOSTANDARD=LVCMOS18; -NET "DA<3>" LOC="40" |FAST |IOSTANDARD=LVCMOS18; -NET "DA<2>" LOC="41" |FAST |IOSTANDARD=LVCMOS18; -NET "DA<1>" LOC="42" |FAST |IOSTANDARD=LVCMOS18; -NET "DA<0>" LOC="43" |FAST |IOSTANDARD=LVCMOS18; - -NET "DD<9>" LOC="17" |FAST |IOSTANDARD=LVCMOS18; -NET "DD<8>" LOC="18" |FAST |IOSTANDARD=LVCMOS18; -NET "DD<7>" LOC="19" |FAST |IOSTANDARD=LVCMOS18; -NET "DD<6>" LOC="24" |FAST |IOSTANDARD=LVCMOS18; -NET "DD<5>" LOC="28" |FAST |IOSTANDARD=LVCMOS18; -NET "DD<4>" LOC="29" |FAST |IOSTANDARD=LVCMOS18; -NET "DD<3>" LOC="30" |FAST |IOSTANDARD=LVCMOS18; -NET "DD<2>" LOC="32" |FAST |IOSTANDARD=LVCMOS18; -NET "DD<1>" LOC="33" |FAST |IOSTANDARD=LVCMOS18; -NET "DD<0>" LOC="34" |FAST |IOSTANDARD=LVCMOS18; - -NET "B1AUX<16>" LOC="60" |FAST |IOSTANDARD=LVCMOS18; -NET "B1AUX<15>" LOC="58" |FAST |IOSTANDARD=LVCMOS18; -NET "B1AUX<14>" LOC="56" |FAST |IOSTANDARD=LVCMOS18; -NET "B1AUX<13>" LOC="55" |FAST |IOSTANDARD=LVCMOS18; -NET "B1AUX<12>" LOC="53" |FAST |IOSTANDARD=LVCMOS18; -NET "B1AUX<11>" LOC="52" |FAST |IOSTANDARD=LVCMOS18; -NET "B1AUX<10>" LOC="50" |FAST |IOSTANDARD=LVCMOS18; -NET "B1AUX<9>" LOC="49" |FAST |IOSTANDARD=LVCMOS18; - -NET "SGPIO<15>" LOC="78" |FAST |IOSTANDARD=LVCMOS33; -NET "SGPIO<14>" LOC="81" |FAST |IOSTANDARD=LVCMOS33; -NET "SGPIO<13>" LOC="90" |FAST |IOSTANDARD=LVCMOS33; -NET "SGPIO<12>" LOC="70" |FAST |IOSTANDARD=LVCMOS33; -NET "SGPIO<11>" LOC="71" |FAST |IOSTANDARD=LVCMOS33; -NET "SGPIO<10>" LOC="76" |FAST |IOSTANDARD=LVCMOS33; -NET "SGPIO<9>" LOC="91" |FAST |IOSTANDARD=LVCMOS33; -NET "SGPIO<8>" LOC="68" |FAST |IOSTANDARD=LVCMOS33; -NET "SGPIO<7>" LOC="77" |FAST |IOSTANDARD=LVCMOS33; -NET "SGPIO<6>" LOC="61" |FAST |IOSTANDARD=LVCMOS33; -NET "SGPIO<5>" LOC="64" |FAST |IOSTANDARD=LVCMOS33; -NET "SGPIO<4>" LOC="67" |FAST |IOSTANDARD=LVCMOS33; -NET "SGPIO<3>" LOC="72" |FAST |IOSTANDARD=LVCMOS33; -NET "SGPIO<2>" LOC="74" |FAST |IOSTANDARD=LVCMOS33; -NET "SGPIO<1>" LOC="79" |FAST |IOSTANDARD=LVCMOS33; -NET "SGPIO<0>" LOC="89" |FAST |IOSTANDARD=LVCMOS33; - -NET "B2AUX<16>" LOC="92" |FAST |IOSTANDARD=LVCMOS33; -NET "B2AUX<15>" LOC="94" |FAST |IOSTANDARD=LVCMOS33; -NET "B2AUX<14>" LOC="97" |FAST |IOSTANDARD=LVCMOS33; -NET "B2AUX<13>" LOC="99" |FAST |IOSTANDARD=LVCMOS33; -NET "B2AUX<12>" LOC="1" |FAST |IOSTANDARD=LVCMOS33; -NET "B2AUX<11>" LOC="2" |FAST |IOSTANDARD=LVCMOS33; -NET "B2AUX<10>" LOC="3" |FAST |IOSTANDARD=LVCMOS33; -NET "B2AUX<9>" LOC="4" |FAST |IOSTANDARD=LVCMOS33; -NET "B2AUX<8>" LOC="6" |FAST |IOSTANDARD=LVCMOS33; -NET "B2AUX<7>" LOC="7" |FAST |IOSTANDARD=LVCMOS33; -NET "B2AUX<6>" LOC="8" |FAST |IOSTANDARD=LVCMOS33; -NET "B2AUX<5>" LOC="9" |FAST |IOSTANDARD=LVCMOS33; -NET "B2AUX<4>" LOC="10" |FAST |IOSTANDARD=LVCMOS33; -NET "B2AUX<3>" LOC="11" |FAST |IOSTANDARD=LVCMOS33; -NET "B2AUX<2>" LOC="12" |FAST |IOSTANDARD=LVCMOS33; -NET "B2AUX<1>" LOC="13" |FAST |IOSTANDARD=LVCMOS33; diff --git a/firmware/cpld/sgpio_if_passthrough/top.vhd b/firmware/cpld/sgpio_if_passthrough/top.vhd deleted file mode 100755 index 55be76b6..00000000 --- a/firmware/cpld/sgpio_if_passthrough/top.vhd +++ /dev/null @@ -1,60 +0,0 @@ --- --- 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. - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; - -library UNISIM; -use UNISIM.vcomponents.all; - -entity top is - Port( - SGPIO : inout std_logic_vector(15 downto 0); - - DA : in std_logic_vector(7 downto 0); - DD : out std_logic_vector(9 downto 0); - - CODEC_CLK : in std_logic; - CODEC_X2_CLK : in std_logic; - - B1AUX : in std_logic_vector(16 downto 9); - B2AUX : inout std_logic_vector(16 downto 1) - ); - -end top; - -architecture Behavioral of top is - type transfer_direction is (to_sgpio, from_sgpio); - signal transfer_direction_i : transfer_direction; - -begin - - transfer_direction_i <= to_sgpio when B1AUX(9) = '0' - else from_sgpio; - - DD <= (DD'high => '1', others => '0'); - - B2AUX <= SGPIO when transfer_direction_i = from_sgpio - else (others => 'Z'); - - SGPIO <= B2AUX when transfer_direction_i = to_sgpio - else (others => 'Z'); - -end Behavioral; From ef695a36e0be232aab8056bb4dfa52ac7d543d7f Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Fri, 17 Feb 2017 07:49:16 -0700 Subject: [PATCH 02/16] Reinstate LPC4330 linker script --- firmware/common/LPC4330_M4_memory.ld | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 firmware/common/LPC4330_M4_memory.ld diff --git a/firmware/common/LPC4330_M4_memory.ld b/firmware/common/LPC4330_M4_memory.ld new file mode 100644 index 00000000..b2f6b8e2 --- /dev/null +++ b/firmware/common/LPC4330_M4_memory.ld @@ -0,0 +1,34 @@ +/* + * Copyright 2012 Michael Ossmann + * 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. + */ + +/* Linker script for Rad1o badge - (LPC4330, 1M SPI flash, 264K SRAM). */ + +MEMORY +{ + /* rom is really the shadow region that points to SPI flash or elsewhere */ + rom (rx) : ORIGIN = 0x00000000, LENGTH = 128K + ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K + ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 64K + ram_sleep (rwx) : ORIGIN = 0x10090000, LENGTH = 8K +} + +INCLUDE LPC43xx_M4_memory.ld From d4c69890b5629e416935494d368f1865d4c0c957 Mon Sep 17 00:00:00 2001 From: schneider Date: Sun, 19 Feb 2017 01:38:11 +0100 Subject: [PATCH 03/16] fix(rad1o): Restore old clock behaviour for now. --- firmware/common/hackrf_core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 9bdcf9d6..e64bf9c0 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -634,6 +634,7 @@ void cpu_clock_init(void) CGU_BASE_SSP1_CLK = CGU_BASE_SSP1_CLK_AUTOBLOCK(1) | CGU_BASE_SSP1_CLK_CLK_SEL(CGU_SRC_PLL1); +#if (defined JAWBREAKER || defined HACKRF_ONE) /* Disable unused clocks */ /* Start with PLLs */ CGU_PLL0AUDIO_CTRL = CGU_PLL0AUDIO_CTRL_PD(1); @@ -699,6 +700,13 @@ void cpu_clock_init(void) // CCU2_CLK_APB2_USART3_CFG = 0; // CCU2_CLK_APLL_CFG = 0; // CCU2_CLK_SDIO_CFG = 0; +#endif + +#ifdef RAD1O + /* Disable unused clock outputs. They generate noise. */ + scu_pinmux(CLK0, SCU_CLK_IN | SCU_CONF_FUNCTION7); + scu_pinmux(CLK2, SCU_CLK_IN | SCU_CONF_FUNCTION7); +#endif } From 13e4dea446442a05d89b7ea130dbc78f9078ffb9 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Sun, 19 Feb 2017 11:10:30 -0700 Subject: [PATCH 04/16] hackrf_sweep: avoid starting RX too early --- host/hackrf-tools/src/hackrf_sweep.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 3d400942..61a4272b 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -581,12 +581,6 @@ int main(int argc, char** argv) { 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_rx() failed: %s (%d)\n", hackrf_error_name(result), result); - usage(); - return EXIT_FAILURE; - } /* * For each range, plan a whole number of tuning steps of a certain @@ -601,6 +595,13 @@ int main(int argc, char** argv) { frequencies[2*i], frequencies[2*i+1]); } + result |= hackrf_start_rx(device, rx_callback, NULL); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_start_rx() failed: %s (%d)\n", hackrf_error_name(result), result); + usage(); + return EXIT_FAILURE; + } + result = hackrf_init_sweep(device, frequencies, num_ranges, num_samples * 2, TUNE_STEP * FREQ_ONE_MHZ, OFFSET, INTERLEAVED); if( result != HACKRF_SUCCESS ) { From 3eb00ed0df83291e817d7902005f481022d226ba Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Mon, 20 Feb 2017 12:34:35 -0700 Subject: [PATCH 05/16] Disable CLK7 and power down CLK6/7 to reduce emissions --- firmware/common/hackrf_core.c | 40 +++++++---------------------------- firmware/common/si5351c.c | 7 +++--- 2 files changed, 12 insertions(+), 35 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 80841c65..5fe5d5ee 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -490,60 +490,36 @@ void cpu_clock_init(void) si5351c_configure_pll_sources(&clock_gen); si5351c_configure_pll_multisynth(&clock_gen); -#if (defined JAWBREAKER || defined HACKRF_ONE) /* - * Jawbreaker clocks: + * Clocks: * CLK0 -> MAX5864/CPLD * CLK1 -> CPLD * CLK2 -> SGPIO - * CLK3 -> external clock output - * CLK4 -> RFFC5072 - * CLK5 -> MAX2837 + * CLK3 -> External Clock Output + * CLK4 -> RFFC5072 (MAX2837 on rad1o) + * CLK5 -> MAX2837 (MAX2871 on rad1o) * CLK6 -> none - * CLK7 -> LPC4330 (but LPC4330 starts up on its own crystal) + * CLK7 -> LPC43xx (uses a 12MHz crystal by default) */ /* MS3/CLK3 is the source for the external clock output. */ si5351c_configure_multisynth(&clock_gen, 3, 80*128-512, 0, 1, 0); /* 800/80 = 10MHz */ +#if (defined JAWBREAKER || defined HACKRF_ONE) /* MS4/CLK4 is the source for the RFFC5071 mixer. */ si5351c_configure_multisynth(&clock_gen, 4, 16*128-512, 0, 1, 0); /* 800/16 = 50MHz */ - /* MS5/CLK5 is the source for the MAX2837 clock input. */ si5351c_configure_multisynth(&clock_gen, 5, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */ - - /* MS6/CLK6 is unused. */ - /* MS7/CLK7 is the source for the LPC43xx microcontroller. */ - uint8_t ms7data[] = { 90, 255, 20, 0 }; - si5351c_write(&clock_gen, ms7data, sizeof(ms7data)); #endif - #ifdef RAD1O - /* rad1o clocks: - * CLK0 -> MAX5864/CPLD - * CLK1 -> CPLD - * CLK2 -> SGPIO - * CLK3 -> External Clock Output - * CLK4 -> MAX2837 - * CLK5 -> MAX2871 - * CLK6 -> none - * CLK7 -> LPC4330 (but LPC4330 starts up on its own crystal) */ - - /* MS3/CLK3 is the source for the external clock output. */ - si5351c_configure_multisynth(&clock_gen, 3, 80*128-512, 0, 1, 0); /* 800/80 = 10MHz */ - /* MS4/CLK4 is the source for the MAX2837 clock input. */ si5351c_configure_multisynth(&clock_gen, 4, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */ - /* MS5/CLK5 is the source for the RFFC5071 mixer. */ si5351c_configure_multisynth(&clock_gen, 5, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */ +#endif /* MS6/CLK6 is unused. */ - - /* MS7/CLK7 is the source for the LPC43xx microcontroller. */ - uint8_t ms7data[] = { 90, 255, 20, 0 }; - si5351c_write(&clock_gen, ms7data, sizeof(ms7data)); -#endif + /* MS7/CLK7 is unused. */ /* Set to 10 MHz, the common rate between Jawbreaker and HackRF One. */ sample_rate_set(10000000); diff --git a/firmware/common/si5351c.c b/firmware/common/si5351c.c index 465b2370..18e4a091 100644 --- a/firmware/common/si5351c.c +++ b/firmware/common/si5351c.c @@ -184,7 +184,7 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_6MA) ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA) ,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/ - ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA) + ,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/ }; si5351c_write(drv, data, sizeof(data)); } @@ -223,8 +223,9 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll /* 3: External clock output is deactivated as it is not used and creates noise */ uint8_t data[] = { 3, ~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4) | (1 << 5))}; #else - /* Enable CLK outputs 0, 1, 2, 3, 4, 5, 7 only. */ - uint8_t data[] = { 3, 0x40 }; + /* Enable CLK outputs 0, 1, 2, 3, 4, 5. */ + /* 7: Clock to CPU is deactivated as it is not used and creates noise */ + uint8_t data[] = { 3, ~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5))}; #endif si5351c_write(drv, data, sizeof(data)); } From f34cc960ffa338c49f196599569f80dbf35f60f2 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Mon, 20 Feb 2017 21:07:00 -0700 Subject: [PATCH 06/16] hackrf_sweep: Added experimental Inverse FFT binary output mode. In this mode, FFT output bins from multiple hops are stitched together into a single set of bins per sweep. Each sweep is then processed with an inverse FFT to simulate a time domain signal at a sample rate equal to the sweep bandwidth. This wideband time domain signal is sent to the output as complex floats and can be piped to or viewed with tools such as fosphor or inspectrum. The output signal is discontinuous, so the time axis (e.g. in inspectrum) will be incorrect. --- host/hackrf-tools/src/hackrf_sweep.c | 68 ++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 9 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 61a4272b..ba43bfad 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -108,6 +108,7 @@ int gettimeofday(struct timeval *tv, void* ignored) { uint32_t num_samples = SAMPLES_PER_BLOCK; int num_ranges = 0; uint16_t frequencies[MAX_SWEEP_RANGES*2]; +int step_count; 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); @@ -175,6 +176,7 @@ bool antenna = false; uint32_t antenna_enable; bool binary_output = false; +bool ifft_output = false; bool one_shot = false; volatile bool sweep_started = false; @@ -183,6 +185,10 @@ double fft_bin_width; fftwf_complex *fftwIn = NULL; fftwf_complex *fftwOut = NULL; fftwf_plan fftwPlan = NULL; +fftwf_complex *ifftwIn = NULL; +fftwf_complex *ifftwOut = NULL; +fftwf_plan ifftwPlan = NULL; +uint32_t ifft_idx = 0; float* pwr; float* window; @@ -200,7 +206,7 @@ int rx_callback(hackrf_transfer* transfer) { uint64_t frequency; /* in Hz */ uint64_t band_edge; uint32_t record_length; - int i, j; + int i, j, ifft_bins; struct tm *fft_time; char time_str[50]; struct timeval usb_transfer_time; @@ -212,6 +218,7 @@ int rx_callback(hackrf_transfer* transfer) { gettimeofday(&usb_transfer_time, NULL); byte_count += transfer->valid_length; buf = (int8_t*) transfer->buffer; + ifft_bins = fftSize * step_count; for(j=0; j i; i++) { + ifftwIn[ifft_idx + i][0] = fftwOut[i + 1 + (fftSize*5)/8][0]; + ifftwIn[ifft_idx + i][1] = fftwOut[i + 1 + (fftSize*5)/8][1]; + } + ifft_idx += fftSize / 2; + ifft_idx %= ifft_bins; + for(i = 0; (fftSize / 4) > i; i++) { + ifftwIn[ifft_idx + i][0] = fftwOut[i + 1 + (fftSize/8)][0]; + ifftwIn[ifft_idx + i][1] = fftwOut[i + 1 + (fftSize/8)][1]; + } } else { fft_time = localtime(&time_stamp.tv_sec); strftime(time_str, 50, "%Y-%m-%d, %H:%M:%S", fft_time); @@ -285,8 +315,8 @@ int rx_callback(hackrf_transfer* transfer) { (uint64_t)(frequency+DEFAULT_SAMPLE_RATE_HZ/4), fft_bin_width, fftSize); - for(i=1+(fftSize*5)/8; (1+(fftSize*7)/8) > i; i++) { - fprintf(fd, ", %.2f", pwr[i]); + for(i = 0; (fftSize / 4) > i; i++) { + fprintf(fd, ", %.2f", pwr[i + 1 + (fftSize*5)/8]); } fprintf(fd, "\n"); fprintf(fd, "%s.%06ld, %" PRIu64 ", %" PRIu64 ", %.2f, %u", @@ -296,8 +326,8 @@ int rx_callback(hackrf_transfer* transfer) { (uint64_t)(frequency+((DEFAULT_SAMPLE_RATE_HZ*3)/4)), fft_bin_width, fftSize); - for(i=1+fftSize/8; (1+(fftSize*3)/8) > i; i++) { - fprintf(fd, ", %.2f", pwr[i]); + for(i = 0; (fftSize / 4) > i; i++) { + fprintf(fd, ", %.2f", pwr[i + 1 + (fftSize/8)]); } fprintf(fd, "\n"); } @@ -318,6 +348,7 @@ static void usage() { fprintf(stderr, "\t[-w bin_width] # FFT bin width (frequency resolution) in Hz\n"); fprintf(stderr, "\t[-1] # one shot mode\n"); fprintf(stderr, "\t[-B] # binary output\n"); + fprintf(stderr, "\t[-I] # binary inverse FFT output\n"); fprintf(stderr, "\t-r filename # output file"); fprintf(stderr, "\n"); fprintf(stderr, "Output fields:\n"); @@ -351,13 +382,12 @@ int main(int argc, char** argv) { struct timeval t_end; float time_diff; unsigned int lna_gain=16, vga_gain=20; - int step_count; uint32_t freq_min = 0; uint32_t freq_max = 6000; uint32_t requested_fft_bin_width; - while( (opt = getopt(argc, argv, "a:f:p:l:g:d:n:w:1Br:h?")) != EOF ) { + while( (opt = getopt(argc, argv, "a:f:p:l:g:d:n:w:1BIr:h?")) != EOF ) { result = HACKRF_SUCCESS; switch( opt ) { @@ -427,6 +457,10 @@ int main(int argc, char** argv) { binary_output = true; break; + case 'I': + ifft_output = true; + break; + case 'r': path = optarg; break; @@ -487,6 +521,16 @@ int main(int argc, char** argv) { num_ranges++; } + if(binary_output && ifft_output) { + fprintf(stderr, "argument error: binary output (-B) and IFFT output (-I) are mutually exclusive.\n"); + return EXIT_FAILURE; + } + + if(ifft_output && (1 < num_ranges)) { + fprintf(stderr, "argument error: only one frequency range is supported in IFFT output (-I) mode.\n"); + return EXIT_FAILURE; + } + if(4 > fftSize) { fprintf(stderr, "argument error: FFT bin width (-w) must be no more than one quarter the sample rate\n"); @@ -595,6 +639,10 @@ int main(int argc, char** argv) { frequencies[2*i], frequencies[2*i+1]); } + ifftwIn = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize * step_count); + ifftwOut = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize * step_count); + ifftwPlan = fftwf_plan_dft_1d(fftSize * step_count, ifftwIn, ifftwOut, FFTW_BACKWARD, FFTW_MEASURE); + result |= hackrf_start_rx(device, rx_callback, NULL); if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_start_rx() failed: %s (%d)\n", hackrf_error_name(result), result); @@ -703,6 +751,8 @@ int main(int argc, char** argv) { fftwf_free(fftwOut); fftwf_free(pwr); fftwf_free(window); + fftwf_free(ifftwIn); + fftwf_free(ifftwOut); fprintf(stderr, "exit\n"); return exit_code; } From 886ba6acfb7961fa331050567f49619dbd78799d Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Mon, 20 Feb 2017 21:42:02 -0700 Subject: [PATCH 07/16] hackrf_sweep: corrected output file descriptors in binary and ifft modes for compatibility with output file option --- host/hackrf-tools/src/hackrf_sweep.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index ba43bfad..6eec1ea8 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -235,8 +235,8 @@ int rx_callback(hackrf_transfer* transfer) { for(i=0; i < ifft_bins; i++) { ifftwOut[i][0] *= 1.0f / ifft_bins; ifftwOut[i][1] *= 1.0f / ifft_bins; - fwrite(&ifftwOut[i][0], sizeof(float), 1, stdout); - fwrite(&ifftwOut[i][1], sizeof(float), 1, stdout); + fwrite(&ifftwOut[i][0], sizeof(float), 1, fd); + fwrite(&ifftwOut[i][1], sizeof(float), 1, fd); } if(one_shot) { do_exit = true; @@ -281,19 +281,19 @@ int rx_callback(hackrf_transfer* transfer) { record_length = 2 * sizeof(band_edge) + (fftSize/4) * sizeof(float); - fwrite(&record_length, sizeof(record_length), 1, stdout); + fwrite(&record_length, sizeof(record_length), 1, fd); band_edge = frequency; - fwrite(&band_edge, sizeof(band_edge), 1, stdout); + fwrite(&band_edge, sizeof(band_edge), 1, fd); band_edge = frequency + DEFAULT_SAMPLE_RATE_HZ / 4; - fwrite(&band_edge, sizeof(band_edge), 1, stdout); - fwrite(&pwr[1+(fftSize*5)/8], sizeof(float), fftSize/4, stdout); + fwrite(&band_edge, sizeof(band_edge), 1, fd); + fwrite(&pwr[1+(fftSize*5)/8], sizeof(float), fftSize/4, fd); - fwrite(&record_length, sizeof(record_length), 1, stdout); + fwrite(&record_length, sizeof(record_length), 1, fd); band_edge = frequency + DEFAULT_SAMPLE_RATE_HZ / 2; - fwrite(&band_edge, sizeof(band_edge), 1, stdout); + fwrite(&band_edge, sizeof(band_edge), 1, fd); band_edge = frequency + (DEFAULT_SAMPLE_RATE_HZ * 3) / 4; - fwrite(&band_edge, sizeof(band_edge), 1, stdout); - fwrite(&pwr[1+fftSize/8], sizeof(float), fftSize/4, stdout); + fwrite(&band_edge, sizeof(band_edge), 1, fd); + fwrite(&pwr[1+fftSize/8], sizeof(float), fftSize/4, fd); } else if(ifft_output) { for(i = 0; (fftSize / 4) > i; i++) { ifftwIn[ifft_idx + i][0] = fftwOut[i + 1 + (fftSize*5)/8][0]; From 9baac3996206a8c5347af41439e5b0f600ed3db1 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Tue, 21 Feb 2017 12:18:41 -0700 Subject: [PATCH 08/16] hackrf_sweep: suppress ifft output unless requested --- host/hackrf-tools/src/hackrf_sweep.c | 30 ++++++++++++++++------------ 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 6eec1ea8..925fd329 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -231,12 +231,14 @@ int rx_callback(hackrf_transfer* transfer) { } if (frequency == (uint64_t)(FREQ_ONE_MHZ*frequencies[0])) { if(sweep_started) { - fftwf_execute(ifftwPlan); - for(i=0; i < ifft_bins; i++) { - ifftwOut[i][0] *= 1.0f / ifft_bins; - ifftwOut[i][1] *= 1.0f / ifft_bins; - fwrite(&ifftwOut[i][0], sizeof(float), 1, fd); - fwrite(&ifftwOut[i][1], sizeof(float), 1, fd); + if(ifft_output) { + fftwf_execute(ifftwPlan); + for(i=0; i < ifft_bins; i++) { + ifftwOut[i][0] *= 1.0f / ifft_bins; + ifftwOut[i][1] *= 1.0f / ifft_bins; + fwrite(&ifftwOut[i][0], sizeof(float), 1, fd); + fwrite(&ifftwOut[i][1], sizeof(float), 1, fd); + } } if(one_shot) { do_exit = true; @@ -274,9 +276,6 @@ int rx_callback(hackrf_transfer* transfer) { for (i=0; i < fftSize; i++) { pwr[i] = logPower(fftwOut[i], 1.0f / fftSize); } - ifft_idx = round((frequency - (uint64_t)(FREQ_ONE_MHZ*frequencies[0])) - / fft_bin_width); - ifft_idx = (ifft_idx + ifft_bins/2) % ifft_bins; if(binary_output) { record_length = 2 * sizeof(band_edge) + (fftSize/4) * sizeof(float); @@ -295,6 +294,9 @@ int rx_callback(hackrf_transfer* transfer) { fwrite(&band_edge, sizeof(band_edge), 1, fd); fwrite(&pwr[1+fftSize/8], sizeof(float), fftSize/4, fd); } else if(ifft_output) { + ifft_idx = round((frequency - (uint64_t)(FREQ_ONE_MHZ*frequencies[0])) + / fft_bin_width); + ifft_idx = (ifft_idx + ifft_bins/2) % ifft_bins; for(i = 0; (fftSize / 4) > i; i++) { ifftwIn[ifft_idx + i][0] = fftwOut[i + 1 + (fftSize*5)/8][0]; ifftwIn[ifft_idx + i][1] = fftwOut[i + 1 + (fftSize*5)/8][1]; @@ -349,7 +351,7 @@ static void usage() { fprintf(stderr, "\t[-1] # one shot mode\n"); fprintf(stderr, "\t[-B] # binary output\n"); fprintf(stderr, "\t[-I] # binary inverse FFT output\n"); - fprintf(stderr, "\t-r filename # output file"); + fprintf(stderr, "\t-r filename # output file\n"); fprintf(stderr, "\n"); fprintf(stderr, "Output fields:\n"); fprintf(stderr, "\tdate, time, hz_low, hz_high, hz_bin_width, num_samples, dB, dB, . . .\n"); @@ -639,9 +641,11 @@ int main(int argc, char** argv) { frequencies[2*i], frequencies[2*i+1]); } - ifftwIn = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize * step_count); - ifftwOut = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize * step_count); - ifftwPlan = fftwf_plan_dft_1d(fftSize * step_count, ifftwIn, ifftwOut, FFTW_BACKWARD, FFTW_MEASURE); + if(ifft_output) { + ifftwIn = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize * step_count); + ifftwOut = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize * step_count); + ifftwPlan = fftwf_plan_dft_1d(fftSize * step_count, ifftwIn, ifftwOut, FFTW_BACKWARD, FFTW_MEASURE); + } result |= hackrf_start_rx(device, rx_callback, NULL); if (result != HACKRF_SUCCESS) { From c7956b49b173b766a64aa7a7be540c5f923c3662 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Tue, 21 Feb 2017 12:43:46 -0700 Subject: [PATCH 09/16] hackrf_sweep: report sweep rate instead of data rate --- host/hackrf-tools/src/hackrf_sweep.c | 35 +++++++++++++--------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 925fd329..c0c81b0a 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -164,6 +164,7 @@ volatile bool do_exit = false; FILE* fd = NULL; volatile uint32_t byte_count = 0; +volatile uint64_t sweep_count = 0; struct timeval time_start; struct timeval t_start; @@ -240,6 +241,7 @@ int rx_callback(hackrf_transfer* transfer) { fwrite(&ifftwOut[i][1], sizeof(float), 1, fd); } } + sweep_count++; if(one_shot) { do_exit = true; } @@ -381,8 +383,9 @@ int main(int argc, char** argv) { const char* path = NULL; const char* serial_number = NULL; int exit_code = EXIT_SUCCESS; - struct timeval t_end; + struct timeval time_now; float time_diff; + float sweep_rate; unsigned int lna_gain=16, vga_gain=20; uint32_t freq_min = 0; uint32_t freq_max = 6000; @@ -685,32 +688,25 @@ int main(int argc, char** argv) { } 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; + float time_difference; 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_difference = TimevalDiff(&time_now, &t_start); + sweep_rate = (float)sweep_count / time_difference; + fprintf(stderr, "%" PRIu64 " total sweeps completed, %.2f sweeps/second\n", + sweep_count, sweep_rate); - time_start = time_now; - - if (byte_count_now == 0) { + if (byte_count == 0) { exit_code = EXIT_FAILURE; - fprintf(stderr, "\nCouldn't transfer any bytes for one second.\n"); + fprintf(stderr, "\nCouldn't transfer any data for one second.\n"); break; } + byte_count = 0; } result = hackrf_is_streaming(device); @@ -721,9 +717,10 @@ int main(int argc, char** argv) { 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); + gettimeofday(&time_now, NULL); + time_diff = TimevalDiff(&time_now, &t_start); + fprintf(stderr, "Total sweeps: %" PRIu64 " in %.5f seconds (%.2f sweeps/second)\n", + sweep_count, time_diff, sweep_rate); if(device != NULL) { result = hackrf_stop_rx(device); From f636658c54a15a87f176c8831d87568a1e8552f9 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 21 Feb 2017 17:41:05 -0700 Subject: [PATCH 10/16] Add clock control hackrf_debug --- host/hackrf-tools/src/hackrf_debug.c | 73 ++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_debug.c b/host/hackrf-tools/src/hackrf_debug.c index 8155477c..ad6cbf78 100644 --- a/host/hackrf-tools/src/hackrf_debug.c +++ b/host/hackrf-tools/src/hackrf_debug.c @@ -148,19 +148,82 @@ int si5351c_write_register( 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 = \n"); + if(clk_ctrl & SI5351C_CLK_POWERDOWN) + printf("\t\tPower Down\n"); + else + printf("\t\tPower Up\n"); + if(clk_ctrl & SI5351C_CLK_INT_MODE) + printf("\t\tInt Mode\n"); + else + printf("\t\tFrac Mode\n"); + if(clk_ctrl & SI5351C_CLK_PLL_SRC) + printf("\t\tPLL src B\n"); + else + printf("\t\tPLL src A\n"); + if(clk_ctrl & SI5351C_CLK_INV) + printf("\t\tInverted\n"); + clk_src = (clk_ctrl >> 2) & 0x3; + switch (clk_src) { + case 0: + printf("\t\tXTAL\n"); + break; + case 1: + printf("\t\tCLKIN\n"); + break; + case 2: + printf("\t\tMULTISYNTH 0 4\n"); + break; + case 3: + printf("\t\tMULTISYNTH SELF\n"); + break; + } + clk_pwr = clk_ctrl & 0x3; + switch (clk_pwr) { + case 0: + printf("\t\t2 mA\n"); + break; + case 1: + printf("\t\t4 mA\n"); + break; + case 2: + printf("\t\t6 mA\n"); + break; + case 3: + printf("\t\t8 mA\n"); + break; + } +} + int si5351c_read_multisynth_config(hackrf_device* device, const uint_fast8_t ms_number) { - uint_fast8_t i; - uint_fast8_t reg_base; - uint16_t parameters[8]; + 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:", 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++) { - uint_fast8_t reg_number = reg_base + i; - int result = hackrf_si5351c_read(device, reg_number, ¶meters[i]); + reg_number = reg_base + i; + result = hackrf_si5351c_read(device, reg_number, ¶meters[i]); if( result != HACKRF_SUCCESS ) { return result; } From 15ea074bdb37752eb76d690abb511406c0fb9865 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 21 Feb 2017 17:43:19 -0700 Subject: [PATCH 11/16] Clean up Si5351c initialisation code --- firmware/common/si5351c.c | 46 +++++++++++---------------------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/firmware/common/si5351c.c b/firmware/common/si5351c.c index 18e4a091..c5f8b713 100644 --- a/firmware/common/si5351c.c +++ b/firmware/common/si5351c.c @@ -164,11 +164,16 @@ void si5351c_configure_multisynth(si5351c_driver_t* const drv, si5351c_write(drv, data, sizeof(data)); } -#if (defined JAWBREAKER || defined HACKRF_ONE) void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll_sources source) { uint8_t pll; +#ifdef RAD1O + (void) source; + /* PLLA on XTAL */ + pll = SI5351C_CLK_PLL_SRC_A; +#endif +#if (defined JAWBREAKER || defined HACKRF_ONE) if (source == PLL_SOURCE_CLKIN) { /* PLLB on CLKIN */ pll = SI5351C_CLK_PLL_SRC_B; @@ -176,29 +181,7 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll /* PLLA on XTAL */ pll = SI5351C_CLK_PLL_SRC_A; } - uint8_t data[] = {16 - ,SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA) - ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA) - ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA) - ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA) - ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_6MA) - ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA) - ,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/ - ,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/ - }; - si5351c_write(drv, data, sizeof(data)); -} #endif - -#ifdef RAD1O -void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll_sources source) -{ - (void) source; - uint8_t pll; - - /* PLLA on XTAL */ - pll = SI5351C_CLK_PLL_SRC_A; - /* Clock to CPU is deactivated as it is not used and creates noise */ /* External clock output is deactivated as it is not used and creates noise */ uint8_t data[] = {16 @@ -206,17 +189,16 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA) ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA) ,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/ - ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_6MA) + ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_6MA) | SI5351C_CLK_INV ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA) ,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/ ,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/ }; si5351c_write(drv, data, sizeof(data)); } -#endif - void si5351c_enable_clock_outputs(si5351c_driver_t* const drv) - { +void si5351c_enable_clock_outputs(si5351c_driver_t* const drv) +{ #ifdef RAD1O /* Enable CLK outputs 0, 1, 2, 4, 5 only. */ /* 7: Clock to CPU is deactivated as it is not used and creates noise */ @@ -227,11 +209,10 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll /* 7: Clock to CPU is deactivated as it is not used and creates noise */ uint8_t data[] = { 3, ~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5))}; #endif - si5351c_write(drv, data, sizeof(data)); - } + si5351c_write(drv, data, sizeof(data)); +} - - void si5351c_set_int_mode(si5351c_driver_t* const drv, const uint_fast8_t ms_number, const uint_fast8_t on){ +void si5351c_set_int_mode(si5351c_driver_t* const drv, const uint_fast8_t ms_number, const uint_fast8_t on){ uint8_t data[] = {16, 0}; if(ms_number < 8){ @@ -245,8 +226,7 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll si5351c_write(drv, data, 2); } - - } +} void si5351c_set_clock_source(si5351c_driver_t* const drv, const enum pll_sources source) { From acaf0d192c6235fc7543f0e83ebda08b50ee5948 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 21 Feb 2017 17:56:37 -0700 Subject: [PATCH 12/16] Change RFFC5071 clock from 40MHz to 50MHz and invert it Now the MAX2837 and RFFC5071 clocks are out of phase with each other Hopefully this reduces some noise --- firmware/common/hackrf_core.c | 14 +++----------- firmware/common/rffc5071.c | 2 +- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 5fe5d5ee..6b792a2f 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -503,20 +503,12 @@ void cpu_clock_init(void) */ /* MS3/CLK3 is the source for the external clock output. */ - si5351c_configure_multisynth(&clock_gen, 3, 80*128-512, 0, 1, 0); /* 800/80 = 10MHz */ + // si5351c_configure_multisynth(&clock_gen, 3, 80*128-512, 0, 1, 0); /* 800/80 = 10MHz */ -#if (defined JAWBREAKER || defined HACKRF_ONE) - /* MS4/CLK4 is the source for the RFFC5071 mixer. */ - si5351c_configure_multisynth(&clock_gen, 4, 16*128-512, 0, 1, 0); /* 800/16 = 50MHz */ - /* MS5/CLK5 is the source for the MAX2837 clock input. */ - si5351c_configure_multisynth(&clock_gen, 5, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */ -#endif -#ifdef RAD1O - /* MS4/CLK4 is the source for the MAX2837 clock input. */ + /* MS4/CLK4 is the source for the RFFC5071 mixer (MAX2837 on rad1o). */ si5351c_configure_multisynth(&clock_gen, 4, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */ - /* MS5/CLK5 is the source for the RFFC5071 mixer. */ + /* MS5/CLK5 is the source for the MAX2837 clock input (MAX2871 on rad1o). */ si5351c_configure_multisynth(&clock_gen, 5, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */ -#endif /* MS6/CLK6 is unused. */ /* MS7/CLK7 is unused. */ diff --git a/firmware/common/rffc5071.c b/firmware/common/rffc5071.c index 653a28a8..d8b06ed1 100644 --- a/firmware/common/rffc5071.c +++ b/firmware/common/rffc5071.c @@ -208,7 +208,7 @@ void rffc5071_enable(rffc5071_driver_t* const drv) { } #define LO_MAX 5400 -#define REF_FREQ 50 +#define REF_FREQ 40 #define FREQ_ONE_MHZ (1000*1000) /* configure frequency synthesizer in integer mode (lo in MHz) */ From 0a48dccd66cd7b2883e5e6ca13b3c4371026611d Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 21 Feb 2017 18:38:50 -0700 Subject: [PATCH 13/16] CLOKOUT off by default --- firmware/common/si5351c.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/firmware/common/si5351c.c b/firmware/common/si5351c.c index c5f8b713..2dad97b6 100644 --- a/firmware/common/si5351c.c +++ b/firmware/common/si5351c.c @@ -199,16 +199,10 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll void si5351c_enable_clock_outputs(si5351c_driver_t* const drv) { -#ifdef RAD1O /* Enable CLK outputs 0, 1, 2, 4, 5 only. */ /* 7: Clock to CPU is deactivated as it is not used and creates noise */ - /* 3: External clock output is deactivated as it is not used and creates noise */ + /* 3: External clock output is deactivated by default */ uint8_t data[] = { 3, ~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4) | (1 << 5))}; -#else - /* Enable CLK outputs 0, 1, 2, 3, 4, 5. */ - /* 7: Clock to CPU is deactivated as it is not used and creates noise */ - uint8_t data[] = { 3, ~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5))}; -#endif si5351c_write(drv, data, sizeof(data)); } From c2e775b1b941db115dd25ee3cc40cb01a902c461 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Thu, 23 Feb 2017 14:34:41 -0700 Subject: [PATCH 14/16] hackrf_info: continue probing devices after errors --- host/hackrf-tools/src/hackrf_info.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/host/hackrf-tools/src/hackrf_info.c b/host/hackrf-tools/src/hackrf_info.c index abb72887..1eb2273b 100644 --- a/host/hackrf-tools/src/hackrf_info.c +++ b/host/hackrf-tools/src/hackrf_info.c @@ -71,6 +71,9 @@ int main(void) if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); + if(result == HACKRF_ERROR_LIBUSB) { + continue; + } return EXIT_FAILURE; } From 00b6099bb32eec1a75af04f75ac934fb35b8a07e Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 28 Feb 2017 15:25:27 -0700 Subject: [PATCH 15/16] Make comments more informative (possibly) --- firmware/common/si5351c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/common/si5351c.c b/firmware/common/si5351c.c index 2dad97b6..3bdefcda 100644 --- a/firmware/common/si5351c.c +++ b/firmware/common/si5351c.c @@ -116,11 +116,11 @@ void si5351c_configure_pll_sources(si5351c_driver_t* const drv) /* MultiSynth NA (PLLA) and NB (PLLB) */ void si5351c_configure_pll_multisynth(si5351c_driver_t* const drv) { - //init plla to (0x0e00+512)/128*25mhz xtal = 800mhz -> int mode + /*PLLA: 25MHz XTAL * (0x0e00+512)/128 = 800mhz -> int mode */ uint8_t data[] = { 26, 0x00, 0x01, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00 }; si5351c_write(drv, data, sizeof(data)); - /* 10 MHz input on CLKIN for PLLB */ + /*PLLB: 10MHz CLKIN * (0x2600+512)/128 = 800mhz */ data[0] = 34; data[4] = 0x26; si5351c_write(drv, data, sizeof(data)); From 8b853266ef5fe7ba53df2d614546d038bb6f4c16 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 28 Feb 2017 15:26:43 -0700 Subject: [PATCH 16/16] Power down CLK3 (CLKOUT) at boot, don't reset it when clocks are reset --- firmware/common/hackrf_core.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 50e2b7ae..59bccb1e 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -495,16 +495,13 @@ void cpu_clock_init(void) * CLK0 -> MAX5864/CPLD * CLK1 -> CPLD * CLK2 -> SGPIO - * CLK3 -> External Clock Output + * CLK3 -> External Clock Output (power down at boot) * CLK4 -> RFFC5072 (MAX2837 on rad1o) * CLK5 -> MAX2837 (MAX2871 on rad1o) * CLK6 -> none * CLK7 -> LPC43xx (uses a 12MHz crystal by default) */ - /* MS3/CLK3 is the source for the external clock output. */ - // si5351c_configure_multisynth(&clock_gen, 3, 80*128-512, 0, 1, 0); /* 800/80 = 10MHz */ - /* MS4/CLK4 is the source for the RFFC5071 mixer (MAX2837 on rad1o). */ si5351c_configure_multisynth(&clock_gen, 4, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */ /* MS5/CLK5 is the source for the MAX2837 clock input (MAX2871 on rad1o). */ @@ -518,8 +515,9 @@ void cpu_clock_init(void) si5351c_set_clock_source(&clock_gen, PLL_SOURCE_XTAL); // soft reset - uint8_t resetdata[] = { 177, 0xac }; - si5351c_write(&clock_gen, resetdata, sizeof(resetdata)); + // uint8_t resetdata[] = { 177, 0xac }; + // si5351c_write(&clock_gen, resetdata, sizeof(resetdata)); + si5351c_reset_pll(&clock_gen); si5351c_enable_clock_outputs(&clock_gen); //FIXME disable I2C