diff --git a/firmware/application/event_m0.cpp b/firmware/application/event_m0.cpp index 58560fbfe..bee76daeb 100644 --- a/firmware/application/event_m0.cpp +++ b/firmware/application/event_m0.cpp @@ -37,8 +37,20 @@ #include "ch.h" -#include "lpc43xx_cpp.hpp" -using namespace lpc43xx; +#include "hackrf_gpio.hpp" +using namespace hackrf::one; + +#include "irq_rtc.hpp" + +#include "i2c_lld.h" + +#include "i2cdevmanager.hpp" +#include "i2cdev_ppmod.hpp" + +#include "lpc43xx.inc" +#include "nvic.h" +#include "lpc43xx_m0.h" +#include "rffc507x_spi.hpp" #include @@ -134,7 +146,194 @@ void EventDispatcher::set_display_sleep(const bool sleep) { // Let frame sync handler turn on backlight after repaint. } EventDispatcher::display_sleep = sleep; -}; +} + +void EventDispatcher::charge_deep_sleep(const bool sleep) { + bool detect = false; + uint8_t valid_mask = 0; + uint8_t percent = 0; + uint16_t voltage = 0; + int32_t current = 0; + + constexpr I2CConfig i2c_config_12mhz{ + .high_count = 15, + .low_count = 15, + }; + + if (sleep) { + auto dev = (i2cdev::I2cDev_PPmod*)i2cdev::I2CDevManager::get_dev_by_model(I2C_DEVMDL::I2CDECMDL_PPMOD); + if (dev) dev->send_poweroff_command(); + + rffc507x::spi::SPI().power_down(); + portapack::shutdown(false, true); + + // Unmount SD card and stop driver + f_mount(nullptr, reinterpret_cast(_T("")), 0); + sdcDisconnect(&SDCD1); + sdcStop(&SDCD1); + + // Signal application shutdown + ShutdownMessage shutdown_message; + shared_memory.application_queue.push(shutdown_message); + shared_memory.baseband_message = nullptr; + + // Disable core interrupts and system tick + nvicDisableVector(DMA_IRQn); + nvicDisableVector(M4CORE_IRQn); + chSysDisable(); + systick_stop(); + + SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk; + +#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)); + LPC_GPIO->DIR[3] &= ~((1 << 7) | (1 << 5)); + 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)); + LPC_GPIO->DIR[3] &= ~((1 << 7) | (1 << 5)); + LPC_GPIO->DIR[5] &= ~(1 << 16); +#endif + + // Power down peripherals (CGU cleanup) + LPC_RGU->RESET_CTRL[0] = (1 << 5); // USB0 Reset + LPC_CGU->PLL0USB_CTRL.PD = 1; + LPC_CGU->BASE_USB0_CLK.PD = 1; + LPC_CREG->CREG0 |= (1 << 5); + + LPC_CGU->BASE_USB1_CLK.PD = 1; + LPC_CGU->BASE_UART0_CLK.PD = 1; + LPC_CGU->BASE_UART1_CLK.PD = 1; + LPC_CGU->BASE_UART2_CLK.PD = 1; + LPC_CGU->BASE_UART3_CLK.PD = 1; + LPC_CGU->BASE_SPI_CLK.PD = 1; + LPC_CGU->BASE_PERIPH_CLK.PD = 1; + LPC_CGU->BASE_SDIO_CLK.PD = 1; + LPC_CGU->BASE_SSP0_CLK.PD = 1; + LPC_CGU->BASE_SSP1_CLK.PD = 1; + LPC_CGU->BASE_LCD_CLK.PD = 1; + LPC_CGU->BASE_OUT_CLK.PD = 1; + + (*(volatile uint32_t*)(&LPC_CGU->PLL0AUDIO_CTRL)) |= (1 << 0); + + LPC_ADC0->CR &= ~(1 << 21); + LPC_ADC1->CR &= ~(1 << 21); + led_rx.off(); + led_usb.off(); + + rtc_wakeup_init(); + NVIC_EnableIRQ(I2C0_OR_I2C1_IRQn); + + while (1) { + // --- Battery Status Check (I2C) --- + detect = battery::BatteryManagement::isDetected(); + if (detect) { + battery::BatteryManagement::getBatteryInfo(valid_mask, percent, voltage, current); + + bool is_full = (valid_mask == 31 && percent == 100 && current <= 10) || + (valid_mask == 1 && percent == 100); + + if (is_full) { + // Case 1: Battery full (All LEDs off) + led_rx.off(); + led_tx.off(); + } else if ((voltage < 4150 && current < 10) || valid_mask == 0) { + // Case 2: Not full but low current draw (<10mA) -> Charging error + led_tx.on(); // LED indicates error/idle + led_rx.off(); + } else { + // Case 3: Actively charging + led_rx.on(); // LED indicates charging + led_tx.off(); + } + } else { + // Case 4: Battery IC not detected -> Error or H2 or older, so don't show that as an error. + led_tx.on(); + led_rx.on(); + } + + // Shut down I2C and power down the APB bus for sleep + portapack::i2c0.stop(); + LPC_CGU->BASE_APB1_CLK.PD = 1; + + // Save interrupt states before mass disable + uint32_t saved_iser0 = NVIC->ISER[0]; + uint32_t saved_iser1 = NVIC->ISER[1]; + uint32_t saved_iser2 = NVIC->ISER[2]; + + // Disable and clear all pending interrupts + NVIC->ICER[0] = 0xFFFFFFFF; + NVIC->ICER[1] = 0xFFFFFFFF; + NVIC->ICER[2] = 0xFFFFFFFF; + + NVIC->ICPR[0] = 0xFFFFFFFF; + NVIC->ICPR[1] = 0xFFFFFFFF; + NVIC->ICPR[2] = 0xFFFFFFFF; + + // Re-enable only necessary wakeup sources + NVIC_EnableIRQ(RTC_IRQn); + NVIC_EnableIRQ(EVENTROUTER_IRQn); + + // Configure RTC wakeup interval + if (valid_mask != 0 || detect) { + rtc_wakeup(60); + } else { + rtc_wakeup(3); + } + + LPC_RTC->ILR = 3; + LPC_EVENTROUTER->CLR_STAT = 0xFFFFFFFF; + NVIC_ClearPendingIRQ(RTC_IRQn); + NVIC_ClearPendingIRQ(EVENTROUTER_IRQn); + + __disable_irq(); + + // Configure and enter Deep Sleep + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + __DSB(); + __ISB(); + + // CPU enters sleep here + __WFI(); + + // --- WAKEUP SEQUENCE --- + __enable_irq(); + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + // Cleanup RTC and restore peripheral clocks + LPC_RTC->AMR = 0xFF; + LPC_RTC->ILR = 3; + LPC_CGU->BASE_APB1_CLK.PD = 0; + LPC_RGU->RESET_CTRL[1] = (1 << 16); + + // Short delay for power stability (3V3 rail) + for (volatile int d = 0; d < 10000; d++); + + // Restart I2C controller + LPC_CGU->BASE_APB1_CLK.PD = 0; + portapack::i2c0.start(i2c_config_12mhz); + + // Restore original interrupt enable states + NVIC->ISER[0] = saved_iser0; + NVIC->ISER[1] = saved_iser1; + NVIC->ISER[2] = saved_iser2; + + } // End of while(1) deep sleep loop + } else { + portapack::display.wake(true); + } +} eventmask_t EventDispatcher::wait() { return chEvtWaitAny(ALL_EVENTS); diff --git a/firmware/application/event_m0.hpp b/firmware/application/event_m0.hpp index 94c1e6b97..593171bff 100644 --- a/firmware/application/event_m0.hpp +++ b/firmware/application/event_m0.hpp @@ -63,6 +63,8 @@ class EventDispatcher { static void set_display_sleep(const bool sleep); + static void charge_deep_sleep(const bool sleep); + static inline void check_fifo_isr() { if (!shared_memory.application_queue.is_empty()) { events_flag_isr(EVT_MASK_APPLICATION); diff --git a/firmware/application/external/sdusb/ui_sd_over_usb.cpp b/firmware/application/external/sdusb/ui_sd_over_usb.cpp index 57a20466d..5b11a2291 100644 --- a/firmware/application/external/sdusb/ui_sd_over_usb.cpp +++ b/firmware/application/external/sdusb/ui_sd_over_usb.cpp @@ -45,7 +45,7 @@ SdOverUsbView::SdOverUsbView(NavigationView& nav) sdcDisconnect(&SDCD1); sdcStop(&SDCD1); - portapack::shutdown(true); + portapack::shutdown(true, false); baseband::run_prepared_image(portapack::memory::map::m4_code.base()); m0_halt(); /* will not return*/ diff --git a/firmware/application/hw/rffc507x_spi.cpp b/firmware/application/hw/rffc507x_spi.cpp index af5f9c8fc..7ea29d4da 100644 --- a/firmware/application/hw/rffc507x_spi.cpp +++ b/firmware/application/hw/rffc507x_spi.cpp @@ -103,5 +103,13 @@ data_t SPI::transfer_word(const Direction direction, const address_t address, co return data_in; } +void SPI::power_down() { + // A 0x01 address the MIX_CTRL register. A 0x0000 + transfer_word(Direction::Write, 0x01, 0x0000); + + // a chip 300 µA-es Power Down + transfer_word(Direction::Write, 0x00, 0x0000); +} + } // namespace spi } // namespace rffc507x diff --git a/firmware/application/hw/rffc507x_spi.hpp b/firmware/application/hw/rffc507x_spi.hpp index b1b168306..09418e544 100644 --- a/firmware/application/hw/rffc507x_spi.hpp +++ b/firmware/application/hw/rffc507x_spi.hpp @@ -41,6 +41,7 @@ class SPI { }; void init(); + void power_down(); reg_t read(const address_t address) { return transfer_word(Direction::Read, address, 0); diff --git a/firmware/application/irq_rtc.cpp b/firmware/application/irq_rtc.cpp index 5fa44b090..a653a80a9 100644 --- a/firmware/application/irq_rtc.cpp +++ b/firmware/application/irq_rtc.cpp @@ -27,6 +27,8 @@ using namespace lpc43xx; #include "event_m0.hpp" +#include "nvic.h" +#include "lpc43xx.inc" static Thread* thread_rtc_event = NULL; @@ -36,6 +38,84 @@ void rtc_interrupt_enable() { nvicEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(LPC_RTC_IRQ_PRIORITY)); } +void rtc_reset_default() { + // 1. FULL RTC CLEANUP/RESET + LPC_RTC->CIIR = 0; + LPC_RTC->AMR = 0xFF; // Disable all alarms + LPC_RTC->ILR = 3; // Clear stuck interrupt flags + LPC_RTC->ASEC = 0; + LPC_RTC->AMIN = 0; + LPC_RTC->AHRS = 0; + + // 2. RESET EVENT ROUTER + // Reset to edge-triggered (Garantálja, hogy nem ragad be az ébresztés!) + LPC_EVENTROUTER->EDGE |= (1 << 5); + + // DISABLE RTC channel routing + LPC_EVENTROUTER->CLR_EN = (1 << 5); + + // Clear pending events + LPC_EVENTROUTER->CLR_STAT = 0xFFFFFFFF; +} + +void rtc_wakeup_init() { + rtc_reset_default(); + + // 1. Force RTC Clock (In case it was modified by the app) + // Bit 0: Enable, Bit 4: Calibration OFF + LPC_RTC->CCR = (1 << 0); + + // 2. EVENT ROUTER CONFIGURATION + LPC_EVENTROUTER->HILO |= (1 << 5); + LPC_EVENTROUTER->EDGE |= (1 << 5); // <-- JAVÍTVA! (Itt volt a hiba a te kódodban) + LPC_EVENTROUTER->CLR_STAT = 0xFFFFFFFF; // Clear pending events + LPC_EVENTROUTER->SET_EN = (1 << 5); // Enable RTC channel routing + + // 3. NVIC Cleanup + NVIC_ClearPendingIRQ(RTC_IRQn); + NVIC_ClearPendingIRQ(EVENTROUTER_IRQn); + NVIC_EnableIRQ(RTC_IRQn); + NVIC_EnableIRQ(EVENTROUTER_IRQn); +} + +void rtc_wakeup(uint32_t sleep_seconds) { + // 1. Safety cleanup after application tasks + LPC_RTC->CCR &= ~(1 << 4); // Disable calibration (Important!) + + uint32_t sec = LPC_RTC->SEC; + uint32_t min = LPC_RTC->MIN; + uint32_t hrs = LPC_RTC->HRS; + + sec += sleep_seconds; + while (sec >= 60) { + sec -= 60; + min++; + } + while (min >= 60) { + min -= 60; + hrs++; + } + while (hrs >= 24) { + hrs -= 24; + } + + // 2. Write values to alarm registers + LPC_RTC->ASEC = sec; + LPC_RTC->AMIN = min; + LPC_RTC->AHRS = hrs; + + // Mask for SEC, MIN, HRS (Disable all other alarm triggers) + uint32_t mask = 0xFF ^ ((1 << 0) | (1 << 1) | (1 << 2)); + LPC_RTC->AMR = mask; + + // Verify write (Sync with RTC domain) + while (LPC_RTC->ASEC != sec); + while (LPC_RTC->AMR != mask); + + // Brief extra delay to allow internal logic to settle/latch + for (volatile int i = 0; i < 5000; i++) __asm__("nop"); +} + extern "C" { CH_IRQ_HANDLER(RTC_IRQHandler) { diff --git a/firmware/application/irq_rtc.hpp b/firmware/application/irq_rtc.hpp index bfaab2900..30bb8340a 100644 --- a/firmware/application/irq_rtc.hpp +++ b/firmware/application/irq_rtc.hpp @@ -22,6 +22,11 @@ #ifndef __IPC_RTC_H__ #define __IPC_RTC_H__ +#include + void rtc_interrupt_enable(); +void rtc_reset_default(); +void rtc_wakeup_init(); +void rtc_wakeup(uint32_t sleep_seconds); #endif /*__IPC_RTC_H__*/ diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index ef2eb9435..7b4873095 100644 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -141,6 +141,8 @@ Continuous (Fox-oring) #include #include "i2cdevmanager.hpp" +#include "lpc43xx.inc" + #include "rffc507x.hpp" /* c/m, avoiding initial short ON Ant_DC_Bias pulse, from cold reset */ rffc507x::RFFC507x first_if; ui::SystemView* system_view_ptr; @@ -181,6 +183,8 @@ static void event_loop() { } int main(void) { + rtc_reset_default(); + #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 fc28ae97a..72d00616a 100644 --- a/firmware/application/portapack.cpp +++ b/firmware/application/portapack.cpp @@ -339,6 +339,20 @@ static void shutdown_base() { clock_manager.shutdown(); } +static void shutdown_base_12mhz() { + i2c0.stop(); + + set_clock_config(clock_config_irc); + + cgu::pll1::disable(); + + set_idivc_base_clocks(cgu::CLK_SEL::IRC); + + i2c0.start(i2c_config_boot_clock); + + clock_manager.shutdown(); +} + static void set_cpu_clock_speed() { /* Incantation from LPC43xx UM10503 section 12.2.1.1, to bring the M4 * core clock speed to the 110 - 204MHz range. @@ -698,7 +712,7 @@ init_status_t init() { return return_code; } -void shutdown(const bool leave_screen_on) { +void shutdown(const bool leave_screen_on, const bool slow_clock) { gpdma::controller.disable(); if (!leave_screen_on) { @@ -712,7 +726,11 @@ void shutdown(const bool leave_screen_on) { hackrf::cpld::init_from_eeprom(); - shutdown_base(); + if (slow_clock) { + shutdown_base_12mhz(); + } else { + shutdown_base(); + } } void setEventDispatcherToUSBSerial(EventDispatcher* evt) { diff --git a/firmware/application/portapack.hpp b/firmware/application/portapack.hpp index a13b987b3..224464f81 100644 --- a/firmware/application/portapack.hpp +++ b/firmware/application/portapack.hpp @@ -78,7 +78,7 @@ void set_antenna_bias(const bool v); bool get_antenna_bias(); init_status_t init(); -void shutdown(const bool leave_screen_on = false); +void shutdown(const bool leave_screen_on = false, const bool slow_clock = false); void setEventDispatcherToUSBSerial(EventDispatcher* evt); diff --git a/firmware/application/radio.cpp b/firmware/application/radio.cpp index dae757f51..46b68ed51 100644 --- a/firmware/application/radio.cpp +++ b/firmware/application/radio.cpp @@ -606,4 +606,4 @@ uint32_t register_read(const size_t register_number) { } /* namespace debug */ -} /* namespace radio */ +} /* namespace radio */ \ No newline at end of file diff --git a/firmware/application/radio.hpp b/firmware/application/radio.hpp index 9a23f3f57..1655669b8 100644 --- a/firmware/application/radio.hpp +++ b/firmware/application/radio.hpp @@ -136,4 +136,4 @@ uint32_t register_read(const size_t register_number); } /* namespace radio */ -#endif /*__RADIO_H__*/ +#endif /*__RADIO_H__*/ \ No newline at end of file diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index 342ad2a2d..eba276ab6 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -347,11 +347,11 @@ void SystemStatusView::on_battery_data(const BatteryStateMessage* msg) { // Only show charging modal when transitioning to charging state nav_.display_modal( "CHARGING", - "Screen on while charging?", + "Enter deep sleep? \n \nExit: Press reset button. \n \nRX LED: Charging. \nTX LED: Charging error. \nLEDs OFF: Charge complete.", YESNO, - [this](bool keep_screen_on) { - if (!keep_screen_on) { - EventDispatcher::set_display_sleep(true); + [this](bool deepsleep) { + if (deepsleep) { + EventDispatcher::charge_deep_sleep(true); } }); } diff --git a/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp b/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp index e80772532..e7c679407 100755 --- a/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp +++ b/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp @@ -15,7 +15,6 @@ limitations under the License. */ - #include "ch.h" #include "hal.h" @@ -39,7 +38,7 @@ bool hackrf_r9; * the internal pull-ups * * LPC43xx pull-ups come on line when 3V3 supply voltage reaches about 2V. - * + * * 3V3 supply: * Ramps up in about 1ms. * @@ -51,589 +50,569 @@ bool hackrf_r9; * 1V8 supply is activated when GPIO is driven high by user code. */ const PALConfig pal_default_config = { - .P = { - { // GPIO0 - .data + .P = { + { + // GPIO0 + .data #ifdef PRALINE - = (0 << 15) // P1_20: CLKIN_CTRL - start low + = (0 << 15) // P1_20: CLKIN_CTRL - start low #else - = (1 << 15) // P1_20: CS_XCVR + = (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 - | (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 << 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 + | (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 , - .dir + .dir #ifdef PRALINE - = (1 << 15) // P1_20: CLKIN_CTRL - output + = (1 << 15) // P1_20: CLKIN_CTRL - output #else - = (1 << 15) // P1_20: CS_XCVR + = (1 << 15) // P1_20: CS_XCVR #endif - | (1 << 14) // P2_10: AMP_BYPASS - | (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 - | (0 << 7) // P2_7: Varies by revision, float until detection - | (0 << 6) // P3_6: SPIFI_MISO - | (0 << 5) // P6_6: SGPIO5, HOST_DATA5 - | (0 << 4) // P1_0: SGPIO7, HOST_DATA7 - | (0 << 3) // P1_16: SGPIO3, HOST_DATA3 - | (0 << 2) // P1_15: SGPIO2, HOST_DATA2 - | (0 << 1) // P0_1: SGPIO1, HOST_DATA1 - | (0 << 0) // P0_0: SGPIO0, HOST_DATA0 - }, - { // GPIO1 - .data - = (1 << 15) // P3_5: SPIFI_SIO2 - | (1 << 14) // P3_4: SPIFI_SIO3 - | (1 << 13) // P2_13: PortaPack DIR - | (1 << 12) // P2_12: !RX_AMP_PWR - | (0 << 11) // P2_11: RX_AMP - | (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 << 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 + | (1 << 14) // P2_10: AMP_BYPASS + | (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 + | (0 << 7) // P2_7: Varies by revision, float until detection + | (0 << 6) // P3_6: SPIFI_MISO + | (0 << 5) // P6_6: SGPIO5, HOST_DATA5 + | (0 << 4) // P1_0: SGPIO7, HOST_DATA7 + | (0 << 3) // P1_16: SGPIO3, HOST_DATA3 + | (0 << 2) // P1_15: SGPIO2, HOST_DATA2 + | (0 << 1) // P0_1: SGPIO1, HOST_DATA1 + | (0 << 0) // P0_0: SGPIO0, HOST_DATA0 + }, + { + // GPIO1 + .data = (1 << 15) // P3_5: SPIFI_SIO2 + | (1 << 14) // P3_4: SPIFI_SIO3 + | (1 << 13) // P2_13: PortaPack DIR + | (1 << 12) // P2_12: !RX_AMP_PWR + | (0 << 11) // P2_11: RX_AMP + | (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 << 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 << 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 - | (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 - }, - { // GPIO2 - .data - = (0 << 15) // P5_6: TX_AMP - | (1 << 14) // P5_5: MIXER_RESETX, 10K PU + .dir = (0 << 15) // P3_5: SPIFI_SIO2 + | (0 << 14) // P3_4: SPIFI_SIO3 + | (0 << 13) // P2_13: PortaPack DIR + | (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 + | (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 + }, + { + // GPIO2 + .data = (0 << 15) // P5_6: TX_AMP + | (1 << 14) // P5_5: MIXER_RESETX, 10K PU #ifdef PRALINE - | (0 << 13) // P5_4: MIXER_ENX, 10K PU + | (0 << 13) // P5_4: MIXER_ENX, 10K PU #else - | (1 << 13) // P5_4: MIXER_ENX, 10K PU + | (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 - | (1 << 3) // P4_3: SGPIO9, HOST_CAPTURE - | (0 << 2) // P4_2: LED2 (RX) - | (0 << 1) // P4_1: LED1 (USB) - | (1 << 0) // P4_0: HP + | (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 + | (1 << 3) // P4_3: SGPIO9, HOST_CAPTURE + | (0 << 2) // P4_2: LED2 (RX) + | (0 << 1) // P4_1: LED1 (USB) + | (1 << 0) // P4_0: HP , - .dir - = (1 << 15) // P5_6: TX_AMP + .dir = (1 << 15) // P5_6: TX_AMP #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 + | (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 #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 + | (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 #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 - }, - { // GPIO3 - .data - = (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) - | (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) + | (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 + }, + { + // GPIO3 + .data = (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) + | (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) , - .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) - }, - { // GPIO4 - .data - = (1 << 11) // P9_6: SGPIO8, SGPIO_CLK + .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) + }, + { + // GPIO4 + .data = (1 << 11) // P9_6: SGPIO8, SGPIO_CLK , - .dir - = (0 << 11) // P9_6: SGPIO8, SGPIO_CLK - }, - { // 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 + .dir = (0 << 11) // P9_6: SGPIO8, SGPIO_CLK + }, + { + // 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 , - .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 = (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 + }, + {// GPIO6 + .data = 0, + .dir = 0}, + {// GPIO7 + .data = 0, + .dir = 0}, }, - { // 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) */ + .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) */ + /* 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) */ - /* 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) */ + /* 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) */ - /* HackRF: I2C0 */ - /* Glitch filter operates at 3ns instead of 50ns due to the WM8731 - * returning an ACK very fast (170ns) and confusing the I2C state - * machine into thinking there was a bus error. It looks like the - * MCU sees SDA fall before SCL falls, indicating a START at the - * point an ACK is expected. With the glitch filter off or set to - * 3ns, it's probably still a bit tight timing-wise, but improves - * reliability on some problem units. - */ - { 25, 1, - scu_config_sfsi2c0_t { - .scl_efp=1, // SCL: 3ns glitch - .scl_ehd=0, // SCL: Standard/Fast mode - .scl_ezi=1, // SCL: Input enabled - .scl_zif=0, // SCL: Enable input glitch filter - .sda_efp=1, // SDA: 3ns glitch - .sda_ehd=0, // SDA: Standard/Fast mode - .sda_ezi=1, // SDA: Input enabled - .sda_zif=0 // SDA: Enable input glitch filter - } - }, + /* HackRF: I2C0 */ + /* Glitch filter operates at 3ns instead of 50ns due to the WM8731 + * returning an ACK very fast (170ns) and confusing the I2C state + * machine into thinking there was a bus error. It looks like the + * MCU sees SDA fall before SCL falls, indicating a START at the + * point an ACK is expected. With the glitch filter off or set to + * 3ns, it's probably still a bit tight timing-wise, but improves + * reliability on some problem units. + */ + {25, 1, + scu_config_sfsi2c0_t{ + .scl_efp = 1, // SCL: 3ns glitch + .scl_ehd = 0, // SCL: Standard/Fast mode + .scl_ezi = 1, // SCL: Input enabled + .scl_zif = 0, // SCL: Enable input glitch filter + .sda_efp = 1, // SDA: 3ns glitch + .sda_ehd = 0, // SDA: Standard/Fast mode + .sda_ezi = 1, // SDA: Input enabled + .sda_zif = 0 // SDA: Enable input glitch filter + }}, - /* 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) */ + /* 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) */ #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 */ + {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 */ #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) */ + /* 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) */ #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) */ + {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) */ #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) */ + /* 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) */ #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) */ + /* 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) */ #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) */ + {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 */ + /* 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 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) */ + /* 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) */ #endif - /* 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) */ + /* 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 */ + /* 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 } }, - } -}; + /* 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 */ -static const std::array gpio_setup_og { { - { // GPIO0 - .data - = (0 << 9) // P1_2: 10K PD, BOOT1 - | (1 << 8) // P1_1: 10K PU, BOOT0 - | (1 << 7) // P2_7: 10K PU, ISP - , - .dir - = (0 << 9) // P1_2: 10K PD, BOOT1 - | (0 << 8) // P1_1: 10K PU, BOOT0 - | (0 << 7) // P2_7: 10K PU, ISP +static const std::array gpio_setup_og{{ + { + // GPIO0 + .data = (0 << 9) // P1_2: 10K PD, BOOT1 + | (1 << 8) // P1_1: 10K PU, BOOT0 + | (1 << 7) // P2_7: 10K PU, ISP + , + .dir = (0 << 9) // P1_2: 10K PD, BOOT1 + | (0 << 8) // P1_1: 10K PU, BOOT0 + | (0 << 7) // P2_7: 10K PU, ISP }, - { // GPIO1 - .data = 0, - .dir = 0 + {// GPIO1 + .data = 0, + .dir = 0}, + { + // GPIO2 + .data = (1 << 9) // P5_0: !VAA_ENABLE + | (0 << 4) // P4_4: TXENABLE + , + .dir = (1 << 9) // P5_0: !VAA_ENABLE + | (1 << 4) // P4_4: TXENABLE }, - { // GPIO2 - .data - = (1 << 9) // P5_0: !VAA_ENABLE - | (0 << 4) // P4_4: TXENABLE - , - .dir - = (1 << 9) // P5_0: !VAA_ENABLE - | (1 << 4) // P4_4: TXENABLE + { + // GPIO3 + .data = (0 << 6) // P6_10: EN1V8, 10K PD + , + .dir = (1 << 6) // P6_10: EN1V8, 10K PD }, - { // GPIO3 - .data - = (0 << 6) // P6_10: EN1V8, 10K PD - , - .dir - = (1 << 6) // P6_10: EN1V8, 10K PD + {// GPIO4 + .data = 0, + .dir = 0}, + { + // GPIO5 + .data = (0 << 15) // P6_7: TX + | (0 << 12) // P4_8: SGPIO13, HOST_SYNC_EN + | (1 << 5) // P2_5: RX + , + .dir = (1 << 15) // P6_7: TX + | (0 << 12) // P4_8: SGPIO13, HOST_SYNC_EN + | (1 << 5) // P2_5: RX }, - { // GPIO4 - .data = 0, - .dir = 0 - }, - { // GPIO5 - .data - = (0 << 15) // P6_7: TX - | (0 << 12) // P4_8: SGPIO13, HOST_SYNC_EN - | (1 << 5) // P2_5: RX - , - .dir - = (1 << 15) // P6_7: TX - | (0 << 12) // P4_8: SGPIO13, HOST_SYNC_EN - | (1 << 5) // P2_5: RX - }, -} }; +}}; /* Additional GPIO configuration for HackRF r9 */ -static const std::array gpio_setup_r9 { { - { // GPIO0 - .data - = (0 << 9) // P1_2: 10K PD, BOOT1, CLKOUT_EN - | (1 << 8) // P1_1: 10K PU, BOOT0, MCU_CLK_EN - | (1 << 7) // P2_7: 10K PU, ISP, RX - , - .dir - = (0 << 9) // P1_2: 10K PD, BOOT1, CLKOUT_EN - | (0 << 8) // P1_1: 10K PU, BOOT0, MCU_CLK_EN - | (0 << 7) // P2_7: 10K PU, ISP, RX +static const std::array gpio_setup_r9{{ + { + // GPIO0 + .data = (0 << 9) // P1_2: 10K PD, BOOT1, CLKOUT_EN + | (1 << 8) // P1_1: 10K PU, BOOT0, MCU_CLK_EN + | (1 << 7) // P2_7: 10K PU, ISP, RX + , + .dir = (0 << 9) // P1_2: 10K PD, BOOT1, CLKOUT_EN + | (0 << 8) // P1_1: 10K PU, BOOT0, MCU_CLK_EN + | (0 << 7) // P2_7: 10K PU, ISP, RX }, - { // GPIO1 - .data = 0, - .dir = 0 + {// GPIO1 + .data = 0, + .dir = 0}, + { + // GPIO2 + .data = (1 << 9) // P5_0: EN1V8, 10K PD + | (1 << 4) // P4_4: !ANT_BIAS + , + .dir = (1 << 9) // P5_0: EN1V8, 10K PD + | (1 << 4) // P4_4: !ANT_BIAS }, - { // GPIO2 - .data - = (1 << 9) // P5_0: EN1V8, 10K PD - | (1 << 4) // P4_4: !ANT_BIAS - , - .dir - = (1 << 9) // P5_0: EN1V8, 10K PD - | (1 << 4) // P4_4: !ANT_BIAS + { + // GPIO3 + .data = (1 << 6) // P6_10: !VAA_ENABLE + , + .dir = (1 << 6) // P6_10: !VAA_ENABLE }, - { // GPIO3 - .data - = (1 << 6) // P6_10: !VAA_ENABLE - , - .dir - = (1 << 6) // P6_10: !VAA_ENABLE + {// GPIO4 + .data = 0, + .dir = 0}, + { + // GPIO5 + .data = (0 << 15) // P6_7: CLKIN_EN + | (0 << 12) // P4_8: CLKIN_DETECT + | (0 << 5) // P2_5: HOST_SYNC_EN + , + .dir = (1 << 15) // P6_7: CLKIN_EN + | (0 << 12) // P4_8: CLKIN_DETECT + | (0 << 5) // P2_5: HOST_SYNC_EN }, - { // GPIO4 - .data = 0, - .dir = 0 - }, - { // GPIO5 - .data - = (0 << 15) // P6_7: CLKIN_EN - | (0 << 12) // P4_8: CLKIN_DETECT - | (0 << 5) // P2_5: HOST_SYNC_EN - , - .dir - = (1 << 15) // P6_7: CLKIN_EN - | (0 << 12) // P4_8: CLKIN_DETECT - | (0 << 5) // P2_5: HOST_SYNC_EN - }, -} }; +}}; /* Additional SCU configuration for HackRF OG */ -static const std::array pins_setup_og { { +static const std::array pins_setup_og{{ /* Power control */ - { 5, 0, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* !VAA_ENABLE: 10K PU, Q3.G(I), power to VAA */ - { 6, 10, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* EN1V8/P70: 10K PD, TPS62410.EN2(I), 1V8LED.A(I) */ + {5, 0, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* !VAA_ENABLE: 10K PU, Q3.G(I), power to VAA */ + {6, 10, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* EN1V8/P70: 10K PD, TPS62410.EN2(I), 1V8LED.A(I) */ /* Radio section control */ - { 2, 5, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* RX/P43: U7.VCTL1(I), U10.VCTL1(I), U2.VCTL1(I) */ - { 4, 4, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* TXENABLE/P55: MAX2837.TXENABLE(I) */ - { 6, 7, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* TX/P42: U7.VCTL2(I), U10.VCTL2(I), U2.VCTL2(I) */ + {2, 5, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* RX/P43: U7.VCTL1(I), U10.VCTL1(I), U2.VCTL1(I) */ + {4, 4, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* TXENABLE/P55: MAX2837.TXENABLE(I) */ + {6, 7, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* TX/P42: U7.VCTL2(I), U10.VCTL2(I), U2.VCTL2(I) */ /* SGPIO for sample transfer interface to HackRF CPLD. */ - { 4, 8, scu_config_normal_drive_t { .mode=4, .epd=1, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* SGPIO13/BANK2F3M2: CPLD.90/HOST_SYNC_EN(I) */ + {4, 8, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* SGPIO13/BANK2F3M2: CPLD.90/HOST_SYNC_EN(I) */ /* Miscellaneous */ - { 1, 1, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* P1_1/P74: 10K PU, BOOT0 */ - { 1, 2, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* P1_2/P73: 10K PD, BOOT1 */ - { 2, 7, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* ISP: 10K PU, Unused */ -} }; + {1, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* P1_1/P74: 10K PU, BOOT0 */ + {1, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* P1_2/P73: 10K PD, BOOT1 */ + {2, 7, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* ISP: 10K PU, Unused */ +}}; /* Additional SCU configuration for HackRF r9 */ -static const std::array pins_setup_r9 { { +static const std::array pins_setup_r9{{ /* Power control */ - { 6, 10, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* !VAA_ENABLE: 10K PU, Q3.G(I), power to VAA */ - { 5, 0, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* EN1V8: 10K PD, TPS62410.EN2(I), 1V8LED.A(I) */ + {6, 10, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* !VAA_ENABLE: 10K PU, Q3.G(I), power to VAA */ + {5, 0, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* EN1V8: 10K PD, TPS62410.EN2(I), 1V8LED.A(I) */ /* Radio section control */ - { 2, 7, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* RX/ISP/P96: U7.VCTL(I), U10.VCTL(I), U2.VCTL(I) */ - { 4, 4, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* !ANT_BIAS: 10K PU, Q4.G(I) */ + {2, 7, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* RX/ISP/P96: U7.VCTL(I), U10.VCTL(I), U2.VCTL(I) */ + {4, 4, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* !ANT_BIAS: 10K PU, Q4.G(I) */ /* SGPIO for sample transfer interface to HackRF CPLD. */ - { 2, 5, scu_config_normal_drive_t { .mode=4, .epd=1, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* BANK2F3M2: CPLD.90/HOST_SYNC_EN(I) */ + {2, 5, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* BANK2F3M2: CPLD.90/HOST_SYNC_EN(I) */ /* Clock control */ - { 1, 1, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* MCU_CLK_EN/BOOT0: 10K PU, U28.1A(I) */ - { 1, 2, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* CLKOUT_EN/BOOT1: 10K PD, U28.2A(I) */ - { 6, 7, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* CLKIN_EN: U16.SEL(I), U26.1A(I) */ + {1, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* MCU_CLK_EN/BOOT0: 10K PU, U28.1A(I) */ + {1, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* CLKOUT_EN/BOOT1: 10K PD, U28.2A(I) */ + {6, 7, scu_config_normal_drive_t{.mode = 4, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* CLKIN_EN: U16.SEL(I), U26.1A(I) */ /* Miscellaneous */ - { 4, 8, scu_config_normal_drive_t { .mode=1, .epd=1, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* CLKIN_DETECT: U26.2Y(O) */ -} }; + {4, 8, scu_config_normal_drive_t{.mode = 1, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* CLKIN_DETECT: U26.2Y(O) */ +}}; #endif #ifdef PRALINE -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, 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 */ - { 7, 0, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_8: PortaPack GPIO3_8(IO) */ - { 7, 1, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_9: PortaPack GPIO3_9(IO) */ - { 7, 2, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_10: PortaPack GPIO3_10(IO) */ - { 7, 3, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_11: PortaPack GPIO3_11(IO) */ - { 7, 4, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_12: PortaPack GPIO3_12(IO) */ - { 7, 5, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_13: PortaPack GPIO3_13(IO) */ - { 7, 6, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_14: PortaPack GPIO3_14(IO) */ - { 7, 7, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_15: PortaPack GPIO3_15(IO) */ +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, 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 */ + {7, 0, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_8: PortaPack GPIO3_8(IO) */ + {7, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_9: PortaPack GPIO3_9(IO) */ + {7, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_10: PortaPack GPIO3_10(IO) */ + {7, 3, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_11: PortaPack GPIO3_11(IO) */ + {7, 4, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_12: PortaPack GPIO3_12(IO) */ + {7, 5, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_13: PortaPack GPIO3_13(IO) */ + {7, 6, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_14: PortaPack GPIO3_14(IO) */ + {7, 7, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_15: PortaPack GPIO3_15(IO) */ /* PortaPack: Audio */ - { 3, 0, scu_config_normal_drive_t { .mode=2, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=0 } }, /* I2S0_TX_SCK: PortaPack I2S0_TX_SCK(I) */ - { 3, 1, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=0 } }, /* I2S0_RX_WS: PortaPack I2S0_TX_WS(I). Input enabled to fold back into RX. */ - { 3, 2, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=0, .ehs=0, .ezi=0, .zif=0 } }, /* I2S0_RX_SDA: PortaPack I2S0_TX_SDA(I) */ - { 24, 2, scu_config_normal_drive_t { .mode=6, .epd=1, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* I2S0_TX_CLK: PortaPack I2S0_TX_MCLK */ + {3, 0, scu_config_normal_drive_t{.mode = 2, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, /* I2S0_TX_SCK: PortaPack I2S0_TX_SCK(I) */ + {3, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, /* I2S0_RX_WS: PortaPack I2S0_TX_WS(I). Input enabled to fold back into RX. */ + {3, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* I2S0_RX_SDA: PortaPack I2S0_TX_SDA(I) */ + {24, 2, scu_config_normal_drive_t{.mode = 6, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* I2S0_TX_CLK: PortaPack I2S0_TX_MCLK */ /* PortaPack: SD card socket */ - { 24, 0, scu_config_normal_drive_t { .mode=4, .epd=1, .epun=1, .ehs=0, .ezi=1, .zif=1 } }, /* SD_CLK: PortaPack SD.CLK, enable input buffer for timing feedback? */ - { 1, 6, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=1 } }, /* SD_CMD: PortaPack SD.CMD(IO) */ - { 1, 9, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=1 } }, /* SD_DAT0: PortaPack SD.DAT0(IO) */ - { 1, 10, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=1 } }, /* SD_DAT1: PortaPack SD.DAT1(IO) */ - { 1, 11, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=1 } }, /* SD_DAT2: PortaPack SD.DAT2(IO) */ - { 1, 12, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=1 } }, /* SD_DAT3: PortaPack SD.DAT3(IO) */ - { 1, 13, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=0 } }, /* SD_CD: PortaPack SD.CD(O) */ + {24, 0, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 1, .zif = 1}}, /* SD_CLK: PortaPack SD.CLK, enable input buffer for timing feedback? */ + {1, 6, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, /* SD_CMD: PortaPack SD.CMD(IO) */ + {1, 9, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, /* SD_DAT0: PortaPack SD.DAT0(IO) */ + {1, 10, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, /* SD_DAT1: PortaPack SD.DAT1(IO) */ + {1, 11, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, /* SD_DAT2: PortaPack SD.DAT2(IO) */ + {1, 12, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, /* SD_DAT3: PortaPack SD.DAT3(IO) */ + {1, 13, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, /* SD_CD: PortaPack SD.CD(O) */ // for pro touch // those pins should choose reserved function mode // and the behavior same as hackrf one(YN YP XN XP) - { 11, 6, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=0, .zif=0 } }, /* PB_6: ADC0_0 yp*/ - { 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*/ -} }; + {11, 6, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* PB_6: ADC0_0 yp*/ + {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*/ +}}; #else -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, 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 */ - { 7, 0, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_8: PortaPack GPIO3_8(IO) */ - { 7, 1, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_9: PortaPack GPIO3_9(IO) */ - { 7, 2, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_10: PortaPack GPIO3_10(IO) */ - { 7, 3, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_11: PortaPack GPIO3_11(IO) */ - { 7, 4, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_12: PortaPack GPIO3_12(IO) */ - { 7, 5, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_13: PortaPack GPIO3_13(IO) */ - { 7, 6, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_14: PortaPack GPIO3_14(IO) */ - { 7, 7, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_15: PortaPack GPIO3_15(IO) */ +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, 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 */ + {7, 0, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_8: PortaPack GPIO3_8(IO) */ + {7, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_9: PortaPack GPIO3_9(IO) */ + {7, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_10: PortaPack GPIO3_10(IO) */ + {7, 3, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_11: PortaPack GPIO3_11(IO) */ + {7, 4, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_12: PortaPack GPIO3_12(IO) */ + {7, 5, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_13: PortaPack GPIO3_13(IO) */ + {7, 6, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_14: PortaPack GPIO3_14(IO) */ + {7, 7, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}, /* GPIO3_15: PortaPack GPIO3_15(IO) */ /* PortaPack: Audio */ - { 3, 0, scu_config_normal_drive_t { .mode=2, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=0 } }, /* I2S0_TX_SCK: PortaPack I2S0_TX_SCK(I) */ - { 3, 1, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=0 } }, /* I2S0_RX_WS: PortaPack I2S0_TX_WS(I). Input enabled to fold back into RX. */ - { 3, 2, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=0, .ehs=0, .ezi=0, .zif=0 } }, /* I2S0_RX_SDA: PortaPack I2S0_TX_SDA(I) */ - { 24, 2, scu_config_normal_drive_t { .mode=6, .epd=1, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* I2S0_TX_CLK: PortaPack I2S0_TX_MCLK */ + {3, 0, scu_config_normal_drive_t{.mode = 2, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, /* I2S0_TX_SCK: PortaPack I2S0_TX_SCK(I) */ + {3, 1, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, /* I2S0_RX_WS: PortaPack I2S0_TX_WS(I). Input enabled to fold back into RX. */ + {3, 2, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 0, .ehs = 0, .ezi = 0, .zif = 0}}, /* I2S0_RX_SDA: PortaPack I2S0_TX_SDA(I) */ + {24, 2, scu_config_normal_drive_t{.mode = 6, .epd = 1, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}}, /* I2S0_TX_CLK: PortaPack I2S0_TX_MCLK */ /* PortaPack: SD card socket */ - { 24, 0, scu_config_normal_drive_t { .mode=4, .epd=1, .epun=1, .ehs=0, .ezi=1, .zif=1 } }, /* SD_CLK: PortaPack SD.CLK, enable input buffer for timing feedback? */ - { 1, 6, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=1 } }, /* SD_CMD: PortaPack SD.CMD(IO) */ - { 1, 9, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=1 } }, /* SD_DAT0: PortaPack SD.DAT0(IO) */ - { 1, 10, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=1 } }, /* SD_DAT1: PortaPack SD.DAT1(IO) */ - { 1, 11, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=1 } }, /* SD_DAT2: PortaPack SD.DAT2(IO) */ - { 1, 12, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=1 } }, /* SD_DAT3: PortaPack SD.DAT3(IO) */ - { 1, 13, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=0 } }, /* SD_CD: PortaPack SD.CD(O) */ -} }; + {24, 0, scu_config_normal_drive_t{.mode = 4, .epd = 1, .epun = 1, .ehs = 0, .ezi = 1, .zif = 1}}, /* SD_CLK: PortaPack SD.CLK, enable input buffer for timing feedback? */ + {1, 6, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, /* SD_CMD: PortaPack SD.CMD(IO) */ + {1, 9, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, /* SD_DAT0: PortaPack SD.DAT0(IO) */ + {1, 10, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, /* SD_DAT1: PortaPack SD.DAT1(IO) */ + {1, 11, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, /* SD_DAT2: PortaPack SD.DAT2(IO) */ + {1, 12, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 1}}, /* SD_DAT3: PortaPack SD.DAT3(IO) */ + {1, 13, scu_config_normal_drive_t{.mode = 7, .epd = 0, .epun = 0, .ehs = 0, .ezi = 1, .zif = 0}}, /* SD_CD: PortaPack SD.CD(O) */ +}}; #endif -static const std::array pins_setup_spifi { { - { 3, 3, scu_config_normal_drive_t { .mode=3, .epd=0, .epun=1, .ehs=1, .ezi=1, .zif=1 } }, /* SPIFI_SCK: W25Q80BV.CLK(I), enable input buffer for timing feedback */ - { 3, 4, scu_config_normal_drive_t { .mode=3, .epd=0, .epun=1, .ehs=1, .ezi=1, .zif=1 } }, /* SPIFI_SIO3/P82: W25Q80BV.HOLD(IO) */ - { 3, 5, scu_config_normal_drive_t { .mode=3, .epd=0, .epun=1, .ehs=1, .ezi=1, .zif=1 } }, /* SPIFI_SIO2/P81: W25Q80BV.WP(IO) */ - { 3, 6, scu_config_normal_drive_t { .mode=3, .epd=0, .epun=1, .ehs=1, .ezi=1, .zif=1 } }, /* SPIFI_MISO: W25Q80BV.DO(IO) */ - { 3, 7, scu_config_normal_drive_t { .mode=3, .epd=0, .epun=1, .ehs=1, .ezi=1, .zif=1 } }, /* SPIFI_MOSI: W25Q80BV.DI(IO) */ - { 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) */ -} }; +static const std::array pins_setup_spifi{{ + {3, 3, scu_config_normal_drive_t{.mode = 3, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, /* SPIFI_SCK: W25Q80BV.CLK(I), enable input buffer for timing feedback */ + {3, 4, scu_config_normal_drive_t{.mode = 3, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, /* SPIFI_SIO3/P82: W25Q80BV.HOLD(IO) */ + {3, 5, scu_config_normal_drive_t{.mode = 3, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, /* SPIFI_SIO2/P81: W25Q80BV.WP(IO) */ + {3, 6, scu_config_normal_drive_t{.mode = 3, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, /* SPIFI_MISO: W25Q80BV.DO(IO) */ + {3, 7, scu_config_normal_drive_t{.mode = 3, .epd = 0, .epun = 1, .ehs = 1, .ezi = 1, .zif = 1}}, /* SPIFI_MOSI: W25Q80BV.DI(IO) */ + {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 +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; + LPC_GPIO->PIN[i] |= pins_setup[i].data; + LPC_GPIO->DIR[i] |= pins_setup[i].dir; } } @@ -641,9 +620,9 @@ static void setup_pin(const scu_setup_t& pin_setup) { LPC_SCU->SFSP[pin_setup.port][pin_setup.pin] = pin_setup.config; } -template +template void setup_pins(const std::array& pins_setup) { - for(const auto& pin_setup : pins_setup) { + for (const auto& pin_setup : pins_setup) { setup_pin(pin_setup); } } @@ -652,7 +631,7 @@ void setup_pins(const std::array& pins_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). */ -static const scu_setup_t pin_setup_detect { 5, 0, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }; +static const scu_setup_t pin_setup_detect{5, 0, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 1, .zif = 0}}; /* Check resistor on GPIO2_9 (P5_0) to detect HackRF hardware revision. */ extern "C" bool detect_hackrf_r9() { @@ -666,46 +645,46 @@ static void configure_spifi(void) { /* Tweak SPIFI mode */ LPC_SPIFI->CTRL = - (0xffff << 0) /* Timeout */ - | (0x1 << 16) /* CS high time in "clocks - 1" */ - | (0 << 21) /* 0: Attempt speculative prefetch on data accesses */ - | (0 << 22) /* 0: No interrupt on command ended */ - | (0 << 23) /* 0: SCK driven low after rising edge at which last bit of command is captured. Stays low while CS# is high. */ - | (0 << 27) /* 0: Cache prefetching enabled */ - | (0 << 28) /* 0: Quad protocol, IO3:0 */ - | (1 << 29) /* 1: Read data sampled on falling edge of clock */ - | (1 << 30) /* 1: Read data is sampled using feedback clock from SCK pin */ - | (0 << 31) /* 0: DMA request disabled */ + (0xffff << 0) /* Timeout */ + | (0x1 << 16) /* CS high time in "clocks - 1" */ + | (0 << 21) /* 0: Attempt speculative prefetch on data accesses */ + | (0 << 22) /* 0: No interrupt on command ended */ + | (0 << 23) /* 0: SCK driven low after rising edge at which last bit of command is captured. Stays low while CS# is high. */ + | (0 << 27) /* 0: Cache prefetching enabled */ + | (0 << 28) /* 0: Quad protocol, IO3:0 */ + | (1 << 29) /* 1: Read data sampled on falling edge of clock */ + | (1 << 30) /* 1: Read data is sampled using feedback clock from SCK pin */ + | (0 << 31) /* 0: DMA request disabled */ ; /* Throttle up the SPIFI interface to 96MHz (IDIVA=PLL1 / 3) */ LPC_CGU->IDIVB_CTRL.word = - ( 0 << 0) /* PD */ - | ( 2 << 2) /* IDIV (/3) */ - | ( 1 << 11) /* AUTOBLOCK */ - | ( 9 << 24) /* PLL1 */ + (0 << 0) /* PD */ + | (2 << 2) /* IDIV (/3) */ + | (1 << 11) /* AUTOBLOCK */ + | (9 << 24) /* PLL1 */ ; } 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); + 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 }, + .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 } }; +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 } }; +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: @@ -719,74 +698,77 @@ static const scu_setup_t pin_setup_vaa_disable_praline = { 8, 1, scu_config_norm * 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. + /* 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... */ - 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; + 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); } - } 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; - } + // 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; + } } /** @@ -817,10 +799,10 @@ extern "C" void __early_init(void) { * Before __early_init, LPC bootloader runs and starts our code. In user code, the process stack * is initialized, hardware floating point is initialized, and stacks are zeroed, */ - const uint32_t CORTEX_M4_CPUID = 0x410fc240; + const uint32_t CORTEX_M4_CPUID = 0x410fc240; const uint32_t CORTEX_M4_CPUID_MASK = 0xff0ffff0; - if( (SCB->CPUID & CORTEX_M4_CPUID_MASK) == CORTEX_M4_CPUID ) { + if ((SCB->CPUID & CORTEX_M4_CPUID_MASK) == CORTEX_M4_CPUID) { /* Enable unaligned exception handler */ SCB_CCR |= (1 << 3); @@ -837,42 +819,42 @@ extern "C" void __early_init(void) { * WWDT, CREG, SCU, SPIFI */ LPC_RGU->RESET_CTRL[0] = - (1U << 16) // LCD_RST - | (1U << 17) // USB0_RST - | (1U << 18) // USB1_RST - | (1U << 19) // DMA_RST - | (1U << 20) // SDIO_RST - | (1U << 21) // EMC_RST - | (1U << 22) // ETHERNET_RST - | (1U << 28) // GPIO_RST + (1U << 16) // LCD_RST + | (1U << 17) // USB0_RST + | (1U << 18) // USB1_RST + | (1U << 19) // DMA_RST + | (1U << 20) // SDIO_RST + | (1U << 21) // EMC_RST + | (1U << 22) // ETHERNET_RST + | (1U << 28) // GPIO_RST ; LPC_RGU->RESET_CTRL[1] = - (1U << 0) // TIMER0_RST - | (1U << 1) // TIMER1_RST - | (1U << 2) // TIMER2_RST - | (1U << 3) // TIMER3_RST - | (1U << 4) // RITIMER_RST - | (1U << 5) // SCT_RST - | (1U << 6) // MOTOCONPWM_RST - | (1U << 7) // QEI_RST - | (1U << 8) // ADC0_RST - | (1U << 9) // ADC1_RST - | (1U << 10) // DAC_RST - | (1U << 12) // UART0_RST - | (1U << 13) // UART1_RST - | (1U << 14) // UART2_RST - | (1U << 15) // UART3_RST - | (1U << 16) // I2C0_RST - | (1U << 17) // I2C1_RST - | (1U << 18) // SSP0_RST - | (1U << 19) // SSP1_RST - | (1U << 20) // I2S_RST - | (1U << 22) // CAN1_RST - | (1U << 23) // CAN0_RST - | (1U << 24) // M0APP_RST - | (1U << 25) // SGPIO_RST - | (1U << 26) // SPI_RST - | (1U << 28) // ADCHS_RST + (1U << 0) // TIMER0_RST + | (1U << 1) // TIMER1_RST + | (1U << 2) // TIMER2_RST + | (1U << 3) // TIMER3_RST + | (1U << 4) // RITIMER_RST + | (1U << 5) // SCT_RST + | (1U << 6) // MOTOCONPWM_RST + | (1U << 7) // QEI_RST + | (1U << 8) // ADC0_RST + | (1U << 9) // ADC1_RST + | (1U << 10) // DAC_RST + | (1U << 12) // UART0_RST + | (1U << 13) // UART1_RST + | (1U << 14) // UART2_RST + | (1U << 15) // UART3_RST + | (1U << 16) // I2C0_RST + | (1U << 17) // I2C1_RST + | (1U << 18) // SSP0_RST + | (1U << 19) // SSP1_RST + | (1U << 20) // I2S_RST + | (1U << 22) // CAN1_RST + | (1U << 23) // CAN0_RST + | (1U << 24) // M0APP_RST + | (1U << 25) // SGPIO_RST + | (1U << 26) // SPI_RST + | (1U << 28) // ADCHS_RST ; configure_spifi(); @@ -884,7 +866,7 @@ extern "C" void __early_init(void) { /* Prevent the M4 from doing any more initializing by sleep-waiting forever... * ...until the M0 resets the M4 with some code to run. */ - while(1) { + while (1) { __WFE(); } } @@ -913,196 +895,237 @@ extern "C" void __late_init(void) { */ 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--); } + /* 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--); } + /* 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--); + } - /* 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--); } + /* 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 */ + /* 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_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 */ + /* 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--); } + /* 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 */ + /* 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_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--); } + /* 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 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 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 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 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--); + } - /* 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 */ + /* 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--); + } - /* 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--); } + /* Ensure RESETX is stable */ + for (volatile int i = 0; i < 10; i++) { + LPC_GPIO->W2[14] = 1; + } - /* 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--); } + /* 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--); + } - // 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); + /* 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 */ - // 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--); } + /* 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--); + } #else - /* Detect HackRF variant */ - /* 1. Perform Standard Initialization first */ - /* This configures VAA power, LED pins, and detects board revision */ - /* Let detect_hackrf_r9() run - don't force for PRALINE */ - hackrf_r9 = detect_hackrf_r9(); - /* Configure variant-dependent pins. */ - if (hackrf_r9) { - setup_gpios(gpio_setup_r9); - setup_pins(pins_setup_r9); - } else { - setup_gpios(gpio_setup_og); - setup_pins(pins_setup_og); - } + /* Detect HackRF variant */ + /* 1. Perform Standard Initialization first */ + /* This configures VAA power, LED pins, and detects board revision */ + /* Let detect_hackrf_r9() run - don't force for PRALINE */ + hackrf_r9 = detect_hackrf_r9(); + /* Configure variant-dependent pins. */ + if (hackrf_r9) { + setup_gpios(gpio_setup_r9); + setup_pins(pins_setup_r9); + } else { + setup_gpios(gpio_setup_og); + setup_pins(pins_setup_og); + } - /* 2. Turn on VAA (Critical for Radio/Transceiver) */ - vaa_power_on(); + /* 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; - } + /* 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; + LPC_GPIO->W2[9] = 0; } else { - LPC_GPIO->W3[6] = 0; + LPC_GPIO->W3[6] = 0; } vaa_power_off(); @@ -1114,41 +1137,41 @@ extern "C" void _default_exit(void) { * WWDT, CREG, SCU, SPIFI, GPIO, M0APP */ LPC_RGU->RESET_CTRL[0] = - (1U << 16) // LCD_RST - | (1U << 17) // USB0_RST - | (1U << 18) // USB1_RST - | (1U << 19) // DMA_RST - | (1U << 20) // SDIO_RST - | (1U << 21) // EMC_RST - | (1U << 22) // ETHERNET_RST + (1U << 16) // LCD_RST + | (1U << 17) // USB0_RST + | (1U << 18) // USB1_RST + | (1U << 19) // DMA_RST + | (1U << 20) // SDIO_RST + | (1U << 21) // EMC_RST + | (1U << 22) // ETHERNET_RST //| (1U << 28) // GPIO_RST ; LPC_RGU->RESET_CTRL[1] = - (1U << 0) // TIMER0_RST - | (1U << 1) // TIMER1_RST - | (1U << 2) // TIMER2_RST - | (1U << 3) // TIMER3_RST - | (1U << 4) // RITIMER_RST - | (1U << 5) // SCT_RST - | (1U << 6) // MOTOCONPWM_RST - | (1U << 7) // QEI_RST - | (1U << 8) // ADC0_RST - | (1U << 9) // ADC1_RST - | (1U << 10) // DAC_RST - | (1U << 12) // UART0_RST - | (1U << 13) // UART1_RST - | (1U << 14) // UART2_RST - | (1U << 15) // UART3_RST - | (1U << 16) // I2C0_RST - | (1U << 17) // I2C1_RST - | (1U << 18) // SSP0_RST - | (1U << 19) // SSP1_RST - | (1U << 20) // I2S_RST - | (1U << 22) // CAN1_RST - | (1U << 23) // CAN0_RST + (1U << 0) // TIMER0_RST + | (1U << 1) // TIMER1_RST + | (1U << 2) // TIMER2_RST + | (1U << 3) // TIMER3_RST + | (1U << 4) // RITIMER_RST + | (1U << 5) // SCT_RST + | (1U << 6) // MOTOCONPWM_RST + | (1U << 7) // QEI_RST + | (1U << 8) // ADC0_RST + | (1U << 9) // ADC1_RST + | (1U << 10) // DAC_RST + | (1U << 12) // UART0_RST + | (1U << 13) // UART1_RST + | (1U << 14) // UART2_RST + | (1U << 15) // UART3_RST + | (1U << 16) // I2C0_RST + | (1U << 17) // I2C1_RST + | (1U << 18) // SSP0_RST + | (1U << 19) // SSP1_RST + | (1U << 20) // I2S_RST + | (1U << 22) // CAN1_RST + | (1U << 23) // CAN0_RST //| (1U << 24) // M0APP_RST - | (1U << 25) // SGPIO_RST - | (1U << 26) // SPI_RST - | (1U << 28) // ADCHS_RST + | (1U << 25) // SGPIO_RST + | (1U << 26) // SPI_RST + | (1U << 28) // ADCHS_RST ; -} +} \ No newline at end of file diff --git a/firmware/chibios-portapack/os/hal/platforms/LPC43xx/lpc43xx.inc b/firmware/chibios-portapack/os/hal/platforms/LPC43xx/lpc43xx.inc index 9d044392f..2d5ff2b05 100644 --- a/firmware/chibios-portapack/os/hal/platforms/LPC43xx/lpc43xx.inc +++ b/firmware/chibios-portapack/os/hal/platforms/LPC43xx/lpc43xx.inc @@ -1167,6 +1167,21 @@ typedef struct { __IO uint32_t AYRS; } LPC_RTC_Type; +// ------------------------------------------------------------------------------------------------ +// ----- EVENT ROUTER ----- +// ------------------------------------------------------------------------------------------------ + +typedef struct { + __IO uint32_t HILO; /* +0x000 */ + __IO uint32_t EDGE; /* +0x004 */ + __O uint32_t CLR_EN; /* +0x008 */ + __O uint32_t SET_EN; /* +0x00C */ + __I uint32_t STATUS; /* +0x010 */ + __I uint32_t ENABLE; /* +0x014 */ + __O uint32_t CLR_STAT; /* +0x018 */ + __O uint32_t SET_STAT; /* +0x01C */ +} LPC_EVENTROUTER_Type; + // ------------------------------------------------------------------------------------------------ // ----- USART0/2/3 ----- // ------------------------------------------------------------------------------------------------ @@ -1466,6 +1481,7 @@ typedef struct { #define LPC_ADC1 ((LPC_ADCx_Type *) LPC_ADC1_BASE) #define LPC_GPIO ((LPC_GPIO_Type *) LPC_GPIO_BASE) #define LPC_SGPIO ((LPC_SGPIO_Type *) LPC_SGPIO_BASE) +#define LPC_EVENTROUTER ((LPC_EVENTROUTER_Type *) LPC_EVENT_ROUTER_BASE) #ifdef __cplusplus } diff --git a/firmware/common/hackrf_gpio.hpp b/firmware/common/hackrf_gpio.hpp index 459bea7c5..1e79138d0 100644 --- a/firmware/common/hackrf_gpio.hpp +++ b/firmware/common/hackrf_gpio.hpp @@ -128,7 +128,8 @@ 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 // 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) diff --git a/firmware/common/i2cdev_ppmod.cpp b/firmware/common/i2cdev_ppmod.cpp index 96d954de3..668437ac6 100644 --- a/firmware/common/i2cdev_ppmod.cpp +++ b/firmware/common/i2cdev_ppmod.cpp @@ -246,7 +246,9 @@ bool I2cDev_PPmod::send_poweroff_command() { if (isLocked()) return false; // device is busy Command cmd = Command::COMMAND_POWER_OFF; uint8_t tmp = 0; // result of the ack. 0 = no, 1 = ok - i2c_read((uint8_t*)&cmd, 2, &tmp, 1); + if (!i2c_read((uint8_t*)&cmd, 2, &tmp, 1)) { + return false; + } return (tmp == 1); } diff --git a/firmware/common/pins.hpp b/firmware/common/pins.hpp index 15fb1b285..4506f0784 100644 --- a/firmware/common/pins.hpp +++ b/firmware/common/pins.hpp @@ -115,7 +115,9 @@ enum Pins { PA_1, PA_2, // Port 8 pins (PRALINE power control and LED4) - P8_1, + P8_1, // VAA_EN + P8_4, // VBUS_IN_EN + P8_5, // VIN_IN_EN P8_6, P8_7, // Port E pins (PRALINE transceiver control) @@ -227,6 +229,8 @@ constexpr Pin pins[]{ [PA_2] = {0xA, 2}, // Port 8 pins [P8_1] = {8, 1}, + [P8_4] = {8, 4}, + [P8_5] = {8, 5}, [P8_6] = {8, 6}, [P8_7] = {8, 7}, // Port E pins (function 4 = GPIO) @@ -333,6 +337,8 @@ enum GPIOs { GPIO4_14, // Power control and LED4 GPIO4_1, + GPIO8_4, + GPIO8_5, GPIO4_6, GPIO4_7, // RF path control @@ -445,6 +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_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 @@ -462,6 +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_6] = {pins[P0_0], 4, 6, 0}, [GPIO4_7] = {pins[P0_0], 4, 7, 0}, [GPIO4_8] = {pins[P0_0], 4, 8, 0},