arch/stm32c0: add FDCAN support

add FDCAN support for stm32c0 family.

Signed-off-by: raiden00pl <raiden00@railab.me>
This commit is contained in:
raiden00pl
2025-04-07 16:29:59 +02:00
committed by Alan C. Assis
parent 25876e327e
commit ba00fa6478
12 changed files with 7156 additions and 13 deletions
+2 -2
View File
@@ -82,8 +82,8 @@
#define STM32_IRQ_USART2 (STM32_IRQ_EXTINT + 28) /* 28: USART2 */
#define STM32_IRQ_USART3 (STM32_IRQ_EXTINT + 29) /* 29: USART3 */
#define STM32_IRQ_USART4 (STM32_IRQ_EXTINT + 29) /* 29: USART4 */
#define STM32_IRQ_FDCAN_IT0 (STM32_IRQ_EXTINT + 30) /* 30: FDCAN global interrupt 0 */
#define STM32_IRQ_FDCAN_IT1 (STM32_IRQ_EXTINT + 31) /* 31: FDCAN global interrupt 1 */
#define STM32_IRQ_FDCAN1_0 (STM32_IRQ_EXTINT + 30) /* 30: FDCAN global interrupt 0 */
#define STM32_IRQ_FDCAN1_1 (STM32_IRQ_EXTINT + 31) /* 31: FDCAN global interrupt 1 */
#define STM32_IRQ_NEXTINT (32)
+9
View File
@@ -111,4 +111,13 @@ if(CONFIG_STM32F0L0G0_WWDG)
list(APPEND SRCS stm32_wwdg.c)
endif()
if(CONFIG_STM32F0L0G0_FDCAN)
if(CONFIG_STM32F0L0G0_FDCAN_CHARDRIVER)
list(APPEND SRCS stm32_fdcan.c)
endif()
if(CONFIG_STM32F0L0G0_FDCAN_SOCKET)
list(APPEND SRCS stm32_fdcan_sock.c)
endif()
endif()
target_sources(arch PRIVATE ${SRCS})
+159 -2
View File
@@ -1346,7 +1346,7 @@ config ARCH_CHIP_STM32C092XX
select STM32F0L0G0_STM32C0
select STM32F0L0G0_HAVE_USART3
select STM32F0L0G0_HAVE_USART4
select STM32F0L0G0_HAVE_FDCAN
select STM32F0L0G0_HAVE_FDCAN1
config STM32F0L0G0_DFU
bool "DFU bootloader"
@@ -1581,7 +1581,7 @@ config STM32F0L0G0_HAVE_OPAMP4
bool
default n
config STM32F0L0G0_HAVE_FDCAN
config STM32F0L0G0_HAVE_FDCAN1
bool
default n
@@ -1680,6 +1680,12 @@ config STM32F0L0G0_DAC1
depends on STM32F0L0G0_HAVE_DAC1
select STM32F0L0G0_DAC
config STM32F0L0G0_FDCAN1
bool "FDCAN1"
default n
depends on STM32F0L0G0_HAVE_FDCAN1
select STM32F0L0G0_FDCAN
config STM32F0L0G0_FSMC
bool "FSMC"
default n
@@ -1922,6 +1928,10 @@ config STM32F0L0G0_TIM
bool
default n
config STM32F0L0G0_FDCAN
bool
default n
config STM32F0L0G0_SERIALDRIVER
bool
default n
@@ -2721,6 +2731,153 @@ config STM32F0L0G0_PWM_MULTICHAN
endmenu # Timer Configuration
menu "FDCAN driver configuration"
depends on STM32F0L0G0_FDCAN
choice
prompt "FDCAN character driver or SocketCAN support"
default STM32F0L0G0_FDCAN_CHARDRIVER
config STM32F0L0G0_FDCAN_CHARDRIVER
bool "STM32 FDCAN character driver support"
select ARCH_HAVE_CAN_ERRORS
select CAN
config STM32F0L0G0_FDCAN_SOCKET
bool "STM32 FDCAN SocketCAN support"
select NET_CAN_HAVE_ERRORS
select NET_CAN_HAVE_CANFD
endchoice # FDCAN character driver or SocketCAN support
config STM32F0L0G0_FDCAN_REGDEBUG
bool "CAN Register level debug"
depends on DEBUG_CAN_INFO
default n
---help---
Output detailed register-level CAN device debug information.
Requires also CONFIG_DEBUG_CAN_INFO.
config STM32F0L0G0_FDCAN_QUEUE_MODE
bool "FDCAN QUEUE mode (vs FIFO mode)"
default n
menu "FDCAN1 device driver options"
depends on STM32F0L0G0_FDCAN1
choice
prompt "FDCAN1 frame format"
default STM32F0L0G0_FDCAN1_ISO11898_1
config STM32F0L0G0_FDCAN1_ISO11898_1
bool "ISO11898-1"
---help---
Enable ISO11898-1 frame format
config STM32F0L0G0_FDCAN1_NONISO_FORMAT
bool "Non ISO"
---help---
Enable Non ISO, Bosch CAN FD Specification V1.0
endchoice # FDCAN1 frame format
choice
prompt "FDCAN1 mode"
default STM32F0L0G0_FDCAN1_CLASSIC
config STM32F0L0G0_FDCAN1_CLASSIC
bool "Classic CAN"
---help---
Enable Classic CAN mode
config STM32F0L0G0_FDCAN1_FD
bool "CAN FD"
depends on CAN_FD || NET_CAN_CANFD
---help---
Enable CAN FD mode
config STM32F0L0G0_FDCAN1_FD_BRS
bool "CAN FD with fast bit rate switching"
depends on CAN_FD || NET_CAN_CANFD
---help---
Enable CAN FD mode with fast bit rate switching mode.
endchoice # FDCAN1 mode
config STM32F0L0G0_FDCAN1_LOOPBACK
bool "Enable FDCAN1 loopback mode"
default n
---help---
Enable the FDCAN1 local loopback mode for testing purposes.
comment "Nominal Bit Timing"
config STM32F0L0G0_FDCAN1_BITRATE
int "FDCAN bitrate"
default 500000
range 0 1000000
---help---
FDCAN1 bitrate in bits per second. Required if STM32F0L0G0_FDCAN1 is defined.
config STM32F0L0G0_FDCAN1_NTSEG1
int "FDCAN1 NTSEG1 (PropSeg + PhaseSeg1)"
default 6
range 1 256
---help---
The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2).
config STM32F0L0G0_FDCAN1_NTSEG2
int "FDCAN1 NTSEG2 (PhaseSeg2)"
default 7
range 1 128
---help---
The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2).
config STM32F0L0G0_FDCAN1_NSJW
int "FDCAN1 synchronization jump width"
default 1
range 1 128
---help---
The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2).
comment "Data Bit Timing"
depends on CAN_FD && STM32F0L0G0_FDCAN1_FD_BRS
config STM32F0L0G0_FDCAN1_DBITRATE
int "FDCAN1 data bitrate"
default 2000000
depends on CAN_FD && STM32F0L0G0_FDCAN1_FD_BRS
---help---
FDCAN1 bitrate in bits per second. Required if operating in FD mode with bit rate switching (BRS).
config STM32F0L0G0_FDCAN1_DTSEG1
int "FDCAN1 DTSEG1 (PropSeg + PhaseSeg1 of data phase)"
default 4
range 1 31
depends on CAN_FD && STM32F0L0G0_FDCAN1_FD_BRS
---help---
The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2).
config STM32F0L0G0_FDCAN1_DTSEG2
int "FDCAN1 DTSEG2 (PhaseSeg2 of data phase)"
default 4
range 1 15
depends on CAN_FD && STM32F0L0G0_FDCAN1_FD_BRS
---help---
The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2).
config STM32F0L0G0_FDCAN1_DSJW
int "FDCAN1 fast synchronization jump width"
default 2
range 1 15
depends on CAN_FD && STM32F0L0G0_FDCAN1_FD_BRS
---help---
The duration of a synchronization jump is Tcan_clk x DSJW.
endmenu # FDCAN1 device driver options
endmenu # "FDCAN driver configuration"
menu "U[S]ART Configuration"
depends on STM32F0L0G0_USART
+9
View File
@@ -104,3 +104,12 @@ endif
ifeq ($(CONFIG_STM32F0L0G0_WWDG),y)
CHIP_CSRCS += stm32_wwdg.c
endif
ifeq ($(CONFIG_STM32F0L0G0_FDCAN),y)
ifeq ($(CONFIG_STM32F0L0G0_FDCAN_CHARDRIVER),y)
CHIP_CSRCS += stm32_fdcan.c
endif
ifeq ($(CONFIG_STM32F0L0G0_FDCAN_SOCKET),y)
CHIP_CSRCS += stm32_fdcan_sock.c
endif
endif
File diff suppressed because it is too large Load Diff
@@ -73,7 +73,7 @@
#define STM32_PWR_BASE 0x40007000 /* 0x40007000-0x400073ff PWR */
#define STM32_USBRAM_BASE 0x40009800 /* 0x40009800-0x40008fff USBRAM */
#define STM32_FDCANSRAM_BASE 0x4000b800 /* 0x4000b800-0x4000cbff FDCAN scratch RAM */
#define STM32_FDCANMRAM_BASE 0x4000b400 /* 0x4000b400-0x4000b7ff FDCAN message RAM */
#define STM32_CANRAM_BASE 0x4000b400 /* 0x4000b400-0x4000b7ff FDCAN message RAM */
#define STM32_SYSCFG_BASE 0x40010000 /* 0x40010000-0x400103ff SYSCFG */
/* EXTI ??? */
#define STM32_ADC1_BASE 0x40012400 /* 0x40012400-0x400127ff ADC1 */
@@ -114,6 +114,27 @@
#define GPIO_USART2_TX_2 (GPIO_ALT | GPIO_PULLUP | GPIO_AF1 | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN14)
#define GPIO_USART2_TX_3 (GPIO_ALT | GPIO_PULLUP | GPIO_AF1 | GPIO_PUSHPULL | GPIO_PORTD | GPIO_PIN6)
/* FDCAN1 */
#define GPIO_FDCAN1_RX_1 (GPIO_ALT | GPIO_AF4 | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN11)
#define GPIO_FDCAN1_RX_2 (GPIO_ALT | GPIO_AF3 | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN0)
#define GPIO_FDCAN1_RX_3 (GPIO_ALT | GPIO_AF4 | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN5)
#define GPIO_FDCAN1_RX_4 (GPIO_ALT | GPIO_AF4 | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN12)
#define GPIO_FDCAN1_RX_5 (GPIO_ALT | GPIO_AF8 | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN8)
#define GPIO_FDCAN1_RX_6 (GPIO_ALT | GPIO_AF4 | GPIO_PUSHPULL | GPIO_PORTC | GPIO_PIN2)
#define GPIO_FDCAN1_RX_7 (GPIO_ALT | GPIO_AF4 | GPIO_PUSHPULL | GPIO_PORTC | GPIO_PIN4)
#define GPIO_FDCAN1_RX_8 (GPIO_ALT | GPIO_AF4 | GPIO_PUSHPULL | GPIO_PORTD | GPIO_PIN0)
#define GPIO_FDCAN1_TX_1 (GPIO_ALT | GPIO_AF4 | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN12)
#define GPIO_FDCAN1_TX_2 (GPIO_ALT | GPIO_AF3 | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN1)
#define GPIO_FDCAN1_TX_3 (GPIO_ALT | GPIO_AF4 | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN13)
#define GPIO_FDCAN1_TX_4 (GPIO_ALT | GPIO_AF15 | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN6)
#define GPIO_FDCAN1_TX_5 (GPIO_ALT | GPIO_AF8 | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN9)
#define GPIO_FDCAN1_TX_6 (GPIO_ALT | GPIO_AF4 | GPIO_PUSHPULL | GPIO_PORTC | GPIO_PIN3)
#define GPIO_FDCAN1_TX_7 (GPIO_ALT | GPIO_AF4 | GPIO_PUSHPULL | GPIO_PORTC | GPIO_PIN5)
#define GPIO_FDCAN1_TX_8 (GPIO_ALT | GPIO_AF13 | GPIO_PUSHPULL | GPIO_PORTC | GPIO_PIN14)
#define GPIO_FDCAN1_TX_9 (GPIO_ALT | GPIO_AF4 | GPIO_PUSHPULL | GPIO_PORTD | GPIO_PIN1)
/* TODO: missing pinmaps */
#endif /* __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_PINMAP_H */
@@ -236,10 +236,10 @@
#define RCC_APB1RSTR_TIM2RST (1 << 0) /* Bit 0: Timer 2 reset */
#define RCC_APB1RSTR_TIM3RST (1 << 1) /* Bit 1: Timer 3 reset */
/* Bits 2-11: Reserved */
#define RCC_APB1RSTR_FDCANRST (1 << 11) /* Bit 11: FDCAN reset */
/* Bit 12: Reserved */
#define RCC_APB1RSTR_FDCANRST (1 << 12) /* Bit 12: FDCAN reset */
#define RCC_APB1RSTR_USBRST (1 << 13) /* Bit 13: USB reset */
#define RCC_APB1RSTR_SPI2RST (1 << 14) /* Bit 14: SPI 2 reset */
#define RCC_APB1RSTR_USBRST (1 << 15) /* Bit 15: USB reset */
/* Bit 15: Reserved */
#define RCC_APB1RSTR_CRCRST (1 << 16) /* Bit 15: CRC reset */
#define RCC_APB1RSTR_USART2RST (1 << 17) /* Bit 17: USART 2 reset */
#define RCC_APB1RSTR_USART3RST (1 << 18) /* Bit 18: USART 3 reset */
@@ -289,11 +289,11 @@
#define RCC_APB1ENR_TIM2EN (1 << 0) /* Bit 0: Timer 2 clock enable */
#define RCC_APB1ENR_TIM3EN (1 << 1) /* Bit 1: Timer 3 clock enable */
/* Bits 2-11: Reserved */
#define RCC_APB1ENR_FDCANEN (1 << 11) /* Bit 11: FDCAN clock enable */
/* Bit 12: Reserved */
#define RCC_APB1ENR_FDCANEN (1 << 12) /* Bit 12: FDCAN clock enable */
#define RCC_APB1ENR_USBEN (1 << 13) /* Bit 13: USB clock enable */
#define RCC_APB1ENR_SPI2EN (1 << 14) /* Bit 14: SPI 2 clock enable */
#define RCC_APB1ENR_USBEN (1 << 15) /* Bit 15: USB clock enable */
#define RCC_APB1ENR_CRCEN (1 << 16) /* Bit 15: CRC clock enable */
/* Bit 15: Reserved */
#define RCC_APB1ENR_CRCEN (1 << 16) /* Bit 16: CRC clock enable */
#define RCC_APB1ENR_USART2EN (1 << 17) /* Bit 17: USART 2 clock enable */
#define RCC_APB1ENR_USART3EN (1 << 18) /* Bit 18: USART 3 clock enable */
#define RCC_APB1ENR_USART4EN (1 << 19) /* Bit 19: USART 4 clock enable */
@@ -326,6 +326,35 @@
/* TODO: APB1 peripheral clock enable in Sleep mode register */
/* RCC peripherals independent clock configuration register 1 */
#define RCC_CCIPR1_USART1SEL_SHIFT (0) /* Bits 0-1: USART1 clock source selection */
# define RCC_CCIPR1_USART1SEL_PCLK (0 << RCC_CCIPR1_USART1SEL_SHIFT)
# define RCC_CCIPR1_USART1SEL_SYSCLK (1 << RCC_CCIPR1_USART1SEL_SHIFT)
# define RCC_CCIPR1_USART1SEL_HSIKER (2 << RCC_CCIPR1_USART1SEL_SHIFT)
# define RCC_CCIPR1_USART1SEL_LSE (3 << RCC_CCIPR1_USART1SEL_SHIFT)
#define RCC_CCIPR1_FDCAN1SEL_SHIFT (8) /* Bits 8-9: FDCAN1 clock source selection */
# define RCC_CCIPR1_FDCAN1SEL_PCLK (0 << RCC_CCIPR1_FDCAN1SEL_SHIFT)
# define RCC_CCIPR1_FDCAN1SEL_SYSCLK (1 << RCC_CCIPR1_FDCAN1SEL_SHIFT)
# define RCC_CCIPR1_FDCAN1SEL_HSIKER (2 << RCC_CCIPR1_FDCAN1SEL_SHIFT)
#define RCC_CCIPR1_I2C1SEL_SHIFT (12) /* Bits 12-13: I2C1 clock source selection */
# define RCC_CCIPR1_I2C1SEL_PCLK (0 << RCC_CCIPR1_I2C1SEL_SHIFT)
# define RCC_CCIPR1_I2C1SEL_SYSCLK (1 << RCC_CCIPR1_I2C1SEL_SHIFT)
# define RCC_CCIPR1_I2C1SEL_HSIKER (2 << RCC_CCIPR1_I2C1SEL_SHIFT)
#define RCC_CCIPR1_I2S1SEL_SHIFT (14) /* Bits 14-15: I2S1 clock source selection */
# define RCC_CCIPR1_I2S1SEL_PCLK (0 << RCC_CCIPR1_I2S1SEL_SHIFT)
# define RCC_CCIPR1_I2S1SEL_HSIKER (2 << RCC_CCIPR1_I2S1SEL_SHIFT)
# define RCC_CCIPR1_I2S1SEL_I2S (3 << RCC_CCIPR1_I2S1SEL_SHIFT)
#define RCC_CCIPR1_ADC1SEL_SHIFT (30) /* Bits 30-31: ADC1 clock source selection */
# define RCC_CCIPR1_ADC1SEL_SYSCLK (0 << RCC_CCIPR1_ADC1SEL_SHIFT)
# define RCC_CCIPR1_ADC1SEL_HSIKER (2 << RCC_CCIPR1_ADC1SEL_SHIFT)
/* RCC peripherals independent clock configuration register 2 */
#define RCC_CCIPR2_USBSEL_SHIFT (12) /* Bit 12: SB clock source selection */
#define RCC_CCIPR2_USBSEL_HSIUSB48 (0 << RCC_CCIPR2_USBSEL_SHIFT)
#define RCC_CCIPR2_USBSEL_HSE (1 << RCC_CCIPR2_USBSEL_SHIFT)
/* Clock configuration register 1 */
#define RCC_CSR1_LSEON (1 << 0) /* Bit 0: LSE enable */
File diff suppressed because it is too large Load Diff
+112
View File
@@ -0,0 +1,112 @@
/****************************************************************************
* arch/arm/src/stm32f0l0g0/stm32_fdcan.h
*
* 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.
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_STM32F0L0G0_STM32_FDCAN_H
#define __ARCH_ARM_SRC_STM32F0L0G0_STM32_FDCAN_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "chip.h"
#include "hardware/stm32_fdcan.h"
#include <nuttx/can/can.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Port numbers for use with stm32_fdcan_initialize() */
#define FDCAN1 1
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef CONFIG_STM32F0L0G0_FDCAN_CHARDRIVER
/****************************************************************************
* Name: stm32_fdcaninitialize
*
* Description:
* Initialize the selected FDCAN port
*
* Input Parameters:
* Port number (for hardware that has multiple FDCAN interfaces)
*
* Returned Value:
* Valid FDCAN device structure reference on success; a NULL on failure
*
****************************************************************************/
struct can_dev_s *stm32_fdcaninitialize(int port);
#endif
#ifdef CONFIG_STM32F0L0G0_FDCAN_SOCKET
/****************************************************************************
* Name: stm32_fdcansockinitialize
*
* Description:
* Initialize the selected FDCAN port as SocketCAN interface
*
* Input Parameters:
* Port number (for hardware that has multiple FDCAN interfaces)
*
* Returned Value:
* OK on success; Negated errno on failure.
*
****************************************************************************/
int stm32_fdcansockinitialize(int port);
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_STM32F0L0G0_STM32_FDCAN_H */
File diff suppressed because it is too large Load Diff
+9 -1
View File
@@ -176,7 +176,7 @@ static inline void rcc_enableapb1(void)
#endif
#endif
#ifdef CONFIG_STM32F0L0G0_FDCAN
#ifdef CONFIG_STM32F0L0G0_FDCAN1
/* FDCAN1 clock enable */
regval |= RCC_APB1ENR_FDCANEN;
@@ -475,6 +475,14 @@ static void stm32_stdclockconfig(void)
/* Wait until the selected source is used as the system clock source */
while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != STM32_SYSCLK_SWS);
#ifdef CONFIG_STM32F0L0G0_FDCAN1
/* Configure FDCAN1 clock source */
regval = getreg32(STM32_RCC_CCIPR1);
regval |= STM32_FDCAN1_SEL;
putreg32(regval, STM32_RCC_CCIPR1);
#endif
}
#endif