stm32: Fix CAN2 handling in can.c
Using the CAN2 interface still requires that CAN1 be enabled, and the filtering hardware is always on the CAN1 hardware block. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
3935f78543
commit
1a693c18d6
|
@ -49,6 +49,7 @@
|
||||||
|
|
||||||
#if CONFIG_MACH_STM32F0
|
#if CONFIG_MACH_STM32F0
|
||||||
#define SOC_CAN CAN
|
#define SOC_CAN CAN
|
||||||
|
#define FILTER_CAN CAN
|
||||||
#define CAN_RX0_IRQn CEC_CAN_IRQn
|
#define CAN_RX0_IRQn CEC_CAN_IRQn
|
||||||
#define CAN_RX1_IRQn CEC_CAN_IRQn
|
#define CAN_RX1_IRQn CEC_CAN_IRQn
|
||||||
#define CAN_TX_IRQn CEC_CAN_IRQn
|
#define CAN_TX_IRQn CEC_CAN_IRQn
|
||||||
|
@ -58,6 +59,7 @@
|
||||||
|
|
||||||
#if CONFIG_MACH_STM32F1
|
#if CONFIG_MACH_STM32F1
|
||||||
#define SOC_CAN CAN1
|
#define SOC_CAN CAN1
|
||||||
|
#define FILTER_CAN CAN1
|
||||||
#define CAN_RX0_IRQn CAN1_RX0_IRQn
|
#define CAN_RX0_IRQn CAN1_RX0_IRQn
|
||||||
#define CAN_RX1_IRQn CAN1_RX1_IRQn
|
#define CAN_RX1_IRQn CAN1_RX1_IRQn
|
||||||
#define CAN_TX_IRQn CAN1_TX_IRQn
|
#define CAN_TX_IRQn CAN1_TX_IRQn
|
||||||
|
@ -69,12 +71,14 @@
|
||||||
#if (CONFIG_STM32_CANBUS_PA11_PA12 || CONFIG_STM32_CANBUS_PB8_PB9 \
|
#if (CONFIG_STM32_CANBUS_PA11_PA12 || CONFIG_STM32_CANBUS_PB8_PB9 \
|
||||||
|| CONFIG_STM32_CANBUS_PD0_PD1 || CONFIG_STM32_CANBUS_PI9_PH13)
|
|| CONFIG_STM32_CANBUS_PD0_PD1 || CONFIG_STM32_CANBUS_PI9_PH13)
|
||||||
#define SOC_CAN CAN1
|
#define SOC_CAN CAN1
|
||||||
|
#define FILTER_CAN CAN1
|
||||||
#define CAN_RX0_IRQn CAN1_RX0_IRQn
|
#define CAN_RX0_IRQn CAN1_RX0_IRQn
|
||||||
#define CAN_RX1_IRQn CAN1_RX1_IRQn
|
#define CAN_RX1_IRQn CAN1_RX1_IRQn
|
||||||
#define CAN_TX_IRQn CAN1_TX_IRQn
|
#define CAN_TX_IRQn CAN1_TX_IRQn
|
||||||
#define CAN_SCE_IRQn CAN1_SCE_IRQn
|
#define CAN_SCE_IRQn CAN1_SCE_IRQn
|
||||||
#elif CONFIG_STM32_CANBUS_PB5_PB6 || CONFIG_STM32_CANBUS_PB12_PB13
|
#elif CONFIG_STM32_CANBUS_PB5_PB6 || CONFIG_STM32_CANBUS_PB12_PB13
|
||||||
#define SOC_CAN CAN2
|
#define SOC_CAN CAN2
|
||||||
|
#define FILTER_CAN CAN1
|
||||||
#define CAN_RX0_IRQn CAN2_RX0_IRQn
|
#define CAN_RX0_IRQn CAN2_RX0_IRQn
|
||||||
#define CAN_RX1_IRQn CAN2_RX1_IRQn
|
#define CAN_RX1_IRQn CAN2_RX1_IRQn
|
||||||
#define CAN_TX_IRQn CAN2_TX_IRQn
|
#define CAN_TX_IRQn CAN2_TX_IRQn
|
||||||
|
@ -131,32 +135,37 @@ canhw_send(struct canbus_msg *msg)
|
||||||
void
|
void
|
||||||
canhw_set_filter(uint32_t id)
|
canhw_set_filter(uint32_t id)
|
||||||
{
|
{
|
||||||
|
CAN_TypeDef *fcan = FILTER_CAN;
|
||||||
/* Select the start slave bank */
|
/* Select the start slave bank */
|
||||||
SOC_CAN->FMR |= CAN_FMR_FINIT;
|
uint32_t fmr = fcan->FMR;
|
||||||
|
if (FILTER_CAN != SOC_CAN)
|
||||||
|
// Using CAN2 with filter on CAN1 - assign CAN2 to first filter
|
||||||
|
fmr &= ~CAN_FMR_CAN2SB;
|
||||||
|
fcan->FMR = fmr | CAN_FMR_FINIT;
|
||||||
/* Initialisation mode for the filter */
|
/* Initialisation mode for the filter */
|
||||||
SOC_CAN->FA1R = 0;
|
fcan->FA1R = 0;
|
||||||
|
|
||||||
if (CONFIG_CANBUS_FILTER) {
|
if (CONFIG_CANBUS_FILTER) {
|
||||||
uint32_t mask = CAN_TI0R_STID | CAN_TI0R_IDE | CAN_TI0R_RTR;
|
uint32_t mask = CAN_TI0R_STID | CAN_TI0R_IDE | CAN_TI0R_RTR;
|
||||||
SOC_CAN->sFilterRegister[0].FR1 = CANBUS_ID_ADMIN << CAN_RI0R_STID_Pos;
|
fcan->sFilterRegister[0].FR1 = CANBUS_ID_ADMIN << CAN_RI0R_STID_Pos;
|
||||||
SOC_CAN->sFilterRegister[0].FR2 = mask;
|
fcan->sFilterRegister[0].FR2 = mask;
|
||||||
SOC_CAN->sFilterRegister[1].FR1 = (id + 1) << CAN_RI0R_STID_Pos;
|
fcan->sFilterRegister[1].FR1 = (id + 1) << CAN_RI0R_STID_Pos;
|
||||||
SOC_CAN->sFilterRegister[1].FR2 = mask;
|
fcan->sFilterRegister[1].FR2 = mask;
|
||||||
SOC_CAN->sFilterRegister[2].FR1 = id << CAN_RI0R_STID_Pos;
|
fcan->sFilterRegister[2].FR1 = id << CAN_RI0R_STID_Pos;
|
||||||
SOC_CAN->sFilterRegister[2].FR2 = mask;
|
fcan->sFilterRegister[2].FR2 = mask;
|
||||||
} else {
|
} else {
|
||||||
SOC_CAN->sFilterRegister[0].FR1 = 0;
|
fcan->sFilterRegister[0].FR1 = 0;
|
||||||
SOC_CAN->sFilterRegister[0].FR2 = 0;
|
fcan->sFilterRegister[0].FR2 = 0;
|
||||||
id = 0;
|
id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 32-bit scale for the filter */
|
/* 32-bit scale for the filter */
|
||||||
SOC_CAN->FS1R = (1<<0) | (1<<1) | (1<<2);
|
fcan->FS1R = (1<<0) | (1<<1) | (1<<2);
|
||||||
|
|
||||||
/* Filter activation */
|
/* Filter activation */
|
||||||
SOC_CAN->FA1R = (1<<0) | (id ? (1<<1) | (1<<2) : 0);
|
fcan->FA1R = (1<<0) | (id ? (1<<1) | (1<<2) : 0);
|
||||||
/* Leave the initialisation mode for the filter */
|
/* Leave the initialisation mode for the filter */
|
||||||
SOC_CAN->FMR &= ~CAN_FMR_FINIT;
|
fcan->FMR = fmr & ~CAN_FMR_FINIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function handles CAN global interrupts
|
// This function handles CAN global interrupts
|
||||||
|
@ -241,7 +250,11 @@ compute_btr(uint32_t pclock, uint32_t bitrate)
|
||||||
void
|
void
|
||||||
can_init(void)
|
can_init(void)
|
||||||
{
|
{
|
||||||
|
// Enable clock
|
||||||
enable_pclock((uint32_t)SOC_CAN);
|
enable_pclock((uint32_t)SOC_CAN);
|
||||||
|
if (FILTER_CAN != SOC_CAN)
|
||||||
|
// Also enable CAN1 clock if using CAN2 with filter on CAN1
|
||||||
|
enable_pclock((uint32_t)FILTER_CAN);
|
||||||
|
|
||||||
gpio_peripheral(GPIO_Rx, CAN_FUNCTION, 1);
|
gpio_peripheral(GPIO_Rx, CAN_FUNCTION, 1);
|
||||||
gpio_peripheral(GPIO_Tx, CAN_FUNCTION, 0);
|
gpio_peripheral(GPIO_Tx, CAN_FUNCTION, 0);
|
||||||
|
|
Loading…
Reference in New Issue