From 15bda174c74dd35938cda41545519b409bb538ab Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Fri, 14 Mar 2014 22:27:30 -0600 Subject: [PATCH] maintain PLLA on XTAL and PLLB on CLKIN at all times (makes automatic clock source switching more reliable) --- firmware/common/hackrf_core.c | 5 +-- firmware/common/si5351c.c | 65 +++++++++++++++++++---------------- firmware/common/si5351c.h | 7 ++-- 3 files changed, 43 insertions(+), 34 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 3ff0318a..dc4c4708 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -268,7 +268,8 @@ void cpu_clock_init(void) si5351c_power_down_all_clocks(); si5351c_set_crystal_configuration(); si5351c_enable_xo_and_ms_fanout(); - si5351c_set_clock_source(PLL_SOURCE_XTAL); + si5351c_configure_pll_sources(); + si5351c_configure_pll_multisynth(); #ifdef JELLYBEAN /* @@ -324,7 +325,7 @@ void cpu_clock_init(void) /* Set to 10 MHz, the common rate between Jellybean and Jawbreaker. */ sample_rate_set(10000000); - si5351c_configure_clock_control(); + si5351c_set_clock_source(PLL_SOURCE_XTAL); // soft reset uint8_t resetdata[] = { 177, 0xac }; si5351c_write(resetdata, sizeof(resetdata)); diff --git a/firmware/common/si5351c.c b/firmware/common/si5351c.c index dd96605c..b4ccc4de 100644 --- a/firmware/common/si5351c.c +++ b/firmware/common/si5351c.c @@ -126,34 +126,34 @@ void si5351c_enable_xo_and_ms_fanout() /* * Register 15: PLL Input Source * CLKIN_DIV=0 (Divide by 1) - * PLLB_SRC=0 (XTAL input) - * PLLA_SRC=0 (XTAL input) + * PLLA_SRC=0 (XTAL) + * PLLB_SRC=1 (CLKIN) */ -void si5351c_configure_pll_sources(const enum pll_sources source) +void si5351c_configure_pll_sources(void) { - uint8_t data[] = { 15, 0x00 }; - - if (source == PLL_SOURCE_CLKIN) { - data[1] = 0x0C; - } + uint8_t data[] = { 15, 0x08 }; si5351c_write(data, sizeof(data)); } -/* MultiSynth NA (PLL1) */ -void si5351c_configure_pll1_multisynth(const enum pll_sources source) +/* MultiSynth NA (PLLA) and NB (PLLB) */ +void si5351c_configure_pll_multisynth(void) { //init plla to (0x0e00+512)/128*25mhz xtal = 800mhz -> int mode uint8_t data[] = { 26, 0x00, 0x01, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00 }; - - if (source == PLL_SOURCE_CLKIN) { - /* 10 MHz input on CLKIN instead of 25 MHz XTAL */ - data[4] = 0x26; - } - si5351c_write(data, sizeof(data)); - //~ data[0] =34;// pllb - //~ si5351c_write(data, sizeof(data)); + + /* 10 MHz input on CLKIN for PLLB */ + data[0] = 34; + data[4] = 0x26; + si5351c_write(data, sizeof(data)); +} + +void si5351c_reset_pll(void) +{ + /* reset PLLA and PLLB */ + uint8_t data[] = { 177, 0xA0 }; + si5351c_write(data, sizeof(data)); } void si5351c_configure_multisynth(const uint_fast8_t ms_number, @@ -240,17 +240,26 @@ void si5351c_configure_clock_control() #endif #if (defined JAWBREAKER || defined HACKRF_ONE) -void si5351c_configure_clock_control() +void si5351c_configure_clock_control(const enum pll_sources source) { + uint8_t pll; + + if (source == PLL_SOURCE_CLKIN) { + /* PLLB on CLKIN */ + pll = SI5351C_CLK_PLL_SRC_B; + } else { + /* PLLA on XTAL */ + pll = SI5351C_CLK_PLL_SRC_A; + } uint8_t data[] = {16 - ,SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA) - ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA) - ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA) - ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA) - ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_6MA) - ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA) + ,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_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | 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_8MA) }; si5351c_write(data, sizeof(data)); } @@ -283,9 +292,7 @@ void si5351c_configure_clock_control() void si5351c_set_clock_source(const enum pll_sources source) { - si5351c_configure_pll_sources(source); - si5351c_configure_pll1_multisynth(source); - + si5351c_configure_clock_control(PLL_SOURCE_XTAL); active_clock_source = source; } diff --git a/firmware/common/si5351c.h b/firmware/common/si5351c.h index 562c37b7..b62279d7 100644 --- a/firmware/common/si5351c.h +++ b/firmware/common/si5351c.h @@ -67,12 +67,13 @@ void si5351c_disable_oeb_pin_control(); void si5351c_power_down_all_clocks(); void si5351c_set_crystal_configuration(); void si5351c_enable_xo_and_ms_fanout(); -void si5351c_configure_pll_sources(const enum pll_sources source); -void si5351c_configure_pll1_multisynth(const enum pll_sources source); +void si5351c_configure_pll_sources(void); +void si5351c_configure_pll_multisynth(void); +void si5351c_reset_pll(void); void si5351c_configure_multisynth(const uint_fast8_t ms_number, const uint32_t p1, const uint32_t p2, const uint32_t p3, const uint_fast8_t r_div); -void si5351c_configure_clock_control(); +void si5351c_configure_clock_control(const enum pll_sources source); void si5351c_enable_clock_outputs(); void si5351c_set_int_mode(const uint_fast8_t ms_number, const uint_fast8_t on);