Reset only sample clock outputs when changing rate
Some checks failed
Build / host (3.10.0, map[os:ubuntu shell:bash]) (push) Failing after 5s
Build / host (3.16.0, map[os:ubuntu shell:bash]) (push) Failing after 7s
Build / host (3.21.0, map[os:ubuntu shell:bash]) (push) Failing after 8s
Build / host (4.0.0, map[os:ubuntu shell:bash]) (push) Failing after 6s
Build / host (latest, map[os:ubuntu shell:bash]) (push) Failing after 6s
Build / firmware (HACKRF_ONE, 3.10.0, ubuntu) (push) Failing after 6s
Build / firmware (HACKRF_ONE, latest, ubuntu) (push) Failing after 3s
Build / firmware (JAWBREAKER, latest, ubuntu) (push) Failing after 3s
Build / firmware (JAWBREAKER, 3.10.0, ubuntu) (push) Failing after 4s
Build / firmware (PRALINE, 3.10.0, ubuntu) (push) Failing after 6s
Build / firmware (RAD1O, 3.10.0, ubuntu) (push) Failing after 4s
Build / firmware (PRALINE, latest, ubuntu) (push) Failing after 6s
Build / firmware (RAD1O, latest, ubuntu) (push) Failing after 5s
Check code style / clang-format (push) Failing after 4s
Check code style / clang-format-1 (push) Failing after 6s
Check code style / clang-format-2 (push) Failing after 7s
Check code style / clang-format-3 (push) Failing after 8s
Build / firmware (RAD1O, latest, macos) (push) Has been cancelled
Build / host (latest, --install-prefix=/usr/local, map[os:windows shell:msys2]) (push) Has been cancelled
Build / host (latest, -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake --install-prefix=$env:GITHUB_WORKSPACE/install, map[os:windows shell:pwsh]) (push) Has been cancelled
Build / host (latest, map[os:macos shell:bash]) (push) Has been cancelled
Build / firmware (HACKRF_ONE, 3.10.0, macos) (push) Has been cancelled
Build / firmware (HACKRF_ONE, latest, macos) (push) Has been cancelled
Build / firmware (HACKRF_ONE, latest, windows) (push) Has been cancelled
Build / firmware (JAWBREAKER, 3.10.0, macos) (push) Has been cancelled
Build / firmware (JAWBREAKER, latest, macos) (push) Has been cancelled
Build / firmware (JAWBREAKER, latest, windows) (push) Has been cancelled
Build / firmware (PRALINE, 3.10.0, macos) (push) Has been cancelled
Build / firmware (PRALINE, latest, macos) (push) Has been cancelled
Build / firmware (PRALINE, latest, windows) (push) Has been cancelled
Build / firmware (RAD1O, 3.10.0, macos) (push) Has been cancelled
Build / host (3.10.0, map[os:macos shell:bash]) (push) Has been cancelled
Build / host (3.16.0, map[os:macos shell:bash]) (push) Has been cancelled
Build / host (3.21.0, -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake --install-prefix=$env:GITHUB_WORKSPACE/install, map[os:windows shell:pwsh]) (push) Has been cancelled
Build / host (3.21.0, map[os:macos shell:bash]) (push) Has been cancelled
Build / host (4.0.0, -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake --install-prefix=$env:GITHUB_WORKSPACE/install, map[os:windows shell:pwsh]) (push) Has been cancelled
Build / host (4.0.0, map[os:macos shell:bash]) (push) Has been cancelled
Build / firmware (RAD1O, latest, windows) (push) Has been cancelled

This commit is contained in:
Michael Ossmann 2026-04-01 19:42:32 -04:00
parent dc8b0c84b1
commit 1c29079faf
3 changed files with 69 additions and 26 deletions

View file

@ -325,7 +325,7 @@ fp_40_24_t sample_rate_set(const fp_40_24_t sample_rate, const bool program)
}
/* Reset PLL to synchronize output clock phase. */
si5351c_reset_pll(&clock_gen);
si5351c_reset_pll(&clock_gen, SI5351C_PLL_A);
#endif
if (streaming) {
@ -622,7 +622,7 @@ void clock_gen_init(void)
si5351c_configure_clock_control(&clock_gen);
si5351c_set_clock_source(&clock_gen, PLL_SOURCE_XTAL);
// soft reset
si5351c_reset_pll(&clock_gen);
si5351c_reset_pll(&clock_gen, SI5351C_PLL_BOTH);
si5351c_enable_clock_outputs(&clock_gen);
}

View file

