cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 Dual CAN - first CAN instance both tx rx works, second CAN instance only tx works, receive does not

Kunaalkk1
Associate III

Moved from this post.

Hi @mƎALLEm,

I am facing the same issue with STM32F407. Whichever CAN is master in filter configuration is working, the other one is not.

void can_init() {

	CAN_FilterTypeDef sFilterConfig1;
	sFilterConfig1.FilterBank = 0;
	sFilterConfig1.FilterMode = CAN_FILTERMODE_IDMASK;
	sFilterConfig1.FilterScale = CAN_FILTERSCALE_32BIT;
	sFilterConfig1.FilterIdHigh = 0x0000;
	sFilterConfig1.FilterIdLow = 0x0000;
	sFilterConfig1.FilterMaskIdHigh = 0x0000;
	sFilterConfig1.FilterMaskIdLow = 0x0000;
	sFilterConfig1.FilterFIFOAssignment = CAN_FILTER_FIFO1;
	sFilterConfig1.FilterActivation = ENABLE;
	sFilterConfig1.SlaveStartFilterBank = 14;
	if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig1) != HAL_OK) {
	    Error_Handler();
	}
	CAN_FilterTypeDef sFilterConfig2;
	sFilterConfig2.FilterBank = 14;
	sFilterConfig2.FilterMode = CAN_FILTERMODE_IDMASK;
	sFilterConfig2.FilterScale = CAN_FILTERSCALE_32BIT;
	sFilterConfig2.FilterIdHigh = 0x0000;
	sFilterConfig2.FilterIdLow = 0x0000;
	sFilterConfig2.FilterMaskIdHigh = 0x0000;
	sFilterConfig2.FilterMaskIdLow = 0x0000;
	sFilterConfig2.FilterFIFOAssignment = CAN_FILTER_FIFO0;
	sFilterConfig2.FilterActivation = ENABLE;
	if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig2) != HAL_OK) {
	    Error_Handler();
	}

    // Start both CAN interfaces
    if (HAL_CAN_Start(&hcan1) != HAL_OK) {
        Error_Handler();
    }

    if (HAL_CAN_Start(&hcan2) != HAL_OK) {
        Error_Handler();
    }

    // Activate notifications for both CAN interfaces
    if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {
        Error_Handler();
    }

    if (HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO1_MSG_PENDING) != HAL_OK) {
        Error_Handler();
    }
}

In the above code, CAN1 is configured with a slave filter bank, CAN2 RX and TX are working, CAN1 only TX is working. I ditched the interrupt and tried with polling also. Same result.

In the below code, CAN2 is configured with slave filter bank, CAN1 RX and TX are working, CAN2 only TX is working. I switched between internal as well as external clock and tried polling.

void can_init() {

	CAN_FilterTypeDef sFilterConfig1;
	sFilterConfig1.FilterBank = 0;
	sFilterConfig1.FilterMode = CAN_FILTERMODE_IDMASK;
	sFilterConfig1.FilterScale = CAN_FILTERSCALE_32BIT;
	sFilterConfig1.FilterIdHigh = 0x0000;
	sFilterConfig1.FilterIdLow = 0x0000;
	sFilterConfig1.FilterMaskIdHigh = 0x0000;
	sFilterConfig1.FilterMaskIdLow = 0x0000;
	sFilterConfig1.FilterFIFOAssignment = CAN_FILTER_FIFO0;
	sFilterConfig1.FilterActivation = ENABLE;
	sFilterConfig1.SlaveStartFilterBank = 14;
	if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig1) != HAL_OK) {
	    Error_Handler();
	}
	CAN_FilterTypeDef sFilterConfig2;
	sFilterConfig2.FilterBank = 14;
	sFilterConfig2.FilterMode = CAN_FILTERMODE_IDMASK;
	sFilterConfig2.FilterScale = CAN_FILTERSCALE_32BIT;
	sFilterConfig2.FilterIdHigh = 0x0000;
	sFilterConfig2.FilterIdLow = 0x0000;
	sFilterConfig2.FilterMaskIdHigh = 0x0000;
	sFilterConfig2.FilterMaskIdLow = 0x0000;
	sFilterConfig2.FilterFIFOAssignment = CAN_FILTER_FIFO1;
	sFilterConfig2.FilterActivation = ENABLE;
	if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig2) != HAL_OK) {
	    Error_Handler();
	}

    // Start both CAN interfaces
    if (HAL_CAN_Start(&hcan1) != HAL_OK) {
        Error_Handler();
    }

    if (HAL_CAN_Start(&hcan2) != HAL_OK) {
        Error_Handler();
    }

    // Activate notifications for both CAN interfaces
    if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {
        Error_Handler();
    }

    if (HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO1_MSG_PENDING) != HAL_OK) {
        Error_Handler();
    }
}

I even tried configuring `HAL_CAN_ConfigFilter` both using hcan1, both using hcan2, and tried putting seperate handles in seperate CANs. Anyway, only one CAN is working at a time, whichever is made the master.

1 REPLY 1
mƎALLEm
ST Employee

Hello,

You are setting the config of CAN1 to CAN2:

	if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig2) != HAL_OK) {
	    Error_Handler();
	}

It's a copy paste issue. You need to replace &hcan1 by &hcan2.

Also for the FIFO config:

For CAN1, you set FIFO1:

sFilterConfig1.FilterFIFOAssignment = CAN_FILTER_FIFO1;

While in the interrupt you configured Rx FIFO0 interrupt:

if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)

Same thing for CAN2, you configured Rx FIFO0 interrupt:

sFilterConfig2.FilterFIFOAssignment = CAN_FILTER_FIFO0;

While in the interrupt you configured Rx FIFO1 interrupt:

if (HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO1_MSG_PENDING) != HAL_OK)

Hope that helps.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.