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-02-21 06:29 AM - edited 2024-02-21 06:35 AM
No. This is not the right way to use CAN in Normal mode.
You need to use transceivers to connect two nodes.
CAN is not UART nor SPI nor something else. You need to use transceivers even with only two nodes on the bus.
2024-02-21 07:02 AM - edited 2024-02-21 07:19 AM
Hi SofLit,
I know, also tested it with a CAN driver on both sides, same issue.
The CAN bus driver provides the differential bus signal, the power to send longer distances and sharpens the received signals.
There would be either a CAN error on the sender side (not observed in any mentioned case) or no CAN ACK on the receiver side (also not observed in any case).
The used 10$ logic anlayser used to provide the shown logs shows clear signals in all cases (so the physical layer is OK) and is able to read and display the send values as the ID/data in a correct way.
Just changing the FilterID2 and global filter as in case 1 and case 2 provides this issue of no interrupt/callback.
Cheers!
2024-02-22 01:39 AM - edited 2024-02-22 01:54 AM
Hi SofLit,
so i relay just need the right filter setting for FDCAN Extended ID Filter one ID with one mask.
As playing around with the code shows, that using
//
canFilterConfig.IdType = FDCAN_EXTENDED_ID; // extended ID
canFilterConfig.FilterType = FDCAN_FILTER_MASK; // second ID is the mask
canFilterConfig.FilterID1 = own_address; // set the CAN ID to be filtered
canFilterConfig.FilterID2 = 0; // mask: 0 => accept all messages
with
HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
FDCAN_REJECT,
FDCAN_REJECT,
FDCAN_FILTER_REMOTE,
FDCAN_FILTER_REMOTE);
rejects everything, even the matching frames, which is not the way HAL_FDCAN_ConfigGlobalFilter suposed to work. But I have to call HAL_FDCAN_ConfigGlobalFilter() otherwise it dosen't work either ...
2024-02-22 02:32 AM
Refer to this thread, it may help you:
2024-02-22 04:05 AM
As far as I know cross-connection CAN RxTx is not the recommended solution - it depends on the internal logic of the CAN frontend. See https://community.st.com/t5/stm32-mcus-products/on-board-communication-via-can-without-transceiver/td-p/152684 for a clean and proven solution (without using transceivers).
2024-02-22 06:03 AM
The solution can work but with very limited bus distance and not recommended for a final design.
2024-02-22 07:20 AM - edited 2024-02-26 10:32 PM
Hi SofLit,
The issue still exists at my side, could somebody confirm or contradict it using the attached project?
I managed to setup a minimum project using 2 NUCLEO-144-H723 boards and two jumper wires (<150 mm), where H723A is the sender and H723B is the receiver. FDCAN2 is used for communication and FDCAN1 is only setup for consistency of this thread.
The sender will send an extended FDCAN message every second, indicated by the RED on-board LED toggling. Every successful received extended FDCAN message at the receiver will be indicated by a toggled GREEN on-board LED. Both H723A/B use the same project code, two #defines select the task.
Setup the sender H723A
uncomment line 105 at the main.c
#define sender // use this definition for the sender H723A
compile, program and run.
Setup the receiver H723B
comment out line 105 at the main.c
//#define sender // use this definition for the sender H723A
1. setup for successful receiving
uncomment line 188 at the ProcessCAN.c
#define RECEIVE_SUCCSEFUL
compile, program and run.
The receiver will use the following global CAN filter setup
// EITHER uncomment this and GREEN BOARD LED toggles -> receiving
HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
FDCAN_ACCEPT_IN_RX_FIFO1,
FDCAN_ACCEPT_IN_RX_FIFO1,
FDCAN_FILTER_REMOTE,
FDCAN_FILTER_REMOTE);
2. setup for unsuccessful receiving
comment out line 188 at the ProcessCAN.c
//#define RECEIVE_SUCCSEFUL
compile, program and run.
The receiver will use the following global CAN filter setup, which should allow the message to pass the filter, but it doesn't.
// OR uncomment this and GREEN BOARD LED does not toggle -> not receiving
HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
FDCAN_REJECT,
FDCAN_REJECT,
FDCAN_FILTER_REMOTE,
FDCAN_FILTER_REMOTE);
Cheers!
2024-02-27 02:22 AM - edited 2024-02-27 02:57 AM
Hi SofLit,
I found an related but also unresolved issue:
Help with FD-CAN filter - STMicroelectronics Community
Cheers!
2024-09-18 09:49 AM
It is not true. It is possible to connect 2 nodes via CAN without the transceiver. A resistor net is needed.
Purifier.2 What is your hw configuration?
2024-09-18 09:52 AM - edited 2024-09-18 09:56 AM
@STDoom wrote:
It is not true. It is possible to connect 2 nodes via CAN without the transceiver. A resistor net is needed.
Not recommended configuration. This could be used just for test and with low bitrate and with a very low distance between nodes.