arch/arm/stm32h5: Fix STM32H5 FDCAN Driver and Add Test Files

Primary Changes
1. Add Kconfig options to select FDCAN1 and FDCAN2.
2. Fix Make.defs to use CONFIG_STM32H5_FDCAN_CHARDRIVER
3. Add FDCAN clock seleection code to stm32h5xx_rcc.c
4. Add fdcan1 config for nucleo-h563zi board.
5. Add FDCAN clock configuration and GPIOs to nucleo-h563zi board.h.
6. Added supporting code (stm32_can.c, stm32_bringup.c changes)
   for fdcan1 config.

Changed can device to start at 0. FDCAN1  = /dev/can0, FDCAN2 = /dev/can1. Enable FDCAN mode for nucleo-h563zi:fdcan1 config.

Removed ampersand from comment block
This commit is contained in:
kywwilson11 2025-08-05 14:18:05 -05:00 committed by Mateusz Szafoni
parent 28cd98c561
commit 821b067a60
10 changed files with 229 additions and 11 deletions

View file

@ -319,6 +319,10 @@ config STM32H5_DMA
bool
default n
config STM32H5_FDCAN
bool
default n
config STM32H5_SPI
bool
default n
@ -375,6 +379,18 @@ config STM32H5_ETHMAC
select ARCH_HAVE_PHY
select STM32H5_HAVE_PHY_POLLED
config STM32H5_FDCAN1
bool "FDCAN1"
default n
depends on STM32H5_HAVE_FDCAN1
select STM32H5_FDCAN
config STM32H5_FDCAN2
bool "FDCAN2"
default n
depends on STM32H5_HAVE_FDCAN2
select STM32H5_FDCAN
config STM32H5_ICACHE
bool "ICACHE"
default n

View file

@ -56,7 +56,7 @@ ifeq ($(CONFIG_ADC),y)
CHIP_CSRCS += stm32_adc.c
endif
ifeq ($(STM32H5_FDCAN_CHARDRIVER),y)
ifeq ($(CONFIG_STM32H5_FDCAN_CHARDRIVER),y)
CHIP_CSRCS += stm32_fdcan.c
endif

View file

@ -283,10 +283,10 @@
#define RCC_CFGR2_PPRE3_SHIFT (12) /* Bits 14-12: PPRE3 Prescaler */
#define RCC_CFGR2_PPRE3_MASK (0x7 << RCC_CFGR2_PPRE3_SHIFT)
# define RCC_CFGR2_PPRE3_HCLK1 (0 << RCC_CFGR2_PPRE3_SHIFT) /* 0xx: HCLK1 not divided */
# define RCC_CFGR2_PPRE3_HCLK1d2 (4 << RCC_CFGR2_PPRE3_SHIFT) /* 1000: HCLK1 divided by 2 */
# define RCC_CFGR2_PPRE3_HCLK1d4 (5 << RCC_CFGR2_PPRE3_SHIFT) /* 1001: HCLK1 divided by 4 */
# define RCC_CFGR2_PPRE3_HCLK1d8 (6 << RCC_CFGR2_PPRE3_SHIFT) /* 1010: HCLK1 divided by 8 */
# define RCC_CFGR2_PPRE3_HCLK1d16 (7 << RCC_CFGR2_PPRE3_SHIFT) /* 1011: HCLK1 divided by 16 */
# define RCC_CFGR2_PPRE3_HCLK1d2 (4 << RCC_CFGR2_PPRE3_SHIFT) /* 100: HCLK1 divided by 2 */
# define RCC_CFGR2_PPRE3_HCLK1d4 (5 << RCC_CFGR2_PPRE3_SHIFT) /* 101: HCLK1 divided by 4 */
# define RCC_CFGR2_PPRE3_HCLK1d8 (6 << RCC_CFGR2_PPRE3_SHIFT) /* 110: HCLK1 divided by 8 */
# define RCC_CFGR2_PPRE3_HCLK1d16 (7 << RCC_CFGR2_PPRE3_SHIFT) /* 111: HCLK1 divided by 16 */
#define RCC_CFGR2_AHB1DIS (1 << 16) /* AHB1 clock disable */
#define RCC_CFGR2_AHB2DIS (1 << 17) /* AHB2 clock disable */

View file

