diff --git a/firmware/application/apps/ui_debug.cpp b/firmware/application/apps/ui_debug.cpp index a93caa31d..d3e077486 100644 --- a/firmware/application/apps/ui_debug.cpp +++ b/firmware/application/apps/ui_debug.cpp @@ -515,6 +515,81 @@ void RadioDiagnosticsView::update_status() { } } +#ifdef PRALINE +PralineRadioDebugView::PralineRadioDebugView(NavigationView& nav) { + add_children({&text_title, &text_lbl_lock, &text_lock_status, + &text_lbl_clk5, &text_clk5_status, + &text_lbl_spi, &text_spi_status, &text_lbl_fpga_ctrl, &text_fpga_ctrl, + &text_lbl_vaa, &text_vaa_status, &text_status_msg, + &button_refresh, &button_toggle_clk5, &button_done}); + + button_refresh.on_select = [this](Button&) { this->refresh(); }; + button_toggle_clk5.on_select = [this](Button&) { this->toggle_clk5(); }; + button_done.on_select = [&nav](Button&) { nav.pop(); }; + + refresh(); +} + +void PralineRadioDebugView::focus() { + button_refresh.focus(); +} + +void PralineRadioDebugView::toggle_clk5() { + // Si5351 Register 3 is the Output Enable mask. Bit 5 = CLK5. + // 0 = Enabled, 1 = Disabled. + uint8_t reg3 = portapack::clock_manager.si5351_read_register(3); + reg3 ^= 0x20; // Toggle Bit 5 (CLK5) + portapack::clock_manager.si5351_write_register(3, reg3); + refresh(); +} + +void PralineRadioDebugView::refresh() { + // 1. Check Mixer Lock Detect (GPIO6[25] / PD_11) [cite: 16, 17] + uint32_t gpio6_state = LPC_GPIO->PIN[6]; + bool locked = (gpio6_state >> 25) & 1; + text_lock_status.set(locked ? "LOCKED (OK)" : "UNLOCKED!"); + text_lock_status.set_style(locked ? Theme::getInstance()->fg_green : Theme::getInstance()->fg_red); + + // 2. Check Si5351 CLK5 Status (Reg 3, Bit 5) - 0 = ON, 1 = OFF + uint8_t si_reg3 = portapack::clock_manager.si5351_read_register(3); + bool clk5_on = !(si_reg3 & 0x20); + text_clk5_status.set(clk5_on ? "ON (40MHz)" : "OFF"); + text_clk5_status.set_style(clk5_on ? Theme::getInstance()->fg_green : Theme::getInstance()->fg_red); + + // 3. Check SPI Bit Mode (SSP1 CR0) + // DSS (Data Size Select) is Bit 3:0. 0x8 = 9-bit (MAX2831), 0xF = 16-bit (Classic) + uint32_t cr0 = LPC_SSP1->CR0; + uint8_t dss = cr0 & 0x0F; + if (dss == 0x08) + text_spi_status.set("9-Bit (Pro)"); + else + text_spi_status.set("Other (Err)"); + text_spi_status.set_style((dss == 0x08) ? Theme::getInstance()->fg_green : Theme::getInstance()->fg_red); + + // 4. Check FPGA Register 1 (DC Block status) [cite: 12, 13] + uint8_t fpga_r1 = radio::debug::fpga::register_read(1); + text_fpga_ctrl.set(to_string_hex(fpga_r1, 2)); + + // 5. Check VAA RF Power (GPIO4[1] / P8_1) - Active LOW [cite: 16, 17] + uint32_t gpio4_state = LPC_GPIO->PIN[4]; + bool vaa_on = !((gpio4_state >> 1) & 1); + text_vaa_status.set(vaa_on ? "ON" : "OFF"); + text_vaa_status.set_style(vaa_on ? Theme::getInstance()->fg_green : Theme::getInstance()->fg_red); + + // Diagnostic Summary + if (!locked && clk5_on && vaa_on) { + text_status_msg.set("Clock/Pwr OK. PLL not locked. Check tuning registers."); + text_status_msg.set_style(Theme::getInstance()->fg_red); + } else if (!clk5_on) { + text_status_msg.set("Mixer Clock is OFF. PLL cannot lock."); + text_status_msg.set_style(Theme::getInstance()->fg_red); + } else { + text_status_msg.set("Hardware Link Active."); + text_status_msg.set_style(Theme::getInstance()->fg_green); + } +} +#endif + /* BasebandStatusView ******************************************************/ BasebandStatusView::BasebandStatusView(NavigationView& nav) @@ -2748,6 +2823,7 @@ void DebugMenuView::on_populate() { #ifdef PRALINE {"System Diag", ui::Theme::getInstance()->fg_yellow->foreground, &bitmap_icon_peripherals, [this]() { nav_.push(); }}, {"Radio Diag", ui::Theme::getInstance()->fg_yellow->foreground, &bitmap_icon_peripherals, [this]() { nav_.push(); }}, + {"ProRadio Debug", ui::Theme::getInstance()->fg_yellow->foreground, &bitmap_icon_peripherals, [this]() { nav_.push(); }}, {"Signal Path", ui::Theme::getInstance()->fg_yellow->foreground, &bitmap_icon_peripherals, [this]() { nav_.push(); }}, {"GPIO Debug", ui::Theme::getInstance()->fg_yellow->foreground, &bitmap_icon_peripherals, [this]() { nav_.push(); }}, {"RFFC Status", ui::Theme::getInstance()->fg_yellow->foreground, &bitmap_icon_peripherals, [this]() { nav_.push(); }}, diff --git a/firmware/application/apps/ui_debug.hpp b/firmware/application/apps/ui_debug.hpp index 90b5cab87..5b4dc6698 100644 --- a/firmware/application/apps/ui_debug.hpp +++ b/firmware/application/apps/ui_debug.hpp @@ -438,6 +438,50 @@ class RadioDiagnosticsView : public View { "Done"}; }; +#ifdef PRALINE +/* Praline-Specific Radio Debug View + * Monitors Mixer Lock, SPI Bit Depth, and toggles Si5351 CLK5 + */ +class PralineRadioDebugView : public View { + public: + PralineRadioDebugView(NavigationView& nav); + void focus() override; + std::string title() const override { return "Pro Radio Debug"; }; + + private: + void refresh(); + void toggle_clk5(); + + Text text_title{{0, 0, 240, 16}, "=== Pro Radio Debug ==="}; + + // Mixer Lock (PD_11 / GPIO6[25]) + Text text_lbl_lock{{0, 24, 124, 16}, "Mix Lock (LD):"}; + Text text_lock_status{{126, 24, 114, 16}, "---"}; + + // Si5351 CLK5 (Mixer Reference) + Text text_lbl_clk5{{0, 40, 124, 16}, "Si5351 CLK5(Mix):"}; + Text text_clk5_status{{126, 40, 114, 16}, "---"}; + + // SPI Bus configuration check + Text text_lbl_spi{{0, 56, 124, 16}, "SPI Bit Mode:"}; + Text text_spi_status{{126, 56, 118, 16}, "---"}; + + // FPGA DC Block (Reg 1) + Text text_lbl_fpga_ctrl{{0, 72, 124, 16}, "FPGA Reg 1:"}; + Text text_fpga_ctrl{{126, 72, 118, 16}, "---"}; + + // VAA Power Rail (P8_1 / GPIO4[1]) + Text text_lbl_vaa{{0, 88, 124, 16}, "VAA RF Power:"}; + Text text_vaa_status{{126, 88, 118, 16}, "---"}; + + Text text_status_msg{{0, 110, 240, 48}, ""}; + + Button button_refresh{{8, 240, 72, 24}, "Refresh"}; + Button button_toggle_clk5{{88, 240, 72, 24}, "CLK5_T"}; + Button button_done{{168, 240, 64, 24}, "Done"}; +}; +#endif + /* BasebandStatusView ***************************************************/ class BasebandStatusView : public View { diff --git a/firmware/application/clock_manager.cpp b/firmware/application/clock_manager.cpp index b1b33d10a..2a6bb156c 100644 --- a/firmware/application/clock_manager.cpp +++ b/firmware/application/clock_manager.cpp @@ -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); diff --git a/firmware/application/hw/rffc507x.cpp b/firmware/application/hw/rffc507x.cpp index e8c2041b4..a7793c398 100644 --- a/firmware/application/hw/rffc507x.cpp +++ b/firmware/application/hw/rffc507x.cpp @@ -65,7 +65,11 @@ constexpr halrtcnt_t ticks_during_reset = (base_m4_clk_f * seconds_during_reset constexpr float seconds_after_reset = 5.0e-6; constexpr halrtcnt_t ticks_after_reset = (base_m4_clk_f * seconds_after_reset + 1); +#ifdef PRALINE +constexpr rf::Frequency reference_frequency = 40000000ULL; +#else constexpr auto reference_frequency = rffc5072_reference_f; +#endif namespace vco { @@ -114,31 +118,9 @@ constexpr size_t divider_min = 1U << divider_log2_min; constexpr size_t divider_max = 1U << divider_log2_max; constexpr size_t divider_log2(const rf::Frequency vco_frequency) { -#ifdef PRALINE - // PRALINE FIX: Avoid N register overflow (9-bit max = 511) - // With 40 MHz reference: - // - For VCO=5400 MHz, presc=÷2: N = (5400×2)/40 = 270 ✓ - // - For VCO=5400 MHz, presc=÷4: N = (5400×4)/40 = 540 ✗ OVERFLOW! - // - // Maximum safe VCO for ÷4 prescaler: - // N_max = 511, so VCO_max = (511 × 40) / 4 = 5110 MHz - // - // Use ÷4 only if VCO < 5110 MHz AND VCO > 3200 MHz - // Use ÷2 for VCO >= 5110 MHz to avoid overflow - - constexpr rf::Frequency overflow_threshold = 5110000000ULL; // Max VCO for ÷4 - constexpr rf::Frequency min_presc4_freq = 3200000000ULL; // Min VCO for ÷4 - - if ((vco_frequency > min_presc4_freq) && (vco_frequency < overflow_threshold)) { - return divider_log2_max; // ÷4 prescaler - } else { - return divider_log2_min; // ÷2 prescaler - } -#else return (vco_frequency > (prescaler::divider_min * prescaler::max_frequency)) ? prescaler::divider_log2_max : prescaler::divider_log2_min; -#endif } } /* namespace prescaler */ @@ -161,11 +143,7 @@ struct SynthConfig { const size_t prescaler_divider_log2 = prescaler::divider_log2(vco_frequency); -#ifndef PRALINE const uint64_t prescaled_lo_q24 = vco_frequency << (24 - prescaler_divider_log2); -#else - const uint64_t prescaled_lo_q24 = vco_frequency << (24 + prescaler_divider_log2); -#endif const uint64_t n_divider_q24 = prescaled_lo_q24 / reference_frequency; #ifdef PRALINE diff --git a/firmware/application/portapack.cpp b/firmware/application/portapack.cpp index 0ad489bd1..770ad8264 100644 --- a/firmware/application/portapack.cpp +++ b/firmware/application/portapack.cpp @@ -58,6 +58,10 @@ using asahi_kasei::ak4951::AK4951; extern "C" { #include "platform_detect.h" + +#ifdef PRALINE +#include "fpga_bridge.h" +#endif } namespace portapack { @@ -547,6 +551,12 @@ static void initialize_boot_splash_screen() { */ init_status_t init() { +#ifdef PRALINE + /* 1. HOLD FPGA IN RESET (Active Low) */ + // P5_2 is GPIO2[11] (FPGA CRESET) + palClearPad(GPIO2, 11); +#endif + set_idivc_base_clocks(cgu::CLK_SEL::IDIVC); i2c0.start(i2c_config_boot_clock); @@ -579,6 +589,25 @@ init_status_t init() { clock_manager.init_clock_generator(); +#ifdef PRALINE + // Force CLK4/CLK5 configuration BEFORE I2C bus stops + // This ensures the inversion bits are written while I2C is still active + + // CLK4 (MAX2831): ON, Integer, PLLA, INVERTED, MS_Self, 4mA = 0x5D + clock_manager.si5351_write_register(20, 0x5D); + + // CLK5 (RFFC5072): ON, Integer, PLLA, INVERTED, MS_Self, 6mA = 0x5E + clock_manager.si5351_write_register(21, 0x5E); + + // Enable CLK4 and CLK5 outputs NOW (before I2C stops) + uint8_t reg3 = clock_manager.si5351_read_register(3); + reg3 &= ~0x30; // Clear bits 4 and 5 to enable + clock_manager.si5351_write_register(3, reg3); + + // Wait for clocks to stabilize + chThdSleepMilliseconds(10); +#endif + i2c0.stop(); chThdSleepMilliseconds(10); @@ -618,6 +647,27 @@ init_status_t init() { clock_manager.enable_if_clocks(); clock_manager.enable_codec_clocks(); +#ifdef PRALINE + chThdSleepMilliseconds(20); + + // This function returns LD_SUCCESS (0) if the FPGA confirms the bitstream + // Call fpga_bridge_init and continue boot regardless of result + // (Watchdog was resetting device when we halted with while(1)) + int load_result = fpga_bridge_init(); + (void)load_result; // Ignore result for now, just let boot continue + + /* RELEASE FPGA RESET */ + // FPGA wakes up and latches the stable 40MHz CLK1 + // P5_2 is GPIO2[11] (FPGA CRESET) + palSetPad(GPIO2, 11); + + // Allow FPGA and related logic a brief stabilization period without busy-waiting + chThdSleepMilliseconds(10); + + // Keep LEDs off after FPGA load + LPC_GPIO->SET[2] = (1 << 1) | (1 << 2) | (1 << 8); +#endif + radio::init(); sdcStart(&SDCD1, nullptr); @@ -637,9 +687,6 @@ init_status_t init() { return_code = init_status_t::INIT_HACKRF_CPLD_FAILED; } -#else - // HackRF Pro (PRALINE) uses FPGA - already loaded in board.cpp __early_init() - // via fpga_bridge_init(), so nothing to do here #endif if (lcd_fast_setup) diff --git a/firmware/application/radio.cpp b/firmware/application/radio.cpp index 09c124473..c84f6b07d 100644 --- a/firmware/application/radio.cpp +++ b/firmware/application/radio.cpp @@ -156,8 +156,9 @@ void init() { #ifdef PRALINE /* Initialize FPGA registers - DC_BLOCK must be enabled for RX */ // debug::fpga::init(); - fpga_debug_register_write(1, 0x01); // DC_BLOCK=1, QUARTER_SHIFT=0, Q_INVERT=0 - fpga_debug_register_write(2, 0x00); // RX_DECIM=0 (no decimation for testing) + // These FPGA registers control DC_BLOCK, Q-Inv, QUARTER SHIFT, and Decimation. + fpga_debug_register_write(1, 0x03); // DC_BLOCK=1, QUARTER_SHIFT=1, Q_INVERT=0 + fpga_debug_register_write(2, 0x03); // RX_DECIM=8 (2^3 decimation for testing 20 MHz -> 2.5 MHz with audio for now) fpga_debug_register_write(3, 0x00); // TX_CTRL=0 fpga_debug_register_write(4, 0x00); // TX_INTRP=0 fpga_debug_register_write(5, 0x00); // TX_PSTEP=0 @@ -209,8 +210,9 @@ void set_direction(const rf::Direction new_direction) { #ifdef PRALINE - // CORRECT: FPGA register 1 only controls DC_BLOCK - fpga_debug_register_write(1, 0x01); // DC_BLOCK only, no QUARTER_SHIFT! + // This FPGA registers fix DC_BLOCK, Q-Inv, QUARTER SHIFT, and Decimation. + fpga_debug_register_write(1, 0x03); // DC_BLOCK, Q-Inv, no-QUARTER_SHIFT. + fpga_debug_register_write(2, 0x03); // RX_DECIM=8 (2^3 decimation for testing 20 MHz -> 2.5 MHz with audio for now) // Q inversion controlled by GPIO0[13] (SGPIO12), not FPGA register bool q_invert = mixer_invert ^ baseband_invert; diff --git a/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp b/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp index 43e1c9cd0..5a738b482 100755 --- a/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp +++ b/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp @@ -24,13 +24,6 @@ // Declare wrapper function. board.cpp to avoid conflicting gpio_t definitions. bool hackrf_r9; -// Declare the bridge function (no need to include HackRF headers here) -#ifdef PRALINE -extern "C" { - int fpga_bridge_init(void); -} -#endif - #if HAL_USE_PAL || defined(__DOXYGEN__) /** * @brief PAL setup. @@ -1043,10 +1036,8 @@ extern "C" void boardInit(void) { LPC_SCU->SFSP[1][0] = 0xF6; /* SGPIO7: P1_0 function 6, HOST_DATA7 */ { volatile uint32_t delay = 200000; while(delay--); } - // Trigger FPGA bitstream loading via fpga bridge - // Attempt to load the FPGA bitstream - // This function returns LD_SUCCESS (0) if the FPGA confirms the bitstream - // Use LEDs to check if initi is successful. + // Trigger FPGA bitstream loading via fpga bridge in portapack.cpp + // Use LEDs to check if boardInit initialization is successful. // Setup LED pin directions // LED1 (USB) = GPIO2[1], LED2 (RX) = GPIO2[2], LED3 (TX) = GPIO2[8] @@ -1057,14 +1048,6 @@ extern "C" void boardInit(void) { LPC_GPIO->SET[2] = (1 << 1) | (1 << 2) | (1 << 8); { volatile uint32_t delay = 200000; while(delay--); } - // Call fpga_bridge_init and continue boot regardless of result - // (Watchdog was resetting device when we halted with while(1)) - int load_result = fpga_bridge_init(); - (void)load_result; // Ignore result for now, just let boot continue - { volatile uint32_t delay = 200000; while(delay--); } - - // Keep LEDs off after FPGA load - LPC_GPIO->SET[2] = (1 << 1) | (1 << 2) | (1 << 8); #endif }