h1r9: add Si5351A support
This commit is contained in:

committed by
Mike Walters

parent
6d48671084
commit
1f73f2fd25
@ -36,6 +36,7 @@
|
||||
#include "i2c_lpc.h"
|
||||
#include "cpld_jtag.h"
|
||||
#include "platform_detect.h"
|
||||
#include "clkin.h"
|
||||
#include <libopencm3/lpc43xx/cgu.h>
|
||||
#include <libopencm3/lpc43xx/ccu.h>
|
||||
#include <libopencm3/lpc43xx/scu.h>
|
||||
@ -414,14 +415,26 @@ bool sample_rate_frac_set(uint32_t rate_num, uint32_t rate_denom)
|
||||
MSx_P2 = (128 * b) % c;
|
||||
MSx_P3 = c;
|
||||
|
||||
/* MS0/CLK0 is the source for the MAX5864/CPLD (CODEC_CLK). */
|
||||
si5351c_configure_multisynth(&clock_gen, 0, MSx_P1, MSx_P2, MSx_P3, 1);
|
||||
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
|
||||
/*
|
||||
* On HackRF One r9 all sample clocks are externally derived
|
||||
* from MS1/CLK1 operating at twice the sample rate.
|
||||
*/
|
||||
si5351c_configure_multisynth(&clock_gen, 1, MSx_P1, MSx_P2, MSx_P3, 0);
|
||||
} else {
|
||||
/*
|
||||
* On other platforms the clock generator produces three
|
||||
* different sample clocks, all derived from multisynth 0.
|
||||
*/
|
||||
/* MS0/CLK0 is the source for the MAX5864/CPLD (CODEC_CLK). */
|
||||
si5351c_configure_multisynth(&clock_gen, 0, MSx_P1, MSx_P2, MSx_P3, 1);
|
||||
|
||||
/* MS0/CLK1 is the source for the CPLD (CODEC_X2_CLK). */
|
||||
si5351c_configure_multisynth(&clock_gen, 1, 0, 0, 0, 0); //p1 doesn't matter
|
||||
/* MS0/CLK1 is the source for the CPLD (CODEC_X2_CLK). */
|
||||
si5351c_configure_multisynth(&clock_gen, 1, 0, 0, 0, 0); //p1 doesn't matter
|
||||
|
||||
/* MS0/CLK2 is the source for SGPIO (CODEC_X2_CLK) */
|
||||
si5351c_configure_multisynth(&clock_gen, 2, 0, 0, 0, 0); //p1 doesn't matter
|
||||
/* MS0/CLK2 is the source for SGPIO (CODEC_X2_CLK) */
|
||||
si5351c_configure_multisynth(&clock_gen, 2, 0, 0, 0, 0); //p1 doesn't matter
|
||||
}
|
||||
|
||||
if (streaming) {
|
||||
sgpio_cpld_stream_enable(&sgpio_config);
|
||||
@ -482,14 +495,38 @@ bool sample_rate_set(const uint32_t sample_rate_hz)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* MS0/CLK0 is the source for the MAX5864/CPLD (CODEC_CLK). */
|
||||
si5351c_configure_multisynth(&clock_gen, 0, p1, p2, p3, 1);
|
||||
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
|
||||
/*
|
||||
* On HackRF One r9 all sample clocks are externally derived
|
||||
* from MS1/CLK1 operating at twice the sample rate.
|
||||
*/
|
||||
si5351c_configure_multisynth(&clock_gen, 0, p1, p2, p3, 0);
|
||||
} else {
|
||||
/*
|
||||
* On other platforms the clock generator produces three
|
||||
* different sample clocks, all derived from multisynth 0.
|
||||
*/
|
||||
/* MS0/CLK0 is the source for the MAX5864/CPLD (CODEC_CLK). */
|
||||
si5351c_configure_multisynth(&clock_gen, 0, p1, p2, p3, 1);
|
||||
|
||||
/* MS0/CLK1 is the source for the CPLD (CODEC_X2_CLK). */
|
||||
si5351c_configure_multisynth(&clock_gen, 1, p1, 0, 1, 0); //p1 doesn't matter
|
||||
/* MS0/CLK1 is the source for the CPLD (CODEC_X2_CLK). */
|
||||
si5351c_configure_multisynth(
|
||||
&clock_gen,
|
||||
1,
|
||||
p1,
|
||||
0,
|
||||
1,
|
||||
0); //p1 doesn't matter
|
||||
|
||||
/* MS0/CLK2 is the source for SGPIO (CODEC_X2_CLK) */
|
||||
si5351c_configure_multisynth(&clock_gen, 2, p1, 0, 1, 0); //p1 doesn't matter
|
||||
/* MS0/CLK2 is the source for SGPIO (CODEC_X2_CLK) */
|
||||
si5351c_configure_multisynth(
|
||||
&clock_gen,
|
||||
2,
|
||||
p1,
|
||||
0,
|
||||
1,
|
||||
0); //p1 doesn't matter
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -596,7 +633,12 @@ void cpu_clock_init(void)
|
||||
si5351c_configure_pll_multisynth(&clock_gen);
|
||||
|
||||
/*
|
||||
* Clocks:
|
||||
* Clocks on HackRF One r9:
|
||||
* CLK0 -> MAX5864/CPLD/SGPIO (sample clocks)
|
||||
* CLK1 -> RFFC5072/MAX2837
|
||||
* CLK2 -> External Clock Output/LPC43xx (power down at boot)
|
||||
*
|
||||
* Clocks on other platforms:
|
||||
* CLK0 -> MAX5864/CPLD
|
||||
* CLK1 -> CPLD
|
||||
* CLK2 -> SGPIO
|
||||
@ -607,22 +649,33 @@ void cpu_clock_init(void)
|
||||
* CLK7 -> LPC43xx (uses a 12MHz crystal by default)
|
||||
*/
|
||||
|
||||
/* 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 */
|
||||
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
|
||||
/* MS0/CLK0 is the reference for both RFFC5071 and MAX2837. */
|
||||
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. */
|
||||
@ -766,6 +819,10 @@ void cpu_clock_init(void)
|
||||
// CCU2_CLK_APLL_CFG = 0;
|
||||
// CCU2_CLK_SDIO_CFG = 0;
|
||||
#endif
|
||||
|
||||
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
|
||||
clkin_detect_init();
|
||||
}
|
||||
}
|
||||
|
||||
clock_source_t activate_best_clock_source(void)
|
||||
|
@ -191,7 +191,7 @@ void si5351c_configure_clock_control(
|
||||
const enum pll_sources source)
|
||||
{
|
||||
uint8_t pll;
|
||||
uint8_t clk3_ctrl;
|
||||
uint8_t clkout_ctrl;
|
||||
|
||||
#ifdef RAD1O
|
||||
(void) source;
|
||||
@ -201,31 +201,29 @@ void si5351c_configure_clock_control(
|
||||
|
||||
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
||||
if (source == PLL_SOURCE_CLKIN) {
|
||||
if (detected_platform() < BOARD_ID_HACKRF1_R9) {
|
||||
/* PLLB on CLKIN */
|
||||
pll = SI5351C_CLK_PLL_SRC_B;
|
||||
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
|
||||
/*
|
||||
* HackRF One r9 always uses PLL A on the XTAL input
|
||||
* but externally switches that input to CLKIN.
|
||||
*/
|
||||
pll = SI5351C_CLK_PLL_SRC_A;
|
||||
gpio_set(&gpio_h1r9_clkin_en);
|
||||
} else {
|
||||
/* PLLB on CLKIN */
|
||||
pll = SI5351C_CLK_PLL_SRC_B;
|
||||
}
|
||||
} else {
|
||||
/* PLLA on XTAL */
|
||||
pll = SI5351C_CLK_PLL_SRC_A;
|
||||
if (detected_platform() < BOARD_ID_HACKRF1_R9) {
|
||||
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
|
||||
gpio_clear(&gpio_h1r9_clkin_en);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (clkout_enabled) {
|
||||
clk3_ctrl = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) |
|
||||
clkout_ctrl = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) |
|
||||
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
|
||||
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA);
|
||||
} else {
|
||||
clk3_ctrl = SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE;
|
||||
clkout_ctrl = SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE;
|
||||
}
|
||||
|
||||
/* Clock to CPU is deactivated as it is not used and creates noise */
|
||||
@ -241,7 +239,7 @@ void si5351c_configure_clock_control(
|
||||
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),
|
||||
clk3_ctrl,
|
||||
clkout_ctrl,
|
||||
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_INV,
|
||||
@ -249,18 +247,28 @@ void si5351c_configure_clock_control(
|
||||
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, /* not connected, but: PLL A int mode */
|
||||
SI5351C_CLK_POWERDOWN |
|
||||
SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/
|
||||
SI5351C_CLK_INT_MODE /* not connected, but: PLL B int mode */
|
||||
};
|
||||
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
|
||||
data[1] = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC_A |
|
||||
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
|
||||
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA);
|
||||
data[2] = SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC_A |
|
||||
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
|
||||
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA);
|
||||
data[3] = clkout_ctrl;
|
||||
data[4] = SI5351C_CLK_POWERDOWN;
|
||||
data[5] = SI5351C_CLK_POWERDOWN;
|
||||
data[6] = SI5351C_CLK_POWERDOWN;
|
||||
}
|
||||
si5351c_write(drv, data, sizeof(data));
|
||||
}
|
||||
|
||||
#define SI5351C_CLK_ENABLE(x) (0 << x)
|
||||
#define SI5351C_CLK_DISABLE(x) (1 << x)
|
||||
#define SI5351C_REG_OUTPUT_EN (3)
|
||||
#define SI5351C_REG_CLK3_CTRL (19)
|
||||
|
||||
void si5351c_enable_clock_outputs(si5351c_driver_t* const drv)
|
||||
{
|
||||
@ -270,8 +278,19 @@ void si5351c_enable_clock_outputs(si5351c_driver_t* const drv)
|
||||
uint8_t value = SI5351C_CLK_ENABLE(0) | SI5351C_CLK_ENABLE(1) |
|
||||
SI5351C_CLK_ENABLE(2) | SI5351C_CLK_ENABLE(4) | SI5351C_CLK_ENABLE(5) |
|
||||
SI5351C_CLK_DISABLE(6) | SI5351C_CLK_DISABLE(7);
|
||||
uint8_t clkout = 3;
|
||||
|
||||
value |= (clkout_enabled) ? SI5351C_CLK_ENABLE(3) : SI5351C_CLK_DISABLE(3);
|
||||
/* HackRF One r9 has only three clock generator outputs. */
|
||||
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
|
||||
clkout = 2;
|
||||
value = SI5351C_CLK_ENABLE(0) | SI5351C_CLK_ENABLE(1) |
|
||||
SI5351C_CLK_DISABLE(3) | SI5351C_CLK_DISABLE(4) |
|
||||
SI5351C_CLK_DISABLE(5) | SI5351C_CLK_DISABLE(6) |
|
||||
SI5351C_CLK_DISABLE(7);
|
||||
}
|
||||
|
||||
value |= (clkout_enabled) ? SI5351C_CLK_ENABLE(clkout) :
|
||||
SI5351C_CLK_DISABLE(clkout);
|
||||
uint8_t data[] = {SI5351C_REG_OUTPUT_EN, value};
|
||||
si5351c_write(drv, data, sizeof(data));
|
||||
|
||||
@ -325,8 +344,14 @@ void si5351c_clkout_enable(si5351c_driver_t* const drv, uint8_t enable)
|
||||
{
|
||||
clkout_enabled = (enable > 0);
|
||||
|
||||
//FIXME this should be somewhere else
|
||||
uint8_t clkout = 3;
|
||||
/* HackRF One r9 has only three clock generator outputs. */
|
||||
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
|
||||
clkout = 2;
|
||||
}
|
||||
/* Configure clock to 10MHz */
|
||||
si5351c_configure_multisynth(drv, 3, 80 * 128 - 512, 0, 1, 0);
|
||||
si5351c_configure_multisynth(drv, clkout, 80 * 128 - 512, 0, 1, 0);
|
||||
|
||||
si5351c_configure_clock_control(drv, active_clock_source);
|
||||
si5351c_enable_clock_outputs(drv);
|
||||
|
Reference in New Issue
Block a user