@ -41,6 +41,7 @@
static enum pll_sources active_clock_source = PLL_SOURCE_UNINITIALIZED;
/* External clock output default is deactivated as it creates noise */
static bool clkout_enabled = false;
static uint8_t outputs_disabled = 0xff;
/* write to single register */
void si5351c_write_single(si5351c_driver_t* const drv, uint8_t reg, uint8_t val)
@ -73,7 +74,30 @@ void si5351c_write(
/* Disable all CLKx outputs. */
void si5351c_disable_all_outputs(si5351c_driver_t* const drv)
{
uint8_t data[] = {3, 0xFF};
outputs_disabled = 0xff;
uint8_t data[] = {3, outputs_disabled};
si5351c_write(drv, data, sizeof(data));
}
/* Disable all CLKx outputs using selected PLL. */
void si5351c_disable_pll_outputs(si5351c_driver_t* const drv, si5351c_pll_t pll)
{
/*
* Bitmask defines outputs using PLL B. Other outputs are assumed to
* use PLL A.
*/
uint8_t pllb_outputs = 0x00;
if (detected_platform() == BOARD_ID_PRALINE) {
pllb_outputs = 0x30;
}
if (pll & SI5351C_PLL_A) {
outputs_disabled |= ~pllb_outputs;
}
if (pll & SI5351C_PLL_B) {
outputs_disabled |= pllb_outputs;
}
uint8_t data[] = {3, outputs_disabled};
si5351c_write(drv, data, sizeof(data));
}
@ -156,11 +180,19 @@ void si5351c_configure_pll_multisynth(
si5351c_write(drv, data, sizeof(data));
}
void si5351c_reset_pll(si5351c_driver_t* const drv)
void si5351c_reset_pll(si5351c_driver_t* const drv, si5351c_pll_t pll)
{
si5351c_disable_all_outputs(drv);
/* reset PLLA and PLLB */
uint8_t data[] = {177, 0xA0};
uint8_t value = 0;
if (pll & SI5351C_PLL_A) {
value |= 0x20;
}
if (pll & SI5351C_PLL_B) {
value |= 0x80;
}
si5351c_disable_pll_outputs(drv, pll);
uint8_t data[] = {177, value};
si5351c_write(drv, data, sizeof(data));
delay_us_at_mhz(2000, 204);
si5351c_enable_clock_outputs(drv);
@ -202,11 +234,10 @@ void si5351c_configure_multisynth(
void si5351c_configure_clock_control(si5351c_driver_t* const drv)
{
const uint8_t pll = SI5351C_CLK_PLL_SRC_A;
uint8_t clkout_ctrl;
if (clkout_enabled) {
clkout_ctrl = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) |
clkout_ctrl = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA);
} else {
@ -217,20 +248,20 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv)
/* External clock output is kept in current state */
uint8_t data[] = {
16,
SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(pll) |
SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_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_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA) | SI5351C_CLK_INV,
SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) |
SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA),
clkout_ctrl,
SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) |
SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_6MA) | SI5351C_CLK_INV,
SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) |
SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA),
SI5351C_CLK_POWERDOWN |
@ -239,10 +270,10 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv)
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 |
data[1] = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_6MA);
data[2] = SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC_A |
data[2] = SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA);
data[3] = clkout_ctrl;
@ -252,20 +283,27 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv)
}
#ifdef PRALINE
/* CLK0: AFE_CLK */
data[1] = SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(pll) |
data[1] = SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA);
/* CLK1: SCT_CLK and FPGA_CLK */
data[2] = SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(pll) |
data[2] = SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA);
/* CLK3: CLKOUT */
clkout_ctrl = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_B) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA);
/* CLK4: XCVR_CLK */
data[5] = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) |
data[5] = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_B) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA) | SI5351C_CLK_INV;
data[6] = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_B) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA);
if ((detected_revision() & ~BOARD_REV_GSG) < BOARD_REV_PRALINE_R1_1) {
/* CLK2: FPGA_CLK (not shared with SCT_CLK on older boards) */
data[3] = SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(pll) |
data[3] = SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA);
} else {
@ -317,6 +355,7 @@ void si5351c_enable_clock_outputs(si5351c_driver_t* const drv)
SI5351C_CLK_DISABLE(clkout);
uint8_t data[] = {SI5351C_REG_OUTPUT_EN, value};
si5351c_write(drv, data, sizeof(data));
outputs_disabled = value;
#if defined(HACKRF_ONE)
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
@ -375,7 +414,7 @@ void si5351c_set_clock_source(si5351c_driver_t* const drv, const enum pll_source
}
si5351c_configure_pll_multisynth(drv, source);
active_clock_source = source;
si5351c_reset_pll(drv);
si5351c_reset_pll(drv, SI5351C_PLL_BOTH);
}
bool si5351c_clkin_signal_valid(si5351c_driver_t* const drv)

View file

@ -39,10 +39,6 @@ extern "C" {
#define SI5351C_CLK_INT_MODE (1 << 6)
#define SI5351C_CLK_FRAC_MODE (0 << 6)
#define SI5351C_CLK_PLL_SRC(x) (x << 5)
#define SI5351C_CLK_PLL_SRC_A 0
#define SI5351C_CLK_PLL_SRC_B 1
#define SI5351C_CLK_INV (1 << 4)
#define SI5351C_CLK_SRC(x) (x << 2)
@ -60,6 +56,14 @@ extern "C" {
#define SI5351C_LOS (1 << 4)
#define SI5351C_REVID 0x03
typedef enum {
SI5351C_PLL_A = 1,
SI5351C_PLL_B = 2,
SI5351C_PLL_BOTH = 3,
} si5351c_pll_t;
#define SI5351C_CLK_PLL_SRC(x) ((x & SI5351C_PLL_B) << 4)
enum pll_sources {
PLL_SOURCE_UNINITIALIZED = -1,
PLL_SOURCE_XTAL = 0,
@ -82,7 +86,7 @@ void si5351c_configure_pll_sources(
void si5351c_configure_pll_multisynth(
si5351c_driver_t* const drv,
const enum pll_sources source);
void si5351c_reset_pll(si5351c_driver_t* const drv);
void si5351c_reset_pll(si5351c_driver_t* const drv, si5351c_pll_t pll);
void si5351c_configure_multisynth(
si5351c_driver_t* const drv,
const uint_fast8_t ms_number,