2024-11-12 10:34 PM - last edited on 2024-11-13 01:16 AM by Andrew Neil
Hello Community,
I'm using an STM32G474RE MCU with FDCAN0 to set up CANopen communication for a sensor node device. The setup is designed to cascade multiple sensor devices on the same CAN bus, each with a unique node ID, so they can transmit data independently.
Currently, I have two devices connected in a simple cascading configuration, both operating as CANopen nodes with different IDs. No CAN master or analyzer is connected, as these sensor nodes are meant to operate autonomously on the bus.
Here is my FDCAN initialization code:
void MX_FDCAN1_Init(void)
{
FDCAN_FilterTypeDef sFilterConfig;
/* FDCAN1 parameter configuration */
hfdcan1.Instance = FDCAN1;
hfdcan1.Init.DataPrescaler = 12;
hfdcan1.Init.NominalPrescaler = 12;
hfdcan1.Init.NominalTimeSeg1 = 13;
hfdcan1.Init.DataTimeSeg1 = 13;
hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = ENABLE;
hfdcan1.Init.TransmitPause = DISABLE;
hfdcan1.Init.ProtocolException = ENABLE;
hfdcan1.Init.NominalSyncJumpWidth = 1;
hfdcan1.Init.NominalTimeSeg2 = 2;
hfdcan1.Init.DataSyncJumpWidth = 1;
hfdcan1.Init.DataTimeSeg2 = 2;
hfdcan1.Init.StdFiltersNbr = 0;
hfdcan1.Init.ExtFiltersNbr = 0;
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
/* Configure Rx filter */
sFilterConfig.IdType = FDCAN_STANDARD_ID;
sFilterConfig.FilterIndex = 0;
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
sFilterConfig.FilterID1 = 0x0000;
sFilterConfig.FilterID2 = 0x0000;
if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
{
DebugPrint("Failed to config filter.");
}
/* Configure global filter to accept all frames */
if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK)
{
DebugPrint("Failed to config global filter.");
}
/* Clearing Error Flags */
__HAL_FDCAN_CLEAR_FLAG(&hfdcan1, FDCAN_FLAG_ERROR_PASSIVE | FDCAN_FLAG_BUS_OFF);
/* Start the FDCAN module */
if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
{
DebugPrint("Failed to start FDCAN.");
}
if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE | FDCAN_IT_ERROR_PASSIVE | FDCAN_IT_BUS_OFF, 0) != HAL_OK)
{
DebugPrint("Failed to activate notifications.");
}
}
With the two sensor nodes connected, the bus doesn’t transition to an Active mode, as expected. Instead, it enters an Error Passive state, and the Transmit Error Counter (TEC) reaches 128. This seems to imply a problem with message transmission or bus communication even though both nodes have unique IDs.
Any insights or suggestions would be greatly appreciated! Thank you!
Solved! Go to Solution.
2024-11-13 03:05 AM - edited 2024-11-13 03:08 AM
Thank you for the sharing.
1- How about the two terminating resistors on both sides of the bus 120ohm each? I don't see it in the shared schematics.
2- What about CAN_nSTB status?:
3- As I understood from your sketch the two nodes are composed of STM32G474, am I right?
4- Again please share your simple code you used for the test to prevent many useless ping pongs.
Thank you.
2024-11-22 02:19 AM
Hi @SofLit , @Andrew Neil
Thanks for the patience.
Answers to your questions
Ans : 1- The shared schematic is for a single node. I am connecting two identical nodes in parallel, and both have 120Ω termination resistors. I also tested the configuration by removing the termination resistor from one of the nodes on the bus, but the issue persists.
Ans : 2- The CAN_nSTB pin is not being used. It is set to logic HIGH due to the pull-up resistor.
Ans : 3- This schematic represents only one node. When I connect two such nodes to the bus, I encounter a passive bus error with this configuration.
Ans : 4- Please find the attached code for a simple project.
Thanks again for your help!
2024-11-22 02:32 AM
@omkarprayag wrote:
both have 120Ω termination resistors. I also tested the configuration by removing the termination resistor from one of the nodes on the bus, but the issue persists.
Need to keep 120ohm on both ends of the bus no matter the number of the nodes that are connected to.
@omkarprayag wrote:
Ans : 2- The CAN_nSTB pin is not being used. It is set to logic HIGH due to the pull-up resistor.
No. Please review what I shared previously from the transceiver datasheet:
-> In normal operation this pin needs to be at GND level otherwise (connected to VDD or over internal pull-up) the transceiver will be in standby mode -> no communication.
2024-11-25 10:18 PM
@SofLit ,
Thank you for your response.
In the code, the pin is already configured to logic '0'. I have also physically connected it to GND, but the issue persists.
2024-11-25 10:48 PM
Hello,
I believe the issue may stem from having only two nodes on the CAN bus, with no CAN analyzer or master device, which could result in the bus lacking an acknowledgment source.
Could this be the cause of the issue? If so, could you provide guidance on how to enable acknowledgment when receiving messages? Specifically, I would appreciate your advice on the suitable CAN interface configurations.
In my previous message, I attached the source code, and within the main.c file, there is a function MX_FDCAN1_Init(), which contains all the CAN-related configurations. Could you please verify if these configurations are correct or if any modifications are needed with respect to this approach? Any other suggestions would also be appreciated
Here is the relevant function:
void MX_FDCAN1_Init(void)
{
FDCAN_FilterTypeDef sFilterConfig;
/* FDCAN1 parameter configuration */
hfdcan1.Init.DataPrescaler = ucCanPrescaler;
hfdcan1.Init.NominalPrescaler = ucCanPrescaler;
hfdcan1.Init.NominalTimeSeg1 = ucCanTimeSeg1;
hfdcan1.Init.DataTimeSeg1 = ucCanTimeSeg1;
hfdcan1.Instance = FDCAN1;
hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = ENABLE;
hfdcan1.Init.TransmitPause = DISABLE;
hfdcan1.Init.ProtocolException = ENABLE;
hfdcan1.Init.NominalSyncJumpWidth = 1;
hfdcan1.Init.NominalTimeSeg2 = 2;
hfdcan1.Init.DataSyncJumpWidth = 1;
hfdcan1.Init.DataTimeSeg2 = 2;
hfdcan1.Init.StdFiltersNbr = 0;
hfdcan1.Init.ExtFiltersNbr = 0;
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
/* Configure Rx filter */
sFilterConfig.IdType = FDCAN_STANDARD_ID;
sFilterConfig.FilterIndex = 0;
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
sFilterConfig.FilterID1 = 0x0000;
sFilterConfig.FilterID2 = 0x7FF; // 0x0000
if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
{
DebugPrint("Failed to config filter.");
}
/* Configure global filter to accept all frames */
if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK)
{
DebugPrint("Failed to config global filter.");
}
/* Clearing Error Flags */
__HAL_FDCAN_CLEAR_FLAG(&hfdcan1, FDCAN_FLAG_ERROR_PASSIVE | FDCAN_FLAG_BUS_OFF);
/* Start the FDCAN module */
if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
{
DebugPrint("Failed to start FDCAN.");
}
if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE | FDCAN_IT_ERROR_PASSIVE | FDCAN_IT_BUS_OFF, 0) != HAL_OK)
{
DebugPrint("Failed to activate notifications.");
}
}
2024-11-26 01:25 AM
Hello @omkarprayag ,
1- "I believe the issue may stem from having only two nodes on the CAN bus" I don't know what do you mean by "stem" but two nodes are sufficient to establish a CAN bus. So this is not the problem.
2- Could you please share your ioc file?
3- Could you please tell if you are using NUCLEO-G474RE board?
4- Not clear what ucCanTimeSeg1 value is?:
hfdcan1.Init.NominalTimeSeg1 = ucCanTimeSeg1;
hfdcan1.Init.NominalTimeSeg2 = 2;
PS: Please in next time try to react rapidly to our requests. We can forget your case and restoring the context needs from us to read all the discussions from the beginning and this is not efficient as we are supporting tens of threads per day. Thank you for your understanding.
2024-11-26 02:30 AM - edited 2024-11-26 02:32 AM
@SofLit ,
Thank you for your response. I will ensure prompt replies moving forward.
Answer 1:
My concern is that these two devices may not be sending an acknowledgment (ACK) bit. I suspect this because I’m receiving the error flag LastErrorCode = FDCAN_PROTOCOL_ERROR_ACK, which indicates that there is no acknowledgment from the receiver.
Do you think this could be the issue here? If so, could you guide me on how to ensure an ACK bit is sent during message reception?
Answer 2:
I do not have an .ioc file, as I manually configured the settings.
Answer 3:
I am using a custom-designed board. The project includes a file called gpio_definitions.h, which contains all the pin configurations.
Answer 4:
The value of ucCanTimeSeg1 is 13. Below are the configurations I’m using for the FDCAN1 port:
/* FDCAN1 parameter configuration */
hfdcan1.Init.DataPrescaler = 12;
hfdcan1.Init.NominalPrescaler = 12;
hfdcan1.Init.NominalTimeSeg1 = 13;
hfdcan1.Init.DataTimeSeg1 = 13;
hfdcan1.Instance = FDCAN1;
hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = ENABLE;
hfdcan1.Init.TransmitPause = DISABLE;
hfdcan1.Init.ProtocolException = ENABLE;
hfdcan1.Init.NominalSyncJumpWidth = 1;
hfdcan1.Init.NominalTimeSeg2 = 2;
hfdcan1.Init.DataSyncJumpWidth = 1;
hfdcan1.Init.DataTimeSeg2 = 2;
hfdcan1.Init.StdFiltersNbr = 0;
hfdcan1.Init.ExtFiltersNbr = 0;
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
Looking forward to your guidance and suggestions!
2024-11-26 03:48 AM
The acknowledgement is sent automatically by the receiver when it receives a correct frame, so you don't even enable it. It's something managed by hardware.
Your issue is either related to your hardware or your software.
Now as you don't have an ioc file. I kindly request to create a CubeMx project where you put the config of the used clocks and the FDCAN parameters and attach it. This way I can help you efficiently.
Also, please confirm if you are using an external Crystal.
2024-11-26 03:57 AM
@SofLit ,
Attached is the .ioc file in CubeMx project, the same configurations I'm using.
Yes, using external crystal of 24MHz.
2024-11-26 04:49 AM - edited 2024-11-26 04:50 AM
Thanks for sharing,
Now do you confirm your CAN bus bitrate is at 250kb/s? I've put the same parameters as you shared in your code.
Prescaler 12, NBS1=13, NBS2=2 -> Sample point ~81%
Is 250kb/s the intended bitrate?