2024-02-13 06:06 AM - edited 2024-02-13 11:11 AM
Hi there,
I am using two STM32H723ZGT communicating via FDCAN2 instance (FDCAN, no bit rate switch, 12500 bit/s). Both controller use the same FDCAN initialization code, but different filter IDs.
As shown below, the message is transfered on receiver CAN_Rx (upper trace) and acknowledged on sender CAN_Rx (lower trace), but neither the HAL_FDCAN_RxFifo0Callback() nor HAL_FDCAN_RxFifo1Callback() is triggered. When the receiver is shut down, the ackowledge disapears, so the message seems stuck in the the CAN peripherial.
CAN instance 1 (CAN2.0) is used for communication with other periperhial devices an works as expected.
What am I missing?
Thanks in advance!
CAN2 initialization FDCAN for both controller
/* USER CODE END FDCAN2_Init 1 */
hfdcan2.Instance = FDCAN2;
hfdcan2.Init.FrameFormat = FDCAN_FRAME_FD_NO_BRS;
hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan2.Init.AutoRetransmission = DISABLE;
hfdcan2.Init.TransmitPause = DISABLE;
hfdcan2.Init.ProtocolException = ENABLE;
hfdcan2.Init.NominalPrescaler = 32;
hfdcan2.Init.NominalSyncJumpWidth = 5;
hfdcan2.Init.NominalTimeSeg1 = 32;
hfdcan2.Init.NominalTimeSeg2 = 7;
hfdcan2.Init.DataPrescaler = 1;
hfdcan2.Init.DataSyncJumpWidth = 16;
hfdcan2.Init.DataTimeSeg1 = 20;
hfdcan2.Init.DataTimeSeg2 = 16;
hfdcan2.Init.MessageRAMOffset = 196;
hfdcan2.Init.StdFiltersNbr = 1;
hfdcan2.Init.ExtFiltersNbr = 1;
hfdcan2.Init.RxFifo0ElmtsNbr = 16;
hfdcan2.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64;
hfdcan2.Init.RxFifo1ElmtsNbr = 16;
hfdcan2.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64;
hfdcan2.Init.RxBuffersNbr = 0;
hfdcan2.Init.RxBufferSize = FDCAN_DATA_BYTES_64;
hfdcan2.Init.TxEventsNbr = 0;
hfdcan2.Init.TxBuffersNbr = 0;
hfdcan2.Init.TxFifoQueueElmtsNbr = 16;
hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
hfdcan2.Init.TxElmtSize = FDCAN_DATA_BYTES_64;
if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN FDCAN2_Init 2 */
CAN2 Filter configuration
uint8_t CAN_ConfigCAN02Filter(uint8_t own_address)
{
//
uint8_t result = 0;
FDCAN_FilterTypeDef canFilterConfig = { 0 };
uint8_t filterindex = 0;
//
canFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
//
canFilterConfig.IdType = FDCAN_EXTENDED_ID;
//
canFilterConfig.FilterType = FDCAN_FILTER_MASK;
//
canFilterConfig.FilterID1 = own_address; // canIdentifier
canFilterConfig.FilterID2 = 0; // mask: 0 => accept all messages
//
canFilterConfig.RxBufferIndex = 0; // set to 0 if using FIFO
// canFilterConfig.IsCalibrationMsg = 0;
//
canFilterConfig.FilterIndex = filterindex;
// configure the FDCAN reception filter
result += HAL_FDCAN_ConfigFilter(&hfdcan2, &canFilterConfig);
//
filterindex += 2;
// enable Rx interrupts
result += HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);
result += HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO1_NEW_MESSAGE, 0);
// enable Tx interrupts
result += HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER0);
result += HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_TX_FIFO_EMPTY, 0);
// configure global filter to reject all non-matching frames
HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
FDCAN_REJECT,
FDCAN_REJECT,
FDCAN_REJECT_REMOTE,
FDCAN_REJECT_REMOTE);
//
return result;
}
CAN1 initialization CAN2.0
/* USER CODE END FDCAN1_Init 1 */
hfdcan1.Instance = FDCAN1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = DISABLE;
hfdcan1.Init.TransmitPause = DISABLE;
hfdcan1.Init.ProtocolException = ENABLE;
hfdcan1.Init.NominalPrescaler = 40;
hfdcan1.Init.NominalSyncJumpWidth = 5;
hfdcan1.Init.NominalTimeSeg1 = 10;
hfdcan1.Init.NominalTimeSeg2 = 9;
hfdcan1.Init.DataPrescaler = 1;
hfdcan1.Init.DataSyncJumpWidth = 16;
hfdcan1.Init.DataTimeSeg1 = 20;
hfdcan1.Init.DataTimeSeg2 = 16;
hfdcan1.Init.MessageRAMOffset = 0;
hfdcan1.Init.StdFiltersNbr = 1;
hfdcan1.Init.ExtFiltersNbr = 1;
hfdcan1.Init.RxFifo0ElmtsNbr = 16;
hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan1.Init.RxFifo1ElmtsNbr = 0;
hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan1.Init.RxBuffersNbr = 0;
hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
hfdcan1.Init.TxEventsNbr = 0;
hfdcan1.Init.TxBuffersNbr = 0;
hfdcan1.Init.TxFifoQueueElmtsNbr = 32;
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN FDCAN1_Init 2 */
2024-09-18 10:59 PM
I've seen it used in almost all application where multiple uC are present on the same board. also automotive grade applications... Where is not recommended?
2024-09-19 12:02 AM
I've seen it used in almost all application where multiple uC are present on the same board.
Intriguing. What kind of commercial products have these applications?
also automotive grade applications...
What automotive manufacturer and node application have you seen this on? BCM, ECM? IPC, DDM?
What bus type? GMLAN/SWCAN? MSCAN? HSCAN? I'd like to investigate.
2024-09-19 12:10 AM
Again: as ST we don’t recommend that config and we don’t guarantee the behavior. If you want to implement it in your application you do it on your own responsability.
2024-09-19 01:14 AM
Some device need to have multiple mcu on the same board (e.g. for redundancy). Quite often (at least on my experience) use or SPI commuincation or CAN communication.
Application like on board battery charger, motor drivers, ECU but also in railway application etc
When CAN communication is used I've never seen used transceiver in this case and for internal CAN commuincations a custom CAN protocol is used .