diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 64254c5d..a42a06ae 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -712,6 +712,15 @@ void cpu_clock_init(void) #endif } +void activate_best_clock_source(void) +{ + if (si5351c_clkin_signal_valid(&clock_gen)) { + si5351c_set_clock_source(&clock_gen, PLL_SOURCE_CLKIN); + } else { + si5351c_set_clock_source(&clock_gen, PLL_SOURCE_XTAL); + } +} + void ssp1_set_mode_max2837(void) { spi_bus_start(max2837.bus, &ssp_config_max2837); diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index 3b2f7982..e6e4e811 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -294,6 +294,8 @@ bool sample_rate_frac_set(uint32_t rate_num, uint32_t rate_denom); bool sample_rate_set(const uint32_t sampling_rate_hz); bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz); +void activate_best_clock_source(void); + #if (defined HACKRF_ONE || defined RAD1O) void enable_rf_power(void); void disable_rf_power(void); diff --git a/firmware/common/si5351c.c b/firmware/common/si5351c.c index 64a3dda1..a7364241 100644 --- a/firmware/common/si5351c.c +++ b/firmware/common/si5351c.c @@ -22,7 +22,7 @@ #include "si5351c.h" -enum pll_sources active_clock_source; +enum pll_sources active_clock_source = PLL_SOURCE_UNINITIALIZED; /* write to single register */ void si5351c_write_single(si5351c_driver_t* const drv, uint8_t reg, uint8_t val) @@ -239,25 +239,14 @@ void si5351c_set_int_mode(si5351c_driver_t* const drv, const uint_fast8_t ms_num void si5351c_set_clock_source(si5351c_driver_t* const drv, const enum pll_sources source) { - si5351c_configure_clock_control(drv, source); - active_clock_source = source; + if( source != active_clock_source ) { + si5351c_configure_clock_control(drv, source); + active_clock_source = source; + } } -void si5351c_activate_best_clock_source(si5351c_driver_t* const drv) -{ - uint8_t device_status = si5351c_read_single(drv, 0); - - if (device_status & SI5351C_LOS) { - /* CLKIN not detected */ - if (active_clock_source == PLL_SOURCE_CLKIN) { - si5351c_set_clock_source(drv, PLL_SOURCE_XTAL); - } - } else { - /* CLKIN detected */ - if (active_clock_source == PLL_SOURCE_XTAL) { - si5351c_set_clock_source(drv, PLL_SOURCE_CLKIN); - } - } +bool si5351c_clkin_signal_valid(si5351c_driver_t* const drv) { + return (si5351c_read_single(drv, 0) & SI5351C_LOS) == 0; } void si5351c_clkout_enable(si5351c_driver_t* const drv, uint8_t enable) diff --git a/firmware/common/si5351c.h b/firmware/common/si5351c.h index 533c5830..03e82260 100644 --- a/firmware/common/si5351c.h +++ b/firmware/common/si5351c.h @@ -29,6 +29,7 @@ extern "C" #endif #include +#include #include "i2c_bus.h" @@ -59,6 +60,7 @@ extern "C" #define SI5351C_LOS (1<<4) enum pll_sources { + PLL_SOURCE_UNINITIALIZED = -1, PLL_SOURCE_XTAL = 0, PLL_SOURCE_CLKIN = 1, }; @@ -84,7 +86,7 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll void si5351c_enable_clock_outputs(si5351c_driver_t* const drv); void si5351c_set_int_mode(si5351c_driver_t* const drv, const uint_fast8_t ms_number, const uint_fast8_t on); void si5351c_set_clock_source(si5351c_driver_t* const drv, const enum pll_sources source); -void si5351c_activate_best_clock_source(si5351c_driver_t* const drv); +bool si5351c_clkin_signal_valid(si5351c_driver_t* const drv); 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); diff --git a/firmware/hackrf_usb/usb_api_transceiver.c b/firmware/hackrf_usb/usb_api_transceiver.c index fda9b6a9..3d64d7f9 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.c +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -273,7 +273,7 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { if( _transceiver_mode != TRANSCEIVER_MODE_OFF ) { - si5351c_activate_best_clock_source(&clock_gen); + activate_best_clock_source(); hw_sync_enable(_hw_sync_mode);