@ -1119,6 +1119,13 @@ void stm32_stdclockconfig(void)
putreg32(regval, STM32_RCC_CCIPR5);
#endif
/* Configure FDCAN source clock */
#if defined(STM32_RCC_CCIPR5_FDCANSEL)
regval = getreg32(STM32_RCC_CCIPR5);
regval &= ~RCC_CCIPR5_FDCANSEL_MASK;
regval |= STM32_RCC_CCIPR5_FDCANSEL;
putreg32(regval, STM32_RCC_CCIPR5);
#endif
/* Configure OCTOSPI1 source clock */
#if defined(STM32_RCC_CCIPR4_OCTOSPI1SEL)

View file

@ -0,0 +1,55 @@
#
# 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_NSH_ARGCAT is not set
# CONFIG_STANDARD_SERIAL is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="nucleo-h563zi"
CONFIG_ARCH_BOARD_NUCLEO_H563ZI=y
CONFIG_ARCH_BUTTONS=y
CONFIG_ARCH_CHIP="stm32h5"
CONFIG_ARCH_CHIP_STM32H563ZI=y
CONFIG_ARCH_CHIP_STM32H5=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_STACKDUMP=y
CONFIG_ARMV8M_STACKCHECK=y
CONFIG_BOARD_LOOPSPERMSEC=9251
CONFIG_BUILTIN=y
CONFIG_CAN_FD=y
CONFIG_DEBUG_ASSERTIONS=y
CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_EXAMPLES_CAN=y
CONFIG_EXAMPLES_CAN_NMSGS=32
CONFIG_FS_PROCFS=y
CONFIG_FS_PROCFS_REGISTER=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_LINE_MAX=64
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_DISABLE_IFUPDOWN=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=655360
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_READLINE_TABCOMPLETION=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_STACK_COLORATION=y
CONFIG_STM32H5_FDCAN1=y
CONFIG_STM32H5_FDCAN1_FD=y
CONFIG_STM32H5_FDCAN1_LOOPBACK=y
CONFIG_STM32H5_USART3=y
CONFIG_SYSTEM_NSH=y
CONFIG_TASK_NAME_SIZE=0
CONFIG_USART3_SERIAL_CONSOLE=y

View file

@ -75,7 +75,7 @@
RCC_PLL1CFGR_PLL1REN)
#define STM32_PLLCFG_PLL1N RCC_PLL1DIVR_PLL1N(100)
#define STM32_PLLCFG_PLL1P RCC_PLL1DIVR_PLL1P(2)
#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_PLL1Q(2)
#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_PLL1Q(4)
#define STM32_PLLCFG_PLL1R RCC_PLL1DIVR_PLL1R(2)
#define STM32_PLLCFG_PLL1DIVR (STM32_PLLCFG_PLL1N | \
STM32_PLLCFG_PLL1P | \
@ -84,7 +84,7 @@
#define STM32_VC01_FRQ ((STM32_HSE_FREQUENCY / 5) * 100)
#define STM32_PLL1P_FREQUENCY (STM32_VCO1_FRQ / 2)
#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FRQ / 2)
#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FRQ / 4)
#define STM32_PLL1R_FREQUENCY (STM32_VCO1_FRQ / 2)
/* PLL2 config: Need to use for max ADC speed. */
@ -120,7 +120,7 @@
RCC_PLL1CFGR_PLL1REN)
#define STM32_PLLCFG_PLL1N RCC_PLL1DIVR_PLL1N(125)
#define STM32_PLLCFG_PLL1P RCC_PLL1DIVR_PLL1P(2)
#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_PLL1Q(2)
#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_PLL1Q(4)
#define STM32_PLLCFG_PLL1R RCC_PLL1DIVR_PLL1R(2)
#define STM32_PLLCFG_PLL1DIVR (STM32_PLLCFG_PLL1N | \
STM32_PLLCFG_PLL1P | \
@ -129,7 +129,7 @@
#define STM32_VCO1_FRQ ((STM32_HSI_FREQUENCY / 8) * 125)
#define STM32_PLL1P_FREQUENCY (STM32_VCO1_FRQ / 2)
#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FRQ / 2)
#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FRQ / 4)
#define STM32_PLL1R_FREQUENCY (STM32_VCO1_FRQ / 2)
/* PLL2 config: Needed to use 2 ADC at max speed. */
@ -317,11 +317,13 @@
/* Alternate function pin selections ****************************************/
/* ADC */
/* ADC GPIOs ****************************************************************/
#define GPIO_ADC1_IN3 (GPIO_ADC1_IN3_0)
#define GPIO_ADC1_IN10 (GPIO_ADC1_IN10_0)
/* USART3 GPIOs *************************************************************/
/* USART3 (Nucleo Virtual Console): Default board solder bridge configuration
* has USART3 going to the on board ST-Link to provide a VCP. Refer to
* STMicro user manual [UM3115] for more info on solder bridge configuration.
@ -330,11 +332,19 @@
#define GPIO_USART3_RX GPIO_USART3_RX_4 /* PD9 */
#define GPIO_USART3_TX GPIO_USART3_TX_4 /* PD8 */
/* USART2 */
/* USART2 GPIOs *************************************************************/
#define GPIO_USART2_RX GPIO_USART2_RX_2 /* PD6 */
#define GPIO_USART2_TX GPIO_USART2_TX_2 /* PD5 */
/* FDCAN Clock Source and GPIOs *********************************************/
#define STM32_FDCAN_FREQUENCY STM32_PLL1Q_FREQUENCY
#define STM32_RCC_CCIPR5_FDCANSEL RCC_CCIPR5_FDCANSEL_PLL1QCK
#define GPIO_FDCAN1_RX GPIO_FDCAN1_RX_3 /* PD0 */
#define GPIO_FDCAN1_TX GPIO_FDCAN1_TX_4 /* PD1 */
/****************************************************************************
* Public Data
****************************************************************************/

