This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 0346c84d9c653541a3de85cdcd8ea6276888c0a4 Author: raiden00pl <[email protected]> AuthorDate: Mon Oct 12 16:34:02 2026 +0200 boards/arm/stm32h7/stm32h735g-dk: Add FDCAN support. FDCAN kernel clock from PLL2Q (80 MHz), FDCAN1/2/3 pins and /dev/canN registration. New fdcan configuration with FDCAN1/2 in internal loopback. Tested on stm32h735g-dk: can example on /dev/can0 and /dev/can1. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: raiden00pl <[email protected]> --- .../arm/stm32h7/boards/stm32h735g-dk/index.rst | 9 +++ .../stm32h7/stm32h735g-dk/configs/fdcan/defconfig | 58 +++++++++++++++ boards/arm/stm32h7/stm32h735g-dk/include/board.h | 41 +++++++++-- .../arm/stm32h7/stm32h735g-dk/src/CMakeLists.txt | 4 ++ boards/arm/stm32h7/stm32h735g-dk/src/Make.defs | 4 ++ .../arm/stm32h7/stm32h735g-dk/src/stm32_bringup.c | 26 +++++++ .../src/{stm32_bringup.c => stm32_can.c} | 82 +++++++++------------- .../arm/stm32h7/stm32h735g-dk/src/stm32h735g-dk.h | 4 ++ 8 files changed, 171 insertions(+), 57 deletions(-) diff --git a/Documentation/platforms/arm/stm32h7/boards/stm32h735g-dk/index.rst b/Documentation/platforms/arm/stm32h7/boards/stm32h735g-dk/index.rst index a49d34868bd..c7b71568278 100644 --- a/Documentation/platforms/arm/stm32h7/boards/stm32h735g-dk/index.rst +++ b/Documentation/platforms/arm/stm32h7/boards/stm32h735g-dk/index.rst @@ -37,3 +37,12 @@ lvgl LVGL widgets demo with the on-board LCD and GT911 touchscreen. Run ``lvgldemo widgets &`` from NSH. + +fdcan +----- + +FDCAN1 and FDCAN2 character drivers (``/dev/can0``, ``/dev/can1``) in CAN FD +mode with bit rate switching and internal loopback. Run ``can`` from NSH. + +The FDCAN kernel clock is PLL2Q at 80 MHz. FDCAN1 is on PH13/PH14 and +FDCAN2 on PB6/PB5. FDCAN3 (PF7/PF6) needs SB29 and SB30 closed. diff --git a/boards/arm/stm32h7/stm32h735g-dk/configs/fdcan/defconfig b/boards/arm/stm32h7/stm32h735g-dk/configs/fdcan/defconfig new file mode 100644 index 00000000000..3fd71a0119c --- /dev/null +++ b/boards/arm/stm32h7/stm32h735g-dk/configs/fdcan/defconfig @@ -0,0 +1,58 @@ +# +# 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_STANDARD_SERIAL is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="stm32h735g-dk" +CONFIG_ARCH_BOARD_STM32H735G_DK=y +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32H735IG=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_CHIP_STM32H7_CORTEXM7=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_BOARD_LOOPSPERMSEC=66627 +CONFIG_BUILTIN=y +CONFIG_CAN_EXTID=y +CONFIG_CAN_FD=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_EXAMPLES_CAN=y +CONFIG_EXAMPLES_CAN_NMSGS=32 +CONFIG_FS_PROCFS=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=4096 +CONFIG_INTELHEX_BINARY=y +CONFIG_LINE_MAX=64 +CONFIG_MM_REGIONS=3 +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=327680 +CONFIG_RAM_START=0x24000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_STM32_DTCMEXCLUDE=y +CONFIG_STM32_FDCAN1=y +CONFIG_STM32_FDCAN1_DBITRATE=2000000 +CONFIG_STM32_FDCAN1_FD_BRS=y +CONFIG_STM32_FDCAN1_LOOPBACK=y +CONFIG_STM32_FDCAN2=y +CONFIG_STM32_FDCAN2_DBITRATE=2000000 +CONFIG_STM32_FDCAN2_FD_BRS=y +CONFIG_STM32_FDCAN2_LOOPBACK=y +CONFIG_STM32_FDCAN_CHARDRIVER=y +CONFIG_STM32_PWR_DIRECT_SMPS_SUPPLY=y +CONFIG_STM32_USART3=y +CONFIG_SYSTEM_NSH=y +CONFIG_USART3_SERIAL_CONSOLE=y diff --git a/boards/arm/stm32h7/stm32h735g-dk/include/board.h b/boards/arm/stm32h7/stm32h735g-dk/include/board.h index 432064d8567..739dd1fdd1d 100644 --- a/boards/arm/stm32h7/stm32h735g-dk/include/board.h +++ b/boards/arm/stm32h7/stm32h735g-dk/include/board.h @@ -43,6 +43,7 @@ /* The board has a 25 MHz HSE oscillator and a 32.768 kHz LSE crystal. * PLL1 supplies a 400 MHz CPU clock, 200 MHz AHB and 100 MHz APB clocks. + * PLL2Q supplies the 80 MHz FDCAN kernel clock. */ /* rcc_reset() leaves the 64 MHz HSI oscillator divided by four. */ @@ -81,14 +82,24 @@ #define STM32_PLL1P_FREQUENCY (STM32_VCO1_FREQUENCY / 2) #define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 4) -/* PLL2 is unused. */ +/* PLL2, wide 4 - 8 MHz input, enable DIVQ + * + * PLL2_VCO = (25,000,000 / 5) * 80 = 400 MHz + * + * PLL2Q = PLL2_VCO/5 = 400 MHz / 5 = 80 MHz + */ -#define STM32_PLLCFG_PLL2CFG 0 -#define STM32_PLLCFG_PLL2M 0 -#define STM32_PLLCFG_PLL2N 0 -#define STM32_PLLCFG_PLL2P 0 -#define STM32_PLLCFG_PLL2Q 0 -#define STM32_PLLCFG_PLL2R 0 +#define STM32_PLLCFG_PLL2CFG (RCC_PLLCFGR_PLL2VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL2RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVQ2EN) +#define STM32_PLLCFG_PLL2M RCC_PLLCKSELR_DIVM2(5) +#define STM32_PLLCFG_PLL2N RCC_PLL2DIVR_N2(80) +#define STM32_PLLCFG_PLL2P RCC_PLL2DIVR_P2(5) +#define STM32_PLLCFG_PLL2Q RCC_PLL2DIVR_Q2(5) +#define STM32_PLLCFG_PLL2R RCC_PLL2DIVR_R2(5) + +#define STM32_VCO2_FREQUENCY ((STM32_HSE_FREQUENCY / 5) * 80) +#define STM32_PLL2Q_FREQUENCY (STM32_VCO2_FREQUENCY / 5) #ifdef CONFIG_STM32_LTDC /* PLL3R supplies the LCD pixel clock: 800 MHz / 83 = 9.64 MHz. */ @@ -167,6 +178,11 @@ #define STM32_TIM16_CLKIN (2*STM32_PCLK2_FREQUENCY) #define STM32_TIM17_CLKIN (2*STM32_PCLK2_FREQUENCY) +/* FDCAN 1 2 3 clock source - PLL2Q */ + +#define STM32_RCC_D2CCIP1R_FDCANSEL RCC_D2CCIP1R_FDCANSEL_PLL2 +#define STM32_FDCANCLK STM32_PLL2Q_FREQUENCY + /* Four flash wait states at 200 MHz ACLK. */ #define BOARD_FLASH_WAITSTATES 4 @@ -176,6 +192,17 @@ #define GPIO_USART3_RX (GPIO_USART3_RX_3 | GPIO_SPEED_100MHz) #define GPIO_USART3_TX (GPIO_USART3_TX_3 | GPIO_SPEED_100MHz) +/* FDCAN1 on PH13/PH14 and FDCAN2 on PB6/PB5, both with transceivers. + * FDCAN3 (PF7/PF6) needs SB29 and SB30 closed. + */ + +#define GPIO_CAN1_RX (GPIO_CAN1_RX_4 | GPIO_SPEED_50MHz) /* PH14 */ +#define GPIO_CAN1_TX (GPIO_CAN1_TX_4 | GPIO_SPEED_50MHz) /* PH13 */ +#define GPIO_CAN2_RX (GPIO_CAN2_RX_2 | GPIO_SPEED_50MHz) /* PB5 */ +#define GPIO_CAN2_TX (GPIO_CAN2_TX_2 | GPIO_SPEED_50MHz) /* PB6 */ +#define GPIO_CAN3_RX (GPIO_CAN3_RX_2 | GPIO_SPEED_50MHz) /* PF6 */ +#define GPIO_CAN3_TX (GPIO_CAN3_TX_2 | GPIO_SPEED_50MHz) /* PF7 */ + /* I2C4: touchscreen on PF14/PF15. */ #define STM32_RCC_D3CCIPR_I2C4SRC RCC_D3CCIPR_I2C4SEL_HSI diff --git a/boards/arm/stm32h7/stm32h735g-dk/src/CMakeLists.txt b/boards/arm/stm32h7/stm32h735g-dk/src/CMakeLists.txt index 991a3c05594..7d6f8dad1c5 100644 --- a/boards/arm/stm32h7/stm32h735g-dk/src/CMakeLists.txt +++ b/boards/arm/stm32h7/stm32h735g-dk/src/CMakeLists.txt @@ -40,5 +40,9 @@ if(CONFIG_INPUT_GT9XX) list(APPEND SRCS stm32_touchscreen.c) endif() +if(CONFIG_STM32_FDCAN_CHARDRIVER) + list(APPEND SRCS stm32_can.c) +endif() + target_sources(board PRIVATE ${SRCS}) set_property(GLOBAL PROPERTY LD_SCRIPT "${NUTTX_BOARD_DIR}/scripts/flash.ld") diff --git a/boards/arm/stm32h7/stm32h735g-dk/src/Make.defs b/boards/arm/stm32h7/stm32h735g-dk/src/Make.defs index aff7f78e042..b0293e18b29 100644 --- a/boards/arm/stm32h7/stm32h735g-dk/src/Make.defs +++ b/boards/arm/stm32h7/stm32h735g-dk/src/Make.defs @@ -42,6 +42,10 @@ ifeq ($(CONFIG_INPUT_GT9XX),y) CSRCS += stm32_touchscreen.c endif +ifeq ($(CONFIG_STM32_FDCAN_CHARDRIVER),y) +CSRCS += stm32_can.c +endif + DEPPATH += --dep-path board VPATH += :board CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board diff --git a/boards/arm/stm32h7/stm32h735g-dk/src/stm32_bringup.c b/boards/arm/stm32h7/stm32h735g-dk/src/stm32_bringup.c index 92113053132..c64c0af6f71 100644 --- a/boards/arm/stm32h7/stm32h735g-dk/src/stm32_bringup.c +++ b/boards/arm/stm32h7/stm32h735g-dk/src/stm32_bringup.c @@ -79,6 +79,32 @@ int stm32_bringup(void) } #endif +#ifdef CONFIG_STM32_FDCAN_CHARDRIVER +# ifdef CONFIG_STM32_FDCAN1 + ret = stm32_can_setup(1); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register FDCAN1: %d\n", ret); + } +# endif + +# ifdef CONFIG_STM32_FDCAN2 + ret = stm32_can_setup(2); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register FDCAN2: %d\n", ret); + } +# endif + +# ifdef CONFIG_STM32_FDCAN3 + ret = stm32_can_setup(3); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register FDCAN3: %d\n", ret); + } +# endif +#endif + #ifdef CONFIG_VIDEO_FB ret = fb_register(0, 0); if (ret < 0) diff --git a/boards/arm/stm32h7/stm32h735g-dk/src/stm32_bringup.c b/boards/arm/stm32h7/stm32h735g-dk/src/stm32_can.c similarity index 54% copy from boards/arm/stm32h7/stm32h735g-dk/src/stm32_bringup.c copy to boards/arm/stm32h7/stm32h735g-dk/src/stm32_can.c index 92113053132..95e2302fa7e 100644 --- a/boards/arm/stm32h7/stm32h735g-dk/src/stm32_bringup.c +++ b/boards/arm/stm32h7/stm32h735g-dk/src/stm32_can.c @@ -1,5 +1,5 @@ /**************************************************************************** - * boards/arm/stm32h7/stm32h735g-dk/src/stm32_bringup.c + * boards/arm/stm32h7/stm32h735g-dk/src/stm32_can.c * * SPDX-License-Identifier: Apache-2.0 * @@ -26,66 +26,48 @@ #include <nuttx/config.h> -#include <sys/mount.h> -#include <syslog.h> -#include <nuttx/fs/fs.h> -#include <nuttx/video/fb.h> -#include <nuttx/leds/userled.h> -#include <nuttx/input/buttons.h> +#include <errno.h> +#include <stdio.h> +#include <nuttx/debug.h> +#include <nuttx/can/can.h> +#include <arch/board/board.h> + +#include "chip.h" +#include "arm_internal.h" +#include "stm32_fdcan.h" #include "stm32h735g-dk.h" +#ifdef CONFIG_STM32_FDCAN_CHARDRIVER + /**************************************************************************** * Public Functions ****************************************************************************/ -int stm32_bringup(void) -{ - int ret = OK; - -#ifdef CONFIG_FS_PROCFS - ret = nx_mount(NULL, "/proc", "procfs", 0, NULL); - if (ret < 0) - { - syslog(LOG_ERR, "ERROR: Failed to mount procfs: %d\n", ret); - return ret; - } -#endif - -#ifdef CONFIG_USERLED_LOWER - ret = userled_lower_initialize("/dev/userleds"); - if (ret < 0) - { - syslog(LOG_ERR, "ERROR: Failed to register LEDs: %d\n", ret); - return ret; - } -#endif +/**************************************************************************** + * Name: stm32_can_setup + * + * Description: + * Initialize FDCAN port and register it as /dev/can<port - 1> + * + ****************************************************************************/ -#ifdef CONFIG_INPUT_BUTTONS_LOWER - ret = btn_lower_initialize("/dev/buttons"); - if (ret < 0) - { - syslog(LOG_ERR, "ERROR: Failed to register buttons: %d\n", ret); - return ret; - } -#endif +int stm32_can_setup(uint8_t port) +{ + struct can_dev_s *can; + char devpath[12]; -#ifdef CONFIG_INPUT_GT9XX - ret = stm32_tsc_setup(0); - if (ret < 0) - { - syslog(LOG_ERR, "ERROR: Failed to register touchscreen: %d\n", ret); - return ret; - } -#endif + /* Call stm32_fdcaninitialize() to get an instance of the CAN interface */ -#ifdef CONFIG_VIDEO_FB - ret = fb_register(0, 0); - if (ret < 0) + can = stm32_fdcaninitialize(port); + if (can == NULL) { - syslog(LOG_ERR, "ERROR: Failed to register framebuffer: %d\n", ret); + canerr("ERROR: Failed to get CAN interface\n"); + return -ENODEV; } -#endif - return ret; + snprintf(devpath, sizeof(devpath), "/dev/can%d", port - 1); + return can_register(devpath, can); } + +#endif /* CONFIG_STM32_FDCAN_CHARDRIVER */ diff --git a/boards/arm/stm32h7/stm32h735g-dk/src/stm32h735g-dk.h b/boards/arm/stm32h7/stm32h735g-dk/src/stm32h735g-dk.h index 3bf521893f7..42e0392166f 100644 --- a/boards/arm/stm32h7/stm32h735g-dk/src/stm32h735g-dk.h +++ b/boards/arm/stm32h7/stm32h735g-dk/src/stm32h735g-dk.h @@ -64,4 +64,8 @@ int stm32_bringup(void); int stm32_tsc_setup(int minor); #endif +#ifdef CONFIG_STM32_FDCAN_CHARDRIVER +int stm32_can_setup(uint8_t port); +#endif + #endif /* __BOARDS_ARM_STM32H7_STM32H735G_DK_SRC_STM32H735G_DK_H */
