2025-08-29 3:21 PM
We are developing a product that needs the ability to run 3 separate CAN interfaces connected to 3 separate CAN buses. I have the NUCLEO-F413ZH and I can successfully initialize and start CAN1, CAN2, and CAN3 and transmit from each of them in a single application, but I only get RX interrupts on CAN3 when all 3 interfaces are initialized and started. Additionally, if I only initialize and start CAN1 or CAN3 in my application, I can transmit and receive from them, but not CAN2.
Pages 1076-1077 of the part datasheet/reference manual (RM0430) lists dual and single CAN peripheral configurations:
First question: is it possible to run all three CAN interfaces simultaneously and receive messages from each of them?
CAN2 doesn't have direct access to SRAM, so I think if I want to use CAN2 for receiving, I also need to enable CAN1. Is that correct?
I don't understand what is meant by the master/slave relationship between CAN1 and CAN2. It sounds like messages received on CAN2 need to "route" through CAN1 to get to SRAM, but I'm not sure. How should CAN1 and CAN 2 be configured so that I can receive messages on either interface?
2025-08-29 5:16 PM
When you configure the filters, you'd typically split the filters (28) in half and assign to accordingly to CAN1 and CAN2.
void CAN_SetFilter(CAN_MsgStruct *msg)
{
static CAN_FilterTypeDef sFilterConfig;
if(msg->hcan == &hcan1)
{
sFilterConfig.FilterBank = 0;
#if defined(CAN2)
sFilterConfig.SlaveStartFilterBank = 14;
#endif
}
#if defined(CAN2)
else if(msg->hcan == &hcan2)
{
sFilterConfig.FilterBank = 14;
sFilterConfig.SlaveStartFilterBank = 14;
}
#endif
#if defined(CAN3)
else if(msg->hcan == &hcan3)
{
sFilterConfig.FilterBank = 0;
}
#endif
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
if(HAL_CAN_ConfigFilter(msg->hcan, &sFilterConfig) != HAL_OK)
{
Error_Handler(); // Error_Handler should never be called, so we won't worry about handling these errors.
}
if(HAL_CAN_Start(msg->hcan) != HAL_OK)
{
Error_Handler();
}
if (HAL_CAN_ActivateNotification(msg->hcan, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_TX_MAILBOX_EMPTY) != HAL_OK)
{
Error_Handler();
}
}