From 2aaa2213c95d0e2bf9bdfe4242efb9c1e4e7e8cb Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 17 Dec 2025 09:54:24 -0500 Subject: [PATCH] Ensure clock generator off before turning on Do not try to activate clock generator if power supply is disabled on Praline. --- firmware/common/hackrf_core.c | 166 ++++++++++++----------- firmware/common/hackrf_core.h | 2 + firmware/hackrf_usb/hackrf_usb.c | 3 + firmware/hackrf_usb/usb_api_board_info.c | 1 + 4 files changed, 95 insertions(+), 77 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 673856ce..3668fed8 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -755,83 +755,6 @@ void cpu_clock_init(void) /* use IRC as clock source for APB3 */ CGU_BASE_APB3_CLK = CGU_BASE_APB3_CLK_CLK_SEL(CGU_SRC_IRC); - i2c_bus_start(clock_gen.bus, &i2c_config_si5351c_fast_clock); - - si5351c_init(&clock_gen); - si5351c_disable_all_outputs(&clock_gen); - si5351c_disable_oeb_pin_control(&clock_gen); - si5351c_power_down_all_clocks(&clock_gen); - si5351c_set_crystal_configuration(&clock_gen); - si5351c_enable_xo_and_ms_fanout(&clock_gen); - si5351c_configure_pll_sources(&clock_gen); - si5351c_configure_pll_multisynth(&clock_gen); - - /* - * Clocks on HackRF One r9: - * CLK0 -> MAX5864/CPLD/SGPIO (sample clocks) - * CLK1 -> RFFC5072/MAX2839 - * CLK2 -> External Clock Output/LPC43xx (power down at boot) - * - * Clocks on other platforms: - * CLK0 -> MAX5864/CPLD - * CLK1 -> CPLD - * CLK2 -> SGPIO - * 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) - * - * Clocks on Praline: - * CLK0 -> AFE_CLK (MAX5864/FPGA) - * CLK1 -> SCT_CLK - * CLK2 -> MCU_CLK (uses a 12MHz crystal by default) - * CLK3 -> External Clock Output (power down at boot) - * CLK4 -> XCVR_CLK (MAX2837) - * CLK5 -> MIX_CLK (RFFC5072) - * CLK6 -> AUX_CLK1 - * CLK7 -> AUX_CLK2 - */ - - if (detected_platform() == BOARD_ID_HACKRF1_R9) { - /* MS0/CLK0 is the reference for both RFFC5071 and MAX2839. */ - si5351c_configure_multisynth( - &clock_gen, - 0, - 20 * 128 - 512, - 0, - 1, - 0); /* 800/20 = 40MHz */ - } else { - /* 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). */ - si5351c_configure_multisynth( - &clock_gen, - 5, - 20 * 128 - 512, - 0, - 1, - 0); /* 800/20 = 40MHz */ - } - - /* MS6/CLK6 is unused. */ - /* MS7/CLK7 is unused. */ - - /* 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); - // soft reset - si5351c_reset_pll(&clock_gen); - si5351c_enable_clock_outputs(&clock_gen); - //FIXME disable I2C /* Kick I2C0 down to 400kHz when we switch over to APB1 clock = 204MHz */ i2c_bus_start(clock_gen.bus, &i2c_config_si5351c_fast_clock); @@ -965,6 +888,95 @@ void cpu_clock_init(void) #endif } +void clock_gen_init(void) +{ + i2c_bus_start(clock_gen.bus, &i2c_config_si5351c_fast_clock); + + si5351c_init(&clock_gen); + si5351c_disable_all_outputs(&clock_gen); + si5351c_disable_oeb_pin_control(&clock_gen); + si5351c_power_down_all_clocks(&clock_gen); + si5351c_set_crystal_configuration(&clock_gen); + si5351c_enable_xo_and_ms_fanout(&clock_gen); + si5351c_configure_pll_sources(&clock_gen); + si5351c_configure_pll_multisynth(&clock_gen); + + /* + * Clocks on HackRF One r9: + * CLK0 -> MAX5864/CPLD/SGPIO (sample clocks) + * CLK1 -> RFFC5072/MAX2839 + * CLK2 -> External Clock Output/LPC43xx (power down at boot) + * + * Clocks on other platforms: + * CLK0 -> MAX5864/CPLD + * CLK1 -> CPLD + * CLK2 -> SGPIO + * 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) + * + * Clocks on Praline: + * CLK0 -> AFE_CLK (MAX5864/FPGA) + * CLK1 -> SCT_CLK + * CLK2 -> MCU_CLK (uses a 12MHz crystal by default) + * CLK3 -> External Clock Output (power down at boot) + * CLK4 -> XCVR_CLK (MAX2837) + * CLK5 -> MIX_CLK (RFFC5072) + * CLK6 -> AUX_CLK1 + * CLK7 -> AUX_CLK2 + */ + + if (detected_platform() == BOARD_ID_HACKRF1_R9) { + /* MS0/CLK0 is the reference for both RFFC5071 and MAX2839. */ + si5351c_configure_multisynth( + &clock_gen, + 0, + 20 * 128 - 512, + 0, + 1, + 0); /* 800/20 = 40MHz */ + } else { + /* 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). */ + si5351c_configure_multisynth( + &clock_gen, + 5, + 20 * 128 - 512, + 0, + 1, + 0); /* 800/20 = 40MHz */ + } + + /* MS6/CLK6 is unused. */ + /* MS7/CLK7 is unused. */ + + /* 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); + // soft reset + si5351c_reset_pll(&clock_gen); + si5351c_enable_clock_outputs(&clock_gen); +} + +void clock_gen_shutdown(void) +{ + i2c_bus_start(clock_gen.bus, &i2c_config_si5351c_fast_clock); + si5351c_init(&clock_gen); + si5351c_disable_all_outputs(&clock_gen); + si5351c_disable_oeb_pin_control(&clock_gen); + si5351c_power_down_all_clocks(&clock_gen); +} + clock_source_t activate_best_clock_source(void) { #if (defined HACKRF_ONE || defined PRALINE) diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index 9a88ab7e..071dc614 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -414,6 +414,8 @@ extern jtag_t jtag_cpld; extern i2c_bus_t i2c0; void cpu_clock_init(void); +void clock_gen_init(void); +void clock_gen_shutdown(void); void ssp1_set_mode_max283x(void); void ssp1_set_mode_max5864(void); #ifdef PRALINE diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 4cd4b031..77d2614f 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -263,15 +263,18 @@ int main(void) detect_hardware_platform(); pin_shutdown(); + clock_gen_shutdown(); delay_us_at_mhz(10000, 96); pin_setup(); #ifndef PRALINE enable_1v8_power(); + clock_gen_init(); #else enable_3v3aux_power(); #if !defined(DFU_MODE) && !defined(RAM_MODE) enable_1v2_power(); enable_rf_power(); + clock_gen_init(); #endif #endif #ifdef HACKRF_ONE diff --git a/firmware/hackrf_usb/usb_api_board_info.c b/firmware/hackrf_usb/usb_api_board_info.c index 248ebf1e..aeff83b8 100644 --- a/firmware/hackrf_usb/usb_api_board_info.c +++ b/firmware/hackrf_usb/usb_api_board_info.c @@ -131,6 +131,7 @@ usb_request_status_t usb_vendor_request_reset( { if (stage == USB_TRANSFER_STAGE_SETUP) { pin_shutdown(); + clock_gen_shutdown(); #ifdef HACKRF_ONE /* * Set boot pins as inputs so that the bootloader reads them