From 9ab367f2e012e9feb267f618e25e912d386a734c Mon Sep 17 00:00:00 2001 From: Pezsma <159525557+Pezsma@users.noreply.github.com> Date: Thu, 11 Jun 2026 13:24:42 +0200 Subject: [PATCH] Add praline gpio (#3218) * Implement antenna bias control for Praline and update GPIO configurations * Add GPIO power management functions and update board initialization for Praline * Refactor power management functions for Praline and update GPIO configurations * Update GPIO configurations for Praline and enable power control pins. AA_EN enabled * Refactor GPIO configuration for Praline: update array size definitions and clean up comments * Add P1 and P2 control functions for PRALINE * Introduced P1_Function and P2_Function enums in ClockManager to manage multiplexer control. * mplemented set_p1_control and set_p2_control methods for configuring P1 and P2 control pins based on specified functions. * Updated clock_manager.hpp and clock_manager.cpp to include new functionality. * Modified MAX2837 and MAX2839 initialization to conditionally configure GPIO based on PRALINE. * Adjusted RFFC507x and RFFC507x_SPI initialization to include GPIO setup for PRALINE. - Refactored RF path initialization to remove unnecessary GPIO setup. - Updated board configuration for PRALINE to reflect new GPIO settings and pin configurations. - Cleaned up FPGA bridge code by removing unused pin configuration functions. - Adjusted SCU array size in pal_lld.h for PRALINE. - Enhanced hackrf_gpio.hpp to define multiplexer control pins for PRALINE. - Modified LED setup to accommodate active-low configuration for PRALINE. * Refactor GPIO and power control functions - Removed unused power control function declarations from board.h. - Enhanced gpio.hpp with new pin setup functions and GPIO control structures for PRALINE. - Consolidated multiplexer control pin definitions into gpio_control namespace. - Moved power control function implementations to gpio.cpp, including detailed VAA power management logic. - Updated power control functions to handle both PRALINE and HackRF R9 configurations. - Cleaned up hackrf_gpio.hpp by removing redundant multiplexer control definitions. * Refactor GPIO control for PRALINE: update MAX2831 and RFFC507x configurations, add new GPIO mappings * Refactor GPIO configurations for PRALINE: update anti-aliasing filter pin mapping, enhance LED setup logic, and add placeholder GPIO entries. * Refactor GPIO configurations for PRALINE: update LED mappings and remove unused anti-aliasing filter GPIO entry. --- firmware/application/CMakeLists.txt | 1 + firmware/application/clock_manager.cpp | 98 +- firmware/application/clock_manager.hpp | 23 + firmware/application/event_m0.cpp | 9 +- firmware/application/hw/max2831.cpp | 19 +- firmware/application/hw/max2837.cpp | 6 + firmware/application/hw/max2839.cpp | 6 + firmware/application/hw/rffc507x.cpp | 6 + firmware/application/hw/rffc507x_spi.cpp | 2 + firmware/application/main.cpp | 5 + firmware/application/portapack.cpp | 12 +- firmware/application/portapack.hpp | 1 - firmware/application/radio.cpp | 8 +- firmware/application/rf_path.cpp | 21 +- firmware/application/rf_path.hpp | 6 +- .../boards/PORTAPACK_APPLICATION/board.cpp | 961 ++++++++---------- .../boards/PORTAPACK_APPLICATION/board.h | 6 +- .../PORTAPACK_APPLICATION/fpga_bridge.c | 34 - .../os/hal/platforms/LPC43xx/pal_lld.c | 34 +- .../os/hal/platforms/LPC43xx/pal_lld.h | 82 +- firmware/common/gpio.cpp | 184 ++++ firmware/common/gpio.hpp | 108 ++ firmware/common/hackrf_gpio.hpp | 17 +- firmware/common/led.hpp | 6 +- firmware/common/pins.hpp | 12 +- 25 files changed, 961 insertions(+), 706 deletions(-) create mode 100644 firmware/common/gpio.cpp diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index 85466ef63..b356bb624 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -192,6 +192,7 @@ set(CPPSRC ${COMMON}/battery.cpp ${COMMON}/performance_counter.cpp ${COMMON}/bmpfile.cpp + ${COMMON}/gpio.cpp app_settings.cpp audio.cpp baseband_api.cpp diff --git a/firmware/application/clock_manager.cpp b/firmware/application/clock_manager.cpp index 74396c9bc..3564b2c8e 100644 --- a/firmware/application/clock_manager.cpp +++ b/firmware/application/clock_manager.cpp @@ -31,6 +31,11 @@ using namespace hackrf::one; #include "lpc43xx_cpp.hpp" using namespace lpc43xx; +#ifdef PRALINE +#include "hackrf_gpio.hpp" +#include "gpio.hpp" +#endif + #ifdef PRALINE extern "C" { #include "fpga_bridge.h" @@ -429,32 +434,10 @@ static void portapack_tcxo_disable() { using namespace hackrf::one; void ClockManager::init_clock_generator() { -#ifdef PRALINE - /* Route the PRALINE P22 10MHz reference to the Si5351 CLKIN pin. */ - LPC_SCU->SFSP[2][10] = 0xF0; - LPC_SCU->SFSP[6][8] = 0xF4; - LPC_SCU->SFSP[6][9] = 0xF0; - LPC_SCU->SFSP[1][20] = 0xF0; - - gpio_p1_ctrl0.output(); - gpio_p1_ctrl1.output(); - gpio_p1_ctrl2.output(); - gpio_clkin_ctrl.output(); - - gpio_p1_ctrl0.write(0); - gpio_p1_ctrl1.write(0); - gpio_p1_ctrl2.write(1); - gpio_clkin_ctrl.write(1); - - chThdSleepMilliseconds(20); - -#else - // HackRF One r9: GPIO0_8 (mcu_clk_en) gates Si5351 CLK2/CLK7 to GP_CLKIN if (hackrf_r9) { gpio_r9_mcu_clk_en.output(); gpio_r9_mcu_clk_en.write(1); } -#endif clock_generator.reset(); clock_generator.set_crystal_internal_load_capacitance(CrystalInternalLoadCapacitance::XTAL_CL_8pF); @@ -1224,3 +1207,74 @@ void ClockManager::enable_clock_output(bool enable) { } #endif } + +#ifdef PRALINE + +void ClockManager::set_p1_control(P1_Function func) { + // Truth table based on P1_Control.csv (L=clear, H=set) + switch (func) { + case P1_Function::TriggerIn: + gpio_control::p1_ctrl2.clear(); + gpio_control::p1_ctrl1.clear(); + gpio_control::p1_ctrl0.clear(); + break; + case P1_Function::AuxClk1: + gpio_control::p1_ctrl2.clear(); + gpio_control::p1_ctrl1.clear(); + gpio_control::p1_ctrl0.set(); + break; + case P1_Function::ClkIn: + gpio_control::p1_ctrl2.clear(); + gpio_control::p1_ctrl1.set(); + gpio_control::p1_ctrl0.clear(); + break; + case P1_Function::TriggerOut: + gpio_control::p1_ctrl2.clear(); + gpio_control::p1_ctrl1.set(); + gpio_control::p1_ctrl0.set(); + break; + case P1_Function::P22_ClkIn: + gpio_control::p1_ctrl2.set(); + gpio_control::p1_ctrl1.clear(); + gpio_control::p1_ctrl0.clear(); + break; + case P1_Function::P2_5: + gpio_control::p1_ctrl2.set(); + gpio_control::p1_ctrl1.clear(); + gpio_control::p1_ctrl0.set(); + break; + case P1_Function::NotConnected: + gpio_control::p1_ctrl2.set(); + gpio_control::p1_ctrl1.set(); + gpio_control::p1_ctrl0.clear(); + break; + case P1_Function::AuxClk2: + gpio_control::p1_ctrl2.set(); + gpio_control::p1_ctrl1.set(); + gpio_control::p1_ctrl0.set(); + break; + } +} + +void ClockManager::set_p2_control(P2_Function func) { + // Ensure all P2 control pins are configured as outputs + + // Truth table based on P2_Control.csv (L=clear, H=set) + switch (func) { + case P2_Function::Clk3: + // CTRL0 is 'X' (don't care) according to CSV, we default it to Low (clear) + gpio_control::p2_ctrl1.clear(); + gpio_control::p2_ctrl0.clear(); + break; + case P2_Function::TriggerIn: + gpio_control::p2_ctrl1.set(); + gpio_control::p2_ctrl0.clear(); + break; + case P2_Function::TriggerOut: + gpio_control::p2_ctrl1.set(); + gpio_control::p2_ctrl0.set(); + break; + } +} + +#endif \ No newline at end of file diff --git a/firmware/application/clock_manager.hpp b/firmware/application/clock_manager.hpp index 6d5f7ba05..e83ba510e 100644 --- a/firmware/application/clock_manager.hpp +++ b/firmware/application/clock_manager.hpp @@ -77,6 +77,29 @@ class ClockManager { void set_reference_ppb(const int32_t ppb); #ifdef PRALINE + + enum class P1_Function { + TriggerIn, // CTRL2: L, CTRL1: L, CTRL0: L + AuxClk1, // CTRL2: L, CTRL1: L, CTRL0: H + ClkIn, // CTRL2: L, CTRL1: H, CTRL0: L + TriggerOut, // CTRL2: L, CTRL1: H, CTRL0: H + P22_ClkIn, // CTRL2: H, CTRL1: L, CTRL0: L + P2_5, // CTRL2: H, CTRL1: L, CTRL0: H + NotConnected, // CTRL2: H, CTRL1: H, CTRL0: L (NC) + AuxClk2 // CTRL2: H, CTRL1: H, CTRL0: H + }; + + // Multiplexer 2 (P2) Functions - Based on P2_Control.csv + enum class P2_Function { + Clk3, // CTRL1: L, CTRL0: X (Don't care) + TriggerIn, // CTRL1: H, CTRL0: L + TriggerOut // CTRL1: H, CTRL0: H + }; + + // Function declarations + void set_p1_control(P1_Function func); + void set_p2_control(P2_Function func); + uint8_t get_resampling_n() const { return _resampling_n; } // Si5351 diagnostic methods diff --git a/firmware/application/event_m0.cpp b/firmware/application/event_m0.cpp index 088fc58cc..fa015546f 100644 --- a/firmware/application/event_m0.cpp +++ b/firmware/application/event_m0.cpp @@ -56,6 +56,8 @@ using namespace hackrf::one; #include "ui_navigation.hpp" +#include "gpio.hpp" + static int delayed_error = 0; extern "C" { @@ -185,10 +187,11 @@ void EventDispatcher::charge_deep_sleep(const bool sleep) { SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk; + power_control::vaa_power_off(); + power_control::core_power_off(); + #ifdef PRALINE // Power management and GPIO configuration for Praline hardware - gpio_vaa_disable.set(); - gpio_1v2_enable.clear(); LPC_GPIO->DIR[0] &= ~0xFFFF4000; LPC_GPIO->DIR[1] &= ~0xFFFF1000; LPC_GPIO->DIR[2] &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 11) | (1 << 10) | (1 << 6) | (1 << 0)); @@ -196,8 +199,6 @@ void EventDispatcher::charge_deep_sleep(const bool sleep) { LPC_GPIO->DIR[5] &= ~(1 << 16); #else // Power management and GPIO configuration for legacy hardware - gpio_og_vaa_disable.set(); - gpio_r9_vaa_disable.clear(); LPC_GPIO->DIR[0] &= ~0xFFFF4000; LPC_GPIO->DIR[1] &= ~0xFFFF1000; LPC_GPIO->DIR[2] &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 11) | (1 << 10) | (1 << 6) | (1 << 0)); diff --git a/firmware/application/hw/max2831.cpp b/firmware/application/hw/max2831.cpp index 2d7259841..2927813b0 100644 --- a/firmware/application/hw/max2831.cpp +++ b/firmware/application/hw/max2831.cpp @@ -103,12 +103,6 @@ void MAX2831::flush_dirty() { void MAX2831::init() { set_mode(Mode::Shutdown); - /* Configure GPIO pins for MAX2831 control */ - gpio_max283x_enable.output(); - gpio_max2831_rx_enable.output(); - gpio_max2831_rxhp.output(); - gpio_max2831_rxhp.write(0); /* RXHP low = 100 Hz HPF (default) */ - /* Reset to default register values */ std::memcpy(_regs.data(), default_regs.data(), sizeof(_regs)); _regs_dirty = 0xFFFF; @@ -348,6 +342,16 @@ void MAX2831::set_lpf_rf_bandwidth_rx(const uint32_t bandwidth_minimum) { #ifdef PRALINE uint32_t actual_bw = bandwidth_minimum; + /* The MAX2831 internal analog low-pass filter cannot go below 1.75 MHz. + * For narrow-band signals (bandwidth < 1.75 MHz), we enable the custom + * external Anti-Aliasing (AA) filter on pin P1_14 to prevent aliasing. + */ + if (actual_bw <= 1750000) { + gpio_control::aa_en.set(); // Enable external narrow AA filter + } else { + gpio_control::aa_en.clear(); // Disable external AA filter for wideband operations + } + _desired_lpf_bw = actual_bw; if (_mode == Mode::Receive || _mode == Mode::Rx_Calibration) { set_lpf_bandwidth_internal(actual_bw); @@ -361,6 +365,9 @@ void MAX2831::set_lpf_rf_bandwidth_rx(const uint32_t bandwidth_minimum) { void MAX2831::set_lpf_rf_bandwidth_tx(const uint32_t bandwidth_minimum) { _desired_lpf_bw = bandwidth_minimum; +#ifdef PRALINE + gpio_control::aa_en.clear(); // Disable external AA filter for wideband operations +#endif if (_mode == Mode::Transmit || _mode == Mode::Tx_Calibration) { set_lpf_bandwidth_internal(bandwidth_minimum); } diff --git a/firmware/application/hw/max2837.cpp b/firmware/application/hw/max2837.cpp index f937a120f..4a59eeceb 100644 --- a/firmware/application/hw/max2837.cpp +++ b/firmware/application/hw/max2837.cpp @@ -99,9 +99,11 @@ constexpr uint32_t pll_factor = 1.0 / (4.0 / 3.0 / reference_frequency) + 0.5; void MAX2837::init() { set_mode(Mode::Shutdown); +#ifndef PRALINE gpio_max283x_enable.output(); gpio_max2837_rxenable.output(); gpio_max2837_txenable.output(); +#endif _map.r.tx_gain.TXVGA_GAIN_SPI_EN = 1; _map.r.tx_gain.TXVGA_GAIN_MSB_SPI_EN = 1; @@ -157,9 +159,11 @@ void MAX2837::set_tx_LO_iq_phase_calibration(const size_t v) { // TX calibration , Logic pins , ENABLE, RXENABLE, TXENABLE = 1,0,1 (5dec), and Reg address 16, D1 (CAL mode 1):DO (CHIP ENABLE 1) set_mode(Mode::Tx_Calibration); // write to ram 3 LOGIC Pins . +#ifndef PRALINE gpio_max283x_enable.output(); gpio_max2837_rxenable.output(); gpio_max2837_txenable.output(); +#endif _map.r.spi_en.CAL_SPI = 1; // Register Settings reg address 16, D1 (CAL mode 1) _map.r.spi_en.EN_SPI = 1; // Register Settings reg address 16, DO (CHIP ENABLE 1) @@ -348,9 +352,11 @@ void MAX2837::set_rx_LO_iq_phase_calibration(const size_t v) { // RX calibration , Logic pins , ENABLE, RXENABLE, TXENABLE = 1,1,0 (3dec), and Reg address 16, D1 (CAL mode 1):DO (CHIP ENABLE 1) set_mode(Mode::Rx_Calibration); // write to ram 3 LOGIC Pins . +#ifndef PRALINE gpio_max283x_enable.output(); gpio_max2837_rxenable.output(); gpio_max2837_txenable.output(); +#endif _map.r.spi_en.CAL_SPI = 1; // Register Settings reg address 16, D1 (CAL mode 1) _map.r.spi_en.EN_SPI = 1; // Register Settings reg address 16, DO (CHIP ENABLE 1) diff --git a/firmware/application/hw/max2839.cpp b/firmware/application/hw/max2839.cpp index 11d5819eb..982dc148e 100644 --- a/firmware/application/hw/max2839.cpp +++ b/firmware/application/hw/max2839.cpp @@ -100,8 +100,10 @@ static int_fast8_t requested_rx_vga_gain = 0; void MAX2839::init() { set_mode(Mode::Shutdown); +#ifndef PRALINE gpio_max283x_enable.output(); gpio_max2839_rxtx.output(); +#endif _map.r.rxrf_1.MIMOmode = 1; /* enable RXINB */ @@ -150,8 +152,10 @@ void MAX2839::set_tx_LO_iq_phase_calibration(const size_t v) { // TX calibration , 2 x Logic pins , ENABLE, RXENABLE = 1,0, (2dec), and Reg address 16, D1 (CAL mode 1):DO (CHIP ENABLE 1) set_mode(Mode::Tx_Calibration); // write to ram 3 LOGIC Pins . +#ifndef PRALINE gpio_max283x_enable.output(); // max2839 has only 2 x pins + regs to decide mode. gpio_max2839_rxtx.output(); // Here is combined rx & tx pin in one port. +#endif _map.r.spi_en.CAL_SPI = 1; // Register Settings reg address 16, D1 (CAL mode 1) _map.r.spi_en.EN_SPI = 1; // Register Settings reg address 16, DO (CHIP ENABLE 1) @@ -390,8 +394,10 @@ void MAX2839::set_rx_LO_iq_phase_calibration(const size_t v) { // RX calibration , Logic pins , ENABLE, RXENABLE, TXENABLE = 1,1,0 (3dec), and Reg address 16, D1 (CAL mode 1):DO (CHIP ENABLE 1) set_mode(Mode::Rx_Calibration); // write to ram 3 LOGIC Pins . +#ifndef PRALINE gpio_max283x_enable.output(); // max2839 has only 2 x pins + regs to decide mode. gpio_max2839_rxtx.output(); // Here is combined rx & tx pin in one port. +#endif _map.r.spi_en.CAL_SPI = 1; // Register Settings reg address 16, D1 (CAL mode 1) _map.r.spi_en.EN_SPI = 1; // Register Settings reg address 16, DO (CHIP ENABLE 1) diff --git a/firmware/application/hw/rffc507x.cpp b/firmware/application/hw/rffc507x.cpp index a7793c398..849d5e3c7 100644 --- a/firmware/application/hw/rffc507x.cpp +++ b/firmware/application/hw/rffc507x.cpp @@ -175,8 +175,14 @@ struct SynthConfig { */ void RFFC507x::init() { +#ifdef PRALINE + gpio_control::rf5072_mix_en.set(); // RF5072_MIX_EN +#endif + gpio_rffc5072_resetx.set(); +#ifndef PRALINE gpio_rffc5072_resetx.output(); +#endif reset(); _bus.init(); diff --git a/firmware/application/hw/rffc507x_spi.cpp b/firmware/application/hw/rffc507x_spi.cpp index 7ea29d4da..f69470d0a 100644 --- a/firmware/application/hw/rffc507x_spi.cpp +++ b/firmware/application/hw/rffc507x_spi.cpp @@ -33,8 +33,10 @@ void SPI::init() { gpio_rffc5072_select.set(); gpio_rffc5072_clock.clear(); +#ifndef PRALINE gpio_rffc5072_select.output(); gpio_rffc5072_clock.output(); +#endif gpio_rffc5072_data.input(); gpio_rffc5072_data.clear(); diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 7b4873095..fe85d3b28 100644 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -144,6 +144,9 @@ Continuous (Fox-oring) #include "lpc43xx.inc" #include "rffc507x.hpp" /* c/m, avoiding initial short ON Ant_DC_Bias pulse, from cold reset */ + +#include "gpio.hpp" + rffc507x::RFFC507x first_if; ui::SystemView* system_view_ptr; @@ -185,6 +188,8 @@ static void event_loop() { int main(void) { rtc_reset_default(); + power_control::vaa_power_on(); + #ifndef PRALINE // Do not perform quick set up of GP01_RFF507X = 1 for PRALINE first_if.init(); /* To avoid initial short Ant_DC_Bias pulse ,we need quick set up GP01_RFF507X =1 */ #endif diff --git a/firmware/application/portapack.cpp b/firmware/application/portapack.cpp index e6ca2e2f7..5715eb2db 100644 --- a/firmware/application/portapack.cpp +++ b/firmware/application/portapack.cpp @@ -56,11 +56,14 @@ using asahi_kasei::ak4951::AK4951; #include "i2cdevmanager.hpp" #include "battery.hpp" +#include "gpio.hpp" + extern "C" { #include "platform_detect.h" #ifdef PRALINE #include "fpga_bridge.h" +#include "board.h" #endif } @@ -561,12 +564,6 @@ 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); @@ -594,9 +591,12 @@ init_status_t init() { } /* Cache some configuration data from persistent memory. */ + rtc_time::dst_init(); chThdSleepMilliseconds(10); + power_control::core_power_on(); + clock_manager.init_clock_generator(); i2c0.stop(); diff --git a/firmware/application/portapack.hpp b/firmware/application/portapack.hpp index 224464f81..775ab8434 100644 --- a/firmware/application/portapack.hpp +++ b/firmware/application/portapack.hpp @@ -67,7 +67,6 @@ extern ReceiverModel receiver_model; extern TransmitterModel transmitter_model; extern uint32_t bl_tick_counter; -extern bool antenna_bias; extern uint16_t touch_threshold; extern TemperatureLogger temperature_logger; diff --git a/firmware/application/radio.cpp b/firmware/application/radio.cpp index 0354e445f..463761410 100644 --- a/firmware/application/radio.cpp +++ b/firmware/application/radio.cpp @@ -391,12 +391,8 @@ void set_baseband_rate(const uint32_t rate) { void set_antenna_bias(const bool on) { #ifdef PRALINE - /* Keep bias control inside the PRALINE RF path state machine so later - * band/direction/amp updates don't silently force ANT_BIAS_EN_N off. - * Reassert output mode here because this pin is safety-critical and - * direct GPIO writes on an input-configured pad have no effect. */ - gpio_ant_bias_disable.output(); - rf_path.set_antenna_bias(on); + /* Praline: P2_12 = GPIO1[12], ANT_BIAS_EN_N (active LOW) */ + rf_path.set_ant_bias(on); #else if (hackrf_r9) { gpio_r9_not_ant_pwr.write(on ? 0 : 1); diff --git a/firmware/application/rf_path.cpp b/firmware/application/rf_path.cpp index 103fc8b92..c9e8dbda3 100644 --- a/firmware/application/rf_path.cpp +++ b/firmware/application/rf_path.cpp @@ -46,14 +46,6 @@ struct PralineConfig { bool rf_amp_en; bool ant_bias_en_n; // Inverted: 0 = bias enabled - static void gpio_init() { - gpio_tx_enable.output(); - gpio_mix_bypass.output(); - gpio_lpf_enable.output(); - gpio_rf_amp_enable.output(); - gpio_ant_bias_disable.output(); - } - void apply() const { gpio_tx_enable.write(tx_en); gpio_mix_bypass.write(mix_bypass); // Control RF path mixer @@ -231,7 +223,6 @@ constexpr Config get_config( void Path::init() { #ifdef PRALINE - PralineConfig::gpio_init(); /* Set safe initial state: RX mode, mixer enabled, LPF on, amp off, no bias */ PralineConfig config = { .tx_en = false, @@ -263,11 +254,15 @@ void Path::set_rf_amp(const bool new_rf_amp) { update(); } -void Path::set_antenna_bias(const bool new_antenna_bias) { - antenna_bias = new_antenna_bias; +void Path::set_ant_bias(const bool new_ant_bias) { + ant_bias = new_ant_bias; update(); } +bool Path::get_ant_bias() const { + return ant_bias; +} + void Path::update() { /* 0 ^ 0 => 0 & 0 = 0 ^ 0 = 0 (no change) * 0 ^ 1 => 1 & 0 = 0 ^ 0 = 0 (ignore change to 1) @@ -306,8 +301,8 @@ void Path::update() { /* RF amp when amplification requested */ config.rf_amp_en = rf_amp; - /* Preserve requested antenna bias state across band/direction/amp updates. */ - config.ant_bias_en_n = !antenna_bias; + /* Antenna bias */ + config.ant_bias_en_n = !ant_bias; config.apply(); diff --git a/firmware/application/rf_path.hpp b/firmware/application/rf_path.hpp index 150bfe59f..bc1b44038 100644 --- a/firmware/application/rf_path.hpp +++ b/firmware/application/rf_path.hpp @@ -65,15 +65,15 @@ class Path { void set_direction(const Direction direction); void set_band(const Band band); void set_rf_amp(const bool rf_amp); - void set_antenna_bias(const bool antenna_bias); - + void set_ant_bias(const bool ant_bias); + bool get_ant_bias() const; Band get_band() const { return _band; } //_band is used solely for debugging purposes. private: Direction direction{Direction::Receive}; Band band{Band::Mid}; bool rf_amp{false}; - bool antenna_bias{false}; + bool ant_bias{false}; void update(); diff --git a/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp b/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp index e7c679407..9904f4564 100755 --- a/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp +++ b/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp @@ -20,9 +20,10 @@ #include +#include "gpio.hpp" + // Declare wrapper function. board.cpp to avoid conflicting gpio_t definitions. bool hackrf_r9; - #if HAL_USE_PAL || defined(__DOXYGEN__) /** * @brief PAL setup. @@ -55,36 +56,44 @@ const PALConfig pal_default_config = { // GPIO0 .data #ifdef PRALINE - = (0 << 15) // P1_20: CLKIN_CTRL - start low + = (0 << 7) // P2_7: Input GND + | (0 << 8) // P1_1: Input GND + | (1 << 9) // P1_2: Input VCC + | boot_bit(gpio_control::p1_ctrl0, 0) // P2_10: P1_CTRL0, start low + | (0 << 15) // P1_20: CLKIN_CTRL - start low #else - = (1 << 15) // P1_20: CS_XCVR + = (1 << 14) // P2_10: AMP_BYPASS + | (1 << 15) // P1_20: CS_XCVR #endif - | (1 << 14) // P2_10: AMP_BYPASS - | (0 << 13) // P1_18: SGPIO12, HOST_Q_INVERT - | (0 << 12) // P1_17: SGPIO11, HOST_DIRECTION | (1 << 11) // P1_4: SSP1_MOSI + | (0 << 13) // P1_18: SGPIO12, HOST_Q_INVERT + | (0 << 12) // P1_17: SGPIO11, HOST_DIRECTION, Praline: FPGA HOST_DIRECTION | (1 << 10) // P1_3: SSP1_MISO | (0 << 9) // P1_2: Varies by revision, float until detection | (0 << 8) // P1_1: Varies by revision, float until detection | (0 << 7) // P2_7: Varies by revision, float until detection | (0 << 6) // P3_6: SPIFI_MISO - | (1 << 5) // P6_6: SGPIO5, HOST_DATA5 - | (1 << 4) // P1_0: SGPIO7, HOST_DATA7 - | (1 << 3) // P1_16: SGPIO3, HOST_DATA3 - | (1 << 2) // P1_15: SGPIO2, HOST_DATA2 - | (1 << 1) // P0_1: SGPIO1, HOST_DATA1 - | (1 << 0) // P0_0: SGPIO0, HOST_DATA0 + | (1 << 5) // P6_6: SGPIO5, HOST_DATA5, Praline: FPGA HOST_DATA5 + | (1 << 4) // P1_0: SGPIO7, HOST_DATA7, Praline: FPGA HOST_DATA7 + | (1 << 3) // P1_16: SGPIO3, HOST_DATA3, Praline: FPGA HOST_DATA3 + | (1 << 2) // P1_15: SGPIO2, HOST_DATA2, Praline: FPGA HOST_DATA2 + | (1 << 1) // P0_1: SGPIO1, HOST_DATA1, Praline: FPGA HOST_DATA1 + | (1 << 0) // P0_0: SGPIO0, HOST_DATA0, Praline: FPGA HOST_DATA0 , .dir #ifdef PRALINE - = (1 << 15) // P1_20: CLKIN_CTRL - output + = (0 << 7) // P2_7: Input + | (0 << 8) // P1_1: Input + | (0 << 9) // P1_2: Input + | boot_bit(gpio_control::p1_ctrl0, 1) // P2_10: P1_CTRL0 + | (1 << 15) // P1_20: CLKIN_CTRL #else - = (1 << 15) // P1_20: CS_XCVR + = (1 << 14) // P2_10: AMP_BYPASS + | (1 << 15) // P1_20: CS_XCVR #endif - | (1 << 14) // P2_10: AMP_BYPASS + | (0 << 11) // P1_4: SSP1_MOSI | (1 << 13) // P1_18: SGPIO12, HOST_Q_INVERT | (0 << 12) // P1_17: SGPIO11, HOST_DIRECTION - | (0 << 11) // P1_4: SSP1_MOSI | (0 << 10) // P1_3: SSP1_MISO | (0 << 9) // P1_2: Varies by revision, float until detection | (0 << 8) // P1_1: Varies by revision, float until detection @@ -102,84 +111,114 @@ const PALConfig pal_default_config = { .data = (1 << 15) // P3_5: SPIFI_SIO2 | (1 << 14) // P3_4: SPIFI_SIO3 | (1 << 13) // P2_13: PortaPack DIR +#ifdef PRALINE + | (1 << 12) // P2_12: BIAS_EN + | (0 << 11) // P2_11: BIAS_OC + | boot_bit(gpio_control::aa_en, 0) // P1_14: AA_EN + | (0 << 0) // P1_7: Output GND +#else | (1 << 12) // P2_12: !RX_AMP_PWR | (0 << 11) // P2_11: RX_AMP + | (1 << 7) // P1_14: SGPIO10, HOST_DISABLE + | (0 << 0) // P1_7: !MIX_BYPASS +#endif | (0 << 10) // P2_9: 10K PD, BOOT3, PortaPack LCD_WRX | (1 << 9) // P1_6: SD_CMD - | (1 << 8) // P1_5: SD_POW, PortaPack CPLD.TDO(O) (input with pull up) - | (1 << 7) // P1_14: SGPIO10, HOST_DISABLE + | (1 << 8) // P1_5: SD_POW, PortaPack CPLD.TDO(O) | (1 << 6) // P1_13: SD_CD | (1 << 5) // P1_12: SD_DAT3 | (1 << 4) // P1_11: SD_DAT2 | (1 << 3) // P1_10: SD_DAT1 | (1 << 2) // P1_9: SD_DAT0 | (1 << 1) // P1_8: PortaPack CPLD.TMS(I) - | (0 << 0) // P1_7: !MIX_BYPASS , .dir = (0 << 15) // P3_5: SPIFI_SIO2 | (0 << 14) // P3_4: SPIFI_SIO3 - | (0 << 13) // P2_13: PortaPack DIR + | (1 << 13) // P2_13: PortaPack DIR +#ifdef PRALINE + | (1 << 12) // P2_12: !BIAS_EN + | (0 << 11) // P2_11: BIAS_OC + | boot_bit(gpio_control::aa_en, 1) // P1_14: AA_EN + | (1 << 0) // P1_7: Output +#else | (1 << 12) // P2_12: !RX_AMP_PWR | (1 << 11) // P2_11: RX_AMP - | (0 << 10) // P2_9: 10K PD, BOOT3, PortaPack LCD_WRX - | (0 << 9) // P1_6: SD_CMD - | (0 << 8) // P1_5: SD_POW, PortaPack CPLD.TDO(O) (input with pull up) | (0 << 7) // P1_14: SGPIO10, HOST_DISABLE + | (1 << 0) // P1_7: !MIX_BYPASS +#endif + | (1 << 10) // P2_9: 10K PD, BOOT3, PortaPack LCD_WRX + | (0 << 9) // P1_6: SD_CMD + | (0 << 8) // P1_5: SD_POW, PortaPack CPLD.TDO(O) | (0 << 6) // P1_13: SD_CD | (0 << 5) // P1_12: SD_DAT3 | (0 << 4) // P1_11: SD_DAT2 | (0 << 3) // P1_10: SD_DAT1 | (0 << 2) // P1_9: SD_DAT0 - | (0 << 1) // P1_8: PortaPack CPLD.TMS(I) (output only when needed, pull up internal to CPLD) - | (1 << 0) // P1_7: !MIX_BYPASS + | (0 << 1) // P1_8: PortaPack CPLD.TMS(I) }, { // GPIO2 - .data = (0 << 15) // P5_6: TX_AMP + .data = (0 << 15) // P5_6: TX_AMP, unused on PRALINE | (1 << 14) // P5_5: MIXER_RESETX, 10K PU #ifdef PRALINE - | (0 << 13) // P5_4: MIXER_ENX, 10K PU + | (1 << 13) // P5_4: RFFC5072 ENX + | (0 << 12) // P5_3: unused on PRALINE + | (0 << 11) // P5_2: FPGA_CRESET + | (1 << 10) // P5_1: FPGA_SPI_CS + | (0 << 4) // P4_4: unused on PRALINE + | (0 << 0) // P4_0: unused on PRALINE + | (0 << 9) // P5_0: unused on PRALINE + | (0 << 3) // P4_3: VBUSCTRL input GND + | (1 << 6) // P4_6: Input VCC (10K PU) + | (1 << 8) // P6_12: LED3 (TX) + | (1 << 2) // P4_2: LED2 (RX) + | (1 << 1) // P4_1: LED1 (USB) #else | (1 << 13) // P5_4: MIXER_ENX, 10K PU -#endif | (1 << 12) // P5_3: RX_MIX_BP | (0 << 11) // P5_2: TX_MIX_BP | (0 << 10) // P5_1: LP - | (0 << 9) // P5_0: Varies by revision, float until detection - | (0 << 8) // P6_12: LED3 (TX) - | (1 << 7) // P5_7: CS_AD - | (0 << 6) // P4_6: XCVR_EN, 10K PD - | (0 << 5) // P4_5: RXENABLE - | (0 << 4) // P4_4: Varies by revision, float until detection + | (0 << 4) // P4_4: Varies by revision + | (0 << 9) // P5_0: Varies by revision + | (1 << 0) // P4_0: HP | (1 << 3) // P4_3: SGPIO9, HOST_CAPTURE + | (0 << 6) // P4_6: XCVR_EN, 10K PD + | (0 << 8) // P6_12: LED3 (TX) | (0 << 2) // P4_2: LED2 (RX) | (0 << 1) // P4_1: LED1 (USB) - | (1 << 0) // P4_0: HP +#endif + + | (1 << 7) // P5_7: CS_AD + | (0 << 5) // P4_5: RXENABLE , - .dir = (1 << 15) // P5_6: TX_AMP + .dir = (1 << 15) // P5_6: TX_AMP, unused on PRALINE #ifdef PRALINE - | (0 << 14) // P5_5: MIXER_RESETX, 10K PU - | (1 << 13) // P5_4: MIXER_ENX - OUTPUT (MCU controlled) - | (0 << 12) // P5_3: RX_MIX_BP - unused on PRALINE - | (0 << 11) // P5_2: FPGA_CRESET - INPUT initially - | (0 << 10) // P5_1: FPGA_SPI_CS - INPUT initially + | (1 << 13) // P5_4: RFFC5072 ENX + | (1 << 12) // P5_3: unused on PRALINE + | (1 << 11) // P5_2: FPGA_CRESET + | (1 << 10) // P5_1: FPGA_SPI_CS + | (1 << 4) // P4_4: unused on PRALINE + | (1 << 9) // P5_0: unused on PRALINE + | (1 << 0) // P4_0: unused on PRALINE + | (0 << 3) // P4_3: VBUSCTRL input + | (0 << 6) // P4_6: Input #else - | (1 << 14) // P5_5: MIXER_RESETX, 10K PU | (1 << 13) // P5_4: MIXER_ENX, 10K PU | (1 << 12) // P5_3: RX_MIX_BP | (1 << 11) // P5_2: TX_MIX_BP | (1 << 10) // P5_1: LP + | (0 << 4) // P4_4: Varies by revision + | (0 << 9) // P5_0: Varies by revision + | (1 << 0) // P4_0: HP + | (0 << 3) // P4_3: SGPIO9, HOST_CAPTURE + | (1 << 6) // P4_6: XCVR_EN, 10K PD #endif - | (0 << 9) // P5_0: Varies by revision, float until detection - | (1 << 8) // P6_12: LED3 (TX) - | (1 << 7) // P5_7: CS_AD - | (1 << 6) // P4_6: XCVR_EN, 10K PD - | (1 << 5) // P4_5: RXENABLE - | (0 << 4) // P4_4: Varies by revision, float until detection - | (0 << 3) // P4_3: SGPIO9, HOST_CAPTURE - | (1 << 2) // P4_2: LED2 (RX) - | (1 << 1) // P4_1: LED1 (USB) - | (1 << 0) // P4_0: HP + | (1 << 14) // P5_5: MIXER_RESETX, 10K PU + | (1 << 8) // P6_12: LED3 (TX) + | (1 << 7) // P5_7: CS_AD + | (1 << 5) // P4_5: RXENABLE + | (1 << 2) // P4_2: LED2 (RX) + | (1 << 1) // P4_1: LED1 (USB) }, { // GPIO3 @@ -191,98 +230,233 @@ const PALConfig pal_default_config = { | (1 << 10) // P7_2: PortaPack GPIO3_10(IO) | (1 << 9) // P7_1: PortaPack GPIO3_9(IO) | (1 << 8) // P7_0: PortaPack GPIO3_8(IO) - | (1 << 7) // P6_11: VREGMODE - | (0 << 6) // P6_10: Varies by revision, float until detection - | (1 << 5) // P6_9: !TX_AMP_PWR, 10K PU - | (1 << 4) // P6_5: HackRF CPLD.TMS(I) (output only when needed, pull-up internal to CPLD when 1V8 present) - | (1 << 3) // P6_4: MIXER_SDATA - | (1 << 2) // P6_3: SGPIO4, HOST_DATA4 - | (1 << 1) // P6_2: HackRF CPLD.TDI(I), PortaPack I2S0_RX_SDA(O), PortaPack CPLD.TDI(I) (output only when needed, pull-up internal to CPLD when 1V8 present) - | (1 << 0) // P6_1: HackRF CPLD.TCK(I), PortaPack CPLD.TCK(I) (output only when needed, pull-up internal to CPLD when 1V8 present) +#ifdef PRALINE + | (0 << 4) // P6_5: TX_ENABLE + | (1 << 2) // P6_3: MIX_ENABLE_N + | (0 << 6) // P6_10: unused on PRALINE + | boot_bit(gpio_control::p1_ctrl2, 0) // P6_9: P1_CTRL2 +#else + | (1 << 4) // P6_5: HackRF CPLD.TMS(I) + | (1 << 7) // P6_11: VREGMODE + | (0 << 6) // P6_10: Varies by revision + | (1 << 2) // P6_3: SGPIO4, HOST_DATA4 + | (1 << 5) // P6_9: !TX_AMP_PWR, 10K PU +#endif + | (1 << 3) // P6_4: MIXER_SDATA + | (1 << 1) // P6_2: HackRF CPLD.TDI(I) + | (1 << 0) // P6_1: HackRF CPLD.TCK(I) , - .dir = (0 << 15) // P7_7: PortaPack GPIO3_15(IO) - | (0 << 14) // P7_6: PortaPack GPIO3_14(IO) - | (0 << 13) // P7_5: PortaPack GPIO3_13(IO) - | (0 << 12) // P7_4: PortaPack GPIO3_12(IO) - | (0 << 11) // P7_3: PortaPack GPIO3_11(IO) - | (0 << 10) // P7_2: PortaPack GPIO3_10(IO) - | (0 << 9) // P7_1: PortaPack GPIO3_9(IO) - | (0 << 8) // P7_0: PortaPack GPIO3_8(IO) - | (1 << 7) // P6_11: VREGMODE - | (0 << 6) // P6_10: Varies by revision, float until detection - | (1 << 5) // P6_9: !TX_AMP_PWR, 10K PU - | (0 << 4) // P6_5: HackRF CPLD.TMS(I) (output only when needed, pull-up internal to CPLD when 1V8 present) - | (0 << 3) // P6_4: MIXER_SDATA - | (0 << 2) // P6_3: SGPIO4, HOST_DATA4 - | (0 << 1) // P6_2: HackRF CPLD.TDI(I), PortaPack I2S0_RX_SDA(O), PortaPack CPLD.TDI(I) (output only when needed, pull-up internal to CPLD when 1V8 present) - | (0 << 0) // P6_1: HackRF CPLD.TCK(I), PortaPack CPLD.TCK(I) (output only when needed, pull-up internal to CPLD when 1V8 present) + .dir = (1 << 15) // P7_7: PortaPack GPIO3_15(IO) + | (1 << 14) // P7_6: PortaPack GPIO3_14(IO) + | (1 << 13) // P7_5: PortaPack GPIO3_13(IO) + | (1 << 12) // P7_4: PortaPack GPIO3_12(IO) + | (1 << 11) // P7_3: PortaPack GPIO3_11(IO) + | (1 << 10) // P7_2: PortaPack GPIO3_10(IO) + | (1 << 9) // P7_1: PortaPack GPIO3_9(IO) + | (1 << 8) // P7_0: PortaPack GPIO3_8(IO) +#ifdef PRALINE + | (0 << 7) // P6_11: 3V3AUX_OC + | (1 << 4) // P6_5: TX_ENABLE + | (1 << 2) // P6_3: MIX_ENABLE_N + | (0 << 6) // P6_10: unused on PRALINE + | boot_bit(gpio_control::p1_ctrl2, 1) // P6_9: P1_CTRL2 +#else + | (1 << 7) // P6_11: VREGMODE + | (0 << 6) // P6_10: Varies by revision + | (0 << 2) // P6_3: SGPIO4, HOST_DATA4 + | (1 << 5) // P6_9: !TX_AMP_PWR, 10K PU +#endif + | (0 << 4) // P6_5: HackRF CPLD.TMS(I) + | (0 << 3) // P6_4: MIXER_SDATA + | (0 << 1) // P6_2: HackRF CPLD.TDI(I) + | (0 << 0) // P6_1: HackRF CPLD.TCK(I) }, { // GPIO4 - .data = (1 << 11) // P9_6: SGPIO8, SGPIO_CLK + .data = +#ifdef PRALINE + (0 << 9) // PA_2: RF_AMP_EN + | (0 << 8) // PA_1: LPF_EN + | (0 << 7) // P8_7: 1V2_EN + | (1 << 6) // P8_6: LED4 + | (0 << 5) // P8_5: VIN_IN_EN + | (0 << 4) // P8_4: VBUS_IN_EN + | (1 << 1) // P8_1: VAA_EN + | (0 << 10) // PA_3: Output GND + | (0 << 11) // P9_6: MAX2831 LD + | boot_bit(gpio_control::rf5072_mix_en, 0) // P9_0: RF5072 enable + | (0 << 13) // P9_1: Output GND + | (0 << 14) // P9_2: RFFC5072 SDATA + | (0 << 3) // P8_3: Output GND +#else + (1 << 11) // P9_6: SGPIO8, SGPIO_CLK, HackRF MAX2831 LD +#endif , - .dir = (0 << 11) // P9_6: SGPIO8, SGPIO_CLK + .dir = +#ifdef PRALINE + (1 << 9) // PA_2: RF_AMP_EN + | (1 << 8) // PA_1: LPF_EN + | (1 << 7) // P8_7: 1V2_EN + | (1 << 6) // P8_6: LED4 + | (1 << 5) // P8_5: VIN_IN_EN + | (1 << 4) // P8_4: VBUS_IN_EN + | (1 << 1) // P8_1: VAA_EN + | (1 << 10) // PA_3: Output + | (0 << 11) // P9_6: MAX2831 LD + | boot_bit(gpio_control::rf5072_mix_en, 1) // P9_0: RF5072 enable + | (1 << 13) // P9_1: Output + | (0 << 14) // P9_2: RFFC5072 SDATA (Bidirectional) + | (1 << 3) // P8_3: Output +#else + (1 << 11) // P9_6: SGPIO8, SGPIO_CLK, HackRF MAX2831 LD +#endif }, { // GPIO5 - .data = (1 << 18) // P9:5: HackRF CPLD.TDO(O) (input with pull up) - | (1 << 16) // P6_8: MIX_BYPASS - | (0 << 15) // P6_7: Varies by revision, float until detection - | (1 << 14) // P4_10: SGPIO15, CPLD (unused) - | (1 << 13) // P4_9: SGPIO14, CPLD (unused) - | (0 << 12) // P4_8: Varies by revision, float until detection - | (1 << 11) // P3_8: SPIFI_CS - | (1 << 10) // P3_7: SPIFI_MOSI - | (1 << 9) // P3_2: I2S0_RX_SDA - | (1 << 8) // P3_1: I2S0_RX_WS - | (0 << 7) // P2_8: BOOT2 - | (0 << 6) // P2_6: MIXER_SCLK - | (0 << 5) // P2_5: Varies by revision, float until detection - | (1 << 4) // P2_4: PortaPack LCD_RDX - | (0 << 3) // P2_3: PortaPack LCD_TE - | (1 << 2) // P2_2: SGPIO6, HOST_DATA6 - | (0 << 1) // P2_1: PortaPack ADDR - | (1 << 0) // P2_0: PortaPack IO_STBX + .data = +#ifdef PRALINE + (0 << 18) // P9_5: RFF5072 SCLK + | boot_bit(gpio_control::trigger_out, 0) // P2_6: Trigger out + | (0 << 14) // P4_10: FPGA CDONE + | (1 << 15) // P6_7: 3V3 AUX_ENABLE + | boot_bit(gpio_control::p1_ctrl1, 0) // P6_8: P1_CTRL1 + | (0 << 17) // P9_4: FPGA SGPIO + | (0 << 19) // PA_4: Output GND + | (0 << 20) // PB_0: Output GND + | (0 << 21) // PB_1: Output GND + | (0 << 22) // PB_2: Unused IN + | (0 << 23) // PB_3: Output GND + | (0 << 24) // PB_4: Unused IN + | (0 << 25) // PB_5: Output GND + | (0 << 5) // P2_5: PPS OUT/IN + | (0 << 12) // P4_8: Output GND + | (0 << 13) // P4_9: TPS62410 VREGMODE +#else + (1 << 18) // P9_5: HackRF CPLD.TDO(O) + | (0 << 6) // P2_6: MIXER_SCLK + | (1 << 14) // P4_10: SGPIO15, CPLD (unused) + | (0 << 15) // P6_7: Varies by revision + | (0 << 5) // P2_5: Varies by revision + | (1 << 16) // P6_8: MIX_BYPASS + | (1 << 13) // P4_9: SGPIO14, CPLD (unused) + | (0 << 12) // P4_8: Varies by revision +#endif + | (1 << 11) // P3_8: SPIFI_CS + | (1 << 10) // P3_7: SPIFI_MOSI + | (1 << 9) // P3_2: I2S0_RX_SDA + | (1 << 8) // P3_1: I2S0_RX_WS + | (0 << 7) // P2_8: BOOT2 + | (1 << 4) // P2_4: PortaPack LCD_RDX + | (0 << 3) // P2_3: PortaPack LCD_TE + | (1 << 2) // P2_2: SGPIO6, HOST_DATA6 + | (1 << 1) // P2_1: PortaPack ADDR + | (1 << 0) // P2_0: PortaPack IO_STBX , - .dir = (0 << 18) // P9_5: HackRF CPLD.TDO(O) (input with pull up) - | (1 << 16) // P6_8: MIX_BYPASS - | (0 << 15) // P6_7: Varies by revision, float until detection - | (0 << 14) // P4_10: SGPIO15, CPLD (unused) - | (0 << 13) // P4_9: SGPIO14, CPLD (unused) - | (0 << 12) // P4_8: Varies by revision, float until detection - | (0 << 11) // P3_8: SPIFI_CS - | (0 << 10) // P3_7: SPIFI_MOSI - | (0 << 9) // P3_2: I2S0_RX_SDA - | (0 << 8) // P3_1: I2S0_RX_WS - | (0 << 7) // P2_8: BOOT2 - | (0 << 6) // P2_6: MIXER_SCLK - | (0 << 5) // P2_5: Varies by revision, float until detection - | (0 << 4) // P2_4: PortaPack LCD_RDX - | (0 << 3) // P2_3: PortaPack LCD_TE - | (0 << 2) // P2_2: SGPIO6, HOST_DATA6 - | (0 << 1) // P2_1: PortaPack ADDR - | (0 << 0) // P2_0: PortaPack IO_STBX + .dir = +#ifdef PRALINE + (1 << 18) // P9_5: RFF5072 SCLK + | boot_bit(gpio_control::trigger_out, 1) // P2_6: Trigger out + | (0 << 14) // P4_10: FPGA CDONE + | (1 << 15) // P6_7: 3V3 AUX_ENABLE + | (1 << 16) // P6_8: P1_CTRL1 + | (0 << 17) // P9_4: FPGA SGPIO + | (1 << 19) // PA_4: Output + | (1 << 20) // PB_0: Output GND + | (1 << 21) // PB_1: Output GND + | (0 << 22) // PB_2: Unused + | (1 << 23) // PB_3: Output + | (0 << 24) // PB_4: Unused + | (1 << 25) // PB_5: Output + | (0 << 5) // P2_5: PPS (Bidirectional) + | (1 << 12) // P4_8: Output + | (1 << 13) // P4_9: TPS62410 VREGMODE +#else + (0 << 18) // P9_5: HackRF CPLD.TDO(O) + | (1 << 6) // P2_6: MIXER_SCLK + | (0 << 14) // P4_10: SGPIO15, CPLD + | (0 << 15) // P6_7: Varies by revision + | (0 << 5) // P2_5: Varies by revision + | (1 << 16) // P6_8: MIX_BYPASS + | (0 << 13) // P4_9: SGPIO14, CPLD + | (0 << 12) // P4_8: Varies by revision +#endif + | (0 << 11) // P3_8: SPIFI_CS + | (0 << 10) // P3_7: SPIFI_MOSI + | (0 << 9) // P3_2: I2S0_RX_SDA + | (0 << 8) // P3_1: I2S0_RX_WS + | (0 << 7) // P2_8: BOOT2 + | (0 << 4) // P2_4: PortaPack LCD_RDX + | (0 << 3) // P2_3: PortaPack LCD_TE + | (0 << 2) // P2_2: SGPIO6, HOST_DATA6 + | (0 << 1) // P2_1: PortaPack ADDR + | (0 << 0) // P2_0: PortaPack IO_STBX + }, + { +// GPIO6 +#ifdef PRALINE + .data = (1 << 28) // PD_14: MAX2831 chip select + | (0 << 29) // PD_15: MAX2831 RXHP control RXHP low = 100 Hz HPF + | (1 << 30) // PD_16: MAX5865 chip select + | (1 << 25) // PD_11: RFFC5072 Lock Detect + | boot_bit(gpio_control::trigger_in, 0) // PD_12: TRIGGER IN + , + .dir = (1 << 28) // PD_14: MAX2831 chip select + | (1 << 29) // PD_15: MAX2831 RXHP control + | (1 << 30) // PD_16: MAX5865 chip select + | (0 << 25) // PD_11: RFFC5072 Lock Detect + | boot_bit(gpio_control::trigger_in, 0) // PD_12: TRIGGER IN +#else + .data = 0, + .dir = 0 +#endif + }, + { +// GPIO7 +#ifdef PRALINE + .data = (0 << 0) // PE_0: Output + | (0 << 1) // PE_1: MAX2831 !SHDN + | (0 << 2) // PE_2: MAX2831 RXTX + | boot_bit(gpio_control::p2_ctrl0, 0) // PE_3: P2_ctrl0 + | boot_bit(gpio_control::p2_ctrl1, 0) // PE_4: P2_ctrl1 + , + .dir = (1 << 0) // PE_0: Output + | (1 << 1) // PE_1: MAX2831 !SHDN + | (1 << 2) // PE_2: MAX2831 RXTX + | boot_bit(gpio_control::p2_ctrl0, 1) // PE_3: P2_ctrl0 + | boot_bit(gpio_control::p2_ctrl1, 1) // PE_4: P2_ctrl1 +#else + .data = 0, + .dir = 0 +#endif }, - {// GPIO6 - .data = 0, - .dir = 0}, - {// GPIO7 - .data = 0, - .dir = 0}, }, .SCU = { - /* Configure GP_CLKIN as soon as possible. It's an output at boot time, and the Si5351C doesn't - * reset when the reset button is pressed, so it could still be output enabled. - */ - {4, 7, scu_config_normal_drive_t{.mode = 1, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, /* GP_CLKIN/P72/MCU_CLK: SI5351C.CLK7(O) */ - /* HackRF: LEDs. Configured early so we can use them to indicate boot status. */ - {4, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* LED1: LED1.A(I) */ - {4, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* LED2: LED2.A(I) */ - {6, 12, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* LED3: LED3.A(I) */ + // SClock LEDs - /* Power control */ - {6, 11, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* VREGMODE/P69: TPS62410.MODE/DATA(I) */ + {4, 7, scu_config_normal_drive_t{.mode = 1, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, // GP_CLKIN: SI5351C.CLK7(O) + {4, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, // LED1: USB + {4, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, // LED2: RX + {6, 12, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, // LED3: TX +#ifdef PRALINE + {8, 6, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, // LED4: PRALINE Custom +#endif + + // POWER MANAGEMENT (Regulators, Bias, Current Limits) + + {6, 11, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // VREGMODE: TPS62410 +#ifdef PRALINE + {8, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P8_1: VAA_EN + {8, 4, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P8_4: VBUS_IN_EN + {8, 5, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P8_5: VIN_IN_EN + {8, 7, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P8_7: 1V2_EN + {6, 7, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P6_7: 3.3V Aux Enable + {4, 9, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P4_9: TPS62410 mode + {gpio_control::map_p1_ctrl0.scu_port, gpio_control::map_p1_ctrl0.scu_pin, scu_config_normal_drive_t{.mode = 0, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P2_10: P1_CTRL0 + {gpio_control::map_p1_ctrl2.scu_port, gpio_control::map_p1_ctrl2.scu_pin, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, // P6_9: P1_CTRL2 (Output VCC, PU ON,) + {gpio_control::map_p2_ctrl0.scu_port, gpio_control::map_p2_ctrl0.scu_pin, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // PE_3: P2_CTRL0 + {gpio_control::map_p2_ctrl1.scu_port, gpio_control::map_p2_ctrl1.scu_pin, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // PE_4: P2_CTRL1 +#endif /* HackRF: I2C0 */ /* Glitch filter operates at 3ns instead of 50ns due to the WM8731 @@ -304,89 +478,120 @@ const PALConfig pal_default_config = { .sda_ezi = 1, // SDA: Input enabled .sda_zif = 0 // SDA: Enable input glitch filter }}, + // FPGA & HIGH-SPEED DATA (SGPIO, Config, Triggers) - /* Radio section control */ - {1, 3, scu_config_normal_drive_t{.mode = 5, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, /* SSP1_MISO/P41: MAX2837.DOUT(O) */ - {1, 4, scu_config_normal_drive_t{.mode = 5, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* SSP1_MOSI/P40: MAX2837.DIN(I), MAX5864.DIN(I) */ - {1, 7, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* !MIX_BYPASS/P35: U1.VCTL1(I), U11.VCTL2(I), U9.V2(I) */ - {1, 19, scu_config_normal_drive_t{.mode = 1, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* SSP1_SCK/P39: MAX2837.SCLK(I), MAX5864.SCLK(I) */ - {1, 20, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* CS_XCVR/P53: MAX2837.CS(I) */ + {0, 0, scu_config_normal_drive_t{.mode = 3, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // SGPIO0: HOST_DATA0(IO) + {0, 1, scu_config_normal_drive_t{.mode = 3, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // SGPIO1: HOST_DATA1(IO) + {1, 15, scu_config_normal_drive_t{.mode = 2, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // SGPIO2: HOST_DATA2(IO) + {1, 16, scu_config_normal_drive_t{.mode = 2, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // SGPIO3: HOST_DATA3(IO) + {6, 6, scu_config_normal_drive_t{.mode = 2, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // SGPIO5: HOST_DATA5(IO) + {2, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // SGPIO6: HOST_DATA6(IO) + {1, 0, scu_config_normal_drive_t{.mode = 6, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // SGPIO7: HOST_DATA7(IO) + {1, 18, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // SGPIO12: HOST_INVERT(I) +#ifdef PRALINE + {8, 0, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // SGPIO8: P8_0 func 4 (CLK) + {8, 2, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // SGPIO10: P8_2 func 4 (DISABLE) + {9, 3, scu_config_normal_drive_t{.mode = 6, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // SGPIO9: P9_3 func 6 (CAPTURE) + {9, 4, scu_config_normal_drive_t{.mode = 6, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // SGPIO4: P9_4 func 6 + {1, 17, scu_config_normal_drive_t{.mode = 6, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // SGPIO11: P1_17 func 6 (DIRECTION) + {6, 4, scu_config_normal_drive_t{.mode = 1, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // P6_4: SCT_CLK IN (Fast clock input, Mode 1) + {4, 10, scu_config_normal_drive_t{.mode = 7, .epd = 1, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, // P4_10: FPGA Config Done (Input GND) + {gpio_control::map_trigger_in.scu_port, gpio_control::map_trigger_in.scu_pin, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, // PD_12: TRIGGER IN (Input GND, Mode 4) + {gpio_control::map_trigger_out.scu_port, gpio_control::map_trigger_out.scu_pin, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 1, .ezi = 0, .zif = 0}}, // P2_6: TRIGGER + {2, 5, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, // P2_5: PPS OUT/IN (Mode 4 per Suppl. Data) +#else + {9, 6, scu_config_normal_drive_t{.mode = 6, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, // SGPIO8: SI5351C.CLK2(O) + {4, 3, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 1}}, // SGPIO9: HOST_CAPTURE(O) + {1, 14, scu_config_normal_drive_t{.mode = 6, .epd = 0, .epun = 0, .ehs = 1, .ezi = 0, .zif = 0}}, // SGPIO10: HOST_DISABLE(I) + {1, 17, scu_config_normal_drive_t{.mode = 6, .epd = 1, .epun = 1, .ehs = 1, .ezi = 0, .zif = 0}}, // SGPIO11: HOST_DIRECTION(I) + {6, 3, scu_config_normal_drive_t{.mode = 2, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // SGPIO4: HOST_DATA4(IO) + {4, 9, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, // SGPIO14/BANK2F3M4: CPLD_P81 + {4, 10, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, // SGPIO15/BANK2F3M6: CPLD_P78 + {2, 6, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 1}}, // MIXER_SCLK/P31: 33pF, RFFC5072.SCLK(I) + {4, 5, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // RXENABLE + {4, 6, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // XCVR_EN: 10K PD +#endif + + // RADIO & RF PATH (MAX2831, RFFC5072, Mixers, Switches, Amps) + {1, 3, scu_config_normal_drive_t{.mode = 5, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, // P1_3 SSP1_MISO: MAX2837.DOUT(O) + {1, 4, scu_config_normal_drive_t{.mode = 5, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, // P1_4 SSP1_MOSI: MAX2837.DIN(I) + {1, 19, scu_config_normal_drive_t{.mode = 1, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, // P1_19 SSP1_SCK: MAX2837.SCLK(I) + {1, 20, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P1_20 CS_XCVR: MAX2837.CS(I) + {2, 11, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P2_11 RX_AMP + {2, 12, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P2_12 !RX_AMP_PWR + {4, 0, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P4_0 HP + {5, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P5_1 LP + {5, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P5_2 TX_MIX_BP #ifdef PRALINE - {2, 6, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 1, .ezi = 0, .zif = 1}}, /* TRIGGER_OUT / MIX_EN_N_R1_0: GPIO5[6] - PRALINE */ + {5, 4, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, // P5_4: RFFC ENX + {5, 5, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, // P5_5: RFFC RESETX + {9, 5, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // P9_5: RFFC5072 SCLK + {9, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 1, .ezi = 1, .zif = 0}}, // P9_2: RFFC5072 DATA (Bidirectional) + {13, 11, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, // PD_11: RFFC Lock Detect + {13, 14, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 1, .ezi = 0, .zif = 0}}, // PD_14: MAX2831 CS + {13, 15, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // PD_15: MAX2831 RXHP + {13, 16, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 1, .ezi = 0, .zif = 0}}, // PD_16: MAX5864 CS + + {14, 1, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 1, .ezi = 0, .zif = 0}}, // PE_1: MAX2831 !SHDN + {14, 2, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, // PE_2: MAX2831 RXTX + {6, 3, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 1, .ezi = 0, .zif = 0}}, // P6_3: MIX_ENABLE_N + {gpio_control::map_p1_ctrl1.scu_port, gpio_control::map_p1_ctrl1.scu_pin, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P6_8 P1_CTRL1 (Output GND, Mode 4) + {gpio_control::map_aa_en.scu_port, gpio_control::map_aa_en.scu_pin, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 0}}, // P1_14: AA_EN + {gpio_control::map_rf5072_mix_en.scu_port, gpio_control::map_rf5072_mix_en.scu_pin, scu_config_normal_drive_t{.mode = 0, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P9_0: RF5072 MIX EN + {9, 6, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, // P9_6: MAX2831 LD Input + {6, 5, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 1, .ezi = 0, .zif = 0}}, // P6_5: TX enable + {10, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 1, .ezi = 0, .zif = 0}}, // PA_1: LPF enable + {10, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 1, .ezi = 0, .zif = 0}}, // PA_2: RF amp enable #else - /* HackRF One RFFC5072 SPI pins */ - {2, 6, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* MIXER_SCLK/P31: 33pF, RFFC5072.SCLK(I) */ + {5, 3, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P5_3 RX_MIX_BP + {5, 4, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // MIXER_ENX + {5, 6, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P5_6 TX_AMP + {5, 7, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P5_7 CS_AD, PRALINE: RFFC5072 CS + {5, 5, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // MIXER_RESETX + {6, 4, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, // MIXER_SDATA + {1, 7, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // !MIX_BYPASS + {2, 10, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // AMP_BYPASS + {6, 8, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P6_8 MIX_BYPASS + {6, 9, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // !TX_AMP_PWR #endif - {2, 10, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* AMP_BYPASS/P50: U14.V2(I), U12.V2(I) */ - {2, 11, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* RX_AMP/P49: U12.V1(I), U14.V3(I) */ - {2, 12, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* !RX_AMP_PWR/P52: 10K PU, Q1.G(I), power to U13 (RX amp) */ - {4, 0, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* HP/P44: U6.VCTL1(I), U5.VCTL2(I) */ - {4, 5, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* RXENABLE/P56: MAX2837.RXENABLE(I) */ - {4, 6, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* XCVR_EN: 10K PD, MAX2837.ENABLE(I) */ - {5, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* LP/P45: U6.VCTL2(I), U5.VCTL1(I) */ - {5, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* TX_MIX_BP/P46: U9.V1(I) */ - {5, 3, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* RX_MIX_BP/P47: U9.V3(I) */ - {5, 4, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* MIXER_ENX/P32: 10K PU, 33pF, RFFC5072.ENX(I) */ - {5, 5, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* MIXER_RESETX/P33: 10K PU, 33pF, RFFC5072.RESETX(I) */ - {5, 6, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* TX_AMP/P48: U12.V3(I), U14.V1(I) */ + +// SAFE TERMINATION (Unused pins grounded to prevent noise & save power) + #ifdef PRALINE - /* PRALINE RFFC5072 SPI pins - different from HackRF One */ - {5, 7, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* P5_7: GPIO2[7], RFFC5072 CS */ - {9, 5, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 0, .ehs = 1, .ezi = 0, .zif = 0}}, /* P9_5: GPIO5[18], RFFC5072 SCLK */ - {9, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 1, .ezi = 1, .zif = 0}}, /* P9_2: GPIO4[14], RFFC5072 SDATA (bidirectional) */ + {1, 1, scu_config_normal_drive_t{.mode = 0, .epd = 1, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, // P1_1: Input GND + {2, 7, scu_config_normal_drive_t{.mode = 0, .epd = 1, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, // P2_7: Input GND + {1, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, // P1_2: Input VCC + {4, 6, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, // P4_6: Input VCC + {6, 10, scu_config_normal_drive_t{.mode = 0, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P6_10: Output GND + {4, 8, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P4_8: Output GND + {8, 3, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P8_3: Output GND + {8, 8, scu_config_normal_drive_t{.mode = 0, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P8_8: Unused + {10, 0, scu_config_normal_drive_t{.mode = 0, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // PA_0: Unused + {11, 2, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, // PB_2: Unused IN + {11, 4, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, // PB_4: Unused IN #else - /* HackRF One RFFC5072 SPI pins - NOT used on PRALINE */ - {5, 7, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* CS_AD/P54: MAX5864.CS(I) */ - {6, 4, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, /* MIXER_SDATA/P27: 33pF, RFFC5072.SDATA(IO) */ + {1, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P1_1 + {1, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P1_2 + {2, 5, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P2_5 + {2, 7, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P2_7 + {4, 8, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P4_8 #endif - {6, 8, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* MIX_BYPASS/P34: U1.VCTL2(I), U11.VCTL1(I) */ - {6, 9, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* !TX_AMP_PWR/P51: 10K PU, Q2.G(I), power to U25 (TX amp) */ - /* SGPIO for sample transfer interface to HackRF CPLD. */ - {0, 0, scu_config_normal_drive_t{.mode = 3, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, /* SGPIO0/P75/BANK2F3M3: CPLD.89/HOST_DATA0(IO) */ - {0, 1, scu_config_normal_drive_t{.mode = 3, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, /* SGPIO1/BANK2F3M5: CPLD.79/HOST_DATA1(IO) */ - {1, 15, scu_config_normal_drive_t{.mode = 2, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, /* SGPIO2/BANK2F3M9: CPLD.74/HOST_DATA2(IO) */ - {1, 16, scu_config_normal_drive_t{.mode = 2, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, /* SGPIO3/BANK2F3M10: CPLD.72/HOST_DATA3(IO) */ - {6, 3, scu_config_normal_drive_t{.mode = 2, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, /* SGPIO4/BANK2F3M14: CPLD.67/HOST_DATA4(IO) */ - {6, 6, scu_config_normal_drive_t{.mode = 2, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, /* SGPIO5/BANK2F3M15: CPLD.64/HOST_DATA5(IO) */ - {2, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, /* SGPIO6/BANK2F3M16: CPLD.61/HOST_DATA6(IO) */ - {1, 0, scu_config_normal_drive_t{.mode = 6, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, /* SGPIO7/P76/BANK2F3M7: CPLD.77/HOST_DATA7(IO) */ - {9, 6, scu_config_normal_drive_t{.mode = 6, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, /* SGPIO8/SGPIO_CLK/P60: SI5351C.CLK2(O) */ - {4, 3, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 1}}, /* SGPIO9/P77/BANK2F3M1: CPLD.91/HOST_CAPTURE(O) */ - {1, 14, scu_config_normal_drive_t{.mode = 6, .epd = 0, .epun = 0, .ehs = 1, .ezi = 0, .zif = 0}}, /* SGPIO10/P78/BANK2F3M8: CPLD.76/HOST_DISABLE(I) */ - {1, 17, scu_config_normal_drive_t{.mode = 6, .epd = 1, .epun = 1, .ehs = 1, .ezi = 0, .zif = 0}}, /* SGPIO11/P79/BANK2F3M11: CPLD.71/HOST_DIRECTION(I) */ - {1, 18, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* SGPIO12/BANK2F3M12: CPLD.70/HOST_INVERT(I) */ - {4, 9, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* SGPIO14/BANK2F3M4: CPLD.81/CPLD_P81 */ - {4, 10, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* SGPIO15/BANK2F3M6: CPLD.78/CPLD_P78 */ + // PORTAPACK SPECIFIC & JTAG (CPLD, UI, Audio, SD) + + {6, 0, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, // I2S0_RX_MCLK: Unused - /* PortaPack CPLD JTAG pins - same for all builds including PRALINE - * (PRALINE FPGA uses P5_1/P5_2/P4_10, not these pins) */ - {6, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* CPLD_TCK: PortaPack CPLD.TCK(I) */ - {6, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* CPLD_TDI: PortaPack CPLD.TDI(I), I2S0_RX_SDA(O) */ - {6, 5, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* CPLD_TMS: HackRF CPLD.TMS(I) */ #ifndef PRALINE - {9, 5, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, /* CPLD_TDO: HackRF CPLD.TDO(O) */ + {9, 5, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, // CPLD_TDO: HackRF CPLD.TDO(O) + {6, 5, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // CPLD_TMS: HackRF CPLD.TMS(I) + {15, 4, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, // I2S0_RX_SCK: Unused #endif + {1, 5, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, // SD_POW: PortaPack CPLD.TDO(O) + {1, 8, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, // SD_VOLT0: PortaPack CPLD.TMS(I) + {6, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // CPLD_TCK: PortaPack CPLD.TCK(I) + {6, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, // CPLD_TDI: PortaPack CPLD.TDI(I) - /* PortaPack CPLD */ - {1, 5, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, /* SD_POW: PortaPack CPLD.TDO(O) */ - {1, 8, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* SD_VOLT0: PortaPack CPLD.TMS(I) */ - - /* Miscellaneous */ - {6, 0, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* I2S0_RX_MCLK: Unused */ - {15, 4, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* I2S0_RX_SCK: Unused */ - - /* Usage of these pins varies by revision, float until detection */ - {1, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, - {1, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, - {2, 5, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, - {2, 7, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, - {4, 4, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, - {4, 8, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, - {5, 0, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, - {6, 7, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, - {6, 10, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, }}; /* Additional GPIO configuration for HackRF OG */ @@ -523,11 +728,11 @@ static const std::array pins_setup_r9{{ #ifdef PRALINE -static const std::array pins_setup_portapack{{ +static const std::array pins_setup_portapack{{ {2, 0, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* U0_TXD: PortaPack P2_0/IO_STBX */ {2, 1, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* U0_RXD: PortaPack P2_1/ADDR */ - {2, 3, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* I2C1_SDA: PortaPack P2_3/LCD_TE */ - {2, 4, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* I2C1_SCL: PortaPack P2_4/LCD_RDX */ + {2, 3, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 1}}, /* I2C1_SDA: PortaPack P2_3/LCD_TE */ + {2, 4, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 1}}, /* I2C1_SCL: PortaPack P2_4/LCD_RDX */ {2, 8, scu_config_normal_drive_t{.mode = 1, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, /* P2_8: 10K PD, BOOT2, DFU switch, PortaPack P2_8/ */ {2, 9, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* P2_9: 10K PD, BOOT3, PortaPack P2_9/LCD_WRX */ {2, 13, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* P2_13: PortaPack P2_13/DIR */ @@ -562,6 +767,21 @@ static const std::array pins_setup_portapack{{ {4, 5, scu_config_normal_drive_t{.mode = 3, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* P4_5: ADC0_2 yn*/ {4, 4, scu_config_normal_drive_t{.mode = 3, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* P4_4: ADC0_5 xp */ {15, 4, scu_config_normal_drive_t{.mode = 3, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* PF_4: ADC0_6 xn*/ + + {1, 7, scu_config_normal_drive_t{.mode = 0, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P1_7: Output GND + {5, 3, scu_config_normal_drive_t{.mode = 0, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P5_3 Output GND + {5, 6, scu_config_normal_drive_t{.mode = 0, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P5_6 Output GND + {5, 7, scu_config_normal_drive_t{.mode = 0, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P5_7 Output GND + {9, 1, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // P9_1: Output GND + {10, 3, scu_config_normal_drive_t{.mode = 0, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // PA_3: Output GND + {10, 4, scu_config_normal_drive_t{.mode = 0, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // PA_4: Output GND + {11, 0, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // PB_0: Output GND + {11, 1, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // PB_1: Output GND + {11, 3, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // PB_3: Output GND + {11, 5, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // PB_5: Output GND + {14, 0, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, // PE_0: Output GND + {4, 3, scu_config_normal_drive_t{.mode = 0, .epd = 1, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, // P4_3: VBUSCTRL Input GND + }}; #else @@ -608,25 +828,6 @@ static const std::array pins_setup_spifi{{ {3, 8, scu_config_normal_drive_t{.mode = 3, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, /* SPIFI_CS/P68: W25Q80BV.CS(I) */ }}; -template -void setup_gpios(const std::array& pins_setup) { - for (size_t i = 0; i < N; i++) { - LPC_GPIO->PIN[i] |= pins_setup[i].data; - LPC_GPIO->DIR[i] |= pins_setup[i].dir; - } -} - -static void setup_pin(const scu_setup_t& pin_setup) { - LPC_SCU->SFSP[pin_setup.port][pin_setup.pin] = pin_setup.config; -} - -template -void setup_pins(const std::array& pins_setup) { - for (const auto& pin_setup : pins_setup) { - setup_pin(pin_setup); - } -} - /* * HackRF One r9 has a pull-up on GPIO3_6 (P6_10) and a pull-down on GPIO2_9 (P5_0). * HackRF One OG has a pull-down on GPIO3_6 (P6_10) and a pull-up on GPIO2_9 (P5_0). @@ -667,110 +868,9 @@ static void configure_spifi(void) { } void configure_pins_portapack(void) { - LPC_GPIO->DIR[1] |= (1 << 13) | (1 << 10); - LPC_GPIO->DIR[3] |= (0xff << 8); - LPC_GPIO->DIR[5] |= (1 << 4) | (1 << 1) | (1 << 0); setup_pins(pins_setup_portapack); } -static const motocon_pwm_resources_t motocon_pwm_resources = { - .base = {.clk = &LPC_CGU->BASE_APB1_CLK, .stat = &LPC_CCU1->BASE_STAT, .stat_mask = (1 << 1)}, - .branch = {.cfg = &LPC_CCU1->CLK_APB1_MOTOCON_PWM_CFG, .stat = &LPC_CCU1->CLK_APB1_MOTOCON_PWM_STAT}, - .reset = {.output_index = 38}, -}; - -static const scu_setup_t pin_setup_vaa_enablex_pwm = {5, 0, scu_config_normal_drive_t{.mode = 1, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}; -static const scu_setup_t pin_setup_vaa_enablex_gpio_og = {5, 0, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}; -static const scu_setup_t pin_setup_vaa_enablex_gpio_r9 = {6, 10, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}; -#ifdef PRALINE -/* PRALINE uses P8_1 (GPIO4[1]) for VAA_DISABLE (high = VAA off, low = VAA on) */ -static const scu_setup_t pin_setup_vaa_disable_praline = {8, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}; -#endif - -/* VAA powers: - * MAX5864 analog section. - * MAX2837 registers and other functions. - * RFFC5072 analog section. - * - * Beware that power applied to pins of the MAX2837 may - * show up on VAA and start powering other components on the - * VAA net. So turn on VAA before driving pins from MCU to - * MAX2837. - */ -void vaa_power_on(void) { - /* Very twitchy process for powering up VAA without glitching the 3.3V rail, which can send the - * microcontroller into reset. - * - * Controlling timing while running from SPIFI flash is tricky, hence use of a PWM peripheral... - */ - if (hackrf_r9) { - /* - * There is enough VCC->VAA leakage prior to VAA activation from IO pins on - * HackRF One r9 that slowing down activation like this isn't necessary, but - * we do it just in case a different start-up sequence in the future results - * in less leakage. - */ - setup_pin(pin_setup_vaa_enablex_gpio_r9); // P6_10 GPIO3[ 6]: !VAA_ENABLE, 10K PU - for (uint32_t i = 0; i < 1000; i++) { - LPC_GPIO->W3[6] = 1; - LPC_GPIO->W3[6] = 0; - } - } else { - /* Configure and enable MOTOCONPWM peripheral clocks. - * Assume IDIVC is running the post-bootloader configuration, outputting 96MHz derived from PLL1. - */ - base_clock_enable(&motocon_pwm_resources.base); - branch_clock_enable(&motocon_pwm_resources.branch); - peripheral_reset(&motocon_pwm_resources.reset); - - /* Combination of pulse duration and duty cycle was arrived at empirically, to keep supply glitching - * to +/- 0.15V. - */ - const uint32_t cycle_period = 256; - uint32_t enable_period = 2; - LPC_MCPWM->TC2 = 0; - LPC_MCPWM->MAT2 = cycle_period - enable_period; - LPC_MCPWM->LIM2 = cycle_period; - - /* Switch !VAA_ENABLE pin from GPIO to MOTOCONPWM peripheral output, now that the peripheral is configured. */ - setup_pin(pin_setup_vaa_enablex_pwm); // P5_0 /GPIO2[ 9]/MCOB2: !VAA_ENABLE, 10K PU - - /* Start the PWM operation. */ - LPC_MCPWM->CON_SET = (1 << 16); - - /* Wait until VAA rises to approximately 90% of final voltage. */ - /* Timing assumes we're running immediately after the bootloader: 96 MHz from IRC+PLL1 - */ - while (enable_period < cycle_period) { - { - volatile uint32_t delay = 2000; - while (delay--); - } - enable_period <<= 1; - LPC_MCPWM->MAT2 = cycle_period - enable_period; - } - - /* Hold !VAA_ENABLE active using a GPIO, so we can reclaim and shut down the MOTOCONPWM peripheral. */ - LPC_GPIO->CLR[2] = (1 << 9); // !VAA_ENABLE - LPC_GPIO->DIR[2] |= (1 << 9); - setup_pin(pin_setup_vaa_enablex_gpio_og); // P5_0 /GPIO2[ 9]/MCOB2: !VAA_ENABLE, 10K PU - - peripheral_reset(&motocon_pwm_resources.reset); - branch_clock_disable(&motocon_pwm_resources.branch); - base_clock_disable(&motocon_pwm_resources.base); - } -} - -void vaa_power_off(void) { - // TODO: There's a lot of other stuff that must be done to prevent - // leakage from +3V3 into VAA. - if (hackrf_r9) { - LPC_GPIO->W3[6] = 1; - } else { - LPC_GPIO->W2[9] = 1; - } -} - /** * @brief Early initialization code. * @details This initialization must be performed just after stack setup @@ -891,206 +991,18 @@ extern "C" void __late_init(void) { /** * @brief Board-specific initialization code. - * @todo Add your board-specific code, if any. + * @details Initializes LEDs, power rails, and configures physical pins + * for both PRALINE and standard HackRF hardware variants. */ extern "C" void boardInit(void) { #ifdef PRALINE /* HackRF Pro Specific: Initialize and Load FPGA */ hackrf_r9 = false; - /* Enable 3.3V aux power - P6_7 = GPIO5[15], active LOW (clear to enable) */ - LPC_SCU->SFSP[6][7] = 0xF4; /* SCU_GPIO_FAST | FUNCTION4 */ - LPC_GPIO->DIR[5] |= (1 << 15); - LPC_GPIO->CLR[5] = (1 << 15); /* Clear = enable 3.3V aux */ - { - volatile uint32_t delay = 200000; - while (delay--); - } - /* Enable 1.2V for FPGA - P8_7 = GPIO4[7], active high */ - LPC_SCU->SFSP[8][7] = 0x10; - LPC_GPIO->DIR[4] |= (1 << 7); - LPC_GPIO->SET[4] = (1 << 7); - { - volatile uint32_t delay = 200000; - while (delay--); - } + power_control::aux_power_on(); - /* Enable VAA for RF - P8_1 = GPIO4[1], active low */ - LPC_SCU->SFSP[8][1] = 0x10; - LPC_GPIO->DIR[4] |= (1 << 1); - LPC_GPIO->CLR[4] = (1 << 1); - { - volatile uint32_t delay = 200000; - while (delay--); - } - - /* Configure RFFC5072 pins for PRALINE */ - /* Set GPIO directions for RFFC5072 SPI pins */ - /* P5_7 = GPIO2[7] RFFC5072 CS */ - LPC_GPIO->SET[2] = (1 << 7); /* CS high (deselected) */ - LPC_GPIO->DIR[2] |= (1 << 7); /* CS as output */ - - /* P9_5 = GPIO5[18] RFFC5072 SCLK */ - LPC_GPIO->CLR[5] = (1 << 18); /* CLK low */ - LPC_GPIO->DIR[5] |= (1 << 18); /* CLK as output */ - - /* P9_2 = GPIO4[14] RFFC5072 DATA (bidirectional) */ - LPC_GPIO->DIR[4] |= (1 << 14); /* DATA as output initially */ - - /* P2_6 = GPIO5[6] TRIGGER_OUT / MIX_EN_N_R1_0 (PRALINE R1.0 mixer bypass) */ - /* SCU configured in PAL array above with mode=4 */ - LPC_GPIO->CLR[5] = (1 << 6); /* Default low (mixer enabled) */ - LPC_GPIO->DIR[5] |= (1 << 6); /* Output */ - { - volatile uint32_t delay = 200000; - while (delay--); - } - - /* Configure Port D pins for PRALINE (use SFSPD registers) */ - /* PD_14 = GPIO6[28] MAX2831 chip select */ - LPC_SCU->SFSPD[14] = 0xF4; /* SCU_GPIO_FAST | FUNCTION4 */ - LPC_GPIO->SET[6] = (1 << 28); /* CS high (inactive) */ - LPC_GPIO->DIR[6] |= (1 << 28); /* Output */ - - /* PD_15 = GPIO6[29] MAX2831 RXHP control */ - LPC_SCU->SFSPD[15] = 0xF4; /* SCU_GPIO_FAST | FUNCTION4 */ - LPC_GPIO->CLR[6] = (1 << 29); /* RXHP low = 100 Hz HPF */ - LPC_GPIO->DIR[6] |= (1 << 29); /* Output */ - - /* PD_16 = GPIO6[30] MAX5864 chip select */ - LPC_SCU->SFSPD[16] = 0xF4; /* SCU_GPIO_FAST | FUNCTION4 */ - LPC_GPIO->SET[6] |= (1 << 30); /* CS high (inactive) */ - LPC_GPIO->DIR[6] |= (1 << 30); /* Output */ - { - volatile uint32_t delay = 200000; - while (delay--); - } - - /* Configure Port E pins for MAX2831 control (use SFSPE registers) */ - /* PE_1 = GPIO7[1] MAX2831 ENABLE */ - LPC_SCU->SFSPE[1] = 0xF4; /* SCU_GPIO_FAST | FUNCTION4 */ - LPC_GPIO->CLR[7] = (1 << 1); /* Start disabled */ - LPC_GPIO->DIR[7] |= (1 << 1); /* Output */ - /* PE_2 = GPIO7[2] MAX2831 RXTX mode select */ - LPC_SCU->SFSPE[2] = 0xF4; /* SCU_GPIO_FAST | FUNCTION4 */ - LPC_GPIO->CLR[7] = (1 << 2); /* Start in shutdown mode */ - LPC_GPIO->DIR[7] |= (1 << 2); /* Output */ - { - volatile uint32_t delay = 200000; - while (delay--); - } - - /* Configure Port 6 pins for RF path control */ - /* P6_3 = GPIO3[2] Mixer enable (inverted: 0 = mixer ON) */ - LPC_SCU->SFSP[6][3] = 0xF0; /* SCU_GPIO_FAST | FUNCTION0 */ - LPC_GPIO->CLR[3] = (1 << 2); /* Mixer enabled by default */ - LPC_GPIO->DIR[3] |= (1 << 2); /* Output */ - /* P6_5 = GPIO3[4] TX enable */ - LPC_SCU->SFSP[6][5] = 0xF0; /* SCU_GPIO_FAST | FUNCTION0 */ - LPC_GPIO->CLR[3] = (1 << 4); /* TX off by default (RX mode) */ - LPC_GPIO->DIR[3] |= (1 << 4); /* Output */ - { - volatile uint32_t delay = 200000; - while (delay--); - } - - /* Configure Port A pins for RF path control */ - /* PA_1 = GPIO4[8] LPF enable */ - LPC_SCU->SFSP[0xA][1] = 0xF0; /* SCU_GPIO_FAST | FUNCTION0 */ - LPC_GPIO->SET[4] = (1 << 8); /* LPF enabled by default (low band) */ - LPC_GPIO->DIR[4] |= (1 << 8); /* Output */ - /* PA_2 = GPIO4[9] RF amp enable */ - LPC_SCU->SFSP[0xA][2] = 0xF0; /* SCU_GPIO_FAST | FUNCTION0 */ - LPC_GPIO->CLR[4] = (1 << 9); /* RF amp off by default */ - LPC_GPIO->DIR[4] |= (1 << 9); /* Output */ - { - volatile uint32_t delay = 200000; - while (delay--); - } - - /* Configure RFFC5072 control pins for PRALINE */ - /* P5_4 = GPIO2[13] RFFC5072 ENX - SPI chip select (managed by SPI driver) */ - LPC_SCU->SFSP[5][4] = 0x10; /* FUNCTION0 (GPIO), pull-up, slow mode (matches HackRF USB) */ - LPC_GPIO->DIR[2] |= (1 << 13); /* ENX: OUTPUT */ - LPC_GPIO->SET[2] = (1 << 13); /* ENX = 1 (deselected initially) */ - { - volatile uint32_t delay = 200000; - while (delay--); - } - - /* P5_5 = GPIO2[14] RFFC5072 RESETX (active high: 1=running) */ - LPC_SCU->SFSP[5][5] = 0x10; /* FUNCTION0 (GPIO), pull-up, slow mode (matches HackRF USB) */ - LPC_GPIO->DIR[2] |= (1 << 14); /* RESETX: OUTPUT */ - LPC_GPIO->SET[2] = (1 << 14); /* RESETX = 1 (RUNNING) */ - { - volatile uint32_t delay = 200000; - while (delay--); - } - - /* Ensure RESETX is stable */ - for (volatile int i = 0; i < 10; i++) { - LPC_GPIO->W2[14] = 1; - } - - /* PD_11 = GPIO6[25] RFFC5072 Lock Detect (input) */ - LPC_SCU->SFSPD[11] = 0x10; /* FUNCTION0 (GPIO), pull-up (matches HackRF USB) */ - LPC_GPIO->DIR[6] &= ~(1 << 25); /* LD: INPUT */ - { - volatile uint32_t delay = 200000; - while (delay--); - } - - /* Configure PRALINE-specific SGPIO pins for FPGA sample interface. - * These override the HackRF One pin config from pins_setup. - * PRALINE uses different pins than HackRF One for SGPIO4/8/9/10. - * SCU_GPIO_FAST = 0xF0 (EPUN + EHS + EZI + ZIF) - */ - /* CRITICAL: Disable HackRF One SGPIO8 pin (P9_6) - PRALINE uses P8_0 instead */ - LPC_SCU->SFSP[9][6] = 0x00; /* P9_6 = GPIO mode 0, disable SGPIO function */ - - /* SGPIO4 = P9_4 function 6 (HOST_DATA4) */ - LPC_SCU->SFSP[9][4] = 0xF6; /* SCU_GPIO_FAST | func 6 */ - /* SGPIO8 = P8_0 function 4 (SGPIO_CLK - clock from FPGA) */ - LPC_SCU->SFSP[8][0] = 0xF4; /* SCU_GPIO_FAST | func 4 */ - /* SGPIO9 = P9_3 function 6 (HOST_CAPTURE) */ - LPC_SCU->SFSP[9][3] = 0xF6; /* SCU_GPIO_FAST | func 6 */ - /* SGPIO10 = P8_2 function 4 (HOST_DISABLE - output to FPGA) */ - LPC_SCU->SFSP[8][2] = 0xF4; /* SCU_GPIO_FAST | func 4 */ - /* SGPIO11 = P1_17 function 6 (HOST_DIRECTION - output to FPGA, tells FPGA TX vs RX) */ - LPC_SCU->SFSP[1][17] = 0xF6; /* SCU_GPIO_FAST | func 6 */ - { - volatile uint32_t delay = 200000; - while (delay--); - } - - /* SGPIO data pins (SGPIO0-7) - all 8 bits required for sample data */ - LPC_SCU->SFSP[0][0] = 0xF3; /* SGPIO0: P0_0 function 3, HOST_DATA0 */ - LPC_SCU->SFSP[0][1] = 0xF3; /* SGPIO1: P0_1 function 3, HOST_DATA1 */ - LPC_SCU->SFSP[1][15] = 0xF2; /* SGPIO2: P1_15 function 2, HOST_DATA2 */ - LPC_SCU->SFSP[1][16] = 0xF2; /* SGPIO3: P1_16 function 2, HOST_DATA3 */ - /* SGPIO4 already configured above at line 942 */ - LPC_SCU->SFSP[6][6] = 0xF2; /* SGPIO5: P6_6 function 2, HOST_DATA5 */ - LPC_SCU->SFSP[2][2] = 0xF0; /* SGPIO6: P2_2 function 0, HOST_DATA6 */ - 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 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] - LPC_GPIO->DIR[2] |= (1 << 1) | (1 << 2) | (1 << 8); - - // Turn off all LEDs to start - // PRALINE LEDs are active-low: SET (HIGH) = OFF, CLR (LOW) = ON LPC_GPIO->SET[2] = (1 << 1) | (1 << 2) | (1 << 8); - { - volatile uint32_t delay = 200000; - while (delay--); - } + LPC_GPIO->CLR[4] = (1 << 6); #else @@ -1108,27 +1020,12 @@ extern "C" void boardInit(void) { setup_pins(pins_setup_og); } - /* 2. Turn on VAA (Critical for Radio/Transceiver) */ - vaa_power_on(); - - /* 3. Handle VAA Enable Pin Latching */ - if (hackrf_r9) { - LPC_GPIO->W2[9] = 1; - } else { - LPC_GPIO->W3[6] = 1; - } - #endif } extern "C" void _default_exit(void) { - if (hackrf_r9) { - LPC_GPIO->W2[9] = 0; - } else { - LPC_GPIO->W3[6] = 0; - } - - vaa_power_off(); + power_control::core_power_off(); + power_control::vaa_power_off(); chSysDisable(); systick_stop(); diff --git a/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.h b/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.h index 972e360fa..b71ed403f 100755 --- a/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.h +++ b/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.h @@ -33,12 +33,10 @@ #ifdef __cplusplus extern "C" { #endif - void boardInit(void); +void boardInit(void); - void configure_pins_portapack(void); +void configure_pins_portapack(void); - void vaa_power_on(void); - void vaa_power_off(void); #ifdef __cplusplus } #endif diff --git a/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/fpga_bridge.c b/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/fpga_bridge.c index e9491e443..495b9f902 100644 --- a/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/fpga_bridge.c +++ b/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/fpga_bridge.c @@ -198,34 +198,6 @@ static void ssp1_init_ice40(void) { SSP1_CR1_LOCAL = SSP_CR1_SSE; } -// Configure SSP1 pins via SCU -static void configure_ssp1_pins(void) { - // P1_3 = SSP1_MISO (function 5) - MMIO32_LOCAL(SCU_SSP1_CIPO_LOCAL) = SCU_SSP_IO_LOCAL | SCU_CONF_FUNCTION5_LOCAL; - // P1_4 = SSP1_MOSI (function 5) - MMIO32_LOCAL(SCU_SSP1_COPI_LOCAL) = SCU_SSP_IO_LOCAL | SCU_CONF_FUNCTION5_LOCAL; - // P1_19 = SSP1_SCK (function 1) - MMIO32_LOCAL(SCU_SSP1_SCK_LOCAL) = SCU_SSP_IO_LOCAL | SCU_CONF_FUNCTION1_LOCAL; -} - -// Configure FPGA control pins via SCU and GPIO -static void configure_fpga_control_pins(void) { - // P5_2 = GPIO2[11] = CRESET (function 0, output) - MMIO32_LOCAL(SCU_FPGA_CRESET_LOCAL) = SCU_GPIO_NOPULL_LOCAL | SCU_CONF_FUNCTION0_LOCAL; - // P4_10 = GPIO5[14] = CDONE (function 4, input with pullup) - MMIO32_LOCAL(SCU_FPGA_CDONE_LOCAL) = SCU_GPIO_PUP_LOCAL | SCU_CONF_FUNCTION4_LOCAL; - // P5_1 = GPIO2[10] = SPI_CS (function 0, output) - MMIO32_LOCAL(SCU_FPGA_SPI_CS_LOCAL) = SCU_GPIO_NOPULL_LOCAL | SCU_CONF_FUNCTION0_LOCAL; - - // Set CRESET and SPI_CS as outputs (GPIO2[11] and GPIO2[10]) - GPIO_DIR(FPGA_CRESET_PORT) |= (1 << FPGA_CRESET_PIN) | (1 << FPGA_SPI_CS_PIN); - // Clear both initially - GPIO_CLR(FPGA_CRESET_PORT) = (1 << FPGA_CRESET_PIN) | (1 << FPGA_SPI_CS_PIN); - - // CDONE is input (GPIO5[14]) - GPIO_DIR(FPGA_CDONE_PORT) &= ~(1 << FPGA_CDONE_PIN); -} - // GPIO control helpers static void fpga_creset_low(void) { GPIO_CLR(FPGA_CRESET_PORT) = (1 << FPGA_CRESET_PIN); @@ -578,12 +550,6 @@ int fpga_bridge_init(uint8_t* mem_base) { CGU_BASE_SSP1_CLK = CGU_BASE_SSP1_CLK_AUTOBLOCK(1) | CGU_BASE_SSP1_CLK_CLK_SEL(CGU_SRC_PLL1); - // Configure SSP1 pins - configure_ssp1_pins(); - - // Configure FPGA control pins - configure_fpga_control_pins(); - // Initialize SSP1 for iCE40 programming ssp1_init_ice40(); diff --git a/firmware/chibios-portapack/os/hal/platforms/LPC43xx/pal_lld.c b/firmware/chibios-portapack/os/hal/platforms/LPC43xx/pal_lld.c index 71c65a24b..05fb04f08 100644 --- a/firmware/chibios-portapack/os/hal/platforms/LPC43xx/pal_lld.c +++ b/firmware/chibios-portapack/os/hal/platforms/LPC43xx/pal_lld.c @@ -52,8 +52,6 @@ /* Driver exported functions. */ /*===========================================================================*/ -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) - /** * @brief LPC43xx I/O ports configuration. * @details Ports 0 through 8. @@ -62,15 +60,15 @@ * * @notapi */ -void _pal_lld_init(const PALConfig *config) { - for(size_t i=0; i<8; i++) { - LPC_GPIO->PIN[i] = config->P[i].data; - LPC_GPIO->DIR[i] = config->P[i].dir; - } +void _pal_lld_init(const PALConfig* config) { + for (size_t i = 0; i < 8; i++) { + LPC_GPIO->PIN[i] = config->P[i].data; + LPC_GPIO->DIR[i] = config->P[i].dir; + } - for(size_t i=0; iSCU); i++) { - LPC_SCU->SFSP[config->SCU[i].port][config->SCU[i].pin] = config->SCU[i].config.word; - } + for (size_t i = 0; i < SCU_ARRAY_SIZE; i++) { + LPC_SCU->SFSP[config->SCU[i].port][config->SCU[i].pin] = config->SCU[i].config.word; + } } /** @@ -87,14 +85,14 @@ void _pal_lld_init(const PALConfig *config) { void _pal_lld_setgroupmode(ioportid_t port, ioportmask_t mask, iomode_t mode) { - /* TODO: Handling pull-up, pull-down modes not implemented, as it would - * require a map from GPIO to SCU pins. Not today. - */ - if( mode == PAL_MODE_OUTPUT_PUSHPULL ) { - LPC_GPIO->DIR[port] |= mask; - } else { - LPC_GPIO->DIR[port] &= ~mask; - } + /* TODO: Handling pull-up, pull-down modes not implemented, as it would + * require a map from GPIO to SCU pins. Not today. + */ + if (mode == PAL_MODE_OUTPUT_PUSHPULL) { + LPC_GPIO->DIR[port] |= mask; + } else { + LPC_GPIO->DIR[port] &= ~mask; + } } #endif /* HAL_USE_PAL */ diff --git a/firmware/chibios-portapack/os/hal/platforms/LPC43xx/pal_lld.h b/firmware/chibios-portapack/os/hal/platforms/LPC43xx/pal_lld.h index f76694632..4c4dd7c81 100644 --- a/firmware/chibios-portapack/os/hal/platforms/LPC43xx/pal_lld.h +++ b/firmware/chibios-portapack/os/hal/platforms/LPC43xx/pal_lld.h @@ -50,10 +50,18 @@ * @note Implementations may extend this structure to contain more, * architecture dependent, fields. */ + +#ifdef PRALINE +#define SCU_ARRAY_SIZE 78 +#else +#define SCU_ARRAY_SIZE 56 +#endif + typedef struct { - /** @brief GPIO setup data.*/ - gpio_setup_t P[8]; - scu_setup_t SCU[60]; + /** @brief GPIO setup data.*/ + gpio_setup_t P[8]; + scu_setup_t SCU[SCU_ARRAY_SIZE]; + } PALConfig; /** @@ -94,50 +102,50 @@ typedef uint8_t iopadid_t; /** * @brief GPIO0 port identifier. */ -#define IOPORT1 0 -#define GPIO0 0 +#define IOPORT1 0 +#define GPIO0 0 /** * @brief GPIO1 port identifier. */ -#define IOPORT2 1 -#define GPIO1 1 +#define IOPORT2 1 +#define GPIO1 1 /** * @brief GPIO1 port identifier. */ -#define IOPORT3 2 -#define GPIO2 2 +#define IOPORT3 2 +#define GPIO2 2 /** * @brief GPIO1 port identifier. */ -#define IOPORT4 3 -#define GPIO3 3 +#define IOPORT4 3 +#define GPIO3 3 /** * @brief GPIO1 port identifier. */ -#define IOPORT5 4 -#define GPIO4 4 +#define IOPORT5 4 +#define GPIO4 4 /** * @brief GPIO1 port identifier. */ -#define IOPORT6 5 -#define GPIO5 5 +#define IOPORT6 5 +#define GPIO5 5 /** * @brief GPIO1 port identifier. */ -#define IOPORT7 6 -#define GPIO6 6 +#define IOPORT7 6 +#define GPIO6 6 /** * @brief GPIO1 port identifier. */ -#define IOPORT8 7 -#define GPIO7 7 +#define IOPORT8 7 +#define GPIO7 7 /*===========================================================================*/ /* Implementation, some of the following macros could be implemented as */ @@ -237,7 +245,7 @@ typedef uint8_t iopadid_t; * * @notapi */ -//#define pal_lld_readgroup(port, mask, offset) 0 +// #define pal_lld_readgroup(port, mask, offset) 0 /** * @brief Writes a group of bits. @@ -253,7 +261,7 @@ typedef uint8_t iopadid_t; * * @notapi */ -//#define pal_lld_writegroup(port, mask, offset, bits) (void)bits +// #define pal_lld_writegroup(port, mask, offset, bits) (void)bits /** * @brief Pads group mode setup. @@ -268,8 +276,8 @@ typedef uint8_t iopadid_t; * * @notapi */ -#define pal_lld_setgroupmode(port, mask, offset, mode) \ - _pal_lld_setgroupmode(port, mask << offset, mode) +#define pal_lld_setgroupmode(port, mask, offset, mode) \ + _pal_lld_setgroupmode(port, mask << offset, mode) /** * @brief Reads a logical state from an I/O pad. @@ -285,8 +293,8 @@ typedef uint8_t iopadid_t; * * @notapi */ -#define pal_lld_readpad(port, pad) \ - (LPC_GPIO->B[((port) * 32) + (pad)]) +#define pal_lld_readpad(port, pad) \ + (LPC_GPIO->B[((port) * 32) + (pad)]) /** * @brief Writes a logical state on an output pad. @@ -303,8 +311,8 @@ typedef uint8_t iopadid_t; * * @notapi */ -#define pal_lld_writepad(port, pad, bit) \ - ((LPC_GPIO->B[((port) * 32) + (pad)]) = (bit)) +#define pal_lld_writepad(port, pad, bit) \ + ((LPC_GPIO->B[((port) * 32) + (pad)]) = (bit)) /** * @brief Sets a pad logical state to @p PAL_HIGH. @@ -317,8 +325,8 @@ typedef uint8_t iopadid_t; * * @notapi */ -#define pal_lld_setpad(port, pad) \ - (LPC_GPIO->SET[(port)] = 1 << (pad)) +#define pal_lld_setpad(port, pad) \ + (LPC_GPIO->SET[(port)] = 1 << (pad)) /** * @brief Clears a pad logical state to @p PAL_LOW. @@ -331,7 +339,7 @@ typedef uint8_t iopadid_t; * * @notapi */ -#define pal_lld_clearpad(port, pad) \ +#define pal_lld_clearpad(port, pad) \ (LPC_GPIO->CLR[(port)] = 1 << (pad)) /** @@ -345,8 +353,8 @@ typedef uint8_t iopadid_t; * * @notapi */ -#define pal_lld_togglepad(port, pad) \ - (LPC_GPIO->NOT[(port)] = 1 << (pad)) +#define pal_lld_togglepad(port, pad) \ + (LPC_GPIO->NOT[(port)] = 1 << (pad)) /** * @brief Pad mode setup. @@ -362,7 +370,7 @@ typedef uint8_t iopadid_t; * * @notapi */ -//#define pal_lld_setpadmode(port, pad, mode) +// #define pal_lld_setpadmode(port, pad, mode) #if !defined(__DOXYGEN__) extern const PALConfig pal_default_config; @@ -371,10 +379,10 @@ extern const PALConfig pal_default_config; #ifdef __cplusplus extern "C" { #endif - void _pal_lld_init(const PALConfig *config); - void _pal_lld_setgroupmode(ioportid_t port, - ioportmask_t mask, - iomode_t mode); +void _pal_lld_init(const PALConfig* config); +void _pal_lld_setgroupmode(ioportid_t port, + ioportmask_t mask, + iomode_t mode); #ifdef __cplusplus } #endif diff --git a/firmware/common/gpio.cpp b/firmware/common/gpio.cpp new file mode 100644 index 000000000..aecabeabe --- /dev/null +++ b/firmware/common/gpio.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2026 Pezsma + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "gpio.hpp" + +#include "platform.hpp" + +namespace power_control { + +/* VAA powers: + * MAX5864 analog section. + * MAX2837 registers and other functions. + * RFFC5072 analog section. + * + * Beware that power applied to pins of the MAX2837 may + * show up on VAA and start powering other components on the + * VAA net. So turn on VAA before driving pins from MCU to + * MAX2837. + */ + +void vaa_power_on(void) { + /* Very twitchy process for powering up VAA without glitching the 3.3V rail, + * which can send the microcontroller into reset. + */ +#ifdef PRALINE + /* P8_1 (GPIO4[1]) does not have MOTOCONPWM hardware routing. + * Using software bit-banging (pseudo-PWM) for VAA soft-start. + * VAA is active LOW (0 = ON). + */ + + /* Software soft-start loop to prevent brown-out */ + for (uint32_t i = 0; i < 1000; i++) { + LPC_GPIO->W4[1] = 0; /* Turn ON briefly */ + LPC_GPIO->W4[1] = 1; /* Turn OFF briefly */ + } + + /* Latch VAA to ON state (Active LOW) */ + LPC_GPIO->CLR[4] = (1 << 1); + +#else + if (hackrf_r9) { + /* + * There is enough VCC->VAA leakage prior to VAA activation from IO pins on + * HackRF One r9 that slowing down activation like this isn't necessary, but + * we do it just in case a different start-up sequence in the future results + * in less leakage. + */ + setup_pin(pin_setup_vaa_enablex_gpio_r9); // P6_10 GPIO3[ 6]: !VAA_ENABLE, 10K PU + for (uint32_t i = 0; i < 1000; i++) { + LPC_GPIO->W3[6] = 1; + LPC_GPIO->W3[6] = 0; + } + } else { + /* Configure and enable MOTOCONPWM peripheral clocks. + * Assume IDIVC is running the post-bootloader configuration, outputting 96MHz derived from PLL1. + */ + base_clock_enable(&motocon_pwm_resources.base); + branch_clock_enable(&motocon_pwm_resources.branch); + peripheral_reset(&motocon_pwm_resources.reset); + + /* Combination of pulse duration and duty cycle was arrived at empirically, to keep supply glitching + * to +/- 0.15V. + */ + const uint32_t cycle_period = 256; + uint32_t enable_period = 2; + LPC_MCPWM->TC2 = 0; + LPC_MCPWM->MAT2 = cycle_period - enable_period; + LPC_MCPWM->LIM2 = cycle_period; + + /* Switch !VAA_ENABLE pin from GPIO to MOTOCONPWM peripheral output, now that the peripheral is configured. */ + setup_pin(pin_setup_vaa_enablex_pwm); // P5_0 /GPIO2[ 9]/MCOB2: !VAA_ENABLE, 10K PU + + /* Start the PWM operation. */ + LPC_MCPWM->CON_SET = (1 << 16); + + /* Wait until VAA rises to approximately 90% of final voltage. */ + /* Timing assumes we're running immediately after the bootloader: 96 MHz from IRC+PLL1 + */ + while (enable_period < cycle_period) { + { + volatile uint32_t delay = 2000; + while (delay--); + } + enable_period <<= 1; + LPC_MCPWM->MAT2 = cycle_period - enable_period; + } + + /* Hold !VAA_ENABLE active using a GPIO, so we can reclaim and shut down the MOTOCONPWM peripheral. */ + LPC_GPIO->CLR[2] = (1 << 9); // !VAA_ENABLE + LPC_GPIO->DIR[2] |= (1 << 9); + setup_pin(pin_setup_vaa_enablex_gpio_og); // P5_0 /GPIO2[ 9]/MCOB2: !VAA_ENABLE, 10K PU + + peripheral_reset(&motocon_pwm_resources.reset); + branch_clock_disable(&motocon_pwm_resources.branch); + base_clock_disable(&motocon_pwm_resources.base); + } + +#endif +} + +void vaa_power_off(void) { + /* TODO: There's a lot of other stuff that must be done to prevent + * leakage from +3V3 into VAA. + */ +#ifdef PRALINE + /* Safe state: OFF (VAA RF is active LOW, so Set = OFF) */ + LPC_GPIO->SET[4] = (1 << 1); + + /* Turn OFF LED3 (TX) */ + LPC_GPIO->SET[2] = (1 << 8); + +#else + if (hackrf_r9) { + LPC_GPIO->W3[6] = 1; // Turn OFF VAA for r9 P6_10 + } else { + LPC_GPIO->W2[9] = 1; // Turn OFF VAA for OG P5_0 + } +#endif +} + +#ifdef PRALINE + +void aux_power_on(void) { + // 3.3V Aux - P6_7 = GPIO5[15], Active LOW (Clear = ON) + LPC_GPIO->CLR[5] = (1 << 15); +} + +void aux_power_off(void) { + // 3.3V Aux - P6_7 = GPIO5[15], Active LOW (Set = OFF) + LPC_GPIO->SET[5] = (1 << 15); +} + +#endif /* PRALINE */ + +void core_power_on(void) { // Core power enable +#ifdef PRALINE + // 1.2V FPGA - P8_7 = GPIO4[7], Active HIGH (Set = ON) + LPC_GPIO->SET[4] = (1 << 7); + +#else + if (hackrf_r9) { + // P5_0 (GPIO2[9]) is the EN1V8 pin + LPC_GPIO->SET[2] = (1 << 9); + } else { + // On older OG HackRF boards, P6_10 (GPIO3[6]) is the EN1V8 pin + LPC_GPIO->SET[3] = (1 << 6); + } +#endif +} + +void core_power_off(void) { // Core power disable +#ifdef PRALINE + // 1.2V FPGA - P8_7 = GPIO4[7], Active HIGH (Clear = OFF) */ + LPC_GPIO->CLR[4] = (1 << 7); + +#else + if (hackrf_r9) { + // P5_0 (GPIO2[9]) is the EN1V8 pin + LPC_GPIO->CLR[2] = (1 << 9); + } else { + // On older OG HackRF boards, P6_10 (GPIO3[6]) is the EN1V8 pin + LPC_GPIO->CLR[3] = (1 << 6); + } +#endif +} +} // namespace power_control \ No newline at end of file diff --git a/firmware/common/gpio.hpp b/firmware/common/gpio.hpp index 7ff3bdaf1..8fc147f9d 100644 --- a/firmware/common/gpio.hpp +++ b/firmware/common/gpio.hpp @@ -22,10 +22,13 @@ #ifndef __GPIO_H__ #define __GPIO_H__ +#include +#include #include #include "ch.h" #include "hal.h" +#include "pal.h" struct PinConfig { const uint32_t mode; @@ -280,4 +283,109 @@ struct GPIO { const uint16_t _gpio_mode; }; +constexpr uint32_t boot_bit(const GPIO& pin, bool state) { + return (state ? 1UL : 0UL) << pin.pad(); +} + +inline void setup_pin(const scu_setup_t& pin_setup) { + LPC_SCU->SFSP[pin_setup.port][pin_setup.pin] = pin_setup.config; +} + +template +inline void setup_gpios(const std::array& pins_setup) { + for (size_t i = 0; i < N; i++) { + LPC_GPIO->PIN[i] |= pins_setup[i].data; + LPC_GPIO->DIR[i] |= pins_setup[i].dir; + } +} + +template +inline void setup_pins(const std::array& pins_setup) { + for (const auto& pin_setup : pins_setup) { + setup_pin(pin_setup); + } +} + +#ifdef PRALINE +namespace gpio_control { + +struct PinMap { + uint8_t scu_port; + uint8_t scu_pin; + uint8_t gpio_port; + uint8_t gpio_pad; +}; + +constexpr PinMap map_p1_ctrl0{2, 10, 0, 14}; // SCU: 2, 10 | GPIO: 0, 14 +constexpr PinMap map_p1_ctrl1{6, 8, 5, 16}; +constexpr PinMap map_p1_ctrl2{6, 9, 3, 5}; +constexpr PinMap map_p2_ctrl0{8, 3, 7, 3}; +constexpr PinMap map_p2_ctrl1{8, 4, 7, 4}; +constexpr PinMap map_trigger_out{2, 6, 5, 6}; +constexpr PinMap map_trigger_in{13, 12, 6, 26}; + +constexpr PinMap map_rf5072_mix_en{9, 0, 4, 12}; + +constexpr PinMap map_aa_en{1, 14, 1, 7}; // Anti-Aliasing filter + +// P1 Multiplexer control pins +constexpr Pin pin_p1_ctrl0{map_p1_ctrl0.scu_port, map_p1_ctrl0.scu_pin}; // SCU: P2_10 +constexpr GPIO p1_ctrl0{pin_p1_ctrl0, map_p1_ctrl0.gpio_port, map_p1_ctrl0.gpio_pad, PAL_MODE_OUTPUT_PUSHPULL}; // GPIO[0]14 + +constexpr Pin pin_p1_ctrl1{map_p1_ctrl1.scu_port, map_p1_ctrl1.scu_pin}; // SCU: P6_8 +constexpr GPIO p1_ctrl1{pin_p1_ctrl1, map_p1_ctrl1.gpio_port, map_p1_ctrl1.gpio_pad, PAL_MODE_OUTPUT_PUSHPULL}; // GPIO[5]16 + +constexpr Pin pin_p1_ctrl2{map_p1_ctrl2.scu_port, map_p1_ctrl2.scu_pin}; // SCU: P6_9 +constexpr GPIO p1_ctrl2{pin_p1_ctrl2, map_p1_ctrl2.gpio_port, map_p1_ctrl2.gpio_pad, PAL_MODE_OUTPUT_PUSHPULL}; // GPIO[3]5 + +// P2 Multiplexer control pins +constexpr Pin pin_p2_ctrl0{map_p2_ctrl0.scu_port, map_p2_ctrl0.scu_pin}; // SCU: PE_3 +constexpr GPIO p2_ctrl0{pin_p2_ctrl0, map_p2_ctrl0.gpio_port, map_p2_ctrl0.gpio_pad, PAL_MODE_OUTPUT_PUSHPULL}; // GPIO[7]3 + +constexpr Pin pin_p2_ctrl1{map_p2_ctrl1.scu_port, map_p2_ctrl1.scu_pin}; // SCU: PE_4 +constexpr GPIO p2_ctrl1{pin_p2_ctrl1, map_p2_ctrl1.gpio_port, map_p2_ctrl1.gpio_pad, PAL_MODE_OUTPUT_PUSHPULL}; // GPIO[7]4 + +// Trigger pins +constexpr Pin trigger_out_pin{map_trigger_out.scu_port, map_trigger_out.scu_pin}; // SCU: P2_6 +constexpr GPIO trigger_out{trigger_out_pin, map_trigger_out.gpio_port, map_trigger_out.gpio_pad, PAL_MODE_OUTPUT_PUSHPULL}; // GPIO[5]6 + +constexpr Pin trigger_in_pin{map_trigger_in.scu_port, map_trigger_in.scu_pin}; // SCU: PD_12 +constexpr GPIO trigger_in{trigger_in_pin, map_trigger_in.gpio_port, map_trigger_in.gpio_pad, PAL_MODE_INPUT}; // GPIO[6]26 + +// RF507x +constexpr Pin pin_rf5072_mix_en{map_rf5072_mix_en.scu_port, map_rf5072_mix_en.scu_pin}; +constexpr GPIO rf5072_mix_en{pin_rf5072_mix_en, map_rf5072_mix_en.gpio_port, map_rf5072_mix_en.gpio_pad, 0}; + +// Anti-Aliasing filter +constexpr Pin pin_aa_en{map_aa_en.scu_port, map_aa_en.scu_pin}; +constexpr GPIO aa_en{pin_aa_en, map_aa_en.gpio_port, map_aa_en.gpio_pad, 0}; + +} // namespace gpio_control +#endif + +namespace power_control { + +void vaa_power_on(void); +void vaa_power_off(void); + +#ifdef PRALINE +void aux_power_on(void); +void aux_power_off(void); +#endif + +void core_power_on(void); +void core_power_off(void); + +static const motocon_pwm_resources_t motocon_pwm_resources = { + .base = {.clk = &LPC_CGU->BASE_APB1_CLK, .stat = &LPC_CCU1->BASE_STAT, .stat_mask = (1 << 1)}, + .branch = {.cfg = &LPC_CCU1->CLK_APB1_MOTOCON_PWM_CFG, .stat = &LPC_CCU1->CLK_APB1_MOTOCON_PWM_STAT}, + .reset = {.output_index = 38}, +}; + +static const scu_setup_t pin_setup_vaa_enablex_pwm = {5, 0, scu_config_normal_drive_t{.mode = 1, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}; +static const scu_setup_t pin_setup_vaa_enablex_gpio_og = {5, 0, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}; +static const scu_setup_t pin_setup_vaa_enablex_gpio_r9 = {6, 10, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}; + +} // namespace power_control + #endif /*__GPIO_H__*/ diff --git a/firmware/common/hackrf_gpio.hpp b/firmware/common/hackrf_gpio.hpp index 1e79138d0..049eccaec 100644 --- a/firmware/common/hackrf_gpio.hpp +++ b/firmware/common/hackrf_gpio.hpp @@ -41,14 +41,6 @@ constexpr GPIO gpio_led_tx = gpio[GPIO2_8]; constexpr GPIO gpio_og_1v8_enable = gpio[GPIO3_6]; constexpr GPIO gpio_r9_1v8_enable = gpio[GPIO2_9]; constexpr GPIO gpio_vregmode = gpio[GPIO3_7]; -#ifdef PRALINE -// PRALINE uses different power control pins -constexpr GPIO gpio_og_vaa_disable = gpio[GPIO4_1]; // PRALINE VAA disable (P8_1) -constexpr GPIO gpio_r9_vaa_disable = gpio[GPIO4_1]; // PRALINE VAA disable (P8_1) -#else -constexpr GPIO gpio_og_vaa_disable = gpio[GPIO2_9]; -constexpr GPIO gpio_r9_vaa_disable = gpio[GPIO3_6]; -#endif constexpr GPIO gpio_rx_mix_bp = gpio[GPIO2_12]; constexpr GPIO gpio_tx_mix_bp = gpio[GPIO2_11]; @@ -70,7 +62,6 @@ constexpr GPIO gpio_hp = gpio[GPIO2_0]; constexpr GPIO gpio_rx_amp = gpio[GPIO1_11]; constexpr GPIO gpio_tx_amp = gpio[GPIO2_15]; constexpr GPIO gpio_amp_bypass = gpio[GPIO0_14]; -constexpr GPIO gpio_not_rx_amp_pwr = gpio[GPIO1_12]; constexpr GPIO gpio_not_tx_amp_pwr = gpio[GPIO3_5]; #ifdef PRALINE @@ -80,6 +71,7 @@ constexpr GPIO gpio_rffc5072_resetx = gpio[GPIO2_14]; // P5_5: LPC43xx controls #else constexpr GPIO gpio_rffc5072_select = gpio[GPIO2_13]; constexpr GPIO gpio_rffc5072_resetx = gpio[GPIO2_14]; +constexpr GPIO gpio_not_rx_amp_pwr = gpio[GPIO1_12]; #endif #ifdef PRALINE @@ -128,14 +120,16 @@ constexpr GPIO gpio_q_invert = gpio[GPIO0_13]; constexpr GPIO gpio_vaa_disable = gpio[GPIO4_1]; // VAA disable (P8_1) constexpr GPIO gpio_1v2_enable = gpio[GPIO4_7]; // 1V2 enable (P8_7) constexpr GPIO gpio_3v3aux_disable = gpio[GPIO5_15]; // 3V3 aux disable (P6_7) -constexpr GPIO gpio_vbus_enable = gpio[GPIO8_4]; // VBUS_IN_EN P8_4 ->LOW -constexpr GPIO gpio_vin_enable = gpio[GPIO8_5]; // VIN_IN_EN P8_5 ->HIGH +constexpr GPIO gpio_3v3aux_oc = gpio[GPIO1_11]; // 3.3V aux overcurrent input (P2_11) +constexpr GPIO gpio_vbus_enable = gpio[GPIO4_4]; // VBUS_IN_EN P8_4 ->LOW +constexpr GPIO gpio_vin_enable = gpio[GPIO4_5]; // VIN_IN_EN P8_5 ->HIGH // PRALINE RF path control constexpr GPIO gpio_tx_enable = gpio[GPIO3_4]; // TX enable (P6_5) // constexpr GPIO gpio_mix_enable_n = gpio[GPIO3_2]; // Mixer enable inverted (P6_3) constexpr GPIO gpio_lpf_enable = gpio[GPIO4_8]; // LPF enable (PA_1) constexpr GPIO gpio_rf_amp_enable = gpio[GPIO4_9]; // RF amp enable (PA_2) constexpr GPIO gpio_ant_bias_disable = gpio[GPIO1_12]; // Antenna bias disable (P2_12) +constexpr GPIO gpio_bias_oc = gpio[GPIO3_7]; // Bias tee overcurrent input (P6_11) // PRALINE mixer lock detect (gpio_max2831_ld defined above at line 93) constexpr GPIO gpio_rffc5072_ld = gpio[GPIO6_25]; // Mixer lock detect (PD_11) @@ -155,6 +149,7 @@ constexpr GPIO gpio_clkin_ctrl = gpio[GPIO0_15]; // CLKIN control (P1_20) constexpr GPIO gpio_trigger_in = gpio[GPIO6_26]; // Trigger input (PD_12) constexpr GPIO gpio_trigger_out = gpio[GPIO5_6]; // Trigger output (P2_6) constexpr GPIO gpio_pps_out = gpio[GPIO5_5]; // PPS output (P2_5) + #endif #ifdef PRALINE diff --git a/firmware/common/led.hpp b/firmware/common/led.hpp index 9c93400a6..fa215bfc8 100644 --- a/firmware/common/led.hpp +++ b/firmware/common/led.hpp @@ -31,13 +31,13 @@ struct LED { void setup() const { #ifdef PRALINE - /* PRALINE LEDs are active-low (GPIO LOW = LED ON) */ - _gpio.set(); /* Start with LED OFF (HIGH) */ +// No-op: GPIO direction and initial OFF state are already +// enforced globally at boot by pal_default_config in board.cpp. #else _gpio.clear(); -#endif _gpio.output(); _gpio.configure(); +#endif } void on() const { diff --git a/firmware/common/pins.hpp b/firmware/common/pins.hpp index 4506f0784..603d649e7 100644 --- a/firmware/common/pins.hpp +++ b/firmware/common/pins.hpp @@ -337,8 +337,8 @@ enum GPIOs { GPIO4_14, // Power control and LED4 GPIO4_1, - GPIO8_4, - GPIO8_5, + GPIO4_4, // VBUS_IN_EN + GPIO4_5, // VIN_IN_EN GPIO4_6, GPIO4_7, // RF path control @@ -451,8 +451,8 @@ constexpr GPIO gpio[] = { #ifdef PRALINE [GPIO4_14] = {pins[P9_2], 4, 14, 0}, // RFFC5072 mixer data [GPIO4_1] = {pins[P8_1], 4, 1, 0}, // VAA disable - [GPIO8_4] = {pins[P8_4], 8, 4, 0}, // VBUS_IN_EN - [GPIO8_5] = {pins[P8_5], 8, 5, 0}, // VIN_IN_EN + [GPIO4_4] = {pins[P8_4], 4, 4, 0}, // VBUS_IN_EN + [GPIO4_5] = {pins[P8_5], 4, 5, 0}, // VIN_IN_EN [GPIO4_6] = {pins[P8_6], 4, 6, 0}, // LED4 [GPIO4_7] = {pins[P8_7], 4, 7, 0}, // 1V2 enable [GPIO4_8] = {pins[PA_1], 4, 8, 0}, // LPF enable @@ -470,8 +470,8 @@ constexpr GPIO gpio[] = { // Placeholder entries for non-PRALINE builds (use P0_0 as dummy) [GPIO4_14] = {pins[P0_0], 4, 14, 0}, [GPIO4_1] = {pins[P0_0], 4, 1, 0}, - [GPIO8_4] = {pins[P0_0], 8, 4, 0}, - [GPIO8_5] = {pins[P0_0], 8, 5, 0}, + [GPIO4_4] = {pins[P0_0], 4, 4, 0}, + [GPIO4_5] = {pins[P0_0], 4, 5, 0}, [GPIO4_6] = {pins[P0_0], 4, 6, 0}, [GPIO4_7] = {pins[P0_0], 4, 7, 0}, [GPIO4_8] = {pins[P0_0], 4, 8, 0},