Mixer lock:: update clocks and move fpga_bridge_init to portapack.cpp (#3039)

* Updated harckrf_gpio methods to more closely reflect hackrf_usb. Added some ui debug updates to RFFC5072 Status View.

* Updated tuning tables for tuning.cpp. Remnoved 15MHz lower limit in max2831.cpp since lower bandwidths don't seem to be causing lower band issues. Added more opportunities for clocks to stabalize at startup in board.cpp. Added/amended UI to help with addresssing low band tuning issues. Cleaned up stale comments in radio.cpp.

* Ran format-code.sh

* Updated to remove commented lines as part of clean up addressing review comments.

* Fixed clock_manager.cpp configruation for praline. Praline hackrf pro should have: CLK4: 6mA, Invert RFFC5072 40MHz ref and CLK5: 4mA, Invert MAX2831 40MHz ref. Improvements should be visible in the watefall at 2.4GHz, and between 2.311 and 2.599GHz.

* After reviewin clock config, updated values to reflect: CLK0 MAX5864 (ADC) 40 MHz 4mA Normal Integer Minimizes sampling jitter for SNR. CLK1 iCE40 FPGA 40 MHz 6mA Normal Integer Stable timing for the SPI bridge. CLK2 LPC43xx MCU 40 MHz 4mA Normal Integer Standard reference for MCU PLL. CLK3 SMA Port P1 10 MHz 8mA Normal Integer Cleanest square wave for Ext Ref. CLK4 RFFC5072 (Mixer) 40 MHz 6mA Inverted Integer Crucial for PLL Lock stability. CLK5 MAX2831 (TRX) 40 MHz 4mA Inverted Integer Reduces phase noise in the 2.4GHz LO. CLK6 SMA Port P2 10 MHz 8mA Normal Integer Sync output for external gear. CLK7 Reserved Off N/A N/A N/A Disabled to save power/reduce EMI.

* Ran format-code.sh

* Moved fpga_brdige_init to portapack.cpp. This more closely resembles how hackrf_usb starts initializes the fpga, and allows time for the clocks to stabilize and facilitate locking to support low band tuning.

* Ran format-code.sh

* Added ProRadio Debug display to check for / debug locking.

* Moved fpga_bridge_init before radio_init in portapack.cpp

* Low band can now see signals. Updated clock_manager, rffc507 and portapack.cpp to ensure fpga intialized correctly. Ensures rffc507x.cpp has correct 40MHz reference frequency, prescaler, and synth configuration.

* Updated radio to add q-invert on, dc-block on, and deimation=3 (8x, for 20 -> 2.5 MHz decimation for testing cleaner low band signals.

* Ran format-code.sh
This commit is contained in:
stafur
2026-02-24 03:36:55 -05:00
committed by GitHub
parent bfbbacd43c
commit b09efb4d3c
7 changed files with 232 additions and 72 deletions
+50 -20
View File
@@ -246,11 +246,11 @@ constexpr ClockControls si5351a_clock_control_common{{
{ClockControl::ClockCurrentDrive::_4mA, ClockControl::ClockSource::MS_Self, ClockControl::ClockInvert::Normal, ClockControl::MultiSynthSource::PLLA, ClockControl::MultiSynthMode::Integer, ClockControl::ClockPowerDown::Power_Off},
// CLK3: CLKOUT (optional) SMA Port P1
{ClockControl::ClockCurrentDrive::_8mA, ClockControl::ClockSource::MS_Self, ClockControl::ClockInvert::Normal, ClockControl::MultiSynthSource::PLLA, ClockControl::MultiSynthMode::Integer, ClockControl::ClockPowerDown::Power_Off},
// CLK4: PRALINE RFFC5072 reference (40 MHz) - INVERTED, 6mA, Integer mode
// CLK4: PRALINE MAX2831 reference (40 MHz) - INVERTED per hackrf_usb, 4mA, Integer mode
{ClockControl::ClockCurrentDrive::_4mA, ClockControl::ClockSource::MS_Self, ClockControl::ClockInvert::Invert, ClockControl::MultiSynthSource::PLLA, ClockControl::MultiSynthMode::Integer, ClockControl::ClockPowerDown::Power_Off},
// CLK5: PRALINE RFFC5072 reference (40 MHz) - INVERTED, 6mA, Integer mode
// This matches HackRF One OG configuration for RFFC5072
{ClockControl::ClockCurrentDrive::_6mA, ClockControl::ClockSource::MS_Self, ClockControl::ClockInvert::Invert, ClockControl::MultiSynthSource::PLLA, ClockControl::MultiSynthMode::Integer, ClockControl::ClockPowerDown::Power_Off},
// CLK5: PRALINE MAX2831 reference (40 MHz) - INVERTED per hackrf_usb, 4mA, Integer mode
{ClockControl::ClockCurrentDrive::_4mA, ClockControl::ClockSource::MS_Self, ClockControl::ClockInvert::Invert, ClockControl::MultiSynthSource::PLLA, ClockControl::MultiSynthMode::Integer, ClockControl::ClockPowerDown::Power_Off},
// CLK6: SMA Port P2
{ClockControl::ClockCurrentDrive::_8mA, ClockControl::ClockSource::MS_Self, ClockControl::ClockInvert::Normal, ClockControl::MultiSynthSource::PLLA, ClockControl::MultiSynthMode::Integer, ClockControl::ClockPowerDown::Power_Off},
#else
@@ -401,8 +401,8 @@ void ClockManager::init_clock_generator() {
/* PRALINE uses Si5351A with:
* CLK0 = AFE_CLK (codec/FPGA sample clock)
* CLK1 = SCT_CLK (FPGA timing clock at 2x sample rate)
* CLK4 = first IF (RFFC5072)
* CLK5 = second IF (MAX2831)
* CLK4 = second IF (MAX2831)
* CLK5 = first IF (RFFC5072)
* Uses PLLA on XTAL only (no CLKIN support).
*/
@@ -489,6 +489,21 @@ void ClockManager::init_clock_generator() {
// CRITICAL: Add delay to ensure Si5351 writes complete before I2C bus stops
chThdSleepMilliseconds(100);
// ===== ADD THIS SAFETY BLOCK =====
// Pre-configure CLK4/CLK5 with correct settings including inversion.
// This ensures the registers have correct values even if enable_if_clocks()
// is not called or fails. The clocks will still be powered off until
// enable_if_clocks() enables the outputs.
// CLK5: OFF (for now), Integer, PLLA, INVERTED, MS_Self, 6mA = 0xDE
// (Same as 0x5E but with bit 7 set for power off)
clock_generator.write_register(21, 0xDE);
// CLK4: OFF (for now), Integer, PLLA, INVERTED, MS_Self, 4mA = 0xDD
clock_generator.write_register(20, 0xDD);
// ===== END SAFETY BLOCK =====
#else
// Wait for PLL(s) to lock - with timeout to prevent hang
uint8_t device_status_mask = hackrf_r9
@@ -496,14 +511,8 @@ void ClockManager::init_clock_generator() {
: (ref_pll == ClockControl::MultiSynthSource::PLLB)
? 0x40
: 0x20;
#ifndef PRALINE
while ((clock_generator.device_status() & device_status_mask) != 0);
#else
uint32_t pll_timeout = 100000;
while ((clock_generator.device_status() & device_status_mask) != 0 && pll_timeout > 0) {
pll_timeout--;
}
#endif
clock_generator.set_clock_control(
clock_generator_output_mcu_clkin,
@@ -579,11 +588,11 @@ void ClockManager::enable_codec_clocks() {
#ifdef PRALINE
/* PRALINE: CLK0 (AFE_CLK) for codec/FPGA, CLK1 (SCT_CLK) for FPGA timing.
* Reference hackrf_core.c shows PRALINE needs both CLK0 and CLK1. */
clock_generator.enable_clock(clock_generator_output_og_codec); /* CLK0 */
clock_generator.enable_clock(clock_generator_output_og_cpld); /* CLK1 */
clock_generator.enable_clock(clock_generator_output_og_codec); /* CLK0 MAX5864*/
clock_generator.enable_clock(clock_generator_output_og_cpld); /* CLK1 iCE40 FPGA*/
clock_generator.enable_clock(clock_generator_output_og_sgpio); /* CLK2 LPC43xx*/
clock_generator.enable_output_mask(
(1U << clock_generator_output_og_codec) |
(1U << clock_generator_output_og_cpld));
(1U << clock_generator_output_og_codec) | (1U << clock_generator_output_og_cpld) | (1U << clock_generator_output_og_sgpio));
#else
if (hackrf_r9) {
clock_generator.enable_clock(clock_generator_output_r9_sgpio);
@@ -611,12 +620,12 @@ void ClockManager::disable_codec_clocks() {
* CLKx_DISABLE_STATE.
*/
#ifdef PRALINE
/* PRALINE: CLK0 (AFE_CLK) and CLK1 (SCT_CLK) used for codec/FPGA */
/* PRALINE: CLK0 (AFE_CLK), CLK1 (SCT_CLK), and CLK2 MCU used for codec/FPGA */
clock_generator.disable_output_mask(
(1U << clock_generator_output_og_codec) |
(1U << clock_generator_output_og_cpld));
(1U << clock_generator_output_og_codec) | (1U << clock_generator_output_og_cpld) | (1U << clock_generator_output_og_sgpio));
clock_generator.disable_clock(clock_generator_output_og_codec);
clock_generator.disable_clock(clock_generator_output_og_cpld);
clock_generator.disable_clock(clock_generator_output_og_sgpio);
#else
if (hackrf_r9) {
clock_generator.disable_output_mask(1U << clock_generator_output_r9_sgpio);
@@ -633,7 +642,28 @@ void ClockManager::disable_codec_clocks() {
void ClockManager::enable_if_clocks() {
#ifdef PRALINE
/* PRALINE uses CLK4 (first IF) and CLK5 (second IF) like original HackRF One */
/* PRALINE: CLK4=MAX2831, CLK5=RFFC5072
*
* Force-write complete configuration to guarantee correct setup.
* Added force-write to verify correct registers are applying necessary register clock settings.
*/
// Configure and enable CLK4 (MAX2831)
// Register 20: ON, Integer, PLLA, INVERTED, MS_Self, 4mA = 0x5D
clock_generator.write_register(20, 0x5D);
// Configure and enable CLK5 (RFFC5072) - CRITICAL!
// Register 21: ON, Integer, PLLA, INVERTED, MS_Self, 6mA = 0x5E
clock_generator.write_register(21, 0x5E);
// Enable outputs (register 3, bits 4 and 5 = 0)
uint8_t reg3 = clock_generator.read_register(3);
reg3 &= ~0x30;
clock_generator.write_register(3, reg3);
chThdSleepMilliseconds(10);
/* PRALINE uses CLK5 (first IF) and CLK4 (second IF) */
clock_generator.enable_clock(clock_generator_output_og_first_if);
clock_generator.enable_output_mask(1U << clock_generator_output_og_first_if);
clock_generator.enable_clock(clock_generator_output_og_second_if);