From ea2ca45cf96e359f85c09dbfc6b80dbe49e006ec Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Mon, 29 Dec 2025 17:15:20 +1300 Subject: [PATCH] boards: add support for Gear Up AirBrainH743 --- .../gearup/airbrainh743/bootloader.px4board | 3 + boards/gearup/airbrainh743/default.px4board | 85 +++++ .../extras/gearup_airbrainh743_bootloader.bin | Bin 0 -> 42648 bytes boards/gearup/airbrainh743/firmware.prototype | 13 + .../airbrainh743/init/rc.board_defaults | 17 + .../gearup/airbrainh743/init/rc.board_extras | 6 + .../gearup/airbrainh743/init/rc.board_sensors | 16 + .../gearup/airbrainh743/nuttx-config/Kconfig | 3 + .../nuttx-config/bootloader/defconfig | 89 +++++ .../airbrainh743/nuttx-config/include/board.h | 339 ++++++++++++++++++ .../nuttx-config/include/board_dma_map.h | 42 +++ .../airbrainh743/nuttx-config/nsh/defconfig | 257 +++++++++++++ .../nuttx-config/scripts/bootloader_script.ld | 213 +++++++++++ .../nuttx-config/scripts/script.ld | 228 ++++++++++++ boards/gearup/airbrainh743/src/CMakeLists.txt | 67 ++++ boards/gearup/airbrainh743/src/board_config.h | 216 +++++++++++ .../gearup/airbrainh743/src/bootloader_main.c | 75 ++++ boards/gearup/airbrainh743/src/hw_config.h | 85 +++++ boards/gearup/airbrainh743/src/i2c.cpp | 45 +++ boards/gearup/airbrainh743/src/init.c | 228 ++++++++++++ boards/gearup/airbrainh743/src/led.c | 205 +++++++++++ boards/gearup/airbrainh743/src/spi.cpp | 58 +++ .../gearup/airbrainh743/src/timer_config.cpp | 70 ++++ boards/gearup/airbrainh743/src/usb.c | 75 ++++ docs/en/SUMMARY.md | 1 + .../autopilot_manufacturer_supported.md | 1 + .../flight_controller/gearup_airbrainh743.md | 96 +++++ 27 files changed, 2533 insertions(+) create mode 100644 boards/gearup/airbrainh743/bootloader.px4board create mode 100644 boards/gearup/airbrainh743/default.px4board create mode 100755 boards/gearup/airbrainh743/extras/gearup_airbrainh743_bootloader.bin create mode 100644 boards/gearup/airbrainh743/firmware.prototype create mode 100644 boards/gearup/airbrainh743/init/rc.board_defaults create mode 100644 boards/gearup/airbrainh743/init/rc.board_extras create mode 100644 boards/gearup/airbrainh743/init/rc.board_sensors create mode 100644 boards/gearup/airbrainh743/nuttx-config/Kconfig create mode 100644 boards/gearup/airbrainh743/nuttx-config/bootloader/defconfig create mode 100644 boards/gearup/airbrainh743/nuttx-config/include/board.h create mode 100644 boards/gearup/airbrainh743/nuttx-config/include/board_dma_map.h create mode 100644 boards/gearup/airbrainh743/nuttx-config/nsh/defconfig create mode 100644 boards/gearup/airbrainh743/nuttx-config/scripts/bootloader_script.ld create mode 100644 boards/gearup/airbrainh743/nuttx-config/scripts/script.ld create mode 100644 boards/gearup/airbrainh743/src/CMakeLists.txt create mode 100644 boards/gearup/airbrainh743/src/board_config.h create mode 100644 boards/gearup/airbrainh743/src/bootloader_main.c create mode 100644 boards/gearup/airbrainh743/src/hw_config.h create mode 100644 boards/gearup/airbrainh743/src/i2c.cpp create mode 100644 boards/gearup/airbrainh743/src/init.c create mode 100644 boards/gearup/airbrainh743/src/led.c create mode 100644 boards/gearup/airbrainh743/src/spi.cpp create mode 100644 boards/gearup/airbrainh743/src/timer_config.cpp create mode 100644 boards/gearup/airbrainh743/src/usb.c create mode 100644 docs/en/flight_controller/gearup_airbrainh743.md diff --git a/boards/gearup/airbrainh743/bootloader.px4board b/boards/gearup/airbrainh743/bootloader.px4board new file mode 100644 index 0000000000..19b6e662be --- /dev/null +++ b/boards/gearup/airbrainh743/bootloader.px4board @@ -0,0 +1,3 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ROMFSROOT="" diff --git a/boards/gearup/airbrainh743/default.px4board b/boards/gearup/airbrainh743/default.px4board new file mode 100644 index 0000000000..bcb4b2b786 --- /dev/null +++ b/boards/gearup/airbrainh743/default.px4board @@ -0,0 +1,85 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS6" +CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS3" +CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS4" +CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS5" +CONFIG_BOARD_SERIAL_TEL4="/dev/ttyS2" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS1" +CONFIG_DRIVERS_ADC_BOARD_ADC=y +CONFIG_DRIVERS_BAROMETER_DPS310=y +CONFIG_DRIVERS_CDCACM_AUTOSTART=y +CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y +CONFIG_COMMON_DISTANCE_SENSOR=y +CONFIG_DRIVERS_DSHOT=y +CONFIG_DRIVERS_GPS=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y +CONFIG_COMMON_LIGHT=y +CONFIG_DRIVERS_MAGNETOMETER_HMC5883=y +CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y +CONFIG_DRIVERS_MAGNETOMETER_LIS3MDL=y +CONFIG_DRIVERS_MAGNETOMETER_QMC5883L=y +CONFIG_DRIVERS_MAGNETOMETER_ST_IIS2MDC=y +CONFIG_DRIVERS_OSD_MSP_OSD=y +CONFIG_COMMON_OPTICAL_FLOW=y +CONFIG_DRIVERS_PWM_OUT=y +CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_TELEMETRY=y +CONFIG_DRIVERS_TONE_ALARM=y +CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y +CONFIG_MODULES_BATTERY_STATUS=y +CONFIG_MODULES_COMMANDER=y +CONFIG_MODULES_CONTROL_ALLOCATOR=y +CONFIG_MODULES_DATAMAN=y +CONFIG_MODULES_EKF2=y +# CONFIG_EKF2_AUX_GLOBAL_POSITION is not set +# CONFIG_EKF2_AUXVEL is not set +# CONFIG_EKF2_BARO_COMPENSATION is not set +# CONFIG_EKF2_DRAG_FUSION is not set +# CONFIG_EKF2_GNSS_YAW is not set +# CONFIG_EKF2_SIDESLIP is not set +CONFIG_MODULES_EVENTS=y +CONFIG_MODULES_FLIGHT_MODE_MANAGER=y +CONFIG_MODULES_FW_ATT_CONTROL=y +CONFIG_MODULES_FW_MODE_MANAGER=y +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=y +CONFIG_MODULES_FW_RATE_CONTROL=y +CONFIG_MODULES_GYRO_CALIBRATION=y +CONFIG_MODULES_GYRO_FFT=y +CONFIG_MODULES_LAND_DETECTOR=y +CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y +CONFIG_MODULES_LOAD_MON=y +CONFIG_MODULES_LOGGER=y +CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y +CONFIG_MODULES_MANUAL_CONTROL=y +CONFIG_MODULES_MAVLINK=y +CONFIG_MODULES_MC_ATT_CONTROL=y +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y +CONFIG_MODULES_MC_POS_CONTROL=y +CONFIG_MODULES_MC_RATE_CONTROL=y +CONFIG_MODULES_NAVIGATOR=y +CONFIG_MODULES_RC_UPDATE=y +CONFIG_MODULES_SENSORS=y +CONFIG_MODULES_UXRCE_DDS_CLIENT=y +CONFIG_MODULES_VTOL_ATT_CONTROL=y +CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y +CONFIG_SYSTEMCMDS_BSONDUMP=y +CONFIG_SYSTEMCMDS_DMESG=y +CONFIG_SYSTEMCMDS_GPIO=y +CONFIG_SYSTEMCMDS_HARDFAULT_LOG=y +CONFIG_SYSTEMCMDS_I2CDETECT=y +CONFIG_SYSTEMCMDS_LED_CONTROL=y +CONFIG_SYSTEMCMDS_MFT=y +CONFIG_SYSTEMCMDS_MTD=y +CONFIG_SYSTEMCMDS_NSHTERM=y +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_TUNE_CONTROL=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_USB_CONNECTED=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y diff --git a/boards/gearup/airbrainh743/extras/gearup_airbrainh743_bootloader.bin b/boards/gearup/airbrainh743/extras/gearup_airbrainh743_bootloader.bin new file mode 100755 index 0000000000000000000000000000000000000000..1363314125b33e07a4f8def73b8eef976d21724b GIT binary patch literal 42648 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 + +#ifndef __ASSEMBLY__ +# include +#endif + +#include "stm32_rcc.h" +#include "stm32_sdmmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Clocking *************************************************************************/ +/* The AirBrainH743 board provides the following clock sources: + * + * X1: 8 MHz crystal for HSE + */ + +#define STM32_BOARD_XTAL 8000000ul + +#define STM32_HSI_FREQUENCY 16000000ul +#define STM32_LSI_FREQUENCY 32000 +#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL +#define STM32_LSE_FREQUENCY 32768 + +/* Main PLL Configuration. + * + * PLL source is HSE = 8,000,000 + * + * PLL_VCOx = (STM32_HSE_FREQUENCY / PLLM) * PLLN + * + * SYSCLK = PLL_VCO / PLLP + * CPUCLK = SYSCLK / D1CPRE + */ + +#define STM32_BOARD_USEHSE + +#define STM32_PLLCFG_PLLSRC RCC_PLLCKSELR_PLLSRC_HSE + +/* PLL1, wide 4 - 8 MHz input, enable DIVP, DIVQ, DIVR + * + * PLL1_VCO = (8,000,000 / 1) * 120 = 960 MHz + * + * PLL1P = PLL1_VCO/2 = 960 MHz / 2 = 480 MHz + * PLL1Q = PLL1_VCO/4 = 960 MHz / 4 = 240 MHz + * PLL1R = PLL1_VCO/8 = 960 MHz / 8 = 120 MHz + */ + +#define STM32_PLLCFG_PLL1CFG (RCC_PLLCFGR_PLL1VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL1RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVP1EN | \ + RCC_PLLCFGR_DIVQ1EN | \ + RCC_PLLCFGR_DIVR1EN) +#define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(1) +#define STM32_PLLCFG_PLL1N RCC_PLL1DIVR_N1(120) +#define STM32_PLLCFG_PLL1P RCC_PLL1DIVR_P1(2) +#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_Q1(5) +#define STM32_PLLCFG_PLL1R RCC_PLL1DIVR_R1(8) + +#define STM32_VCO1_FREQUENCY ((STM32_HSE_FREQUENCY / 1) * 120) +#define STM32_PLL1P_FREQUENCY (STM32_VCO1_FREQUENCY / 2) +#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 5) +#define STM32_PLL1R_FREQUENCY (STM32_VCO1_FREQUENCY / 8) + +/* PLL2 */ + +#define STM32_PLLCFG_PLL2CFG (RCC_PLLCFGR_PLL2VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL2RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVP2EN | \ + RCC_PLLCFGR_DIVQ2EN | \ + RCC_PLLCFGR_DIVR2EN) +#define STM32_PLLCFG_PLL2M RCC_PLLCKSELR_DIVM2(2) +#define STM32_PLLCFG_PLL2N RCC_PLL2DIVR_N2(48) +#define STM32_PLLCFG_PLL2P RCC_PLL2DIVR_P2(2) +#define STM32_PLLCFG_PLL2Q RCC_PLL2DIVR_Q2(2) +#define STM32_PLLCFG_PLL2R RCC_PLL2DIVR_R2(2) + +#define STM32_VCO2_FREQUENCY ((STM32_HSE_FREQUENCY / 2) * 48) +#define STM32_PLL2P_FREQUENCY (STM32_VCO2_FREQUENCY / 2) +#define STM32_PLL2Q_FREQUENCY (STM32_VCO2_FREQUENCY / 2) +#define STM32_PLL2R_FREQUENCY (STM32_VCO2_FREQUENCY / 2) + +/* PLL3 */ + +#define STM32_PLLCFG_PLL3CFG (RCC_PLLCFGR_PLL3VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL3RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVQ3EN) +#define STM32_PLLCFG_PLL3M RCC_PLLCKSELR_DIVM3(2) +#define STM32_PLLCFG_PLL3N RCC_PLL3DIVR_N3(48) +#define STM32_PLLCFG_PLL3P RCC_PLL3DIVR_P3(2) +#define STM32_PLLCFG_PLL3Q RCC_PLL3DIVR_Q3(4) +#define STM32_PLLCFG_PLL3R RCC_PLL3DIVR_R3(2) + +#define STM32_VCO3_FREQUENCY ((STM32_HSE_FREQUENCY / 2) * 48) +#define STM32_PLL3P_FREQUENCY (STM32_VCO3_FREQUENCY / 2) +#define STM32_PLL3Q_FREQUENCY (STM32_VCO3_FREQUENCY / 4) +#define STM32_PLL3R_FREQUENCY (STM32_VCO3_FREQUENCY / 2) + +/* SYSCLK = PLL1P = 480MHz + * CPUCLK = SYSCLK / 1 = 480 MHz + */ + +#define STM32_RCC_D1CFGR_D1CPRE (RCC_D1CFGR_D1CPRE_SYSCLK) +#define STM32_SYSCLK_FREQUENCY (STM32_PLL1P_FREQUENCY) +#define STM32_CPUCLK_FREQUENCY (STM32_SYSCLK_FREQUENCY / 1) + +/* Configure Clock Assignments */ + +/* AHB clock (HCLK) is SYSCLK/2 (240 MHz max) + * HCLK1 = HCLK2 = HCLK3 = HCLK4 = 240 + */ + +#define STM32_RCC_D1CFGR_HPRE RCC_D1CFGR_HPRE_SYSCLKd2 /* HCLK = SYSCLK / 2 */ +#define STM32_ACLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* ACLK in D1, HCLK3 in D1 */ +#define STM32_HCLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* HCLK in D2, HCLK4 in D3 */ +#define STM32_BOARD_HCLK STM32_HCLK_FREQUENCY /* same as above, to satisfy compiler */ + +/* APB1 clock (PCLK1) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D2CFGR_D2PPRE1 RCC_D2CFGR_D2PPRE1_HCLKd2 /* PCLK1 = HCLK / 2 */ +#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB2 clock (PCLK2) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D2CFGR_D2PPRE2 RCC_D2CFGR_D2PPRE2_HCLKd2 /* PCLK2 = HCLK / 2 */ +#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB3 clock (PCLK3) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D1CFGR_D1PPRE RCC_D1CFGR_D1PPRE_HCLKd2 /* PCLK3 = HCLK / 2 */ +#define STM32_PCLK3_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB4 clock (PCLK4) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D3CFGR_D3PPRE RCC_D3CFGR_D3PPRE_HCLKd2 /* PCLK4 = HCLK / 2 */ +#define STM32_PCLK4_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* Timer clock frequencies */ + +/* Timers driven from APB1 will be twice PCLK1 */ + +#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM6_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM7_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY) + +/* Timers driven from APB2 will be twice PCLK2 */ + +#define STM32_APB2_TIM1_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM8_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM15_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM16_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM17_CLKIN (2*STM32_PCLK2_FREQUENCY) + +/* Kernel Clock Configuration */ + +/* I2C123 clock source */ + +#define STM32_RCC_D2CCIP2R_I2C123SRC RCC_D2CCIP2R_I2C123SEL_HSI + +/* I2C4 clock source */ + +#define STM32_RCC_D3CCIPR_I2C4SRC RCC_D3CCIPR_I2C4SEL_HSI + +/* SPI123 clock source */ + +#define STM32_RCC_D2CCIP1R_SPI123SRC RCC_D2CCIP1R_SPI123SEL_PLL2 + +/* SPI45 clock source */ + +#define STM32_RCC_D2CCIP1R_SPI45SRC RCC_D2CCIP1R_SPI45SEL_PLL2 + +/* SPI6 clock source */ + +#define STM32_RCC_D3CCIPR_SPI6SRC RCC_D3CCIPR_SPI6SEL_PLL2 + +/* USB 1 and 2 clock source */ + +#define STM32_RCC_D2CCIP2R_USBSRC RCC_D2CCIP2R_USBSEL_PLL3 + +/* ADC 1 2 3 clock source */ + +#define STM32_RCC_D3CCIPR_ADCSRC RCC_D3CCIPR_ADCSEL_PLL2 + +/* FDCAN 1 clock source */ + +#define STM32_RCC_D2CCIP1R_FDCANSEL RCC_D2CCIP1R_FDCANSEL_HSE +#define STM32_FDCANCLK STM32_HSE_FREQUENCY + +/* FLASH wait states */ + +#define BOARD_FLASH_WAITSTATES 2 + +/* LED definitions ******************************************************************/ + +#define BOARD_LED1 0 +#define BOARD_LED2 1 +#define BOARD_LED3 2 +#define BOARD_NLEDS 3 + +#define BOARD_LED_RED BOARD_LED1 +#define BOARD_LED_GREEN BOARD_LED2 +#define BOARD_LED_BLUE BOARD_LED3 + +/* LED bits for use with board_userled_all() */ + +#define BOARD_LED1_BIT (1 << BOARD_LED1) +#define BOARD_LED2_BIT (1 << BOARD_LED2) +#define BOARD_LED3_BIT (1 << BOARD_LED3) + +#define LED_STARTED 0 /* NuttX has been started OFF OFF OFF */ +#define LED_HEAPALLOCATE 1 /* Heap has been allocated OFF OFF ON */ +#define LED_IRQSENABLED 2 /* Interrupts enabled OFF ON OFF */ +#define LED_STACKCREATED 3 /* Idle stack created OFF ON ON */ +#define LED_INIRQ 4 /* In an interrupt N/C N/C GLOW */ +#define LED_SIGNAL 5 /* In a signal handler N/C GLOW N/C */ +#define LED_ASSERTION 6 /* An assertion failed GLOW N/C GLOW */ +#define LED_PANIC 7 /* The system has crashed Blink OFF N/C */ +#define LED_IDLE 8 /* MCU is is sleep mode ON OFF OFF */ + +/* Alternate function pin selections ************************************************/ + +/* USART1 - Debug (PA9 TX, PA10 RX) */ +#define GPIO_USART1_RX GPIO_USART1_RX_2 /* PA10 */ +#define GPIO_USART1_TX GPIO_USART1_TX_2 /* PA9 */ + +/* USART2 - RC input (PD5 TX, PD6 RX) */ +#define GPIO_USART2_RX GPIO_USART2_RX_2 /* PD6 */ +#define GPIO_USART2_TX GPIO_USART2_TX_2 /* PD5 */ + +/* USART3 - DJI/MSP (PD8 TX, PD9 RX) */ +#define GPIO_USART3_RX GPIO_USART3_RX_3 /* PD9 */ +#define GPIO_USART3_TX GPIO_USART3_TX_3 /* PD8 */ + +/* UART4 - General (PB9 TX, PB8 RX) */ +#define GPIO_UART4_RX GPIO_UART4_RX_3 /* PB8 */ +#define GPIO_UART4_TX GPIO_UART4_TX_3 /* PB9 */ + +/* UART5 - Companion (PB13 TX, PB12 RX) */ +#define GPIO_UART5_RX GPIO_UART5_RX_1 /* PB12 */ +#define GPIO_UART5_TX GPIO_UART5_TX_1 /* PB13 */ + +/* UART7 - ESC telemetry (PE8 TX, PE7 RX) */ +#define GPIO_UART7_RX GPIO_UART7_RX_3 /* PE7 */ +#define GPIO_UART7_TX GPIO_UART7_TX_3 /* PE8 */ + +/* UART8 - GPS (PE1 TX, PE0 RX) */ +#define GPIO_UART8_RX GPIO_UART8_RX_1 /* PE0 */ +#define GPIO_UART8_TX GPIO_UART8_TX_1 /* PE1 */ + + +/* SPI + * + * SPI1: IMU (PA5 SCK, PA6 MISO, PA7 MOSI) + * SPI2: W25N Flash (PD3 SCK, PB14 MISO, PC3 MOSI) + * SPI4: External (PE12 SCK, PE5 MISO, PE6 MOSI) + */ + +#define GPIO_SPI1_MISO GPIO_SPI1_MISO_1 /* PA6 */ +#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_1 /* PA7 */ +#define GPIO_SPI1_SCK GPIO_SPI1_SCK_1 /* PA5 */ + +#define GPIO_SPI2_MISO GPIO_SPI2_MISO_1 /* PB14 */ +#define GPIO_SPI2_MOSI GPIO_SPI2_MOSI_3 /* PC3 */ +#define GPIO_SPI2_SCK GPIO_SPI2_SCK_5 /* PD3 */ + +#define GPIO_SPI4_MISO GPIO_SPI4_MISO_2 /* PE5 */ +#define GPIO_SPI4_MOSI GPIO_SPI4_MOSI_2 /* PE6 */ +#define GPIO_SPI4_SCK GPIO_SPI4_SCK_1 /* PE12 */ + +/* I2C + * + * I2C1: Internal (PB6 SCL, PB7 SDA) + */ + +#define GPIO_I2C1_SCL GPIO_I2C1_SCL_1 /* PB6 */ +#define GPIO_I2C1_SDA GPIO_I2C1_SDA_1 /* PB7 */ + +#define GPIO_I2C1_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN6) +#define GPIO_I2C1_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN7) + + +/* USB + * + * OTG_FS_DM PA11 + * OTG_FS_DP PA12 + * VBUS PD0 + */ + + +#endif /*__NUTTX_CONFIG_AIRBRAINH743_INCLUDE_BOARD_H */ diff --git a/boards/gearup/airbrainh743/nuttx-config/include/board_dma_map.h b/boards/gearup/airbrainh743/nuttx-config/include/board_dma_map.h new file mode 100644 index 0000000000..2bd6646a83 --- /dev/null +++ b/boards/gearup/airbrainh743/nuttx-config/include/board_dma_map.h @@ -0,0 +1,42 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +/* DMA mapping for SPI1 (IMU) */ +#define DMAMAP_SPI1_RX DMAMAP_DMA12_SPI1RX_0 /* DMA1:37 */ +#define DMAMAP_SPI1_TX DMAMAP_DMA12_SPI1TX_0 /* DMA1:38 */ + +/* DMA mapping for SPI2 (W25N Flash) */ +#define DMAMAP_SPI2_RX DMAMAP_DMA12_SPI2RX_0 /* DMA1:39 */ +#define DMAMAP_SPI2_TX DMAMAP_DMA12_SPI2TX_0 /* DMA1:40 */ diff --git a/boards/gearup/airbrainh743/nuttx-config/nsh/defconfig b/boards/gearup/airbrainh743/nuttx-config/nsh/defconfig new file mode 100644 index 0000000000..56f41becc6 --- /dev/null +++ b/boards/gearup/airbrainh743/nuttx-config/nsh/defconfig @@ -0,0 +1,257 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_ENVIRON is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_MMCSD_HAVE_CARDDETECT is not set +# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_MMCSUPPORT is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_DATE is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_ENV is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXIT is not set +# CONFIG_NSH_DISABLE_EXPORT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOOPS is not set +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MKFATFS is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_PRINTF is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SEMICOLON is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_SOURCE is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +# CONFIG_SPI_CALLBACK is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/gearup/airbrainh743/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H743VI=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_INTERRUPTSTACK=512 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_BASEPRI_WAR=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_ARM_MPU_EARLY_RESET=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_CRASHDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=95150 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_BUILTIN=y +CONFIG_CDCACM=y +CONFIG_CDCACM_IFLOWCONTROL=y +CONFIG_CDCACM_PRODUCTID=0x0050 +CONFIG_CDCACM_PRODUCTSTR="AirBrainH743" +CONFIG_CDCACM_RXBUFSIZE=600 +CONFIG_CDCACM_TXBUFSIZE=12000 +CONFIG_CDCACM_VENDORID=0x3162 +CONFIG_CDCACM_VENDORSTR="Gear Up" +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_HARDFAULT_ALERT=y +CONFIG_DEBUG_MEMFAULT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DEV_FIFO_SIZE=0 +CONFIG_DEV_PIPE_MAXSIZE=1024 +CONFIG_DEV_PIPE_SIZE=70 +CONFIG_EXPERIMENTAL=y +CONFIG_FAT_DMAMEMORY=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FAT_LFN_ALIAS_HASH=y +CONFIG_FDCLONE_STDIO=y +CONFIG_FS_BINFS=y +CONFIG_FS_CROMFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FATTIME=y +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_INCLUDE_PROGMEM=y +CONFIG_FS_PROCFS_MAX_TASKS=64 +CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_ROMFS=y +CONFIG_FS_LITTLEFS=y +CONFIG_FS_LITTLEFS_PROGRAM_SIZE_FACTOR=1 +CONFIG_FS_LITTLEFS_READ_SIZE_FACTOR=1 +CONFIG_FS_LITTLEFS_CACHE_SIZE_FACTOR=1 +CONFIG_GRAN=y +CONFIG_GRAN_INTR=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_I2C=y +CONFIG_I2C_RESET=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3194 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_MAX_EXITFUNS=1 +CONFIG_LIBC_STRERROR=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_MM_REGIONS=4 +CONFIG_MTD=y +CONFIG_MTD_BYTE_WRITE=y +CONFIG_MTD_PARTITION=y +CONFIG_MTD_PROGMEM=y +CONFIG_MTD_W25N=y +CONFIG_W25N_SPIFREQUENCY=104000000 +CONFIG_NAME_MAX=40 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_CMDPARMS=y +CONFIG_NSH_CROMFSETC=y +CONFIG_NSH_LINELEN=128 +CONFIG_NSH_MAXARGUMENTS=15 +CONFIG_NSH_NESTDEPTH=8 +CONFIG_NSH_QUOTE=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ROMFSSECTSIZE=128 +CONFIG_NSH_STRERROR=y +CONFIG_NSH_VARS=y +CONFIG_OTG_ID_GPIO_DISABLE=y +CONFIG_PIPES=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PRIORITY_INHERITANCE=y +CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_RTC_DATETIME=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=249 +CONFIG_SCHED_HPWORKSTACKSIZE=1280 +CONFIG_SCHED_INSTRUMENTATION=y +CONFIG_SCHED_INSTRUMENTATION_EXTERNAL=y +CONFIG_SCHED_INSTRUMENTATION_SWITCH=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_LPWORKPRIORITY=50 +CONFIG_SCHED_LPWORKSTACKSIZE=1632 +CONFIG_SCHED_WAITPID=y +CONFIG_SEM_PREALLOCHOLDERS=32 +CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SIG_SIGWORK=4 +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=256 +CONFIG_STM32H7_ADC1=y +CONFIG_STM32H7_ADC3=y +CONFIG_STM32H7_BBSRAM=y +CONFIG_STM32H7_BBSRAM_FILES=5 +CONFIG_STM32H7_BDMA=y +CONFIG_STM32H7_BKPSRAM=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_DMA2=y +CONFIG_STM32H7_DMACAPABLE=y +CONFIG_STM32H7_DMAMUX1=y +CONFIG_STM32H7_FLOWCONTROL_BROKEN=y +CONFIG_STM32H7_I2C1=y +CONFIG_STM32H7_I2C_DYNTIMEO=y +CONFIG_STM32H7_I2C_DYNTIMEO_STARTSTOP=10 +CONFIG_STM32H7_OTGFS=y +CONFIG_STM32H7_PROGMEM=y +CONFIG_STM32H7_RTC=y +CONFIG_STM32H7_RTC_HSECLOCK=y +CONFIG_STM32H7_RTC_MAGIC_REG=1 +CONFIG_STM32H7_SAVE_CRASHDUMP=y +CONFIG_STM32H7_SERIALBRK_BSDCOMPAT=y +CONFIG_STM32H7_SERIAL_DISABLE_REORDERING=y +CONFIG_STM32H7_SPI1=y +CONFIG_STM32H7_SPI1_DMA=y +CONFIG_STM32H7_SPI1_DMA_BUFFER=4096 +CONFIG_STM32H7_SPI2=y +CONFIG_STM32H7_SPI2_DMA=y +CONFIG_STM32H7_SPI2_DMA_BUFFER=4096 +CONFIG_STM32H7_SPI4=y +CONFIG_STM32H7_TIM1=y +CONFIG_STM32H7_TIM2=y +CONFIG_STM32H7_TIM3=y +CONFIG_STM32H7_TIM5=y +CONFIG_STM32H7_TIM8=y +CONFIG_STM32H7_UART4=y +CONFIG_STM32H7_UART5=y +CONFIG_STM32H7_UART7=y +CONFIG_STM32H7_UART8=y +CONFIG_STM32H7_USART1=y +CONFIG_STM32H7_USART2=y +CONFIG_STM32H7_USART3=y +CONFIG_STM32H7_USART_BREAKS=y +CONFIG_STM32H7_USART_INVERT=y +CONFIG_STM32H7_USART_SINGLEWIRE=y +CONFIG_STM32H7_USART_SWAP=y +CONFIG_SYSTEM_CDCACM=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_TTY_SIGINT=y +CONFIG_TTY_SIGTSTP=y +CONFIG_UART4_BAUD=57600 +CONFIG_UART4_RXBUFSIZE=600 +CONFIG_UART4_TXBUFSIZE=1500 +CONFIG_UART5_BAUD=57600 +CONFIG_UART5_RXBUFSIZE=600 +CONFIG_UART5_TXBUFSIZE=1500 +CONFIG_UART7_BAUD=57600 +CONFIG_UART7_RXBUFSIZE=600 +CONFIG_UART7_TXBUFSIZE=1500 +CONFIG_UART8_BAUD=57600 +CONFIG_UART8_RXBUFSIZE=600 +CONFIG_UART8_TXBUFSIZE=1500 +CONFIG_USART1_BAUD=57600 +CONFIG_USART1_RXBUFSIZE=600 +CONFIG_USART1_SERIAL_CONSOLE=y +CONFIG_USART1_TXBUFSIZE=1500 +CONFIG_USART2_BAUD=57600 +CONFIG_USART2_RXBUFSIZE=600 +CONFIG_USART2_TXBUFSIZE=1500 +CONFIG_USART3_BAUD=57600 +CONFIG_USART3_RXBUFSIZE=600 +CONFIG_USART3_TXBUFSIZE=1500 +CONFIG_USBDEV=y +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_MAXPOWER=500 +CONFIG_USEC_PER_TICK=1000 +CONFIG_WATCHDOG=y diff --git a/boards/gearup/airbrainh743/nuttx-config/scripts/bootloader_script.ld b/boards/gearup/airbrainh743/nuttx-config/scripts/bootloader_script.ld new file mode 100644 index 0000000000..fb877cc443 --- /dev/null +++ b/boards/gearup/airbrainh743/nuttx-config/scripts/bootloader_script.ld @@ -0,0 +1,213 @@ +/**************************************************************************** + * scripts/script.ld + * + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The Durandal-v1 uses an STM32H743II has 2048Kb of main FLASH memory. + * The flash memory is partitioned into a User Flash memory and a System + * Flash memory. Each of these memories has two banks: + * + * 1) User Flash memory: + * + * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each + * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each + * + * 2) System Flash memory: + * + * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector + * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector + * + * 3) User option bytes for user configuration, only in Bank 1. + * + * In the STM32H743II, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash memory at 0x0800:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x1FF0:0000 + * + * The Durandal has a Switch on board, the BOOT0 pin is at ground so by default, + * the STM32 will boot to address 0x0800:0000 in FLASH unless the swiutch is + * drepresed, then the boot will be from 0x1FF0:0000 + * + * The STM32H743ZI also has 1024Kb of data SRAM. + * SRAM is split up into several blocks and into three power domains: + * + * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with + * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus + * + * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000 + * + * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit + * DTCM ports. The DTCM-RAM could be used for critical real-time + * data, such as interrupt service routines or stack / heap memory. + * Both DTCM-RAMs can be used in parallel (for load/store operations) + * thanks to the Cortex-M7 dual issue capability. + * + * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000 + * + * This RAM is connected to ITCM 64-bit interface designed for + * execution of critical real-times routines by the CPU. + * + * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA + * through D1 domain AXI bus matrix + * + * 2.1) 512Kb of SRAM beginning at address 0x2400:0000 + * + * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA + * through D2 domain AHB bus matrix + * + * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000 + * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000 + * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000 + * + * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000 + * + * 4) AHB SRAM (D3 domain) accessible by most of system masters + * through D3 domain AHB bus matrix + * + * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000 + * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + */ + +MEMORY +{ + itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + flash (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + dtcm1 (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + dtcm2 (rwx) : ORIGIN = 0x20010000, LENGTH = 64K + sram (rwx) : ORIGIN = 0x24000000, LENGTH = 512K + sram1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K + sram2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K + sram3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K + sram4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K + bbram (rwx) : ORIGIN = 0x38800000, LENGTH = 4K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + + } > flash + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + + .ARM.extab : { + *(.ARM.extab*) + } > flash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > flash + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/gearup/airbrainh743/nuttx-config/scripts/script.ld b/boards/gearup/airbrainh743/nuttx-config/scripts/script.ld new file mode 100644 index 0000000000..a01eb2e2a8 --- /dev/null +++ b/boards/gearup/airbrainh743/nuttx-config/scripts/script.ld @@ -0,0 +1,228 @@ +/**************************************************************************** + * scripts/script.ld + * + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The board uses an STM32H743II and has 2048Kb of main FLASH memory. + * The flash memory is partitioned into a User Flash memory and a System + * Flash memory. Each of these memories has two banks: + * + * 1) User Flash memory: + * + * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each + * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each + * + * 2) System Flash memory: + * + * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector + * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector + * + * 3) User option bytes for user configuration, only in Bank 1. + * + * In the STM32H743II, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash memory at 0x0800:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x1FF0:0000 + * + * There's a switch on board, the BOOT0 pin is at ground so by default, + * the STM32 will boot to address 0x0800:0000 in FLASH unless the switch is + * drepresed, then the boot will be from 0x1FF0:0000 + * + * The STM32H743ZI also has 1024Kb of data SRAM. + * SRAM is split up into several blocks and into three power domains: + * + * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with + * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus + * + * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000 + * + * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit + * DTCM ports. The DTCM-RAM could be used for critical real-time + * data, such as interrupt service routines or stack / heap memory. + * Both DTCM-RAMs can be used in parallel (for load/store operations) + * thanks to the Cortex-M7 dual issue capability. + * + * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000 + * + * This RAM is connected to ITCM 64-bit interface designed for + * execution of critical real-times routines by the CPU. + * + * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA + * through D1 domain AXI bus matrix + * + * 2.1) 512Kb of SRAM beginning at address 0x2400:0000 + * + * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA + * through D2 domain AHB bus matrix + * + * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000 + * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000 + * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000 + * + * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000 + * + * 4) AHB SRAM (D3 domain) accessible by most of system masters + * through D3 domain AHB bus matrix + * + * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000 + * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + */ + +MEMORY +{ + ITCM_RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 1792K /* params in last sector */ + + DTCM1_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + DTCM2_RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 64K + AXI_SRAM (rwx) : ORIGIN = 0x24000000, LENGTH = 512K /* D1 domain AXI bus */ + SRAM1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K /* D2 domain AHB bus */ + SRAM2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K /* D2 domain AHB bus */ + SRAM3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K /* D2 domain AHB bus */ + SRAM4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K /* D3 domain */ + BKPRAM (rwx) : ORIGIN = 0x38800000, LENGTH = 4K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + + } > FLASH + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > FLASH + + + .ARM.extab : { + *(.ARM.extab*) + } > FLASH + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > FLASH + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + + /* Pad out last section as the STM32H7 Flash write size is 256 bits. 32 bytes */ + . = ALIGN(16); + FILL(0xffff) + . += 16; + } > AXI_SRAM AT > FLASH = 0xffff + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > AXI_SRAM + + /* Emit the the D3 power domain section for locating BDMA data */ + + .sram4_reserve (NOLOAD) : + { + *(.sram4) + . = ALIGN(4); + _sram4_heap_start = ABSOLUTE(.); + } > SRAM4 + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/gearup/airbrainh743/src/CMakeLists.txt b/boards/gearup/airbrainh743/src/CMakeLists.txt new file mode 100644 index 0000000000..63d047cdea --- /dev/null +++ b/boards/gearup/airbrainh743/src/CMakeLists.txt @@ -0,0 +1,67 @@ +############################################################################ +# +# Copyright (c) 2026 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +if("${PX4_BOARD_LABEL}" STREQUAL "bootloader") + add_library(drivers_board + bootloader_main.c + usb.c + ) + target_link_libraries(drivers_board + PRIVATE + nuttx_arch + nuttx_drivers + bootloader + ) + target_include_directories(drivers_board PRIVATE ${PX4_SOURCE_DIR}/platforms/nuttx/src/bootloader/common) + +else() + add_library(drivers_board + i2c.cpp + init.c + led.c + spi.cpp + timer_config.cpp + usb.c + ) + add_dependencies(drivers_board arch_board_hw_info) + + target_link_libraries(drivers_board + PRIVATE + arch_io_pins + arch_spi + arch_board_hw_info + drivers__led + nuttx_arch + nuttx_drivers + px4_layer + ) +endif() diff --git a/boards/gearup/airbrainh743/src/board_config.h b/boards/gearup/airbrainh743/src/board_config.h new file mode 100644 index 0000000000..1515f395ad --- /dev/null +++ b/boards/gearup/airbrainh743/src/board_config.h @@ -0,0 +1,216 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file board_config.h + * + * AirBrainH743 (Gear Up) internal definitions + */ + +#pragma once + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include +#include + +#include + +/**************************************************************************************************** + * Definitions + ****************************************************************************************************/ + +/* Enable small flash logging support (for W25N NAND flash) */ +#ifdef CONFIG_MTD_W25N +# define BOARD_SMALL_FLASH_LOGGING 1 +#endif + +/* LEDs are active low + * STAT RGB LED: + * PB15 = Blue + * PD11 = Green + * PD15 = Red + * BAT LED (orange): hardwired to power input + */ +#define GPIO_nLED_BLUE /* PB15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN15) +#define GPIO_nLED_GREEN /* PD11 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN11) +#define GPIO_nLED_RED /* PD15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN15) + +#define BOARD_HAS_CONTROL_STATUS_LEDS 1 +#define BOARD_OVERLOAD_LED LED_RED +#define BOARD_ARMED_STATE_LED LED_GREEN + +/* + * ADC channels + * + * These are the channel numbers of the ADCs of the microcontroller that + * can be used by the Px4 Firmware in the adc driver + */ + +/* ADC defines to be used in sensors.cpp to read from a particular channel */ +#define ADC1_CH(n) (n) + +/* Define GPIO pins used as ADC N.B. Channel numbers must match below */ +#define PX4_ADC_GPIO \ + /* PC4 */ GPIO_ADC12_INP4, \ + /* PC5 */ GPIO_ADC12_INP8 + +/* Define Channel numbers must match above GPIO pin IN(n)*/ +#define ADC_BATTERY_VOLTAGE_CHANNEL /* PC4 */ ADC1_CH(4) +#define ADC_BATTERY_CURRENT_CHANNEL /* PC5 */ ADC1_CH(8) + +#define ADC_CHANNELS \ + ((1 << ADC_BATTERY_VOLTAGE_CHANNEL) | \ + (1 << ADC_BATTERY_CURRENT_CHANNEL)) + + +/* Define Battery Voltage Divider and A per V + */ +#define BOARD_BATTERY1_V_DIV (15.0f) +#define BOARD_BATTERY1_A_PER_V (101.0f) + + +/* PWM + * 8 PWM outputs for motors + 1 for LED strip + */ +#define DIRECT_PWM_OUTPUT_CHANNELS 9 +#define DIRECT_INPUT_TIMER_CHANNELS 9 + +#define BOARD_HAS_PWM DIRECT_PWM_OUTPUT_CHANNELS + + +/* Tone alarm output - PA15 */ +#define GPIO_TONE_ALARM_IDLE /* PA15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TONE_ALARM_GPIO /* PA15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN15) + + +/* ICM42688P FSYNC - directly connected to IMU via GPIO (no timer). + * The driver clears TMST_FSYNC_EN and FIFO_TMST_FSYNC_EN, so FSYNC is unused. + * This GPIO is kept low to prevent spurious triggers. + */ +#define GPIO_42688P_FSYNC /* PC7 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN7) + + +/* USB OTG FS + * + * PD0 VBUS sensing (active high input) + */ +#define GPIO_OTGFS_VBUS /* PD0 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN0) + + +/* High-resolution timer */ +#define HRT_TIMER 8 /* use timer8 for the HRT */ +#define HRT_TIMER_CHANNEL 3 /* use capture/compare channel 3 */ + + +/* + * Serial Port Mapping: + * + * UART Device Pins Function + * ---- ------ ---- -------- + * USART1 /dev/ttyS0 PA9/PA10 Console/Debug + * USART2 /dev/ttyS1 PD5/PD6 RC Input + * USART3 /dev/ttyS2 PD8/PD9 TEL4 (DJI/MSP) + * UART4 /dev/ttyS3 PA0/PA1 TEL1 + * UART5 /dev/ttyS4 PB13/PB12 TEL2 + * UART7 /dev/ttyS5 PE8/PE7 TEL3 (ESC Telemetry) + * UART8 /dev/ttyS6 PE1/PE0 GPS1 + */ + +/* RC Serial port - USART2 (PD5/PD6) */ +#define RC_SERIAL_PORT "/dev/ttyS1" +#define BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT + + +/* This board provides a DMA pool and APIs */ +#define BOARD_DMA_ALLOC_POOL_SIZE 5120 + +/* This board provides the board_on_reset interface */ +#define BOARD_HAS_ON_RESET 1 + + +#define PX4_GPIO_INIT_LIST { \ + PX4_ADC_GPIO, \ + GPIO_nLED_RED, \ + GPIO_nLED_GREEN, \ + GPIO_nLED_BLUE, \ + GPIO_TONE_ALARM_IDLE, \ + GPIO_42688P_FSYNC, \ + } + +#define BOARD_ENABLE_CONSOLE_BUFFER + +#define BOARD_NUM_IO_TIMERS 4 + + +__BEGIN_DECLS + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public data + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +/**************************************************************************** + * Name: stm32_spiinitialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the board. + * + ****************************************************************************/ + +extern void stm32_spiinitialize(void); + +extern void stm32_usbinitialize(void); + +extern void board_peripheral_reset(int ms); + +/* Parameters stored in internal flash */ +#define FLASH_BASED_PARAMS + +#include + +#endif /* __ASSEMBLY__ */ + +__END_DECLS diff --git a/boards/gearup/airbrainh743/src/bootloader_main.c b/boards/gearup/airbrainh743/src/bootloader_main.c new file mode 100644 index 0000000000..996370b00e --- /dev/null +++ b/boards/gearup/airbrainh743/src/bootloader_main.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file bootloader_main.c + * + * AirBrainH743-specific early startup code for bootloader + */ + +#include "board_config.h" +#include "bl.h" + +#include +#include +#include +#include +#include +#include "arm_internal.h" +#include + +extern int sercon_main(int c, char **argv); + +__EXPORT void board_on_reset(int status) {} + +__EXPORT void stm32_boardinitialize(void) +{ + /* configure USB interfaces */ + stm32_usbinitialize(); +} + +__EXPORT int board_app_initialize(uintptr_t arg) +{ + return 0; +} + +void board_late_initialize(void) +{ + sercon_main(0, NULL); +} + +extern void sys_tick_handler(void); +void board_timerhook(void) +{ + sys_tick_handler(); +} diff --git a/boards/gearup/airbrainh743/src/hw_config.h b/boards/gearup/airbrainh743/src/hw_config.h new file mode 100644 index 0000000000..38e16b4059 --- /dev/null +++ b/boards/gearup/airbrainh743/src/hw_config.h @@ -0,0 +1,85 @@ +/**************************************************************************** + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#define APP_LOAD_ADDRESS 0x08020000 +#define BOOTLOADER_DELAY 5000 +#define INTERFACE_USB 1 +#define INTERFACE_USB_CONFIG "/dev/ttyACM0" +#define BOARD_VBUS MK_GPIO_INPUT(GPIO_OTGFS_VBUS) + +#define INTERFACE_USART 1 +#define INTERFACE_USART_CONFIG "/dev/ttyS0,57600" +#define BOOT_DELAY_ADDRESS 0x000001a0 +#define BOARD_TYPE 1209 +#define _FLASH_KBYTES (*(uint32_t *)0x1FF1E880) +#define BOARD_FLASH_SECTORS (14) +#define BOARD_FLASH_SIZE (_FLASH_KBYTES * 1024) + +#define OSC_FREQ 8 + +#define BOARD_PIN_LED_ACTIVITY GPIO_nLED_BLUE +#define BOARD_PIN_LED_BOOTLOADER GPIO_nLED_GREEN +#define BOARD_LED_ON 0 +#define BOARD_LED_OFF 1 + +#define SERIAL_BREAK_DETECT_DISABLED 1 + +#if !defined(ARCH_SN_MAX_LENGTH) +# define ARCH_SN_MAX_LENGTH 12 +#endif + +/* Reserve 128KB (1 sector) at end of flash for parameters */ +#define APP_RESERVATION_SIZE (1 * 128 * 1024) + +#if !defined(BOARD_FIRST_FLASH_SECTOR_TO_ERASE) +# define BOARD_FIRST_FLASH_SECTOR_TO_ERASE 1 +#endif + +#if !defined(USB_DATA_ALIGN) +# define USB_DATA_ALIGN +#endif + +#ifndef BOOT_DEVICES_SELECTION +# define BOOT_DEVICES_SELECTION USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif + +#ifndef BOOT_DEVICES_FILTER_ONUSB +# define BOOT_DEVICES_FILTER_ONUSB USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif + +/* Boot device selection list*/ +#define USB0_DEV 0x01 +#define SERIAL0_DEV 0x02 +#define SERIAL1_DEV 0x04 diff --git a/boards/gearup/airbrainh743/src/i2c.cpp b/boards/gearup/airbrainh743/src/i2c.cpp new file mode 100644 index 0000000000..9bb4992776 --- /dev/null +++ b/boards/gearup/airbrainh743/src/i2c.cpp @@ -0,0 +1,45 @@ +/**************************************************************************** + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +/* + * I2C bus configuration for AirBrainH743 + * + * I2C1: Internal bus - PB6 (SCL), PB7 (SDA) + * Devices: DPS310 baro @ 0x76, LIS2MDL compass @ 0x1E + */ + +constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = { + initI2CBusInternal(1), +}; diff --git a/boards/gearup/airbrainh743/src/init.c b/boards/gearup/airbrainh743/src/init.c new file mode 100644 index 0000000000..0f2a75d6d2 --- /dev/null +++ b/boards/gearup/airbrainh743/src/init.c @@ -0,0 +1,228 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file init.c + * + * AirBrainH743-specific early startup code. + */ + +#include "board_config.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "arm_internal.h" + +#include +#include +#include +#include +#include +#include +#include + +#if defined(FLASH_BASED_PARAMS) +#include +#endif + +#ifdef CONFIG_MTD_W25N +extern FAR struct mtd_dev_s *w25n_initialize(FAR struct spi_dev_s *dev, uint32_t spi_devid); +#endif + +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +__END_DECLS + +/************************************************************************************ + * Name: board_peripheral_reset + * + * Description: + * + ************************************************************************************/ +__EXPORT void board_peripheral_reset(int ms) +{ + UNUSED(ms); +} + +/************************************************************************************ + * Name: board_on_reset + * + * Description: + * Optionally provided function called on entry to board_system_reset + * It should perform any house keeping prior to the rest. + * + * status - 1 if resetting to boot loader + * 0 if just resetting + * + ************************************************************************************/ +__EXPORT void board_on_reset(int status) +{ + for (int i = 0; i < DIRECT_PWM_OUTPUT_CHANNELS; ++i) { + px4_arch_configgpio(PX4_MAKE_GPIO_INPUT(io_timer_channel_get_as_pwm_input(i))); + } + + if (status >= 0) { + up_mdelay(100); + } +} + +/************************************************************************************ + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. + * + ************************************************************************************/ +__EXPORT void stm32_boardinitialize(void) +{ + /* Reset PWM first thing */ + board_on_reset(-1); + + /* configure LEDs */ + board_autoled_initialize(); + + /* configure pins */ + const uint32_t gpio[] = PX4_GPIO_INIT_LIST; + px4_gpio_init(gpio, arraySize(gpio)); + + /* configure USB interfaces */ + stm32_usbinitialize(); +} + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. + * + ****************************************************************************/ +__EXPORT int board_app_initialize(uintptr_t arg) +{ + /* Need hrt running before using the ADC */ + px4_platform_init(); + + /* configure SPI interfaces */ + stm32_spiinitialize(); + + /* configure the DMA allocator */ + if (board_dma_alloc_init() < 0) { + syslog(LOG_ERR, "[boot] DMA alloc FAILED\n"); + } + + /* initial LED state */ + drv_led_start(); + led_off(LED_RED); + led_off(LED_GREEN); + led_off(LED_BLUE); + + if (board_hardfault_init(2, true) != 0) { + led_on(LED_RED); + } + +#ifdef CONFIG_MTD_W25N + /* Initialize W25N01GV NAND Flash on SPI2 */ + struct spi_dev_s *spi2 = stm32_spibus_initialize(2); + + if (!spi2) { + syslog(LOG_ERR, "[boot] FAILED to initialize SPI2 for W25N\n"); + led_on(LED_RED); + + } else { + struct mtd_dev_s *mtd = w25n_initialize(spi2, 0); + + if (!mtd) { + syslog(LOG_ERR, "[boot] FAILED to initialize W25N MTD driver\n"); + led_on(LED_RED); + + } else { + int ret = register_mtddriver("/dev/mtd0", mtd, 0755, NULL); + + if (ret < 0) { + syslog(LOG_ERR, "[boot] FAILED to register MTD driver: %d\n", ret); + led_on(LED_RED); + + } else { + syslog(LOG_INFO, "[boot] W25N MTD registered at /dev/mtd0\n"); + +#ifdef CONFIG_FS_LITTLEFS + ret = nx_mount("/dev/mtd0", "/fs/microsd", "littlefs", 0, "autoformat"); + + if (ret < 0) { + syslog(LOG_ERR, "[boot] FAILED to mount littlefs: %d\n", ret); + led_on(LED_RED); + + } else { + syslog(LOG_INFO, "[boot] LittleFS mounted at /fs/microsd\n"); + } + +#endif + } + } + } + +#endif + +#if defined(FLASH_BASED_PARAMS) + /* Initialize parameters in internal flash (sector 15, 128KB at 0x081E0000) */ + static sector_descriptor_t params_sector_map[] = { + {15, 128 * 1024, 0x081E0000}, + {0, 0, 0}, + }; + + int result = parameter_flashfs_init(params_sector_map, NULL, 0); + + if (result != OK) { + syslog(LOG_ERR, "[boot] FAILED to init params in FLASH %d\n", result); + led_on(LED_RED); + } + +#endif + + /* Configure the HW based on the manifest */ + px4_platform_configure(); + + return OK; +} diff --git a/boards/gearup/airbrainh743/src/led.c b/boards/gearup/airbrainh743/src/led.c new file mode 100644 index 0000000000..016ef9f822 --- /dev/null +++ b/boards/gearup/airbrainh743/src/led.c @@ -0,0 +1,205 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "stm32_gpio.h" +#include "board_config.h" + +#include +#include + +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +extern void led_toggle(int led); +__END_DECLS + +#ifdef CONFIG_ARCH_LEDS +static bool nuttx_owns_leds = true; +static const uint8_t xlatpx4[] = {1, 2, 4, 0}; +# define xlat(p) xlatpx4[(p)] +static uint32_t g_ledmap[] = { + GPIO_nLED_RED, // Indexed by BOARD_LED_RED + GPIO_nLED_GREEN, // Indexed by BOARD_LED_GREEN + GPIO_nLED_BLUE, // Indexed by BOARD_LED_BLUE +}; + +#else + +# define xlat(p) (p) +static uint32_t g_ledmap[] = { + GPIO_nLED_RED, // LED_RED + GPIO_nLED_GREEN, // LED_GREEN + GPIO_nLED_BLUE, // LED_BLUE +}; + +#endif + +__EXPORT void led_init(void) +{ + for (size_t l = 0; l < (sizeof(g_ledmap) / sizeof(g_ledmap[0])); l++) { + if (g_ledmap[l] != 0) { + stm32_configgpio(g_ledmap[l]); + } + } +} + +static void phy_set_led(int led, bool state) +{ + /* Drive Low to switch on (active low LEDs) */ + if (led < (int)(sizeof(g_ledmap) / sizeof(g_ledmap[0])) && g_ledmap[led] != 0) { + stm32_gpiowrite(g_ledmap[led], !state); + } +} + +static bool phy_get_led(int led) +{ + /* If Low it is on */ + if (led < (int)(sizeof(g_ledmap) / sizeof(g_ledmap[0])) && g_ledmap[led] != 0) { + return !stm32_gpioread(g_ledmap[led]); + } + + return false; +} + +__EXPORT void led_on(int led) +{ + phy_set_led(xlat(led), true); +} + +__EXPORT void led_off(int led) +{ + phy_set_led(xlat(led), false); +} + +__EXPORT void led_toggle(int led) +{ + phy_set_led(xlat(led), !phy_get_led(xlat(led))); +} + +#ifdef CONFIG_ARCH_LEDS +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void board_autoled_initialize(void) +{ + led_init(); +} + +void board_autoled_on(int led) +{ + if (!nuttx_owns_leds) { + return; + } + + switch (led) { + default: + break; + + case LED_HEAPALLOCATE: + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_IRQSENABLED: + phy_set_led(BOARD_LED_BLUE, false); + phy_set_led(BOARD_LED_GREEN, true); + break; + + case LED_STACKCREATED: + phy_set_led(BOARD_LED_GREEN, true); + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_INIRQ: + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_SIGNAL: + phy_set_led(BOARD_LED_GREEN, true); + break; + + case LED_ASSERTION: + phy_set_led(BOARD_LED_RED, true); + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_PANIC: + phy_set_led(BOARD_LED_RED, true); + break; + + case LED_IDLE: + phy_set_led(BOARD_LED_RED, true); + break; + } +} + +void board_autoled_off(int led) +{ + if (!nuttx_owns_leds) { + return; + } + + switch (led) { + default: + break; + + case LED_SIGNAL: + phy_set_led(BOARD_LED_GREEN, false); + break; + + case LED_INIRQ: + phy_set_led(BOARD_LED_BLUE, false); + break; + + case LED_ASSERTION: + phy_set_led(BOARD_LED_RED, false); + phy_set_led(BOARD_LED_BLUE, false); + break; + + case LED_PANIC: + phy_set_led(BOARD_LED_RED, false); + break; + + case LED_IDLE: + phy_set_led(BOARD_LED_RED, false); + break; + } +} + +#endif /* CONFIG_ARCH_LEDS */ diff --git a/boards/gearup/airbrainh743/src/spi.cpp b/boards/gearup/airbrainh743/src/spi.cpp new file mode 100644 index 0000000000..05559c44d2 --- /dev/null +++ b/boards/gearup/airbrainh743/src/spi.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + +/* + * SPI bus configuration for AirBrainH743 + * + * SPI1: IMU (Invensensev3/ICM42688P) - PA5 SCK, PA6 MISO, PA7 MOSI, PA3 CS + * SPI2: W25N Flash - PD3 SCK, PB14 MISO, PC3 MOSI, PD4 CS + * SPI4: External/AUX - PE12 SCK, PE5 MISO, PE6 MOSI + */ + +constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { + initSPIBus(SPI::Bus::SPI1, { + initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortA, GPIO::Pin3}), + }), + initSPIBus(SPI::Bus::SPI2, { + initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortD, GPIO::Pin4}), // W25N Flash + }), + initSPIBusExternal(SPI::Bus::SPI4, { + initSPIConfigExternal(SPI::CS{GPIO::PortB, GPIO::Pin3}), // User 1 GPIO as chip select + }), +}; + +static constexpr bool unused = validateSPIConfig(px4_spi_buses); diff --git a/boards/gearup/airbrainh743/src/timer_config.cpp b/boards/gearup/airbrainh743/src/timer_config.cpp new file mode 100644 index 0000000000..e91005bb7a --- /dev/null +++ b/boards/gearup/airbrainh743/src/timer_config.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +/* + * PWM output configuration for AirBrainH743 + * + * M1: PE14 (TIM1_CH4) + * M2: PE13 (TIM1_CH3) + * M3: PE11 (TIM1_CH2) + * M4: PE9 (TIM1_CH1) + * M5: PB0 (TIM3_CH3) + * M6: PB1 (TIM3_CH4) + * M7: PB10 (TIM2_CH3) + * M8: PB11 (TIM2_CH4) + * M9: PA2 (TIM5_CH3) - LED strip + */ + +constexpr io_timers_t io_timers[MAX_IO_TIMERS] = { + initIOTimer(Timer::Timer1, DMA{DMA::Index1, DMA::Stream0, DMA::Channel6}), + initIOTimer(Timer::Timer3, DMA{DMA::Index1, DMA::Stream2, DMA::Channel5}), + initIOTimer(Timer::Timer2, DMA{DMA::Index1, DMA::Stream6, DMA::Channel3}), + initIOTimer(Timer::Timer5), +}; + +constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel4}, {GPIO::PortE, GPIO::Pin14}), // M1 + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel3}, {GPIO::PortE, GPIO::Pin13}), // M2 + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel2}, {GPIO::PortE, GPIO::Pin11}), // M3 + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel1}, {GPIO::PortE, GPIO::Pin9}), // M4 + initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel3}, {GPIO::PortB, GPIO::Pin0}), // M5 + initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel4}, {GPIO::PortB, GPIO::Pin1}), // M6 + initIOTimerChannel(io_timers, {Timer::Timer2, Timer::Channel3}, {GPIO::PortB, GPIO::Pin10}), // M7 + initIOTimerChannel(io_timers, {Timer::Timer2, Timer::Channel4}, {GPIO::PortB, GPIO::Pin11}), // M8 + initIOTimerChannel(io_timers, {Timer::Timer5, Timer::Channel3}, {GPIO::PortA, GPIO::Pin2}), // M9 (LED) +}; + +constexpr io_timers_channel_mapping_t io_timers_channel_mapping = + initIOTimerChannelMapping(io_timers, timer_io_channels); diff --git a/boards/gearup/airbrainh743/src/usb.c b/boards/gearup/airbrainh743/src/usb.c new file mode 100644 index 0000000000..a1c5d345dc --- /dev/null +++ b/boards/gearup/airbrainh743/src/usb.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file usb.c + * + * Board-specific USB functions. + */ + +#include "board_config.h" +#include +#include +#include +#include + +/************************************************************************************ + * Name: stm32_usbinitialize + * + * Description: + * Called to setup USB-related GPIO pins for the board. + * + ************************************************************************************/ + +__EXPORT void stm32_usbinitialize(void) +{ + /* The OTG FS has an internal soft pull-up */ + + /* Configure the OTG FS VBUS sensing GPIO */ +#ifdef CONFIG_STM32H7_OTGFS + stm32_configgpio(GPIO_OTGFS_VBUS); +#endif +} + +/************************************************************************************ + * Name: stm32_usbsuspend + * + * Description: + * Board logic must provide the stm32_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * + ************************************************************************************/ +__EXPORT void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume) +{ + uinfo("resume: %d\n", resume); +} diff --git a/docs/en/SUMMARY.md b/docs/en/SUMMARY.md index cafc85b353..f141f91679 100644 --- a/docs/en/SUMMARY.md +++ b/docs/en/SUMMARY.md @@ -178,6 +178,7 @@ - [CubePilot Cube Orange (CubePilot)](flight_controller/cubepilot_cube_orange.md) - [CubePilot Cube Yellow (CubePilot)](flight_controller/cubepilot_cube_yellow.md) - [Cube Wiring Quickstart](assembly/quick_start_cube.md) + - [Gear Up AirBrainH743](flight_controller/gearup_airbrainh743.md) - [Holybro Kakute H7v2](flight_controller/kakuteh7v2.md) - [Holybro Kakute H7mini](flight_controller/kakuteh7mini.md) - [Holybro Kakute H7](flight_controller/kakuteh7.md) diff --git a/docs/en/flight_controller/autopilot_manufacturer_supported.md b/docs/en/flight_controller/autopilot_manufacturer_supported.md index aa1d4cb5cb..9cdb3492e4 100644 --- a/docs/en/flight_controller/autopilot_manufacturer_supported.md +++ b/docs/en/flight_controller/autopilot_manufacturer_supported.md @@ -25,6 +25,7 @@ The boards in this category are: - [CubePilot Cube Orange+](../flight_controller/cubepilot_cube_orangeplus.md) - [CubePilot Cube Orange](../flight_controller/cubepilot_cube_orange.md) - [CubePilot Cube Yellow](../flight_controller/cubepilot_cube_yellow.md) +- [Gear Up AirBrainH743](../flight_controller/gearup_airbrainh743.md) - [Holybro Kakute H7v2](../flight_controller/kakuteh7v2.md) - [Holybro Kakute H7mini](../flight_controller/kakuteh7mini.md) - [Holybro Kakute H7](../flight_controller/kakuteh7.md) diff --git a/docs/en/flight_controller/gearup_airbrainh743.md b/docs/en/flight_controller/gearup_airbrainh743.md new file mode 100644 index 0000000000..44c3c9ecc1 --- /dev/null +++ b/docs/en/flight_controller/gearup_airbrainh743.md @@ -0,0 +1,96 @@ +# Gear Up AirBrainH743 + +:::warning +PX4 does not manufacture this (or any) autopilot. +Contact the [manufacturer](https://takeyourgear.com/) for hardware support. +::: + +::: info +This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +For more information and pinout, check the [GitHub documentation](https://github.com/GearUp-Company/AirBrainH743). + +## Key Features + +- MCU: STM32H743 32-bit processor running at 480 MHz +- IMU: ICM42688P +- Barometer: DPS310 +- Magnetometer: LIS2MDL (internal) +- 128MB NAND Flash for logging (W25N) +- 7x UARTs +- I2C, SPI +- 9x PWM Outputs (8 Motor outputs, 1 LED strip) +- Battery input voltage: 3S-10S +- Battery voltage/current monitoring +- 5V@2A and 10V@2.5A BEC outputs +- USB Type-C (IP68) +- EMC and ESD protection + +## Connectors and Pins + +:::warning +The pin order is different from the Pixhawk standard (compatible to the Betaflight standard). +::: + +### UARTs + +Current UART configuration: + +| UART | Device | Function | +| ------ | ---------- | ---------------------------- | +| USART1 | /dev/ttyS0 | Console/Debug | +| USART2 | /dev/ttyS1 | RC Input | +| USART3 | /dev/ttyS2 | TEL4 (DJI/MSP) | +| UART4 | /dev/ttyS3 | TEL1 | +| UART5 | /dev/ttyS4 | TEL2 | +| UART7 | /dev/ttyS5 | TEL3 (ESC Telemetry) | +| UART8 | /dev/ttyS6 | GPS1 | + +### Motor/Servo Outputs + +| Connector | Pin | Function | +| ----------| ------------------ | +| ESC | M1 | Motor 1 | +| ESC | M2 | Motor 2 | +| ESC | M3 | Motor 3 | +| ESC | M4 | Motor 4 | +| PWM | M5 | Motor 5 | +| PWM | M6 | Motor 6 | +| PWM | M7 | Motor 7 | +| PWM | M8 | Motor 8 | +| AUX | M9 | LED/PWM/etc. | + + + +## PX4 Bootloader Update + +Before PX4 firmware can be installed, the _PX4 bootloader_ must be flashed. +Download the [gearup_airbrainh743_bootloader.bin](https://github.com/PX4/PX4-Autopilot/blob/main/boards/gearup/airbrainh743/extras/gearup_airbrainh743_bootloader.bin) bootloader binary and read [this page](../advanced_config/bootloader_update_from_betaflight.md) for flashing instructions. + +## Building Firmware + +To [build PX4](../dev_setup/building_px4.md) for this target: + +``` +make gearup_airbrainh743_default +``` + +## Installing PX4 Firmware + +Firmware can be installed in any of the normal ways: + +- Build and upload the source: + + ``` + make gearup_airbrainh743_default upload + ``` + +- [Load the firmware](../config/firmware.md) using _QGroundControl_. + You can use either pre-built firmware or your own custom firmware. + +## Debug Port + +### System Console + +UART1 (ttyS0) is configured for use as the [System Console](../debug/system_console.md).