From 7ef529ec448426aabfea75d1cc7bbb11cc4751a2 Mon Sep 17 00:00:00 2001 From: 19y Date: Sat, 29 Aug 2026 00:10:12 +0800 Subject: [PATCH 01/15] arch/stm32h7: improve Ethernet MII PHY polling on STM32H750B-DK Add PHY status polling and board-specific MII configuration for reliable RJ45 link bring-up on the VelaGuard extension board. Contest: contest2026_004 Team Falcons / VelaGuard Co-authored-by: Cursor --- arch/arm/src/stm32h7/stm32_ethernet.c | 229 +++++++++++++++++- .../arm/stm32h7/stm32h750b-dk/include/board.h | 11 + 2 files changed, 239 insertions(+), 1 deletion(-) diff --git a/arch/arm/src/stm32h7/stm32_ethernet.c b/arch/arm/src/stm32h7/stm32_ethernet.c index d685f27b28f..b177288f08f 100644 --- a/arch/arm/src/stm32h7/stm32_ethernet.c +++ b/arch/arm/src/stm32h7/stm32_ethernet.c @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -65,6 +66,11 @@ #include +#ifdef BOARD_ETH_PHY_POLL +# define STM32_LINK_POLL_DELAY MSEC2TICK(500) +# define STM32_LINK_DEBOUNCE 2 +#endif + /* STM32H7_NETHERNET determines the number of physical interfaces that can * be supported by the hardware. CONFIG_STM32H7_ETHMAC will defined if * any STM32H7 Ethernet support is enabled in the configuration. @@ -612,6 +618,13 @@ struct stm32_ethmac_s struct wdog_s txtimeout; /* TX timeout timer */ struct work_s irqwork; /* For deferring interrupt work to the work queue */ struct work_s pollwork; /* For deferring poll work to the work queue */ +#ifdef BOARD_ETH_PHY_POLL + struct work_s linkwork; /* For polling the PHY link state */ + uint8_t linksamples; /* Number of matching PHY samples */ + bool linkstate; /* Last published PHY link state */ + bool linkcandidate; + bool linkerror; /* MDIO failure already reported */ +#endif /* This holds the information visible to the NuttX network */ @@ -756,6 +769,10 @@ static int stm32_phywrite(uint16_t phydevaddr, uint16_t phyregaddr, static inline int stm32_dm9161(struct stm32_ethmac_s *priv); #endif static int stm32_phyinit(struct stm32_ethmac_s *priv); +#ifdef BOARD_ETH_PHY_POLL +static int stm32_phylinkread(bool *linkup); +static void stm32_link_work(void *arg); +#endif #ifdef CONFIG_STM32H7_ETHMAC_REGDEBUG static void stm32_phyregdump(void); #endif @@ -2417,6 +2434,11 @@ static int stm32_ifup(struct net_driver_s *dev) struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)dev->d_private; int ret; + if (priv->ifup) + { + return OK; + } + #ifdef CONFIG_NET_IPv4 ninfo("Bringing up: %u.%u.%u.%u\n", ip4_addr1(dev->d_ipaddr), ip4_addr2(dev->d_ipaddr), @@ -2443,6 +2465,32 @@ static int stm32_ifup(struct net_driver_s *dev) up_enable_irq(STM32_IRQ_ETH); stm32_checksetup(); +#ifdef BOARD_ETH_PHY_POLL + ret = stm32_phylinkread(&priv->linkstate); + if (ret < 0 || !priv->linkstate) + { + priv->linkstate = false; + netdev_carrier_off(dev); + } + else + { + netdev_carrier_on(dev); + } + + priv->linkcandidate = priv->linkstate; + priv->linksamples = 0; + priv->linkerror = false; + ret = work_queue(LPWORK, &priv->linkwork, stm32_link_work, priv, + STM32_LINK_POLL_DELAY); + if (ret < 0) + { + nerr("ERROR: Failed to schedule PHY link work: %d\n", ret); + stm32_ifdown(dev); + return ret; + } +#else + netdev_carrier_on(dev); +#endif return OK; } @@ -2471,6 +2519,16 @@ static int stm32_ifdown(struct net_driver_s *dev) /* Disable the Ethernet interrupt */ + priv->ifup = false; +#ifdef BOARD_ETH_PHY_POLL + work_cancel(LPWORK, &priv->linkwork); + priv->linkstate = false; + priv->linkcandidate = false; + priv->linksamples = 0; + priv->linkerror = false; +#endif + netdev_carrier_off(dev); + flags = enter_critical_section(); up_disable_irq(STM32_IRQ_ETH); @@ -2487,7 +2545,6 @@ static int stm32_ifdown(struct net_driver_s *dev) /* Mark the device "down" */ - priv->ifup = false; leave_critical_section(flags); return OK; } @@ -3363,6 +3420,18 @@ static int stm32_phyinit(struct stm32_ethmac_s *priv) /* Perform auto-negotiation if so configured */ #ifdef CONFIG_STM32H7_AUTONEG +#ifdef BOARD_ETH_PHY_POLL + /* Start auto-negotiation even when booting without a cable. */ + + ret = stm32_phywrite(CONFIG_STM32H7_PHYADDR, MII_MCR, + MII_MCR_ANENABLE, MII_MCR_ANENABLE); + if (ret < 0) + { + nerr("ERROR: Failed to enable auto-negotiation: %d\n", ret); + return ret; + } +#endif + /* Wait for link status */ for (timeout = 0; timeout < PHY_RETRY_TIMEOUT; timeout++) @@ -3384,7 +3453,12 @@ static int stm32_phyinit(struct stm32_ethmac_s *priv) if (timeout >= PHY_RETRY_TIMEOUT) { nerr("ERROR: Timed out waiting for link status: %04x\n", phyval); +#ifdef BOARD_ETH_PHY_POLL + ninfo("Continuing with carrier off until PHY polling finds a link\n"); + return OK; +#else return -ETIMEDOUT; +#endif } /* Enable auto-negotiation */ @@ -3524,6 +3598,157 @@ static int stm32_phyinit(struct stm32_ethmac_s *priv) return OK; } +#ifdef BOARD_ETH_PHY_POLL +/**************************************************************************** + * Function: stm32_phylinkread + * + * Description: + * Read the PHY link state. MII_MSR link status is latch-low, so the + * register must be read twice to obtain the current value. + * + ****************************************************************************/ + +static int stm32_phylinkread(bool *linkup) +{ + uint16_t phyval; + int ret; + + ret = stm32_phyread(CONFIG_STM32H7_PHYADDR, MII_MSR, &phyval); + if (ret < 0) + { + return ret; + } + + ret = stm32_phyread(CONFIG_STM32H7_PHYADDR, MII_MSR, &phyval); + if (ret >= 0) + { + *linkup = (phyval & MII_MSR_LINKSTATUS) != 0; + } + + return ret; +} + +/**************************************************************************** + * Function: stm32_maclinkconfig + * + * Description: + * Synchronize the MAC speed and duplex bits after PHY auto-negotiation. + * + ****************************************************************************/ + +static void stm32_maclinkconfig(struct stm32_ethmac_s *priv) +{ + uint32_t regval; + uint32_t enabled; + + regval = stm32_getreg(STM32_ETH_MACCR); + enabled = regval & (ETH_MACCR_RE | ETH_MACCR_TE); + regval &= ~(ETH_MACCR_RE | ETH_MACCR_TE | ETH_MACCR_DM | + ETH_MACCR_FES); + stm32_putreg(regval, STM32_ETH_MACCR); + + if (priv->fduplex) + { + regval |= ETH_MACCR_DM; + } + + if (priv->mbps100) + { + regval |= ETH_MACCR_FES; + } + + stm32_putreg(regval | enabled, STM32_ETH_MACCR); +} + +/**************************************************************************** + * Function: stm32_link_work + * + * Description: + * Poll and debounce the external PHY link state from LPWORK. + * + ****************************************************************************/ + +static void stm32_link_work(void *arg) +{ + struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)arg; + bool linkup; + int ret; + + net_lock(); + if (!priv->ifup) + { + net_unlock(); + return; + } + + ret = stm32_phylinkread(&linkup); + if (ret < 0) + { + if (!priv->linkerror) + { + nwarn("WARNING: Failed to read PHY link state: %d\n", ret); + priv->linkerror = true; + } + + goto reschedule; + } + + if (priv->linkerror) + { + ninfo("PHY link status reads recovered\n"); + priv->linkerror = false; + } + + if (linkup != priv->linkcandidate) + { + priv->linkcandidate = linkup; + priv->linksamples = 1; + } + else if (priv->linksamples < STM32_LINK_DEBOUNCE) + { + priv->linksamples++; + } + + if (priv->linksamples >= STM32_LINK_DEBOUNCE && + linkup != priv->linkstate) + { + if (linkup) + { + ret = stm32_phyinit(priv); + if (ret < 0 || stm32_phylinkread(&linkup) < 0 || !linkup) + { + goto reschedule; + } + + stm32_maclinkconfig(priv); + priv->linkstate = true; + netdev_carrier_on(&priv->dev); + ninfo("PHY link is up\n"); + } + else + { + wd_cancel(&priv->txtimeout); + priv->linkstate = false; + netdev_carrier_off(&priv->dev); + ninfo("PHY link is down\n"); + } + } + +reschedule: + if (priv->ifup) + { + ret = work_queue(LPWORK, &priv->linkwork, stm32_link_work, priv, + STM32_LINK_POLL_DELAY); + if (ret < 0) + { + nwarn("WARNING: Failed to reschedule PHY link work: %d\n", ret); + } + } + + net_unlock(); +} +#endif + #endif /**************************************************************************** @@ -3651,8 +3876,10 @@ static inline void stm32_ethgpioconfig(struct stm32_ethmac_s *priv) * MII_RX_ER, MII_RX_DV, MII_CRS, MII_COL, MDC, MDIO */ +# ifndef BOARD_ETH_MII_NO_CRS_COL stm32_configgpio(GPIO_ETH_MII_COL); stm32_configgpio(GPIO_ETH_MII_CRS); +# endif stm32_configgpio(GPIO_ETH_MII_RXD0); stm32_configgpio(GPIO_ETH_MII_RXD1); stm32_configgpio(GPIO_ETH_MII_RXD2); diff --git a/boards/arm/stm32h7/stm32h750b-dk/include/board.h b/boards/arm/stm32h7/stm32h750b-dk/include/board.h index af5f8ed0bb6..0b5aa45d283 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/include/board.h +++ b/boards/arm/stm32h7/stm32h750b-dk/include/board.h @@ -275,6 +275,17 @@ /* Ethernet definitions *****************************************************/ +/* MB1381 H750XB-B01 routes the LAN8740A through full MII. PH2/MII_CRS and + * PH3/MII_COL share pins with QSPI bank 2 IO0/IO1. QSPI-XIP builds must + * leave those pins in their QSPI alternate function; negotiated full-duplex + * Ethernet does not use CRS/COL. + */ + +#ifdef CONFIG_STM32H750B_DK_QSPI_BOOT +# define BOARD_ETH_MII_NO_CRS_COL 1 +# define BOARD_ETH_PHY_POLL 1 +#endif + /* The STM32H7 connects to a LAN8740A PHY using these pins: * * STM32H7 BOARD LAN8740A From 4fd6cbce017d89d2e405ceb05a889e5eb0e7bdd0 Mon Sep 17 00:00:00 2001 From: 19y Date: Sat, 29 Aug 2026 22:31:07 +0800 Subject: [PATCH 02/15] fix(stm32h7): wait for USART TC on RS485 tcdrain path Disable FIFO on RS485 ports, make txempty require TXE|TC then drop DIR in thread context, and avoid flipping DIR from the TC ISR mid-frame. --- arch/arm/src/stm32h7/stm32_serial.c | 66 +++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/arch/arm/src/stm32h7/stm32_serial.c b/arch/arm/src/stm32h7/stm32_serial.c index 506488b5fb4..2e2e5480c33 100644 --- a/arch/arm/src/stm32h7/stm32_serial.c +++ b/arch/arm/src/stm32h7/stm32_serial.c @@ -688,6 +688,7 @@ static void up_send(struct uart_dev_s *dev, int ch); static void up_txint(struct uart_dev_s *dev, bool enable); #endif static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); #ifdef SERIAL_HAVE_TXDMA static void up_dma_send(struct uart_dev_s *dev); @@ -742,7 +743,7 @@ static const struct uart_ops_s g_uart_ops = .send = up_send, .txint = up_txint, .txready = up_txready, - .txempty = up_txready, + .txempty = up_txempty, }; #endif @@ -763,7 +764,7 @@ static const struct uart_ops_s g_uart_rxtxdma_ops = .send = up_send, .txint = up_dma_txint, .txready = up_txready, - .txempty = up_txready, + .txempty = up_txempty, .dmatxavail = up_dma_txavailable, .dmasend = up_dma_send, }; @@ -786,7 +787,7 @@ static const struct uart_ops_s g_uart_rxdma_ops = .send = up_send, .txint = up_txint, .txready = up_txready, - .txempty = up_txready, + .txempty = up_txempty, }; #endif @@ -807,7 +808,7 @@ static const struct uart_ops_s g_uart_txdma_ops = .send = up_send, .txint = up_dma_txint, .txready = up_txready, - .txempty = up_txready, + .txempty = up_txempty, .dmatxavail = up_dma_txavailable, .dmasend = up_dma_send, }; @@ -2161,15 +2162,22 @@ static int up_setup(struct uart_dev_s *dev) /* Enable Rx, Tx, and the USART */ - /* Enable FIFO */ - regval = up_serialin(priv, STM32_USART_CR1_OFFSET); regval |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); #ifdef SERIAL_HAVE_RXDMA regval |= USART_CR1_IDLEIE; #endif - regval |= USART_CR1_FIFOEN; + /* H7 defaults to FIFOEN (TXE becomes TXFNF). For RS-485 half-duplex, + * keep classic shift-register semantics so TC/DIR timing stays sane. + */ + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio == 0) +#endif + { + regval |= USART_CR1_FIFOEN; + } up_serialout(priv, STM32_USART_CR1_OFFSET, regval); @@ -2330,8 +2338,11 @@ static void up_shutdown(struct uart_dev_s *dev) #endif #ifdef HAVE_RS485 + /* Return bus to receive before releasing the pin. */ + if (priv->rs485_dir_gpio != 0) { + stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); stm32_unconfiggpio(priv->rs485_dir_gpio); } #endif @@ -2497,13 +2508,17 @@ static int up_interrupt(int irq, void *context, void *arg) * Note - this should be first, to have the most recent TC bit value * from SR register - sending data affects TC, but without refresh we * will not know that... + * + * Do NOT drop DIR to RX here. Flip DIR in up_txempty() after tcdrain + * sees TXE|TC (thread context), or in up_shutdown(). ISR-only DIR drops + * were implicated in mid-frame bus floats when combined with a bad USB + * adapter; LA on DI/DIR proved MCU timing fine once the peer PHY was OK. */ if ((priv->sr & USART_ISR_TC) != 0 && (priv->ie & USART_CR1_TCIE) != 0 && (priv->ie & USART_CR1_TXEIE) == 0) { - stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); up_restoreusartint(priv, priv->ie & ~USART_CR1_TCIE); } #endif @@ -3520,6 +3535,9 @@ static void up_txint(struct uart_dev_s *dev, bool enable) # ifdef HAVE_RS485 if (priv->rs485_dir_gpio != 0) { + /* Clear stale TC so enabling TCIE does not race the next frame. */ + + up_serialout(priv, STM32_USART_ICR_OFFSET, USART_ICR_TCCF); ie |= USART_CR1_TCIE; } # endif @@ -3567,6 +3585,38 @@ static bool up_txready(struct uart_dev_s *dev) return ((up_serialin(priv, STM32_USART_ISR_OFFSET) & USART_ISR_TXE) != 0); } +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true when the transmitter is fully idle. For RS-485 require + * TXE|TC then force DIR to receive so tcdrain() outlives the shift + * register without an app-layer usleep(). + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t isr = up_serialin(priv, STM32_USART_ISR_OFFSET); + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + if ((isr & (USART_ISR_TXE | USART_ISR_TC)) != + (USART_ISR_TXE | USART_ISR_TC)) + { + return false; + } + + stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); + return true; + } +#endif + + return (isr & USART_ISR_TXE) != 0; +} + /**************************************************************************** * Name: up_dma_rxcallback * From 297da213cd445bf5847482df9ec27063772f6f8a Mon Sep 17 00:00:00 2001 From: 19y Date: Sun, 30 Aug 2026 13:32:02 +0800 Subject: [PATCH 03/15] feat(stm32h750b-dk): add velaguard-net preset with eMMC and ai_agent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add velaguard-net/emmc/ai-probe defconfigs, SDMMC bring-up, /data layout mkdir on eMMC, and stage0→stage1 config path migration for VelaGuard stage1. Co-authored-by: Cursor --- arch/arm/src/stm32h7/stm32_mpuinit.c | 11 ++ boards/Kconfig | 2 +- boards/arm/stm32h7/stm32h750b-dk/Kconfig | 11 ++ .../configs/velaguard-ai-probe/defconfig | 131 +++++++++++++++ .../configs/velaguard-emmc/defconfig | 121 ++++++++++++++ .../configs/velaguard-net/defconfig | 147 +++++++++++++++++ .../arm/stm32h7/stm32h750b-dk/include/board.h | 41 ++++- .../stm32h7/stm32h750b-dk/scripts/Make.defs | 6 +- .../stm32h750b-dk/scripts/qspi_flash.ld | 110 +++++++++++++ .../stm32h7/stm32h750b-dk/src/CMakeLists.txt | 16 +- boards/arm/stm32h7/stm32h750b-dk/src/Makefile | 10 +- .../stm32h7/stm32h750b-dk/src/stm32_bringup.c | 154 ++++++++++++++++++ .../arm/stm32h7/stm32h750b-dk/src/stm32_pwm.c | 56 +++++++ .../stm32h7/stm32h750b-dk/src/stm32_sdmmc.c | 111 +++++++++++++ .../stm32h7/stm32h750b-dk/src/stm32h750b-dk.h | 27 +++ 15 files changed, 949 insertions(+), 5 deletions(-) create mode 100644 boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-ai-probe/defconfig create mode 100644 boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-emmc/defconfig create mode 100644 boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-net/defconfig create mode 100644 boards/arm/stm32h7/stm32h750b-dk/scripts/qspi_flash.ld create mode 100644 boards/arm/stm32h7/stm32h750b-dk/src/stm32_pwm.c create mode 100644 boards/arm/stm32h7/stm32h750b-dk/src/stm32_sdmmc.c diff --git a/arch/arm/src/stm32h7/stm32_mpuinit.c b/arch/arm/src/stm32h7/stm32_mpuinit.c index a42fdc8ad09..e923d76f48e 100644 --- a/arch/arm/src/stm32h7/stm32_mpuinit.c +++ b/arch/arm/src/stm32h7/stm32_mpuinit.c @@ -50,6 +50,11 @@ # endif #endif +#ifdef CONFIG_STM32H750B_DK_QSPI_BOOT +# define STM32_QSPI_BOOT_BASE 0x90000000 +# define STM32_QSPI_BOOT_SIZE (128 * 1024 * 1024) +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -101,6 +106,12 @@ void stm32_mpuinitialize(void) mpu_priv_shmem((uintptr_t)STM32_SHMEM_BASE, STM32_SHMEM_SIZE); #endif +#ifdef CONFIG_STM32H750B_DK_QSPI_BOOT + /* Keep the external QSPI XIP window executable after the MPU is enabled. */ + + mpu_priv_flash((uintptr_t)STM32_QSPI_BOOT_BASE, STM32_QSPI_BOOT_SIZE); +#endif + /* Then enable the MPU */ mpu_control(true, false, true); diff --git a/boards/Kconfig b/boards/Kconfig index c5591528c36..3c64df0b030 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -4137,7 +4137,7 @@ endif if ARCH_BOARD_STM32H745I_DISCO source "boards/arm/stm32h7/stm32h745i-disco/Kconfig" endif -if ARCH_BOARD_STM32H750B_DB +if ARCH_BOARD_STM32H750B_DK source "boards/arm/stm32h7/stm32h750b-dk/Kconfig" endif if ARCH_BOARD_LINUM_STM32H753BI diff --git a/boards/arm/stm32h7/stm32h750b-dk/Kconfig b/boards/arm/stm32h7/stm32h750b-dk/Kconfig index 68542f0f611..2f4389e6bb1 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/Kconfig +++ b/boards/arm/stm32h7/stm32h750b-dk/Kconfig @@ -5,4 +5,15 @@ if ARCH_BOARD_STM32H750B_DK +config STM32H750B_DK_QSPI_BOOT + bool "Link Cortex-M7 image for external QSPI boot" + default n + depends on ARCH_CHIP_STM32H7_CORTEXM7 + ---help--- + Build the main NuttX image for the STM32H750B-DK external + dual-QSPI memory-mapped window at 0x90000000 instead of the + 128 KiB on-die Flash at 0x08000000. This image needs a small + internal-Flash boot stub that initializes QSPI memory-mapped + mode before jumping to the external vector table. + endif # ARCH_BOARD_STM32H750B_DK diff --git a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-ai-probe/defconfig b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-ai-probe/defconfig new file mode 100644 index 00000000000..21c50e1c7a5 --- /dev/null +++ b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-ai-probe/defconfig @@ -0,0 +1,131 @@ +# +# 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_AI_AGENT_FEISHU is not set +# CONFIG_AI_AGENT_MCP is not set +# CONFIG_AI_AGENT_MQTT is not set +# CONFIG_AI_AGENT_NODE is not set +# CONFIG_AI_AGENT_WEIXIN is not set +# CONFIG_ARCH_LEDS is not set +# CONFIG_MBEDTLS_ARIA_C is not set +# CONFIG_MBEDTLS_CCM_C is not set +# CONFIG_STANDARD_SERIAL is not set +# CONFIG_STM32H7_CORTEXM4_ENABLED is not set +# CONFIG_STM32H7_USE_LEGACY_PINMAP is not set +CONFIG_AI_AGENT_TLS_CONN_POOL_SIZE=1 +CONFIG_ALLOW_BSD_COMPONENTS=y +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="stm32h750b-dk" +CONFIG_ARCH_BOARD_STM32H750B_DK=y +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H750B=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_CHIP_STM32H7_CORTEXM7=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARM_MPU=y +CONFIG_BOARD_LOOPSPERMSEC=43103 +CONFIG_BUILTIN=y +CONFIG_CRYPTO_MBEDTLS=y +CONFIG_DEV_URANDOM=y +CONFIG_ETH0_PHY_LAN8740A=y +CONFIG_EXAMPLES_AI_AGENT_VELA=y +CONFIG_FS_LINKS=y +CONFIG_FS_LITTLEFS=y +CONFIG_FS_PROCFS=y +CONFIG_FS_TMPFS=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_LINE_MAX=64 +CONFIG_MBEDTLS_THREADING_C=y +CONFIG_MBEDTLS_THREADING_PTHREAD=y +CONFIG_MM_HEAP_MEMPOOL_THRESHOLD=0 +CONFIG_MM_REGIONS=6 +CONFIG_MQ_MAXMSGSIZE=256 +CONFIG_NET=y +CONFIG_NETDB_DNSCLIENT=y +CONFIG_NETINIT_CARRIER_POLL=y +CONFIG_NETINIT_DHCPC=y +CONFIG_NETINIT_DNS=y +CONFIG_NETINIT_THREAD=y +CONFIG_NETUTILS_CJSON=y +CONFIG_NETUTILS_DHCPC=y +CONFIG_NETUTILS_DHCPC_BOOTP_FLAGS=0x8000 +CONFIG_NETUTILS_ESP8266=y +CONFIG_NETUTILS_ESP8266_BAUDRATE=115200 +CONFIG_NETUTILS_ESP8266_DEV_PATH="/dev/ttyS1" +CONFIG_NETUTILS_MQTTC=y +CONFIG_NETUTILS_WEBCLIENT=y +CONFIG_NET_BROADCAST=y +CONFIG_NET_ETH_PKTSIZE=1500 +CONFIG_NET_ICMP_SOCKET=y +CONFIG_NET_TCP=y +CONFIG_NET_UDP=y +CONFIG_NET_UDP_CHECKSUMS=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PIPES=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PSEUDOFS_FILE=y +CONFIG_PTHREAD_MUTEX_TYPES=y +CONFIG_PWM=y +CONFIG_RAMMTD=y +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_CPULOAD_SYSCLK=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_STM32H750B_DK_QSPI_BOOT=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_DMA2=y +CONFIG_STM32H7_ETHMAC=y +CONFIG_STM32H7_FMC=y +CONFIG_STM32H7_MII=y +CONFIG_STM32H7_PHYADDR=1 +CONFIG_STM32H7_PHYSR=31 +CONFIG_STM32H7_PHYSR_100FD=0x0018 +CONFIG_STM32H7_PHYSR_100HD=0x0008 +CONFIG_STM32H7_PHYSR_10FD=0x0014 +CONFIG_STM32H7_PHYSR_10HD=0x0004 +CONFIG_STM32H7_PHYSR_ALTCONFIG=y +CONFIG_STM32H7_PHYSR_ALTMODE=0x001c +CONFIG_STM32H7_PWR_DIRECT_SMPS_SUPPLY=y +CONFIG_STM32H7_TIM15=y +CONFIG_STM32H7_TIM15_CH2OUT=y +CONFIG_STM32H7_TIM15_CHANNEL=2 +CONFIG_STM32H7_TIM15_PWM=y +CONFIG_STM32H7_UART7=y +CONFIG_STM32H7_USART2=y +CONFIG_STM32H7_USART3=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_PING=y +CONFIG_SYSTEM_POPEN=y +CONFIG_SYSTEM_SYSTEM=y +CONFIG_TLS_TASK_NELEM=4 +CONFIG_TTY_SIGINT=y +CONFIG_UART7_BAUD=9600 +CONFIG_UART7_RS485=y +CONFIG_USART3_SERIAL_CONSOLE=y +CONFIG_VG_BRINGUP_TOOLS=y +CONFIG_VG_NET_FAILOVER=y +CONFIG_VG_WIFI_PASSWORD="12345678" +CONFIG_VG_WIFI_SSID="ASUS" diff --git a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-emmc/defconfig b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-emmc/defconfig new file mode 100644 index 00000000000..50624968941 --- /dev/null +++ b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-emmc/defconfig @@ -0,0 +1,121 @@ +# +# 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_ARCH_LEDS is not set +# CONFIG_MMCSD_HAVE_CARDDETECT is not set +# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_SPI is not set +# CONFIG_STANDARD_SERIAL is not set +# CONFIG_STM32H7_CORTEXM4_ENABLED is not set +# CONFIG_STM32H7_SDMMC_IDMA is not set +# CONFIG_STM32H7_USE_LEGACY_PINMAP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="stm32h750b-dk" +CONFIG_ARCH_BOARD_STM32H750B_DK=y +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H750B=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_CHIP_STM32H7_CORTEXM7=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARM_MPU=y +CONFIG_BOARD_LOOPSPERMSEC=43103 +CONFIG_BUILTIN=y +CONFIG_ETH0_PHY_LAN8740A=y +CONFIG_FAT_LFN=y +CONFIG_FS_LINKS=y +CONFIG_FS_FAT=y +CONFIG_FS_PROCFS=y +CONFIG_INIT_ENTRYPOINT="velaguard_app_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_LINE_MAX=64 +CONFIG_MMCSD=y +CONFIG_MMCSD_MMCSUPPORT=y +CONFIG_MMCSD_SDIO=y +CONFIG_MM_HEAP_MEMPOOL_THRESHOLD=0 +CONFIG_MM_REGIONS=6 +CONFIG_MQ_MAXMSGSIZE=256 +CONFIG_NET=y +CONFIG_NETDB_DNSCLIENT=y +CONFIG_NETINIT_CARRIER_POLL=y +CONFIG_NETINIT_DHCPC=y +CONFIG_NETINIT_DNS=y +CONFIG_NETINIT_THREAD=y +CONFIG_NETUTILS_DHCPC=y +CONFIG_NETUTILS_DHCPC_BOOTP_FLAGS=0x8000 +CONFIG_NETUTILS_MQTTC=y +CONFIG_NETUTILS_ESP8266=y +CONFIG_NETUTILS_ESP8266_DEV_PATH="/dev/ttyS1" +CONFIG_NETUTILS_ESP8266_BAUDRATE=115200 +CONFIG_VG_NET_FAILOVER=y +CONFIG_VG_WIFI_SSID="ASUS" +CONFIG_VG_WIFI_PASSWORD="12345678" +CONFIG_NET_BROADCAST=y +CONFIG_NET_ETH_PKTSIZE=1500 +CONFIG_NET_ICMP_SOCKET=y +CONFIG_NET_TCP=y +CONFIG_NET_UDP=y +CONFIG_NET_UDP_CHECKSUMS=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PSEUDOFS_FILE=y +CONFIG_PWM=y +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_CPULOAD_SYSCLK=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SDMMC1_SDIO_PULLUP=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_STM32H750B_DK_QSPI_BOOT=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_DMA2=y +CONFIG_STM32H7_ETHMAC=y +CONFIG_STM32H7_FMC=y +CONFIG_STM32H7_MII=y +CONFIG_STM32H7_PHYADDR=1 +CONFIG_STM32H7_PHYSR=31 +CONFIG_STM32H7_PHYSR_100FD=0x0018 +CONFIG_STM32H7_PHYSR_100HD=0x0008 +CONFIG_STM32H7_PHYSR_10FD=0x0014 +CONFIG_STM32H7_PHYSR_10HD=0x0004 +CONFIG_STM32H7_PHYSR_ALTCONFIG=y +CONFIG_STM32H7_PHYSR_ALTMODE=0x001c +CONFIG_STM32H7_PWR_DIRECT_SMPS_SUPPLY=y +CONFIG_STM32H7_SDMMC1=y +CONFIG_STM32H7_TIM15=y +CONFIG_STM32H7_TIM15_CH2OUT=y +CONFIG_STM32H7_TIM15_CHANNEL=2 +CONFIG_STM32H7_TIM15_PWM=y +CONFIG_STM32H7_UART7=y +CONFIG_STM32H7_USART2=y +CONFIG_STM32H7_USART3=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_PING=y +CONFIG_TTY_SIGINT=y +CONFIG_UART7_BAUD=9600 +CONFIG_UART7_RS485=y +CONFIG_USART3_SERIAL_CONSOLE=y +CONFIG_VG_BRINGUP_TOOLS=y +CONFIG_VG_CONFIG_STORE=y +CONFIG_VG_CONFIG_BASEDIR="/mnt/emmc/velaguard/config" +CONFIG_VG_FRAME_STATS=y diff --git a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-net/defconfig b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-net/defconfig new file mode 100644 index 00000000000..6dd5fe37225 --- /dev/null +++ b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-net/defconfig @@ -0,0 +1,147 @@ +# +# 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_AI_AGENT_FEISHU is not set +# CONFIG_AI_AGENT_MCP is not set +# CONFIG_AI_AGENT_MQTT is not set +# CONFIG_AI_AGENT_NODE is not set +# CONFIG_AI_AGENT_WEIXIN is not set +# CONFIG_ARCH_LEDS is not set +# CONFIG_MBEDTLS_ARIA_C is not set +# CONFIG_MBEDTLS_CCM_C is not set +# CONFIG_MMCSD_HAVE_CARDDETECT is not set +# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_SPI is not set +# CONFIG_STANDARD_SERIAL is not set +# CONFIG_STM32H7_CORTEXM4_ENABLED is not set +# CONFIG_STM32H7_SDMMC_IDMA is not set +# CONFIG_STM32H7_USE_LEGACY_PINMAP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="stm32h750b-dk" +CONFIG_ARCH_BOARD_STM32H750B_DK=y +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H750B=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_CHIP_STM32H7_CORTEXM7=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARM_MPU=y +CONFIG_BOARD_LOOPSPERMSEC=43103 +CONFIG_BUILTIN=y +CONFIG_AI_AGENT_TLS_CONN_POOL_SIZE=1 +CONFIG_ALLOW_BSD_COMPONENTS=y +CONFIG_CRYPTO_MBEDTLS=y +CONFIG_DEV_URANDOM=y +CONFIG_ETH0_PHY_LAN8740A=y +CONFIG_EXAMPLES_AI_AGENT_VELA=y +CONFIG_EXAMPLES_AI_AGENT_VELA_DATA_DIR="/data/agent" +CONFIG_EXAMPLES_AI_AGENT_VELA_NODE_DISPLAY_NAME="VelaGuard" +CONFIG_EXAMPLES_AI_AGENT_VELA_NODE_ID="velaguard-01" +CONFIG_FAT_LFN=y +CONFIG_FS_FAT=y +CONFIG_FS_LINKS=y +CONFIG_FS_PROCFS=y +CONFIG_INIT_ENTRYPOINT="velaguard_app_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_LINE_MAX=64 +CONFIG_MBEDTLS_THREADING_C=y +CONFIG_MBEDTLS_THREADING_PTHREAD=y +CONFIG_MMCSD=y +CONFIG_MMCSD_MMCSUPPORT=y +CONFIG_MMCSD_SDIO=y +CONFIG_MM_HEAP_MEMPOOL_THRESHOLD=0 +CONFIG_MM_REGIONS=6 +CONFIG_MQ_MAXMSGSIZE=256 +CONFIG_NET=y +CONFIG_NETDB_DNSCLIENT=y +CONFIG_NETINIT_CARRIER_POLL=y +CONFIG_NETINIT_DHCPC=y +CONFIG_NETINIT_DNS=y +CONFIG_NETINIT_THREAD=y +CONFIG_NETUTILS_DHCPC=y +CONFIG_NETUTILS_DHCPC_BOOTP_FLAGS=0x8000 +CONFIG_NETUTILS_CJSON=y +CONFIG_NETUTILS_MQTTC=y +CONFIG_NETUTILS_WEBCLIENT=y +CONFIG_NETUTILS_ESP8266=y +CONFIG_NETUTILS_ESP8266_DEV_PATH="/dev/ttyS1" +CONFIG_NETUTILS_ESP8266_BAUDRATE=115200 +CONFIG_VG_NET_FAILOVER=y +CONFIG_VG_WIFI_SSID="ASUS" +CONFIG_VG_WIFI_PASSWORD="12345678" +CONFIG_NET_BROADCAST=y +CONFIG_NET_ETH_PKTSIZE=1500 +CONFIG_NET_ICMP_SOCKET=y +CONFIG_NET_TCP=y +CONFIG_NET_UDP=y +CONFIG_NET_UDP_CHECKSUMS=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PIPES=y +CONFIG_PSEUDOFS_FILE=y +CONFIG_PTHREAD_MUTEX_TYPES=y +CONFIG_PWM=y +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_CPULOAD_SYSCLK=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SDMMC1_SDIO_PULLUP=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_STM32H750B_DK_QSPI_BOOT=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_DMA2=y +CONFIG_STM32H7_ETHMAC=y +CONFIG_STM32H7_FMC=y +CONFIG_STM32H7_MII=y +CONFIG_STM32H7_PHYADDR=1 +CONFIG_STM32H7_PHYSR=31 +CONFIG_STM32H7_PHYSR_100FD=0x0018 +CONFIG_STM32H7_PHYSR_100HD=0x0008 +CONFIG_STM32H7_PHYSR_10FD=0x0014 +CONFIG_STM32H7_PHYSR_10HD=0x0004 +CONFIG_STM32H7_PHYSR_ALTCONFIG=y +CONFIG_STM32H7_PHYSR_ALTMODE=0x001c +CONFIG_STM32H7_PWR_DIRECT_SMPS_SUPPLY=y +CONFIG_STM32H7_SDMMC1=y +CONFIG_STM32H7_TIM15=y +CONFIG_STM32H7_TIM15_CH2OUT=y +CONFIG_STM32H7_TIM15_CHANNEL=2 +CONFIG_STM32H7_TIM15_PWM=y +CONFIG_STM32H7_UART7=y +CONFIG_STM32H7_USART2=y +CONFIG_STM32H7_USART3=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_PING=y +CONFIG_SYSTEM_POPEN=y +CONFIG_SYSTEM_SYSTEM=y +CONFIG_TLS_TASK_NELEM=4 +CONFIG_TTY_SIGINT=y +CONFIG_UART7_BAUD=9600 +CONFIG_UART7_RS485=y +CONFIG_USART3_SERIAL_CONSOLE=y +CONFIG_VG_BRINGUP_TOOLS=y +CONFIG_VG_CONFIG_STORE=y +CONFIG_VG_CONFIG_BASEDIR="/data/velaguard/config" +CONFIG_VG_FRAME_STATS=y +CONFIG_VG_AGENT_OPS=y +CONFIG_VG_AGENT_AUTOSTART=y diff --git a/boards/arm/stm32h7/stm32h750b-dk/include/board.h b/boards/arm/stm32h7/stm32h750b-dk/include/board.h index 0b5aa45d283..d00e18c8d1b 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/include/board.h +++ b/boards/arm/stm32h7/stm32h750b-dk/include/board.h @@ -271,7 +271,26 @@ #define STM32_SDMMC_MMCXFR_CLKDIV (4 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #define STM32_SDMMC_SDXFR_CLKDIV (4 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) -#define STM32_SDMMC_CLKCR_EDGE STM32_SDMMC_CLKCR_NEGEDGE +/* ST BSP stm32h750b_discovery_mmc.c uses rising edge; prefer that for eMMC. */ + +#define STM32_SDMMC_CLKCR_EDGE (0) /* rising */ + +/* SDMMC1 — on-board eMMC (U11), 8-bit wiring (MB1381 / ST BSP MSP): + * CK=PC12, CMD=PD2, D0–D3=PC8–11, D4–D5=PB8–9, D6–D7=PC6–7 + * NuttX stm32_sdmmc.c configures D0–D3 (+CK/CMD) in sdio_initialize(); + * board stm32_sdmmc.c also arms D4–D7 for a future 8-bit path. + */ + +#define GPIO_SDMMC1_CK (GPIO_SDMMC1_CK_0|GPIO_SPEED_100MHz) /* PC12 */ +#define GPIO_SDMMC1_CMD (GPIO_SDMMC1_CMD_0|GPIO_SPEED_100MHz) /* PD2 */ +#define GPIO_SDMMC1_D0 (GPIO_SDMMC1_D0_0|GPIO_SPEED_100MHz) /* PC8 */ +#define GPIO_SDMMC1_D1 (GPIO_SDMMC1_D1_0|GPIO_SPEED_100MHz) /* PC9 */ +#define GPIO_SDMMC1_D2 (GPIO_SDMMC1_D2_0|GPIO_SPEED_100MHz) /* PC10 */ +#define GPIO_SDMMC1_D3 (GPIO_SDMMC1_D3_0|GPIO_SPEED_100MHz) /* PC11 */ +#define GPIO_SDMMC1_D4 (GPIO_SDMMC1_D4_0|GPIO_SPEED_100MHz) /* PB8 */ +#define GPIO_SDMMC1_D5 (GPIO_SDMMC1_D5_0|GPIO_SPEED_100MHz) /* PB9 */ +#define GPIO_SDMMC1_D6 (GPIO_SDMMC1_D6_0|GPIO_SPEED_100MHz) /* PC6 */ +#define GPIO_SDMMC1_D7 (GPIO_SDMMC1_D7_0|GPIO_SPEED_100MHz) /* PC7 */ /* Ethernet definitions *****************************************************/ @@ -507,6 +526,10 @@ /* Alternate function pin selections ****************************************/ +/* USART2 - ESP-01 (VelaGuard expansion board, STMod P1-2/3) */ +#define GPIO_USART2_RX (GPIO_USART2_RX_2 | GPIO_SPEED_100MHz) /* PD6 */ +#define GPIO_USART2_TX (GPIO_USART2_TX_2 | GPIO_SPEED_100MHz) /* PD5 */ + /* USART3 (Nucleo Virtual Console) */ #define GPIO_USART3_RX (GPIO_USART3_RX_1 | GPIO_SPEED_100MHz) /* PB11 */ @@ -517,6 +540,9 @@ #define GPIO_UART7_RX (GPIO_UART7_RX_1 | GPIO_SPEED_100MHz) /* PA8 */ #define GPIO_UART7_TX (GPIO_UART7_TX_2 | GPIO_SPEED_100MHz) /* PB4 */ +/* TIM15 - PWM (VelaGuard D01 / passive buzzer) */ +#define GPIO_TIM15_CH2OUT (GPIO_TIM15_CH2OUT_2 | GPIO_SPEED_50MHz) /* PE6 */ + /* I2C4 - Used by Touchscreen and Audio Codec */ #define GPIO_I2C4_SCL (GPIO_I2C4_SCL_1 | GPIO_SPEED_50MHz) /* PD12 */ @@ -556,6 +582,19 @@ #define GPIO_LTDC_DE (GPIO_LTDC_DE_3 | GPIO_SPEED_100MHz) #define GPIO_LTDC_CLK (GPIO_LTDC_CLK_3 | GPIO_SPEED_100MHz) +/* RS485 direction (VelaGuard expansion, Arduino D4 / PK1) */ +#define GPIO_UART7_RS485_DIR (GPIO_OUTPUT|GPIO_PUSHPULL|\ + GPIO_SPEED_100MHz|GPIO_OUTPUT_CLEAR|\ + GPIO_PORTK|GPIO_PIN1) /* PK1 */ + +/* ESP-01S control (STMod P1-14 / P1-12) */ +#define GPIO_ESP_EN (GPIO_OUTPUT|GPIO_PUSHPULL|\ + GPIO_SPEED_100MHz|GPIO_OUTPUT_SET|\ + GPIO_PORTA|GPIO_PIN3) /* PA3 */ +#define GPIO_ESP_RST (GPIO_OUTPUT|GPIO_PUSHPULL|\ + GPIO_SPEED_100MHz|GPIO_OUTPUT_SET|\ + GPIO_PORTH|GPIO_PIN10) /* PH10 */ + /* DMA **********************************************************************/ #define DMAMAP_SPI3_RX DMAMAP_DMA12_SPI3RX_0 /* DMA1 */ diff --git a/boards/arm/stm32h7/stm32h750b-dk/scripts/Make.defs b/boards/arm/stm32h7/stm32h750b-dk/scripts/Make.defs index 77ce2f7a7c7..0613a257f33 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/scripts/Make.defs +++ b/boards/arm/stm32h7/stm32h750b-dk/scripts/Make.defs @@ -23,7 +23,11 @@ include $(TOPDIR)/tools/Config.mk include $(TOPDIR)/arch/arm/src/armv7-m/Toolchain.defs ifeq ($(CONFIG_ARCH_CHIP_STM32H7_CORTEXM7),y) - LDSCRIPT = flash.ld + ifeq ($(CONFIG_STM32H750B_DK_QSPI_BOOT),y) + LDSCRIPT = qspi_flash.ld + else + LDSCRIPT = flash.ld + endif else LDSCRIPT = flash_m4.ld endif diff --git a/boards/arm/stm32h7/stm32h750b-dk/scripts/qspi_flash.ld b/boards/arm/stm32h7/stm32h750b-dk/scripts/qspi_flash.ld new file mode 100644 index 00000000000..cf09f2753a2 --- /dev/null +++ b/boards/arm/stm32h7/stm32h750b-dk/scripts/qspi_flash.ld @@ -0,0 +1,110 @@ +/**************************************************************************** + * boards/arm/stm32h7/stm32h750b-dk/scripts/qspi_flash.ld + * + * Link the Cortex-M7 image for execution from the STM32H750B-DK external + * dual-QSPI memory window at 0x90000000. A small internal-Flash stub must + * initialize QSPI memory-mapped mode and jump to this image. + * + ****************************************************************************/ + +#include + +MEMORY +{ + itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + flash (rx) : ORIGIN = 0x90000000, LENGTH = 128M + 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 + sdram (rwx) : ORIGIN = 0xD0000000, LENGTH = 8M +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) +SECTIONS +{ + .text : + { + _stext = ABSOLUTE(.); + *(.vectors) + *(.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_section : + { + _sinit = ABSOLUTE(.); + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP(*(.init_array EXCLUDE_FILE(*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o) .ctors)) + _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 + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : + { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + .sram4_reserve (NOLOAD) : + { + *(.sram4) + . = ALIGN(4); + _sram4_heap_start = ABSOLUTE(.); + } > sram4 + + .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/arm/stm32h7/stm32h750b-dk/src/CMakeLists.txt b/boards/arm/stm32h7/stm32h750b-dk/src/CMakeLists.txt index fde7f720d27..9a2598727c0 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/src/CMakeLists.txt +++ b/boards/arm/stm32h7/stm32h750b-dk/src/CMakeLists.txt @@ -50,10 +50,24 @@ if(CONFIG_STM32H7_LTDC) list(APPEND SRCS stm32_lcd.c) endif() +if(CONFIG_PWM) + list(APPEND SRCS stm32_pwm.c) +endif() + +if(CONFIG_STM32H7_SDMMC) + list(APPEND SRCS stm32_sdmmc.c) +endif() + target_sources(board PRIVATE ${SRCS}) if(CONFIG_ARCH_CHIP_STM32H7_CORTEXM7) - set_property(GLOBAL PROPERTY LD_SCRIPT "${NUTTX_BOARD_DIR}/scripts/flash.ld") + if(CONFIG_STM32H750B_DK_QSPI_BOOT) + set_property(GLOBAL PROPERTY LD_SCRIPT + "${NUTTX_BOARD_DIR}/scripts/qspi_flash.ld") + else() + set_property(GLOBAL PROPERTY LD_SCRIPT + "${NUTTX_BOARD_DIR}/scripts/flash.ld") + endif() else() set_property(GLOBAL PROPERTY LD_SCRIPT "${NUTTX_BOARD_DIR}/scripts/flash_m4.ld") diff --git a/boards/arm/stm32h7/stm32h750b-dk/src/Makefile b/boards/arm/stm32h7/stm32h750b-dk/src/Makefile index a0a30c67a82..656fd418143 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/src/Makefile +++ b/boards/arm/stm32h7/stm32h750b-dk/src/Makefile @@ -52,4 +52,12 @@ ifeq ($(CONFIG_STM32H7_LTDC),y) CSRCS += stm32_lcd.c endif -include $(TOPDIR)/boards/Board.mk \ No newline at end of file +ifeq ($(CONFIG_PWM),y) +CSRCS += stm32_pwm.c +endif + +ifeq ($(CONFIG_STM32H7_SDMMC),y) +CSRCS += stm32_sdmmc.c +endif + +include $(TOPDIR)/boards/Board.mk diff --git a/boards/arm/stm32h7/stm32h750b-dk/src/stm32_bringup.c b/boards/arm/stm32h7/stm32h750b-dk/src/stm32_bringup.c index cb37f043e36..8817f410c72 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/src/stm32_bringup.c +++ b/boards/arm/stm32h7/stm32h750b-dk/src/stm32_bringup.c @@ -23,8 +23,12 @@ ****************************************************************************/ #include +#include #include +#include +#include +#include #include #include @@ -119,6 +123,100 @@ void rpmsg_serialinit(void) * ****************************************************************************/ +#ifdef HAVE_SDIO +# if defined(CONFIG_FS_FAT) && defined(CONFIG_FS_LINKS) + +static void vg_setup_data_layout(void) +{ + struct stat st; + int ret; + + ret = mkdir("/mnt/emmc/data", 0755); + if (ret < 0 && errno != EEXIST) + { + syslog(LOG_WARNING, + "WARNING: mkdir /mnt/emmc/data failed: %d\n", ret); + } + + /* One-time stage0 → stage1: /mnt/emmc/velaguard → /mnt/emmc/data/velaguard */ + + if (stat("/mnt/emmc/velaguard", &st) == 0 && + stat("/mnt/emmc/data/velaguard", &st) != 0) + { + ret = rename("/mnt/emmc/velaguard", "/mnt/emmc/data/velaguard"); + if (ret < 0) + { + syslog(LOG_WARNING, + "WARNING: migrate velaguard dir failed: %d\n", ret); + } + else + { + syslog(LOG_INFO, + "Migrated /mnt/emmc/velaguard -> /mnt/emmc/data/velaguard\n"); + } + } + + ret = mkdir("/mnt/emmc/data/velaguard/config", 0755); + if (ret < 0 && errno != EEXIST) + { + syslog(LOG_WARNING, + "WARNING: mkdir velaguard/config failed: %d\n", ret); + } + + ret = mkdir("/mnt/emmc/data/agent", 0755); + if (ret < 0 && errno != EEXIST) + { + syslog(LOG_WARNING, + "WARNING: mkdir data/agent failed: %d\n", ret); + } + + ret = mkdir("/mnt/emmc/data/agent/config", 0755); + if (ret < 0 && errno != EEXIST) + { + syslog(LOG_WARNING, + "WARNING: mkdir agent/config failed: %d\n", ret); + } + + ret = mkdir("/mnt/emmc/data/agent/memory", 0755); + if (ret < 0 && errno != EEXIST) + { + syslog(LOG_WARNING, + "WARNING: mkdir agent/memory failed: %d\n", ret); + } + + ret = mkdir("/mnt/emmc/data/agent/sessions", 0755); + if (ret < 0 && errno != EEXIST) + { + syslog(LOG_WARNING, + "WARNING: mkdir agent/sessions failed: %d\n", ret); + } + + ret = mkdir("/mnt/emmc/data/agent/skills", 0755); + if (ret < 0 && errno != EEXIST) + { + syslog(LOG_WARNING, + "WARNING: mkdir agent/skills failed: %d\n", ret); + } + + if (lstat("/data", &st) != 0) + { + ret = symlink("/mnt/emmc/data", "/data"); + if (ret < 0) + { + syslog(LOG_WARNING, + "WARNING: symlink /data -> /mnt/emmc/data failed: %d\n", + ret); + } + else + { + syslog(LOG_INFO, "Symlink /data -> /mnt/emmc/data\n"); + } + } +} + +# endif /* CONFIG_FS_FAT && CONFIG_FS_LINKS */ +#endif /* HAVE_SDIO */ + int stm32_bringup(void) { int ret; @@ -141,6 +239,16 @@ int stm32_bringup(void) } #endif /* CONFIG_FS_PROCFS */ +#ifdef CONFIG_PWM + /* Initialize PWM and register the PWM device. */ + + ret = stm32_pwm_setup(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: stm32_pwm_setup failed: %d\n", ret); + } +#endif + #ifdef CONFIG_RPTUN # ifdef CONFIG_ARCH_CHIP_STM32H7_CORTEXM7 stm32_rptun_init("cm4"); @@ -263,5 +371,51 @@ int stm32_bringup(void) } #endif +#ifdef CONFIG_UART7_RS485 + ret = symlink("/dev/ttyS2", "/dev/rs485"); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to create symlink for RS485: %d\n", ret); + } +#endif + +#ifdef CONFIG_STM32H7_USART2 + stm32_configgpio(GPIO_ESP_EN); + stm32_configgpio(GPIO_ESP_RST); +#endif + +#ifdef HAVE_SDIO + /* Initialize on-board eMMC (SDMMC1) and try FAT at /mnt/emmc. + * First boot may lack a filesystem — mount failure is logged only; + * format manually with NSH: mkfatfs /dev/mmcsd0 + */ + + ret = stm32_sdio_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: Failed to initialize eMMC/SDIO: %d\n", ret); + } +#ifdef CONFIG_FS_FAT + else + { + ret = nx_mount("/dev/mmcsd0", "/mnt/emmc", "vfat", 0, NULL); + if (ret < 0) + { + syslog(LOG_WARNING, + "WARNING: eMMC FAT mount /mnt/emmc failed: %d " + "(try: mkfatfs /dev/mmcsd0)\n", ret); + } + else + { + syslog(LOG_INFO, "eMMC mounted at /mnt/emmc\n"); +# if defined(CONFIG_FS_FAT) && defined(CONFIG_FS_LINKS) + vg_setup_data_layout(); +# endif + } + } +#endif +#endif + return OK; } diff --git a/boards/arm/stm32h7/stm32h750b-dk/src/stm32_pwm.c b/boards/arm/stm32h7/stm32h750b-dk/src/stm32_pwm.c new file mode 100644 index 00000000000..e5e9090d3f8 --- /dev/null +++ b/boards/arm/stm32h7/stm32h750b-dk/src/stm32_pwm.c @@ -0,0 +1,56 @@ +/**************************************************************************** + * boards/arm/stm32h7/stm32h750b-dk/src/stm32_pwm.c + * + * VelaGuard TIM15 CH2 PWM (/dev/pwm0) registration for the expansion board. + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "chip.h" +#include "arm_internal.h" +#include "stm32_pwm.h" +#include "stm32h750b-dk.h" + +#ifdef CONFIG_PWM +# ifdef CONFIG_STM32H7_TIM15_PWM +# define HAVE_PWM 1 +# endif +#endif + +int stm32_pwm_setup(void) +{ +#ifdef HAVE_PWM + static bool initialized = false; + struct pwm_lowerhalf_s *pwm; + int ret; + + if (!initialized) + { + pwm = stm32_pwminitialize(15); + if (!pwm) + { + tmrerr("ERROR: Failed to get the STM32 PWM lower half\n"); + return -ENODEV; + } + + ret = pwm_register("/dev/pwm0", pwm); + if (ret < 0) + { + tmrerr("ERROR: pwm_register failed: %d\n", ret); + return ret; + } + + initialized = true; + } + + return OK; +#else + return -ENOSYS; +#endif +} diff --git a/boards/arm/stm32h7/stm32h750b-dk/src/stm32_sdmmc.c b/boards/arm/stm32h7/stm32h750b-dk/src/stm32_sdmmc.c new file mode 100644 index 00000000000..5b1a50ef90e --- /dev/null +++ b/boards/arm/stm32h7/stm32h750b-dk/src/stm32_sdmmc.c @@ -0,0 +1,111 @@ +/**************************************************************************** + * boards/arm/stm32h7/stm32h750b-dk/src/stm32_sdmmc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include "stm32_gpio.h" +#include "stm32_sdmmc.h" + +#include "stm32h750b-dk.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_STM32H7_SDMMC1 +# error SDMMC1 supported only (on-board eMMC) +#endif + +#if CONFIG_MM_REGIONS > 1 && defined(CONFIG_STM32H7_SDMMC_IDMA) +# error SDMMC1 with IDMA does not work with CONFIG_MM_REGIONS > 1 +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct sdio_dev_s *g_sdio_dev; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support for the soldered eMMC. + * No card-detect GPIO — always report media present. + * + ****************************************************************************/ + +int stm32_sdio_initialize(void) +{ + int ret; + + /* Arm D4–D7 as well. sdio_initialize() only configures D0–D3/CK/CMD. + * Stock NuttX MMC path still runs 1-bit until a wider-bus fix lands. + */ + + stm32_configgpio(GPIO_SDMMC1_D4); + stm32_configgpio(GPIO_SDMMC1_D5); + stm32_configgpio(GPIO_SDMMC1_D6); + stm32_configgpio(GPIO_SDMMC1_D7); + + finfo("Initializing SDIO slot %d (eMMC)\n", SDIO_SLOTNO); + + g_sdio_dev = sdio_initialize(SDIO_SLOTNO); + if (!g_sdio_dev) + { + ferr("ERROR: Failed to initialize SDIO slot %d\n", SDIO_SLOTNO); + return -ENODEV; + } + + finfo("Bind SDIO to the MMC/SD driver, minor=%d\n", SDIO_MINOR); + + ret = mmcsd_slotinitialize(SDIO_MINOR, g_sdio_dev); + if (ret != OK) + { + ferr("ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n", ret); + return ret; + } + + /* Soldered eMMC — no CD pin */ + + sdio_mediachange(g_sdio_dev, true); + + return OK; +} diff --git a/boards/arm/stm32h7/stm32h750b-dk/src/stm32h750b-dk.h b/boards/arm/stm32h7/stm32h750b-dk/src/stm32h750b-dk.h index 0e7f4e14cad..0e6b63b05bd 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/src/stm32h750b-dk.h +++ b/boards/arm/stm32h7/stm32h750b-dk/src/stm32h750b-dk.h @@ -156,6 +156,19 @@ #define GPIO_LCD_B2 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ GPIO_OUTPUT_CLEAR|GPIO_PORTJ|GPIO_PIN14) +/* SDMMC / on-board eMMC ****************************************************/ + +#if defined(CONFIG_STM32H7_SDMMC1) +# define HAVE_SDIO +#endif + +#if defined(CONFIG_DISABLE_MOUNTPOINT) || !defined(CONFIG_MMCSD_SDIO) +# undef HAVE_SDIO +#endif + +#define SDIO_SLOTNO 0 +#define SDIO_MINOR 0 + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -182,6 +195,8 @@ int stm32_bringup(void); * ****************************************************************************/ +int stm32_pwm_setup(void); + #ifdef CONFIG_STM32H7_OTGFS void weak_function stm32_usbinitialize(void); #endif @@ -214,4 +229,16 @@ int stm32_usbhost_initialize(void); int stm32_tsc_setup(int minor); #endif +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support (on-board eMMC). + * + ****************************************************************************/ + +#ifdef HAVE_SDIO +int stm32_sdio_initialize(void); +#endif + #endif /* __BOARDS_ARM_STM32H7_STM32H750B_DK_SRC_STM32H750B_DK_H */ From 3ec58fd4f5d6d89f1dd14f7aeb9416ac4946ff0e Mon Sep 17 00:00:00 2001 From: 19y Date: Sun, 30 Aug 2026 13:33:38 +0800 Subject: [PATCH 04/15] fix(input): implement TSIOC_GETMAXPOINTS in ft5x06 touch driver Return max touch points for LVGL and tslib consumers that query the capability via TSIOC_GETMAXPOINTS ioctl. Co-authored-by: Cursor --- drivers/input/ft5x06.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/input/ft5x06.c b/drivers/input/ft5x06.c index be5db167865..3f3b9566008 100644 --- a/drivers/input/ft5x06.c +++ b/drivers/input/ft5x06.c @@ -945,6 +945,24 @@ static int ft5x06_ioctl(FAR struct file *filep, int cmd, unsigned long arg) } break; + case TSIOC_GETMAXPOINTS: /* arg: Pointer to uint8_t maxpoint value */ + { + FAR uint8_t *ptr = (FAR uint8_t *)((uintptr_t)arg); + + if (ptr == NULL) + { + ret = -EINVAL; + break; + } + +#ifdef CONFIG_FT5X06_SINGLEPOINT + *ptr = 1; +#else + *ptr = FT5X06_MAX_TOUCHES; +#endif + } + break; + default: ret = -ENOTTY; break; From b3f045cfac7f552d5877f76ee4afbcb3023adfd6 Mon Sep 17 00:00:00 2001 From: 19y Date: Wed, 9 Sep 2026 19:34:30 +0800 Subject: [PATCH 05/15] feat(stm32h750b-dk): FT5x06 falling-edge IRQ and nonblocking LTDC pan Switch the touch INT to pull-up/falling-edge trigger mode, fix THRESHY drop-outs, and keep framebuffer pan from blocking indev. Land velaguard-lvgl and velaguard-min defconfigs on the board tree instead of contest patches. Co-authored-by: Cursor --- arch/arm/src/stm32h7/stm32_allocateheap.c | 7 + arch/arm/src/stm32h7/stm32_ltdc.c | 36 ++-- arch/arm/src/stm32h7/stm32_pwm.c | 2 +- .../configs/velaguard-ai-probe/defconfig | 2 +- .../configs/velaguard-emmc/defconfig | 2 +- .../configs/velaguard-lvgl/defconfig | 184 ++++++++++++++++++ .../configs/velaguard-min/defconfig | 74 +++++++ .../configs/velaguard-net/defconfig | 6 +- .../arm/stm32h7/stm32h750b-dk/include/board.h | 1 + .../stm32h7/stm32h750b-dk/src/stm32_ft5x06.c | 8 +- .../stm32h7/stm32h750b-dk/src/stm32h750b-dk.h | 2 +- drivers/input/ft5x06.c | 36 ++-- 12 files changed, 325 insertions(+), 35 deletions(-) create mode 100644 boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig create mode 100644 boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-min/defconfig diff --git a/arch/arm/src/stm32h7/stm32_allocateheap.c b/arch/arm/src/stm32h7/stm32_allocateheap.c index d584e783230..7b88b7b69ee 100644 --- a/arch/arm/src/stm32h7/stm32_allocateheap.c +++ b/arch/arm/src/stm32h7/stm32_allocateheap.c @@ -423,7 +423,14 @@ void arm_addregion(void) #ifdef BOARD_SDRAM2_SIZE if (mm_regions < CONFIG_MM_REGIONS) { +#ifdef BOARD_SDRAM2_HEAP_OFFSET + static_assert(BOARD_SDRAM2_HEAP_OFFSET < BOARD_SDRAM2_SIZE, + "SDRAM2 heap offset exceeds the available SDRAM"); + addregion (STM32_FMC_BANK6 + BOARD_SDRAM2_HEAP_OFFSET, + BOARD_SDRAM2_SIZE - BOARD_SDRAM2_HEAP_OFFSET, "SDRAM2"); +#else addregion (STM32_FMC_BANK6, BOARD_SDRAM2_SIZE, "SDRAM2"); +#endif mm_regions++; } #endif diff --git a/arch/arm/src/stm32h7/stm32_ltdc.c b/arch/arm/src/stm32h7/stm32_ltdc.c index a4377db52ca..a5d234ba418 100644 --- a/arch/arm/src/stm32h7/stm32_ltdc.c +++ b/arch/arm/src/stm32h7/stm32_ltdc.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -823,6 +824,10 @@ static sem_t g_lock; static sem_t g_semirq; +#if defined(CONFIG_STM32H7_LTDC_FB_DOUBLE_BUFFER) +static volatile bool g_flip_pending; +#endif + /* This structure provides irq handling */ static struct stm32_interrupt_s g_interrupt = @@ -1493,7 +1498,12 @@ static int stm32_ltdcirq(int irq, void *context, void *arg) priv->error = OK; #if defined(CONFIG_STM32H7_LTDC_FB_DOUBLE_BUFFER) - fb_remove_paninfo(&g_vtable.vtable, FB_NO_OVERLAY); + if (g_flip_pending) + { + g_flip_pending = false; + fb_remove_paninfo(&g_vtable.vtable, FB_NO_OVERLAY); + return OK; + } #endif } else if (regval & LTDC_IER_LIE) @@ -2564,24 +2574,28 @@ static int stm32_waitforvsync(struct fb_vtable_s *vtable) static int stm32_pandisplay(struct fb_vtable_s *vtable, struct fb_planeinfo_s *pinfo) { - int ret = 0; + irqstate_t flags; + uint32_t new_fb_start; DEBUGASSERT(vtable != NULL && vtable == &g_vtable.vtable); DEBUGASSERT(pinfo != NULL); - uint32_t new_fb_start = (uint32_t)pinfo->fbmem + - pinfo->yoffset * pinfo->stride + - pinfo->xoffset * (pinfo->bpp / 8); + new_fb_start = (uint32_t)pinfo->fbmem + + pinfo->yoffset * pinfo->stride + + pinfo->xoffset * (pinfo->bpp / 8); - putreg32(new_fb_start, stm32_cfbar_layer_t[0]); - ret = stm32_ltdc_reload(LTDC_SRCR_VBR, true); - if (ret < 0) + flags = enter_critical_section(); + if (g_flip_pending) { - lcderr("ERROR: stm32_ltdc_reload failed: %d\n", ret); - return ret; + leave_critical_section(flags); + return -EBUSY; } - return ret; + g_flip_pending = true; + putreg32(new_fb_start, stm32_cfbar_layer_t[0]); + putreg32(LTDC_SRCR_VBR, STM32_LTDC_SRCR); + leave_critical_section(flags); + return OK; } #endif diff --git a/arch/arm/src/stm32h7/stm32_pwm.c b/arch/arm/src/stm32h7/stm32_pwm.c index 6d426d9a8fe..6def1d0422d 100644 --- a/arch/arm/src/stm32h7/stm32_pwm.c +++ b/arch/arm/src/stm32h7/stm32_pwm.c @@ -1363,7 +1363,7 @@ static struct stm32_pwmchan_s g_pwm15channels[] = { .channel = 2, .mode = CONFIG_STM32H7_TIM15_CH2MODE, -#ifdef CONFIG_STM32H7_TIM12_CH2OUT +#ifdef CONFIG_STM32H7_TIM15_CH2OUT .out1 = { .in_use = 1, diff --git a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-ai-probe/defconfig b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-ai-probe/defconfig index 21c50e1c7a5..201d86d9340 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-ai-probe/defconfig +++ b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-ai-probe/defconfig @@ -128,4 +128,4 @@ CONFIG_USART3_SERIAL_CONSOLE=y CONFIG_VG_BRINGUP_TOOLS=y CONFIG_VG_NET_FAILOVER=y CONFIG_VG_WIFI_PASSWORD="12345678" -CONFIG_VG_WIFI_SSID="ASUS" +CONFIG_VG_WIFI_SSID="19y" diff --git a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-emmc/defconfig b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-emmc/defconfig index 50624968941..34a49729120 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-emmc/defconfig +++ b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-emmc/defconfig @@ -55,7 +55,7 @@ CONFIG_NETUTILS_ESP8266=y CONFIG_NETUTILS_ESP8266_DEV_PATH="/dev/ttyS1" CONFIG_NETUTILS_ESP8266_BAUDRATE=115200 CONFIG_VG_NET_FAILOVER=y -CONFIG_VG_WIFI_SSID="ASUS" +CONFIG_VG_WIFI_SSID="19y" CONFIG_VG_WIFI_PASSWORD="12345678" CONFIG_NET_BROADCAST=y CONFIG_NET_ETH_PKTSIZE=1500 diff --git a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig new file mode 100644 index 00000000000..34d61e86c89 --- /dev/null +++ b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig @@ -0,0 +1,184 @@ +# +# 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_AI_AGENT_FEISHU is not set +# CONFIG_AI_AGENT_MCP is not set +# CONFIG_AI_AGENT_MQTT is not set +# CONFIG_AI_AGENT_NODE is not set +# CONFIG_AI_AGENT_WEIXIN is not set +# CONFIG_ARCH_LEDS is not set +# CONFIG_EXAMPLES_FB is not set +# CONFIG_EXAMPLES_LVGLDEMO is not set +# CONFIG_EXAMPLES_TOUCHSCREEN is not set +# CONFIG_MBEDTLS_ARIA_C is not set +# CONFIG_MBEDTLS_CCM_C is not set +# CONFIG_MMCSD_HAVE_CARDDETECT is not set +# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_SPI is not set +# CONFIG_STANDARD_SERIAL is not set +# CONFIG_STM32H7_CORTEXM4_ENABLED is not set +# CONFIG_STM32H7_FB_CMAP is not set +# CONFIG_STM32H7_LTDC_L1_CHROMAKEYEN is not set +# CONFIG_STM32H7_LTDC_L2 is not set +# CONFIG_STM32H7_SDMMC_IDMA is not set +# CONFIG_STM32H7_USE_LEGACY_PINMAP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="stm32h750b-dk" +CONFIG_ARCH_BOARD_STM32H750B_DK=y +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H750B=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_CHIP_STM32H7_CORTEXM7=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARM_MPU=y +CONFIG_BOARD_LOOPSPERMSEC=43103 +CONFIG_BUILTIN=y +CONFIG_AI_AGENT_TLS_CONN_POOL_SIZE=1 +CONFIG_ALLOW_BSD_COMPONENTS=y +CONFIG_CRYPTO_MBEDTLS=y +CONFIG_DEV_URANDOM=y +CONFIG_DRIVERS_VIDEO=y +CONFIG_ETH0_PHY_LAN8740A=y +CONFIG_EXAMPLES_AI_AGENT_VELA=y +CONFIG_EXAMPLES_AI_AGENT_VELA_DATA_DIR="/data/agent" +CONFIG_EXAMPLES_AI_AGENT_VELA_NODE_DISPLAY_NAME="VelaGuard" +CONFIG_EXAMPLES_AI_AGENT_VELA_NODE_ID="velaguard-01" +CONFIG_FAT_LFN=y +CONFIG_FS_FAT=y +CONFIG_FS_LINKS=y +CONFIG_FS_PROCFS=y +CONFIG_FT5X06_NPOLLWAITERS=8 +# CONFIG_FT5X06_POLLMODE is not set +CONFIG_FT5X06_SINGLEPOINT=y +CONFIG_FT5X06_SWAPXY=y +CONFIG_FT5X06_THRESHX=2 +CONFIG_FT5X06_THRESHY=2 +CONFIG_GRAPHICS_LVGL=y +CONFIG_INIT_ENTRYPOINT="velaguard_app_main" +CONFIG_INPUT=y +CONFIG_INPUT_FT5X06=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LINE_MAX=64 +CONFIG_LV_DEF_REFR_PERIOD=16 +CONFIG_LV_NUTTX_VSYNC_TIMER_PERIOD=16 +CONFIG_LV_USE_CLIB_MALLOC=y +CONFIG_LV_USE_CLIB_SPRINTF=y +CONFIG_LV_USE_CLIB_STRING=y +CONFIG_LV_USE_LOG=y +CONFIG_LV_LOG_LEVEL_WARN=y +CONFIG_LV_LOG_PRINTF=y +CONFIG_LV_USE_NUTTX=y +CONFIG_LV_USE_NUTTX_TOUCHSCREEN=y +CONFIG_MBEDTLS_THREADING_C=y +CONFIG_MBEDTLS_THREADING_PTHREAD=y +CONFIG_MMCSD=y +CONFIG_MMCSD_MMCSUPPORT=y +CONFIG_MMCSD_SDIO=y +CONFIG_MM_HEAP_MEMPOOL_THRESHOLD=0 +CONFIG_MM_REGIONS=6 +CONFIG_MQ_MAXMSGSIZE=256 +CONFIG_NET=y +CONFIG_NETDB_DNSCLIENT=y +CONFIG_NETINIT_CARRIER_POLL=y +CONFIG_NETINIT_DHCPC=y +CONFIG_NETINIT_DNS=y +CONFIG_NETINIT_THREAD=y +CONFIG_NETUTILS_DHCPC=y +CONFIG_NETUTILS_DHCPC_BOOTP_FLAGS=0x8000 +CONFIG_NETUTILS_CJSON=y +CONFIG_NETUTILS_MQTTC=y +CONFIG_NETUTILS_WEBCLIENT=y +CONFIG_NETUTILS_ESP8266=y +CONFIG_NETUTILS_ESP8266_DEV_PATH="/dev/ttyS1" +CONFIG_NETUTILS_ESP8266_BAUDRATE=115200 +CONFIG_VG_NET_FAILOVER=y +CONFIG_VG_WIFI_SSID="19y" +CONFIG_VG_WIFI_PASSWORD="12345678" +CONFIG_NET_BROADCAST=y +CONFIG_NET_ETH_PKTSIZE=1500 +CONFIG_NET_ICMP_SOCKET=y +CONFIG_NET_TCP=y +CONFIG_NET_UDP=y +CONFIG_NET_UDP_CHECKSUMS=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PIPES=y +CONFIG_PSEUDOFS_FILE=y +CONFIG_PTHREAD_MUTEX_TYPES=y +CONFIG_PWM=y +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_CPULOAD_SYSCLK=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SDMMC1_SDIO_PULLUP=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_STM32H750B_DK_QSPI_BOOT=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_DMA2=y +CONFIG_STM32H7_ETHMAC=y +CONFIG_STM32H7_FMC=y +CONFIG_STM32H7_I2C4=y +CONFIG_STM32H7_LTDC=y +CONFIG_STM32H7_LTDC_FB_BASE=0xd0000000 +CONFIG_STM32H7_LTDC_FB_SIZE=522240 +CONFIG_STM32H7_MII=y +CONFIG_STM32H7_PHYADDR=1 +CONFIG_STM32H7_PHYSR=31 +CONFIG_STM32H7_PHYSR_100FD=0x0018 +CONFIG_STM32H7_PHYSR_100HD=0x0008 +CONFIG_STM32H7_PHYSR_10FD=0x0014 +CONFIG_STM32H7_PHYSR_10HD=0x0004 +CONFIG_STM32H7_PHYSR_ALTCONFIG=y +CONFIG_STM32H7_PHYSR_ALTMODE=0x001c +CONFIG_STM32H7_PWR_DIRECT_SMPS_SUPPLY=y +CONFIG_STM32H7_SDMMC1=y +CONFIG_STM32H7_TIM15=y +CONFIG_STM32H7_TIM15_CH2OUT=y +CONFIG_STM32H7_TIM15_CHANNEL=2 +CONFIG_STM32H7_TIM15_PWM=y +CONFIG_STM32H7_UART7=y +CONFIG_STM32H7_USART2=y +CONFIG_STM32H7_USART3=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_PING=y +CONFIG_SYSTEM_POPEN=y +CONFIG_SYSTEM_SYSTEM=y +CONFIG_TLS_TASK_NELEM=4 +CONFIG_TTY_SIGINT=y +CONFIG_UART7_BAUD=9600 +CONFIG_UART7_RS485=y +CONFIG_USART3_SERIAL_CONSOLE=y +CONFIG_VIDEO_FB=y +CONFIG_VG_BRINGUP_TOOLS=y +CONFIG_VG_CONFIG_STORE=y +CONFIG_VG_CONFIG_BASEDIR="/data/velaguard/config" +CONFIG_VG_FRAME_STATS=y +CONFIG_VG_AGENT_OPS=y +# CONFIG_VG_AGENT_AUTOSTART is not set +CONFIG_VG_BUS_DISCOVER=y +CONFIG_VG_HMI=y +CONFIG_VG_HMI_AUTOSTART=y +CONFIG_VG_HMI_DISCOVER=y +CONFIG_VG_HMI_STACKSIZE=49152 diff --git a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-min/defconfig b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-min/defconfig new file mode 100644 index 00000000000..d7ce14b1288 --- /dev/null +++ b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-min/defconfig @@ -0,0 +1,74 @@ +# +# 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_ARCH_LEDS is not set +# CONFIG_STANDARD_SERIAL is not set +# CONFIG_STM32H7_CORTEXM4_ENABLED is not set +# CONFIG_STM32H7_USE_LEGACY_PINMAP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="stm32h750b-dk" +CONFIG_ARCH_BOARD_STM32H750B_DK=y +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H750B=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_CHIP_STM32H7_CORTEXM7=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARM_MPU=y +CONFIG_BOARD_LOOPSPERMSEC=43103 +CONFIG_BUILTIN=y +CONFIG_FS_LINKS=y +CONFIG_FS_PROCFS=y +CONFIG_INIT_ENTRYPOINT="velaguard_app_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_LINE_MAX=64 +CONFIG_MM_HEAP_MEMPOOL_THRESHOLD=0 +CONFIG_MM_REGIONS=6 +CONFIG_MQ_MAXMSGSIZE=256 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PSEUDOFS_FILE=y +CONFIG_PWM=y +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_CPULOAD_SYSCLK=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_STM32H750B_DK_QSPI_BOOT=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_DMA2=y +CONFIG_STM32H7_FMC=y +CONFIG_STM32H7_PWR_DIRECT_SMPS_SUPPLY=y +CONFIG_STM32H7_TIM15=y +CONFIG_STM32H7_TIM15_CH2OUT=y +CONFIG_STM32H7_TIM15_CHANNEL=2 +CONFIG_STM32H7_TIM15_PWM=y +CONFIG_STM32H7_UART7=y +CONFIG_STM32H7_USART2=y +CONFIG_STM32H7_USART3=y +CONFIG_SYSTEM_NSH=y +CONFIG_TTY_SIGINT=y +CONFIG_UART7_BAUD=9600 +CONFIG_UART7_RS485=y +CONFIG_USART3_SERIAL_CONSOLE=y +CONFIG_VG_BRINGUP_TOOLS=y diff --git a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-net/defconfig b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-net/defconfig index 6dd5fe37225..1613d36d546 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-net/defconfig +++ b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-net/defconfig @@ -74,7 +74,7 @@ CONFIG_NETUTILS_ESP8266=y CONFIG_NETUTILS_ESP8266_DEV_PATH="/dev/ttyS1" CONFIG_NETUTILS_ESP8266_BAUDRATE=115200 CONFIG_VG_NET_FAILOVER=y -CONFIG_VG_WIFI_SSID="ASUS" +CONFIG_VG_WIFI_SSID="19y" CONFIG_VG_WIFI_PASSWORD="12345678" CONFIG_NET_BROADCAST=y CONFIG_NET_ETH_PKTSIZE=1500 @@ -144,4 +144,6 @@ CONFIG_VG_CONFIG_STORE=y CONFIG_VG_CONFIG_BASEDIR="/data/velaguard/config" CONFIG_VG_FRAME_STATS=y CONFIG_VG_AGENT_OPS=y -CONFIG_VG_AGENT_AUTOSTART=y +# CONFIG_VG_AGENT_AUTOSTART is not set +CONFIG_VG_BUS_DISCOVER=y +CONFIG_EXAMPLES_AI_AGENT_VELA_STACKSIZE=65536 diff --git a/boards/arm/stm32h7/stm32h750b-dk/include/board.h b/boards/arm/stm32h7/stm32h750b-dk/include/board.h index d00e18c8d1b..b4b1d4455ee 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/include/board.h +++ b/boards/arm/stm32h7/stm32h750b-dk/include/board.h @@ -380,6 +380,7 @@ #endif #define BOARD_SDRAM2_SIZE (8*1024*1024) +#define BOARD_SDRAM2_HEAP_OFFSET (1*1024*1024) /* BOARD_FMC_SDCR[1..2] - Initial value for SDRAM control registers for SDRAM * bank 1-2. Note that some bits in SDCR1 influence both SDRAM banks and diff --git a/boards/arm/stm32h7/stm32h750b-dk/src/stm32_ft5x06.c b/boards/arm/stm32h7/stm32h750b-dk/src/stm32_ft5x06.c index 3cedc84a392..a3d535c56d1 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/src/stm32_ft5x06.c +++ b/boards/arm/stm32h7/stm32h750b-dk/src/stm32_ft5x06.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include #include @@ -40,7 +42,7 @@ * Pre-processor Definitions ****************************************************************************/ -#define FT5X06_FREQUENCY 100000 /* For now, will boost later */ +#define FT5X06_FREQUENCY 100000 /* Board-validated FT5336 bus rate */ #ifdef CONFIG_INPUT_FT5X06 #ifndef CONFIG_INPUT @@ -177,9 +179,9 @@ static void stm32_ft5x06_enable(const struct ft5x06_config_s *config, flags = enter_critical_section(); if (enable) { - /* Configure the EXTI interrupt using the SAVED handler */ + /* FT5X06 INT is active-low: trigger when a touch asserts it. */ - stm32_gpiosetevent(GPIO_FT5X06_INT, true, false, true, + stm32_gpiosetevent(GPIO_FT5X06_INT, false, true, true, g_priv_config.handler, g_priv_config.arg); } else diff --git a/boards/arm/stm32h7/stm32h750b-dk/src/stm32h750b-dk.h b/boards/arm/stm32h7/stm32h750b-dk/src/stm32h750b-dk.h index 0e6b63b05bd..a79c72081a0 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/src/stm32h750b-dk.h +++ b/boards/arm/stm32h7/stm32h750b-dk/src/stm32h750b-dk.h @@ -114,7 +114,7 @@ /* Touchscreen Interrupt line: PG2 */ -#define GPIO_FT5X06_INT (GPIO_INPUT|GPIO_FLOAT|GPIO_SPEED_100MHz| \ +#define GPIO_FT5X06_INT (GPIO_INPUT|GPIO_PULLUP|GPIO_SPEED_100MHz| \ GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN2) /* The reset line is active low: PB12 */ diff --git a/drivers/input/ft5x06.c b/drivers/input/ft5x06.c index 3f3b9566008..27bf5bc0432 100644 --- a/drivers/input/ft5x06.c +++ b/drivers/input/ft5x06.c @@ -85,8 +85,8 @@ * polling rates. */ -#define POLL_MINDELAY MSEC2TICK(50) -#define POLL_MAXDELAY MSEC2TICK(200) +#define POLL_MINDELAY MSEC2TICK(10) +#define POLL_MAXDELAY MSEC2TICK(20) #define POLL_INCREMENT MSEC2TICK(10) /**************************************************************************** @@ -471,22 +471,18 @@ static ssize_t ft5x06_sample(FAR struct ft5x06_dev_s *priv, FAR char *buffer, deltax = -deltax; } - if (deltax < CONFIG_FT5X06_THRESHX) + deltay = (y - priv->lasty); + if (deltay < 0) { - /* There as been no significant change in X, try Y */ - - deltay = (y - priv->lasty); - if (deltay < 0) - { - deltay = -deltay; - } + deltay = -deltay; + } - if (deltax < CONFIG_FT5X06_THRESHX) - { - /* Ignore... no significant change in Y either */ + if (deltax < CONFIG_FT5X06_THRESHX && + deltay < CONFIG_FT5X06_THRESHY) + { + /* Ignore... no significant change in X or Y */ - goto drop; - } + goto drop; } } } @@ -694,6 +690,16 @@ static int ft5x06_bringup(FAR struct ft5x06_dev_s *priv) } #ifndef CONFIG_FT5X06_POLLMODE + /* Pulse INT on every contact/move so EXTI falling-edge keeps streaming. */ + + data[0] = FT5X06_GMODE_REG; + data[1] = FT5X06_G_MODE_INTERRUPT_TRIGGER; + ret = I2C_TRANSFER(priv->i2c, &msg, 1); + if (ret < 0) + { + return ret; + } + /* Enable FT5x06 interrupts */ config->clear(config); From 9665accb9a5c99f87123f476c355e6e89531df3d Mon Sep 17 00:00:00 2001 From: 19y Date: Wed, 9 Sep 2026 19:34:36 +0800 Subject: [PATCH 06/15] fix(stm32h7): assert RS485 DIR before TX and hold after TC Raising DIR only in up_send() raced the USART shifter; dropping it on TC let A/B float and prepended 0xFF onto the next PDU. Also point /dev/rs485 at ttyS1 when USART2 is not enabled. Co-authored-by: Cursor --- arch/arm/src/stm32h7/stm32_serial.c | 14 ++++++++++++++ .../arm/stm32h7/stm32h750b-dk/src/stm32_bringup.c | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/arch/arm/src/stm32h7/stm32_serial.c b/arch/arm/src/stm32h7/stm32_serial.c index 2e2e5480c33..495107bb7d0 100644 --- a/arch/arm/src/stm32h7/stm32_serial.c +++ b/arch/arm/src/stm32h7/stm32_serial.c @@ -3535,6 +3535,13 @@ static void up_txint(struct uart_dev_s *dev, bool enable) # ifdef HAVE_RS485 if (priv->rs485_dir_gpio != 0) { + /* Drive the transceiver before the first start bit. Setting DIR + * only in up_send() races the USART shifter and shows up as + * 03→20 / truncated PDUs in Modbus Slave. + */ + + stm32_gpiowrite(priv->rs485_dir_gpio, priv->rs485_dir_polarity); + /* Clear stale TC so enabling TCIE does not race the next frame. */ up_serialout(priv, STM32_USART_ICR_OFFSET, USART_ICR_TCCF); @@ -3609,6 +3616,13 @@ static bool up_txempty(struct uart_dev_s *dev) return false; } + /* TC means the stop bit has left the shifter. Dropping DIR in the + * same instant lets A/B float; USB-RS485 then appends 0x7F/0xFF + * onto an otherwise valid CRC (Communication_log_4: D5 CA 7F). + * 9600 bit ≈ 104us; hold ~4 bit times. + */ + + up_udelay(400); stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); return true; } diff --git a/boards/arm/stm32h7/stm32h750b-dk/src/stm32_bringup.c b/boards/arm/stm32h7/stm32h750b-dk/src/stm32_bringup.c index 8817f410c72..3be5f52b4db 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/src/stm32_bringup.c +++ b/boards/arm/stm32h7/stm32h750b-dk/src/stm32_bringup.c @@ -372,7 +372,12 @@ int stm32_bringup(void) #endif #ifdef CONFIG_UART7_RS485 +# if defined(CONFIG_STM32H7_USART2) ret = symlink("/dev/ttyS2", "/dev/rs485"); +# else + /* No USART2: UART7 is the first aux UART -> ttyS1 (see board README). */ + ret = symlink("/dev/ttyS1", "/dev/rs485"); +# endif if (ret < 0) { syslog(LOG_ERR, "ERROR: Failed to create symlink for RS485: %d\n", ret); From 79ac7c7d96d0921d520f701b5fbef4f1d1d160d3 Mon Sep 17 00:00:00 2001 From: 19y Date: Fri, 11 Sep 2026 16:50:20 +0800 Subject: [PATCH 07/15] configs(velaguard-lvgl): widen NSH line and args for host vgpoint Raise LINELEN/MAXARGUMENTS so long vgpoint apply commands fit on the serial shell. Co-authored-by: Cursor --- .../arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig index 34d61e86c89..4ff3fb3c7d1 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig +++ b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig @@ -113,7 +113,8 @@ CONFIG_NSH_ARCHINIT=y CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_DISABLE_IFUPDOWN=y CONFIG_NSH_FILEIOSIZE=512 -CONFIG_NSH_LINELEN=64 +CONFIG_NSH_LINELEN=128 +CONFIG_NSH_MAXARGUMENTS=32 CONFIG_NSH_READLINE=y CONFIG_PREALLOC_TIMERS=4 CONFIG_PIPES=y From 90172c3b0de231fd259bf3e2dbe5e834848fc401 Mon Sep 17 00:00:00 2001 From: 19y Date: Fri, 11 Sep 2026 16:50:20 +0800 Subject: [PATCH 08/15] configs(velaguard-lvgl): set VG_HMI_REPORT_DIR Point the HMI report browser at /data/velaguard/reports. Co-authored-by: Cursor --- .../arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig index 4ff3fb3c7d1..a189752ee80 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig +++ b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig @@ -182,4 +182,5 @@ CONFIG_VG_BUS_DISCOVER=y CONFIG_VG_HMI=y CONFIG_VG_HMI_AUTOSTART=y CONFIG_VG_HMI_DISCOVER=y +CONFIG_VG_HMI_REPORT_DIR="/data/velaguard/reports" CONFIG_VG_HMI_STACKSIZE=49152 From 4065c7e7da7b4df1966e016ea79bb677cd1f07c5 Mon Sep 17 00:00:00 2001 From: 19y Date: Sat, 12 Sep 2026 09:44:51 +0800 Subject: [PATCH 09/15] boards/stm32h750b-dk: fix nxstyle errors in VelaGuard bring-up files checkpatch failed on open-vela/nuttx#352 with: - board.h:274 and stm32_bringup.c:141/155/383: long lines - stm32_bringup.c:378: missing blank line after comment - stm32_pwm.c: no license header and no section banners, so the file was skipped by nxstyle entirely Wrap the long comments and syslog strings, add the blank line, and bring stm32_pwm.c to the standard NuttX file layout (same content as on velaguard/board-and-defconfigs). No functional change. --- .../arm/stm32h7/stm32h750b-dk/include/board.h | 2 +- .../stm32h7/stm32h750b-dk/src/stm32_bringup.c | 11 ++-- .../arm/stm32h7/stm32h750b-dk/src/stm32_pwm.c | 53 ++++++++++++++++--- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/boards/arm/stm32h7/stm32h750b-dk/include/board.h b/boards/arm/stm32h7/stm32h750b-dk/include/board.h index b4b1d4455ee..d49031514da 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/include/board.h +++ b/boards/arm/stm32h7/stm32h750b-dk/include/board.h @@ -271,7 +271,7 @@ #define STM32_SDMMC_MMCXFR_CLKDIV (4 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #define STM32_SDMMC_SDXFR_CLKDIV (4 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) -/* ST BSP stm32h750b_discovery_mmc.c uses rising edge; prefer that for eMMC. */ +/* Rising clock edge, as in ST BSP stm32h750b_discovery_mmc.c (eMMC) */ #define STM32_SDMMC_CLKCR_EDGE (0) /* rising */ diff --git a/boards/arm/stm32h7/stm32h750b-dk/src/stm32_bringup.c b/boards/arm/stm32h7/stm32h750b-dk/src/stm32_bringup.c index 3be5f52b4db..6f2d585dff5 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/src/stm32_bringup.c +++ b/boards/arm/stm32h7/stm32h750b-dk/src/stm32_bringup.c @@ -138,7 +138,9 @@ static void vg_setup_data_layout(void) "WARNING: mkdir /mnt/emmc/data failed: %d\n", ret); } - /* One-time stage0 → stage1: /mnt/emmc/velaguard → /mnt/emmc/data/velaguard */ + /* One-time stage0 -> stage1 migration: + * /mnt/emmc/velaguard -> /mnt/emmc/data/velaguard + */ if (stat("/mnt/emmc/velaguard", &st) == 0 && stat("/mnt/emmc/data/velaguard", &st) != 0) @@ -152,7 +154,8 @@ static void vg_setup_data_layout(void) else { syslog(LOG_INFO, - "Migrated /mnt/emmc/velaguard -> /mnt/emmc/data/velaguard\n"); + "Migrated /mnt/emmc/velaguard -> " + "/mnt/emmc/data/velaguard\n"); } } @@ -376,11 +379,13 @@ int stm32_bringup(void) ret = symlink("/dev/ttyS2", "/dev/rs485"); # else /* No USART2: UART7 is the first aux UART -> ttyS1 (see board README). */ + ret = symlink("/dev/ttyS1", "/dev/rs485"); # endif if (ret < 0) { - syslog(LOG_ERR, "ERROR: Failed to create symlink for RS485: %d\n", ret); + syslog(LOG_ERR, "ERROR: Failed to create symlink for RS485: %d\n", + ret); } #endif diff --git a/boards/arm/stm32h7/stm32h750b-dk/src/stm32_pwm.c b/boards/arm/stm32h7/stm32h750b-dk/src/stm32_pwm.c index e5e9090d3f8..27cba4f73bc 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/src/stm32_pwm.c +++ b/boards/arm/stm32h7/stm32h750b-dk/src/stm32_pwm.c @@ -1,7 +1,27 @@ /**************************************************************************** * boards/arm/stm32h7/stm32h750b-dk/src/stm32_pwm.c * - * VelaGuard TIM15 CH2 PWM (/dev/pwm0) registration for the expansion board. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files ****************************************************************************/ #include @@ -17,12 +37,33 @@ #include "stm32_pwm.h" #include "stm32h750b-dk.h" -#ifdef CONFIG_PWM -# ifdef CONFIG_STM32H7_TIM15_PWM -# define HAVE_PWM 1 -# endif +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifdef CONFIG_STM32H7_TIM15_PWM +# define HAVE_PWM 1 #endif +#ifndef CONFIG_PWM +# undef HAVE_PWM +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_pwm_setup + * + * Description: + * Initialize TIM15 CH2 PWM and register /dev/pwm0 for the expansion + * board buzzer. + * + ****************************************************************************/ + int stm32_pwm_setup(void) { #ifdef HAVE_PWM @@ -33,7 +74,7 @@ int stm32_pwm_setup(void) if (!initialized) { pwm = stm32_pwminitialize(15); - if (!pwm) + if (pwm == NULL) { tmrerr("ERROR: Failed to get the STM32 PWM lower half\n"); return -ENODEV; From 89692ab628ac99fbb7b0cab6631dac68237ef3d5 Mon Sep 17 00:00:00 2001 From: 19y Date: Sat, 12 Sep 2026 11:59:25 +0800 Subject: [PATCH 10/15] fix(arm_m): always dump CFSR/HFSR/BFAR and stacked PC on hardfault Intermittent hard faults on stm32h750b-dk (hpwork 2026-09-12, ai_agent 2026-09-02) reach PANIC_WITH_REGS with no fault detail because the CFSR/HFSR/BFAR dump is gated behind CONFIG_DEBUG_HARDFAULT_ALERT. Print the SCB fault status and the stacked PC/LR unconditionally so the failing access can be identified from the console dump alone. --- arch/arm/src/arm_m/arm_hardfault.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/arm/src/arm_m/arm_hardfault.c b/arch/arm/src/arm_m/arm_hardfault.c index 3ae38a95917..d065cc95375 100644 --- a/arch/arm/src/arm_m/arm_hardfault.c +++ b/arch/arm/src/arm_m/arm_hardfault.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -182,6 +183,23 @@ int arm_hardfault(int irq, void *context, void *arg) } #endif + /* Surface the SCB fault status and the stacked PC/LR unconditionally: + * this image executes from QSPI XIP and intermittent hard faults carry + * no other evidence of the failing access. */ + + syslog(LOG_ALERT, + "HARDFAULT: CFSR=%08" PRIx32 " HFSR=%08" PRIx32 + " BFAR=%08" PRIx32 " MMFAR=%08" PRIx32 "\n", + cfsr, hfsr, getreg32(NVIC_BFAULT_ADDR), + getreg32(NVIC_MEMMANAGE_ADDR)); + if (context != NULL) + { + syslog(LOG_ALERT, + "HARDFAULT: stacked PC=%08" PRIx32 " LR=%08" PRIx32 "\n", + ((FAR uint32_t *)context)[REG_PC], + ((FAR uint32_t *)context)[REG_R14]); + } + up_irq_save(); PANIC_WITH_REGS("panic", context); return OK; From 18bec160782263e7e2ed0f8b9ca06bbda69a5c9f Mon Sep 17 00:00:00 2001 From: 19y Date: Sat, 12 Sep 2026 19:56:19 +0800 Subject: [PATCH 11/15] fix(stm32h750b-dk): move SDRAM heap above LVGL fb reserve; mm_foreach corruption guard - BOARD_SDRAM2_HEAP_OFFSET 1MB -> 2MB: with LTDC double buffering the second framebuffer lands at SDRAM+1MB, exactly where the heap region used to start; normal HMI rendering smashed the region's free-node metadata and the first mallinfo() walk hardfaulted (deterministic, every boot, VelaGuard HMI). - mm_foreach: with CONFIG_MM_RECORD_STACK, validate the walk (size field escaping the region, free-list neighbors outside all heap regions) and dump the offending node + region layout instead of faulting inside DEBUGASSERT. Verified on hardware: catches the corruption and keeps the system alive for diagnosis. --- .../configs/velaguard-lvgl/defconfig | 5 +- .../arm/stm32h7/stm32h750b-dk/include/board.h | 6 +- mm/mm_heap/mm_foreach.c | 130 ++++++++++++++++++ 3 files changed, 139 insertions(+), 2 deletions(-) diff --git a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig index a189752ee80..64037e94cb4 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig +++ b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig @@ -177,7 +177,10 @@ CONFIG_VG_CONFIG_STORE=y CONFIG_VG_CONFIG_BASEDIR="/data/velaguard/config" CONFIG_VG_FRAME_STATS=y CONFIG_VG_AGENT_OPS=y -# CONFIG_VG_AGENT_AUTOSTART is not set +CONFIG_VG_AGENT_AUTOSTART=y +CONFIG_VG_TIME_SYNC=y +CONFIG_EXAMPLES_AI_AGENT_VELA_TIME_OFFSET_SEC=0 +CONFIG_VG_TIME_SYNC_PATH="/data/velaguard/clock.txt" CONFIG_VG_BUS_DISCOVER=y CONFIG_VG_HMI=y CONFIG_VG_HMI_AUTOSTART=y diff --git a/boards/arm/stm32h7/stm32h750b-dk/include/board.h b/boards/arm/stm32h7/stm32h750b-dk/include/board.h index d49031514da..edaebfb61e2 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/include/board.h +++ b/boards/arm/stm32h7/stm32h750b-dk/include/board.h @@ -380,7 +380,11 @@ #endif #define BOARD_SDRAM2_SIZE (8*1024*1024) -#define BOARD_SDRAM2_HEAP_OFFSET (1*1024*1024) +/* 2MB: keep the heap well clear of the LVGL framebuffer reserve (1MB). + * A render-path out-of-bounds write was landing at SDRAM+1MB (right at + * the old heap start) and smashing free-node metadata; the extra 1MB + * dead zone keeps heap metadata out of reach. */ +#define BOARD_SDRAM2_HEAP_OFFSET (2*1024*1024) /* BOARD_FMC_SDCR[1..2] - Initial value for SDRAM control registers for SDRAM * bank 1-2. Note that some bits in SDCR1 influence both SDRAM banks and diff --git a/mm/mm_heap/mm_foreach.c b/mm/mm_heap/mm_foreach.c index f0d0d4a3550..7d13255b287 100644 --- a/mm/mm_heap/mm_foreach.c +++ b/mm/mm_heap/mm_foreach.c @@ -28,6 +28,10 @@ #include #include +#include +#ifdef CONFIG_MM_RECORD_STACK +# include +#endif #include #include @@ -37,6 +41,91 @@ #include "mm_heap/mm.h" +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_MM_RECORD_STACK +/* Dump the allocation backtrace recorded in a node, to identify who + * allocated a heap node with smashed metadata. */ + +static void mm_foreach_dump_node(FAR struct mm_heap_s *heap, + FAR struct mm_allocnode_s *node) +{ + int r; + + merr("MM CORRUPT: node=%p size=%zu preceding=%u\n", + node, MM_SIZEOF_NODE(node), (unsigned int)node->preceding); + + merr("MM CORRUPT: heap=%p regions:", heap); + for (r = 0; r < heap->mm_nregions; r++) + { + merr(" [%p..%p)", heap->mm_heapstart[r], heap->mm_heapend[r]); + } + merr("\n"); + + /* Raw bytes around the smashed header: identifies the writer's + * data fingerprint (pixels / JSON / pointers). */ + + FAR volatile uint8_t *pre = (FAR volatile uint8_t *)node - 32; + FAR volatile uint8_t *post = (FAR volatile uint8_t *)node; + int i; + + for (i = 0; i < 32; i++) + { + merr("%02x", pre[i]); + } + + merr(" | "); + + for (i = 0; i < 48; i++) + { + merr("%02x", post[i]); + } + + merr("\n"); +} + +/* A free-list neighbor must be inside one of the heap regions or inside + * the heap struct itself (bucket list heads). Anything else is corrupted + * metadata; report instead of faulting on the deref. */ + +static bool mm_foreach_nearby(FAR struct mm_heap_s *heap, FAR void *p) +{ + int r; + + if (p == NULL) + { + return true; /* legal list tail */ + } + + if ((uintptr_t)p & 3) + { + return false; + } + + if (p >= (FAR void *)heap && p < (FAR void *)(heap + 1)) + { + return true; + } + +#if CONFIG_MM_REGIONS > 1 + for (r = 0; r < heap->mm_nregions; r++) +#else + for (r = 0; r < 1; r++) +#endif + { + if (p >= heap->mm_heapstart[r] && + p < heap->mm_heapend[r]) + { + return true; + } + } + + return false; +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -115,6 +204,47 @@ void mm_foreach(FAR struct mm_heap_s *heap, mm_node_handler_t handler, MM_PREVNODE_IS_FREE(node) ? 'F' : 'A', MM_NODE_IS_ALLOC(node) ? 'A' : 'F'); +#ifdef CONFIG_MM_RECORD_STACK + /* A smashed size field makes the walk escape the region and + * fault on the next node header. Report the current node + * (its allocation record names the overflowing buffer's + * owner) and stop instead of faulting. */ + + if (nodesize < MM_SIZEOF_ALLOCNODE || + (uintptr_t)node + nodesize > (uintptr_t)heap->mm_heapend[region]) + { + merr("MM CORRUPT: walk escapes region=%d node=%p size=%zu\n", + region, node, nodesize); + mm_foreach_dump_node(heap, node); + kasan_bypass(bypass); + if (locked) + { + DEBUGVERIFY(nxrmutex_unlock(&heap->mm_lock)); + } + return; + } + + if (!MM_NODE_IS_ALLOC(node)) + { + FAR struct mm_freenode_s *fnode = (FAR void *)node; + + if (!mm_foreach_nearby(heap, fnode->blink) || + (fnode->flink != NULL && + !mm_foreach_nearby(heap, fnode->flink))) + { + merr("MM CORRUPT: free node %p blink=%p flink=%p\n", + node, fnode->blink, fnode->flink); + mm_foreach_dump_node(heap, node); + kasan_bypass(bypass); + if (locked) + { + DEBUGVERIFY(nxrmutex_unlock(&heap->mm_lock)); + } + return; + } + } +#endif + handler(node, arg); DEBUGASSERT(MM_PREVNODE_IS_ALLOC(node) || From 8792b0c2744845fcbf8144b8bd54a4a50df5e1a7 Mon Sep 17 00:00:00 2001 From: 19y Date: Mon, 14 Sep 2026 18:32:21 +0800 Subject: [PATCH 12/15] fix(mm): compile foreach dump when CONFIG_MM_REGIONS==1 Goldfish CI builds with a single heap region, so mm_nregions is not a struct member. Guard that access and fix remaining nxstyle nits. Co-authored-by: Cursor --- arch/arm/src/arm_m/arm_hardfault.c | 3 +- .../arm/stm32h7/stm32h750b-dk/include/board.h | 5 +- mm/mm_heap/mm_foreach.c | 73 ++++++++++++++----- 3 files changed, 59 insertions(+), 22 deletions(-) diff --git a/arch/arm/src/arm_m/arm_hardfault.c b/arch/arm/src/arm_m/arm_hardfault.c index d065cc95375..a2eb2769d38 100644 --- a/arch/arm/src/arm_m/arm_hardfault.c +++ b/arch/arm/src/arm_m/arm_hardfault.c @@ -185,7 +185,8 @@ int arm_hardfault(int irq, void *context, void *arg) /* Surface the SCB fault status and the stacked PC/LR unconditionally: * this image executes from QSPI XIP and intermittent hard faults carry - * no other evidence of the failing access. */ + * no other evidence of the failing access. + */ syslog(LOG_ALERT, "HARDFAULT: CFSR=%08" PRIx32 " HFSR=%08" PRIx32 diff --git a/boards/arm/stm32h7/stm32h750b-dk/include/board.h b/boards/arm/stm32h7/stm32h750b-dk/include/board.h index edaebfb61e2..d13b60d86fd 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/include/board.h +++ b/boards/arm/stm32h7/stm32h750b-dk/include/board.h @@ -380,10 +380,13 @@ #endif #define BOARD_SDRAM2_SIZE (8*1024*1024) + /* 2MB: keep the heap well clear of the LVGL framebuffer reserve (1MB). * A render-path out-of-bounds write was landing at SDRAM+1MB (right at * the old heap start) and smashing free-node metadata; the extra 1MB - * dead zone keeps heap metadata out of reach. */ + * dead zone keeps heap metadata out of reach. + */ + #define BOARD_SDRAM2_HEAP_OFFSET (2*1024*1024) /* BOARD_FMC_SDCR[1..2] - Initial value for SDRAM control registers for SDRAM diff --git a/mm/mm_heap/mm_foreach.c b/mm/mm_heap/mm_foreach.c index 7d13255b287..7ea5d7bbfcc 100644 --- a/mm/mm_heap/mm_foreach.c +++ b/mm/mm_heap/mm_foreach.c @@ -46,30 +46,57 @@ ****************************************************************************/ #ifdef CONFIG_MM_RECORD_STACK -/* Dump the allocation backtrace recorded in a node, to identify who - * allocated a heap node with smashed metadata. */ + +/**************************************************************************** + * Name: mm_foreach_nregions + * + * Description: + * Return the number of regions in the heap. mm_nregions exists only + * when CONFIG_MM_REGIONS > 1. + * + ****************************************************************************/ + +static int mm_foreach_nregions(FAR struct mm_heap_s *heap) +{ +#if CONFIG_MM_REGIONS > 1 + return heap->mm_nregions; +#else + UNUSED(heap); + return 1; +#endif +} + +/**************************************************************************** + * Name: mm_foreach_dump_node + * + * Description: + * Dump the allocation backtrace recorded in a node, to identify who + * allocated a heap node with smashed metadata. + * + ****************************************************************************/ static void mm_foreach_dump_node(FAR struct mm_heap_s *heap, FAR struct mm_allocnode_s *node) { + FAR volatile uint8_t *pre = (FAR volatile uint8_t *)node - 32; + FAR volatile uint8_t *post = (FAR volatile uint8_t *)node; int r; + int i; merr("MM CORRUPT: node=%p size=%zu preceding=%u\n", node, MM_SIZEOF_NODE(node), (unsigned int)node->preceding); merr("MM CORRUPT: heap=%p regions:", heap); - for (r = 0; r < heap->mm_nregions; r++) + for (r = 0; r < mm_foreach_nregions(heap); r++) { merr(" [%p..%p)", heap->mm_heapstart[r], heap->mm_heapend[r]); } + merr("\n"); /* Raw bytes around the smashed header: identifies the writer's - * data fingerprint (pixels / JSON / pointers). */ - - FAR volatile uint8_t *pre = (FAR volatile uint8_t *)node - 32; - FAR volatile uint8_t *post = (FAR volatile uint8_t *)node; - int i; + * data fingerprint (pixels / JSON / pointers). + */ for (i = 0; i < 32; i++) { @@ -86,9 +113,15 @@ static void mm_foreach_dump_node(FAR struct mm_heap_s *heap, merr("\n"); } -/* A free-list neighbor must be inside one of the heap regions or inside - * the heap struct itself (bucket list heads). Anything else is corrupted - * metadata; report instead of faulting on the deref. */ +/**************************************************************************** + * Name: mm_foreach_nearby + * + * Description: + * A free-list neighbor must be inside one of the heap regions or inside + * the heap struct itself (bucket list heads). Anything else is corrupted + * metadata; report instead of faulting on the deref. + * + ****************************************************************************/ static bool mm_foreach_nearby(FAR struct mm_heap_s *heap, FAR void *p) { @@ -109,14 +142,10 @@ static bool mm_foreach_nearby(FAR struct mm_heap_s *heap, FAR void *p) return true; } -#if CONFIG_MM_REGIONS > 1 - for (r = 0; r < heap->mm_nregions; r++) -#else - for (r = 0; r < 1; r++) -#endif + for (r = 0; r < mm_foreach_nregions(heap); r++) { - if (p >= heap->mm_heapstart[r] && - p < heap->mm_heapend[r]) + if (p >= (FAR void *)heap->mm_heapstart[r] && + p < (FAR void *)heap->mm_heapend[r]) { return true; } @@ -208,10 +237,12 @@ void mm_foreach(FAR struct mm_heap_s *heap, mm_node_handler_t handler, /* A smashed size field makes the walk escape the region and * fault on the next node header. Report the current node * (its allocation record names the overflowing buffer's - * owner) and stop instead of faulting. */ + * owner) and stop instead of faulting. + */ if (nodesize < MM_SIZEOF_ALLOCNODE || - (uintptr_t)node + nodesize > (uintptr_t)heap->mm_heapend[region]) + ((uintptr_t)node + nodesize > + (uintptr_t)heap->mm_heapend[region])) { merr("MM CORRUPT: walk escapes region=%d node=%p size=%zu\n", region, node, nodesize); @@ -221,6 +252,7 @@ void mm_foreach(FAR struct mm_heap_s *heap, mm_node_handler_t handler, { DEBUGVERIFY(nxrmutex_unlock(&heap->mm_lock)); } + return; } @@ -240,6 +272,7 @@ void mm_foreach(FAR struct mm_heap_s *heap, mm_node_handler_t handler, { DEBUGVERIFY(nxrmutex_unlock(&heap->mm_lock)); } + return; } } From 83768e5a53eb5e0c06763d77d5bfe2cb2600bbb5 Mon Sep 17 00:00:00 2001 From: 19y Date: Wed, 16 Sep 2026 18:41:45 +0800 Subject: [PATCH 13/15] fix(stm32h7): keep SDMMC PIO copies inside reachable SRAM A board watch on 2026-09-14 caught hpwork in stm32_recvfifo taking an imprecise bus fault while writing 0x38010004, just past SRAM4. The PIO path trusts priv->buffer without checking it, so a buffer outside the memory the controller can reach walks off the region. stm32_sdmmc_userbuf_ok() accepts the four regions the controller can reach (DTCM, AXI SRAM, SRAM123, SRAM4) plus the XIP window, and rejects anything else. stm32_sendfifo() and stm32_recvfifo() check each chunk before touching the FIFO: a rejected transfer is drained, the remaining count is zeroed and the drop is logged with the offending pointer instead of being allowed to fault. Keep the region list in step with the memory map. A buffer the system really hands out but that is missing from the list is dropped mid-transfer, and a dropped block write leaves the card answering ETIMEDOUT to everything after it. Co-Authored-By: Claude Code --- arch/arm/src/stm32h7/stm32_sdmmc.c | 166 +++++++++++++++++++++++++++-- 1 file changed, 159 insertions(+), 7 deletions(-) diff --git a/arch/arm/src/stm32h7/stm32_sdmmc.c b/arch/arm/src/stm32h7/stm32_sdmmc.c index 53adba441c5..1adabd79cca 100644 --- a/arch/arm/src/stm32h7/stm32_sdmmc.c +++ b/arch/arm/src/stm32h7/stm32_sdmmc.c @@ -1201,6 +1201,96 @@ static void stm32_datadisable(struct stm32_dev_s *priv) ****************************************************************************/ #if !defined(CONFIG_STM32H7_SDMMC_IDMA) +/* PIO copies must not walk off SRAM. 2026-09-14 board watch: hpwork + * stm32_recvfifo imprecise busfault writing 0x38010004 (past SRAM4). + * + * Keep this list in step with the memory map: a buffer the system really + * hands out but that is missing here is dropped mid-transfer, and a dropped + * block write leaves the card answering ETIMEDOUT to everything after it. + */ + +#define STM32_SDMMC_XIP_WINDOW (256 * 1024 * 1024) /* FMC bank 4, QUADSPI */ + + +static bool stm32_sdmmc_userbuf_ok(FAR const void *p, size_t n) +{ + const uintptr_t a = (uintptr_t)p; + uintptr_t e; + + if (p == NULL || n == 0) + { + return false; + } + + e = a + n; + if (e < a) + { + return false; + } + + if (a >= STM32_DTCRAM_BASE && + e <= (uintptr_t)STM32_DTCRAM_BASE + STM32H7_DTCM_SRAM_SIZE) + { + return true; + } + + if (a >= STM32_AXISRAM_BASE && + e <= (uintptr_t)STM32_AXISRAM_BASE + STM32H7_SRAM_SIZE) + { + return true; + } + + if (a >= STM32_SRAM123_BASE && + e <= (uintptr_t)STM32_SRAM123_BASE + STM32H7_SRAM123_SIZE) + { + return true; + } + + if (a >= STM32_SRAM4_BASE && + e <= (uintptr_t)STM32_SRAM4_BASE + STM32H7_SRAM4_SIZE) + { + return true; + } + + /* A write sources its data from whatever the caller passed, which is not + * always RAM: const objects live in the XIP flash image. The agent skill + * seeds are written straight from such constants at boot, and rejecting + * them aborted the transfer mid-block. + */ + + if (a >= STM32_FMC_BANK4 && + e <= (uintptr_t)STM32_FMC_BANK4 + STM32_SDMMC_XIP_WINDOW) + { + return true; + } + + /* External SDRAM counts too. The PIO path copies through the CPU, so any + * address the CPU can reach is usable, and this board registers SDRAM + * with the kernel heap (BOARD_SDRAM2_HEAP_OFFSET reserves the LVGL + * framebuffers first). Filesystem sector buffers are kmm_malloc'd and do + * land there; rejecting them aborts the transfer mid-block, after which + * the card answers ETIMEDOUT to everything. + */ + +#ifdef BOARD_SDRAM1_SIZE + if (a >= STM32_FMC_BANK5 && + e <= (uintptr_t)STM32_FMC_BANK5 + BOARD_SDRAM1_SIZE) + { + return true; + } +#endif + +#ifdef BOARD_SDRAM2_SIZE + if (a >= STM32_FMC_BANK6 && + e <= (uintptr_t)STM32_FMC_BANK6 + BOARD_SDRAM2_SIZE) + { + return true; + } +#endif + + return false; +} + static void stm32_sendfifo(struct stm32_dev_s *priv) { union @@ -1215,13 +1305,31 @@ static void stm32_sendfifo(struct stm32_dev_s *priv) (sdmmc_getreg32(priv, STM32_SDMMC_STA_OFFSET) & STM32_SDMMC_STA_TXFIFOF) == 0) { + size_t chunk = priv->remaining >= sizeof(uint32_t) ? + sizeof(uint32_t) : priv->remaining; + + if (!stm32_sdmmc_userbuf_ok(priv->buffer, chunk)) + { + /* syslog, not mcerr: mcerr needs CONFIG_DEBUG_MEMCARD_ERROR and + * CONFIG_DEBUG_ERROR, neither of which is set here, so a dropped + * transfer used to leave no trace at all. + */ + + syslog(LOG_ERR, "ERROR: TX buf %p rem %zu outside SRAM, drop\n", + priv->buffer, priv->remaining); + priv->remaining = 0; + break; + } + /* Is there a full word remaining in the user buffer? */ if (priv->remaining >= sizeof(uint32_t)) { /* Yes, transfer the word to the TX FIFO */ - data.w = *priv->buffer++; + memcpy(&data.w, priv->buffer, sizeof(uint32_t)); + priv->buffer = (FAR uint32_t *)((uintptr_t)priv->buffer + + sizeof(uint32_t)); priv->remaining -= sizeof(uint32_t); } else @@ -1230,7 +1338,7 @@ static void stm32_sendfifo(struct stm32_dev_s *priv) * padding with zero as necessary to extend to a full word. */ - uint8_t *ptr = (uint8_t *)priv->remaining; + uint8_t *ptr = (uint8_t *)priv->buffer; int i; data.w = 0; @@ -1289,7 +1397,17 @@ static void stm32_recvfifo(struct stm32_dev_s *priv) { /* Transfer the whole word to the user buffer */ - *priv->buffer++ = data.w; + if (!stm32_sdmmc_userbuf_ok(priv->buffer, sizeof(uint32_t))) + { + syslog(LOG_ERR, "ERROR: RX buf %p rem %zu outside SRAM, drop\n", + priv->buffer, priv->remaining); + priv->remaining = 0; + break; + } + + memcpy(priv->buffer, &data.w, sizeof(uint32_t)); + priv->buffer = (FAR uint32_t *)((uintptr_t)priv->buffer + + sizeof(uint32_t)); priv->remaining -= sizeof(uint32_t); } else @@ -1299,6 +1417,14 @@ static void stm32_recvfifo(struct stm32_dev_s *priv) uint8_t *ptr = (uint8_t *)priv->buffer; int i; + if (!stm32_sdmmc_userbuf_ok(ptr, priv->remaining)) + { + syslog(LOG_ERR, "ERROR: RX tail %p rem %zu outside SRAM, drop\n", + ptr, priv->remaining); + priv->remaining = 0; + break; + } + for (i = 0; i < (int)priv->remaining; i++) { *ptr++ = data.b[i]; @@ -1549,6 +1675,23 @@ static void stm32_endtransfer(struct stm32_dev_s *priv, static void stm32_sdmmc_fifo_monitor(void *arg) { struct stm32_dev_s *priv = (struct stm32_dev_s *)arg; + irqstate_t flags; + bool requeue; + + /* This runs on the work queue, and the SDMMC interrupt handler calls + * stm32_recvfifo() on the same buffer/remaining pair. The handler can + * preempt this thread between the test and the decrement, and the second + * decrement then takes remaining below zero. It is a size_t, so it wraps + * to a huge value, the "remaining < FIFO_SIZE / 2" guard stops meaning + * anything, and buffer walks off the end of SRAM4. 2026-09-15: + * remaining=0xFFFFFDF4, buffer=0x38010000, followed immediately by a + * hardfault in wd_start_abstick once mmcsd_write used the waitwdog that + * shares this struct. + * + * Decide and update inside one critical section. + */ + + flags = enter_critical_section(); if (priv->receivecnt && priv->remaining && priv->remaining < FIFO_SIZE_IN_BYTES / 2) @@ -1558,11 +1701,20 @@ static void stm32_sdmmc_fifo_monitor(void *arg) stm32_recvfifo(priv); } - /* Check for the lame FIFO condition */ + /* Check for the lame FIFO condition. remaining==0 means the user + * buffer is done; re-queueing then livelocks HPWORK every tick. + */ + + requeue = (priv->remaining != 0 && + sdmmc_getreg32(priv, STM32_SDMMC_DCOUNT_OFFSET) != 0 && + sdmmc_getreg32(priv, STM32_SDMMC_STA_OFFSET) == + STM32_SDMMC_STA_DPSMACT); + + leave_critical_section(flags); + + /* Queue outside the critical section: work_queue wakes a thread. */ - if (sdmmc_getreg32(priv, STM32_SDMMC_DCOUNT_OFFSET) != 0 && - sdmmc_getreg32(priv, STM32_SDMMC_STA_OFFSET) == - STM32_SDMMC_STA_DPSMACT) + if (requeue) { work_queue(HPWORK, &priv->cbfifo, stm32_sdmmc_fifo_monitor, arg, 1); From 29c221670d39cf223f028fc29d8c73948b93741c Mon Sep 17 00:00:00 2001 From: 19y Date: Fri, 18 Sep 2026 08:46:57 +0800 Subject: [PATCH 14/15] =?UTF-8?q?config(velaguard):=20ai=5Fagent=20?= =?UTF-8?q?=E6=A0=88=E6=89=A9=E5=88=B0=2032K?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 工具调用与较长 HTTPS 回复需要更大默认栈,与参赛仓 scripts/configs 对齐。 Co-authored-by: Cursor --- .../arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig index 64037e94cb4..1e09a1b9df0 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig +++ b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig @@ -48,6 +48,7 @@ CONFIG_DEV_URANDOM=y CONFIG_DRIVERS_VIDEO=y CONFIG_ETH0_PHY_LAN8740A=y CONFIG_EXAMPLES_AI_AGENT_VELA=y +CONFIG_EXAMPLES_AI_AGENT_VELA_STACKSIZE=32768 CONFIG_EXAMPLES_AI_AGENT_VELA_DATA_DIR="/data/agent" CONFIG_EXAMPLES_AI_AGENT_VELA_NODE_DISPLAY_NAME="VelaGuard" CONFIG_EXAMPLES_AI_AGENT_VELA_NODE_ID="velaguard-01" From 581e576b65ab1c702f9a2b329cfa1cf42f2d9ba5 Mon Sep 17 00:00:00 2001 From: 19y Date: Fri, 18 Sep 2026 08:46:57 +0800 Subject: [PATCH 15/15] =?UTF-8?q?config(velaguard):=20=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=20MQTT=20=E9=BB=98=E8=AE=A4=20broker=20=E5=88=B0=E6=9D=BF?= =?UTF-8?q?=E7=BA=A7=20defconfig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 与参赛仓 scripts/configs/velaguard-lvgl.defconfig 保持一致,避免仅装脚本配置时漏拷。 Co-authored-by: Cursor --- .../stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig index 1e09a1b9df0..a720c6bd70c 100644 --- a/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig +++ b/boards/arm/stm32h7/stm32h750b-dk/configs/velaguard-lvgl/defconfig @@ -104,6 +104,11 @@ CONFIG_NETUTILS_ESP8266_BAUDRATE=115200 CONFIG_VG_NET_FAILOVER=y CONFIG_VG_WIFI_SSID="19y" CONFIG_VG_WIFI_PASSWORD="12345678" +CONFIG_VG_MQTT_BROKER_HOST="8.148.67.174" +CONFIG_VG_MQTT_BROKER_PORT=1883 +CONFIG_VG_MQTT_USERNAME="velaguard" +CONFIG_VG_MQTT_PASSWORD="2f4505862d80e2ccb8fd5ff0739e172f" +CONFIG_VG_MQTT_KEEPALIVE=60 CONFIG_NET_BROADCAST=y CONFIG_NET_ETH_PKTSIZE=1500 CONFIG_NET_ICMP_SOCKET=y