2023-01-17 06:36 AM
I have an STM32F403ZH Nucleo board and it's connected to three separate CAN channels. I would like to be able to receive identical messages on any channel (same identifier, baud rate, etc) and have the microcontroller be able to determine which one it came from so it can handle it differently. This would allow my three identical devices to not have to be reprogrammed to send messages with different identifiers.
I've been looking through the reference manual and I don't think it's possible. The 3 different CAN controllers all send the same interrupt to the main controller. No trace of which CAN controller sent the interrupt or received the message is stored when the message is sent to the FIFO, or in the mailbox when the main controller receives the message from the FIFO. I could differentiate between two channels by having them output into different FIFOs, but not three. If anybody knows a way then I'd be happy to hear it. Thank you.
Solved! Go to Solution.
2023-01-17 06:36 PM
You need to compare the CAN instance
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
if(hcan->Instance == hcan1.Instance)
{
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can1_header, can1_data) != HAL_OK)
{
// error handler
}
}
else if(hcan->Instance == hcan2.Instance)
{
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can2_header, can2_data) != HAL_OK)
{
// error handler
}
}
}
2023-01-17 06:36 PM
You need to compare the CAN instance
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
if(hcan->Instance == hcan1.Instance)
{
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can1_header, can1_data) != HAL_OK)
{
// error handler
}
}
else if(hcan->Instance == hcan2.Instance)
{
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can2_header, can2_data) != HAL_OK)
{
// error handler
}
}
}
2023-01-18 04:47 AM
At the start of the CAN RXFIFO interrupt service routine read the interrupt vector from SCB->ICSR. This will uniquely identify which CAN bus is being processed.
I don't use the HAL or Cube. I have a reentrant RXFIFO handler which services all buses and FIFOs. I use the ICSR to determine which CAN peripheral and FIFO is in use and append the information to the incoming CAN message before queueing it to be passed to the CANopen protocol stack.
Determining the bus is necessary for some CANopen 4 implementations that support redundant buses and flying bus masters.
Jack Peacock
2023-01-18 08:01 AM
Excellent, thank you!