activated CLKOUT (always on) and CLKIN (automatically used when detected)
This commit is contained in:
@ -136,9 +136,6 @@ bool sample_rate_frac_set(uint32_t rate_num, uint32_t rate_denom)
|
|||||||
/* MS0/CLK2 is the source for SGPIO (CODEC_X2_CLK) */
|
/* MS0/CLK2 is the source for SGPIO (CODEC_X2_CLK) */
|
||||||
si5351c_configure_multisynth(2, 0, 0, 0, 0);//p1 doesn't matter
|
si5351c_configure_multisynth(2, 0, 0, 0, 0);//p1 doesn't matter
|
||||||
|
|
||||||
/* MS0/CLK3 is the source for the external clock output. */
|
|
||||||
//si5351c_configure_multisynth(3, p1, 0, 1, 0); // no clk out
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,9 +245,6 @@ bool sample_rate_set(const uint32_t sample_rate_hz) {
|
|||||||
/* MS0/CLK2 is the source for SGPIO (CODEC_X2_CLK) */
|
/* MS0/CLK2 is the source for SGPIO (CODEC_X2_CLK) */
|
||||||
si5351c_configure_multisynth(2, p1, 0, 1, 0);//p1 doesn't matter
|
si5351c_configure_multisynth(2, p1, 0, 1, 0);//p1 doesn't matter
|
||||||
|
|
||||||
/* MS0/CLK3 is the source for the external clock output. */
|
|
||||||
//si5351c_configure_multisynth(3, p1, 0, 1, 0); // no clk out
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -274,8 +268,7 @@ void cpu_clock_init(void)
|
|||||||
si5351c_power_down_all_clocks();
|
si5351c_power_down_all_clocks();
|
||||||
si5351c_set_crystal_configuration();
|
si5351c_set_crystal_configuration();
|
||||||
si5351c_enable_xo_and_ms_fanout();
|
si5351c_enable_xo_and_ms_fanout();
|
||||||
si5351c_configure_pll_sources_for_xtal();
|
si5351c_set_clock_source(PLL_SOURCE_XTAL);
|
||||||
si5351c_configure_pll1_multisynth();
|
|
||||||
|
|
||||||
#ifdef JELLYBEAN
|
#ifdef JELLYBEAN
|
||||||
/*
|
/*
|
||||||
@ -313,6 +306,9 @@ void cpu_clock_init(void)
|
|||||||
* CLK7 -> LPC4330 (but LPC4330 starts up on its own crystal)
|
* CLK7 -> LPC4330 (but LPC4330 starts up on its own crystal)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* MS3/CLK3 is the source for the external clock output. */
|
||||||
|
si5351c_configure_multisynth(3, 80*128-512, 0, 1, 0); /* 800/80 = 10MHz */
|
||||||
|
|
||||||
/* MS4/CLK4 is the source for the RFFC5071 mixer. */
|
/* MS4/CLK4 is the source for the RFFC5071 mixer. */
|
||||||
si5351c_configure_multisynth(4, 16*128-512, 0, 1, 0); /* 800/16 = 50MHz */
|
si5351c_configure_multisynth(4, 16*128-512, 0, 1, 0); /* 800/16 = 50MHz */
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
#include "si5351c.h"
|
#include "si5351c.h"
|
||||||
#include <libopencm3/lpc43xx/i2c.h>
|
#include <libopencm3/lpc43xx/i2c.h>
|
||||||
|
|
||||||
|
enum pll_sources active_clock_source;
|
||||||
|
|
||||||
/* FIXME return i2c0 status from each function */
|
/* FIXME return i2c0 status from each function */
|
||||||
|
|
||||||
/* write to single register */
|
/* write to single register */
|
||||||
@ -117,7 +119,7 @@ void si5351c_set_crystal_configuration()
|
|||||||
*/
|
*/
|
||||||
void si5351c_enable_xo_and_ms_fanout()
|
void si5351c_enable_xo_and_ms_fanout()
|
||||||
{
|
{
|
||||||
uint8_t data[] = { 187, 0x50 };
|
uint8_t data[] = { 187, 0xD0 };
|
||||||
si5351c_write(data, sizeof(data));
|
si5351c_write(data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,18 +129,29 @@ void si5351c_enable_xo_and_ms_fanout()
|
|||||||
* PLLB_SRC=0 (XTAL input)
|
* PLLB_SRC=0 (XTAL input)
|
||||||
* PLLA_SRC=0 (XTAL input)
|
* PLLA_SRC=0 (XTAL input)
|
||||||
*/
|
*/
|
||||||
void si5351c_configure_pll_sources_for_xtal()
|
void si5351c_configure_pll_sources(const enum pll_sources source)
|
||||||
{
|
{
|
||||||
uint8_t data[] = { 15, 0x00 };
|
uint8_t data[] = { 15, 0x00 };
|
||||||
|
|
||||||
|
if (source == PLL_SOURCE_CLKIN) {
|
||||||
|
data[1] = 0x0C;
|
||||||
|
}
|
||||||
|
|
||||||
si5351c_write(data, sizeof(data));
|
si5351c_write(data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MultiSynth NA (PLL1) */
|
/* MultiSynth NA (PLL1) */
|
||||||
void si5351c_configure_pll1_multisynth()
|
void si5351c_configure_pll1_multisynth(const enum pll_sources source)
|
||||||
{
|
{
|
||||||
//init plla and pllb to (0x0e00+512)/128*25mhz xtal = 800mhz -> int mode
|
//init plla to (0x0e00+512)/128*25mhz xtal = 800mhz -> int mode
|
||||||
uint8_t data[] = { 26, 0x00, 0x01, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00 };
|
uint8_t data[] = { 26, 0x00, 0x01, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00 };
|
||||||
si5351c_write(data, sizeof(data));
|
|
||||||
|
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
|
//~ data[0] =34;// pllb
|
||||||
//~ si5351c_write(data, sizeof(data));
|
//~ si5351c_write(data, sizeof(data));
|
||||||
}
|
}
|
||||||
@ -233,7 +246,7 @@ void si5351c_configure_clock_control()
|
|||||||
,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_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_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_POWERDOWN /*not connected, clock out*/
|
,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_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_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_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/
|
,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/
|
||||||
@ -243,10 +256,10 @@ void si5351c_configure_clock_control()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Enable CLK outputs 0, 1, 2, 4, 5, 7 only. */
|
/* Enable CLK outputs 0, 1, 2, 3, 4, 5, 7 only. */
|
||||||
void si5351c_enable_clock_outputs()
|
void si5351c_enable_clock_outputs()
|
||||||
{
|
{
|
||||||
uint8_t data[] = { 3, 0x48 };
|
uint8_t data[] = { 3, 0x40 };
|
||||||
si5351c_write(data, sizeof(data));
|
si5351c_write(data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,3 +280,28 @@ 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);
|
||||||
|
|
||||||
|
active_clock_source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
void si5351c_activate_best_clock_source(void)
|
||||||
|
{
|
||||||
|
uint8_t device_status = si5351c_read_single(0);
|
||||||
|
|
||||||
|
if (device_status & SI5351C_LOS) {
|
||||||
|
/* CLKIN not detected */
|
||||||
|
if (active_clock_source == PLL_SOURCE_CLKIN) {
|
||||||
|
si5351c_set_clock_source(PLL_SOURCE_XTAL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* CLKIN detected */
|
||||||
|
if (active_clock_source == PLL_SOURCE_XTAL) {
|
||||||
|
si5351c_set_clock_source(PLL_SOURCE_CLKIN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -55,13 +55,20 @@ extern "C"
|
|||||||
#define SI5351C_CLK_IDRV_6MA 2
|
#define SI5351C_CLK_IDRV_6MA 2
|
||||||
#define SI5351C_CLK_IDRV_8MA 3
|
#define SI5351C_CLK_IDRV_8MA 3
|
||||||
|
|
||||||
|
#define SI5351C_LOS (1<<4)
|
||||||
|
|
||||||
|
enum pll_sources {
|
||||||
|
PLL_SOURCE_XTAL = 0,
|
||||||
|
PLL_SOURCE_CLKIN = 1,
|
||||||
|
};
|
||||||
|
|
||||||
void si5351c_disable_all_outputs();
|
void si5351c_disable_all_outputs();
|
||||||
void si5351c_disable_oeb_pin_control();
|
void si5351c_disable_oeb_pin_control();
|
||||||
void si5351c_power_down_all_clocks();
|
void si5351c_power_down_all_clocks();
|
||||||
void si5351c_set_crystal_configuration();
|
void si5351c_set_crystal_configuration();
|
||||||
void si5351c_enable_xo_and_ms_fanout();
|
void si5351c_enable_xo_and_ms_fanout();
|
||||||
void si5351c_configure_pll_sources_for_xtal();
|
void si5351c_configure_pll_sources(const enum pll_sources source);
|
||||||
void si5351c_configure_pll1_multisynth();
|
void si5351c_configure_pll1_multisynth(const enum pll_sources source);
|
||||||
void si5351c_configure_multisynth(const uint_fast8_t ms_number,
|
void si5351c_configure_multisynth(const uint_fast8_t ms_number,
|
||||||
const uint32_t p1, const uint32_t p2, const uint32_t p3,
|
const uint32_t p1, const uint32_t p2, const uint32_t p3,
|
||||||
const uint_fast8_t r_div);
|
const uint_fast8_t r_div);
|
||||||
@ -72,6 +79,8 @@ void si5351c_set_int_mode(const uint_fast8_t ms_number, const uint_fast8_t on);
|
|||||||
void si5351c_write_single(uint8_t reg, uint8_t val);
|
void si5351c_write_single(uint8_t reg, uint8_t val);
|
||||||
uint8_t si5351c_read_single(uint8_t reg);
|
uint8_t si5351c_read_single(uint8_t reg);
|
||||||
void si5351c_write(uint8_t* const data, const uint_fast8_t data_count);
|
void si5351c_write(uint8_t* const data, const uint_fast8_t data_count);
|
||||||
|
void si5351c_set_clock_source(const enum pll_sources source);
|
||||||
|
void si5351c_activate_best_clock_source(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "rf_path.h"
|
#include "rf_path.h"
|
||||||
#include "sgpio_isr.h"
|
#include "sgpio_isr.h"
|
||||||
#include "usb_bulk_buffer.h"
|
#include "usb_bulk_buffer.h"
|
||||||
|
#include "si5351c.h"
|
||||||
|
|
||||||
static volatile transceiver_mode_t _transceiver_mode = TRANSCEIVER_MODE_OFF;
|
static volatile transceiver_mode_t _transceiver_mode = TRANSCEIVER_MODE_OFF;
|
||||||
|
|
||||||
@ -210,12 +211,18 @@ int main(void) {
|
|||||||
|
|
||||||
rf_path_init();
|
rf_path_init();
|
||||||
|
|
||||||
|
uint16_t periodic_event_counter = 0;
|
||||||
|
|
||||||
unsigned int phase = 0;
|
unsigned int phase = 0;
|
||||||
while(true) {
|
while(true) {
|
||||||
// Check whether we need to initiate a CPLD update
|
// Check whether we need to initiate a CPLD update
|
||||||
if (start_cpld_update)
|
if (start_cpld_update)
|
||||||
cpld_update();
|
cpld_update();
|
||||||
|
|
||||||
|
if (++periodic_event_counter == 0) {
|
||||||
|
si5351c_activate_best_clock_source();
|
||||||
|
}
|
||||||
|
|
||||||
// Set up IN transfer of buffer 0.
|
// Set up IN transfer of buffer 0.
|
||||||
if ( usb_bulk_buffer_offset >= 16384
|
if ( usb_bulk_buffer_offset >= 16384
|
||||||
&& phase == 1
|
&& phase == 1
|
||||||
|
Reference in New Issue
Block a user