stm32: add FDCAN support for STM32H743 (SKR-3 Series) (#5668)
Signed-off-by: Chen.BJ from BigTreeTech <chenbj@biqu3d.com>
This commit is contained in:
parent
9e4994cbdb
commit
a8883d83e3
|
@ -107,7 +107,7 @@ config HAVE_STM32_CANBUS
|
||||||
default y if MACH_STM32F1 || MACH_STM32F2 || MACH_STM32F4x5 || MACH_STM32F446 || MACH_STM32F0x2
|
default y if MACH_STM32F1 || MACH_STM32F2 || MACH_STM32F4x5 || MACH_STM32F446 || MACH_STM32F0x2
|
||||||
config HAVE_STM32_FDCANBUS
|
config HAVE_STM32_FDCANBUS
|
||||||
bool
|
bool
|
||||||
default y if MACH_STM32G0
|
default y if MACH_STM32G0 || MACH_STM32H7
|
||||||
config HAVE_STM32_USBCANBUS
|
config HAVE_STM32_USBCANBUS
|
||||||
bool
|
bool
|
||||||
depends on HAVE_STM32_USBFS || HAVE_STM32_USBOTG
|
depends on HAVE_STM32_USBFS || HAVE_STM32_USBOTG
|
||||||
|
@ -351,12 +351,20 @@ choice
|
||||||
select CANSERIAL
|
select CANSERIAL
|
||||||
config STM32_MMENU_CANBUS_PD0_PD1
|
config STM32_MMENU_CANBUS_PD0_PD1
|
||||||
bool "CAN bus (on PD0/PD1)" if LOW_LEVEL_OPTIONS
|
bool "CAN bus (on PD0/PD1)" if LOW_LEVEL_OPTIONS
|
||||||
depends on HAVE_STM32_CANBUS
|
depends on HAVE_STM32_CANBUS || HAVE_STM32_FDCANBUS
|
||||||
select CANSERIAL
|
select CANSERIAL
|
||||||
config STM32_MMENU_CANBUS_PB0_PB1
|
config STM32_MMENU_CANBUS_PB0_PB1
|
||||||
bool "CAN bus (on PB0/PB1)"
|
bool "CAN bus (on PB0/PB1)"
|
||||||
depends on HAVE_STM32_FDCANBUS
|
depends on HAVE_STM32_FDCANBUS
|
||||||
select CANSERIAL
|
select CANSERIAL
|
||||||
|
config STM32_MMENU_CANBUS_PD12_PD13
|
||||||
|
bool "CAN bus (on PD12/PD13)"
|
||||||
|
depends on HAVE_STM32_FDCANBUS
|
||||||
|
select CANSERIAL
|
||||||
|
config STM32_MMENU_CANBUS_PC2_PC3
|
||||||
|
bool "CAN bus (on PC2/PC3)"
|
||||||
|
depends on HAVE_STM32_FDCANBUS
|
||||||
|
select CANSERIAL
|
||||||
config STM32_USBCANBUS_PA11_PA12
|
config STM32_USBCANBUS_PA11_PA12
|
||||||
bool "USB to CAN bus bridge (USB on PA11/PA12)"
|
bool "USB to CAN bus bridge (USB on PA11/PA12)"
|
||||||
depends on HAVE_STM32_USBCANBUS
|
depends on HAVE_STM32_USBCANBUS
|
||||||
|
@ -377,10 +385,16 @@ choice
|
||||||
depends on HAVE_STM32_CANBUS && MACH_STM32F4
|
depends on HAVE_STM32_CANBUS && MACH_STM32F4
|
||||||
config STM32_CMENU_CANBUS_PD0_PD1
|
config STM32_CMENU_CANBUS_PD0_PD1
|
||||||
bool "CAN bus (on PD0/PD1)"
|
bool "CAN bus (on PD0/PD1)"
|
||||||
depends on HAVE_STM32_CANBUS
|
depends on HAVE_STM32_CANBUS || HAVE_STM32_FDCANBUS
|
||||||
config STM32_CMENU_CANBUS_PB0_PB1
|
config STM32_CMENU_CANBUS_PB0_PB1
|
||||||
bool "CAN bus (on PB0/PB1)"
|
bool "CAN bus (on PB0/PB1)"
|
||||||
depends on HAVE_STM32_FDCANBUS
|
depends on HAVE_STM32_FDCANBUS
|
||||||
|
config STM32_CMENU_CANBUS_PD12_PD13
|
||||||
|
bool "CAN bus (on PD12/PD13)"
|
||||||
|
depends on HAVE_STM32_FDCANBUS
|
||||||
|
config STM32_CMENU_CANBUS_PC2_PC3
|
||||||
|
bool "CAN bus (on PC2/PC3)"
|
||||||
|
depends on HAVE_STM32_FDCANBUS
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
|
||||||
|
@ -402,5 +416,11 @@ config STM32_CANBUS_PD0_PD1
|
||||||
config STM32_CANBUS_PB0_PB1
|
config STM32_CANBUS_PB0_PB1
|
||||||
bool
|
bool
|
||||||
default y if STM32_MMENU_CANBUS_PB0_PB1 || STM32_CMENU_CANBUS_PB0_PB1
|
default y if STM32_MMENU_CANBUS_PB0_PB1 || STM32_CMENU_CANBUS_PB0_PB1
|
||||||
|
config STM32_CANBUS_PD12_PD13
|
||||||
|
bool
|
||||||
|
default y if STM32_MMENU_CANBUS_PD12_PD13 || STM32_CMENU_CANBUS_PD12_PD13
|
||||||
|
config STM32_CANBUS_PC2_PC3
|
||||||
|
bool
|
||||||
|
default y if STM32_MMENU_CANBUS_PC2_PC3 || STM32_CMENU_CANBUS_PC2_PC3
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -55,13 +55,25 @@ FDCAN_RAM_TypeDef *fdcan_ram = (FDCAN_RAM_TypeDef *)(SRAMCAN_BASE);
|
||||||
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB8,PB9");
|
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB8,PB9");
|
||||||
#define GPIO_Rx GPIO('B', 8)
|
#define GPIO_Rx GPIO('B', 8)
|
||||||
#define GPIO_Tx GPIO('B', 9)
|
#define GPIO_Tx GPIO('B', 9)
|
||||||
|
#elif CONFIG_STM32_CANBUS_PD0_PD1
|
||||||
|
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PD0,PD1");
|
||||||
|
#define GPIO_Rx GPIO('D', 0)
|
||||||
|
#define GPIO_Tx GPIO('D', 1)
|
||||||
|
#elif CONFIG_STM32_CANBUS_PD12_PD13
|
||||||
|
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PD12,PD13");
|
||||||
|
#define GPIO_Rx GPIO('D', 12)
|
||||||
|
#define GPIO_Tx GPIO('D', 13)
|
||||||
#elif CONFIG_STM32_CANBUS_PB0_PB1
|
#elif CONFIG_STM32_CANBUS_PB0_PB1
|
||||||
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB0,PB1");
|
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB0,PB1");
|
||||||
#define GPIO_Rx GPIO('B', 0)
|
#define GPIO_Rx GPIO('B', 0)
|
||||||
#define GPIO_Tx GPIO('B', 1)
|
#define GPIO_Tx GPIO('B', 1)
|
||||||
|
#elif CONFIG_STM32_CANBUS_PC2_PC3
|
||||||
|
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PC2,PC3");
|
||||||
|
#define GPIO_Rx GPIO('C', 2)
|
||||||
|
#define GPIO_Tx GPIO('C', 3)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !CONFIG_STM32_CANBUS_PB0_PB1
|
#if !(CONFIG_STM32_CANBUS_PB0_PB1 || CONFIG_STM32_CANBUS_PC2_PC3)
|
||||||
#define SOC_CAN FDCAN1
|
#define SOC_CAN FDCAN1
|
||||||
#define MSG_RAM fdcan_ram->fdcan1
|
#define MSG_RAM fdcan_ram->fdcan1
|
||||||
#else
|
#else
|
||||||
|
@ -69,8 +81,13 @@ FDCAN_RAM_TypeDef *fdcan_ram = (FDCAN_RAM_TypeDef *)(SRAMCAN_BASE);
|
||||||
#define MSG_RAM fdcan_ram->fdcan2
|
#define MSG_RAM fdcan_ram->fdcan2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CAN_IT0_IRQn TIM16_FDCAN_IT0_IRQn
|
#if CONFIG_MACH_STM32G0
|
||||||
#define CAN_FUNCTION GPIO_FUNCTION(3) // Alternative function mapping number
|
#define CAN_IT0_IRQn TIM16_FDCAN_IT0_IRQn
|
||||||
|
#define CAN_FUNCTION GPIO_FUNCTION(3) // Alternative function mapping number
|
||||||
|
#elif CONFIG_MACH_STM32H7
|
||||||
|
#define CAN_IT0_IRQn FDCAN1_IT0_IRQn
|
||||||
|
#define CAN_FUNCTION GPIO_FUNCTION(9) // Alternative function mapping number
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SOC_CAN
|
#ifndef SOC_CAN
|
||||||
#error No known CAN device for configured MCU
|
#error No known CAN device for configured MCU
|
||||||
|
@ -128,8 +145,14 @@ canbus_set_filter(uint32_t id)
|
||||||
can_filter(0, CANBUS_ID_ADMIN);
|
can_filter(0, CANBUS_ID_ADMIN);
|
||||||
can_filter(1, id);
|
can_filter(1, id);
|
||||||
can_filter(2, id + 1);
|
can_filter(2, id + 1);
|
||||||
|
|
||||||
|
#if CONFIG_MACH_STM32G0
|
||||||
SOC_CAN->RXGFC = ((id ? 3 : 1) << FDCAN_RXGFC_LSS_Pos
|
SOC_CAN->RXGFC = ((id ? 3 : 1) << FDCAN_RXGFC_LSS_Pos
|
||||||
| 0x02 << FDCAN_RXGFC_ANFS_Pos);
|
| 0x02 << FDCAN_RXGFC_ANFS_Pos);
|
||||||
|
#elif CONFIG_MACH_STM32H7
|
||||||
|
SOC_CAN->SIDFC |= (id ? 3 : 1) << FDCAN_SIDFC_LSS_Pos;
|
||||||
|
SOC_CAN->GFC = 0x02 << FDCAN_GFC_ANFS_Pos;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Leave the initialisation mode for the filter */
|
/* Leave the initialisation mode for the filter */
|
||||||
SOC_CAN->CCCR &= ~FDCAN_CCCR_CCE;
|
SOC_CAN->CCCR &= ~FDCAN_CCCR_CCE;
|
||||||
|
@ -251,6 +274,29 @@ can_init(void)
|
||||||
|
|
||||||
SOC_CAN->NBTP = btr;
|
SOC_CAN->NBTP = btr;
|
||||||
|
|
||||||
|
#if CONFIG_MACH_STM32H7
|
||||||
|
/*
|
||||||
|
The Message RAM of STM32H7 is settable
|
||||||
|
So we set it to be consistent with STM32G0
|
||||||
|
*/
|
||||||
|
uint32_t flssa = (uint32_t)&MSG_RAM - (uint32_t)&fdcan_ram->fdcan1;
|
||||||
|
uint32_t f0sa = flssa +
|
||||||
|
(((uint32_t)MSG_RAM.RXF0 - (uint32_t)MSG_RAM.FLS) / 4);
|
||||||
|
uint32_t tbsa = f0sa +
|
||||||
|
(((uint32_t)MSG_RAM.TXFIFO - (uint32_t)MSG_RAM.RXF0) / 4);
|
||||||
|
|
||||||
|
SOC_CAN->SIDFC = flssa << FDCAN_SIDFC_FLSSA_Pos;
|
||||||
|
|
||||||
|
SOC_CAN->RXF0C = ((f0sa << FDCAN_RXF0C_F0SA_Pos)
|
||||||
|
| (3 << FDCAN_RXF0C_F0S_Pos));
|
||||||
|
SOC_CAN->RXESC = ((7 << FDCAN_RXESC_F1DS_Pos)
|
||||||
|
| (7 << FDCAN_RXESC_F0DS_Pos));
|
||||||
|
|
||||||
|
SOC_CAN->TXBC = ((tbsa << FDCAN_TXBC_TBSA_Pos)
|
||||||
|
| (3 << FDCAN_TXBC_TFQS_Pos));
|
||||||
|
SOC_CAN->TXESC = 7 << FDCAN_TXESC_TBDS_Pos;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Leave the initialisation mode */
|
/* Leave the initialisation mode */
|
||||||
SOC_CAN->CCCR &= ~FDCAN_CCCR_CCE;
|
SOC_CAN->CCCR &= ~FDCAN_CCCR_CCE;
|
||||||
SOC_CAN->CCCR &= ~FDCAN_CCCR_INIT;
|
SOC_CAN->CCCR &= ~FDCAN_CCCR_INIT;
|
||||||
|
|
|
@ -46,8 +46,16 @@ lookup_clock_line(uint32_t periph_base)
|
||||||
uint32_t bit = 1 << ((periph_base - D2_APB2PERIPH_BASE) / 0x400);
|
uint32_t bit = 1 << ((periph_base - D2_APB2PERIPH_BASE) / 0x400);
|
||||||
return (struct cline){.en=&RCC->APB2ENR, .rst=&RCC->APB2RSTR, .bit=bit};
|
return (struct cline){.en=&RCC->APB2ENR, .rst=&RCC->APB2RSTR, .bit=bit};
|
||||||
} else {
|
} else {
|
||||||
uint32_t bit = 1 << ((periph_base - D2_APB1PERIPH_BASE) / 0x400);
|
uint32_t offset = ((periph_base - D2_APB1PERIPH_BASE) / 0x400);
|
||||||
return (struct cline){.en=&RCC->APB1LENR,.rst=&RCC->APB1LRSTR,.bit=bit};
|
if (offset < 32) {
|
||||||
|
uint32_t bit = 1 << offset;
|
||||||
|
return (struct cline){
|
||||||
|
.en=&RCC->APB1LENR, .rst=&RCC->APB1LRSTR, .bit=bit};
|
||||||
|
} else {
|
||||||
|
uint32_t bit = 1 << (offset - 32);
|
||||||
|
return (struct cline){
|
||||||
|
.en=&RCC->APB1HENR, .rst=&RCC->APB1HRSTR, .bit=bit};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +178,9 @@ clock_setup(void)
|
||||||
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL1)
|
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL1)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
// Set the source of FDCAN clock
|
||||||
|
MODIFY_REG(RCC->D2CCIP1R, RCC_D2CCIP1R_FDCANSEL, RCC_D2CCIP1R_FDCANSEL_0);
|
||||||
|
|
||||||
// Configure HSI48 clock for USB
|
// Configure HSI48 clock for USB
|
||||||
if (CONFIG_USB) {
|
if (CONFIG_USB) {
|
||||||
SET_BIT(RCC->CR, RCC_CR_HSI48ON);
|
SET_BIT(RCC->CR, RCC_CR_HSI48ON);
|
||||||
|
|
Loading…
Reference in New Issue