From 056ddd06017257975b0fa90f8decd5070490239e Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 13 Jun 2012 16:02:40 -0600 Subject: [PATCH] r divider configurable, added CLK5 for mixer reference input --- firmware/common/hackrf_core.c | 9 ++++--- firmware/common/si5351c.c | 46 +++++++++++++++++++++++++++++------ firmware/common/si5351c.h | 5 ++-- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index adfe54e3..43626947 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -49,13 +49,16 @@ void cpu_clock_init(void) si5351c_configure_pll1_multisynth(); /* MS0/CLK0 is the source for the MAX2837 clock input. */ - si5351c_configure_multisynth(0, 2048, 0, 1); /* 40MHz */ + si5351c_configure_multisynth(0, 2048, 0, 1, 0); /* 40MHz */ /* MS1/CLK1 is the source for the MAX5864 codec. */ - si5351c_configure_multisynth(1, 4608, 0, 1); /* 20MHz */ + si5351c_configure_multisynth(1, 4608, 0, 1, 1); /* 20MHz derived from MS0 */ /* MS4/CLK4 is the source for the LPC43xx microcontroller. */ - si5351c_configure_multisynth(4, 8021, 1, 3); /* 12MHz */ + si5351c_configure_multisynth(4, 8021, 1, 3, 0); /* 12MHz */ + + /* MS5/CLK5 is the source for the RFFC5071 mixer. */ + si5351c_configure_multisynth(5, 1536, 1, 1, 0); /* 50MHz */ si5351c_configure_clock_control(); si5351c_enable_clock_outputs(); diff --git a/firmware/common/si5351c.c b/firmware/common/si5351c.c index 0c3fa1fc..eb91bee0 100644 --- a/firmware/common/si5351c.c +++ b/firmware/common/si5351c.c @@ -87,7 +87,7 @@ void si5351c_disable_oeb_pin_control() /* Power down all CLKx */ void si5351c_power_down_all_clocks() { - uint8_t data[] = { 16, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }; + uint8_t data[] = { 16, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xC0, 0xC0 }; si5351c_write(data, sizeof(data)); } @@ -131,19 +131,28 @@ void si5351c_configure_pll1_multisynth() si5351c_write(data, sizeof(data)); } -void si5351c_configure_multisynth( const uint_fast8_t ms_number, - const uint32_t p1, const uint32_t p2, const uint32_t p3) +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) { /* * TODO: Check for p3 > 0? 0 has no meaning in fractional mode? * And it makes for more jitter in integer mode. */ + /* + * r is the r divider value encoded: + * 0 means divide by 1 + * 1 means divide by 2 + * 2 means divide by 4 + * ... + * 7 means divide by 128 + */ const uint_fast8_t register_number = 42 + (ms_number * 8); uint8_t data[] = { register_number, (p3 >> 8) & 0xFF, (p3 >> 0) & 0xFF, - (0 << 4) | (0 << 2) | ((p1 >> 16) & 0x3), + (r << 4) | (0 << 2) | ((p1 >> 16) & 0x3), (p1 >> 8) & 0xFF, (p1 >> 0) & 0xFF, (((p3 >> 16) & 0xF) << 4) | (((p2 >> 16) & 0xF) << 0), @@ -166,8 +175,22 @@ void si5351c_configure_multisynth( const uint_fast8_t ms_number, * MS1_INT=1 (integer mode) * MS1_SRC=0 (PLLA as source for MultiSynth 1) * CLK1_INV=0 (not inverted) - * CLK1_SRC=3 (MS1 as input source) + * CLK1_SRC=3 (MS0 as input source) * CLK1_IDRV=3 (8mA) + * CLK2: + * CLK2_PDN=0 (powered up) + * MS2_INT=1 (integer mode) + * MS2_SRC=0 (PLLA as source for MultiSynth 2) + * CLK2_INV=0 (not inverted) + * CLK2_SRC=3 (MS0 as input source) + * CLK2_IDRV=3 (8mA) + * CLK3: + * CLK3_PDN=0 (powered up) + * MS3_INT=1 (integer mode) + * MS3_SRC=0 (PLLA as source for MultiSynth 3) + * CLK3_INV=0 (not inverted) + * CLK3_SRC=3 (MS0 as input source) + * CLK3_IDRV=3 (8mA) * CLK4: * CLK4_PDN=0 (powered up) * MS4_INT=0 (fractional mode -- to support 12MHz to LPC for USB DFU) @@ -175,16 +198,23 @@ void si5351c_configure_multisynth( const uint_fast8_t ms_number, * CLK4_INV=0 (not inverted) * CLK4_SRC=3 (MS4 as input source) * CLK4_IDRV=3 (8mA) + * CLK5: + * CLK5_PDN=0 (powered up) + * MS5_INT=1 (integer mode) + * MS5_SRC=0 (PLLA as source for MultiSynth 5) + * CLK5_INV=0 (not inverted) + * CLK5_SRC=3 (MS5 as input source) + * CLK5_IDRV=3 (8mA) */ void si5351c_configure_clock_control() { - uint8_t data[] = { 16, 0x4F, 0x4F, 0x80, 0x80, 0x0F, 0x80, 0x80, 0x80 }; + uint8_t data[] = { 16, 0x4F, 0x4B, 0x4B, 0x4B, 0x0F, 0x4F, 0xC0, 0xC0 }; si5351c_write(data, sizeof(data)); } -/* Enable CLK outputs 0, 1, 4 only. */ +/* Enable CLK outputs 0, 1, 4, 5 only. */ void si5351c_enable_clock_outputs() { - uint8_t data[] = { 3, 0xEC }; + uint8_t data[] = { 3, 0xCC }; si5351c_write(data, sizeof(data)); } diff --git a/firmware/common/si5351c.h b/firmware/common/si5351c.h index e847852c..6ef76be4 100644 --- a/firmware/common/si5351c.h +++ b/firmware/common/si5351c.h @@ -39,8 +39,9 @@ void si5351c_set_crystal_configuration(); void si5351c_enable_xo_and_ms_fanout(); void si5351c_configure_pll_sources_for_xtal(); void si5351c_configure_pll1_multisynth(); -void si5351c_configure_multisynth( const uint_fast8_t ms_number, - const uint32_t p1, const uint32_t p2, const uint32_t p3); +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); void si5351c_configure_clock_control(); void si5351c_enable_clock_outputs();