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 749a1cc23653cf09983d82094c58bb268aa0262d Author: raiden00pl <[email protected]> AuthorDate: Mon Oct 12 09:50:44 2026 +0200 boards/arm/common/stm32: support FDCAN in the common CAN setup stm32_can_setup() and stm32_cansock_setup() now also work with FDCAN, so boards with bxCAN and FDCAN use the same API. Every enabled CAN or FDCAN instance is registered in order as /dev/can0, /dev/can1, ..., as before for bxCAN, and CAN3/FDCAN3 are supported too. A board can define BOARD_CAN_GPIO_STBY in board.h to enable the CAN transceiver before the interfaces are initialized. The STM32H7 FDCAN driver has its own SocketCAN interface, so H7 boards keep their own FDCAN setup. Signed-off-by: raiden00pl <[email protected]> Assisted-by: Claude Code --- boards/arm/common/stm32/include/stm32_can_setup.h | 4 +- .../arm/common/stm32/include/stm32_cansock_setup.h | 3 +- boards/arm/common/stm32/src/CMakeLists.txt | 6 +- boards/arm/common/stm32/src/Make.defs | 6 +- boards/arm/common/stm32/src/stm32_can_setup.c | 101 +++++++++++++-------- boards/arm/common/stm32/src/stm32_cansock_setup.c | 78 +++++++++++----- 6 files changed, 126 insertions(+), 72 deletions(-) diff --git a/boards/arm/common/stm32/include/stm32_can_setup.h b/boards/arm/common/stm32/include/stm32_can_setup.h index 9cd211d05b9..6924313f876 100644 --- a/boards/arm/common/stm32/include/stm32_can_setup.h +++ b/boards/arm/common/stm32/include/stm32_can_setup.h @@ -61,7 +61,9 @@ extern "C" * Name: stm32_can_setup ****************************************************************************/ -#ifdef CONFIG_STM32_CAN_CHARDRIVER +#if (defined(CONFIG_STM32_CAN_CHARDRIVER) || \ + defined(CONFIG_STM32_FDCAN_CHARDRIVER)) && \ + !defined(CONFIG_STM32_HAVE_FDCAN_H7) int stm32_can_setup(void); #endif diff --git a/boards/arm/common/stm32/include/stm32_cansock_setup.h b/boards/arm/common/stm32/include/stm32_cansock_setup.h index 77a41b66574..a55216ff378 100644 --- a/boards/arm/common/stm32/include/stm32_cansock_setup.h +++ b/boards/arm/common/stm32/include/stm32_cansock_setup.h @@ -61,7 +61,8 @@ extern "C" * Name: stm32_cansock_setup ****************************************************************************/ -#ifdef CONFIG_STM32_CAN_SOCKET +#if (defined(CONFIG_STM32_CAN_SOCKET) || defined(CONFIG_STM32_FDCAN_SOCKET)) && \ + !defined(CONFIG_STM32_HAVE_FDCAN_H7) int stm32_cansock_setup(void); #endif diff --git a/boards/arm/common/stm32/src/CMakeLists.txt b/boards/arm/common/stm32/src/CMakeLists.txt index 635c011a731..f54a7c0a5b2 100644 --- a/boards/arm/common/stm32/src/CMakeLists.txt +++ b/boards/arm/common/stm32/src/CMakeLists.txt @@ -192,11 +192,11 @@ if(CONFIG_AUDIO_CS4344) list(APPEND SRCS stm32_cs4344.c) endif() -if(CONFIG_STM32_CAN) - if(CONFIG_STM32_CAN_CHARDRIVER) +if(NOT CONFIG_STM32_HAVE_FDCAN_H7) + if(CONFIG_STM32_CAN_CHARDRIVER OR CONFIG_STM32_FDCAN_CHARDRIVER) list(APPEND SRCS stm32_can_setup.c) endif() - if(CONFIG_STM32_CAN_SOCKET) + if(CONFIG_STM32_CAN_SOCKET OR CONFIG_STM32_FDCAN_SOCKET) list(APPEND SRCS stm32_cansock_setup.c) endif() endif() diff --git a/boards/arm/common/stm32/src/Make.defs b/boards/arm/common/stm32/src/Make.defs index 9920ba1d515..68505219878 100644 --- a/boards/arm/common/stm32/src/Make.defs +++ b/boards/arm/common/stm32/src/Make.defs @@ -206,11 +206,11 @@ ifeq ($(CONFIG_AUDIO_CS4344),y) CSRCS += stm32_cs4344.c endif -ifeq ($(CONFIG_STM32_CAN),y) - ifeq ($(CONFIG_STM32_CAN_CHARDRIVER),y) +ifneq ($(CONFIG_STM32_HAVE_FDCAN_H7),y) + ifneq ($(CONFIG_STM32_CAN_CHARDRIVER)$(CONFIG_STM32_FDCAN_CHARDRIVER),) CSRCS += stm32_can_setup.c endif - ifeq ($(CONFIG_STM32_CAN_SOCKET),y) + ifneq ($(CONFIG_STM32_CAN_SOCKET)$(CONFIG_STM32_FDCAN_SOCKET),) CSRCS += stm32_cansock_setup.c endif endif diff --git a/boards/arm/common/stm32/src/stm32_can_setup.c b/boards/arm/common/stm32/src/stm32_can_setup.c index 2b3e3c476ee..446d383c255 100644 --- a/boards/arm/common/stm32/src/stm32_can_setup.c +++ b/boards/arm/common/stm32/src/stm32_can_setup.c @@ -26,25 +26,57 @@ #include <nuttx/config.h> -#include <stdbool.h> +#include <stdio.h> #include <errno.h> -#include <nuttx/debug.h> +#include <nuttx/debug.h> #include <nuttx/can/can.h> -#include "stm32_can.h" +#include <arch/board/board.h> -#ifdef CONFIG_CAN +#ifdef BOARD_CAN_GPIO_STBY +# include "stm32_gpio.h" +#endif +#ifdef CONFIG_STM32_FDCAN_CHARDRIVER +# include "stm32_fdcan.h" +#else +# include "stm32_can.h" +#endif /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -#ifdef CONFIG_STM32_CAN1 -# define CAN_PORT 1 +#ifdef CONFIG_STM32_FDCAN_CHARDRIVER +# define CAN_INITIALIZE(port) stm32_fdcaninitialize(port) #else -# define CAN_PORT 2 +# define CAN_INITIALIZE(port) stm32_caninitialize(port) +#endif + +#if !defined(CONFIG_STM32_CAN1) && !defined(CONFIG_STM32_CAN2) && \ + !defined(CONFIG_STM32_CAN3) && !defined(CONFIG_STM32_FDCAN1) && \ + !defined(CONFIG_STM32_FDCAN2) && !defined(CONFIG_STM32_FDCAN3) +# error "No CAN is enabled. Please enable at least one CAN device" +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Enabled CAN instances, registered as /dev/can0, /dev/can1, ... */ + +static const uint8_t g_can_ports[] = +{ +#if defined(CONFIG_STM32_CAN1) || defined(CONFIG_STM32_FDCAN1) + 1, #endif +#if defined(CONFIG_STM32_CAN2) || defined(CONFIG_STM32_FDCAN2) + 2, +#endif +#if defined(CONFIG_STM32_CAN3) || defined(CONFIG_STM32_FDCAN3) + 3, +#endif +}; /**************************************************************************** * Public Functions @@ -54,50 +86,41 @@ * Name: stm32_can_setup * * Description: - * Initialize CAN and register the CAN device + * Initialize CAN and register the CAN devices * ****************************************************************************/ int stm32_can_setup(void) { struct can_dev_s *can; + char devpath[16]; int ret; + int i; - /* Register the first enabled CAN interface at "/dev/can0" */ - - can = stm32_caninitialize(CAN_PORT); - if (can == NULL) - { - canerr("ERROR: Failed to get CAN interface\n"); - return -ENODEV; - } - - ret = can_register("/dev/can0", can); - if (ret < 0) - { - canerr("ERROR: can_register failed: %d\n", ret); - return ret; - } - -#if defined(CONFIG_STM32_CAN1) && defined(CONFIG_STM32_CAN2) - /* Both CAN1 and CAN2 are enabled: register CAN2 at "/dev/can1" */ +#ifdef BOARD_CAN_GPIO_STBY + /* Enable the CAN transceiver */ - can = stm32_caninitialize(2); - if (can == NULL) - { - canerr("ERROR: Failed to get CAN interface\n"); - return -ENODEV; - } + stm32_configgpio(BOARD_CAN_GPIO_STBY); + stm32_gpiowrite(BOARD_CAN_GPIO_STBY, false); +#endif - ret = can_register("/dev/can1", can); - if (ret < 0) + for (i = 0; i < sizeof(g_can_ports); i++) { - canerr("ERROR: can_register failed: %d\n", ret); - return ret; + can = CAN_INITIALIZE(g_can_ports[i]); + if (can == NULL) + { + canerr("ERROR: Failed to get CAN%d interface\n", g_can_ports[i]); + return -ENODEV; + } + + snprintf(devpath, sizeof(devpath), "/dev/can%d", i); + ret = can_register(devpath, can); + if (ret < 0) + { + canerr("ERROR: can_register %s failed: %d\n", devpath, ret); + return ret; + } } -#endif return OK; } - -#endif /* CONFIG_CAN */ diff --git a/boards/arm/common/stm32/src/stm32_cansock_setup.c b/boards/arm/common/stm32/src/stm32_cansock_setup.c index aad7a7df26d..0c3dbeb659b 100644 --- a/boards/arm/common/stm32/src/stm32_cansock_setup.c +++ b/boards/arm/common/stm32/src/stm32_cansock_setup.c @@ -28,17 +28,51 @@ #include <nuttx/debug.h> -#include "stm32_can.h" +#include <arch/board/board.h> + +#ifdef BOARD_CAN_GPIO_STBY +# include "stm32_gpio.h" +#endif +#ifdef CONFIG_STM32_FDCAN_SOCKET +# include "stm32_fdcan.h" +#else +# include "stm32_can.h" +#endif /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -/* Configuration ************************************************************/ +#ifdef CONFIG_STM32_FDCAN_SOCKET +# define CANSOCK_INITIALIZE(port) stm32_fdcansockinitialize(port) +#else +# define CANSOCK_INITIALIZE(port) stm32_cansockinitialize(port) +#endif + +#if !defined(CONFIG_STM32_CAN1) && !defined(CONFIG_STM32_CAN2) && \ + !defined(CONFIG_STM32_CAN3) && !defined(CONFIG_STM32_FDCAN1) && \ + !defined(CONFIG_STM32_FDCAN2) && !defined(CONFIG_STM32_FDCAN3) +# error "No CAN is enabled. Please enable at least one CAN device" +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Enabled CAN instances */ -#if !defined(CONFIG_STM32_CAN1) && !defined(CONFIG_STM32_CAN2) -# error "No CAN is enable. Please enable at least one CAN device" +static const uint8_t g_can_ports[] = +{ +#if defined(CONFIG_STM32_CAN1) || defined(CONFIG_STM32_FDCAN1) + 1, +#endif +#if defined(CONFIG_STM32_CAN2) || defined(CONFIG_STM32_FDCAN2) + 2, #endif +#if defined(CONFIG_STM32_CAN3) || defined(CONFIG_STM32_FDCAN3) + 3, +#endif +}; /**************************************************************************** * Public Functions @@ -54,32 +88,26 @@ int stm32_cansock_setup(void) { - int ret = OK; - - UNUSED(ret); + int ret; + int i; -#ifdef CONFIG_STM32_CAN1 - /* Call stm32_caninitialize() to get an instance of the CAN interface */ +#ifdef BOARD_CAN_GPIO_STBY + /* Enable the CAN transceiver */ - ret = stm32_cansockinitialize(1); - if (ret < 0) - { - canerr("ERROR: Failed to get CAN interface %d\n", ret); - goto errout; - } + stm32_configgpio(BOARD_CAN_GPIO_STBY); + stm32_gpiowrite(BOARD_CAN_GPIO_STBY, false); #endif -#ifdef CONFIG_STM32_CAN2 - /* Call stm32_caninitialize() to get an instance of the CAN interface */ - - ret = stm32_cansockinitialize(2); - if (ret < 0) + for (i = 0; i < sizeof(g_can_ports); i++) { - canerr("ERROR: Failed to get CAN interface %d\n", ret); - goto errout; + ret = CANSOCK_INITIALIZE(g_can_ports[i]); + if (ret < 0) + { + canerr("ERROR: Failed to get CAN%d interface %d\n", + g_can_ports[i], ret); + return ret; + } } -#endif -errout: - return ret; + return OK; }