View file

@ -47,4 +47,8 @@ ifeq ($(CONFIG_STM32H5_DTS),y)
CSRCS += stm32_dts.c
endif
ifeq ($(CONFIG_STM32H5_FDCAN),y)
CSRCS += stm32_can.c
endif
include $(TOPDIR)/boards/Board.mk

View file

@ -133,5 +133,17 @@ int stm32_adc_setup(void);
int stm32_dts_setup(int devno);
#endif
/****************************************************************************
* Name: stm32_can_setup
*
* Description:
* Initialize CAN and register the CAN device
*
****************************************************************************/
#ifdef CONFIG_STM32H5_FDCAN_CHARDRIVER
int stm32_can_setup(uint8_t port);
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM_STM32H5_NUCLEO_H563ZI_SRC_NUCLEO_H563ZI_H */

View file

@ -120,6 +120,25 @@ int stm32_bringup(void)
}
#endif
#ifdef CONFIG_STM32H5_FDCAN_CHARDRIVER
/* Initialize CAN and register the CAN driver. */
# ifdef CONFIG_STM32H5_FDCAN1
ret = stm32_can_setup(1);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: FDCAN1 stm32_fdcan_setup failed: %d\n", ret);
}
# endif
# ifdef CONFIG_STM32H5_FDCAN2
ret = stm32_can_setup(2);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: FDCAN2 stm32_fdcan_setup failed: %d\n", ret);
}
# endif
#endif
UNUSED(ret);
return OK;
}

View file

@ -0,0 +1,95 @@
/****************************************************************************
* boards/arm/stm32h5/nucleo-h563zi/src/stm32_can.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 <nuttx/config.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/can/can.h>
#include <arch/board/board.h>
#include "chip.h"
#include "arm_internal.h"
#include "stm32.h"
#include "stm32_fdcan.h"
#include "nucleo-h563zi.h"
#ifdef CONFIG_CAN
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
#if !defined(CONFIG_STM32H5_FDCAN1) && !defined(CONFIG_STM32H5_FDCAN2)
# error "No CAN device is enabled. Please enable at least one CAN device"
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_can_setup
*
* Description:
* Initialize CAN and register the CAN device
*
****************************************************************************/
int stm32_can_setup(uint8_t port)
{
struct can_dev_s *can;
int ret;
/* Call stm32_fdcaninitialize() to get an instance of the CAN interface */
can = stm32_fdcaninitialize(port);
if (can == NULL)
{
canerr("ERROR: Failed to get CAN interface\n");
return -ENODEV;
}
if (port == 1)
{
ret = can_register("/dev/can0", can);
}
else if (port == 2)
{
ret = can_register("/dev/can1", can);
}
else
{
ret = -ENODEV;
}
return ret;
}
#endif /* CONFIG_CAN */